@lazyingart/agintiflow 0.20.261 → 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.261",
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",
@@ -189,6 +189,28 @@ 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
+ 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
+ ]
211
+ ) === "auto",
212
+ "DeepSeek ordinary chat forced a tool merely because few tools were enabled"
213
+ );
192
214
  assert(
193
215
  JSON.stringify(providerStructuredOutputAttempts("deepseek")) === JSON.stringify(["json_object", "prompt"]),
194
216
  "DeepSeek structured extraction still probes an unsupported JSON Schema mode"
@@ -241,7 +263,7 @@ async function main() {
241
263
  completionFreshMutationNeedsSourceRead: false,
242
264
  completionFreshMutationPaths: ["service.py"],
243
265
  },
244
- [{ role: "user", content: "Emit exactly one enabled tool call that performs the next concrete action." }]
266
+ [{ role: "user", content: "Repair the retained source from the exact failure evidence." }]
245
267
  );
246
268
  assert(
247
269
  deepSeekActionPayload?.thinking?.type === "disabled",
@@ -348,27 +348,50 @@ function requiresConcreteToolContinuation(messages = []) {
348
348
  );
349
349
  }
350
350
 
351
- function deepSeekActionOnlyRequest(config = {}, messages = []) {
352
- return normalizeProviderId(config.provider, "") === "deepseek" &&
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 ||
353
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
+ );
354
383
  }
355
384
 
356
385
  export function toolChoiceForProvider(config, messages = [], tools = []) {
357
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
+ }
358
394
  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
395
  return "required";
373
396
  }
374
397
  if (config.provider !== "venice") return "auto";
@@ -2675,7 +2698,7 @@ export async function requestNextStep(client, config, messages) {
2675
2698
  parallel_tool_calls: false,
2676
2699
  messages: prepareMessages(config, messages),
2677
2700
  tools: requestTools,
2678
- ...(deepSeekActionOnlyRequest(config, messages)
2701
+ ...(deepSeekActionOnlyRequest(config, messages, requestTools)
2679
2702
  ? { thinking: { type: "disabled" } }
2680
2703
  : {}),
2681
2704
  ...(Number(config.maxOutputTokens || 0) > 0 ? { max_tokens: Number(config.maxOutputTokens) } : {}),