open-agents-ai 0.187.467 → 0.187.469
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/dist/index.js +370 -53
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -517859,6 +517859,15 @@ var init_agenticRunner = __esm({
|
|
|
517859
517859
|
// a phase's worth of work without recording progress — and on the next
|
|
517860
517860
|
// turn will replay the same plan. Surface a nudge before that happens.
|
|
517861
517861
|
_writesSinceLastTodoWrite = 0;
|
|
517862
|
+
// REG-12: Progress gate (root-cause enforcement). When ≥6 file writes
|
|
517863
|
+
// have happened without a todo_write call, this latch flips ON. While
|
|
517864
|
+
// the latch is on, every tool call EXCEPT todo_write/todo_read/
|
|
517865
|
+
// task_complete/ask_user is intercepted with a synthetic '[PROGRESS GATE]'
|
|
517866
|
+
// result that forces the agent to update its plan before continuing.
|
|
517867
|
+
// Released when todo_write fires successfully. Without this, the agent
|
|
517868
|
+
// can re-emit the same plan a second time (plan-replay) and execute
|
|
517869
|
+
// duplicate work because PROGRESS NUDGE alone is informational.
|
|
517870
|
+
_progressGateActive = false;
|
|
517862
517871
|
// REG-5: Rolling buffer of recent tool failures with their error output.
|
|
517863
517872
|
// Surfaced before every LLM call so the agent can't ignore "I just ran this
|
|
517864
517873
|
// and it errored". Detects same-fingerprint failure repetition and escalates
|
|
@@ -518592,41 +518601,98 @@ ${body}`;
|
|
|
518592
518601
|
if (!output || typeof output !== "string")
|
|
518593
518602
|
return null;
|
|
518594
518603
|
const text = output;
|
|
518595
|
-
const tail = text.slice(-
|
|
518596
|
-
if (/\
|
|
518604
|
+
const tail = text.slice(-4e3);
|
|
518605
|
+
if (/\berror\s+TS\d{3,5}\b/i.test(tail)) {
|
|
518597
518606
|
const m2 = tail.match(/error\s+TS\d{3,5}[^\n]{0,200}/i);
|
|
518598
|
-
return `
|
|
518607
|
+
return `Compile error: ${(m2?.[0] ?? "").slice(0, 240)}`;
|
|
518599
518608
|
}
|
|
518600
|
-
if (/\
|
|
518601
|
-
const m2 = tail.match(/
|
|
518602
|
-
return `
|
|
518609
|
+
if (/\berror\[E\d+\]/i.test(tail)) {
|
|
518610
|
+
const m2 = tail.match(/error\[E\d+\][^\n]{0,200}/i);
|
|
518611
|
+
return `Compile error: ${(m2?.[0] ?? "").slice(0, 240)}`;
|
|
518603
518612
|
}
|
|
518604
|
-
if (/\
|
|
518605
|
-
|
|
518613
|
+
if (/\berror\s+CS\d{3,5}\b/i.test(tail)) {
|
|
518614
|
+
const m2 = tail.match(/error\s+CS\d{3,5}[^\n]{0,200}/i);
|
|
518615
|
+
return `Compile error: ${(m2?.[0] ?? "").slice(0, 240)}`;
|
|
518606
518616
|
}
|
|
518607
|
-
if (
|
|
518608
|
-
const m2 = tail.match(/\d
|
|
518609
|
-
return `
|
|
518617
|
+
if (/(^|\n)\S+:\d+:\d+:\s+error:/i.test(tail)) {
|
|
518618
|
+
const m2 = tail.match(/\S+:\d+:\d+:\s+error:[^\n]{0,200}/i);
|
|
518619
|
+
return `Compile error: ${(m2?.[0] ?? "").slice(0, 240)}`;
|
|
518620
|
+
}
|
|
518621
|
+
if (/\bundefined\s+reference\s+to\b|\bld:\s+error:/i.test(tail)) {
|
|
518622
|
+
const m2 = tail.match(/(undefined\s+reference\s+to|ld:\s+error:)[^\n]{0,200}/i);
|
|
518623
|
+
return `Linker error: ${(m2?.[0] ?? "").slice(0, 240)}`;
|
|
518624
|
+
}
|
|
518625
|
+
if (/\b(Failed to compile|Compilation failed|Build failed|BUILD\s+FAIL(ED|URE))\b/i.test(tail)) {
|
|
518626
|
+
const m2 = tail.match(/(Failed to compile|Compilation failed|Build failed|BUILD\s+FAIL(?:ED|URE))[^\n]{0,300}/i);
|
|
518627
|
+
return `Build failed: ${(m2?.[0] ?? "").slice(0, 240)}`;
|
|
518628
|
+
}
|
|
518629
|
+
if (/\b\d+\s+errors?\s+(found|generated)\b/i.test(tail)) {
|
|
518630
|
+
const m2 = tail.match(/\d+\s+errors?\s+(?:found|generated)[^\n]{0,200}/i);
|
|
518631
|
+
return `Build reported errors: ${(m2?.[0] ?? "").slice(0, 240)}`;
|
|
518610
518632
|
}
|
|
518611
518633
|
if (/\bnpm\s+ERR!|\bnpm error code\b/i.test(tail)) {
|
|
518612
518634
|
const m2 = tail.match(/(npm\s+ERR!|npm error code)[^\n]{0,300}/i);
|
|
518613
|
-
return `
|
|
518635
|
+
return `Package install error: ${(m2?.[0] ?? "").slice(0, 240)}`;
|
|
518636
|
+
}
|
|
518637
|
+
if (/\bERROR:\s+Could not (install|find|build)\b/i.test(tail)) {
|
|
518638
|
+
const m2 = tail.match(/ERROR:\s+Could not[^\n]{0,200}/i);
|
|
518639
|
+
return `Package install error: ${(m2?.[0] ?? "").slice(0, 240)}`;
|
|
518640
|
+
}
|
|
518641
|
+
if (/\b(E:\s+(Unable to|Could not)|apt-get:\s+error|dnf:\s+(?:Error|Failed)|pacman:\s+error)/i.test(tail)) {
|
|
518642
|
+
const m2 = tail.match(/(E:\s+|apt-get:\s+error|dnf:\s+|pacman:\s+error)[^\n]{0,200}/i);
|
|
518643
|
+
return `System package error: ${(m2?.[0] ?? "").slice(0, 240)}`;
|
|
518644
|
+
}
|
|
518645
|
+
if (/\bTests?:\s+\d+\s+failed\b/i.test(tail)) {
|
|
518646
|
+
const m2 = tail.match(/Tests?:[^\n]{0,200}/i);
|
|
518647
|
+
return `Test failures: ${(m2?.[0] ?? "").slice(0, 240)}`;
|
|
518648
|
+
}
|
|
518649
|
+
if (/^FAILED\s+\S+::/m.test(tail) || /=+\s*\d+\s+failed/i.test(tail)) {
|
|
518650
|
+
const m2 = tail.match(/(FAILED\s+\S+|=+\s*\d+\s+failed)[^\n]{0,200}/i);
|
|
518651
|
+
return `Test failures: ${(m2?.[0] ?? "").slice(0, 240)}`;
|
|
518652
|
+
}
|
|
518653
|
+
if (/\b\d+\s+failing\b/i.test(tail) && /\bpassing\b/i.test(tail)) {
|
|
518654
|
+
const m2 = tail.match(/\d+\s+failing[^\n]{0,200}/i);
|
|
518655
|
+
return `Test failures: ${(m2?.[0] ?? "").slice(0, 240)}`;
|
|
518656
|
+
}
|
|
518657
|
+
if (/^---\s+FAIL:/m.test(tail) || /^FAIL\t\S+/m.test(tail)) {
|
|
518658
|
+
const m2 = tail.match(/(---\s+FAIL:[^\n]{0,200}|FAIL\t\S+[^\n]{0,200})/i);
|
|
518659
|
+
return `Test failures: ${(m2?.[0] ?? "").slice(0, 240)}`;
|
|
518660
|
+
}
|
|
518661
|
+
if (/test\s+result:\s+FAILED/i.test(tail)) {
|
|
518662
|
+
const m2 = tail.match(/test\s+result:\s+FAILED[^\n]{0,200}/i);
|
|
518663
|
+
return `Test failures: ${(m2?.[0] ?? "").slice(0, 240)}`;
|
|
518664
|
+
}
|
|
518665
|
+
if (/\b\d+\s+failed\s+(of|out\s+of)\s+\d+\b/i.test(tail)) {
|
|
518666
|
+
const m2 = tail.match(/\d+\s+failed\s+(?:of|out\s+of)\s+\d+[^\n]{0,200}/i);
|
|
518667
|
+
return `Test failures: ${(m2?.[0] ?? "").slice(0, 240)}`;
|
|
518668
|
+
}
|
|
518669
|
+
if (/^Traceback \(most recent call last\):/m.test(tail) && /\w+(?:Error|Exception):\s/.test(tail)) {
|
|
518670
|
+
const m2 = tail.match(/\w+(?:Error|Exception):[^\n]{0,200}/);
|
|
518671
|
+
return `Runtime exception: ${(m2?.[0] ?? "").slice(0, 240)}`;
|
|
518614
518672
|
}
|
|
518615
|
-
if (/\
|
|
518616
|
-
const m2 = tail.match(/
|
|
518617
|
-
return `
|
|
518673
|
+
if (/\b(UnhandledPromiseRejection|throw\s+new\s+\w+|Uncaught\s+\w+Error)\b/i.test(tail)) {
|
|
518674
|
+
const m2 = tail.match(/(UnhandledPromiseRejection|throw\s+new\s+\w+|Uncaught[^\n]{0,200})/i);
|
|
518675
|
+
return `Runtime exception: ${(m2?.[0] ?? "").slice(0, 240)}`;
|
|
518618
518676
|
}
|
|
518619
|
-
if (
|
|
518620
|
-
const m2 = tail.match(/(\w+(?:Error|Exception)
|
|
518621
|
-
return `
|
|
518677
|
+
if (/\b(Exception\s+in\s+thread|java\.\w+(?:Error|Exception):)/i.test(tail)) {
|
|
518678
|
+
const m2 = tail.match(/(Exception\s+in\s+thread[^\n]{0,200}|java\.\w+(?:Error|Exception):[^\n]{0,200})/i);
|
|
518679
|
+
return `Runtime exception: ${(m2?.[0] ?? "").slice(0, 240)}`;
|
|
518622
518680
|
}
|
|
518623
|
-
if (
|
|
518624
|
-
const m2 = tail.match(
|
|
518625
|
-
return `
|
|
518681
|
+
if (/^[\w./:-]+:\d+:in\s+`[^']*':\s+/m.test(tail) && /\b\w+Error\b/.test(tail)) {
|
|
518682
|
+
const m2 = tail.match(/\b\w+Error[^\n]{0,200}/);
|
|
518683
|
+
return `Runtime exception: ${(m2?.[0] ?? "").slice(0, 240)}`;
|
|
518684
|
+
}
|
|
518685
|
+
if (/\bthread\s+'[^']*'\s+panicked\s+at/i.test(tail)) {
|
|
518686
|
+
const m2 = tail.match(/thread\s+'[^']*'\s+panicked\s+at[^\n]{0,200}/i);
|
|
518687
|
+
return `Runtime panic: ${(m2?.[0] ?? "").slice(0, 240)}`;
|
|
518626
518688
|
}
|
|
518627
518689
|
if (/^(fatal|FATAL|panic):\s/m.test(tail)) {
|
|
518628
518690
|
const m2 = tail.match(/^(fatal|FATAL|panic):\s[^\n]{0,200}/m);
|
|
518629
|
-
return `Fatal error: ${(m2?.[0] ?? "").slice(0,
|
|
518691
|
+
return `Fatal error: ${(m2?.[0] ?? "").slice(0, 240)}`;
|
|
518692
|
+
}
|
|
518693
|
+
if (/\b(Segmentation\s+fault|core\s+dumped|Abort(?:ed)?\s+\(core dumped\)|Killed)\b/i.test(tail)) {
|
|
518694
|
+
const m2 = tail.match(/(Segmentation\s+fault|core\s+dumped|Abort(?:ed)?\s+\(core dumped\)|Killed)[^\n]{0,80}/i);
|
|
518695
|
+
return `Process terminated abnormally: ${(m2?.[0] ?? "").slice(0, 240)}`;
|
|
518630
518696
|
}
|
|
518631
518697
|
return null;
|
|
518632
518698
|
}
|
|
@@ -518683,6 +518749,7 @@ ${body}`;
|
|
|
518683
518749
|
if (/(^|[^&\d])(>|>>)\s*\S/.test(cmd))
|
|
518684
518750
|
return false;
|
|
518685
518751
|
const MUTATE_BINS = [
|
|
518752
|
+
// POSIX file/process mutators
|
|
518686
518753
|
"rm",
|
|
518687
518754
|
"mv",
|
|
518688
518755
|
"cp",
|
|
@@ -518690,56 +518757,158 @@ ${body}`;
|
|
|
518690
518757
|
"rmdir",
|
|
518691
518758
|
"chmod",
|
|
518692
518759
|
"chown",
|
|
518760
|
+
"chgrp",
|
|
518693
518761
|
"touch",
|
|
518694
518762
|
"tee",
|
|
518695
518763
|
"dd",
|
|
518696
518764
|
"truncate",
|
|
518697
518765
|
"ln",
|
|
518766
|
+
"install",
|
|
518698
518767
|
"kill",
|
|
518699
518768
|
"pkill",
|
|
518700
518769
|
"killall",
|
|
518701
518770
|
"reboot",
|
|
518702
518771
|
"shutdown",
|
|
518772
|
+
"halt",
|
|
518773
|
+
"poweroff",
|
|
518703
518774
|
"fakeroot",
|
|
518704
518775
|
"sudo",
|
|
518776
|
+
"doas",
|
|
518705
518777
|
"nohup",
|
|
518706
518778
|
"setsid",
|
|
518779
|
+
"su",
|
|
518780
|
+
// Build orchestrators (always trigger compile/test side-effects)
|
|
518707
518781
|
"make",
|
|
518782
|
+
"gmake",
|
|
518783
|
+
"ninja",
|
|
518708
518784
|
"gradle",
|
|
518785
|
+
"gradlew",
|
|
518709
518786
|
"mvn",
|
|
518787
|
+
"mvnw",
|
|
518788
|
+
"ant",
|
|
518789
|
+
"bazel",
|
|
518790
|
+
"buck",
|
|
518791
|
+
"buck2",
|
|
518792
|
+
"cmake",
|
|
518793
|
+
"meson",
|
|
518794
|
+
"scons",
|
|
518795
|
+
"rake",
|
|
518796
|
+
"leiningen",
|
|
518797
|
+
"lein",
|
|
518798
|
+
"sbt",
|
|
518799
|
+
"stack",
|
|
518800
|
+
// Configuration-management / orchestration
|
|
518710
518801
|
"ansible",
|
|
518711
|
-
"
|
|
518802
|
+
"ansible-playbook",
|
|
518803
|
+
"puppet",
|
|
518804
|
+
"chef-client",
|
|
518805
|
+
"salt",
|
|
518806
|
+
"salt-call",
|
|
518807
|
+
"systemd-run",
|
|
518808
|
+
"systemd-analyze",
|
|
518809
|
+
// System package managers
|
|
518810
|
+
"apt",
|
|
518811
|
+
"apt-get",
|
|
518812
|
+
"yum",
|
|
518813
|
+
"dnf",
|
|
518814
|
+
"rpm",
|
|
518815
|
+
"pacman",
|
|
518816
|
+
"zypper",
|
|
518817
|
+
"emerge",
|
|
518818
|
+
"snap",
|
|
518819
|
+
"flatpak",
|
|
518820
|
+
"brew",
|
|
518821
|
+
"port",
|
|
518822
|
+
"pkg",
|
|
518823
|
+
"apk",
|
|
518824
|
+
"choco",
|
|
518825
|
+
"scoop",
|
|
518826
|
+
"winget",
|
|
518827
|
+
// Helm / k8s-flavored
|
|
518828
|
+
"helm",
|
|
518829
|
+
"helmfile",
|
|
518830
|
+
"kustomize"
|
|
518712
518831
|
];
|
|
518713
518832
|
const mutateBinsRe = new RegExp(`\\b(${MUTATE_BINS.join("|")})\\b`, "i");
|
|
518714
518833
|
if (mutateBinsRe.test(cmd))
|
|
518715
518834
|
return false;
|
|
518716
518835
|
if (/\bsed\s+(-i|--in-place)\b/.test(cmd))
|
|
518717
518836
|
return false;
|
|
518718
|
-
if (/\bsystemctl\s+(?!status\b|show\b|is-)/i.test(cmd))
|
|
518837
|
+
if (/\bsystemctl\s+(?!status\b|show\b|is-|cat\b|list-|get-)/i.test(cmd))
|
|
518719
518838
|
return false;
|
|
518720
518839
|
if (/\bservice\s+\S+\s+(?!status\b)/i.test(cmd))
|
|
518721
518840
|
return false;
|
|
518722
518841
|
if (/\bcrontab\s+-(e|d|r)\b/.test(cmd))
|
|
518723
518842
|
return false;
|
|
518724
|
-
if (/\bnpm\s+(install|uninstall|update|run|test|exec|publish|init|link|unlink|version|cache\s+clean|ci|audit\s+fix)\b/i.test(cmd))
|
|
518725
|
-
return false;
|
|
518726
|
-
if (/\bpnpm\s+(install|update|add|remove|run|test|exec|publish|init|link|unlink|version)\b/i.test(cmd))
|
|
518843
|
+
if (/\bnpm\s+(install|i\b|uninstall|un\b|update|up\b|run\s|test\b|exec|publish|init|link|unlink|version|cache\s+clean|ci\b|audit\s+fix|prune|rebuild|adduser|login|logout|deprecate)\b/i.test(cmd))
|
|
518727
518844
|
return false;
|
|
518728
|
-
if (/\
|
|
518845
|
+
if (/\bpnpm\s+(install|i\b|update|up\b|add|remove|rm\b|run\s|test\b|exec|publish|init|link|unlink|version|prune|rebuild)\b/i.test(cmd))
|
|
518729
518846
|
return false;
|
|
518730
|
-
if (/\
|
|
518847
|
+
if (/\byarn\s+(install|add|remove|upgrade|run\s|test\b|exec|publish|init|link|unlink|version)\b/i.test(cmd))
|
|
518731
518848
|
return false;
|
|
518732
518849
|
if (/\bnpx\b/.test(cmd))
|
|
518733
518850
|
return false;
|
|
518734
|
-
if (/\
|
|
518851
|
+
if (/\bpip3?\s+(install|uninstall|wheel|download)\b/i.test(cmd))
|
|
518852
|
+
return false;
|
|
518853
|
+
if (/\bpipenv\s+(install|uninstall|run|update|sync)\b/i.test(cmd))
|
|
518854
|
+
return false;
|
|
518855
|
+
if (/\bpoetry\s+(add|install|run|update|remove|build|publish|init|new|export|lock)\b/i.test(cmd))
|
|
518856
|
+
return false;
|
|
518857
|
+
if (/\bconda\s+(install|remove|update|create|env\s+(create|update|remove))\b/i.test(cmd))
|
|
518858
|
+
return false;
|
|
518859
|
+
if (/\buv\s+(add|remove|sync|install|run|build|publish|pip\s+install)\b/i.test(cmd))
|
|
518860
|
+
return false;
|
|
518861
|
+
if (/\bbundle\s+(install|update|exec|add|remove|init)\b/i.test(cmd))
|
|
518862
|
+
return false;
|
|
518863
|
+
if (/\bgem\s+(install|uninstall|update|build|push|owner)\b/i.test(cmd))
|
|
518864
|
+
return false;
|
|
518865
|
+
if (/\bcpan\b|\bcpanm\b|\bperl\s+-MCPAN\b/i.test(cmd))
|
|
518866
|
+
return false;
|
|
518867
|
+
if (/\bcomposer\s+(install|update|require|remove|create-project|dump-autoload|run-script)\b/i.test(cmd))
|
|
518868
|
+
return false;
|
|
518869
|
+
if (/\bdotnet\s+(build|run|test|publish|pack|restore|add|remove|new|tool\s+install)\b/i.test(cmd))
|
|
518735
518870
|
return false;
|
|
518736
|
-
if (/\
|
|
518871
|
+
if (/\bcargo\s+(build|run|test|bench|update|publish|install|uninstall|fmt|fix|clippy\s+--fix|new|init|add|remove|generate-lockfile)\b/i.test(cmd))
|
|
518737
518872
|
return false;
|
|
518738
|
-
if (/\
|
|
518873
|
+
if (/\bgo\s+(build|run|test|get|install|generate|mod\s+(tidy|download|init|edit|vendor)|work\s+)\b/i.test(cmd))
|
|
518739
518874
|
return false;
|
|
518740
|
-
if (/\
|
|
518875
|
+
if (/\bdocker\s+(build|run|push|pull|exec|kill|stop|rm|rmi|tag|create|cp|commit|save|load|import|export|network\s+create|volume\s+create|compose\s+(up|down|build|run|exec|restart))\b/i.test(cmd))
|
|
518741
518876
|
return false;
|
|
518742
|
-
if (/\
|
|
518877
|
+
if (/\bpodman\s+(build|run|push|pull|exec|kill|stop|rm|rmi|tag|create|commit)\b/i.test(cmd))
|
|
518878
|
+
return false;
|
|
518879
|
+
if (/\bkubectl\s+(apply|delete|create|edit|patch|scale|rollout|exec|cp|drain|cordon|uncordon|taint|label|annotate|set\s)\b/i.test(cmd))
|
|
518880
|
+
return false;
|
|
518881
|
+
if (/\bterraform\s+(apply|destroy|init|plan|import|taint|untaint|workspace\s+(new|delete)|state\s+(rm|mv|push|replace-provider))\b/i.test(cmd))
|
|
518882
|
+
return false;
|
|
518883
|
+
if (/\bpulumi\s+(up|destroy|new|stack\s+(rm|init)|config\s+set|policy\s+enable|import)\b/i.test(cmd))
|
|
518884
|
+
return false;
|
|
518885
|
+
if (/\baws\s+(?:\S+\s+)+(create|delete|put|update|run|start|stop|terminate|attach|detach|cp|sync|mv)\b/i.test(cmd))
|
|
518886
|
+
return false;
|
|
518887
|
+
if (/\bgcloud\s+(?:\S+\s+)+(create|delete|update|deploy|apply|set|enable|disable|attach|detach|reset|move|sign-in|sign-out)\b/i.test(cmd))
|
|
518888
|
+
return false;
|
|
518889
|
+
if (/\baz\s+(?:\S+\s+)+(create|delete|update|deploy|set|attach|detach|reset|move)\b/i.test(cmd))
|
|
518890
|
+
return false;
|
|
518891
|
+
if (/\beslint\s+[^|;&]*--fix\b/i.test(cmd))
|
|
518892
|
+
return false;
|
|
518893
|
+
if (/\bprettier\s+[^|;&]*--write\b/i.test(cmd))
|
|
518894
|
+
return false;
|
|
518895
|
+
if (/\bblack\s+(?!--check\b)/i.test(cmd))
|
|
518896
|
+
return false;
|
|
518897
|
+
if (/\bisort\s+(?!--check\b|--diff\b)/i.test(cmd))
|
|
518898
|
+
return false;
|
|
518899
|
+
if (/\bruff\s+(?:format\b|check\s+[^|;&]*--fix\b)/i.test(cmd))
|
|
518900
|
+
return false;
|
|
518901
|
+
if (/\bgofmt\s+-w\b/i.test(cmd))
|
|
518902
|
+
return false;
|
|
518903
|
+
if (/\brustfmt\s+(?!--check\b)/i.test(cmd))
|
|
518904
|
+
return false;
|
|
518905
|
+
if (/\b(node|python\d?|ruby|perl|bash|sh|zsh|dash|fish)\s+-(e|c)\b/.test(cmd))
|
|
518906
|
+
return false;
|
|
518907
|
+
if (/\bcurl\s+[^|]*\|\s*(bash|sh|zsh|fish|python\d?|ruby|node|perl)\b/i.test(cmd))
|
|
518908
|
+
return false;
|
|
518909
|
+
if (/\bgit\s+(add|commit|push|pull|fetch|clone|init|checkout|switch|restore|reset|rm|mv|merge|rebase|cherry-pick|revert|stash|apply|am|tag(?:\s+\S)?|notes|worktree\s+(add|remove)|gc|prune|repack|filter-branch|filter-repo|reflog\s+(delete|expire)|update-ref|update-index|symbolic-ref|hash-object\s+-w)\b/i.test(cmd))
|
|
518910
|
+
return false;
|
|
518911
|
+
if (/\bollama\s+(pull|push|run|create|rm|cp|serve)\b/i.test(cmd))
|
|
518743
518912
|
return false;
|
|
518744
518913
|
const READ_ONLY_BINS = /* @__PURE__ */ new Set([
|
|
518745
518914
|
"cd",
|
|
@@ -518749,79 +518918,128 @@ ${body}`;
|
|
|
518749
518918
|
"fgrep",
|
|
518750
518919
|
"rg",
|
|
518751
518920
|
"ag",
|
|
518921
|
+
"ack",
|
|
518752
518922
|
"cat",
|
|
518753
518923
|
"head",
|
|
518754
518924
|
"tail",
|
|
518755
518925
|
"less",
|
|
518756
518926
|
"more",
|
|
518927
|
+
"bat",
|
|
518928
|
+
"tac",
|
|
518757
518929
|
"ls",
|
|
518758
518930
|
"ll",
|
|
518759
518931
|
"la",
|
|
518932
|
+
"tree",
|
|
518760
518933
|
"find",
|
|
518761
|
-
|
|
518934
|
+
"fd",
|
|
518935
|
+
// mutating actions pre-filtered above
|
|
518762
518936
|
"wc",
|
|
518763
518937
|
"awk",
|
|
518764
518938
|
"gawk",
|
|
518939
|
+
"mawk",
|
|
518940
|
+
"nawk",
|
|
518765
518941
|
"sort",
|
|
518766
518942
|
"uniq",
|
|
518943
|
+
"shuf",
|
|
518767
518944
|
"tr",
|
|
518768
518945
|
"cut",
|
|
518769
518946
|
"paste",
|
|
518770
518947
|
"join",
|
|
518771
518948
|
"comm",
|
|
518949
|
+
"column",
|
|
518950
|
+
"expand",
|
|
518951
|
+
"unexpand",
|
|
518772
518952
|
"diff",
|
|
518773
518953
|
"cmp",
|
|
518954
|
+
"patch",
|
|
518955
|
+
// patch with -R or no-args could be mutating; --dry-run only is read
|
|
518774
518956
|
"echo",
|
|
518775
518957
|
"printf",
|
|
518776
518958
|
"pwd",
|
|
518777
518959
|
"which",
|
|
518778
518960
|
"type",
|
|
518779
518961
|
"command",
|
|
518780
|
-
"
|
|
518781
|
-
"python",
|
|
518782
|
-
"python3",
|
|
518783
|
-
"ruby",
|
|
518784
|
-
"perl",
|
|
518962
|
+
"whereis",
|
|
518785
518963
|
"git",
|
|
518786
|
-
//
|
|
518964
|
+
// pre-filtered above for mutating subcommands
|
|
518787
518965
|
"ollama",
|
|
518788
|
-
//
|
|
518966
|
+
// pre-filtered above
|
|
518789
518967
|
"cargo",
|
|
518790
|
-
// pre-filtered above for build/run/etc.
|
|
518791
518968
|
"go",
|
|
518792
|
-
|
|
518969
|
+
"rustc",
|
|
518970
|
+
// bin-only forms are read; mutating subcommands pre-filtered
|
|
518793
518971
|
"stat",
|
|
518794
518972
|
"file",
|
|
518795
518973
|
"du",
|
|
518796
518974
|
"df",
|
|
518975
|
+
"lsof",
|
|
518976
|
+
"fuser",
|
|
518797
518977
|
"date",
|
|
518798
518978
|
"uname",
|
|
518799
518979
|
"id",
|
|
518800
518980
|
"whoami",
|
|
518801
518981
|
"hostname",
|
|
518802
518982
|
"uptime",
|
|
518983
|
+
"tty",
|
|
518803
518984
|
"env",
|
|
518804
518985
|
"printenv",
|
|
518986
|
+
"set",
|
|
518805
518987
|
"test",
|
|
518806
518988
|
"[",
|
|
518807
518989
|
"true",
|
|
518808
518990
|
"false",
|
|
518991
|
+
"yes",
|
|
518992
|
+
"seq",
|
|
518809
518993
|
"tsc",
|
|
518810
518994
|
"eslint",
|
|
518811
518995
|
"prettier",
|
|
518812
|
-
|
|
518813
|
-
"
|
|
518814
|
-
"
|
|
518996
|
+
"ruff",
|
|
518997
|
+
"black",
|
|
518998
|
+
"isort",
|
|
518999
|
+
"rustfmt",
|
|
519000
|
+
"gofmt",
|
|
519001
|
+
// Linters/formatters: mutating modes pre-filtered above (--fix/--write/-w/-i),
|
|
519002
|
+
// so reaching here means we have a check-only invocation.
|
|
518815
519003
|
"jq",
|
|
518816
519004
|
"yq",
|
|
518817
519005
|
"xq",
|
|
519006
|
+
"tomlq",
|
|
519007
|
+
"fx",
|
|
518818
519008
|
"base64",
|
|
518819
519009
|
"md5sum",
|
|
518820
519010
|
"sha256sum",
|
|
518821
519011
|
"sha1sum",
|
|
519012
|
+
"sha512sum",
|
|
518822
519013
|
"tldr",
|
|
518823
519014
|
"man",
|
|
518824
|
-
"info"
|
|
519015
|
+
"info",
|
|
519016
|
+
"help",
|
|
519017
|
+
"pip",
|
|
519018
|
+
"pip3",
|
|
519019
|
+
"pipenv",
|
|
519020
|
+
"poetry",
|
|
519021
|
+
"uv",
|
|
519022
|
+
"conda",
|
|
519023
|
+
// pre-filtered above for mutating subcommands
|
|
519024
|
+
"npm",
|
|
519025
|
+
"pnpm",
|
|
519026
|
+
"yarn",
|
|
519027
|
+
// pre-filtered above
|
|
519028
|
+
"kubectl",
|
|
519029
|
+
"terraform",
|
|
519030
|
+
"pulumi",
|
|
519031
|
+
"aws",
|
|
519032
|
+
"gcloud",
|
|
519033
|
+
"az",
|
|
519034
|
+
// pre-filtered above
|
|
519035
|
+
"docker",
|
|
519036
|
+
"podman",
|
|
519037
|
+
// pre-filtered above
|
|
519038
|
+
"composer",
|
|
519039
|
+
"dotnet",
|
|
519040
|
+
"bundle",
|
|
519041
|
+
"gem"
|
|
519042
|
+
// pre-filtered above
|
|
518825
519043
|
]);
|
|
518826
519044
|
if (/\bfind\b[\s\S]*?(-delete|-exec\s+(rm|mv|cp|chmod|chown|sed\s+-i)|--?ok\s+(rm|mv))/i.test(cmd))
|
|
518827
519045
|
return false;
|
|
@@ -518830,11 +519048,42 @@ ${body}`;
|
|
|
518830
519048
|
const segments = cmd.split(/(?:\|\||&&|;)/).map((s2) => s2.trim()).filter(Boolean);
|
|
518831
519049
|
if (segments.length === 0)
|
|
518832
519050
|
return false;
|
|
519051
|
+
const SAFE_INTERP_FLAGS = /^(?:--version|--help|-V|-v|-h|--vers|version)$/;
|
|
519052
|
+
const INTERPRETER_BINS = /* @__PURE__ */ new Set([
|
|
519053
|
+
"node",
|
|
519054
|
+
"python",
|
|
519055
|
+
"python2",
|
|
519056
|
+
"python3",
|
|
519057
|
+
"ruby",
|
|
519058
|
+
"perl",
|
|
519059
|
+
"php",
|
|
519060
|
+
"lua",
|
|
519061
|
+
"bash",
|
|
519062
|
+
"sh",
|
|
519063
|
+
"zsh",
|
|
519064
|
+
"dash",
|
|
519065
|
+
"fish",
|
|
519066
|
+
"ksh",
|
|
519067
|
+
"tcsh",
|
|
519068
|
+
"java",
|
|
519069
|
+
"kotlin",
|
|
519070
|
+
"scala",
|
|
519071
|
+
"groovy"
|
|
519072
|
+
]);
|
|
518833
519073
|
for (const seg of segments) {
|
|
518834
519074
|
const stripped = seg.replace(/^cd\s+\S+\s*$/i, "true").replace(/^!/, "");
|
|
518835
|
-
const
|
|
519075
|
+
const tokens = stripped.split(/\s+/).filter(Boolean);
|
|
519076
|
+
const firstTok = (tokens[0] ?? "").replace(/^.*\//, "");
|
|
518836
519077
|
if (!firstTok)
|
|
518837
519078
|
continue;
|
|
519079
|
+
if (INTERPRETER_BINS.has(firstTok)) {
|
|
519080
|
+
const restToks = tokens.slice(1);
|
|
519081
|
+
if (restToks.length === 0)
|
|
519082
|
+
return false;
|
|
519083
|
+
if (!restToks.every((t2) => SAFE_INTERP_FLAGS.test(t2)))
|
|
519084
|
+
return false;
|
|
519085
|
+
continue;
|
|
519086
|
+
}
|
|
518838
519087
|
if (!READ_ONLY_BINS.has(firstTok))
|
|
518839
519088
|
return false;
|
|
518840
519089
|
}
|
|
@@ -518843,10 +519092,11 @@ ${body}`;
|
|
|
518843
519092
|
/**
|
|
518844
519093
|
* REG-5: Render the recent-failures block so the agent SEES its own error
|
|
518845
519094
|
* output before deciding what to do next. Detects same-fingerprint failure
|
|
518846
|
-
* repetition and escalates the warning. Without this, the agent runs
|
|
518847
|
-
*
|
|
518848
|
-
*
|
|
518849
|
-
*
|
|
519095
|
+
* repetition and escalates the warning. Without this, the agent runs a
|
|
519096
|
+
* build/test/install command, gets a long error stream from the
|
|
519097
|
+
* underlying compiler/runner, ignores the specific error, and blindly
|
|
519098
|
+
* retries with a different flag combination. Caching the failure +
|
|
519099
|
+
* injecting it pre-LLM forces the model to confront what actually broke.
|
|
518850
519100
|
*/
|
|
518851
519101
|
_renderRecentFailuresBlock(turn) {
|
|
518852
519102
|
const fails = this._recentFailures;
|
|
@@ -520429,6 +520679,8 @@ ${memoryLines.join("\n")}`
|
|
|
520429
520679
|
for (const [tool2, budget] of Object.entries(toolBudgets)) {
|
|
520430
520680
|
toolCallBudget.set(tool2, budget);
|
|
520431
520681
|
}
|
|
520682
|
+
this._writesSinceLastTodoWrite = 0;
|
|
520683
|
+
this._progressGateActive = false;
|
|
520432
520684
|
this.emit({
|
|
520433
520685
|
type: "status",
|
|
520434
520686
|
content: `Tool budgets reset for new phase (${Object.keys(toolBudgets).length} tools)`,
|
|
@@ -520436,6 +520688,55 @@ ${memoryLines.join("\n")}`
|
|
|
520436
520688
|
});
|
|
520437
520689
|
}
|
|
520438
520690
|
}
|
|
520691
|
+
const PROGRESS_GATE_BYPASS_TOOLS = /* @__PURE__ */ new Set([
|
|
520692
|
+
"todo_write",
|
|
520693
|
+
"todo_read",
|
|
520694
|
+
"task_complete",
|
|
520695
|
+
"ask_user",
|
|
520696
|
+
"phase_recall"
|
|
520697
|
+
// useful for the agent to consult prior phase state before updating
|
|
520698
|
+
]);
|
|
520699
|
+
if (this._progressGateActive && !PROGRESS_GATE_BYPASS_TOOLS.has(tc.name)) {
|
|
520700
|
+
this.emit({
|
|
520701
|
+
type: "tool_call",
|
|
520702
|
+
toolName: tc.name,
|
|
520703
|
+
toolArgs: tc.arguments,
|
|
520704
|
+
turn,
|
|
520705
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
520706
|
+
});
|
|
520707
|
+
const recentWrites = [];
|
|
520708
|
+
for (const [path8, info] of this._worldFacts.files) {
|
|
520709
|
+
if ((info.writeCount ?? 0) > 0 && (info.lastWriteTurn ?? -1) >= 0 && turn - (info.lastWriteTurn ?? 0) <= 8) {
|
|
520710
|
+
recentWrites.push({ path: path8, turn: info.lastWriteTurn ?? 0 });
|
|
520711
|
+
}
|
|
520712
|
+
}
|
|
520713
|
+
recentWrites.sort((a2, b) => b.turn - a2.turn);
|
|
520714
|
+
const showWrites = recentWrites.slice(0, 16);
|
|
520715
|
+
const gateMsg = [
|
|
520716
|
+
`[PROGRESS GATE — call todo_write FIRST before any other tool]`,
|
|
520717
|
+
``,
|
|
520718
|
+
`You have completed ${this._writesSinceLastTodoWrite} file modification${this._writesSinceLastTodoWrite === 1 ? "" : "s"} since your last todo_write call.`,
|
|
520719
|
+
`The next tool call MUST be todo_write to mark progress. This is enforced — non-todo tool calls are intercepted until plan state is updated.`,
|
|
520720
|
+
``,
|
|
520721
|
+
`Recent file modifications (use these to decide what's done):`,
|
|
520722
|
+
...showWrites.map((w) => ` • ${w.path} (turn ${w.turn})`),
|
|
520723
|
+
recentWrites.length > showWrites.length ? ` • ... +${recentWrites.length - showWrites.length} more` : "",
|
|
520724
|
+
``,
|
|
520725
|
+
`Required action: call todo_write with the updated todo array — mark anything completed that these writes satisfy, advance the next item to in_progress, keep the rest pending.`,
|
|
520726
|
+
`After todo_write succeeds, this gate releases and you can continue normal work.`,
|
|
520727
|
+
``,
|
|
520728
|
+
`Why this exists: without the explicit progress update, your next turn will see the same in_progress todo, re-plan the same work, and re-emit identical tool calls (the "plan replay" failure mode that causes byte-identical writes to appear twice).`
|
|
520729
|
+
].filter(Boolean).join("\n");
|
|
520730
|
+
this.emit({
|
|
520731
|
+
type: "tool_result",
|
|
520732
|
+
toolName: tc.name,
|
|
520733
|
+
success: false,
|
|
520734
|
+
content: gateMsg.slice(0, 120),
|
|
520735
|
+
turn,
|
|
520736
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
520737
|
+
});
|
|
520738
|
+
return { tc, output: gateMsg };
|
|
520739
|
+
}
|
|
520439
520740
|
const _argsKeyForBudget = `${tc.name}:${argsKey}`;
|
|
520440
520741
|
const _isCachedHit = recentToolResults.has(_argsKeyForBudget);
|
|
520441
520742
|
const budgetRemaining = toolCallBudget.get(tc.name);
|
|
@@ -520654,10 +520955,26 @@ ${cachedEntry2.result.slice(0, 500)}` : `[BLOCKED — the observer confirmed thi
|
|
|
520654
520955
|
writeCount: (prev?.writeCount ?? 0) + 1
|
|
520655
520956
|
});
|
|
520656
520957
|
this._writesSinceLastTodoWrite++;
|
|
520958
|
+
if (this._writesSinceLastTodoWrite >= 6 && !this._progressGateActive) {
|
|
520959
|
+
this._progressGateActive = true;
|
|
520960
|
+
this.emit({
|
|
520961
|
+
type: "status",
|
|
520962
|
+
content: `Progress gate engaged at ${this._writesSinceLastTodoWrite} writes without todo_write — non-todo tools will be blocked until plan is updated`,
|
|
520963
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
520964
|
+
});
|
|
520965
|
+
}
|
|
520657
520966
|
}
|
|
520658
520967
|
}
|
|
520659
520968
|
if (tc.name === "todo_write" && result.success) {
|
|
520969
|
+
if (this._progressGateActive) {
|
|
520970
|
+
this.emit({
|
|
520971
|
+
type: "status",
|
|
520972
|
+
content: "Progress gate released — todo_write acknowledged",
|
|
520973
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
520974
|
+
});
|
|
520975
|
+
}
|
|
520660
520976
|
this._writesSinceLastTodoWrite = 0;
|
|
520977
|
+
this._progressGateActive = false;
|
|
520661
520978
|
}
|
|
520662
520979
|
if (tc.name === "file_read") {
|
|
520663
520980
|
const p2 = String(tc.arguments?.["path"] ?? tc.arguments?.["file"] ?? "");
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "open-agents-ai",
|
|
3
|
-
"version": "0.187.
|
|
3
|
+
"version": "0.187.469",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "open-agents-ai",
|
|
9
|
-
"version": "0.187.
|
|
9
|
+
"version": "0.187.469",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "CC-BY-NC-4.0",
|
|
12
12
|
"dependencies": {
|
package/package.json
CHANGED