langflower 0.0.10 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +96 -70
- package/docs/public/README.md +2 -2
- package/docs/public/configuration.md +4 -0
- package/docs/public/extending.md +18 -2
- package/docs/public/getting-started.md +7 -0
- package/docs/public/how-it-works.md +18 -11
- package/docs/public/product.md +35 -25
- package/package.json +1 -1
- package/ui-dist/chunk-QI4IYILJ.js +4 -0
- package/ui-dist/{chunk-7UMVYN3A.js → chunk-UG3GFV4Y.js} +1 -1
- package/ui-dist/index.html +2 -2
- package/ui-dist/main-ODIDCCNX.js +315 -0
- package/ui-dist/styles-2JMBAQC3.css +1 -0
- package/vendor/common-nodes/dist/ai/features/llm-session/llm-session-shell.d.ts +2 -2
- package/vendor/common-nodes/dist/ai/features/llm-session/llm-session-shell.js +39 -7
- package/vendor/common-nodes/dist/ai/features/llm-session/run-session-machine.d.ts +11 -0
- package/vendor/common-nodes/dist/ai/features/llm-session/run-session-machine.js +2 -2
- package/vendor/common-nodes/dist/ai/features/run-host-services.d.ts +10 -0
- package/vendor/common-nodes/dist/ai/nodes/critique/node.js +5 -1
- package/vendor/common-nodes/dist/ai/nodes/fake-llm/node.js +7 -1
- package/vendor/common-nodes/dist/ai/nodes/openai-llm/node.js +5 -1
- package/vendor/common-nodes/dist/ai/nodes/review/node.js +7 -1
- package/vendor/common-nodes/dist/ai/nodes/sub-agent/node.js +62 -22
- package/vendor/common-nodes/dist/catalog.js +10 -0
- package/vendor/common-nodes/dist/crawl/crawl/node.js +11 -3
- package/vendor/common-nodes/dist/crawl/crawl-tools/node.js +5 -1
- package/vendor/common-nodes/dist/crawl/extract-links/node.js +7 -1
- package/vendor/common-nodes/dist/crawl/fetch-url/node.js +13 -4
- package/vendor/common-nodes/dist/crawl/save-page/node.js +11 -3
- package/vendor/common-nodes/dist/embeddings/create-embedding.d.ts +39 -0
- package/vendor/common-nodes/dist/embeddings/create-embedding.js +154 -0
- package/vendor/common-nodes/dist/embeddings/embed-provider/node.d.ts +53 -0
- package/vendor/common-nodes/dist/embeddings/embed-provider/node.js +126 -0
- package/vendor/common-nodes/dist/embeddings/embed-similarity/node.d.ts +20 -0
- package/vendor/common-nodes/dist/embeddings/embed-similarity/node.js +81 -0
- package/vendor/common-nodes/dist/embeddings/embed-text/node.d.ts +53 -0
- package/vendor/common-nodes/dist/embeddings/embed-text/node.js +91 -0
- package/vendor/common-nodes/dist/embeddings/from-embedding.d.ts +8 -0
- package/vendor/common-nodes/dist/embeddings/from-embedding.js +24 -0
- package/vendor/common-nodes/dist/embeddings/resolve-embedding-provider-model.d.ts +11 -0
- package/vendor/common-nodes/dist/embeddings/resolve-embedding-provider-model.js +8 -0
- package/vendor/common-nodes/dist/flow/checkpoint/node.js +7 -3
- package/vendor/common-nodes/dist/flow/delay/node.d.ts +2 -6
- package/vendor/common-nodes/dist/flow/delay/node.js +13 -9
- package/vendor/common-nodes/dist/flow/loop/node.js +7 -1
- package/vendor/common-nodes/dist/flow/merge/node.js +7 -1
- package/vendor/common-nodes/dist/flow/repeat/node.js +5 -1
- package/vendor/common-nodes/dist/flow/router/node.js +7 -1
- package/vendor/common-nodes/dist/hitl/chat-input/node.d.ts +2 -2
- package/vendor/common-nodes/dist/hitl/chat-input/node.js +8 -4
- package/vendor/common-nodes/dist/hitl/review-gate/node.js +11 -5
- package/vendor/common-nodes/dist/langflower-tools/node.js +5 -1
- package/vendor/common-nodes/dist/logic/assert/node.js +7 -1
- package/vendor/common-nodes/dist/logic/compare/node.js +7 -1
- package/vendor/common-nodes/dist/logic/gate/node.js +7 -1
- package/vendor/common-nodes/dist/logic/if/node.js +7 -1
- package/vendor/common-nodes/dist/logic/switch/node.js +7 -1
- package/vendor/common-nodes/dist/mcp/mcp-http/node.js +55 -53
- package/vendor/common-nodes/dist/mcp/mcp-stdio/node.js +52 -50
- package/vendor/common-nodes/dist/memory/memory-tools/node.js +5 -1
- package/vendor/common-nodes/dist/output/finish/node.js +13 -1
- package/vendor/common-nodes/dist/output/preview/node.js +9 -2
- package/vendor/common-nodes/dist/primitives/boolean/node.js +7 -1
- package/vendor/common-nodes/dist/primitives/number/node.js +7 -1
- package/vendor/common-nodes/dist/primitives/string/node.js +7 -1
- package/vendor/common-nodes/dist/primitives/string-multiline/node.d.ts +17 -0
- package/vendor/common-nodes/dist/primitives/string-multiline/node.js +31 -0
- package/vendor/common-nodes/dist/text/append-file/node.js +11 -3
- package/vendor/common-nodes/dist/text/concat/node.js +5 -1
- package/vendor/common-nodes/dist/text/read-file/node.js +9 -3
- package/vendor/common-nodes/dist/text/split-paced/node.d.ts +21 -0
- package/vendor/common-nodes/dist/text/split-paced/node.js +93 -0
- package/vendor/common-nodes/dist/text/write-file/node.js +11 -3
- package/vendor/common-nodes/dist/tools/tool-collection/node.js +5 -2
- package/vendor/common-nodes/package.json +4 -0
- package/vendor/node-sdk/dist/node-factory/define-embed/embed-handle.d.ts +25 -0
- package/vendor/node-sdk/dist/node-factory/define-embed/embed-handle.js +25 -0
- package/vendor/node-sdk/dist/node-factory/define-mcp/mcp-handle.d.ts +1 -0
- package/vendor/node-sdk/dist/node-factory/define-mcp/mcp-handle.js +1 -0
- package/vendor/node-sdk/dist/node-factory/define-node/define-node.d.ts +2 -0
- package/vendor/node-sdk/dist/node-factory/define-node/define-node.js +4 -1
- package/vendor/node-sdk/dist/node-factory/define-reactive-node/define-reactive-node.d.ts +3 -1
- package/vendor/node-sdk/dist/node-factory/define-reactive-node/define-reactive-node.js +2 -1
- package/vendor/node-sdk/dist/node-factory/define-reactive-node/io-helpers.d.ts +15 -0
- package/vendor/node-sdk/dist/node-factory/define-reactive-node/io-helpers.js +17 -1
- package/vendor/node-sdk/dist/node-factory/define-reactive-node/port-meta.d.ts +17 -4
- package/vendor/node-sdk/dist/node-factory/define-reactive-node/test/samples/delay-node.js +4 -2
- package/vendor/node-sdk/dist/node-factory/define-reactive-node/types.d.ts +4 -3
- package/vendor/node-sdk/dist/testing/create-node-harness.d.ts +30 -0
- package/vendor/node-sdk/dist/testing/create-node-harness.js +68 -0
- package/vendor/node-sdk/package.json +4 -4
- package/vendor/runtime/dist/types.d.ts +1 -1
- package/vendor/server/dist/bootstrap/project-bootstrap.service.d.ts +1 -1
- package/vendor/server/dist/bootstrap/seed-skeleton.d.ts +2 -2
- package/vendor/server/dist/bootstrap/seed-skeleton.js +17 -2
- package/vendor/server/dist/bridge/bind-embed-context.d.ts +7 -0
- package/vendor/server/dist/bridge/bind-embed-context.js +16 -0
- package/vendor/server/dist/bridge/build-execution-context.d.ts +2 -2
- package/vendor/server/dist/bridge/build-execution-context.js +6 -2
- package/vendor/server/dist/bridge/emit-bootstrap.js +4 -1
- package/vendor/server/dist/bridge/settings-draft-controller.js +7 -3
- package/vendor/server/dist/bridge/wire-config-handlers.js +2 -0
- package/vendor/server/dist/bridge/wire-editor-handlers.js +14 -0
- package/vendor/server/dist/config/langflower-config.service.d.ts +2 -0
- package/vendor/server/dist/config/langflower-config.service.js +30 -0
- package/vendor/server/dist/session/build-session-bootstrap.js +1 -0
- package/vendor/server/dist/session/langflower-session.d.ts +3 -1
- package/vendor/server/dist/session/langflower-session.js +3 -1
- package/vendor/server/dist/workflow/apply-editor-mutation.js +6 -0
- package/vendor/server/dist/workflow/workflow-persisted-inputs.js +8 -6
- package/vendor/server/skeleton/instructions.md +15 -3
- package/vendor/server/skeleton/nodes/hello-embed/README.md +185 -0
- package/vendor/server/skeleton/nodes/hello-embed/hello-embed.nodes.test.ts +181 -0
- package/vendor/server/skeleton/nodes/hello-embed/ingest.ts +126 -0
- package/vendor/server/skeleton/nodes/hello-embed/lib/chunk-markdown.test.ts +40 -0
- package/vendor/server/skeleton/nodes/hello-embed/lib/chunk-markdown.ts +123 -0
- package/vendor/server/skeleton/nodes/hello-embed/lib/ingest-search.test.ts +180 -0
- package/vendor/server/skeleton/nodes/hello-embed/lib/ingest.ts +128 -0
- package/vendor/server/skeleton/nodes/hello-embed/lib/paths.test.ts +20 -0
- package/vendor/server/skeleton/nodes/hello-embed/lib/paths.ts +70 -0
- package/vendor/server/skeleton/nodes/hello-embed/lib/schema.ts +21 -0
- package/vendor/server/skeleton/nodes/hello-embed/lib/search.ts +254 -0
- package/vendor/server/skeleton/nodes/hello-embed/lib/text-embedder.ts +14 -0
- package/vendor/server/skeleton/nodes/hello-embed/lib/vectors.ts +126 -0
- package/vendor/server/skeleton/nodes/hello-embed/lib/walk-markdown.test.ts +62 -0
- package/vendor/server/skeleton/nodes/hello-embed/lib/walk-markdown.ts +67 -0
- package/vendor/server/skeleton/nodes/hello-embed/package.json +11 -0
- package/vendor/server/skeleton/nodes/hello-embed/search-handle.ts +119 -0
- package/vendor/server/skeleton/nodes/hello-embed/search.ts +98 -0
- package/vendor/server/skeleton/nodes/hello-embed/tsconfig.json +14 -0
- package/vendor/server/skeleton/nodes/my-nodes/README.md +13 -3
- package/vendor/server/skeleton/schemas/langflower-config.schema.json +4 -0
- package/vendor/server/skeleton/skills/langflower-helper/SKILL.md +99 -26
- package/vendor/server/skeleton/skills/langflower-helper/architecture.md +11 -6
- package/vendor/server/skeleton/skills/langflower-helper/layout.md +24 -18
- package/vendor/server/skeleton/skills/langflower-node-writer/SKILL.md +8 -1
- package/vendor/server/skeleton/workflows/kb-ingest.json +88 -0
- package/vendor/server/skeleton/workflows/kb-manual-search.json +105 -0
- package/vendor/server/skeleton/workflows/kb-rag.json +192 -0
- package/vendor/server/skeleton/workflows/kb-tool.json +111 -0
- package/vendor/shared/dist/langflower-bus-config.d.ts +22 -6
- package/vendor/shared/dist/langflower-bus-config.js +23 -7
- package/vendor/shared/dist/langflower-config/merge-langflower-config-layers.test.js +8 -0
- package/vendor/shared/dist/langflower-config/settings-draft.d.ts +5 -0
- package/vendor/shared/dist/langflower-config/settings-draft.js +15 -7
- package/vendor/shared/dist/langflower.d.ts +1 -1
- package/vendor/shared/dist/langflower.js +1 -1
- package/vendor/shared/dist/types/langflower-bootstrap.d.ts +6 -0
- package/vendor/shared/dist/types/langflower-config.d.ts +17 -0
- package/vendor/shared/dist/types/langflower-palette.d.ts +2 -1
- package/vendor/tools/dist/harness-types.d.ts +1 -1
- package/vendor/tools/dist/mcp/build-mcp-handle.d.ts +3 -21
- package/vendor/tools/dist/mcp/build-mcp-handle.js +2 -11
- package/vendor/tools/dist/mcp/create-system-mcp-handles.d.ts +9 -6
- package/vendor/tools/dist/mcp/create-system-mcp-handles.js +21 -17
- package/vendor/tools/package.json +1 -0
- package/ui-dist/chunk-MDGXX73Z.js +0 -4
- package/ui-dist/main-Z7CPFXFA.js +0 -313
- package/ui-dist/styles-2TMDAUD7.css +0 -1
|
@@ -54,11 +54,15 @@ On-demand only (not auto-injected). Use harness `read`:
|
|
|
54
54
|
|
|
55
55
|
### 1. Product
|
|
56
56
|
|
|
57
|
-
- **Can:** Local,
|
|
58
|
-
|
|
59
|
-
ad hoc by the model each turn.
|
|
57
|
+
- **Can:** Local, folder-scoped **reactive node graph**. The LLM is a node,
|
|
58
|
+
not the product. The **workflow graph** is the pipeline law (hard harness)
|
|
59
|
+
— stages and edges are authored, not chosen ad hoc by the model each turn.
|
|
60
|
+
Extend with **MCP** and **skills**, plus **custom nodes** for graph
|
|
61
|
+
processing or custom tools via the same **ToolHandle** contract as built-ins.
|
|
60
62
|
- **Cannot:** Require a cloud account. Let the model skip graph stages
|
|
61
|
-
(QA/review/gates) by “deciding what’s next” outside the graph.
|
|
63
|
+
(QA/review/gates) by “deciding what’s next” outside the graph. Claim
|
|
64
|
+
serializable **chat sessions**, **image/video** asset management for
|
|
65
|
+
multimodal models, or a built-in **IDE / git UI**.
|
|
62
66
|
|
|
63
67
|
### 2. Project layout and bootstrap
|
|
64
68
|
|
|
@@ -67,11 +71,13 @@ templates in the skeleton are **already usable** once copied into the project
|
|
|
67
71
|
do not say coding pipelines “don’t exist” or are unavailable.
|
|
68
72
|
|
|
69
73
|
- **Can:** `langflower start [project-dir]` (default port **4010**) creates
|
|
70
|
-
`.langflower/`, config, `instructions.md`,
|
|
74
|
+
`.langflower/`, config, `instructions.md`, packs `nodes/my-nodes/` and
|
|
75
|
+
`nodes/hello-embed/`, skills
|
|
71
76
|
`langflower-helper`, `langflower-node-writer`, and
|
|
72
77
|
`langflower-workflow-writer`, and opens workflow **`starter`** first.
|
|
73
78
|
- **Can:** Skeleton already ships coding and KB sample workflows
|
|
74
|
-
(`simple-coder`, `advanced-coder`, `kb-create`, `kb-navigate`,
|
|
79
|
+
(`simple-coder`, `advanced-coder`, `kb-create`, `kb-navigate`,
|
|
80
|
+
`kb-ingest`, `kb-manual-search`, `kb-tool`, `kb-rag`, …). With a
|
|
75
81
|
provider configured, they are seeded on first-run → load → composer **Start**.
|
|
76
82
|
- **Can:** Second `langflower start` on an existing `.langflower/` **reuses**
|
|
77
83
|
it as-is (no wipe).
|
|
@@ -88,10 +94,12 @@ do not say coding pipelines “don’t exist” or are unavailable.
|
|
|
88
94
|
### 3. Skeleton and samples
|
|
89
95
|
|
|
90
96
|
- **Can:** First-run seed = config + **all** skeleton workflows (including
|
|
91
|
-
`starter`, coding samples, `kb-create`, `kb-navigate`
|
|
92
|
-
`my-nodes` +
|
|
97
|
+
`starter`, coding samples, `kb-create`, `kb-navigate`, `kb-ingest`,
|
|
98
|
+
`kb-manual-search`, `kb-tool`, `kb-rag`) + three skills + `my-nodes` +
|
|
99
|
+
`hello-embed` + instructions.
|
|
93
100
|
- **Can:** Skeleton inventory includes `node-writer`, `agents-dialog`,
|
|
94
|
-
`simple-coder`, `advanced-coder`, `kb-create`, `kb-navigate
|
|
101
|
+
`simple-coder`, `advanced-coder`, `kb-create`, `kb-navigate`,
|
|
102
|
+
`kb-ingest`, `kb-manual-search`, `kb-tool`, `kb-rag` (and other
|
|
95
103
|
samples under `packages/server/skeleton/` / demo-project).
|
|
96
104
|
- **Cannot:** Claim a Sample workflows **catalog UI** (browse / help /
|
|
97
105
|
one-click copy) is shipped.
|
|
@@ -111,10 +119,36 @@ do not say coding pipelines “don’t exist” or are unavailable.
|
|
|
111
119
|
- **Cannot:** Treat Settings as the selected-node inspector (ports/params).
|
|
112
120
|
- **Cannot:** Reveal a saved API key in the UI.
|
|
113
121
|
|
|
122
|
+
### 4b. Embeddings
|
|
123
|
+
|
|
124
|
+
- **Can:** Settings **Default embedding model** (`embedding: "providerId/modelId"`);
|
|
125
|
+
palette **Embeddings** — `common-embed-text`, `common-embed-similarity`,
|
|
126
|
+
`common-embed-provider`; custom packs wire **`embed`** (`EmbedHandle` from
|
|
127
|
+
`@langflower/node-sdk`); server binds embedding HTTP — packs never see
|
|
128
|
+
`apiKey`. Manual check: String → Embed text → Preview on **`preview`**.
|
|
129
|
+
Sample pack **`hello-embed`**: ingest project `.md` → sqlite (vectors + FTS5);
|
|
130
|
+
hybrid retrieve (cosine + keyword, RRF) packs **Question + full-chunk Context**
|
|
131
|
+
for `hello-embed-search` / `project_search`.
|
|
132
|
+
Workflows `kb-ingest` / `kb-manual-search` / `kb-tool` / `kb-rag`. Needs
|
|
133
|
+
the default embedding model (`langflower start` compiles the pack). Copy
|
|
134
|
+
the pack for a different corpus — see `nodes/hello-embed/README.md`.
|
|
135
|
+
- **Cannot:** Treat embeddings as a host catalog feature. Use **`EmbedHandle`**
|
|
136
|
+
(not `ToolHandle`) for batch float vectors. hello-embed sqlite lives under
|
|
137
|
+
`.langflower/.cache/hello-embed/`.
|
|
138
|
+
|
|
139
|
+
### 4c. Primitives and paced split
|
|
140
|
+
|
|
141
|
+
- **Can:** Palette **Primitives** include String, **String (multiline)**
|
|
142
|
+
(`common-string-multiline`, textarea), Number, Boolean. **Text** includes
|
|
143
|
+
Concat, Read/Write/Append File, and **Split (paced)** (`common-split-paced`)
|
|
144
|
+
— one non-empty chunk per `trigger` (first ASAP; `finish` after the last;
|
|
145
|
+
CSV / logs line-by-line). Not the planned one-shot Split (`parts[]`).
|
|
146
|
+
|
|
114
147
|
### 5. Editor chrome
|
|
115
148
|
|
|
116
149
|
- **Can:** Chat Input graphs start from the composer **Start** control. Plain
|
|
117
|
-
**Run** stays disabled for those graphs.
|
|
150
|
+
**Run** stays disabled for those graphs. Prefill or last typed text lives on
|
|
151
|
+
the Chat Input node (`inputs.message`) and reappears after Stop.
|
|
118
152
|
- **Can:** While running — Hard **Stop**, soft **Pause**, HITL and
|
|
119
153
|
`permission.ask` in the composer. Work log **clears** on successful
|
|
120
154
|
workflow load / create / copy (not rename).
|
|
@@ -123,6 +157,11 @@ do not say coding pipelines “don’t exist” or are unavailable.
|
|
|
123
157
|
drag (`cursor-not-allowed`).
|
|
124
158
|
- **Cannot:** Tell users to press plain **Run** to start a Chat Input graph.
|
|
125
159
|
- **Cannot:** Claim the feed after reload must be **richer** than live.
|
|
160
|
+
- **Can:** Work log shows opted-in roles (`reasoning` / `draft` / `result` /
|
|
161
|
+
tools / `progress`) plus Finish **`done`** and Preview content as result
|
|
162
|
+
bubbles. Unmarked ports and `feed.role: 'none'` are omitted.
|
|
163
|
+
- **Cannot:** Claim unmarked plumbing (`prompt` / `value` wires) appears as
|
|
164
|
+
muted technical rows — use the inspector for those values.
|
|
126
165
|
- **Cannot:** Claim `basic-coder` proves chat-dense mood for the full
|
|
127
166
|
`coding-agent` pipeline.
|
|
128
167
|
|
|
@@ -134,18 +173,43 @@ do not say coding pipelines “don’t exist” or are unavailable.
|
|
|
134
173
|
cleaned graph. Catalog list still shows the file (metadata-only).
|
|
135
174
|
- **Cannot:** Silently rewrite disk on load. Invent port renames — only drop.
|
|
136
175
|
|
|
176
|
+
### 5c. Multi input ports
|
|
177
|
+
|
|
178
|
+
Extra empty handles on a node are **one logical port** authored with `multi`
|
|
179
|
+
(`merge` / `combine` / `zip`). Wiring a slot **grows a trailing empty slot**
|
|
180
|
+
on that same port so you can connect another source. Leave the empty row
|
|
181
|
+
unwired — it is not a duplicate Helper, not a second node, and not a bug.
|
|
182
|
+
|
|
183
|
+
- **Can (starter Helper `feedback`):** `multi: 'merge'` — several sources can
|
|
184
|
+
kick a new agent turn. Example: Review Gate HITL **and** `common-review`
|
|
185
|
+
auto-review.
|
|
186
|
+
- **Can (starter Helper `tools`):** `multi: 'combine'` — several packs land on
|
|
187
|
+
one agent. Example: Langflower Tools **and** Writer Sub-Agent. Optional
|
|
188
|
+
**Tool collection** (`common-tool-collection`) can still merge wires first;
|
|
189
|
+
direct multi-wire still works.
|
|
190
|
+
- **Can (Router):** `common-router` uses the same extra-slot growth for
|
|
191
|
+
channels (`ch` / `ch@1` / …) so many edges stay readable.
|
|
192
|
+
- **Cannot:** Claim every port grows this way — `userPrompt` / `systemPrompt`
|
|
193
|
+
stay single. Claim the empty slot must be wired. Equate `merge` (each emit
|
|
194
|
+
is a turn) with `combine` (inventory array) with `zip` (lockstep, e.g.
|
|
195
|
+
Concat).
|
|
196
|
+
|
|
137
197
|
### 6. Coding workflows
|
|
138
198
|
|
|
139
|
-
| Name
|
|
140
|
-
|
|
|
141
|
-
| `starter`
|
|
142
|
-
| Skeleton stubs
|
|
143
|
-
| `simple-coder`
|
|
144
|
-
| `kb-create`
|
|
145
|
-
| `kb-navigate`
|
|
146
|
-
| `
|
|
147
|
-
| `
|
|
148
|
-
|
|
|
199
|
+
| Name | Fact |
|
|
200
|
+
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
201
|
+
| `starter` | Onboarding chat + this skill + Writer Sub-Agent (`langflower-workflow-writer` + `langflower-node-writer`) — default open after seed |
|
|
202
|
+
| Skeleton stubs | `simple-coder`, `advanced-coder`, `kb-create`, `kb-navigate`, `kb-ingest`, `kb-manual-search`, `kb-tool`, `kb-rag`, … seeded on first-run; with provider → Start |
|
|
203
|
+
| `simple-coder` | Plan⇄HITL→Coder⇄HITL→Finish smoke spine + `common-memory-tools` on Plan/Coder/Researcher/Worker; Researcher Sub-Agent under Plan, Worker under Coder — **not** full multi-loop `coding-agent` |
|
|
204
|
+
| `kb-create` | Memory / project wiki create: Orchestrator **indexes** the repo with `glob`/`read`, persists `history/work-queue.md`, then **serially** calls Explorer → Composer **one unit at a time**; `common-memory-tools` writes `core/*` + `modules/*`; Review rejects non-empty Pending or thin overviews |
|
|
205
|
+
| `kb-navigate` | Memory navigate: Navigator + Searcher + memory tree/grep/section tools; HITL Review Gate for follow-ups |
|
|
206
|
+
| `kb-ingest` | Sample **hello-embed** ingest (Settings embedding model; pack compiles on `langflower start`) |
|
|
207
|
+
| `kb-manual-search` | Sample hello-embed query → Preview / Finish |
|
|
208
|
+
| `kb-tool` | Sample hello-embed `project_search` ToolHandle → agent |
|
|
209
|
+
| `kb-rag` | Simplified RAG: hybrid retrieve packs Question + full chunks into the LLM; `project_search` + grep/read; Review feedback / Approve → Finish |
|
|
210
|
+
| `basic-coder` | Basic coding harness (Plan⇄HITL→Coder⇄HITL→Finish) — not a toy, **not** full multi-loop `coding-agent` |
|
|
211
|
+
| `coding-agent` | Clarify HITL → red team → plan gate → coder → QA → `common-review` → result HITL; **graph** orders stages |
|
|
212
|
+
| Status | Use-case **Partial**; real-LLM Implementable bar open; Fake CI ≠ end-user proof — **not** “no templates” |
|
|
149
213
|
|
|
150
214
|
### 7. Run lifecycle
|
|
151
215
|
|
|
@@ -214,8 +278,9 @@ Sub-Agent is an **explicit canvas node** for **control and observability**
|
|
|
214
278
|
`kb-create` (index with `glob` → `history/work-queue.md` → serial
|
|
215
279
|
Explorer/Composer units into `core/*` + `modules/*`) and `kb-navigate`.
|
|
216
280
|
Managed markdown under `.langflower/memory/` (also reachable with harness
|
|
217
|
-
file tools).
|
|
218
|
-
|
|
281
|
+
file tools). **Embeddings** catalog nodes + Settings default embedding model
|
|
282
|
+
are shipped for API checks and pack **`EmbedHandle`** wiring — separate from
|
|
283
|
+
vector KB ([ADR-033](../../../../../docs/ADR.md#adr-033--markdown-memory-tools-no-embedding-as-base)).
|
|
219
284
|
Obsidian vault helpers are **not** shipped (TBD-007).
|
|
220
285
|
- **skill-refining:** CLI eval + `skillPath` / harness `read`; no canvas
|
|
221
286
|
`skill-refining.json` demo.
|
|
@@ -234,13 +299,15 @@ When the user asks to “create a project wiki”, “build a knowledge base”,
|
|
|
234
299
|
memory **before** deep survey; call the Explorer / Composer specialist
|
|
235
300
|
tools **one unit at a time**.
|
|
236
301
|
- **Cannot:** Recommend one LLM that “reads the whole repo once and dumps a
|
|
237
|
-
wiki”. Claim
|
|
238
|
-
|
|
302
|
+
wiki”. Claim Obsidian vault helpers as shipped. For semantic search over
|
|
303
|
+
markdown, point at **hello-embed** (`kb-ingest` / `kb-rag`) rather than
|
|
304
|
+
inventing catalog embedding-KB nodes.
|
|
239
305
|
|
|
240
306
|
### 11. Custom nodes
|
|
241
307
|
|
|
242
308
|
- **Can:** **TypeScript** via `@langflower/node-sdk` — first-class language;
|
|
243
|
-
`tsc` / IDE types act as compile-time validators.
|
|
309
|
+
`tsc` / IDE types act as compile-time validators. **`langflower start`**
|
|
310
|
+
compiles packs under `.langflower/nodes/`. After file changes call
|
|
244
311
|
**`compile_custom_nodes`** (no args) or Custom → **Update** — same
|
|
245
312
|
composer. On starter you already have the tool (Langflower Tools wired).
|
|
246
313
|
Stop is not required for already-placed custom types (hot-swap).
|
|
@@ -249,6 +316,10 @@ When the user asks to “create a project wiki”, “build a knowledge base”,
|
|
|
249
316
|
auto-place or auto-wire them mid-run.
|
|
250
317
|
Packs under `.langflower/nodes/<pack>/`; user runs `npm install` in the pack
|
|
251
318
|
when adding author deps. See `instructions.md` and `nodes/my-nodes/README.md`.
|
|
319
|
+
Pack `tsconfig.json` gates compile (`tsc --noEmit`). `from './file.ts'`
|
|
320
|
+
requires `"allowImportingTsExtensions": true` next to `"noEmit": true`
|
|
321
|
+
(hello-embed); otherwise the pack does not compile. Extensionless imports
|
|
322
|
+
(`my-nodes`) do not need the flag.
|
|
252
323
|
Nodes may **intentionally keep in-memory internal state across runs**
|
|
253
324
|
(Stop / done / Start) until the user loads another workflow or shuts down
|
|
254
325
|
Langflower — not the same as Checkpoint resume after process kill.
|
|
@@ -265,7 +336,9 @@ When the user asks to add or change a custom node from this starter chat:
|
|
|
265
336
|
1. Call Writer (or edit `.langflower/nodes/<pack>/*.ts` yourself).
|
|
266
337
|
2. Call **`compile_custom_nodes`** (no args). Report `status` / `nodeTypes` /
|
|
267
338
|
`errors` from the tool text. Pack failures also write
|
|
268
|
-
`COMPILATION_ERRORS.md`.
|
|
339
|
+
`COMPILATION_ERRORS.md`. If tsc rejects `.ts` import paths, add
|
|
340
|
+
`allowImportingTsExtensions` next to `noEmit` in the pack `tsconfig.json`
|
|
341
|
+
(copy hello-embed), then compile again.
|
|
269
342
|
3. **Already on the canvas** → live now, no Stop. **New type** → user places
|
|
270
343
|
it from Custom and wires it; this tool does not drop nodes on the canvas.
|
|
271
344
|
4. If a custom tools pack is already wired into this agent, you may call those
|
|
@@ -5,7 +5,8 @@ this file over inventing infrastructure.
|
|
|
5
5
|
|
|
6
6
|
## What it is
|
|
7
7
|
|
|
8
|
-
- Local, **
|
|
8
|
+
- Local, **folder-scoped reactive node graph**. The LLM is a node, not the
|
|
9
|
+
product.
|
|
9
10
|
- The **workflow graph** is the pipeline law (hard harness): stages and edges
|
|
10
11
|
are authored; the model does not freely skip QA/review/gates outside the
|
|
11
12
|
graph.
|
|
@@ -82,7 +83,9 @@ Project product data for Langflower lives under **`.langflower/`**.
|
|
|
82
83
|
the parent work-log visit; the specialist streams as its own card, and
|
|
83
84
|
the parent continues in a new visit below. Optional **Tool collection**
|
|
84
85
|
(`common-tool-collection`) can merge several `tools` wires; direct
|
|
85
|
-
multi-wire into the agent still works.
|
|
86
|
+
multi-wire into the agent still works. Extra empty canvas slots on
|
|
87
|
+
`multi` ports (`feedback` merge, `tools` combine) and Router channels
|
|
88
|
+
(`ch` / `ch@1`) are intentional fan-in — not cloned ports.
|
|
86
89
|
- **Graph order** stages the pipeline; the model does not invent the stage
|
|
87
90
|
sequence outside the graph.
|
|
88
91
|
- Project memory / wiki create is **queue-driven**: index with harness `glob`,
|
|
@@ -94,10 +97,12 @@ Project product data for Langflower lives under **`.langflower/`**.
|
|
|
94
97
|
|
|
95
98
|
- Custom nodes use the same **`@langflower/node-sdk`** path as built-ins.
|
|
96
99
|
- **TypeScript** is first-class; `tsc` / IDE types act as compile-time gates.
|
|
97
|
-
After file changes call
|
|
98
|
-
Tools** is wired — starter
|
|
99
|
-
|
|
100
|
-
instances + refresh the Custom
|
|
100
|
+
`langflower start` compiles packs. After file changes call
|
|
101
|
+
`compile_custom_nodes` (only if **Langflower Tools** is wired — starter
|
|
102
|
+
Helper / Writer already are) or Custom → **Update**. Same composer:
|
|
103
|
+
typecheck + bundle + hot-swap live custom instances + refresh the Custom
|
|
104
|
+
palette. Pack `from './x.ts'` needs `allowImportingTsExtensions` +
|
|
105
|
+
`noEmit` in pack `tsconfig.json` or `tsc --noEmit` fails (hello-embed seed).
|
|
101
106
|
Stop is not required for already-placed custom types.
|
|
102
107
|
An already-wired custom tools pack can be invoked later in the same run
|
|
103
108
|
after compile. Do not auto-place or auto-wire a new type mid-run.
|
|
@@ -7,7 +7,10 @@ Facts for UI chrome and on-disk paths. Prefer this file over guessing.
|
|
|
7
7
|
- **Topbar** — workflow list (switch / create / rename as shipped), gear →
|
|
8
8
|
**Settings**.
|
|
9
9
|
- **Left palette** — built-in nodes; **Custom** packs; **Update** reloads
|
|
10
|
-
custom packs after disk changes.
|
|
10
|
+
custom packs after disk changes. Collapse with `<<` on the Palette title
|
|
11
|
+
row; restore with floating `>>` at the canvas top-left. Visibility is
|
|
12
|
+
project `paletteVisible` (missing key = shown) and is allowed during a
|
|
13
|
+
run.
|
|
11
14
|
- **Center** — canvas (nodes, edges, selection).
|
|
12
15
|
- **Right aside** — mutually exclusive modes: **feed** | **inspector** |
|
|
13
16
|
**Settings**. Opening Settings (gear or empty-provider onboarding) swaps out
|
|
@@ -17,22 +20,25 @@ Facts for UI chrome and on-disk paths. Prefer this file over guessing.
|
|
|
17
20
|
|
|
18
21
|
## Where can I…?
|
|
19
22
|
|
|
20
|
-
| Goal
|
|
21
|
-
|
|
|
22
|
-
| Change provider / API key
|
|
23
|
-
| Start a Chat Input graph
|
|
24
|
-
| See run output / stream
|
|
25
|
-
| Answer HITL / send into a waiting node
|
|
26
|
-
| Allow or Deny `permission.ask`
|
|
27
|
-
| Soft-pause last feed agent / continue
|
|
28
|
-
| Hard-stop a run
|
|
29
|
-
| Edit selected node params / ports
|
|
30
|
-
|
|
|
31
|
-
| Add
|
|
32
|
-
|
|
|
33
|
-
|
|
|
34
|
-
|
|
|
35
|
-
|
|
|
23
|
+
| Goal | Where |
|
|
24
|
+
| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
25
|
+
| Change provider / API key | Gear → **Settings** (right aside; Global auto-opens when none configured), or edit `.langflower/langflower.jsonc` (prefer `{env:VAR}`) |
|
|
26
|
+
| Start a Chat Input graph | Composer **Start** — not plain **Run**. Prefill lives on the node; Stop then Start reuses it. |
|
|
27
|
+
| See run output / stream | Right aside **feed** |
|
|
28
|
+
| Answer HITL / send into a waiting node | Composer + feed context |
|
|
29
|
+
| Allow or Deny `permission.ask` | Composer permission controls |
|
|
30
|
+
| Soft-pause last feed agent / continue | Composer **Pause** (per-node) / Send or Resume (soft pause ≠ Hard Stop) |
|
|
31
|
+
| Hard-stop a run | Composer **Stop** |
|
|
32
|
+
| Edit selected node params / ports | Select node → right aside **inspector** (not Settings). Read-only while a run is active — Stop first. |
|
|
33
|
+
| See what a built-in node does | Hover a palette row (popover) **or** select the node → inspector **description** (markdown). |
|
|
34
|
+
| Add a node from the palette | Drag from the left palette onto the canvas. Disabled while a run is active (`cursor-not-allowed`) — Stop first. |
|
|
35
|
+
| Hide / show the node palette | Palette title `<<` / canvas `>>`. Shared across tabs; stored as `paletteVisible` in project `langflower.jsonc`. Allowed during a run. |
|
|
36
|
+
| Add or reload custom nodes | Pack under `.langflower/nodes/<pack>/`. Server start compiles existing packs. After file changes: on starter, Helper / Writer call `compile_custom_nodes` (Langflower Tools is wired). Else Custom → **Update**. Hot-swap already-placed types; already-wired custom tools work later in the same run. New types: user places from Custom (no auto-place / auto-wire mid-run). |
|
|
37
|
+
| Switch workflow | Topbar workflow list. Load / New / Copy / rename / Delete are locked while a run is active — Stop first. |
|
|
38
|
+
| Open Settings without leaving canvas | Gear — Settings in right aside |
|
|
39
|
+
| Find sample coding graphs | Skeleton / demo-project workflow files — **manual copy** into project, then load → Start. No Sample workflows catalog UI. |
|
|
40
|
+
| Why extra empty ports on Helper / tools / Router | Those inputs are `multi`. Wiring one slot shows the next free slot. **Feedback** = several sources (HITL + auto-review). **Tools** = several packs. **Router** = extra channels (`ch` / `ch@1`). Leave the empty row unwired. |
|
|
41
|
+
| Project instructions for agents | `.langflower/instructions.md` |
|
|
36
42
|
|
|
37
43
|
## On-disk `.langflower/` map
|
|
38
44
|
|
|
@@ -41,7 +47,7 @@ Facts for UI chrome and on-disk paths. Prefer this file over guessing.
|
|
|
41
47
|
| `langflower.jsonc` | Providers, secrets refs, project config |
|
|
42
48
|
| `workflows/` | Saved workflow graphs |
|
|
43
49
|
| `skills/` | Agent skills (`langflower-helper/`, `langflower-node-writer/`, `langflower-workflow-writer/`) |
|
|
44
|
-
| `nodes/` | Custom node packs (
|
|
50
|
+
| `nodes/` | Custom node packs (`my-nodes/`, sample `hello-embed/`) |
|
|
45
51
|
| `instructions.md` | Project-level agent instructions |
|
|
46
52
|
| `runs/` | Run artifacts / checkpoints when created |
|
|
47
53
|
| `logs/` | Server bridge diagnostic JSONL logs when the server runs |
|
|
@@ -20,6 +20,10 @@ You help the user write **custom nodes** for Langflower.
|
|
|
20
20
|
starter, Writer has it because **Langflower Tools** is wired. Custom →
|
|
21
21
|
**Update** is the same composer. Failures land in `COMPILATION_ERRORS.md`.
|
|
22
22
|
Do **not** only remind the user to click Update.
|
|
23
|
+
- Pack `tsconfig.json` is the `tsc --noEmit` gate. `from './lib/x.ts'`
|
|
24
|
+
requires `"allowImportingTsExtensions": true` next to `"noEmit": true`
|
|
25
|
+
(copy `hello-embed/tsconfig.json`). Without it the pack does not compile.
|
|
26
|
+
Extensionless imports (`my-nodes`) do not need the flag.
|
|
23
27
|
- Langflower does **not** auto-`npm install` pack dependencies.
|
|
24
28
|
- Do **not** claim you can place a newly compiled type on the canvas or wire
|
|
25
29
|
it mid-run. Already-placed types hot-swap; already-wired custom tools can
|
|
@@ -28,7 +32,8 @@ You help the user write **custom nodes** for Langflower.
|
|
|
28
32
|
## Contract (do not invent forks)
|
|
29
33
|
|
|
30
34
|
- Default pack: `.langflower/nodes/my-nodes/` (one folder = one `package.json`).
|
|
31
|
-
- Prefer **`defineNode`** for sync/Promise nodes
|
|
35
|
+
- Prefer **`defineNode`** for sync/Promise nodes (`execute` stamps pending
|
|
36
|
+
on outputs). Use
|
|
32
37
|
**`defineToolRegistrations`** for LLM-callable `ToolHandle` packs on a
|
|
33
38
|
`tools` port. Use **`defineReactiveNode`** only when exclusive multi-output
|
|
34
39
|
branches, streams, or advanced bind wiring are required.
|
|
@@ -64,3 +69,5 @@ You help the user write **custom nodes** for Langflower.
|
|
|
64
69
|
- `.langflower/nodes/my-nodes/README.md`
|
|
65
70
|
- Seed demos: `git-diff.ts` (`defineNode`), `git-diff-tool.ts`
|
|
66
71
|
(`defineToolRegistrations`), `review-gate.ts` (`defineReactiveNode`)
|
|
72
|
+
- Multi-file + `.ts` imports: `.langflower/nodes/hello-embed/` (`tsconfig.json`
|
|
73
|
+
already has `allowImportingTsExtensions`)
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "../schemas/workflow.schema.json",
|
|
3
|
+
"metadata": {
|
|
4
|
+
"name": "KB ingest",
|
|
5
|
+
"description": "Sample embedding ingest: set Settings default embedding model, then Run. common-embed-provider fans out embed into hello-embed-ingest. Progress streams in the feed; finish stops the run.",
|
|
6
|
+
"createdAt": "2026-08-26T00:00:00.000Z",
|
|
7
|
+
"updatedAt": "2026-08-26T00:00:00.000Z"
|
|
8
|
+
},
|
|
9
|
+
"graph": {
|
|
10
|
+
"viewport": {
|
|
11
|
+
"x": 0,
|
|
12
|
+
"y": 0,
|
|
13
|
+
"scale": 1,
|
|
14
|
+
"width": 1100,
|
|
15
|
+
"height": 700
|
|
16
|
+
},
|
|
17
|
+
"nodes": [
|
|
18
|
+
{
|
|
19
|
+
"id": "trigger",
|
|
20
|
+
"type": "common-boolean",
|
|
21
|
+
"params": {},
|
|
22
|
+
"inputs": {
|
|
23
|
+
"value": true
|
|
24
|
+
},
|
|
25
|
+
"ui": {
|
|
26
|
+
"position": { "x": 40, "y": 160 },
|
|
27
|
+
"label": "Start"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"id": "embed-provider",
|
|
32
|
+
"type": "common-embed-provider",
|
|
33
|
+
"params": {
|
|
34
|
+
"providerId": "",
|
|
35
|
+
"model": ""
|
|
36
|
+
},
|
|
37
|
+
"inputs": {},
|
|
38
|
+
"ui": {
|
|
39
|
+
"position": { "x": 40, "y": 320 },
|
|
40
|
+
"label": "Embed provider"
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"id": "ingest",
|
|
45
|
+
"type": "hello-embed-ingest",
|
|
46
|
+
"params": {},
|
|
47
|
+
"inputs": {},
|
|
48
|
+
"ui": {
|
|
49
|
+
"position": { "x": 320, "y": 200 },
|
|
50
|
+
"label": "Ingest"
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"id": "done",
|
|
55
|
+
"type": "common-finish",
|
|
56
|
+
"params": {},
|
|
57
|
+
"inputs": {},
|
|
58
|
+
"ui": {
|
|
59
|
+
"position": { "x": 620, "y": 200 },
|
|
60
|
+
"label": "Finish"
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
],
|
|
64
|
+
"edges": [
|
|
65
|
+
{
|
|
66
|
+
"edgeId": "e-trigger-ingest",
|
|
67
|
+
"fromNodeId": "trigger",
|
|
68
|
+
"fromPort": ["value", 0],
|
|
69
|
+
"toNodeId": "ingest",
|
|
70
|
+
"toPort": ["trigger", 0]
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"edgeId": "e-embed-ingest",
|
|
74
|
+
"fromNodeId": "embed-provider",
|
|
75
|
+
"fromPort": ["embed", 0],
|
|
76
|
+
"toNodeId": "ingest",
|
|
77
|
+
"toPort": ["embed", 0]
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"edgeId": "e-ingest-done",
|
|
81
|
+
"fromNodeId": "ingest",
|
|
82
|
+
"fromPort": ["finish", 0],
|
|
83
|
+
"toNodeId": "done",
|
|
84
|
+
"toPort": ["value", 0]
|
|
85
|
+
}
|
|
86
|
+
]
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "../schemas/workflow.schema.json",
|
|
3
|
+
"metadata": {
|
|
4
|
+
"name": "KB manual search",
|
|
5
|
+
"description": "Sample embedding search: run KB ingest first, set Settings default embedding model. Edit the Query string and Run. Hits preview as text; JSON hits stop the run.",
|
|
6
|
+
"createdAt": "2026-08-26T00:00:00.000Z",
|
|
7
|
+
"updatedAt": "2026-08-26T00:00:00.000Z"
|
|
8
|
+
},
|
|
9
|
+
"graph": {
|
|
10
|
+
"viewport": {
|
|
11
|
+
"x": 0,
|
|
12
|
+
"y": 0,
|
|
13
|
+
"scale": 1,
|
|
14
|
+
"width": 1200,
|
|
15
|
+
"height": 700
|
|
16
|
+
},
|
|
17
|
+
"nodes": [
|
|
18
|
+
{
|
|
19
|
+
"id": "query",
|
|
20
|
+
"type": "common-string",
|
|
21
|
+
"params": {},
|
|
22
|
+
"inputs": {
|
|
23
|
+
"value": "project layout"
|
|
24
|
+
},
|
|
25
|
+
"ui": {
|
|
26
|
+
"position": { "x": 40, "y": 160 },
|
|
27
|
+
"label": "Query"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"id": "embed-provider",
|
|
32
|
+
"type": "common-embed-provider",
|
|
33
|
+
"params": {
|
|
34
|
+
"providerId": "",
|
|
35
|
+
"model": ""
|
|
36
|
+
},
|
|
37
|
+
"inputs": {},
|
|
38
|
+
"ui": {
|
|
39
|
+
"position": { "x": 40, "y": 320 },
|
|
40
|
+
"label": "Embed provider"
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"id": "search",
|
|
45
|
+
"type": "hello-embed-search",
|
|
46
|
+
"params": {},
|
|
47
|
+
"inputs": {},
|
|
48
|
+
"ui": {
|
|
49
|
+
"position": { "x": 320, "y": 200 },
|
|
50
|
+
"label": "Search"
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"id": "preview",
|
|
55
|
+
"type": "common-preview",
|
|
56
|
+
"params": {},
|
|
57
|
+
"inputs": {},
|
|
58
|
+
"ui": {
|
|
59
|
+
"position": { "x": 620, "y": 80 },
|
|
60
|
+
"label": "Preview"
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"id": "done",
|
|
65
|
+
"type": "common-finish",
|
|
66
|
+
"params": {},
|
|
67
|
+
"inputs": {},
|
|
68
|
+
"ui": {
|
|
69
|
+
"position": { "x": 620, "y": 320 },
|
|
70
|
+
"label": "Finish"
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
],
|
|
74
|
+
"edges": [
|
|
75
|
+
{
|
|
76
|
+
"edgeId": "e-query-search",
|
|
77
|
+
"fromNodeId": "query",
|
|
78
|
+
"fromPort": ["value", 0],
|
|
79
|
+
"toNodeId": "search",
|
|
80
|
+
"toPort": ["query", 0]
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"edgeId": "e-embed-search",
|
|
84
|
+
"fromNodeId": "embed-provider",
|
|
85
|
+
"fromPort": ["embed", 0],
|
|
86
|
+
"toNodeId": "search",
|
|
87
|
+
"toPort": ["embed", 0]
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"edgeId": "e-search-preview",
|
|
91
|
+
"fromNodeId": "search",
|
|
92
|
+
"fromPort": ["text", 0],
|
|
93
|
+
"toNodeId": "preview",
|
|
94
|
+
"toPort": ["text", 0]
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"edgeId": "e-search-done",
|
|
98
|
+
"fromNodeId": "search",
|
|
99
|
+
"fromPort": ["hits", 0],
|
|
100
|
+
"toNodeId": "done",
|
|
101
|
+
"toPort": ["value", 0]
|
|
102
|
+
}
|
|
103
|
+
]
|
|
104
|
+
}
|
|
105
|
+
}
|