@lazyingart/agintiflow 0.20.260 → 0.20.262
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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lazyingart/agintiflow",
|
|
3
|
-
"version": "0.20.
|
|
3
|
+
"version": "0.20.262",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "AgInTiFlow is a project-aware agent workspace for hybrid wet-dry R&D, hardware-aware intelligence, software automation, and industrial workflows.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -175,13 +175,108 @@ async function main() {
|
|
|
175
175
|
toolChoiceForProvider(
|
|
176
176
|
{ provider: "deepseek" },
|
|
177
177
|
[{ role: "user", content: "Emit exactly one enabled tool call that performs the next concrete action." }]
|
|
178
|
+
) === "required",
|
|
179
|
+
"DeepSeek action recovery did not require a tool call"
|
|
180
|
+
);
|
|
181
|
+
assert(
|
|
182
|
+
JSON.stringify(toolChoiceForProvider(
|
|
183
|
+
{ provider: "deepseek" },
|
|
184
|
+
[{ role: "user", content: "Emit exactly one enabled tool call that performs the next concrete action." }],
|
|
185
|
+
[
|
|
186
|
+
{ type: "function", function: { name: "apply_patch" } },
|
|
187
|
+
{ type: "function", function: { name: "finish" } },
|
|
188
|
+
]
|
|
189
|
+
)) === JSON.stringify({ type: "function", function: { name: "apply_patch" } }),
|
|
190
|
+
"DeepSeek action recovery did not force the only executable tool"
|
|
191
|
+
);
|
|
192
|
+
assert(
|
|
193
|
+
JSON.stringify(toolChoiceForProvider(
|
|
194
|
+
{ provider: "deepseek", completionFreshMutationRequired: true },
|
|
195
|
+
[{ role: "user", content: "Repair the retained source from the exact failure evidence." }],
|
|
196
|
+
[
|
|
197
|
+
{ type: "function", function: { name: "apply_patch" } },
|
|
198
|
+
{ type: "function", function: { name: "finish" } },
|
|
199
|
+
]
|
|
200
|
+
)) === JSON.stringify({ type: "function", function: { name: "apply_patch" } }),
|
|
201
|
+
"DeepSeek constrained recovery relied on a prompt phrase instead of the offered tool contract"
|
|
202
|
+
);
|
|
203
|
+
assert(
|
|
204
|
+
toolChoiceForProvider(
|
|
205
|
+
{ provider: "deepseek" },
|
|
206
|
+
[{ role: "user", content: "Explain what this source does." }],
|
|
207
|
+
[
|
|
208
|
+
{ type: "function", function: { name: "read_file" } },
|
|
209
|
+
{ type: "function", function: { name: "finish" } },
|
|
210
|
+
]
|
|
178
211
|
) === "auto",
|
|
179
|
-
"DeepSeek
|
|
212
|
+
"DeepSeek ordinary chat forced a tool merely because few tools were enabled"
|
|
180
213
|
);
|
|
181
214
|
assert(
|
|
182
215
|
JSON.stringify(providerStructuredOutputAttempts("deepseek")) === JSON.stringify(["json_object", "prompt"]),
|
|
183
216
|
"DeepSeek structured extraction still probes an unsupported JSON Schema mode"
|
|
184
217
|
);
|
|
218
|
+
let deepSeekActionPayload = null;
|
|
219
|
+
await requestNextStep(
|
|
220
|
+
{
|
|
221
|
+
chat: {
|
|
222
|
+
completions: {
|
|
223
|
+
create: async (payload) => {
|
|
224
|
+
deepSeekActionPayload = payload;
|
|
225
|
+
return {
|
|
226
|
+
choices: [{
|
|
227
|
+
message: {
|
|
228
|
+
role: "assistant",
|
|
229
|
+
content: "",
|
|
230
|
+
tool_calls: [{
|
|
231
|
+
id: "deepseek-action-patch",
|
|
232
|
+
type: "function",
|
|
233
|
+
function: {
|
|
234
|
+
name: "apply_patch",
|
|
235
|
+
arguments: JSON.stringify({
|
|
236
|
+
path: "service.py",
|
|
237
|
+
search: "old",
|
|
238
|
+
replace: "new",
|
|
239
|
+
expectedReplacements: 1,
|
|
240
|
+
}),
|
|
241
|
+
},
|
|
242
|
+
}],
|
|
243
|
+
},
|
|
244
|
+
}],
|
|
245
|
+
};
|
|
246
|
+
},
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
provider: "deepseek",
|
|
252
|
+
model: "deepseek-v4-pro",
|
|
253
|
+
reasoning: "xhigh",
|
|
254
|
+
goal: "Repair service.py from exact retained source.",
|
|
255
|
+
taskProfile: "code",
|
|
256
|
+
allowFileTools: true,
|
|
257
|
+
allowShellTool: false,
|
|
258
|
+
allowWebSearch: false,
|
|
259
|
+
allowMcpTools: false,
|
|
260
|
+
allowWrapperTools: false,
|
|
261
|
+
allowAuxiliaryTools: false,
|
|
262
|
+
completionFreshMutationRequired: true,
|
|
263
|
+
completionFreshMutationNeedsSourceRead: false,
|
|
264
|
+
completionFreshMutationPaths: ["service.py"],
|
|
265
|
+
},
|
|
266
|
+
[{ role: "user", content: "Repair the retained source from the exact failure evidence." }]
|
|
267
|
+
);
|
|
268
|
+
assert(
|
|
269
|
+
deepSeekActionPayload?.thinking?.type === "disabled",
|
|
270
|
+
"DeepSeek reasoning-only recovery did not disable a second expensive thinking pass"
|
|
271
|
+
);
|
|
272
|
+
assert(
|
|
273
|
+
deepSeekActionPayload?.tool_choice?.function?.name === "apply_patch",
|
|
274
|
+
"DeepSeek reasoning-only recovery did not force its single executable tool"
|
|
275
|
+
);
|
|
276
|
+
assert(
|
|
277
|
+
!Object.hasOwn(deepSeekActionPayload || {}, "reasoning_effort"),
|
|
278
|
+
"DeepSeek action-only recovery sent a conflicting reasoning effort"
|
|
279
|
+
);
|
|
185
280
|
|
|
186
281
|
assert(!isPublicWebUrl("http://127.0.0.1/private"), "public URL guard accepted loopback");
|
|
187
282
|
assert(!isPublicWebUrl("http://10.0.0.1/private"), "public URL guard accepted RFC1918 address");
|
|
@@ -705,6 +705,24 @@ try {
|
|
|
705
705
|
tracebackPacket.content.includes("### tests/test_traceback_packet.py"),
|
|
706
706
|
"exact same-workspace test files named by a traceback were omitted when discovery metadata was empty"
|
|
707
707
|
);
|
|
708
|
+
const repeatedTracebackPacketState = structuredClone(tracebackPacketState);
|
|
709
|
+
repeatedTracebackPacketState.meta.projectVerification.testRuns[0].failureSignature =
|
|
710
|
+
"repeated-validator-traceback-file-recovery";
|
|
711
|
+
repeatedTracebackPacketState.meta.projectVerification.testRuns[0].failureSummary =
|
|
712
|
+
[
|
|
713
|
+
`File "${path.join(workspace, "duplicate-source.py")}", line 1, in first`,
|
|
714
|
+
`File "${path.join(workspace, "duplicate-source.py")}", line 2, in second`,
|
|
715
|
+
`File "${path.join(workspace, "duplicate-source.py")}", line 3, in third`,
|
|
716
|
+
`File "${path.join(workspace, "tests", "test_traceback_packet.py")}", line 4, in test_contract`,
|
|
717
|
+
].join("\n");
|
|
718
|
+
const repeatedTracebackPacket = await buildFailedTestRecoveryPacket(
|
|
719
|
+
{ commandCwd: workspace },
|
|
720
|
+
repeatedTracebackPacketState
|
|
721
|
+
);
|
|
722
|
+
assert(
|
|
723
|
+
repeatedTracebackPacket.paths.includes("tests/test_traceback_packet.py"),
|
|
724
|
+
"duplicate frames from one validator crowded the actual failing test out of recovery evidence"
|
|
725
|
+
);
|
|
708
726
|
assert(
|
|
709
727
|
(await failedTestRepairPatchBlock(
|
|
710
728
|
duplicateRepairState,
|
package/src/agent-runner.js
CHANGED
|
@@ -4777,8 +4777,8 @@ async function failedTestTracebackSourceDocuments(testRun = {}, config = {}) {
|
|
|
4777
4777
|
? path.resolve(reportedPath)
|
|
4778
4778
|
: path.resolve(commandCwd, reportedPath);
|
|
4779
4779
|
const line = Math.max(1, Number(match[2] || 1));
|
|
4780
|
-
if (seen.has(
|
|
4781
|
-
seen.add(
|
|
4780
|
+
if (seen.has(absolutePath)) continue;
|
|
4781
|
+
seen.add(absolutePath);
|
|
4782
4782
|
const insideWorkspace =
|
|
4783
4783
|
absolutePath === commandCwd || absolutePath.startsWith(`${commandCwd}${path.sep}`);
|
|
4784
4784
|
const namedByCommand = command.includes(absolutePath);
|
|
@@ -4797,7 +4797,7 @@ async function failedTestTracebackSourceDocuments(testRun = {}, config = {}) {
|
|
|
4797
4797
|
const raw = await fs.readFile(absolutePath, "utf8").catch(() => "");
|
|
4798
4798
|
if (!raw) continue;
|
|
4799
4799
|
documents.push({ absolutePath, line, raw });
|
|
4800
|
-
if (documents.length >=
|
|
4800
|
+
if (documents.length >= 5) break;
|
|
4801
4801
|
}
|
|
4802
4802
|
return documents;
|
|
4803
4803
|
}
|
package/src/model-client.js
CHANGED
|
@@ -134,6 +134,10 @@ function chatReasoningEffort(config = {}) {
|
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
function withChatReasoningEffort(payload = {}, config = {}) {
|
|
137
|
+
if (payload.thinking?.type === "disabled") {
|
|
138
|
+
const { reasoning_effort: _reasoningEffort, ...rest } = payload;
|
|
139
|
+
return rest;
|
|
140
|
+
}
|
|
137
141
|
const reasoning = chatReasoningEffort(config);
|
|
138
142
|
if (!reasoning) {
|
|
139
143
|
const { reasoning_effort: _reasoningEffort, ...rest } = payload;
|
|
@@ -336,17 +340,58 @@ function assertLocalRequestWithinContext(payload = {}, config = {}, label = "age
|
|
|
336
340
|
|
|
337
341
|
export { hasExplicitDeepResearchIntent } from "./research-routing.js";
|
|
338
342
|
|
|
339
|
-
|
|
340
|
-
|
|
343
|
+
function requiresConcreteToolContinuation(messages = []) {
|
|
344
|
+
return messages.slice(-3).some(
|
|
341
345
|
(message) =>
|
|
342
346
|
message?.role === "user" &&
|
|
343
347
|
/emit exactly one enabled tool call that performs the next concrete action/i.test(String(message.content || ""))
|
|
344
348
|
);
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
function singleExecutableToolName(tools = []) {
|
|
352
|
+
const names = (Array.isArray(tools) ? tools : [])
|
|
353
|
+
.filter((tool) => tool?.type === "function")
|
|
354
|
+
.map((tool) => String(tool.function?.name || ""))
|
|
355
|
+
.filter(Boolean);
|
|
356
|
+
const actionable = [...new Set(names.filter((name) => name !== "finish"))];
|
|
357
|
+
if (actionable.length !== 1) return "";
|
|
358
|
+
return names.every((name) => name === "finish" || name === actionable[0])
|
|
359
|
+
? actionable[0]
|
|
360
|
+
: "";
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
function deepSeekActionOnlyTool(config = {}, messages = [], tools = []) {
|
|
364
|
+
if (normalizeProviderId(config.provider, "") !== "deepseek") return "";
|
|
365
|
+
const constrainedRecovery = config.completionFreshMutationRequired === true ||
|
|
366
|
+
requiresConcreteToolContinuation(messages);
|
|
367
|
+
if (!constrainedRecovery) return "";
|
|
368
|
+
const constrainedTool = singleExecutableToolName(tools);
|
|
369
|
+
if (constrainedTool) return constrainedTool;
|
|
370
|
+
const actionable = (Array.isArray(tools) ? tools : [])
|
|
371
|
+
.filter((tool) => tool?.type === "function" && tool.function?.name !== "finish")
|
|
372
|
+
.map((tool) => String(tool.function?.name || ""))
|
|
373
|
+
.filter(Boolean);
|
|
374
|
+
return actionable.length === 1 ? actionable[0] : "";
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
function deepSeekActionOnlyRequest(config = {}, messages = [], tools = []) {
|
|
378
|
+
return normalizeProviderId(config.provider, "") === "deepseek" &&
|
|
379
|
+
Boolean(
|
|
380
|
+
requiresConcreteToolContinuation(messages) ||
|
|
381
|
+
(config.completionFreshMutationRequired === true && singleExecutableToolName(tools))
|
|
382
|
+
);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
export function toolChoiceForProvider(config, messages = [], tools = []) {
|
|
386
|
+
const requiresConcreteContinuation = requiresConcreteToolContinuation(messages);
|
|
387
|
+
const deepSeekActionTool = deepSeekActionOnlyTool(config, messages, tools);
|
|
388
|
+
if (deepSeekActionTool) {
|
|
389
|
+
return {
|
|
390
|
+
type: "function",
|
|
391
|
+
function: { name: deepSeekActionTool },
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
if (requiresConcreteContinuation) {
|
|
350
395
|
return "required";
|
|
351
396
|
}
|
|
352
397
|
if (config.provider !== "venice") return "auto";
|
|
@@ -2649,10 +2694,13 @@ export async function requestNextStep(client, config, messages) {
|
|
|
2649
2694
|
const nativePayload = {
|
|
2650
2695
|
model: config.model,
|
|
2651
2696
|
temperature: 0,
|
|
2652
|
-
tool_choice: toolChoiceForProvider(config, messages),
|
|
2697
|
+
tool_choice: toolChoiceForProvider(config, messages, requestTools),
|
|
2653
2698
|
parallel_tool_calls: false,
|
|
2654
2699
|
messages: prepareMessages(config, messages),
|
|
2655
2700
|
tools: requestTools,
|
|
2701
|
+
...(deepSeekActionOnlyRequest(config, messages, requestTools)
|
|
2702
|
+
? { thinking: { type: "disabled" } }
|
|
2703
|
+
: {}),
|
|
2656
2704
|
...(Number(config.maxOutputTokens || 0) > 0 ? { max_tokens: Number(config.maxOutputTokens) } : {}),
|
|
2657
2705
|
};
|
|
2658
2706
|
const textPayload = {
|
package/src/provider-contract.js
CHANGED
|
@@ -75,7 +75,7 @@ export const PROVIDER_CONTRACTS = Object.freeze({
|
|
|
75
75
|
defaultModel: "deepseek-v4-flash",
|
|
76
76
|
toolProtocol: "native",
|
|
77
77
|
structuredOutput: "json_object",
|
|
78
|
-
supportsReasoningEffort:
|
|
78
|
+
supportsReasoningEffort: true,
|
|
79
79
|
textToolFallback: false,
|
|
80
80
|
}),
|
|
81
81
|
openai: Object.freeze({
|