@tangle-network/sdk-provider-cli-base 0.12.0 → 0.13.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.
Files changed (3) hide show
  1. package/dist/index.d.mts +189 -556
  2. package/dist/index.mjs +952 -785
  3. package/package.json +6 -10
package/dist/index.d.mts CHANGED
@@ -1,12 +1,16 @@
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";
8
+ import * as _$_tangle_network_sdk_session_persistence0 from "@tangle-network/sdk-session-persistence";
7
9
  import { MessagePart, MessageStore, PersistedMessage, PersistedSession, SessionStore, readProviderMessageIds } from "@tangle-network/sdk-session-persistence";
8
10
  import { ProviderLogger } from "@tangle-network/cli-agent-registry";
11
+ import { NATIVE_SESSION_CONTRACTS } from "@tangle-network/cli-agent-registry/native-session-contracts";
9
12
  import { DEFAULT_INTERACTION_MCP_SERVER_NAME, InteractionMcpServer as InteractionMcpServer$1, InteractionMcpServerConfig as InteractionMcpServerConfig$1, interactionMcpToolName } from "@tangle-network/agent-core/interactions/mcp";
13
+ import { isRecord as isPlainRecord } from "@tangle-network/agent-core";
10
14
 
11
15
  //#region src/acp-process-launch.d.ts
12
16
  /** How to start the agent process for a session. */
@@ -27,76 +31,75 @@ interface AcpBridgeSpawn {
27
31
  uid?: number;
28
32
  gid?: number;
29
33
  }
30
- /** Spawn an ACP agent over NDJSON stdio. The adapter owns abort, so no signal. */
34
+ /** Spawn an ACP agent over NDJSON stdio from `env` alone, never the sidecar's own environment. The adapter owns abort, so no signal. */
31
35
  declare function spawnAcpBridge(request: AcpBridgeSpawn): RpcBridge;
32
36
  //#endregion
37
+ //#region src/secret-profile-mcp.d.ts
38
+ /** Executor-held MCP credentials shared by native private-profile adapters. */
39
+ declare const SECRET_REFERENCE_PREFIX = "TANGLE_PROFILE_SECRET_";
40
+ declare const SECRET_REFERENCE: RegExp;
41
+ declare function requireRecord(raw: unknown, message: string): Record<string, unknown>;
42
+ /** One MCP server the executor serves for a secret launch. */
43
+ type SecretProfileMcpServer = {
44
+ name: string; /** The server's own upstream URL. */
45
+ url: string; /** Every header the upstream needs, credentials included. */
46
+ headers: Readonly<Record<string, string>>;
47
+ } | {
48
+ 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. */
49
+ command: readonly string[]; /** Its environment with every secret reference resolved. */
50
+ environment: Readonly<Record<string, string>>; /** Every secret value its environment references, whatever its length. */
51
+ secrets: readonly string[];
52
+ };
53
+ /** The executor's loopback proxy for a secret launch's MCP servers. */
54
+ type SecretProfileMcpCredentialProxy = {
55
+ /** The scope's placeholder and one loopback URL per server name. */endpoint(scope: string, names: readonly string[]): Promise<{
56
+ placeholder: string;
57
+ urls: Readonly<Record<string, string>>;
58
+ }>; /** Serve `servers` before resolving; release acknowledges lease termination before the turn settles or its scope is reused. */
59
+ 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. */
60
+ forget(scope: string): Promise<void>;
61
+ };
62
+ /** A config value with its secret references resolved, or undefined. */
63
+ declare function resolveReferences(value: string, references: Readonly<Record<string, string>>): string | undefined;
64
+ /** A stdio server the executor can run: its command and its environment with every secret reference resolved. */
65
+ declare function servableStdioServer(name: string, entry: Record<string, unknown>, references: Readonly<Record<string, string>>): SecretProfileMcpServer | string;
66
+ /** A remote server the executor can serve: its fixed upstream URL and every header with its secret references resolved. */
67
+ declare function servableMcpServer(name: string, entry: Record<string, unknown>, references: Readonly<Record<string, string>>): SecretProfileMcpServer | string;
68
+ /** Join the queue at `key`; `previous` settles when earlier holders release. */
69
+ declare function joinQueue(queues: Map<string, Promise<void>>, key: string): {
70
+ previous: Promise<void>;
71
+ release: () => void;
72
+ };
73
+ declare function untilSettledOrAborted(previous: Promise<void>, signal: AbortSignal): Promise<void>;
74
+ /** Every native discovery ancestor is sealed and free of ambient configuration. */
75
+ declare function assertSealedNativeSearchPath(cwd: string, configNames: readonly string[]): void;
76
+ declare function secretSessionTurnQueue(view: string): {
77
+ previous: Promise<void>;
78
+ release: () => void;
79
+ };
80
+ /** An HTTP URL on loopback with an explicit port and no URL credentials. */
81
+ declare function isLoopbackEndpoint(value: unknown): boolean;
82
+ //#endregion
33
83
  //#region src/types.d.ts
34
84
  type InteractionToggleKind = keyof RequestedInteractions;
35
85
  type InteractionToggleConfig = boolean | RequestedInteractions;
36
86
  declare function interactionToggleEnabled(config: InteractionToggleConfig | undefined, kind: InteractionToggleKind): boolean;
37
87
  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
- */
88
+ /** Per-turn interaction toggle carried on the execution input. */
46
89
  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
- */
90
+ /** Host-composed context for THIS turn only (e.g. */
57
91
  type EphemeralContextInput = {
58
92
  ephemeralContext?: string;
59
93
  systemPrompt?: unknown;
60
94
  };
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
95
  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
- */
96
+ /** Compose the model-facing prompt for a turn: the caller's own text, then this turn's ephemeral context. */
77
97
  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
98
  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
- */
99
+ /** Overlay this turn's interactions onto a latched config, returning a NEW object (no shared mutation — safe when. */
94
100
  declare function withTurnInteractions<TConfig extends {
95
101
  interactions?: InteractionToggleConfig;
96
102
  }>(config: TConfig, input: PerTurnInteractionInput): TConfig;
97
- /**
98
- * Logger interface for CLI providers.
99
- */
100
103
  interface CliProviderLogger {
101
104
  observePhase?: ProviderLogger["observePhase"];
102
105
  debug(message: string, meta?: Record<string, unknown>): void;
@@ -104,167 +107,74 @@ interface CliProviderLogger {
104
107
  warn(message: string, meta?: Record<string, unknown>): void;
105
108
  error(message: string, meta?: Record<string, unknown>): void;
106
109
  }
107
- /**
108
- * Base configuration shared by all CLI providers.
109
- */
110
110
  interface CliProviderConfig {
111
111
  /** Trusted native auth projection resolved by the owning execution host. */
112
112
  nativeAuthEnv?: Record<string, string>;
113
113
  nativeAuthSecretEnv?: string;
114
- /** Sidecar-owned credential HOME for this adapter instance. */
115
114
  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
- */
115
+ /** Shared, persistent agent HOME. */
122
116
  agentHome?: string;
123
117
  /** Trusted, adapter-wide native process identity supplied by the executor. */
124
118
  subprocessUser?: {
125
119
  uid: number;
126
120
  gid: number;
127
121
  };
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
- */
122
+ /** The executor keeps this subprocess identity for later backends of the same session, principal and profile authority: the. */
135
123
  stableIsolatedIdentity?: boolean;
136
- /** Executor-owned base for public, per-revision native profile controls. */
137
124
  publicProfileRevisionRoot?: string;
138
125
  /** Executor-owned base for UID-restricted secret profile revisions. */
139
126
  secretProfileRevisionRoot?: string;
140
127
  /** Root-only 32-byte HMAC key; never copied into a turn result. */
141
128
  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
129
  sandboxedRuntime?: boolean;
148
- /** Portable profile applied to this provider execution. */
149
130
  profile?: AgentProfile;
150
131
  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
- */
132
+ /** Per-turn credential values resolved by secret references in this execution's runtime MCP attachments. */
157
133
  runtimeSecrets?: Record<string, string>;
158
- /** Path to the CLI executable */
159
134
  cliPath?: string;
160
- /** Default model to use */
161
135
  model?: string;
162
- /** Model provider selected by the caller. */
163
136
  provider?: string;
164
- /** API key (provider-specific env var name) */
165
137
  apiKey?: string;
166
- /** OpenAI-compatible or provider-native base URL. */
167
138
  baseUrl?: string;
168
- /** Optional auth files to materialize under the runtime home directory. */
169
139
  authFiles?: Array<{
170
140
  path: string;
171
141
  content: string;
172
142
  mode?: number;
173
143
  }>;
174
- /** Extra flags to pass to the CLI */
175
144
  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
145
  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
146
  interactions?: InteractionToggleConfig;
195
147
  }
196
- /**
197
- * Options for CLI provider adapter constructors.
198
- */
199
148
  interface CliProviderOptions<TConfig extends CliProviderConfig = CliProviderConfig> {
200
- /** Provider configuration */
201
149
  config?: TConfig;
202
- /** Logger instance */
203
150
  logger?: CliProviderLogger;
204
- /** Base storage path for session persistence */
205
151
  storagePath?: string;
206
- /** Storage subdirectory name (e.g., ".claude-code", ".codex") */
207
152
  storageDir?: string;
208
153
  /** Resolve opaque AgentProfile secret references at the private spawn boundary. */
209
154
  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
- */
155
+ /** 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
156
  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
- */
157
+ /** Serves native private-profile MCP servers without giving their keys to the CLI. */
158
+ mcpCredentialProxy?: SecretProfileMcpCredentialProxy;
159
+ /** Environment every CLI child gets in place of the inherited one for these keys: in a sandbox, the. */
160
+ agentEnvironment?: (launch: {
161
+ secretProfile: boolean;
162
+ }) => Record<string, string | undefined>;
229
163
  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
164
  ownProcessGroup?: boolean;
235
165
  }
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
- */
166
+ /** Per-turn input a CLI adapter reads beyond AgentExecutionInput: text added after the harness's own system prompt (a chat. */
241
167
  type CliExecutionInput = AgentExecutionInput & {
242
168
  appendSystemPrompt?: string;
243
169
  };
244
- /**
245
- * CLI execution arguments.
246
- */
247
170
  interface CliExecArgs {
248
- /** CLI command */
249
171
  command: string;
250
- /** Command arguments */
251
172
  args: string[];
252
- /** Whether to send message via stdin */
253
173
  useStdin: boolean;
254
- /** Stdin prompt text before provider formatting. Defaults to the prepared user prompt. */
255
174
  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
- */
175
+ /** Working directory for the spawned process. */
263
176
  cwd?: string;
264
177
  }
265
- /**
266
- * Internal state for tracking tool calls during execution.
267
- */
268
178
  interface ToolCallState {
269
179
  id: string;
270
180
  name: string;
@@ -273,42 +183,33 @@ interface ToolCallState {
273
183
  status: "pending" | "running" | "completed" | "failed";
274
184
  output?: unknown;
275
185
  }
186
+ /** How a turn ended: the closed set every harness names its end in (#16404). */
187
+ type TurnEndReason = "success" | "abort" | "timeout" | "gateway_disconnect" | "harness_exit" | "memory_limit" | "repeated_tool_failure" | "failed";
276
188
  /**
277
- * Internal state for an execution run.
189
+ * The one precedence every engine names a failed turn's end with (#16404): an
190
+ * end the abort, the timeout or the harness named is theirs; only an
191
+ * unexplained death is the link's, the memory limit's or the harness's.
278
192
  */
193
+ declare function turnEndReason(end: {
194
+ aborted?: boolean;
195
+ timedOut?: boolean;
196
+ harnessFailed?: boolean;
197
+ linkLost?: boolean;
198
+ memoryKilled?: boolean;
199
+ signal?: string | null;
200
+ }): TurnEndReason;
279
201
  interface ExecutionState {
280
- /** Session ID (from provider or our persistence layer) */
281
202
  sessionId?: string;
282
- /** Message ID for part correlation */
283
203
  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
204
  workspaceRoot?: string;
291
- /** Text part ID (reused for streaming updates) */
292
205
  textPartId?: string;
293
- /** Active tool calls */
294
206
  toolCalls: Map<string, ToolCallState>;
295
- /** Accumulated text content */
296
207
  textBuffer: string;
297
- /** Accumulated reasoning/thinking blocks */
298
208
  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
209
  reasoningParts?: Array<{
305
210
  id: string;
306
211
  text: string;
307
212
  }>;
308
- /**
309
- * File parts announced this reply, deduped by normalized path/data-URI key.
310
- * Maintained by `trackFilePart`.
311
- */
312
213
  fileParts?: Array<{
313
214
  id: string;
314
215
  key: string;
@@ -316,17 +217,17 @@ interface ExecutionState {
316
217
  mediaType?: string;
317
218
  url: string;
318
219
  }>;
319
- /** Structured native failure retained through process exit. */
320
220
  failure?: {
321
221
  message: string;
322
222
  code?: string;
323
223
  statusCode?: number;
224
+ resetAt?: string;
324
225
  };
325
- /** Latest provider warning emitted before process exit. */
326
226
  lastDiagnostic?: string;
327
- /** Latest terminal status emitted by the provider stream. */
328
227
  terminalStatus?: "completed" | "failed";
329
- /** Observed usage; absent channels were not reported by the provider. */
228
+ endReason?: TurnEndReason;
229
+ /** The sandbox's OOM-kill count when the turn started; a later count is this turn's kill. */
230
+ oomKillsAtStart?: number;
330
231
  tokenUsage?: Partial<TokenUsage>;
331
232
  }
332
233
  //#endregion
@@ -441,11 +342,6 @@ interface AcpTurn<TConfig extends AcpBridgeConfig> {
441
342
  }
442
343
  /** Text carried by ACP content blocks, including tool-call content. */
443
344
  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
345
  //#endregion
450
346
  //#region src/turn-process.d.ts
451
347
  /** A turn transport may finish while its provider server remains alive. */
@@ -483,11 +379,7 @@ type PreparedCliLaunch = {
483
379
  declare abstract class CliAdapterLifecycle<TConfig extends CliProviderConfig = CliProviderConfig> {
484
380
  abstract readonly provider: string;
485
381
  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
- */
382
+ /** The message log directory when the caller names none. */
491
383
  protected readonly defaultStorageDir?: string;
492
384
  protected readonly inheritProcessEnv: boolean;
493
385
  protected config: TConfig;
@@ -506,23 +398,10 @@ declare abstract class CliAdapterLifecycle<TConfig extends CliProviderConfig = C
506
398
  protected readonly activeProcesses: Set<CliTurnProcess>;
507
399
  private readonly initialization;
508
400
  constructor(options?: CliProviderOptions<TConfig>);
509
- /**
510
- * Get the storage directory. Uses provided storageDir or falls back to defaultStorageDir.
511
- */
512
401
  protected get storageDir(): string;
513
402
  /** Bind a live interaction to the exact provider execution that originated it. */
514
403
  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
- */
404
+ /** The uid/gid every CLI process this adapter spawns runs as, or undefined when the host process is already unprivileged. */
526
405
  protected subprocessIdentity(): {
527
406
  uid: number;
528
407
  gid: number;
@@ -532,51 +411,26 @@ declare abstract class CliAdapterLifecycle<TConfig extends CliProviderConfig = C
532
411
  uid?: number;
533
412
  gid?: number;
534
413
  };
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
- */
414
+ /** Run a one-shot CLI command under this adapter's subprocess identity. */
542
415
  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
- */
416
+ /** Run a builtin-only Node script under this adapter's subprocess identity and return its stdout. */
551
417
  protected runNodeAsSubprocess(script: string, args: readonly string[], input?: string): Promise<string>;
552
418
  getCapabilities(): BackendCapabilities;
553
419
  initialize(config: ProviderConfig & Pick<CliProviderConfig, "runtimeAttachments">): Promise<void>;
554
420
  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
- */
421
+ /** Auth/config files the adapter needs on disk that do NOT arrive through `config.model.authFiles` — e.g. */
562
422
  getManagedAuthFiles(): CliAuthFile[];
563
423
  /** Provider-specific initialization runs inside the tracked lifecycle. */
564
424
  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
- */
425
+ /** The harness session contract this adapter honours (cli-agent-registry NATIVE_SESSION_CONTRACTS), or null for a provider that declares none. */
571
426
  protected sessionContract(): HarnessSessionContract | null;
427
+ protected withExecution<T>(signal: AbortSignal | undefined, run: (signal: AbortSignal) => Promise<T>): Promise<T>;
572
428
  shutdown(): Promise<void>;
573
429
  healthCheck(): Promise<boolean>;
574
430
  /** Run this CLI's own one-shot command (version, MCP) in the workspace. */
575
431
  protected runAuxiliaryCli(args: string[], timeoutMs: number): Promise<CliExecResult<unknown>>;
576
432
  updateConfig(config: Partial<TConfig>): Promise<TConfig>;
577
- /**
578
- * Build environment variables for CLI execution.
579
- */
433
+ /** Build environment variables for CLI execution. */
580
434
  protected abstract buildExecEnv(config: TConfig): Record<string, string | undefined>;
581
435
  /** Apply private native credentials to every CLI subprocess through one path. */
582
436
  protected buildNativeExecutionEnvironment(config: TConfig): Record<string, string | undefined>;
@@ -598,91 +452,45 @@ declare abstract class CliAdapterProfile<TConfig extends CliProviderConfig = Cli
598
452
  protected readonly supportsSecretProfileRevisions: boolean;
599
453
  private readonly profileSecretProvider;
600
454
  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;
455
+ /** Private native preparation state; never part of a returned receipt. */
456
+ private readonly secretProfileRevisions;
612
457
  constructor(options?: CliProviderOptions<TConfig>);
613
- /** Apply captured diagnostic identity to this spawn, after profile composition. */
614
458
  /** The exact child environment a turn uses; shared with prewarm paths. */
615
459
  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
- */
460
+ /** 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
461
  private bindProfileToolBinDirs;
623
462
  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
- */
463
+ /** Launcher controls this adapter OWNS on the spawn it starts — see `BINDABLE_LAUNCH_CONTROLS` in the materializer. */
639
464
  protected profileMaterializationBinds(): readonly BindableLaunchControl[];
640
- /** Optional native instruction root. The adapter owns how its runtime locates this directory. */
465
+ /** Optional native instruction root. */
641
466
  protected profileAgentDirectory(_workspaceRoot: string): string | undefined;
642
467
  /** Provider transport bound into the private immutable revision and receipt. */
643
468
  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
- */
469
+ /** The values behind a secret revision's `{env:NAME}` config references, for an executor that serves those references itself. */
649
470
  protected secretProfileReferences(application: WorkspacePlanApplication$1 | undefined): Readonly<Record<string, string>> | undefined;
471
+ /** The one sealed session view repointed only while its native turn owns the queue. */
472
+ protected secretProfileSessionView(sessionId: string): {
473
+ launchRoot: string;
474
+ view: string;
475
+ subprocessUid: number;
476
+ };
477
+ /** Bind the private revision into the session's stable native cwd. */
478
+ protected bindSecretProfileSessionView(revisionWorkspaceDir: string, sessionId: string): string;
650
479
  protected materializeProfileResources(inputProfile: AgentProfile | undefined, workspaceRoot: string, ownerId?: string, sessionId?: string, scope?: "turn" | "prewarm"): Promise<WorkspacePlanApplication$1 | undefined>;
651
480
  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
- */
481
+ /** 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
482
  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;
483
+ /** Prepare the same provider-composed native plan that execute() will check. */
484
+ preparePublicProfileRevision(input: AgentExecutionInput): Promise<Pick<_$_tangle_network_agent_profile_materialize0.ManagedWorkspaceManifest, "workspacePlanDigest" | "materializedDigest" | "conflicts"> & {
664
485
  launchDigest: string;
665
- conflicts: Array<{
666
- relPath: string;
667
- copyRelPath: string;
668
- reason: "existing" | "symlink";
669
- }>;
670
486
  }>;
671
487
  /** Prepare the private native plan and return only an opaque executor receipt. */
672
- prepareSecretProfileRevision(input: AgentExecutionInput): Promise<{
673
- workspacePlanDigest: string;
488
+ prepareSecretProfileRevision(input: AgentExecutionInput): Promise<Omit<Pick<_$_tangle_network_agent_profile_materialize0.ManagedWorkspaceManifest, "workspacePlanDigest" | "materializedDigest" | "conflicts"> & {
489
+ launchDigest: string;
490
+ }, "materializedDigest" | "launchDigest"> & {
674
491
  executorReceipt: string;
675
- conflicts: Array<{
676
- relPath: string;
677
- copyRelPath: string;
678
- reason: "existing" | "symlink";
679
- }>;
680
492
  }>;
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
- */
493
+ /** What the native health check's verdict depends on besides a revision's bytes: the executable that loads them. */
686
494
  protected secretProfileVerificationScope(): string;
687
495
  /** A secret receipt is issued only after the provider can load this revision. */
688
496
  protected verifyPreparedSecretProfileRevision(_input: AgentExecutionInput, _application: WorkspacePlanApplication$1): Promise<void>;
@@ -693,38 +501,22 @@ declare abstract class CliAdapterProfile<TConfig extends CliProviderConfig = Cli
693
501
  /** Compose the provider's user-message channel for this exact turn. */
694
502
  protected composePromptText(promptText: string, input: AgentExecutionInput): string;
695
503
  protected withProfilePlan(config: TConfig, profilePlan: WorkspacePlanApplication$1 | undefined): TConfig;
504
+ /** A profile's addition precedes host context while preserving its harness prompt. */
505
+ protected resolveProfilePrompts(input: CliExecutionInput, plan: WorkspacePlanApplication$1 | undefined, profile?: AgentProfile | undefined): {
506
+ systemPrompt: string | undefined;
507
+ appendSystemPrompt: string | undefined;
508
+ };
696
509
  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
510
  protected resolveProfileModel(requestModel: string | undefined): string | undefined;
705
511
  protected mergeProfilePlanEnvironment(environment: Record<string, string | undefined>, profilePlan: WorkspacePlanApplication$1 | undefined, preserveClearedVariables?: boolean): Record<string, string | undefined>;
706
512
  /** Provider-owned allowlist for a generated revision control after env scrub. */
707
513
  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<{
514
+ protected preparePromptInput(parts: InputPart[], workspaceRoot: string, sessionId: string, options?: Parameters<typeof preparePromptInputParts>[3]): Promise<{
717
515
  promptText: string;
718
- persistedParts: MessagePart[];
516
+ persistedParts: _$_tangle_network_sdk_session_persistence0.MessagePart[];
719
517
  attachments: PreparedAttachment[];
720
518
  }>;
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
- */
519
+ /** Attachment kinds this adapter forwards natively via buildExecArgs (argv flag / stdin content block) instead of the `[Image: ...]` / `[File: ...]` text marker. */
728
520
  protected nativeAttachmentKinds(): ReadonlyArray<"image" | "file">;
729
521
  }
730
522
  //#endregion
@@ -881,7 +673,6 @@ declare class TurnObserver {
881
673
  private readonly options;
882
674
  providerSessionPersistence: Promise<void>;
883
675
  providerSessionPersistenceError: unknown;
884
- repeatedToolFailureTripped: boolean;
885
676
  nativeSessionObserved: boolean;
886
677
  private readonly partUpdates;
887
678
  private readonly liveness;
@@ -897,9 +688,7 @@ declare class TurnObserver {
897
688
  }
898
689
  //#endregion
899
690
  //#region src/execution-state.d.ts
900
- /**
901
- * Creates a new execution state.
902
- */
691
+ /** Creates a new execution state. */
903
692
  declare function createExecutionState(sessionId?: string, messageId?: string, workspaceRoot?: string): ExecutionState;
904
693
  //#endregion
905
694
  //#region src/profile-config.d.ts
@@ -912,34 +701,11 @@ declare function createExecutionState(sessionId?: string, messageId?: string, wo
912
701
  declare function runtimeSecretsOverlay(runtimeSecrets: Record<string, string> | undefined, fallback: AgentProfileSecretProvider): AgentProfileSecretProvider;
913
702
  //#endregion
914
703
  //#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
- */
704
+ /** Base adapter for CLI-based AI agent providers. */
935
705
  declare abstract class CliProviderAdapterBase<TConfig extends CliProviderConfig = CliProviderConfig, TEvent = unknown> extends CliAdapterMcp<TConfig> implements SdkProviderAdapter {
936
706
  protected readonly supportsManagedQuote: boolean;
937
707
  execute(input: AgentExecutionInput, services: SdkHostServices, onEvent?: (event: StreamEvent) => void): Promise<AgentExecutionResult>;
938
708
  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
709
  protected completeTurn(params: {
944
710
  input: AgentExecutionInput;
945
711
  sessionId: string;
@@ -953,39 +719,34 @@ declare abstract class CliProviderAdapterBase<TConfig extends CliProviderConfig
953
719
  }): Promise<AgentExecutionResult>;
954
720
  /** Report and record a failed turn, then throw its error. */
955
721
  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
722
  protected openTurnSession(input: AgentExecutionInput, recorder: SdkHostServices["recorder"], onEvent: ((event: StreamEvent) => void) | undefined): Promise<{
962
- providerMessageIds: any;
723
+ providerMessageIds: _$_tangle_network_sdk_session_persistence0.ProviderMessageIds | undefined;
963
724
  cached: AgentExecutionResult;
964
725
  sessionId: string;
965
726
  providerSessionId: string | undefined;
966
727
  transcriptReplay: "fork" | "restored" | undefined;
967
728
  } | {
968
- providerMessageIds: any;
729
+ providerMessageIds: _$_tangle_network_sdk_session_persistence0.ProviderMessageIds | undefined;
969
730
  cached: undefined;
970
731
  sessionId: string;
971
732
  providerSessionId: string | undefined;
972
733
  transcriptReplay: "fork" | "restored" | undefined;
973
734
  }>;
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
- */
735
+ protected materializeTurnProfile(input: AgentExecutionInput, sessionId: string): Promise<{
736
+ executionProfile: AgentProfile | undefined;
737
+ profilePlan: WorkspacePlanApplication$1 | undefined;
738
+ }>;
981
739
  protected recordTurnPrompt(input: AgentExecutionInput, session: {
982
740
  sessionId: string;
983
741
  transcriptReplay: "fork" | "restored" | undefined;
984
742
  providerMessageIds: ReturnType<typeof readProviderMessageIds>;
985
- }, recorder: SdkHostServices["recorder"]): Promise<{
743
+ }, recorder: SdkHostServices["recorder"], attachmentOptions?: {
744
+ nativeAttachmentKinds?: ReadonlyArray<"image" | "file">;
745
+ inlineImageBudgetBytes?: number;
746
+ }): Promise<{
986
747
  preparedInput: {
987
748
  promptText: string;
988
- persistedParts: readProviderMessageIds[];
749
+ persistedParts: _$_tangle_network_sdk_session_persistence0.MessagePart[];
989
750
  attachments: PreparedAttachment[];
990
751
  };
991
752
  promptText: string;
@@ -994,163 +755,74 @@ declare abstract class CliProviderAdapterBase<TConfig extends CliProviderConfig
994
755
  private planLaunch;
995
756
  /** Reserve and announce the native session id a pre-minted harness already has. */
996
757
  private bindNativeSession;
997
- /** Spawn the turn's process, feed its input, and wait for it to exit. */
998
758
  private runCliTurn;
999
- /**
1000
- * Build CLI execution arguments for the exec command.
1001
- */
1002
759
  protected abstract buildExecArgs(params: {
1003
760
  message: string;
1004
761
  config: TConfig; /** Canonical identity for providers whose native config binds HTTP headers. */
1005
762
  correlationHeaders?: Readonly<Record<string, string>>;
1006
763
  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
- */
764
+ 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
765
  mintedSessionId?: string;
1014
766
  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
- */
767
+ systemPrompt?: string; /** The plan's ADDITIVE prompt intent: the harness's own prompt stays in force and this text is added after it. */
1030
768
  appendSystemPrompt?: string;
1031
769
  attachments?: PreparedAttachment[]; /** Preserve the origin of launch flags when a CLI needs one selected agent. */
1032
770
  profilePlan?: WorkspacePlanApplication$1;
1033
771
  }): CliExecArgs;
1034
- /** Create the provider event parser for CLI output. */
1035
772
  protected abstract createEventParser(state: ExecutionState, onEvent?: (event: StreamEvent) => void): StreamParserConfig<TEvent>;
1036
773
  /** How one turn's argv runs: cwd, environment, identity or launcher, stdio. */
1037
774
  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
- */
775
+ /** The launch one turn would make, without starting it: the spawn config (argv, cwd, environment, identity or launcher). */
1045
776
  prepareLaunch(input: CliExecutionInput, options?: {
1046
777
  providerSessionId?: string;
1047
778
  }): Promise<PreparedCliLaunch>;
1048
- /** Override only when the provider has a turn transport besides a CLI child. */
1049
779
  protected spawnExecutionProcess(request: CliTurnSpawn<TConfig, TEvent>): CliTurnProcess | Promise<CliTurnProcess>;
1050
780
  }
1051
781
  //#endregion
1052
782
  //#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
783
  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
784
  protected abstract readonly loadsNativeSessions: boolean;
1067
785
  private readonly acpSessions;
1068
- /** Resolve the turn's effective config. Throws before any session work. */
1069
786
  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
787
  protected abstract processSpec(turn: TTurn, context: {
1075
788
  sessionId: string;
1076
789
  workspaceRoot: string;
1077
790
  }): AcpProcessSpec | Promise<AcpProcessSpec>;
1078
- /** The error a failed spawn surfaces; `missingBinary` when the command was not found. */
1079
791
  protected abstract spawnFailureMessage(failure: {
1080
792
  message: string;
1081
793
  missingBinary: boolean;
1082
794
  }, turn: TTurn): string;
1083
- /** The `session/prompt` blocks for a turn. */
1084
795
  protected abstract promptBlocks(input: AgentExecutionInput, prepared: {
1085
796
  promptText: string;
1086
797
  persistedParts: MessagePart[];
1087
798
  attachments: PreparedAttachment[];
1088
799
  }, turn: TTurn): AcpContentBlock[];
1089
- /** Spawn the bridge. Tests override it to swap the child process. */
1090
800
  protected spawnBridge(request: AcpBridgeSpawn): RpcBridge;
1091
- /** Refuse an agent version beyond the provider's own floor. */
1092
801
  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
- */
802
+ protected resumeSessionId(): string | undefined;
1097
803
  protected onSessionOpened(_bridge: RpcBridge, _acpSessionId: string, _turn: TTurn, _options: {
1098
804
  timeoutMs: number;
1099
805
  }): Promise<void>;
1100
- /** Install reverse-call handlers on a new bridge, before `initialize`. */
1101
806
  protected onBridgeSpawned(_bridge: RpcBridge, _sessionId: string, _turn: TTurn): void;
1102
- /** Start per-turn state; the returned function ends it on every exit. */
1103
807
  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
808
  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
809
  protected takeTurnFailure(_sessionId: string): Error | undefined;
1111
- /** Release provider state tied to a session's process. */
1112
810
  protected onSessionEvicted(_sessionId: string): void;
1113
- /** Extra fields for the turn-failure log line. */
1114
811
  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
812
  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;
813
+ protected interruptStuckTurn(): void;
814
+ protected acknowledgeLostTurn(_detail: string): Promise<boolean>;
1124
815
  private acquireAcpSession;
1125
816
  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
817
  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
818
  private promptAcpSession;
1138
819
  private scheduleIdleReap;
1139
820
  private cancelIdleReap;
1140
- /** Close a session's agent process and drop it. Idempotent. */
1141
821
  protected evictAcpSession(sessionId: string, reason: string): void;
1142
- /** Evict every cached session whose process key matches. */
1143
822
  protected evictAcpSessionsWhere(matches: (processKey: string) => boolean, reason: string): void;
1144
- /** Translate one `session/update` notification into stream events. */
1145
823
  private mapAcpUpdate;
1146
824
  private mapToolStatus;
1147
825
  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
826
  private sessionSetupError;
1155
827
  healthCheck(): Promise<boolean>;
1156
828
  shutdown(): Promise<void>;
@@ -1208,7 +880,7 @@ interface PlaintextResponse {
1208
880
  }
1209
881
  /**
1210
882
  * Parser for harnesses that print their reply as plain stdout lines (hermes,
1211
- * nanoclaw, forge). Lines classify into provider events; the reply is
883
+ * nanoclaw). Lines classify into provider events; the reply is
1212
884
  * emitted as one text part when stdout closes. A turn that printed errors
1213
885
  * but no reply ends `failed` with the last error instead of an empty
1214
886
  * `completed`.
@@ -1250,23 +922,6 @@ declare function buildFileUrl(input: {
1250
922
  }): string;
1251
923
  /** Deterministic, stable part id for a file announced within one message. */
1252
924
  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
925
  declare function deriveFilePart(input: {
1271
926
  path: string;
1272
927
  messageId: string;
@@ -1278,33 +933,6 @@ declare function deriveFilePart(input: {
1278
933
  mediaType?: string;
1279
934
  url: string;
1280
935
  } | 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
936
  declare function trackFilePart(state: ExecutionState, args: {
1309
937
  path?: string;
1310
938
  dataUri?: string;
@@ -1331,22 +959,6 @@ declare class InteractionMcpServer extends InteractionMcpServer$1 {
1331
959
  }
1332
960
  //#endregion
1333
961
  //#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
962
  declare class McpInteractionSupport {
1351
963
  /** MCP server name; tool names become `mcp__<name>__<tool>`. */
1352
964
  private readonly serverName;
@@ -1432,6 +1044,34 @@ declare function recordCliTokenUsage(state: ExecutionState, ...sources: unknown[
1432
1044
  declare function accumulateCliTokenUsage(state: ExecutionState, ...sources: unknown[]): boolean;
1433
1045
  declare function parseCliUsageLine(line: string): Record<string, unknown> | undefined;
1434
1046
  //#endregion
1047
+ //#region src/secret-native-proof.d.ts
1048
+ type BinaryLaunch = Pick<CliSpawnConfig, "command" | "cwd" | "env" | "signal" | "isolatedIdentity"> & {
1049
+ inheritEnv: boolean;
1050
+ };
1051
+ /** Prove an immutable executable, under the launch's own identity and environment. */
1052
+ declare function provenStoreBinary(expected: string, config: BinaryLaunch): Promise<string>;
1053
+ /** A reported version alone cannot establish an immutable executable. */
1054
+ declare function isTrustedStoreBinary(realpath: string): boolean;
1055
+ /** The real file a launch of `command` executes under `pathEnv`. */
1056
+ declare function resolveExecutableRealpath(command: string, pathEnv: string | undefined): string | undefined;
1057
+ type SealedEntry = readonly [relative: string, mode: number, directory: boolean];
1058
+ declare const SEALED_NATIVE_HOME_LAYOUT: {
1059
+ 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]];
1060
+ readonly opencode: readonly [readonly [".", 456, true], readonly [".opencode", 360, true]];
1061
+ };
1062
+ declare function assertSealedNativeHome(home: string, gid: number, layout: readonly SealedEntry[]): void;
1063
+ type RefusalDetail = {
1064
+ path?: string;
1065
+ exitCode?: number | null;
1066
+ } & Partial<Record<"expected" | "actual", string | number | boolean>>;
1067
+ /** Only selected structural facts enter a refusal; payloads and causes never do. */
1068
+ declare function refuseSecretLaunch(reason: string, {
1069
+ path,
1070
+ expected,
1071
+ actual,
1072
+ exitCode
1073
+ }?: RefusalDetail): never;
1074
+ //#endregion
1435
1075
  //#region src/reasoning-effort.d.ts
1436
1076
  /** The argv carrying `nativeReasoningControl` for a profile effort, or none. */
1437
1077
  declare function nativeEffortArgs(harness: HarnessType, effort: ReasoningEffort | undefined): string[];
@@ -1465,27 +1105,6 @@ declare function trackReasoningBlock(state: ExecutionState, blockText: string):
1465
1105
  } | null;
1466
1106
  //#endregion
1467
1107
  //#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
1108
  /** What a tripped guard reports to the caller. */
1490
1109
  interface RepeatedToolFailure {
1491
1110
  /** The tool the model meant to call. */
@@ -1509,16 +1128,30 @@ interface RepeatedToolFailureGuardOptions {
1509
1128
  */
1510
1129
  repairToolNames?: ReadonlySet<string>;
1511
1130
  }
1512
- interface RepeatedToolFailureGuard {
1131
+ declare function createRepeatedToolFailureGuard(options: RepeatedToolFailureGuardOptions): {
1513
1132
  /**
1514
1133
  * Feed one tool part. Returns the trip on the call that reaches the limit,
1515
1134
  * and `undefined` every other time. A tripped guard stays tripped and
1516
1135
  * reports once, so a caller can kill the turn without racing the events
1517
1136
  * still in flight behind it.
1518
1137
  */
1519
- observe(part: Pick<ToolPart, "id" | "tool" | "state">): RepeatedToolFailure | undefined;
1520
- }
1521
- declare function createRepeatedToolFailureGuard(options: RepeatedToolFailureGuardOptions): RepeatedToolFailureGuard;
1138
+ observe(part: Pick<ToolPart, "id" | "tool" | "state">): {
1139
+ count: number;
1140
+ tool: string;
1141
+ detail: string;
1142
+ } | undefined;
1143
+ };
1144
+ //#endregion
1145
+ //#region src/secret-profile-scope.d.ts
1146
+ type ScopeOwner = {
1147
+ readonly proxy?: SecretProfileMcpCredentialProxy;
1148
+ };
1149
+ declare function secretMcpScope(sessionId: string, uid: number | undefined, owner?: ScopeOwner): string;
1150
+ declare function forgetSessionScopes(target: {
1151
+ sessionId: string;
1152
+ } | {
1153
+ owner: ScopeOwner;
1154
+ }): Promise<void>;
1522
1155
  //#endregion
1523
1156
  //#region src/stream-parts.d.ts
1524
1157
  /**
@@ -1612,5 +1245,5 @@ declare function homeXdgEnv(home: string): {
1612
1245
  XDG_STATE_HOME: string;
1613
1246
  };
1614
1247
  //#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 };
1248
+ 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
1249
  //# sourceMappingURL=index.d.mts.map