@ai-sdk/harness 1.0.76 → 1.0.78
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 +20 -0
- package/bridge/index.ts +2 -0
- package/dist/agent/index.d.ts +42 -23
- package/dist/agent/index.js +168 -61
- package/dist/agent/index.js.map +1 -1
- package/dist/bridge/index.d.ts +12 -7
- package/dist/bridge/index.js +140 -5
- package/dist/bridge/index.js.map +1 -1
- package/dist/index.d.ts +38 -13
- package/dist/index.js +17 -1
- package/dist/index.js.map +1 -1
- package/dist/utils/index.d.ts +177 -1
- package/dist/utils/index.js +121 -1
- package/dist/utils/index.js.map +1 -1
- package/package.json +4 -4
- package/src/agent/harness-agent-session.ts +136 -12
- package/src/agent/harness-agent.ts +54 -22
- package/src/agent/internal/run-prompt.ts +2 -0
- package/src/agent/internal/sandbox-bootstrap.ts +3 -28
- package/src/agent/prepare-sandbox-for-harness.ts +3 -3
- package/src/bridge/index.ts +184 -12
- package/src/utils/bridge-user-message-submitter.ts +96 -0
- package/src/utils/get-restricted-sandbox-session.ts +10 -0
- package/src/utils/index.ts +8 -0
- package/src/utils/resolve-sandbox-default-working-directory.ts +33 -0
- package/src/utils/sandbox-channel.ts +9 -0
- package/src/v1/harness-v1-bridge-protocol.ts +23 -0
- package/src/v1/harness-v1-session.ts +9 -12
- package/src/v1/index.ts +4 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/v1/harness-v1-builtin-tool.ts","../src/v1/harness-v1-stream-part.ts","../src/v1/harness-v1-bridge-protocol.ts","../src/v1/harness-v1-diagnostic.ts","../src/v1/harness-v1-tool-filtering.ts","../src/errors/harness-error.ts","../src/errors/harness-capability-unsupported-error.ts","../src/errors/harness-sandbox-authentication-error.ts"],"sourcesContent":["import { tool, type FlexibleSchema, type Tool } from '@ai-sdk/provider-utils';\nimport { z } from 'zod/v4';\n\n/**\n * Cross-harness vocabulary of common built-in tool names with their baseline\n * input schemas. Adapters that declare a built-in with one of these\n * `commonName`s must accept (at least) every input the baseline schema\n * accepts. Extra optional fields are encouraged.\n *\n * Used both as runtime values (spread into `ToolSet`s for inspection) and as\n * a vocabulary source — `HarnessV1BuiltinToolName` is derived from its keys.\n */\nexport const HARNESS_V1_BUILTIN_TOOLS = {\n read: tool({\n description: 'Read file contents',\n inputSchema: z.object({ file_path: z.string() }),\n outputSchema: z.unknown(),\n }),\n write: tool({\n description: 'Write content to a file',\n inputSchema: z.object({ file_path: z.string(), content: z.string() }),\n outputSchema: z.unknown(),\n }),\n edit: tool({\n description: 'Edit a file by replacing text',\n inputSchema: z.object({\n file_path: z.string(),\n old_string: z.string(),\n new_string: z.string(),\n }),\n outputSchema: z.unknown(),\n }),\n bash: tool({\n description: 'Execute a shell command',\n inputSchema: z.object({ command: z.string() }),\n outputSchema: z.unknown(),\n }),\n grep: tool({\n description: 'Search file contents with regex',\n inputSchema: z.object({ pattern: z.string() }),\n outputSchema: z.unknown(),\n }),\n glob: tool({\n description: 'Find files matching a glob pattern',\n inputSchema: z.object({ pattern: z.string() }),\n outputSchema: z.unknown(),\n }),\n webSearch: tool({\n description: 'Search the web',\n inputSchema: z.object({ query: z.string() }),\n outputSchema: z.unknown(),\n }),\n} as const;\n\nexport type HarnessV1BuiltinToolName = keyof typeof HARNESS_V1_BUILTIN_TOOLS;\n\nexport const HARNESS_V1_BUILTIN_TOOL_NAMES = Object.keys(\n HARNESS_V1_BUILTIN_TOOLS,\n) as ReadonlyArray<HarnessV1BuiltinToolName>;\n\nexport type HarnessV1BuiltinToolUseKind = 'readonly' | 'edit' | 'bash';\n\n/**\n * A tool that the adapter's underlying runtime exposes natively. Extends the\n * AI SDK `Tool` shape with two optional harness-specific fields:\n *\n * - `nativeName`: the name as the underlying runtime knows it. Required\n * only when the tool's key in the harness's `builtinTools` is not the\n * native name — i.e. when the tool maps to a `commonName` (e.g. key\n * `'bash'` for Claude Code's native `'Bash'`). Tools without a common\n * equivalent are keyed by their native name directly, so `nativeName`\n * is redundant and omitted.\n * - `commonName`: cross-harness label drawn from\n * `HARNESS_V1_BUILTIN_TOOL_NAMES`. Set when the tool maps to a familiar\n * capability; consumers use it to recognize, e.g., that Claude Code's\n * `Bash` and Codex's `shell` are the same kind of tool.\n *\n * Always set both fields together via the `commonTool` helper, or neither\n * (declare the tool with the AI SDK's `tool()` directly).\n */\nexport type HarnessV1BuiltinTool<INPUT = unknown, OUTPUT = unknown> = Tool<\n INPUT,\n OUTPUT,\n any\n> & {\n readonly nativeName?: string;\n readonly commonName?: HarnessV1BuiltinToolName;\n readonly toolUseKind?: HarnessV1BuiltinToolUseKind;\n};\n\ntype InputOf<T> = T extends Tool<infer I, any, any> ? I : never;\n\ntype StandardInputOf<N extends HarnessV1BuiltinToolName> = InputOf<\n (typeof HARNESS_V1_BUILTIN_TOOLS)[N]\n>;\n\n/*\n * Type-level superset check. If `TStandard` is assignable to `TAdapter`\n * (i.e. the adapter accepts every input the standard accepts), the return\n * type is `TOk`. Otherwise it's a tagged error tuple that surfaces a clear\n * TypeScript error at the call site.\n */\ntype SupersetCheck<TStandard, TAdapter, TOk> = TStandard extends TAdapter\n ? TOk\n : [\n 'ERROR: adapter input schema must be a superset of the standard schema',\n { expected: TStandard; got: TAdapter },\n ];\n\n/**\n * Declare a built-in tool that maps to a cross-harness common name. The\n * adapter's input schema must accept every input the standard schema for\n * `commonName` accepts. Extra optional fields are encouraged.\n *\n * If the schema is missing a field the standard requires (or has an\n * incompatible type), the return type collapses to a tagged error tuple,\n * which fails the surrounding `as const satisfies ToolSet` assignment and\n * surfaces a readable TypeScript error at the offending entry.\n */\nexport function commonTool<TName extends HarnessV1BuiltinToolName, TInput>(\n commonName: TName,\n opts: {\n readonly nativeName: string;\n readonly toolUseKind?: HarnessV1BuiltinToolUseKind;\n readonly description?: string;\n readonly inputSchema: FlexibleSchema<TInput>;\n },\n): SupersetCheck<StandardInputOf<TName>, TInput, HarnessV1BuiltinTool<TInput>> {\n return {\n ...tool({\n description: opts.description,\n inputSchema: opts.inputSchema as FlexibleSchema<TInput>,\n }),\n nativeName: opts.nativeName,\n commonName,\n toolUseKind: opts.toolUseKind,\n } as never;\n}\n","import type {\n JSONValue,\n LanguageModelV4FinishReason,\n LanguageModelV4ToolApprovalRequest,\n LanguageModelV4ToolCall,\n LanguageModelV4ToolResult,\n LanguageModelV4Usage,\n SharedV4ProviderMetadata,\n} from '@ai-sdk/provider';\nimport { z } from 'zod/v4';\nimport type { HarnessV1CallWarning } from './harness-v1-call-warning';\nimport type { HarnessV1Metadata } from './harness-v1-metadata';\n\n/**\n * One event emitted by a harness adapter during a prompt turn.\n *\n * Mirrors `LanguageModelV4StreamPart` on the variants it shares so a\n * `HarnessAgent` can pipe events through to AI SDK consumers with minimal\n * translation. Primitive types from the V4 spec (`LanguageModelV4ToolCall`,\n * `LanguageModelV4ToolResult`, `LanguageModelV4ToolApprovalRequest`,\n * `LanguageModelV4Usage`, `LanguageModelV4FinishReason`) are reused\n * verbatim — type-compat tests assert this stays the case.\n *\n * The metadata field is named `harnessMetadata` (not `providerMetadata`)\n * because a harness is a peer to a provider, not a kind of provider. The\n * agent rebinds it when forwarding to AI SDK consumers.\n */\nexport type HarnessV1StreamPart =\n | {\n type: 'stream-start';\n warnings?: ReadonlyArray<HarnessV1CallWarning>;\n /**\n * The model the runtime actually resolved to for this turn, when the\n * adapter learns it at stream start (e.g. Claude Code's `init` message\n * reports the resolved/default model). Surfaced into telemetry as\n * `gen_ai.request.model`. Omitted when the adapter doesn't know it here.\n */\n modelId?: string;\n }\n\n // Text blocks\n | { type: 'text-start'; id: string; harnessMetadata?: HarnessV1Metadata }\n | {\n type: 'text-delta';\n id: string;\n delta: string;\n harnessMetadata?: HarnessV1Metadata;\n }\n | { type: 'text-end'; id: string; harnessMetadata?: HarnessV1Metadata }\n\n // Reasoning blocks\n | { type: 'reasoning-start'; id: string; harnessMetadata?: HarnessV1Metadata }\n | {\n type: 'reasoning-delta';\n id: string;\n delta: string;\n harnessMetadata?: HarnessV1Metadata;\n }\n | { type: 'reasoning-end'; id: string; harnessMetadata?: HarnessV1Metadata }\n\n // Tool calls, approvals, results — reuse V4 primitives.\n //\n // `nativeName` is the only harness-only extension on `tool-call`. It lets\n // adapters surface the runtime's native name for a builtin when it differs\n // from the wire `toolName` (e.g. `toolName: 'bash'`, `nativeName: 'Bash'`).\n //\n // Whether the call was executed by the underlying runtime (Claude Code's\n // built-in `Bash`, Codex's `shell`) vs. needs host dispatch is signalled by\n // the standard `providerExecuted` field on `LanguageModelV4ToolCall` —\n // `true` for runtime-executed builtins, false/undefined for host tools.\n | (LanguageModelV4ToolCall & {\n nativeName?: string;\n })\n | LanguageModelV4ToolApprovalRequest\n | LanguageModelV4ToolResult\n\n // Step boundary inside a multi-step turn.\n | {\n type: 'finish-step';\n finishReason: LanguageModelV4FinishReason;\n usage: LanguageModelV4Usage;\n harnessMetadata?: HarnessV1Metadata;\n }\n\n // Turn end.\n | {\n type: 'finish';\n finishReason: LanguageModelV4FinishReason;\n totalUsage: LanguageModelV4Usage;\n harnessMetadata?: HarnessV1Metadata;\n }\n\n // Workspace file mutation that occurred through an opaque underlying\n // mechanism (one with no visible `tool-call` carrying the same data, e.g.\n // Codex's internal `apply_patch`). Emitted per changed path. Path-only by\n // design — when the mutation goes through a visible tool call, the\n // tool-call/tool-result pair already carries the information.\n | {\n type: 'file-change';\n event: 'create' | 'modify' | 'delete';\n path: string;\n harnessMetadata?: HarnessV1Metadata;\n }\n\n // Context compaction performed by the underlying runtime (Claude Code's\n // native compaction, Pi's summarization). Observation only — the runtime\n // owns the compaction; the harness neither implements nor schedules it.\n // Emitted once, on completion, since `summary`/`tokensAfter` only exist then.\n | {\n type: 'compaction';\n trigger: 'manual' | 'auto';\n summary: string;\n tokensBefore?: number;\n tokensAfter?: number;\n harnessMetadata?: HarnessV1Metadata;\n }\n\n // Errors. Multiple may be emitted in a single turn.\n | { type: 'error'; error: unknown }\n\n // Adapter-specific passthrough. Consumers can opt in to receive these via\n // `HarnessAgent` settings; otherwise they are dropped.\n | { type: 'raw'; rawValue: unknown };\n\n/*\n * Runtime (Zod) encoding of `HarnessV1StreamPart`.\n *\n * `HarnessV1StreamPart` is a compile-time type built on `LanguageModelV4*`\n * types that ship no runtime validator. Bridge adapters receive these parts as\n * JSON across a trust boundary (the sandbox WebSocket), so they need a runtime\n * schema. These schemas ARE that encoding — one source of truth, kept from\n * diverging from the type by the `_assignable` guard below and the mutual\n * `toEqualTypeOf` assertion in `harness-v1-stream-part.test-d.ts`.\n *\n * Members are exported individually so `harness-v1-bridge-protocol.ts` can\n * compose them into the bridge outbound union alongside the transport frames.\n */\n\nconst harnessV1JsonValueSchema: z.ZodType<JSONValue> = z.lazy(() =>\n z.union([\n z.string(),\n z.number(),\n z.boolean(),\n z.null(),\n z.array(harnessV1JsonValueSchema),\n z.record(z.string(), harnessV1JsonValueSchema),\n ]),\n);\n\n/*\n * Tool-result values. The inferred type is the spec's `NonNullable<JSONValue>`\n * (matching `LanguageModelV4ToolResult`), but the runtime validator\n * deliberately also accepts `null`: adapters emit `result: <value> ?? null` for\n * tools that produced no output, and that `null` must survive the trust\n * boundary unchanged (it reaches consumers exactly as it did before this schema\n * existed, when a cast hid it). Leniency at runtime, strictness in the type.\n */\nconst harnessV1ToolResultValueSchema =\n harnessV1JsonValueSchema as unknown as z.ZodType<NonNullable<JSONValue>>;\n\nconst harnessV1JsonObjectSchema = z.record(\n z.string(),\n harnessV1JsonValueSchema,\n) as unknown as z.ZodType<Record<string, JSONValue>>;\n\nconst harnessV1MetadataSchema = z.record(\n z.string(),\n z.record(z.string(), harnessV1JsonValueSchema),\n) as unknown as z.ZodType<HarnessV1Metadata>;\n\nconst harnessV1ProviderMetadataSchema = z.record(\n z.string(),\n z.record(z.string(), harnessV1JsonValueSchema),\n) as unknown as z.ZodType<SharedV4ProviderMetadata>;\n\nconst harnessV1CallWarningSchema = z.union([\n z.object({\n type: z.literal('unsupported-setting'),\n setting: z.string(),\n details: z.string().optional(),\n }),\n z.object({\n type: z.literal('unsupported-tool'),\n tool: z.string(),\n details: z.string().optional(),\n }),\n z.object({ type: z.literal('other'), message: z.string() }),\n]) as z.ZodType<HarnessV1CallWarning>;\n\nconst harnessV1UsageSchema = z.object({\n inputTokens: z.object({\n total: z.number().optional(),\n noCache: z.number().optional(),\n cacheRead: z.number().optional(),\n cacheWrite: z.number().optional(),\n }),\n outputTokens: z.object({\n total: z.number().optional(),\n text: z.number().optional(),\n reasoning: z.number().optional(),\n }),\n raw: harnessV1JsonObjectSchema.optional(),\n}) as unknown as z.ZodType<LanguageModelV4Usage>;\n\nconst harnessV1FinishReasonSchema = z.object({\n unified: z.enum([\n 'stop',\n 'length',\n 'content-filter',\n 'tool-calls',\n 'error',\n 'other',\n ]),\n raw: z.string().optional(),\n}) as unknown as z.ZodType<LanguageModelV4FinishReason>;\n\nexport const harnessV1StreamStartPartSchema = z.object({\n type: z.literal('stream-start'),\n warnings: z.array(harnessV1CallWarningSchema).readonly().optional(),\n modelId: z.string().optional(),\n});\n\nexport const harnessV1TextStartPartSchema = z.object({\n type: z.literal('text-start'),\n id: z.string(),\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1TextDeltaPartSchema = z.object({\n type: z.literal('text-delta'),\n id: z.string(),\n delta: z.string(),\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1TextEndPartSchema = z.object({\n type: z.literal('text-end'),\n id: z.string(),\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1ReasoningStartPartSchema = z.object({\n type: z.literal('reasoning-start'),\n id: z.string(),\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1ReasoningDeltaPartSchema = z.object({\n type: z.literal('reasoning-delta'),\n id: z.string(),\n delta: z.string(),\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1ReasoningEndPartSchema = z.object({\n type: z.literal('reasoning-end'),\n id: z.string(),\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1ToolCallPartSchema = z.object({\n type: z.literal('tool-call'),\n toolCallId: z.string(),\n toolName: z.string(),\n input: z.string(),\n providerExecuted: z.boolean().optional(),\n dynamic: z.boolean().optional(),\n providerMetadata: harnessV1ProviderMetadataSchema.optional(),\n nativeName: z.string().optional(),\n});\n\nexport const harnessV1ToolApprovalRequestPartSchema = z.object({\n type: z.literal('tool-approval-request'),\n approvalId: z.string(),\n toolCallId: z.string(),\n providerMetadata: harnessV1ProviderMetadataSchema.optional(),\n});\n\nexport const harnessV1ToolResultPartSchema = z.object({\n type: z.literal('tool-result'),\n toolCallId: z.string(),\n toolName: z.string(),\n result: harnessV1ToolResultValueSchema,\n isError: z.boolean().optional(),\n preliminary: z.boolean().optional(),\n dynamic: z.boolean().optional(),\n providerMetadata: harnessV1ProviderMetadataSchema.optional(),\n});\n\nexport const harnessV1FinishStepPartSchema = z.object({\n type: z.literal('finish-step'),\n finishReason: harnessV1FinishReasonSchema,\n usage: harnessV1UsageSchema,\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1FinishPartSchema = z.object({\n type: z.literal('finish'),\n finishReason: harnessV1FinishReasonSchema,\n totalUsage: harnessV1UsageSchema,\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1FileChangePartSchema = z.object({\n type: z.literal('file-change'),\n event: z.enum(['create', 'modify', 'delete']),\n path: z.string(),\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1CompactionPartSchema = z.object({\n type: z.literal('compaction'),\n trigger: z.enum(['manual', 'auto']),\n summary: z.string(),\n tokensBefore: z.number().optional(),\n tokensAfter: z.number().optional(),\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1ErrorPartSchema = z.object({\n type: z.literal('error'),\n error: z.unknown(),\n});\n\nexport const harnessV1RawPartSchema = z.object({\n type: z.literal('raw'),\n rawValue: z.unknown(),\n});\n\n/**\n * Assembled discriminated union over every `HarnessV1StreamPart` variant. Left\n * un-annotated so it keeps its precise inferred type — the protocol layer\n * composes the individual member schemas, and the type test asserts the\n * inferred union equals `HarnessV1StreamPart`.\n */\nexport const harnessV1StreamPartSchema = z.discriminatedUnion('type', [\n harnessV1StreamStartPartSchema,\n harnessV1TextStartPartSchema,\n harnessV1TextDeltaPartSchema,\n harnessV1TextEndPartSchema,\n harnessV1ReasoningStartPartSchema,\n harnessV1ReasoningDeltaPartSchema,\n harnessV1ReasoningEndPartSchema,\n harnessV1ToolCallPartSchema,\n harnessV1ToolApprovalRequestPartSchema,\n harnessV1ToolResultPartSchema,\n harnessV1FinishStepPartSchema,\n harnessV1FinishPartSchema,\n harnessV1FileChangePartSchema,\n harnessV1CompactionPartSchema,\n harnessV1ErrorPartSchema,\n harnessV1RawPartSchema,\n]);\n\n/*\n * Fail-fast guard at the definition site: the schema's output must be\n * assignable to `HarnessV1StreamPart` (catches a schema variant inventing a\n * shape the type does not allow). The reverse direction — the type being a\n * subset of the schema — is covered by the `toEqualTypeOf` assertion in the\n * type test.\n */\nconst _assignable: z.ZodType<HarnessV1StreamPart> = harnessV1StreamPartSchema;\nvoid _assignable;\n","import { z } from 'zod/v4';\nimport {\n harnessV1DebugConfigSchema,\n harnessV1DebugLevelSchema,\n type HarnessV1Diagnostic,\n} from './harness-v1-diagnostic';\nimport type { HarnessV1ResponseFormat } from './harness-v1-response-format';\nimport {\n harnessV1CompactionPartSchema,\n harnessV1ErrorPartSchema,\n harnessV1FileChangePartSchema,\n harnessV1FinishPartSchema,\n harnessV1FinishStepPartSchema,\n harnessV1RawPartSchema,\n harnessV1ReasoningDeltaPartSchema,\n harnessV1ReasoningEndPartSchema,\n harnessV1ReasoningStartPartSchema,\n harnessV1StreamStartPartSchema,\n harnessV1TextDeltaPartSchema,\n harnessV1TextEndPartSchema,\n harnessV1TextStartPartSchema,\n harnessV1ToolApprovalRequestPartSchema,\n harnessV1ToolCallPartSchema,\n harnessV1ToolResultPartSchema,\n} from './harness-v1-stream-part';\n\n/*\n * The bridge wire protocol shared by every bridge-backed harness adapter.\n *\n * This is the serialization of the host<->runtime contract for adapters that\n * run the agent runtime inside the sandbox and talk to the host over a\n * WebSocket. It exists ONLY because of that transport: untrusted JSON frames\n * crossing the sandbox boundary need runtime validation, the connection needs\n * a handshake, and the host drives turns with serialized commands. Every export\n * here is therefore prefixed `harnessV1Bridge…`.\n *\n * It has three tiers:\n *\n * 1. The OUTBOUND events — `HarnessV1StreamPart` re-expressed as Zod (imported\n * member schemas from `harness-v1-stream-part.ts`), because the part type is\n * compile-time only and the frames need runtime validation at the boundary.\n * 2. The transport/control frames that are NOT consumer events — `bridge-hello`\n * (handshake), `bridge-stop` (runtime resume data), `bridge-thread` (a resume\n * coordinate some runtimes announce). These ride the same socket.\n * 3. The INBOUND command vocabulary the host sends back: the shared commands\n * live here; the per-adapter `start` payload extends\n * `harnessV1BridgeStartBaseSchema` and assembles the final inbound union in\n * the adapter package.\n *\n * Non-bridge adapters (e.g. Pi) do not use this layer at all — they have no\n * serialization boundary and target the universal `HarnessV1StreamPart` type\n * directly. That is the deliberate split: `harness-v1-stream-part.ts` is the\n * transport-agnostic event vocabulary; this file is the bridge transport.\n */\n\n/**\n * The subset of a host-defined tool that travels on the `start` message. The\n * runtime only needs the name, description, and JSON-Schema input to surface\n * the tool; `execute` stays on the host.\n */\nexport const harnessV1BridgeToolWireSchema = z.object({\n name: z.string(),\n description: z.string().optional(),\n inputSchema: z.unknown().optional(),\n});\n\nexport type HarnessV1BridgeToolWire = z.infer<\n typeof harnessV1BridgeToolWireSchema\n>;\n\nexport const harnessV1BridgePermissionModeSchema = z.enum([\n 'allow-reads',\n 'allow-edits',\n 'allow-all',\n]);\n\nexport const harnessV1BridgeBuiltinToolFilteringSchema = z.discriminatedUnion(\n 'mode',\n [\n z.object({\n mode: z.literal('allow'),\n toolNames: z.array(z.string()),\n }),\n z.object({\n mode: z.literal('deny'),\n toolNames: z.array(z.string()),\n }),\n ],\n);\n\nexport const harnessV1BridgeResponseFormatSchema: z.ZodType<HarnessV1ResponseFormat> =\n z.discriminatedUnion('type', [\n z.object({ type: z.literal('text') }),\n z.object({\n type: z.literal('json'),\n schema: z.record(z.string(), z.json()).optional(),\n name: z.string().optional(),\n description: z.string().optional(),\n }),\n ]);\n\n/**\n * Common fields of the inbound `start` message. Each adapter extends this with\n * its runtime-specific configuration (e.g. `thinking`/`continue` for Claude\n * Code, `reasoningEffort`/`webSearch`/`skills`/`resumeThreadId` for Codex) and\n * assembles the final inbound union from the shared command members below.\n *\n * `debug` carries the general `HarnessV1DebugConfig` — diagnostics config is not\n * a bridge concept, it just happens to ride the `start` frame for bridge-backed\n * adapters.\n */\nexport const harnessV1BridgeStartBaseSchema = z.object({\n type: z.literal('start'),\n prompt: z.string(),\n tools: z.array(harnessV1BridgeToolWireSchema).optional(),\n model: z.string().optional(),\n debug: harnessV1DebugConfigSchema.optional(),\n permissionMode: harnessV1BridgePermissionModeSchema.optional(),\n builtinToolFiltering: harnessV1BridgeBuiltinToolFilteringSchema.optional(),\n responseFormat: harnessV1BridgeResponseFormatSchema.optional(),\n});\n\n// --- Transport / control frames (outbound, not consumer events) ---\n\n/**\n * Sent the instant the bridge accepts an authenticated WS connection. The host\n * waits for it before sending `start`/`resume`, because some sandbox runtimes\n * complete the upstream WS handshake before the connection is wired through to\n * the bridge process — anything sent in that gap is dropped. Carries the\n * bridge's lifecycle `state` and highest emitted `seq` for reconnect.\n */\nexport const harnessV1BridgeHelloSchema = z.object({\n type: z.literal('bridge-hello'),\n state: z.string().optional(),\n lastSeq: z.number().optional(),\n});\n\n/**\n * The bridge's reply to an inbound `stop`. Carries the adapter-specific\n * payload the host serializes into lifecycle state `data`.\n */\nexport const harnessV1BridgeStopSchema = z.object({\n type: z.literal('bridge-stop'),\n data: z.unknown(),\n});\n\n/**\n * A resume coordinate the bridge proactively announces (e.g. Codex's thread id)\n * so the host can cache it for a later resume without waiting for `stop`.\n */\nexport const harnessV1BridgeThreadSchema = z.object({\n type: z.literal('bridge-thread'),\n threadId: z.string(),\n});\n\n// --- Diagnostics frames (outbound, not consumer events) ---\n\n/**\n * One captured console line from inside the sandbox. The bridge line-buffers\n * `process.stdout`/`process.stderr` and emits one of these per complete line.\n * Routed host-side to the diagnostics sink, never to the consumer stream.\n */\nexport const harnessV1BridgeSandboxLogSchema = z.object({\n type: z.literal('sandbox-log'),\n source: z.string(),\n stream: z.enum(['stdout', 'stderr']),\n line: z.string(),\n});\n\n/**\n * A structured diagnostic an adapter emits from inside the bridge via\n * `turn.bridgeLog(...)`. Gated by the session's debug level + subsystem filter.\n */\nexport const harnessV1BridgeDebugEventSchema = z.object({\n type: z.literal('debug-event'),\n level: harnessV1DebugLevelSchema,\n subsystem: z.string(),\n message: z.string(),\n attrs: z.record(z.string(), z.unknown()).optional(),\n error: z\n .object({\n name: z.string().optional(),\n message: z.string(),\n stack: z.string().optional(),\n })\n .optional(),\n});\n\n/**\n * Every frame a bridge can send to the host: the stream-part events plus the\n * transport/control frames. This is the schema the host `SandboxChannel`\n * validates inbound frames against.\n */\nexport const harnessV1BridgeOutboundMessageSchema = z.discriminatedUnion(\n 'type',\n [\n harnessV1StreamStartPartSchema,\n harnessV1TextStartPartSchema,\n harnessV1TextDeltaPartSchema,\n harnessV1TextEndPartSchema,\n harnessV1ReasoningStartPartSchema,\n harnessV1ReasoningDeltaPartSchema,\n harnessV1ReasoningEndPartSchema,\n harnessV1ToolCallPartSchema,\n harnessV1ToolApprovalRequestPartSchema,\n harnessV1ToolResultPartSchema,\n harnessV1FinishStepPartSchema,\n harnessV1FinishPartSchema,\n harnessV1FileChangePartSchema,\n harnessV1CompactionPartSchema,\n harnessV1ErrorPartSchema,\n harnessV1RawPartSchema,\n harnessV1BridgeHelloSchema,\n harnessV1BridgeStopSchema,\n harnessV1BridgeThreadSchema,\n harnessV1BridgeSandboxLogSchema,\n harnessV1BridgeDebugEventSchema,\n ],\n);\n\nexport type HarnessV1BridgeOutboundMessage = z.infer<\n typeof harnessV1BridgeOutboundMessageSchema\n>;\n\nexport type HarnessV1BridgeSandboxLog = z.infer<\n typeof harnessV1BridgeSandboxLogSchema\n>;\n\nexport type HarnessV1BridgeDebugEvent = z.infer<\n typeof harnessV1BridgeDebugEventSchema\n>;\n\n/**\n * Normalize a bridge diagnostics wire frame into the transport-agnostic\n * `HarnessV1Diagnostic` an adapter reports to the framework. A captured console\n * line maps `stderr` → `warn` and `stdout` → `info`; a structured event passes\n * its fields through. This is the seam where the bridge's serialization is\n * lifted into the general emission shape every harness shares.\n */\nexport function harnessV1DiagnosticFromBridgeFrame(\n frame: HarnessV1BridgeSandboxLog | HarnessV1BridgeDebugEvent,\n context: { sessionId?: string; timestamp: number },\n): HarnessV1Diagnostic {\n if (frame.type === 'sandbox-log') {\n return {\n level: frame.stream === 'stderr' ? 'warn' : 'info',\n message: frame.line,\n subsystem: `sandbox.log.${frame.source}`,\n kind: 'log',\n source: frame.source,\n stream: frame.stream,\n sessionId: context.sessionId,\n timestamp: context.timestamp,\n };\n }\n return {\n level: frame.level,\n message: frame.message,\n subsystem: frame.subsystem,\n kind: 'event',\n attrs: frame.attrs,\n error: frame.error,\n sessionId: context.sessionId,\n timestamp: context.timestamp,\n };\n}\n\n// --- Shared inbound command members (host -> bridge) ---\n\nexport const harnessV1BridgeToolResultInboundSchema = z.object({\n type: z.literal('tool-result'),\n toolCallId: z.string(),\n output: z.unknown(),\n isError: z.boolean().optional(),\n});\n\nexport const harnessV1BridgeToolApprovalResponseInboundSchema = z.object({\n type: z.literal('tool-approval-response'),\n approvalId: z.string(),\n approved: z.boolean(),\n reason: z.string().optional(),\n});\n\nexport const harnessV1BridgeUserMessageInboundSchema = z.object({\n type: z.literal('user-message'),\n text: z.string(),\n});\n\nexport const harnessV1BridgeAbortInboundSchema = z.object({\n type: z.literal('abort'),\n});\n\nexport const harnessV1BridgeDestroyInboundSchema = z.object({\n type: z.literal('destroy'),\n});\n\n/**\n * Reconnect: after re-establishing the socket the host asks the bridge to\n * replay every buffered event with `seq > lastSeenEventId`.\n */\nexport const harnessV1BridgeResumeInboundSchema = z.object({\n type: z.literal('resume'),\n lastSeenEventId: z.number(),\n});\n\n/**\n * The bridge replies with `bridge-stop` carrying any runtime resume data,\n * then exits.\n */\nexport const harnessV1BridgeStopInboundSchema = z.object({\n type: z.literal('stop'),\n});\n\n/**\n * The inbound command members shared by every bridge adapter. Spread these\n * alongside the adapter's own `start` schema to build the final inbound union:\n * `z.discriminatedUnion('type', [adapterStartSchema, ...harnessV1BridgeInboundCommandSchemas])`.\n */\nexport const harnessV1BridgeInboundCommandSchemas = [\n harnessV1BridgeToolResultInboundSchema,\n harnessV1BridgeToolApprovalResponseInboundSchema,\n harnessV1BridgeUserMessageInboundSchema,\n harnessV1BridgeAbortInboundSchema,\n harnessV1BridgeDestroyInboundSchema,\n harnessV1BridgeResumeInboundSchema,\n harnessV1BridgeStopInboundSchema,\n] as const;\n\n/**\n * The JSON line the bridge writes to stdout once its WebSocket server is bound,\n * announcing the port the host should connect to.\n */\nexport const harnessV1BridgeReadySchema = z.object({\n type: z.literal('bridge-ready'),\n port: z.number(),\n});\n\nexport type HarnessV1BridgeReady = z.infer<typeof harnessV1BridgeReadySchema>;\n","import { z } from 'zod/v4';\n\n/*\n * Diagnostics EMISSION contract — part of the `HarnessV1` spec.\n *\n * These are the types a harness adapter produces and receives: an adapter\n * reports a `HarnessV1Diagnostic` to the framework (a bridge adapter normalizes\n * its wire frames into one; a non-bridge adapter constructs one directly), and\n * receives a `HarnessV1DebugConfig` to gate what it emits. They are distinct\n * from the unaffixed host-facing `HarnessDiagnostic` / `HarnessDebugConfig`\n * (the external/telemetry surface) — the framework maps between the two at the\n * boundary, so the emission and consumption surfaces can evolve independently.\n */\n\n/** Severity of a diagnostic, ordered most → least severe. */\nexport const harnessV1DebugLevelSchema = z.enum([\n 'error',\n 'warn',\n 'info',\n 'debug',\n 'trace',\n]);\n\nexport type HarnessV1DebugLevel = z.infer<typeof harnessV1DebugLevelSchema>;\n\n/**\n * Per-session diagnostics configuration the framework hands an adapter (and the\n * host sends on `start.debug`). When absent or `enabled` is false the adapter\n * captures and emits nothing. `subsystems` filters structured events by dotted\n * prefix; console capture is independent of the subsystem filter.\n */\nexport const harnessV1DebugConfigSchema = z.object({\n enabled: z.boolean().optional(),\n level: harnessV1DebugLevelSchema.optional(),\n subsystems: z.array(z.string()).optional(),\n});\n\nexport type HarnessV1DebugConfig = z.infer<typeof harnessV1DebugConfigSchema>;\n\n/**\n * A diagnostic as emitted by a harness adapter. Structurally identical to the\n * host-facing `HarnessDiagnostic` today, but kept separate: this is the spec's\n * emission shape, that is the external consumption shape.\n */\nexport type HarnessV1Diagnostic = {\n /** Severity. */\n readonly level: HarnessV1DebugLevel;\n /** Human-readable line (console capture) or message (structured event). */\n readonly message: string;\n /** Dotted subsystem (`sandbox.log.<source>` for console capture). */\n readonly subsystem: string;\n /** `'log'` = captured console line; `'event'` = structured emission. */\n readonly kind: 'log' | 'event';\n /** Originating source label (console capture). */\n readonly source?: string;\n /** Which standard stream the line came from (console capture). */\n readonly stream?: 'stdout' | 'stderr';\n /** Structured attributes (structured events only). */\n readonly attrs?: Record<string, unknown>;\n /** Error payload (structured events only). */\n readonly error?: { name?: string; message: string; stack?: string };\n /** The harness session this diagnostic originated from. */\n readonly sessionId?: string;\n /** Emission time (epoch ms). */\n readonly timestamp: number;\n};\n","export type HarnessV1BuiltinToolFiltering =\n | {\n mode: 'allow';\n toolNames: string[];\n }\n | {\n mode: 'deny';\n toolNames: string[];\n };\n\nexport function isHarnessV1BuiltinToolIncluded(input: {\n toolName: string;\n toolFiltering: HarnessV1BuiltinToolFiltering | undefined;\n}): boolean {\n if (input.toolFiltering == null) return true;\n return input.toolFiltering.mode === 'allow'\n ? input.toolFiltering.toolNames.includes(input.toolName)\n : !input.toolFiltering.toolNames.includes(input.toolName);\n}\n\nexport function getHarnessV1BuiltinToolFilteringDenialReason(input: {\n toolName: string;\n}): string {\n return `Tool '${input.toolName}' is inactive due to the HarnessAgent tool filtering policy.`;\n}\n","import { AISDKError } from '@ai-sdk/provider';\n\nconst name = 'AI_HarnessError';\nconst marker = `vercel.ai.error.${name}`;\nconst symbol = Symbol.for(marker);\n\n/**\n * Base error type for failures originating in or signalled by a harness\n * adapter. Specific failure modes (e.g. unsupported capability) extend this\n * class.\n */\nexport class HarnessError extends AISDKError {\n private readonly [symbol] = true;\n\n constructor({ message, cause }: { message: string; cause?: unknown }) {\n super({ name, message, cause });\n }\n\n static isInstance(error: unknown): error is HarnessError {\n return AISDKError.hasMarker(error, marker);\n }\n}\n","import { AISDKError } from '@ai-sdk/provider';\nimport { HarnessError } from './harness-error';\n\nconst name = 'AI_HarnessCapabilityUnsupportedError';\nconst marker = `vercel.ai.error.${name}`;\nconst symbol = Symbol.for(marker);\n\n/**\n * Thrown when a caller asks the harness to do something the adapter (or the\n * supplied sandbox) does not support, e.g. requesting manual compaction from\n * an adapter that only auto-compacts, or invoking `getPortEndpoint` on a\n * sandbox that does not expose one.\n *\n * The caller supplies the full human-readable message. Optional `harnessId`\n * is recorded as structured context for tooling.\n */\nexport class HarnessCapabilityUnsupportedError extends HarnessError {\n private readonly [symbol] = true;\n\n readonly harnessId?: string;\n\n constructor({\n message,\n harnessId,\n cause,\n }: {\n message: string;\n harnessId?: string;\n cause?: unknown;\n }) {\n super({ message, cause });\n Object.defineProperty(this, 'name', { value: name });\n this.harnessId = harnessId;\n }\n\n static isInstance(\n error: unknown,\n ): error is HarnessCapabilityUnsupportedError {\n return AISDKError.hasMarker(error, marker);\n }\n}\n","import { AISDKError } from '@ai-sdk/provider';\nimport { HarnessError } from './harness-error';\n\nconst name = 'AI_HarnessSandboxAuthenticationError';\nconst marker = `vercel.ai.error.${name}`;\nconst symbol = Symbol.for(marker);\n\n/**\n * Thrown when a sandbox provider cannot authenticate or authorize the\n * operation needed to create or resume a harness sandbox. Providers should\n * preserve the underlying SDK failure as `cause` and supply a message that\n * explains how the consumer can configure credentials.\n */\nexport class HarnessSandboxAuthenticationError extends HarnessError {\n private readonly [symbol] = true;\n\n readonly sandboxProviderId: string;\n\n constructor({\n message,\n sandboxProviderId,\n cause,\n }: {\n message: string;\n sandboxProviderId: string;\n cause?: unknown;\n }) {\n super({ message, cause });\n Object.defineProperty(this, 'name', { value: name });\n this.sandboxProviderId = sandboxProviderId;\n }\n\n static isInstance(\n error: unknown,\n ): error is HarnessSandboxAuthenticationError {\n return AISDKError.hasMarker(error, marker);\n }\n}\n"],"mappings":";AAAA,SAAS,YAA4C;AACrD,SAAS,SAAS;AAWX,IAAM,2BAA2B;AAAA,EACtC,MAAM,KAAK;AAAA,IACT,aAAa;AAAA,IACb,aAAa,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;AAAA,IAC/C,cAAc,EAAE,QAAQ;AAAA,EAC1B,CAAC;AAAA,EACD,OAAO,KAAK;AAAA,IACV,aAAa;AAAA,IACb,aAAa,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,GAAG,SAAS,EAAE,OAAO,EAAE,CAAC;AAAA,IACpE,cAAc,EAAE,QAAQ;AAAA,EAC1B,CAAC;AAAA,EACD,MAAM,KAAK;AAAA,IACT,aAAa;AAAA,IACb,aAAa,EAAE,OAAO;AAAA,MACpB,WAAW,EAAE,OAAO;AAAA,MACpB,YAAY,EAAE,OAAO;AAAA,MACrB,YAAY,EAAE,OAAO;AAAA,IACvB,CAAC;AAAA,IACD,cAAc,EAAE,QAAQ;AAAA,EAC1B,CAAC;AAAA,EACD,MAAM,KAAK;AAAA,IACT,aAAa;AAAA,IACb,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;AAAA,IAC7C,cAAc,EAAE,QAAQ;AAAA,EAC1B,CAAC;AAAA,EACD,MAAM,KAAK;AAAA,IACT,aAAa;AAAA,IACb,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;AAAA,IAC7C,cAAc,EAAE,QAAQ;AAAA,EAC1B,CAAC;AAAA,EACD,MAAM,KAAK;AAAA,IACT,aAAa;AAAA,IACb,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;AAAA,IAC7C,cAAc,EAAE,QAAQ;AAAA,EAC1B,CAAC;AAAA,EACD,WAAW,KAAK;AAAA,IACd,aAAa;AAAA,IACb,aAAa,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AAAA,IAC3C,cAAc,EAAE,QAAQ;AAAA,EAC1B,CAAC;AACH;AAIO,IAAM,gCAAgC,OAAO;AAAA,EAClD;AACF;AA6DO,SAAS,WACd,YACA,MAM6E;AAC7E,SAAO;AAAA,IACL,GAAG,KAAK;AAAA,MACN,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA,IACpB,CAAC;AAAA,IACD,YAAY,KAAK;AAAA,IACjB;AAAA,IACA,aAAa,KAAK;AAAA,EACpB;AACF;;;AChIA,SAAS,KAAAA,UAAS;AAiIlB,IAAM,2BAAiDA,GAAE;AAAA,EAAK,MAC5DA,GAAE,MAAM;AAAA,IACNA,GAAE,OAAO;AAAA,IACTA,GAAE,OAAO;AAAA,IACTA,GAAE,QAAQ;AAAA,IACVA,GAAE,KAAK;AAAA,IACPA,GAAE,MAAM,wBAAwB;AAAA,IAChCA,GAAE,OAAOA,GAAE,OAAO,GAAG,wBAAwB;AAAA,EAC/C,CAAC;AACH;AAUA,IAAM,iCACJ;AAEF,IAAM,4BAA4BA,GAAE;AAAA,EAClCA,GAAE,OAAO;AAAA,EACT;AACF;AAEA,IAAM,0BAA0BA,GAAE;AAAA,EAChCA,GAAE,OAAO;AAAA,EACTA,GAAE,OAAOA,GAAE,OAAO,GAAG,wBAAwB;AAC/C;AAEA,IAAM,kCAAkCA,GAAE;AAAA,EACxCA,GAAE,OAAO;AAAA,EACTA,GAAE,OAAOA,GAAE,OAAO,GAAG,wBAAwB;AAC/C;AAEA,IAAM,6BAA6BA,GAAE,MAAM;AAAA,EACzCA,GAAE,OAAO;AAAA,IACP,MAAMA,GAAE,QAAQ,qBAAqB;AAAA,IACrC,SAASA,GAAE,OAAO;AAAA,IAClB,SAASA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,CAAC;AAAA,EACDA,GAAE,OAAO;AAAA,IACP,MAAMA,GAAE,QAAQ,kBAAkB;AAAA,IAClC,MAAMA,GAAE,OAAO;AAAA,IACf,SAASA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,CAAC;AAAA,EACDA,GAAE,OAAO,EAAE,MAAMA,GAAE,QAAQ,OAAO,GAAG,SAASA,GAAE,OAAO,EAAE,CAAC;AAC5D,CAAC;AAED,IAAM,uBAAuBA,GAAE,OAAO;AAAA,EACpC,aAAaA,GAAE,OAAO;AAAA,IACpB,OAAOA,GAAE,OAAO,EAAE,SAAS;AAAA,IAC3B,SAASA,GAAE,OAAO,EAAE,SAAS;AAAA,IAC7B,WAAWA,GAAE,OAAO,EAAE,SAAS;AAAA,IAC/B,YAAYA,GAAE,OAAO,EAAE,SAAS;AAAA,EAClC,CAAC;AAAA,EACD,cAAcA,GAAE,OAAO;AAAA,IACrB,OAAOA,GAAE,OAAO,EAAE,SAAS;AAAA,IAC3B,MAAMA,GAAE,OAAO,EAAE,SAAS;AAAA,IAC1B,WAAWA,GAAE,OAAO,EAAE,SAAS;AAAA,EACjC,CAAC;AAAA,EACD,KAAK,0BAA0B,SAAS;AAC1C,CAAC;AAED,IAAM,8BAA8BA,GAAE,OAAO;AAAA,EAC3C,SAASA,GAAE,KAAK;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAAA,EACD,KAAKA,GAAE,OAAO,EAAE,SAAS;AAC3B,CAAC;AAEM,IAAM,iCAAiCA,GAAE,OAAO;AAAA,EACrD,MAAMA,GAAE,QAAQ,cAAc;AAAA,EAC9B,UAAUA,GAAE,MAAM,0BAA0B,EAAE,SAAS,EAAE,SAAS;AAAA,EAClE,SAASA,GAAE,OAAO,EAAE,SAAS;AAC/B,CAAC;AAEM,IAAM,+BAA+BA,GAAE,OAAO;AAAA,EACnD,MAAMA,GAAE,QAAQ,YAAY;AAAA,EAC5B,IAAIA,GAAE,OAAO;AAAA,EACb,iBAAiB,wBAAwB,SAAS;AACpD,CAAC;AAEM,IAAM,+BAA+BA,GAAE,OAAO;AAAA,EACnD,MAAMA,GAAE,QAAQ,YAAY;AAAA,EAC5B,IAAIA,GAAE,OAAO;AAAA,EACb,OAAOA,GAAE,OAAO;AAAA,EAChB,iBAAiB,wBAAwB,SAAS;AACpD,CAAC;AAEM,IAAM,6BAA6BA,GAAE,OAAO;AAAA,EACjD,MAAMA,GAAE,QAAQ,UAAU;AAAA,EAC1B,IAAIA,GAAE,OAAO;AAAA,EACb,iBAAiB,wBAAwB,SAAS;AACpD,CAAC;AAEM,IAAM,oCAAoCA,GAAE,OAAO;AAAA,EACxD,MAAMA,GAAE,QAAQ,iBAAiB;AAAA,EACjC,IAAIA,GAAE,OAAO;AAAA,EACb,iBAAiB,wBAAwB,SAAS;AACpD,CAAC;AAEM,IAAM,oCAAoCA,GAAE,OAAO;AAAA,EACxD,MAAMA,GAAE,QAAQ,iBAAiB;AAAA,EACjC,IAAIA,GAAE,OAAO;AAAA,EACb,OAAOA,GAAE,OAAO;AAAA,EAChB,iBAAiB,wBAAwB,SAAS;AACpD,CAAC;AAEM,IAAM,kCAAkCA,GAAE,OAAO;AAAA,EACtD,MAAMA,GAAE,QAAQ,eAAe;AAAA,EAC/B,IAAIA,GAAE,OAAO;AAAA,EACb,iBAAiB,wBAAwB,SAAS;AACpD,CAAC;AAEM,IAAM,8BAA8BA,GAAE,OAAO;AAAA,EAClD,MAAMA,GAAE,QAAQ,WAAW;AAAA,EAC3B,YAAYA,GAAE,OAAO;AAAA,EACrB,UAAUA,GAAE,OAAO;AAAA,EACnB,OAAOA,GAAE,OAAO;AAAA,EAChB,kBAAkBA,GAAE,QAAQ,EAAE,SAAS;AAAA,EACvC,SAASA,GAAE,QAAQ,EAAE,SAAS;AAAA,EAC9B,kBAAkB,gCAAgC,SAAS;AAAA,EAC3D,YAAYA,GAAE,OAAO,EAAE,SAAS;AAClC,CAAC;AAEM,IAAM,yCAAyCA,GAAE,OAAO;AAAA,EAC7D,MAAMA,GAAE,QAAQ,uBAAuB;AAAA,EACvC,YAAYA,GAAE,OAAO;AAAA,EACrB,YAAYA,GAAE,OAAO;AAAA,EACrB,kBAAkB,gCAAgC,SAAS;AAC7D,CAAC;AAEM,IAAM,gCAAgCA,GAAE,OAAO;AAAA,EACpD,MAAMA,GAAE,QAAQ,aAAa;AAAA,EAC7B,YAAYA,GAAE,OAAO;AAAA,EACrB,UAAUA,GAAE,OAAO;AAAA,EACnB,QAAQ;AAAA,EACR,SAASA,GAAE,QAAQ,EAAE,SAAS;AAAA,EAC9B,aAAaA,GAAE,QAAQ,EAAE,SAAS;AAAA,EAClC,SAASA,GAAE,QAAQ,EAAE,SAAS;AAAA,EAC9B,kBAAkB,gCAAgC,SAAS;AAC7D,CAAC;AAEM,IAAM,gCAAgCA,GAAE,OAAO;AAAA,EACpD,MAAMA,GAAE,QAAQ,aAAa;AAAA,EAC7B,cAAc;AAAA,EACd,OAAO;AAAA,EACP,iBAAiB,wBAAwB,SAAS;AACpD,CAAC;AAEM,IAAM,4BAA4BA,GAAE,OAAO;AAAA,EAChD,MAAMA,GAAE,QAAQ,QAAQ;AAAA,EACxB,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,iBAAiB,wBAAwB,SAAS;AACpD,CAAC;AAEM,IAAM,gCAAgCA,GAAE,OAAO;AAAA,EACpD,MAAMA,GAAE,QAAQ,aAAa;AAAA,EAC7B,OAAOA,GAAE,KAAK,CAAC,UAAU,UAAU,QAAQ,CAAC;AAAA,EAC5C,MAAMA,GAAE,OAAO;AAAA,EACf,iBAAiB,wBAAwB,SAAS;AACpD,CAAC;AAEM,IAAM,gCAAgCA,GAAE,OAAO;AAAA,EACpD,MAAMA,GAAE,QAAQ,YAAY;AAAA,EAC5B,SAASA,GAAE,KAAK,CAAC,UAAU,MAAM,CAAC;AAAA,EAClC,SAASA,GAAE,OAAO;AAAA,EAClB,cAAcA,GAAE,OAAO,EAAE,SAAS;AAAA,EAClC,aAAaA,GAAE,OAAO,EAAE,SAAS;AAAA,EACjC,iBAAiB,wBAAwB,SAAS;AACpD,CAAC;AAEM,IAAM,2BAA2BA,GAAE,OAAO;AAAA,EAC/C,MAAMA,GAAE,QAAQ,OAAO;AAAA,EACvB,OAAOA,GAAE,QAAQ;AACnB,CAAC;AAEM,IAAM,yBAAyBA,GAAE,OAAO;AAAA,EAC7C,MAAMA,GAAE,QAAQ,KAAK;AAAA,EACrB,UAAUA,GAAE,QAAQ;AACtB,CAAC;AAQM,IAAM,4BAA4BA,GAAE,mBAAmB,QAAQ;AAAA,EACpE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;;;AChWD,SAAS,KAAAC,UAAS;;;ACAlB,SAAS,KAAAC,UAAS;AAeX,IAAM,4BAA4BA,GAAE,KAAK;AAAA,EAC9C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAUM,IAAM,6BAA6BA,GAAE,OAAO;AAAA,EACjD,SAASA,GAAE,QAAQ,EAAE,SAAS;AAAA,EAC9B,OAAO,0BAA0B,SAAS;AAAA,EAC1C,YAAYA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS;AAC3C,CAAC;;;ADyBM,IAAM,gCAAgCC,GAAE,OAAO;AAAA,EACpD,MAAMA,GAAE,OAAO;AAAA,EACf,aAAaA,GAAE,OAAO,EAAE,SAAS;AAAA,EACjC,aAAaA,GAAE,QAAQ,EAAE,SAAS;AACpC,CAAC;AAMM,IAAM,sCAAsCA,GAAE,KAAK;AAAA,EACxD;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,IAAM,4CAA4CA,GAAE;AAAA,EACzD;AAAA,EACA;AAAA,IACEA,GAAE,OAAO;AAAA,MACP,MAAMA,GAAE,QAAQ,OAAO;AAAA,MACvB,WAAWA,GAAE,MAAMA,GAAE,OAAO,CAAC;AAAA,IAC/B,CAAC;AAAA,IACDA,GAAE,OAAO;AAAA,MACP,MAAMA,GAAE,QAAQ,MAAM;AAAA,MACtB,WAAWA,GAAE,MAAMA,GAAE,OAAO,CAAC;AAAA,IAC/B,CAAC;AAAA,EACH;AACF;AAEO,IAAM,sCACXA,GAAE,mBAAmB,QAAQ;AAAA,EAC3BA,GAAE,OAAO,EAAE,MAAMA,GAAE,QAAQ,MAAM,EAAE,CAAC;AAAA,EACpCA,GAAE,OAAO;AAAA,IACP,MAAMA,GAAE,QAAQ,MAAM;AAAA,IACtB,QAAQA,GAAE,OAAOA,GAAE,OAAO,GAAGA,GAAE,KAAK,CAAC,EAAE,SAAS;AAAA,IAChD,MAAMA,GAAE,OAAO,EAAE,SAAS;AAAA,IAC1B,aAAaA,GAAE,OAAO,EAAE,SAAS;AAAA,EACnC,CAAC;AACH,CAAC;AAYI,IAAM,iCAAiCA,GAAE,OAAO;AAAA,EACrD,MAAMA,GAAE,QAAQ,OAAO;AAAA,EACvB,QAAQA,GAAE,OAAO;AAAA,EACjB,OAAOA,GAAE,MAAM,6BAA6B,EAAE,SAAS;AAAA,EACvD,OAAOA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,OAAO,2BAA2B,SAAS;AAAA,EAC3C,gBAAgB,oCAAoC,SAAS;AAAA,EAC7D,sBAAsB,0CAA0C,SAAS;AAAA,EACzE,gBAAgB,oCAAoC,SAAS;AAC/D,CAAC;AAWM,IAAM,6BAA6BA,GAAE,OAAO;AAAA,EACjD,MAAMA,GAAE,QAAQ,cAAc;AAAA,EAC9B,OAAOA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC3B,SAASA,GAAE,OAAO,EAAE,SAAS;AAC/B,CAAC;AAMM,IAAM,4BAA4BA,GAAE,OAAO;AAAA,EAChD,MAAMA,GAAE,QAAQ,aAAa;AAAA,EAC7B,MAAMA,GAAE,QAAQ;AAClB,CAAC;AAMM,IAAM,8BAA8BA,GAAE,OAAO;AAAA,EAClD,MAAMA,GAAE,QAAQ,eAAe;AAAA,EAC/B,UAAUA,GAAE,OAAO;AACrB,CAAC;AASM,IAAM,kCAAkCA,GAAE,OAAO;AAAA,EACtD,MAAMA,GAAE,QAAQ,aAAa;AAAA,EAC7B,QAAQA,GAAE,OAAO;AAAA,EACjB,QAAQA,GAAE,KAAK,CAAC,UAAU,QAAQ,CAAC;AAAA,EACnC,MAAMA,GAAE,OAAO;AACjB,CAAC;AAMM,IAAM,kCAAkCA,GAAE,OAAO;AAAA,EACtD,MAAMA,GAAE,QAAQ,aAAa;AAAA,EAC7B,OAAO;AAAA,EACP,WAAWA,GAAE,OAAO;AAAA,EACpB,SAASA,GAAE,OAAO;AAAA,EAClB,OAAOA,GAAE,OAAOA,GAAE,OAAO,GAAGA,GAAE,QAAQ,CAAC,EAAE,SAAS;AAAA,EAClD,OAAOA,GACJ,OAAO;AAAA,IACN,MAAMA,GAAE,OAAO,EAAE,SAAS;AAAA,IAC1B,SAASA,GAAE,OAAO;AAAA,IAClB,OAAOA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,CAAC,EACA,SAAS;AACd,CAAC;AAOM,IAAM,uCAAuCA,GAAE;AAAA,EACpD;AAAA,EACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAqBO,SAAS,mCACd,OACA,SACqB;AACrB,MAAI,MAAM,SAAS,eAAe;AAChC,WAAO;AAAA,MACL,OAAO,MAAM,WAAW,WAAW,SAAS;AAAA,MAC5C,SAAS,MAAM;AAAA,MACf,WAAW,eAAe,MAAM,MAAM;AAAA,MACtC,MAAM;AAAA,MACN,QAAQ,MAAM;AAAA,MACd,QAAQ,MAAM;AAAA,MACd,WAAW,QAAQ;AAAA,MACnB,WAAW,QAAQ;AAAA,IACrB;AAAA,EACF;AACA,SAAO;AAAA,IACL,OAAO,MAAM;AAAA,IACb,SAAS,MAAM;AAAA,IACf,WAAW,MAAM;AAAA,IACjB,MAAM;AAAA,IACN,OAAO,MAAM;AAAA,IACb,OAAO,MAAM;AAAA,IACb,WAAW,QAAQ;AAAA,IACnB,WAAW,QAAQ;AAAA,EACrB;AACF;AAIO,IAAM,yCAAyCA,GAAE,OAAO;AAAA,EAC7D,MAAMA,GAAE,QAAQ,aAAa;AAAA,EAC7B,YAAYA,GAAE,OAAO;AAAA,EACrB,QAAQA,GAAE,QAAQ;AAAA,EAClB,SAASA,GAAE,QAAQ,EAAE,SAAS;AAChC,CAAC;AAEM,IAAM,mDAAmDA,GAAE,OAAO;AAAA,EACvE,MAAMA,GAAE,QAAQ,wBAAwB;AAAA,EACxC,YAAYA,GAAE,OAAO;AAAA,EACrB,UAAUA,GAAE,QAAQ;AAAA,EACpB,QAAQA,GAAE,OAAO,EAAE,SAAS;AAC9B,CAAC;AAEM,IAAM,0CAA0CA,GAAE,OAAO;AAAA,EAC9D,MAAMA,GAAE,QAAQ,cAAc;AAAA,EAC9B,MAAMA,GAAE,OAAO;AACjB,CAAC;AAEM,IAAM,oCAAoCA,GAAE,OAAO;AAAA,EACxD,MAAMA,GAAE,QAAQ,OAAO;AACzB,CAAC;AAEM,IAAM,sCAAsCA,GAAE,OAAO;AAAA,EAC1D,MAAMA,GAAE,QAAQ,SAAS;AAC3B,CAAC;AAMM,IAAM,qCAAqCA,GAAE,OAAO;AAAA,EACzD,MAAMA,GAAE,QAAQ,QAAQ;AAAA,EACxB,iBAAiBA,GAAE,OAAO;AAC5B,CAAC;AAMM,IAAM,mCAAmCA,GAAE,OAAO;AAAA,EACvD,MAAMA,GAAE,QAAQ,MAAM;AACxB,CAAC;AAOM,IAAM,uCAAuC;AAAA,EAClD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAMO,IAAM,6BAA6BA,GAAE,OAAO;AAAA,EACjD,MAAMA,GAAE,QAAQ,cAAc;AAAA,EAC9B,MAAMA,GAAE,OAAO;AACjB,CAAC;;;AErUM,SAAS,+BAA+B,OAGnC;AACV,MAAI,MAAM,iBAAiB,KAAM,QAAO;AACxC,SAAO,MAAM,cAAc,SAAS,UAChC,MAAM,cAAc,UAAU,SAAS,MAAM,QAAQ,IACrD,CAAC,MAAM,cAAc,UAAU,SAAS,MAAM,QAAQ;AAC5D;AAEO,SAAS,6CAA6C,OAElD;AACT,SAAO,SAAS,MAAM,QAAQ;AAChC;;;ACxBA,SAAS,kBAAkB;AAE3B,IAAM,OAAO;AACb,IAAM,SAAS,mBAAmB,IAAI;AACtC,IAAM,SAAS,OAAO,IAAI,MAAM;AAJhC;AAWO,IAAM,eAAN,eAA2B,iBACd,aADc,IAAW;AAAA,EAG3C,YAAY,EAAE,SAAS,MAAM,GAAyC;AACpE,UAAM,EAAE,MAAM,SAAS,MAAM,CAAC;AAHhC,SAAkB,MAAU;AAAA,EAI5B;AAAA,EAEA,OAAO,WAAW,OAAuC;AACvD,WAAO,WAAW,UAAU,OAAO,MAAM;AAAA,EAC3C;AACF;;;ACrBA,SAAS,cAAAC,mBAAkB;AAG3B,IAAMC,QAAO;AACb,IAAMC,UAAS,mBAAmBD,KAAI;AACtC,IAAME,UAAS,OAAO,IAAID,OAAM;AALhC,IAAAE,KAAAC;AAgBO,IAAM,oCAAN,eAAgDA,MAAA,cACnCD,MAAAD,SADmCE,KAAa;AAAA,EAKlE,YAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAIG;AACD,UAAM,EAAE,SAAS,MAAM,CAAC;AAb1B,SAAkBD,OAAU;AAc1B,WAAO,eAAe,MAAM,QAAQ,EAAE,OAAOH,MAAK,CAAC;AACnD,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,OAAO,WACL,OAC4C;AAC5C,WAAOK,YAAW,UAAU,OAAOJ,OAAM;AAAA,EAC3C;AACF;;;ACxCA,SAAS,cAAAK,mBAAkB;AAG3B,IAAMC,QAAO;AACb,IAAMC,UAAS,mBAAmBD,KAAI;AACtC,IAAME,UAAS,OAAO,IAAID,OAAM;AALhC,IAAAE,KAAAC;AAaO,IAAM,oCAAN,eAAgDA,MAAA,cACnCD,MAAAD,SADmCE,KAAa;AAAA,EAKlE,YAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAIG;AACD,UAAM,EAAE,SAAS,MAAM,CAAC;AAb1B,SAAkBD,OAAU;AAc1B,WAAO,eAAe,MAAM,QAAQ,EAAE,OAAOH,MAAK,CAAC;AACnD,SAAK,oBAAoB;AAAA,EAC3B;AAAA,EAEA,OAAO,WACL,OAC4C;AAC5C,WAAOK,YAAW,UAAU,OAAOJ,OAAM;AAAA,EAC3C;AACF;","names":["z","z","z","z","AISDKError","name","marker","symbol","_a","_b","AISDKError","AISDKError","name","marker","symbol","_a","_b","AISDKError"]}
|
|
1
|
+
{"version":3,"sources":["../src/v1/harness-v1-builtin-tool.ts","../src/v1/harness-v1-stream-part.ts","../src/v1/harness-v1-bridge-protocol.ts","../src/v1/harness-v1-diagnostic.ts","../src/v1/harness-v1-tool-filtering.ts","../src/errors/harness-error.ts","../src/errors/harness-capability-unsupported-error.ts","../src/errors/harness-sandbox-authentication-error.ts"],"sourcesContent":["import { tool, type FlexibleSchema, type Tool } from '@ai-sdk/provider-utils';\nimport { z } from 'zod/v4';\n\n/**\n * Cross-harness vocabulary of common built-in tool names with their baseline\n * input schemas. Adapters that declare a built-in with one of these\n * `commonName`s must accept (at least) every input the baseline schema\n * accepts. Extra optional fields are encouraged.\n *\n * Used both as runtime values (spread into `ToolSet`s for inspection) and as\n * a vocabulary source — `HarnessV1BuiltinToolName` is derived from its keys.\n */\nexport const HARNESS_V1_BUILTIN_TOOLS = {\n read: tool({\n description: 'Read file contents',\n inputSchema: z.object({ file_path: z.string() }),\n outputSchema: z.unknown(),\n }),\n write: tool({\n description: 'Write content to a file',\n inputSchema: z.object({ file_path: z.string(), content: z.string() }),\n outputSchema: z.unknown(),\n }),\n edit: tool({\n description: 'Edit a file by replacing text',\n inputSchema: z.object({\n file_path: z.string(),\n old_string: z.string(),\n new_string: z.string(),\n }),\n outputSchema: z.unknown(),\n }),\n bash: tool({\n description: 'Execute a shell command',\n inputSchema: z.object({ command: z.string() }),\n outputSchema: z.unknown(),\n }),\n grep: tool({\n description: 'Search file contents with regex',\n inputSchema: z.object({ pattern: z.string() }),\n outputSchema: z.unknown(),\n }),\n glob: tool({\n description: 'Find files matching a glob pattern',\n inputSchema: z.object({ pattern: z.string() }),\n outputSchema: z.unknown(),\n }),\n webSearch: tool({\n description: 'Search the web',\n inputSchema: z.object({ query: z.string() }),\n outputSchema: z.unknown(),\n }),\n} as const;\n\nexport type HarnessV1BuiltinToolName = keyof typeof HARNESS_V1_BUILTIN_TOOLS;\n\nexport const HARNESS_V1_BUILTIN_TOOL_NAMES = Object.keys(\n HARNESS_V1_BUILTIN_TOOLS,\n) as ReadonlyArray<HarnessV1BuiltinToolName>;\n\nexport type HarnessV1BuiltinToolUseKind = 'readonly' | 'edit' | 'bash';\n\n/**\n * A tool that the adapter's underlying runtime exposes natively. Extends the\n * AI SDK `Tool` shape with two optional harness-specific fields:\n *\n * - `nativeName`: the name as the underlying runtime knows it. Required\n * only when the tool's key in the harness's `builtinTools` is not the\n * native name — i.e. when the tool maps to a `commonName` (e.g. key\n * `'bash'` for Claude Code's native `'Bash'`). Tools without a common\n * equivalent are keyed by their native name directly, so `nativeName`\n * is redundant and omitted.\n * - `commonName`: cross-harness label drawn from\n * `HARNESS_V1_BUILTIN_TOOL_NAMES`. Set when the tool maps to a familiar\n * capability; consumers use it to recognize, e.g., that Claude Code's\n * `Bash` and Codex's `shell` are the same kind of tool.\n *\n * Always set both fields together via the `commonTool` helper, or neither\n * (declare the tool with the AI SDK's `tool()` directly).\n */\nexport type HarnessV1BuiltinTool<INPUT = unknown, OUTPUT = unknown> = Tool<\n INPUT,\n OUTPUT,\n any\n> & {\n readonly nativeName?: string;\n readonly commonName?: HarnessV1BuiltinToolName;\n readonly toolUseKind?: HarnessV1BuiltinToolUseKind;\n};\n\ntype InputOf<T> = T extends Tool<infer I, any, any> ? I : never;\n\ntype StandardInputOf<N extends HarnessV1BuiltinToolName> = InputOf<\n (typeof HARNESS_V1_BUILTIN_TOOLS)[N]\n>;\n\n/*\n * Type-level superset check. If `TStandard` is assignable to `TAdapter`\n * (i.e. the adapter accepts every input the standard accepts), the return\n * type is `TOk`. Otherwise it's a tagged error tuple that surfaces a clear\n * TypeScript error at the call site.\n */\ntype SupersetCheck<TStandard, TAdapter, TOk> = TStandard extends TAdapter\n ? TOk\n : [\n 'ERROR: adapter input schema must be a superset of the standard schema',\n { expected: TStandard; got: TAdapter },\n ];\n\n/**\n * Declare a built-in tool that maps to a cross-harness common name. The\n * adapter's input schema must accept every input the standard schema for\n * `commonName` accepts. Extra optional fields are encouraged.\n *\n * If the schema is missing a field the standard requires (or has an\n * incompatible type), the return type collapses to a tagged error tuple,\n * which fails the surrounding `as const satisfies ToolSet` assignment and\n * surfaces a readable TypeScript error at the offending entry.\n */\nexport function commonTool<TName extends HarnessV1BuiltinToolName, TInput>(\n commonName: TName,\n opts: {\n readonly nativeName: string;\n readonly toolUseKind?: HarnessV1BuiltinToolUseKind;\n readonly description?: string;\n readonly inputSchema: FlexibleSchema<TInput>;\n },\n): SupersetCheck<StandardInputOf<TName>, TInput, HarnessV1BuiltinTool<TInput>> {\n return {\n ...tool({\n description: opts.description,\n inputSchema: opts.inputSchema as FlexibleSchema<TInput>,\n }),\n nativeName: opts.nativeName,\n commonName,\n toolUseKind: opts.toolUseKind,\n } as never;\n}\n","import type {\n JSONValue,\n LanguageModelV4FinishReason,\n LanguageModelV4ToolApprovalRequest,\n LanguageModelV4ToolCall,\n LanguageModelV4ToolResult,\n LanguageModelV4Usage,\n SharedV4ProviderMetadata,\n} from '@ai-sdk/provider';\nimport { z } from 'zod/v4';\nimport type { HarnessV1CallWarning } from './harness-v1-call-warning';\nimport type { HarnessV1Metadata } from './harness-v1-metadata';\n\n/**\n * One event emitted by a harness adapter during a prompt turn.\n *\n * Mirrors `LanguageModelV4StreamPart` on the variants it shares so a\n * `HarnessAgent` can pipe events through to AI SDK consumers with minimal\n * translation. Primitive types from the V4 spec (`LanguageModelV4ToolCall`,\n * `LanguageModelV4ToolResult`, `LanguageModelV4ToolApprovalRequest`,\n * `LanguageModelV4Usage`, `LanguageModelV4FinishReason`) are reused\n * verbatim — type-compat tests assert this stays the case.\n *\n * The metadata field is named `harnessMetadata` (not `providerMetadata`)\n * because a harness is a peer to a provider, not a kind of provider. The\n * agent rebinds it when forwarding to AI SDK consumers.\n */\nexport type HarnessV1StreamPart =\n | {\n type: 'stream-start';\n warnings?: ReadonlyArray<HarnessV1CallWarning>;\n /**\n * The model the runtime actually resolved to for this turn, when the\n * adapter learns it at stream start (e.g. Claude Code's `init` message\n * reports the resolved/default model). Surfaced into telemetry as\n * `gen_ai.request.model`. Omitted when the adapter doesn't know it here.\n */\n modelId?: string;\n }\n\n // Text blocks\n | { type: 'text-start'; id: string; harnessMetadata?: HarnessV1Metadata }\n | {\n type: 'text-delta';\n id: string;\n delta: string;\n harnessMetadata?: HarnessV1Metadata;\n }\n | { type: 'text-end'; id: string; harnessMetadata?: HarnessV1Metadata }\n\n // Reasoning blocks\n | { type: 'reasoning-start'; id: string; harnessMetadata?: HarnessV1Metadata }\n | {\n type: 'reasoning-delta';\n id: string;\n delta: string;\n harnessMetadata?: HarnessV1Metadata;\n }\n | { type: 'reasoning-end'; id: string; harnessMetadata?: HarnessV1Metadata }\n\n // Tool calls, approvals, results — reuse V4 primitives.\n //\n // `nativeName` is the only harness-only extension on `tool-call`. It lets\n // adapters surface the runtime's native name for a builtin when it differs\n // from the wire `toolName` (e.g. `toolName: 'bash'`, `nativeName: 'Bash'`).\n //\n // Whether the call was executed by the underlying runtime (Claude Code's\n // built-in `Bash`, Codex's `shell`) vs. needs host dispatch is signalled by\n // the standard `providerExecuted` field on `LanguageModelV4ToolCall` —\n // `true` for runtime-executed builtins, false/undefined for host tools.\n | (LanguageModelV4ToolCall & {\n nativeName?: string;\n })\n | LanguageModelV4ToolApprovalRequest\n | LanguageModelV4ToolResult\n\n // Step boundary inside a multi-step turn.\n | {\n type: 'finish-step';\n finishReason: LanguageModelV4FinishReason;\n usage: LanguageModelV4Usage;\n harnessMetadata?: HarnessV1Metadata;\n }\n\n // Turn end.\n | {\n type: 'finish';\n finishReason: LanguageModelV4FinishReason;\n totalUsage: LanguageModelV4Usage;\n harnessMetadata?: HarnessV1Metadata;\n }\n\n // Workspace file mutation that occurred through an opaque underlying\n // mechanism (one with no visible `tool-call` carrying the same data, e.g.\n // Codex's internal `apply_patch`). Emitted per changed path. Path-only by\n // design — when the mutation goes through a visible tool call, the\n // tool-call/tool-result pair already carries the information.\n | {\n type: 'file-change';\n event: 'create' | 'modify' | 'delete';\n path: string;\n harnessMetadata?: HarnessV1Metadata;\n }\n\n // Context compaction performed by the underlying runtime (Claude Code's\n // native compaction, Pi's summarization). Observation only — the runtime\n // owns the compaction; the harness neither implements nor schedules it.\n // Emitted once, on completion, since `summary`/`tokensAfter` only exist then.\n | {\n type: 'compaction';\n trigger: 'manual' | 'auto';\n summary: string;\n tokensBefore?: number;\n tokensAfter?: number;\n harnessMetadata?: HarnessV1Metadata;\n }\n\n // Errors. Multiple may be emitted in a single turn.\n | { type: 'error'; error: unknown }\n\n // Adapter-specific passthrough. Consumers can opt in to receive these via\n // `HarnessAgent` settings; otherwise they are dropped.\n | { type: 'raw'; rawValue: unknown };\n\n/*\n * Runtime (Zod) encoding of `HarnessV1StreamPart`.\n *\n * `HarnessV1StreamPart` is a compile-time type built on `LanguageModelV4*`\n * types that ship no runtime validator. Bridge adapters receive these parts as\n * JSON across a trust boundary (the sandbox WebSocket), so they need a runtime\n * schema. These schemas ARE that encoding — one source of truth, kept from\n * diverging from the type by the `_assignable` guard below and the mutual\n * `toEqualTypeOf` assertion in `harness-v1-stream-part.test-d.ts`.\n *\n * Members are exported individually so `harness-v1-bridge-protocol.ts` can\n * compose them into the bridge outbound union alongside the transport frames.\n */\n\nconst harnessV1JsonValueSchema: z.ZodType<JSONValue> = z.lazy(() =>\n z.union([\n z.string(),\n z.number(),\n z.boolean(),\n z.null(),\n z.array(harnessV1JsonValueSchema),\n z.record(z.string(), harnessV1JsonValueSchema),\n ]),\n);\n\n/*\n * Tool-result values. The inferred type is the spec's `NonNullable<JSONValue>`\n * (matching `LanguageModelV4ToolResult`), but the runtime validator\n * deliberately also accepts `null`: adapters emit `result: <value> ?? null` for\n * tools that produced no output, and that `null` must survive the trust\n * boundary unchanged (it reaches consumers exactly as it did before this schema\n * existed, when a cast hid it). Leniency at runtime, strictness in the type.\n */\nconst harnessV1ToolResultValueSchema =\n harnessV1JsonValueSchema as unknown as z.ZodType<NonNullable<JSONValue>>;\n\nconst harnessV1JsonObjectSchema = z.record(\n z.string(),\n harnessV1JsonValueSchema,\n) as unknown as z.ZodType<Record<string, JSONValue>>;\n\nconst harnessV1MetadataSchema = z.record(\n z.string(),\n z.record(z.string(), harnessV1JsonValueSchema),\n) as unknown as z.ZodType<HarnessV1Metadata>;\n\nconst harnessV1ProviderMetadataSchema = z.record(\n z.string(),\n z.record(z.string(), harnessV1JsonValueSchema),\n) as unknown as z.ZodType<SharedV4ProviderMetadata>;\n\nconst harnessV1CallWarningSchema = z.union([\n z.object({\n type: z.literal('unsupported-setting'),\n setting: z.string(),\n details: z.string().optional(),\n }),\n z.object({\n type: z.literal('unsupported-tool'),\n tool: z.string(),\n details: z.string().optional(),\n }),\n z.object({ type: z.literal('other'), message: z.string() }),\n]) as z.ZodType<HarnessV1CallWarning>;\n\nconst harnessV1UsageSchema = z.object({\n inputTokens: z.object({\n total: z.number().optional(),\n noCache: z.number().optional(),\n cacheRead: z.number().optional(),\n cacheWrite: z.number().optional(),\n }),\n outputTokens: z.object({\n total: z.number().optional(),\n text: z.number().optional(),\n reasoning: z.number().optional(),\n }),\n raw: harnessV1JsonObjectSchema.optional(),\n}) as unknown as z.ZodType<LanguageModelV4Usage>;\n\nconst harnessV1FinishReasonSchema = z.object({\n unified: z.enum([\n 'stop',\n 'length',\n 'content-filter',\n 'tool-calls',\n 'error',\n 'other',\n ]),\n raw: z.string().optional(),\n}) as unknown as z.ZodType<LanguageModelV4FinishReason>;\n\nexport const harnessV1StreamStartPartSchema = z.object({\n type: z.literal('stream-start'),\n warnings: z.array(harnessV1CallWarningSchema).readonly().optional(),\n modelId: z.string().optional(),\n});\n\nexport const harnessV1TextStartPartSchema = z.object({\n type: z.literal('text-start'),\n id: z.string(),\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1TextDeltaPartSchema = z.object({\n type: z.literal('text-delta'),\n id: z.string(),\n delta: z.string(),\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1TextEndPartSchema = z.object({\n type: z.literal('text-end'),\n id: z.string(),\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1ReasoningStartPartSchema = z.object({\n type: z.literal('reasoning-start'),\n id: z.string(),\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1ReasoningDeltaPartSchema = z.object({\n type: z.literal('reasoning-delta'),\n id: z.string(),\n delta: z.string(),\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1ReasoningEndPartSchema = z.object({\n type: z.literal('reasoning-end'),\n id: z.string(),\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1ToolCallPartSchema = z.object({\n type: z.literal('tool-call'),\n toolCallId: z.string(),\n toolName: z.string(),\n input: z.string(),\n providerExecuted: z.boolean().optional(),\n dynamic: z.boolean().optional(),\n providerMetadata: harnessV1ProviderMetadataSchema.optional(),\n nativeName: z.string().optional(),\n});\n\nexport const harnessV1ToolApprovalRequestPartSchema = z.object({\n type: z.literal('tool-approval-request'),\n approvalId: z.string(),\n toolCallId: z.string(),\n providerMetadata: harnessV1ProviderMetadataSchema.optional(),\n});\n\nexport const harnessV1ToolResultPartSchema = z.object({\n type: z.literal('tool-result'),\n toolCallId: z.string(),\n toolName: z.string(),\n result: harnessV1ToolResultValueSchema,\n isError: z.boolean().optional(),\n preliminary: z.boolean().optional(),\n dynamic: z.boolean().optional(),\n providerMetadata: harnessV1ProviderMetadataSchema.optional(),\n});\n\nexport const harnessV1FinishStepPartSchema = z.object({\n type: z.literal('finish-step'),\n finishReason: harnessV1FinishReasonSchema,\n usage: harnessV1UsageSchema,\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1FinishPartSchema = z.object({\n type: z.literal('finish'),\n finishReason: harnessV1FinishReasonSchema,\n totalUsage: harnessV1UsageSchema,\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1FileChangePartSchema = z.object({\n type: z.literal('file-change'),\n event: z.enum(['create', 'modify', 'delete']),\n path: z.string(),\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1CompactionPartSchema = z.object({\n type: z.literal('compaction'),\n trigger: z.enum(['manual', 'auto']),\n summary: z.string(),\n tokensBefore: z.number().optional(),\n tokensAfter: z.number().optional(),\n harnessMetadata: harnessV1MetadataSchema.optional(),\n});\n\nexport const harnessV1ErrorPartSchema = z.object({\n type: z.literal('error'),\n error: z.unknown(),\n});\n\nexport const harnessV1RawPartSchema = z.object({\n type: z.literal('raw'),\n rawValue: z.unknown(),\n});\n\n/**\n * Assembled discriminated union over every `HarnessV1StreamPart` variant. Left\n * un-annotated so it keeps its precise inferred type — the protocol layer\n * composes the individual member schemas, and the type test asserts the\n * inferred union equals `HarnessV1StreamPart`.\n */\nexport const harnessV1StreamPartSchema = z.discriminatedUnion('type', [\n harnessV1StreamStartPartSchema,\n harnessV1TextStartPartSchema,\n harnessV1TextDeltaPartSchema,\n harnessV1TextEndPartSchema,\n harnessV1ReasoningStartPartSchema,\n harnessV1ReasoningDeltaPartSchema,\n harnessV1ReasoningEndPartSchema,\n harnessV1ToolCallPartSchema,\n harnessV1ToolApprovalRequestPartSchema,\n harnessV1ToolResultPartSchema,\n harnessV1FinishStepPartSchema,\n harnessV1FinishPartSchema,\n harnessV1FileChangePartSchema,\n harnessV1CompactionPartSchema,\n harnessV1ErrorPartSchema,\n harnessV1RawPartSchema,\n]);\n\n/*\n * Fail-fast guard at the definition site: the schema's output must be\n * assignable to `HarnessV1StreamPart` (catches a schema variant inventing a\n * shape the type does not allow). The reverse direction — the type being a\n * subset of the schema — is covered by the `toEqualTypeOf` assertion in the\n * type test.\n */\nconst _assignable: z.ZodType<HarnessV1StreamPart> = harnessV1StreamPartSchema;\nvoid _assignable;\n","import { z } from 'zod/v4';\nimport {\n harnessV1DebugConfigSchema,\n harnessV1DebugLevelSchema,\n type HarnessV1Diagnostic,\n} from './harness-v1-diagnostic';\nimport type { HarnessV1ResponseFormat } from './harness-v1-response-format';\nimport {\n harnessV1CompactionPartSchema,\n harnessV1ErrorPartSchema,\n harnessV1FileChangePartSchema,\n harnessV1FinishPartSchema,\n harnessV1FinishStepPartSchema,\n harnessV1RawPartSchema,\n harnessV1ReasoningDeltaPartSchema,\n harnessV1ReasoningEndPartSchema,\n harnessV1ReasoningStartPartSchema,\n harnessV1StreamStartPartSchema,\n harnessV1TextDeltaPartSchema,\n harnessV1TextEndPartSchema,\n harnessV1TextStartPartSchema,\n harnessV1ToolApprovalRequestPartSchema,\n harnessV1ToolCallPartSchema,\n harnessV1ToolResultPartSchema,\n} from './harness-v1-stream-part';\n\n/*\n * The bridge wire protocol shared by every bridge-backed harness adapter.\n *\n * This is the serialization of the host<->runtime contract for adapters that\n * run the agent runtime inside the sandbox and talk to the host over a\n * WebSocket. It exists ONLY because of that transport: untrusted JSON frames\n * crossing the sandbox boundary need runtime validation, the connection needs\n * a handshake, and the host drives turns with serialized commands. Every export\n * here is therefore prefixed `harnessV1Bridge…`.\n *\n * It has three tiers:\n *\n * 1. The OUTBOUND events — `HarnessV1StreamPart` re-expressed as Zod (imported\n * member schemas from `harness-v1-stream-part.ts`), because the part type is\n * compile-time only and the frames need runtime validation at the boundary.\n * 2. The transport/control frames that are NOT consumer events — `bridge-hello`\n * (handshake), `bridge-stop` (runtime resume data), `bridge-thread` (a resume\n * coordinate some runtimes announce). These ride the same socket.\n * 3. The INBOUND command vocabulary the host sends back: the shared commands\n * live here; the per-adapter `start` payload extends\n * `harnessV1BridgeStartBaseSchema` and assembles the final inbound union in\n * the adapter package.\n *\n * Non-bridge adapters (e.g. Pi) do not use this layer at all — they have no\n * serialization boundary and target the universal `HarnessV1StreamPart` type\n * directly. That is the deliberate split: `harness-v1-stream-part.ts` is the\n * transport-agnostic event vocabulary; this file is the bridge transport.\n */\n\n/**\n * The subset of a host-defined tool that travels on the `start` message. The\n * runtime only needs the name, description, and JSON-Schema input to surface\n * the tool; `execute` stays on the host.\n */\nexport const harnessV1BridgeToolWireSchema = z.object({\n name: z.string(),\n description: z.string().optional(),\n inputSchema: z.unknown().optional(),\n});\n\nexport type HarnessV1BridgeToolWire = z.infer<\n typeof harnessV1BridgeToolWireSchema\n>;\n\nexport const harnessV1BridgePermissionModeSchema = z.enum([\n 'allow-reads',\n 'allow-edits',\n 'allow-all',\n]);\n\nexport const harnessV1BridgeBuiltinToolFilteringSchema = z.discriminatedUnion(\n 'mode',\n [\n z.object({\n mode: z.literal('allow'),\n toolNames: z.array(z.string()),\n }),\n z.object({\n mode: z.literal('deny'),\n toolNames: z.array(z.string()),\n }),\n ],\n);\n\nexport const harnessV1BridgeResponseFormatSchema: z.ZodType<HarnessV1ResponseFormat> =\n z.discriminatedUnion('type', [\n z.object({ type: z.literal('text') }),\n z.object({\n type: z.literal('json'),\n schema: z.record(z.string(), z.json()).optional(),\n name: z.string().optional(),\n description: z.string().optional(),\n }),\n ]);\n\n/**\n * Common fields of the inbound `start` message. Each adapter extends this with\n * its runtime-specific configuration (e.g. `thinking`/`continue` for Claude\n * Code, `reasoningEffort`/`webSearch`/`skills`/`resumeThreadId` for Codex) and\n * assembles the final inbound union from the shared command members below.\n *\n * `debug` carries the general `HarnessV1DebugConfig` — diagnostics config is not\n * a bridge concept, it just happens to ride the `start` frame for bridge-backed\n * adapters.\n */\nexport const harnessV1BridgeStartBaseSchema = z.object({\n type: z.literal('start'),\n prompt: z.string(),\n tools: z.array(harnessV1BridgeToolWireSchema).optional(),\n model: z.string().optional(),\n debug: harnessV1DebugConfigSchema.optional(),\n permissionMode: harnessV1BridgePermissionModeSchema.optional(),\n builtinToolFiltering: harnessV1BridgeBuiltinToolFilteringSchema.optional(),\n responseFormat: harnessV1BridgeResponseFormatSchema.optional(),\n});\n\n// --- Transport / control frames (outbound, not consumer events) ---\n\n/**\n * Sent the instant the bridge accepts an authenticated WS connection. The host\n * waits for it before sending `start`/`resume`, because some sandbox runtimes\n * complete the upstream WS handshake before the connection is wired through to\n * the bridge process — anything sent in that gap is dropped. Carries the\n * bridge's lifecycle `state` and highest emitted `seq` for reconnect.\n */\nexport const harnessV1BridgeHelloSchema = z.object({\n type: z.literal('bridge-hello'),\n state: z.string().optional(),\n lastSeq: z.number().optional(),\n capabilities: z\n .object({\n experimental_userMessageResponses: z.boolean().optional(),\n })\n .optional(),\n});\n\nexport const experimental_harnessV1BridgeUserMessageResponseSchema = z.object({\n type: z.literal('user-message-response'),\n messageId: z.string(),\n accepted: z.boolean(),\n error: z.object({ message: z.string() }).optional(),\n});\n\n/**\n * The bridge's reply to an inbound `stop`. Carries the adapter-specific\n * payload the host serializes into lifecycle state `data`.\n */\nexport const harnessV1BridgeStopSchema = z.object({\n type: z.literal('bridge-stop'),\n data: z.unknown(),\n});\n\n/**\n * A resume coordinate the bridge proactively announces (e.g. Codex's thread id)\n * so the host can cache it for a later resume without waiting for `stop`.\n */\nexport const harnessV1BridgeThreadSchema = z.object({\n type: z.literal('bridge-thread'),\n threadId: z.string(),\n});\n\n// --- Diagnostics frames (outbound, not consumer events) ---\n\n/**\n * One captured console line from inside the sandbox. The bridge line-buffers\n * `process.stdout`/`process.stderr` and emits one of these per complete line.\n * Routed host-side to the diagnostics sink, never to the consumer stream.\n */\nexport const harnessV1BridgeSandboxLogSchema = z.object({\n type: z.literal('sandbox-log'),\n source: z.string(),\n stream: z.enum(['stdout', 'stderr']),\n line: z.string(),\n});\n\n/**\n * A structured diagnostic an adapter emits from inside the bridge via\n * `turn.bridgeLog(...)`. Gated by the session's debug level + subsystem filter.\n */\nexport const harnessV1BridgeDebugEventSchema = z.object({\n type: z.literal('debug-event'),\n level: harnessV1DebugLevelSchema,\n subsystem: z.string(),\n message: z.string(),\n attrs: z.record(z.string(), z.unknown()).optional(),\n error: z\n .object({\n name: z.string().optional(),\n message: z.string(),\n stack: z.string().optional(),\n })\n .optional(),\n});\n\n/**\n * Every frame a bridge can send to the host: the stream-part events plus the\n * transport/control frames. This is the schema the host `SandboxChannel`\n * validates inbound frames against.\n */\nexport const harnessV1BridgeOutboundMessageSchema = z.discriminatedUnion(\n 'type',\n [\n harnessV1StreamStartPartSchema,\n harnessV1TextStartPartSchema,\n harnessV1TextDeltaPartSchema,\n harnessV1TextEndPartSchema,\n harnessV1ReasoningStartPartSchema,\n harnessV1ReasoningDeltaPartSchema,\n harnessV1ReasoningEndPartSchema,\n harnessV1ToolCallPartSchema,\n harnessV1ToolApprovalRequestPartSchema,\n harnessV1ToolResultPartSchema,\n harnessV1FinishStepPartSchema,\n harnessV1FinishPartSchema,\n harnessV1FileChangePartSchema,\n harnessV1CompactionPartSchema,\n harnessV1ErrorPartSchema,\n harnessV1RawPartSchema,\n harnessV1BridgeHelloSchema,\n experimental_harnessV1BridgeUserMessageResponseSchema,\n harnessV1BridgeStopSchema,\n harnessV1BridgeThreadSchema,\n harnessV1BridgeSandboxLogSchema,\n harnessV1BridgeDebugEventSchema,\n ],\n);\n\nexport type HarnessV1BridgeOutboundMessage = z.infer<\n typeof harnessV1BridgeOutboundMessageSchema\n>;\n\nexport type Experimental_HarnessV1BridgeUserMessageResponse = z.infer<\n typeof experimental_harnessV1BridgeUserMessageResponseSchema\n>;\n\nexport type HarnessV1BridgeSandboxLog = z.infer<\n typeof harnessV1BridgeSandboxLogSchema\n>;\n\nexport type HarnessV1BridgeDebugEvent = z.infer<\n typeof harnessV1BridgeDebugEventSchema\n>;\n\n/**\n * Normalize a bridge diagnostics wire frame into the transport-agnostic\n * `HarnessV1Diagnostic` an adapter reports to the framework. A captured console\n * line maps `stderr` → `warn` and `stdout` → `info`; a structured event passes\n * its fields through. This is the seam where the bridge's serialization is\n * lifted into the general emission shape every harness shares.\n */\nexport function harnessV1DiagnosticFromBridgeFrame(\n frame: HarnessV1BridgeSandboxLog | HarnessV1BridgeDebugEvent,\n context: { sessionId?: string; timestamp: number },\n): HarnessV1Diagnostic {\n if (frame.type === 'sandbox-log') {\n return {\n level: frame.stream === 'stderr' ? 'warn' : 'info',\n message: frame.line,\n subsystem: `sandbox.log.${frame.source}`,\n kind: 'log',\n source: frame.source,\n stream: frame.stream,\n sessionId: context.sessionId,\n timestamp: context.timestamp,\n };\n }\n return {\n level: frame.level,\n message: frame.message,\n subsystem: frame.subsystem,\n kind: 'event',\n attrs: frame.attrs,\n error: frame.error,\n sessionId: context.sessionId,\n timestamp: context.timestamp,\n };\n}\n\n// --- Shared inbound command members (host -> bridge) ---\n\nexport const harnessV1BridgeToolResultInboundSchema = z.object({\n type: z.literal('tool-result'),\n toolCallId: z.string(),\n output: z.unknown(),\n isError: z.boolean().optional(),\n});\n\nexport const harnessV1BridgeToolApprovalResponseInboundSchema = z.object({\n type: z.literal('tool-approval-response'),\n approvalId: z.string(),\n approved: z.boolean(),\n reason: z.string().optional(),\n});\n\nexport const harnessV1BridgeUserMessageInboundSchema = z.object({\n type: z.literal('user-message'),\n messageId: z.string().optional(),\n text: z.string(),\n});\n\nexport const experimental_harnessV1BridgeUserMessageInboundSchema =\n harnessV1BridgeUserMessageInboundSchema.extend({\n messageId: z.string(),\n });\n\nexport const harnessV1BridgeAbortInboundSchema = z.object({\n type: z.literal('abort'),\n});\n\nexport const harnessV1BridgeDestroyInboundSchema = z.object({\n type: z.literal('destroy'),\n});\n\n/**\n * Reconnect: after re-establishing the socket the host asks the bridge to\n * replay every buffered event with `seq > lastSeenEventId`.\n */\nexport const harnessV1BridgeResumeInboundSchema = z.object({\n type: z.literal('resume'),\n lastSeenEventId: z.number(),\n});\n\n/**\n * The bridge replies with `bridge-stop` carrying any runtime resume data,\n * then exits.\n */\nexport const harnessV1BridgeStopInboundSchema = z.object({\n type: z.literal('stop'),\n});\n\n/**\n * The inbound command members shared by every bridge adapter. Spread these\n * alongside the adapter's own `start` schema to build the final inbound union:\n * `z.discriminatedUnion('type', [adapterStartSchema, ...harnessV1BridgeInboundCommandSchemas])`.\n */\nexport const harnessV1BridgeInboundCommandSchemas = [\n harnessV1BridgeToolResultInboundSchema,\n harnessV1BridgeToolApprovalResponseInboundSchema,\n harnessV1BridgeUserMessageInboundSchema,\n harnessV1BridgeAbortInboundSchema,\n harnessV1BridgeDestroyInboundSchema,\n harnessV1BridgeResumeInboundSchema,\n harnessV1BridgeStopInboundSchema,\n] as const;\n\n/**\n * The JSON line the bridge writes to stdout once its WebSocket server is bound,\n * announcing the port the host should connect to.\n */\nexport const harnessV1BridgeReadySchema = z.object({\n type: z.literal('bridge-ready'),\n port: z.number(),\n});\n\nexport type HarnessV1BridgeReady = z.infer<typeof harnessV1BridgeReadySchema>;\n","import { z } from 'zod/v4';\n\n/*\n * Diagnostics EMISSION contract — part of the `HarnessV1` spec.\n *\n * These are the types a harness adapter produces and receives: an adapter\n * reports a `HarnessV1Diagnostic` to the framework (a bridge adapter normalizes\n * its wire frames into one; a non-bridge adapter constructs one directly), and\n * receives a `HarnessV1DebugConfig` to gate what it emits. They are distinct\n * from the unaffixed host-facing `HarnessDiagnostic` / `HarnessDebugConfig`\n * (the external/telemetry surface) — the framework maps between the two at the\n * boundary, so the emission and consumption surfaces can evolve independently.\n */\n\n/** Severity of a diagnostic, ordered most → least severe. */\nexport const harnessV1DebugLevelSchema = z.enum([\n 'error',\n 'warn',\n 'info',\n 'debug',\n 'trace',\n]);\n\nexport type HarnessV1DebugLevel = z.infer<typeof harnessV1DebugLevelSchema>;\n\n/**\n * Per-session diagnostics configuration the framework hands an adapter (and the\n * host sends on `start.debug`). When absent or `enabled` is false the adapter\n * captures and emits nothing. `subsystems` filters structured events by dotted\n * prefix; console capture is independent of the subsystem filter.\n */\nexport const harnessV1DebugConfigSchema = z.object({\n enabled: z.boolean().optional(),\n level: harnessV1DebugLevelSchema.optional(),\n subsystems: z.array(z.string()).optional(),\n});\n\nexport type HarnessV1DebugConfig = z.infer<typeof harnessV1DebugConfigSchema>;\n\n/**\n * A diagnostic as emitted by a harness adapter. Structurally identical to the\n * host-facing `HarnessDiagnostic` today, but kept separate: this is the spec's\n * emission shape, that is the external consumption shape.\n */\nexport type HarnessV1Diagnostic = {\n /** Severity. */\n readonly level: HarnessV1DebugLevel;\n /** Human-readable line (console capture) or message (structured event). */\n readonly message: string;\n /** Dotted subsystem (`sandbox.log.<source>` for console capture). */\n readonly subsystem: string;\n /** `'log'` = captured console line; `'event'` = structured emission. */\n readonly kind: 'log' | 'event';\n /** Originating source label (console capture). */\n readonly source?: string;\n /** Which standard stream the line came from (console capture). */\n readonly stream?: 'stdout' | 'stderr';\n /** Structured attributes (structured events only). */\n readonly attrs?: Record<string, unknown>;\n /** Error payload (structured events only). */\n readonly error?: { name?: string; message: string; stack?: string };\n /** The harness session this diagnostic originated from. */\n readonly sessionId?: string;\n /** Emission time (epoch ms). */\n readonly timestamp: number;\n};\n","export type HarnessV1BuiltinToolFiltering =\n | {\n mode: 'allow';\n toolNames: string[];\n }\n | {\n mode: 'deny';\n toolNames: string[];\n };\n\nexport function isHarnessV1BuiltinToolIncluded(input: {\n toolName: string;\n toolFiltering: HarnessV1BuiltinToolFiltering | undefined;\n}): boolean {\n if (input.toolFiltering == null) return true;\n return input.toolFiltering.mode === 'allow'\n ? input.toolFiltering.toolNames.includes(input.toolName)\n : !input.toolFiltering.toolNames.includes(input.toolName);\n}\n\nexport function getHarnessV1BuiltinToolFilteringDenialReason(input: {\n toolName: string;\n}): string {\n return `Tool '${input.toolName}' is inactive due to the HarnessAgent tool filtering policy.`;\n}\n","import { AISDKError } from '@ai-sdk/provider';\n\nconst name = 'AI_HarnessError';\nconst marker = `vercel.ai.error.${name}`;\nconst symbol = Symbol.for(marker);\n\n/**\n * Base error type for failures originating in or signalled by a harness\n * adapter. Specific failure modes (e.g. unsupported capability) extend this\n * class.\n */\nexport class HarnessError extends AISDKError {\n private readonly [symbol] = true;\n\n constructor({ message, cause }: { message: string; cause?: unknown }) {\n super({ name, message, cause });\n }\n\n static isInstance(error: unknown): error is HarnessError {\n return AISDKError.hasMarker(error, marker);\n }\n}\n","import { AISDKError } from '@ai-sdk/provider';\nimport { HarnessError } from './harness-error';\n\nconst name = 'AI_HarnessCapabilityUnsupportedError';\nconst marker = `vercel.ai.error.${name}`;\nconst symbol = Symbol.for(marker);\n\n/**\n * Thrown when a caller asks the harness to do something the adapter (or the\n * supplied sandbox) does not support, e.g. requesting manual compaction from\n * an adapter that only auto-compacts, or invoking `getPortEndpoint` on a\n * sandbox that does not expose one.\n *\n * The caller supplies the full human-readable message. Optional `harnessId`\n * is recorded as structured context for tooling.\n */\nexport class HarnessCapabilityUnsupportedError extends HarnessError {\n private readonly [symbol] = true;\n\n readonly harnessId?: string;\n\n constructor({\n message,\n harnessId,\n cause,\n }: {\n message: string;\n harnessId?: string;\n cause?: unknown;\n }) {\n super({ message, cause });\n Object.defineProperty(this, 'name', { value: name });\n this.harnessId = harnessId;\n }\n\n static isInstance(\n error: unknown,\n ): error is HarnessCapabilityUnsupportedError {\n return AISDKError.hasMarker(error, marker);\n }\n}\n","import { AISDKError } from '@ai-sdk/provider';\nimport { HarnessError } from './harness-error';\n\nconst name = 'AI_HarnessSandboxAuthenticationError';\nconst marker = `vercel.ai.error.${name}`;\nconst symbol = Symbol.for(marker);\n\n/**\n * Thrown when a sandbox provider cannot authenticate or authorize the\n * operation needed to create or resume a harness sandbox. Providers should\n * preserve the underlying SDK failure as `cause` and supply a message that\n * explains how the consumer can configure credentials.\n */\nexport class HarnessSandboxAuthenticationError extends HarnessError {\n private readonly [symbol] = true;\n\n readonly sandboxProviderId: string;\n\n constructor({\n message,\n sandboxProviderId,\n cause,\n }: {\n message: string;\n sandboxProviderId: string;\n cause?: unknown;\n }) {\n super({ message, cause });\n Object.defineProperty(this, 'name', { value: name });\n this.sandboxProviderId = sandboxProviderId;\n }\n\n static isInstance(\n error: unknown,\n ): error is HarnessSandboxAuthenticationError {\n return AISDKError.hasMarker(error, marker);\n }\n}\n"],"mappings":"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","names":["z","z","z","z","AISDKError","name","marker","symbol","_a","_b","AISDKError","AISDKError","name","marker","symbol","_a","_b","AISDKError"]}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -97,6 +97,7 @@ declare class SandboxChannel<TOut extends {
|
|
|
97
97
|
private readonly listeners;
|
|
98
98
|
private readonly buffered;
|
|
99
99
|
private readonly onCloseHandlers;
|
|
100
|
+
private readonly onReconnectHandlers;
|
|
100
101
|
private readonly connectThunk;
|
|
101
102
|
private readonly outboundSchema;
|
|
102
103
|
private readonly onDebug;
|
|
@@ -145,6 +146,7 @@ declare class SandboxChannel<TOut extends {
|
|
|
145
146
|
}): Promise<void>;
|
|
146
147
|
on<T extends EventTypeOf<TOut>>(type: T, listener: Listener<TOut, T>): () => void;
|
|
147
148
|
onClose(handler: (code: number, reason: string) => void): void;
|
|
149
|
+
onReconnect(handler: () => void): () => void;
|
|
148
150
|
send(message: TIn): void;
|
|
149
151
|
/**
|
|
150
152
|
* Mark that the host is tearing the session down. The next socket close is
|
|
@@ -181,6 +183,29 @@ declare class SandboxChannel<TOut extends {
|
|
|
181
183
|
private finalizeClose;
|
|
182
184
|
}
|
|
183
185
|
|
|
186
|
+
type Experimental_BridgeUserMessageRequest = {
|
|
187
|
+
type: 'user-message';
|
|
188
|
+
messageId: string;
|
|
189
|
+
text: string;
|
|
190
|
+
};
|
|
191
|
+
type Experimental_BridgeUserMessageResponse = {
|
|
192
|
+
type: 'user-message-response';
|
|
193
|
+
messageId: string;
|
|
194
|
+
accepted: boolean;
|
|
195
|
+
error?: {
|
|
196
|
+
message: string;
|
|
197
|
+
};
|
|
198
|
+
};
|
|
199
|
+
type Experimental_BridgeUserMessageSubmitter = {
|
|
200
|
+
submit(text: string): Promise<void>;
|
|
201
|
+
close(error?: unknown): void;
|
|
202
|
+
};
|
|
203
|
+
declare function experimental_createBridgeUserMessageSubmitter(options: {
|
|
204
|
+
send(message: Experimental_BridgeUserMessageRequest): void;
|
|
205
|
+
onResponse(listener: (response: Experimental_BridgeUserMessageResponse) => void): () => void;
|
|
206
|
+
onReconnect(listener: () => void): () => void;
|
|
207
|
+
}): Experimental_BridgeUserMessageSubmitter;
|
|
208
|
+
|
|
184
209
|
/**
|
|
185
210
|
* Recovery rung selected from an on-disk bridge event log when attach is not
|
|
186
211
|
* possible (the bridge process is gone): `'replay'` when the log holds a
|
|
@@ -208,6 +233,150 @@ declare function getAiGatewayAuthFromEnv({ env, }: {
|
|
|
208
233
|
baseUrl: string;
|
|
209
234
|
};
|
|
210
235
|
|
|
236
|
+
/**
|
|
237
|
+
* Connection details for a sandbox-exposed port. Headers are scoped to the
|
|
238
|
+
* returned URL and must be included when opening the connection.
|
|
239
|
+
*/
|
|
240
|
+
type HarnessV1PortEndpoint = {
|
|
241
|
+
readonly url: string;
|
|
242
|
+
readonly headers?: Readonly<Record<string, string>>;
|
|
243
|
+
};
|
|
244
|
+
/**
|
|
245
|
+
* Network sandbox session returned by `HarnessV1SandboxProvider.createSession()`. The
|
|
246
|
+
* harness keeps this for the lifetime of a session. It is itself a
|
|
247
|
+
* {@link SandboxSession} (file I/O, exec, spawn) and adds the infra surface on
|
|
248
|
+
* top: port resolution, lifecycle, and network-policy mutation.
|
|
249
|
+
*
|
|
250
|
+
* Code that should only touch the filesystem and spawn processes receives the
|
|
251
|
+
* reduced view from {@link HarnessV1NetworkSandboxSession.restricted}, never the
|
|
252
|
+
* network sandbox session itself — so it cannot stop the sandbox, change
|
|
253
|
+
* network access, or transform requests.
|
|
254
|
+
*/
|
|
255
|
+
interface HarnessV1NetworkSandboxSession extends Experimental_SandboxSession {
|
|
256
|
+
/**
|
|
257
|
+
* Stable identifier for the underlying sandbox resource. Used by the
|
|
258
|
+
* harness session manager as the durable lookup key for cross-process
|
|
259
|
+
* resume — the framework persists this on lifecycle state so a future
|
|
260
|
+
* process can call `HarnessV1SandboxProvider.resume?({ sessionId })` and
|
|
261
|
+
* reach the same resource. Providers populate it from their native
|
|
262
|
+
* identifier (Vercel: the sandbox name; just-bash: a UUID minted at
|
|
263
|
+
* create time).
|
|
264
|
+
*/
|
|
265
|
+
readonly id: string;
|
|
266
|
+
/**
|
|
267
|
+
* The sandbox's default working directory — the absolute path that
|
|
268
|
+
* `run`/`spawn` resolve relative commands against when no `workingDirectory`
|
|
269
|
+
* is given. Read from the live sandbox (it is provider-specific and
|
|
270
|
+
* configurable at create time: Vercel defaults to `/vercel/sandbox`,
|
|
271
|
+
* just-bash to `/home/user`), never hardcoded.
|
|
272
|
+
*
|
|
273
|
+
* The framework composes each session's working directory underneath this
|
|
274
|
+
* path (`<defaultWorkingDirectory>/<harnessId>-<sessionId>`) so adapters do
|
|
275
|
+
* not bake a provider-specific base into their own paths.
|
|
276
|
+
*/
|
|
277
|
+
readonly defaultWorkingDirectory: string;
|
|
278
|
+
/** Ports the sandbox exposes; resolvable via `getPortEndpoint`. */
|
|
279
|
+
readonly ports: ReadonlyArray<number>;
|
|
280
|
+
/**
|
|
281
|
+
* Resolve the connection details for a sandbox-exposed port. Bridge-backed
|
|
282
|
+
* adapters call this to open their WebSocket to the in-sandbox bridge.
|
|
283
|
+
*/
|
|
284
|
+
readonly getPortEndpoint: (options: {
|
|
285
|
+
port: number;
|
|
286
|
+
protocol?: 'http' | 'https' | 'ws';
|
|
287
|
+
}) => PromiseLike<HarnessV1PortEndpoint>;
|
|
288
|
+
/**
|
|
289
|
+
* Resolve a publicly-reachable URL for a sandbox-exposed port.
|
|
290
|
+
*
|
|
291
|
+
* @deprecated Use `getPortEndpoint` instead.
|
|
292
|
+
*/
|
|
293
|
+
readonly getPortUrl: (options: {
|
|
294
|
+
port: number;
|
|
295
|
+
protocol?: 'http' | 'https' | 'ws';
|
|
296
|
+
}) => PromiseLike<string>;
|
|
297
|
+
/** Stop the sandbox. Idempotent. */
|
|
298
|
+
readonly stop: () => PromiseLike<void>;
|
|
299
|
+
/**
|
|
300
|
+
* Destroy/delete the sandbox resource when supported. Optional because some
|
|
301
|
+
* providers only have a stop/dispose concept. Implementations must handle
|
|
302
|
+
* both a still-running sandbox and a previously stopped sandbox.
|
|
303
|
+
*/
|
|
304
|
+
readonly destroy?: () => PromiseLike<void>;
|
|
305
|
+
/**
|
|
306
|
+
* Update the sandbox's outbound network policy. Optional — implementations
|
|
307
|
+
* without a local enforcement primitive (e.g. just-bash) omit this. Callers
|
|
308
|
+
* use optional-call (`sandboxSession.setNetworkPolicy?.(policy)`); a
|
|
309
|
+
* missing implementation is a no-op.
|
|
310
|
+
*/
|
|
311
|
+
readonly setNetworkPolicy?: (policy: HarnessV1NetworkPolicy) => PromiseLike<void>;
|
|
312
|
+
/**
|
|
313
|
+
* Replace the sandbox's outbound request-transformation rules. Optional —
|
|
314
|
+
* implementations expose this only when credentials can be injected outside
|
|
315
|
+
* the sandbox security boundary. Calling this method assumes authority over
|
|
316
|
+
* the complete transformation set; harness adapters should normally use
|
|
317
|
+
* `addRequestTransformations` instead. Adapters may preserve legacy
|
|
318
|
+
* credential-forwarding behavior when additive request transformations are
|
|
319
|
+
* unavailable.
|
|
320
|
+
*/
|
|
321
|
+
readonly setRequestTransformations?: (transformations: ReadonlyArray<HarnessV1RequestTransformation>) => PromiseLike<void>;
|
|
322
|
+
/**
|
|
323
|
+
* Add outbound request-transformation rules without replacing rules already
|
|
324
|
+
* managed by the sandbox session. Optional for the same reason as
|
|
325
|
+
* `setRequestTransformations`. Harness adapters should use this additive
|
|
326
|
+
* capability unless they explicitly own the complete transformation set.
|
|
327
|
+
*/
|
|
328
|
+
readonly addRequestTransformations?: (transformations: ReadonlyArray<HarnessV1RequestTransformation>) => PromiseLike<void>;
|
|
329
|
+
/**
|
|
330
|
+
* Replace the set of ports exposed by the sandbox. Full-replacement
|
|
331
|
+
* semantics: ports omitted from the array are deregistered. Optional —
|
|
332
|
+
* implementations that cannot expose ports (e.g. just-bash) omit this.
|
|
333
|
+
*/
|
|
334
|
+
readonly setPorts?: (ports: ReadonlyArray<number>, options?: {
|
|
335
|
+
abortSignal?: AbortSignal;
|
|
336
|
+
}) => PromiseLike<void>;
|
|
337
|
+
/**
|
|
338
|
+
* Reduced view of this session, typed as the bare {@link SandboxSession}
|
|
339
|
+
* (file I/O, exec, spawn) — nothing that could stop the sandbox or change
|
|
340
|
+
* its network policy. Pass this to user-tool `execute()` calls and other
|
|
341
|
+
* code that must not reach the infra surface.
|
|
342
|
+
*
|
|
343
|
+
* The returned object points at exactly the same underlying sandbox
|
|
344
|
+
* resource as the network sandbox session it was produced from; it is only a
|
|
345
|
+
* narrower surface over the same resource, not a separate sandbox. In
|
|
346
|
+
* particular, it cannot mutate network access or request transformations.
|
|
347
|
+
*/
|
|
348
|
+
readonly restricted: () => Experimental_SandboxSession;
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Outbound network policy applied by the sandbox runtime.
|
|
352
|
+
*
|
|
353
|
+
* `'allow-all'` and `'deny-all'` are convenience presets. `'custom'` is an
|
|
354
|
+
* allow-list with an optional CIDR deny-list that takes precedence:
|
|
355
|
+
*
|
|
356
|
+
* - Reachable hosts are the union of `allowedHosts` and `allowedCIDRs`.
|
|
357
|
+
* - `deniedCIDRs` wins over both, useful for blocking cloud-metadata IPs while
|
|
358
|
+
* otherwise allowing broad access.
|
|
359
|
+
*
|
|
360
|
+
* The two `'custom'` branches share the same discriminator but each requires
|
|
361
|
+
* a different allow field. Specifying `'custom'` with only `deniedCIDRs`
|
|
362
|
+
* (deny-only) is rejected at compile time — functionally it would be
|
|
363
|
+
* equivalent to `'deny-all'`.
|
|
364
|
+
*/
|
|
365
|
+
type HarnessV1NetworkPolicy = {
|
|
366
|
+
mode: 'allow-all';
|
|
367
|
+
} | {
|
|
368
|
+
mode: 'deny-all';
|
|
369
|
+
} | {
|
|
370
|
+
mode: 'custom';
|
|
371
|
+
allowedHosts: ReadonlyArray<string>;
|
|
372
|
+
allowedCIDRs?: ReadonlyArray<string>;
|
|
373
|
+
deniedCIDRs?: ReadonlyArray<string>;
|
|
374
|
+
} | {
|
|
375
|
+
mode: 'custom';
|
|
376
|
+
allowedHosts?: ReadonlyArray<string>;
|
|
377
|
+
allowedCIDRs: ReadonlyArray<string>;
|
|
378
|
+
deniedCIDRs?: ReadonlyArray<string>;
|
|
379
|
+
};
|
|
211
380
|
type HarnessV1RequestTransformationPathMatcher = {
|
|
212
381
|
exact: string;
|
|
213
382
|
} | {
|
|
@@ -379,4 +548,11 @@ declare function forwardBridgeProcessStream({ stream, streamName, source, collec
|
|
|
379
548
|
}): Promise<void>;
|
|
380
549
|
declare function drainBridgeProcessStream(stream: ReadableStream<Uint8Array>): Promise<void>;
|
|
381
550
|
|
|
382
|
-
|
|
551
|
+
declare function resolveSandboxDefaultWorkingDirectory({ sandboxSession, abortSignal, }: {
|
|
552
|
+
readonly sandboxSession: HarnessV1NetworkSandboxSession | Experimental_SandboxSession;
|
|
553
|
+
readonly abortSignal?: AbortSignal;
|
|
554
|
+
}): Promise<string>;
|
|
555
|
+
|
|
556
|
+
declare function getRestrictedSandboxSession(sandboxSession: HarnessV1NetworkSandboxSession | Experimental_SandboxSession): Experimental_SandboxSession;
|
|
557
|
+
|
|
558
|
+
export { type BridgeReadyErrorContext, type BridgeReadySource, type DiskLogRecoveryMode, type Experimental_BridgeUserMessageRequest, type Experimental_BridgeUserMessageResponse, type Experimental_BridgeUserMessageSubmitter, SandboxChannel, type SandboxChannelDebugEvent, type SandboxChannelOptions, type SandboxChannelReconnectOptions, type SkillFilePathMode, type WaitForBridgeReadyOptions, type WaitForBridgeReadyResult, type WriteSkillsOptions, classifyDiskLog, createBridgeErrorHandler, createBridgeStartupError, createCredentialRequestTransformation, drainBridgeProcessStream, experimental_createBridgeUserMessageSubmitter, formatBridgeError, forwardBridgeProcessStream, getAiGatewayAuthFromEnv, getRestrictedSandboxSession, logBridgeError, markBridgeStarting, maskSandboxCredentials, resolveSandboxDefaultWorkingDirectory, resolveSandboxHomeDir, shellQuote, waitForBridgeReady, warnCredentialBrokeringUnavailable, writeSkills };
|
package/dist/utils/index.js
CHANGED
|
@@ -16,6 +16,7 @@ var SandboxChannel = class {
|
|
|
16
16
|
this.listeners = /* @__PURE__ */ new Map();
|
|
17
17
|
this.buffered = /* @__PURE__ */ new Map();
|
|
18
18
|
this.onCloseHandlers = /* @__PURE__ */ new Set();
|
|
19
|
+
this.onReconnectHandlers = /* @__PURE__ */ new Set();
|
|
19
20
|
this.connected = false;
|
|
20
21
|
/** Host has begun teardown; suppresses reconnect so a bridge-side close finalises. */
|
|
21
22
|
this.closing = false;
|
|
@@ -99,6 +100,12 @@ var SandboxChannel = class {
|
|
|
99
100
|
onClose(handler) {
|
|
100
101
|
this.onCloseHandlers.add(handler);
|
|
101
102
|
}
|
|
103
|
+
onReconnect(handler) {
|
|
104
|
+
this.onReconnectHandlers.add(handler);
|
|
105
|
+
return () => {
|
|
106
|
+
this.onReconnectHandlers.delete(handler);
|
|
107
|
+
};
|
|
108
|
+
}
|
|
102
109
|
send(message) {
|
|
103
110
|
if (this.terminal) {
|
|
104
111
|
throw new Error(
|
|
@@ -226,6 +233,7 @@ var SandboxChannel = class {
|
|
|
226
233
|
})
|
|
227
234
|
);
|
|
228
235
|
this.flushPending();
|
|
236
|
+
for (const handler of this.onReconnectHandlers) handler();
|
|
229
237
|
(_b = this.onDebug) == null ? void 0 : _b.call(this, {
|
|
230
238
|
event: "reconnected",
|
|
231
239
|
attempt,
|
|
@@ -340,6 +348,69 @@ var SandboxChannel = class {
|
|
|
340
348
|
}
|
|
341
349
|
};
|
|
342
350
|
|
|
351
|
+
// src/utils/bridge-user-message-submitter.ts
|
|
352
|
+
function experimental_createBridgeUserMessageSubmitter(options) {
|
|
353
|
+
const pending = /* @__PURE__ */ new Map();
|
|
354
|
+
let closed = false;
|
|
355
|
+
const send = (request) => {
|
|
356
|
+
try {
|
|
357
|
+
options.send(request);
|
|
358
|
+
} catch (error) {
|
|
359
|
+
const entry = pending.get(request.messageId);
|
|
360
|
+
if (entry == null) return;
|
|
361
|
+
pending.delete(request.messageId);
|
|
362
|
+
entry.reject(error);
|
|
363
|
+
}
|
|
364
|
+
};
|
|
365
|
+
const unsubscribeResponse = options.onResponse((response) => {
|
|
366
|
+
var _a, _b;
|
|
367
|
+
const entry = pending.get(response.messageId);
|
|
368
|
+
if (entry == null) return;
|
|
369
|
+
pending.delete(response.messageId);
|
|
370
|
+
if (response.accepted) {
|
|
371
|
+
entry.resolve();
|
|
372
|
+
} else {
|
|
373
|
+
entry.reject(
|
|
374
|
+
new Error(
|
|
375
|
+
(_b = (_a = response.error) == null ? void 0 : _a.message) != null ? _b : "The runtime rejected the user message."
|
|
376
|
+
)
|
|
377
|
+
);
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
const unsubscribeReconnect = options.onReconnect(() => {
|
|
381
|
+
for (const entry of pending.values()) send(entry.request);
|
|
382
|
+
});
|
|
383
|
+
return {
|
|
384
|
+
submit: (text) => {
|
|
385
|
+
if (closed) {
|
|
386
|
+
return Promise.reject(
|
|
387
|
+
new Error("The bridge turn is no longer accepting user messages.")
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
const messageId = crypto.randomUUID();
|
|
391
|
+
const request = {
|
|
392
|
+
type: "user-message",
|
|
393
|
+
messageId,
|
|
394
|
+
text
|
|
395
|
+
};
|
|
396
|
+
const promise = new Promise((resolve, reject) => {
|
|
397
|
+
pending.set(messageId, { request, resolve, reject });
|
|
398
|
+
});
|
|
399
|
+
send(request);
|
|
400
|
+
return promise;
|
|
401
|
+
},
|
|
402
|
+
close: (error) => {
|
|
403
|
+
if (closed) return;
|
|
404
|
+
closed = true;
|
|
405
|
+
unsubscribeResponse();
|
|
406
|
+
unsubscribeReconnect();
|
|
407
|
+
const reason = error != null ? error : new Error("The bridge turn ended before accepting the user message.");
|
|
408
|
+
for (const entry of pending.values()) entry.reject(reason);
|
|
409
|
+
pending.clear();
|
|
410
|
+
}
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
|
|
343
414
|
// src/utils/classify-disk-log.ts
|
|
344
415
|
import { safeParseJSON as safeParseJSON2 } from "@ai-sdk/provider-utils";
|
|
345
416
|
async function classifyDiskLog(eventLog) {
|
|
@@ -773,7 +844,16 @@ var harnessV1BridgeStartBaseSchema = z3.object({
|
|
|
773
844
|
var harnessV1BridgeHelloSchema = z3.object({
|
|
774
845
|
type: z3.literal("bridge-hello"),
|
|
775
846
|
state: z3.string().optional(),
|
|
776
|
-
lastSeq: z3.number().optional()
|
|
847
|
+
lastSeq: z3.number().optional(),
|
|
848
|
+
capabilities: z3.object({
|
|
849
|
+
experimental_userMessageResponses: z3.boolean().optional()
|
|
850
|
+
}).optional()
|
|
851
|
+
});
|
|
852
|
+
var experimental_harnessV1BridgeUserMessageResponseSchema = z3.object({
|
|
853
|
+
type: z3.literal("user-message-response"),
|
|
854
|
+
messageId: z3.string(),
|
|
855
|
+
accepted: z3.boolean(),
|
|
856
|
+
error: z3.object({ message: z3.string() }).optional()
|
|
777
857
|
});
|
|
778
858
|
var harnessV1BridgeStopSchema = z3.object({
|
|
779
859
|
type: z3.literal("bridge-stop"),
|
|
@@ -821,6 +901,7 @@ var harnessV1BridgeOutboundMessageSchema = z3.discriminatedUnion(
|
|
|
821
901
|
harnessV1ErrorPartSchema,
|
|
822
902
|
harnessV1RawPartSchema,
|
|
823
903
|
harnessV1BridgeHelloSchema,
|
|
904
|
+
experimental_harnessV1BridgeUserMessageResponseSchema,
|
|
824
905
|
harnessV1BridgeStopSchema,
|
|
825
906
|
harnessV1BridgeThreadSchema,
|
|
826
907
|
harnessV1BridgeSandboxLogSchema,
|
|
@@ -841,8 +922,12 @@ var harnessV1BridgeToolApprovalResponseInboundSchema = z3.object({
|
|
|
841
922
|
});
|
|
842
923
|
var harnessV1BridgeUserMessageInboundSchema = z3.object({
|
|
843
924
|
type: z3.literal("user-message"),
|
|
925
|
+
messageId: z3.string().optional(),
|
|
844
926
|
text: z3.string()
|
|
845
927
|
});
|
|
928
|
+
var experimental_harnessV1BridgeUserMessageInboundSchema = harnessV1BridgeUserMessageInboundSchema.extend({
|
|
929
|
+
messageId: z3.string()
|
|
930
|
+
});
|
|
846
931
|
var harnessV1BridgeAbortInboundSchema = z3.object({
|
|
847
932
|
type: z3.literal("abort")
|
|
848
933
|
});
|
|
@@ -1228,6 +1313,38 @@ function lineDecoder2() {
|
|
|
1228
1313
|
function sleep3(ms) {
|
|
1229
1314
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
1230
1315
|
}
|
|
1316
|
+
|
|
1317
|
+
// src/utils/resolve-sandbox-default-working-directory.ts
|
|
1318
|
+
import { posix } from "path";
|
|
1319
|
+
async function resolveSandboxDefaultWorkingDirectory({
|
|
1320
|
+
sandboxSession,
|
|
1321
|
+
abortSignal
|
|
1322
|
+
}) {
|
|
1323
|
+
if ("defaultWorkingDirectory" in sandboxSession) {
|
|
1324
|
+
return sandboxSession.defaultWorkingDirectory;
|
|
1325
|
+
}
|
|
1326
|
+
const result = await sandboxSession.run({
|
|
1327
|
+
command: "pwd",
|
|
1328
|
+
abortSignal
|
|
1329
|
+
});
|
|
1330
|
+
if (result.exitCode !== 0) {
|
|
1331
|
+
throw new Error(
|
|
1332
|
+
`Failed to resolve sandbox default working directory (exit ${result.exitCode}): ${result.stderr || result.stdout}`
|
|
1333
|
+
);
|
|
1334
|
+
}
|
|
1335
|
+
const cwd = result.stdout.trim();
|
|
1336
|
+
if (!posix.isAbsolute(cwd)) {
|
|
1337
|
+
throw new Error(
|
|
1338
|
+
`Failed to resolve sandbox default working directory: expected an absolute path, got ${JSON.stringify(cwd)}.`
|
|
1339
|
+
);
|
|
1340
|
+
}
|
|
1341
|
+
return cwd === "/" ? cwd : cwd.replace(/\/+$/, "");
|
|
1342
|
+
}
|
|
1343
|
+
|
|
1344
|
+
// src/utils/get-restricted-sandbox-session.ts
|
|
1345
|
+
function getRestrictedSandboxSession(sandboxSession) {
|
|
1346
|
+
return "restricted" in sandboxSession ? sandboxSession.restricted() : sandboxSession;
|
|
1347
|
+
}
|
|
1231
1348
|
export {
|
|
1232
1349
|
SandboxChannel,
|
|
1233
1350
|
classifyDiskLog,
|
|
@@ -1235,12 +1352,15 @@ export {
|
|
|
1235
1352
|
createBridgeStartupError,
|
|
1236
1353
|
createCredentialRequestTransformation,
|
|
1237
1354
|
drainBridgeProcessStream,
|
|
1355
|
+
experimental_createBridgeUserMessageSubmitter,
|
|
1238
1356
|
formatBridgeError,
|
|
1239
1357
|
forwardBridgeProcessStream,
|
|
1240
1358
|
getAiGatewayAuthFromEnv,
|
|
1359
|
+
getRestrictedSandboxSession,
|
|
1241
1360
|
logBridgeError,
|
|
1242
1361
|
markBridgeStarting,
|
|
1243
1362
|
maskSandboxCredentials,
|
|
1363
|
+
resolveSandboxDefaultWorkingDirectory,
|
|
1244
1364
|
resolveSandboxHomeDir,
|
|
1245
1365
|
shellQuote,
|
|
1246
1366
|
waitForBridgeReady,
|