@ai-sdk/harness 0.0.0-6b196531-20260710185421

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/CHANGELOG.md +414 -0
  2. package/LICENSE +13 -0
  3. package/README.md +176 -0
  4. package/agent/index.ts +56 -0
  5. package/bridge/index.ts +10 -0
  6. package/dist/agent/index.d.ts +1631 -0
  7. package/dist/agent/index.js +3491 -0
  8. package/dist/agent/index.js.map +1 -0
  9. package/dist/bridge/index.d.ts +129 -0
  10. package/dist/bridge/index.js +482 -0
  11. package/dist/bridge/index.js.map +1 -0
  12. package/dist/index.d.ts +1587 -0
  13. package/dist/index.js +517 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/utils/index.d.ts +329 -0
  16. package/dist/utils/index.js +1241 -0
  17. package/dist/utils/index.js.map +1 -0
  18. package/package.json +100 -0
  19. package/src/agent/harness-agent-session.ts +518 -0
  20. package/src/agent/harness-agent-settings.ts +187 -0
  21. package/src/agent/harness-agent-tool-approval-continuation.ts +94 -0
  22. package/src/agent/harness-agent-tool-types.ts +15 -0
  23. package/src/agent/harness-agent-types.ts +50 -0
  24. package/src/agent/harness-agent.ts +865 -0
  25. package/src/agent/internal/bootstrap-recipe.ts +124 -0
  26. package/src/agent/internal/bridge-port-registry.ts +52 -0
  27. package/src/agent/internal/harness-stream-text-result.ts +731 -0
  28. package/src/agent/internal/lifecycle-state-validation.ts +95 -0
  29. package/src/agent/internal/permission-mode.ts +50 -0
  30. package/src/agent/internal/resolve-observability.ts +128 -0
  31. package/src/agent/internal/run-prompt.ts +901 -0
  32. package/src/agent/internal/sandbox-bootstrap.ts +266 -0
  33. package/src/agent/internal/strip-work-dir.ts +68 -0
  34. package/src/agent/internal/to-harness-stream.ts +75 -0
  35. package/src/agent/internal/tool-filtering.ts +114 -0
  36. package/src/agent/internal/translate-stream-part.ts +221 -0
  37. package/src/agent/internal/turn-telemetry.ts +361 -0
  38. package/src/agent/observability/file-reporter.ts +206 -0
  39. package/src/agent/observability/index.ts +15 -0
  40. package/src/agent/observability/trace-tree-reporter.ts +122 -0
  41. package/src/agent/observability/types.ts +86 -0
  42. package/src/agent/prepare-harness-sandbox-template.ts +68 -0
  43. package/src/agent/prepare-sandbox-for-harness.ts +165 -0
  44. package/src/bridge/index.ts +797 -0
  45. package/src/errors/harness-capability-unsupported-error.ts +41 -0
  46. package/src/errors/harness-error.ts +22 -0
  47. package/src/index.ts +3 -0
  48. package/src/utils/ai-gateway-auth.ts +15 -0
  49. package/src/utils/bridge-diagnostics.ts +213 -0
  50. package/src/utils/bridge-ready.ts +277 -0
  51. package/src/utils/classify-disk-log.ts +43 -0
  52. package/src/utils/index.ts +31 -0
  53. package/src/utils/sandbox-channel.ts +525 -0
  54. package/src/utils/sandbox-home-dir.ts +22 -0
  55. package/src/utils/shell-quote.ts +3 -0
  56. package/src/utils/write-skills.ts +141 -0
  57. package/src/v1/harness-v1-bootstrap.ts +46 -0
  58. package/src/v1/harness-v1-bridge-protocol.ts +342 -0
  59. package/src/v1/harness-v1-builtin-tool.ts +138 -0
  60. package/src/v1/harness-v1-call-warning.ts +22 -0
  61. package/src/v1/harness-v1-diagnostic.ts +66 -0
  62. package/src/v1/harness-v1-lifecycle-state.ts +65 -0
  63. package/src/v1/harness-v1-metadata.ts +13 -0
  64. package/src/v1/harness-v1-network-sandbox-session.ts +123 -0
  65. package/src/v1/harness-v1-observability.ts +20 -0
  66. package/src/v1/harness-v1-permission-mode.ts +11 -0
  67. package/src/v1/harness-v1-prompt-control.ts +41 -0
  68. package/src/v1/harness-v1-prompt.ts +11 -0
  69. package/src/v1/harness-v1-sandbox-provider.ts +76 -0
  70. package/src/v1/harness-v1-session.ts +280 -0
  71. package/src/v1/harness-v1-skill.ts +36 -0
  72. package/src/v1/harness-v1-stream-part.ts +363 -0
  73. package/src/v1/harness-v1-tool-filtering.ts +25 -0
  74. package/src/v1/harness-v1-tool-spec.ts +31 -0
  75. package/src/v1/harness-v1.ts +94 -0
  76. package/src/v1/index.ts +99 -0
  77. package/utils/index.ts +1 -0
@@ -0,0 +1,1587 @@
1
+ import * as _ai_sdk_provider_utils from '@ai-sdk/provider-utils';
2
+ import { Experimental_SandboxSession, UserModelMessage, ToolSet, FlexibleSchema, Tool } from '@ai-sdk/provider-utils';
3
+ import { z } from 'zod/v4';
4
+ import * as _ai_sdk_provider from '@ai-sdk/provider';
5
+ import { JSONValue, LanguageModelV4ToolCall, LanguageModelV4ToolApprovalRequest, LanguageModelV4ToolResult, LanguageModelV4FinishReason, LanguageModelV4Usage, SharedV4ProviderMetadata, JSONSchema7, AISDKError } from '@ai-sdk/provider';
6
+
7
+ /**
8
+ * One file to write into the sandbox as part of an adapter's bootstrap recipe.
9
+ * Paths should live under {@link HarnessV1Bootstrap.bootstrapDir}.
10
+ */
11
+ interface HarnessV1BootstrapFile {
12
+ readonly path: string;
13
+ readonly content: string;
14
+ }
15
+ /**
16
+ * One command to run in the sandbox as part of an adapter's bootstrap recipe.
17
+ * Commands run sequentially after all files have been written; a non-zero exit
18
+ * aborts the bootstrap.
19
+ */
20
+ interface HarnessV1BootstrapCommand {
21
+ readonly command: string;
22
+ readonly workingDirectory?: string;
23
+ }
24
+ /**
25
+ * Adapter-owned bootstrap recipe. The adapter declares the files and commands
26
+ * needed to set up its bridge inside any sandbox. The harness framework hashes
27
+ * the recipe into an identity used by sandbox providers for snapshot-based
28
+ * reuse, and applies the recipe idempotently before the bridge spawns.
29
+ */
30
+ interface HarnessV1Bootstrap {
31
+ /**
32
+ * Stable id of the adapter that owns this recipe. Conventionally matches
33
+ * {@link HarnessV1.harnessId}. Contributes to the recipe hash.
34
+ */
35
+ readonly harnessId: string;
36
+ /**
37
+ * Absolute path inside the sandbox where this recipe writes its state.
38
+ * The marker file lives directly under it. Files declared in {@link files}
39
+ * should also use this prefix so an adapter upgrade can sweep stale state
40
+ * by clearing the directory.
41
+ */
42
+ readonly bootstrapDir: string;
43
+ /** Files to write into the sandbox before any command runs. */
44
+ readonly files: ReadonlyArray<HarnessV1BootstrapFile>;
45
+ /** Commands to run after files are written, in order. */
46
+ readonly commands: ReadonlyArray<HarnessV1BootstrapCommand>;
47
+ }
48
+
49
+ /**
50
+ * Network sandbox session returned by `HarnessV1SandboxProvider.createSession()`. The
51
+ * harness keeps this for the lifetime of a session. It is itself a
52
+ * {@link SandboxSession} (file I/O, exec, spawn) and adds the infra surface on
53
+ * top: port resolution, lifecycle, and network-policy mutation.
54
+ *
55
+ * Code that should only touch the filesystem and spawn processes receives the
56
+ * reduced view from {@link HarnessV1NetworkSandboxSession.restricted}, never the
57
+ * network sandbox session itself — so it cannot stop the sandbox or change its
58
+ * network policy.
59
+ */
60
+ interface HarnessV1NetworkSandboxSession extends Experimental_SandboxSession {
61
+ /**
62
+ * Stable identifier for the underlying sandbox resource. Used by the
63
+ * harness session manager as the durable lookup key for cross-process
64
+ * resume — the framework persists this on lifecycle state so a future
65
+ * process can call `HarnessV1SandboxProvider.resume?({ sessionId })` and
66
+ * reach the same resource. Providers populate it from their native
67
+ * identifier (Vercel: the sandbox name; just-bash: a UUID minted at
68
+ * create time).
69
+ */
70
+ readonly id: string;
71
+ /**
72
+ * The sandbox's default working directory — the absolute path that
73
+ * `run`/`spawn` resolve relative commands against when no `workingDirectory`
74
+ * is given. Read from the live sandbox (it is provider-specific and
75
+ * configurable at create time: Vercel defaults to `/vercel/sandbox`,
76
+ * just-bash to `/home/user`), never hardcoded.
77
+ *
78
+ * The framework composes each session's working directory underneath this
79
+ * path (`<defaultWorkingDirectory>/<harnessId>-<sessionId>`) so adapters do
80
+ * not bake a provider-specific base into their own paths.
81
+ */
82
+ readonly defaultWorkingDirectory: string;
83
+ /** Ports the sandbox exposes; resolvable to public URLs via `getPortUrl`. */
84
+ readonly ports: ReadonlyArray<number>;
85
+ /**
86
+ * Resolve a publicly-reachable URL for a sandbox-exposed port. Bridge-backed
87
+ * adapters call this to open their WebSocket to the in-sandbox bridge.
88
+ */
89
+ readonly getPortUrl: (options: {
90
+ port: number;
91
+ protocol?: 'http' | 'https' | 'ws';
92
+ }) => PromiseLike<string>;
93
+ /** Stop the sandbox. Idempotent. */
94
+ readonly stop: () => PromiseLike<void>;
95
+ /**
96
+ * Destroy/delete the sandbox resource when supported. Optional because some
97
+ * providers only have a stop/dispose concept. Implementations must handle
98
+ * both a still-running sandbox and a previously stopped sandbox.
99
+ */
100
+ readonly destroy?: () => PromiseLike<void>;
101
+ /**
102
+ * Update the sandbox's outbound network policy. Optional — implementations
103
+ * without a local enforcement primitive (e.g. just-bash) omit this. Callers
104
+ * use optional-call (`sandboxSession.setNetworkPolicy?.(policy)`); a
105
+ * missing implementation is a no-op.
106
+ */
107
+ readonly setNetworkPolicy?: (policy: HarnessV1NetworkPolicy) => PromiseLike<void>;
108
+ /**
109
+ * Replace the set of ports exposed by the sandbox. Full-replacement
110
+ * semantics: ports omitted from the array are deregistered. Optional —
111
+ * implementations that cannot expose ports (e.g. just-bash) omit this.
112
+ */
113
+ readonly setPorts?: (ports: ReadonlyArray<number>, options?: {
114
+ abortSignal?: AbortSignal;
115
+ }) => PromiseLike<void>;
116
+ /**
117
+ * Reduced view of this session, typed as the bare {@link SandboxSession}
118
+ * (file I/O, exec, spawn) — nothing that could stop the sandbox or change
119
+ * its network policy. Pass this to user-tool `execute()` calls and other
120
+ * code that must not reach the infra surface.
121
+ *
122
+ * The returned object points at exactly the same underlying sandbox
123
+ * resource as the network sandbox session it was produced from; it is only a
124
+ * narrower surface over the same resource, not a separate sandbox.
125
+ */
126
+ readonly restricted: () => Experimental_SandboxSession;
127
+ }
128
+ /**
129
+ * Outbound network policy applied by the sandbox runtime.
130
+ *
131
+ * `'allow-all'` and `'deny-all'` are convenience presets. `'custom'` is an
132
+ * allow-list with an optional CIDR deny-list that takes precedence:
133
+ *
134
+ * - Reachable hosts are the union of `allowedHosts` and `allowedCIDRs`.
135
+ * - `deniedCIDRs` wins over both, useful for blocking cloud-metadata IPs while
136
+ * otherwise allowing broad access.
137
+ *
138
+ * The two `'custom'` branches share the same discriminator but each requires
139
+ * a different allow field. Specifying `'custom'` with only `deniedCIDRs`
140
+ * (deny-only) is rejected at compile time — functionally it would be
141
+ * equivalent to `'deny-all'`.
142
+ */
143
+ type HarnessV1NetworkPolicy = {
144
+ mode: 'allow-all';
145
+ } | {
146
+ mode: 'deny-all';
147
+ } | {
148
+ mode: 'custom';
149
+ allowedHosts: ReadonlyArray<string>;
150
+ allowedCIDRs?: ReadonlyArray<string>;
151
+ deniedCIDRs?: ReadonlyArray<string>;
152
+ } | {
153
+ mode: 'custom';
154
+ allowedHosts?: ReadonlyArray<string>;
155
+ allowedCIDRs: ReadonlyArray<string>;
156
+ deniedCIDRs?: ReadonlyArray<string>;
157
+ };
158
+
159
+ /** Severity of a diagnostic, ordered most → least severe. */
160
+ declare const harnessV1DebugLevelSchema: z.ZodEnum<{
161
+ error: "error";
162
+ warn: "warn";
163
+ info: "info";
164
+ debug: "debug";
165
+ trace: "trace";
166
+ }>;
167
+ type HarnessV1DebugLevel = z.infer<typeof harnessV1DebugLevelSchema>;
168
+ /**
169
+ * Per-session diagnostics configuration the framework hands an adapter (and the
170
+ * host sends on `start.debug`). When absent or `enabled` is false the adapter
171
+ * captures and emits nothing. `subsystems` filters structured events by dotted
172
+ * prefix; console capture is independent of the subsystem filter.
173
+ */
174
+ declare const harnessV1DebugConfigSchema: z.ZodObject<{
175
+ enabled: z.ZodOptional<z.ZodBoolean>;
176
+ level: z.ZodOptional<z.ZodEnum<{
177
+ error: "error";
178
+ warn: "warn";
179
+ info: "info";
180
+ debug: "debug";
181
+ trace: "trace";
182
+ }>>;
183
+ subsystems: z.ZodOptional<z.ZodArray<z.ZodString>>;
184
+ }, z.core.$strip>;
185
+ type HarnessV1DebugConfig = z.infer<typeof harnessV1DebugConfigSchema>;
186
+ /**
187
+ * A diagnostic as emitted by a harness adapter. Structurally identical to the
188
+ * host-facing `HarnessDiagnostic` today, but kept separate: this is the spec's
189
+ * emission shape, that is the external consumption shape.
190
+ */
191
+ type HarnessV1Diagnostic = {
192
+ /** Severity. */
193
+ readonly level: HarnessV1DebugLevel;
194
+ /** Human-readable line (console capture) or message (structured event). */
195
+ readonly message: string;
196
+ /** Dotted subsystem (`sandbox.log.<source>` for console capture). */
197
+ readonly subsystem: string;
198
+ /** `'log'` = captured console line; `'event'` = structured emission. */
199
+ readonly kind: 'log' | 'event';
200
+ /** Originating source label (console capture). */
201
+ readonly source?: string;
202
+ /** Which standard stream the line came from (console capture). */
203
+ readonly stream?: 'stdout' | 'stderr';
204
+ /** Structured attributes (structured events only). */
205
+ readonly attrs?: Record<string, unknown>;
206
+ /** Error payload (structured events only). */
207
+ readonly error?: {
208
+ name?: string;
209
+ message: string;
210
+ stack?: string;
211
+ };
212
+ /** The harness session this diagnostic originated from. */
213
+ readonly sessionId?: string;
214
+ /** Emission time (epoch ms). */
215
+ readonly timestamp: number;
216
+ };
217
+
218
+ /**
219
+ * Diagnostics wiring the framework hands to an adapter's `doStart`. `report` is
220
+ * the general emission sink: a bridge adapter normalizes each wire frame into a
221
+ * `HarnessV1Diagnostic` (via `harnessV1DiagnosticFromBridgeFrame`) and calls it;
222
+ * a non-bridge adapter constructs a `HarnessV1Diagnostic` from its host-side
223
+ * logs/errors and calls it directly. `debug` gates what the adapter emits.
224
+ * Absent when the consumer has not enabled diagnostics.
225
+ */
226
+ type HarnessV1Observability = {
227
+ /** Per-session debug config gating what the adapter captures/emits. */
228
+ readonly debug?: HarnessV1DebugConfig;
229
+ /** General emission sink — any adapter reports a `HarnessV1Diagnostic` here. */
230
+ readonly report?: (diagnostic: HarnessV1Diagnostic) => void;
231
+ };
232
+
233
+ /**
234
+ * Baseline permission mode for adapter-native built-in tools.
235
+ *
236
+ * Custom host-executed tools are not controlled by this setting. They use
237
+ * `HarnessAgentSettings.toolApproval`, similar to AI SDK's per-tool approval
238
+ * status map.
239
+ */
240
+ type HarnessV1PermissionMode = 'allow-reads' | 'allow-edits' | 'allow-all';
241
+
242
+ /**
243
+ * Prompt shape passed to `HarnessV1Session.doPromptTurn`.
244
+ *
245
+ * A harness session represents an ongoing third-party agent runtime that
246
+ * owns its own conversation history. Each prompt turn carries only the
247
+ * fresh user input for that turn, either as a plain string or as a single
248
+ * `UserModelMessage`.
249
+ */
250
+ type HarnessV1Prompt = string | UserModelMessage;
251
+
252
+ /**
253
+ * Bidirectional control surface returned by `doPromptTurn`.
254
+ *
255
+ * The host uses these methods to feed asynchronous responses back to the
256
+ * adapter while a turn is running. All methods are optional except those
257
+ * the adapter actively supports (host-executed tools require
258
+ * `submitToolResult`; approvals require `submitToolApproval`; mid-turn
259
+ * messages require `submitUserMessage`).
260
+ */
261
+ type HarnessV1PromptControl = {
262
+ /**
263
+ * Provide a result for a `tool-call` the adapter emitted. The adapter
264
+ * forwards the result to the underlying runtime so the model can continue.
265
+ */
266
+ submitToolResult(input: {
267
+ toolCallId: string;
268
+ output: unknown;
269
+ isError?: boolean;
270
+ }): PromiseLike<void>;
271
+ /**
272
+ * Respond to a `tool-approval-request` the adapter emitted.
273
+ */
274
+ submitToolApproval?(input: {
275
+ approvalId: string;
276
+ approved: boolean;
277
+ reason?: string;
278
+ }): PromiseLike<void>;
279
+ /**
280
+ * Inject a fresh user message into a turn that is still in flight.
281
+ * Supported only by runtimes that accept interactive input.
282
+ */
283
+ submitUserMessage?(text: string): PromiseLike<void>;
284
+ /**
285
+ * Resolves when the adapter has finished the turn (success or failure).
286
+ * Rejects with the underlying error when the turn fails.
287
+ */
288
+ readonly done: PromiseLike<void>;
289
+ };
290
+
291
+ type HarnessV1PendingToolApproval = {
292
+ readonly approvalId: string;
293
+ readonly toolCallId: string;
294
+ readonly toolName: string;
295
+ readonly input: string;
296
+ readonly kind: 'builtin' | 'custom';
297
+ readonly providerExecuted?: boolean;
298
+ readonly nativeName?: string;
299
+ };
300
+ type HarnessV1LifecycleStateBase = {
301
+ /**
302
+ * Identifier of the harness that produced this state. Used by adapters to
303
+ * refuse mismatched payloads.
304
+ */
305
+ readonly harnessId: string;
306
+ /**
307
+ * Spec version of the harness that produced this state.
308
+ */
309
+ readonly specificationVersion: 'harness-v1';
310
+ /**
311
+ * Adapter-defined payload. May be persisted as JSON; the adapter is
312
+ * responsible for any necessary encoding.
313
+ */
314
+ readonly data: JSONValue;
315
+ };
316
+ /**
317
+ * Opaque payload returned by between-turn session lifecycle methods and
318
+ * accepted by a future `HarnessV1.doStart({ resumeFrom })` to resume the same
319
+ * underlying session before starting a new turn.
320
+ */
321
+ type HarnessV1ResumeSessionState = HarnessV1LifecycleStateBase & {
322
+ readonly type: 'resume-session';
323
+ /**
324
+ * Optional unfinished-turn state. When present, the session must be resumed
325
+ * before the turn is continued.
326
+ */
327
+ readonly continueFrom?: HarnessV1ContinueTurnState;
328
+ };
329
+ /**
330
+ * Opaque payload returned by `doSuspendTurn` and accepted by a future
331
+ * `HarnessV1.doStart({ continueFrom })` to reconnect to the same session before
332
+ * continuing the interrupted turn.
333
+ */
334
+ type HarnessV1ContinueTurnState = HarnessV1LifecycleStateBase & {
335
+ readonly type: 'continue-turn';
336
+ /**
337
+ * Framework-owned pending approval records. These are intentionally outside
338
+ * adapter-defined `data` so callers can persist the entire lifecycle payload
339
+ * without the harness framework owning storage.
340
+ */
341
+ readonly pendingToolApprovals?: readonly HarnessV1PendingToolApproval[];
342
+ };
343
+ type HarnessV1LifecycleState = HarnessV1ResumeSessionState | HarnessV1ContinueTurnState;
344
+
345
+ /**
346
+ * A self-contained instruction bundle the underlying runtime can load into
347
+ * its context. Adapters decide how to surface skills to the runtime.
348
+ */
349
+ type HarnessV1Skill = {
350
+ /** Stable identifier for the skill (kebab-case slug). */
351
+ readonly name: string;
352
+ /**
353
+ * Short, model-facing description. This is what the runtime sees to
354
+ * decide whether the skill is relevant.
355
+ */
356
+ readonly description: string;
357
+ /** Full skill content the model loads when the skill is active. */
358
+ readonly content: string;
359
+ /**
360
+ * Additional files that belong to this skill. Adapters with native skill
361
+ * directories materialize these next to `SKILL.md`; adapters without native
362
+ * skill files include them with the skill content.
363
+ */
364
+ readonly files?: ReadonlyArray<HarnessV1SkillFile>;
365
+ };
366
+ type HarnessV1SkillFile = {
367
+ /**
368
+ * Skill-relative POSIX path, for example `reference.md` or
369
+ * `references/codes.md`. Absolute paths and `..` segments are rejected by
370
+ * adapters before writing.
371
+ */
372
+ readonly path: string;
373
+ /** UTF-8 text content for the file. */
374
+ readonly content: string;
375
+ };
376
+
377
+ /**
378
+ * Warning emitted by a harness adapter during a call.
379
+ *
380
+ * Surfaces non-fatal issues such as unsupported options or quirks of the
381
+ * underlying agent runtime. Mirrors the shape of `SharedV4Warning` but lives
382
+ * in the harness namespace.
383
+ */
384
+ type HarnessV1CallWarning = {
385
+ type: 'unsupported-setting';
386
+ setting: string;
387
+ details?: string;
388
+ } | {
389
+ type: 'unsupported-tool';
390
+ tool: string;
391
+ details?: string;
392
+ } | {
393
+ type: 'other';
394
+ message: string;
395
+ };
396
+
397
+ /**
398
+ * Adapter-namespaced opaque data attached to harness events.
399
+ *
400
+ * Mirrors the `providerMetadata` pattern from `@ai-sdk/provider`, but lives
401
+ * in the harness namespace because a harness is a peer concept to a
402
+ * provider, not a kind of provider.
403
+ *
404
+ * Keys are harness ids (e.g. `'claude-code'`). Inner values are arbitrary
405
+ * JSON-serializable data the adapter chooses to surface to callers.
406
+ */
407
+ type HarnessV1Metadata = Record<string, Record<string, JSONValue>>;
408
+
409
+ /**
410
+ * One event emitted by a harness adapter during a prompt turn.
411
+ *
412
+ * Mirrors `LanguageModelV4StreamPart` on the variants it shares so a
413
+ * `HarnessAgent` can pipe events through to AI SDK consumers with minimal
414
+ * translation. Primitive types from the V4 spec (`LanguageModelV4ToolCall`,
415
+ * `LanguageModelV4ToolResult`, `LanguageModelV4ToolApprovalRequest`,
416
+ * `LanguageModelV4Usage`, `LanguageModelV4FinishReason`) are reused
417
+ * verbatim — type-compat tests assert this stays the case.
418
+ *
419
+ * The metadata field is named `harnessMetadata` (not `providerMetadata`)
420
+ * because a harness is a peer to a provider, not a kind of provider. The
421
+ * agent rebinds it when forwarding to AI SDK consumers.
422
+ */
423
+ type HarnessV1StreamPart = {
424
+ type: 'stream-start';
425
+ warnings?: ReadonlyArray<HarnessV1CallWarning>;
426
+ /**
427
+ * The model the runtime actually resolved to for this turn, when the
428
+ * adapter learns it at stream start (e.g. Claude Code's `init` message
429
+ * reports the resolved/default model). Surfaced into telemetry as
430
+ * `gen_ai.request.model`. Omitted when the adapter doesn't know it here.
431
+ */
432
+ modelId?: string;
433
+ } | {
434
+ type: 'text-start';
435
+ id: string;
436
+ harnessMetadata?: HarnessV1Metadata;
437
+ } | {
438
+ type: 'text-delta';
439
+ id: string;
440
+ delta: string;
441
+ harnessMetadata?: HarnessV1Metadata;
442
+ } | {
443
+ type: 'text-end';
444
+ id: string;
445
+ harnessMetadata?: HarnessV1Metadata;
446
+ } | {
447
+ type: 'reasoning-start';
448
+ id: string;
449
+ harnessMetadata?: HarnessV1Metadata;
450
+ } | {
451
+ type: 'reasoning-delta';
452
+ id: string;
453
+ delta: string;
454
+ harnessMetadata?: HarnessV1Metadata;
455
+ } | {
456
+ type: 'reasoning-end';
457
+ id: string;
458
+ harnessMetadata?: HarnessV1Metadata;
459
+ } | (LanguageModelV4ToolCall & {
460
+ nativeName?: string;
461
+ }) | LanguageModelV4ToolApprovalRequest | LanguageModelV4ToolResult | {
462
+ type: 'finish-step';
463
+ finishReason: LanguageModelV4FinishReason;
464
+ usage: LanguageModelV4Usage;
465
+ harnessMetadata?: HarnessV1Metadata;
466
+ } | {
467
+ type: 'finish';
468
+ finishReason: LanguageModelV4FinishReason;
469
+ totalUsage: LanguageModelV4Usage;
470
+ harnessMetadata?: HarnessV1Metadata;
471
+ } | {
472
+ type: 'file-change';
473
+ event: 'create' | 'modify' | 'delete';
474
+ path: string;
475
+ harnessMetadata?: HarnessV1Metadata;
476
+ } | {
477
+ type: 'compaction';
478
+ trigger: 'manual' | 'auto';
479
+ summary: string;
480
+ tokensBefore?: number;
481
+ tokensAfter?: number;
482
+ harnessMetadata?: HarnessV1Metadata;
483
+ } | {
484
+ type: 'error';
485
+ error: unknown;
486
+ } | {
487
+ type: 'raw';
488
+ rawValue: unknown;
489
+ };
490
+ declare const harnessV1StreamStartPartSchema: z.ZodObject<{
491
+ type: z.ZodLiteral<"stream-start">;
492
+ warnings: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodType<HarnessV1CallWarning, unknown, z.core.$ZodTypeInternals<HarnessV1CallWarning, unknown>>>>>;
493
+ modelId: z.ZodOptional<z.ZodString>;
494
+ }, z.core.$strip>;
495
+ declare const harnessV1TextStartPartSchema: z.ZodObject<{
496
+ type: z.ZodLiteral<"text-start">;
497
+ id: z.ZodString;
498
+ harnessMetadata: z.ZodOptional<z.ZodType<HarnessV1Metadata, unknown, z.core.$ZodTypeInternals<HarnessV1Metadata, unknown>>>;
499
+ }, z.core.$strip>;
500
+ declare const harnessV1TextDeltaPartSchema: z.ZodObject<{
501
+ type: z.ZodLiteral<"text-delta">;
502
+ id: z.ZodString;
503
+ delta: z.ZodString;
504
+ harnessMetadata: z.ZodOptional<z.ZodType<HarnessV1Metadata, unknown, z.core.$ZodTypeInternals<HarnessV1Metadata, unknown>>>;
505
+ }, z.core.$strip>;
506
+ declare const harnessV1TextEndPartSchema: z.ZodObject<{
507
+ type: z.ZodLiteral<"text-end">;
508
+ id: z.ZodString;
509
+ harnessMetadata: z.ZodOptional<z.ZodType<HarnessV1Metadata, unknown, z.core.$ZodTypeInternals<HarnessV1Metadata, unknown>>>;
510
+ }, z.core.$strip>;
511
+ declare const harnessV1ReasoningStartPartSchema: z.ZodObject<{
512
+ type: z.ZodLiteral<"reasoning-start">;
513
+ id: z.ZodString;
514
+ harnessMetadata: z.ZodOptional<z.ZodType<HarnessV1Metadata, unknown, z.core.$ZodTypeInternals<HarnessV1Metadata, unknown>>>;
515
+ }, z.core.$strip>;
516
+ declare const harnessV1ReasoningDeltaPartSchema: z.ZodObject<{
517
+ type: z.ZodLiteral<"reasoning-delta">;
518
+ id: z.ZodString;
519
+ delta: z.ZodString;
520
+ harnessMetadata: z.ZodOptional<z.ZodType<HarnessV1Metadata, unknown, z.core.$ZodTypeInternals<HarnessV1Metadata, unknown>>>;
521
+ }, z.core.$strip>;
522
+ declare const harnessV1ReasoningEndPartSchema: z.ZodObject<{
523
+ type: z.ZodLiteral<"reasoning-end">;
524
+ id: z.ZodString;
525
+ harnessMetadata: z.ZodOptional<z.ZodType<HarnessV1Metadata, unknown, z.core.$ZodTypeInternals<HarnessV1Metadata, unknown>>>;
526
+ }, z.core.$strip>;
527
+ declare const harnessV1ToolCallPartSchema: z.ZodObject<{
528
+ type: z.ZodLiteral<"tool-call">;
529
+ toolCallId: z.ZodString;
530
+ toolName: z.ZodString;
531
+ input: z.ZodString;
532
+ providerExecuted: z.ZodOptional<z.ZodBoolean>;
533
+ dynamic: z.ZodOptional<z.ZodBoolean>;
534
+ providerMetadata: z.ZodOptional<z.ZodType<SharedV4ProviderMetadata, unknown, z.core.$ZodTypeInternals<SharedV4ProviderMetadata, unknown>>>;
535
+ nativeName: z.ZodOptional<z.ZodString>;
536
+ }, z.core.$strip>;
537
+ declare const harnessV1ToolApprovalRequestPartSchema: z.ZodObject<{
538
+ type: z.ZodLiteral<"tool-approval-request">;
539
+ approvalId: z.ZodString;
540
+ toolCallId: z.ZodString;
541
+ providerMetadata: z.ZodOptional<z.ZodType<SharedV4ProviderMetadata, unknown, z.core.$ZodTypeInternals<SharedV4ProviderMetadata, unknown>>>;
542
+ }, z.core.$strip>;
543
+ declare const harnessV1ToolResultPartSchema: z.ZodObject<{
544
+ type: z.ZodLiteral<"tool-result">;
545
+ toolCallId: z.ZodString;
546
+ toolName: z.ZodString;
547
+ result: z.ZodType<NonNullable<JSONValue>, unknown, z.core.$ZodTypeInternals<NonNullable<JSONValue>, unknown>>;
548
+ isError: z.ZodOptional<z.ZodBoolean>;
549
+ preliminary: z.ZodOptional<z.ZodBoolean>;
550
+ dynamic: z.ZodOptional<z.ZodBoolean>;
551
+ providerMetadata: z.ZodOptional<z.ZodType<SharedV4ProviderMetadata, unknown, z.core.$ZodTypeInternals<SharedV4ProviderMetadata, unknown>>>;
552
+ }, z.core.$strip>;
553
+ declare const harnessV1FinishStepPartSchema: z.ZodObject<{
554
+ type: z.ZodLiteral<"finish-step">;
555
+ finishReason: z.ZodType<LanguageModelV4FinishReason, unknown, z.core.$ZodTypeInternals<LanguageModelV4FinishReason, unknown>>;
556
+ usage: z.ZodType<LanguageModelV4Usage, unknown, z.core.$ZodTypeInternals<LanguageModelV4Usage, unknown>>;
557
+ harnessMetadata: z.ZodOptional<z.ZodType<HarnessV1Metadata, unknown, z.core.$ZodTypeInternals<HarnessV1Metadata, unknown>>>;
558
+ }, z.core.$strip>;
559
+ declare const harnessV1FinishPartSchema: z.ZodObject<{
560
+ type: z.ZodLiteral<"finish">;
561
+ finishReason: z.ZodType<LanguageModelV4FinishReason, unknown, z.core.$ZodTypeInternals<LanguageModelV4FinishReason, unknown>>;
562
+ totalUsage: z.ZodType<LanguageModelV4Usage, unknown, z.core.$ZodTypeInternals<LanguageModelV4Usage, unknown>>;
563
+ harnessMetadata: z.ZodOptional<z.ZodType<HarnessV1Metadata, unknown, z.core.$ZodTypeInternals<HarnessV1Metadata, unknown>>>;
564
+ }, z.core.$strip>;
565
+ declare const harnessV1FileChangePartSchema: z.ZodObject<{
566
+ type: z.ZodLiteral<"file-change">;
567
+ event: z.ZodEnum<{
568
+ create: "create";
569
+ modify: "modify";
570
+ delete: "delete";
571
+ }>;
572
+ path: z.ZodString;
573
+ harnessMetadata: z.ZodOptional<z.ZodType<HarnessV1Metadata, unknown, z.core.$ZodTypeInternals<HarnessV1Metadata, unknown>>>;
574
+ }, z.core.$strip>;
575
+ declare const harnessV1ErrorPartSchema: z.ZodObject<{
576
+ type: z.ZodLiteral<"error">;
577
+ error: z.ZodUnknown;
578
+ }, z.core.$strip>;
579
+ declare const harnessV1RawPartSchema: z.ZodObject<{
580
+ type: z.ZodLiteral<"raw">;
581
+ rawValue: z.ZodUnknown;
582
+ }, z.core.$strip>;
583
+ /**
584
+ * Assembled discriminated union over every `HarnessV1StreamPart` variant. Left
585
+ * un-annotated so it keeps its precise inferred type — the protocol layer
586
+ * composes the individual member schemas, and the type test asserts the
587
+ * inferred union equals `HarnessV1StreamPart`.
588
+ */
589
+ declare const harnessV1StreamPartSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
590
+ type: z.ZodLiteral<"stream-start">;
591
+ warnings: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodType<HarnessV1CallWarning, unknown, z.core.$ZodTypeInternals<HarnessV1CallWarning, unknown>>>>>;
592
+ modelId: z.ZodOptional<z.ZodString>;
593
+ }, z.core.$strip>, z.ZodObject<{
594
+ type: z.ZodLiteral<"text-start">;
595
+ id: z.ZodString;
596
+ harnessMetadata: z.ZodOptional<z.ZodType<HarnessV1Metadata, unknown, z.core.$ZodTypeInternals<HarnessV1Metadata, unknown>>>;
597
+ }, z.core.$strip>, z.ZodObject<{
598
+ type: z.ZodLiteral<"text-delta">;
599
+ id: z.ZodString;
600
+ delta: z.ZodString;
601
+ harnessMetadata: z.ZodOptional<z.ZodType<HarnessV1Metadata, unknown, z.core.$ZodTypeInternals<HarnessV1Metadata, unknown>>>;
602
+ }, z.core.$strip>, z.ZodObject<{
603
+ type: z.ZodLiteral<"text-end">;
604
+ id: z.ZodString;
605
+ harnessMetadata: z.ZodOptional<z.ZodType<HarnessV1Metadata, unknown, z.core.$ZodTypeInternals<HarnessV1Metadata, unknown>>>;
606
+ }, z.core.$strip>, z.ZodObject<{
607
+ type: z.ZodLiteral<"reasoning-start">;
608
+ id: z.ZodString;
609
+ harnessMetadata: z.ZodOptional<z.ZodType<HarnessV1Metadata, unknown, z.core.$ZodTypeInternals<HarnessV1Metadata, unknown>>>;
610
+ }, z.core.$strip>, z.ZodObject<{
611
+ type: z.ZodLiteral<"reasoning-delta">;
612
+ id: z.ZodString;
613
+ delta: z.ZodString;
614
+ harnessMetadata: z.ZodOptional<z.ZodType<HarnessV1Metadata, unknown, z.core.$ZodTypeInternals<HarnessV1Metadata, unknown>>>;
615
+ }, z.core.$strip>, z.ZodObject<{
616
+ type: z.ZodLiteral<"reasoning-end">;
617
+ id: z.ZodString;
618
+ harnessMetadata: z.ZodOptional<z.ZodType<HarnessV1Metadata, unknown, z.core.$ZodTypeInternals<HarnessV1Metadata, unknown>>>;
619
+ }, z.core.$strip>, z.ZodObject<{
620
+ type: z.ZodLiteral<"tool-call">;
621
+ toolCallId: z.ZodString;
622
+ toolName: z.ZodString;
623
+ input: z.ZodString;
624
+ providerExecuted: z.ZodOptional<z.ZodBoolean>;
625
+ dynamic: z.ZodOptional<z.ZodBoolean>;
626
+ providerMetadata: z.ZodOptional<z.ZodType<SharedV4ProviderMetadata, unknown, z.core.$ZodTypeInternals<SharedV4ProviderMetadata, unknown>>>;
627
+ nativeName: z.ZodOptional<z.ZodString>;
628
+ }, z.core.$strip>, z.ZodObject<{
629
+ type: z.ZodLiteral<"tool-approval-request">;
630
+ approvalId: z.ZodString;
631
+ toolCallId: z.ZodString;
632
+ providerMetadata: z.ZodOptional<z.ZodType<SharedV4ProviderMetadata, unknown, z.core.$ZodTypeInternals<SharedV4ProviderMetadata, unknown>>>;
633
+ }, z.core.$strip>, z.ZodObject<{
634
+ type: z.ZodLiteral<"tool-result">;
635
+ toolCallId: z.ZodString;
636
+ toolName: z.ZodString;
637
+ result: z.ZodType<NonNullable<JSONValue>, unknown, z.core.$ZodTypeInternals<NonNullable<JSONValue>, unknown>>;
638
+ isError: z.ZodOptional<z.ZodBoolean>;
639
+ preliminary: z.ZodOptional<z.ZodBoolean>;
640
+ dynamic: z.ZodOptional<z.ZodBoolean>;
641
+ providerMetadata: z.ZodOptional<z.ZodType<SharedV4ProviderMetadata, unknown, z.core.$ZodTypeInternals<SharedV4ProviderMetadata, unknown>>>;
642
+ }, z.core.$strip>, z.ZodObject<{
643
+ type: z.ZodLiteral<"finish-step">;
644
+ finishReason: z.ZodType<LanguageModelV4FinishReason, unknown, z.core.$ZodTypeInternals<LanguageModelV4FinishReason, unknown>>;
645
+ usage: z.ZodType<LanguageModelV4Usage, unknown, z.core.$ZodTypeInternals<LanguageModelV4Usage, unknown>>;
646
+ harnessMetadata: z.ZodOptional<z.ZodType<HarnessV1Metadata, unknown, z.core.$ZodTypeInternals<HarnessV1Metadata, unknown>>>;
647
+ }, z.core.$strip>, z.ZodObject<{
648
+ type: z.ZodLiteral<"finish">;
649
+ finishReason: z.ZodType<LanguageModelV4FinishReason, unknown, z.core.$ZodTypeInternals<LanguageModelV4FinishReason, unknown>>;
650
+ totalUsage: z.ZodType<LanguageModelV4Usage, unknown, z.core.$ZodTypeInternals<LanguageModelV4Usage, unknown>>;
651
+ harnessMetadata: z.ZodOptional<z.ZodType<HarnessV1Metadata, unknown, z.core.$ZodTypeInternals<HarnessV1Metadata, unknown>>>;
652
+ }, z.core.$strip>, z.ZodObject<{
653
+ type: z.ZodLiteral<"file-change">;
654
+ event: z.ZodEnum<{
655
+ create: "create";
656
+ modify: "modify";
657
+ delete: "delete";
658
+ }>;
659
+ path: z.ZodString;
660
+ harnessMetadata: z.ZodOptional<z.ZodType<HarnessV1Metadata, unknown, z.core.$ZodTypeInternals<HarnessV1Metadata, unknown>>>;
661
+ }, z.core.$strip>, z.ZodObject<{
662
+ type: z.ZodLiteral<"compaction">;
663
+ trigger: z.ZodEnum<{
664
+ manual: "manual";
665
+ auto: "auto";
666
+ }>;
667
+ summary: z.ZodString;
668
+ tokensBefore: z.ZodOptional<z.ZodNumber>;
669
+ tokensAfter: z.ZodOptional<z.ZodNumber>;
670
+ harnessMetadata: z.ZodOptional<z.ZodType<HarnessV1Metadata, unknown, z.core.$ZodTypeInternals<HarnessV1Metadata, unknown>>>;
671
+ }, z.core.$strip>, z.ZodObject<{
672
+ type: z.ZodLiteral<"error">;
673
+ error: z.ZodUnknown;
674
+ }, z.core.$strip>, z.ZodObject<{
675
+ type: z.ZodLiteral<"raw">;
676
+ rawValue: z.ZodUnknown;
677
+ }, z.core.$strip>]>;
678
+
679
+ /**
680
+ * Description of a host-defined tool that the harness should make available
681
+ * to the underlying agent runtime.
682
+ *
683
+ * Adapters translate this into whatever shape their runtime expects (e.g.
684
+ * Claude Code's tool definitions, Codex CLI's tool config, an MCP server
685
+ * exposed to the runtime, …). The adapter does not execute the tool; when
686
+ * the runtime calls it, the adapter emits a `tool-call` event and waits for
687
+ * `submitToolResult` from the caller.
688
+ */
689
+ type HarnessV1ToolSpec = {
690
+ /**
691
+ * Tool name the agent runtime sees. Must match the name on incoming
692
+ * `tool-call` events.
693
+ */
694
+ readonly name: string;
695
+ /**
696
+ * Human-readable description handed to the runtime, used to help the model
697
+ * decide when to call the tool.
698
+ */
699
+ readonly description?: string;
700
+ /**
701
+ * JSON Schema describing the expected input for the tool. Optional because
702
+ * some runtimes accept tools without schemas (free-form arguments).
703
+ */
704
+ readonly inputSchema?: JSONSchema7;
705
+ };
706
+
707
+ type HarnessV1BuiltinToolFiltering = {
708
+ mode: 'allow';
709
+ toolNames: string[];
710
+ } | {
711
+ mode: 'deny';
712
+ toolNames: string[];
713
+ };
714
+ declare function isHarnessV1BuiltinToolIncluded(input: {
715
+ toolName: string;
716
+ toolFiltering: HarnessV1BuiltinToolFiltering | undefined;
717
+ }): boolean;
718
+ declare function getHarnessV1BuiltinToolFilteringDenialReason(input: {
719
+ toolName: string;
720
+ }): string;
721
+
722
+ /**
723
+ * Options passed to `HarnessV1.doStart`.
724
+ *
725
+ * `sandboxSession` and `sessionWorkDir` are coupled and always present. The
726
+ * framework creates the sandbox and per-session working directory before
727
+ * calling the adapter, so adapters never need to derive provider-specific paths.
728
+ */
729
+ type HarnessV1StartOptions = {
730
+ /**
731
+ * Stable identifier for this harness session. Used as the underlying
732
+ * resource name where the adapter has a notion of a named session
733
+ * (sandbox name, native session id, …).
734
+ */
735
+ readonly sessionId: string;
736
+ /**
737
+ * Skills made available to the underlying runtime for the lifetime of
738
+ * the session. Adapters decide how to surface them.
739
+ */
740
+ readonly skills?: ReadonlyArray<HarnessV1Skill>;
741
+ /**
742
+ * Optional resume payload returned by a prior session lifecycle method. When
743
+ * provided, the adapter should resume the existing session before accepting a
744
+ * new prompt or continuing a nested unfinished turn.
745
+ */
746
+ readonly resumeFrom?: HarnessV1ResumeSessionState;
747
+ /**
748
+ * Optional continuation payload returned by `doSuspendTurn`, or nested in
749
+ * `resumeFrom`. When provided, the adapter should resume the existing session
750
+ * in a shape ready for `doContinueTurn` rather than for a fresh prompt.
751
+ */
752
+ readonly continueFrom?: HarnessV1ContinueTurnState;
753
+ /**
754
+ * Approval policy for built-in adapter-native tool use. Custom host-executed
755
+ * tools are approved by the framework before results are submitted back to
756
+ * the adapter.
757
+ */
758
+ readonly permissionMode?: HarnessV1PermissionMode;
759
+ /**
760
+ * Adapter-native built-in tools that should be available for this session.
761
+ * Custom host-executed tools are filtered by the framework before they reach
762
+ * the adapter.
763
+ */
764
+ readonly builtinToolFiltering?: HarnessV1BuiltinToolFiltering;
765
+ /**
766
+ * Signal that aborts startup. The adapter must propagate cancellation to
767
+ * any spawned processes or network calls.
768
+ */
769
+ readonly abortSignal?: AbortSignal;
770
+ /**
771
+ * Diagnostics wiring. The framework populates this; the adapter only
772
+ * forwards `observability.onDiagnostic` into its `SandboxChannel` and
773
+ * `observability.debug` into the bridge `start` message. Absent when the
774
+ * consumer has not enabled diagnostics.
775
+ */
776
+ readonly observability?: HarnessV1Observability;
777
+ /**
778
+ * Network sandbox session the adapter operates against. It is owned and
779
+ * lifecycled by `HarnessAgent`. Adapters call `restricted()` for the
780
+ * tool-safe filesystem/exec/spawn surface, and use the infra methods
781
+ * (`getPortUrl`, `ports`, `setNetworkPolicy`) for bridge wiring. Adapters
782
+ * must not call `stop()` themselves; the agent does that during cleanup.
783
+ */
784
+ readonly sandboxSession: HarnessV1NetworkSandboxSession;
785
+ /**
786
+ * Absolute path the adapter runs the agent in for this session. Composed by
787
+ * the framework as `<sandboxSession.defaultWorkingDirectory>/<harnessId>-<sessionId>`
788
+ * and created before `doStart`, so the adapter uses it directly instead of
789
+ * deriving its own provider-specific path.
790
+ */
791
+ readonly sessionWorkDir: string;
792
+ };
793
+ /**
794
+ * Options passed to `HarnessV1Session.doPromptTurn`.
795
+ */
796
+ type HarnessV1PromptTurnOptions = {
797
+ /**
798
+ * Fresh input for this turn — either a plain string or a single
799
+ * `ModelMessage`. The harness session owns its own conversation history,
800
+ * so prior turns are never replayed across the contract.
801
+ */
802
+ readonly prompt: HarnessV1Prompt;
803
+ /**
804
+ * Host-defined tools to make available to the underlying runtime for this
805
+ * turn. The harness emits `tool-call` events when the runtime calls one
806
+ * and waits for `submitToolResult`.
807
+ */
808
+ readonly tools?: ReadonlyArray<HarnessV1ToolSpec>;
809
+ /**
810
+ * Free-form instructions for the session. The framework supplies the same
811
+ * value on every turn; the adapter is responsible for applying it once, by
812
+ * prepending it to the first user message of a fresh (non-resumed) session.
813
+ * On a resumed session the adapter must not re-apply it — the original first
814
+ * message already carried it and lives in the runtime's persisted history.
815
+ */
816
+ readonly instructions?: string;
817
+ /**
818
+ * Signal that aborts the in-flight turn. The adapter must cancel any
819
+ * underlying work and resolve `done` (with an error if appropriate).
820
+ */
821
+ readonly abortSignal?: AbortSignal;
822
+ /**
823
+ * Callback invoked once for each event the adapter produces during the
824
+ * turn. The adapter is responsible for the ordering and completeness of
825
+ * events. `done` resolves once the adapter has emitted all events for the
826
+ * turn (success or failure).
827
+ */
828
+ readonly emit: (event: HarnessV1StreamPart) => void;
829
+ };
830
+ /**
831
+ * Options passed to `HarnessV1Session.doContinueTurn`.
832
+ *
833
+ * Unlike `doPromptTurn`, there is no `prompt`: `doContinueTurn` continues the
834
+ * in-flight turn rather than starting a new one. It is used to continue a turn
835
+ * that was previously suspended temporarily, e.g. by the workflow slice loop.
836
+ */
837
+ type HarnessV1ContinueTurnOptions = {
838
+ /**
839
+ * Host-defined tools to make available for the continued turn. Same shape
840
+ * as `doPromptTurn`'s `tools`. An adapter that purely attaches to a live turn
841
+ * may ignore them; an adapter that re-drives the turn (rerun) needs them.
842
+ */
843
+ readonly tools?: ReadonlyArray<HarnessV1ToolSpec>;
844
+ /**
845
+ * Signal that aborts the continued turn. The adapter must cancel any
846
+ * underlying work and resolve `done` (with an error if appropriate).
847
+ */
848
+ readonly abortSignal?: AbortSignal;
849
+ /**
850
+ * Callback invoked once for each event the adapter produces while the
851
+ * continued turn runs. Same contract as `doPromptTurn`'s `emit`.
852
+ */
853
+ readonly emit: (event: HarnessV1StreamPart) => void;
854
+ };
855
+ /**
856
+ * Active harness session, returned by `HarnessV1.doStart`.
857
+ *
858
+ * A session is the unit of state continuity across multiple prompts (one
859
+ * sandbox, one conversation history, one running agent runtime). The host
860
+ * holds onto the session across `doPromptTurn` calls and ends the local
861
+ * instance via `doDetach`, `doStop`, or `doDestroy`.
862
+ */
863
+ type HarnessV1Session = {
864
+ /**
865
+ * Stable identifier for this session. Same value the host passed in via
866
+ * `HarnessV1StartOptions.sessionId`.
867
+ */
868
+ readonly sessionId: string;
869
+ /**
870
+ * Whether this session was created from `resumeFrom` or `continueFrom`. Fresh
871
+ * sessions report `false`; resumed sessions report `true`.
872
+ */
873
+ readonly isResume: boolean;
874
+ /**
875
+ * The model id the underlying runtime is configured to use, if the adapter
876
+ * knows it (e.g. from its settings). Surfaced into telemetry as
877
+ * `gen_ai.request.model` and the trace span labels. Omitted when the adapter
878
+ * defers to the runtime's own default and has no concrete id.
879
+ */
880
+ readonly modelId?: string;
881
+ /**
882
+ * Run one prompt turn. Returns a control handle the host uses to feed
883
+ * tool results, approvals, and user messages back into the turn while it
884
+ * is in flight. The handle's `done` promise resolves when the turn ends.
885
+ */
886
+ doPromptTurn(options: HarnessV1PromptTurnOptions): PromiseLike<HarnessV1PromptControl>;
887
+ /**
888
+ * Request that the underlying runtime compact its context. The runtime owns
889
+ * the compaction — the harness neither implements nor schedules it; this is
890
+ * only the trigger. When compaction completes, the adapter surfaces a
891
+ * `compaction` stream part on the next/active turn.
892
+ *
893
+ * Required, but not every runtime can honour it: adapters whose transport
894
+ * exposes no manual compaction (e.g. Codex over `codex exec`, which still
895
+ * auto-compacts on its own) throw `HarnessCapabilityUnsupportedError`.
896
+ * `customInstructions`, when supported, steer the compaction summary.
897
+ */
898
+ doCompact(customInstructions?: string): PromiseLike<void>;
899
+ /**
900
+ * Continue the in-flight turn **without a new user prompt**, returning the
901
+ * same control surface as `doPromptTurn`. Used to keep consuming a turn that
902
+ * was interrupted at a process boundary (the workflow slice loop), after the
903
+ * session itself has been resumed via `doStart({ continueFrom })`:
904
+ *
905
+ * - When the runtime's turn is still live and reachable (bridge `attach` /
906
+ * `replay`), the adapter subscribes to its events and resolves `done` on
907
+ * the turn's `finish` — **without** re-driving it. Lossless.
908
+ * - When the live turn is gone (bridge respawned `rerun`, or a host-resident
909
+ * runtime like Pi whose turn cannot survive its process), the adapter
910
+ * re-drives the runtime's own thread from its persisted state. Lossy: work
911
+ * in flight at the interruption is recomputed.
912
+ *
913
+ * Required on every adapter. The behaviour an adapter can guarantee follows
914
+ * from its architecture; the contract is uniform.
915
+ */
916
+ doContinueTurn(options: HarnessV1ContinueTurnOptions): PromiseLike<HarnessV1PromptControl>;
917
+ /**
918
+ * Gracefully freeze the active turn **at a precise cursor while keeping the
919
+ * runtime alive**, returning the continuation payload.
920
+ *
921
+ * This is the slice-boundary primitive. The adapter stops host-side
922
+ * consumption of the in-flight turn without telling the runtime to stop:
923
+ * for a bridge adapter it closes the host socket (the bridge keeps the turn
924
+ * running and accumulates events for replay) and resolves the active
925
+ * `doPromptTurn`/`doContinueTurn` `done` **cleanly** (not as an error) once buffered
926
+ * events have drained, so the cursor in the returned state equals the last
927
+ * event delivered to the host — guaranteeing the next slice's attach replays
928
+ * with no gap and no duplicate. A host-resident adapter (Pi) cannot keep its
929
+ * turn alive, so it persists what it can and the in-flight tail is recomputed
930
+ * on continue.
931
+ *
932
+ * Like `doDetach`, the sandbox/runtime is left running. Unlike `doDetach`,
933
+ * this is for an active turn at a slice boundary rather than a between-turn
934
+ * session handoff. Required on every adapter.
935
+ */
936
+ doSuspendTurn(): PromiseLike<HarnessV1ContinueTurnState>;
937
+ /**
938
+ * Detach from the underlying runtime without tearing it down, returning a
939
+ * payload the host can later pass to
940
+ * `HarnessV1.doStart({ resumeFrom })` to reconnect before a new turn. After
941
+ * `doDetach`, no further methods on this session instance may be called.
942
+ *
943
+ * Required. Adapters that cannot keep a live runtime parked still return the
944
+ * best resume session state they can while leaving the sandbox running.
945
+ */
946
+ doDetach(): PromiseLike<HarnessV1ResumeSessionState>;
947
+ /**
948
+ * Persist enough state to resume later, then stop the underlying runtime.
949
+ * After `doStop`, no further methods on this session instance may be called.
950
+ */
951
+ doStop(): PromiseLike<HarnessV1ResumeSessionState>;
952
+ /**
953
+ * Stop the underlying runtime without returning lifecycle state. After
954
+ * `doDestroy`, no further methods on this session instance may be called.
955
+ */
956
+ doDestroy(): PromiseLike<void>;
957
+ };
958
+
959
+ /**
960
+ * Versioned specification for a harness adapter — the integration point for
961
+ * one third-party coding-agent runtime (Claude Code, Codex, …).
962
+ *
963
+ * Modelled after `LanguageModelV4`: a tagged spec version, a small set of
964
+ * descriptive fields, and one entry-point method (`doStart`) that yields a
965
+ * session. There is intentionally no static "capabilities" object —
966
+ * optional features are signalled by the presence or absence of optional
967
+ * methods on the prompt-control handle. Adapters that cannot satisfy a request
968
+ * (manual compaction not supported, required port exposure unavailable, …)
969
+ * throw `HarnessCapabilityUnsupportedError` from the method that needs the
970
+ * capability.
971
+ */
972
+ type HarnessV1<TBuiltinTools extends ToolSet = ToolSet> = {
973
+ /**
974
+ * Spec version this adapter implements. Always the literal `'harness-v1'`.
975
+ */
976
+ readonly specificationVersion: 'harness-v1';
977
+ /**
978
+ * Stable identifier for this harness, used as the key inside
979
+ * `HarnessV1Metadata` objects. Conventionally a kebab-case slug matching
980
+ * the package name (`'claude-code'`, `'codex'`).
981
+ */
982
+ readonly harnessId: string;
983
+ /**
984
+ * Tools the adapter's underlying runtime exposes natively, as a `ToolSet`
985
+ * keyed by what the bridge emits on `tool-call` events
986
+ * (`commonName ?? nativeName`). Each entry is a `HarnessV1BuiltinTool`
987
+ * (a `Tool` plus harness-specific `nativeName` / `commonName` metadata).
988
+ *
989
+ * The agent merges this with consumer-supplied user tools when validating
990
+ * inbound tool calls and when typing the consumer-facing stream.
991
+ */
992
+ readonly builtinTools: TBuiltinTools;
993
+ /**
994
+ * Whether the adapter can emit approval requests for built-in tools when
995
+ * `permissionMode` is not `'allow-all'`.
996
+ *
997
+ * Custom host-executed tool approvals are handled by `HarnessAgent`, so this
998
+ * only describes adapter-native tool approval support.
999
+ */
1000
+ readonly supportsBuiltinToolApprovals?: boolean;
1001
+ /**
1002
+ * Whether the adapter can prevent its underlying runtime from seeing or
1003
+ * calling inactive built-in tools for every tool in `builtinTools`.
1004
+ *
1005
+ * Adapters without native filtering can still support `activeTools` and
1006
+ * `inactiveTools` for built-ins when `supportsBuiltinToolApprovals` is
1007
+ * `true`: the framework routes inactive built-in tool calls through the
1008
+ * approval path and auto-denies them before they execute.
1009
+ */
1010
+ readonly supportsBuiltinToolFiltering?: boolean;
1011
+ /**
1012
+ * Optional schema for the adapter-defined `data` payload returned by session
1013
+ * lifecycle methods. When present, the adapter promises that exported state
1014
+ * validated by this schema can be re-imported in a future
1015
+ * `doStart({ resumeFrom })` or `doStart({ continueFrom })` call.
1016
+ */
1017
+ readonly lifecycleStateSchema?: FlexibleSchema<unknown>;
1018
+ /**
1019
+ * Optional bootstrap recipe. When defined, the harness session manager
1020
+ * computes a stable identity from the recipe, passes it (along with a
1021
+ * one-time recipe-application hook) to the sandbox provider, and applies
1022
+ * the recipe idempotently after the provider returns the handle.
1023
+ *
1024
+ * Adapters with no bootstrap needs omit this. Adapters that need to install
1025
+ * deps or ship bridge files into the sandbox declare them here so the
1026
+ * provider can cache the result across sessions via snapshots when
1027
+ * supported.
1028
+ */
1029
+ readonly getBootstrap?: (options?: {
1030
+ abortSignal?: AbortSignal;
1031
+ }) => PromiseLike<HarnessV1Bootstrap>;
1032
+ /**
1033
+ * Start a fresh session, resume a parked session via `resumeFrom`, or resume
1034
+ * an interrupted turn via `continueFrom`. The host then issues prompts against
1035
+ * the returned session, ending with `doDetach`, `doStop`, or `doDestroy`.
1036
+ */
1037
+ doStart(options: HarnessV1StartOptions): PromiseLike<HarnessV1Session>;
1038
+ };
1039
+
1040
+ /**
1041
+ * Cross-harness vocabulary of common built-in tool names with their baseline
1042
+ * input schemas. Adapters that declare a built-in with one of these
1043
+ * `commonName`s must accept (at least) every input the baseline schema
1044
+ * accepts. Extra optional fields are encouraged.
1045
+ *
1046
+ * Used both as runtime values (spread into `ToolSet`s for inspection) and as
1047
+ * a vocabulary source — `HarnessV1BuiltinToolName` is derived from its keys.
1048
+ */
1049
+ declare const HARNESS_V1_BUILTIN_TOOLS: {
1050
+ readonly read: Tool<{
1051
+ file_path: string;
1052
+ }, unknown, _ai_sdk_provider_utils.Context>;
1053
+ readonly write: Tool<{
1054
+ file_path: string;
1055
+ content: string;
1056
+ }, unknown, _ai_sdk_provider_utils.Context>;
1057
+ readonly edit: Tool<{
1058
+ file_path: string;
1059
+ old_string: string;
1060
+ new_string: string;
1061
+ }, unknown, _ai_sdk_provider_utils.Context>;
1062
+ readonly bash: Tool<{
1063
+ command: string;
1064
+ }, unknown, _ai_sdk_provider_utils.Context>;
1065
+ readonly grep: Tool<{
1066
+ pattern: string;
1067
+ }, unknown, _ai_sdk_provider_utils.Context>;
1068
+ readonly glob: Tool<{
1069
+ pattern: string;
1070
+ }, unknown, _ai_sdk_provider_utils.Context>;
1071
+ readonly webSearch: Tool<{
1072
+ query: string;
1073
+ }, unknown, _ai_sdk_provider_utils.Context>;
1074
+ };
1075
+ type HarnessV1BuiltinToolName = keyof typeof HARNESS_V1_BUILTIN_TOOLS;
1076
+ declare const HARNESS_V1_BUILTIN_TOOL_NAMES: ReadonlyArray<HarnessV1BuiltinToolName>;
1077
+ type HarnessV1BuiltinToolUseKind = 'readonly' | 'edit' | 'bash';
1078
+ /**
1079
+ * A tool that the adapter's underlying runtime exposes natively. Extends the
1080
+ * AI SDK `Tool` shape with two optional harness-specific fields:
1081
+ *
1082
+ * - `nativeName`: the name as the underlying runtime knows it. Required
1083
+ * only when the tool's key in the harness's `builtinTools` is not the
1084
+ * native name — i.e. when the tool maps to a `commonName` (e.g. key
1085
+ * `'bash'` for Claude Code's native `'Bash'`). Tools without a common
1086
+ * equivalent are keyed by their native name directly, so `nativeName`
1087
+ * is redundant and omitted.
1088
+ * - `commonName`: cross-harness label drawn from
1089
+ * `HARNESS_V1_BUILTIN_TOOL_NAMES`. Set when the tool maps to a familiar
1090
+ * capability; consumers use it to recognize, e.g., that Claude Code's
1091
+ * `Bash` and Codex's `shell` are the same kind of tool.
1092
+ *
1093
+ * Always set both fields together via the `commonTool` helper, or neither
1094
+ * (declare the tool with the AI SDK's `tool()` directly).
1095
+ */
1096
+ type HarnessV1BuiltinTool<INPUT = unknown, OUTPUT = unknown> = Tool<INPUT, OUTPUT, any> & {
1097
+ readonly nativeName?: string;
1098
+ readonly commonName?: HarnessV1BuiltinToolName;
1099
+ readonly toolUseKind?: HarnessV1BuiltinToolUseKind;
1100
+ };
1101
+ type InputOf<T> = T extends Tool<infer I, any, any> ? I : never;
1102
+ type StandardInputOf<N extends HarnessV1BuiltinToolName> = InputOf<(typeof HARNESS_V1_BUILTIN_TOOLS)[N]>;
1103
+ type SupersetCheck<TStandard, TAdapter, TOk> = TStandard extends TAdapter ? TOk : [
1104
+ 'ERROR: adapter input schema must be a superset of the standard schema',
1105
+ {
1106
+ expected: TStandard;
1107
+ got: TAdapter;
1108
+ }
1109
+ ];
1110
+ /**
1111
+ * Declare a built-in tool that maps to a cross-harness common name. The
1112
+ * adapter's input schema must accept every input the standard schema for
1113
+ * `commonName` accepts. Extra optional fields are encouraged.
1114
+ *
1115
+ * If the schema is missing a field the standard requires (or has an
1116
+ * incompatible type), the return type collapses to a tagged error tuple,
1117
+ * which fails the surrounding `as const satisfies ToolSet` assignment and
1118
+ * surfaces a readable TypeScript error at the offending entry.
1119
+ */
1120
+ declare function commonTool<TName extends HarnessV1BuiltinToolName, TInput>(commonName: TName, opts: {
1121
+ readonly nativeName: string;
1122
+ readonly toolUseKind?: HarnessV1BuiltinToolUseKind;
1123
+ readonly description?: string;
1124
+ readonly inputSchema: FlexibleSchema<TInput>;
1125
+ }): SupersetCheck<StandardInputOf<TName>, TInput, HarnessV1BuiltinTool<TInput>>;
1126
+
1127
+ /**
1128
+ * Provider that produces network sandbox sessions for harness sessions. Lives at
1129
+ * module scope as a stable, synchronous object — analogous to
1130
+ * `LanguageModelV4` providers, no I/O performed at construction. The actual
1131
+ * sandbox is created (or wrapped) when `HarnessAgent` calls `createSession()`.
1132
+ */
1133
+ interface HarnessV1SandboxProvider {
1134
+ readonly specificationVersion: 'harness-sandbox-v1';
1135
+ readonly providerId: string;
1136
+ /**
1137
+ * Pool of ports the consumer reserved on a caller-provided sandbox for
1138
+ * concurrent harness sessions. The session manager leases one port per
1139
+ * session and releases on stop or destroy.
1140
+ *
1141
+ * Only meaningful when the provider wraps a caller-provided sandbox
1142
+ * (the caller pre-declared the ports). In create-new modes the provider
1143
+ * mints a fresh sandbox per session, so no leasing is needed; providers
1144
+ * leave this undefined.
1145
+ */
1146
+ readonly bridgePorts?: ReadonlyArray<number>;
1147
+ readonly createSession: (options?: {
1148
+ /**
1149
+ * Stable per-session identifier. When supplied, the provider names the
1150
+ * underlying resource deterministically so a future call to `resume`
1151
+ * (potentially from a different process) can find the same sandbox.
1152
+ * Omitted from prewarm and other paths that don't need a resumable
1153
+ * resource — in that case the provider falls back to its native
1154
+ * auto-naming.
1155
+ */
1156
+ sessionId?: string;
1157
+ abortSignal?: AbortSignal;
1158
+ /**
1159
+ * Stable identity for snapshot-based reuse. Providers that support
1160
+ * persistence/snapshots use this as part of the persistent sandbox
1161
+ * name; subsequent calls with the same identity resume from snapshot.
1162
+ *
1163
+ * Ignored when the provider is wrapping a caller-provided sandbox.
1164
+ */
1165
+ identity?: string;
1166
+ /**
1167
+ * Called exactly once per identity, on fresh creation. Snapshot-capable
1168
+ * providers wire this into the platform's one-time-setup hook so the
1169
+ * side effects are baked into the snapshot. Providers without snapshot
1170
+ * support run it immediately after fresh create.
1171
+ *
1172
+ * Not called when the provider is wrapping a caller-provided sandbox
1173
+ * (the caller owns the sandbox; the framework applies its own
1174
+ * idempotent bootstrap post-create instead).
1175
+ */
1176
+ onFirstCreate?: (session: Experimental_SandboxSession, opts: {
1177
+ abortSignal?: AbortSignal;
1178
+ }) => Promise<void>;
1179
+ }) => PromiseLike<HarnessV1NetworkSandboxSession>;
1180
+ /**
1181
+ * Reattach to an existing sandbox previously created with the same
1182
+ * `sessionId`. Optional — providers that cannot rehydrate by id (e.g.
1183
+ * just-bash) omit this; the harness throws
1184
+ * `HarnessCapabilityUnsupportedError` when resume is attempted against
1185
+ * them.
1186
+ *
1187
+ * The provider derives the sandbox identifier from `sessionId` using the
1188
+ * same deterministic naming scheme it used in `createSession`. Returns a
1189
+ * network sandbox session bound to the existing resource.
1190
+ */
1191
+ readonly resumeSession?: (options: {
1192
+ sessionId: string;
1193
+ abortSignal?: AbortSignal;
1194
+ }) => PromiseLike<HarnessV1NetworkSandboxSession>;
1195
+ }
1196
+
1197
+ /**
1198
+ * The subset of a host-defined tool that travels on the `start` message. The
1199
+ * runtime only needs the name, description, and JSON-Schema input to surface
1200
+ * the tool; `execute` stays on the host.
1201
+ */
1202
+ declare const harnessV1BridgeToolWireSchema: z.ZodObject<{
1203
+ name: z.ZodString;
1204
+ description: z.ZodOptional<z.ZodString>;
1205
+ inputSchema: z.ZodOptional<z.ZodUnknown>;
1206
+ }, z.core.$strip>;
1207
+ type HarnessV1BridgeToolWire = z.infer<typeof harnessV1BridgeToolWireSchema>;
1208
+ declare const harnessV1BridgePermissionModeSchema: z.ZodEnum<{
1209
+ "allow-all": "allow-all";
1210
+ "allow-reads": "allow-reads";
1211
+ "allow-edits": "allow-edits";
1212
+ }>;
1213
+ declare const harnessV1BridgeBuiltinToolFilteringSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
1214
+ mode: z.ZodLiteral<"allow">;
1215
+ toolNames: z.ZodArray<z.ZodString>;
1216
+ }, z.core.$strip>, z.ZodObject<{
1217
+ mode: z.ZodLiteral<"deny">;
1218
+ toolNames: z.ZodArray<z.ZodString>;
1219
+ }, z.core.$strip>]>;
1220
+ /**
1221
+ * Common fields of the inbound `start` message. Each adapter extends this with
1222
+ * its runtime-specific configuration (e.g. `thinking`/`continue` for Claude
1223
+ * Code, `reasoningEffort`/`webSearch`/`skills`/`resumeThreadId` for Codex) and
1224
+ * assembles the final inbound union from the shared command members below.
1225
+ *
1226
+ * `debug` carries the general `HarnessV1DebugConfig` — diagnostics config is not
1227
+ * a bridge concept, it just happens to ride the `start` frame for bridge-backed
1228
+ * adapters.
1229
+ */
1230
+ declare const harnessV1BridgeStartBaseSchema: z.ZodObject<{
1231
+ type: z.ZodLiteral<"start">;
1232
+ prompt: z.ZodString;
1233
+ tools: z.ZodOptional<z.ZodArray<z.ZodObject<{
1234
+ name: z.ZodString;
1235
+ description: z.ZodOptional<z.ZodString>;
1236
+ inputSchema: z.ZodOptional<z.ZodUnknown>;
1237
+ }, z.core.$strip>>>;
1238
+ model: z.ZodOptional<z.ZodString>;
1239
+ debug: z.ZodOptional<z.ZodObject<{
1240
+ enabled: z.ZodOptional<z.ZodBoolean>;
1241
+ level: z.ZodOptional<z.ZodEnum<{
1242
+ error: "error";
1243
+ warn: "warn";
1244
+ info: "info";
1245
+ debug: "debug";
1246
+ trace: "trace";
1247
+ }>>;
1248
+ subsystems: z.ZodOptional<z.ZodArray<z.ZodString>>;
1249
+ }, z.core.$strip>>;
1250
+ permissionMode: z.ZodOptional<z.ZodEnum<{
1251
+ "allow-all": "allow-all";
1252
+ "allow-reads": "allow-reads";
1253
+ "allow-edits": "allow-edits";
1254
+ }>>;
1255
+ builtinToolFiltering: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
1256
+ mode: z.ZodLiteral<"allow">;
1257
+ toolNames: z.ZodArray<z.ZodString>;
1258
+ }, z.core.$strip>, z.ZodObject<{
1259
+ mode: z.ZodLiteral<"deny">;
1260
+ toolNames: z.ZodArray<z.ZodString>;
1261
+ }, z.core.$strip>]>>;
1262
+ }, z.core.$strip>;
1263
+ /**
1264
+ * Sent the instant the bridge accepts an authenticated WS connection. The host
1265
+ * waits for it before sending `start`/`resume`, because some sandbox runtimes
1266
+ * complete the upstream WS handshake before the connection is wired through to
1267
+ * the bridge process — anything sent in that gap is dropped. Carries the
1268
+ * bridge's lifecycle `state` and highest emitted `seq` for reconnect.
1269
+ */
1270
+ declare const harnessV1BridgeHelloSchema: z.ZodObject<{
1271
+ type: z.ZodLiteral<"bridge-hello">;
1272
+ state: z.ZodOptional<z.ZodString>;
1273
+ lastSeq: z.ZodOptional<z.ZodNumber>;
1274
+ }, z.core.$strip>;
1275
+ /**
1276
+ * The bridge's reply to an inbound `detach`. Carries the adapter-specific
1277
+ * payload the host serializes into lifecycle state `data`.
1278
+ */
1279
+ declare const harnessV1BridgeDetachSchema: z.ZodObject<{
1280
+ type: z.ZodLiteral<"bridge-detach">;
1281
+ data: z.ZodUnknown;
1282
+ }, z.core.$strip>;
1283
+ /**
1284
+ * A resume coordinate the bridge proactively announces (e.g. Codex's thread id)
1285
+ * so the host can cache it for a later resume without waiting for `detach`.
1286
+ */
1287
+ declare const harnessV1BridgeThreadSchema: z.ZodObject<{
1288
+ type: z.ZodLiteral<"bridge-thread">;
1289
+ threadId: z.ZodString;
1290
+ }, z.core.$strip>;
1291
+ /**
1292
+ * One captured console line from inside the sandbox. The bridge line-buffers
1293
+ * `process.stdout`/`process.stderr` and emits one of these per complete line.
1294
+ * Routed host-side to the diagnostics sink, never to the consumer stream.
1295
+ */
1296
+ declare const harnessV1BridgeSandboxLogSchema: z.ZodObject<{
1297
+ type: z.ZodLiteral<"sandbox-log">;
1298
+ source: z.ZodString;
1299
+ stream: z.ZodEnum<{
1300
+ stdout: "stdout";
1301
+ stderr: "stderr";
1302
+ }>;
1303
+ line: z.ZodString;
1304
+ }, z.core.$strip>;
1305
+ /**
1306
+ * A structured diagnostic an adapter emits from inside the bridge via
1307
+ * `turn.bridgeLog(...)`. Gated by the session's debug level + subsystem filter.
1308
+ */
1309
+ declare const harnessV1BridgeDebugEventSchema: z.ZodObject<{
1310
+ type: z.ZodLiteral<"debug-event">;
1311
+ level: z.ZodEnum<{
1312
+ error: "error";
1313
+ warn: "warn";
1314
+ info: "info";
1315
+ debug: "debug";
1316
+ trace: "trace";
1317
+ }>;
1318
+ subsystem: z.ZodString;
1319
+ message: z.ZodString;
1320
+ attrs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1321
+ error: z.ZodOptional<z.ZodObject<{
1322
+ name: z.ZodOptional<z.ZodString>;
1323
+ message: z.ZodString;
1324
+ stack: z.ZodOptional<z.ZodString>;
1325
+ }, z.core.$strip>>;
1326
+ }, z.core.$strip>;
1327
+ /**
1328
+ * Every frame a bridge can send to the host: the stream-part events plus the
1329
+ * transport/control frames. This is the schema the host `SandboxChannel`
1330
+ * validates inbound frames against.
1331
+ */
1332
+ declare const harnessV1BridgeOutboundMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
1333
+ type: z.ZodLiteral<"stream-start">;
1334
+ warnings: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodType<HarnessV1CallWarning, unknown, z.core.$ZodTypeInternals<HarnessV1CallWarning, unknown>>>>>;
1335
+ modelId: z.ZodOptional<z.ZodString>;
1336
+ }, z.core.$strip>, z.ZodObject<{
1337
+ type: z.ZodLiteral<"text-start">;
1338
+ id: z.ZodString;
1339
+ harnessMetadata: z.ZodOptional<z.ZodType<HarnessV1Metadata, unknown, z.core.$ZodTypeInternals<HarnessV1Metadata, unknown>>>;
1340
+ }, z.core.$strip>, z.ZodObject<{
1341
+ type: z.ZodLiteral<"text-delta">;
1342
+ id: z.ZodString;
1343
+ delta: z.ZodString;
1344
+ harnessMetadata: z.ZodOptional<z.ZodType<HarnessV1Metadata, unknown, z.core.$ZodTypeInternals<HarnessV1Metadata, unknown>>>;
1345
+ }, z.core.$strip>, z.ZodObject<{
1346
+ type: z.ZodLiteral<"text-end">;
1347
+ id: z.ZodString;
1348
+ harnessMetadata: z.ZodOptional<z.ZodType<HarnessV1Metadata, unknown, z.core.$ZodTypeInternals<HarnessV1Metadata, unknown>>>;
1349
+ }, z.core.$strip>, z.ZodObject<{
1350
+ type: z.ZodLiteral<"reasoning-start">;
1351
+ id: z.ZodString;
1352
+ harnessMetadata: z.ZodOptional<z.ZodType<HarnessV1Metadata, unknown, z.core.$ZodTypeInternals<HarnessV1Metadata, unknown>>>;
1353
+ }, z.core.$strip>, z.ZodObject<{
1354
+ type: z.ZodLiteral<"reasoning-delta">;
1355
+ id: z.ZodString;
1356
+ delta: z.ZodString;
1357
+ harnessMetadata: z.ZodOptional<z.ZodType<HarnessV1Metadata, unknown, z.core.$ZodTypeInternals<HarnessV1Metadata, unknown>>>;
1358
+ }, z.core.$strip>, z.ZodObject<{
1359
+ type: z.ZodLiteral<"reasoning-end">;
1360
+ id: z.ZodString;
1361
+ harnessMetadata: z.ZodOptional<z.ZodType<HarnessV1Metadata, unknown, z.core.$ZodTypeInternals<HarnessV1Metadata, unknown>>>;
1362
+ }, z.core.$strip>, z.ZodObject<{
1363
+ type: z.ZodLiteral<"tool-call">;
1364
+ toolCallId: z.ZodString;
1365
+ toolName: z.ZodString;
1366
+ input: z.ZodString;
1367
+ providerExecuted: z.ZodOptional<z.ZodBoolean>;
1368
+ dynamic: z.ZodOptional<z.ZodBoolean>;
1369
+ providerMetadata: z.ZodOptional<z.ZodType<_ai_sdk_provider.SharedV4ProviderMetadata, unknown, z.core.$ZodTypeInternals<_ai_sdk_provider.SharedV4ProviderMetadata, unknown>>>;
1370
+ nativeName: z.ZodOptional<z.ZodString>;
1371
+ }, z.core.$strip>, z.ZodObject<{
1372
+ type: z.ZodLiteral<"tool-approval-request">;
1373
+ approvalId: z.ZodString;
1374
+ toolCallId: z.ZodString;
1375
+ providerMetadata: z.ZodOptional<z.ZodType<_ai_sdk_provider.SharedV4ProviderMetadata, unknown, z.core.$ZodTypeInternals<_ai_sdk_provider.SharedV4ProviderMetadata, unknown>>>;
1376
+ }, z.core.$strip>, z.ZodObject<{
1377
+ type: z.ZodLiteral<"tool-result">;
1378
+ toolCallId: z.ZodString;
1379
+ toolName: z.ZodString;
1380
+ result: z.ZodType<NonNullable<_ai_sdk_provider.JSONValue>, unknown, z.core.$ZodTypeInternals<NonNullable<_ai_sdk_provider.JSONValue>, unknown>>;
1381
+ isError: z.ZodOptional<z.ZodBoolean>;
1382
+ preliminary: z.ZodOptional<z.ZodBoolean>;
1383
+ dynamic: z.ZodOptional<z.ZodBoolean>;
1384
+ providerMetadata: z.ZodOptional<z.ZodType<_ai_sdk_provider.SharedV4ProviderMetadata, unknown, z.core.$ZodTypeInternals<_ai_sdk_provider.SharedV4ProviderMetadata, unknown>>>;
1385
+ }, z.core.$strip>, z.ZodObject<{
1386
+ type: z.ZodLiteral<"finish-step">;
1387
+ finishReason: z.ZodType<_ai_sdk_provider.LanguageModelV4FinishReason, unknown, z.core.$ZodTypeInternals<_ai_sdk_provider.LanguageModelV4FinishReason, unknown>>;
1388
+ usage: z.ZodType<_ai_sdk_provider.LanguageModelV4Usage, unknown, z.core.$ZodTypeInternals<_ai_sdk_provider.LanguageModelV4Usage, unknown>>;
1389
+ harnessMetadata: z.ZodOptional<z.ZodType<HarnessV1Metadata, unknown, z.core.$ZodTypeInternals<HarnessV1Metadata, unknown>>>;
1390
+ }, z.core.$strip>, z.ZodObject<{
1391
+ type: z.ZodLiteral<"finish">;
1392
+ finishReason: z.ZodType<_ai_sdk_provider.LanguageModelV4FinishReason, unknown, z.core.$ZodTypeInternals<_ai_sdk_provider.LanguageModelV4FinishReason, unknown>>;
1393
+ totalUsage: z.ZodType<_ai_sdk_provider.LanguageModelV4Usage, unknown, z.core.$ZodTypeInternals<_ai_sdk_provider.LanguageModelV4Usage, unknown>>;
1394
+ harnessMetadata: z.ZodOptional<z.ZodType<HarnessV1Metadata, unknown, z.core.$ZodTypeInternals<HarnessV1Metadata, unknown>>>;
1395
+ }, z.core.$strip>, z.ZodObject<{
1396
+ type: z.ZodLiteral<"file-change">;
1397
+ event: z.ZodEnum<{
1398
+ create: "create";
1399
+ modify: "modify";
1400
+ delete: "delete";
1401
+ }>;
1402
+ path: z.ZodString;
1403
+ harnessMetadata: z.ZodOptional<z.ZodType<HarnessV1Metadata, unknown, z.core.$ZodTypeInternals<HarnessV1Metadata, unknown>>>;
1404
+ }, z.core.$strip>, z.ZodObject<{
1405
+ type: z.ZodLiteral<"compaction">;
1406
+ trigger: z.ZodEnum<{
1407
+ manual: "manual";
1408
+ auto: "auto";
1409
+ }>;
1410
+ summary: z.ZodString;
1411
+ tokensBefore: z.ZodOptional<z.ZodNumber>;
1412
+ tokensAfter: z.ZodOptional<z.ZodNumber>;
1413
+ harnessMetadata: z.ZodOptional<z.ZodType<HarnessV1Metadata, unknown, z.core.$ZodTypeInternals<HarnessV1Metadata, unknown>>>;
1414
+ }, z.core.$strip>, z.ZodObject<{
1415
+ type: z.ZodLiteral<"error">;
1416
+ error: z.ZodUnknown;
1417
+ }, z.core.$strip>, z.ZodObject<{
1418
+ type: z.ZodLiteral<"raw">;
1419
+ rawValue: z.ZodUnknown;
1420
+ }, z.core.$strip>, z.ZodObject<{
1421
+ type: z.ZodLiteral<"bridge-hello">;
1422
+ state: z.ZodOptional<z.ZodString>;
1423
+ lastSeq: z.ZodOptional<z.ZodNumber>;
1424
+ }, z.core.$strip>, z.ZodObject<{
1425
+ type: z.ZodLiteral<"bridge-detach">;
1426
+ data: z.ZodUnknown;
1427
+ }, z.core.$strip>, z.ZodObject<{
1428
+ type: z.ZodLiteral<"bridge-thread">;
1429
+ threadId: z.ZodString;
1430
+ }, z.core.$strip>, z.ZodObject<{
1431
+ type: z.ZodLiteral<"bridge-interrupted">;
1432
+ ok: z.ZodBoolean;
1433
+ error: z.ZodOptional<z.ZodUnknown>;
1434
+ }, z.core.$strip>, z.ZodObject<{
1435
+ type: z.ZodLiteral<"sandbox-log">;
1436
+ source: z.ZodString;
1437
+ stream: z.ZodEnum<{
1438
+ stdout: "stdout";
1439
+ stderr: "stderr";
1440
+ }>;
1441
+ line: z.ZodString;
1442
+ }, z.core.$strip>, z.ZodObject<{
1443
+ type: z.ZodLiteral<"debug-event">;
1444
+ level: z.ZodEnum<{
1445
+ error: "error";
1446
+ warn: "warn";
1447
+ info: "info";
1448
+ debug: "debug";
1449
+ trace: "trace";
1450
+ }>;
1451
+ subsystem: z.ZodString;
1452
+ message: z.ZodString;
1453
+ attrs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1454
+ error: z.ZodOptional<z.ZodObject<{
1455
+ name: z.ZodOptional<z.ZodString>;
1456
+ message: z.ZodString;
1457
+ stack: z.ZodOptional<z.ZodString>;
1458
+ }, z.core.$strip>>;
1459
+ }, z.core.$strip>]>;
1460
+ type HarnessV1BridgeOutboundMessage = z.infer<typeof harnessV1BridgeOutboundMessageSchema>;
1461
+ type HarnessV1BridgeSandboxLog = z.infer<typeof harnessV1BridgeSandboxLogSchema>;
1462
+ type HarnessV1BridgeDebugEvent = z.infer<typeof harnessV1BridgeDebugEventSchema>;
1463
+ /**
1464
+ * Normalize a bridge diagnostics wire frame into the transport-agnostic
1465
+ * `HarnessV1Diagnostic` an adapter reports to the framework. A captured console
1466
+ * line maps `stderr` → `warn` and `stdout` → `info`; a structured event passes
1467
+ * its fields through. This is the seam where the bridge's serialization is
1468
+ * lifted into the general emission shape every harness shares.
1469
+ */
1470
+ declare function harnessV1DiagnosticFromBridgeFrame(frame: HarnessV1BridgeSandboxLog | HarnessV1BridgeDebugEvent, context: {
1471
+ sessionId?: string;
1472
+ timestamp: number;
1473
+ }): HarnessV1Diagnostic;
1474
+ declare const harnessV1BridgeToolResultInboundSchema: z.ZodObject<{
1475
+ type: z.ZodLiteral<"tool-result">;
1476
+ toolCallId: z.ZodString;
1477
+ output: z.ZodUnknown;
1478
+ isError: z.ZodOptional<z.ZodBoolean>;
1479
+ }, z.core.$strip>;
1480
+ declare const harnessV1BridgeToolApprovalResponseInboundSchema: z.ZodObject<{
1481
+ type: z.ZodLiteral<"tool-approval-response">;
1482
+ approvalId: z.ZodString;
1483
+ approved: z.ZodBoolean;
1484
+ reason: z.ZodOptional<z.ZodString>;
1485
+ }, z.core.$strip>;
1486
+ declare const harnessV1BridgeUserMessageInboundSchema: z.ZodObject<{
1487
+ type: z.ZodLiteral<"user-message">;
1488
+ text: z.ZodString;
1489
+ }, z.core.$strip>;
1490
+ declare const harnessV1BridgeAbortInboundSchema: z.ZodObject<{
1491
+ type: z.ZodLiteral<"abort">;
1492
+ }, z.core.$strip>;
1493
+ declare const harnessV1BridgeShutdownInboundSchema: z.ZodObject<{
1494
+ type: z.ZodLiteral<"shutdown">;
1495
+ }, z.core.$strip>;
1496
+ /**
1497
+ * Reconnect: after re-establishing the socket the host asks the bridge to
1498
+ * replay every buffered event with `seq > lastSeenEventId`.
1499
+ */
1500
+ declare const harnessV1BridgeResumeInboundSchema: z.ZodObject<{
1501
+ type: z.ZodLiteral<"resume">;
1502
+ lastSeenEventId: z.ZodNumber;
1503
+ }, z.core.$strip>;
1504
+ /**
1505
+ * The bridge replies with `bridge-detach` carrying any cached resume payload,
1506
+ * then exits.
1507
+ */
1508
+ declare const harnessV1BridgeDetachInboundSchema: z.ZodObject<{
1509
+ type: z.ZodLiteral<"detach">;
1510
+ }, z.core.$strip>;
1511
+ /**
1512
+ * The inbound command members shared by every bridge adapter. Spread these
1513
+ * alongside the adapter's own `start` schema to build the final inbound union:
1514
+ * `z.discriminatedUnion('type', [adapterStartSchema, ...harnessV1BridgeInboundCommandSchemas])`.
1515
+ */
1516
+ declare const harnessV1BridgeInboundCommandSchemas: readonly [z.ZodObject<{
1517
+ type: z.ZodLiteral<"tool-result">;
1518
+ toolCallId: z.ZodString;
1519
+ output: z.ZodUnknown;
1520
+ isError: z.ZodOptional<z.ZodBoolean>;
1521
+ }, z.core.$strip>, z.ZodObject<{
1522
+ type: z.ZodLiteral<"tool-approval-response">;
1523
+ approvalId: z.ZodString;
1524
+ approved: z.ZodBoolean;
1525
+ reason: z.ZodOptional<z.ZodString>;
1526
+ }, z.core.$strip>, z.ZodObject<{
1527
+ type: z.ZodLiteral<"user-message">;
1528
+ text: z.ZodString;
1529
+ }, z.core.$strip>, z.ZodObject<{
1530
+ type: z.ZodLiteral<"abort">;
1531
+ }, z.core.$strip>, z.ZodObject<{
1532
+ type: z.ZodLiteral<"interrupt">;
1533
+ }, z.core.$strip>, z.ZodObject<{
1534
+ type: z.ZodLiteral<"shutdown">;
1535
+ }, z.core.$strip>, z.ZodObject<{
1536
+ type: z.ZodLiteral<"resume">;
1537
+ lastSeenEventId: z.ZodNumber;
1538
+ }, z.core.$strip>, z.ZodObject<{
1539
+ type: z.ZodLiteral<"detach">;
1540
+ }, z.core.$strip>];
1541
+ /**
1542
+ * The JSON line the bridge writes to stdout once its WebSocket server is bound,
1543
+ * announcing the port the host should connect to.
1544
+ */
1545
+ declare const harnessV1BridgeReadySchema: z.ZodObject<{
1546
+ type: z.ZodLiteral<"bridge-ready">;
1547
+ port: z.ZodNumber;
1548
+ }, z.core.$strip>;
1549
+ type HarnessV1BridgeReady = z.infer<typeof harnessV1BridgeReadySchema>;
1550
+
1551
+ declare const symbol$1: unique symbol;
1552
+ /**
1553
+ * Base error type for failures originating in or signalled by a harness
1554
+ * adapter. Specific failure modes (e.g. unsupported capability) extend this
1555
+ * class.
1556
+ */
1557
+ declare class HarnessError extends AISDKError {
1558
+ private readonly [symbol$1];
1559
+ constructor({ message, cause }: {
1560
+ message: string;
1561
+ cause?: unknown;
1562
+ });
1563
+ static isInstance(error: unknown): error is HarnessError;
1564
+ }
1565
+
1566
+ declare const symbol: unique symbol;
1567
+ /**
1568
+ * Thrown when a caller asks the harness to do something the adapter (or the
1569
+ * supplied sandbox) does not support, e.g. requesting manual compaction from
1570
+ * an adapter that only auto-compacts, or invoking `getPortUrl` on a sandbox
1571
+ * that does not expose one.
1572
+ *
1573
+ * The caller supplies the full human-readable message. Optional `harnessId`
1574
+ * is recorded as structured context for tooling.
1575
+ */
1576
+ declare class HarnessCapabilityUnsupportedError extends HarnessError {
1577
+ private readonly [symbol];
1578
+ readonly harnessId?: string;
1579
+ constructor({ message, harnessId, cause, }: {
1580
+ message: string;
1581
+ harnessId?: string;
1582
+ cause?: unknown;
1583
+ });
1584
+ static isInstance(error: unknown): error is HarnessCapabilityUnsupportedError;
1585
+ }
1586
+
1587
+ export { HARNESS_V1_BUILTIN_TOOLS, HARNESS_V1_BUILTIN_TOOL_NAMES, HarnessCapabilityUnsupportedError, HarnessError, type HarnessV1, type HarnessV1Bootstrap, type HarnessV1BootstrapCommand, type HarnessV1BootstrapFile, type HarnessV1BridgeDebugEvent, type HarnessV1BridgeOutboundMessage, type HarnessV1BridgeReady, type HarnessV1BridgeSandboxLog, type HarnessV1BridgeToolWire, type HarnessV1BuiltinTool, type HarnessV1BuiltinToolFiltering, type HarnessV1BuiltinToolName, type HarnessV1BuiltinToolUseKind, type HarnessV1CallWarning, type HarnessV1ContinueTurnOptions, type HarnessV1ContinueTurnState, type HarnessV1DebugConfig, type HarnessV1DebugLevel, type HarnessV1Diagnostic, type HarnessV1LifecycleState, type HarnessV1Metadata, type HarnessV1NetworkPolicy, type HarnessV1NetworkSandboxSession, type HarnessV1Observability, type HarnessV1PendingToolApproval, type HarnessV1PermissionMode, type HarnessV1Prompt, type HarnessV1PromptControl, type HarnessV1PromptTurnOptions, type HarnessV1ResumeSessionState, type HarnessV1SandboxProvider, type HarnessV1Session, type HarnessV1Skill, type HarnessV1StartOptions, type HarnessV1StreamPart, type HarnessV1ToolSpec, commonTool, getHarnessV1BuiltinToolFilteringDenialReason, harnessV1BridgeAbortInboundSchema, harnessV1BridgeBuiltinToolFilteringSchema, harnessV1BridgeDebugEventSchema, harnessV1BridgeDetachInboundSchema, harnessV1BridgeDetachSchema, harnessV1BridgeHelloSchema, harnessV1BridgeInboundCommandSchemas, harnessV1BridgeOutboundMessageSchema, harnessV1BridgePermissionModeSchema, harnessV1BridgeReadySchema, harnessV1BridgeResumeInboundSchema, harnessV1BridgeSandboxLogSchema, harnessV1BridgeShutdownInboundSchema, harnessV1BridgeStartBaseSchema, harnessV1BridgeThreadSchema, harnessV1BridgeToolApprovalResponseInboundSchema, harnessV1BridgeToolResultInboundSchema, harnessV1BridgeToolWireSchema, harnessV1BridgeUserMessageInboundSchema, harnessV1DebugConfigSchema, harnessV1DebugLevelSchema, harnessV1DiagnosticFromBridgeFrame, harnessV1ErrorPartSchema, harnessV1FileChangePartSchema, harnessV1FinishPartSchema, harnessV1FinishStepPartSchema, harnessV1RawPartSchema, harnessV1ReasoningDeltaPartSchema, harnessV1ReasoningEndPartSchema, harnessV1ReasoningStartPartSchema, harnessV1StreamPartSchema, harnessV1StreamStartPartSchema, harnessV1TextDeltaPartSchema, harnessV1TextEndPartSchema, harnessV1TextStartPartSchema, harnessV1ToolApprovalRequestPartSchema, harnessV1ToolCallPartSchema, harnessV1ToolResultPartSchema, isHarnessV1BuiltinToolIncluded };