chat-flow-ardymalihi 3.0.0 → 3.0.3
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/package.json +9 -1
- package/dist/adapters/db/InMemorySessionRepository.js +0 -15
- package/dist/adapters/db/RedisSessionRepository.js +0 -41
- package/dist/adapters/intent/IntentMatcher.d.ts +0 -41
- package/dist/adapters/intent/IntentMatcher.d.ts.map +0 -1
- package/dist/adapters/intent/IntentMatcher.js +0 -167
- package/dist/adapters/intent/IntentMatcher.js.map +0 -1
- package/dist/adapters/intent/IntentService.d.ts +0 -26
- package/dist/adapters/intent/IntentService.d.ts.map +0 -1
- package/dist/adapters/intent/IntentService.js +0 -65
- package/dist/adapters/intent/IntentService.js.map +0 -1
- package/dist/adapters/intent/MockIntentAdapter.js +0 -29
- package/dist/adapters/intent/MockIntentService.d.ts +0 -7
- package/dist/adapters/intent/MockIntentService.d.ts.map +0 -1
- package/dist/adapters/intent/MockIntentService.js +0 -36
- package/dist/adapters/intent/MockIntentService.js.map +0 -1
- package/dist/adapters/llm/GeminiLLMAdapter.d.ts +0 -10
- package/dist/adapters/llm/GeminiLLMAdapter.d.ts.map +0 -1
- package/dist/adapters/llm/GeminiLLMAdapter.js +0 -102
- package/dist/adapters/llm/GeminiLLMAdapter.js.map +0 -1
- package/dist/adapters/llm/MockLLMAdapter.d.ts +0 -5
- package/dist/adapters/llm/MockLLMAdapter.d.ts.map +0 -1
- package/dist/adapters/llm/MockLLMAdapter.js +0 -31
- package/dist/adapters/llm/MockLLMAdapter.js.map +0 -1
- package/dist/adapters/llm/OllamaLLMAdapter.d.ts +0 -9
- package/dist/adapters/llm/OllamaLLMAdapter.d.ts.map +0 -1
- package/dist/adapters/llm/OllamaLLMAdapter.js +0 -74
- package/dist/adapters/llm/OllamaLLMAdapter.js.map +0 -1
- package/dist/adapters/logger/ConsoleLogger.d.ts +0 -12
- package/dist/adapters/logger/ConsoleLogger.d.ts.map +0 -1
- package/dist/adapters/logger/ConsoleLogger.js +0 -37
- package/dist/adapters/logger/ConsoleLogger.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 -46
- package/dist/adapters/repository/InMemoryRepository.d.ts.map +0 -1
- package/dist/adapters/repository/InMemoryRepository.js +0 -235
- 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 -63
- package/dist/adapters/repository/RedisRepository.d.ts.map +0 -1
- package/dist/adapters/repository/RedisRepository.js +0 -586
- package/dist/adapters/repository/RedisRepository.js.map +0 -1
- package/dist/adapters/storage/RedisAudioStorageAdapter.d.ts +0 -33
- package/dist/adapters/storage/RedisAudioStorageAdapter.d.ts.map +0 -1
- package/dist/adapters/storage/RedisAudioStorageAdapter.js +0 -121
- package/dist/adapters/storage/RedisAudioStorageAdapter.js.map +0 -1
- package/dist/adapters/storage/RedisBufferStorageAdapter.d.ts +0 -14
- package/dist/adapters/storage/RedisBufferStorageAdapter.d.ts.map +0 -1
- package/dist/adapters/storage/RedisBufferStorageAdapter.js +0 -94
- package/dist/adapters/storage/RedisBufferStorageAdapter.js.map +0 -1
- package/dist/adapters/voice/ElevenLabsVoiceAdapter.d.ts +0 -29
- package/dist/adapters/voice/ElevenLabsVoiceAdapter.d.ts.map +0 -1
- package/dist/adapters/voice/ElevenLabsVoiceAdapter.js +0 -75
- package/dist/adapters/voice/ElevenLabsVoiceAdapter.js.map +0 -1
- package/dist/adapters/voice/GeminiMultimodalLiveAdapter.d.ts +0 -77
- package/dist/adapters/voice/GeminiMultimodalLiveAdapter.d.ts.map +0 -1
- package/dist/adapters/voice/GeminiMultimodalLiveAdapter.js +0 -187
- package/dist/adapters/voice/GeminiMultimodalLiveAdapter.js.map +0 -1
- package/dist/adapters/voice/GeminiVoiceAdapter.d.ts +0 -36
- package/dist/adapters/voice/GeminiVoiceAdapter.d.ts.map +0 -1
- package/dist/adapters/voice/GeminiVoiceAdapter.js +0 -134
- package/dist/adapters/voice/GeminiVoiceAdapter.js.map +0 -1
- package/dist/adapters/voice/GoogleTTSAdapter.d.ts +0 -61
- package/dist/adapters/voice/GoogleTTSAdapter.d.ts.map +0 -1
- package/dist/adapters/voice/GoogleTTSAdapter.js +0 -165
- package/dist/adapters/voice/GoogleTTSAdapter.js.map +0 -1
- package/dist/adapters/voice/GoogleVoiceAdapter.d.ts +0 -33
- package/dist/adapters/voice/GoogleVoiceAdapter.d.ts.map +0 -1
- package/dist/adapters/voice/GoogleVoiceAdapter.js +0 -155
- package/dist/adapters/voice/GoogleVoiceAdapter.js.map +0 -1
- package/dist/adapters/voice/HybridVoiceAdapter.d.ts +0 -54
- package/dist/adapters/voice/HybridVoiceAdapter.d.ts.map +0 -1
- package/dist/adapters/voice/HybridVoiceAdapter.js +0 -102
- package/dist/adapters/voice/HybridVoiceAdapter.js.map +0 -1
- package/dist/adapters/voice/LanguageVoiceMapper.d.ts +0 -60
- package/dist/adapters/voice/LanguageVoiceMapper.d.ts.map +0 -1
- package/dist/adapters/voice/LanguageVoiceMapper.js +0 -130
- package/dist/adapters/voice/LanguageVoiceMapper.js.map +0 -1
- package/dist/adapters/voice/VertexVoiceAdapter.d.ts +0 -32
- package/dist/adapters/voice/VertexVoiceAdapter.d.ts.map +0 -1
- package/dist/adapters/voice/VertexVoiceAdapter.js +0 -179
- package/dist/adapters/voice/VertexVoiceAdapter.js.map +0 -1
- package/dist/adapters/webhook/WebhookService.d.ts +0 -47
- package/dist/adapters/webhook/WebhookService.d.ts.map +0 -1
- package/dist/adapters/webhook/WebhookService.js +0 -265
- package/dist/adapters/webhook/WebhookService.js.map +0 -1
- package/dist/adapters/workflow/MockWorkflowAdapter.d.ts +0 -5
- package/dist/adapters/workflow/MockWorkflowAdapter.d.ts.map +0 -1
- package/dist/adapters/workflow/MockWorkflowAdapter.js +0 -173
- package/dist/adapters/workflow/MockWorkflowAdapter.js.map +0 -1
- package/dist/adapters/workflow/WorkflowAdapter.d.ts +0 -55
- package/dist/adapters/workflow/WorkflowAdapter.d.ts.map +0 -1
- package/dist/adapters/workflow/WorkflowAdapter.js +0 -242
- package/dist/adapters/workflow/WorkflowAdapter.js.map +0 -1
- package/dist/adapters/workflow/actions/getSupportHoursAction.d.ts +0 -10
- package/dist/adapters/workflow/actions/getSupportHoursAction.d.ts.map +0 -1
- package/dist/adapters/workflow/actions/getSupportHoursAction.js +0 -33
- package/dist/adapters/workflow/actions/getSupportHoursAction.js.map +0 -1
- package/dist/adapters/workflow/actions/index.d.ts +0 -6
- package/dist/adapters/workflow/actions/index.d.ts.map +0 -1
- package/dist/adapters/workflow/actions/index.js +0 -22
- package/dist/adapters/workflow/actions/index.js.map +0 -1
- package/dist/adapters/workflow/actions/pushOutputResultAction.d.ts +0 -11
- package/dist/adapters/workflow/actions/pushOutputResultAction.d.ts.map +0 -1
- package/dist/adapters/workflow/actions/pushOutputResultAction.js +0 -31
- package/dist/adapters/workflow/actions/pushOutputResultAction.js.map +0 -1
- package/dist/adapters/workflow/actions/setWorkflowMessageAction.d.ts +0 -12
- package/dist/adapters/workflow/actions/setWorkflowMessageAction.d.ts.map +0 -1
- package/dist/adapters/workflow/actions/setWorkflowMessageAction.js +0 -32
- package/dist/adapters/workflow/actions/setWorkflowMessageAction.js.map +0 -1
- package/dist/adapters/workflow/engine/constants.d.ts +0 -3
- package/dist/adapters/workflow/engine/constants.d.ts.map +0 -1
- package/dist/adapters/workflow/engine/constants.js +0 -6
- package/dist/adapters/workflow/engine/constants.js.map +0 -1
- package/dist/adapters/workflow/engine/engine.d.ts +0 -32
- package/dist/adapters/workflow/engine/engine.d.ts.map +0 -1
- package/dist/adapters/workflow/engine/engine.js +0 -623
- package/dist/adapters/workflow/engine/engine.js.map +0 -1
- package/dist/adapters/workflow/engine/event-registry.d.ts +0 -12
- package/dist/adapters/workflow/engine/event-registry.d.ts.map +0 -1
- package/dist/adapters/workflow/engine/event-registry.js +0 -33
- package/dist/adapters/workflow/engine/event-registry.js.map +0 -1
- package/dist/adapters/workflow/engine/interpolator.d.ts +0 -11
- package/dist/adapters/workflow/engine/interpolator.d.ts.map +0 -1
- package/dist/adapters/workflow/engine/interpolator.js +0 -93
- package/dist/adapters/workflow/engine/interpolator.js.map +0 -1
- package/dist/adapters/workflow/engine/registry.d.ts +0 -12
- package/dist/adapters/workflow/engine/registry.d.ts.map +0 -1
- package/dist/adapters/workflow/engine/registry.js +0 -39
- package/dist/adapters/workflow/engine/registry.js.map +0 -1
- package/dist/adapters/workflow/engine/template-registry.d.ts +0 -60
- package/dist/adapters/workflow/engine/template-registry.d.ts.map +0 -1
- package/dist/adapters/workflow/engine/template-registry.js +0 -92
- package/dist/adapters/workflow/engine/template-registry.js.map +0 -1
- package/dist/adapters/workflow/engine/types.d.ts +0 -182
- package/dist/adapters/workflow/engine/types.d.ts.map +0 -1
- package/dist/adapters/workflow/engine/types.js +0 -3
- package/dist/adapters/workflow/engine/types.js.map +0 -1
- package/dist/adapters/workflow/engine/utils/format-utils.d.ts +0 -43
- package/dist/adapters/workflow/engine/utils/format-utils.d.ts.map +0 -1
- package/dist/adapters/workflow/engine/utils/format-utils.js +0 -137
- package/dist/adapters/workflow/engine/utils/format-utils.js.map +0 -1
- package/dist/adapters/workflow/engine/utils/layout-calculator.d.ts +0 -7
- package/dist/adapters/workflow/engine/utils/layout-calculator.d.ts.map +0 -1
- package/dist/adapters/workflow/engine/utils/layout-calculator.js +0 -87
- package/dist/adapters/workflow/engine/utils/layout-calculator.js.map +0 -1
- package/dist/adapters/workflow/engine/utils/slugify.d.ts +0 -2
- package/dist/adapters/workflow/engine/utils/slugify.d.ts.map +0 -1
- package/dist/adapters/workflow/engine/utils/slugify.js +0 -41
- package/dist/adapters/workflow/engine/utils/slugify.js.map +0 -1
- package/dist/adapters/workflow/engine/validator.d.ts +0 -9
- package/dist/adapters/workflow/engine/validator.d.ts.map +0 -1
- package/dist/adapters/workflow/engine/validator.js +0 -425
- package/dist/adapters/workflow/engine/validator.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 +0 -66
- package/dist/config/ChatFlowConfig.d.ts.map +0 -1
- package/dist/config/ChatFlowConfig.js +0 -54
- package/dist/config/ChatFlowConfig.js.map +0 -1
- package/dist/config/index.d.ts +0 -2
- package/dist/config/index.d.ts.map +0 -1
- package/dist/config/index.js +0 -7
- package/dist/config/index.js.map +0 -1
- package/dist/core/entities/ConversationSession.d.ts +0 -58
- package/dist/core/entities/ConversationSession.d.ts.map +0 -1
- package/dist/core/entities/ConversationSession.js +0 -160
- package/dist/core/entities/ConversationSession.js.map +0 -1
- package/dist/core/entities/Message.d.ts +0 -14
- package/dist/core/entities/Message.d.ts.map +0 -1
- package/dist/core/entities/Message.js +0 -32
- package/dist/core/entities/Message.js.map +0 -1
- package/dist/core/errors/ChatFlowError.d.ts +0 -71
- package/dist/core/errors/ChatFlowError.d.ts.map +0 -1
- package/dist/core/errors/ChatFlowError.js +0 -108
- package/dist/core/errors/ChatFlowError.js.map +0 -1
- package/dist/core/errors/index.d.ts +0 -2
- package/dist/core/errors/index.d.ts.map +0 -1
- package/dist/core/errors/index.js +0 -15
- package/dist/core/errors/index.js.map +0 -1
- package/dist/core/utils/AudioStreamBuffer.d.ts +0 -33
- package/dist/core/utils/AudioStreamBuffer.d.ts.map +0 -1
- package/dist/core/utils/AudioStreamBuffer.js +0 -55
- package/dist/core/utils/AudioStreamBuffer.js.map +0 -1
- package/dist/core/utils/AudioUtils.d.ts +0 -41
- package/dist/core/utils/AudioUtils.d.ts.map +0 -1
- package/dist/core/utils/AudioUtils.js +0 -188
- package/dist/core/utils/AudioUtils.js.map +0 -1
- package/dist/core/utils/LanguageDetector.d.ts +0 -52
- package/dist/core/utils/LanguageDetector.d.ts.map +0 -1
- package/dist/core/utils/LanguageDetector.js +0 -173
- package/dist/core/utils/LanguageDetector.js.map +0 -1
- package/dist/core/utils/WavUtils.d.ts +0 -14
- package/dist/core/utils/WavUtils.d.ts.map +0 -1
- package/dist/core/utils/WavUtils.js +0 -37
- package/dist/core/utils/WavUtils.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 +0 -2
- package/dist/demo/cli-demo.d.ts.map +0 -1
- package/dist/demo/cli-demo.js +0 -146
- package/dist/demo/cli-demo.js.map +0 -1
- package/dist/demo/console-chat.d.ts +0 -2
- package/dist/demo/console-chat.d.ts.map +0 -1
- package/dist/demo/console-chat.js +0 -148
- package/dist/demo/console-chat.js.map +0 -1
- package/dist/demo/interactive-voice-chat.d.ts +0 -2
- package/dist/demo/interactive-voice-chat.d.ts.map +0 -1
- package/dist/demo/interactive-voice-chat.js +0 -180
- package/dist/demo/interactive-voice-chat.js.map +0 -1
- package/dist/demo/voice-demo.d.ts +0 -2
- package/dist/demo/voice-demo.d.ts.map +0 -1
- package/dist/demo/voice-demo.js +0 -188
- package/dist/demo/voice-demo.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 +0 -26
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -76
- 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 -57
- package/dist/intent/IntentService.js.map +0 -1
- package/dist/intent/MockIntentService.d.ts +0 -7
- package/dist/intent/MockIntentService.d.ts.map +0 -1
- package/dist/intent/MockIntentService.js +0 -36
- package/dist/intent/MockIntentService.js.map +0 -1
- package/dist/interfaces.d.ts +0 -653
- package/dist/interfaces.d.ts.map +0 -1
- package/dist/interfaces.js +0 -36
- 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 -62
- package/dist/orchestrator/Orchestrator.d.ts.map +0 -1
- package/dist/orchestrator/Orchestrator.js +0 -697
- 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 +0 -2
- package/dist/scripts/debug-redis.d.ts.map +0 -1
- package/dist/scripts/debug-redis.js +0 -55
- package/dist/scripts/debug-redis.js.map +0 -1
- package/dist/scripts/seed-collaborative-intents.d.ts +0 -2
- package/dist/scripts/seed-collaborative-intents.d.ts.map +0 -1
- package/dist/scripts/seed-collaborative-intents.js +0 -90
- package/dist/scripts/seed-collaborative-intents.js.map +0 -1
- package/dist/scripts/test-isolated-config.d.ts +0 -2
- package/dist/scripts/test-isolated-config.d.ts.map +0 -1
- package/dist/scripts/test-isolated-config.js +0 -80
- package/dist/scripts/test-isolated-config.js.map +0 -1
- package/dist/scripts/verify_memory_intents.d.ts +0 -2
- package/dist/scripts/verify_memory_intents.d.ts.map +0 -1
- package/dist/scripts/verify_memory_intents.js +0 -45
- package/dist/scripts/verify_memory_intents.js.map +0 -1
- package/dist/scripts/verify_redis_intents.d.ts +0 -2
- package/dist/scripts/verify_redis_intents.d.ts.map +0 -1
- package/dist/scripts/verify_redis_intents.js +0 -52
- package/dist/scripts/verify_redis_intents.js.map +0 -1
- package/dist/server/ChatFlowWebSocketServer.d.ts +0 -46
- package/dist/server/ChatFlowWebSocketServer.d.ts.map +0 -1
- package/dist/server/ChatFlowWebSocketServer.js +0 -344
- package/dist/server/ChatFlowWebSocketServer.js.map +0 -1
- package/dist/server/realtime-voice-server.d.ts +0 -2
- package/dist/server/realtime-voice-server.d.ts.map +0 -1
- package/dist/server/realtime-voice-server.js +0 -627
- package/dist/server/realtime-voice-server.js.map +0 -1
- package/dist/src/api/routes/tenants.d.ts +0 -3
- package/dist/src/api/routes/tenants.d.ts.map +0 -1
- package/dist/src/api/routes/tenants.js +0 -109
- package/dist/src/api/routes/tenants.js.map +0 -1
- package/dist/utils/crypto.d.ts +0 -7
- package/dist/utils/crypto.d.ts.map +0 -1
- package/dist/utils/crypto.js +0 -35
- package/dist/utils/crypto.js.map +0 -1
- package/dist/utils/encryption-helpers.d.ts +0 -14
- package/dist/utils/encryption-helpers.d.ts.map +0 -1
- package/dist/utils/encryption-helpers.js +0 -49
- package/dist/utils/encryption-helpers.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 +0 -162
- package/dist/workflow/MockWorkflowAdapter.js.map +0 -1
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import Redis, { Cluster, ClusterOptions, RedisOptions } from 'ioredis';
|
|
2
|
-
import { IRepository, Intent, Tenant, ConversationConfig, Workflow, WorkflowExecution, WorkflowActionLog, WebhookEvent } from '../../interfaces';
|
|
3
|
-
import { ConversationSession } from '../../core/entities/ConversationSession';
|
|
4
|
-
export interface RedisRepositoryConfig {
|
|
5
|
-
connection?: string | Redis | Cluster;
|
|
6
|
-
clusterNodes?: string[];
|
|
7
|
-
clusterOptions?: ClusterOptions;
|
|
8
|
-
redisOptions?: RedisOptions;
|
|
9
|
-
keyPrefix?: string;
|
|
10
|
-
defaultTtl?: number;
|
|
11
|
-
}
|
|
12
|
-
export declare class RedisRepository implements IRepository {
|
|
13
|
-
private client;
|
|
14
|
-
private readonly SESSION_TTL;
|
|
15
|
-
private readonly EXECUTION_TTL_SECONDS;
|
|
16
|
-
private readonly GLOBAL_PREFIX;
|
|
17
|
-
constructor(configOrUrl?: string | RedisRepositoryConfig);
|
|
18
|
-
/**
|
|
19
|
-
* Generates a tenant-scoped key with Hash Tags for Cluster support.
|
|
20
|
-
* Pattern: {prefix}:{tenantId}:{entityType}:{id}
|
|
21
|
-
* Hash Tag: {tenantId} -> Ensures all keys for a tenant map to the same slot.
|
|
22
|
-
*/
|
|
23
|
-
private getKey;
|
|
24
|
-
/**
|
|
25
|
-
* Helper to add item to set with expiry (refreshes whole set expiry)
|
|
26
|
-
*/
|
|
27
|
-
private addToSetWithTtl;
|
|
28
|
-
saveSession(session: ConversationSession): Promise<void>;
|
|
29
|
-
findSessionById(sessionId: string): Promise<ConversationSession | null>;
|
|
30
|
-
private parseSession;
|
|
31
|
-
saveTenant(tenant: Tenant): Promise<void>;
|
|
32
|
-
findTenantById(id: string): Promise<Tenant | null>;
|
|
33
|
-
saveConversationConfig(config: ConversationConfig): Promise<void>;
|
|
34
|
-
findConversationConfig(tenantId: string, configId?: string): Promise<ConversationConfig | null>;
|
|
35
|
-
saveIntent(intent: Intent): Promise<void>;
|
|
36
|
-
upsertIntents(intents: Intent[]): Promise<void>;
|
|
37
|
-
findIntentByName(name: string, tenantId?: string): Promise<Intent | null>;
|
|
38
|
-
deleteIntent(name: string, tenantId?: string): Promise<void>;
|
|
39
|
-
getAllIntents(tenantId?: string): Promise<Intent[]>;
|
|
40
|
-
saveWorkflow(workflow: Workflow): Promise<void>;
|
|
41
|
-
findWorkflowById(id: string, tenantId: string): Promise<Workflow | null>;
|
|
42
|
-
getActiveWorkflowsForEvent(tenantId: string, eventType: string): Promise<Workflow[]>;
|
|
43
|
-
deleteWorkflow(id: string, tenantId: string): Promise<void>;
|
|
44
|
-
createWorkflowExecution(execution: Partial<WorkflowExecution>): Promise<WorkflowExecution>;
|
|
45
|
-
updateWorkflowExecution(executionId: string, updates: Partial<WorkflowExecution>): Promise<void>;
|
|
46
|
-
getWorkflowExecutionById(executionId: string): Promise<WorkflowExecution | null>;
|
|
47
|
-
getWorkflowExecutionWithLogs(executionId: string): Promise<WorkflowExecution & {
|
|
48
|
-
workflow_action_logs: WorkflowActionLog[];
|
|
49
|
-
workflow: Workflow;
|
|
50
|
-
}>;
|
|
51
|
-
getPendingWorkflowExecutions(limit: number): Promise<WorkflowExecution[]>;
|
|
52
|
-
getActiveWorkflowExecutionCount(workflowId: string): Promise<number>;
|
|
53
|
-
markWorkflowExecutionFailed(executionId: string, error: string): Promise<void>;
|
|
54
|
-
logWorkflowAction(logEntry: Partial<WorkflowActionLog>): Promise<WorkflowActionLog>;
|
|
55
|
-
getWorkflowExecutionLogs(executionId: string): Promise<WorkflowActionLog[]>;
|
|
56
|
-
storeWebhookEvent(event: Partial<WebhookEvent>): Promise<number>;
|
|
57
|
-
getWebhookEvent(id: number): Promise<WebhookEvent | null>;
|
|
58
|
-
updateWebhookEventStatus(id: number, updates: Partial<WebhookEvent>): Promise<void>;
|
|
59
|
-
getDueScheduledWorkflows(now: Date): Promise<Workflow[]>;
|
|
60
|
-
updateWorkflowSchedule(workflowId: string, nextRun: Date): Promise<void>;
|
|
61
|
-
disconnect(): Promise<void>;
|
|
62
|
-
}
|
|
63
|
-
//# sourceMappingURL=RedisRepository.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"RedisRepository.d.ts","sourceRoot":"","sources":["../../../src/adapters/repository/RedisRepository.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,586 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.RedisRepository = void 0;
|
|
7
|
-
const ioredis_1 = __importDefault(require("ioredis"));
|
|
8
|
-
const ConversationSession_1 = require("../../core/entities/ConversationSession");
|
|
9
|
-
class RedisRepository {
|
|
10
|
-
constructor(configOrUrl = {}) {
|
|
11
|
-
this.SESSION_TTL = 3600; // 1 Hour for active sessions
|
|
12
|
-
let config;
|
|
13
|
-
if (typeof configOrUrl === 'string') {
|
|
14
|
-
config = { connection: configOrUrl };
|
|
15
|
-
}
|
|
16
|
-
else {
|
|
17
|
-
config = configOrUrl;
|
|
18
|
-
}
|
|
19
|
-
this.GLOBAL_PREFIX = config.keyPrefix || 'chatflow';
|
|
20
|
-
this.EXECUTION_TTL_SECONDS = config.defaultTtl || 604800; // 7 days (7 * 24 * 3600)
|
|
21
|
-
if (config.connection instanceof ioredis_1.default || config.connection?.constructor?.name === 'Cluster') {
|
|
22
|
-
this.client = config.connection;
|
|
23
|
-
}
|
|
24
|
-
else if (config.clusterNodes && config.clusterNodes.length > 0) {
|
|
25
|
-
// Cluster mode
|
|
26
|
-
this.client = new ioredis_1.default.Cluster(config.clusterNodes, {
|
|
27
|
-
...config.clusterOptions,
|
|
28
|
-
redisOptions: config.redisOptions
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
else {
|
|
32
|
-
// Standalone mode
|
|
33
|
-
const connectionString = typeof config.connection === 'string'
|
|
34
|
-
? config.connection
|
|
35
|
-
: process.env.REDIS_URL || 'redis://localhost:6379';
|
|
36
|
-
// Fix: Ensure explicitly strict argument types for ioredis constructor to avoid overload confusion
|
|
37
|
-
if (config.redisOptions) {
|
|
38
|
-
this.client = new ioredis_1.default(connectionString, config.redisOptions);
|
|
39
|
-
}
|
|
40
|
-
else {
|
|
41
|
-
this.client = new ioredis_1.default(connectionString);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
this.client.on('error', (err) => {
|
|
45
|
-
console.error('[Redis Error]', err);
|
|
46
|
-
});
|
|
47
|
-
this.client.on('connect', () => {
|
|
48
|
-
console.log('[Redis] Connected');
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* Generates a tenant-scoped key with Hash Tags for Cluster support.
|
|
53
|
-
* Pattern: {prefix}:{tenantId}:{entityType}:{id}
|
|
54
|
-
* Hash Tag: {tenantId} -> Ensures all keys for a tenant map to the same slot.
|
|
55
|
-
*/
|
|
56
|
-
getKey(tenantId, entityType, id) {
|
|
57
|
-
// Handle global keys (no tenantId) -> Use a fixed hash tag or global namespace
|
|
58
|
-
if (!tenantId || tenantId === 'global') {
|
|
59
|
-
// Global data (e.g. platform metadata)
|
|
60
|
-
return id ? `${this.GLOBAL_PREFIX}:{global}:${entityType}:${id}` : `${this.GLOBAL_PREFIX}:{global}:${entityType}`;
|
|
61
|
-
}
|
|
62
|
-
return id
|
|
63
|
-
? `${this.GLOBAL_PREFIX}:{${tenantId}}:${entityType}:${id}`
|
|
64
|
-
: `${this.GLOBAL_PREFIX}:{${tenantId}}:${entityType}`;
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Helper to add item to set with expiry (refreshes whole set expiry)
|
|
68
|
-
*/
|
|
69
|
-
async addToSetWithTtl(key, member, ttl) {
|
|
70
|
-
const pipeline = this.client.pipeline();
|
|
71
|
-
pipeline.sadd(key, member);
|
|
72
|
-
pipeline.expire(key, ttl);
|
|
73
|
-
await pipeline.exec();
|
|
74
|
-
}
|
|
75
|
-
// ============================================================================
|
|
76
|
-
// Session Management
|
|
77
|
-
// ============================================================================
|
|
78
|
-
async saveSession(session) {
|
|
79
|
-
const tenantId = session.tenantId || 'global';
|
|
80
|
-
const key = this.getKey(tenantId, 'session', session.sessionId);
|
|
81
|
-
const data = JSON.stringify(session.toSnapshot());
|
|
82
|
-
const lookupKey = `${this.GLOBAL_PREFIX}:lookup:session:${session.sessionId}`;
|
|
83
|
-
if (session.status === 'COMPLETED' || session.status === 'FAILED') {
|
|
84
|
-
// Completed sessions: use configured retention TTL (e.g. 7 days)
|
|
85
|
-
await this.client.set(key, data, 'EX', this.EXECUTION_TTL_SECONDS);
|
|
86
|
-
// Verify if we need persistent lookup for completed sessions. Yes, for history.
|
|
87
|
-
await this.client.set(lookupKey, tenantId, 'EX', this.EXECUTION_TTL_SECONDS);
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
// Active sessions: short TTL (1 hour) to auto-clean abandoned sessions
|
|
91
|
-
await this.client.set(key, data, 'EX', this.SESSION_TTL);
|
|
92
|
-
await this.client.set(lookupKey, tenantId, 'EX', this.SESSION_TTL);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
async findSessionById(sessionId) {
|
|
96
|
-
// 1. Try Lookup to find Tenant ID
|
|
97
|
-
const lookupKey = `${this.GLOBAL_PREFIX}:lookup:session:${sessionId}`;
|
|
98
|
-
const tenantId = await this.client.get(lookupKey);
|
|
99
|
-
let key;
|
|
100
|
-
if (tenantId) {
|
|
101
|
-
key = this.getKey(tenantId, 'session', sessionId);
|
|
102
|
-
}
|
|
103
|
-
else {
|
|
104
|
-
// Fallback for legacy keys (before this migration)
|
|
105
|
-
const legacyKey = `session:${sessionId}`;
|
|
106
|
-
const legacyData = await this.client.get(legacyKey);
|
|
107
|
-
if (legacyData)
|
|
108
|
-
return this.parseSession(legacyData, sessionId);
|
|
109
|
-
return null;
|
|
110
|
-
}
|
|
111
|
-
const data = await this.client.get(key);
|
|
112
|
-
if (!data)
|
|
113
|
-
return null;
|
|
114
|
-
return this.parseSession(data, sessionId);
|
|
115
|
-
}
|
|
116
|
-
parseSession(data, sessionId) {
|
|
117
|
-
try {
|
|
118
|
-
const parsed = JSON.parse(data);
|
|
119
|
-
return ConversationSession_1.ConversationSession.reconstitute(parsed);
|
|
120
|
-
}
|
|
121
|
-
catch (err) {
|
|
122
|
-
console.error(`Failed to reconstitute session ${sessionId}`, err);
|
|
123
|
-
return null;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
// ============================================================================
|
|
127
|
-
// Tenant & Config Management
|
|
128
|
-
// ============================================================================
|
|
129
|
-
async saveTenant(tenant) {
|
|
130
|
-
const key = this.getKey('admin', 'tenant', tenant.id);
|
|
131
|
-
await this.client.call('JSON.SET', key, '$', JSON.stringify(tenant));
|
|
132
|
-
}
|
|
133
|
-
async findTenantById(id) {
|
|
134
|
-
const key = this.getKey('admin', 'tenant', id);
|
|
135
|
-
const data = await this.client.call('JSON.GET', key);
|
|
136
|
-
if (!data)
|
|
137
|
-
return null;
|
|
138
|
-
return typeof data === 'string' ? JSON.parse(data) : data;
|
|
139
|
-
}
|
|
140
|
-
async saveConversationConfig(config) {
|
|
141
|
-
const key = this.getKey(config.tenantId, 'config', config.id);
|
|
142
|
-
await this.client.call('JSON.SET', key, '$', JSON.stringify(config));
|
|
143
|
-
// Add to tenant's config list
|
|
144
|
-
const indexKey = this.getKey(config.tenantId, 'configs');
|
|
145
|
-
await this.client.sadd(indexKey, config.id);
|
|
146
|
-
}
|
|
147
|
-
async findConversationConfig(tenantId, configId) {
|
|
148
|
-
let key;
|
|
149
|
-
if (configId) {
|
|
150
|
-
key = this.getKey(tenantId, 'config', configId);
|
|
151
|
-
}
|
|
152
|
-
else {
|
|
153
|
-
// Find first available config via index
|
|
154
|
-
const indexKey = this.getKey(tenantId, 'configs');
|
|
155
|
-
const ids = await this.client.smembers(indexKey);
|
|
156
|
-
if (ids.length === 0)
|
|
157
|
-
return null;
|
|
158
|
-
key = this.getKey(tenantId, 'config', ids[0]);
|
|
159
|
-
}
|
|
160
|
-
const data = await this.client.call('JSON.GET', key);
|
|
161
|
-
if (!data)
|
|
162
|
-
return null;
|
|
163
|
-
return typeof data === 'string' ? JSON.parse(data) : data;
|
|
164
|
-
}
|
|
165
|
-
// ============================================================================
|
|
166
|
-
// Intent Management
|
|
167
|
-
// ============================================================================
|
|
168
|
-
async saveIntent(intent) {
|
|
169
|
-
const tenantId = intent.tenantId || 'global';
|
|
170
|
-
const key = this.getKey(tenantId, 'intent', intent.name);
|
|
171
|
-
await this.client.call('JSON.SET', key, '$', JSON.stringify(intent));
|
|
172
|
-
const indexKey = this.getKey(tenantId, 'intents');
|
|
173
|
-
await this.client.sadd(indexKey, intent.name);
|
|
174
|
-
}
|
|
175
|
-
async upsertIntents(intents) {
|
|
176
|
-
const pipeline = this.client.pipeline();
|
|
177
|
-
for (const intent of intents) {
|
|
178
|
-
const tenantId = intent.tenantId || 'global';
|
|
179
|
-
const key = this.getKey(tenantId, 'intent', intent.name);
|
|
180
|
-
const indexKey = this.getKey(tenantId, 'intents');
|
|
181
|
-
pipeline.call('JSON.SET', key, '$', JSON.stringify(intent));
|
|
182
|
-
pipeline.sadd(indexKey, intent.name);
|
|
183
|
-
}
|
|
184
|
-
await pipeline.exec();
|
|
185
|
-
}
|
|
186
|
-
async findIntentByName(name, tenantId) {
|
|
187
|
-
// 1. Try Tenant Specific
|
|
188
|
-
if (tenantId) {
|
|
189
|
-
const tenantKey = this.getKey(tenantId, 'intent', name);
|
|
190
|
-
const tenantData = await this.client.call('JSON.GET', tenantKey);
|
|
191
|
-
if (tenantData) {
|
|
192
|
-
return typeof tenantData === 'string' ? JSON.parse(tenantData) : tenantData;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
// 2. Fallback to Global
|
|
196
|
-
const globalKey = this.getKey('global', 'intent', name);
|
|
197
|
-
const globalData = await this.client.call('JSON.GET', globalKey);
|
|
198
|
-
if (!globalData) {
|
|
199
|
-
// Legacy global fallback
|
|
200
|
-
const legacyKey = `intent:${name}`;
|
|
201
|
-
const legacyData = await this.client.call('JSON.GET', legacyKey);
|
|
202
|
-
if (legacyData)
|
|
203
|
-
return typeof legacyData === 'string' ? JSON.parse(legacyData) : legacyData;
|
|
204
|
-
return null;
|
|
205
|
-
}
|
|
206
|
-
return typeof globalData === 'string' ? JSON.parse(globalData) : globalData;
|
|
207
|
-
}
|
|
208
|
-
async deleteIntent(name, tenantId) {
|
|
209
|
-
const tid = tenantId || 'global';
|
|
210
|
-
const key = this.getKey(tid, 'intent', name);
|
|
211
|
-
const indexKey = this.getKey(tid, 'intents');
|
|
212
|
-
await this.client.del(key);
|
|
213
|
-
await this.client.srem(indexKey, name);
|
|
214
|
-
}
|
|
215
|
-
async getAllIntents(tenantId) {
|
|
216
|
-
const pipeline = this.client.pipeline();
|
|
217
|
-
// 1. Get Tenant Intents
|
|
218
|
-
if (tenantId) {
|
|
219
|
-
const indexKey = this.getKey(tenantId, 'intents');
|
|
220
|
-
const names = await this.client.smembers(indexKey);
|
|
221
|
-
names.forEach(name => {
|
|
222
|
-
pipeline.call('JSON.GET', this.getKey(tenantId, 'intent', name));
|
|
223
|
-
});
|
|
224
|
-
}
|
|
225
|
-
// 2. Get Global Intents
|
|
226
|
-
const globalIndexKey = this.getKey('global', 'intents');
|
|
227
|
-
const globalNames = await this.client.smembers(globalIndexKey);
|
|
228
|
-
globalNames.forEach(name => {
|
|
229
|
-
pipeline.call('JSON.GET', this.getKey('global', 'intent', name));
|
|
230
|
-
});
|
|
231
|
-
const results = await pipeline.exec();
|
|
232
|
-
if (!results)
|
|
233
|
-
return [];
|
|
234
|
-
return results
|
|
235
|
-
.map(([err, res]) => {
|
|
236
|
-
if (err || !res)
|
|
237
|
-
return null;
|
|
238
|
-
return typeof res === 'string' ? JSON.parse(res) : res;
|
|
239
|
-
})
|
|
240
|
-
.filter((i) => i !== null);
|
|
241
|
-
}
|
|
242
|
-
// ============================================================================
|
|
243
|
-
// Workflow Persistence Methods
|
|
244
|
-
// ============================================================================
|
|
245
|
-
async saveWorkflow(workflow) {
|
|
246
|
-
const tenantId = workflow.tenantId || 'global';
|
|
247
|
-
const key = this.getKey(tenantId, 'workflow', workflow.id);
|
|
248
|
-
await this.client.call('JSON.SET', key, '$', JSON.stringify(workflow));
|
|
249
|
-
// Index by event type
|
|
250
|
-
const eventKey = this.getKey(tenantId, 'workflow:events', workflow.event_type);
|
|
251
|
-
await this.client.sadd(eventKey, workflow.id);
|
|
252
|
-
// Index active status
|
|
253
|
-
const activeKey = this.getKey(tenantId, 'workflow:active');
|
|
254
|
-
if (workflow.is_active) {
|
|
255
|
-
await this.client.sadd(activeKey, workflow.id);
|
|
256
|
-
// Scheduling Index (Global ZSET for Cron)
|
|
257
|
-
if (workflow.workflow_cron_configs) {
|
|
258
|
-
const cronConfig = Array.isArray(workflow.workflow_cron_configs)
|
|
259
|
-
? workflow.workflow_cron_configs[0]
|
|
260
|
-
: workflow.workflow_cron_configs;
|
|
261
|
-
if (cronConfig && cronConfig.next_run_at) {
|
|
262
|
-
const nextRun = new Date(cronConfig.next_run_at).getTime();
|
|
263
|
-
// Store as tenantId:workflowId
|
|
264
|
-
await this.client.zadd(`${this.GLOBAL_PREFIX}:{scheduler}:workflows`, nextRun, `${tenantId}:${workflow.id}`);
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
else {
|
|
269
|
-
await this.client.srem(activeKey, workflow.id);
|
|
270
|
-
await this.client.zrem(`${this.GLOBAL_PREFIX}:{scheduler}:workflows`, `${tenantId}:${workflow.id}`);
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
async findWorkflowById(id, tenantId) {
|
|
274
|
-
const key = this.getKey(tenantId || 'global', 'workflow', id);
|
|
275
|
-
const data = await this.client.call('JSON.GET', key);
|
|
276
|
-
if (!data)
|
|
277
|
-
return null;
|
|
278
|
-
return typeof data === 'string' ? JSON.parse(data) : data;
|
|
279
|
-
}
|
|
280
|
-
async getActiveWorkflowsForEvent(tenantId, eventType) {
|
|
281
|
-
const eventKey = this.getKey(tenantId, 'workflow:events', eventType);
|
|
282
|
-
const workflowIds = await this.client.smembers(eventKey);
|
|
283
|
-
if (workflowIds.length === 0)
|
|
284
|
-
return [];
|
|
285
|
-
const pipeline = this.client.pipeline();
|
|
286
|
-
for (const id of workflowIds) {
|
|
287
|
-
const key = this.getKey(tenantId, 'workflow', id);
|
|
288
|
-
pipeline.call('JSON.GET', key);
|
|
289
|
-
}
|
|
290
|
-
const results = await pipeline.exec();
|
|
291
|
-
if (!results)
|
|
292
|
-
return [];
|
|
293
|
-
return results
|
|
294
|
-
.map(([err, res]) => {
|
|
295
|
-
if (err || !res)
|
|
296
|
-
return null;
|
|
297
|
-
const workflow = typeof res === 'string' ? JSON.parse(res) : res;
|
|
298
|
-
return workflow.is_active ? workflow : null;
|
|
299
|
-
})
|
|
300
|
-
.filter((w) => w !== null);
|
|
301
|
-
}
|
|
302
|
-
async deleteWorkflow(id, tenantId) {
|
|
303
|
-
const tid = tenantId || 'global';
|
|
304
|
-
const key = this.getKey(tid, 'workflow', id);
|
|
305
|
-
const data = await this.client.call('JSON.GET', key);
|
|
306
|
-
if (data) {
|
|
307
|
-
const workflow = typeof data === 'string' ? JSON.parse(data) : data;
|
|
308
|
-
const eventKey = this.getKey(tid, 'workflow:events', workflow.event_type);
|
|
309
|
-
await this.client.srem(eventKey, id);
|
|
310
|
-
await this.client.srem(this.getKey(tid, 'workflow:active'), id);
|
|
311
|
-
await this.client.zrem(`${this.GLOBAL_PREFIX}:{scheduler}:workflows`, `${tid}:${id}`);
|
|
312
|
-
}
|
|
313
|
-
await this.client.del(key);
|
|
314
|
-
}
|
|
315
|
-
// ============================================================================
|
|
316
|
-
// Workflow Execution Management
|
|
317
|
-
// ============================================================================
|
|
318
|
-
async createWorkflowExecution(execution) {
|
|
319
|
-
const id = execution.id || `exec_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
320
|
-
const tenantId = execution.tenantId || 'global';
|
|
321
|
-
const newExecution = {
|
|
322
|
-
id,
|
|
323
|
-
tenantId,
|
|
324
|
-
workflow_id: execution.workflow_id || '',
|
|
325
|
-
event_type: execution.event_type || '',
|
|
326
|
-
event_payload: execution.event_payload || {},
|
|
327
|
-
status: execution.status || 'pending',
|
|
328
|
-
started_at: execution.started_at || new Date().toISOString(),
|
|
329
|
-
completed_at: execution.completed_at || null,
|
|
330
|
-
error_message: execution.error_message || null,
|
|
331
|
-
last_failed_step_id: execution.last_failed_step_id || null,
|
|
332
|
-
step_logs: execution.step_logs || [],
|
|
333
|
-
priority: execution.priority || 0
|
|
334
|
-
};
|
|
335
|
-
const key = this.getKey(tenantId, 'execution', id);
|
|
336
|
-
// SET with TTL
|
|
337
|
-
await this.client.call('JSON.SET', key, '$', JSON.stringify(newExecution));
|
|
338
|
-
await this.client.expire(key, this.EXECUTION_TTL_SECONDS);
|
|
339
|
-
// Save Lookup
|
|
340
|
-
const lookupKey = `${this.GLOBAL_PREFIX}:lookup:execution:${id}`;
|
|
341
|
-
await this.client.set(lookupKey, tenantId, 'EX', this.EXECUTION_TTL_SECONDS);
|
|
342
|
-
// Add to status index
|
|
343
|
-
if (newExecution.status === 'pending') {
|
|
344
|
-
await this.client.zadd(this.getKey(tenantId, 'execution:pending'), newExecution.priority || 0, id);
|
|
345
|
-
}
|
|
346
|
-
// Add to workflow index
|
|
347
|
-
const workflowIndexKey = this.getKey(tenantId, 'execution:workflow', newExecution.workflow_id);
|
|
348
|
-
const startedTime = new Date(newExecution.started_at).getTime();
|
|
349
|
-
await this.client.zadd(workflowIndexKey, startedTime, id);
|
|
350
|
-
return newExecution;
|
|
351
|
-
}
|
|
352
|
-
async updateWorkflowExecution(executionId, updates) {
|
|
353
|
-
const existing = await this.getWorkflowExecutionById(executionId);
|
|
354
|
-
if (!existing)
|
|
355
|
-
return;
|
|
356
|
-
const tenantId = existing.tenantId || 'global';
|
|
357
|
-
const key = this.getKey(tenantId, 'execution', executionId);
|
|
358
|
-
const oldStatus = existing.status;
|
|
359
|
-
Object.assign(existing, updates);
|
|
360
|
-
await this.client.call('JSON.SET', key, '$', JSON.stringify(existing));
|
|
361
|
-
await this.client.expire(key, this.EXECUTION_TTL_SECONDS);
|
|
362
|
-
// Update status indexes
|
|
363
|
-
if (updates.status && updates.status !== oldStatus) {
|
|
364
|
-
const pendingKey = this.getKey(tenantId, 'execution:pending');
|
|
365
|
-
if (oldStatus === 'pending') {
|
|
366
|
-
await this.client.zrem(pendingKey, executionId);
|
|
367
|
-
}
|
|
368
|
-
if (updates.status === 'pending') {
|
|
369
|
-
await this.client.zadd(pendingKey, existing.priority || 0, executionId);
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
async getWorkflowExecutionById(executionId) {
|
|
374
|
-
// 1. Try Lookup
|
|
375
|
-
const lookupKey = `${this.GLOBAL_PREFIX}:lookup:execution:${executionId}`;
|
|
376
|
-
const tenantId = await this.client.get(lookupKey);
|
|
377
|
-
let key;
|
|
378
|
-
if (tenantId) {
|
|
379
|
-
key = this.getKey(tenantId, 'execution', executionId);
|
|
380
|
-
}
|
|
381
|
-
else {
|
|
382
|
-
// Try legacy
|
|
383
|
-
const legacyKey = `execution:${executionId}`;
|
|
384
|
-
const data = await this.client.call('JSON.GET', legacyKey);
|
|
385
|
-
if (data)
|
|
386
|
-
return typeof data === 'string' ? JSON.parse(data) : data;
|
|
387
|
-
// Try assuming global (pre-migration with global prefix?)
|
|
388
|
-
key = this.getKey('global', 'execution', executionId);
|
|
389
|
-
}
|
|
390
|
-
// 2. Fetch
|
|
391
|
-
const data = await this.client.call('JSON.GET', key);
|
|
392
|
-
if (!data)
|
|
393
|
-
return null;
|
|
394
|
-
return typeof data === 'string' ? JSON.parse(data) : data;
|
|
395
|
-
}
|
|
396
|
-
async getWorkflowExecutionWithLogs(executionId) {
|
|
397
|
-
const execution = await this.getWorkflowExecutionById(executionId);
|
|
398
|
-
if (!execution) {
|
|
399
|
-
throw new Error(`Execution ${executionId} not found`);
|
|
400
|
-
}
|
|
401
|
-
const tenantId = execution.tenantId || 'global';
|
|
402
|
-
const logs = await this.getWorkflowExecutionLogs(executionId);
|
|
403
|
-
const workflow = await this.findWorkflowById(execution.workflow_id, tenantId);
|
|
404
|
-
return {
|
|
405
|
-
...execution,
|
|
406
|
-
workflow_action_logs: logs,
|
|
407
|
-
workflow: workflow
|
|
408
|
-
};
|
|
409
|
-
}
|
|
410
|
-
async getPendingWorkflowExecutions(limit) {
|
|
411
|
-
// GLOBAL POLLING MOCK - ideally we poll specific queues or a global one.
|
|
412
|
-
// For now, let's scan a global 'pending' ZSET if we implemented one?
|
|
413
|
-
// We only implemented per-tenant 'execution:pending'.
|
|
414
|
-
// We should PROBABLY have a global 'system:pending' for the dispatcher.
|
|
415
|
-
// But for this refactor, let's just assume we check the 'global' tenant or this method is deprecated for multi-tenant.
|
|
416
|
-
// Or we iterate all tenants? (Impossible efficiently).
|
|
417
|
-
// Fix: We should also add to a global pending queue in createWorkflowExecution if we want a global dispatcher.
|
|
418
|
-
// But that breaks strict data residency if required.
|
|
419
|
-
// Let's assume 'global' tenant for now or verify if we can add a global 'queue'.
|
|
420
|
-
// HACK: Just check 'global' tenant for now since existing tests/usage likely use it.
|
|
421
|
-
const key = this.getKey('global', 'execution:pending');
|
|
422
|
-
const ids = await this.client.zrange(key, 0, limit - 1);
|
|
423
|
-
const results = [];
|
|
424
|
-
for (const id of ids) {
|
|
425
|
-
const exec = await this.getWorkflowExecutionById(id);
|
|
426
|
-
if (exec)
|
|
427
|
-
results.push(exec);
|
|
428
|
-
}
|
|
429
|
-
return results;
|
|
430
|
-
}
|
|
431
|
-
async getActiveWorkflowExecutionCount(workflowId) {
|
|
432
|
-
// Limited implementation without tenant context
|
|
433
|
-
return 0;
|
|
434
|
-
}
|
|
435
|
-
async markWorkflowExecutionFailed(executionId, error) {
|
|
436
|
-
await this.updateWorkflowExecution(executionId, {
|
|
437
|
-
status: 'failed',
|
|
438
|
-
error_message: error,
|
|
439
|
-
completed_at: new Date().toISOString()
|
|
440
|
-
});
|
|
441
|
-
}
|
|
442
|
-
// ============================================================================
|
|
443
|
-
// Workflow Action Logging
|
|
444
|
-
// ============================================================================
|
|
445
|
-
async logWorkflowAction(logEntry) {
|
|
446
|
-
const id = logEntry.id || `log_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
447
|
-
const tenantId = logEntry.tenantId || 'global';
|
|
448
|
-
const newLog = {
|
|
449
|
-
id,
|
|
450
|
-
workflow_id: logEntry.workflow_id || null,
|
|
451
|
-
tenantId,
|
|
452
|
-
execution_id: logEntry.execution_id || '',
|
|
453
|
-
step_id: logEntry.step_id || null,
|
|
454
|
-
action_type: logEntry.action_type || '',
|
|
455
|
-
input: logEntry.input || null,
|
|
456
|
-
output: logEntry.output || null,
|
|
457
|
-
status: logEntry.status || 'pending',
|
|
458
|
-
error_message: logEntry.error_message || null,
|
|
459
|
-
started_at: logEntry.started_at || new Date().toISOString(),
|
|
460
|
-
completed_at: logEntry.completed_at || null
|
|
461
|
-
};
|
|
462
|
-
const key = this.getKey(tenantId, 'log', id);
|
|
463
|
-
await this.client.call('JSON.SET', key, '$', JSON.stringify(newLog));
|
|
464
|
-
await this.client.expire(key, this.EXECUTION_TTL_SECONDS);
|
|
465
|
-
// Index by execution
|
|
466
|
-
const indexKey = this.getKey(tenantId, 'logs:execution', newLog.execution_id);
|
|
467
|
-
await this.client.rpush(indexKey, id);
|
|
468
|
-
await this.client.expire(indexKey, this.EXECUTION_TTL_SECONDS);
|
|
469
|
-
return newLog;
|
|
470
|
-
}
|
|
471
|
-
async getWorkflowExecutionLogs(executionId) {
|
|
472
|
-
const execution = await this.getWorkflowExecutionById(executionId);
|
|
473
|
-
if (!execution)
|
|
474
|
-
return [];
|
|
475
|
-
const tenantId = execution.tenantId || 'global';
|
|
476
|
-
const indexKey = this.getKey(tenantId, 'logs:execution', executionId);
|
|
477
|
-
const logIds = await this.client.lrange(indexKey, 0, -1);
|
|
478
|
-
if (logIds.length === 0)
|
|
479
|
-
return [];
|
|
480
|
-
const pipeline = this.client.pipeline();
|
|
481
|
-
for (const logId of logIds) {
|
|
482
|
-
pipeline.call('JSON.GET', this.getKey(tenantId, 'log', logId));
|
|
483
|
-
}
|
|
484
|
-
const results = await pipeline.exec();
|
|
485
|
-
if (!results)
|
|
486
|
-
return [];
|
|
487
|
-
return results
|
|
488
|
-
.map(([err, res]) => {
|
|
489
|
-
if (err || !res)
|
|
490
|
-
return null;
|
|
491
|
-
return typeof res === 'string' ? JSON.parse(res) : res;
|
|
492
|
-
})
|
|
493
|
-
.filter((log) => log !== null);
|
|
494
|
-
}
|
|
495
|
-
// ============================================================================
|
|
496
|
-
// Webhook Event Storage
|
|
497
|
-
// ============================================================================
|
|
498
|
-
async storeWebhookEvent(event) {
|
|
499
|
-
const id = await this.client.incr(`${this.GLOBAL_PREFIX}:counter:webhook`);
|
|
500
|
-
const tenantId = event.tenantId || 'global';
|
|
501
|
-
const newEvent = {
|
|
502
|
-
id,
|
|
503
|
-
created_at: event.created_at || new Date().toISOString(),
|
|
504
|
-
type: event.type || '',
|
|
505
|
-
payload: event.payload || {},
|
|
506
|
-
source: event.source || '',
|
|
507
|
-
tenantId,
|
|
508
|
-
status: event.status || 'pending',
|
|
509
|
-
error_message: event.error_message || null
|
|
510
|
-
};
|
|
511
|
-
const key = this.getKey(tenantId, 'webhook:event', id.toString());
|
|
512
|
-
await this.client.call('JSON.SET', key, '$', JSON.stringify(newEvent));
|
|
513
|
-
await this.client.expire(key, this.EXECUTION_TTL_SECONDS);
|
|
514
|
-
// Save Lookup
|
|
515
|
-
const lookupKey = `${this.GLOBAL_PREFIX}:lookup:webhook:${id}`;
|
|
516
|
-
await this.client.set(lookupKey, tenantId, 'EX', this.EXECUTION_TTL_SECONDS);
|
|
517
|
-
return id;
|
|
518
|
-
}
|
|
519
|
-
async getWebhookEvent(id) {
|
|
520
|
-
// 1. Try Lookup
|
|
521
|
-
const lookupKey = `${this.GLOBAL_PREFIX}:lookup:webhook:${id}`;
|
|
522
|
-
const tenantId = await this.client.get(lookupKey);
|
|
523
|
-
let key;
|
|
524
|
-
if (tenantId) {
|
|
525
|
-
key = this.getKey(tenantId, 'webhook:event', id.toString());
|
|
526
|
-
}
|
|
527
|
-
else {
|
|
528
|
-
// Fallback to legacy or global check?
|
|
529
|
-
// Assuming existing ones might be under intent-less keys.
|
|
530
|
-
// We can't recover easily without lookup for new segmented model.
|
|
531
|
-
return null;
|
|
532
|
-
}
|
|
533
|
-
const data = await this.client.call('JSON.GET', key);
|
|
534
|
-
if (!data)
|
|
535
|
-
return null;
|
|
536
|
-
return typeof data === 'string' ? JSON.parse(data) : data;
|
|
537
|
-
}
|
|
538
|
-
async updateWebhookEventStatus(id, updates) {
|
|
539
|
-
const event = await this.getWebhookEvent(id);
|
|
540
|
-
if (!event)
|
|
541
|
-
return;
|
|
542
|
-
const tenantId = event.tenantId || 'global'; // Should be there if we found it
|
|
543
|
-
const key = this.getKey(tenantId, 'webhook:event', id.toString());
|
|
544
|
-
Object.assign(event, updates);
|
|
545
|
-
await this.client.call('JSON.SET', key, '$', JSON.stringify(event));
|
|
546
|
-
await this.client.expire(key, this.EXECUTION_TTL_SECONDS);
|
|
547
|
-
}
|
|
548
|
-
// ============================================================================
|
|
549
|
-
// Workflow Scheduling (Cron)
|
|
550
|
-
// ============================================================================
|
|
551
|
-
async getDueScheduledWorkflows(now) {
|
|
552
|
-
const schedulerKey = `${this.GLOBAL_PREFIX}:{scheduler}:workflows`;
|
|
553
|
-
const nowScore = now.getTime();
|
|
554
|
-
const members = await this.client.zrangebyscore(schedulerKey, 0, nowScore);
|
|
555
|
-
if (members.length === 0)
|
|
556
|
-
return [];
|
|
557
|
-
const workflows = [];
|
|
558
|
-
const pipeline = this.client.pipeline();
|
|
559
|
-
for (const member of members) {
|
|
560
|
-
const [tenantId, workflowId] = member.split(':');
|
|
561
|
-
const key = this.getKey(tenantId, 'workflow', workflowId);
|
|
562
|
-
pipeline.call('JSON.GET', key);
|
|
563
|
-
}
|
|
564
|
-
const results = await pipeline.exec();
|
|
565
|
-
if (!results)
|
|
566
|
-
return [];
|
|
567
|
-
results.forEach(([err, res]) => {
|
|
568
|
-
if (!err && res) {
|
|
569
|
-
workflows.push(typeof res === 'string' ? JSON.parse(res) : res);
|
|
570
|
-
}
|
|
571
|
-
});
|
|
572
|
-
return workflows;
|
|
573
|
-
}
|
|
574
|
-
async updateWorkflowSchedule(workflowId, nextRun) {
|
|
575
|
-
// Without tenantId, this is hard.
|
|
576
|
-
// We will assume this method is deprecated or called ONLY after a verification logic that should pass tenantId
|
|
577
|
-
// but interface limits us.
|
|
578
|
-
// We can't implement this efficiently without tenantId in args.
|
|
579
|
-
return;
|
|
580
|
-
}
|
|
581
|
-
async disconnect() {
|
|
582
|
-
await this.client.quit();
|
|
583
|
-
}
|
|
584
|
-
}
|
|
585
|
-
exports.RedisRepository = RedisRepository;
|
|
586
|
-
//# sourceMappingURL=RedisRepository.js.map
|