@dougbots/avenor-core 0.7.1 → 0.8.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/dist/index.d.ts CHANGED
@@ -38,6 +38,7 @@ interface SpawnParams {
38
38
  session_id?: string;
39
39
  sentinel_file?: string;
40
40
  on_event?: string;
41
+ auto_approve?: boolean;
41
42
  [key: string]: unknown;
42
43
  }
43
44
  declare class Client {
@@ -67,7 +68,7 @@ declare class Client {
67
68
  list(): Promise<Array<Record<string, unknown>>>;
68
69
  spawn(params: SpawnParams): Promise<Record<string, unknown>>;
69
70
  shutdown(mode: string): Promise<void>;
70
- answerPermission(runtimeId: string, requestId: string, optionId: string): Promise<void>;
71
+ answerPermission(runtimeId: string, requestId: string, optionId: string, message?: string): Promise<void>;
71
72
  prompt(runtimeId: string, text: string): Promise<void>;
72
73
  interruptAndPrompt(runtimeId: string, text: string, keepQueue?: boolean): Promise<void>;
73
74
  cancel(runtimeId?: string): Promise<void>;
@@ -83,6 +84,7 @@ interface RunPermissionOption {
83
84
  option_id: string;
84
85
  label: string;
85
86
  kind: string;
87
+ requires_message?: boolean;
86
88
  }
87
89
  interface RunPermissionSummary {
88
90
  request_id?: string;
@@ -238,9 +240,11 @@ interface RunInfo {
238
240
  agent?: string;
239
241
  agentProfile?: string;
240
242
  backend?: string;
243
+ model?: string;
241
244
  dir?: string;
242
245
  brokerUrl?: string;
243
246
  parentToken?: string;
247
+ autoApprove?: boolean;
244
248
  }
245
249
  interface SupervisorOptions {
246
250
  binaryPath?: string;
@@ -272,6 +276,9 @@ declare class Supervisor {
272
276
  }): Promise<void>;
273
277
  }
274
278
  //#endregion
279
+ //#region src/paths.d.ts
280
+ declare function socketsRoot(): string;
281
+ //#endregion
275
282
  //#region src/tools/spawn.d.ts
276
283
  declare function spawnTool(args: {
277
284
  agent: string;
@@ -312,6 +319,7 @@ interface StatusResult {
312
319
  option_id: string;
313
320
  label: string;
314
321
  kind: string;
322
+ requires_message?: boolean;
315
323
  }>;
316
324
  };
317
325
  session_id?: string;
@@ -322,6 +330,7 @@ interface StatusResult {
322
330
  dir?: string;
323
331
  parent_id?: string;
324
332
  children?: string[];
333
+ pid?: number;
325
334
  event_path?: string;
326
335
  usage?: Record<string, unknown>;
327
336
  latest_seq?: number;
@@ -384,6 +393,7 @@ declare function answerPermissionTool(args: {
384
393
  optionId: string;
385
394
  requestId?: string;
386
395
  supervisorId?: string;
396
+ message?: string;
387
397
  }): Promise<{
388
398
  ok: boolean;
389
399
  }>;
@@ -424,4 +434,4 @@ declare function shutdownTool(args: {
424
434
  cleaned_up: string[];
425
435
  }>;
426
436
  //#endregion
427
- 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, answerPermissionTool, createRunSnapshot, dial, eventsTool, extractEventText, findAvenorBinary, followUpTool, getInstallDir, getVersion, inspectTool, installerBinaryPath, normalizeRunEvent, observeRun, reduceRunSnapshot, resultTool, shutdownTool, spawnTool, statusTool };
437
+ 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, answerPermissionTool, createRunSnapshot, dial, eventsTool, extractEventText, findAvenorBinary, followUpTool, getInstallDir, getVersion, inspectTool, installerBinaryPath, normalizeRunEvent, observeRun, reduceRunSnapshot, resultTool, shutdownTool, socketsRoot, spawnTool, statusTool };
package/dist/index.js CHANGED
@@ -246,12 +246,14 @@ var Client = class {
246
246
  async shutdown(mode) {
247
247
  await this.call("shutdown", { mode });
248
248
  }
249
- async answerPermission(runtimeId, requestId, optionId) {
250
- await this.call("answer_permission", {
249
+ async answerPermission(runtimeId, requestId, optionId, message) {
250
+ const params = {
251
251
  runtime_id: runtimeId,
252
252
  request_id: requestId,
253
253
  option_id: optionId
254
- });
254
+ };
255
+ if (message) params.message = message;
256
+ await this.call("answer_permission", params);
255
257
  }
256
258
  async prompt(runtimeId, text) {
257
259
  await this.call("prompt", {
@@ -363,13 +365,15 @@ function normalizePermissionOptions(value) {
363
365
  const record = asRecord(item);
364
366
  if (!record) continue;
365
367
  const option_id = stringField(record, "option_id", "optionId") ?? "";
366
- const label = stringField(record, "label") ?? option_id;
368
+ const label = stringField(record, "label", "name") ?? option_id;
367
369
  const kind = stringField(record, "kind") ?? "";
370
+ const requires_message = record.requires_message === true || record.requiresMessage === true;
368
371
  if (!option_id && !label && !kind) continue;
369
372
  options.push({
370
373
  option_id,
371
374
  label,
372
- kind
375
+ kind,
376
+ ...requires_message && { requires_message: true }
373
377
  });
374
378
  }
375
379
  return options;
@@ -1271,9 +1275,11 @@ var Supervisor = class Supervisor {
1271
1275
  agent: spawnParams.agent ?? params.agent,
1272
1276
  agentProfile: spawnParams.agent_profile,
1273
1277
  backend: spawnParams.backend,
1278
+ model: spawnParams.model,
1274
1279
  dir: spawnParams.dir,
1275
1280
  brokerUrl: result.broker_url,
1276
- parentToken: result.parent_token
1281
+ parentToken: result.parent_token,
1282
+ autoApprove: spawnParams.auto_approve
1277
1283
  };
1278
1284
  this.runs.set(runInfo.label, runInfo);
1279
1285
  this.runs.set(runId, runInfo);
@@ -1438,6 +1444,9 @@ async function sentinelExists(filePath) {
1438
1444
  return false;
1439
1445
  }
1440
1446
  }
1447
+ function rawStatusPhase(source) {
1448
+ return stringField(source ?? {}, "phase") || stringField(source ?? {}, "status") || "running";
1449
+ }
1441
1450
  function sentinelStatusToResult(sentinelStatus) {
1442
1451
  switch (sentinelStatus) {
1443
1452
  case "DONE": return "done";
@@ -1475,8 +1484,9 @@ function normalizePermission(raw) {
1475
1484
  if (!record) return null;
1476
1485
  return {
1477
1486
  option_id: stringField(record, "option_id", "optionId") ?? "",
1478
- label: stringField(record, "label") ?? "",
1479
- kind: stringField(record, "kind") ?? ""
1487
+ label: stringField(record, "label", "name") ?? "",
1488
+ kind: stringField(record, "kind") ?? "",
1489
+ ...(record.requires_message === true || record.requiresMessage === true) && { requires_message: true }
1480
1490
  };
1481
1491
  }).filter((item) => item !== null) : [];
1482
1492
  if (!request_id && !description && options.length === 0) return;
@@ -1511,6 +1521,7 @@ function buildBaseStatus(source, fallback, translatedStatus) {
1511
1521
  dir: stringField(source, "dir"),
1512
1522
  parent_id: stringField(source, "parent_id", "parentId"),
1513
1523
  children: stringArrayField(source, "children"),
1524
+ pid: typeof source.pid === "number" ? source.pid : void 0,
1514
1525
  event_path: stringField(source, "event_path", "on_event"),
1515
1526
  usage: asRecord(source.usage) ?? void 0,
1516
1527
  latest_seq: numberField(source, "latest_seq"),
@@ -1535,7 +1546,7 @@ function shapeStatusResult(result, view = "full") {
1535
1546
  async function buildRunStatus(runInfo, liveStatus) {
1536
1547
  let sentinel = null;
1537
1548
  if (await sentinelExists(runInfo.sentinelPath)) sentinel = await parseSentinel$1(runInfo.sentinelPath);
1538
- const translated = translateStatus(liveStatus?.phase ?? liveStatus?.status ?? "running", sentinel);
1549
+ const translated = translateStatus(rawStatusPhase(liveStatus), sentinel);
1539
1550
  return buildBaseStatus(liveStatus ?? {}, {
1540
1551
  run_id: runInfo.runId,
1541
1552
  label: runInfo.label,
@@ -1580,14 +1591,14 @@ async function statusTool(args) {
1580
1591
  runtime_id: stringField(liveStatus ?? {}, "runtime_id", "id"),
1581
1592
  session_id: sentinel?.SESSION ?? liveStatus?.session_id,
1582
1593
  stop_reason: sentinel?._status
1583
- }, translateStatus(liveStatus?.phase ?? liveStatus?.status ?? "running", sentinel)), args.view);
1594
+ }, translateStatus(rawStatusPhase(liveStatus), sentinel)), args.view);
1584
1595
  }
1585
1596
  return (await client.list()).map((entry) => shapeStatusResult(buildBaseStatus(entry, {
1586
1597
  run_id: String(entry.run_id ?? entry.runtime_id ?? entry.id ?? ""),
1587
1598
  label: String(entry.label ?? entry.runtime_id ?? entry.id ?? ""),
1588
1599
  runtime_id: String(entry.runtime_id ?? entry.id ?? ""),
1589
1600
  session_id: entry.session_id
1590
- }, translateStatus(entry.phase ?? entry.status ?? "running", null)), args.view));
1601
+ }, translateStatus(rawStatusPhase(entry), null)), args.view));
1591
1602
  } finally {
1592
1603
  if (!isSingleton) client.close();
1593
1604
  }
@@ -1608,7 +1619,7 @@ async function statusTool(args) {
1608
1619
  runtime_id: stringField(liveStatus ?? {}, "runtime_id", "id"),
1609
1620
  session_id: sentinel?.SESSION ?? liveStatus?.session_id,
1610
1621
  stop_reason: sentinel?._status
1611
- }, translateStatus(liveStatus?.phase ?? liveStatus?.status ?? "running", sentinel)), args.view);
1622
+ }, translateStatus(rawStatusPhase(liveStatus), sentinel)), args.view);
1612
1623
  }
1613
1624
  const list = await client.list();
1614
1625
  const results = [];
@@ -1623,7 +1634,7 @@ async function statusTool(args) {
1623
1634
  label: entryLabel,
1624
1635
  runtime_id: entryId,
1625
1636
  session_id: entry.session_id
1626
- }, translateStatus(entry.phase ?? entry.status ?? "running", null)), args.view));
1637
+ }, translateStatus(rawStatusPhase(entry), null)), args.view));
1627
1638
  }
1628
1639
  return results;
1629
1640
  }
@@ -1981,6 +1992,12 @@ function findRunByLabel$1(sup, runId) {
1981
1992
  if (byKey) return byKey;
1982
1993
  for (const info of runs.values()) if (info.label === runId) return info;
1983
1994
  }
1995
+ function pendingPermissionRequestID(liveStatus) {
1996
+ const status = asRecord(liveStatus);
1997
+ if (!status) return void 0;
1998
+ const permission = asRecord(status.permission) ?? asRecord(status.pending_permission);
1999
+ return permission ? stringField(permission, "request_id", "requestId") : void 0;
2000
+ }
1984
2001
  async function answerPermissionTool(args) {
1985
2002
  let client;
1986
2003
  let sup = null;
@@ -1996,11 +2013,10 @@ async function answerPermissionTool(args) {
1996
2013
  validateRunId(args.runId);
1997
2014
  const runtimeId = (sup ? findRunByLabel$1(sup, args.runId) : void 0)?.runtimeId ?? args.runId;
1998
2015
  if (!requestId) {
1999
- const pp = (await client.status(runtimeId))?.pending_permission;
2000
- if (!pp?.request_id) throw new Error("no pending permission request for this run");
2001
- requestId = pp.request_id;
2016
+ requestId = pendingPermissionRequestID(await client.status(runtimeId));
2017
+ if (!requestId) throw new Error("no pending permission request for this run");
2002
2018
  }
2003
- await client.answerPermission(runtimeId, requestId, args.optionId);
2019
+ await client.answerPermission(runtimeId, requestId, args.optionId, args.message);
2004
2020
  return { ok: true };
2005
2021
  } finally {
2006
2022
  if (supervisorId && !isSingleton) client.close();
@@ -2014,6 +2030,11 @@ function findRunByLabel(sup, runId) {
2014
2030
  if (byKey) return byKey;
2015
2031
  for (const info of runs.values()) if (info.label === runId) return info;
2016
2032
  }
2033
+ function resolveAutoApprove(liveStatus, runInfo) {
2034
+ const liveAutoApprove = liveStatus?.auto_approve;
2035
+ if (typeof liveAutoApprove === "boolean") return liveAutoApprove;
2036
+ return typeof runInfo?.autoApprove === "boolean" ? runInfo.autoApprove : void 0;
2037
+ }
2017
2038
  function requireResumableAgent(agent) {
2018
2039
  if (agent === void 0) throw new Error("run has no agent to resume");
2019
2040
  return agent;
@@ -2046,14 +2067,16 @@ async function followUpTool(args) {
2046
2067
  const fallbackSessionId = runInfo?.sessionId;
2047
2068
  let liveStatus = null;
2048
2069
  try {
2049
- liveStatus = await client.status(args.runId);
2070
+ liveStatus = await client.status(runInfo?.runtimeId ?? args.runId);
2050
2071
  } catch {}
2051
2072
  const sessionId = (await parseSentinel(liveStatus?.sentinel_file ?? path.join(runsRoot(), args.runId, "sentinel.done")))?.SESSION ?? liveStatus?.session_id ?? fallbackSessionId;
2052
2073
  if (!sessionId) throw new Error("run has no session to resume");
2053
2074
  const agent = requireResumableAgent(liveStatus?.agent ?? runInfo?.agent);
2054
2075
  const backend = liveStatus?.backend ?? runInfo?.backend;
2076
+ const model = liveStatus?.model ?? runInfo?.model;
2055
2077
  const dir = liveStatus?.dir ?? runInfo?.dir;
2056
2078
  const agentProfile = liveStatus?.agent_profile ?? runInfo?.agentProfile;
2079
+ const autoApprove = resolveAutoApprove(liveStatus, runInfo);
2057
2080
  const followUpRunId = crypto.randomUUID();
2058
2081
  const followUpLabel = args.label ?? `${args.runId}-followup`;
2059
2082
  const { sentinelPath: followUpSentinelPath, eventLogPath } = ensureRunPaths(followUpRunId);
@@ -2066,8 +2089,10 @@ async function followUpTool(args) {
2066
2089
  on_event: eventLogPath
2067
2090
  };
2068
2091
  if (backend) spawnParams.backend = backend;
2092
+ if (model) spawnParams.model = model;
2069
2093
  if (dir) spawnParams.dir = dir;
2070
2094
  if (agentProfile) spawnParams.agent_profile = agentProfile;
2095
+ if (autoApprove === true) spawnParams.auto_approve = true;
2071
2096
  return {
2072
2097
  run_id: (await client.spawn(spawnParams)).runtime_id ?? followUpRunId,
2073
2098
  label: followUpLabel
@@ -2088,17 +2113,21 @@ async function followUpTool(args) {
2088
2113
  } catch {}
2089
2114
  const agent = requireResumableAgent(liveStatus?.agent ?? runInfo.agent);
2090
2115
  const backend = liveStatus?.backend ?? runInfo.backend;
2116
+ const model = liveStatus?.model ?? runInfo.model;
2091
2117
  const dir = liveStatus?.dir ?? runInfo.dir;
2092
2118
  const agentProfile = liveStatus?.agent_profile ?? runInfo.agentProfile;
2119
+ const autoApprove = resolveAutoApprove(liveStatus, runInfo);
2093
2120
  const followUpLabel = args.label ?? `${runInfo.label}-followup`;
2094
2121
  const followUpRun = await sup.spawn({
2095
2122
  agent,
2096
2123
  backend,
2124
+ model,
2097
2125
  dir,
2098
2126
  agent_profile: agentProfile,
2099
2127
  prompt: args.message,
2100
2128
  session_id: sessionId,
2101
- label: followUpLabel
2129
+ label: followUpLabel,
2130
+ ...autoApprove === true ? { auto_approve: true } : {}
2102
2131
  });
2103
2132
  return {
2104
2133
  run_id: followUpRun.runId,
@@ -2162,4 +2191,4 @@ async function shutdownTool(args) {
2162
2191
  };
2163
2192
  }
2164
2193
  //#endregion
2165
- export { DEFAULT_RUN_REDUCER_LIMITS, RunReducer, Supervisor, answerPermissionTool, createRunSnapshot, dial, eventsTool, extractEventText, findAvenorBinary, followUpTool, getInstallDir, getVersion, inspectTool, installerBinaryPath, normalizeRunEvent, observeRun, reduceRunSnapshot, resultTool, shutdownTool, spawnTool, statusTool };
2194
+ 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 };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dougbots/avenor-core",
3
- "version": "0.7.1",
3
+ "version": "0.8.1",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",