11import { execSync } from 'child_process' ;
22
3- import Anthropic from '@anthropic-ai/sdk' ;
4- import { ContentBlockParam } from '@anthropic-ai/sdk/resources/messages/messages.js' ;
3+ import { anthropic } from '@ai-sdk/anthropic' ;
4+ import {
5+ CoreMessage ,
6+ CoreToolMessage ,
7+ generateText ,
8+ ToolResultPart ,
9+ ToolSet ,
10+ } from 'ai' ;
511import chalk from 'chalk' ;
612
713import { getAnthropicApiKeyError } from '../utils/errors.js' ;
814
915import { executeToolCall } from './executeToolCall.js' ;
10- import { TokenTracker , TokenUsage } from './tokens.js' ;
16+ import { TokenTracker } from './tokens.js' ;
1117import {
1218 Tool ,
13- TextContent ,
1419 ToolUseContent ,
1520 ToolResultContent ,
16- Message ,
1721 ToolContext ,
1822} from './types.js' ;
1923
@@ -24,7 +28,7 @@ export interface ToolAgentResult {
2428
2529const CONFIG = {
2630 maxIterations : 200 ,
27- model : 'claude-3-7-sonnet-latest' ,
31+ model : anthropic ( 'claude-3-7-sonnet-20250219' ) ,
2832 maxTokens : 4096 ,
2933 temperature : 0.7 ,
3034 getSystemPrompt : ( ) => {
@@ -86,9 +90,9 @@ const CONFIG = {
8690interface ToolCallResult {
8791 sequenceCompleted : boolean ;
8892 completionResult ?: string ;
89- toolResults : ToolResultContent [ ] ;
93+ toolResults : ToolResultPart [ ] ;
9094}
91-
95+ /*
9296function processResponse(response: Anthropic.Message) {
9397 const content: (TextContent | ToolUseContent)[] = [];
9498 const toolCalls: ToolUseContent[] = [];
@@ -110,11 +114,12 @@ function processResponse(response: Anthropic.Message) {
110114
111115 return { content, toolCalls };
112116}
117+ */
113118
114119async function executeTools (
115120 toolCalls : ToolUseContent [ ] ,
116121 tools : Tool [ ] ,
117- messages : Message [ ] ,
122+ messages : CoreMessage [ ] ,
118123 context : ToolContext ,
119124) : Promise < ToolCallResult & { respawn ?: { context : string } } > {
120125 if ( toolCalls . length === 0 ) {
@@ -132,18 +137,19 @@ async function executeTools(
132137 sequenceCompleted : false ,
133138 toolResults : [
134139 {
135- type : 'tool_result' ,
136- tool_use_id : respawnCall . id ,
137- content : 'Respawn initiated' ,
138- } ,
140+ type : 'tool-result' ,
141+ toolCallId : respawnCall . id ,
142+ toolName : respawnCall . name ,
143+ result : { success : true } ,
144+ } satisfies ToolResultPart ,
139145 ] ,
140146 respawn : {
141147 context : respawnCall . input . respawnContext ,
142148 } ,
143149 } ;
144150 }
145151
146- const results = await Promise . all (
152+ const toolResults : ToolResultPart [ ] = await Promise . all (
147153 toolCalls . map ( async ( call ) => {
148154 let toolResult = '' ;
149155 try {
@@ -155,35 +161,36 @@ async function executeTools(
155161 toolResult = `Error: Exception thrown during tool execution. Type: ${ error . constructor . name } , Message: ${ error . message } ` ;
156162 }
157163 return {
158- type : 'tool_result' as const ,
159- tool_use_id : call . id ,
160- content : toolResult ,
161- isComplete : call . name === 'sequenceComplete' ,
162- } ;
164+ type : 'tool-result' ,
165+ toolCallId : call . id ,
166+ toolName : call . name ,
167+ result : JSON . parse ( toolResult ) satisfies ToolResultContent ,
168+ } satisfies ToolResultPart ;
163169 } ) ,
164170 ) ;
165171
166- const toolResults = results . map ( ( { type, tool_use_id, content } ) => ( {
167- type,
168- tool_use_id,
169- content,
170- } ) ) ;
171-
172- const sequenceCompleted = results . some ( ( r ) => r . isComplete ) ;
173- const completionResult = results . find ( ( r ) => r . isComplete ) ?. content ;
172+ const sequenceCompletedTool = toolResults . find (
173+ ( r ) => r . toolName === 'sequenceComplete' ,
174+ ) ;
175+ const completionResult = sequenceCompletedTool ?. result as string ;
174176
175177 messages . push ( {
176- role : 'user ' ,
178+ role : 'tool ' ,
177179 content : toolResults ,
178- } ) ;
180+ } satisfies CoreToolMessage ) ;
179181
180- if ( sequenceCompleted ) {
182+ if ( sequenceCompletedTool ) {
181183 logger . verbose ( 'Sequence completed' , { completionResult } ) ;
182184 }
183185
184- return { sequenceCompleted, completionResult, toolResults } ;
186+ return {
187+ sequenceCompleted : sequenceCompletedTool !== undefined ,
188+ completionResult,
189+ toolResults,
190+ } ;
185191}
186192
193+ /*
187194// a function that takes a list of messages and returns a list of messages but with the last message having a cache_control of ephemeral
188195function addCacheControlToTools<T>(messages: T[]): T[] {
189196 return messages.map((m, i) => ({
@@ -238,7 +245,7 @@ function addCacheControlToMessages(
238245 : m.content,
239246 };
240247 });
241- }
248+ }*/
242249
243250export const toolAgent = async (
244251 initialPrompt : string ,
@@ -256,8 +263,8 @@ export const toolAgent = async (
256263 const apiKey = process . env . ANTHROPIC_API_KEY ;
257264 if ( ! apiKey ) throw new Error ( getAnthropicApiKeyError ( ) ) ;
258265
259- const client = new Anthropic ( { apiKey } ) ;
260- const messages : Message [ ] = [
266+ // const client = new Anthropic({ apiKey });
267+ const messages : CoreMessage [ ] = [
261268 {
262269 role : 'user' ,
263270 content : [ { type : 'text' , text : initialPrompt } ] ,
@@ -278,32 +285,31 @@ export const toolAgent = async (
278285
279286 interactions ++ ;
280287
281- // Create request parameters
282- const requestParams : Anthropic . MessageCreateParams = {
283- model : config . model ,
284- max_tokens : config . maxTokens ,
285- temperature : config . temperature ,
286- messages : addCacheControlToMessages ( messages ) ,
287- system : [
288- {
289- type : 'text' ,
290- text : systemPrompt ,
291- cache_control : { type : 'ephemeral' } ,
292- } ,
293- ] ,
294- tools : addCacheControlToTools (
295- tools . map ( ( t ) => ( {
296- name : t . name ,
297- description : t . description ,
298- input_schema : t . parameters as Anthropic . Tool . InputSchema ,
299- } ) ) ,
300- ) ,
301- tool_choice : { type : 'auto' } ,
302- } ;
288+ const toolSet : ToolSet = { } ;
289+ tools . forEach ( ( tool ) => {
290+ toolSet [ tool . name ] = {
291+ description : tool . description ,
292+ parameters : tool . parameters ,
293+ } ;
294+ } ) ;
295+ const { text, reasoning, reasoningDetails, toolCalls, toolResults } =
296+ await generateText ( {
297+ model : config . model ,
298+ temperature : config . temperature ,
299+ messages,
300+ system : systemPrompt ,
301+ tools : toolSet ,
302+ toolChoice : 'auto' ,
303+ } ) ;
303304
304- const response = await client . messages . create ( requestParams ) ;
305+ const localToolCalls : ToolUseContent [ ] = toolCalls . map ( ( call ) => ( {
306+ type : 'tool_use' ,
307+ name : call . toolName ,
308+ id : call . toolCallId ,
309+ input : call . args ,
310+ } ) ) ;
305311
306- if ( ! response . content . length ) {
312+ if ( ! text . length ) {
307313 // Instead of treating empty response as completion, remind the agent
308314 logger . verbose ( 'Received empty response from agent, sending reminder' ) ;
309315 messages . push ( {
@@ -319,31 +325,25 @@ export const toolAgent = async (
319325 }
320326
321327 // Track both regular and cached token usage
322- const tokenUsagePerMessage = TokenUsage . fromMessage ( response ) ;
323- tokenTracker . tokenUsage . add ( tokenUsagePerMessage ) ;
328+ // const tokenUsagePerMessage = TokenUsage.fromMessage(response);
329+ // tokenTracker.tokenUsage.add(tokenUsagePerMessage);
324330
325- const { content, toolCalls } = processResponse ( response ) ;
326331 messages . push ( {
327332 role : 'assistant' ,
328- content,
333+ content : [ { type : 'text' , text : text } ] ,
329334 } ) ;
330335
331- // Log the assistant's message
332- const assistantMessage = content
333- . filter ( ( c ) => c . type === 'text' )
334- . map ( ( c ) => c . text )
335- . join ( '\\n' ) ;
336- if ( assistantMessage ) {
337- logger . info ( assistantMessage ) ;
336+ if ( text ) {
337+ logger . info ( text ) ;
338338 }
339339
340- logger . log (
340+ /* logger.log(
341341 tokenTracker.logLevel,
342342 chalk.blue(`[Token Usage/Message] ${tokenUsagePerMessage.toString()}`),
343- ) ;
343+ );*/
344344
345345 const { sequenceCompleted, completionResult, respawn } = await executeTools (
346- toolCalls ,
346+ localToolCalls ,
347347 tools ,
348348 messages ,
349349 context ,
@@ -361,10 +361,8 @@ export const toolAgent = async (
361361 }
362362
363363 if ( sequenceCompleted ) {
364- const result = {
365- result :
366- completionResult ??
367- 'Sequence explicitly completed with an empty result' ,
364+ const result : ToolAgentResult = {
365+ result : completionResult ?? 'Sequence explicitly completed' ,
368366 interactions,
369367 } ;
370368 logger . log (
0 commit comments