@skaile/workspaces 4.17.0 → 4.19.0
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/CHANGELOG.md +22 -0
- package/dist/{asset-feeds-MQKQDF3R.js → asset-feeds-VXK6SHWK.js} +4 -4
- package/dist/{asset-feeds-MQKQDF3R.js.map → asset-feeds-VXK6SHWK.js.map} +1 -1
- package/dist/asset-manager/index.js +1 -1
- package/dist/bridge/codex-app-server.js +2 -1
- package/dist/bridge/drivers/claude-sdk.js +21 -151
- package/dist/bridge/drivers/claude-sdk.js.map +1 -1
- package/dist/bridge/drivers/codex.js +4 -3
- package/dist/bridge/drivers/codex.js.map +1 -1
- package/dist/bridge/drivers/continue.js +4 -3
- package/dist/bridge/drivers/continue.js.map +1 -1
- package/dist/bridge/drivers/echo.js +1 -1
- package/dist/bridge/drivers/gemini.js +6 -5
- package/dist/bridge/drivers/goose.js +4 -3
- package/dist/bridge/drivers/goose.js.map +1 -1
- package/dist/bridge/drivers/omp.js +813 -40
- package/dist/bridge/drivers/omp.js.map +1 -1
- package/dist/bridge/drivers/opencode.js +4 -3
- package/dist/bridge/drivers/opencode.js.map +1 -1
- package/dist/bridge/drivers/qwen.js +6 -5
- package/dist/bridge/drivers/qwen.js.map +1 -1
- package/dist/bridge/index.js +5 -4
- package/dist/bridge/src/agent-exec.d.ts +6 -0
- package/dist/bridge/src/agent-exec.d.ts.map +1 -1
- package/dist/bridge/src/agent-transcript.d.ts +18 -0
- package/dist/bridge/src/agent-transcript.d.ts.map +1 -0
- package/dist/bridge/src/codex-app-server.d.ts.map +1 -1
- package/dist/bridge/src/drivers/_subprocess-cli.d.ts.map +1 -1
- package/dist/bridge/src/drivers/claude-sdk.d.ts +2 -0
- package/dist/bridge/src/drivers/claude-sdk.d.ts.map +1 -1
- package/dist/bridge/src/drivers/omp.d.ts +287 -7
- package/dist/bridge/src/drivers/omp.d.ts.map +1 -1
- package/dist/bridge/src/drivers/scrub-transcript.d.ts +29 -0
- package/dist/bridge/src/drivers/scrub-transcript.d.ts.map +1 -1
- package/dist/bridge/src/index.d.ts +2 -0
- package/dist/bridge/src/index.d.ts.map +1 -1
- package/dist/bridge/src/normalizer.d.ts +5 -0
- package/dist/bridge/src/normalizer.d.ts.map +1 -1
- package/dist/{chunk-C3YE4REG.js → chunk-25BOOOSM.js} +3 -3
- package/dist/{chunk-C3YE4REG.js.map → chunk-25BOOOSM.js.map} +1 -1
- package/dist/{chunk-XRTOSEF3.js → chunk-66MJRB6K.js} +2 -2
- package/dist/{chunk-XRTOSEF3.js.map → chunk-66MJRB6K.js.map} +1 -1
- package/dist/{chunk-NYDTZ2MK.js → chunk-66WUZ3XL.js} +5 -5
- package/dist/{chunk-NYDTZ2MK.js.map → chunk-66WUZ3XL.js.map} +1 -1
- package/dist/{chunk-3W7AOGPY.js → chunk-6S5KL76M.js} +225 -46
- package/dist/chunk-6S5KL76M.js.map +1 -0
- package/dist/{chunk-4RKCOURU.js → chunk-6V3DMJPL.js} +3 -3
- package/dist/{chunk-4RKCOURU.js.map → chunk-6V3DMJPL.js.map} +1 -1
- package/dist/{chunk-6F4TIY7X.js → chunk-EBYSCP6J.js} +4 -4
- package/dist/{chunk-6F4TIY7X.js.map → chunk-EBYSCP6J.js.map} +1 -1
- package/dist/{chunk-D5CRFGDL.js → chunk-EEODEEKX.js} +16 -3
- package/dist/chunk-EEODEEKX.js.map +1 -0
- package/dist/{chunk-2AQIFJHK.js → chunk-EPSCLN5W.js} +3 -3
- package/dist/{chunk-2AQIFJHK.js.map → chunk-EPSCLN5W.js.map} +1 -1
- package/dist/{chunk-AAZDYM5D.js → chunk-J3K5O6XA.js} +3 -3
- package/dist/{chunk-AAZDYM5D.js.map → chunk-J3K5O6XA.js.map} +1 -1
- package/dist/{chunk-4F2L7WPU.js → chunk-K4O6L3WH.js} +5 -3
- package/dist/chunk-K4O6L3WH.js.map +1 -0
- package/dist/{chunk-JURHZYOY.js → chunk-P6S5K7AI.js} +3 -3
- package/dist/{chunk-JURHZYOY.js.map → chunk-P6S5K7AI.js.map} +1 -1
- package/dist/{chunk-3VGQLF3N.js → chunk-RGB45PIL.js} +2 -2
- package/dist/{chunk-3VGQLF3N.js.map → chunk-RGB45PIL.js.map} +1 -1
- package/dist/{chunk-AOFJ2OKW.js → chunk-RYIWFV67.js} +2 -2
- package/dist/{chunk-AOFJ2OKW.js.map → chunk-RYIWFV67.js.map} +1 -1
- package/dist/{chunk-WOE4LPGF.js → chunk-S4R3WNRF.js} +3 -3
- package/dist/{chunk-WOE4LPGF.js.map → chunk-S4R3WNRF.js.map} +1 -1
- package/dist/{chunk-Z7KDOGKF.js → chunk-T6QGP5HN.js} +6 -6
- package/dist/{chunk-Z7KDOGKF.js.map → chunk-T6QGP5HN.js.map} +1 -1
- package/dist/{chunk-7EAJNEQ5.js → chunk-VXY6LSQ3.js} +6 -6
- package/dist/{chunk-7EAJNEQ5.js.map → chunk-VXY6LSQ3.js.map} +1 -1
- package/dist/{chunk-3H4HP733.js → chunk-W2SDSDR7.js} +23 -13
- package/dist/chunk-W2SDSDR7.js.map +1 -0
- package/dist/chunk-X5O56UO4.js +151 -0
- package/dist/chunk-X5O56UO4.js.map +1 -0
- package/dist/{chunk-RAHLV6QG.js → chunk-XAKGLR4Y.js} +6 -6
- package/dist/{chunk-RAHLV6QG.js.map → chunk-XAKGLR4Y.js.map} +1 -1
- package/dist/chunk-YROR332M.js +25 -0
- package/dist/chunk-YROR332M.js.map +1 -0
- package/dist/{chunk-YXXEHY7D.js → chunk-YUH46KA7.js} +6 -4
- package/dist/chunk-YUH46KA7.js.map +1 -0
- package/dist/cli/index.js +33 -32
- package/dist/cli/index.js.map +1 -1
- package/dist/connectors/index.js +6 -5
- package/dist/{ensure-sources-6XKA46PN.js → ensure-sources-WYXFJWUO.js} +4 -4
- package/dist/{ensure-sources-6XKA46PN.js.map → ensure-sources-WYXFJWUO.js.map} +1 -1
- package/dist/factory-assets/connectors/box.js +6 -5
- package/dist/factory-assets/connectors/deploy.js +6 -5
- package/dist/factory-assets/connectors/devserver.js +6 -5
- package/dist/factory-assets/connectors/flow/adapter.js +6 -5
- package/dist/factory-assets/connectors/flow/run-flow.js +7 -6
- package/dist/factory-assets/connectors/flow.js +6 -5
- package/dist/factory-assets/connectors/git.js +6 -5
- package/dist/factory-assets/connectors/gmail.js +6 -5
- package/dist/factory-assets/connectors/googledrive.js +6 -5
- package/dist/factory-assets/connectors/local.js +6 -5
- package/dist/factory-assets/connectors/mattermost.js +6 -5
- package/dist/factory-assets/connectors/memory.js +6 -5
- package/dist/factory-assets/connectors/minio.js +6 -5
- package/dist/factory-assets/connectors/postgres.js +6 -5
- package/dist/factory-assets/connectors/s3.js +6 -5
- package/dist/factory-assets/connectors/sharepoint.js +6 -5
- package/dist/factory-assets/connectors/sqlite.js +6 -5
- package/dist/factory-assets/connectors/static-server.js +6 -5
- package/dist/factory-assets/connectors/tunnel.js +6 -5
- package/dist/factory-assets/connectors/webdav.js +6 -5
- package/dist/factory-assets/connectors/xstate-store.js +6 -5
- package/dist/factory-assets/connectors/xstate.js +6 -5
- package/dist/{helpers-6I4SY2S7.js → helpers-TANA2HQT.js} +4 -4
- package/dist/{helpers-6I4SY2S7.js.map → helpers-TANA2HQT.js.map} +1 -1
- package/dist/{library-publish-PPNFBAVH.js → library-publish-JQNTMKZG.js} +6 -6
- package/dist/{library-publish-PPNFBAVH.js.map → library-publish-JQNTMKZG.js.map} +1 -1
- package/dist/{open-library-64LO64NE.js → open-library-NKZ4HJJ6.js} +5 -5
- package/dist/{open-library-64LO64NE.js.map → open-library-NKZ4HJJ6.js.map} +1 -1
- package/dist/{project-3UFTV7DL.js → project-AEAM2ZEW.js} +5 -5
- package/dist/{project-3UFTV7DL.js.map → project-AEAM2ZEW.js.map} +1 -1
- package/dist/runner/index.js +9 -8
- package/dist/runner/src/serve-credentials.d.ts +2 -1
- package/dist/runner/src/serve-credentials.d.ts.map +1 -1
- package/dist/runner/src/serve.d.ts.map +1 -1
- package/dist/sdk/asset-manager.js +1 -1
- package/dist/sdk/bridge.js +5 -4
- package/dist/sdk/index.js +9 -8
- package/dist/sdk/index.js.map +1 -1
- package/dist/sdk/runner.js +9 -8
- package/dist/{setup-JGXLTJ57.js → setup-Q7ACRV72.js} +10 -9
- package/dist/setup-Q7ACRV72.js.map +1 -0
- package/dist/{source-NHEYY7WH.js → source-QXQ3NO46.js} +6 -6
- package/dist/{source-NHEYY7WH.js.map → source-QXQ3NO46.js.map} +1 -1
- package/dist/{source-manifest-publish-IJLVR3IL.js → source-manifest-publish-UKWCZA2M.js} +7 -7
- package/dist/{source-manifest-publish-IJLVR3IL.js.map → source-manifest-publish-UKWCZA2M.js.map} +1 -1
- package/dist/tui/index.js +9 -8
- package/dist/tui/index.js.map +1 -1
- package/dist/workspace-plugin/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-3H4HP733.js.map +0 -1
- package/dist/chunk-3W7AOGPY.js.map +0 -1
- package/dist/chunk-4F2L7WPU.js.map +0 -1
- package/dist/chunk-D5CRFGDL.js.map +0 -1
- package/dist/chunk-YXXEHY7D.js.map +0 -1
- package/dist/setup-JGXLTJ57.js.map +0 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { DriverTarget } from "@skaile/workspaces/plugin-registry";
|
|
2
|
+
import { type TokenUsage } from "@skaile/workspaces/types";
|
|
2
3
|
import type { ModelEntry } from "../models.js";
|
|
3
|
-
import { type AgentConfig, AgentDriver, type DriverInfo } from "../types.js";
|
|
4
|
+
import { type AgentConfig, AgentDriver, type AgentPromptInput, type BridgeCapabilityTool, type DriverInfo, type SlashCommandInfo } from "../types.js";
|
|
4
5
|
/**
|
|
5
6
|
* Build the explicit env allowlist forwarded to the omp child process.
|
|
6
7
|
*
|
|
@@ -50,10 +51,79 @@ export declare const OMP_DEFAULT_TOOLS: readonly string[];
|
|
|
50
51
|
* @since 1.5.0
|
|
51
52
|
*/
|
|
52
53
|
export declare function buildOmpToolArgs(tools: AgentConfig["tools"]): string[];
|
|
54
|
+
/** One `set_host_tools` entry (`omp://rpc.md`, "set_host_tools payload"). */
|
|
55
|
+
export interface OmpHostToolDefinition {
|
|
56
|
+
name: string;
|
|
57
|
+
label: string;
|
|
58
|
+
description: string;
|
|
59
|
+
parameters: Record<string, unknown>;
|
|
60
|
+
loadMode: "essential";
|
|
61
|
+
}
|
|
62
|
+
/** Result of {@link buildOmpHostTools}. */
|
|
63
|
+
export interface OmpHostToolSet {
|
|
64
|
+
/** Definitions to send in `set_host_tools`. */
|
|
65
|
+
definitions: OmpHostToolDefinition[];
|
|
66
|
+
/** omp host tool name → capability name, for routing `host_tool_call`. */
|
|
67
|
+
capabilityNames: Map<string, string>;
|
|
68
|
+
/** Capabilities left out because the provider would reject their schema. */
|
|
69
|
+
dropped: Array<{
|
|
70
|
+
tool: string;
|
|
71
|
+
reason: string;
|
|
72
|
+
}>;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Turn the runner's capability tool list into omp host tool definitions.
|
|
76
|
+
*
|
|
77
|
+
* omp accepts any name in `set_host_tools` but forwards it to the provider
|
|
78
|
+
* as-is, and providers reject anything outside `^[a-zA-Z0-9_-]{1,64}$` with a
|
|
79
|
+
* 400 that fails the whole turn (verified against omp 18.6.0 + Anthropic:
|
|
80
|
+
* `app.editor.open` → `tools.3.custom.name: String should match pattern`).
|
|
81
|
+
* Names are therefore sanitised (`app.editor.open` → `app_editor_open`) and
|
|
82
|
+
* the original kept in `capabilityNames`. Collisions — with another
|
|
83
|
+
* capability or with an omp built-in, which omp refuses — get a numeric
|
|
84
|
+
* suffix.
|
|
85
|
+
*
|
|
86
|
+
* omp also forwards the JSON Schema untouched, so each advertised schema is
|
|
87
|
+
* checked with the same rules the claude-sdk driver applies to raw MCP
|
|
88
|
+
* schemas ({@link checkToolInputSchema}); a failing tool is dropped rather
|
|
89
|
+
* than turning every request into a 400. `loadMode: "essential"` keeps every
|
|
90
|
+
* capability in the prompt instead of behind omp's tool discovery, matching
|
|
91
|
+
* claude-sdk where every capability is in the tool list.
|
|
92
|
+
*
|
|
93
|
+
* Pure — exported for direct testing.
|
|
94
|
+
*/
|
|
95
|
+
export declare function buildOmpHostTools(tools: readonly BridgeCapabilityTool[]): OmpHostToolSet;
|
|
96
|
+
/** Thinking levels omp accepts for `--thinking` / `set_thinking_level`. omp drops anything else silently. */
|
|
97
|
+
export declare const OMP_THINKING_LEVELS: readonly ["off", "minimal", "low", "medium", "high", "xhigh", "max", "auto"];
|
|
98
|
+
export type OmpThinkingLevel = (typeof OMP_THINKING_LEVELS)[number];
|
|
99
|
+
/**
|
|
100
|
+
* Map `AgentConfig.thinking` / `effort` to an omp thinking level.
|
|
101
|
+
*
|
|
102
|
+
* `disabled` wins over `effort` → `off`. Otherwise an explicit `effort`
|
|
103
|
+
* (low/medium/high/max) maps to the same-named level (omp clamps `max` to
|
|
104
|
+
* `xhigh` on models without it). Without effort, `enabled` → `medium` and
|
|
105
|
+
* `adaptive` → `auto`. Returns `undefined` when neither is set (omp keeps its
|
|
106
|
+
* own default) or when the value is outside omp's set — `set_thinking_level`
|
|
107
|
+
* accepts garbage without an error, so validation has to happen here.
|
|
108
|
+
*/
|
|
109
|
+
export declare function ompThinkingLevel(cfg: Pick<AgentConfig, "thinking" | "effort">): OmpThinkingLevel | undefined;
|
|
110
|
+
/**
|
|
111
|
+
* Split a model selector into the `provider` / `modelId` pair `set_model`
|
|
112
|
+
* takes. The registry renders selectors as `<providerId>/<providerModelId>`
|
|
113
|
+
* (the spawn-time `--model` value); provider ids never contain `/` but model
|
|
114
|
+
* ids can, so the split is on the FIRST `/`:
|
|
115
|
+
* `openrouter/anthropic/claude-sonnet-4` → `{ provider: "openrouter", modelId: "anthropic/claude-sonnet-4" }`.
|
|
116
|
+
* A bare name (no `provider/` prefix) cannot be expressed: omp's `--model`
|
|
117
|
+
* fuzzy matching has no RPC equivalent, so the result is `undefined`.
|
|
118
|
+
*/
|
|
119
|
+
export declare function splitOmpModel(model: string): {
|
|
120
|
+
provider: string;
|
|
121
|
+
modelId: string;
|
|
122
|
+
} | undefined;
|
|
53
123
|
/**
|
|
54
124
|
* Agent driver for the oh-my-pi (omp) coding agent.
|
|
55
125
|
*
|
|
56
|
-
* Spawns `omp --mode rpc` as a child process and communicates via newline-delimited
|
|
126
|
+
* Spawns `omp --mode rpc-ui --no-ui` as a child process and communicates via newline-delimited
|
|
57
127
|
* JSON-RPC over stdin/stdout. Model-agnostic: supports any LLM provider.
|
|
58
128
|
*
|
|
59
129
|
* @see https://github.com/can1357/oh-my-pi
|
|
@@ -75,6 +145,18 @@ export declare function buildOmpToolArgs(tools: AgentConfig["tools"]): string[];
|
|
|
75
145
|
* **agentDir** — maps to the `PI_CODING_AGENT_DIR` environment variable. omp reads the
|
|
76
146
|
* GitAgent directory at this path natively (agent.yaml, SOUL.md, RULES.md, knowledge/).
|
|
77
147
|
*
|
|
148
|
+
* **Capabilities** — `AgentConfig.capabilities` (Protocol v2) is registered with omp
|
|
149
|
+
* as host tools (`set_host_tools`) once the process is ready, and again whenever the
|
|
150
|
+
* registry reports a change. omp calls them back with `host_tool_call`, answered via
|
|
151
|
+
* `dispatchCapability` exactly as claude-sdk's `skaile-capabilities` MCP server does.
|
|
152
|
+
* Names are sanitised for the provider; see {@link buildOmpHostTools}.
|
|
153
|
+
*
|
|
154
|
+
* **Questions** — omp's `ask` tool is enabled as one `extension_ui_request` dialog
|
|
155
|
+
* (`set_ask_dialog`), published as the same `question` events as claude-sdk's
|
|
156
|
+
* `AskUserQuestion` and answered through {@link OmpDriver.answerQuestion}. The turn stays
|
|
157
|
+
* parked in omp until then; abort, kill and process exit release it. Dialogs the host
|
|
158
|
+
* cannot answer (`confirm`, `input`, `editor`) are cancelled immediately.
|
|
159
|
+
*
|
|
78
160
|
* @docLink packages/bridge/drivers#omp-driver
|
|
79
161
|
*/
|
|
80
162
|
export declare class OmpDriver extends AgentDriver {
|
|
@@ -90,15 +172,96 @@ export declare class OmpDriver extends AgentDriver {
|
|
|
90
172
|
private prevText;
|
|
91
173
|
/** OMP session ID captured via `get_state` after each turn. */
|
|
92
174
|
private _ompSessionId?;
|
|
175
|
+
/**
|
|
176
|
+
* Usage of the most recent turn, summed over every model call in it (a tool
|
|
177
|
+
* loop is one prompt but many assistant messages). Cleared when a turn
|
|
178
|
+
* starts, like claude-sdk, so it never mixes two turns.
|
|
179
|
+
*/
|
|
180
|
+
private _lastTokens;
|
|
181
|
+
/**
|
|
182
|
+
* Prompt size of the most recent model call: the real context fill, which
|
|
183
|
+
* `_lastTokens` (turn-cumulative) overstates on a tool loop. omp's own
|
|
184
|
+
* `get_state.contextUsage.tokens` replaces it once that reply lands.
|
|
185
|
+
*/
|
|
186
|
+
private _lastContextTokens;
|
|
187
|
+
/** Context window of the active model, from `get_state.contextUsage`. */
|
|
188
|
+
private _contextWindow;
|
|
189
|
+
getTokenUsage(): TokenUsage | null;
|
|
190
|
+
getContextTokens(): number | null;
|
|
191
|
+
getContextWindow(): number | null;
|
|
93
192
|
/** Per-turn settlement handlers; non-null only while a prompt is in flight. */
|
|
94
193
|
private turnResolve;
|
|
95
194
|
private turnReject;
|
|
195
|
+
/** omp host tool name → capability name for the last `set_host_tools` sent. */
|
|
196
|
+
private hostToolCapabilities;
|
|
197
|
+
/** In-flight `host_tool_call`s by omp request id; aborted by `host_tool_cancel`. */
|
|
198
|
+
private readonly hostToolCalls;
|
|
199
|
+
/** Requests awaiting a `response`, by request id; failed when the process goes away. */
|
|
200
|
+
private readonly pendingRequests;
|
|
201
|
+
/** Unsubscribes the capability registry listener; set while a process runs. */
|
|
202
|
+
private unsubscribeToolsChanged;
|
|
203
|
+
/** Request ids whose failed `response` is logged by the caller, not surfaced as an error event. */
|
|
204
|
+
private readonly quietRequestIds;
|
|
205
|
+
/** Capability tools already warned about, so a re-send logs each once. */
|
|
206
|
+
private readonly warnedDroppedHostTools;
|
|
207
|
+
/** The `ask` (or `select` fallback) omp is parked on, until answered, cancelled or the process ends. */
|
|
208
|
+
private pendingQuestion;
|
|
209
|
+
/**
|
|
210
|
+
* Tail of the FIFO of prompts: each `prompt()`/`promptInput()` runs only after
|
|
211
|
+
* the previous one settled, so one turn at a time is ever in flight (omp runs
|
|
212
|
+
* a single agent loop). Never rejects.
|
|
213
|
+
*/
|
|
214
|
+
private promptTail;
|
|
96
215
|
get runtimeSessionId(): string | undefined;
|
|
216
|
+
/** Slash commands from omp's last `available_commands_update`. */
|
|
217
|
+
private cachedCommands;
|
|
218
|
+
getSlashCommands(): SlashCommandInfo[];
|
|
97
219
|
getModel(): string | undefined;
|
|
220
|
+
/**
|
|
221
|
+
* What the running omp process was last told, by config snapshot: `model`,
|
|
222
|
+
* `thinking` and `effort` are the config values those settings came from (also
|
|
223
|
+
* the rollback targets when omp rejects a change), `level` the omp thinking
|
|
224
|
+
* level sent. Set at spawn, updated on each successful `set_*`.
|
|
225
|
+
*/
|
|
226
|
+
private ompApplied;
|
|
227
|
+
/** Serialises live reconfigure RPCs so concurrent patches never interleave. */
|
|
228
|
+
private reconfigureChain;
|
|
229
|
+
/**
|
|
230
|
+
* Apply `model` / `thinking` / `effort` to this driver and, when the process
|
|
231
|
+
* is up and idle, to the running omp session (`set_model` /
|
|
232
|
+
* `set_thinking_level`). The base contract is synchronous and void, so the
|
|
233
|
+
* RPCs are fire-and-forget: a rejected change is surfaced as an `error`
|
|
234
|
+
* agent event and the config rolls back, keeping {@link getModel} honest.
|
|
235
|
+
*
|
|
236
|
+
* A patch that arrives mid-turn or before `ready` is not lost: config is the
|
|
237
|
+
* source of truth, flushed before the next `prompt()` and read by the next
|
|
238
|
+
* spawn. A model `set_model` cannot express live (no `provider/` prefix) is
|
|
239
|
+
* rejected the same way as one omp refuses: an `error` event and a rollback,
|
|
240
|
+
* since the running process cannot switch to it. In registry mode the patch
|
|
241
|
+
* also replaces `modelRef`, so a respawn (crash, `resetSession()`) starts the
|
|
242
|
+
* reconfigured model; models.yml already lists every enabled provider.
|
|
243
|
+
*/
|
|
244
|
+
reconfigure(patch: Partial<Pick<AgentConfig, "model" | "thinking" | "effort">>): void;
|
|
245
|
+
private syncReconfigure;
|
|
246
|
+
/** Push config drift to the running process. Never rejects. */
|
|
247
|
+
private applyReconfigure;
|
|
248
|
+
/**
|
|
249
|
+
* Restore the model the running process holds after a failed live switch —
|
|
250
|
+
* unless a newer patch already replaced `model` (it will be applied next).
|
|
251
|
+
*/
|
|
252
|
+
private rollbackModel;
|
|
253
|
+
/** Push thinking/effort drift to the running process. Never rejects. */
|
|
254
|
+
private applyThinking;
|
|
255
|
+
/**
|
|
256
|
+
* Send one live-reconfigure request. A failed `response` is already emitted
|
|
257
|
+
* as an `error` event by {@link handleEvent}; a transport failure (timeout,
|
|
258
|
+
* process gone) is emitted here. Returns whether omp accepted it.
|
|
259
|
+
*/
|
|
260
|
+
private sendReconfigure;
|
|
98
261
|
/**
|
|
99
262
|
* @param config - Driver configuration. omp-relevant fields:
|
|
100
263
|
* - `cwd` — working directory; omp session files are stored under `<cwd>/.omp/sessions/`.
|
|
101
|
-
* - `model`
|
|
264
|
+
* - `model` — forwarded as `--model <selector>`. In registry mode `modelRef` takes precedence at spawn; `reconfigure({ model })` keeps both in step.
|
|
102
265
|
* - `systemPrompt` — written to `<cwd>/.omp/system.md` and appended via `--append-system-prompt`.
|
|
103
266
|
* - `agentDir` — sets `PI_CODING_AGENT_DIR`; omp reads agent identity from this directory.
|
|
104
267
|
* - `sshKeyPath` — injected as `GIT_SSH_COMMAND` for authenticated git operations.
|
|
@@ -107,7 +270,79 @@ export declare class OmpDriver extends AgentDriver {
|
|
|
107
270
|
constructor(config: AgentConfig);
|
|
108
271
|
start(): Promise<void>;
|
|
109
272
|
private _start;
|
|
273
|
+
/**
|
|
274
|
+
* Register the runner's capabilities with omp as host tools.
|
|
275
|
+
*
|
|
276
|
+
* Sends the full set every time: `set_host_tools` replaces omp's previous
|
|
277
|
+
* host-owned set, so a registry change that removes a capability takes
|
|
278
|
+
* effect too. Best-effort — a failure is logged and the session runs
|
|
279
|
+
* without host tools rather than failing to start.
|
|
280
|
+
*/
|
|
281
|
+
private syncHostTools;
|
|
282
|
+
/**
|
|
283
|
+
* Execute a capability omp asked the host to run (`host_tool_call`) and
|
|
284
|
+
* answer with `host_tool_result`. Goes through {@link dispatchCapability}
|
|
285
|
+
* so validation, fire-and-forget and render semantics match claude-sdk.
|
|
286
|
+
*
|
|
287
|
+
* Emits `tool_call` / `tool_execution_end` around the dispatch: the
|
|
288
|
+
* normalizer does not read omp's own tool frames, so without these the
|
|
289
|
+
* call — and its `activity_label` — would never reach the chat.
|
|
290
|
+
*/
|
|
291
|
+
private handleHostToolCall;
|
|
292
|
+
/**
|
|
293
|
+
* `host_tool_cancel`: omp aborted the call, so abort the capability handler
|
|
294
|
+
* and close the call's chat activity (the handler's later settlement is
|
|
295
|
+
* ignored, so this is the only `tool_execution_end` the call gets).
|
|
296
|
+
*/
|
|
297
|
+
private handleHostToolCancel;
|
|
298
|
+
/** Abort one in-flight host tool call and end its activity; no-op if already settled. */
|
|
299
|
+
private abortHostToolCall;
|
|
300
|
+
/**
|
|
301
|
+
* `extension_ui_request`: omp asks the host something. Only `ask` (and the
|
|
302
|
+
* `select` omp falls back to when `set_ask_dialog` is unavailable) can carry
|
|
303
|
+
* a user question; both park until {@link answerQuestion}. Presentation
|
|
304
|
+
* frames expect no reply. Every other kind is a dialog nobody here can
|
|
305
|
+
* answer, so it is cancelled at once — an unanswered dialog would leave the
|
|
306
|
+
* tool call, and the turn, waiting forever.
|
|
307
|
+
*/
|
|
308
|
+
private handleExtensionUiRequest;
|
|
309
|
+
private parseAskRequest;
|
|
310
|
+
private parseSelectRequest;
|
|
311
|
+
/**
|
|
312
|
+
* Publish the parked question the way claude-sdk does for `AskUserQuestion`:
|
|
313
|
+
* an assistant `tool_use` block the normalizer turns into one `question`
|
|
314
|
+
* event per question, plus the matching `tool_call`. Option descriptions and
|
|
315
|
+
* `header`s survive in the tool input for consumers that render them.
|
|
316
|
+
*/
|
|
317
|
+
private announceQuestion;
|
|
318
|
+
hasPendingQuestion(): boolean;
|
|
319
|
+
/**
|
|
320
|
+
* While omp is parked on a question a reply that is not an answer must not
|
|
321
|
+
* become a prompt: the turn is still running, and a second prompt would
|
|
322
|
+
* collide with it.
|
|
323
|
+
*/
|
|
324
|
+
get acceptsReplyAsPrompt(): boolean;
|
|
325
|
+
answerQuestion(answer: string, question?: string, requestId?: string): boolean;
|
|
326
|
+
/** Shape the collected answers as the `extension_ui_response` payload for the request's method. */
|
|
327
|
+
private buildQuestionResponse;
|
|
328
|
+
/** Write an `extension_ui_response`; undeliverable (process gone) is logged, not thrown. */
|
|
329
|
+
private sendUiResponse;
|
|
330
|
+
/** Drop the pending question and tell omp it was cancelled, so its tool call unwinds. */
|
|
331
|
+
private cancelPendingQuestion;
|
|
332
|
+
/**
|
|
333
|
+
* Opt in to omp's single `ask` dialog request (off by default per process).
|
|
334
|
+
* Best-effort: a build without the command answers with a failed response and
|
|
335
|
+
* its `ask` keeps degrading to one `select` per question, which
|
|
336
|
+
* {@link handleExtensionUiRequest} still surfaces as a question.
|
|
337
|
+
*/
|
|
338
|
+
private enableAskDialog;
|
|
110
339
|
private extractMessageText;
|
|
340
|
+
/**
|
|
341
|
+
* `available_commands_update`: replace the cached slash-command list and
|
|
342
|
+
* publish it. Names carry no leading slash (omp's already don't), matching
|
|
343
|
+
* claude-sdk's `commands_available`. Entries without a name are skipped.
|
|
344
|
+
*/
|
|
345
|
+
private handleCommandsUpdate;
|
|
111
346
|
private handleEvent;
|
|
112
347
|
/**
|
|
113
348
|
* Resolve the in-flight prompt turn (on `agent_end`). Idempotent — a turn
|
|
@@ -120,12 +355,35 @@ export declare class OmpDriver extends AgentDriver {
|
|
|
120
355
|
*/
|
|
121
356
|
private rejectTurn;
|
|
122
357
|
/**
|
|
123
|
-
* Query OMP
|
|
124
|
-
*
|
|
125
|
-
*
|
|
358
|
+
* Query OMP's current state via the `get_state` RPC.
|
|
359
|
+
*
|
|
360
|
+
* Always refreshes the context fill from `contextUsage`. With
|
|
361
|
+
* `announceSession` (the default, used after each turn) it also records the
|
|
362
|
+
* native session ID and emits a `session_info` event so the forge layer can
|
|
363
|
+
* persist it. Failures are silently swallowed — both are best-effort.
|
|
364
|
+
*/
|
|
365
|
+
private captureState;
|
|
366
|
+
/** `get_state.contextUsage` → context fill + window; absent or malformed values are ignored. */
|
|
367
|
+
private captureContextUsage;
|
|
368
|
+
/** Forget the previous turn's usage; called as a new turn begins. */
|
|
369
|
+
private beginUsageTurn;
|
|
370
|
+
/**
|
|
371
|
+
* Fold one finished assistant message into the turn's usage. Only the
|
|
372
|
+
* `message_end` value is final (`message_start` and partials carry running
|
|
373
|
+
* zeros). A message without usage, or an errored one reporting all zeros,
|
|
374
|
+
* bills nothing and must neither create a reading nor wipe a good one.
|
|
126
375
|
*/
|
|
127
|
-
private
|
|
376
|
+
private recordMessageUsage;
|
|
128
377
|
private nextId;
|
|
378
|
+
/**
|
|
379
|
+
* Send a command and await its `response` frame.
|
|
380
|
+
*
|
|
381
|
+
* @param options.quiet - Leave a failed response to the caller instead of
|
|
382
|
+
* surfacing it as an `error` agent event.
|
|
383
|
+
* @throws When the process is not running or no response arrives within
|
|
384
|
+
* `options.timeoutMs` (default 5 s).
|
|
385
|
+
*/
|
|
386
|
+
private request;
|
|
129
387
|
private send;
|
|
130
388
|
/**
|
|
131
389
|
* Sends a prompt to the omp process via JSON-RPC and resolves when the turn
|
|
@@ -141,6 +399,28 @@ export declare class OmpDriver extends AgentDriver {
|
|
|
141
399
|
* the child crashes/exits before the turn completes.
|
|
142
400
|
*/
|
|
143
401
|
prompt(message: string): Promise<void>;
|
|
402
|
+
/**
|
|
403
|
+
* Run one prompt after every earlier one settled. A question omp is parked on
|
|
404
|
+
* is cancelled first, synchronously and ahead of the queue: the parked turn
|
|
405
|
+
* can only finish once its `ask` is released, so the new prompt (the user
|
|
406
|
+
* typing instead of answering) must not wait behind it. The runner does not
|
|
407
|
+
* serialise `prompt` commands, so the driver does, as claude-sdk does.
|
|
408
|
+
*/
|
|
409
|
+
private enqueuePrompt;
|
|
410
|
+
/**
|
|
411
|
+
* Structured prompt: text plus image/file/skill attachments. Images travel as
|
|
412
|
+
* omp `ImageContent` (`prompt.images`, base64 + mimeType); file and skill
|
|
413
|
+
* attachments are named in a text preamble, because omp reads files itself.
|
|
414
|
+
* Turn settlement is shared with {@link prompt}.
|
|
415
|
+
*/
|
|
416
|
+
promptInput(input: AgentPromptInput): Promise<void>;
|
|
417
|
+
/** Resolve attachments into the `message` + `images` fields of an omp `prompt` frame. */
|
|
418
|
+
private buildPromptPayload;
|
|
419
|
+
/**
|
|
420
|
+
* Send one `prompt` frame and resolve when the turn completes (`agent_end`).
|
|
421
|
+
* Rejects if the child dies first.
|
|
422
|
+
*/
|
|
423
|
+
private runPrompt;
|
|
144
424
|
/**
|
|
145
425
|
* Sends an in-band abort RPC to the omp process, requesting it to stop the
|
|
146
426
|
* current turn without terminating the child process.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"omp.d.ts","sourceRoot":"","sources":["../../../../bridge/src/drivers/omp.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"omp.d.ts","sourceRoot":"","sources":["../../../../bridge/src/drivers/omp.ts"],"names":[],"mappings":"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"}
|
|
@@ -73,6 +73,29 @@ export interface ScrubTranscriptOptions {
|
|
|
73
73
|
sessionId: string;
|
|
74
74
|
/** Optional logger for diagnostics. */
|
|
75
75
|
log?: ScrubLogger;
|
|
76
|
+
/**
|
|
77
|
+
* Where the transcript is read and written. Defaults to this process's own
|
|
78
|
+
* filesystem access ({@link localTranscriptStore}); with the agent uid split
|
|
79
|
+
* the transcript belongs to the agent uid and must be reached through it.
|
|
80
|
+
*/
|
|
81
|
+
store?: TranscriptStore;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Filesystem access to Claude Code transcripts. The CLI creates them 0600 in
|
|
85
|
+
* 0700 dirs, so when it runs as a different uid than the runner, only that uid
|
|
86
|
+
* can locate, read or rewrite them (see `agent-transcript.ts`).
|
|
87
|
+
*
|
|
88
|
+
* @category Transcript repair
|
|
89
|
+
*/
|
|
90
|
+
export interface TranscriptStore {
|
|
91
|
+
/** Path of `<sessionId>.jsonl` under `<configDir>/projects/`, or `null` when absent. */
|
|
92
|
+
locate(configDir: string, sessionId: string, timeoutMs?: number): Promise<string | null>;
|
|
93
|
+
/** The file's contents as UTF-8 chunks. */
|
|
94
|
+
read(filePath: string): AsyncIterable<string>;
|
|
95
|
+
/** Atomically replace the file with `chunks` via a `.scrub-tmp` sibling. */
|
|
96
|
+
replace(filePath: string, chunks: AsyncIterable<string>): Promise<void>;
|
|
97
|
+
/** Remove the sibling a failed or abandoned {@link replace} left (best effort). */
|
|
98
|
+
discardTemp(filePath: string): Promise<void>;
|
|
76
99
|
}
|
|
77
100
|
/**
|
|
78
101
|
* Outcome of a {@link scrubPoisonedTranscript} pass.
|
|
@@ -127,6 +150,12 @@ export declare function sniffImageMediaType(base64: string): string | null;
|
|
|
127
150
|
* @category Transcript repair
|
|
128
151
|
*/
|
|
129
152
|
export declare function locateTranscriptPath(configDir: string, sessionId: string, timeoutMs?: number): Promise<string | null>;
|
|
153
|
+
/**
|
|
154
|
+
* The runner's own filesystem access: the default {@link TranscriptStore}.
|
|
155
|
+
*
|
|
156
|
+
* @category Transcript repair
|
|
157
|
+
*/
|
|
158
|
+
export declare const localTranscriptStore: TranscriptStore;
|
|
130
159
|
/**
|
|
131
160
|
* Scan a Claude Code SDK transcript for image content blocks whose declared
|
|
132
161
|
* `media_type` does not match the actual bytes, repair them, and atomically
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scrub-transcript.d.ts","sourceRoot":"","sources":["../../../../bridge/src/drivers/scrub-transcript.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AAQH;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC5D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC7D;AAED;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,SAAS,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,GAAG,CAAC,EAAE,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"scrub-transcript.d.ts","sourceRoot":"","sources":["../../../../bridge/src/drivers/scrub-transcript.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AAQH;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC5D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC7D;AAED;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,SAAS,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,GAAG,CAAC,EAAE,WAAW,CAAC;IAClB;;;;OAIG;IACH,KAAK,CAAC,EAAE,eAAe,CAAC;CACzB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC9B,wFAAwF;IACxF,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACzF,2CAA2C;IAC3C,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IAC9C,4EAA4E;IAC5E,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxE,mFAAmF;IACnF,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9C;AAED;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,mEAAmE;IACnE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,uFAAuF;IACvF,SAAS,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,mFAAmF;IACnF,aAAa,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,OAAO,EAAE,OAAO,CAAC;CAClB;AAeD;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAwCjE;AA6FD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,SAAS,GAAE,MAAuB,GACjC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAoBxB;AA+BD;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,EAAE,eAoBlC,CAAC;AA8BF;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,sBAAsB,GAC3B,OAAO,CAAC,qBAAqB,CAAC,CAgGhC"}
|
|
@@ -4,6 +4,8 @@ export { AccountUnavailableError, AuthError, type ClaudeSdkResultErrorInput, cla
|
|
|
4
4
|
export * from "./logger.js";
|
|
5
5
|
export * from "./models.js";
|
|
6
6
|
export * from "./agent-exec.js";
|
|
7
|
+
export { agentTranscriptStore, transcriptStoreForRuntime } from "./agent-transcript.js";
|
|
8
|
+
export { localTranscriptStore, type TranscriptStore } from "./drivers/scrub-transcript.js";
|
|
7
9
|
export * from "./runner-private-env.js";
|
|
8
10
|
export * from "./normalizer.js";
|
|
9
11
|
export * from "./provider-catalog.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../bridge/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,YAAY,CAAC;AAC3B,OAAO,EACL,uBAAuB,EACvB,SAAS,EACT,KAAK,yBAAyB,EAC9B,sBAAsB,EACtB,kCAAkC,GACnC,MAAM,uBAAuB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AAItC,cAAc,0CAA0C,CAAC;AACzD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,eAAe,CAAC;AAC9B,OAAO,EACL,qBAAqB,EACrB,KAAK,kBAAkB,EACvB,sBAAsB,GACvB,MAAM,2BAA2B,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAEhC,OAAO,EAAE,yBAAyB,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../bridge/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAC;AACzC,cAAc,YAAY,CAAC;AAC3B,OAAO,EACL,uBAAuB,EACvB,SAAS,EACT,KAAK,yBAAyB,EAC9B,sBAAsB,EACtB,kCAAkC,GACnC,MAAM,uBAAuB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,OAAO,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AACxF,OAAO,EAAE,oBAAoB,EAAE,KAAK,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAC3F,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AAItC,cAAc,0CAA0C,CAAC;AACzD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,eAAe,CAAC;AAC9B,OAAO,EACL,qBAAqB,EACrB,KAAK,kBAAkB,EACvB,sBAAsB,GACvB,MAAM,2BAA2B,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAEhC,OAAO,EAAE,yBAAyB,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAC"}
|
|
@@ -22,6 +22,11 @@ export declare class EventNormalizer {
|
|
|
22
22
|
private devServerReadyEmitted;
|
|
23
23
|
/** True when message_update deltas have been emitted for the current message. */
|
|
24
24
|
private hasStreamedText;
|
|
25
|
+
/**
|
|
26
|
+
* True once a `_thinkingDelta` run has been reported as `status: thinking`;
|
|
27
|
+
* cleared by the next text delta or assistant message, so a run reports once.
|
|
28
|
+
*/
|
|
29
|
+
private thinkingAnnounced;
|
|
25
30
|
/**
|
|
26
31
|
* tool_use blocks `message_start` already reported, awaiting the driver's
|
|
27
32
|
* matching bridge `tool_call` — which must then not report the call again.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalizer.d.ts","sourceRoot":"","sources":["../../../bridge/src/normalizer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,KAAK,UAAU,IAAI,eAAe,EAKnC,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAgB,UAAU,IAAI,WAAW,EAAgB,MAAM,YAAY,CAAC;AAgDxF;;;;;;;;GAQG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,eAAe,CAA6B;IACpD,OAAO,CAAC,wBAAwB,CAAS;IACzC,OAAO,CAAC,qBAAqB,CAAS;IACtC,iFAAiF;IACjF,OAAO,CAAC,eAAe,CAAS;IAChC;;;OAGG;IACH,OAAO,CAAC,iBAAiB,CAA4C;IAErE;;;;OAIG;IACH,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,eAAe,EAAE;IAoFhD,oDAAoD;IACpD,KAAK,IAAI,IAAI;
|
|
1
|
+
{"version":3,"file":"normalizer.d.ts","sourceRoot":"","sources":["../../../bridge/src/normalizer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,KAAK,UAAU,IAAI,eAAe,EAKnC,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAgB,UAAU,IAAI,WAAW,EAAgB,MAAM,YAAY,CAAC;AAgDxF;;;;;;;;GAQG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,eAAe,CAA6B;IACpD,OAAO,CAAC,wBAAwB,CAAS;IACzC,OAAO,CAAC,qBAAqB,CAAS;IACtC,iFAAiF;IACjF,OAAO,CAAC,eAAe,CAAS;IAChC;;;OAGG;IACH,OAAO,CAAC,iBAAiB,CAAS;IAClC;;;OAGG;IACH,OAAO,CAAC,iBAAiB,CAA4C;IAErE;;;;OAIG;IACH,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,eAAe,EAAE;IAoFhD,oDAAoD;IACpD,KAAK,IAAI,IAAI;IASb,OAAO,CAAC,uBAAuB;IAc/B,OAAO,CAAC,kBAAkB;IAqC1B,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,qBAAqB;IAgD7B,OAAO,CAAC,kBAAkB;IAe1B,OAAO,CAAC,oBAAoB;IA+B5B,OAAO,CAAC,mBAAmB;IAwB3B,OAAO,CAAC,aAAa;IAqBrB,OAAO,CAAC,oBAAoB;IAa5B,OAAO,CAAC,gBAAgB;IA2BxB,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,mBAAmB;IAc3B,OAAO,CAAC,YAAY;IAuCpB,OAAO,CAAC,uBAAuB;IAa/B,OAAO,CAAC,oBAAoB;IA2B5B,OAAO,CAAC,gBAAgB;CAOzB;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CA2BtF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,SAAS,CAS9F;AAiED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,CA6BzE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,eAAe,EAAE,CAiCtF;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,eAAe,GAAG,IAAI,CAE1F"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getProviderPreset, registryCredentialEnv, providerCredentialEnvName, BUILTIN_DRIVER_CATALOG } from './chunk-
|
|
1
|
+
import { getProviderPreset, registryCredentialEnv, providerCredentialEnvName, BUILTIN_DRIVER_CATALOG } from './chunk-RGB45PIL.js';
|
|
2
2
|
import { mergeRegistries, resolveEntryBaseUrl, normalizeEntryBaseUrl, registryEntries, isEntryEnabled, parseModelRef } from './chunk-GZZPKAV5.js';
|
|
3
3
|
|
|
4
4
|
// bridge/src/provider-materialize/env-drivers.ts
|
|
@@ -137,5 +137,5 @@ function continueRoleBinding(session) {
|
|
|
137
137
|
}
|
|
138
138
|
|
|
139
139
|
export { backendModelSelector, backendProviderName, bindSingleProviderEntry, continueRoleBinding, credentialsForEveryProvider, entryBaseUrl, entryModelIds, entrySurface, isStockCatalogEndpoint, registryModelEntries, resolveEnvDriverSession, resolveRegistryBinding, selectableEntries, versionedAnthropicBaseUrl };
|
|
140
|
-
//# sourceMappingURL=chunk-
|
|
141
|
-
//# sourceMappingURL=chunk-
|
|
140
|
+
//# sourceMappingURL=chunk-25BOOOSM.js.map
|
|
141
|
+
//# sourceMappingURL=chunk-25BOOOSM.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../bridge/src/provider-materialize/env-drivers.ts"],"names":[],"mappings":";;;;AAyEO,SAAS,uBAAA,CACd,MAAA,EACA,UAAA,GAAiD,OAAA,CAAQ,GAAA,EACvC;AAClB,EAAA,OAAO;AAAA,IACL,QAAA,EAAU,MAAA,CAAO,QAAA,IAAY,eAAA,CAAgB,EAAE,CAAA;AAAA,IAC/C,WAAW,EAAE,GAAG,UAAA,EAAY,GAAG,OAAO,GAAA,EAAI;AAAA,IAC1C,GAAI,OAAO,QAAA,GAAW,EAAE,UAAU,MAAA,CAAO,QAAA,KAAa,EAAC;AAAA,IACvD,GAAI,OAAO,KAAA,GAAQ,EAAE,OAAO,MAAA,CAAO,KAAA,KAAU;AAAC,GAChD;AACF;AA2BO,SAAS,aAAa,KAAA,EAA0D;AACrF,EAAA,IAAI,KAAA,CAAM,OAAA,EAAS,OAAO,KAAA,CAAM,OAAA;AAChC,EAAA,OAAO,MAAM,MAAA,GAAS,iBAAA,CAAkB,KAAA,CAAM,MAAM,GAAG,OAAA,GAAU,MAAA;AACnE;AAcO,SAAS,aAAa,KAAA,EAA+C;AAC1E,EAAA,MAAM,QAAA,GACJ,mBAAA,CAAoB,KAAK,CAAA,KACxB,KAAA,CAAM,SAAS,iBAAA,CAAkB,KAAA,CAAM,MAAM,CAAA,EAAG,QAAA,GAAW,MAAA,CAAA;AAC9D,EAAA,OAAO,qBAAA,CAAsB,QAAA,EAAU,YAAA,CAAa,KAAK,CAAC,CAAA;AAC5D;AASO,SAAS,yBAAA,CACd,SACA,OAAA,EACQ;AACR,EAAA,IAAI,OAAA,KAAY,sBAAsB,OAAO,OAAA;AAE7C,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,OAAO,CAAA;AAC3B,IAAA,GAAA,CAAI,WAAW,CAAA,EAAG,GAAA,CAAI,SAAS,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAC,CAAA,GAAA,CAAA;AAClD,IAAA,OAAO,IAAI,QAAA,EAAS;AAAA,EACtB,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,GAAG,OAAO,CAAA,GAAA,CAAA;AAAA,EACnB;AACF;AAcO,SAAS,uBAAuB,KAAA,EAAoC;AACzE,EAAA,MAAM,SAAS,KAAA,CAAM,MAAA,GAAS,iBAAA,CAAkB,KAAA,CAAM,MAAM,CAAA,GAAI,MAAA;AAChE,EAAA,IAAI,CAAC,QAAQ,OAAO,KAAA;AACpB,EAAA,OAAO,YAAA,CAAa,KAAK,CAAA,KAAM,qBAAA,CAAsB,OAAO,QAAA,EAAU,YAAA,CAAa,KAAK,CAAC,CAAA;AAC3F;AAaO,SAAS,mBAAA,CAAoB,YAAoB,KAAA,EAAmC;AACzF,EAAA,MAAM,SAAS,KAAA,CAAM,MAAA,GAAS,iBAAA,CAAkB,KAAA,CAAM,MAAM,CAAA,GAAI,MAAA;AAChE,EAAA,IAAI,CAAC,MAAA,IAAU,CAAC,sBAAA,CAAuB,KAAK,GAAG,OAAO,UAAA;AACtD,EAAA,OAAO,MAAA,CAAO,EAAA;AAChB;AAQO,SAAS,kBACd,QAAA,EACqC;AACrC,EAAA,OAAO,eAAA,CAAgB,QAAQ,CAAA,CAAE,MAAA;AAAA,IAC/B,CAAC,IAAA,KAAA,CACE,IAAA,CAAK,CAAC,EAAE,IAAA,KAAS,KAAA,IAAS,IAAA,CAAK,CAAC,EAAE,IAAA,KAAS,OAAA,KAAY,cAAA,CAAe,IAAA,CAAK,CAAC,CAAC;AAAA,GAClF;AACF;AAOO,SAAS,cAAc,KAAA,EAAoD;AAChF,EAAA,MAAM,UAAA,GAAa;AAAA,IACjB,GAAG,MAAA,CAAO,IAAA,CAAK,KAAA,CAAM,SAAA,IAAa,EAAE,CAAA;AAAA,IACpC,GAAG,MAAA,CAAO,IAAA,CAAK,KAAA,CAAM,YAAA,IAAgB,EAAE,CAAA,CAAE,MAAA,CAAO,CAAC,OAAO,EAAE,EAAA,KAAO,KAAA,CAAM,SAAA,IAAa,EAAC,CAAA,CAAG;AAAA,GAC1F;AACA,EAAA,OAAO,UAAA,CAAW,GAAA,CAAI,CAAC,EAAA,KAAO,CAAC,EAAA,EAAI,KAAA,CAAM,SAAA,GAAY,EAAE,CAAA,IAAK,EAAE,CAAC,CAAA;AACjE;AAEA,SAAS,eAAA,CACP,UAAA,EACA,KAAA,EACA,OAAA,EACA,iBACA,QAAA,EACsB;AACtB,EAAA,MAAM,OAAA,GAAU,aAAa,KAAK,CAAA;AAClC,EAAA,MAAM,OAAA,GAAU,aAAa,KAAK,CAAA;AAClC,EAAA,OAAO;AAAA,IACL,UAAA;AAAA,IACA,KAAA;AAAA,IACA,GAAI,OAAA,KAAY,MAAA,GAAY,EAAC,GAAI,EAAE,OAAA,EAAQ;AAAA,IAC3C,GAAI,eAAA,KAAoB,MAAA,GAAY,EAAC,GAAI,EAAE,eAAA,EAAgB;AAAA,IAC3D,GAAI,OAAA,GAAU,EAAE,OAAA,KAAY,EAAC;AAAA,IAC7B,GAAI,OAAA,GAAU,EAAE,OAAA,KAAY,EAAC;AAAA,IAC7B,iBAAA,EAAmB,mBAAA,CAAoB,UAAA,EAAY,KAAK,CAAA;AAAA,IACxD;AAAA,GACF;AACF;AAUO,SAAS,uBACd,OAAA,EACkC;AAClC,EAAA,MAAM,OAAA,GAAU,iBAAA,CAAkB,OAAA,CAAQ,QAAQ,CAAA;AAClD,EAAA,IAAI,OAAA,CAAQ,MAAA,KAAW,CAAA,EAAG,OAAO,MAAA;AAEjC,EAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,QAAA,EAAU,IAAA,EAAK;AACxC,EAAA,IAAI,CAAC,QAAA,EAAU;AACb,IAAA,MAAM,CAAC,UAAA,EAAY,KAAK,CAAA,GAAI,QAAQ,CAAC,CAAA;AACrC,IAAA,OAAO,gBAAgB,UAAA,EAAY,KAAA,EAAO,MAAA,EAAW,MAAA,EAAW,EAAE,CAAA;AAAA,EACpE;AAKA,EAAA,MAAM,KAAA,GAAQ,QAAQ,IAAA,CAAK,CAAC,CAAC,EAAE,CAAA,KAAM,OAAO,QAAQ,CAAA;AACpD,EAAA,IAAI,KAAA,EAAO,OAAO,eAAA,CAAgB,KAAA,CAAM,CAAC,CAAA,EAAG,KAAA,CAAM,CAAC,CAAA,EAAG,MAAA,EAAW,MAAA,EAAW,EAAE,CAAA;AAE9E,EAAA,MAAM,WAAW,aAAA,CAAc,QAAA,EAAU,OAAA,CAAQ,QAAA,EAAU,QAAQ,KAAK,CAAA;AACxE,EAAA,IAAI,CAAC,UAAU,OAAO,MAAA;AACtB,EAAA,MAAM,KAAA,GAAQ,QAAQ,IAAA,CAAK,CAAC,CAAC,EAAE,CAAA,KAAM,EAAA,KAAO,QAAA,CAAS,UAAU,CAAA;AAC/D,EAAA,IAAI,CAAC,OAAO,OAAO,MAAA;AACnB,EAAA,OAAO,eAAA;AAAA,IACL,MAAM,CAAC,CAAA;AAAA,IACP,MAAM,CAAC,CAAA;AAAA,IACP,QAAA,CAAS,OAAA;AAAA,IACT,QAAA,CAAS,eAAA;AAAA,IACT,QAAA,CAAS;AAAA,GACX;AACF;AAQO,SAAS,4BAA4B,OAAA,EAAmD;AAC7F,EAAA,OAAO,sBAAsB,OAAA,CAAQ,QAAA,EAAU,EAAE,GAAA,EAAK,OAAA,CAAQ,WAAW,CAAA;AAC3E;AASO,SAAS,yBAAA,CACd,QAAA,EACA,WAAA,EACA,OAAA,EACM;AACN,EAAA,MAAM,SAAA,GAAY,sBAAA,CAAuB,QAAQ,CAAA,EAAG,QAAA;AACpD,EAAA,IAAI,CAAC,SAAA,IAAa,SAAA,CAAU,MAAA,KAAW,CAAA,EAAG;AAC1C,EAAA,MAAM,UAAU,OAAA,CAAQ,OAAA;AACxB,EAAA,IAAI,CAAC,OAAA,IAAW,SAAA,CAAU,QAAA,CAAS,OAAO,CAAA,EAAG;AAC7C,EAAA,MAAM,IAAI,KAAA;AAAA,IACR,CAAA,EAAG,WAAW,CAAA,mBAAA,EAAsB,OAAO,mCACrC,OAAA,CAAQ,UAAU,CAAA,GAAA,EAAM,WAAW,YAAY,SAAA,CAAU,IAAA,CAAK,IAAI,CAAC,2GAEjC,OAAO,CAAA,EAAA;AAAA,GACjD;AACF;AAYO,SAAS,qBAAqB,OAAA,EAAyC;AAC5E,EAAA,MAAM,MAAoB,EAAC;AAC3B,EAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAC7B,EAAA,KAAA,MAAW,CAAC,UAAA,EAAY,KAAK,KAAK,iBAAA,CAAkB,OAAA,CAAQ,QAAQ,CAAA,EAAG;AACrE,IAAA,MAAM,SAAA,GAAY,mBAAA,CAAoB,UAAA,EAAY,KAAK,CAAA;AACvD,IAAA,MAAM,KAAA,GAAQ,MAAM,KAAA,IAAS,UAAA;AAC7B,IAAA,KAAA,MAAW,CAAC,SAAA,EAAW,eAAe,CAAA,IAAK,aAAA,CAAc,KAAK,CAAA,EAAG;AAC/D,MAAA,MAAM,EAAA,GAAK,CAAA,EAAG,SAAS,CAAA,CAAA,EAAI,eAAe,CAAA,CAAA;AAC1C,MAAA,IAAI,IAAA,CAAK,GAAA,CAAI,EAAE,CAAA,EAAG;AAClB,MAAA,IAAA,CAAK,IAAI,EAAE,CAAA;AACX,MAAA,GAAA,CAAI,IAAA,CAAK,EAAE,EAAA,EAAI,IAAA,EAAM,GAAG,KAAK,CAAA,CAAA,EAAI,SAAS,CAAA,CAAA,EAAI,CAAA;AAAA,IAChD;AAAA,EACF;AACA,EAAA,OAAO,GAAA;AACT;AAWO,SAAS,uBAAA,CACd,QAAA,EACA,WAAA,EACA,OAAA,EACkC;AAClC,EAAA,MAAM,OAAA,GAAU,uBAAuB,OAAO,CAAA;AAC9C,EAAA,IAAI,CAAC,SAAS,OAAO,MAAA;AACrB,EAAA,yBAAA,CAA0B,QAAA,EAAU,aAAa,OAAO,CAAA;AACxD,EAAA,OAAO,OAAA;AACT;AAOO,SAAS,qBAAqB,OAAA,EAAmD;AACtF,EAAA,IAAI,CAAC,OAAA,CAAQ,eAAA,EAAiB,OAAO,MAAA;AACrC,EAAA,OAAO,CAAA,EAAG,OAAA,CAAQ,iBAAiB,CAAA,CAAA,EAAI,QAAQ,eAAe,CAAA,CAAA;AAChE;AAgCO,SAAS,oBAAoB,OAAA,EAA4D;AAC9F,EAAA,MAAM,OAAA,GAAU,uBAAuB,OAAO,CAAA;AAC9C,EAAA,IAAI,CAAC,SAAS,OAAO,MAAA;AACrB,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,MAAA;AAAA,IACN,YAAY,OAAA,CAAQ,UAAA;AAAA,IACpB,UAAU,OAAA,CAAQ,iBAAA;AAAA,IAClB,GAAI,QAAQ,eAAA,GAAkB,EAAE,OAAO,OAAA,CAAQ,eAAA,KAAoB,EAAC;AAAA,IACpE,GAAI,OAAA,CAAQ,OAAA,GACR,EAAE,OAAA,EAAS,yBAAA,CAA0B,OAAA,CAAQ,OAAA,EAAS,OAAA,CAAQ,OAAO,CAAA,EAAE,GACvE,EAAC;AAAA,IACL,SAAA,EAAW,yBAAA,CAA0B,OAAA,CAAQ,UAAU;AAAA,GACzD;AACF","file":"chunk-C3YE4REG.js","sourcesContent":["/**\n * Registry adapter for the **env-shaped CLI drivers** — Gemini, Qwen, OpenCode,\n * Goose and Continue (§2.3).\n *\n * These backends take their endpoint from the environment rather than from a\n * config file, so the adapter's job is three things: resolve which registry\n * entry the session's model selector names, refuse at start when that entry\n * speaks a wire surface the backend cannot, and hand the driver the\n * provider-side model id it must put on the command line.\n *\n * Two pluralities meet here (`BUILTIN_DRIVER_CATALOG.providerPlurality`):\n *\n * - `single` — Gemini and Qwen address exactly one endpoint. The bound entry\n * supplies the credential *and* the base URL, and a surface mismatch is\n * fatal: a Gemini CLI pointed at an `openai-completions` endpoint cannot\n * work, and failing at start names the surface instead of leaving the user\n * with an opaque error mid-turn.\n * - `credentials-n` — OpenCode, Goose and Continue accept every enabled\n * entry's credential at once and select one active model. The credential\n * fan-out is `registryCredentialEnv`; the active model is this module's\n * `<provider>/<model>` binding.\n *\n * Writing the per-endpoint config files those three need for *custom*\n * endpoints (`opencode.json`, Goose `custom_providers/*.json`, Continue\n * `config.yaml`) is the file half, and is deliberately not here.\n *\n * @see PROVIDER-CONFIG-PLAN.md §2.3\n */\n\nimport {\n type AIProviderLlmEntry,\n type AIProviderSurface,\n isEntryEnabled,\n type MergedAIProviderRegistry,\n mergeRegistries,\n normalizeEntryBaseUrl,\n parseModelRef,\n registryEntries,\n resolveEntryBaseUrl,\n} from \"@skaile/workspaces/core/provider-registry\";\nimport type { ModelEntry } from \"../models.js\";\nimport { getProviderPreset } from \"../provider-catalog.js\";\nimport { BUILTIN_DRIVER_CATALOG } from \"../registry.js\";\nimport type { AgentConfig } from \"../types.js\";\nimport { providerCredentialEnvName, registryCredentialEnv } from \"./credential-env.js\";\n\n/**\n * Everything a CLI driver needs to know about this session's AI providers,\n * resolved once from its {@link AgentConfig}.\n */\nexport interface EnvDriverSession {\n /** The merged registry this session may address. Empty when none was configured. */\n registry: MergedAIProviderRegistry;\n /**\n * Environment `credential.ref` lookups resolve against — the process\n * environment widened with `config.env`, which is where the session\n * boundary delivered every resolved `SKAILE_AIP_<ID>_KEY`.\n */\n lookupEnv: Record<string, string | undefined>;\n /** Model selector: `<providerId>/<modelId>`, a bare id, or `@role`. */\n modelRef?: string;\n /** Roles table an `@role` selector resolves through. */\n roles?: Record<string, string>;\n}\n\n/**\n * Resolve the session's providers once, from its {@link AgentConfig}.\n *\n * `config.env` is folded into `lookupEnv` rather than kept apart: it is part\n * of the session's environment, not an extra, and a credential or\n * `*_BASE_URL` delivered there must be visible exactly as the child will see\n * it.\n */\nexport function resolveEnvDriverSession(\n config: AgentConfig,\n processEnv: Record<string, string | undefined> = process.env,\n): EnvDriverSession {\n return {\n registry: config.registry ?? mergeRegistries([]),\n lookupEnv: { ...processEnv, ...config.env },\n ...(config.modelRef ? { modelRef: config.modelRef } : {}),\n ...(config.roles ? { roles: config.roles } : {}),\n };\n}\n\n/** One resolved endpoint + model — everything a driver needs to spawn. */\nexport interface RegistryModelBinding {\n /** Registry id of the selected entry. */\n providerId: string;\n /** The selected entry itself. */\n entry: AIProviderLlmEntry;\n /** Logical model id, after `@role` expansion and before `model_map`. */\n modelId?: string;\n /** Provider-side model id — what goes on the wire / command line. */\n providerModelId?: string;\n /** Wire protocol, from the entry or its preset. */\n surface?: AIProviderSurface;\n /** Resolved endpoint, from the entry, its transport params, or its preset. */\n baseUrl?: string;\n /**\n * The provider name the *backend* knows this endpoint by — a catalog preset\n * id for a stock endpoint, the registry id for anything custom. See\n * {@link backendProviderName}.\n */\n backendProviderId: string;\n /** Non-fatal notes from `parseModelRef` (dangling role, disabled provider). */\n warnings: string[];\n}\n\n/** The entry's wire surface: its own, else its preset's. */\nexport function entrySurface(entry: AIProviderLlmEntry): AIProviderSurface | undefined {\n if (entry.surface) return entry.surface;\n return entry.preset ? getProviderPreset(entry.preset)?.surface : undefined;\n}\n\n/**\n * The entry's endpoint: its literal or transport-derived URL, else its\n * preset's literal, in the canonical spelling for its surface\n * (`normalizeEntryBaseUrl`: an `anthropic-messages` endpoint is its host root,\n * so `https://api.anthropic.com/v1` reads as `https://api.anthropic.com`).\n * Transport templates that still carry `{param}` placeholders never come\n * back — `resolveEntryBaseUrl` withholds those, and a preset's template is not\n * a URL.\n *\n * Every adapter reads the endpoint here and only re-spells it for a client\n * that wants something else ({@link versionedAnthropicBaseUrl}).\n */\nexport function entryBaseUrl(entry: AIProviderLlmEntry): string | undefined {\n const resolved =\n resolveEntryBaseUrl(entry) ??\n (entry.preset ? getProviderPreset(entry.preset)?.base_url : undefined);\n return normalizeEntryBaseUrl(resolved, entrySurface(entry));\n}\n\n/**\n * An `anthropic-messages` endpoint spelled for a client that appends only\n * `/messages` — `@ai-sdk/anthropic` (OpenCode) and Continue — rather than\n * `/v1/messages` like the Claude CLI, the Anthropic SDK and Goose. `baseUrl`\n * must already be canonical ({@link entryBaseUrl}); every other surface passes\n * through unchanged.\n */\nexport function versionedAnthropicBaseUrl(\n baseUrl: string,\n surface: AIProviderSurface | undefined,\n): string {\n if (surface !== \"anthropic-messages\") return baseUrl;\n // Append to the path, not the string: a query or fragment stays at the end.\n try {\n const url = new URL(baseUrl);\n url.pathname = `${url.pathname.replace(/\\/+$/, \"\")}/v1`;\n return url.toString();\n } catch {\n return `${baseUrl}/v1`;\n }\n}\n\n/**\n * True when a `credentials-n` backend already knows this endpoint under its\n * own catalog name — the entry names a preset and did not move it somewhere\n * else. Both sides are compared canonically, so `https://api.anthropic.com/v1`\n * is still the `anthropic` preset's endpoint.\n *\n * The one rule both halves of §2.3 read: it decides the name the env half\n * puts on the command line ({@link backendProviderName}) *and* whether the\n * file half has to describe the endpoint at all. Reading it twice is what\n * keeps `-m <name>/<model>` and the generated provider file talking about the\n * same thing.\n */\nexport function isStockCatalogEndpoint(entry: AIProviderLlmEntry): boolean {\n const preset = entry.preset ? getProviderPreset(entry.preset) : undefined;\n if (!preset) return false;\n return entryBaseUrl(entry) === normalizeEntryBaseUrl(preset.base_url, entrySurface(entry));\n}\n\n/**\n * The provider name to give a `credentials-n` backend (`-m <name>/<model>`,\n * `GOOSE_PROVIDER`).\n *\n * A stock catalog endpoint is named by its preset, because that is the name\n * OpenCode's models.dev list and Goose's built-in provider table already use —\n * `prod-claude: {preset: anthropic}` is still Anthropic to them. An entry with\n * an endpoint of its own is named by its registry id: no built-in table knows\n * it, so the id is what its generated provider file is keyed by (the file half\n * of §2.3).\n */\nexport function backendProviderName(providerId: string, entry: AIProviderLlmEntry): string {\n const preset = entry.preset ? getProviderPreset(entry.preset) : undefined;\n if (!preset || !isStockCatalogEndpoint(entry)) return providerId;\n return preset.id;\n}\n\n/**\n * Enabled `llm`/`embed` entries, in registry order. Also the set the file\n * adapters render (`opencode-config.ts`, `goose-custom-providers.ts`,\n * `continue-config-yaml.ts`): the env half and the file half must agree on\n * which entries exist before they can agree on what to call them.\n */\nexport function selectableEntries(\n registry: MergedAIProviderRegistry,\n): Array<[string, AIProviderLlmEntry]> {\n return registryEntries(registry).filter(\n (pair): pair is [string, AIProviderLlmEntry] =>\n (pair[1].kind === \"llm\" || pair[1].kind === \"embed\") && isEntryEnabled(pair[1]),\n );\n}\n\n/**\n * The provider-side model ids an entry declares, as `[logicalId, providerId]`\n * pairs in declaration order: every `model_map` entry, plus every\n * `capabilities` key the map does not rename.\n */\nexport function entryModelIds(entry: AIProviderLlmEntry): Array<[string, string]> {\n const logicalIds = [\n ...Object.keys(entry.model_map ?? {}),\n ...Object.keys(entry.capabilities ?? {}).filter((id) => !(id in (entry.model_map ?? {}))),\n ];\n return logicalIds.map((id) => [id, entry.model_map?.[id] ?? id]);\n}\n\nfunction describeBinding(\n providerId: string,\n entry: AIProviderLlmEntry,\n modelId: string | undefined,\n providerModelId: string | undefined,\n warnings: string[],\n): RegistryModelBinding {\n const surface = entrySurface(entry);\n const baseUrl = entryBaseUrl(entry);\n return {\n providerId,\n entry,\n ...(modelId === undefined ? {} : { modelId }),\n ...(providerModelId === undefined ? {} : { providerModelId }),\n ...(surface ? { surface } : {}),\n ...(baseUrl ? { baseUrl } : {}),\n backendProviderId: backendProviderName(providerId, entry),\n warnings,\n };\n}\n\n/**\n * Resolve the session's endpoint + model.\n *\n * With no selector the first entry in registry order wins and the backend\n * keeps its own default model — exactly what an absent `model` meant before\n * the registry existed. Returns `undefined` when no entry can serve a model\n * (an empty, fully-disabled or voice-only registry).\n */\nexport function resolveRegistryBinding(\n session: EnvDriverSession,\n): RegistryModelBinding | undefined {\n const entries = selectableEntries(session.registry);\n if (entries.length === 0) return undefined;\n\n const selector = session.modelRef?.trim();\n if (!selector) {\n const [providerId, entry] = entries[0];\n return describeBinding(providerId, entry, undefined, undefined, []);\n }\n\n // A selector that is exactly an entry id names the endpoint and nothing\n // else: the backend keeps its own default model. `parseModelRef` would read\n // it as a bare *model* id and fall back to registry order.\n const named = entries.find(([id]) => id === selector);\n if (named) return describeBinding(named[0], named[1], undefined, undefined, []);\n\n const resolved = parseModelRef(selector, session.registry, session.roles);\n if (!resolved) return undefined;\n const match = entries.find(([id]) => id === resolved.providerId);\n if (!match) return undefined;\n return describeBinding(\n match[0],\n match[1],\n resolved.modelId,\n resolved.providerModelId,\n resolved.warnings,\n );\n}\n\n/**\n * Every credential a `credentials-n` backend may use: one variable per\n * enabled registry entry. OpenCode, Goose and Continue have always received\n * *all* of them, not just the selected endpoint's, because they route across\n * providers inside a single session.\n */\nexport function credentialsForEveryProvider(session: EnvDriverSession): Record<string, string> {\n return registryCredentialEnv(session.registry, { env: session.lookupEnv });\n}\n\n/**\n * Throw when the bound entry speaks a wire surface this driver cannot.\n *\n * The message names the offending surface and lists the ones the backend does\n * speak (`BUILTIN_DRIVER_CATALOG[driverId].surfaces`). An entry that declares\n * no surface and names no preset is not judged — there is nothing to compare.\n */\nexport function assertDriverSpeaksSurface(\n driverId: string,\n productName: string,\n binding: RegistryModelBinding,\n): void {\n const supported = BUILTIN_DRIVER_CATALOG[driverId]?.surfaces;\n if (!supported || supported.length === 0) return;\n const surface = binding.surface;\n if (!surface || supported.includes(surface)) return;\n throw new Error(\n `${productName} cannot speak the '${surface}' surface of AI provider entry ` +\n `'${binding.providerId}'. ${productName} speaks: ${supported.join(\", \")}. ` +\n `Point this session's model at an entry with one of those surfaces, ` +\n `or run it on a driver that speaks '${surface}'.`,\n );\n}\n\n/**\n * The models a `credentials-n` backend can be pointed at, straight from the\n * registry: every enabled entry's mapped ids, namespaced the way the backend\n * takes them (`-m <provider>/<model>`).\n *\n * These backends have no model-list endpoint of their own — OpenCode reads\n * models.dev, Goose and Continue read their config — so the registry is the\n * only list that describes *this* session's reachable models, and it needs no\n * network call to produce.\n */\nexport function registryModelEntries(session: EnvDriverSession): ModelEntry[] {\n const out: ModelEntry[] = [];\n const seen = new Set<string>();\n for (const [providerId, entry] of selectableEntries(session.registry)) {\n const backendId = backendProviderName(providerId, entry);\n const label = entry.label ?? providerId;\n for (const [logicalId, providerModelId] of entryModelIds(entry)) {\n const id = `${backendId}/${providerModelId}`;\n if (seen.has(id)) continue;\n seen.add(id);\n out.push({ id, name: `${label} ${logicalId}` });\n }\n }\n return out;\n}\n\n/**\n * Resolve the binding and enforce the surface — what a `single`-plurality\n * driver does at start.\n *\n * The registry is authoritative: pointing the driver at an entry it cannot\n * speak throws rather than silently running somewhere else. `undefined` when\n * the session configured no endpoint at all, which leaves the driver on its\n * own native auth.\n */\nexport function bindSingleProviderEntry(\n driverId: string,\n productName: string,\n session: EnvDriverSession,\n): RegistryModelBinding | undefined {\n const binding = resolveRegistryBinding(session);\n if (!binding) return undefined;\n assertDriverSpeaksSurface(driverId, productName, binding);\n return binding;\n}\n\n/**\n * The `<provider>/<model>` selector a `credentials-n` backend takes on its\n * command line (`opencode -m`). `undefined` when no model was selected — the\n * backend then uses its own default rather than being handed a bare provider.\n */\nexport function backendModelSelector(binding: RegistryModelBinding): string | undefined {\n if (!binding.providerModelId) return undefined;\n return `${binding.backendProviderId}/${binding.providerModelId}`;\n}\n\n/**\n * Continue's model selection is a **role binding**, not a flag: `cn` has no\n * `--model` option (only `--config <slug>`), and its `config.yaml` binds each\n * model to roles (`chat`, `edit`, `apply`, …). This is the binding for the\n * role a headless `cn -p` turn runs as, and the shape its generated\n * `config.yaml` is rendered from.\n *\n * `apiKeyEnv` is a variable *name*: the secret travels in the child\n * environment, never in a rendered config.\n */\nexport interface ContinueRoleBinding {\n /** Continue role this model serves. A headless prompt is a `chat` turn. */\n role: \"chat\";\n /** Registry id of the entry. */\n providerId: string;\n /** Provider name Continue knows the endpoint by. */\n provider: string;\n /** Provider-side model id. */\n model?: string;\n /** Endpoint, when the entry states one, spelled the way Continue's `apiBase` wants it. */\n apiBase?: string;\n /** Env var holding the credential — the name, never the value. */\n apiKeyEnv: string;\n}\n\n/**\n * Map the session's chosen endpoint onto the Continue role a headless turn\n * runs as. `undefined` when the session configured no endpoint — `cn` then\n * runs against whatever its own `config.yaml` / Hub login provides.\n */\nexport function continueRoleBinding(session: EnvDriverSession): ContinueRoleBinding | undefined {\n const binding = resolveRegistryBinding(session);\n if (!binding) return undefined;\n return {\n role: \"chat\",\n providerId: binding.providerId,\n provider: binding.backendProviderId,\n ...(binding.providerModelId ? { model: binding.providerModelId } : {}),\n ...(binding.baseUrl\n ? { apiBase: versionedAnthropicBaseUrl(binding.baseUrl, binding.surface) }\n : {}),\n apiKeyEnv: providerCredentialEnvName(binding.providerId),\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../bridge/src/provider-materialize/env-drivers.ts"],"names":[],"mappings":"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","file":"chunk-25BOOOSM.js","sourcesContent":["/**\n * Registry adapter for the **env-shaped CLI drivers** — Gemini, Qwen, OpenCode,\n * Goose and Continue (§2.3).\n *\n * These backends take their endpoint from the environment rather than from a\n * config file, so the adapter's job is three things: resolve which registry\n * entry the session's model selector names, refuse at start when that entry\n * speaks a wire surface the backend cannot, and hand the driver the\n * provider-side model id it must put on the command line.\n *\n * Two pluralities meet here (`BUILTIN_DRIVER_CATALOG.providerPlurality`):\n *\n * - `single` — Gemini and Qwen address exactly one endpoint. The bound entry\n * supplies the credential *and* the base URL, and a surface mismatch is\n * fatal: a Gemini CLI pointed at an `openai-completions` endpoint cannot\n * work, and failing at start names the surface instead of leaving the user\n * with an opaque error mid-turn.\n * - `credentials-n` — OpenCode, Goose and Continue accept every enabled\n * entry's credential at once and select one active model. The credential\n * fan-out is `registryCredentialEnv`; the active model is this module's\n * `<provider>/<model>` binding.\n *\n * Writing the per-endpoint config files those three need for *custom*\n * endpoints (`opencode.json`, Goose `custom_providers/*.json`, Continue\n * `config.yaml`) is the file half, and is deliberately not here.\n *\n * @see PROVIDER-CONFIG-PLAN.md §2.3\n */\n\nimport {\n type AIProviderLlmEntry,\n type AIProviderSurface,\n isEntryEnabled,\n type MergedAIProviderRegistry,\n mergeRegistries,\n normalizeEntryBaseUrl,\n parseModelRef,\n registryEntries,\n resolveEntryBaseUrl,\n} from \"@skaile/workspaces/core/provider-registry\";\nimport type { ModelEntry } from \"../models.js\";\nimport { getProviderPreset } from \"../provider-catalog.js\";\nimport { BUILTIN_DRIVER_CATALOG } from \"../registry.js\";\nimport type { AgentConfig } from \"../types.js\";\nimport { providerCredentialEnvName, registryCredentialEnv } from \"./credential-env.js\";\n\n/**\n * Everything a CLI driver needs to know about this session's AI providers,\n * resolved once from its {@link AgentConfig}.\n */\nexport interface EnvDriverSession {\n /** The merged registry this session may address. Empty when none was configured. */\n registry: MergedAIProviderRegistry;\n /**\n * Environment `credential.ref` lookups resolve against — the process\n * environment widened with `config.env`, which is where the session\n * boundary delivered every resolved `SKAILE_AIP_<ID>_KEY`.\n */\n lookupEnv: Record<string, string | undefined>;\n /** Model selector: `<providerId>/<modelId>`, a bare id, or `@role`. */\n modelRef?: string;\n /** Roles table an `@role` selector resolves through. */\n roles?: Record<string, string>;\n}\n\n/**\n * Resolve the session's providers once, from its {@link AgentConfig}.\n *\n * `config.env` is folded into `lookupEnv` rather than kept apart: it is part\n * of the session's environment, not an extra, and a credential or\n * `*_BASE_URL` delivered there must be visible exactly as the child will see\n * it.\n */\nexport function resolveEnvDriverSession(\n config: AgentConfig,\n processEnv: Record<string, string | undefined> = process.env,\n): EnvDriverSession {\n return {\n registry: config.registry ?? mergeRegistries([]),\n lookupEnv: { ...processEnv, ...config.env },\n ...(config.modelRef ? { modelRef: config.modelRef } : {}),\n ...(config.roles ? { roles: config.roles } : {}),\n };\n}\n\n/** One resolved endpoint + model — everything a driver needs to spawn. */\nexport interface RegistryModelBinding {\n /** Registry id of the selected entry. */\n providerId: string;\n /** The selected entry itself. */\n entry: AIProviderLlmEntry;\n /** Logical model id, after `@role` expansion and before `model_map`. */\n modelId?: string;\n /** Provider-side model id — what goes on the wire / command line. */\n providerModelId?: string;\n /** Wire protocol, from the entry or its preset. */\n surface?: AIProviderSurface;\n /** Resolved endpoint, from the entry, its transport params, or its preset. */\n baseUrl?: string;\n /**\n * The provider name the *backend* knows this endpoint by — a catalog preset\n * id for a stock endpoint, the registry id for anything custom. See\n * {@link backendProviderName}.\n */\n backendProviderId: string;\n /** Non-fatal notes from `parseModelRef` (dangling role, disabled provider). */\n warnings: string[];\n}\n\n/** The entry's wire surface: its own, else its preset's. */\nexport function entrySurface(entry: AIProviderLlmEntry): AIProviderSurface | undefined {\n if (entry.surface) return entry.surface;\n return entry.preset ? getProviderPreset(entry.preset)?.surface : undefined;\n}\n\n/**\n * The entry's endpoint: its literal or transport-derived URL, else its\n * preset's literal, in the canonical spelling for its surface\n * (`normalizeEntryBaseUrl`: an `anthropic-messages` endpoint is its host root,\n * so `https://api.anthropic.com/v1` reads as `https://api.anthropic.com`).\n * Transport templates that still carry `{param}` placeholders never come\n * back — `resolveEntryBaseUrl` withholds those, and a preset's template is not\n * a URL.\n *\n * Every adapter reads the endpoint here and only re-spells it for a client\n * that wants something else ({@link versionedAnthropicBaseUrl}).\n */\nexport function entryBaseUrl(entry: AIProviderLlmEntry): string | undefined {\n const resolved =\n resolveEntryBaseUrl(entry) ??\n (entry.preset ? getProviderPreset(entry.preset)?.base_url : undefined);\n return normalizeEntryBaseUrl(resolved, entrySurface(entry));\n}\n\n/**\n * An `anthropic-messages` endpoint spelled for a client that appends only\n * `/messages` — `@ai-sdk/anthropic` (OpenCode) and Continue — rather than\n * `/v1/messages` like the Claude CLI, the Anthropic SDK and Goose. `baseUrl`\n * must already be canonical ({@link entryBaseUrl}); every other surface passes\n * through unchanged.\n */\nexport function versionedAnthropicBaseUrl(\n baseUrl: string,\n surface: AIProviderSurface | undefined,\n): string {\n if (surface !== \"anthropic-messages\") return baseUrl;\n // Append to the path, not the string: a query or fragment stays at the end.\n try {\n const url = new URL(baseUrl);\n url.pathname = `${url.pathname.replace(/\\/+$/, \"\")}/v1`;\n return url.toString();\n } catch {\n return `${baseUrl}/v1`;\n }\n}\n\n/**\n * True when a `credentials-n` backend already knows this endpoint under its\n * own catalog name — the entry names a preset and did not move it somewhere\n * else. Both sides are compared canonically, so `https://api.anthropic.com/v1`\n * is still the `anthropic` preset's endpoint.\n *\n * The one rule both halves of §2.3 read: it decides the name the env half\n * puts on the command line ({@link backendProviderName}) *and* whether the\n * file half has to describe the endpoint at all. Reading it twice is what\n * keeps `-m <name>/<model>` and the generated provider file talking about the\n * same thing.\n */\nexport function isStockCatalogEndpoint(entry: AIProviderLlmEntry): boolean {\n const preset = entry.preset ? getProviderPreset(entry.preset) : undefined;\n if (!preset) return false;\n return entryBaseUrl(entry) === normalizeEntryBaseUrl(preset.base_url, entrySurface(entry));\n}\n\n/**\n * The provider name to give a `credentials-n` backend (`-m <name>/<model>`,\n * `GOOSE_PROVIDER`).\n *\n * A stock catalog endpoint is named by its preset, because that is the name\n * OpenCode's models.dev list and Goose's built-in provider table already use —\n * `prod-claude: {preset: anthropic}` is still Anthropic to them. An entry with\n * an endpoint of its own is named by its registry id: no built-in table knows\n * it, so the id is what its generated provider file is keyed by (the file half\n * of §2.3).\n */\nexport function backendProviderName(providerId: string, entry: AIProviderLlmEntry): string {\n const preset = entry.preset ? getProviderPreset(entry.preset) : undefined;\n if (!preset || !isStockCatalogEndpoint(entry)) return providerId;\n return preset.id;\n}\n\n/**\n * Enabled `llm`/`embed` entries, in registry order. Also the set the file\n * adapters render (`opencode-config.ts`, `goose-custom-providers.ts`,\n * `continue-config-yaml.ts`): the env half and the file half must agree on\n * which entries exist before they can agree on what to call them.\n */\nexport function selectableEntries(\n registry: MergedAIProviderRegistry,\n): Array<[string, AIProviderLlmEntry]> {\n return registryEntries(registry).filter(\n (pair): pair is [string, AIProviderLlmEntry] =>\n (pair[1].kind === \"llm\" || pair[1].kind === \"embed\") && isEntryEnabled(pair[1]),\n );\n}\n\n/**\n * The provider-side model ids an entry declares, as `[logicalId, providerId]`\n * pairs in declaration order: every `model_map` entry, plus every\n * `capabilities` key the map does not rename.\n */\nexport function entryModelIds(entry: AIProviderLlmEntry): Array<[string, string]> {\n const logicalIds = [\n ...Object.keys(entry.model_map ?? {}),\n ...Object.keys(entry.capabilities ?? {}).filter((id) => !(id in (entry.model_map ?? {}))),\n ];\n return logicalIds.map((id) => [id, entry.model_map?.[id] ?? id]);\n}\n\nfunction describeBinding(\n providerId: string,\n entry: AIProviderLlmEntry,\n modelId: string | undefined,\n providerModelId: string | undefined,\n warnings: string[],\n): RegistryModelBinding {\n const surface = entrySurface(entry);\n const baseUrl = entryBaseUrl(entry);\n return {\n providerId,\n entry,\n ...(modelId === undefined ? {} : { modelId }),\n ...(providerModelId === undefined ? {} : { providerModelId }),\n ...(surface ? { surface } : {}),\n ...(baseUrl ? { baseUrl } : {}),\n backendProviderId: backendProviderName(providerId, entry),\n warnings,\n };\n}\n\n/**\n * Resolve the session's endpoint + model.\n *\n * With no selector the first entry in registry order wins and the backend\n * keeps its own default model — exactly what an absent `model` meant before\n * the registry existed. Returns `undefined` when no entry can serve a model\n * (an empty, fully-disabled or voice-only registry).\n */\nexport function resolveRegistryBinding(\n session: EnvDriverSession,\n): RegistryModelBinding | undefined {\n const entries = selectableEntries(session.registry);\n if (entries.length === 0) return undefined;\n\n const selector = session.modelRef?.trim();\n if (!selector) {\n const [providerId, entry] = entries[0];\n return describeBinding(providerId, entry, undefined, undefined, []);\n }\n\n // A selector that is exactly an entry id names the endpoint and nothing\n // else: the backend keeps its own default model. `parseModelRef` would read\n // it as a bare *model* id and fall back to registry order.\n const named = entries.find(([id]) => id === selector);\n if (named) return describeBinding(named[0], named[1], undefined, undefined, []);\n\n const resolved = parseModelRef(selector, session.registry, session.roles);\n if (!resolved) return undefined;\n const match = entries.find(([id]) => id === resolved.providerId);\n if (!match) return undefined;\n return describeBinding(\n match[0],\n match[1],\n resolved.modelId,\n resolved.providerModelId,\n resolved.warnings,\n );\n}\n\n/**\n * Every credential a `credentials-n` backend may use: one variable per\n * enabled registry entry. OpenCode, Goose and Continue have always received\n * *all* of them, not just the selected endpoint's, because they route across\n * providers inside a single session.\n */\nexport function credentialsForEveryProvider(session: EnvDriverSession): Record<string, string> {\n return registryCredentialEnv(session.registry, { env: session.lookupEnv });\n}\n\n/**\n * Throw when the bound entry speaks a wire surface this driver cannot.\n *\n * The message names the offending surface and lists the ones the backend does\n * speak (`BUILTIN_DRIVER_CATALOG[driverId].surfaces`). An entry that declares\n * no surface and names no preset is not judged — there is nothing to compare.\n */\nexport function assertDriverSpeaksSurface(\n driverId: string,\n productName: string,\n binding: RegistryModelBinding,\n): void {\n const supported = BUILTIN_DRIVER_CATALOG[driverId]?.surfaces;\n if (!supported || supported.length === 0) return;\n const surface = binding.surface;\n if (!surface || supported.includes(surface)) return;\n throw new Error(\n `${productName} cannot speak the '${surface}' surface of AI provider entry ` +\n `'${binding.providerId}'. ${productName} speaks: ${supported.join(\", \")}. ` +\n `Point this session's model at an entry with one of those surfaces, ` +\n `or run it on a driver that speaks '${surface}'.`,\n );\n}\n\n/**\n * The models a `credentials-n` backend can be pointed at, straight from the\n * registry: every enabled entry's mapped ids, namespaced the way the backend\n * takes them (`-m <provider>/<model>`).\n *\n * These backends have no model-list endpoint of their own — OpenCode reads\n * models.dev, Goose and Continue read their config — so the registry is the\n * only list that describes *this* session's reachable models, and it needs no\n * network call to produce.\n */\nexport function registryModelEntries(session: EnvDriverSession): ModelEntry[] {\n const out: ModelEntry[] = [];\n const seen = new Set<string>();\n for (const [providerId, entry] of selectableEntries(session.registry)) {\n const backendId = backendProviderName(providerId, entry);\n const label = entry.label ?? providerId;\n for (const [logicalId, providerModelId] of entryModelIds(entry)) {\n const id = `${backendId}/${providerModelId}`;\n if (seen.has(id)) continue;\n seen.add(id);\n out.push({ id, name: `${label} ${logicalId}` });\n }\n }\n return out;\n}\n\n/**\n * Resolve the binding and enforce the surface — what a `single`-plurality\n * driver does at start.\n *\n * The registry is authoritative: pointing the driver at an entry it cannot\n * speak throws rather than silently running somewhere else. `undefined` when\n * the session configured no endpoint at all, which leaves the driver on its\n * own native auth.\n */\nexport function bindSingleProviderEntry(\n driverId: string,\n productName: string,\n session: EnvDriverSession,\n): RegistryModelBinding | undefined {\n const binding = resolveRegistryBinding(session);\n if (!binding) return undefined;\n assertDriverSpeaksSurface(driverId, productName, binding);\n return binding;\n}\n\n/**\n * The `<provider>/<model>` selector a `credentials-n` backend takes on its\n * command line (`opencode -m`). `undefined` when no model was selected — the\n * backend then uses its own default rather than being handed a bare provider.\n */\nexport function backendModelSelector(binding: RegistryModelBinding): string | undefined {\n if (!binding.providerModelId) return undefined;\n return `${binding.backendProviderId}/${binding.providerModelId}`;\n}\n\n/**\n * Continue's model selection is a **role binding**, not a flag: `cn` has no\n * `--model` option (only `--config <slug>`), and its `config.yaml` binds each\n * model to roles (`chat`, `edit`, `apply`, …). This is the binding for the\n * role a headless `cn -p` turn runs as, and the shape its generated\n * `config.yaml` is rendered from.\n *\n * `apiKeyEnv` is a variable *name*: the secret travels in the child\n * environment, never in a rendered config.\n */\nexport interface ContinueRoleBinding {\n /** Continue role this model serves. A headless prompt is a `chat` turn. */\n role: \"chat\";\n /** Registry id of the entry. */\n providerId: string;\n /** Provider name Continue knows the endpoint by. */\n provider: string;\n /** Provider-side model id. */\n model?: string;\n /** Endpoint, when the entry states one, spelled the way Continue's `apiBase` wants it. */\n apiBase?: string;\n /** Env var holding the credential — the name, never the value. */\n apiKeyEnv: string;\n}\n\n/**\n * Map the session's chosen endpoint onto the Continue role a headless turn\n * runs as. `undefined` when the session configured no endpoint — `cn` then\n * runs against whatever its own `config.yaml` / Hub login provides.\n */\nexport function continueRoleBinding(session: EnvDriverSession): ContinueRoleBinding | undefined {\n const binding = resolveRegistryBinding(session);\n if (!binding) return undefined;\n return {\n role: \"chat\",\n providerId: binding.providerId,\n provider: binding.backendProviderId,\n ...(binding.providerModelId ? { model: binding.providerModelId } : {}),\n ...(binding.baseUrl\n ? { apiBase: versionedAnthropicBaseUrl(binding.baseUrl, binding.surface) }\n : {}),\n apiKeyEnv: providerCredentialEnvName(binding.providerId),\n };\n}\n"]}
|
|
@@ -298,5 +298,5 @@ function resolveProjectDir(additionalEnvVars) {
|
|
|
298
298
|
}
|
|
299
299
|
|
|
300
300
|
export { PluginStore, WorkspacePlugin, buildClaudePluginFiles, resolveProjectDir };
|
|
301
|
-
//# sourceMappingURL=chunk-
|
|
302
|
-
//# sourceMappingURL=chunk-
|
|
301
|
+
//# sourceMappingURL=chunk-66MJRB6K.js.map
|
|
302
|
+
//# sourceMappingURL=chunk-66MJRB6K.js.map
|