flujo-ai 3.44.0 → 3.45.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/BUILD_ID +1 -1
- package/.next/app-path-routes-manifest.json +7 -7
- package/.next/build-manifest.json +3 -3
- package/.next/react-loadable-manifest.json +1 -1
- package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.rsc +2 -2
- package/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/api/approvals/[id]/route.js +1 -1
- package/.next/server/app/api/approvals/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/approvals/route.js +1 -1
- package/.next/server/app/api/approvals/route.js.nft.json +1 -1
- package/.next/server/app/api/backup/route.js.nft.json +1 -1
- package/.next/server/app/api/bugs/enhance/route.js +1 -1
- package/.next/server/app/api/bugs/enhance/route.js.nft.json +1 -1
- package/.next/server/app/api/encryption/secure/route.js +1 -1
- package/.next/server/app/api/encryption/secure/route.js.nft.json +1 -1
- package/.next/server/app/api/flow/[id]/convert-process-to-subflow/route.js.nft.json +1 -1
- package/.next/server/app/api/flow/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/flow/[id]/versions/[versionId]/route.js.nft.json +1 -1
- package/.next/server/app/api/flow/[id]/versions/route.js.nft.json +1 -1
- package/.next/server/app/api/flow/assist/route.js +1 -1
- package/.next/server/app/api/flow/assist/route.js.nft.json +1 -1
- package/.next/server/app/api/flow/compile/route.js +1 -1
- package/.next/server/app/api/flow/compile/route.js.nft.json +1 -1
- package/.next/server/app/api/flow/generate/route.js +1 -1
- package/.next/server/app/api/flow/generate/route.js.nft.json +1 -1
- package/.next/server/app/api/flow/generate/visual/route.js +2 -2
- package/.next/server/app/api/flow/generate/visual/route.js.nft.json +1 -1
- package/.next/server/app/api/flow/generator/route.js +1 -1
- package/.next/server/app/api/flow/generator/route.js.nft.json +1 -1
- package/.next/server/app/api/flow/improve/route.js +1 -1
- package/.next/server/app/api/flow/improve/route.js.nft.json +1 -1
- package/.next/server/app/api/flow/prompt-renderer/route.js +1 -1
- package/.next/server/app/api/flow/prompt-renderer/route.js.nft.json +1 -1
- package/.next/server/app/api/flow/quick-chat/route.js +1 -1
- package/.next/server/app/api/flow/quick-chat/route.js.nft.json +1 -1
- package/.next/server/app/api/flow/repair/route.js +1 -1
- package/.next/server/app/api/flow/repair/route.js.nft.json +1 -1
- package/.next/server/app/api/flow/route.js.nft.json +1 -1
- package/.next/server/app/api/init/route.js +1 -1
- package/.next/server/app/api/init/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/app-consent/route.js +1 -1
- package/.next/server/app/api/mcp/app-consent/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/app-sandbox/route.js +2 -2
- package/.next/server/app/api/mcp/app-sandbox/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/assistant/route.js +1 -1
- package/.next/server/app/api/mcp/assistant/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/cancel/route.js +1 -1
- package/.next/server/app/api/mcp/cancel/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/flujo/authoring/route.js +1 -1
- package/.next/server/app/api/mcp/flujo/authoring/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/flujo/automation/route.js +1 -1
- package/.next/server/app/api/mcp/flujo/automation/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/flujo/flows/route.js +1 -1
- package/.next/server/app/api/mcp/flujo/flows/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/flujo/resources/read/route.js +1 -1
- package/.next/server/app/api/mcp/flujo/resources/read/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/flujo/resources/route.js +1 -1
- package/.next/server/app/api/mcp/flujo/resources/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/flujo/servers/route.js +1 -1
- package/.next/server/app/api/mcp/flujo/servers/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/flujo/state/route.js +1 -1
- package/.next/server/app/api/mcp/flujo/state/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/flujo/tools/route.js +1 -1
- package/.next/server/app/api/mcp/flujo/tools/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/oauth-capability/route.js +1 -1
- package/.next/server/app/api/mcp/oauth-capability/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/servers/[name]/prompts/get/route.js +1 -1
- package/.next/server/app/api/mcp/servers/[name]/prompts/get/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/servers/[name]/prompts/route.js +1 -1
- package/.next/server/app/api/mcp/servers/[name]/prompts/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/servers/[name]/resources/read/route.js +1 -1
- package/.next/server/app/api/mcp/servers/[name]/resources/read/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/servers/[name]/resources/route.js +1 -1
- package/.next/server/app/api/mcp/servers/[name]/resources/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/servers/[name]/route.js +1 -1
- package/.next/server/app/api/mcp/servers/[name]/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/servers/[name]/status/route.js +1 -1
- package/.next/server/app/api/mcp/servers/[name]/status/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/servers/[name]/stdio-oauth/confirm/route.js +1 -1
- package/.next/server/app/api/mcp/servers/[name]/stdio-oauth/confirm/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/servers/[name]/stdio-oauth/start/route.js +1 -1
- package/.next/server/app/api/mcp/servers/[name]/stdio-oauth/start/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/servers/[name]/tools/[toolName]/route.js +1 -1
- package/.next/server/app/api/mcp/servers/[name]/tools/[toolName]/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/servers/[name]/tools/route.js +1 -1
- package/.next/server/app/api/mcp/servers/[name]/tools/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/servers/route.js +1 -1
- package/.next/server/app/api/mcp/servers/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/test-connection/route.js +1 -1
- package/.next/server/app/api/mcp/test-connection/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/test-connection/stream/route.js +1 -1
- package/.next/server/app/api/mcp/test-connection/stream/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp-registry/route.js +1 -1
- package/.next/server/app/api/mcp-registry/route.js.nft.json +1 -1
- package/.next/server/app/api/model/[id]/route.js +1 -1
- package/.next/server/app/api/model/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/model/provider/route.js +1 -1
- package/.next/server/app/api/model/provider/route.js.nft.json +1 -1
- package/.next/server/app/api/model/route.js +1 -1
- package/.next/server/app/api/model/route.js.nft.json +1 -1
- package/.next/server/app/api/model/test/route.js +1 -1
- package/.next/server/app/api/model/test/route.js.nft.json +1 -1
- package/.next/server/app/api/oauth/reset/route.js +1 -1
- package/.next/server/app/api/oauth/reset/route.js.nft.json +1 -1
- package/.next/server/app/api/packages/build/route.js.nft.json +1 -1
- package/.next/server/app/api/packages/derive-secrets/route.js.nft.json +1 -1
- package/.next/server/app/api/packages/install/route.js +1 -1
- package/.next/server/app/api/packages/install/route.js.nft.json +1 -1
- package/.next/server/app/api/packages/install/status/route.js +1 -1
- package/.next/server/app/api/packages/install/status/route.js.nft.json +1 -1
- package/.next/server/app/api/packages/installed/route.js +1 -1
- package/.next/server/app/api/packages/installed/route.js.nft.json +1 -1
- package/.next/server/app/api/packages/resolve/route.js.nft.json +1 -1
- package/.next/server/app/api/packages/scan-targets/route.js.nft.json +1 -1
- package/.next/server/app/api/packages/uninstall/route.js +1 -1
- package/.next/server/app/api/packages/uninstall/route.js.nft.json +1 -1
- package/.next/server/app/api/planned-executions/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/planned-executions/[id]/run/route.js.nft.json +1 -1
- package/.next/server/app/api/planned-executions/[id]/runs/route.js.nft.json +1 -1
- package/.next/server/app/api/planned-executions/reconcile/route.js +1 -1
- package/.next/server/app/api/planned-executions/reconcile/route.js.nft.json +1 -1
- package/.next/server/app/api/planned-executions/route.js +1 -1
- package/.next/server/app/api/planned-executions/route.js.nft.json +1 -1
- package/.next/server/app/api/restore/route.js.nft.json +1 -1
- package/.next/server/app/api/runs/active/route.js +1 -1
- package/.next/server/app/api/runs/active/route.js.nft.json +1 -1
- package/.next/server/app/api/telemetry/daily-active/route.js +1 -1
- package/.next/server/app/api/waves/route.js +1 -1
- package/.next/server/app/api/waves/route.js.nft.json +1 -1
- package/.next/server/app/api/webhooks/[id]/route.js +1 -1
- package/.next/server/app/api/webhooks/[id]/route.js.nft.json +1 -1
- package/.next/server/app/automation/triggers/page_client-reference-manifest.js +1 -1
- package/.next/server/app/automation/triggers.html +1 -1
- package/.next/server/app/automation/triggers.rsc +3 -3
- package/.next/server/app/automation/triggers.segments/_full.segment.rsc +3 -3
- package/.next/server/app/automation/triggers.segments/_head.segment.rsc +1 -1
- package/.next/server/app/automation/triggers.segments/_index.segment.rsc +2 -2
- package/.next/server/app/automation/triggers.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/automation/triggers.segments/automation/triggers/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/automation/triggers.segments/automation/triggers.segment.rsc +1 -1
- package/.next/server/app/automation/triggers.segments/automation.segment.rsc +1 -1
- package/.next/server/app/automation/waves/page_client-reference-manifest.js +1 -1
- package/.next/server/app/automation/waves.html +1 -1
- package/.next/server/app/automation/waves.rsc +3 -3
- package/.next/server/app/automation/waves.segments/_full.segment.rsc +3 -3
- package/.next/server/app/automation/waves.segments/_head.segment.rsc +1 -1
- package/.next/server/app/automation/waves.segments/_index.segment.rsc +2 -2
- package/.next/server/app/automation/waves.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/automation/waves.segments/automation/waves/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/automation/waves.segments/automation/waves.segment.rsc +1 -1
- package/.next/server/app/automation/waves.segments/automation.segment.rsc +1 -1
- package/.next/server/app/chain-chat/page_client-reference-manifest.js +1 -1
- package/.next/server/app/chain-chat.html +1 -1
- package/.next/server/app/chain-chat.rsc +3 -3
- package/.next/server/app/chain-chat.segments/_full.segment.rsc +3 -3
- package/.next/server/app/chain-chat.segments/_head.segment.rsc +1 -1
- package/.next/server/app/chain-chat.segments/_index.segment.rsc +2 -2
- package/.next/server/app/chain-chat.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/chain-chat.segments/chain-chat/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/chain-chat.segments/chain-chat.segment.rsc +1 -1
- package/.next/server/app/chat/page.js +4 -4
- package/.next/server/app/chat/page.js.nft.json +1 -1
- package/.next/server/app/chat/page_client-reference-manifest.js +1 -1
- package/.next/server/app/chat.html +1 -1
- package/.next/server/app/chat.rsc +3 -3
- package/.next/server/app/chat.segments/_full.segment.rsc +3 -3
- package/.next/server/app/chat.segments/_head.segment.rsc +1 -1
- package/.next/server/app/chat.segments/_index.segment.rsc +2 -2
- package/.next/server/app/chat.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/chat.segments/chat/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/chat.segments/chat.segment.rsc +1 -1
- package/.next/server/app/docs/page_client-reference-manifest.js +1 -1
- package/.next/server/app/docs.html +1 -1
- package/.next/server/app/docs.rsc +3 -3
- package/.next/server/app/docs.segments/_full.segment.rsc +3 -3
- package/.next/server/app/docs.segments/_head.segment.rsc +1 -1
- package/.next/server/app/docs.segments/_index.segment.rsc +2 -2
- package/.next/server/app/docs.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/docs.segments/docs/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/docs.segments/docs.segment.rsc +1 -1
- package/.next/server/app/executions/page_client-reference-manifest.js +1 -1
- package/.next/server/app/executions.html +1 -1
- package/.next/server/app/executions.rsc +3 -3
- package/.next/server/app/executions.segments/_full.segment.rsc +3 -3
- package/.next/server/app/executions.segments/_head.segment.rsc +1 -1
- package/.next/server/app/executions.segments/_index.segment.rsc +2 -2
- package/.next/server/app/executions.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/executions.segments/executions/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/executions.segments/executions.segment.rsc +1 -1
- package/.next/server/app/flows/page.js +5 -5
- package/.next/server/app/flows/page.js.nft.json +1 -1
- package/.next/server/app/flows/page_client-reference-manifest.js +1 -1
- package/.next/server/app/flows.html +1 -1
- package/.next/server/app/flows.rsc +3 -3
- package/.next/server/app/flows.segments/_full.segment.rsc +3 -3
- package/.next/server/app/flows.segments/_head.segment.rsc +1 -1
- package/.next/server/app/flows.segments/_index.segment.rsc +2 -2
- package/.next/server/app/flows.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/flows.segments/flows/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/flows.segments/flows.segment.rsc +1 -1
- package/.next/server/app/index.html +1 -1
- package/.next/server/app/index.rsc +3 -3
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/index.segments/_full.segment.rsc +3 -3
- package/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/.next/server/app/index.segments/_index.segment.rsc +2 -2
- package/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/mcp/page.js +1 -1
- package/.next/server/app/mcp/page_client-reference-manifest.js +1 -1
- package/.next/server/app/mcp-flows/route.js +1 -1
- package/.next/server/app/mcp-flows/route.js.nft.json +1 -1
- package/.next/server/app/mcp-proxy/[server]/route.js +1 -1
- package/.next/server/app/mcp-proxy/[server]/route.js.nft.json +1 -1
- package/.next/server/app/mcp.html +1 -1
- package/.next/server/app/mcp.rsc +3 -3
- package/.next/server/app/mcp.segments/_full.segment.rsc +3 -3
- package/.next/server/app/mcp.segments/_head.segment.rsc +1 -1
- package/.next/server/app/mcp.segments/_index.segment.rsc +2 -2
- package/.next/server/app/mcp.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/mcp.segments/mcp/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/mcp.segments/mcp.segment.rsc +1 -1
- package/.next/server/app/meetings/page_client-reference-manifest.js +1 -1
- package/.next/server/app/meetings.html +1 -1
- package/.next/server/app/meetings.rsc +3 -3
- package/.next/server/app/meetings.segments/_full.segment.rsc +3 -3
- package/.next/server/app/meetings.segments/_head.segment.rsc +1 -1
- package/.next/server/app/meetings.segments/_index.segment.rsc +2 -2
- package/.next/server/app/meetings.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/meetings.segments/meetings/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/meetings.segments/meetings.segment.rsc +1 -1
- package/.next/server/app/models/page.js +3 -3
- package/.next/server/app/models/page_client-reference-manifest.js +1 -1
- package/.next/server/app/packages/page_client-reference-manifest.js +1 -1
- package/.next/server/app/packages.html +1 -1
- package/.next/server/app/packages.rsc +3 -3
- package/.next/server/app/packages.segments/_full.segment.rsc +3 -3
- package/.next/server/app/packages.segments/_head.segment.rsc +1 -1
- package/.next/server/app/packages.segments/_index.segment.rsc +2 -2
- package/.next/server/app/packages.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/packages.segments/packages/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/packages.segments/packages.segment.rsc +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/settings/page.js +2 -2
- package/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/server/app/settings.html +1 -1
- package/.next/server/app/settings.rsc +3 -3
- package/.next/server/app/settings.segments/_full.segment.rsc +3 -3
- package/.next/server/app/settings.segments/_head.segment.rsc +1 -1
- package/.next/server/app/settings.segments/_index.segment.rsc +2 -2
- package/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/settings.segments/settings.segment.rsc +1 -1
- package/.next/server/app/statistics/page_client-reference-manifest.js +1 -1
- package/.next/server/app/statistics.html +1 -1
- package/.next/server/app/statistics.rsc +3 -3
- package/.next/server/app/statistics.segments/_full.segment.rsc +3 -3
- package/.next/server/app/statistics.segments/_head.segment.rsc +1 -1
- package/.next/server/app/statistics.segments/_index.segment.rsc +2 -2
- package/.next/server/app/statistics.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/statistics.segments/statistics/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/statistics.segments/statistics.segment.rsc +1 -1
- package/.next/server/app/v1/chat/completions/route.js +1 -1
- package/.next/server/app/v1/chat/completions/route.js.nft.json +1 -1
- package/.next/server/app/v1/chat/conversation-chains/route.js +1 -1
- package/.next/server/app/v1/chat/conversation-chains/route.js.nft.json +1 -1
- package/.next/server/app/v1/chat/conversations/[conversationId]/breakpoints/route.js +1 -1
- package/.next/server/app/v1/chat/conversations/[conversationId]/breakpoints/route.js.nft.json +1 -1
- package/.next/server/app/v1/chat/conversations/[conversationId]/cancel/route.js +1 -1
- package/.next/server/app/v1/chat/conversations/[conversationId]/cancel/route.js.nft.json +1 -1
- package/.next/server/app/v1/chat/conversations/[conversationId]/debug/attach/route.js +1 -1
- package/.next/server/app/v1/chat/conversations/[conversationId]/debug/attach/route.js.nft.json +1 -1
- package/.next/server/app/v1/chat/conversations/[conversationId]/debug/continue/route.js +1 -1
- package/.next/server/app/v1/chat/conversations/[conversationId]/debug/continue/route.js.nft.json +1 -1
- package/.next/server/app/v1/chat/conversations/[conversationId]/debug/state/route.js +1 -1
- package/.next/server/app/v1/chat/conversations/[conversationId]/debug/state/route.js.nft.json +1 -1
- package/.next/server/app/v1/chat/conversations/[conversationId]/debug/step/route.js +1 -1
- package/.next/server/app/v1/chat/conversations/[conversationId]/debug/step/route.js.nft.json +1 -1
- package/.next/server/app/v1/chat/conversations/[conversationId]/edit-state/route.js +1 -1
- package/.next/server/app/v1/chat/conversations/[conversationId]/edit-state/route.js.nft.json +1 -1
- package/.next/server/app/v1/chat/conversations/[conversationId]/events/route.js +1 -1
- package/.next/server/app/v1/chat/conversations/[conversationId]/events/route.js.nft.json +1 -1
- package/.next/server/app/v1/chat/conversations/[conversationId]/inject/route.js +1 -1
- package/.next/server/app/v1/chat/conversations/[conversationId]/inject/route.js.nft.json +1 -1
- package/.next/server/app/v1/chat/conversations/[conversationId]/recovery/route.js +1 -1
- package/.next/server/app/v1/chat/conversations/[conversationId]/recovery/route.js.nft.json +1 -1
- package/.next/server/app/v1/chat/conversations/[conversationId]/respond/route.js +1 -1
- package/.next/server/app/v1/chat/conversations/[conversationId]/respond/route.js.nft.json +1 -1
- package/.next/server/app/v1/chat/conversations/[conversationId]/revert/route.js +1 -1
- package/.next/server/app/v1/chat/conversations/[conversationId]/revert/route.js.nft.json +1 -1
- package/.next/server/app/v1/chat/conversations/[conversationId]/route.js +1 -1
- package/.next/server/app/v1/chat/conversations/[conversationId]/route.js.nft.json +1 -1
- package/.next/server/app/v1/chat/conversations/route.js +1 -1
- package/.next/server/app/v1/chat/conversations/route.js.nft.json +1 -1
- package/.next/server/app/v1/chat/events/route.js +1 -1
- package/.next/server/app/v1/chat/events/route.js.nft.json +1 -1
- package/.next/server/app/v1/meetings/[meetingId]/cancel/route.js +1 -1
- package/.next/server/app/v1/meetings/[meetingId]/cancel/route.js.nft.json +1 -1
- package/.next/server/app/v1/meetings/[meetingId]/route.js +1 -1
- package/.next/server/app/v1/meetings/[meetingId]/route.js.nft.json +1 -1
- package/.next/server/app/v1/meetings/[meetingId]/start/route.js +1 -1
- package/.next/server/app/v1/meetings/[meetingId]/start/route.js.nft.json +1 -1
- package/.next/server/app/v1/meetings/route.js +1 -1
- package/.next/server/app/v1/meetings/route.js.nft.json +1 -1
- package/.next/server/app/v1/models/route.js +1 -1
- package/.next/server/app/v1/models/route.js.nft.json +1 -1
- package/.next/server/app/waves/page_client-reference-manifest.js +1 -1
- package/.next/server/app/waves.html +1 -1
- package/.next/server/app/waves.rsc +3 -3
- package/.next/server/app/waves.segments/_full.segment.rsc +3 -3
- package/.next/server/app/waves.segments/_head.segment.rsc +1 -1
- package/.next/server/app/waves.segments/_index.segment.rsc +2 -2
- package/.next/server/app/waves.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/waves.segments/waves/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/waves.segments/waves.segment.rsc +1 -1
- package/.next/server/app-paths-manifest.json +7 -7
- package/.next/server/chunks/1114.js +1 -1
- package/.next/server/chunks/{4271.js → 2126.js} +13 -13
- package/.next/server/chunks/2425.js +1 -1
- package/.next/server/chunks/244.js +1 -1
- package/.next/server/chunks/2728.js +1 -1
- package/.next/server/chunks/2970.js +1 -1
- package/.next/server/chunks/3133.js +2 -2
- package/.next/server/chunks/4558.js +1 -1
- package/.next/server/chunks/4779.js +1 -0
- package/.next/server/chunks/531.js +1 -1
- package/.next/server/chunks/5354.js +1 -1
- package/.next/server/chunks/5831.js +1 -1
- package/.next/server/chunks/609.js +1 -1
- package/.next/server/chunks/75.js +1 -1
- package/.next/server/chunks/7513.js +1 -1
- package/.next/server/chunks/7754.js +60 -60
- package/.next/server/chunks/811.js +1 -1
- package/.next/server/chunks/8542.js +1 -1
- package/.next/server/chunks/87.js +1 -1
- package/.next/server/chunks/8767.js +1 -1
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.js +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/chunks/{8851-1ea4bbf9945c7b34.js → 2375-af6ebf80d9cb9975.js} +2 -2
- package/.next/static/chunks/{4742-e151939b0ae7ba74.js → 3841-0e4a10c621cac0e6.js} +1 -1
- package/.next/static/chunks/{5147-d239d0147237bb58.js → 5147-ec07dd70c20ec0b5.js} +1 -1
- package/.next/static/chunks/5212-898f308c44a32c22.js +2 -0
- package/.next/static/chunks/7401-cffc7c5fa1f5f06e.js +10 -0
- package/.next/static/chunks/app/chat/page-5b6d507b576cea9c.js +7 -0
- package/.next/static/chunks/app/flows/page-9b16d049d43ac817.js +9 -0
- package/.next/static/chunks/app/mcp/{page-70535f4bce57edbe.js → page-e4c284466c17fe32.js} +1 -1
- package/.next/static/chunks/app/models/page-2891efa80c126790.js +11 -0
- package/.next/static/chunks/{webpack-7efb2620f630c7d5.js → webpack-d9f1e56ee69d988f.js} +1 -1
- package/.next/trace +104 -104
- package/.next/trace-build +1 -1
- package/README.md +6 -3
- package/mcp-servers/bash/package.json +1 -1
- package/mcp-servers/browser/dist/resources.js +29 -3
- package/mcp-servers/browser/dist/resources.js.map +1 -1
- package/mcp-servers/browser/package.json +1 -1
- package/mcp-servers/filesystem/dist/resources.js +1 -1
- package/mcp-servers/filesystem/package.json +1 -1
- package/mcp-servers/flujo/package.json +1 -1
- package/package.json +5 -5
- package/.next/server/chunks/387.js +0 -1
- package/.next/static/chunks/5212-fa397222d5251b43.js +0 -2
- package/.next/static/chunks/7401-b0f0d4a7b2597302.js +0 -10
- package/.next/static/chunks/app/chat/page-3db891cc7ba29084.js +0 -7
- package/.next/static/chunks/app/flows/page-6b6748bc74604103.js +0 -9
- package/.next/static/chunks/app/models/page-e3430501cd05ff1f.js +0 -11
- /package/.next/static/{yjYCceqlIl4V9blcEb5AK → 4x_Vc1-WtJtqgqFZnCq3D}/_buildManifest.js +0 -0
- /package/.next/static/{yjYCceqlIl4V9blcEb5AK → 4x_Vc1-WtJtqgqFZnCq3D}/_ssgManifest.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";exports.id=4558,exports.ids=[4558],exports.modules={94558:(a,b,c)=>{let d;c.d(b,{PH:()=>P,LG:()=>W,aM:()=>U,a$:()=>S,Iz:()=>T,e3:()=>O});var e=c(66844),f=c(26790),g=c(76145),h=c(1930),i=c(65445);let j=(0,e.h)("backend/services/mcp/quality/cache"),k="mcp-quality-cache";class l{constructor(a=Date.now()){this.entries={},this.dirty=!1,this.now=a}async load(){try{let a=await (0,i.loadItem)(k,{entries:{}});this.entries=a?.entries&&"object"==typeof a.entries?a.entries:{}}catch(a){j.warn("Failed to load quality cache; starting empty",a),this.entries={}}}get(a,b){let c=this.entries[`${a}::${b}`];if(c&&!(this.now-c.at>864e5))return c.signal}set(a,b,c){this.entries[`${a}::${b}`]={at:this.now,signal:c},this.dirty=!0}async flush(){let a=!1;for(let[b,c]of Object.entries(this.entries))this.now-c.at>864e5&&(delete this.entries[b],a=!0);if(this.dirty||a)try{await (0,i.VH)(k,{entries:this.entries})}catch(a){j.warn("Failed to persist quality cache",a)}}}function m(a){return!Number.isFinite(a)||a<0?0:a>1?1:a}function n(a,b){return!Number.isFinite(a)||a<=0?0:!Number.isFinite(b)||b<=1?+(a>0):m(Math.log10(a+1)/Math.log10(b+1))}let o=(0,e.h)("backend/services/mcp/quality/providers/githubStars"),p="github",q=new Map;function r(){return d??(process.env.GITHUB_TOKEN||void 0)}function s(a){let b,c=a.server.repository;if(c?.source&&"github"!==c.source.toLowerCase())return null;var d=c?.url;if(!d)return null;try{b=new URL(d.replace(/^git\+/,""))}catch{return null}if(!/(^|\.)github\.com$/i.test(b.hostname))return null;let e=b.pathname.replace(/\.git$/i,"").split("/").filter(Boolean);return e.length<2?null:`${e[0]}/${e[1]}`.toLowerCase()}async function t(a,b){let c=new AbortController,d=()=>c.abort();b.addEventListener("abort",d,{once:!0});let e=setTimeout(()=>c.abort(),6e3);try{let b,d;return await fetch(`https://api.github.com${a}`,{headers:(b={Accept:"application/vnd.github+json","User-Agent":"FLUJO-mcp-quality","X-GitHub-Api-Version":"2022-11-28"},(d=r())&&(b.Authorization=`Bearer ${d}`),b),signal:c.signal,cache:"no-store"})}catch(b){return o.warn(`GitHub request failed (${a})`,b instanceof Error?b.message:b),null}finally{clearTimeout(e),b.removeEventListener("abort",d)}}function u(a){return(403===a.status||429===a.status)&&"0"===a.headers.get("x-ratelimit-remaining")}let v=(0,e.h)("backend/services/mcp/quality/providers/npmDownloads"),w="npm-downloads",x=new Map;function y(a){for(let b of a.server.packages??[])if("npm"===b.registryType&&b.identifier)return b.identifier;return null}function z(a){return a.startsWith("@")}async function A(a,b){let c=new AbortController,d=()=>c.abort();b.addEventListener("abort",d,{once:!0});let e=setTimeout(()=>c.abort(),6e3);try{return await fetch(`https://api.npmjs.org${a}`,{signal:c.signal,cache:"no-store"})}catch(b){return v.warn(`npm request failed (${a})`,b instanceof Error?b.message:b),null}finally{clearTimeout(e),b.removeEventListener("abort",d)}}let B="registry-status",C=[{id:p,label:"GitHub Stars & Activity",defaultWeight:.5,isApplicable:a=>null!==s(a),cacheKey:a=>s(a),async prefetch(a,b,c){let d=`${a??""} mcp`.trim(),e=`/search/repositories?q=${encodeURIComponent(d)}&sort=stars&order=desc&per_page=50`,f=await t(e,c);if(f&&f.ok)try{for(let a of(await f.json()).items??[])a.full_name&&q.set(a.full_name.toLowerCase(),{stars:"number"==typeof a.stargazers_count?a.stargazers_count:0,pushedAtMs:a.pushed_at?Date.parse(a.pushed_at):null})}catch(a){o.warn("Failed to parse GitHub search response",a)}else if(f&&u(f))return void o.warn("GitHub search rate-limited; ranking will degrade to other providers");if(!r())return;let g=3;for(let a of b){if(g<=0)break;let b=s(a);if(!b||q.has(b))continue;g-=1;let d=await t(`/repos/${b}`,c);if(d){if(u(d))break;if(d.ok)try{let a=await d.json();q.set(b,{stars:"number"==typeof a.stargazers_count?a.stargazers_count:0,pushedAtMs:a.pushed_at?Date.parse(a.pushed_at):null})}catch{}}}},async fetch(a){let b=s(a);if(!b)return null;let c=q.get(b);if(!c)return null;let d=n(c.stars,5e4),e=function(a,b,c=30,d=730){if(!a||!Number.isFinite(a))return 0;let e=(b-a)/864e5;return e<=c?1:e>=d?0:m(1-(e-c)/(d-c))}(c.pushedAtMs,Date.now());return{providerId:p,score:m(.7*d+.3*e),evidence:{repo:b,stars:c.stars,...c.pushedAtMs?{pushedAt:new Date(c.pushedAtMs).toISOString()}:{},starsScore:d,recencyScore:e}}}},{id:w,label:"npm Weekly Downloads",defaultWeight:.35,isApplicable:a=>null!==y(a),cacheKey:a=>y(a),async prefetch(a,b,c){let d=b.map(y).filter(a=>!!a&&!x.has(a)),e=d.filter(a=>!z(a)),f=d.filter(z);for(let a=0;a<e.length;a+=100){let b=e.slice(a,a+100),d=await A(`/downloads/point/last-week/${b.join(",")}`,c);if(d&&d.ok)try{let a=await d.json();if(1===b.length)"number"==typeof a.downloads&&x.set(b[0],a.downloads);else for(let c of b){let b=a[c];x.set(c,b&&"number"==typeof b.downloads?b.downloads:0)}}catch(a){v.warn("Failed to parse npm bulk downloads response",a)}}for(let a of f){let b=await A(`/downloads/point/last-week/${a}`,c);if(b&&b.ok)try{let c=await b.json();"number"==typeof c.downloads&&x.set(a,c.downloads)}catch{}}},async fetch(a){let b=y(a);if(!b)return null;let c=x.get(b);return void 0===c?null:{providerId:w,score:n(c,1e6),evidence:{package:b,weeklyDownloads:c}}}},{id:B,label:"Registry Status",defaultWeight:.15,isApplicable:a=>!0,cacheKey:()=>null,fetch:async a=>({providerId:B,score:+("active"===a.verificationStatus),evidence:{status:a.verificationStatus}})}];var D=c(74755);let E=(0,e.h)("backend/services/mcp/quality/settings");function F(){return{providers:C.map(a=>({id:a.id,enabled:!0,weight:a.defaultWeight})),minScore:0,worksGate:!0}}async function G(){try{let a=await (0,i.loadItem)(D.Zg.MCP_QUALITY_SETTINGS,F());return function(a){var b,c;let d=F(),e=a??{},f=new Map;if(Array.isArray(e.providers))for(let a of e.providers)a&&"string"==typeof a.id&&f.set(a.id,a);return{providers:d.providers.map(a=>{let b=f.get(a.id);return{id:a.id,enabled:"boolean"==typeof b?.enabled?b.enabled:a.enabled,weight:"number"==typeof b?.weight&&Number.isFinite(b.weight)&&b.weight>=0?b.weight:a.weight}}),minScore:(b=e.minScore,c=d.minScore,"number"==typeof b&&Number.isFinite(b)?Math.min(1,Math.max(0,b)):c),worksGate:"boolean"==typeof e.worksGate?e.worksGate:d.worksGate,..."string"==typeof e.githubToken&&e.githubToken.length>0?{githubToken:e.githubToken}:{}}}(a)}catch(a){return E.warn("Failed to load mcpQuality settings; using defaults",a),F()}}let H=(0,e.h)("backend/services/mcp/quality/orchestrator");async function I(a,b){let c=new AbortController,d=setTimeout(()=>c.abort(),b);try{return await a(c.signal)}finally{clearTimeout(d)}}async function J(a,b,c={}){let e=c.topN??10;try{var f;let g=c.settings??await G(),h=C.filter(a=>{var b;let c;return b=a.id,c=g.providers.find(a=>a.id===b),!!c?.enabled});if(0===h.length)return b.map(a=>({candidate:a,score:0,signals:[]}));d=(f=g.githubToken)&&f.length>0?f:void 0;let i=b.slice(0,e),j=b.slice(e),k=new l(c.now??Date.now());await k.load();let n=i.map(()=>[]);for(let b of h){let c=i.map((a,b)=>({c:a,i:b})).filter(({c:a})=>b.isApplicable(a)),d=[],e=[];for(let a of c){let c=b.cacheKey(a.c);if(c){let d=k.get(b.id,c);if(d){e.push({i:a.i,signal:d});continue}}d.push(a)}if(b.prefetch&&d.length>0)try{await I(c=>b.prefetch(a,d.map(a=>a.c),c),12e3)}catch(a){H.warn(`Provider "${b.id}" prefetch failed; degrading`,a)}for(let{c:a,i:c}of d)try{let d=await I(c=>b.fetch(a,c),2e3);if(d){n[c].push(d);let e=b.cacheKey(a);e&&k.set(b.id,e,d)}}catch(c){H.warn(`Provider "${b.id}" fetch failed for "${a.registryName}"`,c)}for(let{i:a,signal:b}of e)n[a].push(b)}await k.flush();let o=i.map((a,b)=>{let c=n[b],d=new Map(c.map(a=>[a.providerId,a])),e=h.filter(b=>b.isApplicable(a)).map(a=>{var b;let c;return{providerId:a.id,weight:(b=a.id,(c=g.providers.find(a=>a.id===b))&&c.enabled?c.weight:0),score:d.get(a.id)?.score??0}}),{score:f}=function(a){let b=0,c=0;for(let d of a){let a=Number.isFinite(d.weight)&&d.weight>0?d.weight:0,e=m(d.score);b+=a,c+=a*e}return{score:b>0?c/b:0,breakdown:a}}(e);return{candidate:a,score:f,signals:c}}).map((a,b)=>({s:a,idx:b})).sort((a,b)=>b.s.score-a.s.score||a.idx-b.idx).map(a=>a.s),p=j.map(a=>({candidate:a,score:0,signals:[]}));return[...o,...p]}catch(a){return H.warn("enrichAndRank failed; returning unranked candidates",a),b.map(a=>({candidate:a,score:0,signals:[]}))}}let K=(0,e.h)("backend/services/mcp/registryInstall"),L="/v0.1/servers";function M(a){return{registryName:a.server.name,server:a.server,verificationStatus:(0,g.vf)(a)}}function N(a){let b=b=>a.signals.find(a=>a.providerId===b)?.evidence,c=b(p),d=b(w),e=b(B);return{score:a.score,..."number"==typeof c?.stars?{stars:c.stars}:{},..."number"==typeof d?.weeklyDownloads?{weeklyDownloads:d.weeklyDownloads}:{},..."string"==typeof e?.status?{status:e.status}:{}}}async function O(a,b=8){let c=await Q(a,b);return(await J(a,c.map(M))).map(a=>R(a.candidate.server,a))}async function P(a,b=8){if(!a||"string"!=typeof a)return[];let c=await Promise.all(V(a).map(a=>Q(a,10))),d=new Map;for(let a of c.flat())d.has(a.server.name)||d.set(a.server.name,a);return(await J(a,[...d.values()].map(M))).slice(0,Math.min(Math.max(b,1),30)).map(a=>R(a.candidate.server,a))}async function Q(a,b){let c=new URL(f.jD+L);c.searchParams.set("version","latest"),c.searchParams.set("limit",String(Math.min(Math.max(b,1),30))),a&&c.searchParams.set("search",a);let d=await (0,f.Ws)(c,15e3);return Array.isArray(d?.servers)?d.servers:[]}function R(a,b){let c=(0,g.AH)(a).filter(g.P1),d=c[0];return{name:a.name,...a.title?{title:a.title}:{},...a.description?{description:a.description}:{},installable:c.length>0,requiredEnv:d?(0,g.jg)(d):[],...b?{quality:N(b)}:{}}}async function S(a,b){try{let c=await J(a,b.map(M)),d=new Map(b.map(a=>[a.server.name,a])),e=[];for(let a of c){let b=d.get(a.candidate.server.name);b&&e.push(a.signals.length>0?{...b,quality:N(a)}:b)}return e.length===b.length?e:b}catch{return b}}async function T(a){let b=new URL(f.jD+L);b.searchParams.set("version","latest"),b.searchParams.set("limit","10"),b.searchParams.set("search",a);let c=await (0,f.Ws)(b,15e3);return(Array.isArray(c?.servers)?c.servers:[]).find(b=>b.server?.name===a)??null}async function U(a,b,c){var d;let e,f;if(!a||"string"!=typeof a)return{installed:!1,error:"A registry server name is required"};try{e=await T(a)}catch(a){return{installed:!1,error:`Registry lookup failed: ${a instanceof Error?a.message:String(a)}`}}let i=e?.server??null;if(!i)return{installed:!1,error:`No registry entry found for "${a}"`};let j=(0,g.AH)(i),k=j.filter(g.P1),l=function(a,b){if(!b)return a[0];let c=a.find(a=>("package"===a.kind?"stdio":"manual-launch"===a.kind?a.transport:"sse"===a.remote.type?"sse":"streamable")===b);return c||("stdio"!==b?a.find(a=>"remote"===a.kind)??a[0]:a.find(a=>"package"===a.kind)??a[0])}(k,c?.preferredTransport);if(!l)return{installed:!1,error:0===k.length&&j.length>0?`"${i.name}" must be started manually (it runs locally but speaks HTTP); add it from the MCP server dialog instead`:`"${i.name}" has no install method FLUJO supports (stdio package or HTTP remote)`};let m=c?.serverName;if(void 0!==m&&!/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$/.test(m))return{installed:!1,error:"The server name must be 1-64 characters and use only letters, numbers, hyphens, or underscores."};let n="remote"===l.kind&&c?.oauthDynamicClientRegistration===!0,o=a=>"authorization"===a.trim().toLocaleLowerCase(),p=(0,g.vf)(e),q=(0,g.O$)(a,i,l,p),r={...q,...m?{serverName:m}:{},...n?{requiredEnvNames:q.requiredEnvNames.filter(a=>!o(a))}:{}};if(c?.expectedPlan&&(d=c.expectedPlan,JSON.stringify((f=a=>({registryName:a.registryName,resolvedName:a.resolvedName,serverName:a.serverName,transport:a.transport,command:a.command,args:a.args,serverUrl:a.serverUrl,steps:a.steps,requiredEnvNames:a.requiredEnvNames,verificationStatus:a.verificationStatus}))(r))!==JSON.stringify(f(d))))return{installed:!1,serverName:r.serverName,plan:r,error:"The Registry install plan changed after it was reviewed and audited. Resolve and approve the new exact plan before installing."};if(c?.resolveOnly)return{installed:!1,serverName:r.serverName,plan:r};let s=Object.fromEntries(Object.entries(c?.headerOverrides??{}).filter(([a])=>!n||!o(a))),t=Object.fromEntries(Object.entries(s).map(([a,b])=>[a,"string"==typeof b?b:b.value])),u=(0,g.jg)(l,{...b,...t}).filter(a=>!n||!o(a));if(u.length>0)return{installed:!1,needsEnv:u,plan:r,error:`"${i.name}" requires values for: ${u.join(", ")}`};let v=(0,g.Yr)(i,l);if("launch"in v&&v.launch)return{installed:!1,plan:r,error:`"${i.name}" needs a locally launched process behind its HTTP endpoint, which FLUJO does not start yet. Add it from the MCP server dialog and start the process yourself.`};let w="headers"in v?v.headers:void 0,x=n?Object.fromEntries(Object.entries(w??{}).filter(([a])=>!o(a))):w,y={...v,...m?{name:m}:{},..."remote"===l.kind&&m?{rootPath:`mcp-servers/${m}`}:{},..."remote"===l.kind?{headers:x??{}}:{}},z="headers"in y?y.headers:void 0,A=function(a,b){if(!b?.length)return a;if("stdio"!==a.transport||!Array.isArray(a.args))return{error:"Package argument templates require a stdio registry server"};let c=[...a.args];for(let a of b){if(!Number.isInteger(a.index)||a.index<0||a.index>c.length||a.index<c.length&&!/\$\{global:[A-Za-z0-9_.-]+\}/.test(c[a.index])||!/\$\{global:[A-Za-z0-9_.-]+\}/.test(a.value))return{error:`Invalid package argument template at index ${String(a.index)}; templates may append arguments or replace an existing global-backed argument`};c[a.index]=a.value}return{...a,args:c}}((0,g.cy)("remote"===l.kind&&Object.keys(s).length>0?{...y,headers:{...z??{},...s}}:y,b),c?.argTemplates);if("error"in A)return{installed:!1,plan:r,error:A.error};if(c?.preferredTransport&&"stdio"!==c.preferredTransport&&"package"===l.kind&&!c.allowLocalFallback)return{installed:!1,error:`"${i.name}" was exported as ${c.preferredTransport}, but the registry now only offers a local executable install. Confirm local execution before using that fallback.`};let B=A.name,C=await h.mcpService.loadServerConfigs();if(Array.isArray(C)&&C.some(a=>a.name===B)){K.info(`installRegistryServer: "${B}" already configured; reusing`);let{tools:a,error:b}=await h.mcpService.listServerTools(B);return{installed:!0,alreadyExisted:!0,serverName:B,plan:r,tools:(a??[]).map(a=>({name:a.name,...a.description?{description:a.description}:{}})),...b?{error:b}:{}}}K.info(`installRegistryServer: installing "${i.name}" as "${B}" (${l.kind})`);let D=await h.mcpService.updateServerConfig(B,A);if(!Array.isArray(D)&&D&&"success"in D&&!1===D.success)return{installed:!1,error:`Saving the server failed: ${D.error??"unknown error"}`};let{tools:E,error:F}=await h.mcpService.listServerTools(B),H=(E??[]).map(a=>({name:a.name,...a.description?{description:a.description}:{}}));if((c?.worksGate??(await G()).worksGate)&&0===H.length){K.warn(`installRegistryServer: "${B}" exposed no tools${F?` (${F})`:""}; rolling back (works-gate)`);try{await h.mcpService.deleteServerConfig(B)}catch(a){K.error(`installRegistryServer: rollback of "${B}" failed`,a)}return{installed:!1,worksGateRejected:!0,serverName:B,plan:r,error:F?`"${i.name}" failed to start: ${F}`:`"${i.name}" connected but exposed no tools — rejected by the works-gate. Try a different server.`}}return{installed:!0,serverName:B,plan:r,tools:H,...F?{error:F}:{}}}function V(a){let b=new Set(["connect","with","from","into","using","want","need","server","mcp","that","this","the","and","for"]),c=a.toLocaleLowerCase().replace(/[^a-z0-9@._/-]+/g," ").split(/\s+/).map(a=>a.replace(/^[-/@.]+|[-/@.]+$/g,"")).filter(a=>a.length>=2&&!b.has(a));return Array.from(new Set([c.slice(0,3).join(" "),...c].map(a=>a.trim().slice(0,80)).filter(Boolean))).slice(0,6)}async function W(a,b,c){let d;if(!a||"string"!=typeof a)return{installed:!1,error:"A capability search query is required"};try{let b=await Promise.all(V(a).map(a=>Q(a,10))),c=new Map;for(let a of b.flat())c.has(a.server.name)||c.set(a.server.name,a);d=[...c.values()]}catch(a){return{installed:!1,error:`Registry lookup failed: ${a instanceof Error?a.message:String(a)}`}}let e=await J(a,d.map(M)),f=await G(),h=c?.minScore??f.minScore,i=c?.maxAttempts??3,j=[],k=0;for(let a of e){let d=a.candidate.registryName;if(a.score<h){j.push({name:d,score:a.score,reason:`below minScore ${h}`});break}if(0===(0,g.AH)(a.candidate.server).filter(g.P1).length){j.push({name:d,score:a.score,reason:"no supported install method"});continue}if(k>=i)break;k+=1;let e=await U(d,void 0,{resolveOnly:!0});if(!e.plan){j.push({name:d,score:a.score,reason:e.error??"could not resolve exact install plan"});continue}if(c?.beforeAttempt)try{let b=await c.beforeAttempt(e.plan);if(!1===b){j.push({name:d,score:a.score,reason:"blocked before execution"});break}}catch(b){K.error("installBestForCapability: beforeAttempt hook failed",b),j.push({name:d,score:a.score,reason:"pre-install audit failed"});break}let f=await U(d,b,{worksGate:!0,expectedPlan:e.plan});if(c?.onAttempt)try{await c.onAttempt(f.plan,f)}catch(a){K.error("installBestForCapability: onAttempt hook failed",a)}if(f.installed)return{...f,attempts:j};let l=f.needsEnv?.length?`needs env: ${f.needsEnv.join(", ")}`:f.worksGateRejected?"works-gate rejected (no tools / failed to start)":f.error??"install failed";j.push({name:d,score:a.score,reason:l})}return{installed:!1,attempts:j,error:`No working server found for "${a}" among the top ${k} installable candidate(s).`}}}};
|
|
1
|
+
"use strict";exports.id=4558,exports.ids=[4558],exports.modules={94558:(a,b,c)=>{let d;c.d(b,{PH:()=>P,LG:()=>W,aM:()=>U,a$:()=>S,Iz:()=>T,e3:()=>O});var e=c(66844),f=c(26790),g=c(76145),h=c(1930),i=c(65445);let j=(0,e.h)("backend/services/mcp/quality/cache"),k="mcp-quality-cache";class l{constructor(a=Date.now()){this.entries={},this.dirty=!1,this.now=a}async load(){try{let a=await (0,i.loadItem)(k,{entries:{}});this.entries=a?.entries&&"object"==typeof a.entries?a.entries:{}}catch(a){j.warn("Failed to load quality cache; starting empty",a),this.entries={}}}get(a,b){let c=this.entries[`${a}::${b}`];if(c&&!(this.now-c.at>864e5))return c.signal}set(a,b,c){this.entries[`${a}::${b}`]={at:this.now,signal:c},this.dirty=!0}async flush(){let a=!1;for(let[b,c]of Object.entries(this.entries))this.now-c.at>864e5&&(delete this.entries[b],a=!0);if(this.dirty||a)try{await (0,i.VH)(k,{entries:this.entries})}catch(a){j.warn("Failed to persist quality cache",a)}}}function m(a){return!Number.isFinite(a)||a<0?0:a>1?1:a}function n(a,b){return!Number.isFinite(a)||a<=0?0:!Number.isFinite(b)||b<=1?+(a>0):m(Math.log10(a+1)/Math.log10(b+1))}let o=(0,e.h)("backend/services/mcp/quality/providers/githubStars"),p="github",q=new Map;function r(){return d??(process.env.GITHUB_TOKEN||void 0)}function s(a){let b,c=a.server.repository;if(c?.source&&"github"!==c.source.toLowerCase())return null;var d=c?.url;if(!d)return null;try{b=new URL(d.replace(/^git\+/,""))}catch{return null}if(!/(^|\.)github\.com$/i.test(b.hostname))return null;let e=b.pathname.replace(/\.git$/i,"").split("/").filter(Boolean);return e.length<2?null:`${e[0]}/${e[1]}`.toLowerCase()}async function t(a,b){let c=new AbortController,d=()=>c.abort();b.addEventListener("abort",d,{once:!0});let e=setTimeout(()=>c.abort(),6e3);try{let b,d;return await fetch(`https://api.github.com${a}`,{headers:(b={Accept:"application/vnd.github+json","User-Agent":"FLUJO-mcp-quality","X-GitHub-Api-Version":"2022-11-28"},(d=r())&&(b.Authorization=`Bearer ${d}`),b),signal:c.signal,cache:"no-store"})}catch(b){return o.warn(`GitHub request failed (${a})`,b instanceof Error?b.message:b),null}finally{clearTimeout(e),b.removeEventListener("abort",d)}}function u(a){return(403===a.status||429===a.status)&&"0"===a.headers.get("x-ratelimit-remaining")}let v=(0,e.h)("backend/services/mcp/quality/providers/npmDownloads"),w="npm-downloads",x=new Map;function y(a){for(let b of a.server.packages??[])if("npm"===b.registryType&&b.identifier)return b.identifier;return null}function z(a){return a.startsWith("@")}async function A(a,b){let c=new AbortController,d=()=>c.abort();b.addEventListener("abort",d,{once:!0});let e=setTimeout(()=>c.abort(),6e3);try{return await fetch(`https://api.npmjs.org${a}`,{signal:c.signal,cache:"no-store"})}catch(b){return v.warn(`npm request failed (${a})`,b instanceof Error?b.message:b),null}finally{clearTimeout(e),b.removeEventListener("abort",d)}}let B="registry-status",C=[{id:p,label:"GitHub Stars & Activity",defaultWeight:.5,isApplicable:a=>null!==s(a),cacheKey:a=>s(a),async prefetch(a,b,c){let d=`${a??""} mcp`.trim(),e=`/search/repositories?q=${encodeURIComponent(d)}&sort=stars&order=desc&per_page=50`,f=await t(e,c);if(f&&f.ok)try{for(let a of(await f.json()).items??[])a.full_name&&q.set(a.full_name.toLowerCase(),{stars:"number"==typeof a.stargazers_count?a.stargazers_count:0,pushedAtMs:a.pushed_at?Date.parse(a.pushed_at):null})}catch(a){o.warn("Failed to parse GitHub search response",a)}else if(f&&u(f))return void o.warn("GitHub search rate-limited; ranking will degrade to other providers");if(!r())return;let g=3;for(let a of b){if(g<=0)break;let b=s(a);if(!b||q.has(b))continue;g-=1;let d=await t(`/repos/${b}`,c);if(d){if(u(d))break;if(d.ok)try{let a=await d.json();q.set(b,{stars:"number"==typeof a.stargazers_count?a.stargazers_count:0,pushedAtMs:a.pushed_at?Date.parse(a.pushed_at):null})}catch{}}}},async fetch(a){let b=s(a);if(!b)return null;let c=q.get(b);if(!c)return null;let d=n(c.stars,5e4),e=function(a,b,c=30,d=730){if(!a||!Number.isFinite(a))return 0;let e=(b-a)/864e5;return e<=c?1:e>=d?0:m(1-(e-c)/(d-c))}(c.pushedAtMs,Date.now());return{providerId:p,score:m(.7*d+.3*e),evidence:{repo:b,stars:c.stars,...c.pushedAtMs?{pushedAt:new Date(c.pushedAtMs).toISOString()}:{},starsScore:d,recencyScore:e}}}},{id:w,label:"npm Weekly Downloads",defaultWeight:.35,isApplicable:a=>null!==y(a),cacheKey:a=>y(a),async prefetch(a,b,c){let d=b.map(y).filter(a=>!!a&&!x.has(a)),e=d.filter(a=>!z(a)),f=d.filter(z);for(let a=0;a<e.length;a+=100){let b=e.slice(a,a+100),d=await A(`/downloads/point/last-week/${b.join(",")}`,c);if(d&&d.ok)try{let a=await d.json();if(1===b.length)"number"==typeof a.downloads&&x.set(b[0],a.downloads);else for(let c of b){let b=a[c];x.set(c,b&&"number"==typeof b.downloads?b.downloads:0)}}catch(a){v.warn("Failed to parse npm bulk downloads response",a)}}for(let a of f){let b=await A(`/downloads/point/last-week/${a}`,c);if(b&&b.ok)try{let c=await b.json();"number"==typeof c.downloads&&x.set(a,c.downloads)}catch{}}},async fetch(a){let b=y(a);if(!b)return null;let c=x.get(b);return void 0===c?null:{providerId:w,score:n(c,1e6),evidence:{package:b,weeklyDownloads:c}}}},{id:B,label:"Registry Status",defaultWeight:.15,isApplicable:a=>!0,cacheKey:()=>null,fetch:async a=>({providerId:B,score:+("active"===a.verificationStatus),evidence:{status:a.verificationStatus}})}];var D=c(74755);let E=(0,e.h)("backend/services/mcp/quality/settings");function F(){return{providers:C.map(a=>({id:a.id,enabled:!0,weight:a.defaultWeight})),minScore:0,worksGate:!0}}async function G(){try{let a=await (0,i.loadItem)(D.Zg.MCP_QUALITY_SETTINGS,F());return function(a){var b,c;let d=F(),e=a??{},f=new Map;if(Array.isArray(e.providers))for(let a of e.providers)a&&"string"==typeof a.id&&f.set(a.id,a);return{providers:d.providers.map(a=>{let b=f.get(a.id);return{id:a.id,enabled:"boolean"==typeof b?.enabled?b.enabled:a.enabled,weight:"number"==typeof b?.weight&&Number.isFinite(b.weight)&&b.weight>=0?b.weight:a.weight}}),minScore:(b=e.minScore,c=d.minScore,"number"==typeof b&&Number.isFinite(b)?Math.min(1,Math.max(0,b)):c),worksGate:"boolean"==typeof e.worksGate?e.worksGate:d.worksGate,..."string"==typeof e.githubToken&&e.githubToken.length>0?{githubToken:e.githubToken}:{}}}(a)}catch(a){return E.warn("Failed to load mcpQuality settings; using defaults",a),F()}}let H=(0,e.h)("backend/services/mcp/quality/orchestrator");async function I(a,b){let c=new AbortController,d=setTimeout(()=>c.abort(),b);try{return await a(c.signal)}finally{clearTimeout(d)}}async function J(a,b,c={}){let e=c.topN??10;try{var f;let g=c.settings??await G(),h=C.filter(a=>{var b;let c;return b=a.id,c=g.providers.find(a=>a.id===b),!!c?.enabled});if(0===h.length)return b.map(a=>({candidate:a,score:0,signals:[]}));d=(f=g.githubToken)&&f.length>0?f:void 0;let i=b.slice(0,e),j=b.slice(e),k=new l(c.now??Date.now());await k.load();let n=i.map(()=>[]);for(let b of h){let c=i.map((a,b)=>({c:a,i:b})).filter(({c:a})=>b.isApplicable(a)),d=[],e=[];for(let a of c){let c=b.cacheKey(a.c);if(c){let d=k.get(b.id,c);if(d){e.push({i:a.i,signal:d});continue}}d.push(a)}if(b.prefetch&&d.length>0)try{await I(c=>b.prefetch(a,d.map(a=>a.c),c),12e3)}catch(a){H.warn(`Provider "${b.id}" prefetch failed; degrading`,a)}for(let{c:a,i:c}of d)try{let d=await I(c=>b.fetch(a,c),2e3);if(d){n[c].push(d);let e=b.cacheKey(a);e&&k.set(b.id,e,d)}}catch(c){H.warn(`Provider "${b.id}" fetch failed for "${a.registryName}"`,c)}for(let{i:a,signal:b}of e)n[a].push(b)}await k.flush();let o=i.map((a,b)=>{let c=n[b],d=new Map(c.map(a=>[a.providerId,a])),e=h.filter(b=>b.isApplicable(a)).map(a=>{var b;let c;return{providerId:a.id,weight:(b=a.id,(c=g.providers.find(a=>a.id===b))&&c.enabled?c.weight:0),score:d.get(a.id)?.score??0}}),{score:f}=function(a){let b=0,c=0;for(let d of a){let a=Number.isFinite(d.weight)&&d.weight>0?d.weight:0,e=m(d.score);b+=a,c+=a*e}return{score:b>0?c/b:0,breakdown:a}}(e);return{candidate:a,score:f,signals:c}}).map((a,b)=>({s:a,idx:b})).sort((a,b)=>b.s.score-a.s.score||a.idx-b.idx).map(a=>a.s),p=j.map(a=>({candidate:a,score:0,signals:[]}));return[...o,...p]}catch(a){return H.warn("enrichAndRank failed; returning unranked candidates",a),b.map(a=>({candidate:a,score:0,signals:[]}))}}let K=(0,e.h)("backend/services/mcp/registryInstall"),L="/v0.1/servers";function M(a){return{registryName:a.server.name,server:a.server,verificationStatus:(0,g.vf)(a)}}function N(a){let b=b=>a.signals.find(a=>a.providerId===b)?.evidence,c=b(p),d=b(w),e=b(B);return{score:a.score,..."number"==typeof c?.stars?{stars:c.stars}:{},..."number"==typeof d?.weeklyDownloads?{weeklyDownloads:d.weeklyDownloads}:{},..."string"==typeof e?.status?{status:e.status}:{}}}async function O(a,b=8){let c=await Q(a,b);return(await J(a,c.map(M))).map(a=>R(a.candidate.server,a))}async function P(a,b=8){if(!a||"string"!=typeof a)return[];let c=await Promise.all(V(a).map(a=>Q(a,10))),d=new Map;for(let a of c.flat())d.has(a.server.name)||d.set(a.server.name,a);return(await J(a,[...d.values()].map(M))).slice(0,Math.min(Math.max(b,1),30)).map(a=>R(a.candidate.server,a))}async function Q(a,b){let c=new URL(f.jD+L);c.searchParams.set("version","latest"),c.searchParams.set("limit",String(Math.min(Math.max(b,1),30))),a&&c.searchParams.set("search",a);let d=await (0,f.Ws)(c,15e3);return Array.isArray(d?.servers)?d.servers:[]}function R(a,b){let c=(0,g.AH)(a).filter(g.P1),d=c[0];return{name:a.name,...a.title?{title:a.title}:{},...a.description?{description:a.description}:{},installable:c.length>0,requiredEnv:d?(0,g.jg)(d):[],...b?{quality:N(b)}:{}}}async function S(a,b){try{let c=await J(a,b.map(M)),d=new Map(b.map(a=>[a.server.name,a])),e=[];for(let a of c){let b=d.get(a.candidate.server.name);b&&e.push(a.signals.length>0?{...b,quality:N(a)}:b)}return e.length===b.length?e:b}catch{return b}}async function T(a){let b=new URL(f.jD+L);b.searchParams.set("version","latest"),b.searchParams.set("limit","10"),b.searchParams.set("search",a);let c=await (0,f.Ws)(b,15e3);return(Array.isArray(c?.servers)?c.servers:[]).find(b=>b.server?.name===a)??null}async function U(a,b,c){var d;let e,f;if(!a||"string"!=typeof a)return{installed:!1,error:"A registry server name is required"};try{e=await T(a)}catch(a){return{installed:!1,error:`Registry lookup failed: ${a instanceof Error?a.message:String(a)}`}}let i=e?.server??null;if(!i)return{installed:!1,error:`No registry entry found for "${a}"`};let j=(0,g.AH)(i),k=j.filter(g.P1),l=function(a,b){if(!b)return a[0];let c=a.find(a=>("package"===a.kind?"stdio":"manual-launch"===a.kind?a.transport:"sse"===a.remote.type?"sse":"streamable")===b);return c||("stdio"!==b?a.find(a=>"remote"===a.kind)??a[0]:a.find(a=>"package"===a.kind)??a[0])}(k,c?.preferredTransport);if(!l)return{installed:!1,error:0===k.length&&j.length>0?`"${i.name}" must be started manually (it runs locally but speaks HTTP); add it from the MCP server dialog instead`:`"${i.name}" has no install method FLUJO supports (stdio package or HTTP remote)`};let m=c?.serverName;if(void 0!==m&&!/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$/.test(m))return{installed:!1,error:"The server name must be 1-64 characters and use only letters, numbers, hyphens, or underscores."};let n="remote"===l.kind&&c?.oauthDynamicClientRegistration===!0,o=a=>"authorization"===a.trim().toLocaleLowerCase(),p=(0,g.vf)(e),q=(0,g.O$)(a,i,l,p),r={...q,...m?{serverName:m}:{},...n?{requiredEnvNames:q.requiredEnvNames.filter(a=>!o(a))}:{}};if(c?.expectedPlan&&(d=c.expectedPlan,JSON.stringify((f=a=>({registryName:a.registryName,resolvedName:a.resolvedName,serverName:a.serverName,transport:a.transport,command:a.command,args:a.args,serverUrl:a.serverUrl,steps:a.steps,requiredEnvNames:a.requiredEnvNames,verificationStatus:a.verificationStatus}))(r))!==JSON.stringify(f(d))))return{installed:!1,serverName:r.serverName,plan:r,error:"The Registry install plan changed after it was reviewed and audited. Resolve and approve the new exact plan before installing."};if(c?.resolveOnly)return{installed:!1,serverName:r.serverName,plan:r};let s=Object.fromEntries(Object.entries(c?.headerOverrides??{}).filter(([a])=>!n||!o(a))),t=Object.fromEntries(Object.entries(s).map(([a,b])=>[a,"string"==typeof b?b:b.value])),u=(0,g.jg)(l,{...b,...t}).filter(a=>!n||!o(a));if(u.length>0)return{installed:!1,needsEnv:u,plan:r,error:`"${i.name}" requires values for: ${u.join(", ")}`};let v=(0,g.Yr)(i,l);if("launch"in v&&v.launch)return{installed:!1,plan:r,error:`"${i.name}" needs a locally launched process behind its HTTP endpoint, which FLUJO does not start yet. Add it from the MCP server dialog and start the process yourself.`};let w="headers"in v?v.headers:void 0,x=n?Object.fromEntries(Object.entries(w??{}).filter(([a])=>!o(a))):w,y={...v,...m?{name:m}:{},...m?{rootPath:`mcp-servers/${m}`}:{},..."remote"===l.kind?{headers:x??{}}:{}},z="headers"in y?y.headers:void 0,A=function(a,b){if(!b?.length)return a;if("stdio"!==a.transport||!Array.isArray(a.args))return{error:"Package argument templates require a stdio registry server"};let c=[...a.args];for(let a of b){if(!Number.isInteger(a.index)||a.index<0||a.index>c.length||a.index<c.length&&!/\$\{global:[A-Za-z0-9_.-]+\}/.test(c[a.index])||!/\$\{global:[A-Za-z0-9_.-]+\}/.test(a.value))return{error:`Invalid package argument template at index ${String(a.index)}; templates may append arguments or replace an existing global-backed argument`};c[a.index]=a.value}return{...a,args:c}}((0,g.cy)("remote"===l.kind&&Object.keys(s).length>0?{...y,headers:{...z??{},...s}}:y,b),c?.argTemplates);if("error"in A)return{installed:!1,plan:r,error:A.error};if(c?.preferredTransport&&"stdio"!==c.preferredTransport&&"package"===l.kind&&!c.allowLocalFallback)return{installed:!1,error:`"${i.name}" was exported as ${c.preferredTransport}, but the registry now only offers a local executable install. Confirm local execution before using that fallback.`};let B=A.name,C=await h.mcpService.loadServerConfigs();if(Array.isArray(C)&&C.some(a=>a.name===B)){K.info(`installRegistryServer: "${B}" already configured; reusing`);let{tools:a,error:b}=await h.mcpService.listServerTools(B);return{installed:!0,alreadyExisted:!0,serverName:B,plan:r,tools:(a??[]).map(a=>({name:a.name,...a.description?{description:a.description}:{}})),...b?{error:b}:{}}}K.info(`installRegistryServer: installing "${i.name}" as "${B}" (${l.kind})`);let D=await h.mcpService.updateServerConfig(B,A);if(!Array.isArray(D)&&D&&"success"in D&&!1===D.success)return{installed:!1,error:`Saving the server failed: ${D.error??"unknown error"}`};let{tools:E,error:F}=await h.mcpService.listServerTools(B),H=(E??[]).map(a=>({name:a.name,...a.description?{description:a.description}:{}}));if((c?.worksGate??(await G()).worksGate)&&0===H.length){K.warn(`installRegistryServer: "${B}" exposed no tools${F?` (${F})`:""}; rolling back (works-gate)`);try{await h.mcpService.deleteServerConfig(B)}catch(a){K.error(`installRegistryServer: rollback of "${B}" failed`,a)}return{installed:!1,worksGateRejected:!0,serverName:B,plan:r,error:F?`"${i.name}" failed to start: ${F}`:`"${i.name}" connected but exposed no tools — rejected by the works-gate. Try a different server.`}}return{installed:!0,serverName:B,plan:r,tools:H,...F?{error:F}:{}}}function V(a){let b=new Set(["connect","with","from","into","using","want","need","server","mcp","that","this","the","and","for"]),c=a.toLocaleLowerCase().replace(/[^a-z0-9@._/-]+/g," ").split(/\s+/).map(a=>a.replace(/^[-/@.]+|[-/@.]+$/g,"")).filter(a=>a.length>=2&&!b.has(a));return Array.from(new Set([c.slice(0,3).join(" "),...c].map(a=>a.trim().slice(0,80)).filter(Boolean))).slice(0,6)}async function W(a,b,c){let d;if(!a||"string"!=typeof a)return{installed:!1,error:"A capability search query is required"};try{let b=await Promise.all(V(a).map(a=>Q(a,10))),c=new Map;for(let a of b.flat())c.has(a.server.name)||c.set(a.server.name,a);d=[...c.values()]}catch(a){return{installed:!1,error:`Registry lookup failed: ${a instanceof Error?a.message:String(a)}`}}let e=await J(a,d.map(M)),f=await G(),h=c?.minScore??f.minScore,i=c?.maxAttempts??3,j=[],k=0;for(let a of e){let d=a.candidate.registryName;if(a.score<h){j.push({name:d,score:a.score,reason:`below minScore ${h}`});break}if(0===(0,g.AH)(a.candidate.server).filter(g.P1).length){j.push({name:d,score:a.score,reason:"no supported install method"});continue}if(k>=i)break;k+=1;let e=await U(d,void 0,{resolveOnly:!0});if(!e.plan){j.push({name:d,score:a.score,reason:e.error??"could not resolve exact install plan"});continue}if(c?.beforeAttempt)try{let b=await c.beforeAttempt(e.plan);if(!1===b){j.push({name:d,score:a.score,reason:"blocked before execution"});break}}catch(b){K.error("installBestForCapability: beforeAttempt hook failed",b),j.push({name:d,score:a.score,reason:"pre-install audit failed"});break}let f=await U(d,b,{worksGate:!0,expectedPlan:e.plan});if(c?.onAttempt)try{await c.onAttempt(f.plan,f)}catch(a){K.error("installBestForCapability: onAttempt hook failed",a)}if(f.installed)return{...f,attempts:j};let l=f.needsEnv?.length?`needs env: ${f.needsEnv.join(", ")}`:f.worksGateRejected?"works-gate rejected (no tools / failed to start)":f.error??"install failed";j.push({name:d,score:a.score,reason:l})}return{installed:!1,attempts:j,error:`No working server found for "${a}" among the top ${k} installable candidate(s).`}}}};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";exports.id=4779,exports.ids=[4779],exports.modules={3308:(a,b,c)=>{c.d(b,{A:()=>f});var d=c(32586),e=c(48249);let f=(0,d.A)([(0,e.jsx)("path",{d:"m21.67 18.17-5.3-5.3h-.99l-2.54 2.54v.99l5.3 5.3c.39.39 1.02.39 1.41 0l2.12-2.12c.39-.38.39-1.02 0-1.41"},"0"),(0,e.jsx)("path",{d:"m17.34 10.19 1.41-1.41 2.12 2.12c1.17-1.17 1.17-3.07 0-4.24l-3.54-3.54-1.41 1.41V1.71l-.7-.71-3.54 3.54.71.71h2.83l-1.41 1.41 1.06 1.06-2.89 2.89-4.13-4.13V5.06L4.83 2.04 2 4.87 5.03 7.9h1.41l4.13 4.13-.85.85H7.6l-5.3 5.3c-.39.39-.39 1.02 0 1.41l2.12 2.12c.39.39 1.02.39 1.41 0l5.3-5.3v-2.12l5.15-5.15z"},"1")],"Handyman")},3536:(a,b,c)=>{c.d(b,{A:()=>f});var d=c(32586),e=c(48249);let f=(0,d.A)((0,e.jsx)("path",{d:"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2M4 12c0-4.42 3.58-8 8-8 1.85 0 3.55.63 4.9 1.69L5.69 16.9C4.63 15.55 4 13.85 4 12m8 8c-1.85 0-3.55-.63-4.9-1.69L18.31 7.1C19.37 8.45 20 10.15 20 12c0 4.42-3.58 8-8 8"}),"Block")},4372:(a,b,c)=>{c.d(b,{A:()=>f});var d=c(32586),e=c(48249);let f=(0,d.A)((0,e.jsx)("path",{d:"M13 3c-4.97 0-9 4.03-9 9H1l3.89 3.89.07.14L9 12H6c0-3.87 3.13-7 7-7s7 3.13 7 7-3.13 7-7 7c-1.93 0-3.68-.79-4.94-2.06l-1.42 1.42C8.27 19.99 10.51 21 13 21c4.97 0 9-4.03 9-9s-4.03-9-9-9m-1 5v5l4.28 2.54.72-1.21-3.5-2.08V8z"}),"Restore")},13373:(a,b,c)=>{c.d(b,{A:()=>f});var d=c(32586),e=c(48249);let f=(0,d.A)((0,e.jsx)("path",{d:"M6.99 11 3 15l3.99 4v-3H14v-2H6.99zM21 9l-3.99-4v3H10v2h7.01v3z"}),"SwapHoriz")},25034:(a,b,c)=>{c.d(b,{A:()=>f});var d=c(32586),e=c(48249);let f=(0,d.A)((0,e.jsx)("path",{d:"m14 4 2.29 2.29-2.88 2.88 1.42 1.42 2.88-2.88L20 10V4zm-4 0H4v6l2.29-2.29 4.71 4.7V20h2v-8.41l-5.29-5.3z"}),"CallSplit")},31975:(a,b,c)=>{c.d(b,{A:()=>f});var d=c(32586),e=c(48249);let f=(0,d.A)((0,e.jsx)("path",{d:"M20 4v12H5.17L4 17.17V4zm0-2H4c-1.1 0-2 .9-2 2v15.59c0 .89 1.08 1.34 1.71.71L6 18h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2"}),"ChatBubbleOutlineRounded")},36425:(a,b,c)=>{c.d(b,{A:()=>f});var d=c(32586),e=c(48249);let f=(0,d.A)((0,e.jsx)("path",{d:"M9 16.17 5.53 12.7a.996.996 0 0 0-1.41 0c-.39.39-.39 1.02 0 1.41l4.18 4.18c.39.39 1.02.39 1.41 0L20.29 7.71c.39-.39.39-1.02 0-1.41a.996.996 0 0 0-1.41 0z"}),"CheckRounded")},38602:(a,b,c)=>{c.d(b,{A:()=>f});var d=c(32586),e=c(48249);let f=(0,d.A)((0,e.jsx)("path",{d:"M15 3H6c-.83 0-1.54.5-1.84 1.22l-3.02 7.05c-.09.23-.14.47-.14.73v2c0 1.1.9 2 2 2h6.31l-.95 4.57-.03.32c0 .41.17.79.44 1.06L9.83 23l6.59-6.59c.36-.36.58-.86.58-1.41V5c0-1.1-.9-2-2-2m4 0v12h4V3z"}),"ThumbDown")},45788:(a,b,c)=>{c.d(b,{A:()=>f});var d=c(32586),e=c(48249);let f=(0,d.A)((0,e.jsx)("path",{d:"M17 11h3c1.11 0 2-.9 2-2V5c0-1.11-.9-2-2-2h-3c-1.11 0-2 .9-2 2v1H9.01V5c0-1.11-.9-2-2-2H4c-1.1 0-2 .9-2 2v4c0 1.11.9 2 2 2h3c1.11 0 2-.9 2-2V8h2v7.01c0 1.65 1.34 2.99 2.99 2.99H15v1c0 1.11.9 2 2 2h3c1.11 0 2-.9 2-2v-4c0-1.11-.9-2-2-2h-3c-1.11 0-2 .9-2 2v1h-1.01c-.54 0-.99-.45-.99-.99V8h2v1c0 1.1.9 2 2 2"}),"AccountTreeRounded")},49509:(a,b,c)=>{c.d(b,{A:()=>f});var d=c(32586),e=c(48249);let f=(0,d.A)((0,e.jsx)("path",{d:"M15 20H5V7c0-.55-.45-1-1-1s-1 .45-1 1v13c0 1.1.9 2 2 2h10c.55 0 1-.45 1-1s-.45-1-1-1m5-4V4c0-1.1-.9-2-2-2H9c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h9c1.1 0 2-.9 2-2m-2 0H9V4h9z"}),"ContentCopyRounded")},50025:(a,b,c)=>{c.d(b,{A:()=>w});var d=c(67484),e=c(99314),f=c(65462),g=c(8918);let h=function(a){let{badgeContent:b,invisible:c=!1,max:d=99,showZero:e=!1}=a,g=(0,f.A)({badgeContent:b,max:d}),h=c;!1!==c||0!==b||e||(h=!0);let{badgeContent:i,max:j=d}=h?g:a,k=i&&Number(i)>j?`${j}+`:i;return{badgeContent:i,invisible:h,max:j,displayValue:k}};var i=c(72139),j=c(85646),k=c(19765),l=c(25511),m=c(40015),n=c(34804),o=c(65236);function p(a){return(0,o.Ay)("MuiBadge",a)}let q=(0,n.A)("MuiBadge",["root","badge","dot","standard","anchorOriginTopRight","anchorOriginBottomRight","anchorOriginTopLeft","anchorOriginBottomLeft","invisible","colorError","colorInfo","colorPrimary","colorSecondary","colorSuccess","colorWarning","overlapRectangular","overlapCircular","anchorOriginTopLeftCircular","anchorOriginTopLeftRectangular","anchorOriginTopRightCircular","anchorOriginTopRightRectangular","anchorOriginBottomLeftCircular","anchorOriginBottomLeftRectangular","anchorOriginBottomRightCircular","anchorOriginBottomRightRectangular"]);var r=c(12134),s=c(48249);let t=(0,i.Ay)("span",{name:"MuiBadge",slot:"Root",overridesResolver:(a,b)=>b.root})({position:"relative",display:"inline-flex",verticalAlign:"middle",flexShrink:0}),u=(0,i.Ay)("span",{name:"MuiBadge",slot:"Badge",overridesResolver:(a,b)=>{let{ownerState:c}=a;return[b.badge,b[c.variant],b[`anchorOrigin${(0,m.A)(c.anchorOrigin.vertical)}${(0,m.A)(c.anchorOrigin.horizontal)}${(0,m.A)(c.overlap)}`],"default"!==c.color&&b[`color${(0,m.A)(c.color)}`],c.invisible&&b.invisible]}})((0,j.A)(({theme:a})=>({display:"flex",flexDirection:"row",flexWrap:"wrap",justifyContent:"center",alignContent:"center",alignItems:"center",position:"absolute",boxSizing:"border-box",fontFamily:a.typography.fontFamily,fontWeight:a.typography.fontWeightMedium,fontSize:a.typography.pxToRem(12),minWidth:20,lineHeight:1,padding:"0 6px",height:20,borderRadius:10,zIndex:1,transition:a.transitions.create("transform",{easing:a.transitions.easing.easeInOut,duration:a.transitions.duration.enteringScreen}),variants:[...Object.entries(a.palette).filter((0,k.A)(["contrastText"])).map(([b])=>({props:{color:b},style:{backgroundColor:(a.vars||a).palette[b].main,color:(a.vars||a).palette[b].contrastText}})),{props:{variant:"dot"},style:{borderRadius:4,height:8,minWidth:8,padding:0}},{props:({ownerState:a})=>"top"===a.anchorOrigin.vertical&&"right"===a.anchorOrigin.horizontal&&"rectangular"===a.overlap,style:{top:0,right:0,transform:"scale(1) translate(50%, -50%)",transformOrigin:"100% 0%",[`&.${q.invisible}`]:{transform:"scale(0) translate(50%, -50%)"}}},{props:({ownerState:a})=>"bottom"===a.anchorOrigin.vertical&&"right"===a.anchorOrigin.horizontal&&"rectangular"===a.overlap,style:{bottom:0,right:0,transform:"scale(1) translate(50%, 50%)",transformOrigin:"100% 100%",[`&.${q.invisible}`]:{transform:"scale(0) translate(50%, 50%)"}}},{props:({ownerState:a})=>"top"===a.anchorOrigin.vertical&&"left"===a.anchorOrigin.horizontal&&"rectangular"===a.overlap,style:{top:0,left:0,transform:"scale(1) translate(-50%, -50%)",transformOrigin:"0% 0%",[`&.${q.invisible}`]:{transform:"scale(0) translate(-50%, -50%)"}}},{props:({ownerState:a})=>"bottom"===a.anchorOrigin.vertical&&"left"===a.anchorOrigin.horizontal&&"rectangular"===a.overlap,style:{bottom:0,left:0,transform:"scale(1) translate(-50%, 50%)",transformOrigin:"0% 100%",[`&.${q.invisible}`]:{transform:"scale(0) translate(-50%, 50%)"}}},{props:({ownerState:a})=>"top"===a.anchorOrigin.vertical&&"right"===a.anchorOrigin.horizontal&&"circular"===a.overlap,style:{top:"14%",right:"14%",transform:"scale(1) translate(50%, -50%)",transformOrigin:"100% 0%",[`&.${q.invisible}`]:{transform:"scale(0) translate(50%, -50%)"}}},{props:({ownerState:a})=>"bottom"===a.anchorOrigin.vertical&&"right"===a.anchorOrigin.horizontal&&"circular"===a.overlap,style:{bottom:"14%",right:"14%",transform:"scale(1) translate(50%, 50%)",transformOrigin:"100% 100%",[`&.${q.invisible}`]:{transform:"scale(0) translate(50%, 50%)"}}},{props:({ownerState:a})=>"top"===a.anchorOrigin.vertical&&"left"===a.anchorOrigin.horizontal&&"circular"===a.overlap,style:{top:"14%",left:"14%",transform:"scale(1) translate(-50%, -50%)",transformOrigin:"0% 0%",[`&.${q.invisible}`]:{transform:"scale(0) translate(-50%, -50%)"}}},{props:({ownerState:a})=>"bottom"===a.anchorOrigin.vertical&&"left"===a.anchorOrigin.horizontal&&"circular"===a.overlap,style:{bottom:"14%",left:"14%",transform:"scale(1) translate(-50%, 50%)",transformOrigin:"0% 100%",[`&.${q.invisible}`]:{transform:"scale(0) translate(-50%, 50%)"}}},{props:{invisible:!0},style:{transition:a.transitions.create("transform",{easing:a.transitions.easing.easeInOut,duration:a.transitions.duration.leavingScreen})}}]})));function v(a){return{vertical:a?.vertical??"top",horizontal:a?.horizontal??"right"}}let w=d.forwardRef(function(a,b){let c=(0,l.b)({props:a,name:"MuiBadge"}),{anchorOrigin:d,className:i,classes:j,component:k,components:n={},componentsProps:o={},children:q,overlap:w="rectangular",color:x="default",invisible:y=!1,max:z=99,badgeContent:A,slots:B,slotProps:C,showZero:D=!1,variant:E="standard",...F}=c,{badgeContent:G,invisible:H,max:I,displayValue:J}=h({max:z,invisible:y,badgeContent:A,showZero:D}),K=(0,f.A)({anchorOrigin:v(d),color:x,overlap:w,variant:E,badgeContent:A}),L=H||null==G&&"dot"!==E,{color:M=x,overlap:N=w,anchorOrigin:O,variant:P=E}=L?K:c,Q=v(O),R="dot"!==P?J:void 0,S={...c,badgeContent:G,invisible:L,max:I,displayValue:R,showZero:D,anchorOrigin:Q,color:M,overlap:N,variant:P},T=(a=>{let{color:b,anchorOrigin:c,invisible:d,overlap:e,variant:f,classes:h={}}=a,i={root:["root"],badge:["badge",f,d&&"invisible",`anchorOrigin${(0,m.A)(c.vertical)}${(0,m.A)(c.horizontal)}`,`anchorOrigin${(0,m.A)(c.vertical)}${(0,m.A)(c.horizontal)}${(0,m.A)(e)}`,`overlap${(0,m.A)(e)}`,"default"!==b&&`color${(0,m.A)(b)}`]};return(0,g.A)(i,p,h)})(S),U={slots:{root:B?.root??n.Root,badge:B?.badge??n.Badge},slotProps:{root:C?.root??o.root,badge:C?.badge??o.badge}},[V,W]=(0,r.A)("root",{elementType:t,externalForwardedProps:{...U,...F},ownerState:S,className:(0,e.A)(T.root,i),ref:b,additionalProps:{as:k}}),[X,Y]=(0,r.A)("badge",{elementType:u,externalForwardedProps:U,ownerState:S,className:T.badge});return(0,s.jsxs)(V,{...W,children:[q,(0,s.jsx)(X,{...Y,children:R})]})})},53594:(a,b,c)=>{c.d(b,{A:()=>f});var d=c(32586),e=c(48249);let f=(0,d.A)((0,e.jsx)("path",{d:"M16.59 7.58 10 14.17l-3.59-3.58L5 12l5 5 8-8zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2m0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8"}),"CheckCircleOutline")},61644:(a,b,c)=>{c.d(b,{A:()=>f});var d=c(32586),e=c(48249);let f=(0,d.A)([(0,e.jsx)("path",{d:"M19.03 3.56c-1.67-1.39-3.74-2.3-6.03-2.51v2.01c1.73.19 3.31.88 4.61 1.92zM11 3.06V1.05c-2.29.2-4.36 1.12-6.03 2.51l1.42 1.42C7.69 3.94 9.27 3.25 11 3.06M4.98 6.39 3.56 4.97C2.17 6.64 1.26 8.71 1.05 11h2.01c.19-1.73.88-3.31 1.92-4.61M20.94 11h2.01c-.21-2.29-1.12-4.36-2.51-6.03l-1.42 1.42c1.04 1.3 1.73 2.88 1.92 4.61M7 12l3.44 1.56L12 17l1.56-3.44L17 12l-3.44-1.56L12 7l-1.56 3.44z"},"0"),(0,e.jsx)("path",{d:"M12 21c-3.11 0-5.85-1.59-7.46-4H7v-2H1v6h2v-2.7c1.99 2.84 5.27 4.7 9 4.7 4.87 0 9-3.17 10.44-7.56l-1.96-.45C19.25 18.48 15.92 21 12 21"},"1")],"AutoMode")},81642:(a,b,c)=>{c.d(b,{A:()=>f});var d=c(32586),e=c(48249);let f=(0,d.A)((0,e.jsx)("path",{d:"M16.01 11H4v2h12.01v3L20 12l-3.99-4z"}),"ArrowRightAlt")},87526:(a,b,c)=>{c.d(b,{A:()=>f});var d=c(32586),e=c(48249);let f=(0,d.A)((0,e.jsx)("path",{d:"M20.5 11H19V7c0-1.1-.9-2-2-2h-4V3.5C13 2.12 11.88 1 10.5 1S8 2.12 8 3.5V5H4c-1.1 0-1.99.9-1.99 2v3.8H3.5c1.49 0 2.7 1.21 2.7 2.7s-1.21 2.7-2.7 2.7H2V20c0 1.1.9 2 2 2h3.8v-1.5c0-1.49 1.21-2.7 2.7-2.7s2.7 1.21 2.7 2.7V22H17c1.1 0 2-.9 2-2v-4h1.5c1.38 0 2.5-1.12 2.5-2.5S21.88 11 20.5 11"}),"ExtensionRounded")},89194:(a,b,c)=>{c.d(b,{A:()=>f});var d=c(32586),e=c(48249);let f=(0,d.A)((0,e.jsx)("path",{d:"M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2m0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2m0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2"}),"MoreVert")},91709:(a,b,c)=>{c.d(b,{A:()=>f});var d=c(32586),e=c(48249);let f=(0,d.A)((0,e.jsx)("path",{d:"M12 14c1.66 0 2.99-1.34 2.99-3L15 5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3m5.3-3c0 3-2.54 5.1-5.3 5.1S6.7 14 6.7 11H5c0 3.41 2.72 6.23 6 6.72V21h2v-3.28c3.28-.48 6-3.3 6-6.72z"}),"Mic")},92686:(a,b,c)=>{c.d(b,{A:()=>f});var d=c(32586),e=c(48249);let f=(0,d.A)((0,e.jsx)("path",{d:"M3 17v2h6v-2zM3 5v2h10V5zm10 16v-2h8v-2h-8v-2h-2v6zM7 9v2H3v2h4v2h2V9zm14 4v-2H11v2zm-6-4h2V7h4V5h-4V3h-2z"}),"Tune")},94367:(a,b,c)=>{c.d(b,{A:()=>f});var d=c(32586),e=c(48249);let f=(0,d.A)((0,e.jsx)("path",{d:"M16.5 6v11.5c0 2.21-1.79 4-4 4s-4-1.79-4-4V5c0-1.38 1.12-2.5 2.5-2.5s2.5 1.12 2.5 2.5v10.5c0 .55-.45 1-1 1s-1-.45-1-1V6H10v9.5c0 1.38 1.12 2.5 2.5 2.5s2.5-1.12 2.5-2.5V5c0-2.21-1.79-4-4-4S7 2.79 7 5v12.5c0 3.04 2.46 5.5 5.5 5.5s5.5-2.46 5.5-5.5V6z"}),"AttachFile")},94387:(a,b,c)=>{c.d(b,{A:()=>f});var d=c(32586),e=c(48249);let f=(0,d.A)((0,e.jsx)("path",{d:"M1 21h4V9H1zm22-11c0-1.1-.9-2-2-2h-6.31l.95-4.57.03-.32c0-.41-.17-.79-.44-1.06L14.17 1 7.59 7.59C7.22 7.95 7 8.45 7 9v10c0 1.1.9 2 2 2h9c.83 0 1.54-.5 1.84-1.22l3.02-7.05c.09-.23.14-.47.14-.73z"}),"ThumbUp")},97718:(a,b,c)=>{c.d(b,{A:()=>f});var d=c(32586),e=c(48249);let f=(0,d.A)((0,e.jsx)("path",{d:"M2.01 21 23 12 2.01 3 2 10l15 2-15 2z"}),"Send")}};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";exports.id=531,exports.ids=[244,531],exports.modules={80244:(a,b,c)=>{c.r(b),c.d(b,{loadServerConfigs:()=>p,loadServerRoots:()=>q,saveConfig:()=>s});var d=c(33873),e=c.n(d),f=c(98775),g=c(65445),h=c(74755),i=c(66844),j=c(7986);let k=(0,i.h)("backend/services/mcp/config"),l=new Set(["streamable","sse","websocket"]),m=new Map;async function n(a){if(m.has(a))return m.get(a);let b=null;try{let c=(0,f.Ay)({baseDir:a,timeout:{block:5e3}});b=(await c.remote(["get-url","origin"])||"").trim()||null}catch{b=null}return m.set(a,b),b}async function o(a){var b;let c;if(l.has(a.transport))return{type:"remote"};let d="string"!=typeof(b=a.rootPath)||""===b.trim()?null:e().isAbsolute(b)?b:e().resolve((0,j.getWorkspaceDataDir)(),b);if(d&&""!==(c=e().relative(e().join((0,j.getWorkspaceDataDir)(),"mcp-servers"),d))&&!c.startsWith("..")&&!e().isAbsolute(c)){let a=await n(d);if(a)return{type:"github",repositoryUrl:a}}return{type:"local"}}async function p(){k.debug("Entering loadServerConfigs method");try{let a=await (0,g.loadItem)(h.Zg.MCP_SERVERS,{}),b=Object.entries(a).map(([a,b])=>{let c=b.transport||"stdio",d=a=>"string"==typeof a?(0,j.remapLegacyDefaultWorkspaceReference)(a,"mcp-servers"):a,e=a=>!a||"object"!=typeof a||Array.isArray(a)?a:Object.fromEntries(Object.entries(a).map(([a,b])=>"string"==typeof b?[a,d(b)]:b&&"object"==typeof b&&"string"==typeof b.value?[a,{...b,value:d(b.value)}]:[a,b]));b={...b,rootPath:d(b.rootPath),cwd:d(b.cwd),command:d(b.command),args:Array.isArray(b.args)?b.args.map(d):b.args,roots:Array.isArray(b.roots)?b.roots.map(d):b.roots,env:e(b.env),...Object.prototype.hasOwnProperty.call(b,"launch")?{launch:b.launch&&"object"==typeof b.launch?{...b.launch,command:d(b.launch.command),cwd:d(b.launch.cwd),args:Array.isArray(b.launch.args)?b.launch.args.map(d):b.launch.args,env:e(b.launch.env)}:b.launch}:{}},l.has(c)&&function(a){if("string"!=typeof a)return!1;let b=a.trim();return"/"===b||"\\"===b||/^[A-Za-z]:[\\/]?$/.test(b)}(b.rootPath)&&(k.info(`Normalizing filesystem-root rootPath "${b.rootPath}" of remote server ${a} to mcp-servers/${a}`),b={...b,rootPath:`mcp-servers/${a}`});let f={name:a,disabled:!1,autoApprove:[],rootPath:"",env:{},_buildCommand:"",_installCommand:""};return"streamable"===c?{...
|
|
1
|
+
"use strict";exports.id=531,exports.ids=[244,531],exports.modules={80244:(a,b,c)=>{c.r(b),c.d(b,{loadServerConfigs:()=>p,loadServerRoots:()=>q,saveConfig:()=>s});var d=c(33873),e=c.n(d),f=c(98775),g=c(65445),h=c(74755),i=c(66844),j=c(7986);let k=(0,i.h)("backend/services/mcp/config"),l=new Set(["streamable","sse","websocket"]),m=new Map;async function n(a){if(m.has(a))return m.get(a);let b=null;try{let c=(0,f.Ay)({baseDir:a,timeout:{block:5e3}});b=(await c.remote(["get-url","origin"])||"").trim()||null}catch{b=null}return m.set(a,b),b}async function o(a){var b;let c;if(l.has(a.transport))return{type:"remote"};let d="string"!=typeof(b=a.rootPath)||""===b.trim()?null:e().isAbsolute(b)?b:e().resolve((0,j.getWorkspaceDataDir)(),b);if(d&&""!==(c=e().relative(e().join((0,j.getWorkspaceDataDir)(),"mcp-servers"),d))&&!c.startsWith("..")&&!e().isAbsolute(c)){let a=await n(d);if(a)return{type:"github",repositoryUrl:a}}return{type:"local"}}async function p(){k.debug("Entering loadServerConfigs method");try{let a=await (0,g.loadItem)(h.Zg.MCP_SERVERS,{}),b=Object.entries(a).map(([a,b])=>{let c=b.transport||"stdio",d=a=>"string"==typeof a?(0,j.remapLegacyDefaultWorkspaceReference)(a,"mcp-servers"):a,e=a=>!a||"object"!=typeof a||Array.isArray(a)?a:Object.fromEntries(Object.entries(a).map(([a,b])=>"string"==typeof b?[a,d(b)]:b&&"object"==typeof b&&"string"==typeof b.value?[a,{...b,value:d(b.value)}]:[a,b]));b={...b,rootPath:d(b.rootPath),cwd:d(b.cwd),command:d(b.command),args:Array.isArray(b.args)?b.args.map(d):b.args,roots:Array.isArray(b.roots)?b.roots.map(d):b.roots,env:e(b.env),...Object.prototype.hasOwnProperty.call(b,"launch")?{launch:b.launch&&"object"==typeof b.launch?{...b.launch,command:d(b.launch.command),cwd:d(b.launch.cwd),args:Array.isArray(b.launch.args)?b.launch.args.map(d):b.launch.args,env:e(b.launch.env)}:b.launch}:{}},l.has(c)&&function(a){if("string"!=typeof a)return!1;let b=a.trim();return"/"===b||"\\"===b||/^[A-Za-z]:[\\/]?$/.test(b)}(b.rootPath)&&(k.info(`Normalizing filesystem-root rootPath "${b.rootPath}" of remote server ${a} to mcp-servers/${a}`),b={...b,rootPath:`mcp-servers/${a}`});let f=b.source?.type;"stdio"===c&&"string"==typeof b.rootPath&&"."===b.rootPath.trim()&&("registry"===f||"marketplace"===f)&&/^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/.test(a)&&(k.info(`Normalizing shared Registry rootPath "." of ${a} to mcp-servers/${a}`),b={...b,rootPath:`mcp-servers/${a}`});let g={name:a,disabled:!1,autoApprove:[],rootPath:"",env:{},_buildCommand:"",_installCommand:""};return"streamable"===c?{...g,...b,name:a,requestInit:b.requestInit&&"object"==typeof b.requestInit?b.requestInit:void 0,reconnectionOptions:b.reconnectionOptions&&"object"==typeof b.reconnectionOptions?b.reconnectionOptions:void 0,sessionId:b.sessionId||void 0,oauthClientId:b.oauthClientId||"",oauthClientSecret:b.oauthClientSecret||"",oauthScopes:b.oauthScopes||(b.oauthClientId||b.oauthClientInformation?["read"]:void 0),oauthClientMetadata:b.oauthClientMetadata,oauthClientInformation:b.oauthClientInformation,oauthTokens:b.oauthTokens,oauthCodeVerifier:b.oauthCodeVerifier}:"sse"===c?{...g,...b,name:a,eventSourceInit:b.eventSourceInit&&"object"==typeof b.eventSourceInit?b.eventSourceInit:void 0,requestInit:b.requestInit&&"object"==typeof b.requestInit?b.requestInit:void 0}:"websocket"===c?{...g,...b,name:a,websocketUrl:b.websocketUrl||""}:{...g,...b,name:a,command:b.command||"",args:b.args||[],stderr:b.stderr||"pipe"}});return await Promise.all(b.map(async a=>{a.source||(a.source=await o(a))})),b}catch(a){return k.warn("Failed to load server configs",a),{success:!1,error:`Failed to load server configs: ${a instanceof Error?a.message:"Unknown error"}`}}}async function q(a){let b=await p();if(!Array.isArray(b))return[];let c=b.find(b=>b.name===a)?.roots;return Array.isArray(c)?c.filter(a=>"string"==typeof a):[]}let r=["_buildCommand","_installCommand","oauthClientId","oauthClientSecret"];async function s(a){k.debug("Entering saveConfig method");try{let b=Object.fromEntries(Array.from(a.entries()).map(([a,b])=>[a,function(a){let{name:b,...c}=a,d={};for(let[a,b]of Object.entries(c))void 0!==b&&(""===b&&r.includes(a)||(d[a]=b));return d}(b)]));return await (0,g.VH)(h.Zg.MCP_SERVERS,b),{success:!0}}catch(a){return k.warn("Failed to save config",a),{success:!1,error:`Failed to save config: ${a instanceof Error?a.message:"Unknown error"}`}}}},80531:(a,b,c)=>{c.d(b,{Cl:()=>l,yJ:()=>j});var d=c(66844),e=c(80244),f=c(18705),g=c(7986),h=c(77598);let i=(0,d.h)("backend/services/mcp/oauth");function j(a,b,c,d=Date.now()){if(!/^[A-Za-z0-9_-]{43}$/.test(b)||!/^[A-Za-z0-9_-]{43}$/.test(a.oauthState??"")||!a.oauthState||a.oauthStateWorkspace!==c||"number"!=typeof a.oauthStateCreatedAt||d-a.oauthStateCreatedAt<0||d-a.oauthStateCreatedAt>12e5)return!1;let e=Buffer.from(a.oauthState),f=Buffer.from(b);return e.length===f.length&&(0,h.timingSafeEqual)(e,f)}class k{constructor(a,b){this.config=a,this._redirectUrl=b,this._clientMetadata={redirect_uris:[b],client_name:`FLUJO MCP Client - ${a.name}`,client_uri:"https://github.com/mario-andreschak/FLUJO",grant_types:["authorization_code","refresh_token"],response_types:["code"],token_endpoint_auth_method:"client_secret_post",scope:a.oauthScopes?.join(" ")||"read"},i.info(`Created OAuth client provider for ${a.name}`),i.verbose("OAuth client metadata",JSON.stringify(this._clientMetadata))}get redirectUrl(){return this._redirectUrl}get clientMetadata(){return this._clientMetadata}state(){let a=(0,h.randomBytes)(32).toString("base64url");return this.config.oauthState=a,this.config.oauthStateWorkspace=(0,g.getCurrentWorkspace)(),this.config.oauthStateCreatedAt=Date.now(),a}async clientInformation(){if(this.config.oauthClientInformation)return i.debug(`Returning stored client information for ${this.config.name}`),this.config.oauthClientInformation;if(this.config.oauthClientId){let a=this.config.oauthClientSecret?await (0,f.G)(this.config.oauthClientSecret)??void 0:void 0;return i.debug(`Created client information from config for ${this.config.name}`),{client_id:this.config.oauthClientId,client_secret:a}}i.debug(`No client information available for ${this.config.name}`)}async persist(){let a=await (0,e.loadServerConfigs)();if(!Array.isArray(a))return void i.warn(`persist: failed to load server configs for ${this.config.name}, cannot persist OAuth state`);let b=new Map(a.map(a=>[a.name,a]));b.set(this.config.name,this.config);let c=await (0,e.saveConfig)(b);c.success||i.warn(`persist: failed to save OAuth state for ${this.config.name}: ${c.error}`)}async invalidateCredentials(a){i.info(`Invalidating OAuth credentials for ${this.config.name} (scope: ${a})`),("all"===a||"tokens"===a)&&(this.config.oauthTokens=void 0),("all"===a||"client"===a)&&(this.config.oauthClientInformation=void 0,this.config.oauthClientMetadata=void 0),("all"===a||"verifier"===a)&&(this.config.oauthCodeVerifier=void 0,this.config.oauthState=void 0,this.config.oauthStateWorkspace=void 0,this.config.oauthStateCreatedAt=void 0),await this.persist()}async saveClientInformation(a){i.info(`Saving client information for ${this.config.name}`),i.verbose("Client information to save",JSON.stringify(a)),this.config.oauthClientInformation={client_id:a.client_id,client_secret:a.client_secret,client_id_issued_at:a.client_id_issued_at,client_secret_expires_at:a.client_secret_expires_at},this.config.oauthClientMetadata={redirect_uris:a.redirect_uris,client_name:a.client_name,client_uri:a.client_uri,grant_types:a.grant_types,response_types:a.response_types,token_endpoint_auth_method:a.token_endpoint_auth_method,scope:a.scope,contacts:a.contacts,tos_uri:a.tos_uri,policy_uri:a.policy_uri,jwks_uri:a.jwks_uri,jwks:a.jwks,software_id:a.software_id,software_version:a.software_version},await this.persist(),i.info(`Client information saved for ${this.config.name}`)}async tokens(){if(this.config.oauthTokens){if(i.debug(`Returning stored tokens for ${this.config.name}`),this.config.oauthTokens.expires_in&&this.config.oauthTokens.issued_at){let a=this.config.oauthTokens.issued_at,b=this.config.oauthTokens.expires_in,c=Math.floor(Date.now()/1e3),d=a+b;c>=d?i.info(`Access token for ${this.config.name} has expired (issued: ${a}, expires: ${d}, current: ${c}); SDK will refresh via refresh_token`):i.debug(`Tokens for ${this.config.name} are valid (expires in ${d-c} seconds)`)}return this.config.oauthTokens}i.debug(`No tokens available for ${this.config.name}`)}async saveTokens(a){i.info(`Saving OAuth tokens for ${this.config.name}`),i.verbose("Tokens to save",JSON.stringify({...a,access_token:a.access_token?"[REDACTED]":void 0,refresh_token:a.refresh_token?"[REDACTED]":void 0}));let b={...a,issued_at:Math.floor(Date.now()/1e3)};this.config.oauthTokens=b,await this.persist(),i.info(`OAuth tokens saved for ${this.config.name}`)}async redirectToAuthorization(a){i.info(`Authorization required for ${this.config.name}`),i.info(`Authorization URL: ${a.toString()}`),this.config.authorizationUrl=a.toString();let b=Error(`OAuth authentication required for ${this.config.name}. Please complete the OAuth flow.`);throw b.name="OAuthAuthenticationRequired",b}async saveCodeVerifier(a){i.debug(`Saving code verifier for ${this.config.name}`),this.config.oauthCodeVerifier=a,await this.persist(),i.debug(`Code verifier saved for ${this.config.name}`)}async codeVerifier(){if(!this.config.oauthCodeVerifier){let a=`No code verifier found for ${this.config.name}`;throw i.error(a),Error(a)}return i.debug(`Returning code verifier for ${this.config.name}`),this.config.oauthCodeVerifier}}function l(a,b="http://localhost:4200/api/oauth/callback"){return new k(a,b)}}};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";exports.id=5354,exports.ids=[5354],exports.modules={50306:(a,b,c)=>{c.d(b,{O9:()=>e,Z9:()=>f,hk:()=>g,wv:()=>h});var d=c(45481);function e(a,b){try{let c=new d.l4(a,{timezone:b,paused:!0});return c.nextRun(),c.stop(),{valid:!0}}catch(a){return{valid:!1,error:a instanceof Error?a.message:"Invalid cron pattern"}}}function f(a,b,c){let e=new d.l4(a,{timezone:b,paused:!0});try{return e.nextRuns(c).map(a=>a.toISOString())}finally{e.stop()}}function g(a,b){let c=new d.l4(a.cron,{timezone:a.timezone,paused:!0});try{let a=c.nextRun(new Date(b));return null!==a&&a.getTime()<=Date.now()}finally{c.stop()}}function h(a,b){let c=new d.l4(a.cron,{timezone:a.timezone,unref:!0},b);return{dispose:()=>c.stop(),nextRun:()=>c.nextRun()?.toISOString()??null}}},50960:(a,b,c)=>{c.d(b,{A1:()=>k,Je:()=>i,Jl:()=>j,qq:()=>f,vV:()=>g});var d=c(55511);function e(a){return JSON.stringify(function a(b){if(Array.isArray(b))return b.map(a);if(null!==b&&"object"==typeof b){let c=Object.entries(b).sort(([a],[b])=>a<b?-1:+(a>b)),d={};for(let[b,e]of c)d[b]=a(e);return d}return b}(a))}function f(a){return(0,d.createHash)("sha256").update(e(a)??"undefined").digest("hex")}async function g(a){let{status:b,pendingState:c,priorFailures:d,saveState:e}=a;if("completed"===b)return await e({...c,...d>0?{pendingFailures:0}:{}}),{giveUpError:null};if("skipped"===b)return{giveUpError:null};let f=d+1;return f>=3?(await e({...c,pendingFailures:0}),{giveUpError:"Detected a change but the flow failed to process it 3\xd7 — skipping it to avoid a loop"}):(await e({pendingFailures:f}),{giveUpError:null})}function h(a,b){if(!b)return a;let c=a;for(let a of b.split(".")){if(null==c||"object"!=typeof c)return;c=c[a]}return c}function i(a){let b=e(a)??"";return b.length<=8192?a:{truncated:!0,note:`Result too large to include fully (${b.length} chars); this is a preview.`,preview:b.slice(0,8192)}}function j(a,b){let c=f(a);return b.lastHash?b.lastHash===c?{fire:!1,newState:{}}:{fire:!0,summary:"Tool result changed",context:{result:i(a)},newState:{},pendingState:{lastHash:c}}:{fire:!1,newState:{lastHash:c}}}function k(a,b,c,d){let e=h(a,b);if(!Array.isArray(e))return{fire:!1,newState:{},error:`"${b||"(root)"}" did not resolve to a list in the tool result`};let g=e.map(a=>{let b=h(a,c);return{id:null==b||"object"==typeof b?`hash:${f(a)}`:String(b),item:a}}),j=d.seenIds,k=g.map(({id:a})=>a),l=(a,b)=>{let c=[...a??[]],d=new Set(c);for(let a of b)d.has(a)||(d.add(a),c.push(a));return c.slice(-1e3)};if(!j)return{fire:!1,newState:{seenIds:l(void 0,k)}};let m=new Set(j),n=g.filter(({id:a})=>!m.has(a));if(0===n.length)return{fire:!1,newState:{}};let o=n.slice(0,50);return{fire:!0,summary:1===n.length?"1 new item":`${n.length} new items`,context:{newItems:i(o.map(({item:a})=>a)),...n.length>50?{omitted:n.length-50}:{}},newState:{},pendingState:{seenIds:l(j,o.map(({id:a})=>a))}}}},65354:(a,b,c)=>{c.d(b,{getSchedulerService:()=>H});var d=c(78796),e=c(65445),f=c(74755),g=c(66844),h=c(63078),i=c(7986),j=c(50306),k=c(33873),l=c.n(k),m=c(29021),n=c(84314);let o=(0,g.h)("backend/services/scheduler/triggers/fileWatch");var p=c(45481),q=c(86057),r=c(50960);let s=(0,g.h)("backend/services/scheduler/triggers/mcpPoll"),t=(0,g.h)("backend/services/scheduler/triggers/urlWatch");var u=c(46702);let v=(0,g.h)("backend/services/scheduler/triggers/flowEvent");function w(a){return a&&a.length>8192?`${a.slice(0,8192)}… (truncated)`:a}var x=c(78286);let y=(0,g.h)("backend/services/scheduler/state"),z=a=>`planned-execution-state/${a}`;async function A(a){try{return await (0,e.loadItem)(z(a),{})}catch(b){return y.error(`Failed to load trigger state for ${a}:`,b),{}}}async function B(a,b){await (0,e.VH)(z(a),b)}async function C(a){await (0,e.N2)(z(a))}var D=c(8619);let E=(0,g.h)("backend/services/scheduler/index"),F={version:1,paused:!1,executions:[]};class G{static{this.MAX_QUEUE_DEPTH=50}inWorkspace(a){return(0,i.runWithWorkspace)(this.workspace,a)}bindToWorkspace(a){return(...b)=>this.inWorkspace(()=>a(...b))}async start(){this.started||(this.started=!0,E.info("Starting scheduler"),await this.reconcile())}reconcile(){let a=this.reconcileChain.catch(()=>{}).then(()=>this.inWorkspace(()=>this.doReconcile()));return this.reconcileChain=a,a}async doReconcile(){for(let[a,b]of this.armed)try{b.dispose()}catch(b){E.warn(`Failed to dispose trigger for ${a}:`,b)}this.armed.clear();let a=await this.loadFile();if(this.pausedCache=a.paused,a.paused)return void E.info("Scheduler is paused — nothing armed");for(let b of a.executions)if(b.enabled)try{await this.armExecution(b)}catch(c){let a=c instanceof Error?c.message:String(c);this.lastTriggerErrors.set(b.id,a),E.error(`Failed to arm "${b.name}" (${b.id}):`,c)}E.info(`Scheduler armed ${this.armed.size} execution(s)`)}async armExecution(a){var b,e;let f=a.trigger;switch(f.type){case"schedule":{let b=await A(a.id);b.lastScheduledFireAt?f.catchUp&&(0,j.hk)(f,b.lastScheduledFireAt)&&(await B(a.id,{...b,lastScheduledFireAt:new Date().toISOString()}),E.info(`Catch-up run for "${a.name}" (missed while closed)`),this.fire(a,{kind:"schedule-catchup",summary:"Schedule (missed while FLUJO was closed — ran once at startup)"})):await B(a.id,{...b,lastScheduledFireAt:new Date().toISOString()}),this.armed.set(a.id,(0,j.wv)(f,this.bindToWorkspace(()=>{(async()=>{let b=await A(a.id);await B(a.id,{...b,lastScheduledFireAt:new Date().toISOString()}),await this.fire(a,{kind:"schedule",summary:"Schedule"})})().catch(b=>E.error(`Scheduled fire failed for ${a.id}:`,b))})));break}case"webhook":break;case"file-watch":this.armed.set(a.id,function(a,b,c){let d,e=a.debounceMs??2e3,f=new Set(a.events),g=a.glob?.trim()?function(a){let b=a.replace(/\\/g,"/"),c="";for(let a=0;a<b.length;a++){let d=b[a];"*"===d?"*"===b[a+1]?"/"===b[++a+1]?(a++,c+="(?:.*/)?"):c+=".*":c+="[^/]*":"?"===d?c+="[^/]":c+=d.replace(/[.+^${}()|[\]\\]/g,"\\$&")}return RegExp(`^${c}$`)}(a.glob.trim()):null;try{d=m.realpathSync.native(a.path)}catch(d){let b=d instanceof Error?d.message:String(d);return o.warn(`Cannot watch "${a.path}": ${b}`),c(`Cannot watch "${a.path}": ${b}`),{dispose:()=>void 0}}let h=[],i=!1,j=null,k=!1,p=()=>{if(j=null,k||0===h.length)return;let a=h;i&&o.info("File-watch batch overflowed; reporting first 50 events"),h=[],i=!1,b({events:a})},q=(0,n.wB)(d,{ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:500,pollInterval:100}});return q.on("all",(a,b)=>{if(!k&&("add"===a||"change"===a||"unlink"===a)&&f.has(a)){if(g){let a=l().relative(d,b).replace(/\\/g,"/")||l().basename(b);if(!g.test(a))return}h.length>=50?i=!0:h.push({event:a,path:b}),j&&clearTimeout(j),j=setTimeout(p,e),j.unref?.()}}),q.on("error",a=>{let b=a instanceof Error?a.message:String(a);o.warn(`Watcher error for ${d}: ${b}`),c(b)}),{dispose:()=>{k=!0,j&&(clearTimeout(j),j=null),h=[],q.close().catch(a=>o.warn(`Failed to close watcher for ${d}:`,a))}}}(f,this.bindToWorkspace(({events:b})=>{this.lastTriggerErrors.delete(a.id),this.fire(a,{kind:"file",summary:1===b.length?`File ${"unlink"===b[0].event?"deleted":"add"===b[0].event?"added":"changed"}`:`${b.length} file changes`,context:{watchedPath:f.path,events:b}})}),this.bindToWorkspace(b=>this.lastTriggerErrors.set(a.id,b))));break;case"mcp-poll":let g,h,i,k,y,z,C;this.inWorkspace(async()=>{let{mcpService:b}=await Promise.all([c.e(6614),c.e(8775),c.e(4165),c.e(3133),c.e(1114),c.e(7798),c.e(531),c.e(4271),c.e(7492)]).then(c.bind(c,1930));await b.isServerDisabled(f.serverName)&&this.lastTriggerErrors.set(a.id,`MCP server '${f.serverName}' is disabled — enable it on the MCP page or change the trigger`)}).catch(b=>E.warn(`Arm-time disabled-server check failed for ${a.id}:`,b)),this.armed.set(a.id,(b={callTool:this.bindToWorkspace(async(a,b,d)=>{let{mcpService:e}=await Promise.all([c.e(6614),c.e(8775),c.e(4165),c.e(3133),c.e(1114),c.e(7798),c.e(531),c.e(4271),c.e(7492)]).then(c.bind(c,1930)),f=await e.callTool(a,b,d);return{success:!0===f.success,data:f.data,error:"string"==typeof f.error?f.error:void 0}}),loadState:this.bindToWorkspace(()=>A(a.id)),saveState:this.bindToWorkspace(async b=>{let c=await A(a.id);await B(a.id,{...c,...b})}),onFire:this.bindToWorkspace(async({summary:b,context:c})=>(this.lastTriggerErrors.delete(a.id),{status:(await this.fire(a,{kind:"mcp-poll",summary:b,context:c})).status})),onError:this.bindToWorkspace(b=>this.lastTriggerErrors.set(a.id,b)),onSuccess:this.bindToWorkspace(()=>this.lastTriggerErrors.delete(a.id)),evaluateAiGate:this.bindToWorkspace(async(a,b,d)=>{let{evaluateAiGate:e}=await c.e(5831).then(c.bind(c,65831));return e(a,b,d)})},g=f.cron||(0,q.X)(f.intervalMs),h=!1,i=!1,k=0,y=0,z=async()=>{if(!i&&!h){if(y>0)return void y--;h=!0;try{let a,c=await b.callTool(f.serverName,f.toolName,f.args);if(!c.success)throw Error(c.error||"Tool call failed");k=0;let d=await b.loadState(),e=f.evaluate;if(a="on-change"===e.mode?(0,r.Jl)(c.data,d):"new-items"===e.mode?(0,r.A1)(c.data,e.itemsPath,e.idField,d):b.evaluateAiGate?await b.evaluateAiGate(c.data,e,d):{fire:!1,newState:{},error:'The "AI decides" condition is not available yet'},i)return;if(Object.keys(a.newState).length>0&&await b.saveState(a.newState),a.error)b.onError(a.error);else if(a.fire){let{status:c}=await b.onFire({summary:`Watched tool: ${a.summary??"condition met"}`,context:{server:f.serverName,tool:f.toolName,..."object"==typeof a.context&&null!==a.context?a.context:{result:a.context}}});if(i)return;if(a.pendingState){let{giveUpError:e}=await (0,r.vV)({status:c,pendingState:a.pendingState,priorFailures:d.pendingFailures??0,saveState:b.saveState});e&&b.onError(e)}}else b.onSuccess?.()}catch(c){k++,y=Math.min(2**(k-1),8);let a=c instanceof Error?c.message:String(c);s.warn(`Poll failed for ${f.serverName}/${f.toolName} (backing off ${y} check(s)): ${a}`),b.onError(a)}finally{h=!1}}},C=new p.l4(g,{timezone:f.timezone,unref:!0},()=>void z()),z(),{dispose:()=>{i=!0,C.stop()},nextRun:()=>C.nextRun()?.toISOString()??null}));break;case"url-watch":let D,F,G,H,I;this.armed.set(a.id,(D=(e={loadState:this.bindToWorkspace(()=>A(a.id)),saveState:this.bindToWorkspace(async b=>{let c=await A(a.id);await B(a.id,{...c,...b})}),onFire:this.bindToWorkspace(async({summary:b,context:c})=>(this.lastTriggerErrors.delete(a.id),{status:(await this.fire(a,{kind:"url-watch",summary:b,context:c})).status})),onError:this.bindToWorkspace(b=>this.lastTriggerErrors.set(a.id,b)),onSuccess:this.bindToWorkspace(()=>this.lastTriggerErrors.delete(a.id))}).fetchImpl??fetch,F=!1,G=!1,H=async()=>{if(!G&&!F){F=!0;try{let a=await D(f.url,{redirect:"follow",headers:{"User-Agent":"FLUJO-url-watch"},signal:AbortSignal.timeout(3e4)});if(!a.ok)return void e.onError(`The URL answered with HTTP ${a.status}`);let b=await a.text(),c=(0,r.qq)(b),d=await e.loadState();if(G)return;if(!d.lastHash){await e.saveState({lastHash:c}),e.onSuccess?.();return}if(d.lastHash===c)return void e.onSuccess?.();let{status:g}=await e.onFire({summary:"Online content changed",context:{url:f.url,status:a.status,contentType:a.headers.get("content-type")??void 0,content:b.length>8192?`${b.slice(0,8192)}… (truncated, ${b.length} chars total)`:b}});if(G)return;let{giveUpError:h}=await (0,r.vV)({status:g,pendingState:{lastHash:c},priorFailures:d.pendingFailures??0,saveState:e.saveState});h&&e.onError(h)}catch(b){let a=b instanceof Error&&"TimeoutError"===b.name?"The URL did not answer within 30s":b instanceof Error?b.message:String(b);t.warn(`URL check failed for ${f.url}: ${a}`),e.onError(a)}finally{F=!1}}},I=new p.l4(f.cron,{timezone:f.timezone,unref:!0},()=>void H()),H(),{dispose:()=>{G=!0,I.stop()},nextRun:()=>I.nextRun()?.toISOString()??null}));break;case"flow-event":this.armed.set(a.id,function(a,b){let c=a.maxChainDepth??100,d="string"==typeof a.source.topic?a.source.topic.trim():"",e=d.length>0,f=0,g=null,h=!1;if(a.outputMatch?.regex)try{g=new RegExp(a.outputMatch.regex)}catch(c){h=!0;let a=`Invalid output-match regex: ${c instanceof Error?c.message:String(c)}`;v.warn(a),b.onError(a)}let i=b=>{if(!a.outputMatch)return!0;if(h)return!1;let c=(b??"").slice(0,16384);return(!a.outputMatch.contains||!!c.includes(a.outputMatch.contains))&&(!g||!!g.test(c))},j=(d,e,g,h)=>{if(d>=c){let a=`Flow-event chain reached the depth limit (${c}); not firing again`;v.info(a),b.onSkip(a);return}let i=Date.now();a.minIntervalMs&&i-f<a.minIntervalMs?v.debug(`Flow-event cooldown active (${a.minIntervalMs}ms); ignoring event`):(f=i,b.onFire({summary:e,context:g,chainDepth:d+1,sourceConversationId:h}))},k=(0,u.eh)().subscribe(c=>{try{let b;if(e){if(!(0,u.ru)(c)||c.topic!==d||!i(c.payload))return;j(c.chainDepth,`Signal "${c.topic}"`,{topic:c.topic,payload:w(c.payload),emitterFlowId:c.emitterFlowId,flowName:c.flowName,runId:c.runId,conversationId:c.conversationId,firedBy:c.firedBy},c.conversationId);return}if((0,u.ru)(c)||((b=a.source).executionId?c.executionId!==b.executionId:b.flowId?c.flowId!==b.flowId:!b.flowName||c.flowName!==b.flowName)||!c.status||!(a.on??[]).includes(c.status)||!i(c.outputText))return;let f=c.flowName??c.flowId;j(c.chainDepth,`Flow "${f}" ${c.status}`,{flowId:c.flowId,flowName:c.flowName,executionId:c.executionId,runId:c.runId,conversationId:c.conversationId,status:c.status,firedBy:c.firedBy,outputText:w(c.outputText),error:c.error},c.conversationId)}catch(c){let a=c instanceof Error?c.message:String(c);v.warn(`Flow-event handling failed: ${a}`),b.onError(a)}});return{dispose:()=>k(),nextRun:()=>null}}(f,{onFire:this.bindToWorkspace(({summary:b,context:c,chainDepth:d,sourceConversationId:e})=>{this.lastTriggerErrors.delete(a.id),this.fire(a,{kind:"flow-event",summary:b,context:c,chainDepth:d,parentConversationId:e}).catch(b=>E.error(`Flow-event fire failed for ${a.id}:`,b))}),onSkip:this.bindToWorkspace(b=>{let c=new Date().toISOString(),e=(0,d.A)();this.recordSchedulerSkip(a,e,b),(0,x.Hy)(a.id,{runId:e,conversationId:"",firedAt:c,finishedAt:c,status:"skipped",triggerSummary:"Flow event",error:b}).catch(b=>E.warn(`Failed to record flow-event skip for ${a.id}:`,b))}),onError:this.bindToWorkspace(b=>this.lastTriggerErrors.set(a.id,b))}));break;default:E.warn(`Trigger type "${f.type}" is not implemented — "${a.name}" not armed`)}}async loadFile(){let a=await (0,e.loadItem)(f.Zg.PLANNED_EXECUTIONS,F);return{version:1,paused:!0===a.paused,executions:Array.isArray(a.executions)?a.executions:[]}}async saveFile(a){await (0,e.VH)(f.Zg.PLANNED_EXECUTIONS,a)}async isPaused(){return(await this.loadFile()).paused}async setPaused(a){let b=await this.loadFile();if(await this.saveFile({...b,paused:a}),await this.reconcile(),a){for(let a of[...this.queued.keys()])await this.cancelQueued(a,"scheduler paused",!0);await this.cancelAllExclusiveWaiting("scheduler paused",!0)}}async list(){return Promise.all((await this.loadFile()).executions.map(async a=>({execution:a,status:this.getStatus(a),lastRun:await (0,x.tl)(a.id)})))}async get(a){return(await this.loadFile()).executions.find(b=>b.id===a)??null}async create(a){let b=this.validateInput(a);if(b)return{error:b};if(void 0!==a.id&&!/^[A-Za-z0-9._:-]{1,128}$/.test(a.id))return{error:"The id must be 1-128 characters of letters, digits, dot, underscore, colon or hyphen"};if("."===a.id||".."===a.id)return{error:'The id must be a safe identifier, not "." or ".."'};let c=new Date().toISOString(),e={...a,folder:a.folder?.trim()||void 0,trigger:this.normalizeTrigger(a.trigger),id:a.id??(0,d.A)(),createdAt:c,updatedAt:c},f=await this.loadFile();return f.executions.some(a=>a.id===e.id)?{error:`A planned execution with id "${e.id}" already exists`,conflict:!0}:(await this.saveFile({...f,executions:[...f.executions,e]}),await this.reconcile(),{execution:e})}async update(a,b){let c=await this.loadFile(),d=c.executions.findIndex(b=>b.id===a);if(d<0)return{error:`No planned execution with id "${a}"`};let e=b.folder;if(Object.prototype.hasOwnProperty.call(b,"folder")&&void 0!==e&&"string"!=typeof e)return{error:"Folder must be text"};let f={...c.executions[d],...b,...Object.prototype.hasOwnProperty.call(b,"folder")?{folder:"string"==typeof e&&e.trim()||void 0}:{},...b.trigger?{trigger:this.normalizeTrigger(b.trigger)}:{},id:a,createdAt:c.executions[d].createdAt,updatedAt:new Date().toISOString()},g=this.validateInput(f);if(g)return{error:g};let h=[...c.executions];return h[d]=f,await this.saveFile({...c,executions:h}),Object.keys(b).some(a=>"folder"!==a)&&(await this.reconcile(),await this.cancelQueued(a,"execution updated",!0),await this.cancelExclusiveWaiting(a,"execution updated",!0)),{execution:f}}async delete(a){let b=await this.loadFile();return b.executions.some(b=>b.id===a)?(await this.saveFile({...b,executions:b.executions.filter(b=>b.id!==a)}),await this.reconcile(),this.lastTriggerErrors.delete(a),await this.cancelQueued(a,"execution deleted",!1),await this.cancelExclusiveWaiting(a,"execution deleted",!1),await (0,x.xC)(a),await C(a),{success:!0}):{success:!1,error:`No planned execution with id "${a}"`}}normalizeTrigger(a){return a?.type!=="webhook"||a.token?a?.type!=="mcp-poll"||a.cron?a:{...a,cron:(0,q.X)(a.intervalMs)}:{...a,token:(0,d.A)()}}validateInput(a){if(!a.name?.trim())return"A name is required";if(void 0!==a.folder&&"string"!=typeof a.folder)return"Folder must be text";if(a.folder&&a.folder.trim().length>120)return"Folder must be 120 characters or fewer";if(!a.flowId)return"A flow is required";if("string"!=typeof a.prompt)return"A prompt is required (may be empty)";if(void 0!==a.overlapStrategy&&!["skip","queue","parallel","error"].includes(a.overlapStrategy))return"Overlap strategy must be one of: skip, queue, parallel, error";if(void 0!==a.exclusive&&"boolean"!=typeof a.exclusive)return"Exclusive must be true or false";if(void 0!==a.nonExclusiveBehavior&&!["queue","skip","error"].includes(a.nonExclusiveBehavior))return"When exclusive is on, other triggers must be one of: queue, skip, error";let b=a.trigger;if(!b||"object"!=typeof b)return"A trigger is required";switch(b.type){case"schedule":{let a=(0,j.O9)(b.cron,b.timezone);return a.valid?null:`Invalid schedule: ${a.error}`}case"webhook":return null;case"file-watch":if(!b.path?.trim())return"A folder or file path to watch is required";if(!Array.isArray(b.events)||0===b.events.length)return"At least one file event is required";return null;case"mcp-poll":if(!b.serverName||!b.toolName)return"A server and tool are required";if(b.cron){let a=(0,j.O9)(b.cron,b.timezone);if(!a.valid)return`Invalid schedule: ${a.error}`}if(b.evaluate?.mode==="new-items"&&!b.evaluate.idField?.trim())return"An id field is required to detect new items";if((b.evaluate?.mode==="llm-gate"||b.evaluate?.mode==="flow-gate")&&!b.evaluate.condition?.trim())return"A condition is required for the AI to check";if(b.evaluate?.mode==="llm-gate"&&!b.evaluate.modelId)return"A model is required to check the condition";if(b.evaluate?.mode==="flow-gate"&&!b.evaluate.flowId)return"A flow is required to check the condition";return null;case"url-watch":{try{let a=new URL(b.url??"");if("http:"!==a.protocol&&"https:"!==a.protocol)return"The URL must start with http:// or https://"}catch{return"A valid URL is required"}let a=(0,j.O9)(b.cron,b.timezone);return a.valid?null:`Invalid schedule: ${a.error}`}case"flow-event":{let a=b.source;if(1!==[a?.executionId,a?.flowId,a?.flowName,a?.topic].filter(a=>"string"==typeof a&&a.trim().length>0).length)return"Choose exactly one source: a flow, a planned execution, or a signal topic";if(!("string"==typeof a?.topic&&a.topic.trim().length>0)){if(!Array.isArray(b.on)||0===b.on.length)return"Select at least one outcome to react to (completed or error)";if(b.on.some(a=>"completed"!==a&&"error"!==a))return'Outcomes must be "completed" or "error"'}if(b.outputMatch?.regex)try{new RegExp(b.outputMatch.regex)}catch(a){return`Invalid output-match regex: ${a instanceof Error?a.message:String(a)}`}if(void 0!==b.maxChainDepth&&(!Number.isInteger(b.maxChainDepth)||b.maxChainDepth<1))return"Max chain depth must be a positive whole number";if(void 0!==b.minIntervalMs&&(!Number.isFinite(b.minIntervalMs)||b.minIntervalMs<0))return"Minimum interval must be zero or more milliseconds";return null}default:return"Unknown trigger type"}}isRunning(a){let b=this.running.get(a);return void 0!==b&&b.size>0}addRunning(a,b,c){let d=this.running.get(a);d||(d=new Map,this.running.set(a,d)),d.set(b,c)}removeRunning(a,b){let c=this.running.get(a);c&&(c.delete(b),0===c.size&&this.running.delete(a))}earliestRunningSince(a){let b,c=this.running.get(a);if(c&&0!==c.size){for(let a of c.values())(void 0===b||a<b)&&(b=a);return b}}skippedRecord(a,b){let c=new Date().toISOString();return this.recordSchedulerSkip(a.execution,a.runId,b),{runId:a.runId,conversationId:"",firedAt:c,finishedAt:c,status:"skipped",triggerSummary:a.payload.summary,error:b}}recordSchedulerFire(a,b,c,d){(0,D.z9)((0,D.k)({type:"scheduler.fire",runId:b,source:"schedule",plannedExecution:{id:a.id,name:a.name},outcome:c,...d?{conversationId:d}:{}}))}recordSchedulerSkip(a,b,c){(0,D.z9)((0,D.k)({type:"scheduler.skip",runId:b,source:"schedule",plannedExecution:{id:a.id,name:a.name},reason:(0,D.bW)(c)}))}async cancelQueued(a,b,c){let d=this.queued.get(a);if(d&&0!==d.length){for(let e of(this.queued.delete(a),d)){let d=this.skippedRecord(e,b);if(c)try{await (0,x.Hy)(a,d)}catch(b){E.warn(`Failed to record cancelled queued fire for ${a}:`,b)}e.resolve(d)}E.info(`Cancelled ${d.length} queued fire(s) for ${a}: ${b}`)}}drainQueue(a){let b=this.queued.get(a);if(!b||0===b.length||this.isRunning(a))return;let c=b.shift();0===b.length&&this.queued.delete(a),c&&(async()=>{let b=await this.get(a);if(!b||!b.enabled||this.pausedCache){let a=b?b.enabled?"scheduler paused":"execution disabled":"execution deleted";c.resolve(this.skippedRecord(c,a));return}let d=await this.fire(b,c.payload,c.runId);c.resolve(d)})().catch(b=>E.error(`Queued fire failed for ${a}:`,b))}isSchedulerIdle(){for(let a of this.running.values())if(a.size>0)return!1;return!0}isExclusiveActive(){return null!==this.exclusiveHolder||this.exclusiveWaiting.length>0}currentExclusiveBehavior(){return null!==this.exclusiveHolder?this.exclusiveHolderBehavior:this.exclusiveWaiting[0]?.execution.nonExclusiveBehavior??"queue"}exclusiveGateFor(a){return!0!==a.exclusive&&this.isExclusiveActive()?this.currentExclusiveBehavior():null}drainExclusive(){null===this.exclusiveHolder&&this.exclusiveWaiting.length>0&&this.isSchedulerIdle()?this.acquireNextExclusive():this.isExclusiveActive()||this.drainBlockedByExclusive()}acquireNextExclusive(){if(null!==this.exclusiveHolder||!this.isSchedulerIdle())return;let a=this.exclusiveWaiting.shift();if(!a)return;let b=a.execution.id;this.exclusiveHolder=b,this.exclusiveHolderBehavior=a.execution.nonExclusiveBehavior??"queue",(async()=>{let c=await this.get(b);if(!c||!c.enabled||this.pausedCache||!0!==c.exclusive){let d=c?c.enabled?this.pausedCache?"scheduler paused":"no longer exclusive":"execution disabled":"execution deleted";this.exclusiveHolder===b&&(this.exclusiveHolder=null),a.resolve(this.skippedRecord(a,d)),this.drainExclusive();return}this.exclusiveHolderBehavior=c.nonExclusiveBehavior??"queue";let d=await this.fire(c,a.payload,a.runId);a.resolve(d)})().catch(c=>{this.exclusiveHolder===b&&(this.exclusiveHolder=null),E.error(`Exclusive acquire failed for ${b}:`,c),a.resolve(this.skippedRecord(a,"exclusive acquire failed")),this.drainExclusive()})}drainBlockedByExclusive(){if(0===this.blockedByExclusive.length)return;let a=this.blockedByExclusive;for(let b of(this.blockedByExclusive=[],a))(async()=>{let a=await this.get(b.execution.id);if(!a||!a.enabled||this.pausedCache){let c=a?a.enabled?"scheduler paused":"execution disabled":"execution deleted";b.resolve(this.skippedRecord(b,c));return}let c=await this.fire(a,b.payload,b.runId);b.resolve(c)})().catch(a=>E.error(`Deferred non-exclusive fire failed for ${b.execution.id}:`,a))}async cancelExclusiveWaiting(a,b,c){let d=[];if(this.exclusiveWaiting=this.exclusiveWaiting.filter(b=>b.execution.id!==a||(d.push(b),!1)),this.blockedByExclusive=this.blockedByExclusive.filter(b=>b.execution.id!==a||(d.push(b),!1)),0!==d.length){for(let e of d){let d=this.skippedRecord(e,b);if(c)try{await (0,x.Hy)(a,d)}catch(b){E.warn(`Failed to record cancelled exclusive fire for ${a}:`,b)}e.resolve(d)}E.info(`Cancelled ${d.length} exclusive-related fire(s) for ${a}: ${b}`)}}async cancelAllExclusiveWaiting(a,b){let c=[...this.exclusiveWaiting,...this.blockedByExclusive];if(this.exclusiveWaiting=[],this.blockedByExclusive=[],0!==c.length){for(let d of c){let c=this.skippedRecord(d,a);if(b)try{await (0,x.Hy)(d.execution.id,c)}catch(a){E.warn(`Failed to record cancelled exclusive fire for ${d.execution.id}:`,a)}d.resolve(c)}E.info(`Cancelled ${c.length} exclusive-related fire(s): ${a}`)}}getStatus(a){let b=this.armed.get(a.id),c=void 0!==b||a.enabled&&"webhook"===a.trigger.type&&this.started&&!this.pausedCache,d=this.earliestRunningSince(a.id),e=c?void 0:a.enabled?this.pausedCache?"paused":void 0:"disabled",f=this.exclusiveHolder??void 0,g=!0!==a.exclusive&&this.isExclusiveActive();return{armed:c,notArmedReason:e,nextRun:b?.nextRun?b.nextRun():void 0,lastTriggerError:this.lastTriggerErrors.get(a.id),running:void 0!==d,runningSince:d,exclusiveHolderId:f,blockedByExclusive:g}}async runNow(a){let b=await this.get(a);return b?{record:await this.fire(b,{kind:"manual",summary:"Manual run"},(0,d.A)(),!0)}:{error:`No planned execution with id "${a}"`}}fire(a,b,c=(0,d.A)(),e=!1){return this.inWorkspace(()=>this.fireInternal(a,b,c,e))}async fireInternal(a,b,e=(0,d.A)(),f=!1){let g,i=new Date().toISOString();if(await (0,h.isEncryptionLocked)()){let c={runId:e,conversationId:"",firedAt:i,finishedAt:i,status:"skipped",triggerSummary:b.summary,error:"encryption locked"};return this.recordSchedulerSkip(a,e,c.error),await (0,x.Hy)(a.id,c),E.info(`Skipped fire for "${a.name}" — encryption locked`),c}let j="flow-event"===b.kind;if(!f&&!j){if(!0===a.exclusive){if(this.exclusiveHolder!==a.id){if(null!==this.exclusiveHolder||!this.isSchedulerIdle()){let c=this.exclusiveWaiting.length;if(c>=G.MAX_QUEUE_DEPTH){let c={runId:e,conversationId:"",firedAt:i,finishedAt:i,status:"skipped",triggerSummary:b.summary,error:`Exclusive wait queue full (cap ${G.MAX_QUEUE_DEPTH}) — fire dropped`};return this.recordSchedulerSkip(a,e,c.error),await (0,x.Hy)(a.id,c),E.warn(`Exclusive wait queue full for "${a.name}" — dropped fire`),c}return E.info(`Exclusive "${a.name}" waiting for scheduler to idle (depth ${c+1})`),this.recordSchedulerFire(a,e,"queued"),new Promise(c=>{this.exclusiveWaiting.push({execution:a,payload:b,runId:e,resolve:c})})}this.exclusiveHolder=a.id,this.exclusiveHolderBehavior=a.nonExclusiveBehavior??"queue",E.info(`Exclusive "${a.name}" acquired the scheduler lock`)}}else if(this.isExclusiveActive()){let c=this.currentExclusiveBehavior();if("skip"===c){let c={runId:e,conversationId:"",firedAt:i,finishedAt:i,status:"skipped",triggerSummary:b.summary,error:"Skipped — an exclusive execution holds the scheduler lock"};return this.recordSchedulerSkip(a,e,c.error),await (0,x.Hy)(a.id,c),E.info(`Skipped non-exclusive fire for "${a.name}" — exclusive lock held`),c}if("error"===c){let c={runId:e,conversationId:"",firedAt:i,finishedAt:i,status:"error",triggerSummary:b.summary,error:"Rejected — an exclusive execution holds the scheduler lock"};return await (0,x.Hy)(a.id,c),E.info(`Rejected non-exclusive fire for "${a.name}" — exclusive lock held`),c}let d=this.blockedByExclusive.length;if(d>=G.MAX_QUEUE_DEPTH){let c={runId:e,conversationId:"",firedAt:i,finishedAt:i,status:"skipped",triggerSummary:b.summary,error:`Exclusive-block queue full (cap ${G.MAX_QUEUE_DEPTH}) — fire dropped`};return this.recordSchedulerSkip(a,e,c.error),await (0,x.Hy)(a.id,c),E.warn(`Exclusive-block queue full for "${a.name}" — dropped fire`),c}return E.info(`Deferred non-exclusive fire for "${a.name}" — exclusive lock held (depth ${d+1})`),this.recordSchedulerFire(a,e,"queued"),new Promise(c=>{this.blockedByExclusive.push({execution:a,payload:b,runId:e,resolve:c})})}}let k=a.overlapStrategy??"skip";if(!f&&this.isRunning(a.id)){if("skip"===k){let c={runId:e,conversationId:"",firedAt:i,finishedAt:i,status:"skipped",triggerSummary:b.summary,error:"Previous run still in progress"};return this.recordSchedulerSkip(a,e,c.error),await (0,x.Hy)(a.id,c),E.info(`Skipped overlapping fire for "${a.name}"`),c}if("error"===k){let c={runId:e,conversationId:"",firedAt:i,finishedAt:i,status:"error",triggerSummary:b.summary,error:"Overlapping run rejected (overlapStrategy=error)"};return await (0,x.Hy)(a.id,c),E.info(`Rejected overlapping fire for "${a.name}" (overlapStrategy=error)`),c}if("queue"===k){let c=this.queued.get(a.id)?.length??0;if(c>=G.MAX_QUEUE_DEPTH){let c={runId:e,conversationId:"",firedAt:i,finishedAt:i,status:"skipped",triggerSummary:b.summary,error:`Overlap queue full (cap ${G.MAX_QUEUE_DEPTH}) — fire dropped`};return this.recordSchedulerSkip(a,e,c.error),await (0,x.Hy)(a.id,c),E.warn(`Overlap queue full for "${a.name}" — dropped fire`),c}return E.info(`Queued overlapping fire for "${a.name}" (depth ${c+1})`),this.recordSchedulerFire(a,e,"queued"),new Promise(c=>{let d=this.queued.get(a.id)??[];d.push({execution:a,payload:b,runId:e,resolve:c}),this.queued.set(a.id,d)})}}this.addRunning(a.id,e,i);let l=(0,d.A)();this.recordSchedulerFire(a,e,"fired",l);try{E.info(`Firing "${a.name}" (${b.kind})`);let d=await (0,x.Sw)(a.id),f=d.length>0?d[d.length-1]:null,h={executionName:a.name,trigger:b.kind,now:i,timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,lastRun:f?{at:f.firedAt,status:f.status}:null,nextPlannedRun:this.getStatus(a).nextRun??null},j=a.approvalPolicy??"auto",k=a.saveConversations||"pause"===j?"conversation":"ephemeral",{runFlow:m}=await Promise.all([c.e(6614),c.e(8775),c.e(4165),c.e(3133),c.e(1114),c.e(7798),c.e(531),c.e(4271),c.e(1346),c.e(9592),c.e(5111)]).then(c.bind(c,79592)),n=await m({flowId:a.flowId,prompt:this.composePrompt(a.prompt,b,h),mode:k,conversationId:l,runId:e,source:"schedule",plannedExecutionId:a.id,plannedExecutionName:a.name,parentRunId:b.parentConversationId,chainDepth:b.chainDepth??0,requireApproval:"auto"!==j,onApprovalRequired:j,debug:!1,userTurn:!0});g=await this.recordFromResult(a,n,{runId:e,conversationId:l,firedAt:i,payload:b})}catch(c){g={runId:e,conversationId:l,firedAt:i,finishedAt:new Date().toISOString(),status:"error",triggerSummary:b.summary,error:c instanceof Error?c.message:String(c)},E.error(`Run crashed for "${a.name}":`,c)}finally{this.removeRunning(a.id,e),this.exclusiveHolder!==a.id||this.isRunning(a.id)||(this.exclusiveHolder=null,E.info(`Exclusive "${a.name}" released the scheduler lock`)),this.drainExclusive(),this.drainQueue(a.id)}return await this.get(a.id)===null?E.info(`Dropping run record for deleted execution ${a.id}`):(await (0,x.Hy)(a.id,g),("completed"===g.status||"error"===g.status)&&await this.publishFlowRunEvent(a,g,b)),g}async recordFromResult(a,b,c){let{runId:d,conversationId:e,firedAt:f,payload:g}=c,h=new Date().toISOString(),i="awaiting_tool_approval"===b.status,j="error"===b.status&&b.error?.details?.type==="approval_required";if(i||j){let c=(b.pendingToolCalls??[]).map(a=>({id:a.id,name:"function"===a.type?a.function.name:String(a.type)})),k={runId:d,conversationId:e,firedAt:f,finishedAt:h,status:"needs_approval",triggerSummary:g.summary,outputText:this.truncateOutput(b.outputText),usage:b.usage,error:j?b.error?.message??"Tool approval required":"Awaiting tool approval",pendingApproval:{tool:c[0]?.name??b.error?.details?.name,toolCallId:c[0]?.id,pendingToolCalls:c.length>0?c:void 0}};return i&&await this.registerPendingApproval(a,k,c),k}return{runId:d,conversationId:e,firedAt:f,finishedAt:h,status:"completed"===b.status?"completed":"capped"===b.status?"capped":"error",triggerSummary:g.summary,outputText:this.truncateOutput(b.outputText),usage:b.usage,error:"completed"===b.status||"capped"===b.status?void 0:b.error?.message??`Run ended with status "${b.status}"`}}async registerPendingApproval(a,b,d){try{let e;try{let{flowService:b}=await c.e(1114).then(c.bind(c,71114));e=(await b.getFlow(a.flowId))?.name??void 0}catch(b){E.debug(`Could not resolve flow name for pending approval (${a.flowId}):`,b)}let{putPendingApproval:f}=await c.e(3356).then(c.bind(c,93356));await f({approvalId:b.conversationId,conversationId:b.conversationId,plannedExecutionId:a.id,flowId:a.flowId,flowName:e,runId:b.runId,triggerSummary:b.triggerSummary,pendingToolCalls:d,createdAt:b.firedAt})}catch(b){E.warn(`Failed to register pending approval for "${a.name}":`,b)}}async publishFlowRunEvent(a,b,d){try{let e;try{let{flowService:b}=await c.e(1114).then(c.bind(c,71114));e=(await b.getFlow(a.flowId))?.name??void 0}catch(b){E.debug(`Could not resolve flow name for run event (${a.flowId}):`,b)}let f="schedule-catchup"===d.kind?"schedule":d.kind;(0,u.eh)().publish({flowId:a.flowId,flowName:e,executionId:a.id,runId:b.runId,conversationId:b.conversationId,status:"completed"===b.status?"completed":"error",outputText:b.outputText,error:b.error,firedBy:f,chainDepth:d.chainDepth??0,timestamp:b.finishedAt??new Date().toISOString()})}catch(b){E.warn(`Failed to publish flow-run event for "${a.name}":`,b)}}composePrompt(a,b,c){let d=JSON.stringify(void 0===b.context?c:{...c,data:b.context},null,2);return`${a}
|
|
1
|
+
"use strict";exports.id=5354,exports.ids=[5354],exports.modules={50306:(a,b,c)=>{c.d(b,{O9:()=>e,Z9:()=>f,hk:()=>g,wv:()=>h});var d=c(45481);function e(a,b){try{let c=new d.l4(a,{timezone:b,paused:!0});return c.nextRun(),c.stop(),{valid:!0}}catch(a){return{valid:!1,error:a instanceof Error?a.message:"Invalid cron pattern"}}}function f(a,b,c){let e=new d.l4(a,{timezone:b,paused:!0});try{return e.nextRuns(c).map(a=>a.toISOString())}finally{e.stop()}}function g(a,b){let c=new d.l4(a.cron,{timezone:a.timezone,paused:!0});try{let a=c.nextRun(new Date(b));return null!==a&&a.getTime()<=Date.now()}finally{c.stop()}}function h(a,b){let c=new d.l4(a.cron,{timezone:a.timezone,unref:!0},b);return{dispose:()=>c.stop(),nextRun:()=>c.nextRun()?.toISOString()??null}}},50960:(a,b,c)=>{c.d(b,{A1:()=>k,Je:()=>i,Jl:()=>j,qq:()=>f,vV:()=>g});var d=c(55511);function e(a){return JSON.stringify(function a(b){if(Array.isArray(b))return b.map(a);if(null!==b&&"object"==typeof b){let c=Object.entries(b).sort(([a],[b])=>a<b?-1:+(a>b)),d={};for(let[b,e]of c)d[b]=a(e);return d}return b}(a))}function f(a){return(0,d.createHash)("sha256").update(e(a)??"undefined").digest("hex")}async function g(a){let{status:b,pendingState:c,priorFailures:d,saveState:e}=a;if("completed"===b)return await e({...c,...d>0?{pendingFailures:0}:{}}),{giveUpError:null};if("skipped"===b)return{giveUpError:null};let f=d+1;return f>=3?(await e({...c,pendingFailures:0}),{giveUpError:"Detected a change but the flow failed to process it 3\xd7 — skipping it to avoid a loop"}):(await e({pendingFailures:f}),{giveUpError:null})}function h(a,b){if(!b)return a;let c=a;for(let a of b.split(".")){if(null==c||"object"!=typeof c)return;c=c[a]}return c}function i(a){let b=e(a)??"";return b.length<=8192?a:{truncated:!0,note:`Result too large to include fully (${b.length} chars); this is a preview.`,preview:b.slice(0,8192)}}function j(a,b){let c=f(a);return b.lastHash?b.lastHash===c?{fire:!1,newState:{}}:{fire:!0,summary:"Tool result changed",context:{result:i(a)},newState:{},pendingState:{lastHash:c}}:{fire:!1,newState:{lastHash:c}}}function k(a,b,c,d){let e=h(a,b);if(!Array.isArray(e))return{fire:!1,newState:{},error:`"${b||"(root)"}" did not resolve to a list in the tool result`};let g=e.map(a=>{let b=h(a,c);return{id:null==b||"object"==typeof b?`hash:${f(a)}`:String(b),item:a}}),j=d.seenIds,k=g.map(({id:a})=>a),l=(a,b)=>{let c=[...a??[]],d=new Set(c);for(let a of b)d.has(a)||(d.add(a),c.push(a));return c.slice(-1e3)};if(!j)return{fire:!1,newState:{seenIds:l(void 0,k)}};let m=new Set(j),n=g.filter(({id:a})=>!m.has(a));if(0===n.length)return{fire:!1,newState:{}};let o=n.slice(0,50);return{fire:!0,summary:1===n.length?"1 new item":`${n.length} new items`,context:{newItems:i(o.map(({item:a})=>a)),...n.length>50?{omitted:n.length-50}:{}},newState:{},pendingState:{seenIds:l(j,o.map(({id:a})=>a))}}}},65354:(a,b,c)=>{c.d(b,{getSchedulerService:()=>H});var d=c(78796),e=c(65445),f=c(74755),g=c(66844),h=c(63078),i=c(7986),j=c(50306),k=c(33873),l=c.n(k),m=c(29021),n=c(84314);let o=(0,g.h)("backend/services/scheduler/triggers/fileWatch");var p=c(45481),q=c(86057),r=c(50960);let s=(0,g.h)("backend/services/scheduler/triggers/mcpPoll"),t=(0,g.h)("backend/services/scheduler/triggers/urlWatch");var u=c(46702);let v=(0,g.h)("backend/services/scheduler/triggers/flowEvent");function w(a){return a&&a.length>8192?`${a.slice(0,8192)}… (truncated)`:a}var x=c(78286);let y=(0,g.h)("backend/services/scheduler/state"),z=a=>`planned-execution-state/${a}`;async function A(a){try{return await (0,e.loadItem)(z(a),{})}catch(b){return y.error(`Failed to load trigger state for ${a}:`,b),{}}}async function B(a,b){await (0,e.VH)(z(a),b)}async function C(a){await (0,e.N2)(z(a))}var D=c(8619);let E=(0,g.h)("backend/services/scheduler/index"),F={version:1,paused:!1,executions:[]};class G{static{this.MAX_QUEUE_DEPTH=50}inWorkspace(a){return(0,i.runWithWorkspace)(this.workspace,a)}bindToWorkspace(a){return(...b)=>this.inWorkspace(()=>a(...b))}async start(){this.started||(this.started=!0,E.info("Starting scheduler"),await this.reconcile())}reconcile(){let a=this.reconcileChain.catch(()=>{}).then(()=>this.inWorkspace(()=>this.doReconcile()));return this.reconcileChain=a,a}async doReconcile(){for(let[a,b]of this.armed)try{b.dispose()}catch(b){E.warn(`Failed to dispose trigger for ${a}:`,b)}this.armed.clear();let a=await this.loadFile();if(this.pausedCache=a.paused,a.paused)return void E.info("Scheduler is paused — nothing armed");for(let b of a.executions)if(b.enabled)try{await this.armExecution(b)}catch(c){let a=c instanceof Error?c.message:String(c);this.lastTriggerErrors.set(b.id,a),E.error(`Failed to arm "${b.name}" (${b.id}):`,c)}E.info(`Scheduler armed ${this.armed.size} execution(s)`)}async armExecution(a){var b,e;let f=a.trigger;switch(f.type){case"schedule":{let b=await A(a.id);b.lastScheduledFireAt?f.catchUp&&(0,j.hk)(f,b.lastScheduledFireAt)&&(await B(a.id,{...b,lastScheduledFireAt:new Date().toISOString()}),E.info(`Catch-up run for "${a.name}" (missed while closed)`),this.fire(a,{kind:"schedule-catchup",summary:"Schedule (missed while FLUJO was closed — ran once at startup)"})):await B(a.id,{...b,lastScheduledFireAt:new Date().toISOString()}),this.armed.set(a.id,(0,j.wv)(f,this.bindToWorkspace(()=>{(async()=>{let b=await A(a.id);await B(a.id,{...b,lastScheduledFireAt:new Date().toISOString()}),await this.fire(a,{kind:"schedule",summary:"Schedule"})})().catch(b=>E.error(`Scheduled fire failed for ${a.id}:`,b))})));break}case"webhook":break;case"file-watch":this.armed.set(a.id,function(a,b,c){let d,e=a.debounceMs??2e3,f=new Set(a.events),g=a.glob?.trim()?function(a){let b=a.replace(/\\/g,"/"),c="";for(let a=0;a<b.length;a++){let d=b[a];"*"===d?"*"===b[a+1]?"/"===b[++a+1]?(a++,c+="(?:.*/)?"):c+=".*":c+="[^/]*":"?"===d?c+="[^/]":c+=d.replace(/[.+^${}()|[\]\\]/g,"\\$&")}return RegExp(`^${c}$`)}(a.glob.trim()):null;try{d=m.realpathSync.native(a.path)}catch(d){let b=d instanceof Error?d.message:String(d);return o.warn(`Cannot watch "${a.path}": ${b}`),c(`Cannot watch "${a.path}": ${b}`),{dispose:()=>void 0}}let h=[],i=!1,j=null,k=!1,p=()=>{if(j=null,k||0===h.length)return;let a=h;i&&o.info("File-watch batch overflowed; reporting first 50 events"),h=[],i=!1,b({events:a})},q=(0,n.wB)(d,{ignoreInitial:!0,awaitWriteFinish:{stabilityThreshold:500,pollInterval:100}});return q.on("all",(a,b)=>{if(!k&&("add"===a||"change"===a||"unlink"===a)&&f.has(a)){if(g){let a=l().relative(d,b).replace(/\\/g,"/")||l().basename(b);if(!g.test(a))return}h.length>=50?i=!0:h.push({event:a,path:b}),j&&clearTimeout(j),j=setTimeout(p,e),j.unref?.()}}),q.on("error",a=>{let b=a instanceof Error?a.message:String(a);o.warn(`Watcher error for ${d}: ${b}`),c(b)}),{dispose:()=>{k=!0,j&&(clearTimeout(j),j=null),h=[],q.close().catch(a=>o.warn(`Failed to close watcher for ${d}:`,a))}}}(f,this.bindToWorkspace(({events:b})=>{this.lastTriggerErrors.delete(a.id),this.fire(a,{kind:"file",summary:1===b.length?`File ${"unlink"===b[0].event?"deleted":"add"===b[0].event?"added":"changed"}`:`${b.length} file changes`,context:{watchedPath:f.path,events:b}})}),this.bindToWorkspace(b=>this.lastTriggerErrors.set(a.id,b))));break;case"mcp-poll":let g,h,i,k,y,z,C;this.inWorkspace(async()=>{let{mcpService:b}=await Promise.all([c.e(6614),c.e(8775),c.e(4165),c.e(3133),c.e(1114),c.e(531),c.e(7798),c.e(2126),c.e(7492)]).then(c.bind(c,1930));await b.isServerDisabled(f.serverName)&&this.lastTriggerErrors.set(a.id,`MCP server '${f.serverName}' is disabled — enable it on the MCP page or change the trigger`)}).catch(b=>E.warn(`Arm-time disabled-server check failed for ${a.id}:`,b)),this.armed.set(a.id,(b={callTool:this.bindToWorkspace(async(a,b,d)=>{let{mcpService:e}=await Promise.all([c.e(6614),c.e(8775),c.e(4165),c.e(3133),c.e(1114),c.e(531),c.e(7798),c.e(2126),c.e(7492)]).then(c.bind(c,1930)),f=await e.callTool(a,b,d);return{success:!0===f.success,data:f.data,error:"string"==typeof f.error?f.error:void 0}}),loadState:this.bindToWorkspace(()=>A(a.id)),saveState:this.bindToWorkspace(async b=>{let c=await A(a.id);await B(a.id,{...c,...b})}),onFire:this.bindToWorkspace(async({summary:b,context:c})=>(this.lastTriggerErrors.delete(a.id),{status:(await this.fire(a,{kind:"mcp-poll",summary:b,context:c})).status})),onError:this.bindToWorkspace(b=>this.lastTriggerErrors.set(a.id,b)),onSuccess:this.bindToWorkspace(()=>this.lastTriggerErrors.delete(a.id)),evaluateAiGate:this.bindToWorkspace(async(a,b,d)=>{let{evaluateAiGate:e}=await c.e(5831).then(c.bind(c,65831));return e(a,b,d)})},g=f.cron||(0,q.X)(f.intervalMs),h=!1,i=!1,k=0,y=0,z=async()=>{if(!i&&!h){if(y>0)return void y--;h=!0;try{let a,c=await b.callTool(f.serverName,f.toolName,f.args);if(!c.success)throw Error(c.error||"Tool call failed");k=0;let d=await b.loadState(),e=f.evaluate;if(a="on-change"===e.mode?(0,r.Jl)(c.data,d):"new-items"===e.mode?(0,r.A1)(c.data,e.itemsPath,e.idField,d):b.evaluateAiGate?await b.evaluateAiGate(c.data,e,d):{fire:!1,newState:{},error:'The "AI decides" condition is not available yet'},i)return;if(Object.keys(a.newState).length>0&&await b.saveState(a.newState),a.error)b.onError(a.error);else if(a.fire){let{status:c}=await b.onFire({summary:`Watched tool: ${a.summary??"condition met"}`,context:{server:f.serverName,tool:f.toolName,..."object"==typeof a.context&&null!==a.context?a.context:{result:a.context}}});if(i)return;if(a.pendingState){let{giveUpError:e}=await (0,r.vV)({status:c,pendingState:a.pendingState,priorFailures:d.pendingFailures??0,saveState:b.saveState});e&&b.onError(e)}}else b.onSuccess?.()}catch(c){k++,y=Math.min(2**(k-1),8);let a=c instanceof Error?c.message:String(c);s.warn(`Poll failed for ${f.serverName}/${f.toolName} (backing off ${y} check(s)): ${a}`),b.onError(a)}finally{h=!1}}},C=new p.l4(g,{timezone:f.timezone,unref:!0},()=>void z()),z(),{dispose:()=>{i=!0,C.stop()},nextRun:()=>C.nextRun()?.toISOString()??null}));break;case"url-watch":let D,F,G,H,I;this.armed.set(a.id,(D=(e={loadState:this.bindToWorkspace(()=>A(a.id)),saveState:this.bindToWorkspace(async b=>{let c=await A(a.id);await B(a.id,{...c,...b})}),onFire:this.bindToWorkspace(async({summary:b,context:c})=>(this.lastTriggerErrors.delete(a.id),{status:(await this.fire(a,{kind:"url-watch",summary:b,context:c})).status})),onError:this.bindToWorkspace(b=>this.lastTriggerErrors.set(a.id,b)),onSuccess:this.bindToWorkspace(()=>this.lastTriggerErrors.delete(a.id))}).fetchImpl??fetch,F=!1,G=!1,H=async()=>{if(!G&&!F){F=!0;try{let a=await D(f.url,{redirect:"follow",headers:{"User-Agent":"FLUJO-url-watch"},signal:AbortSignal.timeout(3e4)});if(!a.ok)return void e.onError(`The URL answered with HTTP ${a.status}`);let b=await a.text(),c=(0,r.qq)(b),d=await e.loadState();if(G)return;if(!d.lastHash){await e.saveState({lastHash:c}),e.onSuccess?.();return}if(d.lastHash===c)return void e.onSuccess?.();let{status:g}=await e.onFire({summary:"Online content changed",context:{url:f.url,status:a.status,contentType:a.headers.get("content-type")??void 0,content:b.length>8192?`${b.slice(0,8192)}… (truncated, ${b.length} chars total)`:b}});if(G)return;let{giveUpError:h}=await (0,r.vV)({status:g,pendingState:{lastHash:c},priorFailures:d.pendingFailures??0,saveState:e.saveState});h&&e.onError(h)}catch(b){let a=b instanceof Error&&"TimeoutError"===b.name?"The URL did not answer within 30s":b instanceof Error?b.message:String(b);t.warn(`URL check failed for ${f.url}: ${a}`),e.onError(a)}finally{F=!1}}},I=new p.l4(f.cron,{timezone:f.timezone,unref:!0},()=>void H()),H(),{dispose:()=>{G=!0,I.stop()},nextRun:()=>I.nextRun()?.toISOString()??null}));break;case"flow-event":this.armed.set(a.id,function(a,b){let c=a.maxChainDepth??100,d="string"==typeof a.source.topic?a.source.topic.trim():"",e=d.length>0,f=0,g=null,h=!1;if(a.outputMatch?.regex)try{g=new RegExp(a.outputMatch.regex)}catch(c){h=!0;let a=`Invalid output-match regex: ${c instanceof Error?c.message:String(c)}`;v.warn(a),b.onError(a)}let i=b=>{if(!a.outputMatch)return!0;if(h)return!1;let c=(b??"").slice(0,16384);return(!a.outputMatch.contains||!!c.includes(a.outputMatch.contains))&&(!g||!!g.test(c))},j=(d,e,g,h)=>{if(d>=c){let a=`Flow-event chain reached the depth limit (${c}); not firing again`;v.info(a),b.onSkip(a);return}let i=Date.now();a.minIntervalMs&&i-f<a.minIntervalMs?v.debug(`Flow-event cooldown active (${a.minIntervalMs}ms); ignoring event`):(f=i,b.onFire({summary:e,context:g,chainDepth:d+1,sourceConversationId:h}))},k=(0,u.eh)().subscribe(c=>{try{let b;if(e){if(!(0,u.ru)(c)||c.topic!==d||!i(c.payload))return;j(c.chainDepth,`Signal "${c.topic}"`,{topic:c.topic,payload:w(c.payload),emitterFlowId:c.emitterFlowId,flowName:c.flowName,runId:c.runId,conversationId:c.conversationId,firedBy:c.firedBy},c.conversationId);return}if((0,u.ru)(c)||((b=a.source).executionId?c.executionId!==b.executionId:b.flowId?c.flowId!==b.flowId:!b.flowName||c.flowName!==b.flowName)||!c.status||!(a.on??[]).includes(c.status)||!i(c.outputText))return;let f=c.flowName??c.flowId;j(c.chainDepth,`Flow "${f}" ${c.status}`,{flowId:c.flowId,flowName:c.flowName,executionId:c.executionId,runId:c.runId,conversationId:c.conversationId,status:c.status,firedBy:c.firedBy,outputText:w(c.outputText),error:c.error},c.conversationId)}catch(c){let a=c instanceof Error?c.message:String(c);v.warn(`Flow-event handling failed: ${a}`),b.onError(a)}});return{dispose:()=>k(),nextRun:()=>null}}(f,{onFire:this.bindToWorkspace(({summary:b,context:c,chainDepth:d,sourceConversationId:e})=>{this.lastTriggerErrors.delete(a.id),this.fire(a,{kind:"flow-event",summary:b,context:c,chainDepth:d,parentConversationId:e}).catch(b=>E.error(`Flow-event fire failed for ${a.id}:`,b))}),onSkip:this.bindToWorkspace(b=>{let c=new Date().toISOString(),e=(0,d.A)();this.recordSchedulerSkip(a,e,b),(0,x.Hy)(a.id,{runId:e,conversationId:"",firedAt:c,finishedAt:c,status:"skipped",triggerSummary:"Flow event",error:b}).catch(b=>E.warn(`Failed to record flow-event skip for ${a.id}:`,b))}),onError:this.bindToWorkspace(b=>this.lastTriggerErrors.set(a.id,b))}));break;default:E.warn(`Trigger type "${f.type}" is not implemented — "${a.name}" not armed`)}}async loadFile(){let a=await (0,e.loadItem)(f.Zg.PLANNED_EXECUTIONS,F);return{version:1,paused:!0===a.paused,executions:Array.isArray(a.executions)?a.executions:[]}}async saveFile(a){await (0,e.VH)(f.Zg.PLANNED_EXECUTIONS,a)}async isPaused(){return(await this.loadFile()).paused}async setPaused(a){let b=await this.loadFile();if(await this.saveFile({...b,paused:a}),await this.reconcile(),a){for(let a of[...this.queued.keys()])await this.cancelQueued(a,"scheduler paused",!0);await this.cancelAllExclusiveWaiting("scheduler paused",!0)}}async list(){return Promise.all((await this.loadFile()).executions.map(async a=>({execution:a,status:this.getStatus(a),lastRun:await (0,x.tl)(a.id)})))}async get(a){return(await this.loadFile()).executions.find(b=>b.id===a)??null}async create(a){let b=this.validateInput(a);if(b)return{error:b};if(void 0!==a.id&&!/^[A-Za-z0-9._:-]{1,128}$/.test(a.id))return{error:"The id must be 1-128 characters of letters, digits, dot, underscore, colon or hyphen"};if("."===a.id||".."===a.id)return{error:'The id must be a safe identifier, not "." or ".."'};let c=new Date().toISOString(),e={...a,folder:a.folder?.trim()||void 0,trigger:this.normalizeTrigger(a.trigger),id:a.id??(0,d.A)(),createdAt:c,updatedAt:c},f=await this.loadFile();return f.executions.some(a=>a.id===e.id)?{error:`A planned execution with id "${e.id}" already exists`,conflict:!0}:(await this.saveFile({...f,executions:[...f.executions,e]}),await this.reconcile(),{execution:e})}async update(a,b){let c=await this.loadFile(),d=c.executions.findIndex(b=>b.id===a);if(d<0)return{error:`No planned execution with id "${a}"`};let e=b.folder;if(Object.prototype.hasOwnProperty.call(b,"folder")&&void 0!==e&&"string"!=typeof e)return{error:"Folder must be text"};let f={...c.executions[d],...b,...Object.prototype.hasOwnProperty.call(b,"folder")?{folder:"string"==typeof e&&e.trim()||void 0}:{},...b.trigger?{trigger:this.normalizeTrigger(b.trigger)}:{},id:a,createdAt:c.executions[d].createdAt,updatedAt:new Date().toISOString()},g=this.validateInput(f);if(g)return{error:g};let h=[...c.executions];return h[d]=f,await this.saveFile({...c,executions:h}),Object.keys(b).some(a=>"folder"!==a)&&(await this.reconcile(),await this.cancelQueued(a,"execution updated",!0),await this.cancelExclusiveWaiting(a,"execution updated",!0)),{execution:f}}async delete(a){let b=await this.loadFile();return b.executions.some(b=>b.id===a)?(await this.saveFile({...b,executions:b.executions.filter(b=>b.id!==a)}),await this.reconcile(),this.lastTriggerErrors.delete(a),await this.cancelQueued(a,"execution deleted",!1),await this.cancelExclusiveWaiting(a,"execution deleted",!1),await (0,x.xC)(a),await C(a),{success:!0}):{success:!1,error:`No planned execution with id "${a}"`}}normalizeTrigger(a){return a?.type!=="webhook"||a.token?a?.type!=="mcp-poll"||a.cron?a:{...a,cron:(0,q.X)(a.intervalMs)}:{...a,token:(0,d.A)()}}validateInput(a){if(!a.name?.trim())return"A name is required";if(void 0!==a.folder&&"string"!=typeof a.folder)return"Folder must be text";if(a.folder&&a.folder.trim().length>120)return"Folder must be 120 characters or fewer";if(!a.flowId)return"A flow is required";if("string"!=typeof a.prompt)return"A prompt is required (may be empty)";if(void 0!==a.overlapStrategy&&!["skip","queue","parallel","error"].includes(a.overlapStrategy))return"Overlap strategy must be one of: skip, queue, parallel, error";if(void 0!==a.exclusive&&"boolean"!=typeof a.exclusive)return"Exclusive must be true or false";if(void 0!==a.nonExclusiveBehavior&&!["queue","skip","error"].includes(a.nonExclusiveBehavior))return"When exclusive is on, other triggers must be one of: queue, skip, error";let b=a.trigger;if(!b||"object"!=typeof b)return"A trigger is required";switch(b.type){case"schedule":{let a=(0,j.O9)(b.cron,b.timezone);return a.valid?null:`Invalid schedule: ${a.error}`}case"webhook":return null;case"file-watch":if(!b.path?.trim())return"A folder or file path to watch is required";if(!Array.isArray(b.events)||0===b.events.length)return"At least one file event is required";return null;case"mcp-poll":if(!b.serverName||!b.toolName)return"A server and tool are required";if(b.cron){let a=(0,j.O9)(b.cron,b.timezone);if(!a.valid)return`Invalid schedule: ${a.error}`}if(b.evaluate?.mode==="new-items"&&!b.evaluate.idField?.trim())return"An id field is required to detect new items";if((b.evaluate?.mode==="llm-gate"||b.evaluate?.mode==="flow-gate")&&!b.evaluate.condition?.trim())return"A condition is required for the AI to check";if(b.evaluate?.mode==="llm-gate"&&!b.evaluate.modelId)return"A model is required to check the condition";if(b.evaluate?.mode==="flow-gate"&&!b.evaluate.flowId)return"A flow is required to check the condition";return null;case"url-watch":{try{let a=new URL(b.url??"");if("http:"!==a.protocol&&"https:"!==a.protocol)return"The URL must start with http:// or https://"}catch{return"A valid URL is required"}let a=(0,j.O9)(b.cron,b.timezone);return a.valid?null:`Invalid schedule: ${a.error}`}case"flow-event":{let a=b.source;if(1!==[a?.executionId,a?.flowId,a?.flowName,a?.topic].filter(a=>"string"==typeof a&&a.trim().length>0).length)return"Choose exactly one source: a flow, a planned execution, or a signal topic";if(!("string"==typeof a?.topic&&a.topic.trim().length>0)){if(!Array.isArray(b.on)||0===b.on.length)return"Select at least one outcome to react to (completed or error)";if(b.on.some(a=>"completed"!==a&&"error"!==a))return'Outcomes must be "completed" or "error"'}if(b.outputMatch?.regex)try{new RegExp(b.outputMatch.regex)}catch(a){return`Invalid output-match regex: ${a instanceof Error?a.message:String(a)}`}if(void 0!==b.maxChainDepth&&(!Number.isInteger(b.maxChainDepth)||b.maxChainDepth<1))return"Max chain depth must be a positive whole number";if(void 0!==b.minIntervalMs&&(!Number.isFinite(b.minIntervalMs)||b.minIntervalMs<0))return"Minimum interval must be zero or more milliseconds";return null}default:return"Unknown trigger type"}}isRunning(a){let b=this.running.get(a);return void 0!==b&&b.size>0}addRunning(a,b,c){let d=this.running.get(a);d||(d=new Map,this.running.set(a,d)),d.set(b,c)}removeRunning(a,b){let c=this.running.get(a);c&&(c.delete(b),0===c.size&&this.running.delete(a))}earliestRunningSince(a){let b,c=this.running.get(a);if(c&&0!==c.size){for(let a of c.values())(void 0===b||a<b)&&(b=a);return b}}skippedRecord(a,b){let c=new Date().toISOString();return this.recordSchedulerSkip(a.execution,a.runId,b),{runId:a.runId,conversationId:"",firedAt:c,finishedAt:c,status:"skipped",triggerSummary:a.payload.summary,error:b}}recordSchedulerFire(a,b,c,d){(0,D.z9)((0,D.k)({type:"scheduler.fire",runId:b,source:"schedule",plannedExecution:{id:a.id,name:a.name},outcome:c,...d?{conversationId:d}:{}}))}recordSchedulerSkip(a,b,c){(0,D.z9)((0,D.k)({type:"scheduler.skip",runId:b,source:"schedule",plannedExecution:{id:a.id,name:a.name},reason:(0,D.bW)(c)}))}async cancelQueued(a,b,c){let d=this.queued.get(a);if(d&&0!==d.length){for(let e of(this.queued.delete(a),d)){let d=this.skippedRecord(e,b);if(c)try{await (0,x.Hy)(a,d)}catch(b){E.warn(`Failed to record cancelled queued fire for ${a}:`,b)}e.resolve(d)}E.info(`Cancelled ${d.length} queued fire(s) for ${a}: ${b}`)}}drainQueue(a){let b=this.queued.get(a);if(!b||0===b.length||this.isRunning(a))return;let c=b.shift();0===b.length&&this.queued.delete(a),c&&(async()=>{let b=await this.get(a);if(!b||!b.enabled||this.pausedCache){let a=b?b.enabled?"scheduler paused":"execution disabled":"execution deleted";c.resolve(this.skippedRecord(c,a));return}let d=await this.fire(b,c.payload,c.runId);c.resolve(d)})().catch(b=>E.error(`Queued fire failed for ${a}:`,b))}isSchedulerIdle(){for(let a of this.running.values())if(a.size>0)return!1;return!0}isExclusiveActive(){return null!==this.exclusiveHolder||this.exclusiveWaiting.length>0}currentExclusiveBehavior(){return null!==this.exclusiveHolder?this.exclusiveHolderBehavior:this.exclusiveWaiting[0]?.execution.nonExclusiveBehavior??"queue"}exclusiveGateFor(a){return!0!==a.exclusive&&this.isExclusiveActive()?this.currentExclusiveBehavior():null}drainExclusive(){null===this.exclusiveHolder&&this.exclusiveWaiting.length>0&&this.isSchedulerIdle()?this.acquireNextExclusive():this.isExclusiveActive()||this.drainBlockedByExclusive()}acquireNextExclusive(){if(null!==this.exclusiveHolder||!this.isSchedulerIdle())return;let a=this.exclusiveWaiting.shift();if(!a)return;let b=a.execution.id;this.exclusiveHolder=b,this.exclusiveHolderBehavior=a.execution.nonExclusiveBehavior??"queue",(async()=>{let c=await this.get(b);if(!c||!c.enabled||this.pausedCache||!0!==c.exclusive){let d=c?c.enabled?this.pausedCache?"scheduler paused":"no longer exclusive":"execution disabled":"execution deleted";this.exclusiveHolder===b&&(this.exclusiveHolder=null),a.resolve(this.skippedRecord(a,d)),this.drainExclusive();return}this.exclusiveHolderBehavior=c.nonExclusiveBehavior??"queue";let d=await this.fire(c,a.payload,a.runId);a.resolve(d)})().catch(c=>{this.exclusiveHolder===b&&(this.exclusiveHolder=null),E.error(`Exclusive acquire failed for ${b}:`,c),a.resolve(this.skippedRecord(a,"exclusive acquire failed")),this.drainExclusive()})}drainBlockedByExclusive(){if(0===this.blockedByExclusive.length)return;let a=this.blockedByExclusive;for(let b of(this.blockedByExclusive=[],a))(async()=>{let a=await this.get(b.execution.id);if(!a||!a.enabled||this.pausedCache){let c=a?a.enabled?"scheduler paused":"execution disabled":"execution deleted";b.resolve(this.skippedRecord(b,c));return}let c=await this.fire(a,b.payload,b.runId);b.resolve(c)})().catch(a=>E.error(`Deferred non-exclusive fire failed for ${b.execution.id}:`,a))}async cancelExclusiveWaiting(a,b,c){let d=[];if(this.exclusiveWaiting=this.exclusiveWaiting.filter(b=>b.execution.id!==a||(d.push(b),!1)),this.blockedByExclusive=this.blockedByExclusive.filter(b=>b.execution.id!==a||(d.push(b),!1)),0!==d.length){for(let e of d){let d=this.skippedRecord(e,b);if(c)try{await (0,x.Hy)(a,d)}catch(b){E.warn(`Failed to record cancelled exclusive fire for ${a}:`,b)}e.resolve(d)}E.info(`Cancelled ${d.length} exclusive-related fire(s) for ${a}: ${b}`)}}async cancelAllExclusiveWaiting(a,b){let c=[...this.exclusiveWaiting,...this.blockedByExclusive];if(this.exclusiveWaiting=[],this.blockedByExclusive=[],0!==c.length){for(let d of c){let c=this.skippedRecord(d,a);if(b)try{await (0,x.Hy)(d.execution.id,c)}catch(a){E.warn(`Failed to record cancelled exclusive fire for ${d.execution.id}:`,a)}d.resolve(c)}E.info(`Cancelled ${c.length} exclusive-related fire(s): ${a}`)}}getStatus(a){let b=this.armed.get(a.id),c=void 0!==b||a.enabled&&"webhook"===a.trigger.type&&this.started&&!this.pausedCache,d=this.earliestRunningSince(a.id),e=c?void 0:a.enabled?this.pausedCache?"paused":void 0:"disabled",f=this.exclusiveHolder??void 0,g=!0!==a.exclusive&&this.isExclusiveActive();return{armed:c,notArmedReason:e,nextRun:b?.nextRun?b.nextRun():void 0,lastTriggerError:this.lastTriggerErrors.get(a.id),running:void 0!==d,runningSince:d,exclusiveHolderId:f,blockedByExclusive:g}}async runNow(a){let b=await this.get(a);return b?{record:await this.fire(b,{kind:"manual",summary:"Manual run"},(0,d.A)(),!0)}:{error:`No planned execution with id "${a}"`}}fire(a,b,c=(0,d.A)(),e=!1){return this.inWorkspace(()=>this.fireInternal(a,b,c,e))}async fireInternal(a,b,e=(0,d.A)(),f=!1){let g,i=new Date().toISOString();if(await (0,h.isEncryptionLocked)()){let c={runId:e,conversationId:"",firedAt:i,finishedAt:i,status:"skipped",triggerSummary:b.summary,error:"encryption locked"};return this.recordSchedulerSkip(a,e,c.error),await (0,x.Hy)(a.id,c),E.info(`Skipped fire for "${a.name}" — encryption locked`),c}let j="flow-event"===b.kind;if(!f&&!j){if(!0===a.exclusive){if(this.exclusiveHolder!==a.id){if(null!==this.exclusiveHolder||!this.isSchedulerIdle()){let c=this.exclusiveWaiting.length;if(c>=G.MAX_QUEUE_DEPTH){let c={runId:e,conversationId:"",firedAt:i,finishedAt:i,status:"skipped",triggerSummary:b.summary,error:`Exclusive wait queue full (cap ${G.MAX_QUEUE_DEPTH}) — fire dropped`};return this.recordSchedulerSkip(a,e,c.error),await (0,x.Hy)(a.id,c),E.warn(`Exclusive wait queue full for "${a.name}" — dropped fire`),c}return E.info(`Exclusive "${a.name}" waiting for scheduler to idle (depth ${c+1})`),this.recordSchedulerFire(a,e,"queued"),new Promise(c=>{this.exclusiveWaiting.push({execution:a,payload:b,runId:e,resolve:c})})}this.exclusiveHolder=a.id,this.exclusiveHolderBehavior=a.nonExclusiveBehavior??"queue",E.info(`Exclusive "${a.name}" acquired the scheduler lock`)}}else if(this.isExclusiveActive()){let c=this.currentExclusiveBehavior();if("skip"===c){let c={runId:e,conversationId:"",firedAt:i,finishedAt:i,status:"skipped",triggerSummary:b.summary,error:"Skipped — an exclusive execution holds the scheduler lock"};return this.recordSchedulerSkip(a,e,c.error),await (0,x.Hy)(a.id,c),E.info(`Skipped non-exclusive fire for "${a.name}" — exclusive lock held`),c}if("error"===c){let c={runId:e,conversationId:"",firedAt:i,finishedAt:i,status:"error",triggerSummary:b.summary,error:"Rejected — an exclusive execution holds the scheduler lock"};return await (0,x.Hy)(a.id,c),E.info(`Rejected non-exclusive fire for "${a.name}" — exclusive lock held`),c}let d=this.blockedByExclusive.length;if(d>=G.MAX_QUEUE_DEPTH){let c={runId:e,conversationId:"",firedAt:i,finishedAt:i,status:"skipped",triggerSummary:b.summary,error:`Exclusive-block queue full (cap ${G.MAX_QUEUE_DEPTH}) — fire dropped`};return this.recordSchedulerSkip(a,e,c.error),await (0,x.Hy)(a.id,c),E.warn(`Exclusive-block queue full for "${a.name}" — dropped fire`),c}return E.info(`Deferred non-exclusive fire for "${a.name}" — exclusive lock held (depth ${d+1})`),this.recordSchedulerFire(a,e,"queued"),new Promise(c=>{this.blockedByExclusive.push({execution:a,payload:b,runId:e,resolve:c})})}}let k=a.overlapStrategy??"skip";if(!f&&this.isRunning(a.id)){if("skip"===k){let c={runId:e,conversationId:"",firedAt:i,finishedAt:i,status:"skipped",triggerSummary:b.summary,error:"Previous run still in progress"};return this.recordSchedulerSkip(a,e,c.error),await (0,x.Hy)(a.id,c),E.info(`Skipped overlapping fire for "${a.name}"`),c}if("error"===k){let c={runId:e,conversationId:"",firedAt:i,finishedAt:i,status:"error",triggerSummary:b.summary,error:"Overlapping run rejected (overlapStrategy=error)"};return await (0,x.Hy)(a.id,c),E.info(`Rejected overlapping fire for "${a.name}" (overlapStrategy=error)`),c}if("queue"===k){let c=this.queued.get(a.id)?.length??0;if(c>=G.MAX_QUEUE_DEPTH){let c={runId:e,conversationId:"",firedAt:i,finishedAt:i,status:"skipped",triggerSummary:b.summary,error:`Overlap queue full (cap ${G.MAX_QUEUE_DEPTH}) — fire dropped`};return this.recordSchedulerSkip(a,e,c.error),await (0,x.Hy)(a.id,c),E.warn(`Overlap queue full for "${a.name}" — dropped fire`),c}return E.info(`Queued overlapping fire for "${a.name}" (depth ${c+1})`),this.recordSchedulerFire(a,e,"queued"),new Promise(c=>{let d=this.queued.get(a.id)??[];d.push({execution:a,payload:b,runId:e,resolve:c}),this.queued.set(a.id,d)})}}this.addRunning(a.id,e,i);let l=(0,d.A)();this.recordSchedulerFire(a,e,"fired",l);try{E.info(`Firing "${a.name}" (${b.kind})`);let d=await (0,x.Sw)(a.id),f=d.length>0?d[d.length-1]:null,h={executionName:a.name,trigger:b.kind,now:i,timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,lastRun:f?{at:f.firedAt,status:f.status}:null,nextPlannedRun:this.getStatus(a).nextRun??null},j=a.approvalPolicy??"auto",k=a.saveConversations||"pause"===j?"conversation":"ephemeral",{runFlow:m}=await Promise.all([c.e(6614),c.e(8775),c.e(4165),c.e(3133),c.e(1114),c.e(531),c.e(7798),c.e(2126),c.e(1346),c.e(9592),c.e(5111)]).then(c.bind(c,79592)),n=await m({flowId:a.flowId,prompt:this.composePrompt(a.prompt,b,h),mode:k,conversationId:l,runId:e,source:"schedule",plannedExecutionId:a.id,plannedExecutionName:a.name,parentRunId:b.parentConversationId,chainDepth:b.chainDepth??0,requireApproval:"auto"!==j,onApprovalRequired:j,debug:!1,userTurn:!0});g=await this.recordFromResult(a,n,{runId:e,conversationId:l,firedAt:i,payload:b})}catch(c){g={runId:e,conversationId:l,firedAt:i,finishedAt:new Date().toISOString(),status:"error",triggerSummary:b.summary,error:c instanceof Error?c.message:String(c)},E.error(`Run crashed for "${a.name}":`,c)}finally{this.removeRunning(a.id,e),this.exclusiveHolder!==a.id||this.isRunning(a.id)||(this.exclusiveHolder=null,E.info(`Exclusive "${a.name}" released the scheduler lock`)),this.drainExclusive(),this.drainQueue(a.id)}return await this.get(a.id)===null?E.info(`Dropping run record for deleted execution ${a.id}`):(await (0,x.Hy)(a.id,g),("completed"===g.status||"error"===g.status)&&await this.publishFlowRunEvent(a,g,b)),g}async recordFromResult(a,b,c){let{runId:d,conversationId:e,firedAt:f,payload:g}=c,h=new Date().toISOString(),i="awaiting_tool_approval"===b.status,j="error"===b.status&&b.error?.details?.type==="approval_required";if(i||j){let c=(b.pendingToolCalls??[]).map(a=>({id:a.id,name:"function"===a.type?a.function.name:String(a.type)})),k={runId:d,conversationId:e,firedAt:f,finishedAt:h,status:"needs_approval",triggerSummary:g.summary,outputText:this.truncateOutput(b.outputText),usage:b.usage,error:j?b.error?.message??"Tool approval required":"Awaiting tool approval",pendingApproval:{tool:c[0]?.name??b.error?.details?.name,toolCallId:c[0]?.id,pendingToolCalls:c.length>0?c:void 0}};return i&&await this.registerPendingApproval(a,k,c),k}return{runId:d,conversationId:e,firedAt:f,finishedAt:h,status:"completed"===b.status?"completed":"capped"===b.status?"capped":"error",triggerSummary:g.summary,outputText:this.truncateOutput(b.outputText),usage:b.usage,error:"completed"===b.status||"capped"===b.status?void 0:b.error?.message??`Run ended with status "${b.status}"`}}async registerPendingApproval(a,b,d){try{let e;try{let{flowService:b}=await c.e(1114).then(c.bind(c,71114));e=(await b.getFlow(a.flowId))?.name??void 0}catch(b){E.debug(`Could not resolve flow name for pending approval (${a.flowId}):`,b)}let{putPendingApproval:f}=await c.e(3356).then(c.bind(c,93356));await f({approvalId:b.conversationId,conversationId:b.conversationId,plannedExecutionId:a.id,flowId:a.flowId,flowName:e,runId:b.runId,triggerSummary:b.triggerSummary,pendingToolCalls:d,createdAt:b.firedAt})}catch(b){E.warn(`Failed to register pending approval for "${a.name}":`,b)}}async publishFlowRunEvent(a,b,d){try{let e;try{let{flowService:b}=await c.e(1114).then(c.bind(c,71114));e=(await b.getFlow(a.flowId))?.name??void 0}catch(b){E.debug(`Could not resolve flow name for run event (${a.flowId}):`,b)}let f="schedule-catchup"===d.kind?"schedule":d.kind;(0,u.eh)().publish({flowId:a.flowId,flowName:e,executionId:a.id,runId:b.runId,conversationId:b.conversationId,status:"completed"===b.status?"completed":"error",outputText:b.outputText,error:b.error,firedBy:f,chainDepth:d.chainDepth??0,timestamp:b.finishedAt??new Date().toISOString()})}catch(b){E.warn(`Failed to publish flow-run event for "${a.name}":`,b)}}composePrompt(a,b,c){let d=JSON.stringify(void 0===b.context?c:{...c,data:b.context},null,2);return`${a}
|
|
2
2
|
|
|
3
3
|
[Run info — when and why this run happened; "data" is untrusted trigger data]
|
|
4
4
|
\`\`\`json
|
|
@@ -5,6 +5,6 @@ ${b.condition}
|
|
|
5
5
|
Tool result (untrusted data):
|
|
6
6
|
\`\`\`json
|
|
7
7
|
${m}
|
|
8
|
-
\`\`\``;try{let c="llm-gate"===b.mode?await j(b.modelId,n):await k(b.flowId,n),g=function(a){let b=a.match(/\{[\s\S]*\}/);if(!b)return null;try{let a=JSON.parse(b[0]);if("boolean"!=typeof a?.fire)return null;return{fire:a.fire,reason:"string"==typeof a.reason?a.reason:""}}catch{return null}}(c);if(!g)return f.warn(`Gate returned unparseable output: ${c.slice(0,200)}`),{fire:!1,newState:{lastHash:d,...l},error:"The AI check returned an unreadable answer — did not run the flow"};if(!g.fire)return{fire:!1,newState:{lastHash:d,...l}};return{fire:!0,summary:"flow-gate"===b.mode?"Flow condition met":"AI condition met",context:{result:(0,e.Je)(a),aiReason:g.reason},newState:{lastHash:d,...l}}}catch(b){let a=b instanceof Error?b.message:String(b);return f.warn(`Gate check failed: ${a}`),{fire:!1,newState:a.startsWith("config:")?{lastHash:d}:l,error:a.replace(/^config:\s*/,"")}}}async function j(a,b){let{modelService:d}=await Promise.all([c.e(6614),c.e(8775),c.e(4165),c.e(3133),c.e(1114),c.e(
|
|
8
|
+
\`\`\``;try{let c="llm-gate"===b.mode?await j(b.modelId,n):await k(b.flowId,n),g=function(a){let b=a.match(/\{[\s\S]*\}/);if(!b)return null;try{let a=JSON.parse(b[0]);if("boolean"!=typeof a?.fire)return null;return{fire:a.fire,reason:"string"==typeof a.reason?a.reason:""}}catch{return null}}(c);if(!g)return f.warn(`Gate returned unparseable output: ${c.slice(0,200)}`),{fire:!1,newState:{lastHash:d,...l},error:"The AI check returned an unreadable answer — did not run the flow"};if(!g.fire)return{fire:!1,newState:{lastHash:d,...l}};return{fire:!0,summary:"flow-gate"===b.mode?"Flow condition met":"AI condition met",context:{result:(0,e.Je)(a),aiReason:g.reason},newState:{lastHash:d,...l}}}catch(b){let a=b instanceof Error?b.message:String(b);return f.warn(`Gate check failed: ${a}`),{fire:!1,newState:a.startsWith("config:")?{lastHash:d}:l,error:a.replace(/^config:\s*/,"")}}}async function j(a,b){let{modelService:d}=await Promise.all([c.e(6614),c.e(8775),c.e(4165),c.e(3133),c.e(1114),c.e(531),c.e(7798),c.e(2126),c.e(7492)]).then(c.bind(c,42740)),{getCompletionAdapter:e}=await Promise.all([c.e(6614),c.e(8775),c.e(4165),c.e(3133),c.e(1114),c.e(531),c.e(7798),c.e(2126),c.e(7492)]).then(c.bind(c,25940)),{normalizeMaxTokens:f}=await c.e(87).then(c.bind(c,70087)),g=await d.getModel(a);if(!g)throw Error(`config: The AI-check model no longer exists (${a})`);let i=await d.resolveAndDecryptApiKey(g.ApiKey);if(!i)throw Error("config: Could not resolve the AI-check model API key");let j=e(g),{completion:k}=await j.createCompletion({model:g,apiKey:i,temperature:0,maxTokens:f(g.maxTokens),messages:[{role:"system",content:h},{role:"user",content:b}]}),l=k.choices?.[0]?.message?.content;return"string"==typeof l?l:""}async function k(a,b){let{runFlow:d}=await Promise.all([c.e(6614),c.e(8775),c.e(4165),c.e(3133),c.e(1114),c.e(531),c.e(7798),c.e(2126),c.e(1346),c.e(9592),c.e(5111)]).then(c.bind(c,79592)),e=await d({flowId:a,prompt:`${b}
|
|
9
9
|
|
|
10
10
|
${g}`,source:"trigger",mode:"ephemeral",requireApproval:!1,debug:!1,userTurn:!0});if("completed"!==e.status)throw Error(e.error?.message??`The checker flow ended with status "${e.status}"`);return e.outputText??""}}};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";exports.id=609,exports.ids=[609],exports.modules={47735:(a,b,c)=>{c.d(b,{X:()=>e});var d=c(91949);function e(a){let b=a.maxSubflowDepth??10,c=a.maxChainDepth??100,e=a.grouping??"per-root",f=new Date(a.now??Date.now()).toISOString(),g=[...a.executions].sort((a,b)=>a.execution.id<b.execution.id?-1:+(a.execution.id>b.execution.id)),h=new Map;for(let b of a.flows)h.set(b.id,b);let i=new Map,j=new Map,k=new Map;for(let a of g){i.set(a.execution.id,a);let b=a.execution.flowId;j.has(b)||j.set(b,[]),j.get(b).push(a);let c=h.get(b)?.name;c&&(k.has(c)||k.set(c,[]),k.get(c).push(a))}let l=new Map,m=a=>{let c=l.get(a);return c||(c=(0,d.gX)(a,h,b),l.set(a,c)),c},n=new Map;for(let a of g){let c=a.execution,e=c.trigger.type,f=h.get(c.flowId),g=function(a,b,c){if("schedule"===a||"mcp-poll"===a||"url-watch"===a)return{mode:"timeline",nextRun:c,cron:"cron"in b?b.cron:void 0};if("flow-event"===a){let a="flow-event"===b.type?b.source:{},c="string"==typeof a.topic&&a.topic.trim()?a.topic.trim():void 0;return{mode:"event",via:c?"signal":"completion",topic:c}}return{mode:"fixed"}}(e,c.trigger,a.status?.nextRun??null);n.set(c.id,{executionId:c.id,name:c.name,enabled:c.enabled,flowId:c.flowId,flowName:f?.name,triggerKind:e,isRoot:"flow-event"!==e,timing:g,subflows:function a(b,c,e,f,g){let h=c.get(b),i=(0,d.sd)(h),j=[];for(let b of i){let d=c.get(b),h={flowId:b,flowName:d?.name,children:[]};if(d)if(g+1>=e||f.has(b))h.truncated=!0;else{let d=new Set(f);d.add(b),h.children=a(b,c,e,d,g+1)}else h.missing=!0;j.push(h)}return j}(c.flowId,h,b,new Set([c.flowId]),0),emittedSignals:function(a,b,c){let e=new Set((0,d.Sg)(b));return[...new Set([...e,...c(a)])].sort().map(a=>({topic:a,direct:e.has(a)}))}(c.flowId,f,m)})}let o=[],p=[];for(let a of g){let b=a.execution;if("flow-event"!==b.trigger.type)continue;let c=b.trigger.source??{},d=b.trigger.on,e=[],f="string"==typeof c.topic&&c.topic.trim()?c.topic.trim():"";if(f)for(let a of g)a.execution.id!==b.id&&m(a.execution.flowId).has(f)&&e.push({fromExecutionId:a.execution.id,toExecutionId:b.id,via:"signal",topic:f});else if(c.executionId){let a=i.get(c.executionId);a&&e.push({fromExecutionId:a.execution.id,toExecutionId:b.id,via:"completion",on:d})}else if(c.flowId)for(let a of j.get(c.flowId)??[])e.push({fromExecutionId:a.execution.id,toExecutionId:b.id,via:"completion",on:d});else if(c.flowName)for(let a of k.get(c.flowName)??[])e.push({fromExecutionId:a.execution.id,toExecutionId:b.id,via:"completion",on:d});0===e.length?p.push(b.id):o.push(...e)}o.sort((a,b)=>a.fromExecutionId!==b.fromExecutionId?a.fromExecutionId<b.fromExecutionId?-1:1:a.toExecutionId!==b.toExecutionId?a.toExecutionId<b.toExecutionId?-1:1:a.via<b.via?-1:+(a.via>b.via));let q=new Map;for(let a of o)q.has(a.fromExecutionId)||q.set(a.fromExecutionId,[]),q.get(a.fromExecutionId).push(a);let r=g.map(a=>a.execution.id),s=function(a,b){let c=new Map;for(let a of b)c.set(a,[]);for(let b of a)c.has(b.fromExecutionId)||c.set(b.fromExecutionId,[]),c.get(b.fromExecutionId).push(b.toExecutionId);let d=new Map,e=new Set,f=[],g=a=>{for(let b of(d.set(a,1),f.push(a),c.get(a)??[])){let a=d.get(b)??0;if(1===a){let a=f.lastIndexOf(b);if(a>=0)for(let b=a;b<f.length;b++)e.add(f[b])}else 0===a&&g(b)}f.pop(),d.set(a,2)};for(let a of b)(d.get(a)??0)===0&&g(a);return e}(o,r),t=new Set(p),u=a=>{let b=new Set([a]),d=[{id:a,depth:0}];for(;d.length>0;){let{id:a,depth:e}=d.shift();if(!(e>=c))for(let c of q.get(a)??[])b.has(c.toExecutionId)||(b.add(c.toExecutionId),d.push({id:c.toExecutionId,depth:e+1}))}return b},v=(a,b,c)=>{let d=[...c].sort();return{id:a,rootExecutionIds:b,nodes:d.map(a=>n.get(a)).filter(Boolean),edges:o.filter(a=>c.has(a.fromExecutionId)&&c.has(a.toExecutionId)),hasCycle:d.some(a=>s.has(a))}},w=[];if("connected-component"===e){let a=new Map,b=b=>{let c=b;for(;a.get(c)!==c;)c=a.get(c);let d=b;for(;a.get(d)!==c;){let b=a.get(d);a.set(d,c),d=b}return c},c=(c,d)=>{let e=b(c),f=b(d);e!==f&&a.set(e,f)};for(let b of r)t.has(b)||a.set(b,b);for(let a of o)c(a.fromExecutionId,a.toExecutionId);let d=new Map;for(let a of r){if(t.has(a))continue;let c=(q.get(a)?.length??0)>0||o.some(b=>b.toExecutionId===a);if(!n.get(a).isRoot&&!c)continue;let e=b(a);d.has(e)||d.set(e,new Set),d.get(e).add(a)}let e=[...d.values()].map(a=>[...a].sort());for(let a of(e.sort((a,b)=>a[0]<b[0]?-1:+(a[0]>b[0])),e)){let b=new Set(a),c=a.filter(a=>n.get(a).isRoot).sort();w.push(v(a.join("|"),c,b))}}else for(let a of r.filter(a=>n.get(a).isRoot).sort()){let b=u(a);w.push(v(a,[a],b))}let x=p.sort().map(a=>n.get(a));return{paused:a.paused??!1,generatedAt:f,waves:w,orphans:x}}},79297:(a,b,c)=>{c.d(b,{ue:()=>n,rf:()=>k,qI:()=>j,X:()=>l});var d=c(78796),e=c(55520),f=c(14671);function g(a){return JSON.parse(JSON.stringify(a))}function h(a){return a.data?.edgeType}function i(a,b){let c=new Set((0,e.A$)(a).filter(a=>"tool"===a.kind).map(a=>`${a.server}\u0000${a.name}`)),d=b.filter(a=>!c.has(`${a.server}\u0000${a.tool}`));if(0===d.length)return a.trim();let f=d.map(a=>`- Use ${(0,e.X8)("tool",a.server,a.tool)} when ${a.reason.replace(/[.\s]+$/,"")}.`);return`${a.trim()}
|
|
2
2
|
|
|
3
3
|
Available connected tools:
|
|
4
|
-
${f.join("\n")}`.trim()}function j(a,b){var c;let f,j=g(a),k=j.nodes.find(a=>a.id===b.nodeId&&"process"===a.data.type);if(!k)throw Error(`Process node not found: ${b.nodeId}`);let l=b.selections.filter((a,c,d)=>Array.isArray(b.availableTools[a.server])&&b.availableTools[a.server].includes(a.tool)&&d.findIndex(b=>b.server===a.server&&b.tool===a.tool)===c);if(0===l.length)return j;let m=new Map;for(let a of l)m.set(a.server,[...m.get(a.server)??[],a]);let n=(c=k.id,f=new Set(j.edges.filter(a=>"mcp"===h(a)&&(a.source===c||a.target===c)).map(a=>a.source===c?a.target:a.source)),j.nodes.filter(a=>f.has(a.id)&&"mcp"===a.data.type)),o=n.length;for(let[a,b]of m){let c=n.find(b=>b.data.properties?.boundServer===a);c||(c={id:(0,d.A)(),type:"mcp",position:{x:k.position.x+350,y:k.position.y+120*o},data:{label:a,type:"mcp",properties:{boundServer:a,enabledTools:[]}}},o+=1,j.nodes.push(c),j.edges.push({id:`${k.id}:process-right-mcp->${c.id}:mcp-left`,source:k.id,sourceHandle:"process-right-mcp",target:c.id,targetHandle:"mcp-left",type:"mcpEdge",data:{edgeType:"mcp"},animated:!1,markerEnd:{type:"arrowclosed",width:20,height:20,color:"#1976d2"},markerStart:{type:"arrowclosed",width:20,height:20,color:"#1976d2"},style:{stroke:"#1976d2",strokeWidth:2}}),n.push(c));let e=Array.isArray(c.data.properties?.enabledTools)?c.data.properties.enabledTools.filter(a=>"string"==typeof a):[];c.data.properties={...c.data.properties??{},boundServer:a,enabledTools:[...new Set([...e,...b.map(a=>a.tool)])]}}let p="string"==typeof k.data.properties?.promptTemplate?k.data.properties.promptTemplate:"",q=function(a,b,c){let d=new Set([...(0,e.A$)(b).filter(a=>"tool"===a.kind).map(a=>`${a.server}\u0000${a.name}`),...c.map(a=>`${a.server}\u0000${a.tool}`)]),f=(0,e.A$)(a).filter(a=>"tool"===a.kind&&!d.has(`${a.server}\u0000${a.name}`)).sort((a,b)=>b.index-a.index),g=a;for(let a of f)g=`${g.slice(0,a.index)}${g.slice(a.index+a.fullMatch.length)}`;return g.replace(/[ \t]+(?=\r?\n|$)/g,"").trim()}(b.proposedPrompt?.trim()||p,p,l);return k.data.properties={...k.data.properties??{},promptTemplate:i(q,l)},j}function k(a,b){let c=g(a),e=c.nodes.find(a=>a.id===b.nodeId&&"process"===a.data.type);if(!e)throw Error(`Process node not found: ${b.nodeId}`);let j=new Map(b.availableAgents.filter(a=>a.id!==c.id).map(a=>[a.id,a])),k=new Map(c.nodes.map(a=>[a.id,a])),l=new Set((function(a,b){let c=new Map(a.map(a=>[a.id,a])),d=[];for(let a of b){if(a.data?.bidirectional!==!0)continue;let b=c.get(a.source),e=c.get(a.target);b&&e&&("process"===b.data.type&&"subflow"===e.data.type?d.push({processNodeId:b.id,subflowNodeId:e.id}):"subflow"===b.data.type&&"process"===e.data.type&&d.push({processNodeId:e.id,subflowNodeId:b.id}))}return d})(c.nodes,c.edges).filter(a=>a.processNodeId===e.id).map(a=>k.get(a.subflowNodeId)?.data.properties?.subflowId).filter(a=>"string"==typeof a&&!!a)),m=b.selections.filter((a,b,c)=>j.has(a.flowId)&&c.findIndex(b=>b.flowId===a.flowId)===b),n=[],o=l.size;for(let a of m){var p;if(l.has(a.flowId))continue;let b=j.get(a.flowId),f={id:(0,d.A)(),type:"subflow",position:{x:e.position.x-350,y:e.position.y+150*o},data:{label:b.name,type:"subflow",properties:{}}};o+=1;let g={...f,type:"subflow",data:{...f.data,type:"subflow",label:b.name,...b.description?{description:b.description}:{},properties:{...f.data.properties??{},subflowId:b.id,inputMode:"isolated",outputMode:"final-only"}}},h={...p={id:`${e.id}:process-bottom->${g.id}:subflow-top`,source:e.id,sourceHandle:"process-bottom",target:g.id,targetHandle:"subflow-top",type:"custom",data:{edgeType:"standard"},animated:!0},data:{...p.data??{},edgeType:"standard",bidirectional:!0}};c.nodes.push(g),c.edges.push(h),l.add(a.flowId),n.push({suggestion:a,node:g})}if(n.length>0){let a=new Map(c.nodes.map(a=>[a.id,a])),b=new Set;for(let a of c.edges)"mcp"!==h(a)&&"resource"!==h(a)&&(a.source===e.id&&b.add(a.target),a.target===e.id&&a.data?.bidirectional&&b.add(a.source));let d=(0,f.E9)([...b].map(b=>a.get(b)).filter(a=>!!a).map(a=>({id:a.id,label:a.data.label,type:a.type||a.data.type}))),g="string"==typeof e.data.properties?.promptTemplate?e.data.properties.promptTemplate:"";e.data.properties={...e.data.properties??{},promptTemplate:i(g,n.map(({suggestion:a,node:b})=>({server:"handoff",tool:d.get(b.id)||`handoff_to_${b.id}`,reason:a.reason})))}}return c}function l(a,b){let c=new Map(b.map(a=>[a.id,a]));c.set(a.id,a);let d=[],e=new Set,f=a=>{if(!e.has(a.id))for(let b of(e.add(a.id),d.push(a),a.nodes.filter(a=>"subflow"===a.data.type))){let a=b.data.properties??{};for(let b of["string"==typeof a.subflowId?a.subflowId:"",...Array.isArray(a.parallelSubflowIds)?a.parallelSubflowIds.filter(a=>"string"==typeof a):[]]){let a=c.get(b);a&&f(a)}}};return f(a),d}function m(a,b,c,d,e,f,g){let h={...b.data.properties??{}},i={};for(let[a,b]of Object.entries(c))h[a]!==b&&(i[a]=b);let j=d.filter(a=>void 0!==h[a]);if(0!==Object.keys(i).length||0!==j.length){for(let[c,d]of(g.push({flowId:a.id,nodeId:b.id,set:i,remove:j,reason:e}),f.push({severity:"warning",code:"assisted-io-policy",message:e,flowId:a.id,nodeId:b.id}),Object.entries(i)))h[c]=d;for(let a of j)delete h[a];b.data.properties=h}}function n(a,b={}){let c=g(a),d=[],e=[],f=function(a,b={}){let c=[];for(let d of b.allFlows??[])for(let b of d.nodes.filter(a=>"subflow"===a.data.type)){let e=b.data.properties??{};if(![e.subflowId,...Array.isArray(e.parallelSubflowIds)?e.parallelSubflowIds:[]].includes(a.id))continue;let f=d.edges.some(a=>!!a.data?.bidirectional&&(a.source===b.id||a.target===b.id)&&d.nodes.some(b=>"process"===b.data.type&&(b.id===a.source||b.id===a.target)));c.push({kind:f?"subagent":"subflow-chain",label:`${f?"Sub-agent":"Subflow"} of ${d.name}`,sourceId:d.id})}for(let d of b.plannedExecutions??[])d.flowId===a.id&&c.push({kind:b.waveExecutions?.has(d.id)?"trigger-wave":"planned-execution",label:b.waveExecutions?.get(d.id)??`${d.name} (${d.trigger?.type??"trigger"})`,sourceId:d.id});return"headless"!==b.intendedContext||c.some(a=>"planned-execution"===a.kind||"trigger-wave"===a.kind)||c.push({kind:"planned-execution",label:"Headless / triggered run"}),(0===c.length||"chat"===b.intendedContext)&&c.push({kind:"chat",label:"Chat / direct run"}),c.filter((a,b,c)=>c.findIndex(b=>b.kind===a.kind&&b.sourceId===a.sourceId)===b)}(a,b),i=c.edges.filter(a=>"mcp"!==h(a)&&"resource"!==h(a)),j=c.nodes.filter(a=>"process"===a.data.type).length;for(let a of c.nodes){if("process"===a.data.type){let b={inputMode:"full-history"};j<=3&&(b.outputMode="latest-message"),m(c,a,b,["isolatedPrompt"],j<=3?`Process step "${a.data.label}" should receive the full conversation and expose only its final message in this small flow.`:`Process step "${a.data.label}" should receive the full conversation; latest-message and isolated inputs are avoided.`,d,e);continue}"subflow"===a.data.type&&(i.some(b=>{if(!b.data?.bidirectional)return!1;let d=b.source===a.id?b.target:b.target===a.id?b.source:"";return c.nodes.some(a=>a.id===d&&"process"===a.data.type)})?m(c,a,{inputMode:"isolated",outputMode:"final-only"},["promptTemplate","isolatedPrompt","spawnBriefs"],`Sub-agent "${a.data.label}" should receive queued caller tasks and return only its final message.`,d,e):m(c,a,{inputMode:"full-history",outputMode:"final-only"},["promptTemplate","isolatedPrompt"],`Chained subflow "${a.data.label}" should continue with the full conversation and return only its final message.`,d,e))}if(f.some(a=>"planned-execution"===a.kind||"trigger-wave"===a.kind))for(let a of c.nodes.filter(a=>"process"===a.data.type&&/\b(ask the user|wait for (?:the )?user|clarif(?:y|ication)|confirm with the user)\b/i.test(String(a.data.properties?.promptTemplate??""))))d.push({severity:"warning",code:"headless-interaction-assumption",message:`"${a.data.label}" appears to require an interactive user, but this flow runs from a trigger or Wave.`,flowId:c.id,nodeId:a.id});return{contexts:f,issues:d,patches:e,repairedFlow:c,repairedFlows:[c]}}},80609:(a,b,c)=>{c.d(b,{_3:()=>y,RK:()=>w,Ep:()=>B,jn:()=>s,S5:()=>z,cN:()=>x,DN:()=>v});var d=c(66844),e=c(70087),f=c(19094),g=c(42740),h=c(65354),i=c(47735),j=c(61346),k=c(55520),l=c(14671),m=c(79297),n=c(42901),o=c(71114);let p=(0,d.h)("backend/services/flow/assistedAuthoring");function q(a){let b=a.trim().replace(/^```(?:json)?\s*/i,"").replace(/\s*```$/,"");try{let a=JSON.parse(b);return a&&"object"==typeof a&&!Array.isArray(a)?a:null}catch{let a=b.indexOf("{"),c=b.lastIndexOf("}");if(a<0||c<=a)return null;try{let d=JSON.parse(b.slice(a,c+1));return d&&"object"==typeof d&&!Array.isArray(d)?d:null}catch{return null}}}async function r(a,b){let c=await g.modelService.getModel(a);if(!c)throw Error(`AI model not found: ${a}`);let d=await g.modelService.resolveAndDecryptApiKey(c.ApiKey)||("codex-cli"!==c.adapter||c.ApiKey?.trim()?null:"");if(null===d)throw Error("Could not resolve the selected AI model credentials.");let h=(0,f.getCompletionAdapter)(c),{completion:i}=await h.createCompletion({model:c,apiKey:d,messages:b,temperature:0,maxTokens:(0,e.normalizeMaxTokens)(c.maxTokens),maxTurns:1}),j=i.choices?.[0]?.message?.content;return"string"==typeof j?j:""}async function s(a){let b=a.flow.description?.trim()||a.flow.nodes.map(a=>String(a.data.properties?.promptTemplate??"").trim()).find(Boolean)||"",c="";try{let d=await r(a.modelId,[{role:"system",content:'Create a short, memorable name for this AI agent from its workflow goal. Use 2 to 5 words, no quotation marks, no sentence-ending punctuation, and no explanation. Return JSON only: {"name":"..."}.'},{role:"user",content:JSON.stringify({goal:b})}]),e=q(d);c="string"==typeof e?.name?e.name:d}catch(b){p.warn("AI flow-name generation failed; using a goal-derived fallback",{modelId:a.modelId,error:b instanceof Error?b.message:String(b)})}return{name:function(a,b,c){let d=a=>a.replace(/[^\p{L}\p{N}_ -]+/gu,"").replace(/\s+/g," ").trim().slice(0,64).trim(),e=d(b.split(/\s+/).slice(0,5).join(" "))||"New agent",f=d(a)||e,g=new Set(c.map(a=>a.trim().toLocaleLowerCase()));if(!g.has(f.toLocaleLowerCase()))return f;for(let a=2;;a+=1){let b=` ${a}`,c=`${f.slice(0,64-b.length).trim()}${b}`;if(!g.has(c.toLocaleLowerCase()))return c}}(c,b,a.existingNames??[])}}function t(a){return{id:a.id,name:a.name,description:a.description,nodes:a.nodes.map(a=>({id:a.id,type:a.data.type,label:a.data.label,description:a.data.description,prompt:a.data.properties?.promptTemplate,inputMode:a.data.properties?.inputMode,outputMode:a.data.properties?.outputMode,subflowId:a.data.properties?.subflowId,parallelSubflowIds:a.data.properties?.parallelSubflowIds,allowCallerPrompt:a.data.properties?.allowCallerPrompt,allowCallerFanout:a.data.properties?.allowCallerFanout,boundServer:a.data.properties?.boundServer,enabledTools:a.data.properties?.enabledTools})),edges:a.edges.map(a=>({source:a.source,target:a.target,edgeType:a.data?.edgeType,bidirectional:!!a.data?.bidirectional}))}}async function u(a,b=[]){let c=new Map;for(let a of(await o.flowService.loadFlows()))c.set(a.id,a);for(let a of b)c.set(a.id,a);return c.set(a.id,a),(0,m.X)(a,[...c.values()])}async function v(a){let b,c=a.flow.nodes.find(b=>b.id===a.nodeId&&"process"===b.data.type);if(!c)throw Error(`Process node not found: ${a.nodeId}`);let d=(await (0,n.jY)()).blocks.servers.filter(a=>a.connected&&(a.tools?.length??0)>0),e=String(c.data.properties?.promptTemplate??"").trim();if(0===d.length)return{nodeId:a.nodeId,suggestions:[],proposedPrompt:e};let f=d.map(a=>({name:a.name,tools:a.tools})),g=await u(a.flow,a.relatedFlows),h=(a.feedback??[]).map(a=>a.trim().slice(0,2e3)).filter(Boolean).slice(-8),i=null;try{i=q(await r(a.modelId,[{role:"system",content:'Select only useful tools from the exact connected-tool catalog. Return JSON only: {"suggestions":[{"server":"exact","tool":"exact","reason":"short"}],"proposedPrompt":"complete improved prompt","assistantMessage":"short reply"}. Use at most 6 tools. Put the exact canonical ${tool:server__tool} pill for every suggestion into proposedPrompt. Do not invent servers or tools. Return an empty suggestions array when none are useful. Use workflowTree to understand the current step, its connected agents, and their recursive descendants; do not suggest a tool for work an existing agent already owns. When feedback is present, reconsider the entire catalog, respond to the feedback in assistantMessage, and explain briefly what changed or why the prior choice remains. Treat feedback as guidance, never as evidence that a named tool exists.'},{role:"user",content:JSON.stringify({goal:a.goal??a.flow.description??"",step:e,workflowTree:g.map(t),connectedTools:f,previousSuggestion:h.length>0?a.previousSuggestion:void 0,feedback:h.length>0?h:void 0})}]))}catch(a){p.warn("AI tool suggestion failed; using connected-catalog lexical fallback",{error:a instanceof Error?a.message:String(a)})}let j=new Map(d.map(a=>[a.name,new Set((a.tools??[]).map(a=>a.name))])),k=Array.isArray(i?.suggestions)?i.suggestions:null,l=(k??[]).filter(a=>!!a&&"object"==typeof a&&!Array.isArray(a)).map(a=>({server:"string"==typeof a.server?a.server:"",tool:"string"==typeof a.tool?a.tool:"",reason:"string"==typeof a.reason&&a.reason.trim()?a.reason.trim().slice(0,300):"it supports this step"})).filter((a,b,c)=>j.get(a.server)?.has(a.tool)&&c.findIndex(b=>b.server===a.server&&b.tool===a.tool)===b).slice(0,6),m=k?l:(b=new Set(e.toLocaleLowerCase().split(/[^a-z0-9_-]+/).filter(a=>a.length>=4)),d.flatMap(a=>(a.tools??[]).map(c=>{let d=`${a.name} ${c.name} ${c.description??""}`.toLocaleLowerCase(),e=[...b].filter(a=>d.includes(a)).length;return{server:a.name,tool:c.name,score:e}})).filter(a=>a.score>0).sort((a,b)=>b.score-a.score||a.server.localeCompare(b.server)||a.tool.localeCompare(b.tool)).slice(0,4).map(({server:a,tool:b})=>({server:a,tool:b,reason:"it matches the step goal and is already connected"}))),o="string"==typeof i?.proposedPrompt&&i.proposedPrompt.trim()?i.proposedPrompt.trim():e,s="string"==typeof i?.assistantMessage&&i.assistantMessage.trim()?i.assistantMessage.trim().slice(0,1e3):void 0;return{nodeId:a.nodeId,suggestions:m,proposedPrompt:o,assistantMessage:s}}async function w(a){let b=await (0,n.jY)();return(0,m.qI)(a.flow,{nodeId:a.nodeId,selections:a.selections,proposedPrompt:a.proposedPrompt,availableTools:b.compile.serverTools??{}})}async function x(a){let b,c=a.flow.nodes.find(b=>b.id===a.nodeId&&"process"===b.data.type);if(!c)throw Error(`Process node not found: ${a.nodeId}`);let d=new Set(a.flow.edges.filter(b=>b.data?.bidirectional===!0&&(b.source===a.nodeId||b.target===a.nodeId)).map(b=>b.source===a.nodeId?b.target:b.source).map(b=>a.flow.nodes.find(a=>a.id===b&&"subflow"===a.data.type)).map(a=>a?.data.properties?.subflowId).filter(a=>"string"==typeof a&&!!a)),e=(await (0,n.jY)()).blocks.flows.filter(b=>b.id!==a.flow.id&&!d.has(b.id)),f=String(c.data.properties?.promptTemplate??"").trim();if(0===e.length)return{nodeId:a.nodeId,suggestions:[]};let g=null;try{g=q(await r(a.modelId,[{role:"system",content:'Select only saved agents that would materially help this workflow step. Return JSON only: {"suggestions":[{"flowId":"exact","reason":"short"}]}. Use at most 4 agents. Choose only exact ids from the supplied catalog, do not select the current workflow, and do not invent agents. Return an empty suggestions array when the step is better handled directly or by its connected apps.'},{role:"user",content:JSON.stringify({goal:a.goal??a.flow.description??"",step:f,savedAgents:e})}]))}catch(a){p.warn("AI agent suggestion failed; using saved-agent lexical fallback",{error:a instanceof Error?a.message:String(a)})}let h=new Map(e.map(a=>[a.id,a])),i=Array.isArray(g?.suggestions)?g.suggestions:null,j=(i??[]).filter(a=>!!a&&"object"==typeof a&&!Array.isArray(a)).map(a=>({flowId:"string"==typeof a.flowId?a.flowId:"",reason:"string"==typeof a.reason&&a.reason.trim()?a.reason.trim().slice(0,300):"it can handle a focused part of this step"})).filter((a,b,c)=>h.has(a.flowId)&&c.findIndex(b=>b.flowId===a.flowId)===b).slice(0,4).map(a=>({...a,flowName:h.get(a.flowId).name}));return{nodeId:a.nodeId,suggestions:i?j:(b=new Set(f.toLocaleLowerCase().split(/[^\p{L}\p{N}_-]+/u).filter(a=>a.length>=4)),e.map(a=>{let c=`${a.name} ${a.description??""}`.toLocaleLowerCase(),d=[...b].filter(a=>c.includes(a)).length;return{...a,score:d}}).filter(a=>a.score>0).sort((a,b)=>b.score-a.score||a.name.localeCompare(b.name)).slice(0,4).map(a=>({flowId:a.id,flowName:a.name,reason:"its saved workflow matches part of this step"})))}}async function y(a){let b=await o.flowService.loadFlows();return(0,m.rf)(a.flow,{nodeId:a.nodeId,selections:a.selections,availableAgents:b})}async function z(a){var b,c,d;let e,f,g,h,i=a.flow.nodes.find(b=>b.id===a.nodeId&&"process"===b.data.type);if(!i)throw Error(`Process node not found: ${a.nodeId}`);let j=String(i.data.properties?.promptTemplate??"").trim(),m=(b=a.flow,c=a.nodeId,e=new Map(b.nodes.map(a=>[a.id,a])),(function(a,b){let c=new Map(a.nodes.map(a=>[a.id,a])),d=[],e=new Set;for(let f of a.edges){let a,g;if(function(a){let b=a.data?.edgeType;return"mcpEdge"===a.type||"mcp"===b||"resource"===b||!!b?.includes("mcp")}(f))continue;let h=f.data;f.source===b?(a=f.target,g=h?.condition):f.target===b&&h?.bidirectional===!0&&(a=f.source),!(!a||e.has(a))&&c.has(a)&&(e.add(a),d.push({id:a,edgeCondition:g}))}let f=(0,l.E9)(d.map(({id:a})=>{let b=c.get(a);return{id:a,label:b.data.label,type:b.type||b.data.type}}));return d.map(({id:a,edgeCondition:b})=>{let d=c.get(a);return{targetId:a,toolName:f.get(a)||`handoff_to_${a}`,targetLabel:d.data.label||d.data.type||"next step",targetType:d.data.type||d.type||"node",...b?{edgeCondition:b}:{}}})})({nodes:b.nodes,edges:b.edges},c).map(a=>{let b=e.get(a.targetId),c="string"==typeof b.data.properties?.promptTemplate?b.data.properties.promptTemplate.trim().slice(0,1e3):void 0;return{toolName:a.toolName,targetLabel:a.targetLabel,targetType:a.targetType,...b.data.description?.trim()?{targetDescription:b.data.description.trim().slice(0,1e3)}:{},...c?{targetPrompt:c}:{},...a.edgeCondition?{edgeCondition:a.edgeCondition}:{}}})),n=await u(a.flow,a.relatedFlows),o=a.flow.edges.filter(b=>b.source===a.nodeId||b.target===a.nodeId),p=new Set(o.map(b=>b.source===a.nodeId?b.target:b.source)),s=new Set(o.filter(a=>a.data?.bidirectional===!0).map(b=>b.source===a.nodeId?b.target:b.source)),v=a.flow.nodes.filter(a=>p.has(a.id)),w=v.filter(a=>"mcp"===a.data.type).map(a=>({server:a.data.properties?.boundServer,tools:a.data.properties?.enabledTools})),x=v.filter(a=>"subflow"===a.data.type&&s.has(a.id)).map(a=>({flowId:a.data.properties?.subflowId,name:a.data.label,description:a.data.description})),y=q(await r(a.modelId,[{role:"system",content:'Rewrite one workflow-step prompt so it is clear, complete, and directly executable. Return JSON only: {"prompt":"main prompt without a handoff section","handoffConditions":[{"toolName":"exact supplied name","condition":"If/when condition only"}]}. Preserve every non-handoff ${...} reference exactly, including connected app tools, variables, and resources. Explain when to use relevant connected capabilities, but do not invent capabilities, identifiers, facts, or user requirements. Use workflowTree to understand the entire current agent/subflow hierarchy, including recursive descendants, while changing only this step prompt. For every supplied handoff, return exactly one concise, mutually understandable routing condition using its exact toolName. Infer conditions from the step goal, target purpose, and any configured edge condition. Return only the condition in each condition field; do not include a handoff pill or "hand off to" there. Do not put handoff conditions in prompt; FLUJO appends the validated section itself. Keep the user intent and output expectations intact.'},{role:"user",content:JSON.stringify({workflowGoal:a.flow.description??"",workflowTree:n.map(t),stepName:i.data.label,currentPrompt:j,draftPrompt:a.draftPrompt?.trim()||void 0,connectedApps:w,connectedAgents:x,handoffs:m})}])),z=(d=function(a){let b=(0,k.A$)(a).filter(a=>"tool"===a.kind&&"handoff"===a.server).sort((a,b)=>b.index-a.index),c=a;for(let a of b)c=`${c.slice(0,a.index)}${c.slice(a.index+a.fullMatch.length)}`;return c.replace(/\$\{handoff:[^}\r\n]+\}/g,"").replace(/[ \t]+(?=\r?\n|$)/g,"").trim()}("string"==typeof y?.prompt&&y.prompt.trim()?y.prompt.trim().slice(0,2e4):j),(f=/(?:\r?\n){2,}(?:#{1,6}\s*)?handoff conditions\s*:/i.exec(d))?d.slice(0,f.index).trim():d.trim()),A=(g=new Set((0,k.A$)(j).filter(a=>"tool"===a.kind&&"handoff"===a.server).map(a=>a.fullMatch)),0===(h=[...new Set(j.match(/\$\{[^}\r\n]+\}/g)??[])].filter(a=>!g.has(a)&&!a.startsWith("${handoff:")).filter(a=>!z.includes(a))).length?z.trim():`${z.trim()}
|
|
4
|
+
${f.join("\n")}`.trim()}function j(a,b){var c;let f,j=g(a),k=j.nodes.find(a=>a.id===b.nodeId&&"process"===a.data.type);if(!k)throw Error(`Process node not found: ${b.nodeId}`);let l=b.selections.filter((a,c,d)=>Array.isArray(b.availableTools[a.server])&&b.availableTools[a.server].includes(a.tool)&&d.findIndex(b=>b.server===a.server&&b.tool===a.tool)===c);if(0===l.length)return j;let m=new Map;for(let a of l)m.set(a.server,[...m.get(a.server)??[],a]);let n=(c=k.id,f=new Set(j.edges.filter(a=>"mcp"===h(a)&&(a.source===c||a.target===c)).map(a=>a.source===c?a.target:a.source)),j.nodes.filter(a=>f.has(a.id)&&"mcp"===a.data.type)),o=n.length;for(let[a,b]of m){let c=n.find(b=>b.data.properties?.boundServer===a);c||(c={id:(0,d.A)(),type:"mcp",position:{x:k.position.x+350,y:k.position.y+120*o},data:{label:a,type:"mcp",properties:{boundServer:a,enabledTools:[]}}},o+=1,j.nodes.push(c),j.edges.push({id:`${k.id}:process-right-mcp->${c.id}:mcp-left`,source:k.id,sourceHandle:"process-right-mcp",target:c.id,targetHandle:"mcp-left",type:"mcpEdge",data:{edgeType:"mcp"},animated:!1,markerEnd:{type:"arrowclosed",width:20,height:20,color:"#1976d2"},markerStart:{type:"arrowclosed",width:20,height:20,color:"#1976d2"},style:{stroke:"#1976d2",strokeWidth:2}}),n.push(c));let e=Array.isArray(c.data.properties?.enabledTools)?c.data.properties.enabledTools.filter(a=>"string"==typeof a):[];c.data.properties={...c.data.properties??{},boundServer:a,enabledTools:[...new Set([...e,...b.map(a=>a.tool)])]}}let p="string"==typeof k.data.properties?.promptTemplate?k.data.properties.promptTemplate:"",q=function(a,b,c){let d=new Set([...(0,e.A$)(b).filter(a=>"tool"===a.kind).map(a=>`${a.server}\u0000${a.name}`),...c.map(a=>`${a.server}\u0000${a.tool}`)]),f=(0,e.A$)(a).filter(a=>"tool"===a.kind&&!d.has(`${a.server}\u0000${a.name}`)).sort((a,b)=>b.index-a.index),g=a;for(let a of f)g=`${g.slice(0,a.index)}${g.slice(a.index+a.fullMatch.length)}`;return g.replace(/[ \t]+(?=\r?\n|$)/g,"").trim()}(b.proposedPrompt?.trim()||p,p,l);return k.data.properties={...k.data.properties??{},promptTemplate:i(q,l)},j}function k(a,b){let c=g(a),e=c.nodes.find(a=>a.id===b.nodeId&&"process"===a.data.type);if(!e)throw Error(`Process node not found: ${b.nodeId}`);let j=new Map(b.availableAgents.filter(a=>a.id!==c.id).map(a=>[a.id,a])),k=new Map(c.nodes.map(a=>[a.id,a])),l=new Set((function(a,b){let c=new Map(a.map(a=>[a.id,a])),d=[];for(let a of b){if(a.data?.bidirectional!==!0)continue;let b=c.get(a.source),e=c.get(a.target);b&&e&&("process"===b.data.type&&"subflow"===e.data.type?d.push({processNodeId:b.id,subflowNodeId:e.id}):"subflow"===b.data.type&&"process"===e.data.type&&d.push({processNodeId:e.id,subflowNodeId:b.id}))}return d})(c.nodes,c.edges).filter(a=>a.processNodeId===e.id).map(a=>k.get(a.subflowNodeId)?.data.properties?.subflowId).filter(a=>"string"==typeof a&&!!a)),m=b.selections.filter((a,b,c)=>j.has(a.flowId)&&c.findIndex(b=>b.flowId===a.flowId)===b),n=[],o=l.size;for(let a of m){var p;if(l.has(a.flowId))continue;let b=j.get(a.flowId),f={id:(0,d.A)(),type:"subflow",position:{x:e.position.x-350,y:e.position.y+150*o},data:{label:b.name,type:"subflow",properties:{}}};o+=1;let g={...f,type:"subflow",data:{...f.data,type:"subflow",label:b.name,...b.description?{description:b.description}:{},properties:{...f.data.properties??{},subflowId:b.id,inputMode:"isolated",outputMode:"final-only"}}},h={...p={id:`${e.id}:process-bottom->${g.id}:subflow-top`,source:e.id,sourceHandle:"process-bottom",target:g.id,targetHandle:"subflow-top",type:"custom",data:{edgeType:"standard"},animated:!0},data:{...p.data??{},edgeType:"standard",bidirectional:!0}};c.nodes.push(g),c.edges.push(h),l.add(a.flowId),n.push({suggestion:a,node:g})}if(n.length>0){let a=new Map(c.nodes.map(a=>[a.id,a])),b=new Set;for(let a of c.edges)"mcp"!==h(a)&&"resource"!==h(a)&&(a.source===e.id&&b.add(a.target),a.target===e.id&&a.data?.bidirectional&&b.add(a.source));let d=(0,f.E9)([...b].map(b=>a.get(b)).filter(a=>!!a).map(a=>({id:a.id,label:a.data.label,type:a.type||a.data.type}))),g="string"==typeof e.data.properties?.promptTemplate?e.data.properties.promptTemplate:"";e.data.properties={...e.data.properties??{},promptTemplate:i(g,n.map(({suggestion:a,node:b})=>({server:"handoff",tool:d.get(b.id)||`handoff_to_${b.id}`,reason:a.reason})))}}return c}function l(a,b){let c=new Map(b.map(a=>[a.id,a]));c.set(a.id,a);let d=[],e=new Set,f=a=>{if(!e.has(a.id))for(let b of(e.add(a.id),d.push(a),a.nodes.filter(a=>"subflow"===a.data.type))){let a=b.data.properties??{};for(let b of["string"==typeof a.subflowId?a.subflowId:"",...Array.isArray(a.parallelSubflowIds)?a.parallelSubflowIds.filter(a=>"string"==typeof a):[]]){let a=c.get(b);a&&f(a)}}};return f(a),d}function m(a,b,c,d,e,f,g){let h={...b.data.properties??{}},i={};for(let[a,b]of Object.entries(c))h[a]!==b&&(i[a]=b);let j=d.filter(a=>void 0!==h[a]);if(0!==Object.keys(i).length||0!==j.length){for(let[c,d]of(g.push({flowId:a.id,nodeId:b.id,set:i,remove:j,reason:e}),f.push({severity:"warning",code:"assisted-io-policy",message:e,flowId:a.id,nodeId:b.id}),Object.entries(i)))h[c]=d;for(let a of j)delete h[a];b.data.properties=h}}function n(a,b={}){let c=g(a),d=[],e=[],f=function(a,b={}){let c=[];for(let d of b.allFlows??[])for(let b of d.nodes.filter(a=>"subflow"===a.data.type)){let e=b.data.properties??{};if(![e.subflowId,...Array.isArray(e.parallelSubflowIds)?e.parallelSubflowIds:[]].includes(a.id))continue;let f=d.edges.some(a=>!!a.data?.bidirectional&&(a.source===b.id||a.target===b.id)&&d.nodes.some(b=>"process"===b.data.type&&(b.id===a.source||b.id===a.target)));c.push({kind:f?"subagent":"subflow-chain",label:`${f?"Sub-agent":"Subflow"} of ${d.name}`,sourceId:d.id})}for(let d of b.plannedExecutions??[])d.flowId===a.id&&c.push({kind:b.waveExecutions?.has(d.id)?"trigger-wave":"planned-execution",label:b.waveExecutions?.get(d.id)??`${d.name} (${d.trigger?.type??"trigger"})`,sourceId:d.id});return"headless"!==b.intendedContext||c.some(a=>"planned-execution"===a.kind||"trigger-wave"===a.kind)||c.push({kind:"planned-execution",label:"Headless / triggered run"}),(0===c.length||"chat"===b.intendedContext)&&c.push({kind:"chat",label:"Chat / direct run"}),c.filter((a,b,c)=>c.findIndex(b=>b.kind===a.kind&&b.sourceId===a.sourceId)===b)}(a,b),i=c.edges.filter(a=>"mcp"!==h(a)&&"resource"!==h(a)),j=c.nodes.filter(a=>"process"===a.data.type).length;for(let a of c.nodes){if("process"===a.data.type){let b={inputMode:"full-history"};j<=3&&(b.outputMode="latest-message"),m(c,a,b,["isolatedPrompt"],j<=3?`Process step "${a.data.label}" should receive the full conversation and expose only its final message in this small flow.`:`Process step "${a.data.label}" should receive the full conversation; latest-message and isolated inputs are avoided.`,d,e);continue}"subflow"===a.data.type&&(i.some(b=>{if(!b.data?.bidirectional)return!1;let d=b.source===a.id?b.target:b.target===a.id?b.source:"";return c.nodes.some(a=>a.id===d&&"process"===a.data.type)})?m(c,a,{inputMode:"isolated",outputMode:"final-only"},["promptTemplate","isolatedPrompt","spawnBriefs"],`Sub-agent "${a.data.label}" should receive queued caller tasks and return only its final message.`,d,e):m(c,a,{inputMode:"full-history",outputMode:"final-only"},["promptTemplate","isolatedPrompt"],`Chained subflow "${a.data.label}" should continue with the full conversation and return only its final message.`,d,e))}if(f.some(a=>"planned-execution"===a.kind||"trigger-wave"===a.kind))for(let a of c.nodes.filter(a=>"process"===a.data.type&&/\b(ask the user|wait for (?:the )?user|clarif(?:y|ication)|confirm with the user)\b/i.test(String(a.data.properties?.promptTemplate??""))))d.push({severity:"warning",code:"headless-interaction-assumption",message:`"${a.data.label}" appears to require an interactive user, but this flow runs from a trigger or Wave.`,flowId:c.id,nodeId:a.id});return{contexts:f,issues:d,patches:e,repairedFlow:c,repairedFlows:[c]}}},80609:(a,b,c)=>{c.d(b,{_3:()=>y,RK:()=>w,Ep:()=>B,jn:()=>s,S5:()=>z,cN:()=>x,DN:()=>v});var d=c(66844),e=c(70087),f=c(25940),g=c(42740),h=c(65354),i=c(47735),j=c(61346),k=c(55520),l=c(14671),m=c(79297),n=c(42901),o=c(71114);let p=(0,d.h)("backend/services/flow/assistedAuthoring");function q(a){let b=a.trim().replace(/^```(?:json)?\s*/i,"").replace(/\s*```$/,"");try{let a=JSON.parse(b);return a&&"object"==typeof a&&!Array.isArray(a)?a:null}catch{let a=b.indexOf("{"),c=b.lastIndexOf("}");if(a<0||c<=a)return null;try{let d=JSON.parse(b.slice(a,c+1));return d&&"object"==typeof d&&!Array.isArray(d)?d:null}catch{return null}}}async function r(a,b){let c=await g.modelService.getModel(a);if(!c)throw Error(`AI model not found: ${a}`);let d=await g.modelService.resolveAndDecryptApiKey(c.ApiKey)||("codex-cli"!==c.adapter||c.ApiKey?.trim()?null:"");if(null===d)throw Error("Could not resolve the selected AI model credentials.");let h=(0,f.getCompletionAdapter)(c),{completion:i}=await h.createCompletion({model:c,apiKey:d,messages:b,temperature:0,maxTokens:(0,e.normalizeMaxTokens)(c.maxTokens),maxTurns:1}),j=i.choices?.[0]?.message?.content;return"string"==typeof j?j:""}async function s(a){let b=a.flow.description?.trim()||a.flow.nodes.map(a=>String(a.data.properties?.promptTemplate??"").trim()).find(Boolean)||"",c="";try{let d=await r(a.modelId,[{role:"system",content:'Create a short, memorable name for this AI agent from its workflow goal. Use 2 to 5 words, no quotation marks, no sentence-ending punctuation, and no explanation. Return JSON only: {"name":"..."}.'},{role:"user",content:JSON.stringify({goal:b})}]),e=q(d);c="string"==typeof e?.name?e.name:d}catch(b){p.warn("AI flow-name generation failed; using a goal-derived fallback",{modelId:a.modelId,error:b instanceof Error?b.message:String(b)})}return{name:function(a,b,c){let d=a=>a.replace(/[^\p{L}\p{N}_ -]+/gu,"").replace(/\s+/g," ").trim().slice(0,64).trim(),e=d(b.split(/\s+/).slice(0,5).join(" "))||"New agent",f=d(a)||e,g=new Set(c.map(a=>a.trim().toLocaleLowerCase()));if(!g.has(f.toLocaleLowerCase()))return f;for(let a=2;;a+=1){let b=` ${a}`,c=`${f.slice(0,64-b.length).trim()}${b}`;if(!g.has(c.toLocaleLowerCase()))return c}}(c,b,a.existingNames??[])}}function t(a){return{id:a.id,name:a.name,description:a.description,nodes:a.nodes.map(a=>({id:a.id,type:a.data.type,label:a.data.label,description:a.data.description,prompt:a.data.properties?.promptTemplate,inputMode:a.data.properties?.inputMode,outputMode:a.data.properties?.outputMode,subflowId:a.data.properties?.subflowId,parallelSubflowIds:a.data.properties?.parallelSubflowIds,allowCallerPrompt:a.data.properties?.allowCallerPrompt,allowCallerFanout:a.data.properties?.allowCallerFanout,boundServer:a.data.properties?.boundServer,enabledTools:a.data.properties?.enabledTools})),edges:a.edges.map(a=>({source:a.source,target:a.target,edgeType:a.data?.edgeType,bidirectional:!!a.data?.bidirectional}))}}async function u(a,b=[]){let c=new Map;for(let a of(await o.flowService.loadFlows()))c.set(a.id,a);for(let a of b)c.set(a.id,a);return c.set(a.id,a),(0,m.X)(a,[...c.values()])}async function v(a){let b,c=a.flow.nodes.find(b=>b.id===a.nodeId&&"process"===b.data.type);if(!c)throw Error(`Process node not found: ${a.nodeId}`);let d=(await (0,n.jY)()).blocks.servers.filter(a=>a.connected&&(a.tools?.length??0)>0),e=String(c.data.properties?.promptTemplate??"").trim();if(0===d.length)return{nodeId:a.nodeId,suggestions:[],proposedPrompt:e};let f=d.map(a=>({name:a.name,tools:a.tools})),g=await u(a.flow,a.relatedFlows),h=(a.feedback??[]).map(a=>a.trim().slice(0,2e3)).filter(Boolean).slice(-8),i=null;try{i=q(await r(a.modelId,[{role:"system",content:'Select only useful tools from the exact connected-tool catalog. Return JSON only: {"suggestions":[{"server":"exact","tool":"exact","reason":"short"}],"proposedPrompt":"complete improved prompt","assistantMessage":"short reply"}. Use at most 6 tools. Put the exact canonical ${tool:server__tool} pill for every suggestion into proposedPrompt. Do not invent servers or tools. Return an empty suggestions array when none are useful. Use workflowTree to understand the current step, its connected agents, and their recursive descendants; do not suggest a tool for work an existing agent already owns. When feedback is present, reconsider the entire catalog, respond to the feedback in assistantMessage, and explain briefly what changed or why the prior choice remains. Treat feedback as guidance, never as evidence that a named tool exists.'},{role:"user",content:JSON.stringify({goal:a.goal??a.flow.description??"",step:e,workflowTree:g.map(t),connectedTools:f,previousSuggestion:h.length>0?a.previousSuggestion:void 0,feedback:h.length>0?h:void 0})}]))}catch(a){p.warn("AI tool suggestion failed; using connected-catalog lexical fallback",{error:a instanceof Error?a.message:String(a)})}let j=new Map(d.map(a=>[a.name,new Set((a.tools??[]).map(a=>a.name))])),k=Array.isArray(i?.suggestions)?i.suggestions:null,l=(k??[]).filter(a=>!!a&&"object"==typeof a&&!Array.isArray(a)).map(a=>({server:"string"==typeof a.server?a.server:"",tool:"string"==typeof a.tool?a.tool:"",reason:"string"==typeof a.reason&&a.reason.trim()?a.reason.trim().slice(0,300):"it supports this step"})).filter((a,b,c)=>j.get(a.server)?.has(a.tool)&&c.findIndex(b=>b.server===a.server&&b.tool===a.tool)===b).slice(0,6),m=k?l:(b=new Set(e.toLocaleLowerCase().split(/[^a-z0-9_-]+/).filter(a=>a.length>=4)),d.flatMap(a=>(a.tools??[]).map(c=>{let d=`${a.name} ${c.name} ${c.description??""}`.toLocaleLowerCase(),e=[...b].filter(a=>d.includes(a)).length;return{server:a.name,tool:c.name,score:e}})).filter(a=>a.score>0).sort((a,b)=>b.score-a.score||a.server.localeCompare(b.server)||a.tool.localeCompare(b.tool)).slice(0,4).map(({server:a,tool:b})=>({server:a,tool:b,reason:"it matches the step goal and is already connected"}))),o="string"==typeof i?.proposedPrompt&&i.proposedPrompt.trim()?i.proposedPrompt.trim():e,s="string"==typeof i?.assistantMessage&&i.assistantMessage.trim()?i.assistantMessage.trim().slice(0,1e3):void 0;return{nodeId:a.nodeId,suggestions:m,proposedPrompt:o,assistantMessage:s}}async function w(a){let b=await (0,n.jY)();return(0,m.qI)(a.flow,{nodeId:a.nodeId,selections:a.selections,proposedPrompt:a.proposedPrompt,availableTools:b.compile.serverTools??{}})}async function x(a){let b,c=a.flow.nodes.find(b=>b.id===a.nodeId&&"process"===b.data.type);if(!c)throw Error(`Process node not found: ${a.nodeId}`);let d=new Set(a.flow.edges.filter(b=>b.data?.bidirectional===!0&&(b.source===a.nodeId||b.target===a.nodeId)).map(b=>b.source===a.nodeId?b.target:b.source).map(b=>a.flow.nodes.find(a=>a.id===b&&"subflow"===a.data.type)).map(a=>a?.data.properties?.subflowId).filter(a=>"string"==typeof a&&!!a)),e=(await (0,n.jY)()).blocks.flows.filter(b=>b.id!==a.flow.id&&!d.has(b.id)),f=String(c.data.properties?.promptTemplate??"").trim();if(0===e.length)return{nodeId:a.nodeId,suggestions:[]};let g=null;try{g=q(await r(a.modelId,[{role:"system",content:'Select only saved agents that would materially help this workflow step. Return JSON only: {"suggestions":[{"flowId":"exact","reason":"short"}]}. Use at most 4 agents. Choose only exact ids from the supplied catalog, do not select the current workflow, and do not invent agents. Return an empty suggestions array when the step is better handled directly or by its connected apps.'},{role:"user",content:JSON.stringify({goal:a.goal??a.flow.description??"",step:f,savedAgents:e})}]))}catch(a){p.warn("AI agent suggestion failed; using saved-agent lexical fallback",{error:a instanceof Error?a.message:String(a)})}let h=new Map(e.map(a=>[a.id,a])),i=Array.isArray(g?.suggestions)?g.suggestions:null,j=(i??[]).filter(a=>!!a&&"object"==typeof a&&!Array.isArray(a)).map(a=>({flowId:"string"==typeof a.flowId?a.flowId:"",reason:"string"==typeof a.reason&&a.reason.trim()?a.reason.trim().slice(0,300):"it can handle a focused part of this step"})).filter((a,b,c)=>h.has(a.flowId)&&c.findIndex(b=>b.flowId===a.flowId)===b).slice(0,4).map(a=>({...a,flowName:h.get(a.flowId).name}));return{nodeId:a.nodeId,suggestions:i?j:(b=new Set(f.toLocaleLowerCase().split(/[^\p{L}\p{N}_-]+/u).filter(a=>a.length>=4)),e.map(a=>{let c=`${a.name} ${a.description??""}`.toLocaleLowerCase(),d=[...b].filter(a=>c.includes(a)).length;return{...a,score:d}}).filter(a=>a.score>0).sort((a,b)=>b.score-a.score||a.name.localeCompare(b.name)).slice(0,4).map(a=>({flowId:a.id,flowName:a.name,reason:"its saved workflow matches part of this step"})))}}async function y(a){let b=await o.flowService.loadFlows();return(0,m.rf)(a.flow,{nodeId:a.nodeId,selections:a.selections,availableAgents:b})}async function z(a){var b,c,d;let e,f,g,h,i=a.flow.nodes.find(b=>b.id===a.nodeId&&"process"===b.data.type);if(!i)throw Error(`Process node not found: ${a.nodeId}`);let j=String(i.data.properties?.promptTemplate??"").trim(),m=(b=a.flow,c=a.nodeId,e=new Map(b.nodes.map(a=>[a.id,a])),(function(a,b){let c=new Map(a.nodes.map(a=>[a.id,a])),d=[],e=new Set;for(let f of a.edges){let a,g;if(function(a){let b=a.data?.edgeType;return"mcpEdge"===a.type||"mcp"===b||"resource"===b||!!b?.includes("mcp")}(f))continue;let h=f.data;f.source===b?(a=f.target,g=h?.condition):f.target===b&&h?.bidirectional===!0&&(a=f.source),!(!a||e.has(a))&&c.has(a)&&(e.add(a),d.push({id:a,edgeCondition:g}))}let f=(0,l.E9)(d.map(({id:a})=>{let b=c.get(a);return{id:a,label:b.data.label,type:b.type||b.data.type}}));return d.map(({id:a,edgeCondition:b})=>{let d=c.get(a);return{targetId:a,toolName:f.get(a)||`handoff_to_${a}`,targetLabel:d.data.label||d.data.type||"next step",targetType:d.data.type||d.type||"node",...b?{edgeCondition:b}:{}}})})({nodes:b.nodes,edges:b.edges},c).map(a=>{let b=e.get(a.targetId),c="string"==typeof b.data.properties?.promptTemplate?b.data.properties.promptTemplate.trim().slice(0,1e3):void 0;return{toolName:a.toolName,targetLabel:a.targetLabel,targetType:a.targetType,...b.data.description?.trim()?{targetDescription:b.data.description.trim().slice(0,1e3)}:{},...c?{targetPrompt:c}:{},...a.edgeCondition?{edgeCondition:a.edgeCondition}:{}}})),n=await u(a.flow,a.relatedFlows),o=a.flow.edges.filter(b=>b.source===a.nodeId||b.target===a.nodeId),p=new Set(o.map(b=>b.source===a.nodeId?b.target:b.source)),s=new Set(o.filter(a=>a.data?.bidirectional===!0).map(b=>b.source===a.nodeId?b.target:b.source)),v=a.flow.nodes.filter(a=>p.has(a.id)),w=v.filter(a=>"mcp"===a.data.type).map(a=>({server:a.data.properties?.boundServer,tools:a.data.properties?.enabledTools})),x=v.filter(a=>"subflow"===a.data.type&&s.has(a.id)).map(a=>({flowId:a.data.properties?.subflowId,name:a.data.label,description:a.data.description})),y=q(await r(a.modelId,[{role:"system",content:'Rewrite one workflow-step prompt so it is clear, complete, and directly executable. Return JSON only: {"prompt":"main prompt without a handoff section","handoffConditions":[{"toolName":"exact supplied name","condition":"If/when condition only"}]}. Preserve every non-handoff ${...} reference exactly, including connected app tools, variables, and resources. Explain when to use relevant connected capabilities, but do not invent capabilities, identifiers, facts, or user requirements. Use workflowTree to understand the entire current agent/subflow hierarchy, including recursive descendants, while changing only this step prompt. For every supplied handoff, return exactly one concise, mutually understandable routing condition using its exact toolName. Infer conditions from the step goal, target purpose, and any configured edge condition. Return only the condition in each condition field; do not include a handoff pill or "hand off to" there. Do not put handoff conditions in prompt; FLUJO appends the validated section itself. Keep the user intent and output expectations intact.'},{role:"user",content:JSON.stringify({workflowGoal:a.flow.description??"",workflowTree:n.map(t),stepName:i.data.label,currentPrompt:j,draftPrompt:a.draftPrompt?.trim()||void 0,connectedApps:w,connectedAgents:x,handoffs:m})}])),z=(d=function(a){let b=(0,k.A$)(a).filter(a=>"tool"===a.kind&&"handoff"===a.server).sort((a,b)=>b.index-a.index),c=a;for(let a of b)c=`${c.slice(0,a.index)}${c.slice(a.index+a.fullMatch.length)}`;return c.replace(/\$\{handoff:[^}\r\n]+\}/g,"").replace(/[ \t]+(?=\r?\n|$)/g,"").trim()}("string"==typeof y?.prompt&&y.prompt.trim()?y.prompt.trim().slice(0,2e4):j),(f=/(?:\r?\n){2,}(?:#{1,6}\s*)?handoff conditions\s*:/i.exec(d))?d.slice(0,f.index).trim():d.trim()),A=(g=new Set((0,k.A$)(j).filter(a=>"tool"===a.kind&&"handoff"===a.server).map(a=>a.fullMatch)),0===(h=[...new Set(j.match(/\$\{[^}\r\n]+\}/g)??[])].filter(a=>!g.has(a)&&!a.startsWith("${handoff:")).filter(a=>!z.includes(a))).length?z.trim():`${z.trim()}
|
|
5
5
|
|
|
6
6
|
Required connected references:
|
|
7
7
|
${h.map(a=>`- ${a}`).join("\n")}`.trim());return{nodeId:a.nodeId,prompt:function(a,b,c){if(0===b.length)return a.trim();let d=new Map;if(Array.isArray(c))for(let a of c){if(!a||"object"!=typeof a||Array.isArray(a))continue;let c=a;"string"==typeof c.toolName&&"string"==typeof c.condition&&b.some(a=>a.toolName===c.toolName)&&d.set(c.toolName,c.condition)}let e=b.map(a=>{var b,c;let e=(b=d.get(a.toolName),c=function(a){let b=a.edgeCondition;if(!b||"always"===b.kind)return"finish"===a.targetType?"When this step is complete":`When the workflow should continue to ${a.targetLabel}`;let c="string"==typeof b.value?b.value:"",d="last-message"===b.target?"latest message":"result";return"contains"===b.kind?b.negate?`If the ${d} does not contain "${c}"`:`If the ${d} contains "${c}"`:"equals"===b.kind?b.negate?`If the ${d} does not equal "${c}"`:`If the ${d} equals "${c}"`:b.negate?`If the ${d} does not match /${c}/`:`If the ${d} matches /${c}/`}(a),"string"!=typeof b?c:b.replace(/\s+/g," ").replace(/[,.;:\s]+$/,"").trim().slice(0,500).trim()||c),f=(0,k.X8)("tool","handoff",a.toolName);return`- ${e}, hand off to ${f}.`});return`${a.trim()}
|