import type { CompanyClient } from './company.js';
import type { ConversationEvent, ConversationState, EventsPage, OutgoingMessage, PoppyProtocolEntry, StartConversationResponse, TextDelta } from './types.js';
/** A fresh message ID: URL-safe base64, prefixed, unique for the User (7.2, 7.3). */
export declare function newMessageId(): string;
/** Picks the `poppy` conversation protocol entry (7.1); unknown types are skipped. */
export declare function poppyProtocol(company: CompanyClient): PoppyProtocolEntry | undefined;
export type StreamItem = {
    kind: 'event';
    event: ConversationEvent;
} | {
    kind: 'delta';
    delta: TextDelta;
}
/** The reader reconnected; any provisional `text-delta` pieces must be dropped (7.6). */
 | {
    kind: 'reconnected';
}
/** `cursor_expired`: the read restarted from the beginning; part of history is missing. */
 | {
    kind: 'history_gap';
};
export interface FollowOptions {
    signal?: AbortSignal | undefined;
    /** Stop once the conversation is `idle`, `queued` or `closed` after this many events. */
    untilSettled?: boolean | undefined;
    /** Prefer SSE (default). When the Company answers with JSON, long-polling is used. */
    stream?: boolean | undefined;
    /** Long-poll `wait` seconds. */
    wait?: number | undefined;
}
/**
 * Client for one Company's Poppy conversation endpoint (section 7). Every request carries the
 * Session Token with a DPoP proof (7.2), through `CompanyClient.fetch`.
 */
export declare class ConversationClient {
    readonly company: CompanyClient;
    readonly endpoint: string;
    private readonly resource?;
    /** Narrower scope for every request of this client (4.3 "Narrower tokens"), when set. */
    private readonly scope?;
    constructor(company: CompanyClient, entry?: PoppyProtocolEntry | undefined, options?: {
        scope?: string | undefined;
    });
    private url;
    /**
     * POST with retries on network errors / 5xx. Safe because the message ID makes the request
     * idempotent: the Company returns the original response for a repeat (7.3).
     */
    private post;
    private remember;
    /** Starts a conversation (7.3), or a Direct Conversation with `parentConversationId` (7.10). */
    start(message: OutgoingMessage, opts?: {
        parentConversationId?: string | undefined;
        wait?: number | undefined;
        cursor?: string | undefined;
    }): Promise<StartConversationResponse>;
    /** Sends another message (7.3). Returns 202 with `status`/`responder` (+ events with `wait`). */
    send(id: string, message: OutgoingMessage, opts?: {
        wait?: number | undefined;
        cursor?: string | undefined;
    }): Promise<StartConversationResponse>;
    /** One read of events after `cursor` (7.5). */
    read(id: string, opts?: {
        cursor?: string | undefined;
        wait?: number | undefined;
    }): Promise<EventsPage>;
    /** Asks for a person at the Company (7.9). */
    handoff(id: string): Promise<ConversationState>;
    /** Closes the conversation (7.12). */
    close(id: string): Promise<ConversationState>;
    /**
     * Reads (long-polling, JSON) until the Company is no longer `working` and `has_more` is
     * false, returning the new events. Used by the autonomous `ask` mode.
     */
    collect(id: string, opts?: {
        timeoutMs?: number | undefined;
        wait?: number | undefined;
    }): Promise<{
        events: ConversationEvent[];
        state: ConversationState;
    }>;
    /**
     * Follows a conversation's events in order, from the saved cursor: SSE when the Company
     * streams (reconnecting with `Last-Event-ID`), long-polling otherwise. Skips event IDs it
     * already handled, restarts from the beginning on `cursor_expired`, and persists the cursor.
     */
    follow(id: string, opts?: FollowOptions): AsyncGenerator<StreamItem>;
}
//# sourceMappingURL=conversations.d.ts.map