import { s as LifecycleCapability } from "./capability-runner-BiVUtjqC.js";
import { n as Streams } from "./streams-vrCtbUIn.js";
import {
  _ as TranscriptMessage,
  a as DispatchResult,
  b as ChannelMessageSurface,
  c as InboundEvent,
  i as ConversationSnapshot,
  m as ResponseChunk,
  n as ConversationInfo,
  o as EventOrigin,
  r as ConversationOperation,
  s as GatewayOrigin,
  y as TurnStatus
} from "./protocol-CukuI73M.js";
import { i as WebSockets } from "./index-CBt8oRJt.js";
import { t as AgentHarness } from "./harness-B6B9S3rb.js";

//#region src/experimental/channels/conversations.d.ts
/**
 * An inbound event as the gateway sends it. An approval response from a
 * webhook names no turn; Channels finds it from the conversation snapshot.
 */
type GatewayEvent =
  | InboundEvent
  | Omit<
      Extract<
        InboundEvent,
        {
          type: "approval-response";
        }
      >,
      "turnId"
    >;
/** How a response finished, as a reader sees it. */
type ResponseEnding = "ended" | "interrupted" | "not-found";
/** A change Channels pushes to every channel showing a conversation. */
type ConversationUpdate =
  | {
      type: "turn";
      turn: TurnStatus;
    }
  | {
      type: "messages";
      messages: TranscriptMessage[] /** Set when the messages arrived as an inbound event. */;
      origin?: EventOrigin /** The inbound event's id, set with `origin`. */;
      eventId?: string;
    }
  | {
      type: "reset";
    }
  | {
      type: "response-end";
      responseId: string;
      ending: ResponseEnding;
    };
type ResponseReadOptions = {
  from?: number;
  signal?: AbortSignal;
  onChunks(
    from: number,
    chunks: ResponseChunk[]
  ): void /** Everything recorded so far has been read; what follows is live. */;
  onCaughtUp(cursor: number): void;
};
/** Durable state a channel keeps in the agent, private to that channel. */
type ChannelState = {
  get<T>(key: string): T | undefined;
  put(key: string, value: unknown): void;
  delete(key: string): void;
};
/** What Channels gives a mounted channel. */
type ChannelsHost = {
  readonly channelKey: string;
  /**
   * The WebSockets this Channels' channels share: the instance Channels was
   * given, or else the one the first channel to ask creates. Install it with
   * `Lifecycle.use(channels.websockets)`.
   */
  websockets(
    create: () => WebSockets
  ): WebSockets /** This channel's surfaces that have joined the conversation. */;
  surfaces(conversationId: string): Promise<ChannelMessageSurface[]>;
  readonly state: ChannelState;
  snapshot(
    conversationId: string
  ): Promise<ConversationSnapshot> /** The conversation a surface joins when it names none. */;
  defaultConversation(): string /** The conversation operations the agent supports. */;
  readonly operations: readonly ConversationOperation[] /** The agent's conversations. */;
  listConversations(): Promise<ConversationInfo[]>;
  /**
   * Deliver an event to the agent. Resolves once the agent accepted it and
   * rejects if the agent threw.
   */
  dispatch(event: InboundEvent, origin: EventOrigin): Promise<DispatchResult>;
  readResponse(
    conversationId: string,
    responseId: string,
    options: ResponseReadOptions
  ): Promise<ResponseEnding>;
};
/** An interface that shows conversations, such as the Web Channel. */
interface ConversationChannel {
  /** Called once, when Channels is constructed. Take shared dependencies here. */
  mount(host: ChannelsHost): void;
  publish(
    conversationId: string,
    update: ConversationUpdate
  ): void | Promise<void>;
}
type ChannelsOptions = {
  /**
   * The agent: its sessions are served as conversations, a conversation's
   * id being its session's id.
   */
  harness: AgentHarness /** Install it before Channels. */;
  streams: Streams /** Shared with channels that serve WebSockets, such as the Web Channel. */;
  websockets?: WebSockets;
  channels: Record<string, ConversationChannel>;
};
type ForHarnessOptions = {
  channels: Record<
    string,
    ConversationChannel
  > /** Default: a new Streams, exposed as `channels.streams`. */;
  streams?: Streams /** Default: one the Web Channel creates, exposed as `channels.websockets`. */;
  websockets?: WebSockets;
};
/**
 * Serves an agent harness's sessions as conversations: carries inbound
 * events to the harness, and responses, turn statuses and transcript
 * updates back to every channel showing the conversation.
 */
declare class Channels extends LifecycleCapability {
  #private;
  /**
   * Channels for any shared-interface harness, with their own Streams and
   * (when a channel needs them) WebSockets. Lifecycle does not install one
   * capability from another yet, so install them alongside:
   *
   * ```ts
   * readonly channels = Channels.forHarness(harness, {
   *   channels: { web: new WebChannel() }
   * });
   * readonly lifecycle = Lifecycle.install(this)
   *   .use(this.harness)
   *   .use(this.channels.streams)
   *   .use(this.channels)
   *   .use(this.channels.websockets);
   *
   * receive(event: GatewayEvent, origin: GatewayOrigin) {
   *   return this.channels.receive(event, origin);
   * }
   * ```
   */
  static forHarness(
    harness: AgentHarness,
    options: ForHarnessOptions
  ): Channels;
  /** The responses' Streams. Install it before Channels. */
  readonly streams: Streams;
  constructor(options: ChannelsOptions);
  /**
   * The WebSockets the channels share. Install it with Lifecycle. Throws
   * when no channel uses WebSockets.
   */
  get websockets(): WebSockets;
  /** Mark responses left streaming by an earlier instance as interrupted. */
  onStart(): Promise<void>;
  /**
   * Deliver an inbound event from the gateway, through the same path as
   * the agent's own channels. The agent calls this from its RPC method.
   */
  receive(
    event: GatewayEvent,
    from: GatewayOrigin | EventOrigin
  ): Promise<void>;
}
//#endregion
export {
  ConversationChannel as a,
  GatewayEvent as c,
  ChannelsOptions as i,
  ResponseEnding as l,
  Channels as n,
  ConversationUpdate as o,
  ChannelsHost as r,
  ForHarnessOptions as s,
  ChannelState as t,
  ResponseReadOptions as u
};
//# sourceMappingURL=conversations-FjHDRZyD.d.ts.map
