chat-flow-ardymalihi 1.0.2 → 3.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/{adapters → src/adapters}/intent/IntentMatcher.d.ts +16 -0
- package/dist/src/adapters/intent/IntentMatcher.d.ts.map +1 -0
- package/dist/src/adapters/intent/IntentMatcher.js +167 -0
- package/dist/src/adapters/intent/IntentMatcher.js.map +1 -0
- package/dist/{adapters → src/adapters}/intent/IntentService.d.ts +4 -5
- package/dist/src/adapters/intent/IntentService.d.ts.map +1 -0
- package/dist/{adapters → src/adapters}/intent/IntentService.js +15 -9
- package/dist/src/adapters/intent/IntentService.js.map +1 -0
- package/dist/src/adapters/intent/MockIntentService.d.ts +7 -0
- package/dist/src/adapters/intent/MockIntentService.d.ts.map +1 -0
- package/dist/{intent → src/adapters/intent}/MockIntentService.js +9 -3
- package/dist/src/adapters/intent/MockIntentService.js.map +1 -0
- package/dist/src/adapters/llm/GeminiLLMAdapter.d.ts.map +1 -0
- package/dist/src/adapters/llm/GeminiLLMAdapter.js.map +1 -0
- package/dist/src/adapters/llm/MockLLMAdapter.d.ts.map +1 -0
- package/dist/src/adapters/llm/MockLLMAdapter.js.map +1 -0
- package/dist/src/adapters/llm/OllamaLLMAdapter.d.ts +9 -0
- package/dist/src/adapters/llm/OllamaLLMAdapter.d.ts.map +1 -0
- package/dist/src/adapters/llm/OllamaLLMAdapter.js +74 -0
- package/dist/src/adapters/llm/OllamaLLMAdapter.js.map +1 -0
- package/dist/src/adapters/logger/ConsoleLogger.d.ts +12 -0
- package/dist/src/adapters/logger/ConsoleLogger.d.ts.map +1 -0
- package/dist/src/adapters/logger/ConsoleLogger.js +37 -0
- package/dist/src/adapters/logger/ConsoleLogger.js.map +1 -0
- package/dist/src/adapters/repository/InMemoryRepository.d.ts +57 -0
- package/dist/src/adapters/repository/InMemoryRepository.d.ts.map +1 -0
- package/dist/src/adapters/repository/InMemoryRepository.js +269 -0
- package/dist/src/adapters/repository/InMemoryRepository.js.map +1 -0
- package/dist/src/adapters/repository/RedisRepository.d.ts +72 -0
- package/dist/src/adapters/repository/RedisRepository.d.ts.map +1 -0
- package/dist/src/adapters/repository/RedisRepository.js +700 -0
- package/dist/src/adapters/repository/RedisRepository.js.map +1 -0
- package/dist/src/adapters/repository/SupabaseRepository.d.ts +60 -0
- package/dist/src/adapters/repository/SupabaseRepository.d.ts.map +1 -0
- package/dist/src/adapters/repository/SupabaseRepository.js +774 -0
- package/dist/src/adapters/repository/SupabaseRepository.js.map +1 -0
- package/dist/src/adapters/storage/RedisAudioStorageAdapter.d.ts +33 -0
- package/dist/src/adapters/storage/RedisAudioStorageAdapter.d.ts.map +1 -0
- package/dist/src/adapters/storage/RedisAudioStorageAdapter.js +121 -0
- package/dist/src/adapters/storage/RedisAudioStorageAdapter.js.map +1 -0
- package/dist/src/adapters/voice/GoogleVoiceAdapter.d.ts +33 -0
- package/dist/src/adapters/voice/GoogleVoiceAdapter.d.ts.map +1 -0
- package/dist/src/adapters/voice/GoogleVoiceAdapter.js +155 -0
- package/dist/src/adapters/voice/GoogleVoiceAdapter.js.map +1 -0
- package/dist/src/adapters/voice/LanguageVoiceMapper.d.ts +60 -0
- package/dist/src/adapters/voice/LanguageVoiceMapper.d.ts.map +1 -0
- package/dist/src/adapters/voice/LanguageVoiceMapper.js +130 -0
- package/dist/src/adapters/voice/LanguageVoiceMapper.js.map +1 -0
- package/dist/src/adapters/voice/VertexVoiceAdapter.d.ts +32 -0
- package/dist/src/adapters/voice/VertexVoiceAdapter.d.ts.map +1 -0
- package/dist/src/adapters/voice/VertexVoiceAdapter.js +179 -0
- package/dist/src/adapters/voice/VertexVoiceAdapter.js.map +1 -0
- package/dist/src/adapters/webhook/WebhookService.d.ts +47 -0
- package/dist/src/adapters/webhook/WebhookService.d.ts.map +1 -0
- package/dist/src/adapters/webhook/WebhookService.js +265 -0
- package/dist/src/adapters/webhook/WebhookService.js.map +1 -0
- package/dist/src/adapters/workflow/MockWorkflowAdapter.d.ts.map +1 -0
- package/dist/{workflow → src/adapters/workflow}/MockWorkflowAdapter.js +12 -1
- package/dist/src/adapters/workflow/MockWorkflowAdapter.js.map +1 -0
- package/dist/src/adapters/workflow/WorkflowAdapter.d.ts +55 -0
- package/dist/src/adapters/workflow/WorkflowAdapter.d.ts.map +1 -0
- package/dist/src/adapters/workflow/WorkflowAdapter.js +203 -0
- package/dist/src/adapters/workflow/WorkflowAdapter.js.map +1 -0
- package/dist/src/adapters/workflow/actions/index.d.ts +6 -0
- package/dist/src/adapters/workflow/actions/index.d.ts.map +1 -0
- package/dist/src/adapters/workflow/actions/index.js +22 -0
- package/dist/src/adapters/workflow/actions/index.js.map +1 -0
- package/dist/src/adapters/workflow/actions/pushOutputResultAction.d.ts +11 -0
- package/dist/src/adapters/workflow/actions/pushOutputResultAction.d.ts.map +1 -0
- package/dist/src/adapters/workflow/actions/pushOutputResultAction.js +31 -0
- package/dist/src/adapters/workflow/actions/pushOutputResultAction.js.map +1 -0
- package/dist/src/adapters/workflow/engine/constants.d.ts +3 -0
- package/dist/src/adapters/workflow/engine/constants.d.ts.map +1 -0
- package/dist/src/adapters/workflow/engine/constants.js +6 -0
- package/dist/src/adapters/workflow/engine/constants.js.map +1 -0
- package/dist/src/adapters/workflow/engine/engine.d.ts +32 -0
- package/dist/src/adapters/workflow/engine/engine.d.ts.map +1 -0
- package/dist/src/adapters/workflow/engine/engine.js +622 -0
- package/dist/src/adapters/workflow/engine/engine.js.map +1 -0
- package/dist/src/adapters/workflow/engine/event-registry.d.ts +12 -0
- package/dist/src/adapters/workflow/engine/event-registry.d.ts.map +1 -0
- package/dist/src/adapters/workflow/engine/event-registry.js +33 -0
- package/dist/src/adapters/workflow/engine/event-registry.js.map +1 -0
- package/dist/src/adapters/workflow/engine/interpolator.d.ts +11 -0
- package/dist/src/adapters/workflow/engine/interpolator.d.ts.map +1 -0
- package/dist/src/adapters/workflow/engine/interpolator.js +93 -0
- package/dist/src/adapters/workflow/engine/interpolator.js.map +1 -0
- package/dist/src/adapters/workflow/engine/registry.d.ts +12 -0
- package/dist/src/adapters/workflow/engine/registry.d.ts.map +1 -0
- package/dist/src/adapters/workflow/engine/registry.js +39 -0
- package/dist/src/adapters/workflow/engine/registry.js.map +1 -0
- package/dist/src/adapters/workflow/engine/template-registry.d.ts +60 -0
- package/dist/src/adapters/workflow/engine/template-registry.d.ts.map +1 -0
- package/dist/src/adapters/workflow/engine/template-registry.js +92 -0
- package/dist/src/adapters/workflow/engine/template-registry.js.map +1 -0
- package/dist/src/adapters/workflow/engine/utils/format-utils.d.ts +43 -0
- package/dist/src/adapters/workflow/engine/utils/format-utils.d.ts.map +1 -0
- package/dist/src/adapters/workflow/engine/utils/format-utils.js +137 -0
- package/dist/src/adapters/workflow/engine/utils/format-utils.js.map +1 -0
- package/dist/src/adapters/workflow/engine/utils/layout-calculator.d.ts +7 -0
- package/dist/src/adapters/workflow/engine/utils/layout-calculator.d.ts.map +1 -0
- package/dist/src/adapters/workflow/engine/utils/layout-calculator.js +87 -0
- package/dist/src/adapters/workflow/engine/utils/layout-calculator.js.map +1 -0
- package/dist/src/adapters/workflow/engine/utils/slugify.d.ts +2 -0
- package/dist/src/adapters/workflow/engine/utils/slugify.d.ts.map +1 -0
- package/dist/src/adapters/workflow/engine/utils/slugify.js +41 -0
- package/dist/src/adapters/workflow/engine/utils/slugify.js.map +1 -0
- package/dist/src/adapters/workflow/engine/validator.d.ts +9 -0
- package/dist/src/adapters/workflow/engine/validator.d.ts.map +1 -0
- package/dist/src/adapters/workflow/engine/validator.js +425 -0
- package/dist/src/adapters/workflow/engine/validator.js.map +1 -0
- package/dist/src/api/router.d.ts +3 -0
- package/dist/src/api/router.d.ts.map +1 -0
- package/dist/src/api/router.js +27 -0
- package/dist/src/api/router.js.map +1 -0
- package/dist/src/api/routes/configs.d.ts +3 -0
- package/dist/src/api/routes/configs.d.ts.map +1 -0
- package/dist/src/api/routes/configs.js +110 -0
- package/dist/src/api/routes/configs.js.map +1 -0
- package/dist/src/api/routes/executions.d.ts +3 -0
- package/dist/src/api/routes/executions.d.ts.map +1 -0
- package/dist/src/api/routes/executions.js +77 -0
- package/dist/src/api/routes/executions.js.map +1 -0
- package/dist/src/api/routes/intents.d.ts +3 -0
- package/dist/src/api/routes/intents.d.ts.map +1 -0
- package/dist/src/api/routes/intents.js +128 -0
- package/dist/src/api/routes/intents.js.map +1 -0
- package/dist/src/api/routes/sessions.d.ts +3 -0
- package/dist/src/api/routes/sessions.d.ts.map +1 -0
- package/dist/src/api/routes/sessions.js +105 -0
- package/dist/src/api/routes/sessions.js.map +1 -0
- package/dist/src/api/routes/users.d.ts +3 -0
- package/dist/src/api/routes/users.d.ts.map +1 -0
- package/dist/src/api/routes/users.js +51 -0
- package/dist/src/api/routes/users.js.map +1 -0
- package/dist/src/api/routes/workflows.d.ts +3 -0
- package/dist/src/api/routes/workflows.d.ts.map +1 -0
- package/dist/src/api/routes/workflows.js +132 -0
- package/dist/src/api/routes/workflows.js.map +1 -0
- package/dist/{config → src/config}/ChatFlowConfig.d.ts +7 -0
- package/dist/src/config/ChatFlowConfig.d.ts.map +1 -0
- package/dist/{config → src/config}/ChatFlowConfig.js +5 -0
- package/dist/src/config/ChatFlowConfig.js.map +1 -0
- package/dist/src/config/index.d.ts.map +1 -0
- package/dist/src/config/index.js.map +1 -0
- package/dist/src/config/swagger.d.ts +2 -0
- package/dist/src/config/swagger.d.ts.map +1 -0
- package/dist/src/config/swagger.js +136 -0
- package/dist/src/config/swagger.js.map +1 -0
- package/dist/src/core/entities/ConversationSession.d.ts +58 -0
- package/dist/src/core/entities/ConversationSession.d.ts.map +1 -0
- package/dist/src/core/entities/ConversationSession.js +160 -0
- package/dist/src/core/entities/ConversationSession.js.map +1 -0
- package/dist/{core → src/core}/entities/Message.d.ts +5 -2
- package/dist/src/core/entities/Message.d.ts.map +1 -0
- package/dist/{core → src/core}/entities/Message.js +2 -0
- package/dist/src/core/entities/Message.js.map +1 -0
- package/dist/src/core/errors/ChatFlowError.d.ts.map +1 -0
- package/dist/src/core/errors/ChatFlowError.js.map +1 -0
- package/dist/src/core/errors/index.d.ts.map +1 -0
- package/dist/src/core/errors/index.js.map +1 -0
- package/dist/src/core/utils/AudioUtils.d.ts +41 -0
- package/dist/src/core/utils/AudioUtils.d.ts.map +1 -0
- package/dist/src/core/utils/AudioUtils.js +188 -0
- package/dist/src/core/utils/AudioUtils.js.map +1 -0
- package/dist/src/core/utils/LanguageDetector.d.ts +52 -0
- package/dist/src/core/utils/LanguageDetector.d.ts.map +1 -0
- package/dist/src/core/utils/LanguageDetector.js +173 -0
- package/dist/src/core/utils/LanguageDetector.js.map +1 -0
- package/dist/src/demo/cli-demo.d.ts.map +1 -0
- package/dist/{demo → src/demo}/cli-demo.js +10 -6
- package/dist/src/demo/cli-demo.js.map +1 -0
- package/dist/src/demo/console-chat.d.ts.map +1 -0
- package/dist/{demo → src/demo}/console-chat.js +10 -6
- package/dist/src/demo/console-chat.js.map +1 -0
- package/dist/{index.d.ts → src/index.d.ts} +10 -5
- package/dist/src/index.d.ts.map +1 -0
- package/dist/{index.js → src/index.js} +25 -8
- package/dist/src/index.js.map +1 -0
- package/dist/src/interfaces.d.ts +663 -0
- package/dist/src/interfaces.d.ts.map +1 -0
- package/dist/src/interfaces.js +36 -0
- package/dist/src/interfaces.js.map +1 -0
- package/dist/src/orchestrator/Orchestrator.d.ts +62 -0
- package/dist/src/orchestrator/Orchestrator.d.ts.map +1 -0
- package/dist/src/orchestrator/Orchestrator.js +697 -0
- package/dist/src/orchestrator/Orchestrator.js.map +1 -0
- package/dist/src/scripts/debug-redis.d.ts.map +1 -0
- package/dist/src/scripts/debug-redis.js.map +1 -0
- package/dist/src/scripts/seed-collaborative-intents.d.ts +2 -0
- package/dist/src/scripts/seed-collaborative-intents.d.ts.map +1 -0
- package/dist/src/scripts/seed-collaborative-intents.js +90 -0
- package/dist/src/scripts/seed-collaborative-intents.js.map +1 -0
- package/dist/src/scripts/test-isolated-config.d.ts +2 -0
- package/dist/src/scripts/test-isolated-config.d.ts.map +1 -0
- package/dist/src/scripts/test-isolated-config.js +80 -0
- package/dist/src/scripts/test-isolated-config.js.map +1 -0
- package/dist/src/scripts/verify_memory_intents.d.ts.map +1 -0
- package/dist/src/scripts/verify_memory_intents.js.map +1 -0
- package/dist/src/scripts/verify_redis_intents.d.ts.map +1 -0
- package/dist/{scripts → src/scripts}/verify_redis_intents.js +4 -2
- package/dist/src/scripts/verify_redis_intents.js.map +1 -0
- package/dist/src/server/ChatFlowWebSocketServer.d.ts +42 -0
- package/dist/src/server/ChatFlowWebSocketServer.d.ts.map +1 -0
- package/dist/src/server/ChatFlowWebSocketServer.js +355 -0
- package/dist/src/server/ChatFlowWebSocketServer.js.map +1 -0
- package/dist/src/utils/crypto.d.ts +7 -0
- package/dist/src/utils/crypto.d.ts.map +1 -0
- package/dist/src/utils/crypto.js +35 -0
- package/dist/src/utils/crypto.js.map +1 -0
- package/dist/src/utils/encryption-helpers.d.ts +14 -0
- package/dist/src/utils/encryption-helpers.d.ts.map +1 -0
- package/dist/src/utils/encryption-helpers.js +49 -0
- package/dist/src/utils/encryption-helpers.js.map +1 -0
- package/dist/web/seed-demo-data.d.ts +2 -0
- package/dist/web/seed-demo-data.d.ts.map +1 -0
- package/dist/web/seed-demo-data.js +267 -0
- package/dist/web/seed-demo-data.js.map +1 -0
- package/dist/web/web-server.d.ts +2 -0
- package/dist/web/web-server.d.ts.map +1 -0
- package/dist/web/web-server.js +165 -0
- package/dist/web/web-server.js.map +1 -0
- package/package.json +32 -3
- package/dist/adapters/db/InMemorySessionRepository.js +0 -15
- package/dist/adapters/db/RedisSessionRepository.js +0 -41
- package/dist/adapters/intent/IntentMatcher.d.ts.map +0 -1
- package/dist/adapters/intent/IntentMatcher.js +0 -89
- package/dist/adapters/intent/IntentMatcher.js.map +0 -1
- package/dist/adapters/intent/IntentService.d.ts.map +0 -1
- package/dist/adapters/intent/IntentService.js.map +0 -1
- package/dist/adapters/intent/MockIntentAdapter.js +0 -29
- package/dist/adapters/llm/GeminiLLMAdapter.d.ts.map +0 -1
- package/dist/adapters/llm/GeminiLLMAdapter.js.map +0 -1
- package/dist/adapters/llm/MockLLMAdapter.d.ts.map +0 -1
- package/dist/adapters/llm/MockLLMAdapter.js.map +0 -1
- package/dist/adapters/memory/InMemorySessionRepository.js +0 -15
- package/dist/adapters/redis/RedisSessionRepository.js +0 -41
- package/dist/adapters/repository/InMemoryRepository.d.ts +0 -15
- package/dist/adapters/repository/InMemoryRepository.d.ts.map +0 -1
- package/dist/adapters/repository/InMemoryRepository.js +0 -41
- package/dist/adapters/repository/InMemoryRepository.js.map +0 -1
- package/dist/adapters/repository/IntentRepository.d.ts +0 -15
- package/dist/adapters/repository/IntentRepository.d.ts.map +0 -1
- package/dist/adapters/repository/IntentRepository.js +0 -28
- package/dist/adapters/repository/IntentRepository.js.map +0 -1
- package/dist/adapters/repository/RedisRepository.d.ts +0 -16
- package/dist/adapters/repository/RedisRepository.d.ts.map +0 -1
- package/dist/adapters/repository/RedisRepository.js +0 -87
- package/dist/adapters/repository/RedisRepository.js.map +0 -1
- package/dist/adapters/workflow/MockWorkflowAdapter.d.ts.map +0 -1
- package/dist/adapters/workflow/MockWorkflowAdapter.js +0 -162
- package/dist/adapters/workflow/MockWorkflowAdapter.js.map +0 -1
- package/dist/application/ConversationSession.d.ts +0 -23
- package/dist/application/ConversationSession.d.ts.map +0 -1
- package/dist/application/ConversationSession.js +0 -83
- package/dist/application/ConversationSession.js.map +0 -1
- package/dist/application/Message.d.ts +0 -11
- package/dist/application/Message.d.ts.map +0 -1
- package/dist/application/Message.js +0 -30
- package/dist/application/Message.js.map +0 -1
- package/dist/application/Orchestrator.d.ts +0 -18
- package/dist/application/Orchestrator.d.ts.map +0 -1
- package/dist/application/Orchestrator.js +0 -80
- package/dist/application/Orchestrator.js.map +0 -1
- package/dist/application/SessionState.js +0 -2
- package/dist/application/usecases/CreateSession.js +0 -20
- package/dist/application/usecases/HandleUserMessage.js +0 -69
- package/dist/config/ChatFlowConfig.d.ts.map +0 -1
- package/dist/config/ChatFlowConfig.js.map +0 -1
- package/dist/config/index.d.ts.map +0 -1
- package/dist/config/index.js.map +0 -1
- package/dist/core/entities/ConversationSession.d.ts +0 -23
- package/dist/core/entities/ConversationSession.d.ts.map +0 -1
- package/dist/core/entities/ConversationSession.js +0 -83
- package/dist/core/entities/ConversationSession.js.map +0 -1
- package/dist/core/entities/Message.d.ts.map +0 -1
- package/dist/core/entities/Message.js.map +0 -1
- package/dist/core/errors/ChatFlowError.d.ts.map +0 -1
- package/dist/core/errors/ChatFlowError.js.map +0 -1
- package/dist/core/errors/index.d.ts.map +0 -1
- package/dist/core/errors/index.js.map +0 -1
- package/dist/db/InMemoryRepository.d.ts +0 -15
- package/dist/db/InMemoryRepository.d.ts.map +0 -1
- package/dist/db/InMemoryRepository.js +0 -41
- package/dist/db/InMemoryRepository.js.map +0 -1
- package/dist/db/RedisRepository.d.ts +0 -16
- package/dist/db/RedisRepository.d.ts.map +0 -1
- package/dist/db/RedisRepository.js +0 -87
- package/dist/db/RedisRepository.js.map +0 -1
- package/dist/demo/cli-demo.d.ts.map +0 -1
- package/dist/demo/cli-demo.js.map +0 -1
- package/dist/demo/console-chat.d.ts.map +0 -1
- package/dist/demo/console-chat.js.map +0 -1
- package/dist/domain/conversation/ConversationSession.js +0 -82
- package/dist/domain/conversation/Message.js +0 -33
- package/dist/domain/conversation/SessionState.js +0 -10
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/intent/IntentService.d.ts +0 -17
- package/dist/intent/IntentService.d.ts.map +0 -1
- package/dist/intent/IntentService.js +0 -51
- package/dist/intent/IntentService.js.map +0 -1
- package/dist/intent/MockIntentService.d.ts +0 -6
- package/dist/intent/MockIntentService.d.ts.map +0 -1
- package/dist/intent/MockIntentService.js.map +0 -1
- package/dist/interfaces.d.ts +0 -108
- package/dist/interfaces.d.ts.map +0 -1
- package/dist/interfaces.js +0 -18
- package/dist/interfaces.js.map +0 -1
- package/dist/llm/GeminiLLMAdapter.d.ts +0 -10
- package/dist/llm/GeminiLLMAdapter.d.ts.map +0 -1
- package/dist/llm/GeminiLLMAdapter.js +0 -102
- package/dist/llm/GeminiLLMAdapter.js.map +0 -1
- package/dist/llm/MockLLMAdapter.d.ts +0 -5
- package/dist/llm/MockLLMAdapter.d.ts.map +0 -1
- package/dist/llm/MockLLMAdapter.js +0 -31
- package/dist/llm/MockLLMAdapter.js.map +0 -1
- package/dist/orchestrator/Orchestrator.d.ts +0 -18
- package/dist/orchestrator/Orchestrator.d.ts.map +0 -1
- package/dist/orchestrator/Orchestrator.js +0 -80
- package/dist/orchestrator/Orchestrator.js.map +0 -1
- package/dist/ports/IIntentRepository.d.ts +0 -27
- package/dist/ports/IIntentRepository.d.ts.map +0 -1
- package/dist/ports/IIntentRepository.js +0 -3
- package/dist/ports/IIntentRepository.js.map +0 -1
- package/dist/ports/IntentPort.js +0 -2
- package/dist/ports/LLMPort.js +0 -2
- package/dist/ports/SessionRepository.js +0 -2
- package/dist/ports/WorkflowPort.js +0 -2
- package/dist/scripts/debug-redis.d.ts.map +0 -1
- package/dist/scripts/debug-redis.js.map +0 -1
- package/dist/scripts/verify_memory_intents.d.ts.map +0 -1
- package/dist/scripts/verify_memory_intents.js.map +0 -1
- package/dist/scripts/verify_redis_intents.d.ts.map +0 -1
- package/dist/scripts/verify_redis_intents.js.map +0 -1
- package/dist/verify_memory_intents.js +0 -44
- package/dist/verify_redis_intents.js +0 -49
- package/dist/workflow/MockWorkflowAdapter.d.ts +0 -5
- package/dist/workflow/MockWorkflowAdapter.d.ts.map +0 -1
- package/dist/workflow/MockWorkflowAdapter.js.map +0 -1
- /package/dist/{adapters → src/adapters}/llm/GeminiLLMAdapter.d.ts +0 -0
- /package/dist/{adapters → src/adapters}/llm/GeminiLLMAdapter.js +0 -0
- /package/dist/{adapters → src/adapters}/llm/MockLLMAdapter.d.ts +0 -0
- /package/dist/{adapters → src/adapters}/llm/MockLLMAdapter.js +0 -0
- /package/dist/{adapters → src/adapters}/workflow/MockWorkflowAdapter.d.ts +0 -0
- /package/dist/{config → src/config}/index.d.ts +0 -0
- /package/dist/{config → src/config}/index.js +0 -0
- /package/dist/{core → src/core}/errors/ChatFlowError.d.ts +0 -0
- /package/dist/{core → src/core}/errors/ChatFlowError.js +0 -0
- /package/dist/{core → src/core}/errors/index.d.ts +0 -0
- /package/dist/{core → src/core}/errors/index.js +0 -0
- /package/dist/{demo → src/demo}/cli-demo.d.ts +0 -0
- /package/dist/{demo → src/demo}/console-chat.d.ts +0 -0
- /package/dist/{scripts → src/scripts}/debug-redis.d.ts +0 -0
- /package/dist/{scripts → src/scripts}/debug-redis.js +0 -0
- /package/dist/{scripts → src/scripts}/verify_memory_intents.d.ts +0 -0
- /package/dist/{scripts → src/scripts}/verify_memory_intents.js +0 -0
- /package/dist/{scripts → src/scripts}/verify_redis_intents.d.ts +0 -0
|
@@ -0,0 +1,774 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SupabaseRepository = void 0;
|
|
4
|
+
const supabase_js_1 = require("@supabase/supabase-js");
|
|
5
|
+
const lru_cache_1 = require("lru-cache");
|
|
6
|
+
const ConversationSession_1 = require("../../core/entities/ConversationSession");
|
|
7
|
+
const encryption_helpers_1 = require("../../utils/encryption-helpers");
|
|
8
|
+
const DEFAULT_CACHE_TTL_SECONDS = 120; // 2 minutes
|
|
9
|
+
class SupabaseRepository {
|
|
10
|
+
constructor(config) {
|
|
11
|
+
this.supabase = (0, supabase_js_1.createClient)(config.supabaseUrl, config.supabaseKey);
|
|
12
|
+
this.CACHE_TTL_MS = (config.cacheTtlSeconds || DEFAULT_CACHE_TTL_SECONDS) * 1000;
|
|
13
|
+
this.cache = new lru_cache_1.LRUCache({
|
|
14
|
+
max: 500, // Max 500 items in memory
|
|
15
|
+
ttl: this.CACHE_TTL_MS,
|
|
16
|
+
allowStale: false,
|
|
17
|
+
});
|
|
18
|
+
console.log(`[SupabaseRepository] Initialized with Cache TTL: ${this.CACHE_TTL_MS / 1000} s`);
|
|
19
|
+
}
|
|
20
|
+
getCacheKey(type, id) {
|
|
21
|
+
return `${type}:${id} `;
|
|
22
|
+
}
|
|
23
|
+
// ============================================================================
|
|
24
|
+
// Session Management (Write Heavy - Limited Caching)
|
|
25
|
+
// ============================================================================
|
|
26
|
+
async saveSession(session) {
|
|
27
|
+
const snapshot = session.toSnapshot();
|
|
28
|
+
const { error } = await this.supabase
|
|
29
|
+
.from('chat_flow_sessions')
|
|
30
|
+
.upsert({
|
|
31
|
+
session_id: session.sessionId,
|
|
32
|
+
user_id: session.userId || null, // null for global if uuid
|
|
33
|
+
config_id: session.configId,
|
|
34
|
+
data: (0, encryption_helpers_1.encryptJSON)(snapshot), // Store full snapshot in JSONB
|
|
35
|
+
status: session.status,
|
|
36
|
+
updated_at: new Date().toISOString()
|
|
37
|
+
}, { onConflict: 'session_id' });
|
|
38
|
+
if (error) {
|
|
39
|
+
console.error('[Supabase] Failed to save session:', error);
|
|
40
|
+
throw new Error(`Failed to save session: ${error.message} `);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
async findSessionById(sessionId) {
|
|
44
|
+
const { data, error } = await this.supabase
|
|
45
|
+
.from('chat_flow_sessions')
|
|
46
|
+
.select('data')
|
|
47
|
+
.eq('session_id', sessionId)
|
|
48
|
+
.single();
|
|
49
|
+
if (error) {
|
|
50
|
+
if (error.code === 'PGRST116')
|
|
51
|
+
return null; // Not found code
|
|
52
|
+
console.error('[Supabase] Failed to find session:', error);
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
if (!data || !data.data)
|
|
56
|
+
return null;
|
|
57
|
+
try {
|
|
58
|
+
const decryptedData = (0, encryption_helpers_1.decryptJSON)(data.data);
|
|
59
|
+
return ConversationSession_1.ConversationSession.reconstitute(decryptedData);
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
console.error(`Failed to reconstitute session ${sessionId} `, err);
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
async getAllSessions(userId, limit = 50, offset = 0) {
|
|
67
|
+
// Get Total
|
|
68
|
+
const countRes = await this.supabase
|
|
69
|
+
.from('chat_flow_sessions')
|
|
70
|
+
.select('*', { count: 'exact', head: true })
|
|
71
|
+
.eq('user_id', userId);
|
|
72
|
+
const total = countRes.count || 0;
|
|
73
|
+
// Get Data
|
|
74
|
+
const { data, error } = await this.supabase
|
|
75
|
+
.from('chat_flow_sessions')
|
|
76
|
+
.select('data')
|
|
77
|
+
.eq('user_id', userId)
|
|
78
|
+
.order('updated_at', { ascending: false })
|
|
79
|
+
.range(offset, offset + limit - 1);
|
|
80
|
+
if (error) {
|
|
81
|
+
console.error('[Supabase] Failed to list sessions:', error);
|
|
82
|
+
return { sessions: [], total: 0 };
|
|
83
|
+
}
|
|
84
|
+
const sessions = (data || [])
|
|
85
|
+
.map((row) => {
|
|
86
|
+
try {
|
|
87
|
+
return ConversationSession_1.ConversationSession.reconstitute(row.data);
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
})
|
|
93
|
+
.filter((s) => s !== null);
|
|
94
|
+
return { sessions, total };
|
|
95
|
+
}
|
|
96
|
+
// ============================================================================
|
|
97
|
+
// User & Config Management (Read Heavy - Unbounded Time Caching)
|
|
98
|
+
// ============================================================================
|
|
99
|
+
async findUserById(id) {
|
|
100
|
+
const cacheKey = this.getCacheKey('user', id);
|
|
101
|
+
if (this.cache.has(cacheKey))
|
|
102
|
+
return this.cache.get(cacheKey);
|
|
103
|
+
const { data, error } = await this.supabase.auth.admin.getUserById(id);
|
|
104
|
+
if (error || !data || !data.user) {
|
|
105
|
+
console.error('[SupabaseRepository] findUserById failed:', error);
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
const u = data.user;
|
|
109
|
+
const user = {
|
|
110
|
+
id: u.id,
|
|
111
|
+
name: u.user_metadata?.name || u.user_metadata?.full_name || 'Unknown',
|
|
112
|
+
apiKey: u.user_metadata?.api_key || '',
|
|
113
|
+
metadata: u.user_metadata || {}
|
|
114
|
+
};
|
|
115
|
+
this.cache.set(cacheKey, user);
|
|
116
|
+
return user;
|
|
117
|
+
}
|
|
118
|
+
async saveConversationConfig(config) {
|
|
119
|
+
const { error } = await this.supabase
|
|
120
|
+
.from('chat_flow_configs')
|
|
121
|
+
.upsert({
|
|
122
|
+
id: config.id,
|
|
123
|
+
user_id: config.userId,
|
|
124
|
+
system_prompt: config.systemPrompt,
|
|
125
|
+
voice_config: config.voiceConfig,
|
|
126
|
+
allowed_intents: config.allowedIntents,
|
|
127
|
+
allowed_origins: config.allowedOrigins,
|
|
128
|
+
metadata: config.metadata,
|
|
129
|
+
ui_config: config.uiConfig,
|
|
130
|
+
blacklisted_words: config.blacklistedWords,
|
|
131
|
+
exit_phrases: config.exitPhrases,
|
|
132
|
+
multi_lingual_mode: config.multiLingualMode,
|
|
133
|
+
default_language: config.defaultLanguage,
|
|
134
|
+
supported_languages: config.supportedLanguages,
|
|
135
|
+
language_voice_mapping: config.languageVoiceMapping,
|
|
136
|
+
webhook: config.webhook
|
|
137
|
+
});
|
|
138
|
+
if (error)
|
|
139
|
+
throw new Error(error.message);
|
|
140
|
+
this.cache.delete(this.getCacheKey('config', config.id));
|
|
141
|
+
this.cache.delete(this.getCacheKey('configs', config.userId));
|
|
142
|
+
}
|
|
143
|
+
async findConversationConfig(userId, configId) {
|
|
144
|
+
// If configId provided, fetch precise
|
|
145
|
+
if (configId) {
|
|
146
|
+
const cacheKey = this.getCacheKey('config', configId);
|
|
147
|
+
if (this.cache.has(cacheKey))
|
|
148
|
+
return this.cache.get(cacheKey);
|
|
149
|
+
const { data, error } = await this.supabase
|
|
150
|
+
.from('chat_flow_configs')
|
|
151
|
+
.select('*')
|
|
152
|
+
.eq('id', configId)
|
|
153
|
+
.eq('user_id', userId)
|
|
154
|
+
.single();
|
|
155
|
+
if (error || !data)
|
|
156
|
+
return null;
|
|
157
|
+
const config = this.mapConfig(data);
|
|
158
|
+
this.cache.set(cacheKey, config);
|
|
159
|
+
return config;
|
|
160
|
+
}
|
|
161
|
+
// Use getAll to find first if no ID
|
|
162
|
+
const all = await this.getAllConversationConfigs(userId);
|
|
163
|
+
return all.length > 0 ? all[0] : null;
|
|
164
|
+
}
|
|
165
|
+
async getAllConversationConfigs(userId) {
|
|
166
|
+
const cacheKey = this.getCacheKey('configs', userId);
|
|
167
|
+
if (this.cache.has(cacheKey))
|
|
168
|
+
return this.cache.get(cacheKey);
|
|
169
|
+
const { data, error } = await this.supabase
|
|
170
|
+
.from('chat_flow_configs')
|
|
171
|
+
.select('*')
|
|
172
|
+
.eq('user_id', userId);
|
|
173
|
+
if (error)
|
|
174
|
+
return [];
|
|
175
|
+
const configs = data.map(this.mapConfig);
|
|
176
|
+
this.cache.set(cacheKey, configs);
|
|
177
|
+
return configs;
|
|
178
|
+
}
|
|
179
|
+
mapConfig(data) {
|
|
180
|
+
return {
|
|
181
|
+
id: data.id,
|
|
182
|
+
userId: data.user_id,
|
|
183
|
+
systemPrompt: data.system_prompt,
|
|
184
|
+
voiceConfig: data.voice_config,
|
|
185
|
+
allowedIntents: data.allowed_intents,
|
|
186
|
+
allowedOrigins: data.allowed_origins,
|
|
187
|
+
metadata: data.metadata,
|
|
188
|
+
uiConfig: data.ui_config,
|
|
189
|
+
blacklistedWords: data.blacklisted_words,
|
|
190
|
+
exitPhrases: data.exit_phrases,
|
|
191
|
+
multiLingualMode: data.multi_lingual_mode,
|
|
192
|
+
defaultLanguage: data.default_language,
|
|
193
|
+
supportedLanguages: data.supported_languages,
|
|
194
|
+
languageVoiceMapping: data.language_voice_mapping,
|
|
195
|
+
webhook: data.webhook
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
// ============================================================================
|
|
199
|
+
// Intent Management
|
|
200
|
+
// ============================================================================
|
|
201
|
+
async saveIntent(intent) {
|
|
202
|
+
const userId = intent.userId;
|
|
203
|
+
const { error } = await this.supabase
|
|
204
|
+
.from('chat_flow_intents')
|
|
205
|
+
.upsert({
|
|
206
|
+
name: intent.name,
|
|
207
|
+
user_id: userId,
|
|
208
|
+
description: intent.description,
|
|
209
|
+
required_fields: intent.required_fields,
|
|
210
|
+
optional_fields: intent.optional_fields,
|
|
211
|
+
processing_messages: intent.processingMessages,
|
|
212
|
+
skip_workflow: intent.skipWorkflow
|
|
213
|
+
}, { onConflict: 'name, user_id' }); // Assuming composite key
|
|
214
|
+
if (error)
|
|
215
|
+
throw new Error(error.message);
|
|
216
|
+
if (userId) {
|
|
217
|
+
this.cache.delete(this.getCacheKey('intents', userId));
|
|
218
|
+
this.cache.delete(this.getCacheKey('intent', `${userId}:${intent.name} `));
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
async upsertIntents(intents) {
|
|
222
|
+
// Not atomic in Supabase client for unrelated rows easily, loop is fine
|
|
223
|
+
for (const intent of intents) {
|
|
224
|
+
await this.saveIntent(intent);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
async findIntentByName(name, userId) {
|
|
228
|
+
if (!userId)
|
|
229
|
+
return null;
|
|
230
|
+
const cacheKey = this.getCacheKey('intent', `${userId}:${name} `);
|
|
231
|
+
if (this.cache.has(cacheKey))
|
|
232
|
+
return this.cache.get(cacheKey);
|
|
233
|
+
const { data } = await this.supabase
|
|
234
|
+
.from('chat_flow_intents')
|
|
235
|
+
.select('*')
|
|
236
|
+
.eq('name', name)
|
|
237
|
+
.eq('user_id', userId)
|
|
238
|
+
.single();
|
|
239
|
+
if (data) {
|
|
240
|
+
const intent = this.mapIntent(data);
|
|
241
|
+
this.cache.set(cacheKey, intent);
|
|
242
|
+
return intent;
|
|
243
|
+
}
|
|
244
|
+
return null;
|
|
245
|
+
}
|
|
246
|
+
async getAllIntents(userId) {
|
|
247
|
+
if (!userId)
|
|
248
|
+
return [];
|
|
249
|
+
const cacheKey = this.getCacheKey('intents', userId);
|
|
250
|
+
if (this.cache.has(cacheKey))
|
|
251
|
+
return this.cache.get(cacheKey);
|
|
252
|
+
const { data, error } = await this.supabase
|
|
253
|
+
.from('chat_flow_intents')
|
|
254
|
+
.select('*')
|
|
255
|
+
.eq('user_id', userId);
|
|
256
|
+
if (error)
|
|
257
|
+
return [];
|
|
258
|
+
const intents = data.map(d => this.mapIntent(d));
|
|
259
|
+
this.cache.set(cacheKey, intents);
|
|
260
|
+
return intents;
|
|
261
|
+
}
|
|
262
|
+
async deleteIntent(name, userId) {
|
|
263
|
+
if (!userId)
|
|
264
|
+
return;
|
|
265
|
+
await this.supabase
|
|
266
|
+
.from('chat_flow_intents')
|
|
267
|
+
.delete()
|
|
268
|
+
.eq('name', name)
|
|
269
|
+
.eq('user_id', userId);
|
|
270
|
+
this.cache.delete(this.getCacheKey('intents', userId));
|
|
271
|
+
this.cache.delete(this.getCacheKey('intent', `${userId}:${name} `));
|
|
272
|
+
}
|
|
273
|
+
mapIntent(data) {
|
|
274
|
+
return {
|
|
275
|
+
id: data.id,
|
|
276
|
+
userId: data.user_id,
|
|
277
|
+
name: data.name,
|
|
278
|
+
description: data.description,
|
|
279
|
+
required_fields: data.required_fields || [],
|
|
280
|
+
optional_fields: data.optional_fields || [],
|
|
281
|
+
processingMessages: data.processing_messages,
|
|
282
|
+
skipWorkflow: data.skip_workflow
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
// ============================================================================
|
|
286
|
+
// Workflow Management
|
|
287
|
+
// ============================================================================
|
|
288
|
+
async saveWorkflow(workflow) {
|
|
289
|
+
const userId = workflow.userId;
|
|
290
|
+
const payload = {
|
|
291
|
+
user_id: userId,
|
|
292
|
+
name: workflow.name,
|
|
293
|
+
description: workflow.description,
|
|
294
|
+
event_type: workflow.event_type,
|
|
295
|
+
definition: (0, encryption_helpers_1.encryptJSON)(workflow.definition),
|
|
296
|
+
configs: (0, encryption_helpers_1.encryptJSON)(workflow.configs),
|
|
297
|
+
is_active: workflow.is_active,
|
|
298
|
+
updated_at: new Date().toISOString(),
|
|
299
|
+
viewport: workflow.viewport,
|
|
300
|
+
priority: workflow.priority || 100
|
|
301
|
+
};
|
|
302
|
+
// If ID is provided (update or seed), include it
|
|
303
|
+
if (workflow.id) {
|
|
304
|
+
payload.id = workflow.id;
|
|
305
|
+
}
|
|
306
|
+
// Use UPSERT: This handles both "Update Existing" and "Insert New with specified ID"
|
|
307
|
+
// This fixes the issue where seeding with a UUID failed because UPDATE found 0 rows.
|
|
308
|
+
const { data, error } = await this.supabase
|
|
309
|
+
.from('chat_flow_workflows')
|
|
310
|
+
.upsert(payload, { onConflict: 'id' })
|
|
311
|
+
.select('id')
|
|
312
|
+
.single();
|
|
313
|
+
if (error) {
|
|
314
|
+
console.error('[Supabase] Save workflow failed:', error);
|
|
315
|
+
throw new Error(error.message);
|
|
316
|
+
}
|
|
317
|
+
const resultId = data.id;
|
|
318
|
+
// Separate handling for Cron Configs (Separate Table)
|
|
319
|
+
// Strategy: Delete existing config for this workflow and insert new if present
|
|
320
|
+
if (workflow.workflow_cron_configs) {
|
|
321
|
+
await this.supabase
|
|
322
|
+
.from('chat_flow_workflow_cron_configs')
|
|
323
|
+
.delete()
|
|
324
|
+
.eq('workflow_id', resultId);
|
|
325
|
+
const cronEntries = Array.isArray(workflow.workflow_cron_configs)
|
|
326
|
+
? workflow.workflow_cron_configs
|
|
327
|
+
: [workflow.workflow_cron_configs];
|
|
328
|
+
// Filter out empty/invalid configs
|
|
329
|
+
const validCronEntries = cronEntries.filter(c => c && c.cron_schedule);
|
|
330
|
+
if (validCronEntries.length > 0) {
|
|
331
|
+
const cronPayloads = validCronEntries.map(c => ({
|
|
332
|
+
workflow_id: resultId,
|
|
333
|
+
user_id: userId,
|
|
334
|
+
cron_schedule: c.cron_schedule,
|
|
335
|
+
next_run_at: c.next_run_at || new Date().toISOString()
|
|
336
|
+
}));
|
|
337
|
+
const { error: cronError } = await this.supabase
|
|
338
|
+
.from('chat_flow_workflow_cron_configs')
|
|
339
|
+
.insert(cronPayloads);
|
|
340
|
+
if (cronError)
|
|
341
|
+
console.error('[Supabase] Failed to save cron configs:', cronError);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
if (userId) {
|
|
345
|
+
// Invalidate Caches
|
|
346
|
+
this.cache.delete(this.getCacheKey('workflow', `${userId}:${resultId} `));
|
|
347
|
+
this.cache.delete(this.getCacheKey('workflows', userId));
|
|
348
|
+
// Also invalidate event-specific cache.
|
|
349
|
+
// Note: Cache key logic in getActiveWorkflowsForEvent is `workflows:${userId}:${eventType}`
|
|
350
|
+
// But getCacheKey('workflows:event', ...) isn't standard.
|
|
351
|
+
// Let's manually reconstruct the key used in getActiveWorkflowsForEvent:
|
|
352
|
+
this.cache.delete(this.getCacheKey('workflows', `${userId}:${workflow.event_type}`));
|
|
353
|
+
}
|
|
354
|
+
return resultId;
|
|
355
|
+
}
|
|
356
|
+
async findWorkflowById(id, userId) {
|
|
357
|
+
if (!userId)
|
|
358
|
+
return null;
|
|
359
|
+
const cacheKey = this.getCacheKey('workflow', `${userId}:${id} `);
|
|
360
|
+
if (this.cache.has(cacheKey))
|
|
361
|
+
return this.cache.get(cacheKey);
|
|
362
|
+
const { data, error } = await this.supabase
|
|
363
|
+
.from('chat_flow_workflows')
|
|
364
|
+
.select(`
|
|
365
|
+
*,
|
|
366
|
+
workflow_cron_configs: chat_flow_workflow_cron_configs(*)
|
|
367
|
+
`) // Join cron configs
|
|
368
|
+
.eq('id', id)
|
|
369
|
+
.eq('user_id', userId)
|
|
370
|
+
.single();
|
|
371
|
+
if (error || !data)
|
|
372
|
+
return null;
|
|
373
|
+
const workflow = this.mapWorkflow(data);
|
|
374
|
+
this.cache.set(cacheKey, workflow);
|
|
375
|
+
return workflow;
|
|
376
|
+
}
|
|
377
|
+
async getAllWorkflows(userId) {
|
|
378
|
+
if (!userId)
|
|
379
|
+
return [];
|
|
380
|
+
const cacheKey = this.getCacheKey('workflows', userId);
|
|
381
|
+
if (this.cache.has(cacheKey))
|
|
382
|
+
return this.cache.get(cacheKey);
|
|
383
|
+
const { data, error } = await this.supabase
|
|
384
|
+
.from('chat_flow_workflows')
|
|
385
|
+
.select(`
|
|
386
|
+
*,
|
|
387
|
+
workflow_cron_configs: chat_flow_workflow_cron_configs(*)
|
|
388
|
+
`)
|
|
389
|
+
.eq('user_id', userId);
|
|
390
|
+
if (error)
|
|
391
|
+
return [];
|
|
392
|
+
const workflows = data.map(this.mapWorkflow);
|
|
393
|
+
this.cache.set(cacheKey, workflows);
|
|
394
|
+
return workflows;
|
|
395
|
+
}
|
|
396
|
+
async getActiveWorkflowsForEvent(userId, eventType) {
|
|
397
|
+
if (!userId)
|
|
398
|
+
return [];
|
|
399
|
+
const cacheKey = this.getCacheKey('workflows:event', `${userId}:${eventType} `);
|
|
400
|
+
if (this.cache.has(cacheKey))
|
|
401
|
+
return this.cache.get(cacheKey);
|
|
402
|
+
const { data, error } = await this.supabase
|
|
403
|
+
.from('chat_flow_workflows')
|
|
404
|
+
.select(`
|
|
405
|
+
*,
|
|
406
|
+
workflow_cron_configs: chat_flow_workflow_cron_configs(*)
|
|
407
|
+
`)
|
|
408
|
+
.eq('user_id', userId)
|
|
409
|
+
.eq('event_type', eventType)
|
|
410
|
+
.eq('is_active', true);
|
|
411
|
+
if (error) {
|
|
412
|
+
console.error('[Supabase] Failed to fetch active workflows:', error);
|
|
413
|
+
return [];
|
|
414
|
+
}
|
|
415
|
+
const workflows = data.map(this.mapWorkflow);
|
|
416
|
+
this.cache.set(cacheKey, workflows);
|
|
417
|
+
return workflows;
|
|
418
|
+
}
|
|
419
|
+
async deleteWorkflow(id, userId) {
|
|
420
|
+
if (!userId)
|
|
421
|
+
return;
|
|
422
|
+
await this.supabase
|
|
423
|
+
.from('chat_flow_workflows')
|
|
424
|
+
.delete()
|
|
425
|
+
.eq('id', id)
|
|
426
|
+
.eq('user_id', userId);
|
|
427
|
+
this.cache.delete(this.getCacheKey('workflow', `${userId}:${id} `));
|
|
428
|
+
this.cache.delete(this.getCacheKey('workflows', userId));
|
|
429
|
+
this.cache.clear();
|
|
430
|
+
}
|
|
431
|
+
mapWorkflow(data) {
|
|
432
|
+
const cronConfig = data.workflow_cron_configs; // Now an object or array from join
|
|
433
|
+
return {
|
|
434
|
+
id: data.id.toString(),
|
|
435
|
+
userId: data.user_id,
|
|
436
|
+
name: data.name,
|
|
437
|
+
description: data.description,
|
|
438
|
+
event_type: data.event_type,
|
|
439
|
+
definition: (0, encryption_helpers_1.decryptJSON)(data.definition),
|
|
440
|
+
configs: (0, encryption_helpers_1.decryptJSON)(data.configs),
|
|
441
|
+
is_active: data.is_active,
|
|
442
|
+
created_at: data.created_at,
|
|
443
|
+
updated_at: data.updated_at,
|
|
444
|
+
viewport: data.viewport,
|
|
445
|
+
priority: data.priority,
|
|
446
|
+
workflow_cron_configs: Array.isArray(cronConfig) ? cronConfig[0] : cronConfig // Supabase joins return array usually
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
// ============================================================================
|
|
450
|
+
// Workflow Execution (Write Heavy - No Cache)
|
|
451
|
+
// ============================================================================
|
|
452
|
+
async createWorkflowExecution(execution) {
|
|
453
|
+
const userId = execution.userId;
|
|
454
|
+
if (!userId) {
|
|
455
|
+
throw new Error('createWorkflowExecution: userId is required');
|
|
456
|
+
}
|
|
457
|
+
const { data, error } = await this.supabase
|
|
458
|
+
.from('chat_flow_workflow_executions')
|
|
459
|
+
.insert({
|
|
460
|
+
user_id: userId,
|
|
461
|
+
workflow_id: execution.workflow_id,
|
|
462
|
+
event_type: execution.event_type,
|
|
463
|
+
event_payload: (0, encryption_helpers_1.encryptJSON)(execution.event_payload),
|
|
464
|
+
status: execution.status || 'pending',
|
|
465
|
+
started_at: execution.started_at || new Date().toISOString(),
|
|
466
|
+
priority: execution.priority || 0,
|
|
467
|
+
})
|
|
468
|
+
.select('id')
|
|
469
|
+
.single();
|
|
470
|
+
if (error)
|
|
471
|
+
throw new Error(error.message);
|
|
472
|
+
const newExecution = {
|
|
473
|
+
...execution,
|
|
474
|
+
id: data.id.toString(), // Get generated ID
|
|
475
|
+
userId: userId,
|
|
476
|
+
workflow_id: execution.workflow_id || '',
|
|
477
|
+
event_type: execution.event_type || '',
|
|
478
|
+
event_payload: execution.event_payload || {},
|
|
479
|
+
status: execution.status || 'pending',
|
|
480
|
+
started_at: execution.started_at || new Date().toISOString(),
|
|
481
|
+
completed_at: null,
|
|
482
|
+
error_message: null,
|
|
483
|
+
last_failed_step_id: null,
|
|
484
|
+
step_logs: [],
|
|
485
|
+
priority: execution.priority || 0
|
|
486
|
+
};
|
|
487
|
+
return newExecution;
|
|
488
|
+
}
|
|
489
|
+
async updateWorkflowExecution(executionId, updates) {
|
|
490
|
+
const { error } = await this.supabase
|
|
491
|
+
.from('chat_flow_workflow_executions')
|
|
492
|
+
.update({
|
|
493
|
+
status: updates.status,
|
|
494
|
+
completed_at: updates.completed_at,
|
|
495
|
+
error_message: updates.error_message,
|
|
496
|
+
last_failed_step_id: updates.last_failed_step_id,
|
|
497
|
+
output_result: updates.outputResult
|
|
498
|
+
})
|
|
499
|
+
.eq('id', executionId);
|
|
500
|
+
if (error)
|
|
501
|
+
console.error('[Supabase] Update execution failed', error);
|
|
502
|
+
}
|
|
503
|
+
async getWorkflowExecutionById(executionId) {
|
|
504
|
+
const { data, error } = await this.supabase
|
|
505
|
+
.from('chat_flow_workflow_executions')
|
|
506
|
+
.select('*')
|
|
507
|
+
.eq('id', executionId)
|
|
508
|
+
.single();
|
|
509
|
+
if (error || !data)
|
|
510
|
+
return null;
|
|
511
|
+
return {
|
|
512
|
+
id: data.id.toString(),
|
|
513
|
+
userId: data.user_id,
|
|
514
|
+
workflow_id: data.workflow_id,
|
|
515
|
+
event_type: data.event_type,
|
|
516
|
+
event_payload: (0, encryption_helpers_1.decryptJSON)(data.event_payload),
|
|
517
|
+
status: data.status,
|
|
518
|
+
started_at: data.started_at,
|
|
519
|
+
completed_at: data.completed_at,
|
|
520
|
+
error_message: data.error_message,
|
|
521
|
+
last_failed_step_id: data.last_failed_step_id,
|
|
522
|
+
priority: data.priority,
|
|
523
|
+
outputResult: data.output_result, // Map
|
|
524
|
+
};
|
|
525
|
+
}
|
|
526
|
+
async getWorkflowExecutionWithLogs(executionId) {
|
|
527
|
+
// Join query would be better, but simple sequential fetch for now to match interface
|
|
528
|
+
const execution = await this.getWorkflowExecutionById(executionId);
|
|
529
|
+
if (!execution)
|
|
530
|
+
throw new Error('Execution not found');
|
|
531
|
+
const logs = await this.getWorkflowExecutionLogs(executionId);
|
|
532
|
+
const workflow = await this.findWorkflowById(execution.workflow_id, execution.userId);
|
|
533
|
+
return {
|
|
534
|
+
...execution,
|
|
535
|
+
workflow_action_logs: logs,
|
|
536
|
+
workflow: workflow
|
|
537
|
+
};
|
|
538
|
+
}
|
|
539
|
+
async getPendingWorkflowExecutions(limit) {
|
|
540
|
+
const { data, error } = await this.supabase
|
|
541
|
+
.from('chat_flow_workflow_executions')
|
|
542
|
+
.select('*')
|
|
543
|
+
.eq('status', 'pending')
|
|
544
|
+
.order('priority', { ascending: true }) // Higher priority = lower number usually? Or higher? Assuming lower is better/first.
|
|
545
|
+
// Wait, priority 0 is default. Let's assume standard queue.
|
|
546
|
+
.order('started_at', { ascending: true })
|
|
547
|
+
.limit(limit);
|
|
548
|
+
if (error)
|
|
549
|
+
return [];
|
|
550
|
+
return data.map((d) => ({
|
|
551
|
+
id: d.id.toString(),
|
|
552
|
+
userId: d.user_id,
|
|
553
|
+
workflow_id: d.workflow_id,
|
|
554
|
+
event_type: d.event_type,
|
|
555
|
+
event_payload: (0, encryption_helpers_1.decryptJSON)(d.event_payload),
|
|
556
|
+
status: d.status,
|
|
557
|
+
started_at: d.started_at,
|
|
558
|
+
completed_at: d.completed_at,
|
|
559
|
+
error_message: d.error_message,
|
|
560
|
+
priority: d.priority,
|
|
561
|
+
}));
|
|
562
|
+
}
|
|
563
|
+
async getActiveWorkflowExecutionCount(workflowId) {
|
|
564
|
+
const { count, error } = await this.supabase
|
|
565
|
+
.from('chat_flow_workflow_executions')
|
|
566
|
+
.select('*', { count: 'exact', head: true })
|
|
567
|
+
.eq('workflow_id', workflowId)
|
|
568
|
+
.eq('status', 'processing'); // or pending?
|
|
569
|
+
if (error)
|
|
570
|
+
return 0;
|
|
571
|
+
return count || 0;
|
|
572
|
+
}
|
|
573
|
+
async markWorkflowExecutionFailed(executionId, error) {
|
|
574
|
+
await this.updateWorkflowExecution(executionId, {
|
|
575
|
+
status: 'failed',
|
|
576
|
+
error_message: error,
|
|
577
|
+
completed_at: new Date().toISOString()
|
|
578
|
+
});
|
|
579
|
+
}
|
|
580
|
+
async logWorkflowAction(logEntry) {
|
|
581
|
+
let resultId = logEntry.id;
|
|
582
|
+
if (resultId) {
|
|
583
|
+
// Update existing log
|
|
584
|
+
const { error } = await this.supabase
|
|
585
|
+
.from('chat_flow_action_logs')
|
|
586
|
+
.update({
|
|
587
|
+
status: logEntry.status,
|
|
588
|
+
output: (0, encryption_helpers_1.encryptJSON)(logEntry.output),
|
|
589
|
+
error_message: logEntry.error_message,
|
|
590
|
+
completed_at: logEntry.completed_at
|
|
591
|
+
})
|
|
592
|
+
.eq('id', resultId);
|
|
593
|
+
if (error) {
|
|
594
|
+
console.error('[Supabase] Log action update failed', error);
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
else {
|
|
598
|
+
// Insert new log
|
|
599
|
+
const { data, error } = await this.supabase
|
|
600
|
+
.from('chat_flow_action_logs')
|
|
601
|
+
.insert({
|
|
602
|
+
user_id: logEntry.userId || 'global',
|
|
603
|
+
execution_id: logEntry.execution_id,
|
|
604
|
+
workflow_id: logEntry.workflow_id,
|
|
605
|
+
step_id: logEntry.step_id,
|
|
606
|
+
action_type: logEntry.action_type,
|
|
607
|
+
input: (0, encryption_helpers_1.encryptJSON)(logEntry.input),
|
|
608
|
+
output: (0, encryption_helpers_1.encryptJSON)(logEntry.output),
|
|
609
|
+
status: logEntry.status,
|
|
610
|
+
error_message: logEntry.error_message,
|
|
611
|
+
started_at: logEntry.started_at || new Date().toISOString(),
|
|
612
|
+
completed_at: logEntry.completed_at
|
|
613
|
+
})
|
|
614
|
+
.select('id')
|
|
615
|
+
.single();
|
|
616
|
+
if (error) {
|
|
617
|
+
console.error('[Supabase] Log action insert failed', error);
|
|
618
|
+
}
|
|
619
|
+
else {
|
|
620
|
+
resultId = data.id.toString();
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
// Return the log entry with ID (merged)
|
|
624
|
+
return {
|
|
625
|
+
...logEntry,
|
|
626
|
+
id: resultId?.toString(),
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
async getWorkflowExecutionLogs(executionId) {
|
|
630
|
+
const { data, error } = await this.supabase
|
|
631
|
+
.from('chat_flow_action_logs')
|
|
632
|
+
.select('*')
|
|
633
|
+
.eq('execution_id', executionId)
|
|
634
|
+
.order('started_at', { ascending: true });
|
|
635
|
+
if (error)
|
|
636
|
+
return [];
|
|
637
|
+
return data.map((d) => ({
|
|
638
|
+
id: d.id.toString(),
|
|
639
|
+
userId: d.user_id, // Map
|
|
640
|
+
execution_id: d.execution_id,
|
|
641
|
+
workflow_id: d.workflow_id,
|
|
642
|
+
step_id: d.step_id,
|
|
643
|
+
action_type: d.action_type,
|
|
644
|
+
input: (0, encryption_helpers_1.decryptJSON)(d.input),
|
|
645
|
+
output: (0, encryption_helpers_1.decryptJSON)(d.output),
|
|
646
|
+
status: d.status,
|
|
647
|
+
error_message: d.error_message,
|
|
648
|
+
started_at: d.started_at,
|
|
649
|
+
completed_at: d.completed_at
|
|
650
|
+
}));
|
|
651
|
+
}
|
|
652
|
+
// ============================================================================
|
|
653
|
+
// Webhook Events
|
|
654
|
+
// ============================================================================
|
|
655
|
+
async storeWebhookEvent(event) {
|
|
656
|
+
// ID generation in Postgres usually serial, but interface expects number return.
|
|
657
|
+
// We will insert and return 'id'.
|
|
658
|
+
const { data, error } = await this.supabase
|
|
659
|
+
.from('chat_flow_webhook_events')
|
|
660
|
+
.insert({
|
|
661
|
+
type: event.type,
|
|
662
|
+
payload: (0, encryption_helpers_1.encryptJSON)(event.payload),
|
|
663
|
+
source: event.source,
|
|
664
|
+
// user_id: event.userId, // Schema checks: 'user_id' in webhook_events?
|
|
665
|
+
// provided schema: user_id uuid
|
|
666
|
+
user_id: event.userId, // Map
|
|
667
|
+
status: event.status || 'pending',
|
|
668
|
+
created_at: event.created_at || new Date().toISOString()
|
|
669
|
+
})
|
|
670
|
+
.select('id')
|
|
671
|
+
.single();
|
|
672
|
+
if (error)
|
|
673
|
+
throw new Error(error.message);
|
|
674
|
+
return data.id;
|
|
675
|
+
}
|
|
676
|
+
async getWebhookEvent(id) {
|
|
677
|
+
const { data, error } = await this.supabase
|
|
678
|
+
.from('chat_flow_webhook_events')
|
|
679
|
+
.select('*')
|
|
680
|
+
.eq('id', id)
|
|
681
|
+
.single();
|
|
682
|
+
if (error || !data)
|
|
683
|
+
return null;
|
|
684
|
+
return {
|
|
685
|
+
id: data.id,
|
|
686
|
+
created_at: data.created_at,
|
|
687
|
+
type: data.type,
|
|
688
|
+
payload: (0, encryption_helpers_1.decryptJSON)(data.payload),
|
|
689
|
+
source: data.source,
|
|
690
|
+
userId: data.user_id, // Map
|
|
691
|
+
status: data.status,
|
|
692
|
+
error_message: data.error_message
|
|
693
|
+
};
|
|
694
|
+
}
|
|
695
|
+
async updateWebhookEventStatus(id, updates) {
|
|
696
|
+
await this.supabase
|
|
697
|
+
.from('chat_flow_webhook_events')
|
|
698
|
+
.update({
|
|
699
|
+
status: updates.status,
|
|
700
|
+
error_message: updates.error_message
|
|
701
|
+
})
|
|
702
|
+
.eq('id', id);
|
|
703
|
+
}
|
|
704
|
+
// ============================================================================
|
|
705
|
+
// Scheduler
|
|
706
|
+
// ============================================================================
|
|
707
|
+
async getDueScheduledWorkflows(now) {
|
|
708
|
+
// This requires a more complex query joining cron configs or storing next_run in a separate column/table
|
|
709
|
+
// For simplicity, assuming 'workflows' table has a 'next_run_at' derived column or we join.
|
|
710
|
+
// Let's assume a simplified 'scheduled_tasks' table or similar if strictly following relational.
|
|
711
|
+
// OR we query workflows where workflow_cron_configs->0->next_run_at < now.
|
|
712
|
+
// JSONB query:
|
|
713
|
+
// workflow_cron_configs is array or object.
|
|
714
|
+
const { data, error } = await this.supabase
|
|
715
|
+
.from('chat_flow_workflows')
|
|
716
|
+
.select('*')
|
|
717
|
+
.not('workflow_cron_configs', 'is', null);
|
|
718
|
+
if (error)
|
|
719
|
+
return [];
|
|
720
|
+
// Manual filtering in JS for flexibility since JSONB queries can be tricky without specific indexes
|
|
721
|
+
return data.map(this.mapWorkflow).filter(w => {
|
|
722
|
+
const configs = Array.isArray(w.workflow_cron_configs) ? w.workflow_cron_configs : [w.workflow_cron_configs];
|
|
723
|
+
return configs.some((c) => c && c.next_run_at && new Date(c.next_run_at) <= now);
|
|
724
|
+
});
|
|
725
|
+
}
|
|
726
|
+
async updateWorkflowSchedule(workflowId, nextRun) {
|
|
727
|
+
// Fetch, update JSON, Save.
|
|
728
|
+
// This is inefficient but functional for low volume.
|
|
729
|
+
// Ideally we expose updateWorkflowConfig specific method.
|
|
730
|
+
const { data } = await this.supabase.from('chat_flow_workflows').select('workflow_cron_configs').eq('id', workflowId).single();
|
|
731
|
+
if (data && data.workflow_cron_configs) {
|
|
732
|
+
let configs = data.workflow_cron_configs;
|
|
733
|
+
if (Array.isArray(configs)) {
|
|
734
|
+
configs[0].next_run_at = nextRun.toISOString();
|
|
735
|
+
}
|
|
736
|
+
else {
|
|
737
|
+
configs.next_run_at = nextRun.toISOString();
|
|
738
|
+
}
|
|
739
|
+
await this.supabase.from('chat_flow_workflows').update({ workflow_cron_configs: configs }).eq('id', workflowId);
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
async getAllExecutions(userId, limit = 50, offset = 0) {
|
|
743
|
+
const countRes = await this.supabase.from('chat_flow_workflow_executions').select('*', { count: 'exact', head: true }).eq('user_id', userId);
|
|
744
|
+
const total = countRes.count || 0;
|
|
745
|
+
const { data, error } = await this.supabase
|
|
746
|
+
.from('chat_flow_workflow_executions')
|
|
747
|
+
.select('*')
|
|
748
|
+
.eq('user_id', userId)
|
|
749
|
+
.order('started_at', { ascending: false })
|
|
750
|
+
.range(offset, offset + limit - 1);
|
|
751
|
+
if (error)
|
|
752
|
+
return { executions: [], total: 0 };
|
|
753
|
+
const executions = data.map((d) => ({
|
|
754
|
+
id: d.id.toString(),
|
|
755
|
+
userId: d.user_id,
|
|
756
|
+
workflow_id: d.workflow_id,
|
|
757
|
+
event_type: d.event_type,
|
|
758
|
+
event_payload: (0, encryption_helpers_1.decryptJSON)(d.event_payload),
|
|
759
|
+
status: d.status,
|
|
760
|
+
started_at: d.started_at,
|
|
761
|
+
completed_at: d.completed_at,
|
|
762
|
+
error_message: d.error_message,
|
|
763
|
+
priority: d.priority,
|
|
764
|
+
outputResult: d.output_result // Added missing field
|
|
765
|
+
}));
|
|
766
|
+
return { executions, total };
|
|
767
|
+
}
|
|
768
|
+
async disconnect() {
|
|
769
|
+
// Supabase client handles connection pool, usually no explicit disconnect needed for stateless HTTP
|
|
770
|
+
// But if using realtime subscription, we would unsubscribe here.
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
exports.SupabaseRepository = SupabaseRepository;
|
|
774
|
+
//# sourceMappingURL=SupabaseRepository.js.map
|