@vtstech/pi-api 1.1.7 → 1.1.9
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/api.js +156 -129
- package/package.json +2 -2
package/api.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
// .build-npm/api/api.temp.ts
|
|
2
|
-
import * as fs from "node:fs";
|
|
3
|
-
import * as path from "node:path";
|
|
4
|
-
import os from "node:os";
|
|
5
2
|
import { section, ok, info, warn } from "@vtstech/pi-shared/format";
|
|
6
|
-
import { readModelsJson,
|
|
3
|
+
import { readModelsJson, readModifyWriteModelsJson, getOllamaBaseUrl, BUILTIN_PROVIDERS, EXTENSION_VERSION, isLocalProvider } from "@vtstech/pi-shared/ollama";
|
|
4
|
+
import { SETTINGS_PATH, readSettings, writeSettings } from "@vtstech/pi-shared/config-io";
|
|
7
5
|
var API_MODES = {
|
|
8
6
|
"anthropic-messages": "Anthropic Claude API and compatibles",
|
|
9
7
|
"openai-completions": "OpenAI Chat Completions API and compatibles",
|
|
@@ -38,36 +36,33 @@ var COMPAT_FLAGS = {
|
|
|
38
36
|
values: ["qwen", "deepseek", "default"]
|
|
39
37
|
}
|
|
40
38
|
};
|
|
41
|
-
var SETTINGS_PATH = path.join(os.homedir(), ".pi", "agent", "settings.json");
|
|
42
|
-
function readSettings() {
|
|
43
|
-
try {
|
|
44
|
-
if (fs.existsSync(SETTINGS_PATH)) {
|
|
45
|
-
return JSON.parse(fs.readFileSync(SETTINGS_PATH, "utf-8"));
|
|
46
|
-
}
|
|
47
|
-
} catch {
|
|
48
|
-
}
|
|
49
|
-
return {};
|
|
50
|
-
}
|
|
51
|
-
function writeSettings(data) {
|
|
52
|
-
const dir = path.dirname(SETTINGS_PATH);
|
|
53
|
-
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
54
|
-
fs.writeFileSync(SETTINGS_PATH, JSON.stringify(data, null, 2) + "\n", "utf-8");
|
|
55
|
-
}
|
|
56
39
|
function getLocalProvider(config) {
|
|
57
40
|
for (const [name, provider] of Object.entries(config.providers)) {
|
|
58
|
-
|
|
59
|
-
if (url.includes("localhost") || url.includes("127.0.0.1") || url.includes("0.0.0.0") || name === "ollama") {
|
|
41
|
+
if (isLocalProvider(provider.baseUrl || "", name)) {
|
|
60
42
|
return { name, isLocal: true };
|
|
61
43
|
}
|
|
62
44
|
}
|
|
63
45
|
const first = Object.keys(config.providers)[0];
|
|
64
46
|
return { name: first || "ollama", isLocal: false };
|
|
65
47
|
}
|
|
66
|
-
function
|
|
67
|
-
const
|
|
68
|
-
const provider = config.providers[
|
|
48
|
+
function findProvider(providerName) {
|
|
49
|
+
const config = readModelsJson();
|
|
50
|
+
const provider = config.providers[providerName];
|
|
51
|
+
return provider || null;
|
|
52
|
+
}
|
|
53
|
+
function resolveProvider(config, explicit, currentProvider) {
|
|
54
|
+
if (explicit) {
|
|
55
|
+
const provider2 = config.providers[explicit];
|
|
56
|
+
if (!provider2) return null;
|
|
57
|
+
return { name: explicit, config: provider2 };
|
|
58
|
+
}
|
|
59
|
+
if (currentProvider && config.providers[currentProvider]) {
|
|
60
|
+
return { name: currentProvider, config: config.providers[currentProvider] };
|
|
61
|
+
}
|
|
62
|
+
const local = getLocalProvider(config);
|
|
63
|
+
const provider = config.providers[local.name];
|
|
69
64
|
if (!provider) return null;
|
|
70
|
-
return { name:
|
|
65
|
+
return { name: local.name, config: provider };
|
|
71
66
|
}
|
|
72
67
|
function api_temp_default(pi) {
|
|
73
68
|
const branding = [
|
|
@@ -78,50 +73,52 @@ function api_temp_default(pi) {
|
|
|
78
73
|
].join("\n");
|
|
79
74
|
pi.registerCommand("api", {
|
|
80
75
|
description: "View and switch API modes, base URLs, thinking, and compat flags",
|
|
81
|
-
handler: async (args,
|
|
76
|
+
handler: async (args, ctx2) => {
|
|
82
77
|
const parts = args.trim().split(/\s+/);
|
|
83
78
|
const sub = parts[0]?.toLowerCase() || "";
|
|
84
79
|
const rest = parts.slice(1).join(" ");
|
|
85
80
|
const config = readModelsJson();
|
|
86
81
|
if (sub !== "provider" && sub !== "providers") {
|
|
87
|
-
const
|
|
82
|
+
const currentProvider = getCurrentSessionProvider(ctx2);
|
|
83
|
+
const provider = resolveProvider(config, void 0, currentProvider);
|
|
88
84
|
if (!provider) {
|
|
89
|
-
|
|
85
|
+
ctx2.ui.notify("No providers found in models.json", "error");
|
|
90
86
|
return;
|
|
91
87
|
}
|
|
92
88
|
switch (sub) {
|
|
93
89
|
case "":
|
|
94
90
|
case "show":
|
|
95
|
-
return showConfig(provider);
|
|
91
|
+
return showConfig(provider, currentProvider);
|
|
96
92
|
case "mode":
|
|
97
|
-
return setMode(
|
|
93
|
+
return setMode(ctx2, provider.name, rest);
|
|
98
94
|
case "url":
|
|
99
|
-
return setUrl(
|
|
95
|
+
return setUrl(ctx2, provider.name, rest);
|
|
100
96
|
case "think":
|
|
101
|
-
return setThink(
|
|
97
|
+
return setThink(ctx2, provider.name, rest);
|
|
102
98
|
case "compat":
|
|
103
|
-
return handleCompat(
|
|
99
|
+
return handleCompat(ctx2, provider.name, rest);
|
|
104
100
|
case "reload":
|
|
105
|
-
return reloadConfig(
|
|
101
|
+
return reloadConfig(ctx2);
|
|
106
102
|
case "modes":
|
|
107
103
|
return listModes();
|
|
108
104
|
default:
|
|
109
|
-
|
|
105
|
+
ctx2.ui.notify(`Unknown sub-command: "${sub}". Use: mode, url, think, compat, reload, modes, provider, providers`, "error");
|
|
110
106
|
}
|
|
111
107
|
}
|
|
112
108
|
if (sub === "provider" || sub === "providers") {
|
|
113
|
-
return handleProvider(
|
|
109
|
+
return handleProvider(ctx2, config, rest);
|
|
114
110
|
}
|
|
115
111
|
}
|
|
116
112
|
});
|
|
117
|
-
function showConfig(provider) {
|
|
113
|
+
function showConfig(provider, currentProvider) {
|
|
118
114
|
const p = provider.config;
|
|
119
115
|
const compat = p.compat || {};
|
|
120
116
|
const modelCount = p.models?.length || 0;
|
|
121
117
|
const firstModel = p.models?.[0]?.id || "none";
|
|
118
|
+
const isCurrent = currentProvider === provider.name;
|
|
122
119
|
const lines = [branding];
|
|
123
120
|
lines.push(section("CURRENT PROVIDER CONFIG"));
|
|
124
|
-
lines.push(info(`Provider: ${provider.name}`));
|
|
121
|
+
lines.push(info(`Provider: ${provider.name}${isCurrent ? " \u25C0 current" : ""}`));
|
|
125
122
|
lines.push(info(`API mode: ${p.api || "(not set)"}`));
|
|
126
123
|
lines.push(info(`Base URL: ${p.baseUrl || "(not set)"}`));
|
|
127
124
|
lines.push(info(`API key: ${p.apiKey ? "\u2022\u2022\u2022\u2022" + String(p.apiKey).slice(-4) : "(not set)"}`));
|
|
@@ -136,15 +133,20 @@ function api_temp_default(pi) {
|
|
|
136
133
|
lines.push(section("RESOLVED"));
|
|
137
134
|
lines.push(info(`Ollama base: ${ollamaBase}`));
|
|
138
135
|
lines.push(info(`(strip /v1 \u2192 ${ollamaBase})`));
|
|
136
|
+
if (currentProvider && currentProvider !== provider.name) {
|
|
137
|
+
lines.push(section("NOTE"));
|
|
138
|
+
lines.push(info(`Current session is using: ${currentProvider}`));
|
|
139
|
+
lines.push(info(`Use /api provider set ${provider.name} to switch to this provider`));
|
|
140
|
+
}
|
|
139
141
|
pi.sendMessage({
|
|
140
142
|
customType: "api-config",
|
|
141
143
|
content: lines.join("\n"),
|
|
142
144
|
display: { type: "content", content: lines.join("\n") }
|
|
143
145
|
});
|
|
144
146
|
}
|
|
145
|
-
function setMode(
|
|
147
|
+
async function setMode(ctx2, providerName, mode) {
|
|
146
148
|
if (!mode) {
|
|
147
|
-
|
|
149
|
+
ctx2.ui.notify("Usage: /api mode <mode>. Use /api modes to list available modes.", "error");
|
|
148
150
|
return;
|
|
149
151
|
}
|
|
150
152
|
const modeLower = mode.toLowerCase();
|
|
@@ -153,18 +155,21 @@ function api_temp_default(pi) {
|
|
|
153
155
|
matched = Object.keys(API_MODES).find((m) => m.includes(modeLower));
|
|
154
156
|
}
|
|
155
157
|
if (!matched) {
|
|
156
|
-
|
|
158
|
+
ctx2.ui.notify(`Unknown API mode: "${mode}". Use /api modes to list available modes.`, "error");
|
|
157
159
|
return;
|
|
158
160
|
}
|
|
159
|
-
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
161
|
+
let oldMode = "(not set)";
|
|
162
|
+
const written = await readModifyWriteModelsJson((config) => {
|
|
163
|
+
const provider = config.providers[providerName];
|
|
164
|
+
if (!provider) return null;
|
|
165
|
+
oldMode = provider.api || "(not set)";
|
|
166
|
+
provider.api = matched;
|
|
167
|
+
return config;
|
|
168
|
+
});
|
|
169
|
+
if (!written) {
|
|
170
|
+
ctx2.ui.notify(`Provider "${providerName}" not found in models.json`, "error");
|
|
163
171
|
return;
|
|
164
172
|
}
|
|
165
|
-
const oldMode = provider.api || "(not set)";
|
|
166
|
-
provider.api = matched;
|
|
167
|
-
writeModelsJson(config);
|
|
168
173
|
const lines = [branding];
|
|
169
174
|
lines.push(section("API MODE CHANGED"));
|
|
170
175
|
lines.push(ok(`Provider: ${providerName}`));
|
|
@@ -177,11 +182,11 @@ function api_temp_default(pi) {
|
|
|
177
182
|
content: lines.join("\n"),
|
|
178
183
|
display: { type: "content", content: lines.join("\n") }
|
|
179
184
|
});
|
|
180
|
-
|
|
185
|
+
ctx2.ui.notify(`API mode set to ${matched}`, "success");
|
|
181
186
|
}
|
|
182
|
-
function setUrl(
|
|
187
|
+
async function setUrl(ctx2, providerName, url) {
|
|
183
188
|
if (!url) {
|
|
184
|
-
|
|
189
|
+
ctx2.ui.notify("Usage: /api url <base-url>", "error");
|
|
185
190
|
return;
|
|
186
191
|
}
|
|
187
192
|
let normalizedUrl = url.trim();
|
|
@@ -191,22 +196,25 @@ function api_temp_default(pi) {
|
|
|
191
196
|
try {
|
|
192
197
|
new URL(normalizedUrl);
|
|
193
198
|
} catch {
|
|
194
|
-
|
|
199
|
+
ctx2.ui.notify(`Invalid URL: "${url}"`, "error");
|
|
195
200
|
return;
|
|
196
201
|
}
|
|
197
|
-
|
|
198
|
-
const
|
|
199
|
-
|
|
200
|
-
|
|
202
|
+
let oldUrl = "(not set)";
|
|
203
|
+
const written = await readModifyWriteModelsJson((config) => {
|
|
204
|
+
const provider = config.providers[providerName];
|
|
205
|
+
if (!provider) return null;
|
|
206
|
+
const apiMode = provider.api || "";
|
|
207
|
+
if (apiMode.includes("openai") && !normalizedUrl.endsWith("/v1")) {
|
|
208
|
+
normalizedUrl = normalizedUrl.replace(/\/+$/, "") + "/v1";
|
|
209
|
+
}
|
|
210
|
+
oldUrl = provider.baseUrl || "(not set)";
|
|
211
|
+
provider.baseUrl = normalizedUrl;
|
|
212
|
+
return config;
|
|
213
|
+
});
|
|
214
|
+
if (!written) {
|
|
215
|
+
ctx2.ui.notify(`Provider "${providerName}" not found in models.json`, "error");
|
|
201
216
|
return;
|
|
202
217
|
}
|
|
203
|
-
const apiMode = provider.api || "";
|
|
204
|
-
if (apiMode.includes("openai") && !normalizedUrl.endsWith("/v1")) {
|
|
205
|
-
normalizedUrl = normalizedUrl.replace(/\/+$/, "") + "/v1";
|
|
206
|
-
}
|
|
207
|
-
const oldUrl = provider.baseUrl || "(not set)";
|
|
208
|
-
provider.baseUrl = normalizedUrl;
|
|
209
|
-
writeModelsJson(config);
|
|
210
218
|
const lines = [branding];
|
|
211
219
|
lines.push(section("BASE URL CHANGED"));
|
|
212
220
|
lines.push(ok(`Provider: ${providerName}`));
|
|
@@ -218,46 +226,49 @@ function api_temp_default(pi) {
|
|
|
218
226
|
content: lines.join("\n"),
|
|
219
227
|
display: { type: "content", content: lines.join("\n") }
|
|
220
228
|
});
|
|
221
|
-
|
|
229
|
+
ctx2.ui.notify(`Base URL set to ${normalizedUrl}`, "success");
|
|
222
230
|
}
|
|
223
|
-
function setThink(
|
|
231
|
+
async function setThink(ctx2, providerName, value) {
|
|
224
232
|
if (!value) {
|
|
225
|
-
|
|
226
|
-
return;
|
|
227
|
-
}
|
|
228
|
-
const config = readModelsJson();
|
|
229
|
-
const provider = config.providers[providerName];
|
|
230
|
-
if (!provider) {
|
|
231
|
-
ctx.ui.notify(`Provider "${providerName}" not found in models.json`, "error");
|
|
232
|
-
return;
|
|
233
|
-
}
|
|
234
|
-
const models = provider.models || [];
|
|
235
|
-
if (models.length === 0) {
|
|
236
|
-
ctx.ui.notify(`No models found in provider "${providerName}"`, "error");
|
|
233
|
+
ctx2.ui.notify("Usage: /api think <on|off|auto>", "error");
|
|
237
234
|
return;
|
|
238
235
|
}
|
|
239
236
|
const valLower = value.toLowerCase();
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
237
|
+
let models = [];
|
|
238
|
+
const written = await readModifyWriteModelsJson((config) => {
|
|
239
|
+
const provider = config.providers[providerName];
|
|
240
|
+
if (!provider) return null;
|
|
241
|
+
models = provider.models || [];
|
|
242
|
+
if (models.length === 0) return null;
|
|
243
|
+
const setAll = (state) => {
|
|
244
|
+
for (const model of models) {
|
|
245
|
+
if (state === null) {
|
|
246
|
+
const name = (model.id || "").toLowerCase();
|
|
247
|
+
model.reasoning = name.includes("deepseek-r1") || name.includes("qwq") || name.includes("o1") || name.includes("o3") || name.includes("think") || name.includes("qwen3") || name.includes("glm-4");
|
|
248
|
+
} else {
|
|
249
|
+
model.reasoning = state;
|
|
250
|
+
}
|
|
247
251
|
}
|
|
252
|
+
};
|
|
253
|
+
if (valLower === "on" || valLower === "true" || valLower === "1") {
|
|
254
|
+
setAll(true);
|
|
255
|
+
} else if (valLower === "off" || valLower === "false" || valLower === "0") {
|
|
256
|
+
setAll(false);
|
|
257
|
+
} else if (valLower === "auto") {
|
|
258
|
+
setAll(null);
|
|
259
|
+
} else {
|
|
260
|
+
return null;
|
|
248
261
|
}
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
ctx.ui.notify("Invalid value. Use: on, off, or auto", "error");
|
|
262
|
+
return config;
|
|
263
|
+
});
|
|
264
|
+
if (!written) {
|
|
265
|
+
ctx2.ui.notify(`Provider "${providerName}" not found in models.json`, "error");
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
if (models.length === 0) {
|
|
269
|
+
ctx2.ui.notify(`No models found in provider "${providerName}"`, "error");
|
|
258
270
|
return;
|
|
259
271
|
}
|
|
260
|
-
writeModelsJson(config);
|
|
261
272
|
const lines = [branding];
|
|
262
273
|
lines.push(section("THINKING MODE"));
|
|
263
274
|
lines.push(info(`Provider: ${providerName}`));
|
|
@@ -272,20 +283,19 @@ function api_temp_default(pi) {
|
|
|
272
283
|
content: lines.join("\n"),
|
|
273
284
|
display: { type: "content", content: lines.join("\n") }
|
|
274
285
|
});
|
|
275
|
-
|
|
286
|
+
ctx2.ui.notify(`Thinking set to ${valLower} for ${models.length} model(s)`, "success");
|
|
276
287
|
}
|
|
277
|
-
function handleCompat(
|
|
288
|
+
async function handleCompat(ctx2, providerName, args) {
|
|
278
289
|
const parts = args.split(/\s+/);
|
|
279
290
|
const key = parts[0];
|
|
280
291
|
const value = parts.slice(1).join(" ");
|
|
281
292
|
if (!key) {
|
|
282
|
-
const
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
ctx.ui.notify(`Provider "${providerName}" not found`, "error");
|
|
293
|
+
const provider = findProvider(providerName);
|
|
294
|
+
if (!provider) {
|
|
295
|
+
ctx2.ui.notify(`Provider "${providerName}" not found`, "error");
|
|
286
296
|
return;
|
|
287
297
|
}
|
|
288
|
-
const compat =
|
|
298
|
+
const compat = provider.compat || {};
|
|
289
299
|
const lines2 = [branding];
|
|
290
300
|
lines2.push(section("COMPAT FLAGS"));
|
|
291
301
|
if (Object.keys(compat).length === 0) {
|
|
@@ -309,23 +319,15 @@ function api_temp_default(pi) {
|
|
|
309
319
|
return;
|
|
310
320
|
}
|
|
311
321
|
if (!value) {
|
|
312
|
-
const
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
ctx.ui.notify(`Provider "${providerName}" not found`, "error");
|
|
322
|
+
const provider = findProvider(providerName);
|
|
323
|
+
if (!provider) {
|
|
324
|
+
ctx2.ui.notify(`Provider "${providerName}" not found`, "error");
|
|
316
325
|
return;
|
|
317
326
|
}
|
|
318
|
-
const current =
|
|
319
|
-
|
|
327
|
+
const current = provider.compat?.[key];
|
|
328
|
+
ctx2.ui.notify(`${key} = ${current !== void 0 ? JSON.stringify(current) : "(not set)"}`, "info");
|
|
320
329
|
return;
|
|
321
330
|
}
|
|
322
|
-
const config = readModelsJson();
|
|
323
|
-
const provider = config.providers[providerName];
|
|
324
|
-
if (!provider) {
|
|
325
|
-
ctx.ui.notify(`Provider "${providerName}" not found`, "error");
|
|
326
|
-
return;
|
|
327
|
-
}
|
|
328
|
-
if (!provider.compat) provider.compat = {};
|
|
329
331
|
let parsedValue = value;
|
|
330
332
|
if (value === "true") parsedValue = true;
|
|
331
333
|
else if (value === "false") parsedValue = false;
|
|
@@ -336,9 +338,19 @@ function api_temp_default(pi) {
|
|
|
336
338
|
} catch {
|
|
337
339
|
}
|
|
338
340
|
}
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
341
|
+
let oldValue;
|
|
342
|
+
const written = await readModifyWriteModelsJson((config) => {
|
|
343
|
+
const provider = config.providers[providerName];
|
|
344
|
+
if (!provider) return null;
|
|
345
|
+
if (!provider.compat) provider.compat = {};
|
|
346
|
+
oldValue = provider.compat[key];
|
|
347
|
+
provider.compat[key] = parsedValue;
|
|
348
|
+
return config;
|
|
349
|
+
});
|
|
350
|
+
if (!written) {
|
|
351
|
+
ctx2.ui.notify(`Provider "${providerName}" not found`, "error");
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
342
354
|
const lines = [branding];
|
|
343
355
|
lines.push(section("COMPAT FLAG SET"));
|
|
344
356
|
lines.push(ok(`Provider: ${providerName}`));
|
|
@@ -351,9 +363,9 @@ function api_temp_default(pi) {
|
|
|
351
363
|
content: lines.join("\n"),
|
|
352
364
|
display: { type: "content", content: lines.join("\n") }
|
|
353
365
|
});
|
|
354
|
-
|
|
366
|
+
ctx2.ui.notify(`Compat flag ${key} set to ${JSON.stringify(parsedValue)}`, "success");
|
|
355
367
|
}
|
|
356
|
-
function reloadConfig(
|
|
368
|
+
function reloadConfig(ctx2) {
|
|
357
369
|
const lines = [branding];
|
|
358
370
|
lines.push(section("RELOAD"));
|
|
359
371
|
lines.push(ok("models.json has been modified"));
|
|
@@ -365,13 +377,14 @@ function api_temp_default(pi) {
|
|
|
365
377
|
content: lines.join("\n"),
|
|
366
378
|
display: { type: "content", content: lines.join("\n") }
|
|
367
379
|
});
|
|
368
|
-
|
|
380
|
+
ctx2.ui.notify("Run /reload to apply models.json changes", "info");
|
|
369
381
|
}
|
|
370
382
|
function listModes() {
|
|
371
383
|
const lines = [branding];
|
|
372
384
|
lines.push(section("SUPPORTED API MODES"));
|
|
373
385
|
const config = readModelsJson();
|
|
374
|
-
const
|
|
386
|
+
const currentProvider = getCurrentSessionProvider(ctx);
|
|
387
|
+
const provider = resolveProvider(config, void 0, currentProvider);
|
|
375
388
|
const currentMode = provider?.config?.api || "(not set)";
|
|
376
389
|
for (const [mode, description] of Object.entries(API_MODES)) {
|
|
377
390
|
const isActive = mode === currentMode;
|
|
@@ -386,7 +399,7 @@ function api_temp_default(pi) {
|
|
|
386
399
|
display: { type: "content", content: lines.join("\n") }
|
|
387
400
|
});
|
|
388
401
|
}
|
|
389
|
-
function handleProvider(
|
|
402
|
+
function handleProvider(ctx2, config, arg) {
|
|
390
403
|
const parts = arg.trim().split(/\s+/);
|
|
391
404
|
const sub = parts[0]?.toLowerCase() || "";
|
|
392
405
|
const rest = parts.slice(1).join(" ");
|
|
@@ -410,7 +423,7 @@ function api_temp_default(pi) {
|
|
|
410
423
|
const url = p.baseUrl || "(no URL)";
|
|
411
424
|
const api = p.api || "(no mode)";
|
|
412
425
|
const isDefault = name === defaultProvider;
|
|
413
|
-
const isLocal =
|
|
426
|
+
const isLocal = isLocalProvider(url, name);
|
|
414
427
|
const marker = isDefault ? ok(" \u25C0 default") : "";
|
|
415
428
|
const tag = isLocal ? " (local)" : " (cloud)";
|
|
416
429
|
lines.push(info(` ${name}${tag}${marker}`));
|
|
@@ -455,7 +468,7 @@ function api_temp_default(pi) {
|
|
|
455
468
|
lines2.push(info("Configured providers:"));
|
|
456
469
|
for (const name of providerNames) {
|
|
457
470
|
const p = config.providers[name];
|
|
458
|
-
const isLocal = (p.baseUrl || ""
|
|
471
|
+
const isLocal = isLocalProvider(p.baseUrl || "", name);
|
|
459
472
|
lines2.push(info(` ${name}${isLocal ? " (local)" : " (cloud)"}`));
|
|
460
473
|
}
|
|
461
474
|
const builtins = Object.keys(BUILTIN_PROVIDERS).filter((n) => !providerNames.includes(n));
|
|
@@ -470,13 +483,13 @@ function api_temp_default(pi) {
|
|
|
470
483
|
content: lines2.join("\n"),
|
|
471
484
|
display: { type: "content", content: lines2.join("\n") }
|
|
472
485
|
});
|
|
473
|
-
|
|
486
|
+
ctx2.ui.notify("Specify a provider name: /api provider set <name>", "info");
|
|
474
487
|
return;
|
|
475
488
|
}
|
|
476
489
|
const isBuiltin = targetName in BUILTIN_PROVIDERS;
|
|
477
490
|
if (!config.providers[targetName] && !isBuiltin) {
|
|
478
491
|
const allNames = [...providerNames, ...Object.keys(BUILTIN_PROVIDERS).filter((n) => !providerNames.includes(n))];
|
|
479
|
-
|
|
492
|
+
ctx2.ui.notify(`Provider "${targetName}" not found. Available: ${allNames.join(", ")}`, "error");
|
|
480
493
|
return;
|
|
481
494
|
}
|
|
482
495
|
const settings = readSettings();
|
|
@@ -508,13 +521,27 @@ function api_temp_default(pi) {
|
|
|
508
521
|
content: lines.join("\n"),
|
|
509
522
|
display: { type: "content", content: lines.join("\n") }
|
|
510
523
|
});
|
|
511
|
-
|
|
524
|
+
ctx2.ui.notify(`Default provider set to ${targetName}`, "success");
|
|
512
525
|
return;
|
|
513
526
|
}
|
|
514
527
|
if (providerNames.includes(sub) || sub in BUILTIN_PROVIDERS) {
|
|
515
|
-
return handleProvider(
|
|
528
|
+
return handleProvider(ctx2, config, `set ${sub}`);
|
|
529
|
+
}
|
|
530
|
+
ctx2.ui.notify(`Unknown sub-command: "${sub}". Use: show, set, list, or a provider name`, "error");
|
|
531
|
+
}
|
|
532
|
+
function getCurrentSessionProvider(ctx2) {
|
|
533
|
+
if (ctx2.session?.state?.provider) {
|
|
534
|
+
return ctx2.session.state.provider;
|
|
535
|
+
}
|
|
536
|
+
if (ctx2.state?.provider) {
|
|
537
|
+
return ctx2.state.provider;
|
|
538
|
+
}
|
|
539
|
+
try {
|
|
540
|
+
const settings = readSettings();
|
|
541
|
+
return settings.defaultProvider;
|
|
542
|
+
} catch {
|
|
543
|
+
return void 0;
|
|
516
544
|
}
|
|
517
|
-
ctx.ui.notify(`Unknown sub-command: "${sub}". Use: show, set, list, or a provider name`, "error");
|
|
518
545
|
}
|
|
519
546
|
pi.registerCompletion?.("api", {
|
|
520
547
|
getCompletions: () => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vtstech/pi-api",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.9",
|
|
4
4
|
"description": "API Mode Switcher extension for Pi Coding Agent",
|
|
5
5
|
"main": "api.js",
|
|
6
6
|
"keywords": ["pi-extensions"],
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"url": "https://github.com/VTSTech/pi-coding-agent"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@vtstech/pi-shared": "1.1.
|
|
17
|
+
"@vtstech/pi-shared": "1.1.9"
|
|
18
18
|
},
|
|
19
19
|
"peerDependencies": {
|
|
20
20
|
"@mariozechner/pi-coding-agent": ">=0.66"
|