@dougbots/avenor-pi 0.6.0 → 0.7.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.
Files changed (3) hide show
  1. package/README.md +5 -0
  2. package/dist/index.js +56 -14
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -151,6 +151,11 @@ When `agent` is set, avenor passes `PI_AGENT=<name>` to the pi subprocess. The `
151
151
 
152
152
  If you don't need a named profile, `model` alone is sufficient — no agent config or extension setup required.
153
153
 
154
+ When `pi-agents` has selected a session-scoped `/agent-profile`, this extension
155
+ also forwards that optional session metadata to Pi automatically. Avenor does
156
+ not depend on `pi-agents`; absent or malformed metadata is ignored. The setting
157
+ is not an `avenor_spawn` parameter and applies only to Pi-backed child runs.
158
+
154
159
  ## Typical workflows
155
160
 
156
161
  **Blocking (default):**
package/dist/index.js CHANGED
@@ -552,6 +552,41 @@ function formatRunLine(entry) {
552
552
  const phase = entry.phaseLabel ? ` (${entry.phaseLabel})` : "";
553
553
  return `${emoji} ${entry.label} (${entry.agent}) — ${entry.status}${phase}${perm}`;
554
554
  }
555
+ /**
556
+ * decideCompletion determines whether to skip, defer, or send the completion
557
+ * steering message for a tracked run that has reached terminal status.
558
+ *
559
+ * The deferral prevents duplication when avenor_result consumes the result
560
+ * in the same turn: if the agent calls avenor_result between the defer and
561
+ * the next tick, the run is deleted from tracking and the send never fires.
562
+ */
563
+ function decideCompletion(run) {
564
+ if (run.blocking) return "skip";
565
+ if (!run.completionPending) return "defer";
566
+ return "send";
567
+ }
568
+ //#endregion
569
+ //#region src/agent-profile.ts
570
+ const PROFILE_ENTRY_TYPE = "pi-agents:profile";
571
+ /**
572
+ * Read the optional pi-agents session convention without depending on its
573
+ * package. A namespaced environment variable is an optional launch override.
574
+ */
575
+ function resolveAgentProfile(entries, environment = process.env) {
576
+ const fromEnvironment = environment.PI_AGENT_PROFILE;
577
+ if (fromEnvironment) return fromEnvironment;
578
+ let selected;
579
+ for (const entry of entries ?? []) {
580
+ if (!entry || typeof entry !== "object") continue;
581
+ const custom = entry;
582
+ if (custom.type !== "custom" || custom.customType !== PROFILE_ENTRY_TYPE) continue;
583
+ if (!custom.data || typeof custom.data !== "object") continue;
584
+ const name = custom.data.name;
585
+ if (typeof name === "string") selected = name;
586
+ if (name === null) selected = void 0;
587
+ }
588
+ return selected;
589
+ }
555
590
  //#endregion
556
591
  //#region src/index.ts
557
592
  const POLL_INTERVAL_MS = 3e3;
@@ -703,7 +738,8 @@ function createExtension(deps = defaultDeps) {
703
738
  startTime: current?.startTime ?? Date.now(),
704
739
  lastStatus: status ?? current?.lastStatus,
705
740
  blocking: current?.blocking ?? blocking,
706
- permissionNotified: current?.permissionNotified
741
+ permissionNotified: current?.permissionNotified,
742
+ completionPending: current?.completionPending
707
743
  });
708
744
  }
709
745
  async function resolveFinalOutput(run, status) {
@@ -823,19 +859,22 @@ function createExtension(deps = defaultDeps) {
823
859
  if (!run) continue;
824
860
  if (isTerminalStatus(entry.status)) {
825
861
  const prevStatus = prevStatuses.get(entry.runId);
826
- if (!prevStatus || !isTerminalStatus(prevStatus)) {
827
- sessionCtx?.ui.notify(`Sub-agent "${entry.label}" finished: ${entry.status}`, entry.status === "done" ? "info" : "warning");
828
- if (!run.blocking && run.lastStatus) {
829
- const finalOutput = await resolveFinalOutput(run, run.lastStatus);
830
- try {
831
- pi.sendUserMessage(buildCompletionText({
832
- runId: run.runId,
833
- label: run.label
834
- }, run.lastStatus, finalOutput), { deliverAs: "followUp" });
835
- } catch (err) {
836
- console.error("avenor tick: sendUserMessage failed", err);
837
- }
838
- }
862
+ if (!(prevStatus && isTerminalStatus(prevStatus))) sessionCtx?.ui.notify(`Sub-agent "${entry.label}" finished: ${entry.status}`, entry.status === "done" ? "info" : "warning");
863
+ if (run.blocking) continue;
864
+ const action = decideCompletion(run);
865
+ if (action === "defer") {
866
+ run.completionPending = true;
867
+ continue;
868
+ }
869
+ if (action === "skip") continue;
870
+ const finalOutput = await resolveFinalOutput(run, run.lastStatus);
871
+ try {
872
+ pi.sendUserMessage(buildCompletionText({
873
+ runId: run.runId,
874
+ label: run.label
875
+ }, run.lastStatus, finalOutput), { deliverAs: "followUp" });
876
+ } catch (err) {
877
+ console.error("avenor tick: sendUserMessage failed", err);
839
878
  }
840
879
  trackedRuns.delete(entry.runId);
841
880
  } else if (entry.pendingPermission && !run.blocking && !run.permissionNotified) {
@@ -1134,6 +1173,8 @@ function createExtension(deps = defaultDeps) {
1134
1173
  const dir = params.dir ?? ctx.cwd;
1135
1174
  const label = params.label ?? `${params.agent}-${Date.now()}`;
1136
1175
  const backend = params.backend ?? "pi";
1176
+ const entries = ctx.sessionManager?.getEntries?.();
1177
+ const agentProfile = backend === "pi" ? resolveAgentProfile(entries) : void 0;
1137
1178
  const result = await deps.spawnTool({
1138
1179
  agent: params.agent,
1139
1180
  prompt: params.prompt,
@@ -1143,6 +1184,7 @@ function createExtension(deps = defaultDeps) {
1143
1184
  timeout: params.timeout,
1144
1185
  model: params.model,
1145
1186
  backend,
1187
+ agentProfile,
1146
1188
  serverUrl: params.server_url,
1147
1189
  supervisorId: params.supervisor_id
1148
1190
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dougbots/avenor-pi",
3
- "version": "0.6.0",
3
+ "version": "0.7.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.6.0"
38
+ "@dougbots/avenor-core": "^0.7.1"
39
39
  },
40
40
  "peerDependencies": {
41
41
  "@earendil-works/pi-coding-agent": "*",