@poolzin/pool-bot 2026.2.21 → 2026.2.22
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 +17 -0
- package/dist/agents/api-key-rotation.js +47 -0
- package/dist/agents/apply-patch-update.js +19 -9
- package/dist/agents/apply-patch.js +72 -47
- package/dist/agents/bash-tools.exec.js +141 -559
- package/dist/agents/cli-backends.js +49 -6
- package/dist/agents/cli-runner/helpers.js +69 -152
- package/dist/agents/cli-runner.js +70 -19
- package/dist/agents/identity.js +20 -1
- package/dist/agents/image-sanitization.js +9 -0
- package/dist/agents/live-auth-keys.js +123 -26
- package/dist/agents/live-model-filter.js +13 -4
- package/dist/agents/model-catalog.js +40 -9
- package/dist/agents/model-forward-compat.js +60 -23
- package/dist/agents/model-selection.js +134 -41
- package/dist/agents/pi-auth-json.js +2 -2
- package/dist/agents/pi-embedded-helpers/bootstrap.js +65 -15
- package/dist/agents/pi-embedded-helpers/errors.js +140 -15
- package/dist/agents/pi-embedded-helpers/images.js +22 -12
- package/dist/agents/pi-embedded-helpers.js +2 -2
- package/dist/agents/pi-embedded-runner/abort.js +10 -3
- package/dist/agents/pi-embedded-runner/compact.js +230 -32
- package/dist/agents/pi-embedded-runner/extra-params.js +203 -12
- package/dist/agents/pi-embedded-runner/google.js +109 -19
- package/dist/agents/pi-embedded-runner/history.js +35 -17
- package/dist/agents/pi-embedded-runner/run/attempt.js +386 -95
- package/dist/agents/pi-embedded-runner/run/images.js +81 -55
- package/dist/agents/pi-embedded-runner/run/payloads.js +89 -39
- package/dist/agents/pi-embedded-runner/run.js +193 -25
- package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +2 -2
- package/dist/agents/pi-embedded-runner/runs.js +17 -8
- package/dist/agents/pi-embedded-runner/tool-result-context-guard.js +262 -0
- package/dist/agents/pi-embedded-runner.js +1 -1
- package/dist/agents/pi-embedded-subscribe.handlers.tools.js +180 -10
- package/dist/agents/pi-embedded-subscribe.js +37 -0
- package/dist/agents/pi-embedded-subscribe.tools.js +127 -30
- package/dist/agents/pi-model-discovery.js +9 -2
- package/dist/agents/pi-tool-definition-adapter.js +60 -8
- package/dist/agents/pi-tools.before-tool-call.js +1 -1
- package/dist/agents/pi-tools.js +113 -94
- package/dist/agents/pi-tools.read.js +337 -38
- package/dist/agents/poolbot-tools.js +14 -5
- package/dist/agents/sandbox/docker.js +10 -5
- package/dist/agents/sandbox/registry.js +96 -46
- package/dist/agents/sandbox/sanitize-env-vars.js +82 -0
- package/dist/agents/sandbox-paths.js +43 -10
- package/dist/agents/session-tool-result-guard-wrapper.js +23 -11
- package/dist/agents/session-tool-result-guard.js +39 -39
- package/dist/agents/session-transcript-repair.js +36 -33
- package/dist/agents/session-write-lock.js +62 -44
- package/dist/agents/skills/frontmatter.js +49 -88
- package/dist/agents/skills/workspace.js +335 -28
- package/dist/agents/subagent-announce.js +508 -174
- package/dist/agents/subagent-registry.js +45 -4
- package/dist/agents/subagent-spawn.js +16 -33
- package/dist/agents/system-prompt-report.js +27 -10
- package/dist/agents/system-prompt.js +26 -32
- package/dist/agents/tool-call-id.js +69 -17
- package/dist/agents/tool-display-common.js +1 -1
- package/dist/agents/tool-images.js +64 -31
- package/dist/agents/tools/canvas-tool.js +17 -11
- package/dist/agents/tools/common.js +37 -19
- package/dist/agents/tools/cron-tool.js +40 -38
- package/dist/agents/tools/gateway.js +70 -2
- package/dist/agents/tools/message-tool.js +181 -40
- package/dist/agents/tools/nodes-tool.js +128 -36
- package/dist/agents/tools/nodes-utils.js +12 -38
- package/dist/agents/tools/session-status-tool.js +24 -71
- package/dist/agents/tools/sessions-helpers.js +38 -210
- package/dist/agents/tools/sessions-spawn-tool.js +28 -198
- package/dist/agents/tools/telegram-actions.js +58 -7
- package/dist/agents/tools/web-fetch-utils.js +112 -7
- package/dist/agents/tools/web-fetch.js +279 -175
- package/dist/agents/tools/web-shared.js +71 -8
- package/dist/agents/usage.js +25 -16
- package/dist/auto-reply/commands-registry.data.js +85 -11
- package/dist/auto-reply/dispatch.js +40 -21
- package/dist/auto-reply/reply/abort.js +102 -33
- package/dist/auto-reply/reply/commands-core.js +82 -33
- package/dist/auto-reply/reply/commands-export-session.js +1 -1
- package/dist/auto-reply/reply/commands-info.js +41 -12
- package/dist/auto-reply/reply/commands-subagents.js +352 -100
- package/dist/auto-reply/reply/commands-system-prompt.js +2 -2
- package/dist/auto-reply/reply/dispatch-from-config.js +100 -29
- package/dist/auto-reply/reply/elevated-unavailable.js +1 -1
- package/dist/auto-reply/reply/inbound-meta.js +12 -1
- package/dist/auto-reply/reply/mentions.js +18 -11
- package/dist/auto-reply/reply/normalize-reply.js +17 -8
- package/dist/auto-reply/reply/reply-dispatcher.js +62 -10
- package/dist/auto-reply/reply/session.js +102 -21
- package/dist/auto-reply/reply/streaming-directives.js +16 -5
- package/dist/auto-reply/status.js +73 -50
- package/dist/browser/extension-relay.js +3 -3
- package/dist/browser/http-auth.js +1 -1
- package/dist/browser/paths.js +2 -2
- package/dist/build-info.json +3 -3
- package/dist/channels/allowlist-match.js +20 -0
- package/dist/channels/allowlists/resolve-utils.js +65 -2
- package/dist/channels/chat-type.js +8 -4
- package/dist/channels/dock.js +127 -35
- package/dist/channels/draft-stream-loop.js +6 -2
- package/dist/channels/plugins/actions/telegram.js +42 -18
- package/dist/channels/plugins/allowlist-match.js +1 -1
- package/dist/channels/plugins/group-mentions.js +51 -41
- package/dist/channels/plugins/message-action-names.js +2 -0
- package/dist/channels/plugins/message-actions.js +24 -5
- package/dist/channels/plugins/normalize/discord.js +26 -4
- package/dist/channels/plugins/normalize/signal.js +35 -22
- package/dist/channels/plugins/onboarding/helpers.js +8 -26
- package/dist/channels/plugins/outbound/imessage.js +15 -14
- package/dist/channels/registry.js +20 -7
- package/dist/cli/acp-cli.js +7 -5
- package/dist/cli/browser-cli-extension.js +25 -12
- package/dist/cli/browser-cli-state.cookies-storage.js +25 -6
- package/dist/cli/browser-cli-state.js +101 -145
- package/dist/cli/command-options.js +28 -0
- package/dist/cli/completion-cli.js +6 -6
- package/dist/cli/cron-cli/register.cron-add.js +25 -1
- package/dist/cli/cron-cli/register.cron-edit.js +44 -0
- package/dist/cli/cron-cli/shared.js +7 -1
- package/dist/cli/daemon-cli/lifecycle-core.js +23 -21
- package/dist/cli/daemon-cli/lifecycle.js +23 -247
- package/dist/cli/daemon-cli/register-service-commands.js +25 -4
- package/dist/cli/daemon-cli.js +1 -0
- package/dist/cli/devices-cli.js +33 -20
- package/dist/cli/gateway-cli/register.js +37 -105
- package/dist/cli/gateway-cli/run.js +49 -11
- package/dist/cli/nodes-camera.js +59 -4
- package/dist/cli/nodes-cli/register.camera.js +27 -24
- package/dist/cli/nodes-cli/rpc.js +21 -38
- package/dist/cli/qr-cli.js +2 -2
- package/dist/cli/skills-cli.format.js +2 -2
- package/dist/cli/update-cli/progress.js +2 -2
- package/dist/cli/update-cli/restart-helper.js +28 -7
- package/dist/cli/update-cli/shared.js +7 -7
- package/dist/cli/update-cli/status.js +1 -1
- package/dist/cli/update-cli/update-command.js +14 -8
- package/dist/cli/update-cli/wizard.js +2 -2
- package/dist/cli/update-cli.js +21 -1027
- package/dist/commands/auth-choice.apply.anthropic.js +10 -2
- package/dist/commands/channels/add-mutators.js +3 -35
- package/dist/commands/channels/add.js +39 -51
- package/dist/commands/config-validation.js +1 -1
- package/dist/commands/configure.gateway-auth.js +52 -15
- package/dist/commands/configure.gateway.js +84 -40
- package/dist/commands/doctor-completion.js +3 -3
- package/dist/commands/doctor-config-flow.js +536 -16
- package/dist/commands/doctor-gateway-services.js +103 -79
- package/dist/commands/doctor-memory-search.js +9 -9
- package/dist/commands/doctor-platform-notes.js +57 -30
- package/dist/commands/doctor-prompter.js +26 -15
- package/dist/commands/doctor-session-locks.js +1 -1
- package/dist/commands/doctor.js +21 -9
- package/dist/commands/model-picker.js +120 -95
- package/dist/commands/models/set.js +2 -21
- package/dist/commands/models/shared.js +65 -37
- package/dist/commands/onboard-helpers.js +81 -39
- package/dist/commands/openai-codex-oauth.js +1 -1
- package/dist/commands/sessions.js +52 -53
- package/dist/commands/status.summary.js +52 -34
- package/dist/commands/test-wizard-helpers.js +2 -2
- package/dist/config/defaults.js +79 -42
- package/dist/config/group-policy.js +50 -18
- package/dist/config/includes.js +37 -10
- package/dist/config/schema.help.js +5 -4
- package/dist/config/schema.hints.js +2 -2
- package/dist/config/schema.labels.js +1 -0
- package/dist/config/sessions/group.js +12 -11
- package/dist/config/sessions/paths.js +137 -11
- package/dist/config/sessions/store.js +185 -65
- package/dist/config/sessions/types.js +15 -1
- package/dist/config/sessions.js +1 -0
- package/dist/config/telegram-custom-commands.js +3 -2
- package/dist/config/types.js +2 -0
- package/dist/config/zod-schema.agent-defaults.js +6 -27
- package/dist/config/zod-schema.agent-runtime.js +171 -79
- package/dist/config/zod-schema.providers-core.js +138 -65
- package/dist/config/zod-schema.session.js +49 -22
- package/dist/control-ui/assets/index-HRr1grwl.js.map +1 -1
- package/dist/cron/isolated-agent/run.js +224 -57
- package/dist/cron/normalize.js +48 -45
- package/dist/cron/run-log.js +14 -0
- package/dist/cron/service/jobs.js +190 -28
- package/dist/cron/service/normalize.js +29 -11
- package/dist/cron/service/store.js +30 -44
- package/dist/cron/service/timer.js +182 -96
- package/dist/cron/service.js +3 -0
- package/dist/cron/stagger.js +37 -0
- package/dist/daemon/inspect.js +132 -92
- package/dist/daemon/runtime-paths.js +25 -4
- package/dist/daemon/service-audit.js +47 -16
- package/dist/discord/accounts.js +23 -20
- package/dist/discord/monitor/agent-components.js +1115 -219
- package/dist/discord/monitor/allow-list.js +114 -34
- package/dist/discord/monitor/listeners.js +204 -97
- package/dist/discord/monitor/message-handler.js +21 -10
- package/dist/discord/monitor/message-handler.preflight.js +195 -101
- package/dist/discord/monitor/message-handler.process.js +384 -123
- package/dist/discord/monitor/message-utils.js +86 -23
- package/dist/discord/monitor/native-command.js +77 -57
- package/dist/discord/monitor/provider.js +122 -117
- package/dist/discord/monitor/reply-context.js +20 -16
- package/dist/discord/monitor/reply-delivery.js +40 -8
- package/dist/discord/monitor/rest-fetch.js +22 -0
- package/dist/discord/monitor/threading.js +117 -24
- package/dist/discord/send.js +2 -1
- package/dist/discord/send.outbound.js +124 -11
- package/dist/discord/send.shared.js +112 -72
- package/dist/discord/voice-message.js +3 -3
- package/dist/gateway/auth.js +119 -44
- package/dist/gateway/call.js +76 -34
- package/dist/gateway/channel-health-monitor.js +57 -50
- package/dist/gateway/client.js +63 -29
- package/dist/gateway/control-ui-contract.js +1 -1
- package/dist/gateway/gateway-config-prompts.shared.js +2 -2
- package/dist/gateway/net.js +109 -1
- package/dist/gateway/protocol/index.js +5 -8
- package/dist/gateway/protocol/schema/agent.js +19 -1
- package/dist/gateway/protocol/schema/channels.js +21 -0
- package/dist/gateway/protocol/schema/cron.js +43 -30
- package/dist/gateway/protocol/schema/protocol-schemas.js +6 -11
- package/dist/gateway/protocol/schema/sessions.js +5 -1
- package/dist/gateway/protocol/schema.js +0 -1
- package/dist/gateway/server/presence-events.js +12 -0
- package/dist/gateway/server/ws-connection/message-handler.js +203 -212
- package/dist/gateway/server/ws-connection.js +58 -21
- package/dist/gateway/server-broadcast.js +18 -13
- package/dist/gateway/server-cron.js +177 -10
- package/dist/gateway/server-methods/agent-job.js +131 -38
- package/dist/gateway/server-methods/send.js +60 -14
- package/dist/gateway/server-methods/sessions.js +160 -96
- package/dist/gateway/server-methods/system.js +5 -7
- package/dist/gateway/server-methods-list.js +8 -0
- package/dist/gateway/server-methods.js +24 -8
- package/dist/gateway/server-node-events.js +278 -68
- package/dist/gateway/session-utils.fs.js +316 -75
- package/dist/gateway/session-utils.js +224 -70
- package/dist/gateway/sessions-patch.js +63 -20
- package/dist/gateway/test-temp-config.js +1 -1
- package/dist/gateway/tools-invoke-http.js +118 -70
- package/dist/gateway/ws-log.js +135 -107
- package/dist/hooks/frontmatter.js +36 -82
- package/dist/hooks/install.js +149 -139
- package/dist/hooks/internal-hooks.js +29 -4
- package/dist/hooks/plugin-hooks.js +2 -1
- package/dist/imessage/monitor/deliver.js +10 -4
- package/dist/imessage/monitor/monitor-provider.js +138 -375
- package/dist/imessage/monitor/runtime.js +4 -8
- package/dist/imessage/send.js +65 -19
- package/dist/infra/exec-approvals-allowlist.js +7 -0
- package/dist/infra/exec-approvals.js +35 -920
- package/dist/infra/exec-safe-bin-trust.js +64 -0
- package/dist/infra/heartbeat-runner.js +207 -134
- package/dist/infra/heartbeat-wake.js +183 -22
- package/dist/infra/install-source-utils.js +47 -0
- package/dist/infra/net/ssrf.js +170 -36
- package/dist/infra/outbound/deliver.js +224 -58
- package/dist/infra/outbound/message-action-spec.js +12 -5
- package/dist/infra/outbound/outbound-session.js +27 -25
- package/dist/infra/poolbot-root.js +32 -22
- package/dist/infra/ports.js +14 -11
- package/dist/infra/skills-remote.js +48 -37
- package/dist/infra/system-events.js +25 -11
- package/dist/infra/system-presence.js +26 -33
- package/dist/infra/tmp-poolbot-dir.js +81 -2
- package/dist/infra/wsl.js +37 -1
- package/dist/line/bot-message-context.js +163 -191
- package/dist/logging/subsystem.js +59 -22
- package/dist/markdown/ir.js +124 -50
- package/dist/media/store.js +1 -1
- package/dist/media-understanding/runner.entries.js +42 -25
- package/dist/media-understanding/runner.js +53 -488
- package/dist/memory/embeddings-gemini.js +53 -38
- package/dist/memory/manager-embedding-ops.js +48 -69
- package/dist/pairing/pairing-store.js +178 -119
- package/dist/plugin-sdk/index.js +34 -6
- package/dist/plugins/hooks.js +135 -14
- package/dist/plugins/install.js +190 -152
- package/dist/polls.js +11 -0
- package/dist/routing/resolve-route.js +190 -56
- package/dist/routing/session-key.js +38 -22
- package/dist/runtime.js +35 -9
- package/dist/security/audit-channel.js +1 -1
- package/dist/sessions/session-key-utils.js +29 -11
- package/dist/shared/frontmatter.js +5 -5
- package/dist/shared/node-list-types.js +1 -0
- package/dist/shared/string-normalization.js +15 -0
- package/dist/signal/monitor/event-handler.js +68 -36
- package/dist/signal/send.js +29 -37
- package/dist/slack/monitor/allow-list.js +10 -11
- package/dist/slack/monitor/commands.js +14 -3
- package/dist/slack/monitor/events/interactions.js +4 -4
- package/dist/slack/monitor/media.js +224 -16
- package/dist/slack/monitor/message-handler/dispatch.js +247 -13
- package/dist/slack/monitor/message-handler/prepare.js +128 -45
- package/dist/slack/monitor/slash.js +357 -144
- package/dist/slack/streaming.js +77 -0
- package/dist/telegram/accounts.js +40 -13
- package/dist/telegram/allowed-updates.js +3 -0
- package/dist/telegram/bot/delivery.js +129 -66
- package/dist/telegram/bot/helpers.js +136 -122
- package/dist/telegram/bot-handlers.js +600 -339
- package/dist/telegram/bot-message-context.js +115 -73
- package/dist/telegram/bot-message-dispatch.js +235 -104
- package/dist/telegram/bot-native-command-menu.js +3 -1
- package/dist/telegram/bot-native-commands.js +213 -193
- package/dist/telegram/bot.js +24 -132
- package/dist/telegram/draft-stream.js +84 -75
- package/dist/telegram/format.js +150 -6
- package/dist/telegram/send.js +415 -255
- package/dist/telegram/targets.js +21 -2
- package/dist/telegram/update-offset-store.js +19 -3
- package/dist/terminal/restore.js +5 -2
- package/dist/test-utils/fetch-mock.js +5 -0
- package/dist/version.js +18 -5
- package/dist/web/auto-reply/monitor/broadcast.js +7 -3
- package/dist/web/auto-reply/monitor/on-message.js +6 -3
- package/dist/web/inbound/media.js +34 -8
- package/dist/web/inbound/monitor.js +34 -17
- package/dist/web/inbound/send-api.js +18 -17
- package/dist/web/outbound.js +12 -5
- package/dist/wizard/clack-prompter.js +40 -7
- package/extensions/bluebubbles/package.json +1 -1
- package/extensions/copilot-proxy/package.json +1 -1
- package/extensions/diagnostics-otel/package.json +1 -1
- package/extensions/discord/package.json +1 -1
- package/extensions/feishu/package.json +1 -1
- package/extensions/google-antigravity-auth/package.json +1 -1
- package/extensions/google-gemini-cli-auth/package.json +1 -1
- package/extensions/googlechat/package.json +1 -1
- package/extensions/imessage/package.json +1 -1
- package/extensions/irc/package.json +1 -1
- package/extensions/line/package.json +1 -1
- package/extensions/llm-task/package.json +1 -1
- package/extensions/lobster/package.json +1 -1
- package/extensions/matrix/CHANGELOG.md +5 -0
- package/extensions/matrix/package.json +1 -1
- package/extensions/mattermost/package.json +1 -1
- package/extensions/memory-core/package.json +1 -1
- package/extensions/memory-lancedb/package.json +1 -1
- package/extensions/minimax-portal-auth/package.json +1 -1
- package/extensions/msteams/CHANGELOG.md +5 -0
- package/extensions/msteams/package.json +1 -1
- package/extensions/nextcloud-talk/package.json +1 -1
- package/extensions/nostr/CHANGELOG.md +5 -0
- package/extensions/nostr/package.json +1 -1
- package/extensions/open-prose/package.json +1 -1
- package/extensions/openai-codex-auth/package.json +1 -1
- package/extensions/signal/package.json +1 -1
- package/extensions/slack/package.json +1 -1
- package/extensions/telegram/package.json +1 -1
- package/extensions/tlon/package.json +1 -1
- package/extensions/twitch/CHANGELOG.md +5 -0
- package/extensions/twitch/package.json +1 -1
- package/extensions/voice-call/CHANGELOG.md +5 -0
- package/extensions/voice-call/package.json +1 -1
- package/extensions/whatsapp/package.json +1 -1
- package/extensions/zalo/CHANGELOG.md +5 -0
- package/extensions/zalo/package.json +1 -1
- package/extensions/zalouser/CHANGELOG.md +5 -0
- package/extensions/zalouser/package.json +1 -1
- package/package.json +1 -1
- package/skills/apple-reminders/SKILL.md +100 -49
- package/skills/coding-agent/SKILL.md +34 -28
- package/skills/github/SKILL.md +131 -16
- package/skills/imsg/SKILL.md +112 -15
- package/skills/openhue/SKILL.md +101 -19
- package/skills/tmux/SKILL.md +111 -79
- package/skills/weather/SKILL.md +88 -25
|
@@ -5,26 +5,47 @@ import { loadModelCatalog } from "../agents/model-catalog.js";
|
|
|
5
5
|
import { buildAllowedModelSet, buildModelAliasIndex, modelKey, normalizeProviderId, resolveConfiguredModelRef, } from "../agents/model-selection.js";
|
|
6
6
|
import { formatTokenK } from "./models/shared.js";
|
|
7
7
|
import { OPENAI_CODEX_DEFAULT_MODEL } from "./openai-codex-model-default.js";
|
|
8
|
+
import { promptAndConfigureVllm } from "./vllm-setup.js";
|
|
8
9
|
const KEEP_VALUE = "__keep__";
|
|
9
10
|
const MANUAL_VALUE = "__manual__";
|
|
11
|
+
const VLLM_VALUE = "__vllm__";
|
|
10
12
|
const PROVIDER_FILTER_THRESHOLD = 30;
|
|
11
13
|
// Models that are internal routing features and should not be shown in selection lists.
|
|
12
14
|
// These may be valid as defaults (e.g., set automatically during auth flow) but are not
|
|
13
15
|
// directly callable via API and would cause "Unknown model" errors if selected manually.
|
|
14
16
|
const HIDDEN_ROUTER_MODELS = new Set(["openrouter/auto"]);
|
|
15
17
|
function hasAuthForProvider(provider, cfg, store) {
|
|
16
|
-
if (listProfilesForProvider(store, provider).length > 0)
|
|
18
|
+
if (listProfilesForProvider(store, provider).length > 0) {
|
|
17
19
|
return true;
|
|
18
|
-
|
|
20
|
+
}
|
|
21
|
+
if (resolveEnvApiKey(provider)) {
|
|
19
22
|
return true;
|
|
20
|
-
|
|
23
|
+
}
|
|
24
|
+
if (getCustomProviderApiKey(cfg, provider)) {
|
|
21
25
|
return true;
|
|
26
|
+
}
|
|
22
27
|
return false;
|
|
23
28
|
}
|
|
29
|
+
function createProviderAuthChecker(params) {
|
|
30
|
+
const authStore = ensureAuthProfileStore(params.agentDir, {
|
|
31
|
+
allowKeychainPrompt: false,
|
|
32
|
+
});
|
|
33
|
+
const authCache = new Map();
|
|
34
|
+
return (provider) => {
|
|
35
|
+
const cached = authCache.get(provider);
|
|
36
|
+
if (cached !== undefined) {
|
|
37
|
+
return cached;
|
|
38
|
+
}
|
|
39
|
+
const value = hasAuthForProvider(provider, params.cfg, authStore);
|
|
40
|
+
authCache.set(provider, value);
|
|
41
|
+
return value;
|
|
42
|
+
};
|
|
43
|
+
}
|
|
24
44
|
function resolveConfiguredModelRaw(cfg) {
|
|
25
45
|
const raw = cfg.agents?.defaults?.model;
|
|
26
|
-
if (typeof raw === "string")
|
|
46
|
+
if (typeof raw === "string") {
|
|
27
47
|
return raw.trim();
|
|
48
|
+
}
|
|
28
49
|
return raw?.primary?.trim() ?? "";
|
|
29
50
|
}
|
|
30
51
|
function resolveConfiguredModelKeys(cfg) {
|
|
@@ -38,13 +59,52 @@ function normalizeModelKeys(values) {
|
|
|
38
59
|
const next = [];
|
|
39
60
|
for (const raw of values) {
|
|
40
61
|
const value = String(raw ?? "").trim();
|
|
41
|
-
if (!value || seen.has(value))
|
|
62
|
+
if (!value || seen.has(value)) {
|
|
42
63
|
continue;
|
|
64
|
+
}
|
|
43
65
|
seen.add(value);
|
|
44
66
|
next.push(value);
|
|
45
67
|
}
|
|
46
68
|
return next;
|
|
47
69
|
}
|
|
70
|
+
function addModelSelectOption(params) {
|
|
71
|
+
const key = modelKey(params.entry.provider, params.entry.id);
|
|
72
|
+
if (params.seen.has(key)) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
// Skip internal router models that can't be directly called via API.
|
|
76
|
+
if (HIDDEN_ROUTER_MODELS.has(key)) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
const hints = [];
|
|
80
|
+
if (params.entry.name && params.entry.name !== params.entry.id) {
|
|
81
|
+
hints.push(params.entry.name);
|
|
82
|
+
}
|
|
83
|
+
if (params.entry.contextWindow) {
|
|
84
|
+
hints.push(`ctx ${formatTokenK(params.entry.contextWindow)}`);
|
|
85
|
+
}
|
|
86
|
+
if (params.entry.reasoning) {
|
|
87
|
+
hints.push("reasoning");
|
|
88
|
+
}
|
|
89
|
+
const aliases = params.aliasIndex.byKey.get(key);
|
|
90
|
+
if (aliases?.length) {
|
|
91
|
+
hints.push(`alias: ${aliases.join(", ")}`);
|
|
92
|
+
}
|
|
93
|
+
if (!params.hasAuth(params.entry.provider)) {
|
|
94
|
+
hints.push("auth missing");
|
|
95
|
+
}
|
|
96
|
+
params.options.push({
|
|
97
|
+
value: key,
|
|
98
|
+
label: key,
|
|
99
|
+
hint: hints.length > 0 ? hints.join(" · ") : undefined,
|
|
100
|
+
});
|
|
101
|
+
params.seen.add(key);
|
|
102
|
+
}
|
|
103
|
+
function isAnthropicLegacyModel(entry) {
|
|
104
|
+
return (entry.provider === "anthropic" &&
|
|
105
|
+
typeof entry.id === "string" &&
|
|
106
|
+
entry.id.toLowerCase().startsWith("claude-3"));
|
|
107
|
+
}
|
|
48
108
|
async function promptManualModel(params) {
|
|
49
109
|
const modelInput = await params.prompter.text({
|
|
50
110
|
message: params.allowBlank ? "Default model (blank to keep)" : "Default model",
|
|
@@ -53,14 +113,16 @@ async function promptManualModel(params) {
|
|
|
53
113
|
validate: params.allowBlank ? undefined : (value) => (value?.trim() ? undefined : "Required"),
|
|
54
114
|
});
|
|
55
115
|
const model = String(modelInput ?? "").trim();
|
|
56
|
-
if (!model)
|
|
116
|
+
if (!model) {
|
|
57
117
|
return {};
|
|
118
|
+
}
|
|
58
119
|
return { model };
|
|
59
120
|
}
|
|
60
121
|
export async function promptDefaultModel(params) {
|
|
61
122
|
const cfg = params.config;
|
|
62
123
|
const allowKeep = params.allowKeep ?? true;
|
|
63
124
|
const includeManual = params.includeManual ?? true;
|
|
125
|
+
const includeVllm = params.includeVllm ?? false;
|
|
64
126
|
const ignoreAllowlist = params.ignoreAllowlist ?? false;
|
|
65
127
|
const preferredProviderRaw = params.preferredProvider?.trim();
|
|
66
128
|
const preferredProvider = preferredProviderRaw
|
|
@@ -102,7 +164,7 @@ export async function promptDefaultModel(params) {
|
|
|
102
164
|
initialValue: configuredRaw || resolvedKey || undefined,
|
|
103
165
|
});
|
|
104
166
|
}
|
|
105
|
-
const providers = Array.from(new Set(models.map((entry) => entry.provider))).
|
|
167
|
+
const providers = Array.from(new Set(models.map((entry) => entry.provider))).toSorted((a, b) => a.localeCompare(b));
|
|
106
168
|
const hasPreferredProvider = preferredProvider ? providers.includes(preferredProvider) : false;
|
|
107
169
|
const shouldPromptProvider = !hasPreferredProvider && providers.length > 1 && models.length > PROVIDER_FILTER_THRESHOLD;
|
|
108
170
|
if (shouldPromptProvider) {
|
|
@@ -126,19 +188,12 @@ export async function promptDefaultModel(params) {
|
|
|
126
188
|
}
|
|
127
189
|
if (hasPreferredProvider && preferredProvider) {
|
|
128
190
|
models = models.filter((entry) => entry.provider === preferredProvider);
|
|
191
|
+
if (preferredProvider === "anthropic") {
|
|
192
|
+
models = models.filter((entry) => !isAnthropicLegacyModel(entry));
|
|
193
|
+
}
|
|
129
194
|
}
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
});
|
|
133
|
-
const authCache = new Map();
|
|
134
|
-
const hasAuth = (provider) => {
|
|
135
|
-
const cached = authCache.get(provider);
|
|
136
|
-
if (cached !== undefined)
|
|
137
|
-
return cached;
|
|
138
|
-
const value = hasAuthForProvider(provider, cfg, authStore);
|
|
139
|
-
authCache.set(provider, value);
|
|
140
|
-
return value;
|
|
141
|
-
};
|
|
195
|
+
const agentDir = params.agentDir;
|
|
196
|
+
const hasAuth = createProviderAuthChecker({ cfg, agentDir });
|
|
142
197
|
const options = [];
|
|
143
198
|
if (allowKeep) {
|
|
144
199
|
options.push({
|
|
@@ -152,35 +207,17 @@ export async function promptDefaultModel(params) {
|
|
|
152
207
|
if (includeManual) {
|
|
153
208
|
options.push({ value: MANUAL_VALUE, label: "Enter model manually" });
|
|
154
209
|
}
|
|
155
|
-
|
|
156
|
-
const addModelOption = (entry) => {
|
|
157
|
-
const key = modelKey(entry.provider, entry.id);
|
|
158
|
-
if (seen.has(key))
|
|
159
|
-
return;
|
|
160
|
-
// Skip internal router models that can't be directly called via API.
|
|
161
|
-
if (HIDDEN_ROUTER_MODELS.has(key))
|
|
162
|
-
return;
|
|
163
|
-
const hints = [];
|
|
164
|
-
if (entry.name && entry.name !== entry.id)
|
|
165
|
-
hints.push(entry.name);
|
|
166
|
-
if (entry.contextWindow)
|
|
167
|
-
hints.push(`ctx ${formatTokenK(entry.contextWindow)}`);
|
|
168
|
-
if (entry.reasoning)
|
|
169
|
-
hints.push("reasoning");
|
|
170
|
-
const aliases = aliasIndex.byKey.get(key);
|
|
171
|
-
if (aliases?.length)
|
|
172
|
-
hints.push(`alias: ${aliases.join(", ")}`);
|
|
173
|
-
if (!hasAuth(entry.provider))
|
|
174
|
-
hints.push("auth missing");
|
|
210
|
+
if (includeVllm && agentDir) {
|
|
175
211
|
options.push({
|
|
176
|
-
value:
|
|
177
|
-
label:
|
|
178
|
-
hint:
|
|
212
|
+
value: VLLM_VALUE,
|
|
213
|
+
label: "vLLM (custom)",
|
|
214
|
+
hint: "Enter vLLM URL + API key + model",
|
|
179
215
|
});
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
for (const entry of models)
|
|
183
|
-
|
|
216
|
+
}
|
|
217
|
+
const seen = new Set();
|
|
218
|
+
for (const entry of models) {
|
|
219
|
+
addModelSelectOption({ entry, options, seen, aliasIndex, hasAuth });
|
|
220
|
+
}
|
|
184
221
|
if (configuredKey && !seen.has(configuredKey)) {
|
|
185
222
|
options.push({
|
|
186
223
|
value: configuredKey,
|
|
@@ -203,8 +240,9 @@ export async function promptDefaultModel(params) {
|
|
|
203
240
|
options,
|
|
204
241
|
initialValue,
|
|
205
242
|
});
|
|
206
|
-
if (selection === KEEP_VALUE)
|
|
243
|
+
if (selection === KEEP_VALUE) {
|
|
207
244
|
return {};
|
|
245
|
+
}
|
|
208
246
|
if (selection === MANUAL_VALUE) {
|
|
209
247
|
return promptManualModel({
|
|
210
248
|
prompter: params.prompter,
|
|
@@ -212,6 +250,18 @@ export async function promptDefaultModel(params) {
|
|
|
212
250
|
initialValue: configuredRaw || resolvedKey || undefined,
|
|
213
251
|
});
|
|
214
252
|
}
|
|
253
|
+
if (selection === VLLM_VALUE) {
|
|
254
|
+
if (!agentDir) {
|
|
255
|
+
await params.prompter.note("vLLM setup requires an agent directory context.", "vLLM not available");
|
|
256
|
+
return {};
|
|
257
|
+
}
|
|
258
|
+
const { config: nextConfig, modelRef } = await promptAndConfigureVllm({
|
|
259
|
+
cfg,
|
|
260
|
+
prompter: params.prompter,
|
|
261
|
+
agentDir,
|
|
262
|
+
});
|
|
263
|
+
return { model: modelRef, config: nextConfig };
|
|
264
|
+
}
|
|
215
265
|
return { model: String(selection) };
|
|
216
266
|
}
|
|
217
267
|
export async function promptModelAllowlist(params) {
|
|
@@ -245,62 +295,29 @@ export async function promptModelAllowlist(params) {
|
|
|
245
295
|
.split(",")
|
|
246
296
|
.map((value) => value.trim())
|
|
247
297
|
.filter((value) => value.length > 0);
|
|
248
|
-
if (parsed.length === 0)
|
|
298
|
+
if (parsed.length === 0) {
|
|
249
299
|
return {};
|
|
300
|
+
}
|
|
250
301
|
return { models: normalizeModelKeys(parsed) };
|
|
251
302
|
}
|
|
252
303
|
const aliasIndex = buildModelAliasIndex({
|
|
253
304
|
cfg,
|
|
254
305
|
defaultProvider: DEFAULT_PROVIDER,
|
|
255
306
|
});
|
|
256
|
-
const
|
|
257
|
-
allowKeychainPrompt: false,
|
|
258
|
-
});
|
|
259
|
-
const authCache = new Map();
|
|
260
|
-
const hasAuth = (provider) => {
|
|
261
|
-
const cached = authCache.get(provider);
|
|
262
|
-
if (cached !== undefined)
|
|
263
|
-
return cached;
|
|
264
|
-
const value = hasAuthForProvider(provider, cfg, authStore);
|
|
265
|
-
authCache.set(provider, value);
|
|
266
|
-
return value;
|
|
267
|
-
};
|
|
307
|
+
const hasAuth = createProviderAuthChecker({ cfg, agentDir: params.agentDir });
|
|
268
308
|
const options = [];
|
|
269
309
|
const seen = new Set();
|
|
270
|
-
const addModelOption = (entry) => {
|
|
271
|
-
const key = modelKey(entry.provider, entry.id);
|
|
272
|
-
if (seen.has(key))
|
|
273
|
-
return;
|
|
274
|
-
if (HIDDEN_ROUTER_MODELS.has(key))
|
|
275
|
-
return;
|
|
276
|
-
const hints = [];
|
|
277
|
-
if (entry.name && entry.name !== entry.id)
|
|
278
|
-
hints.push(entry.name);
|
|
279
|
-
if (entry.contextWindow)
|
|
280
|
-
hints.push(`ctx ${formatTokenK(entry.contextWindow)}`);
|
|
281
|
-
if (entry.reasoning)
|
|
282
|
-
hints.push("reasoning");
|
|
283
|
-
const aliases = aliasIndex.byKey.get(key);
|
|
284
|
-
if (aliases?.length)
|
|
285
|
-
hints.push(`alias: ${aliases.join(", ")}`);
|
|
286
|
-
if (!hasAuth(entry.provider))
|
|
287
|
-
hints.push("auth missing");
|
|
288
|
-
options.push({
|
|
289
|
-
value: key,
|
|
290
|
-
label: key,
|
|
291
|
-
hint: hints.length > 0 ? hints.join(" · ") : undefined,
|
|
292
|
-
});
|
|
293
|
-
seen.add(key);
|
|
294
|
-
};
|
|
295
310
|
const filteredCatalog = allowedKeySet
|
|
296
311
|
? catalog.filter((entry) => allowedKeySet.has(modelKey(entry.provider, entry.id)))
|
|
297
312
|
: catalog;
|
|
298
|
-
for (const entry of filteredCatalog)
|
|
299
|
-
|
|
313
|
+
for (const entry of filteredCatalog) {
|
|
314
|
+
addModelSelectOption({ entry, options, seen, aliasIndex, hasAuth });
|
|
315
|
+
}
|
|
300
316
|
const supplementalKeys = allowedKeySet ? allowedKeys : existingKeys;
|
|
301
317
|
for (const key of supplementalKeys) {
|
|
302
|
-
if (seen.has(key))
|
|
318
|
+
if (seen.has(key)) {
|
|
303
319
|
continue;
|
|
320
|
+
}
|
|
304
321
|
options.push({
|
|
305
322
|
value: key,
|
|
306
323
|
label: key,
|
|
@@ -308,24 +325,29 @@ export async function promptModelAllowlist(params) {
|
|
|
308
325
|
});
|
|
309
326
|
seen.add(key);
|
|
310
327
|
}
|
|
311
|
-
if (options.length === 0)
|
|
328
|
+
if (options.length === 0) {
|
|
312
329
|
return {};
|
|
330
|
+
}
|
|
313
331
|
const selection = await params.prompter.multiselect({
|
|
314
332
|
message: params.message ?? "Models in /model picker (multi-select)",
|
|
315
333
|
options,
|
|
316
334
|
initialValues: initialKeys.length > 0 ? initialKeys : undefined,
|
|
335
|
+
searchable: true,
|
|
317
336
|
});
|
|
318
337
|
const selected = normalizeModelKeys(selection.map((value) => String(value)));
|
|
319
|
-
if (selected.length > 0)
|
|
338
|
+
if (selected.length > 0) {
|
|
320
339
|
return { models: selected };
|
|
321
|
-
|
|
340
|
+
}
|
|
341
|
+
if (existingKeys.length === 0) {
|
|
322
342
|
return { models: [] };
|
|
343
|
+
}
|
|
323
344
|
const confirmClear = await params.prompter.confirm({
|
|
324
345
|
message: "Clear the model allowlist? (shows all models)",
|
|
325
346
|
initialValue: false,
|
|
326
347
|
});
|
|
327
|
-
if (!confirmClear)
|
|
348
|
+
if (!confirmClear) {
|
|
328
349
|
return {};
|
|
350
|
+
}
|
|
329
351
|
return { models: [] };
|
|
330
352
|
}
|
|
331
353
|
export function applyPrimaryModel(cfg, model) {
|
|
@@ -357,8 +379,9 @@ export function applyModelAllowlist(cfg, models) {
|
|
|
357
379
|
const defaults = cfg.agents?.defaults;
|
|
358
380
|
const normalized = normalizeModelKeys(models);
|
|
359
381
|
if (normalized.length === 0) {
|
|
360
|
-
if (!defaults?.models)
|
|
382
|
+
if (!defaults?.models) {
|
|
361
383
|
return cfg;
|
|
384
|
+
}
|
|
362
385
|
const { models: _ignored, ...restDefaults } = defaults;
|
|
363
386
|
return {
|
|
364
387
|
...cfg,
|
|
@@ -386,16 +409,18 @@ export function applyModelAllowlist(cfg, models) {
|
|
|
386
409
|
}
|
|
387
410
|
export function applyModelFallbacksFromSelection(cfg, selection) {
|
|
388
411
|
const normalized = normalizeModelKeys(selection);
|
|
389
|
-
if (normalized.length <= 1)
|
|
412
|
+
if (normalized.length <= 1) {
|
|
390
413
|
return cfg;
|
|
414
|
+
}
|
|
391
415
|
const resolved = resolveConfiguredModelRef({
|
|
392
416
|
cfg,
|
|
393
417
|
defaultProvider: DEFAULT_PROVIDER,
|
|
394
418
|
defaultModel: DEFAULT_MODEL,
|
|
395
419
|
});
|
|
396
420
|
const resolvedKey = modelKey(resolved.provider, resolved.model);
|
|
397
|
-
if (!normalized.includes(resolvedKey))
|
|
421
|
+
if (!normalized.includes(resolvedKey)) {
|
|
398
422
|
return cfg;
|
|
423
|
+
}
|
|
399
424
|
const defaults = cfg.agents?.defaults;
|
|
400
425
|
const existingModel = defaults?.model;
|
|
401
426
|
const existingPrimary = typeof existingModel === "string"
|
|
@@ -1,27 +1,8 @@
|
|
|
1
1
|
import { logConfigUpdated } from "../../config/logging.js";
|
|
2
|
-
import {
|
|
2
|
+
import { applyDefaultModelPrimaryUpdate, updateConfig } from "./shared.js";
|
|
3
3
|
export async function modelsSetCommand(modelRaw, runtime) {
|
|
4
4
|
const updated = await updateConfig((cfg) => {
|
|
5
|
-
|
|
6
|
-
const key = `${resolved.provider}/${resolved.model}`;
|
|
7
|
-
const nextModels = { ...cfg.agents?.defaults?.models };
|
|
8
|
-
if (!nextModels[key])
|
|
9
|
-
nextModels[key] = {};
|
|
10
|
-
const existingModel = cfg.agents?.defaults?.model;
|
|
11
|
-
return {
|
|
12
|
-
...cfg,
|
|
13
|
-
agents: {
|
|
14
|
-
...cfg.agents,
|
|
15
|
-
defaults: {
|
|
16
|
-
...cfg.agents?.defaults,
|
|
17
|
-
model: {
|
|
18
|
-
...(existingModel?.fallbacks ? { fallbacks: existingModel.fallbacks } : undefined),
|
|
19
|
-
primary: key,
|
|
20
|
-
},
|
|
21
|
-
models: nextModels,
|
|
22
|
-
},
|
|
23
|
-
},
|
|
24
|
-
};
|
|
5
|
+
return applyDefaultModelPrimaryUpdate({ cfg, modelRaw, field: "model" });
|
|
25
6
|
});
|
|
26
7
|
logConfigUpdated(runtime);
|
|
27
8
|
runtime.log(`Default model: ${updated.agents?.defaults?.model?.primary ?? modelRaw}`);
|
|
@@ -10,21 +10,40 @@ export const ensureFlagCompatibility = (opts) => {
|
|
|
10
10
|
}
|
|
11
11
|
};
|
|
12
12
|
export const formatTokenK = (value) => {
|
|
13
|
-
if (!value || !Number.isFinite(value))
|
|
13
|
+
if (!value || !Number.isFinite(value)) {
|
|
14
14
|
return "-";
|
|
15
|
-
|
|
15
|
+
}
|
|
16
|
+
if (value < 1024) {
|
|
16
17
|
return `${Math.round(value)}`;
|
|
18
|
+
}
|
|
17
19
|
return `${Math.round(value / 1024)}k`;
|
|
18
20
|
};
|
|
19
21
|
export const formatMs = (value) => {
|
|
20
|
-
if (value === null || value === undefined)
|
|
22
|
+
if (value === null || value === undefined) {
|
|
21
23
|
return "-";
|
|
22
|
-
|
|
24
|
+
}
|
|
25
|
+
if (!Number.isFinite(value)) {
|
|
23
26
|
return "-";
|
|
24
|
-
|
|
27
|
+
}
|
|
28
|
+
if (value < 1000) {
|
|
25
29
|
return `${Math.round(value)}ms`;
|
|
30
|
+
}
|
|
26
31
|
return `${Math.round(value / 100) / 10}s`;
|
|
27
32
|
};
|
|
33
|
+
export const isLocalBaseUrl = (baseUrl) => {
|
|
34
|
+
try {
|
|
35
|
+
const url = new URL(baseUrl);
|
|
36
|
+
const host = url.hostname.toLowerCase();
|
|
37
|
+
return (host === "localhost" ||
|
|
38
|
+
host === "127.0.0.1" ||
|
|
39
|
+
host === "0.0.0.0" ||
|
|
40
|
+
host === "::1" ||
|
|
41
|
+
host.endsWith(".local"));
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
};
|
|
28
47
|
export async function updateConfig(mutator) {
|
|
29
48
|
const snapshot = await readConfigFileSnapshot();
|
|
30
49
|
if (!snapshot.valid) {
|
|
@@ -50,21 +69,37 @@ export function resolveModelTarget(params) {
|
|
|
50
69
|
}
|
|
51
70
|
return resolved.ref;
|
|
52
71
|
}
|
|
72
|
+
export function resolveModelKeysFromEntries(params) {
|
|
73
|
+
const aliasIndex = buildModelAliasIndex({
|
|
74
|
+
cfg: params.cfg,
|
|
75
|
+
defaultProvider: DEFAULT_PROVIDER,
|
|
76
|
+
});
|
|
77
|
+
return params.entries
|
|
78
|
+
.map((entry) => resolveModelRefFromString({
|
|
79
|
+
raw: entry,
|
|
80
|
+
defaultProvider: DEFAULT_PROVIDER,
|
|
81
|
+
aliasIndex,
|
|
82
|
+
}))
|
|
83
|
+
.filter((entry) => Boolean(entry))
|
|
84
|
+
.map((entry) => modelKey(entry.ref.provider, entry.ref.model));
|
|
85
|
+
}
|
|
53
86
|
export function buildAllowlistSet(cfg) {
|
|
54
87
|
const allowed = new Set();
|
|
55
88
|
const models = cfg.agents?.defaults?.models ?? {};
|
|
56
89
|
for (const raw of Object.keys(models)) {
|
|
57
90
|
const parsed = parseModelRef(String(raw ?? ""), DEFAULT_PROVIDER);
|
|
58
|
-
if (!parsed)
|
|
91
|
+
if (!parsed) {
|
|
59
92
|
continue;
|
|
93
|
+
}
|
|
60
94
|
allowed.add(modelKey(parsed.provider, parsed.model));
|
|
61
95
|
}
|
|
62
96
|
return allowed;
|
|
63
97
|
}
|
|
64
98
|
export function normalizeAlias(alias) {
|
|
65
99
|
const trimmed = alias.trim();
|
|
66
|
-
if (!trimmed)
|
|
100
|
+
if (!trimmed) {
|
|
67
101
|
throw new Error("Alias cannot be empty.");
|
|
102
|
+
}
|
|
68
103
|
if (!/^[A-Za-z0-9_.:-]+$/.test(trimmed)) {
|
|
69
104
|
throw new Error("Alias must use letters, numbers, dots, underscores, colons, or dashes.");
|
|
70
105
|
}
|
|
@@ -82,36 +117,6 @@ export function resolveKnownAgentId(params) {
|
|
|
82
117
|
}
|
|
83
118
|
return agentId;
|
|
84
119
|
}
|
|
85
|
-
export const isLocalBaseUrl = (baseUrl) => {
|
|
86
|
-
try {
|
|
87
|
-
const url = new URL(baseUrl);
|
|
88
|
-
const host = url.hostname.toLowerCase();
|
|
89
|
-
return (host === "localhost" ||
|
|
90
|
-
host === "127.0.0.1" ||
|
|
91
|
-
host === "0.0.0.0" ||
|
|
92
|
-
host === "::1" ||
|
|
93
|
-
host.endsWith(".local"));
|
|
94
|
-
}
|
|
95
|
-
catch {
|
|
96
|
-
return false;
|
|
97
|
-
}
|
|
98
|
-
};
|
|
99
|
-
export { modelKey };
|
|
100
|
-
export { DEFAULT_MODEL, DEFAULT_PROVIDER };
|
|
101
|
-
export function resolveModelKeysFromEntries(params) {
|
|
102
|
-
const aliasIndex = buildModelAliasIndex({
|
|
103
|
-
cfg: params.cfg,
|
|
104
|
-
defaultProvider: DEFAULT_PROVIDER,
|
|
105
|
-
});
|
|
106
|
-
return params.entries
|
|
107
|
-
.map((entry) => resolveModelRefFromString({
|
|
108
|
-
raw: entry,
|
|
109
|
-
defaultProvider: DEFAULT_PROVIDER,
|
|
110
|
-
aliasIndex,
|
|
111
|
-
}))
|
|
112
|
-
.filter((entry) => Boolean(entry))
|
|
113
|
-
.map((entry) => modelKey(entry.ref.provider, entry.ref.model));
|
|
114
|
-
}
|
|
115
120
|
export function mergePrimaryFallbackConfig(existing, patch) {
|
|
116
121
|
const next = { ...existing };
|
|
117
122
|
if (patch.primary !== undefined) {
|
|
@@ -122,6 +127,29 @@ export function mergePrimaryFallbackConfig(existing, patch) {
|
|
|
122
127
|
}
|
|
123
128
|
return next;
|
|
124
129
|
}
|
|
130
|
+
export function applyDefaultModelPrimaryUpdate(params) {
|
|
131
|
+
const resolved = resolveModelTarget({ raw: params.modelRaw, cfg: params.cfg });
|
|
132
|
+
const key = `${resolved.provider}/${resolved.model}`;
|
|
133
|
+
const nextModels = { ...params.cfg.agents?.defaults?.models };
|
|
134
|
+
if (!nextModels[key]) {
|
|
135
|
+
nextModels[key] = {};
|
|
136
|
+
}
|
|
137
|
+
const defaults = params.cfg.agents?.defaults ?? {};
|
|
138
|
+
const existing = defaults[params.field];
|
|
139
|
+
return {
|
|
140
|
+
...params.cfg,
|
|
141
|
+
agents: {
|
|
142
|
+
...params.cfg.agents,
|
|
143
|
+
defaults: {
|
|
144
|
+
...defaults,
|
|
145
|
+
[params.field]: mergePrimaryFallbackConfig(existing, { primary: key }),
|
|
146
|
+
models: nextModels,
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
export { modelKey };
|
|
152
|
+
export { DEFAULT_MODEL, DEFAULT_PROVIDER };
|
|
125
153
|
/**
|
|
126
154
|
* Model key format: "provider/model"
|
|
127
155
|
*
|