@opencode-ai/ai 0.0.0-dev-18164 → 0.0.0-dev-18167
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.
|
@@ -43,8 +43,58 @@ export function parseJSON(jsonString, allowPartial = Allow.ALL) {
|
|
|
43
43
|
return decodeJson(input);
|
|
44
44
|
}
|
|
45
45
|
catch { }
|
|
46
|
-
|
|
46
|
+
const repaired = repairJSON(input);
|
|
47
|
+
if (repaired !== input) {
|
|
48
|
+
try {
|
|
49
|
+
return decodeJson(repaired);
|
|
50
|
+
}
|
|
51
|
+
catch { }
|
|
52
|
+
}
|
|
53
|
+
try {
|
|
54
|
+
return _parseJSON(input, allowPartial);
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
if (repaired !== input)
|
|
58
|
+
return _parseJSON(repaired, allowPartial);
|
|
59
|
+
throw error;
|
|
60
|
+
}
|
|
47
61
|
}
|
|
62
|
+
const repairJSON = (input) => {
|
|
63
|
+
let repaired = "";
|
|
64
|
+
let quoted = false;
|
|
65
|
+
for (let index = 0; index < input.length; index++) {
|
|
66
|
+
const character = input[index];
|
|
67
|
+
if (!quoted) {
|
|
68
|
+
repaired += character;
|
|
69
|
+
if (character === '"')
|
|
70
|
+
quoted = true;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
if (character === '"') {
|
|
74
|
+
repaired += character;
|
|
75
|
+
quoted = false;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (character === "\\") {
|
|
79
|
+
const next = input[index + 1];
|
|
80
|
+
if (next === "u" && /^[0-9a-fA-F]{4}$/.test(input.slice(index + 2, index + 6))) {
|
|
81
|
+
repaired += input.slice(index, index + 6);
|
|
82
|
+
index += 5;
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
if (next !== undefined && '"\\/bfnrtu'.includes(next)) {
|
|
86
|
+
repaired += `\\${next}`;
|
|
87
|
+
index++;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
repaired += "\\\\";
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
const code = character.charCodeAt(0);
|
|
94
|
+
repaired += code <= 0x1f ? `\\u${code.toString(16).padStart(4, "0")}` : character;
|
|
95
|
+
}
|
|
96
|
+
return repaired;
|
|
97
|
+
};
|
|
48
98
|
const _parseJSON = (jsonString, allow) => {
|
|
49
99
|
const length = jsonString.length;
|
|
50
100
|
let index = 0;
|
|
@@ -138,7 +188,12 @@ const _parseJSON = (jsonString, allow) => {
|
|
|
138
188
|
skipBlank();
|
|
139
189
|
index++;
|
|
140
190
|
try {
|
|
141
|
-
object
|
|
191
|
+
Object.defineProperty(object, key, {
|
|
192
|
+
value: parseAny(),
|
|
193
|
+
enumerable: true,
|
|
194
|
+
configurable: true,
|
|
195
|
+
writable: true,
|
|
196
|
+
});
|
|
142
197
|
}
|
|
143
198
|
catch (error) {
|
|
144
199
|
if (Allow.OBJ & allow)
|
|
@@ -61,7 +61,7 @@ export declare const appendOrStart: <K extends StreamKey>(route: string, tools:
|
|
|
61
61
|
export declare const appendExisting: <K extends StreamKey>(route: string, tools: State<K>, key: K, text: string, missingToolMessage: string) => AppendOutcome<K> | AIError;
|
|
62
62
|
/**
|
|
63
63
|
* Finalize one pending tool call: parse the accumulated raw JSON, remove it
|
|
64
|
-
* from state, and
|
|
64
|
+
* from state, and recover incomplete local arguments when needed.
|
|
65
65
|
* Missing keys are a no-op because some providers emit stop events for
|
|
66
66
|
* non-tool content blocks.
|
|
67
67
|
*/
|
|
@@ -19,34 +19,28 @@ const inputStart = (tool) => LLMEvent.toolInputStart({
|
|
|
19
19
|
providerExecuted: tool.providerExecuted ? true : undefined,
|
|
20
20
|
providerMetadata: tool.providerMetadata,
|
|
21
21
|
});
|
|
22
|
-
const inputDelta = (tool, text) => {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
...(Option.isSome(input) ? { input: input.value } : {}),
|
|
29
|
-
});
|
|
30
|
-
};
|
|
22
|
+
const inputDelta = (tool, text) => LLMEvent.toolInputDelta({
|
|
23
|
+
id: tool.id,
|
|
24
|
+
name: tool.name,
|
|
25
|
+
text,
|
|
26
|
+
input: Option.getOrElse(parsePartialInput(tool.input), () => ({})),
|
|
27
|
+
});
|
|
31
28
|
const toolCall = (route, tool, inputOverride) => {
|
|
32
29
|
const raw = inputOverride ?? tool.input;
|
|
33
|
-
return parseToolInput(route, tool.name, raw).pipe(Effect.
|
|
30
|
+
return parseToolInput(route, tool.name, raw).pipe(Effect.catch((error) => tool.providerExecuted
|
|
31
|
+
? Effect.fail(error)
|
|
32
|
+
: Effect.succeed(Option.getOrElse(Option.map(parsePartialInput(raw), (input) => input ?? {}), () => ({})))), Effect.map((input) => LLMEvent.toolCall({
|
|
34
33
|
id: tool.id,
|
|
35
34
|
name: tool.name,
|
|
36
35
|
input,
|
|
37
36
|
providerExecuted: tool.providerExecuted ? true : undefined,
|
|
38
37
|
providerMetadata: tool.providerMetadata,
|
|
39
|
-
}))
|
|
40
|
-
? Effect.fail(error)
|
|
41
|
-
: Effect.succeed(LLMEvent.toolInputError({
|
|
42
|
-
id: tool.id,
|
|
43
|
-
name: tool.name,
|
|
44
|
-
raw,
|
|
45
|
-
}))));
|
|
38
|
+
})));
|
|
46
39
|
};
|
|
47
|
-
const finishEvents = (tool, event) =>
|
|
48
|
-
|
|
49
|
-
|
|
40
|
+
const finishEvents = (tool, event) => [
|
|
41
|
+
LLMEvent.toolInputEnd({ id: tool.id, name: tool.name, providerMetadata: tool.providerMetadata }),
|
|
42
|
+
event,
|
|
43
|
+
];
|
|
50
44
|
/** Store the updated tool and produce the optional public delta event. */
|
|
51
45
|
const appendTool = (tools, key, tool, text) => {
|
|
52
46
|
const events = [];
|
|
@@ -105,7 +99,7 @@ export const appendExisting = (route, tools, key, text, missingToolMessage) => {
|
|
|
105
99
|
};
|
|
106
100
|
/**
|
|
107
101
|
* Finalize one pending tool call: parse the accumulated raw JSON, remove it
|
|
108
|
-
* from state, and
|
|
102
|
+
* from state, and recover incomplete local arguments when needed.
|
|
109
103
|
* Missing keys are a no-op because some providers emit stop events for
|
|
110
104
|
* non-tool content blocks.
|
|
111
105
|
*/
|
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-18167",
|
|
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-18167",
|
|
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-18167",
|
|
43
43
|
"aws4fetch": "1.0.20",
|
|
44
44
|
"effect": "4.0.0-rc.111",
|
|
45
45
|
"google-auth-library": "10.5.0"
|