You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Next.js + TypeScript + Tailwind + React Flow visual editor tailored to Pipecat Flows. The editor runs entirely in the browser, syncs state to `localStorage`, and exports Pipecat-ready JSON _and_ Python code.
3
+
A visual editor for Pipecat Flows. Build a flow with a coding agent, then visualize it here: validate it, fix it, and export it to your Pipecat project. The document it edits is Pipecat's `FlowConfig` YAML: the nodes of a conversation, what each one says, which tools each offers, and where each tool leads. The canvas is a view of that file. The editor runs entirely in the browser, keeps a draft in `localStorage`, and saves the same YAML your Pipecat application loads.
-**Inspector-driven editing** – Schema-backed forms for messages, function schemas, decisions, actions, context strategy, and response controls.
16
-
-**Decision routing visualized** – Function-level decisions appear as inline decision nodes and translate directly to Python conditionals.
17
-
-**JSON + Python export** – Download the validated flow JSON or generate runnable Python scaffolding via the built-in code generator.
18
-
-**Schema validation** – TypeBox + Ajv plus custom graph rules (unique IDs, valid references) before import/export.
19
-
-**Local-first UX** – Autosave, undo/redo, keyboard shortcuts, dark mode, example flows, and Monaco JSON viewer.
14
+
-**The YAML is the document** – Open a `FlowConfig` file, edit it on the canvas or in the YAML pane, and save it. Comments, key order, block scalar styles, and every key in a hand-written file survive the round trip; the one change on save is that long lines, folded or plain, are re-wrapped at 80 columns.
15
+
-**Two views, one document** – The canvas and the YAML pane stay in step: a change on either side updates the other, with problems shown inline in the pane.
16
+
-**Routing as data** – A function is a tool name and a destination: a node, or a branch table keyed on a field of the tool's result. A function that only moves the conversation is written in the config alone, as a transition-only entry with a description, and needs no Python. A node card lists its functions as rows, a branch's cases as sub-rows, and each row has its own port.
17
+
-**Pipecat's schema and checks** – Validation uses the JSON Schema Pipecat ships for `FlowConfig`, vendored and pinned, plus the same cross-reference checks its loader makes and the same graph warnings it reports: unreachable nodes, dead ends, and branches that always go one place. Every finding uses Pipecat's `FlowIssue` shape and codes.
18
+
-**The handoff to code is a list** – The Flow panel lists every tool and action handler the config references and every `{{ key }}` placeholder its prompts read from the manager's state, so you know what the Python side must provide.
19
+
-**What a node does, on the card** – Besides its functions, a card shows the node's actions as a short script: what it says or runs on entry above the functions, what it says or runs on exit below. Click a line to open the node's actions.
20
+
-**Built for flows that arrive written** – Most flows are written by an agent or by hand and opened here to be seen and corrected. The start screen offers four ways in: open a file, paste YAML, start from an example, or a blank flow. A file dropped anywhere or YAML pasted anywhere opens at once.
21
+
-**Local-first UX** – Autosave, undo/redo, keyboard shortcuts, light and dark themes, auto-layout on open, and Pipecat's own example flows.
22
+
-**pipecat.ai's design language** – Zinc tokens, Geist type, hairline chrome, and the site's pixel-stream animation on the landing page and start screen, so the editor and the site read as one product.
20
23
21
24
## Getting Started
22
25
@@ -32,61 +35,65 @@ Run the dev server:
32
35
npm run dev
33
36
```
34
37
35
-
Open http://localhost:3000 to launch the editor.
38
+
Open http://localhost:3000for the landing page, or http://localhost:3000/editorto go straight to the editor's start screen.
36
39
37
40
## Testing
38
41
39
42
```bash
40
43
npm test# Vitest (unit + component tests)
41
-
npm run lint # ESLint + TypeScript rules
44
+
npm run lint # ESLint
45
+
npm run typecheck # TypeScript
42
46
```
43
47
44
48
## Working With Flows
45
49
46
-
- Flows are saved as JSON documents that follow `lib/schema/flow.schema.ts`. Detailed field descriptions live in [docs/SCHEMA.md](./docs/SCHEMA.md).
47
-
- The node palette includes `initial`, `node`, and `end` templates. All nodes ultimately emit the same Pipecat `NodeConfig`, but templates give sensible defaults.
48
-
- Routing is controlled by function metadata:
49
-
-`next_node_id` wires one function directly to the next node.
50
-
-`decision` objects attach Python snippets and conditionals that become decision nodes in the canvas and `if/elif` blocks in generated Python.
51
-
- Decision nodes shown on the canvas are visualization helpers; they are not persisted as standalone nodes. Instead, decision metadata is stored on the originating function.
52
-
- Edges are derived automatically from function routing. When you delete or rename nodes, the UI surfaces broken references so you can fix them before exporting.
50
+
- A flow is a `FlowConfig` YAML file. Its shape is defined by Pipecat's JSON Schema, vendored at `lib/schema/flow_config.schema.json`; the field descriptions there are Pipecat's own. See [docs/INTEGRATION.md](./docs/INTEGRATION.md) for the format and how a Pipecat application loads it.
51
+
- The canvas owns structure and the inspector owns content. Hover a node and press its "+" to add a function: leading to a next node, an end node, or a branch on the tool's result, or staying on the node. Every node is reachable by construction. A branch has an "add case" row. Double-click a node name, a tool name, or a case value to rename it in place; hover a row for its "×". Delete removes what is selected: an edge's route, a row, or a node.
52
+
- A card lists the node's pre-actions above its functions and its post-actions below: a `tts_say` as its text in quotes, a `function` action or custom type by its handler or name. Each block shows two lines and folds the rest into one; hover a line for the full sentence, click it to open the node's Actions tab. A node whose post-actions end the conversation is drawn as an end node instead.
53
+
- Every node needs task messages; the role message is optional and persists across transitions until another node sets its own, so setting it on the initial node covers the whole flow.
54
+
- The initial node is whichever node `initial_node` names; use "Make initial node" in a node's context menu to move it. An end node is one with an `end_conversation` post-action. Every node has the same shape.
55
+
- A node's name is its key in the config. Renaming a node rewrites every destination that pointed at it.
56
+
- Routing lives on functions as `transition_to`: a node name, or a branch table with `field`, `cases`, and an optional `default`. Dragging from a row's port sets that row's destination; dragging from the node's bottom handle adds a function, and from a branch's "add case" row adds a case.
57
+
- A `role_message` or a message's `content` may be `!include path`, which Pipecat fills in from a file beside the config when it loads. The editor keeps the reference as written and shows it as `!include path`; it cannot read the file, so placeholders in it are not listed. Type the same form into a field to make one.
58
+
- Tool descriptions and parameters are not in the config. They come from the direct functions in your Python handlers, referenced by name. The exception is a transition-only function, which the config defines entirely: a name, a description for the LLM, and the node it leads to. Toggle it on a function in the sidebar.
59
+
-`{{ key }}` in a role message, a task message, or a `tts_say` text is filled from `flow_manager.state` each time the node is entered. `{{ order.size }}` reads into a stored mapping, and `\{{ key }}` is a literal. The Flow panel lists the keys the prompts read.
60
+
- Edges are derived from the routing data. Deleting or renaming nodes surfaces broken references on the canvas and in the YAML pane.
61
+
- Canvas positions are not part of the document. A freshly opened file is auto-laid out; positions are then kept in `localStorage`, keyed by flow name.
53
62
54
63
### Persistence
55
64
56
65
- Every edit debounces into `localStorage`, so reloading the page restores the last working draft.
57
-
-No server calls are made; the editor operates entirely client-side.
66
+
-The editor makes no network calls; it operates entirely client-side. The landing page fetches the Pipecat repository's star count from GitHub when it renders, revalidated daily, and leaves the badge out if that fails.
58
67
59
-
### Import / Export
68
+
### Open / Save
60
69
61
70
Toolbar actions let you:
62
71
63
-
-**Import JSON** – Validates against the schema plus custom graph rules, then rehydrates the canvas.
64
-
-**Export JSON** – Serializes the current graph into Pipecat Flow JSON.
65
-
-**Export Python** – Validates the flow, runs `lib/codegen/pythonGenerator.ts`, and downloads a Python file with `NodeConfig` factories, handler scaffolding, optional decision routing, and FlowManager wiring comments.
66
-
67
-
See [docs/INTEGRATION.md](./docs/INTEGRATION.md) for full integration steps.
72
+
-**Open** – Read a `FlowConfig` file as YAML or JSON, validate it, and lay it out. A file in the editor's old JSON format is converted; what cannot convert (tool schemas, decisions) is reported by name.
73
+
-**Save** – Download the flow as `<name>.yaml`, merged into the document it was opened from so comments are preserved.
74
+
-**Layout** – Lay the nodes out automatically, the way a freshly opened file is.
75
+
-**Sidebar** – Always open: it shows the selected node, or the flow when nothing is selected, with the flow's name, its global functions, the issues Pipecat would report, and the tools, action handlers, and state placeholders the config refers to. It collapses from its header and reopens from the toolbar.
76
+
-**YAML** – The tab on the canvas's bottom edge, and the "Node YAML" button in the inspector, open the document itself, with parse, schema, and reference problems marked inline.
68
77
69
78
### Example Flows
70
79
71
-
Example definitions live in `lib/examples/` (e.g., `minimal.json`, `food_ordering.json`). Load them via **Load Example** in the toolbar to see end-to-end patterns.
80
+
The examples under **Load Example** are served from `public/examples/`. Hello world, food ordering, restaurant reservation, patient intake, insurance quote, and podcast interview are Pipecat's own: each is the `flow.yaml` of a directory under `examples/flows/yaml/` in the Pipecat repository, copied verbatim, with a `handlers.py` and a `bot.py` beside it there. Order status and lead qualification are written for the editor; their header comments list the handlers the Python must define and the state keys the prompts read.
72
81
73
82
## Tech Stack
74
83
75
84
-**Next.js 16** (App Router)
76
85
-**React 19** + **@xyflow/react** for the canvas
77
-
-**TypeScript**
78
-
-**Tailwind CSS v4** + custom UI primitives
79
-
-**Monaco Editor** for JSON inspection
80
-
-**TypeBox + Ajv** for schema + validation
86
+
-**TypeScript**, with the `FlowConfig` types generated from Pipecat's schema
87
+
-**Tailwind CSS v4** + custom UI primitives, on pipecat.ai's zinc tokens and Geist type (via `next/font`) so the editor and the site read as one product
88
+
-**yaml** for parsing with comment preservation, **Ajv** for schema validation, **dagre** for auto-layout
89
+
-**Monaco Editor** for the YAML pane
81
90
-**Zustand** for editor state
82
91
83
92
## Contributing
84
93
85
-
When expanding capabilities:
86
-
87
-
1. Update `lib/schema/flow.schema.ts` and `docs/SCHEMA.md` for any schema changes.
88
-
2. Add or tweak templates in `lib/nodes/templates.ts`.
89
-
3. Extend inspector forms under `components/inspector/forms/` to expose new fields.
90
-
4. Update tests (`tests/`) and docs as needed.
94
+
`npm run check:schema` compares the vendored schema with Pipecat's at the pinned commit, and `npm run check:schema -- main` with what has shipped. When Pipecat's `FlowConfig` changes:
91
95
92
-
See [docs/SCHEMA.md](./docs/SCHEMA.md) for authoritative schema details.
96
+
1. Copy the new `flow_config.schema.json` over `lib/schema/flow_config.schema.json` and update the source record in `lib/schema/flowConfig.ts`.
97
+
2. Run `npm run gen:types` to regenerate `lib/schema/flowConfig.generated.ts`.
98
+
3. Mirror any new validator in `lib/validation/flowConfigValidator.ts`.
99
+
4. Extend the inspector forms under `components/inspector/forms/` to expose new fields, and update tests under `tests/`.
0 commit comments