Skip to content

Commit b947f35

Browse files
committed
starting to work.
1 parent 50c70ac commit b947f35

File tree

9 files changed

+87
-29
lines changed

9 files changed

+87
-29
lines changed

packages/agent/src/core/llm/core.ts

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,16 @@
33
*/
44
import { LLMProvider } from './provider.js';
55
import {
6+
AssistantMessage,
67
FunctionDefinition,
78
GenerateOptions,
89
LLMResponse,
910
Message,
11+
SystemMessage,
1012
ToolCall,
13+
ToolResultMessage,
14+
ToolUseMessage,
15+
UserMessage,
1116
} from './types.js';
1217

1318
/**
@@ -112,23 +117,31 @@ export function normalizeMessages(messages: Message[]): Message[] {
112117
return {
113118
role: 'system',
114119
content: msg.content,
115-
};
120+
} satisfies SystemMessage;
116121
case 'user':
117122
return {
118123
role: 'user',
119124
content: msg.content,
120-
};
125+
} satisfies UserMessage;
121126
case 'assistant':
122127
return {
123128
role: 'assistant',
124129
content: msg.content,
125-
};
126-
case 'tool':
130+
} satisfies AssistantMessage;
131+
case 'tool_use':
127132
return {
128-
role: 'tool',
133+
role: 'tool_use',
134+
id: msg.id,
135+
name: msg.name,
129136
content: msg.content,
130-
name: msg.name || 'unknown_tool', // Ensure name is always present for tool messages
131-
};
137+
} satisfies ToolUseMessage;
138+
case 'tool_result':
139+
return {
140+
role: 'tool_result',
141+
tool_use_id: msg.tool_use_id,
142+
content: msg.content,
143+
is_error: msg.is_error,
144+
} satisfies ToolResultMessage;
132145
default:
133146
// Use type assertion for unknown roles
134147
console.warn(

packages/agent/src/core/llm/examples.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,14 @@ async function _openaiExample() {
7070

7171
// Example of adding a tool result
7272
const toolResult: Message = {
73-
role: 'tool',
74-
name: toolCall.name,
73+
role: 'tool_result',
74+
tool_use_id: toolCall.id,
7575
content: JSON.stringify({
7676
temperature: 72,
7777
unit: 'fahrenheit',
7878
description: 'Sunny with some clouds',
7979
}),
80+
is_error: false,
8081
};
8182

8283
// Continue the conversation with the tool result

packages/agent/src/core/llm/providers/anthropic.ts

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,21 @@ export class AnthropicProvider implements LLMProvider {
8282
description: fn.description,
8383
input_schema: fn.parameters,
8484
}));
85-
console.log('Tools for Anthropic:', JSON.stringify(tools, null, 2));
8685
(requestOptions as any).tools = tools;
8786
}
8887

88+
console.log(
89+
'Input Messages for Anthropic:',
90+
JSON.stringify(requestOptions.messages, null, 2),
91+
);
92+
8993
const response = await this.client.messages.create(requestOptions);
9094

95+
console.log(
96+
'Response from Anthropic:',
97+
JSON.stringify(response.content, null, 2),
98+
);
99+
91100
// Extract content and tool calls
92101
const content =
93102
response.content.find((c) => c.type === 'text')?.text || '';
@@ -144,21 +153,32 @@ export class AnthropicProvider implements LLMProvider {
144153
role: 'assistant',
145154
content: msg.content,
146155
};
147-
} else if (msg.role === 'tool') {
156+
} else if (msg.role === 'tool_result') {
148157
// Anthropic expects tool responses as an assistant message with tool_results
149158
return {
150-
role: 'assistant',
159+
role: 'user',
151160
content: [
152161
{
153162
type: 'tool_result',
154-
tool_use_id: msg.name, // Use name as the tool_use_id
163+
tool_use_id: msg.tool_use_id, // Use name as the tool_use_id
155164
content: msg.content,
165+
is_error: msg.is_error,
166+
},
167+
],
168+
};
169+
} else if (msg.role === 'tool_use') {
170+
return {
171+
role: 'assistant',
172+
content: [
173+
{
174+
type: 'tool_use',
175+
name: msg.name,
176+
id: msg.id,
177+
input: JSON.parse(msg.content),
156178
},
157179
],
158180
};
159181
}
160-
161-
// Default fallback
162182
return {
163183
role: 'user',
164184
content: msg.content,

packages/agent/src/core/llm/types.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* Base message type with role and content
77
*/
88
export interface BaseMessage {
9-
role: 'system' | 'user' | 'assistant' | 'tool';
9+
role: 'system' | 'user' | 'assistant' | 'tool_use' | 'tool_result';
1010
content: string;
1111
name?: string;
1212
}
@@ -35,9 +35,18 @@ export interface AssistantMessage extends BaseMessage {
3535
/**
3636
* Tool message for representing tool responses
3737
*/
38-
export interface ToolMessage extends BaseMessage {
39-
role: 'tool';
38+
export interface ToolUseMessage extends BaseMessage {
39+
role: 'tool_use';
4040
name: string; // Tool name is required for tool messages
41+
id: string; // Tool ID is required for tool messages
42+
content: string; // the arguments in string form, but JSON
43+
}
44+
45+
export interface ToolResultMessage extends BaseMessage {
46+
role: 'tool_result';
47+
tool_use_id: string; // Tool Use ID is required for tool messages
48+
content: string; // the results in string form, but JSON
49+
is_error: boolean; // whether the tool call was successful
4150
}
4251

4352
/**
@@ -47,7 +56,8 @@ export type Message =
4756
| SystemMessage
4857
| UserMessage
4958
| AssistantMessage
50-
| ToolMessage;
59+
| ToolUseMessage
60+
| ToolResultMessage;
5161

5262
/**
5363
* Function/Tool definition for LLM

packages/agent/src/core/toolAgent/messageUtils.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export function formatToolCalls(toolCalls: ToolCall[]): any[] {
88
type: 'tool_use',
99
name: call.name,
1010
id: call.id,
11-
input: JSON.parse(call.arguments),
11+
input: call.arguments,
1212
}));
1313
}
1414

@@ -30,13 +30,15 @@ export function createToolCallParts(toolCalls: any[]): any[] {
3030
*/
3131
export function addToolResultToMessages(
3232
messages: Message[],
33-
toolName: string,
33+
toolUseId: string,
3434
toolResult: any,
35+
isError: boolean,
3536
): void {
3637
messages.push({
37-
role: 'tool',
38-
name: toolName,
38+
role: 'tool_result',
39+
tool_use_id: toolUseId,
3940
content:
4041
typeof toolResult === 'string' ? toolResult : JSON.stringify(toolResult),
42+
is_error: isError,
4143
});
4244
}

packages/agent/src/core/toolAgent/toolAgentCore.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { zodToJsonSchema } from 'zod-to-json-schema';
22

3-
import { Message, generateText } from '../llm/index.js';
3+
import { Message, ToolUseMessage, generateText } from '../llm/index.js';
44

55
import { DEFAULT_CONFIG } from './config.js';
66
import { formatToolCalls } from './messageUtils.js';
@@ -105,6 +105,18 @@ export const toolAgent = async (
105105

106106
// Handle tool calls if any
107107
if (toolCalls.length > 0) {
108+
messages.push(
109+
...toolCalls.map(
110+
(toolCall) =>
111+
({
112+
role: 'tool_use',
113+
name: toolCall.name,
114+
id: toolCall.id,
115+
content: toolCall.arguments,
116+
}) satisfies ToolUseMessage,
117+
),
118+
);
119+
108120
// Execute the tools and get results
109121
const { sequenceCompleted, completionResult, respawn } =
110122
await executeTools(localToolCalls, tools, messages, context);

packages/agent/src/core/toolAgent/toolExecutor.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export async function executeTools(
3636
const respawnCall = toolCalls.find((call) => call.name === 'respawn');
3737
if (respawnCall) {
3838
// Add the tool result to messages
39-
addToolResultToMessages(messages, respawnCall.name, { success: true });
39+
addToolResultToMessages(messages, respawnCall.id, { success: true }, false);
4040

4141
return {
4242
sequenceCompleted: false,
@@ -56,12 +56,14 @@ export async function executeTools(
5656
const toolResults = await Promise.all(
5757
toolCalls.map(async (call) => {
5858
let toolResult = '';
59+
let isError = false;
5960
try {
6061
toolResult = await executeToolCall(call, tools, {
6162
...context,
6263
tokenTracker: new TokenTracker(call.name, context.tokenTracker),
6364
});
6465
} catch (errorStr: any) {
66+
isError = true;
6567
if (errorStr instanceof Error) {
6668
if (errorStr.stack) {
6769
context.logger.error(`Tool error stack trace: ${errorStr.stack}`);
@@ -78,7 +80,7 @@ export async function executeTools(
7880
const parsedResult = safeParse(toolResult);
7981

8082
// Add the tool result to messages
81-
addToolResultToMessages(messages, call.name, parsedResult);
83+
addToolResultToMessages(messages, call.id, parsedResult, isError);
8284

8385
return {
8486
toolCallId: call.id,

packages/agent/src/core/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ export type ToolResultContent = {
6262
type: 'tool_result';
6363
tool_use_id: string;
6464
content: string;
65+
is_error: boolean;
6566
};
6667

6768
export type UserMessage = {

pnpm-lock.yaml

Lines changed: 0 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)