@ai-sdk/harness 1.0.11 → 1.0.12

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/sandbox-channel.ts","../../src/utils/classify-disk-log.ts","../../src/utils/ai-gateway-auth.ts","../../src/utils/bridge-ready.ts","../../src/v1/harness-v1-bridge-protocol.ts","../../src/v1/harness-v1-diagnostic.ts","../../src/v1/harness-v1-stream-part.ts"],"sourcesContent":["import {\n safeParseJSON,\n safeValidateTypes,\n type FlexibleSchema,\n} from '@ai-sdk/provider-utils';\nimport type { WebSocket } from 'ws';\n\n/**\n * Diagnostic event surfaced by {@link SandboxChannel} during its connection\n * lifecycle. Silent unless a consumer wires `onDebug`. Reconnects are otherwise\n * invisible — the channel reconnects transparently and the in-flight turn keeps\n * streaming.\n */\nexport type SandboxChannelDebugEvent =\n | { event: 'reconnect-attempt'; attempt: number; lastSeenEventId: number }\n | { event: 'reconnected'; attempt: number; lastSeenEventId: number }\n | {\n event: 'reconnect-failed';\n attempts: number;\n lastSeenEventId: number;\n cause: unknown;\n };\n\nexport interface SandboxChannelReconnectOptions {\n /** Give up reconnecting after this many milliseconds. Default 30_000. */\n readonly maxElapsedMs?: number;\n /** First backoff delay. Default 50. */\n readonly initialDelayMs?: number;\n /** Backoff ceiling. Default 2_000. */\n readonly maxDelayMs?: number;\n}\n\nexport interface SandboxChannelOptions<TOut> {\n /**\n * Open a fresh WebSocket to the bridge and resolve once it is ready to carry\n * frames (i.e. after any adapter-specific handshake such as Claude Code's\n * `bridge-hello`). Called once by {@link SandboxChannel.open} and again on\n * every transient reconnect. Must reject if the connection cannot be\n * established.\n */\n connect: () => Promise<WebSocket>;\n\n /** Schema validating inbound (bridge → host) frames. */\n outboundSchema: FlexibleSchema<TOut>;\n\n reconnect?: SandboxChannelReconnectOptions;\n\n onDebug?: (event: SandboxChannelDebugEvent) => void;\n\n /**\n * Sink for forwarded bridge diagnostics — `sandbox-log` (captured\n * console lines) and `debug-event` (structured) frames. When set, these\n * frame types are routed here instead of the per-type listener dispatch, so\n * they never reach the consumer's stream. Typed to the diagnostic members of\n * `TOut`, so it is a no-op union for channels whose protocol has none.\n */\n onDiagnostic?: (\n event: Extract<TOut, { type: 'sandbox-log' | 'debug-event' }>,\n ) => void;\n\n /**\n * Seed the host-side cursor before the first connect. Pass the\n * `lastSeenEventId` persisted from a prior process so the bridge replays only\n * events past it when this channel opens with `{ resume: true }` — the\n * cross-process attach handshake. Defaults to `0` (fresh session).\n */\n initialLastSeenEventId?: number;\n}\n\ntype EventTypeOf<TOut extends { type: string }> = TOut['type'];\n\ntype Listener<TOut extends { type: string }, T extends EventTypeOf<TOut>> = (\n event: Extract<TOut, { type: T }>,\n) => void;\n\nconst sleep = (ms: number): Promise<void> =>\n new Promise(resolve => {\n const t = setTimeout(resolve, ms);\n (t as { unref?: () => void }).unref?.();\n });\n\n/**\n * Host-side typed wrapper around the bridge WebSocket connection.\n *\n * Buffers inbound messages until a listener for their type is registered, so\n * callers that subscribe asynchronously do not miss early frames. Inbound\n * dispatch is serialised through a promise chain so a `close` event that\n * arrives on the same microtask as the final `finish` message does not fire\n * close handlers until the message has been dispatched.\n *\n * Survives transient disconnects. The bridge keeps running and\n * accumulates events in an in-memory log keyed by a monotonic `seq`; on an\n * unexpected socket drop this channel re-invokes `connect`, re-wires the new\n * socket, and asks the bridge to replay everything past `lastSeenEventId`. The\n * in-flight turn never observes the blip — `onClose` fires only after a\n * host-initiated close or once the reconnect budget is exhausted.\n */\nexport class SandboxChannel<\n TOut extends { type: string },\n TIn extends { type: string } = { type: string },\n> {\n private readonly listeners = new Map<\n EventTypeOf<TOut>,\n Set<Listener<TOut, EventTypeOf<TOut>>>\n >();\n private readonly buffered = new Map<EventTypeOf<TOut>, TOut[]>();\n private readonly onCloseHandlers = new Set<\n (code: number, reason: string) => void\n >();\n\n private readonly connectThunk: () => Promise<WebSocket>;\n private readonly outboundSchema: FlexibleSchema<TOut>;\n private readonly onDebug:\n | ((event: SandboxChannelDebugEvent) => void)\n | undefined;\n private readonly onDiagnostic:\n | ((event: Extract<TOut, { type: 'sandbox-log' | 'debug-event' }>) => void)\n | undefined;\n private readonly maxElapsedMs: number;\n private readonly initialDelayMs: number;\n private readonly maxDelayMs: number;\n\n private ws: WebSocket | undefined;\n private connected = false;\n /** Host has begun teardown; suppresses reconnect so a bridge-side close finalises. */\n private closing = false;\n /**\n * Host has gracefully suspended (slice boundary). Inbound frames are ignored\n * from this point so the cursor stops advancing exactly at the last delivered\n * event — the bridge keeps the turn running and the not-yet-delivered tail is\n * replayed to the next process on `resume`.\n */\n private suspended = false;\n /** Channel is fully torn down; `send` throws and `onClose` has fired. */\n private terminal = false;\n private _lastSeenEventId = 0;\n private readonly pendingSends: string[] = [];\n private dispatchChain: Promise<void> = Promise.resolve();\n\n constructor(options: SandboxChannelOptions<TOut>) {\n this.connectThunk = options.connect;\n this.outboundSchema = options.outboundSchema;\n this.onDebug = options.onDebug;\n this.onDiagnostic = options.onDiagnostic;\n this.maxElapsedMs = options.reconnect?.maxElapsedMs ?? 30_000;\n this.initialDelayMs = options.reconnect?.initialDelayMs ?? 50;\n this.maxDelayMs = options.reconnect?.maxDelayMs ?? 2_000;\n this._lastSeenEventId = options.initialLastSeenEventId ?? 0;\n }\n\n /**\n * Highest bridge event `seq` this channel has observed. Persist it (e.g. via\n * the adapter's resume handle) so a future process can seed\n * {@link SandboxChannelOptions.initialLastSeenEventId} and attach.\n */\n get lastSeenEventId(): number {\n return this._lastSeenEventId;\n }\n\n /**\n * Establish the initial connection. A single attempt — startup failures\n * reject so the caller can fail `doStart` cleanly. Reconnect retries apply\n * only to drops after a successful open.\n *\n * Pass `{ resume: true }` to attach to a bridge that is already mid-session:\n * after the socket opens, the channel sends `{ type: 'resume', lastSeenEventId }`\n * so the bridge replays everything past the seeded cursor. This is the\n * cross-process attach handshake — identical to what a transient reconnect\n * does, but triggered by the initial open from a new process.\n */\n async open(opts?: { resume?: boolean }): Promise<void> {\n if (this.terminal) {\n throw new Error('SandboxChannel: cannot open a closed channel.');\n }\n const ws = await this.connectThunk();\n this.wire(ws);\n this.ws = ws;\n this.connected = true;\n if (opts?.resume) {\n this.rawSend(\n JSON.stringify({\n type: 'resume',\n lastSeenEventId: this._lastSeenEventId,\n }),\n );\n }\n }\n\n on<T extends EventTypeOf<TOut>>(\n type: T,\n listener: Listener<TOut, T>,\n ): () => void {\n let set = this.listeners.get(type);\n if (!set) {\n set = new Set();\n this.listeners.set(type, set);\n }\n set.add(listener as unknown as Listener<TOut, EventTypeOf<TOut>>);\n\n const buffered = this.buffered.get(type);\n if (buffered) {\n this.buffered.delete(type);\n for (const event of buffered) {\n listener(event as Extract<TOut, { type: T }>);\n }\n }\n\n return () => {\n set!.delete(listener as unknown as Listener<TOut, EventTypeOf<TOut>>);\n };\n }\n\n onClose(handler: (code: number, reason: string) => void): void {\n this.onCloseHandlers.add(handler);\n }\n\n send(message: TIn): void {\n if (this.terminal) {\n throw new Error(\n `SandboxChannel: cannot send ${message.type} — channel is closed.`,\n );\n }\n this.rawSend(JSON.stringify(message));\n }\n\n /**\n * Mark that the host is tearing the session down. The next socket close is\n * then treated as terminal rather than triggering a reconnect. Call before\n * sending a `shutdown` / `detach` message whose ack the bridge follows with a\n * socket close.\n */\n beginClose(): void {\n this.closing = true;\n }\n\n close(): void {\n if (this.terminal) return;\n this.closing = true;\n try {\n this.ws?.close();\n } catch {\n // best-effort\n }\n this.enqueue(() => this.finalizeClose(1000, 'closed'));\n }\n\n /**\n * Gracefully suspend at a slice boundary: stop processing inbound frames\n * (so the cursor freezes at the last delivered event), drain any frames\n * already queued for dispatch, then close the socket and finalise with the\n * close reason `'suspended'`. Resolves with the final `lastSeenEventId`.\n *\n * The bridge keeps the in-flight turn running (a host socket close never\n * aborts it) and accumulates events past the cursor for the next process to\n * `resume`. Unlike {@link close}, the consumer's active turn is wound down\n * cleanly — adapters distinguish a suspend from an unexpected drop via the\n * `'suspended'` close reason and resolve `done` successfully.\n */\n suspend(): Promise<number> {\n return new Promise<number>(resolve => {\n if (this.terminal) {\n resolve(this._lastSeenEventId);\n return;\n }\n // Stop counting/dispatching further inbound frames immediately, and\n // suppress reconnect so the socket close finalises.\n this.suspended = true;\n this.closing = true;\n this.onClose(() => resolve(this._lastSeenEventId));\n // Queue the close behind any already-dispatched frames so everything\n // delivered to the consumer is reflected in the final cursor.\n this.enqueue(() => {\n try {\n this.ws?.close();\n } catch {\n // best-effort\n }\n this.finalizeClose(1000, 'suspended');\n });\n });\n }\n\n isClosed(): boolean {\n return this.terminal;\n }\n\n // ─── internals ──────────────────────────────────────────────────────\n\n private wire(ws: WebSocket): void {\n let dropped = false;\n const onDrop = (code: number, reason: string) => {\n if (dropped) return;\n dropped = true;\n if (ws !== this.ws) return;\n this.connected = false;\n if (this.closing) {\n this.enqueue(() => this.finalizeClose(code, reason));\n } else {\n this.enqueue(() => this.reconnectLoop());\n }\n };\n\n ws.on('message', (raw: ArrayBufferLike | string) => {\n // Once suspended, ignore further frames so the cursor freezes exactly at\n // the last delivered event (the bridge replays the rest to the next slice).\n if (this.suspended) return;\n const text =\n typeof raw === 'string' ? raw : Buffer.from(raw).toString('utf8');\n this.enqueue(() => this.handleIncoming(text));\n });\n ws.on('close', (code: number, reason: Buffer) =>\n onDrop(code, reason?.toString?.('utf8') ?? ''),\n );\n ws.on('error', () => onDrop(1006, 'socket error'));\n }\n\n private async reconnectLoop(): Promise<void> {\n if (this.terminal || this.closing) return;\n const start = Date.now();\n let attempt = 0;\n let delay = this.initialDelayMs;\n while (!this.terminal && !this.closing) {\n attempt++;\n this.onDebug?.({\n event: 'reconnect-attempt',\n attempt,\n lastSeenEventId: this._lastSeenEventId,\n });\n try {\n const ws = await this.connectThunk();\n if (this.terminal || this.closing) {\n try {\n ws.close();\n } catch {\n // best-effort\n }\n return;\n }\n this.wire(ws);\n this.ws = ws;\n this.connected = true;\n // Ask the bridge to replay everything we have not seen, then flush any\n // host → bridge frames produced while we were disconnected.\n this.rawSend(\n JSON.stringify({\n type: 'resume',\n lastSeenEventId: this._lastSeenEventId,\n }),\n );\n this.flushPending();\n this.onDebug?.({\n event: 'reconnected',\n attempt,\n lastSeenEventId: this._lastSeenEventId,\n });\n return;\n } catch (cause) {\n if (Date.now() - start >= this.maxElapsedMs) {\n this.finalizeClose(1006, 'reconnect failed');\n this.onDebug?.({\n event: 'reconnect-failed',\n attempts: attempt,\n lastSeenEventId: this._lastSeenEventId,\n cause,\n });\n return;\n }\n await sleep(delay);\n delay = Math.min(delay * 1.5, this.maxDelayMs);\n }\n }\n }\n\n private rawSend(text: string): void {\n if (this.connected && this.ws) {\n this.ws.send(text);\n } else {\n this.pendingSends.push(text);\n }\n }\n\n private flushPending(): void {\n if (!this.connected || !this.ws) return;\n const queued = this.pendingSends.splice(0);\n for (const text of queued) this.ws.send(text);\n }\n\n private enqueue(work: () => void | Promise<void>): void {\n this.dispatchChain = this.dispatchChain.then(work);\n }\n\n private async handleIncoming(text: string): Promise<void> {\n const raw = await safeParseJSON({ text });\n let seq: number | undefined;\n if (\n raw.success &&\n raw.value != null &&\n typeof raw.value === 'object' &&\n typeof (raw.value as { seq?: unknown }).seq === 'number'\n ) {\n seq = (raw.value as { seq: number }).seq;\n }\n\n const validated = await safeValidateTypes({\n value: raw.success ? raw.value : undefined,\n schema: this.outboundSchema,\n });\n if (validated.success) {\n this.dispatch(validated.value);\n } else {\n this.dispatch({\n type: 'error',\n error: validated.error,\n } as unknown as TOut);\n }\n\n if (seq !== undefined && seq > this._lastSeenEventId) {\n this._lastSeenEventId = seq;\n }\n }\n\n private dispatch(message: TOut): void {\n // Diagnostics are routed to their own sink and never enter the\n // per-type listener/buffer path, so they stay off the consumer stream.\n if (message.type === 'sandbox-log' || message.type === 'debug-event') {\n this.onDiagnostic?.(\n message as Extract<TOut, { type: 'sandbox-log' | 'debug-event' }>,\n );\n return;\n }\n const type = message.type as EventTypeOf<TOut>;\n const set = this.listeners.get(type);\n if (!set || set.size === 0) {\n let bucket = this.buffered.get(type);\n if (!bucket) {\n bucket = [];\n this.buffered.set(type, bucket);\n }\n bucket.push(message);\n return;\n }\n for (const listener of set) {\n listener(message as Extract<TOut, { type: EventTypeOf<TOut> }>);\n }\n }\n\n private finalizeClose(code: number, reason: string): void {\n if (this.terminal) return;\n this.terminal = true;\n this.connected = false;\n for (const h of this.onCloseHandlers) h(code, reason);\n }\n}\n","import { safeParseJSON } from '@ai-sdk/provider-utils';\n\n/**\n * Recovery rung selected from an on-disk bridge event log when attach is not\n * possible (the bridge process is gone): `'replay'` when the log holds a\n * complete turn the host can resume from its cursor, `'rerun'` otherwise.\n */\nexport type DiskLogRecoveryMode = 'replay' | 'rerun';\n\n/**\n * Decide whether a respawned bridge can `replay` a turn from its persisted\n * `event-log.ndjson`, or must `rerun` it from scratch.\n *\n * A turn is replayable only when its log ends in a terminal `finish` event —\n * a log that is missing, empty, or ends mid-turn means the bridge died before\n * completing the turn, so there is no coherent tail to deliver and the runtime\n * must re-run it (continuing its own thread from the sandbox snapshot).\n *\n * @param eventLog Raw contents of `event-log.ndjson` (newline-delimited JSON),\n * or `null`/`undefined`/empty when the file is absent.\n */\nexport async function classifyDiskLog(\n eventLog: string | null | undefined,\n): Promise<DiskLogRecoveryMode> {\n if (!eventLog) return 'rerun';\n const lines = eventLog\n .split('\\n')\n .map(line => line.trim())\n .filter(Boolean);\n const lastLine = lines.at(-1);\n if (lastLine == null) return 'rerun';\n\n const parsed = await safeParseJSON({ text: lastLine });\n if (\n parsed.success &&\n parsed.value != null &&\n typeof parsed.value === 'object' &&\n (parsed.value as { type?: unknown }).type === 'finish'\n ) {\n return 'replay';\n }\n return 'rerun';\n}\n","const DEFAULT_AI_GATEWAY_BASE_URL = 'https://ai-gateway.vercel.sh';\n\nexport function getAiGatewayAuthFromEnv({\n env,\n}: {\n env: Record<string, string | undefined>;\n}): {\n apiKey: string | undefined;\n baseUrl: string;\n} {\n return {\n apiKey: env.AI_GATEWAY_API_KEY || env.VERCEL_OIDC_TOKEN || undefined,\n baseUrl: env.AI_GATEWAY_BASE_URL ?? DEFAULT_AI_GATEWAY_BASE_URL,\n };\n}\n","import {\n safeParseJSON,\n type Experimental_SandboxProcess,\n type Experimental_SandboxSession,\n} from '@ai-sdk/provider-utils';\nimport { z } from 'zod/v4';\nimport { harnessV1BridgeReadySchema } from '../v1/harness-v1-bridge-protocol';\n\nconst bridgeMetaSchema = z.object({\n type: z.string().optional(),\n port: z.number().optional(),\n state: z.string().optional(),\n pid: z.number().optional(),\n});\n\nexport type BridgeReadySource = 'stdout' | 'metadata';\n\nexport type BridgeReadyErrorContext = {\n proc: Experimental_SandboxProcess;\n stdoutTail: string[];\n};\n\nexport type WaitForBridgeReadyOptions = {\n proc: Experimental_SandboxProcess;\n sandbox: Experimental_SandboxSession;\n bridgeStateDir: string;\n bridgeType: string;\n timeoutMs: number;\n abortSignal?: AbortSignal;\n pollIntervalMs?: number;\n createTimeoutError?: (\n context: BridgeReadyErrorContext,\n ) => Error | Promise<Error>;\n createExitError?: (\n context: BridgeReadyErrorContext,\n ) => Error | Promise<Error>;\n};\n\nexport type WaitForBridgeReadyResult = {\n port: number;\n source: BridgeReadySource;\n stdoutTail: string[];\n};\n\nexport async function markBridgeStarting({\n sandbox,\n bridgeStateDir,\n bridgeType,\n abortSignal,\n}: {\n sandbox: Experimental_SandboxSession;\n bridgeStateDir: string;\n bridgeType: string;\n abortSignal?: AbortSignal;\n}): Promise<void> {\n try {\n await sandbox.writeTextFile({\n path: bridgeMetaPath(bridgeStateDir),\n content: JSON.stringify({ type: bridgeType, state: 'starting' }),\n abortSignal,\n });\n } catch {\n /*\n * The bridge's own metadata writes are best-effort. This host-side marker\n * only prevents stale readiness fallback when possible; stdout remains the\n * primary readiness signal.\n */\n }\n}\n\nexport async function waitForBridgeReady({\n proc,\n sandbox,\n bridgeStateDir,\n bridgeType,\n timeoutMs,\n abortSignal,\n pollIntervalMs = 100,\n createTimeoutError,\n createExitError,\n}: WaitForBridgeReadyOptions): Promise<WaitForBridgeReadyResult> {\n const reader = proc.stdout.pipeThrough(new TextDecoderStream()).getReader();\n const decoder = lineDecoder();\n const stdoutTail: string[] = [];\n const deadline = Date.now() + timeoutMs;\n let pendingStdoutRead: Promise<ReadableStreamReadResult<string>> | undefined;\n let pendingMetaRead: Promise<number | undefined> | undefined;\n let nextMetaReadAt = 0;\n let cancelReader = false;\n\n try {\n while (true) {\n if (abortSignal?.aborted) {\n cancelReader = true;\n await proc.kill();\n throw abortSignal.reason ?? new DOMException('Aborted', 'AbortError');\n }\n\n const remaining = deadline - Date.now();\n if (remaining <= 0) {\n cancelReader = true;\n await proc.kill();\n throw await makeBridgeReadyError({\n createError: createTimeoutError,\n fallbackMessage: 'bridge did not become ready in time.',\n proc,\n stdoutTail,\n });\n }\n\n pendingStdoutRead ??= reader.read();\n const metaReadDelayMs = Math.max(0, nextMetaReadAt - Date.now());\n if (pendingMetaRead === undefined && metaReadDelayMs === 0) {\n pendingMetaRead = readBridgeMetaReady({\n sandbox,\n bridgeStateDir,\n bridgeType,\n abortSignal,\n });\n }\n\n const result = await Promise.race([\n pendingStdoutRead.then(read => ({ source: 'stdout' as const, read })),\n ...(pendingMetaRead === undefined\n ? []\n : [\n pendingMetaRead.then(port => ({\n source: 'metadata' as const,\n port,\n })),\n ]),\n sleep(\n Math.min(\n remaining,\n pendingMetaRead === undefined ? metaReadDelayMs : pollIntervalMs,\n ),\n ).then(() => undefined),\n ]);\n\n if (result === undefined) continue;\n\n if (result.source === 'metadata') {\n pendingMetaRead = undefined;\n if (result.port !== undefined) {\n cancelReader = true;\n return {\n port: result.port,\n source: 'metadata',\n stdoutTail: [...stdoutTail],\n };\n }\n nextMetaReadAt = Date.now() + pollIntervalMs;\n continue;\n }\n\n pendingStdoutRead = undefined;\n const { value, done } = result.read;\n if (done) {\n for (const line of decoder.flush()) {\n pushTail({ lines: stdoutTail, line });\n }\n throw await makeBridgeReadyError({\n createError: createExitError,\n fallbackMessage: 'bridge exited before becoming ready.',\n proc,\n stdoutTail,\n });\n }\n if (value === undefined) continue;\n for (const line of decoder.push(value)) {\n pushTail({ lines: stdoutTail, line });\n const parsed = await safeParseJSON({\n text: line,\n schema: harnessV1BridgeReadySchema,\n });\n if (parsed.success) {\n return {\n port: parsed.value.port,\n source: 'stdout',\n stdoutTail: [...stdoutTail],\n };\n }\n }\n }\n } finally {\n if (cancelReader) {\n await Promise.race([reader.cancel().catch(() => {}), sleep(100)]);\n }\n try {\n reader.releaseLock();\n } catch {}\n }\n}\n\nasync function readBridgeMetaReady({\n sandbox,\n bridgeStateDir,\n bridgeType,\n abortSignal,\n}: {\n sandbox: Experimental_SandboxSession;\n bridgeStateDir: string;\n bridgeType: string;\n abortSignal?: AbortSignal;\n}): Promise<number | undefined> {\n const raw = await Promise.resolve(\n sandbox.readTextFile({\n path: bridgeMetaPath(bridgeStateDir),\n abortSignal,\n }),\n ).catch(() => null);\n if (raw == null) return undefined;\n\n const parsed = await safeParseJSON({ text: raw, schema: bridgeMetaSchema });\n if (!parsed.success) return undefined;\n if (parsed.value.type !== bridgeType) return undefined;\n if (parsed.value.state !== 'waiting') return undefined;\n if (parsed.value.port === undefined || parsed.value.port <= 0) {\n return undefined;\n }\n return parsed.value.port;\n}\n\nasync function makeBridgeReadyError({\n createError,\n fallbackMessage,\n proc,\n stdoutTail,\n}: {\n createError:\n | ((context: BridgeReadyErrorContext) => Error | Promise<Error>)\n | undefined;\n fallbackMessage: string;\n proc: Experimental_SandboxProcess;\n stdoutTail: string[];\n}): Promise<Error> {\n if (createError) {\n return createError({ proc, stdoutTail: [...stdoutTail] });\n }\n return new Error(fallbackMessage);\n}\n\nfunction bridgeMetaPath(bridgeStateDir: string): string {\n return `${bridgeStateDir}/bridge-meta.json`;\n}\n\nfunction pushTail({ lines, line }: { lines: string[]; line: string }): void {\n lines.push(line);\n if (lines.length > 20) lines.shift();\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\nfunction lineDecoder() {\n let buffer = '';\n return {\n push(chunk: string): string[] {\n buffer += chunk;\n const lines: string[] = [];\n let nl: number;\n while ((nl = buffer.indexOf('\\n')) !== -1) {\n const raw = buffer.slice(0, nl);\n buffer = buffer.slice(nl + 1);\n const line = raw.replace(/\\r$/, '').trim();\n if (line.length > 0) lines.push(line);\n }\n return lines;\n },\n flush(): string[] {\n const line = buffer.replace(/\\r$/, '').trim();\n buffer = '';\n return line.length > 0 ? [line] : [];\n },\n };\n}\n","import { z } from 'zod/v4';\nimport {\n harnessV1DebugConfigSchema,\n harnessV1DebugLevelSchema,\n type HarnessV1Diagnostic,\n} from './harness-v1-diagnostic';\nimport {\n harnessV1CompactionPartSchema,\n harnessV1ErrorPartSchema,\n harnessV1FileChangePartSchema,\n harnessV1FinishPartSchema,\n harnessV1FinishStepPartSchema,\n harnessV1RawPartSchema,\n harnessV1ReasoningDeltaPartSchema,\n harnessV1ReasoningEndPartSchema,\n harnessV1ReasoningStartPartSchema,\n harnessV1StreamStartPartSchema,\n harnessV1TextDeltaPartSchema,\n harnessV1TextEndPartSchema,\n harnessV1TextStartPartSchema,\n harnessV1ToolApprovalRequestPartSchema,\n harnessV1ToolCallPartSchema,\n harnessV1ToolResultPartSchema,\n} from './harness-v1-stream-part';\n\n/*\n * The bridge wire protocol shared by every bridge-backed harness adapter.\n *\n * This is the serialization of the host<->runtime contract for adapters that\n * run the agent runtime inside the sandbox and talk to the host over a\n * WebSocket. It exists ONLY because of that transport: untrusted JSON frames\n * crossing the sandbox boundary need runtime validation, the connection needs\n * a handshake, and the host drives turns with serialized commands. Every export\n * here is therefore prefixed `harnessV1Bridge…`.\n *\n * It has three tiers:\n *\n * 1. The OUTBOUND events — `HarnessV1StreamPart` re-expressed as Zod (imported\n * member schemas from `harness-v1-stream-part.ts`), because the part type is\n * compile-time only and the frames need runtime validation at the boundary.\n * 2. The transport/control frames that are NOT consumer events — `bridge-hello`\n * (handshake), `bridge-detach` (resume payload), `bridge-thread` (a resume\n * coordinate some runtimes announce). These ride the same socket.\n * 3. The INBOUND command vocabulary the host sends back: the shared commands\n * live here; the per-adapter `start` payload extends\n * `harnessV1BridgeStartBaseSchema` and assembles the final inbound union in\n * the adapter package.\n *\n * Non-bridge adapters (e.g. Pi) do not use this layer at all — they have no\n * serialization boundary and target the universal `HarnessV1StreamPart` type\n * directly. That is the deliberate split: `harness-v1-stream-part.ts` is the\n * transport-agnostic event vocabulary; this file is the bridge transport.\n */\n\n/**\n * The subset of a host-defined tool that travels on the `start` message. The\n * runtime only needs the name, description, and JSON-Schema input to surface\n * the tool; `execute` stays on the host.\n */\nexport const harnessV1BridgeToolWireSchema = z.object({\n name: z.string(),\n description: z.string().optional(),\n inputSchema: z.unknown().optional(),\n});\n\nexport type HarnessV1BridgeToolWire = z.infer<\n typeof harnessV1BridgeToolWireSchema\n>;\n\nexport const harnessV1BridgePermissionModeSchema = z.enum([\n 'allow-reads',\n 'allow-edits',\n 'allow-all',\n]);\n\n/**\n * Common fields of the inbound `start` message. Each adapter extends this with\n * its runtime-specific configuration (e.g. `thinking`/`continue` for Claude\n * Code, `reasoningEffort`/`webSearch`/`skills`/`resumeThreadId` for Codex) and\n * assembles the final inbound union from the shared command members below.\n *\n * `debug` carries the general `HarnessV1DebugConfig` — diagnostics config is not\n * a bridge concept, it just happens to ride the `start` frame for bridge-backed\n * adapters.\n */\nexport const harnessV1BridgeStartBaseSchema = z.object({\n type: z.literal('start'),\n prompt: z.string(),\n tools: z.array(harnessV1BridgeToolWireSchema).optional(),\n model: z.string().optional(),\n debug: harnessV1DebugConfigSchema.optional(),\n permissionMode: harnessV1BridgePermissionModeSchema.optional(),\n});\n\n// --- Transport / control frames (outbound, not consumer events) ---\n\n/**\n * Sent the instant the bridge accepts an authenticated WS connection. The host\n * waits for it before sending `start`/`resume`, because some sandbox runtimes\n * complete the upstream WS handshake before the connection is wired through to\n * the bridge process — anything sent in that gap is dropped. Carries the\n * bridge's lifecycle `state` and highest emitted `seq` for reconnect.\n */\nexport const harnessV1BridgeHelloSchema = z.object({\n type: z.literal('bridge-hello'),\n state: z.string().optional(),\n lastSeq: z.number().optional(),\n});\n\n/**\n * The bridge's reply to an inbound `detach`. Carries the adapter-specific\n * payload the host serializes into lifecycle state `data`.\n */\nexport const harnessV1BridgeDetachSchema = z.object({\n type: z.literal('bridge-detach'),\n data: z.unknown(),\n});\n\n/**\n * A resume coordinate the bridge proactively announces (e.g. Codex's thread id)\n * so the host can cache it for a later resume without waiting for `detach`.\n */\nexport const harnessV1BridgeThreadSchema = z.object({\n type: z.literal('bridge-thread'),\n threadId: z.string(),\n});\n\n// --- Diagnostics frames (outbound, not consumer events) ---\n\n/**\n * One captured console line from inside the sandbox. The bridge line-buffers\n * `process.stdout`/`process.stderr` and emits one of these per complete line.\n * Routed host-side to the diagnostics sink, never to the consumer stream.\n */\nexport const harnessV1BridgeSandboxLogSchema = z.object({\n type: z.literal('sandbox-log'),\n source: z.string(),\n stream: z.enum(['stdout', 'stderr']),\n line: z.string(),\n});\n\n/**\n * A structured diagnostic an adapter emits from inside the bridge via\n * `turn.bridgeLog(...)`. Gated by the session's debug level + subsystem filter.\n */\nexport const harnessV1BridgeDebugEventSchema = z.object({\n type: z.literal('debug-event'),\n level: harnessV1DebugLevelSchema,\n subsystem: z.string(),\n message: z.string(),\n attrs: z.record(z.string(), z.unknown()).optional(),\n error: z\n .object({\n name: z.string().optional(),\n message: z.string(),\n stack: z.string().optional(),\n })\n .optional(),\n});\n\n/**\n * Every frame a bridge can send to the host: the stream-part events plus the\n * transport/control frames. This is the schema the host `SandboxChannel`\n * validates inbound frames against.\n */\nexport const harnessV1BridgeOutboundMessageSchema = z.discriminatedUnion(\n 'type',\n [\n harnessV1StreamStartPartSchema,\n harnessV1TextStartPartSchema,\n harnessV1TextDeltaPartSchema,\n harnessV1TextEndPartSchema,\n harnessV1ReasoningStartPartSchema,\n harnessV1ReasoningDeltaPartSchema,\n harnessV1ReasoningEndPartSchema,\n harnessV1ToolCallPartSchema,\n harnessV1ToolApprovalRequestPartSchema,\n harnessV1ToolResultPartSchema,\n harnessV1FinishStepPartSchema,\n harnessV1FinishPartSchema,\n harnessV1FileChangePartSchema,\n harnessV1CompactionPartSchema,\n harnessV1ErrorPartSchema,\n harnessV1RawPartSchema,\n harnessV1BridgeHelloSchema,\n harnessV1BridgeDetachSchema,\n harnessV1BridgeThreadSchema,\n harnessV1BridgeSandboxLogSchema,\n harnessV1BridgeDebugEventSchema,\n ],\n);\n\nexport type HarnessV1BridgeOutboundMessage = z.infer<\n typeof harnessV1BridgeOutboundMessageSchema\n>;\n\nexport type HarnessV1BridgeSandboxLog = z.infer<\n typeof harnessV1BridgeSandboxLogSchema\n>;\n\nexport type HarnessV1BridgeDebugEvent = z.infer<\n typeof harnessV1BridgeDebugEventSchema\n>;\n\n/**\n * Normalize a bridge diagnostics wire frame into the transport-agnostic\n * `HarnessV1Diagnostic` an adapter reports to the framework. A captured console\n * line maps `stderr` → `warn` and `stdout` → `info`; a structured event passes\n * its fields through. This is the seam where the bridge's serialization is\n * lifted into the general emission shape every harness shares.\n */\nexport function harnessV1DiagnosticFromBridgeFrame(\n frame: HarnessV1BridgeSandboxLog | HarnessV1BridgeDebugEvent,\n context: { sessionId?: string; timestamp: number },\n): HarnessV1Diagnostic {\n if (frame.type === 'sandbox-log') {\n return {\n level: frame.stream === 'stderr' ? 'warn' : 'info',\n message: frame.line,\n subsystem: `sandbox.log.${frame.source}`,\n kind: 'log',\n source: frame.source,\n stream: frame.stream,\n sessionId: context.sessionId,\n timestamp: context.timestamp,\n };\n }\n return {\n level: frame.level,\n message: frame.message,\n subsystem: frame.subsystem,\n kind: 'event',\n attrs: frame.attrs,\n error: frame.error,\n sessionId: context.sessionId,\n timestamp: context.timestamp,\n };\n}\n\n// --- Shared inbound command members (host -> bridge) ---\n\nexport const harnessV1BridgeToolResultInboundSchema = z.object({\n type: z.literal('tool-result'),\n toolCallId: z.string(),\n output: z.unknown(),\n isError: z.boolean().optional(),\n});\n\nexport const harnessV1BridgeToolApprovalResponseInboundSchema = z.object({\n type: z.literal('tool-approval-response'),\n approvalId: z.string(),\n approved: z.boolean(),\n reason: z.string().optional(),\n});\n\nexport const harnessV1BridgeUserMessageInboundSchema = z.object({\n type: z.literal('user-message'),\n text: z.string(),\n});\n\nexport const harnessV1BridgeAbortInboundSchema = z.object({\n type: z.literal('abort'),\n});\n\nexport const harnessV1BridgeShutdownInboundSchema = z.object({\n type: z.literal('shutdown'),\n});\n\n/**\n * Reconnect: after re-establishing the socket the host asks the bridge to\n * replay every buffered event with `seq > lastSeenEventId`.\n */\nexport const harnessV1BridgeResumeInboundSchema = z.object({\n type: z.literal('resume'),\n lastSeenEventId: z.number(),\n});\n\n/**\n * The bridge replies with `bridge-detach` carrying any cached resume payload,\n * then exits.\n */\nexport const harnessV1BridgeDetachInboundSchema = z.object({\n type: z.literal('detach'),\n});\n\n/**\n * The inbound command members shared by every bridge adapter. Spread these\n * alongside the adapter's own `start` schema to build the final inbound union:\n * `z.discriminatedUnion('type', [adapterStartSchema, ...harnessV1BridgeInboundCommandSchemas])`.\n */\nexport const harnessV1BridgeInboundCommandSchemas = [\n harnessV1BridgeToolResultInboundSchema,\n harnessV1BridgeToolApprovalResponseInboundSchema,\n harnessV1BridgeUserMessageInboundSchema,\n harnessV1BridgeAbortInboundSchema,\n harnessV1BridgeShutdownInboundSchema,\n harnessV1BridgeResumeInboundSchema,\n harnessV1BridgeDetachInboundSchema,\n] as const;\n\n/**\n * The JSON line the bridge writes to stdout once its WebSocket server is bound,\n * announcing the port the host should connect to.\n */\nexport const harnessV1BridgeReadySchema = z.object({\n type: z.literal('bridge-ready'),\n port: z.number(),\n});\n\nexport type HarnessV1BridgeReady = z.infer<typeof harnessV1BridgeReadySchema>;\n","import { z } from 'zod/v4';\n\n/*\n * Diagnostics EMISSION contract — part of the `HarnessV1` spec.\n *\n * These are the types a harness adapter produces and receives: an adapter\n * reports a `HarnessV1Diagnostic` to the framework (a bridge adapter normalizes\n * its wire frames into one; a non-bridge adapter constructs one directly), and\n * receives a `HarnessV1DebugConfig` to gate what it emits. They are distinct\n * from the unaffixed host-facing `HarnessDiagnostic` / `HarnessDebugConfig`\n * (the external/telemetry surface) — the framework maps between the two at the\n * boundary, so the emission and consumption surfaces can evolve independently.\n */\n\n/** Severity of a diagnostic, ordered most → least severe. */\nexport const harnessV1DebugLevelSchema = z.enum([\n 'error',\n 'warn',\n 'info',\n 'debug',\n 'trace',\n]);\n\nexport type HarnessV1DebugLevel = z.infer<typeof harnessV1DebugLevelSchema>;\n\n/**\n * Per-session diagnostics configuration the framework hands an adapter (and the\n * host sends on `start.debug`). When absent or `enabled` is false the adapter\n * captures and emits nothing. `subsystems` filters structured events by dotted\n * prefix; console capture is independent of the subsystem filter.\n */\nexport const harnessV1DebugConfigSchema = z.object({\n enabled: z.boolean().optional(),\n level: harnessV1DebugLevelSchema.optional(),\n subsystems: z.array(z.string()).optional(),\n});\n\nexport type HarnessV1DebugConfig = z.infer<typeof harnessV1DebugConfigSchema>;\n\n/**\n * A diagnostic as emitted by a harness adapter. Structurally identical to the\n * host-facing `HarnessDiagnostic` today, but kept separate: this is the spec's\n * emission shape, that is the external consumption shape.\n */\nexport type HarnessV1Diagnostic = {\n /** Severity. */\n readonly level: HarnessV1DebugLevel;\n /** Human-readable line (console capture) or message (structured event). */\n readonly message: string;\n /** Dotted subsystem (`sandbox.log.<source>` for console capture). */\n readonly subsystem: string;\n /** `'log'` = captured console line; `'event'` = structured emission. */\n readonly kind: 'log' | 'event';\n /** Originating source label (console capture). */\n readonly source?: string;\n /** Which standard stream the line came from (console capture). */\n readonly stream?: 'stdout' | 'stderr';\n /** Structured attributes (structured events only). */\n readonly attrs?: Record<string, unknown>;\n /** Error payload (structured events only). */\n readonly error?: { name?: string; message: string; stack?: string };\n /** The harness session this diagnostic originated from. */\n readonly sessionId?: string;\n /** Emission time (epoch ms). */\n readonly timestamp: number;\n};\n","import type {\n JSONValue,\n LanguageModelV4FinishReason,\n LanguageModelV4ToolApprovalRequest,\n LanguageModelV4ToolCall,\n LanguageModelV4ToolResult,\n LanguageModelV4Usage,\n SharedV4ProviderMetadata,\n} from '@ai-sdk/provider';\nimport { z } from 'zod/v4';\nimport type { HarnessV1CallWarning } from './harness-v1-call-warning';\nimport type { HarnessV1Metadata } from './harness-v1-metadata';\n\n/**\n * One event emitted by a harness adapter during a prompt turn.\n *\n * Mirrors `LanguageModelV4StreamPart` on the variants it shares so a\n * `HarnessAgent` can pipe events through to AI SDK consumers with minimal\n * translation. Primitive types from the V4 spec (`LanguageModelV4ToolCall`,\n * `LanguageModelV4ToolResult`, `LanguageModelV4ToolApprovalRequest`,\n * `LanguageModelV4Usage`, `LanguageModelV4FinishReason`) are reused\n * verbatim — type-compat tests assert this stays the case.\n *\n * The metadata field is named `harnessMetadata` (not `providerMetadata`)\n * because a harness is a peer to a provider, not a kind of provider. The\n * agent rebinds it when forwarding to AI SDK consumers.\n */\nexport type HarnessV1StreamPart =\n | {\n type: 'stream-start';\n warnings?: ReadonlyArray<HarnessV1CallWarning>;\n /**\n * The model the runtime actually resolved to for this turn, when the\n * adapter learns it at stream start (e.g. Claude Code's `init` message\n * reports the resolved/default model). Surfaced into telemetry as\n * `gen_ai.request.model`. Omitted when the adapter doesn't know it here.\n */\n modelId?: string;\n }\n\n // Text blocks\n | { type: 'text-start'; id: string; harnessMetadata?: HarnessV1Metadata }\n | {\n type: 'text-delta';\n id: string;\n delta: string;\n harnessMetadata?: HarnessV1Metadata;\n }\n | { type: 'text-end'; id: string; harnessMetadata?: HarnessV1Metadata }\n\n // Reasoning blocks\n | { type: 'reasoning-start'; id: string; harnessMetadata?: HarnessV1Metadata }\n | {\n type: 'reasoning-delta';\n id: string;\n delta: string;\n harnessMetadata?: HarnessV1Metadata;\n }\n | { type: 'reasoning-end'; id: string; harnessMetadata?: HarnessV1Metadata }\n\n // Tool calls, approvals, results — reuse V4 primitives.\n //\n // `nativeName` is the only harness-only extension on `tool-call`. It lets\n // adapters surface the runtime's native name for a builtin when it differs\n // from the wire `toolName` (e.g. `toolName: 'bash'`, `nativeName: 'Bash'`).\n //\n // Whether the call was executed by the underlying runtime (Claude Code's\n // built-in `Bash`, Codex's `shell`) vs. needs host dispatch is signalled by\n // the standard `providerExecuted` field on `LanguageModelV4ToolCall` —\n // `true` for runtime-executed builtins, false/undefined for host tools.\n | (LanguageModelV4ToolCall & {\n nativeName?: string;\n })\n | LanguageModelV4ToolApprovalRequest\n | LanguageModelV4ToolResult\n\n // Step boundary inside a multi-step turn.\n | {\n type: 'finish-step';\n finishReason: LanguageModelV4FinishReason;\n usage: LanguageModelV4Usage;\n harnessMetadata?: HarnessV1Metadata;\n }\n\n // Turn end.\n | {\n type: 'finish';\n finishReason: LanguageModelV4FinishReason;\n totalUsage: LanguageModelV4Usage;\n harnessMetadata?: HarnessV1Metadata;\n }\n\n // Workspace file mutation that occurred through an opaque underlying\n // mechanism (one with no visible `tool-call` carrying the same data, e.g.\n // Codex's internal `apply_patch`). Emitted per changed path. Path-only by\n // design — when the mutation goes through a visible tool call, the\n // tool-call/tool-result pair already carries the information.\n | {\n type: 'file-change';\n event: 'create' | 'modify' | 'delete';\n path: string;\n harnessMetadata?: HarnessV1Metadata;\n }\n\n // Context compaction performed by the underlying runtime (Claude Code's\n // native compaction, Pi's summarization). Observation only — the runtime\n // owns the compaction; the harness neither implements nor schedules it.\n // Emitted once, on completion, since `summary`/`tokensAfter` only exist then.\n | {\n type: 'compaction';\n trigger: 'manual' | 'auto';\n summary: string;\n tokensBefore?: number;\n tokensAfter?: number;\n harnessMetadata?: HarnessV1Metadata;\n }\n\n // Errors. Multiple may be emitted in a single turn.\n | { type: 'error'; error: unknown }\n\n // Adapter-specific passthrough. Consumers can opt in to receive these via\n // `HarnessAgent` settings; otherwise they are dropped.\n | { type: 'raw'; rawValue: unknown };\n\n/*\n * Runtime (Zod) encoding of `HarnessV1StreamPart`.\n *\n * `HarnessV1StreamPart` is a compile-time type built on `LanguageModelV4*`\n * types that ship no runtime validator. Bridge adapters receive these parts as\n * JSON across a trust boundary (the sandbox WebSocket), so they need a runtime\n * schema. These schemas ARE that encoding — one source of truth, kept from\n * diverging from the type by the `_assignable` guard below and the mutual\n * `toEqualTypeOf` assertion in `harness-v1-stream-part.test-d.ts`.\n *\n * Members are exported individually so `harness-v1-bridge-protocol.ts` can\n * compose them into the bridge outbound union alongside the transport frames.\n */\n\nconst harnessV1JsonValueSchema: z.ZodType<JSONValue> = z.lazy(() =>\n z.union([\n z.string(),\n z.number(),\n z.boolean(),\n z.null(),\n z.array(harnessV1JsonValueSchema),\n z.record(z.string(), harnessV1JsonValueSchema),\n ]),\n);\n\n/*\n * Tool-result values. The inferred type is the spec's `NonNullable<JSONValue>`\n * (matching `LanguageModelV4ToolResult`), but the runtime validator\n * deliberately also accepts `null`: adapters emit `result: <value> ?? null` for\n * tools that produced no output, and that `null` must survive the trust\n * boundary unchanged (it reaches consumers exactly as it did before this schema\n * existed, when a cast hid it). Leniency at runtime, strictness in the type.\n */\nconst harnessV1ToolResultValueSchema =\n harnessV1JsonValueSchema as unknown as z.ZodType<NonNullable<JSONValue>>;\n\nconst harnessV1JsonObjectSchema = z.record(\n z.string(),\n harnessV1JsonValueSchema,\n) as unknown as z.ZodType<Record<string, JSONValue>>;\n\nconst harnessV1MetadataSchema = z.record(\n z.string(),\n z.record(z.string(), harnessV1JsonValueSchema),\n) as unknown as z.ZodType<HarnessV1Metadata>;\n\nconst harnessV1ProviderMetadataSchema = z.record(\n z.string(),\n z.record(z.string(), harnessV1JsonValueSchema),\n) as unknown as z.ZodType<SharedV4ProviderMetadata>;\n\nconst harnessV1CallWarningSchema = z.union([\n z.object({\n type: z.literal('unsupported-setting'),\n setting: z.string(),\n details: z.string().optional(),\n }),\n z.object({\n type: z.literal('unsupported-tool'),\n tool: z.string(),\n details: z.string().optional(),\n }),\n z.object({ type: z.literal('other'), message: z.string() }),\n]) as z.ZodType<HarnessV1CallWarning>;\n\nconst harnessV1UsageSchema = z.object({\n inputTokens: z.object({\n total: z.number().optional(),\n noCache: z.number().optional(),\n cacheRead: z.number().optional(),\n cacheWrite: z.number().optional(),\n }),\n outputTokens: z.object({\n total: z.number().optional(),\n text: z.number().optional(),\n reasoning: z.number().optional(),\n }),\n raw: harnessV1JsonObjectSchema.optional(),\n}) as unknown as z.ZodType<LanguageModelV4Usage>;\n\nconst harnessV1FinishReasonSchema = z.object({\n unified: z.enum([\n 'stop',\n 'length',\n 'content-filter',\n 'tool-calls',\n 'error',\n 'other',\n ]),\n raw: z.string().optional(),\n}) as unknown as z.ZodType<LanguageModelV4FinishReason>;\n\nexport const harnessV1StreamStartPartSchema = z.object({\n type: z.literal('stream-start'),\n warnings: z.array(harnessV1CallWarningSchema).readonly().optional(),\n modelId: z.string().optional(),\n});\n\nexport const harnessV1TextStartPartSchema = z.object({\n type: z.literal('text-start'),\n id: z.string(),\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1TextDeltaPartSchema = z.object({\n type: z.literal('text-delta'),\n id: z.string(),\n delta: z.string(),\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1TextEndPartSchema = z.object({\n type: z.literal('text-end'),\n id: z.string(),\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1ReasoningStartPartSchema = z.object({\n type: z.literal('reasoning-start'),\n id: z.string(),\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1ReasoningDeltaPartSchema = z.object({\n type: z.literal('reasoning-delta'),\n id: z.string(),\n delta: z.string(),\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1ReasoningEndPartSchema = z.object({\n type: z.literal('reasoning-end'),\n id: z.string(),\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1ToolCallPartSchema = z.object({\n type: z.literal('tool-call'),\n toolCallId: z.string(),\n toolName: z.string(),\n input: z.string(),\n providerExecuted: z.boolean().optional(),\n dynamic: z.boolean().optional(),\n providerMetadata: harnessV1ProviderMetadataSchema.optional(),\n nativeName: z.string().optional(),\n});\n\nexport const harnessV1ToolApprovalRequestPartSchema = z.object({\n type: z.literal('tool-approval-request'),\n approvalId: z.string(),\n toolCallId: z.string(),\n providerMetadata: harnessV1ProviderMetadataSchema.optional(),\n});\n\nexport const harnessV1ToolResultPartSchema = z.object({\n type: z.literal('tool-result'),\n toolCallId: z.string(),\n toolName: z.string(),\n result: harnessV1ToolResultValueSchema,\n isError: z.boolean().optional(),\n preliminary: z.boolean().optional(),\n dynamic: z.boolean().optional(),\n providerMetadata: harnessV1ProviderMetadataSchema.optional(),\n});\n\nexport const harnessV1FinishStepPartSchema = z.object({\n type: z.literal('finish-step'),\n finishReason: harnessV1FinishReasonSchema,\n usage: harnessV1UsageSchema,\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1FinishPartSchema = z.object({\n type: z.literal('finish'),\n finishReason: harnessV1FinishReasonSchema,\n totalUsage: harnessV1UsageSchema,\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1FileChangePartSchema = z.object({\n type: z.literal('file-change'),\n event: z.enum(['create', 'modify', 'delete']),\n path: z.string(),\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1CompactionPartSchema = z.object({\n type: z.literal('compaction'),\n trigger: z.enum(['manual', 'auto']),\n summary: z.string(),\n tokensBefore: z.number().optional(),\n tokensAfter: z.number().optional(),\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1ErrorPartSchema = z.object({\n type: z.literal('error'),\n error: z.unknown(),\n});\n\nexport const harnessV1RawPartSchema = z.object({\n type: z.literal('raw'),\n rawValue: z.unknown(),\n});\n\n/**\n * Assembled discriminated union over every `HarnessV1StreamPart` variant. Left\n * un-annotated so it keeps its precise inferred type — the protocol layer\n * composes the individual member schemas, and the type test asserts the\n * inferred union equals `HarnessV1StreamPart`.\n */\nexport const harnessV1StreamPartSchema = z.discriminatedUnion('type', [\n harnessV1StreamStartPartSchema,\n harnessV1TextStartPartSchema,\n harnessV1TextDeltaPartSchema,\n harnessV1TextEndPartSchema,\n harnessV1ReasoningStartPartSchema,\n harnessV1ReasoningDeltaPartSchema,\n harnessV1ReasoningEndPartSchema,\n harnessV1ToolCallPartSchema,\n harnessV1ToolApprovalRequestPartSchema,\n harnessV1ToolResultPartSchema,\n harnessV1FinishStepPartSchema,\n harnessV1FinishPartSchema,\n harnessV1FileChangePartSchema,\n harnessV1CompactionPartSchema,\n harnessV1ErrorPartSchema,\n harnessV1RawPartSchema,\n]);\n\n/*\n * Fail-fast guard at the definition site: the schema's output must be\n * assignable to `HarnessV1StreamPart` (catches a schema variant inventing a\n * shape the type does not allow). The reverse direction — the type being a\n * subset of the schema — is covered by the `toEqualTypeOf` assertion in the\n * type test.\n */\nconst _assignable: z.ZodType<HarnessV1StreamPart> = harnessV1StreamPartSchema;\nvoid _assignable;\n"],"mappings":"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","names":["safeParseJSON","safeParseJSON","z","z","z","z","z","z","z","sleep","safeParseJSON"]}
1
+ {"version":3,"sources":["../../src/utils/sandbox-channel.ts","../../src/utils/classify-disk-log.ts","../../src/utils/ai-gateway-auth.ts","../../src/utils/sandbox-home-dir.ts","../../src/utils/shell-quote.ts","../../src/utils/write-skills.ts","../../src/utils/bridge-ready.ts","../../src/v1/harness-v1-bridge-protocol.ts","../../src/v1/harness-v1-diagnostic.ts","../../src/v1/harness-v1-stream-part.ts"],"sourcesContent":["import {\n safeParseJSON,\n safeValidateTypes,\n type FlexibleSchema,\n} from '@ai-sdk/provider-utils';\nimport type { WebSocket } from 'ws';\n\n/**\n * Diagnostic event surfaced by {@link SandboxChannel} during its connection\n * lifecycle. Silent unless a consumer wires `onDebug`. Reconnects are otherwise\n * invisible — the channel reconnects transparently and the in-flight turn keeps\n * streaming.\n */\nexport type SandboxChannelDebugEvent =\n | { event: 'reconnect-attempt'; attempt: number; lastSeenEventId: number }\n | { event: 'reconnected'; attempt: number; lastSeenEventId: number }\n | {\n event: 'reconnect-failed';\n attempts: number;\n lastSeenEventId: number;\n cause: unknown;\n };\n\nexport interface SandboxChannelReconnectOptions {\n /** Give up reconnecting after this many milliseconds. Default 30_000. */\n readonly maxElapsedMs?: number;\n /** First backoff delay. Default 50. */\n readonly initialDelayMs?: number;\n /** Backoff ceiling. Default 2_000. */\n readonly maxDelayMs?: number;\n}\n\nexport interface SandboxChannelOptions<TOut> {\n /**\n * Open a fresh WebSocket to the bridge and resolve once it is ready to carry\n * frames (i.e. after any adapter-specific handshake such as Claude Code's\n * `bridge-hello`). Called once by {@link SandboxChannel.open} and again on\n * every transient reconnect. Must reject if the connection cannot be\n * established.\n */\n connect: () => Promise<WebSocket>;\n\n /** Schema validating inbound (bridge → host) frames. */\n outboundSchema: FlexibleSchema<TOut>;\n\n reconnect?: SandboxChannelReconnectOptions;\n\n onDebug?: (event: SandboxChannelDebugEvent) => void;\n\n /**\n * Sink for forwarded bridge diagnostics — `sandbox-log` (captured\n * console lines) and `debug-event` (structured) frames. When set, these\n * frame types are routed here instead of the per-type listener dispatch, so\n * they never reach the consumer's stream. Typed to the diagnostic members of\n * `TOut`, so it is a no-op union for channels whose protocol has none.\n */\n onDiagnostic?: (\n event: Extract<TOut, { type: 'sandbox-log' | 'debug-event' }>,\n ) => void;\n\n /**\n * Seed the host-side cursor before the first connect. Pass the\n * `lastSeenEventId` persisted from a prior process so the bridge replays only\n * events past it when this channel opens with `{ resume: true }` — the\n * cross-process attach handshake. Defaults to `0` (fresh session).\n */\n initialLastSeenEventId?: number;\n}\n\ntype EventTypeOf<TOut extends { type: string }> = TOut['type'];\n\ntype Listener<TOut extends { type: string }, T extends EventTypeOf<TOut>> = (\n event: Extract<TOut, { type: T }>,\n) => void;\n\nconst sleep = (ms: number): Promise<void> =>\n new Promise(resolve => {\n const t = setTimeout(resolve, ms);\n (t as { unref?: () => void }).unref?.();\n });\n\n/**\n * Host-side typed wrapper around the bridge WebSocket connection.\n *\n * Buffers inbound messages until a listener for their type is registered, so\n * callers that subscribe asynchronously do not miss early frames. Inbound\n * dispatch is serialised through a promise chain so a `close` event that\n * arrives on the same microtask as the final `finish` message does not fire\n * close handlers until the message has been dispatched.\n *\n * Survives transient disconnects. The bridge keeps running and\n * accumulates events in an in-memory log keyed by a monotonic `seq`; on an\n * unexpected socket drop this channel re-invokes `connect`, re-wires the new\n * socket, and asks the bridge to replay everything past `lastSeenEventId`. The\n * in-flight turn never observes the blip — `onClose` fires only after a\n * host-initiated close or once the reconnect budget is exhausted.\n */\nexport class SandboxChannel<\n TOut extends { type: string },\n TIn extends { type: string } = { type: string },\n> {\n private readonly listeners = new Map<\n EventTypeOf<TOut>,\n Set<Listener<TOut, EventTypeOf<TOut>>>\n >();\n private readonly buffered = new Map<EventTypeOf<TOut>, TOut[]>();\n private readonly onCloseHandlers = new Set<\n (code: number, reason: string) => void\n >();\n\n private readonly connectThunk: () => Promise<WebSocket>;\n private readonly outboundSchema: FlexibleSchema<TOut>;\n private readonly onDebug:\n | ((event: SandboxChannelDebugEvent) => void)\n | undefined;\n private readonly onDiagnostic:\n | ((event: Extract<TOut, { type: 'sandbox-log' | 'debug-event' }>) => void)\n | undefined;\n private readonly maxElapsedMs: number;\n private readonly initialDelayMs: number;\n private readonly maxDelayMs: number;\n\n private ws: WebSocket | undefined;\n private connected = false;\n /** Host has begun teardown; suppresses reconnect so a bridge-side close finalises. */\n private closing = false;\n /**\n * Host has gracefully suspended (slice boundary). Inbound frames are ignored\n * from this point so the cursor stops advancing exactly at the last delivered\n * event — the bridge keeps the turn running and the not-yet-delivered tail is\n * replayed to the next process on `resume`.\n */\n private suspended = false;\n /** Channel is fully torn down; `send` throws and `onClose` has fired. */\n private terminal = false;\n private _lastSeenEventId = 0;\n private readonly pendingSends: string[] = [];\n private dispatchChain: Promise<void> = Promise.resolve();\n\n constructor(options: SandboxChannelOptions<TOut>) {\n this.connectThunk = options.connect;\n this.outboundSchema = options.outboundSchema;\n this.onDebug = options.onDebug;\n this.onDiagnostic = options.onDiagnostic;\n this.maxElapsedMs = options.reconnect?.maxElapsedMs ?? 30_000;\n this.initialDelayMs = options.reconnect?.initialDelayMs ?? 50;\n this.maxDelayMs = options.reconnect?.maxDelayMs ?? 2_000;\n this._lastSeenEventId = options.initialLastSeenEventId ?? 0;\n }\n\n /**\n * Highest bridge event `seq` this channel has observed. Persist it (e.g. via\n * the adapter's resume handle) so a future process can seed\n * {@link SandboxChannelOptions.initialLastSeenEventId} and attach.\n */\n get lastSeenEventId(): number {\n return this._lastSeenEventId;\n }\n\n /**\n * Establish the initial connection. A single attempt — startup failures\n * reject so the caller can fail `doStart` cleanly. Reconnect retries apply\n * only to drops after a successful open.\n *\n * Pass `{ resume: true }` to attach to a bridge that is already mid-session:\n * after the socket opens, the channel sends `{ type: 'resume', lastSeenEventId }`\n * so the bridge replays everything past the seeded cursor. This is the\n * cross-process attach handshake — identical to what a transient reconnect\n * does, but triggered by the initial open from a new process.\n */\n async open(opts?: { resume?: boolean }): Promise<void> {\n if (this.terminal) {\n throw new Error('SandboxChannel: cannot open a closed channel.');\n }\n const ws = await this.connectThunk();\n this.wire(ws);\n this.ws = ws;\n this.connected = true;\n if (opts?.resume) {\n this.rawSend(\n JSON.stringify({\n type: 'resume',\n lastSeenEventId: this._lastSeenEventId,\n }),\n );\n }\n }\n\n on<T extends EventTypeOf<TOut>>(\n type: T,\n listener: Listener<TOut, T>,\n ): () => void {\n let set = this.listeners.get(type);\n if (!set) {\n set = new Set();\n this.listeners.set(type, set);\n }\n set.add(listener as unknown as Listener<TOut, EventTypeOf<TOut>>);\n\n const buffered = this.buffered.get(type);\n if (buffered) {\n this.buffered.delete(type);\n for (const event of buffered) {\n listener(event as Extract<TOut, { type: T }>);\n }\n }\n\n return () => {\n set!.delete(listener as unknown as Listener<TOut, EventTypeOf<TOut>>);\n };\n }\n\n onClose(handler: (code: number, reason: string) => void): void {\n this.onCloseHandlers.add(handler);\n }\n\n send(message: TIn): void {\n if (this.terminal) {\n throw new Error(\n `SandboxChannel: cannot send ${message.type} — channel is closed.`,\n );\n }\n this.rawSend(JSON.stringify(message));\n }\n\n /**\n * Mark that the host is tearing the session down. The next socket close is\n * then treated as terminal rather than triggering a reconnect. Call before\n * sending a `shutdown` / `detach` message whose ack the bridge follows with a\n * socket close.\n */\n beginClose(): void {\n this.closing = true;\n }\n\n close(): void {\n if (this.terminal) return;\n this.closing = true;\n try {\n this.ws?.close();\n } catch {\n // best-effort\n }\n this.enqueue(() => this.finalizeClose(1000, 'closed'));\n }\n\n /**\n * Gracefully suspend at a slice boundary: stop processing inbound frames\n * (so the cursor freezes at the last delivered event), drain any frames\n * already queued for dispatch, then close the socket and finalise with the\n * close reason `'suspended'`. Resolves with the final `lastSeenEventId`.\n *\n * The bridge keeps the in-flight turn running (a host socket close never\n * aborts it) and accumulates events past the cursor for the next process to\n * `resume`. Unlike {@link close}, the consumer's active turn is wound down\n * cleanly — adapters distinguish a suspend from an unexpected drop via the\n * `'suspended'` close reason and resolve `done` successfully.\n */\n suspend(): Promise<number> {\n return new Promise<number>(resolve => {\n if (this.terminal) {\n resolve(this._lastSeenEventId);\n return;\n }\n // Stop counting/dispatching further inbound frames immediately, and\n // suppress reconnect so the socket close finalises.\n this.suspended = true;\n this.closing = true;\n this.onClose(() => resolve(this._lastSeenEventId));\n // Queue the close behind any already-dispatched frames so everything\n // delivered to the consumer is reflected in the final cursor.\n this.enqueue(() => {\n try {\n this.ws?.close();\n } catch {\n // best-effort\n }\n this.finalizeClose(1000, 'suspended');\n });\n });\n }\n\n isClosed(): boolean {\n return this.terminal;\n }\n\n // ─── internals ──────────────────────────────────────────────────────\n\n private wire(ws: WebSocket): void {\n let dropped = false;\n const onDrop = (code: number, reason: string) => {\n if (dropped) return;\n dropped = true;\n if (ws !== this.ws) return;\n this.connected = false;\n if (this.closing) {\n this.enqueue(() => this.finalizeClose(code, reason));\n } else {\n this.enqueue(() => this.reconnectLoop());\n }\n };\n\n ws.on('message', (raw: ArrayBufferLike | string) => {\n // Once suspended, ignore further frames so the cursor freezes exactly at\n // the last delivered event (the bridge replays the rest to the next slice).\n if (this.suspended) return;\n const text =\n typeof raw === 'string' ? raw : Buffer.from(raw).toString('utf8');\n this.enqueue(() => this.handleIncoming(text));\n });\n ws.on('close', (code: number, reason: Buffer) =>\n onDrop(code, reason?.toString?.('utf8') ?? ''),\n );\n ws.on('error', () => onDrop(1006, 'socket error'));\n }\n\n private async reconnectLoop(): Promise<void> {\n if (this.terminal || this.closing) return;\n const start = Date.now();\n let attempt = 0;\n let delay = this.initialDelayMs;\n while (!this.terminal && !this.closing) {\n attempt++;\n this.onDebug?.({\n event: 'reconnect-attempt',\n attempt,\n lastSeenEventId: this._lastSeenEventId,\n });\n try {\n const ws = await this.connectThunk();\n if (this.terminal || this.closing) {\n try {\n ws.close();\n } catch {\n // best-effort\n }\n return;\n }\n this.wire(ws);\n this.ws = ws;\n this.connected = true;\n // Ask the bridge to replay everything we have not seen, then flush any\n // host → bridge frames produced while we were disconnected.\n this.rawSend(\n JSON.stringify({\n type: 'resume',\n lastSeenEventId: this._lastSeenEventId,\n }),\n );\n this.flushPending();\n this.onDebug?.({\n event: 'reconnected',\n attempt,\n lastSeenEventId: this._lastSeenEventId,\n });\n return;\n } catch (cause) {\n if (Date.now() - start >= this.maxElapsedMs) {\n this.finalizeClose(1006, 'reconnect failed');\n this.onDebug?.({\n event: 'reconnect-failed',\n attempts: attempt,\n lastSeenEventId: this._lastSeenEventId,\n cause,\n });\n return;\n }\n await sleep(delay);\n delay = Math.min(delay * 1.5, this.maxDelayMs);\n }\n }\n }\n\n private rawSend(text: string): void {\n if (this.connected && this.ws) {\n this.ws.send(text);\n } else {\n this.pendingSends.push(text);\n }\n }\n\n private flushPending(): void {\n if (!this.connected || !this.ws) return;\n const queued = this.pendingSends.splice(0);\n for (const text of queued) this.ws.send(text);\n }\n\n private enqueue(work: () => void | Promise<void>): void {\n this.dispatchChain = this.dispatchChain.then(work);\n }\n\n private async handleIncoming(text: string): Promise<void> {\n const raw = await safeParseJSON({ text });\n let seq: number | undefined;\n if (\n raw.success &&\n raw.value != null &&\n typeof raw.value === 'object' &&\n typeof (raw.value as { seq?: unknown }).seq === 'number'\n ) {\n seq = (raw.value as { seq: number }).seq;\n }\n\n const validated = await safeValidateTypes({\n value: raw.success ? raw.value : undefined,\n schema: this.outboundSchema,\n });\n if (validated.success) {\n this.dispatch(validated.value);\n } else {\n this.dispatch({\n type: 'error',\n error: validated.error,\n } as unknown as TOut);\n }\n\n if (seq !== undefined && seq > this._lastSeenEventId) {\n this._lastSeenEventId = seq;\n }\n }\n\n private dispatch(message: TOut): void {\n // Diagnostics are routed to their own sink and never enter the\n // per-type listener/buffer path, so they stay off the consumer stream.\n if (message.type === 'sandbox-log' || message.type === 'debug-event') {\n this.onDiagnostic?.(\n message as Extract<TOut, { type: 'sandbox-log' | 'debug-event' }>,\n );\n return;\n }\n const type = message.type as EventTypeOf<TOut>;\n const set = this.listeners.get(type);\n if (!set || set.size === 0) {\n let bucket = this.buffered.get(type);\n if (!bucket) {\n bucket = [];\n this.buffered.set(type, bucket);\n }\n bucket.push(message);\n return;\n }\n for (const listener of set) {\n listener(message as Extract<TOut, { type: EventTypeOf<TOut> }>);\n }\n }\n\n private finalizeClose(code: number, reason: string): void {\n if (this.terminal) return;\n this.terminal = true;\n this.connected = false;\n for (const h of this.onCloseHandlers) h(code, reason);\n }\n}\n","import { safeParseJSON } from '@ai-sdk/provider-utils';\n\n/**\n * Recovery rung selected from an on-disk bridge event log when attach is not\n * possible (the bridge process is gone): `'replay'` when the log holds a\n * complete turn the host can resume from its cursor, `'rerun'` otherwise.\n */\nexport type DiskLogRecoveryMode = 'replay' | 'rerun';\n\n/**\n * Decide whether a respawned bridge can `replay` a turn from its persisted\n * `event-log.ndjson`, or must `rerun` it from scratch.\n *\n * A turn is replayable only when its log ends in a terminal `finish` event —\n * a log that is missing, empty, or ends mid-turn means the bridge died before\n * completing the turn, so there is no coherent tail to deliver and the runtime\n * must re-run it (continuing its own thread from the sandbox snapshot).\n *\n * @param eventLog Raw contents of `event-log.ndjson` (newline-delimited JSON),\n * or `null`/`undefined`/empty when the file is absent.\n */\nexport async function classifyDiskLog(\n eventLog: string | null | undefined,\n): Promise<DiskLogRecoveryMode> {\n if (!eventLog) return 'rerun';\n const lines = eventLog\n .split('\\n')\n .map(line => line.trim())\n .filter(Boolean);\n const lastLine = lines.at(-1);\n if (lastLine == null) return 'rerun';\n\n const parsed = await safeParseJSON({ text: lastLine });\n if (\n parsed.success &&\n parsed.value != null &&\n typeof parsed.value === 'object' &&\n (parsed.value as { type?: unknown }).type === 'finish'\n ) {\n return 'replay';\n }\n return 'rerun';\n}\n","const DEFAULT_AI_GATEWAY_BASE_URL = 'https://ai-gateway.vercel.sh';\n\nexport function getAiGatewayAuthFromEnv({\n env,\n}: {\n env: Record<string, string | undefined>;\n}): {\n apiKey: string | undefined;\n baseUrl: string;\n} {\n return {\n apiKey: env.AI_GATEWAY_API_KEY || env.VERCEL_OIDC_TOKEN || undefined,\n baseUrl: env.AI_GATEWAY_BASE_URL ?? DEFAULT_AI_GATEWAY_BASE_URL,\n };\n}\n","import path from 'node:path';\nimport type { Experimental_SandboxSession } from '@ai-sdk/provider-utils';\n\nexport async function resolveSandboxHomeDir({\n sandbox,\n abortSignal,\n}: {\n sandbox: Experimental_SandboxSession;\n abortSignal?: AbortSignal;\n}): Promise<string> {\n const result = await sandbox.run({\n command: 'printf \"%s\" \"$HOME\"',\n abortSignal,\n });\n const homeDir = result.stdout.trim();\n if (result.exitCode !== 0 || !homeDir || !path.posix.isAbsolute(homeDir)) {\n throw new Error(\n `Unable to resolve sandbox HOME directory: ${result.stderr || result.stdout}`,\n );\n }\n return homeDir;\n}\n","export function shellQuote(value: string): string {\n return `'${value.replace(/'/g, `'\\\\''`)}'`;\n}\n","import path from 'node:path';\nimport type { Experimental_SandboxSession } from '@ai-sdk/provider-utils';\nimport type { HarnessV1Skill } from '../v1';\nimport { shellQuote } from './shell-quote';\n\nexport type SkillFilePathMode = 'relative' | 'strip-leading-slashes';\n\nexport type WriteSkillsOptions = {\n sandbox: Experimental_SandboxSession;\n rootDir: string;\n skills: ReadonlyArray<HarnessV1Skill>;\n abortSignal?: AbortSignal;\n skillNamePattern?: RegExp;\n invalidSkillNameMessage?: (input: { name: string }) => string;\n filePathMode?: SkillFilePathMode;\n invalidSkillFilePathMessage?: (input: {\n skillName: string;\n filePath: string;\n }) => string;\n trailingNewline?: boolean;\n};\n\nexport async function writeSkills({\n sandbox,\n rootDir,\n skills,\n abortSignal,\n skillNamePattern = /^[A-Za-z0-9._-]+$/,\n invalidSkillNameMessage = ({ name }) => `Invalid skill name: ${name}`,\n filePathMode = 'relative',\n invalidSkillFilePathMessage = ({ skillName, filePath }) =>\n `Invalid skill file path for ${skillName}: ${filePath}`,\n trailingNewline = false,\n}: WriteSkillsOptions): Promise<void> {\n for (const skill of skills) {\n validateSkillName({\n name: skill.name,\n pattern: skillNamePattern,\n message: invalidSkillNameMessage,\n });\n for (const file of skill.files ?? []) {\n normalizeSkillFilePath({\n skillName: skill.name,\n filePath: file.path,\n mode: filePathMode,\n message: invalidSkillFilePathMessage,\n });\n }\n }\n\n await sandbox.run({\n command: `mkdir -p ${shellQuote(rootDir)}`,\n abortSignal,\n });\n\n for (const skill of skills) {\n const name = validateSkillName({\n name: skill.name,\n pattern: skillNamePattern,\n message: invalidSkillNameMessage,\n });\n const skillDir = path.posix.join(rootDir, name);\n await sandbox.writeTextFile({\n path: path.posix.join(skillDir, 'SKILL.md'),\n content: renderSkillFile({ skill, trailingNewline }),\n abortSignal,\n });\n\n for (const file of skill.files ?? []) {\n const filePath = normalizeSkillFilePath({\n skillName: skill.name,\n filePath: file.path,\n mode: filePathMode,\n message: invalidSkillFilePathMessage,\n });\n await sandbox.writeTextFile({\n path: path.posix.join(skillDir, filePath),\n content: file.content,\n abortSignal,\n });\n }\n }\n}\n\nfunction validateSkillName({\n name,\n pattern,\n message,\n}: {\n name: string;\n pattern: RegExp;\n message?: (input: { name: string }) => string;\n}): string {\n if (!pattern.test(name) || name === '.' || name === '..') {\n throw new Error(message?.({ name }) ?? `Invalid skill name: ${name}`);\n }\n return name;\n}\n\nfunction normalizeSkillFilePath({\n skillName,\n filePath,\n mode,\n message,\n}: {\n skillName?: string;\n filePath: string;\n mode: SkillFilePathMode;\n message?: (input: { skillName: string; filePath: string }) => string;\n}): string {\n const normalized =\n mode === 'strip-leading-slashes'\n ? filePath.replace(/^\\/+/, '')\n : path.posix.normalize(filePath);\n const invalid =\n normalized === '' ||\n (mode === 'relative' && normalized === '.') ||\n normalized.startsWith('../') ||\n normalized.includes('/../') ||\n normalized.endsWith('/..') ||\n (mode === 'relative' && path.posix.isAbsolute(normalized));\n\n if (invalid) {\n throw new Error(\n message?.({ skillName: skillName ?? '', filePath }) ??\n `Invalid skill file path for ${skillName}: ${filePath}`,\n );\n }\n return normalized;\n}\n\nfunction renderSkillFile({\n skill,\n trailingNewline,\n}: {\n skill: HarnessV1Skill;\n trailingNewline: boolean;\n}): string {\n const content = `---\\nname: ${skill.name}\\ndescription: ${skill.description}\\n---\\n\\n${skill.content}`;\n return trailingNewline ? `${content}\\n` : content;\n}\n","import {\n safeParseJSON,\n type Experimental_SandboxProcess,\n type Experimental_SandboxSession,\n} from '@ai-sdk/provider-utils';\nimport { z } from 'zod/v4';\nimport { harnessV1BridgeReadySchema } from '../v1/harness-v1-bridge-protocol';\n\nconst bridgeMetaSchema = z.object({\n type: z.string().optional(),\n port: z.number().optional(),\n state: z.string().optional(),\n pid: z.number().optional(),\n});\n\nexport type BridgeReadySource = 'stdout' | 'metadata';\n\nexport type BridgeReadyErrorContext = {\n proc: Experimental_SandboxProcess;\n stdoutTail: string[];\n};\n\nexport type WaitForBridgeReadyOptions = {\n proc: Experimental_SandboxProcess;\n sandbox: Experimental_SandboxSession;\n bridgeStateDir: string;\n bridgeType: string;\n timeoutMs: number;\n abortSignal?: AbortSignal;\n pollIntervalMs?: number;\n createTimeoutError?: (\n context: BridgeReadyErrorContext,\n ) => Error | Promise<Error>;\n createExitError?: (\n context: BridgeReadyErrorContext,\n ) => Error | Promise<Error>;\n};\n\nexport type WaitForBridgeReadyResult = {\n port: number;\n source: BridgeReadySource;\n stdoutTail: string[];\n};\n\nexport async function markBridgeStarting({\n sandbox,\n bridgeStateDir,\n bridgeType,\n abortSignal,\n}: {\n sandbox: Experimental_SandboxSession;\n bridgeStateDir: string;\n bridgeType: string;\n abortSignal?: AbortSignal;\n}): Promise<void> {\n try {\n await sandbox.writeTextFile({\n path: bridgeMetaPath(bridgeStateDir),\n content: JSON.stringify({ type: bridgeType, state: 'starting' }),\n abortSignal,\n });\n } catch {\n /*\n * The bridge's own metadata writes are best-effort. This host-side marker\n * only prevents stale readiness fallback when possible; stdout remains the\n * primary readiness signal.\n */\n }\n}\n\nexport async function waitForBridgeReady({\n proc,\n sandbox,\n bridgeStateDir,\n bridgeType,\n timeoutMs,\n abortSignal,\n pollIntervalMs = 100,\n createTimeoutError,\n createExitError,\n}: WaitForBridgeReadyOptions): Promise<WaitForBridgeReadyResult> {\n const reader = proc.stdout.pipeThrough(new TextDecoderStream()).getReader();\n const decoder = lineDecoder();\n const stdoutTail: string[] = [];\n const deadline = Date.now() + timeoutMs;\n let pendingStdoutRead: Promise<ReadableStreamReadResult<string>> | undefined;\n let pendingMetaRead: Promise<number | undefined> | undefined;\n let nextMetaReadAt = 0;\n let cancelReader = false;\n\n try {\n while (true) {\n if (abortSignal?.aborted) {\n cancelReader = true;\n await proc.kill();\n throw abortSignal.reason ?? new DOMException('Aborted', 'AbortError');\n }\n\n const remaining = deadline - Date.now();\n if (remaining <= 0) {\n cancelReader = true;\n await proc.kill();\n throw await makeBridgeReadyError({\n createError: createTimeoutError,\n fallbackMessage: 'bridge did not become ready in time.',\n proc,\n stdoutTail,\n });\n }\n\n pendingStdoutRead ??= reader.read();\n const metaReadDelayMs = Math.max(0, nextMetaReadAt - Date.now());\n if (pendingMetaRead === undefined && metaReadDelayMs === 0) {\n pendingMetaRead = readBridgeMetaReady({\n sandbox,\n bridgeStateDir,\n bridgeType,\n abortSignal,\n });\n }\n\n const result = await Promise.race([\n pendingStdoutRead.then(read => ({ source: 'stdout' as const, read })),\n ...(pendingMetaRead === undefined\n ? []\n : [\n pendingMetaRead.then(port => ({\n source: 'metadata' as const,\n port,\n })),\n ]),\n sleep(\n Math.min(\n remaining,\n pendingMetaRead === undefined ? metaReadDelayMs : pollIntervalMs,\n ),\n ).then(() => undefined),\n ]);\n\n if (result === undefined) continue;\n\n if (result.source === 'metadata') {\n pendingMetaRead = undefined;\n if (result.port !== undefined) {\n cancelReader = true;\n return {\n port: result.port,\n source: 'metadata',\n stdoutTail: [...stdoutTail],\n };\n }\n nextMetaReadAt = Date.now() + pollIntervalMs;\n continue;\n }\n\n pendingStdoutRead = undefined;\n const { value, done } = result.read;\n if (done) {\n for (const line of decoder.flush()) {\n pushTail({ lines: stdoutTail, line });\n }\n throw await makeBridgeReadyError({\n createError: createExitError,\n fallbackMessage: 'bridge exited before becoming ready.',\n proc,\n stdoutTail,\n });\n }\n if (value === undefined) continue;\n for (const line of decoder.push(value)) {\n pushTail({ lines: stdoutTail, line });\n const parsed = await safeParseJSON({\n text: line,\n schema: harnessV1BridgeReadySchema,\n });\n if (parsed.success) {\n return {\n port: parsed.value.port,\n source: 'stdout',\n stdoutTail: [...stdoutTail],\n };\n }\n }\n }\n } finally {\n if (cancelReader) {\n await Promise.race([reader.cancel().catch(() => {}), sleep(100)]);\n }\n try {\n reader.releaseLock();\n } catch {}\n }\n}\n\nasync function readBridgeMetaReady({\n sandbox,\n bridgeStateDir,\n bridgeType,\n abortSignal,\n}: {\n sandbox: Experimental_SandboxSession;\n bridgeStateDir: string;\n bridgeType: string;\n abortSignal?: AbortSignal;\n}): Promise<number | undefined> {\n const raw = await Promise.resolve(\n sandbox.readTextFile({\n path: bridgeMetaPath(bridgeStateDir),\n abortSignal,\n }),\n ).catch(() => null);\n if (raw == null) return undefined;\n\n const parsed = await safeParseJSON({ text: raw, schema: bridgeMetaSchema });\n if (!parsed.success) return undefined;\n if (parsed.value.type !== bridgeType) return undefined;\n if (parsed.value.state !== 'waiting') return undefined;\n if (parsed.value.port === undefined || parsed.value.port <= 0) {\n return undefined;\n }\n return parsed.value.port;\n}\n\nasync function makeBridgeReadyError({\n createError,\n fallbackMessage,\n proc,\n stdoutTail,\n}: {\n createError:\n | ((context: BridgeReadyErrorContext) => Error | Promise<Error>)\n | undefined;\n fallbackMessage: string;\n proc: Experimental_SandboxProcess;\n stdoutTail: string[];\n}): Promise<Error> {\n if (createError) {\n return createError({ proc, stdoutTail: [...stdoutTail] });\n }\n return new Error(fallbackMessage);\n}\n\nfunction bridgeMetaPath(bridgeStateDir: string): string {\n return `${bridgeStateDir}/bridge-meta.json`;\n}\n\nfunction pushTail({ lines, line }: { lines: string[]; line: string }): void {\n lines.push(line);\n if (lines.length > 20) lines.shift();\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\nfunction lineDecoder() {\n let buffer = '';\n return {\n push(chunk: string): string[] {\n buffer += chunk;\n const lines: string[] = [];\n let nl: number;\n while ((nl = buffer.indexOf('\\n')) !== -1) {\n const raw = buffer.slice(0, nl);\n buffer = buffer.slice(nl + 1);\n const line = raw.replace(/\\r$/, '').trim();\n if (line.length > 0) lines.push(line);\n }\n return lines;\n },\n flush(): string[] {\n const line = buffer.replace(/\\r$/, '').trim();\n buffer = '';\n return line.length > 0 ? [line] : [];\n },\n };\n}\n","import { z } from 'zod/v4';\nimport {\n harnessV1DebugConfigSchema,\n harnessV1DebugLevelSchema,\n type HarnessV1Diagnostic,\n} from './harness-v1-diagnostic';\nimport {\n harnessV1CompactionPartSchema,\n harnessV1ErrorPartSchema,\n harnessV1FileChangePartSchema,\n harnessV1FinishPartSchema,\n harnessV1FinishStepPartSchema,\n harnessV1RawPartSchema,\n harnessV1ReasoningDeltaPartSchema,\n harnessV1ReasoningEndPartSchema,\n harnessV1ReasoningStartPartSchema,\n harnessV1StreamStartPartSchema,\n harnessV1TextDeltaPartSchema,\n harnessV1TextEndPartSchema,\n harnessV1TextStartPartSchema,\n harnessV1ToolApprovalRequestPartSchema,\n harnessV1ToolCallPartSchema,\n harnessV1ToolResultPartSchema,\n} from './harness-v1-stream-part';\n\n/*\n * The bridge wire protocol shared by every bridge-backed harness adapter.\n *\n * This is the serialization of the host<->runtime contract for adapters that\n * run the agent runtime inside the sandbox and talk to the host over a\n * WebSocket. It exists ONLY because of that transport: untrusted JSON frames\n * crossing the sandbox boundary need runtime validation, the connection needs\n * a handshake, and the host drives turns with serialized commands. Every export\n * here is therefore prefixed `harnessV1Bridge…`.\n *\n * It has three tiers:\n *\n * 1. The OUTBOUND events — `HarnessV1StreamPart` re-expressed as Zod (imported\n * member schemas from `harness-v1-stream-part.ts`), because the part type is\n * compile-time only and the frames need runtime validation at the boundary.\n * 2. The transport/control frames that are NOT consumer events — `bridge-hello`\n * (handshake), `bridge-detach` (resume payload), `bridge-thread` (a resume\n * coordinate some runtimes announce). These ride the same socket.\n * 3. The INBOUND command vocabulary the host sends back: the shared commands\n * live here; the per-adapter `start` payload extends\n * `harnessV1BridgeStartBaseSchema` and assembles the final inbound union in\n * the adapter package.\n *\n * Non-bridge adapters (e.g. Pi) do not use this layer at all — they have no\n * serialization boundary and target the universal `HarnessV1StreamPart` type\n * directly. That is the deliberate split: `harness-v1-stream-part.ts` is the\n * transport-agnostic event vocabulary; this file is the bridge transport.\n */\n\n/**\n * The subset of a host-defined tool that travels on the `start` message. The\n * runtime only needs the name, description, and JSON-Schema input to surface\n * the tool; `execute` stays on the host.\n */\nexport const harnessV1BridgeToolWireSchema = z.object({\n name: z.string(),\n description: z.string().optional(),\n inputSchema: z.unknown().optional(),\n});\n\nexport type HarnessV1BridgeToolWire = z.infer<\n typeof harnessV1BridgeToolWireSchema\n>;\n\nexport const harnessV1BridgePermissionModeSchema = z.enum([\n 'allow-reads',\n 'allow-edits',\n 'allow-all',\n]);\n\nexport const harnessV1BridgeBuiltinToolFilteringSchema = z.discriminatedUnion(\n 'mode',\n [\n z.object({\n mode: z.literal('allow'),\n toolNames: z.array(z.string()),\n }),\n z.object({\n mode: z.literal('deny'),\n toolNames: z.array(z.string()),\n }),\n ],\n);\n\n/**\n * Common fields of the inbound `start` message. Each adapter extends this with\n * its runtime-specific configuration (e.g. `thinking`/`continue` for Claude\n * Code, `reasoningEffort`/`webSearch`/`skills`/`resumeThreadId` for Codex) and\n * assembles the final inbound union from the shared command members below.\n *\n * `debug` carries the general `HarnessV1DebugConfig` — diagnostics config is not\n * a bridge concept, it just happens to ride the `start` frame for bridge-backed\n * adapters.\n */\nexport const harnessV1BridgeStartBaseSchema = z.object({\n type: z.literal('start'),\n prompt: z.string(),\n tools: z.array(harnessV1BridgeToolWireSchema).optional(),\n model: z.string().optional(),\n debug: harnessV1DebugConfigSchema.optional(),\n permissionMode: harnessV1BridgePermissionModeSchema.optional(),\n builtinToolFiltering: harnessV1BridgeBuiltinToolFilteringSchema.optional(),\n});\n\n// --- Transport / control frames (outbound, not consumer events) ---\n\n/**\n * Sent the instant the bridge accepts an authenticated WS connection. The host\n * waits for it before sending `start`/`resume`, because some sandbox runtimes\n * complete the upstream WS handshake before the connection is wired through to\n * the bridge process — anything sent in that gap is dropped. Carries the\n * bridge's lifecycle `state` and highest emitted `seq` for reconnect.\n */\nexport const harnessV1BridgeHelloSchema = z.object({\n type: z.literal('bridge-hello'),\n state: z.string().optional(),\n lastSeq: z.number().optional(),\n});\n\n/**\n * The bridge's reply to an inbound `detach`. Carries the adapter-specific\n * payload the host serializes into lifecycle state `data`.\n */\nexport const harnessV1BridgeDetachSchema = z.object({\n type: z.literal('bridge-detach'),\n data: z.unknown(),\n});\n\n/**\n * A resume coordinate the bridge proactively announces (e.g. Codex's thread id)\n * so the host can cache it for a later resume without waiting for `detach`.\n */\nexport const harnessV1BridgeThreadSchema = z.object({\n type: z.literal('bridge-thread'),\n threadId: z.string(),\n});\n\n// --- Diagnostics frames (outbound, not consumer events) ---\n\n/**\n * One captured console line from inside the sandbox. The bridge line-buffers\n * `process.stdout`/`process.stderr` and emits one of these per complete line.\n * Routed host-side to the diagnostics sink, never to the consumer stream.\n */\nexport const harnessV1BridgeSandboxLogSchema = z.object({\n type: z.literal('sandbox-log'),\n source: z.string(),\n stream: z.enum(['stdout', 'stderr']),\n line: z.string(),\n});\n\n/**\n * A structured diagnostic an adapter emits from inside the bridge via\n * `turn.bridgeLog(...)`. Gated by the session's debug level + subsystem filter.\n */\nexport const harnessV1BridgeDebugEventSchema = z.object({\n type: z.literal('debug-event'),\n level: harnessV1DebugLevelSchema,\n subsystem: z.string(),\n message: z.string(),\n attrs: z.record(z.string(), z.unknown()).optional(),\n error: z\n .object({\n name: z.string().optional(),\n message: z.string(),\n stack: z.string().optional(),\n })\n .optional(),\n});\n\n/**\n * Every frame a bridge can send to the host: the stream-part events plus the\n * transport/control frames. This is the schema the host `SandboxChannel`\n * validates inbound frames against.\n */\nexport const harnessV1BridgeOutboundMessageSchema = z.discriminatedUnion(\n 'type',\n [\n harnessV1StreamStartPartSchema,\n harnessV1TextStartPartSchema,\n harnessV1TextDeltaPartSchema,\n harnessV1TextEndPartSchema,\n harnessV1ReasoningStartPartSchema,\n harnessV1ReasoningDeltaPartSchema,\n harnessV1ReasoningEndPartSchema,\n harnessV1ToolCallPartSchema,\n harnessV1ToolApprovalRequestPartSchema,\n harnessV1ToolResultPartSchema,\n harnessV1FinishStepPartSchema,\n harnessV1FinishPartSchema,\n harnessV1FileChangePartSchema,\n harnessV1CompactionPartSchema,\n harnessV1ErrorPartSchema,\n harnessV1RawPartSchema,\n harnessV1BridgeHelloSchema,\n harnessV1BridgeDetachSchema,\n harnessV1BridgeThreadSchema,\n harnessV1BridgeSandboxLogSchema,\n harnessV1BridgeDebugEventSchema,\n ],\n);\n\nexport type HarnessV1BridgeOutboundMessage = z.infer<\n typeof harnessV1BridgeOutboundMessageSchema\n>;\n\nexport type HarnessV1BridgeSandboxLog = z.infer<\n typeof harnessV1BridgeSandboxLogSchema\n>;\n\nexport type HarnessV1BridgeDebugEvent = z.infer<\n typeof harnessV1BridgeDebugEventSchema\n>;\n\n/**\n * Normalize a bridge diagnostics wire frame into the transport-agnostic\n * `HarnessV1Diagnostic` an adapter reports to the framework. A captured console\n * line maps `stderr` → `warn` and `stdout` → `info`; a structured event passes\n * its fields through. This is the seam where the bridge's serialization is\n * lifted into the general emission shape every harness shares.\n */\nexport function harnessV1DiagnosticFromBridgeFrame(\n frame: HarnessV1BridgeSandboxLog | HarnessV1BridgeDebugEvent,\n context: { sessionId?: string; timestamp: number },\n): HarnessV1Diagnostic {\n if (frame.type === 'sandbox-log') {\n return {\n level: frame.stream === 'stderr' ? 'warn' : 'info',\n message: frame.line,\n subsystem: `sandbox.log.${frame.source}`,\n kind: 'log',\n source: frame.source,\n stream: frame.stream,\n sessionId: context.sessionId,\n timestamp: context.timestamp,\n };\n }\n return {\n level: frame.level,\n message: frame.message,\n subsystem: frame.subsystem,\n kind: 'event',\n attrs: frame.attrs,\n error: frame.error,\n sessionId: context.sessionId,\n timestamp: context.timestamp,\n };\n}\n\n// --- Shared inbound command members (host -> bridge) ---\n\nexport const harnessV1BridgeToolResultInboundSchema = z.object({\n type: z.literal('tool-result'),\n toolCallId: z.string(),\n output: z.unknown(),\n isError: z.boolean().optional(),\n});\n\nexport const harnessV1BridgeToolApprovalResponseInboundSchema = z.object({\n type: z.literal('tool-approval-response'),\n approvalId: z.string(),\n approved: z.boolean(),\n reason: z.string().optional(),\n});\n\nexport const harnessV1BridgeUserMessageInboundSchema = z.object({\n type: z.literal('user-message'),\n text: z.string(),\n});\n\nexport const harnessV1BridgeAbortInboundSchema = z.object({\n type: z.literal('abort'),\n});\n\nexport const harnessV1BridgeShutdownInboundSchema = z.object({\n type: z.literal('shutdown'),\n});\n\n/**\n * Reconnect: after re-establishing the socket the host asks the bridge to\n * replay every buffered event with `seq > lastSeenEventId`.\n */\nexport const harnessV1BridgeResumeInboundSchema = z.object({\n type: z.literal('resume'),\n lastSeenEventId: z.number(),\n});\n\n/**\n * The bridge replies with `bridge-detach` carrying any cached resume payload,\n * then exits.\n */\nexport const harnessV1BridgeDetachInboundSchema = z.object({\n type: z.literal('detach'),\n});\n\n/**\n * The inbound command members shared by every bridge adapter. Spread these\n * alongside the adapter's own `start` schema to build the final inbound union:\n * `z.discriminatedUnion('type', [adapterStartSchema, ...harnessV1BridgeInboundCommandSchemas])`.\n */\nexport const harnessV1BridgeInboundCommandSchemas = [\n harnessV1BridgeToolResultInboundSchema,\n harnessV1BridgeToolApprovalResponseInboundSchema,\n harnessV1BridgeUserMessageInboundSchema,\n harnessV1BridgeAbortInboundSchema,\n harnessV1BridgeShutdownInboundSchema,\n harnessV1BridgeResumeInboundSchema,\n harnessV1BridgeDetachInboundSchema,\n] as const;\n\n/**\n * The JSON line the bridge writes to stdout once its WebSocket server is bound,\n * announcing the port the host should connect to.\n */\nexport const harnessV1BridgeReadySchema = z.object({\n type: z.literal('bridge-ready'),\n port: z.number(),\n});\n\nexport type HarnessV1BridgeReady = z.infer<typeof harnessV1BridgeReadySchema>;\n","import { z } from 'zod/v4';\n\n/*\n * Diagnostics EMISSION contract — part of the `HarnessV1` spec.\n *\n * These are the types a harness adapter produces and receives: an adapter\n * reports a `HarnessV1Diagnostic` to the framework (a bridge adapter normalizes\n * its wire frames into one; a non-bridge adapter constructs one directly), and\n * receives a `HarnessV1DebugConfig` to gate what it emits. They are distinct\n * from the unaffixed host-facing `HarnessDiagnostic` / `HarnessDebugConfig`\n * (the external/telemetry surface) — the framework maps between the two at the\n * boundary, so the emission and consumption surfaces can evolve independently.\n */\n\n/** Severity of a diagnostic, ordered most → least severe. */\nexport const harnessV1DebugLevelSchema = z.enum([\n 'error',\n 'warn',\n 'info',\n 'debug',\n 'trace',\n]);\n\nexport type HarnessV1DebugLevel = z.infer<typeof harnessV1DebugLevelSchema>;\n\n/**\n * Per-session diagnostics configuration the framework hands an adapter (and the\n * host sends on `start.debug`). When absent or `enabled` is false the adapter\n * captures and emits nothing. `subsystems` filters structured events by dotted\n * prefix; console capture is independent of the subsystem filter.\n */\nexport const harnessV1DebugConfigSchema = z.object({\n enabled: z.boolean().optional(),\n level: harnessV1DebugLevelSchema.optional(),\n subsystems: z.array(z.string()).optional(),\n});\n\nexport type HarnessV1DebugConfig = z.infer<typeof harnessV1DebugConfigSchema>;\n\n/**\n * A diagnostic as emitted by a harness adapter. Structurally identical to the\n * host-facing `HarnessDiagnostic` today, but kept separate: this is the spec's\n * emission shape, that is the external consumption shape.\n */\nexport type HarnessV1Diagnostic = {\n /** Severity. */\n readonly level: HarnessV1DebugLevel;\n /** Human-readable line (console capture) or message (structured event). */\n readonly message: string;\n /** Dotted subsystem (`sandbox.log.<source>` for console capture). */\n readonly subsystem: string;\n /** `'log'` = captured console line; `'event'` = structured emission. */\n readonly kind: 'log' | 'event';\n /** Originating source label (console capture). */\n readonly source?: string;\n /** Which standard stream the line came from (console capture). */\n readonly stream?: 'stdout' | 'stderr';\n /** Structured attributes (structured events only). */\n readonly attrs?: Record<string, unknown>;\n /** Error payload (structured events only). */\n readonly error?: { name?: string; message: string; stack?: string };\n /** The harness session this diagnostic originated from. */\n readonly sessionId?: string;\n /** Emission time (epoch ms). */\n readonly timestamp: number;\n};\n","import type {\n JSONValue,\n LanguageModelV4FinishReason,\n LanguageModelV4ToolApprovalRequest,\n LanguageModelV4ToolCall,\n LanguageModelV4ToolResult,\n LanguageModelV4Usage,\n SharedV4ProviderMetadata,\n} from '@ai-sdk/provider';\nimport { z } from 'zod/v4';\nimport type { HarnessV1CallWarning } from './harness-v1-call-warning';\nimport type { HarnessV1Metadata } from './harness-v1-metadata';\n\n/**\n * One event emitted by a harness adapter during a prompt turn.\n *\n * Mirrors `LanguageModelV4StreamPart` on the variants it shares so a\n * `HarnessAgent` can pipe events through to AI SDK consumers with minimal\n * translation. Primitive types from the V4 spec (`LanguageModelV4ToolCall`,\n * `LanguageModelV4ToolResult`, `LanguageModelV4ToolApprovalRequest`,\n * `LanguageModelV4Usage`, `LanguageModelV4FinishReason`) are reused\n * verbatim — type-compat tests assert this stays the case.\n *\n * The metadata field is named `harnessMetadata` (not `providerMetadata`)\n * because a harness is a peer to a provider, not a kind of provider. The\n * agent rebinds it when forwarding to AI SDK consumers.\n */\nexport type HarnessV1StreamPart =\n | {\n type: 'stream-start';\n warnings?: ReadonlyArray<HarnessV1CallWarning>;\n /**\n * The model the runtime actually resolved to for this turn, when the\n * adapter learns it at stream start (e.g. Claude Code's `init` message\n * reports the resolved/default model). Surfaced into telemetry as\n * `gen_ai.request.model`. Omitted when the adapter doesn't know it here.\n */\n modelId?: string;\n }\n\n // Text blocks\n | { type: 'text-start'; id: string; harnessMetadata?: HarnessV1Metadata }\n | {\n type: 'text-delta';\n id: string;\n delta: string;\n harnessMetadata?: HarnessV1Metadata;\n }\n | { type: 'text-end'; id: string; harnessMetadata?: HarnessV1Metadata }\n\n // Reasoning blocks\n | { type: 'reasoning-start'; id: string; harnessMetadata?: HarnessV1Metadata }\n | {\n type: 'reasoning-delta';\n id: string;\n delta: string;\n harnessMetadata?: HarnessV1Metadata;\n }\n | { type: 'reasoning-end'; id: string; harnessMetadata?: HarnessV1Metadata }\n\n // Tool calls, approvals, results — reuse V4 primitives.\n //\n // `nativeName` is the only harness-only extension on `tool-call`. It lets\n // adapters surface the runtime's native name for a builtin when it differs\n // from the wire `toolName` (e.g. `toolName: 'bash'`, `nativeName: 'Bash'`).\n //\n // Whether the call was executed by the underlying runtime (Claude Code's\n // built-in `Bash`, Codex's `shell`) vs. needs host dispatch is signalled by\n // the standard `providerExecuted` field on `LanguageModelV4ToolCall` —\n // `true` for runtime-executed builtins, false/undefined for host tools.\n | (LanguageModelV4ToolCall & {\n nativeName?: string;\n })\n | LanguageModelV4ToolApprovalRequest\n | LanguageModelV4ToolResult\n\n // Step boundary inside a multi-step turn.\n | {\n type: 'finish-step';\n finishReason: LanguageModelV4FinishReason;\n usage: LanguageModelV4Usage;\n harnessMetadata?: HarnessV1Metadata;\n }\n\n // Turn end.\n | {\n type: 'finish';\n finishReason: LanguageModelV4FinishReason;\n totalUsage: LanguageModelV4Usage;\n harnessMetadata?: HarnessV1Metadata;\n }\n\n // Workspace file mutation that occurred through an opaque underlying\n // mechanism (one with no visible `tool-call` carrying the same data, e.g.\n // Codex's internal `apply_patch`). Emitted per changed path. Path-only by\n // design — when the mutation goes through a visible tool call, the\n // tool-call/tool-result pair already carries the information.\n | {\n type: 'file-change';\n event: 'create' | 'modify' | 'delete';\n path: string;\n harnessMetadata?: HarnessV1Metadata;\n }\n\n // Context compaction performed by the underlying runtime (Claude Code's\n // native compaction, Pi's summarization). Observation only — the runtime\n // owns the compaction; the harness neither implements nor schedules it.\n // Emitted once, on completion, since `summary`/`tokensAfter` only exist then.\n | {\n type: 'compaction';\n trigger: 'manual' | 'auto';\n summary: string;\n tokensBefore?: number;\n tokensAfter?: number;\n harnessMetadata?: HarnessV1Metadata;\n }\n\n // Errors. Multiple may be emitted in a single turn.\n | { type: 'error'; error: unknown }\n\n // Adapter-specific passthrough. Consumers can opt in to receive these via\n // `HarnessAgent` settings; otherwise they are dropped.\n | { type: 'raw'; rawValue: unknown };\n\n/*\n * Runtime (Zod) encoding of `HarnessV1StreamPart`.\n *\n * `HarnessV1StreamPart` is a compile-time type built on `LanguageModelV4*`\n * types that ship no runtime validator. Bridge adapters receive these parts as\n * JSON across a trust boundary (the sandbox WebSocket), so they need a runtime\n * schema. These schemas ARE that encoding — one source of truth, kept from\n * diverging from the type by the `_assignable` guard below and the mutual\n * `toEqualTypeOf` assertion in `harness-v1-stream-part.test-d.ts`.\n *\n * Members are exported individually so `harness-v1-bridge-protocol.ts` can\n * compose them into the bridge outbound union alongside the transport frames.\n */\n\nconst harnessV1JsonValueSchema: z.ZodType<JSONValue> = z.lazy(() =>\n z.union([\n z.string(),\n z.number(),\n z.boolean(),\n z.null(),\n z.array(harnessV1JsonValueSchema),\n z.record(z.string(), harnessV1JsonValueSchema),\n ]),\n);\n\n/*\n * Tool-result values. The inferred type is the spec's `NonNullable<JSONValue>`\n * (matching `LanguageModelV4ToolResult`), but the runtime validator\n * deliberately also accepts `null`: adapters emit `result: <value> ?? null` for\n * tools that produced no output, and that `null` must survive the trust\n * boundary unchanged (it reaches consumers exactly as it did before this schema\n * existed, when a cast hid it). Leniency at runtime, strictness in the type.\n */\nconst harnessV1ToolResultValueSchema =\n harnessV1JsonValueSchema as unknown as z.ZodType<NonNullable<JSONValue>>;\n\nconst harnessV1JsonObjectSchema = z.record(\n z.string(),\n harnessV1JsonValueSchema,\n) as unknown as z.ZodType<Record<string, JSONValue>>;\n\nconst harnessV1MetadataSchema = z.record(\n z.string(),\n z.record(z.string(), harnessV1JsonValueSchema),\n) as unknown as z.ZodType<HarnessV1Metadata>;\n\nconst harnessV1ProviderMetadataSchema = z.record(\n z.string(),\n z.record(z.string(), harnessV1JsonValueSchema),\n) as unknown as z.ZodType<SharedV4ProviderMetadata>;\n\nconst harnessV1CallWarningSchema = z.union([\n z.object({\n type: z.literal('unsupported-setting'),\n setting: z.string(),\n details: z.string().optional(),\n }),\n z.object({\n type: z.literal('unsupported-tool'),\n tool: z.string(),\n details: z.string().optional(),\n }),\n z.object({ type: z.literal('other'), message: z.string() }),\n]) as z.ZodType<HarnessV1CallWarning>;\n\nconst harnessV1UsageSchema = z.object({\n inputTokens: z.object({\n total: z.number().optional(),\n noCache: z.number().optional(),\n cacheRead: z.number().optional(),\n cacheWrite: z.number().optional(),\n }),\n outputTokens: z.object({\n total: z.number().optional(),\n text: z.number().optional(),\n reasoning: z.number().optional(),\n }),\n raw: harnessV1JsonObjectSchema.optional(),\n}) as unknown as z.ZodType<LanguageModelV4Usage>;\n\nconst harnessV1FinishReasonSchema = z.object({\n unified: z.enum([\n 'stop',\n 'length',\n 'content-filter',\n 'tool-calls',\n 'error',\n 'other',\n ]),\n raw: z.string().optional(),\n}) as unknown as z.ZodType<LanguageModelV4FinishReason>;\n\nexport const harnessV1StreamStartPartSchema = z.object({\n type: z.literal('stream-start'),\n warnings: z.array(harnessV1CallWarningSchema).readonly().optional(),\n modelId: z.string().optional(),\n});\n\nexport const harnessV1TextStartPartSchema = z.object({\n type: z.literal('text-start'),\n id: z.string(),\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1TextDeltaPartSchema = z.object({\n type: z.literal('text-delta'),\n id: z.string(),\n delta: z.string(),\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1TextEndPartSchema = z.object({\n type: z.literal('text-end'),\n id: z.string(),\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1ReasoningStartPartSchema = z.object({\n type: z.literal('reasoning-start'),\n id: z.string(),\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1ReasoningDeltaPartSchema = z.object({\n type: z.literal('reasoning-delta'),\n id: z.string(),\n delta: z.string(),\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1ReasoningEndPartSchema = z.object({\n type: z.literal('reasoning-end'),\n id: z.string(),\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1ToolCallPartSchema = z.object({\n type: z.literal('tool-call'),\n toolCallId: z.string(),\n toolName: z.string(),\n input: z.string(),\n providerExecuted: z.boolean().optional(),\n dynamic: z.boolean().optional(),\n providerMetadata: harnessV1ProviderMetadataSchema.optional(),\n nativeName: z.string().optional(),\n});\n\nexport const harnessV1ToolApprovalRequestPartSchema = z.object({\n type: z.literal('tool-approval-request'),\n approvalId: z.string(),\n toolCallId: z.string(),\n providerMetadata: harnessV1ProviderMetadataSchema.optional(),\n});\n\nexport const harnessV1ToolResultPartSchema = z.object({\n type: z.literal('tool-result'),\n toolCallId: z.string(),\n toolName: z.string(),\n result: harnessV1ToolResultValueSchema,\n isError: z.boolean().optional(),\n preliminary: z.boolean().optional(),\n dynamic: z.boolean().optional(),\n providerMetadata: harnessV1ProviderMetadataSchema.optional(),\n});\n\nexport const harnessV1FinishStepPartSchema = z.object({\n type: z.literal('finish-step'),\n finishReason: harnessV1FinishReasonSchema,\n usage: harnessV1UsageSchema,\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1FinishPartSchema = z.object({\n type: z.literal('finish'),\n finishReason: harnessV1FinishReasonSchema,\n totalUsage: harnessV1UsageSchema,\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1FileChangePartSchema = z.object({\n type: z.literal('file-change'),\n event: z.enum(['create', 'modify', 'delete']),\n path: z.string(),\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1CompactionPartSchema = z.object({\n type: z.literal('compaction'),\n trigger: z.enum(['manual', 'auto']),\n summary: z.string(),\n tokensBefore: z.number().optional(),\n tokensAfter: z.number().optional(),\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1ErrorPartSchema = z.object({\n type: z.literal('error'),\n error: z.unknown(),\n});\n\nexport const harnessV1RawPartSchema = z.object({\n type: z.literal('raw'),\n rawValue: z.unknown(),\n});\n\n/**\n * Assembled discriminated union over every `HarnessV1StreamPart` variant. Left\n * un-annotated so it keeps its precise inferred type — the protocol layer\n * composes the individual member schemas, and the type test asserts the\n * inferred union equals `HarnessV1StreamPart`.\n */\nexport const harnessV1StreamPartSchema = z.discriminatedUnion('type', [\n harnessV1StreamStartPartSchema,\n harnessV1TextStartPartSchema,\n harnessV1TextDeltaPartSchema,\n harnessV1TextEndPartSchema,\n harnessV1ReasoningStartPartSchema,\n harnessV1ReasoningDeltaPartSchema,\n harnessV1ReasoningEndPartSchema,\n harnessV1ToolCallPartSchema,\n harnessV1ToolApprovalRequestPartSchema,\n harnessV1ToolResultPartSchema,\n harnessV1FinishStepPartSchema,\n harnessV1FinishPartSchema,\n harnessV1FileChangePartSchema,\n harnessV1CompactionPartSchema,\n harnessV1ErrorPartSchema,\n harnessV1RawPartSchema,\n]);\n\n/*\n * Fail-fast guard at the definition site: the schema's output must be\n * assignable to `HarnessV1StreamPart` (catches a schema variant inventing a\n * shape the type does not allow). The reverse direction — the type being a\n * subset of the schema — is covered by the `toEqualTypeOf` assertion in the\n * type test.\n */\nconst _assignable: z.ZodType<HarnessV1StreamPart> = harnessV1StreamPartSchema;\nvoid _assignable;\n"],"mappings":"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","names":["safeParseJSON","path","path","safeParseJSON","z","z","z","z","z","z","z","sleep","safeParseJSON"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/harness",
3
- "version": "1.0.11",
3
+ "version": "1.0.12",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -2,6 +2,7 @@ import type { Context, ToolSet } from '@ai-sdk/provider-utils';
2
2
  import type { StreamTextResult, TelemetryOptions } from 'ai';
3
3
  import type { HarnessAgentToolApprovalConfiguration } from './harness-agent-settings';
4
4
  import type {
5
+ HarnessV1BuiltinToolFiltering,
5
6
  HarnessV1NetworkSandboxSession,
6
7
  HarnessV1SandboxProvider,
7
8
  } from '../v1';
@@ -138,7 +139,9 @@ export class HarnessAgentSession {
138
139
  prompt: HarnessAgentPrompt;
139
140
  instructions: string | undefined;
140
141
  tools: TOOLS;
142
+ activeTools: ToolSet;
141
143
  toolSpecs: HarnessAgentToolSpec[];
144
+ builtinToolFiltering: HarnessV1BuiltinToolFiltering | undefined;
142
145
  runtimeContext: RUNTIME_CONTEXT;
143
146
  abortSignal: AbortSignal | undefined;
144
147
  telemetry: TelemetryOptions | undefined;
@@ -154,7 +157,9 @@ export class HarnessAgentSession {
154
157
  prompt: options.prompt,
155
158
  instructions: options.instructions,
156
159
  tools: options.tools,
160
+ activeTools: options.activeTools,
157
161
  toolSpecs: options.toolSpecs,
162
+ builtinToolFiltering: options.builtinToolFiltering,
158
163
  sandboxSession: sandboxSession.restricted(),
159
164
  sessionWorkDir: this.sessionWorkDir,
160
165
  runtimeContext: options.runtimeContext,
@@ -187,7 +192,9 @@ export class HarnessAgentSession {
187
192
  >(options: {
188
193
  instructions: string | undefined;
189
194
  tools: TOOLS;
195
+ activeTools: ToolSet;
190
196
  toolSpecs: HarnessAgentToolSpec[];
197
+ builtinToolFiltering: HarnessV1BuiltinToolFiltering | undefined;
191
198
  runtimeContext: RUNTIME_CONTEXT;
192
199
  abortSignal: AbortSignal | undefined;
193
200
  telemetry: TelemetryOptions | undefined;
@@ -206,7 +213,9 @@ export class HarnessAgentSession {
206
213
  mode: 'continue',
207
214
  instructions: options.instructions,
208
215
  tools: options.tools,
216
+ activeTools: options.activeTools,
209
217
  toolSpecs: options.toolSpecs,
218
+ builtinToolFiltering: options.builtinToolFiltering,
210
219
  sandboxSession: sandboxSession.restricted(),
211
220
  sessionWorkDir: this.sessionWorkDir,
212
221
  runtimeContext: options.runtimeContext,
@@ -12,7 +12,8 @@ import type {
12
12
  Experimental_SandboxSession as SandboxSession,
13
13
  ToolSet,
14
14
  } from '@ai-sdk/provider-utils';
15
- import type { TelemetryOptions, ToolApprovalStatus } from 'ai';
15
+ import type { ActiveTools, TelemetryOptions, ToolApprovalStatus } from 'ai';
16
+ import type { HarnessAllTools } from './harness-agent-tool-types';
16
17
 
17
18
  export type HarnessAgentToolApprovalConfiguration = Readonly<
18
19
  Record<string, ToolApprovalStatus>
@@ -60,6 +61,8 @@ export type HarnessAgentSandboxConfig = {
60
61
  }) => Promise<void>;
61
62
  };
62
63
 
64
+ type HarnessTools<TOOLS extends ToolSet> = ActiveTools<NoInfer<TOOLS>>;
65
+
63
66
  /**
64
67
  * Construction-time settings for a `HarnessAgent`.
65
68
  *
@@ -67,6 +70,24 @@ export type HarnessAgentSandboxConfig = {
67
70
  * `AgentCallParameters` / `AgentStreamParameters` passed to `generate` /
68
71
  * `stream` and are not duplicated here.
69
72
  */
73
+ type HarnessAgentToolFilteringSettings<TOOLS extends ToolSet> =
74
+ | {
75
+ /**
76
+ * Limits the tools that are available for the harness to call without
77
+ * changing the tool call and result types in the result.
78
+ */
79
+ readonly activeTools?: HarnessTools<TOOLS>;
80
+ readonly inactiveTools?: never;
81
+ }
82
+ | {
83
+ readonly activeTools?: never;
84
+ /**
85
+ * Excludes tools from the set that is available for the harness to call
86
+ * without changing the tool call and result types in the result.
87
+ */
88
+ readonly inactiveTools?: HarnessTools<TOOLS>;
89
+ };
90
+
70
91
  export type HarnessAgentSettings<
71
92
  THarness extends HarnessAgentAdapter<any> = HarnessAgentAdapter,
72
93
  TUserTools extends ToolSet = {},
@@ -163,4 +184,4 @@ export type HarnessAgentSettings<
163
184
  * stderr default — wire this to capture diagnostics in code.
164
185
  */
165
186
  readonly onLog?: (event: HarnessDiagnostic) => void;
166
- };
187
+ } & HarnessAgentToolFilteringSettings<HarnessAllTools<THarness, TUserTools>>;
@@ -0,0 +1,15 @@
1
+ import type { HarnessAgentAdapter } from './harness-agent-types';
2
+ import type { ToolSet } from '@ai-sdk/provider-utils';
3
+
4
+ /** Extract the builtin tool set type from a harness adapter parameter. */
5
+ export type HarnessBuiltinToolsOf<H> =
6
+ H extends HarnessAgentAdapter<infer T> ? T : never;
7
+
8
+ /**
9
+ * Type-level merge of a harness's builtin tools with user-defined tools.
10
+ * User tools override builtins on key collision.
11
+ */
12
+ export type HarnessAllTools<
13
+ THarness extends HarnessAgentAdapter<any>,
14
+ TUserTools extends ToolSet,
15
+ > = Omit<HarnessBuiltinToolsOf<THarness>, keyof TUserTools> & TUserTools;
@@ -1,6 +1,7 @@
1
1
  import { HarnessCapabilityUnsupportedError } from '../errors/harness-capability-unsupported-error';
2
2
  import type {
3
3
  HarnessV1Bootstrap,
4
+ HarnessV1BuiltinToolFiltering,
4
5
  HarnessV1NetworkSandboxSession,
5
6
  HarnessV1SandboxProvider,
6
7
  } from '../v1';
@@ -24,6 +25,7 @@ import type {
24
25
  HarnessAgentSandboxConfig,
25
26
  HarnessAgentSettings,
26
27
  } from './harness-agent-settings';
28
+ import type { HarnessAllTools } from './harness-agent-tool-types';
27
29
  import { HarnessAgentSession } from './harness-agent-session';
28
30
  import type {
29
31
  HarnessAgentAdapter,
@@ -55,18 +57,9 @@ import {
55
57
  permissionModeNeedsBuiltinSupport,
56
58
  resolvePermissionMode,
57
59
  } from './internal/permission-mode';
60
+ import { resolveHarnessAgentToolFiltering } from './internal/tool-filtering';
58
61
 
59
- /** Extract the builtin tool set type from a harness adapter parameter. */
60
- type BuiltinToolsOf<H> = H extends HarnessAgentAdapter<infer T> ? T : never;
61
-
62
- /**
63
- * Type-level merge of a harness's builtin tools with user-defined tools.
64
- * User tools override builtins on key collision.
65
- */
66
- export type HarnessAllTools<
67
- THarness extends HarnessAgentAdapter<any>,
68
- TUserTools extends ToolSet,
69
- > = Omit<BuiltinToolsOf<THarness>, keyof TUserTools> & TUserTools;
62
+ export type { HarnessAllTools } from './harness-agent-tool-types';
70
63
 
71
64
  /**
72
65
  * Required `session` extension on every `HarnessAgent.generate` /
@@ -138,7 +131,10 @@ export class HarnessAgent<
138
131
 
139
132
  private readonly settings: HarnessAgentSettings<THarness, TUserTools>;
140
133
  private readonly sandboxConfig: HarnessAgentSandboxConfig;
141
- private readonly userTools: TUserTools;
134
+ private readonly activeUserTools: TUserTools;
135
+ private readonly builtinToolFiltering:
136
+ | HarnessV1BuiltinToolFiltering
137
+ | undefined;
142
138
  private readonly permissionMode: HarnessAgentPermissionMode;
143
139
 
144
140
  constructor(settings: HarnessAgentSettings<THarness, TUserTools>) {
@@ -147,10 +143,23 @@ export class HarnessAgent<
147
143
  this.settings = settings;
148
144
  this.sandboxConfig = sandboxConfig;
149
145
  this.id = settings.id;
150
- this.userTools = settings.tools ?? ({} as TUserTools);
146
+ const userTools = settings.tools ?? ({} as TUserTools);
151
147
  this.permissionMode = resolvePermissionMode({
152
148
  permissionMode: settings.permissionMode,
153
149
  });
150
+ const tools = {
151
+ ...settings.harness.builtinTools,
152
+ ...userTools,
153
+ } as HarnessAllTools<THarness, TUserTools>;
154
+ const toolFiltering = resolveHarnessAgentToolFiltering({
155
+ harness: settings.harness,
156
+ userTools,
157
+ allTools: tools,
158
+ activeTools: settings.activeTools,
159
+ inactiveTools: settings.inactiveTools,
160
+ });
161
+ this.activeUserTools = toolFiltering.activeUserTools;
162
+ this.builtinToolFiltering = toolFiltering.builtinToolFiltering;
154
163
  if (
155
164
  Object.keys(settings.harness.builtinTools).length > 0 &&
156
165
  permissionModeNeedsBuiltinSupport({
@@ -163,10 +172,7 @@ export class HarnessAgent<
163
172
  harnessId: settings.harness.harnessId,
164
173
  });
165
174
  }
166
- this.tools = {
167
- ...settings.harness.builtinTools,
168
- ...this.userTools,
169
- } as HarnessAllTools<THarness, TUserTools>;
175
+ this.tools = tools;
170
176
  }
171
177
 
172
178
  /** Identifier of the harness backing this agent. */
@@ -323,6 +329,7 @@ export class HarnessAgent<
323
329
  resumeFrom: validatedResumeFrom,
324
330
  continueFrom: effectiveContinueFrom,
325
331
  permissionMode: this.permissionMode,
332
+ builtinToolFiltering: this.builtinToolFiltering,
326
333
  abortSignal,
327
334
  observability: buildObservability({ settings: this.settings }),
328
335
  };
@@ -502,7 +509,9 @@ export class HarnessAgent<
502
509
  >({
503
510
  instructions: this.settings.instructions,
504
511
  tools: this.tools,
512
+ activeTools: this.activeUserTools,
505
513
  toolSpecs: this._toToolSpecs(),
514
+ builtinToolFiltering: this.builtinToolFiltering,
506
515
  runtimeContext: input.runtimeContext,
507
516
  abortSignal: input.abortSignal,
508
517
  telemetry: this.settings.telemetry,
@@ -517,7 +526,9 @@ export class HarnessAgent<
517
526
  prompt: input.turnInput.prompt,
518
527
  instructions: this.settings.instructions,
519
528
  tools: this.tools,
529
+ activeTools: this.activeUserTools,
520
530
  toolSpecs: this._toToolSpecs(),
531
+ builtinToolFiltering: this.builtinToolFiltering,
521
532
  runtimeContext: input.runtimeContext,
522
533
  abortSignal: input.abortSignal,
523
534
  telemetry: this.settings.telemetry,
@@ -604,7 +615,7 @@ export class HarnessAgent<
604
615
  private _toToolSpecs(): HarnessAgentToolSpec[] {
605
616
  const specs: HarnessAgentToolSpec[] = [];
606
617
  for (const [name, tool] of Object.entries(
607
- this.userTools as Record<string, unknown>,
618
+ this.activeUserTools as Record<string, unknown>,
608
619
  )) {
609
620
  const t = tool as {
610
621
  description?: string;