import { ChatTransport, UIMessage, UIMessageChunk } from "ai";

//#region src/chat/replay-dedupe.d.ts
/**
 * Replay de-duplication for continuation streams (#1951).
 *
 * A continuation appends to an assistant message this client may already have
 * rendered live. After a reconnect the server replays the continuation's
 * whole buffer, and applying it on top of the live-rendered bytes would
 * duplicate them. Every live and replayed chunk frame carries its index in
 * the stream (`seq`), so a client that records how far it applied each
 * stream can drop the replayed chunks it already has.
 *
 * Non-continuation replays are left alone: the client resets the message and
 * rebuilds it from chunk 0 for those.
 */
type ChunkFrame = {
  body?: string;
  continuation?: boolean;
  replay?: boolean;
  seq?: number;
};
/** Highest chunk `seq` this client applied, per request id. */
declare class AppliedChunkLedger {
  private readonly applied;
  record(requestId: string, seq: number | undefined): void;
  /** Whether `frame` replays a continuation chunk this client already applied. */
  isAppliedReplay(requestId: string, frame: ChunkFrame): boolean;
  forget(requestId: string): void;
  clear(): void;
}
//#endregion
//#region src/chat/ws-chat-transport.d.ts
/**
 * Agent-like interface for sending/receiving WebSocket messages.
 * Matches `AgentClient` from `agents/client` and the connection returned by
 * `useAgent` from `agents/react`.
 */
interface AgentConnection {
  send: (data: string) => boolean | void;
  addEventListener: (
    type: string,
    listener: (event: MessageEvent) => void,
    options?: {
      signal?: AbortSignal;
    }
  ) => void;
  removeEventListener: (
    type: string,
    listener: (event: MessageEvent) => void
  ) => void;
}
type WebSocketChatTransportOptions<ChatMessage extends UIMessage = UIMessage> =
  {
    /** The framework-neutral AgentClient or useAgent connection. */ agent: AgentConnection;
    /**
     * Callback to add custom fields to the request body before sending.
     */
    prepareBody?: (options: {
      messages: ChatMessage[];
      trigger: "submit-message" | "regenerate-message";
      messageId?: string;
    }) => Promise<Record<string, unknown>> | Record<string, unknown>;
    /**
     * Optional set to track active request IDs.
     * IDs are added when a request starts and removed when it completes.
     * Used by the onAgentMessage handler to skip messages already handled by the transport.
     */
    activeRequestIds?: Set<string>;
    /**
     * Whether generic client-side abort/cancel lifecycle should cancel the
     * server turn. Explicit cancellation via cancelActiveServerTurn() always
     * sends CF_AGENT_CHAT_REQUEST_CANCEL.
     * @default false
     */
    cancelOnClientAbort?: boolean;
    /**
     * Called when a `submit-message` request frame was buffered rather than sent
     * immediately (the socket was not OPEN, so PartySocket queued it for the next
     * reconnect). The hook uses this to preserve the optimistic message across the
     * reconnect transcript replay. `messageId` is the submitted user message's id.
     */
    onRequestBuffered?: (messageId: string | undefined) => void;
  };
/**
 * ChatTransport that sends messages over WebSocket and returns a
 * ReadableStream<UIMessageChunk> that the AI SDK's useChat consumes directly.
 *
 * This low-level transport handles new and regenerated request streams plus
 * cancellation. Higher-level protocol coordination such as automatic reconnect
 * resume, cross-tab transcript synchronization, and client-tool continuations
 * is provided by integrations such as `useAgentChat`.
 */
declare class WebSocketChatTransport<
  ChatMessage extends UIMessage = UIMessage
> implements ChatTransport<ChatMessage> {
  agent: AgentConnection;
  private prepareBody?;
  private activeRequestIds?;
  private cancelOnClientAbort;
  private onRequestBuffered?;
  private _resumeResolver;
  /**
   * Continuation chunks this client applied, shared with the hook's fallback
   * observer so a replay after reconnect skips them on either path (#1951).
   */
  readonly appliedChunks: AppliedChunkLedger;
  private _resumeNoneResolver;
  private _onStreamPending;
  private _retryResumeProbe;
  private _expectToolContinuation;
  private _abortToolContinuation;
  private _activeServerTurnId;
  private _cancelAttachedStream;
  private _detachResumeStream;
  constructor(options: WebSocketChatTransportOptions<ChatMessage>);
  /**
   * Point the singleton transport at a new Agent connection. A pending resolver
   * belongs to the old Chat/socket generation and must settle before messages
   * from the replacement connection can be consumed (#1914 review).
   */
  setAgent(agent: AgentConnection): void;
  setCancelOnClientAbort(cancelOnClientAbort: boolean): void;
  /**
   * Explicitly cancel the active server turn, if any.
   * This is separate from generic client-side abort/cancel lifecycle so
   * clients can detach locally without stopping server work.
   */
  cancelActiveServerTurn(): boolean;
  /**
   * The server turn this transport last attached to that has not reported a
   * terminal frame. A socket close ends the local stream but keeps this set,
   * since the server keeps running the turn.
   */
  get activeServerTurnId(): string | null;
  private sendCancelFrame;
  private setActiveServerTurn;
  private clearActiveServerTurn;
  /**
   * Mark that the next reconnectToStream() call should attach to a
   * server-initiated tool continuation rather than a page-load resume.
   */
  expectToolContinuation(): void;
  /**
   * Abort the active client-side tool continuation stream, if one is attached
   * to a server request id.
   */
  abortActiveToolContinuation(): boolean;
  /**
   * True when the transport is waiting for a resume handshake.
   */
  isAwaitingResume(): boolean;
  /**
   * Settle and detach the current handshake without interpreting it as a
   * server-idle response. Used when the owning hook/agent generation changes.
   */
  cancelPendingResume(): boolean;
  /**
   * Invalidate all client-side resume state for an obsolete hook/agent
   * generation without cancelling its durable server turn.
   */
  resetResumeState(): void;
  /**
   * Re-send the active handshake request on the latest socket generation. This
   * preserves one AI SDK resume operation while recovering a request/reply lost
   * with the previous WebSocket.
   */
  retryPendingResume(): boolean;
  /**
   * Called by onAgentMessage when it receives CF_AGENT_STREAM_RESUMING.
   * If reconnectToStream is waiting, this handles the resume handshake
   * (ACK + stream creation) and returns true. Otherwise returns false
   * so the caller can use its own fallback path.
   */
  handleStreamResuming(data: { id: string }): boolean;
  /**
   * Called by onAgentMessage when it receives CF_AGENT_STREAM_RESUME_NONE.
   * If reconnectToStream is waiting, resolves the promise with null
   * immediately (no 5-second timeout). Returns true if handled.
   */
  handleStreamResumeNone(data?: { probeId?: string }): boolean;
  /**
   * Called by onAgentMessage when it receives CF_AGENT_STREAM_PENDING (#1784):
   * the server accepted a turn but its stream has not started yet. If a resume
   * path is awaiting, extend its probe timeout (so it keeps waiting for the
   * eventual STREAM_RESUMING / STREAM_RESUME_NONE instead of resolving null
   * after the short window). Returns true if a waiting path consumed it.
   */
  handleStreamPending(): boolean;
  /**
   * Called by the hook's shared message handler when a server turn finishes
   * outside the currently attached transport stream, such as after local-only
   * client cleanup.
   */
  handleServerTurnCompleted(requestId: string): void;
  /**
   * Register a server turn that is being rendered outside a transport-owned
   * stream, such as the hook's fallback cross-tab/resume observer path.
   */
  observeServerTurn(requestId: string): void;
  sendMessages(options: {
    chatId: string;
    messages: ChatMessage[];
    abortSignal: AbortSignal | undefined;
    trigger: "submit-message" | "regenerate-message";
    messageId?: string;
    body?: object;
    headers?: Record<string, string> | Headers;
    metadata?: unknown;
  }): Promise<ReadableStream<UIMessageChunk>>;
  reconnectToStream(_options: {
    chatId: string;
  }): Promise<ReadableStream<UIMessageChunk> | null>;
  /**
   * Creates a deferred ReadableStream for client-side tool continuations.
   * The stream is returned immediately so AI SDK status becomes "submitted"
   * right after addToolOutput()/addToolApprovalResponse(), then it waits for
   * the server to announce the continuation via STREAM_RESUMING.
   */
  private _createToolContinuationStream;
  /**
   * Creates a ReadableStream that receives resumed stream chunks
   * and forwards them to useChat as UIMessageChunk objects.
   */
  private _createResumeStream;
}
//#endregion
export {
  WebSocketChatTransport as n,
  WebSocketChatTransportOptions as r,
  AgentConnection as t
};
//# sourceMappingURL=ws-chat-transport-BbT1A5Lc.d.ts.map
