agent-orcha 0.0.5 → 0.0.8

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 (404) hide show
  1. package/README.md +250 -1275
  2. package/dist/lib/agents/agent-executor.d.ts +4 -2
  3. package/dist/lib/agents/agent-executor.d.ts.map +1 -1
  4. package/dist/lib/agents/agent-executor.js +85 -53
  5. package/dist/lib/agents/agent-executor.js.map +1 -1
  6. package/dist/lib/agents/agent-loader.d.ts +3 -0
  7. package/dist/lib/agents/agent-loader.d.ts.map +1 -1
  8. package/dist/lib/agents/agent-loader.js +10 -1
  9. package/dist/lib/agents/agent-loader.js.map +1 -1
  10. package/dist/lib/agents/react-loop.d.ts.map +1 -1
  11. package/dist/lib/agents/react-loop.js +207 -142
  12. package/dist/lib/agents/react-loop.js.map +1 -1
  13. package/dist/lib/agents/types.d.ts +181 -18
  14. package/dist/lib/agents/types.d.ts.map +1 -1
  15. package/dist/lib/agents/types.js +18 -2
  16. package/dist/lib/agents/types.js.map +1 -1
  17. package/dist/lib/functions/function-loader.d.ts +2 -0
  18. package/dist/lib/functions/function-loader.d.ts.map +1 -1
  19. package/dist/lib/functions/function-loader.js +10 -0
  20. package/dist/lib/functions/function-loader.js.map +1 -1
  21. package/dist/lib/functions/simple-function-wrapper.js +3 -3
  22. package/dist/lib/functions/simple-function-wrapper.js.map +1 -1
  23. package/dist/lib/integrations/email.d.ts +38 -0
  24. package/dist/lib/integrations/email.d.ts.map +1 -0
  25. package/dist/lib/integrations/email.js +249 -0
  26. package/dist/lib/integrations/email.js.map +1 -0
  27. package/dist/lib/integrations/integration-manager.d.ts +5 -0
  28. package/dist/lib/integrations/integration-manager.d.ts.map +1 -1
  29. package/dist/lib/integrations/integration-manager.js +53 -3
  30. package/dist/lib/integrations/integration-manager.js.map +1 -1
  31. package/dist/lib/integrations/types.d.ts +187 -4
  32. package/dist/lib/integrations/types.d.ts.map +1 -1
  33. package/dist/lib/integrations/types.js +24 -1
  34. package/dist/lib/integrations/types.js.map +1 -1
  35. package/dist/lib/knowledge/knowledge-store.d.ts +7 -1
  36. package/dist/lib/knowledge/knowledge-store.d.ts.map +1 -1
  37. package/dist/lib/knowledge/knowledge-store.js +96 -8
  38. package/dist/lib/knowledge/knowledge-store.js.map +1 -1
  39. package/dist/lib/knowledge/loaders/file-loaders.d.ts +8 -3
  40. package/dist/lib/knowledge/loaders/file-loaders.d.ts.map +1 -1
  41. package/dist/lib/knowledge/loaders/file-loaders.js +96 -75
  42. package/dist/lib/knowledge/loaders/file-loaders.js.map +1 -1
  43. package/dist/lib/knowledge/loaders/web-loader.d.ts +12 -3
  44. package/dist/lib/knowledge/loaders/web-loader.d.ts.map +1 -1
  45. package/dist/lib/knowledge/loaders/web-loader.js +56 -22
  46. package/dist/lib/knowledge/loaders/web-loader.js.map +1 -1
  47. package/dist/lib/knowledge/sqlite-store.d.ts.map +1 -1
  48. package/dist/lib/knowledge/sqlite-store.js +19 -10
  49. package/dist/lib/knowledge/sqlite-store.js.map +1 -1
  50. package/dist/lib/knowledge/types.d.ts +69 -33
  51. package/dist/lib/knowledge/types.d.ts.map +1 -1
  52. package/dist/lib/knowledge/types.js +18 -3
  53. package/dist/lib/knowledge/types.js.map +1 -1
  54. package/dist/lib/llm/index.d.ts +1 -1
  55. package/dist/lib/llm/index.d.ts.map +1 -1
  56. package/dist/lib/llm/index.js +1 -1
  57. package/dist/lib/llm/index.js.map +1 -1
  58. package/dist/lib/llm/llm-call-logger.d.ts +3 -1
  59. package/dist/lib/llm/llm-call-logger.d.ts.map +1 -1
  60. package/dist/lib/llm/llm-call-logger.js +31 -26
  61. package/dist/lib/llm/llm-call-logger.js.map +1 -1
  62. package/dist/lib/llm/llm-config.d.ts +59 -8
  63. package/dist/lib/llm/llm-config.d.ts.map +1 -1
  64. package/dist/lib/llm/llm-config.js +163 -17
  65. package/dist/lib/llm/llm-config.js.map +1 -1
  66. package/dist/lib/llm/llm-factory.d.ts +1 -2
  67. package/dist/lib/llm/llm-factory.d.ts.map +1 -1
  68. package/dist/lib/llm/llm-factory.js +44 -8
  69. package/dist/lib/llm/llm-factory.js.map +1 -1
  70. package/dist/lib/llm/providers/anthropic-chat-model.d.ts +5 -1
  71. package/dist/lib/llm/providers/anthropic-chat-model.d.ts.map +1 -1
  72. package/dist/lib/llm/providers/anthropic-chat-model.js +118 -42
  73. package/dist/lib/llm/providers/anthropic-chat-model.js.map +1 -1
  74. package/dist/lib/llm/providers/gemini-chat-model.d.ts +3 -2
  75. package/dist/lib/llm/providers/gemini-chat-model.d.ts.map +1 -1
  76. package/dist/lib/llm/providers/gemini-chat-model.js +83 -24
  77. package/dist/lib/llm/providers/gemini-chat-model.js.map +1 -1
  78. package/dist/lib/llm/providers/openai-chat-model.d.ts +20 -1
  79. package/dist/lib/llm/providers/openai-chat-model.d.ts.map +1 -1
  80. package/dist/lib/llm/providers/openai-chat-model.js +265 -32
  81. package/dist/lib/llm/providers/openai-chat-model.js.map +1 -1
  82. package/dist/lib/llm/providers/openai-embeddings.d.ts.map +1 -1
  83. package/dist/lib/llm/providers/openai-embeddings.js +41 -10
  84. package/dist/lib/llm/providers/openai-embeddings.js.map +1 -1
  85. package/dist/lib/local-llm/binary-manager.d.ts +66 -0
  86. package/dist/lib/local-llm/binary-manager.d.ts.map +1 -0
  87. package/dist/lib/local-llm/binary-manager.js +441 -0
  88. package/dist/lib/local-llm/binary-manager.js.map +1 -0
  89. package/dist/lib/local-llm/engine-interface.d.ts +47 -0
  90. package/dist/lib/local-llm/engine-interface.d.ts.map +1 -0
  91. package/dist/lib/local-llm/engine-interface.js +2 -0
  92. package/dist/lib/local-llm/engine-interface.js.map +1 -0
  93. package/dist/lib/local-llm/engine-registry.d.ts +20 -0
  94. package/dist/lib/local-llm/engine-registry.d.ts.map +1 -0
  95. package/dist/lib/local-llm/engine-registry.js +56 -0
  96. package/dist/lib/local-llm/engine-registry.js.map +1 -0
  97. package/dist/lib/local-llm/engines/llama-cpp-engine.d.ts +31 -0
  98. package/dist/lib/local-llm/engines/llama-cpp-engine.d.ts.map +1 -0
  99. package/dist/lib/local-llm/engines/llama-cpp-engine.js +164 -0
  100. package/dist/lib/local-llm/engines/llama-cpp-engine.js.map +1 -0
  101. package/dist/lib/local-llm/engines/mlx-serve-engine.d.ts +31 -0
  102. package/dist/lib/local-llm/engines/mlx-serve-engine.d.ts.map +1 -0
  103. package/dist/lib/local-llm/engines/mlx-serve-engine.js +161 -0
  104. package/dist/lib/local-llm/engines/mlx-serve-engine.js.map +1 -0
  105. package/dist/lib/local-llm/gguf-reader.d.ts +20 -0
  106. package/dist/lib/local-llm/gguf-reader.d.ts.map +1 -0
  107. package/dist/lib/local-llm/gguf-reader.js +190 -0
  108. package/dist/lib/local-llm/gguf-reader.js.map +1 -0
  109. package/dist/lib/local-llm/index.d.ts +9 -0
  110. package/dist/lib/local-llm/index.d.ts.map +1 -0
  111. package/dist/lib/local-llm/index.js +6 -0
  112. package/dist/lib/local-llm/index.js.map +1 -0
  113. package/dist/lib/local-llm/llama-server-process.d.ts +42 -0
  114. package/dist/lib/local-llm/llama-server-process.d.ts.map +1 -0
  115. package/dist/lib/local-llm/llama-server-process.js +237 -0
  116. package/dist/lib/local-llm/llama-server-process.js.map +1 -0
  117. package/dist/lib/local-llm/mlx-binary-manager.d.ts +33 -0
  118. package/dist/lib/local-llm/mlx-binary-manager.d.ts.map +1 -0
  119. package/dist/lib/local-llm/mlx-binary-manager.js +211 -0
  120. package/dist/lib/local-llm/mlx-binary-manager.js.map +1 -0
  121. package/dist/lib/local-llm/mlx-server-process.d.ts +26 -0
  122. package/dist/lib/local-llm/mlx-server-process.d.ts.map +1 -0
  123. package/dist/lib/local-llm/mlx-server-process.js +210 -0
  124. package/dist/lib/local-llm/mlx-server-process.js.map +1 -0
  125. package/dist/lib/local-llm/model-manager.d.ts +33 -0
  126. package/dist/lib/local-llm/model-manager.d.ts.map +1 -0
  127. package/dist/lib/local-llm/model-manager.js +591 -0
  128. package/dist/lib/local-llm/model-manager.js.map +1 -0
  129. package/dist/lib/local-llm/types.d.ts +51 -0
  130. package/dist/lib/local-llm/types.d.ts.map +1 -0
  131. package/dist/lib/local-llm/types.js +2 -0
  132. package/dist/lib/local-llm/types.js.map +1 -0
  133. package/dist/lib/logger.d.ts +2 -0
  134. package/dist/lib/logger.d.ts.map +1 -1
  135. package/dist/lib/logger.js +68 -6
  136. package/dist/lib/logger.js.map +1 -1
  137. package/dist/lib/mcp/mcp-client.d.ts.map +1 -1
  138. package/dist/lib/mcp/mcp-client.js +5 -3
  139. package/dist/lib/mcp/mcp-client.js.map +1 -1
  140. package/dist/lib/mcp/types.d.ts +0 -9
  141. package/dist/lib/mcp/types.d.ts.map +1 -1
  142. package/dist/lib/mcp/types.js +1 -2
  143. package/dist/lib/mcp/types.js.map +1 -1
  144. package/dist/lib/memory/memory-manager.d.ts +1 -0
  145. package/dist/lib/memory/memory-manager.d.ts.map +1 -1
  146. package/dist/lib/memory/memory-manager.js +9 -0
  147. package/dist/lib/memory/memory-manager.js.map +1 -1
  148. package/dist/lib/orchestrator.d.ts +11 -8
  149. package/dist/lib/orchestrator.d.ts.map +1 -1
  150. package/dist/lib/orchestrator.js +246 -5
  151. package/dist/lib/orchestrator.js.map +1 -1
  152. package/dist/lib/sandbox/cdp-client.d.ts +15 -0
  153. package/dist/lib/sandbox/cdp-client.d.ts.map +1 -0
  154. package/dist/lib/sandbox/cdp-client.js +139 -0
  155. package/dist/lib/sandbox/cdp-client.js.map +1 -0
  156. package/dist/lib/sandbox/html-to-markdown.d.ts +9 -1
  157. package/dist/lib/sandbox/html-to-markdown.d.ts.map +1 -1
  158. package/dist/lib/sandbox/html-to-markdown.js +67 -10
  159. package/dist/lib/sandbox/html-to-markdown.js.map +1 -1
  160. package/dist/lib/sandbox/index.d.ts +6 -0
  161. package/dist/lib/sandbox/index.d.ts.map +1 -1
  162. package/dist/lib/sandbox/index.js +5 -0
  163. package/dist/lib/sandbox/index.js.map +1 -1
  164. package/dist/lib/sandbox/page-readiness.d.ts +37 -0
  165. package/dist/lib/sandbox/page-readiness.d.ts.map +1 -0
  166. package/dist/lib/sandbox/page-readiness.js +268 -0
  167. package/dist/lib/sandbox/page-readiness.js.map +1 -0
  168. package/dist/lib/sandbox/sandbox-browser.d.ts +4 -0
  169. package/dist/lib/sandbox/sandbox-browser.d.ts.map +1 -0
  170. package/dist/lib/sandbox/sandbox-browser.js +316 -0
  171. package/dist/lib/sandbox/sandbox-browser.js.map +1 -0
  172. package/dist/lib/sandbox/sandbox-container.d.ts +39 -0
  173. package/dist/lib/sandbox/sandbox-container.d.ts.map +1 -0
  174. package/dist/lib/sandbox/sandbox-container.js +176 -0
  175. package/dist/lib/sandbox/sandbox-container.js.map +1 -0
  176. package/dist/lib/sandbox/sandbox-file.d.ts +4 -0
  177. package/dist/lib/sandbox/sandbox-file.d.ts.map +1 -0
  178. package/dist/lib/sandbox/sandbox-file.js +169 -0
  179. package/dist/lib/sandbox/sandbox-file.js.map +1 -0
  180. package/dist/lib/sandbox/sandbox-shell.d.ts +5 -0
  181. package/dist/lib/sandbox/sandbox-shell.d.ts.map +1 -0
  182. package/dist/lib/sandbox/sandbox-shell.js +111 -0
  183. package/dist/lib/sandbox/sandbox-shell.js.map +1 -0
  184. package/dist/lib/sandbox/sandbox-web.d.ts.map +1 -1
  185. package/dist/lib/sandbox/sandbox-web.js +64 -24
  186. package/dist/lib/sandbox/sandbox-web.js.map +1 -1
  187. package/dist/lib/sandbox/types.d.ts +9 -0
  188. package/dist/lib/sandbox/types.d.ts.map +1 -1
  189. package/dist/lib/sandbox/types.js +1 -0
  190. package/dist/lib/sandbox/types.js.map +1 -1
  191. package/dist/lib/sandbox/vision-browser.d.ts +4 -0
  192. package/dist/lib/sandbox/vision-browser.d.ts.map +1 -0
  193. package/dist/lib/sandbox/vision-browser.js +298 -0
  194. package/dist/lib/sandbox/vision-browser.js.map +1 -0
  195. package/dist/lib/sea/app-window.d.ts +7 -0
  196. package/dist/lib/sea/app-window.d.ts.map +1 -0
  197. package/dist/lib/sea/app-window.js +95 -0
  198. package/dist/lib/sea/app-window.js.map +1 -0
  199. package/dist/lib/sea/bootstrap.d.ts +18 -0
  200. package/dist/lib/sea/bootstrap.d.ts.map +1 -0
  201. package/dist/lib/sea/bootstrap.js +103 -0
  202. package/dist/lib/sea/bootstrap.js.map +1 -0
  203. package/dist/lib/sea/sqlite-vec-shim.d.ts +3 -0
  204. package/dist/lib/sea/sqlite-vec-shim.d.ts.map +1 -0
  205. package/dist/lib/sea/sqlite-vec-shim.js +10 -0
  206. package/dist/lib/sea/sqlite-vec-shim.js.map +1 -0
  207. package/dist/lib/skills/skill-loader.d.ts +2 -0
  208. package/dist/lib/skills/skill-loader.d.ts.map +1 -1
  209. package/dist/lib/skills/skill-loader.js +12 -1
  210. package/dist/lib/skills/skill-loader.js.map +1 -1
  211. package/dist/lib/tasks/task-manager.d.ts +3 -1
  212. package/dist/lib/tasks/task-manager.d.ts.map +1 -1
  213. package/dist/lib/tasks/task-manager.js +11 -0
  214. package/dist/lib/tasks/task-manager.js.map +1 -1
  215. package/dist/lib/tasks/task-store.d.ts +1 -1
  216. package/dist/lib/tasks/task-store.d.ts.map +1 -1
  217. package/dist/lib/tasks/task-store.js.map +1 -1
  218. package/dist/lib/tasks/types.d.ts +18 -0
  219. package/dist/lib/tasks/types.d.ts.map +1 -1
  220. package/dist/lib/tools/built-in/integration-tools.d.ts +4 -0
  221. package/dist/lib/tools/built-in/integration-tools.d.ts.map +1 -0
  222. package/dist/lib/tools/built-in/integration-tools.js +47 -0
  223. package/dist/lib/tools/built-in/integration-tools.js.map +1 -0
  224. package/dist/lib/tools/built-in/knowledge-entity-lookup.tool.d.ts +1 -2
  225. package/dist/lib/tools/built-in/knowledge-entity-lookup.tool.d.ts.map +1 -1
  226. package/dist/lib/tools/built-in/knowledge-entity-lookup.tool.js +17 -17
  227. package/dist/lib/tools/built-in/knowledge-entity-lookup.tool.js.map +1 -1
  228. package/dist/lib/tools/built-in/knowledge-graph-schema.tool.d.ts.map +1 -1
  229. package/dist/lib/tools/built-in/knowledge-graph-schema.tool.js +2 -4
  230. package/dist/lib/tools/built-in/knowledge-graph-schema.tool.js.map +1 -1
  231. package/dist/lib/tools/built-in/knowledge-search.tool.js +4 -4
  232. package/dist/lib/tools/built-in/knowledge-search.tool.js.map +1 -1
  233. package/dist/lib/tools/built-in/knowledge-sql.tool.d.ts.map +1 -1
  234. package/dist/lib/tools/built-in/knowledge-sql.tool.js +74 -40
  235. package/dist/lib/tools/built-in/knowledge-sql.tool.js.map +1 -1
  236. package/dist/lib/tools/built-in/knowledge-tools-factory.js +2 -2
  237. package/dist/lib/tools/built-in/knowledge-tools-factory.js.map +1 -1
  238. package/dist/lib/tools/built-in/knowledge-traverse.tool.d.ts +1 -2
  239. package/dist/lib/tools/built-in/knowledge-traverse.tool.d.ts.map +1 -1
  240. package/dist/lib/tools/built-in/knowledge-traverse.tool.js +5 -11
  241. package/dist/lib/tools/built-in/knowledge-traverse.tool.js.map +1 -1
  242. package/dist/lib/tools/built-in/query-validators.d.ts.map +1 -1
  243. package/dist/lib/tools/built-in/query-validators.js +4 -0
  244. package/dist/lib/tools/built-in/query-validators.js.map +1 -1
  245. package/dist/lib/tools/workspace/workspace-tools.d.ts +1 -0
  246. package/dist/lib/tools/workspace/workspace-tools.d.ts.map +1 -1
  247. package/dist/lib/tools/workspace/workspace-tools.js +44 -4
  248. package/dist/lib/tools/workspace/workspace-tools.js.map +1 -1
  249. package/dist/lib/triggers/cron-trigger.d.ts +1 -1
  250. package/dist/lib/triggers/cron-trigger.d.ts.map +1 -1
  251. package/dist/lib/triggers/cron-trigger.js.map +1 -1
  252. package/dist/lib/triggers/trigger-manager.d.ts +1 -0
  253. package/dist/lib/triggers/trigger-manager.d.ts.map +1 -1
  254. package/dist/lib/triggers/trigger-manager.js +26 -0
  255. package/dist/lib/triggers/trigger-manager.js.map +1 -1
  256. package/dist/lib/triggers/webhook-trigger.d.ts +1 -1
  257. package/dist/lib/triggers/webhook-trigger.d.ts.map +1 -1
  258. package/dist/lib/triggers/webhook-trigger.js.map +1 -1
  259. package/dist/lib/types/llm-types.d.ts +22 -4
  260. package/dist/lib/types/llm-types.d.ts.map +1 -1
  261. package/dist/lib/types/llm-types.js +50 -0
  262. package/dist/lib/types/llm-types.js.map +1 -1
  263. package/dist/lib/types/tool-factory.d.ts +2 -2
  264. package/dist/lib/types/tool-factory.d.ts.map +1 -1
  265. package/dist/lib/types/tool-factory.js +9 -2
  266. package/dist/lib/types/tool-factory.js.map +1 -1
  267. package/dist/lib/utils/document-extract.d.ts +10 -0
  268. package/dist/lib/utils/document-extract.d.ts.map +1 -0
  269. package/dist/lib/utils/document-extract.js +149 -0
  270. package/dist/lib/utils/document-extract.js.map +1 -0
  271. package/dist/lib/utils/env-substitution.d.ts +6 -0
  272. package/dist/lib/utils/env-substitution.d.ts.map +1 -0
  273. package/dist/lib/utils/env-substitution.js +15 -0
  274. package/dist/lib/utils/env-substitution.js.map +1 -0
  275. package/dist/lib/workflows/react-workflow-executor.d.ts.map +1 -1
  276. package/dist/lib/workflows/react-workflow-executor.js +23 -17
  277. package/dist/lib/workflows/react-workflow-executor.js.map +1 -1
  278. package/dist/lib/workflows/types.d.ts +81 -55
  279. package/dist/lib/workflows/types.d.ts.map +1 -1
  280. package/dist/lib/workflows/types.js +10 -0
  281. package/dist/lib/workflows/types.js.map +1 -1
  282. package/dist/lib/workflows/workflow-loader.d.ts +3 -0
  283. package/dist/lib/workflows/workflow-loader.d.ts.map +1 -1
  284. package/dist/lib/workflows/workflow-loader.js +10 -1
  285. package/dist/lib/workflows/workflow-loader.js.map +1 -1
  286. package/dist/public/assets/logo.png +0 -0
  287. package/dist/public/chat.html +39 -0
  288. package/dist/public/index.html +6 -176
  289. package/dist/public/src/components/AgentComposer.js +807 -0
  290. package/dist/public/src/components/AgentsView.js +1812 -508
  291. package/dist/public/src/components/AppRoot.js +125 -38
  292. package/dist/public/src/components/GraphView.js +382 -300
  293. package/dist/public/src/components/IdeView.js +277 -86
  294. package/dist/public/src/components/KnowledgeView.js +94 -130
  295. package/dist/public/src/components/LlmView.js +15 -19
  296. package/dist/public/src/components/LocalLlmView.js +2440 -0
  297. package/dist/public/src/components/LogViewer.js +155 -0
  298. package/dist/public/src/components/McpView.js +41 -49
  299. package/dist/public/src/components/MonitorView.js +174 -83
  300. package/dist/public/src/components/NavBar.js +16 -26
  301. package/dist/public/src/components/StandaloneChat.js +875 -0
  302. package/dist/public/src/services/ApiService.js +203 -4
  303. package/dist/public/src/services/SessionStore.js +86 -0
  304. package/dist/public/src/services/StreamManager.js +183 -0
  305. package/dist/public/src/store.js +1 -3
  306. package/dist/public/src/utils/card.js +21 -0
  307. package/dist/public/src/utils/markdown.js +7 -0
  308. package/dist/public/styles.css +2777 -0
  309. package/dist/src/cli/commands/init.d.ts.map +1 -1
  310. package/dist/src/cli/commands/init.js +7 -1
  311. package/dist/src/cli/commands/init.js.map +1 -1
  312. package/dist/src/cli/commands/start.d.ts.map +1 -1
  313. package/dist/src/cli/commands/start.js +28 -5
  314. package/dist/src/cli/commands/start.js.map +1 -1
  315. package/dist/src/cli/index.js +19 -5
  316. package/dist/src/cli/index.js.map +1 -1
  317. package/dist/src/index.js +7 -1
  318. package/dist/src/index.js.map +1 -1
  319. package/dist/src/middleware/auth.d.ts.map +1 -1
  320. package/dist/src/middleware/auth.js +28 -6
  321. package/dist/src/middleware/auth.js.map +1 -1
  322. package/dist/src/middleware/rate-limit.d.ts +8 -0
  323. package/dist/src/middleware/rate-limit.d.ts.map +1 -0
  324. package/dist/src/middleware/rate-limit.js +21 -0
  325. package/dist/src/middleware/rate-limit.js.map +1 -0
  326. package/dist/src/routes/agents.route.d.ts.map +1 -1
  327. package/dist/src/routes/agents.route.js +138 -10
  328. package/dist/src/routes/agents.route.js.map +1 -1
  329. package/dist/src/routes/chat.route.d.ts +3 -0
  330. package/dist/src/routes/chat.route.d.ts.map +1 -0
  331. package/dist/src/routes/chat.route.js +156 -0
  332. package/dist/src/routes/chat.route.js.map +1 -0
  333. package/dist/src/routes/files.route.d.ts.map +1 -1
  334. package/dist/src/routes/files.route.js +37 -2
  335. package/dist/src/routes/files.route.js.map +1 -1
  336. package/dist/src/routes/llm.route.d.ts.map +1 -1
  337. package/dist/src/routes/llm.route.js +263 -8
  338. package/dist/src/routes/llm.route.js.map +1 -1
  339. package/dist/src/routes/local-llm.route.d.ts +3 -0
  340. package/dist/src/routes/local-llm.route.d.ts.map +1 -0
  341. package/dist/src/routes/local-llm.route.js +688 -0
  342. package/dist/src/routes/local-llm.route.js.map +1 -0
  343. package/dist/src/routes/logs.route.d.ts +3 -0
  344. package/dist/src/routes/logs.route.d.ts.map +1 -0
  345. package/dist/src/routes/logs.route.js +24 -0
  346. package/dist/src/routes/logs.route.js.map +1 -0
  347. package/dist/src/routes/tasks.route.d.ts.map +1 -1
  348. package/dist/src/routes/tasks.route.js +15 -1
  349. package/dist/src/routes/tasks.route.js.map +1 -1
  350. package/dist/src/routes/vnc.route.d.ts +12 -0
  351. package/dist/src/routes/vnc.route.d.ts.map +1 -0
  352. package/dist/src/routes/vnc.route.js +74 -0
  353. package/dist/src/routes/vnc.route.js.map +1 -0
  354. package/dist/src/routes/workflows.route.d.ts.map +1 -1
  355. package/dist/src/routes/workflows.route.js +24 -0
  356. package/dist/src/routes/workflows.route.js.map +1 -1
  357. package/dist/src/server.d.ts.map +1 -1
  358. package/dist/src/server.js +29 -3
  359. package/dist/src/server.js.map +1 -1
  360. package/dist/templates/Demo.md +152 -0
  361. package/dist/templates/README.md +12 -3
  362. package/dist/templates/agents/actor.agent.yaml +34 -0
  363. package/dist/templates/agents/architect.agent.yaml +20 -13
  364. package/dist/templates/agents/chatbot.agent.yaml +23 -27
  365. package/dist/templates/agents/corporate.agent.yaml +64 -0
  366. package/dist/templates/agents/functions.agent.yaml +29 -0
  367. package/dist/templates/agents/investment-analyst.agent.yaml +79 -0
  368. package/dist/templates/agents/music-librarian.agent.yaml +46 -0
  369. package/dist/templates/agents/network-security.agent.yaml +81 -0
  370. package/dist/templates/agents/transport-security.agent.yaml +69 -0
  371. package/dist/templates/agents/web-engineer.agent.yaml +98 -0
  372. package/dist/templates/agents/web-pilot.agent.yaml +57 -0
  373. package/dist/templates/knowledge/music-store/LICENSE.md +11 -0
  374. package/dist/templates/knowledge/music-store/musicstore.sqlite +0 -0
  375. package/dist/templates/knowledge/music-store/tables.png +0 -0
  376. package/dist/templates/knowledge/music-store.knowledge.yaml +138 -0
  377. package/dist/templates/knowledge/org-chart/personnel.csv +21 -21
  378. package/dist/templates/knowledge/org-chart.knowledge.yaml +4 -0
  379. package/dist/templates/knowledge/patient-records.knowledge.yaml +20 -0
  380. package/dist/templates/knowledge/pdf-patients/PDF_Deid_Deidentification_0.pdf +0 -0
  381. package/dist/templates/knowledge/pdf-patients/PDF_Deid_Deidentification_1.pdf +0 -0
  382. package/dist/templates/knowledge/pdf-patients/PDF_Deid_Deidentification_10.pdf +0 -0
  383. package/dist/templates/knowledge/pdf-patients/PDF_Deid_Deidentification_11.pdf +0 -0
  384. package/dist/templates/knowledge/pet-store.knowledge.yaml +3 -0
  385. package/dist/templates/knowledge/security-incidents/incidents.json +55935 -0
  386. package/dist/templates/knowledge/security-incidents.knowledge.yaml +46 -0
  387. package/dist/templates/knowledge/{example.knowledge.yaml → transcripts.knowledge.yaml} +9 -5
  388. package/dist/templates/knowledge/transport-ot/systems.csv +117 -0
  389. package/dist/templates/knowledge/transport-ot.knowledge.yaml +55 -0
  390. package/dist/templates/knowledge/web-docs.knowledge.yaml +1 -1
  391. package/dist/templates/llm.json +62 -22
  392. package/dist/templates/mcp.json +7 -4
  393. package/dist/templates/skills/orcha-builder/SKILL.md +148 -215
  394. package/dist/templates/skills/pii-guard/SKILL.md +22 -0
  395. package/dist/templates/skills/sandbox/SKILL.md +25 -48
  396. package/dist/templates/skills/web-pilot/SKILL.md +51 -0
  397. package/dist/templates/workflows/example.workflow.yaml +27 -35
  398. package/dist/templates/workflows/react-example.workflow.yaml +14 -19
  399. package/dist/templates/workflows/team-chat.workflow.yaml +47 -0
  400. package/package.json +17 -4
  401. package/dist/public/src/components/SkillsView.js +0 -137
  402. package/dist/public/src/components/WorkflowsView.js +0 -416
  403. package/dist/templates/agents/knowledge-broker.agent.yaml +0 -39
  404. package/dist/templates/agents/sandbox.agent.yaml +0 -56
@@ -0,0 +1,807 @@
1
+
2
+ import { Component } from '../utils/Component.js';
3
+ import { api } from '../services/ApiService.js';
4
+
5
+ const TOOL_PREFIXES = {
6
+ 'mcp': 'tool-chip-mcp',
7
+ 'knowledge': 'tool-chip-knowledge',
8
+ 'function': 'tool-chip-function',
9
+ 'builtin': 'tool-chip-builtin',
10
+ 'sandbox': 'tool-chip-sandbox',
11
+ 'workspace': 'tool-chip-workspace',
12
+ };
13
+
14
+ export class AgentComposer extends Component {
15
+ constructor() {
16
+ super();
17
+ this._data = {};
18
+ this._llmOptions = [];
19
+ this._mcpServers = [];
20
+ this._knowledgeStores = [];
21
+ this._functions = [];
22
+ this._skills = [];
23
+ this._toolPickerOpen = false;
24
+ this._toolPickerTab = 'mcp';
25
+ this._toolPickerSearch = '';
26
+ }
27
+
28
+ set data(val) {
29
+ this._data = JSON.parse(JSON.stringify(val || {}));
30
+ this._loadExternalData().then(() => this._renderComposer());
31
+ }
32
+
33
+ getData() {
34
+ this._readFormIntoData();
35
+ return this._serializeClean();
36
+ }
37
+
38
+ _emitChange() {
39
+ this.dispatchEvent(new CustomEvent('composer:change', { bubbles: true }));
40
+ }
41
+
42
+ async _loadExternalData() {
43
+ try {
44
+ const [llms, mcpServers, knowledgeStores, functions, skills] = await Promise.all([
45
+ api.getLLMs().catch(() => []),
46
+ api.getMCPServers().catch(() => []),
47
+ api.getKnowledgeStores().catch(() => []),
48
+ api.getFunctions().catch(() => []),
49
+ api.getSkills().catch(() => []),
50
+ ]);
51
+ this._llmOptions = Array.isArray(llms) ? llms : (llms.models || []);
52
+ this._mcpServers = Array.isArray(mcpServers) ? mcpServers : (mcpServers.servers || []);
53
+ this._knowledgeStores = Array.isArray(knowledgeStores) ? knowledgeStores : (knowledgeStores.stores || []);
54
+ this._functions = Array.isArray(functions) ? functions : (functions.functions || []);
55
+ this._skills = Array.isArray(skills) ? skills : (skills.skills || []);
56
+ } catch { /* silent */ }
57
+ }
58
+
59
+ _renderComposer() {
60
+ let root = this.querySelector('#composerRoot');
61
+ if (!root) {
62
+ this.innerHTML = '<div id="composerRoot" class="overflow-y-auto h-full p-4 space-y-4"></div>';
63
+ root = this.querySelector('#composerRoot');
64
+ }
65
+ root.innerHTML = this._buildHTML();
66
+ this._attachListeners();
67
+ }
68
+
69
+ _buildHTML() {
70
+ const d = this._data;
71
+ const llm = d.llm;
72
+ const llmName = typeof llm === 'string' ? llm : (llm?.name || 'default');
73
+ const temp = typeof llm === 'object' ? llm.temperature : undefined;
74
+ const prompt = d.prompt || {};
75
+ const vars = prompt.inputVariables || [];
76
+ const tools = (d.tools || []).map(t => typeof t === 'string' ? t : t.name);
77
+ const mem = d.memory;
78
+ const memEnabled = mem === true || (typeof mem === 'object' && mem?.enabled !== false);
79
+ const memMaxLines = (typeof mem === 'object' && mem?.maxLines) || '';
80
+ const output = d.output || {};
81
+ const outFmt = output.format || 'text';
82
+ const outSchema = output.schema ? JSON.stringify(output.schema, null, 2) : '';
83
+ const pub = d.publish;
84
+ const pubEnabled = pub === true || (typeof pub === 'object' && pub?.enabled);
85
+ const pubPassword = (typeof pub === 'object' && pub?.password) || '';
86
+ const skills = d.skills;
87
+ const isAllSkills = Array.isArray(skills) && skills.length === 1 && skills[0] === '*';
88
+ const selectedSkills = Array.isArray(skills) ? (isAllSkills ? [] : skills) : [];
89
+ const questions = d.sampleQuestions || [];
90
+ const meta = d.metadata ? JSON.stringify(d.metadata, null, 2) : '';
91
+
92
+ const llmOptions = this._llmOptions.map(m => {
93
+ const name = typeof m === 'string' ? m : m.name;
94
+ return `<option value="${this._esc(name)}" ${name === llmName ? 'selected' : ''}>${this._esc(name)}</option>`;
95
+ }).join('');
96
+
97
+ const toolChips = tools.map(t => {
98
+ const prefix = t.split(':')[0];
99
+ const cls = TOOL_PREFIXES[prefix] || TOOL_PREFIXES['workspace'];
100
+ return `<span class="tool-chip ${cls}">
101
+ ${this._esc(t)}<button class="remove-tool-btn composer-remove-btn ml-1" data-tool="${this._esc(t)}">&times;</button>
102
+ </span>`;
103
+ }).join('');
104
+
105
+ const varChips = vars.map(v =>
106
+ `<span class="var-chip">
107
+ ${this._esc(v)}<button class="remove-var-btn composer-remove-btn ml-1" data-var="${this._esc(v)}">&times;</button>
108
+ </span>`
109
+ ).join('');
110
+
111
+ const questionRows = questions.map((q, i) =>
112
+ `<div class="flex gap-2">
113
+ <input type="text" data-field="sampleQuestions.${i}" value="${this._esc(q)}"
114
+ class="composer-input composer-input-field flex-1" />
115
+ <button class="remove-question-btn composer-remove-btn px-1" data-q-idx="${i}"><i class="fas fa-trash"></i></button>
116
+ </div>`
117
+ ).join('');
118
+
119
+ return `
120
+ <!-- Identity & LLM -->
121
+ <div class="grid grid-cols-2 gap-4">
122
+ <div class="composer-section space-y-3">
123
+ <h3 class="section-title">Identity</h3>
124
+ <div>
125
+ <label class="composer-label">Name</label>
126
+ <input type="text" data-field="name" value="${this._esc(d.name || '')}"
127
+ class="composer-input composer-input-field" />
128
+ </div>
129
+ <div>
130
+ <label class="composer-label">Description</label>
131
+ <input type="text" data-field="description" value="${this._esc(d.description || '')}"
132
+ class="composer-input composer-input-field" />
133
+ </div>
134
+ <div class="grid grid-cols-2 gap-3">
135
+ <div>
136
+ <label class="composer-label">Version</label>
137
+ <input type="text" data-field="version" value="${this._esc(d.version || '1.0.0')}"
138
+ class="composer-input composer-input-field" />
139
+ </div>
140
+ <div>
141
+ <label class="composer-label">Max Iterations</label>
142
+ <input type="number" data-field="maxIterations" value="${d.maxIterations || ''}" min="1" placeholder="Default"
143
+ class="composer-input composer-input-field" />
144
+ </div>
145
+ </div>
146
+ </div>
147
+
148
+ <div class="composer-section space-y-3">
149
+ <h3 class="section-title">LLM</h3>
150
+ <div>
151
+ <label class="composer-label">Model</label>
152
+ <select data-field="llm.name"
153
+ class="composer-input composer-input-field">
154
+ <option value="default" ${llmName === 'default' ? 'selected' : ''}>default</option>
155
+ ${llmOptions}
156
+ </select>
157
+ </div>
158
+ <div>
159
+ <label class="composer-label">Temperature <span class="text-muted font-mono" data-temp-display>${temp !== undefined ? temp : '—'}</span></label>
160
+ <input type="range" data-field="llm.temperature" min="0" max="2" step="0.1" value="${temp !== undefined ? temp : 0.7}"
161
+ class="w-full" />
162
+ <div class="flex justify-between text-xs text-muted mt-1">
163
+ <span>0 Precise</span>
164
+ <span>2 Creative</span>
165
+ </div>
166
+ </div>
167
+ </div>
168
+ </div>
169
+
170
+ <!-- Prompt -->
171
+ <div class="composer-section space-y-3">
172
+ <h3 class="section-title">System Prompt</h3>
173
+ <textarea data-field="prompt.system" rows="10"
174
+ class="composer-input composer-input-field font-mono resize-y">${this._esc(prompt.system || '')}</textarea>
175
+ <div>
176
+ <label class="composer-label">Input Variables</label>
177
+ <div class="flex flex-wrap gap-1 mb-2">${varChips}</div>
178
+ <div class="flex gap-2">
179
+ <input type="text" id="newVarInput" placeholder="Add variable..."
180
+ class="composer-input-field flex-1" />
181
+ <button id="addVarBtn" class="btn btn-sm bg-surface">Add</button>
182
+ </div>
183
+ </div>
184
+ </div>
185
+
186
+ <!-- Tools & Skills -->
187
+ <div class="grid grid-cols-2 gap-4">
188
+ <div class="composer-section space-y-3">
189
+ <h3 class="section-title">Tools</h3>
190
+ <div class="flex flex-wrap gap-1">${toolChips || '<span class="text-xs text-muted">No tools added</span>'}</div>
191
+ <button id="addToolBtn" class="composer-add-btn">
192
+ <i class="fas fa-plus mr-1"></i> Add tool
193
+ </button>
194
+ <div id="toolPicker" class="hidden"></div>
195
+ </div>
196
+
197
+ <div class="composer-section space-y-3">
198
+ <h3 class="section-title">Skills</h3>
199
+ <div class="flex gap-3">
200
+ <label class="inline-flex items-center gap-1 text-xs text-secondary cursor-pointer">
201
+ <input type="radio" name="skillsMode" value="none" ${!skills ? 'checked' : ''} class="skills-mode-radio" /> None
202
+ </label>
203
+ <label class="inline-flex items-center gap-1 text-xs text-secondary cursor-pointer">
204
+ <input type="radio" name="skillsMode" value="all" ${isAllSkills ? 'checked' : ''} class="skills-mode-radio" /> All
205
+ </label>
206
+ <label class="inline-flex items-center gap-1 text-xs text-secondary cursor-pointer">
207
+ <input type="radio" name="skillsMode" value="specific" ${(Array.isArray(skills) && !isAllSkills) ? 'checked' : ''} class="skills-mode-radio" /> Specific
208
+ </label>
209
+ </div>
210
+ <div id="skillsList" class="${(Array.isArray(skills) && !isAllSkills) ? '' : 'hidden'} space-y-1">
211
+ ${this._skills.map(s => {
212
+ const name = typeof s === 'string' ? s : s.name;
213
+ const checked = selectedSkills.includes(name);
214
+ return `<label class="flex items-center gap-2 text-xs text-secondary cursor-pointer">
215
+ <input type="checkbox" value="${this._esc(name)}" ${checked ? 'checked' : ''} class="skill-checkbox" /> ${this._esc(name)}
216
+ </label>`;
217
+ }).join('')}
218
+ ${this._skills.length === 0 ? '<span class="text-xs text-muted">No skills loaded</span>' : ''}
219
+ </div>
220
+ </div>
221
+ </div>
222
+
223
+ <!-- Memory, Output, Publish -->
224
+ <div class="grid grid-cols-3 gap-4">
225
+ <div class="composer-section space-y-3">
226
+ <h3 class="section-title">Memory</h3>
227
+ <label class="flex items-center gap-2 text-xs text-secondary cursor-pointer">
228
+ <input type="checkbox" data-field="memory.enabled" ${memEnabled ? 'checked' : ''} class="composer-input" />
229
+ Enable persistent memory
230
+ </label>
231
+ <div id="memoryFields" class="${memEnabled ? '' : 'hidden'}">
232
+ <label class="composer-label">Max Lines</label>
233
+ <input type="number" data-field="memory.maxLines" value="${memMaxLines}" min="1" placeholder="100"
234
+ class="composer-input composer-input-field" />
235
+ </div>
236
+ </div>
237
+
238
+ <div class="composer-section space-y-3">
239
+ <h3 class="section-title">Output</h3>
240
+ <div>
241
+ <label class="composer-label">Format</label>
242
+ <select data-field="output.format"
243
+ class="composer-input composer-input-field">
244
+ <option value="text" ${outFmt === 'text' ? 'selected' : ''}>text</option>
245
+ <option value="structured" ${outFmt === 'structured' ? 'selected' : ''}>structured</option>
246
+ </select>
247
+ </div>
248
+ <div id="outputSchemaField" class="${outFmt === 'structured' ? '' : 'hidden'}">
249
+ <label class="composer-label">Schema (JSON)</label>
250
+ <textarea data-field="output.schema" rows="4"
251
+ class="composer-input composer-input-field text-xs font-mono resize-y">${this._esc(outSchema)}</textarea>
252
+ <div id="outputSchemaError" class="hidden text-xs text-red mt-1"></div>
253
+ </div>
254
+ </div>
255
+
256
+ <div class="composer-section space-y-3">
257
+ <h3 class="section-title">Publish</h3>
258
+ <label class="flex items-center gap-2 text-xs text-secondary cursor-pointer">
259
+ <input type="checkbox" data-field="publish.enabled" ${pubEnabled ? 'checked' : ''} class="composer-input" />
260
+ Standalone chat page
261
+ </label>
262
+ <div id="publishFields" class="${pubEnabled ? '' : 'hidden'}">
263
+ <label class="composer-label">Password</label>
264
+ <input type="text" data-field="publish.password" value="${this._esc(pubPassword)}" placeholder="Optional"
265
+ class="composer-input composer-input-field" />
266
+ </div>
267
+ </div>
268
+ </div>
269
+
270
+ <!-- Integrations -->
271
+ <div class="composer-section space-y-3">
272
+ <div class="flex items-center justify-between">
273
+ <h3 class="section-title">Integrations</h3>
274
+ <div class="flex gap-1">
275
+ <button class="add-integration-btn composer-add-btn" data-integ-type="collabnook"><i class="fas fa-plus mr-1"></i>Collabnook</button>
276
+ <button class="add-integration-btn composer-add-btn ml-3" data-integ-type="email"><i class="fas fa-plus mr-1"></i>Email</button>
277
+ </div>
278
+ </div>
279
+ ${this._renderIntegrations()}
280
+ </div>
281
+
282
+ <!-- Triggers -->
283
+ <div class="composer-section space-y-3">
284
+ <div class="flex items-center justify-between">
285
+ <h3 class="section-title">Triggers</h3>
286
+ <div class="flex gap-1">
287
+ <button class="add-trigger-btn composer-add-btn" data-trigger-type="cron"><i class="fas fa-plus mr-1"></i>Cron</button>
288
+ <button class="add-trigger-btn composer-add-btn ml-3" data-trigger-type="webhook"><i class="fas fa-plus mr-1"></i>Webhook</button>
289
+ </div>
290
+ </div>
291
+ ${this._renderTriggers()}
292
+ </div>
293
+
294
+ <!-- Sample Questions & Metadata -->
295
+ <div class="grid grid-cols-2 gap-4">
296
+ <div class="composer-section space-y-3">
297
+ <h3 class="section-title">Sample Questions</h3>
298
+ <div class="space-y-2">
299
+ ${questionRows || '<span class="text-xs text-muted">No sample questions</span>'}
300
+ </div>
301
+ <button id="addQuestionBtn" class="composer-add-btn">
302
+ <i class="fas fa-plus mr-1"></i> Add question
303
+ </button>
304
+ </div>
305
+
306
+ <div class="composer-section space-y-3">
307
+ <h3 class="section-title">Metadata</h3>
308
+ <textarea data-field="metadata" rows="6"
309
+ class="composer-input composer-input-field text-xs font-mono resize-y">${this._esc(meta)}</textarea>
310
+ <div id="metadataError" class="hidden text-xs text-red mt-1"></div>
311
+ </div>
312
+ </div>
313
+ `;
314
+ }
315
+
316
+ // ── Integrations sub-cards ──
317
+ _renderIntegrations() {
318
+ const integrations = this._data.integrations || [];
319
+ if (!integrations.length) return '<div class="text-xs text-muted">No integrations</div>';
320
+ return integrations.map((integ, i) => integ.type === 'email' ? this._renderEmailCard(integ, i) : this._renderCollabnookCard(integ, i)).join('');
321
+ }
322
+
323
+ _renderCollabnookCard(integ, idx) {
324
+ return `
325
+ <div class="composer-sub-card" data-integ-idx="${idx}">
326
+ <div class="flex items-center justify-between mb-2">
327
+ <span class="text-xs font-medium text-secondary"><i class="fas fa-comments mr-1"></i>Collabnook</span>
328
+ <button class="remove-integration-btn composer-remove-btn" data-integ-idx="${idx}"><i class="fas fa-trash"></i></button>
329
+ </div>
330
+ <div class="grid grid-cols-2 gap-2">
331
+ ${this._field(`integrations.${idx}.url`, 'URL', integ.url)}
332
+ ${this._field(`integrations.${idx}.channel`, 'Channel', integ.channel)}
333
+ ${this._field(`integrations.${idx}.botName`, 'Bot Name', integ.botName)}
334
+ ${this._field(`integrations.${idx}.password`, 'Password', integ.password)}
335
+ </div>
336
+ </div>`;
337
+ }
338
+
339
+ _renderEmailCard(integ, idx) {
340
+ const imap = integ.imap || {}, smtp = integ.smtp || {}, auth = integ.auth || {};
341
+ return `
342
+ <div class="composer-sub-card" data-integ-idx="${idx}">
343
+ <div class="flex items-center justify-between mb-2">
344
+ <span class="text-xs font-medium text-secondary"><i class="fas fa-envelope mr-1"></i>Email</span>
345
+ <button class="remove-integration-btn composer-remove-btn" data-integ-idx="${idx}"><i class="fas fa-trash"></i></button>
346
+ </div>
347
+ <div class="grid grid-cols-3 gap-2 mb-2">
348
+ ${this._field(`integrations.${idx}.imap.host`, 'IMAP Host', imap.host)}
349
+ ${this._fieldNum(`integrations.${idx}.imap.port`, 'Port', imap.port)}
350
+ ${this._fieldSelect(`integrations.${idx}.imap.secure`, 'Secure', imap.secure)}
351
+ </div>
352
+ <div class="grid grid-cols-3 gap-2 mb-2">
353
+ ${this._field(`integrations.${idx}.smtp.host`, 'SMTP Host', smtp.host)}
354
+ ${this._fieldNum(`integrations.${idx}.smtp.port`, 'Port', smtp.port)}
355
+ ${this._fieldSelect(`integrations.${idx}.smtp.secure`, 'Secure', smtp.secure)}
356
+ </div>
357
+ <div class="grid grid-cols-2 gap-2">
358
+ ${this._field(`integrations.${idx}.auth.user`, 'User', auth.user)}
359
+ ${this._field(`integrations.${idx}.auth.pass`, 'Password', auth.pass)}
360
+ ${this._field(`integrations.${idx}.fromName`, 'From Name', integ.fromName)}
361
+ ${this._field(`integrations.${idx}.fromAddress`, 'From Address', integ.fromAddress)}
362
+ ${this._fieldNum(`integrations.${idx}.pollInterval`, 'Poll Interval (s)', integ.pollInterval)}
363
+ ${this._field(`integrations.${idx}.folder`, 'Folder', integ.folder || 'INBOX')}
364
+ </div>
365
+ </div>`;
366
+ }
367
+
368
+ // ── Triggers sub-cards ──
369
+ _renderTriggers() {
370
+ const triggers = this._data.triggers || [];
371
+ const inputVars = this._data.prompt?.inputVariables || [];
372
+ const primaryVar = inputVars[0] || 'query';
373
+
374
+ if (!triggers.length) return '<div class="text-xs text-muted">No triggers</div>';
375
+ return triggers.map((trig, i) => {
376
+ const isCron = trig.type === 'cron' || trig.schedule;
377
+ const inputVal = (typeof trig.input === 'object' && trig.input) ? (trig.input[primaryVar] || '') : '';
378
+ return `
379
+ <div class="composer-sub-card" data-trigger-idx="${i}">
380
+ <div class="flex items-center justify-between mb-2">
381
+ <span class="text-xs font-medium text-secondary"><i class="fas ${isCron ? 'fa-clock' : 'fa-link'} mr-1"></i>${isCron ? 'Cron' : 'Webhook'}</span>
382
+ <button class="remove-trigger-btn composer-remove-btn" data-trigger-idx="${i}"><i class="fas fa-trash"></i></button>
383
+ </div>
384
+ <div class="grid grid-cols-2 gap-2">
385
+ ${isCron
386
+ ? `<div>
387
+ <label class="composer-label">Schedule</label>
388
+ <input type="text" data-field="triggers.${i}.schedule" value="${this._esc(trig.schedule || '')}" placeholder="*/5 * * * *"
389
+ class="composer-input composer-input-sm" />
390
+ <div class="flex flex-wrap gap-1 mt-1">
391
+ <button class="cron-preset-btn" data-preset="* * * * *" data-trigger-idx="${i}">1min</button>
392
+ <button class="cron-preset-btn" data-preset="*/5 * * * *" data-trigger-idx="${i}">5min</button>
393
+ <button class="cron-preset-btn" data-preset="*/15 * * * *" data-trigger-idx="${i}">15min</button>
394
+ <button class="cron-preset-btn" data-preset="0 * * * *" data-trigger-idx="${i}">hourly</button>
395
+ <button class="cron-preset-btn" data-preset="0 */6 * * *" data-trigger-idx="${i}">6hr</button>
396
+ <button class="cron-preset-btn" data-preset="0 0 * * *" data-trigger-idx="${i}">daily</button>
397
+ <button class="cron-preset-btn" data-preset="0 0 * * 1" data-trigger-idx="${i}">weekly</button>
398
+ <button class="cron-preset-btn" data-preset="0 0 1 * *" data-trigger-idx="${i}">monthly</button>
399
+ </div>
400
+ </div>`
401
+ : this._field(`triggers.${i}.path`, 'Path', trig.path, '/webhook/my-hook')
402
+ }
403
+ <div>
404
+ <label class="composer-label">Prompt <span class="text-muted font-mono">(${this._esc(primaryVar)})</span></label>
405
+ <input type="text" data-field="triggers.${i}.inputVar" value="${this._esc(inputVal)}" placeholder="e.g. Generate the daily report"
406
+ class="composer-input composer-input-sm" />
407
+ </div>
408
+ </div>
409
+ </div>`;
410
+ }).join('');
411
+ }
412
+
413
+ // ── Shared field helpers ──
414
+ _field(dataField, label, value, placeholder) {
415
+ return `<div>
416
+ <label class="composer-label">${label}</label>
417
+ <input type="text" data-field="${dataField}" value="${this._esc(value || '')}" ${placeholder ? `placeholder="${placeholder}"` : ''}
418
+ class="composer-input composer-input-sm" />
419
+ </div>`;
420
+ }
421
+ _fieldNum(dataField, label, value) {
422
+ return `<div>
423
+ <label class="composer-label">${label}</label>
424
+ <input type="number" data-field="${dataField}" value="${value || ''}"
425
+ class="composer-input composer-input-sm" />
426
+ </div>`;
427
+ }
428
+ _fieldSelect(dataField, label, value) {
429
+ return `<div>
430
+ <label class="composer-label">${label}</label>
431
+ <select data-field="${dataField}"
432
+ class="composer-input composer-input-sm">
433
+ <option value="false" ${!value ? 'selected' : ''}>false</option>
434
+ <option value="true" ${value ? 'selected' : ''}>true</option>
435
+ </select>
436
+ </div>`;
437
+ }
438
+
439
+ // ── Tool Picker ──
440
+ _renderToolPicker() {
441
+ const existing = new Set((this._data.tools || []).map(t => typeof t === 'string' ? t : t.name));
442
+ const search = this._toolPickerSearch.toLowerCase();
443
+ const tabs = [
444
+ { id: 'mcp', label: 'MCP', items: this._mcpServers.map(s => `mcp:${s.name || s}`) },
445
+ { id: 'knowledge', label: 'Knowledge', items: this._knowledgeStores.map(s => `knowledge:${s.name || s}`) },
446
+ { id: 'function', label: 'Functions', items: this._functions.map(f => `function:${f.name || f}`) },
447
+ { id: 'builtin', label: 'Builtin', items: ['builtin:ask_user'] },
448
+ { id: 'sandbox', label: 'Sandbox', items: ['sandbox:shell','sandbox:exec','sandbox:web_fetch','sandbox:web_search','sandbox:browser_navigate','sandbox:browser_observe','sandbox:browser_click','sandbox:browser_type','sandbox:browser_screenshot','sandbox:browser_evaluate','sandbox:file_read','sandbox:file_write','sandbox:file_edit','sandbox:file_insert','sandbox:file_replace_lines'] },
449
+ ];
450
+ const active = tabs.find(t => t.id === this._toolPickerTab) || tabs[0];
451
+ const filtered = active.items.filter(v => !search || v.toLowerCase().includes(search));
452
+
453
+ return `
454
+ <div class="tool-picker-inline">
455
+ <div class="tool-picker-inline-tabs">
456
+ ${tabs.map(t => `<button class="tool-picker-inline-tab ${t.id === this._toolPickerTab ? 'active' : ''} tool-picker-tab" data-tab="${t.id}">${t.label}</button>`).join('')}
457
+ </div>
458
+ <div class="p-2">
459
+ <input type="text" id="toolPickerSearch" placeholder="Filter..." value="${this._esc(this._toolPickerSearch)}"
460
+ class="composer-input-sm mb-2" />
461
+ <div class="tool-picker-list">
462
+ ${filtered.length === 0 ? '<div class="text-xs text-muted p-2 text-center">No items</div>' : ''}
463
+ ${filtered.map(item => {
464
+ const added = existing.has(item);
465
+ return `<div class="tool-picker-item ${added ? 'added' : 'available'}"
466
+ ${!added ? `data-add-tool="${this._esc(item)}"` : ''}>
467
+ <span>${this._esc(item.split(':')[1] || item)}</span>
468
+ ${added ? '<i class="fas fa-check text-green text-2xs"></i>' : '<i class="fas fa-plus text-muted text-2xs"></i>'}
469
+ </div>`;
470
+ }).join('')}
471
+ </div>
472
+ </div>
473
+ <div class="border-t px-2 py-1 flex justify-end">
474
+ <button id="closeToolPicker" class="composer-add-btn">Close</button>
475
+ </div>
476
+ </div>`;
477
+ }
478
+
479
+ // ── Listeners ──
480
+ _attachListeners() {
481
+ // Generic change tracking
482
+ this.querySelectorAll('.composer-input').forEach(el => {
483
+ const evt = (el.tagName === 'SELECT' || el.type === 'checkbox' || el.type === 'range') ? 'change' : 'input';
484
+ el.addEventListener(evt, () => this._emitChange());
485
+ });
486
+
487
+ // Temperature display
488
+ const tempSlider = this.querySelector('[data-field="llm.temperature"]');
489
+ const tempDisplay = this.querySelector('[data-temp-display]');
490
+ if (tempSlider && tempDisplay) {
491
+ tempSlider.addEventListener('input', () => { tempDisplay.textContent = tempSlider.value; });
492
+ }
493
+
494
+ // Memory toggle
495
+ const memCheck = this.querySelector('[data-field="memory.enabled"]');
496
+ const memFields = this.querySelector('#memoryFields');
497
+ if (memCheck && memFields) memCheck.addEventListener('change', () => { memFields.classList.toggle('hidden', !memCheck.checked); this._emitChange(); });
498
+
499
+ // Publish toggle
500
+ const pubCheck = this.querySelector('[data-field="publish.enabled"]');
501
+ const pubFields = this.querySelector('#publishFields');
502
+ if (pubCheck && pubFields) pubCheck.addEventListener('change', () => { pubFields.classList.toggle('hidden', !pubCheck.checked); this._emitChange(); });
503
+
504
+ // Output format toggle
505
+ const outputFmt = this.querySelector('[data-field="output.format"]');
506
+ const schemaField = this.querySelector('#outputSchemaField');
507
+ if (outputFmt && schemaField) outputFmt.addEventListener('change', () => { schemaField.classList.toggle('hidden', outputFmt.value !== 'structured'); this._emitChange(); });
508
+
509
+ // JSON validation
510
+ this._attachJsonValidation('[data-field="metadata"]', '#metadataError');
511
+ this._attachJsonValidation('[data-field="output.schema"]', '#outputSchemaError');
512
+
513
+ // Input variables
514
+ this._attachVarListeners();
515
+ // Tools
516
+ this._attachToolListeners();
517
+ // Skills
518
+ this._attachSkillListeners();
519
+ // Sample questions
520
+ this._attachQuestionListeners();
521
+ // Integrations
522
+ this._attachIntegrationListeners();
523
+ // Triggers
524
+ this._attachTriggerListeners();
525
+ }
526
+
527
+ _attachJsonValidation(fieldSel, errorSel) {
528
+ const field = this.querySelector(fieldSel), error = this.querySelector(errorSel);
529
+ if (!field || !error) return;
530
+ field.addEventListener('blur', () => {
531
+ const val = field.value.trim();
532
+ if (!val) { error.classList.add('hidden'); field.classList.remove('error'); return; }
533
+ try { JSON.parse(val); error.classList.add('hidden'); field.classList.remove('error'); }
534
+ catch (e) { error.textContent = e.message; error.classList.remove('hidden'); field.classList.add('error'); }
535
+ });
536
+ }
537
+
538
+ _attachVarListeners() {
539
+ const addBtn = this.querySelector('#addVarBtn'), input = this.querySelector('#newVarInput');
540
+ if (addBtn && input) {
541
+ const add = () => {
542
+ const val = input.value.trim();
543
+ if (!val) return;
544
+ if (!this._data.prompt) this._data.prompt = { system: '', inputVariables: [] };
545
+ if (!this._data.prompt.inputVariables) this._data.prompt.inputVariables = [];
546
+ if (!this._data.prompt.inputVariables.includes(val)) {
547
+ this._data.prompt.inputVariables.push(val);
548
+ this._emitChange();
549
+ this._renderComposer();
550
+ }
551
+ };
552
+ addBtn.addEventListener('click', add);
553
+ input.addEventListener('keydown', e => { if (e.key === 'Enter') { e.preventDefault(); add(); } });
554
+ }
555
+ this.querySelectorAll('.remove-var-btn').forEach(btn => {
556
+ btn.addEventListener('click', () => {
557
+ if (this._data.prompt?.inputVariables) {
558
+ this._data.prompt.inputVariables = this._data.prompt.inputVariables.filter(x => x !== btn.dataset.var);
559
+ this._emitChange(); this._renderComposer();
560
+ }
561
+ });
562
+ });
563
+ }
564
+
565
+ _attachToolListeners() {
566
+ const addBtn = this.querySelector('#addToolBtn'), picker = this.querySelector('#toolPicker');
567
+ if (addBtn && picker) {
568
+ addBtn.addEventListener('click', () => {
569
+ this._toolPickerOpen = !this._toolPickerOpen;
570
+ if (this._toolPickerOpen) { picker.classList.remove('hidden'); picker.innerHTML = this._renderToolPicker(); this._attachToolPickerListeners(); }
571
+ else { picker.classList.add('hidden'); picker.innerHTML = ''; }
572
+ });
573
+ }
574
+ this.querySelectorAll('.remove-tool-btn').forEach(btn => {
575
+ btn.addEventListener('click', () => {
576
+ this._data.tools = (this._data.tools || []).filter(t => (typeof t === 'string' ? t : t.name) !== btn.dataset.tool);
577
+ this._emitChange(); this._readFormIntoData(); this._renderComposer();
578
+ });
579
+ });
580
+ }
581
+
582
+ _attachToolPickerListeners() {
583
+ const picker = this.querySelector('#toolPicker');
584
+ if (!picker) return;
585
+ picker.querySelectorAll('.tool-picker-tab').forEach(tab => {
586
+ tab.addEventListener('click', () => { this._toolPickerTab = tab.dataset.tab; this._readFormIntoData(); picker.innerHTML = this._renderToolPicker(); this._attachToolPickerListeners(); });
587
+ });
588
+ const searchInput = picker.querySelector('#toolPickerSearch');
589
+ if (searchInput) {
590
+ searchInput.addEventListener('input', () => {
591
+ this._toolPickerSearch = searchInput.value; this._readFormIntoData();
592
+ picker.innerHTML = this._renderToolPicker(); this._attachToolPickerListeners();
593
+ const ni = picker.querySelector('#toolPickerSearch');
594
+ if (ni) { ni.focus(); ni.selectionStart = ni.selectionEnd = ni.value.length; }
595
+ });
596
+ }
597
+ picker.querySelectorAll('[data-add-tool]').forEach(el => {
598
+ el.addEventListener('click', () => { if (!this._data.tools) this._data.tools = []; this._data.tools.push(el.dataset.addTool); this._emitChange(); this._readFormIntoData(); this._renderComposer(); });
599
+ });
600
+ picker.querySelector('#closeToolPicker')?.addEventListener('click', () => { this._toolPickerOpen = false; picker.classList.add('hidden'); picker.innerHTML = ''; });
601
+ }
602
+
603
+ _attachSkillListeners() {
604
+ this.querySelectorAll('.skills-mode-radio').forEach(radio => {
605
+ radio.addEventListener('change', () => {
606
+ const mode = radio.value;
607
+ this.querySelector('#skillsList')?.classList.toggle('hidden', mode !== 'specific');
608
+ if (mode === 'none') this._data.skills = undefined;
609
+ else if (mode === 'all') this._data.skills = ['*'];
610
+ else this._data.skills = [];
611
+ this._emitChange();
612
+ });
613
+ });
614
+ this.querySelectorAll('.skill-checkbox').forEach(cb => {
615
+ cb.addEventListener('change', () => {
616
+ if (!Array.isArray(this._data.skills)) this._data.skills = [];
617
+ if (cb.checked) { if (!this._data.skills.includes(cb.value)) this._data.skills.push(cb.value); }
618
+ else this._data.skills = this._data.skills.filter(s => s !== cb.value);
619
+ this._emitChange();
620
+ });
621
+ });
622
+ }
623
+
624
+ _attachQuestionListeners() {
625
+ this.querySelector('#addQuestionBtn')?.addEventListener('click', () => {
626
+ this._readFormIntoData();
627
+ if (!this._data.sampleQuestions) this._data.sampleQuestions = [];
628
+ this._data.sampleQuestions.push('');
629
+ this._emitChange(); this._renderComposer();
630
+ });
631
+ this.querySelectorAll('.remove-question-btn').forEach(btn => {
632
+ btn.addEventListener('click', () => {
633
+ const idx = parseInt(btn.dataset.qIdx, 10);
634
+ if (this._data.sampleQuestions) { this._readFormIntoData(); this._data.sampleQuestions.splice(idx, 1); this._emitChange(); this._renderComposer(); }
635
+ });
636
+ });
637
+ }
638
+
639
+ _attachIntegrationListeners() {
640
+ this.querySelectorAll('.add-integration-btn').forEach(btn => {
641
+ btn.addEventListener('click', () => {
642
+ if (!this._data.integrations) this._data.integrations = [];
643
+ this._readFormIntoData();
644
+ const type = btn.dataset.integType;
645
+ if (type === 'collabnook') this._data.integrations.push({ type: 'collabnook', url: '', channel: '', botName: '' });
646
+ else if (type === 'email') this._data.integrations.push({ type: 'email', imap: {}, smtp: {}, auth: {}, fromName: '', fromAddress: '', pollInterval: 30, folder: 'INBOX' });
647
+ this._emitChange(); this._renderComposer();
648
+ });
649
+ });
650
+ this.querySelectorAll('.remove-integration-btn').forEach(btn => {
651
+ btn.addEventListener('click', () => {
652
+ const idx = parseInt(btn.dataset.integIdx, 10);
653
+ if (this._data.integrations) { this._readFormIntoData(); this._data.integrations.splice(idx, 1); this._emitChange(); this._renderComposer(); }
654
+ });
655
+ });
656
+ }
657
+
658
+ _attachTriggerListeners() {
659
+ this.querySelectorAll('.add-trigger-btn').forEach(btn => {
660
+ btn.addEventListener('click', () => {
661
+ if (!this._data.triggers) this._data.triggers = [];
662
+ this._readFormIntoData();
663
+ if (btn.dataset.triggerType === 'cron') this._data.triggers.push({ type: 'cron', schedule: '' });
664
+ else this._data.triggers.push({ type: 'webhook', path: '' });
665
+ this._emitChange(); this._renderComposer();
666
+ });
667
+ });
668
+ this.querySelectorAll('.remove-trigger-btn').forEach(btn => {
669
+ btn.addEventListener('click', () => {
670
+ const idx = parseInt(btn.dataset.triggerIdx, 10);
671
+ if (this._data.triggers) { this._readFormIntoData(); this._data.triggers.splice(idx, 1); this._emitChange(); this._renderComposer(); }
672
+ });
673
+ });
674
+ this.querySelectorAll('.cron-preset-btn').forEach(btn => {
675
+ btn.addEventListener('click', () => {
676
+ const idx = btn.dataset.triggerIdx;
677
+ const input = this.querySelector(`[data-field="triggers.${idx}.schedule"]`);
678
+ if (input) { input.value = btn.dataset.preset; this._emitChange(); }
679
+ });
680
+ });
681
+ }
682
+
683
+ // ── Read form into data ──
684
+ _readFormIntoData() {
685
+ const read = sel => this.querySelector(`[data-field="${sel}"]`)?.value ?? undefined;
686
+ const readChecked = sel => this.querySelector(`[data-field="${sel}"]`)?.checked ?? false;
687
+
688
+ const name = read('name'); if (name !== undefined) this._data.name = name;
689
+ const desc = read('description'); if (desc !== undefined) this._data.description = desc;
690
+ const ver = read('version'); if (ver !== undefined) this._data.version = ver;
691
+ const maxIter = read('maxIterations'); this._data.maxIterations = maxIter ? parseInt(maxIter, 10) : undefined;
692
+
693
+ const llmName = read('llm.name'), llmTemp = read('llm.temperature');
694
+ if (llmName !== undefined) {
695
+ if (llmName === 'default' && llmTemp === undefined) this._data.llm = 'default';
696
+ else { this._data.llm = { name: llmName || 'default' }; if (llmTemp !== undefined) this._data.llm.temperature = parseFloat(llmTemp); }
697
+ }
698
+
699
+ const sys = this.querySelector('[data-field="prompt.system"]')?.value;
700
+ if (sys !== undefined) { if (!this._data.prompt) this._data.prompt = { system: '', inputVariables: [] }; this._data.prompt.system = sys; }
701
+
702
+ const memEnabled = readChecked('memory.enabled'), memMaxLines = read('memory.maxLines');
703
+ if (memEnabled) this._data.memory = memMaxLines ? { enabled: true, maxLines: parseInt(memMaxLines, 10) } : true;
704
+ else this._data.memory = undefined;
705
+
706
+ const outFmt = read('output.format');
707
+ if (outFmt) {
708
+ this._data.output = { format: outFmt };
709
+ if (outFmt === 'structured') { const s = read('output.schema'); if (s) { try { this._data.output.schema = JSON.parse(s); } catch {} } }
710
+ }
711
+
712
+ const pubEnabled = readChecked('publish.enabled'), pubPassword = read('publish.password');
713
+ if (pubEnabled) this._data.publish = pubPassword ? { enabled: true, password: pubPassword } : { enabled: true };
714
+ else this._data.publish = undefined;
715
+
716
+ const qInputs = this.querySelectorAll('[data-field^="sampleQuestions."]');
717
+ if (qInputs.length > 0) this._data.sampleQuestions = Array.from(qInputs).map(el => el.value);
718
+
719
+ const metaStr = this.querySelector('[data-field="metadata"]')?.value?.trim();
720
+ if (metaStr !== undefined) { if (metaStr) { try { this._data.metadata = JSON.parse(metaStr); } catch {} } else this._data.metadata = undefined; }
721
+
722
+ // Integrations
723
+ (this._data.integrations || []).forEach((integ, i) => this._readNestedFields(integ, `integrations.${i}`));
724
+
725
+ // Triggers
726
+ const inputVars = this._data.prompt?.inputVariables || [];
727
+ const primaryVar = inputVars[0] || 'query';
728
+ (this._data.triggers || []).forEach((trig, i) => {
729
+ const schedVal = read(`triggers.${i}.schedule`); if (schedVal !== undefined) trig.schedule = schedVal;
730
+ const pathVal = read(`triggers.${i}.path`); if (pathVal !== undefined) trig.path = pathVal;
731
+ const inputVarVal = this.querySelector(`[data-field="triggers.${i}.inputVar"]`)?.value;
732
+ if (inputVarVal !== undefined) trig.input = inputVarVal.trim() ? { [primaryVar]: inputVarVal } : undefined;
733
+ });
734
+ }
735
+
736
+ _readNestedFields(obj, prefix) {
737
+ this.querySelectorAll(`[data-field^="${prefix}."]`).forEach(el => {
738
+ const path = el.dataset.field.substring(prefix.length + 1);
739
+ const parts = path.split('.');
740
+ let target = obj;
741
+ for (let i = 0; i < parts.length - 1; i++) { if (!target[parts[i]]) target[parts[i]] = {}; target = target[parts[i]]; }
742
+ const key = parts[parts.length - 1];
743
+ if (el.tagName === 'SELECT') { const val = el.value; target[key] = val === 'true' ? true : val === 'false' ? false : val; }
744
+ else if (el.type === 'number') target[key] = el.value ? Number(el.value) : undefined;
745
+ else target[key] = el.value;
746
+ });
747
+ }
748
+
749
+ // ── Serialize clean output ──
750
+ _serializeClean() {
751
+ const d = this._data, out = {};
752
+ if (d.name) out.name = d.name;
753
+ if (d.description) out.description = d.description;
754
+ if (d.version) out.version = d.version;
755
+
756
+ if (d.llm && d.llm !== 'default') {
757
+ if (typeof d.llm === 'object') {
758
+ const llm = { name: d.llm.name || 'default' };
759
+ if (d.llm.temperature !== undefined) llm.temperature = d.llm.temperature;
760
+ out.llm = (llm.name === 'default' && llm.temperature === undefined) ? 'default' : llm;
761
+ } else out.llm = d.llm;
762
+ }
763
+
764
+ if (d.prompt) { out.prompt = { system: d.prompt.system || '' }; if (d.prompt.inputVariables?.length) out.prompt.inputVariables = d.prompt.inputVariables; }
765
+ if (d.tools?.length) out.tools = d.tools;
766
+ if (d.skills) out.skills = d.skills;
767
+ if (d.output?.format) { out.output = { format: d.output.format }; if (d.output.format === 'structured' && d.output.schema) out.output.schema = d.output.schema; }
768
+ if (d.memory) out.memory = d.memory;
769
+
770
+ if (d.integrations?.length) {
771
+ out.integrations = d.integrations.map(integ => {
772
+ const c = { type: integ.type };
773
+ if (integ.type === 'collabnook') { ['url','channel','botName','password','replyDelay'].forEach(k => { if (integ[k]) c[k] = integ[k]; }); }
774
+ else if (integ.type === 'email') { ['imap','smtp','auth','fromName','fromAddress','pollInterval','folder'].forEach(k => { if (integ[k]) c[k] = integ[k]; }); }
775
+ return c;
776
+ });
777
+ }
778
+
779
+ if (d.triggers?.length) {
780
+ out.triggers = d.triggers.map(trig => {
781
+ const c = {};
782
+ if (trig.type) c.type = trig.type;
783
+ if (trig.schedule) c.schedule = trig.schedule;
784
+ if (trig.path) c.path = trig.path;
785
+ if (trig.input) c.input = trig.input;
786
+ return c;
787
+ });
788
+ }
789
+
790
+ if (d.publish) out.publish = d.publish;
791
+ if (d.maxIterations) out.maxIterations = d.maxIterations;
792
+ if (d.sampleQuestions?.length) { const f = d.sampleQuestions.filter(q => q.trim()); if (f.length) out.sampleQuestions = f; }
793
+ if (d.metadata && Object.keys(d.metadata).length) out.metadata = d.metadata;
794
+ return out;
795
+ }
796
+
797
+ _esc(str) {
798
+ if (str === null || str === undefined) return '';
799
+ return String(str).replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
800
+ }
801
+
802
+ template() {
803
+ return '<div id="composerRoot" class="overflow-y-auto h-full p-4 space-y-4"></div>';
804
+ }
805
+ }
806
+
807
+ customElements.define('agent-composer', AgentComposer);