@tiens.nguyen/gu-cli 1.0.700 → 1.0.702
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/agent-model-command.mjs +50 -0
- package/gonext_agent_chat.py +11 -8
- package/gu-repl.mjs +40 -17
- package/package.json +1 -1
package/agent-model-command.mjs
CHANGED
|
@@ -416,3 +416,53 @@ export function describeNotOllama(host, role) {
|
|
|
416
416
|
"for an OpenAI-compatible coder use /model → add or change an OpenAI-compatible provider — or type 'no' to skip.",
|
|
417
417
|
];
|
|
418
418
|
}
|
|
419
|
+
|
|
420
|
+
// ---------------------------------------------------------------------------------------------
|
|
421
|
+
// #44 — WHAT TO CHANGE comes first.
|
|
422
|
+
// ---------------------------------------------------------------------------------------------
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* The first screen of /agent-model: what to change, before any model list.
|
|
426
|
+
*
|
|
427
|
+
* Reported (#44): client mode, agent on api.openai.com — /agent-model opened straight onto "130 on
|
|
428
|
+
* https://api.openai.com/v1" with the current model selected, and the ways to use an Ollama server
|
|
429
|
+
* or another provider sat after all 130 rows. Enter said "already using gpt-4.1-mini — nothing
|
|
430
|
+
* changed", and the only thing the screen seemed to allow was another OpenAI model. First-time setup
|
|
431
|
+
* worked; changing it afterwards did not look possible.
|
|
432
|
+
*
|
|
433
|
+
* So the choice of WHAT to change is its own short list, in the order it is most often wanted. The
|
|
434
|
+
* key entry appears only where a key applies. Returns [{ action, label }].
|
|
435
|
+
*/
|
|
436
|
+
export function agentMenuOptions({ host = "", modelCount = 0, needsKey = false } = {}) {
|
|
437
|
+
const where = host || "this server";
|
|
438
|
+
return [
|
|
439
|
+
{ action: "models", label: `pick another model on ${where}${modelCount ? ` (${modelCount})` : ""}` },
|
|
440
|
+
{ action: "ollama", label: "use an Ollama server for the agent…" },
|
|
441
|
+
{ action: "provider", label: "use another OpenAI-compatible provider…" },
|
|
442
|
+
...(needsKey ? [{ action: "key", label: `enter a new API key for ${where}…` }] : []),
|
|
443
|
+
];
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* The providers already saved on this machine that the agent could switch to — OpenAI-compatible
|
|
448
|
+
* rows, current one marked — then "add a new one". Switching to a provider you already set up must
|
|
449
|
+
* not mean typing its URL again. Returns [{ action: "row" | "add", row?, label }].
|
|
450
|
+
*/
|
|
451
|
+
export function agentProviderChoices(settings) {
|
|
452
|
+
const rows = Array.isArray(settings?.agentCodingBackends) ? settings.agentCodingBackends : [];
|
|
453
|
+
const current = ensureV1Root(String(settings?.agentModelUrl ?? "")).toLowerCase();
|
|
454
|
+
const out = [];
|
|
455
|
+
for (const row of rows) {
|
|
456
|
+
if (!row || row.kind !== "openai" || !row.url) continue;
|
|
457
|
+
let host = String(row.url);
|
|
458
|
+
try {
|
|
459
|
+
host = new URL(String(row.url)).host;
|
|
460
|
+
} catch {
|
|
461
|
+
/* keep the raw url */
|
|
462
|
+
}
|
|
463
|
+
const isCurrent = ensureV1Root(String(row.url)).toLowerCase() === current;
|
|
464
|
+
out.push({ action: "row", row, label: `${host}${isCurrent ? " (current)" : ""}` });
|
|
465
|
+
}
|
|
466
|
+
out.push({ action: "add", label: "add a new OpenAI-compatible provider…" });
|
|
467
|
+
return out;
|
|
468
|
+
}
|
package/gonext_agent_chat.py
CHANGED
|
@@ -9694,22 +9694,25 @@ def run_agent_chat(cfg):
|
|
|
9694
9694
|
f"{_host} refused: "
|
|
9695
9695
|
+ (_why or "the account is out of credit")
|
|
9696
9696
|
+ ". Nothing ran — top up the account, or switch the "
|
|
9697
|
-
"coding model in Settings → Agent."
|
|
9697
|
+
"coding model (in gu: /model; on the web: Settings → Agent)."
|
|
9698
9698
|
) from e
|
|
9699
|
+
# THE TERMINAL WAY FIRST (#44): a client-mode machine has no web app,
|
|
9700
|
+
# so "Settings → Agent" alone was advice it could not follow.
|
|
9699
9701
|
if coding_api_key:
|
|
9700
9702
|
raise _AgentConfigError(
|
|
9701
9703
|
f"The agent coding backend ({_host}) REJECTED the "
|
|
9702
|
-
"coding API key. Nothing ran.
|
|
9703
|
-
"
|
|
9704
|
-
"
|
|
9705
|
-
"save a fresh one
|
|
9704
|
+
"coding API key. Nothing ran. Enter a fresh key — in gu: "
|
|
9705
|
+
"press ctrl+k (or /model → the provider); on the web: "
|
|
9706
|
+
"Settings → Agent. The stored key is write-only, so a "
|
|
9707
|
+
"stale one can't be inspected — just save a fresh one."
|
|
9706
9708
|
) from e
|
|
9707
9709
|
raise _AgentConfigError(
|
|
9708
9710
|
f"The agent coding backend ({_host}) rejected the request: "
|
|
9709
9711
|
"NO coding API key was sent, so the local agent key was "
|
|
9710
|
-
"used instead. Enter the API key
|
|
9711
|
-
"
|
|
9712
|
-
"https://ollama.com URL —
|
|
9712
|
+
"used instead. Enter the API key for this coding backend — in "
|
|
9713
|
+
"gu: press ctrl+k; on the web: Settings → Agent "
|
|
9714
|
+
"(OpenAI-compatible, or Ollama with an https://ollama.com URL — "
|
|
9715
|
+
"local Ollama needs no key)."
|
|
9713
9716
|
) from e
|
|
9714
9717
|
if "404" in emsg and "not found" in emsg.lower():
|
|
9715
9718
|
# Probe with the CODING key when there is one: using the agent
|
package/gu-repl.mjs
CHANGED
|
@@ -6119,6 +6119,29 @@ async function pointAgentAtProvider(row, host) {
|
|
|
6119
6119
|
await saveAgentModel(url, model, host);
|
|
6120
6120
|
}
|
|
6121
6121
|
|
|
6122
|
+
/**
|
|
6123
|
+
* #44: switch the agent to a provider already saved on this machine, or add a new one.
|
|
6124
|
+
*/
|
|
6125
|
+
async function chooseAgentProvider() {
|
|
6126
|
+
const am = await import("./agent-model-command.mjs");
|
|
6127
|
+
const settings = await withPendingStatus("reading your providers", fetchWorkerSettings);
|
|
6128
|
+
if (!settings) {
|
|
6129
|
+
console.log(red(" couldn't reach the API to read your providers.\n"));
|
|
6130
|
+
return;
|
|
6131
|
+
}
|
|
6132
|
+
const choices = am.agentProviderChoices(settings);
|
|
6133
|
+
if (choices.length === 1) return addCodingProvider("agent");
|
|
6134
|
+
console.log(dim(` Which OpenAI-compatible provider should the agent use? (${PICK_HINT})`));
|
|
6135
|
+
const idx = await pickFromList(choices.map((c) => c.label), 0);
|
|
6136
|
+
if (idx < 0) {
|
|
6137
|
+
console.log(dim(" (cancelled)\n"));
|
|
6138
|
+
return;
|
|
6139
|
+
}
|
|
6140
|
+
const pick = choices[idx];
|
|
6141
|
+
if (pick.action === "add") return addCodingProvider("agent");
|
|
6142
|
+
await pointAgentAtProvider(pick.row, hostOf(String(pick.row.url ?? "")));
|
|
6143
|
+
}
|
|
6144
|
+
|
|
6122
6145
|
/**
|
|
6123
6146
|
* #41: the agent model on an OLLAMA server — this machine's, a LAN box, or the Ollama cloud.
|
|
6124
6147
|
*
|
|
@@ -6334,6 +6357,21 @@ async function chooseAgentModel() {
|
|
|
6334
6357
|
return;
|
|
6335
6358
|
}
|
|
6336
6359
|
|
|
6360
|
+
// WHAT TO CHANGE, FIRST (#44). The ways to use an Ollama server or another provider used to sit
|
|
6361
|
+
// after every model on this one — 130 rows down on api.openai.com — which read as "OpenAI models
|
|
6362
|
+
// are all you can choose". A short menu of what to change comes before any list.
|
|
6363
|
+
console.log(dim(` Agent model — the one that TALKS: ${current || "unset"} on ${listHost}`));
|
|
6364
|
+
const menu = am.agentMenuOptions({ host: listHost, modelCount: models.length, needsKey });
|
|
6365
|
+
const first = await pickFromList(menu.map((o) => o.label), 0);
|
|
6366
|
+
const firstAction = first >= 0 ? menu[first].action : "cancel";
|
|
6367
|
+
if (firstAction === "cancel") {
|
|
6368
|
+
console.log(dim(" (cancelled)\n"));
|
|
6369
|
+
return;
|
|
6370
|
+
}
|
|
6371
|
+
if (firstAction === "ollama") return addOllamaAgent();
|
|
6372
|
+
if (firstAction === "provider") return chooseAgentProvider();
|
|
6373
|
+
if (firstAction === "key") return enterAgentProviderKey(source.row, listHost);
|
|
6374
|
+
|
|
6337
6375
|
const rows = am.agentModelRows(models, current);
|
|
6338
6376
|
console.log(dim(` Agent model — the one that TALKS (currently ${current || "unset"})`));
|
|
6339
6377
|
// Strip whichever list endpoint was asked, so the header names the SERVER rather than the path.
|
|
@@ -6360,28 +6398,13 @@ async function chooseAgentModel() {
|
|
|
6360
6398
|
(r.current ? accent(" (current)") : "")
|
|
6361
6399
|
);
|
|
6362
6400
|
});
|
|
6363
|
-
//
|
|
6364
|
-
//
|
|
6365
|
-
// because "which model on the box I am pointed at" and "I want a different provider" are
|
|
6366
|
-
// different questions, and only the first is answered by the rows above.
|
|
6367
|
-
labels.push("add an OpenAI-compatible provider for the agent…");
|
|
6368
|
-
// #41, appended AFTER the provider entry so no existing index moves.
|
|
6369
|
-
labels.push("use an Ollama server for the agent…");
|
|
6401
|
+
// No other entries here any more (#44): the ways to change the provider are on the menu above,
|
|
6402
|
+
// where they can be seen, rather than after every model.
|
|
6370
6403
|
const idx = await pickFromList(labels, Math.max(0, rows.findIndex((r) => r.current)));
|
|
6371
6404
|
if (idx < 0) {
|
|
6372
6405
|
console.log(dim(" (cancelled)\n"));
|
|
6373
6406
|
return;
|
|
6374
6407
|
}
|
|
6375
|
-
// labels is now TWO LONGER than rows. Reading rows[idx] for an appended entry would
|
|
6376
|
-
// dereference undefined and take the picker down, so they are answered before rows is touched.
|
|
6377
|
-
if (idx === rows.length) {
|
|
6378
|
-
await addCodingProvider("agent");
|
|
6379
|
-
return;
|
|
6380
|
-
}
|
|
6381
|
-
if (idx === rows.length + 1) {
|
|
6382
|
-
await addOllamaAgent();
|
|
6383
|
-
return;
|
|
6384
|
-
}
|
|
6385
6408
|
const chosen = rows[idx].model;
|
|
6386
6409
|
if (chosen === current) {
|
|
6387
6410
|
console.log(dim(` already using ${current} — nothing changed.\n`));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tiens.nguyen/gu-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.702",
|
|
4
4
|
"description": "Gu CLI — the gu terminal plus the local worker that runs agent / OCR / PDF / embedding jobs on your Mac (Ollama / MLX / OpenAI-compatible).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|