@opencode-ai/ai 0.0.0-beta-17639 → 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 +5 -5
- package/dist/protocols/gemini.d.ts +5 -9
- package/dist/protocols/gemini.js +5 -4
- package/dist/protocols/open-responses.d.ts +176 -38
- package/dist/protocols/open-responses.js +108 -33
- 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 +27 -5
- package/dist/protocols/openai-responses.d.ts +151 -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 +46 -15
- package/dist/protocols/utils/open-responses-options.js +38 -25
- 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 +43 -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 +40 -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 +29 -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 -14
- package/dist/providers/openai-compatible-responses.d.ts +29 -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 +44 -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 +46 -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/package.json +5 -5
|
@@ -66,6 +66,8 @@ export const InputItem = Schema.Union([
|
|
|
66
66
|
Schema.Struct({ role: Schema.tag("developer"), content: Schema.String }),
|
|
67
67
|
Schema.Struct({ role: Schema.tag("user"), content: Schema.Array(OpenResponsesInputContent) }),
|
|
68
68
|
Schema.Struct({
|
|
69
|
+
type: Schema.tag("message"),
|
|
70
|
+
id: Schema.optionalKey(Schema.String),
|
|
69
71
|
role: Schema.tag("assistant"),
|
|
70
72
|
content: Schema.Array(OpenResponsesOutputText),
|
|
71
73
|
phase: Schema.optionalKey(MessagePhase),
|
|
@@ -74,6 +76,7 @@ export const InputItem = Schema.Union([
|
|
|
74
76
|
OpenResponsesItemReference,
|
|
75
77
|
Schema.Struct({
|
|
76
78
|
type: Schema.tag("function_call"),
|
|
79
|
+
id: Schema.optionalKey(Schema.String),
|
|
77
80
|
call_id: Schema.String,
|
|
78
81
|
name: Schema.String,
|
|
79
82
|
arguments: Schema.String,
|
|
@@ -94,6 +97,11 @@ export const Tool = Schema.Struct({
|
|
|
94
97
|
export const ToolChoice = Schema.Union([
|
|
95
98
|
Schema.Literals(["auto", "none", "required"]),
|
|
96
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
|
+
}),
|
|
97
105
|
]);
|
|
98
106
|
// Fields shared between the HTTP body and the WebSocket `response.create`
|
|
99
107
|
// message. The HTTP body adds `stream: true`; the WebSocket message adds
|
|
@@ -106,6 +114,12 @@ export const coreFields = {
|
|
|
106
114
|
tools: optionalArray(Tool),
|
|
107
115
|
tool_choice: Schema.optional(ToolChoice),
|
|
108
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 }))),
|
|
109
123
|
truncation: Schema.optional(OpenResponsesOptions.TruncationSchema),
|
|
110
124
|
service_tier: Schema.optional(OpenResponsesOptions.ServiceTierSchema),
|
|
111
125
|
prompt_cache_key: Schema.optional(Schema.String),
|
|
@@ -118,8 +132,12 @@ export const coreFields = {
|
|
|
118
132
|
verbosity: Schema.optional(OpenResponsesOptions.TextVerbositySchema),
|
|
119
133
|
})),
|
|
120
134
|
max_output_tokens: Schema.optional(Schema.Number),
|
|
135
|
+
max_tool_calls: Schema.optional(Schema.Int),
|
|
136
|
+
parallel_tool_calls: Schema.optional(Schema.Boolean),
|
|
121
137
|
temperature: Schema.optional(Schema.Number),
|
|
122
138
|
top_p: Schema.optional(Schema.Number),
|
|
139
|
+
presence_penalty: Schema.optional(Schema.Number),
|
|
140
|
+
frequency_penalty: Schema.optional(Schema.Number),
|
|
123
141
|
};
|
|
124
142
|
const OpenResponsesBody = Schema.Struct({
|
|
125
143
|
...coreFields,
|
|
@@ -195,6 +213,19 @@ export const Event = Schema.StructWithRest(Schema.Struct({
|
|
|
195
213
|
status_code: Schema.optional(Schema.Unknown),
|
|
196
214
|
headers: Schema.optional(Schema.Unknown),
|
|
197
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);
|
|
198
229
|
const BASE = { id: ADAPTER, name: NAME };
|
|
199
230
|
// =============================================================================
|
|
200
231
|
// Request Lowering
|
|
@@ -207,7 +238,7 @@ export const lowerTool = Effect.fn("OpenResponses.lowerTool")(function* (protoco
|
|
|
207
238
|
name: tool.name,
|
|
208
239
|
description: tool.description,
|
|
209
240
|
parameters: ToolSchemaProjection.responses(inputSchema),
|
|
210
|
-
//
|
|
241
|
+
// The common tool definition does not currently express Responses strict-schema policy.
|
|
211
242
|
strict: false,
|
|
212
243
|
};
|
|
213
244
|
});
|
|
@@ -217,31 +248,39 @@ export const lowerToolChoice = (protocolName, toolChoice) => ProviderShared.matc
|
|
|
217
248
|
required: () => "required",
|
|
218
249
|
tool: (toolName) => ({ type: "function", name: toolName }),
|
|
219
250
|
});
|
|
220
|
-
const
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
}
|
|
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
|
+
};
|
|
226
267
|
const lowerReasoning = (part, providerMetadataKey) => {
|
|
227
268
|
const metadata = part.providerMetadata?.[providerMetadataKey];
|
|
228
|
-
|
|
269
|
+
const id = itemID(part.providerMetadata, providerMetadataKey);
|
|
270
|
+
if (!ProviderShared.isRecord(metadata) || !id)
|
|
229
271
|
return undefined;
|
|
230
272
|
const encryptedContent = typeof metadata.reasoningEncryptedContent === "string" || metadata.reasoningEncryptedContent === null
|
|
231
273
|
? metadata.reasoningEncryptedContent
|
|
232
274
|
: undefined;
|
|
233
275
|
return {
|
|
234
276
|
type: "reasoning",
|
|
235
|
-
id
|
|
277
|
+
id,
|
|
236
278
|
summary: part.text.length > 0 ? [{ type: "summary_text", text: part.text }] : [],
|
|
237
279
|
encrypted_content: encryptedContent,
|
|
238
280
|
};
|
|
239
281
|
};
|
|
240
282
|
const hostedToolItemID = (part, providerMetadataKey) => {
|
|
241
|
-
|
|
242
|
-
return ProviderShared.isRecord(metadata) && typeof metadata.itemId === "string" && metadata.itemId.length > 0
|
|
243
|
-
? metadata.itemId
|
|
244
|
-
: undefined;
|
|
283
|
+
return itemID(part.providerMetadata, providerMetadataKey);
|
|
245
284
|
};
|
|
246
285
|
const lowerMedia = Effect.fn("OpenResponses.lowerMedia")(function* (part, request, extension) {
|
|
247
286
|
const media = ProviderShared.normalizeMedia(part);
|
|
@@ -310,15 +349,18 @@ const lowerMessages = Effect.fn("OpenResponses.lowerMessages")(function* (reques
|
|
|
310
349
|
return;
|
|
311
350
|
const groups = content.reduce((groups, part) => {
|
|
312
351
|
const metadata = part.providerMetadata?.[providerMetadataKey];
|
|
352
|
+
const id = itemID(part.providerMetadata, providerMetadataKey);
|
|
313
353
|
const phase = ProviderShared.isRecord(metadata) ? messagePhase(metadata.phase, extension) : undefined;
|
|
314
354
|
const group = groups.at(-1);
|
|
315
|
-
if (group && group.phase === phase)
|
|
355
|
+
if (group && group.id === id && group.phase === phase)
|
|
316
356
|
group.parts.push(part);
|
|
317
357
|
else
|
|
318
|
-
groups.push({ phase, parts: [part] });
|
|
358
|
+
groups.push({ id, phase, parts: [part] });
|
|
319
359
|
return groups;
|
|
320
360
|
}, []);
|
|
321
361
|
input.push(...groups.map((group) => ({
|
|
362
|
+
type: "message",
|
|
363
|
+
...(group.id === undefined ? {} : { id: group.id }),
|
|
322
364
|
role: "assistant",
|
|
323
365
|
content: group.parts.map((part) => ({ type: "output_text", text: part.text })),
|
|
324
366
|
...(group.phase === undefined ? {} : { phase: group.phase }),
|
|
@@ -348,20 +390,15 @@ const lowerMessages = Effect.fn("OpenResponses.lowerMessages")(function* (reques
|
|
|
348
390
|
existing.encrypted_content = reasoning.encrypted_content;
|
|
349
391
|
continue;
|
|
350
392
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
summary: reasoning.summary,
|
|
354
|
-
encrypted_content: reasoning.encrypted_content,
|
|
355
|
-
};
|
|
356
|
-
reasoningItems[reasoning.id] = replay;
|
|
357
|
-
input.push(replay);
|
|
393
|
+
reasoningItems[reasoning.id] = reasoning;
|
|
394
|
+
input.push(reasoning);
|
|
358
395
|
continue;
|
|
359
396
|
}
|
|
360
397
|
if (part.type === "tool-call") {
|
|
361
398
|
flushText();
|
|
362
399
|
if (part.providerExecuted === true)
|
|
363
400
|
continue;
|
|
364
|
-
input.push(lowerToolCall(part));
|
|
401
|
+
input.push(lowerToolCall(part, providerMetadataKey));
|
|
365
402
|
continue;
|
|
366
403
|
}
|
|
367
404
|
if (part.type === "tool-result" && part.providerExecuted === true) {
|
|
@@ -412,6 +449,12 @@ const lowerOptions = (request) => {
|
|
|
412
449
|
return {
|
|
413
450
|
...(options.instructions ? { instructions: options.instructions } : {}),
|
|
414
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 } : {}),
|
|
415
458
|
...(request.promptCacheKey ? { prompt_cache_key: request.promptCacheKey } : {}),
|
|
416
459
|
...(options.include ? { include: options.include } : {}),
|
|
417
460
|
...(options.reasoningEffort || options.reasoningSummary
|
|
@@ -419,9 +462,21 @@ const lowerOptions = (request) => {
|
|
|
419
462
|
: {}),
|
|
420
463
|
...(options.textVerbosity ? { text: { verbosity: options.textVerbosity } } : {}),
|
|
421
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 } : {}),
|
|
422
467
|
...(options.truncation ? { truncation: options.truncation } : {}),
|
|
423
468
|
};
|
|
424
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 })),
|
|
478
|
+
};
|
|
479
|
+
};
|
|
425
480
|
export const fromRequestWithExtension = Effect.fn("OpenResponses.fromRequestWithExtension")(function* (request, extension) {
|
|
426
481
|
const generation = request.generation;
|
|
427
482
|
const toolSchemaCompatibility = request.model.compatibility?.toolSchema;
|
|
@@ -431,11 +486,14 @@ export const fromRequestWithExtension = Effect.fn("OpenResponses.fromRequestWith
|
|
|
431
486
|
tools: request.tools.length === 0
|
|
432
487
|
? undefined
|
|
433
488
|
: yield* Effect.forEach(request.tools, (tool) => lowerTool(extension.name, tool, ToolSchemaProjection.modelCompatibility(tool.inputSchema, toolSchemaCompatibility))),
|
|
434
|
-
tool_choice:
|
|
489
|
+
tool_choice: allowedToolChoice(request) ??
|
|
490
|
+
(request.toolChoice ? yield* lowerToolChoice(extension.name, request.toolChoice) : undefined),
|
|
435
491
|
stream: true,
|
|
436
492
|
max_output_tokens: generation?.maxTokens,
|
|
437
493
|
temperature: generation?.temperature,
|
|
438
494
|
top_p: generation?.topP,
|
|
495
|
+
presence_penalty: generation?.presencePenalty,
|
|
496
|
+
frequency_penalty: generation?.frequencyPenalty,
|
|
439
497
|
...lowerOptions(request),
|
|
440
498
|
};
|
|
441
499
|
});
|
|
@@ -498,7 +556,7 @@ const onOutputTextDelta = (state, event, id) => {
|
|
|
498
556
|
return [state, NO_EVENTS];
|
|
499
557
|
const events = [];
|
|
500
558
|
const phase = state.messagePhases[id];
|
|
501
|
-
const metadata = phase === undefined ?
|
|
559
|
+
const metadata = providerMetadata(state, { itemId: id, ...(phase === undefined ? {} : { phase }) });
|
|
502
560
|
const lifecycle = Lifecycle.textStart(state.lifecycle, events, id, metadata);
|
|
503
561
|
return [{ ...state, lifecycle: Lifecycle.textDelta(lifecycle, events, id, event.delta) }, events];
|
|
504
562
|
};
|
|
@@ -682,7 +740,7 @@ const onOutputItemDone = Effect.fn("OpenResponses.onOutputItemDone")(function* (
|
|
|
682
740
|
return [
|
|
683
741
|
{
|
|
684
742
|
...state,
|
|
685
|
-
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 }) })),
|
|
686
744
|
messageItems,
|
|
687
745
|
messagePhases,
|
|
688
746
|
},
|
|
@@ -694,7 +752,11 @@ const onOutputItemDone = Effect.fn("OpenResponses.onOutputItemDone")(function* (
|
|
|
694
752
|
return [state, NO_EVENTS];
|
|
695
753
|
const tools = state.tools[item.id]
|
|
696
754
|
? state.tools
|
|
697
|
-
: 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
|
+
});
|
|
698
760
|
const result = item.arguments === undefined
|
|
699
761
|
? yield* ToolStream.finish(state.id, tools, item.id)
|
|
700
762
|
: yield* ToolStream.finishWithInput(state.id, tools, item.id, item.arguments);
|
|
@@ -737,11 +799,17 @@ const onOutputItemDone = Effect.fn("OpenResponses.onOutputItemDone")(function* (
|
|
|
737
799
|
}
|
|
738
800
|
return [state, NO_EVENTS];
|
|
739
801
|
});
|
|
740
|
-
const onResponseFinish = (state, event)
|
|
741
|
-
|
|
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;
|
|
742
810
|
const lifecycle = Lifecycle.finish(state.lifecycle, events, {
|
|
743
811
|
reason: {
|
|
744
|
-
normalized: mapFinishReason(event,
|
|
812
|
+
normalized: mapFinishReason(event, hasFunctionCall),
|
|
745
813
|
raw: event.response?.incomplete_details?.reason,
|
|
746
814
|
},
|
|
747
815
|
usage: mapUsage(event.response?.usage, state.providerMetadataKey),
|
|
@@ -752,8 +820,8 @@ const onResponseFinish = (state, event) => {
|
|
|
752
820
|
})
|
|
753
821
|
: undefined,
|
|
754
822
|
});
|
|
755
|
-
return [{ ...state, lifecycle }, events];
|
|
756
|
-
};
|
|
823
|
+
return [{ ...state, lifecycle, hasFunctionCall, tools: pending.tools }, events];
|
|
824
|
+
});
|
|
757
825
|
// Build a single human-readable message from whatever the provider supplied.
|
|
758
826
|
// When both code and message are present, prefix the code so consumers see
|
|
759
827
|
// the failure mode (e.g. `rate_limit_exceeded: Slow down`) instead of just
|
|
@@ -790,6 +858,13 @@ export const step = (state, event) => {
|
|
|
790
858
|
? onOutputTextDelta(state, event, event.item_id)
|
|
791
859
|
: onOutputTextDone(state, event, event.item_id));
|
|
792
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
|
+
}
|
|
793
868
|
if (event.type === "response.reasoning.delta" || event.type === "response.reasoning_summary_text.delta") {
|
|
794
869
|
if (!event.item_id)
|
|
795
870
|
return ProviderShared.eventError(state.id, `${event.type} is missing item_id`);
|
|
@@ -821,7 +896,7 @@ export const step = (state, event) => {
|
|
|
821
896
|
return onOutputItemDone(state, event);
|
|
822
897
|
}
|
|
823
898
|
if (event.type === "response.completed" || event.type === "response.incomplete")
|
|
824
|
-
return
|
|
899
|
+
return onResponseFinish(state, event);
|
|
825
900
|
if (event.type === "response.failed")
|
|
826
901
|
return providerError(state, event, `${state.name} response failed`);
|
|
827
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>>;
|
|
@@ -38,17 +38,20 @@ export declare const route: Route<{
|
|
|
38
38
|
readonly text: string;
|
|
39
39
|
})[];
|
|
40
40
|
} | {
|
|
41
|
+
readonly type: "message";
|
|
41
42
|
readonly content: readonly {
|
|
42
43
|
readonly type: "output_text";
|
|
43
44
|
readonly text: string;
|
|
44
45
|
}[];
|
|
45
46
|
readonly role: "assistant";
|
|
47
|
+
readonly id?: string | undefined;
|
|
46
48
|
readonly phase?: "commentary" | "final_answer" | undefined;
|
|
47
49
|
} | {
|
|
48
50
|
readonly type: "function_call";
|
|
49
|
-
readonly call_id: string;
|
|
50
51
|
readonly name: string;
|
|
51
52
|
readonly arguments: string;
|
|
53
|
+
readonly call_id: string;
|
|
54
|
+
readonly id?: string | undefined;
|
|
52
55
|
} | {
|
|
53
56
|
readonly type: "function_call_output";
|
|
54
57
|
readonly call_id: string;
|
|
@@ -67,10 +70,13 @@ export declare const route: Route<{
|
|
|
67
70
|
})[];
|
|
68
71
|
readonly model: string;
|
|
69
72
|
readonly stream: true;
|
|
73
|
+
readonly metadata?: {
|
|
74
|
+
readonly [x: string]: string;
|
|
75
|
+
} | undefined;
|
|
70
76
|
readonly instructions?: string | undefined;
|
|
71
77
|
readonly reasoning?: {
|
|
72
78
|
readonly summary?: "auto" | "concise" | "detailed" | undefined;
|
|
73
|
-
readonly effort?:
|
|
79
|
+
readonly effort?: import("./utils/open-responses-options.js").ReasoningEffort | undefined;
|
|
74
80
|
} | undefined;
|
|
75
81
|
readonly tools?: readonly {
|
|
76
82
|
readonly type: "function";
|
|
@@ -82,19 +88,35 @@ export declare const route: Route<{
|
|
|
82
88
|
readonly strict?: boolean | undefined;
|
|
83
89
|
}[] | undefined;
|
|
84
90
|
readonly text?: {
|
|
85
|
-
readonly verbosity?: "
|
|
91
|
+
readonly verbosity?: import("./utils/open-responses-options.js").TextVerbosity | undefined;
|
|
86
92
|
} | undefined;
|
|
87
93
|
readonly temperature?: number | undefined;
|
|
88
|
-
readonly tool_choice?: "required" | "
|
|
94
|
+
readonly tool_choice?: "required" | "auto" | "none" | {
|
|
89
95
|
readonly type: "function";
|
|
90
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
|
+
}[];
|
|
91
104
|
} | undefined;
|
|
92
105
|
readonly top_p?: number | undefined;
|
|
93
|
-
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;
|
|
94
106
|
readonly store?: boolean | undefined;
|
|
107
|
+
readonly include?: readonly import("./utils/open-responses-options.js").ResponseIncludable[] | undefined;
|
|
95
108
|
readonly truncation?: "auto" | "disabled" | undefined;
|
|
109
|
+
readonly stream_options?: {
|
|
110
|
+
readonly include_obfuscation?: boolean | undefined;
|
|
111
|
+
} | undefined;
|
|
96
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;
|
|
97
117
|
readonly service_tier?: "default" | "auto" | "flex" | "priority" | undefined;
|
|
98
118
|
readonly max_output_tokens?: number | undefined;
|
|
119
|
+
readonly max_tool_calls?: number | undefined;
|
|
120
|
+
readonly parallel_tool_calls?: boolean | undefined;
|
|
99
121
|
}, import("../route/transport/http.js").HttpPrepared<string>>;
|
|
100
122
|
export * as OpenAICompatibleResponses from "./openai-compatible-responses.js";
|