@openrouter/sdk 0.3.7 → 0.3.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/.zed/settings.json +10 -0
  2. package/_speakeasy/.github/action-inputs-config.json +53 -0
  3. package/_speakeasy/.github/action-security-config.json +88 -0
  4. package/esm/funcs/call-model.d.ts +94 -9
  5. package/esm/funcs/call-model.js +102 -120
  6. package/esm/index.d.ts +20 -8
  7. package/esm/index.js +20 -7
  8. package/esm/lib/anthropic-compat.d.ts +6 -2
  9. package/esm/lib/anthropic-compat.js +117 -98
  10. package/esm/lib/async-params.d.ts +53 -0
  11. package/esm/lib/async-params.js +76 -0
  12. package/esm/lib/chat-compat.js +4 -0
  13. package/esm/lib/claude-constants.d.ts +22 -0
  14. package/esm/lib/claude-constants.js +20 -0
  15. package/esm/lib/claude-type-guards.d.ts +10 -0
  16. package/esm/lib/claude-type-guards.js +70 -0
  17. package/esm/lib/config.d.ts +4 -2
  18. package/esm/lib/config.js +2 -2
  19. package/esm/lib/model-result.d.ts +18 -25
  20. package/esm/lib/model-result.js +137 -176
  21. package/esm/lib/next-turn-params.d.ts +30 -0
  22. package/esm/lib/next-turn-params.js +129 -0
  23. package/esm/lib/reusable-stream.js +10 -10
  24. package/esm/lib/stop-conditions.d.ts +80 -0
  25. package/esm/lib/stop-conditions.js +104 -0
  26. package/esm/lib/stream-transformers.d.ts +3 -3
  27. package/esm/lib/stream-transformers.js +311 -260
  28. package/esm/lib/stream-type-guards.d.ts +29 -0
  29. package/esm/lib/stream-type-guards.js +109 -0
  30. package/esm/lib/tool-executor.d.ts +9 -7
  31. package/esm/lib/tool-executor.js +7 -1
  32. package/esm/lib/tool-orchestrator.d.ts +7 -7
  33. package/esm/lib/tool-orchestrator.js +38 -10
  34. package/esm/lib/tool-types.d.ts +163 -29
  35. package/esm/lib/tool-types.js +6 -0
  36. package/esm/lib/tool.d.ts +99 -0
  37. package/esm/lib/tool.js +71 -0
  38. package/esm/lib/turn-context.d.ts +50 -0
  39. package/esm/lib/turn-context.js +59 -0
  40. package/esm/sdk/sdk.d.ts +3 -9
  41. package/jsr.json +1 -1
  42. package/package.json +6 -3
@@ -1,38 +1,28 @@
1
- import { betaResponsesSend } from "../funcs/betaResponsesSend.js";
2
- import { ReusableReadableStream } from "./reusable-stream.js";
3
- import { buildResponsesMessageStream, buildToolCallStream, consumeStreamForCompletion, extractReasoningDeltas, extractResponsesMessageFromResponse, extractTextDeltas, extractTextFromResponse, extractToolCallsFromResponse, extractToolDeltas, } from "./stream-transformers.js";
4
- import { executeTool } from "./tool-executor.js";
5
- import { hasExecuteFunction } from "./tool-types.js";
1
+ import { betaResponsesSend } from '../funcs/betaResponsesSend.js';
2
+ import { hasAsyncFunctions, resolveAsyncFunctions, } from './async-params.js';
3
+ import { ReusableReadableStream } from './reusable-stream.js';
4
+ import { buildResponsesMessageStream, buildToolCallStream, consumeStreamForCompletion, extractReasoningDeltas, extractResponsesMessageFromResponse, extractTextDeltas, extractTextFromResponse, extractToolCallsFromResponse, extractToolDeltas, } from './stream-transformers.js';
5
+ import { executeTool } from './tool-executor.js';
6
+ import { executeNextTurnParamsFunctions, applyNextTurnParamsToRequest } from './next-turn-params.js';
7
+ import { hasExecuteFunction } from './tool-types.js';
8
+ import { isStopConditionMet } from './stop-conditions.js';
6
9
  /**
7
10
  * Type guard for stream event with toReadableStream method
8
11
  */
9
12
  function isEventStream(value) {
10
13
  return (value !== null &&
11
- typeof value === "object" &&
12
- "toReadableStream" in value &&
13
- typeof value.toReadableStream ===
14
- "function");
15
- }
16
- /**
17
- * Type guard for response.output_text.delta events
18
- */
19
- function isOutputTextDeltaEvent(event) {
20
- return "type" in event && event.type === "response.output_text.delta";
21
- }
22
- /**
23
- * Type guard for response.completed events
24
- */
25
- function isResponseCompletedEvent(event) {
26
- return "type" in event && event.type === "response.completed";
14
+ typeof value === 'object' &&
15
+ 'toReadableStream' in value &&
16
+ typeof value.toReadableStream === 'function');
27
17
  }
28
18
  /**
29
19
  * Type guard for output items with a type property
30
20
  */
31
21
  function hasTypeProperty(item) {
32
- return (typeof item === "object" &&
22
+ return (typeof item === 'object' &&
33
23
  item !== null &&
34
- "type" in item &&
35
- typeof item.type === "string");
24
+ 'type' in item &&
25
+ typeof item.type === 'string');
36
26
  }
37
27
  /**
38
28
  * A wrapper around a streaming response that provides multiple consumption patterns.
@@ -50,6 +40,8 @@ function hasTypeProperty(item) {
50
40
  *
51
41
  * All consumption patterns can be used concurrently thanks to the underlying
52
42
  * ReusableReadableStream implementation.
43
+ *
44
+ * @template TTools - The tools array type to enable typed tool calls and results
53
45
  */
54
46
  export class ModelResult {
55
47
  constructor(options) {
@@ -61,6 +53,8 @@ export class ModelResult {
61
53
  this.finalResponse = null;
62
54
  this.preliminaryResults = new Map();
63
55
  this.allToolExecutionRounds = [];
56
+ // Track resolved request after async function resolution
57
+ this.resolvedRequest = null;
64
58
  this.options = options;
65
59
  }
66
60
  /**
@@ -68,11 +62,11 @@ export class ModelResult {
68
62
  */
69
63
  isNonStreamingResponse(value) {
70
64
  return (value !== null &&
71
- typeof value === "object" &&
72
- "id" in value &&
73
- "object" in value &&
74
- "output" in value &&
75
- !("toReadableStream" in value));
65
+ typeof value === 'object' &&
66
+ 'id' in value &&
67
+ 'object' in value &&
68
+ 'output' in value &&
69
+ !('toReadableStream' in value));
76
70
  }
77
71
  /**
78
72
  * Initialize the stream if not already started
@@ -83,16 +77,40 @@ export class ModelResult {
83
77
  return this.initPromise;
84
78
  }
85
79
  this.initPromise = (async () => {
86
- // Force stream mode
87
- const request = {
88
- ...this.options.request,
80
+ // Resolve async functions before initial request
81
+ // Build initial turn context (turn 0 for initial request)
82
+ const initialContext = {
83
+ numberOfTurns: 0,
84
+ };
85
+ // Resolve any async functions first
86
+ let baseRequest;
87
+ if (hasAsyncFunctions(this.options.request)) {
88
+ baseRequest = await resolveAsyncFunctions(this.options.request, initialContext);
89
+ }
90
+ else {
91
+ // Already resolved, extract non-function fields
92
+ // Since request is CallModelInput, we need to filter out stopWhen
93
+ // Note: tools are already in API format at this point (converted in callModel())
94
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
95
+ const { stopWhen, ...rest } = this.options.request;
96
+ // Cast to ResolvedCallModelInput - we know it's resolved if hasAsyncFunctions returned false
97
+ baseRequest = rest;
98
+ }
99
+ // Store resolved request with stream mode
100
+ this.resolvedRequest = {
101
+ ...baseRequest,
89
102
  stream: true,
90
103
  };
104
+ // Force stream mode for initial request
105
+ const request = this.resolvedRequest;
91
106
  // Create the stream promise
92
107
  this.streamPromise = betaResponsesSend(this.options.client, request, this.options.options).then((result) => {
93
108
  if (!result.ok) {
94
109
  throw result.error;
95
110
  }
111
+ // When stream: true, the API returns EventStream
112
+ // TypeScript can't narrow the union type based on runtime parameter values,
113
+ // so we assert the type here based on our knowledge that stream=true
96
114
  return result.value;
97
115
  });
98
116
  // Wait for the stream and create the reusable stream
@@ -112,14 +130,15 @@ export class ModelResult {
112
130
  this.toolExecutionPromise = (async () => {
113
131
  await this.initStream();
114
132
  if (!this.reusableStream) {
115
- throw new Error("Stream not initialized");
133
+ throw new Error('Stream not initialized');
116
134
  }
135
+ // Note: Async functions already resolved in initStream()
117
136
  // Get the initial response
118
137
  const initialResponse = await consumeStreamForCompletion(this.reusableStream);
119
138
  // Check if we have tools and if auto-execution is enabled
120
139
  const shouldAutoExecute = this.options.tools &&
121
140
  this.options.tools.length > 0 &&
122
- initialResponse.output.some((item) => hasTypeProperty(item) && item.type === "function_call");
141
+ initialResponse.output.some((item) => hasTypeProperty(item) && item.type === 'function_call');
123
142
  if (!shouldAutoExecute) {
124
143
  // No tools to execute, use initial response
125
144
  this.finalResponse = initialResponse;
@@ -137,12 +156,34 @@ export class ModelResult {
137
156
  this.finalResponse = initialResponse;
138
157
  return;
139
158
  }
140
- // Get maxToolRounds configuration
141
- const maxToolRounds = this.options.maxToolRounds ?? 5;
142
159
  let currentResponse = initialResponse;
143
160
  let currentRound = 0;
144
- let currentInput = this.options.request.input || [];
145
161
  while (true) {
162
+ // Check stopWhen conditions
163
+ if (this.options.stopWhen) {
164
+ const stopConditions = Array.isArray(this.options.stopWhen)
165
+ ? this.options.stopWhen
166
+ : [this.options.stopWhen];
167
+ const shouldStop = await isStopConditionMet({
168
+ stopConditions,
169
+ steps: this.allToolExecutionRounds.map((round) => ({
170
+ stepType: 'continue',
171
+ text: extractTextFromResponse(round.response),
172
+ toolCalls: round.toolCalls,
173
+ toolResults: round.toolResults.map((tr) => ({
174
+ toolCallId: tr.callId,
175
+ toolName: round.toolCalls.find((tc) => tc.id === tr.callId)?.name ?? '',
176
+ result: JSON.parse(tr.output),
177
+ })),
178
+ response: round.response,
179
+ usage: round.response.usage,
180
+ finishReason: undefined, // OpenResponsesNonStreamingResponse doesn't have finishReason
181
+ })),
182
+ });
183
+ if (shouldStop) {
184
+ break;
185
+ }
186
+ }
146
187
  const currentToolCalls = extractToolCallsFromResponse(currentResponse);
147
188
  if (currentToolCalls.length === 0) {
148
189
  break;
@@ -154,46 +195,19 @@ export class ModelResult {
154
195
  if (!hasExecutable) {
155
196
  break;
156
197
  }
157
- // Check if we should continue based on maxToolRounds
158
- if (typeof maxToolRounds === "number") {
159
- if (currentRound >= maxToolRounds) {
160
- break;
161
- }
162
- }
163
- else if (typeof maxToolRounds === "function") {
164
- // Function signature: (context: TurnContext) => boolean
165
- const turnContext = {
166
- numberOfTurns: currentRound + 1,
167
- messageHistory: currentInput,
168
- ...(this.options.request.model && {
169
- model: this.options.request.model,
170
- }),
171
- ...(this.options.request.models && {
172
- models: this.options.request.models,
173
- }),
174
- };
175
- const shouldContinue = maxToolRounds(turnContext);
176
- if (!shouldContinue) {
177
- break;
178
- }
179
- }
180
- // Store execution round info
181
- this.allToolExecutionRounds.push({
182
- round: currentRound,
183
- toolCalls: currentToolCalls,
184
- response: currentResponse,
185
- });
186
- // Build turn context for tool execution
198
+ // Build turn context for this round (for async parameter resolution only)
187
199
  const turnContext = {
188
200
  numberOfTurns: currentRound + 1, // 1-indexed
189
- messageHistory: currentInput,
190
- ...(this.options.request.model && {
191
- model: this.options.request.model,
192
- }),
193
- ...(this.options.request.models && {
194
- models: this.options.request.models,
195
- }),
196
201
  };
202
+ // Resolve async functions for this turn
203
+ if (hasAsyncFunctions(this.options.request)) {
204
+ const resolved = await resolveAsyncFunctions(this.options.request, turnContext);
205
+ // Update resolved request with new values
206
+ this.resolvedRequest = {
207
+ ...resolved,
208
+ stream: false, // Tool execution turns don't need streaming
209
+ };
210
+ }
197
211
  // Execute all tool calls
198
212
  const toolResults = [];
199
213
  for (const toolCall of currentToolCalls) {
@@ -203,12 +217,11 @@ export class ModelResult {
203
217
  }
204
218
  const result = await executeTool(tool, toolCall, turnContext);
205
219
  // Store preliminary results
206
- if (result.preliminaryResults &&
207
- result.preliminaryResults.length > 0) {
220
+ if (result.preliminaryResults && result.preliminaryResults.length > 0) {
208
221
  this.preliminaryResults.set(toolCall.id, result.preliminaryResults);
209
222
  }
210
223
  toolResults.push({
211
- type: "function_call_output",
224
+ type: 'function_call_output',
212
225
  id: `output_${toolCall.id}`,
213
226
  callId: toolCall.id,
214
227
  output: result.error
@@ -218,19 +231,40 @@ export class ModelResult {
218
231
  : JSON.stringify(result.result),
219
232
  });
220
233
  }
234
+ // Store execution round info including tool results
235
+ this.allToolExecutionRounds.push({
236
+ round: currentRound,
237
+ toolCalls: currentToolCalls,
238
+ response: currentResponse,
239
+ toolResults,
240
+ });
241
+ // Execute nextTurnParams functions for tools that were called
242
+ if (this.options.tools && currentToolCalls.length > 0) {
243
+ if (!this.resolvedRequest) {
244
+ throw new Error('Request not initialized');
245
+ }
246
+ const computedParams = await executeNextTurnParamsFunctions(currentToolCalls, this.options.tools, this.resolvedRequest);
247
+ // Apply computed parameters to the resolved request for next turn
248
+ if (Object.keys(computedParams).length > 0) {
249
+ this.resolvedRequest = applyNextTurnParamsToRequest(this.resolvedRequest, computedParams);
250
+ }
251
+ }
221
252
  // Build new input with tool results
222
253
  // For the Responses API, we need to include the tool results in the input
223
254
  const newInput = [
224
255
  ...(Array.isArray(currentResponse.output)
225
256
  ? currentResponse.output
226
- : [currentResponse.output]),
257
+ : [
258
+ currentResponse.output,
259
+ ]),
227
260
  ...toolResults,
228
261
  ];
229
- // Update current input for next iteration
230
- currentInput = newInput;
231
262
  // Make new request with tool results
263
+ if (!this.resolvedRequest) {
264
+ throw new Error('Request not initialized');
265
+ }
232
266
  const newRequest = {
233
- ...this.options.request,
267
+ ...this.resolvedRequest,
234
268
  input: newInput,
235
269
  stream: false,
236
270
  };
@@ -249,18 +283,17 @@ export class ModelResult {
249
283
  currentResponse = value;
250
284
  }
251
285
  else {
252
- throw new Error("Unexpected response type from API");
286
+ throw new Error('Unexpected response type from API');
253
287
  }
254
288
  currentRound++;
255
289
  }
256
290
  // Validate the final response has required fields
257
291
  if (!currentResponse || !currentResponse.id || !currentResponse.output) {
258
- throw new Error("Invalid final response: missing required fields");
292
+ throw new Error('Invalid final response: missing required fields');
259
293
  }
260
294
  // Ensure the response is in a completed state (has output content)
261
- if (!Array.isArray(currentResponse.output) ||
262
- currentResponse.output.length === 0) {
263
- throw new Error("Invalid final response: empty or invalid output");
295
+ if (!Array.isArray(currentResponse.output) || currentResponse.output.length === 0) {
296
+ throw new Error('Invalid final response: empty or invalid output');
264
297
  }
265
298
  this.finalResponse = currentResponse;
266
299
  })();
@@ -272,7 +305,7 @@ export class ModelResult {
272
305
  async getTextInternal() {
273
306
  await this.executeToolsIfNeeded();
274
307
  if (!this.finalResponse) {
275
- throw new Error("Response not available");
308
+ throw new Error('Response not available');
276
309
  }
277
310
  return extractTextFromResponse(this.finalResponse);
278
311
  }
@@ -295,7 +328,7 @@ export class ModelResult {
295
328
  async getResponse() {
296
329
  await this.executeToolsIfNeeded();
297
330
  if (!this.finalResponse) {
298
- throw new Error("Response not available");
331
+ throw new Error('Response not available');
299
332
  }
300
333
  return this.finalResponse;
301
334
  }
@@ -308,7 +341,7 @@ export class ModelResult {
308
341
  return async function* () {
309
342
  await this.initStream();
310
343
  if (!this.reusableStream) {
311
- throw new Error("Stream not initialized");
344
+ throw new Error('Stream not initialized');
312
345
  }
313
346
  const consumer = this.reusableStream.createConsumer();
314
347
  // Yield original events directly
@@ -321,9 +354,9 @@ export class ModelResult {
321
354
  for (const [toolCallId, results] of this.preliminaryResults) {
322
355
  for (const result of results) {
323
356
  yield {
324
- type: "tool.preliminary_result",
357
+ type: 'tool.preliminary_result',
325
358
  toolCallId,
326
- result,
359
+ result: result,
327
360
  timestamp: Date.now(),
328
361
  };
329
362
  }
@@ -338,7 +371,7 @@ export class ModelResult {
338
371
  return async function* () {
339
372
  await this.initStream();
340
373
  if (!this.reusableStream) {
341
- throw new Error("Stream not initialized");
374
+ throw new Error('Stream not initialized');
342
375
  }
343
376
  yield* extractTextDeltas(this.reusableStream);
344
377
  }.call(this);
@@ -353,38 +386,22 @@ export class ModelResult {
353
386
  return async function* () {
354
387
  await this.initStream();
355
388
  if (!this.reusableStream) {
356
- throw new Error("Stream not initialized");
389
+ throw new Error('Stream not initialized');
357
390
  }
358
391
  // First yield messages from the stream in responses format
359
392
  yield* buildResponsesMessageStream(this.reusableStream);
360
393
  // Execute tools if needed
361
394
  await this.executeToolsIfNeeded();
362
- // Yield function call output for each executed tool
395
+ // Yield function call outputs for each executed tool
363
396
  for (const round of this.allToolExecutionRounds) {
364
- for (const toolCall of round.toolCalls) {
365
- // Find the tool to check if it was executed
366
- const tool = this.options.tools?.find((t) => t.function.name === toolCall.name);
367
- if (!tool || !hasExecuteFunction(tool)) {
368
- continue;
369
- }
370
- // Get the result from preliminary results or construct from the response
371
- const prelimResults = this.preliminaryResults.get(toolCall.id);
372
- const result = prelimResults && prelimResults.length > 0
373
- ? prelimResults[prelimResults.length - 1] // Last result is the final output
374
- : undefined;
375
- // Yield function call output in responses format
376
- yield {
377
- type: "function_call_output",
378
- id: `output_${toolCall.id}`,
379
- callId: toolCall.id,
380
- output: result !== undefined ? JSON.stringify(result) : "",
381
- };
397
+ for (const toolResult of round.toolResults) {
398
+ yield toolResult;
382
399
  }
383
400
  }
384
401
  // If tools were executed, yield the final message (if there is one)
385
402
  if (this.finalResponse && this.allToolExecutionRounds.length > 0) {
386
403
  // Check if the final response contains a message
387
- const hasMessage = this.finalResponse.output.some((item) => hasTypeProperty(item) && item.type === "message");
404
+ const hasMessage = this.finalResponse.output.some((item) => hasTypeProperty(item) && item.type === 'message');
388
405
  if (hasMessage) {
389
406
  yield extractResponsesMessageFromResponse(this.finalResponse);
390
407
  }
@@ -399,7 +416,7 @@ export class ModelResult {
399
416
  return async function* () {
400
417
  await this.initStream();
401
418
  if (!this.reusableStream) {
402
- throw new Error("Stream not initialized");
419
+ throw new Error('Stream not initialized');
403
420
  }
404
421
  yield* extractReasoningDeltas(this.reusableStream);
405
422
  }.call(this);
@@ -414,12 +431,12 @@ export class ModelResult {
414
431
  return async function* () {
415
432
  await this.initStream();
416
433
  if (!this.reusableStream) {
417
- throw new Error("Stream not initialized");
434
+ throw new Error('Stream not initialized');
418
435
  }
419
436
  // Yield tool deltas as structured events
420
437
  for await (const delta of extractToolDeltas(this.reusableStream)) {
421
438
  yield {
422
- type: "delta",
439
+ type: 'delta',
423
440
  content: delta,
424
441
  };
425
442
  }
@@ -429,65 +446,9 @@ export class ModelResult {
429
446
  for (const [toolCallId, results] of this.preliminaryResults) {
430
447
  for (const result of results) {
431
448
  yield {
432
- type: "preliminary_result",
433
- toolCallId,
434
- result,
435
- };
436
- }
437
- }
438
- }.call(this);
439
- }
440
- /**
441
- * Stream events in chat format (compatibility layer).
442
- * Note: This transforms responses API events into a chat-like format.
443
- * Includes preliminary tool result events after tool execution.
444
- *
445
- * @remarks
446
- * This is a compatibility method that attempts to transform the responses API
447
- * stream into a format similar to the chat API. Due to differences in the APIs,
448
- * this may not be a perfect mapping.
449
- */
450
- getFullChatStream() {
451
- return async function* () {
452
- await this.initStream();
453
- if (!this.reusableStream) {
454
- throw new Error("Stream not initialized");
455
- }
456
- const consumer = this.reusableStream.createConsumer();
457
- for await (const event of consumer) {
458
- if (!("type" in event)) {
459
- continue;
460
- }
461
- // Transform responses events to chat-like format using type guards
462
- if (isOutputTextDeltaEvent(event)) {
463
- yield {
464
- type: "content.delta",
465
- delta: event.delta,
466
- };
467
- }
468
- else if (isResponseCompletedEvent(event)) {
469
- yield {
470
- type: "message.complete",
471
- response: event.response,
472
- };
473
- }
474
- else {
475
- // Pass through other events
476
- yield {
477
- type: event.type,
478
- event,
479
- };
480
- }
481
- }
482
- // After stream completes, check if tools were executed and emit preliminary results
483
- await this.executeToolsIfNeeded();
484
- // Emit all preliminary results
485
- for (const [toolCallId, results] of this.preliminaryResults) {
486
- for (const result of results) {
487
- yield {
488
- type: "tool.preliminary_result",
449
+ type: 'preliminary_result',
489
450
  toolCallId,
490
- result,
451
+ result: result,
491
452
  };
492
453
  }
493
454
  }
@@ -502,7 +463,7 @@ export class ModelResult {
502
463
  async getToolCalls() {
503
464
  await this.initStream();
504
465
  if (!this.reusableStream) {
505
- throw new Error("Stream not initialized");
466
+ throw new Error('Stream not initialized');
506
467
  }
507
468
  const completedResponse = await consumeStreamForCompletion(this.reusableStream);
508
469
  return extractToolCallsFromResponse(completedResponse);
@@ -515,7 +476,7 @@ export class ModelResult {
515
476
  return async function* () {
516
477
  await this.initStream();
517
478
  if (!this.reusableStream) {
518
- throw new Error("Stream not initialized");
479
+ throw new Error('Stream not initialized');
519
480
  }
520
481
  yield* buildToolCallStream(this.reusableStream);
521
482
  }.call(this);
@@ -0,0 +1,30 @@
1
+ import type * as models from '../models/index.js';
2
+ import type { NextTurnParamsContext, ParsedToolCall, Tool } from './tool-types.js';
3
+ /**
4
+ * Build a NextTurnParamsContext from the current request
5
+ * Extracts relevant fields that can be modified by nextTurnParams functions
6
+ *
7
+ * @param request - The current OpenResponsesRequest
8
+ * @returns Context object with current parameter values
9
+ */
10
+ export declare function buildNextTurnParamsContext(request: models.OpenResponsesRequest): NextTurnParamsContext;
11
+ /**
12
+ * Execute nextTurnParams functions for all called tools
13
+ * Composes functions when multiple tools modify the same parameter
14
+ *
15
+ * @param toolCalls - Tool calls that were executed in this turn
16
+ * @param tools - All available tools
17
+ * @param currentRequest - The current request
18
+ * @returns Object with computed parameter values
19
+ */
20
+ export declare function executeNextTurnParamsFunctions(toolCalls: ParsedToolCall<Tool>[], tools: readonly Tool[], currentRequest: models.OpenResponsesRequest): Promise<Partial<NextTurnParamsContext>>;
21
+ /**
22
+ * Apply computed nextTurnParams to the current request
23
+ * Returns a new request object with updated parameters
24
+ *
25
+ * @param request - The current request
26
+ * @param computedParams - Computed parameter values from nextTurnParams functions
27
+ * @returns New request with updated parameters
28
+ */
29
+ export declare function applyNextTurnParamsToRequest(request: models.OpenResponsesRequest, computedParams: Partial<NextTurnParamsContext>): models.OpenResponsesRequest;
30
+ //# sourceMappingURL=next-turn-params.d.ts.map