UNPKG

@convo-lang/convo-lang

Version:
1,346 lines 84.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getConvoDateString = exports.defaultConvoTransformGroup = exports.defaultConvoRenderTarget = exports.convoDateFormat = exports.defaultConvoCacheType = exports.commonConvoCacheTypes = exports.convoTaskTriggers = exports.convoJsDocTags = exports.convoAnonTypePrefix = exports.convoAnonTypeTags = exports.convoDynamicTags = exports.convoTags = exports.convoEvents = exports.defaultConvoRagTol = exports.convoImportModifiers = exports.convoVars = exports.convoFunctions = exports.convoReservedRoles = exports.convoRoles = exports.convoRagTemplatePlaceholder = exports.convoAnyModelName = exports.defaultConvoTask = exports.convoScopedModifiers = exports.convoMsgModifiers = exports.defaultConversationName = exports.convoCaptureMetadataTag = exports.convoMetadataKey = exports.convoEnumFnName = exports.convoGlobalRef = exports.convoInvokeFunctionName = exports.convoInvokeFunctionModifier = exports.convoCallFunctionModifier = exports.convoExternFunctionModifier = exports.convoLocalFunctionModifier = exports.convoPipeFnName = exports.convoTestFnName = exports.convoDefaultFnName = exports.convoCaseFnName = exports.convoSwitchFnName = exports.convoJsonArrayFnName = exports.convoJsonMapFnName = exports.convoArrayFnName = exports.convoMapFnName = exports.convoNewFnName = exports.convoStructFnName = exports.convoDisableAutoCompleteName = exports.convoResultErrorName = exports.convoResultReturnName = exports.convoArgsName = exports.convoBodyFnName = void 0; exports.parseConvoUsageTokens = exports.convoPartialUsageTokensToUsage = exports.convoUsageTokensToString = exports.validateConvoTypeName = exports.validateConvoFunctionName = exports.validateConvoVarName = exports.isValidConvoTypeName = exports.isValidConvoFunctionName = exports.isValidConvoVarName = exports.convoStringToComment = exports.convoStringToCommentOut = exports.convoDescriptionToComment = exports.convoDescriptionToCommentOut = exports.collapseConvoPipes = exports.defaultConvoPrintFunction = exports.spreadConvoArgs = exports.escapeConvoMessageContent = exports.escapeConvo = exports.formatConvoMessage = exports.isValidConvoIdentifier = exports.isValidConvoRole = exports.isReservedConvoRole = exports.convoParamsToObj = exports.convoLabeledScopeParamsToObj = exports.convoLabeledScopeFnParamsToObj = exports.getConvoStructPropertyCount = exports.getConvoMetadata = exports.createConvoMetadataForStatement = exports.parseConvoTransformTag = exports.getFlatConvoTagValues = exports.mapToConvoTags = exports.convoTagsToMap = exports.getConvoFnByTag = exports.findConvoMessage = exports.getConvoFnMessageByTag = exports.getConvoTag = exports.containsConvoTag = exports.convoTagMapToCode = exports.setConvoScopeError = exports.isConvoScopeFunction = exports.createConvoScopeFunction = exports.makeAnyConvoType = exports.createConvoBaseTypeDef = exports.createConvoType = exports.createOptionalConvoValue = exports.passthroughConvoOutputType = exports.passthroughConvoInputType = exports.allowedConvoDefinitionFunctions = exports.defaultConvoVisionResponse = exports.defaultConvoVisionSystemMessage = void 0; exports.setFlatConvoMessageCondition = exports.getFlatConvoMessageCondition = exports.setFlatConvoMessageCachedJsonValue = exports.getFlatConvoMessageCachedJsonValue = exports.getConvoSystemMessage = exports.convertFlatConvoMessageToCompletionMessage = exports.appendFlatConvoMessageSuffix = exports.appendFlatConvoMessagePrefix = exports.getConvoMessageModificationAction = exports.getConvoCompletionServiceModelsAsync = exports.insertSystemMessageIntoFlatConvo = exports.isConvoModelAliasMatch = exports.getConvoDebugLabelComment = exports.evalConvoTransformCondition = exports.getLastConvoSuggestions = exports.getFlattenConversationDisplayString = exports.formatConvoContentSpace = exports.getNormalizedFlatMessageList = exports.getFullFlatConvoMessageContent = exports.flatConvoConversationToBase = exports.getSerializableFlatConvoConversation = exports.createFunctionCallConvoCompletionMessage = exports.createTextConvoCompletionMessage = exports.getLastCalledConvoMessage = exports.getLastNonCalledConvoFlatMessage = exports.getLastConvoMessageWithRole = exports.mergeConvoOptions = exports.isConvoThreadFilterMatch = exports.getLastCompletionMessage = exports.convoMessageToString = exports.escapeConvoTagValue = exports.convoRagDocRefToMessage = exports.shouldDisableConvoAutoScroll = exports.getFlatConvoTagBoolean = exports.parseConvoBooleanTag = exports.getConvoStatementSource = exports.parseConvoMessageTemplate = exports.isConvoMessageIncludedInTask = exports.concatConvoCodeAndAppendEmptyUserMessage = exports.concatConvoCode = exports.removeDanglingConvoUserMessage = exports.parseConvoJsonMessage = exports.parseConvoJsonOrStringMessage = exports.isConvoJsonMessage = exports.calculateConvoTokenUsage = exports.unknownConvoTokenPrice = exports.isConvoTokenUsageEmpty = exports.resetConvoUsageTokens = exports.createEmptyConvoTokenUsage = exports.addConvoUsageTokens = void 0; exports.getAssumedConvoCompletionValue = exports.flatConvoMessagesToTextView = void 0; const common_1 = require("@iyio/common"); const json5_1 = require("@iyio/json5"); const date_fns_1 = require("date-fns"); const ConvoError_1 = require("./ConvoError"); const convo_system_messages_1 = require("./convo-system-messages"); const convo_types_1 = require("./convo-types"); exports.convoBodyFnName = '__body'; exports.convoArgsName = '__args'; exports.convoResultReturnName = '__return'; exports.convoResultErrorName = '__error'; exports.convoDisableAutoCompleteName = '__disableAutoComplete'; exports.convoStructFnName = 'struct'; exports.convoNewFnName = 'new'; exports.convoMapFnName = 'map'; exports.convoArrayFnName = 'array'; exports.convoJsonMapFnName = 'jsonMap'; exports.convoJsonArrayFnName = 'jsonArray'; exports.convoSwitchFnName = 'switch'; exports.convoCaseFnName = 'case'; exports.convoDefaultFnName = 'default'; exports.convoTestFnName = 'test'; exports.convoPipeFnName = 'pipe'; exports.convoLocalFunctionModifier = 'local'; exports.convoExternFunctionModifier = 'extern'; exports.convoCallFunctionModifier = 'call'; exports.convoInvokeFunctionModifier = 'invoke'; exports.convoInvokeFunctionName = 'invoke'; exports.convoGlobalRef = 'convo'; exports.convoEnumFnName = 'enum'; exports.convoMetadataKey = Symbol('convoMetadataKey'); exports.convoCaptureMetadataTag = 'captureMetadata'; exports.defaultConversationName = 'default'; exports.convoMsgModifiers = { /** * When applied to the function the function is used as the default function of an agent */ agent: 'agent', }; exports.convoScopedModifiers = [exports.convoMsgModifiers.agent]; exports.defaultConvoTask = 'default'; exports.convoAnyModelName = '__any__'; exports.convoRagTemplatePlaceholder = '$$RAG$$'; exports.convoRoles = { user: 'user', assistant: 'assistant', system: 'system', /** * Used to add a prefix to the previous content message. Prefixes are not seen by the user. */ prefix: 'prefix', /** * Used to add a suffix to the previous content message. Suffixes are not seen by the user. */ suffix: 'suffix', /** * Appends content to the previous content message */ append: 'append', /** * Prepends content to the previous content message */ prepend: 'prepend', /** * Used to replace the content of the previous content message */ replace: 'replace', /** * Used to replace the content of the previous content message before sending to an LLM. The * user will continue to see the previous content message. */ replaceForModel: 'replaceForModel', /** * Used to display message evaluated by inline / thinking prompts */ thinking: 'thinking', /** * Used to set variables set within inline / thinking prompts */ thinkingResult: 'thinkingResult', /** * Contains RAG content */ rag: 'rag', /** * Used to define a prefix to add to rag messages */ ragPrefix: 'ragPrefix', /** * Used to define a suffix to add to rag messages */ ragSuffix: 'ragSuffix', /** * A message used as a template to insert RAG content into. The value __RAG__ will be used replaced with the actual rag content */ ragTemplate: 'ragTemplate', /** * When encountered a conversation will executed the preceding message before continuing unless * preceded by a flushed message. */ queue: 'queue', /** * signals a queue has been flushed */ flush: 'flush', /** * Starts an insertion block. Insertion blocks are used to reorder messages in a flattened conversation. */ insert: 'insert', /** * Ends an insertion block. */ insertEnd: 'insertEnd', /** * No op role. Messages with this role are completely ignored */ nop: 'nop', /** * Used to track transform results including tokens used by transforms */ transformResult: 'transformResult', /** * Starts a parallel execution block */ parallel: 'parallel', /** * Ends a parallel execution block */ parallelEnd: 'parallelEnd', /** * Ends the definition of an agent */ agentEnd: 'agentEnd', call: 'call', do: 'do', result: 'result', define: 'define', debug: 'debug', end: 'end', }; /** * Reserved role names in Convo-Lang that have special meaning and cannot be used as custom roles. * These roles are used for system functionality like function calls, execution blocks, and debugging. */ exports.convoReservedRoles = [ exports.convoRoles.call, exports.convoRoles.do, exports.convoRoles.result, exports.convoRoles.define, exports.convoRoles.debug, exports.convoRoles.end, exports.convoRoles.thinking ]; exports.convoFunctions = { queryImage: 'queryImage', getState: 'getState', /** * When called __rag with be set to true and and params passed will be added the the __ragParams * array. If __ragParams is not an array it will be set to an array first. Duplicated values * will not be added to __ragParams. */ enableRag: 'enableRag', /** * Disables and clears all rag params */ clearRag: 'clearRag', /** * Defines a form that a user can be guided through */ defineForm: 'defineForm', today: 'today', uuid: 'uuid', shortUuid: 'shortUuid', getVar: 'getVar', setVar: 'setVar', idx: 'idx', describeScene: 'describeScene', readDoc: 'readDoc', /** * States the default value of a variable. */ setDefault: 'setDefault', /** * Returns an XML list of agents available to the current conversation. */ getAgentList: 'getAgentList', /** * Explicitly enables a transform by name */ enableTransform: 'enableTransform', /** * Explicitly enables all transforms */ enableAllTransforms: 'enableAllTransforms', /** * Pushes a conversation task on to the task stack. The task will be display in the UI * while a completion is in progress */ pushConvoTask: 'pushConvoTask', /** * Pops the last convo task off the stack */ popConvoTask: 'popConvoTask', /** * Reads a JSON value from the virtual file system */ fsRead: 'fsRead', /** * Writes a JSON value to the virtual file system and returns the written value. */ fsWrite: 'fsWrite', /** * Delete a file or directory from the virtual file system */ fsRemove: 'fsRemove', /** * Creates a directory in the virtual file system */ fsMkDir: 'fsMkDir', /** * Checks if a path exists in the virtual file system */ fsExists: 'fsExists', /** * Joins file paths */ joinPaths: 'joinPaths', /** * Returns true if all values passed to the function are undefined */ isUndefined: 'isUndefined', /** * Returns the passed in value as milliseconds */ secondMs: 'secondMs', /** * Returns the passed in value as milliseconds */ minuteMs: 'minuteMs', /** * Returns the passed in value as milliseconds */ hourMs: 'hourMs', /** * Returns the passed in value as milliseconds */ dayMs: 'dayMs', /** * Finds an item in an array using shallow comparison. */ aryFindMatch: 'aryFindMatch', /** * Removes the first matching item in an array using shallow comparison. */ aryRemoveMatch: 'aryRemoveMatch' }; /** * reserved system variables */ exports.convoVars = { [exports.convoResultReturnName]: exports.convoResultReturnName, /** * Used to enabled prompt caching. A value of true will use the default prompt cached which * by default uses the `ConvoLocalStorageCache`. If assigned a string a cache with a matching * type will be used. */ __cache: '__cache', /** * In environments that have access to the filesystem __cwd defines the current working directory. */ __cwd: '__cwd', /** * Path to the current convo file */ __file: '__file', /** * When set to true debugging information will be added to conversations. */ __debug: '__debug', /** * Sets the default model */ __model: '__model', /** * Sets the default completion endpoint */ __endpoint: '__endpoint', /** * Endpoint to a convo compatible endpoint */ __convoEndpoint: '__convoEndpoint', /** * API key to send to completions endpoint. The `apiKey` of the `FlatConvoConversationBase` will * be populated by this variable if defined. */ __apiKey: '__apiKey', /** * Sets the default user id of the conversation */ __userId: '__userId', /** * When set to true time tracking will be enabled. */ __trackTime: '__trackTime', /** * When set to true token usage tracking will be enabled. */ __trackTokenUsage: '__trackTokenUsage', /** * When set to true the model used as a completion provider will be tracked. */ __trackModel: '__trackModel', /** * When defined __visionSystemMessage will be injected into the system message of conversations * with vision capabilities. __visionSystemMessage will override the default vision * system message. */ __visionSystemMessage: '__visionSystemMessage', /** * The default system message used for completing vision requests. Vision requests are typically * completed in a separate conversation that supports vision messages. By default the system * message of the conversation that triggered the vision request will be used. */ __visionServiceSystemMessage: '__visionServiceSystemMessage', /** * Response used with the system is not able to generate a vision response. */ __defaultVisionResponse: '__defaultVisionResponse', /** * A reference to markdown vars. */ __md: '__md', /** * Enables retrieval augmented generation (RAG). The value of the __rag can either be true, * false or a number. The value indicates the number of rag results that should be sent to the * LLM by default all rag message will be sent to the LLM. When setting the number of rag * messages to a fixed number only the last N number of rag messages will be sent to the LLM. * Setting __rag to a fixed number can help to reduce prompt size. */ __rag: '__rag', /** * An object that will be passed to the rag callback of a conversation. If the value is not an * object it is ignored. */ __ragParams: '__ragParams', /** * The tolerance that determines if matched rag content should be included as contact. */ __ragTol: '__ragTol', /** * Sets the current thread filter. Can either be a string or a ConvoThreadFilter. If __threadFilter * is a string it will be converted into a filter that looks like `{includeThreads:[__threadId]}`. */ __threadFilter: '__threadFilter', /** * A reference to a SceneCtrl that is capable of describing the current scene the user is viewing. */ __sceneCtrl: '__sceneCtrl', /** * The last described scene added to the conversation */ __lastDescribedScene: '__lastDescribedScene', /** * Used by agents to define the voice they use */ __voice: '__voice', /** * used to indicate that forms have been enabled */ __formsEnabled: '__formsEnabled', /** * Default array of forms */ __forms: '__forms', /** * Array of transforms names that have explicity been enabled. Transforms are enabled by default * unless they have the `transformOptional` tag applied. Adding "all" to the list will explicity * enable all components. */ __explicitlyEnabledTransforms: '__explicitlyEnabledTransforms', /** * Name of the currently executing trigger */ __trigger: '__trigger', /** * If true inline prompt messages should be written to debug output */ __debugInline: '__debugInline', }; exports.convoImportModifiers = { /** * Only system messages should be imported */ system: 'system', /** * Content messages should be ignored */ ignoreContent: 'ignoreContent' }; exports.defaultConvoRagTol = 1.2; exports.convoEvents = { /** * Occurs when a user message is added to a conversation * * Functions listening to the `user` event will be called after user messages are * appended. The return value of the function will either replaces the content of the user * message or will be set as the messages prefix or suffix. If the function return false, null or * undefined it is ignored and the next function listening to the `user` event will be called. * * @usage (@)on user [replace|append|prepend|prefix|suffix] [condition] */ user: 'user', /** * Occurs when an assistant message is added to a conversation. * * Functions listening to the `assistant` event will be called after assistant messages are * appended. The return value of the function will either replaces the content of the assistant * message or will be set as the messages prefix or suffix. If the function return false, null or * undefined it is ignored and the next function listening to the `assistant` event will be called. * * @usage (@)on assistant [replace|append|prepend|prefix|suffix] [condition] */ assistant: 'assistant', }; exports.convoTags = { /** * When applied to a user message and the message is the last message in a conversation the message * is considered a conversation initializer. */ init: 'init', /** * Defines an event listener for a message */ on: 'on', /** * Enable rag for a message. The value of the tag will be added as a rag path */ ragForMsg: 'ragForMsg', /** * Enables rag for the current conversation */ rag: 'rag', /** * Defines the start index and length of the actual rag content without prefix and suffix */ ragContentRage: 'ragContentRage', /** * Manually labels a message */ label: 'label', /** * Clears all content messages that precede the messages with the exception of system messages. * If the value of "system" is given as the tags value system message will also be cleared. */ clear: 'clear', /** * Prevents a message from being clear when followed by a message with a `@clear` tag applied. */ noClear: 'noClear', /** * Enables caching for the message the tag is applied to. No value of a value of true will use * the default prompt cached which by default uses the `ConvoLocalStorageCache`. If assigned * a string a cache with a matching type will be used. */ cache: 'cache', /** * When applied to a function the return value of the function will not be used to generate a * new assistant message. */ disableAutoComplete: 'disableAutoComplete', /** * Disables triggers on the message the tag is applied to. */ disableTriggers: 'disableTriggers', /** * Forces a message to be included in triggers. If the tag defines a value the value will be used * to match which trigger the message is included in. */ includeInTriggers: 'includeInTriggers', /** * Excludes a message from being included in triggers. If the tag defines a value the value will * be used to match the trigger it is excluded from. */ excludeFromTriggers: 'excludeFromTriggers', /** * When applied to a content message the message will be appended to the conversation after calling the * function specified by the tag's value. When applied to a function message the content of the * tag will be appended as a user message. */ afterCall: 'afterCall', /** * When used with the `afterCall` tag the appended message will be hidden from the user but * visible to the LLM */ afterCallHide: 'afterCallHide', /** * When used with the `afterCall` tag the appended message will use the given role */ afterCallRole: 'afterCallRole', /** * Indicates a message was created by a afterCall tag */ createdAfterCalling: 'createdAfterCalling', /** * Used to indicate that a message should be evaluated at the edge of a conversation with the * latest state. (@)edge is most commonly used with system message to ensure that all injected values * are updated with the latest state of the conversation. */ edge: 'edge', /** * Used to track the time messages are created. */ time: 'time', /** * Used to track the number of tokens a message used */ tokenUsage: 'tokenUsage', /** * Used to track the model used to generate completions */ model: 'model', /** * Sets the requested model to complete a message with */ responseModel: 'responseModel', /** * Used to track the endpoint to generate completions */ endpoint: 'endpoint', /** * Sets the requested endpoint to complete a message with */ responseEndpoint: 'responseEndpoint', /** * Sets the format as message should be responded to with. */ responseFormat: 'responseFormat', /** * Causes the response of the tagged message to be assigned to a variable */ assign: 'assign', /** * When used with a message the json tag is short and for `@responseFormat json` */ json: 'json', /** * The format of a message */ format: 'format', /** * Used to assign the content or jsonValue of a message to a variable */ assignTo: 'assignTo', /** * Used to enable capabilities. Only the first and last message in the conversation are used * to determine current capabilities. Multiple capability tags can be * applied to a message and multiple capabilities can be specified by separating them with a * comma. */ capability: 'capability', /** * Shorthand for `@capability vision` * Enables vision for all messages in a conversation */ enableVision: 'enableVision', /** * Shorthand for `@capability visionFunction` * The visionFunction capability adds vision support by passing vision messages to a vision model * and exposing vision capabilities as a function. */ enabledVisionFunction: 'enabledVisionFunction', /** * Enables vision for the message the tag is applied to */ vision: 'vision', /** * Sets the task a message is part of. By default messages are part of the "default" task */ task: 'task', /** * Can be used by functions to display a task message while the function is executing. */ taskName: 'taskName', /** * Can be used by functions to display a task message while the function is executing. */ taskDescription: 'taskDescription', /** * Sets the max number of non-system messages that should be included in a task completion */ maxTaskMessageCount: 'maxTaskMessageCount', /** * Defines what triggers a task */ taskTrigger: 'taskTrigger', /** * Defines a message as a template */ template: 'template', /** * used to track the name of templates used to generate messages */ sourceTemplate: 'sourceTemplate', /** * Used to mark a message as a component. The value can be "render" or "input". The default * value is "render" if no value is given. When the "input" value is used the rendered component * will take input from a user then write the input received to the executing conversation. */ component: 'component', /** * When applied to a message the message should be rendered but not sent to LLMs */ renderOnly: 'renderOnly', /** * Controls where a message is rendered. By default messages are rendered in the default chat * view, but applications can define different render targets. */ renderTarget: 'renderTarget', /** * Sets the renderTarget of the message to "hidden" */ hidden: 'hidden', toolId: 'toolId', /** * When applied to the last content or component messages auto scrolling will be disabled */ disableAutoScroll: 'disableAutoScroll', /** * When applied to a message the content of the message will be parsed as markdown */ markdown: 'markdown', /** * When applied to a message the content of the message will be parsed as markdown and the * elements of the markdown will be auto assigned to vars */ markdownVars: 'markdownVars', /** * When applied to a message the message is conditionally added to the flattened view of a * conversation. When the condition is false the message will not be visible to the user * or the LLM. * * @note The example below uses (@) instead of the at symbol because of a limitation of jsdoc. * * The example below will only render and send the second system message to the LLM * @example * * ``` convo * > define * animal = 'dog' * * (@)condition animal frog * > system * You are a frog and you like to hop around. * * (@)condition animal dog * > system * You are a dog and you like to eat dirt. * ``` */ condition: 'condition', /** * When applied to a message the message is completely disregarded and removed from the conversation */ disabled: 'disabled', /** * A URL to the source of the message. Typically used with RAG. */ sourceUrl: 'sourceUrl', /** * The ID of the source content of the message. Typically used with RAG. */ sourceId: 'sourceId', /** * The name of the source content of the message. Typically used with RAG. */ sourceName: 'sourceName', /** * When applied to a message the message becomes a clickable suggestion that when clicked will * add a new user message with the content of the message. If the suggestion tag defines a value * that value will be displayed on the clickable button instead of the message content but the * message content will still be used as the user messaged added to the conversation when clicked. * Suggestion message are render only and not seen by LLMs. */ suggestion: 'suggestion', /** * A title display above a group of suggestions */ suggestionTitle: 'suggestionTitle', /** * Sets the threadId of the current message and all following messages. Using the `@thread` tag * without a value will clear the current thread id. */ thread: 'thread', /** * Used to mark a function as a node output. */ output: 'output', /** * Used to mark a function as an error callback */ errorCallback: 'errorCallback', /** * Used to import external convo script code */ import: 'import', /** * Causes a message to be concatenated with the previous message. Both the message the tag * is attached to and the previous message must be content messages or the tag is ignored. * When a message is concatenated to another message all other tags except the condition * tag are ignored. */ concat: 'concat', /** * Instructs the LLM to call the specified function. The values "none", "required", "auto" have * a special meaning. If no name is given the special "required" value is used. * - none: tells the LLM to not call any functions * - required: tells the LLM it must call a function, any function. * - auto: tells the LLM it can call a function respond with a text response. This is the default behaviour. */ call: 'call', /** * Causes the message to be evaluated as code. The code should be contained in a markdown code block. */ eval: 'eval', /** * Id of the user that created the message */ userId: 'userId', /** * Causes all white space in a content message to be preserved. By define all content message * whitespace is preserved. */ preSpace: 'preSpace', /** * Indicates a message is the system message used to give an LLM instructions on how to use * agents */ agentSystem: 'agentSystem', /** * Defines capabilities for a message */ cap: 'cap', /** * Conversation ID */ cid: 'cid', /** * Adds a message to a transform group. Transform groups are used to transform assistant output. * The transform tags value can be the name of a type or empty. Transform groups are ran after all * text responses from the assistant. Transform messages are not added to the flattened conversation. */ transform: 'transform', /** * Sets the name of the transform group a message will be added to when the transform tag is used. */ transformGroup: 'transformGroup', /** * If present on a transform message the source message processed will be hidden from the user * but still visible to the LLM */ transformHideSource: 'transformHideSource', /** * Overrides `transformHideSource` and `transformRemoveSource` */ transformKeepSource: 'transformKeepSource', /** * If present on a transform message the source message processed will not be added to the * conversation */ transformRemoveSource: 'transformRemoveSource', /** * If present the transformed message has the `renderOnly` tag applied to it causing it to be * visible to the user but not the LLM. */ transformRenderOnly: 'transformRenderOnly', /** * A transform condition that will control if the component tag can be passed to the created message */ transformComponentCondition: 'transformComponentCondition', /** * Messages created by the transform will include the defined tag * @example (@)transformTag renderTarget sideBar */ transformTag: 'transformTag', /** * A shortcut tag combines the `transform`, `transformTag`, `transformRenderOnly`, `transformComponentCondition` * and `transformHideSource` tags to create a transform that renders a * component based on the data structure of a named * struct. * @usage (@)transformComponent [groupName] {componentName} {propType} [?[!] condition] * * Renders the CarView component after every assistant message. The transform is using the default transform group. * @example (@)transformComponent CarView CarProps * * Renders the CatPickerView component if the transformed message is a json object with the "type" key is set to cat. * The transform is in the CatPicker transform group. * @example (@)transformComponent CatPicker CatPickerView AnimalPrefs ? type cat * * Renders the AnimalsOtherThanPickerView component if the transformed message is a json object with the "type" key is NOT set to cat. * The transform is in the default transform group. * @example (@)transformComponent AnimalsOtherThanPickerView AnimalPrefs ?! type cat */ transformComponent: 'transformComponent', /** * Applied to messages created by a transform */ createdByTransform: 'createdByTransform', /** * When applied to a message the message will be included in all transform prompts. It is common * to apply includeInTransforms to system messages */ includeInTransforms: 'includeInTransforms', /** * Describes what the result of the transform is */ transformDescription: 'transformDescription', /** * If applied to a transform message it will not be passed through a filter prompt */ transformRequired: 'transformRequired', /** * When applied to a message the transform filter will be used to select which transforms to * to select. The default filter will list all transform groups and their descriptions to select * the best fitting transform for the assistants response */ transformFilter: 'transformFilter', /** * If applied to a transform message the transform must be explicity enabled applying the `enableTransform` * tag to another message or calling the enableTransform function. */ transformOptional: 'transformOptional', /** * Applied to transform output messages when overwritten by a transform with a higher priority */ overwrittenByTransform: 'overwrittenByTransform', /** * Explicitly enables a transform. Transforms are enabled by default unless the transform has * the `transformOptional` tag applied. */ enableTransform: 'enableTransform', /** * Defines a component to render a function result */ renderer: 'renderer', /** * Indicates a message is a standard system message. Standard system messages are used to * implement common patterns such as the moderator pattern. */ stdSystem: 'stdSystem', /** * Prevents a message from accepting modifiers and allows modifiers to flow through the message */ disableModifiers: 'disableModifiers', /** * Attached to a message to indicate the user has reached their limit of tokens */ tokenLimit: 'tokenLimit', router: 'router', routeTo: 'routeTo', routeFrom: 'routeFrom' }; /** * Tags that are allowed to have dynamic expressions as the value when using the equals operator. * @example (@)condition = eq(name "Bob") */ exports.convoDynamicTags = [ exports.convoTags.condition, exports.convoTags.disabled, exports.convoTags.taskName, exports.convoTags.taskDescription, exports.convoTags.json, exports.convoTags.routeTo, exports.convoTags.routeFrom, ]; /** * Tags whom have a dynamic expression will be evaluated as an anonymous type */ exports.convoAnonTypeTags = [ exports.convoTags.json, ]; /** * Prefix used to define anonymous types */ exports.convoAnonTypePrefix = 'AnonType_'; /** * JSDoc tags can be used in combination with the Convo-Lang CLI to import types, components and * functions from TypeScript. */ exports.convoJsDocTags = { /** * Marks a function or class as a convo component */ convoComponent: 'convoComponent', /** * When used with a component the source message that gets transform into the component should be * kept visible in the conversation */ convoKeepSource: 'convoKeepSource', /** * Used to ignore properties in a type */ convoIgnore: 'convoIgnore', /** * Marks a interface or type as a type to define in convo */ convoType: 'convoType', /** * Marks a function as a function to define in convo */ convoFn: 'convoFn', /** * Used with the convoFn tag to mark a function as local. When a function is local it is not * exposed to the LLM but can be called from convo scripts. */ convoLocal: 'convoLocal' }; exports.convoTaskTriggers = { /** * Triggers a text message is received. Function calls will to trigger. */ onResponse: 'onResponse' }; exports.commonConvoCacheTypes = { localStorage: 'localStorage', memory: 'memory', vfs: 'vfs', userVfs: 'userVfs', }; /** * In the browser the default cache type is local storage and on the backend vfs is the default cache type. */ exports.defaultConvoCacheType = globalThis.window ? exports.commonConvoCacheTypes.localStorage : exports.commonConvoCacheTypes.vfs; exports.convoDateFormat = "yyyy-MM-dd'T'HH:mm:ssxxx"; exports.defaultConvoRenderTarget = 'default'; exports.defaultConvoTransformGroup = 'default'; const getConvoDateString = (date = new Date()) => { return (0, date_fns_1.format)(date, exports.convoDateFormat); }; exports.getConvoDateString = getConvoDateString; exports.defaultConvoVisionSystemMessage = ('If the user references a markdown image without a ' + 'description or the description can not answer the user\'s question or ' + `complete the user\`s request call the ${exports.convoFunctions.queryImage} function. ` + 'Do not use the URL of the image to make any assumptions about the image.'); exports.defaultConvoVisionResponse = 'Unable to answer or respond to questions or requests for the given image or images'; exports.allowedConvoDefinitionFunctions = [ exports.convoNewFnName, exports.convoStructFnName, exports.convoMapFnName, exports.convoArrayFnName, exports.convoEnumFnName, exports.convoJsonMapFnName, exports.convoJsonArrayFnName, exports.convoFunctions.getState, exports.convoFunctions.enableRag, exports.convoFunctions.clearRag, exports.convoFunctions.defineForm, exports.convoFunctions.uuid, exports.convoFunctions.shortUuid, exports.convoFunctions.getVar, exports.convoFunctions.setVar, exports.convoFunctions.idx, exports.convoFunctions.setDefault, exports.convoFunctions.enableTransform, exports.convoFunctions.enableAllTransforms, exports.convoFunctions.isUndefined, exports.convoFunctions.secondMs, exports.convoFunctions.minuteMs, exports.convoFunctions.hourMs, exports.convoFunctions.dayMs, exports.convoFunctions.aryFindMatch, exports.convoFunctions.aryRemoveMatch, 'setObjDefaults', 'is', 'and', 'or', 'not', 'eq', 'gt', 'gte', 'lt', 'lte', 'isIn', 'contains', 'regexMatch', 'starMatch', 'deepCompare', 'add', 'sub', 'mul', 'div', 'mod', 'pow', 'inc', 'dec', 'rand', 'now', 'dateTime', 'encodeURI', 'encodeURIComponent', ]; exports.passthroughConvoInputType = 'FlatConvoConversation'; exports.passthroughConvoOutputType = 'ConvoCompletionMessageAry'; const createOptionalConvoValue = (value) => { return { [convo_types_1.convoObjFlag]: 'optional', value, }; }; exports.createOptionalConvoValue = createOptionalConvoValue; const createConvoType = (typeDef) => { typeDef[convo_types_1.convoObjFlag] = 'type'; return typeDef; }; exports.createConvoType = createConvoType; const createConvoBaseTypeDef = (type) => { return { [convo_types_1.convoObjFlag]: 'type', type, }; }; exports.createConvoBaseTypeDef = createConvoBaseTypeDef; const makeAnyConvoType = (type, value) => { if (!value) { return value; } value[convo_types_1.convoObjFlag] = 'type'; value['type'] = type; return value; }; exports.makeAnyConvoType = makeAnyConvoType; const createConvoScopeFunction = (fnOrCtrl, fn) => { if (typeof fnOrCtrl === 'function') { fnOrCtrl[convo_types_1.convoScopeFunctionMarker] = true; return fnOrCtrl; } if (!fn) { fn = (scope) => scope.paramValues ? scope.paramValues[scope.paramValues.length - 1] : undefined; } if (fnOrCtrl) { fn[convo_types_1.convoFlowControllerKey] = fnOrCtrl; } fn[convo_types_1.convoScopeFunctionMarker] = true; return fn; }; exports.createConvoScopeFunction = createConvoScopeFunction; const isConvoScopeFunction = (value) => { return (value && value[convo_types_1.convoScopeFunctionMarker]) ? true : false; }; exports.isConvoScopeFunction = isConvoScopeFunction; const setConvoScopeError = (scope, error) => { if (typeof error === 'string') { error = { message: error, statement: scope?.s, }; } if (!scope) { throw error; } scope.error = error; if (scope.onError) { const oe = scope.onError; delete scope.onError; delete scope.onComplete; for (let i = 0; i < oe.length; i++) { oe[i]?.(error); } } }; exports.setConvoScopeError = setConvoScopeError; const notWord = /\W/g; const newline = /[\n\r]/g; const multiTagReg = /^(\w+)__\d+$/; const convoTagMapToCode = (tagsMap, append = '', tab = '') => { const out = []; for (const e in tagsMap) { const v = tagsMap[e]; const nameMatch = multiTagReg.exec(e); out.push(`${tab}@${(nameMatch?.[1] ?? e).replace(notWord, '_')}${v ? ' ' + v.replace(newline, ' ') : ''}`); } return out.join('\n') + append; }; exports.convoTagMapToCode = convoTagMapToCode; const containsConvoTag = (tags, tagName) => { if (!tags) { return false; } for (let i = 0; i < tags.length; i++) { if (tags[i]?.name === tagName) { return true; } } return false; }; exports.containsConvoTag = containsConvoTag; const getConvoTag = (tags, tagName) => { if (!tags) { return undefined; } for (let i = 0; i < tags.length; i++) { const tag = tags[i]; if (tag?.name === tagName) { return tag; } } return undefined; }; exports.getConvoTag = getConvoTag; const getConvoFnMessageByTag = (tag, messages, startIndex = 0) => { if (!messages) { return undefined; } for (let i = startIndex; i < messages.length; i++) { const msg = messages[i]; if (!msg || !msg.tags || !msg.fn || msg.fn.call) { continue; } for (const t of msg.tags) { if (t.name === tag) { return msg; } } } return undefined; }; exports.getConvoFnMessageByTag = getConvoFnMessageByTag; const findConvoMessage = (messages, { tag, tagValue, role, startIndex = 0, }) => { if (!messages) { return undefined; } for (let i = startIndex; i < messages.length; i++) { const msg = messages[i]; if (!msg || !msg.tags || (role !== undefined && msg.role !== role)) { continue; } if (tag !== undefined) { for (const t of msg.tags) { if (t.name === tag && (tagValue === undefined ? true : t.value === tagValue)) { return msg; } } continue; } return msg; } return undefined; }; exports.findConvoMessage = findConvoMessage; const getConvoFnByTag = (tag, messages, startIndex = 0) => { return (0, exports.getConvoFnMessageByTag)(tag, messages, startIndex)?.fn; }; exports.getConvoFnByTag = getConvoFnByTag; const convoTagsToMap = (tags, exe) => { const map = {}; for (const t of tags) { let name = t.name; if (name in map) { let i = 2; while (`${t.name}__${i}` in map) { i++; } name = `${t.name}__${i}`; } if (t.statement) { const values = exe.getTagStatementValue(t); let value; if (values.length === 1) { let value = values[0]; if (value && typeof value === 'object') { value = JSON.stringify(value); } } else { value = JSON.stringify(value); } if (value === false || value === null || value === undefined) { map[name] = undefined; } else { map[name] = value + ''; } } else { map[name] = t.value; } } return map; }; exports.convoTagsToMap = convoTagsToMap; const mapToConvoTags = (map) => { const tags = []; for (const e in map) { tags.push({ name: e, value: map[e] }); } return tags; }; exports.mapToConvoTags = mapToConvoTags; const getFlatConvoTagValues = (name, tags) => { const values = []; if (!tags || !(name in tags)) { return values; } values.push(tags[name] ?? ''); let i = 2; while (`${name}__${i}` in tags) { i++; values.push(tags[`${name}__${i}`] ?? ''); } return values; }; exports.getFlatConvoTagValues = getFlatConvoTagValues; const transformTagReg = /^\s*(\w+)(.*)/; const parseConvoTransformTag = (value) => { const match = transformTagReg.exec(value); if (!match) { return undefined; } return { name: match[1] ?? '', value: match[2]?.trim(), }; }; exports.parseConvoTransformTag = parseConvoTransformTag; const createConvoMetadataForStatement = (statement) => { return { name: ((statement.set && !statement.setPath) ? statement.set : statement.label ? statement.label : undefined), comment: statement.comment, tags: statement.tags, }; }; exports.createConvoMetadataForStatement = createConvoMetadataForStatement; const getConvoMetadata = (value) => { return value?.[exports.convoMetadataKey]; }; exports.getConvoMetadata = getConvoMetadata; const getConvoStructPropertyCount = (value) => { const metadata = (0, exports.getConvoMetadata)(value); return metadata?.properties ? (0, common_1.getObjKeyCount)(metadata.properties) : 0; }; exports.getConvoStructPropertyCount = getConvoStructPropertyCount; const convoLabeledScopeFnParamsToObj = (scope, fnParams) => { return (0, exports.convoParamsToObj)(scope, undefined, false, fnParams); }; exports.convoLabeledScopeFnParamsToObj = convoLabeledScopeFnParamsToObj; const convoLabeledScopeParamsToObj = (scope) => { return (0, exports.convoParamsToObj)(scope, undefined, false); }; exports.convoLabeledScopeParamsToObj = convoLabeledScopeParamsToObj; const convoParamsToObj = (scope, unlabeledMap, unlabeledKey = true, fallbackFnParams) => { const obj = {}; const labels = scope.labels; let metadata = undefined; if (scope.cm || (scope.s.tags && (0, exports.containsConvoTag)(scope.s.tags, exports.convoCaptureMetadataTag))) { metadata = (0, exports.createConvoMetadataForStatement)(scope.s); metadata.properties = {}; obj[exports.convoMetadataKey] = metadata; } const labeled = []; let hasLabels = false; if (labels) { for (const e in labels) { hasLabels = true; const label = labels[e]; if (label === undefined) { continue; } const isOptional = typeof label === 'object'; const index = isOptional ? label.value : label; if (index !== undefined) { labeled.push(index); const v = scope.paramValues?.[index]; obj[e] = isOptional ? (0, exports.createOptionalConvoValue)(v) : v; if (metadata?.properties && scope.s.params) { const propStatement = scope.s.params[index]; if (propStatement) { metadata.properties[e] = { name: e, comment: propStatement.comment, tags: propStatement.tags }; } } } } } if (unlabeledKey) { const values = []; if (scope.paramValues) { for (let i = 0; i < scope.paramValues.length; i++) { if (!labeled.includes(i)) { values.push(scope.paramValues[i]); } } } obj[unlabeledKey === true ? '_' : unlabeledKey] = values; if (unlabeledMap) { for (let i = 0; i < unlabeledMap.length; i++) { const key = unlabeledMap[i] ?? ''; if (obj[key] === undefined) { obj[key] = values[i]; } } } } else if (!hasLabels && fallbackFnParams && scope.paramValues) { for (let i = 0; i < fallbackFnParams.length; i++) { const p = fallbackFnParams[i]; const v = scope.paramValues[i]; if (!p?.label || v === undefined) { continue; } obj[p.label] = v; } } return obj; }; exports.convoParamsToObj = convoParamsToObj; const isReservedConvoRole = (role) => { return exports.convoReservedRoles.includes(role); }; exports.isReservedConvoRole = isReservedConvoRole; const isValidConvoRole = (role) => { return /^\w+$/.test(role); }; exports.isValidConvoRole = isValidConvoRole; const isValidConvoIdentifier = (role) => { return /^[a-z]\w*$/.test(role); }; exports.isValidConvoIdentifier = isValidConvoIdentifier; const formatConvoMessage = (role, content, prefix = '') => { if (!(0, exports.isValidConvoRole)(role)) { throw new ConvoError_1.ConvoEr