@lazyingart/agintiflow 0.20.9 → 0.20.11
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/package.json +1 -1
- package/scripts/smoke-model-roles.js +12 -0
- package/src/cli.js +6 -1
- package/src/model-client.js +67 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lazyingart/agintiflow",
|
|
3
|
-
"version": "0.20.
|
|
3
|
+
"version": "0.20.11",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "AgInTiFlow is a web-first coding agent and CLI with DeepSeek routing, sandboxed tools, model providers, canvas artifacts, and optional wrappers.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -150,6 +150,17 @@ assert(nativeMarkerText.length === 0, "native marker text should not be treated
|
|
|
150
150
|
const jsonBlockToolCalls = parseTextToolCalls('TOOL_CALLS:\n```json\n[{"name":"list_files","arguments":{"path":"/workspace"}}]\n```');
|
|
151
151
|
assert(jsonBlockToolCalls.length === 1, "Venice JSON text tool-call parser did not detect JSON block calls");
|
|
152
152
|
assert(jsonBlockToolCalls[0].function.arguments.includes("/workspace"), "Venice JSON text tool-call parser returned wrong arguments");
|
|
153
|
+
const requestedToolCalls = parseTextToolCalls(
|
|
154
|
+
'Requested tools: write_file({"path":"story-ja.txt","content":"雨の夜、彼女は「また会える」と笑った。","mode":"create"})'
|
|
155
|
+
);
|
|
156
|
+
assert(requestedToolCalls.length === 1, "Requested tools parser did not detect function-call text");
|
|
157
|
+
assert(requestedToolCalls[0].function.name === "write_file", "Requested tools parser returned wrong tool name");
|
|
158
|
+
assert(requestedToolCalls[0].function.arguments.includes("story-ja.txt"), "Requested tools parser returned wrong arguments");
|
|
159
|
+
const multipleRequestedToolCalls = parseTextToolCalls(
|
|
160
|
+
'Requested tools: list_files({"path":"."}); inspect_project({"path":".","maxDepth":2})'
|
|
161
|
+
);
|
|
162
|
+
assert(multipleRequestedToolCalls.length === 2, "Requested tools parser did not detect multiple function-call texts");
|
|
163
|
+
assert(multipleRequestedToolCalls[1].function.name === "inspect_project", "Requested tools parser returned wrong second requested tool");
|
|
153
164
|
assert(usesTextToolProtocol({ provider: "venice", model: "gemma-4-uncensored" }), "Venice Gemma should use text tool protocol");
|
|
154
165
|
assert(usesTextToolProtocol({ provider: "venice", model: "e2ee-venice-uncensored-24b-p" }), "Venice 1.1 should use text tool protocol");
|
|
155
166
|
assert(usesTextToolProtocol({ provider: "venice", model: "venice-uncensored" }), "Venice legacy 1.1 should use text tool protocol");
|
|
@@ -180,6 +191,7 @@ console.log(
|
|
|
180
191
|
"auxiliary-catalog",
|
|
181
192
|
"shared-model-selectors",
|
|
182
193
|
"venice-text-tool-parser",
|
|
194
|
+
"requested-tools-parser",
|
|
183
195
|
"cli-models-command",
|
|
184
196
|
"venice-shortcut",
|
|
185
197
|
],
|
package/src/cli.js
CHANGED
|
@@ -33,6 +33,11 @@ import { fileURLToPath } from "node:url";
|
|
|
33
33
|
const packageDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
34
34
|
const packageJson = JSON.parse(await fs.readFile(path.join(packageDir, "package.json"), "utf8"));
|
|
35
35
|
|
|
36
|
+
process.stdout.on("error", (error) => {
|
|
37
|
+
if (error?.code === "EPIPE") process.exit(0);
|
|
38
|
+
throw error;
|
|
39
|
+
});
|
|
40
|
+
|
|
36
41
|
function readOption(argv, index) {
|
|
37
42
|
const value = argv[index + 1];
|
|
38
43
|
if (!value || value.startsWith("--")) return "";
|
|
@@ -614,7 +619,7 @@ async function handleQueueCommand(argv) {
|
|
|
614
619
|
}
|
|
615
620
|
|
|
616
621
|
export async function main(argv = process.argv.slice(2)) {
|
|
617
|
-
if (argv[0] === "
|
|
622
|
+
if (argv[0] === "help" || argv.includes("--help") || argv.includes("-h")) {
|
|
618
623
|
printUsage();
|
|
619
624
|
return;
|
|
620
625
|
}
|
package/src/model-client.js
CHANGED
|
@@ -140,9 +140,10 @@ function messagesWithTextToolProtocol(config, messages, tools) {
|
|
|
140
140
|
|
|
141
141
|
export function parseTextToolCalls(content = "") {
|
|
142
142
|
const text = String(content || "");
|
|
143
|
-
if (!text.includes("[TOOL_CALLS]") && !/TOOL_CALLS\s*:/i.test(text)) return [];
|
|
143
|
+
if (!text.includes("[TOOL_CALLS]") && !/TOOL_CALLS\s*:/i.test(text) && !/Requested tools?\s*:/i.test(text)) return [];
|
|
144
144
|
|
|
145
145
|
const calls = [];
|
|
146
|
+
for (const call of parseRequestedToolCalls(text)) calls.push(call);
|
|
146
147
|
const jsonBlock = text.match(/TOOL_CALLS\s*:\s*```(?:json)?\s*([\s\S]*?)```/i);
|
|
147
148
|
if (jsonBlock?.[1]) {
|
|
148
149
|
try {
|
|
@@ -195,10 +196,75 @@ export function parseTextToolCalls(content = "") {
|
|
|
195
196
|
return calls;
|
|
196
197
|
}
|
|
197
198
|
|
|
199
|
+
function findMatchingParen(text = "", openIndex = 0) {
|
|
200
|
+
let depth = 0;
|
|
201
|
+
let quote = "";
|
|
202
|
+
let escaped = false;
|
|
203
|
+
for (let index = openIndex; index < text.length; index += 1) {
|
|
204
|
+
const char = text[index];
|
|
205
|
+
if (escaped) {
|
|
206
|
+
escaped = false;
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
if (quote) {
|
|
210
|
+
if (char === "\\") escaped = true;
|
|
211
|
+
else if (char === quote) quote = "";
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
if (char === '"' || char === "'") {
|
|
215
|
+
quote = char;
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
if (char === "(") depth += 1;
|
|
219
|
+
if (char === ")") {
|
|
220
|
+
depth -= 1;
|
|
221
|
+
if (depth === 0) return index;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
return -1;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
function parseRequestedToolCalls(content = "") {
|
|
228
|
+
const marker = String(content || "").match(/Requested tools?\s*:/i);
|
|
229
|
+
if (!marker) return [];
|
|
230
|
+
|
|
231
|
+
const text = String(content).slice(marker.index + marker[0].length);
|
|
232
|
+
const calls = [];
|
|
233
|
+
let offset = 0;
|
|
234
|
+
while (offset < text.length) {
|
|
235
|
+
const match = text.slice(offset).match(/([A-Za-z0-9_-]+)\s*\(/);
|
|
236
|
+
if (!match) break;
|
|
237
|
+
|
|
238
|
+
const name = match[1]?.trim();
|
|
239
|
+
const openIndex = offset + match.index + match[0].lastIndexOf("(");
|
|
240
|
+
const closeIndex = findMatchingParen(text, openIndex);
|
|
241
|
+
if (!name || closeIndex < 0) break;
|
|
242
|
+
|
|
243
|
+
const rawArgs = text.slice(openIndex + 1, closeIndex).trim() || "{}";
|
|
244
|
+
try {
|
|
245
|
+
JSON.parse(rawArgs);
|
|
246
|
+
} catch {
|
|
247
|
+
offset = closeIndex + 1;
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
calls.push({
|
|
251
|
+
id: `text-tool-${calls.length + 1}`,
|
|
252
|
+
type: "function",
|
|
253
|
+
function: {
|
|
254
|
+
name,
|
|
255
|
+
arguments: rawArgs,
|
|
256
|
+
},
|
|
257
|
+
});
|
|
258
|
+
offset = closeIndex + 1;
|
|
259
|
+
}
|
|
260
|
+
return calls;
|
|
261
|
+
}
|
|
262
|
+
|
|
198
263
|
function textBeforeToolCallMarker(content = "") {
|
|
199
264
|
return String(content || "")
|
|
200
265
|
.split("[TOOL_CALLS]")[0]
|
|
201
266
|
.split("TOOL_CALLS:")[0]
|
|
267
|
+
.split(/Requested tools?\s*:/i)[0]
|
|
202
268
|
.split("<|tool_call>")[0]
|
|
203
269
|
.trim();
|
|
204
270
|
}
|