@@ -25,7 +25,7 @@ export function buildNextTurnParamsContext(
2525 temperature : request . temperature ?? null ,
2626 maxOutputTokens : request . maxOutputTokens ?? null ,
2727 topP : request . topP ?? null ,
28- topK : request . topK ?? 0 ,
28+ topK : request . topK ,
2929 instructions : request . instructions ?? null ,
3030 } ;
3131}
@@ -66,13 +66,16 @@ export async function executeNextTurnParamsFunctions(
6666
6767 // Validate that call.arguments is a record using type guard
6868 if ( ! isRecord ( call . arguments ) ) {
69+ const typeStr = Array . isArray ( call . arguments )
70+ ? 'array'
71+ : typeof call . arguments ;
6972 throw new Error (
70- `Tool call arguments for ${ tool . function . name } must be an object, got ${ typeof call . arguments } `
73+ `Tool call arguments for ${ tool . function . name } must be an object, got ${ typeStr } `
7174 ) ;
7275 }
7376
7477 // Process each parameter key with proper typing
75- await processNextTurnParamsForCall ( nextParams , call . arguments , workingContext , result ) ;
78+ await processNextTurnParamsForCall ( nextParams , call . arguments , workingContext , result , tool . function . name ) ;
7679 }
7780 }
7881
@@ -86,7 +89,8 @@ async function processNextTurnParamsForCall(
8689 nextParams : Record < string , unknown > ,
8790 params : Record < string , unknown > ,
8891 workingContext : NextTurnParamsContext ,
89- result : Partial < NextTurnParamsContext >
92+ result : Partial < NextTurnParamsContext > ,
93+ toolName : string
9094) : Promise < void > {
9195 // Type-safe processing for each known parameter key
9296 // We iterate through keys and use runtime checks instead of casts
@@ -99,15 +103,20 @@ async function processNextTurnParamsForCall(
99103
100104 // Validate that paramKey is actually a key of NextTurnParamsContext
101105 if ( ! isValidNextTurnParamKey ( paramKey ) ) {
102- // Skip invalid keys silently - they're not part of the API
106+ console . warn (
107+ `Invalid nextTurnParams key "${ paramKey } " in tool "${ toolName } ". ` +
108+ `Valid keys: input, model, models, temperature, maxOutputTokens, topP, topK, instructions`
109+ ) ;
103110 continue ;
104111 }
105112
106113 // Execute the function and await the result
107114 const newValue = await Promise . resolve ( fn ( params , workingContext ) ) ;
108115
109- // Update the result using type-safe assignment
116+ // Update both result and workingContext to enable composition
117+ // Later tools will see modifications made by earlier tools
110118 setNextTurnParam ( result , paramKey , newValue ) ;
119+ setNextTurnParam ( workingContext , paramKey , newValue ) ;
111120 }
112121}
113122
@@ -130,7 +139,8 @@ function isValidNextTurnParamKey(key: string): key is keyof NextTurnParamsContex
130139
131140/**
132141 * Type-safe setter for NextTurnParamsContext
133- * Ensures the value type matches the key type
142+ * This wrapper is needed because TypeScript doesn't properly narrow the type
143+ * after the type guard, even though we've validated the key
134144 */
135145function setNextTurnParam < K extends keyof NextTurnParamsContext > (
136146 target : Partial < NextTurnParamsContext > ,
0 commit comments