@qwen-code/arena-agent 0.0.9-dev.29 → 0.0.9-dev.30
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/.env.example +8 -0
- package/README.md +28 -9
- package/dist/agent.js +19 -1
- package/dist/agent.js.map +1 -1
- package/dist/compaction.js +8 -2
- package/dist/compaction.js.map +1 -1
- package/dist/config.d.ts +2 -0
- package/dist/config.js +11 -0
- package/dist/config.js.map +1 -1
- package/dist/model-diagnostics.js +11 -3
- package/dist/model-diagnostics.js.map +1 -1
- package/dist/openai-responses.d.ts +11 -0
- package/dist/openai-responses.js +399 -0
- package/dist/openai-responses.js.map +1 -0
- package/dist/provider.d.ts +4 -0
- package/dist/provider.js +164 -7
- package/dist/provider.js.map +1 -1
- package/dist/types.d.ts +5 -0
- package/package.json +1 -1
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
function record(value) {
|
|
2
|
+
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
3
|
+
? value
|
|
4
|
+
: {};
|
|
5
|
+
}
|
|
6
|
+
function stringValue(value) {
|
|
7
|
+
return typeof value === "string" ? value : "";
|
|
8
|
+
}
|
|
9
|
+
function responsesUserContent(content) {
|
|
10
|
+
if (!Array.isArray(content))
|
|
11
|
+
return content;
|
|
12
|
+
return content.map((part) => {
|
|
13
|
+
const value = record(part);
|
|
14
|
+
if (typeof value.image === "string") {
|
|
15
|
+
return {
|
|
16
|
+
type: "input_image",
|
|
17
|
+
image_url: value.image,
|
|
18
|
+
detail: "auto",
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
if (value.type === "image_url") {
|
|
22
|
+
const imageUrl = record(value.image_url);
|
|
23
|
+
return {
|
|
24
|
+
type: "input_image",
|
|
25
|
+
image_url: stringValue(imageUrl.url),
|
|
26
|
+
detail: stringValue(imageUrl.detail) || "auto",
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
return { type: "input_text", text: stringValue(value.text) };
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
/** Convert Arena's durable history into Responses API input items. */
|
|
33
|
+
export function responsesInput(messages) {
|
|
34
|
+
const input = [];
|
|
35
|
+
for (const message of messages) {
|
|
36
|
+
if (message.role === "system" || message.role === "user") {
|
|
37
|
+
input.push({
|
|
38
|
+
role: message.role,
|
|
39
|
+
content: responsesUserContent(message.content),
|
|
40
|
+
});
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
if (message.role === "tool") {
|
|
44
|
+
input.push({
|
|
45
|
+
type: "function_call_output",
|
|
46
|
+
call_id: message.tool_call_id,
|
|
47
|
+
output: message.content,
|
|
48
|
+
});
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
if (message.openai_response_items?.length) {
|
|
52
|
+
input.push(...structuredClone(message.openai_response_items));
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
// Compatibility fallback for histories created before Arena persisted
|
|
56
|
+
// native Responses output items.
|
|
57
|
+
if (message.content) {
|
|
58
|
+
input.push({ role: "assistant", content: message.content });
|
|
59
|
+
}
|
|
60
|
+
for (const call of message.tool_calls || []) {
|
|
61
|
+
input.push({
|
|
62
|
+
type: "function_call",
|
|
63
|
+
call_id: call.id,
|
|
64
|
+
name: call.function.name,
|
|
65
|
+
arguments: call.function.arguments,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return input;
|
|
70
|
+
}
|
|
71
|
+
function responsesTools(tools) {
|
|
72
|
+
return tools.map((tool) => ({
|
|
73
|
+
type: "function",
|
|
74
|
+
name: tool.function.name,
|
|
75
|
+
...(tool.function.description
|
|
76
|
+
? { description: tool.function.description }
|
|
77
|
+
: {}),
|
|
78
|
+
parameters: tool.function.parameters,
|
|
79
|
+
}));
|
|
80
|
+
}
|
|
81
|
+
/** Build a native OpenAI Responses request without Chat Completions fields. */
|
|
82
|
+
export function responsesRequestBody(request, model) {
|
|
83
|
+
const allTurnsReasoning = model.toLowerCase().includes("gpt-5.6");
|
|
84
|
+
const reasoning = request.reasoningEffort || allTurnsReasoning
|
|
85
|
+
? {
|
|
86
|
+
...(request.reasoningEffort
|
|
87
|
+
? { effort: request.reasoningEffort }
|
|
88
|
+
: {}),
|
|
89
|
+
...(allTurnsReasoning ? { context: "all_turns" } : {}),
|
|
90
|
+
}
|
|
91
|
+
: undefined;
|
|
92
|
+
return {
|
|
93
|
+
model,
|
|
94
|
+
input: responsesInput(request.messages),
|
|
95
|
+
...(request.tools.length
|
|
96
|
+
? { tools: responsesTools(request.tools), tool_choice: request.toolChoice }
|
|
97
|
+
: {}),
|
|
98
|
+
...(request.maxTokens !== undefined
|
|
99
|
+
? { max_output_tokens: request.maxTokens }
|
|
100
|
+
: {}),
|
|
101
|
+
// Do not inherit Arena's generic temperature on the native Responses path:
|
|
102
|
+
// reasoning models reject sampling controls. Non-reasoning models can opt
|
|
103
|
+
// in explicitly through ARENA_EXTRA_BODY, which is merged by the client.
|
|
104
|
+
...(reasoning ? { reasoning } : {}),
|
|
105
|
+
stream: true,
|
|
106
|
+
// Keep the transport stateless. Completed output items, including opaque
|
|
107
|
+
// encrypted reasoning, are persisted by Arena and replayed in input.
|
|
108
|
+
store: false,
|
|
109
|
+
include: ["reasoning.encrypted_content"],
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
function responsesUsage(value) {
|
|
113
|
+
const usage = record(value);
|
|
114
|
+
if (!Object.keys(usage).length)
|
|
115
|
+
return undefined;
|
|
116
|
+
const inputTokens = usage.input_tokens;
|
|
117
|
+
const outputTokens = usage.output_tokens;
|
|
118
|
+
const totalTokens = usage.total_tokens;
|
|
119
|
+
return {
|
|
120
|
+
...usage,
|
|
121
|
+
...(typeof inputTokens === "number" ? { prompt_tokens: inputTokens } : {}),
|
|
122
|
+
...(typeof outputTokens === "number"
|
|
123
|
+
? { completion_tokens: outputTokens }
|
|
124
|
+
: {}),
|
|
125
|
+
...(typeof totalTokens === "number" ? { total_tokens: totalTokens } : {}),
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function responsesError(event) {
|
|
129
|
+
const error = record(event.error);
|
|
130
|
+
const response = record(event.response);
|
|
131
|
+
const responseError = record(response.error);
|
|
132
|
+
const message = stringValue(error.message) ||
|
|
133
|
+
stringValue(responseError.message) ||
|
|
134
|
+
stringValue(event.message) ||
|
|
135
|
+
`OpenAI Responses stream failed (${stringValue(event.type) || "unknown event"})`;
|
|
136
|
+
return new Error(message);
|
|
137
|
+
}
|
|
138
|
+
function toolIndex(event, fallback) {
|
|
139
|
+
return typeof event.output_index === "number" ? event.output_index : fallback;
|
|
140
|
+
}
|
|
141
|
+
function toolDelta(state, values) {
|
|
142
|
+
return {
|
|
143
|
+
choices: [
|
|
144
|
+
{
|
|
145
|
+
delta: {
|
|
146
|
+
tool_calls: [
|
|
147
|
+
{
|
|
148
|
+
index: state.index,
|
|
149
|
+
...(values.id ? { id: values.id, type: "function" } : {}),
|
|
150
|
+
function: {
|
|
151
|
+
...(values.name ? { name: values.name } : {}),
|
|
152
|
+
...(values.arguments !== undefined
|
|
153
|
+
? { arguments: values.arguments }
|
|
154
|
+
: {}),
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
],
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
],
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
/** Translate native Responses SSE events into Arena's provider-neutral chunks. */
|
|
164
|
+
export async function* responsesChunks(stream) {
|
|
165
|
+
const reader = stream.getReader();
|
|
166
|
+
const decoder = new TextDecoder();
|
|
167
|
+
const tools = new Map();
|
|
168
|
+
const completedItemIndexes = new Set();
|
|
169
|
+
let buffer = "";
|
|
170
|
+
const captureOutputItem = function* (index, item, replace = false) {
|
|
171
|
+
if (!Object.keys(item).length ||
|
|
172
|
+
(!replace && completedItemIndexes.has(index))) {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
completedItemIndexes.add(index);
|
|
176
|
+
yield {
|
|
177
|
+
openai_response_items: [{ index, item: structuredClone(item) }],
|
|
178
|
+
};
|
|
179
|
+
};
|
|
180
|
+
const processEvent = function* (event) {
|
|
181
|
+
const type = stringValue(event.type);
|
|
182
|
+
const response = record(event.response);
|
|
183
|
+
if (type === "error" || type === "response.failed") {
|
|
184
|
+
throw responsesError(event);
|
|
185
|
+
}
|
|
186
|
+
if (type === "response.created" || type === "response.in_progress") {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
if (type === "response.output_text.delta" || type === "response.refusal.delta") {
|
|
190
|
+
yield {
|
|
191
|
+
choices: [{ delta: { content: stringValue(event.delta) } }],
|
|
192
|
+
};
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
if (type === "response.reasoning_summary_text.delta" ||
|
|
196
|
+
type === "response.reasoning_text.delta") {
|
|
197
|
+
yield {
|
|
198
|
+
choices: [{ delta: { reasoning_content: stringValue(event.delta) } }],
|
|
199
|
+
};
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
if (type === "response.output_item.added") {
|
|
203
|
+
const item = record(event.item);
|
|
204
|
+
if (item.type !== "function_call")
|
|
205
|
+
return;
|
|
206
|
+
const index = toolIndex(event, tools.size);
|
|
207
|
+
const state = {
|
|
208
|
+
index,
|
|
209
|
+
id: stringValue(item.call_id),
|
|
210
|
+
name: stringValue(item.name),
|
|
211
|
+
arguments: stringValue(item.arguments),
|
|
212
|
+
headerEmitted: true,
|
|
213
|
+
};
|
|
214
|
+
tools.set(index, state);
|
|
215
|
+
yield {
|
|
216
|
+
...toolDelta(state, {
|
|
217
|
+
id: state.id,
|
|
218
|
+
name: state.name,
|
|
219
|
+
...(state.arguments ? { arguments: state.arguments } : {}),
|
|
220
|
+
}),
|
|
221
|
+
};
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
if (type === "response.function_call_arguments.delta") {
|
|
225
|
+
const index = toolIndex(event, tools.size);
|
|
226
|
+
const state = tools.get(index) || {
|
|
227
|
+
index,
|
|
228
|
+
id: "",
|
|
229
|
+
name: "",
|
|
230
|
+
arguments: "",
|
|
231
|
+
headerEmitted: false,
|
|
232
|
+
};
|
|
233
|
+
const delta = stringValue(event.delta);
|
|
234
|
+
state.arguments += delta;
|
|
235
|
+
tools.set(index, state);
|
|
236
|
+
yield {
|
|
237
|
+
...toolDelta(state, { arguments: delta }),
|
|
238
|
+
};
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
if (type === "response.function_call_arguments.done" ||
|
|
242
|
+
type === "response.output_item.done") {
|
|
243
|
+
const item = record(event.item);
|
|
244
|
+
const index = toolIndex(event, tools.size);
|
|
245
|
+
if (type === "response.output_item.done") {
|
|
246
|
+
yield* captureOutputItem(index, item);
|
|
247
|
+
}
|
|
248
|
+
if (type === "response.output_item.done" && item.type !== "function_call") {
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
const state = tools.get(index) || {
|
|
252
|
+
index,
|
|
253
|
+
id: "",
|
|
254
|
+
name: "",
|
|
255
|
+
arguments: "",
|
|
256
|
+
headerEmitted: false,
|
|
257
|
+
};
|
|
258
|
+
const id = stringValue(item.call_id) || state.id;
|
|
259
|
+
const name = stringValue(item.name) || state.name;
|
|
260
|
+
const completeArguments = stringValue(event.arguments) || stringValue(item.arguments);
|
|
261
|
+
const suffix = completeArguments.startsWith(state.arguments)
|
|
262
|
+
? completeArguments.slice(state.arguments.length)
|
|
263
|
+
: state.arguments
|
|
264
|
+
? ""
|
|
265
|
+
: completeArguments;
|
|
266
|
+
if (!state.headerEmitted || suffix) {
|
|
267
|
+
yield {
|
|
268
|
+
...toolDelta(state, {
|
|
269
|
+
...(!state.headerEmitted && id ? { id } : {}),
|
|
270
|
+
...(!state.headerEmitted && name ? { name } : {}),
|
|
271
|
+
...(suffix ? { arguments: suffix } : {}),
|
|
272
|
+
}),
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
state.id = id;
|
|
276
|
+
state.name = name;
|
|
277
|
+
state.arguments = completeArguments || state.arguments;
|
|
278
|
+
state.headerEmitted = true;
|
|
279
|
+
tools.set(index, state);
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
if (type === "response.completed" || type === "response.incomplete") {
|
|
283
|
+
const completed = response;
|
|
284
|
+
if (Array.isArray(completed.output)) {
|
|
285
|
+
for (const [index, rawItem] of completed.output.entries()) {
|
|
286
|
+
// The completed response is authoritative and may carry fields such
|
|
287
|
+
// as encrypted_content that were absent from an earlier added/done
|
|
288
|
+
// event emitted by a compatible gateway.
|
|
289
|
+
yield* captureOutputItem(index, record(rawItem), true);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
const incompleteDetails = record(completed.incomplete_details);
|
|
293
|
+
const incompleteReason = stringValue(incompleteDetails.reason);
|
|
294
|
+
yield {
|
|
295
|
+
...(responsesUsage(completed.usage)
|
|
296
|
+
? { usage: responsesUsage(completed.usage) }
|
|
297
|
+
: {}),
|
|
298
|
+
choices: [
|
|
299
|
+
{
|
|
300
|
+
delta: {},
|
|
301
|
+
finish_reason: type === "response.incomplete" || incompleteReason
|
|
302
|
+
? incompleteReason === "max_output_tokens"
|
|
303
|
+
? "length"
|
|
304
|
+
: "incomplete"
|
|
305
|
+
: tools.size
|
|
306
|
+
? "tool_calls"
|
|
307
|
+
: "stop",
|
|
308
|
+
},
|
|
309
|
+
],
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
const consumeFrame = function* (frame) {
|
|
314
|
+
const payload = frame
|
|
315
|
+
.split("\n")
|
|
316
|
+
.filter((line) => line.startsWith("data:"))
|
|
317
|
+
.map((line) => line.slice(5).trimStart())
|
|
318
|
+
.join("\n");
|
|
319
|
+
if (!payload || payload === "[DONE]")
|
|
320
|
+
return;
|
|
321
|
+
yield* processEvent(JSON.parse(payload));
|
|
322
|
+
};
|
|
323
|
+
while (true) {
|
|
324
|
+
const { done, value } = await reader.read();
|
|
325
|
+
buffer += decoder.decode(value, { stream: !done }).replace(/\r\n/g, "\n");
|
|
326
|
+
let boundary = buffer.indexOf("\n\n");
|
|
327
|
+
while (boundary !== -1) {
|
|
328
|
+
yield* consumeFrame(buffer.slice(0, boundary));
|
|
329
|
+
buffer = buffer.slice(boundary + 2);
|
|
330
|
+
boundary = buffer.indexOf("\n\n");
|
|
331
|
+
}
|
|
332
|
+
if (done)
|
|
333
|
+
break;
|
|
334
|
+
}
|
|
335
|
+
if (buffer)
|
|
336
|
+
yield* consumeFrame(buffer);
|
|
337
|
+
}
|
|
338
|
+
/** Translate a non-streaming Responses object into one Arena chunk. */
|
|
339
|
+
export function responsesFallbackChunk(value) {
|
|
340
|
+
const output = Array.isArray(value.output) ? value.output : [];
|
|
341
|
+
const content = [];
|
|
342
|
+
const reasoning = [];
|
|
343
|
+
const toolCalls = [];
|
|
344
|
+
for (const rawItem of output) {
|
|
345
|
+
const item = record(rawItem);
|
|
346
|
+
if (item.type === "message" && Array.isArray(item.content)) {
|
|
347
|
+
for (const rawPart of item.content) {
|
|
348
|
+
const part = record(rawPart);
|
|
349
|
+
if (part.type === "output_text" || part.type === "refusal") {
|
|
350
|
+
content.push(stringValue(part.text) || stringValue(part.refusal));
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
else if (item.type === "reasoning" && Array.isArray(item.summary)) {
|
|
355
|
+
for (const rawPart of item.summary) {
|
|
356
|
+
reasoning.push(stringValue(record(rawPart).text));
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
else if (item.type === "function_call") {
|
|
360
|
+
toolCalls.push({
|
|
361
|
+
index: toolCalls.length,
|
|
362
|
+
id: stringValue(item.call_id),
|
|
363
|
+
type: "function",
|
|
364
|
+
function: {
|
|
365
|
+
name: stringValue(item.name),
|
|
366
|
+
arguments: stringValue(item.arguments),
|
|
367
|
+
},
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
const incompleteDetails = record(value.incomplete_details);
|
|
372
|
+
const incompleteReason = stringValue(incompleteDetails.reason);
|
|
373
|
+
return {
|
|
374
|
+
openai_response_items: output.map((rawItem, index) => ({
|
|
375
|
+
index,
|
|
376
|
+
item: structuredClone(record(rawItem)),
|
|
377
|
+
})),
|
|
378
|
+
usage: responsesUsage(value.usage),
|
|
379
|
+
choices: [
|
|
380
|
+
{
|
|
381
|
+
delta: {
|
|
382
|
+
...(content.length ? { content: content.join("") } : {}),
|
|
383
|
+
...(reasoning.length
|
|
384
|
+
? { reasoning_content: reasoning.join("") }
|
|
385
|
+
: {}),
|
|
386
|
+
...(toolCalls.length ? { tool_calls: toolCalls } : {}),
|
|
387
|
+
},
|
|
388
|
+
finish_reason: incompleteReason
|
|
389
|
+
? incompleteReason === "max_output_tokens"
|
|
390
|
+
? "length"
|
|
391
|
+
: "incomplete"
|
|
392
|
+
: toolCalls.length
|
|
393
|
+
? "tool_calls"
|
|
394
|
+
: "stop",
|
|
395
|
+
},
|
|
396
|
+
],
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
//# sourceMappingURL=openai-responses.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-responses.js","sourceRoot":"","sources":["../src/openai-responses.ts"],"names":[],"mappings":"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"}
|
package/dist/provider.d.ts
CHANGED
|
@@ -24,6 +24,9 @@ export interface ApiConnection {
|
|
|
24
24
|
liteLlmProxy: boolean;
|
|
25
25
|
headers: Record<string, string>;
|
|
26
26
|
}
|
|
27
|
+
export type ModelTransport = "anthropic-messages" | "openai-chat-completions" | "openai-responses";
|
|
28
|
+
/** Select the wire protocol without resolving credentials or making a request. */
|
|
29
|
+
export declare function modelTransport(config: ArenaConfig, requestedModel?: string): ModelTransport;
|
|
27
30
|
export declare function resolveApiConnection(config: ArenaConfig, requestedModel?: string): ApiConnection;
|
|
28
31
|
export declare function apiEndpoint(connection: ApiConnection, pathname: string): string;
|
|
29
32
|
export declare function withIdleTimeout(stream: ReadableStream<Uint8Array>, timeoutMs: number | undefined): ReadableStream<Uint8Array>;
|
|
@@ -48,6 +51,7 @@ export declare class HttpModelClient implements ModelClient {
|
|
|
48
51
|
private fetchWithHeadersTimeout;
|
|
49
52
|
private completionResponse;
|
|
50
53
|
stream(request: ModelRequest): AsyncIterable<ModelChunk>;
|
|
54
|
+
private streamOpenAIResponses;
|
|
51
55
|
private streamAnthropic;
|
|
52
56
|
}
|
|
53
57
|
export declare function checkedFetch(connection: ApiConnection, pathname: string, init: RequestInit): Promise<Response>;
|
package/dist/provider.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import crypto from "node:crypto";
|
|
2
2
|
import { anthropicChunks, anthropicFallbackChunk, anthropicRequestBody, } from "./anthropic.js";
|
|
3
3
|
import { diagnosticError, diagnosticValue, rawDiagnosticValue, requestDiagnosticSummary, requestMediaTypes, responseRequestIds, safeEndpoint, } from "./model-diagnostics.js";
|
|
4
|
+
import { responsesChunks, responsesFallbackChunk, responsesRequestBody, } from "./openai-responses.js";
|
|
4
5
|
const defaultModelTransportTimeoutMs = 300_000;
|
|
5
6
|
let undiciRuntimePromise;
|
|
6
7
|
async function modelUndiciRuntime() {
|
|
@@ -147,7 +148,7 @@ function wireMessages(messages) {
|
|
|
147
148
|
};
|
|
148
149
|
}
|
|
149
150
|
if (message.role === "assistant") {
|
|
150
|
-
const { usage: _usage, reasoning_details: _details, reasoning_content: reasoningContent, ...wire } = message;
|
|
151
|
+
const { usage: _usage, reasoning_details: _details, openai_response_items: _responseItems, reasoning_content: reasoningContent, ...wire } = message;
|
|
151
152
|
return {
|
|
152
153
|
...wire,
|
|
153
154
|
...(reasoningContent ? { reasoning_content: reasoningContent } : {}),
|
|
@@ -158,13 +159,39 @@ function wireMessages(messages) {
|
|
|
158
159
|
}
|
|
159
160
|
function stripProviderPrefix(model) {
|
|
160
161
|
const separator = model.indexOf("/");
|
|
161
|
-
if (separator === -1)
|
|
162
|
-
|
|
162
|
+
if (separator === -1) {
|
|
163
|
+
const normalized = model.toLowerCase();
|
|
164
|
+
return {
|
|
165
|
+
provider: normalized.includes("gpt") || !normalized.includes("claude")
|
|
166
|
+
? "openai"
|
|
167
|
+
: "anthropic",
|
|
168
|
+
model,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
163
171
|
return {
|
|
164
172
|
provider: model.slice(0, separator),
|
|
165
173
|
model: model.slice(separator + 1),
|
|
166
174
|
};
|
|
167
175
|
}
|
|
176
|
+
/** Select the wire protocol without resolving credentials or making a request. */
|
|
177
|
+
export function modelTransport(config, requestedModel = config.model) {
|
|
178
|
+
if (config.liteLlmProxyUrl)
|
|
179
|
+
return "openai-chat-completions";
|
|
180
|
+
const parsed = stripProviderPrefix(requestedModel);
|
|
181
|
+
const provider = parsed.provider === "google" ? "gemini" : parsed.provider.toLowerCase();
|
|
182
|
+
if (provider === "anthropic")
|
|
183
|
+
return "anthropic-messages";
|
|
184
|
+
if (provider !== "openai")
|
|
185
|
+
return "openai-chat-completions";
|
|
186
|
+
if (config.openaiApi === "responses")
|
|
187
|
+
return "openai-responses";
|
|
188
|
+
if (config.openaiApi === "chat-completions") {
|
|
189
|
+
return "openai-chat-completions";
|
|
190
|
+
}
|
|
191
|
+
return parsed.model.toLowerCase().includes("gpt")
|
|
192
|
+
? "openai-responses"
|
|
193
|
+
: "openai-chat-completions";
|
|
194
|
+
}
|
|
168
195
|
export function resolveApiConnection(config, requestedModel = config.model) {
|
|
169
196
|
if (config.liteLlmProxyUrl) {
|
|
170
197
|
const apiKey = config.liteLlmApiKey || config.apiKey || process.env.LITELLM_API_KEY || "";
|
|
@@ -355,8 +382,12 @@ class DiagnosticResponseAccumulator {
|
|
|
355
382
|
content = [];
|
|
356
383
|
reasoning = [];
|
|
357
384
|
toolCalls = new Map();
|
|
385
|
+
responseItems = new Map();
|
|
358
386
|
reasoningDetails;
|
|
359
387
|
add(chunk) {
|
|
388
|
+
for (const value of chunk.openai_response_items || []) {
|
|
389
|
+
this.responseItems.set(value.index, structuredClone(value.item));
|
|
390
|
+
}
|
|
360
391
|
if (chunk.reasoning_details?.length) {
|
|
361
392
|
this.reasoningDetails = chunk.reasoning_details;
|
|
362
393
|
}
|
|
@@ -401,6 +432,13 @@ class DiagnosticResponseAccumulator {
|
|
|
401
432
|
...(this.reasoningDetails
|
|
402
433
|
? { reasoning_details: this.reasoningDetails }
|
|
403
434
|
: {}),
|
|
435
|
+
...(this.responseItems.size
|
|
436
|
+
? {
|
|
437
|
+
openai_response_items: [...this.responseItems.entries()]
|
|
438
|
+
.sort(([left], [right]) => left - right)
|
|
439
|
+
.map(([, item]) => item),
|
|
440
|
+
}
|
|
441
|
+
: {}),
|
|
404
442
|
finish_reason: reasons.at(-1) || null,
|
|
405
443
|
};
|
|
406
444
|
}
|
|
@@ -602,19 +640,22 @@ export class HttpModelClient {
|
|
|
602
640
|
}
|
|
603
641
|
async *stream(request) {
|
|
604
642
|
const connection = resolveApiConnection(this.config, request.model);
|
|
643
|
+
const transport = modelTransport(this.config, request.model);
|
|
605
644
|
const context = {
|
|
606
645
|
callId: crypto.randomUUID(),
|
|
607
|
-
protocol:
|
|
608
|
-
? "anthropic-messages"
|
|
609
|
-
: "openai-chat-completions",
|
|
646
|
+
protocol: transport,
|
|
610
647
|
};
|
|
611
648
|
// Direct anthropic/ connections speak the native Messages protocol; the
|
|
612
649
|
// LiteLLM proxy path resolves to provider "litellm" and stays on the
|
|
613
650
|
// OpenAI-compatible wire format below.
|
|
614
|
-
if (
|
|
651
|
+
if (transport === "anthropic-messages") {
|
|
615
652
|
yield* this.streamAnthropic(connection, request, context);
|
|
616
653
|
return;
|
|
617
654
|
}
|
|
655
|
+
if (transport === "openai-responses") {
|
|
656
|
+
yield* this.streamOpenAIResponses(connection, request, context);
|
|
657
|
+
return;
|
|
658
|
+
}
|
|
618
659
|
const body = {
|
|
619
660
|
model: connection.model,
|
|
620
661
|
messages: wireMessages(request.messages),
|
|
@@ -752,6 +793,122 @@ export class HttpModelClient {
|
|
|
752
793
|
throw error;
|
|
753
794
|
}
|
|
754
795
|
}
|
|
796
|
+
async *streamOpenAIResponses(connection, request, context) {
|
|
797
|
+
const body = responsesRequestBody(request, connection.model);
|
|
798
|
+
if (this.config.extraBody && !request.useProviderDefaults) {
|
|
799
|
+
Object.assign(body, this.config.extraBody);
|
|
800
|
+
}
|
|
801
|
+
// Accept the most common Chat Completions spellings in shared rollout
|
|
802
|
+
// configuration, but never send them to the native Responses endpoint.
|
|
803
|
+
if (body.reasoning_effort !== undefined && body.reasoning === undefined) {
|
|
804
|
+
body.reasoning = { effort: body.reasoning_effort };
|
|
805
|
+
}
|
|
806
|
+
if (body.max_tokens !== undefined && body.max_output_tokens === undefined) {
|
|
807
|
+
body.max_output_tokens = body.max_tokens;
|
|
808
|
+
}
|
|
809
|
+
if (body.max_completion_tokens !== undefined &&
|
|
810
|
+
body.max_output_tokens === undefined) {
|
|
811
|
+
body.max_output_tokens = body.max_completion_tokens;
|
|
812
|
+
}
|
|
813
|
+
for (const key of [
|
|
814
|
+
"reasoning_effort",
|
|
815
|
+
"max_tokens",
|
|
816
|
+
"max_completion_tokens",
|
|
817
|
+
"messages",
|
|
818
|
+
"previous_response_id",
|
|
819
|
+
"conversation",
|
|
820
|
+
"stream_options",
|
|
821
|
+
"incremental_output",
|
|
822
|
+
"result_format",
|
|
823
|
+
"enable_thinking",
|
|
824
|
+
"thinking_budget",
|
|
825
|
+
"preserve_thinking",
|
|
826
|
+
]) {
|
|
827
|
+
delete body[key];
|
|
828
|
+
}
|
|
829
|
+
const include = Array.isArray(body.include)
|
|
830
|
+
? body.include.filter((value) => typeof value === "string")
|
|
831
|
+
: [];
|
|
832
|
+
if (!include.includes("reasoning.encrypted_content")) {
|
|
833
|
+
include.push("reasoning.encrypted_content");
|
|
834
|
+
}
|
|
835
|
+
body.include = include;
|
|
836
|
+
body.store = false;
|
|
837
|
+
body.stream = true;
|
|
838
|
+
const endpoint = apiEndpoint(connection, "/responses");
|
|
839
|
+
const startedAt = this.now();
|
|
840
|
+
const mediaTypes = requestMediaTypes(body);
|
|
841
|
+
await this.recordRequest(context, connection, endpoint, body);
|
|
842
|
+
try {
|
|
843
|
+
const { response, httpAttempt } = await this.completionResponse(endpoint, {
|
|
844
|
+
method: "POST",
|
|
845
|
+
headers: {
|
|
846
|
+
"content-type": "application/json",
|
|
847
|
+
...connection.headers,
|
|
848
|
+
...this.affinityHeaders,
|
|
849
|
+
},
|
|
850
|
+
body: JSON.stringify(body),
|
|
851
|
+
signal: request.signal,
|
|
852
|
+
}, context);
|
|
853
|
+
await this.recordResponseHeaders(context, response, httpAttempt, startedAt);
|
|
854
|
+
if (!response.ok) {
|
|
855
|
+
const rawResponseBody = await response.text();
|
|
856
|
+
const original = responseErrorFromText(response, rawResponseBody);
|
|
857
|
+
Object.assign(original, { rawResponseBody });
|
|
858
|
+
const capabilityHint = mediaTypes.length > 0 &&
|
|
859
|
+
isMediaContentRejection(original.message)
|
|
860
|
+
? `The request included media content (${mediaTypes.join(", ")}), ` +
|
|
861
|
+
`but model "${connection.model}" or its selected endpoint rejected ` +
|
|
862
|
+
"a content part. Verify that the configured route supports those " +
|
|
863
|
+
"media types; Arena did not automatically switch models."
|
|
864
|
+
: undefined;
|
|
865
|
+
throw capabilityHint
|
|
866
|
+
? Object.assign(new ModelCapabilityError(capabilityHint, original, mediaTypes), { rawResponseBody })
|
|
867
|
+
: original;
|
|
868
|
+
}
|
|
869
|
+
let chunks = 0;
|
|
870
|
+
const finishReasons = new Set();
|
|
871
|
+
const aggregatedResponse = new DiagnosticResponseAccumulator();
|
|
872
|
+
let usage;
|
|
873
|
+
if (response.body &&
|
|
874
|
+
(response.headers.get("content-type") || "").includes("text/event-stream")) {
|
|
875
|
+
for await (const chunk of responsesChunks(withIdleTimeout(response.body, this.config.modelStreamIdleTimeoutMs))) {
|
|
876
|
+
chunks += 1;
|
|
877
|
+
aggregatedResponse.add(chunk);
|
|
878
|
+
if (chunk.usage)
|
|
879
|
+
usage = chunk.usage;
|
|
880
|
+
for (const choice of chunk.choices || []) {
|
|
881
|
+
if (choice.finish_reason)
|
|
882
|
+
finishReasons.add(choice.finish_reason);
|
|
883
|
+
}
|
|
884
|
+
yield chunk;
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
else {
|
|
888
|
+
const value = (await response.json());
|
|
889
|
+
const chunk = responsesFallbackChunk(value);
|
|
890
|
+
chunks = 1;
|
|
891
|
+
aggregatedResponse.add(chunk);
|
|
892
|
+
usage = chunk.usage;
|
|
893
|
+
for (const choice of chunk.choices || []) {
|
|
894
|
+
if (choice.finish_reason)
|
|
895
|
+
finishReasons.add(choice.finish_reason);
|
|
896
|
+
}
|
|
897
|
+
yield chunk;
|
|
898
|
+
}
|
|
899
|
+
await this.recordAggregatedResponse(context, aggregatedResponse, finishReasons);
|
|
900
|
+
await this.recordCompletion(context, startedAt, chunks, finishReasons, usage);
|
|
901
|
+
}
|
|
902
|
+
catch (error) {
|
|
903
|
+
await this.recordCallError(context, startedAt, error, error instanceof ModelCapabilityError
|
|
904
|
+
? error.capabilityHint
|
|
905
|
+
: undefined, typeof error?.rawResponseBody ===
|
|
906
|
+
"string"
|
|
907
|
+
? error.rawResponseBody
|
|
908
|
+
: undefined);
|
|
909
|
+
throw error;
|
|
910
|
+
}
|
|
911
|
+
}
|
|
755
912
|
async *streamAnthropic(connection, request, context) {
|
|
756
913
|
const body = anthropicRequestBody(request, connection.model);
|
|
757
914
|
if (this.config.extraBody && !request.useProviderDefaults) {
|