@lazyingart/agintiflow 0.20.284 → 0.20.286
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.286",
|
|
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",
|
|
@@ -180,6 +180,7 @@
|
|
|
180
180
|
"smoke:localllm-model-tiers": "node scripts/smoke-localllm-model-tiers.js",
|
|
181
181
|
"smoke:localllm-provider": "node scripts/smoke-localllm-provider.js",
|
|
182
182
|
"smoke:progressive-tools": "node scripts/smoke-progressive-tool-selection.js",
|
|
183
|
+
"smoke:scoped-artifact-research": "node scripts/smoke-scoped-artifact-research.js",
|
|
183
184
|
"smoke:truthful-completion": "node scripts/smoke-truthful-completion.js",
|
|
184
185
|
"smoke:document-artifact-quality": "node scripts/smoke-document-artifact-quality.js",
|
|
185
186
|
"smoke:writing-specialist-routing": "node scripts/smoke-writing-specialist-routing.js",
|
|
@@ -2482,6 +2482,93 @@ try {
|
|
|
2482
2482
|
invalidFocusedRewrite.errors.some((error) => error.code === "ARGUMENT_PATTERN_MISMATCH"),
|
|
2483
2483
|
"focused rewrite smoke input did not exercise the semantic pattern failure"
|
|
2484
2484
|
);
|
|
2485
|
+
const commandDescriptor = {
|
|
2486
|
+
type: "function",
|
|
2487
|
+
function: {
|
|
2488
|
+
name: "run_command",
|
|
2489
|
+
description: "Run one command.",
|
|
2490
|
+
parameters: {
|
|
2491
|
+
type: "object",
|
|
2492
|
+
properties: { command: { type: "string", minLength: 1 } },
|
|
2493
|
+
required: ["command"],
|
|
2494
|
+
additionalProperties: false,
|
|
2495
|
+
},
|
|
2496
|
+
},
|
|
2497
|
+
};
|
|
2498
|
+
const annotatedCommandBatch = [
|
|
2499
|
+
{
|
|
2500
|
+
id: "annotated-command-one",
|
|
2501
|
+
type: "function",
|
|
2502
|
+
function: {
|
|
2503
|
+
name: "run_command",
|
|
2504
|
+
arguments: JSON.stringify({
|
|
2505
|
+
command: "printf one",
|
|
2506
|
+
description: "Inspect the first item",
|
|
2507
|
+
}),
|
|
2508
|
+
},
|
|
2509
|
+
},
|
|
2510
|
+
{
|
|
2511
|
+
id: "annotated-command-two",
|
|
2512
|
+
type: "function",
|
|
2513
|
+
function: {
|
|
2514
|
+
name: "run_command",
|
|
2515
|
+
arguments: JSON.stringify({
|
|
2516
|
+
command: "printf two",
|
|
2517
|
+
description: "Inspect the second item",
|
|
2518
|
+
}),
|
|
2519
|
+
},
|
|
2520
|
+
},
|
|
2521
|
+
];
|
|
2522
|
+
const recoveredAnnotatedCommands = resolveDispatchableToolCallBatch(
|
|
2523
|
+
annotatedCommandBatch,
|
|
2524
|
+
createToolContract([commandDescriptor])
|
|
2525
|
+
);
|
|
2526
|
+
assert(recoveredAnnotatedCommands.ok, "benign command annotations were not normalized");
|
|
2527
|
+
assert(
|
|
2528
|
+
recoveredAnnotatedCommands.recoveredToolCallAnnotations,
|
|
2529
|
+
"benign command annotation recovery was not recorded"
|
|
2530
|
+
);
|
|
2531
|
+
assert(
|
|
2532
|
+
recoveredAnnotatedCommands.recoveredSequentially,
|
|
2533
|
+
"annotated command batch did not retain bounded sequential dispatch"
|
|
2534
|
+
);
|
|
2535
|
+
assert(
|
|
2536
|
+
recoveredAnnotatedCommands.acceptedToolCalls.length === 1 &&
|
|
2537
|
+
recoveredAnnotatedCommands.deferredToolCalls.length === 1,
|
|
2538
|
+
"annotated command batch did not dispatch one call and defer the suffix"
|
|
2539
|
+
);
|
|
2540
|
+
for (const call of [
|
|
2541
|
+
...recoveredAnnotatedCommands.acceptedToolCalls,
|
|
2542
|
+
...recoveredAnnotatedCommands.deferredToolCalls,
|
|
2543
|
+
]) {
|
|
2544
|
+
assert(
|
|
2545
|
+
!Object.hasOwn(JSON.parse(call.function.arguments), "description"),
|
|
2546
|
+
"non-executable command description reached dispatch"
|
|
2547
|
+
);
|
|
2548
|
+
}
|
|
2549
|
+
const unknownAnnotatedCommand = resolveDispatchableToolCallBatch(
|
|
2550
|
+
[
|
|
2551
|
+
{
|
|
2552
|
+
id: "unknown-command-annotation",
|
|
2553
|
+
type: "function",
|
|
2554
|
+
function: {
|
|
2555
|
+
name: "run_command",
|
|
2556
|
+
arguments: JSON.stringify({
|
|
2557
|
+
command: "printf blocked",
|
|
2558
|
+
rationale: "This key is not an approved annotation",
|
|
2559
|
+
}),
|
|
2560
|
+
},
|
|
2561
|
+
},
|
|
2562
|
+
],
|
|
2563
|
+
createToolContract([commandDescriptor])
|
|
2564
|
+
);
|
|
2565
|
+
assert(
|
|
2566
|
+
!unknownAnnotatedCommand.ok &&
|
|
2567
|
+
unknownAnnotatedCommand.errors.some(
|
|
2568
|
+
(error) => error.code === "ARGUMENT_ADDITIONAL_PROPERTY"
|
|
2569
|
+
),
|
|
2570
|
+
"an unknown command annotation bypassed the exact tool schema"
|
|
2571
|
+
);
|
|
2485
2572
|
const focusedWriterCalls = [];
|
|
2486
2573
|
const focusedRewriteState = {
|
|
2487
2574
|
meta: {
|
|
@@ -2440,11 +2440,10 @@ export function selectProgressiveTools(
|
|
|
2440
2440
|
|
|
2441
2441
|
if (config.scopedArtifactTask === true && config.scopedArtifactRoot) {
|
|
2442
2442
|
const available = new Map(enabled.map(({ name, tool }) => [name, tool]));
|
|
2443
|
-
|
|
2443
|
+
const scopedWorkspaceTools = [
|
|
2444
2444
|
constrainScopedArtifactPath(
|
|
2445
2445
|
available.get("list_files"),
|
|
2446
|
-
config.scopedArtifactRoot
|
|
2447
|
-
{ rootOnly: true }
|
|
2446
|
+
config.scopedArtifactRoot
|
|
2448
2447
|
),
|
|
2449
2448
|
constrainScopedArtifactPath(
|
|
2450
2449
|
available.get("read_file"),
|
|
@@ -2452,8 +2451,7 @@ export function selectProgressiveTools(
|
|
|
2452
2451
|
),
|
|
2453
2452
|
constrainScopedArtifactPath(
|
|
2454
2453
|
available.get("search_files"),
|
|
2455
|
-
config.scopedArtifactRoot
|
|
2456
|
-
{ rootOnly: true }
|
|
2454
|
+
config.scopedArtifactRoot
|
|
2457
2455
|
),
|
|
2458
2456
|
constrainScopedArtifactPath(
|
|
2459
2457
|
available.get("write_file"),
|
|
@@ -2464,8 +2462,40 @@ export function selectProgressiveTools(
|
|
|
2464
2462
|
config.scopedArtifactRoot
|
|
2465
2463
|
),
|
|
2466
2464
|
available.get("run_command"),
|
|
2467
|
-
finish,
|
|
2468
2465
|
].filter(Boolean);
|
|
2466
|
+
|
|
2467
|
+
// Artifact isolation limits where the task may read or write; it must not
|
|
2468
|
+
// erase the task's research, browser, or specialist capabilities. Keep
|
|
2469
|
+
// inferred non-file tools while the workspace tools remain root-scoped.
|
|
2470
|
+
const scopedWorkspaceToolNames = new Set(
|
|
2471
|
+
scopedWorkspaceTools.map((tool) => openAiFunctionName(tool)).filter(Boolean)
|
|
2472
|
+
);
|
|
2473
|
+
const taskSpecificTools = compactToolNames({ config, goal, profile, messages })
|
|
2474
|
+
.filter((name) => name !== "finish" && !FILE_TOOL_NAMES.has(name))
|
|
2475
|
+
.filter((name) => !scopedWorkspaceToolNames.has(name))
|
|
2476
|
+
.map((name) => available.get(name))
|
|
2477
|
+
.filter(Boolean);
|
|
2478
|
+
const requestedLimit = finitePositiveInteger(
|
|
2479
|
+
config.toolSurfaceMaxTools ?? config.localToolMaxTools,
|
|
2480
|
+
DEFAULT_LOCAL_TOOL_LIMIT
|
|
2481
|
+
);
|
|
2482
|
+
const toolLimit = Math.min(requestedLimit, LOCAL_TOOL_HARD_CAP);
|
|
2483
|
+
const taskSpecificLimit = Math.max(
|
|
2484
|
+
0,
|
|
2485
|
+
toolLimit - scopedWorkspaceTools.length - 1
|
|
2486
|
+
);
|
|
2487
|
+
const selected = [];
|
|
2488
|
+
const seen = new Set();
|
|
2489
|
+
for (const tool of [
|
|
2490
|
+
...taskSpecificTools.slice(0, taskSpecificLimit),
|
|
2491
|
+
...scopedWorkspaceTools,
|
|
2492
|
+
]) {
|
|
2493
|
+
const name = openAiFunctionName(tool);
|
|
2494
|
+
if (!name || name === "finish" || seen.has(name) || selected.length + 1 >= toolLimit) continue;
|
|
2495
|
+
seen.add(name);
|
|
2496
|
+
selected.push(tool);
|
|
2497
|
+
}
|
|
2498
|
+
return [...selected, finish];
|
|
2469
2499
|
}
|
|
2470
2500
|
|
|
2471
2501
|
if (config.repositoryGroundingRequired === true) {
|
package/src/tool-contract.js
CHANGED
|
@@ -30,6 +30,7 @@ const MAX_VALIDATION_ERRORS = 8;
|
|
|
30
30
|
const MAX_VALIDATION_NODES = 50_000;
|
|
31
31
|
const MAX_SAFE_SEQUENTIAL_READ_CALLS = 4;
|
|
32
32
|
const MAX_REPORTED_SEQUENTIAL_CALLS = 12;
|
|
33
|
+
const BENIGN_TOOL_CALL_ANNOTATION_KEYS = new Set(["description"]);
|
|
33
34
|
|
|
34
35
|
function cloneValue(value) {
|
|
35
36
|
return structuredClone(value);
|
|
@@ -457,6 +458,69 @@ function recoverBoundedCommitSubject(toolCalls, contract, validation) {
|
|
|
457
458
|
};
|
|
458
459
|
}
|
|
459
460
|
|
|
461
|
+
function normalizeBenignToolCallAnnotations(toolCalls, contract) {
|
|
462
|
+
const calls = Array.isArray(toolCalls) ? toolCalls : [];
|
|
463
|
+
if (!calls.length || contract?.[contractMarker] !== true) return null;
|
|
464
|
+
|
|
465
|
+
const normalizedCalls = [];
|
|
466
|
+
const corrections = [];
|
|
467
|
+
for (let index = 0; index < calls.length; index += 1) {
|
|
468
|
+
const call = calls[index];
|
|
469
|
+
const toolName = String(call?.function?.name || "");
|
|
470
|
+
const descriptor = contract.tools.find(
|
|
471
|
+
(candidate) =>
|
|
472
|
+
candidate?.type === "function" && candidate.function?.name === toolName
|
|
473
|
+
);
|
|
474
|
+
if (!descriptor || typeof call?.function?.arguments !== "string") return null;
|
|
475
|
+
|
|
476
|
+
let args;
|
|
477
|
+
try {
|
|
478
|
+
args = JSON.parse(call.function.arguments);
|
|
479
|
+
} catch {
|
|
480
|
+
return null;
|
|
481
|
+
}
|
|
482
|
+
if (!isPlainObject(args)) return null;
|
|
483
|
+
|
|
484
|
+
const parameters = descriptor.function?.parameters;
|
|
485
|
+
const properties = isPlainObject(parameters?.properties)
|
|
486
|
+
? parameters.properties
|
|
487
|
+
: {};
|
|
488
|
+
const correctedArgs = { ...args };
|
|
489
|
+
const removed = [];
|
|
490
|
+
for (const key of BENIGN_TOOL_CALL_ANNOTATION_KEYS) {
|
|
491
|
+
if (
|
|
492
|
+
parameters?.additionalProperties === false &&
|
|
493
|
+
!Object.hasOwn(properties, key) &&
|
|
494
|
+
Object.hasOwn(correctedArgs, key) &&
|
|
495
|
+
typeof correctedArgs[key] === "string" &&
|
|
496
|
+
correctedArgs[key].length <= 1_000
|
|
497
|
+
) {
|
|
498
|
+
delete correctedArgs[key];
|
|
499
|
+
removed.push(key);
|
|
500
|
+
corrections.push({
|
|
501
|
+
callIndex: index,
|
|
502
|
+
property: key,
|
|
503
|
+
source: "non-executable-tool-annotation",
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
normalizedCalls.push(
|
|
509
|
+
removed.length
|
|
510
|
+
? {
|
|
511
|
+
...call,
|
|
512
|
+
function: {
|
|
513
|
+
...call.function,
|
|
514
|
+
arguments: JSON.stringify(correctedArgs),
|
|
515
|
+
},
|
|
516
|
+
}
|
|
517
|
+
: call
|
|
518
|
+
);
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
return corrections.length ? { calls: normalizedCalls, corrections } : null;
|
|
522
|
+
}
|
|
523
|
+
|
|
460
524
|
export function validateToolCallBatch(toolCalls, contract, { maxToolCalls = 1 } = {}) {
|
|
461
525
|
const errors = [];
|
|
462
526
|
const addError = (code, callIndex, message) => {
|
|
@@ -613,6 +677,27 @@ export function resolveDispatchableToolCallBatch(toolCalls, contract) {
|
|
|
613
677
|
};
|
|
614
678
|
}
|
|
615
679
|
|
|
680
|
+
const annotationNormalization = normalizeBenignToolCallAnnotations(calls, contract);
|
|
681
|
+
if (annotationNormalization) {
|
|
682
|
+
const recovered = resolveDispatchableToolCallBatch(
|
|
683
|
+
annotationNormalization.calls,
|
|
684
|
+
contract
|
|
685
|
+
);
|
|
686
|
+
if (recovered.ok) {
|
|
687
|
+
return {
|
|
688
|
+
...recovered,
|
|
689
|
+
recoveredToolCallAnnotations: true,
|
|
690
|
+
argumentCorrections: [
|
|
691
|
+
...(Array.isArray(recovered.argumentCorrections)
|
|
692
|
+
? recovered.argumentCorrections
|
|
693
|
+
: []),
|
|
694
|
+
...annotationNormalization.corrections,
|
|
695
|
+
],
|
|
696
|
+
originalCode: validation.code,
|
|
697
|
+
};
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
|
|
616
701
|
const readRangeRecovery = recoverReadFileRangeAlias(calls, contract, validation);
|
|
617
702
|
if (readRangeRecovery) return readRangeRecovery;
|
|
618
703
|
|