agentainer 0.1.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.
@@ -0,0 +1,257 @@
1
+ # =============================================================================
2
+ # AgentSwarm example configuration
3
+ #
4
+ # cp agents.example.yaml agents.yaml
5
+ # ./swarm.sh validate --show-prompts # check it without launching anything
6
+ # ./swarm.sh up # launch the swarm
7
+ #
8
+ # Every key is documented inline. Anything marked (optional) can be omitted.
9
+ # =============================================================================
10
+
11
+ swarm:
12
+ name: dev-swarm
13
+
14
+ # Where agent working directories are created. One folder per agent, named
15
+ # after the agent. Relative paths resolve against this file's directory.
16
+ root: ./workspace
17
+
18
+ # (optional) Create missing agent folders automatically. Default true.
19
+ # Set to false to point agents at directories that must already exist, so a
20
+ # typo in a path fails loudly instead of silently creating an empty folder.
21
+ create_workdirs: true
22
+
23
+ # (optional) Prefix for tmux session names. With `swarm-`, the agent named
24
+ # `developer` lives in the tmux session `swarm-developer`.
25
+ session_prefix: ""
26
+
27
+ # (optional) Timing knobs, all in milliseconds.
28
+ send_delay_ms: 150 # pause before pasting text into a pane
29
+ enter_delay_ms: 250 # pause between pasting text and pressing Enter
30
+ max_forward_hops: 3 # stops auto-forward loops (A -> B -> A -> ...)
31
+
32
+ # (optional) How long to keep probing an agent's input box for a response
33
+ # before giving up and typing the first prompt anyway. Some CLIs (Claude Code)
34
+ # silently discard keystrokes for several seconds partway through startup, so
35
+ # AgentSwarm waits for the input box to echo a throwaway token before typing.
36
+ ready_timeout_ms: 60000
37
+
38
+ # (optional) An agent is "busy" from when a message is submitted to it until its
39
+ # next captured turn end; senders are refused meanwhile and told to --queue or
40
+ # --wait. If a capture never fires (crashed CLI, bad hook) the agent would look
41
+ # busy forever, so after this long it is treated as idle again, with a warning.
42
+ busy_timeout_ms: 900000
43
+
44
+ # (optional) How messages look on the wire.
45
+ # tagged -- messages arrive inside <swarm-message from=".." id=".."> ... </swarm-message>,
46
+ # and an agent sends one by writing <swarm-send to="..."> ... </swarm-send>
47
+ # in its reply. No shell quoting, so multi-line bodies survive intact.
48
+ # plain -- the older "[swarm] message from <sender>:" header.
49
+ message_format: tagged
50
+
51
+ # (optional) An agent that answers a question as plain prose sends nothing: only a
52
+ # <swarm-send> block is delivered. When it owes a reply and its turn ends without
53
+ # one, AgentSwarm messages it explaining how to send. This is how many times.
54
+ max_reply_reminders: 1
55
+
56
+ # (optional) Reattach agents to their previous conversations on `up`, using the ids
57
+ # recorded in <root>/.swarm/sessions.yaml. Same as passing `up --resume` every time.
58
+ # Useful after a reboot. `up --no-resume` overrides it.
59
+ resume: false
60
+
61
+ # (optional) Only used by agents with `capture: pane` (gemini, hermes).
62
+ pane_idle_ms: 2500 # pane must be unchanged this long to count as "done"
63
+ pane_poll_ms: 700 # how often the watcher samples the pane
64
+ pane_scrollback: 400 # lines of scrollback to diff
65
+
66
+ # (optional) tmux comfort settings for when you `swarm attach <agent>`.
67
+ # The default tmux scrollback (2000 lines) is too small to hold a long
68
+ # multi-agent conversation, so AgentSwarm raises it before creating sessions.
69
+ # mouse mode lets you wheel-scroll the backlog; press q to leave copy mode.
70
+ # Both are applied to the tmux server, so they also affect your other sessions.
71
+ tmux_history_limit: 50000 # lines of scrollback per agent pane (0 = leave tmux's default)
72
+ tmux_mouse: true # enable mouse wheel scrolling in the panes
73
+
74
+ # -----------------------------------------------------------------------------
75
+ # defaults (optional) -- applied to every agent that does not override them.
76
+ # -----------------------------------------------------------------------------
77
+ defaults:
78
+ type: claude
79
+ append_agents_that_you_can_talk_to_prompt: true
80
+ in_first_prompt_append_your_task_will_be_sent_in_the_next_prompt: false
81
+ env:
82
+ SWARM_DEMO: "1"
83
+
84
+ # -----------------------------------------------------------------------------
85
+ # agent_types (optional) -- override the built-in launch commands, or define
86
+ # entirely new agent types. Built-ins are: claude, codex, gemini, hermes.
87
+ #
88
+ # capture: how AgentSwarm learns that an agent finished a turn.
89
+ # hook -- the CLI can run an external program on turn completion.
90
+ # Supported for claude (Stop hook) and codex (notify program).
91
+ # pane -- no such facility: poll the tmux pane and diff it. Heuristic.
92
+ # none -- do not capture at all.
93
+ #
94
+ # boot_delay_ms: a grace period before AgentSwarm starts probing the input
95
+ # box. It does NOT need to cover the full startup time -- delivery of the
96
+ # first prompt is verified and retried, so a small value is fine.
97
+ # -----------------------------------------------------------------------------
98
+ agent_types:
99
+ claude:
100
+ command: "claude --dangerously-skip-permissions"
101
+ capture: hook
102
+ boot_delay_ms: 3000
103
+ codex:
104
+ command: "codex --yolo"
105
+ capture: hook
106
+ boot_delay_ms: 3000
107
+ gemini:
108
+ command: "gemini --yolo"
109
+ capture: pane
110
+ boot_delay_ms: 4000
111
+ hermes:
112
+ command: "hermes"
113
+ capture: pane
114
+ boot_delay_ms: 3000
115
+
116
+ # -----------------------------------------------------------------------------
117
+ # agents -- one tmux session and one directory each.
118
+ # -----------------------------------------------------------------------------
119
+ agents:
120
+
121
+ - name: orchestrator
122
+ type: claude
123
+ # (optional) Override the type's command, e.g. to pin a model.
124
+ command: "claude --dangerously-skip-permissions --model opus"
125
+
126
+ # Who this agent is allowed to message. Use "*" for "everyone else".
127
+ # An agent that tries to message anyone not listed here is refused.
128
+ can_talk_to: ["researcher", "developer", "reviewer"]
129
+
130
+ first_prompt: |
131
+ You are the ORCHESTRATOR of a small software team.
132
+
133
+ Your job is to break the user's goal into concrete pieces of work, hand
134
+ each piece to the right specialist, and assemble their answers into a
135
+ final result. You do not write production code yourself.
136
+
137
+ Team:
138
+ - researcher: investigates prior art, APIs and docs
139
+ - developer: writes the implementation
140
+ - reviewer: critiques diffs and finds bugs
141
+
142
+ Start by asking the researcher what they can find, then brief the developer.
143
+
144
+ # This agent is told its task arrives in a follow-up prompt, so it will
145
+ # acknowledge and wait rather than inventing work.
146
+ in_first_prompt_append_your_task_will_be_sent_in_the_next_prompt: true
147
+
148
+ - name: researcher
149
+ type: gemini
150
+ command: "gemini --yolo"
151
+ can_talk_to: ["orchestrator", "developer"]
152
+
153
+ # Whenever this agent finishes a turn, its final message is automatically
154
+ # relayed to these agents. Every name here must also be in can_talk_to.
155
+ # Leave it out (the default) to let the agent decide when to speak.
156
+ forward_responses_to: ["orchestrator"]
157
+
158
+ first_prompt: |
159
+ You are the RESEARCHER. You investigate libraries, APIs, prior art and
160
+ documentation, then report findings concisely with sources.
161
+
162
+ You never write production code. When you have an answer, state it plainly:
163
+ what exists, what it costs, and what you recommend.
164
+
165
+ - name: developer
166
+ type: codex
167
+ command: "codex --yolo"
168
+ can_talk_to: ["orchestrator", "reviewer"]
169
+
170
+ # (optional) Per-agent environment variables, exported into its tmux session.
171
+ env:
172
+ GIT_AUTHOR_NAME: "swarm-developer"
173
+
174
+ # (optional) Before typing the first prompt, type a throwaway token and wait
175
+ # for the input box to echo it back. Defaults to true; turn it off only for
176
+ # a command that is not an interactive TUI.
177
+ ready_probe: true
178
+
179
+ # (optional) Refuse incoming messages while this agent is mid-turn, so a second
180
+ # agent is told "developer is busy, --queue it or --wait" instead of interrupting.
181
+ # Needs a capture to know when a turn ends; forced off when capture: none.
182
+ busy_check: true
183
+
184
+ # (optional) Read <swarm-send> blocks out of this agent's replies and deliver
185
+ # them. Needs a capture; forced off when capture: none or message_format: plain.
186
+ parse_outbound_tags: true
187
+
188
+ # (optional) Nudge this agent when it owes a reply but sent nothing, or when the
189
+ # block it wrote could not be delivered. Off when its tags are not parsed.
190
+ reply_reminder: true
191
+
192
+ # (optional) How to reattach this agent to a previous conversation. `resume_args`
193
+ # is appended to `command`; `resume_command` replaces it outright, which you need
194
+ # when the command goes through an alias or wrapper. {session_id} is substituted.
195
+ #
196
+ # resume_args: "resume {session_id}" # -> codex --yolo resume <id>
197
+ # resume_command: "bash -ic 'mywrapper --resume {session_id}'"
198
+
199
+ first_prompt: |
200
+ You are the DEVELOPER. You implement what the orchestrator asks for, in
201
+ the working directory you were started in.
202
+
203
+ Write real, runnable code. When you finish a unit of work, send the
204
+ reviewer a short summary of what you changed and why, and ask for review.
205
+
206
+ - name: reviewer
207
+ type: claude
208
+ command: "claude --dangerously-skip-permissions"
209
+ can_talk_to: ["developer", "orchestrator"]
210
+
211
+ # (optional) Run this agent somewhere specific instead of <root>/<name>.
212
+ # Relative paths resolve against this file. `~` is expanded. The
213
+ # placeholders {name}, {root}, {swarm} and {type} are substituted, so a
214
+ # single `defaults.workdir` can serve every agent, e.g. "{root}/{name}-wt".
215
+ #
216
+ # Several agents may share one directory (they then see each other's edits;
217
+ # AgentSwarm warns you). Pair `create_workdir: false` with an existing
218
+ # project so a bad path is an error, not a new empty folder.
219
+ #
220
+ # workdir: ~/projects/acme-api
221
+ # create_workdir: false
222
+
223
+ # (optional) Read the prompt from a file instead of inlining it here.
224
+ # first_prompt_file: ./prompts/reviewer.md
225
+ first_prompt: |
226
+ You are the REVIEWER. You read the developer's changes and hunt for real
227
+ bugs: wrong logic, unhandled errors, race conditions, security problems.
228
+
229
+ Be specific and cite file:line. If a change is fine, say so briefly rather
230
+ than inventing nitpicks. Report your verdict back to the developer.
231
+
232
+ - name: scribe
233
+ type: hermes
234
+ command: "hermes"
235
+
236
+ # This agent listens only: nobody can be messaged by it, and its own
237
+ # responses are not captured.
238
+ can_talk_to: []
239
+ capture: none
240
+
241
+ # Turn off the auto-appended communication block, since it has no peers.
242
+ append_agents_that_you_can_talk_to_prompt: false
243
+
244
+ first_prompt: |
245
+ You are the SCRIBE. Keep a running changelog of the project in NOTES.md.
246
+
247
+ # -----------------------------------------------------------------------------
248
+ # templates (optional) -- override the text AgentSwarm appends to first prompts.
249
+ # Available placeholders: {agent} {swarm} {peers} {prefix} {inbox} {workdir}
250
+ # -----------------------------------------------------------------------------
251
+ #
252
+ # templates:
253
+ # comms: |
254
+ # You are {agent}. You may message: {peers}.
255
+ # Send with: swarm send --to <agent> "message"
256
+ # task_notice: |
257
+ # Stand by. Your real task arrives in the next message.
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env node
2
+ // Agentainer -- global CLI launcher.
3
+ //
4
+ // npm symlinks this file into a bin directory (e.g. /usr/local/bin/agentainer).
5
+ // Node resolves that symlink before setting __dirname, so __dirname always
6
+ // points at the real bin/ inside the installed package -- which makes the
7
+ // package root, and therefore SWARM_HOME, reliable no matter where npm puts us.
8
+ "use strict";
9
+
10
+ const path = require("path");
11
+ const { spawnSync } = require("child_process");
12
+
13
+ const PKG_ROOT = path.resolve(__dirname, "..");
14
+ const ENTRY = path.join(PKG_ROOT, "lib", "swarm.py");
15
+
16
+ // `agentainer doctor` re-runs the dependency check without touching Python.
17
+ if (process.argv[2] === "doctor") {
18
+ const r = spawnSync(process.execPath, [path.join(PKG_ROOT, "scripts", "check-deps.js")], {
19
+ stdio: "inherit",
20
+ });
21
+ process.exit(r.status === null ? 1 : r.status);
22
+ }
23
+
24
+ // Locate a Python interpreter, mirroring swarm.sh (SWARM_PYTHON, then python3,
25
+ // then python).
26
+ function findPython() {
27
+ const candidates = process.env.SWARM_PYTHON
28
+ ? [process.env.SWARM_PYTHON]
29
+ : ["python3", "python"];
30
+ for (const cand of candidates) {
31
+ const probe = spawnSync(cand, ["--version"], { stdio: "ignore" });
32
+ if (!probe.error && probe.status === 0) return cand;
33
+ }
34
+ return null;
35
+ }
36
+
37
+ function has(cmd, args) {
38
+ const probe = spawnSync(cmd, args, { stdio: "ignore" });
39
+ return !probe.error && probe.status === 0;
40
+ }
41
+
42
+ const python = findPython();
43
+ if (!python) {
44
+ process.stderr.write(
45
+ "xx Agentainer needs python3 on PATH (or set SWARM_PYTHON).\n" +
46
+ " Run `agentainer doctor` for install hints.\n"
47
+ );
48
+ process.exit(1);
49
+ }
50
+
51
+ // tmux is required for everything except `validate`; warn but don't block, so
52
+ // `agentainer validate` and `agentainer doctor` still work without it.
53
+ if (!has("tmux", ["-V"])) {
54
+ process.stderr.write(
55
+ "!! tmux was not found on PATH; every command except 'validate' will fail.\n" +
56
+ " Run `agentainer doctor` for install hints.\n"
57
+ );
58
+ }
59
+
60
+ const result = spawnSync(python, [ENTRY, ...process.argv.slice(2)], {
61
+ stdio: "inherit",
62
+ env: { ...process.env, SWARM_HOME: PKG_ROOT },
63
+ });
64
+
65
+ if (result.error) {
66
+ process.stderr.write(`xx failed to launch Agentainer: ${result.error.message}\n`);
67
+ process.exit(1);
68
+ }
69
+ if (result.signal) {
70
+ // Re-raise the signal so the parent shell sees the real cause (e.g. Ctrl-C).
71
+ process.kill(process.pid, result.signal);
72
+ process.exit(1);
73
+ }
74
+ process.exit(result.status === null ? 1 : result.status);
@@ -0,0 +1,112 @@
1
+ # =============================================================================
2
+ # Bug hunt -- an automatic pipeline: reproduce -> diagnose -> fix -> verify.
3
+ #
4
+ # ./swarm.sh up -c examples/bug-hunt.yaml
5
+ # ./swarm.sh send --to reproducer "Uploads over 2MB fail with a 500 in prod."
6
+ #
7
+ # This is the one shape where `forward_responses_to` earns its keep: each stage
8
+ # hands its finished turn to the next stage automatically, with no human in the
9
+ # loop. Everything flows one way, so the hop guard never has to save you.
10
+ #
11
+ # reproducer --> diagnoser --> fixer --> verifier
12
+ #
13
+ # Auto-forwarding is chatty by nature. If you want agents to speak only when
14
+ # they have something to say, delete `forward_responses_to` and let them call
15
+ # `swarm send` themselves.
16
+ # =============================================================================
17
+
18
+ swarm:
19
+ name: bughunt
20
+ root: ./bughunt
21
+ session_prefix: "bug-"
22
+
23
+ # A straight line needs exactly as many hops as it has stages.
24
+ max_forward_hops: 4
25
+
26
+ agents:
27
+
28
+ - name: reproducer
29
+ type: codex
30
+ command: "codex --yolo"
31
+ can_talk_to: ["diagnoser"]
32
+ forward_responses_to: ["diagnoser"]
33
+
34
+ first_prompt: |
35
+ You are the REPRODUCER, the first stage of a bug-hunting pipeline.
36
+
37
+ Given a bug report, your only job is to turn it into a deterministic,
38
+ minimal reproduction: a script or test that fails now and would pass if
39
+ the bug were fixed.
40
+
41
+ Report, in this order:
42
+ 1. The exact command to reproduce.
43
+ 2. The observed output, verbatim.
44
+ 3. The expected output.
45
+ 4. What you had to assume, because the report did not say.
46
+
47
+ If you cannot reproduce it, say so and explain precisely what you tried.
48
+ Do not attempt a fix -- the next stage does that. Everything you say at
49
+ the end of your turn is forwarded automatically to the diagnoser.
50
+
51
+ - name: diagnoser
52
+ type: claude
53
+ command: "claude --dangerously-skip-permissions --model opus"
54
+ can_talk_to: ["fixer"]
55
+ forward_responses_to: ["fixer"]
56
+
57
+ first_prompt: |
58
+ You are the DIAGNOSER, the second stage of a bug-hunting pipeline.
59
+
60
+ You receive a reproduction. Find the root cause -- the specific line or
61
+ design decision that makes the failure inevitable. Not the symptom, and
62
+ not the first suspicious thing you see.
63
+
64
+ Report:
65
+ 1. Root cause, at file:line, in one paragraph.
66
+ 2. The causal chain from input to wrong output.
67
+ 3. Why it was not caught: the missing test, the wrong assumption.
68
+ 4. The smallest correct fix, and one alternative you rejected (say why).
69
+
70
+ Do not write the fix. Describe it. Your turn is forwarded to the fixer.
71
+
72
+ - name: fixer
73
+ type: codex
74
+ command: "codex --yolo"
75
+ can_talk_to: ["verifier"]
76
+ forward_responses_to: ["verifier"]
77
+
78
+ first_prompt: |
79
+ You are the FIXER, the third stage of a bug-hunting pipeline.
80
+
81
+ You receive a diagnosis. Implement the smallest change that fixes the root
82
+ cause, plus a regression test that fails without your change and passes
83
+ with it.
84
+
85
+ Do not refactor surrounding code, rename things, or fix unrelated bugs you
86
+ notice on the way. Mention them instead.
87
+
88
+ Report the diff you made, the test you added, and the test output. Your
89
+ turn is forwarded to the verifier, who does not trust you.
90
+
91
+ - name: verifier
92
+ type: claude
93
+ command: "claude --dangerously-skip-permissions"
94
+
95
+ # End of the line: it forwards to nobody, so the pipeline stops here.
96
+ can_talk_to: []
97
+ append_agents_that_you_can_talk_to_prompt: false
98
+
99
+ first_prompt: |
100
+ You are the VERIFIER, the last stage of a bug-hunting pipeline.
101
+
102
+ You receive a proposed fix. Assume it is wrong until you have checked.
103
+
104
+ Do all of these:
105
+ 1. Run the original reproduction. Does it now pass?
106
+ 2. Run the whole test suite. Did anything else break?
107
+ 3. Read the fix. Does it address the root cause, or only the symptom
108
+ that the reproduction happened to exercise?
109
+ 4. Find one input near the boundary of the change that would still
110
+ break. If you find one, the fix is not done.
111
+
112
+ Print a verdict: SHIPPABLE or NOT SHIPPABLE, then the evidence. Be blunt.
@@ -0,0 +1,72 @@
1
+ # =============================================================================
2
+ # Pair programming on a repository you already have.
3
+ #
4
+ # This example does NOT create any folders. Both agents are started inside one
5
+ # existing checkout, so they see each other's edits immediately -- a driver who
6
+ # writes the code and a navigator who reads it as it lands.
7
+ #
8
+ # 1. Point `workdir` below at a real repository.
9
+ # 2. ./swarm.sh validate -c examples/existing-repo.yaml
10
+ # 3. ./swarm.sh up -c examples/existing-repo.yaml
11
+ # 4. ./swarm.sh send --to driver "Add retry-with-backoff to the HTTP client."
12
+ #
13
+ # Until you edit the paths, `validate` will refuse to run and tell you so --
14
+ # that is the point of `create_workdir: false`.
15
+ # =============================================================================
16
+
17
+ swarm:
18
+ name: pair
19
+ root: ./pair-runtime # only holds logs, inboxes and swarm state
20
+ session_prefix: "pair-"
21
+
22
+ # Never silently mkdir a path the user typed. If it does not exist, that is a
23
+ # typo, not an instruction to create it.
24
+ create_workdirs: false
25
+
26
+ defaults:
27
+ # Both agents share one checkout. Every agent inherits this unless it
28
+ # overrides `workdir` itself.
29
+ #
30
+ # >>> EDIT ME <<<
31
+ workdir: ~/projects/acme-api
32
+
33
+ agents:
34
+
35
+ - name: driver
36
+ type: claude
37
+ command: "claude --dangerously-skip-permissions"
38
+ can_talk_to: ["navigator"]
39
+
40
+ first_prompt: |
41
+ You are the DRIVER in a pairing session. You have the keyboard.
42
+
43
+ You are working in a real repository that someone cares about. Before you
44
+ change anything, read enough of it to match its conventions.
45
+
46
+ Working agreement:
47
+ - Make one coherent change at a time, then tell the navigator what you
48
+ did and why, so they can review it while you continue.
49
+ - Run the tests before you claim something works. Paste real output.
50
+ - Never commit, push, or rewrite git history unless explicitly asked.
51
+ - If the navigator finds a real bug, fix it before moving on.
52
+
53
+ - name: navigator
54
+ type: codex
55
+ command: "codex --yolo"
56
+ can_talk_to: ["driver"]
57
+
58
+ first_prompt: |
59
+ You are the NAVIGATOR in a pairing session. You do not have the keyboard.
60
+
61
+ You read what the driver writes, in the same working tree, and you think
62
+ one step ahead of them. Do not edit files -- your job is to catch what
63
+ they cannot see while typing.
64
+
65
+ Watch for:
66
+ - logic that is wrong on an edge case the tests do not cover
67
+ - error paths that swallow failures
68
+ - a change that breaks an existing caller elsewhere in the repo
69
+ - drifting away from how the rest of this codebase does things
70
+
71
+ Report findings to the driver, citing file:line, with the concrete input
72
+ that goes wrong. If a change looks correct, say so briefly and move on.
@@ -0,0 +1,120 @@
1
+ # =============================================================================
2
+ # Research swarm -- a small team that investigates a topic and writes it up.
3
+ #
4
+ # ./swarm.sh up -c examples/research-swarm.yaml
5
+ # ./swarm.sh send --to lead "Research the state of WebGPU compute shaders."
6
+ #
7
+ # Shape: hub and spoke. The lead hands out work and assembles the result; the
8
+ # specialists only ever report back to the lead (and to each other where it
9
+ # actually helps). Nobody starts working until the lead briefs them.
10
+ # =============================================================================
11
+
12
+ swarm:
13
+ name: research
14
+ root: ./research-workspace
15
+ session_prefix: "r-"
16
+
17
+ defaults:
18
+ type: claude
19
+
20
+ agents:
21
+
22
+ - name: lead
23
+ type: claude
24
+ command: "bash -ic 'chy3'"
25
+ can_talk_to: ["scout", "analyst", "writer"]
26
+
27
+ # The lead waits for the human to supply the research question.
28
+ in_first_prompt_append_your_task_will_be_sent_in_the_next_prompt: true
29
+
30
+ first_prompt: |
31
+ You are the RESEARCH LEAD.
32
+
33
+ You own the research question end to end. You do not gather sources or
34
+ write prose yourself -- you decompose the question, delegate, challenge
35
+ what comes back, and assemble the final answer.
36
+
37
+ Your team:
38
+ - scout: finds primary sources, docs, papers, prior art
39
+ - analyst: reads code and data, runs experiments, checks claims
40
+ - writer: turns findings into a clear written report
41
+
42
+ How to run the project:
43
+ 1. Restate the question and split it into 2-4 concrete sub-questions.
44
+ 2. Send each sub-question to the right specialist. Be specific about
45
+ what a good answer looks like and what you do NOT want.
46
+ 3. When findings come back, look for disagreements between them. Push
47
+ back on anything asserted without a source or a reproduction.
48
+ 4. Once the picture is stable, brief the writer, then review their draft.
49
+ 5. Report the final answer to the human, with the key sources.
50
+
51
+ Never accept "it depends" as a final answer. Force a recommendation.
52
+
53
+ - name: scout
54
+ type: claude
55
+ command: "bash -ic 'chy3'"
56
+ can_talk_to: ["lead", "analyst"]
57
+
58
+ # Gemini has no turn-completion hook, so its output would have to be scraped
59
+ # from the terminal. Capturing nothing and letting it message deliberately
60
+ # is far cleaner. See README, "Capturing what an agent says".
61
+ capture: none
62
+
63
+ first_prompt: |
64
+ You are the SCOUT.
65
+
66
+ You find primary sources: official documentation, specifications, papers,
67
+ release notes, and credible prior art. You do not speculate, and you do
68
+ not summarise from memory -- if you did not open it, you do not cite it.
69
+
70
+ For every finding, report:
71
+ - the claim, in one sentence
72
+ - the source (URL or exact document + section)
73
+ - how current it is, and whether it is authoritative or hearsay
74
+
75
+ Send findings to the lead with:
76
+ swarm send --to lead "..."
77
+
78
+ If a claim needs code or data to verify, hand it to the analyst instead
79
+ of guessing. Say plainly when you could not find something.
80
+
81
+ - name: analyst
82
+ type: claude
83
+ command: "bash -ic 'chy3'"
84
+ can_talk_to: ["lead", "scout"]
85
+
86
+ first_prompt: |
87
+ You are the ANALYST.
88
+
89
+ You verify claims by running things. Given a question, write the smallest
90
+ program, benchmark or query that answers it, run it, and report what you
91
+ actually observed -- not what you expected to observe.
92
+
93
+ Rules:
94
+ - Show the command you ran and the output you got.
95
+ - If a result contradicts the scout's source, say so explicitly and
96
+ message both the scout and the lead.
97
+ - Distinguish "I measured this" from "I reason this is true".
98
+ - A failed experiment is a finding. Report it.
99
+
100
+ Work in your own directory. Keep scratch code; you may be asked to re-run it.
101
+
102
+ - name: writer
103
+ type: claude
104
+ command: "bash -ic 'chy3'"
105
+ can_talk_to: ["lead"]
106
+
107
+ # A custom folder: the report lands somewhere predictable, outside the
108
+ # per-agent scratch directories.
109
+ workdir: ./research-output
110
+
111
+ first_prompt: |
112
+ You are the WRITER.
113
+
114
+ You turn the lead's findings into a report in REPORT.md: an executive
115
+ summary a busy reader can act on, then the evidence, then the open
116
+ questions. Cite every non-obvious claim.
117
+
118
+ Write plainly. No filler, no "in today's fast-paced world", no bulleted
119
+ restatement of the question. If a finding is uncertain, say how uncertain
120
+ and why. When the draft is ready, tell the lead where it is.