📚 Docs / Pipeline Editor — visual pipeline configuration

Pipeline Editor — visual pipeline configuration

The pipeline editor is a ReactFlow canvas (right panel of the app) that visualizes the retrieval/scan pipeline as nodes and edges, lets users strip or restore sub-steps, persists the layout, and supports JSON export/import.
Scope note: this is both a visualization surface and a configuration surface. Since the POST /api/pipeline/config endpoint was added, the exported layout reconfigures the Python backend at runtime — rerank on/off from the rerank node, search mode + dense/sparse fusion weights from the retrieval nodes, and top_k overrides. Config is runtime-only (resets on restart). See PIPELINE_JSON.md §10 for the derivation rules.

1. Where it lives


2. Nodes

NodeType idRole
Intent ClassifierintentClassifierClassifies greeting vs legal query vs scan
ChitchatchitchatFast greeting reply, no retrieval
PlannerplannerWrites search plan, dispatches to dense + sparse
Dense RetrievaldenseRetrievalSemantic search over embeddings (ChromaDB)
Sparse RetrievalsparseRetrievalKeyword / BM25 search
RerankerrerankCross-encoder re-scores candidates
Ingest FilesingestParse attached files → chunk → embed → store
Compliance ScanscanPlaybook scan + flags
AnsweranswerWrites final answer from retrieved documents only
Custom TooltoolGeneric drag-and-drop node

Default flow: intent → planner → dense + sparse → rerank → answer and intent → ingest → scan → answer.


3. Removing a node — auto-bypass

Every node has a button. Deleting a middle sub-node bypasses it: incoming edges are rewired straight to the outgoing targets. Example: removing the Reranker creates dense → answer and sparse → answer edges, so the flow stays connected.


4. Re-enabling a removed sub-node (palette toggles)

The NodePalette shows the five sub-node types (dense, sparse, rerank, ingest, scan) with an on/off toggle switch (role="switch", brass styling, icon dims to 45% when off):

Implementation: PipelineEditor.tsxtoggleSubNode(type) + subNodeStates memo; SUB_NODE_ID_BY_TYPE maps palette type → canonical node id.


5. Persistence (localStorage)

pipelineStorage.ts:


6. Validation on load/import

validateLayout() is shared by localStorage loads and imported files:


7. Export / import (JSON)


8. Live status highlighting

While a query streams, the canvas highlights the active node and dims/brightens edges:


9. Styling

All pipeline CSS is in index.css under the "Pipeline Editor" section and is theme-variable based (works in light parchment and dark mode): .pipeline-node + status variants, .pipeline-node-remove, .pipeline-node-hint, .pipeline-switch, .pipeline-reset-btn, .pipeline-handle, .pipeline-canvas (ReactFlow overrides incl. minimap and controls), and the particle-edge animations.

Questions, answered

Short, self-contained answers about this guide.

What can I edit in the pipeline editor?

A visual canvas with nodes for each retrieval stage — dense, sparse, rerank, ingest, scan — plus toggles and bypass switches. Removing the rerank node sets skip_rerank; dense and sparse presence sets the search mode and fusion weights.

Is the layout persisted?

Yes. Layouts save to localStorage (pipeline-layout-v1), debounced on every change, and the app re-applies them on restart. A default layout is restored if none is saved.

Does the editor affect the backend?

Yes — the editor POSTs the layout to the backend pipeline config endpoint, so changes apply at runtime: top_k overrides, rerank on/off, and search-mode fusion weights all come from the canvas.