@tangle-network/sdk-provider-cli-base 0.12.0 → 0.13.1

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 (3) hide show
  1. package/dist/index.d.mts +187 -555
  2. package/dist/index.mjs +952 -785
  3. package/package.json +8 -8
package/dist/index.d.mts CHANGED
@@ -1,12 +1,15 @@
1
1
  import { a as partitionImageAttachments, i as PreparedAttachment, n as MAX_TOTAL_INLINE_IMAGE_BYTES, o as preparePromptInputParts, r as PROMPT_SECTION_SEPARATOR, s as prependPromptSection, t as MAX_INLINE_IMAGE_BYTES } from "./prompt-input-BHn_1z69.mjs";
2
2
  import { AskUserBridge, DEFAULT_INTERACTION_DECISION_TIMEOUT_MS as PERMISSION_DECISION_TIMEOUT_MS, InteractionBroker, InteractionBroker as InteractionBroker$1, InteractionHttpBridge, PermissionPromptBridge, RequestPermissionBridge, RequestPlanBridge, brokerInteractionTools } from "@tangle-network/agent-core/interactions";
3
+ import * as _$_tangle_network_agent_profile_materialize0 from "@tangle-network/agent-profile-materialize";
4
+ import { BindableLaunchControl, CODEX_DISABLED_FEATURE_ARGS, HarnessId, HarnessId as HarnessId$1, WorkspacePlanApplication, WorkspacePlanApplication as WorkspacePlanApplication$1, WorkspacePlanReceipt, codexDeveloperInstructionArgs } from "@tangle-network/agent-profile-materialize";
3
5
  import { CliExecResult, CliExitResult, CliLauncher, CliProcess, CliSpawnConfig, InvalidAttachmentError, JsonRpcError, RpcBridge, StreamParserConfig } from "@tangle-network/sdk-cli-runner";
4
6
  import { AgentExecutionInput, AgentExecutionOutcome, AgentExecutionResult, AgentProfile, AgentProfileSecretProvider, AgentRuntimeAttachments, BackendCapabilities, BackendMessage, CliAuthFile, DurablePlan, GetMessagesOptions, HarnessType, InputPart, InteractionExecutionBinding, InteractionResponse, LocalMcpConfig, McpConfig, McpStatusResponse, PlanProviderState, ProviderConfig, ReasoningEffort, RequestedInteractions, SdkHostServices, SdkPlanHost, SdkProviderAdapter, StreamEvent, TokenUsage, ToolPart } from "@tangle-network/agent-interface";
5
- import { BindableLaunchControl, HarnessId, HarnessId as HarnessId$1, WorkspacePlanApplication, WorkspacePlanApplication as WorkspacePlanApplication$1, WorkspacePlanReceipt } from "@tangle-network/agent-profile-materialize";
6
7
  import { HarnessSessionContract } from "@tangle-network/cli-agent-registry/session-contract";
7
- import { MessagePart, MessageStore, PersistedMessage, PersistedSession, SessionStore, readProviderMessageIds } from "@tangle-network/sdk-session-persistence";
8
+ import { MessagePart as MessagePart$1, MessageStore, PersistedMessage, PersistedSession, SessionStore, readProviderMessageIds } from "@tangle-network/sdk-session-persistence";
8
9
  import { ProviderLogger } from "@tangle-network/cli-agent-registry";
10
+ import { NATIVE_SESSION_CONTRACTS } from "@tangle-network/cli-agent-registry/native-session-contracts";
9
11
  import { DEFAULT_INTERACTION_MCP_SERVER_NAME, InteractionMcpServer as InteractionMcpServer$1, InteractionMcpServerConfig as InteractionMcpServerConfig$1, interactionMcpToolName } from "@tangle-network/agent-core/interactions/mcp";
12
+ import { isRecord as isPlainRecord } from "@tangle-network/agent-core";
10
13
 
11
14
  //#region src/acp-process-launch.d.ts
12
15
  /** How to start the agent process for a session. */
@@ -27,76 +30,75 @@ interface AcpBridgeSpawn {
27
30
  uid?: number;
28
31
  gid?: number;
29
32
  }
30
- /** Spawn an ACP agent over NDJSON stdio. The adapter owns abort, so no signal. */
33
+ /** Spawn an ACP agent over NDJSON stdio from `env` alone, never the sidecar's own environment. The adapter owns abort, so no signal. */
31
34
  declare function spawnAcpBridge(request: AcpBridgeSpawn): RpcBridge;
32
35
  //#endregion
36
+ //#region src/secret-profile-mcp.d.ts
37
+ /** Executor-held MCP credentials shared by native private-profile adapters. */
38
+ declare const SECRET_REFERENCE_PREFIX = "TANGLE_PROFILE_SECRET_";
39
+ declare const SECRET_REFERENCE: RegExp;
40
+ declare function requireRecord(raw: unknown, message: string): Record<string, unknown>;
41
+ /** One MCP server the executor serves for a secret launch. */
42
+ type SecretProfileMcpServer = {
43
+ name: string; /** The server's own upstream URL. */
44
+ url: string; /** Every header the upstream needs, credentials included. */
45
+ headers: Readonly<Record<string, string>>;
46
+ } | {
47
+ name: string; /** A stdio server whose environment names a secret: the executor runs this command outside the session's UID and serves it over loopback. */
48
+ command: readonly string[]; /** Its environment with every secret reference resolved. */
49
+ environment: Readonly<Record<string, string>>; /** Every secret value its environment references, whatever its length. */
50
+ secrets: readonly string[];
51
+ };
52
+ /** The executor's loopback proxy for a secret launch's MCP servers. */
53
+ type SecretProfileMcpCredentialProxy = {
54
+ /** The scope's placeholder and one loopback URL per server name. */endpoint(scope: string, names: readonly string[]): Promise<{
55
+ placeholder: string;
56
+ urls: Readonly<Record<string, string>>;
57
+ }>; /** Serve `servers` before resolving; release acknowledges lease termination before the turn settles or its scope is reused. */
58
+ lease(scope: string, servers: ReadonlyArray<SecretProfileMcpServer>): Promise<() => void | Promise<void>>; /** The scope's session ended: its placeholder is refused from now on and its stdio servers are stopped. */
59
+ forget(scope: string): Promise<void>;
60
+ };
61
+ /** A config value with its secret references resolved, or undefined. */
62
+ declare function resolveReferences(value: string, references: Readonly<Record<string, string>>): string | undefined;
63
+ /** A stdio server the executor can run: its command and its environment with every secret reference resolved. */
64
+ declare function servableStdioServer(name: string, entry: Record<string, unknown>, references: Readonly<Record<string, string>>): SecretProfileMcpServer | string;
65
+ /** A remote server the executor can serve: its fixed upstream URL and every header with its secret references resolved. */
66
+ declare function servableMcpServer(name: string, entry: Record<string, unknown>, references: Readonly<Record<string, string>>): SecretProfileMcpServer | string;
67
+ /** Join the queue at `key`; `previous` settles when earlier holders release. */
68
+ declare function joinQueue(queues: Map<string, Promise<void>>, key: string): {
69
+ previous: Promise<void>;
70
+ release: () => void;
71
+ };
72
+ declare function untilSettledOrAborted(previous: Promise<void>, signal: AbortSignal): Promise<void>;
73
+ /** Every native discovery ancestor is sealed and free of ambient configuration. */
74
+ declare function assertSealedNativeSearchPath(cwd: string, configNames: readonly string[]): void;
75
+ declare function secretSessionTurnQueue(view: string): {
76
+ previous: Promise<void>;
77
+ release: () => void;
78
+ };
79
+ /** An HTTP URL on loopback with an explicit port and no URL credentials. */
80
+ declare function isLoopbackEndpoint(value: unknown): boolean;
81
+ //#endregion
33
82
  //#region src/types.d.ts
34
83
  type InteractionToggleKind = keyof RequestedInteractions;
35
84
  type InteractionToggleConfig = boolean | RequestedInteractions;
36
85
  declare function interactionToggleEnabled(config: InteractionToggleConfig | undefined, kind: InteractionToggleKind): boolean;
37
86
  declare function enabledInteractionKinds<TKind extends InteractionToggleKind>(config: InteractionToggleConfig | undefined, supported: readonly TKind[]): TKind[];
38
- /**
39
- * Per-turn interaction toggle carried on the execution input. Native harnesses
40
- * treat plan mode as a per-turn property (toggle build/plan on any message), so
41
- * the sidecar sends this turn's interactions on the execution input.
42
- *
43
- * The shared execution contract owns this field. Adapter initialization still
44
- * accepts `true` as shorthand, but each turn carries an exact kind map.
45
- */
87
+ /** Per-turn interaction toggle carried on the execution input. */
46
88
  type PerTurnInteractionInput = Pick<AgentExecutionInput, "interactions">;
47
- /**
48
- * Host-composed context for THIS turn only (e.g. the sidecar's container
49
- * runtime snapshot): it must reach the model and nothing else. The caller's
50
- * `parts`/`message` stay untouched, so recorders and message stores keep a
51
- * transcript of exactly what the user sent.
52
- *
53
- * Optional for the same reason as `PerTurnInteractionInput.interactions`: the
54
- * published `AgentExecutionInput` does not declare the field, and `systemPrompt`
55
- * anchors the weak-type check.
56
- */
89
+ /** Host-composed context for THIS turn only (e.g. */
57
90
  type EphemeralContextInput = {
58
91
  ephemeralContext?: string;
59
92
  systemPrompt?: unknown;
60
93
  };
61
- /**
62
- * Read a turn's ephemeral context, rejecting a wrong-typed value loudly.
63
- *
64
- * The published `AgentExecutionInput` does not declare the field, so nothing
65
- * type-checks it at the process boundary. Left unchecked, a caller passing a
66
- * non-string gets it stringified into the model prompt (`[object Object]`) —
67
- * a corrupted turn with no error anywhere. `undefined`/`null` mean "no context
68
- * this turn"; an empty string is likewise nothing to append.
69
- */
70
94
  declare function readEphemeralContext(input: EphemeralContextInput): string | undefined;
71
- /**
72
- * Compose the model-facing prompt for a turn: the caller's own text, then this
73
- * turn's ephemeral context. Call it at the point the prompt is handed to the
74
- * provider — NEVER on the parts handed to `recordUserMessage` or the message
75
- * store.
76
- */
95
+ /** Compose the model-facing prompt for a turn: the caller's own text, then this turn's ephemeral context. */
77
96
  declare function withEphemeralContext(promptText: string, input: EphemeralContextInput): string;
78
- /**
79
- * Resolve whether an interaction kind is active for THIS turn. When the turn
80
- * carries `interactions` it is authoritative — a complete set that can also
81
- * turn a kind OFF mid-session; otherwise the adapter falls back to its latched
82
- * config (the initialize-time wiring, or a direct non-sidecar caller's option).
83
- */
84
97
  declare function turnInteractionEnabled(input: PerTurnInteractionInput, latched: InteractionToggleConfig | undefined, kind: InteractionToggleKind): boolean;
85
- /**
86
- * Overlay this turn's interactions onto a latched config, returning a NEW
87
- * object (no shared mutation — safe when one adapter instance serves concurrent
88
- * turns from different sessions). When the turn omits `interactions` the config
89
- * is returned unchanged, preserving behavior for direct non-sidecar callers.
90
- * Adapters read plan/permission/question posture off the returned config so a
91
- * mid-session toggle takes effect and can turn a kind off (which the latched
92
- * config, only ever merged by updateConfig, cannot).
93
- */
98
+ /** Overlay this turn's interactions onto a latched config, returning a NEW object (no shared mutation — safe when. */
94
99
  declare function withTurnInteractions<TConfig extends {
95
100
  interactions?: InteractionToggleConfig;
96
101
  }>(config: TConfig, input: PerTurnInteractionInput): TConfig;
97
- /**
98
- * Logger interface for CLI providers.
99
- */
100
102
  interface CliProviderLogger {
101
103
  observePhase?: ProviderLogger["observePhase"];
102
104
  debug(message: string, meta?: Record<string, unknown>): void;
@@ -104,167 +106,74 @@ interface CliProviderLogger {
104
106
  warn(message: string, meta?: Record<string, unknown>): void;
105
107
  error(message: string, meta?: Record<string, unknown>): void;
106
108
  }
107
- /**
108
- * Base configuration shared by all CLI providers.
109
- */
110
109
  interface CliProviderConfig {
111
110
  /** Trusted native auth projection resolved by the owning execution host. */
112
111
  nativeAuthEnv?: Record<string, string>;
113
112
  nativeAuthSecretEnv?: string;
114
- /** Sidecar-owned credential HOME for this adapter instance. */
115
113
  runtimeHome?: string;
116
- /**
117
- * Shared, persistent agent HOME. With `runtimeHome`, a harness whose
118
- * contract can move its native stores off HOME runs with this HOME and keeps
119
- * those stores in `runtimeHome` (configDirHomeEnv). Absent for an
120
- * isolated-profile identity, which keeps the private HOME.
121
- */
114
+ /** Shared, persistent agent HOME. */
122
115
  agentHome?: string;
123
116
  /** Trusted, adapter-wide native process identity supplied by the executor. */
124
117
  subprocessUser?: {
125
118
  uid: number;
126
119
  gid: number;
127
120
  };
128
- /**
129
- * The executor keeps this subprocess identity for later backends of the
130
- * same session, principal and profile authority: the session's secret MCP
131
- * scope and its warm native server outlive this adapter, so the next turn's
132
- * backend reuses its running stdio servers and native server. Session end
133
- * and their idle TTLs still stop them.
134
- */
121
+ /** The executor keeps this subprocess identity for later backends of the same session, principal and profile authority: the. */
135
122
  stableIsolatedIdentity?: boolean;
136
- /** Executor-owned base for public, per-revision native profile controls. */
137
123
  publicProfileRevisionRoot?: string;
138
124
  /** Executor-owned base for UID-restricted secret profile revisions. */
139
125
  secretProfileRevisionRoot?: string;
140
126
  /** Root-only 32-byte HMAC key; never copied into a turn result. */
141
127
  secretProfileNamingKeyPath?: string;
142
- /**
143
- * True when the CLI runs inside a sandbox container or VM, where the OS
144
- * boundary already confines file access. False or absent means the CLI may
145
- * run on a developer's host, so harness path guards stay in force.
146
- */
147
128
  sandboxedRuntime?: boolean;
148
- /** Portable profile applied to this provider execution. */
149
129
  profile?: AgentProfile;
150
130
  runtimeAttachments?: AgentRuntimeAttachments;
151
- /**
152
- * Per-turn credential values resolved by secret references in this
153
- * execution's runtime MCP attachments. The materialization secret provider
154
- * checks this map before the host box environment; values are launch
155
- * state only and never enter the CLI's inherited environment or logs.
156
- */
131
+ /** Per-turn credential values resolved by secret references in this execution's runtime MCP attachments. */
157
132
  runtimeSecrets?: Record<string, string>;
158
- /** Path to the CLI executable */
159
133
  cliPath?: string;
160
- /** Default model to use */
161
134
  model?: string;
162
- /** Model provider selected by the caller. */
163
135
  provider?: string;
164
- /** API key (provider-specific env var name) */
165
136
  apiKey?: string;
166
- /** OpenAI-compatible or provider-native base URL. */
167
137
  baseUrl?: string;
168
- /** Optional auth files to materialize under the runtime home directory. */
169
138
  authFiles?: Array<{
170
139
  path: string;
171
140
  content: string;
172
141
  mode?: number;
173
142
  }>;
174
- /** Extra flags to pass to the CLI */
175
143
  extraFlags?: string[];
176
- /**
177
- * Bypass all permission checks for fully autonomous operation.
178
- * Each CLI has its own flag:
179
- * - Claude Code: --dangerously-skip-permissions
180
- * - Codex: --dangerously-bypass-approvals-and-sandbox
181
- * - Factory Droids: --autonomy-level skip-permissions-unsafe
182
- * Default: true (for headless/automated use)
183
- */
184
144
  bypassPermissions?: boolean;
185
- /**
186
- * Enable structured human interactions by kind. `true` means "all supported
187
- * kinds for this adapter"; object form is the precise public surface:
188
- * `{ question: true }`, `{ permission: true }`, `{ plan: true }`.
189
- *
190
- * Each adapter maps these requested kinds onto its native transport (MCP,
191
- * reverse RPC, or extension hook) while all responses flow through the same
192
- * `/interactions` API.
193
- */
194
145
  interactions?: InteractionToggleConfig;
195
146
  }
196
- /**
197
- * Options for CLI provider adapter constructors.
198
- */
199
147
  interface CliProviderOptions<TConfig extends CliProviderConfig = CliProviderConfig> {
200
- /** Provider configuration */
201
148
  config?: TConfig;
202
- /** Logger instance */
203
149
  logger?: CliProviderLogger;
204
- /** Base storage path for session persistence */
205
150
  storagePath?: string;
206
- /** Storage subdirectory name (e.g., ".claude-code", ".codex") */
207
151
  storageDir?: string;
208
152
  /** Resolve opaque AgentProfile secret references at the private spawn boundary. */
209
153
  profileSecretProvider?: AgentProfileSecretProvider;
210
- /**
211
- * For a secret profile revision: the keys the runtime itself manages (the
212
- * box's TANGLE_API_KEY), which a turn may not deliver as runtimeSecrets.
213
- * Their values reach only the executor's own MCP serving, never the launch.
214
- * Anything else a secret revision references comes from runtimeSecrets.
215
- */
154
+ /** For a secret profile revision: the keys the runtime itself manages (the box's TANGLE_API_KEY), which a turn may not deliver as runtimeSecrets. */
216
155
  secretProfileRuntimeKeyProvider?: AgentProfileSecretProvider;
217
- /**
218
- * Environment every CLI child gets in place of the inherited one for these
219
- * keys: in a sandbox, the agent user's own HOME, PATH and cache paths, so a
220
- * child never inherits the supervisor's cache paths it cannot write. The
221
- * adapter's own environment still wins for any key it sets.
222
- */
223
- agentEnvironment?: () => Record<string, string | undefined>;
224
- /**
225
- * Start each turn's CLI through the consumer's own executor (a container
226
- * slot, a jail) instead of a local spawn. It receives the assembled argv,
227
- * cwd and environment; the adapter still parses, times and stops the turn.
228
- */
156
+ /** Serves native private-profile MCP servers without giving their keys to the CLI. */
157
+ mcpCredentialProxy?: SecretProfileMcpCredentialProxy;
158
+ /** Environment every CLI child gets in place of the inherited one for these keys: in a sandbox, the. */
159
+ agentEnvironment?: (launch: {
160
+ secretProfile: boolean;
161
+ }) => Record<string, string | undefined>;
229
162
  launcher?: CliLauncher;
230
- /**
231
- * Stop what a turn's CLI leaves running in its process group when it exits.
232
- * Off by default: a sandbox turn may start a process meant to outlive it.
233
- */
234
163
  ownProcessGroup?: boolean;
235
164
  }
236
- /**
237
- * Per-turn input a CLI adapter reads beyond AgentExecutionInput: text added
238
- * after the harness's own system prompt (a chat caller's system messages),
239
- * kept apart from `systemPrompt`, which replaces it.
240
- */
165
+ /** Per-turn input a CLI adapter reads beyond AgentExecutionInput: text added after the harness's own system prompt (a chat. */
241
166
  type CliExecutionInput = AgentExecutionInput & {
242
167
  appendSystemPrompt?: string;
243
168
  };
244
- /**
245
- * CLI execution arguments.
246
- */
247
169
  interface CliExecArgs {
248
- /** CLI command */
249
170
  command: string;
250
- /** Command arguments */
251
171
  args: string[];
252
- /** Whether to send message via stdin */
253
172
  useStdin: boolean;
254
- /** Stdin prompt text before provider formatting. Defaults to the prepared user prompt. */
255
173
  stdin?: string;
256
- /**
257
- * Working directory for the spawned process. Defaults to the execution
258
- * workspaceRoot when omitted. Set when the CLI must run from a different root
259
- * than the session workspace — e.g. nanoclaw's chat script derives its data
260
- * dir (the daemon's Unix socket) from cwd, so it must run from the runtime
261
- * root, not the sandbox workspace.
262
- */
174
+ /** Working directory for the spawned process. */
263
175
  cwd?: string;
264
176
  }
265
- /**
266
- * Internal state for tracking tool calls during execution.
267
- */
268
177
  interface ToolCallState {
269
178
  id: string;
270
179
  name: string;
@@ -273,42 +182,33 @@ interface ToolCallState {
273
182
  status: "pending" | "running" | "completed" | "failed";
274
183
  output?: unknown;
275
184
  }
185
+ /** How a turn ended: the closed set every harness names its end in (#16404). */
186
+ type TurnEndReason = "success" | "abort" | "timeout" | "gateway_disconnect" | "harness_exit" | "memory_limit" | "repeated_tool_failure" | "failed";
276
187
  /**
277
- * Internal state for an execution run.
188
+ * The one precedence every engine names a failed turn's end with (#16404): an
189
+ * end the abort, the timeout or the harness named is theirs; only an
190
+ * unexplained death is the link's, the memory limit's or the harness's.
278
191
  */
192
+ declare function turnEndReason(end: {
193
+ aborted?: boolean;
194
+ timedOut?: boolean;
195
+ harnessFailed?: boolean;
196
+ linkLost?: boolean;
197
+ memoryKilled?: boolean;
198
+ signal?: string | null;
199
+ }): TurnEndReason;
279
200
  interface ExecutionState {
280
- /** Session ID (from provider or our persistence layer) */
281
201
  sessionId?: string;
282
- /** Message ID for part correlation */
283
202
  messageId?: string;
284
- /**
285
- * Absolute root the CLI process ran with as its cwd. Used by
286
- * `trackFilePart` to resolve a relative path it observes into the same
287
- * absolute path a sibling observation reports absolutely, so the two unify
288
- * on one dedupe key/url instead of minting divergent parts.
289
- */
290
203
  workspaceRoot?: string;
291
- /** Text part ID (reused for streaming updates) */
292
204
  textPartId?: string;
293
- /** Active tool calls */
294
205
  toolCalls: Map<string, ToolCallState>;
295
- /** Accumulated text content */
296
206
  textBuffer: string;
297
- /** Accumulated reasoning/thinking blocks */
298
207
  reasoningBuffer: string[];
299
- /**
300
- * Reasoning parts emitted so far — one entry per distinct reasoning block,
301
- * carrying the stable part id downstream consumers key on. Maintained by
302
- * `trackReasoningBlock`.
303
- */
304
208
  reasoningParts?: Array<{
305
209
  id: string;
306
210
  text: string;
307
211
  }>;
308
- /**
309
- * File parts announced this reply, deduped by normalized path/data-URI key.
310
- * Maintained by `trackFilePart`.
311
- */
312
212
  fileParts?: Array<{
313
213
  id: string;
314
214
  key: string;
@@ -316,17 +216,17 @@ interface ExecutionState {
316
216
  mediaType?: string;
317
217
  url: string;
318
218
  }>;
319
- /** Structured native failure retained through process exit. */
320
219
  failure?: {
321
220
  message: string;
322
221
  code?: string;
323
222
  statusCode?: number;
223
+ resetAt?: string;
324
224
  };
325
- /** Latest provider warning emitted before process exit. */
326
225
  lastDiagnostic?: string;
327
- /** Latest terminal status emitted by the provider stream. */
328
226
  terminalStatus?: "completed" | "failed";
329
- /** Observed usage; absent channels were not reported by the provider. */
227
+ endReason?: TurnEndReason;
228
+ /** The sandbox's OOM-kill count when the turn started; a later count is this turn's kill. */
229
+ oomKillsAtStart?: number;
330
230
  tokenUsage?: Partial<TokenUsage>;
331
231
  }
332
232
  //#endregion
@@ -441,11 +341,6 @@ interface AcpTurn<TConfig extends AcpBridgeConfig> {
441
341
  }
442
342
  /** Text carried by ACP content blocks, including tool-call content. */
443
343
  declare function acpContentText(content: AcpContentBlock | AcpContentBlock[] | undefined): string;
444
- /** Map an ACP stop reason onto a turn status. */
445
- declare function mapAcpStopReason(reason: string | undefined): {
446
- status: "completed" | "failed";
447
- detail?: string;
448
- };
449
344
  //#endregion
450
345
  //#region src/turn-process.d.ts
451
346
  /** A turn transport may finish while its provider server remains alive. */
@@ -483,11 +378,7 @@ type PreparedCliLaunch = {
483
378
  declare abstract class CliAdapterLifecycle<TConfig extends CliProviderConfig = CliProviderConfig> {
484
379
  abstract readonly provider: string;
485
380
  protected abstract readonly defaultCliPath: string;
486
- /**
487
- * The message log directory when the caller names none. Unset, it is the
488
- * registry spec's `messageStorageDir` for `provider`, the one source; only
489
- * an adapter for a provider the registry does not know sets it.
490
- */
381
+ /** The message log directory when the caller names none. */
491
382
  protected readonly defaultStorageDir?: string;
492
383
  protected readonly inheritProcessEnv: boolean;
493
384
  protected config: TConfig;
@@ -506,23 +397,10 @@ declare abstract class CliAdapterLifecycle<TConfig extends CliProviderConfig = C
506
397
  protected readonly activeProcesses: Set<CliTurnProcess>;
507
398
  private readonly initialization;
508
399
  constructor(options?: CliProviderOptions<TConfig>);
509
- /**
510
- * Get the storage directory. Uses provided storageDir or falls back to defaultStorageDir.
511
- */
512
400
  protected get storageDir(): string;
513
401
  /** Bind a live interaction to the exact provider execution that originated it. */
514
402
  protected interactionExecutionBinding(input: AgentExecutionInput, sessionId: string): InteractionExecutionBinding;
515
- /**
516
- * The uid/gid every CLI process this adapter spawns runs as, or undefined
517
- * when the host process is already unprivileged.
518
- *
519
- * This is an adapter-wide invariant, not a per-callsite option, because
520
- * these CLIs seed their own state on first use — a sqlite database, a log
521
- * directory, a downloaded-binary cache under the harness HOME. An auxiliary
522
- * invocation left at root (`mcp add`, `mcp list`, `--version`) creates that
523
- * tree root-owned, and the streamed run, which does drop privileges, then
524
- * cannot open its own log and exits before emitting a single event.
525
- */
403
+ /** The uid/gid every CLI process this adapter spawns runs as, or undefined when the host process is already unprivileged. */
526
404
  protected subprocessIdentity(): {
527
405
  uid: number;
528
406
  gid: number;
@@ -532,51 +410,26 @@ declare abstract class CliAdapterLifecycle<TConfig extends CliProviderConfig = C
532
410
  uid?: number;
533
411
  gid?: number;
534
412
  };
535
- /**
536
- * Run a one-shot CLI command under this adapter's subprocess identity.
537
- *
538
- * Every auxiliary invocation an adapter makes goes through here so the
539
- * identity cannot be forgotten at a call site. Auxiliary output stays out
540
- * of the streamed turn's raw evidence.
541
- */
413
+ /** Run a one-shot CLI command under this adapter's subprocess identity. */
542
414
  protected runCli(config: Omit<CliSpawnConfig, "rawCapturePath">): Promise<CliExecResult<unknown>>;
543
- /**
544
- * Run a builtin-only Node script under this adapter's subprocess identity
545
- * and return its stdout. File work inside a directory the CLI user owns goes
546
- * through here, so a root sidecar never creates, reads or writes there with
547
- * its own rights: a link the agent plants reaches only what the agent could
548
- * already reach. The script reads `args` from argv after `--` and `input`
549
- * from stdin. A failure carries the script's stderr, not the script text.
550
- */
415
+ /** Run a builtin-only Node script under this adapter's subprocess identity and return its stdout. */
551
416
  protected runNodeAsSubprocess(script: string, args: readonly string[], input?: string): Promise<string>;
552
417
  getCapabilities(): BackendCapabilities;
553
418
  initialize(config: ProviderConfig & Pick<CliProviderConfig, "runtimeAttachments">): Promise<void>;
554
419
  private initializeAtGeneration;
555
- /**
556
- * Auth/config files the adapter needs on disk that do NOT arrive through
557
- * `config.model.authFiles` — e.g. a synthesized `~/.openclaw/openclaw.json`
558
- * pointing at the managed router. The sidecar materializes these through the
559
- * hardened `materializeCliAuthFiles` path AFTER `initialize()`, so an adapter
560
- * can derive them from the resolved config/env. Default: none.
561
- */
420
+ /** Auth/config files the adapter needs on disk that do NOT arrive through `config.model.authFiles` — e.g. */
562
421
  getManagedAuthFiles(): CliAuthFile[];
563
422
  /** Provider-specific initialization runs inside the tracked lifecycle. */
564
423
  protected afterInitialize(_config: ProviderConfig): Promise<void>;
565
- /**
566
- * The harness session contract this adapter honours (cli-agent-registry
567
- * NATIVE_SESSION_CONTRACTS), or null for a provider that declares none.
568
- * Registration refuses a harness spec without one; ACP overrides this per
569
- * sub-agent.
570
- */
424
+ /** The harness session contract this adapter honours (cli-agent-registry NATIVE_SESSION_CONTRACTS), or null for a provider that declares none. */
571
425
  protected sessionContract(): HarnessSessionContract | null;
426
+ protected withExecution<T>(signal: AbortSignal | undefined, run: (signal: AbortSignal) => Promise<T>): Promise<T>;
572
427
  shutdown(): Promise<void>;
573
428
  healthCheck(): Promise<boolean>;
574
429
  /** Run this CLI's own one-shot command (version, MCP) in the workspace. */
575
430
  protected runAuxiliaryCli(args: string[], timeoutMs: number): Promise<CliExecResult<unknown>>;
576
431
  updateConfig(config: Partial<TConfig>): Promise<TConfig>;
577
- /**
578
- * Build environment variables for CLI execution.
579
- */
432
+ /** Build environment variables for CLI execution. */
580
433
  protected abstract buildExecEnv(config: TConfig): Record<string, string | undefined>;
581
434
  /** Apply private native credentials to every CLI subprocess through one path. */
582
435
  protected buildNativeExecutionEnvironment(config: TConfig): Record<string, string | undefined>;
@@ -598,91 +451,45 @@ declare abstract class CliAdapterProfile<TConfig extends CliProviderConfig = Cli
598
451
  protected readonly supportsSecretProfileRevisions: boolean;
599
452
  private readonly profileSecretProvider;
600
453
  private readonly secretProfileRuntimeKeyProvider;
601
- /**
602
- * The materialized digest behind each secret revision. It stays here: the
603
- * executor receipt is all a caller sees of a revision's resolved contents.
604
- */
605
- private readonly secretProfileMaterializedDigests;
606
- /**
607
- * The value behind each `{env:NAME}` reference in a secret revision's
608
- * config, by that revision's application. Executor memory only: no launch
609
- * environment, argv or file ever carries them.
610
- */
611
- private readonly secretProfileReferenceValues;
454
+ /** Private native preparation state; never part of a returned receipt. */
455
+ private readonly secretProfileRevisions;
612
456
  constructor(options?: CliProviderOptions<TConfig>);
613
- /** Apply captured diagnostic identity to this spawn, after profile composition. */
614
457
  /** The exact child environment a turn uses; shared with prewarm paths. */
615
458
  protected buildTurnEnvironment(executionConfig: TConfig, profilePlan: WorkspacePlanApplication$1 | undefined, workspaceRoot: string, correlationHeaders: Readonly<Record<string, string>> | undefined): Record<string, string | undefined>;
616
- /**
617
- * A profile's declared executable tools, sealed in its revision, stand in
618
- * for the app's own tool dirs on this launch's PATH tail. A secret profile's
619
- * env no longer names the app's dirs (app env is scrubbed), so the sidecar's
620
- * own SANDBOX_TOOL_BIN_DIRS says which inherited PATH entries they are.
621
- */
459
+ /** A profile's declared executable tools, sealed in its revision, stand in for the app's own tool dirs on this launch's PATH tail. */
622
460
  private bindProfileToolBinDirs;
623
461
  protected bindExecutionCorrelation(environment: Record<string, string | undefined>, correlationHeaders: Readonly<Record<string, string>> | undefined): Record<string, string | undefined>;
624
- /**
625
- * Provision the inline profile's files and native execution controls with the
626
- * shared materializer used by cli-bridge. Unsupported portable controls fail
627
- * before spawn unless the profile is explicitly best-effort
628
- * (resources.failOnError: false), which materializes the supported subset
629
- * and warns about the rest.
630
- */
631
- /**
632
- * Launcher controls this adapter OWNS on the spawn it starts — see
633
- * `BINDABLE_LAUNCH_CONTROLS` in the materializer. Empty by default: a plan
634
- * whose intent needs a launcher binding then fails closed instead of being
635
- * silently dropped. An adapter that really applies the plan's launch flags
636
- * to its own spawn (sdk-provider-opencode selecting the plan's primary
637
- * agent via `--agent`) overrides this with the controls it honors.
638
- */
462
+ /** Launcher controls this adapter OWNS on the spawn it starts — see `BINDABLE_LAUNCH_CONTROLS` in the materializer. */
639
463
  protected profileMaterializationBinds(): readonly BindableLaunchControl[];
640
- /** Optional native instruction root. The adapter owns how its runtime locates this directory. */
464
+ /** Optional native instruction root. */
641
465
  protected profileAgentDirectory(_workspaceRoot: string): string | undefined;
642
466
  /** Provider transport bound into the private immutable revision and receipt. */
643
467
  protected secretProfileProviderConfig(): Record<string, unknown> | undefined;
644
- /**
645
- * The values behind a secret revision's `{env:NAME}` config references, for
646
- * an executor that serves those references itself. Never pass them to the
647
- * native process.
648
- */
468
+ /** The values behind a secret revision's `{env:NAME}` config references, for an executor that serves those references itself. */
649
469
  protected secretProfileReferences(application: WorkspacePlanApplication$1 | undefined): Readonly<Record<string, string>> | undefined;
470
+ /** The one sealed session view repointed only while its native turn owns the queue. */
471
+ protected secretProfileSessionView(sessionId: string): {
472
+ launchRoot: string;
473
+ view: string;
474
+ subprocessUid: number;
475
+ };
476
+ /** Bind the private revision into the session's stable native cwd. */
477
+ protected bindSecretProfileSessionView(revisionWorkspaceDir: string, sessionId: string): string;
650
478
  protected materializeProfileResources(inputProfile: AgentProfile | undefined, workspaceRoot: string, ownerId?: string, sessionId?: string, scope?: "turn" | "prewarm"): Promise<WorkspacePlanApplication$1 | undefined>;
651
479
  private applyProfileResources;
652
- /**
653
- * Publish the profile as an executor-sealed revision for this session's
654
- * subprocess identity, and record the receipt that binds it to the turn.
655
- */
480
+ /** Publish the profile as an executor-sealed revision for this session's subprocess identity, and record the receipt that binds it to the turn. */
656
481
  private applySecretProfileRevision;
657
- /**
658
- * Prepare the same provider-composed native plan that execute() will check.
659
- * This may publish an immutable public revision, but never starts a model turn.
660
- */
661
- preparePublicProfileRevision(input: AgentExecutionInput): Promise<{
662
- workspacePlanDigest: string;
663
- materializedDigest: string;
482
+ /** Prepare the same provider-composed native plan that execute() will check. */
483
+ preparePublicProfileRevision(input: AgentExecutionInput): Promise<Pick<_$_tangle_network_agent_profile_materialize0.ManagedWorkspaceManifest, "workspacePlanDigest" | "materializedDigest" | "conflicts"> & {
664
484
  launchDigest: string;
665
- conflicts: Array<{
666
- relPath: string;
667
- copyRelPath: string;
668
- reason: "existing" | "symlink";
669
- }>;
670
485
  }>;
671
486
  /** Prepare the private native plan and return only an opaque executor receipt. */
672
- prepareSecretProfileRevision(input: AgentExecutionInput): Promise<{
673
- workspacePlanDigest: string;
487
+ prepareSecretProfileRevision(input: AgentExecutionInput): Promise<Omit<Pick<_$_tangle_network_agent_profile_materialize0.ManagedWorkspaceManifest, "workspacePlanDigest" | "materializedDigest" | "conflicts"> & {
488
+ launchDigest: string;
489
+ }, "materializedDigest" | "launchDigest"> & {
674
490
  executorReceipt: string;
675
- conflicts: Array<{
676
- relPath: string;
677
- copyRelPath: string;
678
- reason: "existing" | "symlink";
679
- }>;
680
491
  }>;
681
- /**
682
- * What the native health check's verdict depends on besides a revision's
683
- * bytes: the executable that loads them. A provider whose check runs
684
- * through a configurable binary names it here.
685
- */
492
+ /** What the native health check's verdict depends on besides a revision's bytes: the executable that loads them. */
686
493
  protected secretProfileVerificationScope(): string;
687
494
  /** A secret receipt is issued only after the provider can load this revision. */
688
495
  protected verifyPreparedSecretProfileRevision(_input: AgentExecutionInput, _application: WorkspacePlanApplication$1): Promise<void>;
@@ -693,38 +500,22 @@ declare abstract class CliAdapterProfile<TConfig extends CliProviderConfig = Cli
693
500
  /** Compose the provider's user-message channel for this exact turn. */
694
501
  protected composePromptText(promptText: string, input: AgentExecutionInput): string;
695
502
  protected withProfilePlan(config: TConfig, profilePlan: WorkspacePlanApplication$1 | undefined): TConfig;
503
+ /** A profile's addition precedes host context while preserving its harness prompt. */
504
+ protected resolveProfilePrompts(input: CliExecutionInput, plan: WorkspacePlanApplication$1 | undefined, profile?: AgentProfile | undefined): {
505
+ systemPrompt: string | undefined;
506
+ appendSystemPrompt: string | undefined;
507
+ };
696
508
  protected resolveProfileSystemPrompt(requestPrompt: string | undefined, profilePlan: WorkspacePlanApplication$1 | undefined): string | undefined;
697
- /**
698
- * The plan's additive prompt intent for this spawn. No request-level
699
- * counterpart exists (`AgentExecutionInput` carries only the replacement),
700
- * so unlike {@link resolveProfileSystemPrompt} there is nothing to
701
- * conflict-check against.
702
- */
703
- protected resolveProfileAppendSystemPrompt(profilePlan: WorkspacePlanApplication$1 | undefined): string | undefined;
704
509
  protected resolveProfileModel(requestModel: string | undefined): string | undefined;
705
510
  protected mergeProfilePlanEnvironment(environment: Record<string, string | undefined>, profilePlan: WorkspacePlanApplication$1 | undefined, preserveClearedVariables?: boolean): Record<string, string | undefined>;
706
511
  /** Provider-owned allowlist for a generated revision control after env scrub. */
707
512
  protected profilePlanMayFillClearedEnvironmentVariable(_name: string, _value: string): boolean;
708
- protected preparePromptInput(parts: InputPart[], workspaceRoot: string, sessionId: string, options?: {
709
- /** Override of the per-request inline-image budget — pass 0 on paths
710
- * that deliver markers only and would discard the base64. */
711
- inlineImageBudgetBytes?: number;
712
- /** Override of the adapter's nativeAttachmentKinds() for this call —
713
- * pass [] on paths that cannot forward any kind natively, so every
714
- * attachment keeps its canonical text marker. */
715
- nativeAttachmentKinds?: ReadonlyArray<"image" | "file">;
716
- }): Promise<{
513
+ protected preparePromptInput(parts: InputPart[], workspaceRoot: string, sessionId: string, options?: Parameters<typeof preparePromptInputParts>[3]): Promise<{
717
514
  promptText: string;
718
515
  persistedParts: MessagePart[];
719
516
  attachments: PreparedAttachment[];
720
517
  }>;
721
- /**
722
- * Attachment kinds this adapter forwards natively via buildExecArgs (argv
723
- * flag / stdin content block) instead of the `[Image: ...]` / `[File: ...]`
724
- * text marker. The base adapter omits those kinds' markers from the prompt
725
- * text — an adapter that opts a kind in MUST deliver every attachment of
726
- * that kind itself, or the model never sees it.
727
- */
518
+ /** Attachment kinds this adapter forwards natively via buildExecArgs (argv flag / stdin content block) instead of the `[Image: ...]` / `[File: ...]` text marker. */
728
519
  protected nativeAttachmentKinds(): ReadonlyArray<"image" | "file">;
729
520
  }
730
521
  //#endregion
@@ -792,7 +583,7 @@ declare abstract class CliAdapterSessions<TConfig extends CliProviderConfig = Cl
792
583
  }): Promise<string>;
793
584
  getMessages(options: GetMessagesOptions): Promise<BackendMessage[]>;
794
585
  protected toBackendMessage(msg: PersistedMessage): BackendMessage;
795
- protected buildAssistantParts(state: ExecutionState): MessagePart[];
586
+ protected buildAssistantParts(state: ExecutionState): MessagePart$1[];
796
587
  protected extractToolInvocations(state: ExecutionState): AgentExecutionResult["toolInvocations"];
797
588
  /**
798
589
  * Names of tools this provider substitutes for a model tool call it could
@@ -881,7 +672,6 @@ declare class TurnObserver {
881
672
  private readonly options;
882
673
  providerSessionPersistence: Promise<void>;
883
674
  providerSessionPersistenceError: unknown;
884
- repeatedToolFailureTripped: boolean;
885
675
  nativeSessionObserved: boolean;
886
676
  private readonly partUpdates;
887
677
  private readonly liveness;
@@ -897,9 +687,7 @@ declare class TurnObserver {
897
687
  }
898
688
  //#endregion
899
689
  //#region src/execution-state.d.ts
900
- /**
901
- * Creates a new execution state.
902
- */
690
+ /** Creates a new execution state. */
903
691
  declare function createExecutionState(sessionId?: string, messageId?: string, workspaceRoot?: string): ExecutionState;
904
692
  //#endregion
905
693
  //#region src/profile-config.d.ts
@@ -912,34 +700,11 @@ declare function createExecutionState(sessionId?: string, messageId?: string, wo
912
700
  declare function runtimeSecretsOverlay(runtimeSecrets: Record<string, string> | undefined, fallback: AgentProfileSecretProvider): AgentProfileSecretProvider;
913
701
  //#endregion
914
702
  //#region src/base-adapter.d.ts
915
- /**
916
- * Base adapter for CLI-based AI agent providers.
917
- *
918
- * Subclasses must implement:
919
- * - provider: string identifier
920
- * - defaultCliPath: default CLI executable name
921
- * - buildExecArgs(): build CLI execution arguments
922
- * - buildExecEnv(): build environment variables
923
- * - createEventParser(): create JSONL event parser
924
- * - mapEventToStreamEvents(): map parsed events to StreamEvents
925
- *
926
- * The message log directory is the registry spec's `messageStorageDir` for
927
- * `provider` (cli-agent-registry `messageStorageDirOf`); only an adapter for
928
- * a provider the registry does not know sets `defaultStorageDir`.
929
- *
930
- * Optional overrides:
931
- * - buildMcpAddArgs(): MCP add command arguments
932
- * - buildMcpListArgs(): MCP list command arguments (if supported)
933
- * - parseMcpListOutput(): parse MCP list output
934
- */
703
+ /** Base adapter for CLI-based AI agent providers. */
935
704
  declare abstract class CliProviderAdapterBase<TConfig extends CliProviderConfig = CliProviderConfig, TEvent = unknown> extends CliAdapterMcp<TConfig> implements SdkProviderAdapter {
936
705
  protected readonly supportsManagedQuote: boolean;
937
706
  execute(input: AgentExecutionInput, services: SdkHostServices, onEvent?: (event: StreamEvent) => void): Promise<AgentExecutionResult>;
938
707
  private executeInternal;
939
- /**
940
- * Record a successful turn: the provider session id, the assistant message,
941
- * and the result, cached for a same-turnId retry.
942
- */
943
708
  protected completeTurn(params: {
944
709
  input: AgentExecutionInput;
945
710
  sessionId: string;
@@ -953,11 +718,6 @@ declare abstract class CliProviderAdapterBase<TConfig extends CliProviderConfig
953
718
  }): Promise<AgentExecutionResult>;
954
719
  /** Report and record a failed turn, then throw its error. */
955
720
  private failCliTurn;
956
- /**
957
- * Open the turn's session (sidecar/provider persistence only; native CLI
958
- * startup is measured separately). A same-turnId retry of a completed turn
959
- * gets that turn's cached result instead of running again.
960
- */
961
721
  protected openTurnSession(input: AgentExecutionInput, recorder: SdkHostServices["recorder"], onEvent: ((event: StreamEvent) => void) | undefined): Promise<{
962
722
  providerMessageIds: any;
963
723
  cached: AgentExecutionResult;
@@ -971,18 +731,18 @@ declare abstract class CliProviderAdapterBase<TConfig extends CliProviderConfig
971
731
  providerSessionId: string | undefined;
972
732
  transcriptReplay: "fork" | "restored" | undefined;
973
733
  }>;
974
- /** Provision the profile's cwd-native dimensions for this turn. */
975
- private materializeTurnProfile;
976
- /**
977
- * Prepare the prompt and record the caller's own parts. `promptText`
978
- * additionally carries the replayed transcript and this turn's ephemeral
979
- * context, which are execution-only and stay out of both stores.
980
- */
734
+ protected materializeTurnProfile(input: AgentExecutionInput, sessionId: string): Promise<{
735
+ executionProfile: AgentProfile | undefined;
736
+ profilePlan: WorkspacePlanApplication$1 | undefined;
737
+ }>;
981
738
  protected recordTurnPrompt(input: AgentExecutionInput, session: {
982
739
  sessionId: string;
983
740
  transcriptReplay: "fork" | "restored" | undefined;
984
741
  providerMessageIds: ReturnType<typeof readProviderMessageIds>;
985
- }, recorder: SdkHostServices["recorder"]): Promise<{
742
+ }, recorder: SdkHostServices["recorder"], attachmentOptions?: {
743
+ nativeAttachmentKinds?: ReadonlyArray<"image" | "file">;
744
+ inlineImageBudgetBytes?: number;
745
+ }): Promise<{
986
746
  preparedInput: {
987
747
  promptText: string;
988
748
  persistedParts: readProviderMessageIds[];
@@ -994,163 +754,74 @@ declare abstract class CliProviderAdapterBase<TConfig extends CliProviderConfig
994
754
  private planLaunch;
995
755
  /** Reserve and announce the native session id a pre-minted harness already has. */
996
756
  private bindNativeSession;
997
- /** Spawn the turn's process, feed its input, and wait for it to exit. */
998
757
  private runCliTurn;
999
- /**
1000
- * Build CLI execution arguments for the exec command.
1001
- */
1002
758
  protected abstract buildExecArgs(params: {
1003
759
  message: string;
1004
760
  config: TConfig; /** Canonical identity for providers whose native config binds HTTP headers. */
1005
761
  correlationHeaders?: Readonly<Record<string, string>>;
1006
762
  model?: string;
1007
- sessionId?: string;
1008
- /**
1009
- * Set on a new session of a harness whose contract pre-mints its id: the
1010
- * adapter MUST start the native session under this id with the contract's
1011
- * identity args (e.g. `--session-id <id>`). The base checks the argv.
1012
- */
763
+ sessionId?: string; /** Set on a new session of a harness whose contract pre-mints its id: the adapter MUST start the native session under this id with the contract's identity args (e.g. */
1013
764
  mintedSessionId?: string;
1014
765
  workspaceRoot: string;
1015
- systemPrompt?: string;
1016
- /**
1017
- * The plan's ADDITIVE prompt intent: the harness's own prompt stays in
1018
- * force and this text is added after it. NEVER the same channel as
1019
- * `systemPrompt` (a replacement) — an adapter must bind it to its
1020
- * harness's additive control, not substitute one for the other.
1021
- *
1022
- * The materializer sets it only for harnesses whose addition control is a
1023
- * launch argument (claude-code, pi and prime `--append-system-prompt`); an
1024
- * adapter for such a harness MUST bind it, or the intent the plan asserted
1025
- * supported is silently dropped. A profile that keeps the harness prompt
1026
- * (keepsHarnessSystemPrompt) also receives the host prompt here; codex
1027
- * binds it to `developer_instructions`, and opencode already carries it in
1028
- * its materialized addition file.
1029
- */
766
+ systemPrompt?: string; /** The plan's ADDITIVE prompt intent: the harness's own prompt stays in force and this text is added after it. */
1030
767
  appendSystemPrompt?: string;
1031
768
  attachments?: PreparedAttachment[]; /** Preserve the origin of launch flags when a CLI needs one selected agent. */
1032
769
  profilePlan?: WorkspacePlanApplication$1;
1033
770
  }): CliExecArgs;
1034
- /** Create the provider event parser for CLI output. */
1035
771
  protected abstract createEventParser(state: ExecutionState, onEvent?: (event: StreamEvent) => void): StreamParserConfig<TEvent>;
1036
772
  /** How one turn's argv runs: cwd, environment, identity or launcher, stdio. */
1037
773
  private turnSpawnConfig;
1038
- /**
1039
- * The launch one turn would make, without starting it: the spawn config
1040
- * (argv, cwd, environment, identity or launcher), the stdin payload, and
1041
- * the profile files written into the workspace. Session and message
1042
- * stores are untouched and no held process is reserved, so a caller that
1043
- * runs the process itself (`execCli`) owns its output and lifecycle.
1044
- */
774
+ /** The launch one turn would make, without starting it: the spawn config (argv, cwd, environment, identity or launcher). */
1045
775
  prepareLaunch(input: CliExecutionInput, options?: {
1046
776
  providerSessionId?: string;
1047
777
  }): Promise<PreparedCliLaunch>;
1048
- /** Override only when the provider has a turn transport besides a CLI child. */
1049
778
  protected spawnExecutionProcess(request: CliTurnSpawn<TConfig, TEvent>): CliTurnProcess | Promise<CliTurnProcess>;
1050
779
  }
1051
780
  //#endregion
1052
781
  //#region src/acp-session-adapter.d.ts
1053
- /**
1054
- * Shared lifecycle of a provider that drives an Agent Client Protocol agent
1055
- * over a JSON-RPC stdio bridge: one cached process and native ACP session per
1056
- * Tangle session, `initialize` then `session/new` (or `session/load` for a
1057
- * provider that resumes), serialized `session/prompt` turns, the cancel
1058
- * sequence (`session/cancel`, grace, close), `session/update` translation,
1059
- * idle reaping and eviction on process exit or turn failure.
1060
- *
1061
- * A provider supplies only its translation: how a turn resolves its config,
1062
- * how the process starts, the prompt blocks, and its own failure signals.
1063
- */
1064
782
  declare abstract class AcpProviderAdapterBase<TConfig extends AcpBridgeConfig, TTurn extends AcpTurn<TConfig> = AcpTurn<TConfig>> extends CliProviderAdapterBase<TConfig> {
1065
- /** True when the agent supports `session/load` for a recorded native session. */
1066
783
  protected abstract readonly loadsNativeSessions: boolean;
1067
784
  private readonly acpSessions;
1068
- /** Resolve the turn's effective config. Throws before any session work. */
1069
785
  protected abstract resolveTurn(input: AgentExecutionInput): TTurn;
1070
- /**
1071
- * How to start the agent process. Runs only when no live process matches.
1072
- * May be async for a provider that must hand files it wrote to the agent user.
1073
- */
1074
786
  protected abstract processSpec(turn: TTurn, context: {
1075
787
  sessionId: string;
1076
788
  workspaceRoot: string;
1077
789
  }): AcpProcessSpec | Promise<AcpProcessSpec>;
1078
- /** The error a failed spawn surfaces; `missingBinary` when the command was not found. */
1079
790
  protected abstract spawnFailureMessage(failure: {
1080
791
  message: string;
1081
792
  missingBinary: boolean;
1082
793
  }, turn: TTurn): string;
1083
- /** The `session/prompt` blocks for a turn. */
1084
794
  protected abstract promptBlocks(input: AgentExecutionInput, prepared: {
1085
795
  promptText: string;
1086
- persistedParts: MessagePart[];
796
+ persistedParts: MessagePart$1[];
1087
797
  attachments: PreparedAttachment[];
1088
798
  }, turn: TTurn): AcpContentBlock[];
1089
- /** Spawn the bridge. Tests override it to swap the child process. */
1090
799
  protected spawnBridge(request: AcpBridgeSpawn): RpcBridge;
1091
- /** Refuse an agent version beyond the provider's own floor. */
1092
800
  protected checkAgentProtocolVersion(_advertised: number, _turn: TTurn): void;
1093
- /**
1094
- * Configure a native session the process just opened or loaded, before its
1095
- * first prompt (e.g. `session/set_model`). A failure fails the acquire.
1096
- */
801
+ protected resumeSessionId(): string | undefined;
1097
802
  protected onSessionOpened(_bridge: RpcBridge, _acpSessionId: string, _turn: TTurn, _options: {
1098
803
  timeoutMs: number;
1099
804
  }): Promise<void>;
1100
- /** Install reverse-call handlers on a new bridge, before `initialize`. */
1101
805
  protected onBridgeSpawned(_bridge: RpcBridge, _sessionId: string, _turn: TTurn): void;
1102
- /** Start per-turn state; the returned function ends it on every exit. */
1103
806
  protected beginTurn(_sessionId: string, _input: AgentExecutionInput, _onEvent: ((event: StreamEvent) => void) | undefined): () => void;
1104
- /** Inspect a failed tool's output; returned events precede its part update. */
1105
807
  protected onToolFailed(_sessionId: string, _failureText: string | undefined): StreamEvent[];
1106
- /**
1107
- * A failure the provider recorded for this session during the turn,
1108
- * cleared on read. It outranks the error the turn surfaced as.
1109
- */
1110
808
  protected takeTurnFailure(_sessionId: string): Error | undefined;
1111
- /** Release provider state tied to a session's process. */
1112
809
  protected onSessionEvicted(_sessionId: string): void;
1113
- /** Extra fields for the turn-failure log line. */
1114
810
  protected turnLogContext(_turn: TTurn): Record<string, unknown>;
1115
- /**
1116
- * One turn through the base turn pipeline: session open with transcript
1117
- * replay and cached-turn replay, then input and result recording around the
1118
- * bridge's `session/prompt`. The agent owns its profile, so the base's
1119
- * profile materialization does not run.
1120
- */
1121
811
  execute(input: AgentExecutionInput, services: SdkHostServices, onEvent?: (event: StreamEvent) => void): Promise<AgentExecutionResult>;
1122
- /** Report a failed turn, retire its process, and throw its error. */
1123
- private failAcpTurn;
812
+ protected interruptStuckTurn(): void;
813
+ protected acknowledgeLostTurn(_detail: string): Promise<boolean>;
1124
814
  private acquireAcpSession;
1125
815
  private checkProtocolVersion;
1126
- /**
1127
- * Open the native ACP session. A recorded session is loaded when the agent
1128
- * can; an agent that refuses the load starts a new native session, and the
1129
- * Tangle transcript stays the record of the earlier turns.
1130
- */
1131
816
  private openNativeSession;
1132
- /**
1133
- * One `session/prompt` turn. Abort sends `session/cancel` before closing so
1134
- * the agent can settle the turn; the bridge's own signal handling would
1135
- * close first and lose the notify.
1136
- */
1137
817
  private promptAcpSession;
1138
818
  private scheduleIdleReap;
1139
819
  private cancelIdleReap;
1140
- /** Close a session's agent process and drop it. Idempotent. */
1141
820
  protected evictAcpSession(sessionId: string, reason: string): void;
1142
- /** Evict every cached session whose process key matches. */
1143
821
  protected evictAcpSessionsWhere(matches: (processKey: string) => boolean, reason: string): void;
1144
- /** Translate one `session/update` notification into stream events. */
1145
822
  private mapAcpUpdate;
1146
823
  private mapToolStatus;
1147
824
  private formatBridgeError;
1148
- /**
1149
- * The error a failed process start surfaces. An agent that exits before its
1150
- * session opens reports why only on stderr, and an agent's JSON-RPC error
1151
- * carries its cause in `data`; a bare "process-exit" or "Internal error"
1152
- * hides both from the caller.
1153
- */
1154
825
  private sessionSetupError;
1155
826
  healthCheck(): Promise<boolean>;
1156
827
  shutdown(): Promise<void>;
@@ -1208,7 +879,7 @@ interface PlaintextResponse {
1208
879
  }
1209
880
  /**
1210
881
  * Parser for harnesses that print their reply as plain stdout lines (hermes,
1211
- * nanoclaw, forge). Lines classify into provider events; the reply is
882
+ * nanoclaw). Lines classify into provider events; the reply is
1212
883
  * emitted as one text part when stdout closes. A turn that printed errors
1213
884
  * but no reply ends `failed` with the last error instead of an empty
1214
885
  * `completed`.
@@ -1250,23 +921,6 @@ declare function buildFileUrl(input: {
1250
921
  }): string;
1251
922
  /** Deterministic, stable part id for a file announced within one message. */
1252
923
  declare function deterministicFilePartId(messageId: string, key: string): string;
1253
- /**
1254
- * Stateless derivation of the canonical file-part fields for one observed
1255
- * path: resolve-once (normalize, then anchor a relative path to
1256
- * `workspaceRoot`), and from that single resolved path derive the dedupe
1257
- * `key`, the deterministic `id`, the `filename`, the inferred `mediaType`,
1258
- * and the percent-encoded `file://` `url` — so every consumer that surfaces
1259
- * the same file agrees on all five.
1260
- *
1261
- * Returns `null` for a relative path with no `workspaceRoot` to anchor it:
1262
- * detection is opportunistic and a fabricated location is worse than a
1263
- * missing part (see `trackFilePart` for the full rationale).
1264
- *
1265
- * This is the ONE derivation chain. `trackFilePart` (exec path, with
1266
- * ExecutionState memoization) and stateless mappers that own no
1267
- * ExecutionState (codex's app-server item mapper) both call it — never
1268
- * re-implement the chain, or the two paths drift.
1269
- */
1270
924
  declare function deriveFilePart(input: {
1271
925
  path: string;
1272
926
  messageId: string;
@@ -1278,33 +932,6 @@ declare function deriveFilePart(input: {
1278
932
  mediaType?: string;
1279
933
  url: string;
1280
934
  } | null;
1281
- /**
1282
- * Tracks a file an adapter observed being created/modified (e.g. from a
1283
- * write-tool call) and returns the canonical `FilePart` fields to stream,
1284
- * deduping by resolved-absolute-path or data-URI content so repeated writes
1285
- * to the same file update one part instead of appending duplicates.
1286
- *
1287
- * The path is normalized and resolved to an absolute form ONCE, and that same
1288
- * resolved value drives both the dedupe key and the `file://` url — so two
1289
- * observations of the same file that differ only in spelling (`./chart.png`
1290
- * vs `/workspace/chart.png`, or `/workspace/sub/../chart.png` vs
1291
- * `/workspace/chart.png`) unify on one part with one stable url, satisfying
1292
- * the stream invariant that a given part id keeps a stable url.
1293
- *
1294
- * A relative path can only be resolved against `state.workspaceRoot` (set by
1295
- * the adapter from the CLI's cwd). Detection here is opportunistic — a
1296
- * tool-call observation, not a guarantee of an absolute path — so when no
1297
- * workspaceRoot is available to anchor a relative path, we drop the
1298
- * observation (`null`) rather than fabricate an anchor (e.g. resolving
1299
- * against "/"): a wrong url is worse than a missing part, and a caller that
1300
- * genuinely lost the file would get a wrong, permanent url once it's on the
1301
- * stream.
1302
- *
1303
- * Detection is opportunistic for other reasons too: a delete, or an
1304
- * observation carrying neither a path nor a data URI, also yields no part
1305
- * (`null`) rather than an error — callers are not required to have a file
1306
- * signal on every tool result.
1307
- */
1308
935
  declare function trackFilePart(state: ExecutionState, args: {
1309
936
  path?: string;
1310
937
  dataUri?: string;
@@ -1331,22 +958,6 @@ declare class InteractionMcpServer extends InteractionMcpServer$1 {
1331
958
  }
1332
959
  //#endregion
1333
960
  //#region src/interaction-support.d.ts
1334
- /**
1335
- * Per-execution lifecycle wrapper for an MCP-capable harness. Permission and
1336
- * question tools use the live {@link InteractionBroker}; plan tools commit
1337
- * through {@link TerminalPlanSupport} and end the provider turn.
1338
- *
1339
- * Mirrors the claude-code permission-server pattern, but for the GENERIC
1340
- * `request_permission` / `ask_user` / `request_plan` tools the agent calls
1341
- * itself — there is no harness-specific reply contract, so any MCP-capable CLI
1342
- * (factory-droids, …) composes this with ~10 lines: declare the capability
1343
- * kinds, start/stop around the spawn, inject the server via the CLI's MCP
1344
- * mechanism, and forward `respondToInteraction` here.
1345
- *
1346
- * Unlike claude-code's `--permission-prompt-tool`, these generic tools fire
1347
- * only when the model chooses to call them. Permission is therefore advisory,
1348
- * while plan-capable adapters separately prove the terminal turn boundary.
1349
- */
1350
961
  declare class McpInteractionSupport {
1351
962
  /** MCP server name; tool names become `mcp__<name>__<tool>`. */
1352
963
  private readonly serverName;
@@ -1432,6 +1043,34 @@ declare function recordCliTokenUsage(state: ExecutionState, ...sources: unknown[
1432
1043
  declare function accumulateCliTokenUsage(state: ExecutionState, ...sources: unknown[]): boolean;
1433
1044
  declare function parseCliUsageLine(line: string): Record<string, unknown> | undefined;
1434
1045
  //#endregion
1046
+ //#region src/secret-native-proof.d.ts
1047
+ type BinaryLaunch = Pick<CliSpawnConfig, "command" | "cwd" | "env" | "signal" | "isolatedIdentity"> & {
1048
+ inheritEnv: boolean;
1049
+ };
1050
+ /** Prove an immutable executable, under the launch's own identity and environment. */
1051
+ declare function provenStoreBinary(expected: string, config: BinaryLaunch): Promise<string>;
1052
+ /** A reported version alone cannot establish an immutable executable. */
1053
+ declare function isTrustedStoreBinary(realpath: string): boolean;
1054
+ /** The real file a launch of `command` executes under `pathEnv`. */
1055
+ declare function resolveExecutableRealpath(command: string, pathEnv: string | undefined): string | undefined;
1056
+ type SealedEntry = readonly [relative: string, mode: number, directory: boolean];
1057
+ declare const SEALED_NATIVE_HOME_LAYOUT: {
1058
+ readonly codex: readonly [readonly [".", 1016, true], readonly [".codex", 1016, true], readonly [".agents", 360, true], readonly [".codex/skills", 360, true], readonly [".codex/rules", 360, true], readonly [".codex/config.toml", 288, false], readonly [".codex/AGENTS.md", 288, false], readonly [".codex/AGENTS.override.md", 288, false], readonly [".codex/hooks.json", 288, false]];
1059
+ readonly opencode: readonly [readonly [".", 456, true], readonly [".opencode", 360, true]];
1060
+ };
1061
+ declare function assertSealedNativeHome(home: string, gid: number, layout: readonly SealedEntry[]): void;
1062
+ type RefusalDetail = {
1063
+ path?: string;
1064
+ exitCode?: number | null;
1065
+ } & Partial<Record<"expected" | "actual", string | number | boolean>>;
1066
+ /** Only selected structural facts enter a refusal; payloads and causes never do. */
1067
+ declare function refuseSecretLaunch(reason: string, {
1068
+ path,
1069
+ expected,
1070
+ actual,
1071
+ exitCode
1072
+ }?: RefusalDetail): never;
1073
+ //#endregion
1435
1074
  //#region src/reasoning-effort.d.ts
1436
1075
  /** The argv carrying `nativeReasoningControl` for a profile effort, or none. */
1437
1076
  declare function nativeEffortArgs(harness: HarnessType, effort: ReasoningEffort | undefined): string[];
@@ -1465,27 +1104,6 @@ declare function trackReasoningBlock(state: ExecutionState, blockText: string):
1465
1104
  } | null;
1466
1105
  //#endregion
1467
1106
  //#region src/repeated-tool-failure.d.ts
1468
- /**
1469
- * Guard against a turn that keeps sending a tool call the tool keeps
1470
- * rejecting.
1471
- *
1472
- * A CLI hands a rejected call back to the model and asks it to try again. It
1473
- * puts no bound on how often it does that. A model that cannot form a valid
1474
- * input therefore bills one round trip per attempt until an unrelated limit
1475
- * runs out, and the user is told about that limit rather than about the call.
1476
- * Staging measured 76 such attempts in 24.5 minutes, ending on a spent key
1477
- * budget.
1478
- *
1479
- * The bound has to sit here, not in the CLI. OpenCode drives the turn with
1480
- * `while (true)` in `session/prompt.ts`. Its per-agent `steps` bound defaults
1481
- * to `Infinity`, and reaching that bound only appends a message that asks the
1482
- * model to stop. Every tool stays enabled.
1483
- *
1484
- * The guard counts identical rejections in a row and nothing else. Any tool
1485
- * call that produces a result clears the count. A retry after a transient
1486
- * error is untouched, because it either succeeds or its error text moves. Only
1487
- * a model that cannot change its input reaches the limit.
1488
- */
1489
1107
  /** What a tripped guard reports to the caller. */
1490
1108
  interface RepeatedToolFailure {
1491
1109
  /** The tool the model meant to call. */
@@ -1509,16 +1127,30 @@ interface RepeatedToolFailureGuardOptions {
1509
1127
  */
1510
1128
  repairToolNames?: ReadonlySet<string>;
1511
1129
  }
1512
- interface RepeatedToolFailureGuard {
1130
+ declare function createRepeatedToolFailureGuard(options: RepeatedToolFailureGuardOptions): {
1513
1131
  /**
1514
1132
  * Feed one tool part. Returns the trip on the call that reaches the limit,
1515
1133
  * and `undefined` every other time. A tripped guard stays tripped and
1516
1134
  * reports once, so a caller can kill the turn without racing the events
1517
1135
  * still in flight behind it.
1518
1136
  */
1519
- observe(part: Pick<ToolPart, "id" | "tool" | "state">): RepeatedToolFailure | undefined;
1520
- }
1521
- declare function createRepeatedToolFailureGuard(options: RepeatedToolFailureGuardOptions): RepeatedToolFailureGuard;
1137
+ observe(part: Pick<ToolPart, "id" | "tool" | "state">): {
1138
+ count: number;
1139
+ tool: string;
1140
+ detail: string;
1141
+ } | undefined;
1142
+ };
1143
+ //#endregion
1144
+ //#region src/secret-profile-scope.d.ts
1145
+ type ScopeOwner = {
1146
+ readonly proxy?: SecretProfileMcpCredentialProxy;
1147
+ };
1148
+ declare function secretMcpScope(sessionId: string, uid: number | undefined, owner?: ScopeOwner): string;
1149
+ declare function forgetSessionScopes(target: {
1150
+ sessionId: string;
1151
+ } | {
1152
+ owner: ScopeOwner;
1153
+ }): Promise<void>;
1522
1154
  //#endregion
1523
1155
  //#region src/stream-parts.d.ts
1524
1156
  /**
@@ -1612,5 +1244,5 @@ declare function homeXdgEnv(home: string): {
1612
1244
  XDG_STATE_HOME: string;
1613
1245
  };
1614
1246
  //#endregion
1615
- export { ACP_MIN_PROTOCOL_VERSION, ACP_PROTOCOL_VERSION, type AcpBridgeConfig, type AcpBridgeSpawn, type AcpContentBlock, type AcpInitializeParams, type AcpInitializeResult, type AcpNewSessionResult, type AcpProcessSpec, type AcpPromptResult, AcpProviderAdapterBase, type AcpSessionUpdateParams, type AcpTurn, type AskUserBridge, type CliExecArgs, type CliExecutionInput, CliProviderAdapterBase, type CliProviderConfig, type CliProviderLogger, type CliProviderOptions, type CliTurnProcess, type CliTurnSpawn, DEFAULT_INTERACTION_MCP_SERVER_NAME, EXECUTION_TRACE_HEADER, type EphemeralContextInput, type ExecutionState, type HarnessId, InteractionBroker, InteractionHttpBridge, InteractionMcpServer, type InteractionMcpServerConfig, type InteractionToggleConfig, type InteractionToggleKind, InvalidAttachmentError, MANAGED_QUOTE_VERSION_HEADER, MAX_INLINE_IMAGE_BYTES, MAX_TOTAL_INLINE_IMAGE_BYTES, McpInteractionSupport, PERMISSION_DECISION_TIMEOUT_MS, PROMPT_SECTION_SEPARATOR, type PerTurnInteractionInput, type PermissionPromptBridge, type PlaintextResponse, type PreparedAttachment, type PreparedCliLaunch, type RepeatedToolFailure, type RepeatedToolFailureGuard, type RepeatedToolFailureGuardOptions, type RequestPermissionBridge, type RequestPlanBridge, SessionRehydrationError, TerminalPlanSupport, type TerminalPlanSupportOptions, type ToolCallState, type WorkspacePlanApplication, accumulateCliTokenUsage, acpContentText, brokerInteractionTools, buildFileUrl, createExecutionState, createRepeatedToolFailureGuard, deriveFilePart, deterministicFilePartId, enabledInteractionKinds, executionCorrelationHeaders, finalTextEvent, homeXdgEnv, inferMediaType, interactionMcpToolName, interactionToggleEnabled, isLocalMcpConfig, jsonEventParser, kimiThinkingArgs, localMcpArgv, localMcpEnv, mapAcpStopReason, nativeEffortArgs, parseCliUsageLine, partitionImageAttachments, plaintextResponseParser, preparePromptInputParts, prependPromptSection, readCliTokenUsage, readEphemeralContext, reasoningEvents, recordCliTokenUsage, rejectNotLaunched, runtimeSecretsOverlay, sessionObservedEvents, spawnAcpBridge, streamPartBase, textDeltaEvents, textSnapshotEvents, toolResultEvents, toolStartEvents, trackFilePart, trackReasoningBlock, turnInteractionEnabled, wasNeverLaunched, withEphemeralContext, withTurnInteractions };
1247
+ export { ACP_MIN_PROTOCOL_VERSION, ACP_PROTOCOL_VERSION, AcpBridgeConfig, type AcpBridgeSpawn, AcpContentBlock, AcpInitializeParams, AcpInitializeResult, AcpNewSessionResult, type AcpProcessSpec, AcpPromptResult, AcpProviderAdapterBase, AcpSessionUpdateParams, AcpTurn, type AskUserBridge, CODEX_DISABLED_FEATURE_ARGS, CliExecArgs, CliExecutionInput, CliProviderAdapterBase, CliProviderConfig, CliProviderLogger, CliProviderOptions, type CliTurnProcess, type CliTurnSpawn, DEFAULT_INTERACTION_MCP_SERVER_NAME, EXECUTION_TRACE_HEADER, EphemeralContextInput, ExecutionState, type HarnessId, InteractionBroker, InteractionHttpBridge, InteractionMcpServer, InteractionMcpServerConfig, InteractionToggleConfig, InteractionToggleKind, InvalidAttachmentError, MANAGED_QUOTE_VERSION_HEADER, MAX_INLINE_IMAGE_BYTES, MAX_TOTAL_INLINE_IMAGE_BYTES, McpInteractionSupport, NATIVE_SESSION_CONTRACTS, PERMISSION_DECISION_TIMEOUT_MS, PROMPT_SECTION_SEPARATOR, PerTurnInteractionInput, type PermissionPromptBridge, PlaintextResponse, PreparedAttachment, type PreparedCliLaunch, RepeatedToolFailure, RepeatedToolFailureGuardOptions, type RequestPermissionBridge, type RequestPlanBridge, SEALED_NATIVE_HOME_LAYOUT, SECRET_REFERENCE, SECRET_REFERENCE_PREFIX, SecretProfileMcpCredentialProxy, SecretProfileMcpServer, SessionRehydrationError, TerminalPlanSupport, TerminalPlanSupportOptions, ToolCallState, TurnEndReason, type WorkspacePlanApplication, accumulateCliTokenUsage, acpContentText, assertSealedNativeHome, assertSealedNativeSearchPath, brokerInteractionTools, buildFileUrl, codexDeveloperInstructionArgs, createExecutionState, createRepeatedToolFailureGuard, deriveFilePart, deterministicFilePartId, enabledInteractionKinds, executionCorrelationHeaders, finalTextEvent, forgetSessionScopes, homeXdgEnv, inferMediaType, interactionMcpToolName, interactionToggleEnabled, isLocalMcpConfig, isLoopbackEndpoint, isPlainRecord, isTrustedStoreBinary, joinQueue, jsonEventParser, kimiThinkingArgs, localMcpArgv, localMcpEnv, nativeEffortArgs, parseCliUsageLine, partitionImageAttachments, plaintextResponseParser, preparePromptInputParts, prependPromptSection, provenStoreBinary, readCliTokenUsage, readEphemeralContext, reasoningEvents, recordCliTokenUsage, refuseSecretLaunch, rejectNotLaunched, requireRecord, resolveExecutableRealpath, resolveReferences, runtimeSecretsOverlay, secretMcpScope, secretSessionTurnQueue, servableMcpServer, servableStdioServer, sessionObservedEvents, spawnAcpBridge, streamPartBase, textDeltaEvents, textSnapshotEvents, toolResultEvents, toolStartEvents, trackFilePart, trackReasoningBlock, turnEndReason, turnInteractionEnabled, untilSettledOrAborted, wasNeverLaunched, withEphemeralContext, withTurnInteractions };
1616
1248
  //# sourceMappingURL=index.d.mts.map