import EventEmitter from 'node:events';
import { Headers } from 'node-fetch';

declare class Conversation extends EventEmitter {
    session: Session;
    message: string;
    /**
     * The response of the conversation, resolved when the conversation is complete.
     */
    response: Promise<string>;
    constructor(session: Session, message: string);
    run(): Promise<string>;
    converse(): Promise<string>;
    /**
     * Emitted when a partial response is received.
     */
    on(event: "partial", listener: (partial: string) => void): this;
    /**
     * Emitted when the conversation is complete.
     */
    on(event: "complete", listener: (complete: string) => void): this;
    /**
     * Emitted when an error occurs.
     */
    on(event: "error", listener: (error: Error) => void): this;
    /**
     * Emitted when a partial response is received.
     */
    once(event: "partial", listener: (partial: string) => void): this;
    /**
     * Emitted when the conversation is complete.
     */
    once(event: "complete", listener: (complete: string) => void): this;
    /**
     * Emitted when an error occurs.
     */
    once(event: "error", listener: (error: Error) => void): this;
    off(event: "partial", listener: (partial: string) => void): this;
    off(event: "complete", listener: (complete: string) => void): this;
    off(event: "error", listener: (error: Error) => void): this;
    emit(event: "partial", partial: string): boolean;
    emit(event: "complete", complete: string): boolean;
    emit(event: "error", error: Error): boolean;
}
interface Block {
    message: {
        id: string;
        role: "assistant";
        user: null;
        create_time: null;
        update_time: null;
        content: {
            content_type: "text";
            parts: string[];
        };
        end_turn: null;
        weight: number;
        metadata: unknown;
        recipient: "all";
    };
    conversation_id: string;
    error: null;
}

declare class Session extends EventEmitter {
    agent: Agent;
    /**
     * Session id.
     */
    id: string;
    /**
     * The conversation history, including the user's messages and the assistant's replies.
     * Only the assistant's replies have a conversation property.
     */
    history: {
        author: "user" | "assistant";
        message: string;
        id: string;
        conversation?: Conversation;
    }[];
    constructor(agent: Agent);
    /**
     * Sends a message to the session.
     * @param message The message to send.
     * @returns A new conversation.
     */
    talk(message: string): Conversation;
    rename(id: string): void;
    /**
     * Get all the replies from the session.
     * @returns An array of conversations.
     */
    replies(): Conversation[];
    on(event: "rename", listener: (data: {
        old: string;
        new: string;
    }) => void): this;
}

declare class Agent extends EventEmitter {
    token: string;
    refresh_token?: string | undefined;
    sessions: Map<string, Session>;
    backend: string;
    timeout: number;
    /**
     * @param token - The token to use.
     * @param refresh_token - Optional refresh token.
     * @param options - Options, including the api backend and timeout.
     */
    constructor(token: string, refresh_token?: string | undefined, { backend, timeout, }?: {
        backend?: string;
        timeout?: number;
    });
    /**
     * Creates a new session.
     */
    session(): Session;
    /**
     * Refreshes the token using the refresh token.
     *
     * @throws Error if no refresh token is set.
     * @throws Error if the token could not be refreshed.
     */
    refresh(): Promise<void>;
    /**
     * Validates the token
     * @returns true if the token is valid, false otherwise.
     */
    validate(): boolean;
    on(event: "refresh", listener: (data: {
        token: string;
        refresh: string;
    }) => void): this;
    off(event: "refresh", listener: (data: {
        token: string;
        refresh: string;
    }) => void): this;
}

declare function make_headers(token?: string): Headers;
declare function moderate(token: string, input: string, backend?: string, timeout?: number): Promise<{
    flagged: boolean;
    blocked: boolean;
    moderation_id: string;
}>;
/**
 * Sends a request to the ChatGPT API to get a response body.
 *
 * @param token - The ChatGPT token
 * @param content - The content of the message
 * @param conversation_id - The conversation id (optional)
 * @param parent_id - The parent id (optional)
 * @param backend - The ChatGPT backend (optional)
 * @param timeout - The timeout (optional)
 * @returns The response body from the ChatGPT API
 */
declare function converse(token: string, content: string, conversation_id?: string, parent_id?: string, backend?: string, timeout?: number): Promise<NodeJS.ReadableStream>;
declare function refresh(refresh_token: string): Promise<{
    token: string;
    refresh: string;
}>;

export { Agent, Block, Conversation, Session, converse, make_headers, moderate, refresh };
