@ai-sdk/harness-deepagents 1.0.18 → 1.0.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @ai-sdk/harness-deepagents
2
2
 
3
+ ## 1.0.20
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [ac306ed]
8
+ - @ai-sdk/provider-utils@5.0.6
9
+ - @ai-sdk/harness@1.0.21
10
+
11
+ ## 1.0.19
12
+
13
+ ### Patch Changes
14
+
15
+ - b2d0306: feat(harness): send `User-Agent` and `x-client-app` headers in harness adapters
16
+ - Updated dependencies [b7aa06a]
17
+ - @ai-sdk/harness@1.0.20
18
+
3
19
  ## 1.0.18
4
20
 
5
21
  ### Patch Changes
@@ -1,6 +1,6 @@
1
1
  // src/bridge/index.ts
2
2
  import { randomUUID } from "crypto";
3
- import { argv } from "process";
3
+ import { argv, env as procEnv2 } from "process";
4
4
 
5
5
  // ../harness/dist/bridge/index.js
6
6
  import { appendFile, mkdir, writeFile } from "fs/promises";
@@ -624,6 +624,7 @@ var NATIVE_TO_COMMON2 = {
624
624
  edit_file: "edit",
625
625
  execute: "bash"
626
626
  };
627
+ var HARNESS_CLIENT_APP = procEnv2.AI_SDK_HARNESS_CLIENT_APP;
627
628
  function toCommonName2(nativeName) {
628
629
  return NATIVE_TO_COMMON2[nativeName] ?? nativeName;
629
630
  }
@@ -641,12 +642,20 @@ function parseArgs(rawArgs) {
641
642
  }
642
643
  function buildModel(rawModel) {
643
644
  if (!rawModel) return void 0;
644
- const baseUrl = process.env.ANTHROPIC_BASE_URL;
645
+ const baseUrl = procEnv2.ANTHROPIC_BASE_URL;
645
646
  const model = baseUrl ? rawModel : rawModel.replace(/^anthropic[/:]/, "");
646
647
  return new ChatAnthropic({
647
648
  model,
648
- ...process.env.ANTHROPIC_API_KEY ? { apiKey: process.env.ANTHROPIC_API_KEY } : {},
649
- ...baseUrl ? { anthropicApiUrl: baseUrl } : {}
649
+ ...procEnv2.ANTHROPIC_API_KEY ? { apiKey: procEnv2.ANTHROPIC_API_KEY } : {},
650
+ ...baseUrl ? { anthropicApiUrl: baseUrl } : {},
651
+ ...procEnv2.AI_GATEWAY_API_KEY && HARNESS_CLIENT_APP ? {
652
+ clientOptions: {
653
+ defaultHeaders: {
654
+ "User-Agent": HARNESS_CLIENT_APP,
655
+ "x-client-app": HARNESS_CLIENT_APP
656
+ }
657
+ }
658
+ } : {}
650
659
  });
651
660
  }
652
661
  function toToolCallInput(raw) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/bridge/index.ts","../../../harness/src/bridge/index.ts","../../src/bridge/approvals.ts","../../src/bridge/json-schema-to-zod.ts","../../src/bridge/local-shell-backend.ts","../../src/bridge/tool-filtering.ts"],"sourcesContent":["// In-sandbox turn driver on `@ai-sdk/harness/bridge`; third-party imports stay external (tsup) and install in-sandbox from src/bridge/package.json — keep import/externals/deps in sync.\n\nimport { randomUUID } from 'node:crypto';\nimport { argv } from 'node:process';\nimport {\n runBridge,\n type BridgeEvent,\n type BridgeTurn,\n} from '@ai-sdk/harness/bridge';\nimport { ChatAnthropic } from '@langchain/anthropic';\nimport { tool } from '@langchain/core/tools';\nimport { Command, MemorySaver } from '@langchain/langgraph';\nimport { createDeepAgent } from 'deepagents';\nimport type { StartMessage } from '../deepagents-bridge-protocol';\nimport { buildInterruptOn, collectActionRequests } from './approvals';\nimport { jsonSchemaToZodObject } from './json-schema-to-zod';\nimport { createLocalShellBackend } from './local-shell-backend';\nimport { createBuiltinToolFilteringMiddleware } from './tool-filtering';\n\n// Native Deep Agents tool name -> harness-v1 common name (renames only; grep/glob/ls/task/write_todos forward unchanged).\nconst NATIVE_TO_COMMON: Readonly<Record<string, string>> = {\n read_file: 'read',\n write_file: 'write',\n edit_file: 'edit',\n execute: 'bash',\n};\n\nfunction toCommonName(nativeName: string): string {\n return NATIVE_TO_COMMON[nativeName] ?? nativeName;\n}\n\nfunction parseArgs(rawArgs: string[]): Record<string, string> {\n const out: Record<string, string> = {};\n for (let i = 0; i < rawArgs.length; i++) {\n const arg = rawArgs[i];\n if (arg.startsWith('--')) {\n const key = arg\n .slice(2)\n .replace(/-([a-z])/g, (_, c: string) => c.toUpperCase());\n out[key] = rawArgs[i + 1];\n i++;\n }\n }\n return out;\n}\n\n// Always drive the Anthropic client. Through the gateway, models keep their\n// `creator/model` slug (gateway translates); direct Anthropic wants the bare id.\nfunction buildModel(rawModel: string | undefined) {\n if (!rawModel) return undefined;\n const baseUrl = process.env.ANTHROPIC_BASE_URL;\n const model = baseUrl ? rawModel : rawModel.replace(/^anthropic[/:]/, '');\n return new ChatAnthropic({\n model,\n ...(process.env.ANTHROPIC_API_KEY\n ? { apiKey: process.env.ANTHROPIC_API_KEY }\n : {}),\n ...(baseUrl ? { anthropicApiUrl: baseUrl } : {}),\n });\n}\n\n// LangChain reports some built-in tool args wrapped as `{ input: \"<json>\" }`; unwrap to the inner JSON so AI SDK validates the real shape.\nfunction toToolCallInput(raw: unknown): string {\n if (\n raw &&\n typeof raw === 'object' &&\n !Array.isArray(raw) &&\n Object.keys(raw).length === 1 &&\n typeof (raw as { input?: unknown }).input === 'string'\n ) {\n const inner = (raw as { input: string }).input;\n if (/^\\s*[[{]/.test(inner)) return inner;\n }\n return JSON.stringify(raw ?? {});\n}\n\nconst args = parseArgs(argv.slice(2));\nconst workdir = args.workdir;\nconst bridgeStateDir = args.bridgeStateDir;\nif (!workdir || !bridgeStateDir) {\n // eslint-disable-next-line no-console\n console.error('deepagents bridge: missing --workdir / --bridge-state-dir');\n process.exit(1);\n}\n\n// One agent per bridge process, reused across turns; host tools read the live turn via `currentTurn`.\nlet agent: ReturnType<typeof createDeepAgent> | undefined;\nlet currentTurn: BridgeTurn | undefined;\n\n// Host tools become LangChain tools that emit a `tool-call` and block on the host's `tool-result`.\nfunction buildHostTools(toolSchemas: StartMessage['tools']) {\n return (toolSchemas ?? []).map(schema =>\n tool(\n async (input: Record<string, unknown>) => {\n const turn = currentTurn;\n if (!turn) throw new Error('no active turn');\n const toolCallId = `${schema.name}-${randomUUID()}`;\n turn.emit({\n type: 'tool-call',\n toolCallId,\n toolName: schema.name,\n input: JSON.stringify(input),\n providerExecuted: false,\n } as BridgeEvent);\n const { output } = await turn.requestToolResult(toolCallId);\n return typeof output === 'string' ? output : JSON.stringify(output);\n },\n {\n name: schema.name,\n description: schema.description ?? '',\n schema: jsonSchemaToZodObject(schema.inputSchema),\n },\n ),\n );\n}\n\nasync function runTurn(start: StartMessage, turn: BridgeTurn): Promise<void> {\n currentTurn = turn;\n const emit = (event: Record<string, unknown>) =>\n turn.emit(event as BridgeEvent);\n\n const interruptOn = buildInterruptOn(\n start.permissionMode,\n start.builtinToolFiltering,\n );\n if (!agent) {\n const model = buildModel(start.model);\n const builtinToolFilteringMiddleware = createBuiltinToolFilteringMiddleware(\n {\n builtinToolFiltering: start.builtinToolFiltering,\n emit: event => {\n const turn = currentTurn;\n if (!turn) throw new Error('no active turn');\n turn.emit(event as BridgeEvent);\n },\n },\n );\n agent = createDeepAgent({\n // Defer to Deep Agents's own default when the host configured no model.\n ...(model ? { model } : {}),\n tools: buildHostTools(start.tools),\n backend: createLocalShellBackend({ rootDir: workdir }),\n systemPrompt: start.instructions || undefined,\n // Native skills loaded from the source dirs ($HOME-materialized + <workDir> for repo-provided skills).\n ...(start.skillsPaths?.length ? { skills: start.skillsPaths } : {}),\n ...(builtinToolFilteringMiddleware\n ? { middleware: [builtinToolFilteringMiddleware] }\n : {}),\n // Gate built-in tools behind HITL approval when the permission mode requires it.\n ...(interruptOn ? { interruptOn } : {}),\n // Real instance (LangGraph rejects `true` for root graphs); gives multi-turn memory.\n checkpointer: new MemorySaver(),\n });\n }\n\n emit({\n type: 'stream-start',\n ...(start.model ? { modelId: start.model } : {}),\n });\n\n const hostToolNames = new Set((start.tools ?? []).map(t => t.name));\n let textBlockId: string | undefined;\n let reasoningBlockId: string | undefined;\n let inputTokens = 0;\n let outputTokens = 0;\n // Per-call streamed-usage fallback (max over chunks), used only when model-end carries no usage.\n let streamedStepInput = 0;\n let streamedStepOutput = 0;\n // Top-level step usage is buffered at model-end and flushed as finish-step only after the step's tools run.\n let pendingStep: { input: number; output: number } | undefined;\n // Approval-gated tools are announced before execution; these tie the later run back to the approval id and dedup the call.\n const approvedToolQueue = new Map<string, string[]>();\n const approvedRunIds = new Map<string, string>();\n\n const ensureTextBlock = (): string => {\n if (!textBlockId) {\n textBlockId = `text-${randomUUID()}`;\n emit({ type: 'text-start', id: textBlockId });\n }\n return textBlockId;\n };\n const endTextBlock = () => {\n if (textBlockId) {\n emit({ type: 'text-end', id: textBlockId });\n textBlockId = undefined;\n }\n };\n const endReasoningBlock = () => {\n if (reasoningBlockId) {\n emit({ type: 'reasoning-end', id: reasoningBlockId });\n reasoningBlockId = undefined;\n }\n };\n // Text and reasoning are mutually exclusive open blocks: starting one closes the other.\n const emitText = (delta: string) => {\n endReasoningBlock();\n emit({ type: 'text-delta', id: ensureTextBlock(), delta });\n };\n const emitReasoning = (delta: string) => {\n endTextBlock();\n if (!reasoningBlockId) {\n reasoningBlockId = `reasoning-${randomUUID()}`;\n emit({ type: 'reasoning-start', id: reasoningBlockId });\n }\n emit({ type: 'reasoning-delta', id: reasoningBlockId, delta });\n };\n // Close the buffered top-level step; called when the next step starts and at turn end so finish-step lands after the step's tools.\n const flushStep = () => {\n if (!pendingStep) return;\n emit({\n type: 'finish-step',\n finishReason: { unified: 'stop' },\n usage: {\n inputTokens: { total: pendingStep.input },\n outputTokens: { total: pendingStep.output },\n },\n });\n pendingStep = undefined;\n };\n\n const config = {\n version: 'v2' as const,\n configurable: { thread_id: 'bridge-session' },\n recursionLimit: start.recursionLimit ?? 100,\n signal: turn.abortSignal,\n };\n\n // After a stream segment ends, return the tool calls paused by HITL interrupts (empty when the turn is truly done).\n const readPendingApprovals = async () => {\n try {\n const state = (await agent!.getState({\n configurable: { thread_id: 'bridge-session' },\n })) as { tasks?: Array<{ interrupts?: Array<{ value?: unknown }> }> };\n return collectActionRequests(\n (state.tasks ?? []).flatMap(t => t.interrupts ?? []),\n );\n } catch {\n return [];\n }\n };\n\n let resumeInput: unknown = {\n messages: [{ role: 'user', content: start.prompt }],\n };\n\n while (true) {\n const stream = await agent.streamEvents(resumeInput as never, config);\n\n for await (const event of stream) {\n const kind = event.event;\n const data = (event.data ?? {}) as Record<string, unknown>;\n // Subagent (e.g. `task`) events carry a `|`-delimited checkpoint namespace; keep their internals out of the top-level stream.\n const ns =\n (event as { metadata?: { langgraph_checkpoint_ns?: string } }).metadata\n ?.langgraph_checkpoint_ns ?? '';\n const nested = ns.includes('|');\n\n if (kind === 'on_chat_model_start') {\n // A new top-level model call means the previous step's tools have run; close it now.\n if (!nested) flushStep();\n } else if (kind === 'on_chat_model_stream') {\n if (nested) continue;\n const chunk = data.chunk as\n | {\n content?: unknown;\n usage_metadata?: {\n input_tokens?: number;\n output_tokens?: number;\n };\n }\n | undefined;\n if (!chunk) continue;\n const content = chunk.content;\n if (typeof content === 'string' && content) {\n emitText(content);\n } else if (Array.isArray(content)) {\n for (const block of content) {\n if (block && typeof block === 'object') {\n const b = block as {\n type?: string;\n text?: string;\n thinking?: string;\n };\n if (b.type === 'text' && b.text) emitText(b.text);\n else if (b.type === 'thinking' && b.thinking)\n emitReasoning(b.thinking);\n }\n }\n }\n const usage = chunk.usage_metadata;\n if (usage) {\n streamedStepInput = Math.max(\n streamedStepInput,\n usage.input_tokens ?? 0,\n );\n streamedStepOutput = Math.max(\n streamedStepOutput,\n usage.output_tokens ?? 0,\n );\n }\n } else if (kind === 'on_chat_model_end') {\n // Final usage lands on model-end, not the chunks; each model call is one step.\n const output = data.output as\n | {\n usage_metadata?: {\n input_tokens?: number;\n output_tokens?: number;\n };\n }\n | undefined;\n const usage = output?.usage_metadata;\n // One model call = one step; count its usage exactly once (model-end usage, else the streamed max).\n const stepInput = usage?.input_tokens ?? streamedStepInput;\n const stepOutput = usage?.output_tokens ?? streamedStepOutput;\n inputTokens += stepInput;\n outputTokens += stepOutput;\n streamedStepInput = 0;\n streamedStepOutput = 0;\n // Nested (subagent) calls still count toward total usage, but only top-level calls bound a visible step.\n if (!nested) {\n endTextBlock();\n endReasoningBlock();\n // Buffer the step; flushStep emits finish-step after this step's tools run (next start / turn end).\n pendingStep = { input: stepInput, output: stepOutput };\n }\n } else if (kind === 'on_tool_start') {\n const toolName = (event.name as string) ?? 'unknown';\n const runId = (event.run_id as string) ?? '';\n // Host tools emit their own tool-call; surface only top-level builtin (providerExecuted) tools.\n if (!nested && !hostToolNames.has(toolName)) {\n const queued = approvedToolQueue.get(toolName);\n if (queued && queued.length > 0) {\n // Already announced at approval time; tie this run to that id and don't re-emit the call.\n const approvalId = queued.shift()!;\n if (runId) approvedRunIds.set(runId, approvalId);\n } else {\n endTextBlock();\n endReasoningBlock();\n emit({\n type: 'tool-call',\n toolCallId: runId,\n toolName: toCommonName(toolName),\n input: toToolCallInput(data.input),\n providerExecuted: true,\n nativeName: toolName,\n });\n }\n }\n } else if (kind === 'on_tool_end') {\n const toolName = (event.name as string) ?? 'unknown';\n const runId = (event.run_id as string) ?? '';\n if (!nested && !hostToolNames.has(toolName)) {\n let output: unknown = data.output ?? '';\n if (output && typeof output === 'object' && 'content' in output) {\n output = (output as { content: unknown }).content;\n }\n emit({\n type: 'tool-result',\n toolCallId: approvedRunIds.get(runId) ?? runId,\n toolName: toCommonName(toolName),\n result: output ?? null,\n });\n approvedRunIds.delete(runId);\n }\n }\n }\n\n const actionRequests = await readPendingApprovals();\n if (actionRequests.length === 0) break;\n\n // HITL paused the run: announce each gated call, collect host decisions, then resume.\n const decisions: Array<\n { type: 'approve' } | { type: 'reject'; message?: string }\n > = [];\n for (const action of actionRequests) {\n const approvalId = `approval-${randomUUID()}`;\n endTextBlock();\n endReasoningBlock();\n emit({\n type: 'tool-call',\n toolCallId: approvalId,\n toolName: toCommonName(action.name),\n input: JSON.stringify(action.args ?? {}),\n providerExecuted: true,\n nativeName: action.name,\n });\n emit({\n type: 'tool-approval-request',\n approvalId,\n toolCallId: approvalId,\n });\n const decision = await turn.requestToolApproval(approvalId);\n if (decision.approved) {\n const queue = approvedToolQueue.get(action.name) ?? [];\n queue.push(approvalId);\n approvedToolQueue.set(action.name, queue);\n decisions.push({ type: 'approve' });\n } else {\n // Rejected tools never execute, so surface the outcome as the result now.\n emit({\n type: 'tool-result',\n toolCallId: approvalId,\n toolName: toCommonName(action.name),\n result: decision.reason ?? 'Rejected by user.',\n });\n decisions.push({\n type: 'reject',\n ...(decision.reason ? { message: decision.reason } : {}),\n });\n }\n }\n\n resumeInput = new Command({ resume: { decisions } });\n }\n\n endTextBlock();\n endReasoningBlock();\n flushStep();\n emit({\n type: 'finish',\n finishReason: { unified: 'stop' },\n totalUsage: {\n inputTokens: { total: inputTokens },\n outputTokens: { total: outputTokens },\n },\n });\n}\n\nawait runBridge<StartMessage>({\n bridgeType: 'deepagents',\n bridgeStateDir: bridgeStateDir!,\n onStart: runTurn,\n});\n","// Shared in-sandbox bridge runtime. Adapter `bridge.mjs` bundles re-bundle\n// this module (tsup inlines it; `ws` stays external and resolves from the\n// sandbox-installed node_modules). It owns everything generic to the bridge\n// transport — the WebSocket server, token auth, single-flight connection\n// replacement, the in-memory event log + monotonic `seq`, resume replay, and\n// the lifecycle/meta files. The adapter supplies only `onStart` (drive its\n// CLI/SDK and translate to wire events) and `onDetach` (its resume payload).\n\nimport { appendFile, mkdir, writeFile } from 'node:fs/promises';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { env as procEnv, pid, stdout } from 'node:process';\nimport { WebSocketServer, type WebSocket } from 'ws';\n\nexport type BridgeState = 'init' | 'waiting' | 'running' | 'draining' | 'done';\n\n/** Outbound turn event the adapter emits. `seq` is added by the runtime. */\nexport type BridgeEvent = Record<string, unknown> & { type: string };\n\nexport type BridgeDebugLevel = 'error' | 'warn' | 'info' | 'debug' | 'trace';\n\n/**\n * Per-session diagnostics config. The host resolves it from settings +\n * env and sends it on `start.debug`; the bridge gates console capture and\n * structured `debug-event`s on it. When disabled, nothing is captured or\n * emitted and no `seq` is consumed.\n */\nexport interface BridgeDebugConfig {\n enabled?: boolean;\n level?: BridgeDebugLevel;\n subsystems?: string[];\n}\n\nconst DEBUG_LEVEL_WEIGHT: Record<BridgeDebugLevel, number> = {\n error: 0,\n warn: 1,\n info: 2,\n debug: 3,\n trace: 4,\n};\n\n/** Exact-or-dotted-prefix subsystem match (`'bridge'` matches `'bridge.turn'`). */\nfunction subsystemMatches(\n filters: string[] | undefined,\n subsystem: string,\n): boolean {\n if (!filters || filters.length === 0) return true;\n return filters.some(\n filter => subsystem === filter || subsystem.startsWith(`${filter}.`),\n );\n}\n\nfunction formatBridgeError(err: unknown): {\n name?: string;\n message: string;\n stack?: string;\n} {\n if (err instanceof Error) {\n return { name: err.name, message: err.message, stack: err.stack };\n }\n return { message: String(err) };\n}\n\nfunction parseEnvList(value: string | undefined): string[] | undefined {\n if (!value) return undefined;\n const items = value\n .split(',')\n .map(item => item.trim())\n .filter(Boolean);\n return items.length > 0 ? items : undefined;\n}\n\nconst ENV_TRUTHY = new Set(['1', 'true', 'yes', 'on']);\n\n/**\n * Per-turn surface handed to {@link RunBridgeOptions.onStart}. The adapter\n * drives its runtime against these primitives; the runtime owns the transport.\n */\nexport interface BridgeTurn {\n /**\n * Emit a turn event to the host. Stamps a monotonic `seq`, appends to the\n * in-memory replay log, and sends to the live socket (best-effort — if the\n * host is mid-reconnect the event waits in the log and is replayed on\n * resume).\n */\n emit(event: BridgeEvent): void;\n\n /**\n * Register interest in a host-executed tool result and resolve when the\n * matching `tool-result` arrives. The adapter emits the `tool-call` event\n * itself (via {@link emit}) using the same `toolCallId`.\n */\n requestToolResult(\n toolCallId: string,\n ): Promise<{ output: unknown; isError?: boolean }>;\n\n /**\n * Register interest in a host approval decision and resolve when the matching\n * `tool-approval-response` arrives. The adapter emits the\n * `tool-approval-request` event itself using the same `approvalId`.\n */\n requestToolApproval(\n approvalId: string,\n ): Promise<{ approved: boolean; reason?: string }>;\n\n /**\n * Live queue of mid-turn user messages. The runtime pushes inbound\n * `user-message` text here; the adapter drains it as its runtime accepts\n * interactive input.\n */\n readonly pendingUserMessages: string[];\n\n /** Aborts when the host sends `abort`. */\n readonly abortSignal: AbortSignal;\n\n /** True for the first turn since this bridge process started. */\n readonly firstTurn: boolean;\n\n /**\n * Emit a structured diagnostic. Gated by the session's debug level +\n * subsystem filter; a no-op when diagnostics are disabled. Adapters use this\n * for runtime-level instrumentation; raw `console.*` output is captured and\n * forwarded automatically.\n */\n bridgeLog(input: {\n level?: BridgeDebugLevel;\n subsystem: string;\n message: string;\n attrs?: Record<string, unknown>;\n error?: unknown;\n }): void;\n}\n\nexport interface RunBridgeOptions<TStart extends { type: 'start' }> {\n /** Identifier written into `bridge-meta.json` (`'claude-code'` / `'codex'`). */\n bridgeType: string;\n /** Directory for `bridge-meta.json` / `start-config.json`. Created if absent. */\n bridgeStateDir: string;\n /** Drive one prompt turn. Rejections surface to the host as an `error` event. */\n onStart(start: TStart, turn: BridgeTurn): Promise<void>;\n /** Produce the adapter-defined resume payload for a `detach`. Defaults to `{}`. */\n onDetach?(): unknown | Promise<unknown>;\n /** WS port. Defaults to `BRIDGE_WS_PORT` env (0 = OS-assigned). */\n port?: number;\n /** Auth token. Defaults to `BRIDGE_CHANNEL_TOKEN` env. */\n token?: string;\n /** Called with the bound port once the server is listening. */\n onListening?(port: number): void;\n /**\n * Tear the process down after a `shutdown` / `detach`. Defaults to closing\n * the server and calling `process.exit(0)`. Overridable for tests.\n */\n onExit?(): void;\n}\n\ntype InboundControl =\n | {\n type: 'tool-result';\n toolCallId: string;\n output: unknown;\n isError?: boolean;\n }\n | {\n type: 'tool-approval-response';\n approvalId: string;\n approved: boolean;\n reason?: string;\n }\n | { type: 'user-message'; text: string }\n | { type: 'abort' }\n | { type: 'shutdown' }\n | { type: 'detach' }\n | { type: 'resume'; lastSeenEventId: number };\n\nconst WS_OPEN = 1;\n\n/**\n * Boot the bridge: bind the WebSocket server, announce `bridge-ready`, and\n * service host connections for the lifetime of the process. Resolves once the\n * server is listening; the process then stays alive on the server until a\n * `shutdown` / `detach` exits it.\n */\nexport interface BridgeHandle {\n /** The port the WebSocket server bound to. */\n readonly port: number;\n /** Close the WebSocket server. Does not call `process.exit`. */\n close(): Promise<void>;\n}\n\nexport async function runBridge<TStart extends { type: 'start' }>(\n options: RunBridgeOptions<TStart>,\n): Promise<BridgeHandle> {\n const { bridgeType, bridgeStateDir, onStart, onDetach } = options;\n const expectedToken = options.token ?? procEnv.BRIDGE_CHANNEL_TOKEN ?? '';\n const bridgeWsPort =\n options.port ?? parseInt(procEnv.BRIDGE_WS_PORT ?? '0', 10);\n\n const bridgeMetaPath = `${bridgeStateDir}/bridge-meta.json`;\n const startConfigPath = `${bridgeStateDir}/start-config.json`;\n const rerunStartConfigPath = `${bridgeStateDir}/rerun-start-config.json`;\n const eventLogPath = `${bridgeStateDir}/event-log.ndjson`;\n\n try {\n await mkdir(bridgeStateDir, { recursive: true });\n } catch {\n // Best-effort; the bridge still runs without its state files.\n }\n\n // ─── mutable runtime state ──────────────────────────────────────────\n let currentBoundPort = 0;\n let currentTurnState: BridgeState = 'init';\n let activeSocket: WebSocket | undefined;\n let isFirstTurn = true;\n let turnAbort: AbortController | undefined;\n let currentUserMessages: string[] | undefined;\n\n // Diagnostics. Resolved per turn from `start.debug` with a sandbox-side\n // env fallback; gates console capture + structured `debug-event`s.\n let debugConfig: BridgeDebugConfig | undefined;\n let consoleCaptureInstalled = false;\n const envDebugEnabled = ENV_TRUTHY.has(\n (procEnv.HARNESS_DEBUG ?? '').toLowerCase(),\n );\n\n // Replay log. `seq` is monotonic across the whole process — never reset —\n // because the host's `SandboxChannel` cursor (`lastSeenEventId`) lives across\n // turns. The log *contents* are cleared at the start of each turn to bound\n // memory; the just-finished turn stays replayable until the next `start`.\n let seqCounter = 0;\n let eventLog: Array<{ seq: number; line: string }> = [];\n\n /*\n * Disk mirror of the in-memory replay log. The in-memory log is lost when the\n * bridge process dies; the on-disk `event-log.ndjson` survives in the sandbox\n * filesystem so a respawned bridge (started with `BRIDGE_REPLAY_FROM_DISK=1`)\n * can reload the just-interrupted turn and serve a host's resume cursor —\n * `replay` recovery. Writes are batched on `setImmediate` (single-flight via\n * `flushPromise`) to keep `emit` off the disk hot path.\n */\n let diskBuffer = '';\n let flushPromise: Promise<void> | null = null;\n\n const flushEventsToDisk = async (): Promise<void> => {\n while (diskBuffer.length > 0) {\n const buf = diskBuffer;\n diskBuffer = '';\n await appendFile(eventLogPath, buf).catch(() => {\n // Best-effort crash-recovery mirror; the in-memory log is the source of\n // truth for the live connection.\n });\n }\n };\n\n const scheduleEventFlush = (): void => {\n if (flushPromise) return;\n flushPromise = new Promise<void>(resolve => {\n setImmediate(() => {\n void flushEventsToDisk().finally(resolve);\n });\n }).finally(() => {\n flushPromise = null;\n if (diskBuffer.length > 0) {\n scheduleEventFlush();\n }\n });\n };\n\n const flushPendingEventsToDisk = async (): Promise<void> => {\n if (diskBuffer.length > 0 && !flushPromise) {\n scheduleEventFlush();\n }\n // Await each in-flight flush, re-reading `flushPromise` after every await\n // since a fresh flush may have been scheduled for buffer that arrived while\n // we waited.\n let inFlight = flushPromise;\n while (inFlight) {\n await inFlight;\n inFlight = flushPromise;\n }\n };\n\n /*\n * When respawned for `replay`, reload the previous turn's log from disk before\n * accepting any connection so the very first `resume{lastSeenEventId}` can be\n * served the tail (including the terminal `finish`). The seq counter is\n * restored to the last persisted seq so it stays aligned with the host's\n * long-lived cursor. The file is NOT truncated in this mode — only a fresh\n * `start` (next turn) clears it.\n */\n const replayFromDisk = procEnv.BRIDGE_REPLAY_FROM_DISK === '1';\n if (replayFromDisk && existsSync(eventLogPath)) {\n try {\n const lines = readFileSync(eventLogPath, 'utf8')\n .split('\\n')\n .map(line => line.trim())\n .filter(Boolean);\n eventLog = lines.map(line => ({\n seq: (JSON.parse(line) as { seq: number }).seq,\n line,\n }));\n seqCounter = eventLog.at(-1)?.seq ?? 0;\n } catch {\n // Corrupt/partial log: fall back to an empty log; the host then degrades\n // to `rerun` instead of replaying a malformed tail.\n eventLog = [];\n seqCounter = 0;\n }\n }\n\n const pendingToolResults = new Map<\n string,\n (output: { output: unknown; isError?: boolean }) => void\n >();\n const pendingToolApprovals = new Map<\n string,\n (response: { approved: boolean; reason?: string }) => void\n >();\n\n // ─── persistence (best-effort meta + start config) ──────────────────\n const writeBridgeMeta = async (state: BridgeState): Promise<void> => {\n try {\n await writeFile(\n bridgeMetaPath,\n JSON.stringify({\n type: bridgeType,\n port: currentBoundPort,\n state,\n pid,\n }),\n );\n } catch {\n // Best-effort resilience metadata; not load-bearing for the active turn.\n }\n };\n\n const writeStartConfig = async (start: unknown): Promise<void> => {\n try {\n const serialized = JSON.stringify(start);\n await writeFile(startConfigPath, serialized);\n // Frozen copy: written once, restored over start-config.json by future\n // rerun-mode recovery to re-run the original turn from scratch.\n if (!existsSync(rerunStartConfigPath)) {\n await writeFile(rerunStartConfigPath, serialized);\n }\n } catch {\n // Best-effort.\n }\n };\n\n // ─── wire send + replay ─────────────────────────────────────────────\n const sendControl = (msg: Record<string, unknown>): void => {\n if (activeSocket?.readyState === WS_OPEN) {\n try {\n activeSocket.send(JSON.stringify(msg));\n } catch {\n // best-effort\n }\n }\n };\n\n const emit = (event: BridgeEvent): void => {\n const seq = ++seqCounter;\n const line = JSON.stringify({ ...event, seq });\n eventLog.push({ seq, line });\n diskBuffer += `${line}\\n`;\n scheduleEventFlush();\n if (activeSocket?.readyState === WS_OPEN) {\n try {\n activeSocket.send(line);\n } catch {\n // Send is best-effort: a dropped socket leaves the event in the log,\n // replayed once the host reconnects and sends `resume`.\n }\n }\n };\n\n const replay = (ws: WebSocket, afterSeq: number): void => {\n for (const entry of eventLog) {\n if (entry.seq > afterSeq && ws.readyState === WS_OPEN) {\n ws.send(entry.line);\n }\n }\n };\n\n // ─── diagnostics ──────────────────────────────────────────────\n const shouldEmitDebugEvent = (\n level: BridgeDebugLevel,\n subsystem: string,\n ): boolean => {\n if (!debugConfig?.enabled) return false;\n const threshold = debugConfig.level ?? 'debug';\n if (DEBUG_LEVEL_WEIGHT[level] > DEBUG_LEVEL_WEIGHT[threshold]) return false;\n return subsystemMatches(debugConfig.subsystems, subsystem);\n };\n\n /*\n * Forward sandbox console output. We line-buffer the original writers (kept so\n * output still reaches the real fds) and emit one `sandbox-log` per complete\n * line. `emit` never writes to stdout/stderr, so there is no recursion.\n * Installed lazily the first time a turn enables diagnostics; once installed,\n * capture is gated per-write on `debugConfig.enabled` so a later turn can\n * disable it. Console capture is independent of the subsystem/level filter.\n */\n const rawStdoutWrite = process.stdout.write.bind(process.stdout);\n const rawStderrWrite = process.stderr.write.bind(process.stderr);\n const installConsoleCapture = (): void => {\n if (consoleCaptureInstalled) return;\n consoleCaptureInstalled = true;\n const buffers: { stdout: string; stderr: string } = {\n stdout: '',\n stderr: '',\n };\n const patch =\n (stream: 'stdout' | 'stderr', raw: typeof process.stdout.write) =>\n (chunk: unknown, encoding?: unknown, cb?: unknown): boolean => {\n if (debugConfig?.enabled) {\n try {\n const enc = typeof encoding === 'string' ? encoding : 'utf8';\n const text =\n typeof chunk === 'string'\n ? chunk\n : Buffer.from(chunk as Uint8Array).toString(\n enc as BufferEncoding,\n );\n const combined = buffers[stream] + text.replace(/\\r\\n/g, '\\n');\n const parts = combined.split('\\n');\n buffers[stream] = parts.pop() ?? '';\n for (const line of parts) {\n const trimmed = line.replace(/\\s+$/, '');\n if (trimmed) {\n emit({\n type: 'sandbox-log',\n source: bridgeType,\n stream,\n line: trimmed,\n });\n }\n }\n } catch {\n // Never let capture break real output.\n }\n }\n return (raw as (c: unknown, e?: unknown, cb?: unknown) => boolean)(\n chunk,\n encoding,\n cb,\n );\n };\n process.stdout.write = patch(\n 'stdout',\n rawStdoutWrite,\n ) as typeof process.stdout.write;\n process.stderr.write = patch(\n 'stderr',\n rawStderrWrite,\n ) as typeof process.stderr.write;\n };\n\n // ─── inbound routing ────────────────────────────────────────────────\n const handleInbound = async (\n msg: TStart | InboundControl,\n ws: WebSocket,\n ): Promise<void> => {\n switch (msg.type) {\n case 'start': {\n const firstTurn = isFirstTurn;\n isFirstTurn = false;\n eventLog = []; // clear previous turn; keep seqCounter monotonic\n // Mirror the in-memory clear to disk: the log tracks only the current\n // turn. Discard any unflushed tail from the prior turn first.\n diskBuffer = '';\n void writeFile(eventLogPath, '').catch(() => {});\n turnAbort = new AbortController();\n currentTurnState = 'running';\n void writeStartConfig(msg);\n void writeBridgeMeta('running');\n const startDebug = (msg as { debug?: BridgeDebugConfig }).debug;\n debugConfig = {\n enabled: startDebug?.enabled ?? envDebugEnabled,\n level:\n startDebug?.level ??\n (procEnv.HARNESS_DEBUG_LEVEL as BridgeDebugLevel | undefined),\n subsystems:\n startDebug?.subsystems ??\n parseEnvList(procEnv.HARNESS_DEBUG_SUBSYSTEMS),\n };\n if (debugConfig.enabled) {\n installConsoleCapture();\n }\n const turn: BridgeTurn = {\n emit,\n requestToolResult: toolCallId =>\n new Promise(resolve => {\n pendingToolResults.set(toolCallId, resolve);\n }),\n requestToolApproval: approvalId =>\n new Promise(resolve => {\n pendingToolApprovals.set(approvalId, resolve);\n }),\n pendingUserMessages: [],\n abortSignal: turnAbort.signal,\n firstTurn,\n bridgeLog: input => {\n const level = input.level ?? 'debug';\n if (!shouldEmitDebugEvent(level, input.subsystem)) return;\n emit({\n type: 'debug-event',\n level,\n subsystem: input.subsystem,\n message: input.message,\n ...(input.attrs ? { attrs: input.attrs } : {}),\n ...(input.error !== undefined\n ? { error: formatBridgeError(input.error) }\n : {}),\n });\n },\n };\n currentUserMessages = turn.pendingUserMessages;\n try {\n await onStart(msg as TStart, turn);\n } catch (err) {\n emit({ type: 'error', error: serialiseError(err) });\n } finally {\n currentTurnState = 'waiting';\n void writeBridgeMeta('waiting');\n }\n return;\n }\n case 'tool-result': {\n const resolver = pendingToolResults.get(msg.toolCallId);\n if (resolver) {\n pendingToolResults.delete(msg.toolCallId);\n resolver({ output: msg.output, isError: msg.isError });\n }\n return;\n }\n case 'tool-approval-response': {\n const resolver = pendingToolApprovals.get(msg.approvalId);\n if (resolver) {\n pendingToolApprovals.delete(msg.approvalId);\n resolver({ approved: msg.approved, reason: msg.reason });\n }\n return;\n }\n case 'user-message':\n currentUserMessages?.push(msg.text);\n return;\n case 'abort':\n turnAbort?.abort();\n return;\n case 'resume':\n replay(ws, msg.lastSeenEventId);\n return;\n case 'shutdown':\n currentTurnState = 'done';\n void writeBridgeMeta('done');\n drainThenExit(ws, 1000, 'shutdown');\n return;\n case 'detach': {\n currentTurnState = 'done';\n void writeBridgeMeta('done');\n const data = (await onDetach?.()) ?? {};\n sendControl({ type: 'bridge-detach', data });\n drainThenExit(ws, 1000, 'detach');\n return;\n }\n }\n };\n\n // ─── server ─────────────────────────────────────────────────────────\n void writeBridgeMeta('init');\n\n const wss = new WebSocketServer({ port: bridgeWsPort, host: '0.0.0.0' });\n\n const exit = (): void => {\n if (options.onExit) {\n options.onExit();\n return;\n }\n wss.close(() => process.exit(0));\n setTimeout(() => process.exit(0), 1000).unref();\n };\n\n const drainThenExit = (ws: WebSocket, code: number, reason: string): void => {\n const start = Date.now();\n const tick = (): void => {\n const drained = ws.bufferedAmount === 0 || ws.readyState !== WS_OPEN;\n if (drained || Date.now() - start >= 5_000) {\n // Flush the on-disk log so a clean shutdown/detach leaves a complete\n // event-log.ndjson for any later replay recovery.\n void flushPendingEventsToDisk().finally(() => {\n try {\n ws.close(code, reason);\n } finally {\n exit();\n }\n });\n return;\n }\n setTimeout(tick, 10).unref();\n };\n tick();\n };\n\n wss.on('listening', () => {\n const addr = wss.address();\n currentBoundPort = typeof addr === 'object' && addr ? addr.port : 0;\n currentTurnState = 'waiting';\n void writeBridgeMeta('waiting');\n stdout.write(\n JSON.stringify({\n type: 'bridge-ready',\n port: currentBoundPort,\n }) + '\\n',\n );\n options.onListening?.(currentBoundPort);\n });\n\n wss.on('connection', (ws: WebSocket, req: { url?: string }) => {\n const url = new URL(req.url ?? '/', 'http://localhost');\n if (url.searchParams.get('agent_bridge_token') !== expectedToken) {\n ws.close(1008, 'unauthorized');\n return;\n }\n\n // Single-flight: a fresh authorized connection *replaces* the active one\n // (the host reconnecting after a drop). The previous socket's close is a\n // no-op below because it is no longer `activeSocket`.\n activeSocket = ws;\n\n // Announce liveness the instant we accept. Some sandbox runtimes complete\n // the host-side WS handshake before the connection is forwarded here; the\n // host waits for this frame before sending `start`/`resume`.\n sendControl({\n type: 'bridge-hello',\n state: currentTurnState,\n lastSeq: seqCounter,\n });\n\n ws.on('message', (raw: ArrayBufferLike | string) => {\n let parsed: TStart | InboundControl;\n try {\n const text =\n typeof raw === 'string' ? raw : Buffer.from(raw).toString('utf8');\n parsed = JSON.parse(text) as TStart | InboundControl;\n } catch (err) {\n sendControl({\n type: 'error',\n error: `protocol parse error: ${(err as Error).message}`,\n });\n return;\n }\n void handleInbound(parsed, ws);\n });\n\n ws.on('close', () => {\n // Only the *current* socket's close matters. A stale socket (already\n // replaced by a reconnect) closing is a no-op. Crucially we do NOT abort\n // the in-flight turn — it keeps running and its events accumulate in the\n // log for replay when the host reconnects.\n if (activeSocket === ws) {\n activeSocket = undefined;\n }\n });\n\n ws.on('error', () => {\n // 'close' follows; nothing to do beyond keeping the process alive.\n });\n });\n\n // Surface bridge-internal crashes to the host instead of dying silently.\n process.on('uncaughtException', err => {\n emit({ type: 'error', error: serialiseError(err) });\n });\n process.on('unhandledRejection', err => {\n emit({ type: 'error', error: serialiseError(err) });\n });\n\n await new Promise<void>((resolve, reject) => {\n if (wss.address() != null) {\n resolve();\n return;\n }\n\n wss.once('listening', resolve);\n wss.once('error', reject);\n });\n\n return {\n port: currentBoundPort,\n close: () =>\n new Promise<void>(resolve => {\n wss.close(() => resolve());\n }),\n };\n}\n\nfunction serialiseError(err: unknown): unknown {\n if (err instanceof Error) {\n return { name: err.name, message: err.message, stack: err.stack };\n }\n return err;\n}\n","import type { StartMessage } from '../deepagents-bridge-protocol';\n\nexport type PermissionMode = NonNullable<StartMessage['permissionMode']>;\n\n// Native built-in tool -> approval kind (mirrors the host adapter's toolUseKind).\nexport const NATIVE_TOOL_KIND: Readonly<\n Record<string, 'readonly' | 'edit' | 'bash'>\n> = {\n read_file: 'readonly',\n write_file: 'edit',\n edit_file: 'edit',\n execute: 'bash',\n grep: 'readonly',\n glob: 'readonly',\n ls: 'readonly',\n task: 'edit',\n write_todos: 'edit',\n};\n\nconst NATIVE_TO_COMMON: Readonly<Record<string, string>> = {\n read_file: 'read',\n write_file: 'write',\n edit_file: 'edit',\n execute: 'bash',\n};\n\nexport function toCommonName(nativeName: string): string {\n return NATIVE_TO_COMMON[nativeName] ?? nativeName;\n}\n\nexport function isBuiltinToolIncluded(input: {\n nativeName: string;\n toolFiltering: StartMessage['builtinToolFiltering'];\n}): boolean {\n if (input.toolFiltering == null) return true;\n const toolName = toCommonName(input.nativeName);\n return input.toolFiltering.mode === 'allow'\n ? input.toolFiltering.toolNames.includes(toolName)\n : !input.toolFiltering.toolNames.includes(toolName);\n}\n\nexport function builtinToolRequiresApproval(\n kind: 'readonly' | 'edit' | 'bash',\n permissionMode: PermissionMode,\n): boolean {\n if (permissionMode === 'allow-all') return false;\n if (permissionMode === 'allow-edits') return kind === 'bash';\n return kind === 'edit' || kind === 'bash';\n}\n\n// Per-tool HITL config for createDeepAgent; only built-ins are gated (host tools approve at the agent layer).\nexport function buildInterruptOn(\n permissionMode: PermissionMode | undefined,\n builtinToolFiltering: StartMessage['builtinToolFiltering'],\n):\n | Record<string, { allowedDecisions: Array<'approve' | 'reject'> }>\n | undefined {\n const config: Record<\n string,\n { allowedDecisions: Array<'approve' | 'reject'> }\n > = {};\n for (const [nativeName, kind] of Object.entries(NATIVE_TOOL_KIND)) {\n if (\n permissionMode != null &&\n isBuiltinToolIncluded({\n nativeName,\n toolFiltering: builtinToolFiltering,\n }) &&\n builtinToolRequiresApproval(kind, permissionMode)\n ) {\n config[nativeName] = { allowedDecisions: ['approve', 'reject'] };\n }\n }\n return Object.keys(config).length > 0 ? config : undefined;\n}\n\ntype ActionRequest = { name: string; args?: Record<string, unknown> };\ntype HITLInterruptValue = { actionRequests?: ActionRequest[] };\n\n// Flatten LangChain HITL interrupt payloads into the gated tool calls awaiting a decision.\nexport function collectActionRequests(\n interrupts: Array<{ value?: unknown }>,\n): { name: string; args: Record<string, unknown> }[] {\n const out: { name: string; args: Record<string, unknown> }[] = [];\n for (const interrupt of interrupts) {\n const value = interrupt.value as HITLInterruptValue | undefined;\n for (const action of value?.actionRequests ?? []) {\n out.push({ name: action.name, args: action.args ?? {} });\n }\n }\n return out;\n}\n","import { z } from 'zod/v4';\n\nexport type JsonSchemaObject = {\n type?: string | string[];\n description?: string;\n properties?: Record<string, JsonSchemaObject>;\n required?: string[];\n items?: JsonSchemaObject;\n nullable?: boolean;\n};\n\n// Convert a host tool's JSON Schema to a zod object for LangChain's `tool()`.\nexport function jsonSchemaToZodObject(input: unknown) {\n const schema =\n input && typeof input === 'object' ? (input as JsonSchemaObject) : {};\n return z.object(toZodShape(schema));\n}\n\nfunction toZodShape(schema: JsonSchemaObject): Record<string, z.ZodTypeAny> {\n if (!schema.properties) return {};\n const required = new Set(schema.required ?? []);\n const shape: Record<string, z.ZodTypeAny> = {};\n for (const [key, propSchema] of Object.entries(schema.properties)) {\n const propType = toZodType(propSchema);\n shape[key] = required.has(key) ? propType : propType.optional();\n }\n return shape;\n}\n\nfunction toZodType(schema: JsonSchemaObject | undefined): z.ZodTypeAny {\n if (!schema) return z.any();\n const types = Array.isArray(schema.type)\n ? schema.type.filter(t => t !== 'null')\n : ([schema.type].filter(Boolean) as string[]);\n let zType: z.ZodTypeAny;\n switch (types[0]) {\n case 'string':\n zType = z.string();\n break;\n case 'number':\n zType = z.number();\n break;\n case 'integer':\n zType = z.number().int();\n break;\n case 'boolean':\n zType = z.boolean();\n break;\n case 'array':\n zType = z.array(toZodType(schema.items));\n break;\n case 'object':\n zType = z.object(toZodShape(schema));\n break;\n case 'null':\n zType = z.null();\n break;\n default:\n zType = z.any();\n }\n if (schema.description) zType = zType.describe(schema.description);\n if (schema.nullable) zType = zType.nullable();\n return zType;\n}\n","import { LocalShellBackend } from 'deepagents';\n\nexport const SANDBOX_PATH_FALLBACK =\n '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin';\n\nexport function createLocalShellBackend({\n rootDir,\n env = process.env,\n}: {\n readonly rootDir: string;\n readonly env?: NodeJS.ProcessEnv;\n}): LocalShellBackend {\n return new LocalShellBackend({\n rootDir,\n env: {\n PATH: env.PATH ?? SANDBOX_PATH_FALLBACK,\n },\n });\n}\n","import {\n AIMessage,\n ToolMessage,\n type ToolCall,\n} from '@langchain/core/messages';\nimport type { createDeepAgent } from 'deepagents';\nimport type { StartMessage } from '../deepagents-bridge-protocol';\nimport {\n isBuiltinToolIncluded,\n NATIVE_TOOL_KIND,\n toCommonName,\n} from './approvals';\n\ntype DeepAgentsMiddleware = NonNullable<\n NonNullable<Parameters<typeof createDeepAgent>[0]>['middleware']\n>[number];\n\ntype DeepAgentsState = {\n messages: unknown[];\n};\n\ntype DeepAgentsMiddlewareUpdate = {\n messages: unknown[];\n jumpTo?: 'model';\n};\n\nconst MIDDLEWARE_BRAND = Symbol.for('AgentMiddleware');\n\nfunction getBuiltinToolFilteringDenialReason(input: {\n toolName: string;\n}): string {\n return `Tool '${input.toolName}' is inactive due to the HarnessAgent tool filtering policy.`;\n}\n\nfunction stringifyToolInput(input: unknown): string {\n return JSON.stringify(input ?? {});\n}\n\nfunction isNativeBuiltinToolCall(input: { toolCall: ToolCall }): boolean {\n return Object.keys(NATIVE_TOOL_KIND).includes(input.toolCall.name);\n}\n\nfunction isInactiveBuiltinToolCall(input: {\n toolCall: ToolCall;\n builtinToolFiltering: StartMessage['builtinToolFiltering'];\n}): boolean {\n return (\n isNativeBuiltinToolCall({ toolCall: input.toolCall }) &&\n !isBuiltinToolIncluded({\n nativeName: input.toolCall.name,\n toolFiltering: input.builtinToolFiltering,\n })\n );\n}\n\nexport function createBuiltinToolFilteringMiddleware(input: {\n builtinToolFiltering: StartMessage['builtinToolFiltering'];\n emit: (event: Record<string, unknown>) => void;\n}): DeepAgentsMiddleware | undefined {\n if (input.builtinToolFiltering == null) return undefined;\n\n return {\n [MIDDLEWARE_BRAND]: true,\n name: 'HarnessBuiltinToolFilteringMiddleware',\n afterModel: {\n canJumpTo: ['model'],\n hook: (\n state: DeepAgentsState,\n ): DeepAgentsMiddlewareUpdate | undefined => {\n const lastMessage = [...state.messages]\n .reverse()\n .find(message => AIMessage.isInstance(message));\n\n if (!lastMessage?.tool_calls?.length) return undefined;\n\n let hasActiveToolCalls = false;\n const deniedToolMessages: ToolMessage[] = [];\n\n for (const toolCall of lastMessage.tool_calls) {\n if (\n !isInactiveBuiltinToolCall({\n toolCall,\n builtinToolFiltering: input.builtinToolFiltering,\n })\n ) {\n hasActiveToolCalls = true;\n continue;\n }\n\n const nativeName = toolCall.name;\n toolCall.id ??= `${nativeName}-filtered-${deniedToolMessages.length}`;\n const toolName = toCommonName(nativeName);\n const reason = getBuiltinToolFilteringDenialReason({ toolName });\n\n input.emit({\n type: 'tool-call',\n toolCallId: toolCall.id,\n toolName,\n input: stringifyToolInput(toolCall.args),\n providerExecuted: true,\n nativeName,\n });\n input.emit({\n type: 'tool-result',\n toolCallId: toolCall.id,\n toolName,\n result: reason,\n });\n\n deniedToolMessages.push(\n new ToolMessage({\n content: reason,\n name: nativeName,\n tool_call_id: toolCall.id,\n status: 'error',\n }),\n );\n }\n\n if (deniedToolMessages.length === 0) return undefined;\n\n return {\n messages: [lastMessage, ...deniedToolMessages],\n ...(hasActiveToolCalls ? {} : { jumpTo: 'model' }),\n };\n },\n },\n } as DeepAgentsMiddleware;\n}\n"],"mappings":"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","names":["bridgeStateDir","NATIVE_TO_COMMON","toCommonName","turn"]}
1
+ {"version":3,"sources":["../../src/bridge/index.ts","../../../harness/src/bridge/index.ts","../../src/bridge/approvals.ts","../../src/bridge/json-schema-to-zod.ts","../../src/bridge/local-shell-backend.ts","../../src/bridge/tool-filtering.ts"],"sourcesContent":["// In-sandbox turn driver on `@ai-sdk/harness/bridge`; third-party imports stay external (tsup) and install in-sandbox from src/bridge/package.json — keep import/externals/deps in sync.\n\nimport { randomUUID } from 'node:crypto';\nimport { argv, env as procEnv } from 'node:process';\nimport {\n runBridge,\n type BridgeEvent,\n type BridgeTurn,\n} from '@ai-sdk/harness/bridge';\nimport { ChatAnthropic } from '@langchain/anthropic';\nimport { tool } from '@langchain/core/tools';\nimport { Command, MemorySaver } from '@langchain/langgraph';\nimport { createDeepAgent } from 'deepagents';\nimport type { StartMessage } from '../deepagents-bridge-protocol';\nimport { buildInterruptOn, collectActionRequests } from './approvals';\nimport { jsonSchemaToZodObject } from './json-schema-to-zod';\nimport { createLocalShellBackend } from './local-shell-backend';\nimport { createBuiltinToolFilteringMiddleware } from './tool-filtering';\n\n// Native Deep Agents tool name -> harness-v1 common name (renames only; grep/glob/ls/task/write_todos forward unchanged).\nconst NATIVE_TO_COMMON: Readonly<Record<string, string>> = {\n read_file: 'read',\n write_file: 'write',\n edit_file: 'edit',\n execute: 'bash',\n};\nconst HARNESS_CLIENT_APP = procEnv.AI_SDK_HARNESS_CLIENT_APP;\n\nfunction toCommonName(nativeName: string): string {\n return NATIVE_TO_COMMON[nativeName] ?? nativeName;\n}\n\nfunction parseArgs(rawArgs: string[]): Record<string, string> {\n const out: Record<string, string> = {};\n for (let i = 0; i < rawArgs.length; i++) {\n const arg = rawArgs[i];\n if (arg.startsWith('--')) {\n const key = arg\n .slice(2)\n .replace(/-([a-z])/g, (_, c: string) => c.toUpperCase());\n out[key] = rawArgs[i + 1];\n i++;\n }\n }\n return out;\n}\n\n// Always drive the Anthropic client. Through the gateway, models keep their\n// `creator/model` slug (gateway translates); direct Anthropic wants the bare id.\nfunction buildModel(rawModel: string | undefined) {\n if (!rawModel) return undefined;\n const baseUrl = procEnv.ANTHROPIC_BASE_URL;\n const model = baseUrl ? rawModel : rawModel.replace(/^anthropic[/:]/, '');\n return new ChatAnthropic({\n model,\n ...(procEnv.ANTHROPIC_API_KEY ? { apiKey: procEnv.ANTHROPIC_API_KEY } : {}),\n ...(baseUrl ? { anthropicApiUrl: baseUrl } : {}),\n ...(procEnv.AI_GATEWAY_API_KEY && HARNESS_CLIENT_APP\n ? {\n clientOptions: {\n defaultHeaders: {\n 'User-Agent': HARNESS_CLIENT_APP,\n 'x-client-app': HARNESS_CLIENT_APP,\n },\n },\n }\n : {}),\n });\n}\n\n// LangChain reports some built-in tool args wrapped as `{ input: \"<json>\" }`; unwrap to the inner JSON so AI SDK validates the real shape.\nfunction toToolCallInput(raw: unknown): string {\n if (\n raw &&\n typeof raw === 'object' &&\n !Array.isArray(raw) &&\n Object.keys(raw).length === 1 &&\n typeof (raw as { input?: unknown }).input === 'string'\n ) {\n const inner = (raw as { input: string }).input;\n if (/^\\s*[[{]/.test(inner)) return inner;\n }\n return JSON.stringify(raw ?? {});\n}\n\nconst args = parseArgs(argv.slice(2));\nconst workdir = args.workdir;\nconst bridgeStateDir = args.bridgeStateDir;\nif (!workdir || !bridgeStateDir) {\n // eslint-disable-next-line no-console\n console.error('deepagents bridge: missing --workdir / --bridge-state-dir');\n process.exit(1);\n}\n\n// One agent per bridge process, reused across turns; host tools read the live turn via `currentTurn`.\nlet agent: ReturnType<typeof createDeepAgent> | undefined;\nlet currentTurn: BridgeTurn | undefined;\n\n// Host tools become LangChain tools that emit a `tool-call` and block on the host's `tool-result`.\nfunction buildHostTools(toolSchemas: StartMessage['tools']) {\n return (toolSchemas ?? []).map(schema =>\n tool(\n async (input: Record<string, unknown>) => {\n const turn = currentTurn;\n if (!turn) throw new Error('no active turn');\n const toolCallId = `${schema.name}-${randomUUID()}`;\n turn.emit({\n type: 'tool-call',\n toolCallId,\n toolName: schema.name,\n input: JSON.stringify(input),\n providerExecuted: false,\n } as BridgeEvent);\n const { output } = await turn.requestToolResult(toolCallId);\n return typeof output === 'string' ? output : JSON.stringify(output);\n },\n {\n name: schema.name,\n description: schema.description ?? '',\n schema: jsonSchemaToZodObject(schema.inputSchema),\n },\n ),\n );\n}\n\nasync function runTurn(start: StartMessage, turn: BridgeTurn): Promise<void> {\n currentTurn = turn;\n const emit = (event: Record<string, unknown>) =>\n turn.emit(event as BridgeEvent);\n\n const interruptOn = buildInterruptOn(\n start.permissionMode,\n start.builtinToolFiltering,\n );\n if (!agent) {\n const model = buildModel(start.model);\n const builtinToolFilteringMiddleware = createBuiltinToolFilteringMiddleware(\n {\n builtinToolFiltering: start.builtinToolFiltering,\n emit: event => {\n const turn = currentTurn;\n if (!turn) throw new Error('no active turn');\n turn.emit(event as BridgeEvent);\n },\n },\n );\n agent = createDeepAgent({\n // Defer to Deep Agents's own default when the host configured no model.\n ...(model ? { model } : {}),\n tools: buildHostTools(start.tools),\n backend: createLocalShellBackend({ rootDir: workdir }),\n systemPrompt: start.instructions || undefined,\n // Native skills loaded from the source dirs ($HOME-materialized + <workDir> for repo-provided skills).\n ...(start.skillsPaths?.length ? { skills: start.skillsPaths } : {}),\n ...(builtinToolFilteringMiddleware\n ? { middleware: [builtinToolFilteringMiddleware] }\n : {}),\n // Gate built-in tools behind HITL approval when the permission mode requires it.\n ...(interruptOn ? { interruptOn } : {}),\n // Real instance (LangGraph rejects `true` for root graphs); gives multi-turn memory.\n checkpointer: new MemorySaver(),\n });\n }\n\n emit({\n type: 'stream-start',\n ...(start.model ? { modelId: start.model } : {}),\n });\n\n const hostToolNames = new Set((start.tools ?? []).map(t => t.name));\n let textBlockId: string | undefined;\n let reasoningBlockId: string | undefined;\n let inputTokens = 0;\n let outputTokens = 0;\n // Per-call streamed-usage fallback (max over chunks), used only when model-end carries no usage.\n let streamedStepInput = 0;\n let streamedStepOutput = 0;\n // Top-level step usage is buffered at model-end and flushed as finish-step only after the step's tools run.\n let pendingStep: { input: number; output: number } | undefined;\n // Approval-gated tools are announced before execution; these tie the later run back to the approval id and dedup the call.\n const approvedToolQueue = new Map<string, string[]>();\n const approvedRunIds = new Map<string, string>();\n\n const ensureTextBlock = (): string => {\n if (!textBlockId) {\n textBlockId = `text-${randomUUID()}`;\n emit({ type: 'text-start', id: textBlockId });\n }\n return textBlockId;\n };\n const endTextBlock = () => {\n if (textBlockId) {\n emit({ type: 'text-end', id: textBlockId });\n textBlockId = undefined;\n }\n };\n const endReasoningBlock = () => {\n if (reasoningBlockId) {\n emit({ type: 'reasoning-end', id: reasoningBlockId });\n reasoningBlockId = undefined;\n }\n };\n // Text and reasoning are mutually exclusive open blocks: starting one closes the other.\n const emitText = (delta: string) => {\n endReasoningBlock();\n emit({ type: 'text-delta', id: ensureTextBlock(), delta });\n };\n const emitReasoning = (delta: string) => {\n endTextBlock();\n if (!reasoningBlockId) {\n reasoningBlockId = `reasoning-${randomUUID()}`;\n emit({ type: 'reasoning-start', id: reasoningBlockId });\n }\n emit({ type: 'reasoning-delta', id: reasoningBlockId, delta });\n };\n // Close the buffered top-level step; called when the next step starts and at turn end so finish-step lands after the step's tools.\n const flushStep = () => {\n if (!pendingStep) return;\n emit({\n type: 'finish-step',\n finishReason: { unified: 'stop' },\n usage: {\n inputTokens: { total: pendingStep.input },\n outputTokens: { total: pendingStep.output },\n },\n });\n pendingStep = undefined;\n };\n\n const config = {\n version: 'v2' as const,\n configurable: { thread_id: 'bridge-session' },\n recursionLimit: start.recursionLimit ?? 100,\n signal: turn.abortSignal,\n };\n\n // After a stream segment ends, return the tool calls paused by HITL interrupts (empty when the turn is truly done).\n const readPendingApprovals = async () => {\n try {\n const state = (await agent!.getState({\n configurable: { thread_id: 'bridge-session' },\n })) as { tasks?: Array<{ interrupts?: Array<{ value?: unknown }> }> };\n return collectActionRequests(\n (state.tasks ?? []).flatMap(t => t.interrupts ?? []),\n );\n } catch {\n return [];\n }\n };\n\n let resumeInput: unknown = {\n messages: [{ role: 'user', content: start.prompt }],\n };\n\n while (true) {\n const stream = await agent.streamEvents(resumeInput as never, config);\n\n for await (const event of stream) {\n const kind = event.event;\n const data = (event.data ?? {}) as Record<string, unknown>;\n // Subagent (e.g. `task`) events carry a `|`-delimited checkpoint namespace; keep their internals out of the top-level stream.\n const ns =\n (event as { metadata?: { langgraph_checkpoint_ns?: string } }).metadata\n ?.langgraph_checkpoint_ns ?? '';\n const nested = ns.includes('|');\n\n if (kind === 'on_chat_model_start') {\n // A new top-level model call means the previous step's tools have run; close it now.\n if (!nested) flushStep();\n } else if (kind === 'on_chat_model_stream') {\n if (nested) continue;\n const chunk = data.chunk as\n | {\n content?: unknown;\n usage_metadata?: {\n input_tokens?: number;\n output_tokens?: number;\n };\n }\n | undefined;\n if (!chunk) continue;\n const content = chunk.content;\n if (typeof content === 'string' && content) {\n emitText(content);\n } else if (Array.isArray(content)) {\n for (const block of content) {\n if (block && typeof block === 'object') {\n const b = block as {\n type?: string;\n text?: string;\n thinking?: string;\n };\n if (b.type === 'text' && b.text) emitText(b.text);\n else if (b.type === 'thinking' && b.thinking)\n emitReasoning(b.thinking);\n }\n }\n }\n const usage = chunk.usage_metadata;\n if (usage) {\n streamedStepInput = Math.max(\n streamedStepInput,\n usage.input_tokens ?? 0,\n );\n streamedStepOutput = Math.max(\n streamedStepOutput,\n usage.output_tokens ?? 0,\n );\n }\n } else if (kind === 'on_chat_model_end') {\n // Final usage lands on model-end, not the chunks; each model call is one step.\n const output = data.output as\n | {\n usage_metadata?: {\n input_tokens?: number;\n output_tokens?: number;\n };\n }\n | undefined;\n const usage = output?.usage_metadata;\n // One model call = one step; count its usage exactly once (model-end usage, else the streamed max).\n const stepInput = usage?.input_tokens ?? streamedStepInput;\n const stepOutput = usage?.output_tokens ?? streamedStepOutput;\n inputTokens += stepInput;\n outputTokens += stepOutput;\n streamedStepInput = 0;\n streamedStepOutput = 0;\n // Nested (subagent) calls still count toward total usage, but only top-level calls bound a visible step.\n if (!nested) {\n endTextBlock();\n endReasoningBlock();\n // Buffer the step; flushStep emits finish-step after this step's tools run (next start / turn end).\n pendingStep = { input: stepInput, output: stepOutput };\n }\n } else if (kind === 'on_tool_start') {\n const toolName = (event.name as string) ?? 'unknown';\n const runId = (event.run_id as string) ?? '';\n // Host tools emit their own tool-call; surface only top-level builtin (providerExecuted) tools.\n if (!nested && !hostToolNames.has(toolName)) {\n const queued = approvedToolQueue.get(toolName);\n if (queued && queued.length > 0) {\n // Already announced at approval time; tie this run to that id and don't re-emit the call.\n const approvalId = queued.shift()!;\n if (runId) approvedRunIds.set(runId, approvalId);\n } else {\n endTextBlock();\n endReasoningBlock();\n emit({\n type: 'tool-call',\n toolCallId: runId,\n toolName: toCommonName(toolName),\n input: toToolCallInput(data.input),\n providerExecuted: true,\n nativeName: toolName,\n });\n }\n }\n } else if (kind === 'on_tool_end') {\n const toolName = (event.name as string) ?? 'unknown';\n const runId = (event.run_id as string) ?? '';\n if (!nested && !hostToolNames.has(toolName)) {\n let output: unknown = data.output ?? '';\n if (output && typeof output === 'object' && 'content' in output) {\n output = (output as { content: unknown }).content;\n }\n emit({\n type: 'tool-result',\n toolCallId: approvedRunIds.get(runId) ?? runId,\n toolName: toCommonName(toolName),\n result: output ?? null,\n });\n approvedRunIds.delete(runId);\n }\n }\n }\n\n const actionRequests = await readPendingApprovals();\n if (actionRequests.length === 0) break;\n\n // HITL paused the run: announce each gated call, collect host decisions, then resume.\n const decisions: Array<\n { type: 'approve' } | { type: 'reject'; message?: string }\n > = [];\n for (const action of actionRequests) {\n const approvalId = `approval-${randomUUID()}`;\n endTextBlock();\n endReasoningBlock();\n emit({\n type: 'tool-call',\n toolCallId: approvalId,\n toolName: toCommonName(action.name),\n input: JSON.stringify(action.args ?? {}),\n providerExecuted: true,\n nativeName: action.name,\n });\n emit({\n type: 'tool-approval-request',\n approvalId,\n toolCallId: approvalId,\n });\n const decision = await turn.requestToolApproval(approvalId);\n if (decision.approved) {\n const queue = approvedToolQueue.get(action.name) ?? [];\n queue.push(approvalId);\n approvedToolQueue.set(action.name, queue);\n decisions.push({ type: 'approve' });\n } else {\n // Rejected tools never execute, so surface the outcome as the result now.\n emit({\n type: 'tool-result',\n toolCallId: approvalId,\n toolName: toCommonName(action.name),\n result: decision.reason ?? 'Rejected by user.',\n });\n decisions.push({\n type: 'reject',\n ...(decision.reason ? { message: decision.reason } : {}),\n });\n }\n }\n\n resumeInput = new Command({ resume: { decisions } });\n }\n\n endTextBlock();\n endReasoningBlock();\n flushStep();\n emit({\n type: 'finish',\n finishReason: { unified: 'stop' },\n totalUsage: {\n inputTokens: { total: inputTokens },\n outputTokens: { total: outputTokens },\n },\n });\n}\n\nawait runBridge<StartMessage>({\n bridgeType: 'deepagents',\n bridgeStateDir: bridgeStateDir!,\n onStart: runTurn,\n});\n","// Shared in-sandbox bridge runtime. Adapter `bridge.mjs` bundles re-bundle\n// this module (tsup inlines it; `ws` stays external and resolves from the\n// sandbox-installed node_modules). It owns everything generic to the bridge\n// transport — the WebSocket server, token auth, single-flight connection\n// replacement, the in-memory event log + monotonic `seq`, resume replay, and\n// the lifecycle/meta files. The adapter supplies only `onStart` (drive its\n// CLI/SDK and translate to wire events) and `onDetach` (its resume payload).\n\nimport { appendFile, mkdir, writeFile } from 'node:fs/promises';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { env as procEnv, pid, stdout } from 'node:process';\nimport { WebSocketServer, type WebSocket } from 'ws';\n\nexport type BridgeState = 'init' | 'waiting' | 'running' | 'draining' | 'done';\n\n/** Outbound turn event the adapter emits. `seq` is added by the runtime. */\nexport type BridgeEvent = Record<string, unknown> & { type: string };\n\nexport type BridgeDebugLevel = 'error' | 'warn' | 'info' | 'debug' | 'trace';\n\n/**\n * Per-session diagnostics config. The host resolves it from settings +\n * env and sends it on `start.debug`; the bridge gates console capture and\n * structured `debug-event`s on it. When disabled, nothing is captured or\n * emitted and no `seq` is consumed.\n */\nexport interface BridgeDebugConfig {\n enabled?: boolean;\n level?: BridgeDebugLevel;\n subsystems?: string[];\n}\n\nconst DEBUG_LEVEL_WEIGHT: Record<BridgeDebugLevel, number> = {\n error: 0,\n warn: 1,\n info: 2,\n debug: 3,\n trace: 4,\n};\n\n/** Exact-or-dotted-prefix subsystem match (`'bridge'` matches `'bridge.turn'`). */\nfunction subsystemMatches(\n filters: string[] | undefined,\n subsystem: string,\n): boolean {\n if (!filters || filters.length === 0) return true;\n return filters.some(\n filter => subsystem === filter || subsystem.startsWith(`${filter}.`),\n );\n}\n\nfunction formatBridgeError(err: unknown): {\n name?: string;\n message: string;\n stack?: string;\n} {\n if (err instanceof Error) {\n return { name: err.name, message: err.message, stack: err.stack };\n }\n return { message: String(err) };\n}\n\nfunction parseEnvList(value: string | undefined): string[] | undefined {\n if (!value) return undefined;\n const items = value\n .split(',')\n .map(item => item.trim())\n .filter(Boolean);\n return items.length > 0 ? items : undefined;\n}\n\nconst ENV_TRUTHY = new Set(['1', 'true', 'yes', 'on']);\n\n/**\n * Per-turn surface handed to {@link RunBridgeOptions.onStart}. The adapter\n * drives its runtime against these primitives; the runtime owns the transport.\n */\nexport interface BridgeTurn {\n /**\n * Emit a turn event to the host. Stamps a monotonic `seq`, appends to the\n * in-memory replay log, and sends to the live socket (best-effort — if the\n * host is mid-reconnect the event waits in the log and is replayed on\n * resume).\n */\n emit(event: BridgeEvent): void;\n\n /**\n * Register interest in a host-executed tool result and resolve when the\n * matching `tool-result` arrives. The adapter emits the `tool-call` event\n * itself (via {@link emit}) using the same `toolCallId`.\n */\n requestToolResult(\n toolCallId: string,\n ): Promise<{ output: unknown; isError?: boolean }>;\n\n /**\n * Register interest in a host approval decision and resolve when the matching\n * `tool-approval-response` arrives. The adapter emits the\n * `tool-approval-request` event itself using the same `approvalId`.\n */\n requestToolApproval(\n approvalId: string,\n ): Promise<{ approved: boolean; reason?: string }>;\n\n /**\n * Live queue of mid-turn user messages. The runtime pushes inbound\n * `user-message` text here; the adapter drains it as its runtime accepts\n * interactive input.\n */\n readonly pendingUserMessages: string[];\n\n /** Aborts when the host sends `abort`. */\n readonly abortSignal: AbortSignal;\n\n /** True for the first turn since this bridge process started. */\n readonly firstTurn: boolean;\n\n /**\n * Emit a structured diagnostic. Gated by the session's debug level +\n * subsystem filter; a no-op when diagnostics are disabled. Adapters use this\n * for runtime-level instrumentation; raw `console.*` output is captured and\n * forwarded automatically.\n */\n bridgeLog(input: {\n level?: BridgeDebugLevel;\n subsystem: string;\n message: string;\n attrs?: Record<string, unknown>;\n error?: unknown;\n }): void;\n}\n\nexport interface RunBridgeOptions<TStart extends { type: 'start' }> {\n /** Identifier written into `bridge-meta.json` (`'claude-code'` / `'codex'`). */\n bridgeType: string;\n /** Directory for `bridge-meta.json` / `start-config.json`. Created if absent. */\n bridgeStateDir: string;\n /** Drive one prompt turn. Rejections surface to the host as an `error` event. */\n onStart(start: TStart, turn: BridgeTurn): Promise<void>;\n /** Produce the adapter-defined resume payload for a `detach`. Defaults to `{}`. */\n onDetach?(): unknown | Promise<unknown>;\n /** WS port. Defaults to `BRIDGE_WS_PORT` env (0 = OS-assigned). */\n port?: number;\n /** Auth token. Defaults to `BRIDGE_CHANNEL_TOKEN` env. */\n token?: string;\n /** Called with the bound port once the server is listening. */\n onListening?(port: number): void;\n /**\n * Tear the process down after a `shutdown` / `detach`. Defaults to closing\n * the server and calling `process.exit(0)`. Overridable for tests.\n */\n onExit?(): void;\n}\n\ntype InboundControl =\n | {\n type: 'tool-result';\n toolCallId: string;\n output: unknown;\n isError?: boolean;\n }\n | {\n type: 'tool-approval-response';\n approvalId: string;\n approved: boolean;\n reason?: string;\n }\n | { type: 'user-message'; text: string }\n | { type: 'abort' }\n | { type: 'shutdown' }\n | { type: 'detach' }\n | { type: 'resume'; lastSeenEventId: number };\n\nconst WS_OPEN = 1;\n\n/**\n * Boot the bridge: bind the WebSocket server, announce `bridge-ready`, and\n * service host connections for the lifetime of the process. Resolves once the\n * server is listening; the process then stays alive on the server until a\n * `shutdown` / `detach` exits it.\n */\nexport interface BridgeHandle {\n /** The port the WebSocket server bound to. */\n readonly port: number;\n /** Close the WebSocket server. Does not call `process.exit`. */\n close(): Promise<void>;\n}\n\nexport async function runBridge<TStart extends { type: 'start' }>(\n options: RunBridgeOptions<TStart>,\n): Promise<BridgeHandle> {\n const { bridgeType, bridgeStateDir, onStart, onDetach } = options;\n const expectedToken = options.token ?? procEnv.BRIDGE_CHANNEL_TOKEN ?? '';\n const bridgeWsPort =\n options.port ?? parseInt(procEnv.BRIDGE_WS_PORT ?? '0', 10);\n\n const bridgeMetaPath = `${bridgeStateDir}/bridge-meta.json`;\n const startConfigPath = `${bridgeStateDir}/start-config.json`;\n const rerunStartConfigPath = `${bridgeStateDir}/rerun-start-config.json`;\n const eventLogPath = `${bridgeStateDir}/event-log.ndjson`;\n\n try {\n await mkdir(bridgeStateDir, { recursive: true });\n } catch {\n // Best-effort; the bridge still runs without its state files.\n }\n\n // ─── mutable runtime state ──────────────────────────────────────────\n let currentBoundPort = 0;\n let currentTurnState: BridgeState = 'init';\n let activeSocket: WebSocket | undefined;\n let isFirstTurn = true;\n let turnAbort: AbortController | undefined;\n let currentUserMessages: string[] | undefined;\n\n // Diagnostics. Resolved per turn from `start.debug` with a sandbox-side\n // env fallback; gates console capture + structured `debug-event`s.\n let debugConfig: BridgeDebugConfig | undefined;\n let consoleCaptureInstalled = false;\n const envDebugEnabled = ENV_TRUTHY.has(\n (procEnv.HARNESS_DEBUG ?? '').toLowerCase(),\n );\n\n // Replay log. `seq` is monotonic across the whole process — never reset —\n // because the host's `SandboxChannel` cursor (`lastSeenEventId`) lives across\n // turns. The log *contents* are cleared at the start of each turn to bound\n // memory; the just-finished turn stays replayable until the next `start`.\n let seqCounter = 0;\n let eventLog: Array<{ seq: number; line: string }> = [];\n\n /*\n * Disk mirror of the in-memory replay log. The in-memory log is lost when the\n * bridge process dies; the on-disk `event-log.ndjson` survives in the sandbox\n * filesystem so a respawned bridge (started with `BRIDGE_REPLAY_FROM_DISK=1`)\n * can reload the just-interrupted turn and serve a host's resume cursor —\n * `replay` recovery. Writes are batched on `setImmediate` (single-flight via\n * `flushPromise`) to keep `emit` off the disk hot path.\n */\n let diskBuffer = '';\n let flushPromise: Promise<void> | null = null;\n\n const flushEventsToDisk = async (): Promise<void> => {\n while (diskBuffer.length > 0) {\n const buf = diskBuffer;\n diskBuffer = '';\n await appendFile(eventLogPath, buf).catch(() => {\n // Best-effort crash-recovery mirror; the in-memory log is the source of\n // truth for the live connection.\n });\n }\n };\n\n const scheduleEventFlush = (): void => {\n if (flushPromise) return;\n flushPromise = new Promise<void>(resolve => {\n setImmediate(() => {\n void flushEventsToDisk().finally(resolve);\n });\n }).finally(() => {\n flushPromise = null;\n if (diskBuffer.length > 0) {\n scheduleEventFlush();\n }\n });\n };\n\n const flushPendingEventsToDisk = async (): Promise<void> => {\n if (diskBuffer.length > 0 && !flushPromise) {\n scheduleEventFlush();\n }\n // Await each in-flight flush, re-reading `flushPromise` after every await\n // since a fresh flush may have been scheduled for buffer that arrived while\n // we waited.\n let inFlight = flushPromise;\n while (inFlight) {\n await inFlight;\n inFlight = flushPromise;\n }\n };\n\n /*\n * When respawned for `replay`, reload the previous turn's log from disk before\n * accepting any connection so the very first `resume{lastSeenEventId}` can be\n * served the tail (including the terminal `finish`). The seq counter is\n * restored to the last persisted seq so it stays aligned with the host's\n * long-lived cursor. The file is NOT truncated in this mode — only a fresh\n * `start` (next turn) clears it.\n */\n const replayFromDisk = procEnv.BRIDGE_REPLAY_FROM_DISK === '1';\n if (replayFromDisk && existsSync(eventLogPath)) {\n try {\n const lines = readFileSync(eventLogPath, 'utf8')\n .split('\\n')\n .map(line => line.trim())\n .filter(Boolean);\n eventLog = lines.map(line => ({\n seq: (JSON.parse(line) as { seq: number }).seq,\n line,\n }));\n seqCounter = eventLog.at(-1)?.seq ?? 0;\n } catch {\n // Corrupt/partial log: fall back to an empty log; the host then degrades\n // to `rerun` instead of replaying a malformed tail.\n eventLog = [];\n seqCounter = 0;\n }\n }\n\n const pendingToolResults = new Map<\n string,\n (output: { output: unknown; isError?: boolean }) => void\n >();\n const pendingToolApprovals = new Map<\n string,\n (response: { approved: boolean; reason?: string }) => void\n >();\n\n // ─── persistence (best-effort meta + start config) ──────────────────\n const writeBridgeMeta = async (state: BridgeState): Promise<void> => {\n try {\n await writeFile(\n bridgeMetaPath,\n JSON.stringify({\n type: bridgeType,\n port: currentBoundPort,\n state,\n pid,\n }),\n );\n } catch {\n // Best-effort resilience metadata; not load-bearing for the active turn.\n }\n };\n\n const writeStartConfig = async (start: unknown): Promise<void> => {\n try {\n const serialized = JSON.stringify(start);\n await writeFile(startConfigPath, serialized);\n // Frozen copy: written once, restored over start-config.json by future\n // rerun-mode recovery to re-run the original turn from scratch.\n if (!existsSync(rerunStartConfigPath)) {\n await writeFile(rerunStartConfigPath, serialized);\n }\n } catch {\n // Best-effort.\n }\n };\n\n // ─── wire send + replay ─────────────────────────────────────────────\n const sendControl = (msg: Record<string, unknown>): void => {\n if (activeSocket?.readyState === WS_OPEN) {\n try {\n activeSocket.send(JSON.stringify(msg));\n } catch {\n // best-effort\n }\n }\n };\n\n const emit = (event: BridgeEvent): void => {\n const seq = ++seqCounter;\n const line = JSON.stringify({ ...event, seq });\n eventLog.push({ seq, line });\n diskBuffer += `${line}\\n`;\n scheduleEventFlush();\n if (activeSocket?.readyState === WS_OPEN) {\n try {\n activeSocket.send(line);\n } catch {\n // Send is best-effort: a dropped socket leaves the event in the log,\n // replayed once the host reconnects and sends `resume`.\n }\n }\n };\n\n const replay = (ws: WebSocket, afterSeq: number): void => {\n for (const entry of eventLog) {\n if (entry.seq > afterSeq && ws.readyState === WS_OPEN) {\n ws.send(entry.line);\n }\n }\n };\n\n // ─── diagnostics ──────────────────────────────────────────────\n const shouldEmitDebugEvent = (\n level: BridgeDebugLevel,\n subsystem: string,\n ): boolean => {\n if (!debugConfig?.enabled) return false;\n const threshold = debugConfig.level ?? 'debug';\n if (DEBUG_LEVEL_WEIGHT[level] > DEBUG_LEVEL_WEIGHT[threshold]) return false;\n return subsystemMatches(debugConfig.subsystems, subsystem);\n };\n\n /*\n * Forward sandbox console output. We line-buffer the original writers (kept so\n * output still reaches the real fds) and emit one `sandbox-log` per complete\n * line. `emit` never writes to stdout/stderr, so there is no recursion.\n * Installed lazily the first time a turn enables diagnostics; once installed,\n * capture is gated per-write on `debugConfig.enabled` so a later turn can\n * disable it. Console capture is independent of the subsystem/level filter.\n */\n const rawStdoutWrite = process.stdout.write.bind(process.stdout);\n const rawStderrWrite = process.stderr.write.bind(process.stderr);\n const installConsoleCapture = (): void => {\n if (consoleCaptureInstalled) return;\n consoleCaptureInstalled = true;\n const buffers: { stdout: string; stderr: string } = {\n stdout: '',\n stderr: '',\n };\n const patch =\n (stream: 'stdout' | 'stderr', raw: typeof process.stdout.write) =>\n (chunk: unknown, encoding?: unknown, cb?: unknown): boolean => {\n if (debugConfig?.enabled) {\n try {\n const enc = typeof encoding === 'string' ? encoding : 'utf8';\n const text =\n typeof chunk === 'string'\n ? chunk\n : Buffer.from(chunk as Uint8Array).toString(\n enc as BufferEncoding,\n );\n const combined = buffers[stream] + text.replace(/\\r\\n/g, '\\n');\n const parts = combined.split('\\n');\n buffers[stream] = parts.pop() ?? '';\n for (const line of parts) {\n const trimmed = line.replace(/\\s+$/, '');\n if (trimmed) {\n emit({\n type: 'sandbox-log',\n source: bridgeType,\n stream,\n line: trimmed,\n });\n }\n }\n } catch {\n // Never let capture break real output.\n }\n }\n return (raw as (c: unknown, e?: unknown, cb?: unknown) => boolean)(\n chunk,\n encoding,\n cb,\n );\n };\n process.stdout.write = patch(\n 'stdout',\n rawStdoutWrite,\n ) as typeof process.stdout.write;\n process.stderr.write = patch(\n 'stderr',\n rawStderrWrite,\n ) as typeof process.stderr.write;\n };\n\n // ─── inbound routing ────────────────────────────────────────────────\n const handleInbound = async (\n msg: TStart | InboundControl,\n ws: WebSocket,\n ): Promise<void> => {\n switch (msg.type) {\n case 'start': {\n const firstTurn = isFirstTurn;\n isFirstTurn = false;\n eventLog = []; // clear previous turn; keep seqCounter monotonic\n // Mirror the in-memory clear to disk: the log tracks only the current\n // turn. Discard any unflushed tail from the prior turn first.\n diskBuffer = '';\n void writeFile(eventLogPath, '').catch(() => {});\n turnAbort = new AbortController();\n currentTurnState = 'running';\n void writeStartConfig(msg);\n void writeBridgeMeta('running');\n const startDebug = (msg as { debug?: BridgeDebugConfig }).debug;\n debugConfig = {\n enabled: startDebug?.enabled ?? envDebugEnabled,\n level:\n startDebug?.level ??\n (procEnv.HARNESS_DEBUG_LEVEL as BridgeDebugLevel | undefined),\n subsystems:\n startDebug?.subsystems ??\n parseEnvList(procEnv.HARNESS_DEBUG_SUBSYSTEMS),\n };\n if (debugConfig.enabled) {\n installConsoleCapture();\n }\n const turn: BridgeTurn = {\n emit,\n requestToolResult: toolCallId =>\n new Promise(resolve => {\n pendingToolResults.set(toolCallId, resolve);\n }),\n requestToolApproval: approvalId =>\n new Promise(resolve => {\n pendingToolApprovals.set(approvalId, resolve);\n }),\n pendingUserMessages: [],\n abortSignal: turnAbort.signal,\n firstTurn,\n bridgeLog: input => {\n const level = input.level ?? 'debug';\n if (!shouldEmitDebugEvent(level, input.subsystem)) return;\n emit({\n type: 'debug-event',\n level,\n subsystem: input.subsystem,\n message: input.message,\n ...(input.attrs ? { attrs: input.attrs } : {}),\n ...(input.error !== undefined\n ? { error: formatBridgeError(input.error) }\n : {}),\n });\n },\n };\n currentUserMessages = turn.pendingUserMessages;\n try {\n await onStart(msg as TStart, turn);\n } catch (err) {\n emit({ type: 'error', error: serialiseError(err) });\n } finally {\n currentTurnState = 'waiting';\n void writeBridgeMeta('waiting');\n }\n return;\n }\n case 'tool-result': {\n const resolver = pendingToolResults.get(msg.toolCallId);\n if (resolver) {\n pendingToolResults.delete(msg.toolCallId);\n resolver({ output: msg.output, isError: msg.isError });\n }\n return;\n }\n case 'tool-approval-response': {\n const resolver = pendingToolApprovals.get(msg.approvalId);\n if (resolver) {\n pendingToolApprovals.delete(msg.approvalId);\n resolver({ approved: msg.approved, reason: msg.reason });\n }\n return;\n }\n case 'user-message':\n currentUserMessages?.push(msg.text);\n return;\n case 'abort':\n turnAbort?.abort();\n return;\n case 'resume':\n replay(ws, msg.lastSeenEventId);\n return;\n case 'shutdown':\n currentTurnState = 'done';\n void writeBridgeMeta('done');\n drainThenExit(ws, 1000, 'shutdown');\n return;\n case 'detach': {\n currentTurnState = 'done';\n void writeBridgeMeta('done');\n const data = (await onDetach?.()) ?? {};\n sendControl({ type: 'bridge-detach', data });\n drainThenExit(ws, 1000, 'detach');\n return;\n }\n }\n };\n\n // ─── server ─────────────────────────────────────────────────────────\n void writeBridgeMeta('init');\n\n const wss = new WebSocketServer({ port: bridgeWsPort, host: '0.0.0.0' });\n\n const exit = (): void => {\n if (options.onExit) {\n options.onExit();\n return;\n }\n wss.close(() => process.exit(0));\n setTimeout(() => process.exit(0), 1000).unref();\n };\n\n const drainThenExit = (ws: WebSocket, code: number, reason: string): void => {\n const start = Date.now();\n const tick = (): void => {\n const drained = ws.bufferedAmount === 0 || ws.readyState !== WS_OPEN;\n if (drained || Date.now() - start >= 5_000) {\n // Flush the on-disk log so a clean shutdown/detach leaves a complete\n // event-log.ndjson for any later replay recovery.\n void flushPendingEventsToDisk().finally(() => {\n try {\n ws.close(code, reason);\n } finally {\n exit();\n }\n });\n return;\n }\n setTimeout(tick, 10).unref();\n };\n tick();\n };\n\n wss.on('listening', () => {\n const addr = wss.address();\n currentBoundPort = typeof addr === 'object' && addr ? addr.port : 0;\n currentTurnState = 'waiting';\n void writeBridgeMeta('waiting');\n stdout.write(\n JSON.stringify({\n type: 'bridge-ready',\n port: currentBoundPort,\n }) + '\\n',\n );\n options.onListening?.(currentBoundPort);\n });\n\n wss.on('connection', (ws: WebSocket, req: { url?: string }) => {\n const url = new URL(req.url ?? '/', 'http://localhost');\n if (url.searchParams.get('agent_bridge_token') !== expectedToken) {\n ws.close(1008, 'unauthorized');\n return;\n }\n\n // Single-flight: a fresh authorized connection *replaces* the active one\n // (the host reconnecting after a drop). The previous socket's close is a\n // no-op below because it is no longer `activeSocket`.\n activeSocket = ws;\n\n // Announce liveness the instant we accept. Some sandbox runtimes complete\n // the host-side WS handshake before the connection is forwarded here; the\n // host waits for this frame before sending `start`/`resume`.\n sendControl({\n type: 'bridge-hello',\n state: currentTurnState,\n lastSeq: seqCounter,\n });\n\n ws.on('message', (raw: ArrayBufferLike | string) => {\n let parsed: TStart | InboundControl;\n try {\n const text =\n typeof raw === 'string' ? raw : Buffer.from(raw).toString('utf8');\n parsed = JSON.parse(text) as TStart | InboundControl;\n } catch (err) {\n sendControl({\n type: 'error',\n error: `protocol parse error: ${(err as Error).message}`,\n });\n return;\n }\n void handleInbound(parsed, ws);\n });\n\n ws.on('close', () => {\n // Only the *current* socket's close matters. A stale socket (already\n // replaced by a reconnect) closing is a no-op. Crucially we do NOT abort\n // the in-flight turn — it keeps running and its events accumulate in the\n // log for replay when the host reconnects.\n if (activeSocket === ws) {\n activeSocket = undefined;\n }\n });\n\n ws.on('error', () => {\n // 'close' follows; nothing to do beyond keeping the process alive.\n });\n });\n\n // Surface bridge-internal crashes to the host instead of dying silently.\n process.on('uncaughtException', err => {\n emit({ type: 'error', error: serialiseError(err) });\n });\n process.on('unhandledRejection', err => {\n emit({ type: 'error', error: serialiseError(err) });\n });\n\n await new Promise<void>((resolve, reject) => {\n if (wss.address() != null) {\n resolve();\n return;\n }\n\n wss.once('listening', resolve);\n wss.once('error', reject);\n });\n\n return {\n port: currentBoundPort,\n close: () =>\n new Promise<void>(resolve => {\n wss.close(() => resolve());\n }),\n };\n}\n\nfunction serialiseError(err: unknown): unknown {\n if (err instanceof Error) {\n return { name: err.name, message: err.message, stack: err.stack };\n }\n return err;\n}\n","import type { StartMessage } from '../deepagents-bridge-protocol';\n\nexport type PermissionMode = NonNullable<StartMessage['permissionMode']>;\n\n// Native built-in tool -> approval kind (mirrors the host adapter's toolUseKind).\nexport const NATIVE_TOOL_KIND: Readonly<\n Record<string, 'readonly' | 'edit' | 'bash'>\n> = {\n read_file: 'readonly',\n write_file: 'edit',\n edit_file: 'edit',\n execute: 'bash',\n grep: 'readonly',\n glob: 'readonly',\n ls: 'readonly',\n task: 'edit',\n write_todos: 'edit',\n};\n\nconst NATIVE_TO_COMMON: Readonly<Record<string, string>> = {\n read_file: 'read',\n write_file: 'write',\n edit_file: 'edit',\n execute: 'bash',\n};\n\nexport function toCommonName(nativeName: string): string {\n return NATIVE_TO_COMMON[nativeName] ?? nativeName;\n}\n\nexport function isBuiltinToolIncluded(input: {\n nativeName: string;\n toolFiltering: StartMessage['builtinToolFiltering'];\n}): boolean {\n if (input.toolFiltering == null) return true;\n const toolName = toCommonName(input.nativeName);\n return input.toolFiltering.mode === 'allow'\n ? input.toolFiltering.toolNames.includes(toolName)\n : !input.toolFiltering.toolNames.includes(toolName);\n}\n\nexport function builtinToolRequiresApproval(\n kind: 'readonly' | 'edit' | 'bash',\n permissionMode: PermissionMode,\n): boolean {\n if (permissionMode === 'allow-all') return false;\n if (permissionMode === 'allow-edits') return kind === 'bash';\n return kind === 'edit' || kind === 'bash';\n}\n\n// Per-tool HITL config for createDeepAgent; only built-ins are gated (host tools approve at the agent layer).\nexport function buildInterruptOn(\n permissionMode: PermissionMode | undefined,\n builtinToolFiltering: StartMessage['builtinToolFiltering'],\n):\n | Record<string, { allowedDecisions: Array<'approve' | 'reject'> }>\n | undefined {\n const config: Record<\n string,\n { allowedDecisions: Array<'approve' | 'reject'> }\n > = {};\n for (const [nativeName, kind] of Object.entries(NATIVE_TOOL_KIND)) {\n if (\n permissionMode != null &&\n isBuiltinToolIncluded({\n nativeName,\n toolFiltering: builtinToolFiltering,\n }) &&\n builtinToolRequiresApproval(kind, permissionMode)\n ) {\n config[nativeName] = { allowedDecisions: ['approve', 'reject'] };\n }\n }\n return Object.keys(config).length > 0 ? config : undefined;\n}\n\ntype ActionRequest = { name: string; args?: Record<string, unknown> };\ntype HITLInterruptValue = { actionRequests?: ActionRequest[] };\n\n// Flatten LangChain HITL interrupt payloads into the gated tool calls awaiting a decision.\nexport function collectActionRequests(\n interrupts: Array<{ value?: unknown }>,\n): { name: string; args: Record<string, unknown> }[] {\n const out: { name: string; args: Record<string, unknown> }[] = [];\n for (const interrupt of interrupts) {\n const value = interrupt.value as HITLInterruptValue | undefined;\n for (const action of value?.actionRequests ?? []) {\n out.push({ name: action.name, args: action.args ?? {} });\n }\n }\n return out;\n}\n","import { z } from 'zod/v4';\n\nexport type JsonSchemaObject = {\n type?: string | string[];\n description?: string;\n properties?: Record<string, JsonSchemaObject>;\n required?: string[];\n items?: JsonSchemaObject;\n nullable?: boolean;\n};\n\n// Convert a host tool's JSON Schema to a zod object for LangChain's `tool()`.\nexport function jsonSchemaToZodObject(input: unknown) {\n const schema =\n input && typeof input === 'object' ? (input as JsonSchemaObject) : {};\n return z.object(toZodShape(schema));\n}\n\nfunction toZodShape(schema: JsonSchemaObject): Record<string, z.ZodTypeAny> {\n if (!schema.properties) return {};\n const required = new Set(schema.required ?? []);\n const shape: Record<string, z.ZodTypeAny> = {};\n for (const [key, propSchema] of Object.entries(schema.properties)) {\n const propType = toZodType(propSchema);\n shape[key] = required.has(key) ? propType : propType.optional();\n }\n return shape;\n}\n\nfunction toZodType(schema: JsonSchemaObject | undefined): z.ZodTypeAny {\n if (!schema) return z.any();\n const types = Array.isArray(schema.type)\n ? schema.type.filter(t => t !== 'null')\n : ([schema.type].filter(Boolean) as string[]);\n let zType: z.ZodTypeAny;\n switch (types[0]) {\n case 'string':\n zType = z.string();\n break;\n case 'number':\n zType = z.number();\n break;\n case 'integer':\n zType = z.number().int();\n break;\n case 'boolean':\n zType = z.boolean();\n break;\n case 'array':\n zType = z.array(toZodType(schema.items));\n break;\n case 'object':\n zType = z.object(toZodShape(schema));\n break;\n case 'null':\n zType = z.null();\n break;\n default:\n zType = z.any();\n }\n if (schema.description) zType = zType.describe(schema.description);\n if (schema.nullable) zType = zType.nullable();\n return zType;\n}\n","import { LocalShellBackend } from 'deepagents';\n\nexport const SANDBOX_PATH_FALLBACK =\n '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin';\n\nexport function createLocalShellBackend({\n rootDir,\n env = process.env,\n}: {\n readonly rootDir: string;\n readonly env?: NodeJS.ProcessEnv;\n}): LocalShellBackend {\n return new LocalShellBackend({\n rootDir,\n env: {\n PATH: env.PATH ?? SANDBOX_PATH_FALLBACK,\n },\n });\n}\n","import {\n AIMessage,\n ToolMessage,\n type ToolCall,\n} from '@langchain/core/messages';\nimport type { createDeepAgent } from 'deepagents';\nimport type { StartMessage } from '../deepagents-bridge-protocol';\nimport {\n isBuiltinToolIncluded,\n NATIVE_TOOL_KIND,\n toCommonName,\n} from './approvals';\n\ntype DeepAgentsMiddleware = NonNullable<\n NonNullable<Parameters<typeof createDeepAgent>[0]>['middleware']\n>[number];\n\ntype DeepAgentsState = {\n messages: unknown[];\n};\n\ntype DeepAgentsMiddlewareUpdate = {\n messages: unknown[];\n jumpTo?: 'model';\n};\n\nconst MIDDLEWARE_BRAND = Symbol.for('AgentMiddleware');\n\nfunction getBuiltinToolFilteringDenialReason(input: {\n toolName: string;\n}): string {\n return `Tool '${input.toolName}' is inactive due to the HarnessAgent tool filtering policy.`;\n}\n\nfunction stringifyToolInput(input: unknown): string {\n return JSON.stringify(input ?? {});\n}\n\nfunction isNativeBuiltinToolCall(input: { toolCall: ToolCall }): boolean {\n return Object.keys(NATIVE_TOOL_KIND).includes(input.toolCall.name);\n}\n\nfunction isInactiveBuiltinToolCall(input: {\n toolCall: ToolCall;\n builtinToolFiltering: StartMessage['builtinToolFiltering'];\n}): boolean {\n return (\n isNativeBuiltinToolCall({ toolCall: input.toolCall }) &&\n !isBuiltinToolIncluded({\n nativeName: input.toolCall.name,\n toolFiltering: input.builtinToolFiltering,\n })\n );\n}\n\nexport function createBuiltinToolFilteringMiddleware(input: {\n builtinToolFiltering: StartMessage['builtinToolFiltering'];\n emit: (event: Record<string, unknown>) => void;\n}): DeepAgentsMiddleware | undefined {\n if (input.builtinToolFiltering == null) return undefined;\n\n return {\n [MIDDLEWARE_BRAND]: true,\n name: 'HarnessBuiltinToolFilteringMiddleware',\n afterModel: {\n canJumpTo: ['model'],\n hook: (\n state: DeepAgentsState,\n ): DeepAgentsMiddlewareUpdate | undefined => {\n const lastMessage = [...state.messages]\n .reverse()\n .find(message => AIMessage.isInstance(message));\n\n if (!lastMessage?.tool_calls?.length) return undefined;\n\n let hasActiveToolCalls = false;\n const deniedToolMessages: ToolMessage[] = [];\n\n for (const toolCall of lastMessage.tool_calls) {\n if (\n !isInactiveBuiltinToolCall({\n toolCall,\n builtinToolFiltering: input.builtinToolFiltering,\n })\n ) {\n hasActiveToolCalls = true;\n continue;\n }\n\n const nativeName = toolCall.name;\n toolCall.id ??= `${nativeName}-filtered-${deniedToolMessages.length}`;\n const toolName = toCommonName(nativeName);\n const reason = getBuiltinToolFilteringDenialReason({ toolName });\n\n input.emit({\n type: 'tool-call',\n toolCallId: toolCall.id,\n toolName,\n input: stringifyToolInput(toolCall.args),\n providerExecuted: true,\n nativeName,\n });\n input.emit({\n type: 'tool-result',\n toolCallId: toolCall.id,\n toolName,\n result: reason,\n });\n\n deniedToolMessages.push(\n new ToolMessage({\n content: reason,\n name: nativeName,\n tool_call_id: toolCall.id,\n status: 'error',\n }),\n );\n }\n\n if (deniedToolMessages.length === 0) return undefined;\n\n return {\n messages: [lastMessage, ...deniedToolMessages],\n ...(hasActiveToolCalls ? {} : { jumpTo: 'model' }),\n };\n },\n },\n } as DeepAgentsMiddleware;\n}\n"],"mappings":"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","names":["procEnv","bridgeStateDir","NATIVE_TO_COMMON","procEnv","toCommonName","turn"]}
package/dist/index.d.ts CHANGED
@@ -60,6 +60,8 @@ declare const DEEPAGENTS_BUILTIN_TOOLS: {
60
60
  };
61
61
  declare function createDeepAgents(settings?: DeepAgentsHarnessSettings): HarnessV1<typeof DEEPAGENTS_BUILTIN_TOOLS>;
62
62
 
63
+ declare const VERSION: string;
64
+
63
65
  /** Default `deepagents` harness instance; equivalent to `createDeepAgents()`. */
64
66
  declare const deepAgents: _ai_sdk_harness.HarnessV1<{
65
67
  readonly read: _ai_sdk_harness.HarnessV1BuiltinTool<{
@@ -95,4 +97,4 @@ declare const deepAgents: _ai_sdk_harness.HarnessV1<{
95
97
  }, any, any>;
96
98
  }>;
97
99
 
98
- export { type DeepAgentsAuthOptions, type DeepAgentsHarnessSettings, createDeepAgents, deepAgents };
100
+ export { type DeepAgentsAuthOptions, type DeepAgentsHarnessSettings, VERSION, createDeepAgents, deepAgents };
package/dist/index.js CHANGED
@@ -90,8 +90,12 @@ var inboundMessageSchema = z.discriminatedUnion("type", [
90
90
  ...harnessV1BridgeInboundCommandSchemas
91
91
  ]);
92
92
 
93
+ // src/version.ts
94
+ var VERSION = true ? "1.0.20" : "0.0.0-test";
95
+
93
96
  // src/deepagents-harness.ts
94
97
  var BOOTSTRAP_DIR = "/tmp/harness/deepagents";
98
+ var DEEPAGENTS_CLIENT_APP = `ai-sdk/harness-deepagents/${VERSION}`;
95
99
  var RIPGREP_VERSION = "14.1.1";
96
100
  var RIPGREP_SHA256_X64 = "4cf9f2741e6c465ffdb7c26f38056a59e2a2544b51f7cc128ef28337eeae4d8e";
97
101
  var RIPGREP_SHA256_ARM = "c827481c4ff4ea10c9dc7a4022c8de5db34a5737cb74484d62eb94a95841ab2f";
@@ -282,6 +286,7 @@ function createDeepAgents(settings = {}) {
282
286
  }
283
287
  const env = {
284
288
  ...resolveDeepAgentsEnv({ auth: settings.auth }),
289
+ AI_SDK_HARNESS_CLIENT_APP: DEEPAGENTS_CLIENT_APP,
285
290
  BRIDGE_CHANNEL_TOKEN: token,
286
291
  BRIDGE_WS_PORT: String(port)
287
292
  };
@@ -696,6 +701,7 @@ function extractUserText(prompt) {
696
701
  // src/index.ts
697
702
  var deepAgents = createDeepAgents();
698
703
  export {
704
+ VERSION,
699
705
  createDeepAgents,
700
706
  deepAgents
701
707
  };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/deepagents-harness.ts","../src/deepagents-auth.ts","../src/deepagents-bridge-protocol.ts","../src/index.ts"],"sourcesContent":["import { randomBytes } from 'node:crypto';\nimport { readFile } from 'node:fs/promises';\nimport { fileURLToPath } from 'node:url';\nimport {\n commonTool,\n HarnessCapabilityUnsupportedError,\n harnessV1DiagnosticFromBridgeFrame,\n type HarnessV1,\n type HarnessV1Bootstrap,\n type HarnessV1BuiltinTool,\n type HarnessV1BuiltinToolFiltering,\n type HarnessV1ContinueTurnState,\n type HarnessV1NetworkSandboxSession,\n type HarnessV1PermissionMode,\n type HarnessV1Prompt,\n type HarnessV1PromptControl,\n type HarnessV1ResumeSessionState,\n type HarnessV1Session,\n type HarnessV1Skill,\n type HarnessV1StreamPart,\n} from '@ai-sdk/harness';\nimport {\n markBridgeStarting,\n resolveSandboxHomeDir,\n SandboxChannel,\n shellQuote,\n waitForBridgeReady,\n writeSkills as writeHarnessSkills,\n} from '@ai-sdk/harness/utils';\nimport { tool, type Experimental_SandboxProcess } from '@ai-sdk/provider-utils';\nimport { WebSocket } from 'ws';\nimport { z } from 'zod/v4';\nimport {\n resolveDeepAgentsEnv,\n type DeepAgentsAuthOptions,\n} from './deepagents-auth';\nimport {\n outboundMessageSchema,\n type InboundMessage,\n type OutboundMessage,\n} from './deepagents-bridge-protocol';\n\ntype DeepAgentsChannel = SandboxChannel<OutboundMessage, InboundMessage>;\n\n// Pure derived state in /tmp; reinstalled per sandbox, persistence is the provider snapshot.\nconst BOOTSTRAP_DIR = '/tmp/harness/deepagents';\n\n// Pinned ripgrep release + per-arch tarball checksums (verified before install).\nconst RIPGREP_VERSION = '14.1.1';\nconst RIPGREP_SHA256_X64 =\n '4cf9f2741e6c465ffdb7c26f38056a59e2a2544b51f7cc128ef28337eeae4d8e';\nconst RIPGREP_SHA256_ARM =\n 'c827481c4ff4ea10c9dc7a4022c8de5db34a5737cb74484d62eb94a95841ab2f';\n\n// Idempotent, checksum-verified install of a static ripgrep binary into a PATH dir.\n// DeepAgents' grep shells out to `rg`; without it, its fallback reads the whole workdir (incl. node_modules) into memory and OOMs. Skipped if `rg` already exists.\nfunction installRipgrepCommand(): string {\n const v = RIPGREP_VERSION;\n return [\n 'command -v rg >/dev/null 2>&1 || {',\n 'case \"$(uname -m)\" in',\n `aarch64) a=aarch64-unknown-linux-gnu; sha=${RIPGREP_SHA256_ARM} ;;`,\n `*) a=x86_64-unknown-linux-musl; sha=${RIPGREP_SHA256_X64} ;;`,\n 'esac;',\n `f=/tmp/ripgrep-${v}.tar.gz;`,\n `curl -fsSL \"https://github.com/BurntSushi/ripgrep/releases/download/${v}/ripgrep-${v}-$a.tar.gz\" -o \"$f\"`,\n '&& echo \"$sha $f\" | sha256sum -c -',\n '&& tar xzf \"$f\" -C /tmp',\n `&& mv \"/tmp/ripgrep-${v}-$a/rg\" /usr/local/bin/rg && chmod +x /usr/local/bin/rg;`,\n '}',\n ].join(' ');\n}\n\n// Skills source subpath, written under $HOME (out of the work dir so it can't clash with code cloned into the work dir) and also discovered from <workDir> for repo-provided skills.\nconst SKILLS_SOURCE_PATH = '/.agents/skills';\n\nexport type DeepAgentsHarnessSettings = {\n readonly auth?: DeepAgentsAuthOptions;\n /** Model id for the DeepAgents runtime, e.g. `claude-sonnet-4` (converted to `provider:model`). */\n readonly model?: string;\n /** Bridge port override; defaults to the sandbox's first declared port. */\n readonly port?: number;\n /** Maximum milliseconds to wait for the bridge to advertise its port. Defaults to 120000. */\n readonly startupTimeoutMs?: number;\n /** Max LangGraph super-steps per turn before it errors. Defaults to 100; raise for long multi-step tasks. */\n readonly recursionLimit?: number;\n};\n\n// Every model-callable DeepAgents built-in, keyed by what the bridge emits (commonName ?? nativeName); all must be listed or AI SDK throws AI_NoSuchToolError.\nconst DEEPAGENTS_BUILTIN_TOOLS = {\n read: commonTool('read', {\n nativeName: 'read_file',\n toolUseKind: 'readonly',\n description: 'Read file contents',\n inputSchema: z.object({ file_path: z.string() }),\n }),\n write: commonTool('write', {\n nativeName: 'write_file',\n toolUseKind: 'edit',\n description: 'Create a file',\n inputSchema: z.object({ file_path: z.string(), content: z.string() }),\n }),\n edit: commonTool('edit', {\n nativeName: 'edit_file',\n toolUseKind: 'edit',\n description: 'Perform exact string replacements in a file',\n inputSchema: z.object({\n file_path: z.string(),\n old_string: z.string(),\n new_string: z.string(),\n }),\n }),\n bash: commonTool('bash', {\n nativeName: 'execute',\n toolUseKind: 'bash',\n description: 'Run a shell command',\n inputSchema: z.object({ command: z.string() }),\n }),\n grep: commonTool('grep', {\n nativeName: 'grep',\n toolUseKind: 'readonly',\n description: 'Search file contents',\n inputSchema: z.object({ pattern: z.string() }),\n }),\n glob: commonTool('glob', {\n nativeName: 'glob',\n toolUseKind: 'readonly',\n description: 'Find files matching a glob pattern',\n inputSchema: z.object({ pattern: z.string() }),\n }),\n // No common-name equivalent — keyed by native name.\n ls: tool({\n description: 'List files in a directory',\n inputSchema: z.object({ path: z.string().optional() }),\n }),\n task: tool({\n description: 'Spawn a subagent to handle a delegated task',\n inputSchema: z.object({\n description: z.string().optional(),\n subagent_type: z.string().optional(),\n }),\n }),\n write_todos: tool({\n description: 'Manage a structured todo list',\n inputSchema: z.object({ todos: z.array(z.unknown()).optional() }),\n }),\n} as const satisfies Record<string, HarnessV1BuiltinTool<any, any>>;\n\n// Live bridge coordinates returned by doDetach/doSuspendTurn so a later process can reattach.\nconst deepAgentsBridgeCoordsSchema = z.object({\n port: z.number(),\n token: z.string(),\n lastSeenEventId: z.number(),\n sandboxId: z.string().optional(),\n});\nconst deepAgentsResumeStateSchema = z.object({\n bridge: deepAgentsBridgeCoordsSchema.optional(),\n});\ntype DeepAgentsBridgeCoords = z.infer<typeof deepAgentsBridgeCoordsSchema>;\n\nexport function createDeepAgents(\n settings: DeepAgentsHarnessSettings = {},\n): HarnessV1<typeof DEEPAGENTS_BUILTIN_TOOLS> {\n let cachedBootstrap: HarnessV1Bootstrap | undefined;\n\n return {\n specificationVersion: 'harness-v1',\n harnessId: 'deepagents',\n builtinTools: DEEPAGENTS_BUILTIN_TOOLS,\n // Built-in tool approvals are gated in-bridge via DeepAgents' interruptOn (HITL) middleware.\n supportsBuiltinToolApprovals: true,\n lifecycleStateSchema: deepAgentsResumeStateSchema,\n getBootstrap: async () => {\n if (cachedBootstrap != null) return cachedBootstrap;\n const [bridge, pkg, lock] = await Promise.all([\n readBridgeAsset('index.mjs'),\n readBridgeAsset('package.json'),\n readBridgeAsset('pnpm-lock.yaml'),\n ]);\n cachedBootstrap = {\n harnessId: 'deepagents',\n bootstrapDir: BOOTSTRAP_DIR,\n files: [\n { path: `${BOOTSTRAP_DIR}/bridge.mjs`, content: bridge },\n { path: `${BOOTSTRAP_DIR}/package.json`, content: pkg },\n { path: `${BOOTSTRAP_DIR}/pnpm-lock.yaml`, content: lock },\n ],\n commands: [\n { command: `mkdir -p ${BOOTSTRAP_DIR}` },\n { command: installRipgrepCommand() },\n {\n command: `pnpm --dir ${BOOTSTRAP_DIR} install --frozen-lockfile --store-dir ${BOOTSTRAP_DIR}/.pnpm-store`,\n },\n ],\n };\n return cachedBootstrap;\n },\n doStart: async startOpts => {\n const permissionMode = startOpts.permissionMode;\n const sandboxSession = startOpts.sandboxSession;\n const session = sandboxSession.restricted();\n const sandboxId = sandboxSession.id;\n\n const lifecycleState = startOpts.continueFrom ?? startOpts.resumeFrom;\n const isResume = lifecycleState != null;\n const isContinue = startOpts.continueFrom != null;\n const coords =\n isResume && typeof lifecycleState?.data === 'object'\n ? (lifecycleState.data as { bridge?: DeepAgentsBridgeCoords }).bridge\n : undefined;\n\n const workDir = startOpts.sessionWorkDir;\n const sessionDataDir = `${sandboxSession.defaultWorkingDirectory}/.agent-runs/${startOpts.sessionId}`;\n const bridgeStateDir = `${sessionDataDir}/bridge`;\n const timeoutMs = settings.startupTimeoutMs ?? 120_000;\n\n const report = startOpts.observability?.report;\n const onDiagnostic = report\n ? (frame: Parameters<typeof harnessV1DiagnosticFromBridgeFrame>[0]) =>\n report(\n harnessV1DiagnosticFromBridgeFrame(frame, {\n sessionId: startOpts.sessionId,\n timestamp: Date.now(),\n }),\n )\n : undefined;\n\n // Attach to the still-running bridge (continueFrom replays past the cursor); on failure fall through to a fresh spawn.\n if (coords) {\n try {\n const attachUrl =\n (await sandboxSession.getPortUrl({\n port: coords.port,\n protocol: 'ws',\n })) + `?agent_bridge_token=${encodeURIComponent(coords.token)}`;\n const attachChannel: DeepAgentsChannel = new SandboxChannel({\n connect: () => openWebSocket(attachUrl),\n outboundSchema: outboundMessageSchema,\n initialLastSeenEventId: coords.lastSeenEventId,\n onDiagnostic,\n });\n await attachChannel.open(isContinue ? { resume: true } : undefined);\n return createSession({\n sessionId: startOpts.sessionId,\n channel: attachChannel,\n proc: undefined,\n model: settings.model,\n bridgePort: coords.port,\n bridgeToken: coords.token,\n sandboxId,\n isResume: true,\n attached: true,\n permissionMode,\n builtinToolFiltering: startOpts.builtinToolFiltering,\n recursionLimit: settings.recursionLimit,\n });\n } catch {\n // Bridge no longer reachable — recover by respawning below.\n }\n }\n\n const port = resolveBridgePort(sandboxSession, settings.port);\n const token = randomBytes(32).toString('hex');\n\n // Always discover repo-provided skills under <workDir>/.agents/skills (e.g. a cloned repo); a missing dir is tolerated by deepagents.\n // Absolute paths: LocalShellBackend (non-virtual) treats a leading-slash path as a real fs path.\n const skillsPaths = [`${workDir}${SKILLS_SOURCE_PATH}`];\n // Host-provided skills go to $HOME (out of the work dir) and take priority (listed last → wins on name collision).\n if ((startOpts.skills?.length ?? 0) > 0) {\n const homeDir = await resolveSandboxHomeDir({\n sandbox: session,\n abortSignal: startOpts.abortSignal,\n });\n const homeSkillsRoot = `${homeDir}${SKILLS_SOURCE_PATH}`;\n await writeSkills({\n sandbox: session,\n root: homeSkillsRoot,\n skills: startOpts.skills ?? [],\n abortSignal: startOpts.abortSignal,\n });\n skillsPaths.push(homeSkillsRoot);\n }\n\n const env = {\n ...resolveDeepAgentsEnv({ auth: settings.auth }),\n BRIDGE_CHANNEL_TOKEN: token,\n BRIDGE_WS_PORT: String(port),\n };\n\n await session.run({\n command: `mkdir -p ${shellQuote(workDir)} ${shellQuote(bridgeStateDir)}`,\n abortSignal: startOpts.abortSignal,\n });\n\n await markBridgeStarting({\n sandbox: session,\n bridgeStateDir,\n bridgeType: 'deepagents',\n abortSignal: startOpts.abortSignal,\n });\n\n const proc = await session.spawn({\n command: `node ${BOOTSTRAP_DIR}/bridge.mjs --workdir ${shellQuote(workDir)} --bridge-state-dir ${shellQuote(bridgeStateDir)} --bootstrap-dir ${shellQuote(BOOTSTRAP_DIR)}`,\n env,\n abortSignal: startOpts.abortSignal,\n });\n\n const { port: boundPort } = await waitForBridgeReady({\n proc,\n sandbox: session,\n bridgeStateDir,\n bridgeType: 'deepagents',\n timeoutMs,\n abortSignal: startOpts.abortSignal,\n createTimeoutError: () =>\n new Error('deepagents bridge did not become ready in time.'),\n createExitError: () =>\n new Error('deepagents bridge exited before becoming ready.'),\n });\n void forwardBridgeStderr(proc.stderr);\n\n const wsUrl =\n (await sandboxSession.getPortUrl({\n port: boundPort,\n protocol: 'ws',\n })) + `?agent_bridge_token=${encodeURIComponent(token)}`;\n\n const channel: DeepAgentsChannel = new SandboxChannel({\n connect: () => openWebSocket(wsUrl),\n outboundSchema: outboundMessageSchema,\n onDiagnostic,\n });\n await channel.open();\n\n return createSession({\n sessionId: startOpts.sessionId,\n channel,\n proc,\n model: settings.model,\n bridgePort: boundPort,\n bridgeToken: token,\n sandboxId,\n isResume,\n // Freshly spawned bridge — it must receive the instructions on the first prompt.\n attached: false,\n skillsPaths,\n permissionMode,\n builtinToolFiltering: startOpts.builtinToolFiltering,\n recursionLimit: settings.recursionLimit,\n });\n },\n };\n}\n\nfunction resolveBridgePort(\n sandboxSession: HarnessV1NetworkSandboxSession,\n override: number | undefined,\n): number {\n if (override !== undefined) return override;\n if (sandboxSession.ports.length > 0) return sandboxSession.ports[0];\n throw new HarnessCapabilityUnsupportedError({\n harnessId: 'deepagents',\n message:\n 'The deepagents harness needs a TCP port exposed by the sandbox. ' +\n 'Create the sandbox with `ports: [<port>]` or pass `createDeepAgents({ port })`.',\n });\n}\n\nasync function readBridgeAsset(name: string): Promise<string> {\n const candidates = [\n new URL(`./bridge/${name}`, import.meta.url),\n new URL(`../bridge/${name}`, import.meta.url),\n ];\n let lastErr: unknown;\n for (const url of candidates) {\n try {\n return await readFile(fileURLToPath(url), 'utf8');\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code !== 'ENOENT') throw err;\n lastErr = err;\n }\n }\n throw lastErr ?? new Error(`bridge asset not found: ${name}`);\n}\n\n// Materialize each skill as a native deepagents `<name>/SKILL.md` folder (+ attached files) under the given root, so skills load on demand and file references resolve.\nasync function writeSkills({\n sandbox,\n root,\n skills,\n abortSignal,\n}: {\n sandbox: ReturnType<HarnessV1NetworkSandboxSession['restricted']>;\n root: string;\n skills: ReadonlyArray<HarnessV1Skill>;\n abortSignal?: AbortSignal;\n}): Promise<void> {\n /*\n * DeepAgents requires each `SKILL.md` frontmatter name to match the parent\n * directory name, so keep the stricter lowercase skill-name policy here.\n */\n await writeHarnessSkills({\n sandbox,\n rootDir: root,\n skills,\n abortSignal,\n skillNamePattern: /^[a-z0-9]([a-z0-9-]{0,62}[a-z0-9])?$/,\n invalidSkillNameMessage: ({ name }) =>\n `Invalid deepagents skill name '${name}': must be lowercase alphanumeric with hyphens, 1-64 chars.`,\n filePathMode: 'strip-leading-slashes',\n invalidSkillFilePathMessage: ({ skillName, filePath }) =>\n `Invalid skill file path for '${skillName}': ${filePath}`,\n });\n}\n\nfunction openWebSocket(url: string): Promise<WebSocket> {\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(url);\n const onOpen = () => {\n ws.off('error', onError);\n resolve(ws);\n };\n const onError = (err: Error) => {\n ws.off('open', onOpen);\n reject(err);\n };\n ws.once('open', onOpen);\n ws.once('error', onError);\n });\n}\n\nasync function forwardBridgeStderr(\n stream: ReadableStream<Uint8Array>,\n): Promise<void> {\n try {\n const reader = stream.pipeThrough(new TextDecoderStream()).getReader();\n while (true) {\n const { value, done } = await reader.read();\n if (done) return;\n if (value) {\n const trimmed = value.endsWith('\\n') ? value.slice(0, -1) : value;\n if (trimmed.length > 0) {\n // eslint-disable-next-line no-console\n console.log(`[bridge stderr] ${trimmed}`);\n }\n }\n }\n } catch {\n // Reader errors are non-fatal — best-effort diagnostic only.\n }\n}\n\nfunction createSession({\n sessionId,\n channel,\n proc,\n model,\n bridgePort,\n bridgeToken,\n sandboxId,\n isResume,\n attached,\n skillsPaths,\n permissionMode,\n builtinToolFiltering,\n recursionLimit,\n}: {\n sessionId: string;\n channel: DeepAgentsChannel;\n // Undefined on attach — the live bridge was spawned by another process.\n proc: Experimental_SandboxProcess | undefined;\n model: string | undefined;\n bridgePort: number;\n bridgeToken: string;\n sandboxId: string;\n isResume: boolean;\n // True only when attaching to a live bridge that already built the agent with\n // its instructions. A fresh spawn (incl. a respawn on attach failure or a\n // stop-resume) starts a new bridge that must receive the instructions again.\n attached: boolean;\n skillsPaths?: string[];\n permissionMode?: HarnessV1PermissionMode;\n builtinToolFiltering?: HarnessV1BuiltinToolFiltering;\n recursionLimit?: number;\n}): HarnessV1Session {\n let stopped = false;\n let instructionsApplied = attached;\n\n const wireTurn = (turnOpts: {\n emit: (event: HarnessV1StreamPart) => void;\n abortSignal?: AbortSignal;\n }): HarnessV1PromptControl => {\n let pendingResolve: (() => void) | undefined;\n let pendingReject: ((err: unknown) => void) | undefined;\n const done = new Promise<void>((resolve, reject) => {\n pendingResolve = resolve;\n pendingReject = reject;\n });\n\n const unsubs: Array<() => void> = [];\n const forward = (event: HarnessV1StreamPart) => {\n try {\n turnOpts.emit(event);\n } catch {}\n };\n\n const eventTypes = [\n 'stream-start',\n 'text-start',\n 'text-delta',\n 'text-end',\n 'reasoning-start',\n 'reasoning-delta',\n 'reasoning-end',\n 'tool-call',\n 'tool-approval-request',\n 'tool-result',\n 'file-change',\n 'finish-step',\n 'raw',\n ] as const;\n let isSettled = false;\n const settleSuccess = () => {\n if (isSettled) return;\n isSettled = true;\n for (const u of unsubs) u();\n pendingResolve!();\n };\n const settleError = (err: unknown) => {\n if (isSettled) return;\n isSettled = true;\n for (const u of unsubs) u();\n pendingReject!(err);\n };\n\n for (const type of eventTypes) {\n unsubs.push(channel.on(type, msg => forward(msg)));\n }\n unsubs.push(\n channel.on('finish', msg => {\n forward(msg);\n settleSuccess();\n }),\n );\n unsubs.push(\n channel.on('error', msg => {\n forward(msg);\n settleError(msg.error);\n }),\n );\n\n // A `'suspended'` close is a graceful slice-boundary freeze (suspend/detach keep the bridge alive for continuation); end the turn cleanly. Any other close is an unexpected bridge failure.\n const onClose = (_code: number, reason: string) => {\n if (isSettled) return;\n if (reason === 'suspended') {\n settleSuccess();\n return;\n }\n settleError(\n new Error('deepagents bridge closed before the turn finished.'),\n );\n };\n channel.onClose(onClose);\n\n const onAbort = () => {\n if (isSettled) return;\n try {\n channel.send({ type: 'abort' });\n } catch {}\n settleError(\n turnOpts.abortSignal?.reason ??\n new DOMException('Aborted', 'AbortError'),\n );\n };\n if (turnOpts.abortSignal) {\n if (turnOpts.abortSignal.aborted) {\n onAbort();\n } else {\n turnOpts.abortSignal.addEventListener('abort', onAbort, { once: true });\n }\n }\n\n return {\n submitToolResult: async input => {\n channel.send({\n type: 'tool-result',\n toolCallId: input.toolCallId,\n output: input.output,\n isError: input.isError,\n });\n },\n submitUserMessage: async text => {\n channel.send({ type: 'user-message', text });\n },\n submitToolApproval: async input => {\n channel.send({\n type: 'tool-approval-response',\n approvalId: input.approvalId,\n approved: input.approved,\n ...(input.reason != null ? { reason: input.reason } : {}),\n });\n },\n done,\n };\n };\n\n const unsupported = (capability: string): never => {\n throw new HarnessCapabilityUnsupportedError({\n harnessId: 'deepagents',\n message: `Harness 'deepagents' does not support ${capability} yet.`,\n });\n };\n\n return {\n sessionId,\n isResume,\n modelId: model,\n doPromptTurn: async promptOpts => {\n const control = wireTurn({\n emit: promptOpts.emit,\n abortSignal: promptOpts.abortSignal,\n });\n\n const applyInstructions =\n !instructionsApplied && !!promptOpts.instructions;\n instructionsApplied = true;\n\n channel.send({\n type: 'start',\n prompt: extractUserText(promptOpts.prompt),\n ...(applyInstructions ? { instructions: promptOpts.instructions } : {}),\n tools: (promptOpts.tools ?? []).map(t => ({\n name: t.name,\n description: t.description,\n inputSchema: t.inputSchema,\n })),\n ...(model ? { model } : {}),\n ...(skillsPaths?.length ? { skillsPaths } : {}),\n ...(permissionMode ? { permissionMode } : {}),\n ...(builtinToolFiltering ? { builtinToolFiltering } : {}),\n ...(recursionLimit != null ? { recursionLimit } : {}),\n });\n\n return control;\n },\n doContinueTurn: async continueOpts => {\n // Attach/replay: doStart opened with `{ resume: true }` so the bridge replays past the cursor; no `start` is sent (that would clear the replay log).\n return wireTurn({\n emit: continueOpts.emit,\n abortSignal: continueOpts.abortSignal,\n });\n },\n doSuspendTurn: async () => {\n if (stopped) {\n throw new Error(\n `deepagents session ${sessionId} is stopped; cannot suspend.`,\n );\n }\n stopped = true;\n // Freeze the active turn at the cursor, leaving the bridge running so the next slice replays the tail.\n const lastSeenEventId = await channel.suspend();\n const payload: HarnessV1ContinueTurnState = {\n type: 'continue-turn',\n harnessId: 'deepagents',\n specificationVersion: 'harness-v1',\n data: {\n bridge: {\n port: bridgePort,\n token: bridgeToken,\n lastSeenEventId,\n sandboxId,\n },\n },\n };\n return payload;\n },\n doDetach: async () => {\n if (stopped) {\n throw new Error(\n `deepagents session ${sessionId} is already stopped; cannot detach.`,\n );\n }\n stopped = true;\n // Park between turns: close the host socket but leave the bridge running for a later reattach via these coords.\n const lastSeenEventId = await channel.suspend();\n const payload: HarnessV1ResumeSessionState = {\n type: 'resume-session',\n harnessId: 'deepagents',\n specificationVersion: 'harness-v1',\n data: {\n bridge: {\n port: bridgePort,\n token: bridgeToken,\n lastSeenEventId,\n sandboxId,\n },\n },\n };\n return payload;\n },\n doCompact: async () => unsupported('manual compaction'),\n doStop: async () => {\n if (stopped) {\n throw new Error(\n `deepagents session ${sessionId} is already stopped; cannot stop.`,\n );\n }\n stopped = true;\n await teardown(channel, proc);\n // In-memory conversation is lost on teardown; the sandbox snapshot preserves the workspace files, not the conversation.\n const payload: HarnessV1ResumeSessionState = {\n type: 'resume-session',\n harnessId: 'deepagents',\n specificationVersion: 'harness-v1',\n data: {},\n };\n return payload;\n },\n doDestroy: async () => {\n if (stopped) return;\n stopped = true;\n await teardown(channel, proc);\n },\n };\n}\n\nasync function teardown(\n channel: DeepAgentsChannel,\n proc: Experimental_SandboxProcess | undefined,\n): Promise<void> {\n channel.beginClose();\n try {\n if (!channel.isClosed()) {\n channel.send({ type: 'shutdown' });\n }\n } catch {}\n let stopTimer: ReturnType<typeof setTimeout> | undefined;\n try {\n if (proc) {\n await Promise.race([\n proc.wait(),\n new Promise<void>(resolve => {\n stopTimer = setTimeout(resolve, 5000);\n stopTimer.unref?.();\n }),\n ]);\n }\n } finally {\n if (stopTimer) clearTimeout(stopTimer);\n try {\n await proc?.kill();\n } catch {}\n channel.close();\n }\n}\n\n// Reduce the prompt to plain user text; non-text parts are unsupported.\nfunction extractUserText(prompt: HarnessV1Prompt): string {\n if (typeof prompt === 'string') return prompt;\n const { content } = prompt;\n if (typeof content === 'string') return content;\n const parts: string[] = [];\n for (const part of content) {\n if (part.type !== 'text') {\n throw new HarnessCapabilityUnsupportedError({\n harnessId: 'deepagents',\n message: `The deepagents harness does not yet support user message parts of type '${part.type}'. Pass a string or a user message whose content contains only text parts.`,\n });\n }\n parts.push(part.text);\n }\n return parts.join('\\n\\n');\n}\n","import { getAiGatewayAuthFromEnv } from '@ai-sdk/harness/utils';\n\nexport type DeepAgentsAuthOptions = {\n readonly anthropic?: {\n readonly apiKey?: string;\n readonly authToken?: string;\n readonly baseUrl?: string;\n };\n readonly gateway?: {\n readonly apiKey?: string;\n readonly baseUrl?: string;\n };\n};\n\n// DeepAgents always drives the Anthropic client. Non-Anthropic models reach it\n// through AI Gateway's Anthropic-compatible endpoint, which translates to any\n// model (Gemini, OpenAI, etc.), tool calls included.\nexport function resolveDeepAgentsEnv({\n auth,\n processEnv = process.env,\n}: {\n auth?: DeepAgentsAuthOptions;\n processEnv?: Record<string, string | undefined>;\n}): Record<string, string> {\n if (auth?.anthropic) {\n return pickAnthropic({ explicit: auth.anthropic, processEnv });\n }\n\n const gatewayAuthFromEnv = getAiGatewayAuthFromEnv({ env: processEnv });\n if (auth?.gateway) {\n return pickGateway({ explicit: auth.gateway, gatewayAuthFromEnv });\n }\n if (gatewayAuthFromEnv.apiKey) {\n return pickGateway({ explicit: {}, gatewayAuthFromEnv });\n }\n\n return pickAnthropic({ processEnv });\n}\n\nfunction pickAnthropic({\n explicit,\n processEnv,\n}: {\n explicit?: NonNullable<DeepAgentsAuthOptions['anthropic']>;\n processEnv: Record<string, string | undefined>;\n}): Record<string, string> {\n const env: Record<string, string> = {};\n const apiKey = explicit?.apiKey ?? processEnv.ANTHROPIC_API_KEY;\n if (apiKey) env.ANTHROPIC_API_KEY = apiKey;\n const authToken = explicit?.authToken ?? processEnv.ANTHROPIC_AUTH_TOKEN;\n if (authToken) env.ANTHROPIC_AUTH_TOKEN = authToken;\n const baseUrl = explicit?.baseUrl ?? processEnv.ANTHROPIC_BASE_URL;\n if (baseUrl) env.ANTHROPIC_BASE_URL = baseUrl;\n return env;\n}\n\nfunction pickGateway({\n explicit,\n gatewayAuthFromEnv,\n}: {\n explicit: NonNullable<DeepAgentsAuthOptions['gateway']>;\n gatewayAuthFromEnv: ReturnType<typeof getAiGatewayAuthFromEnv>;\n}): Record<string, string> {\n const apiKey = explicit.apiKey ?? gatewayAuthFromEnv.apiKey;\n // The Anthropic SDK appends `/v1/messages`, so the gateway base stays at its root.\n const baseUrl = (explicit.baseUrl ?? gatewayAuthFromEnv.baseUrl).replace(\n /\\/+$/,\n '',\n );\n const env: Record<string, string> = {};\n if (apiKey) {\n env.AI_GATEWAY_API_KEY = apiKey;\n env.ANTHROPIC_API_KEY = apiKey;\n }\n env.ANTHROPIC_BASE_URL = baseUrl;\n return env;\n}\n","import {\n harnessV1BridgeInboundCommandSchemas,\n harnessV1BridgeOutboundMessageSchema,\n harnessV1BridgeReadySchema,\n harnessV1BridgeStartBaseSchema,\n} from '@ai-sdk/harness';\nimport { z } from 'zod/v4';\n\n// Deep Agents bridge wire protocol; only the `start` payload is adapter-specific.\nexport const outboundMessageSchema = harnessV1BridgeOutboundMessageSchema;\nexport type OutboundMessage = z.infer<typeof outboundMessageSchema>;\n\nexport const startMessageSchema = harnessV1BridgeStartBaseSchema.extend({\n // Prepended to the first user message (createDeepAgent takes no instructions param).\n instructions: z.string().optional(),\n // In-backend skills source dirs ($HOME and <workDir>), passed to createDeepAgent({ skills }).\n skillsPaths: z.array(z.string()).optional(),\n // Max LangGraph super-steps per turn (streamEvents recursionLimit).\n recursionLimit: z.number().optional(),\n});\n\nexport type StartMessage = z.infer<typeof startMessageSchema>;\n\nexport const inboundMessageSchema = z.discriminatedUnion('type', [\n startMessageSchema,\n ...harnessV1BridgeInboundCommandSchemas,\n]);\nexport type InboundMessage = z.infer<typeof inboundMessageSchema>;\n\nexport const bridgeReadySchema = harnessV1BridgeReadySchema;\nexport type BridgeReady = z.infer<typeof bridgeReadySchema>;\n","import { createDeepAgents } from './deepagents-harness';\n\n/** Default `deepagents` harness instance; equivalent to `createDeepAgents()`. */\nexport const deepAgents = createDeepAgents();\n\nexport { createDeepAgents } from './deepagents-harness';\nexport type { DeepAgentsHarnessSettings } from './deepagents-harness';\nexport type { DeepAgentsAuthOptions } from './deepagents-auth';\n"],"mappings":"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","names":["z","z"]}
1
+ {"version":3,"sources":["../src/deepagents-harness.ts","../src/deepagents-auth.ts","../src/deepagents-bridge-protocol.ts","../src/version.ts","../src/index.ts"],"sourcesContent":["import { randomBytes } from 'node:crypto';\nimport { readFile } from 'node:fs/promises';\nimport { fileURLToPath } from 'node:url';\nimport {\n commonTool,\n HarnessCapabilityUnsupportedError,\n harnessV1DiagnosticFromBridgeFrame,\n type HarnessV1,\n type HarnessV1Bootstrap,\n type HarnessV1BuiltinTool,\n type HarnessV1BuiltinToolFiltering,\n type HarnessV1ContinueTurnState,\n type HarnessV1NetworkSandboxSession,\n type HarnessV1PermissionMode,\n type HarnessV1Prompt,\n type HarnessV1PromptControl,\n type HarnessV1ResumeSessionState,\n type HarnessV1Session,\n type HarnessV1Skill,\n type HarnessV1StreamPart,\n} from '@ai-sdk/harness';\nimport {\n markBridgeStarting,\n resolveSandboxHomeDir,\n SandboxChannel,\n shellQuote,\n waitForBridgeReady,\n writeSkills as writeHarnessSkills,\n} from '@ai-sdk/harness/utils';\nimport { tool, type Experimental_SandboxProcess } from '@ai-sdk/provider-utils';\nimport { WebSocket } from 'ws';\nimport { z } from 'zod/v4';\nimport {\n resolveDeepAgentsEnv,\n type DeepAgentsAuthOptions,\n} from './deepagents-auth';\nimport {\n outboundMessageSchema,\n type InboundMessage,\n type OutboundMessage,\n} from './deepagents-bridge-protocol';\nimport { VERSION } from './version';\n\ntype DeepAgentsChannel = SandboxChannel<OutboundMessage, InboundMessage>;\n\n// Pure derived state in /tmp; reinstalled per sandbox, persistence is the provider snapshot.\nconst BOOTSTRAP_DIR = '/tmp/harness/deepagents';\n/**\n * Value to use in User-Agent and `x-client-app` headers.\n */\nconst DEEPAGENTS_CLIENT_APP = `ai-sdk/harness-deepagents/${VERSION}`;\n\n// Pinned ripgrep release + per-arch tarball checksums (verified before install).\nconst RIPGREP_VERSION = '14.1.1';\nconst RIPGREP_SHA256_X64 =\n '4cf9f2741e6c465ffdb7c26f38056a59e2a2544b51f7cc128ef28337eeae4d8e';\nconst RIPGREP_SHA256_ARM =\n 'c827481c4ff4ea10c9dc7a4022c8de5db34a5737cb74484d62eb94a95841ab2f';\n\n// Idempotent, checksum-verified install of a static ripgrep binary into a PATH dir.\n// DeepAgents' grep shells out to `rg`; without it, its fallback reads the whole workdir (incl. node_modules) into memory and OOMs. Skipped if `rg` already exists.\nfunction installRipgrepCommand(): string {\n const v = RIPGREP_VERSION;\n return [\n 'command -v rg >/dev/null 2>&1 || {',\n 'case \"$(uname -m)\" in',\n `aarch64) a=aarch64-unknown-linux-gnu; sha=${RIPGREP_SHA256_ARM} ;;`,\n `*) a=x86_64-unknown-linux-musl; sha=${RIPGREP_SHA256_X64} ;;`,\n 'esac;',\n `f=/tmp/ripgrep-${v}.tar.gz;`,\n `curl -fsSL \"https://github.com/BurntSushi/ripgrep/releases/download/${v}/ripgrep-${v}-$a.tar.gz\" -o \"$f\"`,\n '&& echo \"$sha $f\" | sha256sum -c -',\n '&& tar xzf \"$f\" -C /tmp',\n `&& mv \"/tmp/ripgrep-${v}-$a/rg\" /usr/local/bin/rg && chmod +x /usr/local/bin/rg;`,\n '}',\n ].join(' ');\n}\n\n// Skills source subpath, written under $HOME (out of the work dir so it can't clash with code cloned into the work dir) and also discovered from <workDir> for repo-provided skills.\nconst SKILLS_SOURCE_PATH = '/.agents/skills';\n\nexport type DeepAgentsHarnessSettings = {\n readonly auth?: DeepAgentsAuthOptions;\n /** Model id for the DeepAgents runtime, e.g. `claude-sonnet-4` (converted to `provider:model`). */\n readonly model?: string;\n /** Bridge port override; defaults to the sandbox's first declared port. */\n readonly port?: number;\n /** Maximum milliseconds to wait for the bridge to advertise its port. Defaults to 120000. */\n readonly startupTimeoutMs?: number;\n /** Max LangGraph super-steps per turn before it errors. Defaults to 100; raise for long multi-step tasks. */\n readonly recursionLimit?: number;\n};\n\n// Every model-callable DeepAgents built-in, keyed by what the bridge emits (commonName ?? nativeName); all must be listed or AI SDK throws AI_NoSuchToolError.\nconst DEEPAGENTS_BUILTIN_TOOLS = {\n read: commonTool('read', {\n nativeName: 'read_file',\n toolUseKind: 'readonly',\n description: 'Read file contents',\n inputSchema: z.object({ file_path: z.string() }),\n }),\n write: commonTool('write', {\n nativeName: 'write_file',\n toolUseKind: 'edit',\n description: 'Create a file',\n inputSchema: z.object({ file_path: z.string(), content: z.string() }),\n }),\n edit: commonTool('edit', {\n nativeName: 'edit_file',\n toolUseKind: 'edit',\n description: 'Perform exact string replacements in a file',\n inputSchema: z.object({\n file_path: z.string(),\n old_string: z.string(),\n new_string: z.string(),\n }),\n }),\n bash: commonTool('bash', {\n nativeName: 'execute',\n toolUseKind: 'bash',\n description: 'Run a shell command',\n inputSchema: z.object({ command: z.string() }),\n }),\n grep: commonTool('grep', {\n nativeName: 'grep',\n toolUseKind: 'readonly',\n description: 'Search file contents',\n inputSchema: z.object({ pattern: z.string() }),\n }),\n glob: commonTool('glob', {\n nativeName: 'glob',\n toolUseKind: 'readonly',\n description: 'Find files matching a glob pattern',\n inputSchema: z.object({ pattern: z.string() }),\n }),\n // No common-name equivalent — keyed by native name.\n ls: tool({\n description: 'List files in a directory',\n inputSchema: z.object({ path: z.string().optional() }),\n }),\n task: tool({\n description: 'Spawn a subagent to handle a delegated task',\n inputSchema: z.object({\n description: z.string().optional(),\n subagent_type: z.string().optional(),\n }),\n }),\n write_todos: tool({\n description: 'Manage a structured todo list',\n inputSchema: z.object({ todos: z.array(z.unknown()).optional() }),\n }),\n} as const satisfies Record<string, HarnessV1BuiltinTool<any, any>>;\n\n// Live bridge coordinates returned by doDetach/doSuspendTurn so a later process can reattach.\nconst deepAgentsBridgeCoordsSchema = z.object({\n port: z.number(),\n token: z.string(),\n lastSeenEventId: z.number(),\n sandboxId: z.string().optional(),\n});\nconst deepAgentsResumeStateSchema = z.object({\n bridge: deepAgentsBridgeCoordsSchema.optional(),\n});\ntype DeepAgentsBridgeCoords = z.infer<typeof deepAgentsBridgeCoordsSchema>;\n\nexport function createDeepAgents(\n settings: DeepAgentsHarnessSettings = {},\n): HarnessV1<typeof DEEPAGENTS_BUILTIN_TOOLS> {\n let cachedBootstrap: HarnessV1Bootstrap | undefined;\n\n return {\n specificationVersion: 'harness-v1',\n harnessId: 'deepagents',\n builtinTools: DEEPAGENTS_BUILTIN_TOOLS,\n // Built-in tool approvals are gated in-bridge via DeepAgents' interruptOn (HITL) middleware.\n supportsBuiltinToolApprovals: true,\n lifecycleStateSchema: deepAgentsResumeStateSchema,\n getBootstrap: async () => {\n if (cachedBootstrap != null) return cachedBootstrap;\n const [bridge, pkg, lock] = await Promise.all([\n readBridgeAsset('index.mjs'),\n readBridgeAsset('package.json'),\n readBridgeAsset('pnpm-lock.yaml'),\n ]);\n cachedBootstrap = {\n harnessId: 'deepagents',\n bootstrapDir: BOOTSTRAP_DIR,\n files: [\n { path: `${BOOTSTRAP_DIR}/bridge.mjs`, content: bridge },\n { path: `${BOOTSTRAP_DIR}/package.json`, content: pkg },\n { path: `${BOOTSTRAP_DIR}/pnpm-lock.yaml`, content: lock },\n ],\n commands: [\n { command: `mkdir -p ${BOOTSTRAP_DIR}` },\n { command: installRipgrepCommand() },\n {\n command: `pnpm --dir ${BOOTSTRAP_DIR} install --frozen-lockfile --store-dir ${BOOTSTRAP_DIR}/.pnpm-store`,\n },\n ],\n };\n return cachedBootstrap;\n },\n doStart: async startOpts => {\n const permissionMode = startOpts.permissionMode;\n const sandboxSession = startOpts.sandboxSession;\n const session = sandboxSession.restricted();\n const sandboxId = sandboxSession.id;\n\n const lifecycleState = startOpts.continueFrom ?? startOpts.resumeFrom;\n const isResume = lifecycleState != null;\n const isContinue = startOpts.continueFrom != null;\n const coords =\n isResume && typeof lifecycleState?.data === 'object'\n ? (lifecycleState.data as { bridge?: DeepAgentsBridgeCoords }).bridge\n : undefined;\n\n const workDir = startOpts.sessionWorkDir;\n const sessionDataDir = `${sandboxSession.defaultWorkingDirectory}/.agent-runs/${startOpts.sessionId}`;\n const bridgeStateDir = `${sessionDataDir}/bridge`;\n const timeoutMs = settings.startupTimeoutMs ?? 120_000;\n\n const report = startOpts.observability?.report;\n const onDiagnostic = report\n ? (frame: Parameters<typeof harnessV1DiagnosticFromBridgeFrame>[0]) =>\n report(\n harnessV1DiagnosticFromBridgeFrame(frame, {\n sessionId: startOpts.sessionId,\n timestamp: Date.now(),\n }),\n )\n : undefined;\n\n // Attach to the still-running bridge (continueFrom replays past the cursor); on failure fall through to a fresh spawn.\n if (coords) {\n try {\n const attachUrl =\n (await sandboxSession.getPortUrl({\n port: coords.port,\n protocol: 'ws',\n })) + `?agent_bridge_token=${encodeURIComponent(coords.token)}`;\n const attachChannel: DeepAgentsChannel = new SandboxChannel({\n connect: () => openWebSocket(attachUrl),\n outboundSchema: outboundMessageSchema,\n initialLastSeenEventId: coords.lastSeenEventId,\n onDiagnostic,\n });\n await attachChannel.open(isContinue ? { resume: true } : undefined);\n return createSession({\n sessionId: startOpts.sessionId,\n channel: attachChannel,\n proc: undefined,\n model: settings.model,\n bridgePort: coords.port,\n bridgeToken: coords.token,\n sandboxId,\n isResume: true,\n attached: true,\n permissionMode,\n builtinToolFiltering: startOpts.builtinToolFiltering,\n recursionLimit: settings.recursionLimit,\n });\n } catch {\n // Bridge no longer reachable — recover by respawning below.\n }\n }\n\n const port = resolveBridgePort(sandboxSession, settings.port);\n const token = randomBytes(32).toString('hex');\n\n // Always discover repo-provided skills under <workDir>/.agents/skills (e.g. a cloned repo); a missing dir is tolerated by deepagents.\n // Absolute paths: LocalShellBackend (non-virtual) treats a leading-slash path as a real fs path.\n const skillsPaths = [`${workDir}${SKILLS_SOURCE_PATH}`];\n // Host-provided skills go to $HOME (out of the work dir) and take priority (listed last → wins on name collision).\n if ((startOpts.skills?.length ?? 0) > 0) {\n const homeDir = await resolveSandboxHomeDir({\n sandbox: session,\n abortSignal: startOpts.abortSignal,\n });\n const homeSkillsRoot = `${homeDir}${SKILLS_SOURCE_PATH}`;\n await writeSkills({\n sandbox: session,\n root: homeSkillsRoot,\n skills: startOpts.skills ?? [],\n abortSignal: startOpts.abortSignal,\n });\n skillsPaths.push(homeSkillsRoot);\n }\n\n const env = {\n ...resolveDeepAgentsEnv({ auth: settings.auth }),\n AI_SDK_HARNESS_CLIENT_APP: DEEPAGENTS_CLIENT_APP,\n BRIDGE_CHANNEL_TOKEN: token,\n BRIDGE_WS_PORT: String(port),\n };\n\n await session.run({\n command: `mkdir -p ${shellQuote(workDir)} ${shellQuote(bridgeStateDir)}`,\n abortSignal: startOpts.abortSignal,\n });\n\n await markBridgeStarting({\n sandbox: session,\n bridgeStateDir,\n bridgeType: 'deepagents',\n abortSignal: startOpts.abortSignal,\n });\n\n const proc = await session.spawn({\n command: `node ${BOOTSTRAP_DIR}/bridge.mjs --workdir ${shellQuote(workDir)} --bridge-state-dir ${shellQuote(bridgeStateDir)} --bootstrap-dir ${shellQuote(BOOTSTRAP_DIR)}`,\n env,\n abortSignal: startOpts.abortSignal,\n });\n\n const { port: boundPort } = await waitForBridgeReady({\n proc,\n sandbox: session,\n bridgeStateDir,\n bridgeType: 'deepagents',\n timeoutMs,\n abortSignal: startOpts.abortSignal,\n createTimeoutError: () =>\n new Error('deepagents bridge did not become ready in time.'),\n createExitError: () =>\n new Error('deepagents bridge exited before becoming ready.'),\n });\n void forwardBridgeStderr(proc.stderr);\n\n const wsUrl =\n (await sandboxSession.getPortUrl({\n port: boundPort,\n protocol: 'ws',\n })) + `?agent_bridge_token=${encodeURIComponent(token)}`;\n\n const channel: DeepAgentsChannel = new SandboxChannel({\n connect: () => openWebSocket(wsUrl),\n outboundSchema: outboundMessageSchema,\n onDiagnostic,\n });\n await channel.open();\n\n return createSession({\n sessionId: startOpts.sessionId,\n channel,\n proc,\n model: settings.model,\n bridgePort: boundPort,\n bridgeToken: token,\n sandboxId,\n isResume,\n // Freshly spawned bridge — it must receive the instructions on the first prompt.\n attached: false,\n skillsPaths,\n permissionMode,\n builtinToolFiltering: startOpts.builtinToolFiltering,\n recursionLimit: settings.recursionLimit,\n });\n },\n };\n}\n\nfunction resolveBridgePort(\n sandboxSession: HarnessV1NetworkSandboxSession,\n override: number | undefined,\n): number {\n if (override !== undefined) return override;\n if (sandboxSession.ports.length > 0) return sandboxSession.ports[0];\n throw new HarnessCapabilityUnsupportedError({\n harnessId: 'deepagents',\n message:\n 'The deepagents harness needs a TCP port exposed by the sandbox. ' +\n 'Create the sandbox with `ports: [<port>]` or pass `createDeepAgents({ port })`.',\n });\n}\n\nasync function readBridgeAsset(name: string): Promise<string> {\n const candidates = [\n new URL(`./bridge/${name}`, import.meta.url),\n new URL(`../bridge/${name}`, import.meta.url),\n ];\n let lastErr: unknown;\n for (const url of candidates) {\n try {\n return await readFile(fileURLToPath(url), 'utf8');\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code !== 'ENOENT') throw err;\n lastErr = err;\n }\n }\n throw lastErr ?? new Error(`bridge asset not found: ${name}`);\n}\n\n// Materialize each skill as a native deepagents `<name>/SKILL.md` folder (+ attached files) under the given root, so skills load on demand and file references resolve.\nasync function writeSkills({\n sandbox,\n root,\n skills,\n abortSignal,\n}: {\n sandbox: ReturnType<HarnessV1NetworkSandboxSession['restricted']>;\n root: string;\n skills: ReadonlyArray<HarnessV1Skill>;\n abortSignal?: AbortSignal;\n}): Promise<void> {\n /*\n * DeepAgents requires each `SKILL.md` frontmatter name to match the parent\n * directory name, so keep the stricter lowercase skill-name policy here.\n */\n await writeHarnessSkills({\n sandbox,\n rootDir: root,\n skills,\n abortSignal,\n skillNamePattern: /^[a-z0-9]([a-z0-9-]{0,62}[a-z0-9])?$/,\n invalidSkillNameMessage: ({ name }) =>\n `Invalid deepagents skill name '${name}': must be lowercase alphanumeric with hyphens, 1-64 chars.`,\n filePathMode: 'strip-leading-slashes',\n invalidSkillFilePathMessage: ({ skillName, filePath }) =>\n `Invalid skill file path for '${skillName}': ${filePath}`,\n });\n}\n\nfunction openWebSocket(url: string): Promise<WebSocket> {\n return new Promise((resolve, reject) => {\n const ws = new WebSocket(url);\n const onOpen = () => {\n ws.off('error', onError);\n resolve(ws);\n };\n const onError = (err: Error) => {\n ws.off('open', onOpen);\n reject(err);\n };\n ws.once('open', onOpen);\n ws.once('error', onError);\n });\n}\n\nasync function forwardBridgeStderr(\n stream: ReadableStream<Uint8Array>,\n): Promise<void> {\n try {\n const reader = stream.pipeThrough(new TextDecoderStream()).getReader();\n while (true) {\n const { value, done } = await reader.read();\n if (done) return;\n if (value) {\n const trimmed = value.endsWith('\\n') ? value.slice(0, -1) : value;\n if (trimmed.length > 0) {\n // eslint-disable-next-line no-console\n console.log(`[bridge stderr] ${trimmed}`);\n }\n }\n }\n } catch {\n // Reader errors are non-fatal — best-effort diagnostic only.\n }\n}\n\nfunction createSession({\n sessionId,\n channel,\n proc,\n model,\n bridgePort,\n bridgeToken,\n sandboxId,\n isResume,\n attached,\n skillsPaths,\n permissionMode,\n builtinToolFiltering,\n recursionLimit,\n}: {\n sessionId: string;\n channel: DeepAgentsChannel;\n // Undefined on attach — the live bridge was spawned by another process.\n proc: Experimental_SandboxProcess | undefined;\n model: string | undefined;\n bridgePort: number;\n bridgeToken: string;\n sandboxId: string;\n isResume: boolean;\n // True only when attaching to a live bridge that already built the agent with\n // its instructions. A fresh spawn (incl. a respawn on attach failure or a\n // stop-resume) starts a new bridge that must receive the instructions again.\n attached: boolean;\n skillsPaths?: string[];\n permissionMode?: HarnessV1PermissionMode;\n builtinToolFiltering?: HarnessV1BuiltinToolFiltering;\n recursionLimit?: number;\n}): HarnessV1Session {\n let stopped = false;\n let instructionsApplied = attached;\n\n const wireTurn = (turnOpts: {\n emit: (event: HarnessV1StreamPart) => void;\n abortSignal?: AbortSignal;\n }): HarnessV1PromptControl => {\n let pendingResolve: (() => void) | undefined;\n let pendingReject: ((err: unknown) => void) | undefined;\n const done = new Promise<void>((resolve, reject) => {\n pendingResolve = resolve;\n pendingReject = reject;\n });\n\n const unsubs: Array<() => void> = [];\n const forward = (event: HarnessV1StreamPart) => {\n try {\n turnOpts.emit(event);\n } catch {}\n };\n\n const eventTypes = [\n 'stream-start',\n 'text-start',\n 'text-delta',\n 'text-end',\n 'reasoning-start',\n 'reasoning-delta',\n 'reasoning-end',\n 'tool-call',\n 'tool-approval-request',\n 'tool-result',\n 'file-change',\n 'finish-step',\n 'raw',\n ] as const;\n let isSettled = false;\n const settleSuccess = () => {\n if (isSettled) return;\n isSettled = true;\n for (const u of unsubs) u();\n pendingResolve!();\n };\n const settleError = (err: unknown) => {\n if (isSettled) return;\n isSettled = true;\n for (const u of unsubs) u();\n pendingReject!(err);\n };\n\n for (const type of eventTypes) {\n unsubs.push(channel.on(type, msg => forward(msg)));\n }\n unsubs.push(\n channel.on('finish', msg => {\n forward(msg);\n settleSuccess();\n }),\n );\n unsubs.push(\n channel.on('error', msg => {\n forward(msg);\n settleError(msg.error);\n }),\n );\n\n // A `'suspended'` close is a graceful slice-boundary freeze (suspend/detach keep the bridge alive for continuation); end the turn cleanly. Any other close is an unexpected bridge failure.\n const onClose = (_code: number, reason: string) => {\n if (isSettled) return;\n if (reason === 'suspended') {\n settleSuccess();\n return;\n }\n settleError(\n new Error('deepagents bridge closed before the turn finished.'),\n );\n };\n channel.onClose(onClose);\n\n const onAbort = () => {\n if (isSettled) return;\n try {\n channel.send({ type: 'abort' });\n } catch {}\n settleError(\n turnOpts.abortSignal?.reason ??\n new DOMException('Aborted', 'AbortError'),\n );\n };\n if (turnOpts.abortSignal) {\n if (turnOpts.abortSignal.aborted) {\n onAbort();\n } else {\n turnOpts.abortSignal.addEventListener('abort', onAbort, { once: true });\n }\n }\n\n return {\n submitToolResult: async input => {\n channel.send({\n type: 'tool-result',\n toolCallId: input.toolCallId,\n output: input.output,\n isError: input.isError,\n });\n },\n submitUserMessage: async text => {\n channel.send({ type: 'user-message', text });\n },\n submitToolApproval: async input => {\n channel.send({\n type: 'tool-approval-response',\n approvalId: input.approvalId,\n approved: input.approved,\n ...(input.reason != null ? { reason: input.reason } : {}),\n });\n },\n done,\n };\n };\n\n const unsupported = (capability: string): never => {\n throw new HarnessCapabilityUnsupportedError({\n harnessId: 'deepagents',\n message: `Harness 'deepagents' does not support ${capability} yet.`,\n });\n };\n\n return {\n sessionId,\n isResume,\n modelId: model,\n doPromptTurn: async promptOpts => {\n const control = wireTurn({\n emit: promptOpts.emit,\n abortSignal: promptOpts.abortSignal,\n });\n\n const applyInstructions =\n !instructionsApplied && !!promptOpts.instructions;\n instructionsApplied = true;\n\n channel.send({\n type: 'start',\n prompt: extractUserText(promptOpts.prompt),\n ...(applyInstructions ? { instructions: promptOpts.instructions } : {}),\n tools: (promptOpts.tools ?? []).map(t => ({\n name: t.name,\n description: t.description,\n inputSchema: t.inputSchema,\n })),\n ...(model ? { model } : {}),\n ...(skillsPaths?.length ? { skillsPaths } : {}),\n ...(permissionMode ? { permissionMode } : {}),\n ...(builtinToolFiltering ? { builtinToolFiltering } : {}),\n ...(recursionLimit != null ? { recursionLimit } : {}),\n });\n\n return control;\n },\n doContinueTurn: async continueOpts => {\n // Attach/replay: doStart opened with `{ resume: true }` so the bridge replays past the cursor; no `start` is sent (that would clear the replay log).\n return wireTurn({\n emit: continueOpts.emit,\n abortSignal: continueOpts.abortSignal,\n });\n },\n doSuspendTurn: async () => {\n if (stopped) {\n throw new Error(\n `deepagents session ${sessionId} is stopped; cannot suspend.`,\n );\n }\n stopped = true;\n // Freeze the active turn at the cursor, leaving the bridge running so the next slice replays the tail.\n const lastSeenEventId = await channel.suspend();\n const payload: HarnessV1ContinueTurnState = {\n type: 'continue-turn',\n harnessId: 'deepagents',\n specificationVersion: 'harness-v1',\n data: {\n bridge: {\n port: bridgePort,\n token: bridgeToken,\n lastSeenEventId,\n sandboxId,\n },\n },\n };\n return payload;\n },\n doDetach: async () => {\n if (stopped) {\n throw new Error(\n `deepagents session ${sessionId} is already stopped; cannot detach.`,\n );\n }\n stopped = true;\n // Park between turns: close the host socket but leave the bridge running for a later reattach via these coords.\n const lastSeenEventId = await channel.suspend();\n const payload: HarnessV1ResumeSessionState = {\n type: 'resume-session',\n harnessId: 'deepagents',\n specificationVersion: 'harness-v1',\n data: {\n bridge: {\n port: bridgePort,\n token: bridgeToken,\n lastSeenEventId,\n sandboxId,\n },\n },\n };\n return payload;\n },\n doCompact: async () => unsupported('manual compaction'),\n doStop: async () => {\n if (stopped) {\n throw new Error(\n `deepagents session ${sessionId} is already stopped; cannot stop.`,\n );\n }\n stopped = true;\n await teardown(channel, proc);\n // In-memory conversation is lost on teardown; the sandbox snapshot preserves the workspace files, not the conversation.\n const payload: HarnessV1ResumeSessionState = {\n type: 'resume-session',\n harnessId: 'deepagents',\n specificationVersion: 'harness-v1',\n data: {},\n };\n return payload;\n },\n doDestroy: async () => {\n if (stopped) return;\n stopped = true;\n await teardown(channel, proc);\n },\n };\n}\n\nasync function teardown(\n channel: DeepAgentsChannel,\n proc: Experimental_SandboxProcess | undefined,\n): Promise<void> {\n channel.beginClose();\n try {\n if (!channel.isClosed()) {\n channel.send({ type: 'shutdown' });\n }\n } catch {}\n let stopTimer: ReturnType<typeof setTimeout> | undefined;\n try {\n if (proc) {\n await Promise.race([\n proc.wait(),\n new Promise<void>(resolve => {\n stopTimer = setTimeout(resolve, 5000);\n stopTimer.unref?.();\n }),\n ]);\n }\n } finally {\n if (stopTimer) clearTimeout(stopTimer);\n try {\n await proc?.kill();\n } catch {}\n channel.close();\n }\n}\n\n// Reduce the prompt to plain user text; non-text parts are unsupported.\nfunction extractUserText(prompt: HarnessV1Prompt): string {\n if (typeof prompt === 'string') return prompt;\n const { content } = prompt;\n if (typeof content === 'string') return content;\n const parts: string[] = [];\n for (const part of content) {\n if (part.type !== 'text') {\n throw new HarnessCapabilityUnsupportedError({\n harnessId: 'deepagents',\n message: `The deepagents harness does not yet support user message parts of type '${part.type}'. Pass a string or a user message whose content contains only text parts.`,\n });\n }\n parts.push(part.text);\n }\n return parts.join('\\n\\n');\n}\n","import { getAiGatewayAuthFromEnv } from '@ai-sdk/harness/utils';\n\nexport type DeepAgentsAuthOptions = {\n readonly anthropic?: {\n readonly apiKey?: string;\n readonly authToken?: string;\n readonly baseUrl?: string;\n };\n readonly gateway?: {\n readonly apiKey?: string;\n readonly baseUrl?: string;\n };\n};\n\n// DeepAgents always drives the Anthropic client. Non-Anthropic models reach it\n// through AI Gateway's Anthropic-compatible endpoint, which translates to any\n// model (Gemini, OpenAI, etc.), tool calls included.\nexport function resolveDeepAgentsEnv({\n auth,\n processEnv = process.env,\n}: {\n auth?: DeepAgentsAuthOptions;\n processEnv?: Record<string, string | undefined>;\n}): Record<string, string> {\n if (auth?.anthropic) {\n return pickAnthropic({ explicit: auth.anthropic, processEnv });\n }\n\n const gatewayAuthFromEnv = getAiGatewayAuthFromEnv({ env: processEnv });\n if (auth?.gateway) {\n return pickGateway({ explicit: auth.gateway, gatewayAuthFromEnv });\n }\n if (gatewayAuthFromEnv.apiKey) {\n return pickGateway({ explicit: {}, gatewayAuthFromEnv });\n }\n\n return pickAnthropic({ processEnv });\n}\n\nfunction pickAnthropic({\n explicit,\n processEnv,\n}: {\n explicit?: NonNullable<DeepAgentsAuthOptions['anthropic']>;\n processEnv: Record<string, string | undefined>;\n}): Record<string, string> {\n const env: Record<string, string> = {};\n const apiKey = explicit?.apiKey ?? processEnv.ANTHROPIC_API_KEY;\n if (apiKey) env.ANTHROPIC_API_KEY = apiKey;\n const authToken = explicit?.authToken ?? processEnv.ANTHROPIC_AUTH_TOKEN;\n if (authToken) env.ANTHROPIC_AUTH_TOKEN = authToken;\n const baseUrl = explicit?.baseUrl ?? processEnv.ANTHROPIC_BASE_URL;\n if (baseUrl) env.ANTHROPIC_BASE_URL = baseUrl;\n return env;\n}\n\nfunction pickGateway({\n explicit,\n gatewayAuthFromEnv,\n}: {\n explicit: NonNullable<DeepAgentsAuthOptions['gateway']>;\n gatewayAuthFromEnv: ReturnType<typeof getAiGatewayAuthFromEnv>;\n}): Record<string, string> {\n const apiKey = explicit.apiKey ?? gatewayAuthFromEnv.apiKey;\n // The Anthropic SDK appends `/v1/messages`, so the gateway base stays at its root.\n const baseUrl = (explicit.baseUrl ?? gatewayAuthFromEnv.baseUrl).replace(\n /\\/+$/,\n '',\n );\n const env: Record<string, string> = {};\n if (apiKey) {\n env.AI_GATEWAY_API_KEY = apiKey;\n env.ANTHROPIC_API_KEY = apiKey;\n }\n env.ANTHROPIC_BASE_URL = baseUrl;\n return env;\n}\n","import {\n harnessV1BridgeInboundCommandSchemas,\n harnessV1BridgeOutboundMessageSchema,\n harnessV1BridgeReadySchema,\n harnessV1BridgeStartBaseSchema,\n} from '@ai-sdk/harness';\nimport { z } from 'zod/v4';\n\n// Deep Agents bridge wire protocol; only the `start` payload is adapter-specific.\nexport const outboundMessageSchema = harnessV1BridgeOutboundMessageSchema;\nexport type OutboundMessage = z.infer<typeof outboundMessageSchema>;\n\nexport const startMessageSchema = harnessV1BridgeStartBaseSchema.extend({\n // Prepended to the first user message (createDeepAgent takes no instructions param).\n instructions: z.string().optional(),\n // In-backend skills source dirs ($HOME and <workDir>), passed to createDeepAgent({ skills }).\n skillsPaths: z.array(z.string()).optional(),\n // Max LangGraph super-steps per turn (streamEvents recursionLimit).\n recursionLimit: z.number().optional(),\n});\n\nexport type StartMessage = z.infer<typeof startMessageSchema>;\n\nexport const inboundMessageSchema = z.discriminatedUnion('type', [\n startMessageSchema,\n ...harnessV1BridgeInboundCommandSchemas,\n]);\nexport type InboundMessage = z.infer<typeof inboundMessageSchema>;\n\nexport const bridgeReadySchema = harnessV1BridgeReadySchema;\nexport type BridgeReady = z.infer<typeof bridgeReadySchema>;\n","// Version string of this package injected at build time.\ndeclare const __PACKAGE_VERSION__: string | undefined;\nexport const VERSION: string =\n typeof __PACKAGE_VERSION__ !== 'undefined'\n ? __PACKAGE_VERSION__\n : '0.0.0-test';\n","import { createDeepAgents } from './deepagents-harness';\n\n/** Default `deepagents` harness instance; equivalent to `createDeepAgents()`. */\nexport const deepAgents = createDeepAgents();\n\nexport { createDeepAgents } from './deepagents-harness';\nexport { VERSION } from './version';\nexport type { DeepAgentsHarnessSettings } from './deepagents-harness';\nexport type { DeepAgentsAuthOptions } from './deepagents-auth';\n"],"mappings":"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","names":["z","z"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/harness-deepagents",
3
- "version": "1.0.18",
3
+ "version": "1.0.20",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -27,8 +27,8 @@
27
27
  },
28
28
  "dependencies": {
29
29
  "ws": "8.21.0",
30
- "@ai-sdk/harness": "1.0.19",
31
- "@ai-sdk/provider-utils": "5.0.5"
30
+ "@ai-sdk/harness": "1.0.21",
31
+ "@ai-sdk/provider-utils": "5.0.6"
32
32
  },
33
33
  "peerDependencies": {
34
34
  "zod": "^3.25.76 || ^4.1.8"
@@ -1,7 +1,7 @@
1
1
  // In-sandbox turn driver on `@ai-sdk/harness/bridge`; third-party imports stay external (tsup) and install in-sandbox from src/bridge/package.json — keep import/externals/deps in sync.
2
2
 
3
3
  import { randomUUID } from 'node:crypto';
4
- import { argv } from 'node:process';
4
+ import { argv, env as procEnv } from 'node:process';
5
5
  import {
6
6
  runBridge,
7
7
  type BridgeEvent,
@@ -24,6 +24,7 @@ const NATIVE_TO_COMMON: Readonly<Record<string, string>> = {
24
24
  edit_file: 'edit',
25
25
  execute: 'bash',
26
26
  };
27
+ const HARNESS_CLIENT_APP = procEnv.AI_SDK_HARNESS_CLIENT_APP;
27
28
 
28
29
  function toCommonName(nativeName: string): string {
29
30
  return NATIVE_TO_COMMON[nativeName] ?? nativeName;
@@ -48,14 +49,22 @@ function parseArgs(rawArgs: string[]): Record<string, string> {
48
49
  // `creator/model` slug (gateway translates); direct Anthropic wants the bare id.
49
50
  function buildModel(rawModel: string | undefined) {
50
51
  if (!rawModel) return undefined;
51
- const baseUrl = process.env.ANTHROPIC_BASE_URL;
52
+ const baseUrl = procEnv.ANTHROPIC_BASE_URL;
52
53
  const model = baseUrl ? rawModel : rawModel.replace(/^anthropic[/:]/, '');
53
54
  return new ChatAnthropic({
54
55
  model,
55
- ...(process.env.ANTHROPIC_API_KEY
56
- ? { apiKey: process.env.ANTHROPIC_API_KEY }
57
- : {}),
56
+ ...(procEnv.ANTHROPIC_API_KEY ? { apiKey: procEnv.ANTHROPIC_API_KEY } : {}),
58
57
  ...(baseUrl ? { anthropicApiUrl: baseUrl } : {}),
58
+ ...(procEnv.AI_GATEWAY_API_KEY && HARNESS_CLIENT_APP
59
+ ? {
60
+ clientOptions: {
61
+ defaultHeaders: {
62
+ 'User-Agent': HARNESS_CLIENT_APP,
63
+ 'x-client-app': HARNESS_CLIENT_APP,
64
+ },
65
+ },
66
+ }
67
+ : {}),
59
68
  });
60
69
  }
61
70
 
@@ -39,11 +39,16 @@ import {
39
39
  type InboundMessage,
40
40
  type OutboundMessage,
41
41
  } from './deepagents-bridge-protocol';
42
+ import { VERSION } from './version';
42
43
 
43
44
  type DeepAgentsChannel = SandboxChannel<OutboundMessage, InboundMessage>;
44
45
 
45
46
  // Pure derived state in /tmp; reinstalled per sandbox, persistence is the provider snapshot.
46
47
  const BOOTSTRAP_DIR = '/tmp/harness/deepagents';
48
+ /**
49
+ * Value to use in User-Agent and `x-client-app` headers.
50
+ */
51
+ const DEEPAGENTS_CLIENT_APP = `ai-sdk/harness-deepagents/${VERSION}`;
47
52
 
48
53
  // Pinned ripgrep release + per-arch tarball checksums (verified before install).
49
54
  const RIPGREP_VERSION = '14.1.1';
@@ -283,6 +288,7 @@ export function createDeepAgents(
283
288
 
284
289
  const env = {
285
290
  ...resolveDeepAgentsEnv({ auth: settings.auth }),
291
+ AI_SDK_HARNESS_CLIENT_APP: DEEPAGENTS_CLIENT_APP,
286
292
  BRIDGE_CHANNEL_TOKEN: token,
287
293
  BRIDGE_WS_PORT: String(port),
288
294
  };
package/src/index.ts CHANGED
@@ -4,5 +4,6 @@ import { createDeepAgents } from './deepagents-harness';
4
4
  export const deepAgents = createDeepAgents();
5
5
 
6
6
  export { createDeepAgents } from './deepagents-harness';
7
+ export { VERSION } from './version';
7
8
  export type { DeepAgentsHarnessSettings } from './deepagents-harness';
8
9
  export type { DeepAgentsAuthOptions } from './deepagents-auth';
package/src/version.ts ADDED
@@ -0,0 +1,6 @@
1
+ // Version string of this package injected at build time.
2
+ declare const __PACKAGE_VERSION__: string | undefined;
3
+ export const VERSION: string =
4
+ typeof __PACKAGE_VERSION__ !== 'undefined'
5
+ ? __PACKAGE_VERSION__
6
+ : '0.0.0-test';