import { ReadonlySubject } from "@iyio/common";
import { Observable } from "rxjs";
import { ZodType, ZodTypeAny, z } from "zod";
import { ConvoExecutionContext } from "./ConvoExecutionContext";
import { AppendConvoMessageObjOptions, CloneConversationOptions, ConvoAppend, ConvoCapability, ConvoCompletion, ConvoCompletionOptions, ConvoCompletionService, ConvoDefItem, ConvoFunction, ConvoFunctionDef, ConvoImportHandler, ConvoMessage, ConvoMessageAndOptStatement, ConvoMessagePart, ConvoMessagePrefixOptions, ConvoParsingResult, ConvoPrintFunction, ConvoRagCallback, ConvoScopeFunction, ConvoSubTask, ConvoTokenUsage, ConvoTypeDef, ConvoVarDef, FlatConvoConversation, FlattenConvoOptions } from "./convo-types";
export interface ConversationOptions {
    userRoles?: string[];
    roleMap?: Record<string, string>;
    completionService?: ConvoCompletionService;
    serviceCapabilities?: ConvoCapability[];
    capabilities?: ConvoCapability[];
    disableMessageCapabilities?: boolean;
    maxAutoCompleteDepth?: number;
    /**
     * If true time tags will be added to appended user message
     */
    trackTime?: boolean;
    /**
     * If true tokenUsage tags will be added to completed messages
     */
    trackTokens?: boolean;
    /**
     * If true model tags will be added to completed messages
     */
    trackModel?: boolean;
    /**
     * If true the conversation will not automatically be flattened when new message are appended.
     */
    disableAutoFlatten?: boolean;
    /**
     * Number of milliseconds to delay before flattening the conversation. The delay is used to
     * debounce appends.
     */
    autoFlattenDelayMs?: number;
    /**
     * A function that will be used to output debug values. By default debug information is written
     * to the output of the conversation as comments
     */
    debug?: (...values: any[]) => void;
    debugMode?: boolean;
    /**
     * If true all text based messages will be parsed as markdown and the lines of the markdown will
     * be used to set vars.
     */
    setMarkdownVars?: boolean;
    /**
     * If true all text based message will be parsed as markdown
     */
    parseMarkdown?: boolean;
    /**
     * A callback used to implement rag retrieval.
     */
    ragCallback?: ConvoRagCallback;
    /**
     * An initial convo script to append to the Conversation
     */
    initConvo?: string;
    /**
     * Called at the end of the Conversation constructor
     */
    onConstructed?: (convo: Conversation) => void;
    defaultVars?: Record<string, any>;
    /**
     * Array of ConvoDefItems to define
     */
    define?: ConvoDefItem[];
    importHandler?: ConvoImportHandler;
}
export declare class Conversation {
    private _convo;
    get convo(): string;
    getConvoStrings(): string[];
    private _messages;
    get messages(): ConvoMessage[];
    private readonly _onAppend;
    get onAppend(): Observable<ConvoAppend>;
    private readonly _activeTaskCount;
    get activeTaskCountSubject(): ReadonlySubject<number>;
    get activeTaskCount(): number;
    private readonly _trackTime;
    get trackTimeSubject(): ReadonlySubject<boolean>;
    get trackTime(): boolean;
    set trackTime(value: boolean);
    private readonly _trackTokens;
    get trackTokensSubject(): ReadonlySubject<boolean>;
    get trackTokens(): boolean;
    set trackTokens(value: boolean);
    private readonly _trackModel;
    get trackModelSubject(): ReadonlySubject<boolean>;
    get trackModel(): boolean;
    set trackModel(value: boolean);
    private readonly _debugMode;
    get debugModeSubject(): ReadonlySubject<boolean>;
    get debugMode(): boolean;
    set debugMode(value: boolean);
    private readonly _flat;
    get flatSubject(): ReadonlySubject<FlatConvoConversation | null>;
    /**
     * A reference to the last flattening of the conversation
     */
    get flat(): FlatConvoConversation | null;
    private readonly _subTasks;
    get subTasksSubject(): ReadonlySubject<ConvoSubTask[]>;
    get subTasks(): ConvoSubTask[];
    private readonly _beforeAppend;
    get beforeAppend(): Observable<ConvoAppend>;
    /**
     * Unregistered variables will be available during execution but will not be added to the code
     * of the conversation. For example the __cwd var is often used to set the current working
     * directory but is not added to the conversation code.
     */
    readonly unregisteredVars: Record<string, any>;
    userRoles: string[];
    roleMap: Record<string, string>;
    private completionService?;
    maxAutoCompleteDepth: number;
    readonly externFunctions: Record<string, ConvoScopeFunction>;
    /**
     * The default capabilities of the conversation. Additional capabilities can be enabled by
     * the first and last message of the conversation as long a disableMessageCapabilities is not
     * true.
     */
    readonly capabilities: ConvoCapability[];
    /**
     * If true capabilities enabled by message in the conversation will be ignored.
     */
    readonly disableMessageCapabilities: boolean;
    /**
     * Capabilities that should be enabled by the underlying completion service.
     */
    readonly serviceCapabilities: ConvoCapability[];
    private readonly disableAutoFlatten;
    private readonly autoFlattenDelayMs;
    dynamicFunctionCallback: ConvoScopeFunction | undefined;
    /**
     * A callback used to implement rag retrieval.
     */
    private readonly ragCallback?;
    /**
     * A function that will be used to output debug values. By default debug information is written
     * to the output of the conversation as comments
     */
    debug?: (...values: any[]) => void;
    print: ConvoPrintFunction;
    private readonly defaultOptions;
    readonly defaultVars: Record<string, any>;
    constructor(options?: ConversationOptions);
    private getMessageListCapabilities;
    /**
     * Gets the capabilities enabled by the given tags. If disableMessageCapabilities is true
     * undefined is always returned
     */
    private getMessageCapabilities;
    private _isDisposed;
    get isDisposed(): boolean;
    dispose(): void;
    private _defaultApiKey;
    setDefaultApiKey(key: string | null): void;
    getDefaultApiKey(): string | null;
    private parseCode;
    private readonly enabledCapabilities;
    enableCapability(cap: ConvoCapability): void;
    autoUpdateCompletionService(): void;
    createChild(options?: ConversationOptions): Conversation;
    /**
     * Creates a new Conversation and appends the messages of this conversation to the newly
     * created conversation.
     */
    clone(options?: CloneConversationOptions): Conversation;
    /**
     * Creates a new Conversation and appends the system messages of this conversation to the newly
     * created conversation.
     */
    cloneSystem(): Conversation;
    /**
     * Creates a new Conversation and appends the non-function messages of this conversation to the newly
     * created conversation.
     */
    cloneWithNoFunctions(): Conversation;
    /**
     * Appends new messages to the conversation and by default does not add code to the conversation.
     */
    appendMessageObject(message: ConvoMessage | ConvoMessage[], { disableAutoFlatten, appendCode }?: AppendConvoMessageObjOptions): void;
    private transformMessageBeforeAppend;
    append(messages: string | (ConvoMessagePart | string)[], mergeWithPrev?: boolean, throwOnError?: boolean): ConvoParsingResult;
    private autoFlattenId;
    private autoFlattenAsync;
    private autoFlatPromiseRef;
    private getAutoFlattenPromise;
    private setFlattenAsync;
    /**
     * Get the flattened version of this Conversation.
     * @param noCache If true the Conversation will not used the current cached version of the
     *                flattening and will be re-flattened.
     */
    getLastAutoFlatAsync(noCache?: boolean): Promise<FlatConvoConversation | undefined>;
    appendUserMessage(message: string, options?: ConvoMessagePrefixOptions): void;
    appendAssistantMessage(message: string, options?: ConvoMessagePrefixOptions): void;
    appendMessage(role: string, message: string, options?: ConvoMessagePrefixOptions): void;
    appendDefine(defineCode: string, description?: string): ConvoParsingResult;
    appendTopLevel(defineCode: string, description?: string): ConvoParsingResult;
    getVar(nameOrPath: string, defaultValue?: any): any;
    private getPrefixTags;
    private setFlat;
    callFunctionAsync(fn: ConvoFunction | string, args?: Record<string, any>, options?: ConvoCompletionOptions): Promise<any>;
    appendFunctionCall(functionName: string, args?: Record<string, any>): void;
    completeWithFunctionCallAsync(name: string, args?: Record<string, any>, options?: ConvoCompletionOptions): Promise<ConvoCompletion>;
    /**
     * Appends a user message then competes the conversation
     * @param append Optional message to append before submitting
     */
    completeUserMessageAsync(userMessage: string): Promise<ConvoCompletion>;
    /**
     * Submits the current conversation and optionally appends messages to the conversation before
     * submitting.
     * @param append Optional message to append before submitting
     */
    completeAsync(appendOrOptions?: string | ConvoCompletionOptions): Promise<ConvoCompletion>;
    /**
     * Completes the conversation and returns the last message as JSON. It is recommended using
     * `@json` mode with the last message that is appended.
     */
    completeJsonAsync(appendOrOptions?: string | ConvoCompletionOptions): Promise<any>;
    /**
     * Completes the conversation and returns the last message as JSON. It is recommended using
     * `@json` mode with the last message that is appended.
     */
    completeJsonSchemeAsync<Z extends ZodTypeAny = ZodType<any>, T = z.infer<Z>>(params: Z, userMessage: string): Promise<T | undefined>;
    /**
     * Completes the conversation and returns the last message call params. The last message of the
     * conversation should instruct the LLM to call a function.
     */
    callStubFunctionAsync(appendOrOptions?: string | ConvoCompletionOptions): Promise<any>;
    private tryCompleteAsync;
    private readonly _isCompleting;
    get isCompletingSubject(): ReadonlySubject<boolean>;
    get isCompleting(): boolean;
    private _completeAsync;
    private writeTemplates;
    private startSubTasks;
    getReversedMappedRole(role: string | null | undefined): string;
    getMappedRole(role: string | null | undefined): string;
    createConvoExecutionContext(append?: string[]): ConvoExecutionContext;
    private flattenMsg;
    private importMessages;
    private loadImportsAsync;
    importAsync(name: string, index?: number): Promise<ConvoMessage[]>;
    flattenAsync(exe?: ConvoExecutionContext, { task, setCurrent, discardTemplates, threadFilter, }?: FlattenConvoOptions): Promise<FlatConvoConversation>;
    private applyRagMode;
    private getThreadFilter;
    private isTagConditionTrue;
    private applyTagsAndState;
    private applyResponseFormat;
    shouldDebug(exe?: ConvoExecutionContext): boolean;
    readonly debugToConversation: (...args: any[]) => void;
    private readonly definitionItems;
    define(items: ConvoDefItem | (ConvoDefItem[]), override?: boolean): ConvoParsingResult | undefined;
    defineType(type: ConvoTypeDef, override?: boolean): ConvoParsingResult | undefined;
    defineTypes(types: ConvoTypeDef[], override?: boolean): ConvoParsingResult | undefined;
    defineVar(variable: ConvoVarDef, override?: boolean): ConvoParsingResult | undefined;
    defineVars(vars: ConvoVarDef[], override?: boolean): ConvoParsingResult | undefined;
    defineFunction(fn: ConvoFunctionDef, override?: boolean): ConvoParsingResult | undefined;
    defineFunctions(fns: ConvoFunctionDef[], override?: boolean): ConvoParsingResult | undefined;
    defineLocalFunctions(funcs: Record<string, (...args: any[]) => any>): void;
    private createFunctionImpl;
    getAssignment(name: string, excludePreAssigned?: boolean): ConvoMessageAndOptStatement | undefined;
    private _getAssignment;
    private preAssignMessages;
    /**
     * Used to mark variables, types and function as assigned before actually appending the code.
     */
    preAssign(convoCode: string): void;
    /**
     * Returns the sum of all token usage tags
     */
    getTokenUsage(fromIndex?: number): ConvoTokenUsage;
}
