@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
|
@@ -1,157 +1,287 @@
|
|
|
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
|
*/
|
|
13
18
|
import { AmaError } from "../errors.js";
|
|
19
|
+
import { PermissionPipeline } from "../permissions/pipeline.js";
|
|
14
20
|
import { SessionManager } from "../session/manager.js";
|
|
21
|
+
import { agentRole } from "../agents/builtin.js";
|
|
15
22
|
import { ZERO_USAGE } from "./loop.js";
|
|
16
|
-
|
|
23
|
+
import { DEFAULT_SUBAGENT_CONCURRENCY, SubagentPool, TASK_CUSTOM_TYPE, subagentRegistryFor, } from "./subagent-registry.js";
|
|
24
|
+
export { DEFAULT_SUBAGENT_CONCURRENCY, SubagentPool, TASK_CUSTOM_TYPE };
|
|
17
25
|
export const DEFAULT_SUBAGENT_MAX_TURNS = 30;
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
export
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
waiters = [];
|
|
24
|
-
constructor(limit) {
|
|
25
|
-
this.limit = limit;
|
|
26
|
-
}
|
|
27
|
-
async acquire(signal) {
|
|
28
|
-
while (this.running >= this.limit) {
|
|
29
|
-
if (signal.aborted)
|
|
30
|
-
throw new AmaError("aborted", "aborted");
|
|
31
|
-
await new Promise((resolve) => this.waiters.push(resolve));
|
|
32
|
-
}
|
|
33
|
-
this.running++;
|
|
34
|
-
}
|
|
35
|
-
release() {
|
|
36
|
-
this.running--;
|
|
37
|
-
this.waiters.shift()?.();
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
/** 子会话的 broker:请求带上发起方上下文(对话框标 `[task]`),其余原样交给父链。 */
|
|
26
|
+
/** 子会话里保留在工具表、运行时拒绝的名字(深度 ≤ 1)。 */
|
|
27
|
+
export const PARENT_ONLY_TOOLS = ["task", "task_ctl"];
|
|
28
|
+
export const FINAL_REPORT_PROMPT = "You have reached the turn limit for this task. Do not call any tools. Reply now with your " +
|
|
29
|
+
"final report: what you did, key findings, and what is left unfinished.";
|
|
30
|
+
/** 子会话的 broker:请求带上发起方上下文(对话框标 `[task:<agent>]`),其余原样交给父链。 */
|
|
41
31
|
function brokersForChild(brokers, context) {
|
|
42
32
|
return (brokers ?? []).map((broker) => ({
|
|
43
33
|
ask: (request, signal) => broker.ask({ ...request, context }, signal),
|
|
44
34
|
}));
|
|
45
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* 只读子会话的权限管线:plan 模式、规则同父;ask 一律转 deny(只读类型不弹审批)。
|
|
38
|
+
* 父管线不是 `PermissionPipeline`(宿主 / SDK 自带实现)时退化为「只放行 read 类」。
|
|
39
|
+
*/
|
|
40
|
+
export function readOnlyPermission(parent, cwd) {
|
|
41
|
+
const base = parent instanceof PermissionPipeline ? parent : undefined;
|
|
42
|
+
const inner = new PermissionPipeline({
|
|
43
|
+
mode: "plan",
|
|
44
|
+
rules: parent?.rules ?? [],
|
|
45
|
+
cwd: base?.cwd ?? cwd,
|
|
46
|
+
...(parent?.projectRoot === undefined ? {} : { projectRoot: parent.projectRoot }),
|
|
47
|
+
// 沿用父的 plan.bash(deny 更严时照样 deny;ask 由下面统一转 deny)
|
|
48
|
+
...(base === undefined ? {} : { planBash: base.planBash }),
|
|
49
|
+
});
|
|
50
|
+
const denied = "Read-only sub-agent: this call is not allowed (it would modify files or run a non-read-only command).";
|
|
51
|
+
return {
|
|
52
|
+
get mode() {
|
|
53
|
+
return "plan";
|
|
54
|
+
},
|
|
55
|
+
setMode: () => undefined,
|
|
56
|
+
get rules() {
|
|
57
|
+
return inner.rules;
|
|
58
|
+
},
|
|
59
|
+
check: (input) => {
|
|
60
|
+
const verdict = inner.check(input);
|
|
61
|
+
return verdict.decision === "ask"
|
|
62
|
+
? { ...verdict, decision: "deny", message: verdict.message ?? denied }
|
|
63
|
+
: verdict;
|
|
64
|
+
},
|
|
65
|
+
rememberForSession: () => undefined,
|
|
66
|
+
...(parent?.projectRoot === undefined ? {} : { projectRoot: parent.projectRoot }),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
46
69
|
function failed(text) {
|
|
47
|
-
return { text, usage: { ...ZERO_USAGE }, stopReason: "error", isError: true };
|
|
70
|
+
return { text, usage: { ...ZERO_USAGE }, stopReason: "error", isError: true, status: "failed" };
|
|
48
71
|
}
|
|
49
|
-
export async function runSubagent(parent, request,
|
|
72
|
+
export async function runSubagent(parent, request, _pool, createChild) {
|
|
50
73
|
if (parent.depth > 0)
|
|
51
74
|
return failed("subagents cannot spawn subagents");
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
75
|
+
const registry = subagentRegistryFor(parent);
|
|
76
|
+
return registry.run(request, (spec) => createAmaRunner(parent, spec, createChild));
|
|
77
|
+
}
|
|
78
|
+
/** 活动集:缺省 = 父活动集(含 task / task_ctl,工具表对齐);白名单 / 黑名单时按名过滤。 */
|
|
79
|
+
function childToolNames(parent, spec, base) {
|
|
80
|
+
const available = new Set((parent.options.tools ?? []).map((tool) => tool.name));
|
|
81
|
+
const all = [...(base ?? available)].filter((name) => available.has(name));
|
|
82
|
+
const allow = spec.request.tools ?? spec.agent.tools;
|
|
83
|
+
if (allow !== undefined)
|
|
84
|
+
return allow.filter((name) => available.has(name) && !PARENT_ONLY_TOOLS.includes(name));
|
|
85
|
+
const deny = spec.agent.disallowedTools;
|
|
86
|
+
if (deny !== undefined)
|
|
87
|
+
return all.filter((name) => !deny.includes(name) && !PARENT_ONLY_TOOLS.includes(name));
|
|
88
|
+
return all;
|
|
89
|
+
}
|
|
90
|
+
/** ama 自己的子会话 runner(同进程)。 */
|
|
91
|
+
export function createAmaRunner(parent, spec, createChild) {
|
|
92
|
+
return {
|
|
93
|
+
id: "ama",
|
|
94
|
+
start: (request) => startAmaChild(parent, spec, createChild, request),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
function childManager(parent, spec) {
|
|
98
|
+
if (spec.resumeFile !== undefined)
|
|
99
|
+
return SessionManager.open(spec.resumeFile);
|
|
100
|
+
const parentFile = parent.manager.file();
|
|
101
|
+
const header = parentFile === undefined ? {} : { parentSession: parentFile };
|
|
102
|
+
const dir = parent.manager.directory();
|
|
103
|
+
const manager = dir === undefined
|
|
104
|
+
? SessionManager.inMemory(spec.cwd, header)
|
|
105
|
+
: SessionManager.create(dir, spec.cwd, header);
|
|
106
|
+
manager.append({
|
|
107
|
+
type: "custom",
|
|
108
|
+
customType: TASK_CUSTOM_TYPE,
|
|
109
|
+
data: {
|
|
110
|
+
taskId: spec.taskId,
|
|
111
|
+
agent: spec.agent.name,
|
|
112
|
+
parentToolCallId: spec.request.parentToolCallId,
|
|
113
|
+
description: spec.request.description,
|
|
114
|
+
parentSession: parentFile,
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
// 立即落盘:subagent_start 带上子会话文件,续聊 / resume 靠它重开
|
|
118
|
+
if (dir !== undefined)
|
|
119
|
+
manager.flush();
|
|
120
|
+
return manager;
|
|
121
|
+
}
|
|
122
|
+
async function startAmaChild(parent, spec, createChild, run) {
|
|
123
|
+
const base = parent.childBase();
|
|
124
|
+
let model = base.model;
|
|
125
|
+
if (spec.modelRef !== undefined) {
|
|
126
|
+
const lookup = parent.options.providers.findModel(spec.modelRef);
|
|
127
|
+
if (!lookup.ok)
|
|
128
|
+
throw new AmaError("model_not_found", `unknown model ${spec.modelRef}`);
|
|
129
|
+
model = lookup.model;
|
|
130
|
+
}
|
|
131
|
+
const manager = childManager(parent, spec);
|
|
132
|
+
const checkpointHooks = spec.isolated ? undefined : parent.checkpointHooks?.();
|
|
133
|
+
let finalRound = false;
|
|
134
|
+
const finalRoundExtension = () => ({
|
|
135
|
+
id: "ama.subagent-final-round",
|
|
136
|
+
wrapStream: (stream) => (m, context, options) => stream(m, context, finalRound ? { ...options, toolChoice: "none" } : options),
|
|
137
|
+
});
|
|
138
|
+
const maxTurns = spec.request.maxTurns ?? spec.agent.maxTurns ?? DEFAULT_SUBAGENT_MAX_TURNS;
|
|
139
|
+
const options = {
|
|
140
|
+
...parent.options,
|
|
141
|
+
...base,
|
|
142
|
+
system: { ...base.system, role: agentRole(spec.agent) },
|
|
143
|
+
sessionManager: manager,
|
|
144
|
+
model,
|
|
145
|
+
thinkingLevel: spec.request.thinkingLevel ?? spec.agent.thinking ?? base.thinkingLevel ?? "off",
|
|
146
|
+
activeTools: childToolNames(parent, spec, base.activeTools),
|
|
147
|
+
brokers: brokersForChild(parent.options.brokers, {
|
|
90
148
|
depth: parent.depth + 1,
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
})
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
149
|
+
parentToolCallId: spec.request.parentToolCallId,
|
|
150
|
+
taskId: spec.taskId,
|
|
151
|
+
}),
|
|
152
|
+
depth: parent.depth + 1,
|
|
153
|
+
maxTurns,
|
|
154
|
+
subagents: false,
|
|
155
|
+
extensions: [...(parent.options.extensions ?? []), finalRoundExtension],
|
|
156
|
+
};
|
|
157
|
+
delete options.checkpointHooks;
|
|
158
|
+
if (checkpointHooks !== undefined)
|
|
159
|
+
options.checkpointHooks = checkpointHooks;
|
|
160
|
+
if (spec.agent.permissionMode === "plan")
|
|
161
|
+
options.permission = readOnlyPermission(parent.options.permission, spec.cwd);
|
|
162
|
+
const child = createChild(options);
|
|
163
|
+
let turns = 0;
|
|
164
|
+
let toolUse = false;
|
|
165
|
+
const unsubscribe = child.subscribe((event) => {
|
|
166
|
+
if (event.type === "tool_execution_start" && event.parentToolCallId === undefined)
|
|
167
|
+
run.onEvent({ type: "tool", toolName: event.toolName, status: "started" });
|
|
168
|
+
else if (event.type === "message_update" && event.assistantMessageEvent.type === "text_delta")
|
|
169
|
+
run.onEvent({ type: "text", delta: event.assistantMessageEvent.delta });
|
|
170
|
+
else if (event.type === "turn_end") {
|
|
171
|
+
turns++;
|
|
172
|
+
toolUse = event.toolResults.length > 0;
|
|
173
|
+
const { input, output, cacheRead, cacheWrite, total } = child.getStats().tokens;
|
|
174
|
+
run.onEvent({
|
|
175
|
+
type: "usage",
|
|
176
|
+
usage: { input, output, cacheRead, cacheWrite, totalTokens: total },
|
|
177
|
+
});
|
|
178
|
+
run.onEvent({ type: "turn", turn: turns });
|
|
179
|
+
}
|
|
180
|
+
else if (event.type === "permission_request" || event.type === "permission_resolved")
|
|
181
|
+
parent.emit(event);
|
|
182
|
+
});
|
|
183
|
+
const onAbort = () => void child.abort();
|
|
184
|
+
run.signal.addEventListener("abort", onAbort, { once: true });
|
|
185
|
+
let billed = { cacheRead: 0, prompt: 0, reBilled: 0 };
|
|
186
|
+
const runOnce = async (prompt) => {
|
|
187
|
+
const startTurns = turns;
|
|
102
188
|
let error;
|
|
103
189
|
try {
|
|
104
|
-
if (
|
|
190
|
+
if (run.signal.aborted)
|
|
105
191
|
throw new AmaError("aborted", "aborted");
|
|
106
|
-
await child.prompt(
|
|
192
|
+
await child.prompt(prompt);
|
|
107
193
|
}
|
|
108
194
|
catch (caught) {
|
|
109
195
|
error = caught instanceof Error ? caught.message : String(caught);
|
|
110
196
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
197
|
+
const exhausted = error === undefined && !run.signal.aborted && turns - startTurns >= maxTurns && toolUse;
|
|
198
|
+
if (exhausted) {
|
|
199
|
+
finalRound = true;
|
|
200
|
+
options.maxTurns = 1;
|
|
201
|
+
try {
|
|
202
|
+
await child.prompt(FINAL_REPORT_PROMPT);
|
|
203
|
+
}
|
|
204
|
+
catch (caught) {
|
|
205
|
+
error = caught instanceof Error ? caught.message : String(caught);
|
|
206
|
+
}
|
|
207
|
+
finally {
|
|
208
|
+
finalRound = false;
|
|
209
|
+
options.maxTurns = maxTurns;
|
|
210
|
+
}
|
|
114
211
|
}
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
? "error"
|
|
121
|
-
: last?.type === "message" && last.message.role === "assistant"
|
|
122
|
-
? last.message.stopReason
|
|
123
|
-
: "stop";
|
|
124
|
-
const result = {
|
|
125
|
-
text: child.getLastAssistantText() ?? error ?? "",
|
|
126
|
-
usage: {
|
|
127
|
-
input: stats.tokens.input,
|
|
128
|
-
output: stats.tokens.output,
|
|
129
|
-
cacheRead: stats.tokens.cacheRead,
|
|
130
|
-
cacheWrite: stats.tokens.cacheWrite,
|
|
131
|
-
totalTokens: stats.tokens.total,
|
|
132
|
-
},
|
|
133
|
-
stopReason,
|
|
134
|
-
isError: error !== undefined || stopReason === "error" || stopReason === "aborted",
|
|
135
|
-
};
|
|
136
|
-
const cache = stats.cache;
|
|
137
|
-
if (cache !== undefined) {
|
|
138
|
-
result.cache = { reBilledTokens: cache.reBilledTokens };
|
|
139
|
-
if (cache.hitRate !== undefined)
|
|
140
|
-
result.cache.hitRate = cache.hitRate;
|
|
141
|
-
// 不报缓存的子会话不进命中率分母(同父会话口径)
|
|
142
|
-
const reported = cache.reporting === "reported";
|
|
143
|
-
const { input, cacheRead, cacheWrite } = stats.tokens;
|
|
144
|
-
parent.cache?.addSubagent(reported
|
|
145
|
-
? { cacheRead, prompt: input + cacheRead + cacheWrite }
|
|
146
|
-
: { cacheRead: 0, prompt: 0 }, cache.reBilledTokens);
|
|
147
|
-
}
|
|
148
|
-
const childFile = childManager.file();
|
|
149
|
-
if (childFile !== undefined)
|
|
150
|
-
result.sessionFile = childFile;
|
|
151
|
-
await child.dispose();
|
|
212
|
+
const result = collect(child, error, exhausted, run.signal.aborted);
|
|
213
|
+
billed = addCache(parent, child.getStats(), billed);
|
|
214
|
+
const file = manager.file();
|
|
215
|
+
if (file !== undefined)
|
|
216
|
+
result.sessionFile = file;
|
|
152
217
|
return result;
|
|
218
|
+
};
|
|
219
|
+
let current = runOnce(run.prompt);
|
|
220
|
+
const handle = {
|
|
221
|
+
id: manager.id,
|
|
222
|
+
model: `${model.provider}/${model.id}`,
|
|
223
|
+
...(manager.file() === undefined ? {} : { sessionFile: manager.file() }),
|
|
224
|
+
send: async (text) => {
|
|
225
|
+
current = runOnce(text);
|
|
226
|
+
},
|
|
227
|
+
wait: () => current,
|
|
228
|
+
stop: () => child.abort(),
|
|
229
|
+
dispose: async () => {
|
|
230
|
+
run.signal.removeEventListener("abort", onAbort);
|
|
231
|
+
unsubscribe();
|
|
232
|
+
await child.dispose();
|
|
233
|
+
},
|
|
234
|
+
};
|
|
235
|
+
return handle;
|
|
236
|
+
}
|
|
237
|
+
function collect(child, error, exhausted, aborted) {
|
|
238
|
+
const stats = child.getStats();
|
|
239
|
+
const last = child.manager
|
|
240
|
+
.branch()
|
|
241
|
+
.findLast((entry) => entry.type === "message" && entry.message.role === "assistant");
|
|
242
|
+
const stopReason = error !== undefined
|
|
243
|
+
? "error"
|
|
244
|
+
: last?.type === "message" && last.message.role === "assistant"
|
|
245
|
+
? last.message.stopReason
|
|
246
|
+
: "stop";
|
|
247
|
+
const isError = error !== undefined || stopReason === "error" || stopReason === "aborted";
|
|
248
|
+
const result = {
|
|
249
|
+
text: child.getLastAssistantText() ?? error ?? "",
|
|
250
|
+
usage: {
|
|
251
|
+
input: stats.tokens.input,
|
|
252
|
+
output: stats.tokens.output,
|
|
253
|
+
cacheRead: stats.tokens.cacheRead,
|
|
254
|
+
cacheWrite: stats.tokens.cacheWrite,
|
|
255
|
+
totalTokens: stats.tokens.total,
|
|
256
|
+
},
|
|
257
|
+
stopReason,
|
|
258
|
+
isError,
|
|
259
|
+
status: aborted || stopReason === "aborted"
|
|
260
|
+
? "aborted"
|
|
261
|
+
: isError
|
|
262
|
+
? "failed"
|
|
263
|
+
: exhausted
|
|
264
|
+
? "max_turns"
|
|
265
|
+
: "completed",
|
|
266
|
+
};
|
|
267
|
+
if (stats.cache !== undefined) {
|
|
268
|
+
result.cache = { reBilledTokens: stats.cache.reBilledTokens };
|
|
269
|
+
if (stats.cache.hitRate !== undefined)
|
|
270
|
+
result.cache.hitRate = stats.cache.hitRate;
|
|
153
271
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
272
|
+
return result;
|
|
273
|
+
}
|
|
274
|
+
/** 子会话命中与重计费按增量汇总进父(续聊不重复计)。 */
|
|
275
|
+
function addCache(parent, stats, before) {
|
|
276
|
+
const cache = stats.cache;
|
|
277
|
+
if (cache === undefined)
|
|
278
|
+
return before;
|
|
279
|
+
// 不报缓存的子会话不进命中率分母(同父会话口径)
|
|
280
|
+
const reported = cache.reporting === "reported";
|
|
281
|
+
const { input, cacheRead, cacheWrite } = stats.tokens;
|
|
282
|
+
const now = reported
|
|
283
|
+
? { cacheRead, prompt: input + cacheRead + cacheWrite, reBilled: cache.reBilledTokens }
|
|
284
|
+
: { cacheRead: 0, prompt: 0, reBilled: cache.reBilledTokens };
|
|
285
|
+
parent.cache?.addSubagent({ cacheRead: now.cacheRead - before.cacheRead, prompt: now.prompt - before.prompt }, now.reBilled - before.reBilled);
|
|
286
|
+
return now;
|
|
157
287
|
}
|
|
@@ -8,13 +8,20 @@
|
|
|
8
8
|
* - `runHookWithEvents`:调 HookDispatcher(公共字段按本会话的 depth / sessionId / sessionFile 覆盖),
|
|
9
9
|
* 逐条发 hook_executed;Hook 自身出错记 warning、按无决策处理。
|
|
10
10
|
*/
|
|
11
|
-
import type { Model, ModelThinkingLevel } from "../ai/types.js";
|
|
11
|
+
import type { Model, ModelRef, ModelThinkingLevel, ProviderRegistryApi } from "../ai/types.js";
|
|
12
12
|
import type { HookEvent, HookEventPayload, HookOutcome } from "../hooks/types.js";
|
|
13
|
-
import type { AgentMessage } from "../session/types.js";
|
|
13
|
+
import type { AgentMessage, SessionEntry } from "../session/types.js";
|
|
14
14
|
import type { ToolDefinition } from "../tools/types.js";
|
|
15
|
+
import type { SessionManager } from "../session/manager.js";
|
|
15
16
|
import type { SessionCore } from "./session-core.js";
|
|
17
|
+
import type { SessionEvent } from "./types.js";
|
|
16
18
|
import { type SystemPromptInput } from "./system-prompt.js";
|
|
17
|
-
export declare function persistMessage(core: SessionCore, message: AgentMessage):
|
|
19
|
+
export declare function persistMessage(core: SessionCore, message: AgentMessage): SessionEntry | undefined;
|
|
18
20
|
export declare function recordModelState(core: SessionCore, model: Model, thinkingLevel: ModelThinkingLevel): void;
|
|
21
|
+
/** 落一条 model_change,返回模型引用(`setModel` 发 model_changed 用)。 */
|
|
22
|
+
export declare function appendModelChange(core: SessionCore, model: Model): ModelRef;
|
|
23
|
+
export declare function findModelOrThrow(providers: ProviderRegistryApi, ref: string): Model;
|
|
19
24
|
export declare function syncSystemMessage(core: SessionCore, input: Omit<SystemPromptInput, "tools" | "cwd">, tools: readonly ToolDefinition[]): void;
|
|
20
25
|
export declare function runHookWithEvents(core: Pick<SessionCore, "options" | "emit" | "log" | "depth" | "manager">, event: HookEvent, payload: HookEventPayload, signal?: AbortSignal): Promise<HookOutcome | undefined>;
|
|
26
|
+
/** session_start 事件(bootstrap / SDK 在会话就绪后发一次)。 */
|
|
27
|
+
export declare function sessionStartEvent(manager: SessionManager, reason: "startup" | "resume" | "new" | "fork"): SessionEvent;
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
* - `runHookWithEvents`:调 HookDispatcher(公共字段按本会话的 depth / sessionId / sessionFile 覆盖),
|
|
9
9
|
* 逐条发 hook_executed;Hook 自身出错记 warning、按无决策处理。
|
|
10
10
|
*/
|
|
11
|
+
import { modelRefOf } from "../ai/providers/channels.js";
|
|
12
|
+
import { AmaError } from "../errors.js";
|
|
11
13
|
import { assembleSections, currentSystemState, definedSections, diffSystem, toolDecls, } from "./system-prompt.js";
|
|
12
14
|
export function persistMessage(core, message) {
|
|
13
15
|
if (message.role === "custom") {
|
|
@@ -19,11 +21,12 @@ export function persistMessage(core, message) {
|
|
|
19
21
|
};
|
|
20
22
|
if (message.details !== undefined)
|
|
21
23
|
input.details = message.details;
|
|
22
|
-
core.appendEntry(input);
|
|
24
|
+
return core.appendEntry(input);
|
|
23
25
|
}
|
|
24
26
|
else if (message.role !== "compactionSummary" && message.role !== "branchSummary") {
|
|
25
|
-
core.appendEntry({ type: "message", message });
|
|
27
|
+
return core.appendEntry({ type: "message", message });
|
|
26
28
|
}
|
|
29
|
+
return undefined;
|
|
27
30
|
}
|
|
28
31
|
export function recordModelState(core, model, thinkingLevel) {
|
|
29
32
|
let provider;
|
|
@@ -40,17 +43,30 @@ export function recordModelState(core, model, thinkingLevel) {
|
|
|
40
43
|
thinking = entry.thinkingLevel;
|
|
41
44
|
}
|
|
42
45
|
if (provider !== model.provider || modelId !== model.id || channel !== model.channel) {
|
|
43
|
-
core
|
|
44
|
-
type: "model_change",
|
|
45
|
-
provider: model.provider,
|
|
46
|
-
modelId: model.id,
|
|
47
|
-
...(model.channel !== undefined ? { channel: model.channel } : {}),
|
|
48
|
-
});
|
|
46
|
+
appendModelChange(core, model);
|
|
49
47
|
}
|
|
50
48
|
if (thinking !== thinkingLevel) {
|
|
51
49
|
core.appendEntry({ type: "thinking_level_change", thinkingLevel });
|
|
52
50
|
}
|
|
53
51
|
}
|
|
52
|
+
/** 落一条 model_change,返回模型引用(`setModel` 发 model_changed 用)。 */
|
|
53
|
+
export function appendModelChange(core, model) {
|
|
54
|
+
const next = modelRefOf(model);
|
|
55
|
+
core.appendEntry({
|
|
56
|
+
type: "model_change",
|
|
57
|
+
provider: next.provider,
|
|
58
|
+
modelId: next.id,
|
|
59
|
+
...(next.channel !== undefined ? { channel: next.channel } : {}),
|
|
60
|
+
});
|
|
61
|
+
return next;
|
|
62
|
+
}
|
|
63
|
+
export function findModelOrThrow(providers, ref) {
|
|
64
|
+
const lookup = providers.findModel(ref);
|
|
65
|
+
if (!lookup.ok) {
|
|
66
|
+
throw new AmaError("model_not_found", `model ${ref} not found`, { detail: lookup.candidates });
|
|
67
|
+
}
|
|
68
|
+
return lookup.model;
|
|
69
|
+
}
|
|
54
70
|
export function syncSystemMessage(core, input, tools) {
|
|
55
71
|
recordModelState(core, core.model(), core.thinkingLevel());
|
|
56
72
|
const sections = definedSections(assembleSections({ ...input, tools, cwd: core.cwd }));
|
|
@@ -109,3 +125,16 @@ export async function runHookWithEvents(core, event, payload, signal) {
|
|
|
109
125
|
return undefined;
|
|
110
126
|
}
|
|
111
127
|
}
|
|
128
|
+
/** session_start 事件(bootstrap / SDK 在会话就绪后发一次)。 */
|
|
129
|
+
export function sessionStartEvent(manager, reason) {
|
|
130
|
+
const event = {
|
|
131
|
+
type: "session_start",
|
|
132
|
+
sessionId: manager.id,
|
|
133
|
+
cwd: manager.cwd,
|
|
134
|
+
reason,
|
|
135
|
+
};
|
|
136
|
+
const file = manager.file();
|
|
137
|
+
if (file !== undefined)
|
|
138
|
+
event.sessionFile = file;
|
|
139
|
+
return event;
|
|
140
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 会话遥测:输出速率与首 token 延迟(docs/wave5-plan.md §1.3,D2)。[W5-A]
|
|
3
|
+
*
|
|
4
|
+
* 以 `SessionExtension.wrapStream` 包一层流,只观察不改事件:
|
|
5
|
+
* - 只统计 `purpose: "turn"`(缺省即 turn);summary / warm / probe / classify 原样透传、不计入;
|
|
6
|
+
* - 首 token = 首个 `text_delta` / `thinking_delta` / `toolcall_start`(`ttftMs = firstTokenAt − requestAt`);
|
|
7
|
+
* - 流式中按增量字符估算输出 token(CJK / 假名 / 谚文每字 1,其余 / 4,与 `compaction/estimate.ts`
|
|
8
|
+
* 同口径,不逐块取整),瞬时速率取最近 2 s 滑动窗口;请求结束改用 `usage.output`(含 reasoning);
|
|
9
|
+
* - `tps = outputTokens / (doneAt − firstTokenAt)`;会话均速 = Σoutput / Σ(done − firstToken),只计有首
|
|
10
|
+
* token、非 error 且生成时长 ≥ 250 ms 的请求(更短的整块到达,速率无意义,`tps` 留空);
|
|
11
|
+
* - 流式中经 `emit` 发 `telemetry_tick`:首个在首 token 后 ≥ 500 ms,之后两次间隔 ≥ 500 ms(≤ 2 Hz,
|
|
12
|
+
* 只由增量驱动、不起计时器);
|
|
13
|
+
* `ticks: false`(`ui.animation: false`)时不发,界面在 message_end 时刷新。
|
|
14
|
+
*
|
|
15
|
+
* 数据从 `getStats().telemetry` 取(`contributeStats`):进行中的请求出了首 token 后 `last` 即指向它(只有
|
|
16
|
+
* `requestAt / firstTokenAt / ttftMs`),结束后补齐 `doneAt / outputTokens / tps`;`sessionStartedAt` 是扩展创建(本进程打开会话)的时刻。
|
|
17
|
+
*/
|
|
18
|
+
import type { SessionExtension, SessionExtensionFactory } from "./session-extensions.js";
|
|
19
|
+
import type { SessionEvent } from "./types.js";
|
|
20
|
+
import type { SessionTelemetry } from "./types-w5.js";
|
|
21
|
+
export declare const TELEMETRY_TICK_MS = 500;
|
|
22
|
+
export declare const TELEMETRY_WINDOW_MS = 2000;
|
|
23
|
+
export interface TelemetryDeps {
|
|
24
|
+
now?(): number;
|
|
25
|
+
/** 发 `telemetry_tick`(缺省不发)。 */
|
|
26
|
+
emit?(event: SessionEvent): void;
|
|
27
|
+
/** false:不发 tick(`ui.animation: false`)。缺省 true。 */
|
|
28
|
+
ticks?: boolean;
|
|
29
|
+
}
|
|
30
|
+
export type TelemetryExtension = SessionExtension & {
|
|
31
|
+
snapshot(): SessionTelemetry;
|
|
32
|
+
};
|
|
33
|
+
/** 一段增量文本的 token 估算(不取整,逐块累加不放大)。 */
|
|
34
|
+
export declare function deltaTokens(text: string): number;
|
|
35
|
+
export declare function createTelemetryExtension(deps?: TelemetryDeps): TelemetryExtension;
|
|
36
|
+
/** 组装表用的工厂:只装主会话(depth 0);`ui.animation: false` 不发 tick。 */
|
|
37
|
+
export declare function telemetryFactory(ui?: {
|
|
38
|
+
animation?: boolean;
|
|
39
|
+
}): SessionExtensionFactory;
|