@armadra/agent 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +177 -294
- package/CHANGELOG.zh-CN.md +442 -0
- package/README.md +408 -364
- package/README.zh-CN.md +705 -0
- package/dist/agent/session-plan.js +2 -2
- package/dist/agent/session-state.d.ts +3 -0
- package/dist/agent/session-state.js +20 -0
- package/dist/agent/session-subagent.d.ts +15 -1
- package/dist/agent/session-subagent.js +26 -3
- package/dist/agent/session-telemetry.d.ts +16 -2
- package/dist/agent/session-telemetry.js +29 -7
- package/dist/agent/session-tools.js +5 -2
- package/dist/agent/session-trace-writer.d.ts +27 -0
- package/dist/agent/session-trace-writer.js +253 -0
- package/dist/agent/session.d.ts +2 -0
- package/dist/agent/session.js +12 -0
- package/dist/agent/subagent-direct.d.ts +20 -0
- package/dist/agent/subagent-direct.js +76 -0
- package/dist/agent/subagent-registry.d.ts +8 -1
- package/dist/agent/subagent-registry.js +28 -1
- package/dist/agent/system-prompt.d.ts +3 -1
- package/dist/agent/system-prompt.js +3 -0
- package/dist/agent/tool-runner.d.ts +2 -1
- package/dist/agent/tool-runner.js +5 -4
- package/dist/agent/types-w6.d.ts +39 -0
- package/dist/agent/types-w6.js +4 -0
- package/dist/agent/types.d.ts +5 -2
- package/dist/agents/external.js +1 -1
- package/dist/agents/task-record.d.ts +74 -1
- package/dist/agents/task-record.js +100 -0
- package/dist/ai/apis/cache-params.js +2 -1
- package/dist/ai/apis/chatgpt-backend.d.ts +52 -0
- package/dist/ai/apis/chatgpt-backend.js +224 -0
- package/dist/ai/apis/chatgpt-rate-limits.d.ts +26 -0
- package/dist/ai/apis/chatgpt-rate-limits.js +91 -0
- package/dist/ai/apis/openai-responses-request.d.ts +2 -1
- package/dist/ai/apis/openai-responses-request.js +8 -2
- package/dist/ai/apis/openai-responses.d.ts +2 -0
- package/dist/ai/apis/openai-responses.js +51 -16
- package/dist/ai/overflow.d.ts +1 -1
- package/dist/ai/overflow.js +10 -7
- package/dist/ai/providers/auth.d.ts +15 -2
- package/dist/ai/providers/auth.js +69 -2
- package/dist/ai/providers/builtin.js +27 -0
- package/dist/ai/providers/catalog-data.js +1 -0
- package/dist/ai/providers/enrich.js +2 -7
- package/dist/ai/providers/models-dev-cache.js +15 -19
- package/dist/ai/providers/models-dev-snapshot.js +8 -7
- package/dist/ai/providers/models-dev.js +5 -15
- package/dist/ai/providers/suggest.js +2 -16
- package/dist/ai/types.d.ts +27 -1
- package/dist/auth/chatgpt/backend-client.d.ts +26 -0
- package/dist/auth/chatgpt/backend-client.js +74 -0
- package/dist/auth/chatgpt/claims.d.ts +17 -0
- package/dist/auth/chatgpt/claims.js +46 -0
- package/dist/auth/chatgpt/cli.d.ts +33 -0
- package/dist/auth/chatgpt/cli.js +252 -0
- package/dist/auth/chatgpt/doctor.d.ts +17 -0
- package/dist/auth/chatgpt/doctor.js +36 -0
- package/dist/auth/chatgpt/host-id.d.ts +7 -0
- package/dist/auth/chatgpt/host-id.js +26 -0
- package/dist/auth/chatgpt/login.d.ts +30 -0
- package/dist/auth/chatgpt/login.js +130 -0
- package/dist/auth/chatgpt/presets.d.ts +66 -0
- package/dist/auth/chatgpt/presets.js +120 -0
- package/dist/auth/chatgpt/quota-text.d.ts +13 -0
- package/dist/auth/chatgpt/quota-text.js +36 -0
- package/dist/auth/oauth/browser.d.ts +12 -0
- package/dist/auth/oauth/browser.js +27 -0
- package/dist/auth/oauth/callback-server.d.ts +47 -0
- package/dist/auth/oauth/callback-server.js +147 -0
- package/dist/auth/oauth/flows.d.ts +62 -0
- package/dist/auth/oauth/flows.js +113 -0
- package/dist/auth/oauth/jwt.d.ts +24 -0
- package/dist/auth/oauth/jwt.js +81 -0
- package/dist/auth/oauth/live.d.ts +21 -0
- package/dist/auth/oauth/live.js +25 -0
- package/dist/auth/oauth/oidc.d.ts +26 -0
- package/dist/auth/oauth/oidc.js +72 -0
- package/dist/auth/oauth/pkce.d.ts +15 -0
- package/dist/auth/oauth/pkce.js +20 -0
- package/dist/auth/oauth/refresh.d.ts +35 -0
- package/dist/auth/oauth/refresh.js +129 -0
- package/dist/auth/oauth/token-client.d.ts +33 -0
- package/dist/auth/oauth/token-client.js +121 -0
- package/dist/auth/oauth/token-store.d.ts +23 -0
- package/dist/auth/oauth/token-store.js +125 -0
- package/dist/auth/testing/fake-oauth.d.ts +73 -0
- package/dist/auth/testing/fake-oauth.js +271 -0
- package/dist/auth/testing/refresh-child.d.ts +5 -0
- package/dist/auth/testing/refresh-child.js +16 -0
- package/dist/bundle/ama.cjs +28307 -13241
- package/dist/checkpoints/backend.js +6 -5
- package/dist/checkpoints/restore.js +3 -2
- package/dist/checkpoints/settings.js +2 -1
- package/dist/checkpoints/shadow-git.js +7 -6
- package/dist/checkpoints/shadow-restore.js +3 -2
- package/dist/checkpoints/tracker.js +4 -3
- package/dist/cli/args.d.ts +9 -2
- package/dist/cli/args.js +74 -27
- package/dist/cli/bootstrap.js +53 -31
- package/dist/cli/choice-prompt.d.ts +58 -0
- package/dist/cli/choice-prompt.js +142 -0
- package/dist/cli/codemode-notice.js +2 -2
- package/dist/cli/compose-agents.js +2 -1
- package/dist/cli/compose-extensions.js +2 -0
- package/dist/cli/compose-memory.d.ts +53 -0
- package/dist/cli/compose-memory.js +127 -0
- package/dist/cli/compose-providers.d.ts +5 -0
- package/dist/cli/compose-providers.js +32 -2
- package/dist/cli/compose-session.d.ts +5 -0
- package/dist/cli/compose-session.js +27 -13
- package/dist/cli/compose-store.d.ts +2 -0
- package/dist/cli/compose-store.js +9 -5
- package/dist/cli/compose.d.ts +2 -0
- package/dist/cli/compose.js +13 -5
- package/dist/cli/default-model.d.ts +0 -2
- package/dist/cli/default-model.js +5 -8
- package/dist/cli/deps.d.ts +5 -1
- package/dist/cli/exit-codes.d.ts +1 -1
- package/dist/cli/exit-codes.js +7 -16
- package/dist/cli/from-prompt.js +3 -2
- package/dist/cli/help-text.d.ts +2 -1
- package/dist/cli/help-text.js +5 -99
- package/dist/cli/main.d.ts +5 -0
- package/dist/cli/main.js +21 -2
- package/dist/cli/proxy.js +14 -9
- package/dist/cli/runtime.d.ts +5 -0
- package/dist/cli/startup-screen.js +20 -27
- package/dist/cli/startup-steps.js +6 -8
- package/dist/cli/subcommands/auth.d.ts +6 -3
- package/dist/cli/subcommands/auth.js +52 -22
- package/dist/cli/subcommands/config-set.d.ts +21 -0
- package/dist/cli/subcommands/config-set.js +137 -0
- package/dist/cli/subcommands/config.d.ts +2 -1
- package/dist/cli/subcommands/config.js +51 -37
- package/dist/cli/subcommands/doctor.d.ts +2 -1
- package/dist/cli/subcommands/doctor.js +97 -58
- package/dist/cli/subcommands/init.d.ts +1 -1
- package/dist/cli/subcommands/init.js +8 -7
- package/dist/cli/subcommands/memory.d.ts +18 -0
- package/dist/cli/subcommands/memory.js +189 -0
- package/dist/cli/subcommands/model-meta.js +11 -9
- package/dist/cli/subcommands/models-cache-probe.d.ts +1 -1
- package/dist/cli/subcommands/models-cache-probe.js +26 -32
- package/dist/cli/subcommands/models-discover.d.ts +3 -0
- package/dist/cli/subcommands/models-discover.js +44 -21
- package/dist/cli/subcommands/models.d.ts +1 -1
- package/dist/cli/subcommands/models.js +29 -22
- package/dist/cli/subcommands/probe-runner.js +8 -7
- package/dist/cli/subcommands/providers-list.js +32 -21
- package/dist/cli/subcommands/providers-plan.js +24 -25
- package/dist/cli/subcommands/providers-probe.js +5 -6
- package/dist/cli/subcommands/providers.d.ts +2 -2
- package/dist/cli/subcommands/providers.js +48 -59
- package/dist/cli/subcommands/sessions-export.d.ts +1 -1
- package/dist/cli/subcommands/sessions-export.js +10 -9
- package/dist/cli/subcommands/sessions-search.d.ts +1 -1
- package/dist/cli/subcommands/sessions-search.js +11 -10
- package/dist/cli/subcommands/sessions-trace.d.ts +30 -0
- package/dist/cli/subcommands/sessions-trace.js +156 -0
- package/dist/cli/subcommands/sessions.d.ts +4 -3
- package/dist/cli/subcommands/sessions.js +40 -37
- package/dist/cli/subcommands/stats.d.ts +1 -1
- package/dist/cli/subcommands/stats.js +49 -30
- package/dist/cli/system-prompt-arg.js +3 -2
- package/dist/codemode/capability.js +3 -2
- package/dist/compaction/post-compact.d.ts +1 -0
- package/dist/compaction/post-compact.js +15 -1
- package/dist/compaction/prune-tier.d.ts +1 -1
- package/dist/compaction/prune-tier.js +3 -3
- package/dist/compaction/serialize.js +2 -1
- package/dist/config/auth-file.d.ts +12 -2
- package/dist/config/auth-file.js +32 -10
- package/dist/config/checker.js +12 -11
- package/dist/config/context-files.js +3 -2
- package/dist/config/edit.d.ts +106 -0
- package/dist/config/edit.js +350 -0
- package/dist/config/init.d.ts +4 -3
- package/dist/config/init.js +10 -18
- package/dist/config/json-schema.d.ts +2 -1
- package/dist/config/json-schema.js +101 -68
- package/dist/config/key-docs.d.ts +18 -7
- package/dist/config/key-docs.js +43 -128
- package/dist/config/load.js +7 -6
- package/dist/config/merge.d.ts +4 -1
- package/dist/config/merge.js +42 -22
- package/dist/config/paths.js +6 -5
- package/dist/config/profile.d.ts +5 -1
- package/dist/config/profile.js +7 -2
- package/dist/config/schema-w5.js +3 -2
- package/dist/config/schema-w6.d.ts +19 -0
- package/dist/config/schema-w6.js +115 -0
- package/dist/config/schema.js +34 -20
- package/dist/config/settings-registry.d.ts +78 -0
- package/dist/config/settings-registry.js +184 -0
- package/dist/config/types-w6.d.ts +109 -0
- package/dist/config/types-w6.js +19 -0
- package/dist/config/types.d.ts +11 -8
- package/dist/config/types.js +1 -0
- package/dist/drivers/acp/client.js +1 -1
- package/dist/drivers/acp/driver.js +13 -8
- package/dist/drivers/agents.js +4 -3
- package/dist/drivers/base.js +3 -2
- package/dist/drivers/host-runners.js +2 -1
- package/dist/drivers/native/claude-stream.js +12 -11
- package/dist/drivers/native/codex-app-server.js +17 -12
- package/dist/drivers/native/oneshot.js +8 -7
- package/dist/drivers/pool.js +1 -1
- package/dist/drivers/runner.d.ts +3 -1
- package/dist/drivers/runner.js +68 -20
- package/dist/drivers/turn.js +1 -1
- package/dist/hooks/config.js +3 -2
- package/dist/hooks/protocol.js +18 -12
- package/dist/host/api-impl.js +11 -10
- package/dist/host/loader.js +9 -8
- package/dist/host/types.d.ts +3 -0
- package/dist/i18n/catalog.d.ts +2169 -0
- package/dist/i18n/catalog.js +72 -0
- package/dist/i18n/format.d.ts +21 -0
- package/dist/i18n/format.js +58 -0
- package/dist/i18n/index.d.ts +58 -0
- package/dist/i18n/index.js +72 -0
- package/dist/i18n/messages/agents.d.ts +84 -0
- package/dist/i18n/messages/agents.js +85 -0
- package/dist/i18n/messages/approval.d.ts +99 -0
- package/dist/i18n/messages/approval.js +100 -0
- package/dist/i18n/messages/auth.d.ts +187 -0
- package/dist/i18n/messages/auth.js +189 -0
- package/dist/i18n/messages/cli-args.d.ts +46 -0
- package/dist/i18n/messages/cli-args.js +46 -0
- package/dist/i18n/messages/cli-help.d.ts +12 -0
- package/dist/i18n/messages/cli-help.js +244 -0
- package/dist/i18n/messages/cli.d.ts +336 -0
- package/dist/i18n/messages/cli.js +311 -0
- package/dist/i18n/messages/config-keys.d.ts +289 -0
- package/dist/i18n/messages/config-keys.js +292 -0
- package/dist/i18n/messages/config.d.ts +502 -0
- package/dist/i18n/messages/config.js +239 -0
- package/dist/i18n/messages/drivers.d.ts +123 -0
- package/dist/i18n/messages/drivers.js +124 -0
- package/dist/i18n/messages/errors.d.ts +83 -0
- package/dist/i18n/messages/errors.js +171 -0
- package/dist/i18n/messages/interactive-line.d.ts +61 -0
- package/dist/i18n/messages/interactive-line.js +69 -0
- package/dist/i18n/messages/interactive-startup.d.ts +103 -0
- package/dist/i18n/messages/interactive-startup.js +104 -0
- package/dist/i18n/messages/interactive-view.d.ts +140 -0
- package/dist/i18n/messages/interactive-view.js +141 -0
- package/dist/i18n/messages/interactive.d.ts +493 -0
- package/dist/i18n/messages/interactive.js +248 -0
- package/dist/i18n/messages/memory.d.ts +123 -0
- package/dist/i18n/messages/memory.js +128 -0
- package/dist/i18n/messages/panels.d.ts +190 -0
- package/dist/i18n/messages/panels.js +189 -0
- package/dist/i18n/messages/permissions.d.ts +126 -0
- package/dist/i18n/messages/permissions.js +151 -0
- package/dist/i18n/messages/plan.d.ts +123 -0
- package/dist/i18n/messages/plan.js +124 -0
- package/dist/i18n/messages/print.d.ts +86 -0
- package/dist/i18n/messages/print.js +91 -0
- package/dist/i18n/messages/report.d.ts +391 -0
- package/dist/i18n/messages/report.js +490 -0
- package/dist/i18n/messages/rewind.d.ts +198 -0
- package/dist/i18n/messages/rewind.js +217 -0
- package/dist/i18n/messages/session.d.ts +230 -0
- package/dist/i18n/messages/session.js +258 -0
- package/dist/i18n/messages/settings.d.ts +348 -0
- package/dist/i18n/messages/settings.js +336 -0
- package/dist/i18n/messages/subcommands-config.d.ts +111 -0
- package/dist/i18n/messages/subcommands-config.js +127 -0
- package/dist/i18n/messages/subcommands.d.ts +548 -0
- package/dist/i18n/messages/subcommands.js +474 -0
- package/dist/i18n/messages/trace.d.ts +243 -0
- package/dist/i18n/messages/trace.js +238 -0
- package/dist/i18n/types.d.ts +15 -0
- package/dist/i18n/types.js +7 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +2 -0
- package/dist/memory/edit.d.ts +24 -0
- package/dist/memory/edit.js +63 -0
- package/dist/memory/frontmatter.d.ts +37 -0
- package/dist/memory/frontmatter.js +79 -0
- package/dist/memory/index.d.ts +28 -0
- package/dist/memory/index.js +126 -0
- package/dist/memory/lock.d.ts +17 -0
- package/dist/memory/lock.js +62 -0
- package/dist/memory/paths.d.ts +57 -0
- package/dist/memory/paths.js +175 -0
- package/dist/memory/report.d.ts +36 -0
- package/dist/memory/report.js +86 -0
- package/dist/memory/runtime.d.ts +42 -0
- package/dist/memory/runtime.js +36 -0
- package/dist/memory/secrets.d.ts +8 -0
- package/dist/memory/secrets.js +27 -0
- package/dist/memory/section.d.ts +28 -0
- package/dist/memory/section.js +59 -0
- package/dist/memory/store.d.ts +70 -0
- package/dist/memory/store.js +284 -0
- package/dist/memory/tool.d.ts +31 -0
- package/dist/memory/tool.js +94 -0
- package/dist/modes/acp/acp-events.js +2 -1
- package/dist/modes/acp/acp-server.js +13 -12
- package/dist/modes/commands-core.d.ts +17 -0
- package/dist/modes/commands-core.js +101 -61
- package/dist/modes/image-input.js +20 -6
- package/dist/modes/interactive/agent-bar.d.ts +95 -0
- package/dist/modes/interactive/agent-bar.js +248 -0
- package/dist/modes/interactive/agent-panels.js +27 -26
- package/dist/modes/interactive/agent-transcript.d.ts +47 -0
- package/dist/modes/interactive/agent-transcript.js +191 -0
- package/dist/modes/interactive/agent-ui.d.ts +36 -1
- package/dist/modes/interactive/agent-ui.js +180 -14
- package/dist/modes/interactive/agent-view.d.ts +72 -0
- package/dist/modes/interactive/agent-view.js +281 -0
- package/dist/modes/interactive/approval-dialog.js +46 -34
- package/dist/modes/interactive/clipboard-paste.d.ts +2 -2
- package/dist/modes/interactive/clipboard-paste.js +9 -4
- package/dist/modes/interactive/commands.d.ts +22 -1
- package/dist/modes/interactive/commands.js +93 -38
- package/dist/modes/interactive/completion.js +2 -1
- package/dist/modes/interactive/config-panel.d.ts +70 -0
- package/dist/modes/interactive/config-panel.js +319 -0
- package/dist/modes/interactive/config-ui.d.ts +96 -0
- package/dist/modes/interactive/config-ui.js +397 -0
- package/dist/modes/interactive/confirm-dialog.d.ts +49 -0
- package/dist/modes/interactive/confirm-dialog.js +120 -0
- package/dist/modes/interactive/event-notices.js +11 -9
- package/dist/modes/interactive/interactive-mode.d.ts +1 -1
- package/dist/modes/interactive/interactive-mode.js +25 -22
- package/dist/modes/interactive/key-dispatch.d.ts +18 -0
- package/dist/modes/interactive/key-dispatch.js +39 -13
- package/dist/modes/interactive/line/line-editor.js +2 -1
- package/dist/modes/interactive/line/line-mode.d.ts +2 -0
- package/dist/modes/interactive/line/line-mode.js +24 -4
- package/dist/modes/interactive/line/line-render.js +25 -24
- package/dist/modes/interactive/memory-panel.d.ts +64 -0
- package/dist/modes/interactive/memory-panel.js +221 -0
- package/dist/modes/interactive/message-view.d.ts +4 -2
- package/dist/modes/interactive/message-view.js +42 -33
- package/dist/modes/interactive/panels.js +39 -31
- package/dist/modes/interactive/pickers.d.ts +2 -1
- package/dist/modes/interactive/pickers.js +10 -6
- package/dist/modes/interactive/plan-command.d.ts +1 -1
- package/dist/modes/interactive/plan-command.js +24 -27
- package/dist/modes/interactive/plan-dialog.js +18 -17
- package/dist/modes/interactive/plan-flow.js +6 -5
- package/dist/modes/interactive/rewind-command.d.ts +1 -1
- package/dist/modes/interactive/rewind-command.js +18 -16
- package/dist/modes/interactive/rewind-flow.d.ts +0 -1
- package/dist/modes/interactive/rewind-flow.js +13 -14
- package/dist/modes/interactive/rewind-list.js +7 -6
- package/dist/modes/interactive/rewind-panel.js +40 -40
- package/dist/modes/interactive/rewind-text.d.ts +5 -3
- package/dist/modes/interactive/rewind-text.js +48 -38
- package/dist/modes/interactive/run-indicator.js +15 -12
- package/dist/modes/interactive/session-events.js +3 -2
- package/dist/modes/interactive/startup-header.js +22 -23
- package/dist/modes/interactive/startup-ui.js +41 -29
- package/dist/modes/interactive/status-area.d.ts +2 -0
- package/dist/modes/interactive/status-area.js +8 -2
- package/dist/modes/interactive/status-bar.js +4 -3
- package/dist/modes/interactive/subagent-view.js +9 -7
- package/dist/modes/interactive/tasks-report.d.ts +6 -0
- package/dist/modes/interactive/tasks-report.js +28 -31
- package/dist/modes/interactive/terminal-setup.d.ts +9 -0
- package/dist/modes/interactive/terminal-setup.js +23 -0
- package/dist/modes/interactive/tool-summary.js +19 -17
- package/dist/modes/interactive/tool-view.js +7 -4
- package/dist/modes/interactive/trace-view.d.ts +89 -0
- package/dist/modes/interactive/trace-view.js +332 -0
- package/dist/modes/print/print-mode.js +14 -15
- package/dist/modes/rpc/commands.js +7 -3
- package/dist/modes/rpc/rpc-mode.js +9 -3
- package/dist/modes/session-report.d.ts +2 -0
- package/dist/modes/session-report.js +101 -105
- package/dist/modes/startup-ui-text.js +11 -6
- package/dist/permissions/bypass.d.ts +30 -0
- package/dist/permissions/bypass.js +45 -0
- package/dist/permissions/memory-class.d.ts +23 -0
- package/dist/permissions/memory-class.js +54 -0
- package/dist/permissions/modes.d.ts +3 -3
- package/dist/permissions/modes.js +21 -16
- package/dist/permissions/pipeline.d.ts +1 -1
- package/dist/permissions/pipeline.js +9 -2
- package/dist/permissions/preview.js +49 -42
- package/dist/permissions/rules.js +5 -2
- package/dist/permissions/types.d.ts +4 -0
- package/dist/plan/store.js +2 -1
- package/dist/rpc.d.ts +39 -1
- package/dist/rpc.js +3 -0
- package/dist/sandbox/bash.js +11 -8
- package/dist/sandbox/detect.js +14 -11
- package/dist/sdk.d.ts +17 -1
- package/dist/sdk.js +29 -7
- package/dist/session/export.js +31 -30
- package/dist/session/manager.d.ts +1 -1
- package/dist/session/manager.js +5 -3
- package/dist/session/reuse.js +5 -4
- package/dist/session/scan.js +3 -2
- package/dist/session/stats-aggregate.d.ts +3 -1
- package/dist/session/stats-aggregate.js +5 -1
- package/dist/session/stats-index.js +2 -1
- package/dist/session/stats-scan.d.ts +4 -1
- package/dist/session/stats-scan.js +6 -2
- package/dist/session/store.d.ts +11 -0
- package/dist/session/store.js +48 -1
- package/dist/session/types.d.ts +2 -0
- package/dist/skills/builtin.js +2 -1
- package/dist/tools/image-file.d.ts +26 -1
- package/dist/tools/image-file.js +55 -13
- package/dist/tools/presets.d.ts +14 -1
- package/dist/tools/presets.js +3 -3
- package/dist/tools/registry.js +1 -1
- package/dist/tools/truncate.d.ts +1 -1
- package/dist/tools/truncate.js +2 -2
- package/dist/tools/types.d.ts +17 -1
- package/dist/trace/build-index.d.ts +91 -0
- package/dist/trace/build-index.js +127 -0
- package/dist/trace/build-nodes.d.ts +24 -0
- package/dist/trace/build-nodes.js +279 -0
- package/dist/trace/build-util.d.ts +43 -0
- package/dist/trace/build-util.js +120 -0
- package/dist/trace/build.d.ts +82 -0
- package/dist/trace/build.js +382 -0
- package/dist/trace/detail.d.ts +35 -0
- package/dist/trace/detail.js +205 -0
- package/dist/trace/flatten.d.ts +69 -0
- package/dist/trace/flatten.js +173 -0
- package/dist/trace/format.d.ts +47 -0
- package/dist/trace/format.js +329 -0
- package/dist/trace/html-template.d.ts +19 -0
- package/dist/trace/html-template.js +150 -0
- package/dist/trace/html.d.ts +104 -0
- package/dist/trace/html.js +292 -0
- package/dist/trace/preview.d.ts +29 -0
- package/dist/trace/preview.js +59 -0
- package/dist/trace/query-session.d.ts +14 -0
- package/dist/trace/query-session.js +38 -0
- package/dist/trace/query.d.ts +55 -0
- package/dist/trace/query.js +188 -0
- package/dist/trace/session.d.ts +40 -0
- package/dist/trace/session.js +168 -0
- package/dist/trace/types.d.ts +243 -0
- package/dist/trace/types.js +13 -0
- package/dist/tui/components/editor-paste.d.ts +2 -0
- package/dist/tui/components/editor-paste.js +6 -3
- package/dist/tui/components/editor.js +2 -2
- package/dist/tui/components/loader.d.ts +3 -0
- package/dist/tui/components/loader.js +14 -0
- package/dist/tui/components/settings-list.d.ts +61 -0
- package/dist/tui/components/settings-list.js +135 -0
- package/dist/tui/keybindings.d.ts +6 -1
- package/dist/tui/keybindings.js +18 -6
- package/dist/tui.d.ts +1 -0
- package/dist/tui.js +2 -0
- package/docs/en/host-api.md +167 -0
- package/docs/en/permissions.md +214 -0
- package/docs/en/providers.md +625 -0
- package/docs/en/rpc.md +361 -0
- package/docs/en/sessions.md +219 -0
- package/docs/en/tui.md +527 -0
- package/docs/host-api.md +18 -17
- package/docs/memory.md +172 -0
- package/docs/permissions.md +3 -2
- package/docs/providers.md +67 -1
- package/docs/rpc.md +31 -3
- package/docs/session-format.md +8 -2
- package/docs/sessions.md +29 -1
- package/docs/tui.md +189 -21
- package/package.json +8 -3
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 轨迹构建器(docs/wave6-plan.md §2.3、D6)。[W6-T1]
|
|
3
|
+
*
|
|
4
|
+
* `buildTrace(input, opts)` 把会话条目重建成 `Trace`(Turn → Step → Tool → Subcall / Subagent):
|
|
5
|
+
* TUI `/trace`、`ama sessions trace`、RPC `get_trace` 三方共用同一棵树。
|
|
6
|
+
*
|
|
7
|
+
* 性质:
|
|
8
|
+
* - **纯函数**:不读时钟、不做 I/O;子会话经 `opts.loadChild` 回调读取(深度 ≤ 1:子轨迹里不再展开孙任务)。
|
|
9
|
+
* - **确定性**:同样的输入(含 `opts.now` / `opts.live`)得到逐字节相同的 JSON;节点顺序 = 条目顺序。
|
|
10
|
+
* - **不改历史**:老会话没有 `ama.trace` 时按条目时间回退推算并标 `approx`;推算出的时间不写回文件。
|
|
11
|
+
* - **容忍**:未知条目、未知 customType、损坏的 data 一律跳过;子会话缺失或读取抛错标 `childMissing`。
|
|
12
|
+
* - **不含正文**:只有 id、时间、计数与用量;提示 / 参数 / 结果的预览由调用方按 `entryIds` 回条目取。
|
|
13
|
+
*
|
|
14
|
+
* 算法:选分支(leaf = 根 → 叶子;all = 文件顺序)→ 预建索引(`ama.trace` 按 assistant / toolCall /
|
|
15
|
+
* compaction / usage 条目 id,`ama.task` 按父 toolCallId,`external_turn` 按 taskId,`context_edit` 的
|
|
16
|
+
* retry / overflow 目标)→ 顺序扫描建节点 → 叠加 `live` → 汇总。推算规则:`requestAt = assistant.timestamp`、
|
|
17
|
+
* `doneAt = 条目时间`、工具 `startedAt = assistant 条目时间`、`endedAt = toolResult.timestamp`;ttft 分位与
|
|
18
|
+
* 平均吞吐只用精确(非 approx)的 step。
|
|
19
|
+
*
|
|
20
|
+
* 汇总口径:`requests` 与 token / 费用和 `usageTotals`(session/export.ts)一致(assistant + 压缩 / 分支摘要 +
|
|
21
|
+
* `usage` 条目;进行中的请求不计);`durationMs` = 各回合耗时之和(不含回合之间的空闲);回合的 `endedAt`
|
|
22
|
+
* 不被后台子 Agent 拉长;文件里 `status: "running"` 的任务在没有 `live` 时视为 `interrupted`。
|
|
23
|
+
*/
|
|
24
|
+
import { indexEntries, pathToRoot } from "../session/tree.js";
|
|
25
|
+
import { buildIndex, entryTime, num, splitRef, traceData, zeroUsage, } from "./build-index.js";
|
|
26
|
+
import { abortedRequest, assistantStep, compactionAsAux, compactionNode, externalNodes, pushUsage, retryNode, subagentNode, } from "./build-nodes.js";
|
|
27
|
+
import { accumulate, emptyTotals, finishTotals, maxDefined, mergeTotals } from "./build-util.js";
|
|
28
|
+
import {} from "./types.js";
|
|
29
|
+
/** 所选分支的条目。 */
|
|
30
|
+
export function selectTraceEntries(input, branch = "leaf") {
|
|
31
|
+
if (branch === "all")
|
|
32
|
+
return [...input.entries];
|
|
33
|
+
const leaf = input.leaf === undefined ? (input.entries.at(-1)?.id ?? null) : input.leaf;
|
|
34
|
+
return pathToRoot(indexEntries(input.entries), leaf);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* 从会话条目构建轨迹树。见文件头的性质与算法;选项见 `BuildTraceOptions`。
|
|
38
|
+
*/
|
|
39
|
+
export function buildTrace(input, opts = {}) {
|
|
40
|
+
const entries = selectTraceEntries(input, opts.branch ?? "leaf");
|
|
41
|
+
const index = buildIndex(entries);
|
|
42
|
+
const state = {
|
|
43
|
+
turns: [],
|
|
44
|
+
aux: [],
|
|
45
|
+
turn: undefined,
|
|
46
|
+
turnModel: undefined,
|
|
47
|
+
model: undefined,
|
|
48
|
+
tools: new Map(),
|
|
49
|
+
resolved: new Set(),
|
|
50
|
+
extraUsage: new Map(),
|
|
51
|
+
};
|
|
52
|
+
const openTurn = (id, startedAt, origin) => {
|
|
53
|
+
const turn = {
|
|
54
|
+
id,
|
|
55
|
+
kind: "turn",
|
|
56
|
+
status: "ok",
|
|
57
|
+
entryIds: [id],
|
|
58
|
+
steps: [],
|
|
59
|
+
usage: emptyTotals(),
|
|
60
|
+
};
|
|
61
|
+
if (startedAt !== undefined)
|
|
62
|
+
turn.startedAt = startedAt;
|
|
63
|
+
if (origin !== undefined)
|
|
64
|
+
turn.origin = origin;
|
|
65
|
+
state.turns.push(turn);
|
|
66
|
+
state.turn = turn;
|
|
67
|
+
state.turnModel = state.model;
|
|
68
|
+
return turn;
|
|
69
|
+
};
|
|
70
|
+
const currentTurn = (entry, at) => state.turn ?? openTurn(entry.id, at);
|
|
71
|
+
for (const entry of entries) {
|
|
72
|
+
const at = entryTime(entry);
|
|
73
|
+
switch (entry.type) {
|
|
74
|
+
case "model_change":
|
|
75
|
+
state.model = `${entry.provider}/${entry.modelId}`;
|
|
76
|
+
break;
|
|
77
|
+
case "message": {
|
|
78
|
+
const m = entry.message;
|
|
79
|
+
if (m.role === "user") {
|
|
80
|
+
if (m.origin === "steer" && state.turn !== undefined)
|
|
81
|
+
state.turn.entryIds.push(entry.id);
|
|
82
|
+
else
|
|
83
|
+
openTurn(entry.id, num(m.timestamp) ?? at, m.origin);
|
|
84
|
+
}
|
|
85
|
+
else if (m.role === "assistant") {
|
|
86
|
+
const turn = currentTurn(entry, num(m.timestamp) ?? at);
|
|
87
|
+
turn.steps.push(assistantStep(entry.id, m, at, turn, state, index));
|
|
88
|
+
}
|
|
89
|
+
else if (m.role === "toolResult") {
|
|
90
|
+
const tool = state.tools.get(m.toolCallId);
|
|
91
|
+
if (tool === undefined)
|
|
92
|
+
break;
|
|
93
|
+
state.resolved.add(tool.id);
|
|
94
|
+
tool.entryIds.push(entry.id);
|
|
95
|
+
tool.isError = m.isError === true;
|
|
96
|
+
if (tool.status !== "denied")
|
|
97
|
+
tool.status = tool.isError ? "error" : "ok";
|
|
98
|
+
if (tool.approx === true) {
|
|
99
|
+
const end = num(m.timestamp) ?? at;
|
|
100
|
+
if (end !== undefined)
|
|
101
|
+
tool.endedAt = end;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
case "compaction": {
|
|
107
|
+
const turn = state.turn;
|
|
108
|
+
const node = compactionNode(entry.id, at, index.compactionByEntry.get(entry.id));
|
|
109
|
+
node.tokensBefore = entry.tokensBefore;
|
|
110
|
+
if (turn === undefined)
|
|
111
|
+
state.aux.push(compactionAsAux(node, entry.usage));
|
|
112
|
+
else {
|
|
113
|
+
turn.steps.push(node);
|
|
114
|
+
if (entry.usage !== undefined)
|
|
115
|
+
pushUsage(state, turn.id, entry.usage);
|
|
116
|
+
}
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
case "branch_summary":
|
|
120
|
+
if (state.turn !== undefined && entry.usage !== undefined)
|
|
121
|
+
pushUsage(state, state.turn.id, entry.usage);
|
|
122
|
+
break;
|
|
123
|
+
case "usage": {
|
|
124
|
+
const trace = index.auxByUsage.get(entry.id);
|
|
125
|
+
const node = {
|
|
126
|
+
id: entry.id,
|
|
127
|
+
kind: "aux",
|
|
128
|
+
purpose: trace?.data.purpose ?? entry.kind,
|
|
129
|
+
status: "ok",
|
|
130
|
+
entryIds: trace === undefined ? [entry.id] : [entry.id, trace.entryId],
|
|
131
|
+
usage: entry.usage,
|
|
132
|
+
};
|
|
133
|
+
const started = num(trace?.data.startedAt);
|
|
134
|
+
const ended = num(trace?.data.endedAt) ?? at;
|
|
135
|
+
if (started !== undefined)
|
|
136
|
+
node.startedAt = started;
|
|
137
|
+
if (ended !== undefined)
|
|
138
|
+
node.endedAt = ended;
|
|
139
|
+
if (started === undefined)
|
|
140
|
+
node.approx = true;
|
|
141
|
+
state.aux.push(node);
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
case "custom": {
|
|
145
|
+
const data = traceData(entry);
|
|
146
|
+
if (data === undefined || state.turn === undefined)
|
|
147
|
+
break;
|
|
148
|
+
if (data.kind === "retry_wait")
|
|
149
|
+
state.turn.steps.push(retryNode(entry.id, data));
|
|
150
|
+
else if (data.kind === "compaction" && typeof data.compactionEntryId !== "string") {
|
|
151
|
+
// 中断的压缩没有 compaction 条目,只有这一条
|
|
152
|
+
state.turn.steps.push(compactionNode(entry.id, at, { data, entryId: entry.id }));
|
|
153
|
+
}
|
|
154
|
+
else if (data.kind === "step" && typeof data.assistantEntryId !== "string")
|
|
155
|
+
abortedRequest(entry.id, data, state);
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
default:
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
attachTasks(state, index, opts);
|
|
163
|
+
applyLive(state, opts.live);
|
|
164
|
+
return finish(input, state, opts);
|
|
165
|
+
}
|
|
166
|
+
function attachTasks(state, index, opts) {
|
|
167
|
+
for (const tool of state.tools.values()) {
|
|
168
|
+
const tasks = index.tasks.get(tool.id);
|
|
169
|
+
if (tasks === undefined)
|
|
170
|
+
continue;
|
|
171
|
+
for (const { data, entryId } of tasks.values()) {
|
|
172
|
+
const node = subagentNode(data, entryId, opts.live !== undefined);
|
|
173
|
+
const external = index.external.get(data.taskId);
|
|
174
|
+
if (external !== undefined)
|
|
175
|
+
node.external = externalNodes(data.taskId, external);
|
|
176
|
+
const file = node.childRef?.sessionFile;
|
|
177
|
+
if (opts.loadChild !== undefined && file !== undefined && node.runner === "ama")
|
|
178
|
+
loadSubagentTrace(node, opts.loadChild, opts.now);
|
|
179
|
+
tool.children.push(node);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* 懒加载 ama 子 Agent 的子轨迹(就地写 `node.child` / `node.childMissing`,返回子轨迹)。深度 ≤ 1:
|
|
185
|
+
* 子轨迹里的任务不再展开。外部 runner 或没有会话文件时返回 undefined 且不标缺失。
|
|
186
|
+
*/
|
|
187
|
+
export function loadSubagentTrace(node, loadChild, now) {
|
|
188
|
+
if (node.child !== undefined)
|
|
189
|
+
return node.child;
|
|
190
|
+
const file = node.childRef?.sessionFile;
|
|
191
|
+
if (file === undefined || node.runner !== "ama")
|
|
192
|
+
return undefined;
|
|
193
|
+
let input;
|
|
194
|
+
try {
|
|
195
|
+
input = loadChild(file);
|
|
196
|
+
}
|
|
197
|
+
catch {
|
|
198
|
+
input = undefined;
|
|
199
|
+
}
|
|
200
|
+
if (input === undefined) {
|
|
201
|
+
node.childMissing = true;
|
|
202
|
+
return undefined;
|
|
203
|
+
}
|
|
204
|
+
try {
|
|
205
|
+
const child = buildTrace({ ...input, sessionFile: input.sessionFile ?? file }, now === undefined ? {} : { now });
|
|
206
|
+
node.child = child;
|
|
207
|
+
delete node.childMissing;
|
|
208
|
+
return child;
|
|
209
|
+
}
|
|
210
|
+
catch {
|
|
211
|
+
node.childMissing = true;
|
|
212
|
+
return undefined;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
function applyLive(state, live) {
|
|
216
|
+
for (const tool of state.tools.values()) {
|
|
217
|
+
if (state.resolved.has(tool.id) || tool.status === "denied")
|
|
218
|
+
continue;
|
|
219
|
+
tool.status = live?.running === true ? "running" : "interrupted";
|
|
220
|
+
}
|
|
221
|
+
if (live === undefined)
|
|
222
|
+
return;
|
|
223
|
+
for (const lt of live.tools ?? []) {
|
|
224
|
+
if (lt.parentId !== undefined) {
|
|
225
|
+
const parent = state.tools.get(lt.parentId);
|
|
226
|
+
if (parent === undefined)
|
|
227
|
+
continue;
|
|
228
|
+
const existing = parent.children.find((c) => c.kind === "subcall" && c.id === lt.id);
|
|
229
|
+
if (existing !== undefined) {
|
|
230
|
+
existing.status = "running";
|
|
231
|
+
delete existing.endedAt;
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
parent.children.push({
|
|
235
|
+
id: lt.id,
|
|
236
|
+
kind: "subcall",
|
|
237
|
+
name: lt.name,
|
|
238
|
+
parentToolCallId: lt.parentId,
|
|
239
|
+
isError: false,
|
|
240
|
+
status: "running",
|
|
241
|
+
startedAt: lt.startedAt,
|
|
242
|
+
entryIds: [],
|
|
243
|
+
});
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
const tool = state.tools.get(lt.id);
|
|
247
|
+
if (tool === undefined || state.resolved.has(tool.id))
|
|
248
|
+
continue;
|
|
249
|
+
tool.status = "running";
|
|
250
|
+
tool.startedAt = lt.startedAt;
|
|
251
|
+
delete tool.endedAt;
|
|
252
|
+
delete tool.approx;
|
|
253
|
+
}
|
|
254
|
+
const turn = state.turn;
|
|
255
|
+
const request = live.request;
|
|
256
|
+
if (request !== undefined && turn !== undefined) {
|
|
257
|
+
const ref = splitRef(state.model);
|
|
258
|
+
const step = {
|
|
259
|
+
id: `live:${request.requestAt}`,
|
|
260
|
+
kind: "step",
|
|
261
|
+
status: "running",
|
|
262
|
+
entryIds: [],
|
|
263
|
+
provider: request.provider ?? ref.provider,
|
|
264
|
+
model: request.model ?? ref.model,
|
|
265
|
+
attempt: 1,
|
|
266
|
+
usage: { ...zeroUsage(), output: request.outputTokens ?? 0 },
|
|
267
|
+
stopReason: "",
|
|
268
|
+
requestAt: request.requestAt,
|
|
269
|
+
startedAt: request.requestAt,
|
|
270
|
+
tools: [],
|
|
271
|
+
};
|
|
272
|
+
if (request.firstTokenAt !== undefined) {
|
|
273
|
+
step.firstTokenAt = request.firstTokenAt;
|
|
274
|
+
step.ttftMs = Math.max(0, request.firstTokenAt - request.requestAt);
|
|
275
|
+
}
|
|
276
|
+
turn.steps.push(step);
|
|
277
|
+
}
|
|
278
|
+
if (live.running && turn !== undefined)
|
|
279
|
+
turn.status = "running";
|
|
280
|
+
}
|
|
281
|
+
function finish(input, state, opts) {
|
|
282
|
+
const all = emptyTotals();
|
|
283
|
+
let partial = false;
|
|
284
|
+
let endedAt;
|
|
285
|
+
let duration = 0;
|
|
286
|
+
let timed = false;
|
|
287
|
+
for (const turn of state.turns) {
|
|
288
|
+
const totals = emptyTotals();
|
|
289
|
+
let end;
|
|
290
|
+
let running = turn.status === "running";
|
|
291
|
+
let interrupted = false;
|
|
292
|
+
for (const node of turn.steps) {
|
|
293
|
+
if (node.approx === true)
|
|
294
|
+
turn.approx = true;
|
|
295
|
+
end = maxDefined(end, node.endedAt);
|
|
296
|
+
if (node.status === "running")
|
|
297
|
+
running = true;
|
|
298
|
+
if (node.kind !== "step")
|
|
299
|
+
continue;
|
|
300
|
+
accumulate(totals, node);
|
|
301
|
+
for (const tool of node.tools) {
|
|
302
|
+
totals.toolCalls++;
|
|
303
|
+
if (tool.approx === true)
|
|
304
|
+
turn.approx = true;
|
|
305
|
+
if (tool.status === "running")
|
|
306
|
+
running = true;
|
|
307
|
+
if (tool.status === "interrupted")
|
|
308
|
+
interrupted = true;
|
|
309
|
+
end = maxDefined(end, tool.endedAt);
|
|
310
|
+
for (const child of tool.children) {
|
|
311
|
+
if (child.status === "running")
|
|
312
|
+
running = running || child.kind === "subcall";
|
|
313
|
+
// 后台任务可能在回合结束后很久才结束,不拉长回合
|
|
314
|
+
if (child.kind === "subcall" || !child.background)
|
|
315
|
+
end = maxDefined(end, child.endedAt);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
for (const usage of state.extraUsage.get(turn.id) ?? [])
|
|
320
|
+
accumulate(totals, { usage });
|
|
321
|
+
const last = [...turn.steps].reverse().find((s) => s.kind === "step");
|
|
322
|
+
if (running) {
|
|
323
|
+
turn.status = "running";
|
|
324
|
+
partial = true;
|
|
325
|
+
}
|
|
326
|
+
else if (interrupted)
|
|
327
|
+
turn.status = "interrupted";
|
|
328
|
+
else if (last?.status === "aborted")
|
|
329
|
+
turn.status = "aborted";
|
|
330
|
+
else if (last?.status === "error")
|
|
331
|
+
turn.status = "error";
|
|
332
|
+
if (!running && end !== undefined)
|
|
333
|
+
turn.endedAt = Math.max(end, turn.startedAt ?? end);
|
|
334
|
+
if (turn.startedAt !== undefined && turn.endedAt !== undefined) {
|
|
335
|
+
totals.durationMs = turn.endedAt - turn.startedAt;
|
|
336
|
+
duration += totals.durationMs;
|
|
337
|
+
timed = true;
|
|
338
|
+
}
|
|
339
|
+
turn.usage = finishTotals(totals);
|
|
340
|
+
mergeTotals(all, totals);
|
|
341
|
+
endedAt = maxDefined(endedAt, turn.endedAt);
|
|
342
|
+
}
|
|
343
|
+
for (const aux of state.aux) {
|
|
344
|
+
if (aux.usage !== undefined)
|
|
345
|
+
accumulate(all, { usage: aux.usage });
|
|
346
|
+
endedAt = maxDefined(endedAt, aux.endedAt);
|
|
347
|
+
}
|
|
348
|
+
if (timed)
|
|
349
|
+
all.durationMs = duration;
|
|
350
|
+
const startedAt = entryTime(input.header) ??
|
|
351
|
+
(input.entries[0] !== undefined ? entryTime(input.entries[0]) : undefined) ??
|
|
352
|
+
opts.now ??
|
|
353
|
+
0;
|
|
354
|
+
const trace = {
|
|
355
|
+
version: 1,
|
|
356
|
+
sessionId: input.header.id,
|
|
357
|
+
cwd: input.header.cwd,
|
|
358
|
+
startedAt,
|
|
359
|
+
totals: finishTotals(all),
|
|
360
|
+
turns: state.turns,
|
|
361
|
+
aux: state.aux,
|
|
362
|
+
partial,
|
|
363
|
+
};
|
|
364
|
+
if (input.sessionFile !== undefined)
|
|
365
|
+
trace.sessionFile = input.sessionFile;
|
|
366
|
+
if (!partial && endedAt !== undefined)
|
|
367
|
+
trace.endedAt = endedAt;
|
|
368
|
+
return trace;
|
|
369
|
+
}
|
|
370
|
+
/** 在轨迹里找任务(子 Agent 节点);深度优先,先找到的为准。 */
|
|
371
|
+
export function findSubagent(trace, taskId) {
|
|
372
|
+
for (const turn of trace.turns)
|
|
373
|
+
for (const step of turn.steps) {
|
|
374
|
+
if (step.kind !== "step")
|
|
375
|
+
continue;
|
|
376
|
+
for (const tool of step.tools)
|
|
377
|
+
for (const child of tool.children)
|
|
378
|
+
if (child.kind === "subagent" && child.taskId === taskId)
|
|
379
|
+
return child;
|
|
380
|
+
}
|
|
381
|
+
return undefined;
|
|
382
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 轨迹节点的正文预览与详情卡片(docs/wave6-plan.md §2.4:Enter 详情——概要 / 用量与缓存 / 参数与结果预览)。
|
|
3
|
+
* [W6-T1]
|
|
4
|
+
*
|
|
5
|
+
* 轨迹树不含正文;这里按节点的 `entryIds` 回会话条目取:回合 → 用户提示,请求 → 助手文字,工具 → 参数
|
|
6
|
+
* (JSON,截到 500 字符)与结果(截到 2000 字符),与 `sessions export --format md` 同一截断口径。
|
|
7
|
+
* 只给本机界面用(TUI 详情、line 模式标签);HTML / RPC 的预览由 W6-T2 另行脱敏。
|
|
8
|
+
*/
|
|
9
|
+
import type { SessionEntry } from "../session/types.js";
|
|
10
|
+
import type { Theme } from "../tui/component.js";
|
|
11
|
+
import type { TraceRowNode } from "./flatten.js";
|
|
12
|
+
/** 参数预览上限(字符)。 */
|
|
13
|
+
export declare const ARGS_PREVIEW_MAX = 500;
|
|
14
|
+
/** 结果 / 提示 / 输出预览上限(字符)。 */
|
|
15
|
+
export declare const RESULT_PREVIEW_MAX = 2000;
|
|
16
|
+
export interface TraceEntryLookup {
|
|
17
|
+
entry(id: string): SessionEntry | undefined;
|
|
18
|
+
/** 工具参数里的路径相对它显示。 */
|
|
19
|
+
cwd?: string;
|
|
20
|
+
}
|
|
21
|
+
/** 由条目数组建查找表。 */
|
|
22
|
+
export declare function entryLookup(entries: readonly SessionEntry[], cwd?: string): TraceEntryLookup;
|
|
23
|
+
/** 行标签里来自正文的部分:回合 → 提示预览,工具 → 参数摘要。 */
|
|
24
|
+
export declare function describeNode(node: TraceRowNode, lookup: TraceEntryLookup): string | undefined;
|
|
25
|
+
/** 详情里的两段预览(标题 → 正文)。 */
|
|
26
|
+
export declare function nodePreviews(node: TraceRowNode, lookup: TraceEntryLookup): {
|
|
27
|
+
title: string;
|
|
28
|
+
text: string;
|
|
29
|
+
}[];
|
|
30
|
+
type Row = [label: string, value: string];
|
|
31
|
+
/** 概要与用量两组键值行。 */
|
|
32
|
+
export declare function summaryRows(node: TraceRowNode, theme: Theme, traceStart: number): Row[];
|
|
33
|
+
/** 详情卡片的行(不含标题与边框;宽度内折行)。 */
|
|
34
|
+
export declare function detailLines(node: TraceRowNode, lookup: TraceEntryLookup, width: number, theme: Theme, traceStart: number): string[];
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 轨迹节点的正文预览与详情卡片(docs/wave6-plan.md §2.4:Enter 详情——概要 / 用量与缓存 / 参数与结果预览)。
|
|
3
|
+
* [W6-T1]
|
|
4
|
+
*
|
|
5
|
+
* 轨迹树不含正文;这里按节点的 `entryIds` 回会话条目取:回合 → 用户提示,请求 → 助手文字,工具 → 参数
|
|
6
|
+
* (JSON,截到 500 字符)与结果(截到 2000 字符),与 `sessions export --format md` 同一截断口径。
|
|
7
|
+
* 只给本机界面用(TUI 详情、line 模式标签);HTML / RPC 的预览由 W6-T2 另行脱敏。
|
|
8
|
+
*/
|
|
9
|
+
import { formatDuration, msg } from "../i18n/index.js";
|
|
10
|
+
import { formatPercent, formatTokenCount, formatUsd } from "../modes/session-report.js";
|
|
11
|
+
import { toolSummary } from "../modes/interactive/tool-summary.js";
|
|
12
|
+
import { contentText } from "../session/reuse.js";
|
|
13
|
+
import { padToWidth, visibleWidth, wrapTextWithAnsi } from "../tui/ansi.js";
|
|
14
|
+
import { durationText } from "./format.js";
|
|
15
|
+
/** 参数预览上限(字符)。 */
|
|
16
|
+
export const ARGS_PREVIEW_MAX = 500;
|
|
17
|
+
/** 结果 / 提示 / 输出预览上限(字符)。 */
|
|
18
|
+
export const RESULT_PREVIEW_MAX = 2000;
|
|
19
|
+
/** 行内标签里的提示预览上限(字符)。 */
|
|
20
|
+
const LABEL_PREVIEW_MAX = 80;
|
|
21
|
+
/** 由条目数组建查找表。 */
|
|
22
|
+
export function entryLookup(entries, cwd) {
|
|
23
|
+
const map = new Map();
|
|
24
|
+
for (const entry of entries)
|
|
25
|
+
map.set(entry.id, entry);
|
|
26
|
+
return { entry: (id) => map.get(id), ...(cwd !== undefined ? { cwd } : {}) };
|
|
27
|
+
}
|
|
28
|
+
function oneLine(text, max) {
|
|
29
|
+
const flat = text.replace(/\s+/g, " ").trim();
|
|
30
|
+
return flat.length > max ? `${flat.slice(0, max - 1)}…` : flat;
|
|
31
|
+
}
|
|
32
|
+
function truncate(text, max) {
|
|
33
|
+
return text.length > max
|
|
34
|
+
? `${text.slice(0, max)}\n${msg().trace.detail.truncated(text.length)}`
|
|
35
|
+
: text;
|
|
36
|
+
}
|
|
37
|
+
function messageOf(lookup, id) {
|
|
38
|
+
const entry = id === undefined ? undefined : lookup.entry(id);
|
|
39
|
+
return entry?.type === "message" ? entry.message : undefined;
|
|
40
|
+
}
|
|
41
|
+
function toolArgs(lookup, node) {
|
|
42
|
+
if (node.kind !== "tool")
|
|
43
|
+
return undefined;
|
|
44
|
+
const m = messageOf(lookup, node.entryIds[0]);
|
|
45
|
+
if (m?.role !== "assistant")
|
|
46
|
+
return undefined;
|
|
47
|
+
for (const block of m.content)
|
|
48
|
+
if (block.type === "toolCall" && block.id === node.id)
|
|
49
|
+
return block.arguments;
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
/** 行标签里来自正文的部分:回合 → 提示预览,工具 → 参数摘要。 */
|
|
53
|
+
export function describeNode(node, lookup) {
|
|
54
|
+
if (node.kind === "turn") {
|
|
55
|
+
const m = messageOf(lookup, node.id);
|
|
56
|
+
return m?.role === "user" ? oneLine(contentText(m.content), LABEL_PREVIEW_MAX) : undefined;
|
|
57
|
+
}
|
|
58
|
+
if (node.kind === "tool") {
|
|
59
|
+
const summary = toolSummary(node.name, toolArgs(lookup, node), lookup.cwd);
|
|
60
|
+
return summary === "" ? undefined : oneLine(summary, LABEL_PREVIEW_MAX);
|
|
61
|
+
}
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
/** 详情里的两段预览(标题 → 正文)。 */
|
|
65
|
+
export function nodePreviews(node, lookup) {
|
|
66
|
+
const d = msg().trace.detail;
|
|
67
|
+
const out = [];
|
|
68
|
+
if (node.kind === "turn") {
|
|
69
|
+
const m = messageOf(lookup, node.id);
|
|
70
|
+
if (m?.role === "user")
|
|
71
|
+
out.push({ title: d.input, text: truncate(contentText(m.content), RESULT_PREVIEW_MAX) });
|
|
72
|
+
}
|
|
73
|
+
else if (node.kind === "step") {
|
|
74
|
+
const m = messageOf(lookup, node.id);
|
|
75
|
+
if (m?.role === "assistant") {
|
|
76
|
+
const text = m.content
|
|
77
|
+
.flatMap((b) => (b.type === "text" && b.text.trim() !== "" ? [b.text] : []))
|
|
78
|
+
.join("\n");
|
|
79
|
+
if (text !== "")
|
|
80
|
+
out.push({ title: d.output, text: truncate(text, RESULT_PREVIEW_MAX) });
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
else if (node.kind === "tool") {
|
|
84
|
+
const args = toolArgs(lookup, node);
|
|
85
|
+
if (args !== undefined)
|
|
86
|
+
out.push({ title: d.args, text: truncate(JSON.stringify(args, null, 2), ARGS_PREVIEW_MAX) });
|
|
87
|
+
const r = messageOf(lookup, node.entryIds[1]);
|
|
88
|
+
if (r?.role === "toolResult")
|
|
89
|
+
out.push({ title: d.result, text: truncate(contentText(r.content), RESULT_PREVIEW_MAX) });
|
|
90
|
+
}
|
|
91
|
+
return out;
|
|
92
|
+
}
|
|
93
|
+
function usageRows(usage, cost) {
|
|
94
|
+
const d = msg().trace.detail;
|
|
95
|
+
if (usage === undefined)
|
|
96
|
+
return [];
|
|
97
|
+
const t = formatTokenCount;
|
|
98
|
+
const rows = [
|
|
99
|
+
[
|
|
100
|
+
d.usage,
|
|
101
|
+
d.usageValue(t(usage.input), t(usage.output), t(usage.cacheRead), t(usage.cacheWrite)),
|
|
102
|
+
],
|
|
103
|
+
];
|
|
104
|
+
const prompt = usage.input + usage.cacheRead + usage.cacheWrite;
|
|
105
|
+
if (prompt > 0)
|
|
106
|
+
rows.push([d.cacheHit, formatPercent(usage.cacheRead / prompt)]);
|
|
107
|
+
if (cost !== undefined)
|
|
108
|
+
rows.push([d.cost, formatUsd(cost)]);
|
|
109
|
+
return rows;
|
|
110
|
+
}
|
|
111
|
+
/** 概要与用量两组键值行。 */
|
|
112
|
+
export function summaryRows(node, theme, traceStart) {
|
|
113
|
+
const d = msg().trace.detail;
|
|
114
|
+
if (node.kind === "more" || node.kind === "aux_group")
|
|
115
|
+
return [];
|
|
116
|
+
const rows = [
|
|
117
|
+
[d.kind, node.kind],
|
|
118
|
+
[d.status, msg().trace.status[node.status]],
|
|
119
|
+
];
|
|
120
|
+
if (node.startedAt !== undefined)
|
|
121
|
+
rows.push([d.start, `+${formatDuration(Math.max(0, node.startedAt - traceStart), "precise")}`]);
|
|
122
|
+
const duration = durationText(node, theme);
|
|
123
|
+
if (duration !== "")
|
|
124
|
+
rows.push([d.duration, duration]);
|
|
125
|
+
if (node.approx === true)
|
|
126
|
+
rows.push([d.approx, d.approxValue]);
|
|
127
|
+
switch (node.kind) {
|
|
128
|
+
case "turn":
|
|
129
|
+
if (node.origin !== undefined)
|
|
130
|
+
rows.push([d.origin, node.origin]);
|
|
131
|
+
rows.push(...usageRows(node.usage, node.usage.cost));
|
|
132
|
+
break;
|
|
133
|
+
case "step":
|
|
134
|
+
rows.push([d.model, `${node.provider}/${node.model}`], [d.attempt, String(node.attempt)]);
|
|
135
|
+
if (node.fallbackFrom !== undefined)
|
|
136
|
+
rows.push([d.fallbackFrom, node.fallbackFrom]);
|
|
137
|
+
if (node.ttftMs !== undefined)
|
|
138
|
+
rows.push([d.ttft, formatDuration(node.ttftMs, "precise")]);
|
|
139
|
+
if (node.tps !== undefined)
|
|
140
|
+
rows.push([d.tps, `${node.tps} tok/s`]);
|
|
141
|
+
if (node.thinkingLevel !== undefined)
|
|
142
|
+
rows.push([d.thinking, node.thinkingLevel]);
|
|
143
|
+
if (node.stopReason !== "")
|
|
144
|
+
rows.push([d.stopReason, node.stopReason]);
|
|
145
|
+
if (node.errorMessage !== undefined)
|
|
146
|
+
rows.push([d.error, node.errorMessage]);
|
|
147
|
+
rows.push(...usageRows(node.usage, node.usage.cost?.total));
|
|
148
|
+
break;
|
|
149
|
+
case "tool":
|
|
150
|
+
if (node.approvalMs !== undefined)
|
|
151
|
+
rows.push([d.approval, formatDuration(node.approvalMs, "precise")]);
|
|
152
|
+
if (node.denied === true)
|
|
153
|
+
rows.push([d.denied, d.yes]);
|
|
154
|
+
break;
|
|
155
|
+
case "subagent":
|
|
156
|
+
rows.push([d.task, `${node.taskId} ${node.agent}`], [d.runner, node.runner]);
|
|
157
|
+
if (node.background)
|
|
158
|
+
rows.push([d.background, d.yes]);
|
|
159
|
+
if (node.turns !== undefined)
|
|
160
|
+
rows.push([d.turns, String(node.turns)]);
|
|
161
|
+
rows.push(...usageRows(node.usage, node.costUsd));
|
|
162
|
+
if (node.childRef?.sessionFile !== undefined)
|
|
163
|
+
rows.push([d.childFile, node.childRef.sessionFile]);
|
|
164
|
+
if (node.childMissing === true)
|
|
165
|
+
rows.push([d.childFile, d.childMissing]);
|
|
166
|
+
break;
|
|
167
|
+
case "external_turn":
|
|
168
|
+
rows.push([d.stopReason, node.stopReason], [d.files, String(node.filesTouched)]);
|
|
169
|
+
if (node.tools.length > 0)
|
|
170
|
+
rows.push([d.tools, node.tools.map((t) => `${t.kind}:${t.status}`).join(" ")]);
|
|
171
|
+
break;
|
|
172
|
+
case "retry_wait":
|
|
173
|
+
if (node.reason !== undefined)
|
|
174
|
+
rows.push([d.reason, node.reason]);
|
|
175
|
+
break;
|
|
176
|
+
case "compaction":
|
|
177
|
+
if (node.tokensBefore !== undefined)
|
|
178
|
+
rows.push([d.usage, formatTokenCount(node.tokensBefore)]);
|
|
179
|
+
break;
|
|
180
|
+
case "aux":
|
|
181
|
+
rows.push(...usageRows(node.usage, node.usage?.cost?.total));
|
|
182
|
+
break;
|
|
183
|
+
default:
|
|
184
|
+
break;
|
|
185
|
+
}
|
|
186
|
+
return rows;
|
|
187
|
+
}
|
|
188
|
+
/** 详情卡片的行(不含标题与边框;宽度内折行)。 */
|
|
189
|
+
export function detailLines(node, lookup, width, theme, traceStart) {
|
|
190
|
+
const rows = summaryRows(node, theme, traceStart);
|
|
191
|
+
// 键列宽取最长的键(en 的 Waiting for approval 比 16 列宽,封顶会让这一行错位)
|
|
192
|
+
const labelWidth = Math.max(0, ...rows.map(([label]) => visibleWidth(label)));
|
|
193
|
+
const out = [];
|
|
194
|
+
const valueWidth = Math.max(8, width - labelWidth - 2);
|
|
195
|
+
for (const [label, value] of rows) {
|
|
196
|
+
const wrapped = wrapTextWithAnsi(value, valueWidth);
|
|
197
|
+
wrapped.forEach((line, i) => out.push(`${i === 0 ? theme.fg("muted", padToWidth(label, labelWidth)) : " ".repeat(labelWidth)} ${line}`));
|
|
198
|
+
}
|
|
199
|
+
for (const preview of nodePreviews(node, lookup)) {
|
|
200
|
+
out.push("", theme.bold(preview.title));
|
|
201
|
+
for (const line of preview.text.split("\n"))
|
|
202
|
+
out.push(...wrapTextWithAnsi(line, Math.max(8, width)));
|
|
203
|
+
}
|
|
204
|
+
return out;
|
|
205
|
+
}
|