//#region src/harness/container/protocol.d.ts
/**
 * The wire between `ContainerHarness` (in a Durable Object) and the harness
 * daemon (in the container). Isomorphic and dependency-free: the daemon
 * imports it in Node, the harness in Workers.
 *
 * One WebSocket per session, dialled by the object through
 * `ctx.container.getTcpPort(port)` at `/sessions/<id>`. The daemon speaks
 * first with `hello`; the object answers with `open` (when the daemon does
 * not hold the session yet) and `replay`, then delivers `prompt`s.
 *
 * Everything the daemon produces for a session is a numbered `frame`. The
 * numbers start at 1 for each session in each container, so a frame is
 * addressed by `(runtimeId, seq)`. The daemon keeps frames until they are
 * acknowledged, so an object that lost its socket (evicted, redeployed)
 * replays what it missed from its cursor. A different `runtimeId` in
 * `hello` means a different container: its numbering starts again, and
 * whatever the old container was doing is gone.
 *
 * @experimental The wire may change before it stabilizes. The object and the image are
 * a matched pair; a version mismatch is reported in `hello`.
 */
/** Bumped on any incompatible change. */
declare const CONTAINER_PROTOCOL_VERSION = 1;
/** The daemon answers `200` here once it accepts connections. */
declare const CONTAINER_HEALTH_PATH = "/healthz";
/** The session socket: `/sessions/<encoded session id>`. */
declare const CONTAINER_SESSION_PATH = "/sessions/";
/** The shared secret the object passes on every request. */
declare const CONTAINER_TOKEN_HEADER = "x-cf-harness-token";
/** The environment variables the object starts the container with. */
declare const CONTAINER_ENV: {
  /** Shared secret for `CONTAINER_TOKEN_HEADER`. */ readonly token: "CF_HARNESS_TOKEN" /** This container's id. Echoed in `hello`. */;
  readonly runtimeId: "CF_HARNESS_RUNTIME_ID" /** The port the daemon listens on. */;
  readonly port: "CF_HARNESS_PORT";
};
/** WebSocket close code: a newer connection for the session replaced this one. */
declare const CLOSE_REPLACED = 4001;
/** WebSocket close code: the request was not authorized. */
declare const CLOSE_UNAUTHORIZED = 4003;
/** A JSON value on the wire. */
type JsonValue =
  | string
  | number
  | boolean
  | null
  | readonly JsonValue[]
  | {
      readonly [key: string]: JsonValue;
    };
/** One part of a prompt. */
type ContainerInputPart =
  | {
      readonly type: "text";
      readonly text: string;
    }
  | {
      readonly type: "image" /** IANA media type, such as `image/png`. */;
      readonly mediaType: string /** Base64 bytes. */;
      readonly data: string;
    };
/** What a prompt carries: plain text, or parts. */
type ContainerInput = string | readonly ContainerInputPart[];
/** What a submission does when the session is already running. */
type ContainerWhenBusy = "followUp" | "steer";
/**
 * Per-session settings the object sends the adapter. `model` is the
 * adapter's own model name; `options` is opaque to everything but the
 * adapter.
 */
type ContainerSettings = {
  readonly model?: string;
  readonly options?: JsonValue;
};
/** One part of a transcript message. */
type ContainerPart =
  | {
      readonly type: "text";
      readonly text: string;
    }
  | {
      readonly type: "reasoning";
      readonly text: string;
    }
  | {
      readonly type: "image";
      readonly mediaType: string;
      readonly data: string;
    }
  | {
      readonly type: "tool";
      readonly toolCallId: string;
      readonly toolName: string;
      readonly input: JsonValue;
      readonly state: "running" | "done" | "error";
      readonly output?: JsonValue;
    };
/**
 * A transcript message, in the one format every container adapter
 * produces. An adapter emits a message again, under the same id, to update
 * it (a tool result arriving, for example).
 */
type ContainerMessage = {
  readonly id: string;
  readonly role: "user" | "assistant";
  readonly parts: readonly ContainerPart[] /** The operation the message belongs to. */;
  readonly operationId?: string;
  readonly createdAt: number;
};
/** What an adapter reports while it runs. */
type ContainerEvent =
  | /** Live text for an assistant message that is still being written. */ {
      readonly type: "text-delta";
      readonly messageId: string;
      readonly delta: string;
    } /** Live reasoning for an assistant message that is still being written. */
  | {
      readonly type: "reasoning-delta";
      readonly messageId: string;
      readonly delta: string;
    } /** A finished or updated transcript message. Stored. */
  | {
      readonly type: "message";
      readonly message: ContainerMessage;
    } /** Token and cost figures the adapter reports, as the adapter counts them. */
  | {
      readonly type: "usage";
      readonly inputTokens?: number;
      readonly outputTokens?: number;
      readonly costUsd?: number;
    } /** A diagnostic line. */
  | {
      readonly type: "log";
      readonly level: "info" | "warn" | "error";
      readonly message: string;
    } /** Anything adapter-specific, passed through untouched. */
  | {
      readonly type: "raw";
      readonly value: JsonValue;
    };
/** How an operation ended, as the daemon reports it. */
type ContainerOutcome =
  | {
      readonly status: "done";
      readonly text: string;
    }
  | {
      readonly status: "unanswered";
      readonly reason: string;
    };
/** What the daemon knows about one operation it was given. */
type DaemonOperation =
  | {
      readonly operationId: string;
      readonly status: "queued" | "running";
    }
  | {
      readonly operationId: string;
      readonly status: "settled";
      readonly outcome: ContainerOutcome;
    };
/** One numbered thing the daemon produced for a session. */
type DaemonFrame =
  | {
      readonly kind: "start";
      readonly operationId: string;
    }
  | {
      readonly kind: "event";
      readonly operationId: string | null;
      readonly event: ContainerEvent;
    }
  /**
   * Adapter resume state to keep. The object stores these entries in order
   * and hands all of them back in `open` on a new container.
   */
  | {
      readonly kind: "persist";
      readonly entries: readonly JsonValue[];
    }
  | {
      readonly kind: "settle";
      readonly operationId: string;
      readonly outcome: ContainerOutcome;
    };
/** The adapter running in the container. */
type AdapterInfo = {
  readonly id: string;
  readonly version: string;
  readonly capabilities: readonly string[];
};
/** Daemon → object. */
type DaemonMessage =
  | {
      readonly type: "hello";
      readonly protocol: number;
      readonly runtimeId: string;
      readonly session: string;
      readonly adapter: AdapterInfo /** The generation of the open adapter session, or null if none is open. */;
      readonly open:
        | number
        | null /** The newest frame number for this session in this container. */;
      readonly lastSeq: number /** Every operation this container was given for the session. */;
      readonly operations: readonly DaemonOperation[];
    }
  | {
      readonly type: "frame";
      readonly seq: number;
      readonly frame: DaemonFrame;
    } /** Every kept frame after the `replay` cursor has been sent. */
  | {
      readonly type: "caught-up";
      readonly lastSeq: number;
    }
  | {
      readonly type: "error";
      readonly message: string;
    };
/**
 * Most JSON characters the object puts in one `restore` message, and the
 * daemon in one `persist` frame (a single larger entry travels alone).
 * Keeps every message well inside WebSocket message limits.
 */
declare const MAX_CHUNK_CHARS: number;
/** Object → daemon. */
type HostMessage =
  /**
   * Part of the resume state for the next `open` of `generation`. Sent
   * before that `open`, in order, so no single message grows with the
   * session's history.
   */
  | {
      readonly type: "restore";
      readonly generation: number;
      readonly entries: readonly JsonValue[];
    }
  /**
   * Open the adapter session. Ignored when the same generation is already
   * open; a different generation closes the open one first.
   */
  | {
      readonly type: "open";
      readonly generation: number;
      readonly settings: ContainerSettings;
      /**
       * The last of the entries the adapter persisted for this session,
       * after any sent in `restore` messages for this generation.
       */
      readonly restore: readonly JsonValue[];
    } /** Send every kept frame after `after`, then live frames. */
  | {
      readonly type: "replay";
      readonly after: number;
    } /** Queue an operation. Idempotent on `operationId`. */
  | {
      readonly type: "prompt";
      readonly operationId: string;
      readonly input: ContainerInput;
      readonly whenBusy: ContainerWhenBusy;
    } /** Stop one operation, or every operation of the session. */
  | {
      readonly type: "abort";
      readonly operationId?: string;
    }
  | {
      readonly type: "configure";
      readonly settings: ContainerSettings;
    } /** Frames up to `seq` are stored; the daemon may forget them. */
  | {
      readonly type: "ack";
      readonly seq: number;
    };
/**
 * Parse one message from the daemon.
 *
 * @param text - The raw WebSocket message.
 * @returns The message, or `undefined` when it is not one.
 */
declare function parseDaemonMessage(text: string): DaemonMessage | undefined;
/**
 * Parse one message from the object.
 *
 * @param text - The raw WebSocket message.
 * @returns The message, or `undefined` when it is not one.
 */
declare function parseHostMessage(text: string): HostMessage | undefined;
/**
 * The text of an input, with image parts left out.
 *
 * @param input - A prompt's input.
 * @returns Its text.
 */
declare function inputText(input: ContainerInput): string;
/**
 * Split entries into groups whose JSON stays under `MAX_CHUNK_CHARS`. An
 * entry larger than that is a group of its own.
 *
 * @param entries - The entries, in order.
 * @returns The groups, in order. Empty for no entries.
 */
declare function chunkEntries(entries: readonly JsonValue[]): JsonValue[][];
//#endregion
export {
  chunkEntries as C,
  parseHostMessage as E,
  MAX_CHUNK_CHARS as S,
  parseDaemonMessage as T,
  DaemonFrame as _,
  CONTAINER_HEALTH_PATH as a,
  HostMessage as b,
  CONTAINER_TOKEN_HEADER as c,
  ContainerInputPart as d,
  ContainerMessage as f,
  ContainerWhenBusy as g,
  ContainerSettings as h,
  CONTAINER_ENV as i,
  ContainerEvent as l,
  ContainerPart as m,
  CLOSE_REPLACED as n,
  CONTAINER_PROTOCOL_VERSION as o,
  ContainerOutcome as p,
  CLOSE_UNAUTHORIZED as r,
  CONTAINER_SESSION_PATH as s,
  AdapterInfo as t,
  ContainerInput as u,
  DaemonMessage as v,
  inputText as w,
  JsonValue as x,
  DaemonOperation as y
};
//# sourceMappingURL=protocol-BEgrJYC5.d.ts.map
