@tangle-network/agent-runtime 0.46.0 → 0.47.0
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/agent.d.ts +1 -1
- package/dist/agent.js +1 -1
- package/dist/analyst-loop.d.ts +1 -1
- package/dist/{chunk-I42NHLKX.js → chunk-5YDS7BLC.js} +11 -6
- package/dist/chunk-5YDS7BLC.js.map +1 -0
- package/dist/{chunk-65FQLI4V.js → chunk-72JQCHOZ.js} +232 -3
- package/dist/chunk-72JQCHOZ.js.map +1 -0
- package/dist/{chunk-GN75RGM6.js → chunk-MGFEUYOH.js} +3 -3
- package/dist/{chunk-KPN7OQ64.js → chunk-T4OQQEE3.js} +2 -2
- package/dist/{chunk-KPN7OQ64.js.map → chunk-T4OQQEE3.js.map} +1 -1
- package/dist/{coder-DCWFQpmJ.d.ts → coder-CVZNGbyg.d.ts} +1 -1
- package/dist/{driver-C-mtBo7h.d.ts → driver-DYU2sgHr.d.ts} +1 -1
- package/dist/index.d.ts +7 -7
- package/dist/index.js +3 -3
- package/dist/{kb-gate-2Gwpz_27.d.ts → kb-gate-51BlLlVM.d.ts} +8 -2
- package/dist/{loop-runner-bin-D-K6bRp3.d.ts → loop-runner-bin-DEm4roYF.d.ts} +4 -4
- package/dist/loop-runner-bin.d.ts +5 -5
- package/dist/loop-runner-bin.js +3 -3
- package/dist/loops.d.ts +5 -5
- package/dist/loops.js +9 -1
- package/dist/mcp/bin.js +3 -3
- package/dist/mcp/index.d.ts +71 -70
- package/dist/mcp/index.js +199 -27
- package/dist/mcp/index.js.map +1 -1
- package/dist/{otel-export-nurzFwuJ.d.ts → otel-export-EzfsVUhh.d.ts} +1 -1
- package/dist/profiles.d.ts +2 -2
- package/dist/{run-loop-CU2Y00Si.d.ts → run-loop-DvD4aGiE.d.ts} +1 -1
- package/dist/runtime.d.ts +96 -13
- package/dist/runtime.js +9 -1
- package/dist/{types-BfoeiQRZ.d.ts → types-Cbx3dNK5.d.ts} +4 -4
- package/dist/{types-DnYoHvvZ.d.ts → types-nBMuollC.d.ts} +17 -0
- package/dist/workflow.d.ts +2 -2
- package/dist/workflow.js +1 -1
- package/package.json +24 -13
- package/skills/loop-writer/SKILL.md +163 -0
- package/dist/chunk-65FQLI4V.js.map +0 -1
- package/dist/chunk-I42NHLKX.js.map +0 -1
- /package/dist/{chunk-GN75RGM6.js.map → chunk-MGFEUYOH.js.map} +0 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: loop-writer
|
|
3
|
+
description: Author clean recursive agent loops on @tangle-network/agent-runtime. Use for Scope/supervisor orchestration, runLoop, Pi/sandbox drivers, fanout, trace analysts, verifiers/judges, question escalation, live messages, and self-improving loop recipes.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# loop-writer
|
|
7
|
+
|
|
8
|
+
Design the smallest loop that can honestly solve the objective. The blessed
|
|
9
|
+
surface is the substrate: `fanout`/`pipeline` for fixed shapes, `runLoop` for
|
|
10
|
+
round-synchronous sandbox loops, and `Scope`/Supervisor for recursive
|
|
11
|
+
driver/worker trees. Do not create a second loop grammar.
|
|
12
|
+
|
|
13
|
+
## Mental Model
|
|
14
|
+
|
|
15
|
+
```txt
|
|
16
|
+
user -> Pi/root driver -> supervisor -> sandbox driver -> worker -> leaf harness
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Each level may spawn below, wait below, analyze below, steer below, and escalate
|
|
20
|
+
questions upward. The substrate owns budget, trace, abort, journal, and replay.
|
|
21
|
+
The driver owns strategy.
|
|
22
|
+
|
|
23
|
+
## Pick The Primitive
|
|
24
|
+
|
|
25
|
+
| Objective | Use |
|
|
26
|
+
|---|---|
|
|
27
|
+
| Try N attempts, pick best | `fanout` or `createFanoutVoteDriver` |
|
|
28
|
+
| Ordered stages | `pipeline` |
|
|
29
|
+
| Improve until executable check passes | `loopUntil` + verifier |
|
|
30
|
+
| Review from several lenses | `panel` |
|
|
31
|
+
| Simulated user/product eval | `defineConversation` + `runConversation` |
|
|
32
|
+
| Dynamic topology / drivers of drivers | `Scope` or sandbox driver + `createCoordinationTools` |
|
|
33
|
+
| Mutate a shared repo | git branch/clone loop with typed merge outcomes |
|
|
34
|
+
|
|
35
|
+
If a fixed combinator solves it, do not use a dynamic driver.
|
|
36
|
+
|
|
37
|
+
## Minimal Sandbox Loop
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
const trace: unknown[] = []
|
|
41
|
+
const result = await runLoop({
|
|
42
|
+
driver: createDriver({ planner, maxIterations: 4 }),
|
|
43
|
+
agentRun: agentRunSpec,
|
|
44
|
+
output,
|
|
45
|
+
validator: executableGate,
|
|
46
|
+
task,
|
|
47
|
+
ctx: {
|
|
48
|
+
sandboxClient,
|
|
49
|
+
traceEmitter: { emit: async (event) => trace.push(event) },
|
|
50
|
+
},
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
const observation = await observe(
|
|
54
|
+
{
|
|
55
|
+
task: String(task),
|
|
56
|
+
output: JSON.stringify(result.winner?.output ?? result.decision),
|
|
57
|
+
trace,
|
|
58
|
+
outcome: result.winner ? 'passed' : 'failed',
|
|
59
|
+
runId,
|
|
60
|
+
},
|
|
61
|
+
{ chat, model, corpus },
|
|
62
|
+
)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Minimal Recursive Driver
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
const driver: Agent<Task, Output> = {
|
|
69
|
+
name: 'secure-build-driver',
|
|
70
|
+
async act(task, scope) {
|
|
71
|
+
const spawned = scope.spawn(workerAgent, task, { budget: perWorker, label: 'worker-a' })
|
|
72
|
+
if (!spawned.ok) throw new Error(spawned.reason)
|
|
73
|
+
|
|
74
|
+
const settled = await scope.next()
|
|
75
|
+
const observation = await observe(
|
|
76
|
+
{
|
|
77
|
+
task: String(task),
|
|
78
|
+
output: JSON.stringify(settled),
|
|
79
|
+
trace: [settled, scope.view],
|
|
80
|
+
outcome: settled?.kind === 'done' ? 'passed' : 'failed',
|
|
81
|
+
runId,
|
|
82
|
+
},
|
|
83
|
+
{ chat, model, corpus },
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
const steer = observation.findings[0]?.recommended_action
|
|
87
|
+
if (!steer) return synthesize(settled, observation)
|
|
88
|
+
|
|
89
|
+
const correction = scope.spawn(workerAgent, { task, prior: settled }, {
|
|
90
|
+
budget: perWorker,
|
|
91
|
+
label: 'worker-corrected',
|
|
92
|
+
})
|
|
93
|
+
if (!correction.ok) throw new Error(correction.reason)
|
|
94
|
+
if (!scope.send(correction.handle.id, { steer })) throw new Error('steer delivery failed')
|
|
95
|
+
|
|
96
|
+
const fixed = await scope.next()
|
|
97
|
+
return synthesize(fixed, observation)
|
|
98
|
+
},
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const result = await createSupervisor<Task, Output>().run(driver, task, supervisorOpts)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
When the driver lives in a sandbox, expose the same verbs through
|
|
105
|
+
`createCoordinationTools`: `spawn_worker`, `await_next`, `observe_worker`,
|
|
106
|
+
`steer_worker`, `list_questions`, `answer_question`, `ask_parent`, `stop`, and
|
|
107
|
+
optional analyst tools.
|
|
108
|
+
|
|
109
|
+
## Role Boundaries
|
|
110
|
+
|
|
111
|
+
- **Verifier**: executable shippability gate; controls accept/reject.
|
|
112
|
+
- **Judge**: held-out score only; never steers the current run.
|
|
113
|
+
- **Analyst**: trace-derived diagnosis over worker, pairwise, subtree, or full
|
|
114
|
+
loop traces; may emit findings, questions, messages, or blockers.
|
|
115
|
+
- **Driver/reviewer**: consumes evidence and chooses continue, steer, spawn,
|
|
116
|
+
answer, escalate, or stop.
|
|
117
|
+
|
|
118
|
+
## Questions And Steering
|
|
119
|
+
|
|
120
|
+
Questions are blockers, not prose hidden in output. A child asks its parent; the
|
|
121
|
+
parent answers when it has evidence, defers when safe, or escalates to Pi/user
|
|
122
|
+
when answering would invent requirements. `failClosed` loops must not stop clean
|
|
123
|
+
with unresolved `blocks-run` questions.
|
|
124
|
+
|
|
125
|
+
Steer sparingly: only when an analyst finds a concrete mistake, a loop is
|
|
126
|
+
duplicating work, a parent/Pi answers a blocker, or a verifier reveals a specific
|
|
127
|
+
fix a running worker can still use. Delivery is through `Scope.send` or
|
|
128
|
+
`steer_worker`; failed delivery means spawn a fresh corrected attempt.
|
|
129
|
+
|
|
130
|
+
## Workspace Loops
|
|
131
|
+
|
|
132
|
+
Git is the durable workspace seam:
|
|
133
|
+
|
|
134
|
+
- one branch/clone per worker
|
|
135
|
+
- `gitWorkspace({ ref })` when host and sandbox need the same clone/commit/push contract
|
|
136
|
+
- explicit commit per worker
|
|
137
|
+
- typed merge result: `merged | conflict | stale-base | rejected | verifier-failed`
|
|
138
|
+
- resume derives completion from git state, not only a side journal
|
|
139
|
+
- conflicts become blockers/questions, not silent overwrite
|
|
140
|
+
|
|
141
|
+
Proof command for the local substrate join:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
pnpm exec tsx bench/src/observe-steer-workspace-loop.mts
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
It proves `Scope.spawn -> coordination tools -> gitWorkspace -> observe ->
|
|
148
|
+
Scope.send -> corrective worker -> integration pass`. Until the same proof runs
|
|
149
|
+
with `openSandboxRun` and a remote branch, claim local substrate closure and
|
|
150
|
+
serial git accumulation, not full cloud migration safety.
|
|
151
|
+
|
|
152
|
+
## Final Check
|
|
153
|
+
|
|
154
|
+
- Does every meaningful product land in result blobs, journals, commits,
|
|
155
|
+
conversation journals, or trace events?
|
|
156
|
+
- Are verifier, judge, analyst, and driver roles separated?
|
|
157
|
+
- Can blocking questions move up the chain?
|
|
158
|
+
- Can Pi/parent steer without bypassing verification?
|
|
159
|
+
- Is workspace mutation transactional if workers edit shared code?
|
|
160
|
+
- Can existing trace/journal views isolate agents, pairs, subtrees, and the full
|
|
161
|
+
run?
|
|
162
|
+
- Is the loop small enough that an agent can author it without inventing hidden
|
|
163
|
+
runtime behavior?
|