llm-simple-router 0.8.2 → 0.9.4
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.en.md +319 -0
- package/README.md +2 -0
- package/config/recommended-providers.json +33 -9
- package/config/recommended-retry-rules.json +9 -8
- package/dist/admin/providers.js +11 -9
- package/dist/admin/quick-setup.d.ts +13 -0
- package/dist/admin/quick-setup.js +169 -0
- package/dist/admin/recommended.js +5 -1
- package/dist/admin/routes.js +2 -0
- package/dist/config/model-context.d.ts +8 -2
- package/dist/config/model-context.js +17 -5
- package/dist/config/recommended.d.ts +2 -1
- package/dist/config/recommended.js +5 -9
- package/dist/core/constants.js +2 -0
- package/dist/db/index.js +5 -0
- package/dist/db/migrations/033_add_adaptive_concurrency.sql +3 -0
- package/dist/db/migrations/036_add_openai_responses_api_type.sql +68 -0
- package/dist/db/migrations/037_fix_035_data_corruption.sql +54 -0
- package/dist/db/providers.d.ts +3 -3
- package/dist/index.js +7 -3
- package/dist/metrics/metrics-extractor.d.ts +3 -2
- package/dist/metrics/metrics-extractor.js +45 -0
- package/dist/metrics/sse-metrics-transform.d.ts +1 -1
- package/dist/metrics/sse-metrics-transform.js +10 -0
- package/dist/monitor/request-tracker.d.ts +1 -1
- package/dist/monitor/stream-content-accumulator.d.ts +1 -1
- package/dist/monitor/stream-extractor.d.ts +1 -1
- package/dist/monitor/stream-extractor.js +21 -0
- package/dist/monitor/types.d.ts +1 -1
- package/dist/proxy/handler/proxy-handler-utils.d.ts +1 -1
- package/dist/proxy/handler/proxy-handler.d.ts +1 -1
- package/dist/proxy/handler/proxy-handler.js +8 -2
- package/dist/proxy/handler/responses.d.ts +7 -0
- package/dist/proxy/handler/responses.js +48 -0
- package/dist/proxy/loop-prevention/tool-loop-guard.d.ts +1 -1
- package/dist/proxy/loop-prevention/tool-loop-guard.js +10 -0
- package/dist/proxy/orchestration/orchestrator.d.ts +1 -1
- package/dist/proxy/orchestration/semaphore.js +6 -0
- package/dist/proxy/patch/deepseek/index.d.ts +1 -1
- package/dist/proxy/patch/deepseek/patch-thinking-param.d.ts +1 -1
- package/dist/proxy/patch/index.d.ts +3 -0
- package/dist/proxy/patch/index.js +28 -0
- package/dist/proxy/patch/tool-round-limiter.d.ts +1 -1
- package/dist/proxy/patch/tool-round-limiter.js +16 -0
- package/dist/proxy/proxy-core.d.ts +1 -1
- package/dist/proxy/proxy-logging.d.ts +3 -3
- package/dist/proxy/response-transform.js +13 -0
- package/dist/proxy/transform/id-utils.d.ts +1 -0
- package/dist/proxy/transform/id-utils.js +3 -0
- package/dist/proxy/transform/plugin-types.d.ts +5 -5
- package/dist/proxy/transform/request-bridge-responses.d.ts +19 -0
- package/dist/proxy/transform/request-bridge-responses.js +311 -0
- package/dist/proxy/transform/request-transform-responses.d.ts +2 -0
- package/dist/proxy/transform/request-transform-responses.js +350 -0
- package/dist/proxy/transform/response-bridge-responses.d.ts +23 -0
- package/dist/proxy/transform/response-bridge-responses.js +173 -0
- package/dist/proxy/transform/response-transform-responses.d.ts +2 -0
- package/dist/proxy/transform/response-transform-responses.js +137 -0
- package/dist/proxy/transform/stream-ant2resp.d.ts +26 -0
- package/dist/proxy/transform/stream-ant2resp.js +322 -0
- package/dist/proxy/transform/stream-bridge-chat2resp.d.ts +40 -0
- package/dist/proxy/transform/stream-bridge-chat2resp.js +382 -0
- package/dist/proxy/transform/stream-bridge-resp2chat.d.ts +24 -0
- package/dist/proxy/transform/stream-bridge-resp2chat.js +237 -0
- package/dist/proxy/transform/stream-resp2ant.d.ts +21 -0
- package/dist/proxy/transform/stream-resp2ant.js +238 -0
- package/dist/proxy/transform/stream-transform-base.d.ts +1 -0
- package/dist/proxy/transform/stream-transform-base.js +3 -0
- package/dist/proxy/transform/transform-coordinator.d.ts +1 -0
- package/dist/proxy/transform/transform-coordinator.js +127 -8
- package/dist/proxy/transform/types-responses.d.ts +177 -0
- package/dist/proxy/transform/types-responses.js +27 -0
- package/dist/proxy/transform/types.d.ts +3 -1
- package/dist/proxy/transport/transport-fn.d.ts +1 -1
- package/frontend-dist/assets/CardContent-BhMXx-JD.js +1 -0
- package/frontend-dist/assets/CardTitle-DQDjTee3.js +1 -0
- package/frontend-dist/assets/CascadingModelSelect-JBQq3JJt.js +1 -0
- package/frontend-dist/assets/Checkbox-ByxbKP_C.js +1 -0
- package/frontend-dist/assets/CollapsibleContent-GecW2Jk_.js +1 -0
- package/frontend-dist/assets/CollapsibleTrigger-Cib3-OsK.js +1 -0
- package/frontend-dist/assets/Collection-Dbvdpa0m.js +1 -0
- package/frontend-dist/assets/Dashboard-3MJPLflT.js +3 -0
- package/frontend-dist/assets/DialogTitle-Ej_rtfV1.js +1 -0
- package/frontend-dist/assets/{Input-CAnKUBBK.js → Input-tcnrMp1v.js} +1 -1
- package/frontend-dist/assets/Label-BwzPFyL-.js +1 -0
- package/frontend-dist/assets/Login-Cdsw2pWC.js +1 -0
- package/frontend-dist/assets/Logs-5_CWiws5.js +1 -0
- package/frontend-dist/assets/MappingList-D8HRph05.js +1 -0
- package/frontend-dist/assets/ModelCard-CZbQcYNn.js +1 -0
- package/frontend-dist/assets/ModelMappings-CJqgl7O8.js +1 -0
- package/frontend-dist/assets/Monitor-B8v5a8fB.js +1 -0
- package/frontend-dist/assets/PopoverTrigger-C88SpJNZ.js +1 -0
- package/frontend-dist/assets/PopperContent-6BXua_FZ.js +1 -0
- package/frontend-dist/assets/Providers-DH0nvlGn.js +1 -0
- package/frontend-dist/assets/ProxyEnhancement-CAH-44W-.js +5 -0
- package/frontend-dist/assets/QuickSetup-CsDO-ZGP.js +1 -0
- package/frontend-dist/assets/RetryRules-8iT9fLsH.js +1 -0
- package/frontend-dist/assets/RouterKeys-BFoEmWgj.js +1 -0
- package/frontend-dist/assets/RovingFocusItem-DdPUFQHC.js +1 -0
- package/frontend-dist/assets/Schedules-B8Se31u4.js +1 -0
- package/frontend-dist/assets/SelectValue-CT2z_-6j.js +1 -0
- package/frontend-dist/assets/Settings-BHvtsJKD.js +6 -0
- package/frontend-dist/assets/Setup-k-l9KDC0.js +1 -0
- package/frontend-dist/assets/Switch-D1NdA4ax.js +1 -0
- package/frontend-dist/assets/TableHeader-CcMyOsUB.js +1 -0
- package/frontend-dist/assets/Teleport-Bmeh33lB.js +3 -0
- package/frontend-dist/assets/TooltipTrigger-LegC_Uvp.js +1 -0
- package/frontend-dist/assets/UnifiedRequestDialog-BVw6W2pk.js +3 -0
- package/frontend-dist/assets/UnifiedRequestDialog-C4MTxb25.css +1 -0
- package/frontend-dist/assets/VisuallyHidden-ogESfc9X.js +1 -0
- package/frontend-dist/assets/VisuallyHiddenInput-BQemVGau.js +1 -0
- package/frontend-dist/assets/alert-dialog-DzKCAoYJ.js +1 -0
- package/frontend-dist/assets/badge-C-9zPTgw.js +1 -0
- package/frontend-dist/assets/button-D27ClX8J.js +14 -0
- package/frontend-dist/assets/check-yTAivq1h.js +1 -0
- package/frontend-dist/assets/common-CWCbKHOK.js +1 -0
- package/frontend-dist/assets/common-D4xnnaqi.js +1 -0
- package/frontend-dist/assets/constants-B-VELBjk.js +1 -0
- package/frontend-dist/assets/copy-DWG9cQPR.js +1 -0
- package/frontend-dist/assets/dashboard-B8eI-t8c.js +1 -0
- package/frontend-dist/assets/dashboard-Dbe6A2lu.js +1 -0
- package/frontend-dist/assets/dialog-BnYR6_dh.js +1 -0
- package/frontend-dist/assets/file-text-D33FJAPX.js +1 -0
- package/frontend-dist/assets/format-BhxQSgt6.js +1 -0
- package/frontend-dist/assets/i18n-CwUfS0tE.js +1 -0
- package/frontend-dist/assets/index-B348nt-T.css +1 -0
- package/frontend-dist/assets/index-DPRxBo3N.js +1 -0
- package/frontend-dist/assets/lib-D0Ek2pPZ.js +1 -0
- package/frontend-dist/assets/loader-circle-EpKC006I.js +1 -0
- package/frontend-dist/assets/login-BTolYxVI.js +1 -0
- package/frontend-dist/assets/login-w_ICpiU5.js +1 -0
- package/frontend-dist/assets/logs-7dT2uyMa.js +1 -0
- package/frontend-dist/assets/logs-_3w8tDQa.js +1 -0
- package/frontend-dist/assets/mappings-Bbn3r2uJ.js +1 -0
- package/frontend-dist/assets/mappings-CTZ-zb1x.js +1 -0
- package/frontend-dist/assets/monitor-DN5m5n_x.js +1 -0
- package/frontend-dist/assets/monitor-DysWEOtt.js +1 -0
- package/frontend-dist/assets/providers-C1gQGzwa.js +1 -0
- package/frontend-dist/assets/providers-CCfko___.js +1 -0
- package/frontend-dist/assets/proxyEnhancement-BItabyLo.js +1 -0
- package/frontend-dist/assets/proxyEnhancement-DeMb7wIE.js +1 -0
- package/frontend-dist/assets/quickSetup-C75HMC_z.js +1 -0
- package/frontend-dist/assets/quickSetup-DStZWiuf.js +1 -0
- package/frontend-dist/assets/requestDetail-BoaPEQs-.js +1 -0
- package/frontend-dist/assets/requestDetail-CM5kFgy6.js +1 -0
- package/frontend-dist/assets/retryRules-CIF37gOl.js +1 -0
- package/frontend-dist/assets/retryRules-o_D8S5gy.js +1 -0
- package/frontend-dist/assets/routerKeys-BAvjW0V8.js +1 -0
- package/frontend-dist/assets/routerKeys-mQt2YPuE.js +1 -0
- package/frontend-dist/assets/schedules-BCV2rxK-.js +1 -0
- package/frontend-dist/assets/schedules-Qte9b7b_.js +1 -0
- package/frontend-dist/assets/settings-Bgu2lJfy.js +1 -0
- package/frontend-dist/assets/settings-UCmMSq_F.js +1 -0
- package/frontend-dist/assets/setup-B_fAfMoV.js +1 -0
- package/frontend-dist/assets/setup-Chc246Zi.js +1 -0
- package/frontend-dist/assets/sidebar-B7rejnZA.js +1 -0
- package/frontend-dist/assets/sidebar-CBMItLst.js +1 -0
- package/frontend-dist/assets/sun-BylRZIWt.js +1 -0
- package/frontend-dist/assets/trash-2-QNFff7V4.js +1 -0
- package/frontend-dist/assets/{useClipboard-BmmsNSGV.js → useClipboard-BFt5f-_-.js} +1 -1
- package/frontend-dist/assets/{useFocusGuards-A-9V2Y-b.js → useFocusGuards-DQBZKWnu.js} +1 -1
- package/frontend-dist/assets/useFormControl-T2RQNBqs.js +1 -0
- package/frontend-dist/assets/useLogRetention-NrrZrpPE.js +1 -0
- package/frontend-dist/assets/useNonce-DR38uny5.js +1 -0
- package/frontend-dist/assets/useTheme-CpTI547G.js +1 -0
- package/frontend-dist/assets/x-DSgLgKC_.js +1 -0
- package/frontend-dist/index.html +25 -22
- package/package.json +1 -1
- package/dist/db/migrations/033_add_pipeline_snapshot.sql +0 -1
- package/frontend-dist/assets/CardContent-BVMQ2_pg.js +0 -1
- package/frontend-dist/assets/CardTitle-GLv7QyIY.js +0 -1
- package/frontend-dist/assets/CascadingModelSelect-CBhqKFDX.js +0 -1
- package/frontend-dist/assets/Checkbox-HPVDmEdV.js +0 -1
- package/frontend-dist/assets/CollapsibleTrigger-DhxD9tpM.js +0 -1
- package/frontend-dist/assets/Collection-BRt7YxN8.js +0 -1
- package/frontend-dist/assets/Dashboard-D1Ys8Zog.js +0 -3
- package/frontend-dist/assets/DialogTitle-23q73lwF.js +0 -1
- package/frontend-dist/assets/Label-DWdYtVMI.js +0 -1
- package/frontend-dist/assets/Login-w5WFOinP.js +0 -1
- package/frontend-dist/assets/Logs-C1F1ZmWF.js +0 -1
- package/frontend-dist/assets/ModelMappings-BzmecWEH.js +0 -1
- package/frontend-dist/assets/Monitor-DrAZFTKR.js +0 -1
- package/frontend-dist/assets/PopoverTrigger-Bj65uUbv.js +0 -1
- package/frontend-dist/assets/PopperContent-gzzf1XHe.js +0 -1
- package/frontend-dist/assets/Providers-DSgf4mb6.js +0 -1
- package/frontend-dist/assets/ProxyEnhancement-Bb1cCP6d.js +0 -5
- package/frontend-dist/assets/RetryRules-BwPfEZtm.js +0 -1
- package/frontend-dist/assets/RouterKeys-CzTSq1Mx.js +0 -1
- package/frontend-dist/assets/RovingFocusItem-CXM_Yfkm.js +0 -1
- package/frontend-dist/assets/Schedules-DVilCXrC.js +0 -1
- package/frontend-dist/assets/SelectValue-C0-LzGQY.js +0 -1
- package/frontend-dist/assets/Settings-Bpk53zVX.js +0 -6
- package/frontend-dist/assets/Setup-Dn7EgC49.js +0 -1
- package/frontend-dist/assets/Switch-BO8Ooae6.js +0 -1
- package/frontend-dist/assets/TableHeader-Bded9VTC.js +0 -1
- package/frontend-dist/assets/TabsTrigger-BzKMi9AF.js +0 -1
- package/frontend-dist/assets/Teleport-DizRK5O3.js +0 -3
- package/frontend-dist/assets/TooltipTrigger-EiIy2zn8.js +0 -1
- package/frontend-dist/assets/UnifiedRequestDialog-BABsTaGb.js +0 -3
- package/frontend-dist/assets/UnifiedRequestDialog-BjEigSaR.css +0 -1
- package/frontend-dist/assets/VisuallyHidden-5AozJQza.js +0 -1
- package/frontend-dist/assets/VisuallyHiddenInput-DdiZrV2i.js +0 -1
- package/frontend-dist/assets/alert-dialog-DlKUuTPe.js +0 -1
- package/frontend-dist/assets/arrow-down-CxWKmZ2I.js +0 -1
- package/frontend-dist/assets/badge-9KJEMa53.js +0 -1
- package/frontend-dist/assets/button-Ul8WlrM5.js +0 -12
- package/frontend-dist/assets/check-7ahK--N4.js +0 -1
- package/frontend-dist/assets/constants-D_0jiLjw.js +0 -1
- package/frontend-dist/assets/copy-DzU2pAMG.js +0 -1
- package/frontend-dist/assets/dialog-B9j-FMrd.js +0 -1
- package/frontend-dist/assets/file-text-Bj3ZIo-E.js +0 -1
- package/frontend-dist/assets/format-Dln15Luw.js +0 -1
- package/frontend-dist/assets/index-Bz_ZaXNn.css +0 -1
- package/frontend-dist/assets/index-MedWZMHB.js +0 -1
- package/frontend-dist/assets/lib-Hhs3NqfD.js +0 -1
- package/frontend-dist/assets/loader-circle-5TJUukEe.js +0 -1
- package/frontend-dist/assets/useFormControl-DEO19lRe.js +0 -1
- package/frontend-dist/assets/useLogRetention-BfnBFZ5K.js +0 -1
- package/frontend-dist/assets/useNonce-BfwUJ1Ci.js +0 -1
- package/frontend-dist/assets/x-Cfopt3QL.js +0 -1
- /package/dist/db/migrations/{034_drop_redundant_log_columns.sql → 035_drop_redundant_log_columns.sql} +0 -0
- /package/frontend-dist/assets/{ohash.D__AXeF1-D5e5Wyzx.js → ohash.D__AXeF1-CTo5WcIm.js} +0 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { BaseSSETransform } from "./stream-transform-base.js";
|
|
2
|
+
export declare class ResponsesToAnthropicTransform extends BaseSSETransform {
|
|
3
|
+
private hasSentMessageStart;
|
|
4
|
+
private blockIndex;
|
|
5
|
+
private msgId;
|
|
6
|
+
private inputTokens;
|
|
7
|
+
private outputTokens;
|
|
8
|
+
private currentOutputIndex;
|
|
9
|
+
private hasSentMessageStop;
|
|
10
|
+
private hasFunctionCall;
|
|
11
|
+
private activeItems;
|
|
12
|
+
private ensureMessageStart;
|
|
13
|
+
protected processEvent(event: {
|
|
14
|
+
event?: string;
|
|
15
|
+
data?: string;
|
|
16
|
+
}): void;
|
|
17
|
+
private emitStopSequence;
|
|
18
|
+
private resolveStopReason;
|
|
19
|
+
protected flushPendingData(): void;
|
|
20
|
+
protected ensureTerminated(): void;
|
|
21
|
+
}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { BaseSSETransform } from "./stream-transform-base.js";
|
|
2
|
+
import { generateMsgId } from "./id-utils.js";
|
|
3
|
+
export class ResponsesToAnthropicTransform extends BaseSSETransform {
|
|
4
|
+
hasSentMessageStart = false;
|
|
5
|
+
blockIndex = 0;
|
|
6
|
+
msgId = generateMsgId();
|
|
7
|
+
inputTokens = 0;
|
|
8
|
+
outputTokens = 0;
|
|
9
|
+
currentOutputIndex = -1;
|
|
10
|
+
hasSentMessageStop = false;
|
|
11
|
+
hasFunctionCall = false;
|
|
12
|
+
// Track current items by output_index
|
|
13
|
+
activeItems = new Map();
|
|
14
|
+
ensureMessageStart() {
|
|
15
|
+
if (this.hasSentMessageStart)
|
|
16
|
+
return;
|
|
17
|
+
this.hasSentMessageStart = true;
|
|
18
|
+
this.pushAnthropicSSE("message_start", {
|
|
19
|
+
type: "message_start",
|
|
20
|
+
message: {
|
|
21
|
+
id: this.msgId,
|
|
22
|
+
type: "message",
|
|
23
|
+
role: "assistant",
|
|
24
|
+
content: [],
|
|
25
|
+
model: this.model,
|
|
26
|
+
status: "in_progress",
|
|
27
|
+
usage: { input_tokens: this.inputTokens },
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
processEvent(event) {
|
|
32
|
+
const eventType = event.event;
|
|
33
|
+
let payload;
|
|
34
|
+
try {
|
|
35
|
+
payload = JSON.parse(event.data);
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
this.emit("warning", err);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
switch (eventType) {
|
|
42
|
+
case "response.created":
|
|
43
|
+
case "response.in_progress":
|
|
44
|
+
case "response.queued": {
|
|
45
|
+
// Extract usage from response object if present
|
|
46
|
+
const resp = payload.response;
|
|
47
|
+
if (resp?.usage) {
|
|
48
|
+
const usage = resp.usage;
|
|
49
|
+
this.inputTokens = usage.input_tokens ?? this.inputTokens;
|
|
50
|
+
}
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
case "response.output_item.added": {
|
|
54
|
+
this.ensureMessageStart();
|
|
55
|
+
const item = payload.item;
|
|
56
|
+
const outputIdx = payload.output_index ?? this.blockIndex;
|
|
57
|
+
this.currentOutputIndex = outputIdx;
|
|
58
|
+
const itemType = item?.type;
|
|
59
|
+
const tracked = {
|
|
60
|
+
type: itemType,
|
|
61
|
+
id: item?.id ?? "",
|
|
62
|
+
name: item?.name,
|
|
63
|
+
callId: item?.call_id ?? undefined,
|
|
64
|
+
outputIndex: outputIdx,
|
|
65
|
+
};
|
|
66
|
+
this.activeItems.set(outputIdx, tracked);
|
|
67
|
+
if (itemType === "message") {
|
|
68
|
+
// Don't start content block yet — wait for content_part.added
|
|
69
|
+
}
|
|
70
|
+
else if (itemType === "function_call") {
|
|
71
|
+
this.hasFunctionCall = true;
|
|
72
|
+
const rawCallId = tracked.callId ?? tracked.id;
|
|
73
|
+
// Anthropic requires "toolu_" prefix on tool_use IDs
|
|
74
|
+
const toolId = rawCallId.startsWith("toolu_") ? rawCallId : `toolu_${rawCallId}`;
|
|
75
|
+
const toolName = tracked.name ?? "";
|
|
76
|
+
this.pushAnthropicSSE("content_block_start", {
|
|
77
|
+
type: "content_block_start",
|
|
78
|
+
index: this.blockIndex,
|
|
79
|
+
content_block: { type: "tool_use", id: toolId, name: toolName, input: {} },
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
else if (itemType === "reasoning") {
|
|
83
|
+
this.pushAnthropicSSE("content_block_start", {
|
|
84
|
+
type: "content_block_start",
|
|
85
|
+
index: this.blockIndex,
|
|
86
|
+
content_block: { type: "thinking", thinking: "" },
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
case "response.content_part.added": {
|
|
92
|
+
this.ensureMessageStart();
|
|
93
|
+
const part = payload.part;
|
|
94
|
+
const partType = part?.type;
|
|
95
|
+
if (partType === "output_text") {
|
|
96
|
+
this.pushAnthropicSSE("content_block_start", {
|
|
97
|
+
type: "content_block_start",
|
|
98
|
+
index: this.blockIndex,
|
|
99
|
+
content_block: { type: "text", text: "" },
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
case "response.output_text.delta": {
|
|
105
|
+
const delta = payload.delta;
|
|
106
|
+
if (delta) {
|
|
107
|
+
this.pushAnthropicSSE("content_block_delta", {
|
|
108
|
+
type: "content_block_delta",
|
|
109
|
+
index: this.blockIndex,
|
|
110
|
+
delta: { type: "text_delta", text: delta },
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
case "response.output_text.done":
|
|
116
|
+
case "response.content_part.done": {
|
|
117
|
+
// Nothing to emit — wait for output_item.done to send content_block_stop
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
case "response.reasoning_summary_text.delta": {
|
|
121
|
+
const delta = payload.delta;
|
|
122
|
+
if (delta) {
|
|
123
|
+
this.pushAnthropicSSE("content_block_delta", {
|
|
124
|
+
type: "content_block_delta",
|
|
125
|
+
index: this.blockIndex,
|
|
126
|
+
delta: { type: "thinking_delta", thinking: delta },
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
case "response.reasoning_summary_part.added":
|
|
132
|
+
case "response.reasoning_summary_text.done":
|
|
133
|
+
case "response.reasoning_summary_part.done": {
|
|
134
|
+
// Sub-events of reasoning — no Anthropic equivalent, handled at output_item.done
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
case "response.function_call_arguments.delta": {
|
|
138
|
+
const delta = payload.delta;
|
|
139
|
+
if (delta) {
|
|
140
|
+
this.pushAnthropicSSE("content_block_delta", {
|
|
141
|
+
type: "content_block_delta",
|
|
142
|
+
index: this.blockIndex,
|
|
143
|
+
delta: { type: "input_json_delta", partial_json: delta },
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
case "response.function_call_arguments.done": {
|
|
149
|
+
// Nothing — wait for output_item.done
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
case "response.output_item.done": {
|
|
153
|
+
const outputIdx = payload.output_index ?? this.currentOutputIndex;
|
|
154
|
+
// content_block_stop — same for all item types (index-only)
|
|
155
|
+
this.pushAnthropicSSE("content_block_stop", {
|
|
156
|
+
type: "content_block_stop",
|
|
157
|
+
index: this.blockIndex,
|
|
158
|
+
});
|
|
159
|
+
this.activeItems.delete(outputIdx);
|
|
160
|
+
this.blockIndex++;
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
case "response.completed": {
|
|
164
|
+
const resp = payload.response;
|
|
165
|
+
if (resp?.usage) {
|
|
166
|
+
const usage = resp.usage;
|
|
167
|
+
this.inputTokens = usage.input_tokens ?? this.inputTokens;
|
|
168
|
+
this.outputTokens = usage.output_tokens ?? this.outputTokens;
|
|
169
|
+
}
|
|
170
|
+
this.emitStopSequence(resp?.status);
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
case "response.incomplete": {
|
|
174
|
+
const resp = payload.response;
|
|
175
|
+
if (resp?.usage) {
|
|
176
|
+
const usage = resp.usage;
|
|
177
|
+
this.outputTokens = usage.output_tokens ?? this.outputTokens;
|
|
178
|
+
}
|
|
179
|
+
this.emitStopSequence("incomplete");
|
|
180
|
+
break;
|
|
181
|
+
}
|
|
182
|
+
case "response.failed": {
|
|
183
|
+
const resp = payload.response;
|
|
184
|
+
const err = resp?.error;
|
|
185
|
+
this.pushAnthropicSSE("error", {
|
|
186
|
+
type: "error",
|
|
187
|
+
error: {
|
|
188
|
+
type: "api_error",
|
|
189
|
+
message: err?.message ?? "Upstream error",
|
|
190
|
+
},
|
|
191
|
+
});
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
case "error": {
|
|
195
|
+
this.pushAnthropicSSE("error", {
|
|
196
|
+
type: "error",
|
|
197
|
+
error: {
|
|
198
|
+
type: "api_error",
|
|
199
|
+
message: payload.message ?? "Stream error",
|
|
200
|
+
},
|
|
201
|
+
});
|
|
202
|
+
break;
|
|
203
|
+
}
|
|
204
|
+
default: {
|
|
205
|
+
this.emit("warning", { event: "unknown_sse_event", eventType });
|
|
206
|
+
break;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
emitStopSequence(status) {
|
|
211
|
+
if (this.hasSentMessageStop)
|
|
212
|
+
return;
|
|
213
|
+
const stopReason = this.resolveStopReason(status);
|
|
214
|
+
this.pushAnthropicSSE("message_delta", {
|
|
215
|
+
type: "message_delta",
|
|
216
|
+
delta: { stop_reason: stopReason, stop_sequence: null },
|
|
217
|
+
usage: { output_tokens: this.outputTokens },
|
|
218
|
+
});
|
|
219
|
+
this.pushAnthropicSSE("message_stop", { type: "message_stop" });
|
|
220
|
+
this.hasSentMessageStop = true;
|
|
221
|
+
}
|
|
222
|
+
resolveStopReason(status) {
|
|
223
|
+
if (status === "incomplete")
|
|
224
|
+
return "max_tokens";
|
|
225
|
+
if (this.hasFunctionCall)
|
|
226
|
+
return "tool_use";
|
|
227
|
+
return "end_turn";
|
|
228
|
+
}
|
|
229
|
+
flushPendingData() {
|
|
230
|
+
// No buffered data
|
|
231
|
+
}
|
|
232
|
+
ensureTerminated() {
|
|
233
|
+
if (!this.hasSentMessageStop) {
|
|
234
|
+
this.ensureMessageStart();
|
|
235
|
+
this.emitStopSequence("completed");
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
@@ -15,5 +15,6 @@ export declare abstract class BaseSSETransform extends Transform {
|
|
|
15
15
|
protected abstract ensureTerminated(): void;
|
|
16
16
|
protected pushAnthropicSSE(eventType: string, data: unknown): void;
|
|
17
17
|
protected pushOpenAISSE(data: unknown): void;
|
|
18
|
+
protected pushResponsesSSE(eventType: string, data: unknown): void;
|
|
18
19
|
protected pushDone(): void;
|
|
19
20
|
}
|
|
@@ -54,6 +54,9 @@ export class BaseSSETransform extends Transform {
|
|
|
54
54
|
pushOpenAISSE(data) {
|
|
55
55
|
this.push(`data: ${JSON.stringify(data)}\n\n`);
|
|
56
56
|
}
|
|
57
|
+
pushResponsesSSE(eventType, data) {
|
|
58
|
+
this.push(`event: ${eventType}\ndata: ${JSON.stringify(data)}\n\n`);
|
|
59
|
+
}
|
|
57
60
|
pushDone() {
|
|
58
61
|
this.push("data: [DONE]\n\n");
|
|
59
62
|
this.done = true;
|
|
@@ -8,4 +8,5 @@ export declare class TransformCoordinator {
|
|
|
8
8
|
transformResponse(bodyStr: string, sourceApiType: string, targetApiType: string): string;
|
|
9
9
|
transformErrorResponse(bodyStr: string, sourceApiType: string, targetApiType: string): string;
|
|
10
10
|
createFormatTransform(entryApiType: string, providerApiType: string, model: string): Transform | undefined;
|
|
11
|
+
private getUpstreamPath;
|
|
11
12
|
}
|
|
@@ -1,32 +1,151 @@
|
|
|
1
1
|
import { transformRequestBody } from "./request-transform.js";
|
|
2
|
-
import { transformResponseBody, transformErrorResponse } from "./response-transform.js";
|
|
2
|
+
import { transformResponseBody, transformErrorResponse as transformErrorBody, } from "./response-transform.js";
|
|
3
3
|
import { OpenAIToAnthropicTransform } from "./stream-oa2ant.js";
|
|
4
4
|
import { AnthropicToOpenAITransform } from "./stream-ant2oa.js";
|
|
5
|
+
import { responsesToAnthropicRequest, anthropicToResponsesRequest, } from "./request-transform-responses.js";
|
|
6
|
+
import { responsesToAnthropicResponse, anthropicToResponsesResponse, } from "./response-transform-responses.js";
|
|
7
|
+
import { responsesToChatRequest, chatToResponsesRequest, } from "./request-bridge-responses.js";
|
|
8
|
+
import { responsesToChatResponse, chatToResponsesResponse, } from "./response-bridge-responses.js";
|
|
9
|
+
import { AnthropicToResponsesTransform } from "./stream-ant2resp.js";
|
|
10
|
+
import { ResponsesToAnthropicTransform } from "./stream-resp2ant.js";
|
|
11
|
+
import { ChatToResponsesBridgeTransform } from "./stream-bridge-chat2resp.js";
|
|
12
|
+
import { ResponsesToChatBridgeTransform } from "./stream-bridge-resp2chat.js";
|
|
5
13
|
export class TransformCoordinator {
|
|
6
14
|
needsTransform(entryApiType, providerApiType) {
|
|
7
15
|
return entryApiType !== providerApiType;
|
|
8
16
|
}
|
|
9
17
|
transformRequest(body, entryApiType, providerApiType, model) {
|
|
10
|
-
|
|
11
|
-
|
|
18
|
+
if (entryApiType === providerApiType) {
|
|
19
|
+
return { body, upstreamPath: this.getUpstreamPath(providerApiType) };
|
|
20
|
+
}
|
|
21
|
+
// Tier-1: Responses ↔ Anthropic
|
|
22
|
+
if (entryApiType === "openai-responses" && providerApiType === "anthropic") {
|
|
23
|
+
return { body: responsesToAnthropicRequest(body), upstreamPath: "/v1/messages" };
|
|
24
|
+
}
|
|
25
|
+
if (entryApiType === "anthropic" && providerApiType === "openai-responses") {
|
|
26
|
+
return { body: anthropicToResponsesRequest(body), upstreamPath: "/v1/responses" };
|
|
27
|
+
}
|
|
28
|
+
// Existing: OpenAI Chat ↔ Anthropic
|
|
29
|
+
if (entryApiType === "openai" && providerApiType === "anthropic") {
|
|
30
|
+
return { body: transformRequestBody(body, "openai", "anthropic", model), upstreamPath: "/v1/messages" };
|
|
31
|
+
}
|
|
32
|
+
if (entryApiType === "anthropic" && providerApiType === "openai") {
|
|
33
|
+
return { body: transformRequestBody(body, "anthropic", "openai", model), upstreamPath: "/v1/chat/completions" };
|
|
34
|
+
}
|
|
35
|
+
// Bridge: Responses ↔ Chat
|
|
36
|
+
if (entryApiType === "openai-responses" && providerApiType === "openai") {
|
|
37
|
+
return { body: responsesToChatRequest(body), upstreamPath: "/v1/chat/completions" };
|
|
38
|
+
}
|
|
39
|
+
if (entryApiType === "openai" && providerApiType === "openai-responses") {
|
|
40
|
+
return { body: chatToResponsesRequest(body), upstreamPath: "/v1/responses" };
|
|
41
|
+
}
|
|
42
|
+
return { body, upstreamPath: this.getUpstreamPath(providerApiType) };
|
|
12
43
|
}
|
|
13
44
|
transformResponse(bodyStr, sourceApiType, targetApiType) {
|
|
14
|
-
|
|
45
|
+
if (sourceApiType === targetApiType)
|
|
46
|
+
return bodyStr;
|
|
47
|
+
// Tier-1
|
|
48
|
+
if (sourceApiType === "openai-responses" && targetApiType === "anthropic") {
|
|
49
|
+
return responsesToAnthropicResponse(bodyStr);
|
|
50
|
+
}
|
|
51
|
+
if (sourceApiType === "anthropic" && targetApiType === "openai-responses") {
|
|
52
|
+
return anthropicToResponsesResponse(bodyStr);
|
|
53
|
+
}
|
|
54
|
+
// Existing
|
|
55
|
+
if (sourceApiType === "openai" && targetApiType === "anthropic") {
|
|
56
|
+
return transformResponseBody(bodyStr, "openai", "anthropic");
|
|
57
|
+
}
|
|
58
|
+
if (sourceApiType === "anthropic" && targetApiType === "openai") {
|
|
59
|
+
return transformResponseBody(bodyStr, "anthropic", "openai");
|
|
60
|
+
}
|
|
61
|
+
// Bridge
|
|
62
|
+
if (sourceApiType === "openai-responses" && targetApiType === "openai") {
|
|
63
|
+
return responsesToChatResponse(bodyStr);
|
|
64
|
+
}
|
|
65
|
+
if (sourceApiType === "openai" && targetApiType === "openai-responses") {
|
|
66
|
+
return chatToResponsesResponse(bodyStr);
|
|
67
|
+
}
|
|
68
|
+
return bodyStr;
|
|
15
69
|
}
|
|
16
70
|
transformErrorResponse(bodyStr, sourceApiType, targetApiType) {
|
|
17
|
-
|
|
71
|
+
if (sourceApiType === targetApiType)
|
|
72
|
+
return bodyStr;
|
|
73
|
+
try {
|
|
74
|
+
const parsed = JSON.parse(bodyStr);
|
|
75
|
+
// Responses ↔ Anthropic error conversion
|
|
76
|
+
if (sourceApiType === "openai-responses" && targetApiType === "anthropic") {
|
|
77
|
+
const err = parsed.error ?? parsed;
|
|
78
|
+
return JSON.stringify({
|
|
79
|
+
type: "error",
|
|
80
|
+
error: { type: "api_error", message: err.message ?? String(err) },
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
if (sourceApiType === "anthropic" && targetApiType === "openai-responses") {
|
|
84
|
+
const err = parsed.error ?? parsed;
|
|
85
|
+
return JSON.stringify({
|
|
86
|
+
error: {
|
|
87
|
+
message: err.message ?? String(err),
|
|
88
|
+
type: "invalid_request_error",
|
|
89
|
+
code: "upstream_error",
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
// Responses ↔ Chat error conversion
|
|
94
|
+
if (sourceApiType === "openai-responses" && targetApiType === "openai") {
|
|
95
|
+
const err = parsed.error ?? parsed;
|
|
96
|
+
return JSON.stringify({
|
|
97
|
+
error: { message: err.message ?? String(err), type: "api_error", code: "upstream_error" },
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
if (sourceApiType === "openai" && targetApiType === "openai-responses") {
|
|
101
|
+
const err = parsed.error ?? parsed;
|
|
102
|
+
return JSON.stringify({
|
|
103
|
+
error: {
|
|
104
|
+
message: err.message ?? String(err),
|
|
105
|
+
type: "invalid_request_error",
|
|
106
|
+
code: "upstream_error",
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
// Fall through to existing Chat ↔ Anthropic error conversion
|
|
111
|
+
return transformErrorBody(bodyStr, sourceApiType, targetApiType);
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
return bodyStr;
|
|
115
|
+
}
|
|
18
116
|
}
|
|
19
117
|
createFormatTransform(entryApiType, providerApiType, model) {
|
|
20
|
-
if (
|
|
118
|
+
if (entryApiType === providerApiType)
|
|
21
119
|
return undefined;
|
|
22
|
-
//
|
|
23
|
-
|
|
120
|
+
// Tier-1 streaming
|
|
121
|
+
if (providerApiType === "anthropic" && entryApiType === "openai-responses") {
|
|
122
|
+
return new ResponsesToAnthropicTransform(model);
|
|
123
|
+
}
|
|
124
|
+
if (providerApiType === "openai-responses" && entryApiType === "anthropic") {
|
|
125
|
+
return new AnthropicToResponsesTransform(model);
|
|
126
|
+
}
|
|
127
|
+
// Existing streaming
|
|
24
128
|
if (providerApiType === "openai" && entryApiType === "anthropic") {
|
|
25
129
|
return new OpenAIToAnthropicTransform(model);
|
|
26
130
|
}
|
|
27
131
|
if (providerApiType === "anthropic" && entryApiType === "openai") {
|
|
28
132
|
return new AnthropicToOpenAITransform(model);
|
|
29
133
|
}
|
|
134
|
+
// Bridge streaming
|
|
135
|
+
if (providerApiType === "openai" && entryApiType === "openai-responses") {
|
|
136
|
+
return new ResponsesToChatBridgeTransform(model);
|
|
137
|
+
}
|
|
138
|
+
if (providerApiType === "openai-responses" && entryApiType === "openai") {
|
|
139
|
+
return new ChatToResponsesBridgeTransform(model);
|
|
140
|
+
}
|
|
30
141
|
return undefined;
|
|
31
142
|
}
|
|
143
|
+
getUpstreamPath(apiType) {
|
|
144
|
+
switch (apiType) {
|
|
145
|
+
case "openai": return "/v1/chat/completions";
|
|
146
|
+
case "openai-responses": return "/v1/responses";
|
|
147
|
+
case "anthropic": return "/v1/messages";
|
|
148
|
+
default: return "/v1/chat/completions";
|
|
149
|
+
}
|
|
150
|
+
}
|
|
32
151
|
}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
export interface ResponseInputMessage {
|
|
2
|
+
type: "message";
|
|
3
|
+
role: "user" | "assistant" | "system" | "developer";
|
|
4
|
+
content: string | ResponseInputContentPart[];
|
|
5
|
+
}
|
|
6
|
+
export interface ResponseInputText {
|
|
7
|
+
type: "input_text";
|
|
8
|
+
text: string;
|
|
9
|
+
}
|
|
10
|
+
export interface ResponseInputImage {
|
|
11
|
+
type: "input_image";
|
|
12
|
+
image_url: string;
|
|
13
|
+
detail?: "auto" | "low" | "high";
|
|
14
|
+
}
|
|
15
|
+
export interface ResponseFunctionCallInput {
|
|
16
|
+
type: "function_call";
|
|
17
|
+
id: string;
|
|
18
|
+
call_id: string;
|
|
19
|
+
name: string;
|
|
20
|
+
arguments: string;
|
|
21
|
+
}
|
|
22
|
+
export interface ResponseFunctionCallOutputInput {
|
|
23
|
+
type: "function_call_output";
|
|
24
|
+
call_id: string;
|
|
25
|
+
output: string;
|
|
26
|
+
}
|
|
27
|
+
export interface ResponseReasoningInput {
|
|
28
|
+
type: "reasoning";
|
|
29
|
+
id: string;
|
|
30
|
+
summary: Array<{
|
|
31
|
+
type: "summary_text";
|
|
32
|
+
text: string;
|
|
33
|
+
}>;
|
|
34
|
+
encrypted_content?: string;
|
|
35
|
+
}
|
|
36
|
+
export type ResponseInputItem = ResponseInputMessage | ResponseInputText | ResponseInputImage | ResponseFunctionCallInput | ResponseFunctionCallOutputInput | ResponseReasoningInput;
|
|
37
|
+
export interface ResponseInputContentPart {
|
|
38
|
+
type: "input_text" | "input_image" | "input_file";
|
|
39
|
+
text?: string;
|
|
40
|
+
image_url?: string;
|
|
41
|
+
file_url?: string;
|
|
42
|
+
file_data?: string;
|
|
43
|
+
filename?: string;
|
|
44
|
+
}
|
|
45
|
+
export interface ResponseFunctionTool {
|
|
46
|
+
type: "function";
|
|
47
|
+
name: string;
|
|
48
|
+
description?: string;
|
|
49
|
+
parameters?: Record<string, unknown>;
|
|
50
|
+
strict?: boolean;
|
|
51
|
+
}
|
|
52
|
+
export interface ResponseWebSearchTool {
|
|
53
|
+
type: "web_search_preview";
|
|
54
|
+
search_context_size?: "low" | "medium" | "high";
|
|
55
|
+
user_location?: {
|
|
56
|
+
type: "approximate";
|
|
57
|
+
city?: string;
|
|
58
|
+
country?: string;
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
export interface ResponseFileSearchTool {
|
|
62
|
+
type: "file_search";
|
|
63
|
+
vector_store_ids?: string[];
|
|
64
|
+
}
|
|
65
|
+
export type ResponseTool = ResponseFunctionTool | ResponseWebSearchTool | ResponseFileSearchTool | Record<string, unknown>;
|
|
66
|
+
export interface ResponseOutputMessage {
|
|
67
|
+
type: "message";
|
|
68
|
+
id: string;
|
|
69
|
+
role: "assistant";
|
|
70
|
+
content: ResponseOutputContent[];
|
|
71
|
+
status?: string;
|
|
72
|
+
}
|
|
73
|
+
export interface ResponseOutputContent {
|
|
74
|
+
type: "output_text";
|
|
75
|
+
text: string;
|
|
76
|
+
annotations?: unknown[];
|
|
77
|
+
}
|
|
78
|
+
export interface ResponseFunctionCallOutput {
|
|
79
|
+
type: "function_call";
|
|
80
|
+
id: string;
|
|
81
|
+
call_id: string;
|
|
82
|
+
name: string;
|
|
83
|
+
arguments: string;
|
|
84
|
+
status?: string;
|
|
85
|
+
}
|
|
86
|
+
export interface ResponseReasoningOutput {
|
|
87
|
+
type: "reasoning";
|
|
88
|
+
id: string;
|
|
89
|
+
summary: Array<{
|
|
90
|
+
type: "summary_text";
|
|
91
|
+
text: string;
|
|
92
|
+
}>;
|
|
93
|
+
encrypted_content?: string;
|
|
94
|
+
}
|
|
95
|
+
export type ResponseOutputItem = ResponseOutputMessage | ResponseFunctionCallOutput | ResponseReasoningOutput | Record<string, unknown>;
|
|
96
|
+
export interface ResponsesApiRequest {
|
|
97
|
+
model: string;
|
|
98
|
+
input: string | ResponseInputItem[];
|
|
99
|
+
instructions?: string;
|
|
100
|
+
max_output_tokens?: number;
|
|
101
|
+
temperature?: number;
|
|
102
|
+
top_p?: number;
|
|
103
|
+
tools?: ResponseTool[];
|
|
104
|
+
tool_choice?: "auto" | "none" | "required" | {
|
|
105
|
+
type: "function";
|
|
106
|
+
name: string;
|
|
107
|
+
};
|
|
108
|
+
stream?: boolean;
|
|
109
|
+
stream_options?: {
|
|
110
|
+
include_usage?: boolean;
|
|
111
|
+
};
|
|
112
|
+
reasoning?: {
|
|
113
|
+
effort?: "low" | "medium" | "high";
|
|
114
|
+
max_tokens?: number;
|
|
115
|
+
summary?: "auto" | "concise" | "detailed";
|
|
116
|
+
};
|
|
117
|
+
previous_response_id?: string;
|
|
118
|
+
metadata?: Record<string, string>;
|
|
119
|
+
text?: {
|
|
120
|
+
format: {
|
|
121
|
+
type: "json_schema";
|
|
122
|
+
json_schema: unknown;
|
|
123
|
+
};
|
|
124
|
+
};
|
|
125
|
+
parallel_tool_calls?: boolean;
|
|
126
|
+
store?: boolean;
|
|
127
|
+
}
|
|
128
|
+
export interface ResponsesApiResponse {
|
|
129
|
+
id: string;
|
|
130
|
+
object: "response";
|
|
131
|
+
model: string;
|
|
132
|
+
status: "completed" | "failed" | "in_progress" | "incomplete";
|
|
133
|
+
output: ResponseOutputItem[];
|
|
134
|
+
usage?: ResponsesApiUsage;
|
|
135
|
+
error?: {
|
|
136
|
+
code: string;
|
|
137
|
+
message: string;
|
|
138
|
+
};
|
|
139
|
+
created_at?: number;
|
|
140
|
+
completed_at?: number;
|
|
141
|
+
}
|
|
142
|
+
export interface ResponsesApiUsage {
|
|
143
|
+
input_tokens: number;
|
|
144
|
+
output_tokens: number;
|
|
145
|
+
total_tokens: number;
|
|
146
|
+
input_tokens_details?: {
|
|
147
|
+
cached_tokens: number;
|
|
148
|
+
};
|
|
149
|
+
output_tokens_details?: {
|
|
150
|
+
reasoning_tokens: number;
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
export declare const RESPONSES_SSE_EVENTS: {
|
|
154
|
+
readonly CREATED: "response.created";
|
|
155
|
+
readonly IN_PROGRESS: "response.in_progress";
|
|
156
|
+
readonly QUEUED: "response.queued";
|
|
157
|
+
readonly OUTPUT_ITEM_ADDED: "response.output_item.added";
|
|
158
|
+
readonly OUTPUT_ITEM_DONE: "response.output_item.done";
|
|
159
|
+
readonly CONTENT_PART_ADDED: "response.content_part.added";
|
|
160
|
+
readonly CONTENT_PART_DONE: "response.content_part.done";
|
|
161
|
+
readonly OUTPUT_TEXT_DELTA: "response.output_text.delta";
|
|
162
|
+
readonly OUTPUT_TEXT_DONE: "response.output_text.done";
|
|
163
|
+
readonly REFUSAL_DELTA: "response.refusal.delta";
|
|
164
|
+
readonly REFUSAL_DONE: "response.refusal.done";
|
|
165
|
+
readonly FUNCTION_CALL_ARGUMENTS_DELTA: "response.function_call_arguments.delta";
|
|
166
|
+
readonly FUNCTION_CALL_ARGUMENTS_DONE: "response.function_call_arguments.done";
|
|
167
|
+
readonly REASONING_SUMMARY_PART_ADDED: "response.reasoning_summary_part.added";
|
|
168
|
+
readonly REASONING_SUMMARY_PART_DONE: "response.reasoning_summary_part.done";
|
|
169
|
+
readonly REASONING_SUMMARY_TEXT_DELTA: "response.reasoning_summary_text.delta";
|
|
170
|
+
readonly REASONING_SUMMARY_TEXT_DONE: "response.reasoning_summary_text.done";
|
|
171
|
+
readonly REASONING_TEXT_DELTA: "response.reasoning_text.delta";
|
|
172
|
+
readonly REASONING_TEXT_DONE: "response.reasoning_text.done";
|
|
173
|
+
readonly COMPLETED: "response.completed";
|
|
174
|
+
readonly FAILED: "response.failed";
|
|
175
|
+
readonly INCOMPLETE: "response.incomplete";
|
|
176
|
+
readonly ERROR: "error";
|
|
177
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// ---------- Responses API 输入 item 类型 ----------
|
|
2
|
+
// ---------- Responses SSE 流式事件类型常量 ----------
|
|
3
|
+
export const RESPONSES_SSE_EVENTS = {
|
|
4
|
+
CREATED: "response.created",
|
|
5
|
+
IN_PROGRESS: "response.in_progress",
|
|
6
|
+
QUEUED: "response.queued",
|
|
7
|
+
OUTPUT_ITEM_ADDED: "response.output_item.added",
|
|
8
|
+
OUTPUT_ITEM_DONE: "response.output_item.done",
|
|
9
|
+
CONTENT_PART_ADDED: "response.content_part.added",
|
|
10
|
+
CONTENT_PART_DONE: "response.content_part.done",
|
|
11
|
+
OUTPUT_TEXT_DELTA: "response.output_text.delta",
|
|
12
|
+
OUTPUT_TEXT_DONE: "response.output_text.done",
|
|
13
|
+
REFUSAL_DELTA: "response.refusal.delta",
|
|
14
|
+
REFUSAL_DONE: "response.refusal.done",
|
|
15
|
+
FUNCTION_CALL_ARGUMENTS_DELTA: "response.function_call_arguments.delta",
|
|
16
|
+
FUNCTION_CALL_ARGUMENTS_DONE: "response.function_call_arguments.done",
|
|
17
|
+
REASONING_SUMMARY_PART_ADDED: "response.reasoning_summary_part.added",
|
|
18
|
+
REASONING_SUMMARY_PART_DONE: "response.reasoning_summary_part.done",
|
|
19
|
+
REASONING_SUMMARY_TEXT_DELTA: "response.reasoning_summary_text.delta",
|
|
20
|
+
REASONING_SUMMARY_TEXT_DONE: "response.reasoning_summary_text.done",
|
|
21
|
+
REASONING_TEXT_DELTA: "response.reasoning_text.delta",
|
|
22
|
+
REASONING_TEXT_DONE: "response.reasoning_text.done",
|
|
23
|
+
COMPLETED: "response.completed",
|
|
24
|
+
FAILED: "response.failed",
|
|
25
|
+
INCOMPLETE: "response.incomplete",
|
|
26
|
+
ERROR: "error",
|
|
27
|
+
};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/** 格式转换方向 */
|
|
2
|
-
export type TransformDirection = "openai-to-anthropic" | "anthropic-to-openai";
|
|
2
|
+
export type TransformDirection = "openai-to-anthropic" | "anthropic-to-openai" | "openai-responses-to-anthropic" | "anthropic-to-openai-responses" | "openai-to-openai-responses" | "openai-responses-to-openai";
|
|
3
|
+
/** 所有支持的 API 格式类型 */
|
|
4
|
+
export type ApiType = "openai" | "openai-responses" | "anthropic";
|
|
3
5
|
export interface AnthropicTextBlock {
|
|
4
6
|
type: "text";
|
|
5
7
|
text: string;
|
|
@@ -11,7 +11,7 @@ export interface TransportFnParams {
|
|
|
11
11
|
cliHdrs: RawHeaders;
|
|
12
12
|
reply: FastifyReply;
|
|
13
13
|
upstreamPath: string;
|
|
14
|
-
apiType: "openai" | "anthropic";
|
|
14
|
+
apiType: "openai" | "openai-responses" | "anthropic";
|
|
15
15
|
isStream: boolean;
|
|
16
16
|
startTime: number;
|
|
17
17
|
logId: string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Bt as e,Q as t,Rt as n,Y as r,pt as i,r as a,ut as o}from"./button-D27ClX8J.js";var s=[`data-size`],c=t({__name:`Card`,props:{class:{type:[Boolean,null,String,Object,Array]},size:{default:`default`}},setup(t){let c=t;return(l,u)=>(o(),r(`div`,{"data-slot":`card`,"data-size":t.size,class:e(n(a)(`ring-foreground/10 bg-card text-card-foreground gap-4 overflow-hidden rounded-lg py-4 text-sm ring-1 has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-lg *:[img:last-child]:rounded-b-lg group/card flex flex-col`,c.class))},[i(l.$slots,`default`)],10,s))}}),l=t({__name:`CardContent`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(t){let s=t;return(t,c)=>(o(),r(`div`,{"data-slot":`card-content`,class:e(n(a)(`px-4 group-data-[size=sm]/card:px-3`,s.class))},[i(t.$slots,`default`)],2))}});export{c as n,l as t};
|