@opencode-ai/ai 0.0.0-beta-17595 → 0.0.0-beta-17727
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -6
- package/dist/cache-policy.js +3 -5
- package/dist/protocols/anthropic-messages.d.ts +26 -28
- package/dist/protocols/anthropic-messages.js +21 -9
- package/dist/protocols/gemini.d.ts +5 -9
- package/dist/protocols/gemini.js +5 -4
- package/dist/protocols/open-responses.d.ts +200 -38
- package/dist/protocols/open-responses.js +115 -42
- package/dist/protocols/openai-chat.d.ts +17 -15
- package/dist/protocols/openai-chat.js +8 -2
- package/dist/protocols/openai-compatible-chat.d.ts +3 -3
- package/dist/protocols/openai-compatible-responses.d.ts +31 -5
- package/dist/protocols/openai-responses.d.ts +171 -33
- package/dist/protocols/openai-responses.js +4 -2
- package/dist/protocols/shared.d.ts +8 -14
- package/dist/protocols/shared.js +8 -14
- package/dist/protocols/utils/bedrock-cache.js +3 -4
- package/dist/protocols/utils/cache.js +3 -6
- package/dist/protocols/utils/open-responses-options.d.ts +49 -14
- package/dist/protocols/utils/open-responses-options.js +40 -22
- package/dist/protocols/utils/openai-options.d.ts +7 -5
- package/dist/protocols/utils/openai-options.js +3 -3
- package/dist/provider-package.d.ts +0 -5
- package/dist/providers/amazon-bedrock-mantle.d.ts +47 -19
- package/dist/providers/amazon-bedrock-mantle.js +0 -1
- package/dist/providers/amazon-bedrock.d.ts +3 -9
- package/dist/providers/amazon-bedrock.js +0 -1
- package/dist/providers/anthropic-compatible.d.ts +11 -11
- package/dist/providers/anthropic-compatible.js +0 -1
- package/dist/providers/anthropic.d.ts +12 -12
- package/dist/providers/anthropic.js +0 -1
- package/dist/providers/azure.d.ts +44 -16
- package/dist/providers/azure.js +0 -1
- package/dist/providers/cloudflare.d.ts +11 -11
- package/dist/providers/google-vertex-chat.d.ts +5 -5
- package/dist/providers/google-vertex-chat.js +0 -1
- package/dist/providers/google-vertex-messages.d.ts +11 -11
- package/dist/providers/google-vertex-messages.js +0 -1
- package/dist/providers/google-vertex-responses.d.ts +33 -7
- package/dist/providers/google-vertex-responses.js +1 -2
- package/dist/providers/google-vertex.d.ts +5 -7
- package/dist/providers/google-vertex.js +1 -2
- package/dist/providers/google.d.ts +4 -4
- package/dist/providers/google.js +0 -1
- package/dist/providers/open-responses-options.d.ts +3 -13
- package/dist/providers/openai-compatible-responses.d.ts +33 -7
- package/dist/providers/openai-compatible-responses.js +0 -1
- package/dist/providers/openai-compatible.d.ts +13 -12
- package/dist/providers/openai-compatible.js +1 -1
- package/dist/providers/openai-options.d.ts +2 -4
- package/dist/providers/openai-options.js +3 -3
- package/dist/providers/openai.d.ts +48 -20
- package/dist/providers/openai.js +0 -1
- package/dist/providers/openrouter.d.ts +16 -17
- package/dist/providers/openrouter.js +1 -2
- package/dist/providers/xai.d.ts +50 -24
- package/dist/providers/xai.js +1 -2
- package/dist/route/client.d.ts +2 -6
- package/dist/route/client.js +1 -2
- package/dist/route/framing.d.ts +2 -2
- package/dist/route/protocol.d.ts +1 -2
- package/dist/route/protocol.js +1 -2
- package/dist/schema/errors.js +2 -1
- package/dist/schema/events.d.ts +5 -3
- package/dist/schema/events.js +5 -2
- package/dist/schema/ids.d.ts +0 -13
- package/dist/schema/ids.js +0 -9
- package/dist/schema/messages.d.ts +7 -7
- package/dist/schema/messages.js +5 -2
- package/dist/schema/options.d.ts +6 -22
- package/dist/schema/options.js +6 -30
- package/dist/testing.d.ts +2 -1
- package/dist/testing.js +7 -2
- package/package.json +5 -5
|
@@ -63,8 +63,11 @@ const OpenResponsesFunctionCallOutput = Schema.Union([
|
|
|
63
63
|
]);
|
|
64
64
|
export const InputItem = Schema.Union([
|
|
65
65
|
Schema.Struct({ role: Schema.tag("system"), content: Schema.String }),
|
|
66
|
+
Schema.Struct({ role: Schema.tag("developer"), content: Schema.String }),
|
|
66
67
|
Schema.Struct({ role: Schema.tag("user"), content: Schema.Array(OpenResponsesInputContent) }),
|
|
67
68
|
Schema.Struct({
|
|
69
|
+
type: Schema.tag("message"),
|
|
70
|
+
id: Schema.optionalKey(Schema.String),
|
|
68
71
|
role: Schema.tag("assistant"),
|
|
69
72
|
content: Schema.Array(OpenResponsesOutputText),
|
|
70
73
|
phase: Schema.optionalKey(MessagePhase),
|
|
@@ -73,6 +76,7 @@ export const InputItem = Schema.Union([
|
|
|
73
76
|
OpenResponsesItemReference,
|
|
74
77
|
Schema.Struct({
|
|
75
78
|
type: Schema.tag("function_call"),
|
|
79
|
+
id: Schema.optionalKey(Schema.String),
|
|
76
80
|
call_id: Schema.String,
|
|
77
81
|
name: Schema.String,
|
|
78
82
|
arguments: Schema.String,
|
|
@@ -93,6 +97,11 @@ export const Tool = Schema.Struct({
|
|
|
93
97
|
export const ToolChoice = Schema.Union([
|
|
94
98
|
Schema.Literals(["auto", "none", "required"]),
|
|
95
99
|
Schema.Struct({ type: Schema.tag("function"), name: Schema.String }),
|
|
100
|
+
Schema.Struct({
|
|
101
|
+
type: Schema.tag("allowed_tools"),
|
|
102
|
+
mode: Schema.Literals(["auto", "none", "required"]),
|
|
103
|
+
tools: Schema.Array(Schema.Struct({ type: Schema.tag("function"), name: Schema.String })),
|
|
104
|
+
}),
|
|
96
105
|
]);
|
|
97
106
|
// Fields shared between the HTTP body and the WebSocket `response.create`
|
|
98
107
|
// message. The HTTP body adds `stream: true`; the WebSocket message adds
|
|
@@ -105,6 +114,13 @@ export const coreFields = {
|
|
|
105
114
|
tools: optionalArray(Tool),
|
|
106
115
|
tool_choice: Schema.optional(ToolChoice),
|
|
107
116
|
store: Schema.optional(Schema.Boolean),
|
|
117
|
+
metadata: Schema.optional(Schema.Record(Schema.String, Schema.String)),
|
|
118
|
+
safety_identifier: Schema.optional(Schema.String),
|
|
119
|
+
stream_options: Schema.optional(Schema.Struct({
|
|
120
|
+
include_obfuscation: Schema.optional(Schema.Boolean),
|
|
121
|
+
})),
|
|
122
|
+
top_logprobs: Schema.optional(Schema.Int.check(Schema.isBetween({ minimum: 0, maximum: 20 }))),
|
|
123
|
+
truncation: Schema.optional(OpenResponsesOptions.TruncationSchema),
|
|
108
124
|
service_tier: Schema.optional(OpenResponsesOptions.ServiceTierSchema),
|
|
109
125
|
prompt_cache_key: Schema.optional(Schema.String),
|
|
110
126
|
include: optionalArray(OpenResponsesOptions.ResponseIncludableSchema),
|
|
@@ -116,8 +132,12 @@ export const coreFields = {
|
|
|
116
132
|
verbosity: Schema.optional(OpenResponsesOptions.TextVerbositySchema),
|
|
117
133
|
})),
|
|
118
134
|
max_output_tokens: Schema.optional(Schema.Number),
|
|
135
|
+
max_tool_calls: Schema.optional(Schema.Int),
|
|
136
|
+
parallel_tool_calls: Schema.optional(Schema.Boolean),
|
|
119
137
|
temperature: Schema.optional(Schema.Number),
|
|
120
138
|
top_p: Schema.optional(Schema.Number),
|
|
139
|
+
presence_penalty: Schema.optional(Schema.Number),
|
|
140
|
+
frequency_penalty: Schema.optional(Schema.Number),
|
|
121
141
|
};
|
|
122
142
|
const OpenResponsesBody = Schema.Struct({
|
|
123
143
|
...coreFields,
|
|
@@ -193,6 +213,19 @@ export const Event = Schema.StructWithRest(Schema.Struct({
|
|
|
193
213
|
status_code: Schema.optional(Schema.Unknown),
|
|
194
214
|
headers: Schema.optional(Schema.Unknown),
|
|
195
215
|
}), [Schema.Record(Schema.String, Schema.Unknown)]);
|
|
216
|
+
const RefusalEvent = Schema.Union([
|
|
217
|
+
Schema.Struct({
|
|
218
|
+
type: Schema.tag("response.refusal.delta"),
|
|
219
|
+
item_id: Schema.String,
|
|
220
|
+
delta: Schema.String,
|
|
221
|
+
}),
|
|
222
|
+
Schema.Struct({
|
|
223
|
+
type: Schema.tag("response.refusal.done"),
|
|
224
|
+
item_id: Schema.String,
|
|
225
|
+
refusal: Schema.String,
|
|
226
|
+
}),
|
|
227
|
+
]);
|
|
228
|
+
const isRefusalEvent = Schema.is(RefusalEvent);
|
|
196
229
|
const BASE = { id: ADAPTER, name: NAME };
|
|
197
230
|
// =============================================================================
|
|
198
231
|
// Request Lowering
|
|
@@ -205,7 +238,7 @@ export const lowerTool = Effect.fn("OpenResponses.lowerTool")(function* (protoco
|
|
|
205
238
|
name: tool.name,
|
|
206
239
|
description: tool.description,
|
|
207
240
|
parameters: ToolSchemaProjection.responses(inputSchema),
|
|
208
|
-
//
|
|
241
|
+
// The common tool definition does not currently express Responses strict-schema policy.
|
|
209
242
|
strict: false,
|
|
210
243
|
};
|
|
211
244
|
});
|
|
@@ -215,31 +248,39 @@ export const lowerToolChoice = (protocolName, toolChoice) => ProviderShared.matc
|
|
|
215
248
|
required: () => "required",
|
|
216
249
|
tool: (toolName) => ({ type: "function", name: toolName }),
|
|
217
250
|
});
|
|
218
|
-
const
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
}
|
|
251
|
+
const itemID = (providerMetadata, providerMetadataKey) => {
|
|
252
|
+
const metadata = providerMetadata?.[providerMetadataKey];
|
|
253
|
+
return ProviderShared.isRecord(metadata) && typeof metadata.itemId === "string" && metadata.itemId.length > 0
|
|
254
|
+
? metadata.itemId
|
|
255
|
+
: undefined;
|
|
256
|
+
};
|
|
257
|
+
const lowerToolCall = (part, providerMetadataKey) => {
|
|
258
|
+
const id = itemID(part.providerMetadata, providerMetadataKey);
|
|
259
|
+
return {
|
|
260
|
+
type: "function_call",
|
|
261
|
+
...(id ? { id } : {}),
|
|
262
|
+
call_id: part.id,
|
|
263
|
+
name: part.name,
|
|
264
|
+
arguments: ProviderShared.encodeJson(part.input),
|
|
265
|
+
};
|
|
266
|
+
};
|
|
224
267
|
const lowerReasoning = (part, providerMetadataKey) => {
|
|
225
268
|
const metadata = part.providerMetadata?.[providerMetadataKey];
|
|
226
|
-
|
|
269
|
+
const id = itemID(part.providerMetadata, providerMetadataKey);
|
|
270
|
+
if (!ProviderShared.isRecord(metadata) || !id)
|
|
227
271
|
return undefined;
|
|
228
272
|
const encryptedContent = typeof metadata.reasoningEncryptedContent === "string" || metadata.reasoningEncryptedContent === null
|
|
229
273
|
? metadata.reasoningEncryptedContent
|
|
230
274
|
: undefined;
|
|
231
275
|
return {
|
|
232
276
|
type: "reasoning",
|
|
233
|
-
id
|
|
277
|
+
id,
|
|
234
278
|
summary: part.text.length > 0 ? [{ type: "summary_text", text: part.text }] : [],
|
|
235
279
|
encrypted_content: encryptedContent,
|
|
236
280
|
};
|
|
237
281
|
};
|
|
238
282
|
const hostedToolItemID = (part, providerMetadataKey) => {
|
|
239
|
-
|
|
240
|
-
return ProviderShared.isRecord(metadata) && typeof metadata.itemId === "string" && metadata.itemId.length > 0
|
|
241
|
-
? metadata.itemId
|
|
242
|
-
: undefined;
|
|
283
|
+
return itemID(part.providerMetadata, providerMetadataKey);
|
|
243
284
|
};
|
|
244
285
|
const lowerMedia = Effect.fn("OpenResponses.lowerMedia")(function* (part, request, extension) {
|
|
245
286
|
const media = ProviderShared.normalizeMedia(part);
|
|
@@ -285,15 +326,10 @@ const lowerMessages = Effect.fn("OpenResponses.lowerMessages")(function* (reques
|
|
|
285
326
|
const providerMetadataKey = request.model.route.providerMetadataKey ?? "openresponses";
|
|
286
327
|
for (const message of request.messages) {
|
|
287
328
|
if (message.role === "system") {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
role: "user",
|
|
293
|
-
content: [...previous.content, { type: "input_text", text: part.text }],
|
|
294
|
-
};
|
|
295
|
-
else
|
|
296
|
-
input.push({ role: "user", content: [{ type: "input_text", text: part.text }] });
|
|
329
|
+
input.push({
|
|
330
|
+
role: "developer",
|
|
331
|
+
content: ProviderShared.joinText(yield* ProviderShared.systemUpdateText(extension.name, message)),
|
|
332
|
+
});
|
|
297
333
|
continue;
|
|
298
334
|
}
|
|
299
335
|
if (message.role === "user") {
|
|
@@ -313,15 +349,18 @@ const lowerMessages = Effect.fn("OpenResponses.lowerMessages")(function* (reques
|
|
|
313
349
|
return;
|
|
314
350
|
const groups = content.reduce((groups, part) => {
|
|
315
351
|
const metadata = part.providerMetadata?.[providerMetadataKey];
|
|
352
|
+
const id = itemID(part.providerMetadata, providerMetadataKey);
|
|
316
353
|
const phase = ProviderShared.isRecord(metadata) ? messagePhase(metadata.phase, extension) : undefined;
|
|
317
354
|
const group = groups.at(-1);
|
|
318
|
-
if (group && group.phase === phase)
|
|
355
|
+
if (group && group.id === id && group.phase === phase)
|
|
319
356
|
group.parts.push(part);
|
|
320
357
|
else
|
|
321
|
-
groups.push({ phase, parts: [part] });
|
|
358
|
+
groups.push({ id, phase, parts: [part] });
|
|
322
359
|
return groups;
|
|
323
360
|
}, []);
|
|
324
361
|
input.push(...groups.map((group) => ({
|
|
362
|
+
type: "message",
|
|
363
|
+
...(group.id === undefined ? {} : { id: group.id }),
|
|
325
364
|
role: "assistant",
|
|
326
365
|
content: group.parts.map((part) => ({ type: "output_text", text: part.text })),
|
|
327
366
|
...(group.phase === undefined ? {} : { phase: group.phase }),
|
|
@@ -351,20 +390,15 @@ const lowerMessages = Effect.fn("OpenResponses.lowerMessages")(function* (reques
|
|
|
351
390
|
existing.encrypted_content = reasoning.encrypted_content;
|
|
352
391
|
continue;
|
|
353
392
|
}
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
summary: reasoning.summary,
|
|
357
|
-
encrypted_content: reasoning.encrypted_content,
|
|
358
|
-
};
|
|
359
|
-
reasoningItems[reasoning.id] = replay;
|
|
360
|
-
input.push(replay);
|
|
393
|
+
reasoningItems[reasoning.id] = reasoning;
|
|
394
|
+
input.push(reasoning);
|
|
361
395
|
continue;
|
|
362
396
|
}
|
|
363
397
|
if (part.type === "tool-call") {
|
|
364
398
|
flushText();
|
|
365
399
|
if (part.providerExecuted === true)
|
|
366
400
|
continue;
|
|
367
|
-
input.push(lowerToolCall(part));
|
|
401
|
+
input.push(lowerToolCall(part, providerMetadataKey));
|
|
368
402
|
continue;
|
|
369
403
|
}
|
|
370
404
|
if (part.type === "tool-result" && part.providerExecuted === true) {
|
|
@@ -415,6 +449,12 @@ const lowerOptions = (request) => {
|
|
|
415
449
|
return {
|
|
416
450
|
...(options.instructions ? { instructions: options.instructions } : {}),
|
|
417
451
|
...(options.store !== undefined ? { store: options.store } : {}),
|
|
452
|
+
...(options.metadata ? { metadata: options.metadata } : {}),
|
|
453
|
+
...(options.safetyIdentifier ? { safety_identifier: options.safetyIdentifier } : {}),
|
|
454
|
+
...(options.streamOptions?.includeObfuscation !== undefined
|
|
455
|
+
? { stream_options: { include_obfuscation: options.streamOptions.includeObfuscation } }
|
|
456
|
+
: {}),
|
|
457
|
+
...(options.topLogprobs !== undefined ? { top_logprobs: options.topLogprobs } : {}),
|
|
418
458
|
...(request.promptCacheKey ? { prompt_cache_key: request.promptCacheKey } : {}),
|
|
419
459
|
...(options.include ? { include: options.include } : {}),
|
|
420
460
|
...(options.reasoningEffort || options.reasoningSummary
|
|
@@ -422,6 +462,19 @@ const lowerOptions = (request) => {
|
|
|
422
462
|
: {}),
|
|
423
463
|
...(options.textVerbosity ? { text: { verbosity: options.textVerbosity } } : {}),
|
|
424
464
|
...(options.serviceTier ? { service_tier: options.serviceTier } : {}),
|
|
465
|
+
...(options.maxToolCalls !== undefined ? { max_tool_calls: options.maxToolCalls } : {}),
|
|
466
|
+
...(options.parallelToolCalls !== undefined ? { parallel_tool_calls: options.parallelToolCalls } : {}),
|
|
467
|
+
...(options.truncation ? { truncation: options.truncation } : {}),
|
|
468
|
+
};
|
|
469
|
+
};
|
|
470
|
+
const allowedToolChoice = (request) => {
|
|
471
|
+
const allowed = OpenResponsesOptions.resolve(request).allowedTools;
|
|
472
|
+
if (!allowed)
|
|
473
|
+
return undefined;
|
|
474
|
+
return {
|
|
475
|
+
type: "allowed_tools",
|
|
476
|
+
mode: allowed.mode,
|
|
477
|
+
tools: allowed.toolNames.map((name) => ({ type: "function", name })),
|
|
425
478
|
};
|
|
426
479
|
};
|
|
427
480
|
export const fromRequestWithExtension = Effect.fn("OpenResponses.fromRequestWithExtension")(function* (request, extension) {
|
|
@@ -433,11 +486,14 @@ export const fromRequestWithExtension = Effect.fn("OpenResponses.fromRequestWith
|
|
|
433
486
|
tools: request.tools.length === 0
|
|
434
487
|
? undefined
|
|
435
488
|
: yield* Effect.forEach(request.tools, (tool) => lowerTool(extension.name, tool, ToolSchemaProjection.modelCompatibility(tool.inputSchema, toolSchemaCompatibility))),
|
|
436
|
-
tool_choice:
|
|
489
|
+
tool_choice: allowedToolChoice(request) ??
|
|
490
|
+
(request.toolChoice ? yield* lowerToolChoice(extension.name, request.toolChoice) : undefined),
|
|
437
491
|
stream: true,
|
|
438
492
|
max_output_tokens: generation?.maxTokens,
|
|
439
493
|
temperature: generation?.temperature,
|
|
440
494
|
top_p: generation?.topP,
|
|
495
|
+
presence_penalty: generation?.presencePenalty,
|
|
496
|
+
frequency_penalty: generation?.frequencyPenalty,
|
|
441
497
|
...lowerOptions(request),
|
|
442
498
|
};
|
|
443
499
|
});
|
|
@@ -500,7 +556,7 @@ const onOutputTextDelta = (state, event, id) => {
|
|
|
500
556
|
return [state, NO_EVENTS];
|
|
501
557
|
const events = [];
|
|
502
558
|
const phase = state.messagePhases[id];
|
|
503
|
-
const metadata = phase === undefined ?
|
|
559
|
+
const metadata = providerMetadata(state, { itemId: id, ...(phase === undefined ? {} : { phase }) });
|
|
504
560
|
const lifecycle = Lifecycle.textStart(state.lifecycle, events, id, metadata);
|
|
505
561
|
return [{ ...state, lifecycle: Lifecycle.textDelta(lifecycle, events, id, event.delta) }, events];
|
|
506
562
|
};
|
|
@@ -684,7 +740,7 @@ const onOutputItemDone = Effect.fn("OpenResponses.onOutputItemDone")(function* (
|
|
|
684
740
|
return [
|
|
685
741
|
{
|
|
686
742
|
...state,
|
|
687
|
-
lifecycle: Lifecycle.textEnd(state.lifecycle, events, item.id, phase === undefined ?
|
|
743
|
+
lifecycle: Lifecycle.textEnd(state.lifecycle, events, item.id, providerMetadata(state, { itemId: item.id, ...(phase === undefined ? {} : { phase }) })),
|
|
688
744
|
messageItems,
|
|
689
745
|
messagePhases,
|
|
690
746
|
},
|
|
@@ -696,7 +752,11 @@ const onOutputItemDone = Effect.fn("OpenResponses.onOutputItemDone")(function* (
|
|
|
696
752
|
return [state, NO_EVENTS];
|
|
697
753
|
const tools = state.tools[item.id]
|
|
698
754
|
? state.tools
|
|
699
|
-
: ToolStream.start(state.tools, item.id, {
|
|
755
|
+
: ToolStream.start(state.tools, item.id, {
|
|
756
|
+
id: item.call_id,
|
|
757
|
+
name: item.name,
|
|
758
|
+
providerMetadata: providerMetadata(state, { itemId: item.id }),
|
|
759
|
+
});
|
|
700
760
|
const result = item.arguments === undefined
|
|
701
761
|
? yield* ToolStream.finish(state.id, tools, item.id)
|
|
702
762
|
: yield* ToolStream.finishWithInput(state.id, tools, item.id, item.arguments);
|
|
@@ -739,11 +799,17 @@ const onOutputItemDone = Effect.fn("OpenResponses.onOutputItemDone")(function* (
|
|
|
739
799
|
}
|
|
740
800
|
return [state, NO_EVENTS];
|
|
741
801
|
});
|
|
742
|
-
const onResponseFinish = (state, event)
|
|
743
|
-
|
|
802
|
+
const onResponseFinish = Effect.fn("OpenResponses.onResponseFinish")(function* (state, event) {
|
|
803
|
+
// Some compatible providers omit output_item.done even after completing the response.
|
|
804
|
+
const pending = event.type === "response.completed"
|
|
805
|
+
? yield* ToolStream.finishAll(state.id, state.tools)
|
|
806
|
+
: { tools: state.tools, events: NO_EVENTS };
|
|
807
|
+
const events = [...pending.events];
|
|
808
|
+
const hasFunctionCall = pending.events.some((event) => LLMEvent.is.toolCall(event) || LLMEvent.is.toolInputError(event)) ||
|
|
809
|
+
state.hasFunctionCall;
|
|
744
810
|
const lifecycle = Lifecycle.finish(state.lifecycle, events, {
|
|
745
811
|
reason: {
|
|
746
|
-
normalized: mapFinishReason(event,
|
|
812
|
+
normalized: mapFinishReason(event, hasFunctionCall),
|
|
747
813
|
raw: event.response?.incomplete_details?.reason,
|
|
748
814
|
},
|
|
749
815
|
usage: mapUsage(event.response?.usage, state.providerMetadataKey),
|
|
@@ -754,8 +820,8 @@ const onResponseFinish = (state, event) => {
|
|
|
754
820
|
})
|
|
755
821
|
: undefined,
|
|
756
822
|
});
|
|
757
|
-
return [{ ...state, lifecycle }, events];
|
|
758
|
-
};
|
|
823
|
+
return [{ ...state, lifecycle, hasFunctionCall, tools: pending.tools }, events];
|
|
824
|
+
});
|
|
759
825
|
// Build a single human-readable message from whatever the provider supplied.
|
|
760
826
|
// When both code and message are present, prefix the code so consumers see
|
|
761
827
|
// the failure mode (e.g. `rate_limit_exceeded: Slow down`) instead of just
|
|
@@ -792,6 +858,13 @@ export const step = (state, event) => {
|
|
|
792
858
|
? onOutputTextDelta(state, event, event.item_id)
|
|
793
859
|
: onOutputTextDone(state, event, event.item_id));
|
|
794
860
|
}
|
|
861
|
+
if (event.type === "response.refusal.delta" || event.type === "response.refusal.done") {
|
|
862
|
+
if (!isRefusalEvent(event))
|
|
863
|
+
return ProviderShared.eventError(state.id, `${event.type} is malformed`);
|
|
864
|
+
return Effect.succeed(event.type === "response.refusal.delta"
|
|
865
|
+
? onOutputTextDelta(state, event, event.item_id)
|
|
866
|
+
: onOutputTextDone(state, { ...event, text: event.refusal }, event.item_id));
|
|
867
|
+
}
|
|
795
868
|
if (event.type === "response.reasoning.delta" || event.type === "response.reasoning_summary_text.delta") {
|
|
796
869
|
if (!event.item_id)
|
|
797
870
|
return ProviderShared.eventError(state.id, `${event.type} is missing item_id`);
|
|
@@ -823,7 +896,7 @@ export const step = (state, event) => {
|
|
|
823
896
|
return onOutputItemDone(state, event);
|
|
824
897
|
}
|
|
825
898
|
if (event.type === "response.completed" || event.type === "response.incomplete")
|
|
826
|
-
return
|
|
899
|
+
return onResponseFinish(state, event);
|
|
827
900
|
if (event.type === "response.failed")
|
|
828
901
|
return providerError(state, event, `${state.name} response failed`);
|
|
829
902
|
if (event.type === "error")
|
|
@@ -95,7 +95,7 @@ export declare const bodyFields: {
|
|
|
95
95
|
}>>;
|
|
96
96
|
store: Schema.optional<Schema.Boolean>;
|
|
97
97
|
prompt_cache_key: Schema.optional<Schema.String>;
|
|
98
|
-
reasoning_effort: Schema.optional<Schema.
|
|
98
|
+
reasoning_effort: Schema.optional<Schema.declare<import("./utils/open-responses-options.js").ReasoningEffort, import("./utils/open-responses-options.js").ReasoningEffort>>;
|
|
99
99
|
max_completion_tokens: Schema.optional<Schema.Number>;
|
|
100
100
|
max_tokens: Schema.optional<Schema.Number>;
|
|
101
101
|
temperature: Schema.optional<Schema.Number>;
|
|
@@ -189,7 +189,7 @@ declare const OpenAIChatBody: Schema.Struct<{
|
|
|
189
189
|
}>>;
|
|
190
190
|
store: Schema.optional<Schema.Boolean>;
|
|
191
191
|
prompt_cache_key: Schema.optional<Schema.String>;
|
|
192
|
-
reasoning_effort: Schema.optional<Schema.
|
|
192
|
+
reasoning_effort: Schema.optional<Schema.declare<import("./utils/open-responses-options.js").ReasoningEffort, import("./utils/open-responses-options.js").ReasoningEffort>>;
|
|
193
193
|
max_completion_tokens: Schema.optional<Schema.Number>;
|
|
194
194
|
max_tokens: Schema.optional<Schema.Number>;
|
|
195
195
|
temperature: Schema.optional<Schema.Number>;
|
|
@@ -204,6 +204,7 @@ export declare const OpenAIChatEvent: Schema.Struct<{
|
|
|
204
204
|
readonly choices: Schema.optional<Schema.NullOr<Schema.$Array<Schema.Struct<{
|
|
205
205
|
readonly delta: Schema.optional<Schema.NullOr<Schema.StructWithRest<Schema.Struct<{
|
|
206
206
|
readonly content: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
207
|
+
readonly refusal: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
207
208
|
readonly reasoning_content: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
208
209
|
readonly reasoning: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
209
210
|
readonly reasoning_text: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
@@ -263,7 +264,7 @@ interface LoweringOptions {
|
|
|
263
264
|
readonly cacheControl?: (cache: CacheHint | undefined) => Schema.Schema.Type<typeof OpenAIChatCacheControl> | undefined;
|
|
264
265
|
}
|
|
265
266
|
export declare const fromRequest: (request: LLMRequest, options?: LoweringOptions | undefined) => Effect.Effect<{
|
|
266
|
-
reasoning_effort?:
|
|
267
|
+
reasoning_effort?: import("./utils/open-responses-options.js").ReasoningEffort | undefined;
|
|
267
268
|
prompt_cache_key?: string | undefined;
|
|
268
269
|
store?: boolean | undefined;
|
|
269
270
|
temperature: number | undefined;
|
|
@@ -347,7 +348,7 @@ export declare const fromRequest: (request: LLMRequest, options?: LoweringOption
|
|
|
347
348
|
readonly ttl?: string | undefined;
|
|
348
349
|
} | undefined;
|
|
349
350
|
}[] | undefined;
|
|
350
|
-
tool_choice: "required" | "
|
|
351
|
+
tool_choice: "required" | "auto" | "none" | {
|
|
351
352
|
type: "function";
|
|
352
353
|
function: {
|
|
353
354
|
name: string;
|
|
@@ -358,7 +359,7 @@ export declare const fromRequest: (request: LLMRequest, options?: LoweringOption
|
|
|
358
359
|
include_usage: boolean;
|
|
359
360
|
};
|
|
360
361
|
} | {
|
|
361
|
-
reasoning_effort?:
|
|
362
|
+
reasoning_effort?: import("./utils/open-responses-options.js").ReasoningEffort | undefined;
|
|
362
363
|
prompt_cache_key?: string | undefined;
|
|
363
364
|
store?: boolean | undefined;
|
|
364
365
|
temperature: number | undefined;
|
|
@@ -442,7 +443,7 @@ export declare const fromRequest: (request: LLMRequest, options?: LoweringOption
|
|
|
442
443
|
readonly ttl?: string | undefined;
|
|
443
444
|
} | undefined;
|
|
444
445
|
}[] | undefined;
|
|
445
|
-
tool_choice: "required" | "
|
|
446
|
+
tool_choice: "required" | "auto" | "none" | {
|
|
446
447
|
type: "function";
|
|
447
448
|
function: {
|
|
448
449
|
name: string;
|
|
@@ -521,7 +522,6 @@ export declare const protocol: Protocol<{
|
|
|
521
522
|
} | undefined;
|
|
522
523
|
})[];
|
|
523
524
|
readonly stream: true;
|
|
524
|
-
readonly stop?: readonly string[] | undefined;
|
|
525
525
|
readonly max_completion_tokens?: number | undefined;
|
|
526
526
|
readonly max_tokens?: number | undefined;
|
|
527
527
|
readonly tools?: readonly {
|
|
@@ -538,9 +538,10 @@ export declare const protocol: Protocol<{
|
|
|
538
538
|
readonly ttl?: string | undefined;
|
|
539
539
|
} | undefined;
|
|
540
540
|
}[] | undefined;
|
|
541
|
+
readonly stop?: readonly string[] | undefined;
|
|
541
542
|
readonly temperature?: number | undefined;
|
|
542
543
|
readonly seed?: number | undefined;
|
|
543
|
-
readonly tool_choice?: "required" | "
|
|
544
|
+
readonly tool_choice?: "required" | "auto" | "none" | {
|
|
544
545
|
readonly type: "function";
|
|
545
546
|
readonly function: {
|
|
546
547
|
readonly name: string;
|
|
@@ -552,7 +553,7 @@ export declare const protocol: Protocol<{
|
|
|
552
553
|
readonly include_usage: boolean;
|
|
553
554
|
} | undefined;
|
|
554
555
|
readonly prompt_cache_key?: string | undefined;
|
|
555
|
-
readonly reasoning_effort?:
|
|
556
|
+
readonly reasoning_effort?: import("./utils/open-responses-options.js").ReasoningEffort | undefined;
|
|
556
557
|
readonly frequency_penalty?: number | undefined;
|
|
557
558
|
readonly presence_penalty?: number | undefined;
|
|
558
559
|
}, string, {
|
|
@@ -584,6 +585,7 @@ export declare const protocol: Protocol<{
|
|
|
584
585
|
readonly reasoning_content?: string | null | undefined;
|
|
585
586
|
readonly reasoning_text?: string | null | undefined;
|
|
586
587
|
readonly content?: string | null | undefined;
|
|
588
|
+
readonly refusal?: string | null | undefined;
|
|
587
589
|
readonly tool_calls?: readonly {
|
|
588
590
|
readonly function?: {
|
|
589
591
|
readonly name?: string | null | undefined;
|
|
@@ -660,7 +662,6 @@ export declare const httpTransport: HttpTransport.HttpJsonTransport<{
|
|
|
660
662
|
} | undefined;
|
|
661
663
|
})[];
|
|
662
664
|
readonly stream: true;
|
|
663
|
-
readonly stop?: readonly string[] | undefined;
|
|
664
665
|
readonly max_completion_tokens?: number | undefined;
|
|
665
666
|
readonly max_tokens?: number | undefined;
|
|
666
667
|
readonly tools?: readonly {
|
|
@@ -677,9 +678,10 @@ export declare const httpTransport: HttpTransport.HttpJsonTransport<{
|
|
|
677
678
|
readonly ttl?: string | undefined;
|
|
678
679
|
} | undefined;
|
|
679
680
|
}[] | undefined;
|
|
681
|
+
readonly stop?: readonly string[] | undefined;
|
|
680
682
|
readonly temperature?: number | undefined;
|
|
681
683
|
readonly seed?: number | undefined;
|
|
682
|
-
readonly tool_choice?: "required" | "
|
|
684
|
+
readonly tool_choice?: "required" | "auto" | "none" | {
|
|
683
685
|
readonly type: "function";
|
|
684
686
|
readonly function: {
|
|
685
687
|
readonly name: string;
|
|
@@ -691,7 +693,7 @@ export declare const httpTransport: HttpTransport.HttpJsonTransport<{
|
|
|
691
693
|
readonly include_usage: boolean;
|
|
692
694
|
} | undefined;
|
|
693
695
|
readonly prompt_cache_key?: string | undefined;
|
|
694
|
-
readonly reasoning_effort?:
|
|
696
|
+
readonly reasoning_effort?: import("./utils/open-responses-options.js").ReasoningEffort | undefined;
|
|
695
697
|
readonly frequency_penalty?: number | undefined;
|
|
696
698
|
readonly presence_penalty?: number | undefined;
|
|
697
699
|
}, string>;
|
|
@@ -757,7 +759,6 @@ export declare const route: Route<{
|
|
|
757
759
|
} | undefined;
|
|
758
760
|
})[];
|
|
759
761
|
readonly stream: true;
|
|
760
|
-
readonly stop?: readonly string[] | undefined;
|
|
761
762
|
readonly max_completion_tokens?: number | undefined;
|
|
762
763
|
readonly max_tokens?: number | undefined;
|
|
763
764
|
readonly tools?: readonly {
|
|
@@ -774,9 +775,10 @@ export declare const route: Route<{
|
|
|
774
775
|
readonly ttl?: string | undefined;
|
|
775
776
|
} | undefined;
|
|
776
777
|
}[] | undefined;
|
|
778
|
+
readonly stop?: readonly string[] | undefined;
|
|
777
779
|
readonly temperature?: number | undefined;
|
|
778
780
|
readonly seed?: number | undefined;
|
|
779
|
-
readonly tool_choice?: "required" | "
|
|
781
|
+
readonly tool_choice?: "required" | "auto" | "none" | {
|
|
780
782
|
readonly type: "function";
|
|
781
783
|
readonly function: {
|
|
782
784
|
readonly name: string;
|
|
@@ -788,7 +790,7 @@ export declare const route: Route<{
|
|
|
788
790
|
readonly include_usage: boolean;
|
|
789
791
|
} | undefined;
|
|
790
792
|
readonly prompt_cache_key?: string | undefined;
|
|
791
|
-
readonly reasoning_effort?:
|
|
793
|
+
readonly reasoning_effort?: import("./utils/open-responses-options.js").ReasoningEffort | undefined;
|
|
792
794
|
readonly frequency_penalty?: number | undefined;
|
|
793
795
|
readonly presence_penalty?: number | undefined;
|
|
794
796
|
}, HttpTransport.HttpPrepared<string>>;
|
|
@@ -13,7 +13,7 @@ import { Lifecycle } from "./utils/lifecycle.js";
|
|
|
13
13
|
import { ToolSchemaProjection } from "./utils/tool-schema.js";
|
|
14
14
|
import { ToolStream } from "./utils/tool-stream.js";
|
|
15
15
|
const ADAPTER = "openai-chat";
|
|
16
|
-
const RESERVED_REASONING_FIELDS = new Set(["role", "content", "tool_calls"]);
|
|
16
|
+
const RESERVED_REASONING_FIELDS = new Set(["role", "content", "refusal", "tool_calls"]);
|
|
17
17
|
export const DEFAULT_BASE_URL = "https://api.openai.com/v1";
|
|
18
18
|
export const PATH = "/chat/completions";
|
|
19
19
|
// =============================================================================
|
|
@@ -144,6 +144,7 @@ const OpenAIChatToolCallDelta = Schema.Struct({
|
|
|
144
144
|
});
|
|
145
145
|
const OpenAIChatDelta = Schema.StructWithRest(Schema.Struct({
|
|
146
146
|
content: optionalNull(Schema.String),
|
|
147
|
+
refusal: optionalNull(Schema.String),
|
|
147
148
|
reasoning_content: optionalNull(Schema.String),
|
|
148
149
|
reasoning: optionalNull(Schema.String),
|
|
149
150
|
reasoning_text: optionalNull(Schema.String),
|
|
@@ -568,6 +569,7 @@ const step = (state, event) => Effect.gen(function* () {
|
|
|
568
569
|
let lifecycle = state.lifecycle;
|
|
569
570
|
const reasoning = reasoningDelta(delta, state.reasoningField);
|
|
570
571
|
const hasLateContent = Boolean(delta?.content) ||
|
|
572
|
+
Boolean(delta?.refusal) ||
|
|
571
573
|
reasoning !== undefined ||
|
|
572
574
|
(Array.isArray(delta?.reasoning_details) && delta.reasoning_details.length > 0) ||
|
|
573
575
|
toolDeltas.some((tool) => Boolean(tool.id) || Boolean(tool.function?.name) || Boolean(tool.function?.arguments));
|
|
@@ -587,13 +589,17 @@ const step = (state, event) => Effect.gen(function* () {
|
|
|
587
589
|
lifecycle = Lifecycle.reasoningDelta(lifecycle, events, "reasoning-0", text, deltaMetadata);
|
|
588
590
|
else if (reasoningDetailsObserved &&
|
|
589
591
|
!lifecycle.reasoning.has("reasoning-0") &&
|
|
590
|
-
(Boolean(delta?.content) || toolDeltas.length > 0))
|
|
592
|
+
(Boolean(delta?.content) || Boolean(delta?.refusal) || toolDeltas.length > 0))
|
|
591
593
|
lifecycle = Lifecycle.reasoningStart(lifecycle, events, "reasoning-0", deltaMetadata);
|
|
592
594
|
const reasoningEmitted = state.reasoningEmitted || lifecycle.reasoning.has("reasoning-0");
|
|
593
595
|
if (delta?.content) {
|
|
594
596
|
lifecycle = Lifecycle.reasoningEnd(lifecycle, events, "reasoning-0", reasoningMetadata(reasoningField, reasoningDetailsObserved ? state.reasoningDetails : undefined));
|
|
595
597
|
lifecycle = Lifecycle.textDelta(lifecycle, events, "text-0", delta.content);
|
|
596
598
|
}
|
|
599
|
+
if (delta?.refusal) {
|
|
600
|
+
lifecycle = Lifecycle.reasoningEnd(lifecycle, events, "reasoning-0", reasoningMetadata(reasoningField, reasoningDetailsObserved ? state.reasoningDetails : undefined));
|
|
601
|
+
lifecycle = Lifecycle.textDelta(lifecycle, events, "text-0", delta.refusal);
|
|
602
|
+
}
|
|
597
603
|
// Compatible providers may omit indexes. Prefer durable identity, then use
|
|
598
604
|
// batch position for parallel deltas or the latest call for sparse chunks.
|
|
599
605
|
for (const [position, tool] of toolDeltas.entries()) {
|
|
@@ -69,7 +69,6 @@ export declare const route: Route<{
|
|
|
69
69
|
} | undefined;
|
|
70
70
|
})[];
|
|
71
71
|
readonly stream: true;
|
|
72
|
-
readonly stop?: readonly string[] | undefined;
|
|
73
72
|
readonly max_completion_tokens?: number | undefined;
|
|
74
73
|
readonly max_tokens?: number | undefined;
|
|
75
74
|
readonly tools?: readonly {
|
|
@@ -86,9 +85,10 @@ export declare const route: Route<{
|
|
|
86
85
|
readonly ttl?: string | undefined;
|
|
87
86
|
} | undefined;
|
|
88
87
|
}[] | undefined;
|
|
88
|
+
readonly stop?: readonly string[] | undefined;
|
|
89
89
|
readonly temperature?: number | undefined;
|
|
90
90
|
readonly seed?: number | undefined;
|
|
91
|
-
readonly tool_choice?: "required" | "
|
|
91
|
+
readonly tool_choice?: "required" | "auto" | "none" | {
|
|
92
92
|
readonly type: "function";
|
|
93
93
|
readonly function: {
|
|
94
94
|
readonly name: string;
|
|
@@ -100,7 +100,7 @@ export declare const route: Route<{
|
|
|
100
100
|
readonly include_usage: boolean;
|
|
101
101
|
} | undefined;
|
|
102
102
|
readonly prompt_cache_key?: string | undefined;
|
|
103
|
-
readonly reasoning_effort?:
|
|
103
|
+
readonly reasoning_effort?: import("./utils/open-responses-options.js").ReasoningEffort | undefined;
|
|
104
104
|
readonly frequency_penalty?: number | undefined;
|
|
105
105
|
readonly presence_penalty?: number | undefined;
|
|
106
106
|
}, import("../route/transport/http.js").HttpPrepared<string>>;
|
|
@@ -20,6 +20,9 @@ export declare const route: Route<{
|
|
|
20
20
|
} | {
|
|
21
21
|
readonly role: "system";
|
|
22
22
|
readonly content: string;
|
|
23
|
+
} | {
|
|
24
|
+
readonly role: "developer";
|
|
25
|
+
readonly content: string;
|
|
23
26
|
} | {
|
|
24
27
|
readonly role: "user";
|
|
25
28
|
readonly content: readonly ({
|
|
@@ -35,17 +38,20 @@ export declare const route: Route<{
|
|
|
35
38
|
readonly text: string;
|
|
36
39
|
})[];
|
|
37
40
|
} | {
|
|
41
|
+
readonly type: "message";
|
|
38
42
|
readonly content: readonly {
|
|
39
43
|
readonly type: "output_text";
|
|
40
44
|
readonly text: string;
|
|
41
45
|
}[];
|
|
42
46
|
readonly role: "assistant";
|
|
47
|
+
readonly id?: string | undefined;
|
|
43
48
|
readonly phase?: "commentary" | "final_answer" | undefined;
|
|
44
49
|
} | {
|
|
45
50
|
readonly type: "function_call";
|
|
46
|
-
readonly call_id: string;
|
|
47
51
|
readonly name: string;
|
|
48
52
|
readonly arguments: string;
|
|
53
|
+
readonly call_id: string;
|
|
54
|
+
readonly id?: string | undefined;
|
|
49
55
|
} | {
|
|
50
56
|
readonly type: "function_call_output";
|
|
51
57
|
readonly call_id: string;
|
|
@@ -64,10 +70,13 @@ export declare const route: Route<{
|
|
|
64
70
|
})[];
|
|
65
71
|
readonly model: string;
|
|
66
72
|
readonly stream: true;
|
|
73
|
+
readonly metadata?: {
|
|
74
|
+
readonly [x: string]: string;
|
|
75
|
+
} | undefined;
|
|
67
76
|
readonly instructions?: string | undefined;
|
|
68
77
|
readonly reasoning?: {
|
|
69
78
|
readonly summary?: "auto" | "concise" | "detailed" | undefined;
|
|
70
|
-
readonly effort?:
|
|
79
|
+
readonly effort?: import("./utils/open-responses-options.js").ReasoningEffort | undefined;
|
|
71
80
|
} | undefined;
|
|
72
81
|
readonly tools?: readonly {
|
|
73
82
|
readonly type: "function";
|
|
@@ -79,18 +88,35 @@ export declare const route: Route<{
|
|
|
79
88
|
readonly strict?: boolean | undefined;
|
|
80
89
|
}[] | undefined;
|
|
81
90
|
readonly text?: {
|
|
82
|
-
readonly verbosity?: "
|
|
91
|
+
readonly verbosity?: import("./utils/open-responses-options.js").TextVerbosity | undefined;
|
|
83
92
|
} | undefined;
|
|
84
93
|
readonly temperature?: number | undefined;
|
|
85
|
-
readonly tool_choice?: "required" | "
|
|
94
|
+
readonly tool_choice?: "required" | "auto" | "none" | {
|
|
86
95
|
readonly type: "function";
|
|
87
96
|
readonly name: string;
|
|
97
|
+
} | {
|
|
98
|
+
readonly type: "allowed_tools";
|
|
99
|
+
readonly mode: "required" | "auto" | "none";
|
|
100
|
+
readonly tools: readonly {
|
|
101
|
+
readonly type: "function";
|
|
102
|
+
readonly name: string;
|
|
103
|
+
}[];
|
|
88
104
|
} | undefined;
|
|
89
105
|
readonly top_p?: number | undefined;
|
|
90
|
-
readonly include?: readonly ("file_search_call.results" | "web_search_call.results" | "web_search_call.action.sources" | "message.input_image.image_url" | "computer_call_output.output.image_url" | "code_interpreter_call.outputs" | "reasoning.encrypted_content" | "message.output_text.logprobs")[] | undefined;
|
|
91
106
|
readonly store?: boolean | undefined;
|
|
107
|
+
readonly include?: readonly import("./utils/open-responses-options.js").ResponseIncludable[] | undefined;
|
|
108
|
+
readonly truncation?: "auto" | "disabled" | undefined;
|
|
109
|
+
readonly stream_options?: {
|
|
110
|
+
readonly include_obfuscation?: boolean | undefined;
|
|
111
|
+
} | undefined;
|
|
92
112
|
readonly prompt_cache_key?: string | undefined;
|
|
113
|
+
readonly frequency_penalty?: number | undefined;
|
|
114
|
+
readonly presence_penalty?: number | undefined;
|
|
115
|
+
readonly safety_identifier?: string | undefined;
|
|
116
|
+
readonly top_logprobs?: number | undefined;
|
|
93
117
|
readonly service_tier?: "default" | "auto" | "flex" | "priority" | undefined;
|
|
94
118
|
readonly max_output_tokens?: number | undefined;
|
|
119
|
+
readonly max_tool_calls?: number | undefined;
|
|
120
|
+
readonly parallel_tool_calls?: boolean | undefined;
|
|
95
121
|
}, import("../route/transport/http.js").HttpPrepared<string>>;
|
|
96
122
|
export * as OpenAICompatibleResponses from "./openai-compatible-responses.js";
|