@wrenautomation/aerie 0.4.6 → 0.5.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,42 @@
1
+ import type { TaskRecord } from "../core/index.js";
2
+ import type { RunEvent, Runner, RunnerName } from "./port.js";
3
+ export interface AdapterOptions {
4
+ /** binary path; default the runner's own name on PATH */
5
+ bin?: string | undefined;
6
+ /** extra args before the prompt */
7
+ args?: string[] | undefined;
8
+ }
9
+ /** What every agent is told: the task whole, and how to ask a person. */
10
+ export declare function promptOf(t: TaskRecord, answers?: string[]): string;
11
+ type ClaudeItem = {
12
+ type: string;
13
+ text?: string;
14
+ name?: string;
15
+ input?: unknown;
16
+ content?: unknown;
17
+ };
18
+ type ClaudeLine = {
19
+ type: string;
20
+ subtype?: string;
21
+ session_id?: string;
22
+ message?: {
23
+ content?: ClaudeItem[];
24
+ };
25
+ result?: string;
26
+ is_error?: boolean;
27
+ total_cost_usd?: number;
28
+ };
29
+ /** headless default: file edits and the aerie CLI, no other shell */
30
+ export declare const CLAUDE_TOOLS: string[];
31
+ export declare function claudeEvent(l: ClaudeLine): RunEvent;
32
+ export declare function claudeRunner(o?: AdapterOptions): Runner;
33
+ export declare function codexRunner(o?: AdapterOptions): Runner;
34
+ export declare function grokRunner(o?: AdapterOptions): Runner;
35
+ export declare function autobrowseRunner(o?: AdapterOptions): Runner;
36
+ export declare function apiRunner(o: {
37
+ spec: string;
38
+ env?: Record<string, string | undefined>;
39
+ }): Runner;
40
+ /** The headless runners from settings: `AERIE_<RUNNER>_BIN`, `AERIE_<RUNNER>_ARGS` (a JSON array), `AERIE_API_MODEL`. */
41
+ export declare function headlessRunners(get: (k: string) => string | undefined): Map<RunnerName, Runner>;
42
+ export {};
@@ -0,0 +1,275 @@
1
+ /**
2
+ * The five headless runners (design: Runners). Each line a child prints is one event, kept whole (`data`).
3
+ * codex and grok: no binary on the dev Mac yet, so their lines are kept raw and the summary is a best guess.
4
+ */
5
+ import { z } from "zod";
6
+ import { runLines } from "./spawn.js";
7
+ /** What every agent is told: the task whole, and how to ask a person. */
8
+ export function promptOf(t, answers = []) {
9
+ const checks = (title, cs) => cs.length
10
+ ? `\n${title}:\n${cs.map((c) => `- [${c.done ? "x" : " "}] ${c.text}`).join("\n")}`
11
+ : "";
12
+ return [
13
+ `Aerie task ${t.id} (area ${t.area}): ${t.title}`,
14
+ t.description ? `\n${t.description}` : "",
15
+ checks("Acceptance criteria", t.ac),
16
+ checks("Definition of done", t.dod),
17
+ t.plan ? `\nPlan:\n${t.plan}` : "",
18
+ t.notes ? `\nNotes:\n${t.notes}` : "",
19
+ answers.length
20
+ ? `\nDecisions already made for this task. Follow them; do not ask again:\n${answers.map((x) => `- ${x}`).join("\n")}`
21
+ : "",
22
+ "\nDo the task. End with a short summary of what you did; it becomes the task's final summary.",
23
+ `If a person must decide something first, run \`aerie ask "<question>" --option a=<text> --option b=<text> --blocks ${t.id}\` and stop.`,
24
+ ].join("\n");
25
+ }
26
+ const parse = (line) => {
27
+ try {
28
+ return JSON.parse(line);
29
+ }
30
+ catch {
31
+ return null;
32
+ }
33
+ };
34
+ const tail = (s, n = 2000) => (s.length > n ? `…${s.slice(-n)}` : s);
35
+ const failedRun = (r, what) => ({
36
+ outcome: "failed",
37
+ summary: r.aborted
38
+ ? `${what} stopped: the lease was lost or the worker stopped`
39
+ : `${what} exited ${r.code ?? r.killed}${r.stderr.trim() ? `: ${tail(r.stderr.trim(), 600)}` : ""}`,
40
+ data: { code: r.code, signal: r.killed, stderr: r.stderr },
41
+ });
42
+ /** headless default: file edits and the aerie CLI, no other shell */
43
+ export const CLAUDE_TOOLS = ["Read", "Edit", "Write", "Glob", "Grep", "Bash(aerie *)"];
44
+ const textOf = (c) => typeof c === "string"
45
+ ? c
46
+ : Array.isArray(c)
47
+ ? c.map((x) => x.text ?? "").join("")
48
+ : "";
49
+ export function claudeEvent(l) {
50
+ if (l.type === "system")
51
+ return { kind: l.subtype === "init" ? "init" : "line", text: l.subtype, data: l };
52
+ const items = l.message?.content ?? [];
53
+ if (l.type === "assistant") {
54
+ const tool = items.find((i) => i.type === "tool_use");
55
+ if (tool)
56
+ return {
57
+ kind: "tool",
58
+ text: `${tool.name} ${JSON.stringify(tool.input)}`.slice(0, 500),
59
+ data: l,
60
+ };
61
+ return { kind: "say", text: items.map((i) => i.text ?? "").join(""), data: l };
62
+ }
63
+ if (l.type === "user" && items.some((i) => i.type === "tool_result"))
64
+ return {
65
+ kind: "tool-result",
66
+ text: items
67
+ .map((i) => textOf(i.content))
68
+ .join("\n")
69
+ .slice(0, 500),
70
+ data: l,
71
+ };
72
+ return { kind: "line", text: l.type, data: l };
73
+ }
74
+ export function claudeRunner(o = {}) {
75
+ return {
76
+ name: "claude",
77
+ async run(t, ctx) {
78
+ let last = null;
79
+ let session;
80
+ const args = [
81
+ "-p",
82
+ promptOf(t, ctx.answers),
83
+ "--output-format",
84
+ "stream-json",
85
+ "--verbose",
86
+ ...(ctx.model ? ["--model", ctx.model] : []),
87
+ ...(o.args ?? ["--allowedTools", ...CLAUDE_TOOLS]),
88
+ ];
89
+ const r = await runLines(o.bin ?? "claude", args, {
90
+ ...spawnOf(ctx),
91
+ onLine: async (line) => {
92
+ const l = parse(line);
93
+ if (!l)
94
+ return ctx.emit({ kind: "line", text: line.slice(0, 500), data: line });
95
+ session ??= l.session_id;
96
+ if (l.type === "result") {
97
+ last = l;
98
+ return;
99
+ }
100
+ await ctx.emit(claudeEvent(l));
101
+ },
102
+ });
103
+ const res = last;
104
+ if (!res || r.aborted)
105
+ return { ...failedRun(r, "claude"), session };
106
+ const ok = res.subtype === "success" && !res.is_error;
107
+ return {
108
+ outcome: ok ? "done" : "failed",
109
+ summary: res.result?.trim() || res.subtype || "no result",
110
+ usd: res.total_cost_usd,
111
+ session,
112
+ data: res,
113
+ };
114
+ },
115
+ };
116
+ }
117
+ // ── codex: `exec --json`, JSON lines (shape unverified) ──
118
+ /** the last string under a `text` or `message` key, depth first: codex's final message, as best we know */
119
+ function lastText(v) {
120
+ if (!v || typeof v !== "object")
121
+ return null;
122
+ let hit = null;
123
+ for (const [k, x] of Object.entries(v)) {
124
+ if ((k === "text" || k === "message") && typeof x === "string" && x.trim())
125
+ hit = x;
126
+ else
127
+ hit = lastText(x) ?? hit;
128
+ }
129
+ return hit;
130
+ }
131
+ export function codexRunner(o = {}) {
132
+ return {
133
+ name: "codex",
134
+ async run(t, ctx) {
135
+ let summary = null;
136
+ const r = await runLines(o.bin ?? "codex", [
137
+ "exec",
138
+ "--json",
139
+ ...(ctx.model ? ["--model", ctx.model] : []),
140
+ ...(o.args ?? []),
141
+ promptOf(t, ctx.answers),
142
+ ], {
143
+ ...spawnOf(ctx),
144
+ onLine: async (line) => {
145
+ const l = parse(line);
146
+ summary = lastText(l) ?? summary;
147
+ await ctx.emit({ kind: "line", text: line.slice(0, 500), data: l ?? line });
148
+ },
149
+ });
150
+ if (r.aborted || r.code !== 0)
151
+ return failedRun(r, "codex");
152
+ return { outcome: "done", summary: summary ?? "codex exited 0" };
153
+ },
154
+ };
155
+ }
156
+ // ── grok: `-p`, plain text (unverified) ──
157
+ export function grokRunner(o = {}) {
158
+ return {
159
+ name: "grok",
160
+ async run(t, ctx) {
161
+ const out = [];
162
+ const r = await runLines(o.bin ?? "grok", [
163
+ ...(ctx.model ? ["--model", ctx.model] : []),
164
+ ...(o.args ?? []),
165
+ "-p",
166
+ promptOf(t, ctx.answers),
167
+ ], {
168
+ ...spawnOf(ctx),
169
+ onLine: async (line) => {
170
+ out.push(line);
171
+ await ctx.emit({ kind: "line", text: line.slice(0, 500), data: line });
172
+ },
173
+ });
174
+ if (r.aborted || r.code !== 0)
175
+ return failedRun(r, "grok");
176
+ return { outcome: "done", summary: tail(out.join("\n").trim()) || "grok exited 0" };
177
+ },
178
+ };
179
+ }
180
+ // ── autobrowse-do: the title is the goal; `extra.input` {k: v} become --input; first line `<status> via <via>: …` ──
181
+ const DO_LINE = /^(done|needs-human|failed|planned) via (\S+)(?: (\S+))?: (.*)$/;
182
+ export function autobrowseRunner(o = {}) {
183
+ return {
184
+ name: "autobrowse-do",
185
+ async run(t, ctx) {
186
+ const input = (t.extra.input ?? {});
187
+ const out = [];
188
+ let head = null;
189
+ const r = await runLines(o.bin ?? "autobrowse", [
190
+ "do",
191
+ ...Object.entries(input).flatMap(([k, v]) => ["--input", `${k}=${String(v)}`]),
192
+ ...(o.args ?? []),
193
+ t.title,
194
+ ], {
195
+ ...spawnOf(ctx),
196
+ onLine: async (line) => {
197
+ out.push(line);
198
+ head ??= DO_LINE.exec(line);
199
+ await ctx.emit({ kind: "line", text: line.slice(0, 500), data: line });
200
+ },
201
+ });
202
+ const h = head;
203
+ if (r.aborted || !h)
204
+ return failedRun(r, "autobrowse do");
205
+ const status = h[1];
206
+ const summary = `${h[4]} (via ${h[2]}${h[3] ? ` ${h[3]}` : ""})`;
207
+ return {
208
+ // planned (--dry-run): nothing ran; the plan waits for a person's go
209
+ outcome: status === "done" ? "done" : status === "failed" ? "failed" : "needs-input",
210
+ summary,
211
+ ...(status === "planned" ? { question: `Run this plan for real? ${summary}` } : {}),
212
+ session: /^session (\S+)/m.exec(out.join("\n"))?.[1],
213
+ data: { status, via: h[2], name: h[3] ?? null, out: out.join("\n") },
214
+ };
215
+ },
216
+ };
217
+ }
218
+ // ── api: one `ask` through `models`; no tools ──
219
+ const ApiAnswer = z.object({
220
+ outcome: z.enum(["done", "needs-input", "failed"]),
221
+ summary: z.string(),
222
+ question: z.string().optional(),
223
+ });
224
+ export function apiRunner(o) {
225
+ return {
226
+ name: "api",
227
+ async run(t, ctx) {
228
+ const { modelFromSpec } = await import("@wrenautomation/models/spec");
229
+ const spec = ctx.model ?? o.spec;
230
+ const m = modelFromSpec(spec, { ...process.env, ...o.env, ...ctx.env });
231
+ await ctx.emit({ kind: "init", text: m.id, data: { spec, model: m.id } });
232
+ try {
233
+ const { value, usage } = await m.ask(`${promptOf(t, ctx.answers)}\n\nYou have no tools. Answer as JSON: outcome (done, needs-input or failed), summary, and question when a person must decide.`, ApiAnswer);
234
+ await ctx.emit({ kind: "say", text: value.summary, data: { value, usage } });
235
+ return {
236
+ outcome: value.outcome,
237
+ summary: value.summary,
238
+ question: value.question,
239
+ usd: usage?.usd,
240
+ data: { value, usage, model: m.id },
241
+ };
242
+ }
243
+ catch (e) {
244
+ return {
245
+ outcome: "failed",
246
+ summary: `${m.id}: ${e.message}`,
247
+ data: { error: String(e) },
248
+ };
249
+ }
250
+ },
251
+ };
252
+ }
253
+ function spawnOf(ctx) {
254
+ return { cwd: ctx.cwd, env: ctx.env, signal: ctx.signal };
255
+ }
256
+ /** The headless runners from settings: `AERIE_<RUNNER>_BIN`, `AERIE_<RUNNER>_ARGS` (a JSON array), `AERIE_API_MODEL`. */
257
+ export function headlessRunners(get) {
258
+ const opt = (name) => {
259
+ const key = name.toUpperCase().replace(/-/g, "_");
260
+ const args = get(`AERIE_${key}_ARGS`);
261
+ return {
262
+ bin: get(`AERIE_${key}_BIN`),
263
+ args: args ? JSON.parse(args) : undefined,
264
+ };
265
+ };
266
+ const rs = [
267
+ claudeRunner(opt("claude")),
268
+ codexRunner(opt("codex")),
269
+ grokRunner(opt("grok")),
270
+ autobrowseRunner(opt("autobrowse")),
271
+ apiRunner({ spec: get("AERIE_API_MODEL") ?? "openrouter" }),
272
+ ];
273
+ return new Map(rs.map((r) => [r.name, r]));
274
+ }
275
+ //# sourceMappingURL=adapters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapters.js","sourceRoot":"","sources":["../../src/run/adapters.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export * from "./adapters.js";
2
+ export * from "./port.js";
3
+ export * from "./route.js";
4
+ export * from "./worker.js";
@@ -0,0 +1,5 @@
1
+ export * from "./adapters.js";
2
+ export * from "./port.js";
3
+ export * from "./route.js";
4
+ export * from "./worker.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/run/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * The runner port (design: Runners, D18). Every runner names its lane; the five headless ones also run.
3
+ * A session runner has no `run`: the route puts the task on a session lane and that session takes it.
4
+ */
5
+ import type { TaskRecord } from "../core/index.js";
6
+ export declare const RUNNERS: readonly ["claude", "codex", "grok", "api", "autobrowse-do", "session"];
7
+ export type RunnerName = (typeof RUNNERS)[number];
8
+ /** where a routed task waits */
9
+ export declare const runLane: (r: RunnerName) => string;
10
+ export interface Route {
11
+ runner: RunnerName;
12
+ /** a model id or spec the runner takes; null = its default */
13
+ model: string | null;
14
+ /** session runners: the session lane; headless: `run:<runner>` */
15
+ lane: string;
16
+ why: string;
17
+ /** the rule's id, or null when the small model picked */
18
+ rule: number | null;
19
+ by: string;
20
+ }
21
+ /** One row of `task_event` per item: a message, a tool call, a tool result. `data` is the source line, whole. */
22
+ export interface RunEvent {
23
+ kind: "init" | "say" | "tool" | "tool-result" | "line" | "stderr";
24
+ text?: string | undefined;
25
+ data?: unknown | undefined;
26
+ }
27
+ export interface RunResult {
28
+ outcome: "done" | "failed" | "needs-input";
29
+ summary: string;
30
+ /** needs-input from a runner with no shell (api): the worker files it as a decision */
31
+ question?: string | undefined;
32
+ usd?: number | undefined;
33
+ /** the vendor's session or run id, so a person can resume it */
34
+ session?: string | undefined;
35
+ data?: unknown | undefined;
36
+ }
37
+ export interface RunContext {
38
+ /** the routed model, or null */
39
+ model: string | null;
40
+ /** answered decisions on this task, one line each: the prompt says to follow them */
41
+ answers?: string[] | undefined;
42
+ /** the scratch folder the child runs in */
43
+ cwd: string;
44
+ /** env for the child: AERIE_TASK and the like, on top of process.env */
45
+ env: Record<string, string>;
46
+ /** aborted when the lease is lost or the worker stops: the child's process group is killed */
47
+ signal: AbortSignal;
48
+ emit(e: RunEvent): Promise<void>;
49
+ }
50
+ export interface Runner {
51
+ name: RunnerName;
52
+ /** headless only; a run settles, never throws for the child's own failure */
53
+ run?(task: TaskRecord, ctx: RunContext): Promise<RunResult>;
54
+ }
@@ -0,0 +1,4 @@
1
+ export const RUNNERS = ["claude", "codex", "grok", "api", "autobrowse-do", "session"];
2
+ /** where a routed task waits */
3
+ export const runLane = (r) => `run:${r}`;
4
+ //# sourceMappingURL=port.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"port.js","sourceRoot":"","sources":["../../src/run/port.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,EAAE,SAAS,CAAU,CAAC;AAG/F,gCAAgC;AAChC,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAAa,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC"}
@@ -0,0 +1,41 @@
1
+ import type { CoordStore } from "../coord/port.js";
2
+ import { type TaskRecord } from "../core/index.js";
3
+ import type { AerieStore } from "../store.js";
4
+ import { type Route, type RunnerName } from "./port.js";
5
+ /** what each runner is for: the picker reads it */
6
+ export declare const RUNNER_USE: Record<RunnerName, string>;
7
+ export type RunnerPick = {
8
+ runner: RunnerName;
9
+ model: string | null;
10
+ why: string;
11
+ };
12
+ /** the small model's choice; tests pass a fake */
13
+ export type Picker = (t: TaskRecord) => Promise<RunnerPick & {
14
+ by: string;
15
+ }>;
16
+ /** the picker on a `models` spec (setting `router_model`) */
17
+ export declare function modelPicker(spec: string, env?: Record<string, string | undefined>): Picker;
18
+ /** the route only; nothing written */
19
+ export declare function routeOf(a: AerieStore, t: TaskRecord, pick?: Picker): Promise<Route>;
20
+ /** headless: pinned to its lane, so a session serving every lane (`*`) never takes it */
21
+ export declare const queueSpot: (r: Pick<Route, "runner" | "lane">) => {
22
+ lane: string;
23
+ pin?: never;
24
+ } | {
25
+ lane: string;
26
+ pin: string;
27
+ };
28
+ /** route, log, queue; the task's own lane already holding it is fine (queueAdd moves it) */
29
+ export declare function route(a: AerieStore, coord: CoordStore, id: string, by: string, pick?: Picker): Promise<Route>;
30
+ /**
31
+ * After a decision on a task a runner had: back on a lane, or not. Answer `william`: assigned to him, off the queue.
32
+ * `session`: the session lane of its area. Else (`retry`, or words for an agent that asked): routed again.
33
+ */
34
+ export declare function afterDecision(a: AerieStore, coord: CoordStore, d: {
35
+ id: number;
36
+ answer?: string | null | undefined;
37
+ blocks: string[];
38
+ }, by: string, pick?: Picker): Promise<{
39
+ id: string;
40
+ lane: string | null;
41
+ }[]>;
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Route at queue time (D18): the first rule in rank order whose Filter matches wins; no match → the small model
3
+ * (setting `router_model`) picks with a why. One `routed` event, then the task goes on its lane.
4
+ */
5
+ import { z } from "zod";
6
+ import { matches } from "../core/index.js";
7
+ import { AerieError } from "../db.js";
8
+ import { RUNNERS, runLane } from "./port.js";
9
+ /** what each runner is for: the picker reads it */
10
+ export const RUNNER_USE = {
11
+ claude: "code and file work in a repo; shell limited to the aerie CLI",
12
+ codex: "code work, OpenAI's agent",
13
+ grok: "code and research, xAI's agent",
14
+ api: "writing, sorting and short answers; no tools, no files",
15
+ "autobrowse-do": "a chore on a website: the task title is the goal",
16
+ session: "long or judgment-heavy work a live Claude Code session should own",
17
+ };
18
+ const PickAnswer = z.object({
19
+ runner: z.enum(RUNNERS),
20
+ why: z.string().min(1),
21
+ });
22
+ /** the picker on a `models` spec (setting `router_model`) */
23
+ export function modelPicker(spec, env = process.env) {
24
+ return async (t) => {
25
+ const { modelFromSpec } = await import("@wrenautomation/models/spec");
26
+ const m = modelFromSpec(spec, env);
27
+ const list = RUNNERS.map((r) => `- ${r}: ${RUNNER_USE[r]}`).join("\n");
28
+ const { value } = await m.ask([
29
+ "Pick the runner for this task. Runners:",
30
+ list,
31
+ "",
32
+ `Task ${t.id} (area ${t.area}, labels ${t.labels.join(", ") || "none"}): ${t.title}`,
33
+ t.description ? t.description.slice(0, 2000) : "",
34
+ "",
35
+ "Answer as JSON: runner, and why in one short sentence.",
36
+ ].join("\n"), PickAnswer);
37
+ return { runner: value.runner, model: null, why: value.why, by: `agent:${m.id}` };
38
+ };
39
+ }
40
+ /** the route only; nothing written */
41
+ export async function routeOf(a, t, pick) {
42
+ for (const r of await a.routeRules()) {
43
+ if (!matches(t, r.filter))
44
+ continue;
45
+ const runner = r.runner;
46
+ return {
47
+ runner,
48
+ model: r.model,
49
+ lane: runner === "session" ? r.lane : runLane(runner),
50
+ why: r.why,
51
+ rule: r.id,
52
+ by: r.by,
53
+ };
54
+ }
55
+ if (!pick)
56
+ throw new AerieError(`no route rule matches ${t.id} and no router_model is set`, 409);
57
+ const p = await pick(t);
58
+ // the picker has no session lanes to name: a session it picks serves the task's area
59
+ return {
60
+ runner: p.runner,
61
+ model: p.model,
62
+ lane: p.runner === "session" ? t.area : runLane(p.runner),
63
+ why: p.why,
64
+ rule: null,
65
+ by: p.by,
66
+ };
67
+ }
68
+ /** headless: pinned to its lane, so a session serving every lane (`*`) never takes it */
69
+ export const queueSpot = (r) => r.runner === "session" ? { lane: r.lane } : { lane: r.lane, pin: r.lane };
70
+ /** route, log, queue; the task's own lane already holding it is fine (queueAdd moves it) */
71
+ export async function route(a, coord, id, by, pick) {
72
+ const t = await a.get(id);
73
+ if (!t)
74
+ throw new AerieError(`no task ${id}`, 404);
75
+ const r = await routeOf(a, t, pick);
76
+ await a.log(t.id, by, "routed", {
77
+ runner: r.runner,
78
+ model: r.model,
79
+ lane: r.lane,
80
+ rule: r.rule,
81
+ picker: r.rule === null ? r.by : null,
82
+ }, r.why);
83
+ await coord.queueAdd([t.id], queueSpot(r));
84
+ return r;
85
+ }
86
+ /**
87
+ * After a decision on a task a runner had: back on a lane, or not. Answer `william`: assigned to him, off the queue.
88
+ * `session`: the session lane of its area. Else (`retry`, or words for an agent that asked): routed again.
89
+ */
90
+ export async function afterDecision(a, coord, d, by, pick) {
91
+ const out = [];
92
+ for (const id of d.blocks) {
93
+ const t = await a.get(id);
94
+ if (t?.status !== "To Do" || !(await a.lastEvent(t.id, "run.start")))
95
+ continue;
96
+ if (d.answer === "william") {
97
+ await a.edit(t.id, { assignees: ["@william"] }, by, { why: `decision ${d.id}` });
98
+ out.push({ id: t.id, lane: null });
99
+ }
100
+ else if (d.answer === "session") {
101
+ await a.log(t.id, by, "routed", { runner: "session", model: null, lane: t.area, rule: null }, `decision ${d.id}`);
102
+ await coord.queueAdd([t.id], { lane: t.area });
103
+ out.push({ id: t.id, lane: t.area });
104
+ }
105
+ else
106
+ out.push({ id: t.id, lane: (await route(a, coord, t.id, by, pick)).lane });
107
+ }
108
+ return out;
109
+ }
110
+ //# sourceMappingURL=route.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../../src/run/route.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export interface Spawned {
2
+ code: number | null;
3
+ /** the signal that ended it, if any */
4
+ killed: string | null;
5
+ aborted: boolean;
6
+ stderr: string;
7
+ }
8
+ export declare function runLines(bin: string, args: string[], o: {
9
+ cwd: string;
10
+ env: Record<string, string>;
11
+ signal: AbortSignal;
12
+ onLine: (line: string) => Promise<void>;
13
+ }): Promise<Spawned>;