@opencode/ai 0.0.0-dev-20120 → 0.0.0-dev-20122
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.
|
@@ -10,6 +10,7 @@ import { classifyProviderFailure } from "../provider-error.js";
|
|
|
10
10
|
import { JsonObject, optionalArray, optionalNull, ProviderShared } from "./shared.js";
|
|
11
11
|
import { Lifecycle } from "./utils/lifecycle.js";
|
|
12
12
|
import { MistralToolID } from "./utils/mistral-tool-id.js";
|
|
13
|
+
import { ToolSchemaProjection } from "./utils/tool-schema.js";
|
|
13
14
|
import { ToolStream } from "./utils/tool-stream.js";
|
|
14
15
|
const ADAPTER = "mistral-chat";
|
|
15
16
|
const DONE = "[DONE]";
|
|
@@ -272,9 +273,9 @@ const lowerMessages = Effect.fn("MistralChat.lowerMessages")(function* (request)
|
|
|
272
273
|
}
|
|
273
274
|
return messages;
|
|
274
275
|
});
|
|
275
|
-
const lowerTool = (tool) => ({
|
|
276
|
+
const lowerTool = (tool, inputSchema) => ({
|
|
276
277
|
type: "function",
|
|
277
|
-
function: { name: tool.name, description: tool.description, parameters:
|
|
278
|
+
function: { name: tool.name, description: tool.description, parameters: inputSchema, strict: false },
|
|
278
279
|
});
|
|
279
280
|
export const fromRequest = Effect.fn("MistralChat.fromRequest")(function* (request) {
|
|
280
281
|
const options = yield* ProviderShared.validateWith(Schema.decodeUnknownEffect(MistralOptions))(request.providerOptions ?? {});
|
|
@@ -295,7 +296,9 @@ export const fromRequest = Effect.fn("MistralChat.fromRequest")(function* (reque
|
|
|
295
296
|
return {
|
|
296
297
|
model: request.model.id,
|
|
297
298
|
messages: yield* lowerMessages(flattened.request),
|
|
298
|
-
tools: flattened.tools.length > 0
|
|
299
|
+
tools: flattened.tools.length > 0
|
|
300
|
+
? flattened.tools.map((tool) => lowerTool(tool, ToolSchemaProjection.modelCompatibility(tool.inputSchema, request.model)))
|
|
301
|
+
: undefined,
|
|
299
302
|
tool_choice: toolChoice,
|
|
300
303
|
stream: true,
|
|
301
304
|
max_tokens: request.generation?.maxTokens,
|
|
@@ -54,18 +54,31 @@ const MODEL_NAMES = [
|
|
|
54
54
|
[/gemini/i, "gemini"],
|
|
55
55
|
[/kimi/i, "moonshot"],
|
|
56
56
|
];
|
|
57
|
-
//
|
|
58
|
-
//
|
|
59
|
-
//
|
|
57
|
+
// Tool arguments are always a JSON object, and most providers reject a tool schema whose root does not
|
|
58
|
+
// declare `type: "object"`, such as `{}` or a bare `properties` map. Effect encodes an empty struct as
|
|
59
|
+
// `anyOf` object or array; every object matches its bare object branch, so that `anyOf` is dropped.
|
|
60
|
+
const objectRoot = (schema) => {
|
|
61
|
+
if (schema.type !== undefined)
|
|
62
|
+
return schema;
|
|
63
|
+
if (Array.isArray(schema.anyOf) &&
|
|
64
|
+
schema.anyOf.some((branch) => isRecord(branch) && branch.type === "object" && Object.keys(branch).length === 1))
|
|
65
|
+
return { type: "object", ...Object.fromEntries(Object.entries(schema).filter(([key]) => key !== "anyOf")) };
|
|
66
|
+
return { type: "object", ...schema };
|
|
67
|
+
};
|
|
68
|
+
// Every tool schema gets an object root. Then an explicit `sanitizer` wins, and `none` opts out.
|
|
69
|
+
// Otherwise the protocol's own default applies (the Gemini API always uses Gemini's rules), then the
|
|
70
|
+
// model name selects the family's rules so models reached through gateways and OpenAI-compatible
|
|
71
|
+
// endpoints get the same handling.
|
|
60
72
|
const modelCompatibility = (schema, model, protocolDefault) => {
|
|
73
|
+
const root = objectRoot(schema);
|
|
61
74
|
switch (model.compatibility?.sanitizer ?? protocolDefault ?? MODEL_NAMES.find(([name]) => name.test(model.id))?.[1]) {
|
|
62
75
|
case "gemini":
|
|
63
|
-
return gemini(
|
|
76
|
+
return gemini(root);
|
|
64
77
|
case "moonshot":
|
|
65
|
-
return moonshot(
|
|
78
|
+
return moonshot(root);
|
|
66
79
|
case "none":
|
|
67
80
|
case undefined:
|
|
68
|
-
return
|
|
81
|
+
return root;
|
|
69
82
|
}
|
|
70
83
|
};
|
|
71
84
|
export const ToolSchemaProjection = {
|
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-20122",
|
|
4
4
|
"name": "@opencode/ai",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@clack/prompts": "1.0.0-alpha.1",
|
|
36
36
|
"@effect/platform-node": "4.0.0-rc.112",
|
|
37
|
-
"@opencode/http-recorder": "0.0.0-dev-
|
|
37
|
+
"@opencode/http-recorder": "0.0.0-dev-20122",
|
|
38
38
|
"@tsconfig/bun": "1.0.9",
|
|
39
39
|
"@types/bun": "1.4.0",
|
|
40
40
|
"@typescript/native-preview": "7.0.0-dev.20251207.1",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"@aws-sdk/credential-providers": "3.1057.0",
|
|
45
45
|
"@smithy/eventstream-codec": "4.2.14",
|
|
46
46
|
"@smithy/util-utf8": "4.2.2",
|
|
47
|
-
"@opencode/schema": "0.0.0-dev-
|
|
47
|
+
"@opencode/schema": "0.0.0-dev-20122",
|
|
48
48
|
"aws4fetch": "1.0.20",
|
|
49
49
|
"effect": "4.0.0-rc.112",
|
|
50
50
|
"google-auth-library": "10.5.0"
|