@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.
- package/README.md +273 -0
- package/bin/stkxp.mjs +198 -0
- package/package.json +97 -0
- package/src/bootstrap.mjs +37 -0
- package/src/bootstrap.test.mjs +73 -0
- package/src/deploy.mjs +145 -0
- package/src/deploy.test.mjs +131 -0
- package/src/export.mjs +30 -0
- package/src/export.test.mjs +56 -0
- package/src/secret-input.mjs +64 -0
- package/src/secret-input.test.mjs +58 -0
- package/src/serve.mjs +83 -0
- package/src/serve.test.mjs +93 -0
- package/vendor/dist-server/asyncapi/generator.js +1 -0
- package/vendor/dist-server/asyncapi/messages.js +1 -0
- package/vendor/dist-server/asyncapi/viewer.html +43 -0
- package/vendor/dist-server/core/app-config/branding.js +1 -0
- package/vendor/dist-server/core/app-config/mantine-theme.js +1 -0
- package/vendor/dist-server/core/app-config/mermaid-theme.js +2 -0
- package/vendor/dist-server/core/app-config/prompt-optimization.js +1 -0
- package/vendor/dist-server/core/app-config/settings.js +1 -0
- package/vendor/dist-server/core/config.js +1 -0
- package/vendor/dist-server/core/graph/a2a-agent-executor.js +2 -0
- package/vendor/dist-server/core/graph/app.js +120 -0
- package/vendor/dist-server/core/graph/delegated-agent-adapter.js +1 -0
- package/vendor/dist-server/core/graph/graph-builder.js +3 -0
- package/vendor/dist-server/core/graph/kibana-agent-executor.js +1 -0
- package/vendor/dist-server/core/graph/nodes/context/assistants-context.js +5 -0
- package/vendor/dist-server/core/graph/nodes/context/compare-context.js +10 -0
- package/vendor/dist-server/core/graph/nodes/context/enrich-context.js +8 -0
- package/vendor/dist-server/core/graph/nodes/context/inventory-context.js +4 -0
- package/vendor/dist-server/core/graph/nodes/context/namespace-context.js +2 -0
- package/vendor/dist-server/core/graph/nodes/context/node-types-context.js +4 -0
- package/vendor/dist-server/core/graph/nodes/context/relevant-assistants-context.js +5 -0
- package/vendor/dist-server/core/graph/nodes/context/relevant-skills-context.js +5 -0
- package/vendor/dist-server/core/graph/nodes/context/skills-context.js +8 -0
- package/vendor/dist-server/core/graph/nodes/context/state-setter.js +1 -0
- package/vendor/dist-server/core/graph/nodes/control/check-reset.js +1 -0
- package/vendor/dist-server/core/graph/nodes/control/topic-detection.js +1 -0
- package/vendor/dist-server/core/graph/nodes/governance/human-approval.js +16 -0
- package/vendor/dist-server/core/graph/nodes/index.js +1 -0
- package/vendor/dist-server/core/graph/nodes/orchestration/suggestion-generator.js +17 -0
- package/vendor/dist-server/core/graph/nodes/orchestration/team-decider.js +1 -0
- package/vendor/dist-server/core/graph/nodes/orchestration/team-execution/decider-error.js +4 -0
- package/vendor/dist-server/core/graph/nodes/orchestration/team-execution/decider-standalone-runner.js +1 -0
- package/vendor/dist-server/core/graph/nodes/orchestration/team-execution/decider-synthesis.js +29 -0
- package/vendor/dist-server/core/graph/nodes/orchestration/team-execution/pipeline-memory.js +2 -0
- package/vendor/dist-server/core/graph/nodes/orchestration/team-execution/pipeline-runner.js +7 -0
- package/vendor/dist-server/core/graph/nodes/orchestration/team-execution/team-assistant-utils.js +1 -0
- package/vendor/dist-server/core/graph/nodes/orchestration/team-finder.js +13 -0
- package/vendor/dist-server/core/graph/nodes/orchestration/team-invoker.js +3 -0
- package/vendor/dist-server/core/graph/nodes/orchestration/team-parallel.js +1 -0
- package/vendor/dist-server/core/graph/nodes/orchestration/team-pipeline.js +6 -0
- package/vendor/dist-server/core/graph/nodes/orchestration/team-router.js +26 -0
- package/vendor/dist-server/core/graph/nodes/reasoning/code-executor/index.js +6 -0
- package/vendor/dist-server/core/graph/nodes/reasoning/code-executor/resource-bridge.js +2 -0
- package/vendor/dist-server/core/graph/nodes/reasoning/code-executor/sandbox.js +6 -0
- package/vendor/dist-server/core/graph/nodes/reasoning/code-executor/tool-bridge.js +1 -0
- package/vendor/dist-server/core/graph/nodes/reasoning/local-extractor.js +5 -0
- package/vendor/dist-server/core/graph/nodes/reasoning/response-generator.js +47 -0
- package/vendor/dist-server/core/graph/nodes/reasoning/static-code-executor/index.js +1 -0
- package/vendor/dist-server/core/graph/nodes/reasoning/system.js +54 -0
- package/vendor/dist-server/core/graph/nodes/reasoning/tool-executor.js +9 -0
- package/vendor/dist-server/core/graph/nodes/tools/raw-output.js +4 -0
- package/vendor/dist-server/core/graph/nodes/tools/tool-cleaner.js +7 -0
- package/vendor/dist-server/core/graph/nodes/tools/tool-execution/execute-tool-calls.js +3 -0
- package/vendor/dist-server/core/graph/nodes/tools/tool-execution/invoke.js +1 -0
- package/vendor/dist-server/core/graph/nodes/tools/tool-execution/namespace-guard.js +1 -0
- package/vendor/dist-server/core/graph/nodes/tools/tool-execution/result-limits.js +3 -0
- package/vendor/dist-server/core/graph/nodes/tools/tool-invoker.js +1 -0
- package/vendor/dist-server/core/graph/nodes/tools/tool.js +4 -0
- package/vendor/dist-server/core/graph/schemas.js +1 -0
- package/vendor/dist-server/core/graph/topic-variants.js +1 -0
- package/vendor/dist-server/core/graph/types.js +1 -0
- package/vendor/dist-server/core/graph/utils/content-utils.js +17 -0
- package/vendor/dist-server/core/graph/utils/edge-jsonata-condition.js +1 -0
- package/vendor/dist-server/core/graph/utils/engine-vars.js +1 -0
- package/vendor/dist-server/core/graph/utils/logging-utils.js +4 -0
- package/vendor/dist-server/core/graph/utils/message-utils.js +5 -0
- package/vendor/dist-server/core/graph/utils/node-type-defaults-cache.js +1 -0
- package/vendor/dist-server/core/graph/utils/sandbox-catalog.js +1 -0
- package/vendor/dist-server/core/graph/utils/schema-utils.js +1 -0
- package/vendor/dist-server/core/graph/utils/team-context-policy.js +5 -0
- package/vendor/dist-server/core/graph/utils/team-node-resolvers.js +1 -0
- package/vendor/dist-server/core/graph/utils/tool-result.js +4 -0
- package/vendor/dist-server/core/graph/utils/tool-wrapper.js +14 -0
- package/vendor/dist-server/core/llm/init-indices.js +1 -0
- package/vendor/dist-server/core/llm/models/index.js +1 -0
- package/vendor/dist-server/core/llm/models/model.model.js +1 -0
- package/vendor/dist-server/core/llm/models/provider.model.js +1 -0
- package/vendor/dist-server/core/llm/models/routing-rule.model.js +1 -0
- package/vendor/dist-server/core/llm/providers.js +1 -0
- package/vendor/dist-server/core/mcp/client.js +1 -0
- package/vendor/dist-server/core/runtime/active-runs-registry.js +1 -0
- package/vendor/dist-server/core/runtime/system-prompt-cache.js +1 -0
- package/vendor/dist-server/core/runtime/trace-bus.js +1 -0
- package/vendor/dist-server/core/schema/cluster_health_report.js +1 -0
- package/vendor/dist-server/core/schema/cluster_info.js +1 -0
- package/vendor/dist-server/core/schema/cluster_license.js +5 -0
- package/vendor/dist-server/core/schema/cluster_stats.js +12 -0
- package/vendor/dist-server/core/schema/dashboard.js +1 -0
- package/vendor/dist-server/core/schema/indices_settings.js +1 -0
- package/vendor/dist-server/core/schema/indices_shards.js +1 -0
- package/vendor/dist-server/core/schema/indices_stats.js +1 -0
- package/vendor/dist-server/core/schema/nodes_info.js +2 -0
- package/vendor/dist-server/core/schema/nodes_stats.js +11 -0
- package/vendor/dist-server/core/schema/pricing.js +1 -0
- package/vendor/dist-server/core/schema/ui.js +1 -0
- package/vendor/dist-server/core/schema/zod_client.js +83 -0
- package/vendor/dist-server/core/services/a2a-client.js +2 -0
- package/vendor/dist-server/core/services/alerts-service.js +1 -0
- package/vendor/dist-server/core/services/api-keys-service.js +1 -0
- package/vendor/dist-server/core/services/assistant-resolver.js +1 -0
- package/vendor/dist-server/core/services/assistants-index-service.js +1 -0
- package/vendor/dist-server/core/services/async-conversations-service.js +22 -0
- package/vendor/dist-server/core/services/asyncapi-dispatch.js +1 -0
- package/vendor/dist-server/core/services/asyncapi-drivers/driver-manager.js +1 -0
- package/vendor/dist-server/core/services/asyncapi-drivers/driver-types.js +0 -0
- package/vendor/dist-server/core/services/asyncapi-drivers/http-driver.js +1 -0
- package/vendor/dist-server/core/services/asyncapi-drivers/nats-driver.js +1 -0
- package/vendor/dist-server/core/services/asyncapi-drivers/websocket-driver.js +1 -0
- package/vendor/dist-server/core/services/asyncapi-events-service.js +1 -0
- package/vendor/dist-server/core/services/asyncapi-reply-service.js +1 -0
- package/vendor/dist-server/core/services/asyncapi-sink.js +1 -0
- package/vendor/dist-server/core/services/asyncapi-tools-service.js +1 -0
- package/vendor/dist-server/core/services/block-repair-service.js +13 -0
- package/vendor/dist-server/core/services/chart-renderer.js +1 -0
- package/vendor/dist-server/core/services/chat-llms-service.js +1 -0
- package/vendor/dist-server/core/services/chat-runs-service.js +1 -0
- package/vendor/dist-server/core/services/chat-tools-service.js +1 -0
- package/vendor/dist-server/core/services/chat-traces-service.js +1 -0
- package/vendor/dist-server/core/services/chats-service.js +5 -0
- package/vendor/dist-server/core/services/comparison-service.js +107 -0
- package/vendor/dist-server/core/services/default-model.service.js +1 -0
- package/vendor/dist-server/core/services/elastic-stack-sync-service.js +2 -0
- package/vendor/dist-server/core/services/elasticsearch-wrapper.js +1 -0
- package/vendor/dist-server/core/services/embed-rate-limiter.js +1 -0
- package/vendor/dist-server/core/services/error-analytics-service.js +1 -0
- package/vendor/dist-server/core/services/es-field-resolver.js +1 -0
- package/vendor/dist-server/core/services/gateway-platform-types.js +1 -0
- package/vendor/dist-server/core/services/gliner-tagging-service.js +1 -0
- package/vendor/dist-server/core/services/golden-questions-scoring.js +1 -0
- package/vendor/dist-server/core/services/golden-questions-service.js +1 -0
- package/vendor/dist-server/core/services/graph-drilldown-service.js +1 -0
- package/vendor/dist-server/core/services/graph-registry-service.js +1 -0
- package/vendor/dist-server/core/services/hitl-analytics-service.js +1 -0
- package/vendor/dist-server/core/services/ingestion-jobs-service.js +1 -0
- package/vendor/dist-server/core/services/ingestion-service.js +5 -0
- package/vendor/dist-server/core/services/kibana-client-factory.js +1 -0
- package/vendor/dist-server/core/services/kibana-client.js +2 -0
- package/vendor/dist-server/core/services/kibana-dashboard-extractor.js +1 -0
- package/vendor/dist-server/core/services/kibana-service.js +1 -0
- package/vendor/dist-server/core/services/llm-analytics-service.js +1 -0
- package/vendor/dist-server/core/services/llm-client-resolver.js +1 -0
- package/vendor/dist-server/core/services/llm-models-service.js +1 -0
- package/vendor/dist-server/core/services/llm-pricing-pure.js +1 -0
- package/vendor/dist-server/core/services/llm-pricing-service.js +1 -0
- package/vendor/dist-server/core/services/llm-providers-service.js +1 -0
- package/vendor/dist-server/core/services/llm-routing-service.js +1 -0
- package/vendor/dist-server/core/services/llm-services.js +1 -0
- package/vendor/dist-server/core/services/llm-sync-service.js +1 -0
- package/vendor/dist-server/core/services/manifest-loader.js +1 -0
- package/vendor/dist-server/core/services/mcp-servers-service.js +1 -0
- package/vendor/dist-server/core/services/mcp-sync-service.js +1 -0
- package/vendor/dist-server/core/services/mcp-tools-service.js +1 -0
- package/vendor/dist-server/core/services/memories-service.js +2 -0
- package/vendor/dist-server/core/services/memory-analytics-service.js +1 -0
- package/vendor/dist-server/core/services/monitoring-analytics-service.js +1 -0
- package/vendor/dist-server/core/services/monitoring-service.js +1 -0
- package/vendor/dist-server/core/services/multi-kibana-service.js +1 -0
- package/vendor/dist-server/core/services/node-latency-service.js +1 -0
- package/vendor/dist-server/core/services/package-policy-service.js +2 -0
- package/vendor/dist-server/core/services/pdf-service.js +572 -0
- package/vendor/dist-server/core/services/plan-service.js +1 -0
- package/vendor/dist-server/core/services/platform-direction.js +1 -0
- package/vendor/dist-server/core/services/platform-secrets.js +1 -0
- package/vendor/dist-server/core/services/platforms-service.js +1 -0
- package/vendor/dist-server/core/services/policy-factory.js +1 -0
- package/vendor/dist-server/core/services/prompt-cache-service.js +1 -0
- package/vendor/dist-server/core/services/provider-rate-limits.js +1 -0
- package/vendor/dist-server/core/services/quota-service.js +1 -0
- package/vendor/dist-server/core/services/report-assets-service.js +1 -0
- package/vendor/dist-server/core/services/run-analytics-collector.js +1 -0
- package/vendor/dist-server/core/services/run-stream-sink.js +1 -0
- package/vendor/dist-server/core/services/send_mail.js +460 -0
- package/vendor/dist-server/core/services/share-service.js +1 -0
- package/vendor/dist-server/core/services/slack-signature.js +1 -0
- package/vendor/dist-server/core/services/sources-service.js +6 -0
- package/vendor/dist-server/core/services/team-mcp-result.js +4 -0
- package/vendor/dist-server/core/services/team-mcp-run-tokens.js +1 -0
- package/vendor/dist-server/core/services/team-mcp-runner.js +1 -0
- package/vendor/dist-server/core/services/team-mcp-server.js +1 -0
- package/vendor/dist-server/core/services/team-mcp-tools.js +1 -0
- package/vendor/dist-server/core/services/team-mcp-ui.js +551 -0
- package/vendor/dist-server/core/services/team-run-progress.js +1 -0
- package/vendor/dist-server/core/services/team-runner-headless.js +7 -0
- package/vendor/dist-server/core/services/team-search-service.js +1 -0
- package/vendor/dist-server/core/services/teams-service.js +1 -0
- package/vendor/dist-server/core/services/token-projection-service.js +1 -0
- package/vendor/dist-server/core/services/tool-analytics-service.js +1 -0
- package/vendor/dist-server/core/services/tool-history-service.js +1 -0
- package/vendor/dist-server/core/services/tool-metrics-service.js +1 -0
- package/vendor/dist-server/core/services/tool-scoring.js +1 -0
- package/vendor/dist-server/core/services/toolbox-import-mappers.js +1 -0
- package/vendor/dist-server/core/services/toolbox-import-service.js +1 -0
- package/vendor/dist-server/core/services/trigger-service.js +1 -0
- package/vendor/dist-server/core/services/version-snapshot-service.js +1 -0
- package/vendor/dist-server/core/services/webhook-calls-service.js +1 -0
- package/vendor/dist-server/core/tools/compare-chat.js +46 -0
- package/vendor/dist-server/core/tools/enrich-chat.js +50 -0
- package/vendor/dist-server/core/tools/variable-encoding.js +1 -0
- package/vendor/dist-server/core/types/settings.js +1 -0
- package/vendor/dist-server/core/utils/ab-evaluator.js +5 -0
- package/vendor/dist-server/core/utils/condition-evaluator.js +1 -0
- package/vendor/dist-server/core/utils/http-client.js +1 -0
- package/vendor/dist-server/core/utils/json-schema-to-form.js +1 -0
- package/vendor/dist-server/core/utils/logger.js +3 -0
- package/vendor/dist-server/core/utils/owner-scope.js +1 -0
- package/vendor/dist-server/core/utils/ownership.js +1 -0
- package/vendor/dist-server/core/utils/parallel-tool-executor.js +1 -0
- package/vendor/dist-server/core/utils/performance-tracker.js +3 -0
- package/vendor/dist-server/core/utils/prompt-optimizer.js +40 -0
- package/vendor/dist-server/core/utils/response-cache.js +1 -0
- package/vendor/dist-server/core/utils/schema-validator.js +1 -0
- package/vendor/dist-server/core/utils/streaming-optimizer.js +2 -0
- package/vendor/dist-server/core/utils/string-helpers.js +1 -0
- package/vendor/dist-server/core/utils/test-responses.js +9 -0
- package/vendor/dist-server/core/utils/text-utils.js +1 -0
- package/vendor/dist-server/core/utils/tool-form-trigger.js +1 -0
- package/vendor/dist-server/entrypoints/cli-bootstrap-run.js +1 -0
- package/vendor/dist-server/entrypoints/cli-deploy-run.js +1 -0
- package/vendor/dist-server/entrypoints/cli-deploy.js +1 -0
- package/vendor/dist-server/entrypoints/team-runner.js +1 -0
- package/vendor/dist-server/generated/toolbox-catalog.js +1 -0
- package/vendor/dist-server/index.js +2 -0
- package/vendor/dist-server/middleware/integration-logos.js +1 -0
- package/vendor/dist-server/middleware/plan-guard.js +1 -0
- package/vendor/dist-server/openapi/generator.js +1 -0
- package/vendor/dist-server/openapi/html-tool-spec.js +1 -0
- package/vendor/dist-server/routes/a2a-routes.js +1 -0
- package/vendor/dist-server/routes/a2a-server-routes.js +5 -0
- package/vendor/dist-server/routes/admin.js +1 -0
- package/vendor/dist-server/routes/assistants-routes.js +1 -0
- package/vendor/dist-server/routes/asyncapi-routes.js +1 -0
- package/vendor/dist-server/routes/auth.js +1 -0
- package/vendor/dist-server/routes/billing-routes.js +1 -0
- package/vendor/dist-server/routes/chat-llms.js +1 -0
- package/vendor/dist-server/routes/chat-tools.js +1 -0
- package/vendor/dist-server/routes/chat-traces.js +1 -0
- package/vendor/dist-server/routes/chats.js +1 -0
- package/vendor/dist-server/routes/clusters.js +1 -0
- package/vendor/dist-server/routes/compare.js +43 -0
- package/vendor/dist-server/routes/connectors-routes.js +1 -0
- package/vendor/dist-server/routes/consumptions-routes.js +1 -0
- package/vendor/dist-server/routes/data-admin-routes.js +1 -0
- package/vendor/dist-server/routes/data-transfer-routes.js +1 -0
- package/vendor/dist-server/routes/elastic-tool-execution-routes.js +1 -0
- package/vendor/dist-server/routes/geo-proxy-routes.js +1 -0
- package/vendor/dist-server/routes/golden-questions-routes.js +1 -0
- package/vendor/dist-server/routes/graph-registry.js +1 -0
- package/vendor/dist-server/routes/graph-templates-routes.js +1 -0
- package/vendor/dist-server/routes/helpdesk-routes.js +35 -0
- package/vendor/dist-server/routes/html-routes.js +1 -0
- package/vendor/dist-server/routes/index.js +1 -0
- package/vendor/dist-server/routes/indices.js +1 -0
- package/vendor/dist-server/routes/integrations-routes.js +1 -0
- package/vendor/dist-server/routes/langgraph.js +7 -0
- package/vendor/dist-server/routes/live-resources-routes.js +1 -0
- package/vendor/dist-server/routes/llm-analytics.js +1 -0
- package/vendor/dist-server/routes/llm-control-plane.js +1 -0
- package/vendor/dist-server/routes/llm.js +1 -0
- package/vendor/dist-server/routes/mcp-gateway-routes.js +1 -0
- package/vendor/dist-server/routes/mcp-query-routes.js +1 -0
- package/vendor/dist-server/routes/mcp-servers-routes.js +1 -0
- package/vendor/dist-server/routes/mcp-team-routes.js +1 -0
- package/vendor/dist-server/routes/mcp-tools-routes.js +1 -0
- package/vendor/dist-server/routes/me-routes.js +63 -0
- package/vendor/dist-server/routes/memories-routes.js +1 -0
- package/vendor/dist-server/routes/monitoring-analytics.js +12 -0
- package/vendor/dist-server/routes/monitoring.js +1 -0
- package/vendor/dist-server/routes/node-types-routes.js +171 -0
- package/vendor/dist-server/routes/nodes.js +1 -0
- package/vendor/dist-server/routes/packages.js +1 -0
- package/vendor/dist-server/routes/pdf.js +3 -0
- package/vendor/dist-server/routes/plan-routes.js +1 -0
- package/vendor/dist-server/routes/platform-requests-routes.js +1 -0
- package/vendor/dist-server/routes/platforms-routes.js +1 -0
- package/vendor/dist-server/routes/prompts-routes.js +1 -0
- package/vendor/dist-server/routes/proxy-logos.js +1 -0
- package/vendor/dist-server/routes/quality-routes.js +1 -0
- package/vendor/dist-server/routes/resources-ingest-routes.js +1 -0
- package/vendor/dist-server/routes/resources-routes.js +1 -0
- package/vendor/dist-server/routes/schema-routes.js +1 -0
- package/vendor/dist-server/routes/settings-original.js +1 -0
- package/vendor/dist-server/routes/settings.js +1 -0
- package/vendor/dist-server/routes/share-routes.js +1 -0
- package/vendor/dist-server/routes/sources-catalog-routes.js +1 -0
- package/vendor/dist-server/routes/sources-routes.js +1 -0
- package/vendor/dist-server/routes/team-optimizer-routes.js +1 -0
- package/vendor/dist-server/routes/team-schedule-routes.js +1 -0
- package/vendor/dist-server/routes/teams-routes.js +1 -0
- package/vendor/dist-server/routes/tool-analytics.js +1 -0
- package/vendor/dist-server/routes/tool-history-routes.js +1 -0
- package/vendor/dist-server/routes/tool-metrics-routes.js +1 -0
- package/vendor/dist-server/routes/toolbox-import-routes.js +1 -0
- package/vendor/dist-server/routes/tools-routes.js +5 -0
- package/vendor/dist-server/routes/transcribe-routes.js +1 -0
- package/vendor/dist-server/routes/triggers.js +1 -0
- package/vendor/dist-server/routes/versions-routes.js +1 -0
- package/vendor/dist-server/routes/webhooks-routes.js +1 -0
- package/vendor/dist-server/scripts/add-label-to-tools.js +4 -0
- package/vendor/dist-server/scripts/migrate-assistants-to-mcp.js +10 -0
- package/vendor/dist-server/scripts/migrate-chat-runs.js +8 -0
- package/vendor/dist-server/scripts/migrate-mcp-protocol.js +8 -0
- package/vendor/dist-server/scripts/migrate-mcp-to-platforms.js +15 -0
- package/vendor/dist-server/services/alert-evaluator.js +3 -0
- package/vendor/dist-server/services/auth.js +1 -0
- package/vendor/dist-server/services/billing-service.js +1 -0
- package/vendor/dist-server/services/chat-title-generator.js +12 -0
- package/vendor/dist-server/services/clone/clone-executor.js +1 -0
- package/vendor/dist-server/services/clone/closure-resolver.js +3 -0
- package/vendor/dist-server/services/clone/entity-graph.js +3 -0
- package/vendor/dist-server/services/clone/team-bundle-bootstrap.js +1 -0
- package/vendor/dist-server/services/clone/team-bundle-crypto.js +1 -0
- package/vendor/dist-server/services/clone/team-bundle-encrypted.js +1 -0
- package/vendor/dist-server/services/clone/team-bundle.js +1 -0
- package/vendor/dist-server/services/cluster-service.js +1 -0
- package/vendor/dist-server/services/connection-adapters.js +1 -0
- package/vendor/dist-server/services/connectors-service.js +10 -0
- package/vendor/dist-server/services/cost-forecast-service.js +1 -0
- package/vendor/dist-server/services/eui-ssr-renderer.js +4 -0
- package/vendor/dist-server/services/graph-canvas/full-structure-builder.js +1 -0
- package/vendor/dist-server/services/graph-templates-service.js +13 -0
- package/vendor/dist-server/services/guest-service.js +1 -0
- package/vendor/dist-server/services/html-service.js +1 -0
- package/vendor/dist-server/services/langgraph-service.js +2 -0
- package/vendor/dist-server/services/leaflet-render-service.js +80 -0
- package/vendor/dist-server/services/live-resources-service.js +16 -0
- package/vendor/dist-server/services/mcp-app-tester-package.js +1 -0
- package/vendor/dist-server/services/mcp-gateway/executors/openapi-executor.js +1 -0
- package/vendor/dist-server/services/mcp-gateway/gateway-grant-service.js +2 -0
- package/vendor/dist-server/services/team-optimizer-service.js +1 -0
- package/vendor/dist-server/services/trace-bus-sink.js +1 -0
- package/vendor/dist-server/services/user-provisioning-service.js +3 -0
- package/vendor/dist-server/templates/mcp-app-tester/src/mcp-http.js +3 -0
- package/vendor/dist-server/templates/mcp-app-tester/src/server.js +1 -0
- package/vendor/dist-server/utils.js +1 -0
- package/vendor/dist-server/ws/assistant-executor.js +7 -0
- package/vendor/dist-server/ws/classify-streamed-json-block.js +1 -0
- package/vendor/dist-server/ws/collect-response-generator-node-ids.js +1 -0
- package/vendor/dist-server/ws/extractors/blockkit-extractor.js +1 -0
- package/vendor/dist-server/ws/extractors/echarts-extractor.js +1 -0
- package/vendor/dist-server/ws/extractors/eui-extractor.js +1 -0
- package/vendor/dist-server/ws/extractors/form-extractor.js +1 -0
- package/vendor/dist-server/ws/extractors/index.js +1 -0
- package/vendor/dist-server/ws/extractors/leaflet-extractor.js +1 -0
- package/vendor/dist-server/ws/extractors/mantine-extractor.js +1 -0
- package/vendor/dist-server/ws/extractors/markdown-extractor.js +7 -0
- package/vendor/dist-server/ws/extractors/mermaid-extractor.js +1 -0
- package/vendor/dist-server/ws/extractors/recharts-extractor.js +1 -0
- package/vendor/dist-server/ws/extractors/remotion-extractor.js +1 -0
- package/vendor/dist-server/ws/handler.js +66 -0
- package/vendor/dist-server/ws/parsers/anthropic-parser.js +7 -0
- package/vendor/dist-server/ws/parsers/base-parser.js +3 -0
- package/vendor/dist-server/ws/parsers/gemini-parser.js +8 -0
- package/vendor/dist-server/ws/parsers/index.js +1 -0
- package/vendor/dist-server/ws/parsers/parse-json-blocks.js +1 -0
- package/vendor/dist-server/ws/types.js +0 -0
- package/vendor/dist-server/ws/utils.js +1 -0
- package/vendor/shared/engine-vars.ts +51 -0
- package/vendor/shared/llm-providers-config.ts +69 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import{randomUUID as Gt}from"node:crypto";import{writeFileSync as Ht}from"node:fs";import{PassThrough as zt,Transform as qt}from"node:stream";import{HumanMessage as Ct}from"@langchain/core/messages";import{MemorySaver as Kt}from"@langchain/langgraph-checkpoint";import{EventEmitter as Vt}from"node:events";import{parse as Qt,Allow as wt}from"partial-json";import{parseJsonBlocks as Xt}from"./parsers/parse-json-blocks";import{buildAppFromDefinition as Yt}from"../core/graph/graph-builder";import{buildKibanaAgentApp as Zt,runKibanaAgentConversation as en}from"../core/graph/kibana-agent-executor";import{buildA2aAgentApp as tn,runA2aAgentConversation as nn}from"../core/graph/a2a-agent-executor";import{isDelegatedAgentApp as sn,adaptDelegatedAgentApp as on}from"../core/graph/delegated-agent-adapter";import{getGraph as $t,getDefaultGraphForOwner as an}from"../core/services/graph-registry-service";import{DashboardSchema as rn,UiBlockSchema as ln}from"../core/schema/ui";import{findTestResponse as cn,streamTestResponseAsync as dn}from"../core/utils/test-responses";import{userToken as Tt,getUserProviders as un}from"../services/auth";import{PerformanceTracker as pn}from"../core/utils/performance-tracker";import{StreamingOptimizer as gn,StreamingMetrics as mn,defaultStreamingConfig as hn}from"../core/utils/streaming-optimizer";import{dashboardCacheInstance as lt,dataCacheInstance as Dt}from"../core/utils/response-cache";import{safeValidateBlocks as fn}from"../core/utils/schema-validator";import{config as Wt}from"../core/config";import{Client as yn}from"@elastic/elasticsearch";import{send as l,waitForDrain as Mt}from"./utils";import{RechartsExtractor as Sn,EchartsExtractor as kn,EuiExtractor as bn,MermaidExtractor as In,FormExtractor as _n,LeafletExtractor as vn,BlockkitExtractor as Cn,MantineExtractor as wn,RemotionExtractor as $n}from"./extractors";import{createParser as Tn}from"./parsers";import{classifyStreamedJsonBlock as Wn}from"./classify-streamed-json-block";import{collectResponseGeneratorNodeIds as An}from"./collect-response-generator-node-ids";import{evaluateCondition as Nn}from"../core/utils/condition-evaluator";import*as Jt from"../core/services/chat-tools-service";import*as xn from"../core/services/chat-llms-service";import{createChatRun as En,completeChatRun as st,classifyError as At}from"../core/services/chat-runs-service";import{registerActiveRunMeta as On,unregisterActiveRunMeta as Qe}from"../core/runtime/active-runs-registry";import{setSystemPromptForRun as Dn}from"../core/runtime/system-prompt-cache";import{createChatTrace as Mn}from"../core/services/chat-traces-service";import{parseChatModelEndUsage as Jn}from"../core/services/run-analytics-collector";import{loadModelIdPricingTable as Pn}from"../core/services/llm-pricing-service";import{lookupModelIdPrice as Rn,computeCostUsdFromPricing as Bn}from"../core/services/llm-pricing-pure";import{buildEnrichedChatMemoryContext as Ln}from"../core/services/chats-service";import{buildLTMContext as jn,getLastChatTraceId as Fn}from"../core/services/memories-service";import{stripLoneSurrogates as Pt,truncateUtf16Safe as Un}from"../core/utils/text-utils";import{registerRunTraceCollector as Gn,unregisterRunTraceCollector as Nt}from"./utils";import{validateShareToken as Rt,incrementUsesCount as Bt,verifyGuestJWT as Hn,checkEmbedBudget as zn,consumeEmbedBudget as qn}from"../core/services/share-service";const Lt=256*1024,Kn=500,se=new Map,ct=new Map;setInterval(()=>{const i=Date.now(),I=600*1e3;for(const[t,p]of ct.entries())i-p.timestamp>I&&(console.log(`[HITL] Expiring stale pending interrupt for thread: ${t}`),ct.delete(t))},120*1e3),setInterval(()=>{const i=Date.now(),I=1800*1e3;for(const[t,p]of se.entries())i-p.startTime>I&&(console.log(`[ActiveRuns] Cleaning up stale run: ${t}`),p.abortController.abort(),se.delete(t),Qe(t))},300*1e3);class jt extends qt{constructor(t,p,c,m){super({decodeStrings:!1,highWaterMark:Lt});this.ws=t;this.token=p;this.runId=c;this.responseParser=Tn(m),console.log(`[JsonSlicer] Using parser for provider: ${m||"default (anthropic)"}`),this.responseParser.on("markdownChunk",f=>{console.log("[WS] Markdown streaming DISABLED - chunk received but not sent:",f.slice(0,50),"...")}),this.rechartsExtractor.on("rechartsBlock",f=>{console.log("[WS] Sending recharts_token"),l(this.ws,{type:"recharts_token",runId:this.runId,block:f})}),this.echartsExtractor.on("echartsBlock",f=>{console.log("[WS] Sending echarts_token"),l(this.ws,{type:"echarts_token",runId:this.runId,block:f})}),this.euiExtractor.on("euiBlock",f=>{console.log("[WS] Sending eui_token"),l(this.ws,{type:"eui_token",runId:this.runId,block:f})}),this.mermaidExtractor.on("mermaidBlock",f=>{console.log("[WS] Sending mermaid_token"),l(this.ws,{type:"mermaid_token",runId:this.runId,block:f})}),this.remotionExtractor.on("remotionBlock",f=>{console.log("[WS] Sending remotion_token"),l(this.ws,{type:"remotion_token",runId:this.runId,block:f})}),this.formExtractor.on("formBlock",f=>{console.log("[WS] Sending form_token for tool:",f.tool),l(this.ws,{type:"form_token",runId:this.runId,block:f})}),this.leafletExtractor.on("leafletBlock",f=>{console.log("[WS] Sending leaflet_token"),l(this.ws,{type:"leaflet_token",runId:this.runId,block:f})}),this.blockkitExtractor.on("blockkitBlock",f=>{console.log("[WS] Sending blockkit_token"),l(this.ws,{type:"blockkit_token",runId:this.runId,block:f})}),this.mantineExtractor.on("mantineBlock",f=>{console.log("[WS] Sending mantine_token"),l(this.ws,{type:"mantine_token",runId:this.runId,block:f})})}buffer="";lastEmit=0;partialBlocks=[];responseParser;rechartsExtractor=new Sn;echartsExtractor=new kn;euiExtractor=new bn;mermaidExtractor=new In;formExtractor=new _n;leafletExtractor=new vn;blockkitExtractor=new Cn;mantineExtractor=new wn;remotionExtractor=new $n;processedHashes=new Set;isProcessingComplete=!1;lastPushHadData=!1;inThinkingBlock=!1;thinkingBuffer="";markComplete(){console.log("[JsonSlicer] markComplete"),this.isProcessingComplete=!0}getTotalMarkdownContent(){return this.responseParser.getTotalContent()}_transform(t,p,c){console.log("[JsonSlicer] _transform",t.slice(0,100));try{this.buffer+=t,this.rechartsExtractor.processChunk(t),this.echartsExtractor.processChunk(t),this.euiExtractor.processChunk(t),this.mermaidExtractor.processChunk(t),this.formExtractor.processChunk(t),this.leafletExtractor.processChunk(t),this.blockkitExtractor.processChunk(t),this.mantineExtractor.processChunk(t),this.remotionExtractor.processChunk(t),this.processBuffer(),this.push(""),this.lastPushHadData=!1,c()}catch(m){c(m)}}extractJsonObjects(t){const p=[];let c=0,m=-1,f=!1,_=!1;for(let ee=0;ee<t.length;ee++){const de=t[ee];if(_){_=!1;continue}if(de==="\\"){_=!0;continue}if(de==='"'&&!_){f=!f;continue}if(!f){if(de==="{")c===0&&(m=ee),c++;else if(de==="}"&&(c--,c===0&&m>=0)){const Be=t.substring(m,ee+1);p.push(Be),m=-1}}}return p}processBuffer(){if(console.log("[JsonSlicer] processBuffer",this.buffer),this.isProcessingComplete)return;let t=this.buffer;t=t.replace(/```json/gi,""),t=t.replace(/```\s*\{/g,`
|
|
2
|
+
{`),t=t.replace(/\}\s*\{/g,`}
|
|
3
|
+
{`),console.log("[JsonSlicer] \u2699\uFE0F Buffer after regex transformations:"),console.log(" Length:",t.length),console.log(" Newlines:",(t.match(/\n/g)||[]).length),console.log(" First 300 chars:",t.substring(0,300)),console.log(" Contains }```{:",t.includes("}```{")),console.log(" Contains }{:",t.includes("}{")),t=t.replace(/```json\s*\n({[\s\S]*?})\n\s*```/g,"$1"),t=t.replace(/```json\s*\n({[\s\S]*?})```/g,"$1"),t=t.replace(/```json\s*({[\s\S]*?})\s*```/g,"$1"),t=t.replace(/```\s*\n({[\s\S]*?})\n\s*```/g,"$1"),t=t.replace(/```\s*({[\s\S]*?})\s*```/g,"$1"),t=t.replace(/```json\\n({[^`]*?})\\n```/g,"$1"),t=t.replace(/```json\\s*\\n?({[^`]*?})\\s*\\n?```/g,"$1"),console.log("[JsonSlicer] Unwrapped markdown code blocks"),console.log("[JsonSlicer] \u{1F50D} Attempting to extract JSON objects from buffer (length:",t.length,")"),console.log("[JsonSlicer] Buffer content (first 500):",t.substring(0,500));const p=this.extractJsonObjects(t);if(console.log(`[JsonSlicer] \u2705 Found ${p.length} complete JSON object(s)`),p.length>0){for(let f=0;f<p.length;f++){const _=p[f];if(console.log("[JsonSlicer] \u{1F4E6} Processing JSON object",f+1,"of",p.length,":",_.substring(0,100)),_.includes("\u{1F527} **Calling")||_.includes("\u{1F4CA} **")){console.log("[JsonSlicer] \u23ED\uFE0F Skipping tool calling message");continue}this.tryParseJsonLine(_),this.lastPushHadData=!0}const c=p[p.length-1],m=t.lastIndexOf(c);m>=0&&(this.buffer=t.substring(m+c.length).trim(),console.log("[JsonSlicer] \u{1F4DD} Buffer updated, remaining:",this.buffer.length,"chars"))}if(this.partialBlocks.length===0&&t.startsWith("{")&&t.endsWith("}")&&this.isValidJsonStructure(t))try{const c=this.sanitizeJson(t),m=JSON.parse(c);if(console.log("[JsonSlicer] Parsed complete buffer:",Object.keys(m)),this.isDashboardFormat(m)){console.log("[JsonSlicer] Found complete dashboard format in buffer");const _=this.hashContent(c);if(!this.processedHashes.has(_)){this.processedHashes.add(_),this.emit("data",{type:"dashboard",data:m}),this.buffer="";return}}const f=this.convertToMockDashboard(m);if(this.isDashboardFormat(f)){console.log("[JsonSlicer] Converted to dashboard format");const _=this.hashContent(c);if(!this.processedHashes.has(_)){this.processedHashes.add(_),this.emit("data",{type:"dashboard",data:f}),this.buffer="";return}}}catch(c){console.log("[JsonSlicer] Complete buffer parsing failed:",c.message)}this.maybeEmitPartialBlocks()}emitCompleteJson(t){console.log("[JsonSlicer] emitCompleteJson");try{console.log("[JsonSlicer] Emitting complete JSON:",t.slice(0,200));const p=this.sanitizeJson(t),c=JSON.parse(p);if(this.isDashboardFormat(c)){console.log("[JsonSlicer] Pushing dashboard"),this.push({type:"dashboard",data:c});return}if(this.isDashboardBlock(c)){console.log("[JsonSlicer] Pushing block"),this.partialBlocks.push(c),this.push({type:"block",data:c});return}console.log("[JsonSlicer] Pushing generic JSON"),this.push({type:"json",data:c})}catch(p){console.warn("[JsonSlicer] Parse error:",p,"JSON:",t.slice(0,200))}}isDashboardFormat(t){return console.log("[JsonSlicer] isDashboardFormat"),t&&typeof t=="object"&&t.session_id&&t.result&&Array.isArray(t.result.content)}convertToMockDashboard(t){if(console.log("[JsonSlicer] convertToMockDashboard"),t&&typeof t=="object"&&t.cluster_overview){console.log("[JsonSlicer] Converting cluster_overview to dashboard format");const p=[];for(const[c,m]of Object.entries(t.cluster_overview))typeof m=="object"&&m!==null&&p.push({type:"markdown",title:`\u{1F4CB} ${c.replace(/_/g," ").replace(/\b\w/g,f=>f.toUpperCase())}`,body:this.objectToMarkdown(m)});return{session_id:this.token,result:{content:p}}}return t}convertRawJsonToDashboard(t){if(console.log("[JsonSlicer] convertRawJsonToDashboard"),!t||typeof t!="object")return null;console.log("[JsonSlicer] Converting raw JSON data to dashboard format");const p=[];if(t.nodes&&Array.isArray(t.nodes)){p.push({type:"markdown",title:"\u{1F5A5}\uFE0F Nodes Overview",body:`**Total Nodes:** ${t.nodes.length}
|
|
4
|
+
|
|
5
|
+
${t.nodes.map(m=>`- **${m.key||"Unknown"}**: ${m.info?.roles?.join(", ")||"No roles"}`).join(`
|
|
6
|
+
`)}`});const c=t.nodes.flatMap(m=>m.info?.roles||[]);if(c.length>0){const m=c.reduce((f,_)=>(f[_]=(f[_]||0)+1,f),{});p.push({type:"echarts",title:"\u{1F4CA} Node Roles Distribution",options:{tooltip:{},legend:{top:"bottom"},series:[{type:"pie",radius:"50%",data:Object.entries(m).map(([f,_])=>({name:f,value:_}))}]}})}}if(t.cluster_name||t.status||t.number_of_nodes){const c=[];t.cluster_name&&c.push(`**Cluster Name:** ${t.cluster_name}`),t.status&&c.push(`**Status:** ${t.status}`),t.number_of_nodes&&c.push(`**Nodes:** ${t.number_of_nodes}`),t.number_of_data_nodes&&c.push(`**Data Nodes:** ${t.number_of_data_nodes}`),p.push({type:"markdown",title:"\u{1F3AF} Cluster Information",body:c.join(`
|
|
7
|
+
`)})}return t.indices&&typeof t.indices=="object"&&p.push({type:"markdown",title:"\u{1F4DA} Indices Summary",body:this.objectToMarkdown(t.indices)}),p.length===0&&p.push({type:"markdown",title:"\u{1F4CA} Data Overview",body:this.objectToMarkdown(t)}),{session_id:this.token,result:{content:p}}}objectToMarkdown(t,p=0){console.log("[JsonSlicer] objectToMarkdown");const c=" ".repeat(p);let m="";for(const[f,_]of Object.entries(t)){const ee=f.replace(/_/g," ").replace(/\b\w/g,de=>de.toUpperCase());typeof _=="object"&&_!==null&&!Array.isArray(_)?(m+=`${c}**${ee}:**
|
|
8
|
+
`,m+=this.objectToMarkdown(_,p+1)):Array.isArray(_)?(m+=`${c}**${ee}:**
|
|
9
|
+
`,_.forEach(de=>{m+=`${c} - ${typeof de=="string"?de:JSON.stringify(de)}
|
|
10
|
+
`})):m+=`${c}**${ee}:** ${_}
|
|
11
|
+
`}return m}processBufferSafe(){console.log("[JsonSlicer] processBufferSafe");const t=this.buffer.split(`
|
|
12
|
+
`);for(const p of t){const c=p.trim();if(!c||c.startsWith("```")||c.startsWith("#"))continue;const m=this.extractJsonLine(c);if(m)try{console.log("[JsonSlicer] Processing JSON line:",m.substring(0,80)+"...");const f=this.sanitizeJson(m),_=JSON.parse(f);this.isDashboardBlock(_)?(console.log("[JsonSlicer] Safe processing - emitting block:",_.type),this.partialBlocks.push(_),this.emit("data",{type:"block",data:_})):(console.log("[JsonSlicer] Safe processing - generic JSON"),this.emit("data",{type:"json",data:_}))}catch{}}}hashContent(t){console.log("[JsonSlicer] hashContent");let p=0;for(let c=0;c<t.length;c++){const m=t.charCodeAt(c);p=(p<<5)-p+m,p=p&p}return p.toString()}isValidJsonStructure(t){console.log("[JsonSlicer] isValidJsonStructure");let p=0,c=0,m=!1,f=!1;for(let _=0;_<t.length;_++){const ee=t[_];if(f){f=!1;continue}if(ee==="\\"){f=!0;continue}if(ee==='"'&&!f){m=!m;continue}if(!m){if(ee==="{")p++;else if(ee==="}"){if(p--,p<0)return!1}else if(ee==="[")c++;else if(ee==="]"&&(c--,c<0))return!1}}return p===0&&c===0}isDashboardBlock(t){return console.log("[JsonSlicer] isDashboardBlock"),t&&typeof t=="object"&&t.type&&["markdown","echarts","recharts","eui","table","mermaid","leaflet","blockkit","mantine","remotion"].includes(t.type)}sanitizeJson(t){console.log("[JsonSlicer] sanitizeJson");let p=t;return[/"function\s*\([^)]*\)\s*\{[^}]*\}"/g,/function\([^)]*[^"]/g,/:\s*function\s*\([^)]*\)/g,/"\s*\([^)]*\)\s*=>\s*[^"]*"/g,/"[^"]*function\s*\(/g].forEach(m=>{p=p.replace(m,'""')}),p=p.replace(/,\s*,/g,",").replace(/,(\s*[}\]])/g,"$1").replace(/:\s*,/g,': ""').replace(/"\s*:\s*$/gm,'""'),p}maybeEmitPartialBlocks(){console.log("[JsonSlicer] maybeEmitPartialBlocks");const t=Date.now();this.partialBlocks.length>0&&t-this.lastEmit>Kn&&(this.emit("data",{type:"partial_dashboard",data:{session_id:this.token,result:{content:[...this.partialBlocks]}}}),this.lastEmit=t)}tryParseJsonLine(t){if(console.log("[JsonSlicer] tryParseJsonLine"),!!this.isValidJsonStructure(t))try{const p=this.sanitizeJson(t),c=JSON.parse(p);console.log("[JsonSlicer] Parsed JSON line successfully",p,t);const m=this.hashContent(p);if(this.processedHashes.has(m)){console.log("[JsonSlicer] Skipping duplicate JSON line");return}this.processedHashes.add(m),this.isDashboardBlock(c)?(console.log("[JsonSlicer] Parsed dashboard block:",c.type),this.partialBlocks.push(c),this.emit("data",{type:"block",data:c})):(console.log("[JsonSlicer] Parsed generic JSON"),this.emit("data",{type:"json",data:c}))}catch(p){console.warn("[JsonSlicer] Failed to parse JSON line:",p.message,"JSON:",t.slice(0,100))}}_flush(t){if(console.log("[JsonSlicer] _flush"),this.responseParser.complete(),this.rechartsExtractor.complete(),this.echartsExtractor.complete(),this.euiExtractor.complete(),this.mermaidExtractor.complete(),this.leafletExtractor.complete(),this.blockkitExtractor.complete(),this.mantineExtractor.complete(),this.remotionExtractor.complete(),this.partialBlocks.length===0&&this.buffer.trim()){console.log("[JsonSlicer] Processing final buffer as no blocks were emitted during streaming");const p=this.buffer.trim();if(p.startsWith("{")&&p.endsWith("}"))try{const c=this.sanitizeJson(p),m=JSON.parse(c);if(this.isDashboardFormat(m)){console.log("[JsonSlicer] Found complete dashboard in final buffer");const f=this.hashContent(c);this.processedHashes.has(f)||(this.processedHashes.add(f),this.emit("data",{type:"dashboard",data:m}))}else{const f=this.convertToMockDashboard(m);if(this.isDashboardFormat(f)){console.log("[JsonSlicer] Converted to dashboard format in final buffer");const _=this.hashContent(c);this.processedHashes.has(_)||(this.processedHashes.add(_),this.emit("data",{type:"dashboard",data:f}))}}}catch(c){console.log("[JsonSlicer] Final buffer parsing failed:",c.message)}}else this.partialBlocks.length>0&&console.log("[JsonSlicer] Blocks were processed during streaming, skipping final buffer processing");t()}}class Ft{constructor(I,t,p,c){this.ws=I;this.token=t;this.runId=p;this.assistantId=c}blocks=[];isComplete=!1;addBlock(I){console.log("[DashboardStreamManager] addBlock called with:",I.type,I.title),console.log("[DashboardStreamManager] BEFORE push - blocks.length:",this.blocks.length),this.blocks.push(I),console.log("[DashboardStreamManager] AFTER push - blocks.length:",this.blocks.length),console.log("[DashboardStreamManager] Current blocks:",this.blocks.map(t=>t.title).join(" | "));try{console.log("[DashboardStreamManager] Validating block...");const t=ln.parse(I);console.log("[DashboardStreamManager] Block validated successfully, sending to client"),l(this.ws,{type:"ui",runId:this.runId,sessionId:this.token,phase:"partial",content:[t],assistantId:this.assistantId})}catch(t){console.log(`[DashboardStreamManager] Validation failed, wrapping in raw block: ${t.message}`);const p={type:"raw",id:I.id||`raw-${Date.now()}`,title:I.title||"Contenu non format\xE9",content:I,error:t.message};l(this.ws,{type:"ui",runId:this.runId,sessionId:this.token,phase:"partial",content:[p],assistantId:this.assistantId})}}setDashboard(I){console.log("[DashboardStreamManager] setDashboard called with:",JSON.stringify(I).substring(0,200));try{const t=rn.parse(I),p=t.session_id;console.log("[DashboardStreamManager] Dashboard validated successfully, content blocks:",t.result.content.length),this.blocks=t.result.content.filter(c=>typeof c.title=="string").map(c=>c.type==="echarts"&&!c.options&&c.option?{...c,options:c.option,title:c.title}:{...c,title:c.title}),this.isComplete=!0,console.log("[DashboardStreamManager] Sending FINAL UI blocks to client:",this.blocks.length,"blocks"),console.log("[DashboardStreamManager] Block types:",this.blocks.map(c=>c.type).join(", ")),console.log("[DashboardStreamManager] Block titles:",this.blocks.map(c=>c.title).join(" | ")),console.log("[DashboardStreamManager] validated.result.content length:",t.result.content.length),console.log("[DashboardStreamManager] Content preview:",JSON.stringify(t.result.content).substring(0,300)),l(this.ws,{type:"ui",runId:this.runId,sessionId:p,phase:"final",content:t.result.content,assistantId:this.assistantId}),console.log("[DashboardStreamManager] FINAL UI message sent successfully")}catch(t){console.log(`[DashboardStreamManager] Dashboard validation failed, wrapping in raw block: ${t.message}`);const p={type:"raw",id:`raw-dashboard-${Date.now()}`,title:"Dashboard non format\xE9",content:I,error:t.message};this.blocks=[p],this.isComplete=!0,l(this.ws,{type:"ui",runId:this.runId,sessionId:I?.session_id||this.token,phase:"final",content:[p],assistantId:this.assistantId})}}getStatus(){return console.log("[DashboardStreamManager] getStatus called - blocks.length:",this.blocks.length,"isComplete:",this.isComplete),console.log("[DashboardStreamManager] getStatus - blocks:",this.blocks.map(I=>I.title).join(" | ")),{blocksCount:this.blocks.length,hasBlocks:this.blocks.length>0,isComplete:this.isComplete,sessionId:this.token}}getBlocks(){return[...this.blocks]}sendFallbackBlock(I){if(this.blocks.length>0){console.log("[DashboardStreamManager] Blocks already emitted, no fallback needed");return}console.log(`[DashboardStreamManager] No blocks emitted, sending fallback with ${I.length} chars`);let t=I;t=t.replace(/\{\s*"type"\s*:\s*"(echarts|recharts|eui|markdown)"\s*,[\s\S]*?\}/gs,""),t=t.replace(/^\s*\{\s*$/gm,""),t=t.replace(/^\s*\}\s*$/gm,""),t=t.replace(/\n{3,}/g,`
|
|
13
|
+
|
|
14
|
+
`).trim(),t!==I&&console.log(`[DashboardStreamManager] Filtered ${I.length-t.length} chars of JSON from fallback`);const p={type:"markdown",id:`fallback-${Date.now()}`,body:t};this.blocks.push(p),this.isComplete=!0,l(this.ws,{type:"ui",runId:this.runId,sessionId:this.token,phase:"final",content:[p],assistantId:this.assistantId})}}function Vn(i){let I=i;return console.log("[Sanitizer] Original JSON preview:",i.slice(0,20)),[/"function\s*\([^)]*\)\s*\{[^}]*\}"/g,/function\([^)]*[^"]/g,/:\s*function\s*\([^)]*\)/g,/"\s*\([^)]*\)\s*=>\s*[^"]*"/g,/"[^"]*function\s*\(/g,/"[^"]*":\s*function\([^)]*$/gm].forEach((p,c)=>{const m=I;I=I.replace(p,'""'),m!==I&&console.log(`[Sanitizer] Pattern ${c} matched and replaced`)}),I=I.replace(/,\s*,/g,",").replace(/,(\s*[}\]])/g,"$1").replace(/:\s*,/g,': ""').replace(/"\s*:\s*$/gm,': ""'),console.log("[Sanitizer] Cleaned JSON preview:",I.slice(0,20)),I}async function Qn(i){try{const{loadLLMConfigsForGraph:I}=await import("../core/graph/graph-builder"),t={provider:"anthropic",model:"claude-sonnet-4-5",temperature:0,maxTokens:8e3,streaming:!0,apiKey:Wt.llm.apiKey||"",baseURL:Wt.llm.baseURL},p=await I(i,t),c=i.nodes.find(f=>f.type==="assistant"||f.type==="system");if(!c)return console.warn("[WS] No assistant/system node found in graph, using fallback config"),{provider:t.provider,model:t.model,llmConfigs:p};const m=p.get(c.id);return m?{provider:m.provider,model:m.model,llmConfigs:p}:(console.warn(`[WS] No LLM config found for node ${c.id}, using fallback`),{provider:t.provider,model:t.model,llmConfigs:p})}catch(I){return console.error("[WS] Error extracting LLM config from graph:",I),null}}const Ut=new yn(Wt.elasticsearch);async function Xn(i,I,t){const c=(await Ut.search({index:".stkxp_tools",body:{query:{term:{name:i}},size:1}})).hits.hits[0];if(!c)throw new Error(`Tool "${i}" not found in .stkxp_tools`);const m=c._source;let f={};try{f=JSON.parse(m.openApiMeta??"{}")}catch{throw new Error(`Invalid openApiMeta for tool "${i}"`)}const{method:_,path:ee,servers:de,platformId:Be}=f;if(!_||!ee)throw new Error(`Tool "${i}" is missing method or path in openApiMeta`);let Le=null;if(Be)try{const he=(await Ut.search({index:".stkxp_platforms",body:{query:{term:{id:Be}},size:1}})).hits.hits[0];he&&(Le=he._source)}catch(me){console.warn(`[executeToolDirectly] Could not load platform ${Be}:`,me.message)}const Ce=(de?.[0]??Le?.config?.baseUrl??"").replace(/\/+$/,"");if(!Ce)throw new Error(`No baseUrl resolved for tool "${i}" (platformId=${Be})`);const G=Le?.config?.auth,dt=(()=>{if(!G)return{};switch(G.type){case"bearer":return G.bearerToken?{Authorization:`Bearer ${G.bearerToken}`}:{};case"apiKey":if(G.apiKeyHeader&&G.apiKeyValue){const me=G.apiKeySecret?`${G.apiKeyValue}:${G.apiKeySecret}`:G.apiKeyValue;return{[G.apiKeyHeader]:me}}return{};case"basic":return G.username&&G.password?{Authorization:`Basic ${Buffer.from(`${G.username}:${G.password}`).toString("base64")}`}:{};default:return{}}})();let Xe={};try{Xe=JSON.parse(m.inputSchema??"{}")}catch{}const ht=Xe.properties??{};let M=ee;const e={},V={},Se={};for(const[me,he]of Object.entries(I)){const A=ht[me],We=A?.["x-openapi-in"],be=A?.["x-openapi-name"]??me;We==="path"?M=M.replace(`:${be}`,encodeURIComponent(String(he))):We==="header"?V[be]=String(he):We==="body"||!We&&_.toUpperCase()!=="GET"?Se[be]=he:e[be]=Array.isArray(he)?he.join(","):String(he)}const oe=new URLSearchParams(e).toString(),r=`${Ce}${M}${oe?`?${oe}`:""}`,xe=Object.keys(Se),we=xe.length===1&&xe[0]==="body"?Se.body:Se,$e=xe.length>0;console.log(`[executeToolDirectly] ${_.toUpperCase()} ${r}`);const ze={method:_.toUpperCase(),headers:{"Content-Type":"application/json",Accept:"application/json",...dt,...V},signal:AbortSignal.timeout(3e4),...$e?{body:typeof we=="string"?we:JSON.stringify(we)}:{}},Je=await fetch(r,ze),k=await Je.text();if(!Je.ok)throw new Error(`HTTP ${Je.status} ${Je.statusText}: ${k.slice(0,500)}`);try{return JSON.parse(k)}catch{return k}}async function Ks(i,I,t){console.log("[WS] MCP auto-discovery enabled - servers will be loaded per-topic"),console.log("[WS] Client connected");const p=new Kt,c=new Map,m=[],f=M=>{m.push(M)};i.on("message",f);let _,ee,de=Tt(I)?.username??"",Be=!1,Le;const Ce=Hn(I);if(Ce){de=Ce.guestEmail;const{valid:M,link:e,error:V}=await Rt(Ce.shareLinkId,Ce.guestEmail,!1);if(!M||!e){console.warn(`[WS] Invalid guest share token for '${Ce.guestEmail}': ${V}`),l(i,{type:"error",error:V??"Invalid share link"}),i.close();return}if(_=e.ownerId,ee=e.label,Bt(Ce.shareLinkId).catch(()=>{}),console.log(`[WS] \u{1F517} Guest run: guest='${Ce.guestEmail}' \u2192 owner='${_}'`),e.embed&&(Be=!0,Le=Ce.shareLinkId,!zn(e))){console.warn(`[WS] Embed budget exceeded for link '${Le}'`),l(i,{type:"error",error:"This assistant has reached its usage limit for today."}),i.close();return}}else if(t){const{valid:M,link:e,error:V}=await Rt(t,de);if(!M||!e){console.warn(`[WS] Invalid share token '${t}' for '${de}': ${V}`),l(i,{type:"error",error:V??"Invalid share link"}),i.close();return}_=e.ownerId,ee=e.label,Bt(t).catch(()=>{}),console.log(`[WS] \u{1F517} Shared run: guest='${de}' \u2192 owner='${_}' team='${e.teamId}'`)}const G=()=>_??Tt(I)?.username??"";let dt=null;try{const M=G();M&&(console.log(`[WS] Fetching providers for user: ${M}`),dt=un(M).then(e=>(console.log("[WS] User providers:",e?`${e.length} providers`:"none"),e)).catch(e=>(console.error("[WS] Error fetching user providers:",e),null)))}catch(M){console.error("[WS] Error decoding token:",M)}const Xe=async(M,e,V,Se,oe,r,xe,we,$e,ze,Je,k,me,he,A,We)=>{const be=dt?await dt:null,ke=oe?.graphId;if(ke){console.log(`[WS] \u{1F3AF} Loading graph for assistant: ${oe?.name||"unknown"}`),console.log("[WS] \u{1F4CA} Assistant details:",{assistantId:oe?.assistantId,name:oe?.name,package:oe?.package,topic:oe?.topic,graphId:oe?.graphId,priority:oe?.priority}),console.log(`[WS] Loading graph from registry: ${ke}`);try{let P=await $t(ke);if(console.log(P),!P||P.enabled===!1){const E=P?`disabled (name: ${P.name})`:"not found in registry";console.warn(`[WS] Graph '${ke}' ${E} \u2014 falling back to owner default`);const Ye=G(),je=await an(Ye);if(!je)throw new Error(`Graph '${ke}' ${E}. No default graph configured for user '${Ye}'.`);console.log(`[WS] Using default graph: ${je.id} (${je.name})`),P=je}console.log(`[WS] \u2705 Using graph: ${P.name} (v${P.version})`),console.log(`[WS] Graph nodes: ${(P.nodes||[]).length}, edges: ${(P.edges||[]).length}`);const J=await Qn(P);if(P.graphType==="kibana_agent")return console.log(`[WS] \u{1F916} Kibana Agent Builder path for graph: ${P.name}`),{app:Zt(P),llmConfig:{provider:"kibana",model:P.kibanaAgent?.agentId||"kibana-agent"},llmConfigs:new Map};if(P.graphType==="a2a_agent")return console.log(`[WS] \u{1F310} A2A Agent path for graph: ${P.name}`),{app:tn(P),llmConfig:{provider:"a2a",model:P.a2aAgent?.agentUrl||"a2a-agent"},llmConfigs:new Map};console.log("[WS] buildAppFromDefinition params",{mcp:void 0,threadId:M,queryParams:e,userToken:I,userProviders:be,performanceTracker:V,userContext:Se,assistant:oe});const Pe=(P.nodes||[]).some(E=>E.type==="team_pipeline"||E.type==="team_parallel"||E.type==="team_decider"||E.type==="team_router"||E.type==="team_invoker"),Q=Pe&&(P.nodes||[]).some(E=>E.type==="team_decider"),ft=new Map,yt=Pe?async(E,Ye)=>{const je=`${M}-ta-${Ye}`,ue=await Xe(je,e,void 0,Se,E,void 0,void 0,we,$e,ze,Je,k,Q,he,A,We);for(const[gt,St]of ue.llmConfigs||new Map)ft.set(gt,St);return sn(ue.app)?on(ue.app,je,E.name):ue.app}:void 0,ut=await Yt(P,{mcp:void 0,memory:p,threadId:M,queryParams:e,userToken:I,userProviders:be,performanceTracker:V,userContext:Se,teamSharedContext:We,assistant:{...oe,overrideAllowedTools:oe?.allowedTools},compareChatId:r,enrichChatId:xe,username:we,selectedNamespaces:$e,teamId:ze,chatId:Je,memoryScoped:he,rawUserInput:k,behindDecider:me,channel:A,...Pe?{teamAssistants:oe?.teamAssistants||[],buildAssistantApp:yt}:{}}),qe=Pe?(P.nodes||[]).filter(E=>E.type==="team_decider"||E.type==="team_pipeline"||E.type==="team_parallel"||E.type==="team_router"||E.type==="team_invoker").map(E=>E.id):[],Ke=[...Pe?(P.nodes||[]).filter(E=>E.type==="team_decider").map(E=>E.id):[],...await An(P.nodes,$t,oe?.teamAssistants)],pt=Pe&&(P.nodes||[]).some(E=>E.type==="team_decider");return{app:ut,llmConfig:J?{provider:J.provider,model:J.model}:null,llmConfigs:J?.llmConfigs||new Map,toolNames:ut.toolNames,teamNodeIds:qe,teamStreamableNodeIds:Ke,hasTeamDecider:pt,teamSubLLMConfigs:ft}}catch(P){throw console.error(`[WS] \u274C Failed to load graph ${ke}:`,P.message),new Error(`Failed to load graph ${ke}: ${P.message}`)}}throw console.error("[WS] \u274C No graphId provided - buildApp() is deprecated"),new Error("No graphId provided. buildApp() is deprecated, please provide a graphId to use buildAppFromDefinition().")};console.log("[WS] Setting up message listener..."),console.log("[WS] WebSocket ready state:",i.readyState),console.log("[WS] WebSocket listeners:",i.listenerCount("message"),"message handlers");const ht=async M=>{console.log("[WS] \u2705\u2705\u2705 MESSAGE EVENT TRIGGERED \u2705\u2705\u2705"),console.log("[WS] Message received, length:",M.toString().length);let e;try{e=JSON.parse(M.toString()),console.log("[WS] Message parsed successfully, type:",e.type)}catch(s){console.error("[WS] \u274C JSON parse error:",s.message),l(i,{type:"error",error:"Message JSON invalide"});return}if(e.type==="interrupt"){const s=e.runId;if(console.log(`[WS] Interrupt request for run: ${s}`),!s){console.error("[WS] Interrupt request missing runId"),l(i,{type:"error",error:"Interrupt request requires a runId"});return}const o=se.get(s);if(o){console.log(`[WS] Aborting run: ${s}`),o.abortController.abort();try{await st(s,"error",{metadata:{error:"Run interrupted by user",interrupted:!0},errorType:"abort",errorMessage:"Run interrupted by user"}),console.log(`[WS] \u2705 Completed chat run record (interrupted): ${s}`)}catch(b){console.error("[WS] \u26A0\uFE0F Failed to complete chat run record:",b)}se.delete(s),Qe(s),l(i,{type:"interrupted",runId:s}),console.log(`[WS] Run ${s} interrupted successfully`)}else console.log(`[WS] Run ${s} not found in active runs (may have already completed)`),l(i,{type:"interrupted",runId:s});return}if(e.type==="hitl_resume"){const s=e.threadId;if(console.log(`[HITL] Resume request for thread: ${s}`),!s){l(i,{type:"error",error:"hitl_resume requires threadId"});return}const o=ct.get(s);if(!o){console.warn(`[HITL] No pending interrupt for thread: ${s}`),l(i,{type:"error",error:`No pending HITL interrupt for thread ${s}`});return}const b=o.timestamp;ct.delete(s),console.log(`[HITL] \u25B6\uFE0F Resuming graph for thread: ${s}, decision:`,e.hitlDecision);const{Command:W}=await import("@langchain/langgraph"),L=new W({resume:e.hitlDecision??{approved:!1}}),j=e.hitlDecision??{approved:!1},N=j?.approved===!1?"rejected":"approved",C=Date.now()-b;let B=null;try{const w=await o.compiledApp.streamEvents(L,{version:"v2",configurable:{thread_id:o.threadId,run_id:o.runId,checkpoint_ns:o.checkpointNs},recursionLimit:100,maxConcurrency:1});l(o.ws,{type:"hitl_resumed",threadId:s,runId:o.runId,decision:N,values:j?.values,durationMs:C});const ae=new Ft(o.ws,o.sessionToken,o.runId),H=new jt(o.ws,o.sessionToken,o.runId,o.llmProvider);let g=0,u=null;H.on("data",h=>{switch(h.type){case"dashboard":case"partial_dashboard":{u=h.data;const te=h.data?.result?.content??[];for(let Z=g;Z<te.length;Z++)ae.addBlock(te[Z]);g=te.length;break}case"block":ae.addBlock(h.data),g++;break}});let le=!1;const Fe=h=>!h||h==="LangGraph"||h==="__start__"||h==="__end__"||h==="_write"?!0:h.startsWith("ChannelWrite")||h.startsWith("RunnableLambda")||h.startsWith("RunnableSequence")||h.startsWith("RunnableAssign")||h.startsWith("RunnablePassthrough")||h.startsWith("RunnableParallel")||h.startsWith("RunnableWithMessageHistory");for await(const h of w){if(B={event:h?.event,name:h?.name,nodeId:h?.metadata?.langgraph_node},se.get(o.runId)?.abortController.signal.aborted){console.log(`[HITL] Run ${o.runId} aborted during resume`);break}const te=h.event==="on_chain_stream"&&h.name==="LangGraph"&&(h.data?.chunk?.__interrupt__||h.data?.__interrupt__)||h.event==="on_chain_end"&&h.name==="LangGraph"&&h.data?.output?.__interrupt__;if(te&&Array.isArray(te)&&te.length>0){const ge=te[0]?.value??te[0];console.log(`[HITL] Nested interrupt detected for thread: ${o.threadId}`),ct.set(o.threadId,{compiledApp:o.compiledApp,threadId:o.threadId,runId:o.runId,checkpointNs:o.checkpointNs,ws:o.ws,timestamp:Date.now(),sessionToken:o.sessionToken,llmProvider:o.llmProvider}),l(o.ws,{type:"hitl_interrupt",runId:o.runId,threadId:o.threadId,node:h.name,interruptValue:ge}),le=!0;break}const Z=h.data;if(h.event==="on_chain_start"&&h.name&&!Fe(h.name)&&l(o.ws,{type:"node_start",runId:o.runId,node:h.name,ts:Date.now()}),h.event==="on_chain_end"&&h.name&&!Fe(h.name)){let ge;try{const pe=Z?.output;if(pe!=null){const tt=new Set(["messages","last_tool_error","lastSummaryAt","lastToolNamesSummary","topic","userContext","codeExecConsoleLogs","codeExecStats","codeExecScript","codeExecTrace","toolsUsedAccum","toolExecRounds"]),Ue={};for(const[Ae,Ot]of Object.entries(pe))tt.has(Ae)||(Ue[Ae]=Ot);Object.keys(Ue).length>0&&(ge=JSON.stringify(Ue,null,2))}}catch{ge=void 0}l(o.ws,{type:"node_end",runId:o.runId,node:h.name,ts:Date.now(),nodeOutput:ge,consoleLogs:Z?.output?.codeExecConsoleLogs,sandboxStats:Z?.output?.codeExecStats,script:Z?.output?.codeExecScript,codeExecTrace:Z?.output?.codeExecTrace,toolsUsedAccum:Z?.output?.toolsUsedAccum,toolExecRounds:Z?.output?.toolExecRounds})}if(h.event==="on_chat_model_stream"){const ge=Z?.chunk?.content?.[0]?.text??(typeof Z?.chunk?.content=="string"?Z.chunk.content:"")??"";ge&&(l(o.ws,{type:"markdown_token",text:ge,runId:o.runId}),H.write(ge))}if(h.event==="on_tool_start"&&l(o.ws,{type:"tool_start",runId:o.runId,text:JSON.stringify({toolName:h.name||"tool",toolInput:h.data?.input||null})}),h.event==="on_tool_end"&&l(o.ws,{type:"tool_end",runId:o.runId,text:JSON.stringify({toolName:h.name||"tool",output:h.data?.output||null})}),h.event==="on_custom_event"&&h.name==="decider_direct_block"){const ge=typeof h.data?.ndjson=="string"?h.data.ndjson:"";ge&&(console.log(`[HITL] \u{1F4E8} team_decider direct error block captured during resume (${h.data?.failedCount??"?"} failed assistant(s))`),H.write(ge+`
|
|
15
|
+
`))}}if(H.end(),await new Promise(h=>{const te=()=>h();H.once("finish",te),setTimeout(te,1500)}),!le&&(u?ae.setDashboard(u):ae.getStatus().hasBlocks||ae.sendFallbackBlock(H.getTotalMarkdownContent()),l(o.ws,{type:"blocks_complete",runId:o.runId}),se.delete(o.runId),Qe(o.runId),console.log(`[HITL] Cleaned up active run after resume: ${o.runId}`),o.compiledApp?.cleanup)){try{o.compiledApp.cleanup()}catch{}console.log(`[HITL] Released MCP clients after resume: ${s}`)}}catch(w){console.error(`[HITL] Error during resume for thread ${s} \u2014 last event before crash:`,B,`
|
|
16
|
+
stack:`,w?.stack||w),l(o.ws,{type:"error",error:`HITL resume failed: ${w.message}`})}return}if(e.type==="compare"){console.log("[WS] Comparison request received:",{currentChatId:e.currentChatId,referenceChatId:e.referenceChatId,runId:e.runId});const s=Tt(I);if(!s||!s.username){console.error("[WS] No user found in token for comparison"),l(i,{type:"error",error:"Authentication required for comparison",runId:e.runId});return}const{summarizeChat:o,buildComparisonPrompt:b}=await import("../core/services/comparison-service");try{const[W,L]=await Promise.all([o(e.referenceChatId,s.username),o(e.currentChatId,s.username)]);console.log("[WS] Summaries created:",{past:W.title,present:L.title,pastTools:W.toolsSummary.length,presentTools:L.toolsSummary.length});const j=b(W,L);console.log("[WS] Comparison prompt built, length:",j.length),e.type="invoke",e.input=j}catch(W){console.error("[WS] Comparison error:",W),l(i,{type:"error",error:`Comparison failed: ${W.message}`,runId:e.runId});return}}if(e.type==="form_submit"){const s=e;if(console.log(`[WS] form_submit received \u2014 tool: ${s.tool}, action: ${s.action}`),s.action==="execute"){try{const o=await Xn(s.tool,s.values,I);l(i,{type:"form_result",runId:s.runId,tool:s.tool,result:o})}catch(o){console.error("[WS] form_submit execute error:",o),l(i,{type:"error",runId:s.runId,error:`Tool execution failed: ${o.message}`})}return}if(s.action==="chat"){const o=JSON.stringify(s.values,null,2),b=[`[Formulaire soumis \u2014 tool: ${s.tool}]`,`Valeurs saisies:
|
|
17
|
+
${o}`].join(`
|
|
18
|
+
`);e.type="invoke",e.input=b,e.runId=s.runId,e.threadId=s.threadId}else{console.warn(`[WS] Unknown form_submit action: ${s.action}`);return}}if(console.log("[WS] Message:",JSON.stringify(e)),e.type!=="invoke")return;console.log("[WS] invoke",JSON.stringify(e));let V=null,Se=new Map;if(e.userContext?console.log("[WS] \u2705 userContext received:",{length:e.userContext.length,preview:e.userContext.substring(0,100)}):console.log("[WS] \u26A0\uFE0F No userContext in message"),e.teamId&&e.teamId!=="unknown"&&Array.isArray(e.assistantIds)&&e.assistantIds.length>0)try{const{getTeamInvocationConfig:s}=await import("../core/services/teams-service"),o=await s(e.teamId);if(o){const b=new Set(o.assistants.filter(w=>w.enabled).map(w=>w.id).filter(w=>!!w)),W=e.assistantIds,L=W.filter(w=>b.has(w)),j=W.filter(w=>!b.has(w));j.length>0&&(console.warn(`[WS] \u26A0\uFE0F Dropping assistantId(s) not in team ${e.teamId} (${o.name??"unknown"}): ${j.join(", ")}`),e.assistantIds=L.length>0?L:Array.from(b),console.log(`[WS] \u{1F527} Re-scoped assistantIds to team membership: ${e.assistantIds.join(", ")}`));const N=e.assistantConditions,C={};for(const w of o.assistants)!w.id||!b.has(w.id)||(w.condition||w.runAlways)&&(C[w.id]={condition:w.condition??null,runAlways:w.runAlways??!1});JSON.stringify(N??{})!==JSON.stringify(C)&&(N&&console.warn(`[WS] \u26A0\uFE0F Ignoring client-submitted assistantConditions for team ${e.teamId} (${o.name??"unknown"}); using team.assistants routing config instead`),e.assistantConditions=Object.keys(C).length>0?C:void 0)}}catch(s){console.warn(`[WS] \u26A0\uFE0F Could not re-scope assistantIds for team ${e.teamId}:`,s?.message)}if(e.assistantIds&&Array.isArray(e.assistantIds)&&e.assistantIds.length>0){console.log(`[WS] \u{1F3AF} Assistants requested: ${e.assistantIds.length} assistant(s)`);try{const{resolveAssistants:s}=await import("../core/services/assistant-resolver"),o=await s(e.assistantIds,G());if(o.length===0){console.error("[WS] \u274C No valid assistants found"),l(i,{type:"error",error:"No valid assistants found for the provided IDs",runId:e.runId});return}console.log(`[WS] \u2705 Resolved ${o.length} assistant(s)`);const W=e.assistantIds.map(C=>o.find(B=>B.assistantId===C)).filter(Boolean),L=e.assistantOverrides,j=e.assistantConditions,N=W.map(C=>{const B=L?.[C.assistantId],w=j?.[C.assistantId];return{...C,...B?.nodes?{nodeOverrides:B.nodes}:{},...B?.allowedTools?{allowedTools:B.allowedTools}:{},condition:w?.condition??null,runAlways:w?.runAlways??!1}});if(e.resolvedAssistants=N,e.teamId)try{const{getTeamSharedContext:C,getTeamById:B}=await import("../core/services/teams-service"),[w,ae]=await Promise.all([C(e.teamId),B(e.teamId).catch(()=>null)]);w&&(e.teamSharedContext={context:w.context,policy:w.policy},console.log(`[WS] \u{1F3F7}\uFE0F Team sharedContext available (${w.context.length} chars) \u2014 policy resolved per-consumer`),l(i,{type:"context_inject",runId:e.runId||"",ts:Date.now(),content:w.context,label:"Team Context"})),ae?.graphId&&(e.teamGraphId=ae.graphId,e.teamAssistants=N,console.log(`[WS] \u{1F3D7}\uFE0F Team has coordination graph: ${ae.graphId}`))}catch(C){console.warn(`[WS] \u26A0\uFE0F Could not load team data for teamId=${e.teamId}:`,C?.message)}if(N.length===1){const C=N[0],B=C.nodeOverrides?Object.keys(C.nodeOverrides).length:0,w=C.allowedTools?C.allowedTools.length:"all";console.log(`[WS] \u{1F3AF} Using single assistant: ${C.name} (graph: ${C.graphId}, nodeOverrides: ${B}, tools: ${w})`)}else console.log(`[WS] \u{1F3AF} Multi-assistant orchestration: ${N.length} assistants will be executed in order`),N.forEach((C,B)=>{const w=C.nodeOverrides?Object.keys(C.nodeOverrides).length:0;console.log(` ${B+1}. ${C.name} (graph: ${C.graphId}, priority order: ${B+1}, nodeOverrides: ${w})`)})}catch(s){console.error("[WS] \u274C Assistant resolution failed:",s),l(i,{type:"error",error:`Failed to resolve assistants: ${s.message}`,runId:e.runId});return}}else if(e.teamId)try{const{getTeamSharedContext:s,getTeamById:o}=await import("../core/services/teams-service"),[b,W]=await Promise.all([s(e.teamId),o(e.teamId).catch(()=>null)]);b&&(e.teamSharedContext={context:b.context,policy:b.policy},l(i,{type:"context_inject",runId:e.runId||"",ts:Date.now(),content:b.context,label:"Team Context"})),W?.graphId&&(e.teamGraphId=W.graphId,e.teamAssistants=[],console.log(`[WS] \u{1F3D7}\uFE0F Team has coordination graph (no member assistants): ${W.graphId}`))}catch(s){console.warn(`[WS] \u26A0\uFE0F Could not load team data for teamId=${e.teamId}:`,s?.message)}const oe=typeof e.channel=="string"&&e.channel?e.channel:"web",r=e.runId??Gt(),xe=e.threadId??crypto.randomUUID(),we=e.checkpointNs??"ui-v1",$e=new AbortController;Vt.setMaxListeners(20,$e.signal),se.set(r,{runId:r,abortController:$e,ws:i,startTime:Date.now()}),On({runId:r,startTime:Date.now(),username:G()||void 0,chatId:e.chatId||r,teamId:e.teamId,teamName:e.teamName}),console.log(`[WS] Registered active run: ${r} (total active: ${se.size})`);const ze=[];Gn(r,s=>ze.push(s));const Je=G();if(Je)try{await En(r,r,Je,{source:e.source==="playground"?"playground":"chat",userMessage:typeof e.input=="string"?e.input:void 0,topic:e.queryParams?.topic,cluster:e.queryParams?.cluster,namespace:we,llmProvider:e.queryParams?.llmProvider,llmModel:e.queryParams?.llmModel,teamId:e.teamId||"unknown",teamName:e.teamName||"unknown",graphId:e.graphId,assistantId:"pending",assistantName:"pending",...t||Ce?{sharedRun:!0,guestId:de,shareTokenId:t??Ce?.shareLinkId}:{}}),console.log(`[WS] \u2705 Created chat run record: ${r}`)}catch(s){console.error("[WS] \u26A0\uFE0F Failed to create chat run record:",s)}const k=new pn(r);k.start("total_execution"),k.start("message_received"),k.end("message_received"),k.start("cache_check");const me=lt.generateKey({query:e.input,topic:e.queryParams?.topic,namespace:we}),he=lt.get(me);if(k.end("cache_check"),he&&process.env.CACHE_ENABLED!=="false"){console.log("[Dashboard Cache] HIT - Returning cached dashboard"),k.instant("cache_hit",{key:me,type:"dashboard"});const s=fn(he.blocks||[]);if(!s.success||!s.data)console.warn("[Dashboard Cache] Invalid cached data, invalidating cache entry"),lt.delete(me);else{s.fallbackApplied&&console.warn("[Dashboard Cache] Some cached blocks were sanitized"),await l(i,{type:"ui",runId:r,sessionId:I,phase:"final",content:s.data}),await Mt(i),await l(i,{type:"blocks_complete",runId:r,timestamp:Date.now()}),console.log("[WS] \u{1F4E6} Sent blocks_complete message (CACHE HIT)"),console.log(`[WS] \u{1F3C1} Sending DONE message for run ${r} (CACHE HIT)`,{ok:!0,cached:!0,stackTrace:new Error().stack?.split(`
|
|
19
|
+
`).slice(1,4).join(`
|
|
20
|
+
`)}),await l(i,{type:"done",runId:r,ok:!0,stats:{blocksGenerated:s.data.length,responseLength:JSON.stringify(he).length,totalDuration:k.getTotalDuration(),cached:!0,cacheHit:!0}});try{await st(r,"success",{duration:k.getTotalDuration(),toolsUsed:[],toolCallsCount:0,metadata:{cached:!0}}),console.log(`[WS] \u2705 Completed chat run record (cache hit): ${r}`)}catch(W){console.error("[WS] \u26A0\uFE0F Failed to complete chat run record:",W)}se.delete(r),Qe(r),console.log(`[WS] Removed active run: ${r} (remaining: ${se.size})`),k.end("total_execution"),k.printSummary();const o=lt.getStats(),b=Dt.getStats();console.log("[Cache] Stats:",{dashboard:{hitRate:`${o.hitRate}%`,size:`${o.size}/${o.maxSize}`,bytes:`${Math.round(o.totalBytes/1024)}KB`},data:{hitRate:`${b.hitRate}%`,size:`${b.size}/${b.maxSize}`,bytes:`${Math.round(b.totalBytes/1024)}KB`}});return}}console.log("[Dashboard Cache] MISS - Generating new response"),k.instant("cache_miss",{key:me,type:"dashboard"}),k.start("app_build");let A=[];const We=e.resolvedAssistants||[],be=e.teamGraphId,ke=e.teamAssistants;if(be&&ke){console.log(`[WS] \u{1F3D7}\uFE0F Team coordination graph detected: ${be} (${ke.length} assistants)`);try{const s=await $t(be);if(!s||s.enabled===!1)throw new Error(`Team graph '${be}' not found or disabled`);const o=await Xe(xe,e.queryParams,k,e.userContext,{graphId:be,name:"team",assistantId:`team-${e.teamId}`,mcp_servers_policy:{mode:"none",servers:[]},teamAssistants:ke},e.compareChatId,e.enrichChatId,G(),e.selectedNamespaces,e.teamId,e.chatId||r,typeof e.input=="string"?e.input:void 0,void 0,e.memoryScoped===!0,oe,e.teamSharedContext);A=[{app:o.app,assistant:{graphId:be,name:"team",assistantId:`team-${e.teamId}`},threadId:xe,llmConfig:o.llmConfig,llmConfigs:o.llmConfigs,toolNames:o.toolNames,teamNodeIds:o.teamNodeIds||[],teamStreamableNodeIds:o.teamStreamableNodeIds||[],hasTeamDecider:o.hasTeamDecider||!1,teamSubLLMConfigs:o.teamSubLLMConfigs||new Map}],console.log("[WS] \u2705 Team coordination graph compiled"),o.llmConfig&&(V=o.llmConfig,Se=o.llmConfigs||new Map,await l(i,{type:"model_info",runId:e.runId,provider:o.llmConfig.provider,model:o.llmConfig.model}))}catch(s){console.error(`[WS] \u274C Failed to build team graph: ${s.message} \u2014 falling back to standard multi-assistant flow`)}}if(We.length>0&&A.length===0){console.log(`[WS] \u{1F504} Building ${We.length} app(s) for assistants...`);try{const s=We.map(async(o,b)=>{const W=`${xe}-assistant-${b}`;console.log(`[WS] \u{1F528} Building app ${b+1}/${We.length} for assistant: ${o.name}`);const L=await Xe(W,e.queryParams,k,e.userContext,o,e.compareChatId,e.enrichChatId,G(),e.selectedNamespaces,e.teamId,e.chatId||r,typeof e.input=="string"?e.input:void 0,void 0,e.memoryScoped===!0,oe,e.teamSharedContext);return{app:L.app,assistant:o,threadId:W,llmConfig:L.llmConfig,llmConfigs:L.llmConfigs,toolNames:L.toolNames,teamNodeIds:L.teamNodeIds||[],teamStreamableNodeIds:L.teamStreamableNodeIds||[],hasTeamDecider:L.hasTeamDecider||!1,teamSubLLMConfigs:L.teamSubLLMConfigs||new Map}});A=await Promise.all(s),console.log(`[WS] \u2705 Successfully built ${A.length} app(s)`),A.length>0&&A[0].llmConfig&&(V=A[0].llmConfig,Se=A[0].llmConfigs||new Map,await l(i,{type:"model_info",runId:e.runId,provider:A[0].llmConfig.provider,model:A[0].llmConfig.model}),console.log(`[WS] \u{1F4E4} Sent model info to frontend: ${A[0].llmConfig.provider}:${A[0].llmConfig.model}`))}catch(s){console.error("[WS] \u274C Failed to build apps for assistants:",s),l(i,{type:"error",error:`Erreur lors de la construction des applications: ${s.message}`});try{const o=At(s);await st(r,"error",{metadata:{error:s.message,phase:"app_build_assistants"},errorType:o.errorType,errorMessage:o.errorMessage,errorNodeId:"app_build_assistants"}),console.log(`[WS] \u2705 Completed chat run record with error: ${r}`)}catch(o){console.error("[WS] \u26A0\uFE0F Failed to complete chat run record:",o)}se.delete(r),Qe(r),console.log(`[WS] Removed active run (error): ${r} (remaining: ${se.size})`),k.end("app_build"),k.end("total_execution"),k.printSummary();return}}else if(A.length===0){console.log("[WS] \u26A0\uFE0F No assistants resolved, using legacy single-app flow");try{const s=e.graphId?{graphId:e.graphId,name:"legacy",assistantId:"legacy"}:void 0,o=await Xe(xe,e.queryParams,k,e.userContext,s,void 0,void 0,void 0,e.selectedNamespaces,e.teamId,e.chatId||r,typeof e.input=="string"?e.input:void 0,void 0,e.memoryScoped===!0,oe,e.teamSharedContext);A=[{app:o.app,assistant:s,threadId:xe,llmConfig:o.llmConfig,llmConfigs:o.llmConfigs,toolNames:o.toolNames}],o.llmConfig&&(V=o.llmConfig,Se=o.llmConfigs||new Map,await l(i,{type:"model_info",runId:e.runId,provider:o.llmConfig.provider,model:o.llmConfig.model}),console.log(`[WS] \u{1F4E4} Sent model info to frontend: ${o.llmConfig.provider}:${o.llmConfig.model}`))}catch(s){console.error("[WS] Failed to build legacy app:",s),l(i,{type:"error",error:"Erreur lors de la reconstruction de l'application"});try{const o=At(s);await st(r,"error",{metadata:{error:s.message,phase:"app_build_legacy"},errorType:o.errorType,errorMessage:o.errorMessage,errorNodeId:"app_build_legacy"}),console.log(`[WS] \u2705 Completed chat run record with error: ${r}`)}catch(o){console.error("[WS] \u26A0\uFE0F Failed to complete chat run record:",o)}se.delete(r),Qe(r),console.log(`[WS] Removed active run (error): ${r} (remaining: ${se.size})`),k.end("app_build"),k.end("total_execution"),k.printSummary();return}}k.end("app_build"),l(i,{type:"accepted",runId:r});const P=A.length>0?A[0].assistant?.assistantId:void 0,J=new Ft(i,I,r,P),Pe=[],Q=[],ft="Error: Tool execution interrupted by generation start";function yt(s,o){if(o){const b=Q.find(W=>W.toolCallId===o);if(b)return b}return Q.find(b=>b.name===s&&(b.output===null||b.output===ft))}const ut=await Jt.loadAllToolsMetadata();console.log(`[WS] Loaded ${ut.size} tool descriptions for session`);let qe=0,Ke=0,pt=0,E;const Ye=new zt({encoding:"utf8",highWaterMark:Lt}),je=V?.provider,ue=new jt(i,I,r,je);ue.resume(),[Ye,ue].forEach(s=>{s.on("error",o=>{console.error("[WS] Pipeline error:",o),l(i,{type:"parser_error",runId:r,error:`Pipeline: ${o.message}`})})});let gt=!1;ue.on("data",s=>{switch(console.log("[WS] Parsed____:",JSON.stringify(s.type)),gt=!0,s.type){case"dashboard":console.log("[WS] Dashboard received, parsing raw content for additional blocks");const b=St(Ie,s.data);console.log(`[WS] Parsed ${b.length} total blocks from raw content`);const W={...s.data,result:{...s.data.result,content:b}};J.setDashboard(W);break;case"block":J.addBlock(s.data),console.log("[WS] Added block:",s.data.type,s.data.title);break;case"partial_dashboard":console.log("[WS] Partial dashboard received, parsing raw content for additional blocks");const j=St(Ie,s.data);console.log(`[WS] Parsed ${j.length} total blocks from raw content`);const N={...s.data,result:{...s.data.result,content:j}};J.setDashboard(N);break;default:console.log("[WS] Unknown JSON type:",s.type)}});const St=(s,o)=>{if(!s||!s.trim())return o?.result?.content||[];const b=j=>{const N=[];let C="",B=0,w=!1,ae=!1;for(let H=0;H<j.length;H++){const g=j[H];if(ae){C+=g,ae=!1;continue}if(g==="\\"){ae=!0,C+=g;continue}if(g==='"'&&!ae){w=!w,C+=g;continue}w?C+=g:g==="{"?(B===0&&(C=""),B++,C+=g):g==="}"?(B--,C+=g,B===0&&C.trim()&&(N.push(C.trim()),C="")):B>0&&(C+=g)}return N};console.log(`[parseDashboardBlocks] Extracting blocks from ${s.length} chars`);const W=b(s);console.log(`[parseDashboardBlocks] Found ${W.length} JSON objects`);const L=[];for(let j=0;j<W.length;j++)try{const N=JSON.parse(W[j]);N.type&&N.title?(console.log(`[parseDashboardBlocks] \u2705 Block ${j}: ${N.type} - ${N.title}`),L.push(N)):console.log(`[parseDashboardBlocks] \u26A0\uFE0F Block ${j}: Missing type or title`)}catch{console.error(`[parseDashboardBlocks] \u274C Block ${j}: Parse error`)}return L.length===0?(console.log("[parseDashboardBlocks] No valid blocks found, returning original content"),o?.result?.content||[]):L};let Ee="",Ie="",ot="",mt="",_e="",xt=!1,Ze=0,Et=0;const It=new Map;let at=null;const _t={},vt=new mn,et=new gn(i,({text:s})=>{l(i,{type:"markdown_token",runId:r,text:s}),vt.recordToken(s)},hn);let kt=!1;try{k.start("langgraph_stream_init");let o={messages:[new Ct({content:[{type:"text",text:e.input}]})]};const b=e.teamId,W=e.chatId,L=e.memoryScoped===!0,j=G();if(b&&j&&!e.test&&typeof e.input=="string")try{const g=!W,u=L,[le,Fe]=await Promise.all([!u&&g?Ln(j,b):Promise.resolve(null),jn(j,e.input,{k:5,includeChatTraces:!0,excludeMemoryIds:W?[Fn(W)].filter(te=>!!te):void 0,...L&&W?{sourceChatId:W}:{teamId:b}})]),h=[];if(le&&h.push(le),Fe&&h.push(Fe),h.length>0){const te=h.join(`
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
`),Z=Pt(`${te}
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
${e.input}`);o={messages:[new Ct({content:[{type:"text",text:Z}]})]},console.log(`[WS] \u{1F9E0} Injected memory context for team ${b} (L2: ${le?le.length:0} chars, LTM: ${Fe?Fe.length:0} chars)`)}}catch(g){console.warn("[WS] Memory context injection failed (non-fatal):",g.message)}if(e.test){console.log("[WS] Test mode enabled, loading test response");const g=cn(e.input);if(!g){console.warn("[WS] No test response found for input:",e.input),l(i,{type:"error",runId:r,error:"Aucune r\xE9ponse test trouv\xE9e pour cette entr\xE9e"});return}console.log("[WS] Using test response:",g.id);for await(const u of dn(g,10))ue.write(u);if(ue.end(),await new Promise(u=>ue.once("finish",u)),l(i,{type:"end",runId:r}),console.log("[WS] Test mode completed"),A.length>0&&A[0].app&&A[0].app.cleanup)try{A[0].app.cleanup()}catch(u){console.error("[WS] Error cleaning up MCP clients:",u)}return}if(k.end("langgraph_stream_init"),k.start("langgraph_stream"),A.length===0){console.error("[WS] \u274C No apps to execute"),l(i,{type:"error",runId:r,error:"No apps available for execution"});return}console.log(`
|
|
29
|
+
${"\u{1F3AF} ".repeat(40)}`),console.log("\u{1F3AF} MULTI-ASSISTANT ORCHESTRATION"),console.log(`${"\u{1F3AF} ".repeat(40)}`),console.log(`\u{1F4CA} Total Assistants: ${A.length}`),A.forEach((g,u)=>{console.log(` ${u+1}. ${g.assistant?.name} (${g.assistant?.assistantId})`)}),console.log("\u{1F504} Execution Mode: Sequential"),console.log(`${"\u{1F3AF} ".repeat(40)}
|
|
30
|
+
`);const N=[],C=[];let B=e.queryParams?.topic||void 0;const w=[];let ae;const H=A.length;for(let g=0;g<H;g++){const u=A[g],le=u.assistant;if(!le?.runAlways&&le?.condition&&(console.log("\u{1F4CA} Assistant CONDITION __ :",le.condition,e.input,B,ae),!await Nn(le.condition,{topic:B,userMessage:typeof e.input=="string"?e.input:"",lastResult:ae}))){console.log(`[WS] \u23ED\uFE0F Skipping assistant "${le.name}" \u2014 condition not met: "${le.condition}" (topic: "${B}")`),await l(i,{type:"assistant_skipped",runId:r,assistantId:le.assistantId,assistantName:le.name,assistantIndex:g,totalAssistants:H,condition:le.condition,topic:B});continue}Ze=0,_e="";let Fe=[],h=[];const te=Q.length;let Z,ge;try{const pe=new Map;if(console.log(`
|
|
31
|
+
${"\u{1F916} ".repeat(40)}`),console.log(`\u{1F916} EXECUTING ASSISTANT ${g+1}/${H}`),console.log(`${"\u{1F916} ".repeat(40)}`),console.log(`\u{1F4CA} Assistant: ${u.assistant?.name||"unknown"}`),console.log(`\u{1F4CA} AssistantId: ${u.assistant?.assistantId||"unknown"}`),console.log(`\u{1F4CA} GraphId: ${u.assistant?.graphId}`),console.log(`\u{1F4CA} ThreadId: ${u.threadId}`),console.log(`${"\u{1F916} ".repeat(40)}
|
|
32
|
+
`),await l(i,{type:"assistant_start",runId:r,assistantId:u.assistant?.assistantId,assistantName:u.assistant?.name,assistantIndex:g,totalAssistants:H,tools:u.toolNames??[]}),u.app.isKibanaAgent){const n=u.app,Re=Date.now();try{console.log(`[WS] \u{1F916} Executing Kibana Agent: ${n.agentId} on platform ${n.platformId}`);const X=[...o.messages].reverse().find(fe=>fe._getType?.()==="human"||fe.constructor?.name==="HumanMessage"),Oe=X?typeof X.content=="string"?X.content:JSON.stringify(X.content):typeof e.input=="string"?e.input:"",Te=c.get(u.threadId),{text:Ne,toolsUsed:Ge,conversationId:z}=await en(n,Oe,{conversationId:Te,abortSignal:$e.signal,onToken:fe=>et.addToken(fe),onToolStart:(fe,rt)=>l(i,{type:"tool_start",runId:r,text:JSON.stringify({toolName:fe,toolInput:rt})}),onToolEnd:fe=>l(i,{type:"tool_end",runId:r,text:JSON.stringify({toolName:fe})})});z&&c.set(u.threadId,z),console.log(`[WS][KibanaAgent] SSE loop done. accumulatedText length: ${Ne.length}, kibanaToolsUsed: ${Ge.length}`),et.finalize(),Ne.trim()&&J.sendFallbackBlock(Ne);const He=Date.now()-Re;N.push({assistantName:u.assistant?.name||"unknown",assistantId:u.assistant?.assistantId||"unknown",toolsUsed:Ge.map(fe=>({name:fe,description:void 0,input:null,output:null,timestamp:new Date().toISOString(),error:!1,empty:!1})),blocksGenerated:J.getBlocks().length,success:!0,duration:He,llmCallsCount:1}),await l(i,{type:"assistant_end",runId:r,assistantId:u.assistant?.assistantId,assistantName:u.assistant?.name,assistantIndex:g,totalAssistants:H,success:!0,duration:He})}catch(X){$e.signal.aborted?console.log("[WS] Kibana agent run aborted"):(console.error("[WS] \u274C Kibana agent error:",X.message),N.push({assistantName:u.assistant?.name||"unknown",assistantId:u.assistant?.assistantId||"unknown",toolsUsed:[],blocksGenerated:0,success:!1,duration:Date.now()-Re,llmCallsCount:0}),await l(i,{type:"assistant_end",runId:r,assistantId:u.assistant?.assistantId,assistantName:u.assistant?.name,assistantIndex:g,totalAssistants:H,success:!1,error:X.message}))}finally{n.cleanup()}continue}if(u.app.isA2aAgent){const n=u.app,Re=Date.now();try{console.log(`[WS] \u{1F310} Executing A2A Agent: ${n.agentUrl}`);const X=[...o.messages].reverse().find(z=>z._getType?.()==="human"||z.constructor?.name==="HumanMessage"),Oe=X?typeof X.content=="string"?X.content:JSON.stringify(X.content):typeof e.input=="string"?e.input:"",{text:Te,toolsUsed:Ne}=await nn(n,Oe,{abortSignal:$e.signal,onToken:z=>et.addToken(z),onToolStart:z=>l(i,{type:"tool_start",runId:r,text:JSON.stringify({toolName:z,toolInput:null})}),onToolEnd:z=>l(i,{type:"tool_end",runId:r,text:JSON.stringify({toolName:z})})});et.finalize(),Te.trim()&&J.sendFallbackBlock(Te);const Ge=Date.now()-Re;N.push({assistantName:u.assistant?.name||"unknown",assistantId:u.assistant?.assistantId||"unknown",toolsUsed:Ne.map(z=>({name:z,description:void 0,input:null,output:null,timestamp:new Date().toISOString(),error:!1,empty:!1})),blocksGenerated:J.getBlocks().length,success:!0,duration:Ge,llmCallsCount:1}),await l(i,{type:"assistant_end",runId:r,assistantId:u.assistant?.assistantId,assistantName:u.assistant?.name,assistantIndex:g,totalAssistants:H,success:!0,duration:Ge})}catch(X){$e.signal.aborted?console.log("[WS] A2A agent run aborted"):(console.error("[WS] \u274C A2A agent error:",X.message),N.push({assistantName:u.assistant?.name||"unknown",assistantId:u.assistant?.assistantId||"unknown",toolsUsed:[],blocksGenerated:0,success:!1,duration:Date.now()-Re,llmCallsCount:0}),await l(i,{type:"assistant_end",runId:r,assistantId:u.assistant?.assistantId,assistantName:u.assistant?.name,assistantIndex:g,totalAssistants:H,success:!1,error:X.message}))}finally{n.cleanup()}continue}ot="",Z=void 0,ge=void 0;const tt=await u.app.streamEvents(o,{version:"v2",configurable:{thread_id:u.threadId,run_id:r,checkpoint_ns:we},recursionLimit:100,maxConcurrency:1,signal:$e.signal});k.start("stream_processing"),console.log(`[WS] \u{1F680} Starting to iterate over stream events for runId: ${r}`);let Ue=!1;const Ae=n=>(It.get(n?.metadata?.thread_id||"")||at)?.assistantId||u.assistant?.assistantId;for await(const n of tt){console.log(`[WS] \u{1F525} RECEIVED EVENT - Type: ${n.event}, Name: ${n.name}`);const Re=u.teamNodeIds||[],X=u.teamStreamableNodeIds||[],Oe=!!u.hasTeamDecider;if(n.event==="on_chat_model_end"&&console.log("[WS] \u{1F50D} on_chat_model_end full event:",JSON.stringify({event:n.event,name:n.name,run_id:n.run_id,tags:n.tags,metadata:n.metadata,data:n.data?"present":"missing"},null,2)),n.event&&(n.event.includes("tool")||n.event.includes("chain")||n.name?.toLowerCase().includes("tool"))&&(console.log("[WS] \u{1F50D} DETAILED EVENT DUMP:"),console.log(JSON.stringify({event:n.event,name:n.name,run_id:n.run_id,tags:n.tags,metadata:n.metadata,data_keys:n.data?Object.keys(n.data):[],data_input:n.data?.input,data_output:n.data?.output?"[exists]":void 0},null,2))),$e.signal.aborted){console.log(`[WS] Run ${r} aborted, stopping stream processing`);break}(n.event==="on_chain_stream"||n.event==="on_chain_end")&&n.name==="LangGraph"&&console.log("[HITL] \u{1F50D} LangGraph event data structure:",JSON.stringify({event:n.event,dataKeys:n.data?Object.keys(n.data):[],chunkKeys:n.data?.chunk?typeof n.data.chunk=="object"?Object.keys(n.data.chunk):typeof n.data.chunk:"no chunk",outputKeys:n.data?.output?typeof n.data.output=="object"?Object.keys(n.data.output):typeof n.data.output:"no output",hasInterruptInChunk:!!n.data?.chunk?.__interrupt__,hasInterruptInOutput:!!n.data?.output?.__interrupt__,hasInterruptInData:!!n.data?.__interrupt__,chunkRaw:JSON.stringify(n.data?.chunk)?.slice(0,300)}));const Te=n.event==="on_chain_stream"&&n.name==="LangGraph"&&(n.data?.chunk?.__interrupt__||n.data?.__interrupt__)||n.event==="on_chain_end"&&n.name==="LangGraph"&&n.data?.output?.__interrupt__;if(Te&&Array.isArray(Te)&&Te.length>0){const a=Te[0]?.value??Te[0];console.log(`[HITL] \u{1F6D1} Graph interrupted for thread: ${u.threadId}`),ct.set(u.threadId,{compiledApp:u.app,threadId:u.threadId,runId:r,checkpointNs:we,ws:i,timestamp:Date.now(),sessionToken:I,llmProvider:V?.provider}),l(i,{type:"hitl_interrupt",runId:r,threadId:u.threadId,node:Z,interruptValue:a}),kt=!0;break}const Ne=n.data?.chunk??n.data?.output,Ge=Ne?.content?.[0]?.text??Ne?.content??Ne?.delta??Ne?.token??"";console.log("[WS] Event:",JSON.stringify(n.metadata.langgraph_checkpoint_ns),"| event:",n.event,"| name:",n.name,"| piece:",Ge);const z=a=>!a||a==="LangGraph"||a==="__start__"||a==="__end__"||a==="_write"?!0:a.startsWith("ChannelWrite")||a.startsWith("RunnableLambda")||a.startsWith("RunnableSequence")||a.startsWith("RunnableAssign")||a.startsWith("RunnablePassthrough")||a.startsWith("RunnableParallel")||a.startsWith("RunnableWithMessageHistory");if(n.event==="on_chain_start"&&n.name&&!z(n.name)&&(Z=n.name,k.start(`node_${n.name}`),l(i,{type:"node_start",runId:r,node:n.name,ts:Date.now(),assistantId:Ae(n)})),n.event==="on_chain_end"&&n.name&&!z(n.name)){ge=n.name,Z=void 0,k.end(`node_${n.name}`);try{const S=n.data?.output,O=Array.isArray(S?.messages)?S.messages:[],y=O[O.length-1];if(y?.additional_kwargs?.__raw_output__){const R=y?.content,d=typeof R=="string"?R:Array.isArray(R)?R.map(F=>typeof F=="string"?F:F?.text??"").join(""):"";d&&d.trim()&&(mt=d,console.log(`[WS] \u2705 Captured raw_output content from node "${n.name}" (${d.length} chars) for final fallback`))}}catch(S){console.warn(`[WS] \u26A0\uFE0F Failed to capture raw_output content: ${S?.message}`)}if(n.name==="topic_detection"){const S=n.data?.output;S?.topic&&(B=S.topic,console.log(`[WS] \u2705 Captured runtimeTopic: "${B}"`))}if(n.name==="system"){console.log("[WS] System node ended, checking for systemPrompt...");const S=n.data?.output;S?(console.log("[WS] System node output keys:",Object.keys(S)),S.systemPromptFinal?(E=S.systemPromptFinal,Dn(r,E),console.log("[WS] \u2705 Captured system prompt from node system (length:",E.length,"chars)"),console.log("[WS] \u2705 Stored system prompt in cache for runId:",r),console.log("[WS] System prompt preview:",E.substring(0,200)+"..."),l(i,{type:"context_inject",runId:r,ts:Date.now(),content:E,label:"System Prompt"})):console.log("[WS] \u26A0\uFE0F System node output has no systemPrompt field")):console.log("[WS] \u26A0\uFE0F System node has no output data")}let a,T,U,v,x,$,q;try{const S=n.data?.output;if(S!=null){const O=new Set(["messages","last_tool_error","lastSummaryAt","lastToolNamesSummary","topic","userContext","codeExecConsoleLogs","codeExecStats","codeExecScript","codeExecTrace","toolsUsedAccum","toolExecRounds"]);T=S.codeExecConsoleLogs,U=S.codeExecStats,v=S.codeExecScript,x=S.codeExecTrace,$=S.toolsUsedAccum,q=S.toolExecRounds;const y={};for(const[d,F]of Object.entries(S))O.has(d)||(y[d]=F);a=JSON.stringify(y,null,2),Object.keys(y).length===0&&(a=void 0)}}catch{a=void 0}l(i,{type:"node_end",runId:r,node:n.name,ts:Date.now(),nodeOutput:a,consoleLogs:T,sandboxStats:U,script:v,codeExecTrace:x,toolsUsedAccum:$,toolExecRounds:q,assistantId:Ae(n)})}if(n.event==="on_chat_model_end"){const a=n.data?.output,T=n.metadata||{},U=y=>Se.get(y)||u.teamSubLLMConfigs?.get(y),v=Jn(n,{resolveAssistant:y=>It.get(y)||at||void 0,defaultAssistant:{assistantId:u.assistant?.assistantId,assistantName:u.assistant?.name},llmCallAssistant:{assistantId:u.assistant?.assistantId,assistantName:u.assistant?.name},nodeProvider:y=>U(y)?.provider||T.ls_provider||V?.provider||void 0,routingRule:y=>{const R=U(y);return{id:R?.routingRuleId,name:R?.routingRuleName}},startTimeMs:pe.get(n.run_id)});if(v){pe.delete(n.run_id);const{tokenUsage:y,llmCall:R}=v;R.callIndex=h.length;try{const d=await Pn(),F=Rn(d,y.model);y.costUsd=Bn(F,{input:y.inputTokens,output:y.outputTokens,cacheRead:y.cacheReadTokens,cacheCreate:y.cacheCreationTokens})}catch(d){console.error("[WS] Failed to compute live token_usage cost:",d)}console.log(`[WS] \u2705 Token usage for node "${y.nodeId}": ${y.provider}:${y.model}`,JSON.stringify(y)),Fe.push(y),w.push(y),h.push(R),l(i,{type:"token_usage",runId:r,assistantId:y.assistantId,usage:y})}a?.tool_calls&&a.tool_calls.length>0?(console.log("[WS] AIMessage tool_calls detected:",a.tool_calls.length),a.tool_calls.length>1&&(qe=a.tool_calls.length,Ke=0,pt=Date.now(),console.log(`[ParallelTools] \u{1F680} ${a.tool_calls.length} tools will execute in PARALLEL`),console.log(`[ParallelTools] Tools: ${a.tool_calls.map(y=>y.name).join(", ")}`),k.start("parallel_tools_execution",{toolCount:a.tool_calls.length,toolNames:a.tool_calls.map(y=>y.name)})),a.tool_calls.forEach((y,R)=>{console.log(`[WS] Tool call ${R}:`,y.name,JSON.stringify(y.args||{}).substring(0,100))})):console.log("[WS] AIMessage with NO tool_calls - content:",typeof a?.content);const x=n.metadata?.langgraph_checkpoint_ns||"",$=Re.some(y=>x.includes(y))||x.includes("team_decider"),q=x.includes("response_generator")&&!$,S=(x.includes("response_generator")||$)&&!(Oe&&q),O=x.includes("response_generator")&&!$&&Et>0;if(S&&!O){const y=typeof a?.content=="string"?a.content:Array.isArray(a?.content)?a.content.map(R=>typeof R=="string"?R:R?.text??"").join(""):"";y&&(console.log("[WS] \u{1F4DD} Captured response generator content from on_chat_model_end, length:",y.length),Ie+=y,Ee+=y)}}if((n.event==="on_chat_model_stream"||n.event==="on_llm_stream")&&console.log("[WS] Stream event checkpoint_ns:",n.metadata.langgraph_checkpoint_ns),n.event==="on_custom_event"){const a=n.data||{};if(n.name==="assistant_start")a.subThreadId&&It.set(a.subThreadId,{assistantId:a.assistantId||"",assistantName:a.assistantName||"unknown"}),at={assistantId:a.assistantId||"",assistantName:a.assistantName||"unknown"},l(i,{type:"assistant_start",runId:r,assistantId:a.assistantId||"",assistantName:a.assistantName||"unknown",assistantIndex:a.index??0,totalAssistants:a.total??1});else if(n.name==="assistant_end"){if(a.assistantId&&Array.isArray(a.toolsUsed)&&a.toolsUsed.length>0&&(_t[a.assistantId]=a.toolsUsed),at=null,l(i,{type:"assistant_end",runId:r,assistantId:a.assistantId||"",assistantName:a.assistantName||"unknown",success:a.success??!0,stats:{toolsCount:Array.isArray(a.toolsUsed)?a.toolsUsed.length:0,duration:a.durationMs},output:typeof a.output=="string"?a.output:void 0,errorStack:typeof a.errorStack=="string"?a.errorStack:void 0}),e.teamId){const T=a.assistantId||"",U=w.filter(x=>x.assistantId===T),v=x=>x.reduce(($,q)=>({inputTokens:$.inputTokens+(q.inputTokens||0),outputTokens:$.outputTokens+(q.outputTokens||0),totalTokens:$.totalTokens+(q.totalTokens||0),cacheCreationTokens:$.cacheCreationTokens+(q.cacheCreationTokens||0),cacheReadTokens:$.cacheReadTokens+(q.cacheReadTokens||0)}),{inputTokens:0,outputTokens:0,totalTokens:0,cacheCreationTokens:0,cacheReadTokens:0});l(i,{type:"team_token_running_total",runId:r,teamId:e.teamId,assistantId:T,assistantName:a.assistantName||"unknown",perAssistant:v(U),cumulative:v(w)})}}else if(n.name==="assistant_progress")l(i,{type:"assistant_progress",runId:r,assistantId:a.assistantId||at?.assistantId||"",assistantName:a.assistantName||at?.assistantName||"unknown",phase:a.phase||"info",index:a.index,total:a.total,durationMs:a.durationMs,toolsUsed:Array.isArray(a.toolsUsed)?a.toolsUsed:void 0,message:typeof a.message=="string"?a.message:void 0});else if(n.name==="team_event")l(i,{type:"team_event",runId:r,node:typeof a.node=="string"?a.node:"team",kind:typeof a.kind=="string"?a.kind:"info",details:a});else if(n.name==="chat_suggestions")Array.isArray(a.suggestions)&&a.suggestions.length>0&&l(i,{type:"suggestions",runId:r,suggestions:a.suggestions.filter(T=>typeof T=="string")});else if(n.name==="decider_direct_block"){const T=typeof a.ndjson=="string"?a.ndjson:"";T&&(Ie+=T+`
|
|
33
|
+
`,Ee+=T+`
|
|
34
|
+
`,console.log(`[WS] \u{1F4E8} team_decider direct error block captured into aiContentOnly (${a.failedCount??"?"} failed assistant(s)):`,T.slice(0,160)))}}const He=n.event==="on_chain_end"&&n.name==="LangGraph",fe=He&&(n.metadata?.langgraph_checkpoint_ns||"")==="";if(He){const a=(n.metadata?.langgraph_checkpoint_ns||"")===""?"(empty=outer)":n.metadata?.langgraph_checkpoint_ns;console.log("[WS] \u2705 ALLOWING graph end event - on_chain_end with name: LangGraph, checkpoint_ns:",a),fe?(l(i,{type:"end",runId:r}),console.log("[WS] \u{1F4E4} Sent 'end' signal to frontend for runId:",r)):console.log("[WS] \u26A0\uFE0F Sub-graph chain end \u2014 letting it pass through but not sending 'end'")}else if(!(!n.metadata.langgraph_checkpoint_ns&&(n.event==="on_chain_start"||n.event==="on_chain_end")&&typeof n.name=="string"&&Re.includes(n.name))&&(!n.metadata.langgraph_checkpoint_ns||n.metadata.langgraph_checkpoint_ns&&n.metadata.langgraph_checkpoint_ns.indexOf("assistant")===-1&&n.metadata.langgraph_checkpoint_ns.indexOf("documentation")===-1&&n.metadata.langgraph_checkpoint_ns.indexOf("tool")===-1&&n.metadata.langgraph_checkpoint_ns.indexOf("response_generator")===-1&&n.metadata.langgraph_checkpoint_ns.indexOf("generate")===-1&&n.metadata.langgraph_checkpoint_ns.indexOf("team_decider")===-1&&n.metadata.langgraph_checkpoint_ns.indexOf("team_pipeline")===-1&&n.metadata.langgraph_checkpoint_ns.indexOf("team_parallel")===-1&&!Re.some(U=>n.metadata.langgraph_checkpoint_ns?.indexOf(U)!==-1))){console.log("[WS] \u26A0\uFE0F SKIPPING event - checkpoint_ns doesn't match assistant/documentation/tool","| event:",n.event,"| checkpoint_ns:",n.metadata.langgraph_checkpoint_ns);continue}if(n.event==="on_chat_model_start"){n.run_id&&pe.set(n.run_id,Date.now());const a=n.metadata?.langgraph_checkpoint_ns||"";(a.includes("assistant_response_generator")||X.some(T=>a.includes(T)))&&(console.log("[WS] \u{1F504} Resetting jsonAccumulatorBuffer for new assistant_response_generator run (checkpoint_ns:",a,")"),_e="")}if(n.event==="on_chat_model_stream"||n.event==="on_llm_stream"){const a=n.metadata?.langgraph_checkpoint_ns||"",T=X.some($=>a.includes($)),U=Oe&&a.includes("response_generator")&&!T;if(!a.includes("response_generator")&&!a.includes("team_decider")&&!T||U){if(a.includes("tool_executor")){const $=n.data?.chunk??n.data?.output,q=$?.content,S=typeof q=="string"?q:Array.isArray(q)?q.map(O=>typeof O=="string"?O:O?.text??"").join(""):$?.delta??$?.token??"";S&&typeof S=="string"&&(l(i,{type:"reasoning_token",runId:r,assistantId:Ae(n),text:S}),Oe||(ot+=S))}continue}const v=n.data?.chunk??n.data?.output,x=v?.content?.[0]?.text??v?.content??v?.delta??v?.token??"";if(x&&typeof x=="string"){if(process.env.GRAPH_STATE_DEBUG&&console.log("[WS] Streaming piece:",x.slice(0,50)),Ee+=x,Ie+=x,a.includes("response_generator")&&!a.includes("team_decider")&&(Et+=x.length),!xt){xt=!0,console.log("[WS] \u{1F3AF} First generation token detected - closing running tools"),console.log(`[WS] \u{1F50D} toolsUsed array length: ${Q.length}`),console.log("[WS] \u{1F50D} toolsUsed:",Q.map(O=>({name:O.name,hasOutput:O.output!==null})));const S=Q.filter(O=>O.output===null);console.log(`[WS] \u{1F50D} Filtered running tools: ${S.length}`,S.map(O=>O.name)),S.length>0&&(console.log(`[WS] \u26A0\uFE0F Found ${S.length} tools still running, marking as error`),S.forEach(O=>{O.output="Error: Tool execution interrupted by generation start",l(i,{type:"tool_end",runId:r,assistantId:Ae(n),text:JSON.stringify({toolName:O.name,toolInput:null,output:O.output,error:!0,errorMessage:"Tool execution interrupted by generation start"})}),console.log(`[WS] \u274C Closed running tool: ${O.name}`)}))}const $=et.getStats().firstTokenSent?"normal":"high";et.addToken(x,{priority:$}),vt.recordChunk(),_e+=x;const q=ue.extractJsonObjects(_e);if(q.length>0){for(const y of q)try{const R=JSON.parse(y),d=Wn(R);d?.channel==="blockkit_token"?(l(i,{type:"blockkit_token",runId:r,block:R}),Ze++,console.log(`[WS] \u{1F4E6} Streaming blockkit block sent (total: ${Ze}), type: ${R.type}`)):d?.channel==="dashboard_block"&&(l(i,{type:"dashboard_block",runId:r,block:R,timestamp:Date.now()}),Ze++,console.log(`[WS] \u{1F4E6} Streaming block sent (total: ${Ze}), type: ${R.type}`))}catch(R){console.error("[WS] Failed to parse JSON block:",R)}const S=q[q.length-1],O=_e.lastIndexOf(S);O>=0&&(_e=_e.substring(O+S.length))}}}if(n.event==="on_tool_start"){const a=n.name,T=n.data?.input,U=JSON.stringify(n.metadata.langgraph_checkpoint_ns);console.log("[WS] Tool starting:",a,"| checkpoint_ns:",U,"| input:",JSON.stringify(T)?.substring(0,100)),k.start(`tool_${a}`,{toolName:a,hasInput:!!T});const v=ut.get(a);console.log(`[WS] Tool metadata lookup for "${a}":`,v?`Found: "${v.description}"`:"NOT FOUND"),Q.push({name:a,description:v?.description,input:T,output:null,timestamp:new Date().toISOString(),error:!1,empty:!1,mcpServerId:u.toolServerMap?.[a]?.serverId,toolCallId:n.run_id}),l(i,{type:"tool_start",runId:r,assistantId:Ae(n),text:JSON.stringify({toolName:a,toolInput:T||null})});const x=`
|
|
35
|
+
|
|
36
|
+
\u{1F527} **Calling ${a}...**
|
|
37
|
+
`;Ee+=x}if(n.event==="on_tool_end"){const a=n.name,T=n.data?.output;if(console.log("[WS] \u{1F527} Tool ended:",a,"| Has result:",!!T,"| Type:",typeof T),k.end(`tool_${a}`,{hasOutput:!!T}),qe>1&&(Ke++,console.log(`[ParallelTools] Tool ${a} completed (${Ke}/${qe})`),Ke===qe)){const v=Date.now()-pt;k.end("parallel_tools_execution",{completed:Ke,duration:v});const S=k.getAllMetrics().filter(y=>y.name.startsWith("tool_")&&y.duration).map(y=>y.duration).reduce((y,R)=>y+R,0),O=S>0?(S-v)/S*100:0;console.log(`[ParallelTools] \u2705 All ${qe} tools completed in ${v}ms`),console.log(`[ParallelTools] Sequential time would be: ${S}ms`),console.log(`[ParallelTools] Time saved: ${S-v}ms (${O.toFixed(1)}%)`),qe=0,Ke=0,pt=0}let U=null;if(T&&(typeof T=="string"?(console.log("[WS] \u2705 Tool returned direct string response"),U=T):T.content?(console.log("[WS] \u2705 Tool returned object with .content property"),U=Array.isArray(T.content)?T.content.map(v=>v.text||JSON.stringify(v)).join(`
|
|
38
|
+
`):T.content):(console.log("[WS] \u26A0\uFE0F Tool returned unknown format, stringifying..."),U=JSON.stringify(T))),U&&typeof U=="string"){console.log("[WS] Tool content streaming:",U.substring(0,200));let v=!1,x="";try{const S=JSON.parse(U);if(Object.keys(S).length===0)v=!0,x="No data returned (empty object)";else if(Array.isArray(S)&&S.length===0)v=!0,x="No data returned (empty array)";else if(Object.keys(S).length===1){const O=Object.keys(S)[0],y=S[O];typeof y=="object"&&(Array.isArray(y)&&y.length===0?(v=!0,x=`No data in ${O} array`):!Array.isArray(y)&&Object.keys(y).length===0&&(v=!0,x=`No data in ${O} object`))}}catch{console.log("[WS] Tool result is not JSON, assuming has data")}const $=yt(a,n.run_id);$&&($.output=v?`Empty: ${x}`:U,$.empty=v,$.error=!1,$.duration=Date.now()-new Date($.timestamp).getTime(),v&&($.emptyReason=x)),l(i,{type:"tool_end",runId:r,assistantId:Ae(n),text:JSON.stringify({toolName:a,toolInput:$?.input||null,output:v?`Empty: ${x}`:U,error:!1,empty:v,emptyReason:v?x:void 0})}),v&&console.log(`[WS] \u26A0\uFE0F Tool ${a} returned empty data: ${x}`);const q=`
|
|
39
|
+
|
|
40
|
+
\u{1F4CA} **${a} Result:**
|
|
41
|
+
\`\`\`json
|
|
42
|
+
${U}
|
|
43
|
+
\`\`\`
|
|
44
|
+
|
|
45
|
+
`;Ee+=q}else{console.log("[WS] \u274C Tool ended without valid content:",a),console.log("[WS] toolResult was:",T?"exists but no valid content":"null/undefined");const v=yt(a,n.run_id);v&&(v.output="Error: Tool execution failed or timed out",v.error=!0,v.duration=Date.now()-new Date(v.timestamp).getTime()),l(i,{type:"tool_end",runId:r,assistantId:Ae(n),text:JSON.stringify({toolName:a,toolInput:null,output:v?v.output:"Error: Tool execution failed or timed out",error:!0,errorMessage:"Tool execution failed or returned no content"})})}}const rt=n.metadata?.langgraph_checkpoint_ns||"",nt=n.event==="on_graph_end"||n.event==="on_chain_end"&&n.name==="LangGraph"&&rt==="";if((n.event==="on_chain_end"||n.event==="on_graph_end")&&console.log(`[WS] Chain/Graph end event: ${n.event}, name: ${n.name}, checkpoint_ns: "${rt}", isEnd: ${nt}`),nt&&!Ue){Ue=!0,console.log("[WS] \u{1F3C1} FINAL END DETECTED - Calling slicer.end()"),k.end("stream_processing"),k.end("langgraph_stream"),k.start("response_finalization"),et.finalize();const a=vt.getSummary();console.log("[WS] Streaming metrics:",{timeToFirstToken:`${a.timeToFirstToken}ms`,totalDuration:`${a.totalDuration}ms`,tokensPerSecond:a.tokensPerSecond.toFixed(2),totalTokens:a.totalTokens,totalChunks:a.totalChunks,avgChunkSize:Math.round(a.averageChunkSize)}),console.log("[WS] Generation complete"),console.log("[WS] Full response length:",Ee.length),Ee.length>500?console.log("[WS] Full response (truncated):",Ee.substring(0,20)+"..."):console.log("[WS] Full response:",Ee.substring(0,20)+"...");const T=ue.extractJsonObjects(_e),U=["markdown","echarts","eui","recharts","table","mermaid","leaflet","blockkit","mantine","remotion"];if(T.length>0){for(const re of T)try{const ve=JSON.parse(re);ve.type&&U.includes(ve.type)&&l(i,{type:"dashboard_block",runId:r,block:ve,timestamp:Date.now()})}catch(ve){console.error("[WS] Failed to parse final JSON block:",ve)}const d=T[T.length-1],F=_e.lastIndexOf(d);F>=0&&(_e=_e.substring(F+d.length)),await new Promise(re=>setTimeout(re,200))}const v=_e.indexOf("{"),x=v>=0?_e.slice(v):"";if(x.length>2&&x.includes('"type"'))try{const d=Qt(x,wt.OBJ|wt.ARR|wt.STR),F=d&&(d.body||d.content||d.title||d.data);d?.type&&U.includes(d.type)&&F&&(console.warn(`[WS] \u{1FA79} Salvaged a truncated final '${d.type}' block via partial-json (tail=${x.length} chars) \u2014 generation was likely cut off at max_tokens`),l(i,{type:"dashboard_block",runId:r,block:d,timestamp:Date.now()}),await new Promise(re=>setTimeout(re,100)))}catch(d){console.error("[WS] partial-json salvage of trailing buffer failed:",d?.message)}_e="",ue.end(),await new Promise(d=>setTimeout(d,100));const $=J.getStatus();if(console.log("[WS] Dashboard status:",$.blocksCount,$.hasBlocks),console.log("[WS] Slicer processed data:",gt),console.log("[WS] Fallback check:",{slicerProcessedData:gt,hasBlocks:$.hasBlocks,blocksCount:$.blocksCount,aiContentLength:Ie.length,willRunFallback:Ie.trim().length>0}),Ie.trim()){console.log("[WS] \u2705 Attempting fallback parsing to extract all blocks from final response"),console.log("[WS] AI content only length:",Ie.length);try{let d=Ie;console.log(`[WS] Fallback parsing: Content length: ${Ie.length}`),console.log("[WS] Content preview:",Ie.substring(0,300));const F=`/tmp/llm-response-${Date.now()}.txt`;Ht(F,Ie),console.log(`[WS] \u{1F50D} Full content saved to: ${F}`);let re=Ie.replace(/```json\s*/g,"").replace(/```\s*/g,"").trim();console.log(`[WS] \u{1F50D} After removing markdown fences, content length: ${re.length}`);let ve=[];{const ce=(K=>{const ye=[];let Y="",Ve=0,ie=!1,De=!1;for(let it=0;it<K.length;it++){const Me=K[it];if(De){Y+=Me,De=!1;continue}if(Me==="\\"){De=!0,Y+=Me;continue}if(Me==='"'&&!De){ie=!ie,Y+=Me;continue}ie?Y+=Me:Me==="{"?(Ve++,Y+=Me):Me==="}"?(Ve--,Y+=Me,Ve===0&&Y.trim()&&(ye.push(Y.trim()),Y="")):Y+=Me}return ye})(re);if(console.log(`[WS] \u{1F50D} Brace-counting parser extracted ${ce.length} JSON objects`),console.log("[WS] \u{1F50D} Individual objects preview:",ce.map((K,ye)=>`Block ${ye}: ${K.substring(0,100)}...`)),ve=ce.map(K=>[K,K]),console.log(`[WS] \u2705 Extracted ${ve.length} JSON block(s) from content`),ve.length===1)d=ve[0][1].trim();else{const K=Xt(ve.map(Y=>Y[1]));console.log(`[WS] Parsed ${K.length} valid blocks from ${ve.length} code fences`),console.log("[WS] Block types:",K.map(Y=>Y.type).join(", ")),console.log("[WS] Block titles:",K.map(Y=>Y.title).join(" | "));const ye=K.filter(Y=>Y.type&&["markdown","echarts","eui","recharts","table","mermaid","leaflet","blockkit","mantine","remotion"].includes(Y.type));if(console.log(`[WS] \u{1F50D} Filtered to ${ye.length} valid dashboard blocks (from ${K.length} parsed blocks)`),ye.length>0){console.log(`[WS] \u2705 Sending ${ye.length} blocks one-by-one via addBlock()`);const Ve=(async()=>{for(let ie=0;ie<ye.length;ie++){const De=ye[ie];console.log(`[WS] \u{1F4E4} Sending block ${ie+1}/${ye.length}: ${De.type} - ${De.title}`),J.addBlock(De),ie<ye.length-1&&await new Promise(it=>setTimeout(it,200))}})();Pe.push(Ve.then(()=>{console.log(`[WS] \u2705 Blocks sent sequentially for assistant ${g+1}`)}).catch(ie=>{console.error("[WS] Error sending blocks sequentially:",ie)})),d=null}else console.warn(`[WS] \u26A0\uFE0F No valid dashboard blocks found (${K.length} blocks parsed, 0 valid)`),K.length>0?(console.log("[WS] \u{1F4CB} First block details:",{type:K[0].type,title:K[0].title,keys:Object.keys(K[0])}),d=JSON.stringify(K[0])):d=null}}if(d===null){console.log("[WS] \u2705 Blocks already sent individually, skipping fallback JSON parsing");const D=J.getStatus();console.log("[WS] After fallback - blocks count:",D.blocksCount)}else{console.log("cleanedResponse",d.substring(0,100)+"..."),d=Vn(d),console.log("cleanedResponse II",d.substring(0,20)+"...");let D;try{D=JSON.parse(d)}catch(ne){console.log("[WS] JSON parsing failed, trying to fix truncated JSON:",ne,d.substring(0,20)+"...");let ce=d.trim();if(!ce.endsWith("}")&&!ce.endsWith("]")){const K=(ce.match(/\{/g)||[]).length,ye=(ce.match(/\}/g)||[]).length,Y=(ce.match(/\[/g)||[]).length,Ve=(ce.match(/\]/g)||[]).length;for(let ie=0;ie<Y-Ve;ie++)ce+="]";for(let ie=0;ie<K-ye;ie++)ce+="}";console.log("[WS] Attempting to parse fixed JSON...");try{D=JSON.parse(ce),console.log("[WS] Successfully parsed fixed JSON")}catch(ie){const De='{"session_id":"'+I+'","result":{"content":[{"type":"markdown","title":"robot","body":'+JSON.stringify(ce)+"}]}}";D=JSON.parse(De),console.log("[WS] Fixed JSON parsing also failed:",ie)}}else throw ne}if(D&&typeof D=="object"&&D.result&&Array.isArray(D.result.content))console.log("[WS] Fallback: parsed dashboard format"),J.setDashboard(D);else if(D&&typeof D=="object"&&D.blocks&&Array.isArray(D.blocks))console.log("[WS] Fallback: parsed {blocks: [...]} format"),D.blocks.forEach(ne=>{ne&&ne.type&&ne.title&&J.addBlock(ne)});else if(Array.isArray(D))console.log("[WS] Fallback: parsed array of blocks"),D.forEach(ne=>{ne&&ne.type&&ne.title&&J.addBlock(ne)});else if(D&&D.type==="json"&&D.body!==void 0)console.log("[WS] \u2728 json-type block detected \u2192 sending as dashboard_block"),l(i,{type:"dashboard_block",runId:r,block:D,timestamp:Date.now()});else if(D&&typeof D=="object"){console.log("[WS] Fallback: converting raw JSON to dashboard format");const ne=ue.convertRawJsonToDashboard(D);if(ne&&ne.result&&Array.isArray(ne.result.content))console.log("[WS] Successfully converted raw JSON to dashboard"),J.setDashboard(ne);else{console.log("[WS] Failed to convert raw JSON, creating simple markdown block");const ce={type:"markdown",title:"\u{1F4CA} Raw Data",body:`\`\`\`json
|
|
46
|
+
${JSON.stringify(D,null,2)}\`\`\``};J.addBlock(ce)}}else D&&D.type&&D.title&&(console.log("[WS] Fallback: parsed single block"),J.addBlock(D))}}catch(d){console.error("[WS] Fallback parsing failed:",d),l(i,{type:"format_error",runId:r,error:"Failed to parse AI response as JSON",raw_response:Ee.slice(0,500)})}}else console.log("[WS] Streaming processed successfully, blocks count:",$.blocksCount);if(console.log("[WS] done",$.blocksCount),Ze>0)console.log(`[WS] \u2705 Skipping fallback: ${Ze} block(s) already sent via streaming path`);else if($.blocksCount===0){console.log("[WS] No blocks emitted, attempting fallback...");const d=ue.getTotalMarkdownContent();if(mt&&mt.trim().length>0){console.log(`[WS] Fallback: Using raw_output node content (${mt.length} chars)`),J.sendFallbackBlock(mt.trim());const F=J.getStatus();console.log("[WS] After raw_output fallback - blocks count:",F.blocksCount)}else if(d&&d.length>0){console.log(`[WS] Fallback: Found ${d.length} chars of markdown content`),J.sendFallbackBlock(d);const F=J.getStatus();console.log("[WS] After fallback - blocks count:",F.blocksCount)}else if(ot&&ot.trim().length>0){console.log(`[WS] Fallback: Using assistant_tool_executor text (${ot.length} chars)`),J.sendFallbackBlock(ot.trim());const F=J.getStatus();console.log("[WS] After tool-executor fallback - blocks count:",F.blocksCount)}else console.log("[WS] Fallback: No markdown content captured")}const q=J.getStatus();console.log("[WS] Final status after fallback:",q.blocksCount,"blocks"),console.log("[WS] \u23F3 Waiting 300ms for late-arriving tool_end events..."),await new Promise(d=>setTimeout(d,300));const S=Q.filter(d=>d.output===null);if(S.length>0?(console.log(`[WS] \u26A0\uFE0F Found ${S.length} tools that never completed:`,S.map(d=>d.name)),S.forEach(d=>{d.output="Timeout: Tool execution exceeded time limit",d.error=!0,d.timeout=!0,l(i,{type:"tool_end",runId:r,text:JSON.stringify({toolName:d.name,toolInput:d.input,output:d.output,error:!0,timeout:!0,errorMessage:"Tool execution exceeded time limit"})}),console.log(`[WS] \u23F1\uFE0F Marked incomplete tool as timeout: ${d.name}`)})):console.log("[WS] \u2705 All tools completed successfully"),Q.length>0&&(console.log("[WS] Sending tools summary:",Q.length,"tools used"),console.log("[WS] Tools completion status:",Q.map(d=>({name:d.name,hasOutput:d.output!==null,error:d.error,empty:d.empty}))),l(i,{type:"tools_summary",runId:r,tools:Q.map(d=>({name:d.name,description:d.description,input:d.input,output:d.output,timestamp:d.timestamp,error:d.error,empty:d.empty,emptyReason:d.emptyReason}))}),console.log(`[WS] \u{1F4E4} Sending assistant_end for ${u.assistant?.name}`),await l(i,{type:"assistant_end",runId:r,assistantId:u.assistant?.assistantId,assistantName:u.assistant?.name,assistantIndex:g,totalAssistants:H,success:!0,tools:Q.slice(te),llmCallsCount:h.length,stats:{toolsCount:Q.slice(te).length,duration:k.get("langgraph_stream")||0}}),(async()=>{try{const d=G();if(!d){console.warn("[WS] Cannot save tools to ES: no username found");return}const F=e.chatId||r;console.log("[WS] Saving tools to Elasticsearch:",{chatId:F,runId:r,username:d,toolsCount:Q.length}),await Jt.createChatToolsRecord({chatId:F,runId:r,username:d,assistantId:u.assistant?.assistantId||"unknown",assistantName:u.assistant?.name||"unknown",tools:Q.slice(te).map(re=>({name:re.name,description:re.description,input:re.input,output:re.output,timestamp:re.timestamp,error:re.error??!1,duration:re.duration??0,mcpServerId:re.mcpServerId})),metadata:{cluster:e.queryParams?.cluster,topic:e.queryParams?.topic,llmProvider:u.llmConfig?.provider||V?.provider||"unknown",llmModel:u.llmConfig?.model||V?.model||"unknown"},createdAt:new Date().toISOString()}),console.log("[WS] \u2705 Tools saved to Elasticsearch successfully"),h.length>0&&(await xn.createChatLLMsRecord({chatId:F,runId:r,username:d,teamId:e.teamId,assistantId:u.assistant?.assistantId||"unknown",assistantName:u.assistant?.name||"unknown",llms:h,createdAt:new Date().toISOString()}),console.log(`[WS] \u2705 LLM calls saved to Elasticsearch (${h.length} calls)`))}catch(d){console.error("[WS] Failed to save tools to Elasticsearch:",d)}})()),k.end("response_finalization"),$.hasBlocks&&process.env.CACHE_ENABLED!=="false"){k.start("cache_store");try{const d=J.getBlocks();if(d.length>0){const F={blocks:d,query:e.input,timestamp:Date.now()};lt.set(me,F,{topic:e.queryParams?.topic,namespace:we,blocksCount:$.blocksCount}),console.log("[Dashboard Cache] Stored response for future queries")}}catch(d){console.error("[Cache] Failed to store response:",d)}k.end("cache_store")}se.delete(r),Qe(r),console.log(`[WS] Removed active run (complete): ${r} (remaining: ${se.size})`);try{const d=Array.from(new Set(Q.map(ne=>ne.name))),F=e.graphId||A[0]?.assistant?.graphId,re=ke?.length===1?ke[0]:void 0,ve=re?.assistantId||A[0]?.assistant?.assistantId||"unknown",D=re?.name||A[0]?.assistant?.name||"unknown";await st(r,"success",{duration:k.getTotalDuration(),toolsUsed:d,toolCallsCount:Q.length,graphId:F,assistantId:ve,assistantName:D,llmUsage:w,...Object.keys(_t).length>0?{subAssistantToolsMap:_t}:{}}),console.log(`[WS] \u2705 Completed chat run record: ${r}`)}catch(d){console.error("[WS] \u26A0\uFE0F Failed to complete chat run record:",d)}k.end("total_execution"),k.printSummary(),await l(i,{type:"performance_summary",runId:r,summary:k.getSummary()});const O=lt.getStats(),y=Dt.getStats();await Mt(i);const R=$.isComplete||$.hasBlocks||ue.getTotalMarkdownContent().length>0;R||console.error(`[WS] \u26A0\uFE0F DONE ok=false for run ${r} \u2014 last completed node: ${ge??"(none)"}, assistant: ${u.assistant?.name}`),console.log(`[WS] \u{1F3C1} Sending DONE message for run ${r}`,{ok:R,isComplete:$.isComplete,hasBlocks:$.hasBlocks,markdownLength:ue.getTotalMarkdownContent().length,lastCompletedNode:ge,stackTrace:new Error().stack?.split(`
|
|
47
|
+
`).slice(1,4).join(`
|
|
48
|
+
`)}),await l(i,{type:"done",runId:r,ok:R,stats:{blocksGenerated:q.blocksCount,responseLength:Ee.length,totalDuration:k.getTotalDuration(),streaming:{timeToFirstToken:a.timeToFirstToken,tokensPerSecond:Math.round(a.tokensPerSecond),totalChunks:a.totalChunks},cache:{enabled:process.env.CACHE_ENABLED!=="false",hit:!1,dashboard:{hitRate:O.hitRate,size:O.size},data:{hitRate:y.hitRate,size:y.size}}}})}}if(kt){console.log(`[HITL] Skipping assistant ${g+1} finalization \u2014 HITL interrupt pending`);break}console.log(`
|
|
49
|
+
${"\u2705 ".repeat(40)}`),console.log(`\u2705 ASSISTANT ${g+1}/${H} COMPLETED`),console.log(`${"\u2705 ".repeat(40)}`),console.log(`\u{1F4CA} Assistant: ${u.assistant?.name}`),console.log(`\u{1F4CA} Duration: ${k.get("langgraph_stream")||0}ms`),console.log(`\u{1F4CA} Tools Used: ${Q.filter(n=>n.name).length}`),console.log(`\u{1F4CA} Blocks: ${J.getBlocks().length}`),console.log(`${"\u2705 ".repeat(40)}
|
|
50
|
+
`),N.push({assistantName:u.assistant?.name||"unknown",assistantId:u.assistant?.assistantId||"unknown",toolsUsed:Q.slice(),blocksGenerated:J.getBlocks().length,success:!0,duration:k.get("langgraph_stream")||0,llmCallsCount:h.length});const bt=[...Q.slice(te)].reverse().find(n=>n.output&&!n.error);if(bt?.output&&typeof bt.output=="string")try{ae=JSON.parse(bt.output),console.log(`[WS] \u{1F4E6} Captured structured result from tool "${bt.name}" for next assistant condition eval`)}catch{ae=void 0}else ae=void 0;if(!(u.app.isKibanaAgent||u.app.isA2aAgent))try{const X=((await u.app.getState({configurable:{thread_id:u.threadId,checkpoint_ns:""}}))?.values?.messages||[]).filter(Oe=>Oe._getType?.()==="ai"||Oe.constructor?.name==="AIMessage").slice(-1)[0];if(X?.content){const Te=(typeof X.content=="string"?X.content:Array.isArray(X.content)?X.content.map(z=>typeof z=="string"?z:z.text??"").join(""):JSON.stringify(X.content)).trim(),Ne=g>0?C.reduce((z,He)=>z+He.toolNames.length,0):0,Ge=[...new Set(Q.slice(Ne).map(z=>z.name).filter(Boolean))];if(C.push({assistantName:u.assistant?.name||"unknown",content:Te,toolNames:Ge}),g<H-1&&Te.length>0){const z=A[g+1]?.assistant?.name||"next assistant",He=C.map(nt=>`### ${nt.assistantName}
|
|
51
|
+
${Un(nt.content,1500)}`).join(`
|
|
52
|
+
|
|
53
|
+
`),fe=[...new Set(C.flatMap(nt=>nt.toolNames))],rt=["[Previous analyses \u2014 already covered in this session]",He,"","[Your scope]","Do NOT repeat, restate or summarise findings already covered above.",fe.length>0?`Tools already called (avoid redundant calls unless you have a different query): ${fe.join(", ")}.`:"","Focus exclusively on aspects NOT yet addressed.","Bring new findings, a different perspective or deeper analysis."].filter(Boolean).join(`
|
|
54
|
+
`);o={messages:[new Ct({content:[{type:"text",text:Pt(`${rt}
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
${e.input}`)}]})]},console.log(`[WS] \u{1F517} Pipeline: built scope-reduced input for "${z}" (${C.length} previous analysis/analyses, ${fe.length} tools already called)`)}}}catch(n){console.warn(`[WS] \u26A0\uFE0F Pipeline context injection failed after assistant ${g+1}, using original input:`,n.message),console.warn(`[WS] \u{1F50D} Pipeline debug \u2014 assistant: ${u.assistant?.name}`),console.warn(`[WS] \u{1F50D} Pipeline debug \u2014 threadId: ${u.threadId}`),console.warn(`[WS] \u{1F50D} Pipeline debug \u2014 checkpointNs: ${we}`),console.warn(`[WS] \u{1F50D} Pipeline debug \u2014 app type: ${u.app?.constructor?.name}`),console.warn(`[WS] \u{1F50D} Pipeline debug \u2014 app.getState exists: ${typeof u.app?.getState}`),console.warn("[WS] \u{1F50D} Pipeline debug \u2014 stack:",n.stack?.split(`
|
|
59
|
+
`).slice(0,5).join(`
|
|
60
|
+
`))}}catch(pe){console.error(`
|
|
61
|
+
${"\u274C ".repeat(40)}`),console.error(`\u274C ASSISTANT ${g+1}/${H} FAILED`),console.error(`${"\u274C ".repeat(40)}`),console.error(`\u{1F4CA} Assistant: ${u.assistant?.name}`),console.error(`\u{1F4CA} Node at failure: ${Z??"(before graph execution)"}`),console.error(`\u{1F4CA} Error: ${pe.message}`),pe?.stack&&console.error(`\u{1F4CA} Stack:
|
|
62
|
+
${pe.stack}`),console.error(`${"\u274C ".repeat(40)}
|
|
63
|
+
`),N.push({assistantName:u.assistant?.name||"unknown",assistantId:u.assistant?.assistantId||"unknown",toolsUsed:[],blocksGenerated:0,success:!1,duration:0,llmCallsCount:h.length});let tt=pe.message||"Unknown error";const Ue=pe.error?.error?.type||pe.error?.type,Ae=pe.error?.error?.message||pe.error?.message;Ue&&(tt=Ae||tt),await l(i,{type:"assistant_end",runId:r,assistantId:u.assistant?.assistantId,assistantName:u.assistant?.name,assistantIndex:g,totalAssistants:H,success:!1,error:tt,errorType:Ue,errorStack:pe?.stack,failedNode:Z,tools:[],stats:{toolsCount:0,duration:0}})}}if(kt)console.log(`[HITL] Skipping blocks_complete / orchestration_complete \u2014 HITL interrupt pending for run ${r}`);else{if(Pe.length>0&&(await Promise.all(Pe),console.log("[WS] \u2705 All blocks sent for all assistants")),await l(i,{type:"blocks_complete",runId:r,timestamp:Date.now(),runAssistants:N.map(g=>({assistantId:g.assistantId,assistantName:g.assistantName,toolCallsCount:g.toolsUsed.length,llmCallsCount:g.llmCallsCount,success:g.success}))}),console.log("[WS] \u{1F4E6} Sent blocks_complete message (all assistants complete)"),Be&&Le){const g=w.reduce((u,le)=>u+(le.totalTokens||0),0);qn(Le,{tokens:g}).catch(()=>{}),console.log(`[WS] \u{1F4CA} Embed run metered: +${g} tokens (link ${Le})`)}console.log(`
|
|
64
|
+
${"\u{1F389} ".repeat(40)}`),console.log("\u{1F389} ALL ASSISTANTS COMPLETED"),console.log(`${"\u{1F389} ".repeat(40)}`),console.log(`\u{1F4CA} Total Assistants: ${H}`),console.log(`\u{1F4CA} Successful: ${N.filter(g=>g.success).length}`),console.log(`\u{1F4CA} Failed: ${N.filter(g=>!g.success).length}`),console.log(`\u{1F4CA} Total Tools Used: ${Q.length}`),console.log(`\u{1F4CA} Total Blocks Generated: ${J.getBlocks().length}`),console.log(`${"\u{1F389} ".repeat(40)}
|
|
65
|
+
`),await l(i,{type:"orchestration_complete",runId:r,assistants:N.map(g=>({name:g.assistantName,id:g.assistantId,success:g.success,toolsCount:g.toolsUsed.length,blocksCount:g.blocksGenerated,duration:g.duration})),totalAssistants:H,successfulAssistants:N.filter(g=>g.success).length,failedAssistants:N.filter(g=>!g.success).length})}if(ze.length>0){const g=G();g&&(async()=>{try{Nt(r),await Mn({chatId:e.chatId||r,runId:r,username:g,teamId:e.teamId,events:ze,createdAt:new Date().toISOString()})}catch(u){console.error(`[chat-traces] Failed to flush trace for run ${r}:`,u)}})()}else Nt(r)}catch(s){if(s?.name==="AbortError"||se.get(r)?.abortController.signal.aborted===!0||/aborted/i.test(String(s?.message??""))){console.log(`[WS] \u{1F6D1} Run ${r} cancelled by user (AbortError caught \u2014 not an error)`);return}console.error(`[WS] \u274C Global stream error for run ${r}:`,s),s?.stack&&console.error(`[WS] \u274C Stack for run ${r}:
|
|
66
|
+
${s.stack}`);let b={message:s.message||"Unknown error occurred",type:"stream_error",details:null};s.error?.type==="overloaded_error"?b={message:"L'API Claude est temporairement surcharg\xE9e. Veuillez r\xE9essayer dans quelques instants.",type:"api_overloaded",details:{apiError:s.error.type,requestId:s.requestID,retryAfter:"30 seconds"}}:s.error?.type==="rate_limit_error"?b={message:"Limite de taux d'API atteinte. Veuillez patienter avant de faire une nouvelle requ\xEAte.",type:"rate_limit",details:{apiError:s.error.type,requestId:s.requestID,retryAfter:"1 minute"}}:s.error?.type&&(b={message:`Erreur API Claude: ${s.error.message||s.message}`,type:"api_error",details:{apiError:s.error.type,requestId:s.requestID}}),l(i,{type:"error",runId:r,error:b.message,errorType:b.type,errorDetails:b.details,errorStack:s?.stack,timestamp:new Date().toISOString()});try{const W=ke?.length===1?ke[0]:void 0,L=W?.assistantId||A[0]?.assistant?.assistantId||"unknown",j=W?.name||A[0]?.assistant?.name||"unknown",N=At(s);await st(r,"error",{assistantId:L,assistantName:j,metadata:{error:b.message,errorType:b.type},errorType:N.errorType,errorMessage:N.errorMessage,errorNodeId:b.type?`runtime:${b.type}`:void 0}),console.log(`[WS] \u2705 Completed chat run record with error: ${r}`)}catch(W){console.error("[WS] \u26A0\uFE0F Failed to complete chat run record:",W)}Nt(r);try{Ye.destroy()}catch{}}finally{if(!kt&&A&&A.length>0){for(const s of A)if(s.app&&s.app.cleanup)try{console.log(`[WS] Cleaning up app for assistant: ${s.assistant?.name||"unknown"}`),s.app.cleanup()}catch(o){console.error(`[WS] Error cleaning up MCP clients for assistant ${s.assistant?.name}:`,o)}}}};i.off("message",f);for(const M of m)await ht(M);i.on("message",ht),i.on("close",async()=>{console.log("[WS] Client disconnected - cleaning up active runs");const M=[];if(se.forEach((e,V)=>{e.ws===i&&M.push(V)}),M.length>0){console.log(`[WS] Aborting ${M.length} active runs:`,M);for(const e of M){const V=se.get(e);if(V){console.log(`[WS] Aborting run ${e}`),V.abortController.abort(),se.delete(e),Qe(e);try{await st(e,"error",{errorType:"abort",errorMessage:"Client disconnected",metadata:{error:"Client disconnected",interrupted:!0}}),console.log(`[WS] \u2705 Completed chat run record (client disconnected): ${e}`)}catch(Se){console.error("[WS] \u26A0\uFE0F Failed to complete chat run record on disconnect:",Se)}}}console.log(`[WS] Cleanup complete (remaining active runs: ${se.size})`)}else console.log("[WS] No active runs to clean up")}),i.on("error",M=>{console.error("[WS] WebSocket error:",M)})}export{Ft as DashboardStreamManager,jt as OptimizedJsonSlicer,Ks as attachHandlers};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import{BaseResponseParser as d}from"./base-parser";class m extends d{inMarkdownBody=!1;bodyStart=!1;markdownBuffer="";braceCount=0;inJsonBlock=!1;lastStreamTime=0;introPatterns=[/^Here\s+is\s+the\s+detailed\s+information\s+about/i,/^I'?ll\s+help\s+you\s+with/i,/^Let\s+me\s+analyze/i,/^Based\s+on\s+the\s+data/i,/^I'?ve\s+fetched/i,/^I'?ve\s+gathered/i,/^Here'?s\s+what\s+I\s+found/i,/^The\s+information\s+shows/i];processChunk(t){this.buffer+=t;const r=this.buffer.match(/\{"type"\s*:\s*"markdown"/),e=this.buffer.includes('{"type"')&&this.buffer.includes('"markdown"');if((r||e)&&!this.inJsonBlock&&(this.inJsonBlock=!0,this.braceCount=1),this.inJsonBlock){const a=(t.match(/\{/g)||[]).length,s=(t.match(/\}/g)||[]).length;this.braceCount+=a-s,this.inMarkdownBody||this.buffer.match(/"body"\s*:\s*"/)&&(this.inMarkdownBody=!0,this.bodyStart=!0,this.markdownBuffer=""),this.inMarkdownBody&&this.extractMarkdownFromChunk(t),this.braceCount===0&&this.inJsonBlock&&this.resetState()}else t.includes('{"type"')&&(this.inJsonBlock=!0,this.braceCount=0)}extractMarkdownFromChunk(t){if(!this.inMarkdownBody)return;let r=-1,e=0;for(;e<t.length;){const n=t[e];if(this.bodyStart){this.bodyStart=!1,e++;continue}if(n==='"'&&(e===0||t[e-1]!=="\\")&&t.slice(e).match(/^"\s*[,}]/)){r=e;break}e++}const a=r>=0?t.slice(0,r):t;let s="";for(e=this.bodyStart?1:0;e<a.length;){const n=a[e];if(n==="\\"&&e+1<a.length)switch(a[e+1]){case"n":s+=`
|
|
2
|
+
`,e+=2;break;case"t":s+=" ",e+=2;break;case"r":s+="\r",e+=2;break;case'"':s+='"',e+=2;break;case"\\":s+="\\",e+=2;break;case"/":s+="/",e+=2;break;default:s+=n,e++;break}else s+=n,e++}this.markdownBuffer+=s,this.totalMarkdownContent+=s,console.log("[MarkdownExtractor] markdownBuffer length:",this.markdownBuffer.length);const i=Date.now(),o=this.markdownBuffer.length>=15,h=i-this.lastStreamTime>200;if((o||h)&&this.markdownBuffer.trim()){const n=this.cleanMarkdownForStreaming(this.markdownBuffer);console.log("[MarkdownExtractor] Streaming chunk:",n.slice(0,50),"..."),n.trim()&&(this.emit("markdownChunk",n),this.lastStreamTime=i),this.markdownBuffer=""}if(r>=0){if(console.log("[MarkdownExtractor] End of markdown body, final buffer:",this.markdownBuffer.length,"chars"),this.markdownBuffer.trim()){const n=this.cleanMarkdownForStreaming(this.markdownBuffer);n.trim()&&this.emit("markdownChunk",n)}this.inMarkdownBody=!1,this.markdownBuffer=""}}resetState(){if(this.inJsonBlock=!1,this.inMarkdownBody=!1,this.bodyStart=!1,this.braceCount=0,this.buffer="",this.lastStreamTime=0,this.markdownBuffer.trim()){const t=this.cleanMarkdownForStreaming(this.markdownBuffer);t.trim()&&this.emit("markdownChunk",t),this.markdownBuffer=""}}complete(){if(this.markdownBuffer.trim()){const t=this.cleanMarkdownForStreaming(this.markdownBuffer);t.trim()&&this.emit("markdownChunk",t)}this.resetState()}getTotalContent(){let t=this.totalMarkdownContent;return t=t.replace(/```json\s*/gi,""),t=t.replace(/```\s*/g,""),t=t.replace(/^json\s*$/gim,""),t=t.replace(/\{\s*"type"\s*:\s*"[^"]+"\s*,[\s\S]*?\}/g,""),t=t.replace(/^\s*\{\s*$/gm,""),t=t.replace(/^\s*\}\s*$/gm,""),t=t.replace(/\n{3,}/g,`
|
|
3
|
+
|
|
4
|
+
`),t=t.replace(/^\s*\n/gm,`
|
|
5
|
+
`),t=t.replace(/ {2,}/g," "),t.trim()}resetTotalContent(){this.totalMarkdownContent=""}cleanMarkdownForStreaming(t){const r=t.trim();return r.startsWith("{")&&r.endsWith("}")&&r.includes('"type"')&&r.includes('"echarts"')?(console.warn("[MarkdownExtractor] Rejected pure JSON block in markdown stream:",r.substring(0,100)),""):t.replace(/\\"/g,'"').replace(/\\\\/g,"\\").replace(/^#{4,6}\s+/gm,"### ").replace(/\n{3,}/g,`
|
|
6
|
+
|
|
7
|
+
`).trim()}}export{m as AnthropicParser};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{EventEmitter as r}from"node:events";class o extends r{buffer="";totalMarkdownContent="";getTotalContent(){return this.totalMarkdownContent.trim()}resetTotalContent(){this.totalMarkdownContent="",this.buffer=""}cleanMarkdown(t){return t.replace(/\n{3,}/g,`
|
|
2
|
+
|
|
3
|
+
`).replace(/ {2,}/g," ").trim()}isPureJson(t){const e=t.trim();return e.startsWith("{")&&e.endsWith("}")&&e.includes('"type"')}static cleanTextForDisplay(t){return t}}export{o as BaseResponseParser};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import{BaseResponseParser as i}from"./base-parser";class c extends i{static cleanTextForDisplay(e){let t=e;return t=t.replace(/\{\s*"type"\s*:\s*"(echarts|recharts|eui|markdown)"\s*,[\s\S]*?\}/gs,""),t=t.replace(/\n\s*Comment:\s*[^\n]*/g,""),t=t.replace(/^\s*\{\s*$/gm,""),t=t.replace(/^\s*\}\s*$/gm,""),t=t.replace(/\n{3,}/g,`
|
|
2
|
+
|
|
3
|
+
`).trim(),t}inMarkdownBody=!1;bodyStart=!1;markdownBuffer="";braceCount=0;inJsonBlock=!1;lastStreamTime=0;introPatterns=[/^Here\s+is\s+the\s+detailed\s+information\s+about/i,/^I'?ll\s+help\s+you\s+with/i,/^Let\s+me\s+analyze/i,/^Based\s+on\s+the\s+data/i,/^I'?ve\s+fetched/i,/^I'?ve\s+gathered/i,/^Here'?s\s+what\s+I\s+found/i,/^The\s+information\s+shows/i];processChunk(e){this.buffer+=e;const t=this.buffer.match(/\{"type"\s*:\s*"markdown"/),r=this.buffer.includes('{"type"')&&this.buffer.includes('"markdown"');if((t||r)&&!this.inJsonBlock&&(this.inJsonBlock=!0,this.braceCount=1),this.inJsonBlock){const s=(e.match(/\{/g)||[]).length,n=(e.match(/\}/g)||[]).length;this.braceCount+=s-n,this.inMarkdownBody||this.buffer.match(/"body"\s*:\s*"/)&&(this.inMarkdownBody=!0,this.bodyStart=!0,this.markdownBuffer=""),this.inMarkdownBody&&this.extractMarkdownFromChunk(e),this.braceCount===0&&this.inJsonBlock&&this.resetState()}}extractMarkdownFromChunk(e){if(!this.inMarkdownBody)return;let t=-1,r=0;for(;r<e.length;){const s=e[r];if(this.bodyStart){this.bodyStart=!1,r++;continue}if(s==='"'&&r>0&&e[r-1]!=="\\"&&e.slice(r+1,r+3).match(/^[\s,}]/)){t=r;break}this.markdownBuffer+=s,r++}if(this.markdownBuffer.length>100||Date.now()-this.lastStreamTime>200){const s=this.cleanMarkdownForStreaming(this.markdownBuffer);console.log("[GeminiParser] Streaming markdown chunk:",s.length,"chars:",s.slice(0,50),"..."),s.trim()&&(this.emit("markdownChunk",s),this.lastStreamTime=Date.now()),this.markdownBuffer=""}if(t>=0){if(console.log("[GeminiParser] End of markdown body, final buffer:",this.markdownBuffer.length,"chars"),this.markdownBuffer.trim()){const s=this.cleanMarkdownForStreaming(this.markdownBuffer);s.trim()&&this.emit("markdownChunk",s)}this.inMarkdownBody=!1,this.markdownBuffer=""}}resetState(){if(this.inJsonBlock=!1,this.inMarkdownBody=!1,this.bodyStart=!1,this.braceCount=0,this.buffer="",this.lastStreamTime=0,this.markdownBuffer.trim()){const e=this.cleanMarkdownForStreaming(this.markdownBuffer);e.trim()&&this.emit("markdownChunk",e),this.markdownBuffer=""}}complete(){if(this.markdownBuffer.trim()){const e=this.cleanMarkdownForStreaming(this.markdownBuffer);e.trim()&&this.emit("markdownChunk",e)}this.resetState()}getTotalContent(){let e=this.totalMarkdownContent;return e=e.replace(/```json\s*/gi,""),e=e.replace(/```\s*/g,""),e=e.replace(/^json\s*$/gim,""),e=e.replace(/\{\s*"type"\s*:\s*"[^"]+"\s*,[\s\S]*?\}/g,""),e=e.replace(/^\s*\{\s*$/gm,""),e=e.replace(/^\s*\}\s*$/gm,""),e=e.replace(/\n{3,}/g,`
|
|
4
|
+
|
|
5
|
+
`),e=e.replace(/^\s*\n/gm,`
|
|
6
|
+
`),e=e.replace(/ {2,}/g," "),e.trim()}cleanMarkdownForStreaming(e){const t=e.trim();return this.isPureJson(t)&&(t.includes('"echarts"')||t.includes('"eui"')||t.includes('"recharts"')||t.includes('"markdown"')&&t.includes('"options"'))?(console.warn("[GeminiParser] \u26A0\uFE0F Rejected pure JSON block in markdown stream:",t.substring(0,100)),""):e.replace(/\\"/g,'"').replace(/\\\\/g,"\\").replace(/^#{4,6}\s+/gm,"### ").replace(/\n{3,}/g,`
|
|
7
|
+
|
|
8
|
+
`).trim()}}export{c as GeminiParser};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{BaseResponseParser as u}from"./base-parser";import{AnthropicParser as d}from"./anthropic-parser";import{GeminiParser as w}from"./gemini-parser";import{AnthropicParser as e}from"./anthropic-parser";import{GeminiParser as a}from"./gemini-parser";function p(r){const o=r?.toLowerCase()||"anthropic";switch(console.log(`[ParserFactory] Creating parser for provider: ${o}`),o){case"google":case"gemini":return new a;case"anthropic":case"claude":return new e;case"openai":case"gpt":return new e;default:return console.warn(`[ParserFactory] Unknown provider "${o}", using Anthropic parser as fallback`),new e}}function l(r,o){switch(o?.toLowerCase()||"anthropic"){case"google":case"gemini":return a.cleanTextForDisplay(r);case"anthropic":case"claude":return e.cleanTextForDisplay(r);case"openai":case"gpt":return e.cleanTextForDisplay(r);default:return e.cleanTextForDisplay(r)}}export{d as AnthropicParser,u as BaseResponseParser,w as GeminiParser,l as cleanTextForProvider,p as createParser};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{parse as i,Allow as c}from"partial-json";function p(s){let e=s;const r=s.length;e=e.replace(/([,\{:]\s*)\\"/g,'$1"'),e=e.replace(/\\"(\s*:)/g,'"$1');const o=r-e.length;return o>0&&console.log(`[WS] \u{1F527} Fixed ${o/2} escaped quotes in JSON`),e}function d(s){return s.map((e,r)=>{const o=e.trim();try{const t=JSON.parse(o);return console.log(`[WS] \u2705 Block ${r} parsed successfully:`,{type:t?.type,title:t?.title,hasBody:!!t?.body}),t}catch(t){try{const l=p(o),n=JSON.parse(l);return console.log(`[WS] \u2705 Block ${r} parsed after fixMalformedJson:`,{type:n?.type,title:n?.title,hasBody:!!n?.body}),n}catch{console.error(`[WS] \u274C Failed to parse block ${r}:`,t,o);const l=o.search(/[{\[]/);if(l===-1)return console.error(`[WS] \u274C Block ${r}: No JSON object/array start found, dropping.`),null;const n=o.slice(l);try{const a=i(n,c.OBJ|c.ARR|c.STR);return console.error(`[WS] \u26A0\uFE0F Block ${r} recovered via lenient parser:`,a),a}catch(a){return console.error(`[WS] \u274C Block ${r}: lenient parser also failed, dropping.`,a),null}}}}).filter(e=>e!==null)}export{d as parseJsonBlocks};
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{wsMessageToTraceEvent as u}from"../core/services/chat-traces-service";import{publishTraceEvent as f}from"../core/runtime/trace-bus";const a=256*1024,i=new Map;function m(e,t){i.set(e,t)}function v(e){i.delete(e)}function g(e,t){if(e.readyState!==e.OPEN)return Promise.resolve();const r=t;if(r?.runId){const o=u(r);if(o){const n=i.get(r.runId);n&&n(o),f(r.runId,o)}}const s=JSON.stringify(t),c=r?.type||"unknown";return e.bufferedAmount>a?(console.log(`[WS] \u23F3 Queueing ${c} message due to backpressure (buffered: ${e.bufferedAmount} bytes)`),new Promise(o=>{const n=setInterval(()=>{e.bufferedAmount<=a&&(clearInterval(n),console.log(`[WS] \u2705 Backpressure cleared, sending queued ${c} message`),e.send(s),o())},10)})):(console.log("[WS] ws.send(data)",JSON.stringify(s)),e.send(s),Promise.resolve())}function b(e){return e.readyState!==e.OPEN||e.bufferedAmount===0?Promise.resolve():(console.log(`[WS] \u{1F504} Waiting for buffer to drain (${e.bufferedAmount} bytes buffered)...`),new Promise(t=>{const r=setInterval(()=>{(e.bufferedAmount===0||e.readyState!==e.OPEN)&&(clearInterval(r),console.log("[WS] \u2705 Buffer drained, ready to send final messages"),t())},10)}))}export{m as registerRunTraceCollector,g as send,v as unregisterRunTraceCollector,b as waitForDrain};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// shared/engine-vars.ts
|
|
2
|
+
// Canonical list of {{...}} template variables a node's instructions/prompt
|
|
3
|
+
// field can reference (docs/GRAPH-NODE-TEMPLATE-VARS.md). Single source of
|
|
4
|
+
// truth for both server/graph/utils/engine-vars.ts's ENGINE_VAR_KEYS (which
|
|
5
|
+
// names interpolateEngineVars actually substitutes) and the frontend
|
|
6
|
+
// "Add variable" autocomplete (src/shared/components/AddVariableButton.tsx) —
|
|
7
|
+
// keeping these in one place prevents the two from drifting out of sync.
|
|
8
|
+
export interface EngineVarDef {
|
|
9
|
+
name: string;
|
|
10
|
+
description: string;
|
|
11
|
+
// false for entries resolved by a separate mechanism, not
|
|
12
|
+
// interpolateEngineVars itself — availableTools/availableResources are
|
|
13
|
+
// substituted via their own .replace() calls in code-executor/index.ts
|
|
14
|
+
// before interpolateEngineVars ever runs, so they must stay out of
|
|
15
|
+
// ENGINE_VAR_KEYS but still belong in the FE picker, since that's exactly
|
|
16
|
+
// where a user would look for them.
|
|
17
|
+
resolvedByEngineVars?: boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const ENGINE_VARS: EngineVarDef[] = [
|
|
21
|
+
{ name: "availableTools", description: "Names of the tools bound to this node (assistant_tool_executor only)", resolvedByEngineVars: false },
|
|
22
|
+
{ name: "availableResources", description: "Summary listing of the assistant's attached resources (resources_policy), or all owned .stkxp_resources KB entries if none are attached (code_executor only)", resolvedByEngineVars: false },
|
|
23
|
+
{ name: "threadId", description: "Current chat thread id" },
|
|
24
|
+
{ name: "userContext", description: "User-provided context" },
|
|
25
|
+
{ name: "topic", description: "Detected conversation topic" },
|
|
26
|
+
{ name: "context", description: "Assistant-level context" },
|
|
27
|
+
{ name: "compressionStats", description: "Chat history compression stats (JSON)" },
|
|
28
|
+
{ name: "entityTokenMap", description: "Extracted entity → token map (JSON)" },
|
|
29
|
+
{ name: "compareChatId", description: "Chat id being compared against" },
|
|
30
|
+
{ name: "enrichChatId", description: "Chat id being enriched" },
|
|
31
|
+
{ name: "last_tool_error", description: "Most recent tool error, if any" },
|
|
32
|
+
{ name: "namespaceMap", description: "Resolved namespace map (JSON)" },
|
|
33
|
+
{ name: "teamAssistantResults", description: "This team run's per-assistant results (JSON)" },
|
|
34
|
+
{ name: "teamAssistantResultsHistory", description: "Prior team runs' per-assistant results (JSON)" },
|
|
35
|
+
{ name: "selectedAssistantIds", description: "Assistant ids selected for this team run" },
|
|
36
|
+
{ name: "selectedTeamId", description: "Team id for this run" },
|
|
37
|
+
{ name: "teamRouterDecision", description: "team_router's routing decision (JSON)" },
|
|
38
|
+
{ name: "toolExecRounds", description: "Agentic-loop round counter" },
|
|
39
|
+
{ name: "toolsUsedAccum", description: "Tools used so far, accumulated" },
|
|
40
|
+
{ name: "systemPromptTools", description: "Prompt-optimizer's tool prompt channel" },
|
|
41
|
+
{ name: "systemPromptFinal", description: "Prompt-optimizer's final system prompt channel" },
|
|
42
|
+
{ name: "channel", description: "Delivery channel (web/slack/embed/…)" },
|
|
43
|
+
{ name: "codeExecTrace", description: "Prior code_executor tool-call trace" },
|
|
44
|
+
{ name: "codeExecScript", description: "Prior code_executor's generated script" },
|
|
45
|
+
{ name: "previousNodeOutput", description: "Preceding node's returned output (code_executor only)" },
|
|
46
|
+
{ name: "lastUserMessage", description: "The user's most recent chat message (code_executor only)" },
|
|
47
|
+
];
|
|
48
|
+
|
|
49
|
+
export const ENGINE_VAR_KEYS: ReadonlySet<string> = new Set(
|
|
50
|
+
ENGINE_VARS.filter((v) => v.resolvedByEngineVars !== false).map((v) => v.name)
|
|
51
|
+
);
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// shared/llm-providers-config.ts
|
|
2
|
+
// Shared LLM providers configuration used by both frontend and backend
|
|
3
|
+
|
|
4
|
+
export interface ProviderModelInfo {
|
|
5
|
+
label: string;
|
|
6
|
+
value: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface ProviderConfig {
|
|
10
|
+
id: string;
|
|
11
|
+
name: string;
|
|
12
|
+
icon: string;
|
|
13
|
+
endpoint: string;
|
|
14
|
+
models: ProviderModelInfo[];
|
|
15
|
+
defaultModel: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const LLM_PROVIDERS_CONFIG: Record<string, ProviderConfig> = {
|
|
19
|
+
openai: {
|
|
20
|
+
id: "openai",
|
|
21
|
+
name: "OpenAI",
|
|
22
|
+
icon: "compute",
|
|
23
|
+
endpoint: "https://api.openai.com/v1",
|
|
24
|
+
models: [
|
|
25
|
+
{ label: "GPT-4o", value: "gpt-4o" },
|
|
26
|
+
{ label: "GPT-4o Mini", value: "gpt-4o-mini" },
|
|
27
|
+
{ label: "GPT-4 Turbo", value: "gpt-4-turbo" },
|
|
28
|
+
{ label: "GPT-3.5 Turbo", value: "gpt-3.5-turbo" },
|
|
29
|
+
],
|
|
30
|
+
defaultModel: "gpt-4o",
|
|
31
|
+
},
|
|
32
|
+
anthropic: {
|
|
33
|
+
id: "anthropic",
|
|
34
|
+
name: "Anthropic",
|
|
35
|
+
icon: "desktop",
|
|
36
|
+
endpoint: "https://api.anthropic.com/v1",
|
|
37
|
+
models: [
|
|
38
|
+
{ label: "Claude Sonnet 4.5", value: "claude-sonnet-4-5" },
|
|
39
|
+
{ label: "Claude Haiku 4.5", value: "claude-haiku-4-5" },
|
|
40
|
+
{ label: "Claude Opus 4.1", value: "claude-opus-4-1" },
|
|
41
|
+
{ label: "Claude Sonnet 3.7", value: "claude-3-7-sonnet-20250219" },
|
|
42
|
+
{ label: "Claude Haiku 3.5", value: "claude-3-5-haiku-20241022" },
|
|
43
|
+
],
|
|
44
|
+
defaultModel: "claude-sonnet-4-5",
|
|
45
|
+
},
|
|
46
|
+
google: {
|
|
47
|
+
id: "google",
|
|
48
|
+
name: "Google Gemini",
|
|
49
|
+
icon: "logoGoogleG",
|
|
50
|
+
endpoint: "https://generativelanguage.googleapis.com/v1",
|
|
51
|
+
models: [
|
|
52
|
+
{ label: "Gemini 2.0 Flash", value: "gemini-2.0-flash-exp" },
|
|
53
|
+
{ label: "Gemini 1.5 Pro", value: "gemini-1.5-pro" },
|
|
54
|
+
{ label: "Gemini 1.5 Flash", value: "gemini-1.5-flash" },
|
|
55
|
+
],
|
|
56
|
+
defaultModel: "gemini-2.0-flash-exp",
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// Helper to get model values as array for backend
|
|
61
|
+
export function getProviderModels(providerId: string): string[] {
|
|
62
|
+
const config = LLM_PROVIDERS_CONFIG[providerId];
|
|
63
|
+
return config ? config.models.map((m) => m.value) : [];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Helper to get all available providers
|
|
67
|
+
export function getAllProviders(): ProviderConfig[] {
|
|
68
|
+
return Object.values(LLM_PROVIDERS_CONFIG);
|
|
69
|
+
}
|