pi-subagents 0.70.1 → 0.72.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/CHANGELOG.md +87 -0
- package/README.md +4 -2
- package/agents/worker.md +2 -2
- package/docs/agents.md +1 -1
- package/docs/configuration.md +18 -2
- package/docs/extension-api.md +67 -3
- package/docs/models.md +1 -1
- package/docs/observability.md +17 -13
- package/docs/tool-reference.md +14 -10
- package/docs/workflows.md +3 -1
- package/package.json +11 -4
- package/prompts/council.md +6 -3
- package/skills/pi-subagents/references/constraints-and-recipes.md +5 -2
- package/skills/pi-subagents/references/execution-controls.md +3 -3
- package/skills/pi-subagents/references/management-authoring-rpc.md +2 -2
- package/src/agents/agent-management.d.ts +2 -1
- package/src/agents/agent-management.d.ts.map +1 -1
- package/src/agents/agent-management.js +32 -29
- package/src/agents/agent-management.js.map +1 -1
- package/src/agents/agents.d.ts +7 -3
- package/src/agents/agents.d.ts.map +1 -1
- package/src/agents/agents.js +16 -15
- package/src/agents/agents.js.map +1 -1
- package/src/agents/global-npm-root.d.ts +7 -0
- package/src/agents/global-npm-root.d.ts.map +1 -0
- package/src/agents/global-npm-root.js +58 -0
- package/src/agents/global-npm-root.js.map +1 -0
- package/src/agents/proactive-skills.d.ts +1 -0
- package/src/agents/proactive-skills.d.ts.map +1 -1
- package/src/agents/proactive-skills.js +3 -1
- package/src/agents/proactive-skills.js.map +1 -1
- package/src/agents/skills.d.ts +2 -0
- package/src/agents/skills.d.ts.map +1 -1
- package/src/agents/skills.js +41 -8
- package/src/agents/skills.js.map +1 -1
- package/src/api/delegation.d.ts +14 -0
- package/src/api/delegation.d.ts.map +1 -1
- package/src/api/inspectors.d.ts +21 -0
- package/src/api/inspectors.d.ts.map +1 -0
- package/src/api/inspectors.js +12 -0
- package/src/api/inspectors.js.map +1 -0
- package/src/extension/fanout-child.d.ts.map +1 -1
- package/src/extension/fanout-child.js +9 -0
- package/src/extension/fanout-child.js.map +1 -1
- package/src/extension/index.d.ts.map +1 -1
- package/src/extension/index.js +76 -29
- package/src/extension/index.js.map +1 -1
- package/src/extension/rpc.d.ts +1 -1
- package/src/extension/rpc.d.ts.map +1 -1
- package/src/extension/rpc.js +11 -1
- package/src/extension/rpc.js.map +1 -1
- package/src/extension/schemas.js +5 -5
- package/src/extension/schemas.js.map +1 -1
- package/src/extension/subagent-guide.d.ts +1 -1
- package/src/extension/subagent-guide.d.ts.map +1 -1
- package/src/extension/subagent-guide.js +11 -4
- package/src/extension/subagent-guide.js.map +1 -1
- package/src/extension/tool-activation.d.ts +9 -0
- package/src/extension/tool-activation.d.ts.map +1 -0
- package/src/extension/tool-activation.js +182 -0
- package/src/extension/tool-activation.js.map +1 -0
- package/src/extension/tool-description.d.ts +4 -4
- package/src/extension/tool-description.d.ts.map +1 -1
- package/src/extension/tool-description.js +1 -1
- package/src/inspectors/plugins.d.ts +7 -2
- package/src/inspectors/plugins.d.ts.map +1 -1
- package/src/inspectors/plugins.js +78 -3
- package/src/inspectors/plugins.js.map +1 -1
- package/src/intercom/intercom-bridge.d.ts.map +1 -1
- package/src/intercom/intercom-bridge.js +2 -0
- package/src/intercom/intercom-bridge.js.map +1 -1
- package/src/intercom/native-supervisor-channel.d.ts.map +1 -1
- package/src/intercom/native-supervisor-channel.js +3 -1
- package/src/intercom/native-supervisor-channel.js.map +1 -1
- package/src/runs/background/active-async-capacity.d.ts.map +1 -1
- package/src/runs/background/active-async-capacity.js +4 -33
- package/src/runs/background/active-async-capacity.js.map +1 -1
- package/src/runs/background/async-execution.d.ts.map +1 -1
- package/src/runs/background/async-execution.js +7 -33
- package/src/runs/background/async-execution.js.map +1 -1
- package/src/runs/background/async-job-tracker.d.ts.map +1 -1
- package/src/runs/background/async-job-tracker.js +26 -39
- package/src/runs/background/async-job-tracker.js.map +1 -1
- package/src/runs/background/async-resume.d.ts +1 -1
- package/src/runs/background/async-resume.d.ts.map +1 -1
- package/src/runs/background/async-resume.js +7 -2
- package/src/runs/background/async-resume.js.map +1 -1
- package/src/runs/background/async-status.d.ts +1 -0
- package/src/runs/background/async-status.d.ts.map +1 -1
- package/src/runs/background/async-status.js +1 -0
- package/src/runs/background/async-status.js.map +1 -1
- package/src/runs/background/binary-bootstrap.d.ts.map +1 -1
- package/src/runs/background/binary-bootstrap.js +34 -6
- package/src/runs/background/binary-bootstrap.js.map +1 -1
- package/src/runs/background/fleet-view.d.ts.map +1 -1
- package/src/runs/background/fleet-view.js +26 -7
- package/src/runs/background/fleet-view.js.map +1 -1
- package/src/runs/background/notify.d.ts +11 -0
- package/src/runs/background/notify.d.ts.map +1 -1
- package/src/runs/background/notify.js +73 -3
- package/src/runs/background/notify.js.map +1 -1
- package/src/runs/background/pid-namespace.d.ts +3 -0
- package/src/runs/background/pid-namespace.d.ts.map +1 -0
- package/src/runs/background/pid-namespace.js +20 -0
- package/src/runs/background/pid-namespace.js.map +1 -0
- package/src/runs/background/process-terminal-candidate.d.ts +18 -0
- package/src/runs/background/process-terminal-candidate.d.ts.map +1 -0
- package/src/runs/background/process-terminal-candidate.js +97 -0
- package/src/runs/background/process-terminal-candidate.js.map +1 -0
- package/src/runs/background/process-terminal.d.ts +3 -15
- package/src/runs/background/process-terminal.d.ts.map +1 -1
- package/src/runs/background/process-terminal.js +19 -96
- package/src/runs/background/process-terminal.js.map +1 -1
- package/src/runs/background/retained-children.d.ts.map +1 -1
- package/src/runs/background/retained-children.js +3 -2
- package/src/runs/background/retained-children.js.map +1 -1
- package/src/runs/background/run-child-session.d.ts +2 -0
- package/src/runs/background/run-child-session.d.ts.map +1 -1
- package/src/runs/background/run-child-session.js +2 -0
- package/src/runs/background/run-child-session.js.map +1 -1
- package/src/runs/background/run-status.d.ts.map +1 -1
- package/src/runs/background/run-status.js +5 -1
- package/src/runs/background/run-status.js.map +1 -1
- package/src/runs/background/runner-aliases.d.ts.map +1 -1
- package/src/runs/background/runner-aliases.js +2 -1
- package/src/runs/background/runner-aliases.js.map +1 -1
- package/src/runs/background/runner-startup-failure.d.ts +14 -0
- package/src/runs/background/runner-startup-failure.d.ts.map +1 -0
- package/src/runs/background/runner-startup-failure.js +47 -0
- package/src/runs/background/runner-startup-failure.js.map +1 -0
- package/src/runs/background/stale-run-reconciler.d.ts +1 -0
- package/src/runs/background/stale-run-reconciler.d.ts.map +1 -1
- package/src/runs/background/stale-run-reconciler.js +18 -3
- package/src/runs/background/stale-run-reconciler.js.map +1 -1
- package/src/runs/background/subagent-runner-bootstrap.d.ts +14 -0
- package/src/runs/background/subagent-runner-bootstrap.d.ts.map +1 -0
- package/src/runs/background/subagent-runner-bootstrap.js +277 -0
- package/src/runs/background/subagent-runner-bootstrap.js.map +1 -0
- package/src/runs/background/subagent-runner.d.ts +4 -2
- package/src/runs/background/subagent-runner.d.ts.map +1 -1
- package/src/runs/background/subagent-runner.js +58 -180
- package/src/runs/background/subagent-runner.js.map +1 -1
- package/src/runs/background/workflow-terminal-proof.d.ts +18 -0
- package/src/runs/background/workflow-terminal-proof.d.ts.map +1 -0
- package/src/runs/background/workflow-terminal-proof.js +68 -0
- package/src/runs/background/workflow-terminal-proof.js.map +1 -0
- package/src/runs/foreground/execution.d.ts.map +1 -1
- package/src/runs/foreground/execution.js +43 -14
- package/src/runs/foreground/execution.js.map +1 -1
- package/src/runs/foreground/prompt-audit.d.ts.map +1 -1
- package/src/runs/foreground/prompt-audit.js +2 -6
- package/src/runs/foreground/prompt-audit.js.map +1 -1
- package/src/runs/foreground/subagent-executor.d.ts +2 -1
- package/src/runs/foreground/subagent-executor.d.ts.map +1 -1
- package/src/runs/foreground/subagent-executor.js +228 -24
- package/src/runs/foreground/subagent-executor.js.map +1 -1
- package/src/runs/shared/child-launch.d.ts.map +1 -1
- package/src/runs/shared/child-launch.js +3 -0
- package/src/runs/shared/child-launch.js.map +1 -1
- package/src/runs/shared/child-runtime-config.d.ts +4 -0
- package/src/runs/shared/child-runtime-config.d.ts.map +1 -1
- package/src/runs/shared/child-runtime-config.js.map +1 -1
- package/src/runs/shared/child-session.d.ts +1 -0
- package/src/runs/shared/child-session.d.ts.map +1 -1
- package/src/runs/shared/child-session.js +1 -0
- package/src/runs/shared/child-session.js.map +1 -1
- package/src/runs/shared/child-tool-plan.d.ts.map +1 -1
- package/src/runs/shared/child-tool-plan.js +4 -6
- package/src/runs/shared/child-tool-plan.js.map +1 -1
- package/src/runs/shared/external-cli-runner.d.ts.map +1 -1
- package/src/runs/shared/external-cli-runner.js +3 -1
- package/src/runs/shared/external-cli-runner.js.map +1 -1
- package/src/runs/shared/external-job-bridge.d.ts +7 -0
- package/src/runs/shared/external-job-bridge.d.ts.map +1 -1
- package/src/runs/shared/external-job-bridge.js +63 -0
- package/src/runs/shared/external-job-bridge.js.map +1 -1
- package/src/runs/shared/git-environment.d.ts +3 -0
- package/src/runs/shared/git-environment.d.ts.map +1 -0
- package/src/runs/shared/git-environment.js +28 -0
- package/src/runs/shared/git-environment.js.map +1 -0
- package/src/runs/shared/mcp-config-sources.d.ts +3 -0
- package/src/runs/shared/mcp-config-sources.d.ts.map +1 -1
- package/src/runs/shared/mcp-config-sources.js.map +1 -1
- package/src/runs/shared/mcp-direct-tool-allowlist.js +1 -1
- package/src/runs/shared/mcp-direct-tool-allowlist.js.map +1 -1
- package/src/runs/shared/mcp-direct-tool-grant.d.ts +3 -1
- package/src/runs/shared/mcp-direct-tool-grant.d.ts.map +1 -1
- package/src/runs/shared/mcp-direct-tool-grant.js +19 -5
- package/src/runs/shared/mcp-direct-tool-grant.js.map +1 -1
- package/src/runs/shared/model-resolution.d.ts.map +1 -1
- package/src/runs/shared/model-resolution.js +7 -1
- package/src/runs/shared/model-resolution.js.map +1 -1
- package/src/runs/shared/pi-spawn.d.ts +10 -1
- package/src/runs/shared/pi-spawn.d.ts.map +1 -1
- package/src/runs/shared/pi-spawn.js +86 -7
- package/src/runs/shared/pi-spawn.js.map +1 -1
- package/src/runs/shared/single-output.js +1 -1
- package/src/runs/shared/single-output.js.map +1 -1
- package/src/runs/shared/structured-output.d.ts +7 -0
- package/src/runs/shared/structured-output.d.ts.map +1 -1
- package/src/runs/shared/structured-output.js +74 -0
- package/src/runs/shared/structured-output.js.map +1 -1
- package/src/runs/shared/subagent-prompt-runtime.d.ts.map +1 -1
- package/src/runs/shared/subagent-prompt-runtime.js +23 -7
- package/src/runs/shared/subagent-prompt-runtime.js.map +1 -1
- package/src/runs/shared/tool-availability.js +2 -2
- package/src/runs/shared/tool-availability.js.map +1 -1
- package/src/runs/shared/worktree.d.ts.map +1 -1
- package/src/runs/shared/worktree.js +9 -3
- package/src/runs/shared/worktree.js.map +1 -1
- package/src/shared/child-session-name.d.ts.map +1 -1
- package/src/shared/child-session-name.js +4 -2
- package/src/shared/child-session-name.js.map +1 -1
- package/src/shared/fork-context.d.ts +4 -0
- package/src/shared/fork-context.d.ts.map +1 -1
- package/src/shared/fork-context.js +9 -4
- package/src/shared/fork-context.js.map +1 -1
- package/src/shared/pruned-fork.d.ts.map +1 -1
- package/src/shared/pruned-fork.js +68 -56
- package/src/shared/pruned-fork.js.map +1 -1
- package/src/shared/types.d.ts +31 -3
- package/src/shared/types.d.ts.map +1 -1
- package/src/shared/types.js +2 -0
- package/src/shared/types.js.map +1 -1
- package/src/slash/delegation-adapters.d.ts +7 -1
- package/src/slash/delegation-adapters.d.ts.map +1 -1
- package/src/slash/delegation-adapters.js +17 -0
- package/src/slash/delegation-adapters.js.map +1 -1
- package/src/slash/prompt-template-bridge.d.ts.map +1 -1
- package/src/slash/prompt-template-bridge.js +14 -1
- package/src/slash/prompt-template-bridge.js.map +1 -1
- package/src/slash/prompt-workflows.d.ts.map +1 -1
- package/src/slash/prompt-workflows.js +16 -2
- package/src/slash/prompt-workflows.js.map +1 -1
- package/src/slash/slash-commands.d.ts.map +1 -1
- package/src/slash/slash-commands.js +7 -253
- package/src/slash/slash-commands.js.map +1 -1
- package/src/slash/subagent-cost.d.ts +30 -0
- package/src/slash/subagent-cost.d.ts.map +1 -0
- package/src/slash/subagent-cost.js +307 -0
- package/src/slash/subagent-cost.js.map +1 -0
- package/src/tui/fleet-status.d.ts +2 -0
- package/src/tui/fleet-status.d.ts.map +1 -1
- package/src/tui/fleet-status.js +25 -2
- package/src/tui/fleet-status.js.map +1 -1
- package/src/tui/fleet.d.ts +1 -1
- package/src/tui/fleet.d.ts.map +1 -1
- package/src/tui/fleet.js +5 -1
- package/src/tui/fleet.js.map +1 -1
- package/src/tui/render.d.ts.map +1 -1
- package/src/tui/render.js +8 -4
- package/src/tui/render.js.map +1 -1
- package/src/watchdog/diff-tool.d.ts +2 -1
- package/src/watchdog/diff-tool.d.ts.map +1 -1
- package/src/watchdog/diff-tool.js +9 -3
- package/src/watchdog/diff-tool.js.map +1 -1
- package/src/watchdog/permission-arbiter.d.ts.map +1 -1
- package/src/watchdog/permission-arbiter.js +2 -7
- package/src/watchdog/permission-arbiter.js.map +1 -1
- package/src/watchdog/register-child.d.ts +3 -1
- package/src/watchdog/register-child.d.ts.map +1 -1
- package/src/watchdog/register-child.js +12 -3
- package/src/watchdog/register-child.js.map +1 -1
- package/src/watchdog/review.d.ts +1 -1
- package/src/watchdog/review.d.ts.map +1 -1
- package/src/watchdog/review.js +2 -7
- package/src/watchdog/review.js.map +1 -1
- package/src/watchdog/runtime.d.ts +1 -1
- package/src/watchdog/runtime.d.ts.map +1 -1
- package/src/watchdog/runtime.js +2 -1
- package/src/watchdog/runtime.js.map +1 -1
- package/src/watchdog/turn-delta.d.ts +5 -1
- package/src/watchdog/turn-delta.d.ts.map +1 -1
- package/src/watchdog/turn-delta.js +9 -5
- package/src/watchdog/turn-delta.js.map +1 -1
package/prompts/council.md
CHANGED
|
@@ -8,8 +8,11 @@ session, are the supervisor. You select the roster, curate cross-advisor packets
|
|
|
8
8
|
decide which feedback is valid, and write the final memo. Advisors do not talk
|
|
9
9
|
directly or see peer transcripts by default. This is not free-form agent chat.
|
|
10
10
|
|
|
11
|
-
Before you orchestrate,
|
|
12
|
-
`
|
|
11
|
+
Before you orchestrate, load the council protocol with
|
|
12
|
+
`subagent({ action: "guide", topic: "council" })`. If only `subagents_enable`
|
|
13
|
+
is available, call it first; `subagent` is available on the next request. The
|
|
14
|
+
guide returns the packaged council-mode skill and the references it asks you to
|
|
15
|
+
read, so it also works when Pi runs with `--no-skills`.
|
|
13
16
|
|
|
14
17
|
Parse the invocation yourself. The flags below are conventions, not runtime
|
|
15
18
|
options. Record a brief with the question, scope, non-goals, evidence targets,
|
|
@@ -48,7 +51,7 @@ path if the run is not resumable.
|
|
|
48
51
|
## Run the protocol
|
|
49
52
|
|
|
50
53
|
Use the canonical workflow, structured advisor contracts, aggregate pass receipts,
|
|
51
|
-
and memo requirements
|
|
54
|
+
and memo requirements from the council guide. Keep the parent as the
|
|
52
55
|
only synthesizer and decision maker. Do not introduce a chair advisor, peer chat,
|
|
53
56
|
or transcript sharing.
|
|
54
57
|
|
|
@@ -6,10 +6,13 @@ This file is a detailed reference loaded from `skills/pi-subagents/SKILL.md`.
|
|
|
6
6
|
|
|
7
7
|
- **Explicit forking requires a persisted parent session.** If the current session
|
|
8
8
|
does not have a persisted session file or current leaf, explicit `context: "fork"`
|
|
9
|
-
fails. An agent-level `defaultContext: fork` is a preference: packaged `
|
|
10
|
-
|
|
9
|
+
fails. An agent-level `defaultContext: fork` is a preference: packaged `oracle`
|
|
10
|
+
and `advisor` fall back to `fresh` when those fork preconditions are not
|
|
11
11
|
met yet. Use `context: "fresh"` when you do not want a fork even after the parent
|
|
12
12
|
session exists.
|
|
13
|
+
- **Packaged workers start fresh.** `worker` defaults to fresh context so its brief,
|
|
14
|
+
not the parent's unfinished agenda, controls the implementation. Pass explicit
|
|
15
|
+
`context: "fork"` when inherited conversation history is required.
|
|
13
16
|
- **Forked runs inherit parent history.** They are branched threads, not fresh
|
|
14
17
|
filtered contexts. Use fresh context for adversarial reviewers unless the user explicitly asks for forked context.
|
|
15
18
|
- **Default subagent nesting depth is 2.** Deeper recursive delegation is blocked
|
|
@@ -32,7 +32,7 @@ An agent may set `runner.type: external-job` with a non-empty `provider` and opt
|
|
|
32
32
|
|
|
33
33
|
External job profiles are async-only. The provider owns the remote job and Pi owns the async run record. Status persists provider name, provider job id, prompt digest, provider options, handle/conversation URLs when supplied, result artifact path, last known state, and provider failure code/message. Recovery uses existing provider job metadata to call `reattach` and `result`; it refuses to redispatch a prompt when the persisted provider job does not match the prompt digest.
|
|
34
34
|
|
|
35
|
-
External job profiles do not support foreground/clarify, steer
|
|
35
|
+
External job profiles do not support foreground/clarify, live steer or native session resume, Pi models/tools/extensions/skills, tool budgets, structured output, native child permissions, or Pi child sessions. Completed external-job runs can use `action: "resume"` for provider follow-up when the registered provider exposes `followUp(input)`; running jobs must finish first, and providers without follow-up support fail closed with an update/reload message. Capacity conflicts fail closed and include the blocking provider job id when the provider supplies it.
|
|
36
36
|
|
|
37
37
|
### Single agent
|
|
38
38
|
|
|
@@ -103,7 +103,7 @@ For a typed post-run check, pass the object form `gate: { command, output: "json
|
|
|
103
103
|
|
|
104
104
|
If omitted, acceptance is inferred from role, mode, and risk. Use `level: "checked"` for ordinary writer evidence and `level: "verified"` when the runtime should run explicit validation commands. Independent review is orthogonal: use `review: { required: true, agent: "reviewer" }`; reviewer/read-only calls omit `acceptance`. `review-required` means evidence passed but review is pending; `reviewed` means an independent review found no blockers. Never request `level: "reviewed"`; it is recognized only so preflight can return an actionable correction. Disable gates with `{ level: "none", reason: "..." }`; bare `"none"` is rejected and `false` is only a deprecated shorthand. Child-reported command success is evidence, not runtime verification.
|
|
105
105
|
|
|
106
|
-
Completed workflow children from this parent session stay addressable as retained children. `subagent({ action: "children.list" })` lists up to the last 10 with run ids and reports each row as `resumable` or `not resumable` with a reason. Resume only rows reported `resumable`. For a retained-child challenge, use `resume` instead of `steer` when the child is complete.
|
|
106
|
+
Completed workflow children from this parent session stay addressable as retained children. `subagent({ action: "children.list" })` lists up to the last 10 with run ids and reports each row as `resumable` or `not resumable` with a reason. This workflow-only roster is not an exhaustive list of direct native children. Resume only rows reported `resumable`. When the exact run id of an intended direct child is known, inspect it with `subagent({ action: "status", id: "<run-id>" })`; if status identifies the candidate, attempt `subagent({ action: "resume", id: "<run-id>", message: "..." })`. Resume performs the authoritative eligibility check and may reject the attempt. For a retained-child challenge, use `resume` instead of `steer` when the child is complete. Launch a same-role fallback challenge, labeled as fallback, only when no known candidate exists or resume rejects eligibility. A later workflow continues a resumable child with `runs.run(key, { resume: "<run-id>", task: "follow-up" })`. Inside `workflowScript`, awaiting that call waits for the revived child to finish and returns its completed output and new `runId`; top-level `{ action: "resume" }` remains detached. Pass explicit follow-up task text. Assign each returned child result back to the loop variable because every resume can return a new retained `runId`; always resume the latest returned id. `resume` and `agent` are mutually exclusive, the revived child keeps its stored agent/model/tool contract, and `gate` is rejected on retained resume items.
|
|
107
107
|
|
|
108
108
|
Each workflow key identifies one result lane: use a new stable workflow key for every distinct retained resume pass; same-key calls are reused only when launch parameters are identical, and incompatible parameters are rejected.
|
|
109
109
|
|
|
@@ -493,7 +493,7 @@ subagent({
|
|
|
493
493
|
workflowScript: `return runs.run("oracle-check", { agent: "oracle", task: "Review my current direction, challenge assumptions, and propose the best next move." })`
|
|
494
494
|
})
|
|
495
495
|
|
|
496
|
-
// Implementation only after explicit approval. Worker defaults to
|
|
496
|
+
// Implementation only after explicit approval. Worker defaults to fresh context.
|
|
497
497
|
subagent({
|
|
498
498
|
workflowScript: `return runs.run("implementation", { agent: "worker", task: "Implement the approved approach: ..." })`
|
|
499
499
|
})
|
|
@@ -18,7 +18,7 @@ subagent({ action: "list" })
|
|
|
18
18
|
subagent({ action: "children.list" })
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
Lists up to the last 10 retained workflow children from this parent session with explicit `resumable` or `not resumable` rows. Resume only rows reported `resumable`.
|
|
21
|
+
Lists up to the last 10 retained workflow children from this parent session with explicit `resumable` or `not resumable` rows. This workflow-only roster is not an exhaustive list of direct native children. Resume only rows reported `resumable`. When the exact run id of an intended direct child is known, inspect it with `subagent({ action: "status", id: "<run-id>" })`; if status identifies the candidate, attempt `subagent({ action: "resume", id: "<run-id>", message: "..." })`. Resume performs the authoritative eligibility check and may reject the attempt. Continue one inside a workflow with `runs.run(key, { resume: "<run-id>", task: "follow-up" })`; each workflow key identifies one result lane, so use a new stable workflow key for every distinct retained resume pass. Same-key calls are reused only when launch parameters are identical, and incompatible parameters are rejected. The revived child keeps its stored agent, model, and tool contract. Start a same-role fallback challenge, labeled as fallback, only when no known candidate exists or resume rejects eligibility. `steer` with `mode: "follow_up"` only queues text for the next `resume` when the child has already completed.
|
|
22
22
|
|
|
23
23
|
### Refinement overlays
|
|
24
24
|
|
|
@@ -158,4 +158,4 @@ Additional user prompt templates can delegate into `pi-subagents` through the na
|
|
|
158
158
|
|
|
159
159
|
Other Pi extensions can call `pi-subagents` through the in-process event bus. The RPC channels are `subagents:rpc:v1:ready`, `subagents:rpc:v1:request`, and per-request replies at `subagents:rpc:v1:reply:<requestId>`. Envelopes use `{ version: 1, requestId, method, params }`, and replies use `{ version: 1, requestId, success, data | error }`. `ping` advertises the exact process-local async completion event as `events.asyncComplete` for RPC-spawn consumers.
|
|
160
160
|
|
|
161
|
-
Methods: `ping`, `status`, `spawn`, `steer`, `interrupt`, `resume`, and `
|
|
161
|
+
Methods: `ping`, `status`, `manage`, `spawn`, `steer`, `interrupt`, `resume`, `stop`, and `cost`. `ping` capability metadata advertises optional projections: `capabilities.fleetStatus: { version: 1 }` adds bounded current-session `data.fleet` records (opaque reconciliation `key`, resolved `agent`, optional `role`, `model`, `effort`, caller-facing `goal`, `startedAt`, split `{ input, output, total }` tokens, plus `totalActive`/`omitted` overflow counts) to successful `status` replies; `capabilities.launchResolvedExtensions` advertises parent-resolved opaque launch-extension identifiers in status details; `capabilities.runtimeAcknowledgedExtensions` advertises the best-effort child-runtime acknowledgement projection fed by cooperating extensions emitting `subagent:acknowledge-extension`; `capabilities.cost: { version: 1 }` advertises parent-plus-child accounting as data. Foreground `details.results[]` rows carry a stable numeric `index`; correlate children by `(runId, index)` rather than row position. Consumers should read status/result artifacts and RPC projections instead of scraping terminal output and must ignore unknown fields. `spawn` accepts either `{ agent, task? }`, an inline `workflowScript`, or `workflowScriptPath`; it is async-only and rejects management actions, `async: false`, or `clarify: true`. It reuses the normal executor, so discovery, validation, session attribution, configured spawn caps, child-safety depth, artifacts, and async status are shared with the `subagent` tool. `manage` accepts only the schedule actions advertised by `ping.capabilities.managementActions`. `status`, acknowledged async `steer`, and `interrupt` map to the normal control actions. RPC steer disables pause-and-revive recovery and advertises `capabilities.nonRecoveringSteer`, preserving the caller's authority over the exact spawned child. `resume` requires a target plus non-empty message and delegates to the package-owned revival path; it may set a caller-owned `file-only` output path but cannot override the persisted child model, tools, budgets, session ownership, or exclusive session lease. For retained-child workflows, resume only roster rows reported `resumable`; because that workflow-only roster is not exhaustive, inspect the exact status of a known direct-run candidate and attempt the authoritative resume when status identifies it. Start a labeled same-role fallback only when there is no known candidate or resume rejects eligibility. `stop` targets running async runs through the existing timeout control channel. `pi.events` is process-local, so separate Pi processes and child subagents need lifecycle artifact files or `pi-intercom` instead.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AgentToolResult } from "@earendil-works/pi-agent-core";
|
|
2
2
|
import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
3
|
-
import { type AgentConfig } from "./agents.ts";
|
|
3
|
+
import { type AgentConfig, discoverAgentsAll } from "./agents.ts";
|
|
4
4
|
import type { Details, ExtensionConfig } from "../shared/types.ts";
|
|
5
5
|
import { type RuntimeAgentOwner } from "./runtime-agent-registry.ts";
|
|
6
6
|
type ManagementContext = Pick<ExtensionContext, "cwd" | "modelRegistry"> & {
|
|
@@ -9,6 +9,7 @@ type ManagementContext = Pick<ExtensionContext, "cwd" | "modelRegistry"> & {
|
|
|
9
9
|
currentSessionId?: string;
|
|
10
10
|
runtimeAgentOwner?: RuntimeAgentOwner;
|
|
11
11
|
onAgentsChanged?: () => void;
|
|
12
|
+
discoverAgentsAll?: typeof discoverAgentsAll;
|
|
12
13
|
};
|
|
13
14
|
interface ManagementParams {
|
|
14
15
|
action?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-management.d.ts","sourceRoot":"","sources":["../../../src/agents/agent-management.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,EACN,KAAK,WAAW,
|
|
1
|
+
{"version":3,"file":"agent-management.d.ts","sourceRoot":"","sources":["../../../src/agents/agent-management.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,EACN,KAAK,WAAW,EAQhB,iBAAiB,EASjB,MAAM,aAAa,CAAC;AAcrB,OAAO,KAAK,EAAkE,OAAO,EAAE,eAAe,EAAoB,MAAM,oBAAoB,CAAC;AAIrJ,OAAO,EAAsB,KAAK,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAKzF,KAAK,iBAAiB,GAAG,IAAI,CAAC,gBAAgB,EAAE,KAAK,GAAG,eAAe,CAAC,GAAG;IAAE,KAAK,CAAC,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAAC,MAAM,CAAC,EAAE,eAAe,CAAC;IAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAAC,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;IAAC,iBAAiB,CAAC,EAAE,OAAO,iBAAiB,CAAA;CAAE,CAAC;AAMzR,UAAU,gBAAgB;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;CACjB;AAoMD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,WAAW,GAAG,WAAW,CA8EnE;AAWD,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,CAsD7G;AA+jBD,wBAAgB,UAAU,CAAC,MAAM,EAAE,gBAAgB,EAAE,GAAG,EAAE,iBAAiB,GAAG,eAAe,CAAC,OAAO,CAAC,CAuCrG;AAmID,wBAAgB,YAAY,CAAC,MAAM,EAAE,gBAAgB,EAAE,GAAG,EAAE,iBAAiB,GAAG,eAAe,CAAC,OAAO,CAAC,CAiDvG;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,gBAAgB,EAAE,GAAG,EAAE,iBAAiB,GAAG,eAAe,CAAC,OAAO,CAAC,CA+DvG;AAoJD,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,GAAG,EAAE,iBAAiB,GAAG,eAAe,CAAC,OAAO,CAAC,CAcjI"}
|
|
@@ -17,6 +17,9 @@ import { previewDisplayText } from "../shared/display-text.js";
|
|
|
17
17
|
import { capabilityCeilingAgentRestrictionSources, isAgentAllowedByCapabilityCeiling, resolveCurrentSubagentCapabilityCeiling } from "../runs/shared/capability-ceiling.js";
|
|
18
18
|
import { mergeRuntimeAgents } from "./runtime-agent-registry.js";
|
|
19
19
|
import { listExternalJobProviders } from "../api/external-job-provider.js";
|
|
20
|
+
function discoverCatalog(ctx, cwd = ctx.cwd, provider) {
|
|
21
|
+
return (ctx.discoverAgentsAll ?? discoverAgentsAll)(cwd, provider);
|
|
22
|
+
}
|
|
20
23
|
function result(text, isError = false, details) {
|
|
21
24
|
return { content: [{ type: "text", text }], isError, details: { mode: "management", results: [], ...details } };
|
|
22
25
|
}
|
|
@@ -97,8 +100,8 @@ function availableAgentNamesFromDiscovery(d, runtimeAgentOwner, preferredModelPr
|
|
|
97
100
|
const agents = runtimeAgentOwner ? effectiveAgentsForScope("both", d, runtimeAgentOwner, preferredModelProvider) : allAgents(d);
|
|
98
101
|
return [...new Set(agents.map((agent) => agent.name))].sort((a, b) => a.localeCompare(b));
|
|
99
102
|
}
|
|
100
|
-
function availableAgentNames(cwd) {
|
|
101
|
-
return availableAgentNamesFromDiscovery(
|
|
103
|
+
function availableAgentNames(ctx, cwd = ctx.cwd) {
|
|
104
|
+
return availableAgentNamesFromDiscovery(discoverCatalog(ctx, cwd));
|
|
102
105
|
}
|
|
103
106
|
function findAgentsInDiscovery(name, d, scope = "both", runtimeAgentOwner, preferredModelProvider) {
|
|
104
107
|
const raw = name.trim();
|
|
@@ -114,8 +117,8 @@ function findAgentsInDiscovery(name, d, scope = "both", runtimeAgentOwner, prefe
|
|
|
114
117
|
|| (sanitized !== raw && Boolean(resolveAgentName(sanitized, [agent]).agent)))
|
|
115
118
|
.sort((a, b) => a.source.localeCompare(b.source));
|
|
116
119
|
}
|
|
117
|
-
function findAgents(name,
|
|
118
|
-
return findAgentsInDiscovery(name,
|
|
120
|
+
function findAgents(name, ctx, scope = "both") {
|
|
121
|
+
return findAgentsInDiscovery(name, discoverCatalog(ctx), scope);
|
|
119
122
|
}
|
|
120
123
|
function diagnosticsForScope(diagnostics, scope) {
|
|
121
124
|
if (scope === "both")
|
|
@@ -142,8 +145,8 @@ function resolveEffectiveAgent(d, name) {
|
|
|
142
145
|
const matches = candidates.filter((agent) => agent.name === resolved.agent.name);
|
|
143
146
|
return { agent: matches.reduce((best, agent) => (AGENT_SOURCE_PRECEDENCE[agent.source] > AGENT_SOURCE_PRECEDENCE[best.source] ? agent : best)) };
|
|
144
147
|
}
|
|
145
|
-
function nameExistsInScope(
|
|
146
|
-
const d =
|
|
148
|
+
function nameExistsInScope(ctx, scope, name, excludePath) {
|
|
149
|
+
const d = discoverCatalog(ctx);
|
|
147
150
|
for (const a of scope === "user" ? d.user : d.project) {
|
|
148
151
|
if (a.name === name && a.filePath !== excludePath)
|
|
149
152
|
return true;
|
|
@@ -664,7 +667,7 @@ function applyAgentConfig(target, cfg) {
|
|
|
664
667
|
}
|
|
665
668
|
return undefined;
|
|
666
669
|
}
|
|
667
|
-
function resolveTarget(name, matches, cwd, scopeHint) {
|
|
670
|
+
function resolveTarget(name, matches, cwd, ctx, scopeHint) {
|
|
668
671
|
const distinctNames = [...new Set(matches.map((match) => match.name))];
|
|
669
672
|
if (distinctNames.length > 1)
|
|
670
673
|
return result(`Ambiguous agent alias or name '${name}': ${distinctNames.sort((a, b) => a.localeCompare(b)).join(", ")}`, true);
|
|
@@ -672,7 +675,7 @@ function resolveTarget(name, matches, cwd, scopeHint) {
|
|
|
672
675
|
if (mutable.length === 0) {
|
|
673
676
|
if (matches.length > 0)
|
|
674
677
|
return result(`Agent '${name}' is read-only and cannot be modified. Create a same-named agent in user or project scope to override it.`, true);
|
|
675
|
-
return result(`Agent '${name}' not found. Available: ${availableAgentNames(cwd).join(", ") || "none"}.`, true);
|
|
678
|
+
return result(`Agent '${name}' not found. Available: ${availableAgentNames(ctx, cwd).join(", ") || "none"}.`, true);
|
|
676
679
|
}
|
|
677
680
|
if (mutable.length === 1)
|
|
678
681
|
return mutable[0];
|
|
@@ -688,8 +691,8 @@ function resolveTarget(name, matches, cwd, scopeHint) {
|
|
|
688
691
|
return result(`Multiple agents named '${name}' found in scope '${scope}': ${scoped.map((match) => match.filePath).join(", ")}`, true);
|
|
689
692
|
return scoped[0];
|
|
690
693
|
}
|
|
691
|
-
function renamePath(currentPath, newName, scope,
|
|
692
|
-
if (nameExistsInScope(
|
|
694
|
+
function renamePath(currentPath, newName, scope, ctx) {
|
|
695
|
+
if (nameExistsInScope(ctx, scope, newName, currentPath))
|
|
693
696
|
return { error: `Name '${newName}' already exists in ${scope} scope.` };
|
|
694
697
|
const filePath = path.join(path.dirname(currentPath), `${newName}.md`);
|
|
695
698
|
if (fs.existsSync(filePath) && filePath !== currentPath)
|
|
@@ -1017,7 +1020,7 @@ function formatAgentDetail(agent) {
|
|
|
1017
1020
|
}
|
|
1018
1021
|
export function handleList(params, ctx) {
|
|
1019
1022
|
const scope = normalizeListScope(params.agentScope) ?? "both";
|
|
1020
|
-
const d =
|
|
1023
|
+
const d = discoverCatalog(ctx, ctx.cwd, ctx.model?.provider);
|
|
1021
1024
|
let scopedAgents = effectiveAgentsForScope(scope, d, ctx.runtimeAgentOwner, ctx.model?.provider);
|
|
1022
1025
|
scopedAgents = scopedAgents
|
|
1023
1026
|
.sort((a, b) => a.name.localeCompare(b.name));
|
|
@@ -1074,7 +1077,7 @@ function handleModels(params, ctx) {
|
|
|
1074
1077
|
const scope = normalizeListScope(params.agentScope);
|
|
1075
1078
|
if (!scope)
|
|
1076
1079
|
return result("agentScope must be 'user', 'project', or 'both' for models.", true);
|
|
1077
|
-
const discovered =
|
|
1080
|
+
const discovered = discoverCatalog(ctx, ctx.cwd, ctx.model?.provider);
|
|
1078
1081
|
const effectiveAgents = effectiveAgentsForScope(scope, discovered, ctx.runtimeAgentOwner, ctx.model?.provider)
|
|
1079
1082
|
.sort((a, b) => a.name.localeCompare(b.name));
|
|
1080
1083
|
const availableModels = ctx.modelRegistry.getAvailable().map(toModelInfo);
|
|
@@ -1174,7 +1177,7 @@ function handleGet(params, ctx) {
|
|
|
1174
1177
|
const scope = normalizeListScope(params.agentScope);
|
|
1175
1178
|
if (!scope)
|
|
1176
1179
|
return result("agentScope must be 'user', 'project', or 'both' for get.", true);
|
|
1177
|
-
const discovered =
|
|
1180
|
+
const discovered = discoverCatalog(ctx, ctx.cwd, ctx.model?.provider);
|
|
1178
1181
|
const matches = findAgentsInDiscovery(params.agent, discovered, scope);
|
|
1179
1182
|
const diagnostics = diagnosticsForScope(discovered.agentDiagnostics, scope);
|
|
1180
1183
|
const rawName = params.agent.trim();
|
|
@@ -1215,11 +1218,11 @@ export function handleCreate(params, ctx) {
|
|
|
1215
1218
|
const scope = scopeRaw;
|
|
1216
1219
|
if (hasKey(cfg, "steps"))
|
|
1217
1220
|
return result("Durable chain definitions were removed; use workflowScript or /prompt-workflow for repeatable workflows.", true);
|
|
1218
|
-
const d =
|
|
1221
|
+
const d = discoverCatalog(ctx);
|
|
1219
1222
|
const projectConfigDir = getProjectConfigDir(ctx.cwd);
|
|
1220
1223
|
const targetDir = scope === "user" ? d.userDir : d.projectDir ?? path.join(projectConfigDir, "agents");
|
|
1221
1224
|
fs.mkdirSync(targetDir, { recursive: true });
|
|
1222
|
-
if (nameExistsInScope(ctx
|
|
1225
|
+
if (nameExistsInScope(ctx, scope, runtimeName))
|
|
1223
1226
|
return result(`Name '${runtimeName}' already exists in ${scope} scope. Use update instead.`, true);
|
|
1224
1227
|
const targetPath = path.join(targetDir, `${runtimeName}.md`);
|
|
1225
1228
|
if (fs.existsSync(targetPath))
|
|
@@ -1269,7 +1272,7 @@ export function handleUpdate(params, ctx) {
|
|
|
1269
1272
|
return result("Durable chain definitions were removed; use workflowScript or /prompt-workflow for repeatable workflows.", true);
|
|
1270
1273
|
const warnings = [];
|
|
1271
1274
|
const scopeHint = asDisambiguationScope(params.agentScope);
|
|
1272
|
-
const targetOrError = resolveTarget(params.agent, findAgents(params.agent, ctx
|
|
1275
|
+
const targetOrError = resolveTarget(params.agent, findAgents(params.agent, ctx, scopeHint ?? "both"), ctx.cwd, ctx, scopeHint);
|
|
1273
1276
|
if ("content" in targetOrError)
|
|
1274
1277
|
return targetOrError;
|
|
1275
1278
|
const target = targetOrError;
|
|
@@ -1327,7 +1330,7 @@ export function handleUpdate(params, ctx) {
|
|
|
1327
1330
|
warnings.push(sw);
|
|
1328
1331
|
}
|
|
1329
1332
|
if (updated.name !== oldName) {
|
|
1330
|
-
const renamed = renamePath(target.filePath, updated.name, target.source, ctx
|
|
1333
|
+
const renamed = renamePath(target.filePath, updated.name, target.source, ctx);
|
|
1331
1334
|
if (renamed.error)
|
|
1332
1335
|
return result(renamed.error, true);
|
|
1333
1336
|
updated.filePath = renamed.filePath;
|
|
@@ -1343,7 +1346,7 @@ function handleDelete(params, ctx) {
|
|
|
1343
1346
|
if (!params.agent)
|
|
1344
1347
|
return result("Specify 'agent' for delete.", true);
|
|
1345
1348
|
const scopeHint = asDisambiguationScope(params.agentScope);
|
|
1346
|
-
const targetOrError = resolveTarget(params.agent, findAgents(params.agent, ctx
|
|
1349
|
+
const targetOrError = resolveTarget(params.agent, findAgents(params.agent, ctx, scopeHint ?? "both"), ctx.cwd, ctx, scopeHint);
|
|
1347
1350
|
if ("content" in targetOrError)
|
|
1348
1351
|
return targetOrError;
|
|
1349
1352
|
const target = targetOrError;
|
|
@@ -1360,17 +1363,17 @@ function handleEject(params, ctx) {
|
|
|
1360
1363
|
if (parsedScope.error)
|
|
1361
1364
|
return parsedScope.error;
|
|
1362
1365
|
const scope = parsedScope.scope;
|
|
1363
|
-
const d =
|
|
1366
|
+
const d = discoverCatalog(ctx);
|
|
1364
1367
|
const source = [...d.package, ...d.builtin].find((a) => a.name === raw || a.name === sanitized);
|
|
1365
1368
|
if (!source) {
|
|
1366
|
-
return result(`Agent '${raw}' not found or is not a bundled/package agent. eject copies a builtin or package agent to ${scope} scope so it can be customized. Available: ${availableAgentNames(ctx
|
|
1369
|
+
return result(`Agent '${raw}' not found or is not a bundled/package agent. eject copies a builtin or package agent to ${scope} scope so it can be customized. Available: ${availableAgentNames(ctx).join(", ") || "none"}.`, true);
|
|
1367
1370
|
}
|
|
1368
1371
|
const runtimeName = source.name;
|
|
1369
1372
|
const existingCustom = (scope === "user" ? d.user : d.project).find((a) => a.name === runtimeName);
|
|
1370
1373
|
if (existingCustom) {
|
|
1371
1374
|
return result(`Agent '${runtimeName}' is already a custom ${scope} agent at ${existingCustom.filePath}. Edit it with { action: "update", agent: "${runtimeName}" } or delete it first.`, true);
|
|
1372
1375
|
}
|
|
1373
|
-
if (nameExistsInScope(ctx
|
|
1376
|
+
if (nameExistsInScope(ctx, scope, runtimeName)) {
|
|
1374
1377
|
return result(`An agent named '${runtimeName}' already exists in ${scope} scope. Remove or rename it first.`, true);
|
|
1375
1378
|
}
|
|
1376
1379
|
const projectConfigDir = getProjectConfigDir(ctx.cwd);
|
|
@@ -1400,7 +1403,7 @@ function handleDisable(params, ctx) {
|
|
|
1400
1403
|
if (parsedScope.error)
|
|
1401
1404
|
return parsedScope.error;
|
|
1402
1405
|
const scope = parsedScope.scope;
|
|
1403
|
-
const d =
|
|
1406
|
+
const d = discoverCatalog(ctx);
|
|
1404
1407
|
if (scope === "project" && d.projectSettingsPath === null) {
|
|
1405
1408
|
return result("Project override is not available here: no project config root (.pi or .agents) was found above the cwd. Use agentScope: 'user' or run from inside a project.", true);
|
|
1406
1409
|
}
|
|
@@ -1408,11 +1411,11 @@ function handleDisable(params, ctx) {
|
|
|
1408
1411
|
if (effective.error)
|
|
1409
1412
|
return result(effective.error, true);
|
|
1410
1413
|
if (!effective.agent) {
|
|
1411
|
-
return result(`Agent '${raw}' not found. Available: ${availableAgentNames(ctx
|
|
1414
|
+
return result(`Agent '${raw}' not found. Available: ${availableAgentNames(ctx).join(", ") || "none"}.`, true);
|
|
1412
1415
|
}
|
|
1413
1416
|
const runtimeName = effective.agent.name;
|
|
1414
1417
|
const settingsPath = mergeBuiltinAgentOverride(ctx.cwd, runtimeName, scope, { disabled: true });
|
|
1415
|
-
const after = resolveEffectiveAgent(
|
|
1418
|
+
const after = resolveEffectiveAgent(discoverCatalog(ctx), raw).agent;
|
|
1416
1419
|
if (after?.disabled === true) {
|
|
1417
1420
|
ctx.onAgentsChanged?.();
|
|
1418
1421
|
return result(`Disabled agent '${runtimeName}' via ${scope} settings override at ${settingsPath}. It is now hidden from runtime discovery and { action: "list" }.`);
|
|
@@ -1427,7 +1430,7 @@ function handleEnable(params, ctx) {
|
|
|
1427
1430
|
if (parsedScope.error)
|
|
1428
1431
|
return parsedScope.error;
|
|
1429
1432
|
const scope = parsedScope.scope;
|
|
1430
|
-
const d =
|
|
1433
|
+
const d = discoverCatalog(ctx);
|
|
1431
1434
|
if (scope === "project" && d.projectSettingsPath === null) {
|
|
1432
1435
|
return result("Project override is not available here: no project config root (.pi or .agents) was found above the cwd. Use agentScope: 'user' or run from inside a project.", true);
|
|
1433
1436
|
}
|
|
@@ -1435,11 +1438,11 @@ function handleEnable(params, ctx) {
|
|
|
1435
1438
|
if (effective.error)
|
|
1436
1439
|
return result(effective.error, true);
|
|
1437
1440
|
if (!effective.agent) {
|
|
1438
|
-
return result(`Agent '${raw}' not found. Available: ${availableAgentNames(ctx
|
|
1441
|
+
return result(`Agent '${raw}' not found. Available: ${availableAgentNames(ctx).join(", ") || "none"}.`, true);
|
|
1439
1442
|
}
|
|
1440
1443
|
const runtimeName = effective.agent.name;
|
|
1441
1444
|
const { path: settingsPath, removed } = removeBuiltinAgentOverrideFields(ctx.cwd, runtimeName, scope, ["disabled"]);
|
|
1442
|
-
const after = resolveEffectiveAgent(
|
|
1445
|
+
const after = resolveEffectiveAgent(discoverCatalog(ctx), raw).agent;
|
|
1443
1446
|
if (after && after.disabled !== true) {
|
|
1444
1447
|
if (removed)
|
|
1445
1448
|
ctx.onAgentsChanged?.();
|
|
@@ -1461,7 +1464,7 @@ function handleReset(params, ctx) {
|
|
|
1461
1464
|
if (parsedScope.error)
|
|
1462
1465
|
return parsedScope.error;
|
|
1463
1466
|
const scope = parsedScope.scope;
|
|
1464
|
-
const d =
|
|
1467
|
+
const d = discoverCatalog(ctx);
|
|
1465
1468
|
if (scope === "project" && d.projectSettingsPath === null) {
|
|
1466
1469
|
return result("Project override is not available here: no project config root (.pi or .agents) was found above the cwd. Use agentScope: 'user' or run from inside a project.", true);
|
|
1467
1470
|
}
|
|
@@ -1471,7 +1474,7 @@ function handleReset(params, ctx) {
|
|
|
1471
1474
|
if (custom) {
|
|
1472
1475
|
return result(`Agent '${raw}' has no bundled default to reset to. Use { action: "delete", agent: "${custom.name}" } to remove the custom ${custom.source} agent.`, true);
|
|
1473
1476
|
}
|
|
1474
|
-
return result(`Agent '${raw}' not found. Available: ${availableAgentNames(ctx
|
|
1477
|
+
return result(`Agent '${raw}' not found. Available: ${availableAgentNames(ctx).join(", ") || "none"}.`, true);
|
|
1475
1478
|
}
|
|
1476
1479
|
const runtimeName = bundled.name;
|
|
1477
1480
|
const custom = (scope === "user" ? d.user : d.project).find((a) => a.name === raw || a.name === sanitized);
|