@selesai/code 0.5.19 → 0.5.21
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/extensions/handoff-new.test.ts +8 -9
- package/dist/extensions/handoff-new.ts +6 -8
- package/dist/extensions/pi-intercom/broker/spawn.test.ts +31 -0
- package/dist/extensions/pi-intercom/broker/spawn.ts +5 -3
- package/dist/extensions/pi-subagents/CHANGELOG.md +1367 -0
- package/dist/extensions/pi-subagents/README.md +602 -220
- package/dist/extensions/pi-subagents/banner.png +0 -0
- package/dist/extensions/pi-subagents/index.ts +1 -0
- package/dist/extensions/pi-subagents/install.mjs +3 -3
- package/dist/extensions/pi-subagents/package-lock.json +3405 -0
- package/dist/extensions/pi-subagents/package.json +26 -14
- package/dist/extensions/pi-subagents/prompts/gather-context-and-clarify.md +1 -1
- package/dist/extensions/pi-subagents/prompts/parallel-cleanup.md +9 -9
- package/dist/extensions/pi-subagents/prompts/parallel-context-build.md +3 -3
- package/dist/extensions/pi-subagents/prompts/parallel-handoff-plan.md +7 -7
- package/dist/extensions/pi-subagents/prompts/parallel-research.md +6 -6
- package/dist/extensions/pi-subagents/prompts/parallel-review.md +8 -8
- package/dist/extensions/pi-subagents/prompts/review-loop.md +13 -11
- package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +267 -176
- package/dist/extensions/pi-subagents/src/agents/agent-management.ts +89 -16
- package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +19 -0
- package/dist/extensions/pi-subagents/src/agents/agents.ts +218 -120
- package/dist/extensions/pi-subagents/src/agents/frontmatter.ts +67 -13
- package/dist/extensions/pi-subagents/src/agents/proactive-skills.ts +2 -2
- package/dist/extensions/pi-subagents/src/agents/skills.ts +25 -12
- package/dist/extensions/pi-subagents/src/api/background-work.ts +197 -0
- package/dist/extensions/pi-subagents/src/api/capability-ceiling.ts +17 -0
- package/dist/extensions/pi-subagents/src/api/delegation.ts +285 -0
- package/dist/extensions/pi-subagents/src/api/preflight.ts +399 -0
- package/dist/extensions/pi-subagents/src/extension/chain-validation.ts +165 -0
- package/dist/extensions/pi-subagents/src/extension/config.ts +7 -1
- package/dist/extensions/pi-subagents/src/extension/doctor.ts +15 -0
- package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +3 -1
- package/dist/extensions/pi-subagents/src/extension/index.ts +113 -157
- package/dist/extensions/pi-subagents/src/extension/rpc.ts +41 -4
- package/dist/extensions/pi-subagents/src/extension/schemas.ts +45 -15
- package/dist/extensions/pi-subagents/src/extension/steering-notices.ts +35 -0
- package/dist/extensions/pi-subagents/src/extension/tool-description.ts +28 -15
- package/dist/extensions/pi-subagents/src/intercom/intercom-bridge.ts +4 -3
- package/dist/extensions/pi-subagents/src/intercom/native-supervisor-channel.ts +225 -29
- package/dist/extensions/pi-subagents/src/intercom/result-intercom.ts +11 -0
- package/dist/extensions/pi-subagents/src/profiles/profiles.ts +8 -10
- package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +452 -62
- package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +60 -9
- package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +198 -52
- package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +119 -21
- package/dist/extensions/pi-subagents/src/runs/background/auto-drain.ts +67 -0
- package/dist/extensions/pi-subagents/src/runs/background/chain-append.ts +2 -0
- package/dist/extensions/pi-subagents/src/runs/background/chain-root-attachment.ts +16 -8
- package/dist/extensions/pi-subagents/src/runs/background/completion-batcher.ts +6 -4
- package/dist/extensions/pi-subagents/src/runs/background/completion-dedupe.ts +2 -11
- package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +260 -13
- package/dist/extensions/pi-subagents/src/runs/background/fleet-view.ts +32 -6
- package/dist/extensions/pi-subagents/src/runs/background/notify.ts +171 -90
- package/dist/extensions/pi-subagents/src/runs/background/process-terminal.ts +280 -0
- package/dist/extensions/pi-subagents/src/runs/background/result-watcher.ts +149 -88
- package/dist/extensions/pi-subagents/src/runs/background/run-id-resolver.ts +14 -2
- package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +33 -17
- package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +9 -1
- package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +38 -10
- package/dist/extensions/pi-subagents/src/runs/background/steering.ts +237 -0
- package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +1297 -307
- package/dist/extensions/pi-subagents/src/runs/background/subagent-wait.ts +610 -0
- package/dist/extensions/pi-subagents/src/runs/background/top-level-async.ts +2 -1
- package/dist/extensions/pi-subagents/src/runs/background/wait-config.ts +36 -0
- package/dist/extensions/pi-subagents/src/runs/background/wait-tool.ts +26 -0
- package/dist/extensions/pi-subagents/src/runs/foreground/async-steering-action.ts +230 -0
- package/dist/extensions/pi-subagents/src/runs/foreground/chain-clarify.ts +22 -6
- package/dist/extensions/pi-subagents/src/runs/foreground/chain-execution.ts +228 -140
- package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +452 -138
- package/dist/extensions/pi-subagents/src/runs/foreground/foreground-control.ts +90 -0
- package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +1001 -416
- package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +443 -132
- package/dist/extensions/pi-subagents/src/runs/shared/agent-contract.ts +38 -0
- package/dist/extensions/pi-subagents/src/runs/shared/capability-ceiling.ts +178 -0
- package/dist/extensions/pi-subagents/src/runs/shared/child-protocol.ts +121 -0
- package/dist/extensions/pi-subagents/src/runs/shared/completion-guard.ts +41 -93
- package/dist/extensions/pi-subagents/src/runs/shared/context-mode.ts +44 -0
- package/dist/extensions/pi-subagents/src/runs/shared/dynamic-fanout.ts +11 -9
- package/dist/extensions/pi-subagents/src/runs/shared/long-running-guard.ts +4 -0
- package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +12 -6
- package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +36 -0
- package/dist/extensions/pi-subagents/src/runs/shared/nested-events.ts +44 -7
- package/dist/extensions/pi-subagents/src/runs/shared/nested-render.ts +4 -1
- package/dist/extensions/pi-subagents/src/runs/shared/parallel-handoff.ts +154 -0
- package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +18 -0
- package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +174 -54
- package/dist/extensions/pi-subagents/src/runs/shared/pi-spawn.ts +38 -31
- package/dist/extensions/pi-subagents/src/runs/shared/run-history.ts +90 -5
- package/dist/extensions/pi-subagents/src/runs/shared/session-lease.ts +299 -0
- package/dist/extensions/pi-subagents/src/runs/shared/single-output.ts +61 -6
- package/dist/extensions/pi-subagents/src/runs/shared/spawn-budget.ts +128 -0
- package/dist/extensions/pi-subagents/src/runs/shared/structured-output.ts +112 -7
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-control.ts +14 -6
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +149 -36
- package/dist/extensions/pi-subagents/src/runs/shared/task-intent.ts +181 -0
- package/dist/extensions/pi-subagents/src/runs/shared/tool-availability.ts +83 -0
- package/dist/extensions/pi-subagents/src/runs/shared/tool-budget.ts +11 -5
- package/dist/extensions/pi-subagents/src/runs/shared/turn-budget.ts +50 -4
- package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +63 -14
- package/dist/extensions/pi-subagents/src/shared/accessible-dir.ts +25 -0
- package/dist/extensions/pi-subagents/src/shared/artifacts.ts +37 -7
- package/dist/extensions/pi-subagents/src/shared/atomic-json.ts +18 -43
- package/dist/extensions/pi-subagents/src/shared/child-transcript.ts +52 -0
- package/dist/extensions/pi-subagents/src/shared/env.ts +16 -0
- package/dist/extensions/pi-subagents/src/shared/file-system-retry.ts +47 -0
- package/dist/extensions/pi-subagents/src/shared/fork-context.ts +28 -3
- package/dist/extensions/pi-subagents/src/shared/launch-contract.ts +123 -0
- package/dist/extensions/pi-subagents/src/shared/model-info.ts +8 -5
- package/dist/extensions/pi-subagents/src/shared/settings.ts +9 -1
- package/dist/extensions/pi-subagents/src/shared/status-format.ts +7 -1
- package/dist/extensions/pi-subagents/src/shared/types.ts +522 -51
- package/dist/extensions/pi-subagents/src/shared/utils.ts +59 -53
- package/dist/extensions/pi-subagents/src/slash/delegation-adapters.ts +604 -0
- package/dist/extensions/pi-subagents/src/slash/delegation-json.ts +108 -0
- package/dist/extensions/pi-subagents/src/slash/delegation-request.ts +249 -0
- package/dist/extensions/pi-subagents/src/slash/prompt-template-bridge.ts +353 -345
- package/dist/extensions/pi-subagents/src/slash/prompt-workflows.ts +2 -2
- package/dist/extensions/pi-subagents/src/slash/selector.ts +147 -0
- package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +265 -23
- package/dist/extensions/pi-subagents/src/slash/slash-live-state.ts +2 -2
- package/dist/extensions/pi-subagents/src/slash/subagents-admin.ts +428 -0
- package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +362 -0
- package/dist/extensions/pi-subagents/src/tui/fleet-transcript.ts +472 -0
- package/dist/extensions/pi-subagents/src/tui/fleet.ts +664 -0
- package/dist/extensions/pi-subagents/src/tui/render.ts +115 -31
- package/dist/extensions/pi-subagents/src/watchdog/change-signature.ts +220 -0
- package/dist/extensions/pi-subagents/src/watchdog/child-status.ts +205 -0
- package/dist/extensions/pi-subagents/src/watchdog/emission-guard.ts +123 -0
- package/dist/extensions/pi-subagents/src/watchdog/lsp-diagnostics.ts +532 -0
- package/dist/extensions/pi-subagents/src/watchdog/model-selection.ts +167 -0
- package/dist/extensions/pi-subagents/src/watchdog/register-child.ts +117 -0
- package/dist/extensions/pi-subagents/src/watchdog/register-main.ts +433 -0
- package/dist/extensions/pi-subagents/src/watchdog/render.ts +54 -0
- package/dist/extensions/pi-subagents/src/watchdog/review.ts +298 -0
- package/dist/extensions/pi-subagents/src/watchdog/runtime.ts +714 -0
- package/dist/extensions/pi-subagents/src/watchdog/settings.ts +528 -0
- package/dist/extensions/pi-subagents/src/watchdog/tool-actions.ts +155 -0
- package/dist/extensions/pi-subagents/src/watchdog/turn-delta.ts +161 -0
- package/dist/extensions/pi-subagents/src/watchdog/types.ts +188 -0
- package/dist/extensions/pi-subagents/src/watchdog/warning-format.ts +73 -0
- package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +130 -2
- package/dist/extensions/pi-subagents/test/integration/acceptance-file-report.test.ts +439 -0
- package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +1632 -61
- package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +54 -1
- package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +112 -0
- package/dist/extensions/pi-subagents/test/integration/chain-clarify.test.ts +98 -1
- package/dist/extensions/pi-subagents/test/integration/chain-execution.test.ts +179 -9
- package/dist/extensions/pi-subagents/test/integration/detect-error.test.ts +16 -9
- package/dist/extensions/pi-subagents/test/integration/error-handling.test.ts +6 -5
- package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +589 -9
- package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +528 -21
- package/dist/extensions/pi-subagents/test/integration/parallel-execution.test.ts +227 -3
- package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +235 -7
- package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +27 -0
- package/dist/extensions/pi-subagents/test/integration/result-watcher.test.ts +172 -2
- package/dist/extensions/pi-subagents/test/integration/single-execution.test.ts +1502 -18
- package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +993 -4
- package/dist/extensions/pi-subagents/test/integration/slash-live-state.test.ts +27 -0
- package/dist/extensions/pi-subagents/test/integration/top-level-async.test.ts +7 -1
- package/dist/extensions/pi-subagents/test/support/helpers.ts +32 -0
- package/dist/extensions/pi-subagents/test/support/mock-pi-script.mjs +59 -2
- package/dist/extensions/pi-subagents/test/support/mock-pi.ts +32 -6
- package/dist/extensions/pi-subagents/test/support/real-session-child-cli.mjs +25 -24
- package/dist/extensions/pi-subagents/test/support/real-session-runner.ts +59 -35
- package/dist/extensions/pi-subagents/test/support/session-lease-child.mjs +42 -0
- package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +703 -69
- package/dist/extensions/pi-subagents/test/unit/accessible-dir.test.ts +82 -0
- package/dist/extensions/pi-subagents/test/unit/agent-disabled.test.ts +15 -15
- package/dist/extensions/pi-subagents/test/unit/agent-eject-disable.test.ts +66 -66
- package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +478 -19
- package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +228 -7
- package/dist/extensions/pi-subagents/test/unit/agent-memory.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +198 -78
- package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +15 -1
- package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +102 -7
- package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +439 -6
- package/dist/extensions/pi-subagents/test/unit/atomic-json.test.ts +41 -1
- package/dist/extensions/pi-subagents/test/unit/auto-drain.test.ts +79 -0
- package/dist/extensions/pi-subagents/test/unit/background-work.test.ts +285 -0
- package/dist/extensions/pi-subagents/test/unit/capability-ceiling-pi-args.test.ts +84 -0
- package/dist/extensions/pi-subagents/test/unit/capability-ceiling.test.ts +68 -0
- package/dist/extensions/pi-subagents/test/unit/chain-validation.test.ts +326 -0
- package/dist/extensions/pi-subagents/test/unit/child-protocol.test.ts +82 -0
- package/dist/extensions/pi-subagents/test/unit/child-transcript.test.ts +46 -4
- package/dist/extensions/pi-subagents/test/unit/completion-batcher.test.ts +3 -1
- package/dist/extensions/pi-subagents/test/unit/completion-dedupe.test.ts +9 -17
- package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +175 -3
- package/dist/extensions/pi-subagents/test/unit/config-dir-runtime.test.ts +10 -5
- package/dist/extensions/pi-subagents/test/unit/control-channel.test.ts +126 -6
- package/dist/extensions/pi-subagents/test/unit/default-extensions.test.ts +219 -0
- package/dist/extensions/pi-subagents/test/unit/delegation-api.test.ts +913 -0
- package/dist/extensions/pi-subagents/test/unit/doctor.test.ts +13 -2
- package/dist/extensions/pi-subagents/test/unit/dynamic-fanout.test.ts +3 -3
- package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +351 -0
- package/dist/extensions/pi-subagents/test/unit/fleet-transcript.test.ts +280 -0
- package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +575 -0
- package/dist/extensions/pi-subagents/test/unit/foreground-control.test.ts +65 -0
- package/dist/extensions/pi-subagents/test/unit/fork-context.test.ts +94 -1
- package/dist/extensions/pi-subagents/test/unit/get-final-output.test.ts +23 -0
- package/dist/extensions/pi-subagents/test/unit/host-peer-runtime-imports.test.ts +157 -0
- package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +367 -5
- package/dist/extensions/pi-subagents/test/unit/intercom-bridge.test.ts +11 -0
- package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +36 -0
- package/dist/extensions/pi-subagents/test/unit/model-info.test.ts +25 -3
- package/dist/extensions/pi-subagents/test/unit/model-scope.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/native-supervisor-channel.test.ts +341 -10
- package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +16 -0
- package/dist/extensions/pi-subagents/test/unit/nested-events.test.ts +52 -0
- package/dist/extensions/pi-subagents/test/unit/notify.test.ts +168 -7
- package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +85 -7
- package/dist/extensions/pi-subagents/test/unit/parallel-handoff.test.ts +175 -0
- package/dist/extensions/pi-subagents/test/unit/path-resolution.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +243 -16
- package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +79 -36
- package/dist/extensions/pi-subagents/test/unit/pi-spawn.test.ts +174 -56
- package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +322 -0
- package/dist/extensions/pi-subagents/test/unit/process-terminal.test.ts +204 -0
- package/dist/extensions/pi-subagents/test/unit/recursion-guard.test.ts +20 -12
- package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +117 -4
- package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +40 -7
- package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +48 -1
- package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +21 -3
- package/dist/extensions/pi-subagents/test/unit/selector.test.ts +57 -0
- package/dist/extensions/pi-subagents/test/unit/session-lease.test.ts +326 -0
- package/dist/extensions/pi-subagents/test/unit/single-output.test.ts +101 -2
- package/dist/extensions/pi-subagents/test/unit/skills-fallback.test.ts +111 -1
- package/dist/extensions/pi-subagents/test/unit/spawn-budget.test.ts +124 -0
- package/dist/extensions/pi-subagents/test/unit/stale-run-reconciler.test.ts +6 -4
- package/dist/extensions/pi-subagents/test/unit/status-format.test.ts +7 -0
- package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +397 -0
- package/dist/extensions/pi-subagents/test/unit/steering-notices.test.ts +58 -0
- package/dist/extensions/pi-subagents/test/unit/steering.test.ts +173 -0
- package/dist/extensions/pi-subagents/test/unit/subagent-control.test.ts +25 -4
- package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +390 -25
- package/dist/extensions/pi-subagents/test/unit/subagent-wait.test.ts +837 -0
- package/dist/extensions/pi-subagents/test/unit/task-intent.test.ts +86 -0
- package/dist/extensions/pi-subagents/test/unit/tool-budget.test.ts +15 -0
- package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +47 -1
- package/dist/extensions/pi-subagents/test/unit/turn-budget.test.ts +56 -10
- package/dist/extensions/pi-subagents/test/unit/watchdog-change-signature.test.ts +387 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-child-status.test.ts +110 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-emission-guard.test.ts +62 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-lsp-diagnostics.test.ts +144 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-model-selection.test.ts +121 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-render.test.ts +76 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-review.test.ts +327 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-runtime.test.ts +863 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-settings.test.ts +290 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-tool-actions.test.ts +91 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-turn-delta.test.ts +130 -0
- package/dist/extensions/pi-subagents/test/unit/widget-nested-render.test.ts +32 -4
- package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +5 -1
- package/dist/extensions/pi-subagents/test/unit/writer-budget-guidance.test.ts +30 -0
- package/dist/extensions/question/batch.ts +39 -0
- package/dist/extensions/question/dialog-adapter.ts +23 -1
- package/dist/extensions/question/index.ts +237 -7
- package/dist/extensions/question/schemas.ts +28 -15
- package/dist/extensions/question/tests/batch.test.ts +26 -0
- package/dist/extensions/question/tests/ui-protocol.test.ts +23 -3
- package/dist/extensions/question/tui-adapter.ts +2 -3
- package/dist/extensions/question/types.ts +37 -0
- package/dist/extensions/question/ui-protocol.ts +3 -3
- package/dist/skills/batch-grill-me/SKILL.md +3 -1
- package/package.json +2 -1
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ExtensionAPI, ToolDefinition } from "@selesai/code";
|
|
2
|
+
import { SubagentWaitParams } from "../../extension/schemas.ts";
|
|
3
|
+
import type { Details, SubagentState } from "../../shared/types.ts";
|
|
4
|
+
import { resolveWaitToolConfig, waitForSubagents } from "./subagent-wait.ts";
|
|
5
|
+
|
|
6
|
+
export function registerWaitTool(pi: ExtensionAPI, state: SubagentState, enabled = resolveWaitToolConfig().enabled): void {
|
|
7
|
+
const tool: ToolDefinition<typeof SubagentWaitParams, Details> = {
|
|
8
|
+
name: "subagent_wait",
|
|
9
|
+
label: "Subagent Wait",
|
|
10
|
+
description: `Block until background work owned by this session changes, then return.
|
|
11
|
+
|
|
12
|
+
In an interactive chat, do not call this merely to wait: return control to the user and let Pi wake the session on completion. Override that default and call it when the current request is run-to-completion — for example, the user asked you to report results back before continuing or a skill cannot return before its work finishes. Headless runs auto-drain current-session work at agent_end; call this when the current turn must receive results before it ends.
|
|
13
|
+
|
|
14
|
+
• { } — return when the first initially active async run or registered provider item finishes, or when a subagent needs attention.
|
|
15
|
+
• { all: true } — wait for every async run and provider item that was active when the call began.
|
|
16
|
+
• { id: "..." } — wait for one async or remembered detached foreground subagent run (id or prefix).
|
|
17
|
+
• { timeoutMs: 600000 } — stop waiting after N ms; active work keeps running.
|
|
18
|
+
|
|
19
|
+
Provider jobs are session-scoped and identified exactly, so replacing one job with another cannot hide a completion. Provider extensions must be explicitly loaded in this process. In a child agent, keep \`subagent_wait\` in the child tool allowlist and load each provider through the agent's extensions or subagentOnlyExtensions; this tool never loads providers or grants tools itself.${enabled ? "" : "\n\nConfigured behavior: subagent_wait is disabled by config.waitTool or SELESAI_SUBAGENT_WAIT_TOOL_ENABLED and returns immediately without blocking."}`,
|
|
20
|
+
parameters: SubagentWaitParams,
|
|
21
|
+
execute(_id, params, signal, onUpdate) {
|
|
22
|
+
return waitForSubagents(params, signal, { state, events: pi.events, enabled, onUpdate });
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
pi.registerTool(tool);
|
|
26
|
+
}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import * as fs from "node:fs";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import type { AgentToolResult } from "@earendil-works/pi-agent-core";
|
|
5
|
+
import { writeAtomicJson } from "../../shared/atomic-json.ts";
|
|
6
|
+
import type { AsyncStatus, Details, SubagentState, ToolBudgetConfig, TurnBudgetConfig } from "../../shared/types.ts";
|
|
7
|
+
import { readStatus } from "../../shared/utils.ts";
|
|
8
|
+
import { consumeSteerAcks, deliverInterruptRequest, requestAsyncSteer } from "../background/control-channel.ts";
|
|
9
|
+
import { resolveAsyncResumeTarget } from "../background/async-resume.ts";
|
|
10
|
+
import { reconcileAsyncRun } from "../background/stale-run-reconciler.ts";
|
|
11
|
+
import { actionResultFromSteeringStatus, claimSteeringRecovery, remainingSteeringRecoveryLimits, updateSteeringTarget, waitForSteeringAction } from "../background/steering.ts";
|
|
12
|
+
|
|
13
|
+
export async function steerAsyncRun(input: {
|
|
14
|
+
state: SubagentState;
|
|
15
|
+
runId: string;
|
|
16
|
+
message: string;
|
|
17
|
+
index?: number;
|
|
18
|
+
kill?: (pid: number, signal?: NodeJS.Signals | 0) => boolean;
|
|
19
|
+
location: { asyncDir: string | null };
|
|
20
|
+
signal?: AbortSignal;
|
|
21
|
+
ackTimeoutMs?: number;
|
|
22
|
+
recoveryTimeoutMs?: number;
|
|
23
|
+
onRequestQueued?: (requestPath: string) => void;
|
|
24
|
+
onBeforeRecoveryClaim?: (requestId: string, committedAt: number) => void;
|
|
25
|
+
onRecoveryCommitted?: (requestId: string, committedAt: number) => void;
|
|
26
|
+
recover?: (limits: { timeoutMs?: number; absoluteDeadlineAt?: number; turnBudget?: TurnBudgetConfig; toolBudget?: ToolBudgetConfig }) => Promise<AgentToolResult<Details>>;
|
|
27
|
+
}): Promise<AgentToolResult<Details>> {
|
|
28
|
+
if (!input.location.asyncDir) {
|
|
29
|
+
return {
|
|
30
|
+
content: [{ type: "text", text: `Async run '${input.runId}' has no live run directory to steer.` }],
|
|
31
|
+
isError: true,
|
|
32
|
+
details: { mode: "management", results: [] },
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
const asyncDir = input.location.asyncDir;
|
|
36
|
+
const status = reconcileAsyncRun(asyncDir, { kill: input.kill }).status;
|
|
37
|
+
if (input.state.currentSessionId && status?.sessionId !== input.state.currentSessionId) {
|
|
38
|
+
return {
|
|
39
|
+
content: [{ type: "text", text: `Async run '${input.runId}' was not found in the active session.` }],
|
|
40
|
+
isError: true,
|
|
41
|
+
details: { mode: "management", results: [] },
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
if (!status || (status.state !== "running" && status.state !== "queued")) {
|
|
45
|
+
return {
|
|
46
|
+
content: [{ type: "text", text: `Async run '${input.runId}' is not running or queued and cannot be steered.` }],
|
|
47
|
+
isError: true,
|
|
48
|
+
details: { mode: "management", results: [] },
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
const steps = status.steps ?? [];
|
|
52
|
+
if (input.index !== undefined) {
|
|
53
|
+
if (input.index < 0 || input.index >= steps.length) {
|
|
54
|
+
return {
|
|
55
|
+
content: [{ type: "text", text: `Async run '${status.runId}' has ${steps.length} children. Index ${input.index} is out of range.` }],
|
|
56
|
+
isError: true,
|
|
57
|
+
details: { mode: "management", results: [] },
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
const targetStep = steps[input.index];
|
|
61
|
+
if (targetStep && targetStep.status !== "running" && targetStep.status !== "pending") {
|
|
62
|
+
return {
|
|
63
|
+
content: [{ type: "text", text: `Async run '${status.runId}' child ${input.index} is ${targetStep.status} and cannot be steered.` }],
|
|
64
|
+
isError: true,
|
|
65
|
+
details: { mode: "management", results: [] },
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
} else {
|
|
69
|
+
const running = steps.filter((step) => step.status === "running");
|
|
70
|
+
if (running.length === 0 && steps.length > 1) {
|
|
71
|
+
return {
|
|
72
|
+
content: [{ type: "text", text: `Async run '${status.runId}' has no running child yet. Provide index to steer a queued child.` }],
|
|
73
|
+
isError: true,
|
|
74
|
+
details: { mode: "management", results: [] },
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const runningIndexes = steps
|
|
79
|
+
.map((step, index) => step.status === "running" ? index : undefined)
|
|
80
|
+
.filter((index): index is number => index !== undefined);
|
|
81
|
+
const effectiveTargetIndex = input.index ?? (status.mode === "single" && runningIndexes.length === 0 && steps[0]?.status === "pending" ? 0 : undefined);
|
|
82
|
+
const targetIndexes = effectiveTargetIndex !== undefined ? [effectiveTargetIndex] : runningIndexes;
|
|
83
|
+
if (targetIndexes.length === 0) {
|
|
84
|
+
return {
|
|
85
|
+
content: [{ type: "text", text: `Async run '${status.runId}' has no running child to steer.` }],
|
|
86
|
+
isError: true,
|
|
87
|
+
details: { mode: "management", results: [] },
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
const requestId = randomUUID();
|
|
91
|
+
let requestPath: string;
|
|
92
|
+
try {
|
|
93
|
+
requestPath = requestAsyncSteer(asyncDir, {
|
|
94
|
+
message: input.message,
|
|
95
|
+
...(effectiveTargetIndex !== undefined ? { targetIndex: effectiveTargetIndex } : { targetIndexes }),
|
|
96
|
+
source: "steer-action",
|
|
97
|
+
id: requestId,
|
|
98
|
+
});
|
|
99
|
+
} catch (error) {
|
|
100
|
+
return {
|
|
101
|
+
content: [{ type: "text", text: `Failed to queue steering for async run ${status.runId}: ${error instanceof Error ? error.message : String(error)}` }],
|
|
102
|
+
isError: true,
|
|
103
|
+
details: { mode: "management", results: [] },
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
input.onRequestQueued?.(requestPath);
|
|
107
|
+
const tracked = input.state.asyncJobs.get(status.runId);
|
|
108
|
+
if (tracked) tracked.updatedAt = Date.now();
|
|
109
|
+
const targets = targetIndexes.map((index) => ({ index, state: status.steps?.[index]?.status === "pending" ? "scheduled" as const : "pending" as const }));
|
|
110
|
+
if (targets.every((target) => target.state === "scheduled")) {
|
|
111
|
+
const scheduled = { requestId, state: "scheduled" as const, sourceRunId: status.runId, targets };
|
|
112
|
+
return { content: [{ type: "text", text: `Steering scheduled for async run ${status.runId} (request ${requestId}).` }], details: { mode: "management", results: [], steering: scheduled } };
|
|
113
|
+
}
|
|
114
|
+
const waited = await waitForSteeringAction({ asyncDir, sourceRunId: status.runId, requestId, timeoutMs: input.ackTimeoutMs ?? 3_000, signal: input.signal });
|
|
115
|
+
const result = waited ?? { requestId, state: "pending" as const, sourceRunId: status.runId, targets };
|
|
116
|
+
if (input.signal?.aborted) {
|
|
117
|
+
return { content: [{ type: "text", text: `Steering pending for async run ${status.runId} (request ${requestId}); caller aborted before recovery.` }], details: { mode: "management", results: [], steering: result } };
|
|
118
|
+
}
|
|
119
|
+
const finalStatus = readStatus(asyncDir);
|
|
120
|
+
const finalResult = finalStatus?.steering ? actionResultFromSteeringStatus(finalStatus.steering, status.runId, requestId) : undefined;
|
|
121
|
+
if (finalResult?.state === "delivered") {
|
|
122
|
+
return { content: [{ type: "text", text: `Steering delivered for async run ${status.runId} (request ${requestId}).` }], details: { mode: "management", results: [], steering: finalResult } };
|
|
123
|
+
}
|
|
124
|
+
const running = (finalStatus?.steps ?? status.steps).filter((step) => step.status === "running");
|
|
125
|
+
const recoveryAllowed = status.mode === "single" && status.isNested !== true && running.length === 1 && Boolean(finalStatus?.steering) && (input.index === undefined || input.index === 0);
|
|
126
|
+
if (recoveryAllowed && finalResult?.state !== "scheduled" && input.recover) {
|
|
127
|
+
const appendSteeringNotice = (state: "failed" | "recovered", message: string): void => {
|
|
128
|
+
try {
|
|
129
|
+
fs.appendFileSync(path.join(asyncDir, "events.jsonl"), `${JSON.stringify({ type: "subagent.steering.notice", ts: Date.now(), runId: status.runId, requestId, state, message, ...(status.sessionId ? { currentSessionId: status.sessionId } : {}) })}\n`);
|
|
130
|
+
} catch {
|
|
131
|
+
// The action result and status remain authoritative if diagnostic notification persistence fails.
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
try {
|
|
135
|
+
const latest = readStatus(asyncDir);
|
|
136
|
+
const latestResult = latest?.steering ? actionResultFromSteeringStatus(latest.steering, status.runId, requestId) : undefined;
|
|
137
|
+
if (latestResult?.state === "delivered") return { content: [{ type: "text", text: `Steering delivered for async run ${status.runId} (request ${requestId}).` }], details: { mode: "management", results: [], steering: latestResult } };
|
|
138
|
+
const committedAt = Date.now();
|
|
139
|
+
input.onBeforeRecoveryClaim?.(requestId, committedAt);
|
|
140
|
+
const { claimPath, markerPath } = claimSteeringRecovery(asyncDir, { requestId, sourceRunId: status.runId, committedAt });
|
|
141
|
+
input.onRecoveryCommitted?.(requestId, committedAt);
|
|
142
|
+
const preCommitStatus = readStatus(asyncDir);
|
|
143
|
+
const preCommitResult = preCommitStatus?.steering ? actionResultFromSteeringStatus(preCommitStatus.steering, status.runId, requestId) : undefined;
|
|
144
|
+
if (preCommitResult?.state === "delivered" && preCommitResult.targets.every((target) => target.deliveredAt !== undefined && target.deliveredAt <= committedAt)) {
|
|
145
|
+
fs.rmSync(markerPath, { force: true });
|
|
146
|
+
fs.rmSync(claimPath, { force: true });
|
|
147
|
+
return { content: [{ type: "text", text: `Steering delivered for async run ${status.runId} (request ${requestId}).` }], details: { mode: "management", results: [], steering: preCommitResult } };
|
|
148
|
+
}
|
|
149
|
+
try {
|
|
150
|
+
deliverInterruptRequest({ asyncDir, pid: latest?.pid ?? status.pid, kill: input.kill, source: "steering-recovery" });
|
|
151
|
+
} catch (error) {
|
|
152
|
+
fs.rmSync(markerPath, { force: true });
|
|
153
|
+
fs.rmSync(claimPath, { force: true });
|
|
154
|
+
throw new Error(`Failed to commit steering recovery interrupt: ${error instanceof Error ? error.message : String(error)}`);
|
|
155
|
+
}
|
|
156
|
+
const pauseDeadline = Date.now() + (input.recoveryTimeoutMs ?? 15_000);
|
|
157
|
+
let paused: AsyncStatus | null = null;
|
|
158
|
+
while (Date.now() <= pauseDeadline) {
|
|
159
|
+
if (input.signal?.aborted) break;
|
|
160
|
+
const candidate = readStatus(asyncDir);
|
|
161
|
+
if (candidate?.state === "paused" && candidate.endedAt !== undefined) { paused = candidate; break; }
|
|
162
|
+
await new Promise<void>((resolve) => setTimeout(resolve, 50));
|
|
163
|
+
}
|
|
164
|
+
if (!paused) throw new Error("Source run did not reach confirmed paused state within 15 seconds; no replacement was launched and the recovery claim remains committed to prevent a delayed duplicate.");
|
|
165
|
+
let lateAckRecorded = false;
|
|
166
|
+
for (const ack of consumeSteerAcks(asyncDir)) {
|
|
167
|
+
if (!paused.steering?.recent.some((request) => request.id === ack.requestId && request.targets.some((target) => target.index === ack.index))) continue;
|
|
168
|
+
const state = ack.state === "delivered" ? "late" : "failed";
|
|
169
|
+
const reason = ack.state === "delivered" ? "acknowledged after recovery commit" : ack.message;
|
|
170
|
+
updateSteeringTarget(paused.steering, ack.requestId, ack.index, state, ack.ts, { reason });
|
|
171
|
+
const stepSteering = paused.steps?.[ack.index]?.steering;
|
|
172
|
+
if (stepSteering) updateSteeringTarget(stepSteering, ack.requestId, ack.index, state, ack.ts, { reason });
|
|
173
|
+
lateAckRecorded = true;
|
|
174
|
+
try {
|
|
175
|
+
fs.appendFileSync(path.join(asyncDir, "events.jsonl"), `${JSON.stringify({ type: ack.state === "delivered" ? "subagent.steer.delivered" : "subagent.steer.failed", ts: ack.ts, runId: status.runId, requestId: ack.requestId, index: ack.index, late: true, message: ack.message })}\n`);
|
|
176
|
+
} catch {
|
|
177
|
+
// Status remains authoritative when diagnostic event persistence fails.
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
if (lateAckRecorded) writeAtomicJson(path.join(asyncDir, "status.json"), paused);
|
|
181
|
+
let recoveryTarget;
|
|
182
|
+
try {
|
|
183
|
+
recoveryTarget = resolveAsyncResumeTarget(
|
|
184
|
+
{ id: status.runId },
|
|
185
|
+
{ kill: input.kill },
|
|
186
|
+
{ sessionId: input.state.currentSessionId ?? undefined },
|
|
187
|
+
);
|
|
188
|
+
} catch (error) {
|
|
189
|
+
throw new Error(`Source run remains paused and cannot be revived safely: ${error instanceof Error ? error.message : String(error)}`);
|
|
190
|
+
}
|
|
191
|
+
if (recoveryTarget.kind !== "revive" || !recoveryTarget.sessionFile) throw new Error("Source run has no valid persisted child session; it remains paused and requires a new run.");
|
|
192
|
+
if (!recoveryTarget.recoveryDescriptor) throw new Error("Source run has no private recovery descriptor; it remains paused and is not safely resumable.");
|
|
193
|
+
const limits = remainingSteeringRecoveryLimits(recoveryTarget.recoveryDescriptor, paused);
|
|
194
|
+
const revived = await input.recover(limits);
|
|
195
|
+
if (revived.isError || !revived.details.asyncId) throw new Error(revived.content[0]?.type === "text" ? revived.content[0].text : "Replacement launch failed; source run remains paused.");
|
|
196
|
+
const sourceStatus = readStatus(asyncDir);
|
|
197
|
+
const targetIndex = input.index ?? status.steps.findIndex((step) => step.status === "running");
|
|
198
|
+
if (sourceStatus?.state === "paused" && sourceStatus.steering && targetIndex >= 0) {
|
|
199
|
+
updateSteeringTarget(sourceStatus.steering, requestId, targetIndex, "recovered", Date.now(), { replacementRunId: revived.details.asyncId });
|
|
200
|
+
const stepSteering = sourceStatus.steps?.[targetIndex]?.steering;
|
|
201
|
+
if (stepSteering) updateSteeringTarget(stepSteering, requestId, targetIndex, "recovered", Date.now(), { replacementRunId: revived.details.asyncId });
|
|
202
|
+
writeAtomicJson(path.join(asyncDir, "status.json"), sourceStatus);
|
|
203
|
+
}
|
|
204
|
+
const recovered = sourceStatus?.steering ? actionResultFromSteeringStatus(sourceStatus.steering, status.runId, requestId, revived.details.asyncId) : undefined;
|
|
205
|
+
appendSteeringNotice("recovered", `Steering recovered for run ${status.runId}; replacement ${revived.details.asyncId} launched.`);
|
|
206
|
+
return { content: [{ type: "text", text: `Steering recovered for async run ${status.runId}; replacement ${revived.details.asyncId} launched after the source paused.` }], details: { mode: "management", results: [], steering: recovered ?? { requestId, state: "recovered", sourceRunId: status.runId, replacementRunId: revived.details.asyncId, targets: [{ index: input.index ?? 0, state: "recovered" }] } } };
|
|
207
|
+
} catch (error) {
|
|
208
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
209
|
+
const failedStatus = readStatus(asyncDir);
|
|
210
|
+
const targetIndex = input.index ?? status.steps.findIndex((step) => step.status === "running");
|
|
211
|
+
if (failedStatus && failedStatus.state !== "running" && failedStatus.state !== "queued" && failedStatus.steering && targetIndex >= 0) {
|
|
212
|
+
updateSteeringTarget(failedStatus.steering, requestId, targetIndex, "failed", Date.now(), { reason });
|
|
213
|
+
const stepSteering = failedStatus.steps?.[targetIndex]?.steering;
|
|
214
|
+
if (stepSteering) updateSteeringTarget(stepSteering, requestId, targetIndex, "failed", Date.now(), { reason });
|
|
215
|
+
failedStatus.activityState = "needs_attention";
|
|
216
|
+
writeAtomicJson(path.join(asyncDir, "status.json"), failedStatus);
|
|
217
|
+
}
|
|
218
|
+
const failed = failedStatus?.steering ? actionResultFromSteeringStatus(failedStatus.steering, status.runId, requestId) : undefined;
|
|
219
|
+
appendSteeringNotice("failed", `Steering failed for run ${status.runId}: ${reason}`);
|
|
220
|
+
return { content: [{ type: "text", text: `Steering failed for async run ${status.runId} (request ${requestId}): ${reason}` }], isError: true, details: { mode: "management", results: [], steering: failed ?? { requestId, state: "failed", sourceRunId: status.runId, targets: [{ index: input.index ?? 0, state: "failed", reason }] } } };
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
const stateText = result.state === "delivered" ? "delivered" : result.state === "scheduled" ? "scheduled" : result.state === "recovered" ? "recovered" : result.state === "failed" ? "failed" : result.state === "partial" ? "partial" : "pending";
|
|
224
|
+
const isError = result.state === "failed" || result.state === "partial";
|
|
225
|
+
return {
|
|
226
|
+
content: [{ type: "text", text: `Steering ${stateText} for async run ${status.runId} (request ${requestId}).` }],
|
|
227
|
+
...(isError ? { isError: true } : {}),
|
|
228
|
+
details: { mode: "management", results: [], steering: result },
|
|
229
|
+
};
|
|
230
|
+
}
|
|
@@ -1004,6 +1004,7 @@ export class ChainClarifyComponent implements Component {
|
|
|
1004
1004
|
"medium": "Moderate reasoning",
|
|
1005
1005
|
"high": "Deep reasoning",
|
|
1006
1006
|
"xhigh": "Maximum reasoning (ultrathink)",
|
|
1007
|
+
"max": "Maximum available reasoning",
|
|
1007
1008
|
};
|
|
1008
1009
|
|
|
1009
1010
|
const levels = this.getAvailableThinkingLevels(this.editingStep!);
|
|
@@ -1102,18 +1103,29 @@ export class ChainClarifyComponent implements Component {
|
|
|
1102
1103
|
return lines;
|
|
1103
1104
|
}
|
|
1104
1105
|
|
|
1105
|
-
private
|
|
1106
|
-
const
|
|
1106
|
+
private getShortcutHelpText(): string {
|
|
1107
|
+
const th = this.theme;
|
|
1108
|
+
const shortcut = (key: string, label: string) =>
|
|
1109
|
+
th.fg("accent", `[${key}]`) + th.fg("dim", label);
|
|
1110
|
+
const backgroundState = this.runInBackground ? "ON" : "OFF";
|
|
1111
|
+
const background = shortcut("b", `Background:${backgroundState}`);
|
|
1112
|
+
|
|
1107
1113
|
switch (this.mode) {
|
|
1108
1114
|
case 'single':
|
|
1109
|
-
return `
|
|
1115
|
+
return ` ${shortcut("e", "Task")} ${shortcut("m", "Model")} ${shortcut("t", "Think")} ${shortcut("w", "Output")} ${shortcut("s", "Skills")} ${background}`;
|
|
1110
1116
|
case 'parallel':
|
|
1111
|
-
return `
|
|
1117
|
+
return ` ${shortcut("e", "Task")} ${shortcut("m", "Model")} ${shortcut("t", "Think")} ${shortcut("s", "Skills")} ${background}`;
|
|
1112
1118
|
case 'chain':
|
|
1113
|
-
return `
|
|
1119
|
+
return ` ${shortcut("e", "Task")} ${shortcut("m", "Model")} ${shortcut("t", "Think")} ${shortcut("w", "Output")} ${shortcut("r", "Reads")} ${shortcut("p", "Prog")} ${shortcut("s", "Skills")} ${background}`;
|
|
1114
1120
|
}
|
|
1115
1121
|
}
|
|
1116
1122
|
|
|
1123
|
+
private getFooterText(): string {
|
|
1124
|
+
return this.mode === 'single'
|
|
1125
|
+
? " [Enter] Run • [Esc] Cancel "
|
|
1126
|
+
: " [Enter] Run • [Esc] Cancel • [↑↓] Navigate ";
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1117
1129
|
private appendNotice(lines: string[]): void {
|
|
1118
1130
|
if (!this.noticeMessage) return;
|
|
1119
1131
|
const color = this.noticeMessage.type === "error" ? "error" : "success";
|
|
@@ -1162,7 +1174,7 @@ export class ChainClarifyComponent implements Component {
|
|
|
1162
1174
|
const skillsLabel = th.fg("dim", "skills: ");
|
|
1163
1175
|
lines.push(this.row(` ${skillsLabel}${truncateToWidth(skillsValue, innerW - 14)}`));
|
|
1164
1176
|
|
|
1165
|
-
lines.push(this.row(
|
|
1177
|
+
lines.push(this.row(this.getShortcutHelpText()));
|
|
1166
1178
|
|
|
1167
1179
|
this.appendNotice(lines);
|
|
1168
1180
|
lines.push(this.renderFooter(this.getFooterText()));
|
|
@@ -1216,6 +1228,8 @@ export class ChainClarifyComponent implements Component {
|
|
|
1216
1228
|
lines.push(this.row(""));
|
|
1217
1229
|
}
|
|
1218
1230
|
|
|
1231
|
+
if (this.agentConfigs.length > 0) lines.pop();
|
|
1232
|
+
lines.push(this.row(this.getShortcutHelpText()));
|
|
1219
1233
|
this.appendNotice(lines);
|
|
1220
1234
|
lines.push(this.renderFooter(this.getFooterText()));
|
|
1221
1235
|
|
|
@@ -1319,6 +1333,8 @@ export class ChainClarifyComponent implements Component {
|
|
|
1319
1333
|
lines.push(this.row(""));
|
|
1320
1334
|
}
|
|
1321
1335
|
|
|
1336
|
+
if (this.agentConfigs.length > 0) lines.pop();
|
|
1337
|
+
lines.push(this.row(this.getShortcutHelpText()));
|
|
1322
1338
|
this.appendNotice(lines);
|
|
1323
1339
|
lines.push(this.renderFooter(this.getFooterText()));
|
|
1324
1340
|
|