@openagt/agent-runner 0.0.1
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/LICENSE +21 -0
- package/bin/agent-runner +11 -0
- package/dist/cli.d.ts +19 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +208 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +17 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +62 -0
- package/dist/config.js.map +1 -0
- package/dist/ended.d.ts +66 -0
- package/dist/ended.d.ts.map +1 -0
- package/dist/ended.js +114 -0
- package/dist/ended.js.map +1 -0
- package/dist/git-host.d.ts +31 -0
- package/dist/git-host.d.ts.map +1 -0
- package/dist/git-host.js +26 -0
- package/dist/git-host.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +39 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +104 -0
- package/dist/init.js.map +1 -0
- package/dist/live-card.d.ts +27 -0
- package/dist/live-card.d.ts.map +1 -0
- package/dist/live-card.js +56 -0
- package/dist/live-card.js.map +1 -0
- package/dist/names.d.ts +12 -0
- package/dist/names.d.ts.map +1 -0
- package/dist/names.js +12 -0
- package/dist/names.js.map +1 -0
- package/dist/parent.d.ts +47 -0
- package/dist/parent.d.ts.map +1 -0
- package/dist/parent.js +52 -0
- package/dist/parent.js.map +1 -0
- package/dist/records.d.ts +81 -0
- package/dist/records.d.ts.map +1 -0
- package/dist/records.js +89 -0
- package/dist/records.js.map +1 -0
- package/dist/run-lock.d.ts +29 -0
- package/dist/run-lock.d.ts.map +1 -0
- package/dist/run-lock.js +80 -0
- package/dist/run-lock.js.map +1 -0
- package/dist/run.d.ts +169 -0
- package/dist/run.d.ts.map +1 -0
- package/dist/run.js +462 -0
- package/dist/run.js.map +1 -0
- package/dist/runner.d.ts +148 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/runner.js +208 -0
- package/dist/runner.js.map +1 -0
- package/dist/sweep.d.ts +46 -0
- package/dist/sweep.d.ts.map +1 -0
- package/dist/sweep.js +83 -0
- package/dist/sweep.js.map +1 -0
- package/dist/test-repo.d.ts +18 -0
- package/dist/test-repo.d.ts.map +1 -0
- package/dist/test-repo.js +49 -0
- package/dist/test-repo.js.map +1 -0
- package/package.json +54 -0
package/dist/run.js
ADDED
|
@@ -0,0 +1,462 @@
|
|
|
1
|
+
import { hostname } from 'node:os';
|
|
2
|
+
import { mkdir, stat, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { AgentExitError, continuationPrompt, logDiaryFile, parseQuestion, promptOf, takeInbox } from '@openagt/agent-driver';
|
|
5
|
+
import { nodeGitRunner } from '@openagt/agent-data';
|
|
6
|
+
import { agentBranchName, attachCheckout, createCheckout, reclaimWorktree, worktreeBranch, worktreePath } from '@openagt/skill-branches';
|
|
7
|
+
import { findRun, readDiary } from '@openagt/skill-logs';
|
|
8
|
+
import { hideLiveDir, inboxPath, liveDir, readLiveCard, readLiveDiary } from './live-card.js';
|
|
9
|
+
import { forReaders, lasting, markerCard, recordBranchGone, recordRun, runnerMark, startOf, writeMarker } from './records.js';
|
|
10
|
+
import { projectGitHost } from './git-host.js';
|
|
11
|
+
import { acquireRunLock, isPidAlive, releaseRunLock } from './run-lock.js';
|
|
12
|
+
import { runEndedLine } from './ended.js';
|
|
13
|
+
import { childEndedLine, tellParent } from './parent.js';
|
|
14
|
+
/**
|
|
15
|
+
* One run (#1774): a checkout from the branches package, a session from agent-driver, the prompt
|
|
16
|
+
* once, and the agent's own loop to the end. No system prompt and no gates: the
|
|
17
|
+
* command's skill file is the whole instruction, and the agent publishes its own work, when asked
|
|
18
|
+
* to, through the skills in its checkout. How far it takes its work is the run's publish level
|
|
19
|
+
* (`run --publish <commit|branch|pr|merge>`), said in one sentence after the prompt: commit the work,
|
|
20
|
+
* and from there push the branch, open its pull request, or set it to merge once its checks pass.
|
|
21
|
+
* The sentence follows every message the agent is sent, a queued one too, and the record keeps it
|
|
22
|
+
* apart from the message. A run with no level gets its prompt as written, and its agent commits
|
|
23
|
+
* only when the prompt asks.
|
|
24
|
+
* This process records the run and reclaims the checkout when the
|
|
25
|
+
* agent stops; a run that dies is caught by the sweep, which a scheduler runs on every tick.
|
|
26
|
+
*
|
|
27
|
+
* The session keeps the run's live record itself, the card and the diary under `.the-framework/`
|
|
28
|
+
* in the checkout, in the run record's shape; this process adds its mark, the pid and the host,
|
|
29
|
+
* and copies the two files onto the branch unchanged when the run ends. What reaches the agent
|
|
30
|
+
* from outside comes through the session's inbox: a line waiting when a turn ends becomes the
|
|
31
|
+
* next turn; when the last turn ended on a question and nothing waited, the run ends `waiting`,
|
|
32
|
+
* keeps its checkout, and the answer resumes it (`resumeRun`): the same run, the same record,
|
|
33
|
+
* continued.
|
|
34
|
+
*
|
|
35
|
+
* SIGINT or SIGTERM to this process stops the run: the agent's whole process tree is ended
|
|
36
|
+
* through the driver, the run is recorded `stopped`, the checkout reclaimed. That is what a
|
|
37
|
+
* dashboard's Stop sends, the pid being on the live card; nothing else steers a run.
|
|
38
|
+
*
|
|
39
|
+
* One-shot: `agent-runner run <prompt>` runs on its own. A scheduler's tick spawns the same thing
|
|
40
|
+
* with the marker already written and the id chosen.
|
|
41
|
+
*
|
|
42
|
+
* A run may name a follow-up (`run --then <prompt>`): once it ends done with a pull request, a
|
|
43
|
+
* fresh agent, a run of its own with its own record, works on the same branch from the prompt,
|
|
44
|
+
* the first run's id after it. The first agent is told, in a line after its prompt, to publish its
|
|
45
|
+
* work without arming the pull request's merge, whatever level the run was given; the follow-up
|
|
46
|
+
* is given no level, its prompt says what it publishes; the follow-up ending done is when this
|
|
47
|
+
* process merges it, through the project's git host (`git-host.ts`). A follow-up that fails or is
|
|
48
|
+
* stopped leaves the request open, for a person.
|
|
49
|
+
*
|
|
50
|
+
* The pull request a run's branch has is read back the same way, through the git host the project
|
|
51
|
+
* declares; a project with no git host package records none.
|
|
52
|
+
*
|
|
53
|
+
* A run may be started for another run, its parent (`run --parent <id>`), and from a branch other
|
|
54
|
+
* than origin's default (`run --base <ref>`); both are on its record for its whole life. When it
|
|
55
|
+
* ends, however it ends, its parent is told (`parent.ts`).
|
|
56
|
+
*
|
|
57
|
+
* A run that makes its own branch writes down the commit the branch was made at, on its record
|
|
58
|
+
* for its whole life: the run's own work is what came after it, which is how it is still told
|
|
59
|
+
* apart once it is merged. A run given a branch that exists (a follow-up's) writes none: that
|
|
60
|
+
* branch's work began with another run.
|
|
61
|
+
*/
|
|
62
|
+
/** The detail a stopped run's record carries. */
|
|
63
|
+
export const STOPPED_DETAIL = 'stopped by a signal to its process';
|
|
64
|
+
const COMMIT_OPENING = 'When you finish, if you changed any file, commit your work';
|
|
65
|
+
const PUBLISH_OPENING = `${COMMIT_OPENING}, push your branch`;
|
|
66
|
+
/** The sentence after a prompt that says how far to take the work, every level starting with the commit; how is the business of the skills in the checkout. */
|
|
67
|
+
export const PUBLISH_LINES = {
|
|
68
|
+
commit: `${COMMIT_OPENING}.`,
|
|
69
|
+
branch: `${PUBLISH_OPENING} and open no pull request.`,
|
|
70
|
+
pr: `${PUBLISH_OPENING} and open its pull request.`,
|
|
71
|
+
merge: `${PUBLISH_OPENING} and open its pull request, set to merge on its own once its checks pass.`,
|
|
72
|
+
};
|
|
73
|
+
/** The sentence when a follow-up is coming: the agent publishes its work, this process merges the request later. */
|
|
74
|
+
export const HOLD_MERGE_LINE = `${PUBLISH_OPENING} and open its pull request, but do not arm its merge: it is merged for you once a follow-up is done.`;
|
|
75
|
+
/**
|
|
76
|
+
* The sentence a run adds after every prompt of its agent, the first and each message after it:
|
|
77
|
+
* that of its publish level, the hold sentence instead when the run names a follow-up, none for a
|
|
78
|
+
* run with neither. The session sends it after the prompt and writes it down apart from it, so a
|
|
79
|
+
* reader shows the person's words as the person wrote them.
|
|
80
|
+
*/
|
|
81
|
+
export function addedLine(publish, then) {
|
|
82
|
+
return then !== undefined ? HOLD_MERGE_LINE : publish !== undefined ? PUBLISH_LINES[publish] : undefined;
|
|
83
|
+
}
|
|
84
|
+
/** The sentence as a session takes it: named, or left out. */
|
|
85
|
+
function addedOf(publish, then) {
|
|
86
|
+
const added = addedLine(publish, then);
|
|
87
|
+
return added !== undefined ? { added } : {};
|
|
88
|
+
}
|
|
89
|
+
/** Filesystem-safe, time-ordered id from an ISO start: the shape the dashboard sorts runs by. */
|
|
90
|
+
export function runIdFrom(startedAt) {
|
|
91
|
+
return startedAt.replace(/[:.]/g, '-');
|
|
92
|
+
}
|
|
93
|
+
/** The model as a card or a session takes it: named, or left out so the tool starts on its own default. */
|
|
94
|
+
function modelOf(model) {
|
|
95
|
+
return model !== undefined ? { model } : {};
|
|
96
|
+
}
|
|
97
|
+
export async function runCommand(repo, opts) {
|
|
98
|
+
const outcome = await runOnce(repo, opts);
|
|
99
|
+
return opts.then !== undefined ? followUp(repo, outcome, opts.then, opts) : outcome;
|
|
100
|
+
}
|
|
101
|
+
async function runOnce(repo, opts) {
|
|
102
|
+
const git = opts.git ?? nodeGitRunner();
|
|
103
|
+
const now = opts.now ?? (() => new Date());
|
|
104
|
+
const clock = () => now().toISOString();
|
|
105
|
+
const host = opts.host ?? hostname();
|
|
106
|
+
const pid = opts.pid ?? process.pid;
|
|
107
|
+
const startedAt = clock();
|
|
108
|
+
const id = opts.id ?? runIdFrom(startedAt);
|
|
109
|
+
let mark = { host, pid, ...lasting(opts) };
|
|
110
|
+
const log = opts.log ?? (() => { });
|
|
111
|
+
const logs = opts.logs ?? {};
|
|
112
|
+
const isAlive = opts.isAlive ?? isPidAlive;
|
|
113
|
+
const telling = { host, isAlive, ...(opts.resume ? { resume: opts.resume } : {}), log };
|
|
114
|
+
await acquireRunLock(repo, id, { pid, isAlive });
|
|
115
|
+
try {
|
|
116
|
+
// A person's run marks itself; a scheduler's run was marked before it was spawned. The marker
|
|
117
|
+
// is pushed while the checkout is made and the agent starts: pushing takes seconds, and the
|
|
118
|
+
// person watching the run waits on the agent. It never writes `.git/config`, so the agent's own
|
|
119
|
+
// git is never locked out by it. The run's record waits on it, so it lands after.
|
|
120
|
+
const marking = opts.marked
|
|
121
|
+
? Promise.resolve()
|
|
122
|
+
: writeMarker(repo, markerCard({ id, startedAt, prompt: opts.prompt, driver: opts.driver.id, ...modelOf(opts.model), mark }), logs).then(marked => {
|
|
123
|
+
if (!marked.ok && !marked.committed)
|
|
124
|
+
log(`[agent-runner] the run's record could not be written: ${marked.error}`);
|
|
125
|
+
}, err => log(`[agent-runner] the run's record could not be written: ${errorMessage(err)}`));
|
|
126
|
+
// The checkout: the branches package's one sequence, on a fresh branch or the one given.
|
|
127
|
+
// Without one there is no run, and the record says so instead of a marker left running.
|
|
128
|
+
let checkout;
|
|
129
|
+
try {
|
|
130
|
+
checkout = opts.branch !== undefined ? await attachCheckout(repo, { agentId: id, branch: opts.branch }, git) : await createCheckout(repo, { agentId: id, ...(opts.base !== undefined ? { base: opts.base } : {}) }, git);
|
|
131
|
+
}
|
|
132
|
+
catch (err) {
|
|
133
|
+
const detail = `could not create a checkout: ${errorMessage(err)}`;
|
|
134
|
+
const endedAt = clock();
|
|
135
|
+
await marking;
|
|
136
|
+
await recordRun(repo, { ...markerCard({ id, startedAt, prompt: opts.prompt, driver: opts.driver.id, ...modelOf(opts.model), mark }), status: 'failed', endedAt }, [{ kind: 'ended', status: 'failed', detail, at: endedAt }], logs);
|
|
137
|
+
if (opts.parent !== undefined)
|
|
138
|
+
await tellParent(repo, opts.parent, childEndedLine({ id, status: 'failed', detail }), telling);
|
|
139
|
+
return { id, status: 'failed', checkout: { reclaimed: false, reason: 'no checkout' }, detail };
|
|
140
|
+
}
|
|
141
|
+
// Only a branch this run made: one it was given holds another run's work, begun elsewhere.
|
|
142
|
+
if (opts.branch === undefined)
|
|
143
|
+
mark = { ...mark, ...(await startCommit(checkout.path, git)) };
|
|
144
|
+
// Awaited here, not returned: the lock is let go in `finally`, and a bare `return` of the
|
|
145
|
+
// promise would run that before the session ends, leaving the run to the sweep.
|
|
146
|
+
return await session(repo, {
|
|
147
|
+
id,
|
|
148
|
+
checkout,
|
|
149
|
+
card: { id, startedAt, status: 'running', intent: opts.prompt, driver: opts.driver.id, ...modelOf(opts.model), branch: checkout.branch, caller: { runner: mark, pid, host, ...forReaders(mark), kind: 'prompt', workspace: checkout.path } },
|
|
150
|
+
prompt: opts.prompt,
|
|
151
|
+
...addedOf(opts.publish, opts.then),
|
|
152
|
+
driver: opts.driver,
|
|
153
|
+
...modelOf(opts.model),
|
|
154
|
+
...(opts.branchPr ? { prBefore: opts.branchPr } : {}),
|
|
155
|
+
continued: false,
|
|
156
|
+
marking,
|
|
157
|
+
telling,
|
|
158
|
+
git,
|
|
159
|
+
gitHost: opts.gitHost ?? projectGitHost,
|
|
160
|
+
logs,
|
|
161
|
+
log,
|
|
162
|
+
clock,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
finally {
|
|
166
|
+
await releaseRunLock(repo, id, pid).catch(() => { });
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Continue an ended run: the same id, the same record, the same branch. The checkout is the one
|
|
171
|
+
* the run kept, or a new one attached to its branch; a branch that went with the checkout, for
|
|
172
|
+
* holding nothing, starts again from the base the record names, or origin's default branch. The session resumes by the id the
|
|
173
|
+
* record carries; the diary goes on from where it stopped. The prompt is the user's text, or the
|
|
174
|
+
* continuation of the question the run ended on with the given answer. The sentence of the publish
|
|
175
|
+
* level the record keeps is said again after it. A run whose work was landed, its branch gone
|
|
176
|
+
* with that, is no longer recorded as landed once it is on a branch made again: what it does from
|
|
177
|
+
* here is not. A follow-up the record names is still owed: the
|
|
178
|
+
* agent is told again not to arm the merge, and the follow-up runs once this ends done.
|
|
179
|
+
*/
|
|
180
|
+
export async function resumeRun(repo, opts) {
|
|
181
|
+
const resumed = await resumeOnce(repo, opts);
|
|
182
|
+
return resumed.then !== undefined ? followUp(repo, resumed.outcome, resumed.then, { ...opts, ...(resumed.model !== undefined ? { model: resumed.model } : {}) }) : resumed.outcome;
|
|
183
|
+
}
|
|
184
|
+
async function resumeOnce(repo, opts) {
|
|
185
|
+
const git = opts.git ?? nodeGitRunner();
|
|
186
|
+
const now = opts.now ?? (() => new Date());
|
|
187
|
+
const clock = () => now().toISOString();
|
|
188
|
+
const host = opts.host ?? hostname();
|
|
189
|
+
const pid = opts.pid ?? process.pid;
|
|
190
|
+
const logs = opts.logs ?? {};
|
|
191
|
+
const log = opts.log ?? (() => { });
|
|
192
|
+
const id = opts.id;
|
|
193
|
+
const isAlive = opts.isAlive ?? isPidAlive;
|
|
194
|
+
// Another process of this run, the one that ended it and still records and reclaims, or a
|
|
195
|
+
// resume started just before this one, goes first: this one waits, then reads the run as that
|
|
196
|
+
// one left it.
|
|
197
|
+
await acquireRunLock(repo, id, { pid, isAlive });
|
|
198
|
+
try {
|
|
199
|
+
const card = await findRun(repo, opts.id, logs);
|
|
200
|
+
if (!card)
|
|
201
|
+
throw new Error(`no run ${opts.id}`);
|
|
202
|
+
// Every process of this run is gone by now, so a record still saying running is one whose
|
|
203
|
+
// process died before it could end it: the sweep's to close first.
|
|
204
|
+
if (card.status === 'running')
|
|
205
|
+
throw new Error(`run ${opts.id} is still recorded running`);
|
|
206
|
+
const previous = runnerMark(card);
|
|
207
|
+
if (!previous)
|
|
208
|
+
throw new Error(`run ${opts.id} is not this tool's`);
|
|
209
|
+
const diary = (await readDiary(repo, opts.id, logs)) ?? [];
|
|
210
|
+
const sessionId = typeof card.caller?.['sessionId'] === 'string' ? card.caller['sessionId'] : undefined;
|
|
211
|
+
let prompt;
|
|
212
|
+
if (opts.answer !== undefined) {
|
|
213
|
+
const question = [...diary].reverse().find(line => line.kind === 'question');
|
|
214
|
+
const title = typeof question?.['title'] === 'string' ? question['title'] : 'your question';
|
|
215
|
+
prompt = continuationPrompt(title, opts.answer);
|
|
216
|
+
}
|
|
217
|
+
else if (opts.text) {
|
|
218
|
+
prompt = opts.text;
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
throw new Error('a text or an answer is needed to resume a run');
|
|
222
|
+
}
|
|
223
|
+
const branch = card.branch ?? agentBranchName(opts.id);
|
|
224
|
+
const path = worktreePath(repo, opts.id);
|
|
225
|
+
const kept = await stat(path).then(s => s.isDirectory(), () => false);
|
|
226
|
+
const checkout = kept ? { path, branch } : await attachCheckout(repo, { agentId: opts.id, branch, ...(previous.base !== undefined ? { base: previous.base } : {}) }, git);
|
|
227
|
+
// A branch that was gone everywhere was just made again, from where it starts as that is now:
|
|
228
|
+
// that is where the run's own work begins. One still on origin came back with its work.
|
|
229
|
+
const restarted = checkout.again ? await startCommit(checkout.path, git) : {};
|
|
230
|
+
// The record is written running again over the ended one, so every reader sees the run in flight.
|
|
231
|
+
const mark = { host, pid, ...lasting(previous), ...restarted };
|
|
232
|
+
const runningCard = { ...card, status: 'running', caller: { ...card.caller, runner: mark, pid, host, ...forReaders(mark), workspace: checkout.path } };
|
|
233
|
+
delete runningCard.endedAt;
|
|
234
|
+
// A record that says its work was landed lost its branch to that. On a branch made again the
|
|
235
|
+
// work is new and not landed: left on the record, every reader would go on saying it is.
|
|
236
|
+
if (checkout.again)
|
|
237
|
+
delete runningCard.caller?.['landed'];
|
|
238
|
+
const reopened = await recordRun(repo, runningCard, diary, logs);
|
|
239
|
+
if (!reopened.ok && !reopened.committed)
|
|
240
|
+
log(`[agent-runner] the run's record could not be written: ${reopened.error}`);
|
|
241
|
+
const model = opts.model ?? card.model;
|
|
242
|
+
const outcome = await session(repo, {
|
|
243
|
+
id: opts.id,
|
|
244
|
+
checkout,
|
|
245
|
+
card: { ...runningCard },
|
|
246
|
+
priorDiary: diary,
|
|
247
|
+
prompt,
|
|
248
|
+
...addedOf(previous.publish, previous.then),
|
|
249
|
+
driver: opts.driver,
|
|
250
|
+
...modelOf(model),
|
|
251
|
+
continued: true,
|
|
252
|
+
...(sessionId !== undefined ? { resumeSessionId: sessionId } : {}),
|
|
253
|
+
telling: { host, isAlive, ...(opts.resume ? { resume: opts.resume } : {}), log },
|
|
254
|
+
git,
|
|
255
|
+
gitHost: opts.gitHost ?? projectGitHost,
|
|
256
|
+
logs,
|
|
257
|
+
log,
|
|
258
|
+
clock,
|
|
259
|
+
});
|
|
260
|
+
return { outcome, ...(previous.then !== undefined ? { then: previous.then } : {}), ...modelOf(model) };
|
|
261
|
+
}
|
|
262
|
+
finally {
|
|
263
|
+
await releaseRunLock(repo, id, pid).catch(() => { });
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* The follow-up a run named, once the run ended done with a pull request: a fresh agent on the
|
|
268
|
+
* run's branch, a run of its own, given the prompt and the first run's id. When it ends done the
|
|
269
|
+
* first run's request is merged through the project's git host; otherwise the request stays open. A
|
|
270
|
+
* run that did not end done, or opened no request, has nothing to follow up.
|
|
271
|
+
*/
|
|
272
|
+
async function followUp(repo, first, then, opts) {
|
|
273
|
+
if (first.status !== 'done' || !first.pr || !first.branch)
|
|
274
|
+
return first;
|
|
275
|
+
const id = runIdFrom((opts.now ?? (() => new Date()))().toISOString());
|
|
276
|
+
const next = await runCommand(repo, {
|
|
277
|
+
prompt: `${then} ${first.id}`,
|
|
278
|
+
id,
|
|
279
|
+
branch: first.branch,
|
|
280
|
+
branchPr: first.pr,
|
|
281
|
+
driver: opts.nextDriver ? opts.nextDriver(id) : opts.driver,
|
|
282
|
+
...pick(opts, ['model', 'host', 'pid', 'isAlive', 'now', 'git', 'gitHost', 'logs', 'log']),
|
|
283
|
+
});
|
|
284
|
+
if (next.status !== 'done')
|
|
285
|
+
return { ...first, then: next };
|
|
286
|
+
return { ...first, then: { ...next, merge: await (opts.gitHost ?? projectGitHost).mergeRequest(repo, first.pr.number) } };
|
|
287
|
+
}
|
|
288
|
+
function pick(from, keys) {
|
|
289
|
+
const picked = {};
|
|
290
|
+
for (const key of keys)
|
|
291
|
+
if (from[key] !== undefined)
|
|
292
|
+
picked[key] = from[key];
|
|
293
|
+
return picked;
|
|
294
|
+
}
|
|
295
|
+
/** The session, its end, the record and the reclaim: the part a fresh run and a continued one share. */
|
|
296
|
+
async function session(repo, run) {
|
|
297
|
+
const dir = liveDir(run.checkout.path);
|
|
298
|
+
const inbox = inboxPath(run.checkout.path);
|
|
299
|
+
if (run.priorDiary) {
|
|
300
|
+
await mkdir(dir, { recursive: true });
|
|
301
|
+
await writeFile(join(dir, logDiaryFile(run.id)), run.priorDiary.map(line => JSON.stringify(line) + '\n').join(''));
|
|
302
|
+
}
|
|
303
|
+
// A checkout with an untracked directory in it is a dirty tree, which the branches rule never reclaims.
|
|
304
|
+
await hideLiveDir(run.checkout.path).catch(() => { });
|
|
305
|
+
// A signal stops the run: the first aborts the session, which ends the agent's process tree.
|
|
306
|
+
// The handlers stay until this process is done, so a second signal, or one that comes while the
|
|
307
|
+
// run records and reclaims, is ignored instead of killing the process halfway through a write.
|
|
308
|
+
const stop = new AbortController();
|
|
309
|
+
const onSignal = () => stop.abort();
|
|
310
|
+
process.on('SIGINT', onSignal);
|
|
311
|
+
process.on('SIGTERM', onSignal);
|
|
312
|
+
try {
|
|
313
|
+
return await sessionToEnd(repo, run, dir, inbox, stop.signal);
|
|
314
|
+
}
|
|
315
|
+
finally {
|
|
316
|
+
process.off('SIGINT', onSignal);
|
|
317
|
+
process.off('SIGTERM', onSignal);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
async function sessionToEnd(repo, run, dir, inbox, stopped) {
|
|
321
|
+
const { id: _id, status: _status, endedAt: _endedAt, ...startCard } = run.card;
|
|
322
|
+
let status = 'done';
|
|
323
|
+
let detail;
|
|
324
|
+
let branch = run.checkout.branch;
|
|
325
|
+
let pr;
|
|
326
|
+
let question;
|
|
327
|
+
let lastWords = '';
|
|
328
|
+
let driverSession;
|
|
329
|
+
try {
|
|
330
|
+
driverSession = await run.driver.start({
|
|
331
|
+
cwd: run.checkout.path,
|
|
332
|
+
...(run.model !== undefined ? { model: run.model } : {}),
|
|
333
|
+
signal: stopped,
|
|
334
|
+
...(run.resumeSessionId !== undefined ? { resumeSessionId: run.resumeSessionId } : {}),
|
|
335
|
+
log: { dir, card: { id: run.id, ...startCard }, continue: run.continued },
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
catch (err) {
|
|
339
|
+
status = 'failed';
|
|
340
|
+
detail = errorMessage(err);
|
|
341
|
+
}
|
|
342
|
+
try {
|
|
343
|
+
// The prompts this process owes the agent: the run's own, then the lines that reached the
|
|
344
|
+
// inbox after the last turn took it but while the card still said running. Whoever wrote
|
|
345
|
+
// them was told the run has them, so this process sends them before it lets the run go.
|
|
346
|
+
let prompts = [run.prompt];
|
|
347
|
+
let resume = run.continued;
|
|
348
|
+
while (driverSession) {
|
|
349
|
+
status = 'done';
|
|
350
|
+
detail = undefined;
|
|
351
|
+
question = undefined;
|
|
352
|
+
let failure;
|
|
353
|
+
let lastText = '';
|
|
354
|
+
try {
|
|
355
|
+
for (const [i, prompt] of prompts.entries()) {
|
|
356
|
+
// Only the last one drains the inbox: a line written meanwhile comes after these.
|
|
357
|
+
const last = i === prompts.length - 1;
|
|
358
|
+
const turn = await driverSession.prompt(prompt, { ...(last ? { inbox } : {}), ...(resume ? { resume: true } : {}), ...(run.added !== undefined ? { added: run.added } : {}) });
|
|
359
|
+
lastText = turn.text;
|
|
360
|
+
lastWords = turn.text;
|
|
361
|
+
resume = true;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
catch (err) {
|
|
365
|
+
status = 'failed';
|
|
366
|
+
detail = errorMessage(err);
|
|
367
|
+
failure = err;
|
|
368
|
+
}
|
|
369
|
+
if (stopped.aborted) {
|
|
370
|
+
status = 'stopped';
|
|
371
|
+
detail = STOPPED_DETAIL;
|
|
372
|
+
}
|
|
373
|
+
else if (status === 'done') {
|
|
374
|
+
// The last turn asked and nothing waited in the inbox: the run ends here, waiting, and
|
|
375
|
+
// keeps its checkout for the answer to resume it.
|
|
376
|
+
question = parseQuestion(lastText)?.title;
|
|
377
|
+
if (question !== undefined)
|
|
378
|
+
status = 'waiting';
|
|
379
|
+
}
|
|
380
|
+
// Where the work ended up: the agent renames its branch itself, and the pull request it
|
|
381
|
+
// opened, if any, is read back off the branch through the project's git host.
|
|
382
|
+
branch = (await worktreeBranch(run.checkout.path, run.git).catch(() => undefined)) ?? run.checkout.branch;
|
|
383
|
+
pr = await run.gitHost.requestOfBranch(repo, branch).catch(() => undefined);
|
|
384
|
+
const live = driverSession.log;
|
|
385
|
+
if (!live)
|
|
386
|
+
break;
|
|
387
|
+
await live.patch({ branch, ...(pr ? { pr } : {}) });
|
|
388
|
+
// The ended line leaves out a reason the diary already holds: the agent's error line, written
|
|
389
|
+
// just before its process exited, says it, so the ended line says only that the agent exited.
|
|
390
|
+
await live.end(status, status === 'failed' && failure instanceof AgentExitError ? failure.exit : detail);
|
|
391
|
+
await live.settled();
|
|
392
|
+
// The card says ended now, so a line written from here on goes to the project's resume
|
|
393
|
+
// hook, which waits for this process. What is in the inbox was written before: this
|
|
394
|
+
// process's to send. A stopped run was stopped on purpose; what reached it is dropped.
|
|
395
|
+
if (status === 'stopped' || stopped.aborted)
|
|
396
|
+
break;
|
|
397
|
+
const late = await takeInbox(inbox);
|
|
398
|
+
if (late.length === 0)
|
|
399
|
+
break;
|
|
400
|
+
prompts = late.map(promptOf);
|
|
401
|
+
await live.reopen();
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
finally {
|
|
405
|
+
await driverSession?.dispose().catch(() => { });
|
|
406
|
+
}
|
|
407
|
+
// The record: the two files the session kept, copied onto the branch unchanged.
|
|
408
|
+
const live = driverSession?.log;
|
|
409
|
+
const card = (await readLiveCard(run.checkout.path, run.id)) ?? { ...run.card, status, endedAt: run.clock(), branch, ...(pr ? { pr } : {}) };
|
|
410
|
+
const diary = live ? await readLiveDiary(run.checkout.path, run.id) : [...(run.priorDiary ?? []), { kind: 'ended', status, ...(detail !== undefined ? { detail } : {}), at: card.endedAt ?? run.clock() }];
|
|
411
|
+
await run.marking;
|
|
412
|
+
const recorded = await recordRun(repo, card, diary, run.logs);
|
|
413
|
+
if (!recorded.ok && !recorded.committed)
|
|
414
|
+
run.log(`[agent-runner] the run's record could not be written: ${recorded.error}`);
|
|
415
|
+
// The person's line, when this end needs them: a question, or a pull request new to this session.
|
|
416
|
+
await runEndedLine(repo, { id: run.id, prompt: run.card.intent ?? '', status, ...(question !== undefined ? { question } : {}), ...(pr ? { pr } : {}), ...((run.prBefore ?? run.card.pr) ? { prBefore: run.prBefore ?? run.card.pr } : {}) }, { log: run.log });
|
|
417
|
+
// The run's parent, when it has one, is told how it ended, once the branch it would be pointed
|
|
418
|
+
// at is known to have stayed: an empty one goes with the checkout.
|
|
419
|
+
const parent = runnerMark(run.card)?.parent;
|
|
420
|
+
const tell = async (branchStayed) => {
|
|
421
|
+
if (parent === undefined)
|
|
422
|
+
return;
|
|
423
|
+
const line = childEndedLine({ id: run.id, status, ...(detail !== undefined ? { detail } : {}), ...(question !== undefined ? { question } : {}), ...(branchStayed ? { branch } : {}), ...(pr ? { pr } : {}), lastWords });
|
|
424
|
+
await tellParent(repo, parent, line, run.telling);
|
|
425
|
+
};
|
|
426
|
+
// The checkout goes once its branch holds everything in it (the branches rule), and the branch
|
|
427
|
+
// stays on this machine: nothing is pushed here, publishing is the agent's when it was asked, the person's otherwise. A dirty tree
|
|
428
|
+
// keeps the checkout, and the sweep tries again later. A waiting run keeps it on purpose: the
|
|
429
|
+
// answer resumes the run there.
|
|
430
|
+
if (status === 'waiting') {
|
|
431
|
+
await tell(true);
|
|
432
|
+
return outcomeOf(run.id, status, branch, pr, card.cost, { reclaimed: false, reason: 'waiting' }, detail);
|
|
433
|
+
}
|
|
434
|
+
const reclaimed = await reclaimWorktree(repo, run.checkout.path, { birthBranch: agentBranchName(run.id), ...startOf(run.card), git: run.git });
|
|
435
|
+
if (reclaimed.ok) {
|
|
436
|
+
const rewritten = await recordBranchGone(repo, card, diary, reclaimed.branchesDeleted, run.logs);
|
|
437
|
+
if (rewritten && !rewritten.ok && !rewritten.committed)
|
|
438
|
+
run.log(`[agent-runner] the run's record could not be written: ${rewritten.error}`);
|
|
439
|
+
}
|
|
440
|
+
await tell(!(reclaimed.ok && reclaimed.branchesDeleted?.includes(branch)));
|
|
441
|
+
return outcomeOf(run.id, status, branch, pr, card.cost, reclaimed.ok ? { reclaimed: true } : { reclaimed: false, reason: reclaimed.reason }, detail);
|
|
442
|
+
}
|
|
443
|
+
/** The commit a checkout just made is at: where the run's own work begins. Nothing when git cannot say. */
|
|
444
|
+
async function startCommit(checkout, git) {
|
|
445
|
+
const commit = (await git(['rev-parse', '--verify', '--quiet', 'HEAD^{commit}'], checkout).catch(() => '')).trim();
|
|
446
|
+
return commit ? { baseCommit: commit } : {};
|
|
447
|
+
}
|
|
448
|
+
function outcomeOf(id, status, branch, pr, cost, checkout, detail) {
|
|
449
|
+
return {
|
|
450
|
+
id,
|
|
451
|
+
status,
|
|
452
|
+
branch,
|
|
453
|
+
...(pr ? { pr } : {}),
|
|
454
|
+
...(cost !== undefined ? { cost } : {}),
|
|
455
|
+
checkout,
|
|
456
|
+
...(detail !== undefined ? { detail } : {}),
|
|
457
|
+
};
|
|
458
|
+
}
|
|
459
|
+
function errorMessage(err) {
|
|
460
|
+
return err instanceof Error ? err.message : String(err);
|
|
461
|
+
}
|
|
462
|
+
//# sourceMappingURL=run.js.map
|
package/dist/run.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"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"}
|
package/dist/runner.d.ts
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { type CliProbe, type Driver, type DriverReadiness, type PersonalSetup } from '@openagt/agent-driver';
|
|
2
|
+
import { type RunOutcome } from './run.js';
|
|
3
|
+
import type { Publish } from './records.js';
|
|
4
|
+
/** The environment name the tickets skill reads the claiming agent's id from. */
|
|
5
|
+
export declare const AGENT_ID_ENV = "AGENT_ID";
|
|
6
|
+
/** The coding agents a run can be on, by the name the run's record carries. */
|
|
7
|
+
export declare const DRIVER_NAMES: readonly ['claude-code', 'codex'];
|
|
8
|
+
export type DriverName = (typeof DRIVER_NAMES)[number];
|
|
9
|
+
export declare function isDriverName(name: string): name is DriverName;
|
|
10
|
+
/**
|
|
11
|
+
* Whether a run on `driver` can start on this machine, asked before it spends a checkout: the
|
|
12
|
+
* coding agent's CLI is installed and logged in (a problem when not: the session would die
|
|
13
|
+
* before its first turn). Warnings: running as root, and on Codex, skills in `~/.agents/skills`
|
|
14
|
+
* it cannot keep out and `memory` on that does nothing while `skills` is off. What a dashboard's check hook runs, and what a
|
|
15
|
+
* person's run and a scheduler's tick refuse on. The git host is not probed: a project with no
|
|
16
|
+
* git host package runs fine, and one whose git host cannot answer says so in the run's own log.
|
|
17
|
+
*/
|
|
18
|
+
export declare function readyToRun(repo: string, driver: DriverName, deps?: {
|
|
19
|
+
probe?: CliProbe;
|
|
20
|
+
isRoot?: () => boolean;
|
|
21
|
+
agentsSkills?: string;
|
|
22
|
+
}): Promise<DriverReadiness>;
|
|
23
|
+
/** The command line of a spawned run: the model, the coding agent, the follow-up, the publish level, the parent and the base named only when the run has them, so the run's own defaults apply otherwise. */
|
|
24
|
+
export declare function runArgs(run: SpawnedRun): string[];
|
|
25
|
+
/** A run spawned in its own process, its marker already on the branch unless it is to write it itself. */
|
|
26
|
+
export interface SpawnedRun {
|
|
27
|
+
id: string;
|
|
28
|
+
prompt: string;
|
|
29
|
+
/** The run writes its own marker: a person's detached start, answered before the marker is pushed. */
|
|
30
|
+
mark?: boolean;
|
|
31
|
+
model?: string;
|
|
32
|
+
driver?: DriverName;
|
|
33
|
+
/** The follow-up's prompt (`run --then`); a person's start only. */
|
|
34
|
+
then?: string;
|
|
35
|
+
/** How far the run publishes (`run --publish`): a schedule line's level for a scheduler's run, the person's pick for a detached start. */
|
|
36
|
+
publish?: Publish;
|
|
37
|
+
/** The run this one is started for (`run --parent`). */
|
|
38
|
+
parent?: string;
|
|
39
|
+
/** The branch this run's branch starts from (`run --base`). */
|
|
40
|
+
base?: string;
|
|
41
|
+
}
|
|
42
|
+
/** The command line of a spawned resume: the text as the argument, or the answer. */
|
|
43
|
+
export declare function resumeArgs(run: {
|
|
44
|
+
id: string;
|
|
45
|
+
text?: string;
|
|
46
|
+
answer?: string;
|
|
47
|
+
model?: string;
|
|
48
|
+
}): string[];
|
|
49
|
+
/**
|
|
50
|
+
* The run's process, detached from whoever started it: `agent-runner run <prompt> --id <id>`, its
|
|
51
|
+
* stderr kept. The run's lock is taken here before the process exists and handed to it once it
|
|
52
|
+
* does, so the sweep never finds the run with neither a lock nor a checkout while it boots.
|
|
53
|
+
*/
|
|
54
|
+
export declare function spawnRun(repo: string, run: SpawnedRun): Promise<void>;
|
|
55
|
+
/** A resumed run's process, detached the same way: `agent-runner run --resume <id> …`. */
|
|
56
|
+
export declare function spawnResume(repo: string, run: {
|
|
57
|
+
id: string;
|
|
58
|
+
text?: string;
|
|
59
|
+
answer?: string;
|
|
60
|
+
model?: string;
|
|
61
|
+
}): Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* A person's run, answered at once: the run's process spawned detached, the id returned. What a
|
|
64
|
+
* dashboard's start hook runs: it needs the id back now, not when the agent ends. The run's process
|
|
65
|
+
* writes its own marker: pushing it takes seconds, and the page waits on the id.
|
|
66
|
+
*/
|
|
67
|
+
export declare function detachRun(repo: string, opts: {
|
|
68
|
+
prompt: string;
|
|
69
|
+
model?: string;
|
|
70
|
+
driver?: DriverName;
|
|
71
|
+
then?: string;
|
|
72
|
+
publish?: Publish;
|
|
73
|
+
parent?: string;
|
|
74
|
+
base?: string;
|
|
75
|
+
now?: () => Date;
|
|
76
|
+
}, deps?: {
|
|
77
|
+
spawn?: typeof spawnRun;
|
|
78
|
+
}): Promise<{
|
|
79
|
+
id: string;
|
|
80
|
+
driver: DriverName;
|
|
81
|
+
model?: string;
|
|
82
|
+
}>;
|
|
83
|
+
/**
|
|
84
|
+
* An ended run continued in its own process, and answered at once: what a dashboard's resume
|
|
85
|
+
* hook runs. A run this project has no record of is refused here, while someone is still
|
|
86
|
+
* listening; everything after is the resumed run's own record.
|
|
87
|
+
*/
|
|
88
|
+
export declare function detachResume(repo: string, opts: {
|
|
89
|
+
id: string;
|
|
90
|
+
text?: string;
|
|
91
|
+
answer?: string;
|
|
92
|
+
model?: string;
|
|
93
|
+
}, deps?: {
|
|
94
|
+
spawn?: typeof spawnResume;
|
|
95
|
+
}): Promise<{
|
|
96
|
+
id: string;
|
|
97
|
+
}>;
|
|
98
|
+
/**
|
|
99
|
+
* A run of the real project, in this process, on the coding agent named (Claude Code when none is). A
|
|
100
|
+
* scheduler's run comes with its id and its marker already on the branch; a person's run mints its
|
|
101
|
+
* id here and marks itself. A follow-up it names runs on the same coding agent. The model is the
|
|
102
|
+
* one given; none given, the coding agent starts on its own default. A parent it names that has
|
|
103
|
+
* ended by the time this run ends is continued in a process of its own.
|
|
104
|
+
*/
|
|
105
|
+
export declare function runProject(repo: string, opts: {
|
|
106
|
+
prompt: string;
|
|
107
|
+
id?: string;
|
|
108
|
+
mark?: boolean;
|
|
109
|
+
model?: string;
|
|
110
|
+
driver?: DriverName;
|
|
111
|
+
then?: string;
|
|
112
|
+
publish?: Publish;
|
|
113
|
+
parent?: string;
|
|
114
|
+
base?: string;
|
|
115
|
+
log?: (line: string) => void;
|
|
116
|
+
}): Promise<RunOutcome>;
|
|
117
|
+
/** How a run's ended parent is continued: in a process of its own, with the line it is told. */
|
|
118
|
+
export declare function resumeDetached(repo: string): (id: string, line: {
|
|
119
|
+
text: string;
|
|
120
|
+
} | {
|
|
121
|
+
answer: string;
|
|
122
|
+
}) => Promise<void>;
|
|
123
|
+
/**
|
|
124
|
+
* Continue an ended run of the real project, in this process: the user's text, or the answer to
|
|
125
|
+
* the question it ended on. The coding agent is the one the run's record names: the session
|
|
126
|
+
* to resume is its own.
|
|
127
|
+
*/
|
|
128
|
+
export declare function resumeProject(repo: string, opts: {
|
|
129
|
+
id: string;
|
|
130
|
+
text?: string;
|
|
131
|
+
answer?: string;
|
|
132
|
+
model?: string;
|
|
133
|
+
log?: (line: string) => void;
|
|
134
|
+
}, deps?: {
|
|
135
|
+
driverFor?: typeof driverFor;
|
|
136
|
+
}): Promise<RunOutcome>;
|
|
137
|
+
/**
|
|
138
|
+
* The coding agent a run is on, unrestricted either way: Claude Code with permissions bypassed, Codex
|
|
139
|
+
* with full access. The run's agent, when asked to publish, pushes its branch and opens its pull request itself, which
|
|
140
|
+
* Codex's default sandbox (the workspace only) does not allow. The run's id is in the agent's
|
|
141
|
+
* environment, so the claim it makes names the run (the tickets skill reads `AGENT_ID`).
|
|
142
|
+
*
|
|
143
|
+
* The coding agent starts with the person's own setup, as when started by hand, less the parts
|
|
144
|
+
* this machine's config turns off (`personal:` in `config.ts`). How a part is turned off is the
|
|
145
|
+
* adapter's own business.
|
|
146
|
+
*/
|
|
147
|
+
export declare function driverFor(name: DriverName, id: string, personal: PersonalSetup): Driver;
|
|
148
|
+
//# sourceMappingURL=runner.d.ts.map
|