@opencode-ai/ai 0.0.0-next-15845 → 0.0.0-next-15848
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/dist/protocols/openai-chat.d.ts +10 -0
- package/dist/protocols/openai-chat.js +106 -16
- package/dist/protocols/openai-compatible-chat.d.ts +1 -0
- package/dist/protocols/utils/lifecycle.js +1 -1
- package/dist/provider-error.js +10 -1
- package/dist/providers/azure.d.ts +1 -0
- package/dist/providers/cloudflare.d.ts +3 -0
- package/dist/providers/github-copilot.d.ts +1 -0
- package/dist/providers/google-vertex-chat.d.ts +1 -0
- package/dist/providers/openai-compatible.d.ts +1 -0
- package/dist/providers/openai.d.ts +1 -0
- package/dist/providers/openrouter.d.ts +5 -0
- package/dist/providers/openrouter.js +26 -4
- package/dist/providers/xai.d.ts +1 -0
- package/package.json +3 -3
|
@@ -37,6 +37,7 @@ export declare const bodyFields: {
|
|
|
37
37
|
readonly reasoning_content: Schema.optional<Schema.String>;
|
|
38
38
|
readonly reasoning: Schema.optional<Schema.String>;
|
|
39
39
|
readonly reasoning_text: Schema.optional<Schema.String>;
|
|
40
|
+
readonly reasoning_details: Schema.optional<Schema.$Array<Schema.Unknown>>;
|
|
40
41
|
}>, Schema.Struct<{
|
|
41
42
|
readonly role: Schema.Literal<"tool">;
|
|
42
43
|
readonly tool_call_id: Schema.String;
|
|
@@ -100,6 +101,7 @@ declare const OpenAIChatBody: Schema.Struct<{
|
|
|
100
101
|
readonly reasoning_content: Schema.optional<Schema.String>;
|
|
101
102
|
readonly reasoning: Schema.optional<Schema.String>;
|
|
102
103
|
readonly reasoning_text: Schema.optional<Schema.String>;
|
|
104
|
+
readonly reasoning_details: Schema.optional<Schema.$Array<Schema.Unknown>>;
|
|
103
105
|
}>, Schema.Struct<{
|
|
104
106
|
readonly role: Schema.Literal<"tool">;
|
|
105
107
|
readonly tool_call_id: Schema.String;
|
|
@@ -141,6 +143,7 @@ export declare const OpenAIChatEvent: Schema.Struct<{
|
|
|
141
143
|
readonly reasoning_content: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
142
144
|
readonly reasoning: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
143
145
|
readonly reasoning_text: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
146
|
+
readonly reasoning_details: Schema.optional<Schema.NullOr<Schema.$Array<Schema.Unknown>>>;
|
|
144
147
|
readonly tool_calls: Schema.optional<Schema.NullOr<Schema.$Array<Schema.Struct<{
|
|
145
148
|
readonly index: Schema.Number;
|
|
146
149
|
readonly id: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
@@ -178,6 +181,9 @@ export interface ParserState {
|
|
|
178
181
|
readonly finishReason?: FinishReason;
|
|
179
182
|
readonly lifecycle: Lifecycle.State;
|
|
180
183
|
readonly reasoningField?: "reasoning" | "reasoning_content" | "reasoning_text";
|
|
184
|
+
readonly reasoningDetails: Array<unknown>;
|
|
185
|
+
readonly reasoningDetailsObserved: boolean;
|
|
186
|
+
readonly reasoningEmitted: boolean;
|
|
181
187
|
}
|
|
182
188
|
/**
|
|
183
189
|
* The OpenAI Chat protocol — request body construction, body schema, and the
|
|
@@ -214,6 +220,7 @@ export declare const protocol: Protocol<{
|
|
|
214
220
|
}, "Type">[] | undefined;
|
|
215
221
|
readonly reasoning_content?: string | undefined;
|
|
216
222
|
readonly reasoning_text?: string | undefined;
|
|
223
|
+
readonly reasoning_details?: readonly unknown[] | undefined;
|
|
217
224
|
} | Schema.Struct.ReadonlySide<{
|
|
218
225
|
readonly role: Schema.Literal<"tool">;
|
|
219
226
|
readonly tool_call_id: Schema.String;
|
|
@@ -262,6 +269,7 @@ export declare const protocol: Protocol<{
|
|
|
262
269
|
}[] | null | undefined;
|
|
263
270
|
readonly reasoning_content?: string | null | undefined;
|
|
264
271
|
readonly reasoning_text?: string | null | undefined;
|
|
272
|
+
readonly reasoning_details?: readonly unknown[] | null | undefined;
|
|
265
273
|
} | null | undefined;
|
|
266
274
|
readonly finish_reason?: string | null | undefined;
|
|
267
275
|
}[];
|
|
@@ -306,6 +314,7 @@ export declare const httpTransport: HttpTransport.HttpJsonTransport<{
|
|
|
306
314
|
}, "Type">[] | undefined;
|
|
307
315
|
readonly reasoning_content?: string | undefined;
|
|
308
316
|
readonly reasoning_text?: string | undefined;
|
|
317
|
+
readonly reasoning_details?: readonly unknown[] | undefined;
|
|
309
318
|
} | Schema.Struct.ReadonlySide<{
|
|
310
319
|
readonly role: Schema.Literal<"tool">;
|
|
311
320
|
readonly tool_call_id: Schema.String;
|
|
@@ -369,6 +378,7 @@ export declare const route: Route<{
|
|
|
369
378
|
}, "Type">[] | undefined;
|
|
370
379
|
readonly reasoning_content?: string | undefined;
|
|
371
380
|
readonly reasoning_text?: string | undefined;
|
|
381
|
+
readonly reasoning_details?: readonly unknown[] | undefined;
|
|
372
382
|
} | Schema.Struct.ReadonlySide<{
|
|
373
383
|
readonly role: Schema.Literal<"tool">;
|
|
374
384
|
readonly tool_call_id: Schema.String;
|
|
@@ -57,6 +57,7 @@ const OpenAIChatMessage = Schema.Union([
|
|
|
57
57
|
reasoning_content: Schema.optional(Schema.String),
|
|
58
58
|
reasoning: Schema.optional(Schema.String),
|
|
59
59
|
reasoning_text: Schema.optional(Schema.String),
|
|
60
|
+
reasoning_details: optionalArray(Schema.Unknown),
|
|
60
61
|
}),
|
|
61
62
|
Schema.Struct({ role: Schema.Literal("tool"), tool_call_id: Schema.String, content: Schema.String }),
|
|
62
63
|
]).pipe(Schema.toTaggedUnion("role"));
|
|
@@ -116,6 +117,7 @@ const OpenAIChatDelta = Schema.Struct({
|
|
|
116
117
|
reasoning_content: optionalNull(Schema.String),
|
|
117
118
|
reasoning: optionalNull(Schema.String),
|
|
118
119
|
reasoning_text: optionalNull(Schema.String),
|
|
120
|
+
reasoning_details: optionalNull(Schema.Array(Schema.Unknown)),
|
|
119
121
|
tool_calls: optionalNull(Schema.Array(OpenAIChatToolCallDelta)),
|
|
120
122
|
});
|
|
121
123
|
const OpenAIChatChoice = Schema.Struct({
|
|
@@ -163,7 +165,16 @@ const reasoningField = (part) => {
|
|
|
163
165
|
const field = part.providerMetadata?.openai?.reasoningField;
|
|
164
166
|
if (field === "reasoning" || field === "reasoning_content" || field === "reasoning_text")
|
|
165
167
|
return field;
|
|
166
|
-
|
|
168
|
+
};
|
|
169
|
+
const reasoningDetails = (parts, native) => {
|
|
170
|
+
const observed = parts.flatMap((part) => {
|
|
171
|
+
const details = part.providerMetadata?.openai?.reasoningDetails;
|
|
172
|
+
return Array.isArray(details) ? details : [];
|
|
173
|
+
});
|
|
174
|
+
if (parts.some((part) => Array.isArray(part.providerMetadata?.openai?.reasoningDetails)))
|
|
175
|
+
return observed;
|
|
176
|
+
if (isRecord(native) && Array.isArray(native.reasoning_details))
|
|
177
|
+
return native.reasoning_details;
|
|
167
178
|
};
|
|
168
179
|
const lowerUserMessage = Effect.fn("OpenAIChat.lowerUserMessage")(function* (message) {
|
|
169
180
|
const content = [];
|
|
@@ -203,18 +214,34 @@ const lowerAssistantMessage = Effect.fn("OpenAIChat.lowerAssistantMessage")(func
|
|
|
203
214
|
}
|
|
204
215
|
}
|
|
205
216
|
const text = reasoning.map((part) => part.text).join("");
|
|
206
|
-
const
|
|
217
|
+
const details = reasoningDetails(reasoning, message.native?.openaiCompatible);
|
|
218
|
+
const observedField = reasoning.map(reasoningField).find((value) => value !== undefined);
|
|
219
|
+
const nativeReasoning = openAICompatibleReasoningContent(message.native?.openaiCompatible);
|
|
220
|
+
const fullyStructured = reasoning.every((part) => Array.isArray(part.providerMetadata?.openai?.reasoningDetails));
|
|
221
|
+
const field = (() => {
|
|
222
|
+
if (reasoning.length === 0)
|
|
223
|
+
return;
|
|
224
|
+
if (observedField !== undefined)
|
|
225
|
+
return observedField;
|
|
226
|
+
if (nativeReasoning !== undefined)
|
|
227
|
+
return "reasoning_content";
|
|
228
|
+
if (!fullyStructured)
|
|
229
|
+
return "reasoning_content";
|
|
230
|
+
})();
|
|
231
|
+
const reasoningContent = (() => {
|
|
232
|
+
if (reasoning.length === 0)
|
|
233
|
+
return nativeReasoning;
|
|
234
|
+
if (field === "reasoning_content")
|
|
235
|
+
return text;
|
|
236
|
+
})();
|
|
207
237
|
return {
|
|
208
238
|
role: "assistant",
|
|
209
239
|
content: content.length === 0 ? null : ProviderShared.joinText(content),
|
|
210
240
|
tool_calls: toolCalls.length === 0 ? undefined : toolCalls,
|
|
211
|
-
reasoning_content:
|
|
212
|
-
? openAICompatibleReasoningContent(message.native?.openaiCompatible)
|
|
213
|
-
: field === "reasoning_content"
|
|
214
|
-
? text
|
|
215
|
-
: undefined,
|
|
241
|
+
reasoning_content: reasoningContent,
|
|
216
242
|
reasoning: reasoning.length > 0 && field === "reasoning" ? text : undefined,
|
|
217
243
|
reasoning_text: reasoning.length > 0 && field === "reasoning_text" ? text : undefined,
|
|
244
|
+
reasoning_details: details,
|
|
218
245
|
};
|
|
219
246
|
});
|
|
220
247
|
const lowerToolMessages = Effect.fn("OpenAIChat.lowerToolMessages")(function* (message) {
|
|
@@ -360,6 +387,51 @@ const reasoningDelta = (delta) => {
|
|
|
360
387
|
if (delta?.reasoning_text)
|
|
361
388
|
return { field: "reasoning_text", text: delta.reasoning_text };
|
|
362
389
|
};
|
|
390
|
+
const detailText = (details) => {
|
|
391
|
+
const text = details.flatMap((detail) => {
|
|
392
|
+
if (!isRecord(detail))
|
|
393
|
+
return [];
|
|
394
|
+
if (detail.type === "reasoning.text" && typeof detail.text === "string" && detail.text)
|
|
395
|
+
return [detail.text];
|
|
396
|
+
if (detail.type === "reasoning.summary" && typeof detail.summary === "string" && detail.summary)
|
|
397
|
+
return [detail.summary];
|
|
398
|
+
return [];
|
|
399
|
+
});
|
|
400
|
+
if (text.length > 0)
|
|
401
|
+
return text.join("");
|
|
402
|
+
};
|
|
403
|
+
const appendReasoningDetails = (result, details) => {
|
|
404
|
+
for (const detail of details) {
|
|
405
|
+
const previous = result.at(-1);
|
|
406
|
+
if (!isRecord(previous) ||
|
|
407
|
+
previous.type !== "reasoning.text" ||
|
|
408
|
+
!isRecord(detail) ||
|
|
409
|
+
detail.type !== "reasoning.text" ||
|
|
410
|
+
conflictingReasoningTextDetails(previous, detail)) {
|
|
411
|
+
result.push(detail);
|
|
412
|
+
continue;
|
|
413
|
+
}
|
|
414
|
+
result[result.length - 1] = {
|
|
415
|
+
...previous,
|
|
416
|
+
...Object.fromEntries(Object.entries(detail).filter((entry) => entry[1] !== undefined)),
|
|
417
|
+
text: `${typeof previous.text === "string" ? previous.text : ""}${typeof detail.text === "string" ? detail.text : ""}`,
|
|
418
|
+
signature: mergeDetailValue(previous.signature, detail.signature),
|
|
419
|
+
format: mergeDetailValue(previous.format, detail.format),
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
};
|
|
423
|
+
const mergeDetailValue = (previous, current) => previous || current || (previous !== undefined ? previous : current);
|
|
424
|
+
const conflictingReasoningTextDetails = (previous, current) => conflictingDetailValue(previous.id, current.id) ||
|
|
425
|
+
conflictingDetailValue(previous.index, current.index) ||
|
|
426
|
+
conflictingDetailValue(previous.format, current.format) ||
|
|
427
|
+
(Boolean(previous.signature) && Boolean(current.signature) && previous.signature !== current.signature);
|
|
428
|
+
const conflictingDetailValue = (previous, current) => previous !== undefined && previous !== null && current !== undefined && current !== null && previous !== current;
|
|
429
|
+
const reasoningMetadata = (field, details) => ({
|
|
430
|
+
openai: {
|
|
431
|
+
...(field ? { reasoningField: field } : {}),
|
|
432
|
+
...(details ? { reasoningDetails: details } : {}),
|
|
433
|
+
},
|
|
434
|
+
});
|
|
363
435
|
const step = (state, event) => Effect.gen(function* () {
|
|
364
436
|
const events = [];
|
|
365
437
|
const usage = mapUsage(event.usage) ?? state.usage;
|
|
@@ -371,17 +443,24 @@ const step = (state, event) => Effect.gen(function* () {
|
|
|
371
443
|
let pendingTools = state.pendingTools;
|
|
372
444
|
let lifecycle = state.lifecycle;
|
|
373
445
|
const reasoning = reasoningDelta(delta);
|
|
374
|
-
const reasoningField = state.reasoningField ?? reasoning?.field;
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
446
|
+
const reasoningField = state.reasoningField ?? (!state.lifecycle.text.has("text-0") ? reasoning?.field : undefined);
|
|
447
|
+
const detailDelta = Array.isArray(delta?.reasoning_details) ? delta.reasoning_details : undefined;
|
|
448
|
+
if (detailDelta !== undefined)
|
|
449
|
+
appendReasoningDetails(state.reasoningDetails, detailDelta);
|
|
450
|
+
const reasoningDetailsObserved = state.reasoningDetailsObserved || detailDelta !== undefined;
|
|
451
|
+
const deltaMetadata = reasoningMetadata(reasoningField);
|
|
452
|
+
const text = detailDelta?.length ? (detailText(detailDelta) ?? reasoning?.text) : reasoning?.text;
|
|
453
|
+
if (!state.lifecycle.text.has("text-0") && text !== undefined)
|
|
454
|
+
lifecycle = Lifecycle.reasoningDelta(lifecycle, events, "reasoning-0", text, deltaMetadata);
|
|
455
|
+
else if (reasoningDetailsObserved &&
|
|
456
|
+
!lifecycle.reasoning.has("reasoning-0") &&
|
|
457
|
+
(Boolean(delta?.content) || toolDeltas.length > 0))
|
|
458
|
+
lifecycle = Lifecycle.reasoningStart(lifecycle, events, "reasoning-0", deltaMetadata);
|
|
459
|
+
const reasoningEmitted = state.reasoningEmitted || lifecycle.reasoning.has("reasoning-0");
|
|
379
460
|
if (delta?.content) {
|
|
380
|
-
lifecycle = Lifecycle.reasoningEnd(lifecycle, events, "reasoning-0");
|
|
461
|
+
lifecycle = Lifecycle.reasoningEnd(lifecycle, events, "reasoning-0", reasoningMetadata(reasoningField, reasoningDetailsObserved ? state.reasoningDetails : undefined));
|
|
381
462
|
lifecycle = Lifecycle.textDelta(lifecycle, events, "text-0", delta.content);
|
|
382
463
|
}
|
|
383
|
-
if (toolDeltas.length)
|
|
384
|
-
lifecycle = Lifecycle.reasoningEnd(lifecycle, events, "reasoning-0");
|
|
385
464
|
for (const tool of toolDeltas) {
|
|
386
465
|
const current = tools[tool.index];
|
|
387
466
|
const pending = pendingTools[tool.index];
|
|
@@ -420,6 +499,9 @@ const step = (state, event) => Effect.gen(function* () {
|
|
|
420
499
|
finishReason,
|
|
421
500
|
lifecycle,
|
|
422
501
|
reasoningField,
|
|
502
|
+
reasoningDetails: state.reasoningDetails,
|
|
503
|
+
reasoningDetailsObserved,
|
|
504
|
+
reasoningEmitted,
|
|
423
505
|
},
|
|
424
506
|
events,
|
|
425
507
|
];
|
|
@@ -428,7 +510,12 @@ const finishEvents = (state) => {
|
|
|
428
510
|
const events = [];
|
|
429
511
|
const hasToolCalls = state.toolCallEvents.length > 0;
|
|
430
512
|
const reason = state.finishReason === "stop" && hasToolCalls ? "tool-calls" : state.finishReason;
|
|
431
|
-
const
|
|
513
|
+
const metadata = reasoningMetadata(state.reasoningField, state.reasoningDetailsObserved ? state.reasoningDetails : undefined);
|
|
514
|
+
const started = state.reasoningDetailsObserved && !state.reasoningEmitted
|
|
515
|
+
? Lifecycle.reasoningStart(state.lifecycle, events, "reasoning-0", reasoningMetadata(state.reasoningField))
|
|
516
|
+
: state.lifecycle;
|
|
517
|
+
const ended = Lifecycle.reasoningEnd(started, events, "reasoning-0", metadata);
|
|
518
|
+
const lifecycle = state.toolCallEvents.length ? Lifecycle.stepStart(ended, events) : ended;
|
|
432
519
|
events.push(...state.toolCallEvents);
|
|
433
520
|
if (reason)
|
|
434
521
|
Lifecycle.finish(lifecycle, events, { reason, usage: state.usage });
|
|
@@ -457,6 +544,9 @@ export const protocol = Protocol.make({
|
|
|
457
544
|
toolCallEvents: [],
|
|
458
545
|
lifecycle: Lifecycle.initial(),
|
|
459
546
|
reasoningField: undefined,
|
|
547
|
+
reasoningDetails: [],
|
|
548
|
+
reasoningDetailsObserved: false,
|
|
549
|
+
reasoningEmitted: false,
|
|
460
550
|
}),
|
|
461
551
|
step,
|
|
462
552
|
onHalt: finishEvents,
|
|
@@ -36,6 +36,7 @@ export declare const route: Route<{
|
|
|
36
36
|
}, "Type">[] | undefined;
|
|
37
37
|
readonly reasoning_content?: string | undefined;
|
|
38
38
|
readonly reasoning_text?: string | undefined;
|
|
39
|
+
readonly reasoning_details?: readonly unknown[] | undefined;
|
|
39
40
|
} | import("effect/Schema").Struct.ReadonlySide<{
|
|
40
41
|
readonly role: import("effect/Schema").Literal<"tool">;
|
|
41
42
|
readonly tool_call_id: import("effect/Schema").String;
|
|
@@ -24,7 +24,7 @@ export const reasoningStart = (state, events, id, providerMetadata) => {
|
|
|
24
24
|
};
|
|
25
25
|
export const reasoningDelta = (state, events, id, text, providerMetadata) => {
|
|
26
26
|
const started = reasoningStart(state, events, id, providerMetadata);
|
|
27
|
-
events.push(LLMEvent.reasoningDelta({ id, text }));
|
|
27
|
+
events.push(LLMEvent.reasoningDelta({ id, text, providerMetadata }));
|
|
28
28
|
return started;
|
|
29
29
|
};
|
|
30
30
|
export const reasoningEnd = (state, events, id, providerMetadata) => {
|
package/dist/provider-error.js
CHANGED
|
@@ -2,13 +2,17 @@ import { Option, Schema } from "effect";
|
|
|
2
2
|
import { AuthenticationReason, ContentPolicyReason, InvalidRequestReason, LLMError, ProviderErrorEvent, ProviderInternalReason, QuotaExceededReason, RateLimitReason, UnknownProviderReason, } from "./schema";
|
|
3
3
|
const patterns = [
|
|
4
4
|
/prompt is too long/i,
|
|
5
|
+
/request_too_large/i,
|
|
5
6
|
/input is too long for requested model/i,
|
|
6
7
|
/exceeds the context window/i,
|
|
8
|
+
/exceeds (?:the )?(?:model'?s )?maximum context length(?: of [\d,]+ tokens?|\s*\([\d,]+\))/i,
|
|
7
9
|
/input token count.*exceeds the maximum/i,
|
|
8
10
|
/tokens in request more than max tokens allowed/i,
|
|
9
11
|
/maximum prompt length is \d+/i,
|
|
10
12
|
/reduce the length of the messages/i,
|
|
11
13
|
/maximum context length is \d+ tokens/i,
|
|
14
|
+
/exceeds (?:the )?maximum allowed input length of [\d,]+ tokens?/i,
|
|
15
|
+
/input \(\d+ tokens\) is longer than the model'?s context length \(\d+ tokens\)/i,
|
|
12
16
|
/exceeds the limit of \d+/i,
|
|
13
17
|
/exceeds the available context size/i,
|
|
14
18
|
/greater than the context length/i,
|
|
@@ -20,9 +24,14 @@ const patterns = [
|
|
|
20
24
|
/input length.*exceeds.*context length/i,
|
|
21
25
|
/prompt too long; exceeded (?:max )?context length/i,
|
|
22
26
|
/too large for model with \d+ maximum context length/i,
|
|
27
|
+
/prompt has [\d,]+ tokens?, but the configured context size is [\d,]+ tokens?/i,
|
|
23
28
|
/model_context_window_exceeded/i,
|
|
29
|
+
/too many tokens/i,
|
|
30
|
+
/token limit exceeded/i,
|
|
24
31
|
];
|
|
25
|
-
|
|
32
|
+
const exclusions = [/^(throttling error|service unavailable):/i, /rate limit/i, /too many requests/i];
|
|
33
|
+
export const isContextOverflow = (message) => !exclusions.some((pattern) => pattern.test(message)) &&
|
|
34
|
+
(patterns.some((pattern) => pattern.test(message)) || /^4(00|13)\s*(status code)?\s*\(no body\)/i.test(message));
|
|
26
35
|
export const isContextOverflowFailure = (failure) => failure instanceof LLMError
|
|
27
36
|
? failure.reason._tag === "InvalidRequest" && failure.reason.classification === "context-overflow"
|
|
28
37
|
: Schema.is(ProviderErrorEvent)(failure) && failure.classification === "context-overflow";
|
|
@@ -50,6 +50,7 @@ export declare const routes: (RouteDef<{
|
|
|
50
50
|
}, "Type">[] | undefined;
|
|
51
51
|
readonly reasoning_content?: string | undefined;
|
|
52
52
|
readonly reasoning_text?: string | undefined;
|
|
53
|
+
readonly reasoning_details?: readonly unknown[] | undefined;
|
|
53
54
|
} | import("effect/Schema").Struct.ReadonlySide<{
|
|
54
55
|
readonly role: import("effect/Schema").Literal<"tool">;
|
|
55
56
|
readonly tool_call_id: import("effect/Schema").String;
|
|
@@ -53,6 +53,7 @@ export declare const aiGatewayRoute: import("../route").Route<{
|
|
|
53
53
|
}, "Type">[] | undefined;
|
|
54
54
|
readonly reasoning_content?: string | undefined;
|
|
55
55
|
readonly reasoning_text?: string | undefined;
|
|
56
|
+
readonly reasoning_details?: readonly unknown[] | undefined;
|
|
56
57
|
} | import("effect/Schema").Struct.ReadonlySide<{
|
|
57
58
|
readonly role: import("effect/Schema").Literal<"tool">;
|
|
58
59
|
readonly tool_call_id: import("effect/Schema").String;
|
|
@@ -116,6 +117,7 @@ export declare const workersAIRoute: import("../route").Route<{
|
|
|
116
117
|
}, "Type">[] | undefined;
|
|
117
118
|
readonly reasoning_content?: string | undefined;
|
|
118
119
|
readonly reasoning_text?: string | undefined;
|
|
120
|
+
readonly reasoning_details?: readonly unknown[] | undefined;
|
|
119
121
|
} | import("effect/Schema").Struct.ReadonlySide<{
|
|
120
122
|
readonly role: import("effect/Schema").Literal<"tool">;
|
|
121
123
|
readonly tool_call_id: import("effect/Schema").String;
|
|
@@ -179,6 +181,7 @@ export declare const routes: import("../route").Route<{
|
|
|
179
181
|
}, "Type">[] | undefined;
|
|
180
182
|
readonly reasoning_content?: string | undefined;
|
|
181
183
|
readonly reasoning_text?: string | undefined;
|
|
184
|
+
readonly reasoning_details?: readonly unknown[] | undefined;
|
|
182
185
|
} | import("effect/Schema").Struct.ReadonlySide<{
|
|
183
186
|
readonly role: import("effect/Schema").Literal<"tool">;
|
|
184
187
|
readonly tool_call_id: import("effect/Schema").String;
|
|
@@ -38,6 +38,7 @@ export declare const routes: (import("../route").Route<{
|
|
|
38
38
|
}, "Type">[] | undefined;
|
|
39
39
|
readonly reasoning_content?: string | undefined;
|
|
40
40
|
readonly reasoning_text?: string | undefined;
|
|
41
|
+
readonly reasoning_details?: readonly unknown[] | undefined;
|
|
41
42
|
} | import("effect/Schema").Struct.ReadonlySide<{
|
|
42
43
|
readonly role: import("effect/Schema").Literal<"tool">;
|
|
43
44
|
readonly tool_call_id: import("effect/Schema").String;
|
|
@@ -45,6 +45,7 @@ export declare const routes: import("../route").Route<{
|
|
|
45
45
|
}, "Type">[] | undefined;
|
|
46
46
|
readonly reasoning_content?: string | undefined;
|
|
47
47
|
readonly reasoning_text?: string | undefined;
|
|
48
|
+
readonly reasoning_details?: readonly unknown[] | undefined;
|
|
48
49
|
} | import("effect/Schema").Struct.ReadonlySide<{
|
|
49
50
|
readonly role: import("effect/Schema").Literal<"tool">;
|
|
50
51
|
readonly tool_call_id: import("effect/Schema").String;
|
|
@@ -44,6 +44,7 @@ export declare const routes: import("../route").Route<{
|
|
|
44
44
|
}, "Type">[] | undefined;
|
|
45
45
|
readonly reasoning_content?: string | undefined;
|
|
46
46
|
readonly reasoning_text?: string | undefined;
|
|
47
|
+
readonly reasoning_details?: readonly unknown[] | undefined;
|
|
47
48
|
} | import("effect/Schema").Struct.ReadonlySide<{
|
|
48
49
|
readonly role: import("effect/Schema").Literal<"tool">;
|
|
49
50
|
readonly tool_call_id: import("effect/Schema").String;
|
|
@@ -36,6 +36,7 @@ export declare const routes: (Route<{
|
|
|
36
36
|
}, "Type">[] | undefined;
|
|
37
37
|
readonly reasoning_content?: string | undefined;
|
|
38
38
|
readonly reasoning_text?: string | undefined;
|
|
39
|
+
readonly reasoning_details?: readonly unknown[] | undefined;
|
|
39
40
|
} | import("effect/Schema").Struct.ReadonlySide<{
|
|
40
41
|
readonly role: import("effect/Schema").Literal<"tool">;
|
|
41
42
|
readonly tool_call_id: import("effect/Schema").String;
|
|
@@ -52,6 +52,7 @@ declare const OpenRouterBody: Schema.StructWithRest<Schema.Struct<{
|
|
|
52
52
|
readonly reasoning_content: Schema.optional<Schema.String>;
|
|
53
53
|
readonly reasoning: Schema.optional<Schema.String>;
|
|
54
54
|
readonly reasoning_text: Schema.optional<Schema.String>;
|
|
55
|
+
readonly reasoning_details: Schema.optional<Schema.$Array<Schema.Unknown>>;
|
|
55
56
|
}>, Schema.Struct<{
|
|
56
57
|
readonly role: Schema.Literal<"tool">;
|
|
57
58
|
readonly tool_call_id: Schema.String;
|
|
@@ -116,6 +117,7 @@ export declare const protocol: Protocol<{
|
|
|
116
117
|
}, "Type">[] | undefined;
|
|
117
118
|
readonly reasoning_content?: string | undefined;
|
|
118
119
|
readonly reasoning_text?: string | undefined;
|
|
120
|
+
readonly reasoning_details?: readonly unknown[] | undefined;
|
|
119
121
|
} | Schema.Struct.ReadonlySide<{
|
|
120
122
|
readonly role: Schema.Literal<"tool">;
|
|
121
123
|
readonly tool_call_id: Schema.String;
|
|
@@ -164,6 +166,7 @@ export declare const protocol: Protocol<{
|
|
|
164
166
|
}[] | null | undefined;
|
|
165
167
|
readonly reasoning_content?: string | null | undefined;
|
|
166
168
|
readonly reasoning_text?: string | null | undefined;
|
|
169
|
+
readonly reasoning_details?: readonly unknown[] | null | undefined;
|
|
167
170
|
} | null | undefined;
|
|
168
171
|
readonly finish_reason?: string | null | undefined;
|
|
169
172
|
}[];
|
|
@@ -209,6 +212,7 @@ export declare const route: Route<{
|
|
|
209
212
|
}, "Type">[] | undefined;
|
|
210
213
|
readonly reasoning_content?: string | undefined;
|
|
211
214
|
readonly reasoning_text?: string | undefined;
|
|
215
|
+
readonly reasoning_details?: readonly unknown[] | undefined;
|
|
212
216
|
} | Schema.Struct.ReadonlySide<{
|
|
213
217
|
readonly role: Schema.Literal<"tool">;
|
|
214
218
|
readonly tool_call_id: Schema.String;
|
|
@@ -273,6 +277,7 @@ export declare const routes: Route<{
|
|
|
273
277
|
}, "Type">[] | undefined;
|
|
274
278
|
readonly reasoning_content?: string | undefined;
|
|
275
279
|
readonly reasoning_text?: string | undefined;
|
|
280
|
+
readonly reasoning_details?: readonly unknown[] | undefined;
|
|
276
281
|
} | Schema.Struct.ReadonlySide<{
|
|
277
282
|
readonly role: Schema.Literal<"tool">;
|
|
278
283
|
readonly tool_call_id: Schema.String;
|
|
@@ -18,10 +18,32 @@ export const protocol = Protocol.make({
|
|
|
18
18
|
id: "openrouter-chat",
|
|
19
19
|
body: {
|
|
20
20
|
schema: OpenRouterBody,
|
|
21
|
-
from: (request) => OpenAIChat.protocol.body.from(request).pipe(Effect.map((body) =>
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
from: (request) => OpenAIChat.protocol.body.from(request).pipe(Effect.map((body) => {
|
|
22
|
+
const sourceAssistants = request.messages.filter((message) => message.role === "assistant");
|
|
23
|
+
let assistantIndex = 0;
|
|
24
|
+
const messages = body.messages.map((message) => {
|
|
25
|
+
if (message.role !== "assistant")
|
|
26
|
+
return message;
|
|
27
|
+
const source = sourceAssistants[assistantIndex++];
|
|
28
|
+
const reasoning = source?.content
|
|
29
|
+
.filter((part) => part.type === "reasoning")
|
|
30
|
+
.map((part) => part.text)
|
|
31
|
+
.join("");
|
|
32
|
+
const reasoningDetails = Array.isArray(message.reasoning_details) ? message.reasoning_details : undefined;
|
|
33
|
+
return {
|
|
34
|
+
...message,
|
|
35
|
+
reasoning_content: undefined,
|
|
36
|
+
reasoning_text: undefined,
|
|
37
|
+
reasoning: reasoning && reasoningDetails && reasoningDetails.length > 0 ? reasoning : undefined,
|
|
38
|
+
reasoning_details: reasoningDetails,
|
|
39
|
+
};
|
|
40
|
+
});
|
|
41
|
+
return {
|
|
42
|
+
...body,
|
|
43
|
+
messages,
|
|
44
|
+
...bodyOptions(request.providerOptions?.openrouter),
|
|
45
|
+
};
|
|
46
|
+
})),
|
|
25
47
|
},
|
|
26
48
|
stream: OpenAIChat.protocol.stream,
|
|
27
49
|
});
|
package/dist/providers/xai.d.ts
CHANGED
|
@@ -34,6 +34,7 @@ export declare const routes: (import("../route").Route<{
|
|
|
34
34
|
}, "Type">[] | undefined;
|
|
35
35
|
readonly reasoning_content?: string | undefined;
|
|
36
36
|
readonly reasoning_text?: string | undefined;
|
|
37
|
+
readonly reasoning_details?: readonly unknown[] | undefined;
|
|
37
38
|
} | import("effect/Schema").Struct.ReadonlySide<{
|
|
38
39
|
readonly role: import("effect/Schema").Literal<"tool">;
|
|
39
40
|
readonly tool_call_id: import("effect/Schema").String;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
|
-
"version": "0.0.0-next-
|
|
3
|
+
"version": "0.0.0-next-15848",
|
|
4
4
|
"name": "@opencode-ai/ai",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@clack/prompts": "1.0.0-alpha.1",
|
|
28
28
|
"@effect/platform-node": "4.0.0-beta.98",
|
|
29
|
-
"@opencode-ai/http-recorder": "0.0.0-next-
|
|
29
|
+
"@opencode-ai/http-recorder": "0.0.0-next-15848",
|
|
30
30
|
"@tsconfig/bun": "1.0.9",
|
|
31
31
|
"@types/bun": "1.3.13",
|
|
32
32
|
"@typescript/native-preview": "7.0.0-dev.20251207.1",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@smithy/eventstream-codec": "4.2.14",
|
|
37
37
|
"@smithy/util-utf8": "4.2.2",
|
|
38
|
-
"@opencode-ai/schema": "0.0.0-next-
|
|
38
|
+
"@opencode-ai/schema": "0.0.0-next-15848",
|
|
39
39
|
"aws4fetch": "1.0.20",
|
|
40
40
|
"effect": "4.0.0-beta.98",
|
|
41
41
|
"google-auth-library": "10.5.0"
|