@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
|
@@ -10,11 +10,20 @@
|
|
|
10
10
|
* auth.json 的 `apiKey` 以 `!` 开头 = 执行命令取值(stdout 去首尾空白;超时 10 s;空输出或
|
|
11
11
|
* 非零退出视为未配置,继续找下一来源);同一命令进程内只执行一次。
|
|
12
12
|
* 密钥只出现在 `resolve()` 的返回值里:warning 文案不含密钥与命令输出。
|
|
13
|
+
*
|
|
14
|
+
* [W6-O] auth.json 的 OAuth 条目(`type: "oauth"`,ChatGPT 登录)在 ②③ 的位置解析:每次从磁盘重读(绕过
|
|
15
|
+
* `fileCache`),临近过期经 `auth/oauth/refresh.ts` 刷新(跨进程锁),返回 `{ source: "oauth" }`,并把 token 的
|
|
16
|
+
* 上下文登记进 `auth/oauth/live.ts` 供协议层取账户 id、401 时强制刷新。永久失效(needsLogin)时仍返回旧 token
|
|
17
|
+
* 并在登记里标 needsLogin,协议层据此直接报 `auth_expired`(不发请求)。
|
|
13
18
|
*/
|
|
14
19
|
import { exec } from "node:child_process";
|
|
15
20
|
import { readFileSync, statSync } from "node:fs";
|
|
16
21
|
import { homedir } from "node:os";
|
|
17
22
|
import { join } from "node:path";
|
|
23
|
+
import { registerLiveToken } from "../../auth/oauth/live.js";
|
|
24
|
+
import { authExpiredError, freshOAuthEntry } from "../../auth/oauth/refresh.js";
|
|
25
|
+
import { readOAuthEntry } from "../../auth/oauth/token-store.js";
|
|
26
|
+
import { apiKeyEntry, isOAuthEntry } from "../../config/types-w6.js";
|
|
18
27
|
/** 用户级配置目录:AMA_CONFIG_DIR > %APPDATA%\ama > $XDG_CONFIG_HOME/ama > ~/.config/ama。 */
|
|
19
28
|
export function defaultConfigDir(env = process.env) {
|
|
20
29
|
if (env["AMA_CONFIG_DIR"])
|
|
@@ -110,12 +119,61 @@ export class ApiKeyResolver {
|
|
|
110
119
|
/** auth.json 里该供应商的条目(按 ② ③ 顺序第一个)。 */
|
|
111
120
|
authEntry(providerId) {
|
|
112
121
|
for (const path of this.authFiles()) {
|
|
113
|
-
const entry = this.loadFile(path)?.providers[providerId];
|
|
122
|
+
const entry = apiKeyEntry(this.loadFile(path)?.providers[providerId]);
|
|
114
123
|
if (entry && typeof entry.apiKey === "string")
|
|
115
124
|
return { entry, path };
|
|
116
125
|
}
|
|
117
126
|
return undefined;
|
|
118
127
|
}
|
|
128
|
+
/** [W6-O] 第一个给该供应商写了条目的 auth.json 若是 OAuth 条目,返回其路径。 */
|
|
129
|
+
oauthPath(providerId) {
|
|
130
|
+
for (const path of this.authFiles()) {
|
|
131
|
+
const raw = this.loadFile(path)?.providers[providerId];
|
|
132
|
+
if (raw === undefined)
|
|
133
|
+
continue;
|
|
134
|
+
return isOAuthEntry(raw) ? path : undefined;
|
|
135
|
+
}
|
|
136
|
+
return undefined;
|
|
137
|
+
}
|
|
138
|
+
register(path, providerId, entry) {
|
|
139
|
+
const deps = this.options.oauth ?? {};
|
|
140
|
+
registerLiveToken(entry.accessToken, {
|
|
141
|
+
provider: providerId,
|
|
142
|
+
flavor: entry.flavor,
|
|
143
|
+
accountId: entry.accountId,
|
|
144
|
+
planType: entry.planType,
|
|
145
|
+
...(entry.needsLogin === true ? { needsLogin: true } : {}),
|
|
146
|
+
refresh: async () => {
|
|
147
|
+
const next = await freshOAuthEntry(path, providerId, deps, {
|
|
148
|
+
force: true,
|
|
149
|
+
staleToken: entry.accessToken,
|
|
150
|
+
});
|
|
151
|
+
if (next === undefined)
|
|
152
|
+
throw authExpiredError(providerId);
|
|
153
|
+
this.register(path, providerId, next);
|
|
154
|
+
return next.accessToken;
|
|
155
|
+
},
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
async fromOAuth(providerId, path) {
|
|
159
|
+
let entry;
|
|
160
|
+
try {
|
|
161
|
+
entry = await freshOAuthEntry(path, providerId, this.options.oauth ?? {});
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
// 失效:用旧 token 登记 needsLogin,协议层报 auth_expired;暂时失败:先用现有 token
|
|
165
|
+
entry = readOAuthEntry(path, providerId);
|
|
166
|
+
const code = error.code;
|
|
167
|
+
if (entry !== undefined && code === "auth_expired")
|
|
168
|
+
entry = { ...entry, needsLogin: true };
|
|
169
|
+
else
|
|
170
|
+
this.warn(`${providerId}: OAuth token refresh failed (${String(code ?? "error")})`);
|
|
171
|
+
}
|
|
172
|
+
if (entry === undefined)
|
|
173
|
+
return undefined;
|
|
174
|
+
this.register(path, providerId, entry);
|
|
175
|
+
return { apiKey: entry.accessToken, source: "oauth", origin: path };
|
|
176
|
+
}
|
|
119
177
|
runCommand(command, extraEnv) {
|
|
120
178
|
const key = `${command}\0${JSON.stringify(extraEnv ?? {})}`;
|
|
121
179
|
let pending = this.commandCache.get(key);
|
|
@@ -138,7 +196,14 @@ export class ApiKeyResolver {
|
|
|
138
196
|
}
|
|
139
197
|
async fromAuthFiles(providerId) {
|
|
140
198
|
for (const path of this.authFiles()) {
|
|
141
|
-
const
|
|
199
|
+
const raw = this.loadFile(path)?.providers[providerId];
|
|
200
|
+
if (isOAuthEntry(raw)) {
|
|
201
|
+
const resolved = await this.fromOAuth(providerId, path);
|
|
202
|
+
if (resolved)
|
|
203
|
+
return resolved;
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
const entry = apiKeyEntry(raw);
|
|
142
207
|
if (!entry || typeof entry.apiKey !== "string" || entry.apiKey.length === 0)
|
|
143
208
|
continue;
|
|
144
209
|
const value = entry.apiKey.startsWith("!")
|
|
@@ -194,6 +259,8 @@ export class ApiKeyResolver {
|
|
|
194
259
|
return true;
|
|
195
260
|
if (this.authEntry(provider.id)?.entry.apiKey)
|
|
196
261
|
return true;
|
|
262
|
+
if (this.oauthPath(provider.id) !== undefined)
|
|
263
|
+
return true;
|
|
197
264
|
const raw = this.options.configKeys?.[provider.id];
|
|
198
265
|
if (raw && (raw.startsWith("!") || expandEnvRefs(raw, this.env) !== undefined))
|
|
199
266
|
return true;
|
|
@@ -227,6 +227,33 @@ export const BUILTIN_PROVIDERS = [
|
|
|
227
227
|
envKeys: ["TOKENHUB_API_KEY", "HUNYUAN_API_KEY", "AMA_API_KEY_TENCENT"],
|
|
228
228
|
requiresApiKey: true,
|
|
229
229
|
},
|
|
230
|
+
{
|
|
231
|
+
// [W6-O] ChatGPT 订阅(docs/wave6-plan.md §4、D14):`ama auth login chatgpt` 写 auth.json 的 OAuth 条目;
|
|
232
|
+
// 缺省渠道在组装时按条目的 flavor 定(compose-providers.ts)。模型表为空:`chatgpt/<slug>` 任意接受,
|
|
233
|
+
// `ama models discover chatgpt` 列出账户可用的 slug。缓存只有 prompt_cache_key(无 24h / 30m 显式缓存)。
|
|
234
|
+
id: "chatgpt",
|
|
235
|
+
name: "ChatGPT (subscription)",
|
|
236
|
+
api: RESPONSES,
|
|
237
|
+
baseUrl: "https://api.openai.com/v1",
|
|
238
|
+
channels: [
|
|
239
|
+
ch("siwc", RESPONSES, "https://api.openai.com/v1", { compat: { chatgptBackend: "siwc" } }),
|
|
240
|
+
ch("codex", RESPONSES, "https://chatgpt.com/backend-api/codex", {
|
|
241
|
+
headers: { originator: "codex_cli_rs" },
|
|
242
|
+
compat: { chatgptBackend: "codex" },
|
|
243
|
+
}),
|
|
244
|
+
],
|
|
245
|
+
defaultChannel: "siwc",
|
|
246
|
+
envKeys: [],
|
|
247
|
+
requiresApiKey: true,
|
|
248
|
+
compat: {
|
|
249
|
+
supportsStore: true,
|
|
250
|
+
supportsReasoningSummary: true,
|
|
251
|
+
sendPromptCacheKey: true,
|
|
252
|
+
sendSessionAffinityHeaders: false,
|
|
253
|
+
supportsLongCacheRetention: false,
|
|
254
|
+
supportsExplicitPromptCacheMode: false,
|
|
255
|
+
},
|
|
256
|
+
},
|
|
230
257
|
{
|
|
231
258
|
id: "ollama",
|
|
232
259
|
name: "Ollama (local)",
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export const CATALOG_SOURCES = {
|
|
6
6
|
anthropic: '{"version":1,"provider":"anthropic","modelsDev":"anthropic","models":[{"id":"claude-fable-5-1","thinkingLevelMap":{"off":null,"xhigh":"xhigh"},"promptCache":{"short":300,"long":3600,"minTokens":512},"compat":{"adaptiveThinking":true}},{"id":"claude-fable-5","thinkingLevelMap":{"off":null,"xhigh":"xhigh"},"promptCache":{"short":300,"long":3600,"minTokens":512},"compat":{"adaptiveThinking":true}},{"id":"claude-opus-5-5","thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":"high","xhigh":"xhigh"},"promptCache":{"short":300,"long":3600,"minTokens":512},"compat":{"adaptiveThinking":true}},{"id":"claude-opus-5","thinkingLevelMap":{"off":null,"xhigh":"xhigh"},"promptCache":{"short":300,"long":3600,"minTokens":512},"compat":{"adaptiveThinking":true}},{"id":"claude-opus-4-8","thinkingLevelMap":{"xhigh":"xhigh"},"promptCache":{"short":300,"long":3600,"minTokens":1024},"compat":{"adaptiveThinking":true}},{"id":"claude-opus-4-7","thinkingLevelMap":{"xhigh":"xhigh"},"promptCache":{"short":300,"long":3600,"minTokens":2048},"compat":{"adaptiveThinking":true}},{"id":"claude-opus-4-6","promptCache":{"short":300,"long":3600,"minTokens":4096},"compat":{"adaptiveThinking":true}},{"id":"claude-sonnet-5-5","thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":"high","xhigh":"xhigh"},"promptCache":{"short":300,"long":3600,"minTokens":512},"compat":{"adaptiveThinking":true}},{"id":"claude-sonnet-5","thinkingLevelMap":{"xhigh":"xhigh"},"promptCache":{"short":300,"long":3600,"minTokens":1024},"compat":{"adaptiveThinking":true}},{"id":"claude-sonnet-4-6","promptCache":{"short":300,"long":3600,"minTokens":1024},"compat":{"adaptiveThinking":true}},{"id":"claude-sonnet-4-5","promptCache":{"short":300,"long":3600,"minTokens":1024}},{"id":"claude-haiku-4-5","promptCache":{"short":300,"long":3600,"minTokens":4096}},{"id":"claude-opus-4-5","promptCache":{"short":300,"long":3600,"minTokens":4096}}]}',
|
|
7
|
+
chatgpt: '{"version":1,"provider":"chatgpt","modelsDev":false,"models":[]}',
|
|
7
8
|
dashscope: '{"version":1,"provider":"dashscope","modelsDev":"alibaba-cn","models":[{"id":"qwen3.8-max","thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":null,"xhigh":"xhigh"},"compat":{"supportsReasoningEffort":true}},{"id":"qwen3.8-flash","thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":null,"xhigh":"xhigh"},"compat":{"supportsReasoningEffort":true}},{"id":"qwen3.7-max","maxTokens":131072,"compat":{"supportsReasoningEffort":false}},{"id":"qwen3.7-plus","maxTokens":65536,"compat":{"supportsReasoningEffort":false}},{"id":"qwen3.6-plus","compat":{"supportsReasoningEffort":false}},{"id":"qwen3.6-flash","compat":{"supportsReasoningEffort":false}}]}',
|
|
8
9
|
deepseek: '{"version":1,"provider":"deepseek","modelsDev":"deepseek","models":[{"id":"deepseek-v4-pro","maxTokens":384000,"cost":{"input":1.32,"output":3.96,"cacheRead":0.044},"thinkingLevelMap":{"minimal":null,"low":null,"medium":null,"high":"high"},"_reason":"按官方价格页的高峰价(UTC 工作日 01–04、06–10 时)计,作上界;平峰为半价。快照价是平峰价或旧价"},{"id":"deepseek-flash","maxTokens":384000,"cost":{"input":0.3,"output":1.2,"cacheRead":0.006},"thinkingLevelMap":{"minimal":null,"low":"low","medium":null,"high":"high"},"_reason":"按官方价格页的高峰价(UTC 工作日 01–04、06–10 时)计,作上界;平峰为半价。快照价是平峰价或旧价"}]}',
|
|
9
10
|
google: '{"version":1,"provider":"google","modelsDev":"google","models":[{"id":"gemini-3.8-flash","thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":"high","xhigh":null}},{"id":"gemini-3.7-flash","thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":"high","xhigh":null}},{"id":"gemini-3.5-flash","thinkingLevelMap":{"off":null,"minimal":"minimal","low":"low","medium":"medium","high":"high","xhigh":null}},{"id":"gemini-3.5-flash-lite","thinkingLevelMap":{"off":null,"minimal":"minimal","low":"low","medium":"medium","high":"high","xhigh":null}},{"id":"gemini-3.1-pro-preview","thinkingLevelMap":{"off":null,"minimal":null,"low":"low","medium":"medium","high":"high","xhigh":null}},{"id":"gemini-3-flash-preview","thinkingLevelMap":{"off":null,"minimal":"minimal","low":"low","medium":"medium","high":"high","xhigh":null}},{"id":"gemini-2.5-pro","thinkingLevelMap":{"off":null,"minimal":128,"low":2048,"medium":8192,"high":32768}},{"id":"gemini-2.5-flash","thinkingLevelMap":{"minimal":128,"low":2048,"medium":8192,"high":24576}},{"id":"gemini-2.5-flash-lite","thinkingLevelMap":{"minimal":512,"low":2048,"medium":8192,"high":24576}}]}',
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { catalogInherited } from "./catalog.js";
|
|
9
9
|
import { ENRICHABLE_FIELDS, modelsDevFields, } from "./models-dev.js";
|
|
10
|
+
import { msg } from "../../i18n/index.js";
|
|
10
11
|
/** 惰性取索引:只有真的要补字段时才读缓存(启动时没有自定义模型就不读约 2 MB 的缓存)。 */
|
|
11
12
|
export function lazyIndex(source) {
|
|
12
13
|
if (typeof source !== "function")
|
|
@@ -90,12 +91,6 @@ export function catalogMetadata(model) {
|
|
|
90
91
|
}
|
|
91
92
|
return { sources, looked: false };
|
|
92
93
|
}
|
|
93
|
-
const SOURCE_TEXT = {
|
|
94
|
-
config: "config",
|
|
95
|
-
catalog: "目录",
|
|
96
|
-
"models.dev": "models.dev",
|
|
97
|
-
default: "缺省",
|
|
98
|
-
};
|
|
99
94
|
export function sourceText(source) {
|
|
100
|
-
return
|
|
95
|
+
return msg().errors.models.source(source);
|
|
101
96
|
}
|
|
@@ -12,6 +12,7 @@ import { mkdirSync, readFileSync, renameSync, statSync, writeFileSync } from "no
|
|
|
12
12
|
import { dirname, join } from "node:path";
|
|
13
13
|
import { ModelsDevIndex as Index } from "./models-dev.js";
|
|
14
14
|
import { buildSnapshot, builtinSnapshot, builtinSnapshotIndex, diffSnapshots, mergeSnapshot, snapshotList, snapshotMeta, } from "./models-dev-snapshot.js";
|
|
15
|
+
import { msg } from "../../i18n/index.js";
|
|
15
16
|
export const MODELS_DEV_URL = "https://models.dev/api.json";
|
|
16
17
|
export const MODELS_DEV_URL_ENV = "AMA_MODELS_DEV_URL";
|
|
17
18
|
export const MODELS_DEV_FILE = "models-dev.json";
|
|
@@ -79,11 +80,11 @@ export function loadModelsDevIndex(dataDir) {
|
|
|
79
80
|
export function describeModelsDev(dataDir) {
|
|
80
81
|
const index = loadModelsDevIndex(dataDir);
|
|
81
82
|
const file = readModelsDevCache(dataDir);
|
|
82
|
-
const
|
|
83
|
+
const m = msg().errors.models;
|
|
83
84
|
const via = file !== undefined && overrideApplies(file)
|
|
84
|
-
?
|
|
85
|
-
:
|
|
86
|
-
return
|
|
85
|
+
? m.viaRefresh(snapshotMeta().fetchedAt, file.fetchedAt)
|
|
86
|
+
: m.viaSnapshot(snapshotMeta().fetchedAt);
|
|
87
|
+
return m.describe(via, index.providerCount, index.modelCount);
|
|
87
88
|
}
|
|
88
89
|
/** 显式联网刷新(只被 `ama models refresh` 调用):拉 api.json、按清单裁剪、写用户级覆盖。 */
|
|
89
90
|
export async function refreshModelsDev(options) {
|
|
@@ -94,12 +95,12 @@ export async function refreshModelsDev(options) {
|
|
|
94
95
|
status: "failed",
|
|
95
96
|
url,
|
|
96
97
|
index: before,
|
|
97
|
-
warning:
|
|
98
|
+
warning: msg().errors.models.refreshFailed(reason),
|
|
98
99
|
});
|
|
99
100
|
const list = snapshotList();
|
|
100
101
|
const unknown = (options.providers ?? []).filter((p) => !list.providers.includes(p));
|
|
101
102
|
if (unknown.length > 0)
|
|
102
|
-
return fail(
|
|
103
|
+
return fail(msg().errors.models.notListed(unknown.join(", "), list.providers.join(", ")));
|
|
103
104
|
let fresh;
|
|
104
105
|
try {
|
|
105
106
|
const response = await (options.fetch ?? fetch)(url, {
|
|
@@ -134,28 +135,23 @@ export async function refreshModelsDev(options) {
|
|
|
134
135
|
}
|
|
135
136
|
/** 刷新结果的说明(命令输出用):一行状态 + 新增 / 删除 / 变化清单。 */
|
|
136
137
|
export function describeRefresh(result, limit = 20) {
|
|
137
|
-
const
|
|
138
|
-
const text = {
|
|
139
|
-
updated: "已刷新",
|
|
140
|
-
unchanged: "已刷新,无变化",
|
|
141
|
-
failed: "刷新失败",
|
|
142
|
-
};
|
|
138
|
+
const m = msg().errors.models;
|
|
143
139
|
const lines = [
|
|
144
|
-
|
|
140
|
+
m.refreshStatus(result.status, result.index.providerCount, result.index.modelCount, result.fetchedAt),
|
|
145
141
|
];
|
|
146
|
-
const section = (
|
|
142
|
+
const section = (kind, items) => {
|
|
147
143
|
if (items.length === 0)
|
|
148
144
|
return;
|
|
149
|
-
lines.push(
|
|
145
|
+
lines.push(m.section(kind, items.length));
|
|
150
146
|
for (const item of items.slice(0, limit))
|
|
151
147
|
lines.push(` ${item}`);
|
|
152
148
|
if (items.length > limit)
|
|
153
|
-
lines.push(
|
|
149
|
+
lines.push(m.more(items.length - limit));
|
|
154
150
|
};
|
|
155
151
|
if (result.diff !== undefined) {
|
|
156
|
-
section("
|
|
157
|
-
section("
|
|
158
|
-
section("
|
|
152
|
+
section("added", result.diff.added);
|
|
153
|
+
section("removed", result.diff.removed);
|
|
154
|
+
section("changed", result.diff.changed);
|
|
159
155
|
}
|
|
160
156
|
return lines.join("\n");
|
|
161
157
|
}
|
|
@@ -7,10 +7,11 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { MODELS_DEV_SOURCES } from "./models-dev-data.js";
|
|
9
9
|
import { ModelsDevIndex, keepForSnapshot, trimProvider, } from "./models-dev.js";
|
|
10
|
+
import { msg } from "../../i18n/index.js";
|
|
10
11
|
function parse(id) {
|
|
11
12
|
const text = MODELS_DEV_SOURCES[id];
|
|
12
13
|
if (text === undefined)
|
|
13
|
-
throw new Error(
|
|
14
|
+
throw new Error(msg().errors.models.snapshotMissing(id));
|
|
14
15
|
return JSON.parse(text);
|
|
15
16
|
}
|
|
16
17
|
let meta;
|
|
@@ -69,17 +70,17 @@ function isRecord(value) {
|
|
|
69
70
|
*/
|
|
70
71
|
export function buildSnapshot(raw, snapshot = snapshotList(), only) {
|
|
71
72
|
if (!isRecord(raw))
|
|
72
|
-
throw new Error(
|
|
73
|
+
throw new Error(msg().errors.models.apiNotObject);
|
|
73
74
|
const out = {};
|
|
74
75
|
for (const id of only ?? snapshot.providers) {
|
|
75
76
|
const provider = raw[id];
|
|
76
77
|
if (!isRecord(provider))
|
|
77
|
-
throw new Error(
|
|
78
|
+
throw new Error(msg().errors.models.apiMissingProvider(id));
|
|
78
79
|
const prefixes = snapshot.prefixes?.[id];
|
|
79
80
|
const trimmed = trimProvider(id, provider, (modelId, model) => keepForSnapshot(model) &&
|
|
80
81
|
(prefixes === undefined || prefixes.some((p) => modelId.startsWith(`${p}/`))));
|
|
81
82
|
if (Object.keys(trimmed.models).length === 0)
|
|
82
|
-
throw new Error(
|
|
83
|
+
throw new Error(msg().errors.models.noModelsAfterFilter(id));
|
|
83
84
|
for (const model of Object.values(trimmed.models))
|
|
84
85
|
delete model.tool_call;
|
|
85
86
|
out[id] = trimmed;
|
|
@@ -89,7 +90,7 @@ export function buildSnapshot(raw, snapshot = snapshotList(), only) {
|
|
|
89
90
|
function priceText(model) {
|
|
90
91
|
const c = model.cost;
|
|
91
92
|
return c === undefined
|
|
92
|
-
?
|
|
93
|
+
? msg().errors.models.none
|
|
93
94
|
: `${c.input}/${c.output}/${c.cache_read ?? "-"}/${c.cache_write ?? "-"}`;
|
|
94
95
|
}
|
|
95
96
|
/** 新旧对比(与脚本摘要同一口径);只比较 `after` 里出现的供应商。 */
|
|
@@ -109,12 +110,12 @@ export function diffSnapshots(before, after) {
|
|
|
109
110
|
const parts = [];
|
|
110
111
|
for (const key of ["context", "output"]) {
|
|
111
112
|
if (prev.limit?.[key] !== next.limit?.[key])
|
|
112
|
-
parts.push(`${key} ${prev.limit?.[key] ??
|
|
113
|
+
parts.push(`${key} ${prev.limit?.[key] ?? msg().errors.models.none} → ${next.limit?.[key] ?? msg().errors.models.none}`);
|
|
113
114
|
}
|
|
114
115
|
if (priceText(prev) !== priceText(next))
|
|
115
116
|
parts.push(`cost ${priceText(prev)} → ${priceText(next)}`);
|
|
116
117
|
if (parts.length > 0)
|
|
117
|
-
out.changed.push(`${providerId}/${id}
|
|
118
|
+
out.changed.push(msg().errors.models.changed(`${providerId}/${id}`, parts));
|
|
118
119
|
}
|
|
119
120
|
}
|
|
120
121
|
out.added.sort();
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*
|
|
9
9
|
* 本模块只做纯计算(不读文件、不联网);缓存与拉取在 models-dev-cache.ts。
|
|
10
10
|
*/
|
|
11
|
+
import { msg } from "../../i18n/index.js";
|
|
11
12
|
/**
|
|
12
13
|
* 原厂供应商(models.dev 的供应商 id,顺序即优先级)。通义在 `alibaba`、Meta 在 `meta`(Llama API
|
|
13
14
|
* 在 `llama`)、智谱国际站在 `zai`、豆包在 `volcengine`、混元在 `tencent-tokenhub`;models.dev 没有
|
|
@@ -168,7 +169,7 @@ export function trimProvider(providerId, provider, keep) {
|
|
|
168
169
|
/** 校验并裁剪 api.json:只留用到的字段;形状不对的供应商 / 模型跳过。整体不是对象抛错。 */
|
|
169
170
|
export function trimModelsDev(raw) {
|
|
170
171
|
if (!isRecord(raw))
|
|
171
|
-
throw new Error(
|
|
172
|
+
throw new Error(msg().errors.models.notObject);
|
|
172
173
|
const out = {};
|
|
173
174
|
for (const [providerId, provider] of Object.entries(raw)) {
|
|
174
175
|
if (!isRecord(provider) || !isRecord(provider["models"]))
|
|
@@ -322,9 +323,7 @@ export class ModelsDevIndex {
|
|
|
322
323
|
candidates,
|
|
323
324
|
};
|
|
324
325
|
if (groups.size > 1) {
|
|
325
|
-
match.warning =
|
|
326
|
-
`${key}:models.dev 有 ${pool.length} 个条目、${groups.size} 种取值,` +
|
|
327
|
-
`取多数(${best.length} 条:${signature(chosen.model)})`;
|
|
326
|
+
match.warning = msg().errors.models.consensus(key, pool.length, groups.size, best.length, signature(chosen.model));
|
|
328
327
|
}
|
|
329
328
|
return match;
|
|
330
329
|
}
|
|
@@ -394,15 +393,6 @@ export const ENRICHABLE_FIELDS = [
|
|
|
394
393
|
/** 匹配方式的中文说明(表格与 `models list`)。 */
|
|
395
394
|
export function matchLabel(match) {
|
|
396
395
|
if (match === undefined)
|
|
397
|
-
return
|
|
398
|
-
|
|
399
|
-
explicit: "显式",
|
|
400
|
-
prefix: "前缀",
|
|
401
|
-
canonical: "原厂",
|
|
402
|
-
vendor: "原厂",
|
|
403
|
-
consensus: "多数",
|
|
404
|
-
single: "唯一",
|
|
405
|
-
};
|
|
406
|
-
const via = match.normalized !== undefined ? `,按 ${match.normalized}` : "";
|
|
407
|
-
return `${kind[match.kind]} ${match.ref}${via}`;
|
|
396
|
+
return msg().errors.models.unmatched;
|
|
397
|
+
return msg().errors.models.match(match.kind, match.ref, match.normalized);
|
|
408
398
|
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* 候选排序:包含关系(`sonnet` ⊂ `claude-sonnet-5`)优先,其次按编辑距离;距离超过
|
|
5
5
|
* `max(2, ⌈长度 / 3⌉)` 的不算接近。只比较 id 本身(不含 `provider/` 前缀),大小写不敏感。
|
|
6
6
|
*/
|
|
7
|
+
import { msg } from "../../i18n/index.js";
|
|
7
8
|
/** Levenshtein 距离(插入 / 删除 / 替换各计 1)。 */
|
|
8
9
|
export function editDistance(a, b) {
|
|
9
10
|
if (a === b)
|
|
@@ -53,20 +54,5 @@ export function closest(needle, candidates, limit = 5, key = String) {
|
|
|
53
54
|
/** 解析失败的一行说明(不含前缀标签):`渠道不存在:x;该模型可用渠道:…` 等。 */
|
|
54
55
|
export function describeLookupFailure(ref, failure) {
|
|
55
56
|
const list = failure.candidates.slice(0, 20).join(", ");
|
|
56
|
-
|
|
57
|
-
case "channel_not_found":
|
|
58
|
-
return failure.candidates.length > 0
|
|
59
|
-
? `渠道不存在:${ref};该模型可用渠道:${list}`
|
|
60
|
-
: `渠道不存在:${ref};该模型没有可选渠道(去掉 @ 后缀)`;
|
|
61
|
-
case "provider_not_found":
|
|
62
|
-
return failure.candidates.length > 0
|
|
63
|
-
? `供应商不存在:${ref};最接近的供应商:${list}`
|
|
64
|
-
: `供应商不存在:${ref}(ama providers list 查看已配置的供应商)`;
|
|
65
|
-
case "ambiguous":
|
|
66
|
-
return `模型名有歧义:${ref};候选:${list}`;
|
|
67
|
-
default:
|
|
68
|
-
return failure.candidates.length > 0
|
|
69
|
-
? `模型不存在:${ref};最接近的模型:${list}`
|
|
70
|
-
: `模型不存在:${ref}(ama models list 查看可用模型)`;
|
|
71
|
-
}
|
|
57
|
+
return msg().errors.models.lookupFailure(ref, failure.reason, list, failure.candidates.length > 0);
|
|
72
58
|
}
|
package/dist/ai/types.d.ts
CHANGED
|
@@ -115,6 +115,8 @@ export interface Usage {
|
|
|
115
115
|
* 协议尚未解析该标记时缺省(第三波 §1.6,「值为 0」与「不报」由此区分)。
|
|
116
116
|
*/
|
|
117
117
|
cacheReported?: boolean;
|
|
118
|
+
/** [W6-C0] 订阅计费(ChatGPT 登录,W6-O):`cost` 为 0,统计单列「订阅」不折算美元。 */
|
|
119
|
+
billing?: "subscription";
|
|
118
120
|
}
|
|
119
121
|
export type StopReason = "stop" | "length" | "toolUse" | "aborted" | "error";
|
|
120
122
|
/** 工具声明(发给供应商的形状)。 */
|
|
@@ -230,6 +232,12 @@ export interface OpenAIResponsesCompat {
|
|
|
230
232
|
supportsStore: boolean;
|
|
231
233
|
/** [W5-C0] 端点私有的显式缓存字段:`volcengine` = 火山方舟 `caching: { type: "enabled" }`。 */
|
|
232
234
|
explicitCacheField?: "volcengine";
|
|
235
|
+
/** [W6-C0] ChatGPT 订阅后端(W6-O):决定请求体白名单、请求头与配额解析。 */
|
|
236
|
+
chatgptBackend?: "siwc" | "codex";
|
|
237
|
+
/** [W6-C0] 系统提示的放法:native(`instructions`)/ developer-message(codex flavor 400 回退)。 */
|
|
238
|
+
instructionsMode?: "native" | "developer-message";
|
|
239
|
+
/** [W6-C0] 工具放进 namespace(SIWC 待实测)。 */
|
|
240
|
+
toolsInNamespace?: boolean;
|
|
233
241
|
}
|
|
234
242
|
/**
|
|
235
243
|
* [W3-C0] 供应商不报缓存时的处理(第三波 §1.6):`auto` 按响应自动判定三态;`silent` /
|
|
@@ -390,6 +398,23 @@ export interface StreamOptions {
|
|
|
390
398
|
/** 观测 / 替换请求体:返回非 undefined 即替换。 */
|
|
391
399
|
onPayload?(payload: unknown): unknown;
|
|
392
400
|
onResponse?(status: number, headers: Headers): void;
|
|
401
|
+
/**
|
|
402
|
+
* [W6-O] 订阅配额更新(ChatGPT 后端的响应头 / `codex.rate_limits` / 429);会话层转成 `quota_update` 事件。
|
|
403
|
+
* 窗口时间为 epoch 毫秒,usedPercent 0–100。
|
|
404
|
+
*/
|
|
405
|
+
onQuota?(update: {
|
|
406
|
+
planType?: string;
|
|
407
|
+
primary?: {
|
|
408
|
+
usedPercent: number;
|
|
409
|
+
resetsAt?: number;
|
|
410
|
+
windowMinutes?: number;
|
|
411
|
+
};
|
|
412
|
+
secondary?: {
|
|
413
|
+
usedPercent: number;
|
|
414
|
+
resetsAt?: number;
|
|
415
|
+
windowMinutes?: number;
|
|
416
|
+
};
|
|
417
|
+
}): void;
|
|
393
418
|
}
|
|
394
419
|
export type AssistantEvent = {
|
|
395
420
|
type: "start";
|
|
@@ -452,7 +477,8 @@ export interface ApiImplementation<C = unknown> {
|
|
|
452
477
|
/** 推断缺省 compat。 */
|
|
453
478
|
detectCompat?(model: Model, provider: ProviderData): C;
|
|
454
479
|
}
|
|
455
|
-
|
|
480
|
+
/** [W6-C0] `oauth`:auth.json 的 OAuth 条目(W6-O)。 */
|
|
481
|
+
export type KeySource = "cli" | "auth-file" | "config" | "env" | "oauth" | "none";
|
|
456
482
|
/** 密钥只存在于 `apiKey` 字段,不进日志、会话、事件。 */
|
|
457
483
|
export interface ApiKeyResolution {
|
|
458
484
|
apiKey: string | undefined;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ChatGPT 后端的只读查询([W6-O]):模型列表(`ama models discover chatgpt`)与 codex 的 `wham/usage`。
|
|
3
|
+
*
|
|
4
|
+
* - SIWC:`GET {base}/models`,只留 `visibility === "list"`(没有该字段的也留);
|
|
5
|
+
* - codex:`GET {base}/models?client_version=<ama 版本>`,`models[].slug`(同样按 visibility 筛);
|
|
6
|
+
* `GET https://chatgpt.com/backend-api/wham/usage`(由 codex base 推出),私有格式,解析失败返回 undefined。
|
|
7
|
+
* 只取 slug 与显示名,上下文窗口不猜。请求带 Bearer;codex 另带 `ChatGPT-Account-ID` 与 `originator`。
|
|
8
|
+
*/
|
|
9
|
+
import { type QuotaSnapshot } from "../../ai/apis/chatgpt-rate-limits.js";
|
|
10
|
+
import type { ChatGptFlavor } from "../../config/types-w6.js";
|
|
11
|
+
import type { FetchLike } from "../oauth/token-client.js";
|
|
12
|
+
export declare const BACKEND_TIMEOUT_MS = 15000;
|
|
13
|
+
export interface BackendAuth {
|
|
14
|
+
flavor: ChatGptFlavor;
|
|
15
|
+
accessToken: string;
|
|
16
|
+
accountId?: string | undefined;
|
|
17
|
+
originator?: string | undefined;
|
|
18
|
+
}
|
|
19
|
+
export interface DiscoveredModel {
|
|
20
|
+
id: string;
|
|
21
|
+
name?: string;
|
|
22
|
+
}
|
|
23
|
+
export declare function listChatGptModels(fetchFn: FetchLike, baseUrl: string, auth: BackendAuth): Promise<DiscoveredModel[]>;
|
|
24
|
+
export declare function usageUrl(codexBaseUrl: string): string;
|
|
25
|
+
/** codex 的配额;任何失败返回 undefined。 */
|
|
26
|
+
export declare function fetchCodexUsage(fetchFn: FetchLike, codexBaseUrl: string, auth: BackendAuth, timeoutMs?: number): Promise<QuotaSnapshot | undefined>;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ChatGPT 后端的只读查询([W6-O]):模型列表(`ama models discover chatgpt`)与 codex 的 `wham/usage`。
|
|
3
|
+
*
|
|
4
|
+
* - SIWC:`GET {base}/models`,只留 `visibility === "list"`(没有该字段的也留);
|
|
5
|
+
* - codex:`GET {base}/models?client_version=<ama 版本>`,`models[].slug`(同样按 visibility 筛);
|
|
6
|
+
* `GET https://chatgpt.com/backend-api/wham/usage`(由 codex base 推出),私有格式,解析失败返回 undefined。
|
|
7
|
+
* 只取 slug 与显示名,上下文窗口不猜。请求带 Bearer;codex 另带 `ChatGPT-Account-ID` 与 `originator`。
|
|
8
|
+
*/
|
|
9
|
+
import { parseUsagePayload } from "../../ai/apis/chatgpt-rate-limits.js";
|
|
10
|
+
import { AMA_VERSION } from "../../version.js";
|
|
11
|
+
import { DEFAULT_ORIGINATOR } from "./presets.js";
|
|
12
|
+
export const BACKEND_TIMEOUT_MS = 15_000;
|
|
13
|
+
function headers(auth) {
|
|
14
|
+
const out = {
|
|
15
|
+
authorization: `Bearer ${auth.accessToken}`,
|
|
16
|
+
accept: "application/json",
|
|
17
|
+
};
|
|
18
|
+
if (auth.flavor === "codex") {
|
|
19
|
+
if (auth.accountId !== undefined)
|
|
20
|
+
out["ChatGPT-Account-ID"] = auth.accountId;
|
|
21
|
+
out["originator"] = auth.originator ?? DEFAULT_ORIGINATOR;
|
|
22
|
+
}
|
|
23
|
+
return out;
|
|
24
|
+
}
|
|
25
|
+
function listed(item) {
|
|
26
|
+
const visibility = item["visibility"];
|
|
27
|
+
return visibility === undefined || visibility === "list";
|
|
28
|
+
}
|
|
29
|
+
export async function listChatGptModels(fetchFn, baseUrl, auth) {
|
|
30
|
+
const base = baseUrl.replace(/\/+$/, "");
|
|
31
|
+
const url = auth.flavor === "codex"
|
|
32
|
+
? `${base}/models?client_version=${encodeURIComponent(AMA_VERSION)}`
|
|
33
|
+
: `${base}/models`;
|
|
34
|
+
const response = await fetchFn(url, {
|
|
35
|
+
headers: headers(auth),
|
|
36
|
+
signal: AbortSignal.timeout(BACKEND_TIMEOUT_MS),
|
|
37
|
+
});
|
|
38
|
+
if (!response.ok)
|
|
39
|
+
throw new Error(`${response.status} listing models from ${url}`);
|
|
40
|
+
const body = (await response.json());
|
|
41
|
+
const items = (Array.isArray(body.models) ? body.models : Array.isArray(body.data) ? body.data : [])
|
|
42
|
+
.filter((x) => typeof x === "object" && x !== null)
|
|
43
|
+
.filter(listed);
|
|
44
|
+
const out = [];
|
|
45
|
+
const seen = new Set();
|
|
46
|
+
for (const item of items) {
|
|
47
|
+
const id = item["slug"] ?? item["id"];
|
|
48
|
+
if (typeof id !== "string" || id === "" || seen.has(id))
|
|
49
|
+
continue;
|
|
50
|
+
seen.add(id);
|
|
51
|
+
const name = item["display_name"];
|
|
52
|
+
out.push(typeof name === "string" && name !== "" ? { id, name } : { id });
|
|
53
|
+
}
|
|
54
|
+
return out;
|
|
55
|
+
}
|
|
56
|
+
export function usageUrl(codexBaseUrl) {
|
|
57
|
+
const base = codexBaseUrl.replace(/\/+$/, "").replace(/\/codex$/, "");
|
|
58
|
+
return `${base}/wham/usage`;
|
|
59
|
+
}
|
|
60
|
+
/** codex 的配额;任何失败返回 undefined。 */
|
|
61
|
+
export async function fetchCodexUsage(fetchFn, codexBaseUrl, auth, timeoutMs = 5_000) {
|
|
62
|
+
try {
|
|
63
|
+
const response = await fetchFn(usageUrl(codexBaseUrl), {
|
|
64
|
+
headers: headers(auth),
|
|
65
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
66
|
+
});
|
|
67
|
+
if (!response.ok)
|
|
68
|
+
return undefined;
|
|
69
|
+
return parseUsagePayload(await response.json());
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* id_token 声明里的账户信息(R6 §1.2 账户 id 行)。[W6-O]
|
|
3
|
+
*
|
|
4
|
+
* codex:`https://api.openai.com/auth` 下的 `chatgpt_account_id` / `chatgpt_plan_type`;SIWC:以验签后的
|
|
5
|
+
* `sub` 作账户标识(官方文档),计划类型若有同样取 auth 声明。邮箱取 `email` 或 profile 声明。
|
|
6
|
+
*/
|
|
7
|
+
import type { JwtPayload } from "../oauth/jwt.js";
|
|
8
|
+
export interface ChatGptAccount {
|
|
9
|
+
accountId?: string;
|
|
10
|
+
planType?: string;
|
|
11
|
+
email?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function chatgptAccount(claims: JwtPayload | undefined, flavor: "siwc" | "codex"): ChatGptAccount;
|
|
14
|
+
/** 空格分隔的 scope 是否含 `required`。 */
|
|
15
|
+
export declare function hasScope(scope: string | undefined, required: string): boolean;
|
|
16
|
+
/** `a***@example.com`:status / doctor 用。 */
|
|
17
|
+
export declare function maskEmail(email: string | undefined): string | undefined;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* id_token 声明里的账户信息(R6 §1.2 账户 id 行)。[W6-O]
|
|
3
|
+
*
|
|
4
|
+
* codex:`https://api.openai.com/auth` 下的 `chatgpt_account_id` / `chatgpt_plan_type`;SIWC:以验签后的
|
|
5
|
+
* `sub` 作账户标识(官方文档),计划类型若有同样取 auth 声明。邮箱取 `email` 或 profile 声明。
|
|
6
|
+
*/
|
|
7
|
+
function obj(value) {
|
|
8
|
+
return typeof value === "object" && value !== null && !Array.isArray(value)
|
|
9
|
+
? value
|
|
10
|
+
: undefined;
|
|
11
|
+
}
|
|
12
|
+
function str(value) {
|
|
13
|
+
return typeof value === "string" && value !== "" ? value : undefined;
|
|
14
|
+
}
|
|
15
|
+
export function chatgptAccount(claims, flavor) {
|
|
16
|
+
if (claims === undefined)
|
|
17
|
+
return {};
|
|
18
|
+
const auth = obj(claims["https://api.openai.com/auth"]);
|
|
19
|
+
const profile = obj(claims["https://api.openai.com/profile"]);
|
|
20
|
+
const out = {};
|
|
21
|
+
const accountId = flavor === "codex"
|
|
22
|
+
? (str(auth?.["chatgpt_account_id"]) ?? str(claims["chatgpt_account_id"]))
|
|
23
|
+
: (str(claims["sub"]) ?? str(auth?.["chatgpt_account_id"]));
|
|
24
|
+
if (accountId !== undefined)
|
|
25
|
+
out.accountId = accountId;
|
|
26
|
+
const plan = str(auth?.["chatgpt_plan_type"]) ?? str(claims["chatgpt_plan_type"]);
|
|
27
|
+
if (plan !== undefined)
|
|
28
|
+
out.planType = plan;
|
|
29
|
+
const email = str(claims["email"]) ?? str(profile?.["email"]);
|
|
30
|
+
if (email !== undefined)
|
|
31
|
+
out.email = email;
|
|
32
|
+
return out;
|
|
33
|
+
}
|
|
34
|
+
/** 空格分隔的 scope 是否含 `required`。 */
|
|
35
|
+
export function hasScope(scope, required) {
|
|
36
|
+
return (scope ?? "").split(/[\s+]+/).includes(required);
|
|
37
|
+
}
|
|
38
|
+
/** `a***@example.com`:status / doctor 用。 */
|
|
39
|
+
export function maskEmail(email) {
|
|
40
|
+
if (email === undefined)
|
|
41
|
+
return undefined;
|
|
42
|
+
const at = email.indexOf("@");
|
|
43
|
+
if (at <= 0)
|
|
44
|
+
return "***";
|
|
45
|
+
return `${email.slice(0, 1)}***${email.slice(at)}`;
|
|
46
|
+
}
|