UNPKG

@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
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 {};