@poolzin/pool-bot 2026.2.3 → 2026.2.5

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.
Files changed (81) hide show
  1. package/dist/agents/agent-paths.js +3 -1
  2. package/dist/agents/anthropic-payload-log.js +2 -1
  3. package/dist/agents/bash-tools.exec.js +2 -1
  4. package/dist/agents/cache-trace.js +8 -4
  5. package/dist/agents/live-auth-keys.js +2 -1
  6. package/dist/agents/model-auth.js +1 -0
  7. package/dist/agents/model-forward-compat.js +187 -0
  8. package/dist/agents/pi-embedded-runner/model.js +10 -56
  9. package/dist/agents/pi-embedded-runner/session-manager-cache.js +2 -1
  10. package/dist/agents/pi-embedded-subscribe.raw-stream.js +2 -1
  11. package/dist/agents/skills/bundled-dir.js +2 -1
  12. package/dist/browser/constants.js +1 -1
  13. package/dist/browser/profiles.js +1 -1
  14. package/dist/build-info.json +3 -3
  15. package/dist/channels/plugins/catalog.js +6 -1
  16. package/dist/cli/daemon-cli/install.js +4 -1
  17. package/dist/cli/daemon-cli/status.gather.js +4 -2
  18. package/dist/cli/memory-cli.js +9 -3
  19. package/dist/cli/profile.js +6 -2
  20. package/dist/cli/program/register.onboard.js +10 -0
  21. package/dist/commands/auth-choice-options.js +11 -0
  22. package/dist/commands/auth-choice.apply.api-providers.js +55 -1
  23. package/dist/commands/auth-choice.apply.plugin-provider.js +1 -56
  24. package/dist/commands/auth-choice.preferred-provider.js +1 -0
  25. package/dist/commands/configure.wizard.js +29 -10
  26. package/dist/commands/dashboard.js +4 -1
  27. package/dist/commands/doctor-gateway-daemon-flow.js +8 -2
  28. package/dist/commands/doctor-gateway-services.js +6 -2
  29. package/dist/commands/doctor-platform-notes.js +3 -1
  30. package/dist/commands/gateway-status/helpers.js +3 -1
  31. package/dist/commands/models/auth.js +1 -58
  32. package/dist/commands/models/list.errors.js +14 -0
  33. package/dist/commands/models/list.list-command.js +32 -21
  34. package/dist/commands/models/list.registry.js +120 -28
  35. package/dist/commands/models/list.status-command.js +1 -0
  36. package/dist/commands/models/shared.js +14 -0
  37. package/dist/commands/onboard-auth.config-core.js +60 -2
  38. package/dist/commands/onboard-auth.credentials.js +12 -1
  39. package/dist/commands/onboard-auth.js +3 -3
  40. package/dist/commands/onboard-auth.models.js +22 -0
  41. package/dist/commands/onboard-non-interactive/local/auth-choice-inference.js +1 -0
  42. package/dist/commands/onboard-non-interactive/local/auth-choice.js +21 -1
  43. package/dist/commands/provider-auth-helpers.js +61 -0
  44. package/dist/commands/status-all.js +4 -2
  45. package/dist/commands/status.gateway-probe.js +4 -2
  46. package/dist/commands/status.scan.js +2 -1
  47. package/dist/config/paths.js +18 -6
  48. package/dist/daemon/launchd.js +4 -1
  49. package/dist/daemon/schtasks.js +4 -1
  50. package/dist/daemon/systemd.js +4 -1
  51. package/dist/entry.js +4 -2
  52. package/dist/gateway/auth.js +4 -1
  53. package/dist/gateway/call.js +4 -2
  54. package/dist/gateway/server/ws-connection/message-handler.js +4 -1
  55. package/dist/gateway/server-browser.js +4 -2
  56. package/dist/gateway/server-constants.js +5 -2
  57. package/dist/gateway/server-cron.js +3 -1
  58. package/dist/gateway/server-discovery-runtime.js +5 -2
  59. package/dist/infra/restart.js +2 -1
  60. package/dist/infra/shell-env.js +3 -2
  61. package/dist/infra/state-migrations.js +3 -1
  62. package/dist/infra/system-presence.js +4 -1
  63. package/dist/infra/update-runner.js +4 -1
  64. package/dist/macos/gateway-daemon.js +6 -3
  65. package/dist/macos/relay-smoke.js +5 -1
  66. package/dist/macos/relay.js +2 -1
  67. package/dist/media/image-ops.js +3 -1
  68. package/dist/node-host/runner.js +2 -1
  69. package/dist/plugins/bundled-dir.js +2 -1
  70. package/dist/plugins/manifest-registry.js +2 -1
  71. package/dist/security/audit.js +2 -1
  72. package/dist/telegram/bot-message-dispatch.js +1 -1
  73. package/dist/telegram/network-config.js +4 -2
  74. package/dist/terminal/palette.js +8 -6
  75. package/dist/terminal/theme.js +12 -12
  76. package/dist/tui/gateway-chat.js +2 -1
  77. package/dist/tui/theme/theme.js +5 -5
  78. package/dist/tui/tui.js +12 -6
  79. package/dist/version.js +2 -1
  80. package/dist/wizard/onboarding.js +6 -2
  81. package/package.json +1 -1
@@ -1,43 +1,129 @@
1
- import { discoverAuthStorage, discoverModels } from "../../agents/pi-model-discovery.js";
2
1
  import { resolvePoolbotAgentDir } from "../../agents/agent-paths.js";
3
2
  import { listProfilesForProvider } from "../../agents/auth-profiles.js";
4
3
  import { getCustomProviderApiKey, resolveAwsSdkEnvVarName, resolveEnvApiKey, } from "../../agents/model-auth.js";
4
+ import { ANTIGRAVITY_OPUS_46_FORWARD_COMPAT_CANDIDATES, resolveForwardCompatModel, } from "../../agents/model-forward-compat.js";
5
5
  import { ensurePoolbotModelsJson } from "../../agents/models-config.js";
6
- import { modelKey } from "./shared.js";
7
- const isLocalBaseUrl = (baseUrl) => {
8
- try {
9
- const url = new URL(baseUrl);
10
- const host = url.hostname.toLowerCase();
11
- return (host === "localhost" ||
12
- host === "127.0.0.1" ||
13
- host === "0.0.0.0" ||
14
- host === "::1" ||
15
- host.endsWith(".local"));
16
- }
17
- catch {
6
+ import { discoverAuthStorage, discoverModels } from "../../agents/pi-model-discovery.js";
7
+ import { formatErrorWithStack, MODEL_AVAILABILITY_UNAVAILABLE_CODE, shouldFallbackToAuthHeuristics, } from "./list.errors.js";
8
+ import { isLocalBaseUrl, modelKey } from "./shared.js";
9
+ const hasAuthForProvider = (provider, cfg, authStore) => {
10
+ if (!cfg || !authStore) {
18
11
  return false;
19
12
  }
20
- };
21
- const hasAuthForProvider = (provider, cfg, authStore) => {
22
- if (listProfilesForProvider(authStore, provider).length > 0)
13
+ if (listProfilesForProvider(authStore, provider).length > 0) {
23
14
  return true;
24
- if (provider === "amazon-bedrock" && resolveAwsSdkEnvVarName())
15
+ }
16
+ if (provider === "amazon-bedrock" && resolveAwsSdkEnvVarName()) {
25
17
  return true;
26
- if (resolveEnvApiKey(provider))
18
+ }
19
+ if (resolveEnvApiKey(provider)) {
27
20
  return true;
28
- if (getCustomProviderApiKey(cfg, provider))
21
+ }
22
+ if (getCustomProviderApiKey(cfg, provider)) {
29
23
  return true;
24
+ }
30
25
  return false;
31
26
  };
27
+ function createAvailabilityUnavailableError(message) {
28
+ const err = new Error(message);
29
+ err.code = MODEL_AVAILABILITY_UNAVAILABLE_CODE;
30
+ return err;
31
+ }
32
+ function normalizeAvailabilityError(err) {
33
+ if (shouldFallbackToAuthHeuristics(err) && err instanceof Error) {
34
+ return err;
35
+ }
36
+ return createAvailabilityUnavailableError(`Model availability unavailable: getAvailable() failed.\n${formatErrorWithStack(err)}`);
37
+ }
38
+ function validateAvailableModels(availableModels) {
39
+ if (!Array.isArray(availableModels)) {
40
+ throw createAvailabilityUnavailableError("Model availability unavailable: getAvailable() returned a non-array value.");
41
+ }
42
+ for (const model of availableModels) {
43
+ if (!model ||
44
+ typeof model !== "object" ||
45
+ typeof model.provider !== "string" ||
46
+ typeof model.id !== "string") {
47
+ throw createAvailabilityUnavailableError("Model availability unavailable: getAvailable() returned invalid model entries.");
48
+ }
49
+ }
50
+ return availableModels;
51
+ }
52
+ function loadAvailableModels(registry) {
53
+ let availableModels;
54
+ try {
55
+ availableModels = registry.getAvailable();
56
+ }
57
+ catch (err) {
58
+ throw normalizeAvailabilityError(err);
59
+ }
60
+ try {
61
+ return validateAvailableModels(availableModels);
62
+ }
63
+ catch (err) {
64
+ throw normalizeAvailabilityError(err);
65
+ }
66
+ }
32
67
  export async function loadModelRegistry(cfg) {
33
68
  await ensurePoolbotModelsJson(cfg);
34
69
  const agentDir = resolvePoolbotAgentDir();
35
70
  const authStorage = discoverAuthStorage(agentDir);
36
71
  const registry = discoverModels(authStorage, agentDir);
37
- const models = registry.getAll();
38
- const availableModels = registry.getAvailable();
39
- const availableKeys = new Set(availableModels.map((model) => modelKey(model.provider, model.id)));
40
- return { registry, models, availableKeys };
72
+ const appended = appendAntigravityForwardCompatModels(registry.getAll(), registry);
73
+ const models = appended.models;
74
+ const synthesizedForwardCompat = appended.synthesizedForwardCompat;
75
+ let availableKeys;
76
+ let availabilityErrorMessage;
77
+ try {
78
+ const availableModels = loadAvailableModels(registry);
79
+ availableKeys = new Set(availableModels.map((model) => modelKey(model.provider, model.id)));
80
+ for (const synthesized of synthesizedForwardCompat) {
81
+ if (hasAvailableTemplate(availableKeys, synthesized.templatePrefixes)) {
82
+ availableKeys.add(synthesized.key);
83
+ }
84
+ }
85
+ }
86
+ catch (err) {
87
+ if (!shouldFallbackToAuthHeuristics(err)) {
88
+ throw err;
89
+ }
90
+ // Some providers can report model-level availability as unavailable.
91
+ // Fall back to provider-level auth heuristics when availability is undefined.
92
+ availableKeys = undefined;
93
+ if (!availabilityErrorMessage) {
94
+ availabilityErrorMessage = formatErrorWithStack(err);
95
+ }
96
+ }
97
+ return { registry, models, availableKeys, availabilityErrorMessage };
98
+ }
99
+ function appendAntigravityForwardCompatModels(models, modelRegistry) {
100
+ const nextModels = [...models];
101
+ const synthesizedForwardCompat = [];
102
+ for (const candidate of ANTIGRAVITY_OPUS_46_FORWARD_COMPAT_CANDIDATES) {
103
+ const key = modelKey("google-antigravity", candidate.id);
104
+ const hasForwardCompat = nextModels.some((model) => modelKey(model.provider, model.id) === key);
105
+ if (hasForwardCompat) {
106
+ continue;
107
+ }
108
+ const fallback = resolveForwardCompatModel("google-antigravity", candidate.id, modelRegistry);
109
+ if (!fallback) {
110
+ continue;
111
+ }
112
+ nextModels.push(fallback);
113
+ synthesizedForwardCompat.push({
114
+ key,
115
+ templatePrefixes: candidate.templatePrefixes,
116
+ });
117
+ }
118
+ return { models: nextModels, synthesizedForwardCompat };
119
+ }
120
+ function hasAvailableTemplate(availableKeys, templatePrefixes) {
121
+ for (const key of availableKeys) {
122
+ if (templatePrefixes.some((prefix) => key.startsWith(prefix))) {
123
+ return true;
124
+ }
125
+ }
126
+ return false;
41
127
  }
42
128
  export function toModelRow(params) {
43
129
  const { model, key, tags, aliases = [], availableKeys, cfg, authStore } = params;
@@ -55,18 +141,24 @@ export function toModelRow(params) {
55
141
  }
56
142
  const input = model.input.join("+") || "text";
57
143
  const local = isLocalBaseUrl(model.baseUrl);
58
- const available = cfg && authStore
59
- ? hasAuthForProvider(model.provider, cfg, authStore)
60
- : (availableKeys?.has(modelKey(model.provider, model.id)) ?? false);
144
+ // Prefer model-level registry availability when present.
145
+ // Fall back to provider-level auth heuristics only if registry availability isn't available.
146
+ const available = availableKeys !== undefined
147
+ ? availableKeys.has(modelKey(model.provider, model.id))
148
+ : cfg && authStore
149
+ ? hasAuthForProvider(model.provider, cfg, authStore)
150
+ : false;
61
151
  const aliasTags = aliases.length > 0 ? [`alias:${aliases.join(",")}`] : [];
62
152
  const mergedTags = new Set(tags);
63
153
  if (aliasTags.length > 0) {
64
154
  for (const tag of mergedTags) {
65
- if (tag === "alias" || tag.startsWith("alias:"))
155
+ if (tag === "alias" || tag.startsWith("alias:")) {
66
156
  mergedTags.delete(tag);
157
+ }
67
158
  }
68
- for (const tag of aliasTags)
159
+ for (const tag of aliasTags) {
69
160
  mergedTags.add(tag);
161
+ }
70
162
  }
71
163
  return {
72
164
  key,
@@ -89,6 +89,7 @@ export async function modelsStatusCommand(opts, runtime) {
89
89
  "zai",
90
90
  "mistral",
91
91
  "synthetic",
92
+ "nvidia",
92
93
  ];
93
94
  for (const provider of envProbeProviders) {
94
95
  if (resolveEnvApiKey(provider))
@@ -82,6 +82,20 @@ export function resolveKnownAgentId(params) {
82
82
  }
83
83
  return agentId;
84
84
  }
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
+ };
85
99
  export { modelKey };
86
100
  export { DEFAULT_MODEL, DEFAULT_PROVIDER };
87
101
  /**
@@ -3,8 +3,8 @@ import { buildQianfanProvider, buildXiaomiProvider, QIANFAN_DEFAULT_MODEL_ID, XI
3
3
  import { buildSyntheticModelDefinition, SYNTHETIC_BASE_URL, SYNTHETIC_DEFAULT_MODEL_REF, SYNTHETIC_MODEL_CATALOG, } from "../agents/synthetic-models.js";
4
4
  import { buildTogetherModelDefinition, TOGETHER_BASE_URL, TOGETHER_MODEL_CATALOG, } from "../agents/together-models.js";
5
5
  import { buildVeniceModelDefinition, VENICE_BASE_URL, VENICE_DEFAULT_MODEL_REF, VENICE_MODEL_CATALOG, } from "../agents/venice-models.js";
6
- import { CLOUDFLARE_AI_GATEWAY_DEFAULT_MODEL_REF, OPENROUTER_DEFAULT_MODEL_REF, TOGETHER_DEFAULT_MODEL_REF, VERCEL_AI_GATEWAY_DEFAULT_MODEL_REF, XIAOMI_DEFAULT_MODEL_REF, ZAI_DEFAULT_MODEL_REF, XAI_DEFAULT_MODEL_REF, } from "./onboard-auth.credentials.js";
7
- import { buildMoonshotModelDefinition, buildXaiModelDefinition, QIANFAN_BASE_URL, QIANFAN_DEFAULT_MODEL_REF, KIMI_CODING_MODEL_REF, MOONSHOT_BASE_URL, MOONSHOT_CN_BASE_URL, MOONSHOT_DEFAULT_MODEL_ID, MOONSHOT_DEFAULT_MODEL_REF, XAI_BASE_URL, XAI_DEFAULT_MODEL_ID, } from "./onboard-auth.models.js";
6
+ import { CLOUDFLARE_AI_GATEWAY_DEFAULT_MODEL_REF, OPENROUTER_DEFAULT_MODEL_REF, TOGETHER_DEFAULT_MODEL_REF, VERCEL_AI_GATEWAY_DEFAULT_MODEL_REF, XIAOMI_DEFAULT_MODEL_REF, ZAI_DEFAULT_MODEL_REF, XAI_DEFAULT_MODEL_REF, NVIDIA_DEFAULT_MODEL_REF, } from "./onboard-auth.credentials.js";
7
+ import { buildMoonshotModelDefinition, buildNvidiaModelDefinition, buildXaiModelDefinition, QIANFAN_BASE_URL, QIANFAN_DEFAULT_MODEL_REF, KIMI_CODING_MODEL_REF, MOONSHOT_BASE_URL, MOONSHOT_CN_BASE_URL, MOONSHOT_DEFAULT_MODEL_ID, MOONSHOT_DEFAULT_MODEL_REF, NVIDIA_BASE_URL, NVIDIA_DEFAULT_MODEL_ID, XAI_BASE_URL, XAI_DEFAULT_MODEL_ID, } from "./onboard-auth.models.js";
8
8
  export function applyZaiConfig(cfg) {
9
9
  const models = { ...cfg.agents?.defaults?.models };
10
10
  models[ZAI_DEFAULT_MODEL_REF] = {
@@ -722,3 +722,61 @@ export function applyQianfanConfig(cfg) {
722
722
  },
723
723
  };
724
724
  }
725
+ export function applyNvidiaProviderConfig(cfg) {
726
+ const models = { ...cfg.agents?.defaults?.models };
727
+ models[NVIDIA_DEFAULT_MODEL_REF] = {
728
+ ...models[NVIDIA_DEFAULT_MODEL_REF],
729
+ alias: models[NVIDIA_DEFAULT_MODEL_REF]?.alias ?? "Nemotron",
730
+ };
731
+ const providers = { ...cfg.models?.providers };
732
+ const existingProvider = providers.nvidia;
733
+ const existingModels = Array.isArray(existingProvider?.models) ? existingProvider.models : [];
734
+ const defaultModel = buildNvidiaModelDefinition();
735
+ const hasDefaultModel = existingModels.some((model) => model.id === NVIDIA_DEFAULT_MODEL_ID);
736
+ const mergedModels = hasDefaultModel ? existingModels : [...existingModels, defaultModel];
737
+ const { apiKey: existingApiKey, ...existingProviderRest } = (existingProvider ?? {});
738
+ const resolvedApiKey = typeof existingApiKey === "string" ? existingApiKey : undefined;
739
+ const normalizedApiKey = resolvedApiKey?.trim();
740
+ providers.nvidia = {
741
+ ...existingProviderRest,
742
+ baseUrl: NVIDIA_BASE_URL,
743
+ api: "openai-completions",
744
+ ...(normalizedApiKey ? { apiKey: normalizedApiKey } : {}),
745
+ models: mergedModels.length > 0 ? mergedModels : [defaultModel],
746
+ };
747
+ return {
748
+ ...cfg,
749
+ agents: {
750
+ ...cfg.agents,
751
+ defaults: {
752
+ ...cfg.agents?.defaults,
753
+ models,
754
+ },
755
+ },
756
+ models: {
757
+ mode: cfg.models?.mode ?? "merge",
758
+ providers,
759
+ },
760
+ };
761
+ }
762
+ export function applyNvidiaConfig(cfg) {
763
+ const next = applyNvidiaProviderConfig(cfg);
764
+ const existingModel = next.agents?.defaults?.model;
765
+ return {
766
+ ...next,
767
+ agents: {
768
+ ...next.agents,
769
+ defaults: {
770
+ ...next.agents?.defaults,
771
+ model: {
772
+ ...(existingModel && "fallbacks" in existingModel
773
+ ? {
774
+ fallbacks: existingModel.fallbacks,
775
+ }
776
+ : undefined),
777
+ primary: NVIDIA_DEFAULT_MODEL_REF,
778
+ },
779
+ },
780
+ },
781
+ };
782
+ }
@@ -1,7 +1,7 @@
1
1
  import { resolvePoolbotAgentDir } from "../agents/agent-paths.js";
2
2
  import { upsertAuthProfile } from "../agents/auth-profiles.js";
3
3
  export { CLOUDFLARE_AI_GATEWAY_DEFAULT_MODEL_REF } from "../agents/cloudflare-ai-gateway.js";
4
- export { XAI_DEFAULT_MODEL_REF } from "./onboard-auth.models.js";
4
+ export { XAI_DEFAULT_MODEL_REF, NVIDIA_DEFAULT_MODEL_REF } from "./onboard-auth.models.js";
5
5
  const resolveAuthAgentDir = (agentDir) => agentDir ?? resolvePoolbotAgentDir();
6
6
  export async function writeOAuthCredentials(provider, creds, agentDir) {
7
7
  const email = typeof creds.email === "string" && creds.email.trim() ? creds.email.trim() : "default";
@@ -207,3 +207,14 @@ export function setXaiApiKey(key, agentDir) {
207
207
  agentDir: resolveAuthAgentDir(agentDir),
208
208
  });
209
209
  }
210
+ export function setNvidiaApiKey(key, agentDir) {
211
+ upsertAuthProfile({
212
+ profileId: "nvidia:default",
213
+ credential: {
214
+ type: "api_key",
215
+ provider: "nvidia",
216
+ key,
217
+ },
218
+ agentDir: resolveAuthAgentDir(agentDir),
219
+ });
220
+ }
@@ -1,7 +1,7 @@
1
1
  export { SYNTHETIC_DEFAULT_MODEL_ID, SYNTHETIC_DEFAULT_MODEL_REF, } from "../agents/synthetic-models.js";
2
2
  export { VENICE_DEFAULT_MODEL_ID, VENICE_DEFAULT_MODEL_REF } from "../agents/venice-models.js";
3
- export { applyAuthProfileConfig, applyCloudflareAiGatewayConfig, applyCloudflareAiGatewayProviderConfig, applyQianfanConfig, applyQianfanProviderConfig, applyKimiCodeConfig, applyKimiCodeProviderConfig, applyMoonshotConfig, applyMoonshotConfigCn, applyMoonshotProviderConfig, applyMoonshotProviderConfigCn, applyOpenrouterConfig, applyOpenrouterProviderConfig, applySyntheticConfig, applySyntheticProviderConfig, applyTogetherConfig, applyTogetherProviderConfig, applyVeniceConfig, applyVeniceProviderConfig, applyVercelAiGatewayConfig, applyVercelAiGatewayProviderConfig, applyXaiConfig, applyXaiProviderConfig, applyXiaomiConfig, applyXiaomiProviderConfig, applyZaiConfig, } from "./onboard-auth.config-core.js";
3
+ export { applyAuthProfileConfig, applyCloudflareAiGatewayConfig, applyCloudflareAiGatewayProviderConfig, applyQianfanConfig, applyQianfanProviderConfig, applyKimiCodeConfig, applyKimiCodeProviderConfig, applyMoonshotConfig, applyMoonshotConfigCn, applyMoonshotProviderConfig, applyMoonshotProviderConfigCn, applyOpenrouterConfig, applyOpenrouterProviderConfig, applySyntheticConfig, applySyntheticProviderConfig, applyTogetherConfig, applyTogetherProviderConfig, applyVeniceConfig, applyVeniceProviderConfig, applyVercelAiGatewayConfig, applyVercelAiGatewayProviderConfig, applyNvidiaConfig, applyNvidiaProviderConfig, applyXaiConfig, applyXaiProviderConfig, applyXiaomiConfig, applyXiaomiProviderConfig, applyZaiConfig, } from "./onboard-auth.config-core.js";
4
4
  export { applyMinimaxApiConfig, applyMinimaxApiProviderConfig, applyMinimaxConfig, applyMinimaxHostedConfig, applyMinimaxHostedProviderConfig, applyMinimaxProviderConfig, } from "./onboard-auth.config-minimax.js";
5
5
  export { applyOpencodeZenConfig, applyOpencodeZenProviderConfig, } from "./onboard-auth.config-opencode.js";
6
- export { CLOUDFLARE_AI_GATEWAY_DEFAULT_MODEL_REF, OPENROUTER_DEFAULT_MODEL_REF, setAnthropicApiKey, setCloudflareAiGatewayConfig, setQianfanApiKey, setGeminiApiKey, setKimiCodingApiKey, setMinimaxApiKey, setMoonshotApiKey, setOpencodeZenApiKey, setOpenrouterApiKey, setSyntheticApiKey, setTogetherApiKey, setVeniceApiKey, setVercelAiGatewayApiKey, setXiaomiApiKey, setZaiApiKey, setXaiApiKey, writeOAuthCredentials, VERCEL_AI_GATEWAY_DEFAULT_MODEL_REF, XIAOMI_DEFAULT_MODEL_REF, ZAI_DEFAULT_MODEL_REF, TOGETHER_DEFAULT_MODEL_REF, XAI_DEFAULT_MODEL_REF, } from "./onboard-auth.credentials.js";
7
- export { buildMinimaxApiModelDefinition, buildMinimaxModelDefinition, buildMoonshotModelDefinition, DEFAULT_MINIMAX_BASE_URL, MOONSHOT_CN_BASE_URL, QIANFAN_BASE_URL, QIANFAN_DEFAULT_MODEL_ID, QIANFAN_DEFAULT_MODEL_REF, KIMI_CODING_MODEL_ID, KIMI_CODING_MODEL_REF, MINIMAX_API_BASE_URL, MINIMAX_HOSTED_MODEL_ID, MINIMAX_HOSTED_MODEL_REF, MOONSHOT_BASE_URL, MOONSHOT_DEFAULT_MODEL_ID, MOONSHOT_DEFAULT_MODEL_REF, } from "./onboard-auth.models.js";
6
+ export { CLOUDFLARE_AI_GATEWAY_DEFAULT_MODEL_REF, OPENROUTER_DEFAULT_MODEL_REF, setAnthropicApiKey, setCloudflareAiGatewayConfig, setQianfanApiKey, setGeminiApiKey, setKimiCodingApiKey, setMinimaxApiKey, setMoonshotApiKey, setOpencodeZenApiKey, setOpenrouterApiKey, setSyntheticApiKey, setTogetherApiKey, setVeniceApiKey, setVercelAiGatewayApiKey, setXiaomiApiKey, setZaiApiKey, setNvidiaApiKey, setXaiApiKey, writeOAuthCredentials, VERCEL_AI_GATEWAY_DEFAULT_MODEL_REF, NVIDIA_DEFAULT_MODEL_REF, XIAOMI_DEFAULT_MODEL_REF, ZAI_DEFAULT_MODEL_REF, TOGETHER_DEFAULT_MODEL_REF, XAI_DEFAULT_MODEL_REF, } from "./onboard-auth.credentials.js";
7
+ export { buildMinimaxApiModelDefinition, buildMinimaxModelDefinition, buildMoonshotModelDefinition, DEFAULT_MINIMAX_BASE_URL, MOONSHOT_CN_BASE_URL, QIANFAN_BASE_URL, QIANFAN_DEFAULT_MODEL_ID, QIANFAN_DEFAULT_MODEL_REF, KIMI_CODING_MODEL_ID, KIMI_CODING_MODEL_REF, MINIMAX_API_BASE_URL, MINIMAX_HOSTED_MODEL_ID, MINIMAX_HOSTED_MODEL_REF, MOONSHOT_BASE_URL, MOONSHOT_DEFAULT_MODEL_ID, MOONSHOT_DEFAULT_MODEL_REF, buildNvidiaModelDefinition, NVIDIA_BASE_URL, NVIDIA_DEFAULT_MODEL_ID, } from "./onboard-auth.models.js";
@@ -100,3 +100,25 @@ export function buildXaiModelDefinition() {
100
100
  maxTokens: XAI_DEFAULT_MAX_TOKENS,
101
101
  };
102
102
  }
103
+ export const NVIDIA_BASE_URL = "https://integrate.api.nvidia.com/v1";
104
+ export const NVIDIA_DEFAULT_MODEL_ID = "llama-3.1-nemotron-ultra-253b-v1";
105
+ export const NVIDIA_DEFAULT_MODEL_REF = `nvidia/${NVIDIA_DEFAULT_MODEL_ID}`;
106
+ export const NVIDIA_DEFAULT_CONTEXT_WINDOW = 131072;
107
+ export const NVIDIA_DEFAULT_MAX_TOKENS = 8192;
108
+ export const NVIDIA_DEFAULT_COST = {
109
+ input: 0,
110
+ output: 0,
111
+ cacheRead: 0,
112
+ cacheWrite: 0,
113
+ };
114
+ export function buildNvidiaModelDefinition() {
115
+ return {
116
+ id: NVIDIA_DEFAULT_MODEL_ID,
117
+ name: "Nemotron Ultra 253B",
118
+ reasoning: false,
119
+ input: ["text"],
120
+ cost: NVIDIA_DEFAULT_COST,
121
+ contextWindow: NVIDIA_DEFAULT_CONTEXT_WINDOW,
122
+ maxTokens: NVIDIA_DEFAULT_MAX_TOKENS,
123
+ };
124
+ }
@@ -16,6 +16,7 @@ const AUTH_CHOICE_FLAG_MAP = [
16
16
  { flag: "zaiApiKey", authChoice: "zai-api-key", label: "--zai-api-key" },
17
17
  { flag: "xiaomiApiKey", authChoice: "xiaomi-api-key", label: "--xiaomi-api-key" },
18
18
  { flag: "xaiApiKey", authChoice: "xai-api-key", label: "--xai-api-key" },
19
+ { flag: "nvidiaApiKey", authChoice: "nvidia-api-key", label: "--nvidia-api-key" },
19
20
  { flag: "minimaxApiKey", authChoice: "minimax-api", label: "--minimax-api-key" },
20
21
  { flag: "opencodeZenApiKey", authChoice: "opencode-zen", label: "--opencode-zen-api-key" },
21
22
  ];
@@ -6,7 +6,7 @@ import { normalizeSecretInput } from "../../../utils/normalize-secret-input.js";
6
6
  import { buildTokenProfileId, validateAnthropicSetupToken } from "../../auth-token.js";
7
7
  import { applyGoogleGeminiModelDefault } from "../../google-gemini-model-default.js";
8
8
  import { applyOpenAIConfig } from "../../openai-model-default.js";
9
- import { applyAuthProfileConfig, applyCloudflareAiGatewayConfig, applyKimiCodeConfig, applyMinimaxApiConfig, applyMinimaxConfig, applyMoonshotConfig, applyMoonshotConfigCn, applyOpencodeZenConfig, applyOpenrouterConfig, applyQianfanConfig, applySyntheticConfig, applyTogetherConfig, applyVeniceConfig, applyVercelAiGatewayConfig, applyXaiConfig, applyXiaomiConfig, applyZaiConfig, setAnthropicApiKey, setCloudflareAiGatewayConfig, setGeminiApiKey, setKimiCodingApiKey, setMinimaxApiKey, setMoonshotApiKey, setOpencodeZenApiKey, setOpenrouterApiKey, setQianfanApiKey, setSyntheticApiKey, setTogetherApiKey, setVeniceApiKey, setVercelAiGatewayApiKey, setXaiApiKey, setXiaomiApiKey, setZaiApiKey, } from "../../onboard-auth.js";
9
+ import { applyAuthProfileConfig, applyCloudflareAiGatewayConfig, applyKimiCodeConfig, applyMinimaxApiConfig, applyMinimaxConfig, applyMoonshotConfig, applyMoonshotConfigCn, applyOpencodeZenConfig, applyOpenrouterConfig, applyQianfanConfig, applySyntheticConfig, applyTogetherConfig, applyVeniceConfig, applyVercelAiGatewayConfig, applyNvidiaConfig, applyXaiConfig, applyXiaomiConfig, applyZaiConfig, setAnthropicApiKey, setCloudflareAiGatewayConfig, setGeminiApiKey, setKimiCodingApiKey, setMinimaxApiKey, setMoonshotApiKey, setNvidiaApiKey, setOpencodeZenApiKey, setOpenrouterApiKey, setQianfanApiKey, setSyntheticApiKey, setTogetherApiKey, setVeniceApiKey, setVercelAiGatewayApiKey, setXaiApiKey, setXiaomiApiKey, setZaiApiKey, } from "../../onboard-auth.js";
10
10
  import { resolveNonInteractiveApiKey } from "../api-keys.js";
11
11
  import { shortenHomePath } from "../../../utils.js";
12
12
  export async function applyNonInteractiveAuthChoice(params) {
@@ -358,6 +358,26 @@ export async function applyNonInteractiveAuthChoice(params) {
358
358
  });
359
359
  return applyQianfanConfig(nextConfig);
360
360
  }
361
+ if (authChoice === "nvidia-api-key") {
362
+ const resolved = await resolveNonInteractiveApiKey({
363
+ provider: "nvidia",
364
+ cfg: baseConfig,
365
+ flagValue: opts.nvidiaApiKey,
366
+ flagName: "--nvidia-api-key",
367
+ envVar: "NVIDIA_API_KEY",
368
+ runtime,
369
+ });
370
+ if (!resolved)
371
+ return null;
372
+ if (resolved.source !== "profile")
373
+ setNvidiaApiKey(resolved.key);
374
+ nextConfig = applyAuthProfileConfig(nextConfig, {
375
+ profileId: "nvidia:default",
376
+ provider: "nvidia",
377
+ mode: "api_key",
378
+ });
379
+ return applyNvidiaConfig(nextConfig);
380
+ }
361
381
  if (authChoice === "cloudflare-ai-gateway-api-key") {
362
382
  const accountId = opts.cloudflareAiGatewayAccountId?.trim() ?? "";
363
383
  const gatewayId = opts.cloudflareAiGatewayGatewayId?.trim() ?? "";
@@ -0,0 +1,61 @@
1
+ import { normalizeProviderId } from "../agents/model-selection.js";
2
+ export function resolveProviderMatch(providers, rawProvider) {
3
+ const raw = rawProvider?.trim();
4
+ if (!raw) {
5
+ return null;
6
+ }
7
+ const normalized = normalizeProviderId(raw);
8
+ return (providers.find((provider) => normalizeProviderId(provider.id) === normalized) ??
9
+ providers.find((provider) => provider.aliases?.some((alias) => normalizeProviderId(alias) === normalized) ?? false) ??
10
+ null);
11
+ }
12
+ export function pickAuthMethod(provider, rawMethod) {
13
+ const raw = rawMethod?.trim();
14
+ if (!raw) {
15
+ return null;
16
+ }
17
+ const normalized = raw.toLowerCase();
18
+ return (provider.auth.find((method) => method.id.toLowerCase() === normalized) ??
19
+ provider.auth.find((method) => method.label.toLowerCase() === normalized) ??
20
+ null);
21
+ }
22
+ function isPlainRecord(value) {
23
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
24
+ }
25
+ export function mergeConfigPatch(base, patch) {
26
+ if (!isPlainRecord(base) || !isPlainRecord(patch)) {
27
+ return patch;
28
+ }
29
+ const next = { ...base };
30
+ for (const [key, value] of Object.entries(patch)) {
31
+ const existing = next[key];
32
+ if (isPlainRecord(existing) && isPlainRecord(value)) {
33
+ next[key] = mergeConfigPatch(existing, value);
34
+ }
35
+ else {
36
+ next[key] = value;
37
+ }
38
+ }
39
+ return next;
40
+ }
41
+ export function applyDefaultModel(cfg, model) {
42
+ const models = { ...cfg.agents?.defaults?.models };
43
+ models[model] = models[model] ?? {};
44
+ const existingModel = cfg.agents?.defaults?.model;
45
+ return {
46
+ ...cfg,
47
+ agents: {
48
+ ...cfg.agents,
49
+ defaults: {
50
+ ...cfg.agents?.defaults,
51
+ models,
52
+ model: {
53
+ ...(existingModel && typeof existingModel === "object" && "fallbacks" in existingModel
54
+ ? { fallbacks: existingModel.fallbacks }
55
+ : undefined),
56
+ primary: model,
57
+ },
58
+ },
59
+ },
60
+ };
61
+ }
@@ -118,9 +118,11 @@ export async function statusAllCommand(runtime, opts) {
118
118
  ? typeof remote?.token === "string" && remote.token.trim()
119
119
  ? remote.token.trim()
120
120
  : undefined
121
- : process.env.POOLBOT_GATEWAY_TOKEN?.trim() || process.env.CLAWDBOT_GATEWAY_TOKEN?.trim() ||
121
+ : process.env.POOLBOT_GATEWAY_TOKEN?.trim() ||
122
+ process.env.CLAWDBOT_GATEWAY_TOKEN?.trim() ||
122
123
  (typeof authToken === "string" && authToken.trim() ? authToken.trim() : undefined);
123
- const password = process.env.POOLBOT_GATEWAY_PASSWORD?.trim() || process.env.CLAWDBOT_GATEWAY_PASSWORD?.trim() ||
124
+ const password = process.env.POOLBOT_GATEWAY_PASSWORD?.trim() ||
125
+ process.env.CLAWDBOT_GATEWAY_PASSWORD?.trim() ||
124
126
  (mode === "remote"
125
127
  ? typeof remote?.password === "string" && remote.password.trim()
126
128
  ? remote.password.trim()
@@ -7,9 +7,11 @@ export function resolveGatewayProbeAuth(cfg) {
7
7
  ? typeof remote?.token === "string" && remote.token.trim().length > 0
8
8
  ? remote.token.trim()
9
9
  : undefined
10
- : process.env.POOLBOT_GATEWAY_TOKEN?.trim() || process.env.CLAWDBOT_GATEWAY_TOKEN?.trim() ||
10
+ : process.env.POOLBOT_GATEWAY_TOKEN?.trim() ||
11
+ process.env.CLAWDBOT_GATEWAY_TOKEN?.trim() ||
11
12
  (typeof authToken === "string" && authToken.trim().length > 0 ? authToken.trim() : undefined);
12
- const password = process.env.POOLBOT_GATEWAY_PASSWORD?.trim() || process.env.CLAWDBOT_GATEWAY_PASSWORD?.trim() ||
13
+ const password = process.env.POOLBOT_GATEWAY_PASSWORD?.trim() ||
14
+ process.env.CLAWDBOT_GATEWAY_PASSWORD?.trim() ||
13
15
  (isRemoteMode
14
16
  ? typeof remote?.password === "string" && remote.password.trim().length > 0
15
17
  ? remote.password.trim()
@@ -87,7 +87,8 @@ export async function scanStatus(opts, _runtime) {
87
87
  const channels = await buildChannelsTable(cfg, {
88
88
  // Show token previews in regular status; keep `status --all` redacted.
89
89
  // Set `POOLBOT_SHOW_SECRETS=0` (or `CLAWDBOT_SHOW_SECRETS=0`) to force redaction.
90
- showSecrets: (process.env.POOLBOT_SHOW_SECRETS?.trim() ?? process.env.CLAWDBOT_SHOW_SECRETS?.trim()) !== "0",
90
+ showSecrets: (process.env.POOLBOT_SHOW_SECRETS?.trim() ??
91
+ process.env.CLAWDBOT_SHOW_SECRETS?.trim()) !== "0",
91
92
  });
92
93
  progress.tick();
93
94
  progress.setLabel("Checking memory…");
@@ -47,7 +47,9 @@ export function resolveNewStateDir(homedir = resolveDefaultHomeDir) {
47
47
  */
48
48
  export function resolveStateDir(env = process.env, homedir = envHomedir(env)) {
49
49
  const effectiveHomedir = () => resolveRequiredHomeDir(env, homedir);
50
- const override = env.POOLBOT_STATE_DIR?.trim() || env.MOLTBOT_STATE_DIR?.trim() || env.CLAWDBOT_STATE_DIR?.trim();
50
+ const override = env.POOLBOT_STATE_DIR?.trim() ||
51
+ env.MOLTBOT_STATE_DIR?.trim() ||
52
+ env.CLAWDBOT_STATE_DIR?.trim();
51
53
  if (override) {
52
54
  return resolveUserPath(override, env, effectiveHomedir);
53
55
  }
@@ -92,7 +94,9 @@ export const STATE_DIR = resolveStateDir();
92
94
  * Default: ~/.poolbot/poolbot.json (or $*_STATE_DIR/poolbot.json)
93
95
  */
94
96
  export function resolveCanonicalConfigPath(env = process.env, stateDir = resolveStateDir(env, envHomedir(env))) {
95
- const override = env.POOLBOT_CONFIG_PATH?.trim() || env.MOLTBOT_CONFIG_PATH?.trim() || env.CLAWDBOT_CONFIG_PATH?.trim();
97
+ const override = env.POOLBOT_CONFIG_PATH?.trim() ||
98
+ env.MOLTBOT_CONFIG_PATH?.trim() ||
99
+ env.CLAWDBOT_CONFIG_PATH?.trim();
96
100
  if (override) {
97
101
  return resolveUserPath(override, env, envHomedir(env));
98
102
  }
@@ -121,11 +125,15 @@ export function resolveConfigPathCandidate(env = process.env, homedir = envHomed
121
125
  * Active config path (prefers existing config files).
122
126
  */
123
127
  export function resolveConfigPath(env = process.env, stateDir = resolveStateDir(env, envHomedir(env)), homedir = envHomedir(env)) {
124
- const override = env.POOLBOT_CONFIG_PATH?.trim() || env.MOLTBOT_CONFIG_PATH?.trim() || env.CLAWDBOT_CONFIG_PATH?.trim();
128
+ const override = env.POOLBOT_CONFIG_PATH?.trim() ||
129
+ env.MOLTBOT_CONFIG_PATH?.trim() ||
130
+ env.CLAWDBOT_CONFIG_PATH?.trim();
125
131
  if (override) {
126
132
  return resolveUserPath(override, env, homedir);
127
133
  }
128
- const stateOverride = env.POOLBOT_STATE_DIR?.trim() || env.MOLTBOT_STATE_DIR?.trim() || env.CLAWDBOT_STATE_DIR?.trim();
134
+ const stateOverride = env.POOLBOT_STATE_DIR?.trim() ||
135
+ env.MOLTBOT_STATE_DIR?.trim() ||
136
+ env.CLAWDBOT_STATE_DIR?.trim();
129
137
  const candidates = [
130
138
  path.join(stateDir, CONFIG_FILENAME),
131
139
  ...LEGACY_CONFIG_FILENAMES.map((name) => path.join(stateDir, name)),
@@ -157,12 +165,16 @@ export const CONFIG_PATH = resolveConfigPathCandidate();
157
165
  */
158
166
  export function resolveDefaultConfigCandidates(env = process.env, homedir = envHomedir(env)) {
159
167
  const effectiveHomedir = () => resolveRequiredHomeDir(env, homedir);
160
- const explicit = env.POOLBOT_CONFIG_PATH?.trim() || env.MOLTBOT_CONFIG_PATH?.trim() || env.CLAWDBOT_CONFIG_PATH?.trim();
168
+ const explicit = env.POOLBOT_CONFIG_PATH?.trim() ||
169
+ env.MOLTBOT_CONFIG_PATH?.trim() ||
170
+ env.CLAWDBOT_CONFIG_PATH?.trim();
161
171
  if (explicit) {
162
172
  return [resolveUserPath(explicit, env, effectiveHomedir)];
163
173
  }
164
174
  const candidates = [];
165
- const poolbotStateDir = env.POOLBOT_STATE_DIR?.trim() || env.MOLTBOT_STATE_DIR?.trim() || env.CLAWDBOT_STATE_DIR?.trim();
175
+ const poolbotStateDir = env.POOLBOT_STATE_DIR?.trim() ||
176
+ env.MOLTBOT_STATE_DIR?.trim() ||
177
+ env.CLAWDBOT_STATE_DIR?.trim();
166
178
  if (poolbotStateDir) {
167
179
  const resolved = resolveUserPath(poolbotStateDir, env, effectiveHomedir);
168
180
  candidates.push(path.join(resolved, CONFIG_FILENAME));
@@ -278,7 +278,10 @@ export async function installLaunchAgent({ env, stdout, programArguments, workin
278
278
  const serviceDescription = description ??
279
279
  formatGatewayServiceDescription({
280
280
  profile: env.POOLBOT_PROFILE ?? env.CLAWDBOT_PROFILE,
281
- version: environment?.POOLBOT_SERVICE_VERSION ?? environment?.CLAWDBOT_SERVICE_VERSION ?? env.POOLBOT_SERVICE_VERSION ?? env.CLAWDBOT_SERVICE_VERSION,
281
+ version: environment?.POOLBOT_SERVICE_VERSION ??
282
+ environment?.CLAWDBOT_SERVICE_VERSION ??
283
+ env.POOLBOT_SERVICE_VERSION ??
284
+ env.CLAWDBOT_SERVICE_VERSION,
282
285
  });
283
286
  const plist = buildLaunchAgentPlist({
284
287
  label,
@@ -186,7 +186,10 @@ export async function installScheduledTask({ env, stdout, programArguments, work
186
186
  const taskDescription = description ??
187
187
  formatGatewayServiceDescription({
188
188
  profile: env.POOLBOT_PROFILE ?? env.CLAWDBOT_PROFILE,
189
- version: environment?.POOLBOT_SERVICE_VERSION ?? environment?.CLAWDBOT_SERVICE_VERSION ?? env.POOLBOT_SERVICE_VERSION ?? env.CLAWDBOT_SERVICE_VERSION,
189
+ version: environment?.POOLBOT_SERVICE_VERSION ??
190
+ environment?.CLAWDBOT_SERVICE_VERSION ??
191
+ env.POOLBOT_SERVICE_VERSION ??
192
+ env.CLAWDBOT_SERVICE_VERSION,
190
193
  });
191
194
  const script = buildTaskScript({
192
195
  description: taskDescription,
@@ -153,7 +153,10 @@ export async function installSystemdService({ env, stdout, programArguments, wor
153
153
  const serviceDescription = description ??
154
154
  formatGatewayServiceDescription({
155
155
  profile: env.POOLBOT_PROFILE ?? env.CLAWDBOT_PROFILE,
156
- version: environment?.POOLBOT_SERVICE_VERSION ?? environment?.CLAWDBOT_SERVICE_VERSION ?? env.POOLBOT_SERVICE_VERSION ?? env.CLAWDBOT_SERVICE_VERSION,
156
+ version: environment?.POOLBOT_SERVICE_VERSION ??
157
+ environment?.CLAWDBOT_SERVICE_VERSION ??
158
+ env.POOLBOT_SERVICE_VERSION ??
159
+ env.CLAWDBOT_SERVICE_VERSION,
157
160
  });
158
161
  const unit = buildSystemdUnit({
159
162
  description: serviceDescription,
package/dist/entry.js CHANGED
@@ -25,9 +25,11 @@ function hasExperimentalWarningSuppressed() {
25
25
  return false;
26
26
  }
27
27
  function ensureExperimentalWarningSuppressed() {
28
- if (isTruthyEnvValue(process.env.POOLBOT_NO_RESPAWN) || isTruthyEnvValue(process.env.CLAWDBOT_NO_RESPAWN))
28
+ if (isTruthyEnvValue(process.env.POOLBOT_NO_RESPAWN) ||
29
+ isTruthyEnvValue(process.env.CLAWDBOT_NO_RESPAWN))
29
30
  return false;
30
- if (isTruthyEnvValue(process.env.POOLBOT_NODE_OPTIONS_READY) || isTruthyEnvValue(process.env.CLAWDBOT_NODE_OPTIONS_READY))
31
+ if (isTruthyEnvValue(process.env.POOLBOT_NODE_OPTIONS_READY) ||
32
+ isTruthyEnvValue(process.env.CLAWDBOT_NODE_OPTIONS_READY))
31
33
  return false;
32
34
  if (hasExperimentalWarningSuppressed())
33
35
  return false;
@@ -128,7 +128,10 @@ export function resolveGatewayAuth(params) {
128
128
  const authConfig = params.authConfig ?? {};
129
129
  const env = params.env ?? process.env;
130
130
  const token = authConfig.token ?? env.POOLBOT_GATEWAY_TOKEN ?? env.CLAWDBOT_GATEWAY_TOKEN ?? undefined;
131
- const password = authConfig.password ?? env.POOLBOT_GATEWAY_PASSWORD ?? env.CLAWDBOT_GATEWAY_PASSWORD ?? undefined;
131
+ const password = authConfig.password ??
132
+ env.POOLBOT_GATEWAY_PASSWORD ??
133
+ env.CLAWDBOT_GATEWAY_PASSWORD ??
134
+ undefined;
132
135
  const mode = authConfig.mode ?? (password ? "password" : "token");
133
136
  const allowTailscale = authConfig.allowTailscale ?? (params.tailscaleMode === "serve" && mode !== "password");
134
137
  return {