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.
Files changed (159) hide show
  1. package/README.md +96 -70
  2. package/docs/public/README.md +2 -2
  3. package/docs/public/configuration.md +4 -0
  4. package/docs/public/extending.md +18 -2
  5. package/docs/public/getting-started.md +7 -0
  6. package/docs/public/how-it-works.md +18 -11
  7. package/docs/public/product.md +35 -25
  8. package/package.json +1 -1
  9. package/ui-dist/chunk-QI4IYILJ.js +4 -0
  10. package/ui-dist/{chunk-7UMVYN3A.js → chunk-UG3GFV4Y.js} +1 -1
  11. package/ui-dist/index.html +2 -2
  12. package/ui-dist/main-ODIDCCNX.js +315 -0
  13. package/ui-dist/styles-2JMBAQC3.css +1 -0
  14. package/vendor/common-nodes/dist/ai/features/llm-session/llm-session-shell.d.ts +2 -2
  15. package/vendor/common-nodes/dist/ai/features/llm-session/llm-session-shell.js +39 -7
  16. package/vendor/common-nodes/dist/ai/features/llm-session/run-session-machine.d.ts +11 -0
  17. package/vendor/common-nodes/dist/ai/features/llm-session/run-session-machine.js +2 -2
  18. package/vendor/common-nodes/dist/ai/features/run-host-services.d.ts +10 -0
  19. package/vendor/common-nodes/dist/ai/nodes/critique/node.js +5 -1
  20. package/vendor/common-nodes/dist/ai/nodes/fake-llm/node.js +7 -1
  21. package/vendor/common-nodes/dist/ai/nodes/openai-llm/node.js +5 -1
  22. package/vendor/common-nodes/dist/ai/nodes/review/node.js +7 -1
  23. package/vendor/common-nodes/dist/ai/nodes/sub-agent/node.js +62 -22
  24. package/vendor/common-nodes/dist/catalog.js +10 -0
  25. package/vendor/common-nodes/dist/crawl/crawl/node.js +11 -3
  26. package/vendor/common-nodes/dist/crawl/crawl-tools/node.js +5 -1
  27. package/vendor/common-nodes/dist/crawl/extract-links/node.js +7 -1
  28. package/vendor/common-nodes/dist/crawl/fetch-url/node.js +13 -4
  29. package/vendor/common-nodes/dist/crawl/save-page/node.js +11 -3
  30. package/vendor/common-nodes/dist/embeddings/create-embedding.d.ts +39 -0
  31. package/vendor/common-nodes/dist/embeddings/create-embedding.js +154 -0
  32. package/vendor/common-nodes/dist/embeddings/embed-provider/node.d.ts +53 -0
  33. package/vendor/common-nodes/dist/embeddings/embed-provider/node.js +126 -0
  34. package/vendor/common-nodes/dist/embeddings/embed-similarity/node.d.ts +20 -0
  35. package/vendor/common-nodes/dist/embeddings/embed-similarity/node.js +81 -0
  36. package/vendor/common-nodes/dist/embeddings/embed-text/node.d.ts +53 -0
  37. package/vendor/common-nodes/dist/embeddings/embed-text/node.js +91 -0
  38. package/vendor/common-nodes/dist/embeddings/from-embedding.d.ts +8 -0
  39. package/vendor/common-nodes/dist/embeddings/from-embedding.js +24 -0
  40. package/vendor/common-nodes/dist/embeddings/resolve-embedding-provider-model.d.ts +11 -0
  41. package/vendor/common-nodes/dist/embeddings/resolve-embedding-provider-model.js +8 -0
  42. package/vendor/common-nodes/dist/flow/checkpoint/node.js +7 -3
  43. package/vendor/common-nodes/dist/flow/delay/node.d.ts +2 -6
  44. package/vendor/common-nodes/dist/flow/delay/node.js +13 -9
  45. package/vendor/common-nodes/dist/flow/loop/node.js +7 -1
  46. package/vendor/common-nodes/dist/flow/merge/node.js +7 -1
  47. package/vendor/common-nodes/dist/flow/repeat/node.js +5 -1
  48. package/vendor/common-nodes/dist/flow/router/node.js +7 -1
  49. package/vendor/common-nodes/dist/hitl/chat-input/node.d.ts +2 -2
  50. package/vendor/common-nodes/dist/hitl/chat-input/node.js +8 -4
  51. package/vendor/common-nodes/dist/hitl/review-gate/node.js +11 -5
  52. package/vendor/common-nodes/dist/langflower-tools/node.js +5 -1
  53. package/vendor/common-nodes/dist/logic/assert/node.js +7 -1
  54. package/vendor/common-nodes/dist/logic/compare/node.js +7 -1
  55. package/vendor/common-nodes/dist/logic/gate/node.js +7 -1
  56. package/vendor/common-nodes/dist/logic/if/node.js +7 -1
  57. package/vendor/common-nodes/dist/logic/switch/node.js +7 -1
  58. package/vendor/common-nodes/dist/mcp/mcp-http/node.js +55 -53
  59. package/vendor/common-nodes/dist/mcp/mcp-stdio/node.js +52 -50
  60. package/vendor/common-nodes/dist/memory/memory-tools/node.js +5 -1
  61. package/vendor/common-nodes/dist/output/finish/node.js +13 -1
  62. package/vendor/common-nodes/dist/output/preview/node.js +9 -2
  63. package/vendor/common-nodes/dist/primitives/boolean/node.js +7 -1
  64. package/vendor/common-nodes/dist/primitives/number/node.js +7 -1
  65. package/vendor/common-nodes/dist/primitives/string/node.js +7 -1
  66. package/vendor/common-nodes/dist/primitives/string-multiline/node.d.ts +17 -0
  67. package/vendor/common-nodes/dist/primitives/string-multiline/node.js +31 -0
  68. package/vendor/common-nodes/dist/text/append-file/node.js +11 -3
  69. package/vendor/common-nodes/dist/text/concat/node.js +5 -1
  70. package/vendor/common-nodes/dist/text/read-file/node.js +9 -3
  71. package/vendor/common-nodes/dist/text/split-paced/node.d.ts +21 -0
  72. package/vendor/common-nodes/dist/text/split-paced/node.js +93 -0
  73. package/vendor/common-nodes/dist/text/write-file/node.js +11 -3
  74. package/vendor/common-nodes/dist/tools/tool-collection/node.js +5 -2
  75. package/vendor/common-nodes/package.json +4 -0
  76. package/vendor/node-sdk/dist/node-factory/define-embed/embed-handle.d.ts +25 -0
  77. package/vendor/node-sdk/dist/node-factory/define-embed/embed-handle.js +25 -0
  78. package/vendor/node-sdk/dist/node-factory/define-mcp/mcp-handle.d.ts +1 -0
  79. package/vendor/node-sdk/dist/node-factory/define-mcp/mcp-handle.js +1 -0
  80. package/vendor/node-sdk/dist/node-factory/define-node/define-node.d.ts +2 -0
  81. package/vendor/node-sdk/dist/node-factory/define-node/define-node.js +4 -1
  82. package/vendor/node-sdk/dist/node-factory/define-reactive-node/define-reactive-node.d.ts +3 -1
  83. package/vendor/node-sdk/dist/node-factory/define-reactive-node/define-reactive-node.js +2 -1
  84. package/vendor/node-sdk/dist/node-factory/define-reactive-node/io-helpers.d.ts +15 -0
  85. package/vendor/node-sdk/dist/node-factory/define-reactive-node/io-helpers.js +17 -1
  86. package/vendor/node-sdk/dist/node-factory/define-reactive-node/port-meta.d.ts +17 -4
  87. package/vendor/node-sdk/dist/node-factory/define-reactive-node/test/samples/delay-node.js +4 -2
  88. package/vendor/node-sdk/dist/node-factory/define-reactive-node/types.d.ts +4 -3
  89. package/vendor/node-sdk/dist/testing/create-node-harness.d.ts +30 -0
  90. package/vendor/node-sdk/dist/testing/create-node-harness.js +68 -0
  91. package/vendor/node-sdk/package.json +4 -4
  92. package/vendor/runtime/dist/types.d.ts +1 -1
  93. package/vendor/server/dist/bootstrap/project-bootstrap.service.d.ts +1 -1
  94. package/vendor/server/dist/bootstrap/seed-skeleton.d.ts +2 -2
  95. package/vendor/server/dist/bootstrap/seed-skeleton.js +17 -2
  96. package/vendor/server/dist/bridge/bind-embed-context.d.ts +7 -0
  97. package/vendor/server/dist/bridge/bind-embed-context.js +16 -0
  98. package/vendor/server/dist/bridge/build-execution-context.d.ts +2 -2
  99. package/vendor/server/dist/bridge/build-execution-context.js +6 -2
  100. package/vendor/server/dist/bridge/emit-bootstrap.js +4 -1
  101. package/vendor/server/dist/bridge/settings-draft-controller.js +7 -3
  102. package/vendor/server/dist/bridge/wire-config-handlers.js +2 -0
  103. package/vendor/server/dist/bridge/wire-editor-handlers.js +14 -0
  104. package/vendor/server/dist/config/langflower-config.service.d.ts +2 -0
  105. package/vendor/server/dist/config/langflower-config.service.js +30 -0
  106. package/vendor/server/dist/session/build-session-bootstrap.js +1 -0
  107. package/vendor/server/dist/session/langflower-session.d.ts +3 -1
  108. package/vendor/server/dist/session/langflower-session.js +3 -1
  109. package/vendor/server/dist/workflow/apply-editor-mutation.js +6 -0
  110. package/vendor/server/dist/workflow/workflow-persisted-inputs.js +8 -6
  111. package/vendor/server/skeleton/instructions.md +15 -3
  112. package/vendor/server/skeleton/nodes/hello-embed/README.md +185 -0
  113. package/vendor/server/skeleton/nodes/hello-embed/hello-embed.nodes.test.ts +181 -0
  114. package/vendor/server/skeleton/nodes/hello-embed/ingest.ts +126 -0
  115. package/vendor/server/skeleton/nodes/hello-embed/lib/chunk-markdown.test.ts +40 -0
  116. package/vendor/server/skeleton/nodes/hello-embed/lib/chunk-markdown.ts +123 -0
  117. package/vendor/server/skeleton/nodes/hello-embed/lib/ingest-search.test.ts +180 -0
  118. package/vendor/server/skeleton/nodes/hello-embed/lib/ingest.ts +128 -0
  119. package/vendor/server/skeleton/nodes/hello-embed/lib/paths.test.ts +20 -0
  120. package/vendor/server/skeleton/nodes/hello-embed/lib/paths.ts +70 -0
  121. package/vendor/server/skeleton/nodes/hello-embed/lib/schema.ts +21 -0
  122. package/vendor/server/skeleton/nodes/hello-embed/lib/search.ts +254 -0
  123. package/vendor/server/skeleton/nodes/hello-embed/lib/text-embedder.ts +14 -0
  124. package/vendor/server/skeleton/nodes/hello-embed/lib/vectors.ts +126 -0
  125. package/vendor/server/skeleton/nodes/hello-embed/lib/walk-markdown.test.ts +62 -0
  126. package/vendor/server/skeleton/nodes/hello-embed/lib/walk-markdown.ts +67 -0
  127. package/vendor/server/skeleton/nodes/hello-embed/package.json +11 -0
  128. package/vendor/server/skeleton/nodes/hello-embed/search-handle.ts +119 -0
  129. package/vendor/server/skeleton/nodes/hello-embed/search.ts +98 -0
  130. package/vendor/server/skeleton/nodes/hello-embed/tsconfig.json +14 -0
  131. package/vendor/server/skeleton/nodes/my-nodes/README.md +13 -3
  132. package/vendor/server/skeleton/schemas/langflower-config.schema.json +4 -0
  133. package/vendor/server/skeleton/skills/langflower-helper/SKILL.md +99 -26
  134. package/vendor/server/skeleton/skills/langflower-helper/architecture.md +11 -6
  135. package/vendor/server/skeleton/skills/langflower-helper/layout.md +24 -18
  136. package/vendor/server/skeleton/skills/langflower-node-writer/SKILL.md +8 -1
  137. package/vendor/server/skeleton/workflows/kb-ingest.json +88 -0
  138. package/vendor/server/skeleton/workflows/kb-manual-search.json +105 -0
  139. package/vendor/server/skeleton/workflows/kb-rag.json +192 -0
  140. package/vendor/server/skeleton/workflows/kb-tool.json +111 -0
  141. package/vendor/shared/dist/langflower-bus-config.d.ts +22 -6
  142. package/vendor/shared/dist/langflower-bus-config.js +23 -7
  143. package/vendor/shared/dist/langflower-config/merge-langflower-config-layers.test.js +8 -0
  144. package/vendor/shared/dist/langflower-config/settings-draft.d.ts +5 -0
  145. package/vendor/shared/dist/langflower-config/settings-draft.js +15 -7
  146. package/vendor/shared/dist/langflower.d.ts +1 -1
  147. package/vendor/shared/dist/langflower.js +1 -1
  148. package/vendor/shared/dist/types/langflower-bootstrap.d.ts +6 -0
  149. package/vendor/shared/dist/types/langflower-config.d.ts +17 -0
  150. package/vendor/shared/dist/types/langflower-palette.d.ts +2 -1
  151. package/vendor/tools/dist/harness-types.d.ts +1 -1
  152. package/vendor/tools/dist/mcp/build-mcp-handle.d.ts +3 -21
  153. package/vendor/tools/dist/mcp/build-mcp-handle.js +2 -11
  154. package/vendor/tools/dist/mcp/create-system-mcp-handles.d.ts +9 -6
  155. package/vendor/tools/dist/mcp/create-system-mcp-handles.js +21 -17
  156. package/vendor/tools/package.json +1 -0
  157. package/ui-dist/chunk-MDGXX73Z.js +0 -4
  158. package/ui-dist/main-Z7CPFXFA.js +0 -313
  159. package/ui-dist/styles-2TMDAUD7.css +0 -1
@@ -0,0 +1,192 @@
1
+ {
2
+ "$schema": "../schemas/workflow.schema.json",
3
+ "metadata": {
4
+ "name": "KB RAG",
5
+ "description": "Simplified RAG: run KB ingest first, set Settings default embedding model. Chat Start. Hybrid retrieve packs Question + full-chunk Context into the LLM userPrompt. project_search is a second retrieve; grep/read open hit paths. Review feedback loops; Approve stops the run.",
6
+ "createdAt": "2026-08-26T00:00:00.000Z",
7
+ "updatedAt": "2026-08-26T20:30:34.296Z"
8
+ },
9
+ "graph": {
10
+ "viewport": {
11
+ "x": 77.33349609375,
12
+ "y": 180.26641845703125,
13
+ "scale": 0.85,
14
+ "width": 672.71875,
15
+ "height": 1005.328125
16
+ },
17
+ "nodes": [
18
+ {
19
+ "id": "chat",
20
+ "type": "common-chat-input",
21
+ "params": {},
22
+ "inputs": {
23
+ "message": "project overview"
24
+ },
25
+ "ui": {
26
+ "position": {
27
+ "x": 120,
28
+ "y": 200
29
+ },
30
+ "label": "Ask"
31
+ }
32
+ },
33
+ {
34
+ "id": "embed-provider",
35
+ "type": "common-embed-provider",
36
+ "params": {
37
+ "providerId": "",
38
+ "model": ""
39
+ },
40
+ "inputs": {},
41
+ "ui": {
42
+ "position": {
43
+ "x": 80,
44
+ "y": 540
45
+ },
46
+ "label": "Embed provider"
47
+ }
48
+ },
49
+ {
50
+ "id": "search",
51
+ "type": "hello-embed-search",
52
+ "params": {},
53
+ "inputs": {},
54
+ "ui": {
55
+ "position": {
56
+ "x": 400,
57
+ "y": 340
58
+ },
59
+ "label": "Vector search"
60
+ }
61
+ },
62
+ {
63
+ "id": "search-handle",
64
+ "type": "hello-embed-search-handle",
65
+ "params": {},
66
+ "inputs": {},
67
+ "ui": {
68
+ "position": {
69
+ "x": 360,
70
+ "y": 600
71
+ },
72
+ "label": "Project search"
73
+ }
74
+ },
75
+ {
76
+ "id": "agent",
77
+ "type": "common-openai-llm",
78
+ "params": {
79
+ "rolePreset": "custom",
80
+ "providerId": "",
81
+ "model": "",
82
+ "maxIterations": 8,
83
+ "maxFeedbackTurns": 4,
84
+ "toolPermissions": {
85
+ "read": "allow",
86
+ "glob": "allow",
87
+ "grep": "allow",
88
+ "edit": "deny",
89
+ "write": "deny",
90
+ "create": "deny",
91
+ "delete": "deny",
92
+ "bash": "deny"
93
+ }
94
+ },
95
+ "inputs": {
96
+ "systemPrompt": "The user message is Question plus Context: hybrid-retrieved markdown chunks (full bodies, path, heading, score). Answer from Context. Cite path and heading. Call project_search, grep, or read only when Context is missing the detail. If hits are missing or weak, retrieve again rather than inventing. On HITL feedback, search or grep again if needed and revise."
97
+ },
98
+ "ui": {
99
+ "position": {
100
+ "x": 620,
101
+ "y": 180
102
+ },
103
+ "label": "Agent"
104
+ }
105
+ },
106
+ {
107
+ "id": "review",
108
+ "type": "common-hitl-review-gate",
109
+ "params": {},
110
+ "inputs": {},
111
+ "ui": {
112
+ "position": {
113
+ "x": 880,
114
+ "y": 520
115
+ },
116
+ "label": "Review"
117
+ }
118
+ },
119
+ {
120
+ "id": "done",
121
+ "type": "common-finish",
122
+ "params": {},
123
+ "inputs": {},
124
+ "ui": {
125
+ "position": {
126
+ "x": 1100,
127
+ "y": 560
128
+ },
129
+ "label": "Finish"
130
+ }
131
+ }
132
+ ],
133
+ "edges": [
134
+ {
135
+ "edgeId": "e-chat-search",
136
+ "fromNodeId": "chat",
137
+ "fromPort": ["message", 0],
138
+ "toNodeId": "search",
139
+ "toPort": ["query", 0]
140
+ },
141
+ {
142
+ "edgeId": "e-embed-search",
143
+ "fromNodeId": "embed-provider",
144
+ "fromPort": ["embed", 0],
145
+ "toNodeId": "search",
146
+ "toPort": ["embed", 0]
147
+ },
148
+ {
149
+ "edgeId": "e-embed-handle",
150
+ "fromNodeId": "embed-provider",
151
+ "fromPort": ["embed", 0],
152
+ "toNodeId": "search-handle",
153
+ "toPort": ["embed", 0]
154
+ },
155
+ {
156
+ "edgeId": "e-search-agent",
157
+ "fromNodeId": "search",
158
+ "fromPort": ["text", 0],
159
+ "toNodeId": "agent",
160
+ "toPort": ["userPrompt", 0]
161
+ },
162
+ {
163
+ "edgeId": "e-tools-agent",
164
+ "fromNodeId": "search-handle",
165
+ "fromPort": ["tools", 0],
166
+ "toNodeId": "agent",
167
+ "toPort": ["tools", 0]
168
+ },
169
+ {
170
+ "edgeId": "e-agent-review",
171
+ "fromNodeId": "agent",
172
+ "fromPort": ["response", 0],
173
+ "toNodeId": "review",
174
+ "toPort": ["result", 0]
175
+ },
176
+ {
177
+ "edgeId": "e-review-feedback",
178
+ "fromNodeId": "review",
179
+ "fromPort": ["feedback", 0],
180
+ "toNodeId": "agent",
181
+ "toPort": ["feedback", 0]
182
+ },
183
+ {
184
+ "edgeId": "e-review-done",
185
+ "fromNodeId": "review",
186
+ "fromPort": ["response", 0],
187
+ "toNodeId": "done",
188
+ "toPort": ["value", 0]
189
+ }
190
+ ]
191
+ }
192
+ }
@@ -0,0 +1,111 @@
1
+ {
2
+ "$schema": "../schemas/workflow.schema.json",
3
+ "metadata": {
4
+ "name": "KB tool",
5
+ "description": "Sample embedding tool loop: run KB ingest first, set Settings default embedding model. Chat Start. The agent calls project_search (hello-embed-search-handle) and cites path + heading.",
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": 0.9,
14
+ "width": 1200,
15
+ "height": 800
16
+ },
17
+ "nodes": [
18
+ {
19
+ "id": "chat",
20
+ "type": "common-chat-input",
21
+ "params": {},
22
+ "inputs": {},
23
+ "ui": {
24
+ "position": { "x": 40, "y": 200 },
25
+ "label": "Ask"
26
+ }
27
+ },
28
+ {
29
+ "id": "embed-provider",
30
+ "type": "common-embed-provider",
31
+ "params": {
32
+ "providerId": "",
33
+ "model": ""
34
+ },
35
+ "inputs": {},
36
+ "ui": {
37
+ "position": { "x": 40, "y": 40 },
38
+ "label": "Embed provider"
39
+ }
40
+ },
41
+ {
42
+ "id": "search-handle",
43
+ "type": "hello-embed-search-handle",
44
+ "params": {},
45
+ "inputs": {},
46
+ "ui": {
47
+ "position": { "x": 320, "y": 40 },
48
+ "label": "Project search"
49
+ }
50
+ },
51
+ {
52
+ "id": "agent",
53
+ "type": "common-openai-llm",
54
+ "params": {
55
+ "rolePreset": "custom",
56
+ "providerId": "",
57
+ "model": "",
58
+ "maxIterations": 8,
59
+ "maxFeedbackTurns": 4
60
+ },
61
+ "inputs": {
62
+ "systemPrompt": "You answer questions about this project using the project_search tool (markdown chunks with embeddings). Always call project_search first. Cite file path and heading from the hits. If hits are weak or the index is empty, say so — do not invent. On HITL feedback, search again if needed and revise."
63
+ },
64
+ "ui": {
65
+ "position": { "x": 320, "y": 200 },
66
+ "label": "Agent"
67
+ }
68
+ },
69
+ {
70
+ "id": "review",
71
+ "type": "common-hitl-review-gate",
72
+ "params": {},
73
+ "inputs": {},
74
+ "ui": {
75
+ "position": { "x": 640, "y": 220 },
76
+ "label": "Review"
77
+ }
78
+ }
79
+ ],
80
+ "edges": [
81
+ {
82
+ "edgeId": "e-chat-agent",
83
+ "fromNodeId": "chat",
84
+ "fromPort": ["message", 0],
85
+ "toNodeId": "agent",
86
+ "toPort": ["userPrompt", 0]
87
+ },
88
+ {
89
+ "edgeId": "e-embed-handle",
90
+ "fromNodeId": "embed-provider",
91
+ "fromPort": ["embed", 0],
92
+ "toNodeId": "search-handle",
93
+ "toPort": ["embed", 0]
94
+ },
95
+ {
96
+ "edgeId": "e-tools-agent",
97
+ "fromNodeId": "search-handle",
98
+ "fromPort": ["tools", 0],
99
+ "toNodeId": "agent",
100
+ "toPort": ["tools", 0]
101
+ },
102
+ {
103
+ "edgeId": "e-agent-review",
104
+ "fromNodeId": "agent",
105
+ "fromPort": ["response", 0],
106
+ "toNodeId": "review",
107
+ "toPort": ["result", 0]
108
+ }
109
+ ]
110
+ }
111
+ }
@@ -31,7 +31,7 @@ import type { CanvasViewport, WorkflowCurrentSnapshotPayload, WorkflowCurrentSta
31
31
  *
32
32
  * | Domain | Model | Reconnect | Live updates |
33
33
  * | ------ | ----- | --------- | -------------- |
34
- * | Session chrome (dividers, selection, settings) + effective `langflowerConfig` | **snapshot only** | slim `session.state.snapshot` | dividers / selection / settings via `editor.dividers.snapshot` / `editor.nodeSelected` / `editor.settings.snapshot` |
34
+ * | Session chrome (dividers, palette visibility, selection, settings) + effective `langflowerConfig` | **snapshot only** | slim `session.state.snapshot` | dividers / palette / selection / settings via `editor.dividers.snapshot` / `editor.paletteVisible.snapshot` / `editor.nodeSelected` / `editor.settings.snapshot` |
35
35
  * | Langflower project config (full layers) | **snapshot only** | `langflower.config.snapshot` after `session.ready`; effective also in slim session | full slice replace |
36
36
  * | Live provider model catalogs | **snapshot only** | `langflower.models.catalog.snapshot` after config (async on connect) + after Save | full map replace |
37
37
  * | Tool config | **snapshot only** | `toolConfig.snapshot` | full slice replace |
@@ -260,6 +260,14 @@ export declare const langflowerWsConfig: {
260
260
  * persists to `langflower.jsonc`.
261
261
  */
262
262
  readonly 'editor.dividers.requested': import("@langflower/websocket-bridge").WsBridgeMessageDefinition<DividerPositions>;
263
+ /**
264
+ * Left palette shown/hidden — client sends on hide (`<<`) / show (`>>`).
265
+ *
266
+ * Server validates, updates session, broadcasts to all tabs, and
267
+ * persists `paletteVisible` to project `langflower.jsonc`. Missing
268
+ * jsonc key means visible (`true`).
269
+ */
270
+ readonly 'editor.paletteVisible.requested': import("@langflower/websocket-bridge").WsBridgeMessageDefinition<boolean>;
263
271
  /**
264
272
  * Canvas selection changed — `nodeId` is the clicked node, or `null`
265
273
  * to clear. Shared session state, like {@link CanvasViewport}: not
@@ -349,11 +357,13 @@ export declare const langflowerWsConfig: {
349
357
  * `session.ready`).
350
358
  *
351
359
  * Payload is only {@link SessionStateSnapshotPayload}: `version`,
352
- * `langflowerConfig`, `dividerPositions`, `selectedNode`, `settings`.
353
- * Replace those slices from this event; hydrate workflows / runner /
354
- * feed / viewport / tool config from their dedicated snapshot keys
355
- * (see state-sync table on {@link langflowerWsConfig}). Live Settings
356
- * updates after connect use `editor.settings.snapshot`.
360
+ * `langflowerConfig`, `dividerPositions`, `paletteVisible`,
361
+ * `selectedNode`, `settings`. Replace those slices from this event;
362
+ * hydrate workflows / runner / feed / viewport / tool config from
363
+ * their dedicated snapshot keys (see state-sync table on
364
+ * {@link langflowerWsConfig}). Live Settings updates after connect use
365
+ * `editor.settings.snapshot`; live palette chrome uses
366
+ * `editor.paletteVisible.snapshot`.
357
367
  */
358
368
  readonly 'session.state.snapshot': import("@langflower/websocket-bridge").WsBridgeMessageDefinition<SessionStateSnapshotPayload>;
359
369
  /**
@@ -444,6 +454,12 @@ export declare const langflowerWsConfig: {
444
454
  readonly 'editor.viewport.delta': import("@langflower/websocket-bridge").WsBridgeMessageDefinition<CanvasViewport>;
445
455
  /** Divider positions — broadcast to all tabs after server persistence. */
446
456
  readonly 'editor.dividers.snapshot': import("@langflower/websocket-bridge").WsBridgeMessageDefinition<DividerPositions>;
457
+ /**
458
+ * Left palette visibility — broadcast to all tabs after server
459
+ * persistence. Hydrated on connect via
460
+ * {@link SessionStateSnapshotPayload.paletteVisible}.
461
+ */
462
+ readonly 'editor.paletteVisible.snapshot': import("@langflower/websocket-bridge").WsBridgeMessageDefinition<boolean>;
447
463
  /**
448
464
  * Authoritative selected node — full {@link WorkflowNodePersisted}
449
465
  * plus its {@link PaletteNodeDefinition} (for Inspector panel
@@ -87,6 +87,14 @@ const editorConfig = {
87
87
  * persists to `langflower.jsonc`.
88
88
  */
89
89
  'editor.dividers.requested': message(),
90
+ /**
91
+ * Left palette shown/hidden — client sends on hide (`<<`) / show (`>>`).
92
+ *
93
+ * Server validates, updates session, broadcasts to all tabs, and
94
+ * persists `paletteVisible` to project `langflower.jsonc`. Missing
95
+ * jsonc key means visible (`true`).
96
+ */
97
+ 'editor.paletteVisible.requested': message(),
90
98
  /**
91
99
  * Canvas selection changed — `nodeId` is the clicked node, or `null`
92
100
  * to clear. Shared session state, like {@link CanvasViewport}: not
@@ -123,6 +131,12 @@ const editorConfig = {
123
131
  'editor.viewport.delta': message(),
124
132
  /** Divider positions — broadcast to all tabs after server persistence. */
125
133
  'editor.dividers.snapshot': message(),
134
+ /**
135
+ * Left palette visibility — broadcast to all tabs after server
136
+ * persistence. Hydrated on connect via
137
+ * {@link SessionStateSnapshotPayload.paletteVisible}.
138
+ */
139
+ 'editor.paletteVisible.snapshot': message(),
126
140
  /**
127
141
  * Authoritative selected node — full {@link WorkflowNodePersisted}
128
142
  * plus its {@link PaletteNodeDefinition} (for Inspector panel
@@ -280,7 +294,7 @@ const runnerConfig = {
280
294
  * slice from its own key — there is no fat all-domains bootstrap payload.
281
295
  *
282
296
  * **Slim `session.state.snapshot` only:** `version`, `langflowerConfig`,
283
- * `dividerPositions`, `selectedNode`, `settings`.
297
+ * `dividerPositions`, `paletteVisible`, `selectedNode`, `settings`.
284
298
  *
285
299
  * **Do not put here** (dedicated keys, see emit order on
286
300
  * {@link langflowerWsConfig}): workflows, viewport, runner gate, execution
@@ -298,11 +312,13 @@ const bootstrapConfig = {
298
312
  * `session.ready`).
299
313
  *
300
314
  * Payload is only {@link SessionStateSnapshotPayload}: `version`,
301
- * `langflowerConfig`, `dividerPositions`, `selectedNode`, `settings`.
302
- * Replace those slices from this event; hydrate workflows / runner /
303
- * feed / viewport / tool config from their dedicated snapshot keys
304
- * (see state-sync table on {@link langflowerWsConfig}). Live Settings
305
- * updates after connect use `editor.settings.snapshot`.
315
+ * `langflowerConfig`, `dividerPositions`, `paletteVisible`,
316
+ * `selectedNode`, `settings`. Replace those slices from this event;
317
+ * hydrate workflows / runner / feed / viewport / tool config from
318
+ * their dedicated snapshot keys (see state-sync table on
319
+ * {@link langflowerWsConfig}). Live Settings updates after connect use
320
+ * `editor.settings.snapshot`; live palette chrome uses
321
+ * `editor.paletteVisible.snapshot`.
306
322
  */
307
323
  'session.state.snapshot': message(),
308
324
  /**
@@ -566,7 +582,7 @@ const workflowManagerConfig = {
566
582
  *
567
583
  * | Domain | Model | Reconnect | Live updates |
568
584
  * | ------ | ----- | --------- | -------------- |
569
- * | Session chrome (dividers, selection, settings) + effective `langflowerConfig` | **snapshot only** | slim `session.state.snapshot` | dividers / selection / settings via `editor.dividers.snapshot` / `editor.nodeSelected` / `editor.settings.snapshot` |
585
+ * | Session chrome (dividers, palette visibility, selection, settings) + effective `langflowerConfig` | **snapshot only** | slim `session.state.snapshot` | dividers / palette / selection / settings via `editor.dividers.snapshot` / `editor.paletteVisible.snapshot` / `editor.nodeSelected` / `editor.settings.snapshot` |
570
586
  * | Langflower project config (full layers) | **snapshot only** | `langflower.config.snapshot` after `session.ready`; effective also in slim session | full slice replace |
571
587
  * | Live provider model catalogs | **snapshot only** | `langflower.models.catalog.snapshot` after config (async on connect) + after Save | full map replace |
572
588
  * | Tool config | **snapshot only** | `toolConfig.snapshot` | full slice replace |
@@ -29,6 +29,14 @@ describe('mergeLangflowerConfigLayers', () => {
29
29
  expect(merged.model).toBe('global/m');
30
30
  expect(merged.provider?.x?.name).toBe('X');
31
31
  });
32
+ it('lets project embedding win over global', () => {
33
+ const merged = mergeLangflowerConfigLayers({ embedding: 'global/e' }, { embedding: 'project/e' });
34
+ expect(merged.embedding).toBe('project/e');
35
+ });
36
+ it('keeps global embedding when project omits it', () => {
37
+ expect(mergeLangflowerConfigLayers({ embedding: 'global/e' }, {})
38
+ .embedding).toBe('global/e');
39
+ });
32
40
  it('lets project serverLogs win over global when set', () => {
33
41
  expect(mergeLangflowerConfigLayers({ serverLogs: true }, { serverLogs: false }).serverLogs).toBe(false);
34
42
  expect(mergeLangflowerConfigLayers({ serverLogs: false }, {}).serverLogs).toBe(false);
@@ -14,6 +14,9 @@ export type SettingsDraft = {
14
14
  /** Split from disk `model: "provider/model"` for Settings selects. */
15
15
  readonly defaultProviderId: string;
16
16
  readonly defaultModelId: string;
17
+ /** Split from disk `embedding: "provider/model"` for Settings selects. */
18
+ readonly defaultEmbeddingProviderId: string;
19
+ readonly defaultEmbeddingModelId: string;
17
20
  readonly providers: readonly ProviderDraft[];
18
21
  readonly serverLogs: ServerLogsDraft;
19
22
  };
@@ -38,6 +41,8 @@ export declare const mergeDraftPatch: (previous: SettingsDraft, patch: SettingsD
38
41
  * layer, then fully align when non-secret fields already match (post-Save).
39
42
  */
40
43
  export declare const draftAfterLayerSnapshot: (previousDraft: SettingsDraft, previousBaseline: SettingsDraft, nextBaseline: SettingsDraft) => SettingsDraft;
44
+ /** Static model ids from the provider row matching `providerId`. */
45
+ export declare const staticModelIdsForProvider: (draft: SettingsDraft, providerId: string) => readonly string[];
41
46
  /** Static model ids from the provider row matching `defaultProviderId`. */
42
47
  export declare const defaultProviderStaticModelIds: (draft: SettingsDraft) => readonly string[];
43
48
  /** Row key for connections map (stable for empty ids). */
@@ -27,9 +27,12 @@ export const configToDraft = (config) => {
27
27
  ? 'off'
28
28
  : 'default';
29
29
  const parts = parseDefaultChatModel(config.model);
30
+ const embeddingParts = parseDefaultChatModel(config.embedding);
30
31
  return {
31
32
  defaultProviderId: parts?.providerId ?? '',
32
33
  defaultModelId: parts?.model ?? '',
34
+ defaultEmbeddingProviderId: embeddingParts?.providerId ?? '',
35
+ defaultEmbeddingModelId: embeddingParts?.model ?? '',
33
36
  providers,
34
37
  serverLogs,
35
38
  };
@@ -73,13 +76,16 @@ export const draftToSavePayload = (scope, draft) => {
73
76
  },
74
77
  ];
75
78
  }));
76
- // Always send `model` so clearing the selects removes it from the layer
77
- // (omit would leave the previous disk value — Save looked like a no-op).
79
+ // Always send `model` / `embedding` so clearing the selects removes them
80
+ // from the layer (omit would leave the previous disk value — Save looked
81
+ // like a no-op).
78
82
  const model = formatDefaultChatModel(draft.defaultProviderId, draft.defaultModelId) ??
79
83
  '';
84
+ const embedding = formatDefaultChatModel(draft.defaultEmbeddingProviderId, draft.defaultEmbeddingModelId) ?? '';
80
85
  return {
81
86
  scope,
82
87
  model,
88
+ embedding,
83
89
  provider,
84
90
  providerApiKeys,
85
91
  serverLogs: serverLogsToSave(draft.serverLogs),
@@ -127,17 +133,19 @@ export const draftAfterLayerSnapshot = (previousDraft, previousBaseline, nextBas
127
133
  };
128
134
  return sameDraft(cleared, nextBaseline) ? nextBaseline : cleared;
129
135
  };
130
- /** Static model ids from the provider row matching `defaultProviderId`. */
131
- export const defaultProviderStaticModelIds = (draft) => {
132
- const providerId = draft.defaultProviderId.trim();
133
- if (providerId.length === 0) {
136
+ /** Static model ids from the provider row matching `providerId`. */
137
+ export const staticModelIdsForProvider = (draft, providerId) => {
138
+ const id = providerId.trim();
139
+ if (id.length === 0) {
134
140
  return [];
135
141
  }
136
- const row = draft.providers.find((provider) => provider.id === providerId);
142
+ const row = draft.providers.find((provider) => provider.id === id);
137
143
  if (row === undefined) {
138
144
  return [];
139
145
  }
140
146
  return parseModelsText(row.modelsText);
141
147
  };
148
+ /** Static model ids from the provider row matching `defaultProviderId`. */
149
+ export const defaultProviderStaticModelIds = (draft) => staticModelIdsForProvider(draft, draft.defaultProviderId);
142
150
  /** Row key for connections map (stable for empty ids). */
143
151
  export const providerConnectionKey = (index) => String(index);
@@ -15,7 +15,7 @@ export type { LangflowerConfig, LangflowerConfigDraft, LangflowerConfigDraftDisc
15
15
  export { mergeLangflowerConfigLayers } from './langflower-config/merge-langflower-config-layers.js';
16
16
  export { defaultChatModelEmptyTitle, formatDefaultChatModel, parseDefaultChatModel, } from './langflower-config/parse-default-chat-model.js';
17
17
  export type { DefaultChatModelParts } from './langflower-config/parse-default-chat-model.js';
18
- export { configToDraft, defaultProviderStaticModelIds, draftAfterLayerSnapshot, draftToSavePayload, mergeDraftPatch, providerConnectionKey, redactDraftSecrets, sameDraft, } from './langflower-config/settings-draft.js';
18
+ export { configToDraft, defaultProviderStaticModelIds, staticModelIdsForProvider, draftAfterLayerSnapshot, draftToSavePayload, mergeDraftPatch, providerConnectionKey, redactDraftSecrets, sameDraft, } from './langflower-config/settings-draft.js';
19
19
  export type { ProviderDraft, ServerLogsDraft, SettingsDraft, } from './langflower-config/settings-draft.js';
20
20
  export { resolveServerLogsEnabled } from './langflower-config/resolve-server-logs-enabled.js';
21
21
  export type { EditorAddEdgeRequestedPayload, EditorAddNodeRequestedPayload, EditorPasteRequestedPayload, EditorSelectedNodePayload, EditorSelectNodeRequestedPayload, EditorSettingsRequestedPayload, EditorSettingsSnapshotPayload, EditorUpdateNodeRequestedPayload, } from './types/langflower-editor.js';
@@ -6,7 +6,7 @@ export { displayEnabledToolIds, HARNESS_BUILTIN_TOOL_OPTIONS, mergeEnabledToolId
6
6
  export { langflowerWsConfig } from './langflower-bus-config.js';
7
7
  export { mergeLangflowerConfigLayers } from './langflower-config/merge-langflower-config-layers.js';
8
8
  export { defaultChatModelEmptyTitle, formatDefaultChatModel, parseDefaultChatModel, } from './langflower-config/parse-default-chat-model.js';
9
- export { configToDraft, defaultProviderStaticModelIds, draftAfterLayerSnapshot, draftToSavePayload, mergeDraftPatch, providerConnectionKey, redactDraftSecrets, sameDraft, } from './langflower-config/settings-draft.js';
9
+ export { configToDraft, defaultProviderStaticModelIds, staticModelIdsForProvider, draftAfterLayerSnapshot, draftToSavePayload, mergeDraftPatch, providerConnectionKey, redactDraftSecrets, sameDraft, } from './langflower-config/settings-draft.js';
10
10
  export { resolveServerLogsEnabled } from './langflower-config/resolve-server-logs-enabled.js';
11
11
  export { toCheckpointJsonValue } from './checkpoint/json-value.js';
12
12
  export { buildWorkflowFingerprint } from './checkpoint/workflow-fingerprint.js';
@@ -55,6 +55,12 @@ export type SessionStateSnapshotPayload = {
55
55
  readonly langflowerConfig: LangflowerConfig;
56
56
  /** Editor divider positions (sidebar + composer sizes). */
57
57
  readonly dividerPositions: DividerPositions;
58
+ /**
59
+ * Left node palette shown. Hydrated from project `langflower.jsonc`
60
+ * (`paletteVisible`; missing key → `true`) and updated live via
61
+ * `editor.paletteVisible.snapshot`.
62
+ */
63
+ readonly paletteVisible: boolean;
58
64
  /** Currently selected canvas node (in memory, shared across tabs), or `null`. */
59
65
  readonly selectedNode: EditorSelectedNodePayload['node'];
60
66
  /**
@@ -93,6 +93,11 @@ export type LangflowerConfig = {
93
93
  */
94
94
  readonly currentWorkflowId?: string;
95
95
  readonly model?: string;
96
+ /**
97
+ * Default embedding identity `"providerId/modelId"`, distinct from chat
98
+ * {@link LangflowerConfig.model}.
99
+ */
100
+ readonly embedding?: string;
96
101
  readonly provider?: Readonly<Record<string, LangflowerProviderConfig>>;
97
102
  /** Tools available to `optionsSource: 'langflower.tools'` uiSchema fields. */
98
103
  readonly tools?: readonly LangflowerToolConfig[];
@@ -103,6 +108,11 @@ export type LangflowerConfig = {
103
108
  readonly skills?: readonly LangflowerSkillConfig[];
104
109
  /** Editor divider positions (sidebar + composer sizes). */
105
110
  readonly dividerPositions?: DividerPositions;
111
+ /**
112
+ * Left node palette shown. Project jsonc only (same class as
113
+ * {@link LangflowerConfig.dividerPositions}). Omit = visible.
114
+ */
115
+ readonly paletteVisible?: boolean;
106
116
  /**
107
117
  * Runtime allow/ask/deny for harness tools (≠ author-time `enabledToolIds`).
108
118
  */
@@ -134,6 +144,11 @@ export type LangflowerConfigScope = 'project' | 'global';
134
144
  export type LangflowerConfigSaveRequestedPayload = {
135
145
  readonly scope: LangflowerConfigScope;
136
146
  readonly model?: string;
147
+ /**
148
+ * Default embedding identity `"providerId/modelId"`. Empty string clears
149
+ * the layer key (same as `model`). Omitted leaves the existing value.
150
+ */
151
+ readonly embedding?: string;
137
152
  readonly provider?: Readonly<Record<string, LangflowerProviderConfig>>;
138
153
  readonly providerApiKeys?: Readonly<Record<string, string>>;
139
154
  /**
@@ -211,6 +226,8 @@ export type ProviderConnectionStatus = {
211
226
  export type LangflowerConfigDraft = {
212
227
  readonly defaultProviderId: string;
213
228
  readonly defaultModelId: string;
229
+ readonly defaultEmbeddingProviderId: string;
230
+ readonly defaultEmbeddingModelId: string;
214
231
  readonly providers: readonly {
215
232
  readonly id: string;
216
233
  readonly name: string;
@@ -6,7 +6,8 @@ export type PaletteNodeSource = 'system' | 'custom';
6
6
  * node factory, plus wire-only {@link PaletteNodeSource}.
7
7
  *
8
8
  * Port metadata lives in `inputsConfigs` / `outputsConfigs` (`config` fields).
9
- * Optional `description` is markdown for the palette detail popover footer.
9
+ * Optional `description` is markdown for the palette detail popover footer
10
+ * and the inspector header.
10
11
  */
11
12
  export type PaletteNodeDefinition = Omit<ReactiveNodeDefinition, 'getInstance'> & {
12
13
  readonly source: PaletteNodeSource;
@@ -23,7 +23,7 @@ export type BuiltinToolRegistration = {
23
23
  };
24
24
  /**
25
25
  * Project harness surface (builtins + optional webFetch).
26
- * MCP tools are not on the harness — agents consume wired `McpHandle` values.
26
+ * MCP tools are not on the harness — agents consume wired `ToolHandle[]`.
27
27
  */
28
28
  export type Harness = {
29
29
  readonly invoke: (call: ToolInvokeCall) => Promise<ToolInvokeResult>;
@@ -1,30 +1,12 @@
1
+ import type { ToolHandle } from '@langflower/node-sdk';
1
2
  import type { McpClient } from './mcp-client-types.js';
2
3
  /**
3
- * Structural twin of node-sdk `ToolHandle` (tools must not import
4
- * `@langflower/node-sdk`). Assignable at call sites that expect the
5
- * author-facing handle.
6
- */
7
- export type BuiltMcpToolHandle = {
8
- readonly toolId: string;
9
- readonly name: string;
10
- readonly description: string;
11
- readonly inputSchema: object;
12
- readonly invoke: (args: Readonly<Record<string, unknown>>) => Promise<string>;
13
- };
14
- /** Structural twin of node-sdk `McpHandle`. */
15
- export type BuiltMcpHandle = {
16
- readonly id: string;
17
- readonly name: string;
18
- readonly tools: readonly BuiltMcpToolHandle[];
19
- };
20
- /**
21
- * After connect: list tools once and build a live MCP handle with eager tools.
4
+ * After connect: list tools once and bind invoke closures.
22
5
  * Optional `toolNamesRaw` filters for system MCP jsonc; canvas nodes omit it
23
6
  * and expose the full `tools/list` inventory. Tool ids use `client.serverName`
24
7
  * (`<mcp_name>__<tool>`).
25
8
  */
26
9
  export declare const buildMcpHandle: (options: {
27
- readonly id: string;
28
10
  readonly toolNamesRaw?: unknown;
29
11
  readonly client: McpClient;
30
- }) => Promise<BuiltMcpHandle>;
12
+ }) => Promise<readonly ToolHandle[]>;