ГібридЧат-ботПлагінDataflowControl flow
bashnpm i rete rete-engine
Для належної роботи всі класи вузлів повинні реалізовувати метод execute для керування потоком та метод data для потоку даних.
Клас Start призначений для передачі керування та має стандартний метод data, який повертає порожній об'єкт.
tsconst socket = new ClassicPreset.Socket("socket"); class Start extends ClassicPreset.Node { constructor() { super("Start"); this.addOutput("exec", new ClassicPreset.Output(socket, "Exec")); } execute(_: never, forward: (output: "exec") => void) { forward("exec"); } data() { return {}; } }
Разом із отриманням керування, клас Log також може запитувати дані від вхідних вузлів через порт message за допомогою методу fetchInputs екземпляра DataflowEngine.
tsclass Log extends ClassicPreset.Node { constructor() { super("Log"); this.addInput("exec", new ClassicPreset.Input(socket, "Exec", true)); this.addInput("message", new ClassicPreset.Input(socket, "Text")); this.addOutput("exec", new ClassicPreset.Output(socket, "Exec")); } async execute(input: "exec", forward: (output: "exec") => void) { const inputs = (await dataflow.fetchInputs(this.id)) as { message: string[]; }; console.log((inputs.message && inputs.message[0]) || ""); forward("exec"); } data() { return {}; } }
Клас TextNode відповідає лише за надання даних і не може приймати чи передавати керування.
tsclass TextNode extends ClassicPreset.Node { constructor(private text: string) { super("Text"); this.addOutput("value", new ClassicPreset.Output(socket, "Number")); } execute() {} data(): { value: string } { return { value: this.text }; } } class Connection<A extends NodeProps, B extends NodeProps> extends ClassicPreset.Connection<A, B> {} type NodeProps = Start | Log | TextNode; type ConnProps = Connection<Start, Log> | Connection<TextNode, Log>; type Schemes = GetSchemes<NodeProps, ConnProps>;
tsimport { NodeEditor } from "rete"; import { DataflowEngine, ControlFlowEngine } from "rete-engine"; const editor = new NodeEditor<Schemes>(); const dataflow = new DataflowEngine<Schemes>(({ inputs, outputs }) => { return { inputs: () => Object.keys(inputs).filter((name) => name !== "exec"), outputs: () => Object.keys(outputs).filter((name) => name !== "exec") }; }); const controlflow = new ControlFlowEngine<Schemes>(() => { return { inputs: () => ["exec"], outputs: () => ["exec"] }; }); editor.use(dataflow); editor.use(controlflow);
tsconst start = new Start(); const text1 = new TextNode("log"); const log1 = new Log(); const con1 = new Connection(start, "exec", log1, "exec"); const con2 = new Connection(text1, "value", log1, "message"); await editor.addNode(start); await editor.addNode(text1); await editor.addNode(log1); await editor.addConnection(con1); await editor.addConnection(con2);
Вузол start служить початковою точкою для виконання графа.
tsengine.execute(start.id);
У результаті вузол start передає керування вузлу log1, який отримує дані з вузла text1 за допомогою методу fetchInputs.
Перегляньте повний результат на сторінці прикладу Гібрид. Крім того, ви можете дослідити інший більш складний приклад Чат-бота, який використовує цей підхід.