@lazyingart/agintiflow 0.20.261 → 0.20.263

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.261",
3
+ "version": "0.20.263",
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",
@@ -189,6 +189,43 @@ async function main() {
189
189
  )) === JSON.stringify({ type: "function", function: { name: "apply_patch" } }),
190
190
  "DeepSeek action recovery did not force the only executable tool"
191
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
+ JSON.stringify(toolChoiceForProvider(
205
+ {
206
+ provider: "deepseek",
207
+ testFailureRepairActive: true,
208
+ testFailureRepairMutationRequired: true,
209
+ },
210
+ [{ role: "user", content: "Continue from the retained failing test evidence." }],
211
+ [
212
+ { type: "function", function: { name: "apply_patch" } },
213
+ { type: "function", function: { name: "finish" } },
214
+ ]
215
+ )) === JSON.stringify({ type: "function", function: { name: "apply_patch" } }),
216
+ "DeepSeek failed-test repair did not force its sole bounded mutation tool"
217
+ );
218
+ assert(
219
+ toolChoiceForProvider(
220
+ { provider: "deepseek" },
221
+ [{ role: "user", content: "Explain what this source does." }],
222
+ [
223
+ { type: "function", function: { name: "read_file" } },
224
+ { type: "function", function: { name: "finish" } },
225
+ ]
226
+ ) === "auto",
227
+ "DeepSeek ordinary chat forced a tool merely because few tools were enabled"
228
+ );
192
229
  assert(
193
230
  JSON.stringify(providerStructuredOutputAttempts("deepseek")) === JSON.stringify(["json_object", "prompt"]),
194
231
  "DeepSeek structured extraction still probes an unsupported JSON Schema mode"
@@ -241,7 +278,7 @@ async function main() {
241
278
  completionFreshMutationNeedsSourceRead: false,
242
279
  completionFreshMutationPaths: ["service.py"],
243
280
  },
244
- [{ role: "user", content: "Emit exactly one enabled tool call that performs the next concrete action." }]
281
+ [{ role: "user", content: "Repair the retained source from the exact failure evidence." }]
245
282
  );
246
283
  assert(
247
284
  deepSeekActionPayload?.thinking?.type === "disabled",
@@ -348,27 +348,57 @@ function requiresConcreteToolContinuation(messages = []) {
348
348
  );
349
349
  }
350
350
 
351
- function deepSeekActionOnlyRequest(config = {}, messages = []) {
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 deepSeekConstrainedActionRequired(config = {}, messages = []) {
364
+ return requiresConcreteToolContinuation(messages) ||
365
+ config.completionFreshMutationRequired === true ||
366
+ (
367
+ config.testFailureRepairActive === true &&
368
+ config.testFailureRepairMutationRequired === true
369
+ );
370
+ }
371
+
372
+ function deepSeekActionOnlyTool(config = {}, messages = [], tools = []) {
373
+ if (normalizeProviderId(config.provider, "") !== "deepseek") return "";
374
+ if (!deepSeekConstrainedActionRequired(config, messages)) return "";
375
+ const constrainedTool = singleExecutableToolName(tools);
376
+ if (constrainedTool) return constrainedTool;
377
+ const actionable = (Array.isArray(tools) ? tools : [])
378
+ .filter((tool) => tool?.type === "function" && tool.function?.name !== "finish")
379
+ .map((tool) => String(tool.function?.name || ""))
380
+ .filter(Boolean);
381
+ return actionable.length === 1 ? actionable[0] : "";
382
+ }
383
+
384
+ function deepSeekActionOnlyRequest(config = {}, messages = [], tools = []) {
352
385
  return normalizeProviderId(config.provider, "") === "deepseek" &&
353
- requiresConcreteToolContinuation(messages);
386
+ Boolean(
387
+ requiresConcreteToolContinuation(messages) ||
388
+ (deepSeekConstrainedActionRequired(config, messages) && singleExecutableToolName(tools))
389
+ );
354
390
  }
355
391
 
356
392
  export function toolChoiceForProvider(config, messages = [], tools = []) {
357
393
  const requiresConcreteContinuation = requiresConcreteToolContinuation(messages);
394
+ const deepSeekActionTool = deepSeekActionOnlyTool(config, messages, tools);
395
+ if (deepSeekActionTool) {
396
+ return {
397
+ type: "function",
398
+ function: { name: deepSeekActionTool },
399
+ };
400
+ }
358
401
  if (requiresConcreteContinuation) {
359
- const actionable = (Array.isArray(tools) ? tools : [])
360
- .filter((tool) => tool?.type === "function" && tool.function?.name !== "finish")
361
- .map((tool) => String(tool.function?.name || ""))
362
- .filter(Boolean);
363
- if (
364
- normalizeProviderId(config.provider, "") === "deepseek" &&
365
- actionable.length === 1
366
- ) {
367
- return {
368
- type: "function",
369
- function: { name: actionable[0] },
370
- };
371
- }
372
402
  return "required";
373
403
  }
374
404
  if (config.provider !== "venice") return "auto";
@@ -2675,7 +2705,7 @@ export async function requestNextStep(client, config, messages) {
2675
2705
  parallel_tool_calls: false,
2676
2706
  messages: prepareMessages(config, messages),
2677
2707
  tools: requestTools,
2678
- ...(deepSeekActionOnlyRequest(config, messages)
2708
+ ...(deepSeekActionOnlyRequest(config, messages, requestTools)
2679
2709
  ? { thinking: { type: "disabled" } }
2680
2710
  : {}),
2681
2711
  ...(Number(config.maxOutputTokens || 0) > 0 ? { max_tokens: Number(config.maxOutputTokens) } : {}),