@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,2 @@
1
+ import A from"https";import k from"http";import{HttpsClient as $}from"../utils/http-client";import{createAuthHeader as E}from"../utils/string-helpers";class q{httpsClient;hostname;port;basePath;credentials;apiKey;platformId;platformName;constructor(e){this.hostname=e.hostname,this.port=e.port,this.basePath=e.basePath,this.credentials=e.credentials,this.apiKey=e.apiKey,this.platformId=e.platformId,this.platformName=e.platformName,this.httpsClient=new $(e.certificates,e.timeout||3e4,e.rejectUnauthorized??!0)}getPlatformId(){return this.platformId}getPlatformName(){return this.platformName}getAuthHeader(){if(this.apiKey)return`ApiKey ${this.apiKey}`;if(this.credentials)return E(this.credentials.username,this.credentials.password);throw new Error("KibanaClient: no credentials or apiKey configured")}async checkPolicy(e){const n={hostname:this.hostname,port:this.port,path:`${this.basePath}/api/fleet/package_policies/${e}`,method:"GET",headers:{Authorization:this.getAuthHeader(),"kbn-xsrf":"reporting","Content-Type":"application/json"}};return await this.httpsClient.request(n)}async createPolicy(e){console.log("kibana Creating policy:",JSON.stringify(e,null,2));const n=JSON.stringify(e),t={hostname:this.hostname,port:this.port,path:`${this.basePath}/api/fleet/package_policies`,method:"POST",headers:{Authorization:this.getAuthHeader(),"kbn-xsrf":"reporting","Content-Type":"application/json","Content-Length":Buffer.byteLength(n).toString()},timeout:6e4};return await this.httpsClient.request(t,n)}async updatePolicy(e,n){console.log(`[KibanaClient] Updating policy ${e}:`,JSON.stringify(n,null,2));const t=JSON.stringify(n),a={hostname:this.hostname,port:this.port,path:`${this.basePath}/api/fleet/package_policies/${e}`,method:"PUT",headers:{Authorization:this.getAuthHeader(),"kbn-xsrf":"reporting","Content-Type":"application/json","Content-Length":Buffer.byteLength(t).toString()},timeout:6e4};console.log(`[KibanaClient] PUT request to: ${a.path}`);const r=await this.httpsClient.request(a,t);return console.log("[KibanaClient] Update result:",JSON.stringify(r,null,2)),r}async getEpmPackages(e=!1){const n={hostname:this.hostname,port:this.port,path:`${this.basePath}/api/fleet/epm/packages?prerelease=${e}`,method:"GET",headers:{Authorization:this.getAuthHeader(),"kbn-xsrf":"reporting","Content-Type":"application/json"},timeout:3e4};console.log("KibanaClient getEpmPackages options:",n);const t=await this.httpsClient.request(n);return console.log("KibanaClient getEpmPackages result:",JSON.stringify(t,null,2)),t}async getEpmPackage(e,n){const t={hostname:this.hostname,port:this.port,path:`${this.basePath}/api/fleet/epm/packages/${e}/${n}`,method:"GET",headers:{Authorization:this.getAuthHeader(),"kbn-xsrf":"reporting","Content-Type":"application/json"}};return console.log("KibanaClient getEpmPackage options:",t),await this.httpsClient.request(t)}async installEpmPackage(e,n){const t=JSON.stringify({force:!0}),a={hostname:this.hostname,port:this.port,path:`${this.basePath}/api/fleet/epm/packages/${e}/${n}`,method:"POST",headers:{Authorization:this.getAuthHeader(),"kbn-xsrf":"reporting","Content-Type":"application/json","Content-Length":Buffer.byteLength(t)},timeout:12e4};return console.log("KibanaClient installEpmPackage options:",a),await this.httpsClient.request(a,t)}async getPackagePolicies(e){let t=1;const a=[];for(;;){const r=new URLSearchParams({perPage:String(100),page:String(t)});e&&r.set("kuery",e);const g=`${this.basePath}/api/fleet/package_policies?${r.toString()}`,p={hostname:this.hostname,port:this.port,path:g,method:"GET",timeout:1e4,headers:{Authorization:this.getAuthHeader(),"kbn-xsrf":"reporting","Content-Type":"application/json"}},s=await this.httpsClient.request(p);if(s?.error){if(t===1)return s;break}const i=s?.data?.items||s?.items||[],h=s?.data?.total??s?.total??i.length;if(a.push(...i),console.log(`[KibanaClient] getPackagePolicies page=${t}: ${i.length} items, total=${h}, collected=${a.length}`),a.length>=h||i.length<100)break;t++}return{statusCode:200,data:{items:a,total:a.length}}}async getPackagePolicy(e){const n={hostname:this.hostname,port:this.port,path:`${this.basePath}/api/fleet/package_policies/${e}`,method:"GET",headers:{Authorization:this.getAuthHeader(),"kbn-xsrf":"reporting","Content-Type":"application/json"}};console.log("[KibanaClient] getPackagePolicy request:",{url:`https://${n.hostname}:${n.port}${n.path}`,method:n.method,policyId:e});try{const t=await this.httpsClient.request(n);return t&&t.data&&t.data.item?console.log("[KibanaClient] getPackagePolicy success:",{policyId:e,policyName:t.data.item.name,packageName:t.data.item.package?.name}):t&&t.error?console.error("[KibanaClient] getPackagePolicy error:",{policyId:e,statusCode:t.statusCode,error:t.error}):console.warn("[KibanaClient] getPackagePolicy no data:",{policyId:e}),t}catch(t){throw console.error("[KibanaClient] getPackagePolicy exception:",{policyId:e,error:t.message||t,stack:t.stack}),t}}async getPackageByVersion(e,n){const t=`${this.basePath}/api/fleet/epm/packages/${encodeURIComponent(e)}/${encodeURIComponent(n)}`,a={hostname:this.hostname,port:this.port,path:t,method:"GET",headers:{Authorization:this.getAuthHeader(),"kbn-xsrf":"reporting","Content-Type":"application/json"}};return this.httpsClient.request(a)}async deletePackagePolicy(e){const n={hostname:this.hostname,port:this.port,path:`${this.basePath}/api/fleet/package_policies/${e}`,method:"DELETE",headers:{Authorization:this.getAuthHeader(),"kbn-xsrf":"reporting","Content-Type":"application/json"}};return console.log("KibanaClient deletePackagePolicy options:",n),await this.httpsClient.request(n)}async getAgentPolicies(e){let t=1;const a=[];for(;;){const r=new URLSearchParams({perPage:String(100),page:String(t)});e&&r.set("kuery",e);const g=`${this.basePath}/api/fleet/agent_policies?${r.toString()}`,p={hostname:this.hostname,port:this.port,path:g,method:"GET",headers:{Authorization:this.getAuthHeader(),"kbn-xsrf":"reporting","Content-Type":"application/json"}},s=await this.httpsClient.request(p);if(s?.error){if(t===1)return s;break}const i=s?.data?.items||s?.items||[],h=s?.data?.total??s?.total??i.length;if(a.push(...i),console.log(`[KibanaClient] getAgentPolicies page=${t}: ${i.length} items, total=${h}, collected=${a.length}`),a.length>=h||i.length<100)break;t++}return{statusCode:200,data:{items:a,total:a.length}}}async getFleetServerHosts(){const e={hostname:this.hostname,port:this.port,path:`${this.basePath}/api/fleet/fleet_server_hosts`,method:"GET",headers:{Authorization:this.getAuthHeader(),"kbn-xsrf":"reporting","Content-Type":"application/json"}};return await this.httpsClient.request(e)}async getFleetAgents(e){const n=e?`${this.basePath}/api/fleet/agents?kuery=${encodeURIComponent(e)}`:`${this.basePath}/api/fleet/agents`,t={hostname:this.hostname,port:this.port,path:n,method:"GET",headers:{Authorization:this.getAuthHeader(),"kbn-xsrf":"reporting","Content-Type":"application/json"}};return await this.httpsClient.request(t)}async getVersion(){const e={hostname:this.hostname,port:this.port,path:`${this.basePath}/api/status`,method:"GET",headers:{Authorization:this.getAuthHeader(),"kbn-xsrf":"reporting","Content-Type":"application/json"}};return await this.httpsClient.request(e)}async getEnrollmentApiKeys(e){const n=new URLSearchParams({page:"1",perPage:"2000",kuery:"not hidden:true"});e&&n.set("kuery",`(not hidden:true) and (policy_id:"${e}")`);const t={hostname:this.hostname,port:this.port,path:`${this.basePath}/api/fleet/enrollment_api_keys?${n.toString()}`,method:"GET",headers:{Authorization:this.getAuthHeader(),"kbn-xsrf":"reporting","Content-Type":"application/json"}};return await this.httpsClient.request(t)}async createAgentPolicy(e,n){const t=JSON.stringify({name:e,description:n||"",namespace:"default",monitoring_enabled:["logs","metrics"]}),a={hostname:this.hostname,port:this.port,path:`${this.basePath}/api/fleet/agent_policies`,method:"POST",headers:{Authorization:this.getAuthHeader(),"kbn-xsrf":"reporting","Content-Type":"application/json","Content-Length":Buffer.byteLength(t)}};return await this.httpsClient.request(a,t)}async bulkInstallEpmPackages(e){const n=JSON.stringify({force:!1,packages:e}),t={hostname:this.hostname,port:this.port,path:`${this.basePath}/api/fleet/epm/packages/_bulk`,method:"POST",headers:{Authorization:this.getAuthHeader(),"kbn-xsrf":"reporting","Content-Type":"application/json","Content-Length":Buffer.byteLength(n)},timeout:3e5};return console.log("KibanaClient bulkInstallEpmPackages options:",t),console.log("KibanaClient bulkInstallEpmPackages packages:",e),await this.httpsClient.request(t,n)}async getAgentBuilderAgents(){const e={hostname:this.hostname,port:this.port,path:`${this.basePath}/api/agent_builder/agents`,method:"GET",headers:{Authorization:this.getAuthHeader(),"kbn-xsrf":"reporting","Content-Type":"application/json"}},n=await this.httpsClient.request(e);if(n.statusCode!==200)throw new Error(`getAgentBuilderAgents failed: HTTP ${n.statusCode}`);const t=n.data;return Array.isArray(t)?t:Array.isArray(t?.results)?t.results:Array.isArray(t?.agents)?t.agents:Array.isArray(t?.agents?.results)?t.agents.results:[]}async getAgentBuilderAgentDetail(e){const n={hostname:this.hostname,port:this.port,path:`${this.basePath}/api/agent_builder/a2a/${encodeURIComponent(e)}.json`,method:"GET",headers:{Authorization:this.getAuthHeader(),"kbn-xsrf":"reporting","Content-Type":"application/json"}},t=await this.httpsClient.request(n);if(t.statusCode!==200)throw new Error(`getAgentBuilderAgentDetail failed: HTTP ${t.statusCode}`);return t.data}async*converseAsync(e,n){const t=JSON.stringify(e),a=this.getAuthHeader(),r={hostname:this.hostname,port:this.port,path:`${this.basePath}/api/agent_builder/converse/async`,method:"POST",headers:{Authorization:a,"kbn-xsrf":"reporting","Content-Type":"application/json",Accept:"text/event-stream","Cache-Control":"no-cache","Content-Length":Buffer.byteLength(t)},rejectUnauthorized:!1},g=this.port===80?k:A,p=[];let s=null,i=!1,h=null;const d=g.request(r,o=>{if(o.statusCode&&o.statusCode!==200){let l="";o.setEncoding("utf8"),o.on("data",f=>{l+=f}),o.on("end",()=>{h=new Error(`Kibana converseAsync HTTP ${o.statusCode}: ${l.slice(0,300)}`),i=!0,s&&(s(),s=null)});return}let y="",c="",u="";o.setEncoding("utf8"),o.on("data",l=>{y+=l;const f=y.split(`
2
+ `);y=f.pop()??"";for(const b of f){const m=b.trimEnd();if(m===""){if(c&&u)try{const P=JSON.parse(u),C={event:c,data:P?.data??P};p.push(C),s&&(s(),s=null)}catch{console.warn(`[KibanaSSE] Failed to parse data for event '${c}':`,u.slice(0,100))}c="",u=""}else m.startsWith("event:")?c=m.slice(6).trim():m.startsWith("data:")&&(u=m.slice(5).trim())}}),o.on("end",()=>{i=!0,s&&(s(),s=null)}),o.on("error",l=>{h=l,i=!0,s&&(s(),s=null)})});for(d.on("error",o=>{h=o,i=!0,s&&(s(),s=null)}),n&&n.addEventListener("abort",()=>{d.destroy(),i=!0,s&&(s(),s=null)}),d.write(t),d.end();!i||p.length>0;)p.length>0?yield p.shift():i||await new Promise(o=>{s=o});if(h)throw h}}export{q as KibanaClient};
@@ -0,0 +1 @@
1
+ import M from"crypto";const et=new Set(["terms","date_histogram","auto_date_histogram","histogram","filters","range","date_range"]),L=new Set(["cardinality","value_count","sum","avg","min","max"]);function q(e){if(e==null)return{};if(typeof e=="object")return e;try{return JSON.parse(e)}catch{return{}}}function P(e){return String(e).replace(/[^\w\s-]/g,"").replace(/\s+/g,"_").toLowerCase()}function F(e){return String(e).replace(/^@/,"").replace(/\./g,"_").replace(/[^\w]+/g,"_").replace(/_+/g,"_").replace(/^_+|_+$/g,"").toLowerCase()}function x(e){return Object.keys(e).filter(t=>t!=="aggs")[0]??null}function z(e,n,t){const r=x(n);if(!r)return`agg_${e.substring(0,8)}`;const o=n[r],s=["agg",r];if(o?.field&&s.push(F(o.field)),r==="terms"&&o?.order)for(const[i,c]of Object.entries(o.order)){const l=t[i];if(l){const g=x(l),u=l[g??""]?.field;u&&s.push("order",F(u),c)}else(i==="_count"||i==="_key")&&s.push("order",i.replace("_",""),c)}return s.join("_")}function Q(e,n){const t=x(e);if(!t)return e;const r={...e[t]};if(r.order){const o={};for(const[s,i]of Object.entries(r.order)){const c=s==="___records___"?"_count":n.get(s)??s;o[c]=i}r.order=o}return{[t]:r}}function C(e,n={}){if(!e||Object.keys(e).length===0)return e;const t=new Map;for(const[o,s]of Object.entries(e))t.set(o,z(o,s,e));const r={};for(const[o,s]of Object.entries(e)){const i=t.get(o),c=Q(s,t),l=x(c),g=c[l];r[i]={[l]:g},s.aggs&&Object.keys(s.aggs).length>0&&(r[i].aggs=C(s.aggs,n))}return r}function E(e){const{operationType:n,sourceField:t,params:r={}}=e;switch(n){case"terms":return{terms:{field:t,size:r.size||10}};case"date_histogram":return r.interval==="auto"?{auto_date_histogram:{field:t,buckets:10}}:{date_histogram:{field:t,calendar_interval:r.interval||"1h",min_doc_count:r.includeEmptyRows?0:1}};case"histogram":return{histogram:{field:t,interval:r.interval||1}};case"cardinality":return{cardinality:{field:t}};case"unique_count":return{cardinality:{field:t}};case"count":return{value_count:{field:t==="___records___"?"_index":t||"_index"}};case"sum":case"avg":case"min":case"max":return{[n]:{field:t}};default:return null}}function H(e){const n=e.columns||{},t=e.columnOrder||[],r=[],o=[];for(const l of t){const g=n[l];g&&(g.isBucketed?r:o).push({columnId:l,column:g})}const s={};for(const{columnId:l,column:g}of r){const u=E(g);u&&(s[l]=u)}const i={};for(const{columnId:l,column:g}of o){const u=E(g);u&&(i[l]=u)}const c={};if(Object.keys(s).length>0)for(const l of r.map(g=>g.columnId))s[l]&&(c[l]=s[l],Object.keys(i).length>0&&(c[l].aggs={...i}));else Object.assign(c,i);return C(c,n)}function U(e){if(!e?.panelsJSON)return[];const n=q(e.panelsJSON),t=[];for(const[r,o]of Object.entries(n)){const s={panelId:r,type:o.type??null,order:o.order??null,grow:o.grow??null,width:o.width??null};if(o.explicitInput){const i=o.explicitInput;s.explicitInput={dataViewId:i.dataViewId??null,fieldName:i.fieldName??null,id:i.id??r,title:i.title??null,sort:i.sort??null,selectedOptions:i.selectedOptions??null}}t.push(s)}return t}function k(e){const n=[];for(const t of e)t.meta?.disabled||t.query&&(t.meta?.negate?n.push({bool:{must_not:[t.query]}}):n.push(t.query));return n}function R(e,n){const t=[],r=[...e];for(const o of n){const s=typeof o=="string"?o.trim():"";s&&s!=="*"&&t.push({query_string:{query:s,default_operator:"AND"}})}return t.length===0&&r.length===0?{match_all:{}}:{bool:{must:t,filter:r}}}function I(e,n){if(!(!e||typeof e!="object")){if(e.term&&typeof e.term=="object")for(const t of Object.keys(e.term))n.add(t);if(e.terms&&typeof e.terms=="object")for(const t of Object.keys(e.terms))t!=="boost"&&n.add(t);for(const t of["match_phrase","match"])if(e[t]&&typeof e[t]=="object")for(const r of Object.keys(e[t]))n.add(r);if(e.bool&&typeof e.bool=="object")for(const t of["must","should","filter","must_not"]){const r=e.bool[t];if(Array.isArray(r))for(const o of r)I(o,n);else r&&I(r,n)}}}function $(e,n){for(const t of Object.values(e)){if(!t||typeof t!="object")continue;if(x(t)==="terms"){const o=t.terms?.field;o&&n.add(o)}t.filter&&typeof t.filter=="object"&&I(t.filter,n),t.aggs&&typeof t.aggs=="object"&&$(t.aggs,n)}}const W=new Set(["@timestamp","data_stream.type","data_stream.dataset","data_stream.namespace","event.dataset","event.module"]);function N(e,n,t=!0){const r={},o=[];t&&(r.timeRange={type:"object",description:"Time range for the query",properties:{from:{type:"string",description:"Start time (e.g. now-2h or ISO date)"},to:{type:"string",description:"End time (e.g. now or ISO date)"}},required:["from","to"]},o.push("timeRange"));for(const i of e){const c=i.explicitInput;c?.fieldName&&(r[c.fieldName]={type:"string",description:c.title?`Filter by ${c.title}`:`Filter by ${c.fieldName}`})}const s=new Set;$(n,s);for(const i of s)i in r||W.has(i)||(r[i]={type:"string",description:`Optional filter on ${i}`});return{type:"object",properties:r,...o.length?{required:o}:{}}}function J(e){const n=x(e);if(!n)return{type:"object"};const t=e.aggs?G(e.aggs):{};return L.has(n)?{type:"object",properties:{value:{type:"number"}}}:n==="date_histogram"||n==="auto_date_histogram"?{type:"object",properties:{buckets:{type:"array",items:{type:"object",properties:{key_as_string:{type:"string"},key:{type:"number"},doc_count:{type:"integer"},...t}}}}}:n==="terms"?{type:"object",properties:{buckets:{type:"array",items:{type:"object",properties:{key:{type:e[n]?.field?.includes("@timestamp")?"number":"string"},doc_count:{type:"integer"},...t}}}}}:n==="histogram"?{type:"object",properties:{buckets:{type:"array",items:{type:"object",properties:{key:{type:"number"},doc_count:{type:"integer"},...t}}}}}:{type:"object",properties:{buckets:{type:"array",items:{type:"object",additionalProperties:!0}}}}}function G(e){const n={};for(const[t,r]of Object.entries(e))n[t]=J(r);return n}function T(e){if(!e||Object.keys(e).length===0)return{type:"object",properties:{hits:{type:"object",properties:{total:{type:"object"},hits:{type:"array"}}},aggregations:{type:"object",additionalProperties:!0}}};const n={};for(const[t,r]of Object.entries(e))n[t]=J(r);return{type:"object",properties:{took:{type:"number"},hits:{type:"object",properties:{total:{type:"object"},hits:{type:"array"}}},aggregations:{type:"object",properties:n}}}}const X=new Set(["by","of","the","from","for","in","on","at","to","a","an","and","or","with","per","over","all","top","total","count","type","types","log","logs","data","event","events"]);function Y(e){let n=0;for(let t=0;t<e.length;t++)n=Math.imul(31,n)+e.charCodeAt(t)|0;return Math.abs(n).toString(36).slice(0,4).padStart(4,"0")}function w(e,n,t){const r=Object.keys(t).sort().join("|"),o=`${n}|${r}`,s=M.createHash("sha256").update(o).digest("hex").slice(0,3),i=Y(o),c=P(e).slice(0,30),l=P(n).slice(0,40);return`${c}_${l}_${s}_${i}`}function v(e,n,t){const s=t.slice(-8),i=P(e).slice(0,12),c=new Set(i.split("_").filter(d=>d.length>2)),l=P(n).split("_").filter(d=>d.length>1&&!X.has(d)&&!c.has(d)),g=64-i.length-2-8,u=[];let p=0;for(const d of l){const m=(u.length>0?1:0)+d.length;if(p+m>g)break;u.push(d),p+=m}const h=u.length>0?u.join("_"):P(n).slice(0,g);return`${i}_${h}_${s}`}function V(e,n,t,r,o,s,i,c,l,g){const u=e?.attributes?.state,p=u?.datasourceStates?.formBased??u?.datasourceStates?.indexpattern;if(!p?.layers)return[];const h=k(u?.filters??[]),d=u?.query?.query??"",m=[];for(const y of Object.values(p.layers)){const a=H(y);if(Object.keys(a).length===0)continue;const f=k(y.filters??[]),j=y.query?.query??"",b=[...i,...l,...h,...f],_=[c,g,d,j].filter(Boolean),O=R(b,_),S=w(t,n,a),A=v(t,n,S),K=N(s,a),B=T(a);m.push({uniquePath:S,toolName:A,panelName:P(n),panelType:"lens",query:O,aggs:a,controlPanels:s,inputSchema:K,outputSchema:B,dashboardId:r,dashboardTitle:o,indexPatternId:y.indexPatternId??void 0})}return m}function Z(e,n,t,r,o,s,i,c,l,g){const u=q(e?.attributes?.kibanaSavedObjectMeta?.searchSourceJSON);if(!u?.query)return[];const p=k(u.filter??[]),h=u.query?.query??"",d=[...i,...l,...p],m=[c,g,h].filter(Boolean),y=R(d,m),a={},f=w(t,n,a),j=v(t,n,f),b=N(s,a),_=T(a);return[{uniquePath:f,toolName:j,panelName:P(n),panelType:"search",query:y,aggs:a,controlPanels:s,inputSchema:b,outputSchema:_,dashboardId:r,dashboardTitle:o}]}function D(e,n,t,r,o,s,i,c,l,g){const u=q(e?.attributes?.layerListJSON);if(!Array.isArray(u))return[];const p=[];for(const[h,d]of u.entries()){if(d?.sourceDescriptor?.type!=="ES_GEO_GRID")continue;const m=d.sourceDescriptor.geoField,y=`${n}_layer_${h}`,a={geo_grid:{geohash_grid:{field:m,precision:5}}},f=[...i,...l],j=[c,g].filter(Boolean),b=R(f,j),_=w(t,y,a),O=v(t,y,_),S=N(s,a),A=T(a);p.push({uniquePath:_,toolName:O,panelName:P(y),panelType:"map",query:b,aggs:a,controlPanels:s,inputSchema:S,outputSchema:A,dashboardId:r,dashboardTitle:o})}return p}function nt(e,n,t){const r=e.attributes??{},o=e.id??"unknown",s=r.title??o,i=q(r.kibanaSavedObjectMeta?.searchSourceJSON),c=k(Array.isArray(i.filter)?i.filter:[]),l=i.query?.query??"",u=(e.references??[]).filter(a=>a.type==="index-pattern"&&a.id).map(a=>a.id)[0],p=U(r.controlGroupInput),h=Array.isArray(r.panelsJSON)?r.panelsJSON:q(r.panelsJSON);if(!Array.isArray(h))return[];const d=[];for(const a of h){const f=a.type??a.embeddableConfig?.attributes?.visualizationType??"unknown",j=a.title??a.embeddableConfig?.attributes?.title??`panel_${d.length}`,b=a.embeddableConfig,_=k(Array.isArray(b?.filters)?b.filters:[]),O=b?.query?.query??"";let S=[];f==="lens"?S=V(b,j,n,o,s,p,c,l,_,O):f==="search"?S=Z(b,j,n,o,s,p,c,l,_,O):f==="map"&&(S=D(b,j,n,o,s,p,c,l,_,O)),d.push(...S)}const m=new Set,y=d.filter(a=>m.has(a.uniquePath)?!1:(m.add(a.uniquePath),!0));for(const a of y){if(a.indexPatternId&&t&&t.size>0){const f=t.get(a.indexPatternId);if(f){a.indexPattern=f;continue}}!a.indexPattern&&u&&(a.indexPattern=u)}return y}export{H as buildAggregations,nt as extractPanelsFromDashboard,N as generateInputSchema,T as generateOutputSchema};
@@ -0,0 +1 @@
1
+ import{HttpsClient as c}from"../utils/http-client";import{settingsConfig as i}from"../app-config/settings";class f{httpsClient;hostname;port;basePath;authHeader;constructor(){this.httpsClient=new c(i.certificates,i.defaults.timeout,!1),this.hostname=i.kibana.hostname,this.port=i.kibana.port,this.basePath=i.kibana.basePath;const e=i.kibana;if(e.apiKey)this.authHeader=`ApiKey ${e.apiKey}`;else{const{username:s,password:t}=e.credentials;this.authHeader=`Basic ${Buffer.from(`${s}:${t}`).toString("base64")}`}}getAuthHeader(){return this.authHeader}async checkPolicy(e){const s={hostname:this.hostname,port:this.port,path:`${this.basePath}/api/fleet/package_policies/${e}`,method:"GET",headers:{Authorization:this.getAuthHeader(),"kbn-xsrf":"reporting","Content-Type":"application/json"}};return await this.httpsClient.request(s)}async createPolicy(e){console.log("kibana Creating policy:",JSON.stringify(e,null,2));const s=JSON.stringify(e),t={hostname:this.hostname,port:this.port,path:`${this.basePath}/api/fleet/package_policies`,method:"POST",headers:{Authorization:this.getAuthHeader(),"kbn-xsrf":"reporting","Content-Type":"application/json","Content-Length":Buffer.byteLength(s).toString()},timeout:6e4};return await this.httpsClient.request(t,s)}async updatePolicy(e,s){console.log(`[KibanaService] Updating policy ${e}:`,JSON.stringify(s,null,2));const t=JSON.stringify(s),a={hostname:this.hostname,port:this.port,path:`${this.basePath}/api/fleet/package_policies/${e}`,method:"PUT",headers:{Authorization:this.getAuthHeader(),"kbn-xsrf":"reporting","Content-Type":"application/json","Content-Length":Buffer.byteLength(t).toString()},timeout:6e4};console.log(`[KibanaService] PUT request to: ${a.path}`);const n=await this.httpsClient.request(a,t);return console.log("[KibanaService] Update result:",JSON.stringify(n,null,2)),n}async getEpmPackages(e=!1){const s={hostname:this.hostname,port:this.port,path:`${this.basePath}/api/fleet/epm/packages?prerelease=${e}`,method:"GET",headers:{Authorization:this.getAuthHeader(),"kbn-xsrf":"reporting","Content-Type":"application/json"},timeout:3e4};return console.log("KibanaService getEpmPackages options:",s),await this.httpsClient.request(s)}async getEpmPackage(e,s){const t={hostname:this.hostname,port:this.port,path:`${this.basePath}/api/fleet/epm/packages/${e}/${s}`,method:"GET",headers:{Authorization:this.getAuthHeader(),"kbn-xsrf":"reporting","Content-Type":"application/json"}};return console.log("KibanaService getEpmPackage options:",t),await this.httpsClient.request(t)}async installEpmPackage(e,s){const t=JSON.stringify({force:!0}),a={hostname:this.hostname,port:this.port,path:`${this.basePath}/api/fleet/epm/packages/${e}/${s}`,method:"POST",headers:{Authorization:this.getAuthHeader(),"kbn-xsrf":"reporting","Content-Type":"application/json","Content-Length":Buffer.byteLength(t)},timeout:12e4};return console.log("KibanaService installEpmPackage options:",a),await this.httpsClient.request(a,t)}async getPackagePolicies(e){let t=1;const a=[];for(;;){const n=new URLSearchParams({perPage:String(100),page:String(t)});e&&n.set("kuery",e);const p=`${this.basePath}/api/fleet/package_policies?${n.toString()}`,l={hostname:this.hostname,port:this.port,path:p,method:"GET",headers:{Authorization:this.getAuthHeader(),"kbn-xsrf":"reporting","Content-Type":"application/json"}},o=await this.httpsClient.request(l);if(o?.error){if(t===1)return o;break}const r=o?.data?.items||o?.items||[],h=o?.data?.total??o?.total??r.length;if(a.push(...r),console.log(`[KibanaService] getPackagePolicies page=${t}: ${r.length} items, total=${h}, collected=${a.length}`),a.length>=h||r.length<100)break;t++}return{items:a,total:a.length}}async getPackagePolicy(e){const s={hostname:this.hostname,port:this.port,path:`${this.basePath}/api/fleet/package_policies/${e}`,method:"GET",headers:{Authorization:this.getAuthHeader(),"kbn-xsrf":"reporting","Content-Type":"application/json"}};console.log("[KibanaService] getPackagePolicy request:",{url:`https://${s.hostname}:${s.port}${s.path}`,method:s.method,policyId:e});try{const t=await this.httpsClient.request(s);return t&&t.data&&t.data.item?console.log("[KibanaService] getPackagePolicy success:",{policyId:e,policyName:t.data.item.name,packageName:t.data.item.package?.name}):t&&t.error?console.error("[KibanaService] getPackagePolicy error:",{policyId:e,statusCode:t.statusCode,error:t.error}):console.warn("[KibanaService] getPackagePolicy no data:",{policyId:e}),t}catch(t){throw console.error("[KibanaService] getPackagePolicy exception:",{policyId:e,error:t.message||t,stack:t.stack}),t}}async deletePackagePolicy(e){const s={hostname:this.hostname,port:this.port,path:`${this.basePath}/api/fleet/package_policies/${e}`,method:"DELETE",headers:{Authorization:this.getAuthHeader(),"kbn-xsrf":"reporting","Content-Type":"application/json"}};return console.log("KibanaService deletePackagePolicy options:",s),await this.httpsClient.request(s)}async getAgentPolicies(e){const s=new URLSearchParams;e&&s.set("kuery",e);const t=`${this.basePath}/api/fleet/agent_policies?${s.toString()}`,a={hostname:this.hostname,port:this.port,path:t,method:"GET",headers:{Authorization:this.getAuthHeader(),"kbn-xsrf":"reporting","Content-Type":"application/json"}};return console.log("KibanaService getAgentPolicies options:",a),await this.httpsClient.request(a)}async getFleetServerHosts(){const e={hostname:this.hostname,port:this.port,path:`${this.basePath}/api/fleet/fleet_server_hosts`,method:"GET",headers:{Authorization:this.getAuthHeader(),"kbn-xsrf":"reporting","Content-Type":"application/json"}};return await this.httpsClient.request(e)}async getFleetAgents(e){const s=e?`${this.basePath}/api/fleet/agents?kuery=${encodeURIComponent(e)}`:`${this.basePath}/api/fleet/agents`,t={hostname:this.hostname,port:this.port,path:s,method:"GET",headers:{Authorization:this.getAuthHeader(),"kbn-xsrf":"reporting","Content-Type":"application/json"}};return await this.httpsClient.request(t)}async getEnrollmentApiKeys(e){const s=new URLSearchParams({page:"1",perPage:"2000",kuery:"not hidden:true"});e&&s.set("kuery",`(not hidden:true) and (policy_id:"${e}")`);const t={hostname:this.hostname,port:this.port,path:`${this.basePath}/api/fleet/enrollment_api_keys?${s.toString()}`,method:"GET",headers:{Authorization:this.getAuthHeader(),"kbn-xsrf":"reporting","Content-Type":"application/json"}};return await this.httpsClient.request(t)}async createAgentPolicy(e,s){const t=JSON.stringify({name:e,description:s||"",namespace:"default",monitoring_enabled:["logs","metrics"]}),a={hostname:this.hostname,port:this.port,path:`${this.basePath}/api/fleet/agent_policies`,method:"POST",headers:{Authorization:this.getAuthHeader(),"kbn-xsrf":"reporting","Content-Type":"application/json","Content-Length":Buffer.byteLength(t)}};return await this.httpsClient.request(a,t)}async bulkInstallEpmPackages(e){const s=JSON.stringify({force:!1,packages:e}),t={hostname:this.hostname,port:this.port,path:`${this.basePath}/api/fleet/epm/packages/_bulk`,method:"POST",headers:{Authorization:this.getAuthHeader(),"kbn-xsrf":"reporting","Content-Type":"application/json","Content-Length":Buffer.byteLength(s)},timeout:3e5};return console.log("KibanaService bulkInstallEpmPackages options:",t),console.log("KibanaService bulkInstallEpmPackages packages:",e),await this.httpsClient.request(t,s)}}export{f as KibanaService};
@@ -0,0 +1 @@
1
+ import{Client as E}from"@elastic/elasticsearch";import{config as k}from"../config";const x=new E(k.elasticsearch),M=".stkxp_chats",L={openai:{"gpt-4o":{input:2.5,output:10},"gpt-4o-mini":{input:.15,output:.6},"gpt-4-turbo":{input:10,output:30}},anthropic:{"claude-sonnet-4-5":{input:3,output:15},"claude-opus-4":{input:15,output:75},"claude-haiku-3-5":{input:.8,output:4}},google:{"gemini-2.0-flash-exp":{input:0,output:0},"gemini-1.5-pro":{input:1.25,output:5},"gemini-1.5-flash":{input:.075,output:.3}}};function F(r){return Math.ceil(r.length/4)}function B(r,a,n,i){const o=L[r]?.[a];if(!o)return 0;const d=n/1e6*o.input+i/1e6*o.output;return parseFloat(d.toFixed(6))}function R(r){if(!(r.length<2)){for(let a=0;a<r.length-1;a++)if(r[a].role==="user"&&(r[a+1].role==="assistant"||r[a+1].role==="agent")){const n=new Date(r[a].timestamp).getTime();return new Date(r[a+1].timestamp).getTime()-n}}}async function v(r,a){try{const n={bool:{must:[{exists:{field:"metadata.llmProvider"}}]}};r&&n.bool.must.push({range:{createdAt:{gte:r.start,lte:r.end}}}),a&&n.bool.must.push({term:{username:a}});const o=(await x.search({index:M,body:{query:n,size:1e4}})).hits.hits.map(e=>({id:e._id,...e._source})),d=new Map;o.forEach(e=>{const c=e.metadata?.llmProvider||"unknown",h=e.metadata?.llmModel||"unknown",g=`${c}:${h}`;d.has(g)||d.set(g,{totalCalls:0,inputTokens:0,outputTokens:0,responseTimes:[],usageByTopic:new Map,usageByUser:new Map,lastUsed:e.createdAt});const p=d.get(g);p.totalCalls++;let t=0,s=0;e.messages.forEach(u=>{const y=JSON.stringify(u.content||"");u.role==="user"||u.role==="system"?t+=y.length:(u.role==="assistant"||u.role==="agent")&&(s+=y.length)}),p.inputTokens+=F(String(t)),p.outputTokens+=F(String(s));const T=R(e.messages);T&&p.responseTimes.push(T);const l=e.metadata?.topic||"general";p.usageByTopic.set(l,(p.usageByTopic.get(l)||0)+1),p.usageByUser.set(e.username,(p.usageByUser.get(e.username)||0)+1),new Date(e.createdAt)>new Date(p.lastUsed)&&(p.lastUsed=e.createdAt)});const f=[];return d.forEach((e,c)=>{const[h,g]=c.split(":"),p=e.responseTimes.length>0?e.responseTimes.reduce((l,u)=>l+u,0)/e.responseTimes.length:0,t=B(h,g,e.inputTokens,e.outputTokens),s={};e.usageByTopic.forEach((l,u)=>{s[u]=l});const T={};e.usageByUser.forEach((l,u)=>{T[u]=l}),f.push({provider:h,model:g,totalCalls:e.totalCalls,estimatedInputTokens:e.inputTokens,estimatedOutputTokens:e.outputTokens,avgResponseTime:parseFloat(p.toFixed(2)),costEstimate:parseFloat(t.toFixed(6)),usageByTopic:s,usageByUser:T,lastUsed:e.lastUsed})}),f.sort((e,c)=>c.totalCalls-e.totalCalls)}catch(n){throw console.error("Error getting LLM usage stats:",n),n}}async function S(r,a,n){try{const i=await v(a,n),o=i.reduce((t,s)=>t+s.costEstimate,0),d=new Map;i.forEach(t=>{d.set(t.provider,(d.get(t.provider)||0)+t.costEstimate)});const f=Array.from(d.entries()).map(([t,s])=>({provider:t,cost:parseFloat(s.toFixed(6)),percentage:o>0?parseFloat((s/o*100).toFixed(2)):0})).sort((t,s)=>s.cost-t.cost),e=i.map(t=>({model:t.model,provider:t.provider,cost:t.costEstimate,percentage:o>0?parseFloat((t.costEstimate/o*100).toFixed(2)):0})).sort((t,s)=>s.cost-t.cost),c=new Map;i.forEach(t=>{Object.entries(t.usageByUser).forEach(([s,T])=>{const l=t.costEstimate/t.totalCalls*T;c.set(s,(c.get(s)||0)+l)})});const h=Array.from(c.entries()).map(([t,s])=>({username:t,cost:parseFloat(s.toFixed(6)),percentage:o>0?parseFloat((s/o*100).toFixed(2)):0})).sort((t,s)=>s.cost-t.cost),g=new Map;i.forEach(t=>{Object.entries(t.usageByTopic).forEach(([s,T])=>{const l=t.costEstimate/t.totalCalls*T;g.set(s,(g.get(s)||0)+l)})});const p=Array.from(g.entries()).map(([t,s])=>({topic:t,cost:parseFloat(s.toFixed(6)),percentage:o>0?parseFloat((s/o*100).toFixed(2)):0})).sort((t,s)=>s.cost-t.cost);return{total:parseFloat(o.toFixed(6)),byProvider:f,byModel:e,byUser:h,byTopic:p}}catch(i){throw console.error("Error getting LLM cost breakdown:",i),i}}async function D(r,a,n,i){try{const o={bool:{must:[{term:{"metadata.llmProvider":r}},{term:{"metadata.llmModel":a}}]}};n&&o.bool.must.push({range:{createdAt:{gte:n.start,lte:n.end}}}),i&&o.bool.must.push({term:{username:i}});const f=(await x.search({index:M,body:{query:o,size:1e4}})).hits.hits.map(m=>({id:m._id,...m._source}));if(f.length===0)return null;const e=[],c=new Map;f.forEach(m=>{const b=R(m.messages);b&&e.push(b);const C=new Date(m.createdAt).toISOString().slice(0,13)+":00:00";c.set(C,(c.get(C)||0)+1)}),e.sort((m,b)=>m-b);const h=e.length>0?e.reduce((m,b)=>m+b,0)/e.length:0,g=e.length>0?e[0]:0,p=e.length>0?e[e.length-1]:0,t=Math.floor(e.length*.5),s=Math.floor(e.length*.95),T=Math.floor(e.length*.99),l=e.length>0?e[t]:0,u=e.length>0?e[s]:0,y=e.length>0?e[T]:0,w=Array.from(c.entries()).map(([m,b])=>({timestamp:m,count:b})).sort((m,b)=>m.timestamp.localeCompare(b.timestamp));return{provider:r,model:a,totalCalls:f.length,avgResponseTime:parseFloat(h.toFixed(2)),minResponseTime:parseFloat(g.toFixed(2)),maxResponseTime:parseFloat(p.toFixed(2)),p50ResponseTime:parseFloat(l.toFixed(2)),p95ResponseTime:parseFloat(u.toFixed(2)),p99ResponseTime:parseFloat(y.toFixed(2)),callsOverTime:w}}catch(o){return console.error("Error getting LLM performance:",o),null}}async function _(r,a){try{return{models:(await v(r,a)).map(o=>({provider:o.provider,model:o.model,totalCalls:o.totalCalls,avgCost:o.totalCalls>0?parseFloat((o.costEstimate/o.totalCalls).toFixed(6)):0,avgResponseTime:o.avgResponseTime,successRate:100}))}}catch(n){throw console.error("Error getting model comparison:",n),n}}export{S as getLLMCostBreakdown,D as getLLMPerformance,v as getLLMUsageStats,_ as getModelComparison};
@@ -0,0 +1 @@
1
+ import{loadLLMConfigForNode as n}from"../graph/graph-builder";import{resolveAssistant as a}from"./assistant-resolver";import{createLLMInstance as i}from"../llm/providers";import{config as o}from"../config";const l={provider:"anthropic",model:"claude-sonnet-4-5",temperature:0,maxTokens:8e3,streaming:!0,apiKey:o.llm.apiKey||"",baseURL:o.llm.baseURL};async function d(e,t){const s=(e?await a(e):null)?.llm_overrides?.assistant_response_generator,r=await n("assistant_response_generator",s,l,t);return i({...r,streaming:!1})}export{d as resolveLlmClientForAssistant};
@@ -0,0 +1 @@
1
+ import{LLM_INDICES as u,LLMModelSchema as g,CreateModelSchema as _,UpdateModelSchema as L}from"../llm/models";class k{constructor(o){this.esClient=o}async createModel(o){const t=_.parse(o),r=t.id||t.modelId,e=new Date().toISOString(),i={...t,id:r,createdAt:e,updatedAt:e};g.parse(i);const{_id:c,...a}=i;return await this.esClient.index({index:u.MODELS,id:r,body:a,refresh:!0}),{...i,_id:r}}async getModel(o){try{let t,r=o;try{t=await this.esClient.get({index:u.MODELS,id:o})}catch(a){if(a.meta?.statusCode===404){const l=await this.esClient.search({index:u.MODELS,body:{query:{bool:{should:[{term:{id:o}},{term:{model:o}},{term:{modelId:o}}]}},size:1}});if(l.hits.hits.length===0)return null;const m=l.hits.hits[0];r=m._id,t={_source:m._source}}else throw a}const e=t._source,i=a=>{if(!a)return new Date().toISOString();const l=a.replace(/ZZ$/,"Z");return/Z$|[+-]\d{2}:?\d{2}$/.test(l)?l:l+"Z"};return{_id:r,id:e.id||e.model||o,providerId:e.providerId||e.provider||"unknown",name:e.name||e.model||"Unknown Model",modelId:e.modelId||e.model||"",contextWindow:e.contextWindow||e.context_window||128e3,capabilities:e.capabilities||{streaming:!0,toolCalling:!0,jsonMode:!0,vision:!1,multimodal:!1},pricing:e.pricing||(e.current_price?{inputTokens:e.current_price.input||0,outputTokens:e.current_price.output||0}:void 0),parameters:e.parameters,enabled:e.enabled!==void 0?e.enabled:!0,owner:e.owner,metadata:e.metadata||{},createdAt:i(e.createdAt||e.last_updated),updatedAt:i(e.updatedAt||e.last_updated)}}catch(t){if(t.meta?.statusCode===404)return null;throw t}}async listModels(o={},t){const{providerId:r,enabled:e,capabilities:i,deprecated:c,search:a,limit:l=50,offset:m=0}=o,d=[];r&&d.push({term:{providerId:r}}),e!==void 0&&d.push({term:{enabled:e}}),c!==void 0&&d.push({term:{"metadata.deprecated":c}}),i&&(i.streaming!==void 0&&d.push({term:{"capabilities.streaming":i.streaming}}),i.toolCalling!==void 0&&d.push({term:{"capabilities.toolCalling":i.toolCalling}}),i.jsonMode!==void 0&&d.push({term:{"capabilities.jsonMode":i.jsonMode}}),i.vision!==void 0&&d.push({term:{"capabilities.vision":i.vision}}),i.multimodal!==void 0&&d.push({term:{"capabilities.multimodal":i.multimodal}})),a&&d.push({multi_match:{query:a,fields:["name","modelId","metadata.tags"],type:"phrase_prefix"}}),t&&d.push({term:{owner:t}});const f={query:{bool:{must:d}},size:l,from:m,sort:[{createdAt:{order:"desc",unmapped_type:"date"}}]},M=await this.esClient.search({index:u.MODELS,body:f}),h=s=>{if(!s)return new Date().toISOString();const n=s.replace(/ZZ$/,"Z");return/Z$|[+-]\d{2}:?\d{2}$/.test(n)?n:n+"Z"},w=M.hits.hits.map(s=>{const n=s._source,p=n.id||n.model||`${n.provider}-${n.model}`,y=n.providerId||n.provider||"unknown",b=n.modelId||n.model||"";return{_id:s._id,id:p,providerId:y,name:n.name||n.model||"Unknown Model",modelId:b,contextWindow:n.contextWindow||n.context_window||128e3,capabilities:n.capabilities||{streaming:!0,toolCalling:!0,jsonMode:!0,vision:!1,multimodal:!1},pricing:n.pricing||(n.current_price?{inputTokens:n.current_price.input||0,outputTokens:n.current_price.output||0}:void 0),parameters:n.parameters,enabled:n.enabled!==void 0?n.enabled:!0,owner:n.owner,metadata:n.metadata||{},createdAt:h(n.createdAt||n.last_updated),updatedAt:h(n.updatedAt||n.last_updated)}});return{models:await Promise.all(w.map(async s=>{if(s.owner)return s;try{const p=(await this.esClient.get({index:u.PROVIDERS,id:s.providerId}))._source;return{...s,owner:p?.metadata?.owner||"Unknown"}}catch{return{...s,owner:"Unknown"}}})),total:M.hits.total.value||0}}async updateModel(o,t){L.parse(t);const r=await this.getModel(o);if(!r)throw new Error(`Model not found: ${o}`);const e=r._id||o,{_id:i,...c}=r,a={...c,...t,createdAt:r.createdAt,updatedAt:new Date().toISOString()};g.parse(a);const{_id:l,...m}=a;return await this.esClient.index({index:u.MODELS,id:e,body:m,refresh:!0}),{...a,_id:e}}async deleteModel(o){try{const t=await this.getModel(o);if(!t)return!1;const r=t._docId||o;return await this.esClient.delete({index:u.MODELS,id:r,refresh:!0}),!0}catch(t){if(t.meta?.statusCode===404)return!1;throw t}}async toggleModel(o,t){return this.updateModel(o,{enabled:t})}async getModelsByProvider(o,t=!0){const r={providerId:o,limit:100};return t&&(r.enabled=!0),(await this.listModels(r)).models}async getModelsByCapabilities(o){const t=[{term:{enabled:!0}}];for(const e of o)t.push({term:{[`capabilities.${e}`]:!0}});return(await this.esClient.search({index:u.MODELS,body:{query:{bool:{must:t}},size:100}})).hits.hits.map(e=>e._source)}async exists(o){return await this.getModel(o)!==null}async getStatistics(){const t=(await this.esClient.search({index:u.MODELS,body:{size:0,aggs:{total:{value_count:{field:"id"}},enabled:{filter:{term:{enabled:!0}}},by_provider:{terms:{field:"providerId",size:20}},with_tool_calling:{filter:{term:{"capabilities.toolCalling":!0}}},avg_context_window:{avg:{field:"contextWindow"}}}}})).aggregations;return{total:t.total.value,enabled:t.enabled.doc_count,byProvider:Object.fromEntries(t.by_provider.buckets.map(r=>[r.key,r.doc_count])),withToolCalling:t.with_tool_calling.doc_count,avgContextWindow:Math.round(t.avg_context_window.value||0)}}}export{k as LLMModelsService};
@@ -0,0 +1 @@
1
+ function c(e,n){if(!n)return null;const t=n.toLowerCase();if(e[t])return e[t];for(const[r,o]of Object.entries(e))if(r.startsWith(t)||t.startsWith(r))return o;return null}function i(e,n){if(!e)return 0;const t=n.cacheRead??0,r=n.cacheCreate??0;let u=Math.max(0,(n.input??0)-t-r)/1e6*e.input;return u+=(n.output??0)/1e6*e.output,t>0&&(u+=t/1e6*(e.inputCached??e.input)),r>0&&(u+=r/1e6*e.input*1.25),parseFloat(u.toFixed(6))}export{i as computeCostUsdFromPricing,c as lookupModelIdPrice};
@@ -0,0 +1 @@
1
+ import{Client as h}from"@elastic/elasticsearch";import{config as m}from"../config";const p=new h(m.elasticsearch),d=".stkxp_llm_models";class g{cache=new Map;lastUpdate=0;CACHE_TTL=300*1e3;getCacheKey(r,e){return`${r.toLowerCase()}:${e.toLowerCase()}`}set(r,e,t){this.cache.set(this.getCacheKey(r,e),t)}get(r,e){return Date.now()-this.lastUpdate>this.CACHE_TTL?null:this.cache.get(this.getCacheKey(r,e))||null}setLastUpdate(){this.lastUpdate=Date.now()}clear(){this.cache.clear(),this.lastUpdate=0}isExpired(){return Date.now()-this.lastUpdate>this.CACHE_TTL}}const s=new g;async function f(){try{const o=await p.search({index:d,body:{query:{match_all:{}},size:1e3}}),r=[];return o.hits.hits.forEach(e=>{const t=e._source;if(t.current_price){const i={provider:t.provider,model:t.model,name:t.name,input:t.current_price.input,output:t.current_price.output,input_cached:t.current_price.input_cached};r.push(i),s.set(t.provider,t.model,i)}}),s.setLastUpdate(),r}catch(o){throw console.error("Error fetching LLM pricing from Elasticsearch:",o),o}}function _(o){const r=o.toLowerCase(),e=[r];if(/-\d+$/.test(r)){const t=r.replace(/-(\d+)$/,".$1");e.push(t)}if(r.includes(".")){const t=r.replace(/\./g,"-");e.push(t)}return[...new Set(e)]}async function L(o,r){try{if(!s.isExpired()){const t=s.get(o,r);if(t)return t}const e=_(r);for(const t of e){const i=await p.search({index:d,body:{query:{bool:{must:[{term:{provider:o.toLowerCase()}},{term:{model:t}}]}},size:1}});if(i.hits.hits.length>0){const n=i.hits.hits[0]._source;if(!n.current_price)continue;const c={provider:n.provider,model:n.model,name:n.name,input:n.current_price.input,output:n.current_price.output,input_cached:n.current_price.input_cached};return s.set(o,r,c),s.setLastUpdate(),c}}return console.warn(`No pricing found for ${o}/${r} (tried variants: ${e.join(", ")})`),null}catch(e){return console.error(`Error fetching pricing for ${o}/${r}:`,e),null}}async function y(o,r,e,t,i=0){try{const n=await L(o,r);if(!n)return console.warn(`No pricing data for ${o}/${r}, cost set to 0`),0;let c=0;const a=e-i;return a>0&&(c+=a/1e6*n.input),i>0&&n.input_cached!==null&&n.input_cached!==void 0&&(c+=i/1e6*n.input_cached),t>0&&(c+=t/1e6*n.output),parseFloat(c.toFixed(6))}catch(n){return console.error(`Error calculating cost for ${o}/${r}:`,n),0}}async function M(o){try{return s.isExpired()&&await f(),await Promise.all(o.map(async e=>{const t=await y(e.provider,e.model,e.inputTokens,e.outputTokens,e.cachedInputTokens||0);return{provider:e.provider,model:e.model,cost:t}}))}catch(r){return console.error("Error in batch cost calculation:",r),o.map(e=>({provider:e.provider,model:e.model,cost:0}))}}function v(){s.clear()}let u={},l=0;const b=300*1e3;function x(){l=0}async function C(){const o=Date.now();if(o-l<b&&Object.keys(u).length>0)return u;try{const r=await p.search({index:d,body:{query:{match_all:{}},size:1e3,_source:["modelId","id","model","pricing","current_price"]}}),e={};for(const t of r.hits.hits){const i=t._source;if(i?.pricing?.inputTokens!==void 0){const n=(i.modelId||i.id||"").toLowerCase();n&&(e[n]={input:i.pricing.inputTokens??0,output:i.pricing.outputTokens??0,inputCached:i.pricing.inputCachedTokens});continue}if(i?.current_price&&i?.model){const n=i.model.toLowerCase();e[n]={input:i.current_price.input??0,output:i.current_price.output??0,inputCached:i.current_price.input_cached??void 0}}}return u=e,l=o,e}catch(r){return r?.meta?.body?.error?.type==="index_not_found_exception"?{}:(console.error("[pricing] Failed to load modelId pricing table:",r?.message),u)}}async function E(o,r,e){const t=await C(),i=o.toLowerCase();let n=t[i];if(!n){for(const[c,a]of Object.entries(t))if(c.startsWith(i)||i.startsWith(c)){n=a;break}}return n?r/1e6*n.input+e/1e6*n.output:0}export{M as calculateBatchCosts,y as calculateCost,v as clearPricingCache,E as estimateCostByModelId,f as fetchAllLLMPricing,L as getLLMPricing,x as invalidateModelIdPricingCache,C as loadModelIdPricingTable};
@@ -0,0 +1 @@
1
+ import{LLM_INDICES as s,LLMProviderSchema as m,CreateProviderSchema as P,UpdateProviderSchema as h}from"../llm/models";class I{constructor(r){this.esClient=r}async createProvider(r){const e=P.parse(r),t=e.id||`${e.type}-${Date.now()}`,i=new Date().toISOString(),o={...e,id:t,createdAt:i,updatedAt:i};return m.parse(o),await this.esClient.index({index:s.PROVIDERS,id:t,body:o,refresh:!0}),o}async getProvider(r){try{const e=await this.esClient.get({index:s.PROVIDERS,id:r});return{...e._source,id:e._id}}catch(e){if(e.meta?.statusCode===404)return null;throw e}}async listProviders(r={},e){const{type:t,enabled:i,owner:o,environment:a,region:d,search:u,limit:v=50,offset:y=0}=r,n=[];t&&n.push({term:{type:t}}),i!==void 0&&n.push({term:{enabled:i}}),o?n.push({term:{owner:o}}):e&&n.push({term:{owner:e}}),a&&n.push({term:{"metadata.environment":a}}),d&&n.push({term:{"metadata.region":d}}),u&&n.push({multi_match:{query:u,fields:["name","id","metadata.tags"],type:"phrase_prefix"}});const p={query:{bool:{must:n}},size:v,from:y,sort:[{createdAt:{order:"desc",unmapped_type:"date"}}]},c=await this.esClient.search({index:s.PROVIDERS,body:p});return{providers:c.hits.hits.map(l=>({...l._source,id:l._id})),total:c.hits.total.value||0}}async updateProvider(r,e){h.parse(e);const t=await this.getProvider(r);if(!t)throw new Error(`Provider not found: ${r}`);const i={...t,...e,id:r,createdAt:t.createdAt,updatedAt:new Date().toISOString()};return m.parse(i),await this.esClient.index({index:s.PROVIDERS,id:r,body:i,refresh:!0}),i}async deleteProvider(r){try{return await this.esClient.delete({index:s.PROVIDERS,id:r,refresh:!0}),!0}catch(e){if(e.meta?.statusCode===404)return!1;throw e}}async toggleProvider(r,e){return this.updateProvider(r,{enabled:e})}async getProvidersByType(r,e=!0){const t={type:r,limit:100};return e&&(t.enabled=!0),(await this.listProviders(t)).providers}async exists(r){return await this.getProvider(r)!==null}async getStatistics(){const e=(await this.esClient.search({index:s.PROVIDERS,body:{size:0,aggs:{total:{value_count:{field:"id"}},enabled:{filter:{term:{enabled:!0}}},by_type:{terms:{field:"type",size:20}},by_environment:{terms:{field:"metadata.environment",size:10}}}}})).aggregations;return{total:e.total.value,enabled:e.enabled.doc_count,byType:Object.fromEntries(e.by_type.buckets.map(t=>[t.key,t.doc_count])),byEnvironment:Object.fromEntries(e.by_environment.buckets.map(t=>[t.key,t.doc_count]))}}}export{I as LLMProvidersService};
@@ -0,0 +1 @@
1
+ import{randomUUID as p}from"crypto";import{LLM_INDICES as n,LLMRoutingRuleSchema as c,CreateRoutingRuleSchema as h,UpdateRoutingRuleSchema as f}from"../llm/models";class D{constructor(e,t,i){this.esClient=e;this.providersService=t;this.modelsService=i}async selectDeployment(e){console.log("[Routing] Selecting model for context:",e);const t=await this.getApplicableRules(e);if(console.log(`[Routing] Found ${t.length} applicable rules`),t.length===0)throw new Error("No routing rules match the given context");for(const i of t){console.log(`[Routing] Trying rule: ${i.name} (priority: ${i.priority})`);try{const o=await this.resolveRule(i);if(o)return console.log(`[Routing] \u2705 Selected model: ${o.model.modelId} via rule: ${i.name}`),o}catch(o){console.warn(`[Routing] Rule ${i.name} failed:`,o.message)}}throw new Error("No suitable model found for the given context")}async resolveRule(e){const t=await this.modelsService.getModel(e.modelId);if(!t)return console.warn(`[Routing] Model not found: ${e.modelId}`),null;const i=await this.providersService.getProvider(t.providerId);return i?{provider:i,model:t,rule:e,reason:`Selected via rule "${e.name}" (modelId: ${e.modelId})`,timestamp:new Date().toISOString()}:(console.warn(`[Routing] Provider not found: ${t.providerId}`),null)}async getApplicableRules(e){const t=[{term:{enabled:!0}}];e.owner&&t.push({term:{owner:e.owner}});const i=[];return e.environment&&i.push({term:{"conditions.environment":e.environment}}),e.userRole&&i.push({term:{"conditions.userRole":e.userRole}}),e.topic&&(i.push({wildcard:{"conditions.topic":e.topic}}),i.push({prefix:{"conditions.topic":e.topic.split("_")[0]}})),i.push({bool:{must_not:[{exists:{field:"conditions.environment"}},{exists:{field:"conditions.userRole"}},{exists:{field:"conditions.topic"}}]}}),(await this.esClient.search({index:n.ROUTING_RULES,body:{query:{bool:{must:t,should:i,minimum_should_match:1}},size:50,sort:[{priority:{order:"desc"}}]}})).hits.hits.map(r=>r._source)}async createRoutingRule(e){const t=h.parse(e),i=t.id||p(),o=new Date().toISOString(),r={...t,id:i,createdAt:o,updatedAt:o};c.parse(r);const{_id:l,...u}=r;return await this.esClient.index({index:n.ROUTING_RULES,id:i,body:u,refresh:!0}),{...r,_id:i}}async getRoutingRule(e,t){try{const i=await this.esClient.get({index:n.ROUTING_RULES,id:e}),o={...i._source,_id:i._id};return t&&o.owner!==t?null:o}catch(i){if(i.meta?.statusCode===404)return null;throw i}}async getRoutingRuleByBusinessId(e,t){const o=(await this.esClient.search({index:n.ROUTING_RULES,body:{query:{bool:{must:[{term:{id:e}},{term:{owner:t}}]}},size:1}})).hits.hits[0];return o?{...o._source,_id:o._id}:null}async listRoutingRules(e={},t){const{enabled:i,owner:o,environment:r,topic:l,userRole:u,search:a,limit:g=50,offset:m=0}=e,s=[];i!==void 0&&s.push({term:{enabled:i}}),o?s.push({term:{owner:o}}):t&&s.push({term:{owner:t}}),r&&s.push({term:{"conditions.environment":r}}),l&&s.push({wildcard:{"conditions.topic":l}}),u&&s.push({term:{"conditions.userRole":u}}),a&&s.push({multi_match:{query:a,fields:["name","description","tags"],type:"phrase_prefix"}});const d=await this.esClient.search({index:n.ROUTING_RULES,body:{query:{bool:{must:s}},size:g,from:m,sort:[{priority:{order:"desc",unmapped_type:"long"}},{createdAt:{order:"desc",unmapped_type:"date"}}]}});return{rules:d.hits.hits.map(R=>({...R._source,_id:R._id})),total:d.hits.total.value||0}}async updateRoutingRule(e,t,i){f.parse(t);const o=await this.getRoutingRule(e);if(!o||i&&o.owner!==i)throw new Error(`Routing rule not found: ${e}`);const r={...o,...t,createdAt:o.createdAt,updatedAt:new Date().toISOString()};c.parse(r);const{_id:l,...u}=r;return await this.esClient.index({index:n.ROUTING_RULES,id:e,body:u,refresh:!0}),{...r,_id:e}}async getDefaultRoutingRule(e){try{const t=await this.esClient.search({index:n.ROUTING_RULES,body:{query:{bool:{must:[{term:{owner:e}},{term:{isDefault:!0}}]}},size:1}});return t.hits.hits[0]?{...t.hits.hits[0]._source,_id:t.hits.hits[0]._id}:null}catch(t){throw console.error(`[Routing] Error getting default routing rule for owner ${e}:`,t.message),new Error(`Failed to get default routing rule: ${t.message}`)}}async setDefaultRoutingRule(e,t){const i=await this.getRoutingRule(e);if(!i)throw new Error(`Routing rule not found: ${e}`);if(i.owner!==t)throw new Error("Unauthorized: cannot set default on a rule you do not own");await this.esClient.updateByQuery({index:n.ROUTING_RULES,refresh:!0,body:{script:{source:"ctx._source.isDefault = false",lang:"painless"},query:{bool:{must:[{term:{owner:t}},{term:{isDefault:!0}}]}}}}),await this.esClient.update({index:n.ROUTING_RULES,id:e,doc:{isDefault:!0,updatedAt:new Date().toISOString()},refresh:!0}),console.log(`[Routing] Default routing rule for owner '${t}' set to: ${e}`)}async deleteRoutingRule(e,t){if(t&&!await this.getRoutingRule(e,t))return!1;try{return await this.esClient.delete({index:n.ROUTING_RULES,id:e,refresh:!0}),!0}catch(i){if(i.meta?.statusCode===404)return!1;throw i}}async toggleRoutingRule(e,t){return this.updateRoutingRule(e,{enabled:t})}}export{D as LLMRoutingService};
@@ -0,0 +1 @@
1
+ import{LLMProvidersService as t}from"./llm-providers-service";import{LLMModelsService as o}from"./llm-models-service";import{LLMRoutingService as s}from"./llm-routing-service";export*from"./llm-providers-service";export*from"./llm-models-service";export*from"./llm-routing-service";class e{static instance=null;providersService;modelsService;routingService;constructor(r){this.providersService=new t(r),this.modelsService=new o(r),this.routingService=new s(r,this.providersService,this.modelsService)}static getInstance(r){return e.instance||(e.instance=new e(r)),e.instance}static reset(){e.instance=null}getProvidersService(){return this.providersService}getModelsService(){return this.modelsService}getRoutingService(){return this.routingService}getAllServices(){return{providers:this.providersService,models:this.modelsService,routing:this.routingService}}}function l(i){return e.getInstance(i)}export{e as LLMServicesFactory,l as createLLMServices};
@@ -0,0 +1 @@
1
+ import b from"axios";const v="https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",f=".stkxp_llm_models",k=".stkxp_llm_providers",T={openai:"openai","text-completion-openai":"openai",anthropic:"anthropic",gemini:"google","vertex_ai-language-models":"google",vertex_ai:"google","vertex_ai-anthropic_models":"anthropic",azure:"azure",azure_ai:"azure",azure_text:"azure",openrouter:"openrouter",deepseek:"deepseek",mistral:"mistral",groq:"groq",xai:"xai",cohere:"cohere",cohere_chat:"cohere",together_ai:"together",cerebras:"cerebras",databricks:"databricks",perplexity:"perplexity",deepinfra:"deepinfra",fireworks_ai:"fireworks",sambanova:"sambanova",moonshot:"moonshot",minimax:"minimax",dashscope:"qwen",bedrock:"bedrock",bedrock_converse:"bedrock",amazon_nova:"amazon",hyperbolic:"hyperbolic",nebius:"nebius",novita:"novita",cloudflare:"cloudflare"},w={openai:"openai",anthropic:"anthropic",google:"google",azure:"azure",openrouter:"openrouter",deepseek:"deepseek",mistral:"mistral",groq:"groq",xai:"xai",cohere:"cohere",together:"together",cerebras:"cerebras",bedrock:"bedrock",custom:"custom"};function I(n){if(!n)return"custom";const e=n.toLowerCase().trim();return w[e]??e}const S=new Set(["gemini","openrouter","azure","mistral","groq","xai","deepseek","deepinfra","fireworks_ai","together_ai","sambanova","cerebras","moonshot","minimax","cohere","perplexity","databricks","cloudflare","huggingface","replicate","nlp_cloud","hyperbolic","nebius","novita","bedrock","anthropic"]);function M(n){const e=n.indexOf("/");if(e===-1)return n;const r=n.substring(0,e);return S.has(r)?n.substring(e+1):n}function P(n,e){if(!e||typeof e!="object"||n==="sample_spec"||e.mode!=="chat"&&e.mode!=="completion"||!e.input_cost_per_token&&!e.output_cost_per_token)return null;const r=e.litellm_provider??"",o=T[r];if(!o)return null;const c=M(n);if(!c)return null;const a=e.label??e.name??e.display_name??c,s=e.max_input_tokens??e.max_tokens??128e3,i=Math.round((e.input_cost_per_token??0)*1e6*100)/100,d=Math.round((e.output_cost_per_token??0)*1e6*100)/100,m={streaming:!0,toolCalling:e.supports_function_calling??e.supports_parallel_function_calling??!1,jsonMode:e.supports_response_schema??!1,vision:e.supports_vision??!1,multimodal:e.supports_vision??e.supports_audio_input??!1};return{modelId:c,providerType:o,name:a,contextWindow:Math.max(0,Math.round(s)),pricing:{inputTokens:i,outputTokens:d},capabilities:m}}async function W(){const e=(await b.get(v,{timeout:15e3})).data;if(typeof e!="object"||Array.isArray(e))throw new Error("Unexpected response format from LiteLLM model prices URL");const r=[],o=new Set,c=Object.entries(e).sort(([a],[s])=>a.length-s.length||a.localeCompare(s));for(const[a,s]of c){const i=P(a,s);if(!i)continue;const d=`${i.modelId}::${i.providerType}`;o.has(d)||(o.add(d),r.push(i))}return r}async function D(n,e){return(await n.search({index:k,body:{query:{term:{owner:e}},size:200,_source:["id","name","type"]}})).hits.hits.map(o=>({id:o._id,name:o._source?.name,type:o._source?.type}))}async function z(n,e){return(await n.search({index:f,body:{query:{term:{owner:e}},size:1e3,_source:["id","modelId","name","providerId","pricing","contextWindow"]}})).hits.hits.map(o=>({id:o._id,modelId:o._source?.modelId,name:o._source?.name,providerId:o._source?.providerId,pricing:o._source?.pricing,contextWindow:o._source?.contextWindow}))}function R(n,e){const r=[];n.contextWindow&&e.contextWindow&&Math.abs(n.contextWindow-e.contextWindow)>0&&r.push("contextWindow");const o=e.pricing?.inputTokens??0,c=e.pricing?.outputTokens??0;return Math.abs(n.pricing.inputTokens-o)>.001&&r.push("pricing.inputTokens"),Math.abs(n.pricing.outputTokens-c)>.001&&r.push("pricing.outputTokens"),e.name&&n.name&&n.name!==e.name&&r.push("name"),r}async function A(n,e){const r=await W(),o=await D(n,e),c=new Map;for(const t of o){const p=I(t.type);c.has(p)||c.set(p,{id:t.id,name:t.name})}const a=await z(n,e),s=new Map;for(const t of o)s.set(t.id,I(t.type));const i=new Map;for(const t of a){const p=s.get(t.providerId)??"",u=`${t.modelId}::${p}`;i.has(u)||i.set(u,t)}const d=[],m=[],_=new Set;let y=0,h=0;for(const t of r){const p=c.get(t.providerType);if(!p){y++;continue}h++;const u=`${t.modelId}::${t.providerType}`;_.add(u);const l=i.get(u);if(!l)d.push({incoming:t,providerId:p.id,providerName:p.name});else{const g=R(t,l);g.length>0&&m.push({incoming:t,providerId:p.id,providerName:p.name,existingId:l.id,changedFields:g,existingPricing:l.pricing,existingContextWindow:l.contextWindow})}}const x=[];for(const t of a){const p=s.get(t.providerId)??"",u=`${t.modelId}::${p}`;if(!_.has(u)){const l=o.find(g=>g.id===t.providerId);x.push({id:t.id,modelId:t.modelId,name:t.name,providerId:t.providerId,providerName:l?.name??t.providerId})}}return{toAdd:d,toUpdate:m,toDeprecate:x,source:{fetched:r.length,matched:h,skipped:y}}}async function C(n,e,r,o){const c=new Date().toISOString(),a=[];for(const s of r){const i=s.incoming,d=`${e}_${i.modelId}_${i.providerType}`;a.push({index:{_index:f,_id:d}},{id:d,providerId:s.providerId,name:i.name,modelId:i.modelId,contextWindow:i.contextWindow,capabilities:i.capabilities,pricing:{inputTokens:i.pricing.inputTokens,outputTokens:i.pricing.outputTokens,currency:"USD"},enabled:!0,owner:e,metadata:{tags:["synced","llm-prices"]},createdAt:c,updatedAt:c})}for(const s of o){const i=s.incoming,d=s.existingId;a.push({update:{_index:f,_id:d}},{doc:{name:i.name,contextWindow:i.contextWindow,capabilities:i.capabilities,pricing:{inputTokens:i.pricing.inputTokens,outputTokens:i.pricing.outputTokens,currency:"USD"},updatedAt:c}})}return a.length===0?{added:0,updated:0}:(await n.bulk({operations:a,refresh:!0}),{added:r.length,updated:o.length})}export{C as applySync,A as previewSync};
@@ -0,0 +1 @@
1
+ import*as s from"fs";import*as m from"path";import*as d from"js-yaml";const y="/root/integrations/packages";class M{loadPackageManifest(a,e){try{const t=m.join(y,a,"manifest.yml");if(!s.existsSync(t))return console.warn(`Manifest not found: ${t}`),null;const n=s.readFileSync(t,"utf8");return d.load(n)}catch(t){return console.error(`Error loading package manifest for ${a}:`,t),null}}loadDataStreamManifests(a){const e=new Map;try{const t=m.join(y,a,"data_stream");if(!s.existsSync(t))return console.warn(`Data streams directory not found: ${t}`),e;const n=s.readdirSync(t,{withFileTypes:!0}).filter(r=>r.isDirectory()).map(r=>r.name);for(const r of n){const i=m.join(t,r,"manifest.yml");if(s.existsSync(i)){const f=s.readFileSync(i,"utf8"),c=d.load(f);e.set(r,c)}}}catch(t){console.error(`Error loading data stream manifests for ${a}:`,t)}return e}getPackageDetails(a,e){const t=this.loadPackageManifest(a,e);if(!t)return null;const n=this.loadDataStreamManifests(a),r=t.policy_templates.map(i=>{const f=i.inputs.map(c=>{const g=[];return n.forEach((o,p)=>{const l=o.streams.find(u=>u.input===c.type);l&&g.push({id:p,title:l.title||o.title,description:l.description||o.title,type:o.type,dataset:o.dataset||`${a}.${p}`,vars:l.vars||[]})}),{...c,data_streams:g}});return{...i,inputs:f}});return{name:t.name,title:t.title,version:t.version,description:t.description,vars:t.vars||[],policy_templates:r}}}export{M as ManifestLoader};
@@ -0,0 +1 @@
1
+ import{Client as h}from"@elastic/elasticsearch";const S=process.env.ELASTICSEARCH_HOST||"https://51.159.174.230:9205",f=process.env.ELASTICSEARCH_USER||"elastic",C=process.env.ELASTICSEARCH_PASSWORD||"",g=".stkxp_platforms",d=new h({node:S,auth:{username:f,password:C},tls:{rejectUnauthorized:!1},requestTimeout:6e4,maxRetries:3}),P={term:{type:"MCPServer"}};function y(t){const r=t._source??t,e=r.config??{};return{id:t._id??r.id,name:r.name,description:r.description,enabled:r.enabled,owner:r.owner,url:e.url,authKey:e.authKey,packageName:e.packageName,namespace:e.namespace,protocol:e.protocol,type:e.serverType,headers:e.headers??{},queryParams:e.queryParams??{},createdAt:r.created,updatedAt:r.updated}}async function v(){try{console.log("[MCP Service] Fetching active MCPServer platforms from Elasticsearch...");const r=(await d.search({index:g,body:{query:{bool:{must:[P,{term:{enabled:!0}}]}},size:100,sort:[{created:{order:"desc",unmapped_type:"date"}}]}})).hits.hits.map(y);return console.log(`[MCP Service] Found ${r.length} active MCPServer platform(s)`),r.map(e=>{let i=e.url??"";const n=e.queryParams||{};if(Object.keys(n).length>0)try{const a=new URL(i);Object.entries(n).forEach(([c,p])=>a.searchParams.set(c,p)),i=a.toString()}catch{}const l=e.headers||{},m=Object.keys(l).some(a=>a.toLowerCase()==="authorization");return{url:i,protocol:e.protocol||"http",type:e.type||"remote",headers:{...e.authKey&&!m?{authorization:`ApiKey ${e.authKey}`}:{},...l}}})}catch(t){if(console.error("[MCP Service] Error fetching MCPServer platforms:",t.message),t.meta?.statusCode===404)return console.log("[MCP Service] Index not found, returning empty list"),[];throw t}}async function w(){try{const t=await v();return t.length===0&&(console.warn("[MCP Service] No active MCPServer platforms found"),console.warn("[MCP Service] Please configure MCP servers via the Platforms UI")),t}catch(t){throw console.error("[MCP Service] Error fetching MCPServer configs:",t),new Error("Failed to load MCP server configuration. Please check Elasticsearch connectivity.")}}async function E(t){try{const r=await d.get({index:g,id:t}),e=y({_id:r._id,_source:r._source}),{createMcpClient:i}=await import("../mcp/client"),n=await i(e.url??"",{headers:{Authorization:`ApiKey ${e.authKey}`},transportType:e.protocol||"http",timeout:1e4}),m=((await Promise.race([n.client.listTools(),new Promise((o,s)=>setTimeout(()=>s(new Error("listTools timeout")),1e4))])).tools||[]).map(o=>({name:o.name,description:o.description,inputSchema:o.inputSchema})),a=n.client.getServerCapabilities();let c=[];if(a?.prompts)try{c=((await Promise.race([n.client.listPrompts(),new Promise((s,u)=>setTimeout(()=>u(new Error("listPrompts timeout")),1e4))])).prompts||[]).map(s=>({name:s.name,description:s.description,arguments:s.arguments}))}catch(o){console.warn(`[MCP Service] Failed to fetch prompts from ${e.name}: ${o.message}`)}let p=[];if(a?.resources)try{p=((await Promise.race([n.client.listResources(),new Promise((s,u)=>setTimeout(()=>u(new Error("listResources timeout")),1e4))])).resources||[]).map(s=>({uri:s.uri,name:s.name,description:s.description}))}catch(o){console.warn(`[MCP Service] Failed to fetch resources from ${e.name}: ${o.message}`)}return n.close&&await n.close(),{tools:m,prompts:c,resources:p,toolsCount:m.length,promptsCount:c.length,resourcesCount:p.length}}catch(r){throw console.error(`[MCP Service] Error fetching capabilities for server ${t}:`,r.message),r}}export{v as getActiveMcpServers,E as getMcpServerCapabilities,w as getMcpServerConfigs};
@@ -0,0 +1 @@
1
+ import{Client as b}from"@elastic/elasticsearch";const C=process.env.ELASTICSEARCH_HOST||"https://51.159.174.230:9205",x=process.env.ELASTICSEARCH_USER||"elastic",P=process.env.ELASTICSEARCH_PASSWORD||"",h=".stkxp_tools",R=".stkxp_assistants",E=".stkxp_prompts",A=".stkxp_resources",S=new b({node:C,auth:{username:x,password:P},tls:{rejectUnauthorized:!1},requestTimeout:6e4,maxRetries:3}),T=new b({node:C,auth:{username:x,password:P},tls:{rejectUnauthorized:!1},requestTimeout:6e4,maxRetries:3}),O=new b({node:C,auth:{username:x,password:P},tls:{rejectUnauthorized:!1},requestTimeout:6e4,maxRetries:3}),q=new b({node:C,auth:{username:x,password:P},tls:{rejectUnauthorized:!1},requestTimeout:6e4,maxRetries:3}),B=new Set(["by","of","the","from","for","in","on","at","to","a","an","and","or","with","per","over","all","top","total","count","type","types","log","logs","data","event","events","system","windows","security","terms","winlog"]);function D(e){return e.length>20&&!e.includes("_")}function L(e,n,o){const a=e.toLowerCase().replace(/[^a-z0-9]+/g,"_").slice(0,12),t=new Set(a.split("_").filter(r=>r.length>2)),m=n.toLowerCase().replace(/[^a-z0-9]+/g,"_").split("_").filter(r=>r.length>1&&!B.has(r)&&!t.has(r)),p=Buffer.from(o).toString("base64").replace(/[^a-z0-9]/gi,"").slice(0,6).toLowerCase(),c=64-a.length-1-1-p.length;let i="";for(const r of m){const u=i?`${i}_${r}`:r;if(u.length>c)break;i=u}return`${a}_${i||"tool"}_${p}`.slice(0,64)}function j(e,n){const o=e.name||"";if(!D(o))return o;const a=e.label||e.description||o,t=e.system||"";return L(t,a,n)}async function z(e,n){if(n.length!==0)try{const a=(await T.search({index:R,body:{query:{term:{"mcp_servers_policy.servers.name.keyword":e}},size:500,_source:["mcp_servers_policy"]}})).hits.hits;if(a.length===0)return;for(const t of a){const m=t._source,c=(m?.mcp_servers_policy?.servers||[]).map(i=>i.name!==e?i:{...i,excluded_tools:(i.excluded_tools||[]).filter(r=>!n.includes(r))});await T.update({index:R,id:t._id,body:{doc:{mcp_servers_policy:{...m.mcp_servers_policy,servers:c},updated_at:new Date().toISOString()}},refresh:!1})}console.log(`[MCP Sync] Cleaned ${n.length} removed tools from ${a.length} assistants`)}catch(o){console.error("[MCP Sync] Failed to clean removed tools from assistants:",o.message)}}function $(e){const n=e.config;let o=n.url;const a=n.queryParams||{};if(Object.keys(a).length>0){const c=new URL(o);Object.entries(a).forEach(([i,r])=>c.searchParams.set(i,r)),o=c.toString()}const t=n.headers||{},m=Object.keys(t).some(c=>c.toLowerCase()==="authorization"),p={...n.authKey&&!m?{authorization:`ApiKey ${n.authKey}`}:{},...t};return{serverUrl:o,headers:p,transportType:n.protocol||"http"}}async function X(e,n,o){const a=n.config,t=n.name,{createMcpClient:m}=await import("../mcp/client"),{serverUrl:p,headers:c,transportType:i}=$(n),r=await m(p,{headers:c,transportType:i,timeout:1e4});let u;try{u=(await r.client.listTools()).tools||[]}catch(s){throw await r.close(),new Error(`Cannot reach MCP server "${t}": ${s.message}`)}await r.close();const d=await S.search({index:h,body:{query:{bool:{must:[{term:{type:"mcp_remote"}},{term:{mcpServerId:e}}]}},_source:["name"],size:1e3}}),y=new Set(d.hits.hits.map(s=>s._source?.name).filter(Boolean)),f=new Set(u.map(s=>s.name)),w=[...y].filter(s=>!f.has(s));if(await S.deleteByQuery({index:h,body:{query:{bool:{must:[{term:{type:"mcp_remote"}},{term:{mcpServerId:e}}]}}},refresh:!0}),await z(t,w),u.length===0)return console.log(`[MCP Sync] No tools found for server "${t}" (${e})`),{synced:0};const l=a.packageName||t,g=new Date().toISOString(),v=u.flatMap(s=>[{index:{_index:h}},{name:s.name,label:s.name,description:s.description||"",type:"mcp_remote",system:l,mcpServerId:e,mcpServerName:t,mcpServerUrl:a.url,inputSchema:s.inputSchema?JSON.stringify(s.inputSchema):void 0,enabled:!0,owner:o,createdAt:g,updatedAt:g,createdBy:o,updatedBy:o}]);return await S.bulk({operations:v,refresh:!0}),console.log(`[MCP Sync] Synced ${u.length} tools for "${t}" (${e}), system="${l}"`),{synced:u.length}}function F(e){return e?e.startsWith("text/")||e==="application/json":!1}async function K(e,n,o){const a=n.name,{createMcpClient:t}=await import("../mcp/client"),{serverUrl:m,headers:p,transportType:c}=$(n),i=await t(m,{headers:p,transportType:c,timeout:1e4});let r;try{if(!i.client.getServerCapabilities()?.prompts)return{synced:0,skipped:!0};r=(await i.client.listPrompts()).prompts||[]}catch(y){throw new Error(`Cannot fetch prompts from MCP server "${a}": ${y.message}`)}finally{await i.close()}if(await O.deleteByQuery({index:E,body:{query:{bool:{must:[{term:{source:"mcp"}},{term:{mcpServerId:e}}]}}},refresh:!0}),r.length===0)return console.log(`[MCP Sync] No prompts found for server "${a}" (${e})`),{synced:0};const u=new Date().toISOString(),d=r.flatMap(y=>[{index:{_index:E}},{name:y.name,description:y.description||"",source:"mcp",mcpServerId:e,mcpServerName:a,tags:["mcp"],metadata:{argsSchema:y.arguments||[]},owner:o,created_at:u,updated_at:u}]);return await O.bulk({operations:d,refresh:!0}),console.log(`[MCP Sync] Synced ${r.length} prompts for "${a}" (${e})`),{synced:r.length}}async function J(e,n,o){const a=n.name,{createMcpClient:t}=await import("../mcp/client"),{serverUrl:m,headers:p,transportType:c}=$(n),i=await t(m,{headers:p,transportType:c,timeout:1e4});let r;try{if(!i.client.getServerCapabilities()?.resources)return{synced:0,skipped:!0};const f=(await i.client.listResources()).resources||[],w=new Date().toISOString();r=[];for(const l of f){let g;if(F(l.mimeType))try{g=(await i.client.readResource({uri:l.uri})).contents?.[0]?.text}catch(v){console.warn(`[MCP Sync] Failed to read resource "${l.uri}" from "${a}": ${v.message}`)}r.push({title:l.name||l.uri,description:l.description||"",uri:l.uri,mimeType:l.mimeType,type:"mcp_resource",source:"mcp",mcpServerId:e,mcpServerName:a,owner:o,created_at:w,updated_at:w,...g?{prompt_text:g,semantic_content:g}:{}})}}catch(d){throw new Error(`Cannot fetch resources from MCP server "${a}": ${d.message}`)}finally{await i.close()}if(await q.deleteByQuery({index:A,body:{query:{bool:{must:[{term:{source:"mcp"}},{term:{mcpServerId:e}}]}}},refresh:!0}),r.length===0)return console.log(`[MCP Sync] No resources found for server "${a}" (${e})`),{synced:0};const u=r.flatMap(d=>[{index:{_index:A}},d]);return await q.bulk({operations:u,refresh:!0}),console.log(`[MCP Sync] Synced ${r.length} resources for "${a}" (${e})`),{synced:r.length}}async function G(e){const{createMcpClient:n}=await import("../mcp/client"),{serverUrl:o,headers:a,transportType:t}=$(e),m=await n(o,{headers:a,transportType:t,timeout:1e4});try{const p=m.client.getServerCapabilities();let c=0;if(p?.prompts)try{c=((await m.client.listPrompts()).prompts||[]).length}catch(r){console.warn(`[MCP Sync] Failed to count prompts for "${e.name}": ${r.message}`)}let i=0;if(p?.resources)try{i=((await m.client.listResources()).resources||[]).length}catch(r){console.warn(`[MCP Sync] Failed to count resources for "${e.name}": ${r.message}`)}return{promptsSupported:!!p?.prompts,promptsCount:c,resourcesSupported:!!p?.resources,resourcesCount:i}}finally{await m.close()}}const N="stkxp";async function V(e,n,o){const t=n.config?.packageName||n.packageName||n.name,m=n.name,[p,c]=await Promise.all([S.search({index:h,body:{query:{bool:{must:[{term:{system:t}},{term:{owner:N}}]}},size:1e4,_source:["name","description"]}}),S.search({index:h,body:{query:{bool:{must:[{term:{system:t}},{term:{owner:o}}]}},size:1e4,_source:["name","description"]}})]),i=p.hits.hits.map(s=>({name:s._source?.name,description:s._source?.description})),r=c.hits.hits.map(s=>({name:s._source?.name,description:s._source?.description})),u=new Set(i.map(s=>s.name)),d=new Set(r.map(s=>s.name)),y=i.filter(s=>!d.has(s.name)),f=r.filter(s=>!u.has(s.name)),w=i.filter(s=>d.has(s.name)).length,l=new Set(f.map(s=>s.name)),v=(await T.search({index:R,body:{query:{term:{"mcp_servers_policy.servers.name.keyword":m}},size:500,_source:["name","mcp_servers_policy"]}})).hits.hits.map(s=>{const M=s._source,k=(M?.mcp_servers_policy?.servers||[]).find(_=>_.name===m)?.excluded_tools||[],U=k.filter(_=>l.has(_)),I=f.map(_=>_.name).filter(_=>!k.includes(_));return{id:s._id,name:M?.name||s._id,staleExclusions:U,lostTools:I}}).filter(s=>s.staleExclusions.length>0||s.lostTools.length>0);return{platform:{id:e,name:m,packageName:t},toolChanges:{added:y,removed:f,unchanged:w,total:i.length},affectedAssistants:v}}async function Y(e,n,o){const t=n.config?.packageName||n.packageName||n.name,m=n.name,p=await S.search({index:h,body:{query:{bool:{must:[{term:{system:t}},{term:{owner:N}}]}},size:1e4}}),c=p.hits.hits.map(l=>l._source),i=new Set(c.map(l=>l.name)),d=(await S.search({index:h,body:{query:{bool:{must:[{term:{system:t}},{term:{owner:o}}]}},_source:["name"],size:1e4}})).hits.hits.map(l=>l._source?.name).filter(Boolean).filter(l=>!i.has(l));if(await S.deleteByQuery({index:h,body:{query:{bool:{must:[{term:{system:t}},{term:{owner:o}}]}}},refresh:!0}),await z(m,d),c.length===0)return console.log(`[MCP Sync] No template tools found for packageName="${t}" (owner=${N})`),{synced:0,removed:d.length};const y=new Date().toISOString(),f=p.hits.hits,w=c.flatMap((l,g)=>[{index:{_index:h}},{...l,name:j(l,f[g]?._id??String(g)),owner:o,createdBy:o,updatedBy:o,updatedAt:y}]);return await S.bulk({operations:w,refresh:!0}),console.log(`[MCP Sync] Synced ${c.length} managed tools for "${m}" (packageName="${t}"), owner="${o}"`),{synced:c.length,removed:d.length}}async function Z(e,n){const[o,a]=await Promise.all([S.search({index:h,body:{query:{bool:{must:[{term:{type:"mcp_remote"}},{term:{mcpServerId:e}}]}},_source:["name"],size:200}}),T.search({index:R,body:{query:{term:{"mcp_servers_policy.servers.name.keyword":n}},_source:["name"],size:200}})]);return{tools:o.hits.hits.map(t=>({id:t._id,name:t._source?.name||t._id})),assistants:a.hits.hits.map(t=>({id:t._id,name:t._source?.name||t._id}))}}export{N as TEMPLATE_OWNER,$ as buildRemoteMcpConnection,Z as getMcpPlatformImpact,G as getRemoteMcpCapabilityCounts,V as previewManagedSync,Y as syncManagedToolsForPlatform,K as syncRemotePromptsForPlatform,J as syncRemoteResourcesForPlatform,X as syncRemoteToolsForPlatform};
@@ -0,0 +1 @@
1
+ import{createMcpClient as i}from"../mcp/client";import{config as l}from"../config";class a{mcpUrl;constructor(s){this.mcpUrl=s||l.mcpUrl||process.env.MCP_URL||"",this.mcpUrl||(console.warn("[MCP Tools Service] No MCP_URL configured. MCP tools will not be available."),console.warn("[MCP Tools Service] Please configure MCP servers via Settings UI."))}async listTools(s){if(process.env.TOOLS_URL)try{console.log(`[TOOLS] Fetching tools from ${process.env.TOOLS_URL}`);const e=await fetch(process.env.TOOLS_URL,{method:"GET",headers:{Authorization:`ApiKey ${process.env.MCP_AUTH||""}`,"Content-Type":"application/json"}});if(!e.ok)throw new Error(`HTTP ${e.status}: ${e.statusText}`);const t=await e.json(),o=(t.results||t.tools||t||[]).map(n=>({name:n.id||n.name,description:n.description||"",inputSchema:n.configuration?.schema||n.inputSchema||null,outputSchema:n.outputSchema||null}));return console.log(`[TOOLS] Successfully loaded ${o.length} tools from TOOLS_URL`),{success:!0,tools:o,total:o.length}}catch(e){return console.error("[TOOLS] Failed to fetch tools from TOOLS_URL:",e.message),{success:!1,tools:[],total:0,error:e.message||"Failed to fetch tools from TOOLS_URL"}}if(!this.mcpUrl)return{success:!1,tools:[],total:0,error:"MCP server not configured. Please configure MCP servers via Settings UI."};let r;try{const e={};s&&(e.Authorization=`Bearer ${s}`),r=await i(this.mcpUrl,e);const c=((await r.client.listTools()).tools||[]).map(o=>({name:o.name,description:o.description,inputSchema:o.inputSchema,outputSchema:o.outputSchema||null}));return{success:!0,tools:c,total:c.length}}catch(e){return console.error("Error listing MCP tools:",e),{success:!1,tools:[],total:0,error:e.message||"Failed to list MCP tools"}}finally{if(r)try{await r.close()}catch(e){console.error("Error closing MCP client:",e)}}}async getTool(s,r){const e=await this.listTools(r);if(!e.success)return{success:!1,error:e.error};const t=e.tools.find(c=>c.name===s);return t?{success:!0,tool:t}:{success:!1,error:`Tool '${s}' not found`}}}const f=new a;export{a as McpToolsService,f as mcpToolsService};
@@ -0,0 +1,2 @@
1
+ import{Client as w}from"@elastic/elasticsearch";import{config as _}from"../config";import{stripLoneSurrogates as M,truncateUtf16Safe as C}from"../utils/text-utils";const i=new w(_.elasticsearch),a=".stkxp_memories",m=".multilingual-e5-small-elasticsearch";async function R(){try{if(await i.indices.exists({index:a}))return;await i.indices.create({index:a,body:{settings:{number_of_shards:1,number_of_replicas:1},mappings:{properties:{owner:{type:"keyword"},teamId:{type:"keyword"},memoryType:{type:"keyword"},tags:{type:"keyword"},text:{type:"text",copy_to:"text_semantic"},text_semantic:{type:"semantic_text",inference_id:m},sourceChatId:{type:"keyword"},sourceRunId:{type:"keyword"},createdAt:{type:"date"},updatedAt:{type:"date"},expiresAt:{type:"date"},salience:{type:"float"}}}}}),console.log(`[memories] Created index ${a} (inference: ${m})`)}catch(e){console.error("[memories] initializeMemoriesIndex failed:",e?.message??e)}}const u=new Map;function q(e){return u.get(e)}function S(e,t){u.set(e,t)}async function T(e){if(!e.owner||!e.query)return[];const t=[{term:{owner:e.owner}}];e.sourceChatId?t.push({term:{sourceChatId:e.sourceChatId}}):e.teamId&&t.push({term:{teamId:e.teamId}}),e.memoryType&&t.push({term:{memoryType:e.memoryType}});const r=[];!e.includeChatTraces&&e.memoryType!=="chat_trace"&&r.push({term:{memoryType:"chat_trace"}}),e.excludeMemoryIds&&e.excludeMemoryIds.length>0&&r.push({ids:{values:e.excludeMemoryIds}});try{return((await i.search({index:a,body:{size:e.k??5,retriever:{rrf:{retrievers:[{standard:{query:{bool:{must:[{semantic:{field:"text_semantic",query:e.query}}],filter:t,must_not:r}}}},{standard:{query:{bool:{must:[{multi_match:{query:e.query,fields:["text"]}}],filter:t,must_not:r}}}}],rank_window_size:50,rank_constant:20}}}})).hits?.hits??[]).map(n=>({id:n._id,...n._source,score:typeof n._score=="number"?n._score:void 0}))}catch(s){return console.error("[memories] searchMemoriesRRF failed:",s?.message??s),[]}}async function v(e,t,r={}){const{teamId:s,sourceChatId:n,k:g=5,maxCharsPerMemory:d=600,includeChatTraces:x,excludeMemoryIds:h}=r,l=await T({owner:e,query:t,k:g,teamId:s??null,sourceChatId:n??null,includeChatTraces:x,excludeMemoryIds:h});if(l.length===0)return null;const y=["[Long-term memory recall \u2014 relevant to the current question]"];for(const o of l){const f=o.createdAt?new Date(o.createdAt).toISOString().slice(0,10):"",I=o.tags&&o.tags.length?` (${o.tags.join(", ")})`:"",c=M((o.text||"").replace(/\s+/g," ").trim()),p=c.length>d?C(c,d)+"\u2026":c;y.push(`- ${f}${I}: ${p}`)}return y.join(`
2
+ `)}async function E(e){if(!e.owner||!e.text)return null;const t=new Date().toISOString(),r={owner:e.owner,teamId:e.teamId??null,memoryType:e.memoryType??"context",tags:e.tags??[],text:e.text,sourceChatId:e.sourceChatId??null,createdAt:t,updatedAt:t};typeof e.salience=="number"&&(r.salience=e.salience);try{return{id:(await i.index({index:a,body:r,refresh:"wait_for"}))._id}}catch(s){return console.error("[memories] saveMemoryDoc failed:",s?.message??s),null}}export{a as MEMORIES_INDEX,m as MEMORIES_INFERENCE_ID,v as buildLTMContext,q as getLastChatTraceId,R as initializeMemoriesIndex,E as saveMemoryDoc,T as searchMemoriesRRF,S as setLastChatTraceId};
@@ -0,0 +1 @@
1
+ import{Client as q}from"@elastic/elasticsearch";import{config as z}from"../config";const B=new q(z.elasticsearch),Q=".stkxp_memories",C=".stkxp_chat_tools",j=["memory_save","memory_search","memory_list","memory_delete"];function S(t){return t.toISOString().slice(0,10)}function O(t){if(t==null)return null;if(typeof t=="object")return t;if(typeof t=="string")try{return JSON.parse(t)}catch{return null}return null}function L(t){const e=O(t);if(!e)return null;if(e.ok!==void 0||e.count!==void 0||e.memories)return e;if(Array.isArray(e.content)){const o=e.content.find(s=>typeof s?.text=="string");if(o)try{return JSON.parse(o.text)}catch{return null}}return null}async function J(t){try{const e=await B.search({index:Q,body:{size:0,query:{term:{owner:t}},aggs:{by_type:{terms:{field:"memoryType",size:10}},by_tag:{terms:{field:"tags",size:15}},scoped:{filter:{exists:{field:"teamId"}}}}}}),o=e.aggregations??{},s=typeof e.hits.total=="object"?Number(e.hits.total.value||0):Number(e.hits.total||0),u=(o.by_type?.buckets||[]).map(a=>({memoryType:a.key,count:a.doc_count})),y=(o.by_tag?.buckets||[]).map(a=>({tag:a.key,count:a.doc_count})),m=Number(o.scoped?.doc_count||0),d=Math.max(s-m,0);return{totalMemories:s,byMemoryType:u,byTag:y,scopedMemories:m,unscopedMemories:d}}catch(e){if(e?.meta?.statusCode===404)return{totalMemories:0,byMemoryType:[],byTag:[],scopedMemories:0,unscopedMemories:0};throw e}}async function X(t,e){const o=[{term:{username:t}}];e&&o.push({range:{createdAt:{gte:e.start,lte:e.end}}});const s=await B.search({index:C,body:{query:{bool:{must:o}},size:5e3,_source:["tools","createdAt"],sort:[{createdAt:"desc"}]}}),u=new Map,y=new Map,m=new Map;let d=0,a=0,T=0,x=0,_=0,f=0,l=0;for(const n of s.hits.hits){const r=n._source,P=Array.isArray(r.tools)?r.tools:[];for(const p of P){const g=p?.name;if(!g||!j.includes(g))continue;const R=p.timestamp||r.createdAt,A=S(R?new Date(R):new Date),M=u.get(A)??{saves:0,searches:0};switch(g){case"memory_save":{d+=1,M.saves+=1;break}case"memory_search":{a+=1,M.searches+=1,l+=1;const i=L(p.output);if(i?.ok===!1)break;const I=typeof i?.count=="number"?i.count:Array.isArray(i?.memories)?i.memories.length:0;f+=I,I===0&&(_+=1);const v=O(p.input),h=v?.query||v?.q;if(typeof h=="string"&&h.trim()){const c=h.trim().slice(0,200);y.set(c,(y.get(c)??0)+1)}const E=Array.isArray(i?.memories)?i.memories:[];for(const c of E){const k=c?.id||c?._id;if(!k)continue;const w=typeof c?.text=="string"?c.text.slice(0,200):"",b=m.get(k)??{text:w,count:0};b.count+=1,!b.text&&w&&(b.text=w),m.set(k,b)}break}case"memory_list":T+=1;break;case"memory_delete":x+=1;break}u.set(A,M)}}const W=Array.from(u.entries()).map(([n,r])=>({date:n,...r})).sort((n,r)=>n.date<r.date?-1:1),D=Array.from(y.entries()).map(([n,r])=>({query:n,count:r})).sort((n,r)=>r.count-n.count).slice(0,10),N=Array.from(m.entries()).map(([n,r])=>({memoryId:n,text:r.text,count:r.count})).sort((n,r)=>r.count-n.count).slice(0,10);return{daily:W,savesInWindow:d,searchesInWindow:a,listsInWindow:T,deletesInWindow:x,emptyRecallRate:l>0?_/l:0,avgRecallSize:l>0?f/l:0,totalRecalled:f,topQueries:D,topReusedMemories:N}}async function U(t,e){const[o,s]=await Promise.all([J(t),X(t,e)]);return{windowStart:e?.start,windowEnd:e?.end,...o,...s}}export{U as getMemoryAnalyticsReport};
@@ -0,0 +1 @@
1
+ import{Client as Y}from"@elastic/elasticsearch";import{config as Q}from"../config";import{getRecentRuns as W}from"./monitoring-service";import{loadModelIdPricingTable as x,estimateCostByModelId as V,invalidateModelIdPricingCache as Z}from"./llm-pricing-service";import{getTraceByRunId as tt}from"./chat-traces-service";const N=new Y(Q.elasticsearch),j=".stkxp_chat_runs",E=".stkxp_chat_tools",B=".stkxp_chat_llms",st=".stkxp_tools",nt=".stkxp_graphs",ot=".stkxp_chats",et=".stkxp_assistants";function $(o){return o.source==="playground"||o.teamId==="playground"}function rt(o,c){const s=[];return o&&s.push({range:{startTime:{gte:o.start,lte:o.end}}}),c&&s.push({term:{username:c}}),s}function at(o,c){const s=[];return o&&s.push({range:{createdAt:{gte:o.start,lte:o.end}}}),c&&s.push({term:{username:c}}),s}const yt=Z,_=(o,c,s,m)=>V(c,s,m);function X(o){return o.startsWith("mcp__")&&o.split("__")[1]||o}function it(o){return o.startsWith("mcp__")&&o.split("__")[2]||o}function D(o){const c=[...o].sort((r,k)=>(k.createdAt||"").localeCompare(r.createdAt||"")),s=new Set,m=[];for(const r of c){const k=r.runId||"",p=Array.isArray(r.llms)?r.llms:[];for(let a=0;a<p.length;a++){const l=p[a],n=l.callId,d=n?`${k}:${n}`:`${k}:${l.provider||""}:${l.modelId||""}:${l.startTime||a}`;s.has(d)||(s.add(d),m.push({runId:k,chatId:r.chatId,teamId:r.teamId,assistantId:r.assistantId,provider:l.provider||"unknown",modelId:l.modelId||"unknown",inputTokens:l.inputTokens||0,outputTokens:l.outputTokens||0,totalTokens:l.totalTokens||(l.inputTokens||0)+(l.outputTokens||0),duration:typeof l.duration=="number"?l.duration:void 0,callId:n,createdAt:r.createdAt}))}}return m}let q={},F=0;const lt=300*1e3;async function K(){const o=Date.now();if(o-F<lt&&Object.keys(q).length>0)return q;try{const c=await N.search({index:st,body:{query:{match_all:{}},size:1e4,_source:["name","system"]}}),s={};for(const m of c.hits.hits){const r=m._source;r?.name&&r?.system&&(s[r.name]=r.system)}return q=s,F=o,s}catch(c){return c?.meta?.body?.error?.type==="index_not_found_exception"?{}:(console.error("[monitoring] Failed to load tool system map:",c?.message),q)}}async function O(o,c){const s=rt(o,c);return(await N.search({index:j,body:{query:s.length>0?{bool:{must:s}}:{match_all:{}},size:5e3,sort:[{startTime:"desc"}]}})).hits.hits.map(r=>({id:r._id,...r._source}))}async function U(o,c){const s=at(o,c);return(await N.search({index:E,body:{query:s.length>0?{bool:{must:s}}:{match_all:{}},size:5e3}})).hits.hits.map(r=>({id:r._id,...r._source}))}async function L(o,c){const s=[];o&&s.push({range:{createdAt:{gte:o.start,lte:o.end}}}),c&&s.push({term:{username:c}});try{return(await N.search({index:B,body:{query:s.length>0?{bool:{must:s}}:{match_all:{}},size:5e3,sort:[{createdAt:"desc"}]}})).hits.hits.map(r=>({id:r._id,...r._source}))}catch(m){if(m?.meta?.body?.error?.type==="index_not_found_exception")return[];throw m}}async function G(o,c){const s=[];o&&s.push({range:{updatedAt:{gte:o.start,lte:o.end}}}),c&&s.push({term:{username:c}});try{return(await N.search({index:ot,body:{query:s.length>0?{bool:{must:s}}:{match_all:{}},size:5e3,_source:["teamId","teamName","assistants","username","updatedAt"]}})).hits.hits.map(r=>({id:r._id,...r._source}))}catch(m){if(m?.meta?.body?.error?.type==="index_not_found_exception")return[];throw m}}async function H(){try{const o=await N.search({index:et,body:{query:{match_all:{}},size:1e3,_source:["name","topic","metadata.status","graphId"]}}),c={};for(const s of o.hits.hits){const m=s._source;c[s._id]={name:m.name||s._id,status:m.metadata?.status||"unknown",topic:m.topic||void 0,graphId:m.graphId||void 0}}return c}catch(o){return o?.meta?.body?.error?.type==="index_not_found_exception"?{}:(console.error("[monitoring] Failed to load assistant catalog:",o?.message),{})}}async function ut(o,c){try{const{runs:s}=await W(0,1e3,c);let m=s;if(o){const p=new Date(o.start).getTime(),a=new Date(o.end).getTime();m=s.filter(l=>{const n=new Date(l.startTime).getTime();return n>=p&&n<=a})}const r={};return m.forEach(p=>{p.llmUsage.forEach(l=>{const n=`${l.provider}:${l.model}`;r[n]||(r[n]={calls:0,inputTokens:0,outputTokens:0,totalTokens:0,totalResponseTime:0,totalCost:0}),r[n].calls+=1,r[n].inputTokens+=l.inputTokens,r[n].outputTokens+=l.outputTokens,r[n].totalTokens+=l.totalTokens,r[n].totalResponseTime+=p.duration||0});const a=p.estimatedCost||0;if(p.llmUsage.length>0){const l=a/p.llmUsage.length;p.llmUsage.forEach(n=>{const d=`${n.provider}:${n.model}`;r[d]&&(r[d].totalCost+=l)})}}),{llms:Object.entries(r).map(([p,a])=>{const[l,n]=p.split(":");return{provider:l,model:n,calls:a.calls,inputTokens:a.inputTokens,outputTokens:a.outputTokens,totalTokens:a.totalTokens,avgResponseTime:a.calls>0?a.totalResponseTime/a.calls:0,totalCost:a.totalCost}})}}catch(s){throw console.error("Error getting LLM stats:",s),s}}async function Tt(o,c){try{const{llms:s}=await ut(o,c),m=s.map(a=>({provider:a.provider,model:a.model,cost:a.totalCost,calls:a.calls})),r={};s.forEach(a=>{r[a.provider]||(r[a.provider]={cost:0,calls:0}),r[a.provider].cost+=a.totalCost,r[a.provider].calls+=a.calls});const k=Object.entries(r).map(([a,l])=>({provider:a,cost:l.cost,calls:l.calls})),p=s.reduce((a,l)=>a+l.totalCost,0);return{byModel:m,byProvider:k,total:p}}catch(s){throw console.error("Error getting LLM costs:",s),s}}async function ht(o,c){try{const s=[];o&&s.push({range:{createdAt:{gte:o.start,lte:o.end}}}),c&&s.push({term:{username:c}});const m=await N.search({index:E,body:{query:s.length>0?{bool:{must:s}}:{match_all:{}},size:1e3}}),r={};return m.hits.hits.forEach(p=>{const a=p._source;a.tools&&Array.isArray(a.tools)&&a.tools.forEach(l=>{const n=l.name;r[n]||(r[n]={totalCalls:0,successCount:0,totalDuration:0,failureCount:0}),r[n].totalCalls+=1,l.status==="success"?r[n].successCount+=1:(l.status==="error"||l.status==="failed")&&(r[n].failureCount+=1),l.duration&&(r[n].totalDuration+=l.duration)})}),{tools:Object.entries(r).map(([p,a])=>({name:p,toolName:p,totalCalls:a.totalCalls,successRate:a.totalCalls>0?a.successCount/a.totalCalls*100:0,avgDuration:a.totalCalls>0?a.totalDuration/a.totalCalls:0,failureCount:a.failureCount}))}}catch(s){throw console.error("Error getting tools stats:",s),s}}async function kt(o,c,s,m){try{const{runs:r}=await W(0,1e3,m);let k=r.filter(f=>f.llmUsage.some(y=>y.provider===o&&y.model===c));if(s){const f=new Date(s.start).getTime(),y=new Date(s.end).getTime();k=k.filter(h=>{const R=new Date(h.startTime).getTime();return R>=f&&R<=y})}const p={};let a=0,l=0,n=0;return k.forEach(f=>{const y=new Date(f.startTime).toISOString().slice(0,13)+":00:00";p[y]||(p[y]={calls:0,cost:0,totalDuration:0});const h=f.llmUsage.filter(R=>R.provider===o&&R.model===c).length;h>0&&(p[y].calls+=h,p[y].cost+=(f.estimatedCost||0)/f.llmUsage.length,p[y].totalDuration+=f.duration||0,a+=h,l+=(f.estimatedCost||0)/f.llmUsage.length,n+=f.duration||0)}),{callsOverTime:Object.entries(p).map(([f,y])=>({timestamp:f,calls:y.calls,cost:y.cost})).sort((f,y)=>f.timestamp.localeCompare(y.timestamp)),avgResponseTime:a>0?n/a:0,totalCalls:a,totalCost:l}}catch(r){throw console.error("Error getting LLM performance:",r),r}}async function Ct(o,c){return{}}async function vt(o,c){try{const[s,m,r]=await Promise.all([O(o,c),L(o,c),o?L(void 0,c):Promise.resolve(null)]);let k=0,p=0,a=0,l=0,n=0,d=0;for(const e of s){k+=1;const b=e.status||"";b==="success"?p+=1:b==="error"&&(a+=1),typeof e.duration=="number"&&e.duration>0&&(l+=e.duration,n+=1)}const f=new Set(m.map(e=>e.runId).filter(Boolean));p===0&&k>0&&(p=f.size,a=Math.max(0,k-p));let y=0,h=0,R=0;const t=new Set,u={};for(const e of s)e.runId&&(u[e.runId]=e.source==="generator"||e.source==="playground"?e.source:"chat");const i={chat:0,playground:0,generator:0};await x();const g={},T=D(m);for(const e of T){y+=e.inputTokens,h+=e.outputTokens,R+=1,t.add(`${e.provider}:${e.modelId}`);const b=await _(e.provider,e.modelId,e.inputTokens,e.outputTokens);d+=b;const v=e.runId&&u[e.runId]||"chat";i[v]+=b,e.runId&&typeof e.duration=="number"&&e.duration>0&&(g[e.runId]=(g[e.runId]||0)+e.duration)}if(n===0){const e=Object.values(g);e.length>0&&(l=e.reduce((b,v)=>b+v,0),n=e.length)}const w=r??m,C=new Set;for(const e of D(w))C.add(`${e.provider}:${e.modelId}`);const I={};for(const e of s){const b=(e.startTime||e.createdAt||"").slice(0,10);b&&(I[b]||(I[b]={date:b,runs:0,completed:0,failed:0,cost:0,inputTokens:0,outputTokens:0}),I[b].runs+=1,f.has(e.runId)?I[b].completed+=1:I[b].failed+=1)}for(const e of T){const b=(e.createdAt||"").slice(0,10);!b||!I[b]||(I[b].inputTokens+=e.inputTokens,I[b].outputTokens+=e.outputTokens,I[b].cost+=await _(e.provider,e.modelId,e.inputTokens,e.outputTokens))}const A=Object.values(I).sort((e,b)=>e.date.localeCompare(b.date));return{totalRuns:k,completedRuns:p,failedRuns:a,runningRuns:Math.max(0,k-p-a),avgDuration:n>0?l/n:0,avgInputTokens:R>0?Math.round(y/R):0,avgOutputTokens:R>0?Math.round(h/R):0,activeLLMs:t.size,totalActiveLLMs:C.size,totalCost:d,costBySource:i,timeseries:A}}catch(s){throw console.error("Error getting overview stats:",s),s}}async function It(o,c){try{const s=await L(o,c),m=o?await L(void 0,c):s,r={},k=new Set;for(const l of D(m))k.add(l.provider);await x();const p={};for(const l of D(s)){const n=l.provider;r[n]||(r[n]={calls:0,inputTokens:0,outputTokens:0,totalTokens:0},p[n]=0),r[n].calls+=1,r[n].inputTokens+=l.inputTokens,r[n].outputTokens+=l.outputTokens,r[n].totalTokens+=l.totalTokens,p[n]+=await _(n,l.modelId,l.inputTokens,l.outputTokens)}const a=Object.entries(r).map(([l,n])=>({provider:l,calls:n.calls,inputTokens:n.inputTokens,outputTokens:n.outputTokens,totalTokens:n.totalTokens,totalCost:p[l]??0,active:!0}));for(const l of k)r[l]||a.push({provider:l,calls:0,inputTokens:0,outputTokens:0,totalTokens:0,totalCost:0,active:!1});return{providers:a,activeCount:Object.keys(r).length,totalCount:k.size}}catch(s){throw console.error("Error getting LLM stats by provider:",s),s}}async function wt(o,c){try{const s=await L(o,c),m=o?await L(void 0,c):s,r={},k=new Set;for(const a of D(m))k.add(`${a.provider}:${a.modelId}`);for(const a of D(s)){const l=`${a.provider}:${a.modelId}`;r[l]||(r[l]={provider:a.provider,calls:0,inputTokens:0,outputTokens:0,totalTokens:0}),r[l].calls+=1,r[l].inputTokens+=a.inputTokens,r[l].outputTokens+=a.outputTokens,r[l].totalTokens+=a.totalTokens}const p=await Promise.all(Object.entries(r).map(async([a,l])=>{const n=a.indexOf(":"),d=n>=0?a.slice(n+1):a,f=await _(l.provider,d,l.inputTokens,l.outputTokens);return{provider:l.provider,model:d,calls:l.calls,inputTokens:l.inputTokens,outputTokens:l.outputTokens,totalTokens:l.totalTokens,totalCost:f,active:!0}}));for(const a of k)if(!r[a]){const l=a.indexOf(":"),n=l>=0?a.slice(0,l):"unknown",d=l>=0?a.slice(l+1):a;p.push({provider:n,model:d,calls:0,inputTokens:0,outputTokens:0,totalTokens:0,totalCost:0,active:!1})}return{models:p,activeCount:Object.keys(r).length,totalCount:k.size}}catch(s){throw console.error("Error getting LLM stats by model:",s),s}}async function Rt(o,c){try{const[s,m]=await Promise.all([U(o,c),K()]),r=o?await U(void 0,c):s,k=n=>m[n]||X(n),p={},a=new Set;for(const n of r){const d=Array.isArray(n.tools)?n.tools:[];for(const f of d)a.add(k(f.name||""))}for(const n of s){const d=Array.isArray(n.tools)?n.tools:[];for(const f of d){const y=k(f.name||"");p[y]||(p[y]={toolNames:new Set,totalCalls:0,successCount:0,totalDuration:0}),p[y].toolNames.add(f.name||""),p[y].totalCalls+=1,f.error||(p[y].successCount+=1),typeof f.duration=="number"&&f.duration>0&&(p[y].totalDuration+=f.duration)}}const l=Object.entries(p).map(([n,d])=>({server:n,toolsCount:d.toolNames.size,calls:d.totalCalls,successRate:d.totalCalls>0?d.successCount/d.totalCalls*100:0,avgDuration:d.totalCalls>0?d.totalDuration/d.totalCalls:0,active:!0}));return{servers:l,activeCount:l.length,totalCount:a.size}}catch(s){throw console.error("Error getting tools by server:",s),s}}async function St(o,c,s="all",m={}){try{const[r,k,p]=await Promise.all([U(o,c),K(),s!=="all"?O(o,c):Promise.resolve([])]),a=o?await U(void 0,c):r,l=new Map;if(s!=="all")for(const C of p)l.set(C.runId||C.id,$(C)?"playground":"chat");const n=C=>s==="all"?!0:(l.get(C.runId)??"chat")===s,d=C=>k[C]||X(C),f={},y=new Set;for(const C of a){const I=Array.isArray(C.tools)?C.tools:[];for(const A of I)A.name&&y.add(A.name)}for(const C of r){if(!n(C))continue;const I=Array.isArray(C.tools)?C.tools:[];for(const A of I){const e=A.name||"unknown",b=d(e);f[e]||(f[e]={server:b,description:A.description,totalCalls:0,successCount:0,totalDuration:0,totalInputSize:0,totalOutputSize:0}),f[e].totalCalls+=1,A.error||(f[e].successCount+=1),typeof A.duration=="number"&&A.duration>0&&(f[e].totalDuration+=A.duration),f[e].totalInputSize+=JSON.stringify(A.input||"").length,f[e].totalOutputSize+=JSON.stringify(A.output||"").length}}const h=Object.entries(f).map(([C,I])=>({toolName:I.description||it(C),server:I.server,calls:I.totalCalls,successRate:I.totalCalls>0?I.successCount/I.totalCalls*100:0,avgDuration:I.totalCalls>0?I.totalDuration/I.totalCalls:0,avgInputBytes:I.totalCalls>0?I.totalInputSize/I.totalCalls:0,avgOutputBytes:I.totalCalls>0?I.totalOutputSize/I.totalCalls:0,active:!0})),R=m.sortField??"calls",u=(m.sortDirection??"desc")==="asc"?1:-1;h.sort((C,I)=>{const A=C[R],e=I[R];return typeof A=="number"&&typeof e=="number"?(A-e)*u:String(A??"").localeCompare(String(e??""))*u});const i=h.length,g=Math.max(0,m.page??0),T=Math.max(1,Math.min(200,m.pageSize??25));return{tools:h.slice(g*T,g*T+T),activeCount:i,totalCount:y.size,totalTools:i,page:g,pageSize:T}}catch(r){throw console.error("Error getting tools by tool:",r),r}}async function J(){try{const o=await N.search({index:nt,body:{query:{match_all:{}},size:1e3,_source:["id","name"]}}),c={};for(const s of o.hits.hits){const m=s._source;m?.id&&m?.name&&(c[m.id]=m.name)}return c}catch(o){return o?.meta?.body?.error?.type==="index_not_found_exception"?{}:(console.error("[monitoring] Failed to load graph name map:",o?.message),{})}}async function Mt(o,c){try{const[s,m,r]=await Promise.all([O(o,c),L(o,c),J()]),k=o?await O(void 0,c):s;await x();const p={};for(const d of D(m))d.runId&&(p[d.runId]||(p[d.runId]={totalTokens:0,totalCost:0}),p[d.runId].totalTokens+=d.totalTokens,p[d.runId].totalCost+=await _(d.provider,d.modelId,d.inputTokens,d.outputTokens));const a={},l=new Set;for(const d of k){const f=d.graphId||"unknown";l.add(f)}for(const d of s){const f=d.graphId||"unknown";a[f]||(a[f]={runs:0,totalTokens:0,totalCost:0}),a[f].runs+=1;const y=p[d.runId];y&&(a[f].totalTokens+=y.totalTokens,a[f].totalCost+=y.totalCost)}const n=Object.entries(a).map(([d,f])=>({graphId:d,graphName:r[d]||d,runs:f.runs,avgTokens:f.runs>0?Math.round(f.totalTokens/f.runs):0,avgCost:f.runs>0?f.totalCost/f.runs:0,totalCost:f.totalCost,active:!0}));for(const d of l)a[d]||n.push({graphId:d,graphName:r[d]||d,runs:0,avgTokens:0,avgCost:0,totalCost:0,active:!1});return{graphs:n,activeCount:Object.keys(a).length,totalCount:l.size}}catch(s){throw console.error("Error getting graphs stats:",s),s}}async function At(o,c){try{const[s,m,r]=await Promise.all([G(o,c),L(o,c),H()]),k=o?await G(void 0,c):s,p={};for(const i of s){const T=(Array.isArray(i.assistants)?i.assistants:[]).map(w=>w.assistantId).filter(w=>w&&w!=="unknown");T.length>0&&(p[i.id]=T)}await x();const a={},l=D(m);for(const i of l){const g=await _(i.provider,i.modelId,i.inputTokens,i.outputTokens);if(g!==0){if(i.assistantId&&i.assistantId!=="unknown")a[i.assistantId]=(a[i.assistantId]||0)+g;else if(i.chatId){const T=p[i.chatId]||[];if(T.length>0){const w=g/T.length;for(const C of T)a[C]=(a[C]||0)+w}}}}const n=new Set;for(const i of k){const g=Array.isArray(i.assistants)?i.assistants:[];for(const T of g)T.assistantId&&T.assistantId!=="unknown"&&n.add(T.assistantId)}const d=await O(o,c),f={};for(const i of d){const g=i.assistantId,T=i.assistantName;g&&g!=="unknown"&&g!=="pending"&&T&&T!=="unknown"&&T!=="pending"&&T!=="team"&&(f[g]||(f[g]=T))}const y={};for(const i of d){const g=i.assistantId;g&&g!=="unknown"&&typeof i.duration=="number"&&i.duration>0&&(y[g]||(y[g]={total:0,count:0}),y[g].total+=i.duration,y[g].count+=1)}const h={};for(const i of l)!i.assistantId||i.assistantId==="unknown"||(h[i.assistantId]=(h[i.assistantId]||0)+i.inputTokens+i.outputTokens);const R={};for(const i of d){if(!$(i))continue;const g=i.assistantId;g&&g!=="unknown"&&g!=="pending"&&(R[g]=(R[g]||0)+1)}const t={};for(const i of s){const g=Array.isArray(i.assistants)?i.assistants:[];for(const T of g){const w=T.assistantId;if(!w||w==="unknown")continue;const C=r[w]?.name||f[w]||T.assistantName||w;t[w]||(t[w]={assistantName:C,runs:0,successCount:0}),t[w].runs+=1,T.success===!0&&(t[w].successCount+=1)}}const u=Object.entries(t).map(([i,g])=>{const T=a[i]||0;return{assistantId:i,assistantName:g.assistantName,runs:g.runs,playgroundRuns:R[i]||0,avgCost:g.runs>0?T/g.runs:0,totalCost:T,avgDuration:y[i]?y[i].total/y[i].count:0,avgTokens:g.runs>0?Math.round((h[i]||0)/g.runs):0,successRate:g.runs>0?g.successCount/g.runs*100:0,active:!0}});u.sort((i,g)=>g.runs-i.runs);for(const i of n)t[i]||u.push({assistantId:i,assistantName:r[i]?.name||f[i]||i,runs:0,playgroundRuns:R[i]||0,avgCost:0,totalCost:0,avgDuration:0,avgTokens:0,successRate:0,active:!1});return{assistants:u,activeCount:Object.keys(t).length,totalCount:n.size}}catch(s){throw console.error("Error getting assistants stats:",s),s}}async function Nt(o,c){try{const[s,m]=await Promise.all([G(o,c),L(o,c)]),r=o?await G(void 0,c):s,k={};for(const t of s)t.teamId&&t.teamId!=="unknown"&&(k[t.id]=t.teamId);await x();const p={},a=D(m);for(const t of a){const u=await _(t.provider,t.modelId,t.inputTokens,t.outputTokens);if(u!==0){if(t.teamId&&t.teamId!=="unknown")p[t.teamId]=(p[t.teamId]||0)+u;else if(t.chatId){const i=k[t.chatId];i&&(p[i]=(p[i]||0)+u)}}}const l=new Map;for(const t of r){const u=t.teamId;u&&u!=="unknown"&&l.set(u,t.teamName||u)}const n=await O(o,c),d={};for(const t of n){const u=t.teamId;u&&u!=="unknown"&&typeof t.duration=="number"&&t.duration>0&&(d[u]||(d[u]={total:0,count:0}),d[u].total+=t.duration,d[u].count+=1)}const f={};for(const t of a)!t.teamId||t.teamId==="unknown"||(f[t.teamId]||(f[t.teamId]={total:0,runs:0}),f[t.teamId].total+=t.inputTokens+t.outputTokens);const y={};for(const t of n){if(!$(t))continue;const u=t.teamId;u&&u!=="unknown"&&u!=="playground"&&(y[u]=(y[u]||0)+1)}const h={};for(const t of s){const u=t.teamId,i=t.teamName||u;if(!u||u==="unknown")continue;const g=Array.isArray(t.assistants)?t.assistants:[];if(g.length===0){h[u]||(h[u]={teamName:i,runs:0,successCount:0}),h[u].runs+=1;continue}for(const T of g)h[u]||(h[u]={teamName:i,runs:0,successCount:0}),h[u].runs+=1,T.success===!0&&(h[u].successCount+=1)}const R=Object.entries(h).map(([t,u])=>({teamId:t,teamName:u.teamName,runs:u.runs,playgroundRuns:y[t]||0,totalCost:p[t]||0,avgDuration:d[t]?d[t].total/d[t].count:0,avgTokens:f[t]&&u.runs>0?Math.round(f[t].total/u.runs):0,successRate:u.runs>0?u.successCount/u.runs*100:0,active:!0}));R.sort((t,u)=>u.runs-t.runs);for(const[t,u]of l)h[t]||R.push({teamId:t,teamName:u,runs:0,playgroundRuns:y[t]||0,totalCost:0,avgDuration:0,avgTokens:0,successRate:0,active:!1});return{teams:R,activeCount:Object.keys(h).length,totalCount:l.size}}catch(s){throw console.error("Error getting teams stats:",s),s}}async function _t(o,c){try{const s=await O(o,c),m={},r=[];for(const y of s){const h=y.status||"unknown";m[h]=(m[h]||0)+1,typeof y.duration=="number"&&y.duration>=0&&r.push(y.duration)}const k=s.length,p=Object.entries(m).map(([y,h])=>({status:y,count:h,percentage:k>0?h/k*100:0})),l=[{label:"0-1s",min:0,max:1e3},{label:"1-5s",min:1e3,max:5e3},{label:"5-15s",min:5e3,max:15e3},{label:"15-30s",min:15e3,max:3e4},{label:"30s-1m",min:3e4,max:6e4},{label:"1m+",min:6e4,max:1/0}].map(y=>({label:y.label,min:y.min,max:y.max===1/0?-1:y.max,count:r.filter(h=>h>=y.min&&h<y.max).length})),n=[...r].sort((y,h)=>y-h),d=y=>{if(n.length===0)return 0;const h=Math.floor(y/100*n.length);return n[Math.min(h,n.length-1)]},f=r.length>0?r.reduce((y,h)=>y+h,0)/r.length:0;return{total:k,byStatus:p,durationBuckets:l,p50:d(50),p95:d(95),avgDuration:f}}catch(s){throw console.error("Error getting runs distribution:",s),s}}async function xt(o,c,s=0,m=50){try{const[r,k]=await Promise.all([O(o,c),H()]),p=r.filter(n=>!$(n)),a=p.length;return await x(),{runs:await Promise.all(p.slice(s,s+m).map(async n=>{let d=typeof n.estimatedCost=="number"&&n.estimatedCost>0?n.estimatedCost:void 0;const f=Array.isArray(n.llmUsage)?n.llmUsage:[];if(d==null&&f.length>0){let t=0;const u=new Set;for(const i of f){if(i.callId){if(u.has(i.callId))continue;u.add(i.callId)}t+=await _(i.provider||"",i.modelId||i.model||"",i.inputTokens||0,i.outputTokens||0)}t>0&&(d=t)}const y=new Map;for(const t of f){const u=t.assistantId||"",i=t.assistantName||"";if(!(!i||i==="team"||u.startsWith("team-"))&&!y.has(u||i)){const g=u?k[u]?.topic:void 0;y.set(u||i,{assistantName:i,topic:g})}}const h=y.size>0?[...y.values()]:void 0,R=n.topic||(n.assistantId&&!String(n.assistantId).startsWith("team-")?k[n.assistantId]?.topic:void 0);return{id:n.id,runId:n.runId||n.id,chatId:n.chatId||"",status:n.status||"unknown",startTime:n.startTime||"",duration:typeof n.duration=="number"?n.duration:void 0,teamName:n.teamName,assistantName:n.assistantName,subAssistants:h,graphId:n.graphId,username:n.username,topic:R,totalTokens:typeof n.totalTokens=="number"?n.totalTokens:void 0,estimatedCost:d,toolCallsCount:typeof n.toolCallsCount=="number"?n.toolCallsCount:void 0}})),total:a}}catch(r){throw console.error("Error getting runs list:",r),r}}async function Dt(o){try{const s=(await N.search({index:j,body:{query:{term:{runId:o}},size:1}})).hits.hits[0];if(!s)return null;const m={id:s._id,...s._source};let r=[];try{r=(await N.search({index:B,body:{query:{term:{runId:o}},size:100}})).hits.hits.map(b=>b._source)}catch(e){if(e?.meta?.body?.error?.type!=="index_not_found_exception")throw e}let k=[];try{k=(await N.search({index:E,body:{query:{term:{runId:o}},size:10}})).hits.hits.map(b=>b._source)}catch(e){if(e?.meta?.body?.error?.type!=="index_not_found_exception")throw e}const[p,a,l]=await Promise.all([tt(o),H(),J()]);await x();const n=new Set,d={},f=[...r].sort((e,b)=>(e.createdAt||"").localeCompare(b.createdAt||""));for(const e of f){const b=Array.isArray(e.llms)?e.llms:[];for(const v of b){if(v.callId){if(n.has(v.callId))continue;n.add(v.callId)}const S=`${v.provider||"unknown"}:${v.modelId||"unknown"}`;d[S]||(d[S]={calls:0,inputTokens:0,outputTokens:0,totalTokens:0,cost:0,totalDuration:0}),d[S].calls+=1,d[S].inputTokens+=v.inputTokens||0,d[S].outputTokens+=v.outputTokens||0,d[S].totalTokens+=(v.inputTokens||0)+(v.outputTokens||0),d[S].cost+=await _(v.provider||"",v.modelId||"",v.inputTokens||0,v.outputTokens||0),typeof v.duration=="number"&&(d[S].totalDuration+=v.duration)}}const y=Object.entries(d).map(([e,b])=>{const v=e.indexOf(":"),S=e.slice(0,v),M=e.slice(v+1);return{provider:S,modelId:M,...b,avgDuration:b.calls>0?Math.round(b.totalDuration/b.calls):0}}),h=new Set,R={},t=[...k].sort((e,b)=>(e.createdAt||"").localeCompare(b.createdAt||""));for(const e of t){const b=Array.isArray(e.tools)?e.tools:[];for(const v of b){const S=`${v.name||""}:${v.timestamp||""}`;if(v.timestamp){if(h.has(S))continue;h.add(S)}const M=v.name||"unknown";R[M]||(R[M]={calls:0,successCount:0,totalDuration:0}),R[M].calls+=1,v.error||(R[M].successCount+=1),typeof v.duration=="number"&&(R[M].totalDuration+=v.duration)}}const u=Object.entries(R).map(([e,b])=>({name:e,calls:b.calls,avgDuration:b.calls>0?Math.round(b.totalDuration/b.calls):0,successRate:b.calls>0?b.successCount/b.calls*100:0,errorCount:b.calls-b.successCount})).sort((e,b)=>b.calls-e.calls),i=y.reduce((e,b)=>e+b.cost,0),g=Array.isArray(m.llmUsage)?m.llmUsage:[],T={},w=new Set;for(const e of g){const b=e.assistantId||"",v=e.assistantName||"";if(!(!v||v==="team"||b.startsWith("team-"))){if(e.callId){if(w.has(e.callId))continue;w.add(e.callId)}T[b]||(T[b]={assistantName:v,llmCalls:0,inputTokens:0,outputTokens:0,estimatedCost:0,toolNames:new Set}),T[b].llmCalls+=1,T[b].inputTokens+=e.inputTokens||0,T[b].outputTokens+=e.outputTokens||0,T[b].estimatedCost+=await _(e.provider||"",e.modelId||e.model||"",e.inputTokens||0,e.outputTokens||0)}}const C=m.subAssistantToolsMap||{};if(Object.keys(C).length>0){for(const[e,b]of Object.entries(C))if(T[e])for(const v of b)T[e].toolNames.add(v)}else if(p&&p.events.length>0){const e={};for(const[S,M]of Object.entries(T))e[M.assistantName]=S;const b=[];let v=null;for(const S of p.events)S.kind==="assistant_start"?v={assistantName:S.assistantName,ts:S.ts}:S.kind==="assistant_end"&&v&&(b.push({assistantName:v.assistantName,start:v.ts,end:S.ts}),v=null);for(const S of p.events){if(S.kind!=="tool_start")continue;const M=S.toolName;if(!M)continue;const z=b.find(P=>S.ts>=P.start&&S.ts<=P.end);if(z){const P=e[z.assistantName];P&&T[P]&&T[P].toolNames.add(M)}}}else{const e=new Set;for(const b of t){const v=b.assistantId||"";if(!v||v.startsWith("team-")||!T[v])continue;const S=Array.isArray(b.tools)?b.tools:[];for(const M of S){const z=`${v}:${M.name||""}:${M.timestamp||""}`;if(M.timestamp){if(e.has(z))continue;e.add(z)}M.name&&T[v].toolNames.add(M.name)}}}const A=Object.entries(T).map(([e,b])=>{const S=a[e]?.graphId,M=S?l[S]:void 0;return{assistantId:e,assistantName:b.assistantName,llmCalls:b.llmCalls,inputTokens:b.inputTokens,outputTokens:b.outputTokens,estimatedCost:b.estimatedCost,toolNames:[...b.toolNames],graphName:M}});return{run:{runId:m.runId||m.id,chatId:m.chatId,teamId:m.teamId,teamName:m.teamName,assistantId:m.assistantId,assistantName:m.assistantName,userMessage:m.userMessage,status:m.status||"unknown",startTime:m.startTime||"",endTime:m.endTime,duration:m.duration,topic:m.topic,graphId:m.graphId,username:m.username,totalTokens:m.totalTokens,toolCallsCount:m.toolCallsCount,estimatedCost:i||m.estimatedCost},subAssistants:A,llmBreakdown:y,toolsBreakdown:u,trace:p?{events:p.events}:null}}catch(c){throw console.error("[monitoring] Error getting run detail:",c),c}}async function Lt(o,c,s){try{const m=[{term:{teamId:o}}];s&&m.push({term:{"teamName.keyword":s}},{match:{teamName:s}});const r=[{bool:{should:m,minimum_should_match:1}}];c&&r.push({range:{startTime:{gte:c.start,lte:c.end}}});const p=(await N.search({index:j,body:{query:{bool:{filter:r}},size:200,sort:[{startTime:"desc"}]}})).hits.hits.map(t=>({id:t._id,...t._source})),a=s||p[0]?.teamName||o,l=p.slice(0,10).map(t=>({id:t.id,runId:t.runId||t.id,chatId:t.chatId||"",status:t.status||"unknown",startTime:t.startTime||"",duration:typeof t.duration=="number"?t.duration:void 0,teamName:t.teamName,assistantName:t.assistantName,graphId:t.graphId,username:t.username,topic:t.topic,totalTokens:typeof t.totalTokens=="number"?t.totalTokens:void 0,estimatedCost:typeof t.estimatedCost=="number"?t.estimatedCost:void 0,toolCallsCount:typeof t.toolCallsCount=="number"?t.toolCallsCount:void 0})),n={};for(const t of p){const u=t.assistantId||"unknown";n[u]||(n[u]={assistantName:t.assistantName||u,runs:0,successCount:0,totalCost:0}),n[u].runs+=1,t.status==="success"&&(n[u].successCount+=1),n[u].totalCost+=t.estimatedCost||0}const d=Object.entries(n).map(([t,u])=>({assistantId:t,assistantName:u.assistantName,runs:u.runs,successRate:u.runs>0?u.successCount/u.runs*100:0,totalCost:u.totalCost})).sort((t,u)=>u.runs-t.runs),f=p.map(t=>t.runId||t.id).filter(Boolean);let y=[];try{const t=await N.search({index:E,body:{query:{terms:{runId:f.slice(0,200)}},size:200}}),u={};for(const i of t.hits.hits){const g=Array.isArray(i._source.tools)?i._source.tools:[];for(const T of g){const w=T.name||"unknown";u[w]||(u[w]={calls:0,totalDuration:0}),u[w].calls+=1,typeof T.duration=="number"&&(u[w].totalDuration+=T.duration)}}y=Object.entries(u).map(([i,g])=>({name:i,calls:g.calls,avgDuration:g.calls>0?g.totalDuration/g.calls:0})).sort((i,g)=>g.calls-i.calls).slice(0,10)}catch(t){t?.meta?.body?.error?.type!=="index_not_found_exception"&&console.error("[monitoring] team tools:",t.message)}await x();const h={};for(const t of p){const u=(t.startTime||"").slice(0,10);u&&(h[u]||(h[u]={date:u,runs:0,cost:0}),h[u].runs+=1,h[u].cost+=t.estimatedCost||0)}try{const t=[{term:{teamId:o}}];c&&t.push({range:{createdAt:{gte:c.start,lte:c.end}}});const u=await N.search({index:B,body:{query:{bool:{must:t}},size:500}});for(const i of u.hits.hits){const g=i._source,T=(g.createdAt||"").slice(0,10);if(!T||!h[T])continue;const w=Array.isArray(g.llms)?g.llms:[];for(const C of w)h[T].cost+=await _(C.provider||"",C.modelId||"",C.inputTokens||0,C.outputTokens||0)}}catch{}const R=Object.values(h).sort((t,u)=>t.date.localeCompare(u.date));return{teamId:o,teamName:a,recentRuns:l,assistantBreakdown:d,topTools:y,timeseries:R}}catch(m){throw console.error("[monitoring] Error getting team detail:",m),m}}async function Ot(o,c){try{const s=[{term:{assistantId:o}}];if(o.startsWith("team-")){const t=o.slice(5);s.push({term:{teamId:t}})}const m=[{bool:{should:s,minimum_should_match:1}}];c&&m.push({range:{startTime:{gte:c.start,lte:c.end}}});const k=(await N.search({index:j,body:{query:{bool:{filter:m}},size:200,sort:[{startTime:"desc"}]}})).hits.hits.map(t=>({id:t._id,...t._source})),a=(await H())[o]?.name||k[0]?.assistantName||o,l=k.slice(0,10).map(t=>({id:t.id,runId:t.runId||t.id,chatId:t.chatId||"",status:t.status||"unknown",startTime:t.startTime||"",duration:typeof t.duration=="number"?t.duration:void 0,teamName:t.teamName,assistantName:t.assistantName,graphId:t.graphId,username:t.username,topic:t.topic,totalTokens:typeof t.totalTokens=="number"?t.totalTokens:void 0,estimatedCost:typeof t.estimatedCost=="number"?t.estimatedCost:void 0,toolCallsCount:typeof t.toolCallsCount=="number"?t.toolCallsCount:void 0})),n={};for(const t of k)t.teamId&&t.teamId!=="unknown"&&(n[t.teamId]||(n[t.teamId]={teamName:t.teamName||t.teamId,runs:0}),n[t.teamId].runs+=1);const d=Object.entries(n).map(([t,u])=>({teamId:t,teamName:u.teamName,runs:u.runs})).sort((t,u)=>u.runs-t.runs);await x();const f=[];try{const t=[{term:{assistantId:o}}];c&&t.push({range:{createdAt:{gte:c.start,lte:c.end}}});const u=await N.search({index:B,body:{query:{bool:{must:t}},size:500}}),i={};for(const g of u.hits.hits){const T=g._source,w=Array.isArray(T.llms)?T.llms:[];for(const C of w){const I=`${C.provider||"unknown"}:${C.modelId||"unknown"}`;i[I]||(i[I]={calls:0,inputTokens:0,outputTokens:0,cost:0}),i[I].calls+=1,i[I].inputTokens+=C.inputTokens||0,i[I].outputTokens+=C.outputTokens||0,i[I].cost+=await _(C.provider||"",C.modelId||"",C.inputTokens||0,C.outputTokens||0)}}for(const[g,T]of Object.entries(i)){const w=g.indexOf(":");f.push({provider:g.slice(0,w),modelId:g.slice(w+1),...T})}f.sort((g,T)=>T.calls-g.calls)}catch(t){t?.meta?.body?.error?.type!=="index_not_found_exception"&&console.error("[monitoring] assistant llm:",t.message)}let y=[];try{const t=[{term:{assistantId:o}}];c&&t.push({range:{createdAt:{gte:c.start,lte:c.end}}});const u=await N.search({index:E,body:{query:{bool:{must:t}},size:200}}),i={};for(const g of u.hits.hits){const T=Array.isArray(g._source.tools)?g._source.tools:[];for(const w of T){const C=w.name||"unknown";i[C]||(i[C]={calls:0,successCount:0,totalDuration:0}),i[C].calls+=1,w.error||(i[C].successCount+=1),typeof w.duration=="number"&&(i[C].totalDuration+=w.duration)}}y=Object.entries(i).map(([g,T])=>({name:g,calls:T.calls,avgDuration:T.calls>0?T.totalDuration/T.calls:0,successRate:T.calls>0?T.successCount/T.calls*100:0})).sort((g,T)=>T.calls-g.calls).slice(0,10)}catch(t){t?.meta?.body?.error?.type!=="index_not_found_exception"&&console.error("[monitoring] assistant tools:",t.message)}const h=k.length,R=k.filter(t=>t.status==="success"||t.status==="completed").length;return{assistantId:o,assistantName:a,totalRunsCount:h,successRunsCount:R,recentRuns:l,llmBreakdown:f,topTools:y,teams:d}}catch(s){throw console.error("[monitoring] Error getting assistant detail:",s),s}}export{Ot as getAssistantDetail,At as getAssistantsStats,Mt as getGraphsStats,Tt as getLLMCosts,kt as getLLMPerformance,ut as getLLMStats,wt as getLLMStatsByModel,It as getLLMStatsByProvider,vt as getOverviewStats,Dt as getRunDetail,_t as getRunsDistribution,xt as getRunsList,Lt as getTeamDetail,Nt as getTeamsStats,Ct as getToolsAnalytics,Rt as getToolsByServer,St as getToolsByTool,ht as getToolsStats,yt as invalidateMonitoringPricingCache};
@@ -0,0 +1 @@
1
+ import{Client as U}from"@elastic/elasticsearch";import{config as w}from"../config";import{getChatRuns as I,getChatRunsByTimeRange as x}from"./chat-runs-service";import{calculateCost as R}from"./llm-pricing-service";const C=new U(w.elasticsearch),b=".stkxp_chats",M=".stkxp_chat_tools",_=".stkxp_chat_runs";function D(t){if(t.length<2)return;const o=new Date(t[0].timestamp).getTime();return new Date(t[t.length-1].timestamp).getTime()-o}function S(t,o){if(t.length===0)return"running";const s=t[t.length-1];if(s.role==="user")return"running";if(s.role==="assistant"||s.role==="agent"){const e=JSON.stringify(s.content).toLowerCase();if(e.includes("error")||e.includes("failed"))return"failed"}return s.role==="assistant"||s.role==="agent"?"completed":"running"}async function E(t,o,s,e,n=0){return await R(t,o,s,e,n)}async function J(t,o){const s=o?.runId||t.messages.find(i=>i.toolsRunId)?.toolsRunId;if(!s)return null;const e=t.messages,n=D(e),c=S(e,o),r=o?.tools?.map(i=>i.name)||[],d=Array.from(new Set(r)),l=e[0]?.timestamp||t.createdAt,g=e[e.length-1]?.timestamp,m=[],f=t.metadata?.tokenUsage;t.assistants&&Array.isArray(t.assistants)&&t.assistants.forEach(i=>{i.llm&&m.push({provider:i.llm.provider||"unknown",model:i.llm.modelId||"unknown",inputTokens:i.llm.inputTokens||0,outputTokens:i.llm.outputTokens||0,totalTokens:i.llm.totalTokens||0})});const y=t.metadata?.topic||"general",T=t.metadata?.cluster,a=t.metadata?.namespace,u=f?.totalTokens||0;let p=0;for(const i of m){const k=await E(i.provider,i.model,i.inputTokens,i.outputTokens);p+=k}return{runId:s,chatId:t.id,username:t.username,startTime:l,endTime:g,duration:n,status:c,llmUsage:m,topic:y,cluster:T,namespace:a,toolsUsed:d,toolCallsCount:o?.tools?.length||0,messageCount:e.length,totalTokens:u,estimatedCost:p}}async function h(t=0,o=50,s){try{const{runs:e,total:n}=await I(t,o,s);return{runs:e.map(r=>({runId:r.runId,chatId:r.chatId,username:r.username,startTime:r.startTime,endTime:r.endTime,duration:r.duration||0,status:r.status,llmUsage:r.llmUsage||[],topic:r.topic||"",cluster:r.cluster,namespace:r.namespace,toolsUsed:r.toolsUsed||[],toolCallsCount:r.toolCallsCount||0,messageCount:r.messageCount||0,totalTokens:r.totalTokens||0,estimatedCost:r.estimatedCost||0,source:r.source})),total:n}}catch(e){throw console.error("Error getting recent runs:",e),e}}async function j(t){try{const o=await C.search({index:_,body:{query:{term:{runId:t}},size:1}});if(o.hits.hits.length===0)return console.warn(`Run not found: ${t}`),null;const s=o.hits.hits[0],e={id:s._id,...s._source};let n=null;try{try{const l=await C.get({index:b,id:e.chatId});n={id:l._id,...l._source}}catch{const g=await C.search({index:b,body:{query:{bool:{should:[{nested:{path:"messages",query:{prefix:{"messages.id":`run-${t}`}}}},{nested:{path:"messages",query:{term:{"messages.toolsRunId":t}}}}],minimum_should_match:1}},size:1,sort:[{createdAt:"desc"}]}});if(g.hits.hits.length>0){const m=g.hits.hits[0];n={id:m._id,...m._source},console.log(`[monitoring] Found chat by searching for runId ${t}`)}}}catch(l){console.warn(`Chat not found for runId ${t}, chatId ${e.chatId}:`,l)}const c=await C.search({index:M,body:{query:{term:{runId:t}},size:1}}),r=c.hits.hits.length>0?{id:c.hits.hits[0]._id,...c.hits.hits[0]._source}:void 0;return{runId:e.runId,chatId:e.chatId,username:e.username,startTime:e.startTime,endTime:e.endTime,duration:e.duration||0,status:e.status,llmUsage:e.llmUsage||[],topic:e.topic||"",cluster:e.cluster,namespace:e.namespace,toolsUsed:e.toolsUsed||[],toolCallsCount:e.toolCallsCount||0,messageCount:e.messageCount||0,totalTokens:e.totalTokens||0,estimatedCost:e.estimatedCost||0,messages:n?.messages||[],tools:r?.tools||[],metadata:e.metadata||{}}}catch(o){return console.error("Error getting run details:",o),null}}async function q(t,o){try{return(await x(t.start,t.end,o)).map(n=>({runId:n.runId,chatId:n.chatId,username:n.username,startTime:n.startTime,endTime:n.endTime,duration:n.duration||0,status:n.status,llmUsage:n.llmUsage||[],topic:n.topic||"",cluster:n.cluster,namespace:n.namespace,toolsUsed:n.toolsUsed||[],toolCallsCount:n.toolCallsCount||0,messageCount:n.messageCount||0,totalTokens:n.totalTokens||0,estimatedCost:n.estimatedCost||0,source:n.source}))}catch(s){throw console.error("Error getting runs by time range:",s),s}}async function G(t){return(await h(0,1e3,t)).runs}async function K(t){return(await h(0,100,t)).runs.filter(s=>s.status==="failed")}async function Q(t,o){try{const s=t?await q(t,o):(await h(0,1e3,o)).runs,e=s.length,n=s.filter(a=>a.status==="completed").length,c=s.filter(a=>a.status==="failed").length,r=s.filter(a=>a.status==="running").length,d=s.filter(a=>a.duration).map(a=>a.duration),l=d.length>0?d.reduce((a,u)=>a+u,0)/d.length:0,g=s.reduce((a,u)=>a+u.toolCallsCount,0),m=s.reduce((a,u)=>a+(u.estimatedCost||0),0),f=s.reduce((a,u)=>{const p=u.source==="generator"||u.source==="playground"?u.source:"chat";return a[p]+=u.estimatedCost||0,a},{chat:0,playground:0,generator:0}),T=new Set(s.map(a=>a.username)).size;return{totalRuns:e,completedRuns:n,failedRuns:c,runningRuns:r,avgDuration:l,totalToolCalls:g,totalCost:m,costBySource:f,activeUsers:T}}catch(s){throw console.error("Error getting run stats:",s),s}}export{K as getFailedRuns,h as getRecentRuns,j as getRunDetails,Q as getRunStats,q as getRunsByTimeRange,G as getRunsByUser};
@@ -0,0 +1 @@
1
+ import{KibanaClientFactory as P}from"./kibana-client-factory";import{getPlatforms as h}from"./platforms-service";import{settingsConfig as b}from"../app-config/settings";const w=`${b.kibana.hostname}:${b.kibana.port}`;class T{async getAllPackagesFromAllPlatforms(g,e=!0){const t=[],a=[];try{const{platforms:i}=await h(g,void 0,void 0,1,1e3),r=i.filter(s=>s.enabled&&s.type==="ElasticStack");if(e)try{const s=b.kibana.hostname.toLowerCase();if(!r.some(l=>{try{const f=l.config.endpoints?.kibana?.url||"";return(f.startsWith("http")?new URL(f).hostname.toLowerCase():f.toLowerCase())===s}catch{return!1}})){const l=P.createFromSettings();t.push({client:l,platformId:"settings",platformName:w})}}catch(s){console.error("[MultiKibanaService] Failed to create settings client:",s.message),a.push({platformId:"settings",platformName:w,error:s.message})}for(const s of r)try{const p=P.createFromPlatform(s);t.push({client:p,platformId:s.id,platformName:s.name})}catch(p){console.error(`[MultiKibanaService] Failed to create client for platform ${s.name} (${s.id}): ${p.message}`),a.push({platformId:s.id,platformName:s.name,error:p.message})}const d=t.map(async({client:s,platformId:p,platformName:l})=>{try{const[f,m,I]=await Promise.all([s.getEpmPackages(!1),s.getPackagePolicies(),s.getAgentPolicies()]);if(f?.error){const c=f.error?.message||f.error?.code||JSON.stringify(f.error),y=`getEpmPackages HTTP ${f.statusCode??"network_error"}: ${c}`;return console.error(`[MultiKibanaService] ${l}: ${y}`),a.push({platformId:p,platformName:l,error:y}),[]}const M=f?.data?.items||f?.items||[];if(m?.error){const c=m.error?.message||m.error?.code||JSON.stringify(m.error),y=`getPackagePolicies HTTP ${m.statusCode??"network_error"}: ${c}`;return console.error(`[MultiKibanaService] ${l}: ${y}`),a.push({platformId:p,platformName:l,error:y}),[]}else!m?.data?.items&&!m?.items&&console.warn(`[MultiKibanaService] getPackagePolicies unexpected response for ${l}:`,JSON.stringify(m)?.slice(0,300));const S=m?.data?.items||m?.items||[],N=I?.data?.items||I?.items||[],A=new Map(N.map(c=>[c.id,c.name])),$=new Map(M.map(c=>[c.name,c]));return S.filter(c=>c.package?.name!=="fleet_server"&&c.package?.name!=="apm").map(c=>{const y=c.package?.name,v=$.get(y)||{},k=c.policy_ids&&c.policy_ids.length>0?c.policy_ids[0]:c.policy_id||void 0,E=k?A.get(k):void 0;return{...v,name:y,version:c.package?.version||v.version,platformId:p,platformName:l,policyId:c.id,policyName:c.name,namespace:c.namespace,policyStatus:"enrolled",agentPolicyId:k,agentPolicyName:E}})}catch(f){return console.error(`[MultiKibanaService] Error fetching packages from ${l} (${p}): ${f.message}`),a.push({platformId:p,platformName:l,error:f.message}),[]}}),n=(await Promise.all(d)).flat(),o=this.createSeparatePackageLines(n);return console.log(`[MultiKibanaService] ${t.length} clients, ${n.length} packages, ${o.length} entries for user (${a.length} errors)`),{packages:o,errors:a}}catch(i){throw console.error("[MultiKibanaService] Error in getAllPackagesFromAllPlatforms:",i),i}}createSeparatePackageLines(g){return g.map(e=>({id:e.policyId,name:e.name,version:e.version,title:e.title,description:e.description,status:e.policyStatus||e.status,icons:e.icons,categories:e.categories,platforms:[{platformId:e.platformId,platformName:e.platformName,status:e.policyStatus||e.status,policyId:e.policyId,policyName:e.policyName,namespace:e.namespace,agentPolicyId:e.agentPolicyId,agentPolicyName:e.agentPolicyName}]}))}aggregatePackagesByName(g){const e=new Map;for(const t of g){const a=t.name;e.has(a)||e.set(a,{name:t.name,version:t.version,title:t.title,description:t.description,status:t.status,icons:t.icons,categories:t.categories,platforms:[]}),e.get(a).platforms.push({platformId:t.platformId,platformName:t.platformName,status:t.policyStatus||t.status,policyId:t.policyId,namespace:t.namespace})}return Array.from(e.values())}async getInstalledPackagesFromAllPlatforms(g){const e=await this.getAllPackagesFromAllPlatforms(g,!1),t=new Map;for(const a of e.packages){const i=a.platforms[0];if(!i?.policyId)continue;const r=a.name;t.has(r)||t.set(r,{id:i.policyId,name:r,title:a.title||r,description:a.description||"",version:a.version||"unknown",status:"installed",icons:a.icons||[],installationInfo:{install_status:"installed",install_source:"registry"},policy_id:i.policyId,namespace:i.namespace,platformId:i.platformId,platformName:i.platformName})}return{packageMap:t,errors:e.errors}}async findPolicyByPackageName(g,e){const t=[];try{const{platforms:a}=await h(e,void 0,void 0,1,1e3),i=a.filter(r=>r.enabled&&r.type==="ElasticStack");try{const{settingsConfig:r}=await import("../app-config/settings"),d=r.kibana.hostname.toLowerCase();i.some(n=>{try{const o=n.config.endpoints?.kibana?.url||"";return(o.startsWith("http")?new URL(o).hostname.toLowerCase():o.toLowerCase())===d}catch{return!1}})||t.push({client:P.createFromSettings(),platformId:"settings",platformName:w})}catch{}for(const r of i)try{t.push({client:P.createFromPlatform(r),platformId:r.id,platformName:r.name})}catch{}}catch(a){return console.error("[MultiKibanaService] findPolicyByPackageName: failed to build clients:",a.message),null}for(const{client:a,platformId:i,platformName:r}of t)try{const d=await a.getPackagePolicies(),n=(d?.data?.items||d?.items||[]).find(o=>o.package?.name===g);if(n)return console.log(`[MultiKibanaService] Found policy for ${g} on platform ${r}`),{policyId:n.id,platformId:i,platformName:r,policy:n}}catch(d){console.warn(`[MultiKibanaService] findPolicyByPackageName: error on ${r}:`,d.message)}return null}async getEpmCatalogFromAllPlatforms(g){const e=[],{platforms:t}=await h(g,void 0,void 0,1,1e3),i=t.filter(o=>o.enabled&&o.type==="ElasticStack").map(o=>({platformId:o.id,platformName:o.name,managedType:o.managedType,client:P.createFromPlatform(o)})),d=(await Promise.all(i.map(async({client:o,platformId:s,platformName:p})=>{try{const l=await o.getEpmPackages(!1);return(l?.data?.items||l?.items||[]).map(m=>({name:m.name,version:m.version,title:m.title,description:m.description,status:m.status,icons:m.icons||[],categories:m.categories||[],platformId:s,platformName:p}))}catch(l){return console.error(`[MultiKibanaService] getEpmCatalogFromAllPlatforms error on ${p}:`,l.message),e.push({platformId:s,platformName:p,error:l.message}),[]}}))).flat(),u=new Set;for(const o of d)for(const s of o.categories??[])u.add(s);const n=Array.from(u).sort();return{packages:d,allCategories:n,errors:e}}async getPlatformsWithPackage(g,e,t){const a=[],{platforms:i}=await h(e,void 0,void 0,1,1e3);let r=i.filter(n=>n.enabled&&n.type==="ElasticStack");return t&&(r=r.filter(n=>n.managedType===t)),{platforms:(await Promise.all(r.map(async n=>{try{const s=await P.createFromPlatform(n).getEpmPackages(!1),l=(s?.data?.items||s?.items||[]).some(f=>f.name===g&&f.status==="installed");return{platform:n,hasPackage:l}}catch(o){return a.push({platformId:n.id,platformName:n.name,error:o.message}),{platform:n,hasPackage:!1}}}))).filter(n=>n.hasPackage).map(n=>n.platform),errors:a}}async getPackagesFromPlatform(g,e){if(g==="settings"){const u=await P.createFromSettings().getEpmPackages(!1);return u?.data?.items||u?.items||[]}const{getPlatformById:t}=await import("../core/services/platforms-service"),a=await t(g,e);if(!a)throw new Error(`Platform ${g} not found or not accessible`);const r=await P.createFromPlatform(a).getEpmPackages(!1);return r?.data?.items||r?.items||[]}}export{T as MultiKibanaService};
@@ -0,0 +1 @@
1
+ import{Client as w}from"@elastic/elasticsearch";import{config as N}from"../config";const I=new w(N.elasticsearch),k=".stkxp_chat_traces";function M(e,c){if(e.length===0)return 0;const s=c/100*(e.length-1),t=Math.floor(s),n=Math.ceil(s);if(t===n)return e[t];const o=s-t;return e[t]*(1-o)+e[n]*o}function _(e){if(!Array.isArray(e))return[];const c={},s=[];for(const t of e){if(!t||t.kind!=="node_start"&&t.kind!=="node_end")continue;const n=t;if(n.kind==="node_start"){(c[n.node]||=[]).push(n.ts);continue}let o=typeof n.durationMs=="number"&&n.durationMs>=0?n.durationMs:void 0;const m=c[n.node];if(m&&m.length>0){const d=m.pop();o===void 0&&typeof n.ts=="number"&&(o=Math.max(n.ts-d,0))}typeof o=="number"&&Number.isFinite(o)&&o>=0&&s.push({node:n.node,durationMs:o})}return s}async function E(e,c,s={}){const t=[];e&&t.push({range:{createdAt:{gte:e.start,lte:e.end}}}),c&&t.push({term:{username:c}}),s.teamId&&t.push({term:{teamId:s.teamId}});const n=e?.start??new Date(Date.now()-1440*60*1e3).toISOString(),o=e?.end??new Date().toISOString(),m=await I.search({index:k,body:{query:t.length?{bool:{must:t}}:{match_all:{}},size:1e3,_source:["events","assistantId"],sort:[{createdAt:{order:"desc"}}]}}),d=new Map;let g=0;for(const u of m.hits.hits){const a=u._source;if(s.assistantId&&a.assistantId&&a.assistantId!==s.assistantId)continue;const r=_(a.events||[]);for(const i of r){const l=d.get(i.node)??[];l.push(i.durationMs),d.set(i.node,l),g+=1}}const p=Array.from(d.values()).reduce((u,a)=>u+a.reduce((r,i)=>r+i,0),0),f=[];for(const[u,a]of d.entries()){const r=a.slice().sort((h,b)=>h-b),i=r.reduce((h,b)=>h+b,0),l=r.length?i/r.length:0;f.push({node:u,count:r.length,meanMs:l,p50Ms:M(r,50),p95Ms:M(r,95),maxMs:r[r.length-1]??0,totalMs:i,share:p>0?i/p:0})}f.sort((u,a)=>a.totalMs-u.totalMs);const y=s.topN??50;return{windowStart:n,windowEnd:o,tracesScanned:m.hits.hits.length,pairsCollected:g,totalElapsedMs:p,nodes:f.slice(0,y)}}export{E as getNodeLatencyReport};
@@ -0,0 +1,2 @@
1
+ import{KibanaService as b}from"./kibana-service";import{createSlug as k,generateRandomId as h}from"../utils/string-helpers";const v=new b;function p(e){return typeof e=="object"&&e!==null?e.isSecretRef===!0&&typeof e.id=="string":!1}function u(e){return typeof e=="boolean"?!1:e==null||e===""||e==="redacted"}const S=new Set(["ssl","resource_ssl","resources","xsd","state","regexp","config"]);function f(e,t){return typeof t=="boolean"?"bool":typeof t=="number"?"integer":e.includes("secret")||e.includes("password")?"password":S.has(e)||typeof t=="string"&&(t.includes(`
2
+ `)||t.trimStart().startsWith("- "))?"yaml":"text"}function m(e,t){const s=h(),a=k(`${e.integrationName}_${s}`),c={name:`${e.integrationName} ${a}`,description:e.description||"",namespace:a,policy_ids:[t||e.agentPolicyId].filter(Boolean),package:{name:e.packageName,version:e.packageVersion},inputs:[]};return e.vars&&Object.keys(e.vars).length>0&&(c.vars={},Object.keys(e.vars).forEach(r=>{const n=e.vars[r];p(n)||u(n)||(c.vars[r]={type:f(r,n),value:n})})),e.inputs&&Object.keys(e.inputs).forEach(r=>{const n=e.inputs[r];if(!n.enabled)return;const y={type:r,policy_template:e.policyTemplate,enabled:!0,streams:[],vars:{}};n.vars&&Object.keys(n.vars).forEach(l=>{const o=n.vars[l];p(o)||u(o)||(y.vars[l]={type:f(l,o),value:o})}),n.streams&&Object.keys(n.streams).length>0&&Object.keys(n.streams).forEach(l=>{const o=n.streams[l];if(!o.enabled)return;const P={enabled:!0,data_stream:{dataset:l.includes(".")?l:`${e.packageName}.${l}`,type:"logs"},vars:{}};o.vars&&Object.keys(o.vars).forEach(g=>{const d=o.vars[g];!p(d)&&!u(d)&&(P.vars[g]={type:f(g,d),value:d})}),y.streams.push(P)}),c.inputs.push(y)}),c}function j(e,t){const s={...e};return s.name=t.integrationName,s.description=t.description||s.description,t.inputs&&(s.inputs=[],Object.keys(t.inputs).forEach(a=>{const i=t.inputs[a],c={type:a,policy_template:t.policyTemplate,enabled:i.enabled,streams:[],vars:{}};i.vars&&Object.keys(i.vars).forEach(r=>{const n=i.vars[r];p(n)||u(n)||(c.vars[r]={type:"text",value:n})}),i.streams&&Object.keys(i.streams).forEach(r=>{const n=i.streams[r],y={enabled:n.enabled,data_stream:{type:"metrics",dataset:r},vars:{}};n.vars&&Object.keys(n.vars).forEach(l=>{const o=n.vars[l];!p(o)&&!u(o)&&(y.vars[l]={type:f(l,o),value:o})}),c.streams.push(y)}),s.inputs.push(c)})),t.vars&&s.vars&&Object.keys(t.vars).forEach(a=>{const i=t.vars[a],c=s.vars[a];c&&typeof c.value=="object"&&c.value!==null&&c.value.isSecretRef?!p(i)&&!u(i)&&(s.vars[a].value=i):!u(i)&&s.vars[a]&&(s.vars[a].value=i)}),delete s.id,delete s.created_at,delete s.created_by,delete s.updated_at,delete s.updated_by,delete s.revision,delete s.secret_references,s}class O{async installPackage(t,s,a){const i=m(t,s||t.agentPolicyId),c=a??v;console.log("[PackagePolicyService] Creating Fleet policy for package:",t.packageName);const r=await c.createPolicy(i);return console.log("[PackagePolicyService] Fleet policy created:",r?.data?.item?.id,r),r}async updatePackagePolicy(t,s,a){const i=a??v;console.log("[PackagePolicyService] Fetching existing policy:",t);const c=await i.getPackagePolicy(t);if(!c?.data?.item){const y=new Error(`Policy ${t} not found`);throw y.statusCode=404,y}const r=j(c.data.item,s);console.log("[PackagePolicyService] Updating Fleet policy:",t);const n=await i.updatePolicy(t,r);return console.log("[PackagePolicyService] Fleet policy updated:",t),n}async deletePackagePolicy(t,s){const a=s??v;console.log("[PackagePolicyService] Deleting Fleet policy:",t);const i=await a.deletePackagePolicy(t);return console.log("[PackagePolicyService] Fleet policy deleted:",t),i}}export{O as PackagePolicyService,m as buildFleetPolicy,j as mergeFormDataIntoPolicy};