@providerprotocol/ai 0.0.21 → 0.0.23
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/README.md +188 -6
- package/dist/anthropic/index.d.ts +1 -1
- package/dist/anthropic/index.js +115 -39
- package/dist/anthropic/index.js.map +1 -1
- package/dist/{chunk-Y3GBJNA2.js → chunk-55X3W2MN.js} +4 -3
- package/dist/chunk-55X3W2MN.js.map +1 -0
- package/dist/chunk-73IIE3QT.js +120 -0
- package/dist/chunk-73IIE3QT.js.map +1 -0
- package/dist/{chunk-M4BMM5IB.js → chunk-MF5ETY5O.js} +13 -4
- package/dist/chunk-MF5ETY5O.js.map +1 -0
- package/dist/{chunk-SKY2JLA7.js → chunk-MKDLXV4O.js} +1 -1
- package/dist/chunk-MKDLXV4O.js.map +1 -0
- package/dist/{chunk-Z7RBRCRN.js → chunk-NWS5IKNR.js} +37 -11
- package/dist/chunk-NWS5IKNR.js.map +1 -0
- package/dist/{chunk-EDENPF3E.js → chunk-QNJO7DSD.js} +152 -53
- package/dist/chunk-QNJO7DSD.js.map +1 -0
- package/dist/{chunk-Z4ILICF5.js → chunk-SBCATNHA.js} +43 -14
- package/dist/chunk-SBCATNHA.js.map +1 -0
- package/dist/chunk-Z6DKC37J.js +50 -0
- package/dist/chunk-Z6DKC37J.js.map +1 -0
- package/dist/google/index.d.ts +22 -7
- package/dist/google/index.js +286 -85
- package/dist/google/index.js.map +1 -1
- package/dist/http/index.d.ts +3 -3
- package/dist/http/index.js +4 -4
- package/dist/index.d.ts +10 -6
- package/dist/index.js +331 -204
- package/dist/index.js.map +1 -1
- package/dist/ollama/index.d.ts +5 -2
- package/dist/ollama/index.js +87 -28
- package/dist/ollama/index.js.map +1 -1
- package/dist/openai/index.d.ts +1 -1
- package/dist/openai/index.js +226 -81
- package/dist/openai/index.js.map +1 -1
- package/dist/openrouter/index.d.ts +1 -1
- package/dist/openrouter/index.js +199 -64
- package/dist/openrouter/index.js.map +1 -1
- package/dist/{provider-DGQHYE6I.d.ts → provider-DR1yins0.d.ts} +159 -53
- package/dist/proxy/index.d.ts +2 -2
- package/dist/proxy/index.js +178 -17
- package/dist/proxy/index.js.map +1 -1
- package/dist/{retry-Pcs3hnbu.d.ts → retry-DJiqAslw.d.ts} +11 -2
- package/dist/{stream-Di9acos2.d.ts → stream-BuTrqt_j.d.ts} +103 -41
- package/dist/xai/index.d.ts +1 -1
- package/dist/xai/index.js +189 -75
- package/dist/xai/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-EDENPF3E.js.map +0 -1
- package/dist/chunk-M4BMM5IB.js.map +0 -1
- package/dist/chunk-SKY2JLA7.js.map +0 -1
- package/dist/chunk-Y3GBJNA2.js.map +0 -1
- package/dist/chunk-Z4ILICF5.js.map +0 -1
- package/dist/chunk-Z7RBRCRN.js.map +0 -1
package/dist/openai/index.js
CHANGED
|
@@ -1,25 +1,35 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Image
|
|
3
3
|
} from "../chunk-WAKD3OO5.js";
|
|
4
|
+
import {
|
|
5
|
+
parseJsonResponse
|
|
6
|
+
} from "../chunk-Z6DKC37J.js";
|
|
7
|
+
import {
|
|
8
|
+
StreamEventType
|
|
9
|
+
} from "../chunk-73IIE3QT.js";
|
|
4
10
|
import {
|
|
5
11
|
AssistantMessage,
|
|
6
12
|
createProvider,
|
|
13
|
+
generateId,
|
|
7
14
|
isAssistantMessage,
|
|
8
15
|
isToolResultMessage,
|
|
9
16
|
isUserMessage
|
|
10
|
-
} from "../chunk-
|
|
17
|
+
} from "../chunk-MF5ETY5O.js";
|
|
11
18
|
import {
|
|
12
19
|
parseSSEStream
|
|
13
|
-
} from "../chunk-
|
|
20
|
+
} from "../chunk-NWS5IKNR.js";
|
|
14
21
|
import {
|
|
15
22
|
resolveApiKey
|
|
16
|
-
} from "../chunk-
|
|
23
|
+
} from "../chunk-55X3W2MN.js";
|
|
17
24
|
import {
|
|
25
|
+
ErrorCode,
|
|
26
|
+
ModalityType,
|
|
18
27
|
UPPError,
|
|
19
28
|
doFetch,
|
|
20
29
|
doStreamFetch,
|
|
21
|
-
normalizeHttpError
|
|
22
|
-
|
|
30
|
+
normalizeHttpError,
|
|
31
|
+
toError
|
|
32
|
+
} from "../chunk-QNJO7DSD.js";
|
|
23
33
|
|
|
24
34
|
// src/providers/openai/transform.completions.ts
|
|
25
35
|
function transformRequest(request, modelId) {
|
|
@@ -55,9 +65,40 @@ function transformRequest(request, modelId) {
|
|
|
55
65
|
return openaiRequest;
|
|
56
66
|
}
|
|
57
67
|
function normalizeSystem(system) {
|
|
58
|
-
if (
|
|
68
|
+
if (system === void 0 || system === null) return void 0;
|
|
59
69
|
if (typeof system === "string") return system;
|
|
60
|
-
|
|
70
|
+
if (!Array.isArray(system)) {
|
|
71
|
+
throw new UPPError(
|
|
72
|
+
"System prompt must be a string or an array of text blocks",
|
|
73
|
+
ErrorCode.InvalidRequest,
|
|
74
|
+
"openai",
|
|
75
|
+
ModalityType.LLM
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
const texts = [];
|
|
79
|
+
for (const block of system) {
|
|
80
|
+
if (!block || typeof block !== "object" || !("text" in block)) {
|
|
81
|
+
throw new UPPError(
|
|
82
|
+
"System prompt array must contain objects with a text field",
|
|
83
|
+
ErrorCode.InvalidRequest,
|
|
84
|
+
"openai",
|
|
85
|
+
ModalityType.LLM
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
const textValue = block.text;
|
|
89
|
+
if (typeof textValue !== "string") {
|
|
90
|
+
throw new UPPError(
|
|
91
|
+
"System prompt text must be a string",
|
|
92
|
+
ErrorCode.InvalidRequest,
|
|
93
|
+
"openai",
|
|
94
|
+
ModalityType.LLM
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
if (textValue.length > 0) {
|
|
98
|
+
texts.push(textValue);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return texts.length > 0 ? texts.join("\n\n") : void 0;
|
|
61
102
|
}
|
|
62
103
|
function transformMessages(messages, system) {
|
|
63
104
|
const result = [];
|
|
@@ -225,7 +266,7 @@ function transformResponse(data) {
|
|
|
225
266
|
textContent,
|
|
226
267
|
toolCalls.length > 0 ? toolCalls : void 0,
|
|
227
268
|
{
|
|
228
|
-
id: data.id,
|
|
269
|
+
id: data.id || generateId(),
|
|
229
270
|
metadata: {
|
|
230
271
|
openai: {
|
|
231
272
|
model: data.model,
|
|
@@ -285,7 +326,7 @@ function transformStreamEvent(chunk, state) {
|
|
|
285
326
|
const events = [];
|
|
286
327
|
if (chunk.id && !state.id) {
|
|
287
328
|
state.id = chunk.id;
|
|
288
|
-
events.push({ type:
|
|
329
|
+
events.push({ type: StreamEventType.MessageStart, index: 0, delta: {} });
|
|
289
330
|
}
|
|
290
331
|
if (chunk.model) {
|
|
291
332
|
state.model = chunk.model;
|
|
@@ -295,7 +336,7 @@ function transformStreamEvent(chunk, state) {
|
|
|
295
336
|
if (choice.delta.content) {
|
|
296
337
|
state.text += choice.delta.content;
|
|
297
338
|
events.push({
|
|
298
|
-
type:
|
|
339
|
+
type: StreamEventType.TextDelta,
|
|
299
340
|
index: 0,
|
|
300
341
|
delta: { text: choice.delta.content }
|
|
301
342
|
});
|
|
@@ -304,7 +345,7 @@ function transformStreamEvent(chunk, state) {
|
|
|
304
345
|
state.hadRefusal = true;
|
|
305
346
|
state.text += choice.delta.refusal;
|
|
306
347
|
events.push({
|
|
307
|
-
type:
|
|
348
|
+
type: StreamEventType.TextDelta,
|
|
308
349
|
index: 0,
|
|
309
350
|
delta: { text: choice.delta.refusal }
|
|
310
351
|
});
|
|
@@ -326,7 +367,7 @@ function transformStreamEvent(chunk, state) {
|
|
|
326
367
|
if (toolCallDelta.function?.arguments) {
|
|
327
368
|
toolCall.arguments += toolCallDelta.function.arguments;
|
|
328
369
|
events.push({
|
|
329
|
-
type:
|
|
370
|
+
type: StreamEventType.ToolCallDelta,
|
|
330
371
|
index,
|
|
331
372
|
delta: {
|
|
332
373
|
toolCallId: toolCall.id,
|
|
@@ -339,7 +380,7 @@ function transformStreamEvent(chunk, state) {
|
|
|
339
380
|
}
|
|
340
381
|
if (choice.finish_reason) {
|
|
341
382
|
state.finishReason = choice.finish_reason;
|
|
342
|
-
events.push({ type:
|
|
383
|
+
events.push({ type: StreamEventType.MessageStop, index: 0, delta: {} });
|
|
343
384
|
}
|
|
344
385
|
}
|
|
345
386
|
if (chunk.usage) {
|
|
@@ -374,11 +415,12 @@ function buildResponseFromState(state) {
|
|
|
374
415
|
arguments: args
|
|
375
416
|
});
|
|
376
417
|
}
|
|
418
|
+
const messageId = state.id || generateId();
|
|
377
419
|
const message = new AssistantMessage(
|
|
378
420
|
textContent,
|
|
379
421
|
toolCalls.length > 0 ? toolCalls : void 0,
|
|
380
422
|
{
|
|
381
|
-
id:
|
|
423
|
+
id: messageId,
|
|
382
424
|
metadata: {
|
|
383
425
|
openai: {
|
|
384
426
|
model: state.model,
|
|
@@ -440,9 +482,9 @@ function createCompletionsLLMHandler() {
|
|
|
440
482
|
if (!providerRef) {
|
|
441
483
|
throw new UPPError(
|
|
442
484
|
"Provider reference not set. Handler must be used with createProvider() or have _setProvider called.",
|
|
443
|
-
|
|
485
|
+
ErrorCode.InvalidRequest,
|
|
444
486
|
"openai",
|
|
445
|
-
|
|
487
|
+
ModalityType.LLM
|
|
446
488
|
);
|
|
447
489
|
}
|
|
448
490
|
const model = {
|
|
@@ -483,7 +525,7 @@ function createCompletionsLLMHandler() {
|
|
|
483
525
|
"openai",
|
|
484
526
|
"llm"
|
|
485
527
|
);
|
|
486
|
-
const data = await response
|
|
528
|
+
const data = await parseJsonResponse(response, "openai", "llm");
|
|
487
529
|
return transformResponse(data);
|
|
488
530
|
},
|
|
489
531
|
stream(request) {
|
|
@@ -508,7 +550,8 @@ function createCompletionsLLMHandler() {
|
|
|
508
550
|
body.stream_options = { include_usage: true };
|
|
509
551
|
const headers = {
|
|
510
552
|
"Content-Type": "application/json",
|
|
511
|
-
Authorization: `Bearer ${apiKey}
|
|
553
|
+
Authorization: `Bearer ${apiKey}`,
|
|
554
|
+
Accept: "text/event-stream"
|
|
512
555
|
};
|
|
513
556
|
if (request.config.headers) {
|
|
514
557
|
for (const [key, value] of Object.entries(request.config.headers)) {
|
|
@@ -537,9 +580,9 @@ function createCompletionsLLMHandler() {
|
|
|
537
580
|
if (!response.body) {
|
|
538
581
|
const error = new UPPError(
|
|
539
582
|
"No response body for streaming request",
|
|
540
|
-
|
|
583
|
+
ErrorCode.ProviderError,
|
|
541
584
|
"openai",
|
|
542
|
-
|
|
585
|
+
ModalityType.LLM
|
|
543
586
|
);
|
|
544
587
|
responseReject(error);
|
|
545
588
|
throw error;
|
|
@@ -554,9 +597,9 @@ function createCompletionsLLMHandler() {
|
|
|
554
597
|
const errorData = chunk.error;
|
|
555
598
|
const error = new UPPError(
|
|
556
599
|
errorData.message ?? "Unknown error",
|
|
557
|
-
|
|
600
|
+
ErrorCode.ProviderError,
|
|
558
601
|
"openai",
|
|
559
|
-
|
|
602
|
+
ModalityType.LLM
|
|
560
603
|
);
|
|
561
604
|
responseReject(error);
|
|
562
605
|
throw error;
|
|
@@ -569,8 +612,9 @@ function createCompletionsLLMHandler() {
|
|
|
569
612
|
}
|
|
570
613
|
responseResolve(buildResponseFromState(state));
|
|
571
614
|
} catch (error) {
|
|
572
|
-
|
|
573
|
-
|
|
615
|
+
const err = toError(error);
|
|
616
|
+
responseReject(err);
|
|
617
|
+
throw err;
|
|
574
618
|
}
|
|
575
619
|
}
|
|
576
620
|
return {
|
|
@@ -626,9 +670,40 @@ function transformRequest2(request, modelId) {
|
|
|
626
670
|
return openaiRequest;
|
|
627
671
|
}
|
|
628
672
|
function normalizeSystem2(system) {
|
|
629
|
-
if (
|
|
673
|
+
if (system === void 0 || system === null) return void 0;
|
|
630
674
|
if (typeof system === "string") return system;
|
|
631
|
-
|
|
675
|
+
if (!Array.isArray(system)) {
|
|
676
|
+
throw new UPPError(
|
|
677
|
+
"System prompt must be a string or an array of text blocks",
|
|
678
|
+
ErrorCode.InvalidRequest,
|
|
679
|
+
"openai",
|
|
680
|
+
ModalityType.LLM
|
|
681
|
+
);
|
|
682
|
+
}
|
|
683
|
+
const texts = [];
|
|
684
|
+
for (const block of system) {
|
|
685
|
+
if (!block || typeof block !== "object" || !("text" in block)) {
|
|
686
|
+
throw new UPPError(
|
|
687
|
+
"System prompt array must contain objects with a text field",
|
|
688
|
+
ErrorCode.InvalidRequest,
|
|
689
|
+
"openai",
|
|
690
|
+
ModalityType.LLM
|
|
691
|
+
);
|
|
692
|
+
}
|
|
693
|
+
const textValue = block.text;
|
|
694
|
+
if (typeof textValue !== "string") {
|
|
695
|
+
throw new UPPError(
|
|
696
|
+
"System prompt text must be a string",
|
|
697
|
+
ErrorCode.InvalidRequest,
|
|
698
|
+
"openai",
|
|
699
|
+
ModalityType.LLM
|
|
700
|
+
);
|
|
701
|
+
}
|
|
702
|
+
if (textValue.length > 0) {
|
|
703
|
+
texts.push(textValue);
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
return texts.length > 0 ? texts.join("\n\n") : void 0;
|
|
632
707
|
}
|
|
633
708
|
function transformInputItems(messages, system) {
|
|
634
709
|
const result = [];
|
|
@@ -819,24 +894,26 @@ function transformResponse2(data) {
|
|
|
819
894
|
} else if (item.type === "image_generation_call") {
|
|
820
895
|
const imageGen = item;
|
|
821
896
|
if (imageGen.result) {
|
|
897
|
+
const mimeType = imageGen.mime_type ?? "image/png";
|
|
822
898
|
content.push({
|
|
823
899
|
type: "image",
|
|
824
|
-
mimeType
|
|
900
|
+
mimeType,
|
|
825
901
|
source: { type: "base64", data: imageGen.result }
|
|
826
902
|
});
|
|
827
903
|
}
|
|
828
904
|
}
|
|
829
905
|
}
|
|
906
|
+
const responseId = data.id || generateId();
|
|
830
907
|
const message = new AssistantMessage(
|
|
831
908
|
content,
|
|
832
909
|
toolCalls.length > 0 ? toolCalls : void 0,
|
|
833
910
|
{
|
|
834
|
-
id:
|
|
911
|
+
id: responseId,
|
|
835
912
|
metadata: {
|
|
836
913
|
openai: {
|
|
837
914
|
model: data.model,
|
|
838
915
|
status: data.status,
|
|
839
|
-
response_id:
|
|
916
|
+
response_id: responseId,
|
|
840
917
|
functionCallItems: functionCallItems.length > 0 ? functionCallItems : void 0
|
|
841
918
|
}
|
|
842
919
|
}
|
|
@@ -875,6 +952,7 @@ function createStreamState2() {
|
|
|
875
952
|
toolCalls: /* @__PURE__ */ new Map(),
|
|
876
953
|
images: [],
|
|
877
954
|
status: "in_progress",
|
|
955
|
+
incompleteReason: void 0,
|
|
878
956
|
inputTokens: 0,
|
|
879
957
|
outputTokens: 0,
|
|
880
958
|
cacheReadTokens: 0,
|
|
@@ -883,27 +961,36 @@ function createStreamState2() {
|
|
|
883
961
|
}
|
|
884
962
|
function transformStreamEvent2(event, state) {
|
|
885
963
|
const events = [];
|
|
964
|
+
const updateFromResponse = (response) => {
|
|
965
|
+
state.id = response.id || state.id;
|
|
966
|
+
state.model = response.model || state.model;
|
|
967
|
+
state.status = response.status;
|
|
968
|
+
if (response.incomplete_details?.reason) {
|
|
969
|
+
state.incompleteReason = response.incomplete_details.reason;
|
|
970
|
+
} else if (response.status !== "incomplete") {
|
|
971
|
+
state.incompleteReason = void 0;
|
|
972
|
+
}
|
|
973
|
+
if (response.usage) {
|
|
974
|
+
state.inputTokens = response.usage.input_tokens;
|
|
975
|
+
state.outputTokens = response.usage.output_tokens;
|
|
976
|
+
state.cacheReadTokens = response.usage.input_tokens_details?.cached_tokens ?? 0;
|
|
977
|
+
}
|
|
978
|
+
};
|
|
886
979
|
switch (event.type) {
|
|
887
980
|
case "response.created":
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
events.push({ type: "message_start", index: 0, delta: {} });
|
|
981
|
+
updateFromResponse(event.response);
|
|
982
|
+
events.push({ type: StreamEventType.MessageStart, index: 0, delta: {} });
|
|
891
983
|
break;
|
|
892
984
|
case "response.in_progress":
|
|
893
|
-
|
|
985
|
+
updateFromResponse(event.response);
|
|
894
986
|
break;
|
|
895
987
|
case "response.completed":
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
state.inputTokens = event.response.usage.input_tokens;
|
|
899
|
-
state.outputTokens = event.response.usage.output_tokens;
|
|
900
|
-
state.cacheReadTokens = event.response.usage.input_tokens_details?.cached_tokens ?? 0;
|
|
901
|
-
}
|
|
902
|
-
events.push({ type: "message_stop", index: 0, delta: {} });
|
|
988
|
+
updateFromResponse(event.response);
|
|
989
|
+
events.push({ type: StreamEventType.MessageStop, index: 0, delta: {} });
|
|
903
990
|
break;
|
|
904
991
|
case "response.failed":
|
|
905
|
-
|
|
906
|
-
events.push({ type:
|
|
992
|
+
updateFromResponse(event.response);
|
|
993
|
+
events.push({ type: StreamEventType.MessageStop, index: 0, delta: {} });
|
|
907
994
|
break;
|
|
908
995
|
case "response.output_item.added":
|
|
909
996
|
if (event.item.type === "function_call") {
|
|
@@ -920,7 +1007,7 @@ function transformStreamEvent2(event, state) {
|
|
|
920
1007
|
state.toolCalls.set(event.output_index, existing);
|
|
921
1008
|
}
|
|
922
1009
|
events.push({
|
|
923
|
-
type:
|
|
1010
|
+
type: StreamEventType.ContentBlockStart,
|
|
924
1011
|
index: event.output_index,
|
|
925
1012
|
delta: {}
|
|
926
1013
|
});
|
|
@@ -941,11 +1028,14 @@ function transformStreamEvent2(event, state) {
|
|
|
941
1028
|
} else if (event.item.type === "image_generation_call") {
|
|
942
1029
|
const imageGen = event.item;
|
|
943
1030
|
if (imageGen.result) {
|
|
944
|
-
state.images.push(
|
|
1031
|
+
state.images.push({
|
|
1032
|
+
data: imageGen.result,
|
|
1033
|
+
mimeType: imageGen.mime_type ?? "image/png"
|
|
1034
|
+
});
|
|
945
1035
|
}
|
|
946
1036
|
}
|
|
947
1037
|
events.push({
|
|
948
|
-
type:
|
|
1038
|
+
type: StreamEventType.ContentBlockStop,
|
|
949
1039
|
index: event.output_index,
|
|
950
1040
|
delta: {}
|
|
951
1041
|
});
|
|
@@ -954,7 +1044,7 @@ function transformStreamEvent2(event, state) {
|
|
|
954
1044
|
const currentText = state.textByIndex.get(event.output_index) ?? "";
|
|
955
1045
|
state.textByIndex.set(event.output_index, currentText + event.delta);
|
|
956
1046
|
events.push({
|
|
957
|
-
type:
|
|
1047
|
+
type: StreamEventType.TextDelta,
|
|
958
1048
|
index: event.output_index,
|
|
959
1049
|
delta: { text: event.delta }
|
|
960
1050
|
});
|
|
@@ -968,7 +1058,7 @@ function transformStreamEvent2(event, state) {
|
|
|
968
1058
|
const currentRefusal = state.textByIndex.get(event.output_index) ?? "";
|
|
969
1059
|
state.textByIndex.set(event.output_index, currentRefusal + event.delta);
|
|
970
1060
|
events.push({
|
|
971
|
-
type:
|
|
1061
|
+
type: StreamEventType.TextDelta,
|
|
972
1062
|
index: event.output_index,
|
|
973
1063
|
delta: { text: event.delta }
|
|
974
1064
|
});
|
|
@@ -992,7 +1082,7 @@ function transformStreamEvent2(event, state) {
|
|
|
992
1082
|
}
|
|
993
1083
|
toolCall.arguments += event.delta;
|
|
994
1084
|
events.push({
|
|
995
|
-
type:
|
|
1085
|
+
type: StreamEventType.ToolCallDelta,
|
|
996
1086
|
index: event.output_index,
|
|
997
1087
|
delta: {
|
|
998
1088
|
toolCallId: toolCall.callId ?? toolCall.itemId ?? "",
|
|
@@ -1028,7 +1118,10 @@ function transformStreamEvent2(event, state) {
|
|
|
1028
1118
|
function buildResponseFromState2(state) {
|
|
1029
1119
|
const content = [];
|
|
1030
1120
|
let structuredData;
|
|
1031
|
-
|
|
1121
|
+
const orderedTextEntries = [...state.textByIndex.entries()].sort(
|
|
1122
|
+
([leftIndex], [rightIndex]) => leftIndex - rightIndex
|
|
1123
|
+
);
|
|
1124
|
+
for (const [, text] of orderedTextEntries) {
|
|
1032
1125
|
if (text) {
|
|
1033
1126
|
content.push({ type: "text", text });
|
|
1034
1127
|
if (structuredData === void 0) {
|
|
@@ -1042,13 +1135,16 @@ function buildResponseFromState2(state) {
|
|
|
1042
1135
|
for (const imageData of state.images) {
|
|
1043
1136
|
content.push({
|
|
1044
1137
|
type: "image",
|
|
1045
|
-
mimeType:
|
|
1046
|
-
source: { type: "base64", data: imageData }
|
|
1138
|
+
mimeType: imageData.mimeType,
|
|
1139
|
+
source: { type: "base64", data: imageData.data }
|
|
1047
1140
|
});
|
|
1048
1141
|
}
|
|
1049
1142
|
const toolCalls = [];
|
|
1050
1143
|
const functionCallItems = [];
|
|
1051
|
-
|
|
1144
|
+
const orderedToolEntries = [...state.toolCalls.entries()].sort(
|
|
1145
|
+
([leftIndex], [rightIndex]) => leftIndex - rightIndex
|
|
1146
|
+
);
|
|
1147
|
+
for (const [, toolCall] of orderedToolEntries) {
|
|
1052
1148
|
let args = {};
|
|
1053
1149
|
if (toolCall.arguments) {
|
|
1054
1150
|
try {
|
|
@@ -1059,6 +1155,9 @@ function buildResponseFromState2(state) {
|
|
|
1059
1155
|
const itemId = toolCall.itemId ?? "";
|
|
1060
1156
|
const callId = toolCall.callId ?? toolCall.itemId ?? "";
|
|
1061
1157
|
const name = toolCall.name ?? "";
|
|
1158
|
+
if (!name || !callId) {
|
|
1159
|
+
continue;
|
|
1160
|
+
}
|
|
1062
1161
|
toolCalls.push({
|
|
1063
1162
|
toolCallId: callId,
|
|
1064
1163
|
toolName: name,
|
|
@@ -1073,16 +1172,17 @@ function buildResponseFromState2(state) {
|
|
|
1073
1172
|
});
|
|
1074
1173
|
}
|
|
1075
1174
|
}
|
|
1175
|
+
const responseId = state.id || generateId();
|
|
1076
1176
|
const message = new AssistantMessage(
|
|
1077
1177
|
content,
|
|
1078
1178
|
toolCalls.length > 0 ? toolCalls : void 0,
|
|
1079
1179
|
{
|
|
1080
|
-
id:
|
|
1180
|
+
id: responseId,
|
|
1081
1181
|
metadata: {
|
|
1082
1182
|
openai: {
|
|
1083
1183
|
model: state.model,
|
|
1084
1184
|
status: state.status,
|
|
1085
|
-
response_id:
|
|
1185
|
+
response_id: responseId,
|
|
1086
1186
|
functionCallItems: functionCallItems.length > 0 ? functionCallItems : void 0
|
|
1087
1187
|
}
|
|
1088
1188
|
}
|
|
@@ -1098,6 +1198,8 @@ function buildResponseFromState2(state) {
|
|
|
1098
1198
|
let stopReason = "end_turn";
|
|
1099
1199
|
if (state.status === "completed") {
|
|
1100
1200
|
stopReason = toolCalls.length > 0 ? "tool_use" : "end_turn";
|
|
1201
|
+
} else if (state.status === "incomplete") {
|
|
1202
|
+
stopReason = state.incompleteReason === "max_output_tokens" ? "max_tokens" : "end_turn";
|
|
1101
1203
|
} else if (state.status === "failed") {
|
|
1102
1204
|
stopReason = "error";
|
|
1103
1205
|
}
|
|
@@ -1132,9 +1234,9 @@ function createResponsesLLMHandler() {
|
|
|
1132
1234
|
if (!providerRef) {
|
|
1133
1235
|
throw new UPPError(
|
|
1134
1236
|
"Provider reference not set. Handler must be used with createProvider() or have _setProvider called.",
|
|
1135
|
-
|
|
1237
|
+
ErrorCode.InvalidRequest,
|
|
1136
1238
|
"openai",
|
|
1137
|
-
|
|
1239
|
+
ModalityType.LLM
|
|
1138
1240
|
);
|
|
1139
1241
|
}
|
|
1140
1242
|
const model = {
|
|
@@ -1175,13 +1277,13 @@ function createResponsesLLMHandler() {
|
|
|
1175
1277
|
"openai",
|
|
1176
1278
|
"llm"
|
|
1177
1279
|
);
|
|
1178
|
-
const data = await response
|
|
1280
|
+
const data = await parseJsonResponse(response, "openai", "llm");
|
|
1179
1281
|
if (data.status === "failed" && data.error) {
|
|
1180
1282
|
throw new UPPError(
|
|
1181
1283
|
data.error.message,
|
|
1182
|
-
|
|
1284
|
+
ErrorCode.ProviderError,
|
|
1183
1285
|
"openai",
|
|
1184
|
-
|
|
1286
|
+
ModalityType.LLM
|
|
1185
1287
|
);
|
|
1186
1288
|
}
|
|
1187
1289
|
return transformResponse2(data);
|
|
@@ -1207,7 +1309,8 @@ function createResponsesLLMHandler() {
|
|
|
1207
1309
|
body.stream = true;
|
|
1208
1310
|
const headers = {
|
|
1209
1311
|
"Content-Type": "application/json",
|
|
1210
|
-
Authorization: `Bearer ${apiKey}
|
|
1312
|
+
Authorization: `Bearer ${apiKey}`,
|
|
1313
|
+
Accept: "text/event-stream"
|
|
1211
1314
|
};
|
|
1212
1315
|
if (request.config.headers) {
|
|
1213
1316
|
for (const [key, value] of Object.entries(request.config.headers)) {
|
|
@@ -1236,9 +1339,9 @@ function createResponsesLLMHandler() {
|
|
|
1236
1339
|
if (!response.body) {
|
|
1237
1340
|
const error = new UPPError(
|
|
1238
1341
|
"No response body for streaming request",
|
|
1239
|
-
|
|
1342
|
+
ErrorCode.ProviderError,
|
|
1240
1343
|
"openai",
|
|
1241
|
-
|
|
1344
|
+
ModalityType.LLM
|
|
1242
1345
|
);
|
|
1243
1346
|
responseReject(error);
|
|
1244
1347
|
throw error;
|
|
@@ -1253,9 +1356,9 @@ function createResponsesLLMHandler() {
|
|
|
1253
1356
|
const errorEvent = event;
|
|
1254
1357
|
const error = new UPPError(
|
|
1255
1358
|
errorEvent.error.message,
|
|
1256
|
-
|
|
1359
|
+
ErrorCode.ProviderError,
|
|
1257
1360
|
"openai",
|
|
1258
|
-
|
|
1361
|
+
ModalityType.LLM
|
|
1259
1362
|
);
|
|
1260
1363
|
responseReject(error);
|
|
1261
1364
|
throw error;
|
|
@@ -1268,8 +1371,9 @@ function createResponsesLLMHandler() {
|
|
|
1268
1371
|
}
|
|
1269
1372
|
responseResolve(buildResponseFromState2(state));
|
|
1270
1373
|
} catch (error) {
|
|
1271
|
-
|
|
1272
|
-
|
|
1374
|
+
const err = toError(error);
|
|
1375
|
+
responseReject(err);
|
|
1376
|
+
throw err;
|
|
1273
1377
|
}
|
|
1274
1378
|
}
|
|
1275
1379
|
return {
|
|
@@ -1307,9 +1411,9 @@ function createEmbeddingHandler() {
|
|
|
1307
1411
|
if (!providerRef) {
|
|
1308
1412
|
throw new UPPError(
|
|
1309
1413
|
"Provider reference not set. Handler must be used with createProvider().",
|
|
1310
|
-
|
|
1414
|
+
ErrorCode.InvalidRequest,
|
|
1311
1415
|
"openai",
|
|
1312
|
-
|
|
1416
|
+
ModalityType.Embedding
|
|
1313
1417
|
);
|
|
1314
1418
|
}
|
|
1315
1419
|
const model = {
|
|
@@ -1337,9 +1441,9 @@ function createEmbeddingHandler() {
|
|
|
1337
1441
|
}
|
|
1338
1442
|
throw new UPPError(
|
|
1339
1443
|
"OpenAI embeddings only support text input",
|
|
1340
|
-
|
|
1444
|
+
ErrorCode.InvalidRequest,
|
|
1341
1445
|
"openai",
|
|
1342
|
-
|
|
1446
|
+
ModalityType.Embedding
|
|
1343
1447
|
);
|
|
1344
1448
|
});
|
|
1345
1449
|
const body = {
|
|
@@ -1364,7 +1468,7 @@ function createEmbeddingHandler() {
|
|
|
1364
1468
|
body: JSON.stringify(body),
|
|
1365
1469
|
signal: request.signal
|
|
1366
1470
|
}, request.config, "openai", "embedding");
|
|
1367
|
-
const data = await response
|
|
1471
|
+
const data = await parseJsonResponse(response, "openai", "embedding");
|
|
1368
1472
|
return {
|
|
1369
1473
|
embeddings: data.data.map((d) => ({
|
|
1370
1474
|
vector: d.embedding,
|
|
@@ -1402,9 +1506,9 @@ function createImageHandler() {
|
|
|
1402
1506
|
if (!providerRef) {
|
|
1403
1507
|
throw new UPPError(
|
|
1404
1508
|
"Provider reference not set. Handler must be used with createProvider().",
|
|
1405
|
-
|
|
1509
|
+
ErrorCode.InvalidRequest,
|
|
1406
1510
|
"openai",
|
|
1407
|
-
|
|
1511
|
+
ModalityType.Image
|
|
1408
1512
|
);
|
|
1409
1513
|
}
|
|
1410
1514
|
const capabilities = getCapabilities(modelId);
|
|
@@ -1460,7 +1564,7 @@ async function executeGenerate(modelId, request) {
|
|
|
1460
1564
|
body: JSON.stringify(body),
|
|
1461
1565
|
signal: request.signal
|
|
1462
1566
|
}, request.config, "openai", "image");
|
|
1463
|
-
const data = await response
|
|
1567
|
+
const data = await parseJsonResponse(response, "openai", "image");
|
|
1464
1568
|
return transformResponse3(data);
|
|
1465
1569
|
}
|
|
1466
1570
|
async function executeEdit(modelId, request) {
|
|
@@ -1505,7 +1609,7 @@ async function executeEdit(modelId, request) {
|
|
|
1505
1609
|
body: formData,
|
|
1506
1610
|
signal: request.signal
|
|
1507
1611
|
}, request.config, "openai", "image");
|
|
1508
|
-
const data = await response
|
|
1612
|
+
const data = await parseJsonResponse(response, "openai", "image");
|
|
1509
1613
|
return transformResponse3(data);
|
|
1510
1614
|
}
|
|
1511
1615
|
function executeStream(modelId, request) {
|
|
@@ -1554,9 +1658,9 @@ function executeStream(modelId, request) {
|
|
|
1554
1658
|
if (!reader) {
|
|
1555
1659
|
throw new UPPError(
|
|
1556
1660
|
"No response body for streaming",
|
|
1557
|
-
|
|
1661
|
+
ErrorCode.ProviderError,
|
|
1558
1662
|
"openai",
|
|
1559
|
-
|
|
1663
|
+
ModalityType.Image
|
|
1560
1664
|
);
|
|
1561
1665
|
}
|
|
1562
1666
|
const decoder = new TextDecoder();
|
|
@@ -1604,6 +1708,46 @@ function executeStream(modelId, request) {
|
|
|
1604
1708
|
}
|
|
1605
1709
|
}
|
|
1606
1710
|
}
|
|
1711
|
+
const remaining = decoder.decode();
|
|
1712
|
+
if (remaining) {
|
|
1713
|
+
buffer += remaining;
|
|
1714
|
+
const lines = buffer.split("\n");
|
|
1715
|
+
buffer = lines.pop() ?? "";
|
|
1716
|
+
for (const line of lines) {
|
|
1717
|
+
if (line.startsWith("data: ")) {
|
|
1718
|
+
const data = line.slice(6);
|
|
1719
|
+
if (data === "[DONE]") {
|
|
1720
|
+
continue;
|
|
1721
|
+
}
|
|
1722
|
+
try {
|
|
1723
|
+
const chunk = JSON.parse(data);
|
|
1724
|
+
if (chunk.type === "image_generation.partial_image" && chunk.data?.b64_json) {
|
|
1725
|
+
const previewImage = Image.fromBase64(chunk.data.b64_json, "image/png");
|
|
1726
|
+
yield {
|
|
1727
|
+
type: "preview",
|
|
1728
|
+
image: previewImage,
|
|
1729
|
+
index: chunk.index ?? 0
|
|
1730
|
+
};
|
|
1731
|
+
} else if (chunk.type === "image_generation.completed" && chunk.data) {
|
|
1732
|
+
const image = chunk.data.b64_json ? Image.fromBase64(chunk.data.b64_json, "image/png") : Image.fromUrl(chunk.data.url ?? "", "image/png");
|
|
1733
|
+
const genImage = {
|
|
1734
|
+
image,
|
|
1735
|
+
metadata: chunk.data.revised_prompt ? { revised_prompt: chunk.data.revised_prompt } : void 0
|
|
1736
|
+
};
|
|
1737
|
+
generatedImages.push(genImage);
|
|
1738
|
+
yield {
|
|
1739
|
+
type: "complete",
|
|
1740
|
+
image: genImage,
|
|
1741
|
+
index: chunk.index ?? generatedImages.length - 1
|
|
1742
|
+
};
|
|
1743
|
+
} else if (chunk.type === "response.done") {
|
|
1744
|
+
responseMetadata = chunk.data;
|
|
1745
|
+
}
|
|
1746
|
+
} catch {
|
|
1747
|
+
}
|
|
1748
|
+
}
|
|
1749
|
+
}
|
|
1750
|
+
}
|
|
1607
1751
|
resolveResponse({
|
|
1608
1752
|
images: generatedImages,
|
|
1609
1753
|
metadata: responseMetadata,
|
|
@@ -1612,8 +1756,9 @@ function executeStream(modelId, request) {
|
|
|
1612
1756
|
}
|
|
1613
1757
|
});
|
|
1614
1758
|
} catch (error) {
|
|
1615
|
-
|
|
1616
|
-
|
|
1759
|
+
const err = toError(error);
|
|
1760
|
+
rejectResponse(err);
|
|
1761
|
+
throw err;
|
|
1617
1762
|
}
|
|
1618
1763
|
}
|
|
1619
1764
|
const generator = generateStream();
|
|
@@ -1632,9 +1777,9 @@ function transformResponse3(data) {
|
|
|
1632
1777
|
} else {
|
|
1633
1778
|
throw new UPPError(
|
|
1634
1779
|
"No image data in response",
|
|
1635
|
-
|
|
1780
|
+
ErrorCode.ProviderError,
|
|
1636
1781
|
"openai",
|
|
1637
|
-
|
|
1782
|
+
ModalityType.Image
|
|
1638
1783
|
);
|
|
1639
1784
|
}
|
|
1640
1785
|
return {
|