mirror of
https://github.com/run-llama/workflows-ts.git
synced 2026-08-27 01:21:16 -04:00
feat: simplify using visualization (#165)
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
---
|
||||
"demo-viz": patch
|
||||
"@llamaindex/workflow-otel": patch
|
||||
"@llamaindex/workflow-viz": patch
|
||||
---
|
||||
|
||||
Simplify visualization by exporting .draw function
|
||||
@@ -9,13 +9,10 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@llamaindex/workflow-core": "latest",
|
||||
"@llamaindex/workflow-viz": "latest",
|
||||
"graphology": "^0.26.0",
|
||||
"graphology-layout-force": "^0.2.4",
|
||||
"@llamaindex/workflow-core": "^1.3.1",
|
||||
"@llamaindex/workflow-viz": "^1.0.1",
|
||||
"react": "^19.1.0",
|
||||
"react-dom": "^19.1.0",
|
||||
"sigma": "^3.0.1"
|
||||
"react-dom": "^19.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^19.1.2",
|
||||
|
||||
@@ -1,28 +1,9 @@
|
||||
import "./style.css";
|
||||
import Sigma from "sigma";
|
||||
import { workflow } from "./workflow";
|
||||
import { toSigma } from "@llamaindex/workflow-viz";
|
||||
import ForceSupervisor from "graphology-layout-force/worker";
|
||||
|
||||
const container = document.getElementById("app") as HTMLElement;
|
||||
|
||||
// const graph = new Graph();
|
||||
// graph.addNode("John", { x: 0, y: 10, size: 5, label: "John", color: "blue" });
|
||||
// graph.addNode("Mary", { x: 10, y: 0, size: 3, label: "Mary", color: "red" });
|
||||
// graph.addEdge("John", "Mary");
|
||||
const graph = toSigma(workflow.getGraph());
|
||||
|
||||
graph.nodes().forEach((node, i) => {
|
||||
const angle = (i * 2 * Math.PI) / graph.order;
|
||||
graph.setNodeAttribute(node, "x", 100 * Math.cos(angle));
|
||||
graph.setNodeAttribute(node, "y", 100 * Math.sin(angle));
|
||||
});
|
||||
|
||||
const layout = new ForceSupervisor(graph);
|
||||
layout.start();
|
||||
|
||||
const settings = {
|
||||
workflow.draw(container, {
|
||||
defaultEdgeColor: "#999",
|
||||
};
|
||||
|
||||
new Sigma(graph, container, settings);
|
||||
layout: "force",
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { createWorkflow, workflowEvent } from "@llamaindex/workflow-core";
|
||||
import { withGraph } from "@llamaindex/workflow-viz";
|
||||
import { withDrawing } from "@llamaindex/workflow-viz";
|
||||
|
||||
//#region define workflow events
|
||||
const startEvent = workflowEvent<string>({
|
||||
@@ -26,7 +26,7 @@ const stopEvent = workflowEvent<string>({
|
||||
//#endregion
|
||||
|
||||
//#region defines workflow
|
||||
const workflow = withGraph(createWorkflow());
|
||||
const workflow = withDrawing(createWorkflow());
|
||||
|
||||
workflow.handle([startEvent], async (ctx) => {
|
||||
const { sendEvent, stream } = ctx;
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/run-llama/llama-flow.git",
|
||||
"url": "https://github.com/run-llama/workflow-ts.git",
|
||||
"directory": "packages/otel"
|
||||
},
|
||||
"publishConfig": {
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
import { createWorkflow, workflowEvent } from "@llamaindex/workflow-core";
|
||||
import { withGraph } from "@llamaindex/workflow-viz";
|
||||
|
||||
//#region define workflow events
|
||||
const startEvent = workflowEvent<string>({
|
||||
debugLabel: "start",
|
||||
});
|
||||
const branchAEvent = workflowEvent<string>({
|
||||
debugLabel: "branchA",
|
||||
});
|
||||
const branchBEvent = workflowEvent<string>({
|
||||
debugLabel: "branchB",
|
||||
});
|
||||
const branchCEvent = workflowEvent<string>({
|
||||
debugLabel: "branchC",
|
||||
});
|
||||
const branchCompleteEvent = workflowEvent<string>({
|
||||
debugLabel: "branchComplete",
|
||||
});
|
||||
const allCompleteEvent = workflowEvent<string>({
|
||||
debugLabel: "allComplete",
|
||||
});
|
||||
const stopEvent = workflowEvent<string>({
|
||||
debugLabel: "stop",
|
||||
});
|
||||
//#endregion
|
||||
|
||||
//#region defines workflow
|
||||
const workflow = withGraph(createWorkflow());
|
||||
workflow.handle([startEvent], async (context) => {
|
||||
const { sendEvent, stream } = context;
|
||||
// emit 3 different events, handled separately
|
||||
sendEvent(branchAEvent.with("Branch A"));
|
||||
sendEvent(branchBEvent.with("Branch B"));
|
||||
sendEvent(branchCEvent.with("Branch C"));
|
||||
|
||||
const results = await stream.filter(branchCompleteEvent).take(3).toArray();
|
||||
|
||||
return allCompleteEvent.with(results.map((e) => e.data).join(", "));
|
||||
});
|
||||
|
||||
workflow.handle([branchAEvent], (_context1, branchA) => {
|
||||
return branchCompleteEvent.with(branchA.data);
|
||||
});
|
||||
|
||||
workflow.handle([branchBEvent], (_context2, branchB) => {
|
||||
return branchCompleteEvent.with(branchB.data);
|
||||
});
|
||||
|
||||
workflow.handle([branchCEvent], (_context3, branchC) => {
|
||||
return branchCompleteEvent.with(branchC.data);
|
||||
});
|
||||
|
||||
workflow.handle([allCompleteEvent], (_context4, allComplete) => {
|
||||
return stopEvent.with(allComplete.data);
|
||||
});
|
||||
|
||||
//#endregion
|
||||
|
||||
const graph = workflow.getGraph();
|
||||
console.log("--- Graph Nodes ---");
|
||||
graph.forEachNode((node, attributes) => {
|
||||
console.log(`Node: ${node}, Attributes: ${JSON.stringify(attributes)}`);
|
||||
});
|
||||
|
||||
console.log("\n--- Graph Edges ---");
|
||||
graph.forEachEdge((edge, attributes, source, target) => {
|
||||
console.log(
|
||||
`Edge from ${source} to ${target} (ID: ${edge}), Attributes: ${JSON.stringify(attributes)}`,
|
||||
);
|
||||
});
|
||||
console.log("--- End of Graph Details ---");
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@llamaindex/workflow-viz",
|
||||
"version": "1.0.2",
|
||||
"description": "Visualization components for LlamaFlow",
|
||||
"description": "Visualization components for drawing LlamaIndex Workflows in the browser",
|
||||
"type": "module",
|
||||
"main": "dist/index.cjs",
|
||||
"types": "dist/index.d.ts",
|
||||
@@ -46,7 +46,7 @@
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/run-llama/llama-flow.git",
|
||||
"url": "https://github.com/run-llama/workflow-ts.git",
|
||||
"directory": "packages/viz"
|
||||
},
|
||||
"publishConfig": {
|
||||
@@ -54,6 +54,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.27.2",
|
||||
"graphology": "^0.26.0"
|
||||
"graphology": "^0.26.0",
|
||||
"graphology-layout-force": "^0.2.4",
|
||||
"sigma": "^3.0.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
import type { Workflow } from "@llamaindex/workflow-core";
|
||||
import Sigma from "sigma";
|
||||
import type { Settings } from "sigma/settings";
|
||||
import { withGraph } from "./graph";
|
||||
import { toSigma } from "./sigma";
|
||||
import ForceSupervisor from "graphology-layout-force/worker";
|
||||
|
||||
export type DrawingOptions = {
|
||||
layout?: "force" | "none";
|
||||
} & Partial<Settings>;
|
||||
|
||||
export type WithDrawingWorkflow = {
|
||||
draw(container: HTMLElement, options?: DrawingOptions): void;
|
||||
};
|
||||
|
||||
export function withDrawing<WorkflowLike extends Workflow>(
|
||||
workflow: WorkflowLike,
|
||||
): WorkflowLike & WithDrawingWorkflow {
|
||||
const workflowWithGraph = withGraph(workflow);
|
||||
|
||||
return {
|
||||
...workflowWithGraph,
|
||||
draw: (container: HTMLElement, options?: DrawingOptions) => {
|
||||
const graph = toSigma(workflowWithGraph.getGraph());
|
||||
|
||||
// simple radial positions so nodes don't overlap before layout
|
||||
const nodes = graph.nodes();
|
||||
const order = graph.order || nodes.length || 1;
|
||||
nodes.forEach((node, i) => {
|
||||
const angle = (i * 2 * Math.PI) / order;
|
||||
graph.setNodeAttribute(node, "x", 100 * Math.cos(angle));
|
||||
graph.setNodeAttribute(node, "y", 100 * Math.sin(angle));
|
||||
});
|
||||
|
||||
// default to force layout unless explicitly disabled
|
||||
if ((options?.layout ?? "force") === "force") {
|
||||
const layout = new ForceSupervisor(graph);
|
||||
layout.start();
|
||||
}
|
||||
|
||||
// create sigma renderer
|
||||
const { layout: _layout, ...sigmaSettings } = options ?? {};
|
||||
void _layout;
|
||||
new Sigma(graph, container, sigmaSettings);
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,2 +1 @@
|
||||
export * from "./graph";
|
||||
export * from "./sigma";
|
||||
export { withDrawing } from "./drawing";
|
||||
|
||||
Generated
+8
-11
@@ -203,26 +203,17 @@ importers:
|
||||
demo/visualization:
|
||||
dependencies:
|
||||
'@llamaindex/workflow-core':
|
||||
specifier: latest
|
||||
specifier: ^1.3.1
|
||||
version: link:../../packages/core
|
||||
'@llamaindex/workflow-viz':
|
||||
specifier: latest
|
||||
specifier: ^1.0.1
|
||||
version: link:../../packages/viz
|
||||
graphology:
|
||||
specifier: ^0.26.0
|
||||
version: 0.26.0(graphology-types@0.24.8)
|
||||
graphology-layout-force:
|
||||
specifier: ^0.2.4
|
||||
version: 0.2.4(graphology-types@0.24.8)
|
||||
react:
|
||||
specifier: ^19.1.0
|
||||
version: 19.1.0
|
||||
react-dom:
|
||||
specifier: ^19.1.0
|
||||
version: 19.1.0(react@19.1.0)
|
||||
sigma:
|
||||
specifier: ^3.0.1
|
||||
version: 3.0.2(graphology-types@0.24.8)
|
||||
devDependencies:
|
||||
'@types/react':
|
||||
specifier: ^19.1.2
|
||||
@@ -384,6 +375,12 @@ importers:
|
||||
graphology:
|
||||
specifier: ^0.26.0
|
||||
version: 0.26.0(graphology-types@0.24.8)
|
||||
graphology-layout-force:
|
||||
specifier: ^0.2.4
|
||||
version: 0.2.4(graphology-types@0.24.8)
|
||||
sigma:
|
||||
specifier: ^3.0.1
|
||||
version: 3.0.2(graphology-types@0.24.8)
|
||||
devDependencies:
|
||||
'@babel/types':
|
||||
specifier: ^7.27.1
|
||||
|
||||
Reference in New Issue
Block a user