@jini-ai/agent-runtime 0.3.2 → 0.3.7
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/anthropic-live-models.d.ts +45 -0
- package/dist/anthropic-live-models.js +0 -0
- package/dist/claude-code-models.d.ts +63 -0
- package/dist/claude-code-models.js +252 -0
- package/dist/defs/aider.d.ts +1 -0
- package/dist/defs/aider.js +17 -1
- package/dist/defs/amp.js +9 -0
- package/dist/defs/amr.d.ts +1 -0
- package/dist/defs/amr.js +7 -0
- package/dist/defs/claude.d.ts +2 -1
- package/dist/defs/claude.js +78 -8
- package/dist/defs/codex.d.ts +20 -1
- package/dist/defs/codex.js +170 -17
- package/dist/defs/copilot.js +14 -0
- package/dist/defs/cursor-agent.js +11 -0
- package/dist/defs/deepseek.js +12 -0
- package/dist/defs/grok-build.js +10 -0
- package/dist/defs/opencode.d.ts +1 -0
- package/dist/defs/opencode.js +7 -2
- package/dist/defs/pi.d.ts +1 -0
- package/dist/defs/pi.js +12 -4
- package/dist/defs/qoder.js +11 -0
- package/dist/defs/qwen.js +9 -0
- package/dist/detection.d.ts +21 -1
- package/dist/detection.js +59 -4
- package/dist/registry.d.ts +2 -1
- package/dist/registry.js +2 -1
- package/dist/types.d.ts +67 -1
- package/package.json +5 -4
- package/dist/acp-model-probe.d.ts.map +0 -1
- package/dist/acp-model-probe.js.map +0 -1
- package/dist/agent-protocol/acp/account-failure.d.ts.map +0 -1
- package/dist/agent-protocol/acp/account-failure.js.map +0 -1
- package/dist/agent-protocol/acp/constants.d.ts.map +0 -1
- package/dist/agent-protocol/acp/constants.js.map +0 -1
- package/dist/agent-protocol/acp/index.d.ts.map +0 -1
- package/dist/agent-protocol/acp/index.js.map +0 -1
- package/dist/agent-protocol/acp/json.d.ts.map +0 -1
- package/dist/agent-protocol/acp/json.js.map +0 -1
- package/dist/agent-protocol/acp/models.d.ts.map +0 -1
- package/dist/agent-protocol/acp/models.js.map +0 -1
- package/dist/agent-protocol/acp/rpc.d.ts.map +0 -1
- package/dist/agent-protocol/acp/rpc.js.map +0 -1
- package/dist/agent-protocol/acp/session-params.d.ts.map +0 -1
- package/dist/agent-protocol/acp/session-params.js.map +0 -1
- package/dist/agent-protocol/acp/session.d.ts.map +0 -1
- package/dist/agent-protocol/acp/session.js.map +0 -1
- package/dist/agent-protocol/acp/text-suppression.d.ts.map +0 -1
- package/dist/agent-protocol/acp/text-suppression.js.map +0 -1
- package/dist/agent-protocol/acp/types.d.ts.map +0 -1
- package/dist/agent-protocol/acp/types.js.map +0 -1
- package/dist/agent-protocol/acp/updates.d.ts.map +0 -1
- package/dist/agent-protocol/acp/updates.js.map +0 -1
- package/dist/agent-protocol/core/index.d.ts.map +0 -1
- package/dist/agent-protocol/core/index.js.map +0 -1
- package/dist/agent-protocol/core/json-line-stream.d.ts.map +0 -1
- package/dist/agent-protocol/core/json-line-stream.js.map +0 -1
- package/dist/agent-protocol/index.d.ts.map +0 -1
- package/dist/agent-protocol/index.js.map +0 -1
- package/dist/agent-protocol/pi-rpc/events.d.ts.map +0 -1
- package/dist/agent-protocol/pi-rpc/events.js.map +0 -1
- package/dist/agent-protocol/pi-rpc/index.d.ts.map +0 -1
- package/dist/agent-protocol/pi-rpc/index.js.map +0 -1
- package/dist/agent-protocol/pi-rpc/internal.d.ts.map +0 -1
- package/dist/agent-protocol/pi-rpc/internal.js.map +0 -1
- package/dist/agent-protocol/pi-rpc/models.d.ts.map +0 -1
- package/dist/agent-protocol/pi-rpc/models.js.map +0 -1
- package/dist/agent-protocol/pi-rpc/session.d.ts.map +0 -1
- package/dist/agent-protocol/pi-rpc/session.js.map +0 -1
- package/dist/amr-model-cache.d.ts.map +0 -1
- package/dist/amr-model-cache.js.map +0 -1
- package/dist/amr-profile-resolver.d.ts.map +0 -1
- package/dist/amr-profile-resolver.js.map +0 -1
- package/dist/artifact-taxonomy.d.ts.map +0 -1
- package/dist/artifact-taxonomy.js.map +0 -1
- package/dist/auth.d.ts.map +0 -1
- package/dist/auth.js.map +0 -1
- package/dist/capabilities.d.ts.map +0 -1
- package/dist/capabilities.js.map +0 -1
- package/dist/claude-stream.d.ts.map +0 -1
- package/dist/claude-stream.js.map +0 -1
- package/dist/copilot-stream.d.ts.map +0 -1
- package/dist/copilot-stream.js.map +0 -1
- package/dist/defs/aider.d.ts.map +0 -1
- package/dist/defs/aider.js.map +0 -1
- package/dist/defs/amp.d.ts.map +0 -1
- package/dist/defs/amp.js.map +0 -1
- package/dist/defs/amr.d.ts.map +0 -1
- package/dist/defs/amr.js.map +0 -1
- package/dist/defs/antigravity.d.ts.map +0 -1
- package/dist/defs/antigravity.js.map +0 -1
- package/dist/defs/claude.d.ts.map +0 -1
- package/dist/defs/claude.js.map +0 -1
- package/dist/defs/codebuddy.d.ts.map +0 -1
- package/dist/defs/codebuddy.js.map +0 -1
- package/dist/defs/codex.d.ts.map +0 -1
- package/dist/defs/codex.js.map +0 -1
- package/dist/defs/copilot.d.ts.map +0 -1
- package/dist/defs/copilot.js.map +0 -1
- package/dist/defs/cursor-agent.d.ts.map +0 -1
- package/dist/defs/cursor-agent.js.map +0 -1
- package/dist/defs/deepseek.d.ts.map +0 -1
- package/dist/defs/deepseek.js.map +0 -1
- package/dist/defs/devin.d.ts.map +0 -1
- package/dist/defs/devin.js.map +0 -1
- package/dist/defs/grok-build.d.ts.map +0 -1
- package/dist/defs/grok-build.js.map +0 -1
- package/dist/defs/hermes.d.ts.map +0 -1
- package/dist/defs/hermes.js.map +0 -1
- package/dist/defs/index.d.ts.map +0 -1
- package/dist/defs/index.js.map +0 -1
- package/dist/defs/kilo.d.ts.map +0 -1
- package/dist/defs/kilo.js.map +0 -1
- package/dist/defs/kimi.d.ts.map +0 -1
- package/dist/defs/kimi.js.map +0 -1
- package/dist/defs/kiro.d.ts.map +0 -1
- package/dist/defs/kiro.js.map +0 -1
- package/dist/defs/mimo.d.ts.map +0 -1
- package/dist/defs/mimo.js.map +0 -1
- package/dist/defs/opencode.d.ts.map +0 -1
- package/dist/defs/opencode.js.map +0 -1
- package/dist/defs/pi.d.ts.map +0 -1
- package/dist/defs/pi.js.map +0 -1
- package/dist/defs/qoder.d.ts.map +0 -1
- package/dist/defs/qoder.js.map +0 -1
- package/dist/defs/qwen.d.ts.map +0 -1
- package/dist/defs/qwen.js.map +0 -1
- package/dist/defs/reasonix.d.ts.map +0 -1
- package/dist/defs/reasonix.js.map +0 -1
- package/dist/defs/shared.d.ts.map +0 -1
- package/dist/defs/shared.js.map +0 -1
- package/dist/defs/trae-cli.d.ts.map +0 -1
- package/dist/defs/trae-cli.js.map +0 -1
- package/dist/defs/vibe.d.ts.map +0 -1
- package/dist/defs/vibe.js.map +0 -1
- package/dist/detection.d.ts.map +0 -1
- package/dist/detection.js.map +0 -1
- package/dist/diagnostics.d.ts.map +0 -1
- package/dist/diagnostics.js.map +0 -1
- package/dist/env.d.ts.map +0 -1
- package/dist/env.js.map +0 -1
- package/dist/executables.d.ts.map +0 -1
- package/dist/executables.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/invocation.d.ts.map +0 -1
- package/dist/invocation.js.map +0 -1
- package/dist/json-event-stream.d.ts.map +0 -1
- package/dist/json-event-stream.js.map +0 -1
- package/dist/launch.d.ts.map +0 -1
- package/dist/launch.js.map +0 -1
- package/dist/log-file.d.ts.map +0 -1
- package/dist/log-file.js.map +0 -1
- package/dist/mcp.d.ts.map +0 -1
- package/dist/mcp.js.map +0 -1
- package/dist/metadata.d.ts.map +0 -1
- package/dist/metadata.js.map +0 -1
- package/dist/mmd-routes.d.ts.map +0 -1
- package/dist/mmd-routes.js.map +0 -1
- package/dist/model-registry.d.ts.map +0 -1
- package/dist/model-registry.js.map +0 -1
- package/dist/models.d.ts.map +0 -1
- package/dist/models.js.map +0 -1
- package/dist/opencode-log.d.ts.map +0 -1
- package/dist/opencode-log.js.map +0 -1
- package/dist/paths.d.ts.map +0 -1
- package/dist/paths.js.map +0 -1
- package/dist/pi-models.d.ts.map +0 -1
- package/dist/pi-models.js.map +0 -1
- package/dist/prompt-augmenter.d.ts.map +0 -1
- package/dist/prompt-augmenter.js.map +0 -1
- package/dist/prompt-budget.d.ts.map +0 -1
- package/dist/prompt-budget.js.map +0 -1
- package/dist/prompt-file.d.ts.map +0 -1
- package/dist/prompt-file.js.map +0 -1
- package/dist/providers/aihubmix.d.ts.map +0 -1
- package/dist/providers/aihubmix.js.map +0 -1
- package/dist/providers/anthropic-messages.d.ts.map +0 -1
- package/dist/providers/anthropic-messages.js.map +0 -1
- package/dist/providers/azure-chat.d.ts.map +0 -1
- package/dist/providers/azure-chat.js.map +0 -1
- package/dist/providers/connection-guard.d.ts.map +0 -1
- package/dist/providers/connection-guard.js.map +0 -1
- package/dist/providers/connection-test.d.ts.map +0 -1
- package/dist/providers/connection-test.js.map +0 -1
- package/dist/providers/elevenlabs.d.ts.map +0 -1
- package/dist/providers/elevenlabs.js.map +0 -1
- package/dist/providers/google-messages.d.ts.map +0 -1
- package/dist/providers/google-messages.js.map +0 -1
- package/dist/providers/google.d.ts.map +0 -1
- package/dist/providers/google.js.map +0 -1
- package/dist/providers/index.d.ts.map +0 -1
- package/dist/providers/index.js.map +0 -1
- package/dist/providers/model-catalog.d.ts.map +0 -1
- package/dist/providers/model-catalog.js.map +0 -1
- package/dist/providers/oauth-callback-server.d.ts.map +0 -1
- package/dist/providers/oauth-callback-server.js.map +0 -1
- package/dist/providers/oauth-credentials.d.ts.map +0 -1
- package/dist/providers/oauth-credentials.js.map +0 -1
- package/dist/providers/oauth-provider.d.ts.map +0 -1
- package/dist/providers/oauth-provider.js.map +0 -1
- package/dist/providers/oauth-tokens.d.ts.map +0 -1
- package/dist/providers/oauth-tokens.js.map +0 -1
- package/dist/providers/ollama-chat.d.ts.map +0 -1
- package/dist/providers/ollama-chat.js.map +0 -1
- package/dist/providers/openai-chat.d.ts.map +0 -1
- package/dist/providers/openai-chat.js.map +0 -1
- package/dist/providers/pkce.d.ts.map +0 -1
- package/dist/providers/pkce.js.map +0 -1
- package/dist/providers/sse-decode.d.ts.map +0 -1
- package/dist/providers/sse-decode.js.map +0 -1
- package/dist/providers/token-params.d.ts.map +0 -1
- package/dist/providers/token-params.js.map +0 -1
- package/dist/providers/turn-end-guard.d.ts.map +0 -1
- package/dist/providers/turn-end-guard.js.map +0 -1
- package/dist/providers/types.d.ts.map +0 -1
- package/dist/providers/types.js.map +0 -1
- package/dist/qoder-stream.d.ts.map +0 -1
- package/dist/qoder-stream.js.map +0 -1
- package/dist/registry.d.ts.map +0 -1
- package/dist/registry.js.map +0 -1
- package/dist/resolution.d.ts.map +0 -1
- package/dist/resolution.js.map +0 -1
- package/dist/role-marker-guard.d.ts.map +0 -1
- package/dist/role-marker-guard.js.map +0 -1
- package/dist/telemetry-sink.d.ts.map +0 -1
- package/dist/telemetry-sink.js.map +0 -1
- package/dist/terminal-launch.d.ts.map +0 -1
- package/dist/terminal-launch.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
package/dist/defs/codex.js
CHANGED
|
@@ -7,7 +7,88 @@
|
|
|
7
7
|
* `source-map.md` for the exact original names.
|
|
8
8
|
*/
|
|
9
9
|
import { DEFAULT_MODEL_OPTION, clampCodexReasoning } from './shared.js';
|
|
10
|
-
|
|
10
|
+
/**
|
|
11
|
+
* The `visibility` values that mean "reachable by id, but do not render in a picker".
|
|
12
|
+
*
|
|
13
|
+
* A SET rather than one literal, because the vendor has demonstrably used more than one spelling of
|
|
14
|
+
* this single state: the shipped Codex catalog says `hide` (verified live against
|
|
15
|
+
* `codex debug models` 0.153.4 — `gpt-reserve` and `codex-auto-review` both carry it), while this
|
|
16
|
+
* adapter was originally written against `hidden`. Matching only one of them let every `hide` entry
|
|
17
|
+
* render in the Local-CLI model picker. Being permissive on input costs nothing here — no real
|
|
18
|
+
* catalog value is a cased or padded variant of a DIFFERENT visibility state — and it means a third
|
|
19
|
+
* spelling does not silently reopen the same hole.
|
|
20
|
+
*/
|
|
21
|
+
const HIDDEN_MODEL_VISIBILITIES = new Set(['hide', 'hidden']);
|
|
22
|
+
function isHiddenVisibility(visibility) {
|
|
23
|
+
return typeof visibility === 'string' && HIDDEN_MODEL_VISIBILITIES.has(visibility.trim().toLowerCase());
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Display labels for the effort levels, keyed by the catalog's own `effort` token.
|
|
27
|
+
*
|
|
28
|
+
* Spelled out rather than derived by capitalizing, because `xhigh` renders as `XHigh` — the exact
|
|
29
|
+
* casing the static `reasoningOptions` list below already used, so a live-derived list and a
|
|
30
|
+
* fallback list read identically in the picker. Unknown tokens (a level the vendor adds tomorrow)
|
|
31
|
+
* fall through to a capitalize, which is right often enough and is never worse than dropping the
|
|
32
|
+
* level entirely.
|
|
33
|
+
*/
|
|
34
|
+
const CODEX_EFFORT_LABELS = {
|
|
35
|
+
none: 'None', minimal: 'Minimal', low: 'Low', medium: 'Medium',
|
|
36
|
+
high: 'High', xhigh: 'XHigh', max: 'Max', ultra: 'Ultra',
|
|
37
|
+
};
|
|
38
|
+
function codexEffortLabel(effort) {
|
|
39
|
+
return CODEX_EFFORT_LABELS[effort] ?? `${effort.charAt(0).toUpperCase()}${effort.slice(1)}`;
|
|
40
|
+
}
|
|
41
|
+
/** Accepts both catalog spellings of a level: the `{ effort, description }` object the live 0.153.x
|
|
42
|
+
* catalog emits, and a bare string (the shape an older/simpler catalog could use). */
|
|
43
|
+
function codexEffortToken(raw) {
|
|
44
|
+
if (typeof raw === 'string')
|
|
45
|
+
return raw.trim();
|
|
46
|
+
if (raw && typeof raw === 'object') {
|
|
47
|
+
const effort = raw.effort;
|
|
48
|
+
if (typeof effort === 'string')
|
|
49
|
+
return effort.trim();
|
|
50
|
+
}
|
|
51
|
+
return '';
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Reads one catalog entry's `supported_reasoning_levels` into picker options.
|
|
55
|
+
*
|
|
56
|
+
* @returns The levels in catalog order, de-duplicated; `undefined` when the entry declares none, so
|
|
57
|
+
* the model row simply omits the field rather than claiming "supports no effort levels".
|
|
58
|
+
* @complexity O(n) in the entry's declared level count.
|
|
59
|
+
*/
|
|
60
|
+
function parseCodexEntryReasoning(raw) {
|
|
61
|
+
if (!Array.isArray(raw))
|
|
62
|
+
return undefined;
|
|
63
|
+
const seen = new Set();
|
|
64
|
+
const out = [];
|
|
65
|
+
for (const level of raw) {
|
|
66
|
+
const effort = codexEffortToken(level);
|
|
67
|
+
if (!effort || seen.has(effort))
|
|
68
|
+
continue;
|
|
69
|
+
seen.add(effort);
|
|
70
|
+
out.push({ id: effort, label: codexEffortLabel(effort) });
|
|
71
|
+
}
|
|
72
|
+
return out.length > 0 ? out : undefined;
|
|
73
|
+
}
|
|
74
|
+
function codexEntryId(entry) {
|
|
75
|
+
if (typeof entry.slug === 'string')
|
|
76
|
+
return entry.slug.trim();
|
|
77
|
+
if (typeof entry.id === 'string')
|
|
78
|
+
return entry.id.trim();
|
|
79
|
+
return '';
|
|
80
|
+
}
|
|
81
|
+
function codexEntryLabel(entry, id) {
|
|
82
|
+
if (typeof entry.display_name === 'string' && entry.display_name.trim())
|
|
83
|
+
return entry.display_name.trim();
|
|
84
|
+
if (typeof entry.name === 'string' && entry.name.trim())
|
|
85
|
+
return entry.name.trim();
|
|
86
|
+
return id;
|
|
87
|
+
}
|
|
88
|
+
/** JSON-decodes `codex debug models` stdout down to its `models` array, or `null` for any shape
|
|
89
|
+
* that isn't one. Split out of `parseCodexDebugModels` so that function stays a single readable
|
|
90
|
+
* loop over already-validated input. */
|
|
91
|
+
function readCodexCatalogEntries(stdout) {
|
|
11
92
|
let parsed;
|
|
12
93
|
try {
|
|
13
94
|
parsed = JSON.parse(String(stdout || ''));
|
|
@@ -18,29 +99,76 @@ export function parseCodexDebugModels(stdout) {
|
|
|
18
99
|
if (!parsed || typeof parsed !== 'object')
|
|
19
100
|
return null;
|
|
20
101
|
const models = parsed.models;
|
|
21
|
-
|
|
102
|
+
return Array.isArray(models) ? models : null;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Parses `codex debug models` stdout into the Local-CLI picker's model rows.
|
|
106
|
+
*
|
|
107
|
+
* Each row carries the model's OWN supported effort levels when the catalog reports them — see
|
|
108
|
+
* `RuntimeModelOption.reasoning`. Hidden entries are dropped (see `isHiddenVisibility`).
|
|
109
|
+
*
|
|
110
|
+
* @returns The rows, `default` sentinel first; `null` when the output is unparseable or yielded no
|
|
111
|
+
* model at all, which is `detection.ts#fetchModels`'s signal to keep the static fallback list.
|
|
112
|
+
* @complexity O(n·m) — one pass over n catalog entries, each with m declared effort levels.
|
|
113
|
+
*/
|
|
114
|
+
/** One catalog entry as a picker row, or `null` when it is malformed, hidden, id-less, or a repeat
|
|
115
|
+
* of an id already taken. Split from the loop below purely to keep both units small. */
|
|
116
|
+
function codexCatalogRow(raw, takenIds) {
|
|
117
|
+
if (!raw || typeof raw !== 'object')
|
|
118
|
+
return null;
|
|
119
|
+
const entry = raw;
|
|
120
|
+
if (isHiddenVisibility(entry.visibility))
|
|
121
|
+
return null;
|
|
122
|
+
const id = codexEntryId(entry);
|
|
123
|
+
if (!id || takenIds.has(id))
|
|
124
|
+
return null;
|
|
125
|
+
const reasoning = parseCodexEntryReasoning(entry.supported_reasoning_levels);
|
|
126
|
+
return { id, label: codexEntryLabel(entry, id), ...(reasoning ? { reasoning } : {}) };
|
|
127
|
+
}
|
|
128
|
+
export function parseCodexDebugModels(stdout) {
|
|
129
|
+
const models = readCodexCatalogEntries(stdout);
|
|
130
|
+
if (!models)
|
|
22
131
|
return null;
|
|
23
132
|
const out = [DEFAULT_MODEL_OPTION];
|
|
24
133
|
const seen = new Set([DEFAULT_MODEL_OPTION.id]);
|
|
25
134
|
for (const raw of models) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const entry = raw;
|
|
29
|
-
if (entry.visibility === 'hidden')
|
|
135
|
+
const row = codexCatalogRow(raw, seen);
|
|
136
|
+
if (!row)
|
|
30
137
|
continue;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
continue;
|
|
34
|
-
seen.add(id);
|
|
35
|
-
const label = typeof entry.display_name === 'string' && entry.display_name.trim()
|
|
36
|
-
? entry.display_name.trim()
|
|
37
|
-
: typeof entry.name === 'string' && entry.name.trim()
|
|
38
|
-
? entry.name.trim()
|
|
39
|
-
: id;
|
|
40
|
-
out.push({ id, label });
|
|
138
|
+
seen.add(row.id);
|
|
139
|
+
out.push(row);
|
|
41
140
|
}
|
|
42
141
|
return out.length > 1 ? out : null;
|
|
43
142
|
}
|
|
143
|
+
/**
|
|
144
|
+
* Collapses the per-model effort levels on a fetched model list into the single agent-level list a
|
|
145
|
+
* picker renders, in first-seen catalog order, behind the `default` sentinel.
|
|
146
|
+
*
|
|
147
|
+
* A UNION rather than an intersection: the alternative would offer only the levels EVERY model
|
|
148
|
+
* supports, which on the live 0.153.4 catalog is `low..xhigh` — precisely the truncated list this
|
|
149
|
+
* exists to replace, since `gpt-5.5` would veto `max`/`ultra` for `gpt-6-astra`. Over-offering is
|
|
150
|
+
* the same failure mode the previous hardcoded list already had (it listed `none`/`minimal`, which
|
|
151
|
+
* no catalog model supports), so this is strictly better; narrowing the offer per SELECTED model is
|
|
152
|
+
* a picker-side concern, and the data for it rides along on each row's `reasoning` field.
|
|
153
|
+
*
|
|
154
|
+
* @param models - A fetched model list; rows without `reasoning` contribute nothing.
|
|
155
|
+
* @returns The union, or `null` when no row carried levels — the caller's signal to keep its own
|
|
156
|
+
* static list rather than replace it with an empty one.
|
|
157
|
+
* @complexity O(n·m) over n models and their m levels.
|
|
158
|
+
*/
|
|
159
|
+
export function unionModelReasoningOptions(models) {
|
|
160
|
+
const seen = new Set();
|
|
161
|
+
const out = [];
|
|
162
|
+
for (const model of models) {
|
|
163
|
+
for (const level of model.reasoning ?? []) {
|
|
164
|
+
if (seen.has(level.id))
|
|
165
|
+
continue;
|
|
166
|
+
seen.add(level.id);
|
|
167
|
+
out.push(level);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return out.length > 0 ? [{ id: 'default', label: 'Default' }, ...out] : null;
|
|
171
|
+
}
|
|
44
172
|
export function codexNeedsDangerFullAccessSandbox(platform = process.platform, env = process.env) {
|
|
45
173
|
// Operator override for deployments where Codex cannot create its
|
|
46
174
|
// workspace-write sandbox, for example unprivileged Linux containers.
|
|
@@ -69,12 +197,24 @@ export const codexAgentDef = {
|
|
|
69
197
|
args: ['login', 'status'],
|
|
70
198
|
timeoutMs: 5000,
|
|
71
199
|
},
|
|
200
|
+
// The OLD-CLI path: a Codex build new enough to answer `debug models` never renders this list.
|
|
201
|
+
// Kept current anyway — a stale fallback is invisible until the day the catalog probe fails, and
|
|
202
|
+
// that is the worst moment to discover it. Current entries first, superseded ones kept below
|
|
203
|
+
// rather than dropped.
|
|
72
204
|
fallbackModels: [
|
|
73
205
|
DEFAULT_MODEL_OPTION,
|
|
206
|
+
{ id: 'gpt-6-astra', label: 'gpt-6-astra' },
|
|
207
|
+
{ id: 'gpt-5.6-sol', label: 'gpt-5.6-sol' },
|
|
208
|
+
{ id: 'gpt-5.6-terra', label: 'gpt-5.6-terra' },
|
|
209
|
+
{ id: 'gpt-5.6-luna', label: 'gpt-5.6-luna' },
|
|
74
210
|
{ id: 'gpt-5.5', label: 'gpt-5.5' },
|
|
75
211
|
{ id: 'gpt-5.4', label: 'gpt-5.4' },
|
|
76
212
|
{ id: 'gpt-5.4-mini', label: 'gpt-5.4-mini' },
|
|
77
213
|
{ id: 'gpt-5.3-codex', label: 'gpt-5.3-codex' },
|
|
214
|
+
// Found by the freshness guard (R13/MF3) against an older Codex install's BUNDLED catalog:
|
|
215
|
+
// codex-cli 0.140.0 lists gpt-5.2 as visible when it cannot reach the backend, which is
|
|
216
|
+
// exactly the population this fallback list serves.
|
|
217
|
+
{ id: 'gpt-5.2', label: 'gpt-5.2' },
|
|
78
218
|
{ id: 'gpt-5.1', label: 'gpt-5.1' },
|
|
79
219
|
{ id: 'gpt-5.1-codex-mini', label: 'gpt-5.1-codex-mini' },
|
|
80
220
|
{ id: 'gpt-5-codex', label: 'gpt-5-codex' },
|
|
@@ -82,6 +222,15 @@ export const codexAgentDef = {
|
|
|
82
222
|
{ id: 'o3', label: 'o3' },
|
|
83
223
|
{ id: 'o4-mini', label: 'o4-mini' },
|
|
84
224
|
],
|
|
225
|
+
// Asserted against a live `codex debug models` run (codex-cli 0.153.4). See
|
|
226
|
+
// `RuntimeAgentDef.fallbackModelsAssertedAt` and `scripts/check-model-fallback-freshness.ts`.
|
|
227
|
+
fallbackModelsAssertedAt: '2026-09-05',
|
|
228
|
+
// The OLD-CLI path only. A Codex build new enough to answer `debug models` gets its effort list
|
|
229
|
+
// derived from that catalog instead (see `deriveReasoningOptions` below), which is what makes
|
|
230
|
+
// `max` and `ultra` reachable. This list is deliberately NOT widened to match: it is what a build
|
|
231
|
+
// too old to have a catalog gets, and `none`/`minimal` — which no model in the current catalog
|
|
232
|
+
// supports — are exactly the levels such a build did accept. `clampCodexReasoning` still maps
|
|
233
|
+
// `minimal` to `low` for the late GPT-5 families.
|
|
85
234
|
reasoningOptions: [
|
|
86
235
|
{ id: 'default', label: 'Default' },
|
|
87
236
|
{ id: 'none', label: 'None' },
|
|
@@ -91,6 +240,10 @@ export const codexAgentDef = {
|
|
|
91
240
|
{ id: 'high', label: 'High' },
|
|
92
241
|
{ id: 'xhigh', label: 'XHigh' },
|
|
93
242
|
],
|
|
243
|
+
// Replaces the list above whenever the live catalog actually reported per-model levels. See
|
|
244
|
+
// `RuntimeAgentDef.deriveReasoningOptions` for the contract and `unionModelReasoningOptions` for
|
|
245
|
+
// why a union and not an intersection.
|
|
246
|
+
deriveReasoningOptions: unionModelReasoningOptions,
|
|
94
247
|
// Prompt is delivered via stdin pipe (gated by `promptViaStdin: true`
|
|
95
248
|
// below) to avoid Windows `spawn ENAMETOOLONG` while keeping Codex on
|
|
96
249
|
// its structured JSON stream. Recent Codex CLI versions reject a bare
|
|
@@ -179,7 +332,7 @@ export const codexAgentDef = {
|
|
|
179
332
|
// not create-only and needs no `resumeSessionId` guard. Pushed for
|
|
180
333
|
// every claimed attachment path the caller hands in here, not only
|
|
181
334
|
// ones actually of kind "image": the caller
|
|
182
|
-
// (`agent-daemon-server.ts#resolveAttachmentRunFields`,
|
|
335
|
+
// (`agent-daemon-server.ts#resolveAttachmentRunFields`, in the consuming product) already
|
|
183
336
|
// stopped filtering by kind for the same reason `qoderAgentDef`'s
|
|
184
337
|
// `--attachment` above does not filter either — a same-shaped
|
|
185
338
|
// repeated-flag mechanism, see `imageDelivery`'s doc below.
|
package/dist/defs/copilot.js
CHANGED
|
@@ -87,5 +87,19 @@ export const copilotAgentDef = {
|
|
|
87
87
|
// operator to override this via its own env var if it wants it
|
|
88
88
|
// tighter.
|
|
89
89
|
inactivityTimeoutMs: 30 * 60 * 1000,
|
|
90
|
+
// No `externalMcpInjection` yet. Copilot CLI has an explicit, run-scoped
|
|
91
|
+
// flag for this: `--additional-mcp-config <json|@path>`, documented as
|
|
92
|
+
// session-only and the highest-priority MCP source (it wins over both
|
|
93
|
+
// `~/.copilot/mcp-config.json` and the auto-discovered project
|
|
94
|
+
// `.github/mcp.json`/`.mcp.json`) — so, unlike the global-file or
|
|
95
|
+
// auto-discovery routes this comment previously (incorrectly) treated as
|
|
96
|
+
// the only options, this one needs neither `COPILOT_HOME` redirection nor
|
|
97
|
+
// `GITHUB_COPILOT_PROMPT_MODE_WORKSPACE_MCP` trust gating. What's still
|
|
98
|
+
// unconfirmed is the exact JSON shape the flag expects at its top level
|
|
99
|
+
// (official docs describe the flag's purpose but not its schema
|
|
100
|
+
// verbatim) — needs a local `copilot --help`/`copilot mcp --help` check
|
|
101
|
+
// before wiring, not a guess. Closest candidate for a new strategy: pass
|
|
102
|
+
// `@<run-scoped-file>` the same way `'claude-mcp-json'` passes a path,
|
|
103
|
+
// once the schema is confirmed.
|
|
90
104
|
};
|
|
91
105
|
//# sourceMappingURL=copilot.js.map
|
|
@@ -100,5 +100,16 @@ export const cursorAgentDef = {
|
|
|
100
100
|
// it here is what makes detection surface an "auth required" badge for
|
|
101
101
|
// Cursor Agent (the generalized probe only runs for adapters that opt in).
|
|
102
102
|
authProbe: { args: ['status'], timeoutMs: 5000 },
|
|
103
|
+
// No `externalMcpInjection`: Cursor CLI does support native MCP — it
|
|
104
|
+
// auto-discovers `.cursor/mcp.json` (project) / `~/.cursor/mcp.json`
|
|
105
|
+
// (global) with project→global→nested precedence, and reportedly has an
|
|
106
|
+
// `--approve-mcps` flag to skip the interactive trust prompt — but there
|
|
107
|
+
// is no confirmed explicit `--mcp-config <path>` flag, so wiring it would
|
|
108
|
+
// mean merging into the project's real `.cursor/mcp.json` (never a
|
|
109
|
+
// run-scoped file) and needs `--approve-mcps` verified live against this
|
|
110
|
+
// package's headless spawn shape first. Needs a new
|
|
111
|
+
// merge-into-existing-file strategy, not a reuse of `'claude-mcp-json'`
|
|
112
|
+
// (which relies on an explicit per-run path, never auto-discovery — see
|
|
113
|
+
// `buildClaudeMcpConfigArgs`'s doc for why).
|
|
103
114
|
};
|
|
104
115
|
//# sourceMappingURL=cursor-agent.js.map
|
package/dist/defs/deepseek.js
CHANGED
|
@@ -49,5 +49,17 @@ export const deepseekAgentDef = {
|
|
|
49
49
|
// --auto --model <id>` and any internal quoting.
|
|
50
50
|
maxPromptArgBytes: 30_000,
|
|
51
51
|
streamFormat: 'plain',
|
|
52
|
+
// No `externalMcpInjection`: CodeWhale (this dispatcher's underlying TUI)
|
|
53
|
+
// does support native MCP via `DEEPSEEK_MCP_CONFIG=<path>` — an explicit
|
|
54
|
+
// per-run env override naming an `mcp.json`-shaped file, falling back to
|
|
55
|
+
// `~/.codewhale/mcp.json` / `~/.deepseek/mcp.json` when unset. That is the
|
|
56
|
+
// closest of any unwired def here to this package's existing shape
|
|
57
|
+
// (explicit, run-scoped, no reliance on auto-discovery's interactive
|
|
58
|
+
// trust prompt), but it is a path-in-an-env-var mechanism — neither
|
|
59
|
+
// `'claude-mcp-json'` (file path passed as a CLI flag) nor
|
|
60
|
+
// `'opencode-env-content'`/`'mimo-env-content'` (env var carries the
|
|
61
|
+
// config *content*, not a path) match it. Cheapest real follow-up
|
|
62
|
+
// candidate among the 12; needs a 5th strategy, not a stretch of an
|
|
63
|
+
// existing one.
|
|
52
64
|
};
|
|
53
65
|
//# sourceMappingURL=deepseek.js.map
|
package/dist/defs/grok-build.js
CHANGED
|
@@ -101,5 +101,15 @@ export const grokBuildAgentDef = {
|
|
|
101
101
|
streamFormat: 'plain',
|
|
102
102
|
installUrl: 'https://x.ai/cli',
|
|
103
103
|
docsUrl: 'https://x.ai/cli',
|
|
104
|
+
// No `externalMcpInjection`: Grok Build does ship native MCP support and
|
|
105
|
+
// reads `.mcp.json`/Claude/Cursor configs directly ("zero configuration
|
|
106
|
+
// needed" per xAI's docs) plus `grok mcp enable/disable <name>` CLI
|
|
107
|
+
// control, but that is auto-discovery of a fixed path, not an explicit
|
|
108
|
+
// `--mcp-config <path>` flag. `buildArgs` above already had to route around
|
|
109
|
+
// several non-standard CLI quirks for this def (`--prompt-file` instead of
|
|
110
|
+
// stdin/argv); auto-discovery risks the same interactive-trust-prompt stall
|
|
111
|
+
// `'claude-mcp-json'` was built to avoid for Claude Code (see
|
|
112
|
+
// `buildClaudeMcpConfigArgs`'s doc), unverified here. Needs live
|
|
113
|
+
// verification before any strategy — new or reused — is safe to assign.
|
|
104
114
|
};
|
|
105
115
|
//# sourceMappingURL=grok-build.js.map
|
package/dist/defs/opencode.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ export declare const opencodeAgentDef: {
|
|
|
16
16
|
timeoutMs: number;
|
|
17
17
|
};
|
|
18
18
|
fallbackModels: import("../types.js").RuntimeModelOption[];
|
|
19
|
+
fallbackModelsAssertedAt: string;
|
|
19
20
|
buildArgs: (_prompt: string, _imagePaths: string[], _extra: string[] | undefined, options?: import("../types.js").RuntimeBuildOptions | undefined, runtimeContext?: import("../types.js").RuntimeContext | undefined) => string[];
|
|
20
21
|
promptViaStdin: true;
|
|
21
22
|
resumesSessionViaCli: true;
|
package/dist/defs/opencode.js
CHANGED
|
@@ -26,12 +26,17 @@ export const opencodeAgentDef = {
|
|
|
26
26
|
fallbackModels: [
|
|
27
27
|
DEFAULT_MODEL_OPTION,
|
|
28
28
|
{
|
|
29
|
-
id: 'anthropic/claude-sonnet-
|
|
30
|
-
label: 'anthropic/claude-sonnet-
|
|
29
|
+
id: 'anthropic/claude-sonnet-5',
|
|
30
|
+
label: 'anthropic/claude-sonnet-5',
|
|
31
31
|
},
|
|
32
32
|
{ id: 'openai/gpt-5', label: 'openai/gpt-5' },
|
|
33
33
|
{ id: 'google/gemini-2.5-pro', label: 'google/gemini-2.5-pro' },
|
|
34
34
|
],
|
|
35
|
+
// Checked against `packages/ui/src/features/execution/constants.ts`'s current OpenAI preset —
|
|
36
|
+
// `gpt-5` is a distinct, still-current generation from the newer gpt-5.6 sol/terra/luna tier
|
|
37
|
+
// names, so it is not stale. See `RuntimeAgentDef.fallbackModelsAssertedAt` and
|
|
38
|
+
// `scripts/check-model-fallback-freshness.ts`.
|
|
39
|
+
fallbackModelsAssertedAt: '2026-09-16',
|
|
35
40
|
// OpenCode's CLI help currently exposes model selection and session
|
|
36
41
|
// controls, but not an explicit per-run reasoning / effort flag. Keep
|
|
37
42
|
// `reasoningOptions` undefined and do not synthesize argv for
|
package/dist/defs/pi.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export declare const piAgentDef: {
|
|
|
6
6
|
versionProbeTimeoutMs: number;
|
|
7
7
|
fetchModels: (resolvedBin: string, env: import("../types.js").RuntimeEnv) => Promise<import("../types.js").RuntimeModelOption[] | null>;
|
|
8
8
|
fallbackModels: import("../types.js").RuntimeModelOption[];
|
|
9
|
+
fallbackModelsAssertedAt: string;
|
|
9
10
|
reasoningOptions: {
|
|
10
11
|
id: string;
|
|
11
12
|
label: string;
|
package/dist/defs/pi.js
CHANGED
|
@@ -34,15 +34,23 @@ export const piAgentDef = {
|
|
|
34
34
|
fallbackModels: [
|
|
35
35
|
DEFAULT_MODEL_OPTION,
|
|
36
36
|
{
|
|
37
|
-
id: 'anthropic/claude-sonnet-
|
|
38
|
-
label: 'Claude Sonnet
|
|
37
|
+
id: 'anthropic/claude-sonnet-5',
|
|
38
|
+
label: 'Claude Sonnet 5 (anthropic)',
|
|
39
39
|
},
|
|
40
|
-
{ id: 'anthropic/claude-opus-
|
|
40
|
+
{ id: 'anthropic/claude-opus-5', label: 'Claude Opus 5 (anthropic)' },
|
|
41
41
|
{ id: 'openai/gpt-5', label: 'GPT-5 (openai)' },
|
|
42
|
-
|
|
42
|
+
// `o4-mini` is stale — OpenAI's GPT-5.6 family replaced the old flagship/mini/nano naming
|
|
43
|
+
// with named tiers (sol/terra/luna); `terra` is the mid tier `o4-mini` mapped to. See
|
|
44
|
+
// `packages/ui/src/features/execution/constants.ts`'s OpenAI preset and
|
|
45
|
+
// `scripts/check-model-fallback-freshness.ts`.
|
|
46
|
+
{ id: 'openai/gpt-5.6-terra', label: 'GPT-5.6 Terra (openai)' },
|
|
43
47
|
{ id: 'google/gemini-2.5-pro', label: 'Gemini 2.5 Pro (google)' },
|
|
44
48
|
{ id: 'google/gemini-2.5-flash', label: 'Gemini 2.5 Flash (google)' },
|
|
45
49
|
],
|
|
50
|
+
// Asserted against `packages/ui/src/features/execution/constants.ts`'s current OpenAI preset
|
|
51
|
+
// (gpt-5.6-sol/terra/luna). See `RuntimeAgentDef.fallbackModelsAssertedAt` and
|
|
52
|
+
// `scripts/check-model-fallback-freshness.ts`.
|
|
53
|
+
fallbackModelsAssertedAt: '2026-09-16',
|
|
46
54
|
// Thinking level presets mapped to pi's --thinking flag.
|
|
47
55
|
reasoningOptions: [
|
|
48
56
|
{ id: 'default', label: 'Default' },
|
package/dist/defs/qoder.js
CHANGED
|
@@ -54,5 +54,16 @@ export const qoderAgentDef = {
|
|
|
54
54
|
// native CLI mechanism, not a workaround. See
|
|
55
55
|
// `types.ts#RuntimeAgentDef.imageDelivery`'s doc.
|
|
56
56
|
imageDelivery: 'native',
|
|
57
|
+
// No `externalMcpInjection`: Qoder CLI does support native MCP — `qoder
|
|
58
|
+
// mcp add -s project` writes to `${project}/.mcp.json`, the same filename
|
|
59
|
+
// Claude Code reads — but only via that CLI-mutation subcommand; no
|
|
60
|
+
// explicit `--mcp-config <path>` flag or env-content surface was found,
|
|
61
|
+
// so `buildArgs` above has nothing to point at a run-scoped file with.
|
|
62
|
+
// Wiring this as `'claude-mcp-json'` would be wrong: that strategy relies
|
|
63
|
+
// on an explicit per-spawn flag (see `buildClaudeMcpConfigArgs`'s doc),
|
|
64
|
+
// and Qoder's only path writes into the *project's real* `.mcp.json` via
|
|
65
|
+
// a stateful CLI call, not this run's isolated one. Promising follow-up
|
|
66
|
+
// once auto-discovery's headless trust-prompt behavior is verified live
|
|
67
|
+
// for this CLI specifically.
|
|
57
68
|
};
|
|
58
69
|
//# sourceMappingURL=qoder.js.map
|
package/dist/defs/qwen.js
CHANGED
|
@@ -29,5 +29,14 @@ export const qwenAgentDef = {
|
|
|
29
29
|
},
|
|
30
30
|
promptViaStdin: true,
|
|
31
31
|
streamFormat: 'plain',
|
|
32
|
+
// No `externalMcpInjection`: Qwen Code (a Gemini CLI fork) does support
|
|
33
|
+
// native MCP via `mcpServers` in `.qwen/settings.json` (project) /
|
|
34
|
+
// `~/.qwen/settings.json` (user) — one key alongside unrelated settings,
|
|
35
|
+
// not a dedicated file — with no confirmed CLI flag to point elsewhere or
|
|
36
|
+
// force-trust project servers in headless mode. Structurally closest to
|
|
37
|
+
// the `'opencode-env-content'`/`'mimo-env-content'` merge-into-an-
|
|
38
|
+
// existing-document pattern, but delivered via a settings *file* at a
|
|
39
|
+
// fixed relative path rather than an env var, so it doesn't literally fit
|
|
40
|
+
// either. Needs a new settings.json-merge strategy.
|
|
32
41
|
};
|
|
33
42
|
//# sourceMappingURL=qwen.js.map
|
package/dist/detection.d.ts
CHANGED
|
@@ -1,6 +1,25 @@
|
|
|
1
1
|
import { type AmrProfileResolver } from './amr-profile-resolver.js';
|
|
2
2
|
import type { AgentDiagnostic, DetectedAgent, RuntimeAgentDef, RuntimeModelSource, RuntimeModelOption } from './types.js';
|
|
3
|
-
|
|
3
|
+
type FetchedRuntimeModels = {
|
|
4
|
+
models: RuntimeModelOption[];
|
|
5
|
+
source: RuntimeModelSource;
|
|
6
|
+
};
|
|
7
|
+
/** Result of {@link probeAgentModels}: the models to surface and where they came from. */
|
|
8
|
+
export type ProbedAgentModels = FetchedRuntimeModels;
|
|
9
|
+
/**
|
|
10
|
+
* The model half of {@link detectAgents} for ONE def, without the `--version`/`--help`/auth probes:
|
|
11
|
+
* resolves the launch path, builds the same probe env, runs the def's `fetchModels`/`listModels`,
|
|
12
|
+
* and refreshes the live-model validation cache exactly like `detectAgents` does.
|
|
13
|
+
*
|
|
14
|
+
* For hosts that do their own cheaper availability check but still want the live model catalog —
|
|
15
|
+
* without this, such a host can only ever show `fallbackModels`.
|
|
16
|
+
*
|
|
17
|
+
* @returns `source: 'live'` when the CLI supplied a list; otherwise the def's `fallbackModels` with
|
|
18
|
+
* `source: 'fallback'` (including when the binary is not found). Never rejects.
|
|
19
|
+
* @complexity At most one model-listing spawn, bounded by the def's own timeout.
|
|
20
|
+
*/
|
|
21
|
+
export declare function probeAgentModels(def: RuntimeAgentDef, configuredEnv?: Record<string, string>, amrProfileResolver?: AmrProfileResolver): Promise<ProbedAgentModels>;
|
|
22
|
+
export declare function detectAgents(configuredEnvByAgent?: Record<string, Record<string, string>>, amrProfileResolver?: AmrProfileResolver): Promise<(Omit<RuntimeAgentDef, "buildArgs" | "listModels" | "fetchModels" | "deriveReasoningOptions" | "fallbackModels" | "fallbackModelsAssertedAt" | "helpArgs" | "capabilityFlags" | "fallbackBins" | "versionProbeTimeoutMs" | "maxPromptArgBytes" | "env" | "inactivityTimeoutMs" | "authProbe" | "needsAgentLogFile" | "stdoutPolicy" | "runtimeLock"> & {
|
|
4
23
|
models: RuntimeModelOption[];
|
|
5
24
|
modelsSource: RuntimeModelSource;
|
|
6
25
|
available: boolean;
|
|
@@ -11,4 +30,5 @@ export declare function detectAgents(configuredEnvByAgent?: Record<string, Recor
|
|
|
11
30
|
diagnostics?: AgentDiagnostic[];
|
|
12
31
|
})[]>;
|
|
13
32
|
export declare function detectAgentsStream(configuredEnvByAgent?: Record<string, Record<string, string>>, amrProfileResolver?: AmrProfileResolver): AsyncGenerator<DetectedAgent>;
|
|
33
|
+
export {};
|
|
14
34
|
//# sourceMappingURL=detection.d.ts.map
|
package/dist/detection.js
CHANGED
|
@@ -153,6 +153,53 @@ async function probeCapabilities(def, launchPath, env) {
|
|
|
153
153
|
return {};
|
|
154
154
|
}
|
|
155
155
|
}
|
|
156
|
+
/**
|
|
157
|
+
* The effort-level override a live model catalog earns, if any.
|
|
158
|
+
*
|
|
159
|
+
* `stripFns` already carries the def's static `reasoningOptions` through, so this returns a spread
|
|
160
|
+
* fragment that REPLACES it only when the def declares `deriveReasoningOptions` AND that hook found
|
|
161
|
+
* real per-model levels in the fetched list. Every other case — no hook, an older CLI whose catalog
|
|
162
|
+
* carries no levels, a fallback list — returns `{}` and leaves the static declaration untouched, so
|
|
163
|
+
* this can only add accuracy and never empties a picker's effort choices.
|
|
164
|
+
*
|
|
165
|
+
* @param models - The models `fetchModels` actually surfaced (live or fallback).
|
|
166
|
+
* @complexity O(1) here; the hook's own cost is documented on `deriveReasoningOptions`.
|
|
167
|
+
*/
|
|
168
|
+
function derivedReasoningOverride(def, models) {
|
|
169
|
+
const derived = def.deriveReasoningOptions?.(models);
|
|
170
|
+
return derived && derived.length > 0 ? { reasoningOptions: derived } : {};
|
|
171
|
+
}
|
|
172
|
+
/** The env every probe of one def spawns with — the same env a real run would see. */
|
|
173
|
+
function probeEnvForLaunch(def, configuredEnv, launch) {
|
|
174
|
+
return applyAgentLaunchEnv(spawnEnvForAgent(def.id, { ...process.env, ...(def.env || {}) }, configuredEnv, undefined, {}), launch);
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* The model half of {@link detectAgents} for ONE def, without the `--version`/`--help`/auth probes:
|
|
178
|
+
* resolves the launch path, builds the same probe env, runs the def's `fetchModels`/`listModels`,
|
|
179
|
+
* and refreshes the live-model validation cache exactly like `detectAgents` does.
|
|
180
|
+
*
|
|
181
|
+
* For hosts that do their own cheaper availability check but still want the live model catalog —
|
|
182
|
+
* without this, such a host can only ever show `fallbackModels`.
|
|
183
|
+
*
|
|
184
|
+
* @returns `source: 'live'` when the CLI supplied a list; otherwise the def's `fallbackModels` with
|
|
185
|
+
* `source: 'fallback'` (including when the binary is not found). Never rejects.
|
|
186
|
+
* @complexity At most one model-listing spawn, bounded by the def's own timeout.
|
|
187
|
+
*/
|
|
188
|
+
export async function probeAgentModels(def, configuredEnv = {}, amrProfileResolver = noopAmrProfileResolver) {
|
|
189
|
+
try {
|
|
190
|
+
const launch = resolveAgentLaunch(def, configuredEnv);
|
|
191
|
+
if (!launch.launchPath)
|
|
192
|
+
return { models: def.fallbackModels, source: 'fallback' };
|
|
193
|
+
const probeEnv = probeEnvForLaunch(def, configuredEnv, launch);
|
|
194
|
+
const fetched = await fetchModels(def, launch.launchPath, probeEnv);
|
|
195
|
+
const result = withRememberedAmrModels(def, probeEnv, fetched, amrProfileResolver);
|
|
196
|
+
rememberDetectedModelList(def, configuredEnv, result.models, amrProfileResolver);
|
|
197
|
+
return result;
|
|
198
|
+
}
|
|
199
|
+
catch {
|
|
200
|
+
return { models: def.fallbackModels, source: 'fallback' };
|
|
201
|
+
}
|
|
202
|
+
}
|
|
156
203
|
async function probe(def, configuredEnv = {}, amrProfileResolver) {
|
|
157
204
|
// Detection must probe the exact path the runtime will spawn, not just
|
|
158
205
|
// the PATH-visible shim. This is load-bearing under nvm/fnm/mise: the
|
|
@@ -166,7 +213,7 @@ async function probe(def, configuredEnv = {}, amrProfileResolver) {
|
|
|
166
213
|
if (!launch.selectedPath || !launch.launchPath) {
|
|
167
214
|
return unavailableAgent(def, [buildExecutableDiagnostic(def, configuredEnv)]);
|
|
168
215
|
}
|
|
169
|
-
const probeEnv =
|
|
216
|
+
const probeEnv = probeEnvForLaunch(def, configuredEnv, launch);
|
|
170
217
|
const outcome = await probeVersionAtPath(def, launch.launchPath, probeEnv);
|
|
171
218
|
if (outcome.kind === 'not-invocable') {
|
|
172
219
|
return unavailableAgent(def, [buildNotInvocableDiagnostic(def, launch, outcome.cause)]);
|
|
@@ -188,6 +235,7 @@ async function probe(def, configuredEnv = {}, amrProfileResolver) {
|
|
|
188
235
|
const authDiagnostic = auth ? buildAuthDiagnostic(def, auth) : null;
|
|
189
236
|
return {
|
|
190
237
|
...stripFns(def),
|
|
238
|
+
...derivedReasoningOverride(def, surfacedModelResult.models),
|
|
191
239
|
models: surfacedModelResult.models,
|
|
192
240
|
modelsSource: surfacedModelResult.source,
|
|
193
241
|
available: true,
|
|
@@ -199,6 +247,10 @@ async function probe(def, configuredEnv = {}, amrProfileResolver) {
|
|
|
199
247
|
};
|
|
200
248
|
}
|
|
201
249
|
function stripFns(def) {
|
|
250
|
+
// `deriveReasoningOptions` is dropped with the other closures, and for the same reason
|
|
251
|
+
// `buildArgs` is: a registry consumer has no model list to feed it and `JSON.stringify`
|
|
252
|
+
// would publish nothing where the function was. Its RESULT already shipped — `probe`
|
|
253
|
+
// applies it to `reasoningOptions` before this projection runs.
|
|
202
254
|
// Drop the buildArgs / listModels closures but keep declarative metadata
|
|
203
255
|
// (reasoningOptions, streamFormat, name, bin, etc.). `models` is
|
|
204
256
|
// populated separately by `fetchModels`, so we strip the static
|
|
@@ -213,7 +265,7 @@ function stripFns(def) {
|
|
|
213
265
|
// matter extra because they carry closures — `JSON.stringify` would drop
|
|
214
266
|
// the functions but keep their enclosing objects, publishing a misleading
|
|
215
267
|
// `{"buffering":"until-close"}` / `{}` instead of omitting them.
|
|
216
|
-
const { buildArgs: _buildArgs, listModels: _listModels, fetchModels: _fetchModels, fallbackModels: _fallbackModels, helpArgs: _helpArgs, capabilityFlags: _capabilityFlags, fallbackBins: _fallbackBins, versionProbeTimeoutMs: _versionProbeTimeoutMs, maxPromptArgBytes: _maxPromptArgBytes, env: _env, inactivityTimeoutMs: _inactivityTimeoutMs, authProbe: _authProbe, needsAgentLogFile: _needsAgentLogFile, stdoutPolicy: _stdoutPolicy, runtimeLock: _runtimeLock, ...rest } = def;
|
|
268
|
+
const { buildArgs: _buildArgs, listModels: _listModels, fetchModels: _fetchModels, deriveReasoningOptions: _deriveReasoningOptions, fallbackModels: _fallbackModels, fallbackModelsAssertedAt: _fallbackModelsAssertedAt, helpArgs: _helpArgs, capabilityFlags: _capabilityFlags, fallbackBins: _fallbackBins, versionProbeTimeoutMs: _versionProbeTimeoutMs, maxPromptArgBytes: _maxPromptArgBytes, env: _env, inactivityTimeoutMs: _inactivityTimeoutMs, authProbe: _authProbe, needsAgentLogFile: _needsAgentLogFile, stdoutPolicy: _stdoutPolicy, runtimeLock: _runtimeLock, ...rest } = def;
|
|
217
269
|
return rest;
|
|
218
270
|
}
|
|
219
271
|
async function safeProbe(def, configuredEnv = {}, amrProfileResolver) {
|
|
@@ -229,12 +281,15 @@ async function safeProbe(def, configuredEnv = {}, amrProfileResolver) {
|
|
|
229
281
|
}
|
|
230
282
|
}
|
|
231
283
|
function rememberDetectedLiveModels(def, configuredEnv, agent, amrProfileResolver) {
|
|
232
|
-
|
|
284
|
+
rememberDetectedModelList(def, configuredEnv, agent.models, amrProfileResolver);
|
|
285
|
+
}
|
|
286
|
+
function rememberDetectedModelList(def, configuredEnv, models, amrProfileResolver) {
|
|
287
|
+
if (def.id === 'amr' && models.length === 0)
|
|
233
288
|
return;
|
|
234
289
|
const scope = def.id === 'amr'
|
|
235
290
|
? amrModelScopeFromEnv({ ...process.env, ...(def.env || {}), ...configuredEnv }, amrProfileResolver)
|
|
236
291
|
: null;
|
|
237
|
-
rememberLiveModels(
|
|
292
|
+
rememberLiveModels(def.id, models, scope);
|
|
238
293
|
}
|
|
239
294
|
export async function detectAgents(configuredEnvByAgent = {}, amrProfileResolver = noopAmrProfileResolver) {
|
|
240
295
|
const results = await Promise.all(AGENT_DEFS.map((def) => safeProbe(def, configuredEnvByAgent?.[def.id] ?? {}, amrProfileResolver)));
|
package/dist/registry.d.ts
CHANGED
|
@@ -3,7 +3,8 @@ export declare const BASE_AGENT_DEFS: RuntimeAgentDef[];
|
|
|
3
3
|
export declare const AGENT_DEFS: RuntimeAgentDef[];
|
|
4
4
|
export declare function getAgentDef(id: string): RuntimeAgentDef | null;
|
|
5
5
|
/**
|
|
6
|
-
* Whether a caller can inject external MCP servers (
|
|
6
|
+
* Whether a caller can inject external MCP servers (the host application's or this engine's own
|
|
7
|
+
* tools) into a session run by this
|
|
7
8
|
* def, per its own `externalMcpInjection` declaration (`types.ts`'s own doc names the six wired
|
|
8
9
|
* strategies and the defs that leave the field `undefined` because the CLI has no mechanism to
|
|
9
10
|
* receive one — `aider`, `amp`, `copilot`, `cursor-agent`, `deepseek`, `grok-build`, `pi`,
|
package/dist/registry.js
CHANGED
|
@@ -56,7 +56,8 @@ export function getAgentDef(id) {
|
|
|
56
56
|
return AGENT_DEFS.find((a) => a.id === id) || null;
|
|
57
57
|
}
|
|
58
58
|
/**
|
|
59
|
-
* Whether a caller can inject external MCP servers (
|
|
59
|
+
* Whether a caller can inject external MCP servers (the host application's or this engine's own
|
|
60
|
+
* tools) into a session run by this
|
|
60
61
|
* def, per its own `externalMcpInjection` declaration (`types.ts`'s own doc names the six wired
|
|
61
62
|
* strategies and the defs that leave the field `undefined` because the CLI has no mechanism to
|
|
62
63
|
* receive one — `aider`, `amp`, `copilot`, `cursor-agent`, `deepseek`, `grok-build`, `pi`,
|