@aexol/spectral 0.9.231 → 0.9.240
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 +47 -0
- package/dist/agent/index.d.ts +32 -5
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/index.js +209 -36
- package/dist/backend/generated-images.d.ts +1 -1
- package/dist/backend/generated-images.d.ts.map +1 -1
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +18 -4
- package/dist/commands/desktop.d.ts +167 -0
- package/dist/commands/desktop.d.ts.map +1 -0
- package/dist/commands/desktop.js +540 -0
- package/dist/commands/serve.d.ts +9 -1
- package/dist/commands/serve.d.ts.map +1 -1
- package/dist/commands/serve.js +90 -2
- package/dist/commands/update.d.ts +85 -5
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +288 -58
- package/dist/extensions/desktop-control/macos.d.ts.map +1 -1
- package/dist/extensions/desktop-control/macos.js +2 -2
- package/dist/extensions/logic-trace.d.ts +1 -1
- package/dist/extensions/logic-trace.d.ts.map +1 -1
- package/dist/extensions/logic-trace.js +199 -70
- package/dist/extensions/video-generation/index.d.ts +3 -0
- package/dist/extensions/video-generation/index.d.ts.map +1 -0
- package/dist/extensions/video-generation/index.js +299 -0
- package/dist/generated/zeus/const.d.ts.map +1 -1
- package/dist/generated/zeus/const.js +30 -0
- package/dist/generated/zeus/index.d.ts +140 -0
- package/dist/generated/zeus/index.d.ts.map +1 -1
- package/dist/generated/zeus/index.js +5 -0
- package/dist/mcp/server-manager.d.ts.map +1 -1
- package/dist/mcp/server-manager.js +6 -0
- package/dist/memory/tools/receive-agent-observations.d.ts.map +1 -1
- package/dist/memory/tools/receive-agent-observations.js +12 -2
- package/dist/relay/dispatcher.d.ts +13 -1
- package/dist/relay/dispatcher.d.ts.map +1 -1
- package/dist/relay/dispatcher.js +41 -2
- package/dist/sdk/agent-core/agent-loop.js +13 -3
- package/dist/sdk/agent-core/agent.d.ts +11 -4
- package/dist/sdk/agent-core/agent.d.ts.map +1 -1
- package/dist/sdk/agent-core/agent.js +16 -4
- package/dist/sdk/agent-core/tool-call-registry.d.ts +75 -0
- package/dist/sdk/agent-core/tool-call-registry.d.ts.map +1 -0
- package/dist/sdk/agent-core/tool-call-registry.js +131 -0
- package/dist/sdk/agent-core/tool-execution.d.ts.map +1 -1
- package/dist/sdk/agent-core/tool-execution.js +103 -4
- package/dist/sdk/agent-core/types.d.ts +15 -4
- package/dist/sdk/agent-core/types.d.ts.map +1 -1
- package/dist/sdk/ai/index.d.ts +3 -0
- package/dist/sdk/ai/index.d.ts.map +1 -1
- package/dist/sdk/ai/index.js +3 -0
- package/dist/sdk/ai/providers/faux.d.ts.map +1 -1
- package/dist/sdk/ai/providers/faux.js +3 -0
- package/dist/sdk/ai/providers/leaked-tool-call-parser.d.ts +39 -6
- package/dist/sdk/ai/providers/leaked-tool-call-parser.d.ts.map +1 -1
- package/dist/sdk/ai/providers/leaked-tool-call-parser.js +159 -18
- package/dist/sdk/ai/providers/openai-completions.d.ts.map +1 -1
- package/dist/sdk/ai/providers/openai-completions.js +22 -8
- package/dist/sdk/ai/providers/openrouter-videos.d.ts +3 -0
- package/dist/sdk/ai/providers/openrouter-videos.d.ts.map +1 -0
- package/dist/sdk/ai/providers/openrouter-videos.js +412 -0
- package/dist/sdk/ai/providers/register-builtins.d.ts.map +1 -1
- package/dist/sdk/ai/providers/register-builtins.js +6 -0
- package/dist/sdk/ai/providers/simple-options.d.ts +1 -6
- package/dist/sdk/ai/providers/simple-options.d.ts.map +1 -1
- package/dist/sdk/ai/providers/simple-options.js +0 -22
- package/dist/sdk/ai/providers/transform-messages.d.ts.map +1 -1
- package/dist/sdk/ai/providers/transform-messages.js +52 -1
- package/dist/sdk/ai/types.d.ts +91 -10
- package/dist/sdk/ai/types.d.ts.map +1 -1
- package/dist/sdk/ai/video-models.d.ts +10 -0
- package/dist/sdk/ai/video-models.d.ts.map +1 -0
- package/dist/sdk/ai/video-models.generated.d.ts +440 -0
- package/dist/sdk/ai/video-models.generated.d.ts.map +1 -0
- package/dist/sdk/ai/video-models.generated.js +441 -0
- package/dist/sdk/ai/video-models.js +22 -0
- package/dist/sdk/ai/videos-api-registry.d.ts +14 -0
- package/dist/sdk/ai/videos-api-registry.d.ts.map +1 -0
- package/dist/sdk/ai/videos-api-registry.js +21 -0
- package/dist/sdk/ai/videos.d.ts +4 -0
- package/dist/sdk/ai/videos.d.ts.map +1 -0
- package/dist/sdk/ai/videos.js +13 -0
- package/dist/sdk/coding-agent/core/agent-session.d.ts +8 -0
- package/dist/sdk/coding-agent/core/agent-session.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/agent-session.js +11 -0
- package/dist/sdk/coding-agent/core/extensions/loader.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/extensions/loader.js +14 -0
- package/dist/sdk/coding-agent/core/extensions/native-extensions.d.ts +26 -0
- package/dist/sdk/coding-agent/core/extensions/native-extensions.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/extensions/native-extensions.js +23 -0
- package/dist/sdk/coding-agent/core/extensions/session-events.d.ts +2 -2
- package/dist/sdk/coding-agent/core/extensions/session-events.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/extensions/types.d.ts +12 -2
- package/dist/sdk/coding-agent/core/extensions/types.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/messages.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/messages.js +42 -2
- package/dist/sdk/coding-agent/core/resource-loader.d.ts +11 -0
- package/dist/sdk/coding-agent/core/resource-loader.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/resource-loader.js +23 -6
- package/dist/sdk/coding-agent/core/sdk.d.ts +24 -2
- package/dist/sdk/coding-agent/core/sdk.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/sdk.js +15 -3
- package/dist/sdk/coding-agent/core/settings-manager.d.ts +0 -8
- package/dist/sdk/coding-agent/core/settings-manager.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/settings-manager.js +3 -3
- package/dist/sdk/coding-agent/core/system-prompt.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/system-prompt.js +5 -0
- package/dist/sdk/coding-agent/index.d.ts +2 -2
- package/dist/sdk/coding-agent/index.d.ts.map +1 -1
- package/dist/sdk/coding-agent/index.js +1 -1
- package/dist/sdk-public.d.ts +96 -0
- package/dist/sdk-public.d.ts.map +1 -0
- package/dist/sdk-public.js +109 -0
- package/dist/server/agent-bridge/rehydrate.d.ts +2 -2
- package/dist/server/agent-bridge/rehydrate.d.ts.map +1 -1
- package/dist/server/agent-bridge/rehydrate.js +14 -0
- package/dist/server/agent-bridge/tps-metrics.d.ts +34 -0
- package/dist/server/agent-bridge/tps-metrics.d.ts.map +1 -1
- package/dist/server/agent-bridge/tps-metrics.js +22 -0
- package/dist/server/agent-bridge.d.ts +17 -2
- package/dist/server/agent-bridge.d.ts.map +1 -1
- package/dist/server/agent-bridge.js +108 -5
- package/dist/server/handlers/paths-list.d.ts +1 -1
- package/dist/server/handlers/paths-list.js +1 -1
- package/dist/server/inter-agent-broker.d.ts +12 -0
- package/dist/server/inter-agent-broker.d.ts.map +1 -1
- package/dist/server/inter-agent-broker.js +1 -0
- package/dist/server/preset-chain.d.ts +151 -0
- package/dist/server/preset-chain.d.ts.map +1 -0
- package/dist/server/preset-chain.js +250 -0
- package/dist/server/session-stream.d.ts +74 -1
- package/dist/server/session-stream.d.ts.map +1 -1
- package/dist/server/session-stream.js +238 -24
- package/dist/server/storage/rows.d.ts +2 -0
- package/dist/server/storage/rows.d.ts.map +1 -1
- package/dist/server/storage/schema.d.ts +2 -2
- package/dist/server/storage/schema.d.ts.map +1 -1
- package/dist/server/storage/schema.js +2 -1
- package/dist/server/storage.d.ts +7 -0
- package/dist/server/storage.d.ts.map +1 -1
- package/dist/server/storage.js +142 -9
- package/dist/server/wire.d.ts +84 -0
- package/dist/server/wire.d.ts.map +1 -1
- package/dist/utils/augment-path.d.ts +51 -0
- package/dist/utils/augment-path.d.ts.map +1 -0
- package/dist/utils/augment-path.js +234 -0
- package/dist/utils/open-browser.d.ts +55 -0
- package/dist/utils/open-browser.d.ts.map +1 -0
- package/dist/utils/open-browser.js +163 -0
- package/dist/utils/serve-state.d.ts +264 -0
- package/dist/utils/serve-state.d.ts.map +1 -0
- package/dist/utils/serve-state.js +563 -0
- package/dist/utils/standalone.d.ts +14 -0
- package/dist/utils/standalone.d.ts.map +1 -0
- package/dist/utils/standalone.js +23 -0
- package/package.json +7 -3
|
@@ -15,6 +15,12 @@
|
|
|
15
15
|
* where the wrapper tag is `function_calls` (optionally with an `antml:`
|
|
16
16
|
* namespace prefix) and invoke/parameter tags follow the same convention.
|
|
17
17
|
*
|
|
18
|
+
* Models also emit the same markup WITHOUT the wrapper — orphan
|
|
19
|
+
* `<invoke name="x">…</invoke>` blocks straight in prose (pi-style) — or
|
|
20
|
+
* truncated blocks that never receive their closing tags before the stream
|
|
21
|
+
* ends. Both shapes are recovered: orphan blocks during streaming, truncated
|
|
22
|
+
* parameter-complete tails at end of stream (see salvageLeakedToolCallTail).
|
|
23
|
+
*
|
|
18
24
|
* Everything here is pure string logic — no provider imports — so the tests
|
|
19
25
|
* cover it without any streaming harness.
|
|
20
26
|
*/
|
|
@@ -22,16 +28,52 @@
|
|
|
22
28
|
const NS = "(?:antml:)?";
|
|
23
29
|
const INVOKE_RE = new RegExp(`<${NS}invoke\\s+name="([^"]*)"\\s*>([\\s\\S]*?)</${NS}invoke\\s*>`, "g");
|
|
24
30
|
const PARAMETER_RE = new RegExp(`<${NS}parameter\\s+name="([^"]*)"\\s*>([\\s\\S]*?)</${NS}parameter\\s*>`, "g");
|
|
31
|
+
const INVOKE_OPEN_RE = new RegExp(`<${NS}invoke\\s+name="([^"]*)"\\s*>`, "g");
|
|
32
|
+
const INVOKE_CLOSE_RE = new RegExp(`</${NS}invoke\\s*>`, "g");
|
|
33
|
+
const PARAMETER_OPEN_RE = new RegExp(`<${NS}parameter\\s+name="[^"]*"\\s*>`, "g");
|
|
25
34
|
const WRAPPER_OPEN_RE = /<(?:antml:)?function_calls\s*>/;
|
|
26
35
|
const WRAPPER_CLOSE = /<\/(?:antml:)?function_calls\s*>/;
|
|
27
|
-
/**
|
|
36
|
+
/**
|
|
37
|
+
* Floor for how much tail a caller should expect a partial opener to occupy
|
|
38
|
+
* (the longest opener tag is the antml-prefixed one, 22 chars, plus margin).
|
|
39
|
+
* Partial detection anchors at the last `<` of the buffered text, so an
|
|
40
|
+
* invoke opener whose name attribute is still open can hold back more than
|
|
41
|
+
* this when the tool name is long — it is a floor, not a cap.
|
|
42
|
+
*/
|
|
28
43
|
export const LEAK_TAIL_LENGTH = 32;
|
|
29
44
|
const OPENER_PREFIXES = ["<function_calls", "<antml:function_calls"];
|
|
45
|
+
const INVOKE_OPENER_PREFIXES = ['<invoke name="', '<antml:invoke name="'];
|
|
46
|
+
const escapeRegExp = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
47
|
+
/**
|
|
48
|
+
* A buffered tail that could still grow into a leaked opener, matched
|
|
49
|
+
* (anchored) against everything from the last `<` of the buffered text:
|
|
50
|
+
* - any prefix of a wrapper/invoke opener literal, from a bare `<` up to the
|
|
51
|
+
* full declared prefix (`<function_ca`, `<invoke name="`),
|
|
52
|
+
* - an invoke opener whose double-quoted name attribute is still open
|
|
53
|
+
* (`<invoke name="bash` — the closing `">` has not arrived), however long
|
|
54
|
+
* the name is.
|
|
55
|
+
* Single-quoted names and attribute-less `<invoke>` tags never match, so
|
|
56
|
+
* ordinary prose (`a < b`, `Array<string>`) stays out of the buffer.
|
|
57
|
+
*/
|
|
58
|
+
const PARTIAL_TAIL_RE = new RegExp(`^(?:${[
|
|
59
|
+
...[...OPENER_PREFIXES, ...INVOKE_OPENER_PREFIXES].flatMap((opener) => {
|
|
60
|
+
const prefixes = [];
|
|
61
|
+
for (let size = 1; size <= opener.length; size++) {
|
|
62
|
+
prefixes.push(escapeRegExp(opener.slice(0, size)));
|
|
63
|
+
}
|
|
64
|
+
return prefixes;
|
|
65
|
+
}),
|
|
66
|
+
'<(?:antml:)?invoke\\s+name="[^">]*',
|
|
67
|
+
].join("|")})$`);
|
|
30
68
|
/**
|
|
31
|
-
* Locate a leaked
|
|
69
|
+
* Locate a leaked opener tag in `text` — either the wrapper
|
|
70
|
+
* (`<function_calls>`) or an orphan invoke (`<invoke name="x">`, pi-style
|
|
71
|
+
* markup emitted without the wrapper).
|
|
32
72
|
* - "full": a complete opener tag exists; `index` points at its `<`.
|
|
33
|
-
* - "partial": the text ENDS
|
|
34
|
-
*
|
|
73
|
+
* - "partial": the text ENDS mid-opener (an opener split across streaming
|
|
74
|
+
* deltas); `index` points at the start of that tail. A partial always
|
|
75
|
+
* starts at the last `<` — the tail matcher admits no further `<` — so the
|
|
76
|
+
* scan is a single anchored match there instead of a prefix enumeration.
|
|
35
77
|
* - "none": no opener, complete or partial.
|
|
36
78
|
*/
|
|
37
79
|
export function findLeakedToolCallOpener(text) {
|
|
@@ -46,19 +88,16 @@ export function findLeakedToolCallOpener(text) {
|
|
|
46
88
|
best = { match: "full", index: m.index };
|
|
47
89
|
}
|
|
48
90
|
}
|
|
91
|
+
for (const m of text.matchAll(INVOKE_OPEN_RE)) {
|
|
92
|
+
if (best.match !== "full" || m.index < best.index) {
|
|
93
|
+
best = { match: "full", index: m.index };
|
|
94
|
+
}
|
|
95
|
+
}
|
|
49
96
|
if (best.match === "full")
|
|
50
97
|
return best;
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if (text.endsWith(opener.slice(0, size))) {
|
|
55
|
-
const index = text.length - size;
|
|
56
|
-
if (best.match === "none" || index < best.index) {
|
|
57
|
-
best = { match: "partial", index };
|
|
58
|
-
}
|
|
59
|
-
break;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
98
|
+
const lastLt = text.lastIndexOf("<");
|
|
99
|
+
if (lastLt >= 0 && PARTIAL_TAIL_RE.test(text.slice(lastLt))) {
|
|
100
|
+
best = { match: "partial", index: lastLt };
|
|
62
101
|
}
|
|
63
102
|
return best;
|
|
64
103
|
}
|
|
@@ -71,13 +110,17 @@ export function findLeakedToolCallOpener(text) {
|
|
|
71
110
|
* before + after). `consumed` is the raw block text (opener→closer
|
|
72
111
|
* inclusive) so callers can fall back to emitting it as text when the
|
|
73
112
|
* parsed tool names turn out to be unknown.
|
|
74
|
-
*
|
|
75
|
-
*
|
|
113
|
+
* When no wrapper opener exists at all, orphan invoke blocks (pi-style, no
|
|
114
|
+
* wrapper) are parsed instead — but only when EVERY invoke opener has a
|
|
115
|
+
* matching closer; otherwise `complete: false` and `remaining`/`consumed`
|
|
116
|
+
* echo the input so nothing is cut prematurely. (A wrapper opener blocks the
|
|
117
|
+
* orphan path: wrapper-less invokes around a wrapper block are picked up
|
|
118
|
+
* later from `remaining`, once the wrapper block itself is consumed.)
|
|
76
119
|
*/
|
|
77
120
|
export function extractLeakedToolCalls(text) {
|
|
78
121
|
const openMatch = WRAPPER_OPEN_RE.exec(text);
|
|
79
122
|
if (!openMatch) {
|
|
80
|
-
return
|
|
123
|
+
return extractOrphanInvokes(text);
|
|
81
124
|
}
|
|
82
125
|
const openStart = openMatch.index;
|
|
83
126
|
const bodyStart = openStart + openMatch[0].length;
|
|
@@ -112,6 +155,104 @@ export function extractLeakedToolCalls(text) {
|
|
|
112
155
|
remaining: text.slice(0, openStart) + text.slice(closeEnd + 1),
|
|
113
156
|
};
|
|
114
157
|
}
|
|
158
|
+
/**
|
|
159
|
+
* Orphan invoke blocks: pi-style markup without any wrapper tag. Complete
|
|
160
|
+
* only when EVERY invoke opener has a matching closer; otherwise nothing is
|
|
161
|
+
* cut and the caller keeps buffering. `consumed` spans the first opener
|
|
162
|
+
* through the last closer (prose between invokes inside the parsed region is
|
|
163
|
+
* dropped, mirroring the wrapper path) and `remaining` echoes the prose
|
|
164
|
+
* before and after.
|
|
165
|
+
*/
|
|
166
|
+
function extractOrphanInvokes(text) {
|
|
167
|
+
const opens = [...text.matchAll(INVOKE_OPEN_RE)];
|
|
168
|
+
if (opens.length === 0) {
|
|
169
|
+
return { calls: [], complete: false, remaining: text, consumed: "" };
|
|
170
|
+
}
|
|
171
|
+
const closes = [...text.matchAll(INVOKE_CLOSE_RE)];
|
|
172
|
+
let closerPtr = 0;
|
|
173
|
+
const calls = [];
|
|
174
|
+
let firstOpen = -1;
|
|
175
|
+
let lastCloseEnd = -1;
|
|
176
|
+
for (const open of opens) {
|
|
177
|
+
const openStart = open.index;
|
|
178
|
+
if (firstOpen === -1)
|
|
179
|
+
firstOpen = openStart;
|
|
180
|
+
while (closerPtr < closes.length && closes[closerPtr].index < openStart) {
|
|
181
|
+
closerPtr++;
|
|
182
|
+
}
|
|
183
|
+
const closer = closes[closerPtr];
|
|
184
|
+
if (!closer) {
|
|
185
|
+
return { calls: [], complete: false, remaining: text, consumed: "" };
|
|
186
|
+
}
|
|
187
|
+
const body = text.slice(openStart + open[0].length, closer.index);
|
|
188
|
+
const args = {};
|
|
189
|
+
for (const p of body.matchAll(PARAMETER_RE)) {
|
|
190
|
+
args[p[1]] = p[2].trim();
|
|
191
|
+
}
|
|
192
|
+
calls.push({ name: open[1], args });
|
|
193
|
+
closerPtr++;
|
|
194
|
+
lastCloseEnd = closer.index + closer[0].length;
|
|
195
|
+
}
|
|
196
|
+
return {
|
|
197
|
+
calls,
|
|
198
|
+
complete: true,
|
|
199
|
+
consumed: text.slice(firstOpen, lastCloseEnd),
|
|
200
|
+
remaining: text.slice(0, firstOpen) + text.slice(lastCloseEnd),
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* End-of-stream recovery for a leaked buffer that never received its closing
|
|
205
|
+
* tags (stream cut off, or a model that forgets `</invoke>` / the wrapper
|
|
206
|
+
* closer). Parses invoke blocks tolerantly: a missing closer is fine as long
|
|
207
|
+
* as every `<parameter>` value is fully closed. A truncated parameter value
|
|
208
|
+
* means the model was cut mid-argument — guessing at the value is unsafe, so
|
|
209
|
+
* the whole tail degrades to plain text (null).
|
|
210
|
+
*
|
|
211
|
+
* Returns the parsed calls (leading wrapper skeleton dropped), or null when
|
|
212
|
+
* nothing salvageable remains. Callers still validate tool names before
|
|
213
|
+
* emitting synthetic tool calls.
|
|
214
|
+
*/
|
|
215
|
+
export function salvageLeakedToolCallTail(text) {
|
|
216
|
+
const opens = [...text.matchAll(INVOKE_OPEN_RE)];
|
|
217
|
+
if (opens.length === 0)
|
|
218
|
+
return null;
|
|
219
|
+
const closes = [...text.matchAll(INVOKE_CLOSE_RE)];
|
|
220
|
+
const calls = [];
|
|
221
|
+
let closerPtr = 0;
|
|
222
|
+
for (let i = 0; i < opens.length; i++) {
|
|
223
|
+
const open = opens[i];
|
|
224
|
+
const openStart = open.index;
|
|
225
|
+
while (closerPtr < closes.length && closes[closerPtr].index < openStart) {
|
|
226
|
+
closerPtr++;
|
|
227
|
+
}
|
|
228
|
+
const closer = closes[closerPtr];
|
|
229
|
+
const nextOpen = opens[i + 1];
|
|
230
|
+
let bodyEnd;
|
|
231
|
+
if (closer && (!nextOpen || closer.index < nextOpen.index)) {
|
|
232
|
+
bodyEnd = closer.index;
|
|
233
|
+
closerPtr++;
|
|
234
|
+
}
|
|
235
|
+
else if (nextOpen) {
|
|
236
|
+
// Unclosed invoke whose body runs up to the next opener.
|
|
237
|
+
bodyEnd = nextOpen.index;
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
bodyEnd = text.length;
|
|
241
|
+
}
|
|
242
|
+
const body = text.slice(openStart + open[0].length, bodyEnd);
|
|
243
|
+
const args = {};
|
|
244
|
+
for (const p of body.matchAll(PARAMETER_RE)) {
|
|
245
|
+
args[p[1]] = p[2].trim();
|
|
246
|
+
}
|
|
247
|
+
const paramOpeners = [...body.matchAll(PARAMETER_OPEN_RE)];
|
|
248
|
+
if (paramOpeners.length > 0 &&
|
|
249
|
+
paramOpeners.length !== [...body.matchAll(PARAMETER_RE)].length) {
|
|
250
|
+
return null;
|
|
251
|
+
}
|
|
252
|
+
calls.push({ name: open[1], args });
|
|
253
|
+
}
|
|
254
|
+
return calls;
|
|
255
|
+
}
|
|
115
256
|
/**
|
|
116
257
|
* Coerce a leaked parameter string into a JSON value when it clearly parses
|
|
117
258
|
* as one — native `tool_calls` arguments are real JSON, so a leaked
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai-completions.d.ts","sourceRoot":"","sources":["../../../../src/sdk/ai/providers/openai-completions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"openai-completions.d.ts","sourceRoot":"","sources":["../../../../src/sdk/ai/providers/openai-completions.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAMX,0BAA0B,EAE1B,MAAM,sCAAsC,CAAC;AAI9C,OAAO,KAAK,EAGX,OAAO,EAGP,KAAK,EACL,uBAAuB,EACvB,mBAAmB,EAEnB,cAAc,EACd,aAAa,EAMb,MAAM,aAAa,CAAC;AA+FrB,MAAM,WAAW,wBAAyB,SAAQ,aAAa;IAC9D,UAAU,CAAC,EACR,MAAM,GACN,MAAM,GACN,UAAU,GACV;QAAE,IAAI,EAAE,UAAU,CAAC;QAAC,QAAQ,EAAE;YAAE,IAAI,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC;IACpD,eAAe,CAAC,EAAE,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;CAClE;AAED,KAAK,+BAA+B,GAAG,QAAQ,CAAC,uBAAuB,CAAC,CAAC;AAuBzE,eAAO,MAAM,uBAAuB,EAAE,cAAc,CACnD,oBAAoB,EACpB,wBAAwB,CAumBxB,CAAC;AAEF,eAAO,MAAM,6BAA6B,EAAE,cAAc,CACzD,oBAAoB,EACpB,mBAAmB,CAyBnB,CAAC;AAkNF,wBAAgB,eAAe,CAC9B,KAAK,EAAE,KAAK,CAAC,oBAAoB,CAAC,EAClC,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,+BAA+B,GACrC,0BAA0B,EAAE,CA0R9B"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import OpenAI from "openai";
|
|
2
|
-
import { coerceLeakedParameterValue, extractLeakedToolCalls, findLeakedToolCallOpener, } from "./leaked-tool-call-parser.js";
|
|
2
|
+
import { coerceLeakedParameterValue, extractLeakedToolCalls, findLeakedToolCallOpener, salvageLeakedToolCallTail, } from "./leaked-tool-call-parser.js";
|
|
3
3
|
import { backendHostedImageResolver } from "../utils/hosted-image-resolver.js";
|
|
4
4
|
import { getApiUrl, readConfig } from "../../../config.js";
|
|
5
5
|
import { getEnvApiKey } from "../env-api-keys.js";
|
|
@@ -179,9 +179,11 @@ export const streamOpenAICompletions = (model, context, options) => {
|
|
|
179
179
|
let inlineThinkingPending = "";
|
|
180
180
|
let inInlineThinking = false;
|
|
181
181
|
// Leaked tool-call XML: some OpenRouter models emit antml-style
|
|
182
|
-
// markup in plain content instead of native tool_calls
|
|
183
|
-
//
|
|
184
|
-
//
|
|
182
|
+
// markup in plain content instead of native tool_calls — either a
|
|
183
|
+
// wrapper block or orphan pi-style invoke blocks with no wrapper
|
|
184
|
+
// at all. Text is buffered here until a complete block arrives,
|
|
185
|
+
// then parsed into real toolCall blocks (see
|
|
186
|
+
// leaked-tool-call-parser.ts).
|
|
185
187
|
let leakMode = false;
|
|
186
188
|
let leakBuffer = "";
|
|
187
189
|
let leakPending = "";
|
|
@@ -548,11 +550,23 @@ export const streamOpenAICompletions = (model, context, options) => {
|
|
|
548
550
|
}
|
|
549
551
|
inlineThinkingPending = "";
|
|
550
552
|
}
|
|
551
|
-
// Flush leak buffers. A never-closed block is
|
|
552
|
-
//
|
|
553
|
-
//
|
|
553
|
+
// Flush leak buffers. A never-closed block is first offered to the
|
|
554
|
+
// end-of-stream salvage (models that were cut off after emitting
|
|
555
|
+
// complete parameter values); whatever it cannot recover is emitted
|
|
556
|
+
// as plain text (graceful degradation) so no content is lost. A
|
|
557
|
+
// held-back tail without an opener is just prose.
|
|
554
558
|
if (leakMode && leakBuffer) {
|
|
555
|
-
|
|
559
|
+
const salvaged = salvageLeakedToolCallTail(leakBuffer);
|
|
560
|
+
if (salvaged &&
|
|
561
|
+
salvaged.length > 0 &&
|
|
562
|
+
salvaged.every((call) => availableToolNames.has(call.name))) {
|
|
563
|
+
for (const call of salvaged)
|
|
564
|
+
emitSyntheticToolCall(call);
|
|
565
|
+
emittedLeakedToolCalls = true;
|
|
566
|
+
}
|
|
567
|
+
else {
|
|
568
|
+
emitTextDelta(leakBuffer);
|
|
569
|
+
}
|
|
556
570
|
leakBuffer = "";
|
|
557
571
|
leakMode = false;
|
|
558
572
|
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { ProviderVideosOptions, VideosContext, VideosModel, VideosResult } from "../types.js";
|
|
2
|
+
export declare function generateOpenRouterVideos(model: VideosModel<"openrouter-videos">, context: VideosContext, options?: ProviderVideosOptions): Promise<VideosResult>;
|
|
3
|
+
//# sourceMappingURL=openrouter-videos.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openrouter-videos.d.ts","sourceRoot":"","sources":["../../../../src/sdk/ai/providers/openrouter-videos.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEX,qBAAqB,EAIrB,aAAa,EACb,WAAW,EACX,YAAY,EACZ,MAAM,aAAa,CAAC;AAgarB,wBAAsB,wBAAwB,CAC7C,KAAK,EAAE,WAAW,CAAC,mBAAmB,CAAC,EACvC,OAAO,EAAE,aAAa,EACtB,OAAO,GAAE,qBAA0B,GACjC,OAAO,CAAC,YAAY,CAAC,CAkCvB"}
|