@dougbots/avenor-pi 0.4.1 → 0.5.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/README.md CHANGED
@@ -112,7 +112,9 @@ Available tools for LLM sub-agent management:
112
112
  | Tool | Description |
113
113
  |---|---|
114
114
  | `avenor_spawn` | Dispatch an agent run (blocking or fire-and-forget). Accepts `agent` (optional, maps to a named profile in `agents.json`), `model`, `prompt`, and `dir`. |
115
- | `avenor_status` | Get status of a run or all runs |
115
+ | `avenor_status` | Get status of a run or all runs; use `view="lifecycle"` for compact progress and permission checks |
116
+ | `avenor_result` | Wait for a run and return its bounded final output without transcript details |
117
+ | `avenor_inspect` | Review a bounded transcript, tool activity, permissions, and final output |
116
118
  | `avenor_answer_permission` | Answer a pending permission request |
117
119
  | `avenor_follow_up` | Resume a completed run with a follow-up message |
118
120
  | `avenor_events` | Read events from a run |
@@ -154,18 +156,20 @@ If you don't need a named profile, `model` alone is sufficient — no agent conf
154
156
  **Blocking (default):**
155
157
  ```
156
158
  1. avenor_spawn → tool call shows live progress, blocks until done
157
- 2. tool call returns → structured result with status + session_id
158
- 3. avenor_events → inspect detailed output
159
- 4. avenor_follow_up → optionally iterate
160
- 5. avenor_shutdown → clean up when finished
159
+ 2. tool call returns → completion preview with status + session_id
160
+ 3. avenor_result → retrieve the bounded final output when needed
161
+ 4. avenor_inspect → inspect transcript and tool details when needed
162
+ 5. avenor_follow_up → optionally iterate
163
+ 6. avenor_shutdown → clean up when finished
161
164
  ```
162
165
 
163
166
  **Parallel / fire-and-forget (`wait=false`):**
164
167
  ```
165
168
  1. avenor_spawn × N → each returns run_id immediately
166
169
  2. (status widget updates) → persistent widget shows all active runs
167
- 3. /avenor-watch <id> → open live event feed for a specific run
168
- 4. avenor_events → inspect output when done
170
+ 3. avenor_status → optional compact lifecycle/permission check
171
+ 4. avenor_result → wait for and retrieve each final output
172
+ 5. /avenor-watch <id> → open live diagnostics for a specific run
169
173
  ```
170
174
 
171
175
  ## Dependencies
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { InspectResult, StatusResult, Supervisor, answerPermissionTool, dial, eventsTool, followUpTool, inspectTool, observeRun, shutdownTool, spawnTool, statusTool } from "@dougbots/avenor-core";
1
+ import { InspectResult, StatusResult, Supervisor, answerPermissionTool, dial, eventsTool, followUpTool, inspectTool, observeRun, resultTool, shutdownTool, spawnTool, statusTool } from "@dougbots/avenor-core";
2
2
  import { ExtensionAPI } from "@earendil-works/pi-coding-agent";
3
3
 
4
4
  //#region src/types.d.ts
@@ -21,6 +21,7 @@ interface ExtensionDeps {
21
21
  answerPermissionTool: typeof answerPermissionTool;
22
22
  followUpTool: typeof followUpTool;
23
23
  inspectTool: typeof inspectTool;
24
+ resultTool: typeof resultTool;
24
25
  shutdownTool: typeof shutdownTool;
25
26
  observeRun: typeof observeRun;
26
27
  dial: typeof dial;
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Input, Key, Text, matchesKey, truncateToWidth, visibleWidth, wrapTextWithAnsi } from "@earendil-works/pi-tui";
2
2
  import { Type } from "typebox";
3
- import { Supervisor, answerPermissionTool, dial, eventsTool, followUpTool, inspectTool, observeRun, shutdownTool, spawnTool, statusTool } from "@dougbots/avenor-core";
3
+ import { Supervisor, answerPermissionTool, dial, eventsTool, followUpTool, inspectTool, observeRun, resultTool, shutdownTool, spawnTool, statusTool } from "@dougbots/avenor-core";
4
4
  //#region src/watch.ts
5
5
  const ANSI_PATTERN = /[\u001B\u009B][[\]()#;?]*(?:(?:(?:[a-zA-Z\d]*(?:;[a-zA-Z\d]*)*)?\u0007)|(?:(?:\d{1,4}(?:;\d{0,4})*)?[\dA-PR-TZcf-nq-uy=><~]))/g;
6
6
  const TRANSCRIPT_SCROLL_STEP = 4;
@@ -568,6 +568,7 @@ const defaultDeps = {
568
568
  answerPermissionTool,
569
569
  followUpTool,
570
570
  inspectTool,
571
+ resultTool,
571
572
  shutdownTool,
572
573
  observeRun,
573
574
  dial,
@@ -880,8 +881,8 @@ function createExtension(deps = defaultDeps) {
880
881
  return (await deps.Supervisor.get()).supervisorId;
881
882
  }
882
883
  async function withClient(run, work) {
883
- const socket = await resolveSupervisorSocket(run);
884
- const client = await deps.dial(socket);
884
+ if (!run.supervisorId || deps.Supervisor.isCurrentInstance(run.supervisorId)) return work((await deps.Supervisor.get()).getClient());
885
+ const client = await deps.dial(run.supervisorId);
885
886
  try {
886
887
  return await work(client);
887
888
  } finally {
@@ -1101,11 +1102,12 @@ function createExtension(deps = defaultDeps) {
1101
1102
  name: "avenor_spawn",
1102
1103
  label: "Avenor Spawn",
1103
1104
  description: "Dispatch an agent run via avenor. Blocks by default, showing live progress. Set wait=false for fire-and-forget.",
1104
- promptSnippet: "Dispatch sub-agent runs via avenor (spawn, status, inspect, events, follow-up, shutdown)",
1105
+ promptSnippet: "Dispatch sub-agent runs via avenor (spawn, status, result, inspect, events, follow-up, shutdown)",
1105
1106
  promptGuidelines: [
1106
1107
  "Use avenor_spawn to delegate well-defined tasks to sub-agents.",
1107
- "Use avenor_status to check progress of fire-and-forget runs.",
1108
- "Use avenor_inspect to review a bounded transcript, tools, and final output from a run.",
1108
+ "Use avenor_status with view \"lifecycle\" only to check progress or pending permissions.",
1109
+ "Use avenor_result to wait for and retrieve a sub-agent final result.",
1110
+ "Use avenor_inspect to review a bounded transcript and tool activity from a run.",
1109
1111
  "Use avenor_events only when raw event payloads are specifically needed.",
1110
1112
  "Use avenor_follow_up to iterate on a completed run.",
1111
1113
  "Use avenor_shutdown when done delegating work."
@@ -1156,7 +1158,7 @@ function createExtension(deps = defaultDeps) {
1156
1158
  if (!wait) return {
1157
1159
  content: [{
1158
1160
  type: "text",
1159
- text: `Dispatched "${label}" (run_id: ${result.run_id}). Call avenor_status to check progress or avenor_inspect for a bounded transcript snapshot.`
1161
+ text: `Dispatched "${label}" (run_id: ${result.run_id}). Completion will be delivered automatically; use avenor_status with view "lifecycle" for progress or avenor_result to wait for the final result.`
1160
1162
  }],
1161
1163
  details: {
1162
1164
  run_id: result.run_id,
@@ -1273,15 +1275,21 @@ function createExtension(deps = defaultDeps) {
1273
1275
  pi.registerTool({
1274
1276
  name: "avenor_status",
1275
1277
  label: "Avenor Status",
1276
- description: "Get status of a run or all runs. Surfaces pending permission requests.",
1278
+ description: "Get lifecycle status of a run or all runs. Use view=\"lifecycle\" for compact polling; full is the compatibility default.",
1277
1279
  parameters: Type.Object({
1278
1280
  run_id: Type.Optional(Type.String({ description: "Specific run ID to query" })),
1281
+ view: Type.Optional(Type.Unsafe({
1282
+ type: "string",
1283
+ enum: ["lifecycle", "full"],
1284
+ description: "Response detail (default full for compatibility)"
1285
+ })),
1279
1286
  supervisor_id: Type.Optional(Type.String({ description: "Reuse an existing supervisor by socket path" }))
1280
1287
  }),
1281
1288
  async execute(_toolCallId, params) {
1282
1289
  const result = await deps.statusTool({
1283
1290
  runId: params.run_id,
1284
- supervisorId: params.supervisor_id
1291
+ supervisorId: params.supervisor_id,
1292
+ view: params.view
1285
1293
  });
1286
1294
  return {
1287
1295
  content: [{
@@ -1292,6 +1300,44 @@ function createExtension(deps = defaultDeps) {
1292
1300
  };
1293
1301
  }
1294
1302
  });
1303
+ pi.registerTool({
1304
+ name: "avenor_result",
1305
+ label: "Avenor Result",
1306
+ description: "Wait for a run to finish and return its bounded final output without transcript or event details.",
1307
+ parameters: Type.Object({
1308
+ run_id: Type.String({ description: "Run ID to await" }),
1309
+ wait: Type.Optional(Type.Boolean({ description: "Wait for a terminal result (default true)" })),
1310
+ timeout: Type.Optional(Type.String({ description: "Maximum time to wait (e.g. 30s, 5m)" })),
1311
+ supervisor_id: Type.Optional(Type.String({ description: "Reuse an existing supervisor by socket path" }))
1312
+ }),
1313
+ async execute(_toolCallId, params, signal) {
1314
+ const tracked = trackedRuns.get(params.run_id);
1315
+ const previousBlocking = tracked?.blocking;
1316
+ if (tracked) tracked.blocking = true;
1317
+ let completed = false;
1318
+ try {
1319
+ const result = await deps.resultTool({
1320
+ runId: params.run_id,
1321
+ supervisorId: params.supervisor_id,
1322
+ wait: params.wait,
1323
+ timeout: params.timeout,
1324
+ signal
1325
+ });
1326
+ completed = result.ready;
1327
+ if (completed) trackedRuns.delete(params.run_id);
1328
+ else if (tracked && result.status === "waiting") tracked.permissionNotified = true;
1329
+ return {
1330
+ content: [{
1331
+ type: "text",
1332
+ text: JSON.stringify(result, null, 2)
1333
+ }],
1334
+ details: result
1335
+ };
1336
+ } finally {
1337
+ if (!completed && tracked && trackedRuns.get(params.run_id) === tracked) tracked.blocking = previousBlocking ?? false;
1338
+ }
1339
+ }
1340
+ });
1295
1341
  pi.registerTool({
1296
1342
  name: "avenor_inspect",
1297
1343
  label: "Avenor Inspect",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dougbots/avenor-pi",
3
- "version": "0.4.1",
3
+ "version": "0.5.1",
4
4
  "type": "module",
5
5
  "keywords": [
6
6
  "pi-package"
@@ -35,7 +35,7 @@
35
35
  "dev": "tsdown --watch"
36
36
  },
37
37
  "dependencies": {
38
- "@dougbots/avenor-core": "^0.4.1"
38
+ "@dougbots/avenor-core": "^0.5.1"
39
39
  },
40
40
  "peerDependencies": {
41
41
  "@earendil-works/pi-coding-agent": "*",