@opencode-ai/ai 0.0.0-dev-18232 → 0.0.0-dev-18235
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.
|
@@ -241,7 +241,7 @@ const lowerUserMessage = Effect.fn("OpenAIChat.lowerUserMessage")(function* (mes
|
|
|
241
241
|
};
|
|
242
242
|
return { role: "user", content };
|
|
243
243
|
});
|
|
244
|
-
const lowerAssistantMessage = Effect.fn("OpenAIChat.lowerAssistantMessage")(function* (message, configuredField, options
|
|
244
|
+
const lowerAssistantMessage = Effect.fn("OpenAIChat.lowerAssistantMessage")(function* (message, configuredField, requireReasoning, options) {
|
|
245
245
|
const content = [];
|
|
246
246
|
const reasoning = [];
|
|
247
247
|
const toolCalls = [];
|
|
@@ -267,22 +267,22 @@ const lowerAssistantMessage = Effect.fn("OpenAIChat.lowerAssistantMessage")(func
|
|
|
267
267
|
const nativeReasoning = openAICompatibleReasoningContent(message.native?.openaiCompatible);
|
|
268
268
|
const fullyStructured = reasoning.every((part) => Array.isArray(part.providerMetadata?.openai?.reasoningDetails));
|
|
269
269
|
const field = (() => {
|
|
270
|
-
if (configuredField !== undefined)
|
|
270
|
+
if (configuredField !== undefined && (requireReasoning || reasoning.length > 0 || nativeReasoning !== undefined))
|
|
271
271
|
return configuredField;
|
|
272
272
|
if (reasoning.length === 0)
|
|
273
|
-
return undefined;
|
|
273
|
+
return requireReasoning ? "reasoning_content" : undefined;
|
|
274
274
|
if (observedField !== undefined)
|
|
275
275
|
return observedField;
|
|
276
276
|
if (nativeReasoning !== undefined)
|
|
277
277
|
return "reasoning_content";
|
|
278
|
-
if (!fullyStructured)
|
|
278
|
+
if (!fullyStructured || requireReasoning)
|
|
279
279
|
return "reasoning_content";
|
|
280
280
|
})();
|
|
281
281
|
const reasoningText = (() => {
|
|
282
282
|
if (configuredField !== undefined)
|
|
283
|
-
return reasoning.length === 0 ? (nativeReasoning ?? "") : text;
|
|
283
|
+
return reasoning.length === 0 ? (nativeReasoning ?? (requireReasoning ? "" : undefined)) : text;
|
|
284
284
|
if (reasoning.length === 0)
|
|
285
|
-
return nativeReasoning;
|
|
285
|
+
return nativeReasoning ?? (requireReasoning ? "" : undefined);
|
|
286
286
|
return text;
|
|
287
287
|
})();
|
|
288
288
|
const cached = message.content.findLast((part) => "cache" in part && part.cache !== undefined);
|
|
@@ -326,11 +326,11 @@ const lowerToolMessages = Effect.fn("OpenAIChat.lowerToolMessages")(function* (m
|
|
|
326
326
|
}
|
|
327
327
|
return { messages, images };
|
|
328
328
|
});
|
|
329
|
-
const lowerMessage = Effect.fn("OpenAIChat.lowerMessage")(function* (message, reasoningField, options
|
|
329
|
+
const lowerMessage = Effect.fn("OpenAIChat.lowerMessage")(function* (message, reasoningField, requireReasoning, options) {
|
|
330
330
|
if (message.role === "user")
|
|
331
331
|
return [yield* lowerUserMessage(message, options)];
|
|
332
332
|
if (message.role === "assistant")
|
|
333
|
-
return [yield* lowerAssistantMessage(message, reasoningField, options)];
|
|
333
|
+
return [yield* lowerAssistantMessage(message, reasoningField, requireReasoning, options)];
|
|
334
334
|
return (yield* lowerToolMessages(message, options)).messages;
|
|
335
335
|
});
|
|
336
336
|
const lowerMessages = Effect.fn("OpenAIChat.lowerMessages")(function* (request, options) {
|
|
@@ -350,6 +350,12 @@ const lowerMessages = Effect.fn("OpenAIChat.lowerMessages")(function* (request,
|
|
|
350
350
|
: [{ role: "system", content: ProviderShared.joinText(request.system) }];
|
|
351
351
|
const messages = [...system];
|
|
352
352
|
const modelID = request.model.id.toLowerCase();
|
|
353
|
+
const requireReasoning = request.model.compatibility?.requireReasoning ??
|
|
354
|
+
(request.model.compatibility?.reasoningField !== undefined ||
|
|
355
|
+
request.model.provider === "deepseek" ||
|
|
356
|
+
request.model.route.endpoint.baseURL?.toLowerCase().includes("deepseek.com") ||
|
|
357
|
+
modelID.includes("deepseek"));
|
|
358
|
+
const reasoningField = request.model.compatibility?.reasoningField;
|
|
353
359
|
const mistral = ["mistral", "devstral", "codestral", "pixtral", "mixtral"].some((family) => modelID.includes(family));
|
|
354
360
|
const lowering = {
|
|
355
361
|
...options,
|
|
@@ -427,7 +433,7 @@ const lowerMessages = Effect.fn("OpenAIChat.lowerMessages")(function* (request,
|
|
|
427
433
|
continue;
|
|
428
434
|
}
|
|
429
435
|
flushImages();
|
|
430
|
-
messages.push(...(yield* lowerMessage(message,
|
|
436
|
+
messages.push(...(yield* lowerMessage(message, reasoningField, requireReasoning, lowering)));
|
|
431
437
|
}
|
|
432
438
|
flushImages();
|
|
433
439
|
return messages;
|
package/dist/schema/options.d.ts
CHANGED
|
@@ -72,6 +72,8 @@ export type LanguageModelMaxTokensFieldCompatibility = Schema.Schema.Type<typeof
|
|
|
72
72
|
declare const LanguageModelCompatibility_base: Schema.Class<LanguageModelCompatibility, Schema.Struct<{
|
|
73
73
|
readonly toolSchema: Schema.optional<Schema.Literals<readonly ["gemini", "moonshot"]>>;
|
|
74
74
|
readonly reasoningField: Schema.optional<Schema.String>;
|
|
75
|
+
/** Require every assistant message to include its reasoning field, even when empty. */
|
|
76
|
+
readonly requireReasoning: Schema.optional<Schema.Boolean>;
|
|
75
77
|
readonly maxTokensField: Schema.optional<Schema.Literals<readonly ["max_completion_tokens", "max_tokens"]>>;
|
|
76
78
|
readonly requireFinishReason: Schema.optional<Schema.Boolean>;
|
|
77
79
|
readonly requireAssistantAfterTool: Schema.optional<Schema.Boolean>;
|
package/dist/schema/options.js
CHANGED
|
@@ -99,6 +99,8 @@ export const LanguageModelMaxTokensFieldCompatibility = Schema.Literals(["max_co
|
|
|
99
99
|
export class LanguageModelCompatibility extends Schema.Class("LLM.LanguageModelCompatibility")({
|
|
100
100
|
toolSchema: Schema.optional(LanguageModelToolSchemaCompatibility),
|
|
101
101
|
reasoningField: Schema.optional(Schema.String),
|
|
102
|
+
/** Require every assistant message to include its reasoning field, even when empty. */
|
|
103
|
+
requireReasoning: Schema.optional(Schema.Boolean),
|
|
102
104
|
maxTokensField: Schema.optional(LanguageModelMaxTokensFieldCompatibility),
|
|
103
105
|
requireFinishReason: Schema.optional(Schema.Boolean),
|
|
104
106
|
requireAssistantAfterTool: Schema.optional(Schema.Boolean),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
|
-
"version": "0.0.0-dev-
|
|
3
|
+
"version": "0.0.0-dev-18235",
|
|
4
4
|
"name": "@opencode-ai/ai",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@clack/prompts": "1.0.0-alpha.1",
|
|
32
32
|
"@effect/platform-node": "4.0.0-rc.111",
|
|
33
|
-
"@opencode-ai/http-recorder": "0.0.0-dev-
|
|
33
|
+
"@opencode-ai/http-recorder": "0.0.0-dev-18235",
|
|
34
34
|
"@tsconfig/bun": "1.0.9",
|
|
35
35
|
"@types/bun": "1.3.13",
|
|
36
36
|
"@typescript/native-preview": "7.0.0-dev.20251207.1",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@smithy/eventstream-codec": "4.2.14",
|
|
41
41
|
"@smithy/util-utf8": "4.2.2",
|
|
42
|
-
"@opencode-ai/schema": "0.0.0-dev-
|
|
42
|
+
"@opencode-ai/schema": "0.0.0-dev-18235",
|
|
43
43
|
"aws4fetch": "1.0.20",
|
|
44
44
|
"effect": "4.0.0-rc.111",
|
|
45
45
|
"google-auth-library": "10.5.0"
|