@armadra/agent 0.4.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +184 -1
- package/README.md +202 -83
- package/THIRD_PARTY_NOTICES.md +34 -0
- package/dist/acp.d.ts +18 -0
- package/dist/acp.js +19 -0
- package/dist/agent/limits.d.ts +38 -0
- package/dist/agent/limits.js +127 -0
- package/dist/agent/loop-guard.d.ts +38 -0
- package/dist/agent/loop-guard.js +95 -0
- package/dist/agent/loop.d.ts +4 -0
- package/dist/agent/loop.js +7 -0
- package/dist/agent/prompt-rules.d.ts +12 -0
- package/dist/agent/prompt-rules.js +18 -0
- package/dist/agent/reminders.d.ts +59 -0
- package/dist/agent/reminders.js +327 -0
- package/dist/agent/session-cache.d.ts +5 -0
- package/dist/agent/session-cache.js +17 -1
- package/dist/agent/session-classifier.d.ts +1 -1
- package/dist/agent/session-classifier.js +3 -1
- package/dist/agent/session-compaction.d.ts +35 -6
- package/dist/agent/session-compaction.js +157 -31
- package/dist/agent/session-core.d.ts +27 -1
- package/dist/agent/session-extensions.d.ts +61 -0
- package/dist/agent/session-extensions.js +129 -0
- package/dist/agent/session-images.d.ts +23 -0
- package/dist/agent/session-images.js +97 -0
- package/dist/agent/session-plan.d.ts +21 -0
- package/dist/agent/session-plan.js +524 -0
- package/dist/agent/session-rewind.d.ts +81 -0
- package/dist/agent/session-rewind.js +354 -0
- package/dist/agent/session-run.d.ts +28 -1
- package/dist/agent/session-run.js +157 -6
- package/dist/agent/session-settings.d.ts +49 -0
- package/dist/agent/session-settings.js +95 -0
- package/dist/agent/session-subagent.d.ts +36 -24
- package/dist/agent/session-subagent.js +259 -129
- package/dist/agent/session-sync.d.ts +10 -3
- package/dist/agent/session-sync.js +37 -8
- package/dist/agent/session-telemetry.d.ts +39 -0
- package/dist/agent/session-telemetry.js +231 -0
- package/dist/agent/session-tools.js +40 -1
- package/dist/agent/session.d.ts +30 -29
- package/dist/agent/session.js +79 -123
- package/dist/agent/subagent-registry.d.ts +91 -0
- package/dist/agent/subagent-registry.js +494 -0
- package/dist/agent/system-prompt.d.ts +6 -3
- package/dist/agent/system-prompt.js +7 -2
- package/dist/agent/tool-runner.d.ts +8 -1
- package/dist/agent/tool-runner.js +57 -4
- package/dist/agent/types-w5.d.ts +192 -0
- package/dist/agent/types-w5.js +10 -0
- package/dist/agent/types.d.ts +47 -4
- package/dist/agent/types.js +2 -0
- package/dist/agent/worktree.d.ts +36 -0
- package/dist/agent/worktree.js +86 -0
- package/dist/agents/builtin.d.ts +14 -0
- package/dist/agents/builtin.js +39 -0
- package/dist/agents/catalog.d.ts +43 -0
- package/dist/agents/catalog.js +82 -0
- package/dist/agents/discover.d.ts +35 -0
- package/dist/agents/discover.js +83 -0
- package/dist/agents/external.d.ts +82 -0
- package/dist/agents/external.js +326 -0
- package/dist/agents/parse.d.ts +18 -0
- package/dist/agents/parse.js +116 -0
- package/dist/agents/result.d.ts +32 -0
- package/dist/agents/result.js +67 -0
- package/dist/agents/task-control.d.ts +17 -0
- package/dist/agents/task-control.js +17 -0
- package/dist/agents/task-record.d.ts +78 -0
- package/dist/agents/task-record.js +141 -0
- package/dist/agents/types.d.ts +46 -0
- package/dist/agents/types.js +8 -0
- package/dist/ai/apis/anthropic-compat.d.ts +36 -0
- package/dist/ai/apis/anthropic-compat.js +92 -0
- package/dist/ai/apis/anthropic-request.d.ts +7 -6
- package/dist/ai/apis/anthropic-request.js +10 -28
- package/dist/ai/apis/cache-params.d.ts +11 -2
- package/dist/ai/apis/cache-params.js +25 -6
- package/dist/ai/apis/openai-compat.d.ts +4 -1
- package/dist/ai/apis/openai-compat.js +8 -1
- package/dist/ai/image-limits.d.ts +45 -0
- package/dist/ai/image-limits.js +68 -0
- package/dist/ai/providers/builtin.d.ts +18 -6
- package/dist/ai/providers/builtin.js +135 -6
- package/dist/ai/providers/catalog-data.js +17 -13
- package/dist/ai/providers/catalog.d.ts +60 -7
- package/dist/ai/providers/catalog.js +197 -38
- package/dist/ai/providers/channels.d.ts +33 -3
- package/dist/ai/providers/channels.js +108 -7
- package/dist/ai/providers/enrich.d.ts +6 -3
- package/dist/ai/providers/enrich.js +19 -4
- package/dist/ai/providers/models-dev-cache.d.ts +28 -24
- package/dist/ai/providers/models-dev-cache.js +92 -78
- package/dist/ai/providers/models-dev-data.d.ts +7 -0
- package/dist/ai/providers/models-dev-data.js +32 -0
- package/dist/ai/providers/models-dev-snapshot.d.ts +50 -0
- package/dist/ai/providers/models-dev-snapshot.js +137 -0
- package/dist/ai/providers/models-dev.d.ts +51 -10
- package/dist/ai/providers/models-dev.js +132 -39
- package/dist/ai/providers/registry.d.ts +20 -10
- package/dist/ai/providers/registry.js +82 -43
- package/dist/ai/types.d.ts +28 -2
- package/dist/ai/types.js +5 -0
- package/dist/bundle/ama.cjs +37605 -21619
- package/dist/checkpoints/backend.d.ts +61 -0
- package/dist/checkpoints/backend.js +135 -0
- package/dist/checkpoints/blobs.d.ts +60 -0
- package/dist/checkpoints/blobs.js +203 -0
- package/dist/checkpoints/gc.d.ts +47 -0
- package/dist/checkpoints/gc.js +144 -0
- package/dist/checkpoints/git-head.d.ts +15 -0
- package/dist/checkpoints/git-head.js +89 -0
- package/dist/checkpoints/index.d.ts +17 -0
- package/dist/checkpoints/index.js +17 -0
- package/dist/checkpoints/replay.d.ts +48 -0
- package/dist/checkpoints/replay.js +154 -0
- package/dist/checkpoints/restore.d.ts +86 -0
- package/dist/checkpoints/restore.js +263 -0
- package/dist/checkpoints/settings.d.ts +14 -0
- package/dist/checkpoints/settings.js +23 -0
- package/dist/checkpoints/shadow-git.d.ts +108 -0
- package/dist/checkpoints/shadow-git.js +491 -0
- package/dist/checkpoints/shadow-restore.d.ts +25 -0
- package/dist/checkpoints/shadow-restore.js +128 -0
- package/dist/checkpoints/tracker.d.ts +64 -0
- package/dist/checkpoints/tracker.js +192 -0
- package/dist/checkpoints/types.d.ts +99 -0
- package/dist/checkpoints/types.js +12 -0
- package/dist/cli/args.d.ts +8 -4
- package/dist/cli/args.js +17 -97
- package/dist/cli/bootstrap.js +13 -1
- package/dist/cli/choice-prompt.d.ts +58 -0
- package/dist/cli/choice-prompt.js +140 -0
- package/dist/cli/codemode-notice.d.ts +3 -2
- package/dist/cli/codemode-notice.js +3 -2
- package/dist/cli/compose-agents.d.ts +27 -0
- package/dist/cli/compose-agents.js +111 -0
- package/dist/cli/compose-extensions.d.ts +29 -0
- package/dist/cli/compose-extensions.js +44 -0
- package/dist/cli/compose-session.d.ts +3 -0
- package/dist/cli/compose-session.js +47 -4
- package/dist/cli/compose.d.ts +3 -0
- package/dist/cli/compose.js +33 -6
- package/dist/cli/deps.d.ts +6 -0
- package/dist/cli/exit-codes.d.ts +10 -0
- package/dist/cli/exit-codes.js +12 -0
- package/dist/cli/help-text.d.ts +4 -0
- package/dist/cli/help-text.js +102 -0
- package/dist/cli/startup-screen.js +5 -3
- package/dist/cli/startup-steps.js +7 -1
- package/dist/cli/subcommands/config.d.ts +4 -1
- package/dist/cli/subcommands/config.js +17 -6
- package/dist/cli/subcommands/doctor.js +21 -0
- package/dist/cli/subcommands/models-cache-probe.d.ts +1 -1
- package/dist/cli/subcommands/models-cache-probe.js +3 -12
- package/dist/cli/subcommands/models-discover.js +5 -6
- package/dist/cli/subcommands/models.d.ts +2 -0
- package/dist/cli/subcommands/models.js +33 -14
- package/dist/cli/subcommands/providers.d.ts +1 -1
- package/dist/cli/subcommands/providers.js +8 -15
- package/dist/cli/subcommands/sessions.d.ts +3 -1
- package/dist/cli/subcommands/sessions.js +36 -2
- package/dist/codemode/capability.d.ts +24 -7
- package/dist/codemode/capability.js +38 -10
- package/dist/codemode/host-side.d.ts +14 -0
- package/dist/codemode/host-side.js +24 -1
- package/dist/codemode/tool.d.ts +1 -1
- package/dist/codemode/tool.js +6 -4
- package/dist/compaction/breaker.d.ts +25 -9
- package/dist/compaction/breaker.js +47 -17
- package/dist/compaction/estimate.d.ts +11 -3
- package/dist/compaction/estimate.js +64 -22
- package/dist/compaction/image-budget.d.ts +45 -0
- package/dist/compaction/image-budget.js +115 -0
- package/dist/compaction/post-compact.d.ts +38 -0
- package/dist/compaction/post-compact.js +152 -0
- package/dist/compaction/protect.d.ts +27 -0
- package/dist/compaction/protect.js +56 -0
- package/dist/compaction/prune-tier.d.ts +58 -12
- package/dist/compaction/prune-tier.js +120 -54
- package/dist/compaction/summarize-tier.d.ts +23 -4
- package/dist/compaction/summarize-tier.js +100 -29
- package/dist/config/checker.d.ts +28 -0
- package/dist/config/checker.js +97 -0
- package/dist/config/json-schema.js +63 -2
- package/dist/config/key-docs.js +72 -3
- package/dist/config/merge.d.ts +5 -3
- package/dist/config/merge.js +81 -7
- package/dist/config/profile.d.ts +2 -0
- package/dist/config/profile.js +2 -0
- package/dist/config/schema-w5.d.ts +18 -0
- package/dist/config/schema-w5.js +109 -0
- package/dist/config/schema.d.ts +5 -9
- package/dist/config/schema.js +68 -114
- package/dist/config/types-w5.d.ts +118 -0
- package/dist/config/types-w5.js +20 -0
- package/dist/config/types.d.ts +50 -1
- package/dist/config/types.js +12 -0
- package/dist/drivers/acp/client.d.ts +57 -0
- package/dist/drivers/acp/client.js +160 -0
- package/dist/drivers/acp/driver.d.ts +31 -0
- package/dist/drivers/acp/driver.js +274 -0
- package/dist/drivers/acp/testing/fake-agent-main.d.ts +5 -0
- package/dist/drivers/acp/testing/fake-agent-main.js +7 -0
- package/dist/drivers/acp/testing/fake-agent.d.ts +27 -0
- package/dist/drivers/acp/testing/fake-agent.js +211 -0
- package/dist/drivers/acp/types.d.ts +285 -0
- package/dist/drivers/acp/types.js +36 -0
- package/dist/drivers/agents.d.ts +58 -0
- package/dist/drivers/agents.js +142 -0
- package/dist/drivers/base.d.ts +35 -0
- package/dist/drivers/base.js +59 -0
- package/dist/drivers/catalog.d.ts +46 -0
- package/dist/drivers/catalog.js +167 -0
- package/dist/drivers/env.d.ts +20 -0
- package/dist/drivers/env.js +46 -0
- package/dist/drivers/host-runners.d.ts +18 -0
- package/dist/drivers/host-runners.js +45 -0
- package/dist/drivers/jsonrpc.d.ts +58 -0
- package/dist/drivers/jsonrpc.js +180 -0
- package/dist/drivers/native/claude-normalize.d.ts +46 -0
- package/dist/drivers/native/claude-normalize.js +106 -0
- package/dist/drivers/native/claude-stream.d.ts +29 -0
- package/dist/drivers/native/claude-stream.js +456 -0
- package/dist/drivers/native/codex-app-server.d.ts +26 -0
- package/dist/drivers/native/codex-app-server.js +407 -0
- package/dist/drivers/native/codex-normalize.d.ts +38 -0
- package/dist/drivers/native/codex-normalize.js +124 -0
- package/dist/drivers/native/oneshot.d.ts +28 -0
- package/dist/drivers/native/oneshot.js +312 -0
- package/dist/drivers/permissions.d.ts +40 -0
- package/dist/drivers/permissions.js +92 -0
- package/dist/drivers/pids.d.ts +32 -0
- package/dist/drivers/pids.js +93 -0
- package/dist/drivers/pool.d.ts +28 -0
- package/dist/drivers/pool.js +96 -0
- package/dist/drivers/probe.d.ts +47 -0
- package/dist/drivers/probe.js +172 -0
- package/dist/drivers/process.d.ts +48 -0
- package/dist/drivers/process.js +100 -0
- package/dist/drivers/runner.d.ts +61 -0
- package/dist/drivers/runner.js +388 -0
- package/dist/drivers/store.d.ts +49 -0
- package/dist/drivers/store.js +91 -0
- package/dist/drivers/turn.d.ts +41 -0
- package/dist/drivers/turn.js +99 -0
- package/dist/drivers/types.d.ts +122 -0
- package/dist/drivers/types.js +11 -0
- package/dist/git/info.d.ts +75 -0
- package/dist/git/info.js +191 -0
- package/dist/hooks/protocol.js +6 -1
- package/dist/hooks/types.d.ts +10 -1
- package/dist/hooks/types.js +2 -0
- package/dist/host/api-impl.d.ts +7 -0
- package/dist/host/api-impl.js +15 -0
- package/dist/host/types.d.ts +24 -2
- package/dist/host/types.js +4 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1 -0
- package/dist/modes/acp/acp-events.d.ts +46 -0
- package/dist/modes/acp/acp-events.js +233 -0
- package/dist/modes/acp/acp-mode.d.ts +17 -0
- package/dist/modes/acp/acp-mode.js +47 -0
- package/dist/modes/acp/acp-server.d.ts +79 -0
- package/dist/modes/acp/acp-server.js +315 -0
- package/dist/modes/commands-core.d.ts +13 -1
- package/dist/modes/commands-core.js +64 -0
- package/dist/modes/image-input.d.ts +12 -4
- package/dist/modes/image-input.js +22 -5
- package/dist/modes/interactive/agent-panels.d.ts +14 -0
- package/dist/modes/interactive/agent-panels.js +103 -0
- package/dist/modes/interactive/agent-ui.d.ts +73 -0
- package/dist/modes/interactive/agent-ui.js +234 -0
- package/dist/modes/interactive/approval-dialog.d.ts +21 -4
- package/dist/modes/interactive/approval-dialog.js +98 -20
- package/dist/modes/interactive/approval-merge.d.ts +41 -0
- package/dist/modes/interactive/approval-merge.js +89 -0
- package/dist/modes/interactive/clipboard-paste.d.ts +18 -0
- package/dist/modes/interactive/clipboard-paste.js +28 -0
- package/dist/modes/interactive/commands.d.ts +12 -1
- package/dist/modes/interactive/commands.js +31 -1
- package/dist/modes/interactive/confirm-dialog.d.ts +49 -0
- package/dist/modes/interactive/confirm-dialog.js +121 -0
- package/dist/modes/interactive/double-esc.d.ts +20 -0
- package/dist/modes/interactive/double-esc.js +34 -0
- package/dist/modes/interactive/event-notices.d.ts +32 -0
- package/dist/modes/interactive/event-notices.js +79 -0
- package/dist/modes/interactive/external-editor.d.ts +16 -0
- package/dist/modes/interactive/external-editor.js +39 -0
- package/dist/modes/interactive/interactive-mode.d.ts +14 -1
- package/dist/modes/interactive/interactive-mode.js +140 -136
- package/dist/modes/interactive/key-dispatch.d.ts +22 -2
- package/dist/modes/interactive/key-dispatch.js +66 -7
- package/dist/modes/interactive/line/line-mode.d.ts +4 -1
- package/dist/modes/interactive/line/line-mode.js +31 -5
- package/dist/modes/interactive/line/line-render.d.ts +2 -1
- package/dist/modes/interactive/line/line-render.js +40 -4
- package/dist/modes/interactive/message-view.d.ts +1 -1
- package/dist/modes/interactive/message-view.js +24 -2
- package/dist/modes/interactive/panels.d.ts +18 -1
- package/dist/modes/interactive/panels.js +19 -5
- package/dist/modes/interactive/plan-command.d.ts +40 -0
- package/dist/modes/interactive/plan-command.js +129 -0
- package/dist/modes/interactive/plan-dialog.d.ts +98 -0
- package/dist/modes/interactive/plan-dialog.js +290 -0
- package/dist/modes/interactive/plan-flow.d.ts +34 -0
- package/dist/modes/interactive/plan-flow.js +98 -0
- package/dist/modes/interactive/rewind-command.d.ts +31 -0
- package/dist/modes/interactive/rewind-command.js +106 -0
- package/dist/modes/interactive/rewind-flow.d.ts +37 -0
- package/dist/modes/interactive/rewind-flow.js +151 -0
- package/dist/modes/interactive/rewind-list.d.ts +36 -0
- package/dist/modes/interactive/rewind-list.js +123 -0
- package/dist/modes/interactive/rewind-panel.d.ts +77 -0
- package/dist/modes/interactive/rewind-panel.js +309 -0
- package/dist/modes/interactive/rewind-text.d.ts +40 -0
- package/dist/modes/interactive/rewind-text.js +139 -0
- package/dist/modes/interactive/session-events.d.ts +24 -0
- package/dist/modes/interactive/session-events.js +96 -0
- package/dist/modes/interactive/startup-ui.js +5 -1
- package/dist/modes/interactive/status-area.d.ts +73 -0
- package/dist/modes/interactive/status-area.js +190 -0
- package/dist/modes/interactive/status-bar.d.ts +99 -11
- package/dist/modes/interactive/status-bar.js +273 -90
- package/dist/modes/interactive/status-line.d.ts +33 -0
- package/dist/modes/interactive/status-line.js +113 -0
- package/dist/modes/interactive/subagent-view.d.ts +56 -0
- package/dist/modes/interactive/subagent-view.js +154 -0
- package/dist/modes/interactive/tasks-report.d.ts +27 -0
- package/dist/modes/interactive/tasks-report.js +114 -0
- package/dist/modes/interactive/tool-view.d.ts +12 -2
- package/dist/modes/interactive/tool-view.js +34 -4
- package/dist/modes/print/print-mode.d.ts +13 -4
- package/dist/modes/print/print-mode.js +56 -12
- package/dist/modes/rpc/commands.d.ts +9 -0
- package/dist/modes/rpc/commands.js +44 -0
- package/dist/modes/rpc/rpc-mode.js +7 -1
- package/dist/modes/session-report.d.ts +11 -0
- package/dist/modes/session-report.js +48 -1
- package/dist/permissions/auto-safe.d.ts +5 -0
- package/dist/permissions/auto-safe.js +18 -0
- package/dist/permissions/bypass.d.ts +32 -0
- package/dist/permissions/bypass.js +36 -0
- package/dist/permissions/classifier.d.ts +4 -0
- package/dist/permissions/classifier.js +2 -0
- package/dist/permissions/modes.js +1 -1
- package/dist/permissions/pipeline.d.ts +43 -4
- package/dist/permissions/pipeline.js +114 -9
- package/dist/permissions/readonly-bash.d.ts +30 -0
- package/dist/permissions/readonly-bash.js +118 -0
- package/dist/permissions/types.d.ts +42 -0
- package/dist/plan/compose.d.ts +9 -0
- package/dist/plan/compose.js +19 -0
- package/dist/plan/controller.d.ts +71 -0
- package/dist/plan/controller.js +27 -0
- package/dist/plan/done-markers.d.ts +17 -0
- package/dist/plan/done-markers.js +51 -0
- package/dist/plan/extract.d.ts +29 -0
- package/dist/plan/extract.js +160 -0
- package/dist/plan/prompts.d.ts +36 -0
- package/dist/plan/prompts.js +89 -0
- package/dist/plan/store.d.ts +37 -0
- package/dist/plan/store.js +90 -0
- package/dist/rpc.d.ts +58 -2
- package/dist/rpc.js +7 -0
- package/dist/sandbox/bash.d.ts +74 -0
- package/dist/sandbox/bash.js +126 -0
- package/dist/sandbox/detect.d.ts +48 -0
- package/dist/sandbox/detect.js +149 -0
- package/dist/sandbox/index.d.ts +5 -0
- package/dist/sandbox/index.js +5 -0
- package/dist/sandbox/profile.d.ts +33 -0
- package/dist/sandbox/profile.js +76 -0
- package/dist/sandbox/wrap.d.ts +29 -0
- package/dist/sandbox/wrap.js +117 -0
- package/dist/sdk.d.ts +33 -2
- package/dist/sdk.js +24 -2
- package/dist/session/types.d.ts +3 -1
- package/dist/session/types.js +1 -0
- package/dist/skills/builtin.d.ts +31 -0
- package/dist/skills/builtin.js +109 -0
- package/dist/skills/discover.d.ts +2 -1
- package/dist/skills/index-prompt.js +5 -8
- package/dist/tools/background-jobs.d.ts +71 -0
- package/dist/tools/background-jobs.js +198 -0
- package/dist/tools/bash.d.ts +53 -1
- package/dist/tools/bash.js +158 -7
- package/dist/tools/clipboard-image.d.ts +44 -0
- package/dist/tools/clipboard-image.js +148 -0
- package/dist/tools/edit.d.ts +2 -0
- package/dist/tools/edit.js +18 -3
- package/dist/tools/image-file.d.ts +38 -3
- package/dist/tools/image-file.js +81 -10
- package/dist/tools/image-resize.d.ts +58 -0
- package/dist/tools/image-resize.js +97 -0
- package/dist/tools/presets.d.ts +7 -2
- package/dist/tools/presets.js +11 -4
- package/dist/tools/read.d.ts +5 -2
- package/dist/tools/read.js +13 -10
- package/dist/tools/registry.d.ts +7 -1
- package/dist/tools/registry.js +27 -4
- package/dist/tools/task-ctl.d.ts +22 -0
- package/dist/tools/task-ctl.js +116 -0
- package/dist/tools/task.d.ts +22 -10
- package/dist/tools/task.js +66 -26
- package/dist/tools/todo.d.ts +22 -2
- package/dist/tools/todo.js +58 -14
- package/dist/tools/truncate.d.ts +15 -0
- package/dist/tools/truncate.js +25 -0
- package/dist/tools/types.d.ts +113 -0
- package/dist/tools/types.js +5 -0
- package/dist/tools/write.js +3 -0
- package/dist/tui/glyphs.d.ts +4 -0
- package/dist/tui/glyphs.js +4 -0
- package/dist/tui/keybindings.d.ts +6 -1
- package/dist/tui/keybindings.js +6 -1
- package/docs/acp.md +78 -0
- package/docs/agents.md +250 -0
- package/docs/codemode.md +12 -8
- package/docs/hooks.md +26 -22
- package/docs/permissions.md +78 -13
- package/docs/plan.md +107 -0
- package/docs/providers.md +228 -52
- package/docs/rewind-plan.md +181 -0
- package/docs/rpc.md +92 -5
- package/docs/sandbox.md +215 -0
- package/docs/session-format.md +41 -21
- package/docs/sessions.md +41 -1
- package/docs/tui-design.md +751 -0
- package/docs/tui.md +179 -21
- package/package.json +13 -2
|
@@ -10,12 +10,31 @@
|
|
|
10
10
|
* - 将要停下时发 agent_before_settle 并跑 Stop(子 Agent 为 SubagentStop)Hook:block + reason →
|
|
11
11
|
* 以 reason 作为新 user 消息再跑一轮(上限 3 次,stopHookActive 传给 Hook)。
|
|
12
12
|
* - 最终失败后若 followUp 队列非空,照常投递。
|
|
13
|
+
* - [W5-H2] 模型回退:可重试错误在 overloaded 时、或重试用尽后,若配置了 `fallbackModel` 就切过去
|
|
14
|
+
* 重试一次本请求(`model_fallback` 事件),回退模型回复后切回主模型;每个周期最多一次。
|
|
15
|
+
* - [W5-H2] 扩展经 `noteSettleWarning` 登记的 warning(预算到限 `limit_reached`)写进本周期的 agent_settled;
|
|
16
|
+
* `limit_reached:` 开头的错误回复(预算拦下请求)不重试。
|
|
17
|
+
* - [W5-H2] run 带 `warning`(重复调用检测 `repeated_tool_call`):不跑 Stop Hook,agent_settled 带该 warning。
|
|
13
18
|
*/
|
|
14
19
|
import { AmaError } from "../errors.js";
|
|
20
|
+
import { formatModelRef, modelRefOf } from "../ai/providers/channels.js";
|
|
15
21
|
import { classifyFailure, retryDelayMs, sleep } from "./retry.js";
|
|
16
22
|
export const MAX_STOP_HOOK_CONTINUATIONS = 3;
|
|
17
23
|
export const ABORTED_CUSTOM_TYPE = "ama.aborted";
|
|
18
|
-
|
|
24
|
+
/** [W5-H2] 预算拦下请求时错误回复的前缀(limits.ts):判为最终失败,不重试、不回退。 */
|
|
25
|
+
export const LIMIT_ERROR_PREFIX = "limit_reached:";
|
|
26
|
+
/** [W5-H2] 扩展(limits)登记的 agent_settled warning:本周期收尾时取走。 */
|
|
27
|
+
const settleWarnings = new WeakMap();
|
|
28
|
+
export function noteSettleWarning(core, warning) {
|
|
29
|
+
if (!settleWarnings.has(core))
|
|
30
|
+
settleWarnings.set(core, warning);
|
|
31
|
+
}
|
|
32
|
+
function takeSettleWarning(core) {
|
|
33
|
+
const warning = settleWarnings.get(core);
|
|
34
|
+
settleWarnings.delete(core);
|
|
35
|
+
return warning;
|
|
36
|
+
}
|
|
37
|
+
export function decideAfterRun(deps, outcome, retryAttempt, overflowRecovered, fallbackUsed = false) {
|
|
19
38
|
if (outcome.stopReason === "aborted")
|
|
20
39
|
return { kind: "aborted" };
|
|
21
40
|
const last = outcome.lastAssistant;
|
|
@@ -25,6 +44,8 @@ export function decideAfterRun(deps, outcome, retryAttempt, overflowRecovered) {
|
|
|
25
44
|
if (!failedStop)
|
|
26
45
|
return { kind: "done" };
|
|
27
46
|
const errorMessage = last.errorMessage ?? (last.stopReason === "length" ? "output hit the token limit" : "error");
|
|
47
|
+
if (errorMessage.startsWith(LIMIT_ERROR_PREFIX))
|
|
48
|
+
return { kind: "failed", errorMessage };
|
|
28
49
|
const classifyOptions = deps.core.options.isContextOverflow === undefined
|
|
29
50
|
? {}
|
|
30
51
|
: { isContextOverflow: deps.core.options.isContextOverflow };
|
|
@@ -38,11 +59,75 @@ export function decideAfterRun(deps, outcome, retryAttempt, overflowRecovered) {
|
|
|
38
59
|
return recoverable ? { kind: "overflow" } : { kind: "failed", errorMessage };
|
|
39
60
|
}
|
|
40
61
|
const settings = deps.retry();
|
|
62
|
+
const canFallback = kind === "retryable" && !fallbackUsed && fallbackTarget(deps.core) !== undefined;
|
|
63
|
+
if (canFallback && OVERLOADED.test(errorMessage))
|
|
64
|
+
return { kind: "fallback", errorMessage };
|
|
41
65
|
if (kind === "retryable" && settings.enabled && retryAttempt < settings.maxRetries) {
|
|
42
66
|
return { kind: "retry", errorMessage };
|
|
43
67
|
}
|
|
68
|
+
if (canFallback)
|
|
69
|
+
return { kind: "fallback", errorMessage };
|
|
44
70
|
return { kind: "failed", errorMessage };
|
|
45
71
|
}
|
|
72
|
+
const OVERLOADED = /overloaded/i;
|
|
73
|
+
/** 配置了与当前模型不同、且能找到的回退模型时返回它的引用。 */
|
|
74
|
+
function fallbackTarget(core) {
|
|
75
|
+
const target = core.options.fallbackModel?.trim();
|
|
76
|
+
if (target === undefined || target === "")
|
|
77
|
+
return undefined;
|
|
78
|
+
if (core.setModel === undefined)
|
|
79
|
+
return undefined;
|
|
80
|
+
const current = core.model();
|
|
81
|
+
const refs = [formatModelRef(current), `${current.provider}/${current.id}`];
|
|
82
|
+
if (refs.includes(target))
|
|
83
|
+
return undefined;
|
|
84
|
+
// 找不到的回退模型等于没配:照常重试(启动时不校验,避免目录未加载时误报)
|
|
85
|
+
return core.options.providers.findModel(target).ok ? target : undefined;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* [W5-H2] 模型回退(§8.3 H7):经 `setModel` 切到回退模型(落 model_change、发 model_changed——缓存
|
|
89
|
+
* 未命中归因 `model_changed`,思考块按跨模型规则降级),发 `model_fallback{from, to, reason}`;
|
|
90
|
+
* 回退模型的第一条回复落盘后切回主模型(下一次请求仍用主模型)。返回「切回」函数;切换失败返回
|
|
91
|
+
* undefined(按最终失败处理)。
|
|
92
|
+
*/
|
|
93
|
+
async function switchToFallback(core, reason) {
|
|
94
|
+
const target = fallbackTarget(core);
|
|
95
|
+
const switcher = core;
|
|
96
|
+
if (target === undefined || switcher.setModel === undefined)
|
|
97
|
+
return undefined;
|
|
98
|
+
const primary = core.model();
|
|
99
|
+
try {
|
|
100
|
+
await switcher.setModel(target);
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
core.log("warn", `fallbackModel ${target} unavailable: ${String(error)}`);
|
|
104
|
+
return undefined;
|
|
105
|
+
}
|
|
106
|
+
core.emit({
|
|
107
|
+
type: "model_fallback",
|
|
108
|
+
from: modelRefOf(primary),
|
|
109
|
+
to: modelRefOf(core.model()),
|
|
110
|
+
reason,
|
|
111
|
+
});
|
|
112
|
+
let restored = false;
|
|
113
|
+
const restore = async () => {
|
|
114
|
+
if (restored)
|
|
115
|
+
return;
|
|
116
|
+
restored = true;
|
|
117
|
+
unsubscribe();
|
|
118
|
+
try {
|
|
119
|
+
await switcher.setModel?.(formatModelRef(primary));
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
core.log("warn", `cannot switch back to ${formatModelRef(primary)}: ${String(error)}`);
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
const unsubscribe = core.agent.subscribe(async (event) => {
|
|
126
|
+
if (event.type === "message_end" && event.message.role === "assistant")
|
|
127
|
+
await restore();
|
|
128
|
+
});
|
|
129
|
+
return restore;
|
|
130
|
+
}
|
|
46
131
|
/** 用 context_edit 把失败尝试(助手消息与其后补的结果)从上下文剔除。 */
|
|
47
132
|
export function excludeFailedAttempt(core, failed, reason) {
|
|
48
133
|
if (failed === undefined)
|
|
@@ -72,7 +157,30 @@ export function recordAbort(core) {
|
|
|
72
157
|
});
|
|
73
158
|
core.reloadMessages();
|
|
74
159
|
}
|
|
160
|
+
/**
|
|
161
|
+
* 会话周期:跑完一轮(到 agent_settled 与 onAgentSettled)后,若期间(Stop Hook、agent_settled 监听器、
|
|
162
|
+
* onAgentSettled 扩展)又有 steer / followUp 入队——宿主 `sendUser`、子 Agent 后台通知等在周期收尾
|
|
163
|
+
* 阶段调用时会话仍算忙,只能入队——就在同一周期里再开一轮投递它们([W5-H2],W5-G 发现的竞态)。
|
|
164
|
+
* abort 或已请求停止(Hook continue:false、预算到限)时不续投,消息留在队列。
|
|
165
|
+
*/
|
|
75
166
|
export async function runCycle(deps, prompts, signal) {
|
|
167
|
+
let next = prompts;
|
|
168
|
+
for (;;) {
|
|
169
|
+
await runSettledCycle(deps, next, signal);
|
|
170
|
+
if (signal.aborted || deps.stopRequested())
|
|
171
|
+
return;
|
|
172
|
+
const queued = drainQueued(deps.core);
|
|
173
|
+
if (queued.length === 0)
|
|
174
|
+
return;
|
|
175
|
+
next = queued;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/** 先取 steer(按其投递模式),没有再取 followUp。 */
|
|
179
|
+
function drainQueued(core) {
|
|
180
|
+
const steering = core.agent.steeringQueue.drain();
|
|
181
|
+
return steering.length > 0 ? steering : core.agent.followUpQueue.drain();
|
|
182
|
+
}
|
|
183
|
+
async function runSettledCycle(deps, prompts, signal) {
|
|
76
184
|
const { core, compaction } = deps;
|
|
77
185
|
let next = prompts;
|
|
78
186
|
let retryAttempt = 0;
|
|
@@ -80,6 +188,8 @@ export async function runCycle(deps, prompts, signal) {
|
|
|
80
188
|
let stopHooks = 0;
|
|
81
189
|
let warning;
|
|
82
190
|
let announced = false;
|
|
191
|
+
let fallbackUsed = false;
|
|
192
|
+
let restoreModel;
|
|
83
193
|
const endRetry = (success, finalError) => {
|
|
84
194
|
if (retryAttempt === 0)
|
|
85
195
|
return;
|
|
@@ -100,8 +210,8 @@ export async function runCycle(deps, prompts, signal) {
|
|
|
100
210
|
const outcome = await core.agent.run(next, {
|
|
101
211
|
signal,
|
|
102
212
|
onRunEnd: (result) => {
|
|
103
|
-
decision = decideAfterRun(deps, result, retryAttempt, overflowRecovered);
|
|
104
|
-
return decision.kind === "retry" || decision.kind === "overflow";
|
|
213
|
+
decision = decideAfterRun(deps, result, retryAttempt, overflowRecovered, fallbackUsed);
|
|
214
|
+
return (decision.kind === "retry" || decision.kind === "overflow" || decision.kind === "fallback");
|
|
105
215
|
},
|
|
106
216
|
});
|
|
107
217
|
next = undefined;
|
|
@@ -141,7 +251,21 @@ export async function runCycle(deps, prompts, signal) {
|
|
|
141
251
|
next = [];
|
|
142
252
|
continue;
|
|
143
253
|
}
|
|
254
|
+
if (current.kind === "fallback") {
|
|
255
|
+
fallbackUsed = true;
|
|
256
|
+
endRetry(false, current.errorMessage);
|
|
257
|
+
restoreModel = await switchToFallback(core, current.errorMessage);
|
|
258
|
+
if (restoreModel !== undefined) {
|
|
259
|
+
excludeFailedAttempt(core, outcome.lastAssistant, "retry");
|
|
260
|
+
next = [];
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
144
264
|
endRetry(current.kind === "done", current.kind === "failed" ? current.errorMessage : undefined);
|
|
265
|
+
// [W5-H2] harness 提前结束(重复调用检测):带 warning 停下,不跑 Stop Hook、不续投队列
|
|
266
|
+
const harnessStop = outcome.warning;
|
|
267
|
+
if (harnessStop !== undefined)
|
|
268
|
+
warning = harnessStop;
|
|
145
269
|
if (current.kind === "overflow") {
|
|
146
270
|
overflowRecovered = true;
|
|
147
271
|
excludeFailedAttempt(core, outcome.lastAssistant, "overflow");
|
|
@@ -156,19 +280,30 @@ export async function runCycle(deps, prompts, signal) {
|
|
|
156
280
|
}
|
|
157
281
|
warning = recovery.warning;
|
|
158
282
|
}
|
|
159
|
-
else if (current.kind === "failed") {
|
|
283
|
+
else if (current.kind === "failed" || current.kind === "fallback") {
|
|
160
284
|
warning = current.errorMessage;
|
|
161
285
|
void core.runHook("Notification", {
|
|
162
286
|
notification: { kind: "error", message: current.errorMessage },
|
|
163
287
|
});
|
|
164
288
|
}
|
|
165
|
-
if (current.kind === "failed"
|
|
289
|
+
if ((current.kind === "failed" || current.kind === "fallback") &&
|
|
290
|
+
core.agent.followUpQueue.hasItems()) {
|
|
166
291
|
next = core.agent.followUpQueue.drain();
|
|
167
292
|
continue;
|
|
168
293
|
}
|
|
294
|
+
// [W5-H2] run 收尾时(循环已不再取队列)入队的 steer / followUp:本周期接着投递,不滞留到下次提示
|
|
295
|
+
const queuedNow = () => harnessStop === undefined && !deps.stopRequested() && !signal.aborted
|
|
296
|
+
? drainQueued(core)
|
|
297
|
+
: [];
|
|
298
|
+
let queued = queuedNow();
|
|
299
|
+
if (queued.length > 0) {
|
|
300
|
+
next = queued;
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
169
303
|
core.emit({ type: "agent_before_settle" });
|
|
170
304
|
announced = true;
|
|
171
305
|
if (current.kind === "done" &&
|
|
306
|
+
harnessStop === undefined &&
|
|
172
307
|
!deps.stopRequested() &&
|
|
173
308
|
stopHooks < MAX_STOP_HOOK_CONTINUATIONS) {
|
|
174
309
|
const event = core.depth > 0 ? "SubagentStop" : "Stop";
|
|
@@ -183,16 +318,28 @@ export async function runCycle(deps, prompts, signal) {
|
|
|
183
318
|
continue;
|
|
184
319
|
}
|
|
185
320
|
}
|
|
321
|
+
queued = queuedNow(); // Stop Hook 期间入队的
|
|
322
|
+
if (queued.length > 0)
|
|
323
|
+
next = queued;
|
|
186
324
|
}
|
|
325
|
+
await restoreModel?.();
|
|
187
326
|
if (!announced)
|
|
188
327
|
core.emit({ type: "agent_before_settle" });
|
|
189
328
|
const settled = { type: "agent_settled" };
|
|
329
|
+
const noted = takeSettleWarning(core);
|
|
330
|
+
if (noted !== undefined && (warning === undefined || warning.startsWith(LIMIT_ERROR_PREFIX)))
|
|
331
|
+
warning = noted;
|
|
190
332
|
if (warning !== undefined)
|
|
191
333
|
settled.warning = warning;
|
|
192
334
|
core.emit(settled);
|
|
193
335
|
void core.runHook("Notification", {
|
|
194
336
|
notification: { kind: "settled", message: warning ?? "run finished" },
|
|
195
337
|
});
|
|
338
|
+
await deps.afterSettled?.();
|
|
339
|
+
}
|
|
340
|
+
/** `"user"` = 普通用户输入,不写 origin。 */
|
|
341
|
+
export function normalizeOrigin(origin) {
|
|
342
|
+
return origin === undefined || origin === "user" ? undefined : origin;
|
|
196
343
|
}
|
|
197
344
|
export function makeUserMessage(text, images, origin) {
|
|
198
345
|
const message = {
|
|
@@ -226,7 +373,8 @@ export async function runPrompt(deps, text, images, origin, signal) {
|
|
|
226
373
|
if (hook.updatedPrompt !== undefined)
|
|
227
374
|
prompt = hook.updatedPrompt;
|
|
228
375
|
}
|
|
229
|
-
const
|
|
376
|
+
const message = makeUserMessage(prompt, images, origin);
|
|
377
|
+
const prompts = [message];
|
|
230
378
|
if (hook?.additionalContext !== undefined && hook.additionalContext !== "") {
|
|
231
379
|
prompts.push({
|
|
232
380
|
role: "custom",
|
|
@@ -240,6 +388,9 @@ export async function runPrompt(deps, text, images, origin, signal) {
|
|
|
240
388
|
if (signal.aborted)
|
|
241
389
|
return "handled";
|
|
242
390
|
deps.syncSystem();
|
|
391
|
+
deps.beginTurn?.(message);
|
|
392
|
+
if (deps.beforePrompts !== undefined)
|
|
393
|
+
prompts.push(...(await deps.beforePrompts(prompts)));
|
|
243
394
|
core.emit({ type: "before_agent_start", prompt });
|
|
244
395
|
await runCycle(deps, prompts, signal);
|
|
245
396
|
return "started";
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 会话的可变设置:模型、思考级别、工具表与活动集、系统提示静态部分(从 session.ts 搬出,
|
|
3
|
+
* docs/wave5-plan.md §9「session.ts → session-settings.ts」)。[W5-C0]
|
|
4
|
+
*
|
|
5
|
+
* 纯搬迁:`setModel / setThinkingLevel / setPermissionMode / setActiveTools / addTool /
|
|
6
|
+
* updateSystem / announceStart / getTools` 的行为与事件顺序不变;`AgentSessionImpl` 以同名成员转发。
|
|
7
|
+
*/
|
|
8
|
+
import type { Model, ModelThinkingLevel, ProviderRegistryApi } from "../ai/types.js";
|
|
9
|
+
import type { PermissionMode } from "../permissions/types.js";
|
|
10
|
+
import type { ToolDefinition } from "../tools/types.js";
|
|
11
|
+
import type { StreamFn } from "./loop.js";
|
|
12
|
+
import type { AgentSessionOptions, SessionCore } from "./session-core.js";
|
|
13
|
+
import type { SystemPromptInput } from "./system-prompt.js";
|
|
14
|
+
/** 按模型的协议分派到已注册的实现(会话流的最内层)。 */
|
|
15
|
+
export declare function providerStream(providers: ProviderRegistryApi): StreamFn;
|
|
16
|
+
export type StaticSystemInput = Omit<SystemPromptInput, "tools" | "cwd">;
|
|
17
|
+
export interface SessionSettingsDeps {
|
|
18
|
+
/** 会话本身(构造完成后才会被调用)。 */
|
|
19
|
+
core: SessionCore;
|
|
20
|
+
assertUsable(): void;
|
|
21
|
+
/** 换模型后刷新压缩阈值。 */
|
|
22
|
+
onModelChanged(): void;
|
|
23
|
+
}
|
|
24
|
+
export declare class SessionSettings {
|
|
25
|
+
private readonly options;
|
|
26
|
+
private readonly deps;
|
|
27
|
+
model: Model;
|
|
28
|
+
thinking: ModelThinkingLevel;
|
|
29
|
+
systemInput: StaticSystemInput;
|
|
30
|
+
private readonly allTools;
|
|
31
|
+
private activeNames;
|
|
32
|
+
constructor(options: AgentSessionOptions, deps: SessionSettingsDeps);
|
|
33
|
+
activeTool(name: string): ToolDefinition | undefined;
|
|
34
|
+
tool(name: string): ToolDefinition | undefined;
|
|
35
|
+
activeToolNames(): string[];
|
|
36
|
+
/** 子会话 / fork 继承的活动集(同一数组引用,与搬迁前一致)。 */
|
|
37
|
+
activeNamesRef(): string[];
|
|
38
|
+
setModel(ref: string): Promise<void>;
|
|
39
|
+
setThinkingLevel(level: ModelThinkingLevel): void;
|
|
40
|
+
setPermissionMode(mode: PermissionMode): void;
|
|
41
|
+
setActiveTools(names: string[]): void;
|
|
42
|
+
/** 宿主 / SDK 在会话创建后追加工具(下次请求前以 system 补丁声明)。 */
|
|
43
|
+
addTool(tool: ToolDefinition, active?: boolean): void;
|
|
44
|
+
/** 更新系统提示的静态部分(SessionStart Hook 的 hookContext、宿主 instructions 等)。 */
|
|
45
|
+
updateSystem(patch: Partial<StaticSystemInput>): void;
|
|
46
|
+
getTools(): readonly ToolDefinition[];
|
|
47
|
+
/** 发 session_start(bootstrap / SDK 在会话就绪后调用一次)。 */
|
|
48
|
+
announceStart(reason: "startup" | "resume" | "new" | "fork"): void;
|
|
49
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 会话的可变设置:模型、思考级别、工具表与活动集、系统提示静态部分(从 session.ts 搬出,
|
|
3
|
+
* docs/wave5-plan.md §9「session.ts → session-settings.ts」)。[W5-C0]
|
|
4
|
+
*
|
|
5
|
+
* 纯搬迁:`setModel / setThinkingLevel / setPermissionMode / setActiveTools / addTool /
|
|
6
|
+
* updateSystem / announceStart / getTools` 的行为与事件顺序不变;`AgentSessionImpl` 以同名成员转发。
|
|
7
|
+
*/
|
|
8
|
+
import { AmaError } from "../errors.js";
|
|
9
|
+
import { appendModelChange, findModelOrThrow, sessionStartEvent } from "./session-sync.js";
|
|
10
|
+
/** 按模型的协议分派到已注册的实现(会话流的最内层)。 */
|
|
11
|
+
export function providerStream(providers) {
|
|
12
|
+
return (model, context, streamOptions) => {
|
|
13
|
+
const api = providers.getApi(model.api);
|
|
14
|
+
if (api === undefined) {
|
|
15
|
+
throw new AmaError("provider_not_found", `no implementation registered for api ${model.api}`);
|
|
16
|
+
}
|
|
17
|
+
return api.stream(model, context, streamOptions);
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export class SessionSettings {
|
|
21
|
+
options;
|
|
22
|
+
deps;
|
|
23
|
+
model;
|
|
24
|
+
thinking;
|
|
25
|
+
systemInput;
|
|
26
|
+
allTools = new Map();
|
|
27
|
+
activeNames;
|
|
28
|
+
constructor(options, deps) {
|
|
29
|
+
this.options = options;
|
|
30
|
+
this.deps = deps;
|
|
31
|
+
this.model = options.model;
|
|
32
|
+
this.thinking = options.thinkingLevel ?? "off";
|
|
33
|
+
for (const tool of options.tools ?? [])
|
|
34
|
+
this.allTools.set(tool.name, tool);
|
|
35
|
+
this.activeNames = [...(options.activeTools ?? this.allTools.keys())].filter((name) => this.allTools.has(name));
|
|
36
|
+
this.systemInput = { ...(options.system ?? {}) };
|
|
37
|
+
}
|
|
38
|
+
activeTool(name) {
|
|
39
|
+
return this.activeNames.includes(name) ? this.allTools.get(name) : undefined;
|
|
40
|
+
}
|
|
41
|
+
tool(name) {
|
|
42
|
+
return this.allTools.get(name);
|
|
43
|
+
}
|
|
44
|
+
activeToolNames() {
|
|
45
|
+
return [...this.activeNames];
|
|
46
|
+
}
|
|
47
|
+
/** 子会话 / fork 继承的活动集(同一数组引用,与搬迁前一致)。 */
|
|
48
|
+
activeNamesRef() {
|
|
49
|
+
return this.activeNames;
|
|
50
|
+
}
|
|
51
|
+
async setModel(ref) {
|
|
52
|
+
this.deps.assertUsable();
|
|
53
|
+
this.model = findModelOrThrow(this.options.providers, ref);
|
|
54
|
+
this.deps.onModelChanged();
|
|
55
|
+
const core = this.deps.core;
|
|
56
|
+
core.emit({ type: "model_changed", model: appendModelChange(core, this.model) });
|
|
57
|
+
}
|
|
58
|
+
setThinkingLevel(level) {
|
|
59
|
+
this.thinking = level;
|
|
60
|
+
this.deps.core.appendEntry({ type: "thinking_level_change", thinkingLevel: level });
|
|
61
|
+
this.deps.core.emit({ type: "thinking_level_changed", level });
|
|
62
|
+
}
|
|
63
|
+
setPermissionMode(mode) {
|
|
64
|
+
this.options.permission?.setMode(mode);
|
|
65
|
+
this.deps.core.emit({ type: "permission_mode_changed", mode });
|
|
66
|
+
}
|
|
67
|
+
setActiveTools(names) {
|
|
68
|
+
const unknown = names.filter((name) => !this.allTools.has(name));
|
|
69
|
+
if (unknown.length > 0)
|
|
70
|
+
throw new AmaError("tool_not_found", `unknown tools: ${unknown.join(", ")}`);
|
|
71
|
+
this.activeNames = [...new Set(names)];
|
|
72
|
+
}
|
|
73
|
+
/** 宿主 / SDK 在会话创建后追加工具(下次请求前以 system 补丁声明)。 */
|
|
74
|
+
addTool(tool, active = true) {
|
|
75
|
+
if (this.allTools.has(tool.name))
|
|
76
|
+
throw new AmaError("tool_exists", `tool ${tool.name} already exists`);
|
|
77
|
+
this.allTools.set(tool.name, tool);
|
|
78
|
+
if (active)
|
|
79
|
+
this.activeNames.push(tool.name);
|
|
80
|
+
}
|
|
81
|
+
/** 更新系统提示的静态部分(SessionStart Hook 的 hookContext、宿主 instructions 等)。 */
|
|
82
|
+
updateSystem(patch) {
|
|
83
|
+
this.systemInput = { ...this.systemInput, ...patch };
|
|
84
|
+
}
|
|
85
|
+
getTools() {
|
|
86
|
+
return this.activeNames
|
|
87
|
+
.map((name) => this.allTools.get(name))
|
|
88
|
+
.filter((tool) => tool !== undefined)
|
|
89
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
90
|
+
}
|
|
91
|
+
/** 发 session_start(bootstrap / SDK 在会话就绪后调用一次)。 */
|
|
92
|
+
announceStart(reason) {
|
|
93
|
+
this.deps.core.emit(sessionStartEvent(this.deps.core.manager, reason));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -1,39 +1,43 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* 子 Agent(设计 §5.2 task、D14):`ToolContext.spawnSubagent`
|
|
2
|
+
* 子 Agent(设计 §5.2 task、D14;第五波 docs/wave5-plan.md §7,D22–D24):`ToolContext.spawnSubagent`
|
|
3
|
+
* 的实现与 ama 自己的 runner(`AmaRunner`)。[B2 → W5-G]
|
|
3
4
|
*
|
|
4
|
-
* -
|
|
5
|
-
*
|
|
6
|
-
* -
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
5
|
+
* - `runSubagent`:交给会话的任务注册表(subagent-registry.ts)——类型解析、并发池、前台 / 后台、
|
|
6
|
+
* 续聊、结果上限、事件都在那里;这里只提供「起一个 ama 子会话」的 runner。
|
|
7
|
+
* - 子会话:同进程新会话,独立 JSONL(头的 parentSession 指回父文件;父为内存会话则子也在内存),
|
|
8
|
+
* 首条 `custom{ama.task}` 记父 toolCallId 与 taskId;深度 ≤ 1(depth 1、无 spawnSubagent)。
|
|
9
|
+
* - **工具表与父字节一致**(D23):活动集 = 父活动集,`task` / `task_ctl` 保留在表里、运行时按深度
|
|
10
|
+
* 拒绝,子会话首请求能命中父的 tools + system 前缀;角色说明进系统提示末位 `role` 节。只有类型
|
|
11
|
+
* 声明了 `tools` / `disallowed-tools`(或调用参数给了 `tools`)时工具表才不同。
|
|
12
|
+
* - 只读类型(`permission-mode: plan`):子会话用一条 plan 模式的权限管线(规则同父),ask 一律转
|
|
13
|
+
* deny——写类工具与识别不了的 bash 被拒且不弹审批;`inherit` 共用父的管线(不会比父宽)。
|
|
14
|
+
* - 轮数耗尽且最后停在工具结果上:以 `toolChoice:"none"` 再跑一轮要最终报告,状态 `max_turns`。
|
|
15
|
+
* - broker 包一层,请求带 `context{depth, parentToolCallId, taskId}`,审批事件转发到父会话;
|
|
16
|
+
* [RW-B] 父的检查点钩子(worktree 里运行时不记);[W3-C1b] 子会话命中与重计费汇总进父。
|
|
12
17
|
*/
|
|
18
|
+
import type { CheckpointHooks } from "../checkpoints/types.js";
|
|
19
|
+
import type { PermissionPipelineApi } from "../permissions/types.js";
|
|
13
20
|
import { SessionManager } from "../session/manager.js";
|
|
14
|
-
import type {
|
|
21
|
+
import type { AgentMessage } from "../session/types.js";
|
|
22
|
+
import type { SubagentRequest, SubagentResult, SubagentRunner } from "../tools/types.js";
|
|
15
23
|
import type { AgentSessionOptions } from "./session-core.js";
|
|
24
|
+
import { DEFAULT_SUBAGENT_CONCURRENCY, SubagentPool, TASK_CUSTOM_TYPE, type AmaRunnerSpec, type RegistryHost } from "./subagent-registry.js";
|
|
16
25
|
import type { SessionEvent, SessionStats } from "./types.js";
|
|
17
|
-
export
|
|
26
|
+
export { DEFAULT_SUBAGENT_CONCURRENCY, SubagentPool, TASK_CUSTOM_TYPE };
|
|
18
27
|
export declare const DEFAULT_SUBAGENT_MAX_TURNS = 30;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
export declare
|
|
22
|
-
|
|
23
|
-
private running;
|
|
24
|
-
private readonly waiters;
|
|
25
|
-
constructor(limit: number);
|
|
26
|
-
acquire(signal: AbortSignal): Promise<void>;
|
|
27
|
-
release(): void;
|
|
28
|
-
}
|
|
29
|
-
export interface SubagentParent {
|
|
28
|
+
/** 子会话里保留在工具表、运行时拒绝的名字(深度 ≤ 1)。 */
|
|
29
|
+
export declare const PARENT_ONLY_TOOLS: readonly string[];
|
|
30
|
+
export declare const FINAL_REPORT_PROMPT: string;
|
|
31
|
+
export interface SubagentParent extends RegistryHost {
|
|
30
32
|
readonly options: AgentSessionOptions;
|
|
31
33
|
readonly manager: SessionManager;
|
|
32
34
|
readonly cwd: string;
|
|
33
35
|
readonly depth: number;
|
|
34
36
|
childBase(): Pick<AgentSessionOptions, "model" | "thinkingLevel" | "activeTools" | "system">;
|
|
35
37
|
/** 子会话的审批事件转发给父会话的订阅者(RPC 客户端 / TUI 据此作答)。 */
|
|
36
|
-
emit
|
|
38
|
+
emit(event: SessionEvent): void;
|
|
39
|
+
/** [RW-B] 父会话的检查点钩子:子会话的编辑记到父会话当前回合。 */
|
|
40
|
+
checkpointHooks?(): CheckpointHooks | undefined;
|
|
37
41
|
/** [W3-C1b] 父会话的缓存控制器:汇总子会话的命中与重计费。 */
|
|
38
42
|
readonly cache?: {
|
|
39
43
|
addSubagent(tokens: {
|
|
@@ -44,6 +48,7 @@ export interface SubagentParent {
|
|
|
44
48
|
}
|
|
45
49
|
export interface ChildSession {
|
|
46
50
|
readonly manager: SessionManager;
|
|
51
|
+
readonly messages: readonly AgentMessage[];
|
|
47
52
|
prompt(text: string): Promise<unknown>;
|
|
48
53
|
abort(): Promise<void>;
|
|
49
54
|
subscribe(listener: (event: SessionEvent) => void): () => void;
|
|
@@ -51,4 +56,11 @@ export interface ChildSession {
|
|
|
51
56
|
getLastAssistantText(): string | null;
|
|
52
57
|
dispose(): Promise<void>;
|
|
53
58
|
}
|
|
54
|
-
|
|
59
|
+
/**
|
|
60
|
+
* 只读子会话的权限管线:plan 模式、规则同父;ask 一律转 deny(只读类型不弹审批)。
|
|
61
|
+
* 父管线不是 `PermissionPipeline`(宿主 / SDK 自带实现)时退化为「只放行 read 类」。
|
|
62
|
+
*/
|
|
63
|
+
export declare function readOnlyPermission(parent: PermissionPipelineApi | undefined, cwd: string): PermissionPipelineApi;
|
|
64
|
+
export declare function runSubagent(parent: SubagentParent, request: SubagentRequest, _pool: SubagentPool, createChild: (options: AgentSessionOptions) => ChildSession): Promise<SubagentResult>;
|
|
65
|
+
/** ama 自己的子会话 runner(同进程)。 */
|
|
66
|
+
export declare function createAmaRunner(parent: SubagentParent, spec: AmaRunnerSpec, createChild: (options: AgentSessionOptions) => ChildSession): SubagentRunner;
|