@armadra/agent 0.5.1 → 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 -304
- 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 +25928 -11144
- 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.js +8 -6
- 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.js +23 -20
- 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 +1 -1
- package/dist/cli/subcommands/providers.js +45 -50
- 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 +11 -0
- package/dist/modes/commands-core.js +93 -62
- 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 +19 -1
- package/dist/modes/interactive/commands.js +84 -40
- 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.js +6 -7
- 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 +19 -22
- package/dist/modes/interactive/key-dispatch.d.ts +12 -0
- package/dist/modes/interactive/key-dispatch.js +24 -9
- package/dist/modes/interactive/line/line-editor.js +2 -1
- package/dist/modes/interactive/line/line-mode.js +18 -7
- 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 +38 -30
- 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 +8 -10
- package/dist/permissions/bypass.js +19 -10
- 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 +5 -0
- package/dist/tui/keybindings.js +17 -5
- 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 +2 -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 +132 -3
- package/package.json +8 -3
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 轨迹树扁平化(docs/wave6-plan.md §2.4)。[W6-T1]
|
|
3
|
+
*
|
|
4
|
+
* 把 `Trace` 按展开状态摊成行数组(列表模型),TUI 只渲染可见窗口、line 模式整表输出。
|
|
5
|
+
* - 行 key 是从根开始的路径(`t:<turnId>/s:<stepId>/x:<toolCallId>/a:<taskId>/…`),刷新后仍稳定,
|
|
6
|
+
* 展开状态与光标都按 key 记。
|
|
7
|
+
* - 缺省展开:回合与请求展开、工具 / 子 Agent / 子调用折叠(子 Agent 展开即懒加载子轨迹,见 `needsChild`)。
|
|
8
|
+
* - 分页:`fromTurn` 之前的回合折成一行「更早的 N 个回合」(尾部优先);辅助请求(保温 / 分类器 / 回合外的
|
|
9
|
+
* 压缩)在末尾收成一组,缺省折叠。
|
|
10
|
+
* - 每行带所在回合的时间窗 `span`,格式化时据此画条形(同一回合的行共用一个时间轴)。
|
|
11
|
+
*/
|
|
12
|
+
import type { Trace, TraceAuxNode, TraceCompactionNode, TraceExternalTurnNode, TraceRetryWaitNode, TraceStepNode, TraceSubagentNode, TraceSubcallNode, TraceToolNode, TraceTurnNode } from "./types.js";
|
|
13
|
+
/** 轨迹树里的任一节点。 */
|
|
14
|
+
export type TraceNode = TraceTurnNode | TraceStepNode | TraceCompactionNode | TraceRetryWaitNode | TraceToolNode | TraceSubcallNode | TraceSubagentNode | TraceExternalTurnNode | TraceAuxNode;
|
|
15
|
+
/** 分页行:更早的回合。 */
|
|
16
|
+
export interface TraceMoreNode {
|
|
17
|
+
kind: "more";
|
|
18
|
+
id: "more";
|
|
19
|
+
hidden: number;
|
|
20
|
+
}
|
|
21
|
+
/** 末尾的辅助请求组。 */
|
|
22
|
+
export interface TraceAuxGroupNode {
|
|
23
|
+
kind: "aux_group";
|
|
24
|
+
id: "aux";
|
|
25
|
+
nodes: readonly TraceAuxNode[];
|
|
26
|
+
}
|
|
27
|
+
export type TraceRowNode = TraceNode | TraceMoreNode | TraceAuxGroupNode;
|
|
28
|
+
export interface TraceSpan {
|
|
29
|
+
start: number;
|
|
30
|
+
end: number;
|
|
31
|
+
}
|
|
32
|
+
export interface TraceRow {
|
|
33
|
+
/** 路径 key(稳定)。 */
|
|
34
|
+
key: string;
|
|
35
|
+
depth: number;
|
|
36
|
+
node: TraceRowNode;
|
|
37
|
+
/** 所属回合的序号(1 起,按根轨迹计;子轨迹里的行按子轨迹计);分页 / 辅助组为 0。 */
|
|
38
|
+
turn: number;
|
|
39
|
+
/** 条形的时间窗(所属回合的起止);没有可用时间时缺省。 */
|
|
40
|
+
span?: TraceSpan;
|
|
41
|
+
expandable: boolean;
|
|
42
|
+
expanded: boolean;
|
|
43
|
+
}
|
|
44
|
+
export interface FlattenOptions {
|
|
45
|
+
/** 展开状态覆盖(key → 是否展开);没有的按缺省。 */
|
|
46
|
+
expanded?: ReadonlyMap<string, boolean>;
|
|
47
|
+
/** 从第几个回合开始显示(0 起);之前的折成一行。缺省 0。 */
|
|
48
|
+
fromTurn?: number;
|
|
49
|
+
}
|
|
50
|
+
export declare function rowKey(prefix: string, node: TraceNode): string;
|
|
51
|
+
/** 子节点(子 Agent:已加载的子轨迹的回合,或外部骨架)。 */
|
|
52
|
+
export declare function childrenOf(node: TraceRowNode): readonly TraceNode[];
|
|
53
|
+
/** ama 子 Agent 有子会话文件但还没加载(展开时由调用方 `loadSubagentTrace`)。 */
|
|
54
|
+
export declare function needsChild(node: TraceRowNode): node is TraceSubagentNode;
|
|
55
|
+
export declare function isExpandable(node: TraceRowNode): boolean;
|
|
56
|
+
/** 缺省展开:回合与请求。 */
|
|
57
|
+
export declare function defaultExpanded(node: TraceRowNode): boolean;
|
|
58
|
+
/** 回合的时间窗:起点 = 回合开始,终点 = 回合结束或已知的最晚时刻(进行中)。 */
|
|
59
|
+
export declare function turnSpan(turn: TraceTurnNode): TraceSpan | undefined;
|
|
60
|
+
/** 尾部优先分页的起始回合:最后 `page` 个回合。 */
|
|
61
|
+
export declare function tailStart(trace: Trace, page: number): number;
|
|
62
|
+
/** 摊平整棵轨迹(分页 + 展开状态)。 */
|
|
63
|
+
export declare function flattenTrace(trace: Trace, opts?: FlattenOptions): TraceRow[];
|
|
64
|
+
/** 摊平单个节点的子树(`/trace <任务 id>` 以子 Agent 为根)。 */
|
|
65
|
+
export declare function flattenNode(node: TraceNode, opts?: FlattenOptions): TraceRow[];
|
|
66
|
+
/** 按 key 找行下标(没有返回 -1)。 */
|
|
67
|
+
export declare function rowIndex(rows: readonly TraceRow[], key: string): number;
|
|
68
|
+
/** 节点计数(性能测试与 `--format json` 的规模提示用)。 */
|
|
69
|
+
export declare function countNodes(trace: Trace): number;
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 轨迹树扁平化(docs/wave6-plan.md §2.4)。[W6-T1]
|
|
3
|
+
*
|
|
4
|
+
* 把 `Trace` 按展开状态摊成行数组(列表模型),TUI 只渲染可见窗口、line 模式整表输出。
|
|
5
|
+
* - 行 key 是从根开始的路径(`t:<turnId>/s:<stepId>/x:<toolCallId>/a:<taskId>/…`),刷新后仍稳定,
|
|
6
|
+
* 展开状态与光标都按 key 记。
|
|
7
|
+
* - 缺省展开:回合与请求展开、工具 / 子 Agent / 子调用折叠(子 Agent 展开即懒加载子轨迹,见 `needsChild`)。
|
|
8
|
+
* - 分页:`fromTurn` 之前的回合折成一行「更早的 N 个回合」(尾部优先);辅助请求(保温 / 分类器 / 回合外的
|
|
9
|
+
* 压缩)在末尾收成一组,缺省折叠。
|
|
10
|
+
* - 每行带所在回合的时间窗 `span`,格式化时据此画条形(同一回合的行共用一个时间轴)。
|
|
11
|
+
*/
|
|
12
|
+
const KEY_CODE = {
|
|
13
|
+
turn: "t",
|
|
14
|
+
step: "s",
|
|
15
|
+
compaction: "c",
|
|
16
|
+
retry_wait: "w",
|
|
17
|
+
tool: "x",
|
|
18
|
+
subcall: "n",
|
|
19
|
+
subagent: "a",
|
|
20
|
+
external_turn: "e",
|
|
21
|
+
aux: "u",
|
|
22
|
+
};
|
|
23
|
+
export function rowKey(prefix, node) {
|
|
24
|
+
return `${prefix}${KEY_CODE[node.kind]}:${node.id}`;
|
|
25
|
+
}
|
|
26
|
+
/** 子节点(子 Agent:已加载的子轨迹的回合,或外部骨架)。 */
|
|
27
|
+
export function childrenOf(node) {
|
|
28
|
+
switch (node.kind) {
|
|
29
|
+
case "turn":
|
|
30
|
+
return node.steps;
|
|
31
|
+
case "step":
|
|
32
|
+
return node.tools;
|
|
33
|
+
case "tool":
|
|
34
|
+
return node.children;
|
|
35
|
+
case "subagent":
|
|
36
|
+
return node.child?.turns ?? node.external ?? [];
|
|
37
|
+
case "aux_group":
|
|
38
|
+
return node.nodes;
|
|
39
|
+
default:
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/** ama 子 Agent 有子会话文件但还没加载(展开时由调用方 `loadSubagentTrace`)。 */
|
|
44
|
+
export function needsChild(node) {
|
|
45
|
+
return (node.kind === "subagent" &&
|
|
46
|
+
node.runner === "ama" &&
|
|
47
|
+
node.child === undefined &&
|
|
48
|
+
node.childMissing !== true &&
|
|
49
|
+
node.childRef?.sessionFile !== undefined);
|
|
50
|
+
}
|
|
51
|
+
export function isExpandable(node) {
|
|
52
|
+
return childrenOf(node).length > 0 || needsChild(node);
|
|
53
|
+
}
|
|
54
|
+
/** 缺省展开:回合与请求。 */
|
|
55
|
+
export function defaultExpanded(node) {
|
|
56
|
+
return node.kind === "turn" || node.kind === "step";
|
|
57
|
+
}
|
|
58
|
+
/** 回合的时间窗:起点 = 回合开始,终点 = 回合结束或已知的最晚时刻(进行中)。 */
|
|
59
|
+
export function turnSpan(turn) {
|
|
60
|
+
const start = turn.startedAt;
|
|
61
|
+
if (start === undefined)
|
|
62
|
+
return undefined;
|
|
63
|
+
let end = turn.endedAt ?? start;
|
|
64
|
+
const see = (t) => {
|
|
65
|
+
if (t !== undefined && t > end)
|
|
66
|
+
end = t;
|
|
67
|
+
};
|
|
68
|
+
for (const node of turn.steps) {
|
|
69
|
+
see(node.startedAt);
|
|
70
|
+
see(node.endedAt);
|
|
71
|
+
if (node.kind !== "step")
|
|
72
|
+
continue;
|
|
73
|
+
see(node.firstTokenAt);
|
|
74
|
+
for (const tool of node.tools) {
|
|
75
|
+
see(tool.startedAt);
|
|
76
|
+
see(tool.endedAt);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return { start, end };
|
|
80
|
+
}
|
|
81
|
+
/** 节点自身的时间窗(子 Agent / 外部回合的子行用)。 */
|
|
82
|
+
function nodeSpan(node) {
|
|
83
|
+
if (node.startedAt === undefined)
|
|
84
|
+
return undefined;
|
|
85
|
+
return { start: node.startedAt, end: node.endedAt ?? node.startedAt };
|
|
86
|
+
}
|
|
87
|
+
/** 尾部优先分页的起始回合:最后 `page` 个回合。 */
|
|
88
|
+
export function tailStart(trace, page) {
|
|
89
|
+
return Math.max(0, trace.turns.length - page);
|
|
90
|
+
}
|
|
91
|
+
function walk(w, node, prefix, depth, turn, span) {
|
|
92
|
+
const key = rowKey(prefix, node);
|
|
93
|
+
const expandable = isExpandable(node);
|
|
94
|
+
const expanded = expandable && (w.expanded.get(key) ?? defaultExpanded(node));
|
|
95
|
+
const row = { key, depth, node, turn, expandable, expanded };
|
|
96
|
+
if (span !== undefined)
|
|
97
|
+
row.span = span;
|
|
98
|
+
w.rows.push(row);
|
|
99
|
+
if (!expanded)
|
|
100
|
+
return;
|
|
101
|
+
const childPrefix = `${key}/`;
|
|
102
|
+
if (node.kind === "subagent") {
|
|
103
|
+
// 子轨迹的回合各用自己的时间窗;外部骨架用子 Agent 的时间窗
|
|
104
|
+
if (node.child !== undefined) {
|
|
105
|
+
node.child.turns.forEach((child, i) => walk(w, child, childPrefix, depth + 1, i + 1, turnSpan(child)));
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const own = nodeSpan(node) ?? span;
|
|
109
|
+
for (const child of node.external ?? [])
|
|
110
|
+
walk(w, child, childPrefix, depth + 1, turn, own);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
for (const child of childrenOf(node))
|
|
114
|
+
walk(w, child, childPrefix, depth + 1, turn, span);
|
|
115
|
+
}
|
|
116
|
+
/** 摊平整棵轨迹(分页 + 展开状态)。 */
|
|
117
|
+
export function flattenTrace(trace, opts = {}) {
|
|
118
|
+
const w = { rows: [], expanded: opts.expanded ?? new Map() };
|
|
119
|
+
const from = Math.max(0, Math.min(opts.fromTurn ?? 0, trace.turns.length));
|
|
120
|
+
if (from > 0)
|
|
121
|
+
w.rows.push({
|
|
122
|
+
key: "more",
|
|
123
|
+
depth: 0,
|
|
124
|
+
node: { kind: "more", id: "more", hidden: from },
|
|
125
|
+
turn: 0,
|
|
126
|
+
expandable: false,
|
|
127
|
+
expanded: false,
|
|
128
|
+
});
|
|
129
|
+
for (let i = from; i < trace.turns.length; i++) {
|
|
130
|
+
const turn = trace.turns[i];
|
|
131
|
+
walk(w, turn, "", 0, i + 1, turnSpan(turn));
|
|
132
|
+
}
|
|
133
|
+
if (trace.aux.length > 0) {
|
|
134
|
+
const group = { kind: "aux_group", id: "aux", nodes: trace.aux };
|
|
135
|
+
const expanded = w.expanded.get("aux") ?? false;
|
|
136
|
+
w.rows.push({ key: "aux", depth: 0, node: group, turn: 0, expandable: true, expanded });
|
|
137
|
+
if (expanded)
|
|
138
|
+
for (const aux of trace.aux)
|
|
139
|
+
walk(w, aux, "aux/", 1, 0, nodeSpan(aux));
|
|
140
|
+
}
|
|
141
|
+
return w.rows;
|
|
142
|
+
}
|
|
143
|
+
/** 摊平单个节点的子树(`/trace <任务 id>` 以子 Agent 为根)。 */
|
|
144
|
+
export function flattenNode(node, opts = {}) {
|
|
145
|
+
const w = { rows: [], expanded: opts.expanded ?? new Map() };
|
|
146
|
+
walk(w, node, "", 0, 0, nodeSpan(node));
|
|
147
|
+
return w.rows;
|
|
148
|
+
}
|
|
149
|
+
/** 按 key 找行下标(没有返回 -1)。 */
|
|
150
|
+
export function rowIndex(rows, key) {
|
|
151
|
+
return rows.findIndex((row) => row.key === key);
|
|
152
|
+
}
|
|
153
|
+
/** 节点计数(性能测试与 `--format json` 的规模提示用)。 */
|
|
154
|
+
export function countNodes(trace) {
|
|
155
|
+
let n = trace.aux.length;
|
|
156
|
+
const visit = (node) => {
|
|
157
|
+
n++;
|
|
158
|
+
if (node.kind === "subagent") {
|
|
159
|
+
if (node.child !== undefined)
|
|
160
|
+
for (const t of node.child.turns)
|
|
161
|
+
visit(t);
|
|
162
|
+
else
|
|
163
|
+
for (const e of node.external ?? [])
|
|
164
|
+
visit(e);
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
for (const child of childrenOf(node))
|
|
168
|
+
visit(child);
|
|
169
|
+
};
|
|
170
|
+
for (const turn of trace.turns)
|
|
171
|
+
visit(turn);
|
|
172
|
+
return n;
|
|
173
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 轨迹行的文本格式(docs/wave6-plan.md §2.4)。[W6-T1]
|
|
3
|
+
*
|
|
4
|
+
* 一行:`光标 缩进 折叠符 状态 标签 耗时 ▕████▒▒▒░░▏ ↑in ↓out 缓存%`
|
|
5
|
+
* - 条形是所在回合的相对时间轴:`▒` = TTFT、`█` = 解码、`░` = 工具、`│` = 进行中节点的起点(不编造时长);
|
|
6
|
+
* ASCII 或无色(`NO_COLOR`)降级为 `[==..--]`(`.` = TTFT、`=` = 解码、`-` = 工具、`|` = 起点)。
|
|
7
|
+
* - 宽 ≥ 60 显示条形与 token 列;宽 < 60 只留「标签 · 耗时」;40 列可用。
|
|
8
|
+
* - 耗时:精确时间 `2.1s`,推算的加 `≈`(ASCII `~`),进行中 `…`。
|
|
9
|
+
* - ↑ = 提示 token(input + cacheRead + cacheWrite),↓ = 输出 token,缓存% = cacheRead / 提示 token。
|
|
10
|
+
*
|
|
11
|
+
* `formatTraceText` 是 line 模式 `/trace` 的整表输出(无条形、不截断)。标签里来自正文的部分(用户提示预览、
|
|
12
|
+
* 工具参数摘要)由调用方经 `describe` 提供——轨迹本身不含正文。
|
|
13
|
+
*/
|
|
14
|
+
import type { Theme } from "../tui/component.js";
|
|
15
|
+
import { type TraceRow, type TraceRowNode } from "./flatten.js";
|
|
16
|
+
import type { Trace } from "./types.js";
|
|
17
|
+
export interface TraceFormatContext {
|
|
18
|
+
theme: Theme;
|
|
19
|
+
/** 来自正文的标签部分:回合 → 用户提示预览,工具 → 参数摘要;没有返回 undefined。 */
|
|
20
|
+
describe?(node: TraceRowNode): string | undefined;
|
|
21
|
+
}
|
|
22
|
+
/** 宽度低于它时去掉条形与 token 列。 */
|
|
23
|
+
export declare const NARROW_WIDTH = 60;
|
|
24
|
+
export declare function barWidth(width: number): number;
|
|
25
|
+
/** 节点耗时文字:精确 `2.1s`、推算 `≈2.1s`、进行中 `…`、没有时间为空。 */
|
|
26
|
+
export declare function durationText(node: TraceRowNode, theme: Theme): string;
|
|
27
|
+
/** 状态记号(完成时为空)。 */
|
|
28
|
+
export declare function statusMark(node: TraceRowNode, theme: Theme): string;
|
|
29
|
+
/** token 列:`↑12k ↓980`(没有用量为空)。 */
|
|
30
|
+
export declare function tokensText(node: TraceRowNode, theme: Theme): string;
|
|
31
|
+
/** 缓存命中列。 */
|
|
32
|
+
export declare function cacheText(node: TraceRowNode): string;
|
|
33
|
+
/** 行标签(不含缩进、折叠符与状态记号)。 */
|
|
34
|
+
export declare function rowLabel(row: TraceRow, ctx: Pick<TraceFormatContext, "describe">): string;
|
|
35
|
+
/** 条形(含两侧括号,共 `width` 列);没有时间窗时为空白。 */
|
|
36
|
+
export declare function barText(row: TraceRow, width: number, theme: Theme): string;
|
|
37
|
+
/** 一行(可见宽恰为 `width`)。`selected` 时行首画光标。 */
|
|
38
|
+
export declare function formatRow(row: TraceRow, width: number, ctx: TraceFormatContext, selected?: boolean): string;
|
|
39
|
+
/** 顶部汇总:回合 · 请求 · 工具 · 总耗时 · ↑↓ · 缓存 · ttft 分位 · 平均吞吐。 */
|
|
40
|
+
export declare function summaryText(trace: Trace, theme: Theme): string;
|
|
41
|
+
/** 整表展开(line 模式与测试):全部节点展开,子调用与子 Agent 也展开。 */
|
|
42
|
+
export declare function expandAll(rows: (expanded: Map<string, boolean>) => TraceRow[]): TraceRow[];
|
|
43
|
+
/**
|
|
44
|
+
* line 模式 `/trace` 的文本:标题 + 汇总 + 全部节点(缩进树),每行「标签 耗时 ↑in ↓out 缓存%」,
|
|
45
|
+
* 不画条形、不截断。
|
|
46
|
+
*/
|
|
47
|
+
export declare function formatTraceText(trace: Trace, ctx: TraceFormatContext, rows?: TraceRow[], title?: string): string;
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 轨迹行的文本格式(docs/wave6-plan.md §2.4)。[W6-T1]
|
|
3
|
+
*
|
|
4
|
+
* 一行:`光标 缩进 折叠符 状态 标签 耗时 ▕████▒▒▒░░▏ ↑in ↓out 缓存%`
|
|
5
|
+
* - 条形是所在回合的相对时间轴:`▒` = TTFT、`█` = 解码、`░` = 工具、`│` = 进行中节点的起点(不编造时长);
|
|
6
|
+
* ASCII 或无色(`NO_COLOR`)降级为 `[==..--]`(`.` = TTFT、`=` = 解码、`-` = 工具、`|` = 起点)。
|
|
7
|
+
* - 宽 ≥ 60 显示条形与 token 列;宽 < 60 只留「标签 · 耗时」;40 列可用。
|
|
8
|
+
* - 耗时:精确时间 `2.1s`,推算的加 `≈`(ASCII `~`),进行中 `…`。
|
|
9
|
+
* - ↑ = 提示 token(input + cacheRead + cacheWrite),↓ = 输出 token,缓存% = cacheRead / 提示 token。
|
|
10
|
+
*
|
|
11
|
+
* `formatTraceText` 是 line 模式 `/trace` 的整表输出(无条形、不截断)。标签里来自正文的部分(用户提示预览、
|
|
12
|
+
* 工具参数摘要)由调用方经 `describe` 提供——轨迹本身不含正文。
|
|
13
|
+
*/
|
|
14
|
+
import { formatDuration, msg } from "../i18n/index.js";
|
|
15
|
+
import { formatPercent, formatTokenCount } from "../modes/session-report.js";
|
|
16
|
+
import { padToWidth, truncateToWidth, visibleWidth } from "../tui/ansi.js";
|
|
17
|
+
import { cacheHitRatio } from "./build-index.js";
|
|
18
|
+
import { flattenTrace, } from "./flatten.js";
|
|
19
|
+
/** 宽度低于它时去掉条形与 token 列。 */
|
|
20
|
+
export const NARROW_WIDTH = 60;
|
|
21
|
+
const DURATION_WIDTH = 7;
|
|
22
|
+
const TOKENS_WIDTH = 13;
|
|
23
|
+
const CACHE_WIDTH = 4;
|
|
24
|
+
/** 缩进上限(深层子 Agent 不把标签挤没)。 */
|
|
25
|
+
const MAX_INDENT = 10;
|
|
26
|
+
export function barWidth(width) {
|
|
27
|
+
return width >= 100 ? 26 : width >= 80 ? 14 : 10;
|
|
28
|
+
}
|
|
29
|
+
function plainBars(theme) {
|
|
30
|
+
return theme.glyphs.ascii || theme.caps.colors === 0;
|
|
31
|
+
}
|
|
32
|
+
/** 节点耗时文字:精确 `2.1s`、推算 `≈2.1s`、进行中 `…`、没有时间为空。 */
|
|
33
|
+
export function durationText(node, theme) {
|
|
34
|
+
if (node.kind === "more" || node.kind === "aux_group")
|
|
35
|
+
return "";
|
|
36
|
+
if (node.status === "running")
|
|
37
|
+
return theme.glyphs.ellipsis;
|
|
38
|
+
if (node.startedAt === undefined || node.endedAt === undefined)
|
|
39
|
+
return "";
|
|
40
|
+
const text = formatDuration(node.endedAt - node.startedAt, "precise");
|
|
41
|
+
return node.approx === true ? `${theme.glyphs.ascii ? "~" : "≈"}${text}` : text;
|
|
42
|
+
}
|
|
43
|
+
const STATUS_COLOR = {
|
|
44
|
+
error: "error",
|
|
45
|
+
denied: "error",
|
|
46
|
+
aborted: "warning",
|
|
47
|
+
interrupted: "warning",
|
|
48
|
+
retried: "warning",
|
|
49
|
+
running: "accent",
|
|
50
|
+
};
|
|
51
|
+
/** 状态记号(完成时为空)。 */
|
|
52
|
+
export function statusMark(node, theme) {
|
|
53
|
+
if (node.kind === "more" || node.kind === "aux_group")
|
|
54
|
+
return "";
|
|
55
|
+
const g = theme.glyphs;
|
|
56
|
+
const mark = {
|
|
57
|
+
error: g.fail,
|
|
58
|
+
denied: g.blocked,
|
|
59
|
+
aborted: g.warn,
|
|
60
|
+
interrupted: g.warn,
|
|
61
|
+
retried: g.retry,
|
|
62
|
+
running: g.spinnerStatic,
|
|
63
|
+
};
|
|
64
|
+
const text = mark[node.status];
|
|
65
|
+
const color = STATUS_COLOR[node.status];
|
|
66
|
+
return text === undefined || color === undefined ? "" : theme.fg(color, text);
|
|
67
|
+
}
|
|
68
|
+
function usageOf(node) {
|
|
69
|
+
switch (node.kind) {
|
|
70
|
+
case "step":
|
|
71
|
+
case "aux":
|
|
72
|
+
case "subagent":
|
|
73
|
+
return node.usage;
|
|
74
|
+
default:
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/** token 列:`↑12k ↓980`(没有用量为空)。 */
|
|
79
|
+
export function tokensText(node, theme) {
|
|
80
|
+
const { arrowUp, arrowDown } = theme.glyphs;
|
|
81
|
+
if (node.kind === "turn") {
|
|
82
|
+
const u = node.usage;
|
|
83
|
+
if (u.requests === 0)
|
|
84
|
+
return "";
|
|
85
|
+
const prompt = u.input + u.cacheRead + u.cacheWrite;
|
|
86
|
+
return `${arrowUp}${formatTokenCount(prompt)} ${arrowDown}${formatTokenCount(u.output)}`;
|
|
87
|
+
}
|
|
88
|
+
const usage = usageOf(node);
|
|
89
|
+
if (usage === undefined)
|
|
90
|
+
return "";
|
|
91
|
+
const prompt = usage.input + usage.cacheRead + usage.cacheWrite;
|
|
92
|
+
if (prompt === 0 && usage.output === 0)
|
|
93
|
+
return "";
|
|
94
|
+
return `${arrowUp}${formatTokenCount(prompt)} ${arrowDown}${formatTokenCount(usage.output)}`;
|
|
95
|
+
}
|
|
96
|
+
/** 缓存命中列。 */
|
|
97
|
+
export function cacheText(node) {
|
|
98
|
+
const ratio = node.kind === "turn" ? node.usage.cacheHitRatio : cacheHitRatio(usageOf(node));
|
|
99
|
+
return ratio === undefined ? "" : formatPercent(ratio);
|
|
100
|
+
}
|
|
101
|
+
function auxLabel(purpose) {
|
|
102
|
+
const aux = msg().trace.row.aux;
|
|
103
|
+
return purpose === "cache_warm"
|
|
104
|
+
? aux.cache_warm
|
|
105
|
+
: purpose === "permission_classify"
|
|
106
|
+
? aux.permission_classify
|
|
107
|
+
: purpose === "compaction"
|
|
108
|
+
? msg().trace.row.compactionPlain
|
|
109
|
+
: purpose;
|
|
110
|
+
}
|
|
111
|
+
/** 行标签(不含缩进、折叠符与状态记号)。 */
|
|
112
|
+
export function rowLabel(row, ctx) {
|
|
113
|
+
const m = msg().trace.row;
|
|
114
|
+
const node = row.node;
|
|
115
|
+
const described = ctx.describe?.(node);
|
|
116
|
+
switch (node.kind) {
|
|
117
|
+
case "more":
|
|
118
|
+
return m.more(node.hidden);
|
|
119
|
+
case "aux_group":
|
|
120
|
+
return m.auxGroup(node.nodes.length);
|
|
121
|
+
case "turn": {
|
|
122
|
+
const text = described ?? "";
|
|
123
|
+
const origin = node.origin;
|
|
124
|
+
return origin === undefined || origin === "followUp"
|
|
125
|
+
? m.turn(row.turn, text).trimEnd()
|
|
126
|
+
: m.turnOrigin(row.turn, origin, text).trimEnd();
|
|
127
|
+
}
|
|
128
|
+
case "step": {
|
|
129
|
+
const base = node.attempt > 1 ? m.stepAttempt(node.model, node.attempt) : m.step(node.model);
|
|
130
|
+
const parts = [base];
|
|
131
|
+
if (node.fallbackFrom !== undefined)
|
|
132
|
+
parts.push(m.fallback(node.fallbackFrom));
|
|
133
|
+
if (node.ttftMs !== undefined)
|
|
134
|
+
parts.push(`ttft ${formatDuration(node.ttftMs, "precise")}`);
|
|
135
|
+
if (node.tps !== undefined)
|
|
136
|
+
parts.push(`${Math.round(node.tps)} tok/s`);
|
|
137
|
+
return parts.join(" · ");
|
|
138
|
+
}
|
|
139
|
+
case "tool":
|
|
140
|
+
return described !== undefined && described !== "" ? `${node.name} ${described}` : node.name;
|
|
141
|
+
case "subcall":
|
|
142
|
+
return described !== undefined && described !== "" ? `${node.name} ${described}` : node.name;
|
|
143
|
+
case "subagent": {
|
|
144
|
+
const base = node.runner === "ama" || node.runner === node.agent
|
|
145
|
+
? m.subagent(node.taskId, node.agent)
|
|
146
|
+
: m.subagentExternal(node.taskId, node.agent, node.runner);
|
|
147
|
+
const parts = [base];
|
|
148
|
+
if (node.background)
|
|
149
|
+
parts.push(m.background);
|
|
150
|
+
if (node.childMissing === true)
|
|
151
|
+
parts.push(m.childMissing);
|
|
152
|
+
return parts.join(" · ");
|
|
153
|
+
}
|
|
154
|
+
case "external_turn":
|
|
155
|
+
return m.externalTurn(node.turn, node.toolCount, node.filesTouched);
|
|
156
|
+
case "compaction":
|
|
157
|
+
return node.trigger === undefined ? m.compactionPlain : m.compaction(node.trigger);
|
|
158
|
+
case "retry_wait":
|
|
159
|
+
return m.retryWait(formatDuration(node.delayMs, "precise"), node.attempt);
|
|
160
|
+
case "aux":
|
|
161
|
+
return auxLabel(node.purpose);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
const DECODE = 3;
|
|
165
|
+
const TTFT = 2;
|
|
166
|
+
const TOOL = 1;
|
|
167
|
+
const MARK = 4;
|
|
168
|
+
function pushSegments(node, out, deep) {
|
|
169
|
+
const running = node.status === "running" && node.endedAt === undefined;
|
|
170
|
+
switch (node.kind) {
|
|
171
|
+
case "step": {
|
|
172
|
+
const start = node.requestAt ?? node.startedAt;
|
|
173
|
+
if (start !== undefined) {
|
|
174
|
+
if (node.firstTokenAt !== undefined) {
|
|
175
|
+
out.push({ from: start, to: node.firstTokenAt, rank: TTFT });
|
|
176
|
+
if (node.doneAt !== undefined)
|
|
177
|
+
out.push({ from: node.firstTokenAt, to: node.doneAt, rank: DECODE });
|
|
178
|
+
}
|
|
179
|
+
else if (node.doneAt !== undefined)
|
|
180
|
+
out.push({ from: start, to: node.doneAt, rank: DECODE });
|
|
181
|
+
if (running)
|
|
182
|
+
out.push({ from: start, to: start, rank: MARK });
|
|
183
|
+
}
|
|
184
|
+
for (const tool of node.tools)
|
|
185
|
+
pushSegments(tool, out, false);
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
case "turn":
|
|
189
|
+
for (const child of node.steps)
|
|
190
|
+
pushSegments(child, out, true);
|
|
191
|
+
return;
|
|
192
|
+
case "retry_wait":
|
|
193
|
+
return;
|
|
194
|
+
default: {
|
|
195
|
+
const start = node.startedAt;
|
|
196
|
+
if (start === undefined)
|
|
197
|
+
return;
|
|
198
|
+
const rank = node.kind === "compaction" || node.kind === "aux" ? DECODE : TOOL;
|
|
199
|
+
if (running)
|
|
200
|
+
out.push({ from: start, to: start, rank: MARK });
|
|
201
|
+
else if (node.endedAt !== undefined)
|
|
202
|
+
out.push({ from: start, to: node.endedAt, rank });
|
|
203
|
+
if (deep && node.kind === "tool")
|
|
204
|
+
for (const child of node.children)
|
|
205
|
+
pushSegments(child, out, false);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
/** 条形(含两侧括号,共 `width` 列);没有时间窗时为空白。 */
|
|
210
|
+
export function barText(row, width, theme) {
|
|
211
|
+
const plain = plainBars(theme);
|
|
212
|
+
const cells = Math.max(1, width - 2);
|
|
213
|
+
const ranks = new Array(cells).fill(0);
|
|
214
|
+
const span = row.span;
|
|
215
|
+
const node = row.node;
|
|
216
|
+
if (span !== undefined && node.kind !== "more" && node.kind !== "aux_group") {
|
|
217
|
+
const segs = [];
|
|
218
|
+
pushSegments(node, segs, true);
|
|
219
|
+
const total = Math.max(1, span.end - span.start);
|
|
220
|
+
const cellOf = (t) => Math.min(cells - 1, Math.max(0, Math.floor(((t - span.start) / total) * cells)));
|
|
221
|
+
for (const seg of segs) {
|
|
222
|
+
const a = cellOf(seg.from);
|
|
223
|
+
const b = seg.to > seg.from ? cellOf(seg.to - 1e-6) : a;
|
|
224
|
+
for (let i = a; i <= b; i++)
|
|
225
|
+
ranks[i] = Math.max(ranks[i], seg.rank);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
const chars = plain ? [" ", "-", ".", "=", "|"] : [" ", "░", "▒", "█", "│"];
|
|
229
|
+
const colors = [undefined, "tool", "muted", "accent", "warning"];
|
|
230
|
+
let body = "";
|
|
231
|
+
for (const rank of ranks) {
|
|
232
|
+
const ch = chars[rank];
|
|
233
|
+
const color = colors[rank];
|
|
234
|
+
body += color === undefined || plain ? ch : theme.fg(color, ch);
|
|
235
|
+
}
|
|
236
|
+
const [open, close] = plain ? ["[", "]"] : ["▕", "▏"];
|
|
237
|
+
return theme.fg("border", open) + body + theme.fg("border", close);
|
|
238
|
+
}
|
|
239
|
+
function labelPart(row, ctx) {
|
|
240
|
+
const g = ctx.theme.glyphs;
|
|
241
|
+
const indent = " ".repeat(Math.min(row.depth * 2, MAX_INDENT));
|
|
242
|
+
const fold = row.expandable ? (row.expanded ? g.collapse : g.expand) : " ";
|
|
243
|
+
const mark = statusMark(row.node, ctx.theme);
|
|
244
|
+
const label = rowLabel(row, ctx);
|
|
245
|
+
const styled = row.node.kind === "turn"
|
|
246
|
+
? ctx.theme.bold(label)
|
|
247
|
+
: row.node.kind === "more" || row.node.kind === "aux_group"
|
|
248
|
+
? ctx.theme.dim(label)
|
|
249
|
+
: label;
|
|
250
|
+
return `${indent}${ctx.theme.fg("dim", fold)} ${mark === "" ? "" : `${mark} `}${styled}`;
|
|
251
|
+
}
|
|
252
|
+
/** 一行(可见宽恰为 `width`)。`selected` 时行首画光标。 */
|
|
253
|
+
export function formatRow(row, width, ctx, selected = false) {
|
|
254
|
+
const theme = ctx.theme;
|
|
255
|
+
const cursor = selected ? theme.fg("accent", theme.glyphs.prompt) : " ";
|
|
256
|
+
const inner = Math.max(1, width - 1);
|
|
257
|
+
const duration = durationText(row.node, theme).padStart(DURATION_WIDTH);
|
|
258
|
+
let right;
|
|
259
|
+
if (width < NARROW_WIDTH)
|
|
260
|
+
right = ` ${duration}`;
|
|
261
|
+
else {
|
|
262
|
+
const bar = barText(row, barWidth(width), theme);
|
|
263
|
+
const tokens = padToWidth(tokensText(row.node, theme), TOKENS_WIDTH);
|
|
264
|
+
const cache = cacheText(row.node).padStart(CACHE_WIDTH);
|
|
265
|
+
right = ` ${duration} ${bar} ${tokens} ${cache}`;
|
|
266
|
+
}
|
|
267
|
+
const labelWidth = Math.max(1, inner - visibleWidth(right));
|
|
268
|
+
const label = padToWidth(truncateToWidth(labelPart(row, ctx), labelWidth, theme.glyphs.ellipsis), labelWidth);
|
|
269
|
+
const line = `${cursor}${label}${theme.fg("muted", right)}`;
|
|
270
|
+
return selected && theme.caps.colors >= 256 ? theme.bg("selection", line) : line;
|
|
271
|
+
}
|
|
272
|
+
/** 顶部汇总:回合 · 请求 · 工具 · 总耗时 · ↑↓ · 缓存 · ttft 分位 · 平均吞吐。 */
|
|
273
|
+
export function summaryText(trace, theme) {
|
|
274
|
+
const m = msg().trace;
|
|
275
|
+
const t = trace.totals;
|
|
276
|
+
const parts = [m.summary(trace.turns.length, t.requests, t.toolCalls)];
|
|
277
|
+
if (t.durationMs !== undefined)
|
|
278
|
+
parts.push(formatDuration(t.durationMs, "precise"));
|
|
279
|
+
if (t.requests > 0) {
|
|
280
|
+
const prompt = t.input + t.cacheRead + t.cacheWrite;
|
|
281
|
+
const { arrowUp, arrowDown } = theme.glyphs;
|
|
282
|
+
parts.push(`${arrowUp}${formatTokenCount(prompt)} ${arrowDown}${formatTokenCount(t.output)}`);
|
|
283
|
+
}
|
|
284
|
+
if (t.cacheHitRatio !== undefined)
|
|
285
|
+
parts.push(m.cache(formatPercent(t.cacheHitRatio)));
|
|
286
|
+
if (t.ttftP50 !== undefined) {
|
|
287
|
+
const p50 = formatDuration(t.ttftP50, "precise");
|
|
288
|
+
const p90 = t.ttftP90 !== undefined ? ` / p90 ${formatDuration(t.ttftP90, "precise")}` : "";
|
|
289
|
+
parts.push(`ttft p50 ${p50}${p90}`);
|
|
290
|
+
}
|
|
291
|
+
if (t.avgTps !== undefined)
|
|
292
|
+
parts.push(`${Math.round(t.avgTps)} tok/s`);
|
|
293
|
+
return parts.join(" · ");
|
|
294
|
+
}
|
|
295
|
+
/** 整表展开(line 模式与测试):全部节点展开,子调用与子 Agent 也展开。 */
|
|
296
|
+
export function expandAll(rows) {
|
|
297
|
+
const expanded = new Map();
|
|
298
|
+
for (let guard = 0; guard < 8; guard++) {
|
|
299
|
+
let changed = false;
|
|
300
|
+
for (const row of rows(expanded))
|
|
301
|
+
if (row.expandable && !row.expanded && row.node.kind !== "more") {
|
|
302
|
+
expanded.set(row.key, true);
|
|
303
|
+
changed = true;
|
|
304
|
+
}
|
|
305
|
+
if (!changed)
|
|
306
|
+
break;
|
|
307
|
+
}
|
|
308
|
+
return rows(expanded);
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* line 模式 `/trace` 的文本:标题 + 汇总 + 全部节点(缩进树),每行「标签 耗时 ↑in ↓out 缓存%」,
|
|
312
|
+
* 不画条形、不截断。
|
|
313
|
+
*/
|
|
314
|
+
export function formatTraceText(trace, ctx, rows = expandAll((expanded) => flattenTrace(trace, { expanded })), title = `${msg().trace.title} · ${summaryText(trace, ctx.theme)}`) {
|
|
315
|
+
const theme = ctx.theme;
|
|
316
|
+
const lines = [title];
|
|
317
|
+
if (rows.length === 0)
|
|
318
|
+
lines.push(msg().trace.empty);
|
|
319
|
+
for (const row of rows) {
|
|
320
|
+
const indent = " ".repeat(row.depth);
|
|
321
|
+
const mark = statusMark(row.node, theme);
|
|
322
|
+
const cols = [durationText(row.node, theme), tokensText(row.node, theme), cacheText(row.node)]
|
|
323
|
+
.filter((c) => c !== "")
|
|
324
|
+
.join(" ");
|
|
325
|
+
const label = `${indent}${mark === "" ? "" : `${mark} `}${rowLabel(row, ctx)}`;
|
|
326
|
+
lines.push(cols === "" ? label : `${label} ${cols}`);
|
|
327
|
+
}
|
|
328
|
+
return `${lines.join("\n")}\n`;
|
|
329
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 轨迹 HTML 的页面骨架、样式与脚本(docs/wave6-plan.md §2.5)。[W6-T2]
|
|
3
|
+
*
|
|
4
|
+
* 全部静态:页面只插入三样东西——`lang`、转义过的 `<title>`、已做脚本安全转义的 JSON(`html.ts`)。
|
|
5
|
+
* 脚本只用 `textContent` / `createElement` 写 DOM,不用 `innerHTML`;没有任何外部资源(CSP 见 `CSP`)。
|
|
6
|
+
*
|
|
7
|
+
* 页面:顶部标题 / 汇总 / 工具栏(搜索、跳到回合、缩放、全部展开 / 折叠、图例);中间是一张表——左列树
|
|
8
|
+
* (sticky)+ 右侧瀑布(横轴 = 会话时间,回合间空闲已压缩,刻度标原始时间);底部详情。行高固定、只建
|
|
9
|
+
* 可见 ±50 行的 DOM(虚拟列表),10k 行也流畅。键:↑↓ 选择、←→ 折叠 / 展开、`/` 搜索、Enter / Shift+Enter
|
|
10
|
+
* 在匹配间跳转、Ctrl + 滚轮缩放。深浅色跟随系统。
|
|
11
|
+
*/
|
|
12
|
+
export declare const CSP = "default-src 'none'; style-src 'unsafe-inline'; script-src 'unsafe-inline'";
|
|
13
|
+
export declare function escapeHtml(text: string): string;
|
|
14
|
+
/** 页面骨架。`json` 必须已经过 `scriptSafeJson`。 */
|
|
15
|
+
export declare function renderPage(parts: {
|
|
16
|
+
lang: string;
|
|
17
|
+
title: string;
|
|
18
|
+
json: string;
|
|
19
|
+
}): string;
|