omp-conductor 0.15.13 → 0.16.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/REFERENCE.md +72 -2
- package/package.json +2 -1
- package/schema/config.schema.json +6 -0
- package/src/admission.ts +745 -0
- package/src/ask.ts +47 -0
- package/src/backups.ts +19 -7
- package/src/board.ts +1 -2
- package/src/briefs/orchestrator.md +62 -4
- package/src/cli.ts +26 -0
- package/src/commands/context.ts +3 -0
- package/src/commands/decision.ts +10 -1
- package/src/commands/doctor.ts +2 -0
- package/src/commands/message.ts +8 -1
- package/src/commands/restart.ts +15 -3
- package/src/commands/restore-db.ts +146 -0
- package/src/commands/stop.ts +24 -15
- package/src/commands/unfreeze.ts +56 -0
- package/src/commands/watch.ts +77 -0
- package/src/config-schema.ts +9 -0
- package/src/config.ts +24 -0
- package/src/daemon.ts +239 -530
- package/src/dashboard/server.ts +2 -1
- package/src/decisions.ts +32 -7
- package/src/depends-on.ts +73 -0
- package/src/doctor.ts +178 -5
- package/src/escalate.ts +114 -15
- package/src/failure-class.ts +47 -0
- package/src/fleet.ts +41 -410
- package/src/gitops.ts +86 -1
- package/src/log.ts +40 -0
- package/src/model-fallback.ts +3 -2
- package/src/omp-settings.ts +114 -0
- package/src/omp.ts +39 -0
- package/src/orchestrator-tick.ts +7 -1
- package/src/reports.ts +124 -12
- package/src/session-host.ts +6 -0
- package/src/setup-wizard.ts +36 -0
- package/src/setup.ts +58 -1
- package/src/status-render.ts +445 -0
- package/src/stop-provenance.ts +53 -0
- package/src/store.ts +352 -11
- package/src/types.ts +187 -4
- package/src/unblock.ts +1 -1
- package/src/upgrade-verify.ts +1 -1
- package/src/upgrade.ts +1 -2
- package/src/verbs/server.ts +25 -0
- package/src/worker.ts +162 -10
package/REFERENCE.md
CHANGED
|
@@ -979,6 +979,41 @@ honour the pattern it says so, and the daemon logs that per run:
|
|
|
979
979
|
Worth reading the log for. A run that quietly used a weaker model than you chose
|
|
980
980
|
otherwise looks like a run that was merely unlucky.
|
|
981
981
|
|
|
982
|
+
## Omp settings overlay
|
|
983
|
+
|
|
984
|
+
`ompSettings` on a project is the fleet-owned channel for saying "this project's
|
|
985
|
+
workers run with *these* omp settings" without editing the daemon account's
|
|
986
|
+
global `~/.omp/agent/config.yml`. The value is an opaque map serialised verbatim
|
|
987
|
+
to a YAML overlay file by the dispatcher, under the run's own session directory
|
|
988
|
+
(never inside the worktree), and threaded to the session through omp's own
|
|
989
|
+
`Settings.init({ configFiles: [<path>] })` seam. Conductor validates YAML shape
|
|
990
|
+
only — omp owns the schema; an unknown key or a wrong-typed value is omp's to
|
|
991
|
+
reject, never conductor's to understand.
|
|
992
|
+
|
|
993
|
+
```json
|
|
994
|
+
"ompSettings": {
|
|
995
|
+
"retry": {
|
|
996
|
+
"modelFallback": true,
|
|
997
|
+
"fallbackChains": {
|
|
998
|
+
"default": ["openai/gpt-4o-mini", "google/gemini-x"]
|
|
999
|
+
}
|
|
1000
|
+
},
|
|
1001
|
+
"modelRoles": {
|
|
1002
|
+
"worker": "@slow"
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
```
|
|
1006
|
+
|
|
1007
|
+
The overlay is deep-merged **after** the daemon account's global config and any
|
|
1008
|
+
project `<cwd>/.omp/config.yml`, so it layers on top of both without erasing
|
|
1009
|
+
either. A config edit takes effect on the next dispatch (the overlay is
|
|
1010
|
+
rewritten on every attempt), and a project without the field dispatches
|
|
1011
|
+
byte-for-byte as it always has.
|
|
1012
|
+
|
|
1013
|
+
The retry keys derived from `modelFallbacks` are merged into the effective
|
|
1014
|
+
overlay (unless the map already names a `retry` mapping), which is where
|
|
1015
|
+
#539's within-run staging lives.
|
|
1016
|
+
|
|
982
1017
|
## Code-graph discovery
|
|
983
1018
|
|
|
984
1019
|
Optional, off unless you answer yes in the wizard, and worth answering yes to for
|
|
@@ -1409,7 +1444,38 @@ refused rather than overwriting the first answer.
|
|
|
1409
1444
|
anything is open: `decisions 2 open (oldest 26h)`, or `decisions none open`. A
|
|
1410
1445
|
row that appeared only when something was outstanding would leave "it forgot to
|
|
1411
1446
|
record the question" and "there genuinely is none" looking identical, which is
|
|
1412
|
-
the ambiguity this table exists to remove.
|
|
1447
|
+
the ambiguity this table exists to remove. `decisions N open` counts only rows a
|
|
1448
|
+
human must answer (#459): watches the orchestrator set for itself are reported
|
|
1449
|
+
separately, as `· watches N`, so a fleet waiting on GitHub's checks is never
|
|
1450
|
+
mistaken for a fleet waiting on its operator.
|
|
1451
|
+
|
|
1452
|
+
### Watches, and the split from questions (#459)
|
|
1453
|
+
|
|
1454
|
+
A front-row sharp edge: the floor's no-sleep rule said "anything that needs
|
|
1455
|
+
waiting for is a watch (`decision open --resolves-when …`)". So the orchestrator
|
|
1456
|
+
opened its own conditions as decision rows — "merge #576 once its checks are
|
|
1457
|
+
green" — and every one of them rendered, counted and expired exactly like a
|
|
1458
|
+
question put to you. `omp-conductor status` reported `decisions 3 open` and the
|
|
1459
|
+
tick prompt listed them under "Open operator decisions … resolve or withdraw",
|
|
1460
|
+
so you reasonably read a self-reminder as an ask aimed at you. The fix is a
|
|
1461
|
+
durable split at the row, never a heuristic over the wording or over whether a
|
|
1462
|
+
condition is attached (a real question may carry one too):
|
|
1463
|
+
|
|
1464
|
+
```bash
|
|
1465
|
+
omp-conductor watch add --note "merge #576 once its checks are green on the rebased head" \
|
|
1466
|
+
--blocks "#576 merge" --resolves-when pr-checks-green:https://github.com/acme/api/pull/576
|
|
1467
|
+
omp-conductor watch list
|
|
1468
|
+
```
|
|
1469
|
+
|
|
1470
|
+
A watch is a row `kind: watch` that the orchestrator opened for itself — either
|
|
1471
|
+
a `--resolves-when` condition (the daemon checks it and wakes the next tick when
|
|
1472
|
+
met, exactly as for a question), or a plain carry note the next tick should
|
|
1473
|
+
read. It renders under its own "Watches" heading, is never offered to you to
|
|
1474
|
+
resolve, and has **no seven-day expiry** — that deadline is for a question
|
|
1475
|
+
nobody answered; silently expiring a watch could drop a release the day its
|
|
1476
|
+
condition finally fires. A superseded watch is closed with the ordinary
|
|
1477
|
+
`decision withdraw <id>`. `decision open --resolves-when` still records an
|
|
1478
|
+
operator question: a condition governs *when* to ask, not *who* answers.
|
|
1413
1479
|
|
|
1414
1480
|
## Failure classes and recovery by class (#132)
|
|
1415
1481
|
|
|
@@ -2169,6 +2235,8 @@ omp-conductor decision open --question TEXT [--blocks TEXT] [--resolves-when CON
|
|
|
2169
2235
|
omp-conductor decision resolve <id> --answer TEXT [--project NAME]
|
|
2170
2236
|
omp-conductor decision withdraw <id> [--reason TEXT] [--project NAME]
|
|
2171
2237
|
omp-conductor decision list [--project NAME]
|
|
2238
|
+
omp-conductor watch add --note TEXT [--blocks TEXT] [--resolves-when COND] [--project NAME]
|
|
2239
|
+
omp-conductor watch list [--project NAME]
|
|
2172
2240
|
omp-conductor daemon [--once] [--port N] [--project NAME]
|
|
2173
2241
|
omp-conductor resume [--project NAME]
|
|
2174
2242
|
omp-conductor brief-upgrade [--migrate|--retrofit] [--apply] [--file PATH] [--project NAME]
|
|
@@ -2202,7 +2270,9 @@ omp-conductor help
|
|
|
2202
2270
|
| `decision open --question TEXT [--blocks TEXT] [--resolves-when COND]` | project | Record a question the orchestrator has put to you, and print its id. A question that lives only in a session's context is lost at the next compaction — after which it is either asked twice or dropped silently. `--resolves-when` attaches a machine-checkable condition: `pr-merged:<https url>`, `pr-checks-green:<https url>`, `pr-mergeable:<https url>`, `issue-closed:<n>`, `npm-version:<pkg>@<version>`, or `rate-limit-reset:github`; anything else exits `2` listing the six forms. See [The decision ledger](#the-decision-ledger-136). |
|
|
2203
2271
|
| `decision resolve <id> --answer TEXT` | project | Record what you decided. Exits `1` naming the id when it is unknown or no longer open, so a second answer cannot overwrite the first. |
|
|
2204
2272
|
| `decision withdraw <id> [--reason TEXT]` | project | Close a question the session stopped needing, with why. Same guard as `resolve`. |
|
|
2205
|
-
| `decision list` | project | Open questions, oldest first: id, age, what each blocks, whether its condition is met, and the question. Prints `no open decisions` when there are none. |
|
|
2273
|
+
| `decision list` | project | Open questions, oldest first: id, age, what each blocks, whether its condition is met, and the question. Prints `no open decisions` when there are none. Watches are not listed here — `watch list` shows those. |
|
|
2274
|
+
| `watch add --note TEXT [--blocks TEXT] [--resolves-when COND]` | project | Record a condition or carry note the orchestrator set for itself, with no human in the loop (#459). `--resolves-when` attaches a machine-checkable condition the daemon checks for you; a met watch wakes the next tick exactly as a met question does. Renders under its own "Watches" heading, is never counted in `decisions N open`, and has no seven-day expiry. |
|
|
2275
|
+
| `watch list` | project | Open watches, oldest first: id, age, what each blocks, whether its condition is met, and the note. Prints `no watches` when there are none. |
|
|
2206
2276
|
| `daemon` | host | Run the loop in the **foreground**, ticking every 5 minutes and serving `/healthz`. Admitted workers run in a tracked background pool, so settlement and capacity checks remain periodic while they work; shutdown drains the pool before closing the store. This is what `start` launches and what a systemd unit should call. |
|
|
2207
2277
|
| `daemon --once` | host | Run a single tick, wait for workers admitted by that tick, and exit. No HTTP server or pidfile — a drill must not register itself as the daemon, or the next reader believes it and the real daemon's in-flight runs get reconciled as orphans. |
|
|
2208
2278
|
| `--port N` | — | Accepted by `start`, `restart` and `daemon`. Both `--port 9000` and `--port=9000` work; missing or out of range exits `2` rather than falling back to the default, because probing the wrong endpoint is worse than a hard failure. |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omp-conductor",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "A 24/7 dispatcher that takes ready GitHub issues to green, mergeable PRs using omp coding sessions, with tiered escalation first to an orchestrator session and then to a human.",
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"schema": "bun run src/generate-schema.ts"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
+
"yaml": "^2.9.0",
|
|
36
37
|
"zod": "^4"
|
|
37
38
|
},
|
|
38
39
|
"peerDependencies": {
|
|
@@ -94,6 +94,11 @@
|
|
|
94
94
|
"additionalProperties": {},
|
|
95
95
|
"description": "Per-fleet or per-project hard limits"
|
|
96
96
|
},
|
|
97
|
+
"dbBackupDir": {
|
|
98
|
+
"description": "Absolute directory for restorable conductor.db snapshots; defaults to <stateDir>/backups/db",
|
|
99
|
+
"type": "string",
|
|
100
|
+
"minLength": 1
|
|
101
|
+
},
|
|
97
102
|
"projects": {
|
|
98
103
|
"minItems": 1,
|
|
99
104
|
"type": "array",
|
|
@@ -299,6 +304,7 @@
|
|
|
299
304
|
"workerModel": {},
|
|
300
305
|
"modelFallbacks": {},
|
|
301
306
|
"modelFallbackThreshold": {},
|
|
307
|
+
"ompSettings": {},
|
|
302
308
|
"escalation": {
|
|
303
309
|
"type": "object",
|
|
304
310
|
"properties": {
|