open-agents-ai 0.187.495 → 0.187.497
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/README.md +138 -0
- package/dist/index.js +1590 -1219
- package/npm-shrinkwrap.json +2 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -67,6 +67,7 @@ An autonomous multi-turn tool-calling agent that reads your code, makes changes,
|
|
|
67
67
|
- [ETag + Conditional GET](#etag--conditional-get)
|
|
68
68
|
- [Web Interface](#web-interface)
|
|
69
69
|
- [Architecture](#architecture)
|
|
70
|
+
- [Failure-Mode Defense Stack — How Small Models Stay Productive](#failure-mode-defense-stack--how-small-models-stay-productive)
|
|
70
71
|
- [Context Engineering](#context-engineering)
|
|
71
72
|
- [Model-Tier Awareness](#model-tier-awareness)
|
|
72
73
|
- [Small Model Optimization (Research-Backed)](#small-model-optimization-research-backed)
|
|
@@ -1737,6 +1738,143 @@ User task → assembleContext(c_instr, c_state, c_know) → LLM → tool_calls
|
|
|
1737
1738
|
|
|
1738
1739
|
|
|
1739
1740
|
|
|
1741
|
+
## Failure-Mode Defense Stack — How Small Models Stay Productive
|
|
1742
|
+
|
|
1743
|
+
<div align="right"><a href="#top">back to top</a></div>
|
|
1744
|
+
|
|
1745
|
+
Small open-weight models (9B-35B) hit specific failure modes that crush long-horizon coding runs: **read-cycling** (re-listing directories the agent already saw), **cache-blocked thrash** (re-issuing identical tool calls), **specification drift** (test imports a symbol the source never exports), **false-claim completions** (`task_complete` fired before tests pass), and **stream-vs-state context collapse** (agent re-derives workdir state from message history instead of seeing it directly).
|
|
1746
|
+
|
|
1747
|
+
Open Agents ships a layered defense stack — six small composable interventions, each addressing a specific failure mode, each with a literature anchor. They activate via env vars and emit telemetry status events so you can confirm them firing.
|
|
1748
|
+
|
|
1749
|
+
### REG-44 — Generic STUCK detector
|
|
1750
|
+
|
|
1751
|
+
Three structural triggers in a 15-tool-call window — ANY one fires a CRITICAL halt with four escape directives (PRODUCE / WEB SEARCH / DEBATE / DECLARE BLOCKED):
|
|
1752
|
+
- **T1**: reads/exploration ≥ 9 AND mutations ≤ 2 (read-heavy thrash)
|
|
1753
|
+
- **T2**: stale-result rate ≥ 50% (cache-blocked / no-op / forced-progress markers)
|
|
1754
|
+
- **T3**: zero mutations in a 12+ window (pure read window)
|
|
1755
|
+
|
|
1756
|
+
Generic across stacks — purely structural counts of tool names + result text markers; no framework keywords.
|
|
1757
|
+
*Lit anchor*: Yao 2024 (Tree-of-Thoughts) bounded-action-budget pattern; reflection-paralysis literature.
|
|
1758
|
+
|
|
1759
|
+
### REG-45 — Sticky cross-turn escalation
|
|
1760
|
+
|
|
1761
|
+
When a tool stem accumulates ≥ 3 attempts OR ≥ 3 distinct error signatures, its reflection becomes "sticky" — surfaced at top-of-turn every turn until the underlying failure clears, even when the agent stops re-emitting the failed stem. Capped at 2 surfaces/turn, prioritized by attempt count.
|
|
1762
|
+
*Lit anchor*: Reflexion (Shinn et al. NeurIPS 2024) — verbal reinforcement via persisted failure memory.
|
|
1763
|
+
|
|
1764
|
+
### REG-46 — Periodic world-state regeneration
|
|
1765
|
+
|
|
1766
|
+
The deep root cause of small-model stuck patterns: **context is a stream of past actions, not a state of the present world.** The agent's questions ("what files exist?", "what's left in the plan?") are correct but the system answers them with negatives ("you can't ask again — cached") instead of positives ("here's the state").
|
|
1767
|
+
|
|
1768
|
+
Every 8 turns OR after 5+ file_writes OR after a build success, the orchestrator regenerates a `<world-state>` snapshot:
|
|
1769
|
+
|
|
1770
|
+
```
|
|
1771
|
+
<world-state turn="32" trigger="file_writes_threshold">
|
|
1772
|
+
GOAL: <original user task — survives compaction>
|
|
1773
|
+
WORKSPACE FACTS: 56 files, last modified src/components/MapBlock.tsx (12s ago)
|
|
1774
|
+
PLAN STATUS (reconciled against disk):
|
|
1775
|
+
[OK] Build cache module — 1 artifact present
|
|
1776
|
+
[MISS] Wire data feeds — declared `src/lib/feeds.ts` (missing on disk)
|
|
1777
|
+
[pending] Run tests
|
|
1778
|
+
RECENT UNRESOLVED FAILURES: (none)
|
|
1779
|
+
SUGGESTED NEXT STEP: A completed todo claims a missing artifact...
|
|
1780
|
+
</world-state>
|
|
1781
|
+
```
|
|
1782
|
+
|
|
1783
|
+
Prior `<world-state>` blocks are stripped before injecting the freshest one — only the current snapshot lives in context. Plan reconciliation uses `verifyCommand` + `declaredArtifacts` from the todo store + heuristic filename matching. Disk scan is gitignore-aware, capped at 200 files. Generic across stacks.
|
|
1784
|
+
*Lit anchors*: MetaGPT (Hong et al. ICLR 2024) — SOP-encoded state representation; AlphaCodium (Pinto 2024) — symbol-aware iteration.
|
|
1785
|
+
|
|
1786
|
+
Configurable via `OA_WORLD_STATE_INTERVAL` (default 8), `OA_WORLD_STATE_FILE_WRITE_THRESHOLD` (default 5), `OA_WORLD_STATE_MAX_FILES` (default 200).
|
|
1787
|
+
|
|
1788
|
+
### REG-47 — Backward-pass critic on `task_complete`
|
|
1789
|
+
|
|
1790
|
+
When the agent calls `task_complete` AND ≥ 1 file mutation occurred AND `OA_BACKWARD_PASS=on`, the orchestrator spawns a dedicated CRITIC sub-agent against the same backend. The critic gets the diff + plan reconciliation + recent failures + a 10-point structural audit checklist (dead refs, missing imports, off-by-one, null-handling, stateful regex, hardcoded paths, untested code paths, plan-disk gaps, unresolved failures, generic-vs-specific drift) and votes:
|
|
1791
|
+
- **approve** → task_complete proceeds, run terminates
|
|
1792
|
+
- **request_changes** → issue feedback injected as a system message; agent loops to address
|
|
1793
|
+
- **reject** → critical event; same as request_changes but with escalation marker
|
|
1794
|
+
|
|
1795
|
+
Cycle-bounded (default 2 cycles before fail-soft). Default OFF — explicit opt-in via `OA_BACKWARD_PASS=on`.
|
|
1796
|
+
*Lit anchors*: Self-Refine (Madaan et al. NeurIPS 2024) — +6-12% HumanEval correctness from a dedicated reviewer; CodeT (Chen et al. arxiv 2306.03907) — critic-contested implementer claims.
|
|
1797
|
+
|
|
1798
|
+
### REG-48 — Cross-file specification drift detection
|
|
1799
|
+
|
|
1800
|
+
The drift failure mode: a consumer file imports a symbol that the producer file doesn't export. Build may pass (lenient compilers tolerate unresolved imports if not actually called); tests fail; agent has to triangulate which side is wrong by reading dozens of files.
|
|
1801
|
+
|
|
1802
|
+
REG-48 parses each modified TS/JS file's imports + exports + path aliases (sourced from project `tsconfig.json` `compilerOptions.paths`, no hardcoded ecosystem defaults), and flags every import that doesn't match a real export. Surfaces a `CROSS-FILE DRIFT` block in the world-state snapshot:
|
|
1803
|
+
|
|
1804
|
+
```
|
|
1805
|
+
CROSS-FILE DRIFT (3 mismatches detected):
|
|
1806
|
+
- src/components/MapBlock.tsx:3
|
|
1807
|
+
imports `GeoPoint` from '@/types/metrics'
|
|
1808
|
+
but the source exports: AirQualityData, ElevationData, ...
|
|
1809
|
+
- tests/cache.test.ts:2
|
|
1810
|
+
imports `cacheGet` from '@/lib/cache'
|
|
1811
|
+
but the source exports: CacheEntry, cache
|
|
1812
|
+
Pick ONE side to fix per mismatch...
|
|
1813
|
+
```
|
|
1814
|
+
|
|
1815
|
+
Pre-shipping backtest against a stuck run's workdir detected 19 real drift entries in <100ms — exactly the bugs that had stalled the agent for 20+ minutes manually. Generic across stacks; only ES-style imports/exports parsed; non-JS/TS files silently skip.
|
|
1816
|
+
*Lit anchors*: MetaGPT (Hong et al. ICLR 2024) — interface contracts; AlphaCodium (Pinto 2024) — symbol-level awareness.
|
|
1817
|
+
|
|
1818
|
+
### Result: Run #19 — first end-to-end spec implementation on a 35B local model
|
|
1819
|
+
|
|
1820
|
+
With REG-43..48 active, on **`open-agents-qwen36:latest`** (Qwen 3.6, 35B, local Ollama, no cloud), the agent implemented a 49KB Next.js + Prisma + SQLite + Tailwind + Vitest geospatial dashboard spec end-to-end:
|
|
1821
|
+
|
|
1822
|
+
```
|
|
1823
|
+
duration: 33m 27s
|
|
1824
|
+
turns: 39
|
|
1825
|
+
tool calls: 216
|
|
1826
|
+
tokens: 3,533,665
|
|
1827
|
+
files written: 62
|
|
1828
|
+
task_complete: 3 attempts (REG-47 critic rejected 2, approved 3rd)
|
|
1829
|
+
|
|
1830
|
+
verification at termination — all green:
|
|
1831
|
+
✅ npx prisma migrate dev --name init — migration applied
|
|
1832
|
+
✅ npx tsc --noEmit — 0 errors
|
|
1833
|
+
✅ npm run build — Next.js 5 pages built
|
|
1834
|
+
✅ npm test — 6/6 tests passed
|
|
1835
|
+
```
|
|
1836
|
+
|
|
1837
|
+
The REG-47 critic intervention is the most interesting moment: the agent's first two `task_complete` attempts were rejected, forcing re-verification. During the second cycle the agent ran `npx tsc --noEmit` and **caught a real type error** (`tests/geospatial.test.ts(14,36): Expected 0 arguments, but got 2`) that the agent's own claim had hidden. The third `task_complete` — with a tighter, evidence-backed summary — was approved, and the run terminated cleanly.
|
|
1838
|
+
|
|
1839
|
+
Without REG-47, the run would have shipped a false-success completion with a real test bug.
|
|
1840
|
+
|
|
1841
|
+
Run-by-run progression of the orchestrator:
|
|
1842
|
+
|
|
1843
|
+
| Run | Defenses | Outcome | Files | Build | Tests |
|
|
1844
|
+
|-----|----------|---------|-------|-------|-------|
|
|
1845
|
+
| #15 | none | 2-hour timeout, shell-thrash | unknown | ✗ | ✗ |
|
|
1846
|
+
| #17 | REG-43 only | killed @ 13m, 33-file plateau | 33 (stalled) | ✗ | ✗ |
|
|
1847
|
+
| #18 | 43/44/45/46/47 | killed @ ~30m, 8/9 phases done, test-debug stuck | 62 | ✓ | partial |
|
|
1848
|
+
| **#19** | **43/44/45/46/47/48** | **completed cleanly** | **62** | **✓** | **6/6 pass** |
|
|
1849
|
+
|
|
1850
|
+
Detailed archival report: [`.aiwg/oa-eval/RESULTS-RUN-19.md`](.aiwg/oa-eval/RESULTS-RUN-19.md).
|
|
1851
|
+
|
|
1852
|
+
### Configuration summary
|
|
1853
|
+
|
|
1854
|
+
```bash
|
|
1855
|
+
# Defense activation (set in daemon env or systemd unit)
|
|
1856
|
+
OA_BACKWARD_PASS=on # enable REG-47 critic (default: off)
|
|
1857
|
+
OA_BACKWARD_PASS_MAX_CYCLES=2 # max review iterations
|
|
1858
|
+
OA_BACKWARD_PASS_MIN_WRITES=1 # min file mutations to trigger review
|
|
1859
|
+
OA_BACKWARD_PASS_TIMEOUT_MS=120000 # critic call timeout
|
|
1860
|
+
OA_BACKWARD_PASS_MAX_TOKENS=4096 # critic response cap
|
|
1861
|
+
OA_BACKWARD_PASS_MAX_FILES=60 # max files in critic prompt
|
|
1862
|
+
OA_BACKWARD_PASS_MAX_FILE_PREVIEW=8000
|
|
1863
|
+
|
|
1864
|
+
OA_WORLD_STATE_INTERVAL=8 # REG-46 turn-cadence (default: 8)
|
|
1865
|
+
OA_WORLD_STATE_FILE_WRITE_THRESHOLD=5 # REG-46 write-trigger (default: 5)
|
|
1866
|
+
OA_WORLD_STATE_MAX_FILES=200 # REG-46 disk-scan cap
|
|
1867
|
+
|
|
1868
|
+
OA_WORLD_STATE_DRIFT=on # REG-48 drift detector (default: on)
|
|
1869
|
+
OA_DRIFT_ALIASES='{"~/":"src/"}' # extra path aliases (JSON)
|
|
1870
|
+
|
|
1871
|
+
OA_RUN_RETENTION_H=24 # run-record GC (default: 24h, 0 disables)
|
|
1872
|
+
OA_TOOL_OVERRIDES='{"shell":{"off_device_allowed":true}}' # per-tool security overrides
|
|
1873
|
+
```
|
|
1874
|
+
|
|
1875
|
+
|
|
1876
|
+
|
|
1877
|
+
|
|
1740
1878
|
## Context Engineering
|
|
1741
1879
|
|
|
1742
1880
|
<div align="right"><a href="#top">back to top</a></div>
|