@poolzin/pool-bot 2026.2.4 → 2026.2.6
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/dist/agents/auth-profiles/profiles.js +9 -0
- package/dist/agents/auth-profiles.js +1 -1
- package/dist/agents/huggingface-models.js +166 -0
- package/dist/agents/model-auth.js +6 -0
- package/dist/agents/model-forward-compat.js +187 -0
- package/dist/agents/pi-embedded-runner/model.js +10 -56
- package/dist/browser/constants.js +1 -1
- package/dist/browser/profiles.js +1 -1
- package/dist/build-info.json +3 -3
- package/dist/cli/config-cli.js +17 -3
- package/dist/cli/program/register.onboard.js +38 -5
- package/dist/commands/auth-choice-options.js +71 -7
- package/dist/commands/auth-choice.apply.api-providers.js +202 -97
- package/dist/commands/auth-choice.apply.huggingface.js +130 -0
- package/dist/commands/auth-choice.apply.openrouter.js +77 -0
- package/dist/commands/auth-choice.apply.plugin-provider.js +1 -56
- package/dist/commands/auth-choice.apply.vllm.js +92 -0
- package/dist/commands/auth-choice.preferred-provider.js +10 -0
- package/dist/commands/models/auth.js +1 -58
- package/dist/commands/models/list.errors.js +14 -0
- package/dist/commands/models/list.list-command.js +32 -21
- package/dist/commands/models/list.registry.js +120 -28
- package/dist/commands/models/list.status-command.js +1 -0
- package/dist/commands/models/shared.js +14 -0
- package/dist/commands/onboard-auth.config-core.js +265 -8
- package/dist/commands/onboard-auth.credentials.js +47 -6
- package/dist/commands/onboard-auth.js +3 -3
- package/dist/commands/onboard-auth.models.js +67 -0
- package/dist/commands/onboard-custom.js +181 -70
- package/dist/commands/onboard-non-interactive/api-keys.js +10 -1
- package/dist/commands/onboard-non-interactive/local/auth-choice-inference.js +15 -7
- package/dist/commands/onboard-non-interactive/local/auth-choice.js +322 -124
- package/dist/commands/provider-auth-helpers.js +61 -0
- package/dist/commands/zai-endpoint-detect.js +97 -0
- package/dist/config/legacy.migrations.part-3.js +57 -0
- package/dist/terminal/theme.js +1 -1
- package/package.json +1 -1
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { fetchWithTimeout } from "../utils/fetch-timeout.js";
|
|
2
|
+
import { ZAI_CN_BASE_URL, ZAI_CODING_CN_BASE_URL, ZAI_CODING_GLOBAL_BASE_URL, ZAI_GLOBAL_BASE_URL, } from "./onboard-auth.models.js";
|
|
3
|
+
async function probeZaiChatCompletions(params) {
|
|
4
|
+
try {
|
|
5
|
+
const res = await fetchWithTimeout(`${params.baseUrl}/chat/completions`, {
|
|
6
|
+
method: "POST",
|
|
7
|
+
headers: {
|
|
8
|
+
authorization: `Bearer ${params.apiKey}`,
|
|
9
|
+
"content-type": "application/json",
|
|
10
|
+
},
|
|
11
|
+
body: JSON.stringify({
|
|
12
|
+
model: params.modelId,
|
|
13
|
+
stream: false,
|
|
14
|
+
max_tokens: 1,
|
|
15
|
+
messages: [{ role: "user", content: "ping" }],
|
|
16
|
+
}),
|
|
17
|
+
}, params.timeoutMs, params.fetchFn);
|
|
18
|
+
if (res.ok) {
|
|
19
|
+
return { ok: true };
|
|
20
|
+
}
|
|
21
|
+
let errorCode;
|
|
22
|
+
let errorMessage;
|
|
23
|
+
try {
|
|
24
|
+
const json = (await res.json());
|
|
25
|
+
const code = json?.error?.code;
|
|
26
|
+
const msg = json?.error?.message ?? json?.msg ?? json?.message;
|
|
27
|
+
if (typeof code === "string") {
|
|
28
|
+
errorCode = code;
|
|
29
|
+
}
|
|
30
|
+
else if (typeof code === "number") {
|
|
31
|
+
errorCode = String(code);
|
|
32
|
+
}
|
|
33
|
+
if (typeof msg === "string") {
|
|
34
|
+
errorMessage = msg;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
// ignore
|
|
39
|
+
}
|
|
40
|
+
return { ok: false, status: res.status, errorCode, errorMessage };
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return { ok: false };
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
export async function detectZaiEndpoint(params) {
|
|
47
|
+
// Never auto-probe in vitest; it would create flaky network behavior.
|
|
48
|
+
if (process.env.VITEST && !params.fetchFn) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
const timeoutMs = params.timeoutMs ?? 5_000;
|
|
52
|
+
// Prefer GLM-5 on the general API endpoints.
|
|
53
|
+
const glm5 = [
|
|
54
|
+
{ endpoint: "global", baseUrl: ZAI_GLOBAL_BASE_URL },
|
|
55
|
+
{ endpoint: "cn", baseUrl: ZAI_CN_BASE_URL },
|
|
56
|
+
];
|
|
57
|
+
for (const candidate of glm5) {
|
|
58
|
+
const result = await probeZaiChatCompletions({
|
|
59
|
+
baseUrl: candidate.baseUrl,
|
|
60
|
+
apiKey: params.apiKey,
|
|
61
|
+
modelId: "glm-5",
|
|
62
|
+
timeoutMs,
|
|
63
|
+
fetchFn: params.fetchFn,
|
|
64
|
+
});
|
|
65
|
+
if (result.ok) {
|
|
66
|
+
return {
|
|
67
|
+
endpoint: candidate.endpoint,
|
|
68
|
+
baseUrl: candidate.baseUrl,
|
|
69
|
+
modelId: "glm-5",
|
|
70
|
+
note: `Verified GLM-5 on ${candidate.endpoint} endpoint.`,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Fallback: Coding Plan endpoint (GLM-5 not available there).
|
|
75
|
+
const coding = [
|
|
76
|
+
{ endpoint: "coding-global", baseUrl: ZAI_CODING_GLOBAL_BASE_URL },
|
|
77
|
+
{ endpoint: "coding-cn", baseUrl: ZAI_CODING_CN_BASE_URL },
|
|
78
|
+
];
|
|
79
|
+
for (const candidate of coding) {
|
|
80
|
+
const result = await probeZaiChatCompletions({
|
|
81
|
+
baseUrl: candidate.baseUrl,
|
|
82
|
+
apiKey: params.apiKey,
|
|
83
|
+
modelId: "glm-4.7",
|
|
84
|
+
timeoutMs,
|
|
85
|
+
fetchFn: params.fetchFn,
|
|
86
|
+
});
|
|
87
|
+
if (result.ok) {
|
|
88
|
+
return {
|
|
89
|
+
endpoint: candidate.endpoint,
|
|
90
|
+
baseUrl: candidate.baseUrl,
|
|
91
|
+
modelId: "glm-4.7",
|
|
92
|
+
note: "Coding Plan endpoint detected; GLM-5 is not available there. Defaulting to GLM-4.7.",
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
@@ -161,4 +161,61 @@ export const LEGACY_CONFIG_MIGRATIONS_PART_3 = [
|
|
|
161
161
|
delete raw.identity;
|
|
162
162
|
},
|
|
163
163
|
},
|
|
164
|
+
{
|
|
165
|
+
id: "gateway.bind-enum-fix",
|
|
166
|
+
describe: "Fix invalid gateway.bind values to 'auto'",
|
|
167
|
+
apply: (raw, changes) => {
|
|
168
|
+
const gateway = getRecord(raw.gateway);
|
|
169
|
+
if (!gateway)
|
|
170
|
+
return;
|
|
171
|
+
const bind = gateway.bind;
|
|
172
|
+
if (bind === undefined)
|
|
173
|
+
return;
|
|
174
|
+
const validBindValues = new Set(["auto", "lan", "loopback", "custom", "tailnet"]);
|
|
175
|
+
if (typeof bind !== "string" || !validBindValues.has(bind)) {
|
|
176
|
+
gateway.bind = "auto";
|
|
177
|
+
changes.push(`Fixed gateway.bind from ${JSON.stringify(bind)} → "auto".`);
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
id: "gateway.nodes.browser.mode-enum-fix",
|
|
183
|
+
describe: "Fix invalid gateway.nodes.browser.mode values to 'auto'",
|
|
184
|
+
apply: (raw, changes) => {
|
|
185
|
+
const gateway = getRecord(raw.gateway);
|
|
186
|
+
if (!gateway)
|
|
187
|
+
return;
|
|
188
|
+
const nodes = getRecord(gateway.nodes);
|
|
189
|
+
if (!nodes)
|
|
190
|
+
return;
|
|
191
|
+
const browser = getRecord(nodes.browser);
|
|
192
|
+
if (!browser)
|
|
193
|
+
return;
|
|
194
|
+
const mode = browser.mode;
|
|
195
|
+
if (mode === undefined)
|
|
196
|
+
return;
|
|
197
|
+
const validModes = new Set(["auto", "manual", "off"]);
|
|
198
|
+
if (typeof mode !== "string" || !validModes.has(mode)) {
|
|
199
|
+
browser.mode = "auto";
|
|
200
|
+
changes.push(`Fixed gateway.nodes.browser.mode from ${JSON.stringify(mode)} → "auto".`);
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
id: "gateway.mode-enum-fix",
|
|
206
|
+
describe: "Fix invalid gateway.mode values to 'local'",
|
|
207
|
+
apply: (raw, changes) => {
|
|
208
|
+
const gateway = getRecord(raw.gateway);
|
|
209
|
+
if (!gateway)
|
|
210
|
+
return;
|
|
211
|
+
const mode = gateway.mode;
|
|
212
|
+
if (mode === undefined)
|
|
213
|
+
return;
|
|
214
|
+
const validModes = new Set(["local", "remote"]);
|
|
215
|
+
if (typeof mode !== "string" || !validModes.has(mode)) {
|
|
216
|
+
gateway.mode = "local";
|
|
217
|
+
changes.push(`Fixed gateway.mode from ${JSON.stringify(mode)} → "local".`);
|
|
218
|
+
}
|
|
219
|
+
},
|
|
220
|
+
},
|
|
164
221
|
];
|
package/dist/terminal/theme.js
CHANGED
|
@@ -16,7 +16,7 @@ export const theme = {
|
|
|
16
16
|
muted: hex(POOLBOT_PALETTE.muted),
|
|
17
17
|
heading: baseChalk.bold.hex(POOLBOT_PALETTE.accent),
|
|
18
18
|
command: hex(POOLBOT_PALETTE.accentBright),
|
|
19
|
-
option: hex(POOLBOT_PALETTE.
|
|
19
|
+
option: hex(POOLBOT_PALETTE.info),
|
|
20
20
|
};
|
|
21
21
|
export const isRich = () => Boolean(baseChalk.level > 0);
|
|
22
22
|
export const colorize = (rich, color, value) => rich ? color(value) : value;
|