@flowdrop/flowdrop 1.0.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 (403) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +252 -0
  3. package/dist/adapters/WorkflowAdapter.d.ts +167 -0
  4. package/dist/adapters/WorkflowAdapter.js +368 -0
  5. package/dist/adapters/agentspec/AgentSpecAdapter.d.ts +96 -0
  6. package/dist/adapters/agentspec/AgentSpecAdapter.js +626 -0
  7. package/dist/adapters/agentspec/agentAdapter.d.ts +59 -0
  8. package/dist/adapters/agentspec/agentAdapter.js +91 -0
  9. package/dist/adapters/agentspec/autoLayout.d.ts +34 -0
  10. package/dist/adapters/agentspec/autoLayout.js +127 -0
  11. package/dist/adapters/agentspec/componentTypeDefaults.d.ts +73 -0
  12. package/dist/adapters/agentspec/componentTypeDefaults.js +238 -0
  13. package/dist/adapters/agentspec/defaultNodeTypes.d.ts +53 -0
  14. package/dist/adapters/agentspec/defaultNodeTypes.js +561 -0
  15. package/dist/adapters/agentspec/index.d.ts +37 -0
  16. package/dist/adapters/agentspec/index.js +39 -0
  17. package/dist/adapters/agentspec/validator.d.ts +34 -0
  18. package/dist/adapters/agentspec/validator.js +169 -0
  19. package/dist/api/enhanced-client.d.ts +183 -0
  20. package/dist/api/enhanced-client.js +430 -0
  21. package/dist/components/App.svelte +981 -0
  22. package/dist/components/App.svelte.d.ts +54 -0
  23. package/dist/components/CanvasBanner.stories.svelte +29 -0
  24. package/dist/components/CanvasBanner.stories.svelte.d.ts +27 -0
  25. package/dist/components/CanvasBanner.svelte +57 -0
  26. package/dist/components/CanvasBanner.svelte.d.ts +8 -0
  27. package/dist/components/ConfigForm.svelte +1138 -0
  28. package/dist/components/ConfigForm.svelte.d.ts +44 -0
  29. package/dist/components/ConfigModal.svelte +188 -0
  30. package/dist/components/ConfigModal.svelte.d.ts +13 -0
  31. package/dist/components/ConfigPanel.stories.svelte +47 -0
  32. package/dist/components/ConfigPanel.stories.svelte.d.ts +27 -0
  33. package/dist/components/ConfigPanel.svelte +182 -0
  34. package/dist/components/ConfigPanel.svelte.d.ts +32 -0
  35. package/dist/components/ConnectionLine.svelte +32 -0
  36. package/dist/components/ConnectionLine.svelte.d.ts +3 -0
  37. package/dist/components/EdgeRefresher.svelte +41 -0
  38. package/dist/components/EdgeRefresher.svelte.d.ts +9 -0
  39. package/dist/components/FlowDropZone.svelte +83 -0
  40. package/dist/components/FlowDropZone.svelte.d.ts +13 -0
  41. package/dist/components/LoadingSpinner.stories.svelte +30 -0
  42. package/dist/components/LoadingSpinner.stories.svelte.d.ts +27 -0
  43. package/dist/components/LoadingSpinner.svelte +36 -0
  44. package/dist/components/LoadingSpinner.svelte.d.ts +8 -0
  45. package/dist/components/Logo.stories.svelte +22 -0
  46. package/dist/components/Logo.stories.svelte.d.ts +27 -0
  47. package/dist/components/Logo.svelte +102 -0
  48. package/dist/components/Logo.svelte.d.ts +26 -0
  49. package/dist/components/LogsSidebar.svelte +563 -0
  50. package/dist/components/LogsSidebar.svelte.d.ts +17 -0
  51. package/dist/components/MarkdownDisplay.stories.svelte +36 -0
  52. package/dist/components/MarkdownDisplay.stories.svelte.d.ts +27 -0
  53. package/dist/components/MarkdownDisplay.svelte +29 -0
  54. package/dist/components/MarkdownDisplay.svelte.d.ts +7 -0
  55. package/dist/components/Navbar.stories.svelte +53 -0
  56. package/dist/components/Navbar.stories.svelte.d.ts +27 -0
  57. package/dist/components/Navbar.svelte +726 -0
  58. package/dist/components/Navbar.svelte.d.ts +29 -0
  59. package/dist/components/NodeSidebar.svelte +762 -0
  60. package/dist/components/NodeSidebar.svelte.d.ts +9 -0
  61. package/dist/components/NodeStatusOverlay.stories.svelte +85 -0
  62. package/dist/components/NodeStatusOverlay.stories.svelte.d.ts +27 -0
  63. package/dist/components/NodeStatusOverlay.svelte +327 -0
  64. package/dist/components/NodeStatusOverlay.svelte.d.ts +11 -0
  65. package/dist/components/PipelineStatus.svelte +314 -0
  66. package/dist/components/PipelineStatus.svelte.d.ts +20 -0
  67. package/dist/components/PortCoordinateTracker.svelte +58 -0
  68. package/dist/components/PortCoordinateTracker.svelte.d.ts +12 -0
  69. package/dist/components/ReadOnlyDetails.svelte +170 -0
  70. package/dist/components/ReadOnlyDetails.svelte.d.ts +25 -0
  71. package/dist/components/SchemaForm.stories.svelte +116 -0
  72. package/dist/components/SchemaForm.stories.svelte.d.ts +27 -0
  73. package/dist/components/SchemaForm.svelte +536 -0
  74. package/dist/components/SchemaForm.svelte.d.ts +83 -0
  75. package/dist/components/SettingsModal.svelte +279 -0
  76. package/dist/components/SettingsModal.svelte.d.ts +23 -0
  77. package/dist/components/SettingsPanel.svelte +638 -0
  78. package/dist/components/SettingsPanel.svelte.d.ts +21 -0
  79. package/dist/components/StatusIcon.stories.svelte +60 -0
  80. package/dist/components/StatusIcon.stories.svelte.d.ts +27 -0
  81. package/dist/components/StatusIcon.svelte +119 -0
  82. package/dist/components/StatusIcon.svelte.d.ts +10 -0
  83. package/dist/components/StatusLabel.stories.svelte +17 -0
  84. package/dist/components/StatusLabel.stories.svelte.d.ts +27 -0
  85. package/dist/components/StatusLabel.svelte +33 -0
  86. package/dist/components/StatusLabel.svelte.d.ts +7 -0
  87. package/dist/components/ThemeToggle.stories.svelte +25 -0
  88. package/dist/components/ThemeToggle.stories.svelte.d.ts +27 -0
  89. package/dist/components/ThemeToggle.svelte +185 -0
  90. package/dist/components/ThemeToggle.svelte.d.ts +14 -0
  91. package/dist/components/UniversalNode.svelte +155 -0
  92. package/dist/components/UniversalNode.svelte.d.ts +15 -0
  93. package/dist/components/WorkflowEditor.svelte +1035 -0
  94. package/dist/components/WorkflowEditor.svelte.d.ts +23 -0
  95. package/dist/components/form/FormArray.svelte +1049 -0
  96. package/dist/components/form/FormArray.svelte.d.ts +22 -0
  97. package/dist/components/form/FormAutocomplete.svelte +1009 -0
  98. package/dist/components/form/FormAutocomplete.svelte.d.ts +25 -0
  99. package/dist/components/form/FormCheckboxGroup.stories.svelte +28 -0
  100. package/dist/components/form/FormCheckboxGroup.stories.svelte.d.ts +27 -0
  101. package/dist/components/form/FormCheckboxGroup.svelte +155 -0
  102. package/dist/components/form/FormCheckboxGroup.svelte.d.ts +17 -0
  103. package/dist/components/form/FormCodeEditor.svelte +458 -0
  104. package/dist/components/form/FormCodeEditor.svelte.d.ts +25 -0
  105. package/dist/components/form/FormField.svelte +417 -0
  106. package/dist/components/form/FormField.svelte.d.ts +29 -0
  107. package/dist/components/form/FormFieldLight.svelte +425 -0
  108. package/dist/components/form/FormFieldLight.svelte.d.ts +18 -0
  109. package/dist/components/form/FormFieldWrapper.stories.svelte +53 -0
  110. package/dist/components/form/FormFieldWrapper.stories.svelte.d.ts +27 -0
  111. package/dist/components/form/FormFieldWrapper.svelte +125 -0
  112. package/dist/components/form/FormFieldWrapper.svelte.d.ts +18 -0
  113. package/dist/components/form/FormFieldset.svelte +142 -0
  114. package/dist/components/form/FormFieldset.svelte.d.ts +11 -0
  115. package/dist/components/form/FormMarkdownEditor.svelte +752 -0
  116. package/dist/components/form/FormMarkdownEditor.svelte.d.ts +33 -0
  117. package/dist/components/form/FormNumberField.stories.svelte +36 -0
  118. package/dist/components/form/FormNumberField.stories.svelte.d.ts +27 -0
  119. package/dist/components/form/FormNumberField.svelte +112 -0
  120. package/dist/components/form/FormNumberField.svelte.d.ts +25 -0
  121. package/dist/components/form/FormRangeField.stories.svelte +31 -0
  122. package/dist/components/form/FormRangeField.stories.svelte.d.ts +27 -0
  123. package/dist/components/form/FormRangeField.svelte +246 -0
  124. package/dist/components/form/FormRangeField.svelte.d.ts +23 -0
  125. package/dist/components/form/FormSelect.stories.svelte +50 -0
  126. package/dist/components/form/FormSelect.stories.svelte.d.ts +27 -0
  127. package/dist/components/form/FormSelect.svelte +129 -0
  128. package/dist/components/form/FormSelect.svelte.d.ts +20 -0
  129. package/dist/components/form/FormTemplateEditor.svelte +825 -0
  130. package/dist/components/form/FormTemplateEditor.svelte.d.ts +41 -0
  131. package/dist/components/form/FormTextField.stories.svelte +30 -0
  132. package/dist/components/form/FormTextField.stories.svelte.d.ts +27 -0
  133. package/dist/components/form/FormTextField.svelte +91 -0
  134. package/dist/components/form/FormTextField.svelte.d.ts +19 -0
  135. package/dist/components/form/FormTextarea.stories.svelte +34 -0
  136. package/dist/components/form/FormTextarea.stories.svelte.d.ts +27 -0
  137. package/dist/components/form/FormTextarea.svelte +97 -0
  138. package/dist/components/form/FormTextarea.svelte.d.ts +21 -0
  139. package/dist/components/form/FormToggle.stories.svelte +30 -0
  140. package/dist/components/form/FormToggle.stories.svelte.d.ts +27 -0
  141. package/dist/components/form/FormToggle.svelte +126 -0
  142. package/dist/components/form/FormToggle.svelte.d.ts +19 -0
  143. package/dist/components/form/FormUISchemaRenderer.svelte +136 -0
  144. package/dist/components/form/FormUISchemaRenderer.svelte.d.ts +32 -0
  145. package/dist/components/form/index.d.ts +50 -0
  146. package/dist/components/form/index.js +54 -0
  147. package/dist/components/form/templateAutocomplete.d.ts +29 -0
  148. package/dist/components/form/templateAutocomplete.js +254 -0
  149. package/dist/components/form/types.d.ts +485 -0
  150. package/dist/components/form/types.js +73 -0
  151. package/dist/components/interrupt/ChoicePrompt.stories.svelte +52 -0
  152. package/dist/components/interrupt/ChoicePrompt.stories.svelte.d.ts +27 -0
  153. package/dist/components/interrupt/ChoicePrompt.svelte +401 -0
  154. package/dist/components/interrupt/ChoicePrompt.svelte.d.ts +23 -0
  155. package/dist/components/interrupt/ConfirmationPrompt.stories.svelte +71 -0
  156. package/dist/components/interrupt/ConfirmationPrompt.stories.svelte.d.ts +27 -0
  157. package/dist/components/interrupt/ConfirmationPrompt.svelte +292 -0
  158. package/dist/components/interrupt/ConfirmationPrompt.svelte.d.ts +25 -0
  159. package/dist/components/interrupt/FormPrompt.svelte +236 -0
  160. package/dist/components/interrupt/FormPrompt.svelte.d.ts +23 -0
  161. package/dist/components/interrupt/InterruptBubble.svelte +601 -0
  162. package/dist/components/interrupt/InterruptBubble.svelte.d.ts +16 -0
  163. package/dist/components/interrupt/ReviewPrompt.stories.svelte +67 -0
  164. package/dist/components/interrupt/ReviewPrompt.stories.svelte.d.ts +27 -0
  165. package/dist/components/interrupt/ReviewPrompt.svelte +861 -0
  166. package/dist/components/interrupt/ReviewPrompt.svelte.d.ts +23 -0
  167. package/dist/components/interrupt/TextInputPrompt.stories.svelte +47 -0
  168. package/dist/components/interrupt/TextInputPrompt.stories.svelte.d.ts +27 -0
  169. package/dist/components/interrupt/TextInputPrompt.svelte +346 -0
  170. package/dist/components/interrupt/TextInputPrompt.svelte.d.ts +23 -0
  171. package/dist/components/interrupt/index.d.ts +13 -0
  172. package/dist/components/interrupt/index.js +15 -0
  173. package/dist/components/layouts/MainLayout.svelte +718 -0
  174. package/dist/components/layouts/MainLayout.svelte.d.ts +62 -0
  175. package/dist/components/nodes/GatewayNode.stories.svelte +108 -0
  176. package/dist/components/nodes/GatewayNode.stories.svelte.d.ts +26 -0
  177. package/dist/components/nodes/GatewayNode.svelte +591 -0
  178. package/dist/components/nodes/GatewayNode.svelte.d.ts +15 -0
  179. package/dist/components/nodes/IdeaNode.stories.svelte +52 -0
  180. package/dist/components/nodes/IdeaNode.stories.svelte.d.ts +26 -0
  181. package/dist/components/nodes/IdeaNode.svelte +455 -0
  182. package/dist/components/nodes/IdeaNode.svelte.d.ts +24 -0
  183. package/dist/components/nodes/NotesNode.stories.svelte +76 -0
  184. package/dist/components/nodes/NotesNode.stories.svelte.d.ts +26 -0
  185. package/dist/components/nodes/NotesNode.svelte +378 -0
  186. package/dist/components/nodes/NotesNode.svelte.d.ts +24 -0
  187. package/dist/components/nodes/SimpleNode.stories.svelte +159 -0
  188. package/dist/components/nodes/SimpleNode.stories.svelte.d.ts +26 -0
  189. package/dist/components/nodes/SimpleNode.svelte +451 -0
  190. package/dist/components/nodes/SimpleNode.svelte.d.ts +25 -0
  191. package/dist/components/nodes/SquareNode.stories.svelte +82 -0
  192. package/dist/components/nodes/SquareNode.stories.svelte.d.ts +26 -0
  193. package/dist/components/nodes/SquareNode.svelte +407 -0
  194. package/dist/components/nodes/SquareNode.svelte.d.ts +25 -0
  195. package/dist/components/nodes/TerminalNode.stories.svelte +25 -0
  196. package/dist/components/nodes/TerminalNode.stories.svelte.d.ts +26 -0
  197. package/dist/components/nodes/TerminalNode.svelte +690 -0
  198. package/dist/components/nodes/TerminalNode.svelte.d.ts +25 -0
  199. package/dist/components/nodes/ToolNode.stories.svelte +189 -0
  200. package/dist/components/nodes/ToolNode.stories.svelte.d.ts +26 -0
  201. package/dist/components/nodes/ToolNode.svelte +471 -0
  202. package/dist/components/nodes/ToolNode.svelte.d.ts +36 -0
  203. package/dist/components/nodes/WorkflowNode.stories.svelte +55 -0
  204. package/dist/components/nodes/WorkflowNode.stories.svelte.d.ts +26 -0
  205. package/dist/components/nodes/WorkflowNode.svelte +571 -0
  206. package/dist/components/nodes/WorkflowNode.svelte.d.ts +15 -0
  207. package/dist/components/playground/ChatPanel.svelte +905 -0
  208. package/dist/components/playground/ChatPanel.svelte.d.ts +46 -0
  209. package/dist/components/playground/ExecutionLogs.svelte +488 -0
  210. package/dist/components/playground/ExecutionLogs.svelte.d.ts +14 -0
  211. package/dist/components/playground/InputCollector.svelte +444 -0
  212. package/dist/components/playground/InputCollector.svelte.d.ts +16 -0
  213. package/dist/components/playground/MessageBubble.stories.svelte +62 -0
  214. package/dist/components/playground/MessageBubble.stories.svelte.d.ts +27 -0
  215. package/dist/components/playground/MessageBubble.svelte +633 -0
  216. package/dist/components/playground/MessageBubble.svelte.d.ts +24 -0
  217. package/dist/components/playground/Playground.svelte +1075 -0
  218. package/dist/components/playground/Playground.svelte.d.ts +25 -0
  219. package/dist/components/playground/PlaygroundModal.svelte +220 -0
  220. package/dist/components/playground/PlaygroundModal.svelte.d.ts +25 -0
  221. package/dist/components/playground/SessionManager.svelte +538 -0
  222. package/dist/components/playground/SessionManager.svelte.d.ts +20 -0
  223. package/dist/config/agentSpecEndpoints.d.ts +70 -0
  224. package/dist/config/agentSpecEndpoints.js +65 -0
  225. package/dist/config/constants.d.ts +43 -0
  226. package/dist/config/constants.js +31 -0
  227. package/dist/config/defaultCategories.d.ts +7 -0
  228. package/dist/config/defaultCategories.js +126 -0
  229. package/dist/config/defaultPortConfig.d.ts +6 -0
  230. package/dist/config/defaultPortConfig.js +201 -0
  231. package/dist/config/endpoints.d.ts +160 -0
  232. package/dist/config/endpoints.js +146 -0
  233. package/dist/config/runtimeConfig.d.ts +47 -0
  234. package/dist/config/runtimeConfig.js +80 -0
  235. package/dist/core/index.d.ts +75 -0
  236. package/dist/core/index.js +92 -0
  237. package/dist/display/index.d.ts +29 -0
  238. package/dist/display/index.js +36 -0
  239. package/dist/editor/index.d.ts +95 -0
  240. package/dist/editor/index.js +138 -0
  241. package/dist/form/code.d.ts +101 -0
  242. package/dist/form/code.js +168 -0
  243. package/dist/form/fieldRegistry.d.ts +169 -0
  244. package/dist/form/fieldRegistry.js +152 -0
  245. package/dist/form/full.d.ts +56 -0
  246. package/dist/form/full.js +80 -0
  247. package/dist/form/index.d.ts +77 -0
  248. package/dist/form/index.js +91 -0
  249. package/dist/form/markdown.d.ts +69 -0
  250. package/dist/form/markdown.js +103 -0
  251. package/dist/helpers/nodeLayoutHelper.d.ts +14 -0
  252. package/dist/helpers/nodeLayoutHelper.js +19 -0
  253. package/dist/helpers/proximityConnect.d.ts +94 -0
  254. package/dist/helpers/proximityConnect.js +314 -0
  255. package/dist/helpers/workflowEditorHelper.d.ts +183 -0
  256. package/dist/helpers/workflowEditorHelper.js +595 -0
  257. package/dist/index.d.ts +37 -0
  258. package/dist/index.js +64 -0
  259. package/dist/mocks/app-environment.d.ts +8 -0
  260. package/dist/mocks/app-environment.js +16 -0
  261. package/dist/mocks/app-forms.d.ts +2 -0
  262. package/dist/mocks/app-forms.js +22 -0
  263. package/dist/mocks/app-navigation.d.ts +5 -0
  264. package/dist/mocks/app-navigation.js +36 -0
  265. package/dist/mocks/app-stores.d.ts +14 -0
  266. package/dist/mocks/app-stores.js +26 -0
  267. package/dist/playground/index.d.ts +131 -0
  268. package/dist/playground/index.js +172 -0
  269. package/dist/playground/mount.d.ts +203 -0
  270. package/dist/playground/mount.js +235 -0
  271. package/dist/registry/BaseRegistry.d.ts +92 -0
  272. package/dist/registry/BaseRegistry.js +124 -0
  273. package/dist/registry/builtinFormats.d.ts +23 -0
  274. package/dist/registry/builtinFormats.js +70 -0
  275. package/dist/registry/builtinNodes.d.ts +77 -0
  276. package/dist/registry/builtinNodes.js +211 -0
  277. package/dist/registry/index.d.ts +8 -0
  278. package/dist/registry/index.js +12 -0
  279. package/dist/registry/nodeComponentRegistry.d.ts +276 -0
  280. package/dist/registry/nodeComponentRegistry.js +262 -0
  281. package/dist/registry/plugin.d.ts +215 -0
  282. package/dist/registry/plugin.js +249 -0
  283. package/dist/registry/workflowFormatRegistry.d.ts +122 -0
  284. package/dist/registry/workflowFormatRegistry.js +96 -0
  285. package/dist/schema/index.d.ts +23 -0
  286. package/dist/schema/index.js +23 -0
  287. package/dist/schemas/v1/workflow.schema.json +1078 -0
  288. package/dist/services/agentSpecExecutionService.d.ts +106 -0
  289. package/dist/services/agentSpecExecutionService.js +334 -0
  290. package/dist/services/api.d.ts +115 -0
  291. package/dist/services/api.js +214 -0
  292. package/dist/services/apiVariableService.d.ts +114 -0
  293. package/dist/services/apiVariableService.js +338 -0
  294. package/dist/services/autoSaveService.d.ts +112 -0
  295. package/dist/services/autoSaveService.js +227 -0
  296. package/dist/services/categoriesApi.d.ts +14 -0
  297. package/dist/services/categoriesApi.js +49 -0
  298. package/dist/services/draftStorage.d.ts +171 -0
  299. package/dist/services/draftStorage.js +299 -0
  300. package/dist/services/dynamicSchemaService.d.ts +108 -0
  301. package/dist/services/dynamicSchemaService.js +444 -0
  302. package/dist/services/globalSave.d.ts +69 -0
  303. package/dist/services/globalSave.js +248 -0
  304. package/dist/services/historyService.d.ts +208 -0
  305. package/dist/services/historyService.js +321 -0
  306. package/dist/services/interruptService.d.ts +133 -0
  307. package/dist/services/interruptService.js +280 -0
  308. package/dist/services/nodeExecutionService.d.ts +63 -0
  309. package/dist/services/nodeExecutionService.js +266 -0
  310. package/dist/services/playgroundService.d.ts +130 -0
  311. package/dist/services/playgroundService.js +321 -0
  312. package/dist/services/portConfigApi.d.ts +14 -0
  313. package/dist/services/portConfigApi.js +54 -0
  314. package/dist/services/settingsService.d.ts +92 -0
  315. package/dist/services/settingsService.js +196 -0
  316. package/dist/services/toastService.d.ts +156 -0
  317. package/dist/services/toastService.js +265 -0
  318. package/dist/services/variableService.d.ts +141 -0
  319. package/dist/services/variableService.js +463 -0
  320. package/dist/services/workflowStorage.d.ts +37 -0
  321. package/dist/services/workflowStorage.js +116 -0
  322. package/dist/settings/index.d.ts +25 -0
  323. package/dist/settings/index.js +33 -0
  324. package/dist/stores/categoriesStore.svelte.d.ts +32 -0
  325. package/dist/stores/categoriesStore.svelte.js +77 -0
  326. package/dist/stores/editorStateMachine.svelte.d.ts +42 -0
  327. package/dist/stores/editorStateMachine.svelte.js +132 -0
  328. package/dist/stores/historyStore.svelte.d.ts +136 -0
  329. package/dist/stores/historyStore.svelte.js +207 -0
  330. package/dist/stores/interruptStore.svelte.d.ts +179 -0
  331. package/dist/stores/interruptStore.svelte.js +346 -0
  332. package/dist/stores/playgroundStore.svelte.d.ts +230 -0
  333. package/dist/stores/playgroundStore.svelte.js +515 -0
  334. package/dist/stores/portCoordinateStore.svelte.d.ts +66 -0
  335. package/dist/stores/portCoordinateStore.svelte.js +186 -0
  336. package/dist/stores/settingsStore.svelte.d.ts +158 -0
  337. package/dist/stores/settingsStore.svelte.js +544 -0
  338. package/dist/stores/workflowStore.svelte.d.ts +260 -0
  339. package/dist/stores/workflowStore.svelte.js +649 -0
  340. package/dist/stories/CanvasDecorator.svelte +49 -0
  341. package/dist/stories/CanvasDecorator.svelte.d.ts +8 -0
  342. package/dist/stories/NodeDecorator.svelte +73 -0
  343. package/dist/stories/NodeDecorator.svelte.d.ts +8 -0
  344. package/dist/stories/utils.d.ts +93 -0
  345. package/dist/stories/utils.js +122 -0
  346. package/dist/styles/base.css +1300 -0
  347. package/dist/styles/toast.css +35 -0
  348. package/dist/styles/tokens.css +475 -0
  349. package/dist/svelte-app.d.ts +150 -0
  350. package/dist/svelte-app.js +295 -0
  351. package/dist/types/agentspec.d.ts +318 -0
  352. package/dist/types/agentspec.js +48 -0
  353. package/dist/types/auth.d.ts +263 -0
  354. package/dist/types/auth.js +229 -0
  355. package/dist/types/config.d.ts +151 -0
  356. package/dist/types/config.js +7 -0
  357. package/dist/types/events.d.ts +190 -0
  358. package/dist/types/events.js +30 -0
  359. package/dist/types/index.d.ts +1234 -0
  360. package/dist/types/index.js +27 -0
  361. package/dist/types/interrupt.d.ts +390 -0
  362. package/dist/types/interrupt.js +145 -0
  363. package/dist/types/interruptState.d.ts +211 -0
  364. package/dist/types/interruptState.js +308 -0
  365. package/dist/types/playground.d.ts +351 -0
  366. package/dist/types/playground.js +95 -0
  367. package/dist/types/settings.d.ts +189 -0
  368. package/dist/types/settings.js +97 -0
  369. package/dist/types/uischema.d.ts +144 -0
  370. package/dist/types/uischema.js +51 -0
  371. package/dist/utils/colors.d.ts +288 -0
  372. package/dist/utils/colors.js +548 -0
  373. package/dist/utils/config.d.ts +37 -0
  374. package/dist/utils/config.js +226 -0
  375. package/dist/utils/connections.d.ts +125 -0
  376. package/dist/utils/connections.js +414 -0
  377. package/dist/utils/errors.d.ts +28 -0
  378. package/dist/utils/errors.js +44 -0
  379. package/dist/utils/fetchWithAuth.d.ts +25 -0
  380. package/dist/utils/fetchWithAuth.js +34 -0
  381. package/dist/utils/handleIds.d.ts +35 -0
  382. package/dist/utils/handleIds.js +58 -0
  383. package/dist/utils/handlePositioning.d.ts +31 -0
  384. package/dist/utils/handlePositioning.js +35 -0
  385. package/dist/utils/icons.d.ts +106 -0
  386. package/dist/utils/icons.js +157 -0
  387. package/dist/utils/logger.d.ts +47 -0
  388. package/dist/utils/logger.js +72 -0
  389. package/dist/utils/nodeStatus.d.ts +53 -0
  390. package/dist/utils/nodeStatus.js +183 -0
  391. package/dist/utils/nodeTypes.d.ts +117 -0
  392. package/dist/utils/nodeTypes.js +244 -0
  393. package/dist/utils/nodeWrapper.d.ts +39 -0
  394. package/dist/utils/nodeWrapper.js +62 -0
  395. package/dist/utils/performanceUtils.d.ts +30 -0
  396. package/dist/utils/performanceUtils.js +108 -0
  397. package/dist/utils/sanitize.d.ts +19 -0
  398. package/dist/utils/sanitize.js +31 -0
  399. package/dist/utils/uischema.d.ts +52 -0
  400. package/dist/utils/uischema.js +88 -0
  401. package/dist/utils/validation.d.ts +29 -0
  402. package/dist/utils/validation.js +39 -0
  403. package/package.json +292 -0
@@ -0,0 +1,905 @@
1
+ <!--
2
+ ChatPanel Component
3
+
4
+ Clean conversational chat interface for the playground.
5
+ Displays messages with chat bubbles and includes a simple input area.
6
+ Styled with BEM syntax for a Langflow-like appearance.
7
+ -->
8
+
9
+ <script lang="ts">
10
+ import Icon from '@iconify/svelte';
11
+ import { tick } from 'svelte';
12
+ import MessageBubble from './MessageBubble.svelte';
13
+ import { InterruptBubble } from '../interrupt/index.js';
14
+ import type { PlaygroundMessage } from '../../types/playground.js';
15
+ import { hasEnableRunFlag } from '../../types/playground.js';
16
+ import {
17
+ isInterruptMetadata,
18
+ extractInterruptMetadata,
19
+ metadataToInterrupt
20
+ } from '../../types/interrupt.js';
21
+ import {
22
+ getMessages,
23
+ getChatMessages,
24
+ getIsExecuting,
25
+ getSessionStatus,
26
+ getCurrentSession
27
+ } from '../../stores/playgroundStore.svelte.js';
28
+ import {
29
+ getInterruptsMap,
30
+ interruptActions,
31
+ getInterruptByMessageId
32
+ } from '../../stores/interruptStore.svelte.js';
33
+
34
+ /**
35
+ * Component props
36
+ */
37
+ interface Props {
38
+ /** Whether to show timestamps on messages */
39
+ showTimestamps?: boolean;
40
+ /** Whether to auto-scroll to bottom on new messages */
41
+ autoScroll?: boolean;
42
+ /** Placeholder text for the input */
43
+ placeholder?: string;
44
+ /** Callback when user sends a message */
45
+ onSendMessage?: (content: string) => void;
46
+ /** Callback when user requests to stop execution */
47
+ onStopExecution?: () => void;
48
+ /** Whether to show log messages inline (false = hide them) */
49
+ showLogsInline?: boolean;
50
+ /** Whether to enable markdown rendering in messages */
51
+ enableMarkdown?: boolean;
52
+ /** Callback when an interrupt is resolved (to refresh messages) */
53
+ onInterruptResolved?: () => void;
54
+ /**
55
+ * Whether to show the chat text input (default: true)
56
+ * When false, only the "Run" button is displayed.
57
+ */
58
+ showChatInput?: boolean;
59
+ /**
60
+ * Whether to show the "Run" button (default: true)
61
+ * When false, the Run button is hidden.
62
+ */
63
+ showRunButton?: boolean;
64
+ /**
65
+ * Predefined message to send when "Run" button is clicked
66
+ * Used when showChatInput is false.
67
+ */
68
+ predefinedMessage?: string;
69
+ /**
70
+ * Whether to display system messages in compact mode.
71
+ * When true, system messages appear as minimal inline text
72
+ * instead of full chat bubbles to reduce visual noise.
73
+ * @default true
74
+ */
75
+ compactSystemMessages?: boolean;
76
+ }
77
+
78
+ let {
79
+ showTimestamps = true,
80
+ autoScroll = true,
81
+ placeholder = 'Type your message...',
82
+ onSendMessage,
83
+ onStopExecution,
84
+ showLogsInline = false,
85
+ enableMarkdown = true,
86
+ onInterruptResolved,
87
+ showChatInput = true,
88
+ showRunButton = true,
89
+ predefinedMessage = 'Run workflow',
90
+ compactSystemMessages = true
91
+ }: Props = $props();
92
+
93
+ /**
94
+ * Tracks whether the Run button is enabled.
95
+ * Starts as true, becomes false after Run is clicked,
96
+ * and is re-enabled when backend sends a message with enableRun: true metadata.
97
+ */
98
+ let runEnabled = $state(true);
99
+
100
+ /**
101
+ * Computed flag: true if both chat input and run button are hidden.
102
+ * In this case, we show a helpful message to the user.
103
+ */
104
+ const noInputsAvailable = $derived(!showChatInput && !showRunButton);
105
+
106
+ /** Input field value */
107
+ let inputValue = $state('');
108
+
109
+ /** Reference to the messages container for scrolling */
110
+ let messagesContainer = $state<HTMLDivElement>();
111
+
112
+ /** Reference to the input field */
113
+ let inputField = $state<HTMLTextAreaElement>();
114
+
115
+ /**
116
+ * Filter messages based on showLogsInline setting
117
+ */
118
+ const displayMessages = $derived(showLogsInline ? getMessages() : getChatMessages());
119
+
120
+ /**
121
+ * Track previous message count for detecting new messages.
122
+ * We only want to auto-scroll when NEW messages are added,
123
+ * not when existing messages are updated.
124
+ */
125
+ let previousMessageCount = $state(0);
126
+
127
+ /**
128
+ * Check if user is near the bottom of the scroll container.
129
+ * Used to determine if we should auto-scroll when new messages arrive.
130
+ * If user has scrolled up to read previous messages, we don't interrupt them.
131
+ *
132
+ * @param threshold - Pixels from bottom to consider "near bottom"
133
+ * @returns True if user is within threshold of the bottom
134
+ */
135
+ function isNearBottom(threshold: number = 100): boolean {
136
+ if (!messagesContainer) return true;
137
+ const { scrollTop, scrollHeight, clientHeight } = messagesContainer;
138
+ return scrollHeight - scrollTop - clientHeight <= threshold;
139
+ }
140
+
141
+ /**
142
+ * Check if a form element inside the messages container has focus.
143
+ * When user is interacting with a form (e.g., interrupt prompt),
144
+ * we should not auto-scroll as it disrupts their input.
145
+ */
146
+ function isFormFocused(): boolean {
147
+ if (!messagesContainer) return false;
148
+ const activeElement = document.activeElement;
149
+ if (!activeElement) return false;
150
+ // Check if active element is a form control inside the messages container
151
+ const isFormControl =
152
+ activeElement.tagName === 'INPUT' ||
153
+ activeElement.tagName === 'TEXTAREA' ||
154
+ activeElement.tagName === 'SELECT' ||
155
+ activeElement.tagName === 'BUTTON' ||
156
+ activeElement.getAttribute('contenteditable') === 'true';
157
+ return isFormControl && messagesContainer.contains(activeElement);
158
+ }
159
+
160
+ /**
161
+ * Check if a message is an interrupt request
162
+ */
163
+ function isInterruptMessage(message: PlaygroundMessage): boolean {
164
+ return isInterruptMetadata(message.metadata as Record<string, unknown> | undefined);
165
+ }
166
+
167
+ /**
168
+ * Sync interrupt messages to the interrupt store.
169
+ * This effect runs when messages change and adds any new interrupt messages
170
+ * to the interrupt store. We do this in an effect rather than during render
171
+ * to avoid Svelte 5's state_unsafe_mutation error.
172
+ *
173
+ * If a message has status 'completed', the interrupt is marked as resolved
174
+ * to show the "Confirmation Submitted" header, disabled buttons, and
175
+ * "Response submitted" indicator.
176
+ */
177
+ $effect(() => {
178
+ // Get all messages that are interrupt requests
179
+ const interruptMessages = displayMessages.filter(isInterruptMessage);
180
+
181
+ for (const message of interruptMessages) {
182
+ // Check if we already have this interrupt in the store
183
+ const existing = getInterruptByMessageId(message.id);
184
+ if (!existing) {
185
+ // Extract and validate interrupt metadata
186
+ const metadata = extractInterruptMetadata(
187
+ message.metadata as Record<string, unknown> | undefined
188
+ );
189
+ if (metadata) {
190
+ const interrupt = metadataToInterrupt(metadata, message.id, message.content);
191
+ interruptActions.addInterrupt(interrupt);
192
+
193
+ // If the message status is 'completed', mark the interrupt as resolved
194
+ // This ensures completed interrupts show proper UI state:
195
+ // - "Confirmation Submitted" header
196
+ // - Disabled buttons
197
+ // - "Response submitted" indicator
198
+ if (message.status === 'completed') {
199
+ interruptActions.resolveInterrupt(interrupt.id, metadata.response_value);
200
+ }
201
+ }
202
+ }
203
+ }
204
+ });
205
+
206
+ /**
207
+ * Reactive map of message IDs to interrupts.
208
+ * This ensures the component re-renders when interrupts are added to the store.
209
+ */
210
+ const interruptsByMessageId = $derived(
211
+ new Map(
212
+ Array.from(getInterruptsMap().values())
213
+ .filter((i) => i.messageId)
214
+ .map((i) => [i.messageId, i])
215
+ )
216
+ );
217
+
218
+ /**
219
+ * Get interrupt data for a message from the reactive map
220
+ */
221
+ function getInterruptForMessage(message: PlaygroundMessage) {
222
+ return interruptsByMessageId.get(message.id);
223
+ }
224
+
225
+ /**
226
+ * Check if we should show the welcome state
227
+ */
228
+ const showWelcome = $derived(!getCurrentSession() && displayMessages.length === 0);
229
+
230
+ /**
231
+ * Check if we should show the empty chat state (session exists but no messages)
232
+ */
233
+ const showEmptyChat = $derived(getCurrentSession() && displayMessages.length === 0);
234
+
235
+ /**
236
+ * Handle sending a message
237
+ */
238
+ function handleSend(): void {
239
+ const trimmedValue = inputValue.trim();
240
+ if (!trimmedValue || getIsExecuting()) {
241
+ return;
242
+ }
243
+
244
+ onSendMessage?.(trimmedValue);
245
+ inputValue = '';
246
+
247
+ // Reset textarea height
248
+ if (inputField) {
249
+ inputField.style.height = 'auto';
250
+ }
251
+
252
+ // Re-focus the input
253
+ tick().then(() => {
254
+ inputField?.focus();
255
+ });
256
+ }
257
+
258
+ /**
259
+ * Handle keyboard events in the input
260
+ */
261
+ function handleKeydown(event: KeyboardEvent): void {
262
+ if (event.key === 'Enter' && !event.shiftKey) {
263
+ event.preventDefault();
264
+ handleSend();
265
+ }
266
+ }
267
+
268
+ /**
269
+ * Handle stop execution
270
+ */
271
+ function handleStop(): void {
272
+ onStopExecution?.();
273
+ }
274
+
275
+ /**
276
+ * Handle "Run" button click when chat input is hidden.
277
+ * Sends the predefined message to execute the workflow.
278
+ * Disables the Run button after clicking until backend re-enables it.
279
+ */
280
+ function handleRun(): void {
281
+ if (getIsExecuting() || !runEnabled) {
282
+ return;
283
+ }
284
+ // Disable the Run button after clicking
285
+ runEnabled = false;
286
+ onSendMessage?.(predefinedMessage);
287
+ }
288
+
289
+ /**
290
+ * Track processed message IDs for enableRun detection
291
+ * to avoid re-processing the same messages.
292
+ */
293
+ let processedEnableRunIds = $state(new Set<string>());
294
+
295
+ /**
296
+ * Watch for messages with enableRun: true metadata from the backend.
297
+ * When detected, re-enable the Run button.
298
+ */
299
+ $effect(() => {
300
+ // Check all messages for enableRun flag
301
+ for (const message of displayMessages) {
302
+ // Skip if already processed
303
+ if (processedEnableRunIds.has(message.id)) {
304
+ continue;
305
+ }
306
+ // Check if this message has the enableRun flag
307
+ if (hasEnableRunFlag(message.metadata)) {
308
+ // Mark as processed
309
+ processedEnableRunIds = new Set([...processedEnableRunIds, message.id]);
310
+ // Re-enable the Run button
311
+ runEnabled = true;
312
+ }
313
+ }
314
+ });
315
+
316
+ /**
317
+ * Reset runEnabled state when session changes.
318
+ * This ensures a fresh state for each session.
319
+ */
320
+ $effect(() => {
321
+ const session = getCurrentSession();
322
+ if (session) {
323
+ // Reset to enabled state for new/changed sessions
324
+ runEnabled = true;
325
+ // Clear processed IDs for the new session
326
+ processedEnableRunIds = new Set();
327
+ }
328
+ });
329
+
330
+ /**
331
+ * Smart auto-scroll to bottom when NEW messages are added.
332
+ *
333
+ * Only scrolls if:
334
+ * 1. autoScroll prop is enabled
335
+ * 2. New messages were actually added (not just updates)
336
+ * 3. User is already near the bottom (hasn't scrolled up to read)
337
+ * 4. User is not interacting with a form inside the chat
338
+ *
339
+ * This prevents disruptive scrolling when:
340
+ * - User is reading previous messages
341
+ * - User is filling out an interrupt form
342
+ * - Messages are being updated (e.g., status changes)
343
+ */
344
+ $effect(() => {
345
+ const currentCount = displayMessages.length;
346
+
347
+ // Skip if auto-scroll is disabled or no container
348
+ if (!autoScroll || !messagesContainer) {
349
+ previousMessageCount = currentCount;
350
+ return;
351
+ }
352
+
353
+ // Check if this is a NEW message (count increased)
354
+ const hasNewMessage = currentCount > previousMessageCount;
355
+
356
+ // Update the tracked count
357
+ previousMessageCount = currentCount;
358
+
359
+ // Only scroll if there's a new message
360
+ if (!hasNewMessage) {
361
+ return;
362
+ }
363
+
364
+ // Don't scroll if user has scrolled up to read previous messages
365
+ if (!isNearBottom()) {
366
+ return;
367
+ }
368
+
369
+ // Don't scroll if user is interacting with a form
370
+ if (isFormFocused()) {
371
+ return;
372
+ }
373
+
374
+ // Safe to scroll to bottom
375
+ tick().then(() => {
376
+ if (messagesContainer) {
377
+ messagesContainer.scrollTop = messagesContainer.scrollHeight;
378
+ }
379
+ });
380
+ });
381
+
382
+ /**
383
+ * Track previous executing state to detect when execution completes
384
+ */
385
+ let wasExecuting = $state(false);
386
+
387
+ /**
388
+ * Auto-focus input when execution completes or session becomes ready
389
+ */
390
+ $effect(() => {
391
+ const currentlyExecuting = getIsExecuting();
392
+
393
+ // Focus input when execution completes (was executing, now not)
394
+ if (wasExecuting && !currentlyExecuting && inputField) {
395
+ tick().then(() => {
396
+ inputField?.focus();
397
+ });
398
+ }
399
+
400
+ // Update tracking state
401
+ wasExecuting = currentlyExecuting;
402
+ });
403
+
404
+ /**
405
+ * Focus input when session status changes to idle or completed
406
+ */
407
+ $effect(() => {
408
+ const status = getSessionStatus();
409
+ if ((status === 'idle' || status === 'completed') && inputField && !getIsExecuting()) {
410
+ tick().then(() => {
411
+ inputField?.focus();
412
+ });
413
+ }
414
+ });
415
+
416
+ /**
417
+ * Focus input when a new session is created/loaded
418
+ */
419
+ $effect(() => {
420
+ const session = getCurrentSession();
421
+ if (session && inputField && !getIsExecuting()) {
422
+ tick().then(() => {
423
+ inputField?.focus();
424
+ });
425
+ }
426
+ });
427
+
428
+ /**
429
+ * Auto-resize textarea based on content
430
+ */
431
+ function handleInput(): void {
432
+ if (inputField) {
433
+ inputField.style.height = 'auto';
434
+ inputField.style.height = `${Math.min(inputField.scrollHeight, 120)}px`;
435
+ }
436
+ }
437
+ </script>
438
+
439
+ <div class="chat-panel">
440
+ <!-- Messages Container -->
441
+ <div class="chat-panel__messages" bind:this={messagesContainer}>
442
+ {#if showWelcome}
443
+ <!-- Welcome State (no session) -->
444
+ <div class="chat-panel__welcome">
445
+ <div class="chat-panel__welcome-icon">
446
+ <svg
447
+ width="48"
448
+ height="48"
449
+ viewBox="0 0 48 48"
450
+ fill="none"
451
+ xmlns="http://www.w3.org/2000/svg"
452
+ >
453
+ <path
454
+ d="M8 16L24 8L40 16V32L24 40L8 32V16Z"
455
+ stroke="currentColor"
456
+ stroke-width="2"
457
+ stroke-linejoin="round"
458
+ />
459
+ <path
460
+ d="M8 16L24 24L40 16"
461
+ stroke="currentColor"
462
+ stroke-width="2"
463
+ stroke-linejoin="round"
464
+ />
465
+ <path d="M24 24V40" stroke="currentColor" stroke-width="2" stroke-linejoin="round" />
466
+ <path d="M16 12L32 20" stroke="currentColor" stroke-width="2" stroke-linejoin="round" />
467
+ <path d="M16 36L32 28" stroke="currentColor" stroke-width="2" stroke-linejoin="round" />
468
+ </svg>
469
+ </div>
470
+ {#if noInputsAvailable}
471
+ <h2 class="chat-panel__welcome-title">View only</h2>
472
+ <p class="chat-panel__welcome-text">
473
+ This playground is in view-only mode. No inputs are available.
474
+ </p>
475
+ {:else if showChatInput}
476
+ <h2 class="chat-panel__welcome-title">New session</h2>
477
+ <p class="chat-panel__welcome-text">Test your flow with a prompt</p>
478
+ {:else}
479
+ <h2 class="chat-panel__welcome-title">Ready to run</h2>
480
+ <p class="chat-panel__welcome-text">Click Run to execute your workflow</p>
481
+ {/if}
482
+ </div>
483
+ {:else if showEmptyChat}
484
+ <!-- Empty Chat State (session exists but no messages) -->
485
+ <div class="chat-panel__welcome">
486
+ <div class="chat-panel__welcome-icon">
487
+ <svg
488
+ width="48"
489
+ height="48"
490
+ viewBox="0 0 48 48"
491
+ fill="none"
492
+ xmlns="http://www.w3.org/2000/svg"
493
+ >
494
+ <path
495
+ d="M8 16L24 8L40 16V32L24 40L8 32V16Z"
496
+ stroke="currentColor"
497
+ stroke-width="2"
498
+ stroke-linejoin="round"
499
+ />
500
+ <path
501
+ d="M8 16L24 24L40 16"
502
+ stroke="currentColor"
503
+ stroke-width="2"
504
+ stroke-linejoin="round"
505
+ />
506
+ <path d="M24 24V40" stroke="currentColor" stroke-width="2" stroke-linejoin="round" />
507
+ <path d="M16 12L32 20" stroke="currentColor" stroke-width="2" stroke-linejoin="round" />
508
+ <path d="M16 36L32 28" stroke="currentColor" stroke-width="2" stroke-linejoin="round" />
509
+ </svg>
510
+ </div>
511
+ {#if noInputsAvailable}
512
+ <h2 class="chat-panel__welcome-title">View only</h2>
513
+ <p class="chat-panel__welcome-text">
514
+ This playground is in view-only mode. No inputs are available.
515
+ </p>
516
+ {:else if showChatInput}
517
+ <h2 class="chat-panel__welcome-title">New session</h2>
518
+ <p class="chat-panel__welcome-text">Test your flow with a prompt</p>
519
+ {:else}
520
+ <h2 class="chat-panel__welcome-title">Ready to run</h2>
521
+ <p class="chat-panel__welcome-text">Click Run to execute your workflow</p>
522
+ {/if}
523
+ </div>
524
+ {:else}
525
+ <!-- Messages -->
526
+ {#each displayMessages as message, index (message.id)}
527
+ {#if isInterruptMessage(message)}
528
+ <!-- Render interrupt inline -->
529
+ {@const interrupt = getInterruptForMessage(message)}
530
+ {#if interrupt}
531
+ <InterruptBubble
532
+ {interrupt}
533
+ showTimestamp={showTimestamps}
534
+ onResolved={onInterruptResolved}
535
+ />
536
+ {/if}
537
+ {:else}
538
+ <MessageBubble
539
+ {message}
540
+ showTimestamp={showTimestamps}
541
+ isLast={index === displayMessages.length - 1}
542
+ {enableMarkdown}
543
+ {compactSystemMessages}
544
+ />
545
+ {/if}
546
+ {/each}
547
+
548
+ {#if getIsExecuting()}
549
+ <div class="chat-panel__typing">
550
+ <div class="chat-panel__typing-indicator">
551
+ <span></span>
552
+ <span></span>
553
+ <span></span>
554
+ </div>
555
+ <span class="chat-panel__typing-text">Processing...</span>
556
+ </div>
557
+ {/if}
558
+ {/if}
559
+ </div>
560
+
561
+ <!-- Input Area -->
562
+ <div class="chat-panel__input-area">
563
+ {#if noInputsAvailable}
564
+ <!-- No inputs available - show informational message -->
565
+ <div class="chat-panel__no-inputs">
566
+ <Icon icon="mdi:information-outline" />
567
+ <span>View-only mode. Workflow execution is controlled externally.</span>
568
+ </div>
569
+ {:else}
570
+ <div
571
+ class="chat-panel__input-container"
572
+ class:chat-panel__input-container--run-only={!showChatInput}
573
+ >
574
+ {#if showChatInput}
575
+ <div class="chat-panel__input-wrapper">
576
+ <textarea
577
+ bind:this={inputField}
578
+ bind:value={inputValue}
579
+ class="chat-panel__input"
580
+ {placeholder}
581
+ rows="1"
582
+ disabled={getIsExecuting()}
583
+ onkeydown={handleKeydown}
584
+ oninput={handleInput}
585
+ ></textarea>
586
+ </div>
587
+ {/if}
588
+
589
+ {#if getSessionStatus() === 'running' || getIsExecuting()}
590
+ <button
591
+ type="button"
592
+ class="chat-panel__stop-btn"
593
+ onclick={handleStop}
594
+ title="Stop execution"
595
+ >
596
+ <Icon icon="mdi:stop" />
597
+ Stop
598
+ </button>
599
+ {:else if showChatInput}
600
+ <button
601
+ type="button"
602
+ class="chat-panel__send-btn"
603
+ onclick={handleSend}
604
+ disabled={!inputValue.trim()}
605
+ title="Send message"
606
+ >
607
+ Send
608
+ </button>
609
+ {:else if showRunButton}
610
+ <button
611
+ type="button"
612
+ class="chat-panel__run-btn"
613
+ onclick={handleRun}
614
+ disabled={!runEnabled}
615
+ title={runEnabled ? 'Run workflow' : 'Waiting for workflow to be ready...'}
616
+ >
617
+ <Icon icon="mdi:play" />
618
+ Run
619
+ </button>
620
+ {/if}
621
+ </div>
622
+ {/if}
623
+ </div>
624
+ </div>
625
+
626
+ <style>
627
+ .chat-panel {
628
+ display: flex;
629
+ flex-direction: column;
630
+ height: 100%;
631
+ min-height: 0; /* Critical: allows flexbox to shrink properly */
632
+ background-color: var(--fd-background);
633
+ }
634
+
635
+ /* Messages Container - Scrollable area that takes remaining space */
636
+ .chat-panel__messages {
637
+ flex: 1;
638
+ min-height: 0; /* Critical: allows overflow to work in flex container */
639
+ overflow-y: auto;
640
+ padding: var(--fd-space-3xl);
641
+ scroll-behavior: smooth;
642
+ }
643
+
644
+ /* Welcome State */
645
+ .chat-panel__welcome {
646
+ display: flex;
647
+ flex-direction: column;
648
+ align-items: center;
649
+ justify-content: center;
650
+ height: 100%;
651
+ text-align: center;
652
+ padding: var(--fd-space-4xl);
653
+ }
654
+
655
+ .chat-panel__welcome-icon {
656
+ display: flex;
657
+ align-items: center;
658
+ justify-content: center;
659
+ width: 80px;
660
+ height: 80px;
661
+ margin-bottom: var(--fd-space-3xl);
662
+ color: var(--fd-foreground);
663
+ }
664
+
665
+ .chat-panel__welcome-icon svg {
666
+ width: 100%;
667
+ height: 100%;
668
+ }
669
+
670
+ .chat-panel__welcome-title {
671
+ font-size: var(--fd-text-2xl);
672
+ font-weight: 600;
673
+ color: var(--fd-foreground);
674
+ margin: 0 0 var(--fd-space-xs) 0;
675
+ }
676
+
677
+ .chat-panel__welcome-text {
678
+ font-size: var(--fd-text-base);
679
+ color: var(--fd-muted-foreground);
680
+ margin: 0;
681
+ }
682
+
683
+ /* Typing Indicator */
684
+ .chat-panel__typing {
685
+ display: flex;
686
+ align-items: center;
687
+ gap: var(--fd-space-xs);
688
+ padding: var(--fd-space-md) var(--fd-space-xl);
689
+ margin-top: var(--fd-space-xs);
690
+ background-color: var(--fd-muted);
691
+ border-radius: var(--fd-radius-2xl);
692
+ width: fit-content;
693
+ }
694
+
695
+ .chat-panel__typing-indicator {
696
+ display: flex;
697
+ gap: var(--fd-space-3xs);
698
+ }
699
+
700
+ .chat-panel__typing-indicator span {
701
+ width: var(--fd-space-2xs);
702
+ height: var(--fd-space-2xs);
703
+ background-color: var(--fd-muted-foreground);
704
+ border-radius: var(--fd-radius-full);
705
+ animation: bounce 1.4s ease-in-out infinite;
706
+ }
707
+
708
+ .chat-panel__typing-indicator span:nth-child(1) {
709
+ animation-delay: 0s;
710
+ }
711
+
712
+ .chat-panel__typing-indicator span:nth-child(2) {
713
+ animation-delay: 0.2s;
714
+ }
715
+
716
+ .chat-panel__typing-indicator span:nth-child(3) {
717
+ animation-delay: 0.4s;
718
+ }
719
+
720
+ @keyframes bounce {
721
+ 0%,
722
+ 60%,
723
+ 100% {
724
+ transform: translateY(0);
725
+ }
726
+ 30% {
727
+ transform: translateY(-0.25rem);
728
+ }
729
+ }
730
+
731
+ .chat-panel__typing-text {
732
+ font-size: var(--fd-text-sm);
733
+ color: var(--fd-muted-foreground);
734
+ }
735
+
736
+ /* Input Area - Always stays at bottom, never shrinks */
737
+ .chat-panel__input-area {
738
+ flex-shrink: 0;
739
+ padding: var(--fd-space-xl) var(--fd-space-3xl) var(--fd-space-3xl);
740
+ background-color: var(--fd-background);
741
+ border-top: 1px solid var(--fd-border-muted);
742
+ }
743
+
744
+ .chat-panel__input-container {
745
+ display: flex;
746
+ align-items: flex-end;
747
+ gap: var(--fd-space-md);
748
+ max-width: 800px;
749
+ margin: 0 auto;
750
+ }
751
+
752
+ .chat-panel__input-wrapper {
753
+ flex: 1;
754
+ display: flex;
755
+ align-items: flex-end;
756
+ background-color: var(--fd-background);
757
+ border: 1px solid var(--fd-border);
758
+ border-radius: var(--fd-radius-xl);
759
+ padding: var(--fd-space-sm) var(--fd-space-md);
760
+ transition:
761
+ border-color var(--fd-transition-fast),
762
+ box-shadow var(--fd-transition-fast);
763
+ }
764
+
765
+ .chat-panel__input-wrapper:focus-within {
766
+ border-color: var(--fd-primary);
767
+ box-shadow: 0 0 0 3px var(--fd-primary-muted);
768
+ }
769
+
770
+ .chat-panel__input {
771
+ flex: 1;
772
+ border: none;
773
+ outline: none;
774
+ resize: none;
775
+ font-family: inherit;
776
+ font-size: var(--fd-text-base);
777
+ line-height: var(--fd-leading-normal);
778
+ max-height: 120px;
779
+ background: transparent;
780
+ color: var(--fd-foreground);
781
+ }
782
+
783
+ .chat-panel__input::placeholder {
784
+ color: var(--fd-muted-foreground);
785
+ }
786
+
787
+ .chat-panel__input:disabled {
788
+ cursor: not-allowed;
789
+ opacity: 0.6;
790
+ }
791
+
792
+ .chat-panel__send-btn {
793
+ display: flex;
794
+ align-items: center;
795
+ justify-content: center;
796
+ padding: var(--fd-space-sm) var(--fd-space-2xl);
797
+ border: none;
798
+ border-radius: var(--fd-radius-lg);
799
+ background-color: var(--fd-foreground);
800
+ color: var(--fd-background);
801
+ font-size: var(--fd-text-sm);
802
+ font-weight: 500;
803
+ cursor: pointer;
804
+ transition: all var(--fd-transition-fast);
805
+ flex-shrink: 0;
806
+ }
807
+
808
+ .chat-panel__send-btn:hover:not(:disabled) {
809
+ opacity: 0.85;
810
+ }
811
+
812
+ .chat-panel__send-btn:disabled {
813
+ background-color: var(--fd-border);
814
+ color: var(--fd-muted-foreground);
815
+ cursor: not-allowed;
816
+ }
817
+
818
+ .chat-panel__stop-btn {
819
+ display: flex;
820
+ align-items: center;
821
+ gap: var(--fd-space-3xs);
822
+ padding: var(--fd-space-sm) var(--fd-space-xl);
823
+ border: none;
824
+ border-radius: var(--fd-radius-lg);
825
+ background-color: var(--fd-error);
826
+ color: var(--fd-error-foreground);
827
+ font-size: var(--fd-text-sm);
828
+ font-weight: 500;
829
+ cursor: pointer;
830
+ transition: background-color var(--fd-transition-fast);
831
+ flex-shrink: 0;
832
+ }
833
+
834
+ .chat-panel__stop-btn:hover {
835
+ background-color: var(--fd-error-hover);
836
+ }
837
+
838
+ /* Run button (when chat input is hidden) */
839
+ .chat-panel__run-btn {
840
+ display: flex;
841
+ align-items: center;
842
+ gap: var(--fd-space-3xs);
843
+ padding: var(--fd-space-sm) var(--fd-space-2xl);
844
+ border: none;
845
+ border-radius: var(--fd-radius-lg);
846
+ background-color: var(--fd-success);
847
+ color: var(--fd-success-foreground);
848
+ font-size: var(--fd-text-sm);
849
+ font-weight: 500;
850
+ cursor: pointer;
851
+ transition: all var(--fd-transition-fast);
852
+ flex-shrink: 0;
853
+ }
854
+
855
+ .chat-panel__run-btn:hover:not(:disabled) {
856
+ background-color: var(--fd-success-hover);
857
+ }
858
+
859
+ .chat-panel__run-btn:disabled {
860
+ background-color: var(--fd-border);
861
+ color: var(--fd-muted-foreground);
862
+ cursor: not-allowed;
863
+ }
864
+
865
+ /* Container modifier for run-only mode (no text input) */
866
+ .chat-panel__input-container--run-only {
867
+ justify-content: flex-end;
868
+ }
869
+
870
+ /* No inputs available message (view-only mode) */
871
+ .chat-panel__no-inputs {
872
+ display: flex;
873
+ align-items: center;
874
+ justify-content: center;
875
+ gap: var(--fd-space-xs);
876
+ padding: var(--fd-space-md) var(--fd-space-xl);
877
+ background-color: var(--fd-muted);
878
+ border-radius: var(--fd-radius-lg);
879
+ color: var(--fd-muted-foreground);
880
+ font-size: var(--fd-text-sm);
881
+ max-width: 800px;
882
+ margin: 0 auto;
883
+ }
884
+
885
+ /* Responsive */
886
+ @media (max-width: 640px) {
887
+ .chat-panel__messages {
888
+ padding: var(--fd-space-xl);
889
+ }
890
+
891
+ .chat-panel__input-area {
892
+ padding: var(--fd-space-md) var(--fd-space-xl) var(--fd-space-xl);
893
+ }
894
+
895
+ .chat-panel__input-container {
896
+ gap: var(--fd-space-xs);
897
+ }
898
+
899
+ .chat-panel__send-btn,
900
+ .chat-panel__stop-btn,
901
+ .chat-panel__run-btn {
902
+ padding: var(--fd-space-xs) var(--fd-space-xl);
903
+ }
904
+ }
905
+ </style>