openfox 2.0.128 → 2.0.130
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/CHANGELOG.md +43 -0
- package/README.md +2 -0
- package/dist/CHANGELOG.md +43 -0
- package/dist/auth-D3WLIBTG.js +19 -0
- package/dist/{auto-config-454YE6KC.js → auto-config-5VSNLVNI.js} +6 -5
- package/dist/{backend-4YPEC3J2.js → backend-NDBY3DAQ.js} +4 -2
- package/dist/{chat-handler-3O6AIOID.js → chat-handler-4WCKNCQV.js} +32 -32
- package/dist/chunk-25DAVVTP.js +395 -0
- package/dist/{chunk-ISE55FOR.js → chunk-2AI7VYPN.js} +11 -1
- package/dist/{chunk-VHMZBKWY.js → chunk-2OMXXCJJ.js} +24 -24
- package/dist/{chunk-JEMPUHAA.js → chunk-35GQEIH2.js} +13 -13
- package/dist/{chunk-N2Q3KYWM.js → chunk-3DZSHRXE.js} +7 -2
- package/dist/chunk-3OBZ55SX.js +7 -0
- package/dist/{chunk-ZIL6VKLU.js → chunk-64N4CZFT.js} +2 -2
- package/dist/{chunk-66MG44TF.js → chunk-6QZVAOSA.js} +2 -2
- package/dist/{chunk-VJRLIKLE.js → chunk-7ET46SNE.js} +4 -4
- package/dist/{chunk-YJD5A375.js → chunk-AYCB32NI.js} +5 -5
- package/dist/{chunk-GIJUWPRQ.js → chunk-CGCEAKG5.js} +2 -2
- package/dist/{auth-GTGIGX5X.js → chunk-CQGJ5RWB.js} +4 -4
- package/dist/{chunk-B2RPFZ3U.js → chunk-CYQUM42E.js} +76 -32
- package/dist/{chunk-D5QVV3LT.js → chunk-DHDIKVRT.js} +278 -16
- package/dist/{chunk-4MXY7ELN.js → chunk-DI5GTIAU.js} +1154 -196
- package/dist/chunk-DQTN4B33.js +235 -0
- package/dist/{chunk-RV5G7QQU.js → chunk-DQTXXHD2.js} +3 -3
- package/dist/{chunk-OWCJRSOU.js → chunk-DYIDDGMN.js} +54 -36
- package/dist/{chunk-KAZWU73N.js → chunk-EUOWCVU6.js} +20 -7
- package/dist/{chunk-CQW4QASE.js → chunk-EVVWDRM5.js} +45 -16
- package/dist/{chunk-KSDWQ6IZ.js → chunk-HCYSGLY2.js} +1 -1
- package/dist/{chunk-KBESUA3W.js → chunk-JHA2SPCU.js} +2 -2
- package/dist/{chunk-ZIYETXOW.js → chunk-JKRMMNUR.js} +4 -4
- package/dist/{chunk-FYXZRVOL.js → chunk-JSONBGSY.js} +24 -4
- package/dist/{chunk-LWDL7HWL.js → chunk-KHKRHGA6.js} +15 -5
- package/dist/{chunk-K2QKX4ZJ.js → chunk-OA2FURC3.js} +8 -2
- package/dist/{chunk-ZFNBATE3.js → chunk-OXMOKQPW.js} +3 -2
- package/dist/{chunk-XAAEP5XM.js → chunk-P57IBMK4.js} +6 -2
- package/dist/{session-status-6Q5B5PEN.js → chunk-T3S5MTMD.js} +2 -3
- package/dist/{chunk-7ZMOP5LS.js → chunk-TS5WKTFB.js} +18 -1
- package/dist/{chunk-PBFGJFGC.js → chunk-UV6IH6HK.js} +32 -10
- package/dist/{chunk-KD4W3I6C.js → chunk-VJNA5AOB.js} +39 -7
- package/dist/{chunk-S6ATKIT2.js → chunk-VUIXQ6X4.js} +4 -4
- package/dist/{chunk-53R7QNZG.js → chunk-X24XN2M2.js} +97 -57
- package/dist/{chunk-AQBRI7TM.js → chunk-X3FHIDLT.js} +2 -2
- package/dist/chunk-YNMP647F.js +24 -0
- package/dist/{chunk-7YP4O4XE.js → chunk-ZRCRGPGT.js} +2 -2
- package/dist/cli/dev.js +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/client-26RSMUAX.js +16 -0
- package/dist/{client-pure-CJKM3ACP.js → client-pure-FLKP6PTI.js} +2 -2
- package/dist/{compactor-B6IVMDES.js → compactor-HYBSSFKP.js} +14 -14
- package/dist/dynamic-context-2VLACYK4.js +50 -0
- package/dist/{events-GMHRX4LF.js → events-D33QXGSX.js} +7 -7
- package/dist/{folding-7K2GRPF4.js → folding-QOKBKUU6.js} +5 -5
- package/dist/{http-client-ROVNSHF6.js → http-client-MGAJTGPR.js} +3 -3
- package/dist/launch-KFENN5GS.js +53 -0
- package/dist/{manager-NOKJQTTF.js → manager-VRHX7BVI.js} +4 -4
- package/dist/mcp-YU7AM3UV.js +120 -0
- package/dist/{model-catalog-ZLOWTQA7.js → model-catalog-2PCKTYGW.js} +2 -2
- package/dist/{oauth-provider-DGBC2YM6.js → oauth-provider-VHUS2KEG.js} +8 -2
- package/dist/{orchestrator-WLNW7TS7.js → orchestrator-PLTAEOMR.js} +30 -30
- package/dist/package.json +1 -1
- package/dist/{path-security-YTPZ35SL.js → path-security-4WQJGU3Z.js} +11 -11
- package/dist/{platform-EMKWQTZX.js → platform-MWWJ6OKV.js} +3 -3
- package/dist/plugins-registry.json +12 -0
- package/dist/{processor-ZMXU5MOT.js → processor-K4WHZKE6.js} +31 -31
- package/dist/{profiles-HXGJIPF2.js → profiles-EBCVFYG7.js} +2 -2
- package/dist/{protocol-DCMH9Ufp.d.ts → protocol-BMUoqwYH.d.ts} +8 -3
- package/dist/{protocol-TLODRZSB.js → protocol-Y7MRKRUO.js} +5 -3
- package/dist/provider/index.d.ts +4 -4
- package/dist/{provider-QIOTESLB.js → provider-CVM33XHW.js} +10 -10
- package/dist/{provider-manager-FVI22EWM.js → provider-manager-7NL5EQLG.js} +10 -10
- package/dist/{registry-Z4GVYFTV.js → registry-KFFZFIZT.js} +3 -3
- package/dist/{serve-7M4HCERR.js → serve-KQAPXO5X.js} +42 -40
- package/dist/server/index.d.ts +18 -3
- package/dist/server/index.js +39 -37
- package/dist/server-RPKVKMDD.js +56 -0
- package/dist/{service-F4TWYTKE.js → service-7TLOSFAO.js} +12 -12
- package/dist/{session-overrides-4WAD3X5Q.js → session-overrides-U573CU2V.js} +5 -5
- package/dist/session-status-UFO5IFI7.js +10 -0
- package/dist/{sessions-D7VRCHQY.js → sessions-LUVWWRFO.js} +4 -4
- package/dist/{settings-VOWWO4VG.js → settings-LMAMF2X7.js} +2 -2
- package/dist/shared/index.d.ts +3 -3
- package/dist/shared/index.js +1 -1
- package/dist/skill-defaults/browser/SKILL.md +20 -1
- package/dist/{tasks-36WHYN3H.js → tasks-FA6Z52H2.js} +12 -12
- package/dist/{tools-WAUWG4PE.js → tools-SSPC3UQZ.js} +34 -34
- package/dist/{types-PAKlAzp9.d.ts → types-BIkpxjaj.d.ts} +11 -2
- package/dist/{types-BWuVnaBw.d.ts → types-CoY8Ka1C.d.ts} +1 -1
- package/dist/{update-AIVWCRXR.js → update-QRGK67DB.js} +2 -2
- package/dist/web/assets/{index-DtQsFnyQ.js → index-0PVQNOfW.js} +88 -88
- package/dist/web/assets/{index-CbX8veVW.css → index-Ds94aclE.css} +1 -1
- package/dist/web/index.html +2 -2
- package/dist/web/sw.js +1 -1
- package/package.json +1 -1
- package/plugins-registry.json +12 -0
- package/dist/chunk-BQNQJE57.js +0 -151
- package/dist/chunk-ES5635OP.js +0 -7
- package/dist/chunk-RSB4AR2A.js +0 -108
- package/dist/client-VDXO7IIV.js +0 -16
- package/dist/dynamic-context-4WVMNJTZ.js +0 -28
- package/dist/launch-AKIMGAGC.js +0 -53
- package/dist/server-RX5JM7IT.js +0 -56
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getModelProfile
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-TS5WKTFB.js";
|
|
4
4
|
import {
|
|
5
5
|
getBackendCapabilities
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-UV6IH6HK.js";
|
|
7
7
|
import {
|
|
8
8
|
ensureVersionPrefix,
|
|
9
9
|
stripVersionPrefix
|
|
@@ -14,16 +14,267 @@ import {
|
|
|
14
14
|
getThinking,
|
|
15
15
|
mapFinishReason,
|
|
16
16
|
parseToolArguments
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-EUOWCVU6.js";
|
|
18
18
|
import {
|
|
19
19
|
ChatHttpClient,
|
|
20
|
+
DONE,
|
|
20
21
|
LLMError,
|
|
21
22
|
OpenAIHttpClient
|
|
22
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-OXMOKQPW.js";
|
|
23
24
|
import {
|
|
24
25
|
logger
|
|
25
26
|
} from "./chunk-K44MW7JJ.js";
|
|
26
27
|
|
|
28
|
+
// src/server/llm/responses-routing.ts
|
|
29
|
+
var OPENCODE_GO_RESPONSES_RULES = [
|
|
30
|
+
{
|
|
31
|
+
pattern: /^(gpt-5\.6-luna|grok-4\.6|muse-spark-1\.2-contributor)$/i,
|
|
32
|
+
protocol: "responses"
|
|
33
|
+
}
|
|
34
|
+
];
|
|
35
|
+
function basename(modelId) {
|
|
36
|
+
return modelId.split("/").pop() ?? modelId;
|
|
37
|
+
}
|
|
38
|
+
function matchesRules(modelId, rules) {
|
|
39
|
+
const name = basename(modelId);
|
|
40
|
+
for (const rule of rules) {
|
|
41
|
+
if (rule.pattern.test(modelId) || rule.pattern.test(name)) return rule.protocol;
|
|
42
|
+
}
|
|
43
|
+
return void 0;
|
|
44
|
+
}
|
|
45
|
+
function resolveApiProtocol(input) {
|
|
46
|
+
const { model, backend, profileApiProtocol, explicitApiProtocol } = input;
|
|
47
|
+
if (explicitApiProtocol) return explicitApiProtocol;
|
|
48
|
+
if (backend === "openai" && profileApiProtocol) return profileApiProtocol;
|
|
49
|
+
if (backend === "opencode-go") {
|
|
50
|
+
const matched = matchesRules(model, OPENCODE_GO_RESPONSES_RULES);
|
|
51
|
+
if (matched) return matched;
|
|
52
|
+
}
|
|
53
|
+
return "chat-completions";
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// src/server/llm/responses-native.ts
|
|
57
|
+
function messageToInputItem(message) {
|
|
58
|
+
if (message.role === "system" || message.role === "developer") return null;
|
|
59
|
+
if (message.role === "tool") {
|
|
60
|
+
return { type: "function_call_output", call_id: message.tool_call_id ?? "", output: message.content ?? "" };
|
|
61
|
+
}
|
|
62
|
+
if (message.role === "assistant" && message.tool_calls?.length) {
|
|
63
|
+
const items = [];
|
|
64
|
+
if (message.content) items.push({ role: "assistant", content: message.content });
|
|
65
|
+
for (const toolCall of message.tool_calls) {
|
|
66
|
+
items.push({
|
|
67
|
+
type: "function_call",
|
|
68
|
+
call_id: toolCall.id,
|
|
69
|
+
name: toolCall.function.name,
|
|
70
|
+
arguments: toolCall.function.arguments
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
return items.length === 1 ? items[0] : { __multi: items };
|
|
74
|
+
}
|
|
75
|
+
return { role: message.role, content: message.content ?? "" };
|
|
76
|
+
}
|
|
77
|
+
function flattenInput(items) {
|
|
78
|
+
return items.flatMap(
|
|
79
|
+
(item) => item["__multi"] !== void 0 ? item["__multi"] : [item]
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
function convertTools(tools) {
|
|
83
|
+
return tools.map((tool) => ({
|
|
84
|
+
type: "function",
|
|
85
|
+
name: tool.function.name,
|
|
86
|
+
description: tool.function.description,
|
|
87
|
+
parameters: tool.function.parameters
|
|
88
|
+
}));
|
|
89
|
+
}
|
|
90
|
+
function buildResponsesRequest(params) {
|
|
91
|
+
const systemMessages = params.messages.filter((m) => m.role === "system" || m.role === "developer");
|
|
92
|
+
const instructions = systemMessages.map((m) => typeof m.content === "string" ? m.content : "").join("\n\n");
|
|
93
|
+
const body = {
|
|
94
|
+
model: params.model,
|
|
95
|
+
input: flattenInput(
|
|
96
|
+
params.messages.map(messageToInputItem).filter((item) => item !== null)
|
|
97
|
+
),
|
|
98
|
+
stream: Boolean(params.stream),
|
|
99
|
+
store: false
|
|
100
|
+
};
|
|
101
|
+
if (instructions) body.instructions = instructions;
|
|
102
|
+
if (params.tools?.length) body.tools = convertTools(params.tools);
|
|
103
|
+
if (params.tool_choice !== void 0) {
|
|
104
|
+
const choice = params.tool_choice;
|
|
105
|
+
body.tool_choice = choice === "auto" || choice === "none" ? choice : "auto";
|
|
106
|
+
}
|
|
107
|
+
const maxTokens = params.max_tokens ?? params.max_completion_tokens;
|
|
108
|
+
if (maxTokens !== void 0) body.max_output_tokens = maxTokens;
|
|
109
|
+
const effort = params.reasoning_effort;
|
|
110
|
+
if (effort && effort !== "none") {
|
|
111
|
+
body.reasoning = { effort };
|
|
112
|
+
}
|
|
113
|
+
return body;
|
|
114
|
+
}
|
|
115
|
+
function mapResponseStatus(status, incompleteReason) {
|
|
116
|
+
switch (status) {
|
|
117
|
+
case "incomplete":
|
|
118
|
+
return incompleteReason === "max_output_tokens" ? "length" : "stop";
|
|
119
|
+
case "failed":
|
|
120
|
+
case "cancelled":
|
|
121
|
+
return "content_filter";
|
|
122
|
+
default:
|
|
123
|
+
return "stop";
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
function parseResponsesResponse(data) {
|
|
127
|
+
let content = "";
|
|
128
|
+
let reasoning = "";
|
|
129
|
+
const toolCalls = [];
|
|
130
|
+
for (const item of data.output ?? []) {
|
|
131
|
+
if (item.type === "message") {
|
|
132
|
+
for (const block of item.content ?? []) {
|
|
133
|
+
if (block.type === "output_text" && block.text) content += block.text;
|
|
134
|
+
}
|
|
135
|
+
} else if (item.type === "reasoning") {
|
|
136
|
+
for (const block of item.summary ?? []) {
|
|
137
|
+
if (block.text) reasoning += block.text;
|
|
138
|
+
}
|
|
139
|
+
} else if (item.type === "function_call") {
|
|
140
|
+
toolCalls.push({
|
|
141
|
+
id: item.call_id ?? item.id ?? `call_${toolCalls.length}`,
|
|
142
|
+
type: "function",
|
|
143
|
+
function: { name: item.name ?? "", arguments: item.arguments ?? "{}" }
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
const promptTokens = data.usage?.input_tokens ?? 0;
|
|
148
|
+
const completionTokens = data.usage?.output_tokens ?? 0;
|
|
149
|
+
const message = { content };
|
|
150
|
+
if (reasoning) message["reasoning_content"] = reasoning;
|
|
151
|
+
if (toolCalls.length > 0) message["tool_calls"] = toolCalls;
|
|
152
|
+
return {
|
|
153
|
+
id: data.id ?? `resp_${Date.now()}`,
|
|
154
|
+
choices: [
|
|
155
|
+
{
|
|
156
|
+
finish_reason: toolCalls.length > 0 ? "tool_calls" : mapResponseStatus(data.status, data.incomplete_details?.reason),
|
|
157
|
+
message
|
|
158
|
+
}
|
|
159
|
+
],
|
|
160
|
+
usage: {
|
|
161
|
+
prompt_tokens: promptTokens,
|
|
162
|
+
completion_tokens: completionTokens,
|
|
163
|
+
total_tokens: data.usage?.total_tokens ?? promptTokens + completionTokens
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
function parseResponsesEvent(event) {
|
|
168
|
+
const type = event["type"];
|
|
169
|
+
const responseId = typeof event["response_id"] === "string" ? event["response_id"] : "resp";
|
|
170
|
+
switch (type) {
|
|
171
|
+
case "response.output_text.delta":
|
|
172
|
+
return chunk(responseId, { content: String(event["delta"] ?? "") });
|
|
173
|
+
case "response.reasoning_summary_text.delta":
|
|
174
|
+
return chunk(responseId, { reasoning_content: String(event["delta"] ?? "") });
|
|
175
|
+
case "response.reasoning_text.delta":
|
|
176
|
+
return chunk(responseId, { reasoning_content: String(event["delta"] ?? "") });
|
|
177
|
+
case "response.output_item.added": {
|
|
178
|
+
const item = event["item"];
|
|
179
|
+
if (item?.type === "function_call") {
|
|
180
|
+
const callId = item.call_id ?? item.id;
|
|
181
|
+
const toolCall = {
|
|
182
|
+
index: 0,
|
|
183
|
+
...callId ? { id: callId } : {},
|
|
184
|
+
function: { name: item.name ?? "", arguments: item.arguments ?? "" }
|
|
185
|
+
};
|
|
186
|
+
return chunk(responseId, { tool_calls: [toolCall] });
|
|
187
|
+
}
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
case "response.function_call_arguments.delta": {
|
|
191
|
+
const toolCall = { index: 0, function: { arguments: String(event["delta"] ?? "") } };
|
|
192
|
+
return chunk(responseId, { tool_calls: [toolCall] });
|
|
193
|
+
}
|
|
194
|
+
case "response.output_text.done":
|
|
195
|
+
case "response.reasoning_summary_text.done":
|
|
196
|
+
case "response.reasoning_text.done":
|
|
197
|
+
case "response.function_call_arguments.done":
|
|
198
|
+
case "response.output_item.done":
|
|
199
|
+
case "response.content_part.added":
|
|
200
|
+
case "response.content_part.done":
|
|
201
|
+
return null;
|
|
202
|
+
case "response.completed": {
|
|
203
|
+
const response = event["response"];
|
|
204
|
+
return finalChunk(responseId, response);
|
|
205
|
+
}
|
|
206
|
+
case "response.failed": {
|
|
207
|
+
const response = event["response"];
|
|
208
|
+
const message = response?.error?.message ?? "Responses API request failed";
|
|
209
|
+
logger.warn("Responses API stream failed", { message });
|
|
210
|
+
return finalChunk(responseId, response);
|
|
211
|
+
}
|
|
212
|
+
case "error": {
|
|
213
|
+
const message = event["message"] ?? "Responses API stream error";
|
|
214
|
+
logger.warn("Responses API stream error event", { message });
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
default:
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
function chunk(id, delta) {
|
|
222
|
+
return { id, choices: [{ delta, finish_reason: null }] };
|
|
223
|
+
}
|
|
224
|
+
function finalChunk(id, response) {
|
|
225
|
+
const usage = response?.usage;
|
|
226
|
+
const c = {
|
|
227
|
+
id,
|
|
228
|
+
choices: [
|
|
229
|
+
{
|
|
230
|
+
delta: {},
|
|
231
|
+
finish_reason: mapResponseStatus(response?.status, response?.incomplete_details?.reason)
|
|
232
|
+
}
|
|
233
|
+
]
|
|
234
|
+
};
|
|
235
|
+
if (usage) {
|
|
236
|
+
c.usage = {
|
|
237
|
+
prompt_tokens: usage.input_tokens ?? 0,
|
|
238
|
+
completion_tokens: usage.output_tokens ?? 0,
|
|
239
|
+
total_tokens: usage.total_tokens ?? (usage.input_tokens ?? 0) + (usage.output_tokens ?? 0)
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
return c;
|
|
243
|
+
}
|
|
244
|
+
var OpenAIResponsesHttpClient = class extends ChatHttpClient {
|
|
245
|
+
baseURL;
|
|
246
|
+
apiKey;
|
|
247
|
+
constructor(options) {
|
|
248
|
+
super();
|
|
249
|
+
this.baseURL = options.baseURL;
|
|
250
|
+
this.apiKey = options.apiKey;
|
|
251
|
+
}
|
|
252
|
+
buildRequest(params) {
|
|
253
|
+
return {
|
|
254
|
+
url: `${this.baseURL}/responses`,
|
|
255
|
+
headers: {
|
|
256
|
+
"Content-Type": "application/json",
|
|
257
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
258
|
+
},
|
|
259
|
+
body: JSON.stringify(buildResponsesRequest(params))
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
parseNonStreaming(data) {
|
|
263
|
+
return parseResponsesResponse(data);
|
|
264
|
+
}
|
|
265
|
+
parseStreamLine(trimmed) {
|
|
266
|
+
if (!trimmed.startsWith("data: ")) return null;
|
|
267
|
+
const data = trimmed.slice(6);
|
|
268
|
+
if (data === "[DONE]") return DONE;
|
|
269
|
+
try {
|
|
270
|
+
return parseResponsesEvent(JSON.parse(data));
|
|
271
|
+
} catch (error) {
|
|
272
|
+
logger.warn("Failed to parse Responses SSE event", { data, error });
|
|
273
|
+
return null;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
|
|
27
278
|
// src/server/llm/ollama-native.ts
|
|
28
279
|
function mapDoneReason(reason) {
|
|
29
280
|
switch (reason) {
|
|
@@ -233,7 +484,15 @@ function createLLMClient(config, initialBackend = config.llm.backend ?? "unknown
|
|
|
233
484
|
const ollamaHttpClient = new OllamaHttpClient({
|
|
234
485
|
baseURL: stripVersionPrefix(baseURL)
|
|
235
486
|
});
|
|
236
|
-
const
|
|
487
|
+
const responsesHttpClient = new OpenAIResponsesHttpClient({
|
|
488
|
+
baseURL,
|
|
489
|
+
apiKey: config.llm.apiKey ?? "not-needed"
|
|
490
|
+
});
|
|
491
|
+
const httpFor = (b) => {
|
|
492
|
+
if (b === "ollama") return ollamaHttpClient;
|
|
493
|
+
if (currentApiProtocol() === "responses") return responsesHttpClient;
|
|
494
|
+
return httpClient;
|
|
495
|
+
};
|
|
237
496
|
let model = config.llm.model;
|
|
238
497
|
let profile = getModelProfile(model);
|
|
239
498
|
let backend = initialBackend;
|
|
@@ -242,17 +501,20 @@ function createLLMClient(config, initialBackend = config.llm.backend ?? "unknown
|
|
|
242
501
|
const thinkingField = config.llm.thinkingField;
|
|
243
502
|
const sendReasoningInMessages = config.llm.sendReasoningInMessages;
|
|
244
503
|
const idleTimeout = config.llm.idleTimeout ?? 12e4;
|
|
504
|
+
const currentApiProtocol = () => resolveApiProtocol({ model, backend, profileApiProtocol: profile.apiProtocol });
|
|
245
505
|
function buildExtraParams(resolvedEffort) {
|
|
246
506
|
return {
|
|
247
507
|
...resolvedEffort ? { reasoningEffort: resolvedEffort } : {},
|
|
248
508
|
...thinkingField ? { thinkingField } : {},
|
|
249
|
-
...sendReasoningInMessages !== void 0 ? { sendReasoningInMessages } : {}
|
|
509
|
+
...sendReasoningInMessages !== void 0 ? { sendReasoningInMessages } : {},
|
|
510
|
+
apiProtocol: currentApiProtocol()
|
|
250
511
|
};
|
|
251
512
|
}
|
|
252
513
|
return {
|
|
253
514
|
getModel() {
|
|
254
515
|
return model;
|
|
255
516
|
},
|
|
517
|
+
usesResponsesApi: () => currentApiProtocol() === "responses",
|
|
256
518
|
getProfile() {
|
|
257
519
|
return profile;
|
|
258
520
|
},
|
|
@@ -381,25 +643,25 @@ function createLLMClient(config, initialBackend = config.llm.backend ?? "unknown
|
|
|
381
643
|
const onAbort = () => clearInterval(idleTimer);
|
|
382
644
|
request.signal?.addEventListener("abort", onAbort, { once: true });
|
|
383
645
|
try {
|
|
384
|
-
for await (const
|
|
646
|
+
for await (const chunk2 of stream) {
|
|
385
647
|
if (idleTimeoutController.signal.aborted) {
|
|
386
648
|
throw new Error(`LLM stream idle timeout: no chunks received for ${idleTimeout}ms`);
|
|
387
649
|
}
|
|
388
650
|
lastChunkTime = Date.now();
|
|
389
|
-
if (!Array.isArray(
|
|
390
|
-
const streamError =
|
|
651
|
+
if (!Array.isArray(chunk2?.choices)) {
|
|
652
|
+
const streamError = chunk2?.error;
|
|
391
653
|
const errorMessage = typeof streamError === "string" ? streamError : streamError && typeof streamError === "object" && "message" in streamError && typeof streamError.message === "string" ? streamError.message : "Invalid LLM stream chunk: missing choices";
|
|
392
654
|
throw new LLMError(errorMessage);
|
|
393
655
|
}
|
|
394
|
-
responseId =
|
|
395
|
-
if (
|
|
656
|
+
responseId = chunk2.id;
|
|
657
|
+
if (chunk2.usage) {
|
|
396
658
|
usage = {
|
|
397
|
-
promptTokens:
|
|
398
|
-
completionTokens:
|
|
399
|
-
totalTokens:
|
|
659
|
+
promptTokens: chunk2.usage.prompt_tokens ?? usage.promptTokens,
|
|
660
|
+
completionTokens: chunk2.usage.completion_tokens ?? usage.completionTokens,
|
|
661
|
+
totalTokens: chunk2.usage.total_tokens ?? usage.totalTokens
|
|
400
662
|
};
|
|
401
663
|
}
|
|
402
|
-
const choice =
|
|
664
|
+
const choice = chunk2.choices[0];
|
|
403
665
|
if (!choice) continue;
|
|
404
666
|
if (choice.finish_reason) {
|
|
405
667
|
finishReason = mapFinishReason(choice.finish_reason);
|
|
@@ -506,4 +768,4 @@ function createLLMClient(config, initialBackend = config.llm.backend ?? "unknown
|
|
|
506
768
|
export {
|
|
507
769
|
createLLMClient
|
|
508
770
|
};
|
|
509
|
-
//# sourceMappingURL=chunk-
|
|
771
|
+
//# sourceMappingURL=chunk-DHDIKVRT.js.map
|