@proagentstore/cli 0.4.160 → 0.4.161
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.
|
@@ -123,3 +123,43 @@ export function checkEngine(input, deps = {}) {
|
|
|
123
123
|
...(engine === "grok" && binaryPath ? { vendor: grokVendor(versionText, (deps.realpath ?? safeRealpath)(binaryPath)) } : {}),
|
|
124
124
|
};
|
|
125
125
|
}
|
|
126
|
+
/** `grok models` → its ids and default; null when the output has no model list in it. */
|
|
127
|
+
export function parseGrokModels(text) {
|
|
128
|
+
const lines = text.split(/\r?\n/);
|
|
129
|
+
const start = lines.findIndex((l) => /^\s*Available models:\s*$/i.test(l));
|
|
130
|
+
if (start < 0)
|
|
131
|
+
return null;
|
|
132
|
+
const models = [];
|
|
133
|
+
for (const line of lines.slice(start + 1)) {
|
|
134
|
+
const m = /^\s*[*-]\s+(\S+)/.exec(line);
|
|
135
|
+
if (m)
|
|
136
|
+
models.push(m[1]);
|
|
137
|
+
else if (line.trim())
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
if (!models.length)
|
|
141
|
+
return null;
|
|
142
|
+
const named = /^\s*Default model:\s*(\S+)/im.exec(text)?.[1] ?? null;
|
|
143
|
+
const starred = lines.slice(start + 1).find((l) => /^\s*\*\s+/.test(l))?.trim().split(/\s+/)[1] ?? null;
|
|
144
|
+
return { models, defaultModel: named ?? starred };
|
|
145
|
+
}
|
|
146
|
+
export function listEngineModels(input, deps = {}) {
|
|
147
|
+
const engine = (["claude", "gemini", "codex", "grok", "generic"].includes(input.clientType ?? "") ? input.clientType : "claude");
|
|
148
|
+
if (engine !== "grok")
|
|
149
|
+
return { clientType: engine, models: null, defaultModel: null, reason: `the ${engine} CLI publishes no model list` };
|
|
150
|
+
const command = parseCommand(input.command);
|
|
151
|
+
const bin = unwrapLauncher(command.bin, command.args).bin || "grok";
|
|
152
|
+
const launch = resolveEngineSpawn(bin, ["models"], deps);
|
|
153
|
+
if (!launch.binaryPath)
|
|
154
|
+
return { clientType: engine, models: null, defaultModel: null, reason: "grok is not installed on this machine" };
|
|
155
|
+
const text = (deps.listText ?? defaultListText)(launch, deps.env ?? process.env);
|
|
156
|
+
const parsed = text ? parseGrokModels(text) : null;
|
|
157
|
+
if (!parsed)
|
|
158
|
+
return { clientType: engine, models: null, defaultModel: null, reason: "`grok models` gave no model list (is the CLI signed in?)" };
|
|
159
|
+
return { clientType: engine, ...parsed };
|
|
160
|
+
}
|
|
161
|
+
function defaultListText(launch, env) {
|
|
162
|
+
const command = launch.via === "direct" && launch.binaryPath ? launch.binaryPath : launch.command;
|
|
163
|
+
const r = spawnSync(command, launch.args, { encoding: "utf8", env, timeout: 20_000, windowsHide: true, windowsVerbatimArguments: launch.windowsVerbatimArguments });
|
|
164
|
+
return r.error || r.status !== 0 ? null : `${r.stdout ?? ""}${r.stderr ?? ""}`;
|
|
165
|
+
}
|
|
@@ -5,7 +5,7 @@ import { URL } from "node:url";
|
|
|
5
5
|
import { recordRequestFailure } from "./request-failure.js";
|
|
6
6
|
import { LocalRunner, RunnerInputError } from "./runner.js";
|
|
7
7
|
import { probeGitSshIdentity } from "./coding/repo.js";
|
|
8
|
-
import { checkEngine } from "./coding/engine-check.js";
|
|
8
|
+
import { checkEngine, listEngineModels } from "./coding/engine-check.js";
|
|
9
9
|
import { listGithubOrgs, listGithubRepos, searchGithubRepos, getGithubRepoDetail, getGithubCredentialScope } from "./coding/github-browse.js";
|
|
10
10
|
import { routeLocalApplyHandoff } from "./local-apply/handoff-routes.js";
|
|
11
11
|
import { runNativePreflight } from "./native/preflight.js";
|
|
@@ -552,10 +552,10 @@ async function route(runner, req, res) {
|
|
|
552
552
|
// Can this machine run an engine — its binary on PATH, its subscription login stored (#879)? Asked
|
|
553
553
|
// BEFORE a session is launched, so a missing engine is a named refusal rather than a dead pane.
|
|
554
554
|
// An older runner 404s this, and the cloud reads that as "unverified", never as "missing".
|
|
555
|
-
if (req.method === "POST" && path === "/coding/engine-check") {
|
|
555
|
+
if (req.method === "POST" && (path === "/coding/engine-check" || path === "/coding/engine-models")) {
|
|
556
556
|
const b = await readJson(req);
|
|
557
557
|
try {
|
|
558
|
-
return json(res, 200, checkEngine(b));
|
|
558
|
+
return json(res, 200, path === "/coding/engine-models" ? listEngineModels(b) : checkEngine(b)); // #1199: the CLI's live model list
|
|
559
559
|
}
|
|
560
560
|
catch (e) {
|
|
561
561
|
return json(res, 400, { error: e instanceof Error ? e.message : String(e) });
|