@elimeleth/vct-flow
Version:
Crea un archivo app.ts, coloca el codigo de abajo alli y luego puedes correrlo con `npx tsx src/app.ts`
332 lines (331 loc) • 10.8 kB
TypeScript
import { Assistant, BaseAssistant, ClaudeAsst, GeminiAsst, OpenAILegacyAsst } from "@elimeleth/vct-assistants";
import { Workflow } from "./core";
import { ProviderClass } from "./io/providerClass";
import { Database } from "./io/database/database";
import { ExecutionError, Logging } from "./io/database/entities/others";
import FollowUp from "./core/followup";
export type PrinterFunction = (message: string | string[], title: string, cName?: 'bgMagenta' | 'bgRed' | 'bgCyan') => void;
export interface Nodes {
name?: string;
id: number | string;
delay?: number;
wait?: number;
capture?: boolean;
wait_for_input?: boolean;
wait_input_id?: string | number;
fallback?: (msg: string) => Promise<{
message?: string;
passed: boolean;
next_node?: GotoRotue;
}>;
follow_up?: FollowUp;
isChild: boolean;
next_node?: GotoRotue;
conditional?: (ctx: Context) => Promise<boolean>;
}
export interface CrontabSchedule {
minute: string;
hour: string;
dayOfMonth: string;
month: string;
dayOfWeek: string;
}
export type FollowUpArgs = {
to_forward_worflow: {
workflow_name: string;
action_id: string | number;
};
inactive_at: {
time: number;
type: "minutes" | "hours" | "days";
};
remove_on?: "target_move_on" | "trigger_message";
trigger_message: string;
};
export type ReturnTypeFromKey<T, K extends keyof T> = T[K];
export interface FollowUpRecord {
id: number;
name: string;
phone: string;
current_workflow_name: string;
current_action_id: string | number;
workflow_name: string;
action_id: string | number;
condition: "equals_to" | "contains";
remove_on: ReturnTypeFromKey<FollowUpArgs, "remove_on">;
trigger_message: string;
inactive_at: Date;
}
export interface Attrb {
name: string;
phone: string;
current_workflow_name: string;
current_action_id: string | number;
database: Database;
}
export interface CustomerWorkflowHistory {
message_id: string;
phone: string;
name: string;
current_workflow_name: string;
current_action_id: string | number;
last_date_activity: string;
last_message: string;
last_message_bot?: string;
reason_inactivity?: string | null;
action_type?: "send" | "goto" | "input" | "end" | "wait" | "follow_up" | "fallback" | "desicion" | "capture";
action_description?: string | null;
target_node?: string | null;
delay?: number | null;
wait?: number | null;
capture?: boolean;
wait_for_input?: boolean;
follow_up_time?: string | null;
is_decision?: boolean;
is_fallback?: boolean;
is_capture?: boolean;
is_final?: boolean;
is_pending?: boolean;
}
export type EdgeRouter = (ctx: Context) => Promise<Workflow<string> | null>;
export type InferWorkflowNames<T extends Workflow<string>[]> = T[number]["metadata"]["name"];
export type GlobalRouterArgs<TProvider extends Partial<ProviderClass>> = {
database?: Database;
restorePreviousCheckpoint?: boolean;
pauseFn?: {
pause: (ctx: Context) => Promise<boolean>;
is_pause: (ctx: Context) => Promise<boolean>;
};
circuitBreaker?: (ctx: Context) => Promise<boolean>;
llm?: Llm;
transform_message?: (message: string) => string;
follow_up_crontab?: CrontabSchedule | undefined;
downloadConf?: {
auto: boolean;
directory: string;
};
on_error?: (error: ExecutionError) => Promise<void>;
openai_assistant?: {
apiKey?: string;
functions?: Function[];
} | boolean | Assistant;
assistant?: {
type?: "openai_legacy" | "gemini" | "claude";
apiKey?: string;
functions?: Function[];
tools?: any[];
};
provider: TProvider;
force_trigger_flow?: boolean;
cancelEventFromMe?: boolean;
experimental_tracing_messages?: {
crontab_schema?: string;
cb: (messages: Array<Logging>) => Promise<void>;
};
force_redirect_flow?: {
key: WorkflowKey;
to_workflow: Workflow<any, any> | string;
}[] | undefined;
};
export type Extensions<TProvider extends Partial<ProviderClass>> = {
http: <T>(options: HttpRequestOptions<T>) => Promise<T>;
provider: TProvider;
assistant: Assistant | BaseAssistant | ClaudeAsst | GeminiAsst | OpenAILegacyAsst;
database: Database;
checkpointer: ICheckpointer;
};
export interface InternalMethods<TProvider extends Partial<ProviderClass>> {
send: (message: DynamicSendMessage, options?: DynamicOptionsSendMessage) => Promise<any>;
end: (args?: {
is_pending: boolean;
}) => Promise<void>;
goto: (targetNodeId: GotoRotue) => Promise<void>;
state: StateManager;
extensions: Extensions<TProvider>;
}
export type GotoRotue = number | string | Workflow<string> | {
parentNode: Workflow<string> | "this";
node_id: number | string | "last";
};
export interface CallbackMapping {
[nodeId: number]: (params: any) => Promise<any>;
}
export interface Provider {
on(event: 'fromMe' | 'message', callback: (ctx: any) => void): void;
sendMessage(message: string, options: any, type: 'plain' | 'image' | 'voice' | 'auto'): void;
}
export declare abstract class ICheckpointer {
abstract isCompleted(ctx: Context): Boolean;
abstract deleteCheckpoint(thread_id: string): Promise<void>;
abstract getCheckpointStatusPending(): GlobalCheckpoint[];
abstract loadAllCheckpointsOnInit(): Promise<void>;
abstract getCheckpointStatus(thread_id: string): string | null;
abstract saveCheckpoint(args: GlobalCheckpoint): Promise<void>;
abstract loadCheckpointFromFile(filePath: string): any;
abstract updateCheckpointStatus(args: GlobalCheckpoint): Promise<any>;
abstract updateCheckpointStatus(args: Partial<GlobalCheckpoint>, force?: boolean): Promise<any>;
abstract getActualThreadID(thread_id: string): GlobalCheckpoint;
}
export type Llm = {
apiKey?: string;
model?: string;
provider: "google-genai" | 'groq' | 'openai';
multimodal?: {
capture_intentions?: boolean;
} | boolean;
};
export interface GlobalCheckpoint {
trigger_key: WorkflowKey;
workflow_name: string;
thread_id: string;
message_id: string;
node_id: number | string;
timestamp?: Date | string | number;
state: any;
status?: StatusChck;
ctx: Context;
}
export type MethodsOROptions<TProvider extends Partial<ProviderClass>> = ((ctx: Context, methods: InternalMethods<TProvider>) => Promise<void>) | Omit<Partial<Nodes>, "isChild">;
export type CallbackMethods<TProvider extends Partial<ProviderClass>> = ((ctx: Context, methods: InternalMethods<TProvider>) => Promise<void>);
export type MessageContentType = 'audio' | 'video' | 'document' | 'image' | 'text' | "url";
export type Metadata<TName extends string> = {
name?: TName;
intentions?: {
intention: string;
description: string;
}[];
id?: string | number;
[key: string]: any;
};
type ConditionsRaise = "when_not_command_found" | (() => boolean);
export type OptionsWorkFlow<TName extends string> = {
delay?: number;
metadata?: Metadata<TName>;
conditions_raise?: {
condition?: ConditionsRaise;
};
[key: string]: any;
};
export type DynamicSendMessage = string | string[] | DynamicOptionsSendMessage[] | Array<string | DynamicOptionsSendMessage>;
export type DynamicOptionsSendMessage = {
body: string | string[];
save_metadata?: {
usage?: {
total_tokens: number;
cost: number;
model: string;
};
intentions?: string;
services?: string;
[key: string]: any;
};
reaction?: {
message_id: string;
emoji: string;
};
reply?: any;
media?: string;
buttons?: {
body: string;
}[];
};
export type HttpCallback = (error: Error | null, data?: any) => Promise<void>;
export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';
export interface HttpRequestOptions<T> {
urlString: string;
method: HttpMethod;
headers?: Record<string, string>;
body?: T;
}
export type Context = {
file_dir_path?: string;
http_request: {
data: any;
error: Error | null;
};
created_at?: Date;
variables?: Record<string, any>;
file: any;
type?: "text" | "image" | "audio" | string;
connection: any;
breakpoint?: boolean;
from: string;
message_id: string;
phone?: string;
thread_id?: string;
name?: string;
body?: string;
caption?: string;
messages?: string[];
node_id?: number | string;
timestamp: Date | string | number;
shouldEnd?: boolean;
isFromMe?: boolean;
next_child_id?: number;
ref?: string;
host?: string;
[key: string]: any;
};
export type StatusChck = 'pending' | 'in-progress' | 'completed' | 'reset';
export interface StateManager {
/**
* Updates the value associated with the given key.
*
* @param {string} key - The key for which the value needs to be updated.
* @param {any} value - The new value to be associated with the key.
* @returns {Promise<void>} - A promise that resolves when the update is complete.
*/
update: (key: string, value: any) => Promise<void>;
/**
* Retrieves a value from storage by its key.
*
* @template T - The type of the value to be retrieved.
* @param {string} key - The key associated with the value to retrieve.
* @returns {Promise<T>} - A promise that resolves to the retrieved value.
*/
get: <T = any>(key: string) => Promise<T>;
clear: () => Promise<void>;
delete: (key: string) => Promise<void>;
}
export type StateHandler = {
state: any;
manager: StateManager;
};
export type EventRegex = {
MEDIA: RegExp;
DOCUMENT: RegExp;
VOICE_NOTE: RegExp;
LOCATION: RegExp;
ORDER: RegExp;
TEMPLATE: RegExp;
ANY: RegExp;
};
export type StaticEventsxp = "image" | "media" | "voice" | "document" | "location" | "order" | "template" | "any";
export type Eventsxp = StaticEventsxp | (string & {});
export type WorkflowKey = Eventsxp | RegExp | Array<Eventsxp | RegExp>;
export type ProviderEventTypes = {
message: [arg1: any];
require_action: [
arg1: {
title: string;
instructions: string[];
}
];
notice: [
arg1: {
title: string;
instructions: string[];
}
];
ready: any;
auth_failure: any;
host: any;
[extra: string]: any | [args: any];
};
export type GlobalVendorArgs<V = {
[key: string]: any;
}> = {
name?: string;
port?: number;
} & V;
export {};