@openrouter/sdk 0.1.27 → 0.2.9

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 (146) hide show
  1. package/biome.json +171 -0
  2. package/esm/funcs/callModel.d.ts +7 -7
  3. package/esm/funcs/callModel.js +35 -23
  4. package/esm/funcs/embeddingsGenerate.js +2 -4
  5. package/esm/funcs/oAuthCreateAuthorizationUrl.d.ts +3 -3
  6. package/esm/funcs/oAuthCreateAuthorizationUrl.js +30 -14
  7. package/esm/funcs/oAuthCreateSHA256CodeChallenge.d.ts +2 -2
  8. package/esm/funcs/oAuthCreateSHA256CodeChallenge.js +13 -12
  9. package/esm/hooks/registration.d.ts +2 -2
  10. package/esm/hooks/registration.js +1 -2
  11. package/esm/lib/config.d.ts +3 -3
  12. package/esm/lib/config.js +3 -3
  13. package/esm/lib/encodings.d.ts +1 -0
  14. package/esm/lib/encodings.js +12 -1
  15. package/esm/lib/response-wrapper.d.ts +17 -5
  16. package/esm/lib/response-wrapper.js +119 -68
  17. package/esm/lib/reusable-stream.js +26 -7
  18. package/esm/lib/stream-transformers.d.ts +3 -3
  19. package/esm/lib/stream-transformers.js +43 -41
  20. package/esm/lib/tool-executor.d.ts +9 -9
  21. package/esm/lib/tool-executor.js +9 -9
  22. package/esm/lib/tool-orchestrator.d.ts +3 -3
  23. package/esm/lib/tool-orchestrator.js +39 -19
  24. package/esm/lib/tool-types.d.ts +26 -25
  25. package/esm/lib/tool-types.js +3 -3
  26. package/esm/models/chatcompletionfinishreason.d.ts +13 -0
  27. package/esm/models/chatcompletionfinishreason.js +14 -0
  28. package/esm/models/chatgenerationparams.d.ts +16 -4
  29. package/esm/models/chatgenerationparams.js +16 -4
  30. package/esm/models/chatmessagecontentitem.d.ts +2 -19
  31. package/esm/models/chatmessagecontentitem.js +6 -9
  32. package/esm/models/chatmessagecontentitemaudio.d.ts +1 -16
  33. package/esm/models/chatmessagecontentitemaudio.js +2 -16
  34. package/esm/models/chatmessagecontentitemcachecontrol.d.ts +29 -0
  35. package/esm/models/chatmessagecontentitemcachecontrol.js +33 -0
  36. package/esm/models/chatmessagecontentitemtext.d.ts +3 -0
  37. package/esm/models/chatmessagecontentitemtext.js +12 -0
  38. package/esm/models/chatmessagecontentitemvideo.d.ts +23 -11
  39. package/esm/models/chatmessagecontentitemvideo.js +24 -11
  40. package/esm/models/chatresponsechoice.d.ts +1 -21
  41. package/esm/models/chatresponsechoice.js +1 -25
  42. package/esm/models/chatstreamingchoice.d.ts +16 -0
  43. package/esm/models/chatstreamingchoice.js +24 -0
  44. package/esm/models/chatstreamingresponsechunk.d.ts +1 -1
  45. package/esm/models/chatstreamingresponsechunk.js +1 -1
  46. package/esm/models/completionchoice.d.ts +2 -0
  47. package/esm/models/completionchoice.js +3 -0
  48. package/esm/models/completioncreateparams.d.ts +4 -4
  49. package/esm/models/completioncreateparams.js +4 -4
  50. package/esm/models/completionresponse.d.ts +1 -0
  51. package/esm/models/completionresponse.js +1 -0
  52. package/esm/models/filecitation.d.ts +2 -11
  53. package/esm/models/filecitation.js +2 -9
  54. package/esm/models/filepath.d.ts +2 -11
  55. package/esm/models/filepath.js +2 -10
  56. package/esm/models/index.d.ts +3 -2
  57. package/esm/models/index.js +3 -2
  58. package/esm/models/message.d.ts +2 -2
  59. package/esm/models/message.js +1 -1
  60. package/esm/models/openairesponsesannotation.d.ts +2 -2
  61. package/esm/models/openairesponsesannotation.js +2 -2
  62. package/esm/models/openairesponsesinputunion.d.ts +5 -45
  63. package/esm/models/openairesponsesinputunion.js +20 -20
  64. package/esm/models/openairesponsesrefusalcontent.d.ts +2 -11
  65. package/esm/models/openairesponsesrefusalcontent.js +2 -9
  66. package/esm/models/openresponseseasyinputmessage.d.ts +6 -54
  67. package/esm/models/openresponseseasyinputmessage.js +12 -12
  68. package/esm/models/openresponseserrorevent.d.ts +1 -8
  69. package/esm/models/openresponseserrorevent.js +1 -6
  70. package/esm/models/openresponsesimagegencallcompleted.d.ts +1 -8
  71. package/esm/models/openresponsesimagegencallcompleted.js +1 -6
  72. package/esm/models/openresponsesimagegencallgenerating.d.ts +1 -8
  73. package/esm/models/openresponsesimagegencallgenerating.js +1 -6
  74. package/esm/models/openresponsesimagegencallinprogress.d.ts +1 -8
  75. package/esm/models/openresponsesimagegencallinprogress.js +1 -6
  76. package/esm/models/openresponsesimagegencallpartialimage.d.ts +1 -8
  77. package/esm/models/openresponsesimagegencallpartialimage.js +1 -6
  78. package/esm/models/openresponsesinputmessageitem.d.ts +4 -36
  79. package/esm/models/openresponsesinputmessageitem.js +8 -8
  80. package/esm/models/openresponsesnonstreamingresponse.d.ts +1 -7
  81. package/esm/models/openresponsesnonstreamingresponse.js +1 -6
  82. package/esm/models/openresponsesreasoningdeltaevent.d.ts +1 -8
  83. package/esm/models/openresponsesreasoningdeltaevent.js +1 -6
  84. package/esm/models/openresponsesreasoningdoneevent.d.ts +1 -8
  85. package/esm/models/openresponsesreasoningdoneevent.js +1 -6
  86. package/esm/models/openresponsesreasoningsummarypartaddedevent.d.ts +1 -8
  87. package/esm/models/openresponsesreasoningsummarypartaddedevent.js +1 -6
  88. package/esm/models/openresponsesreasoningsummarytextdeltaevent.d.ts +1 -8
  89. package/esm/models/openresponsesreasoningsummarytextdeltaevent.js +1 -6
  90. package/esm/models/openresponsesreasoningsummarytextdoneevent.d.ts +1 -8
  91. package/esm/models/openresponsesreasoningsummarytextdoneevent.js +1 -6
  92. package/esm/models/openresponsesrequest.d.ts +26 -44
  93. package/esm/models/openresponsesrequest.js +15 -32
  94. package/esm/models/openresponsesstreamevent.d.ts +30 -125
  95. package/esm/models/openresponsesstreamevent.js +34 -119
  96. package/esm/models/openresponseswebsearch20250826tool.d.ts +2 -11
  97. package/esm/models/openresponseswebsearch20250826tool.js +2 -9
  98. package/esm/models/openresponseswebsearchpreview20250311tool.d.ts +2 -11
  99. package/esm/models/openresponseswebsearchpreview20250311tool.js +2 -9
  100. package/esm/models/openresponseswebsearchpreviewtool.d.ts +2 -11
  101. package/esm/models/openresponseswebsearchpreviewtool.js +2 -9
  102. package/esm/models/openresponseswebsearchtool.d.ts +2 -11
  103. package/esm/models/openresponseswebsearchtool.js +2 -9
  104. package/esm/models/operations/createembeddings.d.ts +5 -21
  105. package/esm/models/operations/createembeddings.js +3 -22
  106. package/esm/models/operations/getcredits.d.ts +16 -1
  107. package/esm/models/operations/getcredits.js +17 -1
  108. package/esm/models/operations/getparameters.d.ts +5 -1
  109. package/esm/models/operations/getparameters.js +5 -1
  110. package/esm/models/providername.d.ts +5 -1
  111. package/esm/models/providername.js +5 -1
  112. package/esm/models/responseformattextconfig.d.ts +2 -2
  113. package/esm/models/responseformattextconfig.js +2 -2
  114. package/esm/models/responseinputaudio.d.ts +3 -11
  115. package/esm/models/responseinputaudio.js +2 -9
  116. package/esm/models/responseinputfile.d.ts +2 -11
  117. package/esm/models/responseinputfile.js +2 -9
  118. package/esm/models/responseinputimage.d.ts +3 -11
  119. package/esm/models/responseinputimage.js +2 -9
  120. package/esm/models/responseinputtext.d.ts +2 -11
  121. package/esm/models/responseinputtext.js +2 -9
  122. package/esm/models/responseoutputtext.d.ts +2 -11
  123. package/esm/models/responseoutputtext.js +2 -9
  124. package/esm/models/responsesformatjsonobject.d.ts +2 -11
  125. package/esm/models/responsesformatjsonobject.js +2 -9
  126. package/esm/models/responsesformattext.d.ts +2 -11
  127. package/esm/models/responsesformattext.js +2 -9
  128. package/esm/models/responsesformattextjsonschemaconfig.d.ts +2 -11
  129. package/esm/models/responsesformattextjsonschemaconfig.js +2 -9
  130. package/esm/models/responsesoutputitem.d.ts +13 -1
  131. package/esm/models/responsesoutputitem.js +6 -6
  132. package/esm/models/urlcitation.d.ts +2 -11
  133. package/esm/models/urlcitation.js +2 -9
  134. package/esm/sdk/oauth.d.ts +2 -2
  135. package/esm/sdk/oauth.js +2 -3
  136. package/esm/sdk/sdk.d.ts +9 -8
  137. package/esm/types/unrecognized.d.ts +7 -1
  138. package/esm/types/unrecognized.js +9 -1
  139. package/jsr.json +1 -1
  140. package/package.json +1 -1
  141. package/tsconfig.json +0 -1
  142. package/vitest.config.ts +14 -8
  143. package/esm/models/chatmessagecontentitemfile.d.ts +0 -36
  144. package/esm/models/chatmessagecontentitemfile.js +0 -51
  145. package/esm/models/videourl.d.ts +0 -17
  146. package/esm/models/videourl.js +0 -21
@@ -1,8 +1,8 @@
1
- import { betaResponsesSend } from "../funcs/betaResponsesSend.js";
2
- import { ReusableReadableStream } from "./reusable-stream.js";
3
- import { extractTextDeltas, extractReasoningDeltas, extractToolDeltas, buildMessageStream, consumeStreamForCompletion, extractMessageFromResponse, extractTextFromResponse, extractToolCallsFromResponse, buildToolCallStream, } from "./stream-transformers.js";
4
- import { hasExecuteFunction, } from "./tool-types.js";
5
- import { executeTool, } from "./tool-executor.js";
1
+ import { betaResponsesSend } from '../funcs/betaResponsesSend.js';
2
+ import { ReusableReadableStream } from './reusable-stream.js';
3
+ import { buildMessageStream, buildToolCallStream, consumeStreamForCompletion, extractMessageFromResponse, extractReasoningDeltas, extractTextDeltas, extractTextFromResponse, extractToolCallsFromResponse, extractToolDeltas, } from './stream-transformers.js';
4
+ import { executeTool } from './tool-executor.js';
5
+ import { hasExecuteFunction } from './tool-types.js';
6
6
  /**
7
7
  * A wrapper around a streaming response that provides multiple consumption patterns.
8
8
  *
@@ -29,6 +29,17 @@ export class ResponseWrapper {
29
29
  this.allToolExecutionRounds = [];
30
30
  this.options = options;
31
31
  }
32
+ /**
33
+ * Type guard to check if a value is a non-streaming response
34
+ */
35
+ isNonStreamingResponse(value) {
36
+ return (value !== null &&
37
+ typeof value === "object" &&
38
+ "id" in value &&
39
+ "object" in value &&
40
+ "output" in value &&
41
+ !("toReadableStream" in value));
42
+ }
32
43
  /**
33
44
  * Initialize the stream if not already started
34
45
  * This is idempotent - multiple calls will return the same promise
@@ -39,7 +50,10 @@ export class ResponseWrapper {
39
50
  }
40
51
  this.initPromise = (async () => {
41
52
  // Force stream mode
42
- const request = { ...this.options.request, stream: true };
53
+ const request = {
54
+ ...this.options.request,
55
+ stream: true,
56
+ };
43
57
  // Create the stream promise
44
58
  this.streamPromise = betaResponsesSend(this.options.client, request, this.options.options).then((result) => {
45
59
  if (!result.ok) {
@@ -64,14 +78,14 @@ export class ResponseWrapper {
64
78
  this.toolExecutionPromise = (async () => {
65
79
  await this.initStream();
66
80
  if (!this.reusableStream) {
67
- throw new Error("Stream not initialized");
81
+ throw new Error('Stream not initialized');
68
82
  }
69
83
  // Get the initial response
70
84
  const initialResponse = await consumeStreamForCompletion(this.reusableStream);
71
85
  // Check if we have tools and if auto-execution is enabled
72
86
  const shouldAutoExecute = this.options.tools &&
73
87
  this.options.tools.length > 0 &&
74
- initialResponse.output.some((item) => "type" in item && item.type === "function_call");
88
+ initialResponse.output.some((item) => 'type' in item && item.type === 'function_call');
75
89
  if (!shouldAutoExecute) {
76
90
  // No tools to execute, use initial response
77
91
  this.finalResponse = initialResponse;
@@ -107,18 +121,22 @@ export class ResponseWrapper {
107
121
  break;
108
122
  }
109
123
  // Check if we should continue based on maxToolRounds
110
- if (typeof maxToolRounds === "number") {
124
+ if (typeof maxToolRounds === 'number') {
111
125
  if (currentRound >= maxToolRounds) {
112
126
  break;
113
127
  }
114
128
  }
115
- else if (typeof maxToolRounds === "function") {
129
+ else if (typeof maxToolRounds === 'function') {
116
130
  // Function signature: (context: TurnContext) => boolean
117
131
  const turnContext = {
118
132
  numberOfTurns: currentRound + 1,
119
133
  messageHistory: currentInput,
120
- ...(this.options.request.model && { model: this.options.request.model }),
121
- ...(this.options.request.models && { models: this.options.request.models }),
134
+ ...(this.options.request.model && {
135
+ model: this.options.request.model,
136
+ }),
137
+ ...(this.options.request.models && {
138
+ models: this.options.request.models,
139
+ }),
122
140
  };
123
141
  const shouldContinue = maxToolRounds(turnContext);
124
142
  if (!shouldContinue) {
@@ -135,8 +153,12 @@ export class ResponseWrapper {
135
153
  const turnContext = {
136
154
  numberOfTurns: currentRound + 1, // 1-indexed
137
155
  messageHistory: currentInput,
138
- ...(this.options.request.model && { model: this.options.request.model }),
139
- ...(this.options.request.models && { models: this.options.request.models }),
156
+ ...(this.options.request.model && {
157
+ model: this.options.request.model,
158
+ }),
159
+ ...(this.options.request.models && {
160
+ models: this.options.request.models,
161
+ }),
140
162
  };
141
163
  // Execute all tool calls
142
164
  const toolResults = [];
@@ -151,18 +173,24 @@ export class ResponseWrapper {
151
173
  this.preliminaryResults.set(toolCall.id, result.preliminaryResults);
152
174
  }
153
175
  toolResults.push({
154
- type: "function_call_output",
176
+ type: 'function_call_output',
155
177
  id: `output_${toolCall.id}`,
156
178
  callId: toolCall.id,
157
179
  output: result.error
158
- ? JSON.stringify({ error: result.error.message })
180
+ ? JSON.stringify({
181
+ error: result.error.message,
182
+ })
159
183
  : JSON.stringify(result.result),
160
184
  });
161
185
  }
162
186
  // Build new input with tool results
163
187
  // For the Responses API, we need to include the tool results in the input
164
188
  const newInput = [
165
- ...(Array.isArray(currentResponse.output) ? currentResponse.output : [currentResponse.output]),
189
+ ...(Array.isArray(currentResponse.output)
190
+ ? currentResponse.output
191
+ : [
192
+ currentResponse.output,
193
+ ]),
166
194
  ...toolResults,
167
195
  ];
168
196
  // Update current input for next iteration
@@ -179,20 +207,51 @@ export class ResponseWrapper {
179
207
  }
180
208
  // Handle the result - it might be a stream or a response
181
209
  const value = newResult.value;
182
- if (value && typeof value === "object" && "toReadableStream" in value) {
210
+ if (value && typeof value === 'object' && 'toReadableStream' in value) {
183
211
  // It's a stream, consume it
184
212
  const stream = new ReusableReadableStream(value);
185
213
  currentResponse = await consumeStreamForCompletion(stream);
186
214
  }
187
- else {
215
+ else if (this.isNonStreamingResponse(value)) {
188
216
  currentResponse = value;
189
217
  }
218
+ else {
219
+ throw new Error("Unexpected response type from API");
220
+ }
190
221
  currentRound++;
191
222
  }
223
+ // Validate the final response has required fields
224
+ if (!currentResponse || !currentResponse.id || !currentResponse.output) {
225
+ throw new Error("Invalid final response: missing required fields");
226
+ }
227
+ // Ensure the response is in a completed state (has output content)
228
+ if (!Array.isArray(currentResponse.output) || currentResponse.output.length === 0) {
229
+ throw new Error("Invalid final response: empty or invalid output");
230
+ }
192
231
  this.finalResponse = currentResponse;
193
232
  })();
194
233
  return this.toolExecutionPromise;
195
234
  }
235
+ /**
236
+ * Internal helper to get the message after tool execution
237
+ */
238
+ async getMessageInternal() {
239
+ await this.executeToolsIfNeeded();
240
+ if (!this.finalResponse) {
241
+ throw new Error("Response not available");
242
+ }
243
+ return extractMessageFromResponse(this.finalResponse);
244
+ }
245
+ /**
246
+ * Internal helper to get the text after tool execution
247
+ */
248
+ async getTextInternal() {
249
+ await this.executeToolsIfNeeded();
250
+ if (!this.finalResponse) {
251
+ throw new Error("Response not available");
252
+ }
253
+ return extractTextFromResponse(this.finalResponse);
254
+ }
196
255
  /**
197
256
  * Get the completed message from the response.
198
257
  * This will consume the stream until completion, execute any tools, and extract the first message.
@@ -202,13 +261,7 @@ export class ResponseWrapper {
202
261
  if (this.messagePromise) {
203
262
  return this.messagePromise;
204
263
  }
205
- this.messagePromise = (async () => {
206
- await this.executeToolsIfNeeded();
207
- if (!this.finalResponse) {
208
- throw new Error("Response not available");
209
- }
210
- return extractMessageFromResponse(this.finalResponse);
211
- })();
264
+ this.messagePromise = this.getMessageInternal();
212
265
  return this.messagePromise;
213
266
  }
214
267
  /**
@@ -219,13 +272,7 @@ export class ResponseWrapper {
219
272
  if (this.textPromise) {
220
273
  return this.textPromise;
221
274
  }
222
- this.textPromise = (async () => {
223
- await this.executeToolsIfNeeded();
224
- if (!this.finalResponse) {
225
- throw new Error("Response not available");
226
- }
227
- return extractTextFromResponse(this.finalResponse);
228
- })();
275
+ this.textPromise = this.getTextInternal();
229
276
  return this.textPromise;
230
277
  }
231
278
  /**
@@ -236,7 +283,7 @@ export class ResponseWrapper {
236
283
  async getResponse() {
237
284
  await this.executeToolsIfNeeded();
238
285
  if (!this.finalResponse) {
239
- throw new Error("Response not available");
286
+ throw new Error('Response not available');
240
287
  }
241
288
  return this.finalResponse;
242
289
  }
@@ -246,10 +293,10 @@ export class ResponseWrapper {
246
293
  * Includes preliminary tool result events after tool execution.
247
294
  */
248
295
  getFullResponsesStream() {
249
- return (async function* () {
296
+ return async function* () {
250
297
  await this.initStream();
251
298
  if (!this.reusableStream) {
252
- throw new Error("Stream not initialized");
299
+ throw new Error('Stream not initialized');
253
300
  }
254
301
  const consumer = this.reusableStream.createConsumer();
255
302
  // Yield original events directly
@@ -262,27 +309,27 @@ export class ResponseWrapper {
262
309
  for (const [toolCallId, results] of this.preliminaryResults) {
263
310
  for (const result of results) {
264
311
  yield {
265
- type: "tool.preliminary_result",
312
+ type: 'tool.preliminary_result',
266
313
  toolCallId,
267
314
  result,
268
315
  timestamp: Date.now(),
269
316
  };
270
317
  }
271
318
  }
272
- }.call(this));
319
+ }.call(this);
273
320
  }
274
321
  /**
275
322
  * Stream only text deltas as they arrive.
276
323
  * This filters the full event stream to only yield text content.
277
324
  */
278
325
  getTextStream() {
279
- return (async function* () {
326
+ return async function* () {
280
327
  await this.initStream();
281
328
  if (!this.reusableStream) {
282
- throw new Error("Stream not initialized");
329
+ throw new Error('Stream not initialized');
283
330
  }
284
331
  yield* extractTextDeltas(this.reusableStream);
285
- }.call(this));
332
+ }.call(this);
286
333
  }
287
334
  /**
288
335
  * Stream incremental message updates as content is added.
@@ -291,10 +338,10 @@ export class ResponseWrapper {
291
338
  * Returns AssistantMessage or ToolResponseMessage in chat format.
292
339
  */
293
340
  getNewMessagesStream() {
294
- return (async function* () {
341
+ return async function* () {
295
342
  await this.initStream();
296
343
  if (!this.reusableStream) {
297
- throw new Error("Stream not initialized");
344
+ throw new Error('Stream not initialized');
298
345
  }
299
346
  // First yield assistant messages from the stream
300
347
  yield* buildMessageStream(this.reusableStream);
@@ -315,8 +362,8 @@ export class ResponseWrapper {
315
362
  : undefined;
316
363
  // Yield tool response message
317
364
  yield {
318
- role: "tool",
319
- content: result !== undefined ? JSON.stringify(result) : "",
365
+ role: 'tool',
366
+ content: result !== undefined ? JSON.stringify(result) : '',
320
367
  toolCallId: toolCall.id,
321
368
  };
322
369
  }
@@ -324,25 +371,25 @@ export class ResponseWrapper {
324
371
  // If tools were executed, yield the final assistant message (if there is one)
325
372
  if (this.finalResponse && this.allToolExecutionRounds.length > 0) {
326
373
  // Check if the final response contains a message
327
- const hasMessage = this.finalResponse.output.some((item) => "type" in item && item.type === "message");
374
+ const hasMessage = this.finalResponse.output.some((item) => 'type' in item && item.type === 'message');
328
375
  if (hasMessage) {
329
376
  yield extractMessageFromResponse(this.finalResponse);
330
377
  }
331
378
  }
332
- }.call(this));
379
+ }.call(this);
333
380
  }
334
381
  /**
335
382
  * Stream only reasoning deltas as they arrive.
336
383
  * This filters the full event stream to only yield reasoning content.
337
384
  */
338
385
  getReasoningStream() {
339
- return (async function* () {
386
+ return async function* () {
340
387
  await this.initStream();
341
388
  if (!this.reusableStream) {
342
- throw new Error("Stream not initialized");
389
+ throw new Error('Stream not initialized');
343
390
  }
344
391
  yield* extractReasoningDeltas(this.reusableStream);
345
- }.call(this));
392
+ }.call(this);
346
393
  }
347
394
  /**
348
395
  * Stream tool call argument deltas and preliminary results.
@@ -351,14 +398,17 @@ export class ResponseWrapper {
351
398
  * - Preliminary results as { type: "preliminary_result", toolCallId, result }
352
399
  */
353
400
  getToolStream() {
354
- return (async function* () {
401
+ return async function* () {
355
402
  await this.initStream();
356
403
  if (!this.reusableStream) {
357
- throw new Error("Stream not initialized");
404
+ throw new Error('Stream not initialized');
358
405
  }
359
406
  // Yield tool deltas as structured events
360
407
  for await (const delta of extractToolDeltas(this.reusableStream)) {
361
- yield { type: "delta", content: delta };
408
+ yield {
409
+ type: 'delta',
410
+ content: delta,
411
+ };
362
412
  }
363
413
  // After stream completes, check if tools were executed and emit preliminary results
364
414
  await this.executeToolsIfNeeded();
@@ -366,13 +416,13 @@ export class ResponseWrapper {
366
416
  for (const [toolCallId, results] of this.preliminaryResults) {
367
417
  for (const result of results) {
368
418
  yield {
369
- type: "preliminary_result",
419
+ type: 'preliminary_result',
370
420
  toolCallId,
371
421
  result,
372
422
  };
373
423
  }
374
424
  }
375
- }.call(this));
425
+ }.call(this);
376
426
  }
377
427
  /**
378
428
  * Stream events in chat format (compatibility layer).
@@ -385,28 +435,29 @@ export class ResponseWrapper {
385
435
  * this may not be a perfect mapping.
386
436
  */
387
437
  getFullChatStream() {
388
- return (async function* () {
438
+ return async function* () {
389
439
  await this.initStream();
390
440
  if (!this.reusableStream) {
391
- throw new Error("Stream not initialized");
441
+ throw new Error('Stream not initialized');
392
442
  }
393
443
  const consumer = this.reusableStream.createConsumer();
394
444
  for await (const event of consumer) {
395
- if (!("type" in event))
445
+ if (!('type' in event)) {
396
446
  continue;
447
+ }
397
448
  // Transform responses events to chat-like format
398
449
  // This is a simplified transformation - you may need to adjust based on your needs
399
- if (event.type === "response.output_text.delta") {
450
+ if (event.type === 'response.output_text.delta') {
400
451
  const deltaEvent = event;
401
452
  yield {
402
- type: "content.delta",
453
+ type: 'content.delta',
403
454
  delta: deltaEvent.delta,
404
455
  };
405
456
  }
406
- else if (event.type === "response.completed") {
457
+ else if (event.type === 'response.completed') {
407
458
  const completedEvent = event;
408
459
  yield {
409
- type: "message.complete",
460
+ type: 'message.complete',
410
461
  response: completedEvent.response,
411
462
  };
412
463
  }
@@ -424,13 +475,13 @@ export class ResponseWrapper {
424
475
  for (const [toolCallId, results] of this.preliminaryResults) {
425
476
  for (const result of results) {
426
477
  yield {
427
- type: "tool.preliminary_result",
478
+ type: 'tool.preliminary_result',
428
479
  toolCallId,
429
480
  result,
430
481
  };
431
482
  }
432
483
  }
433
- }.call(this));
484
+ }.call(this);
434
485
  }
435
486
  /**
436
487
  * Get all tool calls from the completed response (before auto-execution).
@@ -441,7 +492,7 @@ export class ResponseWrapper {
441
492
  async getToolCalls() {
442
493
  await this.initStream();
443
494
  if (!this.reusableStream) {
444
- throw new Error("Stream not initialized");
495
+ throw new Error('Stream not initialized');
445
496
  }
446
497
  const completedResponse = await consumeStreamForCompletion(this.reusableStream);
447
498
  return extractToolCallsFromResponse(completedResponse);
@@ -451,13 +502,13 @@ export class ResponseWrapper {
451
502
  * Each iteration yields a complete tool call with parsed arguments.
452
503
  */
453
504
  getToolCallsStream() {
454
- return (async function* () {
505
+ return async function* () {
455
506
  await this.initStream();
456
507
  if (!this.reusableStream) {
457
- throw new Error("Stream not initialized");
508
+ throw new Error('Stream not initialized');
458
509
  }
459
510
  yield* buildToolCallStream(this.reusableStream);
460
- }.call(this));
511
+ }.call(this);
461
512
  }
462
513
  /**
463
514
  * Cancel the underlying stream and all consumers
@@ -41,22 +41,34 @@ export class ReusableReadableStream {
41
41
  async next() {
42
42
  const consumer = self.consumers.get(consumerId);
43
43
  if (!consumer) {
44
- return { done: true, value: undefined };
44
+ return {
45
+ done: true,
46
+ value: undefined,
47
+ };
45
48
  }
46
49
  if (consumer.cancelled) {
47
- return { done: true, value: undefined };
50
+ return {
51
+ done: true,
52
+ value: undefined,
53
+ };
48
54
  }
49
55
  // If we have buffered data at this position, return it
50
56
  if (consumer.position < self.buffer.length) {
51
57
  const value = self.buffer[consumer.position];
52
58
  consumer.position++;
53
59
  // Note: We don't clean up buffer to allow sequential/reusable access
54
- return { done: false, value };
60
+ return {
61
+ done: false,
62
+ value,
63
+ };
55
64
  }
56
65
  // If source is complete and we've read everything, we're done
57
66
  if (self.sourceComplete) {
58
67
  self.consumers.delete(consumerId);
59
- return { done: true, value: undefined };
68
+ return {
69
+ done: true,
70
+ value: undefined,
71
+ };
60
72
  }
61
73
  // If source had an error, propagate it
62
74
  if (self.sourceError) {
@@ -66,7 +78,10 @@ export class ReusableReadableStream {
66
78
  // Wait for more data - but check conditions after setting up the promise
67
79
  // to avoid race condition where source completes between check and wait
68
80
  const waitPromise = new Promise((resolve, reject) => {
69
- consumer.waitingPromise = { resolve, reject };
81
+ consumer.waitingPromise = {
82
+ resolve,
83
+ reject,
84
+ };
70
85
  });
71
86
  // Double-check conditions after setting up promise to handle race
72
87
  if (self.sourceComplete || self.sourceError || consumer.position < self.buffer.length) {
@@ -86,7 +101,10 @@ export class ReusableReadableStream {
86
101
  consumer.cancelled = true;
87
102
  self.consumers.delete(consumerId);
88
103
  }
89
- return { done: true, value: undefined };
104
+ return {
105
+ done: true,
106
+ value: undefined,
107
+ };
90
108
  },
91
109
  async throw(e) {
92
110
  const consumer = self.consumers.get(consumerId);
@@ -105,8 +123,9 @@ export class ReusableReadableStream {
105
123
  * Start pumping data from the source stream into the buffer
106
124
  */
107
125
  startPump() {
108
- if (this.pumpStarted)
126
+ if (this.pumpStarted) {
109
127
  return;
128
+ }
110
129
  this.pumpStarted = true;
111
130
  this.sourceReader = this.sourceStream.getReader();
112
131
  void (async () => {
@@ -1,6 +1,6 @@
1
- import * as models from "../models/index.js";
2
- import { ReusableReadableStream } from "./reusable-stream.js";
3
- import { ParsedToolCall } from "./tool-types.js";
1
+ import type * as models from '../models/index.js';
2
+ import type { ReusableReadableStream } from './reusable-stream.js';
3
+ import type { ParsedToolCall } from './tool-types.js';
4
4
  /**
5
5
  * Extract text deltas from responses stream events
6
6
  */