ГібридЧат-ботПлагінDataflowControl flow
npm i rete rete-engine
Для належної роботи всі класи вузлів повинні реалізовувати метод execute
для керування потоком та метод data
для потоку даних.
Клас Start
призначений для передачі керування та має стандартний метод data
, який повертає порожній об'єкт.
const 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
.
class 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
відповідає лише за надання даних і не може приймати чи передавати керування.
class 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>;
import { 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);
const 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
служить початковою точкою для виконання графа.
engine.execute(start.id);
У результаті вузол start
передає керування вузлу log1
, який отримує дані з вузла text1
за допомогою методу fetchInputs
.
Перегляньте повний результат на сторінці прикладу Гібрид. Крім того, ви можете дослідити інший більш складний приклад Чат-бота, який використовує цей підхід.