@jini-ai/agent-runtime 0.4.1 → 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 (127) hide show
  1. package/CHANGELOG.md +4 -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/qoder-stream.d.ts +0 -3
  119. package/dist/qoder-stream.js +0 -3
  120. package/dist/registry.d.ts +1 -1
  121. package/dist/registry.js +3 -3
  122. package/dist/resolution.js +1 -4
  123. package/dist/role-marker-guard.d.ts +0 -5
  124. package/dist/role-marker-guard.js +0 -5
  125. package/dist/telemetry-sink.d.ts +3 -14
  126. package/dist/types.d.ts +9 -2
  127. package/package.json +27 -6
package/dist/index.js CHANGED
@@ -1,246 +1,14 @@
1
1
  /**
2
2
  * @module @jini-ai/agent-runtime
3
- *
4
- * Public barrel. See `ADS-memory/reports/jini-port/extraction-plan.md` for the target
5
- * architecture and `archived provenance ledger` for full provenance.
6
- *
7
- * This barrel merges two independently-ported trees:
8
- * - the flat `runtimes/` -> agent-runtime TypeScript source (`src/*.ts` +
9
- * `src/defs/*.ts`): the runtime-adapter registry, detection, launch, and
10
- * stream-parser modules;
11
- * - the `agent-protocol/` capability barrel (`src/agent-protocol/**`): the
12
- * ACP + pi-rpc subprocess transport the registry's ACP-based defs call
13
- * into for live model discovery.
14
- *
15
- * Two names are exported by both ported trees under the same identifier
16
- * and are aliased below to avoid a duplicate-export error; see
17
- * archived provenance ledger's "Barrel merge (2026-07-18)" section for the full
18
- * rationale.
19
-
20
- * Archived provenance rationale:
21
- * ### Design decisions (judgment calls)
22
- *
23
- * **1. The ACP subprocess transport (1744 lines) and pi-rpc transport (684 lines) are out of
24
- * scope — `AcpModelProbe` is a fourth port beyond the anticipated trio + vela import.** The
25
- * task brief named the coupled trio (PromptAugmenter/ArtifactTaxonomy/TelemetrySink) plus the
26
- * single vela import in `detection.ts` as "the only real judgment-call work". In practice,
27
- * `defs/shared.ts` also imports `detectAcpModels` from OD's top-level ACP transport module —
28
- * the full ACP JSON-RPC handshake protocol (session/new, session/list_models, …), used by 8 of
29
- * the 24 def literals (devin, hermes, kilo, kimi, kiro, reasonix, trae-cli, vibe) as their
30
- * `fetchModels` implementation. `r1-daemon.md` itself classifies OD's `agent-protocol/` (the
31
- * ACP + pi-rpc subprocess layer, 17 files) as its OWN separate GENERIC-ENGINE extraction
32
- * target, not part of `runtimes/`'s file scope — porting 2400+ lines of a distinct subsystem
33
- * into this task would have blown "harvest wholesale" far past what was asked. So
34
- * `detectAcpModels` becomes `AcpModelProbe` (interface + no-op default + module-level
35
- * `setAcpModelProbe()` installer), mirroring the `AmrProfileResolver` pattern the brief already
36
- * asked for. Every ACP-based def's `fetchModels` keeps calling `detectAcpModels(...)` unchanged
37
- * (via `defs/shared.ts`'s re-export) — with the no-op probe installed, they degrade to "no live
38
- * models" and fall back to `fallbackModels`, exactly like a real vela/ACP timeout would. Proven
39
- * wired end-to-end in `ports.test.ts` (`setAcpModelProbe(stub)` then calling
40
- * `devinAgentDef.fetchModels(...)` directly and asserting the stub was reached).
41
- *
42
- * **2. `env.ts` needed the same port treatment as the coupled trio, despite being listed as a
43
- * "supporting generic file".** The real `runtimes/env/env.ts` reads OD's `app-config.js` (for
44
- * an installation-id analytics identity env var, gated on a telemetry-consent flag), OD's
45
- * `sandbox-mode.ts`, and a vela-specific profile-forwarding module, and hardcodes the origin
46
- * product's own identity string as an `AMR_CLIENT_SOURCE` env value plus a product-prefixed
47
- * data-dir-derived temp-home path. None of that is generic. `spawnEnvForAgent` keeps its real,
48
- * generic behavior (proxy-aware merge via `@jini/platform`, OpenCode/MiMo
49
- * project-config-discovery disabling, AMR's `HOME`/`VELA_OPENCODE_BIN` backfill) and gains two
50
- * optional hooks — `perAgentEnv` and `sandboxOverlay` — so a host can re-attach its own
51
- * vela/sandbox-specific behavior without this package needing to import OD's
52
- * app-config/sandbox-mode/vela-profile modules. OD's AMR trace-env helper (a small function
53
- * whose whole purpose was emitting a product-prefixed trace-correlation env triad) is dropped
54
- * entirely, not ported — it is inherently OD/vela-adapter-owned and has no generic equivalent
55
- * to keep.
56
- *
57
- * **3. `reasonix.ts`'s design-instructions constant is a real strip, not a comment reword.**
58
- * Unlike every other def literal (pure declarative CLI-adapter config), OD's `reasonix.ts`
59
- * injected a hardcoded system-prompt block via `env.REASONIX_ACP_SYSTEM_APPEND` that literally
60
- * told the model it was running inside the host product and instructed it to wrap output in
61
- * that product's own artifact-tag convention. That is genuine product-specific prompt content
62
- * smuggled into what the task brief assumed was a pure literal. It is dropped; a host wanting
63
- * equivalent behavior should compose it via `PromptAugmenter.systemOverlay` and merge the result
64
- * into this def's `env.REASONIX_ACP_SYSTEM_APPEND` itself (the engine has no generic mechanism
65
- * to know a given def has an env-based system-prompt hook — that's inherently a reasonix-specific
66
- * integration detail the host must wire).
67
- *
68
- * **4. `registry/local-profiles.ts` (the user-configurable local-agent-profile-file loader) is
69
- * deliberately not ported.** The task's own scope description for `registry.ts` names only
70
- * "`BASE_AGENT_DEFS` array + dup-id guard + `getAgentDef(id)`" — it does not mention
71
- * local-profile merging. The real file also turned out to be far more coupled than a
72
- * "supporting generic file" would suggest: it reads a product-prefixed config-path override env
73
- * var, falls back to a product-branded default path under the user's home directory, reads a
74
- * product-prefixed data-dir env var, and depends on OD's daemon-level `sandbox-mode.ts`
75
- * subsystem entirely outside this package's charter. Rather than either violate the explicit
76
- * scope or half-port a coupled file, it's left out; `AGENT_DEFS` here is exactly
77
- * `BASE_AGENT_DEFS`. Flagged as a real follow-up: a future task could reintroduce a de-branded,
78
- * sandbox-free local-profile loader as an injected port (e.g. a `LocalProfileSource` interface)
79
- * if a consumer needs runtime-configurable custom agent defs.
80
- *
81
- * **5. `amr/amr-model-probe.ts` (the other file in OD's `runtimes/amr/` subdir) is not ported;
82
- * only `amr/amr-model-cache.ts` is.** `amr-model-probe.ts`'s `resolveAmrModelProbe` composes
83
- * `launch`/`env`/`registry` (all in-scope) with OD's `app-config.js` (`readAppConfig`,
84
- * persisted settings) and a vela-integration module's credential-revision reader (both
85
- * out-of-scope OD subsystems) to build a cache key + spawn env for probing AMR's live model
86
- * catalog. This is daemon-level composition glue, not a pure CLI-adapter concern, and the task
87
- * brief never named `runtimes/amr/` in its explicit scope. `AmrModelLoadingCache` (the reusable
88
- * generic caching *pattern*) is kept; the OD-app-config-coupled probe-composition function is
89
- * not. A host wiring AMR needs to build its own equivalent of `resolveAmrModelProbe` using its
90
- * own config/credential ports plus this package's `AmrModelLoadingCache` + `resolveAgentLaunch`
91
- * + `spawnEnvForAgent`.
92
- *
93
- * **6. `chat-prompt-inputs.ts` is entirely OD-product prompt content, not partially generic —
94
- * confirmed after reading the full 938-line file.** Beyond the design-system-selection
95
- * functions r1b explicitly named (`resolveEffectiveDesignSystemSelection`,
96
- * `designSystemIdFromPluginSnapshot`, `formatDesignFilesWorkspaceHint`), the file also contains
97
- * comment-attachment rendering (OD's "attached preview comments" annotation feature), Codex
98
- * image-generation prompt overrides (OD's media-generation feature), and a research-command-
99
- * contract composer (OD's "research" feature) — every one of them product-specific, none of
100
- * them a generic prompt-composition mechanism. Per the task's explicit instruction ("do NOT
101
- * lift the OD logic itself"), none of it is ported; `PromptAugmenter` is the injection seam in
102
- * full.
103
- *
104
- * ### Product-neutral seams (design decisions)
105
- *
106
- * The task brief identified four real OD coupling points to port-inject; a fifth (literal `promoted_by` strings) and a build-config note surfaced during the coverage-driven pass. Each below follows this codebase's existing DI/port convention (`packages/core/src/pack.ts`'s small explicit interfaces, `packages/daemon/archived provenance ledger`'s injected-collaborator framing) — a small named interface, a default no-op implementation, injected via caller options, not a kitchen-sink object.
107
- *
108
- * **1. `AccountFailureClassifier` (`acp/account-failure.ts`).** OD's `acp/updates.ts` imported `classifyAmrAccountFailure`/`amrAccountFailureDetails` directly from `../../integrations/vela-errors.js` — a real AMR/vela-branded text classifier with a hardcoded `https://open-design.ai/amr/wallet?source=open_design` recharge URL literal (read in full from `/tmp/od-source`). That URL alone makes the file impossible to port verbatim. The replacement is a two-method-shaped port (`AccountFailureClassifier.classify(text): AccountFailure | null`) with fields named generically (`code`/`message`/`action`/`actionUrl`, not AMR's field names) so any provider's classifier can satisfy it. `promotedAmrRetryStatusPayload`/`promotedAmrStderrPayload` (kept their AMR-referencing names, per the task brief's own framing of "the two call sites are `promotedAmrRetryStatusPayload(update)` and `promotedAmrStderrPayload(chunk)`" — AMR is a routing/vendor concept the task treated as out of scope to rename, unlike the literal `'open-design'` string) now take a `classifier` parameter defaulting to `noopAccountFailureClassifier` (always returns `null`). This reproduces "the feature doesn't exist" for any caller that doesn't inject a real classifier — verified by dedicated tests exercising both the no-op default and an injected matching classifier in `acp/updates.test.ts` and `acp/session.test.ts`. A future OD adapter package (not this task) would implement the real vela-backed classifier and inject it.
109
- *
110
- * **2. `ExecutionProfile` inlined (`acp/types.ts`).** OD's `acp/session.ts` imported `type ExecutionProfile from '@open-design/contracts'`. The real type, read from `/tmp/od-source/packages/contracts/src/execution-profile.ts`, is `export type ExecutionProfile = 'filesystem' | 'text_artifact';` plus one small helper function this port does not need (`executionProfileFromStreamFormat`, an OD-stream-format-specific mapper not used by `acp/session.ts` itself). Importing an entire external package for a two-value literal union would be the tail wagging the dog, so it's inlined as a local exported type instead.
111
- *
112
- * **3. Client-name / env-var de-branding.** Two literal `'open-design'`-prefixed defaults (`acp/session.ts`'s `clientName = 'open-design'` → `'agent-runtime'`; `acp/models.ts`'s `clientName = 'open-design-detect'` → `'agent-runtime-detect'`) and one hardcoded env var name (`acp/json.ts`'s `resolveAcpTimeoutMs` reading `env.OD_ACP_TIMEOUT_MS` → an optional `envVarName` parameter, default `'AGENT_RUNTIME_ACP_TIMEOUT_MS'`). All three are harmless-to-rename ACP protocol/runtime details (a handshake `clientInfo.name` value, a timeout knob), not behavior changes. **Extended beyond the task brief's explicit list**: three `promoted_by: 'open_design_acp...'` marker-string *values* (not just doc comments) found in `acp/rpc.ts` and `acp/updates.ts` during the audit — these don't match the literal grep patterns the task specified (`open-design` has a hyphen; the marker strings use an underscore, `open_design_acp`), but are clearly the same class of product-identity leak in spirit, so they were renamed too (`agent_runtime_acp`, `agent_runtime_acp_retry_status`, `agent_runtime_acp_stderr_retry_status`) and called out explicitly here rather than silently fixed.
113
- *
114
- * **4. `resolveAcpTimeoutMs`'s env var name.** Covered under seam 3 above; listed separately in the task brief as its own numbered item, so cross-referenced here for clarity.
115
- *
116
- * **5. Doc-comment / prose rewording.** "Open Design", `OD_ACP_STAGE_TIMEOUT_MS`, `OD_ACP_TIMEOUT_MS`, and `server.ts` (an OD-specific file path with no Jini equivalent) references in JSDoc/inline comments across `acp/constants.ts`, `acp/json.ts`, `acp/rpc.ts`, `acp/updates.ts`, and `acp/session.ts` were reworded to generic language (e.g., "a structured error object", "a host application may resolve its own branded environment variable"). The `text-suppression.ts` port additionally needed this treatment in its own new `@module` docblock (see next item) and one internal comment referencing this skill's coverage-discipline convention by a path that itself contains the substring `open-design` (`ADS-memory/reports/jini-port/skills/fixing-open-design.md`) — reworded to avoid the literal path.
117
- *
118
- * **6. `text-suppression.ts`'s two dropped dead functions.** `possibleDsmlArtifactOpenStart` and `possibleArtifactCloseStart` are declared in the origin file but never called anywhere in it (confirmed by `grep -n` across the full origin file — zero call sites, not exported). The task brief said "port this file verbatim," but keeping genuinely dead, unreachable, unexported code would force a choice between a contrived test asserting nothing real, or a coverage-suppression comment — both of which `ADS-memory/reports/jini-port/skills/fixing-open-design.md`'s Phase 6.5 explicitly rules out ("a hard-to-cover branch is a refactor signal, not something to suppress"). Dropped instead; this is the one deliberate "not quite verbatim" deviation in an otherwise byte-for-byte port of that file.
119
- *
120
- * **7. Four dead-branch removals in `acp/session.ts` and one in `core/json-line-stream.ts`'s `flush()`, plus three `noUncheckedIndexedAccess`-guard-to-non-null-assertion conversions across `core/json-line-stream.ts`, `pi-rpc/models.ts`, and `pi-rpc/session.ts`.** These surfaced only during the coverage-driven pass (Phase 6.5), not from the OD-coupling analysis — each is a genuinely unreachable branch given the *current* call graph, not a speculative "this could never happen" guess:
121
- * - `core/json-line-stream.ts`'s `flush()` had a defensive re-emit-and-clear on a leftover `pendingJson` candidate; proven dead because `pendingJson` is only ever retained when `classifyJsonCandidate` most recently judged it `'incomplete'`, and a 200,000-trial fuzz (random truncated valid-JSON fragments) found zero cases where `classifyJsonCandidate` says `'incomplete'` while `JSON.parse` on the identical string would actually succeed — so a bare re-attempt at end-of-stream could never succeed either.
122
- * - `core/json-line-stream.ts`'s `closeFrame` helper carried a `!current || current.kind !== kind` mismatch guard; proven dead because every one of its 4 call sites is already nested inside a branch that established the popped frame's kind, confirmed by a 2,000,000-trial adversarial fuzz (malformed bracket sequences) finding zero mismatches.
123
- * - `acp/session.ts`'s `failWithPayload` and `finishCleanPrompt` each carried their own `if (finished) return;` re-entry guard; both have call sites entirely nested inside the parser callback's own `if (aborted || finished) return;` at that callback's top, or (for the stderr-promotion call site) the stderr handler's own equivalent guard — so neither function can actually be invoked a second time once `finished` is true. **Contrast**: `fail()`'s own `if (finished) return;` guard was *kept*, because it has two call sites (`child.on('error', ...)` and `stdin.on('error', ...)`) with no pre-check of their own — genuinely reachable, and a real test (`acp/session.test.ts`) exercises it by emitting a stdin error followed by a child-process error.
124
- * - `acp/session.ts`'s parser callback had a second, inline `if (finished) return;` inside its RPC-error-handling block, fully redundant with the same callback's own top-of-function check three lines earlier (nothing between them can flip `finished`) — removed.
125
- * - `acp/session.ts`'s `emitVisibleTextDelta` carried an `if (!delta) return;` guard; all three call sites already guard against an empty delta before calling it (`if (flushedText) {...}`, `if (outputDelta) {...}`, and the plain-else branch which is only reached after an earlier `if (!toolCallStrippedDelta) return;` already ruled out emptiness).
126
- * - `pi-rpc/models.ts` (`if (line === undefined) continue;`, `if (provider === undefined || modelId === undefined) continue;`) and `pi-rpc/session.ts` (`changed[0]?.path ?? null`) each had a `noUncheckedIndexedAccess`-driven guard around an array index that the enclosing loop bound / length check already guarantees is defined — converted to a documented non-null assertion (`fixing-open-design.md` Phase 6.5's fourth classification bucket: "TS-required fallback with no real runtime path").
127
- *
128
- * Every removal is accompanied by an inline comment in the source explaining the reachability proof, and none change observable behavior for any input reachable through the public API — verified by re-running the full test suite (450 tests) after each change.
129
- *
130
- * ## Barrel merge (2026-07-18)
131
- *
132
- * `packages/agent-runtime/` was independently built out from an empty stub on
133
- * two separate branches: `port/agent-runtime-from-runtimes` (merged to `main`
134
- * as PR #24, the "runtimes/" section above) and
135
- * `port/agent-protocol-toolexecutor-daemoncore` (this PR, the
136
- * "agent-protocol/" section above). Merging `main` into the latter conflicted
137
- * on the shared package scaffolding (`package.json`, this file, `src/index.ts`,
138
- * `tsconfig.json`, `vitest.config.ts`) since both branches independently
139
- * created it — not on either side's actual ported content, which is disjoint
140
- * (`src/agent-protocol/**` vs. everything else under `src/`).
141
- *
142
- * **`package.json`**: merged `dependencies` (`@jini/platform`, from the
143
- * `runtimes/` port's `invocation.ts`/`executables.ts`/`env.ts`) and
144
- * `devDependencies` (`@vitest/coverage-v8`, from the `agent-protocol/` port)
145
- * into one list; kept the `runtimes/` port's `test:coverage` script.
146
- *
147
- * **`tsconfig.json`** / **`vitest.config.ts`**: both sides independently
148
- * excluded `src/skills/**` (needed — one skill,
149
- * `chat-motion-overlay`, ships a self-contained Remotion template with its own
150
- * `.ts`/`.tsx` files that aren't part of this package's own compilation/test
151
- * surface); only the `runtimes/` side also excluded `src/craft/**` (a no-op
152
- * today since `craft/` is markdown-only, but kept for explicitness as content
153
- * grows). Merged to exclude both directories in both files. `vitest.config.ts`
154
- * also merged `include` (`src/**`, the broader of the two — the
155
- * `agent-protocol/`-scoped `src/agent-protocol/**` from this PR was a subset)
156
- * and merged the type-only-file coverage carve-outs (`src/types.ts` from the
157
- * `runtimes/` port, `src/agent-protocol/acp/types.ts` from this PR) into one
158
- * `exclude` list. Coverage `thresholds` differed (this PR: 99/99/99/99; the
159
- * `runtimes/` port: 99.9/99.9/99.9/99.9) — set to 99 on all four metrics,
160
- * matching the documented floor in `ADS-memory/reports/jini-port/skills/fixing-open-design.md`
161
- * Phase 6.5 (">=99% ... 100% as the actual goal"), and verified against the
162
- * actual merged coverage run (see this package's own CI/PR validation output
163
- * for the authoritative merged numbers, same as the `runtimes/` section's own
164
- * "Independent re-verification pass" above).
165
- *
166
- * **`src/index.ts`**: merged both barrels' export statements. Two real name
167
- * collisions were found between the two ported trees (verified via a
168
- * top-level `export (function|const|class|interface|type) <name>` scan across
169
- * both trees, not just an alphabetical-ordering artifact of the merge) and
170
- * resolved by aliasing rather than dropping either side:
171
- *
172
- * 1. **`detectAcpModels`.** This PR's `src/agent-protocol/acp/models.ts`
173
- * exports the REAL ACP subprocess transport: it spawns the CLI and performs
174
- * the actual `initialize` + `session/new` JSON-RPC handshake to fetch live
175
- * models. The `runtimes/` port's `src/acp-model-probe.ts` (see that
176
- * section's Design decision 1) *also* exports a function named
177
- * `detectAcpModels` — but it is an injectable, no-op-by-default seam
178
- * (`AcpModelProbe.detectModels`) that `defs/shared.ts` re-exports and 8 def
179
- * literals (devin, hermes, kilo, kimi, kiro, reasonix, trae-cli, vibe) call
180
- * as their `fetchModels` implementation, because at the time that branch
181
- * was written the real ACP transport did not yet exist in this package (it
182
- * was a separate, not-yet-ported subsystem — see that section's Design
183
- * decision 1). Now that the real transport IS present, both are kept:
184
- * the plain `detectAcpModels` name is bound to the real transport (from
185
- * `agent-protocol/`, arguably the more generally useful public name for an
186
- * external consumer), and `acp-model-probe.ts`'s seam function is
187
- * re-exported as `probeAcpModels` instead. **Not touched**: `defs/shared.ts`
188
- * still imports its own `detectAcpModels` directly from
189
- * `./acp-model-probe.js` (a same-package file import, unaffected by the
190
- * barrel-level alias) — the 8 ACP-based def literals' `fetchModels` still
191
- * resolve to the no-op-by-default seam exactly as before this merge. Wiring
192
- * those defs' `fetchModels` to the real transport instead (i.e., calling
193
- * `setAcpModelProbe()` with an adapter over `agent-protocol`'s
194
- * `detectAcpModels`) is a real, valuable follow-up this merge deliberately
195
- * does not attempt — it is new integration work, not a conflict-resolution
196
- * choice, and needs its own scoped task with its own tests (the two
197
- * functions' request/response shapes are structurally similar but not
198
- * identical: `AcpModelProbeRequest`/`RuntimeModelOption` vs.
199
- * `DetectAcpModelsOptions`/`ModelOption`).
200
- * 2. **`parsePiModels`.** Both ports independently lifted the identical OD
201
- * origin function (`apps/daemon/src/pi-rpc.ts#parsePiModels`, a pure
202
- * string-parsing function with no transport dependency) into two different
203
- * files: the `runtimes/` port's standalone `src/pi-models.ts` (used
204
- * internally by `defs/shared.ts` for the `pi` CLI's own model listing) and
205
- * this PR's `src/agent-protocol/pi-rpc/models.ts` (part of the
206
- * patch-mirrored `agent-protocol/` subtree, used internally by
207
- * `pi-rpc/session.ts`). Confirmed byte-for-logic-identical (same
208
- * line-parsing algorithm, same `DEFAULT_MODEL_OPTION` shape, same
209
- * dedup-by-`provider/modelId` behavior; only cosmetic differences — return
210
- * type name `PiModelOption` vs. `RuntimeModelOption`, and
211
- * non-null-assertion vs. `undefined`-check style for the
212
- * `noUncheckedIndexedAccess` guard). `pi-models.ts`'s copy keeps the plain
213
- * `parsePiModels` name (it is the one with real internal consumers reached
214
- * through this package's own barrel-adjacent re-export chain); the
215
- * `agent-protocol/pi-rpc` copy is re-exported as `parsePiRpcModels`
216
- * instead. Neither internal consumer (`defs/shared.ts`, `pi-rpc/session.ts`)
217
- * was touched — both import their own local copy by direct file path, not
218
- * through the package barrel, so the alias only affects the barrel's public
219
- * surface, not either port's internal behavior.
220
- * `src/index.test.ts` was extended (not just left as the pre-merge,
221
- * `agent-protocol/`-only assertions) to prove both aliases resolve to two
222
- * distinct, real functions (`not.toBe`) and that the two independent
223
- * `parsePiModels`/`parsePiRpcModels` ports still agree on output for the
224
- * same input, backing up the "verified byte-for-logic-identical" claim
225
- * above with an executable assertion rather than only a source-reading one.
226
- *
227
- * No other export names collided (`ModelOption` vs. `RuntimeModelOption`,
228
- * `AttachAcpSessionOptions`, `AccountFailure`/`AccountFailureClassifier`, the
229
- * 24 `*AgentDef` def-literal exports, etc. are all distinctly named across the
230
- * two trees).
231
- *
232
- * **`packages/platform/src/index.ts`**: the two sides added disjoint modules
233
- * (this PR's `home-expansion.ts`/`sandbox-env.ts`/`resource-paths.ts`/
234
- * `terminal.ts`, from the "flat generic daemon primitives" part of this PR's
235
- * scope, vs. `main`'s unrelated `download.ts` from a different, already-merged
236
- * PR) — no name collisions; both sides' export blocks and module-doc bullet
237
- * list entries were concatenated as-is.
238
- *
239
- * **`pnpm-lock.yaml`**: not hand-merged; `origin/main`'s version was accepted
240
- * to resolve the conflict marker, then `CI=true pnpm install` was run from the
241
- * repo root to regenerate it from the merged `package.json` files.
3
+ * Public runtime catalog, detection, launch and stream parsers plus ACP/pi-rpc transports.
4
+ * Host-specific prompt, sandbox/environment, telemetry, account-failure and profile behavior
5
+ * enters through the ports documented at each owner, never through a product dependency.
6
+ * Skills/craft are content, not runtime compilation inputs: skill bundles can contain standalone
7
+ * templates with their own TypeScript dependencies.
8
+ * Alias contracts are documented beside their exports below; internal consumers import their
9
+ * local implementations directly, so barrel aliases do not redirect those calls.
242
10
  */
243
- // Core contract + vendored diagnostic types.
11
+ // Core contract and diagnostic types.
244
12
  export * from './types.js';
245
13
  // Generic supporting modules.
246
14
  export * from './paths.js';
@@ -278,56 +46,30 @@ export * from './defs/index.js';
278
46
  // from `./types.js` rather than redefining a second, looser copy; its own
279
47
  // `ModelOption` is exported here as `ModelCatalogOption` since the plain
280
48
  // `ModelOption` name is already owned by `agent-protocol/acp/models.ts`'s
281
- // narrower ACP-probe shape re-exported below. See archived provenance ledger.
49
+ // narrower ACP-probe shape re-exported below.
282
50
  export * from './model-registry.js';
283
- // Stream parsers. Each handler's event union is exported alongside it — previously only
284
- // `Record<string, unknown>` was visible to a consumer outside this package, which is how a real
285
- // external integration guessed a nonexistent field name (`event.text`) and silently lost every
286
- // streamed token instead of getting a compile error. `json-event-stream.ts`'s
287
- // `createJsonEventStreamHandler` is the one parser NOT given this treatment here: it is a
288
- // generic multi-CLI parser (`ParserKind`-dispatched, ~40 emission sites across many wire
289
- // formats), and typing it accurately is a larger, separate task than this pass covers.
51
+ // Stream parsers expose their event unions so consumers cannot guess nonexistent payload fields.
52
+ // json-event-stream remains a generic ParserKind-dispatched parser with Record<string, unknown>;
53
+ // an accurate union across its many CLI formats requires a separate contract decision.
290
54
  export { createClaudeStreamHandler } from './claude-stream.js';
291
55
  export { createJsonEventStreamHandler } from './json-event-stream.js';
292
56
  export { createQoderStreamHandler } from './qoder-stream.js';
293
57
  export { createCopilotStreamHandler } from './copilot-stream.js';
294
- // Ports (injected seams — see each module's doc comment for what OD logic it replaces).
58
+ // Host-injected seams; each owner documents its contract.
295
59
  export * from './amr-profile-resolver.js';
296
- // `detectAcpModels` collides by name with the real ACP transport re-exported
297
- // below from `./agent-protocol/index.js`. This module's own `detectAcpModels`
298
- // is a no-op-by-default injectable seam (used internally by
299
- // `defs/shared.ts` for 8 ACP-based def literals so they don't need to
300
- // depend on the full ACP transport) — aliased to `probeAcpModels` here so
301
- // the real transport keeps the plain name. See archived provenance ledger.
60
+ // `probeAcpModels` is the replaceable probe used by defs/shared.ts; the native ACP transport
61
+ // keeps `detectAcpModels`. See acp-model-probe.ts for defaults and injection behavior.
302
62
  export { noopAcpModelProbe, setAcpModelProbe, detectAcpModels as probeAcpModels, } from './acp-model-probe.js';
303
- // `parsePiModels` is exported under its plain name from this standalone
304
- // module (it has real internal consumers in this package: `defs/shared.ts`
305
- // / the `pi` def). `agent-protocol/pi-rpc`'s own copy of the identical OD
306
- // origin function is aliased to `parsePiRpcModels` below to avoid the
307
- // barrel-level name clash.
63
+ // Runtime defs use `parsePiModels`; the protocol parser is exported as `parsePiRpcModels`
64
+ // below to avoid a public-name collision while preserving both consumers' contracts.
308
65
  export * from './pi-models.js';
309
66
  export * from './prompt-augmenter.js';
310
67
  export * from './artifact-taxonomy.js';
311
68
  export * from './telemetry-sink.js';
312
69
  // LLM-provider integrations (BYOK model catalogs, OAuth+PKCE, gateway helpers).
313
70
  export * from './providers/index.js';
314
- /** @jini-ai/agent-runtime — public barrel (agent-protocol/ half).
315
- * Re-exports the agent-protocol/ capability barrel's public surface (ACP +
316
- * pi-rpc subprocess protocol adapters over a shared JSON-line-stream core).
317
- * See src/agent-protocol/README.md and archived provenance ledger for provenance.
318
- *
319
- * Two of this barrel's exports collide by name with the `runtimes/`-ported
320
- * modules above and are aliased here (see archived provenance ledger's "Barrel merge"
321
- * section for the full reasoning):
322
- * - `detectAcpModels` — the REAL ACP subprocess transport (spawns the CLI,
323
- * performs the `initialize` + `session/new` JSON-RPC handshake). Kept
324
- * under its plain name; `acp-model-probe.ts`'s same-named seam function
325
- * is aliased to `probeAcpModels` above instead.
326
- * - `parsePiModels` — aliased to `parsePiRpcModels` below. Both this file's
327
- * copy and the standalone `pi-models.ts` copy exported above are
328
- * independent, verified-identical ports of the same OD origin function
329
- * (`apps/daemon/src/pi-rpc.ts#parsePiModels`); `pi-models.ts`'s copy keeps
330
- * the plain name since it has real internal consumers in this package.
331
- */
71
+ /** ACP + pi-rpc protocol adapters over the shared JSON-line-stream core. See aliases above. */
332
72
  export { createJsonLineStream, buildAcpSessionNewParams, normalizeModels, detectAcpModels, attachAcpSession, noopAccountFailureClassifier, mapPiRpcEvent, attachPiRpcSession, parsePiModels as parsePiRpcModels, } from './agent-protocol/index.js';
73
+ export * from './model-discovery.js';
74
+ export { defaultModelDiscoveryDeps, parseClaudeInitializeMetadata, parsePiRpcMetadata } from './model-discovery-adapters.js';
333
75
  //# sourceMappingURL=index.js.map
@@ -24,35 +24,15 @@ function stringifyContent(value) {
24
24
  return JSON.stringify(value);
25
25
  }
26
26
  catch {
27
- // Genuinely unreachable through this module's real call graph, not just
28
- // unobserved: every one of this function's 8 call sites passes either
29
- // `obj` itself or a field/subfield of `obj` (e.g. `statePart.output`,
30
- // `obj.content`, `item.aggregated_output`), and `obj` is only ever
31
- // produced one way in this file — `handleLine`'s `obj = JSON.parse(line)`
32
- // (this module's sole exported entry point, `createJsonEventStreamHandler`,
33
- // routes every event through it). A value that came out of `JSON.parse`
34
- // can only be `null`/a string/a plain finite number/a boolean/an array/a
35
- // plain object — the JSON grammar has no circular-reference or BigInt
36
- // production — so `JSON.stringify` can never throw on it or on any of
37
- // its nested fields. Kept (not deleted) as protection against a future
38
- // caller that feeds this module data from somewhere other than
39
- // `JSON.parse`, the same "keep the defensive branch, document it, don't
40
- // force a test around impossible data" call `@jini-ai/cli`'s
41
- // `defaultReadFile`'s `finish()` guard made on 2026-07-22 — see
42
- // `archived provenance ledger`'s 2026-07-22 entry for the full re-derivation.
27
+ // Current callers pass JSON.parse results or their fields, which cannot contain cycles or
28
+ // BigInts, so stringify cannot throw. Keep this fallback for future non-JSON callers without
29
+ // forcing a coverage test around data the current parser cannot produce.
43
30
  return String(value);
44
31
  }
45
32
  }
46
33
  function parseJsonObjectsFromContent(value) {
47
- // No `!trimmed` early-return: this function's only real call site
48
- // (`connectorToolSelectionErrorMessage`, below) has already checked
49
- // `content.includes('CONNECTOR_TOOL_NOT_FOUND')` before calling in, so
50
- // `value` can never trim down to empty here. The guard was dead code for
51
- // every real caller; removed rather than padded with a test, since the
52
- // fallback path below already produces the same `[]` result for an empty
53
- // string on its own (safeParseJson('') throws -> null -> not a record;
54
- // ''.split(/\r?\n/u) yields [''] -> same outcome), so nothing changes
55
- // for a hypothetical future caller either.
34
+ // The caller requires CONNECTOR_TOOL_NOT_FOUND before parsing. Empty input also reaches the
35
+ // existing [] fallback naturally, so no separate empty-string branch is needed.
56
36
  const trimmed = value.trim();
57
37
  const direct = safeParseJson(trimmed);
58
38
  if (isRecord(direct))
@@ -225,7 +205,8 @@ function handleOpenCodeEvent(obj, onEvent, state) {
225
205
  }
226
206
  return false;
227
207
  }
228
- function handleGeminiEvent(obj, onEvent, state) {
208
+ // Retain the neutral legacy wire decoder for stored streams; no CLI agent uses this kind.
209
+ function handleLegacyGoogleStreamEvent(obj, onEvent, state) {
229
210
  if (!isRecord(obj))
230
211
  return false;
231
212
  const isAssistantTextMessage = obj.type === 'message' &&
@@ -298,7 +279,7 @@ function handleGeminiEvent(obj, onEvent, state) {
298
279
  }
299
280
  if (obj.type === 'error') {
300
281
  const severity = typeof obj.severity === 'string' ? obj.severity.toLowerCase() : '';
301
- const message = extractErrorMessage(obj.message ?? obj.error, severity === 'warning' ? 'Gemini CLI warning' : 'Gemini CLI error');
282
+ const message = extractErrorMessage(obj.message ?? obj.error, severity === 'warning' ? 'Google stream warning' : 'Google stream error');
302
283
  if (severity === 'warning') {
303
284
  onEvent({ type: 'status', label: 'warning', detail: message });
304
285
  }
@@ -311,7 +292,7 @@ function handleGeminiEvent(obj, onEvent, state) {
311
292
  if (obj.status === 'error' || isRecord(obj.error)) {
312
293
  onEvent({
313
294
  type: 'error',
314
- message: extractErrorMessage(obj.error, 'Gemini CLI error'),
295
+ message: extractErrorMessage(obj.error, 'Google stream error'),
315
296
  raw: stringifyContent(obj),
316
297
  });
317
298
  return true;
@@ -884,9 +865,22 @@ export function createJsonEventStreamHandler({ kind, onEvent }) {
884
865
  onEvent({ type: 'raw', line });
885
866
  return;
886
867
  }
868
+ // Preserve structured model receipts before vendor event translation. These fields describe
869
+ // session/turn/assistant-message metadata; generated text is never used for model identity.
870
+ if (obj && typeof obj === 'object' && !Array.isArray(obj)) {
871
+ const frame = obj;
872
+ const properties = frame.properties;
873
+ const info = frame.type === 'message.updated' ? properties?.info : undefined;
874
+ if (info?.role === 'assistant' && typeof info.modelID === 'string') {
875
+ onEvent({ type: 'status', label: 'model', model: info.providerID ? `${info.providerID}/${info.modelID}` : info.modelID });
876
+ }
877
+ if (typeof frame.model === 'string' && ['session.created', 'thread.started', 'turn.started', 'model.changed'].includes(String(frame.type))) {
878
+ onEvent({ type: 'status', label: 'model', model: frame.model });
879
+ }
880
+ }
887
881
  if (kind === 'opencode' && handleOpenCodeEvent(obj, onEvent, state))
888
882
  return;
889
- if (kind === 'gemini' && handleGeminiEvent(obj, onEvent, state))
883
+ if (kind === 'legacy-google-stream-json' && handleLegacyGoogleStreamEvent(obj, onEvent, state))
890
884
  return;
891
885
  if (kind === 'kimi' && handleKimiEvent(obj, onEvent))
892
886
  return;
package/dist/launch.js CHANGED
@@ -1,10 +1,6 @@
1
1
  /**
2
2
  * @module launch
3
- *
4
- * Turns a resolved agent executable into a launchable process: launch-path
5
- * resolution (including Codex's native-binary-vs-node-wrapper detection)
6
- * and PATH env application for the spawned child. Ported verbatim from
7
- * OD's `apps/daemon/src/runtimes/launch.ts` — no product coupling.
3
+ * Resolve a launchable process, including Codex native-binary/node-wrapper selection and child PATH.
8
4
  */
9
5
  import { accessSync, closeSync, constants, openSync, readdirSync, readSync, realpathSync, statSync } from 'node:fs';
10
6
  import path, { delimiter } from 'node:path';
package/dist/log-file.js CHANGED
@@ -17,11 +17,6 @@
17
17
  * itself with its own flags). Only the containing directory is created, and
18
18
  * `mkdtemp` gives it `0o700` — which is the actual confidentiality control
19
19
  * here, since the CLI, not this module, decides the log file's own mode.
20
- *
21
- * No OD provenance: OD's daemon derived antigravity's `--log-file` path
22
- * inline in `server.ts` rather than through a reusable helper. Extracted as
23
- * one here so the staging is testable on its own and so a second adapter with
24
- * a log-file flag needs no new code — see `archived provenance ledger`.
25
20
  */
26
21
  import { promises as fs } from 'node:fs';
27
22
  import os from 'node:os';
package/dist/metadata.js CHANGED
@@ -35,10 +35,6 @@ export const DEFAULT_AGENT_INSTALL_LINKS = {
35
35
  installUrl: 'https://cursor.com/docs/cli/overview',
36
36
  docsUrl: 'https://docs.cursor.com/en/cli/overview',
37
37
  },
38
- gemini: {
39
- installUrl: 'https://github.com/google-gemini/gemini-cli',
40
- docsUrl: 'https://geminicli.com/docs/',
41
- },
42
38
  qwen: {
43
39
  installUrl: 'https://github.com/QwenLM/qwen-code',
44
40
  docsUrl: 'https://qwenlm.github.io/qwen-code-docs/en/index',
@@ -1,11 +1,7 @@
1
1
  /**
2
2
  * @module mmd-routes
3
- *
4
- * Loads a user-configurable "model routes" file (an on-disk JSON map of
5
- * synthetic model ids to a provider base-URL + key) and merges its ids into
6
- * an agent's model list, so a Claude-Code-shaped adapter can be pointed at a
7
- * routed/self-hosted endpoint per model. Ported verbatim from OD's
8
- * `apps/daemon/src/runtimes/mmd-routes.ts` — no product coupling.
3
+ * Merge synthetic model ids from a configured JSON routing file so Claude-shaped adapters can
4
+ * use a per-model self-hosted/routed endpoint and credential.
9
5
  */
10
6
  import { readFile } from 'node:fs/promises';
11
7
  import { homedir } from 'node:os';
@@ -0,0 +1,19 @@
1
+ import { type AgentDiscoveryConfiguration } from './model-discovery.js';
2
+ import type { ModelDiscoveryContext, ModelDiscoveryDeps, ModelProbeResult } from './model-discovery-types.js';
3
+ export declare function modelProbeTimeoutMs(agentId: string): number;
4
+ /** Shared CLI-subcommand adapter. Output parsers are pure def-owned functions, not vendor tools. */
5
+ export declare function probeCliSubcommand(context: ModelDiscoveryContext, config: AgentDiscoveryConfiguration, deps: ModelDiscoveryDeps, signal: AbortSignal): Promise<ModelProbeResult>;
6
+ /** ACP can create CLI session state/start services. It never sends a user prompt. */
7
+ export declare function probeAcpMetadata(context: ModelDiscoveryContext, args: readonly string[], deps: ModelDiscoveryDeps, signal: AbortSignal): Promise<ModelProbeResult>;
8
+ /** Keep selection IDs, resolved concrete IDs and display names, including capability variants. */
9
+ export declare function parseClaudeInitializeMetadata(stdout: string): ModelProbeResult | null;
10
+ /** Shared initialize category; CodeBuddy compatibility remains UNVERIFIED locally. */
11
+ export declare function probeClaudeInitialize(context: ModelDiscoveryContext, deps: ModelDiscoveryDeps, signal: AbortSignal): Promise<ModelProbeResult>;
12
+ export declare function probeProviderApi(agentId: string, context: ModelDiscoveryContext, deps: ModelDiscoveryDeps, signal: AbortSignal): Promise<ModelProbeResult>;
13
+ /** Caches are partial observed catalogs, always stale, never silently promoted to live. */
14
+ export declare function probeCliCache(agentId: string, context: ModelDiscoveryContext, deps: ModelDiscoveryDeps, signal: AbortSignal): Promise<ModelProbeResult>;
15
+ export declare function probeAgentCatalog(agentId: string, context: ModelDiscoveryContext, configuration: AgentDiscoveryConfiguration, deps: ModelDiscoveryDeps, signal: AbortSignal): Promise<ModelProbeResult>;
16
+ export declare const defaultModelDiscoveryDeps: ModelDiscoveryDeps;
17
+ /** Pi's native RPC supplies catalog AND current provider/id without making an inference call. */
18
+ export declare function parsePiRpcMetadata(stdout: string): ModelProbeResult;
19
+ //# sourceMappingURL=model-discovery-adapters.d.ts.map