@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
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 黄金记录用的假 ACP Agent(docs/wave5-plan.md §5.1、§5.7)。[W5-E]
|
|
3
|
+
*
|
|
4
|
+
* 零依赖、不联网、不碰文件系统;行为由提示文本里的标记决定,供 ama 自己的测试与 Armadra 复用
|
|
5
|
+
* (`@armadra/agent/acp` 导出 {@link runFakeAcpAgent} 与可执行入口路径):
|
|
6
|
+
*
|
|
7
|
+
* | 提示里含 | 行为 |
|
|
8
|
+
* | ---------------- | --------------------------------------------------------------------------------- |
|
|
9
|
+
* | (无标记) | `agent_message_chunk` 回 `echo: <文本>`,`usage_update`,`end_turn` |
|
|
10
|
+
* | `[permission]` | `tool_call`(edit, pending) → `session/request_permission`(四个选项)→ 按结果 |
|
|
11
|
+
* | | `tool_call_update` completed / failed;客户端回 cancelled 时本回合 `cancelled` |
|
|
12
|
+
* | `[slow]` | 一直等,直到 `session/cancel` → `cancelled` |
|
|
13
|
+
* | `[plan]` | 先发 `plan`(两条)再回文本 |
|
|
14
|
+
* | `[think]` | 先发 `agent_thought_chunk` |
|
|
15
|
+
* | `[refuse]` | `refusal` |
|
|
16
|
+
*
|
|
17
|
+
* 会话:`session/new` 发 `fake-<n>`;`session/resume` / `session/load` 接受任何 `fake-` 开头的 id
|
|
18
|
+
* (load 先回放一条用户消息与一条回复);`session/list` 列本进程建过的会话。
|
|
19
|
+
*/
|
|
20
|
+
import { ACP_METHODS, ACP_PROTOCOL_VERSION, RPC_ERRORS } from "../types.js";
|
|
21
|
+
import { JsonRpcPeer, RpcError } from "../../jsonrpc.js";
|
|
22
|
+
const MODES = [
|
|
23
|
+
{ id: "default", name: "Default" },
|
|
24
|
+
{ id: "plan", name: "Plan" },
|
|
25
|
+
];
|
|
26
|
+
function textOf(blocks) {
|
|
27
|
+
return blocks.map((b) => (b.type === "text" ? b.text : `[${b.type}]`)).join("");
|
|
28
|
+
}
|
|
29
|
+
function waitAbort(signal) {
|
|
30
|
+
return new Promise((resolve) => {
|
|
31
|
+
if (signal.aborted)
|
|
32
|
+
return resolve();
|
|
33
|
+
signal.addEventListener("abort", () => resolve(), { once: true });
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
/** 在给定流上跑假 Agent;输入流结束时 resolve。 */
|
|
37
|
+
export function runFakeAcpAgent(input, output, options = {}) {
|
|
38
|
+
const sessions = new Map();
|
|
39
|
+
let counter = 0;
|
|
40
|
+
const update = (sessionId, value) => peer.notify(ACP_METHODS.sessionUpdate, { sessionId, update: value });
|
|
41
|
+
const session = (id) => {
|
|
42
|
+
const found = typeof id === "string" ? sessions.get(id) : undefined;
|
|
43
|
+
if (found === undefined)
|
|
44
|
+
throw new RpcError(RPC_ERRORS.resourceNotFound, `unknown session: ${String(id)}`);
|
|
45
|
+
return found;
|
|
46
|
+
};
|
|
47
|
+
const open = (id, cwd) => {
|
|
48
|
+
const created = { id, cwd, mode: "default", turns: 0 };
|
|
49
|
+
sessions.set(id, created);
|
|
50
|
+
return created;
|
|
51
|
+
};
|
|
52
|
+
const prompt = async (params) => {
|
|
53
|
+
const s = session(params.sessionId);
|
|
54
|
+
const turn = new AbortController();
|
|
55
|
+
s.turn = turn;
|
|
56
|
+
s.turns += 1;
|
|
57
|
+
const text = textOf(params.prompt);
|
|
58
|
+
const usage = { inputTokens: 10 * s.turns, outputTokens: 5, totalTokens: 10 * s.turns + 5 };
|
|
59
|
+
const done = (stopReason) => {
|
|
60
|
+
s.turn = undefined;
|
|
61
|
+
return { stopReason, usage };
|
|
62
|
+
};
|
|
63
|
+
if (text.includes("[think]"))
|
|
64
|
+
await update(s.id, {
|
|
65
|
+
sessionUpdate: "agent_thought_chunk",
|
|
66
|
+
content: { type: "text", text: "thinking…" },
|
|
67
|
+
});
|
|
68
|
+
if (text.includes("[plan]"))
|
|
69
|
+
await update(s.id, {
|
|
70
|
+
sessionUpdate: "plan",
|
|
71
|
+
entries: [
|
|
72
|
+
{ content: "read", priority: "high", status: "completed" },
|
|
73
|
+
{ content: "write", priority: "medium", status: "pending" },
|
|
74
|
+
],
|
|
75
|
+
});
|
|
76
|
+
if (text.includes("[refuse]"))
|
|
77
|
+
return done("refusal");
|
|
78
|
+
if (text.includes("[slow]")) {
|
|
79
|
+
await waitAbort(turn.signal);
|
|
80
|
+
return done("cancelled");
|
|
81
|
+
}
|
|
82
|
+
if (text.includes("[permission]")) {
|
|
83
|
+
const toolCallId = `call-${s.turns}`;
|
|
84
|
+
await update(s.id, {
|
|
85
|
+
sessionUpdate: "tool_call",
|
|
86
|
+
toolCallId,
|
|
87
|
+
title: "Write note.txt",
|
|
88
|
+
kind: "edit",
|
|
89
|
+
status: "pending",
|
|
90
|
+
locations: [{ path: `${s.cwd}/note.txt` }],
|
|
91
|
+
rawInput: { path: "note.txt", content: "hi" },
|
|
92
|
+
});
|
|
93
|
+
let answer;
|
|
94
|
+
try {
|
|
95
|
+
answer = await peer.request(ACP_METHODS.requestPermission, {
|
|
96
|
+
sessionId: s.id,
|
|
97
|
+
toolCall: { toolCallId, title: "Write note.txt", kind: "edit", status: "pending" },
|
|
98
|
+
options: [
|
|
99
|
+
{ optionId: "allow", name: "Allow", kind: "allow_once" },
|
|
100
|
+
{ optionId: "always", name: "Always allow", kind: "allow_always" },
|
|
101
|
+
{ optionId: "reject", name: "Reject", kind: "reject_once" },
|
|
102
|
+
{ optionId: "never", name: "Never", kind: "reject_always" },
|
|
103
|
+
],
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return done("cancelled");
|
|
108
|
+
}
|
|
109
|
+
if (answer.outcome.outcome === "cancelled" || turn.signal.aborted) {
|
|
110
|
+
await update(s.id, { sessionUpdate: "tool_call_update", toolCallId, status: "failed" });
|
|
111
|
+
return done("cancelled");
|
|
112
|
+
}
|
|
113
|
+
const allowed = answer.outcome.optionId === "allow" || answer.outcome.optionId === "always";
|
|
114
|
+
await update(s.id, {
|
|
115
|
+
sessionUpdate: "tool_call_update",
|
|
116
|
+
toolCallId,
|
|
117
|
+
status: allowed ? "completed" : "failed",
|
|
118
|
+
});
|
|
119
|
+
await update(s.id, {
|
|
120
|
+
sessionUpdate: "agent_message_chunk",
|
|
121
|
+
content: { type: "text", text: allowed ? "wrote note.txt" : "write rejected" },
|
|
122
|
+
});
|
|
123
|
+
await update(s.id, { sessionUpdate: "usage_update", used: usage.totalTokens, size: 1000 });
|
|
124
|
+
return done("end_turn");
|
|
125
|
+
}
|
|
126
|
+
await update(s.id, {
|
|
127
|
+
sessionUpdate: "agent_message_chunk",
|
|
128
|
+
content: { type: "text", text: `echo: ${text}` },
|
|
129
|
+
});
|
|
130
|
+
await update(s.id, {
|
|
131
|
+
sessionUpdate: "usage_update",
|
|
132
|
+
used: usage.totalTokens,
|
|
133
|
+
size: 1000,
|
|
134
|
+
cost: { amount: 0.001 * s.turns, currency: "USD" },
|
|
135
|
+
});
|
|
136
|
+
return done("end_turn");
|
|
137
|
+
};
|
|
138
|
+
const peer = new JsonRpcPeer({
|
|
139
|
+
input,
|
|
140
|
+
output,
|
|
141
|
+
async onRequest(method, raw) {
|
|
142
|
+
const params = (raw ?? {});
|
|
143
|
+
switch (method) {
|
|
144
|
+
case ACP_METHODS.initialize:
|
|
145
|
+
return {
|
|
146
|
+
protocolVersion: ACP_PROTOCOL_VERSION,
|
|
147
|
+
agentCapabilities: options.minimal
|
|
148
|
+
? { promptCapabilities: { image: false } }
|
|
149
|
+
: {
|
|
150
|
+
loadSession: true,
|
|
151
|
+
promptCapabilities: { image: false, embeddedContext: false },
|
|
152
|
+
sessionCapabilities: { list: {}, resume: {}, close: {} },
|
|
153
|
+
},
|
|
154
|
+
authMethods: [],
|
|
155
|
+
agentInfo: { name: options.name ?? "fake-acp-agent", version: "1.0.0" },
|
|
156
|
+
};
|
|
157
|
+
case ACP_METHODS.sessionNew: {
|
|
158
|
+
counter += 1;
|
|
159
|
+
const s = open(`fake-${counter}`, String(params["cwd"] ?? ""));
|
|
160
|
+
if (options.minimal)
|
|
161
|
+
return { sessionId: s.id };
|
|
162
|
+
return { sessionId: s.id, modes: { currentModeId: s.mode, availableModes: MODES } };
|
|
163
|
+
}
|
|
164
|
+
case ACP_METHODS.sessionResume:
|
|
165
|
+
case ACP_METHODS.sessionLoad: {
|
|
166
|
+
const id = String(params["sessionId"] ?? "");
|
|
167
|
+
if (options.minimal || !id.startsWith("fake-"))
|
|
168
|
+
throw new RpcError(RPC_ERRORS.resourceNotFound, `unknown session: ${id}`);
|
|
169
|
+
const s = sessions.get(id) ?? open(id, String(params["cwd"] ?? ""));
|
|
170
|
+
if (method === ACP_METHODS.sessionLoad) {
|
|
171
|
+
await update(id, {
|
|
172
|
+
sessionUpdate: "user_message_chunk",
|
|
173
|
+
content: { type: "text", text: "earlier" },
|
|
174
|
+
});
|
|
175
|
+
await update(id, {
|
|
176
|
+
sessionUpdate: "agent_message_chunk",
|
|
177
|
+
content: { type: "text", text: "echo: earlier" },
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
return { modes: { currentModeId: s.mode, availableModes: MODES } };
|
|
181
|
+
}
|
|
182
|
+
case ACP_METHODS.sessionList:
|
|
183
|
+
return {
|
|
184
|
+
sessions: [...sessions.values()].map((s) => ({ sessionId: s.id, cwd: s.cwd })),
|
|
185
|
+
};
|
|
186
|
+
case ACP_METHODS.sessionClose:
|
|
187
|
+
session(params["sessionId"]).turn?.abort();
|
|
188
|
+
sessions.delete(String(params["sessionId"]));
|
|
189
|
+
return {};
|
|
190
|
+
case ACP_METHODS.sessionSetMode: {
|
|
191
|
+
const s = session(params["sessionId"]);
|
|
192
|
+
s.mode = String(params["modeId"]);
|
|
193
|
+
await update(s.id, { sessionUpdate: "current_mode_update", currentModeId: s.mode });
|
|
194
|
+
return {};
|
|
195
|
+
}
|
|
196
|
+
case ACP_METHODS.sessionPrompt:
|
|
197
|
+
return prompt(raw);
|
|
198
|
+
default:
|
|
199
|
+
throw new RpcError(RPC_ERRORS.methodNotFound, `method not found: ${method}`);
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
onNotification(method, raw) {
|
|
203
|
+
if (method !== ACP_METHODS.sessionCancel)
|
|
204
|
+
return;
|
|
205
|
+
const id = raw?.sessionId;
|
|
206
|
+
if (typeof id === "string")
|
|
207
|
+
sessions.get(id)?.turn?.abort();
|
|
208
|
+
},
|
|
209
|
+
});
|
|
210
|
+
return peer.closed;
|
|
211
|
+
}
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ACP(Agent Client Protocol)v1 的子集类型(docs/wave5-plan.md §5.1,D14)。[W5-E]
|
|
3
|
+
*
|
|
4
|
+
* 手写、零依赖;只收 ama 作为客户端(驱动外部 Agent)与服务端(`ama --mode acp`)两侧用到的部分:
|
|
5
|
+
* `initialize`、`session/new|load|resume|list|close`、`session/prompt|cancel|set_mode`、
|
|
6
|
+
* `session/update`(含 `usage_update`)、`session/request_permission`。字段名与规范一致(camelCase),
|
|
7
|
+
* 未知字段一律保留不报错;`_meta` 不解释。
|
|
8
|
+
*
|
|
9
|
+
* 不声明 `fs` / `terminal` 客户端能力(与 Armadra Q5 一致):外部 Agent 自己读写、自己跑命令,
|
|
10
|
+
* 用它自己的权限策略;它要问人的才经 `session/request_permission` 回到 ama。
|
|
11
|
+
*/
|
|
12
|
+
import type { AcpToolKind } from "../types.js";
|
|
13
|
+
export declare const ACP_PROTOCOL_VERSION: 1;
|
|
14
|
+
/** 方法名(客户端 → Agent 的请求 / 通知,Agent → 客户端的请求 / 通知)。 */
|
|
15
|
+
export declare const ACP_METHODS: {
|
|
16
|
+
readonly initialize: "initialize";
|
|
17
|
+
readonly sessionNew: "session/new";
|
|
18
|
+
readonly sessionLoad: "session/load";
|
|
19
|
+
readonly sessionResume: "session/resume";
|
|
20
|
+
readonly sessionList: "session/list";
|
|
21
|
+
readonly sessionClose: "session/close";
|
|
22
|
+
readonly sessionPrompt: "session/prompt";
|
|
23
|
+
readonly sessionCancel: "session/cancel";
|
|
24
|
+
readonly sessionSetMode: "session/set_mode";
|
|
25
|
+
readonly sessionUpdate: "session/update";
|
|
26
|
+
readonly requestPermission: "session/request_permission";
|
|
27
|
+
};
|
|
28
|
+
/** JSON-RPC 错误码(规范沿用 JSON-RPC 2.0;`-32000` 为 ACP 的 auth_required)。 */
|
|
29
|
+
export declare const RPC_ERRORS: {
|
|
30
|
+
readonly parseError: -32700;
|
|
31
|
+
readonly invalidRequest: -32600;
|
|
32
|
+
readonly methodNotFound: -32601;
|
|
33
|
+
readonly invalidParams: -32602;
|
|
34
|
+
readonly internalError: -32603;
|
|
35
|
+
readonly authRequired: -32000;
|
|
36
|
+
readonly resourceNotFound: -32002;
|
|
37
|
+
};
|
|
38
|
+
export interface AcpTextContent {
|
|
39
|
+
type: "text";
|
|
40
|
+
text: string;
|
|
41
|
+
}
|
|
42
|
+
export interface AcpImageContent {
|
|
43
|
+
type: "image";
|
|
44
|
+
/** base64。 */
|
|
45
|
+
data: string;
|
|
46
|
+
mimeType: string;
|
|
47
|
+
uri?: string;
|
|
48
|
+
}
|
|
49
|
+
export interface AcpResourceLink {
|
|
50
|
+
type: "resource_link";
|
|
51
|
+
uri: string;
|
|
52
|
+
name: string;
|
|
53
|
+
mimeType?: string;
|
|
54
|
+
title?: string;
|
|
55
|
+
description?: string;
|
|
56
|
+
size?: number;
|
|
57
|
+
}
|
|
58
|
+
export interface AcpEmbeddedResource {
|
|
59
|
+
type: "resource";
|
|
60
|
+
resource: {
|
|
61
|
+
uri: string;
|
|
62
|
+
text?: string;
|
|
63
|
+
blob?: string;
|
|
64
|
+
mimeType?: string;
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
export type AcpContentBlock = AcpTextContent | AcpImageContent | AcpResourceLink | AcpEmbeddedResource;
|
|
68
|
+
export interface AcpImplementationInfo {
|
|
69
|
+
name: string;
|
|
70
|
+
title?: string;
|
|
71
|
+
version: string;
|
|
72
|
+
}
|
|
73
|
+
export interface AcpClientCapabilities {
|
|
74
|
+
fs?: {
|
|
75
|
+
readTextFile?: boolean;
|
|
76
|
+
writeTextFile?: boolean;
|
|
77
|
+
};
|
|
78
|
+
terminal?: boolean;
|
|
79
|
+
}
|
|
80
|
+
export interface AcpInitializeParams {
|
|
81
|
+
protocolVersion: number;
|
|
82
|
+
clientCapabilities: AcpClientCapabilities;
|
|
83
|
+
clientInfo?: AcpImplementationInfo;
|
|
84
|
+
}
|
|
85
|
+
export interface AcpAgentCapabilities {
|
|
86
|
+
loadSession?: boolean;
|
|
87
|
+
promptCapabilities?: {
|
|
88
|
+
image?: boolean;
|
|
89
|
+
audio?: boolean;
|
|
90
|
+
embeddedContext?: boolean;
|
|
91
|
+
};
|
|
92
|
+
mcpCapabilities?: {
|
|
93
|
+
http?: boolean;
|
|
94
|
+
sse?: boolean;
|
|
95
|
+
};
|
|
96
|
+
/** 2026 年稳定进 v1 的会话能力(存在即支持)。 */
|
|
97
|
+
sessionCapabilities?: {
|
|
98
|
+
list?: Record<string, unknown> | null;
|
|
99
|
+
resume?: Record<string, unknown> | null;
|
|
100
|
+
close?: Record<string, unknown> | null;
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
export interface AcpAuthMethod {
|
|
104
|
+
id: string;
|
|
105
|
+
name: string;
|
|
106
|
+
description?: string | null;
|
|
107
|
+
}
|
|
108
|
+
export interface AcpInitializeResult {
|
|
109
|
+
protocolVersion: number;
|
|
110
|
+
agentCapabilities?: AcpAgentCapabilities;
|
|
111
|
+
authMethods?: AcpAuthMethod[];
|
|
112
|
+
agentInfo?: AcpImplementationInfo;
|
|
113
|
+
}
|
|
114
|
+
/** ama 不向外部 Agent 传 MCP 服务器(Skills 不做 MCP),总是空数组。 */
|
|
115
|
+
export type AcpMcpServer = Record<string, unknown>;
|
|
116
|
+
export interface AcpSessionMode {
|
|
117
|
+
id: string;
|
|
118
|
+
name: string;
|
|
119
|
+
description?: string | null;
|
|
120
|
+
}
|
|
121
|
+
export interface AcpSessionModeState {
|
|
122
|
+
currentModeId: string;
|
|
123
|
+
availableModes: AcpSessionMode[];
|
|
124
|
+
}
|
|
125
|
+
export interface AcpNewSessionParams {
|
|
126
|
+
cwd: string;
|
|
127
|
+
mcpServers: AcpMcpServer[];
|
|
128
|
+
}
|
|
129
|
+
export interface AcpNewSessionResult {
|
|
130
|
+
sessionId: string;
|
|
131
|
+
modes?: AcpSessionModeState | null;
|
|
132
|
+
}
|
|
133
|
+
export interface AcpLoadSessionParams {
|
|
134
|
+
sessionId: string;
|
|
135
|
+
cwd: string;
|
|
136
|
+
mcpServers: AcpMcpServer[];
|
|
137
|
+
}
|
|
138
|
+
export interface AcpLoadSessionResult {
|
|
139
|
+
modes?: AcpSessionModeState | null;
|
|
140
|
+
}
|
|
141
|
+
export type AcpResumeSessionParams = AcpLoadSessionParams;
|
|
142
|
+
export type AcpResumeSessionResult = AcpLoadSessionResult;
|
|
143
|
+
export interface AcpListSessionsParams {
|
|
144
|
+
cwd?: string;
|
|
145
|
+
cursor?: string;
|
|
146
|
+
}
|
|
147
|
+
export interface AcpSessionInfo {
|
|
148
|
+
sessionId: string;
|
|
149
|
+
cwd: string;
|
|
150
|
+
title?: string | null;
|
|
151
|
+
updatedAt?: string | null;
|
|
152
|
+
}
|
|
153
|
+
export interface AcpListSessionsResult {
|
|
154
|
+
sessions: AcpSessionInfo[];
|
|
155
|
+
nextCursor?: string | null;
|
|
156
|
+
}
|
|
157
|
+
export interface AcpCloseSessionParams {
|
|
158
|
+
sessionId: string;
|
|
159
|
+
}
|
|
160
|
+
export interface AcpSetModeParams {
|
|
161
|
+
sessionId: string;
|
|
162
|
+
modeId: string;
|
|
163
|
+
}
|
|
164
|
+
export type AcpStopReason = "end_turn" | "max_tokens" | "max_turn_requests" | "refusal" | "cancelled";
|
|
165
|
+
export interface AcpPromptParams {
|
|
166
|
+
sessionId: string;
|
|
167
|
+
prompt: AcpContentBlock[];
|
|
168
|
+
}
|
|
169
|
+
/** 本回合用量(可选字段,按 2026-06 稳定的 usage 提案)。 */
|
|
170
|
+
export interface AcpPromptUsage {
|
|
171
|
+
totalTokens?: number;
|
|
172
|
+
inputTokens?: number;
|
|
173
|
+
outputTokens?: number;
|
|
174
|
+
thoughtTokens?: number;
|
|
175
|
+
cachedReadTokens?: number;
|
|
176
|
+
cachedWriteTokens?: number;
|
|
177
|
+
}
|
|
178
|
+
export interface AcpPromptResult {
|
|
179
|
+
stopReason: AcpStopReason;
|
|
180
|
+
usage?: AcpPromptUsage | null;
|
|
181
|
+
}
|
|
182
|
+
export interface AcpCancelParams {
|
|
183
|
+
sessionId: string;
|
|
184
|
+
}
|
|
185
|
+
export type { AcpToolKind };
|
|
186
|
+
export type AcpToolCallStatus = "pending" | "in_progress" | "completed" | "failed";
|
|
187
|
+
export interface AcpToolCallLocation {
|
|
188
|
+
path: string;
|
|
189
|
+
line?: number | null;
|
|
190
|
+
}
|
|
191
|
+
export type AcpToolCallContent = {
|
|
192
|
+
type: "content";
|
|
193
|
+
content: AcpContentBlock;
|
|
194
|
+
} | {
|
|
195
|
+
type: "diff";
|
|
196
|
+
path: string;
|
|
197
|
+
oldText?: string | null;
|
|
198
|
+
newText: string;
|
|
199
|
+
} | {
|
|
200
|
+
type: "terminal";
|
|
201
|
+
terminalId: string;
|
|
202
|
+
};
|
|
203
|
+
export interface AcpToolCall {
|
|
204
|
+
toolCallId: string;
|
|
205
|
+
title: string;
|
|
206
|
+
kind?: AcpToolKind;
|
|
207
|
+
status?: AcpToolCallStatus;
|
|
208
|
+
content?: AcpToolCallContent[];
|
|
209
|
+
locations?: AcpToolCallLocation[];
|
|
210
|
+
rawInput?: unknown;
|
|
211
|
+
rawOutput?: unknown;
|
|
212
|
+
}
|
|
213
|
+
/** `tool_call_update` 与权限请求里的 toolCall:除 id 外都可缺。 */
|
|
214
|
+
export type AcpToolCallUpdate = Partial<AcpToolCall> & {
|
|
215
|
+
toolCallId: string;
|
|
216
|
+
};
|
|
217
|
+
export interface AcpPlanEntry {
|
|
218
|
+
content: string;
|
|
219
|
+
priority: "high" | "medium" | "low";
|
|
220
|
+
status: "pending" | "in_progress" | "completed";
|
|
221
|
+
}
|
|
222
|
+
export type AcpSessionUpdate = {
|
|
223
|
+
sessionUpdate: "user_message_chunk";
|
|
224
|
+
content: AcpContentBlock;
|
|
225
|
+
} | {
|
|
226
|
+
sessionUpdate: "agent_message_chunk";
|
|
227
|
+
content: AcpContentBlock;
|
|
228
|
+
} | {
|
|
229
|
+
sessionUpdate: "agent_thought_chunk";
|
|
230
|
+
content: AcpContentBlock;
|
|
231
|
+
} | ({
|
|
232
|
+
sessionUpdate: "tool_call";
|
|
233
|
+
} & AcpToolCall) | ({
|
|
234
|
+
sessionUpdate: "tool_call_update";
|
|
235
|
+
} & AcpToolCallUpdate) | {
|
|
236
|
+
sessionUpdate: "plan";
|
|
237
|
+
entries: AcpPlanEntry[];
|
|
238
|
+
} | {
|
|
239
|
+
sessionUpdate: "current_mode_update";
|
|
240
|
+
currentModeId: string;
|
|
241
|
+
} | {
|
|
242
|
+
sessionUpdate: "usage_update";
|
|
243
|
+
/** 当前上下文已用 token。 */
|
|
244
|
+
used: number;
|
|
245
|
+
/** 上下文窗口。 */
|
|
246
|
+
size: number;
|
|
247
|
+
cost?: {
|
|
248
|
+
amount: number;
|
|
249
|
+
currency: string;
|
|
250
|
+
} | null;
|
|
251
|
+
} | {
|
|
252
|
+
sessionUpdate: "available_commands_update";
|
|
253
|
+
availableCommands: {
|
|
254
|
+
name: string;
|
|
255
|
+
description: string;
|
|
256
|
+
}[];
|
|
257
|
+
} | {
|
|
258
|
+
sessionUpdate: "session_info_update";
|
|
259
|
+
title?: string | null;
|
|
260
|
+
updatedAt?: string | null;
|
|
261
|
+
};
|
|
262
|
+
export interface AcpSessionNotification {
|
|
263
|
+
sessionId: string;
|
|
264
|
+
update: AcpSessionUpdate;
|
|
265
|
+
}
|
|
266
|
+
export type AcpPermissionOptionKind = "allow_once" | "allow_always" | "reject_once" | "reject_always";
|
|
267
|
+
export interface AcpPermissionOption {
|
|
268
|
+
optionId: string;
|
|
269
|
+
name: string;
|
|
270
|
+
kind: AcpPermissionOptionKind;
|
|
271
|
+
}
|
|
272
|
+
export interface AcpRequestPermissionParams {
|
|
273
|
+
sessionId: string;
|
|
274
|
+
toolCall: AcpToolCallUpdate;
|
|
275
|
+
options: AcpPermissionOption[];
|
|
276
|
+
}
|
|
277
|
+
export type AcpPermissionOutcome = {
|
|
278
|
+
outcome: "cancelled";
|
|
279
|
+
} | {
|
|
280
|
+
outcome: "selected";
|
|
281
|
+
optionId: string;
|
|
282
|
+
};
|
|
283
|
+
export interface AcpRequestPermissionResult {
|
|
284
|
+
outcome: AcpPermissionOutcome;
|
|
285
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ACP(Agent Client Protocol)v1 的子集类型(docs/wave5-plan.md §5.1,D14)。[W5-E]
|
|
3
|
+
*
|
|
4
|
+
* 手写、零依赖;只收 ama 作为客户端(驱动外部 Agent)与服务端(`ama --mode acp`)两侧用到的部分:
|
|
5
|
+
* `initialize`、`session/new|load|resume|list|close`、`session/prompt|cancel|set_mode`、
|
|
6
|
+
* `session/update`(含 `usage_update`)、`session/request_permission`。字段名与规范一致(camelCase),
|
|
7
|
+
* 未知字段一律保留不报错;`_meta` 不解释。
|
|
8
|
+
*
|
|
9
|
+
* 不声明 `fs` / `terminal` 客户端能力(与 Armadra Q5 一致):外部 Agent 自己读写、自己跑命令,
|
|
10
|
+
* 用它自己的权限策略;它要问人的才经 `session/request_permission` 回到 ama。
|
|
11
|
+
*/
|
|
12
|
+
export const ACP_PROTOCOL_VERSION = 1;
|
|
13
|
+
/** 方法名(客户端 → Agent 的请求 / 通知,Agent → 客户端的请求 / 通知)。 */
|
|
14
|
+
export const ACP_METHODS = {
|
|
15
|
+
initialize: "initialize",
|
|
16
|
+
sessionNew: "session/new",
|
|
17
|
+
sessionLoad: "session/load",
|
|
18
|
+
sessionResume: "session/resume",
|
|
19
|
+
sessionList: "session/list",
|
|
20
|
+
sessionClose: "session/close",
|
|
21
|
+
sessionPrompt: "session/prompt",
|
|
22
|
+
sessionCancel: "session/cancel",
|
|
23
|
+
sessionSetMode: "session/set_mode",
|
|
24
|
+
sessionUpdate: "session/update",
|
|
25
|
+
requestPermission: "session/request_permission",
|
|
26
|
+
};
|
|
27
|
+
/** JSON-RPC 错误码(规范沿用 JSON-RPC 2.0;`-32000` 为 ACP 的 auth_required)。 */
|
|
28
|
+
export const RPC_ERRORS = {
|
|
29
|
+
parseError: -32700,
|
|
30
|
+
invalidRequest: -32600,
|
|
31
|
+
methodNotFound: -32601,
|
|
32
|
+
invalidParams: -32602,
|
|
33
|
+
internalError: -32603,
|
|
34
|
+
authRequired: -32000,
|
|
35
|
+
resourceNotFound: -32002,
|
|
36
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 外部 Agent 的入口(W5-G 的 `task(agent=…)` 经它拿 runner,docs/wave5-plan.md §5.5、§7.6、D13、D17)。[W5-E]
|
|
3
|
+
*
|
|
4
|
+
* - `resolve("claude" | "codex" | "acp:<program>" | 表里的 id)` → {@link ProcessRunner}(按驱动表候选链,
|
|
5
|
+
* 每次 `start` 时按模式与安装情况选驱动);同一 spec 复用同一个 runner。
|
|
6
|
+
* - 宿主(`HostApi.runners.provide`)注入的 runner 优先:同名替换内置外部 runner。
|
|
7
|
+
* - **有宿主(profile.host)时不自 spawn**:内置外部 runner 一律不可用,只认宿主注入的(D17;绕过画布
|
|
8
|
+
* spawn 会让节点、连线授权与审批全部失效)。
|
|
9
|
+
* - 共用一个并发池、一个探测缓存(`<dataDir>/drivers.json`)与 pid 登记(`<dataDir>/drivers/pids.json`;
|
|
10
|
+
* 首次创建时清理上次崩溃留下的孤儿进程)。
|
|
11
|
+
*/
|
|
12
|
+
import type { AgentInfo } from "../agents/types.js";
|
|
13
|
+
import type { AgentsConfig } from "../config/types-w5.js";
|
|
14
|
+
import type { PermissionMode } from "../permissions/types.js";
|
|
15
|
+
import type { SubagentRunner } from "../tools/types.js";
|
|
16
|
+
import type { DriverDeps } from "./base.js";
|
|
17
|
+
import { type CatalogCandidate } from "./catalog.js";
|
|
18
|
+
import { HostRunnerRegistry } from "./host-runners.js";
|
|
19
|
+
import type { ApproveFn } from "./permissions.js";
|
|
20
|
+
import { type DriverPool } from "./pool.js";
|
|
21
|
+
import type { AgentStore } from "./store.js";
|
|
22
|
+
import type { AgentDriver } from "./types.js";
|
|
23
|
+
/** 按候选种类建驱动。 */
|
|
24
|
+
export declare function createDriver(agentId: string, candidate: CatalogCandidate, deps: DriverDeps): AgentDriver;
|
|
25
|
+
export { HostRunnerRegistry };
|
|
26
|
+
export interface ExternalAgentsOptions {
|
|
27
|
+
config?: AgentsConfig;
|
|
28
|
+
/** 原始环境(子进程环境由 runner 按 D16 清理)。 */
|
|
29
|
+
env: NodeJS.ProcessEnv;
|
|
30
|
+
cwd: string;
|
|
31
|
+
/** 探测缓存与 pid 登记的位置;不给则只做内存缓存、不登记。 */
|
|
32
|
+
dataDir?: string;
|
|
33
|
+
/** 有宿主(profile.host):只认宿主注入的 runner。 */
|
|
34
|
+
hosted: boolean;
|
|
35
|
+
/** 宿主注入的 runner(宿主适配器一份,跨会话共享);不给则本实例自建一份。 */
|
|
36
|
+
hostRunners?: HostRunnerRegistry;
|
|
37
|
+
/** 审批只交给人:接到会话的 requestApproval。 */
|
|
38
|
+
approve: ApproveFn;
|
|
39
|
+
store?: AgentStore;
|
|
40
|
+
parentMode?(): PermissionMode;
|
|
41
|
+
unattended?: boolean | (() => boolean);
|
|
42
|
+
trusted(cwd: string): boolean;
|
|
43
|
+
/** 测试 / 宿主注入(spawn、probe)。 */
|
|
44
|
+
driverDeps?: DriverDeps;
|
|
45
|
+
log?(level: "debug" | "info" | "warn", message: string): void;
|
|
46
|
+
}
|
|
47
|
+
export declare class ExternalAgents {
|
|
48
|
+
private readonly options;
|
|
49
|
+
readonly hostRunners: HostRunnerRegistry;
|
|
50
|
+
readonly pool: DriverPool;
|
|
51
|
+
private readonly runners;
|
|
52
|
+
private readonly driverDeps;
|
|
53
|
+
constructor(options: ExternalAgentsOptions);
|
|
54
|
+
/** `task(agent=<spec>)` 的 runner;不可用时抛 AmaError(`agent_host_only` / `agent_unknown`)。 */
|
|
55
|
+
resolve(spec: string): SubagentRunner;
|
|
56
|
+
/** `/agents` 与 RPC `get_agents` 的外部 Agent 部分(探测 PATH 与版本,不联网)。 */
|
|
57
|
+
list(): Promise<AgentInfo[]>;
|
|
58
|
+
}
|