@stkxp/cli 0.1.2

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 (371) hide show
  1. package/README.md +273 -0
  2. package/bin/stkxp.mjs +198 -0
  3. package/package.json +97 -0
  4. package/src/bootstrap.mjs +37 -0
  5. package/src/bootstrap.test.mjs +73 -0
  6. package/src/deploy.mjs +145 -0
  7. package/src/deploy.test.mjs +131 -0
  8. package/src/export.mjs +30 -0
  9. package/src/export.test.mjs +56 -0
  10. package/src/secret-input.mjs +64 -0
  11. package/src/secret-input.test.mjs +58 -0
  12. package/src/serve.mjs +83 -0
  13. package/src/serve.test.mjs +93 -0
  14. package/vendor/dist-server/asyncapi/generator.js +1 -0
  15. package/vendor/dist-server/asyncapi/messages.js +1 -0
  16. package/vendor/dist-server/asyncapi/viewer.html +43 -0
  17. package/vendor/dist-server/core/app-config/branding.js +1 -0
  18. package/vendor/dist-server/core/app-config/mantine-theme.js +1 -0
  19. package/vendor/dist-server/core/app-config/mermaid-theme.js +2 -0
  20. package/vendor/dist-server/core/app-config/prompt-optimization.js +1 -0
  21. package/vendor/dist-server/core/app-config/settings.js +1 -0
  22. package/vendor/dist-server/core/config.js +1 -0
  23. package/vendor/dist-server/core/graph/a2a-agent-executor.js +2 -0
  24. package/vendor/dist-server/core/graph/app.js +120 -0
  25. package/vendor/dist-server/core/graph/delegated-agent-adapter.js +1 -0
  26. package/vendor/dist-server/core/graph/graph-builder.js +3 -0
  27. package/vendor/dist-server/core/graph/kibana-agent-executor.js +1 -0
  28. package/vendor/dist-server/core/graph/nodes/context/assistants-context.js +5 -0
  29. package/vendor/dist-server/core/graph/nodes/context/compare-context.js +10 -0
  30. package/vendor/dist-server/core/graph/nodes/context/enrich-context.js +8 -0
  31. package/vendor/dist-server/core/graph/nodes/context/inventory-context.js +4 -0
  32. package/vendor/dist-server/core/graph/nodes/context/namespace-context.js +2 -0
  33. package/vendor/dist-server/core/graph/nodes/context/node-types-context.js +4 -0
  34. package/vendor/dist-server/core/graph/nodes/context/relevant-assistants-context.js +5 -0
  35. package/vendor/dist-server/core/graph/nodes/context/relevant-skills-context.js +5 -0
  36. package/vendor/dist-server/core/graph/nodes/context/skills-context.js +8 -0
  37. package/vendor/dist-server/core/graph/nodes/context/state-setter.js +1 -0
  38. package/vendor/dist-server/core/graph/nodes/control/check-reset.js +1 -0
  39. package/vendor/dist-server/core/graph/nodes/control/topic-detection.js +1 -0
  40. package/vendor/dist-server/core/graph/nodes/governance/human-approval.js +16 -0
  41. package/vendor/dist-server/core/graph/nodes/index.js +1 -0
  42. package/vendor/dist-server/core/graph/nodes/orchestration/suggestion-generator.js +17 -0
  43. package/vendor/dist-server/core/graph/nodes/orchestration/team-decider.js +1 -0
  44. package/vendor/dist-server/core/graph/nodes/orchestration/team-execution/decider-error.js +4 -0
  45. package/vendor/dist-server/core/graph/nodes/orchestration/team-execution/decider-standalone-runner.js +1 -0
  46. package/vendor/dist-server/core/graph/nodes/orchestration/team-execution/decider-synthesis.js +29 -0
  47. package/vendor/dist-server/core/graph/nodes/orchestration/team-execution/pipeline-memory.js +2 -0
  48. package/vendor/dist-server/core/graph/nodes/orchestration/team-execution/pipeline-runner.js +7 -0
  49. package/vendor/dist-server/core/graph/nodes/orchestration/team-execution/team-assistant-utils.js +1 -0
  50. package/vendor/dist-server/core/graph/nodes/orchestration/team-finder.js +13 -0
  51. package/vendor/dist-server/core/graph/nodes/orchestration/team-invoker.js +3 -0
  52. package/vendor/dist-server/core/graph/nodes/orchestration/team-parallel.js +1 -0
  53. package/vendor/dist-server/core/graph/nodes/orchestration/team-pipeline.js +6 -0
  54. package/vendor/dist-server/core/graph/nodes/orchestration/team-router.js +26 -0
  55. package/vendor/dist-server/core/graph/nodes/reasoning/code-executor/index.js +6 -0
  56. package/vendor/dist-server/core/graph/nodes/reasoning/code-executor/resource-bridge.js +2 -0
  57. package/vendor/dist-server/core/graph/nodes/reasoning/code-executor/sandbox.js +6 -0
  58. package/vendor/dist-server/core/graph/nodes/reasoning/code-executor/tool-bridge.js +1 -0
  59. package/vendor/dist-server/core/graph/nodes/reasoning/local-extractor.js +5 -0
  60. package/vendor/dist-server/core/graph/nodes/reasoning/response-generator.js +47 -0
  61. package/vendor/dist-server/core/graph/nodes/reasoning/static-code-executor/index.js +1 -0
  62. package/vendor/dist-server/core/graph/nodes/reasoning/system.js +54 -0
  63. package/vendor/dist-server/core/graph/nodes/reasoning/tool-executor.js +9 -0
  64. package/vendor/dist-server/core/graph/nodes/tools/raw-output.js +4 -0
  65. package/vendor/dist-server/core/graph/nodes/tools/tool-cleaner.js +7 -0
  66. package/vendor/dist-server/core/graph/nodes/tools/tool-execution/execute-tool-calls.js +3 -0
  67. package/vendor/dist-server/core/graph/nodes/tools/tool-execution/invoke.js +1 -0
  68. package/vendor/dist-server/core/graph/nodes/tools/tool-execution/namespace-guard.js +1 -0
  69. package/vendor/dist-server/core/graph/nodes/tools/tool-execution/result-limits.js +3 -0
  70. package/vendor/dist-server/core/graph/nodes/tools/tool-invoker.js +1 -0
  71. package/vendor/dist-server/core/graph/nodes/tools/tool.js +4 -0
  72. package/vendor/dist-server/core/graph/schemas.js +1 -0
  73. package/vendor/dist-server/core/graph/topic-variants.js +1 -0
  74. package/vendor/dist-server/core/graph/types.js +1 -0
  75. package/vendor/dist-server/core/graph/utils/content-utils.js +17 -0
  76. package/vendor/dist-server/core/graph/utils/edge-jsonata-condition.js +1 -0
  77. package/vendor/dist-server/core/graph/utils/engine-vars.js +1 -0
  78. package/vendor/dist-server/core/graph/utils/logging-utils.js +4 -0
  79. package/vendor/dist-server/core/graph/utils/message-utils.js +5 -0
  80. package/vendor/dist-server/core/graph/utils/node-type-defaults-cache.js +1 -0
  81. package/vendor/dist-server/core/graph/utils/sandbox-catalog.js +1 -0
  82. package/vendor/dist-server/core/graph/utils/schema-utils.js +1 -0
  83. package/vendor/dist-server/core/graph/utils/team-context-policy.js +5 -0
  84. package/vendor/dist-server/core/graph/utils/team-node-resolvers.js +1 -0
  85. package/vendor/dist-server/core/graph/utils/tool-result.js +4 -0
  86. package/vendor/dist-server/core/graph/utils/tool-wrapper.js +14 -0
  87. package/vendor/dist-server/core/llm/init-indices.js +1 -0
  88. package/vendor/dist-server/core/llm/models/index.js +1 -0
  89. package/vendor/dist-server/core/llm/models/model.model.js +1 -0
  90. package/vendor/dist-server/core/llm/models/provider.model.js +1 -0
  91. package/vendor/dist-server/core/llm/models/routing-rule.model.js +1 -0
  92. package/vendor/dist-server/core/llm/providers.js +1 -0
  93. package/vendor/dist-server/core/mcp/client.js +1 -0
  94. package/vendor/dist-server/core/runtime/active-runs-registry.js +1 -0
  95. package/vendor/dist-server/core/runtime/system-prompt-cache.js +1 -0
  96. package/vendor/dist-server/core/runtime/trace-bus.js +1 -0
  97. package/vendor/dist-server/core/schema/cluster_health_report.js +1 -0
  98. package/vendor/dist-server/core/schema/cluster_info.js +1 -0
  99. package/vendor/dist-server/core/schema/cluster_license.js +5 -0
  100. package/vendor/dist-server/core/schema/cluster_stats.js +12 -0
  101. package/vendor/dist-server/core/schema/dashboard.js +1 -0
  102. package/vendor/dist-server/core/schema/indices_settings.js +1 -0
  103. package/vendor/dist-server/core/schema/indices_shards.js +1 -0
  104. package/vendor/dist-server/core/schema/indices_stats.js +1 -0
  105. package/vendor/dist-server/core/schema/nodes_info.js +2 -0
  106. package/vendor/dist-server/core/schema/nodes_stats.js +11 -0
  107. package/vendor/dist-server/core/schema/pricing.js +1 -0
  108. package/vendor/dist-server/core/schema/ui.js +1 -0
  109. package/vendor/dist-server/core/schema/zod_client.js +83 -0
  110. package/vendor/dist-server/core/services/a2a-client.js +2 -0
  111. package/vendor/dist-server/core/services/alerts-service.js +1 -0
  112. package/vendor/dist-server/core/services/api-keys-service.js +1 -0
  113. package/vendor/dist-server/core/services/assistant-resolver.js +1 -0
  114. package/vendor/dist-server/core/services/assistants-index-service.js +1 -0
  115. package/vendor/dist-server/core/services/async-conversations-service.js +22 -0
  116. package/vendor/dist-server/core/services/asyncapi-dispatch.js +1 -0
  117. package/vendor/dist-server/core/services/asyncapi-drivers/driver-manager.js +1 -0
  118. package/vendor/dist-server/core/services/asyncapi-drivers/driver-types.js +0 -0
  119. package/vendor/dist-server/core/services/asyncapi-drivers/http-driver.js +1 -0
  120. package/vendor/dist-server/core/services/asyncapi-drivers/nats-driver.js +1 -0
  121. package/vendor/dist-server/core/services/asyncapi-drivers/websocket-driver.js +1 -0
  122. package/vendor/dist-server/core/services/asyncapi-events-service.js +1 -0
  123. package/vendor/dist-server/core/services/asyncapi-reply-service.js +1 -0
  124. package/vendor/dist-server/core/services/asyncapi-sink.js +1 -0
  125. package/vendor/dist-server/core/services/asyncapi-tools-service.js +1 -0
  126. package/vendor/dist-server/core/services/block-repair-service.js +13 -0
  127. package/vendor/dist-server/core/services/chart-renderer.js +1 -0
  128. package/vendor/dist-server/core/services/chat-llms-service.js +1 -0
  129. package/vendor/dist-server/core/services/chat-runs-service.js +1 -0
  130. package/vendor/dist-server/core/services/chat-tools-service.js +1 -0
  131. package/vendor/dist-server/core/services/chat-traces-service.js +1 -0
  132. package/vendor/dist-server/core/services/chats-service.js +5 -0
  133. package/vendor/dist-server/core/services/comparison-service.js +107 -0
  134. package/vendor/dist-server/core/services/default-model.service.js +1 -0
  135. package/vendor/dist-server/core/services/elastic-stack-sync-service.js +2 -0
  136. package/vendor/dist-server/core/services/elasticsearch-wrapper.js +1 -0
  137. package/vendor/dist-server/core/services/embed-rate-limiter.js +1 -0
  138. package/vendor/dist-server/core/services/error-analytics-service.js +1 -0
  139. package/vendor/dist-server/core/services/es-field-resolver.js +1 -0
  140. package/vendor/dist-server/core/services/gateway-platform-types.js +1 -0
  141. package/vendor/dist-server/core/services/gliner-tagging-service.js +1 -0
  142. package/vendor/dist-server/core/services/golden-questions-scoring.js +1 -0
  143. package/vendor/dist-server/core/services/golden-questions-service.js +1 -0
  144. package/vendor/dist-server/core/services/graph-drilldown-service.js +1 -0
  145. package/vendor/dist-server/core/services/graph-registry-service.js +1 -0
  146. package/vendor/dist-server/core/services/hitl-analytics-service.js +1 -0
  147. package/vendor/dist-server/core/services/ingestion-jobs-service.js +1 -0
  148. package/vendor/dist-server/core/services/ingestion-service.js +5 -0
  149. package/vendor/dist-server/core/services/kibana-client-factory.js +1 -0
  150. package/vendor/dist-server/core/services/kibana-client.js +2 -0
  151. package/vendor/dist-server/core/services/kibana-dashboard-extractor.js +1 -0
  152. package/vendor/dist-server/core/services/kibana-service.js +1 -0
  153. package/vendor/dist-server/core/services/llm-analytics-service.js +1 -0
  154. package/vendor/dist-server/core/services/llm-client-resolver.js +1 -0
  155. package/vendor/dist-server/core/services/llm-models-service.js +1 -0
  156. package/vendor/dist-server/core/services/llm-pricing-pure.js +1 -0
  157. package/vendor/dist-server/core/services/llm-pricing-service.js +1 -0
  158. package/vendor/dist-server/core/services/llm-providers-service.js +1 -0
  159. package/vendor/dist-server/core/services/llm-routing-service.js +1 -0
  160. package/vendor/dist-server/core/services/llm-services.js +1 -0
  161. package/vendor/dist-server/core/services/llm-sync-service.js +1 -0
  162. package/vendor/dist-server/core/services/manifest-loader.js +1 -0
  163. package/vendor/dist-server/core/services/mcp-servers-service.js +1 -0
  164. package/vendor/dist-server/core/services/mcp-sync-service.js +1 -0
  165. package/vendor/dist-server/core/services/mcp-tools-service.js +1 -0
  166. package/vendor/dist-server/core/services/memories-service.js +2 -0
  167. package/vendor/dist-server/core/services/memory-analytics-service.js +1 -0
  168. package/vendor/dist-server/core/services/monitoring-analytics-service.js +1 -0
  169. package/vendor/dist-server/core/services/monitoring-service.js +1 -0
  170. package/vendor/dist-server/core/services/multi-kibana-service.js +1 -0
  171. package/vendor/dist-server/core/services/node-latency-service.js +1 -0
  172. package/vendor/dist-server/core/services/package-policy-service.js +2 -0
  173. package/vendor/dist-server/core/services/pdf-service.js +572 -0
  174. package/vendor/dist-server/core/services/plan-service.js +1 -0
  175. package/vendor/dist-server/core/services/platform-direction.js +1 -0
  176. package/vendor/dist-server/core/services/platform-secrets.js +1 -0
  177. package/vendor/dist-server/core/services/platforms-service.js +1 -0
  178. package/vendor/dist-server/core/services/policy-factory.js +1 -0
  179. package/vendor/dist-server/core/services/prompt-cache-service.js +1 -0
  180. package/vendor/dist-server/core/services/provider-rate-limits.js +1 -0
  181. package/vendor/dist-server/core/services/quota-service.js +1 -0
  182. package/vendor/dist-server/core/services/report-assets-service.js +1 -0
  183. package/vendor/dist-server/core/services/run-analytics-collector.js +1 -0
  184. package/vendor/dist-server/core/services/run-stream-sink.js +1 -0
  185. package/vendor/dist-server/core/services/send_mail.js +460 -0
  186. package/vendor/dist-server/core/services/share-service.js +1 -0
  187. package/vendor/dist-server/core/services/slack-signature.js +1 -0
  188. package/vendor/dist-server/core/services/sources-service.js +6 -0
  189. package/vendor/dist-server/core/services/team-mcp-result.js +4 -0
  190. package/vendor/dist-server/core/services/team-mcp-run-tokens.js +1 -0
  191. package/vendor/dist-server/core/services/team-mcp-runner.js +1 -0
  192. package/vendor/dist-server/core/services/team-mcp-server.js +1 -0
  193. package/vendor/dist-server/core/services/team-mcp-tools.js +1 -0
  194. package/vendor/dist-server/core/services/team-mcp-ui.js +551 -0
  195. package/vendor/dist-server/core/services/team-run-progress.js +1 -0
  196. package/vendor/dist-server/core/services/team-runner-headless.js +7 -0
  197. package/vendor/dist-server/core/services/team-search-service.js +1 -0
  198. package/vendor/dist-server/core/services/teams-service.js +1 -0
  199. package/vendor/dist-server/core/services/token-projection-service.js +1 -0
  200. package/vendor/dist-server/core/services/tool-analytics-service.js +1 -0
  201. package/vendor/dist-server/core/services/tool-history-service.js +1 -0
  202. package/vendor/dist-server/core/services/tool-metrics-service.js +1 -0
  203. package/vendor/dist-server/core/services/tool-scoring.js +1 -0
  204. package/vendor/dist-server/core/services/toolbox-import-mappers.js +1 -0
  205. package/vendor/dist-server/core/services/toolbox-import-service.js +1 -0
  206. package/vendor/dist-server/core/services/trigger-service.js +1 -0
  207. package/vendor/dist-server/core/services/version-snapshot-service.js +1 -0
  208. package/vendor/dist-server/core/services/webhook-calls-service.js +1 -0
  209. package/vendor/dist-server/core/tools/compare-chat.js +46 -0
  210. package/vendor/dist-server/core/tools/enrich-chat.js +50 -0
  211. package/vendor/dist-server/core/tools/variable-encoding.js +1 -0
  212. package/vendor/dist-server/core/types/settings.js +1 -0
  213. package/vendor/dist-server/core/utils/ab-evaluator.js +5 -0
  214. package/vendor/dist-server/core/utils/condition-evaluator.js +1 -0
  215. package/vendor/dist-server/core/utils/http-client.js +1 -0
  216. package/vendor/dist-server/core/utils/json-schema-to-form.js +1 -0
  217. package/vendor/dist-server/core/utils/logger.js +3 -0
  218. package/vendor/dist-server/core/utils/owner-scope.js +1 -0
  219. package/vendor/dist-server/core/utils/ownership.js +1 -0
  220. package/vendor/dist-server/core/utils/parallel-tool-executor.js +1 -0
  221. package/vendor/dist-server/core/utils/performance-tracker.js +3 -0
  222. package/vendor/dist-server/core/utils/prompt-optimizer.js +40 -0
  223. package/vendor/dist-server/core/utils/response-cache.js +1 -0
  224. package/vendor/dist-server/core/utils/schema-validator.js +1 -0
  225. package/vendor/dist-server/core/utils/streaming-optimizer.js +2 -0
  226. package/vendor/dist-server/core/utils/string-helpers.js +1 -0
  227. package/vendor/dist-server/core/utils/test-responses.js +9 -0
  228. package/vendor/dist-server/core/utils/text-utils.js +1 -0
  229. package/vendor/dist-server/core/utils/tool-form-trigger.js +1 -0
  230. package/vendor/dist-server/entrypoints/cli-bootstrap-run.js +1 -0
  231. package/vendor/dist-server/entrypoints/cli-deploy-run.js +1 -0
  232. package/vendor/dist-server/entrypoints/cli-deploy.js +1 -0
  233. package/vendor/dist-server/entrypoints/team-runner.js +1 -0
  234. package/vendor/dist-server/generated/toolbox-catalog.js +1 -0
  235. package/vendor/dist-server/index.js +2 -0
  236. package/vendor/dist-server/middleware/integration-logos.js +1 -0
  237. package/vendor/dist-server/middleware/plan-guard.js +1 -0
  238. package/vendor/dist-server/openapi/generator.js +1 -0
  239. package/vendor/dist-server/openapi/html-tool-spec.js +1 -0
  240. package/vendor/dist-server/routes/a2a-routes.js +1 -0
  241. package/vendor/dist-server/routes/a2a-server-routes.js +5 -0
  242. package/vendor/dist-server/routes/admin.js +1 -0
  243. package/vendor/dist-server/routes/assistants-routes.js +1 -0
  244. package/vendor/dist-server/routes/asyncapi-routes.js +1 -0
  245. package/vendor/dist-server/routes/auth.js +1 -0
  246. package/vendor/dist-server/routes/billing-routes.js +1 -0
  247. package/vendor/dist-server/routes/chat-llms.js +1 -0
  248. package/vendor/dist-server/routes/chat-tools.js +1 -0
  249. package/vendor/dist-server/routes/chat-traces.js +1 -0
  250. package/vendor/dist-server/routes/chats.js +1 -0
  251. package/vendor/dist-server/routes/clusters.js +1 -0
  252. package/vendor/dist-server/routes/compare.js +43 -0
  253. package/vendor/dist-server/routes/connectors-routes.js +1 -0
  254. package/vendor/dist-server/routes/consumptions-routes.js +1 -0
  255. package/vendor/dist-server/routes/data-admin-routes.js +1 -0
  256. package/vendor/dist-server/routes/data-transfer-routes.js +1 -0
  257. package/vendor/dist-server/routes/elastic-tool-execution-routes.js +1 -0
  258. package/vendor/dist-server/routes/geo-proxy-routes.js +1 -0
  259. package/vendor/dist-server/routes/golden-questions-routes.js +1 -0
  260. package/vendor/dist-server/routes/graph-registry.js +1 -0
  261. package/vendor/dist-server/routes/graph-templates-routes.js +1 -0
  262. package/vendor/dist-server/routes/helpdesk-routes.js +35 -0
  263. package/vendor/dist-server/routes/html-routes.js +1 -0
  264. package/vendor/dist-server/routes/index.js +1 -0
  265. package/vendor/dist-server/routes/indices.js +1 -0
  266. package/vendor/dist-server/routes/integrations-routes.js +1 -0
  267. package/vendor/dist-server/routes/langgraph.js +7 -0
  268. package/vendor/dist-server/routes/live-resources-routes.js +1 -0
  269. package/vendor/dist-server/routes/llm-analytics.js +1 -0
  270. package/vendor/dist-server/routes/llm-control-plane.js +1 -0
  271. package/vendor/dist-server/routes/llm.js +1 -0
  272. package/vendor/dist-server/routes/mcp-gateway-routes.js +1 -0
  273. package/vendor/dist-server/routes/mcp-query-routes.js +1 -0
  274. package/vendor/dist-server/routes/mcp-servers-routes.js +1 -0
  275. package/vendor/dist-server/routes/mcp-team-routes.js +1 -0
  276. package/vendor/dist-server/routes/mcp-tools-routes.js +1 -0
  277. package/vendor/dist-server/routes/me-routes.js +63 -0
  278. package/vendor/dist-server/routes/memories-routes.js +1 -0
  279. package/vendor/dist-server/routes/monitoring-analytics.js +12 -0
  280. package/vendor/dist-server/routes/monitoring.js +1 -0
  281. package/vendor/dist-server/routes/node-types-routes.js +171 -0
  282. package/vendor/dist-server/routes/nodes.js +1 -0
  283. package/vendor/dist-server/routes/packages.js +1 -0
  284. package/vendor/dist-server/routes/pdf.js +3 -0
  285. package/vendor/dist-server/routes/plan-routes.js +1 -0
  286. package/vendor/dist-server/routes/platform-requests-routes.js +1 -0
  287. package/vendor/dist-server/routes/platforms-routes.js +1 -0
  288. package/vendor/dist-server/routes/prompts-routes.js +1 -0
  289. package/vendor/dist-server/routes/proxy-logos.js +1 -0
  290. package/vendor/dist-server/routes/quality-routes.js +1 -0
  291. package/vendor/dist-server/routes/resources-ingest-routes.js +1 -0
  292. package/vendor/dist-server/routes/resources-routes.js +1 -0
  293. package/vendor/dist-server/routes/schema-routes.js +1 -0
  294. package/vendor/dist-server/routes/settings-original.js +1 -0
  295. package/vendor/dist-server/routes/settings.js +1 -0
  296. package/vendor/dist-server/routes/share-routes.js +1 -0
  297. package/vendor/dist-server/routes/sources-catalog-routes.js +1 -0
  298. package/vendor/dist-server/routes/sources-routes.js +1 -0
  299. package/vendor/dist-server/routes/team-optimizer-routes.js +1 -0
  300. package/vendor/dist-server/routes/team-schedule-routes.js +1 -0
  301. package/vendor/dist-server/routes/teams-routes.js +1 -0
  302. package/vendor/dist-server/routes/tool-analytics.js +1 -0
  303. package/vendor/dist-server/routes/tool-history-routes.js +1 -0
  304. package/vendor/dist-server/routes/tool-metrics-routes.js +1 -0
  305. package/vendor/dist-server/routes/toolbox-import-routes.js +1 -0
  306. package/vendor/dist-server/routes/tools-routes.js +5 -0
  307. package/vendor/dist-server/routes/transcribe-routes.js +1 -0
  308. package/vendor/dist-server/routes/triggers.js +1 -0
  309. package/vendor/dist-server/routes/versions-routes.js +1 -0
  310. package/vendor/dist-server/routes/webhooks-routes.js +1 -0
  311. package/vendor/dist-server/scripts/add-label-to-tools.js +4 -0
  312. package/vendor/dist-server/scripts/migrate-assistants-to-mcp.js +10 -0
  313. package/vendor/dist-server/scripts/migrate-chat-runs.js +8 -0
  314. package/vendor/dist-server/scripts/migrate-mcp-protocol.js +8 -0
  315. package/vendor/dist-server/scripts/migrate-mcp-to-platforms.js +15 -0
  316. package/vendor/dist-server/services/alert-evaluator.js +3 -0
  317. package/vendor/dist-server/services/auth.js +1 -0
  318. package/vendor/dist-server/services/billing-service.js +1 -0
  319. package/vendor/dist-server/services/chat-title-generator.js +12 -0
  320. package/vendor/dist-server/services/clone/clone-executor.js +1 -0
  321. package/vendor/dist-server/services/clone/closure-resolver.js +3 -0
  322. package/vendor/dist-server/services/clone/entity-graph.js +3 -0
  323. package/vendor/dist-server/services/clone/team-bundle-bootstrap.js +1 -0
  324. package/vendor/dist-server/services/clone/team-bundle-crypto.js +1 -0
  325. package/vendor/dist-server/services/clone/team-bundle-encrypted.js +1 -0
  326. package/vendor/dist-server/services/clone/team-bundle.js +1 -0
  327. package/vendor/dist-server/services/cluster-service.js +1 -0
  328. package/vendor/dist-server/services/connection-adapters.js +1 -0
  329. package/vendor/dist-server/services/connectors-service.js +10 -0
  330. package/vendor/dist-server/services/cost-forecast-service.js +1 -0
  331. package/vendor/dist-server/services/eui-ssr-renderer.js +4 -0
  332. package/vendor/dist-server/services/graph-canvas/full-structure-builder.js +1 -0
  333. package/vendor/dist-server/services/graph-templates-service.js +13 -0
  334. package/vendor/dist-server/services/guest-service.js +1 -0
  335. package/vendor/dist-server/services/html-service.js +1 -0
  336. package/vendor/dist-server/services/langgraph-service.js +2 -0
  337. package/vendor/dist-server/services/leaflet-render-service.js +80 -0
  338. package/vendor/dist-server/services/live-resources-service.js +16 -0
  339. package/vendor/dist-server/services/mcp-app-tester-package.js +1 -0
  340. package/vendor/dist-server/services/mcp-gateway/executors/openapi-executor.js +1 -0
  341. package/vendor/dist-server/services/mcp-gateway/gateway-grant-service.js +2 -0
  342. package/vendor/dist-server/services/team-optimizer-service.js +1 -0
  343. package/vendor/dist-server/services/trace-bus-sink.js +1 -0
  344. package/vendor/dist-server/services/user-provisioning-service.js +3 -0
  345. package/vendor/dist-server/templates/mcp-app-tester/src/mcp-http.js +3 -0
  346. package/vendor/dist-server/templates/mcp-app-tester/src/server.js +1 -0
  347. package/vendor/dist-server/utils.js +1 -0
  348. package/vendor/dist-server/ws/assistant-executor.js +7 -0
  349. package/vendor/dist-server/ws/classify-streamed-json-block.js +1 -0
  350. package/vendor/dist-server/ws/collect-response-generator-node-ids.js +1 -0
  351. package/vendor/dist-server/ws/extractors/blockkit-extractor.js +1 -0
  352. package/vendor/dist-server/ws/extractors/echarts-extractor.js +1 -0
  353. package/vendor/dist-server/ws/extractors/eui-extractor.js +1 -0
  354. package/vendor/dist-server/ws/extractors/form-extractor.js +1 -0
  355. package/vendor/dist-server/ws/extractors/index.js +1 -0
  356. package/vendor/dist-server/ws/extractors/leaflet-extractor.js +1 -0
  357. package/vendor/dist-server/ws/extractors/mantine-extractor.js +1 -0
  358. package/vendor/dist-server/ws/extractors/markdown-extractor.js +7 -0
  359. package/vendor/dist-server/ws/extractors/mermaid-extractor.js +1 -0
  360. package/vendor/dist-server/ws/extractors/recharts-extractor.js +1 -0
  361. package/vendor/dist-server/ws/extractors/remotion-extractor.js +1 -0
  362. package/vendor/dist-server/ws/handler.js +66 -0
  363. package/vendor/dist-server/ws/parsers/anthropic-parser.js +7 -0
  364. package/vendor/dist-server/ws/parsers/base-parser.js +3 -0
  365. package/vendor/dist-server/ws/parsers/gemini-parser.js +8 -0
  366. package/vendor/dist-server/ws/parsers/index.js +1 -0
  367. package/vendor/dist-server/ws/parsers/parse-json-blocks.js +1 -0
  368. package/vendor/dist-server/ws/types.js +0 -0
  369. package/vendor/dist-server/ws/utils.js +1 -0
  370. package/vendor/shared/engine-vars.ts +51 -0
  371. package/vendor/shared/llm-providers-config.ts +69 -0
@@ -0,0 +1 @@
1
+ import{z as e}from"zod";const t=e.string().describe("Identifier of the assistant run that produced this event"),a=[{name:"ChatMessage",discriminator:"message",direction:"clientToServer",summary:"Submit a user message to start or continue an assistant run",description:"Sent by the client to initiate a chat turn. The handler resolves the team/assistant, builds the LangGraph state and starts streaming response events back over the same WebSocket.",tags:["chat"],schema:e.object({type:e.literal("message"),text:e.string().describe("Raw user input"),teamId:e.string().optional(),chatId:e.string().optional().describe("Resume an existing chat by id, otherwise a new chat is created"),assistantId:e.string().optional(),threadId:e.string().optional()})},{name:"InterruptCommand",discriminator:"interrupt",direction:"clientToServer",summary:"Cancel the in-flight run on this connection",description:"The server stops streaming, cleans up the LangGraph stream, and emits `interrupted`.",tags:["control"],schema:e.object({type:e.literal("interrupt"),runId:t.optional()})},{name:"HitlResume",discriminator:"hitl_resume",direction:"clientToServer",summary:"Resume a paused run with values supplied by the user",description:"Sent in response to a `hitl_interrupt` event. The payload travels back through the LangGraph checkpointer and the run resumes from where it paused.",tags:["hitl"],schema:e.object({type:e.literal("hitl_resume"),runId:t,values:e.record(e.any()).optional().describe("Form values keyed by field name")})},{name:"FormSubmit",discriminator:"form_submit",direction:"clientToServer",summary:"Submit a form rendered earlier in the stream",description:"Used by the dynamic form system to feed user-edited values back to the running graph.",tags:["form"],schema:e.object({type:e.literal("form_submit"),runId:t,formId:e.string(),values:e.record(e.any())})},{name:"AssistantStart",discriminator:"assistant_start",direction:"serverToClient",summary:"An assistant subgraph has begun executing",description:"Emitted when the team handler enters a new assistant. Multiple `assistant_start`/`assistant_end` pairs appear for a multi-assistant team run.",tags:["lifecycle"],schema:e.object({type:e.literal("assistant_start"),runId:t,assistantId:e.string(),assistantName:e.string().optional()})},{name:"AssistantEnd",discriminator:"assistant_end",direction:"serverToClient",summary:"An assistant subgraph has finished",tags:["lifecycle"],schema:e.object({type:e.literal("assistant_end"),runId:t,assistantId:e.string(),assistantName:e.string().optional(),llm:e.object({provider:e.string().optional(),modelId:e.string().optional(),inputTokens:e.number().optional(),outputTokens:e.number().optional(),totalTokens:e.number().optional()}).optional()})},{name:"MarkdownToken",discriminator:"markdown_token",direction:"serverToClient",summary:"Streaming chunk of clean markdown text",description:"Character-by-character (or token-by-token) stream of the assistant's textual response. Stripped of JSON envelope and structural noise \u2014 the `MarkdownExtractor` only forwards human-readable content.",tags:["streaming"],schema:e.object({type:e.literal("markdown_token"),runId:t,text:e.string()})},{name:"ToolStart",discriminator:"tool_start",direction:"serverToClient",summary:"An MCP tool is about to be invoked",tags:["tool"],schema:e.object({type:e.literal("tool_start"),runId:t,text:e.string().describe("JSON-encoded `{ toolName, toolInput }` \u2014 kept as a string for backwards compatibility")})},{name:"ToolEnd",discriminator:"tool_end",direction:"serverToClient",summary:"An MCP tool call has finished",tags:["tool"],schema:e.object({type:e.literal("tool_end"),runId:t,text:e.string().describe("JSON-encoded `{ toolName, output }`")})},{name:"TokenUsage",discriminator:"token_usage",direction:"serverToClient",summary:"LLM cost telemetry for one assistant iteration",description:"Emitted at the end of each assistant turn within a run. Aggregated client-side into the per-run `metadata.tokenUsage` of the `.stkxp_chats` doc.",tags:["telemetry"],schema:e.object({type:e.literal("token_usage"),runId:t,assistantId:e.string().optional(),provider:e.string().optional(),modelId:e.string().optional(),inputTokens:e.number(),outputTokens:e.number(),totalTokens:e.number()})},{name:"HitlInterrupt",discriminator:"hitl_interrupt",direction:"serverToClient",summary:"Run is paused waiting for user input (Human-in-the-loop)",description:"The client should render an interactive prompt (form, choice list, free text) and reply with a `hitl_resume` message carrying the user's answer.",tags:["hitl"],schema:e.object({type:e.literal("hitl_interrupt"),runId:t,prompt:e.string().optional(),schema:e.any().optional().describe("JSON Schema describing the expected response shape")})},{name:"Block",discriminator:"block",direction:"serverToClient",summary:"A fully-formed structured block (dashboard tile, chart, table, \u2026)",description:"Emitted by the JSON slicer when a complete block is parsed from the LLM output. Block types include `markdown`, `echarts`, `mermaid`, `table`, `metric`, `leaflet`, `recharts`, `image`, etc.",tags:["dashboard"],schema:e.object({type:e.literal("block"),data:e.record(e.any()).describe("The block payload \u2014 shape varies by block.type")})},{name:"RunError",discriminator:"error",direction:"serverToClient",summary:"Run-level error (recoverable or fatal)",tags:["lifecycle"],schema:e.object({type:e.literal("error"),runId:t.optional(),message:e.string(),code:e.string().optional()})}];export{a as messages};
@@ -0,0 +1,43 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <title>Stack Expert WS — AsyncAPI docs</title>
6
+ <meta name="viewport" content="width=device-width,initial-scale=1" />
7
+ <link
8
+ rel="stylesheet"
9
+ href="https://unpkg.com/@asyncapi/react-component@2.6.4/styles/default.min.css"
10
+ />
11
+ <style>
12
+ body { margin: 0; font-family: system-ui, sans-serif; }
13
+ #asyncapi { min-height: 100vh; }
14
+ .loading { padding: 24px; color: #555; }
15
+ </style>
16
+ </head>
17
+ <body>
18
+ <div id="asyncapi"><div class="loading">Loading AsyncAPI spec…</div></div>
19
+ <script src="https://unpkg.com/@asyncapi/react-component@2.6.4/browser/standalone/index.js"></script>
20
+ <script>
21
+ (async () => {
22
+ try {
23
+ const res = await fetch('/api/asyncapi.json');
24
+ if (!res.ok) throw new Error('Failed to fetch /api/asyncapi.json: ' + res.status);
25
+ const schema = await res.json();
26
+ AsyncApiStandalone.render(
27
+ {
28
+ schema,
29
+ config: {
30
+ show: { sidebar: true, info: true, servers: true, operations: true, messages: true, schemas: true },
31
+ expand: { messageExamples: true },
32
+ },
33
+ },
34
+ document.getElementById('asyncapi')
35
+ );
36
+ } catch (err) {
37
+ document.getElementById('asyncapi').innerHTML =
38
+ '<pre style="padding:24px;color:#b00">' + (err && err.message ? err.message : String(err)) + '</pre>';
39
+ }
40
+ })();
41
+ </script>
42
+ </body>
43
+ </html>
@@ -0,0 +1 @@
1
+ const s=process.env.STKXP_BRAND_NAME??"Stack Expert",t=process.env.STKXP_BRAND_TAGLINE??"AI Assistant",A=`${s} \u2014 ${t}`;export{A as BRAND_FULL_TITLE,s as BRAND_NAME,t as BRAND_TAGLINE};
@@ -0,0 +1 @@
1
+ const e=["#eaf6ff","#d0ecff","#a1d8ff","#6cc0ff","#41a8ff","#1f8ff2","#0077CC","#0067b3","#005596","#00447a"],f={primaryColor:"blue",colors:{blue:e},defaultRadius:"md",fontFamily:'system-ui, -apple-system, "Segoe UI", sans-serif'};export{f as mantineTheme};
@@ -0,0 +1,2 @@
1
+ const e={primary:"#0077CC",primaryText:"#343741",success:"#017D73",danger:"#BD271E",warning:"#F5A700",accent:"#DD0A73",subdued:"#69707D",background:"#ffffff",lightShade:"#F5F7FA",mediumShade:"#D3DAE6",darkShade:"#98A2B3",text:"#343741",textSubdued:"#69707D",border:"#D3DAE6",borderStrong:"#98A2B3"},i={primaryColor:e.primary,primaryTextColor:e.primaryText,primaryBorderColor:e.border,lineColor:e.subdued,secondaryColor:e.success,tertiaryColor:e.accent,background:e.background,mainBkg:e.lightShade,secondaryBkg:e.mediumShade,tertiaryBkg:"#FFF4E0",textColor:e.text,nodeBorder:e.border,clusterBorder:e.borderStrong,errorBkgColor:e.danger,errorTextColor:"#ffffff",classText:e.text,labelColor:e.text,actorBorder:e.border,actorBkg:e.lightShade,actorTextColor:e.text,actorLineColor:e.subdued,signalColor:e.text,signalTextColor:e.text,gridColor:e.mediumShade,todayLineColor:e.danger,git0:e.primary,git1:e.success,git2:e.warning,git3:e.accent,git4:"#9170B8",git5:"#54B399",git6:"#E7664C",git7:"#DA8B45",pie1:e.primary,pie2:e.success,pie3:e.warning,pie4:e.accent,pie5:"#9170B8",pie6:"#54B399",pie7:"#E7664C",pie8:"#DA8B45",pie9:"#6092C0",pie10:"#D6BF57",pie11:"#B9A888",pie12:"#DA8B45"},o={theme:"base",themeVariables:i,fontFamily:'system-ui, -apple-system, "Segoe UI", "Roboto", "Helvetica Neue", "Arial", sans-serif',startOnLoad:!1,securityLevel:"strict",flowchart:{diagramPadding:16,htmlLabels:!0,curve:"basis",useMaxWidth:!0,rankSpacing:50,nodeSpacing:50},sequence:{diagramMarginX:50,diagramMarginY:30,actorMargin:50,width:150,height:65,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,mirrorActors:!0,useMaxWidth:!0},gantt:{titleTopMargin:25,barHeight:20,barGap:4,topPadding:50,leftPadding:75,gridLineStartPadding:35,fontSize:12,sectionFontSize:14,numberSectionStyles:4,axisFormat:"%Y-%m-%d",useMaxWidth:!0},class:{useMaxWidth:!0},state:{dividerMargin:10,sizeUnit:5,padding:8,textHeight:10,titleShift:-15,noteMargin:10,forkWidth:70,forkHeight:7,miniPadding:2,fontSizeFactor:5.02,fontSize:24,labelHeight:16,edgeLengthFactor:"20",compositTitleSize:35,radius:5,useMaxWidth:!0},er:{diagramPadding:20,layoutDirection:"TB",minEntityWidth:100,minEntityHeight:75,entityPadding:15,stroke:e.border,fill:e.lightShade,fontSize:12,useMaxWidth:!0},gitGraph:{diagramPadding:8,nodeLabel:{width:75,height:100,x:-25,y:0},mainBranchName:"main",mainBranchOrder:0,showCommitLabel:!0,showBranches:!0,rotateCommitLabel:!0},pie:{useMaxWidth:!0,textPosition:.75},maxTextSize:5e4,maxEdges:500,logLevel:process.env.NODE_ENV==="production"?"error":"warn"},d={...i,primaryColor:"#36A2EF",background:"#1D1E24",mainBkg:"#25262E",secondaryBkg:"#343741",textColor:"#DFE5EF",primaryTextColor:"#DFE5EF",lineColor:"#535966",primaryBorderColor:"#343741",nodeBorder:"#535966",clusterBorder:"#69707D",actorBkg:"#25262E",actorBorder:"#535966",actorTextColor:"#DFE5EF",signalColor:"#DFE5EF",signalTextColor:"#DFE5EF",labelColor:"#DFE5EF"};function l(t){if(!t||typeof t!="string")return!1;const r=t.trim();return r.length===0?!1:["graph","flowchart","sequenceDiagram","classDiagram","stateDiagram","stateDiagram-v2","erDiagram","gantt","pie","gitGraph","journey","quadrantChart","requirementDiagram","mindmap","timeline"].some(a=>r.startsWith(a)||r.includes(`
2
+ ${a}`))}function g(t="browser"){const r={...o};switch(t){case"ssr":return{...r,startOnLoad:!1,securityLevel:"strict",logLevel:"error"};case"pdf":return{...r,startOnLoad:!1,securityLevel:"strict",logLevel:"error",flowchart:{...r.flowchart,htmlLabels:!1}};case"browser":default:return r}}var c=o;export{e as EUI_COLORS,c as default,d as euiDarkThemeVariables,i as euiThemeVariables,g as getMermaidConfig,o as mermaidThemeConfig,l as validateMermaidSyntax};
@@ -0,0 +1 @@
1
+ const o={maxAgentPromptTokens:parseInt(process.env.MAX_AGENT_PROMPT_TOKENS||"1500",10),enableTruncation:process.env.ENABLE_PROMPT_TRUNCATION!=="false",compactParams:process.env.COMPACT_PARAMS!=="false",maxToolNamesInPrompt:parseInt(process.env.MAX_TOOL_NAMES_IN_PROMPT||"5",10),verboseLogging:process.env.VERBOSE_PROMPT_OPTIMIZATION==="true"};function n(e){return{...o,...e}}export{n as getPromptOptimizationConfig,o as promptOptimizationConfig};
@@ -0,0 +1 @@
1
+ const e={certificates:void 0,kibana:{hostname:"51.159.174.230",port:5605,basePath:"",credentials:{username:process.env.ELASTICSEARCH_USER||"elastic",password:process.env.ELASTICSEARCH_PASSWORD||""},apiKey:void 0},defaults:{timeout:5e3,interval:"10m",packageVersion:"0.0.99",minimalPackageVersion:"0.0.81"},fleet:{policyId:"fleet-server-policy"}};export{e as settingsConfig};
@@ -0,0 +1 @@
1
+ import t from"path";import{fileURLToPath as n}from"url";import c from"fs";const a=t.dirname(n(import.meta.url));function i(e){if(e)try{return c.readFileSync(e)}catch{return}}const l={path:{work:a,tmp:"/tmp",json:"./json",dev:"./dev",csv:"./log/csv",log:"./log"},elasticsearch:{node:process.env.ELASTICSEARCH_HOST||"https://51.159.174.230:9205",auth:{username:process.env.ELASTICSEARCH_USER||"elastic",password:process.env.ELASTICSEARCH_PASSWORD||""},tls:{ca:i(process.env.ELASTICSEARCH_CA_PATH),rejectUnauthorized:process.env.ELASTICSEARCH_TLS_REJECT_UNAUTHORIZED!=="false"},maxRetries:1,requestTimeout:5e3},hosts:{mcp:"127.0.0.1"},ports:{mcp:3001},llm:{provider:process.env.LLM_PROVIDER||"openai",model:process.env.LLM_MODEL||"gpt-4o-mini",temperature:parseFloat(process.env.LLM_TEMPERATURE||"0"),streaming:process.env.LLM_STREAMING!=="false",apiKey:void 0,baseURL:process.env.LLM_BASE_URL,promptAdapter:{maxTokens:parseInt(process.env.PROMPT_ADAPTER_MAX_TOKENS||"20000")}},stripeSecretKey:process.env.STRIPE_SECRET_KEY||"sk_test_2A5bKqqtuLx4i3ti6iCRzAlz",stripeWebhookSecret:process.env.STRIPE_WEBHOOK_SECRET||"",stripePrices:{basic:process.env.STRIPE_PRICE_BASIC||"",enterprise:process.env.STRIPE_PRICE_ENTERPRISE||"",premium:process.env.STRIPE_PRICE_PREMIUM||""},jwtSecret:"PierDavForce",issuer:"stkxp",httpOptions:{allowCrossDomain:function(e,s,o){var r=!1;s.header("Access-Control-Allow-Origin","*"),s.header("Access-Control-Allow-Methods","PUT, GET, POST, DELETE, OPTIONS"),s.header("Access-Control-Allow-Headers","Content-Type"),r=!0,e.headers["access-control-request-method"]&&(s.header("Access-Control-Allow-Methods",e.headers["access-control-request-method"]),r=!0),e.headers["access-control-request-headers"]&&(s.header("Access-Control-Allow-Headers",e.headers["access-control-request-headers"]),r=!0),r&&s.header("Access-Control-Max-Age",3600*24*365),r&&e.method=="OPTIONS"?s.sendStatus(200):o()},rawParser:function(e){return e.raw({type:"*/*"})}}};export{l as config};
@@ -0,0 +1,2 @@
1
+ function u(a){const e=a.a2aAgent??{};if(!e.agentUrl)throw new Error("A2A agent graph is missing a2aAgent.agentUrl");return{isA2aAgent:!0,agentUrl:e.agentUrl,authKey:e.authKey,metadata:e.metadata,cleanup:()=>{}}}async function A(a,e,n={}){const{A2aClient:l}=await import("../services/a2a-client"),i=new l({agentUrl:a.agentUrl,authKey:a.authKey,timeout:12e4});let c=!0;try{c=(await i.getAgentCard()).streaming}catch(t){console.warn(`[A2aAgent] Could not fetch agent card (will use streaming): ${t.message}`)}let s="";const g=[],d=c?i.sendSubscribe(e,void 0,n.abortSignal,a.metadata):(async function*(){yield await i.send(e,void 0,n.abortSignal,a.metadata)})();for await(const t of d){if(n.abortSignal?.aborted)break;switch(t.type){case"text_chunk":s+=t.text,n.onToken?.(t.text);break;case"tool_call":g.push(t.toolName),n.onToolStart?.(t.toolName);break;case"completed":if(t.artifacts?.length){const o=t.artifacts.flatMap(r=>r.parts??[]).filter(r=>r.type==="text").map(r=>r.text).join(`
2
+ `);o&&(s=o)}g.forEach(o=>n.onToolEnd?.(o));break;case"error":throw new Error(t.error)}}return{text:s,toolsUsed:g}}export{u as buildA2aAgentApp,A as runA2aAgentConversation};
@@ -0,0 +1,120 @@
1
+ import{MessagesAnnotation as _e,StateGraph as Ae,Annotation as J}from"@langchain/langgraph";import{AIMessage as Pe,SystemMessage as Ce}from"@langchain/core/messages";import{createLLMInstance as ne}from"../llm/providers";import{config as X}from"../config";import{loadMcpTools as Me}from"@langchain/mcp-adapters";import{createAgent as Oe}from"langchain";import{DynamicStructuredTool as G}from"@langchain/core/tools";import{z as g}from"zod";import{TavilySearch as ve}from"@langchain/tavily";import{PerformanceTracker as Se}from"../utils/performance-tracker";import{buildOptimizedSystemPrompt as $e}from"../utils/prompt-optimizer";import{promptOptimizationConfig as se}from"../app-config/prompt-optimization";import{runTopicABTest as we,generateTopicHybrid as Ee}from"./topic-variants";import{createCompareChatTool as ke}from"../tools/compare-chat";import{TOOL_RESULT_MAX_TOKENS as re}from"./utils/content-utils";import ae from"jsonwebtoken";import{Client as Le}from"@elastic/elasticsearch";import{createMcpClient as Ne}from"../mcp/client";const Re=process.env.ELASTICSEARCH_HOST||"https://51.159.174.230:9205",Ie=process.env.ELASTICSEARCH_USER||"elastic",xe=process.env.ELASTICSEARCH_PASSWORD||"",ie=".stkxp_platforms",L=new Le({node:Re,auth:{username:Ie,password:xe},tls:{rejectUnauthorized:!1},requestTimeout:3e4,maxRetries:3,maxSockets:256,maxFreeSockets:256});L.connectionPool&&typeof L.connectionPool.setMaxListeners=="function"&&L.connectionPool.setMaxListeners(50);const F=new Map,De=300*1e3;setInterval(()=>{const o=Date.now();for(const[t,r]of F.entries())r.refCount===0&&o-r.lastUsed>De&&(console.log(`[MCP Pool] Closing inactive client: ${t}`),r.client.close().catch(c=>console.error("[MCP Pool] Error closing client:",c)),F.delete(t))},120*1e3);async function Fe(o,t){const r=`${o}`,c=F.get(r);if(c)return console.log(`[MCP Pool] Reusing existing client for ${o}`),c.lastUsed=Date.now(),c.refCount++,c.client;console.log(`[MCP Pool] Creating new client for ${o}`);const i=await Ne(o,t);return i.transport&&typeof i.transport.setMaxListeners=="function"&&i.transport.setMaxListeners(50),i.client&&typeof i.client.setMaxListeners=="function"&&i.client.setMaxListeners(50),F.set(r,{client:i,lastUsed:Date.now(),refCount:1}),i}function Ue(o){const t=`${o}`,r=F.get(t);r&&(r.refCount=Math.max(0,r.refCount-1),r.lastUsed=Date.now())}async function je(o){try{const t=o.toLowerCase().replace(/\s+/g,"_").split("_")[0]||"clusters";console.log(`[MCP Discovery] Searching for servers with packageName matching "${t}" and enabled=true`);const c=(await L.search({index:ie,body:{query:{bool:{must:[{term:{enabled:!0}},{prefix:{"packageName.keyword":t}}]}},size:100,sort:[{createdAt:{order:"desc"}}]}})).hits.hits.map(i=>({id:i._id,name:i._source.name,url:i._source.url,authKey:i._source.authKey,type:i._source.type,packageName:i._source.packageName,enabled:i._source.enabled,description:i._source.description}));if(console.log(`[MCP Discovery] Found ${c.length} enabled servers for system "${t}"`),c.length>0)return console.log("[MCP Discovery] Servers:",c.map(i=>`${i.name} (${i.packageName})`).join(", ")),c;if(t!=="clusters"&&t!=="unknown"){console.log(`[MCP Discovery] No servers found for "${t}", falling back to "clusters" package`);const P=(await L.search({index:ie,body:{query:{bool:{must:[{term:{enabled:!0}},{prefix:{"packageName.keyword":"clusters"}}]}},size:100,sort:[{createdAt:{order:"desc"}}]}})).hits.hits.map(y=>({id:y._id,name:y._source.name,url:y._source.url,authKey:y._source.authKey,type:y._source.type,packageName:y._source.packageName,enabled:y._source.enabled,description:y._source.description}));if(P.length>0)return console.log(`[MCP Discovery] \u2705 Fallback successful: Found ${P.length} "clusters" server(s)`),P}return c}catch(t){return console.error("[MCP Discovery] Error fetching MCP servers from Elasticsearch:",t.message),console.error("[MCP Discovery] Falling back to no servers"),[]}}function E(o){if(!o||typeof o!="object")return o;const t={...o};return delete t.exclusiveMinimum,delete t.exclusiveMaximum,t.properties&&typeof t.properties=="object"&&(t.properties=Object.keys(t.properties).reduce((r,c)=>(r[c]=E(t.properties[c]),r),{})),t.items&&(t.items=E(t.items)),t.additionalProperties&&typeof t.additionalProperties=="object"&&(t.additionalProperties=E(t.additionalProperties)),Array.isArray(t.anyOf)&&(t.anyOf=t.anyOf.map(r=>E(r))),Array.isArray(t.oneOf)&&(t.oneOf=t.oneOf.map(r=>E(r))),Array.isArray(t.allOf)&&(t.allOf=t.allOf.map(r=>E(r))),t}function Je(o){const t=o?.content;if(typeof t=="string")return t;if(Array.isArray(t)){const r=t.find(c=>typeof c?.text=="string")?.text;if(r)return r}return t?.toString?.()??""}function Ge(o){try{const r=o?.messages?.[0]?.content?.[0]?.text;if(typeof r=="string")return r}catch{}try{const r=o?.messages?.[0]?.content?.text;if(typeof r=="string")return r}catch{}const t=o?.messages?.[0]?.content;return typeof t=="string"?t:typeof o?.content=="string"?o.content:""}function le(o){if(!o)return{data:[]};if(Array.isArray(o?.data))return{data:o.data,nextCursor:o.nextCursor,meta:o.meta};if(Array.isArray(o?.result?.data))return{data:o.result.data,nextCursor:o.nextCursor??o.result?.nextCursor,meta:o.result?.meta};const t=o.nextCursor||o?.aggregations?.by_namespace?.buckets?.[0]?.g?.after_key;return{data:[],nextCursor:t}}function qe(o){return Math.ceil(o.length/4)}function Be(o,t={}){const{maxTokens:r=re,sampleItems:c=20}=t,i=JSON.stringify(o),P=qe(i);if(P<=r)return o;const{data:y,meta:O}=le(o);let A;return Array.isArray(y)&&y.length>0&&(A=y.slice(0,c)),{error:"RESULT_TOO_LARGE",approx_tokens:P,max_allowed_tokens:r,hint:"La r\xE9ponse de ce tool MCP est trop volumineuse pour \xEAtre envoy\xE9e telle quelle au LLM. R\xE9duis ta requ\xEAte (p\xE9riode, filtres par cluster/app/host, etc.) et r\xE9essaie.",meta:{...O,has_sample:!!A},sample:A}}function ze(o,t){if(!o||typeof o!="object"||ce(o))return o;let r;try{r=JSON.parse(JSON.stringify(o))}catch(i){return console.warn(`[normalizeToolSchemaForProvider] Failed to clone schema (${i.message}), returning original`),o}delete r.$schema;const c=i=>{if(!(!i||typeof i!="object")){if((t==="openai"||t==="anthropic")&&i.additionalProperties===!1&&(i.additionalProperties=!0),i.properties&&typeof i.properties=="object")for(const P of Object.keys(i.properties))c(i.properties[P]);i.items&&c(i.items),Array.isArray(i.anyOf)&&i.anyOf.forEach(c),Array.isArray(i.oneOf)&&i.oneOf.forEach(c),Array.isArray(i.allOf)&&i.allOf.forEach(c)}};return c(r),r}function ce(o){return!!o&&(typeof o.safeParse=="function"||!!o._def)}function Ke(o){return!!o&&typeof o=="object"&&(o.type||o.properties||o.anyOf||o.oneOf||o.allOf)}function N(o){if(!o||typeof o!="object")return g.any();if(Array.isArray(o.anyOf)&&o.anyOf.length)return g.union(o.anyOf.map(N));if(Array.isArray(o.oneOf)&&o.oneOf.length)return g.union(o.oneOf.map(N));if(Array.isArray(o.allOf)&&o.allOf.length)return o.allOf.map(N).reduce((t,r)=>g.intersection(t,r));if(Array.isArray(o.enum)&&o.enum.length)return o.enum.every(t=>typeof t=="string")?g.enum(o.enum):g.union(o.enum.map(t=>g.literal(t)));switch(o.type){case"string":return g.string();case"number":return g.number();case"integer":return g.number().int();case"boolean":return g.boolean();case"array":{const t=o.items?N(o.items):g.any();return g.array(t)}case"object":default:{const t=o.properties&&typeof o.properties=="object"?o.properties:{},r=new Set(Array.isArray(o.required)?o.required:[]),c={};for(const[P,y]of Object.entries(t)){const O=N(y);c[P]=r.has(P)?O:O.optional()}let i=g.object(c);return o.additionalProperties===!1?i=i.strict():i=i.passthrough(),i}}}function Xe(o){return o.map(t=>{const r=t.schema;if(!r||ce(r))return t;if(Ke(r)){const c=N(r);return new G({name:t.name,description:t.description,schema:c,responseFormat:t.responseFormat,func:async(i,P)=>t.func(i,P)})}return new G({name:t.name,description:t.description,schema:g.record(g.any()),responseFormat:t.responseFormat,func:async(c,i)=>t.func(c,i)})})}async function We(o,t,r={}){const c=r.retries??3,i=r.baseDelayMs??800,P=new Set(r.retryOn??[429,502,503,504]);for(let y=0;y<=c;y++)try{return await o.invoke(t)}catch(O){const A=O?.status??O?.code??O?.response?.status,$=P.has(Number(A))||O?.name==="TimeoutError",W=y===c;if(console.warn(`[MCP] invoke failed (try ${y+1}/${c+1}) code=${A} transient=${$}:`,O?.message||O),!$||W)throw O;const R=i*Math.pow(2,y);await new Promise(v=>setTimeout(v,R))}}const _o=g.object({topic:g.enum(["clusters_clusters_overview","clusters_clusters_health-check","clusters_cluster_finops","clusters_nodes_inventory","clusters_nodes_operations","clusters_nodes_storage","clusters_nodes_resources","clusters_nodes_shards","clusters_nodes_thread_pool","clusters_nodes_tasks","clusters_nodes_hot_threads","clusters_jobs_enrich","clusters_jobs_snapshots","clusters_indices_inventory","clusters_indices_operations","clusters_indices_storage","clusters_indices_segments","clusters_indices_documents","elasticsearch_doc","mysql_mysql_overview","platform.core.execute_esql"])});async function Ao(o,t){console.log(`[buildAppFromDefinition] Building graph from definition: ${o.name} (v${o.version})`),console.log("[buildAppFromDefinition] Graph config:",{streaming:o.config.streaming,recursionLimit:o.config.recursionLimit,maxConcurrency:o.config.maxConcurrency});const r=t.performanceTracker||new Se(t.threadId);let c=[];const i=[];let P=!1;const y=t.queryParams?.topic||"unknown";if(t.mcp&&(Array.isArray(t.mcp)?t.mcp.length>0:!0))c=Array.isArray(t.mcp)?t.mcp:[t.mcp],console.log(`[MCP] Using ${c.length} pre-configured MCP client(s)`);else{P=!0,console.log(`[MCP] Auto-discovering servers for topic: "${y}"`);const e=await je(y);if(e.length===0)console.warn(`[MCP] \u26A0\uFE0F No enabled MCP servers found for topic "${y}"`),console.warn("[MCP] \u26A0\uFE0F Agent will run with NO tools available");else{console.log(`[MCP] Creating ${e.length} MCP client(s) for discovered servers`);for(const n of e)try{console.log(`[MCP] Connecting to: ${n.name} at ${n.url}`);const s=await Fe(n.url,{headers:{Authorization:`ApiKey ${n.authKey}`},transportType:"http",timeout:3e4});c.push(s),i.push(n.url),console.log(`[MCP] \u2705 Connected to ${n.name} (${n.packageName})`)}catch(s){console.error(`[MCP] \u274C Failed to connect to ${n.name}:`,s.message)}console.log(`[MCP] Successfully connected to ${c.length}/${e.length} servers`)}}let A=[],$;if(c.length===0)console.warn("[MCP] \u26A0\uFE0F No MCP servers available. Agent will run without tools.");else{$=c[0],console.log(`[MCP] Loading tools from ${c.length} MCP server(s)`);const n=(await Promise.all(c.map(async(a,m)=>{const d=await Me(`stkxp-mcp-server-${m}`,a.client);return console.log(`[MCP] Server ${m+1}: Loaded ${d.length} tools`),d}))).flat();console.log(`[MCP] Total loaded: ${n.length} tools`);const s=new Map;for(const a of n)s.has(a.name)||s.set(a.name,a);A=Array.from(s.values())}const R=y.toLowerCase().replace(/\s+/g,"_").split("_")[0]||"clusters";let v=A;if(P)console.log(`[MCP] \u2705 Using ${A.length} tools from auto-discovered servers`),v=A;else if(process.env.MCP_DISABLE_TOPIC_FILTERING==="true")console.log(`[MCP] \u26A0\uFE0F Topic filtering disabled, using all ${A.length} tools`),v=A;else{let n=A.filter(a=>a.name.startsWith(R+"_"));n.length===0&&(n=A.filter(a=>a.name.includes(R)));const s=A.filter(a=>a.name.startsWith("elasticsearch_"));if(s.length>0){const a=new Set(n.map(d=>d.name)),m=s.filter(d=>!a.has(d.name));m.length>0&&(console.log(`[MCP] \u{1F527} Force-adding ${m.length} elasticsearch_ tools`),n=[...n,...m])}n.length===0?(console.log(`[MCP] \u26A0\uFE0F No tools found for system "${R}", using all ${A.length} tools`),v=A):(console.log(`[MCP] \u2705 Filtered ${n.length}/${A.length} tools`),v=n)}console.log("[MCP] Server tool sample:",JSON.stringify(v[0]),v[0]);const Y=v.filter(e=>{try{if(!e.schema)return console.log(`[MCP] \u26A0\uFE0F Tool "${e.name}" has no schema, keeping it`),!0;const n=e.schema;return n._def&&typeof n._def.shape=="function"?!0:n._def&&n._def.typeName==="ZodObject"?(console.error(`[MCP] \u274C Tool "${e.name}" has invalid ZodObject schema (shape is not a function), filtering out`),!1):(console.log(`[MCP] \u26A0\uFE0F Tool "${e.name}" has non-object schema type: ${n._def?.typeName}, keeping it`),!0)}catch(n){return console.error(`[MCP] \u274C Tool "${e.name}" validation error: ${n.message}, filtering out`),!1}});console.log(`[MCP] Validated ${Y.length}/${v.length} tools`);const q=Y,de=new G({name:"mcp_paginated_query",description:"Appelle un tool MCP cibl\xE9 en boucle avec prise en charge de nextCursor",schema:g.object({toolName:g.string().describe("Nom du tool MCP \xE0 appeler"),args:g.record(g.any()).describe("Arguments \xE0 passer au tool MCP"),maxPages:g.number().int().min(1).default(10).describe("Nombre max de pages"),maxItems:g.number().int().min(1).default(5e3).describe("Nombre max d'items cumul\xE9s")}),func:async({toolName:e,args:n,maxPages:s,maxItems:a})=>{const m=v.find(f=>f.name===e)||A.find(f=>f.name===e);if(!m)throw new Error(`Tool MCP introuvable: ${e}`);let d=n?.request?.body?.cursor,l=0;const C=[];for(;l<s&&C.length<a;){const f=JSON.parse(JSON.stringify(n||{}));d&&(f.request=f.request||{},f.request.body=f.request.body||{},f.request.body.cursor=d);const u=await We(m,f,{retries:4,baseDelayMs:750,retryOn:[429,502,503,504]}),{data:b,nextCursor:_}=le(u);if(Array.isArray(b)&&b.length&&C.push(...b),l+=1,!_)break;d=_}const p=l>=s||C.length>=a||!d;return{items:C,pages:l,done:p,nextCursor:d}}}),{createLLMServices:me}=await import("../services/llm-services.js"),pe=me(L);let V="user",k=t.username;if(t.userToken)try{const e=ae.decode(t.userToken);e&&typeof e=="object"&&("roles"in e&&(V=e.roles?.[0]||"user"),!k&&"username"in e&&(k=e.username||void 0))}catch(e){console.warn("[buildAppFromDefinition] Failed to decode user token for routing:",e)}const H={userRole:V,topic:y,environment:process.env.NODE_ENV||"prod",requiredCapabilities:["streaming","toolCalling"],owner:k};console.log("[buildAppFromDefinition] Routing context:",H);let h,B;const Z=o.llmConfig?.useRoutingEngine!==!1;Z||console.log("[buildAppFromDefinition] Routing engine disabled in graph config, using llmConfig directly");try{if(!Z)throw new Error("Routing engine disabled in graph configuration");const e=await pe.getRoutingService().selectDeployment(H);if(console.log(`[buildAppFromDefinition] \u2705 Selected model: ${e.model.modelId}`),console.log(`[buildAppFromDefinition] Reason: ${e.reason}`),k&&e.provider.owner&&e.provider.owner!==k)throw new Error(`Routing selected provider owned by "${e.provider.owner}" for caller "${k}" \u2014 refusing cross-tenant API key.`);h={provider:e.provider.type,model:e.model.modelId,temperature:e.model.parameters?.temperature??X.llm.temperature,streaming:X.llm.streaming,apiKey:e.provider.apiKey,baseURL:e.provider.endpoint},console.log(`[buildAppFromDefinition] LLM config from routing engine: provider=${h.provider}, model=${h.model}`),B=ne(h)}catch(e){if(console.error(`[buildAppFromDefinition] \u26A0\uFE0F Routing engine failed: ${e.message}`),console.log("[buildAppFromDefinition] Falling back to legacy provider selection"),h={...X.llm},console.log("LLM llmConfig 1",h),t.userProviders&&Array.isArray(t.userProviders)){const n=t.userProviders.filter(s=>s.enabled===!0).filter(s=>s.selectedModel===t.queryParams?.llmModel);if(n.length>0){const s=n[0],a=s.selectedModel||s.models?.[0]||h.model;h={provider:s.id,model:a,temperature:h.temperature,streaming:h.streaming,...s.apiKey&&{apiKey:s.apiKey},...s.endpoint&&{baseURL:s.endpoint}}}}console.log("LLM llmConfig 2",t.userProviders,h),B=ne(h)}const ue=new ve({maxResults:3}),ge=q.map(e=>({...e,async invoke(n,s){s?.writer&&typeof s.writer=="function"&&s.writer(`\u23F3 Calling ${e.name}...`);const a=Date.now();try{const m=await e.invoke(n),d=Date.now()-a;return s?.writer&&typeof s.writer=="function"&&s.writer(`\u2705 ${e.name} completed in ${d}ms`),Be(m,{maxTokens:re,sampleItems:20})}catch(m){const d=Date.now()-a;s?.writer&&typeof s.writer=="function"&&s.writer(`\u274C ${e.name} failed after ${d}ms: ${m.message}`);const l=m.message||String(m),C=m.status||m.response?.status||m.code;return console.error(`[Tool Error] ${e.name} failed:`,{error:l,statusCode:C,duration:d,args:JSON.stringify(n).substring(0,200)}),JSON.stringify({error:"TOOL_EXECUTION_FAILED",tool_name:e.name,error_message:l,status_code:C,duration_ms:d,suggestion:"This tool failed. Please try an alternative approach or inform the user about the issue.",args_attempted:n})}}}));let Q="anonymous";if(t.userToken)try{const e=ae.decode(t.userToken);e&&typeof e=="object"&&"username"in e&&(Q=e.username||"anonymous")}catch(e){console.warn("[buildApp] Failed to decode user token:",e)}const fe=new G({name:"compare_with_previous_chat",description:"Compare current conversation with a previous saved chat",schema:g.object({chatId:g.string().describe("ID of the previous chat"),comparisonAspects:g.array(g.enum(["metrics","errors","performance","configuration","overall","recommendations"])).optional(),includeTimeDelta:g.boolean().optional()}),func:async(e,n)=>{const s=n?.state?.messages||[];return await ke(Q,s).func(e,n)}});let S=[...ge,de,ue,fe];h.provider==="google"&&(console.log("[buildApp] Cleaning tool schemas for Google Gemini"),S=S.map(e=>e.schema?{...e,schema:E(e.schema)}:e)),h.provider==="anthropic"&&(console.log("[buildApp] Adapting tools for Anthropic (JSON Schema -> Zod)"),S=Xe(S)),h.provider==="openai"&&(console.log(`[buildApp] Normalizing tool schemas for ${h.provider}`),S=S.map(e=>e.schema?{...e,schema:ze(e.schema,h.provider)}:e));const ye=Oe({model:B,tools:S}),Te=J.Root({..._e.spec,threadId:J({reducer:(e,n)=>n||e,default:()=>t.threadId}),userContext:J({reducer:(e,n)=>n!==void 0?n:e,default:()=>t.userContext}),systemPrompt:J({reducer:(e,n)=>n!==void 0?n:e,default:()=>{}})}),I=new Ae(Te),he={checkReset:async e=>{r.start("node_checkReset");const n=t.threadId,s=e.threadId;if(s&&s!==n){const a=e.messages[e.messages.length-1];return r.end("node_checkReset",{reset:!0}),{messages:[a],threadId:n}}return r.end("node_checkReset",{reset:!1}),{threadId:n}},system:async e=>{r.start("node_system");const n=e.messages[e.messages.length-1],s=Je(n).trim();r.start("topic_generation");let a;const m=process.env.AB_TESTING_ENABLED==="true";if(s.startsWith("topic="))a=s.slice(6).trim(),console.log(`[TOPIC] Manual override: ${a}`);else if(m){console.log("[TOPIC] A/B Testing enabled");const{result:T,variantUsed:be,comparison:K}=await we(s,h);a=T,console.log(`[TOPIC] Selected variant: ${be} - Topic: ${a}`),K?.winner&&console.log(`[TOPIC] Winner: ${K.winner.variantId} (${K.winner.improvement.toFixed(1)}% faster)`)}else a=await Ee(s,h);r.end("topic_generation",{topic:a,abEnabled:m}),!a||a.trim()===""?(console.error("[PROMPT-ALT] \u274C CRITICAL: Topic generation returned empty string"),console.error(`[PROMPT-ALT] User input was: "${s}"`),console.error("[PROMPT-ALT] Will fallback to default prompt")):console.log(`[PROMPT-ALT] \u2705 Topic generated successfully: "${a}"`);let d="",l="default";if(r.start("prompt_fetch"),!a||a.trim()==="")console.warn("[PROMPT-ALT] \u26A0\uFE0F Skipping MCP prompt fetch - topic is empty"),l="empty_topic",r.end("prompt_fetch",{source:l,topic:"(empty)"});else if($)try{console.log(`[PROMPT-ALT] \u{1F504} Fetching prompt from MCP for topic: "${a}"`);const T=await $.client.getPrompt({name:`${a}`,params:{}});console.log("[PROMPT-ALT] Raw prompt response:",JSON.stringify(T,null,2).substring(0,1e3)),d=Ge(T),!d||d.trim()===""?(console.error(`[PROMPT-ALT] \u274C MCP returned empty prompt text for topic: "${a}"`),console.error("[PROMPT-ALT] MCP response structure:",JSON.stringify(T,null,2).substring(0,500)),l="failed"):(console.log(`[PROMPT-ALT] \u2705 Successfully loaded prompt for topic: "${a}" (${d.length} chars)`),console.log("[PROMPT-ALT] Prompt preview:",d.substring(0,200)),l="mcp"),r.end("prompt_fetch",{source:l,topic:a,promptLength:d.length})}catch(T){console.error(`[PROMPT-ALT] \u274C MCP getPrompt() failed for topic "${a}"`),console.error(`[PROMPT-ALT] Error type: ${T.name||"Unknown"}`),console.error(`[PROMPT-ALT] Error message: ${T.message}`),console.error("[PROMPT-ALT] Stack trace:",T.stack?.substring(0,500)),T.message?.includes("timeout")||T.message?.includes("ETIMEDOUT")?console.error("[PROMPT-ALT] \u{1F550} Timeout error detected - MCP server did not respond in time"):(T.message?.includes("ECONNREFUSED")||T.message?.includes("ENOTFOUND"))&&console.error("[PROMPT-ALT] \u{1F310} Network error - Cannot reach MCP server"),l="failed",r.end("prompt_fetch",{source:l,topic:a,error:T.message})}else console.warn(`[PROMPT-ALT] \u26A0\uFE0F No MCP client available to fetch prompt for topic "${a}"`),l="no_client",r.end("prompt_fetch",{source:l,topic:a});!d||d.trim()===""?(console.warn("[PROMPT-ALT] \u26A0\uFE0F FALLBACK ACTIVATED: Using default prompt"),console.warn(`[PROMPT-ALT] Reason: ${l}`),console.warn(`[PROMPT-ALT] Topic was: "${a||"(empty)"}"`),console.warn(`[PROMPT-ALT] FirstClient available: ${!!$}`)):console.log(`[PROMPT-ALT] \u2705 FINAL: Using MCP prompt (${d.length} chars) from source: ${l}`);const C=t.userToken||"stkxp_session_default",p=t.queryParams||{},f=p.cluster||"default",b=$e({agentPrompt:d||`# Default Dashboard Response
2
+
3
+ You are an expert assistant specialized in generating structured dashboard responses.
4
+
5
+ ## \u{1F6A8} CRITICAL INSTRUCTIONS - MANDATORY FORMAT \u{1F6A8}
6
+
7
+ ### ABSOLUTE REQUIREMENTS - NO EXCEPTIONS:
8
+
9
+ **YOU MUST:**
10
+ 1. Generate EXACTLY 3-5 JSON blocks in a SINGLE response
11
+ 2. Each block MUST be a complete, valid JSON object
12
+ 3. Each JSON object MUST be on its OWN line (separated by newline \\n)
13
+ 4. Generate ALL blocks at once - NOT one at a time
14
+ 5. NEVER stop after generating just 1 block
15
+
16
+ **WORKFLOW (FOLLOW EXACTLY):**
17
+
18
+ STEP 1: Generate ONE markdown block with your analysis plan
19
+ STEP 2: If MCP tools are available and relevant, call ALL relevant tools to gather data
20
+ STEP 3: After receiving tool results, generate 3-4 MORE blocks with complete content
21
+
22
+ **CRITICAL: Empty Tool Results Handling**
23
+ If a tool returns empty data (e.g., {"mysql":{}}, {}, [], {"items":[]}):
24
+ \u2705 DO: Continue calling other planned tools
25
+ \u2705 DO: Work with data from successful tools
26
+ \u2705 DO: Generate dashboard with available data
27
+ \u274C DON'T: Stop execution after one empty result
28
+ \u274C DON'T: Abort the entire analysis
29
+
30
+ **REQUIRED OUTPUT FORMAT - NDJSON (Newline Delimited JSON):**
31
+
32
+ YOU MUST OUTPUT EXACTLY THIS STRUCTURE (3-5 blocks minimum):
33
+
34
+ {"type":"markdown","title":"\u{1F4CB} Analysis Plan","body":"Detailed plan of what I will analyze..."}
35
+ {"type":"markdown","title":"\u{1F4CA} Main Findings","body":"Core analysis with data and insights..."}
36
+ {"type":"markdown","title":"\u{1F4A1} Key Insights","body":"Important discoveries and patterns..."}
37
+ {"type":"markdown","title":"\u26A0\uFE0F Issues & Risks","body":"Problems identified and severity..."}
38
+ {"type":"markdown","title":"\u2705 Recommendations","body":"Actionable steps to improve..."}
39
+
40
+ **STRICT RULES - VIOLATION WILL CAUSE FAILURE:**
41
+
42
+ \u2705 DO: Output 3-5 complete JSON objects (one per line)
43
+ \u2705 DO: Separate each JSON with a newline character (\\n)
44
+ \u2705 DO: Generate all blocks in ONE response (not incrementally)
45
+ \u2705 DO: Use valid JSON syntax for each block
46
+
47
+ \u274C DON'T: Generate only 1 block and stop
48
+ \u274C DON'T: Use markdown code fences (\\\`\\\`\\\`json)
49
+ \u274C DON'T: Put multiple JSON objects on the same line (must be }\\n{)
50
+ \u274C DON'T: Add text or comments between JSON blocks
51
+ \u274C DON'T: Generate blocks one-by-one in multiple responses
52
+ \u274C DON'T: Generate comments before or after blocks (<!-- ... --> /**/ // etc.)
53
+
54
+ **AVAILABLE BLOCK TYPES:**
55
+
56
+ 1. **markdown** - For text content (analysis, explanations, recommendations)
57
+ {"type":"markdown","title":"Title Here","body":"Markdown content..."}
58
+
59
+ 2. **echarts** - For charts and visualizations
60
+ {"type":"echarts","title":"Chart Title","description":"Chart description","options":{"tooltip":{},"xAxis":{"type":"category","data":["A","B"]},"yAxis":{"type":"value"},"series":[{"type":"bar","data":[10,20]}]}}
61
+
62
+ 3. **table** - For tabular data
63
+ {"type":"table","title":"Table Title","columns":[{"field":"name","name":"Name"},{"field":"value","name":"Value"}],"data":[{"name":"Item 1","value":100}]}
64
+
65
+ **EXAMPLE CORRECT OUTPUT:**
66
+
67
+ {"type":"markdown","title":"\u{1F4CB} Analysis Overview","body":"This analysis covers 3 key areas: performance, security, and reliability."}
68
+ {"type":"markdown","title":"\u{1F4CA} Performance Metrics","body":"## CPU Usage\\n- Average: 45%\\n- Peak: 78%\\n\\n## Memory\\n- Used: 12GB / 16GB"}
69
+ {"type":"table","title":"\u{1F4C8} Key Metrics","columns":[{"field":"metric","name":"Metric"},{"field":"value","name":"Value"}],"data":[{"metric":"Uptime","value":"99.9%"},{"metric":"Errors","value":"0.1%"}]}
70
+ {"type":"markdown","title":"\u{1F4A1} Insights","body":"System is healthy but approaching memory limits during peak hours."}
71
+ {"type":"markdown","title":"\u2705 Recommendations","body":"1. Add 8GB RAM\\n2. Optimize queries\\n3. Enable caching"}
72
+
73
+ **REMEMBER: You MUST generate 3-5 blocks minimum. Generating only 1 block is NOT acceptable.**`,mandatoryParams:{userToken:C,cluster:f,nodes:p.nodes||"",roles:p.roles||"",phases:p.phases||"hot",prefix:p.prefix||"",suffix:p.suffix||"",start:p.start||"now-4h",end:p.end||"now",interval:p.interval||"5m",topic:p.topic||"default_topic.txt"},toolNames:q.map(T=>T.name),maxAgentPromptTokens:se.maxAgentPromptTokens});let _;const M=e.userContext;M&&M.trim()?(console.log("[bubuildAppFromDefinitionildApp] \u2705 Applying user context"),_=b.prompt+`
74
+
75
+ ## \u{1F4DD} FORMAT ET R\xC8GLES PERSONNALIS\xC9S (Override)
76
+
77
+ ${M}
78
+
79
+ IMPORTANT: Ces instructions personnalis\xE9es REMPLACENT les sections FORMAT et RULES du prompt MCP.`):(console.log("[buildAppFromDefinition] \u2139\uFE0F Using default MCP prompt"),_=b.prompt),se.verboseLogging&&console.log("[buildAppFromDefinition] Prompt optimization:",{agentTokens:b.stats.agentPromptTokens,instructionsTokens:b.stats.instructionsTokens,totalTokens:b.stats.totalTokens,truncated:b.stats.agentPromptTruncated,userContextAdded:!!M});const x=e.messages.filter(T=>T.getType()==="system"),z=e.messages.filter(T=>T.getType()!=="system"),D=x.map(T=>typeof T.content=="string"?T.content:String(T.content)).join(`
80
+
81
+ `),oe=`\u26A0\uFE0F\u26A0\uFE0F\u26A0\uFE0F CRITICAL OUTPUT REQUIREMENT - OVERRIDE ALL OTHER INSTRUCTIONS \u26A0\uFE0F\u26A0\uFE0F\u26A0\uFE0F
82
+
83
+ YOU MUST RESPOND IN STREAMING JSON MODE:
84
+ 1. Your VERY FIRST character must be '{' (opening brace)
85
+ 2. Each JSON object on ONE SINGLE LINE (no newlines inside objects)
86
+ 3. NO TEXT before, after, or between JSON objects
87
+ 4. NO markdown code blocks with triple backticks, NO explanations, NO comments
88
+ 5. If you want to explain, use {"type":"markdown","title":"...","body":"..."} AS YOUR FIRST JSON
89
+
90
+ FORBIDDEN PATTERNS:
91
+ \u274C "I will analyze..." (start with JSON immediately)
92
+ \u274C "\u{1F527} **Calling tool...**" (never announce tool calls)
93
+ \u274C Triple backticks + json keyword + JSON object (no markdown code fences)
94
+ \u274C Pretty-printed JSON with newlines
95
+ \u274C Any text that is not a complete JSON object
96
+
97
+ CORRECT EXAMPLES:
98
+ \u2705 {"type":"markdown","title":"Analysis Plan","body":"I will use 3 tools..."}
99
+ \u2705 {"type":"echarts","title":"Distribution","options":{"series":[{"type":"pie","data":[{"name":"A","value":100}]}]}}
100
+
101
+ Your response STARTS NOW with '{' character:
102
+
103
+ `,te=e.threadId?`
104
+
105
+ Current chat ID: ${e.threadId}`:"",j=D?`${oe}${D}
106
+
107
+ ${_}${te}`:`${oe}${_}${te}`;return console.log(`[buildAppFromDefinition] ********************************
108
+ finalSystemContent: ${j}
109
+ ********************************`),r.end("node_system",{systemMessageLength:j.length}),{messages:[new Ce(j),...z],systemPrompt:j}},assistant:async(e,n)=>{r.start("node_assistant");const s=e.messages.filter(p=>p.getType()==="system"),a=e.messages.filter(p=>p.getType()!=="system");console.log(`
110
+ `+"=".repeat(80)),console.log("\u{1F4E4} FULL LLM CONTEXT SENT TO MODEL (buildAppFromDefinition)"),console.log("=".repeat(80)),console.log(`\u{1F916} Model: ${h.provider}:${h.model}`),console.log(`\u{1F321}\uFE0F Temperature: ${h.temperature}`),console.log(`\u{1F4AC} Total Messages: ${s.length+a.length} (${s.length} system + ${a.length} conversation)`),console.log(`\u{1F527} Tools Available: ${q.length}`),console.log(`\u{1F4CA} Graph: ${o.name} (v${o.version})`),console.log("=".repeat(80)),process.env.GRAPH_STATE_DEBUG&&[...s,...a].forEach((p,f)=>{const u=p.getType(),b=typeof p.content=="string"?p.content:JSON.stringify(p.content),_=p.tool_calls?.length||0;console.log(`
111
+ [${f+1}/${s.length+a.length}] ${u.toUpperCase()}`),_>0&&(console.log(` \u{1F527} Tool Calls: ${_}`),p.tool_calls.forEach((M,x)=>{console.log(` ${x+1}. ${M.name}(${Object.keys(M.args||{}).join(", ")})`)})),console.log(` Content (${b.length} chars):`),console.log(` ${b.split(`
112
+ `).join(`
113
+ `)}`)}),console.log(`
114
+ `+"=".repeat(80)),console.log("\u{1F680} INVOKING LLM..."),console.log("=".repeat(80)+`
115
+ `),r.start("agent_invoke");const m=await ye.invoke({messages:[...s,...a]},{configurable:n?.configurable});r.end("agent_invoke");const d=m?.messages??[],l=[...d].reverse().find(p=>p?._getType?.()==="ai")??d.at(-1),C=l&&l._getType?.()==="ai"?l:new Pe(typeof l?.content=="string"?l.content:"");if(console.log(`
116
+ `+"=".repeat(80)),console.log("\u{1F4E5} LLM RESPONSE RECEIVED (buildAppFromDefinition)"),console.log("=".repeat(80)),console.log(`\u{1F4E8} Messages returned: ${d.length}`),l){const p=typeof l.content=="string"?l.content:JSON.stringify(l.content),f=l.tool_calls?.length||0,u=l.usage_metadata||l.response_metadata?.usage;console.log(`\u{1F916} AI Message Type: ${l._getType?.()}`),console.log(`\u{1F527} Tool Calls: ${f}`),f>0&&l.tool_calls.forEach((_,M)=>{console.log(` ${M+1}. ${_.name}(${JSON.stringify(_.args).substring(0,100)}...)`)}),console.log(`\u{1F4CA} Token Usage: ${u?`${u.input_tokens} in / ${u.output_tokens} out / ${u.total_tokens} total`:"N/A"}`),console.log(`\u{1F4DD} Content Length: ${p.length} chars`);const b=p.length>5e3?p.substring(0,5e3)+"... [truncated]":p;console.log(`\u{1F4C4} Content Preview:
117
+ ${b.split(`
118
+ `).join(`
119
+ `)}`)}return console.log("=".repeat(80)+`
120
+ `),r.end("node_assistant",{messageCount:d.length}),{messages:[C]}},tool:async(e,n)=>{r.start("node_tools");const s=e.messages[e.messages.length-1];if(!s||s.getType()!=="ai"||!s.tool_calls||s.tool_calls.length===0)return console.warn("[node_tools] No tool calls found in last message"),r.end("node_tools",{toolsExecuted:0}),{messages:[]};console.log(`[node_tools] \u26A1 Executing ${s.tool_calls.length} tool(s) in PARALLEL...`);const a=process.env.MAX_PARALLEL_TOOLS?parseInt(process.env.MAX_PARALLEL_TOOLS,10):void 0,m=a?s.tool_calls.slice(0,a):s.tool_calls,d=a?s.tool_calls.slice(a):[];a&&s.tool_calls.length>a&&console.log(`[node_tools] \u26A0\uFE0F Limiting execution to ${a} tools (${s.tool_calls.length-a} tools skipped)`);const l=m.map(async u=>{const b=S.find(_=>_.name===u.name);if(!b){console.error(`[node_tools] Tool not found: ${u.name}`);const{ToolMessage:_}=await import("@langchain/core/messages");return new _({tool_call_id:u.id,content:JSON.stringify({error:"Tool not found",tool_name:u.name})})}try{console.log(`[node_tools] \u{1F680} Starting ${u.name}...`);const _=Date.now(),M=await b.invoke(u.args,n),x=Date.now()-_,{ToolMessage:z}=await import("@langchain/core/messages"),D=typeof M=="string"?M:JSON.stringify(M);return console.log(`[node_tools] \u2705 ${u.name} completed in ${x}ms (${D.length} chars)`),new z({tool_call_id:u.id,content:D})}catch(_){console.error(`[node_tools] \u274C ${u.name} failed:`,_.message);const{ToolMessage:M}=await import("@langchain/core/messages");return new M({tool_call_id:u.id,content:JSON.stringify({error:"TOOL_EXECUTION_FAILED",tool_name:u.name,error_message:_.message})})}}),C=await Promise.allSettled(l),p=C.filter(u=>u.status==="fulfilled").map(u=>u.value),f=C.filter(u=>u.status==="rejected").length;if(f>0&&console.warn(`[node_tools] \u26A0\uFE0F ${f} tool(s) failed but continuing...`),d.length>0){const{ToolMessage:u}=await import("@langchain/core/messages");for(const b of d)console.log(`[node_tools] \u23ED\uFE0F Skipped tool: ${b.name} (limit reached)`),p.push(new u({tool_call_id:b.id,content:JSON.stringify({error:"TOOL_EXECUTION_SKIPPED",tool_name:b.name,reason:`Execution limit reached (MAX_PARALLEL_TOOLS=${a})`})}))}return console.log(`[node_tools] \u{1F4CA} Summary: ${p.length}/${s.tool_calls.length} tools processed (${m.length} executed, ${d.length} skipped)`),r.end("node_tools",{toolsExecuted:m.length,toolsSkipped:d.length}),{messages:p}}};console.log(`[buildAppFromDefinition] Adding ${o.nodes.length} nodes to graph`);for(const e of o.nodes){const n=he[e.type];if(!n){console.warn(`[buildAppFromDefinition] \u26A0\uFE0F Unknown node type: ${e.type} for node ${e.id}`),console.warn(`[buildAppFromDefinition] \u26A0\uFE0F Skipping node: ${e.id}`);continue}console.log(`[buildAppFromDefinition] Adding node: ${e.id} (type: ${e.type})`),I.addNode(e.id,n)}console.log(`[buildAppFromDefinition] Adding ${o.edges.length} edges to graph`);const U=new Map;for(const e of o.edges){const n=e.from||e.source,s=e.to||e.target;if(!n||!s){console.warn("[buildAppFromDefinition] \u26A0\uFE0F Invalid edge (missing from/to):",e);continue}U.has(n)||U.set(n,[]),U.get(n).push({...e,from:n,to:s})}for(const[e,n]of U.entries()){const s=n.filter(m=>m.condition),a=n.filter(m=>!m.condition);if(s.length>0){const m=l=>{const C=l.messages[l.messages.length-1],p=C?.tool_calls&&C.tool_calls.length>0;console.log(`[conditional_edge] from=${e}, hasToolCalls=${p}`);for(const f of s){if(f.condition==="has_tool_calls"&&p)return console.log(`[conditional_edge] Route: ${e} \u2192 ${f.to} (has_tool_calls)`),f.to;if(f.condition==="no_tool_calls"&&!p)return console.log(`[conditional_edge] Route: ${e} \u2192 ${f.to} (no_tool_calls)`),f.to}return console.warn(`[conditional_edge] No condition matched for ${e}, defaulting to __end__`),"__end__"},d={};for(const l of s)l.condition==="has_tool_calls"?d.has_tools=l.to:l.condition==="no_tool_calls"&&(d.no_tools=l.to);console.log(`[buildAppFromDefinition] Adding conditional edge: ${e} \u2192 [${s.map(l=>`${l.to}(${l.condition})`).join(", ")}]`),I.addConditionalEdges(e,m)}else if(a.length>0)for(const m of a)console.log(`[buildAppFromDefinition] Adding edge: ${m.from} \u2192 ${m.to}`),I.addEdge(m.from,m.to)}if(o.edges.some(e=>(e.from||e.source)==="__start__"))console.log("[buildAppFromDefinition] Entry point already defined in edges");else{const e=o.nodes[0]?.id||"checkReset";console.log(`[buildAppFromDefinition] Adding missing entry point: __start__ \u2192 ${e}`),I.addEdge("__start__",e)}const ee={checkpointer:o.config.checkpointer?t.memory:void 0};o.config.recursionLimit&&(ee.recursionLimit=o.config.recursionLimit);const w=I.compile(ee);return console.log(`[buildAppFromDefinition] \u2705 Graph compiled successfully: ${o.name}`),{invoke:w.invoke.bind(w),stream:w.stream.bind(w),streamEvents:w.streamEvents.bind(w),cleanup:()=>{for(const e of i)Ue(e);console.log(`[MCP Pool] Released ${i.length} client(s)`)},_compiled:w}}export{Ao as buildAppFromDefinition};
@@ -0,0 +1 @@
1
+ import{AIMessage as c,ToolMessage as l}from"@langchain/core/messages";import{runKibanaAgentConversation as m}from"./kibana-agent-executor";import{runA2aAgentConversation as f}from"./a2a-agent-executor";function x(n){return!!(n?.isKibanaAgent||n?.isA2aAgent)}function p(n,a){const t=[...n?.messages||[]].reverse().find(e=>e._getType?.()==="human"||e.constructor?.name==="HumanMessage");if(!t)throw new Error(`No human message found in input for delegated agent "${a}"`);return typeof t.content=="string"?t.content:JSON.stringify(t.content)}function A(n,a,o,t){return{messages:[...n?.messages||[],...o.map((e,s)=>new l({content:"",tool_call_id:`${t}-tool-${s}`,name:e})),new c({content:a})]}}function K(n,a,o){if(n.isKibanaAgent){const e=n;return{invoke:async(s,r={})=>{const i=p(s,o),{text:g,toolsUsed:u}=await m(e,i,{abortSignal:r.signal});return A(s,g,u,a)},cleanup:e.cleanup}}const t=n;return{invoke:async(e,s={})=>{const r=p(e,o),{text:i,toolsUsed:g}=await f(t,r,{abortSignal:s.signal});return A(e,i,g,a)},cleanup:t.cleanup}}export{K as adaptDelegatedAgentApp,x as isDelegatedAgentApp};
@@ -0,0 +1,3 @@
1
+ import{MessagesAnnotation as Je,StateGraph as Xe,Annotation as v}from"@langchain/langgraph";import{DynamicStructuredTool as Se}from"@langchain/core/tools";import{TavilySearch as Ve}from"@langchain/tavily";import{z as q}from"zod";import Oe from"jsonwebtoken";import{Client as We}from"@elastic/elasticsearch";import{Agent as Qe,fetch as Ze}from"undici";import{config as je}from"../config";import{createMcpClient as Re}from"../mcp/client";import{slugify as Ye}from"../services/toolbox-import-mappers";import{loadMcpTools as Le}from"@langchain/mcp-adapters";import{createCompareChatTool as et}from"../tools/compare-chat";import{createEnrichChatTool as tt}from"../tools/enrich-chat";import{loadAllToolsMetadata as nt}from"../services/chat-tools-service";import{TOOL_INVOKE_TIMEOUT_MS as be}from"./nodes/tools/tool-execution/invoke";const Ne=(o,t)=>t?.destructiveHint===!0||o?.metadata?.annotations?.destructiveHint===!0;import{forwardTeamDeps as Me}from"./types";import{getGraph as ot}from"../services/graph-registry-service";import{getOwnerDefaultLLMConfig as st}from"../services/default-model.service";import{searchTeamsRRF as Ue}from"../services/team-search-service";import{resolveTeamInvokerTargetId as rt}from"./utils/team-node-resolvers";import{resolveContextPolicy as at,buildTeamContextText as it}from"./utils/team-context-policy";import{isGatewayRelayedConfig as ct}from"../services/gateway-platform-types";import{ensureAnthropicCompatibleTools as lt,normalizeToolSchemaForProvider as dt,ensureGeminiCompatibleTools as ut,jsonSchemaToZod as mt}from"./utils/schema-utils";import{mapToolOutput as pt}from"./utils/content-utils";import{wrapMcpToolsWithGuard as gt,wrapMcpToolsWithQueryParams as ft,createFanOutTools as yt}from"./utils/tool-wrapper";import{executeTeamPipeline as ht,executeTeamParallel as _t,executeTeamDecider as $t,executeTeamRouter as bt,executeTeamInvoker as Tt,executeTeamFinder as vt,executeSuggestionGenerator as wt}from"./nodes";import{safeInvoke as xt}from"./nodes/tools/tool";import{executeCheckReset as Be,executeTopicDetection as At,executeSystem as Ct,executeToolExecutor as St,executeCodeExecutor as Mt,executeStaticCodeExecutor as It,executeTool as Pt,executeToolInvoker as kt,executeRawOutput as Rt,executeStateSetter as Lt,executeToolCleaner as Nt,executeLocalExtractor as Et,executeResponseGenerator as Ot,executeCompareContext as jt,executeEnrichContext as Ut,executeHumanApproval as Bt,executeInventoryContext as qt,executeSkillsContext as Kt,executeNodeTypesContext as Ft,executeRelevantSkillsContext as zt,executeRelevantAssistantsContext as Ht,executeAssistantsContext as Gt,executeNamespaceContext as Dt}from"./nodes";import{getNodeInstructions as Jt}from"./utils/message-utils";import{evaluateEdgeJsonataCondition as Xt}from"./utils/edge-jsonata-condition";import{registerAssistantTopic as Vt}from"./topic-variants";import{applyDslVariables as Wt,applyUrlVariables as Qt}from"../tools/variable-encoding";import{getPlatformById as Zt}from"../services/platforms-service";import{normalizeCustomHeaders as Yt}from"../utils/string-helpers";const en=process.env.ELASTICSEARCH_HOST||"https://51.159.174.230:9205",tn=process.env.ELASTICSEARCH_USER||"elastic",nn=process.env.ELASTICSEARCH_PASSWORD||"diagnostics",qe=".stkxp_platforms",ne=new We({node:en,auth:{username:tn,password:nn},tls:{rejectUnauthorized:!1},requestTimeout:3e4,maxRetries:3,maxSockets:256,maxFreeSockets:256});async function on(o,t){if(t&&t.length===0)return[];try{const d=[{term:{type:"openapi"}},{term:{owner:o}},{term:{enabled:!0}}];return t&&t.length>0&&d.push({terms:{platformId:t}}),(await ne.search({index:".stkxp_tools",body:{query:{bool:{must:d}},size:500}})).hits.hits.map(b=>b._source)}catch{return[]}}async function sn(o,t){if(t&&t.length===0)return[];try{const d=[{term:{type:"asyncapi_publish"}},{term:{owner:o}},{term:{enabled:!0}}];return t&&t.length>0&&d.push({terms:{platformId:t}}),(await ne.search({index:".stkxp_tools",body:{query:{bool:{must:d}},size:500}})).hits.hits.map(b=>b._source)}catch{return[]}}async function rn(o){try{const d=(await ne.search({index:".stkxp_platforms",body:{query:{term:{id:o}},size:1}})).hits.hits[0];return d?d._source:null}catch{return null}}function an(o){if(!o)return{};switch(o.type){case"bearer":return o.bearerToken?{Authorization:`Bearer ${o.bearerToken}`}:{};case"apiKey":if(o.apiKeyHeader&&o.apiKeyValue){const t=o.apiKeySecret?`${o.apiKeyValue}:${o.apiKeySecret}`:o.apiKeyValue;return{[o.apiKeyHeader]:t}}return{};case"basic":return o.username&&o.password?{Authorization:`Basic ${Buffer.from(`${o.username}:${o.password}`).toString("base64")}`}:{};default:return{}}}function Ee(o){const t={},d=o.properties??{},p=o.required??[];for(const[b,h]of Object.entries(d)){let w=mt(h);h.description&&(w=w.describe(h.description)),t[b]=p.includes(b)?w:w.optional()}return t}function cn(o){return!o||o.type==="none"?{}:o.type==="bearer"&&o.bearerToken?{Authorization:`Bearer ${o.bearerToken}`}:o.type==="basic"&&o.username?{Authorization:`Basic ${Buffer.from(`${o.username}:${o.password??""}`).toString("base64")}`}:o.type==="apiKey"&&o.apiKeyHeader&&o.apiKeyValue?{[o.apiKeyHeader]:o.apiKeyValue}:{}}function Ke(o,t){const d=o.broker;if(!d?.host||d.protocol!=="http")return console.warn(`[AsyncAPI] Skipping tool ${o.name}: missing broker.host or non-http protocol`),null;const p=o.channel||"";if(!p)return console.warn(`[AsyncAPI] Skipping tool ${o.name}: missing channel`),null;const b=(()=>{try{return JSON.parse(o.inputSchema??"{}")}catch{return{}}})(),h=Ee(b),w=d.channelStrategy??"path",P=String(d.host).replace(/\/+$/,""),_=(t?.webhookDepth??0)+1;return new Se({name:o.name,description:o.description??`Publish a message to "${p}".`,schema:q.object(h),func:async ce=>{const K={"Content-Type":"application/json",Accept:"application/json","X-Stkxp-Webhook-Depth":String(_),...cn(d.auth)};let M=P;if(w==="path")M=`${P}/${encodeURIComponent(p)}`;else if(w==="query"){const E=new URL(P);E.searchParams.set("channel",p),M=E.toString()}else w==="header"&&(K["X-Channel"]=p);try{const E=await fetch(M,{method:"POST",headers:K,body:JSON.stringify(ce),...be>0?{signal:AbortSignal.timeout(be)}:{}}),Q=await E.text();let F;try{F=Q?JSON.parse(Q):void 0}catch{F=void 0}return E.ok?{success:!0,channel:p,url:M,response:F??Q??null}:{error:`Broker returned HTTP ${E.status}`,url:M,response:F??Q}}catch(E){return{error:`Broker request failed: ${E?.message??String(E)}`,url:M}}}})}async function Fe(o,t){const d=JSON.parse(o.openApiMeta??"{}"),p=JSON.parse(o.inputSchema??"{}"),{method:b,path:h,servers:w,platformId:P}=d;if(!b||!h)return null;let _=t.get(P)??null;!_&&P&&(_=await rn(P),_&&t.set(P,_));const ce=(w?.[0]??_?.config?.baseUrl??"").replace(/\/+$/,"");if(!ce)return console.warn(`[OpenAPI] No baseUrl for tool ${o.name} (platformId=${P})`),null;const K=an(_?.config?.auth),M=Ee(p),E=p.properties??{};return new Se({name:o.name,description:o.description??`${b} ${h}`,schema:q.object(M),func:async Q=>{let F=h;const $={},g={},Z={};for(const[e,n]of Object.entries(Q)){const s=E[e],l=s?.["x-openapi-in"],c=s?.["x-openapi-name"]??e;l==="path"?F=F.replace(`:${c}`,encodeURIComponent(String(n))):l==="header"?g[c]=String(n):l==="body"||!l&&b!=="GET"?Z[c]=n:$[c]=Array.isArray(n)?n.join(","):String(n)}const z=new URLSearchParams($).toString(),oe=`${ce}${F}${z?`?${z}`:""}`,se=Object.keys(Z),ge=se.length===1&&se[0]==="body"?Z.body:Z,Te=se.length>0,fe={method:b,headers:{"Content-Type":"application/json",Accept:"application/json",...K,...g},...be>0?{signal:AbortSignal.timeout(be)}:{},...Te?{body:typeof ge=="string"?ge:JSON.stringify(ge)}:{}},me=await fetch(oe,fe),Y=await me.text();if(!me.ok)throw new Error(`HTTP ${me.status} ${me.statusText}: ${Y.slice(0,500)}`);try{return JSON.parse(Y)}catch{return Y}}})}async function ze(o,t,d){const b=(await ne.search({index:".stkxp_llm_routing_rules",body:{query:{bool:{must:[{term:{owner:t}},{term:{isDefault:!0}}]}},size:1}})).hits.hits[0]?._source;if(b)return console.log(`[LLM Config] Node ${o}: Using default routing rule '${b.id}' for owner '${t}'`),Pe(o,b.id,d,t,!0);const w=(await ne.search({index:".stkxp_llm_routing_rules",body:{query:{term:{owner:t}},size:1}})).hits.hits[0]?._source;if(w)return console.log(`[LLM Config] Node ${o}: No default rule for '${t}', using first available rule '${w.id}'`),Pe(o,w.id,d,t,!0);throw new Error(`Node "${o}" has no routing rule configured and no routing rules exist for user "${t}". Please configure an LLM routing rule in Settings \u2192 LLM Routing Rules.`)}async function Pe(o,t,d,p,b=!1){if(!t)return p&&!b?ze(o,p,d):(console.log(`[LLM Config] Node ${o}: No routing rule ID, using fallback`),d);const h=await ne.search({index:".stkxp_llm_routing_rules",body:{query:{bool:{must:[{term:{id:t}}]}},size:1}});if(!h.hits.hits[0])throw new Error(`[LLM Config] Node "${o}": routing rule "${t}" not found in .stkxp_llm_routing_rules`);const w=h.hits.hits[0]._source,P=w.modelId||w.llmModelId;if(!P)throw new Error(`[LLM Config] Node "${o}": routing rule "${t}" has no modelId configured`);const _={index:".stkxp_llm_models",body:{query:{bool:{must:[{term:{id:P}}]}},size:1}};console.log(`[LLM Config] Node ${o}: Loading model id=${P}`);const ce=await ne.search(_);if(!ce.hits.hits[0])throw new Error(`[LLM Config] Node "${o}": model "${P}" (rule "${t}") not found in .stkxp_llm_models`);const K=ce.hits.hits[0]._source,M=K.providerId,E=K.modelId,Q=w.temperature??K.parameters?.temperature??d.temperature,F=w.maxTokens??K.parameters?.maxTokens??d.maxTokens;let $=null;try{const se=await ne.get({index:".stkxp_llm_providers",id:M});se.found!==!1&&($=se._source)}catch{$=(await ne.search({index:".stkxp_llm_providers",body:{query:{bool:{must:[{term:{id:M}}]}},size:1}})).hits.hits[0]?._source??null}if(!$)throw new Error(`[LLM Config] Node "${o}": provider "${M}" (model "${P}") not found in .stkxp_llm_providers`);const g=$;if(p&&g.owner!==p){if(b)throw new Error(`[LLM Config] Node "${o}": user "${p}"'s own fallback routing rule resolves to provider "${M}" owned by "${g.owner??"(none)"}". Fix the user's default LLM routing rule / provider.`);return console.warn(`[LLM Config] Node "${o}": provider "${M}" belongs to owner "${g.owner??"(none)"}", not "${p}". Falling back to user's default routing rule.`),ze(o,p,d)}if(!g.apiKey)throw new Error(`[LLM Config] Node "${o}": provider "${g.name||M}" has no API key configured. Go to Settings \u2192 LLM Providers and add your API key.`);const Z=["openai","anthropic","google","local","openrouter","custom","mistral"],z=g.type;if(!Z.includes(z))throw new Error(`[LLM Config] Node "${o}": provider type "${g.type}" is not supported (valid: ${Z.join(", ")})`);const oe=`${g.apiKey.slice(0,8)}...${g.apiKey.slice(-4)}`;return console.log(`[LLM Config] Node ${o}: ${t} \u2192 ${P} \u2192 ${z}:${E} (T=${Q}, max=${F}) apiKey=${oe}`),{provider:z,model:E,temperature:Q,maxTokens:F,streaming:!0,apiKey:g.apiKey,baseURL:g.endpoint,routingRuleId:t,routingRuleName:w.name}}const ln=new Set(["topic_detection","assistant_tool_executor","assistant_tool_cleaner","assistant_response_generator","local_extractor","human_approval","suggestion_generator","code_executor"]);async function He(o,t,d){const p=new Map;console.log(`[LLM Config] Loading configs for graph ${o.id} with ${o.nodes.length} nodes`);for(const b of o.nodes){if(b.type==="subgraph")continue;const h=ln.has(b.type)||b.llm_routing_rule_id?d:void 0,w=await Pe(b.id,b.llm_routing_rule_id,t,h);p.set(b.id,w)}return console.log(`[LLM Config] Loaded ${p.size} configs for graph ${o.id}`),p}const Ge=5,ke=new Map;async function Hn(o,t){const d=(ke.get(t.threadId)||0)+1;ke.set(t.threadId,d),console.log(`
2
+ ${"\u{1F3D7}\uFE0F ".repeat(40)}`),console.log(`\u{1F3D7}\uFE0F buildAppFromDefinition CALLED (thread: ${t.threadId.substring(0,8)})`),console.log(`${"\u{1F3D7}\uFE0F ".repeat(40)}`),console.log(`\u{1F4CA} Concurrent calls for this thread: ${d}`),console.log(`\u{1F3AF} Assistant: ${t.assistant?.name||"unknown"}`),console.log(`\u{1F4E6} MCP servers in policy: ${t.assistant?.mcp_servers_policy?.servers?.length||0}`),console.log(`${"\u{1F3D7}\uFE0F ".repeat(40)}
3
+ `);const p=t.queryParams||{},b=p.packageName?.replace("stack_expert","clusters")||"clusters",h=t.assistant?.topic?.trim()||void 0,w=t.assistant?.assistantId||t.assistant?.id;h&&w&&Vt(w,h);const P=h||p.topic||(b!=="clusters"?`${b}_overview`:"unknown"),_={provider:"anthropic",model:"claude-haiku-4-5-20251001",temperature:0,maxTokens:8e3,streaming:!0,apiKey:je.llm.apiKey||"",baseURL:je.llm.baseURL};if(t.username)try{const a=await st(t.username);a&&(_.provider=a.provider,_.model=a.model,_.apiKey=a.apiKey,_.baseURL=a.baseURL)}catch(a){console.warn(`[LLM Config] Could not resolve owner default for fallback: ${a?.message}`)}const ce=_.apiKey?`${_.apiKey.slice(0,8)}...${_.apiKey.slice(-4)}`:"(none)";console.log(`[LLM Config] Fallback provider=${_.provider} apiKey=${ce} (owner '${t.username??"(none)"}' default)`);const K=await He(o,_,t.username);if(console.log(`[buildApp] Loaded ${K.size} LLM configs for graph nodes`),t.assistant?.llm_overrides)for(const[a,A]of Object.entries(t.assistant.llm_overrides)){const C=o.nodes.filter(L=>L.type===a);for(const L of C){const ee=await Pe(L.id,A,_,t.username);K.set(L.id,ee),console.log(`[LLM Config] llm_override: node "${L.id}" (type: ${a}) \u2192 routingRule: ${A}`)}}console.log(`[MCP] Building app for topic: ${P}`);let M=[];const E=t.assistant?.mcp_servers_policy?.mode,Q=t.assistant?.mcp_servers_policy?.servers,F=E==="none"||!Q||Q.length===0;F&&console.log(`[MCP] \u2139\uFE0F No MCP servers configured for assistant: ${t.assistant?.name||"unknown"} (mode=${E||"unset"}) \u2014 running tool-free.`);let $=[],g;const Z=F?new Map:await nt();if(F)console.log("[MCP] \u23ED\uFE0F Skipping MCP setup for tool-free assistant");else{let a="";if(t.userToken){const r=Oe.decode(t.userToken);r&&typeof r=="object"&&"username"in r&&(a=r.username||"")}!a&&t.username&&(a=t.username),console.log(`[MCP] \u{1F527} Loading tools from mcp_servers_policy (${t.assistant.name} has ${t.assistant.mcp_servers_policy.servers.length} servers)`);const A=t.assistant.mcp_servers_policy;console.log(`[MCP] \u{1F4CB} Server list for thread ${t.threadId.substring(0,8)}:`),A.servers.forEach((r,i)=>{console.log(` ${i+1}. ${r.name} (${r.id}) - enabled: ${r.enabled}`)});const C=Array.from(new Map(A.servers.map(r=>[r.name,r])).values());C.length<A.servers.length&&console.warn(`[MCP] \u26A0\uFE0F Detected duplicate servers: ${A.servers.length} \u2192 ${C.length} (removed ${A.servers.length-C.length} duplicates)`);const L=t.selectedNamespaces?new Map(t.selectedNamespaces.map(r=>[r.serverId,r])):null;for(const r of C){if(!r.enabled){console.log(`[MCP] \u23ED\uFE0F Skipping disabled server: ${r.name} (${r.id})`);continue}if(r.id?.startsWith("__personal_tools__:")){const i=r.id.replace("__personal_tools__:","");console.log(`[MCP] \u{1F9D1} Loading personal MCP tools for user: ${i}`);try{const m=await ne.search({index:".stkxp_tools",body:{query:{bool:{must:[{term:{owner:i}},{term:{enabled:!0}}],should:[{bool:{must:[{term:{type:"mcp"}}],must_not:[{exists:{field:"system"}}]}},{term:{type:"assistant_mapping"}}],minimum_should_match:1}},size:1e4,_source:["name","label","description","type","endpoint","inputSchema","httpMethod","authConfig","bodyFormat","customHeaders","bodyTemplate","variables","platformId"]}}),ae=r.excluded_tools||[];for(const B of m.hits.hits){const f=B._source;if(ae.includes(f.name))continue;const I=(()=>{try{return JSON.parse(f.inputSchema||"{}")}catch{return{}}})(),pe=Ee(I),_e=f.endpoint||"",$e=(f.httpMethod||"GET").toUpperCase(),x=f.authConfig||{},ue=f.bodyFormat==="form"?"form":"json",Ae=typeof f.bodyTemplate=="string"&&f.bodyTemplate.trim()?f.bodyTemplate:void 0,xe=Array.isArray(f.variables)?f.variables:[],Ie=Ae!==void 0||xe.length>0,Ce=Yt(f.customHeaders),y=f.type||"mcp",k=new Se({name:f.name,description:f.description||f.label||f.name,schema:q.object(pe),func:async ie=>{try{if(y==="assistant_mapping"){const j=ie.assistant_id;if(!j)return{error:"assistant_id parameter is required"};const N=`${process.env.STKXP_APP_URL||`https://localhost:${process.env.PORT||3003}`}/api/assistants/${encodeURIComponent(j)}/mapping`,u={Accept:"application/json"};t.userToken&&(u.Authorization=`Bearer ${t.userToken}`),console.log(`[MCP] \u{1F5FA}\uFE0F assistant_mapping: GET ${N}`);const S=new Qe({connect:{rejectUnauthorized:!1}}),de=await(await Ze(N,{method:"GET",headers:u,dispatcher:S})).text();try{return JSON.parse(de)}catch{return de}}const R={Accept:"application/json",...Ce};if(x.type==="bearer"&&x.token)R.Authorization=`Bearer ${x.token}`;else if(x.type==="bearer_internal"&&t.userToken)R.Authorization=`Bearer ${t.userToken}`;else if(x.type==="apiKey"&&x.apiKey)R[x.headerName||"X-API-Key"]=x.apiKey;else if(x.type==="basic"&&x.username)R.Authorization=`Basic ${Buffer.from(`${x.username}:${x.password||""}`).toString("base64")}`;else if(x.type==="platform_es"){const j=f.platformId;if(!j)return{error:"authConfig.type=platform_es requires the tool to have a platformId set"};try{const U=await Zt(j,t.username||"",!0,!t.username),N=U?.config,u=N?.endpoints?.elasticsearch?.username,S=N?.endpoints?.elasticsearch?.password;if(!U||U.type!=="ElasticStack"||!u||!S)return{error:`platform_es: platform "${j}" not found or has no Elasticsearch credentials`};R.Authorization=`Basic ${Buffer.from(`${u}:${S}`).toString("base64")}`}catch(U){return{error:`platform_es lookup failed for "${j}": ${U.message}`}}}const H={method:$e,headers:R};let G;const X={__username:t.username,__teamId:t.teamId,__chatId:t.chatId,__now:new Date().toISOString()};if(Ie){if(G=Qt(_e,xe,ie,X),$e!=="GET"&&Ae){const j=Wt(Ae,xe,ie,X);let U;try{U=JSON.parse(j)}catch(u){return{error:`bodyTemplate did not render to valid JSON: ${u.message}`}}Object.keys(R).some(u=>u.toLowerCase()==="content-type")||(R["Content-Type"]="application/json"),H.body=JSON.stringify(U)}}else{const j={...ie},U=/\{([^}]+)\}|:([A-Za-z_][A-Za-z0-9_]*)/g;if(G=_e.replace(U,(N,u,S)=>{const W=u||S,de=j[W];return de==null||de===""?N:(delete j[W],encodeURIComponent(String(de)))}),$e==="GET"){const N=new URLSearchParams(Object.entries(j).filter(([,u])=>u!=null).map(([u,S])=>[u,String(S)])).toString();N&&(G=`${G}${G.includes("?")?"&":"?"}${N}`)}else{const N=Object.keys(R).some(u=>u.toLowerCase()==="content-type");ue==="form"?(N||(R["Content-Type"]="application/x-www-form-urlencoded"),H.body=new URLSearchParams(Object.entries(j).filter(([,u])=>u!=null).map(([u,S])=>[u,String(S)])).toString()):(N||(R["Content-Type"]="application/json"),H.body=JSON.stringify(j))}}const V=await(await fetch(G,H)).text();try{return JSON.parse(V)}catch{return V}}catch(R){return{error:R.message}}}});$.push(k),console.log(`[MCP] \u2705 Personal tool registered: ${f.name}`)}}catch(m){console.error(`[MCP] \u274C Failed to load personal tools for ${i}:`,m.message)}continue}try{console.log(`[MCP] \u{1F4E6} Loading server: ${r.name} (${r.id})`);let i;try{i=(await ne.get({index:qe,id:r.id}))._source}catch(y){if(y.meta?.statusCode===404&&r.name){console.warn(`[MCP] \u26A0\uFE0F Server ID ${r.id} not found in ES (stale after restore), falling back to name lookup: ${r.name}`);const k=await ne.search({index:qe,body:{query:{bool:{must:[{term:{name:r.name}},{term:{type:"MCPServer"}}]}},size:1}});if(k.hits.hits.length>0)i=k.hits.hits[0]._source,console.log(`[MCP] \u2705 Found MCPServer platform by name: ${r.name}`);else throw new Error(`MCPServer platform not found by name: ${r.name}`)}else throw y}const m=i.config??{};if(i.type==="OpenAPI"&&!ct(m)){console.log(`[MCP] \u{1F50C} OpenAPI platform detected: ${r.name} \u2014 loading connector tools directly`);let y=[];try{y=(await ne.search({index:".stkxp_tools",body:{query:{bool:{must:[{term:{platformId:r.id}},{term:{enabled:!0}}]}},size:500}})).hits.hits.map(te=>te._source)}catch(X){console.error(`[MCP] \u274C Failed to load connector tools from OpenAPI platform ${r.name}:`,X.message);continue}const k=r.excluded_tools||[],ie=new Set(["oauth2_cc"]),R=new Set;if(ie.has(m?.auth?.type)){const X=new Map;for(const V of y)k.includes(V.name)||!V.system||(X.has(V.system)||X.set(V.system,new Set),X.get(V.system).add(V.name));const te=(process.env.MCP_URL||"https://51.158.76.76:3001/mcp").replace(/\/+$/,"");for(const[V,j]of X.entries())try{const U={};t.userToken&&(U.Authorization=`Bearer ${t.userToken}`),U["X-Platform-Id"]=r.id,a&&(U["X-Username"]=a);const N=await Re(`${te}/${encodeURIComponent(V)}`,{headers:U,transportType:"http",timeout:1e4});M.push(N),g||(g=N);const S=(await Le(`${r.name}`,N.client,{defaultToolTimeout:be})).filter(W=>j.has(W.name)).map(W=>{const de=Z.get(W.name);return de?.description&&(W.description=de.description),W._destructiveHint=Ne(W,de),W._mcpServerId=r.id,W._mcpServerName=r.name,W});S.forEach(W=>R.add(W.name)),$.push(...S),console.log(`[MCP] \u{1F510} oauth2_cc OpenAPI "${r.name}" \u2192 routed ${S.length} tool(s) via mcp-server package "${V}"`)}catch(U){console.warn(`[MCP] \u26A0\uFE0F oauth2_cc routing via mcp-server failed for package "${V}" (${U.message}) \u2014 those tools fall back to in-process`)}}const H=new Map;let G=0;for(const X of y)if(!k.includes(X.name)&&!R.has(X.name))try{const te=await Fe(X,H);te&&(te._mcpServerId=r.id,te._mcpServerName=r.name,$.push(te),G++)}catch(te){console.warn(`[MCP] \u26A0\uFE0F Skipped connector tool ${X.name}: ${te.message}`)}G>0&&console.log(`[MCP] \u2705 Loaded ${G} connector tool(s) in-process from OpenAPI platform "${r.name}"`);continue}if(i.type==="AsyncAPI"){console.log(`[MCP] \u{1F4E1} AsyncAPI platform detected: ${r.name} \u2014 loading publish tools directly`);try{const k=(await ne.search({index:".stkxp_tools",body:{query:{bool:{must:[{term:{platformId:r.id}},{term:{type:"asyncapi_publish"}},{term:{enabled:!0}}]}},size:500}})).hits.hits.map(H=>H._source),ie=r.excluded_tools||[];let R=0;for(const H of k)if(!ie.includes(H.name))try{const G=Ke(H,{webhookDepth:t.webhookDepth});G&&($.push(G),R++)}catch(G){console.warn(`[MCP] \u26A0\uFE0F Skipped asyncapi tool ${H.name}: ${G.message}`)}console.log(`[MCP] \u2705 Loaded ${R}/${k.length} publish tools from AsyncAPI platform "${r.name}"`)}catch(y){console.error(`[MCP] \u274C Failed to load publish tools from AsyncAPI platform ${r.name}:`,y.message)}continue}if(i.type==="Toolbox"){const y=String(m.url||"").replace(/\/$/,""),k=/\/mcp(\/sse)?$/.test(y)?y.replace(/\/mcp\/sse$/,"/mcp"):`${y}/mcp`,ie={};m.authKey&&(ie.Authorization=`ApiKey ${m.authKey}`);const R=`${Ye(a)}__`;try{const H=await Re(k,{headers:ie,transportType:"http",timeout:1e4});M.push(H),g||(g=H);const G=await Le(`${r.name}`,H.client,{defaultToolTimeout:be}),X=r.excluded_tools||[],te=(u,S)=>u===S||u.endsWith(`__${S}`),V=u=>X.some(S=>te(u,S)),j=r.included_tools||[],U=u=>j.length===0||j.some(S=>te(u,S)),N=G.filter(u=>u.name.startsWith(R)).filter(u=>!V(u.name)).filter(u=>U(u.name)).map(u=>{const S=Z.get(u.name);return S?.description&&(u.description=S.description),u._destructiveHint=Ne(u,S),u._mcpServerId=r.id,u._mcpServerName=r.name,u});$.push(...N),console.log(`[MCP] \u2705 Loaded ${N.length}/${G.length} Toolbox tools (owner-prefixed "${R}") from "${r.name}"`)}catch(H){console.error(`[MCP] \u274C Failed to load Toolbox tools from ${r.name}:`,H.message)}continue}const ae=i.id||t.queryParams?.platformId||"",B=m.namespace||t.queryParams?.namespace||"",f=m.serverType==="remote"||m.serverType==="gateway",I={};if(f){const y=m.headers||{},k=Object.keys(y).some(ie=>ie.toLowerCase()==="authorization");m.authKey&&!k&&(I.Authorization=`ApiKey ${m.authKey}`),Object.assign(I,y)}else t.userToken&&(I.Authorization=`Bearer ${t.userToken}`),ae&&(I["X-Platform-Id"]=ae),B&&(I["X-Namespace"]=B),a&&(I["X-Username"]=a),t.memoryScoped&&t.chatId&&(I["X-Chat-Id"]=t.chatId);const pe={headers:I,transportType:m.protocol||"http",timeout:1e4},_e=process.env.MCP_LOAD_TIMEOUT_MS?parseInt(process.env.MCP_LOAD_TIMEOUT_MS,10):8e3,$e=(async()=>{const y=await Re(m.url,pe),k=await Le(`${r.name}`,y.client,{defaultToolTimeout:be});return{client:y,serverTools:k}})();$e.catch(()=>{});const{client:x,serverTools:ue}=await Promise.race([$e,new Promise((y,k)=>setTimeout(()=>k(new Error(`MCP load timeout after ${_e}ms`)),_e))]);M.push(x),g||(g=x),console.log(`[MCP] \u2705 Loaded ${ue.length} tools from ${r.name}`);const Ae=t.assistant?.overrideAllowedTools,xe=Ae&&Ae.length>0?[]:r.excluded_tools||[],Ie=L?.get(r.id),Ce=ue.filter(y=>!xe.includes(y.name)).map(y=>{const k=Z.get(y.name);return k?.description&&(y.description=k.description),y._destructiveHint=Ne(y,k),y._mcpServerId=r.id,y._mcpServerName=r.name,Ie&&(y._system=Ie.system,y._selectedNamespace=Ie.namespace),y});xe.length>0&&(console.log(`[MCP] \u{1F6AB} Excluded ${ue.length} / ${Ce.length} / ${ue.length-Ce.length} tools from ${r.name}`),console.log(`[MCP] Excluded tools: ${xe.join(", ")}`)),$.push(...Ce),console.log(`[MCP] \u2705 Loaded allTools ${$.length}`,JSON.stringify(Ce.map(y=>y.name)))}catch(i){console.error(`[MCP] \u274C Failed to load server ${r.name}:`,i.message)}}if(console.log(`[MCP] \u{1F3AF} Total tools loaded: ${$.length} (after server exclusions)`),t.selectedNamespaces&&t.selectedNamespaces.length>1){const r=new Map;for(const m of t.selectedNamespaces)r.has(m.system)||r.set(m.system,[]),r.get(m.system).push(m);const i=new Set($.map(m=>m._mcpServerId).filter(Boolean));for(const[m,ae]of r){if(ae.length<=1)continue;const B=ae.filter(f=>!i.has(f.serverId)&&f.mcpUrl);for(const f of B)try{const I={};t.userToken&&(I.Authorization=`Bearer ${t.userToken}`),I["X-Platform-Id"]=f.serverId,I["X-Namespace"]=f.namespace,a&&(I["X-Username"]=a),t.memoryScoped&&t.chatId&&(I["X-Chat-Id"]=t.chatId);const pe=await Re(f.mcpUrl,{headers:I,transportType:"http",timeout:1e4});M.push(pe);const _e=await Le(`${m}_${f.namespace}`,pe.client,{defaultToolTimeout:be}),$e=_e.map(x=>{const ue=Z.get(x.name);return ue?.description&&(x.description=ue.description),x._destructiveHint=Ne(x,ue),x._mcpServerId=f.serverId,x._mcpServerName=`${m}_${f.namespace}`,x._system=m,x._selectedNamespace=f.namespace,x});$.push(...$e),console.log(`[MCP] \u2705 Fan-out: loaded ${_e.length} tools for ${m}/${f.namespace}`)}catch(I){console.warn(`[MCP] \u26A0\uFE0F Fan-out: failed to load ${m}/${f.namespace}: ${I.message}`)}}}const ee=t.assistant?.overrideAllowedTools;if(ee&&ee.length>0){const r=new Set(ee),i=$.length,m=$.filter(ae=>r.has(ae.name));if(m.length===0&&i>0){const ae=ee.filter(B=>!$.some(f=>f.name===B));console.warn(`[MCP] \u26A0\uFE0F allowedTools override ignored: all ${ee.length} selected tools are excluded by server policy. Stale: ${ae.join(", ")}. Using all ${i} available tools.`)}else $=m,console.log(`[MCP] \u{1F527} allowedTools override: ${i} \u2192 ${$.length} tools`)}}const z=$,oe=gt(z,_),se=t.selectedNamespaces&&t.selectedNamespaces.length>1?yt(oe):oe,ge=new Se({name:"mcp_paginated_query",description:"Call an MCP tool in a loop with nextCursor support",schema:q.object({toolName:q.string(),args:q.record(q.any()),maxPages:q.number().int().min(1).default(10),maxItems:q.number().int().min(1).default(5e3)}),func:async({toolName:a,args:A,maxPages:C,maxItems:L})=>{const ee=z.find(B=>B.name===a)||$.find(B=>B.name===a);if(!ee)throw new Error(`Tool not found: ${a}`);let r=A?.request?.body?.cursor,i=0;const m=[];for(;i<C&&m.length<L;){const B=JSON.parse(JSON.stringify(A||{}));r&&(B.request=B.request||{},B.request.body=B.request.body||{},B.request.body.cursor=r);const f=await xt(ee,B,{retries:4,baseDelayMs:750,retryOn:[429,502,503,504]}),{data:I,nextCursor:pe}=pt(f);if(Array.isArray(I)&&I.length&&m.push(...I),i+=1,!pe)break;r=pe}const ae=i>=C||m.length>=L||!r;return{items:m,pages:i,done:ae,nextCursor:r}}}),Te=new Ve({maxResults:3});let fe="anonymous";if(t.userToken){const a=Oe.decode(t.userToken);a&&typeof a=="object"&&"username"in a&&(fe=a.username||"anonymous")}const me=t.assistant?.assistantIds||(t.assistant?.assistantId?[t.assistant.assistantId]:t.assistant?.id?[t.assistant.id]:[]),Y=new Se({name:"compare_with_previous_chat",description:"Compare current conversation with a previous saved chat",schema:q.object({chatId:q.string(),comparisonAspects:q.array(q.enum(["metrics","errors","performance","configuration","overall","recommendations"])).optional(),includeTimeDelta:q.boolean().optional()}),func:async(a,A)=>{const C=A?.state?.messages||[];return await et(fe,C).func(a,A)}}),e=new Se({name:"enrich_from_previous_chat",description:"Enrich the current analysis with insights and perspectives from a previous chat session",schema:q.object({chatId:q.string(),enrichmentFocus:q.array(q.enum(["metrics","errors","recommendations","configuration","performance","security","overall"])).optional(),includeTimeDelta:q.boolean().optional()}),func:async(a,A)=>{const C=A?.state?.messages||[];return await tt(fe,C,me).func(a,A)}}),n=(t.assistant?.mcp_servers_policy?.servers||[]).filter(a=>a?.enabled!==!1&&a?.id).map(a=>String(a.id)),s=[];try{const a=await on(fe,n);if(a.length>0){const A=new Map;for(const C of a)try{const L=await Fe(C,A);L&&(C.requiresForm===!0&&(L._requiresForm=!0,L._toolDoc=C),s.push(L))}catch(L){console.warn(`[OpenAPI] \u26A0\uFE0F Skipped tool ${C.name}: ${L.message}`)}console.log(`[OpenAPI] \u2705 Loaded ${s.length} OpenAPI connector tools`)}}catch(a){console.warn(`[OpenAPI] \u26A0\uFE0F Failed to load OpenAPI tools: ${a.message}`)}const l=[];try{const a=await sn(fe,n);if(a.length>0){for(const A of a)try{const C=Ke(A,{webhookDepth:t.webhookDepth});C&&l.push(C)}catch(C){console.warn(`[AsyncAPI] \u26A0\uFE0F Skipped tool ${A.name}: ${C.message}`)}console.log(`[AsyncAPI] \u2705 Loaded ${l.length} AsyncAPI publish tools`)}}catch(a){console.warn(`[AsyncAPI] \u26A0\uFE0F Failed to load AsyncAPI tools: ${a.message}`)}let c=F?[]:[...se,...s,...l];console.log(`[MCP] Loaded ${c.length} tools before provider adaptation`,c.map(a=>a.name));const O=o.nodes.find(a=>a.type==="assistant_tool_executor"),T=o.nodes.find(a=>a.type==="assistant_response_generator"),D=O&&K.get(O.id)||_,re=T&&K.get(T.id)||_;console.log(`[LLM Config] Tool Executor (${O?.id??"no-tool-executor-in-graph"}):`,D),console.log(`[LLM Config] Response Generator (${T?.id??"no-response-generator-in-graph"}):`,re),D.provider==="openai"&&(c=c.map(a=>a.schema?{...a,schema:dt(a.schema,"openai")}:a),console.log(`[MCP] Adapted ${c.length} tools for OpenAI`)),D.provider==="anthropic"&&(c=lt(c),console.log(`[MCP] Adapted ${c.length} tools for Anthropic`)),D.provider==="google"&&(c=ut(c),console.log(`[MCP] Adapted ${c.length} tools for Gemini`)),console.log(`[MCP] Wrapping ${z.length} MCP tools with queryParams injection...`);const J=new Set(z.map(a=>a.name));c=ft(c,J,{userToken:t.userToken,queryParams:p}),console.log(`[MCP] \u2705 Wrapped ${J.size} MCP tools with queryParams`);const ye=c,ve=new Map;for(const a of ye)ve.has(a.name)||ve.set(a.name,a);c=Array.from(ve.values());const he={};for(const a of c)a._mcpServerId&&(he[a.name]={serverId:a._mcpServerId,serverName:a._mcpServerName||""});console.log(`[MCP] Deduplicated tools: ${ye.length} \u2192 ${c.length} tools`,c);const we=await De(o,t,K,c,g,_,M,P,0),le=(ke.get(t.threadId)||1)-1;return le<=0?ke.delete(t.threadId):ke.set(t.threadId,le),console.log(`[buildApp] \u2705 Build complete for thread ${t.threadId.substring(0,8)} (remaining concurrent calls: ${le})`),{...we,toolServerMap:he}}async function De(o,t,d,p,b,h,w,P,_){const ce=t.queryParams||{};if(t.assistant?.nodeOverrides){const e=t.assistant.nodeOverrides;for(const[n,s]of Object.entries(e)){let l=d.get(n);if(l){if(s.routingRuleId)try{l=await Pe(n,s.routingRuleId,h,t.username)}catch(c){console.warn(`[LLM Config] nodeOverride: failed to resolve routingRuleId "${s.routingRuleId}" for node "${n}": ${c?.message}`)}d.set(n,{...l,...s.maxTokens!==void 0?{maxTokens:s.maxTokens}:{},...s.temperature!==void 0?{temperature:s.temperature}:{}}),console.log(`[LLM Config] nodeOverride (depth ${_}): node "${n}" \u2192 `+`${s.routingRuleId?`routingRuleId=${s.routingRuleId} `:""}${s.maxTokens!==void 0?`maxTokens=${s.maxTokens} `:""}${s.temperature!==void 0?`temperature=${s.temperature}`:""}`.trim())}}}const K=o.nodes.find(e=>e.type==="assistant_tool_executor"),M=o.nodes.find(e=>e.type==="assistant_response_generator"),E=K&&d.get(K.id)||h,Q=M&&d.get(M.id)||h,F=v.Root({...Je.spec,toolExecRounds:v({reducer:(e,n)=>n!==void 0?n:e,default:()=>0}),toolsUsedAccum:v({reducer:(e,n)=>n?.length?[...new Set([...e||[],...n])]:e||[],default:()=>[]}),threadId:v({reducer:(e,n)=>n||e,default:()=>t.threadId}),userContext:v({reducer:(e,n)=>n!==void 0?n:e,default:()=>t.userContext}),teamContext:v({reducer:(e,n)=>n!==void 0?n:e,default:()=>it(t.teamSharedContext,at(t.teamSharedContext?.policy),"assistants")}),topic:v({reducer:(e,n)=>n!==void 0?n:e,default:()=>{}}),context:v({reducer:(e,n)=>n!==void 0?n:e,default:()=>{}}),systemPromptTools:v({reducer:(e,n)=>n!==void 0?n:e,default:()=>{}}),systemPromptFinal:v({reducer:(e,n)=>n!==void 0?n:e,default:()=>{}}),compressionStats:v({reducer:(e,n)=>n!==void 0?n:e,default:()=>{}}),entityTokenMap:v({reducer:(e,n)=>({...e,...n}),default:()=>({})}),toolResults:v({reducer:(e,n)=>({...e,...n}),default:()=>({})}),customFields:v({reducer:(e,n)=>({...e,...n}),default:()=>({})}),compareChatId:v({reducer:(e,n)=>n!==void 0?n:e,default:()=>t.compareChatId}),enrichChatId:v({reducer:(e,n)=>n!==void 0?n:e,default:()=>t.enrichChatId}),last_tool_error:v({reducer:(e,n)=>n!==void 0?n:e,default:()=>!1}),namespaceMap:v({reducer:(e,n)=>n!==void 0?n:e,default:()=>({})}),codeExecTrace:v({reducer:(e,n)=>n!==void 0?n:e,default:()=>[]}),codeExecScript:v({reducer:(e,n)=>n!==void 0?n:e,default:()=>{}}),codeExecConsoleLogs:v({reducer:(e,n)=>n!==void 0?n:e,default:()=>{}}),codeExecStats:v({reducer:(e,n)=>n!==void 0?n:e,default:()=>{}}),teamAssistantResults:v({reducer:(e,n)=>n!==void 0?n:e,default:()=>[]}),teamAssistantResultsHistory:v({reducer:(e,n)=>n===void 0?e:[...e??[],...n],default:()=>[]}),selectedAssistantIds:v({reducer:(e,n)=>n!==void 0?n:e,default:()=>{}}),selectedTeamId:v({reducer:(e,n)=>n!==void 0?n:e,default:()=>{}}),ancestorTeamIds:v({reducer:(e,n)=>n!==void 0?n:e,default:()=>{}}),keywords:v({reducer:(e,n)=>n!==void 0?n:e,default:()=>{}}),language:v({reducer:(e,n)=>n!==void 0?n:e,default:()=>{}}),teamRouterDecision:v({reducer:(e,n)=>n!==void 0?n:e,default:()=>{}})}),$=new Xe(F),g=(e,n)=>{const s=e?.metadata?.langgraph_node??e?.configurable?.langgraph_node;if(s){const l=o.nodes?.find(c=>c.id===s);if(l)return l}return o.nodes?.find(l=>l.type===n)},Z=(e,n)=>async(s,l)=>{const c=await n(s,l);if(process.env.GRAPH_MESSAGE_LOG&&c?.messages?.length){const O=l?.metadata?.langgraph_node??l?.configurable?.langgraph_node??e;for(const T of c.messages)console.log(`[GRAPH-MSG][thread=${t.threadId}][node=${O}] type=${T?._getType?.()??"?"}`+(T?.tool_calls?.length?` tool_calls=${JSON.stringify(T.tool_calls)}`:"")+(T?.tool_call_id?` tool_call_id=${T.tool_call_id}`:"")+` content=${JSON.stringify(T?.content)}`)}return c},z={checkReset:async e=>Be(e,{threadId:t.threadId}),check_reset:async e=>Be(e,{threadId:t.threadId}),inventory_context:async e=>qt(e,{username:t.username||""}),skills_context:async e=>Kt(e,{username:t.username||""}),node_types_context:async e=>Ft(e,{username:t.username||""}),relevant_skills_context:async e=>zt(e,{username:t.username||""}),relevant_assistants_context:async e=>Ht(e,{username:t.username||""}),assistants_context:async e=>Gt(e,{username:t.username||""}),namespace_context:async e=>Dt(e,{mcpServersPolicy:t.assistant?.mcp_servers_policy,username:t.username||""}),topic_detection:async(e,n)=>At(e,{llmConfig:d.get("topic_detection")||h,graphDef:o,topicName:P,assistant:t.assistant,nodeDef:g(n,"topic_detection")}),system:async e=>Ct(e,{llmConfig:d.get("system")||h,graphDef:o,firstClient:b,queryParams:ce,systemPrefix:(()=>{const n=ce.packageName?.replace("stack_expert","clusters")||"";return n==="clusters"?"":n})(),userToken:t.userToken,assistant:t.assistant,chatId:t.chatId,channel:t.channel}),assistant_tool_executor:async(e,n)=>{const s=g(n,"assistant_tool_executor");return St(e,{llmConfig:d.get(s?.id??"assistant_tool_executor")||E,graphDef:o,tools:p,contextFromSystem:e.context,cfg:n,assistant:t.assistant,channel:t.channel})},code_executor:async(e,n)=>{const s=g(n,"code_executor");return Mt(e,{llmConfig:d.get(s?.id??"code_executor")||E,graphDef:o,tools:p,contextFromSystem:e.context,cfg:n,assistant:t.assistant,channel:t.channel,username:t.username,timeoutMs:s?.codeExecutorTimeoutMs,maxMemoryMb:s?.codeExecutorMaxMemoryMb,nodeDef:s})},static_code_executor:async(e,n)=>{const s=g(n,"static_code_executor");return It(e,{graphDef:o,tools:p,cfg:n,assistant:t.assistant,timeoutMs:s?.codeExecutorTimeoutMs,maxMemoryMb:s?.codeExecutorMaxMemoryMb,channel:t.channel,username:t.username,nodeDef:s})},tool:async(e,n)=>Pt(e,{finalTools:p,cfg:n}),tool_invoker:async(e,n)=>{const s=g(n,"tool_invoker");return kt(e,{nodeDef:s,tools:p,deps:t})},raw_output:async(e,n)=>{const s=g(n,"raw_output");return Rt(e,{nodeDef:s})},state_setter:async(e,n)=>{const s=g(n,"state_setter");return Lt(e,{nodeDef:s})},assistant_tool_cleaner:async(e,n)=>{const s=d.get("assistant_tool_cleaner")||h;return console.log("[Tool Cleaner Node] \u{1F9F9} Executing tool cleaner with config:",s),Nt(e,{llmConfig:s,graphDef:o,cfg:n,assistant:t.assistant})},local_extractor:async e=>{const n=await Jt(o,"local_extractor",void 0,t.assistant),s=d.get("local_extractor")??null;return Et(e,{llmConfig:s,extractorInstructions:n})},assistant_response_generator:async(e,n)=>t.behindDecider?(console.log("[assistant_response_generator] \u23ED\uFE0F Skipped (behindDecider=true) \u2014 saved an LLM call for sub-assistant"),{messages:[],systemPromptFinal:""}):Ot(e,{llmConfig:d.get("assistant_response_generator")||Q,graphDef:o,cfg:n,assistant:t.assistant,channel:t.channel}),compare_context:async e=>jt(e,{username:t.username||""}),enrich_context:async e=>Ut(e,{username:t.username||"",currentAssistantIds:t.assistant?.assistantIds||[]}),human_approval:async(e,n)=>{const l=g(n,"human_approval")?.id??"human_approval",c=t.assistant?.mcp_servers_policy?.servers??[],O=(c[0]?.name||c[0]?.packageName||"").toLowerCase()||void 0;return Bt(e,{graphDef:o,nodeId:l,llmConfig:d.get(l)||h,defaultSystem:O,tools:p,assistant:t.assistant,username:t.username})},team_pipeline:async(e,n)=>{const s=g(n,"team_pipeline");return ht(e,{teamAssistants:t.teamAssistants||[],buildAssistantApp:t.buildAssistantApp||(()=>Promise.reject(new Error("buildAssistantApp not injected"))),deps:Me(t),nodeDef:s,cfg:n})},team_parallel:async(e,n)=>{const s=g(n,"team_parallel");return _t(e,{teamAssistants:t.teamAssistants||[],buildAssistantApp:t.buildAssistantApp||(()=>Promise.reject(new Error("buildAssistantApp not injected"))),deps:Me(t),nodeDef:s,cfg:n})},team_decider:async(e,n)=>{const s=g(n,"team_decider"),l=s?.id??"team_decider";return $t(e,{llmConfig:d.get(l)||h,graphDef:o,cfg:n,assistant:t.assistant,teamAssistants:t.teamAssistants||[],buildAssistantApp:t.buildAssistantApp,deps:Me(t),nodeDef:s})},team_router:async(e,n)=>{const s=g(n,"team_router"),l=s?.id??"team_router";return bt(e,{llmConfig:d.get(l)||h,graphDef:o,deps:Me(t),teamAssistants:t.teamAssistants||[],nodeDef:s})},team_finder:async(e,n)=>{const s=g(n,"team_finder"),l=s?.id??"team_finder";return vt(e,{llmConfig:d.get(l)||h,graphDef:o,deps:Me(t),nodeDef:s,searchTeams:Ue})},suggestion_generator:async(e,n)=>{const s=g(n,"suggestion_generator"),l=s?.id??"suggestion_generator";return wt(e,{llmConfig:d.get(l)||h,deps:{username:t.username,teamId:t.teamId,channel:t.channel,teamAssistants:t.teamAssistants||[]},nodeDef:s,searchTeams:Ue})},team_invoker:async(e,n)=>{const s=g(n,"team_invoker"),l=async(c,O)=>{const{getTeamInvocationConfig:T}=await import("../services/teams-service"),{resolveAssistants:D}=await import("../services/assistant-resolver"),{mergeAssistantRouting:re}=await import("../services/team-runner-headless"),J=await T(c);if(!J||J.assistantIds.length===0)return J?{name:J.name,assistants:[]}:null;const ye=await D(J.assistantIds,J.owner||O),ve=new Set(J.assistants.filter(le=>le.enabled!==!1).map(le=>le.id)),he=J.assistants.length>0?ye.filter(le=>ve.has(le.assistantId)):ye,we=re(he,J.assistants);return{name:J.name,assistants:we}};return Tt(e,{targetTeamId:rt(s,e),resolveTargetTeam:l,buildAssistantApp:t.buildAssistantApp||(()=>Promise.reject(new Error("buildAssistantApp not injected"))),deps:Me(t),nodeDef:s,cfg:n,sourceGraphId:o.id,sourceAssistantId:t.assistant?.assistantId})}};for(const e of Object.keys(z))z[e]=Z(e,z[e]);console.log(`[buildApp] Adding ${o.nodes.length} nodes from graphDef to graph`);const oe=new Set(["__start__","__end__"]);for(const e of o.nodes){if(e.type==="subgraph"){if(!e.graphId){console.warn(`[buildApp] \u26A0\uFE0F Subgraph node ${e.id} has no graphId, skipping`);continue}if(_>=Ge){console.warn(`[buildApp] \u26A0\uFE0F Max subgraph depth (${Ge}) reached at node ${e.id}, skipping`);continue}try{console.log(`[buildApp] \u{1F517} Loading subgraph node: ${e.id} \u2192 graphId: ${e.graphId} (depth: ${_+1})`);const s=await ot(e.graphId);if(!s){console.warn(`[buildApp] \u26A0\uFE0F Subgraph ${e.graphId} not found (node: ${e.id}), skipping`);continue}if(s.graphType==="kibana_agent"||s.graphType==="a2a_agent"){const O=s.graphType==="kibana_agent"?"Kibana Agent Builder":"A2A Agent";throw new Error(`Subgraph node '${e.id}' references '${s.name}' (${e.graphId}), a ${O} runtime. ${O} graphs delegate execution outside LangGraph and can only be used as a root-level assistant/team runtime, not nested inside another graph.`)}const l=await He(s,h,t.username),c=await De(s,t,l,p,b,h,w,P,_+1);$.addNode(e.id,c._compiled),oe.add(e.id),console.log(`[buildApp] \u2705 Added subgraph node: ${e.id} \u2192 ${e.graphId}`)}catch(s){console.error(`[buildApp] \u274C Failed to build subgraph node ${e.id}:`,s.message)}continue}const n=z[e.type];if(!n){console.warn(`[buildApp] \u26A0\uFE0F Unknown node type: ${e.type} for node ${e.id}`),console.warn(`[buildApp] \u26A0\uFE0F Skipping node: ${e.id}`);continue}console.log(`[buildApp] Adding node: ${e.id} (type: ${e.type})`),$.addNode(e.id,n),oe.add(e.id)}const se=!!t.compareChatId,ge=!!t.enrichChatId;if(se||ge){const e=o.nodes.find(l=>l.type==="system")?.id||"system",n=o.nodes.find(l=>l.type==="assistant_tool_executor")?.id||"assistant_tool_executor";if(!o.edges.some(l=>{const c=l.from||l.source,O=l.to||l.target;return c===e&&O===n}))console.warn(`[buildApp] \u26A0\uFE0F Skipping compare/enrich injection: no '${e} \u2192 ${n}' edge found in graph. Topology probably uses a custom intercept point \u2014 implement it in the graph itself or update this heuristic.`);else{se&&($.addNode("compare_context",z.compare_context),oe.add("compare_context"),console.log("[buildApp] Injected compare_context node")),ge&&($.addNode("enrich_context",z.enrich_context),oe.add("enrich_context"),console.log("[buildApp] Injected enrich_context node"));const l=[];for(const c of o.edges){const O=c.from||c.source,T=c.to||c.target;if(O===e&&T===n){const D=[e];se&&D.push("compare_context"),ge&&D.push("enrich_context"),D.push(n);for(let re=0;re<D.length-1;re++)l.push({from:D[re],to:D[re+1]});console.log(`[buildApp] Patched edge: ${D.join(" \u2192 ")}`)}else l.push(c)}o={...o,edges:l}}}console.log(`[buildApp] Adding ${o.edges.length} edges from graphDef to graph`);const Te=new Map;for(const e of o.edges){const n=e.from||e.source,s=e.to||e.target;if(!n||!s){console.warn("[buildApp] \u26A0\uFE0F Invalid edge (missing from/to):",e);continue}if(!oe.has(n)){console.warn(`[buildApp] \u26A0\uFE0F Skipping edge ${n} \u2192 ${s}: node '${n}' was not registered (check graph definition)`);continue}if(s!=="__end__"&&!oe.has(s)){console.warn(`[buildApp] \u26A0\uFE0F Skipping edge ${n} \u2192 ${s}: node '${s}' was not registered (check graph definition)`);continue}Te.has(n)||Te.set(n,[]),Te.get(n).push({...e,from:n,to:s})}for(const[e,n]of Te.entries()){const s=n.filter(c=>c.condition),l=n.filter(c=>!c.condition);if(s.length>0){const c=async T=>{const D=T.messages[T.messages.length-1],re=D?.tool_calls&&D.tool_calls.length>0,J=process.env.MAX_TOOL_ROUNDS?parseInt(process.env.MAX_TOOL_ROUNDS,10):8,ye=T.toolExecRounds??0,ve=s.some(i=>i.condition==="no_tool_calls"),he=re&&ve&&J>0&&ye>=J,we=[...T.messages].reverse(),le=we.findIndex(i=>i.getType?.()==="ai"),a=(le>=0?we.slice(0,le):we).filter(i=>i.getType?.()==="tool"),A=a[0]??null;let C=null;if(A)try{C=JSON.parse(A.content)}catch{}const L=i=>{try{return JSON.parse(i.content)}catch{return null}},ee=a.some(i=>{const m=L(i);return m?.available===!0||m?.domains?.[0]?.available===!0}),r=Object.keys(T.namespaceMap||{}).length>0;console.log(`[conditional_edge] from=${e}, hasToolCalls=${re}, last_tool_error=${T.last_tool_error}, isAvailable=${ee}, namespaceResolved=${r}`);for(const i of s){if(i.condition==="has_tool_calls"&&re&&!he)return console.log(`[conditional_edge] Route: ${e} \u2192 ${i.to} (has_tool_calls)`),i.to;if(i.condition==="no_tool_calls"&&(!re||he))return he?console.warn(`[conditional_edge] \u{1F6D1} tool-loop cap reached (${ye}/${J} rounds) \u2014 forcing exit ${e} \u2192 ${i.to} despite pending tool_calls`):console.log(`[conditional_edge] Route: ${e} \u2192 ${i.to} (no_tool_calls)`),i.to;if(i.condition==="available"&&ee)return console.log(`[conditional_edge] Route: ${e} \u2192 ${i.to} (available)`),i.to;if(i.condition==="not_available"&&!ee)return console.log(`[conditional_edge] Route: ${e} \u2192 ${i.to} (not_available)`),i.to;if(i.condition==="tool_success"&&!T.last_tool_error)return console.log(`[conditional_edge] Route: ${e} \u2192 ${i.to} (tool_success)`),i.to;if(i.condition==="tool_error"&&T.last_tool_error)return console.log(`[conditional_edge] Route: ${e} \u2192 ${i.to} (tool_error)`),i.to;if(i.condition==="namespace_resolved"&&r)return console.log(`[conditional_edge] Route: ${e} \u2192 ${i.to} (namespace_resolved)`),i.to;if(i.condition==="namespace_not_resolved"&&!r)return console.log(`[conditional_edge] Route: ${e} \u2192 ${i.to} (namespace_not_resolved)`),i.to;if(i.condition==="custom_jsonata"&&await Xt(i.conditionExpr,{state:T}))return console.log(`[conditional_edge] Route: ${e} \u2192 ${i.to} (custom_jsonata: ${i.conditionExpr})`),i.to}return console.warn(`[conditional_edge] No condition matched for ${e}, defaulting to __end__`),"__end__"},O={};for(const T of s)O[T.to]=T.to;O.__end__="__end__",console.log(`[buildApp] Adding conditional edge: ${e} \u2192 [${s.map(T=>`${T.to}(${T.condition})`).join(", ")}]`),$.addConditionalEdges(e,c,O)}else if(l.length>0)for(const c of l)console.log(`[buildApp] Adding edge: ${c.from} \u2192 ${c.to}`),$.addEdge(c.from,c.to)}if(o.edges.some(e=>(e.from||e.source)==="__start__"))console.log("[buildApp] Entry point already defined in edges");else{const e=o.nodes[0]?.id||"checkReset";console.log(`[buildApp] Adding missing entry point: __start__ \u2192 ${e}`),$.addEdge("__start__",e)}const me={checkpointer:_===0?t.memory:void 0};o.config?.recursionLimit&&(me.recursionLimit=o.config.recursionLimit);const Y=$.compile(me);return console.log(`[buildApp] \u2705 Graph compiled (depth: ${_})`),{invoke:Y.invoke.bind(Y),stream:Y.stream.bind(Y),streamEvents:Y.streamEvents.bind(Y),getState:Y.getState.bind(Y),cleanup:()=>{for(const e of w)e.close().catch(()=>{})},_compiled:Y,toolNames:p.map(e=>e.name)}}export{Hn as buildAppFromDefinition,Pe as loadLLMConfigForNode,He as loadLLMConfigsForGraph};
@@ -0,0 +1 @@
1
+ import{getPlatformById as c}from"../services/platforms-service";import{KibanaClientFactory as f}from"../services/kibana-client-factory";function u(e){const t=e.kibanaAgent??{};if(!t.agentId)throw new Error("Kibana agent graph is missing kibanaAgent.agentId");if(!t.platformId)throw new Error("Kibana agent graph is missing kibanaAgent.platformId");return{isKibanaAgent:!0,agentId:t.agentId,platformId:t.platformId,cleanup:()=>{}}}async function I(e,t,n={}){const r=await c(e.platformId,"",!1,!0);if(!r)throw new Error(`Platform not found: ${e.platformId}`);const l=f.createFromPlatform(r),i={input:t,agent_id:e.agentId};n.conversationId&&(i.conversation_id=n.conversationId);let o="",s=n.conversationId;const d=[];for await(const a of l.converseAsync(i,n.abortSignal)){if(n.abortSignal?.aborted)break;switch(a.event){case"conversation_id_set":a.data?.conversation_id&&(s=a.data.conversation_id);break;case"message_chunk":a.data?.text_chunk&&(o+=a.data.text_chunk,n.onToken?.(a.data.text_chunk));break;case"message_complete":a.data?.message_content&&(o=a.data.message_content);break;case"tool_call":a.data?.tool_id&&(d.push(a.data.tool_id),n.onToolStart?.(a.data.tool_id,a.data.params||null));break;case"tool_result":a.data?.tool_id&&n.onToolEnd?.(a.data.tool_id);break;case"reasoning":a.data?.reasoning&&!a.data?.transient&&console.log(`[KibanaAgent] reasoning: ${String(a.data.reasoning).slice(0,100)}`);break;case"error":{const g=a.data?.error?.message||a.data?.message||JSON.stringify(a.data).slice(0,300);throw console.error("[KibanaAgent] Error event from Kibana:",g),new Error(`Kibana Agent error: ${g}`)}default:console.log(`[KibanaAgent] Unknown event: "${a.event}", data:`,JSON.stringify(a.data).slice(0,200));break}}return{text:o,toolsUsed:d,conversationId:s}}export{u as buildKibanaAgentApp,I as runKibanaAgentConversation};
@@ -0,0 +1,5 @@
1
+ import{SystemMessage as c}from"@langchain/core/messages";import{Client as u}from"@elastic/elasticsearch";const m=new u({node:process.env.ELASTICSEARCH_HOST||"https://51.159.174.230:9205",auth:{username:process.env.ELASTICSEARCH_USER||"elastic",password:process.env.ELASTICSEARCH_PASSWORD||"diagnostics"},tls:{rejectUnauthorized:!1}});async function l(n){try{return(await m.search({index:".stkxp_assistants",body:{query:{bool:{must:[{bool:{should:[{term:{owner:n}},{term:{owner:"stkxp"}}],minimum_should_match:1}}],must_not:[{term:{tags:"internal"}}]}},size:100,sort:[{"topic.keyword":{order:"asc",missing:"_last"}}],_source:["name","topic","description","tags","context.role"]}})).hits.hits.map(s=>({id:s._id,name:s._source?.name||"unknown",topic:s._source?.topic||"",description:s._source?.description||"",role:s._source?.context?.role||"",tags:s._source?.tags||[]}))}catch{return[]}}const g=/^[A-Za-z0-9+/=]{20,}$/;function r(n){return n.split("|").map(t=>t.trim()).filter(t=>t.length>0&&!g.test(t))}function p(n){const t=r(n);return t.length===0?null:`topic:${t[0]}`}function d(n){if(n.length===0)return`## Available Assistants
2
+
3
+ _No assistants found. Output assistants: []._
4
+ `;const t=new Map;for(const e of n){const o=r(e.topic)[0]||"_no_topic_";t.has(o)||t.set(o,[]),t.get(o).push(e)}const s=["## Available Assistants","","Format: id | name | condition_hint",""];for(const[e,i]of t){s.push(`### Domain: ${e}`);for(const o of i){const a=p(o.topic)||"runAlways:true";s.push(`- \`${o.id}\` | ${o.name} | ${a}`)}s.push("")}return s.push("Use the exact id from the backtick value above. Derive condition from condition_hint. If condition_hint is 'runAlways:true', set condition:null and runAlways:true."),s.join(`
5
+ `)}async function A(n,t){const s=t.username||"";if(process.env.GRAPH_STATE_DEBUG&&console.log("[STATE][ASSISTANTS-CONTEXT]: "+JSON.stringify(n)),!s)return console.warn("[assistants_context] No username in context \u2014 skipping"),{};console.log(`[assistants_context] Fetching assistants for user: ${s}`);const e=await l(s),i=d(e);return console.log(`[assistants_context] Injected ${e.length} assistants`),{messages:[new c(i)]}}export{A as execute};
@@ -0,0 +1,10 @@
1
+ import{SystemMessage as p}from"@langchain/core/messages";import{Client as g}from"@elastic/elasticsearch";const u=new g({node:process.env.ELASTICSEARCH_HOST||"https://51.159.174.230:9205",auth:{username:process.env.ELASTICSEARCH_USER||"elastic",password:process.env.ELASTICSEARCH_PASSWORD||"diagnostics"},tls:{rejectUnauthorized:!1}}),f=".stkxp_chats";async function h(o,r){try{const s=(await u.get({index:f,id:o}))._source;if(!s||s.username!==r)return null;const a=s.title||"Untitled chat",m=s.messages||[],c=[`Reference chat: "${a}"`];for(const n of m){const i=Array.isArray(n.role)?n.role[0]:n.role,t=Array.isArray(n.content)?n.content[0]:n.content;if(!t||typeof t!="string"||t.startsWith("[React Element"))continue;const l=t.length>1e3?t.slice(0,1e3)+"\u2026":t;i==="user"?c.push(`[User] ${l}`):(i==="agent"||i==="assistant")&&c.push(`[Assistant] ${l}`)}return c.join(`
2
+
3
+ `)}catch(e){return e?.meta?.statusCode!==404&&console.error(`[compare_context] Failed to load chat ${o}:`,e?.message),null}}async function A(o,r){const{compareChatId:e}=o;if(process.env.GRAPH_STATE_DEBUG&&console.log("[STATE][COMPARE-CONTEXT]: "+JSON.stringify(o)),!e)return console.log("[compare_context] No compareChatId in state \u2014 skipping"),{};console.log(`[compare_context] Loading reference chat: ${e}`);const s=await h(e,r.username);if(!s)return console.warn(`[compare_context] Could not load chat ${e} \u2014 skipping injection`),{};const a=new p(`[COMPARE CONTEXT]
4
+ A previous analysis has been selected for comparison (Chat ID: "${e}").
5
+ When using the compare_with_previous_chat tool, pass chatId="${e}" exactly as shown.
6
+ After completing your analysis of the current request, identify key differences, improvements, or regressions compared to the following reference:
7
+
8
+ `+s+`
9
+
10
+ [End of reference chat]`);return console.log(`[compare_context] Injected compare context (${s.length} chars)`),{messages:[a]}}export{A as execute};
@@ -0,0 +1,8 @@
1
+ import{SystemMessage as y}from"@langchain/core/messages";import{Client as A}from"@elastic/elasticsearch";const E=new A({node:process.env.ELASTICSEARCH_HOST||"https://51.159.174.230:9205",auth:{username:process.env.ELASTICSEARCH_USER||"elastic",password:process.env.ELASTICSEARCH_PASSWORD||"diagnostics"},tls:{rejectUnauthorized:!1}}),C=".stkxp_chats";async function I(o,a,t){try{const e=(await E.get({index:C,id:o}))._source;if(!e||e.username!==a)return null;const d=e.title||"Untitled chat",m=e.messages||[],l=(e.assistants||[]).filter(s=>!t.includes(s.assistantId)),u=new Set(l.map(s=>s.assistantId)),g=l.map(s=>s.assistantName||s.assistantId),h=u.size===0,i=[`Enrichment source: "${d}"`,g.length>0?`New perspectives from: ${g.join(", ")}`:"Additional perspectives:"];for(const s of m){const c=Array.isArray(s.role)?s.role[0]:s.role,r=Array.isArray(s.content)?s.content[0]:s.content,p=Array.isArray(s.assistantId)?s.assistantId[0]:s.assistantId;if(!r||typeof r!="string"||r.startsWith("[React Element")||c!=="agent"&&c!=="assistant"||!h&&!u.has(p))continue;const f=r.length>1200?r.slice(0,1200)+"\u2026":r;i.push(`[${c}] ${f}`)}return i.length<=2?null:i.join(`
2
+
3
+ `)}catch(n){return n?.meta?.statusCode!==404&&console.error(`[enrich_context] Failed to load chat ${o}:`,n?.message),null}}async function _(o,a){process.env.GRAPH_STATE_DEBUG&&console.log("[STATE][ENRICH-CONTEXT]: "+JSON.stringify(o));const{enrichChatId:t}=o;if(!t)return console.log("[enrich_context] No enrichChatId in state \u2014 skipping"),{};console.log(`[enrich_context] Loading enrichment source: ${t}`);const n=await I(t,a.username,a.currentAssistantIds);if(!n)return console.warn(`[enrich_context] Could not load or no useful content in ${t} \u2014 skipping`),{};const e=new y(`[ENRICHMENT CONTEXT]
4
+ Complementary insights from a related analysis using different assistants are provided below. Incorporate these perspectives to enrich your current response where relevant:
5
+
6
+ `+n+`
7
+
8
+ [End of enrichment source]`);return console.log(`[enrich_context] Injected enrichment context (${n.length} chars)`),{messages:[e]}}export{_ as execute};
@@ -0,0 +1,4 @@
1
+ import{SystemMessage as a}from"@langchain/core/messages";import{Client as u}from"@elastic/elasticsearch";const c=new u({node:process.env.ELASTICSEARCH_HOST||"https://51.159.174.230:9205",auth:{username:process.env.ELASTICSEARCH_USER||"elastic",password:process.env.ELASTICSEARCH_PASSWORD||"diagnostics"},tls:{rejectUnauthorized:!1}});async function p(n){try{return(await c.search({index:".stkxp_platforms",body:{query:{bool:{must:[{term:{enabled:!0}},{bool:{should:[{term:{owner:n}},{term:{owner:"stkxp"}}],minimum_should_match:1}}],filter:[{term:{type:"MCPServer"}}]}},size:50,_source:["name","description"]}})).hits.hits.map(e=>({id:e._id,name:e._source?.name||"unknown",description:e._source?.description||""}))}catch{return[]}}async function m(n){try{return(await c.search({index:".stkxp_connectors",body:{query:{bool:{must:[{term:{enabled:!0}},{bool:{should:[{term:{owner:n}},{term:{owner:"stkxp"}}],minimum_should_match:1}}]}},size:50,_source:["name","description","domain"]}})).hits.hits.map(e=>({name:e._source?.name||"unknown",description:e._source?.description||"",domain:e._source?.domain||""}))}catch{return[]}}async function l(n){try{return(await c.search({index:".stkxp_tools",body:{query:{bool:{must:[{term:{enabled:!0}},{bool:{should:[{term:{owner:n}},{term:{owner:"stkxp"}}],minimum_should_match:1}}]}},size:100,_source:["name","label","description","type"]}})).hits.hits.map(e=>({name:e._source?.name||e._source?.label||"unknown",description:e._source?.description||"",type:e._source?.type||"unknown"}))}catch{return[]}}function d(n){if(!n||!/^[A-Za-z0-9+/=_-]{10,}$/.test(n))return n;try{const o=Buffer.from(n,"base64").toString("utf-8");if(/^[a-zA-Z0-9_\-\s]{3,100}$/.test(o))return o}catch{}return n}function g(n,o,e){const s=[`## Available resources on this instance
2
+ `];if(n.length>0){s.push("### Active MCP Servers");for(const t of n)s.push(`- **${t.name}**${t.description?`: ${t.description}`:""}`);s.push("")}if(o.length>0){s.push("### Active Connectors (OpenAPI)");for(const t of o){const r=[t.domain,t.description].filter(Boolean).join(" \u2014 ");s.push(`- **${t.name}**${r?`: ${r}`:""}`)}s.push("")}if(e.length>0){const t={};for(const r of e){const i=d(r.name);t[r.type]||(t[r.type]=[]),t[r.type].length<20&&t[r.type].push(i)}s.push("### Available Tools");for(const[r,i]of Object.entries(t))s.push(`- [${r}] ${i.join(", ")}`);s.push("")}return n.length===0&&o.length===0&&e.length===0&&s.push(`_No resources configured for this user._
3
+ `),s.join(`
4
+ `)}async function y(n,o){process.env.GRAPH_STATE_DEBUG&&console.log("[STATE][INVENTORY-CONTEXT]: "+JSON.stringify(n));const e=o.username||"";if(!e)return console.warn("[inventory_context] No username in context \u2014 skipping"),{};console.log(`[inventory_context] Fetching inventory for user: ${e}`);const[s,t,r]=await Promise.all([p(e),m(e),l(e)]),i=g(s,t,r);return console.log(`[inventory_context] Injected inventory: ${s.length} MCP servers, ${t.length} connectors, ${r.length} tools`),{messages:[new a(i)]}}export{g as buildInventoryMessage,d as decodeToolName,y as execute,m as fetchConnectors,p as fetchMcpServers,l as fetchTools};
@@ -0,0 +1,2 @@
1
+ import{SystemMessage as y}from"@langchain/core/messages";import{getPlatforms as d}from"../../../services/platforms-service";import{KibanaClientFactory as h}from"../../../services/kibana-client-factory";const N={stack_expert:"clusters"},P=t=>N[t]??t,f=new Map,S=6e4;async function E(t,r){if(!t)return{};const a=`${t}::${[...r].sort().join(",")}`,n=f.get(a);if(n&&n.expiresAt>Date.now())return n.map;let s=[];try{s=(await d(t,void 0,"ElasticStack",1,50)).platforms||[]}catch(o){return console.warn(`[namespace_context] getPlatforms(ElasticStack) failed for ${t}: ${o?.message}`),{}}if(s.length===0)return{};const e={};for(const o of s){let i;try{i=h.createFromPlatform(o)}catch(c){console.warn(`[namespace_context] skip ElasticStack platform "${o.name}": ${c?.message}`);continue}let p=[];try{const c=await i.getPackagePolicies();p=c?.items||c?.data?.items||[]}catch(c){console.warn(`[namespace_context] getPackagePolicies failed for "${o.name}": ${c?.message}`);continue}for(const c of p){const l=c?.package?.name,g=c?.namespace;if(!l||!g)continue;const m=P(l);if(r.size>0&&!r.has(m.toLowerCase())&&!r.has(l.toLowerCase()))continue;e[m]||(e[m]=[]),e[m].some(u=>u.namespace===g)||e[m].push({namespace:g,platformId:o.id,platformName:o.name})}}return f.set(a,{expiresAt:Date.now()+S,map:e}),e}function w(t){const r=Object.entries(t);if(r.length===0)return"";const a=["## Available Namespaces per System (from Elastic Fleet)","","When a tool requires a `namespace` argument, use the values below.","Each system is an enrolled Elastic integration; its namespace(s) come from Fleet.","Pick the namespace that best matches the user's intent (prod vs staging, etc.).",""];for(const[n,s]of r)if(s.length===1){const e=s[0];a.push(`- **${n}** \u2192 namespace: \`${e.namespace}\` (${e.platformName})`)}else{a.push(`- **${n}** \u2192 multiple namespaces available:`);for(const e of s)a.push(` - \`${e.namespace}\` \u2014 ${e.platformName}`)}return a.push(""),a.push("Pass the exact namespace string (case-sensitive) as the tool's `namespace` argument."),a.join(`
2
+ `)}async function _(t,r){const a=r.mcpServersPolicy?.servers??[];if(process.env.GRAPH_STATE_DEBUG&&console.log("[STATE][NAMESPACE-CONTEXT]: "+JSON.stringify(t)),a.length===0)return console.warn("[namespace_context] No MCP servers in policy \u2014 skipping"),{};const n=new Set;for(const i of a)i.name&&n.add(String(i.name).toLowerCase()),i.packageName&&n.add(String(i.packageName).toLowerCase());const s=await E(r.username||"",n),e=Object.keys(s).length;if(e===0)return console.warn("[namespace_context] No namespace bindings found"),{namespaceMap:{}};console.log(`[namespace_context] Resolved ${e} system(s) with namespace bindings`),console.log("[namespace_context] map="+JSON.stringify(Object.fromEntries(Object.entries(s).map(([i,p])=>[i,p.map(c=>c.namespace)])))+` | scopedSystems=[${[...n].join(",")}]`);const o=w(s);return{messages:[new y(o)],namespaceMap:s}}export{_ as execute};
@@ -0,0 +1,4 @@
1
+ import{SystemMessage as i}from"@langchain/core/messages";import{Client as l}from"@elastic/elasticsearch";const c=new l({node:process.env.ELASTICSEARCH_HOST||"https://51.159.174.230:9205",auth:{username:process.env.ELASTICSEARCH_USER||"elastic",password:process.env.ELASTICSEARCH_PASSWORD||"diagnostics"},tls:{rejectUnauthorized:!1}}),p=".stkxp_node_types",r=[{condition:"(none / empty)",meaning:"Unconditional edge \u2014 always routes."},{condition:"has_tool_calls",meaning:"assistant_tool_executor produced tool calls \u2192 route to the tool node."},{condition:"no_tool_calls",meaning:"assistant_tool_executor returned a direct answer (no tools left) \u2192 route forward (e.g. to response generator)."},{condition:"tool_success",meaning:"Last tool call succeeded \u2192 typically loop back to the executor."},{condition:"tool_error",meaning:"Last tool call failed \u2192 route to an error/response branch."},{condition:"available",meaning:"Last tool result reports available=true (or domains[0].available=true)."},{condition:"not_available",meaning:"Last tool result reports available=false."},{condition:"namespace_resolved",meaning:"namespace_context resolved at least one namespace \u2192 continue normally."},{condition:"namespace_not_resolved",meaning:"namespace_context resolved none \u2192 route to a human_approval form to ask the user."}];async function u(){try{return(await c.search({index:p,body:{query:{match_all:{}},size:100,sort:[{label:"asc"}]}})).hits.hits.map(e=>e._source)}catch{return[]}}function d(o){if(!o)return"";const e={llm_routing_rule_id:"llm_routing_rule_id",graphId:"graphId",instructions:"instructions",interrupt_type:"interrupt_type",interrupt_message:"interrupt_message",interrupt_payload_fields:"interrupt_payload_fields",always_interrupt:"always_interrupt"},t=Object.entries(o).filter(([,s])=>s===!0).map(([s])=>e[s]||s);return t.length?`
2
+ Settable fields: ${t.join(", ")}`:""}function _(o){const e=["## Available LangGraph node types (live registry)","","Design the runtime using ONLY the `type` values below. Each node MUST have an `id` (snake_case) and a `type` from this list. Set the extra fields listed per type only when relevant.",""];if(o.length===0)e.push("_Node-type registry unavailable \u2014 fall back to the core types: check_reset, system, assistant_tool_executor, tool, assistant_response_generator._");else for(const t of o){const s=d(t.applicableProperties);let a="";if(t.hitlDefaults){const n=t.hitlDefaults;a=`
3
+ HITL defaults: interrupt_type="${n.interrupt_type}", interrupt_message="${n.interrupt_message}", interrupt_payload_fields=${JSON.stringify(n.interrupt_payload_fields??[])}`}e.push(`- \`${t.id}\` \u2014 ${t.label}: ${t.description}${s}${a}`)}e.push(""),e.push("## Valid edge conditions"),e.push(""),e.push("Edges use `from` / `to` (snake_case node ids) and an optional `condition` from this list:");for(const t of r)e.push(`- \`${t.condition}\` \u2014 ${t.meaning}`);return e.push(""),e.push("## Structural rules"),e.push("- Start the flow at `check_reset` for any multi-turn graph."),e.push("- Place context injectors (inventory_context, skills_context, node_types_context, assistants_context, namespace_context) BEFORE the `system` node."),e.push("- If the runtime calls tools, wire the loop: executor --has_tool_calls--> tool, tool --tool_success--> executor, tool --tool_error--> response, executor --no_tool_calls--> response."),e.push("- Every terminal branch must reach `__end__`."),e.push("- For human-in-the-loop, use `human_approval` (interrupt_type is `approval` for a simple approve/reject dialog, or `form` for an advanced scripted form). For a form, provide form_schema; to feed an answer back into state, use form_schema.writeToState."),e.push("- To embed an existing skill as a step, use a `subgraph` node with its real graphId (see the skills list above)."),e.join(`
4
+ `)}async function m(o,e){process.env.GRAPH_STATE_DEBUG&&console.log("[STATE][NODE-TYPES-CONTEXT]: "+JSON.stringify(o));const t=await u();return console.log(`[node_types_context] Injected ${t.length} node types + ${r.length} edge conditions`),{messages:[new i(_(t))]}}export{m as execute};
@@ -0,0 +1,5 @@
1
+ import{SystemMessage as o}from"@langchain/core/messages";import{Client as r}from"@elastic/elasticsearch";const a=new r({node:process.env.ELASTICSEARCH_HOST||"https://51.159.174.230:9205",auth:{username:process.env.ELASTICSEARCH_USER||"elastic",password:process.env.ELASTICSEARCH_PASSWORD||"diagnostics"},tls:{rejectUnauthorized:!1}}),c=14,l=/^[A-Za-z0-9+/=]{20,}$/;function u(s){const t=s?.messages??[];for(let e=t.length-1;e>=0;e--){const n=t[e];if((n?._getType?.()??n?.role)==="human")return typeof n.content=="string"?n.content:n.content?.[0]?.text??""}return""}function m(s){return s.split("|").map(t=>t.trim()).filter(t=>t.length>0&&!l.test(t))}function g(s){const t=m(s);return t.length===0?null:`topic:${t[0]}`}async function p(s,t){try{const e=[{bool:{should:[{term:{owner:t}},{term:{owner:"stkxp"}}],minimum_should_match:1}}];return s&&e.push({multi_match:{query:s,fields:["name^3","context.role^2","topic^2","description^2","tags","behavior.task_brief"],type:"best_fields",fuzziness:"AUTO"}}),(await a.search({index:".stkxp_assistants",body:{query:{bool:{must:e,must_not:[{term:{tags:"internal"}}]}},size:c,sort:s?["_score"]:[{"topic.keyword":{order:"asc",missing:"_last"}}],_source:["name","topic","description","tags","context.role"]}})).hits.hits.map(i=>({id:i._id,name:i._source?.name||"unknown",topic:i._source?.topic||"",role:i._source?.context?.role||"",score:i._score||0}))}catch{return[]}}function d(s){if(s.length===0)return`## Relevant assistants for this use case
2
+
3
+ _No assistant matched. Output assistants: []._
4
+ `;const t=["## Relevant assistants for this use case (ranked by relevance)","","Format: `id` | name | role | condition_hint","Pick the assistants whose role/topic actually fit the use case (you don't have to use all of them). Use the EXACT id in backticks. Derive condition from condition_hint; if it is 'runAlways:true', set condition:null and runAlways:true.",""];for(const e of s){const n=g(e.topic)||"runAlways:true",i=e.role?` | ${e.role.slice(0,90)}`:"";t.push(`- \`${e.id}\` | ${e.name}${i} | ${n}`)}return t.join(`
5
+ `)}async function h(s,t){process.env.GRAPH_STATE_DEBUG&&console.log("[STATE][RELEVANT-ASSISTANTS-CONTEXT]: "+JSON.stringify(s));const e=t.username||"";if(!e)return console.warn("[relevant_assistants_context] No username in context \u2014 skipping"),{};const n=u(s).slice(0,500).trim(),i=await p(n,e);return console.log(`[relevant_assistants_context] query="${n.slice(0,60)}\u2026" \u2192 ${i.length} assistants`),{messages:[new o(d(i))]}}export{h as execute};
@@ -0,0 +1,5 @@
1
+ import{SystemMessage as p}from"@langchain/core/messages";import{Client as d}from"@elastic/elasticsearch";import{decodeToolName as u}from"./inventory-context";const l=new d({node:process.env.ELASTICSEARCH_HOST||"https://51.159.174.230:9205",auth:{username:process.env.ELASTICSEARCH_USER||"elastic",password:process.env.ELASTICSEARCH_PASSWORD||"diagnostics"},tls:{rejectUnauthorized:!1}}),g=8,y=30;function f(o){const a=o?.messages??[];for(let n=a.length-1;n>=0;n--){const t=a[n];if((t?._getType?.()??t?.role)==="human")return typeof t.content=="string"?t.content:t.content?.[0]?.text??""}return""}function m(o){return{bool:{should:[{term:{owner:o}},{term:{owner:"stkxp"}}],minimum_should_match:1}}}async function h(o,a){try{const n=[{term:{status:"active"}},m(a)];return o&&n.push({multi_match:{query:o,fields:["name^3","description^2","tags^2"],type:"best_fields",fuzziness:"AUTO"}}),(await l.search({index:".stkxp_graphs",body:{query:{bool:{must:n,must_not:[{term:{tags:"internal"}}]}},size:g,sort:o?["_score"]:[{updatedAt:{order:"desc"}}],_source:["id","name","description","nodes","tags"]}})).hits.hits.map(s=>{const e=s._source||{},r=[...new Set((e.nodes||[]).map(i=>i.type).filter(Boolean))];return{id:e.id||s._id,name:e.name||"unknown",description:e.description||"",nodeTypes:r,score:s._score||0}})}catch{return[]}}async function _(o,a){try{const n=[{term:{enabled:!0}},m(a)];return o&&n.push({multi_match:{query:o,fields:["name^2","label^2","description^2","tags","system","namespace"],type:"best_fields",fuzziness:"AUTO"}}),(await l.search({index:".stkxp_tools",body:{query:{bool:{must:n}},size:y,sort:o?["_score"]:[{_doc:{order:"asc"}}],_source:["name","label","description","mcpServerId","mcpServerName","platformId","system"]}})).hits.hits.map(s=>{const e=s._source||{};return{name:u(e.name||e.label||"unknown"),description:(e.description||"").slice(0,100),mcpServerId:e.mcpServerId,mcpServerName:e.mcpServerName,platformId:e.platformId,system:e.system}})}catch{return[]}}async function v(o,a){const n=[...new Set(o.filter(Boolean))];if(n.length===0)return{};try{const t=await l.search({index:".stkxp_platforms",body:{query:{bool:{must:[{terms:{"name.keyword":n}},{bool:{should:[{term:{owner:a}},{term:{owner:"stkxp"}}],minimum_should_match:1}}]}},size:n.length*4,_source:["name","type","owner"]}}),s={};for(const r of t.hits.hits){const i=r._source?.name;if(!i)continue;const c=r._source?.owner||"";(!s[i]||c===a&&s[i].owner!==a)&&(s[i]={id:r._id,type:r._source?.type||"",owner:c})}const e={};for(const[r,i]of Object.entries(s))e[r]={id:i.id,type:i.type};return e}catch{return{}}}function S(o,a,n){const t=[`## Most relevant skills for this use case (ranked by relevance)
2
+ `];if(o.length>0)for(const s of o){const e=s.nodeTypes.length?`
3
+ Node types: ${s.nodeTypes.join(", ")}`:"";t.push(`- **${s.name}** (id: \`${s.id}\`)${s.description?`: ${s.description}`:""}${e}`)}else t.push("_No matching skill found. Omit graphId from the generated profile._");if(t.push(""),t.push("## Most relevant servers & their tools for this use case (ranked by relevance)"),t.push(`Reference these in mcp_servers_policy.servers using the EXACT id and name below.
4
+ `),a.length>0){const s=new Map;for(const e of a){const r=e.system||e.mcpServerName;if(!r)continue;const i=n[r];if(!i)continue;s.has(r)||s.set(r,{id:i.id,name:r,type:i.type,tools:[]});const c=s.get(r);c.tools.length<20&&!c.tools.includes(e.name)&&c.tools.push(e.name)}s.size===0&&t.push("_No matching tools belong to a referenceable server. Output mcp_servers_policy.servers as []._");for(const e of s.values()){const r=e.type?` [${e.type}]`:"";t.push(`### ${e.name}${r} (id: \`${e.id}\`)`),t.push(` Tools (${e.tools.length}): ${e.tools.join(", ")}`)}}else t.push("_No matching tools found. Output mcp_servers_policy.servers as []._");return t.push(""),t.join(`
5
+ `)}async function b(o,a){process.env.GRAPH_STATE_DEBUG&&console.log("[STATE][RELEVANT-SKILLS-CONTEXT]: "+JSON.stringify(o));const n=a.username||"";if(!n)return console.warn("[relevant_skills_context] No username in context \u2014 skipping"),{};const t=f(o).slice(0,500).trim(),[s,e]=await Promise.all([h(t,n),_(t,n)]),r=await v(e.map(i=>i.system||i.mcpServerName||""),n);return console.log(`[relevant_skills_context] query="${t.slice(0,60)}\u2026" \u2192 ${s.length} skills, ${e.length} tools across ${Object.keys(r).length} servers`),{messages:[new p(S(s,e,r))]}}export{b as execute};
@@ -0,0 +1,8 @@
1
+ import{SystemMessage as m}from"@langchain/core/messages";import{Client as g}from"@elastic/elasticsearch";import{fetchConnectors as h,fetchTools as y,decodeToolName as p}from"./inventory-context";const l=new g({node:process.env.ELASTICSEARCH_HOST||"https://51.159.174.230:9205",auth:{username:process.env.ELASTICSEARCH_USER||"elastic",password:process.env.ELASTICSEARCH_PASSWORD||"diagnostics"},tls:{rejectUnauthorized:!1}});async function f(r){try{return(await l.search({index:".stkxp_graphs",body:{query:{bool:{must:[{term:{status:"active"}},{bool:{should:[{term:{owner:r}},{term:{owner:"stkxp"}}],minimum_should_match:1}}],must_not:[{term:{tags:"internal"}}]}},size:30,sort:[{updatedAt:{order:"desc"}}],_source:["id","name","description","nodes","tags"]}})).hits.hits.map(i=>{const n=i._source||{},e=(n.nodes||[]).map(s=>s.type).filter(Boolean);return{id:n.id||i._id,name:n.name||"unknown",description:n.description||"",nodeTypes:[...new Set(e)]}})}catch{return[]}}async function S(r,o){if(!o?.url)return[];try{const{createMcpClient:i}=await import("../../../mcp/client"),n=o.headers||{},e=Object.keys(n).some(a=>a.toLowerCase()==="authorization"),s={...o.authKey&&!e?{authorization:`ApiKey ${o.authKey}`}:{},...n},t=await i(o.url,{headers:s,transportType:o.protocol||"http",timeout:6e3});try{return((await t.client.listTools()).tools||[]).map(c=>({name:p(c.name||""),description:(c.description||"").slice(0,120)}))}finally{await t.close()}}catch{return[]}}async function _(r){let o=[];try{o=(await l.search({index:".stkxp_platforms",body:{query:{bool:{must:[{term:{enabled:!0}},{term:{type:"MCPServer"}},{bool:{should:[{term:{owner:r}},{term:{owner:"stkxp"}}],minimum_should_match:1}}]}},size:50,_source:["name","description","config"]}})).hits.hits.map(e=>({id:e._id,name:e._source?.name||"unknown",description:e._source?.description||"",config:e._source?.config||{}}))}catch{return[]}return o.length===0?[]:await Promise.all(o.map(async n=>{let e=[];try{e=(await l.search({index:".stkxp_tools",body:{query:{term:{mcpServerId:n.id}},size:200,_source:["name","label","description"]}})).hits.hits.map(t=>({name:p(t._source?.name||t._source?.label||"unknown"),description:(t._source?.description||"").slice(0,120)}))}catch{}return e.length===0&&(e=await S(n.id,n.config)),{id:n.id,name:n.name,description:n.description,tools:e}}))}function T(r,o,i,n){const e=[`## Available Skills (Graphs)
2
+ `];if(r.length>0)for(const s of r){const t=s.nodeTypes.length>0?`
3
+ Node types: ${s.nodeTypes.join(", ")}`:"";e.push(`- **${s.name}** (id: \`${s.id}\`)${s.description?`: ${s.description}`:""}${t}`)}else e.push("_No active skills found. Omit graphId from the generated assistant._");if(e.push(""),e.push(`## Available Resources on this instance
4
+ `),o.length>0){e.push("### Active MCP Servers");for(const s of o){const t=s.tools.length>0?`
5
+ Tools (${s.tools.length}): ${s.tools.map(a=>a.name).slice(0,30).join(", ")}`:`
6
+ Tools: (not yet indexed \u2014 tools will be available after sync)`;e.push(`- **${s.name}** (id: \`${s.id}\`)${s.description?`: ${s.description}`:""}${t}`)}e.push("")}if(i.length>0){e.push("### Active Connectors (OpenAPI)");for(const s of i){const t=[s.domain,s.description].filter(Boolean).join(" \u2014 ");e.push(`- **${s.name}**${t?`: ${t}`:""}`)}e.push("")}if(n.length>0){const s={};for(const t of n)s[t.type]||(s[t.type]=[]),s[t.type].length<20&&s[t.type].push(t.name);e.push("### Additional Available Tools");for(const[t,a]of Object.entries(s))e.push(`- [${t}] ${a.join(", ")}`);e.push("")}return o.length===0&&i.length===0&&n.length===0&&e.push(`_No resources configured for this user._
7
+ `),e.join(`
8
+ `)}async function v(r,o){const i=o.username||"";if(process.env.GRAPH_STATE_DEBUG&&console.log("[STATE][SKILLS-CONTEXT]: "+JSON.stringify(r)),!i)return console.warn("[skills_context] No username in context \u2014 skipping"),{};console.log(`[skills_context] Fetching context for user: ${i}`);const[n,e,s,t]=await Promise.all([f(i),_(i),h(i),y(i)]),a=e.reduce((u,d)=>u+d.tools.length,0),c=T(n,e,s,t);return console.log(`[skills_context] Injected: ${n.length} skills, ${e.length} MCP servers (${a} tools), ${s.length} connectors, ${t.length} standalone tools`),{messages:[new m(c)]}}export{v as execute};
@@ -0,0 +1 @@
1
+ import m from"jsonata";import{lastToolMessageContent as E,lastAIMessageContent as w,coerceToJson as d}from"../../utils/tool-result";const $=new Set(["compareChatId","enrichChatId","context","variables","toolArgs","selectedTeamId"]),g=new Set(["messages","threadId","teamAssistantResults","toolExecRounds","toolsUsedAccum","last_tool_error","entityTokenMap","namespaceMap","toolResults","customFields"]);async function j(i,f){process.env.GRAPH_STATE_DEBUG&&console.log("[STATE][STATE-SETTER]: "+JSON.stringify(i));const{nodeDef:o}=f,n=o?.id||"state_setter",t=typeof o?.stateField=="string"?o.stateField.trim():"";if(!t||g.has(t))return console.warn(`[state_setter] ${n}: stateField "${t}" missing or reserved (${[...g].join(", ")}) \u2014 writing nothing`),{};const s=typeof o?.jsonata=="string"?o.jsonata.trim():"";if(!s)return console.warn(`[state_setter] ${n}: no jsonata expression set \u2014 writing nothing`),{};const l=m(s);let e;const c=i?.toolResults;if(c&&typeof c=="object"&&Object.keys(c).length>0)try{e=await l.evaluate(c)}catch(a){console.warn(`[state_setter] ${n}: jsonata eval error against toolResults for "${s}": ${a?.message}`)}if(e==null||e===""){const a=E(i?.messages),r=d(a);if(r!==void 0)try{e=await l.evaluate(r)}catch(u){return console.warn(`[state_setter] ${n}: jsonata eval error for "${s}": ${u?.message} \u2014 writing nothing`),{}}}if(e==null||e===""){const a=w(i?.messages),r=d(a);if(r!==void 0)try{e=await l.evaluate(r)}catch(u){return console.warn(`[state_setter] ${n}: jsonata eval error against last AIMessage for "${s}": ${u?.message} \u2014 writing nothing`),{}}}if(e==null||e==="")try{e=await l.evaluate({})}catch{}return e==null||e===""?(console.warn(`[state_setter] ${n}: jsonata "${s}" produced no value \u2014 writing nothing to "${t}"`),{}):(console.log(`[state_setter] ${n}: set "${t}" via jsonata "${s}"`),$.has(t)?{[t]:e}:{customFields:{[t]:e}})}export{j as execute};
@@ -0,0 +1 @@
1
+ async function d(e,r){process.env.GRAPH_STATE_DEBUG&&console.log("[STATE][CHECK-RESET]: "+JSON.stringify(e));const s=r.threadId;return e.threadId&&e.threadId!==s?{messages:[e.messages[e.messages.length-1]],threadId:s}:{threadId:s}}export{d as execute};
@@ -0,0 +1 @@
1
+ import{contentToString as T}from"../../utils/content-utils";import{getNodeInstructions as m}from"../../utils/message-utils";import{generateTopicHybrid as y,resolveTopicByRegExp as D,extractKeywordsAndLanguage as w}from"../../topic-variants";async function x(i,a){process.env.GRAPH_STATE_DEBUG&&console.log("[STATE][TOPIC-DETECTION]: "+JSON.stringify(i));const{llmConfig:r,graphDef:l,topicName:o,assistant:p,nodeDef:d}=a,f=i.messages[i.messages.length-1],t=T(f).trim();console.log("**************************topic_detection: userText",t);const u=d?.forceDetect===!0;let e,s,c;if(u){const n=await w(t,r);return s=n.keywords,c=n.language,e=o&&o!=="unknown"?o:t,console.log(`[Topic Detection] forceDetect: keywords=${JSON.stringify(s)} language=${c} topic=${e}`),{topic:e,keywords:s,language:c}}if(t.startsWith("topic="))e=t.slice(6).trim(),console.log(`[Topic Detection] Manual override: ${e}`);else if(o&&o!=="unknown")e=o,console.log(`[Topic Detection] Bypassed \u2014 assistant topic: ${e}`);else{const n=D(t);if(n)e=n,console.log(`[Topic Detection] Dynamic registry match: ${e}`);else{const g=await m(l,"topic_detection",void 0,p);console.log(`[Topic Detection] Using instructions (${g.length} chars)`),e=await y(t,r,g),console.log(`[Topic Detection] Auto-detected: ${e}`)}}return{topic:e}}export{x as execute};