@iyio/convo-lang
Version:
A conversational language.
390 lines (389 loc) • 11.4 kB
TypeScript
import { CancelToken } from "@iyio/common";
import { BehaviorSubject, Observable } from "rxjs";
import { ZodType } from "zod";
import { Conversation } from "./Conversation";
export interface ConvoGraph {
id: string;
name?: string;
nodes: ConvoNode[];
edges: ConvoEdge[];
}
export interface ConvoGraphDb {
nodes: ConvoNode[];
edges: ConvoEdge[];
traversers: ConvoTraverser[];
inputs: ConvoInputTemplate[];
sourceNodes: ConvoSourceNode[];
}
export interface ConvoNodeTypeMetadata {
/**
* The name of the type
*/
name: string;
}
export interface ConvoNode {
/**
* Unique id of the node
*/
id: string;
/**
* A display name for the node
*/
name?: string;
/**
* A description of what the node does.
*/
description?: string;
/**
* Shared convo script that is prefixed to each step of the node
*/
sharedConvo?: string;
/**
* A set of steps the node will execute to generate an output
*/
steps: ConvoNodeStep[];
/**
* If true auto input transforming is disabled. When input is passed to node and the input
* does not conform to the input type of the node a input transform step will be added to the
* start of the node. When `disableAutoTransform` is set to true the auto generated input
* transform step will not be added.
*/
disableAutoTransform?: boolean;
/**
* Compiled metadata based on the convo scripts of the node
*/
metadata?: ConvoNodeMetadata;
x?: number;
y?: number;
}
export interface ConvoNodeStep {
name?: string;
/**
* The convo script for the step
*/
convo: string;
}
export interface ConvoNodeExecCtx extends ConvoMetadataAndTypeMap {
/**
* Node steps paired with a conversation for execution
*/
steps: ConvoNodeExecCtxStep[];
/**
* Variable defaults passed to the conversations
*/
defaultVars: Record<string, any>;
}
export interface ConvoNodeExecCtxStep {
nodeStep: ConvoNodeStep;
convo: Conversation;
}
export interface ConvoNodeOutput extends ConvoNodeTypeMetadata {
/**
* The name of the output function. fnName can be used by edges to match to specific output
* functions
*/
fnName?: string;
}
export interface ConvoNodeMetadata {
/**
* The input type of the node. If not defined the input type is `any`
*/
inputType?: ConvoNodeTypeMetadata;
outputTypes?: ConvoNodeOutput[];
}
export interface ConvoMetadataAndTypeMap {
/**
* Maps types defined by ConvoNodeMetadata to zod objects.
*/
typeMap: Record<string, ZodType<any>>;
/**
* metadata related to a ConvoNode
*/
metadata: ConvoNodeMetadata;
}
/**
* Connects the output of a node to the input of another node.
*/
export interface ConvoEdge {
/**
* A display name for the edge
*/
name?: string;
/**
* A description of why the edge connects it nodes
*/
description?: string;
/**
* Unique id of the edge
*/
id: string;
/**
* The node id that the from side of the edge connects to.
*/
from: string;
/**
* If defined the "from" node of the the edge must product an output that is generated by a
* function with a name that matches `fromFn`.
*/
fromFn?: string;
/**
* If defined the output from the "from" node of the the edge must product an output that of a
* type that matches `fromType`.
*/
fromType?: string;
/**
* The node id that the "to" side of the edge connects to.
*/
to: string;
/**
* A convo script that can be used to filter. The condition script will not be completed only
* flatted and checked for a variable named isMatch. If isMatch is true the condition node
* will be connected to it target node.
*/
conditionConvo?: string;
/**
* Defines conditions for pausing the traversal of a traverser crossing the edge.
*/
pause?: ConvoTraversalPause;
x?: number;
y?: number;
}
export interface ConvoEdgePattern {
/**
* Id of the from node to match
*/
from: string;
/**
* Matches they payload type produced by the from node
*/
fromType?: string;
/**
* Name of the function that produced the payload
*/
fromFn?: string;
/**
* Input value that for dynamic condition checking
*/
input?: any;
}
/**
* Defines conditions for pausing the traversal of a traverser crossing an edge. If empty traversal
* can be resumed by any user and may be paused indefinitely.
*/
export interface ConvoTraversalPause {
/**
* A delay in milliseconds to delay traversing to the next node. The delay is applied after
* checking the condition of the edge.
*/
delayMs?: number;
/**
* If true approval from a user is required before allow the traverser to continue
*/
approvalRequired?: boolean;
}
/**
* `paused` - Execution is paused due to a ConvoTraversalPause object being assigned to the traverser.
*
* `ready` - The traverser is ready to execute a node
*
* `transforming-input` - The traverser is transforming input according to the input type of the node the traverser is on.
*
* `invoking` - The traverser is executing the invoke script of the node it is on.
*
* `invoked` - The traverser has executed a node and is ready to traverse the next edge.
*
* `stopped` - The traverser has reached the end of its node path and is stopped and can not resume.
*
* `failed` - The traverser has ran into an error and can not resume.
*/
export type ConvoNodeExeState = ('paused' | 'ready' | 'invoking' | 'invoked' | 'stopped' | 'failed');
export interface ConvoTraverser {
/**
* A unique id for the traverser
*/
id: string;
/**
* The current execution state of the traverser
*/
exeState: ConvoNodeExeState;
/**
* The index of the current step of the current node the traverser is on
*/
currentStepIndex: number;
/**
* Defines the conditions for pausing the traverser.
*/
pause?: ConvoTraversalPause;
/**
* A timestamp when to resume traversal after being paused.
*/
resumeAt?: number;
/**
* Shared state of the traverser. Nodes can store data in the state object.
*/
state: Record<string, any>;
/**
* Stores the input and output of nodes as the traverser travels
*/
payload?: any;
/**
* Address of the node the traverser is currently at either executing or waiting to execute.
* When execution is paused the traverser will move to its next node then wait to execute.
*/
address?: string;
/**
* The path the traverser has traveled.
*/
path?: ConvoEdge[];
/**
* Id of the current node the traverser is on.
*/
currentNodeId?: string;
/**
* An error message describing what caused the traverser to fail
*/
errorMessage?: string;
/**
* An optional name for the traverser
*/
name?: string;
/**
* An optional user id to associate with the traverser.
*/
userId?: string;
/**
* An optional user group id to associate with the traverser.
*/
userGroupId?: string;
x?: number;
y?: number;
}
export interface CreateConvoTraverserOptions {
defaults?: Partial<ConvoTraverser>;
}
export interface StartConvoTraversalOptions {
createTvOptions?: CreateConvoTraverserOptions;
/**
* The edge where the traverser will start. If edge is a string it is converted to an edge
* with a `to` value of the string value.
*/
edge?: ConvoEdge | string;
/**
* Used to match and existing edge in the graph store
*/
edgePattern?: ConvoEdgePattern;
payload?: any;
state?: Record<string, any>;
/**
* If true the traversers created will be saved to the graph store
*/
saveToStore?: boolean;
/**
* A cancelation token that can be used to stop the traversal of the traverser and all forked
* traversers
*/
cancel?: CancelToken;
}
/**
* An interface that defines common properties for node input
*/
export interface ConvoCommonNodeInput {
/**
* A short chunk of text that can be used to pass any information. For example if the input
* was a book `text` would be a summary of the book.
*/
text: string;
/**
* The full source of the content. For example if the input was a book `source` would be the
* full content of the book.
*/
source?: string;
title?: string;
sourceId?: string;
sourceUrl?: string;
type?: string;
}
export type ConvoGraphMonitorEventType = ('other' | 'traverser-created' | 'start-traversal' | 'traversal-failed' | 'edge-crossed' | 'start-exe' | 'start-invoke' | 'execute-step' | 'exe-complete' | 'traversal-stopped' | 'convo-result' | 'auto-transformer-created');
export interface ConvoGraphMonitorEvent {
type: ConvoGraphMonitorEventType;
text: string;
node?: ConvoNode;
traverser?: ConvoTraverser;
step?: ConvoNodeStep;
stepIndex?: number;
edge?: ConvoEdge;
data?: any;
pause?: ConvoTraversalPause;
time: number;
}
export type ConvoEdgeSide = 'to' | 'from';
export interface ConvoGraphStoreEvt {
node?: ConvoNode;
nodeId?: string;
edge?: ConvoEdge;
sourceNode?: ConvoSourceNode;
edgeId?: string;
traverser?: ConvoTraverser;
traverserId?: string;
}
export interface IHasConvoGraph {
graph: ConvoGraph;
}
export interface IHasConvoGraphDb {
db: ConvoGraphDb;
}
/**
* Stores data for a single ConvoGraph
*/
export interface ConvoGraphStore {
readonly graphId: string;
get onDbChange(): Observable<ConvoGraphStoreEvt>;
/**
* If the store support tracking changes it should save all unsaved changes
*/
saveChangesAsync(): Promise<void>;
getNodeAsync(id: string): Promise<ConvoNode | undefined>;
putNodeAsync(graph: ConvoNode): Promise<void>;
deleteNodeAsync(id: string): Promise<void>;
getNodeEdgesAsync(nodeId: string, side: ConvoEdgeSide): Promise<ConvoEdge[]>;
getEdgeAsync(id: string): Promise<ConvoEdge | undefined>;
putEdgeAsync(graph: ConvoEdge): Promise<void>;
deleteEdgeAsync(id: string): Promise<void>;
getTraverserAsync(id: string): Promise<ConvoTraverser | undefined>;
putTraverserAsync(traverser: ConvoTraverser): Promise<void>;
deleteTraverserAsync(id: string): Promise<void>;
getSourceNodesAsync(): Promise<ConvoSourceNode[]>;
getSourceNodeAsync(id: string): Promise<ConvoSourceNode | undefined>;
putSourceNodeAsync(SourceNode: ConvoSourceNode): Promise<void>;
deleteSourceNodeAsync(id: string): Promise<void>;
}
export interface ConvoInputTemplate {
id: string;
name?: string;
value: string;
isJson?: boolean;
x?: number;
y?: number;
to?: string;
}
export interface ConvoTraverserGroup {
traversers: BehaviorSubject<ConvoTraverser[]>;
saveToStore: boolean;
createTvOptions?: CreateConvoTraverserOptions;
cancel: CancelToken;
}
/**
* Represents a convo source file
*/
export interface ConvoSourceNode {
id: string;
name?: string;
/**
* Source convo lang content
*/
source: string;
type?: string;
shared?: boolean;
x?: number;
y?: number;
}