bullswarm 0.8.0 → 0.10.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/CHANGELOG.md +45 -0
- package/README.md +87 -11
- package/connectors/_schema.json +28 -2
- package/connectors/claude-code.json +16 -2
- package/connectors/codex.json +14 -2
- package/connectors/command-code.json +18 -2
- package/connectors/echo-worker.mjs +7 -0
- package/connectors/echo.json +1 -1
- package/connectors/grok.json +15 -2
- package/connectors/opencode2.json +14 -2
- package/docs/experiments/2026-08-28-trending-ai-autonomy.md +208 -0
- package/package.json +1 -1
- package/skill/SKILL.md +43 -9
- package/src/cli.js +24 -6
- package/src/lib/agent-events.js +216 -0
- package/src/lib/state.js +1 -0
- package/src/lib/strategy.js +31 -3
- package/src/lib/usage.js +17 -5
- package/src/lib/verify.js +19 -4
- package/src/lib/watch.js +89 -23
- package/src/setup.js +42 -1
- package/src/strategy-cli.js +118 -2
- package/src/workflow/cli.js +106 -10
- package/src/workflow/dashboard.js +41 -6
- package/src/workflow/draft-cli.js +4 -3
- package/src/workflow/draft.js +4 -2
- package/src/workflow/goal.js +14 -5
- package/src/workflow/runner.js +138 -44
- package/src/workflow/runtime.js +233 -48
- package/src/workflow/short-id.js +95 -4
- package/src/workflow/steering.js +61 -0
- package/src/workflow/tui.js +8 -0
- package/src/workflow/watch-cli.js +183 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,50 @@
|
|
|
1
1
|
# bullswarm changelog
|
|
2
2
|
|
|
3
|
+
## 0.10.0 — battle-tested advisory orchestration and agent activity
|
|
4
|
+
|
|
5
|
+
- Made `maxAgents` and `maxWorkflowSeconds` advisory planning targets instead
|
|
6
|
+
of hard stops. Workflows can exceed them to finish required implementation
|
|
7
|
+
and verification; structural graph-growth limits remain enforced.
|
|
8
|
+
- Removed implicit connector and generated-goal wall-clock timeouts. Delegates
|
|
9
|
+
wait for natural completion unless an operator explicitly supplies a timeout,
|
|
10
|
+
requests cancellation, or a definitive auth/quota failure is observed.
|
|
11
|
+
- Added compatibility migration for generated 0.9.0 goals carrying Bullswarm's
|
|
12
|
+
former 900-second planner/action timeout defaults.
|
|
13
|
+
- Fixed adaptive completion policy, current-action metadata, provider routing
|
|
14
|
+
history, usage aggregation, latest-worker verification, and truthful partial
|
|
15
|
+
token/cost accounting found during the Kipwise battle test.
|
|
16
|
+
- Added connector-owned native JSONL event adapters for Codex, Claude, Grok,
|
|
17
|
+
Command Code, and OpenCode. Workflows now retain and display the latest three
|
|
18
|
+
semantic shell/read/edit/write/response actions for every active agent.
|
|
19
|
+
- Added conservative stall evidence: ten minutes without transport, parsed
|
|
20
|
+
event, or semantic action activity is labeled `suspected_stalled` but never
|
|
21
|
+
causes an automatic kill.
|
|
22
|
+
- Added a low-noise `workflow watch <id>` progress stream with semantic-change
|
|
23
|
+
updates, heartbeats, last-three agent actions, and terminal per-attempt timing.
|
|
24
|
+
- Added optional durable `workflow steer <id> --message ...` guidance delivered
|
|
25
|
+
only at the next planning checkpoint, never injected into an active worker.
|
|
26
|
+
- Captured runtime model IDs declared in provider event streams for more complete
|
|
27
|
+
model/cost attribution, preserved Grok tool kinds across name-less updates,
|
|
28
|
+
and enabled Claude's supported forwarded-subagent text stream.
|
|
29
|
+
- Taught planners to reuse clean full-suite evidence and isolate mutation/pre-fix
|
|
30
|
+
experiments instead of redundantly or concurrently testing a changing tree.
|
|
31
|
+
- Expanded the offline suite to 224 tests. Real bounded CLI probes confirmed
|
|
32
|
+
all five provider event formats, and an exact packaged OpenCode watch smoke
|
|
33
|
+
passed argument injection, action normalization, final-output extraction,
|
|
34
|
+
and the content gate together.
|
|
35
|
+
|
|
36
|
+
## 0.9.0 — resilient dynamic workflow routing
|
|
37
|
+
|
|
38
|
+
- Added cooperative `SIGTERM`/`SIGINT` handling, durable `interrupted` states,
|
|
39
|
+
dead/stale owner reconciliation, and clean resume after interruption.
|
|
40
|
+
- Added capability-context filtering for model recommendations plus an explicit
|
|
41
|
+
`strategy apply --yes` approval gate and TTL-based automatic refresh.
|
|
42
|
+
- Added setup-time worktree policy and strategy-autopilot choices.
|
|
43
|
+
- Added per-attempt routing reasons/candidate surplus to durable events, state,
|
|
44
|
+
decision logs, and the printable workflow tree.
|
|
45
|
+
- Added top-level `runs` and `--version` aliases, complete `workflow goal`
|
|
46
|
+
budget help, and correct phase/terminal display for completed runs.
|
|
47
|
+
|
|
3
48
|
## 0.8.0 — autonomous goals, model strategy, and auditable usage
|
|
4
49
|
|
|
5
50
|
- Added `workflow goal` for bounded observe-plan-execute loops without an
|
package/README.md
CHANGED
|
@@ -31,7 +31,7 @@ npm install -g bullswarm # or: node bin/bullswarm.js directly from a checkout
|
|
|
31
31
|
bullswarm # first run: interactive setup wizard
|
|
32
32
|
bullswarm setup # re-run or repair
|
|
33
33
|
bullswarm pools # meter state, pace position, quarantine status
|
|
34
|
-
bullswarm strategy refresh #
|
|
34
|
+
bullswarm strategy refresh --apply --yes # approve capability-aware tier autopilot
|
|
35
35
|
bullswarm run --lane analyze --add-dir ~/some-repo --task-file /tmp/t.md --json
|
|
36
36
|
bullswarm workflow goal "Fix the failing tests and verify the change" --cwd ~/some-repo
|
|
37
37
|
bullswarm health # re-judge saved outputs; catch gate failures
|
|
@@ -57,18 +57,25 @@ connector-declared, dated pricing/benchmark metadata with live quota surplus:
|
|
|
57
57
|
```bash
|
|
58
58
|
bullswarm strategy refresh
|
|
59
59
|
bullswarm strategy show --json
|
|
60
|
+
bullswarm strategy apply --yes --refresh-hours 24
|
|
61
|
+
bullswarm strategy auto status
|
|
60
62
|
bullswarm strategy set-subscription command-code \
|
|
61
63
|
--plan GOAT --monthly-usd 10 --included-usd 70 --quota-window monthly
|
|
62
64
|
bullswarm strategy assign high --pool claude-code --model claude-opus-4-6
|
|
63
65
|
bullswarm run --effort high --lane analyze --task-file /tmp/task.md --json
|
|
64
66
|
```
|
|
65
67
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
68
|
+
Interactive setup asks whether to enable strategy autopilot; non-interactive
|
|
69
|
+
setup requires the explicit `setup --yes --strategy` flag. Recommendations are
|
|
70
|
+
context-filtered before ranking: high requires analysis plus workflow-planning,
|
|
71
|
+
medium requires build/edit capabilities, and low targets bounded chores. An
|
|
72
|
+
approved policy refreshes stale discovery before later runs and re-applies the
|
|
73
|
+
best eligible models on its configured interval. Disable it with
|
|
74
|
+
`strategy auto off --yes`. Discovery commands, model argument syntax, pricing,
|
|
75
|
+
and benchmark declarations remain connector-owned. Unknown license value,
|
|
76
|
+
prices, and benchmarks stay `null` rather than being guessed. An assignment is
|
|
77
|
+
only a preference: quarantine, exhaustion, burst gates, and capability checks
|
|
78
|
+
still win.
|
|
72
79
|
|
|
73
80
|
Every run and workflow attempt reports its selected agent/model and estimated
|
|
74
81
|
usage. When a delegate does not expose counters, Bullswarm labels its UTF-8
|
|
@@ -94,8 +101,9 @@ bullswarm workflow goal \
|
|
|
94
101
|
--cwd ~/some-repo --detach --json
|
|
95
102
|
```
|
|
96
103
|
|
|
97
|
-
Bullswarm
|
|
98
|
-
|
|
104
|
+
Bullswarm first honors an approved high-tier provider/model assignment when it
|
|
105
|
+
remains eligible, otherwise it selects an eligible `workflow-planning`
|
|
106
|
+
orchestrator by live quota surplus. The orchestrator observes durable evidence, proposes bounded actions,
|
|
99
107
|
and decides when another expansion or verification is necessary. Bullswarm
|
|
100
108
|
validates the proposal, owns agent/process selection, routes workers, and calls
|
|
101
109
|
the orchestrator again until completion, cancellation, failure, approval, or a
|
|
@@ -106,6 +114,7 @@ The detached response includes a short ID and exact observation commands:
|
|
|
106
114
|
|
|
107
115
|
```bash
|
|
108
116
|
bullswarm workflow runs show <shortId>
|
|
117
|
+
bullswarm workflow watch <shortId> # low-noise live progress + terminal timing
|
|
109
118
|
bullswarm workflow tui <shortId> # printable phase/action/attempt tree
|
|
110
119
|
bullswarm workflow tui --json <shortId>
|
|
111
120
|
bullswarm workflow events --json <shortId> --after 0
|
|
@@ -121,7 +130,9 @@ bullswarm workflow goal --resume <shortId> --json
|
|
|
121
130
|
`--orchestrator <pool>` exists for controlled testing; ordinary use should
|
|
122
131
|
leave selection on `auto`. Hard limits can be adjusted with `--max-agents`,
|
|
123
132
|
`--max-expansion-rounds`, `--max-actions`, `--max-items-per-expansion`, and
|
|
124
|
-
`--max-workflow-seconds`.
|
|
133
|
+
`--max-workflow-seconds`. Interactive setup also records a worktree-isolation
|
|
134
|
+
preference (`agent-decides`, `off`, or `required`); Bullswarm communicates that
|
|
135
|
+
policy to the orchestrator without imposing repository topology itself.
|
|
125
136
|
|
|
126
137
|
## Building a workflow from the shell
|
|
127
138
|
|
|
@@ -164,6 +175,7 @@ bullswarm workflow runs --historical # only historical
|
|
|
164
175
|
bullswarm workflow runs --name audit-code # filter by workflow
|
|
165
176
|
bullswarm workflow runs --limit 20 # cap the result count
|
|
166
177
|
bullswarm workflow runs show <shortId> # state + report + summary
|
|
178
|
+
bullswarm runs show <shortId> # top-level shorthand
|
|
167
179
|
bullswarm workflow runs delete <shortId> --yes # remove the run dir
|
|
168
180
|
|
|
169
181
|
# Resume by shortId — runs the same logic as the full runId
|
|
@@ -172,6 +184,18 @@ bullswarm workflow run audit-code --resume <shortId>
|
|
|
172
184
|
|
|
173
185
|
### Live workflow dashboard
|
|
174
186
|
|
|
187
|
+
For ordinary observation, use the non-interactive watcher. It prints only when
|
|
188
|
+
the phase, step, agent action, routing, or status changes, plus a 60-second
|
|
189
|
+
heartbeat while otherwise quiet. Terminal output includes every attempt's
|
|
190
|
+
agent/model, elapsed time, outcome, and tokens, so a slow test is distinguishable
|
|
191
|
+
from a stalled process without writing a polling script.
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
bullswarm workflow watch <shortId>
|
|
195
|
+
bullswarm workflow watch <shortId> --jsonl # automation-friendly stream
|
|
196
|
+
bullswarm workflow watch <shortId> --once # one current/terminal snapshot
|
|
197
|
+
```
|
|
198
|
+
|
|
175
199
|
`workflow tui` is the interactive, Claude-style `/workflows` view. It watches
|
|
176
200
|
ongoing runs from disk and supports `j`/`k` or arrow-key selection, Enter for
|
|
177
201
|
details, `c` to request a cooperative stop, `r` to refresh, and `q` to quit.
|
|
@@ -191,17 +215,62 @@ bullswarm workflow tui --json --cancel <id> # request cooperative stop
|
|
|
191
215
|
bullswarm workflow capabilities --json # pools, lanes, models, meters, limits
|
|
192
216
|
bullswarm workflow inspect <file-or-name> # workflow shape and semantics
|
|
193
217
|
bullswarm workflow events --json <id> --after 20
|
|
218
|
+
bullswarm workflow steer <id> --message "Prefer focused tests before another full suite"
|
|
194
219
|
bullswarm workflow action show --json <id> <actionId>
|
|
195
220
|
bullswarm workflow approval approve --json <id> # then resume the run
|
|
196
221
|
```
|
|
197
222
|
|
|
198
223
|
Cancellation is persisted as `cancelling`, terminates an active child process,
|
|
199
224
|
records its termination signal and latency evidence, then commits `cancelled`.
|
|
225
|
+
`SIGTERM` and `SIGINT` use the same cooperative child termination path but
|
|
226
|
+
commit a distinct resumable `interrupted` state. On every workflow command,
|
|
227
|
+
active states with a dead/stale owner are automatically reconciled to
|
|
228
|
+
`interrupted` instead of remaining falsely `running`.
|
|
229
|
+
|
|
230
|
+
`workflow steer` is optional operator guidance, not hot-patching. It appends a
|
|
231
|
+
durable instruction that is delivered only to the next not-yet-started
|
|
232
|
+
`decide` checkpoint; the active worker continues unchanged. Steering remains
|
|
233
|
+
inside the original goal and authorization boundary and cannot bypass runtime
|
|
234
|
+
validation or required verification. Static workflows and terminal runs reject
|
|
235
|
+
steering because they have no future orchestration checkpoint.
|
|
236
|
+
Live attempts record the last stdout/stderr activity time and observed byte
|
|
237
|
+
count separately from the runner heartbeat. This makes a silent process
|
|
238
|
+
visible without treating elapsed wall time alone as proof that it is hung.
|
|
239
|
+
Supported coding-agent connectors also enable their native JSONL event mode and
|
|
240
|
+
declaratively map provider events into a common semantic action record:
|
|
241
|
+
|
|
242
|
+
```json
|
|
243
|
+
{"id":"provider-action-id","at":"...","kind":"shell_command|read_file|edit|response","status":"running|completed|failed","summary":"safe scalar preview"}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
The live workflow pane retains the latest three logical actions per agent.
|
|
247
|
+
Repeated updates for the same tool call replace its status, and streaming text
|
|
248
|
+
chunks coalesce into one response action. Heartbeats, token/thought deltas,
|
|
249
|
+
usage messages, hooks, and unparsed output remain liveness evidence but do not
|
|
250
|
+
occupy the action pane. Connector-specific flags, paths, and mappings live in
|
|
251
|
+
`connectors/*.json` under `eventStream`; core contains no provider event names.
|
|
252
|
+
|
|
253
|
+
After ten minutes without transport, parsed-event, or semantic-action evidence,
|
|
254
|
+
an active child is labeled `suspected_stalled`. This is an inspection signal,
|
|
255
|
+
not a death verdict and never an automatic kill: buffered CLIs can be silent
|
|
256
|
+
while working. Process exit, a fatal auth/quota signature, explicit operator
|
|
257
|
+
cancellation, or an opt-in timeout remain the terminal signals.
|
|
258
|
+
|
|
259
|
+
Each attempt records the phase/action, selected pool and model, effort tier,
|
|
260
|
+
routing reason, all eligible candidates with quota surplus, timestamps,
|
|
261
|
+
artifact paths, outcome, and reported-or-estimated token/cost/quota usage.
|
|
262
|
+
`workflow tui <id>` renders this breakdown for completed runs as well as live
|
|
263
|
+
ones; `workflow tui --json <id>` exposes the durable audit document.
|
|
264
|
+
When a provider event stream reports the actual model, Bullswarm records that
|
|
265
|
+
runtime value and uses its matching connector rate metadata for the attempt's
|
|
266
|
+
cost estimate. Unknown or provider-hidden model identity remains explicitly
|
|
267
|
+
unknown.
|
|
200
268
|
|
|
201
269
|
### Adaptive workflows
|
|
202
270
|
|
|
203
271
|
Static workflows remain zero-extra-LLM orchestration. An adaptive workflow adds
|
|
204
|
-
an explicit `decide` step and
|
|
272
|
+
an explicit `decide` step, advisory resource targets, and structural expansion
|
|
273
|
+
limits:
|
|
205
274
|
|
|
206
275
|
```json
|
|
207
276
|
{
|
|
@@ -228,6 +297,13 @@ an explicit `decide` step and hard limits:
|
|
|
228
297
|
}
|
|
229
298
|
```
|
|
230
299
|
|
|
300
|
+
`maxAgents` and `maxWorkflowSeconds` are advisory inputs to the orchestrator.
|
|
301
|
+
Crossing either target is recorded in durable state but never stops a worker,
|
|
302
|
+
skips verification, or fails a run. `maxExpansionRounds`, `maxActions`, and
|
|
303
|
+
`maxItemsPerExpansion` remain hard graph-growth safeguards. Delegates have no
|
|
304
|
+
implicit wall-clock timeout; set a step's `timeoutSec` (or direct-run
|
|
305
|
+
`--timeout`) only when an operator explicitly wants a hard termination timer.
|
|
306
|
+
|
|
231
307
|
The planner returns versioned JSON. It may propose `needs_more_work` with
|
|
232
308
|
bounded `run`, inline-`fanout`, or `verify` actions. The deterministic runtime
|
|
233
309
|
validates IDs, dependencies, operation types, capabilities, and budgets before
|
package/connectors/_schema.json
CHANGED
|
@@ -12,9 +12,35 @@
|
|
|
12
12
|
"authSignatures": ["strings in output that mean auth/throttle failure"],
|
|
13
13
|
"outputExtraction": {
|
|
14
14
|
"$comment": "how to get the real answer out of stdout+stderr+files",
|
|
15
|
-
"strategy": "stdout|stdout-tail|json-field|file",
|
|
15
|
+
"strategy": "stdout|stdout-tail|json-field|file|event-stream",
|
|
16
16
|
"field": "optional json field path or file glob"
|
|
17
17
|
},
|
|
18
|
+
"eventStream": {
|
|
19
|
+
"$comment": "Optional declarative JSONL adapter. Provider quirks stay here; core emits normalized semantic actions.",
|
|
20
|
+
"format": "jsonl",
|
|
21
|
+
"args": ["CLI flags that enable machine-readable streaming"],
|
|
22
|
+
"modelPaths": ["provider model-id paths in priority order"],
|
|
23
|
+
"silenceThresholdSec": 600,
|
|
24
|
+
"rules": [{
|
|
25
|
+
"rootMatch": {"path": "provider.event.type", "equals": "tool_started"},
|
|
26
|
+
"forEach": "optional.array.path",
|
|
27
|
+
"match": {"path": "nested.type", "equals": "tool_use"},
|
|
28
|
+
"idPaths": ["provider action id paths in priority order"],
|
|
29
|
+
"kindPaths": ["tool or response kind paths"],
|
|
30
|
+
"summaryPaths": ["safe command/path/text scalar paths"],
|
|
31
|
+
"status": "queued|running|streaming|completed|failed",
|
|
32
|
+
"statusPath": "optional provider status path",
|
|
33
|
+
"statusMap": {"provider-status": "normalized-status"},
|
|
34
|
+
"aggregate": "consecutive",
|
|
35
|
+
"summaryMode": "replace|concat"
|
|
36
|
+
}],
|
|
37
|
+
"output": [{
|
|
38
|
+
"match": {"path": "provider.event.type", "equals": "final"},
|
|
39
|
+
"path": "provider final response scalar path",
|
|
40
|
+
"mode": "last|concat",
|
|
41
|
+
"separator": "optional separator"
|
|
42
|
+
}]
|
|
43
|
+
},
|
|
18
44
|
"meter": {
|
|
19
45
|
"$comment": "none | declared (manual) | reader (programmatic)",
|
|
20
46
|
"type": "none|declared|reader",
|
|
@@ -50,5 +76,5 @@
|
|
|
50
76
|
"stealth": false,
|
|
51
77
|
"$comment-stealth": "stealth=true: prompts/completions retained by an anonymous provider — opt-in only, never a default"
|
|
52
78
|
},
|
|
53
|
-
"
|
|
79
|
+
"$comment-timeout": "Delegates have no implicit wall-clock timeout; use direct --timeout or workflow step.timeoutSec as an explicit opt-in"
|
|
54
80
|
}
|
|
@@ -23,7 +23,21 @@
|
|
|
23
23
|
"please run /login"
|
|
24
24
|
],
|
|
25
25
|
"outputExtraction": {
|
|
26
|
-
"strategy": "
|
|
26
|
+
"strategy": "event-stream"
|
|
27
|
+
},
|
|
28
|
+
"eventStream": {
|
|
29
|
+
"format": "jsonl",
|
|
30
|
+
"args": ["--output-format", "stream-json", "--verbose", "--forward-subagent-text"],
|
|
31
|
+
"modelPaths": ["model", "message.model"],
|
|
32
|
+
"silenceThresholdSec": 600,
|
|
33
|
+
"rules": [
|
|
34
|
+
{ "rootMatch": { "path": "type", "equals": "assistant" }, "forEach": "message.content", "match": { "path": "type", "equals": "tool_use" }, "idPaths": ["id"], "kindPaths": ["name"], "summaryPaths": ["input.command", "input.file_path", "input.path", "input.pattern"], "status": "running" },
|
|
35
|
+
{ "rootMatch": { "path": "type", "equals": "user" }, "forEach": "message.content", "match": { "path": "type", "equals": "tool_result" }, "idPaths": ["tool_use_id"], "kind": "tool", "statusPath": "is_error", "statusMap": { "true": "failed", "false": "completed" }, "defaultStatus": "completed" },
|
|
36
|
+
{ "rootMatch": { "path": "type", "equals": "assistant" }, "forEach": "message.content", "match": { "path": "type", "equals": "text" }, "kind": "response", "summaryPaths": ["text"], "status": "completed" }
|
|
37
|
+
],
|
|
38
|
+
"output": [
|
|
39
|
+
{ "match": { "path": "type", "equals": "result" }, "path": "result", "mode": "last" }
|
|
40
|
+
]
|
|
27
41
|
},
|
|
28
42
|
"$comment-meter": "the CALLER pool \u2014 competes in analyze/build, wins only when no delegate can take the lane",
|
|
29
43
|
"meter": {
|
|
@@ -51,5 +65,5 @@
|
|
|
51
65
|
"stealth": false,
|
|
52
66
|
"isCaller": true
|
|
53
67
|
},
|
|
54
|
-
"
|
|
68
|
+
"$comment-timeout": "No implicit wall-clock timeout; callers may opt in with --timeout or workflow step.timeoutSec"
|
|
55
69
|
}
|
package/connectors/codex.json
CHANGED
|
@@ -22,7 +22,19 @@
|
|
|
22
22
|
"invalid api key"
|
|
23
23
|
],
|
|
24
24
|
"outputExtraction": {
|
|
25
|
-
"strategy": "
|
|
25
|
+
"strategy": "event-stream"
|
|
26
|
+
},
|
|
27
|
+
"eventStream": {
|
|
28
|
+
"format": "jsonl",
|
|
29
|
+
"args": ["--json"],
|
|
30
|
+
"silenceThresholdSec": 600,
|
|
31
|
+
"rules": [
|
|
32
|
+
{ "rootMatch": { "path": "type", "equals": "item.started" }, "idPaths": ["item.id"], "kindPaths": ["item.type"], "kindMap": { "agent_message": "response" }, "summaryPaths": ["item.command", "item.text"], "status": "running" },
|
|
33
|
+
{ "rootMatch": { "path": "type", "equals": "item.completed" }, "idPaths": ["item.id"], "kindPaths": ["item.type"], "kindMap": { "agent_message": "response" }, "summaryPaths": ["item.command", "item.text"], "status": "completed" }
|
|
34
|
+
],
|
|
35
|
+
"output": [
|
|
36
|
+
{ "match": { "path": "type", "equals": "item.completed" }, "path": "item.text", "mode": "last" }
|
|
37
|
+
]
|
|
26
38
|
},
|
|
27
39
|
"meter": {
|
|
28
40
|
"type": "reader",
|
|
@@ -49,5 +61,5 @@
|
|
|
49
61
|
"flags": {
|
|
50
62
|
"stealth": false
|
|
51
63
|
},
|
|
52
|
-
"
|
|
64
|
+
"$comment-timeout": "No implicit wall-clock timeout; callers may opt in with --timeout or workflow step.timeoutSec"
|
|
53
65
|
}
|
|
@@ -22,7 +22,23 @@
|
|
|
22
22
|
"cmd login"
|
|
23
23
|
],
|
|
24
24
|
"outputExtraction": {
|
|
25
|
-
"strategy": "
|
|
25
|
+
"strategy": "event-stream"
|
|
26
|
+
},
|
|
27
|
+
"eventStream": {
|
|
28
|
+
"format": "jsonl",
|
|
29
|
+
"args": ["--output-format", "json"],
|
|
30
|
+
"modelPaths": ["event.model", "model"],
|
|
31
|
+
"silenceThresholdSec": 600,
|
|
32
|
+
"rules": [
|
|
33
|
+
{ "rootMatch": { "path": "event.type", "equals": "tool_queued" }, "idPaths": ["event.toolCallId"], "kindPaths": ["event.toolName"], "summaryPaths": ["event.input.command", "event.input.file_path", "event.input.path"], "status": "queued" },
|
|
34
|
+
{ "rootMatch": { "path": "event.type", "equals": "tool_running" }, "idPaths": ["event.toolCallId"], "kindPaths": ["event.toolName"], "summaryPaths": ["event.description"], "status": "running" },
|
|
35
|
+
{ "rootMatch": { "path": "event.type", "equals": "tool_completed" }, "idPaths": ["event.toolCallId"], "kindPaths": ["event.toolName"], "status": "completed" },
|
|
36
|
+
{ "rootMatch": { "path": "event.type", "equals": "message_end" }, "forEach": "event.content", "match": { "path": "type", "equals": "text" }, "kind": "response", "summaryPaths": ["text"], "status": "completed" }
|
|
37
|
+
],
|
|
38
|
+
"output": [
|
|
39
|
+
{ "match": { "path": "type", "equals": "result" }, "path": "finalText", "mode": "last" },
|
|
40
|
+
{ "match": { "path": "event.type", "equals": "run_end" }, "path": "event.result.finalText", "mode": "last" }
|
|
41
|
+
]
|
|
26
42
|
},
|
|
27
43
|
"meter": {
|
|
28
44
|
"type": "reader",
|
|
@@ -53,5 +69,5 @@
|
|
|
53
69
|
"flags": {
|
|
54
70
|
"stealth": false
|
|
55
71
|
},
|
|
56
|
-
"
|
|
72
|
+
"$comment-timeout": "No implicit wall-clock timeout; callers may opt in with --timeout or workflow step.timeoutSec"
|
|
57
73
|
}
|
|
@@ -8,7 +8,14 @@
|
|
|
8
8
|
import { readFileSync } from 'node:fs';
|
|
9
9
|
|
|
10
10
|
const task = readFileSync(process.argv[2], 'utf8');
|
|
11
|
+
const sleepMatch = task.match(/SLEEP_MS:(\d+)/);
|
|
12
|
+
if (sleepMatch) await new Promise((resolve) => setTimeout(resolve, Number(sleepMatch[1])));
|
|
11
13
|
|
|
14
|
+
if (task.includes('FAIL:auth-hang')) {
|
|
15
|
+
console.log('Authentication failed: quota exhausted; waiting process should be terminated.');
|
|
16
|
+
await new Promise((resolve) => setTimeout(resolve, 5000));
|
|
17
|
+
process.exit(0);
|
|
18
|
+
}
|
|
12
19
|
if (task.includes('FAIL:auth')) {
|
|
13
20
|
console.log('Authentication failed: no credentials found in keychain.');
|
|
14
21
|
process.exit(0);
|
package/connectors/echo.json
CHANGED
package/connectors/grok.json
CHANGED
|
@@ -18,7 +18,20 @@
|
|
|
18
18
|
"invalid api key"
|
|
19
19
|
],
|
|
20
20
|
"outputExtraction": {
|
|
21
|
-
"strategy": "
|
|
21
|
+
"strategy": "event-stream"
|
|
22
|
+
},
|
|
23
|
+
"eventStream": {
|
|
24
|
+
"format": "jsonl",
|
|
25
|
+
"args": ["--output-format", "streaming-json"],
|
|
26
|
+
"silenceThresholdSec": 600,
|
|
27
|
+
"rules": [
|
|
28
|
+
{ "rootMatch": { "path": "type", "equals": "tool_call" }, "idPaths": ["toolCallId"], "kindPaths": ["toolName", "title"], "summaryPaths": ["rawInput.command", "rawInput.file_path", "rawInput.path", "title"], "statusPath": "status" },
|
|
29
|
+
{ "rootMatch": { "path": "type", "equals": "tool_call_update" }, "idPaths": ["toolCallId"], "kindPaths": ["toolName"], "summaryPaths": ["rawOutput.command"], "statusPath": "status" },
|
|
30
|
+
{ "rootMatch": { "path": "type", "equals": "text" }, "kind": "response", "summaryPaths": ["data"], "status": "streaming", "aggregate": "consecutive", "summaryMode": "concat" }
|
|
31
|
+
],
|
|
32
|
+
"output": [
|
|
33
|
+
{ "match": { "path": "type", "equals": "text" }, "path": "data", "mode": "concat" }
|
|
34
|
+
]
|
|
22
35
|
},
|
|
23
36
|
"meter": {
|
|
24
37
|
"type": "reader",
|
|
@@ -43,6 +56,6 @@
|
|
|
43
56
|
"flags": {
|
|
44
57
|
"stealth": false
|
|
45
58
|
},
|
|
46
|
-
"
|
|
59
|
+
"$comment-timeout": "No implicit wall-clock timeout; callers may opt in with --timeout or workflow step.timeoutSec",
|
|
47
60
|
"$comment-meter": "weekly shared credit pool via billing endpoint; no 5h window exists on unified-billing accounts"
|
|
48
61
|
}
|
|
@@ -8,7 +8,19 @@
|
|
|
8
8
|
"$comment-cwdMode": "QUIRK: resolves its project from $PWD, not the spawn cwd. The watcher MUST set env.PWD and spawn with cwd inside the target repo, or it will silently analyse the wrong repository and answer confidently about it."
|
|
9
9
|
},
|
|
10
10
|
"authSignatures": ["No cookie auth credentials found", "unauthorized"],
|
|
11
|
-
"outputExtraction": { "strategy": "
|
|
11
|
+
"outputExtraction": { "strategy": "event-stream" },
|
|
12
|
+
"eventStream": {
|
|
13
|
+
"format": "jsonl",
|
|
14
|
+
"args": ["--format", "json"],
|
|
15
|
+
"silenceThresholdSec": 600,
|
|
16
|
+
"rules": [
|
|
17
|
+
{ "rootMatch": { "path": "type", "equals": "tool_use" }, "idPaths": ["part.callID", "part.id"], "kindPaths": ["part.tool"], "summaryPaths": ["part.state.input.command", "part.state.input.file_path", "part.state.input.path", "part.state.title"], "statusPath": "part.state.status" },
|
|
18
|
+
{ "rootMatch": { "path": "type", "equals": "text" }, "idPaths": ["part.id"], "kind": "response", "summaryPaths": ["part.text"], "status": "completed" }
|
|
19
|
+
],
|
|
20
|
+
"output": [
|
|
21
|
+
{ "match": { "path": "type", "equals": "text" }, "path": "part.text", "mode": "concat", "separator": "\n" }
|
|
22
|
+
]
|
|
23
|
+
},
|
|
12
24
|
"$comment-auto": "--auto is required for headless workflow dispatch: task files live under ~/.bullswarm, outside the target repo, and OpenCode otherwise pauses for an interactive permission approval. --model pins the QA/runtime pool to Luna instead of the CLI default.",
|
|
13
25
|
"$comment-exit1": "known failure mode: writes a complete correct answer, then dies with a Console-sync auth error and exit 1. The verdict sets contentUsableDespiteExit instead of discarding the work.",
|
|
14
26
|
"meter": { "type": "none" },
|
|
@@ -24,5 +36,5 @@
|
|
|
24
36
|
],
|
|
25
37
|
"subscription": { "plan": null, "monthlyPriceUsd": null, "includedValueUsd": null, "quotaWindow": null },
|
|
26
38
|
"flags": { "stealth": false },
|
|
27
|
-
"
|
|
39
|
+
"$comment-timeout": "No implicit wall-clock timeout; callers may opt in with --timeout or workflow step.timeoutSec"
|
|
28
40
|
}
|