@tanstack/openai-base 0.9.12 → 0.9.14
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.
- package/dist/esm/adapters/chat-completions-text.d.ts +10 -0
- package/dist/esm/adapters/chat-completions-text.js +63 -19
- package/dist/esm/adapters/chat-completions-text.js.map +1 -1
- package/dist/esm/adapters/responses-text.js +19 -21
- package/dist/esm/adapters/responses-text.js.map +1 -1
- package/dist/esm/utils/schema-converter.js.map +1 -1
- package/package.json +5 -5
- package/src/adapters/chat-completions-text.ts +82 -19
- package/src/adapters/responses-text.ts +19 -21
|
@@ -115,6 +115,53 @@ export abstract class OpenAIBaseChatCompletionsTextAdapter<
|
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
+
const rejectedToolCall = this.extractRejectedToolCall(
|
|
119
|
+
rawEvent,
|
|
120
|
+
errorPayload.message,
|
|
121
|
+
)
|
|
122
|
+
if (rejectedToolCall) {
|
|
123
|
+
const toolCallId = generateId(this.name)
|
|
124
|
+
yield {
|
|
125
|
+
type: EventType.TOOL_CALL_START,
|
|
126
|
+
toolCallId,
|
|
127
|
+
toolCallName: rejectedToolCall.toolName,
|
|
128
|
+
toolName: rejectedToolCall.toolName,
|
|
129
|
+
parentMessageId: aguiState.messageId,
|
|
130
|
+
model: options.model,
|
|
131
|
+
timestamp: Date.now(),
|
|
132
|
+
}
|
|
133
|
+
yield {
|
|
134
|
+
type: EventType.TOOL_CALL_ARGS,
|
|
135
|
+
toolCallId,
|
|
136
|
+
delta: rejectedToolCall.arguments,
|
|
137
|
+
args: rejectedToolCall.arguments,
|
|
138
|
+
model: options.model,
|
|
139
|
+
timestamp: Date.now(),
|
|
140
|
+
}
|
|
141
|
+
yield {
|
|
142
|
+
type: EventType.TOOL_CALL_END,
|
|
143
|
+
toolCallId,
|
|
144
|
+
toolCallName: rejectedToolCall.toolName,
|
|
145
|
+
toolName: rejectedToolCall.toolName,
|
|
146
|
+
...(rejectedToolCall.input !== undefined && {
|
|
147
|
+
input: rejectedToolCall.input,
|
|
148
|
+
}),
|
|
149
|
+
result: JSON.stringify({ error: rejectedToolCall.error }),
|
|
150
|
+
state: 'output-error',
|
|
151
|
+
model: options.model,
|
|
152
|
+
timestamp: Date.now(),
|
|
153
|
+
}
|
|
154
|
+
yield {
|
|
155
|
+
type: EventType.RUN_FINISHED,
|
|
156
|
+
runId: aguiState.runId,
|
|
157
|
+
threadId: aguiState.threadId,
|
|
158
|
+
model: options.model,
|
|
159
|
+
timestamp: Date.now(),
|
|
160
|
+
finishReason: 'tool_calls',
|
|
161
|
+
}
|
|
162
|
+
return
|
|
163
|
+
}
|
|
164
|
+
|
|
118
165
|
// Emit AG-UI RUN_ERROR. Conditional `code` spread keeps the wire
|
|
119
166
|
// shape spec-compliant under `exactOptionalPropertyTypes`: AG-UI's
|
|
120
167
|
// `RunErrorEvent.code` is `string?` (absent vs explicit `undefined`
|
|
@@ -142,6 +189,24 @@ export abstract class OpenAIBaseChatCompletionsTextAdapter<
|
|
|
142
189
|
}
|
|
143
190
|
}
|
|
144
191
|
|
|
192
|
+
/**
|
|
193
|
+
* Extracts a rejected tool call from a provider error. Returned calls are
|
|
194
|
+
* emitted as non-executable `output-error` results so the model can repair them.
|
|
195
|
+
*/
|
|
196
|
+
protected extractRejectedToolCall(
|
|
197
|
+
_rawEvent: unknown,
|
|
198
|
+
_fallbackMessage: string,
|
|
199
|
+
):
|
|
200
|
+
| {
|
|
201
|
+
toolName: string
|
|
202
|
+
arguments: string
|
|
203
|
+
input?: unknown
|
|
204
|
+
error: string
|
|
205
|
+
}
|
|
206
|
+
| undefined {
|
|
207
|
+
return undefined
|
|
208
|
+
}
|
|
209
|
+
|
|
145
210
|
/**
|
|
146
211
|
* Generate structured output using the provider's JSON Schema response format.
|
|
147
212
|
* Uses stream: false to get the complete response in one call.
|
|
@@ -256,12 +321,10 @@ export abstract class OpenAIBaseChatCompletionsTextAdapter<
|
|
|
256
321
|
outputSchema.required,
|
|
257
322
|
)
|
|
258
323
|
|
|
259
|
-
const timestamp = Date.now()
|
|
260
324
|
const aguiState = {
|
|
261
325
|
runId: generateId(this.name),
|
|
262
326
|
threadId: chatOptions.threadId ?? generateId(this.name),
|
|
263
327
|
messageId: generateId(this.name),
|
|
264
|
-
timestamp,
|
|
265
328
|
hasEmittedRunStarted: false,
|
|
266
329
|
}
|
|
267
330
|
|
|
@@ -285,13 +348,13 @@ export abstract class OpenAIBaseChatCompletionsTextAdapter<
|
|
|
285
348
|
type: EventType.REASONING_MESSAGE_END,
|
|
286
349
|
messageId: reasoningMessageId,
|
|
287
350
|
model: lastModel || chatOptions.model,
|
|
288
|
-
timestamp,
|
|
351
|
+
timestamp: Date.now(),
|
|
289
352
|
}
|
|
290
353
|
yield {
|
|
291
354
|
type: EventType.REASONING_END,
|
|
292
355
|
messageId: reasoningMessageId,
|
|
293
356
|
model: lastModel || chatOptions.model,
|
|
294
|
-
timestamp,
|
|
357
|
+
timestamp: Date.now(),
|
|
295
358
|
}
|
|
296
359
|
if (stepId) {
|
|
297
360
|
yield {
|
|
@@ -299,7 +362,7 @@ export abstract class OpenAIBaseChatCompletionsTextAdapter<
|
|
|
299
362
|
stepName: stepId,
|
|
300
363
|
stepId,
|
|
301
364
|
model: lastModel || chatOptions.model,
|
|
302
|
-
timestamp,
|
|
365
|
+
timestamp: Date.now(),
|
|
303
366
|
content: accumulatedReasoning,
|
|
304
367
|
}
|
|
305
368
|
}
|
|
@@ -364,7 +427,7 @@ export abstract class OpenAIBaseChatCompletionsTextAdapter<
|
|
|
364
427
|
runId: aguiState.runId,
|
|
365
428
|
threadId: aguiState.threadId,
|
|
366
429
|
model: chunk.model || chatOptions.model,
|
|
367
|
-
timestamp,
|
|
430
|
+
timestamp: Date.now(),
|
|
368
431
|
parentRunId: chatOptions.parentRunId,
|
|
369
432
|
}
|
|
370
433
|
}
|
|
@@ -379,21 +442,21 @@ export abstract class OpenAIBaseChatCompletionsTextAdapter<
|
|
|
379
442
|
type: EventType.REASONING_START,
|
|
380
443
|
messageId: reasoningMessageId,
|
|
381
444
|
model: chunk.model || chatOptions.model,
|
|
382
|
-
timestamp,
|
|
445
|
+
timestamp: Date.now(),
|
|
383
446
|
}
|
|
384
447
|
yield {
|
|
385
448
|
type: EventType.REASONING_MESSAGE_START,
|
|
386
449
|
messageId: reasoningMessageId,
|
|
387
450
|
role: 'reasoning' as const,
|
|
388
451
|
model: chunk.model || chatOptions.model,
|
|
389
|
-
timestamp,
|
|
452
|
+
timestamp: Date.now(),
|
|
390
453
|
}
|
|
391
454
|
yield {
|
|
392
455
|
type: EventType.STEP_STARTED,
|
|
393
456
|
stepName: stepId,
|
|
394
457
|
stepId,
|
|
395
458
|
model: chunk.model || chatOptions.model,
|
|
396
|
-
timestamp,
|
|
459
|
+
timestamp: Date.now(),
|
|
397
460
|
stepType: 'thinking',
|
|
398
461
|
}
|
|
399
462
|
}
|
|
@@ -403,7 +466,7 @@ export abstract class OpenAIBaseChatCompletionsTextAdapter<
|
|
|
403
466
|
messageId: reasoningMessageId,
|
|
404
467
|
delta: reasoning.text,
|
|
405
468
|
model: chunk.model || chatOptions.model,
|
|
406
|
-
timestamp,
|
|
469
|
+
timestamp: Date.now(),
|
|
407
470
|
}
|
|
408
471
|
}
|
|
409
472
|
|
|
@@ -420,7 +483,7 @@ export abstract class OpenAIBaseChatCompletionsTextAdapter<
|
|
|
420
483
|
type: EventType.TEXT_MESSAGE_START,
|
|
421
484
|
messageId: aguiState.messageId,
|
|
422
485
|
model: chunk.model || chatOptions.model,
|
|
423
|
-
timestamp,
|
|
486
|
+
timestamp: Date.now(),
|
|
424
487
|
role: 'assistant',
|
|
425
488
|
}
|
|
426
489
|
}
|
|
@@ -431,7 +494,7 @@ export abstract class OpenAIBaseChatCompletionsTextAdapter<
|
|
|
431
494
|
type: EventType.TEXT_MESSAGE_CONTENT,
|
|
432
495
|
messageId: aguiState.messageId,
|
|
433
496
|
model: chunk.model || chatOptions.model,
|
|
434
|
-
timestamp,
|
|
497
|
+
timestamp: Date.now(),
|
|
435
498
|
delta: deltaContent,
|
|
436
499
|
content: accumulatedContent,
|
|
437
500
|
}
|
|
@@ -448,7 +511,7 @@ export abstract class OpenAIBaseChatCompletionsTextAdapter<
|
|
|
448
511
|
type: EventType.TEXT_MESSAGE_END,
|
|
449
512
|
messageId: aguiState.messageId,
|
|
450
513
|
model: lastModel || chatOptions.model,
|
|
451
|
-
timestamp,
|
|
514
|
+
timestamp: Date.now(),
|
|
452
515
|
}
|
|
453
516
|
}
|
|
454
517
|
|
|
@@ -457,7 +520,7 @@ export abstract class OpenAIBaseChatCompletionsTextAdapter<
|
|
|
457
520
|
type: EventType.RUN_ERROR,
|
|
458
521
|
runId: aguiState.runId,
|
|
459
522
|
model: lastModel || chatOptions.model,
|
|
460
|
-
timestamp,
|
|
523
|
+
timestamp: Date.now(),
|
|
461
524
|
message: `${this.name}.structuredOutputStream: response contained no content`,
|
|
462
525
|
code: 'empty-response',
|
|
463
526
|
error: {
|
|
@@ -476,7 +539,7 @@ export abstract class OpenAIBaseChatCompletionsTextAdapter<
|
|
|
476
539
|
type: EventType.RUN_ERROR,
|
|
477
540
|
runId: aguiState.runId,
|
|
478
541
|
model: lastModel || chatOptions.model,
|
|
479
|
-
timestamp,
|
|
542
|
+
timestamp: Date.now(),
|
|
480
543
|
message: `Failed to parse structured output as JSON. Content: ${accumulatedContent.slice(0, 200)}${accumulatedContent.length > 200 ? '...' : ''}`,
|
|
481
544
|
code: 'parse-error',
|
|
482
545
|
error: {
|
|
@@ -498,7 +561,7 @@ export abstract class OpenAIBaseChatCompletionsTextAdapter<
|
|
|
498
561
|
...(accumulatedReasoning ? { reasoning: accumulatedReasoning } : {}),
|
|
499
562
|
},
|
|
500
563
|
model: lastModel || chatOptions.model,
|
|
501
|
-
timestamp,
|
|
564
|
+
timestamp: Date.now(),
|
|
502
565
|
}
|
|
503
566
|
|
|
504
567
|
yield {
|
|
@@ -506,7 +569,7 @@ export abstract class OpenAIBaseChatCompletionsTextAdapter<
|
|
|
506
569
|
runId: aguiState.runId,
|
|
507
570
|
threadId: aguiState.threadId,
|
|
508
571
|
model: lastModel || chatOptions.model,
|
|
509
|
-
timestamp,
|
|
572
|
+
timestamp: Date.now(),
|
|
510
573
|
finishReason: 'stop',
|
|
511
574
|
...(lastUsage && {
|
|
512
575
|
usage: buildChatCompletionsUsage(lastUsage),
|
|
@@ -520,7 +583,7 @@ export abstract class OpenAIBaseChatCompletionsTextAdapter<
|
|
|
520
583
|
runId: aguiState.runId,
|
|
521
584
|
threadId: aguiState.threadId,
|
|
522
585
|
model: chatOptions.model,
|
|
523
|
-
timestamp,
|
|
586
|
+
timestamp: Date.now(),
|
|
524
587
|
parentRunId: chatOptions.parentRunId,
|
|
525
588
|
}
|
|
526
589
|
}
|
|
@@ -540,7 +603,7 @@ export abstract class OpenAIBaseChatCompletionsTextAdapter<
|
|
|
540
603
|
type: EventType.RUN_ERROR,
|
|
541
604
|
runId: aguiState.runId,
|
|
542
605
|
model: lastModel || chatOptions.model,
|
|
543
|
-
timestamp,
|
|
606
|
+
timestamp: Date.now(),
|
|
544
607
|
message: errorPayload.message,
|
|
545
608
|
...(resolvedCode !== undefined && { code: resolvedCode }),
|
|
546
609
|
...(rawEvent !== undefined && { rawEvent }),
|
|
@@ -303,12 +303,10 @@ export abstract class OpenAIBaseResponsesTextAdapter<
|
|
|
303
303
|
outputSchema.required,
|
|
304
304
|
)
|
|
305
305
|
|
|
306
|
-
const timestamp = Date.now()
|
|
307
306
|
const aguiState = {
|
|
308
307
|
runId: generateId(this.name),
|
|
309
308
|
threadId: chatOptions.threadId ?? generateId(this.name),
|
|
310
309
|
messageId: generateId(this.name),
|
|
311
|
-
timestamp,
|
|
312
310
|
hasEmittedRunStarted: false,
|
|
313
311
|
}
|
|
314
312
|
|
|
@@ -330,13 +328,13 @@ export abstract class OpenAIBaseResponsesTextAdapter<
|
|
|
330
328
|
type: EventType.REASONING_MESSAGE_END,
|
|
331
329
|
messageId: reasoningMessageId,
|
|
332
330
|
model,
|
|
333
|
-
timestamp,
|
|
331
|
+
timestamp: Date.now(),
|
|
334
332
|
}
|
|
335
333
|
yield {
|
|
336
334
|
type: EventType.REASONING_END,
|
|
337
335
|
messageId: reasoningMessageId,
|
|
338
336
|
model,
|
|
339
|
-
timestamp,
|
|
337
|
+
timestamp: Date.now(),
|
|
340
338
|
}
|
|
341
339
|
if (stepId) {
|
|
342
340
|
yield {
|
|
@@ -344,7 +342,7 @@ export abstract class OpenAIBaseResponsesTextAdapter<
|
|
|
344
342
|
stepName: stepId,
|
|
345
343
|
stepId,
|
|
346
344
|
model,
|
|
347
|
-
timestamp,
|
|
345
|
+
timestamp: Date.now(),
|
|
348
346
|
content: accumulatedReasoning,
|
|
349
347
|
}
|
|
350
348
|
}
|
|
@@ -361,21 +359,21 @@ export abstract class OpenAIBaseResponsesTextAdapter<
|
|
|
361
359
|
type: EventType.REASONING_START,
|
|
362
360
|
messageId: reasoningMessageId,
|
|
363
361
|
model,
|
|
364
|
-
timestamp,
|
|
362
|
+
timestamp: Date.now(),
|
|
365
363
|
}
|
|
366
364
|
yield {
|
|
367
365
|
type: EventType.REASONING_MESSAGE_START,
|
|
368
366
|
messageId: reasoningMessageId,
|
|
369
367
|
role: 'reasoning' as const,
|
|
370
368
|
model,
|
|
371
|
-
timestamp,
|
|
369
|
+
timestamp: Date.now(),
|
|
372
370
|
}
|
|
373
371
|
yield {
|
|
374
372
|
type: EventType.STEP_STARTED,
|
|
375
373
|
stepName: stepId,
|
|
376
374
|
stepId,
|
|
377
375
|
model,
|
|
378
|
-
timestamp,
|
|
376
|
+
timestamp: Date.now(),
|
|
379
377
|
stepType: 'thinking',
|
|
380
378
|
}
|
|
381
379
|
}.bind(this)
|
|
@@ -418,7 +416,7 @@ export abstract class OpenAIBaseResponsesTextAdapter<
|
|
|
418
416
|
runId: aguiState.runId,
|
|
419
417
|
threadId: aguiState.threadId,
|
|
420
418
|
model,
|
|
421
|
-
timestamp,
|
|
419
|
+
timestamp: Date.now(),
|
|
422
420
|
parentRunId: chatOptions.parentRunId,
|
|
423
421
|
}
|
|
424
422
|
}
|
|
@@ -442,7 +440,7 @@ export abstract class OpenAIBaseResponsesTextAdapter<
|
|
|
442
440
|
type: EventType.RUN_ERROR,
|
|
443
441
|
runId: aguiState.runId,
|
|
444
442
|
model,
|
|
445
|
-
timestamp,
|
|
443
|
+
timestamp: Date.now(),
|
|
446
444
|
message: `Model refused: ${delta}`,
|
|
447
445
|
code: 'refusal',
|
|
448
446
|
error: { message: `Model refused: ${delta}`, code: 'refusal' },
|
|
@@ -471,7 +469,7 @@ export abstract class OpenAIBaseResponsesTextAdapter<
|
|
|
471
469
|
messageId: reasoningMessageId,
|
|
472
470
|
delta: reasoningDelta,
|
|
473
471
|
model,
|
|
474
|
-
timestamp,
|
|
472
|
+
timestamp: Date.now(),
|
|
475
473
|
}
|
|
476
474
|
continue
|
|
477
475
|
}
|
|
@@ -493,7 +491,7 @@ export abstract class OpenAIBaseResponsesTextAdapter<
|
|
|
493
491
|
type: EventType.TEXT_MESSAGE_START,
|
|
494
492
|
messageId: aguiState.messageId,
|
|
495
493
|
model,
|
|
496
|
-
timestamp,
|
|
494
|
+
timestamp: Date.now(),
|
|
497
495
|
role: 'assistant',
|
|
498
496
|
}
|
|
499
497
|
}
|
|
@@ -502,7 +500,7 @@ export abstract class OpenAIBaseResponsesTextAdapter<
|
|
|
502
500
|
type: EventType.TEXT_MESSAGE_CONTENT,
|
|
503
501
|
messageId: aguiState.messageId,
|
|
504
502
|
model,
|
|
505
|
-
timestamp,
|
|
503
|
+
timestamp: Date.now(),
|
|
506
504
|
delta: textDelta,
|
|
507
505
|
content: accumulatedContent,
|
|
508
506
|
}
|
|
@@ -531,7 +529,7 @@ export abstract class OpenAIBaseResponsesTextAdapter<
|
|
|
531
529
|
type: EventType.RUN_ERROR,
|
|
532
530
|
runId: aguiState.runId,
|
|
533
531
|
model,
|
|
534
|
-
timestamp,
|
|
532
|
+
timestamp: Date.now(),
|
|
535
533
|
message,
|
|
536
534
|
...(code !== undefined && { code }),
|
|
537
535
|
error: { message, ...(code !== undefined && { code }) },
|
|
@@ -547,7 +545,7 @@ export abstract class OpenAIBaseResponsesTextAdapter<
|
|
|
547
545
|
type: EventType.TEXT_MESSAGE_END,
|
|
548
546
|
messageId: aguiState.messageId,
|
|
549
547
|
model,
|
|
550
|
-
timestamp,
|
|
548
|
+
timestamp: Date.now(),
|
|
551
549
|
}
|
|
552
550
|
}
|
|
553
551
|
|
|
@@ -556,7 +554,7 @@ export abstract class OpenAIBaseResponsesTextAdapter<
|
|
|
556
554
|
type: EventType.RUN_ERROR,
|
|
557
555
|
runId: aguiState.runId,
|
|
558
556
|
model,
|
|
559
|
-
timestamp,
|
|
557
|
+
timestamp: Date.now(),
|
|
560
558
|
message: `${this.name}.structuredOutputStream: response contained no content`,
|
|
561
559
|
code: 'empty-response',
|
|
562
560
|
error: {
|
|
@@ -575,7 +573,7 @@ export abstract class OpenAIBaseResponsesTextAdapter<
|
|
|
575
573
|
type: EventType.RUN_ERROR,
|
|
576
574
|
runId: aguiState.runId,
|
|
577
575
|
model,
|
|
578
|
-
timestamp,
|
|
576
|
+
timestamp: Date.now(),
|
|
579
577
|
message: `Failed to parse structured output as JSON. Content: ${accumulatedContent.slice(0, 200)}${accumulatedContent.length > 200 ? '...' : ''}`,
|
|
580
578
|
code: 'parse-error',
|
|
581
579
|
error: {
|
|
@@ -600,7 +598,7 @@ export abstract class OpenAIBaseResponsesTextAdapter<
|
|
|
600
598
|
...(accumulatedReasoning ? { reasoning: accumulatedReasoning } : {}),
|
|
601
599
|
},
|
|
602
600
|
model,
|
|
603
|
-
timestamp,
|
|
601
|
+
timestamp: Date.now(),
|
|
604
602
|
}
|
|
605
603
|
|
|
606
604
|
yield {
|
|
@@ -608,7 +606,7 @@ export abstract class OpenAIBaseResponsesTextAdapter<
|
|
|
608
606
|
runId: aguiState.runId,
|
|
609
607
|
threadId: aguiState.threadId,
|
|
610
608
|
model,
|
|
611
|
-
timestamp,
|
|
609
|
+
timestamp: Date.now(),
|
|
612
610
|
finishReason: 'stop',
|
|
613
611
|
...(usage && {
|
|
614
612
|
usage: buildResponsesUsage(usage),
|
|
@@ -622,7 +620,7 @@ export abstract class OpenAIBaseResponsesTextAdapter<
|
|
|
622
620
|
runId: aguiState.runId,
|
|
623
621
|
threadId: aguiState.threadId,
|
|
624
622
|
model,
|
|
625
|
-
timestamp,
|
|
623
|
+
timestamp: Date.now(),
|
|
626
624
|
parentRunId: chatOptions.parentRunId,
|
|
627
625
|
}
|
|
628
626
|
}
|
|
@@ -641,7 +639,7 @@ export abstract class OpenAIBaseResponsesTextAdapter<
|
|
|
641
639
|
type: EventType.RUN_ERROR,
|
|
642
640
|
runId: aguiState.runId,
|
|
643
641
|
model,
|
|
644
|
-
timestamp,
|
|
642
|
+
timestamp: Date.now(),
|
|
645
643
|
message: errorPayload.message,
|
|
646
644
|
...(resolvedCode !== undefined && { code: resolvedCode }),
|
|
647
645
|
...(rawEvent !== undefined && { rawEvent }),
|