@dougbots/avenor-pi 0.16.0 → 0.16.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,7 @@ Available tools for LLM sub-agent management:
112
112
 
113
113
  | Tool | Description |
114
114
  |---|---|
115
- | `avenor_spawn` | Dispatch an agent run (blocking or fire-and-forget). Uses the `pi` backend by default in direct mode; accepts optional `agent`, `model`, `prompt`, `dir`, `roster_file`, and `roster_entry`. |
115
+ | `avenor_spawn` | Dispatch an agent run (blocking or fire-and-forget). Uses the `pi` backend by default in direct mode; accepts optional `agent`, `model`, `prompt`, `dir`, `roster_file`, and `roster_entry`. In host mode, spawns to this process's singleton supervisor (the default) receive a parent broker note for `avenor_message`. Non-local and nested spawns need an address supplied in the brief; their asks are not forwarded to the parent. |
116
116
  | `avenor_status` | Get status of a run or all runs; use `view="lifecycle"` for compact progress and permission checks |
117
117
  | `avenor_result` | Wait for a run and return its complete final output without transcript details |
118
118
  | `avenor_inspect` | Review a bounded transcript, tool activity, permissions, and final output |
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, THINKING_LEVELS, answerPermissionTool, attachOwner, boundFinalOutput, brokerReceiveTool, createChildMessageProvider, createHostMessageProvider, dial, eventsTool, extractEventText, extractReplyMessage, extractTurnText, getSupervisorClient, inspectTool, installAskClaims, isGenerationMismatchError, killTool, messageTool, normalizeAskTimeoutMs, normalizeTurnStopReason, observeRun, peersDetails, peersTool, renderPeerList, resultOutput, resultTool, shutdownTool, socketsRoot, spawnTool, statusTool, validateSpawnSelection, workflowCancelTool, workflowCompleteTool, workflowControllerStatusTool, workflowEventsTool, workflowGateTool, workflowInspectTool, workflowReadyTool, workflowStatusTool, workflowWaitTool } from "@dougbots/avenor-core";
3
+ import { SUPERVISOR_RUN_ID, Supervisor, THINKING_LEVELS, answerPermissionTool, attachOwner, boundFinalOutput, brokerReceiveTool, createChildMessageProvider, createHostMessageProvider, dial, eventsTool, extractEventText, extractReplyMessage, extractTurnText, getSupervisorClient, inspectTool, installAskClaims, isClosedSocketError, isGenerationMismatchError, killTool, messageTool, normalizeAskTimeoutMs, normalizeTurnStopReason, observeRun, peersDetails, peersTool, renderPeerList, resultOutput, resultTool, shutdownTool, socketsRoot, spawnTool, statusTool, validateSpawnSelection, workflowCancelTool, workflowCompleteTool, workflowControllerStatusTool, workflowEventsTool, workflowGateTool, workflowInspectTool, workflowReadyTool, workflowStatusTool, workflowWaitTool } from "@dougbots/avenor-core";
4
4
  import * as fs from "node:fs";
5
5
  import * as path from "node:path";
6
6
  import { createHash } from "node:crypto";
@@ -2101,6 +2101,7 @@ function createExtension(deps = defaultDeps, options = {}) {
2101
2101
  let pollingErrorCount = 0;
2102
2102
  const pollingErrors = [];
2103
2103
  let lastStatusEntries = [];
2104
+ let lastTurnSocketClosed = false;
2104
2105
  const pendingWaits = /* @__PURE__ */ new Set();
2105
2106
  /** The agent-facing prose clause for a stopping point. A synthetic status
2106
2107
  * such as `asking` has no run-status spelling, so it must not appear raw in
@@ -2750,6 +2751,7 @@ function createExtension(deps = defaultDeps, options = {}) {
2750
2751
  const binding = hostProviders.get(key);
2751
2752
  hostProviders.delete(key);
2752
2753
  hostAskClaims.delete(key);
2754
+ if (key === "") lastTurnSocketClosed = false;
2753
2755
  if (!binding || binding.isSingleton || !binding.client) return;
2754
2756
  try {
2755
2757
  binding.client.close();
@@ -2758,6 +2760,7 @@ function createExtension(deps = defaultDeps, options = {}) {
2758
2760
  function disposeHostProviders() {
2759
2761
  for (const key of [...hostProviders.keys()]) disposeHostProvider(key);
2760
2762
  hostAskClaims.clear();
2763
+ lastTurnSocketClosed = false;
2761
2764
  }
2762
2765
  async function defaultHostProviderFor(supervisorId) {
2763
2766
  const key = supervisorId ?? "";
@@ -2828,6 +2831,7 @@ function createExtension(deps = defaultDeps, options = {}) {
2828
2831
  }
2829
2832
  pi.on("turn_end", async (event) => {
2830
2833
  if (isSubAgentBrokerMode) return;
2834
+ if (lastTurnSocketClosed) return;
2831
2835
  if (!deps.Supervisor.currentInstance?.()) return;
2832
2836
  const turn = extractTurnText([event.message]);
2833
2837
  try {
@@ -2836,12 +2840,14 @@ function createExtension(deps = defaultDeps, options = {}) {
2836
2840
  const bounded = boundFinalOutput(turn.text);
2837
2841
  await provider.recordLastTurn(bounded, normalizeTurnStopReason(turn.stopReason), turn.text.length > bounded.length);
2838
2842
  } catch (error) {
2843
+ if (isClosedSocketError(error)) lastTurnSocketClosed = true;
2839
2844
  console.error("[avenor] session_last_set failed:", error instanceof Error ? error.message : error);
2840
2845
  }
2841
2846
  });
2842
2847
  pi.on("session_start", async (_event, ctx) => {
2843
2848
  sessionCtx = ctx;
2844
2849
  lastStatusEntries = [];
2850
+ lastTurnSocketClosed = false;
2845
2851
  pollingErrorCount = 0;
2846
2852
  pollingErrors.length = 0;
2847
2853
  if (!isSubAgentBrokerMode) startHostAskPoll();
@@ -2950,6 +2956,7 @@ function createExtension(deps = defaultDeps, options = {}) {
2950
2956
  ...params,
2951
2957
  backend
2952
2958
  };
2959
+ const parentRunId = isSubAgentBrokerMode ? void 0 : !params.supervisor_id || Boolean(deps.Supervisor.isCurrentInstance?.(params.supervisor_id)) ? SUPERVISOR_RUN_ID : void 0;
2953
2960
  const result = await deps.spawnTool({
2954
2961
  ...params.agent !== void 0 ? { agent: params.agent } : {},
2955
2962
  ...params.prompt !== void 0 ? { prompt: params.prompt } : {},
@@ -2964,7 +2971,8 @@ function createExtension(deps = defaultDeps, options = {}) {
2964
2971
  ...params.roster_entry !== void 0 ? { rosterEntry: params.roster_entry } : {},
2965
2972
  ...agentProfile !== void 0 ? { agentProfile } : {},
2966
2973
  ...params.server_url !== void 0 ? { serverUrl: params.server_url } : {},
2967
- ...params.supervisor_id !== void 0 ? { supervisorId: params.supervisor_id } : {}
2974
+ ...params.supervisor_id !== void 0 ? { supervisorId: params.supervisor_id } : {},
2975
+ ...parentRunId !== void 0 ? { parent_run_id: parentRunId } : {}
2968
2976
  });
2969
2977
  const supervisorId = statusSupervisorId(params.supervisor_id, result.supervisor_id);
2970
2978
  const runRef = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dougbots/avenor-pi",
3
- "version": "0.16.0",
3
+ "version": "0.16.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.16.0"
38
+ "@dougbots/avenor-core": "^0.16.1"
39
39
  },
40
40
  "peerDependencies": {
41
41
  "@earendil-works/pi-coding-agent": ">=0.74.0",