@convo-lang/convo-lang
Version:
The language of AI
1,532 lines • 100 kB
JavaScript
import { UnsupportedError, asArray, deepClone, dupDeleteUndefined, escapeHtml, getFileName, getObjKeyCount, getValueByPath, isClassInstanceObject, parseBoolean, parseRegexCached, starStringTestCached, zodTypeToJsonScheme } from "@iyio/common";
import { parseJson5 } from '@iyio/json5';
import { format } from "date-fns";
import { ConvoError } from "./ConvoError.js";
import { convoSystemMessages } from "./convo-system-messages.js";
import { convoFlowControllerKey, convoMessageSourceReferenceKey, convoObjFlag, convoScopeFunctionMarker, convoScopeParentKey, convoStringTemplateLiteralOptionsFlag } from "./convo-types.js";
export const convoBodyFnName = '__body';
export const convoArgsName = '__args';
export const convoResultReturnName = '__return';
export const convoResultErrorName = '__error';
export const convoDisableAutoCompleteName = '__disableAutoComplete';
export const convoStructFnName = 'struct';
export const convoNewFnName = 'new';
export const convoMapFnName = 'map';
export const convoArrayFnName = 'array';
export const convoJsonMapFnName = 'jsonMap';
export const convoJsonArrayFnName = 'jsonArray';
export const convoSwitchFnName = 'switch';
export const convoCaseFnName = 'case';
export const convoDefaultFnName = 'default';
export const convoTestFnName = 'test';
export const convoPipeFnName = 'pipe';
export const convoLocalFunctionModifier = 'local';
export const convoExternFunctionModifier = 'extern';
export const convoCallFunctionModifier = 'call';
export const convoInvokeFunctionModifier = 'invoke';
export const convoInvokeFunctionName = 'invoke';
export const convoGlobalRef = 'convo';
export const convoEnumFnName = 'enum';
export const convoMetadataKey = Symbol('convoMetadataKey');
export const convoCaptureMetadataTag = 'captureMetadata';
export const defaultConversationName = 'default';
export const defaultConvoNodeId = 'main';
export const convoUtilModels = {
empty: 'empty',
echo: 'echo',
};
export const convoLogDir = '.convo-lang-logs';
export const convoMsgModifiers = {
/**
* When applied to the function the function is used as the default function of an agent
*/
agent: 'agent',
};
export const convoScopedModifiers = [convoMsgModifiers.agent];
export const defaultConvoTask = 'default';
export const convoAnyModelName = '__any__';
export const convoRagTemplatePlaceholder = '$$RAG$$';
export const convoRoles = {
/**
* Represents messages from the user
*/
user: 'user',
/**
* Represents messages from the LLM
*/
assistant: 'assistant',
/**
* System instruction messages
*/
system: 'system',
/**
* Groups messages together
*/
group: 'group',
/**
* Ends a group of messages
*/
groupEnd: 'groupEnd',
/**
* 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',
/**
* Appends content to the last system message
*/
appendSystem: 'appendSystem',
/**
* Appends content to the last user message
*/
appendUser: 'appendUser',
/**
* Appends content to the last assistant message
*/
appendAssistant: 'appendAssistant',
/**
* 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',
/**
* importTemplate messages are used to format imported content such as markdown.
*/
importTemplate: 'importTemplate',
/**
* 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',
/**
* Used by the convo make build system to define a make target. `std://make.convo` must
* be imported to function correctly
*/
target: 'target',
/**
* Used by the convo make build system to define target defaults and configure build options
*/
make: 'make',
/**
* Used by the convo make build system to define an app. `std://make.convo` must
* be imported to function correctly
*/
app: 'app',
/**
* Used by the convo make build system to define a build stage. `std://make.convo` must
* be imported to function correctly
*/
stage: 'stage',
/**
* Groups following nodes as a single graph. The context of the
*/
graph: 'graph',
graphEnd: 'graphEnd',
/**
* Defines the start of a node. Messages following the node will be part of the node.
*/
node: 'node',
/**
* Explicitly ends a node
*/
nodeEnd: 'nodeEnd',
/**
* Defines a node to goto by id
*/
goto: 'goto',
/**
* Indicates graph traversal has exited.
*/
exitGraph: 'exitGraph',
/**
* Graph exit route
*/
exit: 'exit',
/**
* Graph to route
*/
to: 'to',
/**
* Graph from route
*/
from: 'from',
/**
* A temporary message type use to pass convo source code.
*/
_sourceRef: '_sourceRef',
template: 'template',
templateEnd: 'templateEnd',
/**
* Indicates a worker is ready to run
*/
run: 'run',
};
/**
* List of built-in role that are allowed to be used with custom message handlers
*/
export const convoHandlerAllowedRoles = [
convoRoles.make,
convoRoles.target,
convoRoles.app,
convoRoles.stage,
];
/**
* 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.
*/
export const convoReservedRoles = [
convoRoles.call,
convoRoles.do,
convoRoles.result,
convoRoles.define,
convoRoles.debug,
convoRoles.end,
convoRoles.thinking
];
export const 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
*/
fsReadJson: 'fsReadJson',
/**
* Reads a file from the virtual file system and returns it as a base64 string
*/
fsReadBase64: 'fsReadBase64',
/**
* Reads a file from the virtual file system and returns it as a base64 url. This function can
* be used to read files as images or other assets that get embedded as base 64 urls.
*
* @signature (path:string contentType?:string) -> string
*
* @example This is an image: }})
*/
fsReadBase64Url: 'fsReadBase64Url',
/**
* Similar to fsReadBase64Url but returns an image formatted as markdown
*
* @signature (path:string description?:string contentType?:string) -> string
*/
fsReadBase64Image: 'fsReadBase64Image',
/**
* Creates a markdown image from the given path and description. mdImg is an alias of `fsReadBase64Image`
*
* @signature (path:string description?:string contentType?:string) -> string
*/
mdImg: 'mdImg',
/**
* Writes a JSON value to the virtual file system and returns the written value.
*/
fsWriteJson: 'fsWriteJson',
/**
* Reads a string value from the virtual file system
*/
fsRead: 'fsRead',
/**
* Reads multiple files as a single string using a list of names and an optional pattern that
* the each name is inserted into.
*/
fsMultiRead: 'fsMultiRead',
/**
* Writes a string value to the virtual file system and returns the written value.
*/
fsWrite: 'fsWrite',
/**
* Append a string value to the virtual file system and returns the written value.
*/
fsAppend: 'fsAppend',
/**
* 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',
/**
* Reads directory items
*/
fsReadDir: 'fsReadDir',
/**
* Returns the full and normalized path for the given value.
*/
fsFullPath: 'fsFullPath',
/**
* Joins file paths
*/
joinPaths: 'joinPaths',
/**
* Returns true if all values passed to the function are undefined
*/
isUndefined: 'isUndefined',
/**
* Returns the number of keys in an option
*/
getObjKeyCount: 'getObjKeyCount',
/**
* Returns the keys of an options
*/
getObjKeys: 'getObjKeys',
/**
* Returns the values of an options
*/
getObjKeyValues: 'getObjKeyValues',
/**
* 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',
/**
* Finds an item's index in an array using shallow comparison.
*/
aryFindIndex: 'aryFindIndex',
/**
* Removes the first matching item in an array using shallow comparison.
*/
aryRemoveMatch: 'aryRemoveMatch',
/**
* Used by the convo make build system to define target defaults and build options
*/
makeDefaults: 'makeDefaults',
/**
* Used by the convo make build system to define a output to make
*/
makeTarget: 'makeTarget',
/**
* Defines a make app
*/
makeApp: 'makeApp',
/**
* Defines a make stage
*/
makeStage: 'makeStage',
/**
* Similar to the map function except unlabeled values are place the the `_` property
*/
mapWithCapture: 'mapWithCapture',
/**
* Used to access properties of a make target by path
*/
mkt: 'mkt',
/**
* Returns information about the current graph node or a node by step index.
* Negative indexes can be used to return nodes indexed from the end of the node stack
*/
getNodeInfo: 'getNodeInfo',
/**
* Returns node input for the current graph node or a node by step index.
* Negative indexes can be used to return nodes indexed from the end of the node stack
*/
getNodeInput: 'getNodeInput',
/**
* Configures the ConvoDb connection
*/
dbConfig: 'dbConfig',
/**
* Queries the ConvoDb
*/
dbQueryNodes: 'dbQueryNodes',
/**
* Returns nodes matching a given path. A wildcard path (path ending with /*) can return multiple
* nodes
*/
dbGetNodesByPath: 'dbGetNodesByPath',
/**
* Gets the permissions from one node to another
*/
dbGetNodePermission: 'dbGetNodePermission',
/**
* Checks if one node has permission to another
*/
dbCheckNodePermission: 'dbCheckNodePermission',
/**
* Inserts a node
*/
dbInsertNode: 'dbInsertNode',
/**
* Updates a node
*/
dbUpdateNode: 'dbUpdateNode',
/**
* Deletes a node
*/
dbDeleteNode: 'dbDeleteNode',
/**
* Queries edges
*/
dbQueryEdges: 'dbQueryEdges',
/**
* Gets an edge by id
*/
dbGetEdgeById: 'dbGetEdgeById',
/**
* Inserts an edge
*/
dbInsertEdge: 'dbInsertEdge',
/**
* Updates an edge
*/
dbUpdateEdge: 'dbUpdateEdge',
/**
* Deletes an edge
*/
dbDeleteEdge: 'dbDeleteEdge',
/**
* Queries embeddings
*/
dbQueryEmbeddings: 'dbQueryEmbeddings',
/**
* Gets an embedding by id
*/
dbGetEmbeddingById: 'dbGetEmbeddingById',
/**
* Inserts an embedding
*/
dbInsertEmbedding: 'dbInsertEmbedding',
/**
* Updates an embedding
*/
dbUpdateEmbedding: 'dbUpdateEmbedding',
/**
* Deletes an embedding
*/
dbDeleteEmbedding: 'dbDeleteEmbedding',
};
/**
* reserved system variables
*/
export const convoVars = {
[convoResultReturnName]: 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 main file that loaded the conversation
*/
__mainFile: '__mainFile',
/**
* 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',
/**
* Controls the penalty for repeated tokens in completions.
*/
__frequencyPenalty: '__frequencyPenalty',
/**
* Controls the penalty for new tokens based on their presence in the text so far.
*/
__presencePenalty: '__presencePenalty',
/**
* If set, requests log probabilities of generated tokens.
*/
__logprobs: '__logprobs',
/**
* Sets the maximum number of tokens to generate in a completion.
*/
__maxTokens: '__maxTokens',
/**
* Indicates the level of reasoning effort to apply.
*/
__reasoningEffort: '__reasoningEffort',
/**
* Sets the random seed for reproducible completions.
*/
__seed: '__seed',
/**
* Specifies the service tier to use for completions.
*/
__serviceTier: '__serviceTier',
/**
* Controls the randomness of completions (temperature parameter).
*/
__temperature: '__temperature',
/**
* Controls the nucleus sampling parameter for completions (top_p).
*/
__topP: '__topP',
/**
* Requests the log probabilities for the top tokens.
*/
__topLogprobs: '__topLogprobs',
/**
* Controls the verbosity of the model's response.
*/
__responseVerbosity: '__responseVerbosity',
/**
* Allows biasing the likelihood of specific tokens.
*/
__logitBias: '__logitBias',
/**
* Object containing additional parameters to pass to the LLM.
*/
__modelParams: '__modelParams',
/**
* Array of ConvoMakeApp objects
*/
__makeDefaults: '__makeDefaults',
/**
* Array of ConvoMakeTargetDeclaration objects
*/
__makeTargets: '__makeTargets',
/**
* Array of ConvoMakeApp objects
*/
__makeApps: '__makeApps',
/**
* Array of ConvoMakeStage objects
*/
__makeStages: '__makeStages',
/**
* Relative path to the make directory the current convo file was created in
*/
__makeRoot: '__makeRoot',
__makeFile: '__makeFile',
__makeOut: '__makeOut',
/**
* Maps custom messages to handler functions
*/
__messageHandlers: '__messageHandlers',
/**
* Name of a type to be used as the default json response type
*/
__defaultResponseType: '__defaultResponseType',
/**
* Sets the default node context depth
*/
__nodeContextDepth: '__nodeContextDepth',
/**
* Stores historical node information including each node input
*/
__nodeStack: '__nodeStack',
/**
* A reference to a ConvoDb
*/
__db: '__db',
/**
* A ConvoDb connection string
*/
__dbConnection: '__dbConnection'
};
export const convoImportModifiers = {
/**
* Only system messages should be imported
*/
system: 'system',
/**
* Content messages should be ignored
*/
ignoreContent: 'ignoreContent',
/**
* Merges the contents of multiple files into a single imports. This is useful when importing
* multiple content files using a glob.
*/
merge: 'merge'
};
/**
* Used to indicate a result message will take over control flow
*/
export const convoControlResult = Symbol('convoControlResult');
export const convoControlResultKeys = {
source: 'source',
messages: 'messages',
};
export const defaultConvoRagTol = 1.2;
export const 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',
};
export const 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',
/**
* Used to set the name of the message
*/
name: 'name',
/**
* Defines an event listener for a message. Functions tagged with `@on` will
* be made local and not visible to LLMs.
*/
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',
/**
* Name of the server a message was created from.
*/
fromMcp: 'fromMcp',
/**
* Marks a message as a resource list from an MCP server
*/
mcpResourceList: 'mcpResourceList',
/**
* 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',
/**
* Controls the penalty for repeated tokens in completions for the message the tag is applied to.
*/
frequencyPenalty: 'frequencyPenalty',
/**
* Controls the penalty for new tokens based on their presence in the text so far for the message the tag is applied to.
*/
presencePenalty: 'presencePenalty',
/**
* If set, requests log probabilities of generated tokens for the message the tag is applied to.
*/
logprobs: 'logprobs',
/**
* Sets the maximum number of tokens to generate in a completion for the message the tag is applied to.
*/
maxTokens: 'maxTokens',
/**
* Indicates the level of reasoning effort to apply for the message the tag is applied to.
*/
reasoningEffort: 'reasoningEffort',
/**
* Sets the random seed for reproducible completions for the message the tag is applied to.
*/
seed: 'seed',
/**
* Specifies the service tier to use for completions for the message the tag is applied to.
*/
serviceTier: 'serviceTier',
/**
* Controls the randomness of completions (temperature parameter) for the message the tag is applied to.
*/
temperature: 'temperature',
/**
* Controls the nucleus sampling parameter for completions (top_p) for the message the tag is applied to.
*/
topP: 'topP',
/**
* Requests the log probabilities for the top tokens for the message the tag is applied to.
*/
topLogprobs: 'topLogprobs',
/**
* Controls the verbosity of the model's response for the message the tag is applied to.
*/
responseVerbosity: 'responseVerbosity',
/**
* Object containing additional parameters to pass to the LLM for the message the tag is applied to.
*/
modelParams: 'modelParams',
/**
* 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',
/**
* Applied to result values to indicate they will alter the control flow of a conversation.
*/
controlResult: 'controlResult',
/**
* 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',
/**
* Alias for (@)order 0
*/
top: 'top',
/**
* Sets the order which the tagged message appears. negative value are inserted form the end
* of the conversation
*/
order: 'order',
/**
* 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',
/**
* Reference to a document related to a message. Typically used with RAG.
*/
docRef: 'docRef',
/**
* 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',
/**
* A function to call when a suggestion is selected by the user instead of sending message to LLM
*/
suggestionCallback: 'suggestionCallback',
/**
* 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',
/**
* Defines a path to write a messages output to
*/
output: 'output',
/**
* Used to mark a function as an error callback
*/
errorCallback: 'errorCallback',
/**
* Used to import external convo script code or other resource types.
*
* @usage
* (@)import [type[:label]] url
*/
import: 'import',
/**
* Matches an import by path. The match value can use wild cards are be a regular expression.
* Regular expressions start with a (!) followed by a space then the regular expression pattern
*
* @example // By path
* (@)importMatch ./company-policies.md
*
* @example // wildcard
* (@)importMatch *policies.md
*
* @example // regular expression
* (@)importMatch ! policies\.(md|mdx)$
*/
importMatch: 'importMatch',
importRole: 'importRole',
/**
* 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',
/**
* When applied to a node message a `to` route for is added to the node.
*/
to: 'to',
/**
* When applied to a node message a `from` route for is added to the node.
*/
from: 'from',
/**
* When applied to a node message an `exit` route for is added to the node.
*/
exit: 'exit',
/**
* Used by graph messages to mark their default entry node
*/
entryNode: 'entryNode',
/**
* Controls the LLM model used to evaluate route conditions.
*/
routingModel: 'routingModel',
/**
* When applied to a node message forking node execution is allowed. When execution is allowed
* to be forked all routes with a true condition will be taken and if more than one route is
* taken a new conversation will be created.
*/
fork: 'fork',
/**
* Controls the number of node contexts to include in the context of the node.
*/
contextDepth: 'contextDepth',
/**
* Causes a content message to be included in node execution context. By Default all non-node
* messages are excluded from node execution context.
*/
includeInNodes: 'includeInNodes',
/**
* Defines the input type expected by a node. If the input for a node does not match
* its input type the input will attempted to be converted using natural language
*/
inputType: 'inputType',
/**
* Indicates a message is the result of input conversation
*/
inputConversation: 'inputConversation',
/**
* Use to mark a function as a message handler. Functions tagged with `@messageHandler` will
* be made local and not visible to LLMs.
*/
messageHandler: 'messageHandler',
/**
* Name of the prop that the head value of handles messages are passed to.
* @default "name"
*/
messageHandlerHeadProp: 'messageHandlerHeadProp',
/**
* When applied to a message handler the handler will assume the location of the message
* the handler is handling
*/
assumeHandledMessageLocation: 'assumeHandledMessageLocation',
/**
* Enables auto memory management in works
*/
autoMemory: 'autoMemory',
/**
* Causes the output of a message to be saved as a workers memory
*/
saveMemory: 'saveMemory',
};
/**
* Functions marked with tags defined in `localFunctionTags` will be marked as local and not visible
* to LLMs.
*/
export const localFunctionTags = [
convoTags.on,
convoTags.messageHandler,
];
/**
* Tags that are allowed to have dynamic expressions as the value when using the equals operator.
* @example (@)condition = eq(name "Bob")
*/
export const convoDynamicTags = [
convoTags.condition,
convoTags.disabled,
convoTags.taskName,
convoTags.taskDescription,
convoTags.json,
convoTags.to,
convoTags.from,
convoTags.exit,
convoTags.on,
];
/**
* Tags who's first word on its value will be used as a label
*/
export const convoLabeledTags = [
convoTags.to,
convoTags.from,
];
/**
* Tags who's dynamic values will not be evaled when flattening. This can be useful when defining
* tags who's dynamic value will be used out of line of the flattening of a conversation.
*/
export const convoDisableStatementEvalTags = [
convoTags.to,
convoTags.from,
convoTags.exit,
];
/**
* Tags whom have a dynamic expression will be evaluated as an anonymous type
*/
export const convoAnonTypeTags = [
convoTags.json,
];
/**
* Prefix used to define anonymous types
*/
export const convoAnonTypePrefix = 'AnonType_';
/**
* JSDoc tags can be used in combination with the Convo-Lang CLI to import types, components and
* functions from TypeScript.
*/
export const 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'
};
export const convoTaskTriggers = {
/**
* Triggers a text message is received. Function calls will to trigger.
*/
onResponse: 'onResponse'
};
export const 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.
*/
export const defaultConvoCacheType = globalThis.window ? commonConvoCacheTypes.localStorage : commonConvoCacheTypes.vfs;
export const convoDateFormat = "yyyy-MM-dd'T'HH:mm:ssxxx";
export const defaultConvoRenderTarget = 'default';
export const defaultConvoTransformGroup = 'default';
export const convoStdImportPrefix = 'std://';
export const getConvoDateString = (date = new Date()) => {
return format(date, convoDateFormat);
};
export const 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 ${convoFunctions.queryImage} function. ` +
'Do not use the URL of the image to make any assumptions about the image.');
export const defaultConvoVisionResponse = 'Unable to answer or respond to questions or requests for the given image or images';
export const allowedConvoDefinitionFunctions = [
convoNewFnName,
convoStructFnName,
convoMapFnName,
convoFunctions.mapWithCapture,
convoArrayFnName,
convoEnumFnName,
convoJsonMapFnName,
convoJsonArrayFnName,
convoFunctions.getState,
convoFunctions.enableRag,
convoFunctions.clearRag,
c