@armadra/agent 0.3.0 → 0.5.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 +257 -0
- package/README.md +263 -95
- package/THIRD_PARTY_NOTICES.md +34 -0
- package/dist/acp.d.ts +18 -0
- package/dist/acp.js +19 -0
- package/dist/agent/limits.d.ts +38 -0
- package/dist/agent/limits.js +127 -0
- package/dist/agent/loop-guard.d.ts +38 -0
- package/dist/agent/loop-guard.js +95 -0
- package/dist/agent/loop.d.ts +4 -0
- package/dist/agent/loop.js +7 -0
- package/dist/agent/prompt-rules.d.ts +12 -0
- package/dist/agent/prompt-rules.js +18 -0
- package/dist/agent/reminders.d.ts +59 -0
- package/dist/agent/reminders.js +327 -0
- package/dist/agent/retry.d.ts +1 -1
- package/dist/agent/retry.js +2 -1
- package/dist/agent/session-cache.d.ts +5 -0
- package/dist/agent/session-cache.js +18 -2
- package/dist/agent/session-classifier.d.ts +18 -0
- package/dist/agent/session-classifier.js +105 -0
- package/dist/agent/session-compaction.d.ts +35 -6
- package/dist/agent/session-compaction.js +157 -31
- package/dist/agent/session-core.d.ts +40 -1
- package/dist/agent/session-extensions.d.ts +61 -0
- package/dist/agent/session-extensions.js +129 -0
- package/dist/agent/session-images.d.ts +23 -0
- package/dist/agent/session-images.js +97 -0
- package/dist/agent/session-plan.d.ts +21 -0
- package/dist/agent/session-plan.js +524 -0
- package/dist/agent/session-rewind.d.ts +81 -0
- package/dist/agent/session-rewind.js +354 -0
- package/dist/agent/session-run.d.ts +28 -1
- package/dist/agent/session-run.js +157 -6
- package/dist/agent/session-settings.d.ts +49 -0
- package/dist/agent/session-settings.js +95 -0
- package/dist/agent/session-subagent.d.ts +36 -24
- package/dist/agent/session-subagent.js +259 -129
- package/dist/agent/session-sync.d.ts +10 -3
- package/dist/agent/session-sync.js +37 -8
- package/dist/agent/session-telemetry.d.ts +39 -0
- package/dist/agent/session-telemetry.js +231 -0
- package/dist/agent/session-tools.js +63 -3
- package/dist/agent/session.d.ts +33 -29
- package/dist/agent/session.js +91 -126
- package/dist/agent/subagent-registry.d.ts +91 -0
- package/dist/agent/subagent-registry.js +494 -0
- package/dist/agent/system-prompt.d.ts +6 -3
- package/dist/agent/system-prompt.js +7 -2
- package/dist/agent/tool-runner.d.ts +8 -1
- package/dist/agent/tool-runner.js +72 -6
- package/dist/agent/types-w5.d.ts +192 -0
- package/dist/agent/types-w5.js +10 -0
- package/dist/agent/types.d.ts +55 -4
- package/dist/agent/types.js +2 -0
- package/dist/agent/worktree.d.ts +36 -0
- package/dist/agent/worktree.js +86 -0
- package/dist/agents/builtin.d.ts +14 -0
- package/dist/agents/builtin.js +39 -0
- package/dist/agents/catalog.d.ts +43 -0
- package/dist/agents/catalog.js +82 -0
- package/dist/agents/discover.d.ts +35 -0
- package/dist/agents/discover.js +83 -0
- package/dist/agents/external.d.ts +82 -0
- package/dist/agents/external.js +326 -0
- package/dist/agents/parse.d.ts +18 -0
- package/dist/agents/parse.js +116 -0
- package/dist/agents/result.d.ts +32 -0
- package/dist/agents/result.js +67 -0
- package/dist/agents/task-control.d.ts +17 -0
- package/dist/agents/task-control.js +17 -0
- package/dist/agents/task-record.d.ts +78 -0
- package/dist/agents/task-record.js +141 -0
- package/dist/agents/types.d.ts +46 -0
- package/dist/agents/types.js +8 -0
- package/dist/ai/apis/anthropic-compat.d.ts +36 -0
- package/dist/ai/apis/anthropic-compat.js +92 -0
- package/dist/ai/apis/anthropic-messages.js +3 -2
- package/dist/ai/apis/anthropic-request.d.ts +7 -6
- package/dist/ai/apis/anthropic-request.js +10 -28
- package/dist/ai/apis/cache-params.d.ts +11 -2
- package/dist/ai/apis/cache-params.js +25 -6
- package/dist/ai/apis/google-generative-ai.js +3 -2
- package/dist/ai/apis/openai-compat.d.ts +4 -1
- package/dist/ai/apis/openai-compat.js +8 -1
- package/dist/ai/apis/openai-completions.js +3 -2
- package/dist/ai/apis/openai-responses.js +3 -2
- package/dist/ai/http.d.ts +28 -6
- package/dist/ai/http.js +41 -8
- package/dist/ai/image-limits.d.ts +45 -0
- package/dist/ai/image-limits.js +68 -0
- package/dist/ai/providers/builtin.d.ts +18 -6
- package/dist/ai/providers/builtin.js +135 -6
- package/dist/ai/providers/catalog-data.js +17 -13
- package/dist/ai/providers/catalog.d.ts +60 -7
- package/dist/ai/providers/catalog.js +197 -38
- package/dist/ai/providers/channels.d.ts +33 -3
- package/dist/ai/providers/channels.js +108 -7
- package/dist/ai/providers/enrich.d.ts +6 -3
- package/dist/ai/providers/enrich.js +19 -4
- package/dist/ai/providers/models-dev-cache.d.ts +28 -24
- package/dist/ai/providers/models-dev-cache.js +92 -78
- package/dist/ai/providers/models-dev-data.d.ts +7 -0
- package/dist/ai/providers/models-dev-data.js +32 -0
- package/dist/ai/providers/models-dev-snapshot.d.ts +50 -0
- package/dist/ai/providers/models-dev-snapshot.js +137 -0
- package/dist/ai/providers/models-dev.d.ts +51 -10
- package/dist/ai/providers/models-dev.js +132 -39
- package/dist/ai/providers/registry.d.ts +28 -11
- package/dist/ai/providers/registry.js +112 -65
- package/dist/ai/providers/suggest.d.ts +18 -0
- package/dist/ai/providers/suggest.js +72 -0
- package/dist/ai/sse.d.ts +6 -2
- package/dist/ai/sse.js +22 -2
- package/dist/ai/types.d.ts +37 -4
- package/dist/ai/types.js +5 -0
- package/dist/bundle/ama.cjs +41979 -21147
- package/dist/checkpoints/backend.d.ts +61 -0
- package/dist/checkpoints/backend.js +135 -0
- package/dist/checkpoints/blobs.d.ts +60 -0
- package/dist/checkpoints/blobs.js +203 -0
- package/dist/checkpoints/gc.d.ts +47 -0
- package/dist/checkpoints/gc.js +144 -0
- package/dist/checkpoints/git-head.d.ts +15 -0
- package/dist/checkpoints/git-head.js +89 -0
- package/dist/checkpoints/index.d.ts +17 -0
- package/dist/checkpoints/index.js +17 -0
- package/dist/checkpoints/replay.d.ts +48 -0
- package/dist/checkpoints/replay.js +154 -0
- package/dist/checkpoints/restore.d.ts +86 -0
- package/dist/checkpoints/restore.js +263 -0
- package/dist/checkpoints/settings.d.ts +14 -0
- package/dist/checkpoints/settings.js +23 -0
- package/dist/checkpoints/shadow-git.d.ts +108 -0
- package/dist/checkpoints/shadow-git.js +491 -0
- package/dist/checkpoints/shadow-restore.d.ts +25 -0
- package/dist/checkpoints/shadow-restore.js +128 -0
- package/dist/checkpoints/tracker.d.ts +64 -0
- package/dist/checkpoints/tracker.js +192 -0
- package/dist/checkpoints/types.d.ts +99 -0
- package/dist/checkpoints/types.js +12 -0
- package/dist/cli/args.d.ts +26 -7
- package/dist/cli/args.js +75 -82
- package/dist/cli/bootstrap.js +40 -4
- package/dist/cli/codemode-notice.d.ts +21 -0
- package/dist/cli/codemode-notice.js +56 -0
- package/dist/cli/compose-agents.d.ts +27 -0
- package/dist/cli/compose-agents.js +111 -0
- package/dist/cli/compose-extensions.d.ts +29 -0
- package/dist/cli/compose-extensions.js +44 -0
- package/dist/cli/compose-session.d.ts +8 -0
- package/dist/cli/compose-session.js +76 -2
- package/dist/cli/compose-store.d.ts +1 -1
- package/dist/cli/compose-store.js +3 -1
- package/dist/cli/compose.d.ts +17 -4
- package/dist/cli/compose.js +60 -14
- package/dist/cli/default-model.d.ts +38 -1
- package/dist/cli/default-model.js +96 -9
- package/dist/cli/deps.d.ts +42 -0
- package/dist/cli/exit-codes.d.ts +12 -0
- package/dist/cli/exit-codes.js +15 -0
- package/dist/cli/fake-visibility.d.ts +13 -0
- package/dist/cli/fake-visibility.js +26 -0
- package/dist/cli/from-prompt.d.ts +18 -0
- package/dist/cli/from-prompt.js +49 -0
- package/dist/cli/help-text.d.ts +4 -0
- package/dist/cli/help-text.js +102 -0
- package/dist/cli/main.d.ts +9 -2
- package/dist/cli/main.js +77 -3
- package/dist/cli/proxy.d.ts +51 -0
- package/dist/cli/proxy.js +135 -0
- package/dist/cli/startup-screen.d.ts +29 -0
- package/dist/cli/startup-screen.js +51 -2
- package/dist/cli/startup-steps.d.ts +1 -1
- package/dist/cli/startup-steps.js +21 -13
- package/dist/cli/subcommands/config.d.ts +22 -3
- package/dist/cli/subcommands/config.js +119 -21
- package/dist/cli/subcommands/context.js +4 -1
- package/dist/cli/subcommands/doctor.js +33 -1
- package/dist/cli/subcommands/init.js +2 -1
- package/dist/cli/subcommands/models-discover.d.ts +15 -9
- package/dist/cli/subcommands/models-discover.js +58 -52
- package/dist/cli/subcommands/models.d.ts +2 -0
- package/dist/cli/subcommands/models.js +33 -14
- package/dist/cli/subcommands/probe-runner.d.ts +96 -0
- package/dist/cli/subcommands/probe-runner.js +264 -0
- package/dist/cli/subcommands/providers-probe.d.ts +34 -0
- package/dist/cli/subcommands/providers-probe.js +87 -0
- package/dist/cli/subcommands/providers.d.ts +3 -2
- package/dist/cli/subcommands/providers.js +53 -51
- package/dist/cli/subcommands/sessions-export.d.ts +10 -0
- package/dist/cli/subcommands/sessions-export.js +59 -0
- package/dist/cli/subcommands/sessions-search.d.ts +13 -0
- package/dist/cli/subcommands/sessions-search.js +103 -0
- package/dist/cli/subcommands/sessions.d.ts +6 -3
- package/dist/cli/subcommands/sessions.js +58 -3
- package/dist/cli/subcommands/stats.d.ts +17 -0
- package/dist/cli/subcommands/stats.js +198 -0
- package/dist/cli/system-prompt-arg.d.ts +11 -0
- package/dist/cli/system-prompt-arg.js +34 -0
- package/dist/codemode/capability.d.ts +24 -7
- package/dist/codemode/capability.js +38 -10
- package/dist/codemode/host-side.d.ts +14 -0
- package/dist/codemode/host-side.js +24 -1
- package/dist/codemode/modes.d.ts +4 -11
- package/dist/codemode/modes.js +5 -27
- package/dist/codemode/tool.d.ts +18 -14
- package/dist/codemode/tool.js +76 -31
- package/dist/compaction/breaker.d.ts +25 -9
- package/dist/compaction/breaker.js +47 -17
- package/dist/compaction/estimate.d.ts +11 -3
- package/dist/compaction/estimate.js +64 -22
- package/dist/compaction/image-budget.d.ts +45 -0
- package/dist/compaction/image-budget.js +115 -0
- package/dist/compaction/post-compact.d.ts +38 -0
- package/dist/compaction/post-compact.js +152 -0
- package/dist/compaction/protect.d.ts +27 -0
- package/dist/compaction/protect.js +56 -0
- package/dist/compaction/prune-tier.d.ts +58 -12
- package/dist/compaction/prune-tier.js +120 -54
- package/dist/compaction/summarize-tier.d.ts +23 -4
- package/dist/compaction/summarize-tier.js +100 -29
- package/dist/config/checker.d.ts +28 -0
- package/dist/config/checker.js +97 -0
- package/dist/config/init.d.ts +6 -2
- package/dist/config/init.js +12 -5
- package/dist/config/json-schema.d.ts +1 -0
- package/dist/config/json-schema.js +98 -4
- package/dist/config/key-docs.d.ts +22 -0
- package/dist/config/key-docs.js +174 -0
- package/dist/config/merge.d.ts +12 -9
- package/dist/config/merge.js +102 -13
- package/dist/config/profile.d.ts +2 -0
- package/dist/config/profile.js +2 -0
- package/dist/config/schema-w5.d.ts +18 -0
- package/dist/config/schema-w5.js +109 -0
- package/dist/config/schema.d.ts +5 -9
- package/dist/config/schema.js +91 -118
- package/dist/config/types-w5.d.ts +118 -0
- package/dist/config/types-w5.js +20 -0
- package/dist/config/types.d.ts +84 -7
- package/dist/config/types.js +29 -1
- package/dist/drivers/acp/client.d.ts +57 -0
- package/dist/drivers/acp/client.js +160 -0
- package/dist/drivers/acp/driver.d.ts +31 -0
- package/dist/drivers/acp/driver.js +274 -0
- package/dist/drivers/acp/testing/fake-agent-main.d.ts +5 -0
- package/dist/drivers/acp/testing/fake-agent-main.js +7 -0
- package/dist/drivers/acp/testing/fake-agent.d.ts +27 -0
- package/dist/drivers/acp/testing/fake-agent.js +211 -0
- package/dist/drivers/acp/types.d.ts +285 -0
- package/dist/drivers/acp/types.js +36 -0
- package/dist/drivers/agents.d.ts +58 -0
- package/dist/drivers/agents.js +142 -0
- package/dist/drivers/base.d.ts +35 -0
- package/dist/drivers/base.js +59 -0
- package/dist/drivers/catalog.d.ts +46 -0
- package/dist/drivers/catalog.js +167 -0
- package/dist/drivers/env.d.ts +20 -0
- package/dist/drivers/env.js +46 -0
- package/dist/drivers/host-runners.d.ts +18 -0
- package/dist/drivers/host-runners.js +45 -0
- package/dist/drivers/jsonrpc.d.ts +58 -0
- package/dist/drivers/jsonrpc.js +180 -0
- package/dist/drivers/native/claude-normalize.d.ts +46 -0
- package/dist/drivers/native/claude-normalize.js +106 -0
- package/dist/drivers/native/claude-stream.d.ts +29 -0
- package/dist/drivers/native/claude-stream.js +456 -0
- package/dist/drivers/native/codex-app-server.d.ts +26 -0
- package/dist/drivers/native/codex-app-server.js +407 -0
- package/dist/drivers/native/codex-normalize.d.ts +38 -0
- package/dist/drivers/native/codex-normalize.js +124 -0
- package/dist/drivers/native/oneshot.d.ts +28 -0
- package/dist/drivers/native/oneshot.js +312 -0
- package/dist/drivers/permissions.d.ts +40 -0
- package/dist/drivers/permissions.js +92 -0
- package/dist/drivers/pids.d.ts +32 -0
- package/dist/drivers/pids.js +93 -0
- package/dist/drivers/pool.d.ts +28 -0
- package/dist/drivers/pool.js +96 -0
- package/dist/drivers/probe.d.ts +47 -0
- package/dist/drivers/probe.js +172 -0
- package/dist/drivers/process.d.ts +48 -0
- package/dist/drivers/process.js +100 -0
- package/dist/drivers/runner.d.ts +61 -0
- package/dist/drivers/runner.js +388 -0
- package/dist/drivers/store.d.ts +49 -0
- package/dist/drivers/store.js +91 -0
- package/dist/drivers/turn.d.ts +41 -0
- package/dist/drivers/turn.js +99 -0
- package/dist/drivers/types.d.ts +122 -0
- package/dist/drivers/types.js +11 -0
- package/dist/git/info.d.ts +75 -0
- package/dist/git/info.js +191 -0
- package/dist/hooks/protocol.js +6 -1
- package/dist/hooks/types.d.ts +10 -1
- package/dist/hooks/types.js +2 -0
- package/dist/host/api-impl.d.ts +7 -0
- package/dist/host/api-impl.js +15 -0
- package/dist/host/types.d.ts +24 -2
- package/dist/host/types.js +4 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1 -0
- package/dist/modes/acp/acp-events.d.ts +46 -0
- package/dist/modes/acp/acp-events.js +233 -0
- package/dist/modes/acp/acp-mode.d.ts +17 -0
- package/dist/modes/acp/acp-mode.js +47 -0
- package/dist/modes/acp/acp-server.d.ts +79 -0
- package/dist/modes/acp/acp-server.js +315 -0
- package/dist/modes/commands-core.d.ts +7 -1
- package/dist/modes/commands-core.js +61 -5
- package/dist/modes/image-input.d.ts +12 -4
- package/dist/modes/image-input.js +22 -5
- package/dist/modes/interactive/agent-panels.d.ts +14 -0
- package/dist/modes/interactive/agent-panels.js +103 -0
- package/dist/modes/interactive/agent-ui.d.ts +73 -0
- package/dist/modes/interactive/agent-ui.js +234 -0
- package/dist/modes/interactive/approval-dialog.d.ts +40 -7
- package/dist/modes/interactive/approval-dialog.js +192 -35
- package/dist/modes/interactive/approval-merge.d.ts +41 -0
- package/dist/modes/interactive/approval-merge.js +89 -0
- package/dist/modes/interactive/clipboard-paste.d.ts +18 -0
- package/dist/modes/interactive/clipboard-paste.js +28 -0
- package/dist/modes/interactive/commands.d.ts +20 -3
- package/dist/modes/interactive/commands.js +75 -16
- package/dist/modes/interactive/double-esc.d.ts +20 -0
- package/dist/modes/interactive/double-esc.js +34 -0
- package/dist/modes/interactive/event-notices.d.ts +32 -0
- package/dist/modes/interactive/event-notices.js +79 -0
- package/dist/modes/interactive/external-editor.d.ts +16 -0
- package/dist/modes/interactive/external-editor.js +39 -0
- package/dist/modes/interactive/interactive-mode.d.ts +16 -2
- package/dist/modes/interactive/interactive-mode.js +184 -202
- package/dist/modes/interactive/key-dispatch.d.ts +18 -2
- package/dist/modes/interactive/key-dispatch.js +53 -6
- package/dist/modes/interactive/line/line-mode.d.ts +3 -1
- package/dist/modes/interactive/line/line-mode.js +28 -9
- package/dist/modes/interactive/line/line-render.d.ts +6 -1
- package/dist/modes/interactive/line/line-render.js +66 -8
- package/dist/modes/interactive/message-view.d.ts +49 -10
- package/dist/modes/interactive/message-view.js +262 -46
- package/dist/modes/interactive/panels.d.ts +35 -0
- package/dist/modes/interactive/panels.js +157 -0
- package/dist/modes/interactive/pickers.d.ts +23 -2
- package/dist/modes/interactive/pickers.js +48 -15
- package/dist/modes/interactive/plan-command.d.ts +40 -0
- package/dist/modes/interactive/plan-command.js +129 -0
- package/dist/modes/interactive/plan-dialog.d.ts +98 -0
- package/dist/modes/interactive/plan-dialog.js +290 -0
- package/dist/modes/interactive/plan-flow.d.ts +34 -0
- package/dist/modes/interactive/plan-flow.js +98 -0
- package/dist/modes/interactive/rewind-command.d.ts +31 -0
- package/dist/modes/interactive/rewind-command.js +106 -0
- package/dist/modes/interactive/rewind-flow.d.ts +37 -0
- package/dist/modes/interactive/rewind-flow.js +151 -0
- package/dist/modes/interactive/rewind-list.d.ts +36 -0
- package/dist/modes/interactive/rewind-list.js +123 -0
- package/dist/modes/interactive/rewind-panel.d.ts +77 -0
- package/dist/modes/interactive/rewind-panel.js +309 -0
- package/dist/modes/interactive/rewind-text.d.ts +40 -0
- package/dist/modes/interactive/rewind-text.js +139 -0
- package/dist/modes/interactive/run-indicator.d.ts +51 -0
- package/dist/modes/interactive/run-indicator.js +189 -0
- package/dist/modes/interactive/session-events.d.ts +24 -0
- package/dist/modes/interactive/session-events.js +96 -0
- package/dist/modes/interactive/startup-header.d.ts +40 -0
- package/dist/modes/interactive/startup-header.js +169 -0
- package/dist/modes/interactive/status-area.d.ts +73 -0
- package/dist/modes/interactive/status-area.js +190 -0
- package/dist/modes/interactive/status-bar.d.ts +107 -16
- package/dist/modes/interactive/status-bar.js +306 -81
- package/dist/modes/interactive/status-line.d.ts +33 -0
- package/dist/modes/interactive/status-line.js +113 -0
- package/dist/modes/interactive/subagent-view.d.ts +56 -0
- package/dist/modes/interactive/subagent-view.js +154 -0
- package/dist/modes/interactive/tasks-report.d.ts +27 -0
- package/dist/modes/interactive/tasks-report.js +114 -0
- package/dist/modes/interactive/tool-summary.d.ts +46 -0
- package/dist/modes/interactive/tool-summary.js +218 -0
- package/dist/modes/interactive/tool-view.d.ts +58 -15
- package/dist/modes/interactive/tool-view.js +233 -145
- package/dist/modes/print/print-mode.d.ts +40 -4
- package/dist/modes/print/print-mode.js +161 -8
- package/dist/modes/rpc/commands.d.ts +9 -0
- package/dist/modes/rpc/commands.js +49 -0
- package/dist/modes/rpc/rpc-mode.js +7 -1
- package/dist/modes/session-report.d.ts +11 -0
- package/dist/modes/session-report.js +48 -1
- package/dist/permissions/auto-safe.d.ts +65 -0
- package/dist/permissions/auto-safe.js +547 -0
- package/dist/permissions/classifier.d.ts +68 -0
- package/dist/permissions/classifier.js +186 -0
- package/dist/permissions/dangerous.d.ts +5 -0
- package/dist/permissions/dangerous.js +1 -1
- package/dist/permissions/modes.d.ts +30 -0
- package/dist/permissions/modes.js +78 -0
- package/dist/permissions/pipeline.d.ts +72 -6
- package/dist/permissions/pipeline.js +306 -11
- package/dist/permissions/protected.d.ts +19 -0
- package/dist/permissions/protected.js +74 -0
- package/dist/permissions/readonly-bash.d.ts +30 -0
- package/dist/permissions/readonly-bash.js +118 -0
- package/dist/permissions/rules.js +3 -0
- package/dist/permissions/types.d.ts +92 -3
- package/dist/permissions/types.js +3 -0
- package/dist/plan/compose.d.ts +9 -0
- package/dist/plan/compose.js +19 -0
- package/dist/plan/controller.d.ts +71 -0
- package/dist/plan/controller.js +27 -0
- package/dist/plan/done-markers.d.ts +17 -0
- package/dist/plan/done-markers.js +51 -0
- package/dist/plan/extract.d.ts +29 -0
- package/dist/plan/extract.js +160 -0
- package/dist/plan/prompts.d.ts +36 -0
- package/dist/plan/prompts.js +89 -0
- package/dist/plan/store.d.ts +37 -0
- package/dist/plan/store.js +90 -0
- package/dist/rpc.d.ts +58 -2
- package/dist/rpc.js +7 -0
- package/dist/sandbox/bash.d.ts +74 -0
- package/dist/sandbox/bash.js +126 -0
- package/dist/sandbox/detect.d.ts +48 -0
- package/dist/sandbox/detect.js +149 -0
- package/dist/sandbox/index.d.ts +5 -0
- package/dist/sandbox/index.js +5 -0
- package/dist/sandbox/profile.d.ts +33 -0
- package/dist/sandbox/profile.js +76 -0
- package/dist/sandbox/wrap.d.ts +29 -0
- package/dist/sandbox/wrap.js +117 -0
- package/dist/sdk.d.ts +42 -5
- package/dist/sdk.js +34 -4
- package/dist/session/export.d.ts +32 -0
- package/dist/session/export.js +187 -0
- package/dist/session/redact.d.ts +15 -0
- package/dist/session/redact.js +55 -0
- package/dist/session/reuse.d.ts +33 -0
- package/dist/session/reuse.js +86 -0
- package/dist/session/scan.d.ts +34 -0
- package/dist/session/scan.js +140 -0
- package/dist/session/search.d.ts +52 -0
- package/dist/session/search.js +211 -0
- package/dist/session/stats-aggregate.d.ts +63 -0
- package/dist/session/stats-aggregate.js +163 -0
- package/dist/session/stats-index.d.ts +26 -0
- package/dist/session/stats-index.js +91 -0
- package/dist/session/stats-scan.d.ts +54 -0
- package/dist/session/stats-scan.js +236 -0
- package/dist/session/types.d.ts +3 -1
- package/dist/session/types.js +1 -0
- package/dist/skills/builtin.d.ts +31 -0
- package/dist/skills/builtin.js +109 -0
- package/dist/skills/discover.d.ts +2 -1
- package/dist/skills/index-prompt.js +5 -8
- package/dist/tools/background-jobs.d.ts +71 -0
- package/dist/tools/background-jobs.js +198 -0
- package/dist/tools/bash.d.ts +53 -1
- package/dist/tools/bash.js +158 -7
- package/dist/tools/clipboard-image.d.ts +44 -0
- package/dist/tools/clipboard-image.js +148 -0
- package/dist/tools/edit.d.ts +2 -0
- package/dist/tools/edit.js +18 -3
- package/dist/tools/image-file.d.ts +38 -3
- package/dist/tools/image-file.js +81 -10
- package/dist/tools/image-resize.d.ts +58 -0
- package/dist/tools/image-resize.js +97 -0
- package/dist/tools/presets.d.ts +40 -8
- package/dist/tools/presets.js +65 -19
- package/dist/tools/read.d.ts +5 -2
- package/dist/tools/read.js +13 -10
- package/dist/tools/registry.d.ts +7 -1
- package/dist/tools/registry.js +27 -4
- package/dist/tools/task-ctl.d.ts +22 -0
- package/dist/tools/task-ctl.js +116 -0
- package/dist/tools/task.d.ts +22 -10
- package/dist/tools/task.js +66 -26
- package/dist/tools/todo.d.ts +22 -2
- package/dist/tools/todo.js +58 -14
- package/dist/tools/truncate.d.ts +15 -0
- package/dist/tools/truncate.js +25 -0
- package/dist/tools/types.d.ts +113 -0
- package/dist/tools/types.js +5 -0
- package/dist/tools/write.js +3 -0
- package/dist/tui/component.d.ts +8 -2
- package/dist/tui/component.js +3 -1
- package/dist/tui/components/box.d.ts +6 -1
- package/dist/tui/components/box.js +16 -6
- package/dist/tui/components/card.d.ts +23 -0
- package/dist/tui/components/card.js +37 -0
- package/dist/tui/components/editor-history.d.ts +6 -0
- package/dist/tui/components/editor-history.js +45 -0
- package/dist/tui/components/editor-paste.d.ts +1 -1
- package/dist/tui/components/editor-paste.js +4 -4
- package/dist/tui/components/editor.d.ts +11 -5
- package/dist/tui/components/editor.js +52 -58
- package/dist/tui/components/key-value.d.ts +3 -0
- package/dist/tui/components/key-value.js +16 -6
- package/dist/tui/components/loader.d.ts +37 -7
- package/dist/tui/components/loader.js +84 -21
- package/dist/tui/components/markdown.d.ts +5 -1
- package/dist/tui/components/markdown.js +45 -21
- package/dist/tui/components/meter.d.ts +3 -3
- package/dist/tui/components/meter.js +13 -11
- package/dist/tui/components/select-list.d.ts +23 -1
- package/dist/tui/components/select-list.js +76 -13
- package/dist/tui/glyphs.d.ts +72 -0
- package/dist/tui/glyphs.js +118 -0
- package/dist/tui/keybindings.d.ts +5 -0
- package/dist/tui/keybindings.js +5 -0
- package/dist/tui/theme.d.ts +30 -6
- package/dist/tui/theme.js +103 -17
- package/dist/tui.d.ts +4 -2
- package/dist/tui.js +3 -1
- package/docs/acp.md +78 -0
- package/docs/agents.md +250 -0
- package/docs/codemode.md +28 -10
- package/docs/hooks.md +36 -32
- package/docs/permissions.md +212 -0
- package/docs/plan.md +107 -0
- package/docs/providers.md +261 -62
- package/docs/rewind-plan.md +181 -0
- package/docs/rpc.md +127 -40
- package/docs/sandbox.md +215 -0
- package/docs/session-format.md +43 -22
- package/docs/sessions.md +174 -0
- package/docs/tui-design.md +751 -0
- package/docs/tui.md +260 -64
- package/package.json +15 -2
|
@@ -19,8 +19,14 @@
|
|
|
19
19
|
* 重新物化(协议、地址、headers、compat 取渠道的,模型级 api / baseUrl 仍覆盖);渠道 key 经
|
|
20
20
|
* `resolveApiKey(provider, channel)`。没有 `channels` 的供应商行为不变。
|
|
21
21
|
*
|
|
22
|
+
* 内置渠道([W5-M2],builtin.ts):用户 `channels` 同名字段级覆盖、新名追加,`defaultChannel` 用户优先
|
|
23
|
+
* (也可只写 `defaultChannel`,或只写 `api` 选同协议的内置渠道);目录模型缺省挂全部渠道、缺省渠道在前。
|
|
24
|
+
* 用户(config / auth.json / `*_BASE_URL`)改了供应商级 baseUrl 而没写自己的 `channels` 时,内置渠道作废,
|
|
25
|
+
* 按单渠道回落(`api` 取用户写的或内置的回落协议)。
|
|
26
|
+
*
|
|
22
27
|
* models.dev(enrich.ts):config 里缺元数据的自定义模型与合成模型,用传入的索引(只读缓存)补
|
|
23
|
-
* contextWindow / maxTokens / input / reasoning / cost,来源记在 `modelMetadata()
|
|
28
|
+
* contextWindow / maxTokens / input / reasoning / cost,来源记在 `modelMetadata()`;内置目录按同一索引
|
|
29
|
+
* (快照 ⊕ `ama models refresh` 的覆盖)在 catalog.ts 合并,缺字段的条目退回内置快照。
|
|
24
30
|
*/
|
|
25
31
|
import { ApiRegistry, createDefaultApiRegistry } from "../apis/api.js";
|
|
26
32
|
import { fakeProviderData } from "../fake/fake-provider.js";
|
|
@@ -28,33 +34,10 @@ import { mergeHeaders } from "../http.js";
|
|
|
28
34
|
import { ApiKeyResolver } from "./auth.js";
|
|
29
35
|
import { BUILTIN_PROVIDERS, fallbackEnvKey, isRelayedBaseUrl } from "./builtin.js";
|
|
30
36
|
import { applyModelOverride, loadBuiltinCatalog, toModel, withCustomDefaults } from "./catalog.js";
|
|
31
|
-
import { channelKeyId, modelChannels, parseChannels, splitChannelRef } from "./channels.js";
|
|
37
|
+
import { catalogChannels, channelKeyId, dropChannels, materializeModel, pickBuiltinChannel, modelChannels, parseChannels, splitChannelRef, } from "./channels.js";
|
|
32
38
|
import { catalogMetadata, enrichEntry, lazyIndex, } from "./enrich.js";
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
* `explicit` 覆盖优先),headers / compat 按 供应商 ← 渠道 ← 模型 合并,并记下渠道名。
|
|
36
|
-
*/
|
|
37
|
-
export function materializeModel(model, provider, channel, explicit) {
|
|
38
|
-
const out = {
|
|
39
|
-
...model,
|
|
40
|
-
provider: provider.id,
|
|
41
|
-
baseUrl: model.baseUrl ?? provider.baseUrl,
|
|
42
|
-
};
|
|
43
|
-
if (channel !== undefined) {
|
|
44
|
-
out.api = explicit?.api ?? channel.api;
|
|
45
|
-
out.baseUrl = explicit?.baseUrl ?? channel.baseUrl;
|
|
46
|
-
out.channel = channel.name;
|
|
47
|
-
}
|
|
48
|
-
if (provider.headers || channel?.headers || model.headers)
|
|
49
|
-
out.headers = mergeHeaders(provider.headers, channel?.headers, model.headers);
|
|
50
|
-
if (provider.compat || channel?.compat || model.compat)
|
|
51
|
-
out.compat = { ...provider.compat, ...channel?.compat, ...model.compat };
|
|
52
|
-
const authHeader = channel?.authHeader ?? provider.authHeader;
|
|
53
|
-
if (authHeader !== undefined)
|
|
54
|
-
out.authHeader = model.authHeader ?? authHeader;
|
|
55
|
-
out.requiresApiKey = provider.requiresApiKey;
|
|
56
|
-
return out;
|
|
57
|
-
}
|
|
39
|
+
import { closest } from "./suggest.js";
|
|
40
|
+
export { materializeModel } from "./channels.js";
|
|
58
41
|
function configKeysOf(config) {
|
|
59
42
|
const keys = {};
|
|
60
43
|
for (const [id, provider] of Object.entries(config?.providers ?? {})) {
|
|
@@ -74,6 +57,10 @@ export class ProviderRegistry {
|
|
|
74
57
|
envBaseUrls = new Map();
|
|
75
58
|
/** baseUrl 指向非官方主机的内置供应商:接受目录外的 model id。 */
|
|
76
59
|
relayed = new Set();
|
|
60
|
+
/** config 里写了自己 `channels` 的供应商(内置渠道不因改 baseUrl 作废)。 */
|
|
61
|
+
userChannels = new Set();
|
|
62
|
+
/** config 里写了供应商级 `api` 的供应商(单渠道回落时目录模型跟它走)。 */
|
|
63
|
+
userApi = new Set();
|
|
77
64
|
/** `provider/model` → 物化前的模型(多渠道供应商切换渠道时重新物化)。 */
|
|
78
65
|
raw = new Map();
|
|
79
66
|
/** `provider/model` → 元数据来源与 models.dev 匹配。 */
|
|
@@ -91,9 +78,9 @@ export class ProviderRegistry {
|
|
|
91
78
|
configKeys: options.keys?.configKeys ?? configKeysOf(options.config),
|
|
92
79
|
onWarning: (message) => this.warn(message),
|
|
93
80
|
});
|
|
94
|
-
const catalog =
|
|
81
|
+
const catalog = this.loadCatalog();
|
|
95
82
|
const env = options.keys?.useEnv === false ? {} : (options.keys?.env ?? process.env);
|
|
96
|
-
for (const { baseUrlEnv, ...base } of BUILTIN_PROVIDERS) {
|
|
83
|
+
for (const { baseUrlEnv, catalogApi: _catalogApi, ...base } of BUILTIN_PROVIDERS) {
|
|
97
84
|
const models = (catalog.get(base.id) ?? []).map((entry) => {
|
|
98
85
|
const api = entry.api ?? base.api;
|
|
99
86
|
this.sources.set(`${base.id}/${entry.id}`, "builtin");
|
|
@@ -106,12 +93,12 @@ export class ProviderRegistry {
|
|
|
106
93
|
const fromEnv = baseUrlEnv !== undefined ? env[baseUrlEnv]?.trim() : undefined;
|
|
107
94
|
if (baseUrlEnv !== undefined && fromEnv)
|
|
108
95
|
this.envBaseUrls.set(base.id, baseUrlEnv);
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
96
|
+
const provider = { ...structuredClone(base), models, builtin: true };
|
|
97
|
+
if (fromEnv) {
|
|
98
|
+
provider.baseUrl = fromEnv;
|
|
99
|
+
dropChannels(provider);
|
|
100
|
+
}
|
|
101
|
+
this.providers.set(base.id, provider);
|
|
115
102
|
}
|
|
116
103
|
for (const [id, config] of Object.entries(options.config?.providers ?? {})) {
|
|
117
104
|
this.applyConfig(id, config);
|
|
@@ -121,6 +108,8 @@ export class ProviderRegistry {
|
|
|
121
108
|
if (baseUrl) {
|
|
122
109
|
provider.baseUrl = baseUrl;
|
|
123
110
|
this.envBaseUrls.delete(provider.id);
|
|
111
|
+
if (provider.builtin && !this.userChannels.has(provider.id))
|
|
112
|
+
dropChannels(provider);
|
|
124
113
|
}
|
|
125
114
|
if (provider.builtin && isRelayedBaseUrl(provider.id, provider.baseUrl)) {
|
|
126
115
|
this.relayed.add(provider.id);
|
|
@@ -135,9 +124,52 @@ export class ProviderRegistry {
|
|
|
135
124
|
this.providers.set(fake.id, fake);
|
|
136
125
|
}
|
|
137
126
|
for (const provider of this.providers.values()) {
|
|
127
|
+
if (provider.builtin)
|
|
128
|
+
this.settleBuiltinChannels(provider);
|
|
138
129
|
provider.models = provider.models.map((model) => this.materialize(provider, model));
|
|
139
130
|
}
|
|
140
131
|
}
|
|
132
|
+
/** 内置目录(快照 ⊕ 用户刷新);刷新数据出任何问题都退回内置快照,不让启动失败。 */
|
|
133
|
+
loadCatalog() {
|
|
134
|
+
try {
|
|
135
|
+
return loadBuiltinCatalog(this.modelsDev());
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
this.warn(`models.dev refresh data ignored: ${error.message}`);
|
|
139
|
+
return loadBuiltinCatalog();
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* 内置供应商定渠道:供应商级 api / baseUrl 取缺省渠道的(discover 等单地址的用法看它);用户没指定渠道的
|
|
144
|
+
* 模型挂全部渠道(缺省在前)。渠道已作废的去掉模型上残留的 `channels`。
|
|
145
|
+
*/
|
|
146
|
+
settleBuiltinChannels(provider) {
|
|
147
|
+
const channels = provider.channels;
|
|
148
|
+
if (channels === undefined || channels.length === 0) {
|
|
149
|
+
// 单渠道回落:没有模型级协议的目录模型走 catalogApi(用户改了 api 时走用户的)
|
|
150
|
+
const builtin = BUILTIN_PROVIDERS.find((p) => p.id === provider.id);
|
|
151
|
+
const api = builtin === undefined || this.userApi.has(provider.id)
|
|
152
|
+
? provider.api
|
|
153
|
+
: (builtin.catalogApi ?? builtin.api);
|
|
154
|
+
for (const model of provider.models) {
|
|
155
|
+
delete model.channels;
|
|
156
|
+
const key = `${provider.id}/${model.id}`;
|
|
157
|
+
if (this.sources.get(key) === "builtin" && this.raw.get(key)?.explicit.api === undefined)
|
|
158
|
+
model.api = api;
|
|
159
|
+
}
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const first = channels.find((c) => c.name === provider.defaultChannel) ?? channels[0];
|
|
163
|
+
if (first === undefined)
|
|
164
|
+
return;
|
|
165
|
+
provider.defaultChannel = first.name;
|
|
166
|
+
provider.api = first.api;
|
|
167
|
+
provider.baseUrl = first.baseUrl;
|
|
168
|
+
for (const model of provider.models) {
|
|
169
|
+
if (this.sources.get(`${provider.id}/${model.id}`) === "builtin" || !model.channels)
|
|
170
|
+
model.channels = catalogChannels(model.channels, channels, first.name);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
141
173
|
warn(message) {
|
|
142
174
|
this.warnings.push(message);
|
|
143
175
|
this.onWarning?.(message);
|
|
@@ -159,7 +191,15 @@ export class ProviderRegistry {
|
|
|
159
191
|
}
|
|
160
192
|
applyConfig(id, config) {
|
|
161
193
|
const existing = this.providers.get(id);
|
|
162
|
-
const
|
|
194
|
+
const builtinChannels = existing?.builtin ? existing.channels : undefined;
|
|
195
|
+
const parsed = config.channels !== undefined
|
|
196
|
+
? parseChannels(id, config, builtinChannels && {
|
|
197
|
+
channels: builtinChannels,
|
|
198
|
+
defaultChannel: existing?.defaultChannel,
|
|
199
|
+
})
|
|
200
|
+
: undefined;
|
|
201
|
+
if (config.channels !== undefined)
|
|
202
|
+
this.userChannels.add(id);
|
|
163
203
|
for (const warning of parsed?.warnings ?? [])
|
|
164
204
|
this.warn(warning);
|
|
165
205
|
const first = parsed?.channels.find((c) => c.name === parsed.defaultChannel);
|
|
@@ -179,12 +219,16 @@ export class ProviderRegistry {
|
|
|
179
219
|
};
|
|
180
220
|
if (config.name !== undefined)
|
|
181
221
|
provider.name = config.name;
|
|
182
|
-
if (config.api !== undefined)
|
|
222
|
+
if (config.api !== undefined) {
|
|
183
223
|
provider.api = config.api;
|
|
224
|
+
this.userApi.add(id);
|
|
225
|
+
}
|
|
184
226
|
if (config.baseUrl !== undefined) {
|
|
185
227
|
provider.baseUrl = config.baseUrl;
|
|
186
228
|
this.envBaseUrls.delete(id);
|
|
187
229
|
}
|
|
230
|
+
if (builtinChannels !== undefined && parsed === undefined)
|
|
231
|
+
pickBuiltinChannel(provider, config, (m) => this.warn(m));
|
|
188
232
|
if (parsed !== undefined && first !== undefined) {
|
|
189
233
|
// 有渠道时供应商级 api / baseUrl 取首选渠道的(discover 等单地址的用法看它)。
|
|
190
234
|
provider.channels = parsed.channels;
|
|
@@ -214,7 +258,8 @@ export class ProviderRegistry {
|
|
|
214
258
|
if (typeof entry.modelsDev === "string" && metadata.looked && metadata.match === undefined)
|
|
215
259
|
this.warn(`modelsDev "${entry.modelsDev}" for "${id}/${entry.id}" not found`);
|
|
216
260
|
const model = withCustomDefaults(filled, id, entry.api ?? provider.api);
|
|
217
|
-
|
|
261
|
+
// 内置供应商上没写 channels 的模型:定渠道时挂全部渠道(settleBuiltinChannels)
|
|
262
|
+
if (provider.channels !== undefined && (entry.channels !== undefined || !provider.builtin))
|
|
218
263
|
model.channels = channelsOf(entry.channels, entry.id);
|
|
219
264
|
const index = provider.models.findIndex((m) => m.id === entry.id);
|
|
220
265
|
if (index >= 0)
|
|
@@ -262,11 +307,6 @@ export class ProviderRegistry {
|
|
|
262
307
|
if (fields[field] !== undefined)
|
|
263
308
|
meta.sources[field] = "config";
|
|
264
309
|
}
|
|
265
|
-
if (provider.channels !== undefined) {
|
|
266
|
-
// 目录模型(给内置供应商加了渠道时)挂到首选渠道。
|
|
267
|
-
for (const model of provider.models)
|
|
268
|
-
model.channels ??= [provider.defaultChannel ?? ""];
|
|
269
|
-
}
|
|
270
310
|
this.providers.set(id, provider);
|
|
271
311
|
}
|
|
272
312
|
/** baseUrl 来自哪个环境变量(未生效返回 undefined)。 */
|
|
@@ -326,36 +366,40 @@ export class ProviderRegistry {
|
|
|
326
366
|
const channelData = provider.channels?.find((c) => c.name === (channel ?? model.channels?.[0]));
|
|
327
367
|
return materializeModel(model, provider, channelData);
|
|
328
368
|
}
|
|
329
|
-
/** 按渠道取模型:渠道不在模型的 channels 里 →
|
|
369
|
+
/** 按渠道取模型:渠道不在模型的 channels 里 → channel_not_found,列出可用渠道。 */
|
|
330
370
|
withChannel(provider, model, channel) {
|
|
331
371
|
const available = model.channels ?? [];
|
|
332
|
-
if (!available.includes(channel)) {
|
|
372
|
+
if (!available.includes(channel) || !provider.channels?.some((c) => c.name === channel)) {
|
|
333
373
|
return {
|
|
334
374
|
ok: false,
|
|
335
|
-
reason: "
|
|
336
|
-
candidates: available.map((c) => `${provider.id}/${model.id}@${c}`),
|
|
375
|
+
reason: "channel_not_found",
|
|
376
|
+
candidates: available.filter(Boolean).map((c) => `${provider.id}/${model.id}@${c}`),
|
|
337
377
|
};
|
|
338
378
|
}
|
|
339
379
|
if (channel === model.channel)
|
|
340
380
|
return { ok: true, model, provider };
|
|
341
381
|
return { ok: true, model: this.materialize(provider, model, channel), provider };
|
|
342
382
|
}
|
|
383
|
+
/**
|
|
384
|
+
* `provider/model`、`provider/model@渠道` 或裸模型 id。`@` 先按渠道解析(id 里本来就带 `@` 且已登记的
|
|
385
|
+
* 模型除外),中转供应商的「未登记即合成」不会把 `@渠道` 吞进模型 id。失败的 reason:供应商不存在 →
|
|
386
|
+
* provider_not_found(候选是编辑距离最近的供应商);渠道不存在 → channel_not_found;模型不存在 →
|
|
387
|
+
* not_found(候选是最接近的模型)。
|
|
388
|
+
*/
|
|
343
389
|
findModel(ref) {
|
|
344
390
|
const trimmed = ref.trim();
|
|
345
|
-
const direct = this.findPlain(trimmed);
|
|
346
|
-
if (direct.ok)
|
|
347
|
-
return direct;
|
|
348
391
|
const split = splitChannelRef(trimmed);
|
|
349
392
|
if (split === undefined)
|
|
350
|
-
return
|
|
393
|
+
return this.findPlain(trimmed);
|
|
394
|
+
const exact = this.findPlain(trimmed, undefined, false);
|
|
395
|
+
if (exact.ok)
|
|
396
|
+
return exact;
|
|
351
397
|
const base = this.findPlain(split.base, split.channel);
|
|
352
398
|
if (!base.ok)
|
|
353
|
-
return base
|
|
354
|
-
if (!base.provider.channels?.some((c) => c.name === split.channel))
|
|
355
|
-
return direct;
|
|
399
|
+
return base;
|
|
356
400
|
return this.withChannel(base.provider, base.model, split.channel);
|
|
357
401
|
}
|
|
358
|
-
findPlain(trimmed, channel) {
|
|
402
|
+
findPlain(trimmed, channel, synthesize = true) {
|
|
359
403
|
const slash = trimmed.indexOf("/");
|
|
360
404
|
if (slash > 0) {
|
|
361
405
|
const provider = this.providers.get(trimmed.slice(0, slash));
|
|
@@ -364,7 +408,8 @@ export class ProviderRegistry {
|
|
|
364
408
|
const model = provider.models.find((m) => m.id === id);
|
|
365
409
|
if (model)
|
|
366
410
|
return { ok: true, model, provider };
|
|
367
|
-
|
|
411
|
+
const relayed = provider.models.length === 0 || this.relayed.has(provider.id);
|
|
412
|
+
if (synthesize && relayed && id.length > 0) {
|
|
368
413
|
const synthesized = this.synthesize(provider, id);
|
|
369
414
|
if (channel !== undefined && provider.channels?.some((c) => c.name === channel))
|
|
370
415
|
synthesized.channels = [...new Set([...(synthesized.channels ?? []), channel])];
|
|
@@ -374,6 +419,14 @@ export class ProviderRegistry {
|
|
|
374
419
|
}
|
|
375
420
|
}
|
|
376
421
|
const matches = this.listModels().filter((entry) => entry.model.id === trimmed);
|
|
422
|
+
if (matches.length === 0 && slash > 0) {
|
|
423
|
+
const ids = [...this.providers.keys()];
|
|
424
|
+
return {
|
|
425
|
+
ok: false,
|
|
426
|
+
reason: "provider_not_found",
|
|
427
|
+
candidates: closest(trimmed.slice(0, slash), ids),
|
|
428
|
+
};
|
|
429
|
+
}
|
|
377
430
|
if (matches.length === 1 && matches[0]) {
|
|
378
431
|
return { ok: true, model: matches[0].model, provider: matches[0].provider };
|
|
379
432
|
}
|
|
@@ -390,16 +443,10 @@ export class ProviderRegistry {
|
|
|
390
443
|
candidates: (configured.length > 0 ? configured : matches).map((entry) => `${entry.provider.id}/${entry.model.id}`),
|
|
391
444
|
};
|
|
392
445
|
}
|
|
446
|
+
/** 最接近的模型(包含关系优先,其次编辑距离),`provider/id` 形式。 */
|
|
393
447
|
similar(id, providerId) {
|
|
394
|
-
const
|
|
395
|
-
return
|
|
396
|
-
.filter((entry) => providerId === undefined || entry.provider.id === providerId)
|
|
397
|
-
.filter((entry) => {
|
|
398
|
-
const candidate = entry.model.id.toLowerCase();
|
|
399
|
-
return needle.length > 0 && (candidate.includes(needle) || needle.includes(candidate));
|
|
400
|
-
})
|
|
401
|
-
.slice(0, 10)
|
|
402
|
-
.map((entry) => `${entry.provider.id}/${entry.model.id}`);
|
|
448
|
+
const entries = this.listModels().filter((entry) => providerId === undefined || entry.provider.id === providerId);
|
|
449
|
+
return closest(id, entries, 5, (entry) => entry.model.id).map((entry) => `${entry.provider.id}/${entry.model.id}`);
|
|
403
450
|
}
|
|
404
451
|
hasConfiguredKey(providerId) {
|
|
405
452
|
const provider = this.providers.get(providerId);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 模型 / 供应商 / 渠道写错时的候选与报错文案(W4-C)。
|
|
3
|
+
*
|
|
4
|
+
* 候选排序:包含关系(`sonnet` ⊂ `claude-sonnet-5`)优先,其次按编辑距离;距离超过
|
|
5
|
+
* `max(2, ⌈长度 / 3⌉)` 的不算接近。只比较 id 本身(不含 `provider/` 前缀),大小写不敏感。
|
|
6
|
+
*/
|
|
7
|
+
import type { ModelLookup } from "../types.js";
|
|
8
|
+
/** Levenshtein 距离(插入 / 删除 / 替换各计 1)。 */
|
|
9
|
+
export declare function editDistance(a: string, b: string): number;
|
|
10
|
+
/**
|
|
11
|
+
* 从 `candidates` 里挑与 `needle` 最接近的至多 `limit` 个。`key` 取参与比较的部分
|
|
12
|
+
* (缺省整串),返回原值。
|
|
13
|
+
*/
|
|
14
|
+
export declare function closest<T>(needle: string, candidates: readonly T[], limit?: number, key?: (item: T) => string): T[];
|
|
15
|
+
/** 解析失败的一行说明(不含前缀标签):`渠道不存在:x;该模型可用渠道:…` 等。 */
|
|
16
|
+
export declare function describeLookupFailure(ref: string, failure: Extract<ModelLookup, {
|
|
17
|
+
ok: false;
|
|
18
|
+
}>): string;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 模型 / 供应商 / 渠道写错时的候选与报错文案(W4-C)。
|
|
3
|
+
*
|
|
4
|
+
* 候选排序:包含关系(`sonnet` ⊂ `claude-sonnet-5`)优先,其次按编辑距离;距离超过
|
|
5
|
+
* `max(2, ⌈长度 / 3⌉)` 的不算接近。只比较 id 本身(不含 `provider/` 前缀),大小写不敏感。
|
|
6
|
+
*/
|
|
7
|
+
/** Levenshtein 距离(插入 / 删除 / 替换各计 1)。 */
|
|
8
|
+
export function editDistance(a, b) {
|
|
9
|
+
if (a === b)
|
|
10
|
+
return 0;
|
|
11
|
+
if (a.length === 0)
|
|
12
|
+
return b.length;
|
|
13
|
+
if (b.length === 0)
|
|
14
|
+
return a.length;
|
|
15
|
+
let prev = Array.from({ length: b.length + 1 }, (_, i) => i);
|
|
16
|
+
for (let i = 1; i <= a.length; i++) {
|
|
17
|
+
const row = [i];
|
|
18
|
+
for (let j = 1; j <= b.length; j++) {
|
|
19
|
+
const cost = a[i - 1] === b[j - 1] ? 0 : 1;
|
|
20
|
+
row[j] = Math.min((prev[j] ?? 0) + 1, (row[j - 1] ?? 0) + 1, (prev[j - 1] ?? 0) + cost);
|
|
21
|
+
}
|
|
22
|
+
prev = row;
|
|
23
|
+
}
|
|
24
|
+
return prev[b.length] ?? 0;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* 从 `candidates` 里挑与 `needle` 最接近的至多 `limit` 个。`key` 取参与比较的部分
|
|
28
|
+
* (缺省整串),返回原值。
|
|
29
|
+
*/
|
|
30
|
+
export function closest(needle, candidates, limit = 5, key = String) {
|
|
31
|
+
const target = needle.toLowerCase();
|
|
32
|
+
if (target === "")
|
|
33
|
+
return [];
|
|
34
|
+
const budget = Math.max(2, Math.ceil(target.length / 3));
|
|
35
|
+
const scored = [];
|
|
36
|
+
candidates.forEach((item, index) => {
|
|
37
|
+
const value = key(item).toLowerCase();
|
|
38
|
+
if (value === "")
|
|
39
|
+
return;
|
|
40
|
+
if (value.includes(target) || target.includes(value)) {
|
|
41
|
+
scored.push({ item, score: Math.abs(value.length - target.length) / 1000, index });
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const distance = editDistance(target, value);
|
|
45
|
+
if (distance <= budget)
|
|
46
|
+
scored.push({ item, score: distance, index });
|
|
47
|
+
});
|
|
48
|
+
return scored
|
|
49
|
+
.sort((a, b) => a.score - b.score || a.index - b.index)
|
|
50
|
+
.slice(0, limit)
|
|
51
|
+
.map((entry) => entry.item);
|
|
52
|
+
}
|
|
53
|
+
/** 解析失败的一行说明(不含前缀标签):`渠道不存在:x;该模型可用渠道:…` 等。 */
|
|
54
|
+
export function describeLookupFailure(ref, failure) {
|
|
55
|
+
const list = failure.candidates.slice(0, 20).join(", ");
|
|
56
|
+
switch (failure.reason) {
|
|
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
|
+
}
|
|
72
|
+
}
|
package/dist/ai/sse.d.ts
CHANGED
|
@@ -28,5 +28,9 @@ export declare class SseParser {
|
|
|
28
28
|
private processLine;
|
|
29
29
|
private dispatch;
|
|
30
30
|
}
|
|
31
|
-
/**
|
|
32
|
-
|
|
31
|
+
/**
|
|
32
|
+
* 从字节流读 SSE 事件;`signal` 中止时停止读取(调用方据此产出 aborted)。
|
|
33
|
+
* `idleTimeoutMs`:等待下一块字节的上限,每收到一块即重新计时(消费者处理事件的时间不计);
|
|
34
|
+
* 超时取消底层流并抛 `IdleTimeoutError`(phase `stream`)。
|
|
35
|
+
*/
|
|
36
|
+
export declare function readSseEvents(body: ReadableStream<Uint8Array>, signal?: AbortSignal, idleTimeoutMs?: number): AsyncGenerator<SseEvent>;
|
package/dist/ai/sse.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* 第一个空格去掉;多条 data 以 LF 连接。为兼容不规范服务端,流结束时未以空行收尾的最后一个
|
|
7
7
|
* 事件也会分派。
|
|
8
8
|
*/
|
|
9
|
+
import { IdleTimeoutError } from "./http.js";
|
|
9
10
|
export class SseParser {
|
|
10
11
|
buffer = "";
|
|
11
12
|
event;
|
|
@@ -102,8 +103,12 @@ export class SseParser {
|
|
|
102
103
|
return hadContent ? event : undefined;
|
|
103
104
|
}
|
|
104
105
|
}
|
|
105
|
-
/**
|
|
106
|
-
|
|
106
|
+
/**
|
|
107
|
+
* 从字节流读 SSE 事件;`signal` 中止时停止读取(调用方据此产出 aborted)。
|
|
108
|
+
* `idleTimeoutMs`:等待下一块字节的上限,每收到一块即重新计时(消费者处理事件的时间不计);
|
|
109
|
+
* 超时取消底层流并抛 `IdleTimeoutError`(phase `stream`)。
|
|
110
|
+
*/
|
|
111
|
+
export async function* readSseEvents(body, signal, idleTimeoutMs) {
|
|
107
112
|
const reader = body.getReader();
|
|
108
113
|
const decoder = new TextDecoder("utf-8");
|
|
109
114
|
const parser = new SseParser();
|
|
@@ -112,11 +117,25 @@ export async function* readSseEvents(body, signal) {
|
|
|
112
117
|
};
|
|
113
118
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
114
119
|
let drained = false;
|
|
120
|
+
let idle;
|
|
121
|
+
let stalled = false;
|
|
122
|
+
const arm = () => {
|
|
123
|
+
if (idleTimeoutMs === undefined || idleTimeoutMs <= 0)
|
|
124
|
+
return;
|
|
125
|
+
idle = setTimeout(() => {
|
|
126
|
+
stalled = true;
|
|
127
|
+
reader.cancel().catch(() => undefined);
|
|
128
|
+
}, idleTimeoutMs);
|
|
129
|
+
};
|
|
115
130
|
try {
|
|
116
131
|
while (true) {
|
|
117
132
|
if (signal?.aborted)
|
|
118
133
|
return;
|
|
134
|
+
arm();
|
|
119
135
|
const { value, done } = await reader.read();
|
|
136
|
+
clearTimeout(idle);
|
|
137
|
+
if (stalled && !signal?.aborted)
|
|
138
|
+
throw new IdleTimeoutError(idleTimeoutMs ?? 0, "stream");
|
|
120
139
|
if (done)
|
|
121
140
|
break;
|
|
122
141
|
if (signal?.aborted)
|
|
@@ -131,6 +150,7 @@ export async function* readSseEvents(body, signal) {
|
|
|
131
150
|
yield event;
|
|
132
151
|
}
|
|
133
152
|
finally {
|
|
153
|
+
clearTimeout(idle);
|
|
134
154
|
signal?.removeEventListener("abort", onAbort);
|
|
135
155
|
// 消费者提前退出(读到终止事件即 break)或中止:取消底层流,释放连接
|
|
136
156
|
if (!drained)
|
package/dist/ai/types.d.ts
CHANGED
|
@@ -15,6 +15,11 @@
|
|
|
15
15
|
* - [W3-C0] 第三波 §1.3 的五个缓存兼容开关单列为 `PromptCacheCompat`(各协议共用),只并入
|
|
16
16
|
* `ProviderCompat`(全部可选),不改各协议 compat 接口——`detectCompat` 的返回形状不变,
|
|
17
17
|
* 缺省值由 C1a 在协议层按端点推断。
|
|
18
|
+
* - [W5-C0] 第五波(docs/wave5-plan.md §2.1、§3.1):`Model` 加 models.dev 元数据字段
|
|
19
|
+
* (`family / knowledge / releaseDate / inputLimit / status`);`AnthropicMessagesCompat` 加
|
|
20
|
+
* `sendInterleavedThinkingBeta / sendCacheControl`、`OpenAIResponsesCompat` 加
|
|
21
|
+
* `explicitCacheField`,全部可选(缺省由 W5-M2 的主机推断表给出);`ProviderData.channels /
|
|
22
|
+
* defaultChannel` 已有,内置供应商(`BuiltinProvider`)同样可带。
|
|
18
23
|
*/
|
|
19
24
|
export type KnownApi = "anthropic-messages" | "openai-completions" | "openai-responses" | "google-generative-ai";
|
|
20
25
|
export type Api = KnownApi | (string & {});
|
|
@@ -27,7 +32,8 @@ export type CacheRetention = "none" | "short" | "long";
|
|
|
27
32
|
* 真实回合,`summary` 是压缩 / 分支摘要,`warm` 是缓存保温重放,`probe` 是 `models check` /
|
|
28
33
|
* `cache-probe` 一类的探测。缺省视为 `turn`。协议层只透传,不改变请求体。
|
|
29
34
|
*/
|
|
30
|
-
|
|
35
|
+
/** `classify`:auto 权限模式的分类请求(独立请求,不经会话层缓存观测、不触发保温)。 */
|
|
36
|
+
export type RequestPurpose = "turn" | "summary" | "warm" | "probe" | "classify";
|
|
31
37
|
/** `provider/model-id` 拆开后的引用。 */
|
|
32
38
|
export interface ModelRef {
|
|
33
39
|
provider: string;
|
|
@@ -206,6 +212,12 @@ export interface AnthropicMessagesCompat {
|
|
|
206
212
|
/** true:新模型用 `effort` 参数;false:老模型用 `budget_tokens`。 */
|
|
207
213
|
adaptiveThinking: boolean;
|
|
208
214
|
maxCacheBreakpoints: number;
|
|
215
|
+
/**
|
|
216
|
+
* [W5-C0] 发 `interleaved-thinking` beta 头;缺省(W5-M2 主机表):官方端点 true、其它主机 false。
|
|
217
|
+
*/
|
|
218
|
+
sendInterleavedThinkingBeta?: boolean;
|
|
219
|
+
/** [W5-C0] 打 `cache_control`;缺省 true,忽略它的端点(DeepSeek 等)可关以减小请求体。 */
|
|
220
|
+
sendCacheControl?: boolean;
|
|
209
221
|
}
|
|
210
222
|
/** B8 补全。 */
|
|
211
223
|
export interface GoogleCompat {
|
|
@@ -216,6 +228,8 @@ export interface GoogleCompat {
|
|
|
216
228
|
export interface OpenAIResponsesCompat {
|
|
217
229
|
supportsReasoningSummary: boolean;
|
|
218
230
|
supportsStore: boolean;
|
|
231
|
+
/** [W5-C0] 端点私有的显式缓存字段:`volcengine` = 火山方舟 `caching: { type: "enabled" }`。 */
|
|
232
|
+
explicitCacheField?: "volcengine";
|
|
219
233
|
}
|
|
220
234
|
/**
|
|
221
235
|
* [W3-C0] 供应商不报缓存时的处理(第三波 §1.6):`auto` 按响应自动判定三态;`silent` /
|
|
@@ -301,6 +315,16 @@ export interface Model {
|
|
|
301
315
|
channel?: string;
|
|
302
316
|
/** 该模型挂载的全部渠道,首个为首选(多渠道供应商才有)。 */
|
|
303
317
|
channels?: string[];
|
|
318
|
+
/** 模型家族(如 `claude-sonnet`)。 */
|
|
319
|
+
family?: string;
|
|
320
|
+
/** 知识截止(`YYYY-MM` 或 `YYYY-MM-DD`)。 */
|
|
321
|
+
knowledge?: string;
|
|
322
|
+
/** 发布日期(`YYYY-MM-DD`)。 */
|
|
323
|
+
releaseDate?: string;
|
|
324
|
+
/** 输入上限(token),与 `contextWindow` 不同的模型才有。 */
|
|
325
|
+
inputLimit?: number;
|
|
326
|
+
/** 发布状态;正式版不填(deprecated 的模型在快照里已过滤)。 */
|
|
327
|
+
status?: "beta";
|
|
304
328
|
}
|
|
305
329
|
/** 物化后的渠道(docs/providers.md「渠道」);key 不在这里,经 `resolveApiKey(provider, channel)` 取。 */
|
|
306
330
|
export interface ProviderChannel {
|
|
@@ -325,9 +349,12 @@ export interface ProviderData {
|
|
|
325
349
|
/** 本地服务 false:无 key 也能用。 */
|
|
326
350
|
requiresApiKey: boolean;
|
|
327
351
|
builtin: boolean;
|
|
328
|
-
/**
|
|
352
|
+
/**
|
|
353
|
+
* 渠道(没有 `channels` 的供应商不填,按单渠道处理)。[W5-C0] 内置供应商也可带内置渠道,
|
|
354
|
+
* 用户配置同名字段级覆盖、新名追加(物化归 W5-M2)。
|
|
355
|
+
*/
|
|
329
356
|
channels?: ProviderChannel[];
|
|
330
|
-
/** 首选渠道名(有 `channels`
|
|
357
|
+
/** 首选渠道名(有 `channels` 时;用户配置优先)。 */
|
|
331
358
|
defaultChannel?: string;
|
|
332
359
|
}
|
|
333
360
|
/** `catalog/*.json` 文件形状(§3.4)。 */
|
|
@@ -342,6 +369,11 @@ export interface StreamOptions {
|
|
|
342
369
|
/** 值为 null 表示删除该头。 */
|
|
343
370
|
headers?: Record<string, string | null>;
|
|
344
371
|
timeoutMs?: number;
|
|
372
|
+
/**
|
|
373
|
+
* 空闲超时:等响应头、以及流中两块数据之间的最长间隔(每收到字节即重新计时)。缺省 300 000,
|
|
374
|
+
* 0 关闭。超时报 `idle timeout` 错误,会话层按可重试处理。
|
|
375
|
+
*/
|
|
376
|
+
idleTimeoutMs?: number;
|
|
345
377
|
maxTokens?: number;
|
|
346
378
|
temperature?: number;
|
|
347
379
|
thinkingLevel?: ModelThinkingLevel;
|
|
@@ -434,7 +466,8 @@ export type ModelLookup = {
|
|
|
434
466
|
provider: ProviderData;
|
|
435
467
|
} | {
|
|
436
468
|
ok: false;
|
|
437
|
-
|
|
469
|
+
/** `channel_not_found`:模型在,`@渠道` 不在(候选是该模型可用的 `provider/model@渠道`)。 */
|
|
470
|
+
reason: "not_found" | "ambiguous" | "provider_not_found" | "channel_not_found";
|
|
438
471
|
candidates: string[];
|
|
439
472
|
};
|
|
440
473
|
export interface ProviderRegistryApi {
|
package/dist/ai/types.js
CHANGED
|
@@ -15,5 +15,10 @@
|
|
|
15
15
|
* - [W3-C0] 第三波 §1.3 的五个缓存兼容开关单列为 `PromptCacheCompat`(各协议共用),只并入
|
|
16
16
|
* `ProviderCompat`(全部可选),不改各协议 compat 接口——`detectCompat` 的返回形状不变,
|
|
17
17
|
* 缺省值由 C1a 在协议层按端点推断。
|
|
18
|
+
* - [W5-C0] 第五波(docs/wave5-plan.md §2.1、§3.1):`Model` 加 models.dev 元数据字段
|
|
19
|
+
* (`family / knowledge / releaseDate / inputLimit / status`);`AnthropicMessagesCompat` 加
|
|
20
|
+
* `sendInterleavedThinkingBeta / sendCacheControl`、`OpenAIResponsesCompat` 加
|
|
21
|
+
* `explicitCacheField`,全部可选(缺省由 W5-M2 的主机推断表给出);`ProviderData.channels /
|
|
22
|
+
* defaultChannel` 已有,内置供应商(`BuiltinProvider`)同样可带。
|
|
18
23
|
*/
|
|
19
24
|
export {};
|