@jini-ai/agent-runtime 0.4.0 → 0.4.2

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.
Files changed (129) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/acp-model-probe.d.ts +6 -27
  3. package/dist/acp-model-probe.js +6 -4
  4. package/dist/agent-protocol/acp/models.d.ts +8 -0
  5. package/dist/agent-protocol/acp/models.js +38 -6
  6. package/dist/agent-protocol/acp/session.js +15 -2
  7. package/dist/agent-protocol/pi-rpc/events.js +4 -0
  8. package/dist/amr-model-cache.d.ts +2 -12
  9. package/dist/amr-profile-resolver.d.ts +3 -14
  10. package/dist/anthropic-live-models.d.ts +1 -1
  11. package/dist/anthropic-live-models.js +0 -0
  12. package/dist/artifact-taxonomy.d.ts +3 -17
  13. package/dist/auth.d.ts +0 -6
  14. package/dist/auth.js +1 -30
  15. package/dist/claude-code-models.d.ts +3 -4
  16. package/dist/claude-code-models.js +5 -7
  17. package/dist/claude-stream.d.ts +0 -4
  18. package/dist/claude-stream.js +4 -4
  19. package/dist/copilot-stream.d.ts +0 -5
  20. package/dist/copilot-stream.js +0 -5
  21. package/dist/defs/aider.d.ts +15 -0
  22. package/dist/defs/aider.js +4 -2
  23. package/dist/defs/amp.d.ts +16 -0
  24. package/dist/defs/amp.js +5 -1
  25. package/dist/defs/amr.d.ts +15 -0
  26. package/dist/defs/amr.js +6 -15
  27. package/dist/defs/antigravity.d.ts +16 -1
  28. package/dist/defs/antigravity.js +3 -2
  29. package/dist/defs/auggie.d.ts +15 -0
  30. package/dist/defs/auggie.js +3 -0
  31. package/dist/defs/claude.d.ts +15 -0
  32. package/dist/defs/claude.js +26 -36
  33. package/dist/defs/cline.d.ts +15 -0
  34. package/dist/defs/cline.js +3 -0
  35. package/dist/defs/codebuddy.d.ts +15 -0
  36. package/dist/defs/codebuddy.js +3 -1
  37. package/dist/defs/codex.d.ts +15 -0
  38. package/dist/defs/codex.js +11 -48
  39. package/dist/defs/copilot.d.ts +15 -0
  40. package/dist/defs/copilot.js +5 -14
  41. package/dist/defs/crush.d.ts +15 -0
  42. package/dist/defs/crush.js +3 -0
  43. package/dist/defs/cursor-agent.d.ts +15 -0
  44. package/dist/defs/cursor-agent.js +3 -1
  45. package/dist/defs/deepseek.d.ts +15 -0
  46. package/dist/defs/deepseek.js +3 -1
  47. package/dist/defs/devin.d.ts +15 -0
  48. package/dist/defs/devin.js +3 -1
  49. package/dist/defs/droid.d.ts +15 -0
  50. package/dist/defs/droid.js +3 -0
  51. package/dist/defs/goose.d.ts +15 -0
  52. package/dist/defs/goose.js +3 -0
  53. package/dist/defs/grok-build.d.ts +15 -0
  54. package/dist/defs/grok-build.js +5 -9
  55. package/dist/defs/hermes.d.ts +15 -0
  56. package/dist/defs/hermes.js +3 -1
  57. package/dist/defs/index.d.ts +1 -6
  58. package/dist/defs/index.js +1 -6
  59. package/dist/defs/kilo.d.ts +15 -0
  60. package/dist/defs/kilo.js +3 -1
  61. package/dist/defs/kimi.d.ts +15 -0
  62. package/dist/defs/kimi.js +3 -1
  63. package/dist/defs/kiro.d.ts +15 -0
  64. package/dist/defs/kiro.js +3 -1
  65. package/dist/defs/mimo.d.ts +15 -0
  66. package/dist/defs/mimo.js +3 -1
  67. package/dist/defs/opencode.d.ts +15 -1
  68. package/dist/defs/opencode.js +2 -1
  69. package/dist/defs/pi.d.ts +15 -0
  70. package/dist/defs/pi.js +6 -5
  71. package/dist/defs/qoder.d.ts +15 -0
  72. package/dist/defs/qoder.js +3 -1
  73. package/dist/defs/qwen.d.ts +15 -0
  74. package/dist/defs/qwen.js +3 -1
  75. package/dist/defs/reasonix.d.ts +15 -0
  76. package/dist/defs/reasonix.js +7 -23
  77. package/dist/defs/shared.d.ts +3 -8
  78. package/dist/defs/shared.js +3 -8
  79. package/dist/defs/trae-cli.d.ts +15 -0
  80. package/dist/defs/trae-cli.js +3 -1
  81. package/dist/defs/vibe.d.ts +15 -0
  82. package/dist/defs/vibe.js +3 -1
  83. package/dist/detection.d.ts +23 -4
  84. package/dist/detection.js +41 -59
  85. package/dist/diagnostics.js +1 -9
  86. package/dist/env.js +5 -31
  87. package/dist/executables.js +0 -1
  88. package/dist/index.d.ts +10 -257
  89. package/dist/index.js +20 -278
  90. package/dist/json-event-stream.js +23 -29
  91. package/dist/launch.js +1 -5
  92. package/dist/log-file.js +0 -5
  93. package/dist/metadata.js +0 -4
  94. package/dist/mmd-routes.js +2 -6
  95. package/dist/model-discovery-adapters.d.ts +19 -0
  96. package/dist/model-discovery-adapters.js +387 -0
  97. package/dist/model-discovery-config.d.ts +17 -0
  98. package/dist/model-discovery-config.js +137 -0
  99. package/dist/model-discovery-sdk.d.ts +18 -0
  100. package/dist/model-discovery-sdk.js +56 -0
  101. package/dist/model-discovery-types.d.ts +139 -0
  102. package/dist/model-discovery-types.js +2 -0
  103. package/dist/model-discovery.d.ts +46 -0
  104. package/dist/model-discovery.js +258 -0
  105. package/dist/model-registry.d.ts +5 -36
  106. package/dist/models.d.ts +1 -4
  107. package/dist/models.js +3 -1
  108. package/dist/opencode-log.js +1 -3
  109. package/dist/paths.js +1 -4
  110. package/dist/pi-models.d.ts +1 -7
  111. package/dist/pi-models.js +1 -3
  112. package/dist/prompt-augmenter.d.ts +3 -17
  113. package/dist/prompt-augmenter.js +3 -17
  114. package/dist/providers/model-catalog.d.ts +2 -0
  115. package/dist/providers/model-catalog.js +76 -55
  116. package/dist/providers/sse-decode.d.ts +4 -48
  117. package/dist/providers/sse-decode.js +3 -108
  118. package/dist/providers/tool-turn-types.d.ts +5 -0
  119. package/dist/providers/tool-turn.js +10 -4
  120. package/dist/qoder-stream.d.ts +0 -3
  121. package/dist/qoder-stream.js +0 -3
  122. package/dist/registry.d.ts +1 -1
  123. package/dist/registry.js +3 -3
  124. package/dist/resolution.js +1 -4
  125. package/dist/role-marker-guard.d.ts +0 -5
  126. package/dist/role-marker-guard.js +0 -5
  127. package/dist/telemetry-sink.d.ts +3 -14
  128. package/dist/types.d.ts +9 -2
  129. package/package.json +28 -7
package/dist/defs/amp.js CHANGED
@@ -1,4 +1,4 @@
1
- /** Ported verbatim from OD's `apps/daemon/src/runtimes/defs/amp.ts` (import path adjusted only). See `archived provenance ledger`. */
1
+ import { createAgentModelDiscovery } from '../model-discovery.js';
2
2
  import { DEFAULT_MODEL_OPTION } from './shared.js';
3
3
  // Amp CLI (https://ampcode.com) is a full agentic coding CLI, argv-shaped
4
4
  // much like Claude Code: it has a headless execute mode and emits a
@@ -31,6 +31,8 @@ import { DEFAULT_MODEL_OPTION } from './shared.js';
31
31
  // "Custom model" input since an arbitrary model id is meaningless here.
32
32
  const AMP_MODES = new Set(['deep', 'smart', 'rush']);
33
33
  export const ampAgentDef = {
34
+ // UNVERIFIED live integration locally; source/category and limits are documented in model-discovery-adapters.ts.
35
+ ...createAgentModelDiscovery('amp', { fallbackModels: () => ampAgentDef.fallbackModels }),
34
36
  id: 'amp',
35
37
  name: 'Amp',
36
38
  bin: 'amp',
@@ -43,6 +45,8 @@ export const ampAgentDef = {
43
45
  { id: 'rush', label: 'Rush (mode)' },
44
46
  ],
45
47
  supportsCustomModel: false,
48
+ // Plugin-agent model IDs cannot pin the built-in agent's smart/deep/rush routing.
49
+ supportsConcreteModelSelection: false,
46
50
  buildArgs: ({ prompt: _prompt, imagePaths: _imagePaths }, { extraAllowedDirs: _extraAllowedDirs = [], options = {} } = {}) => {
47
51
  // See `RuntimeBuildOptions.permissionMode`'s doc: bypass is the default (unchanged
48
52
  // behavior) unless a caller explicitly opts into a restricted run, in which case Amp
@@ -50,5 +50,20 @@ export declare const amrAgentDef: {
50
50
  imageDelivery: "native";
51
51
  defaultModelEnvVar: string;
52
52
  inactivityTimeoutMs: number;
53
+ discoverModels(requiredArgs: {
54
+ context: import("../model-discovery-types.js").ModelDiscoveryContext;
55
+ }, optionalArgs?: {
56
+ signal?: AbortSignal;
57
+ force?: boolean;
58
+ staleWhileRevalidate?: boolean;
59
+ deps?: import("../model-discovery-types.js").ModelDiscoveryDeps;
60
+ }): Promise<import("../model-discovery-types.js").ModelCatalogSnapshot>;
61
+ resolveDefaultModel(requiredArgs: {
62
+ context: import("../model-discovery-types.js").ModelDiscoveryContext;
63
+ catalog: import("../model-discovery-types.js").ModelCatalogSnapshot;
64
+ }, optionalArgs?: {
65
+ signal?: AbortSignal;
66
+ deps?: import("../model-discovery-types.js").ModelDiscoveryDeps;
67
+ }): Promise<import("../model-discovery-types.js").DefaultModelResolution>;
53
68
  };
54
69
  //# sourceMappingURL=amr.d.ts.map
package/dist/defs/amr.js CHANGED
@@ -1,4 +1,4 @@
1
- /** Ported from OD's `apps/daemon/src/runtimes/defs/amr.ts` (two de-branded comments; see `archived provenance ledger`). */
1
+ import { createAgentModelDiscovery } from '../model-discovery.js';
2
2
  import { execAgentFile } from './shared.js';
3
3
  const AMR_MODELS_TIMEOUT_MS = 10_000;
4
4
  const AMR_MODELS_RETRY_DELAYS_MS = [250, 750];
@@ -210,20 +210,9 @@ export async function fetchVelaRemoteModelsWithRetry({ resolvedBin, env }) {
210
210
  // `AMR_MODELS_RETRY_DELAYS_MS` whenever we reach the `sleep()` call below
211
211
  // (the assertion just satisfies `noUncheckedIndexedAccess`).
212
212
  //
213
- // Coverage note (re-derived, not merely restated from the paragraph
214
- // above): `for (let attempt = 0; ; attempt += 1)` has an empty middle
215
- // clause — an unconditional, infinite loop — and its body contains no
216
- // `break` (grepped: none). The only two ways out are the `return` on a
217
- // successful parse and the `throw` in the catch arm, and the `throw` is
218
- // unconditionally forced once `attempt === AMR_MODELS_RETRY_DELAYS_MS.length`
219
- // (`AMR_MODELS_RETRY_DELAYS_MS` is the literal 2-element `[250, 750]`
220
- // above, so that's guaranteed after at most 3 attempts). So this
221
- // function's implicit end-of-body statement (the closing `}` two lines
222
- // below) can never execute — v8/istanbul still instruments it because
223
- // it can't prove an arbitrary `for(;;)` terminates, but the real control
224
- // flow genuinely never reaches it. Documented here (and in
225
- // `archived provenance ledger`'s 2026-07-22 entry) instead of forced via a test,
226
- // per this repo's no-`/* v8 ignore */` standard.
213
+ // The empty loop condition and absence of break make the closing statement unreachable:
214
+ // success returns, and exhaustion throws after at most three attempts. Coverage instrumentation
215
+ // cannot prove that; document the invariant instead of forcing a test or adding v8 ignore.
227
216
  for (let attempt = 0;; attempt += 1) {
228
217
  try {
229
218
  const { stdout } = await execAgentFile({ command: resolvedBin, args: ['model', 'list', '--format', 'json'] }, { options: {
@@ -270,6 +259,8 @@ export async function fetchVelaBillingSummary({ resolvedBin, env }) {
270
259
  return { plan: tier, balanceUsd };
271
260
  }
272
261
  export const amrAgentDef = {
262
+ // UNVERIFIED live integration locally; source/category and limits are documented in model-discovery-adapters.ts.
263
+ ...createAgentModelDiscovery('amr', { fallbackModels: () => amrAgentDef.fallbackModels, parse: ({ stdout }) => parseVelaModelJson({ stdout, expectedSource: 'remote' }) }),
273
264
  id: 'amr',
274
265
  name: 'AMR',
275
266
  bin: 'vela',
@@ -8,7 +8,7 @@ import type { RuntimeModelOption } from '../types.js';
8
8
  * already has an owner — `auth.ts`'s `classifyAgentAuthFailure` /
9
9
  * `isAntigravityAuthFailureText`, consumed by whatever surfaces a structured
10
10
  * auth error — and duplicating the decision here would mean this def silently
11
- * rewrites assistant text into instructions. See `archived provenance ledger`.
11
+ * rewrites assistant text into instructions.
12
12
  *
13
13
  * @param fullText - The concatenation of every stdout chunk agy produced.
14
14
  * @returns The same text with every sign-in URL replaced by a placeholder.
@@ -74,5 +74,20 @@ export declare const antigravityAgentDef: {
74
74
  installUrl: string;
75
75
  docsUrl: string;
76
76
  externalMcpInjection: "env-passthrough";
77
+ discoverModels(requiredArgs: {
78
+ context: import("../model-discovery-types.js").ModelDiscoveryContext;
79
+ }, optionalArgs?: {
80
+ signal?: AbortSignal;
81
+ force?: boolean;
82
+ staleWhileRevalidate?: boolean;
83
+ deps?: import("../model-discovery-types.js").ModelDiscoveryDeps;
84
+ }): Promise<import("../model-discovery-types.js").ModelCatalogSnapshot>;
85
+ resolveDefaultModel(requiredArgs: {
86
+ context: import("../model-discovery-types.js").ModelDiscoveryContext;
87
+ catalog: import("../model-discovery-types.js").ModelCatalogSnapshot;
88
+ }, optionalArgs?: {
89
+ signal?: AbortSignal;
90
+ deps?: import("../model-discovery-types.js").ModelDiscoveryDeps;
91
+ }): Promise<import("../model-discovery-types.js").DefaultModelResolution>;
77
92
  };
78
93
  //# sourceMappingURL=antigravity.d.ts.map
@@ -1,4 +1,4 @@
1
- /** Ported verbatim from OD's `apps/daemon/src/runtimes/defs/antigravity.ts` (import path adjusted only). See `archived provenance ledger`. */
1
+ import { createAgentModelDiscovery } from '../model-discovery.js';
2
2
  import { redactOAuthUrls } from '@jini-ai/oauth';
3
3
  import { DEFAULT_MODEL_OPTION } from './shared.js';
4
4
  // `agy` v1.1.24 has a real `--model <id>` flag (`agy --help`: "Model for the current CLI
@@ -69,7 +69,7 @@ const OAUTH_URL_PLACEHOLDER = '[redacted sign-in URL]';
69
69
  * already has an owner — `auth.ts`'s `classifyAgentAuthFailure` /
70
70
  * `isAntigravityAuthFailureText`, consumed by whatever surfaces a structured
71
71
  * auth error — and duplicating the decision here would mean this def silently
72
- * rewrites assistant text into instructions. See `archived provenance ledger`.
72
+ * rewrites assistant text into instructions.
73
73
  *
74
74
  * @param fullText - The concatenation of every stdout chunk agy produced.
75
75
  * @returns The same text with every sign-in URL replaced by a placeholder.
@@ -121,6 +121,7 @@ export function parseAgyModels({ stdout }) {
121
121
  return out.length > 1 ? out : null;
122
122
  }
123
123
  export const antigravityAgentDef = {
124
+ ...createAgentModelDiscovery('antigravity', { fallbackModels: () => antigravityAgentDef.fallbackModels, args: ['models'], parse: (input) => antigravityAgentDef.listModels.parse(input) }),
124
125
  id: 'antigravity',
125
126
  name: 'Antigravity',
126
127
  bin: 'agy',
@@ -12,5 +12,20 @@ export declare const auggieAgentDef: {
12
12
  streamFormat: string;
13
13
  externalMcpInjection: "acp-merge";
14
14
  imageDelivery: "native";
15
+ discoverModels(requiredArgs: {
16
+ context: import("../model-discovery-types.js").ModelDiscoveryContext;
17
+ }, optionalArgs?: {
18
+ signal?: AbortSignal;
19
+ force?: boolean;
20
+ staleWhileRevalidate?: boolean;
21
+ deps?: import("../model-discovery-types.js").ModelDiscoveryDeps;
22
+ }): Promise<import("../model-discovery-types.js").ModelCatalogSnapshot>;
23
+ resolveDefaultModel(requiredArgs: {
24
+ context: import("../model-discovery-types.js").ModelDiscoveryContext;
25
+ catalog: import("../model-discovery-types.js").ModelCatalogSnapshot;
26
+ }, optionalArgs?: {
27
+ signal?: AbortSignal;
28
+ deps?: import("../model-discovery-types.js").ModelDiscoveryDeps;
29
+ }): Promise<import("../model-discovery-types.js").DefaultModelResolution>;
15
30
  };
16
31
  //# sourceMappingURL=auggie.d.ts.map
@@ -1,3 +1,4 @@
1
+ import { createAgentModelDiscovery } from '../model-discovery.js';
1
2
  /**
2
3
  * @module defs/auggie
3
4
  *
@@ -8,6 +9,8 @@
8
9
  */
9
10
  import { detectAcpModels, DEFAULT_MODEL_OPTION } from './shared.js';
10
11
  export const auggieAgentDef = {
12
+ // UNVERIFIED live integration locally; source/category and limits are documented in model-discovery-adapters.ts.
13
+ ...createAgentModelDiscovery('auggie', { fallbackModels: () => auggieAgentDef.fallbackModels }),
11
14
  id: 'auggie',
12
15
  name: 'Auggie CLI',
13
16
  bin: 'auggie',
@@ -48,5 +48,20 @@ export declare const claudeAgentDef: {
48
48
  };
49
49
  resumesSessionViaCli: true;
50
50
  imageDelivery: "prompt-path";
51
+ discoverModels(requiredArgs: {
52
+ context: import("../model-discovery-types.js").ModelDiscoveryContext;
53
+ }, optionalArgs?: {
54
+ signal?: AbortSignal;
55
+ force?: boolean;
56
+ staleWhileRevalidate?: boolean;
57
+ deps?: import("../model-discovery-types.js").ModelDiscoveryDeps;
58
+ }): Promise<import("../model-discovery-types.js").ModelCatalogSnapshot>;
59
+ resolveDefaultModel(requiredArgs: {
60
+ context: import("../model-discovery-types.js").ModelDiscoveryContext;
61
+ catalog: import("../model-discovery-types.js").ModelCatalogSnapshot;
62
+ }, optionalArgs?: {
63
+ signal?: AbortSignal;
64
+ deps?: import("../model-discovery-types.js").ModelDiscoveryDeps;
65
+ }): Promise<import("../model-discovery-types.js").DefaultModelResolution>;
51
66
  };
52
67
  //# sourceMappingURL=claude.d.ts.map
@@ -1,31 +1,9 @@
1
+ import { createAgentModelDiscovery } from '../model-discovery.js';
1
2
  /**
2
- * Ported verbatim from OD's `apps/daemon/src/runtimes/defs/claude.ts` (import
3
- * path adjusted only). See `archived provenance ledger`.
4
- *
5
- * **Image delivery (added 2026-08-03):** `buildArgs` below takes an
6
- * `_imagePaths` parameter but never references it — the Claude Code CLI has
7
- * no dedicated image-attachment flag or wire mechanism this adapter could
8
- * forward to. It is not, however, blind to images: confirmed live by piping
9
- * `Tell me what this image is as best you can: /tmp/probe-image.png` into a
10
- * real `claude -p` and getting an accurate description back — the CLI reads
11
- * a local file itself once its path is named in the prompt text. The one
12
- * real precondition, also confirmed live: the path's directory has to be in
13
- * the CLI's allowed-directory list (`claude -p` first refused the identical
14
- * probe when the path was under `/Users/la/Desktop`, reporting that
15
- * directory as outside its allowed working directories) — which is exactly
16
- * what `buildArgs`'s existing `extraAllowedDirs` -> `--add-dir` handling
17
- * below already provides, unmodified.
18
- *
19
- * `imageDelivery: 'prompt-path'` (declared below) is what turns this into
20
- * real behavior: `@jini-ai/daemon`'s `agent-executor.ts` reads that field and,
21
- * before `buildArgs` ever runs, (1) appends an attachment-naming section to
22
- * the prompt text via `image-prompt-delivery.ts#augmentPromptWithImageAttachments`
23
- * and (2) widens `extraAllowedDirs` with each image's containing directory —
24
- * so this file needed no change to its own `dirs`/`--add-dir` logic at all,
25
- * only the one-line `imageDelivery` declaration. See
26
- * `types.ts#RuntimeAgentDef.imageDelivery`'s doc for the full mode contract
27
- * and why 'native'-delivery defs (ACP, pi-rpc, qoder) must never also get
28
- * this treatment.
3
+ * Claude Code has no dedicated image-attachment flag. imageDelivery: 'prompt-path' makes the
4
+ * executor append local image paths to the prompt and add their directories to extraAllowedDirs;
5
+ * buildArgs then grants --add-dir access so the CLI can read them itself. Native-delivery defs
6
+ * must not also receive this augmentation; see RuntimeAgentDef.imageDelivery for that contract.
29
7
  */
30
8
  import { agentCapabilities } from '../capabilities.js';
31
9
  import { buildClaudeMcpConfigArgs, DEFAULT_MODEL_OPTION } from './shared.js';
@@ -46,13 +24,16 @@ const CLAUDE_EFFORT_LEVELS = new Set([
46
24
  * The list a picker renders when nothing live is available — no `~/.config/mms/model-routes.json`,
47
25
  * the CLI's own picker catalog unreadable (see `claude-code-models.ts`), and no `ANTHROPIC_API_KEY`
48
26
  * in the agent's environment or a failed live call. Not the primary source: see `fetchModels` below.
49
- * Every live source is unioned ON TOP of this list, so it is also the floor that never shrinks.
27
+ * Historically every live source was unioned on top of this list. Packaged hints are now
28
+ * offline-only: successful native discovery can remove retired models.
50
29
  *
51
30
  * Ordered current-first, then the still-active-but-superseded generations, which are KEPT rather
52
31
  * than dropped — an installed CLI may be pinned to one via its own config, and removing a working
53
32
  * selection out from under a user is worse than listing it last.
54
33
  *
55
- * Every id below is verified present in the installed Claude Code binary's own embedded model
34
+ * The current picker cache was rechecked on 2026-10-07; its four newer selectable IDs are
35
+ * included first. The previous verification below still explains why older IDs remain.
36
+ * Every older id below is verified present in the installed Claude Code binary's own embedded model
56
37
  * table (2.1.261), and `claude-fable-5-1` is additionally the value in `~/.claude.json`'s
57
38
  * server-fetched `additionalModelOptionsCache`. `claude-fable-5-mythos-5` appears in the binary but
58
39
  * NOT in that server-fetched picker list, so it is deliberately omitted: an id in the binary is not
@@ -71,6 +52,11 @@ const CLAUDE_FALLBACK_MODELS = [
71
52
  { id: 'sonnet', label: 'Sonnet (alias)' },
72
53
  { id: 'opus', label: 'Opus (alias)' },
73
54
  { id: 'haiku', label: 'Haiku (alias)' },
55
+ // Current picker cache additions; older selectable IDs remain below for pinned installs.
56
+ { id: 'claude-opus-5-5', label: 'claude-opus-5-5' },
57
+ { id: 'claude-sonnet-5-5', label: 'claude-sonnet-5-5' },
58
+ { id: 'claude-haiku-5-5', label: 'claude-haiku-5-5' },
59
+ { id: 'claude-haiku-4-5-20251001', label: 'claude-haiku-4-5-20251001' },
74
60
  { id: 'claude-fable-5-1', label: 'claude-fable-5-1' },
75
61
  { id: 'claude-fable-5', label: 'claude-fable-5' },
76
62
  { id: 'claude-opus-5', label: 'claude-opus-5' },
@@ -84,6 +70,7 @@ const CLAUDE_FALLBACK_MODELS = [
84
70
  { id: 'claude-sonnet-4-5', label: 'claude-sonnet-4-5' },
85
71
  ];
86
72
  export const claudeAgentDef = {
73
+ ...createAgentModelDiscovery('claude', { fallbackModels: () => claudeAgentDef.fallbackModels }),
87
74
  id: 'claude',
88
75
  name: 'Claude Code',
89
76
  bin: 'claude',
@@ -122,18 +109,20 @@ export const claudeAgentDef = {
122
109
  // falling back to `~/.claude.json`'s `additionalModelOptionsCache`. Cached per process.
123
110
  // b. The account's live Anthropic catalog, when `ANTHROPIC_API_KEY` is in this agent's
124
111
  // environment (makes no network call at all without a key).
125
- // Both are merged ON TOP of the static list, never in place of it; neither shadows the other.
112
+ // Successful discovery replaces packaged hints. The snapshot layer labels caches separately.
126
113
  // 3. The static list, when neither live source answers.
127
114
  //
128
115
  // Returning `null` from any step is "nothing to add", and `detection.ts#fetchModels` renders
129
- // `fallbackModels` for it — so a live-discovery failure can never empty or shrink the picker.
116
+ // `fallbackModels` for it in legacy callers. The required discovery port uses the shared
117
+ // snapshot layer instead: configured routes are not proof of live availability.
130
118
  fallbackModels: CLAUDE_FALLBACK_MODELS,
131
- // Asserted against the installed Claude Code 2.1.261 binary's embedded model table and
119
+ // Reasserted on 2026-10-07 against the local picker cache, retaining the previous
120
+ // assertion against the installed Claude Code 2.1.261 binary's embedded model table and
132
121
  // `~/.claude.json`'s server-fetched `additionalModelOptionsCache`. See
133
122
  // `RuntimeAgentDef.fallbackModelsAssertedAt` and `scripts/check-model-fallback-freshness.ts`.
134
- fallbackModelsAssertedAt: '2026-09-05',
123
+ fallbackModelsAssertedAt: '2026-10-07',
135
124
  fetchModels: async ({ resolvedBin, env }) => {
136
- const routed = await loadMmdRouteModels({ env: env, fallbackModels: CLAUDE_FALLBACK_MODELS });
125
+ const routed = await loadMmdRouteModels({ env: env, fallbackModels: [] });
137
126
  if (routed)
138
127
  return routed;
139
128
  const [fromCli, fromApi] = await Promise.all([
@@ -151,7 +140,8 @@ export const claudeAgentDef = {
151
140
  // the CLI, which would warn on stderr and silently fall back to the default.
152
141
  reasoningOptions: [
153
142
  // Spelled out rather than reusing DEFAULT_MODEL_OPTION: its label reads
154
- // "Default (CLI config)", which is right for a model row and wrong here.
143
+ // "Default (CLI config)". Reasoning retains its Default option; model defaults now use
144
+ // a pre-selected concrete entry, and never display that historical model label.
155
145
  { id: 'default', label: 'Default' },
156
146
  { id: 'low', label: 'Low' },
157
147
  { id: 'medium', label: 'Medium' },
@@ -164,7 +154,7 @@ export const claudeAgentDef = {
164
154
  // `spawn ENAMETOOLONG` (CreateProcess caps the full command line at
165
155
  // ~32 KB direct, ~8 KB via .cmd shim). `claude -p` with no positional
166
156
  // prompt reads the prompt from stdin under `--input-format text` (the
167
- // default), which has no length cap. Mirrors the codex/gemini/opencode/
157
+ // default), which has no length cap. Mirrors the codex/opencode/
168
158
  // cursor/qwen entries below.
169
159
  buildArgs: ({ prompt: _prompt, imagePaths: _imagePaths }, { extraAllowedDirs = [], options = {}, runtimeContext = {} } = {}) => {
170
160
  const caps = agentCapabilities.get('claude') || {};
@@ -12,5 +12,20 @@ export declare const clineAgentDef: {
12
12
  streamFormat: string;
13
13
  externalMcpInjection: "acp-merge";
14
14
  imageDelivery: "native";
15
+ discoverModels(requiredArgs: {
16
+ context: import("../model-discovery-types.js").ModelDiscoveryContext;
17
+ }, optionalArgs?: {
18
+ signal?: AbortSignal;
19
+ force?: boolean;
20
+ staleWhileRevalidate?: boolean;
21
+ deps?: import("../model-discovery-types.js").ModelDiscoveryDeps;
22
+ }): Promise<import("../model-discovery-types.js").ModelCatalogSnapshot>;
23
+ resolveDefaultModel(requiredArgs: {
24
+ context: import("../model-discovery-types.js").ModelDiscoveryContext;
25
+ catalog: import("../model-discovery-types.js").ModelCatalogSnapshot;
26
+ }, optionalArgs?: {
27
+ signal?: AbortSignal;
28
+ deps?: import("../model-discovery-types.js").ModelDiscoveryDeps;
29
+ }): Promise<import("../model-discovery-types.js").DefaultModelResolution>;
15
30
  };
16
31
  //# sourceMappingURL=cline.d.ts.map
@@ -1,3 +1,4 @@
1
+ import { createAgentModelDiscovery } from '../model-discovery.js';
1
2
  /**
2
3
  * @module defs/cline
3
4
  *
@@ -10,6 +11,8 @@
10
11
  */
11
12
  import { detectAcpModels, DEFAULT_MODEL_OPTION } from './shared.js';
12
13
  export const clineAgentDef = {
14
+ // UNVERIFIED live integration locally; source/category and limits are documented in model-discovery-adapters.ts.
15
+ ...createAgentModelDiscovery('cline', { fallbackModels: () => clineAgentDef.fallbackModels }),
13
16
  id: 'cline',
14
17
  name: 'Cline',
15
18
  bin: 'cline',
@@ -29,5 +29,20 @@ export declare const codebuddyAgentDef: {
29
29
  resumesSessionViaCli: true;
30
30
  installUrl: string;
31
31
  docsUrl: string;
32
+ discoverModels(requiredArgs: {
33
+ context: import("../model-discovery-types.js").ModelDiscoveryContext;
34
+ }, optionalArgs?: {
35
+ signal?: AbortSignal;
36
+ force?: boolean;
37
+ staleWhileRevalidate?: boolean;
38
+ deps?: import("../model-discovery-types.js").ModelDiscoveryDeps;
39
+ }): Promise<import("../model-discovery-types.js").ModelCatalogSnapshot>;
40
+ resolveDefaultModel(requiredArgs: {
41
+ context: import("../model-discovery-types.js").ModelDiscoveryContext;
42
+ catalog: import("../model-discovery-types.js").ModelCatalogSnapshot;
43
+ }, optionalArgs?: {
44
+ signal?: AbortSignal;
45
+ deps?: import("../model-discovery-types.js").ModelDiscoveryDeps;
46
+ }): Promise<import("../model-discovery-types.js").DefaultModelResolution>;
32
47
  };
33
48
  //# sourceMappingURL=codebuddy.d.ts.map
@@ -1,4 +1,4 @@
1
- /** Ported verbatim from OD's `apps/daemon/src/runtimes/defs/codebuddy.ts` (import path adjusted only). See `archived provenance ledger`. */
1
+ import { createAgentModelDiscovery } from '../model-discovery.js';
2
2
  import { agentCapabilities } from '../capabilities.js';
3
3
  import { buildClaudeMcpConfigArgs, DEFAULT_MODEL_OPTION } from './shared.js';
4
4
  // Codebuddy Code (https://www.codebuddy.cn) — a Claude Code–compatible CLI
@@ -42,6 +42,8 @@ const CODEBUDDY_FALLBACK_MODELS = [
42
42
  { id: 'minimax-m2.7-ioa', label: 'minimax-m2.7-ioa' },
43
43
  ];
44
44
  export const codebuddyAgentDef = {
45
+ // UNVERIFIED live integration locally; source/category and limits are documented in model-discovery-adapters.ts.
46
+ ...createAgentModelDiscovery('codebuddy', { fallbackModels: () => codebuddyAgentDef.fallbackModels }),
45
47
  id: 'codebuddy',
46
48
  name: 'Codebuddy Code',
47
49
  bin: 'codebuddy',
@@ -61,5 +61,20 @@ export declare const codexAgentDef: {
61
61
  eventParser: string;
62
62
  imageDelivery: "native";
63
63
  externalMcpInjection: "codex-toml";
64
+ discoverModels(requiredArgs: {
65
+ context: import("../model-discovery-types.js").ModelDiscoveryContext;
66
+ }, optionalArgs?: {
67
+ signal?: AbortSignal;
68
+ force?: boolean;
69
+ staleWhileRevalidate?: boolean;
70
+ deps?: import("../model-discovery-types.js").ModelDiscoveryDeps;
71
+ }): Promise<import("../model-discovery-types.js").ModelCatalogSnapshot>;
72
+ resolveDefaultModel(requiredArgs: {
73
+ context: import("../model-discovery-types.js").ModelDiscoveryContext;
74
+ catalog: import("../model-discovery-types.js").ModelCatalogSnapshot;
75
+ }, optionalArgs?: {
76
+ signal?: AbortSignal;
77
+ deps?: import("../model-discovery-types.js").ModelDiscoveryDeps;
78
+ }): Promise<import("../model-discovery-types.js").DefaultModelResolution>;
64
79
  };
65
80
  //# sourceMappingURL=codex.d.ts.map
@@ -1,11 +1,6 @@
1
- /**
2
- * Ported from OD's `apps/daemon/src/runtimes/defs/codex.ts` with one
3
- * de-branding change: the two operator-override env vars (originally
4
- * product-prefixed) are renamed to `CODEX_SANDBOX_MODE` /
5
- * `CODEX_DISABLE_PLUGINS` — these are already codex-adapter-scoped
6
- * operator knobs, so no product namespacing is needed. See
7
- * `archived provenance ledger` for the exact original names.
8
- */
1
+ import { createAgentModelDiscovery } from '../model-discovery.js';
2
+ /** CODEX_SANDBOX_MODE and CODEX_DISABLE_PLUGINS are adapter-scoped operator overrides;
3
+ * no product-specific environment naming is required. */
9
4
  import { DEFAULT_MODEL_OPTION, clampCodexReasoning } from './shared.js';
10
5
  /**
11
6
  * The `visibility` values that mean "reachable by id, but do not render in a picker".
@@ -182,6 +177,7 @@ export function codexNeedsDangerFullAccessSandbox({}, { platform = process.platf
182
177
  return Boolean(env.WSL_DISTRO_NAME?.trim());
183
178
  }
184
179
  export const codexAgentDef = {
180
+ ...createAgentModelDiscovery('codex', { fallbackModels: () => codexAgentDef.fallbackModels, args: ['debug', 'models'], parse: (input) => codexAgentDef.listModels.parse(input) }),
185
181
  id: 'codex',
186
182
  name: 'Codex CLI',
187
183
  bin: 'codex',
@@ -359,47 +355,14 @@ export const codexAgentDef = {
359
355
  capturesSessionIdFromStream: true,
360
356
  streamFormat: 'json-event-stream',
361
357
  eventParser: 'codex',
362
- // Own dedicated `-i/--image <FILE>` argv flag, built above — a real
363
- // native CLI mechanism, not a workaround. See
364
- // `types.ts#RuntimeAgentDef.imageDelivery`'s doc. Before this, no
365
- // `imageDelivery` was declared at all, which per that field's own
366
- // `undefined` doc means "images are silently dropped exactly as they
367
- // were previously" — confirmed live: `buildArgs` never read the paths,
368
- // and no other def-specific mechanism named them to the model either.
358
+ // Native -i/--image <FILE> arguments carry the paths; see RuntimeAgentDef.imageDelivery.
369
359
  imageDelivery: 'native',
370
- // `'codex-toml'`: Codex CLI's native MCP config is a `[mcp_servers.<name>]` TOML table under
371
- // `CODEX_HOME` (`~/.codex/config.toml` by default) — TOML, not the JSON any of the other four
372
- // wired strategies produce, and `codex mcp add`/`-c mcp_servers.<name>...=` both write to (or
373
- // resolve against) the OPERATOR'S REAL global config, which this driver must never touch on a
374
- // routine agent spawn.
375
- //
376
- // Confirmed against a real installed Codex CLI (0.151.0), not assumed from docs:
377
- // - `codex mcp add`/`codex mcp list` against a scratch `CODEX_HOME` round-tripped the exact
378
- // `[mcp_servers.<name>]` / `command` / `args` / `[mcp_servers.<name>.env]` TOML shape
379
- // `@jini-ai/daemon`'s `buildCodexMcpServerToml` now serializes.
380
- // - Relocating `CODEX_HOME` (env var) to a fresh scratch directory containing a copied
381
- // `auth.json` plus a `config.toml` carrying `[mcp_servers.jini]` produced a normal, fast
382
- // `codex exec --json` turn — no interactive trust prompt, no hang. `-C` pointing at an
383
- // unrelated, untrusted project directory under `--skip-git-repo-check` behaved identically:
384
- // headless `codex exec` never blocks on the "trust this project" prompt that gates
385
- // *auto-discovered* project `.codex/config.toml` (the exact hazard that ruled out
386
- // `claude-mcp-json`'s auto-discovery-based approach for Claude) — it silently records the
387
- // directory as trusted and proceeds.
388
- // - A scratch `CODEX_HOME` with **no** `auth.json` at all does not hang either: the spawned
389
- // CLI fails fast with a structured `turn.failed` stream event carrying a real `401
390
- // Unauthorized`, after a bounded handful of reconnect attempts (~20s) — never an interactive
391
- // login prompt. This is why `prepareCodexHomeForRun`'s `auth.json` copy is allowed to be
392
- // best-effort: a missing/unreadable source credential degrades to an observable run failure,
393
- // never a stuck run.
394
- // - Using the REAL `CODEX_HOME` at all — even read-only via `-c` override flags, never writing
395
- // through `codex mcp add` — was rejected after live testing showed every `codex exec`
396
- // invocation appends a `[projects."<cwd>"]` trust-tracking entry to the real
397
- // `~/.codex/config.toml` as an undocumented side effect of being run at all, regardless of
398
- // `-c` flags. A relocated, run-scoped `CODEX_HOME` (this strategy) is the only mechanism
399
- // that keeps the operator's real config untouched by routine daemon spawns.
400
- //
401
- // See `@jini-ai/daemon`'s `agent-executor.ts` (`prepareCodexHomeForRun`, `buildCodexHomeConfigToml`)
402
- // for the staging/cleanup implementation and `archived provenance ledger` for the full verification transcript.
360
+ // Codex uses [mcp_servers.<name>] TOML under CODEX_HOME. Use a run-scoped home: even read-only
361
+ // -c overrides leave Codex free to append project-trust entries to the operator's real config.
362
+ // A staged config plus best-effort auth.json copy supports headless exec without a trust/login
363
+ // prompt. Missing credentials fail observably through turn.failed instead of blocking a run.
364
+ // The staged shape includes command, args and a nested env table. Staging and cleanup belong
365
+ // to daemon's prepareCodexHomeForRun/buildCodexHomeConfigToml.
403
366
  externalMcpInjection: 'codex-toml',
404
367
  };
405
368
  //# sourceMappingURL=codex.js.map
@@ -15,5 +15,20 @@ export declare const copilotAgentDef: {
15
15
  promptViaStdin: true;
16
16
  streamFormat: string;
17
17
  inactivityTimeoutMs: number;
18
+ discoverModels(requiredArgs: {
19
+ context: import("../model-discovery-types.js").ModelDiscoveryContext;
20
+ }, optionalArgs?: {
21
+ signal?: AbortSignal;
22
+ force?: boolean;
23
+ staleWhileRevalidate?: boolean;
24
+ deps?: import("../model-discovery-types.js").ModelDiscoveryDeps;
25
+ }): Promise<import("../model-discovery-types.js").ModelCatalogSnapshot>;
26
+ resolveDefaultModel(requiredArgs: {
27
+ context: import("../model-discovery-types.js").ModelDiscoveryContext;
28
+ catalog: import("../model-discovery-types.js").ModelCatalogSnapshot;
29
+ }, optionalArgs?: {
30
+ signal?: AbortSignal;
31
+ deps?: import("../model-discovery-types.js").ModelDiscoveryDeps;
32
+ }): Promise<import("../model-discovery-types.js").DefaultModelResolution>;
18
33
  };
19
34
  //# sourceMappingURL=copilot.d.ts.map
@@ -1,15 +1,8 @@
1
- /**
2
- * Ported from OD's `apps/daemon/src/runtimes/defs/copilot.ts` with two
3
- * de-branding edits to comments (no behavior change): a product-named
4
- * prompt-size example reworded to generic phrasing, and a
5
- * product-prefixed operator-override env var name replaced with generic
6
- * phrasing (this package's `types.ts` already documents
7
- * `inactivityTimeoutMs` as "callers may still allow an operator override
8
- * via their own env var"). See `archived provenance ledger` for the exact original
9
- * wording.
10
- */
1
+ import { createAgentModelDiscovery } from '../model-discovery.js';
11
2
  import { DEFAULT_MODEL_OPTION } from './shared.js';
12
3
  export const copilotAgentDef = {
4
+ // UNVERIFIED live integration locally; source/category and limits are documented in model-discovery-adapters.ts.
5
+ ...createAgentModelDiscovery('copilot', { fallbackModels: () => copilotAgentDef.fallbackModels }),
13
6
  id: 'copilot',
14
7
  name: 'GitHub Copilot CLI',
15
8
  bin: 'copilot',
@@ -26,10 +19,8 @@ export const copilotAgentDef = {
26
19
  // per upstream copilot-cli issue #1046 (closed as already supported,
27
20
  // confirmed working on Copilot CLI for `echo "..." | copilot
28
21
  // --model <id>` and `cat prompt.txt | copilot --model <id>`). The
29
- // earlier `-p -` attempt (PR #351) and the argv-bound revert
30
- // (PR #466) both pre-dated that confirmation: `-p -` made Copilot
31
- // interpret `-` as a literal one-character prompt, but omitting
32
- // `-p` entirely is a separate code path that does delegate to
22
+ // `-p -` form is a literal one-character prompt; omitting
23
+ // `-p` entirely is the separate code path that delegates to
33
24
  // stdin under a non-TTY pipe — which is exactly how the daemon
34
25
  // spawns the child (`stdio: ['pipe', 'pipe', 'pipe']`).
35
26
  //
@@ -14,5 +14,20 @@ export declare const crushAgentDef: {
14
14
  } | undefined) => string[];
15
15
  promptViaStdin: true;
16
16
  streamFormat: string;
17
+ discoverModels(requiredArgs: {
18
+ context: import("../model-discovery-types.js").ModelDiscoveryContext;
19
+ }, optionalArgs?: {
20
+ signal?: AbortSignal;
21
+ force?: boolean;
22
+ staleWhileRevalidate?: boolean;
23
+ deps?: import("../model-discovery-types.js").ModelDiscoveryDeps;
24
+ }): Promise<import("../model-discovery-types.js").ModelCatalogSnapshot>;
25
+ resolveDefaultModel(requiredArgs: {
26
+ context: import("../model-discovery-types.js").ModelDiscoveryContext;
27
+ catalog: import("../model-discovery-types.js").ModelCatalogSnapshot;
28
+ }, optionalArgs?: {
29
+ signal?: AbortSignal;
30
+ deps?: import("../model-discovery-types.js").ModelDiscoveryDeps;
31
+ }): Promise<import("../model-discovery-types.js").DefaultModelResolution>;
17
32
  };
18
33
  //# sourceMappingURL=crush.d.ts.map
@@ -1,3 +1,4 @@
1
+ import { createAgentModelDiscovery } from '../model-discovery.js';
1
2
  /**
2
3
  * @module defs/crush
3
4
  *
@@ -12,6 +13,8 @@
12
13
  */
13
14
  import { DEFAULT_MODEL_OPTION } from './shared.js';
14
15
  export const crushAgentDef = {
16
+ // UNVERIFIED live integration locally; source/category and limits are documented in model-discovery-adapters.ts.
17
+ ...createAgentModelDiscovery('crush', { fallbackModels: () => crushAgentDef.fallbackModels }),
15
18
  id: 'crush',
16
19
  name: 'Crush',
17
20
  bin: 'crush',
@@ -34,5 +34,20 @@ export declare const cursorAgentDef: {
34
34
  args: string[];
35
35
  timeoutMs: number;
36
36
  };
37
+ discoverModels(requiredArgs: {
38
+ context: import("../model-discovery-types.js").ModelDiscoveryContext;
39
+ }, optionalArgs?: {
40
+ signal?: AbortSignal;
41
+ force?: boolean;
42
+ staleWhileRevalidate?: boolean;
43
+ deps?: import("../model-discovery-types.js").ModelDiscoveryDeps;
44
+ }): Promise<import("../model-discovery-types.js").ModelCatalogSnapshot>;
45
+ resolveDefaultModel(requiredArgs: {
46
+ context: import("../model-discovery-types.js").ModelDiscoveryContext;
47
+ catalog: import("../model-discovery-types.js").ModelCatalogSnapshot;
48
+ }, optionalArgs?: {
49
+ signal?: AbortSignal;
50
+ deps?: import("../model-discovery-types.js").ModelDiscoveryDeps;
51
+ }): Promise<import("../model-discovery-types.js").DefaultModelResolution>;
37
52
  };
38
53
  //# sourceMappingURL=cursor-agent.d.ts.map
@@ -1,4 +1,4 @@
1
- /** Ported verbatim from OD's `apps/daemon/src/runtimes/defs/cursor-agent.ts` (import path adjusted only). See `archived provenance ledger`. */
1
+ import { createAgentModelDiscovery } from '../model-discovery.js';
2
2
  import { DEFAULT_MODEL_OPTION } from './shared.js';
3
3
  import { agentCapabilities } from '../capabilities.js';
4
4
  export function parseCursorAgentModels({ stdout }) {
@@ -26,6 +26,8 @@ export function parseCursorAgentModels({ stdout }) {
26
26
  return out.length > 1 ? out : null;
27
27
  }
28
28
  export const cursorAgentDef = {
29
+ // UNVERIFIED live integration locally; source/category and limits are documented in model-discovery-adapters.ts.
30
+ ...createAgentModelDiscovery('cursor-agent', { fallbackModels: () => cursorAgentDef.fallbackModels, args: ['models'], parse: (input) => cursorAgentDef.listModels.parse(input) }),
29
31
  id: 'cursor-agent',
30
32
  name: 'Cursor Agent',
31
33
  bin: 'cursor-agent',