@dougbots/avenor-core 0.9.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/README.md +27 -1
- package/dist/index.d.ts +62 -6
- package/dist/index.js +521 -90
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -50,7 +50,33 @@ const result = await spawnTool({
|
|
|
50
50
|
// { run_id: '...', label: 'reverse-string', supervisor_id: '/path/to/socket' }
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
-
Accepts `agent`, `prompt`, `promptFile`, `label`, `dir`, `timeout`, `model`, `backend`, `serverUrl`, `sessionId`, and `supervisorId` (to target a specific socket).
|
|
53
|
+
Accepts `agent`, `prompt`, `promptFile`, `label`, `dir`, `timeout`, `model`, `thinking`, `backend`, `rosterFile`, `rosterEntry`, `serverUrl`, `sessionId`, and `supervisorId` (to target a specific socket).
|
|
54
|
+
|
|
55
|
+
### Roster selection
|
|
56
|
+
|
|
57
|
+
`rosterFile` is the path to a top-level JSON roster map and `rosterEntry` is the key selected from it. Each entry must contain `backend` and at least one of `agent` or `model`:
|
|
58
|
+
|
|
59
|
+
```json
|
|
60
|
+
{
|
|
61
|
+
"planner": {
|
|
62
|
+
"backend": "opencode-acp",
|
|
63
|
+
"model": "provider/planner"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
A direct roster spawn forwards both selectors and must not also provide `agent`, `model`, or `backend`. Direct mode without a roster allows each of those identity fields to be omitted independently, including a backend-only request; the selected runtime supplies defaults for omitted values. `thinking` is run-level, not a roster field, and is checked against the effective backend. The shared selector validation rejects missing selector pairs, mixed direct/roster fields, and unknown selector keys. Roster-file loading rejects deferred entry fields such as `system`; `thinking` remains a valid run-level option but is never read from a roster entry.
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
await spawnTool({
|
|
72
|
+
prompt: 'Analyze the repository',
|
|
73
|
+
dir: '/repo',
|
|
74
|
+
rosterFile: '/repo/roster.json',
|
|
75
|
+
rosterEntry: 'planner',
|
|
76
|
+
})
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Roster phase selection is resolved by Avenor's Go workflow runners. A roster entry may override backend/agent/model per phase. CLI workflow fallback and nested roster inheritance are CLI-only; stable nesting keeps its existing behavior. A resumed session must use the same effective backend as the original session.
|
|
54
80
|
|
|
55
81
|
### `statusTool`
|
|
56
82
|
|
package/dist/index.d.ts
CHANGED
|
@@ -36,6 +36,8 @@ interface SpawnParams {
|
|
|
36
36
|
thinking?: ThinkingLevel;
|
|
37
37
|
agent_profile?: string;
|
|
38
38
|
backend?: string;
|
|
39
|
+
roster_file?: string;
|
|
40
|
+
roster_entry?: string;
|
|
39
41
|
server_url?: string;
|
|
40
42
|
session_id?: string;
|
|
41
43
|
sentinel_file?: string;
|
|
@@ -43,6 +45,24 @@ interface SpawnParams {
|
|
|
43
45
|
auto_approve?: boolean;
|
|
44
46
|
[key: string]: unknown;
|
|
45
47
|
}
|
|
48
|
+
interface SpawnResult {
|
|
49
|
+
runtime_id?: string;
|
|
50
|
+
session_id?: string;
|
|
51
|
+
on_event?: string;
|
|
52
|
+
sentinel_file?: string;
|
|
53
|
+
broker_url?: string;
|
|
54
|
+
parent_token?: string;
|
|
55
|
+
agent?: string;
|
|
56
|
+
agent_profile?: string;
|
|
57
|
+
model?: string;
|
|
58
|
+
backend?: string;
|
|
59
|
+
roster_file?: string;
|
|
60
|
+
roster_entry?: string;
|
|
61
|
+
effective_agent?: string;
|
|
62
|
+
effective_model?: string;
|
|
63
|
+
effective_backend?: string;
|
|
64
|
+
[key: string]: unknown;
|
|
65
|
+
}
|
|
46
66
|
declare class Client {
|
|
47
67
|
private socket;
|
|
48
68
|
private rl;
|
|
@@ -69,7 +89,7 @@ declare class Client {
|
|
|
69
89
|
status(runtimeId?: string): Promise<Record<string, unknown>>;
|
|
70
90
|
result(runtimeId?: string): Promise<Record<string, unknown>>;
|
|
71
91
|
list(): Promise<Array<Record<string, unknown>>>;
|
|
72
|
-
spawn(params: SpawnParams): Promise<
|
|
92
|
+
spawn(params: SpawnParams): Promise<SpawnResult>;
|
|
73
93
|
shutdown(mode: string): Promise<void>;
|
|
74
94
|
answerPermission(runtimeId: string, requestId: string, optionId: string, message?: string): Promise<void>;
|
|
75
95
|
prompt(runtimeId: string, text: string): Promise<void>;
|
|
@@ -245,6 +265,11 @@ interface RunInfo {
|
|
|
245
265
|
agentProfile?: string;
|
|
246
266
|
backend?: string;
|
|
247
267
|
model?: string;
|
|
268
|
+
effectiveAgent?: string;
|
|
269
|
+
effectiveModel?: string;
|
|
270
|
+
effectiveBackend?: string;
|
|
271
|
+
rosterFile?: string;
|
|
272
|
+
rosterEntry?: string;
|
|
248
273
|
thinking?: ThinkingLevel;
|
|
249
274
|
dir?: string;
|
|
250
275
|
brokerUrl?: string;
|
|
@@ -255,6 +280,14 @@ interface SupervisorOptions {
|
|
|
255
280
|
binaryPath?: string;
|
|
256
281
|
callTimeoutMs?: number;
|
|
257
282
|
}
|
|
283
|
+
/** Metadata retained locally when a follow-up uses a resolved direct identity. */
|
|
284
|
+
interface SpawnMetadata {
|
|
285
|
+
rosterFile?: string;
|
|
286
|
+
rosterEntry?: string;
|
|
287
|
+
effectiveAgent?: string;
|
|
288
|
+
effectiveModel?: string;
|
|
289
|
+
effectiveBackend?: string;
|
|
290
|
+
}
|
|
258
291
|
declare function findAvenorBinary(): string;
|
|
259
292
|
declare class Supervisor {
|
|
260
293
|
private static instance;
|
|
@@ -267,6 +300,7 @@ declare class Supervisor {
|
|
|
267
300
|
private crashed;
|
|
268
301
|
private crashCode;
|
|
269
302
|
private runs;
|
|
303
|
+
private aliases;
|
|
270
304
|
private binaryPath;
|
|
271
305
|
private callTimeoutMs;
|
|
272
306
|
private constructor();
|
|
@@ -277,7 +311,7 @@ declare class Supervisor {
|
|
|
277
311
|
static isCurrentInstance(supervisorId: string): boolean;
|
|
278
312
|
static currentInstance(): Supervisor | null;
|
|
279
313
|
getClient(): Client;
|
|
280
|
-
spawn(params: SpawnParams, runId?: `${string}-${string}-${string}-${string}-${string}
|
|
314
|
+
spawn(params: SpawnParams, runId?: `${string}-${string}-${string}-${string}-${string}`, metadata?: SpawnMetadata): Promise<RunInfo>;
|
|
281
315
|
close(options?: {
|
|
282
316
|
skipShutdown?: boolean;
|
|
283
317
|
}): Promise<void>;
|
|
@@ -287,7 +321,7 @@ declare class Supervisor {
|
|
|
287
321
|
declare function socketsRoot(): string;
|
|
288
322
|
//#endregion
|
|
289
323
|
//#region src/tools/spawn.d.ts
|
|
290
|
-
|
|
324
|
+
interface SpawnToolArgs {
|
|
291
325
|
agent?: string;
|
|
292
326
|
prompt?: string;
|
|
293
327
|
promptFile?: string;
|
|
@@ -298,18 +332,33 @@ declare function spawnTool(args: {
|
|
|
298
332
|
thinking?: ThinkingLevel;
|
|
299
333
|
agentProfile?: string;
|
|
300
334
|
backend?: string;
|
|
335
|
+
rosterFile?: string;
|
|
336
|
+
rosterEntry?: string;
|
|
301
337
|
serverUrl?: string;
|
|
302
338
|
sessionId?: string;
|
|
303
339
|
supervisorId?: string;
|
|
304
340
|
parent_run_id?: string;
|
|
305
|
-
}
|
|
341
|
+
}
|
|
342
|
+
interface SpawnToolResult {
|
|
306
343
|
run_id: string;
|
|
307
344
|
label: string;
|
|
308
345
|
supervisor_id: string;
|
|
309
346
|
runtime_id?: string;
|
|
310
347
|
broker_url?: string;
|
|
311
348
|
parent_token?: string;
|
|
312
|
-
}
|
|
349
|
+
}
|
|
350
|
+
declare const spawnTool: (args: SpawnToolArgs) => Promise<SpawnToolResult>;
|
|
351
|
+
//#endregion
|
|
352
|
+
//#region src/spawn-selection.d.ts
|
|
353
|
+
interface SpawnSelectionInput {
|
|
354
|
+
agent?: string;
|
|
355
|
+
model?: string;
|
|
356
|
+
backend?: string;
|
|
357
|
+
roster_file?: string;
|
|
358
|
+
roster_entry?: string;
|
|
359
|
+
}
|
|
360
|
+
/** Validate the direct-versus-roster selector contract. */
|
|
361
|
+
declare function validateSpawnSelection(input: unknown, rosterConfigured?: boolean): void;
|
|
313
362
|
//#endregion
|
|
314
363
|
//#region src/tools/status.d.ts
|
|
315
364
|
type StatusView = 'lifecycle' | 'full';
|
|
@@ -337,9 +386,15 @@ interface StatusResult {
|
|
|
337
386
|
};
|
|
338
387
|
session_id?: string;
|
|
339
388
|
stop_reason?: string;
|
|
389
|
+
roster_file?: string;
|
|
390
|
+
roster_entry?: string;
|
|
340
391
|
backend?: string;
|
|
341
392
|
agent?: string;
|
|
342
393
|
model?: string;
|
|
394
|
+
agent_profile?: string;
|
|
395
|
+
effective_backend?: string;
|
|
396
|
+
effective_agent?: string;
|
|
397
|
+
effective_model?: string;
|
|
343
398
|
dir?: string;
|
|
344
399
|
parent_id?: string;
|
|
345
400
|
children?: string[];
|
|
@@ -436,6 +491,7 @@ interface FollowUpToolArgs {
|
|
|
436
491
|
interface FollowUpToolResult {
|
|
437
492
|
run_id: string;
|
|
438
493
|
label: string;
|
|
494
|
+
runtime_id?: string;
|
|
439
495
|
}
|
|
440
496
|
declare const followUpTool: (args: FollowUpToolArgs) => Promise<FollowUpToolResult>;
|
|
441
497
|
//#endregion
|
|
@@ -448,4 +504,4 @@ declare function shutdownTool(args: {
|
|
|
448
504
|
cleaned_up: string[];
|
|
449
505
|
}>;
|
|
450
506
|
//#endregion
|
|
451
|
-
export { type Client, DEFAULT_RUN_REDUCER_LIMITS, type Event, type HistoryOptions, type HistoryResult, type InspectResult, type NormalizedRunEvent, type ObserveRunOptions, type ResultResult, type ResultToolArgs, type RunChunkRole, type RunIdentity, type RunInfo, type RunObserver, type RunObserverClient, type RunPermissionOption, type RunPermissionSummary, RunReducer, type RunReducerLimits, type RunSnapshot, type RunSnapshotSeed, type RunToolState, type RunToolSummary, type RunTranscriptEntry, type SpawnParams, type StatusResult, type StatusView, type SubscribeOptions, Supervisor, type SupervisorOptions, type ThinkingLevel, answerPermissionTool, createRunSnapshot, dial, eventsTool, extractEventText, findAvenorBinary, followUpTool, getInstallDir, getVersion, inspectTool, installerBinaryPath, normalizeRunEvent, observeRun, reduceRunSnapshot, resultTool, shutdownTool, socketsRoot, spawnTool, statusTool };
|
|
507
|
+
export { type Client, DEFAULT_RUN_REDUCER_LIMITS, type Event, type FollowUpToolArgs, type FollowUpToolResult, type HistoryOptions, type HistoryResult, type InspectResult, type NormalizedRunEvent, type ObserveRunOptions, type ResultResult, type ResultToolArgs, type RunChunkRole, type RunIdentity, type RunInfo, type RunObserver, type RunObserverClient, type RunPermissionOption, type RunPermissionSummary, RunReducer, type RunReducerLimits, type RunSnapshot, type RunSnapshotSeed, type RunToolState, type RunToolSummary, type RunTranscriptEntry, type SpawnMetadata, type SpawnParams, type SpawnResult, type SpawnSelectionInput, type SpawnToolArgs, type SpawnToolResult, type StatusResult, type StatusToolArgs, type StatusView, type SubscribeOptions, Supervisor, type SupervisorOptions, type ThinkingLevel, answerPermissionTool, createRunSnapshot, dial, eventsTool, extractEventText, findAvenorBinary, followUpTool, getInstallDir, getVersion, inspectTool, installerBinaryPath, normalizeRunEvent, observeRun, reduceRunSnapshot, resultTool, shutdownTool, socketsRoot, spawnTool, statusTool, validateSpawnSelection };
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,8 @@ import * as fs from "node:fs";
|
|
|
6
6
|
import * as os from "node:os";
|
|
7
7
|
import * as path from "node:path";
|
|
8
8
|
import * as crypto from "node:crypto";
|
|
9
|
+
import { umpire } from "@umpire/core";
|
|
10
|
+
import { fromJson } from "@umpire/json";
|
|
9
11
|
//#region src/client.ts
|
|
10
12
|
function normalizeSubscribeOptions(options) {
|
|
11
13
|
if (!options) return void 0;
|
|
@@ -1074,6 +1076,95 @@ function observeRun(client, options = {}) {
|
|
|
1074
1076
|
};
|
|
1075
1077
|
}
|
|
1076
1078
|
//#endregion
|
|
1079
|
+
//#region ../../schemas/spawn_selection.umpire.json
|
|
1080
|
+
var spawn_selection_umpire_default = {
|
|
1081
|
+
version: 1,
|
|
1082
|
+
conditions: { "rosterConfigured": {
|
|
1083
|
+
"type": "boolean",
|
|
1084
|
+
"description": "Whether the caller has a configured roster context"
|
|
1085
|
+
} },
|
|
1086
|
+
fields: {
|
|
1087
|
+
"agent": { "isEmpty": "string" },
|
|
1088
|
+
"model": { "isEmpty": "string" },
|
|
1089
|
+
"backend": { "isEmpty": "string" },
|
|
1090
|
+
"roster_file": { "isEmpty": "string" },
|
|
1091
|
+
"roster_entry": { "isEmpty": "string" }
|
|
1092
|
+
},
|
|
1093
|
+
rules: [
|
|
1094
|
+
{
|
|
1095
|
+
"type": "requires",
|
|
1096
|
+
"field": "roster_file",
|
|
1097
|
+
"dependency": "roster_entry",
|
|
1098
|
+
"reason": "roster_file requires roster_entry"
|
|
1099
|
+
},
|
|
1100
|
+
{
|
|
1101
|
+
"type": "fairWhen",
|
|
1102
|
+
"field": "roster_entry",
|
|
1103
|
+
"when": {
|
|
1104
|
+
"op": "or",
|
|
1105
|
+
"exprs": [{
|
|
1106
|
+
"op": "present",
|
|
1107
|
+
"field": "roster_file"
|
|
1108
|
+
}, {
|
|
1109
|
+
"op": "cond",
|
|
1110
|
+
"condition": "rosterConfigured"
|
|
1111
|
+
}]
|
|
1112
|
+
},
|
|
1113
|
+
"reason": "roster_entry requires roster_file unless a roster context is configured"
|
|
1114
|
+
},
|
|
1115
|
+
{
|
|
1116
|
+
"type": "disables",
|
|
1117
|
+
"source": "roster_entry",
|
|
1118
|
+
"targets": [
|
|
1119
|
+
"agent",
|
|
1120
|
+
"model",
|
|
1121
|
+
"backend"
|
|
1122
|
+
],
|
|
1123
|
+
"reason": "direct identity fields are disabled in roster mode"
|
|
1124
|
+
}
|
|
1125
|
+
]
|
|
1126
|
+
};
|
|
1127
|
+
//#endregion
|
|
1128
|
+
//#region src/spawn-selection.ts
|
|
1129
|
+
const selectorFields = [
|
|
1130
|
+
"agent",
|
|
1131
|
+
"model",
|
|
1132
|
+
"backend",
|
|
1133
|
+
"roster_file",
|
|
1134
|
+
"roster_entry"
|
|
1135
|
+
];
|
|
1136
|
+
const selectorFieldSet = new Set(selectorFields);
|
|
1137
|
+
const parsedSchema = fromJson(spawn_selection_umpire_default);
|
|
1138
|
+
const spawnSelectionUmpire = umpire({
|
|
1139
|
+
fields: parsedSchema.fields,
|
|
1140
|
+
rules: parsedSchema.rules
|
|
1141
|
+
});
|
|
1142
|
+
function assertInput(input) {
|
|
1143
|
+
if (input === null || typeof input !== "object" || Array.isArray(input)) throw new Error("invalid spawn selector: expected an object");
|
|
1144
|
+
for (const key of Object.keys(input)) {
|
|
1145
|
+
if (!selectorFieldSet.has(key)) throw new Error(`invalid spawn selector: unknown field "${key}"`);
|
|
1146
|
+
const value = input[key];
|
|
1147
|
+
if (value !== void 0 && typeof value !== "string") throw new Error(`invalid spawn selector: ${key} must be a string`);
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
/** Validate the direct-versus-roster selector contract. */
|
|
1151
|
+
function validateSpawnSelection(input, rosterConfigured = false) {
|
|
1152
|
+
assertInput(input);
|
|
1153
|
+
if (typeof rosterConfigured !== "boolean") throw new Error("invalid spawn selector: rosterConfigured must be a boolean");
|
|
1154
|
+
const values = {};
|
|
1155
|
+
for (const field of selectorFields) {
|
|
1156
|
+
const value = input[field];
|
|
1157
|
+
if (value !== void 0 && value !== "") values[field] = value;
|
|
1158
|
+
}
|
|
1159
|
+
const availability = spawnSelectionUmpire.check(values, { rosterConfigured });
|
|
1160
|
+
for (const field of selectorFields) {
|
|
1161
|
+
const value = values[field];
|
|
1162
|
+
const status = availability[field];
|
|
1163
|
+
if (value === void 0 || status?.enabled && status.fair) continue;
|
|
1164
|
+
throw new Error(`invalid spawn selector: ${status?.reason ?? `${field} is disabled`}`);
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
//#endregion
|
|
1077
1168
|
//#region src/paths.ts
|
|
1078
1169
|
function avenorHome() {
|
|
1079
1170
|
return process.env.AVENOR_HOME || path.join(os.homedir(), ".avenor");
|
|
@@ -1098,6 +1189,37 @@ function ensureRunPaths(runId) {
|
|
|
1098
1189
|
}
|
|
1099
1190
|
//#endregion
|
|
1100
1191
|
//#region src/supervisor.ts
|
|
1192
|
+
function retainLiveIdentity(runInfo, liveStatus) {
|
|
1193
|
+
const value = (candidate) => typeof candidate === "string" && candidate.length > 0 ? candidate : void 0;
|
|
1194
|
+
const liveIdentity = (effectiveKey, directKey) => {
|
|
1195
|
+
if (typeof liveStatus[effectiveKey] === "string") return {
|
|
1196
|
+
present: true,
|
|
1197
|
+
value: value(liveStatus[effectiveKey])
|
|
1198
|
+
};
|
|
1199
|
+
if (typeof liveStatus[directKey] === "string") return {
|
|
1200
|
+
present: true,
|
|
1201
|
+
value: value(liveStatus[directKey])
|
|
1202
|
+
};
|
|
1203
|
+
return { present: false };
|
|
1204
|
+
};
|
|
1205
|
+
const effectiveAgent = liveIdentity("effective_agent", "agent");
|
|
1206
|
+
const effectiveModel = liveIdentity("effective_model", "model");
|
|
1207
|
+
const effectiveBackend = liveIdentity("effective_backend", "backend");
|
|
1208
|
+
const sessionId = value(liveStatus.session_id);
|
|
1209
|
+
const rosterFilePresent = typeof liveStatus.roster_file === "string";
|
|
1210
|
+
const rosterFile = value(liveStatus.roster_file);
|
|
1211
|
+
const rosterEntryPresent = typeof liveStatus.roster_entry === "string";
|
|
1212
|
+
const rosterEntry = value(liveStatus.roster_entry);
|
|
1213
|
+
const agentProfilePresent = typeof liveStatus.agent_profile === "string";
|
|
1214
|
+
const agentProfile = value(liveStatus.agent_profile);
|
|
1215
|
+
if (effectiveAgent.present) runInfo.agent = runInfo.effectiveAgent = effectiveAgent.value;
|
|
1216
|
+
if (effectiveModel.present) runInfo.model = runInfo.effectiveModel = effectiveModel.value;
|
|
1217
|
+
if (effectiveBackend.present) runInfo.backend = runInfo.effectiveBackend = effectiveBackend.value;
|
|
1218
|
+
if (sessionId) runInfo.sessionId = sessionId;
|
|
1219
|
+
if (rosterFilePresent) runInfo.rosterFile = rosterFile;
|
|
1220
|
+
if (rosterEntryPresent) runInfo.rosterEntry = rosterEntry;
|
|
1221
|
+
if (agentProfilePresent) runInfo.agentProfile = agentProfile;
|
|
1222
|
+
}
|
|
1101
1223
|
function findAvenorBinary() {
|
|
1102
1224
|
const envBin = process.env.AVENOR_BIN;
|
|
1103
1225
|
if (envBin) try {
|
|
@@ -1154,6 +1276,7 @@ var Supervisor = class Supervisor {
|
|
|
1154
1276
|
crashed = false;
|
|
1155
1277
|
crashCode = null;
|
|
1156
1278
|
runs = /* @__PURE__ */ new Map();
|
|
1279
|
+
aliases = /* @__PURE__ */ new Map();
|
|
1157
1280
|
binaryPath;
|
|
1158
1281
|
callTimeoutMs;
|
|
1159
1282
|
constructor(binaryPath, socketPath, opts) {
|
|
@@ -1292,7 +1415,14 @@ var Supervisor = class Supervisor {
|
|
|
1292
1415
|
}
|
|
1293
1416
|
return this.client;
|
|
1294
1417
|
}
|
|
1295
|
-
async spawn(params, runId = crypto.randomUUID()) {
|
|
1418
|
+
async spawn(params, runId = crypto.randomUUID(), metadata) {
|
|
1419
|
+
if (!(typeof params.loop_file === "string" || typeof params.team_file === "string")) validateSpawnSelection({
|
|
1420
|
+
agent: params.agent,
|
|
1421
|
+
model: params.model,
|
|
1422
|
+
backend: params.backend,
|
|
1423
|
+
roster_file: params.roster_file,
|
|
1424
|
+
roster_entry: params.roster_entry
|
|
1425
|
+
});
|
|
1296
1426
|
const client = this.getClient();
|
|
1297
1427
|
const { sentinelPath, eventLogPath } = ensureRunPaths(runId);
|
|
1298
1428
|
const spawnParams = {
|
|
@@ -1301,26 +1431,60 @@ var Supervisor = class Supervisor {
|
|
|
1301
1431
|
sentinel_file: sentinelPath,
|
|
1302
1432
|
on_event: eventLogPath
|
|
1303
1433
|
};
|
|
1434
|
+
if (spawnParams.roster_entry) {
|
|
1435
|
+
for (const field of [
|
|
1436
|
+
"agent",
|
|
1437
|
+
"model",
|
|
1438
|
+
"backend"
|
|
1439
|
+
]) if (spawnParams[field] === "") delete spawnParams[field];
|
|
1440
|
+
}
|
|
1304
1441
|
const result = await client.spawn(spawnParams);
|
|
1442
|
+
let identityResult = result;
|
|
1443
|
+
if (spawnParams.roster_entry && result.runtime_id) {
|
|
1444
|
+
const hasBackend = [result.effective_backend, result.backend].some((value) => typeof value === "string" && value.length > 0);
|
|
1445
|
+
const hasAgentOrModel = [
|
|
1446
|
+
result.effective_agent,
|
|
1447
|
+
result.agent,
|
|
1448
|
+
result.effective_model,
|
|
1449
|
+
result.model
|
|
1450
|
+
].some((value) => typeof value === "string" && value.length > 0);
|
|
1451
|
+
if (!(hasBackend && hasAgentOrModel)) try {
|
|
1452
|
+
identityResult = {
|
|
1453
|
+
...result,
|
|
1454
|
+
...await client.status(result.runtime_id)
|
|
1455
|
+
};
|
|
1456
|
+
} catch {}
|
|
1457
|
+
}
|
|
1458
|
+
const value = (candidate) => typeof candidate === "string" && candidate.length > 0 ? candidate : void 0;
|
|
1459
|
+
const effectiveAgent = metadata?.effectiveAgent ?? value(identityResult.effective_agent) ?? value(identityResult.agent) ?? value(spawnParams.agent);
|
|
1460
|
+
const effectiveModel = metadata?.effectiveModel ?? value(identityResult.effective_model) ?? value(identityResult.model) ?? value(spawnParams.model);
|
|
1461
|
+
const effectiveBackend = metadata?.effectiveBackend ?? value(identityResult.effective_backend) ?? value(identityResult.backend) ?? value(spawnParams.backend);
|
|
1462
|
+
const rosterFile = metadata?.rosterFile ?? value(identityResult.roster_file) ?? value(spawnParams.roster_file);
|
|
1463
|
+
const rosterEntry = metadata?.rosterEntry ?? value(identityResult.roster_entry) ?? value(spawnParams.roster_entry);
|
|
1305
1464
|
const runInfo = {
|
|
1306
1465
|
runId,
|
|
1307
1466
|
label: spawnParams.label ?? runId,
|
|
1308
1467
|
sentinelPath: result.sentinel_file ?? sentinelPath,
|
|
1309
1468
|
eventLogPath: result.on_event ?? eventLogPath,
|
|
1310
|
-
runtimeId:
|
|
1311
|
-
sessionId:
|
|
1312
|
-
agent:
|
|
1313
|
-
agentProfile: spawnParams.agent_profile,
|
|
1314
|
-
backend:
|
|
1315
|
-
model:
|
|
1469
|
+
runtimeId: value(identityResult.runtime_id),
|
|
1470
|
+
sessionId: value(identityResult.session_id),
|
|
1471
|
+
agent: effectiveAgent,
|
|
1472
|
+
agentProfile: value(identityResult.agent_profile) ?? spawnParams.agent_profile,
|
|
1473
|
+
backend: effectiveBackend,
|
|
1474
|
+
model: effectiveModel,
|
|
1475
|
+
effectiveAgent,
|
|
1476
|
+
effectiveModel,
|
|
1477
|
+
effectiveBackend,
|
|
1478
|
+
rosterFile,
|
|
1479
|
+
rosterEntry,
|
|
1316
1480
|
thinking: spawnParams.thinking,
|
|
1317
1481
|
dir: spawnParams.dir,
|
|
1318
1482
|
brokerUrl: result.broker_url,
|
|
1319
1483
|
parentToken: result.parent_token,
|
|
1320
1484
|
autoApprove: spawnParams.auto_approve
|
|
1321
1485
|
};
|
|
1322
|
-
this.runs.set(runInfo.label, runInfo);
|
|
1323
1486
|
this.runs.set(runId, runInfo);
|
|
1487
|
+
this.aliases.set(runInfo.label, runInfo);
|
|
1324
1488
|
return runInfo;
|
|
1325
1489
|
}
|
|
1326
1490
|
async close(options = {}) {
|
|
@@ -1343,6 +1507,7 @@ var Supervisor = class Supervisor {
|
|
|
1343
1507
|
this.crashed = false;
|
|
1344
1508
|
this.crashCode = null;
|
|
1345
1509
|
this.runs.clear();
|
|
1510
|
+
this.aliases.clear();
|
|
1346
1511
|
Supervisor.instance = null;
|
|
1347
1512
|
}
|
|
1348
1513
|
};
|
|
@@ -1388,8 +1553,125 @@ async function getSupervisorClient(supervisorId) {
|
|
|
1388
1553
|
};
|
|
1389
1554
|
}
|
|
1390
1555
|
//#endregion
|
|
1556
|
+
//#region src/tools/run-registry.ts
|
|
1557
|
+
const externalRuns = /* @__PURE__ */ new Map();
|
|
1558
|
+
function runsFor(supervisorId) {
|
|
1559
|
+
let runs = externalRuns.get(supervisorId);
|
|
1560
|
+
if (!runs) {
|
|
1561
|
+
runs = {
|
|
1562
|
+
byRunId: /* @__PURE__ */ new Map(),
|
|
1563
|
+
byAlias: /* @__PURE__ */ new Map()
|
|
1564
|
+
};
|
|
1565
|
+
externalRuns.set(supervisorId, runs);
|
|
1566
|
+
}
|
|
1567
|
+
return runs;
|
|
1568
|
+
}
|
|
1569
|
+
function indexRun(runInfo) {
|
|
1570
|
+
const runs = runsFor(runInfo.supervisorId);
|
|
1571
|
+
runs.byRunId.set(runInfo.runId, runInfo);
|
|
1572
|
+
runs.byAlias.set(runInfo.label, runInfo);
|
|
1573
|
+
if (runInfo.runtimeId) runs.byAlias.set(runInfo.runtimeId, runInfo);
|
|
1574
|
+
}
|
|
1575
|
+
function isSafeRunReference(reference) {
|
|
1576
|
+
return /^[a-zA-Z0-9_-]+$/.test(reference);
|
|
1577
|
+
}
|
|
1578
|
+
function externalRunMetadataPath(runId) {
|
|
1579
|
+
if (!isSafeRunReference(runId)) throw new Error(`unsafe external run reference: ${runId}`);
|
|
1580
|
+
return path.join(runsRoot(), runId, "run.json");
|
|
1581
|
+
}
|
|
1582
|
+
function optionalString(value) {
|
|
1583
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
1584
|
+
}
|
|
1585
|
+
function readPersistedRun(supervisorId, runId) {
|
|
1586
|
+
if (!isSafeRunReference(runId)) return void 0;
|
|
1587
|
+
try {
|
|
1588
|
+
const parsed = JSON.parse(fs.readFileSync(externalRunMetadataPath(runId), "utf-8"));
|
|
1589
|
+
if (parsed.schemaVersion !== 1 || parsed.runId !== runId || parsed.supervisorId !== supervisorId || typeof parsed.label !== "string") return;
|
|
1590
|
+
const runDir = path.join(runsRoot(), runId);
|
|
1591
|
+
const runInfo = {
|
|
1592
|
+
runId,
|
|
1593
|
+
label: parsed.label,
|
|
1594
|
+
supervisorId,
|
|
1595
|
+
sentinelPath: path.join(runDir, "sentinel.done"),
|
|
1596
|
+
eventLogPath: path.join(runDir, "events.log"),
|
|
1597
|
+
runtimeId: optionalString(parsed.runtimeId),
|
|
1598
|
+
sessionId: optionalString(parsed.sessionId),
|
|
1599
|
+
agent: optionalString(parsed.agent),
|
|
1600
|
+
agentProfile: optionalString(parsed.agentProfile),
|
|
1601
|
+
backend: optionalString(parsed.backend),
|
|
1602
|
+
model: optionalString(parsed.model),
|
|
1603
|
+
effectiveAgent: optionalString(parsed.effectiveAgent),
|
|
1604
|
+
effectiveModel: optionalString(parsed.effectiveModel),
|
|
1605
|
+
effectiveBackend: optionalString(parsed.effectiveBackend),
|
|
1606
|
+
rosterFile: optionalString(parsed.rosterFile),
|
|
1607
|
+
rosterEntry: optionalString(parsed.rosterEntry),
|
|
1608
|
+
thinking: parsed.thinking,
|
|
1609
|
+
dir: optionalString(parsed.dir),
|
|
1610
|
+
brokerUrl: optionalString(parsed.brokerUrl),
|
|
1611
|
+
parentToken: optionalString(parsed.parentToken),
|
|
1612
|
+
autoApprove: typeof parsed.autoApprove === "boolean" ? parsed.autoApprove : void 0
|
|
1613
|
+
};
|
|
1614
|
+
indexRun(runInfo);
|
|
1615
|
+
return runInfo;
|
|
1616
|
+
} catch {
|
|
1617
|
+
return;
|
|
1618
|
+
}
|
|
1619
|
+
}
|
|
1620
|
+
/** Persist the public-to-runtime identity for runs spawned through an external supervisor. */
|
|
1621
|
+
function registerExternalRun(runInfo) {
|
|
1622
|
+
const persisted = {
|
|
1623
|
+
schemaVersion: 1,
|
|
1624
|
+
...runInfo,
|
|
1625
|
+
parentToken: void 0
|
|
1626
|
+
};
|
|
1627
|
+
const metadataPath = externalRunMetadataPath(runInfo.runId);
|
|
1628
|
+
const temporaryPath = `${metadataPath}.${process.pid}.${crypto.randomUUID()}.tmp`;
|
|
1629
|
+
fs.writeFileSync(temporaryPath, `${JSON.stringify(persisted, null, 2)}\n`, {
|
|
1630
|
+
mode: 384,
|
|
1631
|
+
flag: "wx"
|
|
1632
|
+
});
|
|
1633
|
+
try {
|
|
1634
|
+
fs.renameSync(temporaryPath, metadataPath);
|
|
1635
|
+
} catch (error) {
|
|
1636
|
+
try {
|
|
1637
|
+
fs.unlinkSync(temporaryPath);
|
|
1638
|
+
} catch {}
|
|
1639
|
+
throw error;
|
|
1640
|
+
}
|
|
1641
|
+
indexRun(runInfo);
|
|
1642
|
+
}
|
|
1643
|
+
function findExternalRun(supervisorId, reference) {
|
|
1644
|
+
const exact = externalRuns.get(supervisorId)?.byRunId.get(reference);
|
|
1645
|
+
if (exact) return exact;
|
|
1646
|
+
const persisted = readPersistedRun(supervisorId, reference);
|
|
1647
|
+
if (persisted) return persisted;
|
|
1648
|
+
listExternalRuns(supervisorId);
|
|
1649
|
+
return externalRuns.get(supervisorId)?.byAlias.get(reference);
|
|
1650
|
+
}
|
|
1651
|
+
function listExternalRuns(supervisorId) {
|
|
1652
|
+
try {
|
|
1653
|
+
for (const entry of fs.readdirSync(runsRoot(), { withFileTypes: true })) if (entry.isDirectory()) readPersistedRun(supervisorId, entry.name);
|
|
1654
|
+
} catch {}
|
|
1655
|
+
return [...externalRuns.get(supervisorId)?.byRunId.values() ?? []];
|
|
1656
|
+
}
|
|
1657
|
+
function forgetExternalRuns(supervisorId) {
|
|
1658
|
+
externalRuns.delete(supervisorId);
|
|
1659
|
+
}
|
|
1660
|
+
function clearExternalRuns(supervisorId) {
|
|
1661
|
+
const runs = listExternalRuns(supervisorId);
|
|
1662
|
+
forgetExternalRuns(supervisorId);
|
|
1663
|
+
return runs;
|
|
1664
|
+
}
|
|
1665
|
+
//#endregion
|
|
1391
1666
|
//#region src/tools/spawn.ts
|
|
1392
|
-
async function
|
|
1667
|
+
async function executeSpawnTool(args, getSupervisorClient) {
|
|
1668
|
+
validateSpawnSelection({
|
|
1669
|
+
agent: args.agent,
|
|
1670
|
+
model: args.model,
|
|
1671
|
+
backend: args.backend,
|
|
1672
|
+
roster_file: args.rosterFile,
|
|
1673
|
+
roster_entry: args.rosterEntry
|
|
1674
|
+
});
|
|
1393
1675
|
const runId = crypto.randomUUID();
|
|
1394
1676
|
const label = args.label ?? runId;
|
|
1395
1677
|
const baseParams = {
|
|
@@ -1405,10 +1687,23 @@ async function spawnTool(args) {
|
|
|
1405
1687
|
session_id: args.sessionId,
|
|
1406
1688
|
parent_run_id: args.parent_run_id
|
|
1407
1689
|
};
|
|
1690
|
+
if (args.rosterFile) baseParams.roster_file = args.rosterFile;
|
|
1691
|
+
if (args.rosterEntry) baseParams.roster_entry = args.rosterEntry;
|
|
1408
1692
|
if (args.agent) baseParams.agent = args.agent;
|
|
1409
1693
|
if (args.thinking !== void 0) baseParams.thinking = args.thinking;
|
|
1410
1694
|
if (args.supervisorId) {
|
|
1411
|
-
const { client, isSingleton, supervisorId } = await getSupervisorClient(args.supervisorId);
|
|
1695
|
+
const { client, isSingleton, sup, supervisorId } = await getSupervisorClient(args.supervisorId);
|
|
1696
|
+
if (isSingleton && sup) {
|
|
1697
|
+
const runInfo = await sup.spawn(baseParams, runId);
|
|
1698
|
+
return {
|
|
1699
|
+
run_id: runInfo.runId,
|
|
1700
|
+
label: runInfo.label,
|
|
1701
|
+
supervisor_id: supervisorId,
|
|
1702
|
+
runtime_id: runInfo.runtimeId,
|
|
1703
|
+
broker_url: runInfo.brokerUrl,
|
|
1704
|
+
parent_token: runInfo.parentToken
|
|
1705
|
+
};
|
|
1706
|
+
}
|
|
1412
1707
|
const { sentinelPath, eventLogPath } = ensureRunPaths(runId);
|
|
1413
1708
|
try {
|
|
1414
1709
|
const result = await client.spawn({
|
|
@@ -1416,13 +1711,37 @@ async function spawnTool(args) {
|
|
|
1416
1711
|
sentinel_file: sentinelPath,
|
|
1417
1712
|
on_event: eventLogPath
|
|
1418
1713
|
});
|
|
1714
|
+
const stringValue = (candidate) => typeof candidate === "string" && candidate.length > 0 ? candidate : void 0;
|
|
1715
|
+
const runtimeId = stringValue(result.runtime_id);
|
|
1716
|
+
registerExternalRun({
|
|
1717
|
+
runId,
|
|
1718
|
+
label,
|
|
1719
|
+
supervisorId,
|
|
1720
|
+
sentinelPath,
|
|
1721
|
+
eventLogPath,
|
|
1722
|
+
runtimeId,
|
|
1723
|
+
sessionId: stringValue(result.session_id),
|
|
1724
|
+
agent: stringValue(result.effective_agent) ?? stringValue(result.agent) ?? baseParams.agent,
|
|
1725
|
+
model: stringValue(result.effective_model) ?? stringValue(result.model) ?? baseParams.model,
|
|
1726
|
+
backend: stringValue(result.effective_backend) ?? stringValue(result.backend) ?? baseParams.backend,
|
|
1727
|
+
effectiveAgent: stringValue(result.effective_agent) ?? stringValue(result.agent) ?? baseParams.agent,
|
|
1728
|
+
effectiveModel: stringValue(result.effective_model) ?? stringValue(result.model) ?? baseParams.model,
|
|
1729
|
+
effectiveBackend: stringValue(result.effective_backend) ?? stringValue(result.backend) ?? baseParams.backend,
|
|
1730
|
+
agentProfile: stringValue(result.agent_profile) ?? baseParams.agent_profile,
|
|
1731
|
+
rosterFile: stringValue(result.roster_file) ?? baseParams.roster_file,
|
|
1732
|
+
rosterEntry: stringValue(result.roster_entry) ?? baseParams.roster_entry,
|
|
1733
|
+
thinking: baseParams.thinking,
|
|
1734
|
+
dir: baseParams.dir,
|
|
1735
|
+
brokerUrl: stringValue(result.broker_url),
|
|
1736
|
+
parentToken: stringValue(result.parent_token)
|
|
1737
|
+
});
|
|
1419
1738
|
return {
|
|
1420
|
-
run_id:
|
|
1739
|
+
run_id: runId,
|
|
1421
1740
|
label,
|
|
1422
1741
|
supervisor_id: supervisorId,
|
|
1423
|
-
runtime_id:
|
|
1424
|
-
broker_url: result.broker_url,
|
|
1425
|
-
parent_token: result.parent_token
|
|
1742
|
+
runtime_id: runtimeId,
|
|
1743
|
+
broker_url: stringValue(result.broker_url),
|
|
1744
|
+
parent_token: stringValue(result.parent_token)
|
|
1426
1745
|
};
|
|
1427
1746
|
} finally {
|
|
1428
1747
|
if (!isSingleton) client.close();
|
|
@@ -1439,14 +1758,25 @@ async function spawnTool(args) {
|
|
|
1439
1758
|
parent_token: runInfo.parentToken
|
|
1440
1759
|
};
|
|
1441
1760
|
}
|
|
1761
|
+
function createSpawnTool(getSupervisorClient) {
|
|
1762
|
+
return (args) => executeSpawnTool(args, getSupervisorClient);
|
|
1763
|
+
}
|
|
1764
|
+
const spawnTool = createSpawnTool(getSupervisorClient);
|
|
1442
1765
|
//#endregion
|
|
1443
|
-
//#region src/tools/
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
const
|
|
1447
|
-
|
|
1448
|
-
|
|
1766
|
+
//#region src/tools/run-resolution.ts
|
|
1767
|
+
/** Resolve a local public run ID before considering a label alias. */
|
|
1768
|
+
function findLocalRunByReference(sup, reference) {
|
|
1769
|
+
const { runs, aliases } = sup;
|
|
1770
|
+
return runs.get(reference) ?? aliases.get(reference);
|
|
1771
|
+
}
|
|
1772
|
+
/** Match a supervisor list entry to its stored runtime identity. */
|
|
1773
|
+
function findLocalRunByRuntimeId(sup, runtimeId) {
|
|
1774
|
+
if (!runtimeId) return void 0;
|
|
1775
|
+
const { runs } = sup;
|
|
1776
|
+
for (const runInfo of runs.values()) if (runInfo.runtimeId === runtimeId) return runInfo;
|
|
1449
1777
|
}
|
|
1778
|
+
//#endregion
|
|
1779
|
+
//#region src/tools/status.ts
|
|
1450
1780
|
async function parseSentinel$1(filePath) {
|
|
1451
1781
|
try {
|
|
1452
1782
|
const content = (await fs.promises.readFile(filePath, "utf-8")).trim();
|
|
@@ -1534,6 +1864,15 @@ function extractPendingPermission(liveStatus) {
|
|
|
1534
1864
|
return normalizePermission(asRecord(pendingPermission));
|
|
1535
1865
|
}
|
|
1536
1866
|
function buildBaseStatus(source, fallback, translatedStatus) {
|
|
1867
|
+
const identity = fallback.identity;
|
|
1868
|
+
const authoritativeValue = (effectiveKey, directKey, fallbackEffective, fallbackDirect) => {
|
|
1869
|
+
if (typeof source[effectiveKey] === "string") return stringField(source, effectiveKey);
|
|
1870
|
+
if (typeof source[directKey] === "string") return stringField(source, directKey);
|
|
1871
|
+
return fallbackEffective ?? fallbackDirect;
|
|
1872
|
+
};
|
|
1873
|
+
const effectiveAgent = authoritativeValue("effective_agent", "agent", identity?.effective_agent, identity?.agent);
|
|
1874
|
+
const effectiveModel = authoritativeValue("effective_model", "model", identity?.effective_model, identity?.model);
|
|
1875
|
+
const effectiveBackend = authoritativeValue("effective_backend", "backend", identity?.effective_backend, identity?.backend);
|
|
1537
1876
|
return {
|
|
1538
1877
|
run_id: fallback.prefer_fallback_run_id ? fallback.run_id : stringField(source, "run_id") ?? fallback.run_id,
|
|
1539
1878
|
label: stringField(source, "label") ?? fallback.label,
|
|
@@ -1544,9 +1883,15 @@ function buildBaseStatus(source, fallback, translatedStatus) {
|
|
|
1544
1883
|
pending_permission: extractPendingPermission(source),
|
|
1545
1884
|
session_id: stringField(source, "session_id") ?? fallback.session_id,
|
|
1546
1885
|
stop_reason: stringField(source, "stop_reason") ?? fallback.stop_reason,
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1886
|
+
roster_file: typeof source.roster_file === "string" ? stringField(source, "roster_file") : identity?.roster_file,
|
|
1887
|
+
roster_entry: typeof source.roster_entry === "string" ? stringField(source, "roster_entry") : identity?.roster_entry,
|
|
1888
|
+
backend: effectiveBackend,
|
|
1889
|
+
agent: effectiveAgent,
|
|
1890
|
+
model: effectiveModel,
|
|
1891
|
+
agent_profile: typeof source.agent_profile === "string" ? stringField(source, "agent_profile") : identity?.agent_profile,
|
|
1892
|
+
effective_backend: effectiveBackend,
|
|
1893
|
+
effective_agent: effectiveAgent,
|
|
1894
|
+
effective_model: effectiveModel,
|
|
1550
1895
|
dir: stringField(source, "dir"),
|
|
1551
1896
|
parent_id: stringField(source, "parent_id", "parentId"),
|
|
1552
1897
|
children: stringArrayField(source, "children"),
|
|
@@ -1573,6 +1918,7 @@ function shapeStatusResult(result, view = "full") {
|
|
|
1573
1918
|
};
|
|
1574
1919
|
}
|
|
1575
1920
|
async function buildRunStatus(runInfo, liveStatus) {
|
|
1921
|
+
if (liveStatus) retainLiveIdentity(runInfo, liveStatus);
|
|
1576
1922
|
let sentinel = null;
|
|
1577
1923
|
if (await sentinelExists(runInfo.sentinelPath)) sentinel = await parseSentinel$1(runInfo.sentinelPath);
|
|
1578
1924
|
const translated = translateStatus(rawStatusPhase(liveStatus), sentinel);
|
|
@@ -1582,7 +1928,18 @@ async function buildRunStatus(runInfo, liveStatus) {
|
|
|
1582
1928
|
prefer_fallback_run_id: true,
|
|
1583
1929
|
runtime_id: runInfo.runtimeId,
|
|
1584
1930
|
session_id: sentinel?.SESSION ?? liveStatus?.session_id ?? runInfo.sessionId,
|
|
1585
|
-
stop_reason: sentinel?.
|
|
1931
|
+
stop_reason: sentinel?.STOP_REASON,
|
|
1932
|
+
identity: {
|
|
1933
|
+
roster_file: runInfo.rosterFile,
|
|
1934
|
+
roster_entry: runInfo.rosterEntry,
|
|
1935
|
+
agent: runInfo.agent,
|
|
1936
|
+
model: runInfo.model,
|
|
1937
|
+
backend: runInfo.backend,
|
|
1938
|
+
agent_profile: runInfo.agentProfile,
|
|
1939
|
+
effective_agent: runInfo.effectiveAgent,
|
|
1940
|
+
effective_model: runInfo.effectiveModel,
|
|
1941
|
+
effective_backend: runInfo.effectiveBackend
|
|
1942
|
+
}
|
|
1586
1943
|
}, translated);
|
|
1587
1944
|
}
|
|
1588
1945
|
async function queryLiveStatus(client, runtimeId) {
|
|
@@ -1595,11 +1952,11 @@ async function queryLiveStatus(client, runtimeId) {
|
|
|
1595
1952
|
}
|
|
1596
1953
|
async function executeStatusTool(args, getSupervisorClient) {
|
|
1597
1954
|
if (args.supervisorId) {
|
|
1598
|
-
const { client, isSingleton, sup } = await getSupervisorClient(args.supervisorId);
|
|
1955
|
+
const { client, isSingleton, sup, supervisorId } = await getSupervisorClient(args.supervisorId);
|
|
1599
1956
|
try {
|
|
1600
1957
|
if (args.runId) {
|
|
1601
1958
|
validateRunId(args.runId);
|
|
1602
|
-
const runInfo = isSingleton && sup ?
|
|
1959
|
+
const runInfo = isSingleton && sup ? findLocalRunByReference(sup, args.runId) : findExternalRun(supervisorId, args.runId);
|
|
1603
1960
|
if (runInfo) return shapeStatusResult(await buildRunStatus(runInfo, await queryLiveStatus(client, runInfo.runtimeId)), args.view);
|
|
1604
1961
|
let liveStatus = await queryLiveStatus(client, args.runId);
|
|
1605
1962
|
if (!liveStatus) try {
|
|
@@ -1617,17 +1974,30 @@ async function executeStatusTool(args, getSupervisorClient) {
|
|
|
1617
1974
|
return shapeStatusResult(buildBaseStatus(liveStatus ?? {}, {
|
|
1618
1975
|
run_id: args.runId,
|
|
1619
1976
|
label: args.runId,
|
|
1977
|
+
prefer_fallback_run_id: true,
|
|
1620
1978
|
runtime_id: stringField(liveStatus ?? {}, "runtime_id", "id"),
|
|
1621
1979
|
session_id: sentinel?.SESSION ?? liveStatus?.session_id,
|
|
1622
|
-
stop_reason: sentinel?.
|
|
1980
|
+
stop_reason: sentinel?.STOP_REASON
|
|
1623
1981
|
}, translateStatus(rawStatusPhase(liveStatus), sentinel)), args.view);
|
|
1624
1982
|
}
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1983
|
+
const list = await client.list();
|
|
1984
|
+
if (!isSingleton) listExternalRuns(supervisorId);
|
|
1985
|
+
const results = [];
|
|
1986
|
+
for (const entry of list) {
|
|
1987
|
+
const entryId = String(entry.runtime_id ?? entry.id ?? "");
|
|
1988
|
+
const runInfo = !isSingleton ? findExternalRun(supervisorId, entryId) ?? findExternalRun(supervisorId, String(entry.run_id ?? "")) ?? findExternalRun(supervisorId, String(entry.label ?? "")) : void 0;
|
|
1989
|
+
if (runInfo) {
|
|
1990
|
+
results.push(shapeStatusResult(await buildRunStatus(runInfo, entry), args.view));
|
|
1991
|
+
continue;
|
|
1992
|
+
}
|
|
1993
|
+
results.push(shapeStatusResult(buildBaseStatus(entry, {
|
|
1994
|
+
run_id: String(entry.run_id ?? entryId),
|
|
1995
|
+
label: String(entry.label ?? entryId),
|
|
1996
|
+
runtime_id: entryId,
|
|
1997
|
+
session_id: entry.session_id
|
|
1998
|
+
}, translateStatus(rawStatusPhase(entry), null)), args.view));
|
|
1999
|
+
}
|
|
2000
|
+
return results;
|
|
1631
2001
|
} finally {
|
|
1632
2002
|
if (!isSingleton) client.close();
|
|
1633
2003
|
}
|
|
@@ -1635,7 +2005,7 @@ async function executeStatusTool(args, getSupervisorClient) {
|
|
|
1635
2005
|
const sup = await Supervisor.get();
|
|
1636
2006
|
const client = sup.getClient();
|
|
1637
2007
|
if (args.runId) {
|
|
1638
|
-
const runInfo =
|
|
2008
|
+
const runInfo = findLocalRunByReference(sup, args.runId);
|
|
1639
2009
|
if (runInfo) return shapeStatusResult(await buildRunStatus(runInfo, await queryLiveStatus(client, runInfo.runtimeId)), args.view);
|
|
1640
2010
|
validateRunId(args.runId);
|
|
1641
2011
|
const liveStatus = await queryLiveStatus(client, args.runId);
|
|
@@ -1647,7 +2017,7 @@ async function executeStatusTool(args, getSupervisorClient) {
|
|
|
1647
2017
|
label: args.runId,
|
|
1648
2018
|
runtime_id: stringField(liveStatus ?? {}, "runtime_id", "id"),
|
|
1649
2019
|
session_id: sentinel?.SESSION ?? liveStatus?.session_id,
|
|
1650
|
-
stop_reason: sentinel?.
|
|
2020
|
+
stop_reason: sentinel?.STOP_REASON
|
|
1651
2021
|
}, translateStatus(rawStatusPhase(liveStatus), sentinel)), args.view);
|
|
1652
2022
|
}
|
|
1653
2023
|
const list = await client.list();
|
|
@@ -1655,9 +2025,9 @@ async function executeStatusTool(args, getSupervisorClient) {
|
|
|
1655
2025
|
for (const entry of list) {
|
|
1656
2026
|
const entryId = String(entry.runtime_id ?? entry.id ?? "");
|
|
1657
2027
|
const entryLabel = String(entry.label ?? entryId);
|
|
1658
|
-
const runInfo =
|
|
2028
|
+
const runInfo = findLocalRunByRuntimeId(sup, entryId) ?? findLocalRunByReference(sup, entryId) ?? findLocalRunByReference(sup, entryLabel);
|
|
1659
2029
|
const liveStatus = runInfo ? await queryLiveStatus(client, runInfo.runtimeId) : null;
|
|
1660
|
-
if (runInfo
|
|
2030
|
+
if (runInfo) results.push(shapeStatusResult(await buildRunStatus(runInfo, liveStatus), args.view));
|
|
1661
2031
|
else results.push(shapeStatusResult(buildBaseStatus(entry, {
|
|
1662
2032
|
run_id: String(entry.run_id ?? entryId),
|
|
1663
2033
|
label: entryLabel,
|
|
@@ -1677,12 +2047,6 @@ const MAX_EVENT_LIMIT = 1e3;
|
|
|
1677
2047
|
const MAX_STRING_CHARS = 4e3;
|
|
1678
2048
|
const MAX_ARRAY_ITEMS = 32;
|
|
1679
2049
|
const MAX_OBJECT_KEYS = 64;
|
|
1680
|
-
function findRunByLabel$2(sup, runId) {
|
|
1681
|
-
const runs = sup.runs;
|
|
1682
|
-
const byKey = runs.get(runId);
|
|
1683
|
-
if (byKey) return byKey;
|
|
1684
|
-
for (const info of runs.values()) if (info.label === runId) return info;
|
|
1685
|
-
}
|
|
1686
2050
|
function normalizeLimit(limit) {
|
|
1687
2051
|
return Math.max(1, Math.min(MAX_EVENT_LIMIT, Math.trunc(limit ?? 50)));
|
|
1688
2052
|
}
|
|
@@ -1752,8 +2116,8 @@ async function readNdjsonEvents(filePath, args) {
|
|
|
1752
2116
|
}
|
|
1753
2117
|
async function resolveRun(args, getSupervisorClient) {
|
|
1754
2118
|
if (args.supervisorId) {
|
|
1755
|
-
const { client, isSingleton, sup } = await getSupervisorClient(args.supervisorId);
|
|
1756
|
-
const runInfo = isSingleton && sup ?
|
|
2119
|
+
const { client, isSingleton, sup, supervisorId } = await getSupervisorClient(args.supervisorId);
|
|
2120
|
+
const runInfo = isSingleton && sup ? findLocalRunByReference(sup, args.runId) : findExternalRun(supervisorId, args.runId);
|
|
1757
2121
|
if (runInfo) return {
|
|
1758
2122
|
client,
|
|
1759
2123
|
isSingleton,
|
|
@@ -1796,7 +2160,7 @@ async function resolveRun(args, getSupervisorClient) {
|
|
|
1796
2160
|
};
|
|
1797
2161
|
}
|
|
1798
2162
|
const sup = await Supervisor.get();
|
|
1799
|
-
const runInfo =
|
|
2163
|
+
const runInfo = findLocalRunByReference(sup, args.runId);
|
|
1800
2164
|
if (runInfo) return {
|
|
1801
2165
|
client: sup.getClient(),
|
|
1802
2166
|
isSingleton: true,
|
|
@@ -1822,6 +2186,7 @@ async function resolveRun(args, getSupervisorClient) {
|
|
|
1822
2186
|
};
|
|
1823
2187
|
}
|
|
1824
2188
|
async function executeEventsTool(args, getSupervisorClient) {
|
|
2189
|
+
validateRunId(args.runId);
|
|
1825
2190
|
const limit = normalizeLimit(args.limit);
|
|
1826
2191
|
const resolved = await resolveRun(args, getSupervisorClient);
|
|
1827
2192
|
try {
|
|
@@ -2030,12 +2395,6 @@ async function resultTool(args) {
|
|
|
2030
2395
|
}
|
|
2031
2396
|
//#endregion
|
|
2032
2397
|
//#region src/tools/answer-permission.ts
|
|
2033
|
-
function findRunByLabel$1(sup, runId) {
|
|
2034
|
-
const runs = sup.runs;
|
|
2035
|
-
const byKey = runs.get(runId);
|
|
2036
|
-
if (byKey) return byKey;
|
|
2037
|
-
for (const info of runs.values()) if (info.label === runId) return info;
|
|
2038
|
-
}
|
|
2039
2398
|
function pendingPermissionRequestID(liveStatus) {
|
|
2040
2399
|
const status = asRecord(liveStatus);
|
|
2041
2400
|
if (!status) return void 0;
|
|
@@ -2055,7 +2414,7 @@ async function answerPermissionTool(args) {
|
|
|
2055
2414
|
}
|
|
2056
2415
|
try {
|
|
2057
2416
|
validateRunId(args.runId);
|
|
2058
|
-
const runtimeId = (sup ?
|
|
2417
|
+
const runtimeId = (sup ? findLocalRunByReference(sup, args.runId) : supervisorId ? findExternalRun(supervisorId, args.runId) : void 0)?.runtimeId ?? args.runId;
|
|
2059
2418
|
if (!requestId) {
|
|
2060
2419
|
requestId = pendingPermissionRequestID(await client.status(runtimeId));
|
|
2061
2420
|
if (!requestId) throw new Error("no pending permission request for this run");
|
|
@@ -2068,20 +2427,18 @@ async function answerPermissionTool(args) {
|
|
|
2068
2427
|
}
|
|
2069
2428
|
//#endregion
|
|
2070
2429
|
//#region src/tools/follow-up.ts
|
|
2071
|
-
function findRunByLabel(sup, runId) {
|
|
2072
|
-
const runs = sup.runs;
|
|
2073
|
-
const byKey = runs.get(runId);
|
|
2074
|
-
if (byKey) return byKey;
|
|
2075
|
-
for (const info of runs.values()) if (info.label === runId) return info;
|
|
2076
|
-
}
|
|
2077
2430
|
function resolveAutoApprove(liveStatus, runInfo) {
|
|
2078
2431
|
const liveAutoApprove = liveStatus?.auto_approve;
|
|
2079
2432
|
if (typeof liveAutoApprove === "boolean") return liveAutoApprove;
|
|
2080
2433
|
return typeof runInfo?.autoApprove === "boolean" ? runInfo.autoApprove : void 0;
|
|
2081
2434
|
}
|
|
2082
|
-
function
|
|
2083
|
-
|
|
2084
|
-
|
|
2435
|
+
function value(candidate) {
|
|
2436
|
+
return typeof candidate === "string" && candidate.length > 0 ? candidate : void 0;
|
|
2437
|
+
}
|
|
2438
|
+
function resolvedIdentity(liveStatus, effectiveKey, directKey, fallbackEffective, fallbackDirect) {
|
|
2439
|
+
if (liveStatus && typeof liveStatus[effectiveKey] === "string") return value(liveStatus[effectiveKey]);
|
|
2440
|
+
if (liveStatus && typeof liveStatus[directKey] === "string") return value(liveStatus[directKey]);
|
|
2441
|
+
return fallbackEffective ?? fallbackDirect;
|
|
2085
2442
|
}
|
|
2086
2443
|
async function parseSentinel(filePath) {
|
|
2087
2444
|
try {
|
|
@@ -2101,85 +2458,144 @@ async function parseSentinel(filePath) {
|
|
|
2101
2458
|
return null;
|
|
2102
2459
|
}
|
|
2103
2460
|
}
|
|
2461
|
+
function rejectSessionConflict(sentinel, liveStatus) {
|
|
2462
|
+
const sentinelStopReason = value(sentinel?.STOP_REASON);
|
|
2463
|
+
const liveStopReason = value(liveStatus?.stop_reason);
|
|
2464
|
+
if (sentinelStopReason === "session_id_conflict" || liveStopReason === "session_id_conflict") throw new Error("run is not resumable: session_id_conflict");
|
|
2465
|
+
}
|
|
2104
2466
|
async function executeFollowUpTool(args, getSupervisorClient) {
|
|
2105
2467
|
if (args.supervisorId) {
|
|
2106
|
-
const { client, isSingleton, sup } = await getSupervisorClient(args.supervisorId);
|
|
2468
|
+
const { client, isSingleton, sup, supervisorId } = await getSupervisorClient(args.supervisorId);
|
|
2107
2469
|
try {
|
|
2108
2470
|
validateRunId(args.runId);
|
|
2109
2471
|
let runInfo;
|
|
2110
|
-
if (isSingleton && sup) runInfo =
|
|
2472
|
+
if (isSingleton && sup) runInfo = findLocalRunByReference(sup, args.runId);
|
|
2473
|
+
else runInfo = findExternalRun(supervisorId, args.runId);
|
|
2111
2474
|
const fallbackSessionId = runInfo?.sessionId;
|
|
2112
2475
|
let liveStatus = null;
|
|
2113
2476
|
try {
|
|
2114
2477
|
liveStatus = await client.status(runInfo?.runtimeId ?? args.runId);
|
|
2115
2478
|
} catch {}
|
|
2116
|
-
const
|
|
2479
|
+
const sentinel = await parseSentinel(liveStatus?.sentinel_file ?? runInfo?.sentinelPath ?? path.join(runsRoot(), args.runId, "sentinel.done"));
|
|
2480
|
+
rejectSessionConflict(sentinel, liveStatus);
|
|
2481
|
+
const sessionId = sentinel?.SESSION ?? liveStatus?.session_id ?? fallbackSessionId;
|
|
2117
2482
|
if (!sessionId) throw new Error("run has no session to resume");
|
|
2118
|
-
const agent =
|
|
2119
|
-
const
|
|
2120
|
-
const
|
|
2483
|
+
const agent = resolvedIdentity(liveStatus, "effective_agent", "agent", runInfo?.effectiveAgent, runInfo?.agent);
|
|
2484
|
+
const model = resolvedIdentity(liveStatus, "effective_model", "model", runInfo?.effectiveModel, runInfo?.model);
|
|
2485
|
+
const backend = resolvedIdentity(liveStatus, "effective_backend", "backend", runInfo?.effectiveBackend, runInfo?.backend);
|
|
2486
|
+
if (runInfo && liveStatus) retainLiveIdentity(runInfo, liveStatus);
|
|
2121
2487
|
const thinking = liveStatus?.thinking ?? runInfo?.thinking;
|
|
2122
2488
|
const dir = liveStatus?.dir ?? runInfo?.dir;
|
|
2123
2489
|
const agentProfile = liveStatus?.agent_profile ?? runInfo?.agentProfile;
|
|
2124
2490
|
const autoApprove = resolveAutoApprove(liveStatus, runInfo);
|
|
2125
2491
|
const followUpRunId = crypto.randomUUID();
|
|
2126
2492
|
const followUpLabel = args.label ?? `${args.runId}-followup`;
|
|
2127
|
-
const { sentinelPath: followUpSentinelPath, eventLogPath } = ensureRunPaths(followUpRunId);
|
|
2128
2493
|
const spawnParams = {
|
|
2129
|
-
agent,
|
|
2130
2494
|
prompt: args.message,
|
|
2131
2495
|
label: followUpLabel,
|
|
2132
|
-
session_id: sessionId
|
|
2133
|
-
sentinel_file: followUpSentinelPath,
|
|
2134
|
-
on_event: eventLogPath
|
|
2496
|
+
session_id: sessionId
|
|
2135
2497
|
};
|
|
2498
|
+
if (agent) spawnParams.agent = agent;
|
|
2136
2499
|
if (backend) spawnParams.backend = backend;
|
|
2137
2500
|
if (model) spawnParams.model = model;
|
|
2138
2501
|
if (thinking) spawnParams.thinking = thinking;
|
|
2139
2502
|
if (dir) spawnParams.dir = dir;
|
|
2140
2503
|
if (agentProfile) spawnParams.agent_profile = agentProfile;
|
|
2141
2504
|
if (autoApprove === true) spawnParams.auto_approve = true;
|
|
2505
|
+
if (isSingleton && sup) {
|
|
2506
|
+
const followUpRun = await sup.spawn(spawnParams, followUpRunId, {
|
|
2507
|
+
rosterFile: runInfo?.rosterFile,
|
|
2508
|
+
rosterEntry: runInfo?.rosterEntry,
|
|
2509
|
+
effectiveAgent: agent,
|
|
2510
|
+
effectiveModel: model,
|
|
2511
|
+
effectiveBackend: backend
|
|
2512
|
+
});
|
|
2513
|
+
return {
|
|
2514
|
+
run_id: followUpRun.runId,
|
|
2515
|
+
label: followUpRun.label,
|
|
2516
|
+
runtime_id: followUpRun.runtimeId
|
|
2517
|
+
};
|
|
2518
|
+
}
|
|
2519
|
+
const { sentinelPath: followUpSentinelPath, eventLogPath } = ensureRunPaths(followUpRunId);
|
|
2520
|
+
spawnParams.sentinel_file = followUpSentinelPath;
|
|
2521
|
+
spawnParams.on_event = eventLogPath;
|
|
2522
|
+
const result = await client.spawn(spawnParams);
|
|
2523
|
+
const runtimeId = value(result.runtime_id);
|
|
2524
|
+
registerExternalRun({
|
|
2525
|
+
runId: followUpRunId,
|
|
2526
|
+
label: followUpLabel,
|
|
2527
|
+
supervisorId,
|
|
2528
|
+
sentinelPath: followUpSentinelPath,
|
|
2529
|
+
eventLogPath,
|
|
2530
|
+
runtimeId,
|
|
2531
|
+
sessionId: value(result.session_id) ?? sessionId,
|
|
2532
|
+
agent,
|
|
2533
|
+
model,
|
|
2534
|
+
backend,
|
|
2535
|
+
effectiveAgent: agent,
|
|
2536
|
+
effectiveModel: model,
|
|
2537
|
+
effectiveBackend: backend,
|
|
2538
|
+
rosterFile: runInfo?.rosterFile,
|
|
2539
|
+
rosterEntry: runInfo?.rosterEntry,
|
|
2540
|
+
thinking,
|
|
2541
|
+
dir,
|
|
2542
|
+
agentProfile,
|
|
2543
|
+
autoApprove
|
|
2544
|
+
});
|
|
2142
2545
|
return {
|
|
2143
|
-
run_id:
|
|
2144
|
-
label: followUpLabel
|
|
2546
|
+
run_id: followUpRunId,
|
|
2547
|
+
label: followUpLabel,
|
|
2548
|
+
runtime_id: runtimeId
|
|
2145
2549
|
};
|
|
2146
2550
|
} finally {
|
|
2147
2551
|
if (!isSingleton) client.close();
|
|
2148
2552
|
}
|
|
2149
2553
|
}
|
|
2150
2554
|
const sup = await Supervisor.get();
|
|
2151
|
-
const runInfo =
|
|
2555
|
+
const runInfo = findLocalRunByReference(sup, args.runId);
|
|
2152
2556
|
if (!runInfo) throw new Error(`run not found: ${args.runId}`);
|
|
2153
|
-
const
|
|
2557
|
+
const sentinel = await parseSentinel(runInfo.sentinelPath);
|
|
2558
|
+
rejectSessionConflict(sentinel, null);
|
|
2559
|
+
const sessionId = sentinel?.SESSION ?? runInfo.sessionId;
|
|
2154
2560
|
if (!sessionId) throw new Error("run has no session to resume");
|
|
2155
2561
|
const client = sup.getClient();
|
|
2156
2562
|
let liveStatus = null;
|
|
2157
2563
|
if (runInfo.runtimeId) try {
|
|
2158
2564
|
liveStatus = await client.status(runInfo.runtimeId);
|
|
2159
2565
|
} catch {}
|
|
2160
|
-
|
|
2161
|
-
const
|
|
2162
|
-
const model = liveStatus
|
|
2566
|
+
rejectSessionConflict(sentinel, liveStatus);
|
|
2567
|
+
const agent = resolvedIdentity(liveStatus, "effective_agent", "agent", runInfo.effectiveAgent, runInfo.agent);
|
|
2568
|
+
const model = resolvedIdentity(liveStatus, "effective_model", "model", runInfo.effectiveModel, runInfo.model);
|
|
2569
|
+
const backend = resolvedIdentity(liveStatus, "effective_backend", "backend", runInfo.effectiveBackend, runInfo.backend);
|
|
2570
|
+
if (liveStatus) retainLiveIdentity(runInfo, liveStatus);
|
|
2163
2571
|
const thinking = liveStatus?.thinking ?? runInfo.thinking;
|
|
2164
2572
|
const dir = liveStatus?.dir ?? runInfo.dir;
|
|
2165
2573
|
const agentProfile = liveStatus?.agent_profile ?? runInfo.agentProfile;
|
|
2166
2574
|
const autoApprove = resolveAutoApprove(liveStatus, runInfo);
|
|
2167
2575
|
const followUpLabel = args.label ?? `${runInfo.label}-followup`;
|
|
2168
|
-
const
|
|
2169
|
-
agent,
|
|
2170
|
-
backend,
|
|
2171
|
-
model,
|
|
2172
|
-
thinking,
|
|
2173
|
-
dir,
|
|
2174
|
-
agent_profile: agentProfile,
|
|
2576
|
+
const followUpParams = {
|
|
2577
|
+
...agent ? { agent } : {},
|
|
2578
|
+
...backend ? { backend } : {},
|
|
2579
|
+
...model ? { model } : {},
|
|
2580
|
+
...thinking ? { thinking } : {},
|
|
2581
|
+
...dir ? { dir } : {},
|
|
2582
|
+
...agentProfile ? { agent_profile: agentProfile } : {},
|
|
2175
2583
|
prompt: args.message,
|
|
2176
2584
|
session_id: sessionId,
|
|
2177
2585
|
label: followUpLabel,
|
|
2178
2586
|
...autoApprove === true ? { auto_approve: true } : {}
|
|
2587
|
+
};
|
|
2588
|
+
const followUpRun = await sup.spawn(followUpParams, void 0, {
|
|
2589
|
+
rosterFile: runInfo.rosterFile,
|
|
2590
|
+
rosterEntry: runInfo.rosterEntry,
|
|
2591
|
+
effectiveAgent: agent,
|
|
2592
|
+
effectiveModel: model,
|
|
2593
|
+
effectiveBackend: backend
|
|
2179
2594
|
});
|
|
2180
2595
|
return {
|
|
2181
2596
|
run_id: followUpRun.runId,
|
|
2182
|
-
label: followUpRun.label
|
|
2597
|
+
label: followUpRun.label,
|
|
2598
|
+
runtime_id: followUpRun.runtimeId
|
|
2183
2599
|
};
|
|
2184
2600
|
}
|
|
2185
2601
|
function createFollowUpTool(getSupervisorClient) {
|
|
@@ -2212,9 +2628,24 @@ async function shutdownTool(args) {
|
|
|
2212
2628
|
const client = await dial(supervisorId);
|
|
2213
2629
|
try {
|
|
2214
2630
|
await client.shutdown(args.force ? "force" : "graceful");
|
|
2215
|
-
}
|
|
2631
|
+
} finally {
|
|
2216
2632
|
client.close();
|
|
2217
2633
|
}
|
|
2634
|
+
for (const info of clearExternalRuns(supervisorId)) {
|
|
2635
|
+
try {
|
|
2636
|
+
await fs.promises.unlink(info.sentinelPath);
|
|
2637
|
+
cleanedUp.push(info.sentinelPath);
|
|
2638
|
+
} catch {}
|
|
2639
|
+
try {
|
|
2640
|
+
await fs.promises.unlink(info.eventLogPath);
|
|
2641
|
+
cleanedUp.push(info.eventLogPath);
|
|
2642
|
+
} catch {}
|
|
2643
|
+
const metadataPath = externalRunMetadataPath(info.runId);
|
|
2644
|
+
try {
|
|
2645
|
+
await fs.promises.unlink(metadataPath);
|
|
2646
|
+
cleanedUp.push(metadataPath);
|
|
2647
|
+
} catch {}
|
|
2648
|
+
}
|
|
2218
2649
|
}
|
|
2219
2650
|
return {
|
|
2220
2651
|
ok: true,
|
|
@@ -2243,4 +2674,4 @@ async function shutdownTool(args) {
|
|
|
2243
2674
|
};
|
|
2244
2675
|
}
|
|
2245
2676
|
//#endregion
|
|
2246
|
-
export { DEFAULT_RUN_REDUCER_LIMITS, RunReducer, Supervisor, answerPermissionTool, createRunSnapshot, dial, eventsTool, extractEventText, findAvenorBinary, followUpTool, getInstallDir, getVersion, inspectTool, installerBinaryPath, normalizeRunEvent, observeRun, reduceRunSnapshot, resultTool, shutdownTool, socketsRoot, spawnTool, statusTool };
|
|
2677
|
+
export { DEFAULT_RUN_REDUCER_LIMITS, RunReducer, Supervisor, answerPermissionTool, createRunSnapshot, dial, eventsTool, extractEventText, findAvenorBinary, followUpTool, getInstallDir, getVersion, inspectTool, installerBinaryPath, normalizeRunEvent, observeRun, reduceRunSnapshot, resultTool, shutdownTool, socketsRoot, spawnTool, statusTool, validateSpawnSelection };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dougbots/avenor-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -34,5 +34,9 @@
|
|
|
34
34
|
"tsdown": "^0.22.0",
|
|
35
35
|
"typescript": "^6.0.3",
|
|
36
36
|
"unrun": "^0.3.0"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@umpire/core": "1.0.1",
|
|
40
|
+
"@umpire/json": "1.0.0"
|
|
37
41
|
}
|
|
38
42
|
}
|