@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
|
@@ -7,13 +7,14 @@
|
|
|
7
7
|
* (字段缺失或恒 0);其余(读到一点、只有写入)→ `inconclusive`(粒度或 TTL 问题)。
|
|
8
8
|
*
|
|
9
9
|
* 计费动作:执行前打印预估(两次 × `--tokens` × 目录输入价,无价 `$?`);非 TTY 必须 `--yes`
|
|
10
|
-
* (否则退出 2),TTY
|
|
10
|
+
* (否则退出 2),TTY 下方向键选一次「继续 / 取消」(choice-prompt.ts)。`--json` 时预估写 stderr,stdout 只有一个结果对象。
|
|
11
11
|
* 协议层不保留原始响应,「usage 字段」列的是该协议解析时读取的字段名。
|
|
12
12
|
*/
|
|
13
|
-
import { createInterface } from "node:readline/promises";
|
|
14
13
|
import { priceTokens } from "../../ai/cost.js";
|
|
15
14
|
import { UsageError } from "../args.js";
|
|
15
|
+
import { confirmContinue } from "../choice-prompt.js";
|
|
16
16
|
import { ExitCode } from "../exit-codes.js";
|
|
17
|
+
import { msg } from "../../i18n/index.js";
|
|
17
18
|
export const PROBE_DEFAULT_TOKENS = 2048;
|
|
18
19
|
export const PROBE_DEFAULT_GAP_MS = 3000;
|
|
19
20
|
export const PROBE_REQUEST_TIMEOUT_MS = 60_000;
|
|
@@ -56,17 +57,16 @@ export function judgeProbe(first, second) {
|
|
|
56
57
|
return any === 0 ? "silent" : "inconclusive";
|
|
57
58
|
}
|
|
58
59
|
export function probeAdvice(verdict, model, samples = []) {
|
|
60
|
+
const t = msg().subcommands.cacheProbe;
|
|
59
61
|
if (verdict === "silent") {
|
|
60
62
|
// 实测:同一中转的 Kimi 间隔 3 s 两次都是 0、间隔更久才命中——字段存在时提示写入延迟的可能
|
|
61
|
-
const present = samples.some((s) => s.cacheReported === true)
|
|
62
|
-
|
|
63
|
-
: "";
|
|
64
|
-
return `可在 config 里设 providers.${model.provider}.compat.cacheReporting: "silent",状态栏将显示未报告${present}`;
|
|
63
|
+
const present = samples.some((s) => s.cacheReported === true);
|
|
64
|
+
return t.adviceSilent(model.provider, present);
|
|
65
65
|
}
|
|
66
66
|
if (verdict === "inconclusive")
|
|
67
|
-
return
|
|
67
|
+
return t.adviceInconclusive;
|
|
68
68
|
if (model.promptCache === undefined)
|
|
69
|
-
return
|
|
69
|
+
return t.advicePromptCache(model.provider, model.id);
|
|
70
70
|
return undefined;
|
|
71
71
|
}
|
|
72
72
|
function intOption(ctx, name, fallback, min) {
|
|
@@ -75,21 +75,13 @@ function intOption(ctx, name, fallback, min) {
|
|
|
75
75
|
return fallback;
|
|
76
76
|
const value = Number(raw);
|
|
77
77
|
if (!Number.isInteger(value) || value < min)
|
|
78
|
-
throw new UsageError(
|
|
78
|
+
throw new UsageError(msg().subcommands.cacheProbe.intAtLeast(name, min));
|
|
79
79
|
return value;
|
|
80
80
|
}
|
|
81
|
-
async function confirm() {
|
|
82
|
-
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
83
|
-
try {
|
|
84
|
-
return /^y(es)?$/i.test((await rl.question("继续?[y/N] ")).trim());
|
|
85
|
-
}
|
|
86
|
-
finally {
|
|
87
|
-
rl.close();
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
81
|
function sampleLine(index, s) {
|
|
91
|
-
const
|
|
92
|
-
|
|
82
|
+
const t = msg().subcommands.cacheProbe;
|
|
83
|
+
const field = s.cacheReported === undefined ? "?" : s.cacheReported ? t.yes : t.no;
|
|
84
|
+
return t.sample(index, s.input, s.cacheRead, s.cacheWrite, field);
|
|
93
85
|
}
|
|
94
86
|
async function run(ctx) {
|
|
95
87
|
const { io, registry } = ctx;
|
|
@@ -99,31 +91,33 @@ async function run(ctx) {
|
|
|
99
91
|
const json = ctx.flags.has("json");
|
|
100
92
|
const found = registry.findModel(ref);
|
|
101
93
|
if (!found.ok) {
|
|
102
|
-
io.stderr(
|
|
94
|
+
io.stderr(msg().subcommands.common.modelNotFound(ref));
|
|
103
95
|
return ExitCode.NoModel;
|
|
104
96
|
}
|
|
105
97
|
const { model, provider } = found;
|
|
106
98
|
const key = await registry.resolveApiKey(provider.id, model.channel);
|
|
107
99
|
if (key.apiKey === undefined && provider.requiresApiKey) {
|
|
108
|
-
io.stderr(
|
|
100
|
+
io.stderr(msg().subcommands.common.noApiKey(provider.id));
|
|
109
101
|
return ExitCode.NoModel;
|
|
110
102
|
}
|
|
111
103
|
const api = registry.getApi(model.api);
|
|
112
104
|
if (api === undefined) {
|
|
113
|
-
io.stderr(
|
|
105
|
+
io.stderr(msg().subcommands.common.apiNotImplemented(model.api));
|
|
114
106
|
return ExitCode.RuntimeError;
|
|
115
107
|
}
|
|
116
108
|
const estimate = priceTokens(model, { input: tokens * 2, output: 32 });
|
|
117
109
|
const name = `${provider.id}/${model.id}`;
|
|
118
|
-
const
|
|
110
|
+
const t = msg().subcommands.cacheProbe;
|
|
111
|
+
const cost = estimate === undefined ? "$?" : `$${estimate.toFixed(4)}`;
|
|
112
|
+
const head = t.head(name, model.api, tokens, gapMs, cost);
|
|
119
113
|
(json ? io.stderr : io.stdout)(head);
|
|
120
114
|
if (!ctx.flags.has("yes")) {
|
|
121
115
|
if (!io.stdinIsTTY) {
|
|
122
|
-
io.stderr(
|
|
116
|
+
io.stderr(t.needsYes);
|
|
123
117
|
return ExitCode.Usage;
|
|
124
118
|
}
|
|
125
|
-
if (!(await
|
|
126
|
-
io.stderr(
|
|
119
|
+
if (!(await confirmContinue({ env: io.env }))) {
|
|
120
|
+
io.stderr(msg().subcommands.common.cancelled);
|
|
127
121
|
return ExitCode.Ok;
|
|
128
122
|
}
|
|
129
123
|
}
|
|
@@ -145,7 +139,7 @@ async function run(ctx) {
|
|
|
145
139
|
})
|
|
146
140
|
.result();
|
|
147
141
|
if (message.stopReason === "error" || message.stopReason === "aborted") {
|
|
148
|
-
io.stderr(
|
|
142
|
+
io.stderr(t.requestFailed(i + 1, message.errorMessage ?? message.stopReason));
|
|
149
143
|
return ExitCode.RuntimeError;
|
|
150
144
|
}
|
|
151
145
|
samples.push(sampleOf(message.usage));
|
|
@@ -170,14 +164,14 @@ async function run(ctx) {
|
|
|
170
164
|
return ExitCode.Ok;
|
|
171
165
|
}
|
|
172
166
|
const share = first.promptTokens > 0
|
|
173
|
-
?
|
|
167
|
+
? t.share(Math.round((second.cacheRead / first.promptTokens) * 100))
|
|
174
168
|
: "";
|
|
175
169
|
io.stdout([
|
|
176
170
|
sampleLine(1, first),
|
|
177
171
|
sampleLine(2, second),
|
|
178
|
-
...(fields.length > 0 ? [
|
|
179
|
-
|
|
180
|
-
...(advice !== undefined ? [
|
|
172
|
+
...(fields.length > 0 ? [t.usageFields(model.api, fields)] : []),
|
|
173
|
+
t.verdict(verdict, share),
|
|
174
|
+
...(advice !== undefined ? [t.advice(advice)] : []),
|
|
181
175
|
].join("\n") + "\n");
|
|
182
176
|
return ExitCode.Ok;
|
|
183
177
|
}
|
|
@@ -16,6 +16,9 @@
|
|
|
16
16
|
*
|
|
17
17
|
* models.dev:列表之后按需刷新缓存(24 小时内不重拉),每个模型标出上下文、输出、图片、工具调用与
|
|
18
18
|
* 匹配结果;`--write` 跳过 models.dev 标明不支持工具调用的模型。元数据不写进配置——运行时从缓存补。
|
|
19
|
+
*
|
|
20
|
+
* [W6-O] `chatgpt`:按登录的 flavor 调对应后端的模型列表(SIWC `GET /v1/models` 筛 `visibility: list`;codex
|
|
21
|
+
* `GET /models?client_version=…`),只取 slug 与显示名;`--probe` 不适用(订阅后端只有一种协议)。
|
|
19
22
|
*/
|
|
20
23
|
import type { Api, Model, ProviderData, ProviderRegistryApi } from "../../ai/types.js";
|
|
21
24
|
import type { ModelsAction } from "./models.js";
|
|
@@ -16,8 +16,14 @@
|
|
|
16
16
|
*
|
|
17
17
|
* models.dev:列表之后按需刷新缓存(24 小时内不重拉),每个模型标出上下文、输出、图片、工具调用与
|
|
18
18
|
* 匹配结果;`--write` 跳过 models.dev 标明不支持工具调用的模型。元数据不写进配置——运行时从缓存补。
|
|
19
|
+
*
|
|
20
|
+
* [W6-O] `chatgpt`:按登录的 flavor 调对应后端的模型列表(SIWC `GET /v1/models` 筛 `visibility: list`;codex
|
|
21
|
+
* `GET /models?client_version=…`),只取 slug 与显示名;`--probe` 不适用(订阅后端只有一种协议)。
|
|
19
22
|
*/
|
|
20
23
|
import { authHeaders, mergeHeaders } from "../../ai/http.js";
|
|
24
|
+
import { listChatGptModels } from "../../auth/chatgpt/backend-client.js";
|
|
25
|
+
import { CHATGPT_PROVIDER_ID } from "../../auth/chatgpt/presets.js";
|
|
26
|
+
import { liveToken } from "../../auth/oauth/live.js";
|
|
21
27
|
import { discoverLocalModels, materializeModel } from "../../ai/providers/registry.js";
|
|
22
28
|
import { withCustomDefaults } from "../../ai/providers/catalog.js";
|
|
23
29
|
import { describeModelsDev, loadModelsDevIndex } from "../../ai/providers/models-dev-cache.js";
|
|
@@ -26,6 +32,7 @@ import { existsSync } from "node:fs";
|
|
|
26
32
|
import { loadConfigFile } from "../../config/load.js";
|
|
27
33
|
import { writeConfigFile } from "../../config/write.js";
|
|
28
34
|
import { UsageError } from "../args.js";
|
|
35
|
+
import { msg } from "../../i18n/index.js";
|
|
29
36
|
import { ExitCode } from "../exit-codes.js";
|
|
30
37
|
import { compactTokens } from "./model-meta.js";
|
|
31
38
|
import { describeProbePlan, parseProbeTuning, ProbeProgress, ProbeScheduler, } from "./probe-runner.js";
|
|
@@ -47,6 +54,23 @@ export function modelsUrl(provider) {
|
|
|
47
54
|
}
|
|
48
55
|
export async function discoverModels(provider, apiKey, options = {}) {
|
|
49
56
|
const timeoutMs = options.timeoutMs ?? DISCOVER_TIMEOUT_MS;
|
|
57
|
+
if (provider.id === CHATGPT_PROVIDER_ID && apiKey !== undefined) {
|
|
58
|
+
const live = liveToken(apiKey);
|
|
59
|
+
const flavor = live?.flavor ?? (provider.defaultChannel === "codex" ? "codex" : "siwc");
|
|
60
|
+
const channel = provider.channels?.find((c) => c.name === flavor);
|
|
61
|
+
const models = await listChatGptModels(fetch, channel?.baseUrl ?? provider.baseUrl, {
|
|
62
|
+
flavor,
|
|
63
|
+
accessToken: apiKey,
|
|
64
|
+
accountId: live?.accountId,
|
|
65
|
+
originator: channel?.headers?.["originator"],
|
|
66
|
+
});
|
|
67
|
+
return models.map((m) => {
|
|
68
|
+
const model = withCustomDefaults({ id: m.id }, provider.id, provider.api);
|
|
69
|
+
if (m.name !== undefined)
|
|
70
|
+
model.name = m.name;
|
|
71
|
+
return model;
|
|
72
|
+
});
|
|
73
|
+
}
|
|
50
74
|
if (!provider.requiresApiKey && apiKey === undefined)
|
|
51
75
|
return discoverLocalModels(provider, { timeoutMs });
|
|
52
76
|
const anthropic = provider.api === "anthropic-messages";
|
|
@@ -114,17 +138,18 @@ function parseLimit(raw) {
|
|
|
114
138
|
return DEFAULT_PROBE_LIMIT;
|
|
115
139
|
const n = Number(raw);
|
|
116
140
|
if (!Number.isInteger(n) || n < 1)
|
|
117
|
-
throw new UsageError(
|
|
141
|
+
throw new UsageError(msg().subcommands.discover.limitPositive(raw));
|
|
118
142
|
return n;
|
|
119
143
|
}
|
|
120
144
|
/** 把新条目合并进用户级 config.json;返回写入条数。 */
|
|
121
145
|
function writeEntries(ctx, provider, entries, notes) {
|
|
122
146
|
const { io } = ctx;
|
|
147
|
+
const m = msg().subcommands.discover;
|
|
123
148
|
const path = ctx.level.userConfigPath;
|
|
124
149
|
const config = structuredClone(loadConfigFile("config", path)?.value ?? { version: 1 });
|
|
125
150
|
const providers = (config.providers ??= {});
|
|
126
151
|
if (providers[provider.id] === undefined && !provider.builtin) {
|
|
127
|
-
io.stderr(
|
|
152
|
+
io.stderr(m.notInUserConfig(provider.id, path));
|
|
128
153
|
return 0;
|
|
129
154
|
}
|
|
130
155
|
const target = (providers[provider.id] ??= {});
|
|
@@ -133,34 +158,33 @@ function writeEntries(ctx, provider, entries, notes) {
|
|
|
133
158
|
const added = entries.filter((entry) => !existing.has(entry.id));
|
|
134
159
|
const kept = entries.length - added.length;
|
|
135
160
|
if (added.length === 0) {
|
|
136
|
-
io.stdout(
|
|
161
|
+
io.stdout(m.nothingToWrite(kept));
|
|
137
162
|
return 0;
|
|
138
163
|
}
|
|
139
164
|
models.push(...added);
|
|
140
165
|
const backup = existsSync(path);
|
|
141
166
|
writeConfigFile(path, config, { backup: true });
|
|
142
|
-
io.stdout(
|
|
143
|
-
`${kept > 0 ? `,${kept} 个已存在未覆盖` : ""}${backup ? `(原文件备份为 ${path}.bak)` : ""}\n`);
|
|
167
|
+
io.stdout(m.written(path, provider.id, added.length, kept, backup));
|
|
144
168
|
if (notes.noTools.size > 0)
|
|
145
|
-
io.stdout(
|
|
169
|
+
io.stdout(m.skippedNoTools([...notes.noTools].join(", ")));
|
|
146
170
|
const blind = added.filter((entry) => notes.unmatched.has(entry.id)).map((entry) => entry.id);
|
|
147
171
|
if (blind.length > 0)
|
|
148
|
-
io.stderr(
|
|
149
|
-
`需要时在 config.json 里补上或写 modelsDev\n`);
|
|
172
|
+
io.stderr(m.unmatchedWarning(blind.join(", ")));
|
|
150
173
|
return added.length;
|
|
151
174
|
}
|
|
152
175
|
async function run(ctx) {
|
|
153
176
|
const { io, registry } = ctx;
|
|
177
|
+
const m = msg().subcommands.discover;
|
|
154
178
|
const id = ctx.args[0] ?? "";
|
|
155
179
|
const limit = parseLimit(ctx.values.get("limit"));
|
|
156
180
|
const provider = registry.get(id);
|
|
157
181
|
if (provider === undefined) {
|
|
158
|
-
io.stderr(
|
|
182
|
+
io.stderr(msg().subcommands.common.providerNotFound(id));
|
|
159
183
|
return ExitCode.NoModel;
|
|
160
184
|
}
|
|
161
185
|
const key = await registry.resolveApiKey(provider.id);
|
|
162
186
|
if (key.apiKey === undefined && provider.requiresApiKey) {
|
|
163
|
-
io.stderr(
|
|
187
|
+
io.stderr(msg().subcommands.common.noApiKey(provider.id));
|
|
164
188
|
return ExitCode.NoModel;
|
|
165
189
|
}
|
|
166
190
|
let found;
|
|
@@ -168,11 +192,11 @@ async function run(ctx) {
|
|
|
168
192
|
found = await discoverModels(provider, key.apiKey);
|
|
169
193
|
}
|
|
170
194
|
catch (error) {
|
|
171
|
-
io.stderr(
|
|
195
|
+
io.stderr(m.listFailed(provider.id, error.message));
|
|
172
196
|
return ExitCode.RuntimeError;
|
|
173
197
|
}
|
|
174
198
|
const configured = new Map(provider.models.map((m) => [m.id, m]));
|
|
175
|
-
io.stdout(
|
|
199
|
+
io.stdout(m.found(provider.id, found.length, modelsUrl(provider)));
|
|
176
200
|
// models.dev 只读本地(快照 ⊕ `ama models refresh` 的覆盖),不联网。
|
|
177
201
|
const mdIndex = loadModelsDevIndex(ctx.level.dataDir);
|
|
178
202
|
io.stdout(`${describeModelsDev(ctx.level.dataDir)}\n`);
|
|
@@ -187,14 +211,14 @@ async function run(ctx) {
|
|
|
187
211
|
if (match === undefined)
|
|
188
212
|
unmatched.add(model.id);
|
|
189
213
|
const meta = fields === undefined
|
|
190
|
-
?
|
|
214
|
+
? m.unmatched
|
|
191
215
|
: ` ctx ${compactTokens(fields.contextWindow)} · out ${compactTokens(fields.maxTokens)}` +
|
|
192
|
-
`${fields.input?.includes("image") ?
|
|
193
|
-
`${fields.toolCall === false ?
|
|
194
|
-
io.stdout(` ${model.id}${known !== undefined ?
|
|
216
|
+
`${fields.input?.includes("image") ? m.image : ""}${fields.reasoning ? m.reasoning : ""}` +
|
|
217
|
+
`${fields.toolCall === false ? m.noTools : ""} · ${matchLabel(match)}`;
|
|
218
|
+
io.stdout(` ${model.id}${known !== undefined ? m.configured(known.api) : ""}${meta}\n`);
|
|
195
219
|
}
|
|
196
220
|
const write = ctx.flags.has("write");
|
|
197
|
-
if (!ctx.flags.has("probe")) {
|
|
221
|
+
if (!ctx.flags.has("probe") || provider.id === CHATGPT_PROVIDER_ID) {
|
|
198
222
|
if (write)
|
|
199
223
|
writeEntries(ctx, provider, found.filter((m) => !noTools.has(m.id)).map((m) => ({ id: m.id })), { noTools, unmatched });
|
|
200
224
|
return ExitCode.Ok;
|
|
@@ -203,15 +227,14 @@ async function run(ctx) {
|
|
|
203
227
|
const count = Math.min(limit, ids.length);
|
|
204
228
|
const order = probeOrder(provider);
|
|
205
229
|
const tuning = parseProbeTuning(ctx.values);
|
|
206
|
-
io.stdout(
|
|
207
|
-
`${ids.length > count ? `;另有 ${ids.length - count} 个超出 --limit ${limit},未探测` : ""}\n` +
|
|
230
|
+
io.stdout(m.probeHeader(count, order.join(" → "), count * order.length, ids.length - count, limit) +
|
|
208
231
|
`${describeProbePlan(count * order.length, tuning.concurrency, tuning.timeoutMs)}\n`);
|
|
209
232
|
let stopped;
|
|
210
233
|
const progress = new ProbeProgress(io.stdout, io.stdoutIsTTY, count);
|
|
211
234
|
const probed = await probeModelApis(registry, provider, ids, limit, {
|
|
212
235
|
...tuning,
|
|
213
236
|
onSettled: () => progress.tick(),
|
|
214
|
-
onResult: (modelId, api) => progress.line(` ${modelId} ${api ??
|
|
237
|
+
onResult: (modelId, api) => progress.line(` ${modelId} ${api ?? m.unavailable}\n`),
|
|
215
238
|
onStop: (reason) => (stopped = reason),
|
|
216
239
|
});
|
|
217
240
|
progress.finish();
|
|
@@ -224,7 +247,7 @@ async function run(ctx) {
|
|
|
224
247
|
writeEntries(ctx, provider, entries, { noTools, unmatched });
|
|
225
248
|
}
|
|
226
249
|
if (stopped !== undefined) {
|
|
227
|
-
io.stderr(
|
|
250
|
+
io.stderr(m.probeStopped(stopped));
|
|
228
251
|
return ExitCode.RuntimeError;
|
|
229
252
|
}
|
|
230
253
|
return ExitCode.Ok;
|
|
@@ -38,5 +38,5 @@ export interface ModelsAction {
|
|
|
38
38
|
export declare const CHECK_TIMEOUT_MS = 30000;
|
|
39
39
|
/** 动作表:键是子命令名,顺序即用法文本顺序。 */
|
|
40
40
|
export declare const MODELS_ACTIONS: Readonly<Record<string, ModelsAction>>;
|
|
41
|
-
export declare
|
|
41
|
+
export declare function modelsUsage(): string;
|
|
42
42
|
export declare function runModels(argv: readonly string[], io: CliIo, deps: Pick<RuntimeDeps, "providers"> | undefined): Promise<number>;
|
|
@@ -19,21 +19,23 @@ import { buildRegistry, loadUserLevel } from "./context.js";
|
|
|
19
19
|
import { CACHE_PROBE_ACTION } from "./models-cache-probe.js";
|
|
20
20
|
import { DISCOVER_ACTION } from "./models-discover.js";
|
|
21
21
|
import { metadataOf, modelFlags, sourcesLine } from "./model-meta.js";
|
|
22
|
+
import { msg } from "../../i18n/index.js";
|
|
22
23
|
const COMMON_VALUE_OPTIONS = ["profile", "auth-file"];
|
|
23
24
|
export const CHECK_TIMEOUT_MS = 30_000;
|
|
24
25
|
async function list(io, registry, only) {
|
|
25
26
|
const providers = registry.list().filter((p) => only === undefined || p.id === only);
|
|
26
27
|
if (only !== undefined && providers.length === 0) {
|
|
27
|
-
io.stderr(
|
|
28
|
+
io.stderr(msg().subcommands.common.providerNotFound(only));
|
|
28
29
|
return ExitCode.NoModel;
|
|
29
30
|
}
|
|
30
31
|
for (const provider of providers) {
|
|
31
32
|
const key = await registry.resolveApiKey(provider.id);
|
|
33
|
+
const t = msg().subcommands.models;
|
|
32
34
|
const keyText = key.apiKey !== undefined
|
|
33
|
-
?
|
|
35
|
+
? t.keyFrom(key.source, key.origin)
|
|
34
36
|
: provider.requiresApiKey
|
|
35
|
-
?
|
|
36
|
-
:
|
|
37
|
+
? t.noKey
|
|
38
|
+
: t.keyNotNeeded;
|
|
37
39
|
io.stdout(`${provider.id} ${provider.api} ${keyText}\n`);
|
|
38
40
|
for (const channel of provider.channels ?? [])
|
|
39
41
|
io.stdout(` @${channel.name} ${channel.api} ${channel.baseUrl}\n`);
|
|
@@ -49,19 +51,18 @@ async function list(io, registry, only) {
|
|
|
49
51
|
async function check(io, registry, ref) {
|
|
50
52
|
const found = registry.findModel(ref);
|
|
51
53
|
if (!found.ok) {
|
|
52
|
-
|
|
53
|
-
io.stderr(`ama: 模型不存在:${ref}${hint}\n`);
|
|
54
|
+
io.stderr(msg().subcommands.common.modelNotFound(ref, found.candidates.slice(0, 10)));
|
|
54
55
|
return ExitCode.NoModel;
|
|
55
56
|
}
|
|
56
57
|
const { model, provider } = found;
|
|
57
58
|
const key = await registry.resolveApiKey(provider.id, model.channel);
|
|
58
59
|
if (key.apiKey === undefined && provider.requiresApiKey) {
|
|
59
|
-
io.stderr(
|
|
60
|
+
io.stderr(msg().subcommands.common.noApiKey(provider.id));
|
|
60
61
|
return ExitCode.NoModel;
|
|
61
62
|
}
|
|
62
63
|
const api = registry.getApi(model.api);
|
|
63
64
|
if (api === undefined) {
|
|
64
|
-
io.stderr(
|
|
65
|
+
io.stderr(msg().subcommands.common.apiNotImplemented(model.api));
|
|
65
66
|
return ExitCode.RuntimeError;
|
|
66
67
|
}
|
|
67
68
|
const started = Date.now();
|
|
@@ -74,11 +75,11 @@ async function check(io, registry, ref) {
|
|
|
74
75
|
const message = await stream.result();
|
|
75
76
|
const ms = Date.now() - started;
|
|
76
77
|
if (message.stopReason === "error" || message.stopReason === "aborted") {
|
|
77
|
-
io.stderr(
|
|
78
|
+
io.stderr(msg().subcommands.models.checkFailed(`${provider.id}/${model.id}`, ms, message.errorMessage ?? message.stopReason));
|
|
78
79
|
return ExitCode.RuntimeError;
|
|
79
80
|
}
|
|
80
81
|
const shown = formatModelRef(modelRefOf(model));
|
|
81
|
-
io.stdout(
|
|
82
|
+
io.stdout(msg().subcommands.models.checkOk(shown, model.api, ms, message.stopReason));
|
|
82
83
|
return ExitCode.Ok;
|
|
83
84
|
}
|
|
84
85
|
/**
|
|
@@ -94,7 +95,7 @@ const REFRESH_ACTION = {
|
|
|
94
95
|
?.split(",")
|
|
95
96
|
.map((p) => p.trim())
|
|
96
97
|
.filter(Boolean);
|
|
97
|
-
ctx.io.stdout(
|
|
98
|
+
ctx.io.stdout(msg().subcommands.models.refreshing(snapshotMeta().fetchedAt));
|
|
98
99
|
const result = await refreshModelsDev({
|
|
99
100
|
dataDir: ctx.level.dataDir,
|
|
100
101
|
env: ctx.io.env,
|
|
@@ -105,7 +106,7 @@ const REFRESH_ACTION = {
|
|
|
105
106
|
ctx.io.stdout(`${describeRefresh(result)}\n`);
|
|
106
107
|
if (result.status === "failed")
|
|
107
108
|
return ExitCode.RuntimeError;
|
|
108
|
-
ctx.io.stdout(
|
|
109
|
+
ctx.io.stdout(msg().subcommands.models.written(modelsDevCachePath(ctx.level.dataDir)));
|
|
109
110
|
return ExitCode.Ok;
|
|
110
111
|
},
|
|
111
112
|
};
|
|
@@ -124,11 +125,17 @@ export const MODELS_ACTIONS = Object.freeze({
|
|
|
124
125
|
discover: DISCOVER_ACTION,
|
|
125
126
|
"cache-probe": CACHE_PROBE_ACTION,
|
|
126
127
|
refresh: REFRESH_ACTION,
|
|
127
|
-
|
|
128
|
+
// 用法行按界面语言取,用 getter(模块级求值会按 import 时的语言定死)
|
|
129
|
+
"refresh-catalog": {
|
|
130
|
+
...REFRESH_ACTION,
|
|
131
|
+
get usage() {
|
|
132
|
+
return msg().subcommands.models.refreshCatalogUsage;
|
|
133
|
+
},
|
|
134
|
+
},
|
|
128
135
|
});
|
|
129
|
-
export
|
|
130
|
-
.map((a) => a.usage)
|
|
131
|
-
|
|
136
|
+
export function modelsUsage() {
|
|
137
|
+
return msg().subcommands.models.usage(Object.values(MODELS_ACTIONS).map((a) => a.usage));
|
|
138
|
+
}
|
|
132
139
|
function unique(lists) {
|
|
133
140
|
return [...new Set(lists.flatMap((l) => l ?? []))];
|
|
134
141
|
}
|
|
@@ -137,12 +144,12 @@ export async function runModels(argv, io, deps) {
|
|
|
137
144
|
const { positionals, values, flags } = parseSubArgs(argv, unique([...actions.map((a) => a.valueOptions), COMMON_VALUE_OPTIONS]), unique(actions.map((a) => a.flagOptions)));
|
|
138
145
|
const name = positionals[0];
|
|
139
146
|
if (flags.has("help") || name === undefined) {
|
|
140
|
-
io.stdout(
|
|
147
|
+
io.stdout(modelsUsage());
|
|
141
148
|
return flags.has("help") ? ExitCode.Ok : ExitCode.Usage;
|
|
142
149
|
}
|
|
143
150
|
const action = Object.hasOwn(MODELS_ACTIONS, name) ? MODELS_ACTIONS[name] : undefined;
|
|
144
151
|
if (action === undefined)
|
|
145
|
-
throw new UsageError(
|
|
152
|
+
throw new UsageError(msg().subcommands.common.unknownSubcommand("models", name));
|
|
146
153
|
// 选项按全部动作的并集解析;这里再拒绝不属于本动作的(如 `list --json`)。
|
|
147
154
|
for (const option of [...values.keys(), ...flags]) {
|
|
148
155
|
const own = [
|
|
@@ -151,13 +158,13 @@ export async function runModels(argv, io, deps) {
|
|
|
151
158
|
...(action.flagOptions ?? []),
|
|
152
159
|
];
|
|
153
160
|
if (!own.includes(option))
|
|
154
|
-
throw new UsageError(
|
|
161
|
+
throw new UsageError(msg().subcommands.common.unknownOption(option));
|
|
155
162
|
}
|
|
156
163
|
const args = positionals.slice(1);
|
|
157
164
|
if (action.required !== undefined && args[0] === undefined)
|
|
158
|
-
throw new UsageError(`ama models ${name}
|
|
165
|
+
throw new UsageError(msg().subcommands.common.needsArg(`ama models ${name}`, action.required));
|
|
159
166
|
if (deps === undefined) {
|
|
160
|
-
io.stderr("
|
|
167
|
+
io.stderr(msg().subcommands.common.notAssembled("models"));
|
|
161
168
|
return ExitCode.RuntimeError;
|
|
162
169
|
}
|
|
163
170
|
const level = loadUserLevel(io, {
|
|
@@ -165,7 +172,7 @@ export async function runModels(argv, io, deps) {
|
|
|
165
172
|
authFile: values.get("auth-file"),
|
|
166
173
|
});
|
|
167
174
|
for (const warning of level.warnings)
|
|
168
|
-
io.stderr(
|
|
175
|
+
io.stderr(msg().subcommands.common.warning(warning));
|
|
169
176
|
const registry = await buildRegistry(level, io, deps);
|
|
170
177
|
return action.run({ io, registry, level, args, values, flags });
|
|
171
178
|
}
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* `ama models check` 不走这里:它只发一次,要看到完整回复与耗时。
|
|
14
14
|
*/
|
|
15
15
|
import { UsageError } from "../args.js";
|
|
16
|
+
import { msg } from "../../i18n/index.js";
|
|
16
17
|
export const PROBE_TIMEOUT_MS = 15_000;
|
|
17
18
|
export const DEFAULT_PROBE_CONCURRENCY = 6;
|
|
18
19
|
export const MAX_PROBE_CONCURRENCY = 16;
|
|
@@ -36,7 +37,7 @@ const sleep = (ms, signal) => new Promise((resolve) => {
|
|
|
36
37
|
export async function probeOnce(registry, model, apiKey, tuning = {}, signal) {
|
|
37
38
|
const impl = registry.getApi(model.api);
|
|
38
39
|
if (impl === undefined)
|
|
39
|
-
return { error:
|
|
40
|
+
return { error: msg().subcommands.probe.apiNotImplemented(model.api) };
|
|
40
41
|
if (signal?.aborted)
|
|
41
42
|
return { aborted: true };
|
|
42
43
|
const timeoutMs = tuning.timeoutMs ?? PROBE_TIMEOUT_MS;
|
|
@@ -53,7 +54,7 @@ export async function probeOnce(registry, model, apiKey, tuning = {}, signal) {
|
|
|
53
54
|
if (signal?.aborted)
|
|
54
55
|
return { aborted: true };
|
|
55
56
|
if (timedOut)
|
|
56
|
-
return { error:
|
|
57
|
+
return { error: msg().subcommands.probe.timeout(Math.round(timeoutMs / 1000)) };
|
|
57
58
|
return outcome;
|
|
58
59
|
};
|
|
59
60
|
try {
|
|
@@ -147,7 +148,7 @@ export class ProbeScheduler {
|
|
|
147
148
|
return { aborted: true };
|
|
148
149
|
outcome = await probeOnce(this.registry, model, this.apiKey, this.options, this.signal);
|
|
149
150
|
if (outcome.error !== undefined && RATE_LIMITED.test(outcome.error)) {
|
|
150
|
-
this.stop(
|
|
151
|
+
this.stop(msg().subcommands.probe.rateLimitedStop(outcome.error));
|
|
151
152
|
return outcome;
|
|
152
153
|
}
|
|
153
154
|
}
|
|
@@ -208,7 +209,7 @@ export function parseProbeTuning(values) {
|
|
|
208
209
|
return fallback;
|
|
209
210
|
const n = Number(raw);
|
|
210
211
|
if (!Number.isInteger(n) || n < min || n > max)
|
|
211
|
-
throw new UsageError(
|
|
212
|
+
throw new UsageError(msg().subcommands.probe.intRange(name, min, max, raw));
|
|
212
213
|
return n;
|
|
213
214
|
};
|
|
214
215
|
return {
|
|
@@ -219,7 +220,7 @@ export function parseProbeTuning(values) {
|
|
|
219
220
|
/** 预估文案:`并发 6,单次最长 15 s,预计不超过 150 s`。 */
|
|
220
221
|
export function describeProbePlan(requests, concurrency, timeoutMs) {
|
|
221
222
|
const worst = Math.ceil(requests / concurrency) * Math.ceil(timeoutMs / 1000);
|
|
222
|
-
return
|
|
223
|
+
return msg().subcommands.probe.plan(concurrency, Math.round(timeoutMs / 1000), worst);
|
|
223
224
|
}
|
|
224
225
|
/** 进度:TTY 下单行刷新「探测 18/60」;非 TTY 只在结束时打印一行汇总。 */
|
|
225
226
|
export class ProbeProgress {
|
|
@@ -247,12 +248,12 @@ export class ProbeProgress {
|
|
|
247
248
|
finish() {
|
|
248
249
|
this.clear();
|
|
249
250
|
const seconds = ((Date.now() - this.started) / 1000).toFixed(1);
|
|
250
|
-
this.write(
|
|
251
|
+
this.write(msg().subcommands.probe.done(this.done, this.total, seconds));
|
|
251
252
|
}
|
|
252
253
|
draw() {
|
|
253
254
|
if (!this.tty)
|
|
254
255
|
return;
|
|
255
|
-
this.write(`\r\x1b[2K
|
|
256
|
+
this.write(`\r\x1b[2K${msg().subcommands.probe.progress(this.done, this.total)}`);
|
|
256
257
|
this.shown = true;
|
|
257
258
|
}
|
|
258
259
|
clear() {
|
|
@@ -8,23 +8,21 @@ import { writeConfigFile } from "../../config/write.js";
|
|
|
8
8
|
import { ExitCode } from "../exit-codes.js";
|
|
9
9
|
import { buildRegistry } from "./context.js";
|
|
10
10
|
import { userConfig } from "./providers.js";
|
|
11
|
+
import { msg } from "../../i18n/index.js";
|
|
11
12
|
async function keySource(registry, config, id, channel) {
|
|
13
|
+
const m = msg().subcommands.providersList;
|
|
12
14
|
const raw = channel !== undefined ? config?.channels?.[channel]?.apiKey : config?.apiKey;
|
|
13
15
|
if (raw !== undefined) {
|
|
14
16
|
const kind = classifyKeyValue(raw);
|
|
15
|
-
return kind === "env-ref"
|
|
16
|
-
? raw
|
|
17
|
-
: kind === "command"
|
|
18
|
-
? "!命令(config.json)"
|
|
19
|
-
: "字面量(config.json)";
|
|
17
|
+
return kind === "env-ref" ? raw : kind === "command" ? m.keyCommand : m.keyLiteral;
|
|
20
18
|
}
|
|
21
19
|
const resolved = await registry.resolveApiKey(id, channel);
|
|
22
20
|
if (resolved.apiKey === undefined)
|
|
23
|
-
return channel !== undefined ?
|
|
21
|
+
return channel !== undefined ? m.keySameProvider : m.keyNone;
|
|
24
22
|
if (channel !== undefined && resolved.source !== "auth-file")
|
|
25
|
-
return
|
|
23
|
+
return m.keySameProvider;
|
|
26
24
|
return resolved.source === "env"
|
|
27
|
-
?
|
|
25
|
+
? m.keyEnv(resolved.origin ?? "")
|
|
28
26
|
: resolved.source === "auth-file"
|
|
29
27
|
? "auth.json"
|
|
30
28
|
: resolved.source;
|
|
@@ -41,36 +39,49 @@ export async function listProviders(ctx) {
|
|
|
41
39
|
(await registry.resolveApiKey(provider.id)).apiKey !== undefined))
|
|
42
40
|
continue;
|
|
43
41
|
shown++;
|
|
44
|
-
const kind = provider.builtin ? "内置" : "自定义";
|
|
45
42
|
const channels = provider.channels ?? [];
|
|
46
|
-
|
|
47
|
-
|
|
43
|
+
const t = msg().subcommands.providersList;
|
|
44
|
+
ctx.io.stdout(t.providerLine({
|
|
45
|
+
id: provider.id,
|
|
46
|
+
builtin: provider.builtin,
|
|
47
|
+
channels: channels.length,
|
|
48
|
+
endpoint: `${provider.api} ${provider.baseUrl}`,
|
|
49
|
+
models: provider.models.length,
|
|
50
|
+
key: await keySource(registry, own, provider.id),
|
|
51
|
+
}));
|
|
48
52
|
for (const c of channels) {
|
|
49
53
|
const count = provider.models.filter((m) => m.channels?.includes(c.name)).length;
|
|
50
|
-
|
|
54
|
+
const key = await keySource(registry, own, provider.id, c.name);
|
|
55
|
+
ctx.io.stdout(t.channelLine(c.name, c.api, c.baseUrl, count, key));
|
|
51
56
|
}
|
|
52
57
|
}
|
|
53
58
|
if (shown === 0)
|
|
54
|
-
ctx.io.stdout(
|
|
59
|
+
ctx.io.stdout(msg().subcommands.providersList.noProviders);
|
|
55
60
|
return ExitCode.Ok;
|
|
56
61
|
}
|
|
57
62
|
export async function listChannels(ctx, id) {
|
|
58
63
|
const registry = await buildRegistry(ctx.level, ctx.io, ctx.deps);
|
|
59
64
|
const provider = registry.get(id);
|
|
60
65
|
if (provider === undefined) {
|
|
61
|
-
ctx.io.stderr(
|
|
66
|
+
ctx.io.stderr(msg().subcommands.common.providerNotFound(id));
|
|
62
67
|
return ExitCode.NoModel;
|
|
63
68
|
}
|
|
64
69
|
const own = userConfig(ctx.level).providers?.[id];
|
|
65
70
|
if (provider.channels === undefined) {
|
|
66
|
-
ctx.io.stdout(
|
|
71
|
+
ctx.io.stdout(msg().subcommands.providersList.singleChannel(id, provider.api, provider.baseUrl, provider.models.length));
|
|
67
72
|
return ExitCode.Ok;
|
|
68
73
|
}
|
|
69
74
|
for (const c of provider.channels) {
|
|
70
75
|
const models = provider.models.filter((m) => m.channels?.includes(c.name));
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
76
|
+
ctx.io.stdout(msg().subcommands.providersList.channelDetail({
|
|
77
|
+
name: c.name,
|
|
78
|
+
isDefault: c.name === provider.defaultChannel,
|
|
79
|
+
short: apiShortName(c.api),
|
|
80
|
+
api: c.api,
|
|
81
|
+
url: c.baseUrl,
|
|
82
|
+
key: await keySource(registry, own, id, c.name),
|
|
83
|
+
models: models.map((m) => m.id),
|
|
84
|
+
}));
|
|
74
85
|
}
|
|
75
86
|
return ExitCode.Ok;
|
|
76
87
|
}
|
|
@@ -80,7 +91,7 @@ export function removeProvider(ctx, id) {
|
|
|
80
91
|
if (had) {
|
|
81
92
|
delete config.providers?.[id];
|
|
82
93
|
writeConfigFile(ctx.level.userConfigPath, config, { backup: true });
|
|
83
|
-
ctx.io.stdout(
|
|
94
|
+
ctx.io.stdout(msg().subcommands.providersList.removed(ctx.level.userConfigPath, id));
|
|
84
95
|
}
|
|
85
96
|
const auth = readAuthFile(ctx.level.authFile).file;
|
|
86
97
|
let keys = 0;
|
|
@@ -88,9 +99,9 @@ export function removeProvider(ctx, id) {
|
|
|
88
99
|
if (name === id || name.startsWith(`${id}@`))
|
|
89
100
|
keys += removeAuthKey(ctx.level.authFile, name) ? 1 : 0;
|
|
90
101
|
if (keys > 0)
|
|
91
|
-
ctx.io.stdout(
|
|
102
|
+
ctx.io.stdout(msg().subcommands.providersList.keysRemoved(ctx.level.authFile, id, keys));
|
|
92
103
|
if (!had && keys === 0) {
|
|
93
|
-
ctx.io.stderr(
|
|
104
|
+
ctx.io.stderr(msg().subcommands.providersList.noSuchProvider(id));
|
|
94
105
|
return ExitCode.RuntimeError;
|
|
95
106
|
}
|
|
96
107
|
return ExitCode.Ok;
|