@convo-lang/convo-lang
Version:
The language of AI
529 lines (528 loc) • 24.3 kB
TypeScript
import { AnyFunction, CancelToken, DisposeCallback, ReadonlySubject } from "@iyio/common";
import { Observable, Subscription } from "rxjs";
import { ZodType, ZodTypeAny, z } from "zod";
import { ConvoExecutionContext } from "./ConvoExecutionContext.js";
import { ConvoRoom } from "./ConvoRoom.js";
import { ConvoComponentCompletionHandler, ConvoComponentDef, ConvoComponentMessagesCallback, ConvoComponentSubmissionWithIndex } from "./convo-component-types.js";
import { FindConvoMessageOptions } from "./convo-lib.js";
import { ConvoRagCallback } from "./convo-rag-types.js";
import { AppendConvoMessageObjOptions, AppendConvoOptions, BeforeCreateConversationExeCtx, CloneConversationOptions, ConvoAgentDef, ConvoAppend, ConvoCapability, ConvoCompletion, ConvoCompletionMessage, ConvoCompletionOptions, ConvoCompletionService, ConvoCompletionServiceAndModel, ConvoCompletionStartEvt, ConvoConversationCache, ConvoConversationConverter, ConvoDefItem, ConvoFunction, ConvoFunctionDef, ConvoImportContext, ConvoImportHandler, ConvoImportService, ConvoImportSourceEvt, ConvoMessage, ConvoMessageAndOptStatement, ConvoMessageModification, ConvoMessagePart, ConvoMessagePrefixOptions, ConvoModelInfo, ConvoModelInputOutputPair, ConvoModule, ConvoObject, ConvoParsingResult, ConvoPrintFunction, ConvoScope, ConvoScopeFunction, ConvoStartOfConversationCallback, ConvoSubTask, ConvoTask, ConvoTokenUsage, ConvoTypeDef, ConvoVarDef, FlatConvoConversation, FlatConvoMessage, FlattenConvoOptions, InlineConvoPrompt } from "./convo-types.js";
export interface ConversationOptions {
name?: string;
room?: ConvoRoom;
userRoles?: string[];
assistantRoles?: string[];
systemRoles?: string[];
roleMap?: Record<string, string>;
completionService?: ConvoCompletionService<any, any> | ConvoCompletionService<any, any>[];
converters?: ConvoConversationConverter<any, any>[];
serviceCapabilities?: ConvoCapability[];
capabilities?: ConvoCapability[];
disableMessageCapabilities?: boolean;
maxAutoCompleteDepth?: number;
/**
* If true the conversation is an agent
*/
isAgent?: boolean;
/**
* 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;
/**
* Called whenever tokens usage occurs
*/
onTokenUsage?: (usage: ConvoTokenUsage) => void;
/**
* If defined the conversation will add used tokens to the usage object
*/
usage?: ConvoTokenUsage;
/**
* 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[];
/**
* Handles import requests
*/
importHandler?: ConvoImportHandler;
importServices?: ConvoImportService[] | null;
onComponentMessages?: ConvoComponentMessagesCallback | ConvoComponentMessagesCallback[];
/**
* Used to complete conversations ending with a component
*/
componentCompletionCallback?: ConvoComponentCompletionHandler;
/**
* If true arbitrary code will be allowed to be executed.
*/
allowEvalCode?: boolean;
ragPrefix?: string;
ragSuffix?: string;
ragTemplate?: string;
formatWhitespace?: boolean;
externFunctions?: Record<string, AnyFunction>;
externScopeFunctions?: Record<string, ConvoScopeFunction>;
components?: Record<string, ConvoComponentDef>;
/**
* Array of modules that can be imported. The modules are not automatically imported, they have
* to be imported to take effect.
*/
modules?: ConvoModule[];
/**
* Called each time the conversation is flattened allowing dynamic messages to be inserted
* at the start of the conversation.
*/
getStartOfConversation?: ConvoStartOfConversationCallback;
/**
* Used to cache responses
*/
cache?: boolean | ConvoConversationCache | ConvoConversationCache[];
/**
* If true the flattened version of the conversation will be logged before sending to LLMs.
* @note Cached responses are not logged. Use `logFlatCached` to log both cached and non-cached
* flattened conversations.
*/
logFlat?: boolean;
/**
* If true both cached and non-cached versions of the conversation are logged before being set
* to an LLM
*/
logFlatCached?: boolean;
beforeCreateExeCtx?: BeforeCreateConversationExeCtx;
defaultModel?: string | null;
childDepth?: number;
/** When true, message triggers will not be evaluated automatically */
disableTriggers?: boolean;
/**
* Prevents transforms from being applied
*/
disableTransforms?: boolean;
/**
* When the current conversation is an inline prompt inlineHost is the conversation that is
* hosting inline conversation
*/
inlineHost?: Conversation;
/**
* The inline prompt the conversation the conversation represents
*/
inlinePrompt?: InlineConvoPrompt;
/**
* A template used to wrap imported content such as markdown files.
*/
defaultImportTemplate?: string;
/**
* If true the conversation will not able to call standard library functions to access external
* resources or tools
*/
sandboxMode?: boolean;
}
export declare class Conversation {
private _convo;
get convo(): string;
getConvoStrings(): string[];
readonly instanceId: number;
readonly name: string;
readonly room: ConvoRoom;
readonly isAgent: boolean;
readonly childDepth: number;
readonly inlineHost?: Conversation;
inlinePrompt?: InlineConvoPrompt;
private _messages;
get messages(): ConvoMessage[];
private readonly _onAppend;
get onAppend(): Observable<ConvoAppend>;
private readonly _onImportSource;
get onImportSource(): Observable<ConvoImportSourceEvt>;
private readonly _openTasks;
get openTasksSubject(): ReadonlySubject<ConvoTask[]>;
get openTasks(): ConvoTask[];
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 _onTokenUsage?;
/**
* Tracks the token usages of the Conversation. Includes tokens use by children and clones of the conversation.
*/
readonly usage: ConvoTokenUsage;
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.
*
* @note shares the same functionality as defaultVars. Maybe remove
*/
readonly unregisteredVars: Record<string, any>;
userRoles: string[];
assistantRoles: string[];
systemRoles: string[];
roleMap: Record<string, string>;
private completionService?;
private converters;
maxAutoCompleteDepth: number;
beforeCreateExeCtx?: BeforeCreateConversationExeCtx;
readonly externFunctions: Record<string, ConvoScopeFunction>;
readonly components: Record<string, ConvoComponentDef>;
/**
* Array of modules that can be imported. The modules are not automatically imported, they have
* to be imported to take effect.
*/
readonly modules: ConvoModule[];
/**
* 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;
disableTriggers: boolean;
/**
* Prevents transforms from being applied
*/
disableTransforms: boolean;
dynamicFunctionCallback: ConvoScopeFunction | undefined;
private readonly componentCompletionCallback?;
/**
* A callback used to implement rag retrieval.
*/
private readonly ragCallback?;
getStartOfConversation?: ConvoStartOfConversationCallback;
/**
* 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;
get sandboxMode(): boolean;
readonly defaultVars: Record<string, any>;
cache?: ConvoConversationCache[];
/**
* If true the flattened version of the conversation will be logged before sending to LLMs.
* @note Cached responses are not logged. Use `logFlatCached` to log both cached and non-cached
* flattened conversations.
*/
logFlat: boolean;
/**
* If true both cached and non-cached versions of the conversation are logged before being set
* to an LLM
*/
logFlatCached: boolean;
defaultModel?: string;
/**
* Sub conversations
*/
readonly subs: Record<string, Conversation>;
constructor(options?: ConversationOptions);
initMessageReady(): boolean;
addTask(task: ConvoTask): DisposeCallback;
popTask(): void;
watchComponentMessages(callback: ConvoComponentMessagesCallback): Subscription;
private getMessageListCapabilities;
/**
* Gets the capabilities enabled by the given tags. If disableMessageCapabilities is true
* undefined is always returned
*/
private getMessageCapabilities;
private _isDisposed;
private readonly _disposeToken;
get disposeToken(): CancelToken;
get isDisposed(): boolean;
dispose(): void;
private _defaultApiKey;
setDefaultApiKey(key: string | null | (() => string | null)): void;
getDefaultApiKey(): string | null;
private parseCode;
private readonly enabledCapabilities;
enableCapability(cap: ConvoCapability): void;
autoUpdateCompletionService(): void;
createChild(options?: ConversationOptions): Conversation;
getCloneOptions(options?: ConversationOptions): ConversationOptions;
/**
* Creates a new Conversation and appends the messages of this conversation to the newly
* created conversation.
*/
clone({ inlinePrompt, triggerName, empty, noFunctions, systemOnly, removeAgents, dropLast, dropUntilContent, last, cloneConvoString, }?: CloneConversationOptions, convoOptions?: ConversationOptions): Conversation;
private filterConvoMessagesForTrigger;
/**
* 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;
private appendMsgsAry;
private defineAgent;
private appendAfterCall;
readonly agents: ConvoAgentDef[];
/**
* Appends new messages to the conversation and by default does not add code to the conversation.
*/
appendMessageObject(message: ConvoMessage | ConvoMessage[], { disableAutoFlatten, appendCode, source, }?: AppendConvoMessageObjOptions): void;
private transformMessageBeforeAppend;
appendDefineVars(vars: Record<string, any>): void;
appendDefineVar(name: string, value: any): void;
append(convo: ConvoObject<any>, options?: AppendConvoOptions): ConvoParsingResult;
append(messages: string | (ConvoMessagePart | string)[], mergeWithPrev?: boolean, throwOnError?: boolean): ConvoParsingResult;
append(messages: string | (ConvoMessagePart | string)[], options?: AppendConvoOptions): 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>;
getLastMessage(): ConvoMessage | undefined;
getLastUserMessage<T extends ConvoMessage | FlatConvoMessage | ConvoCompletionMessage>(messages: (T | null | undefined)[] | null | undefined): T | undefined;
getLastUserOrThinkingMessage<T extends ConvoMessage | FlatConvoMessage | ConvoCompletionMessage>(messages: (T | null | undefined)[] | null | undefined): T | 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 readonly modelServiceMap;
private readonly endpointModelServiceMap;
getCompletionServiceAsync(flat: FlatConvoConversation): Promise<ConvoCompletionServiceAndModel | undefined>;
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>;
/**
* Appends the convo to this conversation and return the completion result. Using completeConvoAsync
* instead of awaiting the convo has a key difference in the fact that function responses
* are waited for by default when calling completeConvoAsync.
*/
completeAsync<T>(convo: ConvoObject<T>, options?: ConvoCompletionOptions): Promise<T>;
/**
* 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>;
private readonly httpEndpointServices;
private getHttpService;
private completeWithServiceAsync;
/**
* 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>;
private readonly _onCompletionStart;
/**
* Occurs at the start of a public completion.
*/
get onCompletionStart(): Observable<ConvoCompletionStartEvt>;
/**
* 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 completeParallelAsync;
getModelsAsync(serviceOrId: string | ConvoCompletionService<any, any>): Promise<ConvoModelInfo[]>;
getAllModelsAsync(): Promise<ConvoModelInfo[]>;
private completeParallelMessagesAsync;
private readonly _isCompleting;
get isCompletingSubject(): ReadonlySubject<boolean>;
get isCompleting(): boolean;
private _completeAsync;
private transformUsingFlatTransformersAsync;
private writeTransformResult;
private writeTemplates;
private startSubTasks;
getReversedMappedRole(role: string | null | undefined): string;
getMappedRole(role: string | null | undefined): string;
createConvoExecutionContext(append?: string[]): ConvoExecutionContext;
isSystemMessage(msg: ConvoMessage | FlatConvoMessage | ConvoCompletionMessage | null | undefined): boolean;
isAssistantMessage(msg: ConvoMessage | FlatConvoMessage | ConvoCompletionMessage | null | undefined): boolean;
isUserMessage(msg: ConvoMessage | FlatConvoMessage | ConvoCompletionMessage | null | undefined): boolean;
isModificationMessage(msg: ConvoMessage | FlatConvoMessage | ConvoCompletionMessage | null | undefined): boolean;
isUserOrThinkingMessage(msg: ConvoMessage | FlatConvoMessage | ConvoCompletionMessage | null | undefined): boolean;
isContentMessage(msg: ConvoMessage | FlatConvoMessage | ConvoCompletionMessage | null | undefined): boolean;
private flattenMsg;
private importMessages;
/**
* Called when an import message is found
*/
private loadImportsAsync;
importAsync(name: string, context: ConvoImportContext, index?: number, externFunctions?: Record<string, ConvoScopeFunction>): Promise<ConvoMessage[]>;
readonly importedModules: Record<string, ConvoModule>;
private registerModule;
private getImportTemplateMessage;
flattenSourceAsync({ appendTo, convo, cacheName, options, passExe }: FlattenSourceOptions): Promise<boolean>;
private flattenWithTriggersAsync;
flattenAsync(exe?: ConvoExecutionContext, { task, setCurrent, discardTemplates, threadFilter, toolChoice, messages: messageOverride, disableTransforms, initFlatMessages, messageStartIndex, flatMessages, excludeMessages, excludeMessageSetters, importOnly, }?: FlattenConvoOptions): Promise<FlatConvoConversation>;
private applyRagMode;
private getThreadFilter;
private applyTagsAndState;
private applyResponseFormat;
shouldDebug(exe?: ConvoExecutionContext): boolean;
readonly debugToConversation: (...args: any[]) => void;
/**
* Appends arguments as formatted comments to the conversation with the specified role.
* Used for debugging and logging execution information.
*
* @param role - The role to use for the comment message
* @param args - Arguments to format and append as comments
*/
appendArgsAsComment(role: string, args: any[], msgAry?: boolean): 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;
implementExternFunction(name: string, func: (...param: any[]) => any): (scope: ConvoScope) => any;
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;
private readonly onComponentSubmission;
submitComponentData(submission: ConvoComponentSubmissionWithIndex): void;
private completeUsingComponentInputAsync;
private completeUsingEvalAsync;
/**
* Appends output returned from an LLM
*/
appendModelOutputAsync(modelInputOutput: ConvoModelInputOutputPair): Promise<ConvoCompletion>;
/**
* Converts the conversation into input for its target LLM.
*/
toModelInputAsync(flat?: FlatConvoConversation): Promise<any>;
/**
* Converts the conversation into input for its target LLM as a string.
*/
toModelInputStringAsync(flat?: FlatConvoConversation): Promise<string>;
addUsage(usage: Partial<ConvoTokenUsage>): void;
getDebuggingImportCode(): string;
getDebuggingModulesCode(): string;
private evalTriggersAsync;
appendModification(modification: ConvoMessageModification, content: string, flat?: FlatConvoConversation): void;
appendResponse(content: string, flat: FlatConvoConversation): void;
private appendFunctionSetters;
findMessage(options: FindConvoMessageOptions): ConvoMessage | undefined;
/**
* Merges "replace", "append" and "prepend" messages with their corresponding content messages.
* This function processes a list of flat conversation messages and applies content modification
* operations (replace, append, prepend) to their target content messages.
*
* @param messages - Array of flat conversation messages to process in-place
*/
private mergeConvoFlatContentMessages;
}
interface FlattenSourceOptions {
convo: string;
appendTo?: FlatConvoConversation;
cacheName?: string;
options?: FlattenConvoOptions;
passExe?: boolean;
}
export {};