@ajna-inc/workflow 0.5.37 → 0.6.1
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/.npmvc/attestations.jsonld +32 -0
- package/LICENSE +202 -0
- package/build/WorkflowEvents.d.mts +40 -0
- package/build/WorkflowEvents.d.mts.map +1 -0
- package/build/WorkflowEvents.mjs +11 -0
- package/build/WorkflowEvents.mjs.map +1 -0
- package/build/WorkflowModule.d.mts +17 -0
- package/build/WorkflowModule.d.mts.map +1 -0
- package/build/WorkflowModule.mjs +446 -0
- package/build/WorkflowModule.mjs.map +1 -0
- package/build/WorkflowModuleConfig.d.mts +39 -0
- package/build/WorkflowModuleConfig.d.mts.map +1 -0
- package/build/WorkflowModuleConfig.mjs +19 -0
- package/build/WorkflowModuleConfig.mjs.map +1 -0
- package/build/_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs +14 -0
- package/build/_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs +11 -0
- package/build/_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateParam.mjs +9 -0
- package/build/_virtual/rolldown_runtime.mjs +41 -0
- package/build/actions/ActionRegistry.d.mts +64 -0
- package/build/actions/ActionRegistry.d.mts.map +1 -0
- package/build/actions/ActionRegistry.mjs +304 -0
- package/build/actions/ActionRegistry.mjs.map +1 -0
- package/build/api/WorkflowApi.d.mts +99 -0
- package/build/api/WorkflowApi.d.mts.map +1 -0
- package/build/api/WorkflowApi.mjs +228 -0
- package/build/api/WorkflowApi.mjs.map +1 -0
- package/build/engine/AttributePlanner.d.mts +12 -0
- package/build/engine/AttributePlanner.d.mts.map +1 -0
- package/build/engine/AttributePlanner.mjs +58 -0
- package/build/engine/AttributePlanner.mjs.map +1 -0
- package/build/engine/GuardEvaluator.d.mts +16 -0
- package/build/engine/GuardEvaluator.d.mts.map +1 -0
- package/build/engine/GuardEvaluator.mjs +38 -0
- package/build/engine/GuardEvaluator.mjs.map +1 -0
- package/build/index.d.mts +46 -0
- package/build/index.mjs +53 -0
- package/build/index.mjs.map +1 -0
- package/build/model/TemplateValidation.d.mts +8 -0
- package/build/model/TemplateValidation.d.mts.map +1 -0
- package/build/model/TemplateValidation.mjs +278 -0
- package/build/model/TemplateValidation.mjs.map +1 -0
- package/build/model/types.d.mts +120 -0
- package/build/model/types.d.mts.map +1 -0
- package/build/model/types.mjs +11 -0
- package/build/model/types.mjs.map +1 -0
- package/build/protocol/WorkflowMessageTypes.d.mts +19 -0
- package/build/protocol/WorkflowMessageTypes.d.mts.map +1 -0
- package/build/protocol/WorkflowMessageTypes.mjs +20 -0
- package/build/protocol/WorkflowMessageTypes.mjs.map +1 -0
- package/build/protocol/handlers/AdvanceHandler.d.mts +16 -0
- package/build/protocol/handlers/AdvanceHandler.d.mts.map +1 -0
- package/build/protocol/handlers/AdvanceHandler.mjs +148 -0
- package/build/protocol/handlers/AdvanceHandler.mjs.map +1 -0
- package/build/protocol/handlers/CancelHandler.d.mts +16 -0
- package/build/protocol/handlers/CancelHandler.d.mts.map +1 -0
- package/build/protocol/handlers/CancelHandler.mjs +103 -0
- package/build/protocol/handlers/CancelHandler.mjs.map +1 -0
- package/build/protocol/handlers/CompleteHandler.d.mts +16 -0
- package/build/protocol/handlers/CompleteHandler.d.mts.map +1 -0
- package/build/protocol/handlers/CompleteHandler.mjs +103 -0
- package/build/protocol/handlers/CompleteHandler.mjs.map +1 -0
- package/build/protocol/handlers/DiscoverHandler.d.mts +15 -0
- package/build/protocol/handlers/DiscoverHandler.d.mts.map +1 -0
- package/build/protocol/handlers/DiscoverHandler.mjs +73 -0
- package/build/protocol/handlers/DiscoverHandler.mjs.map +1 -0
- package/build/protocol/handlers/FetchTemplateHandler.d.mts +16 -0
- package/build/protocol/handlers/FetchTemplateHandler.d.mts.map +1 -0
- package/build/protocol/handlers/FetchTemplateHandler.mjs +64 -0
- package/build/protocol/handlers/FetchTemplateHandler.mjs.map +1 -0
- package/build/protocol/handlers/PauseHandler.d.mts +16 -0
- package/build/protocol/handlers/PauseHandler.d.mts.map +1 -0
- package/build/protocol/handlers/PauseHandler.mjs +103 -0
- package/build/protocol/handlers/PauseHandler.mjs.map +1 -0
- package/build/protocol/handlers/ProblemReportHandler.d.mts +11 -0
- package/build/protocol/handlers/ProblemReportHandler.d.mts.map +1 -0
- package/build/protocol/handlers/ProblemReportHandler.mjs +26 -0
- package/build/protocol/handlers/ProblemReportHandler.mjs.map +1 -0
- package/build/protocol/handlers/PublishTemplateHandler.d.mts +15 -0
- package/build/protocol/handlers/PublishTemplateHandler.d.mts.map +1 -0
- package/build/protocol/handlers/PublishTemplateHandler.mjs +47 -0
- package/build/protocol/handlers/PublishTemplateHandler.mjs.map +1 -0
- package/build/protocol/handlers/ResumeHandler.d.mts +16 -0
- package/build/protocol/handlers/ResumeHandler.d.mts.map +1 -0
- package/build/protocol/handlers/ResumeHandler.mjs +103 -0
- package/build/protocol/handlers/ResumeHandler.mjs.map +1 -0
- package/build/protocol/handlers/StartHandler.d.mts +16 -0
- package/build/protocol/handlers/StartHandler.d.mts.map +1 -0
- package/build/protocol/handlers/StartHandler.mjs +238 -0
- package/build/protocol/handlers/StartHandler.mjs.map +1 -0
- package/build/protocol/handlers/StatusHandler.d.mts +16 -0
- package/build/protocol/handlers/StatusHandler.d.mts.map +1 -0
- package/build/protocol/handlers/StatusHandler.mjs +169 -0
- package/build/protocol/handlers/StatusHandler.mjs.map +1 -0
- package/build/protocol/handlers/TemplateHandler.d.mts +14 -0
- package/build/protocol/handlers/TemplateHandler.d.mts.map +1 -0
- package/build/protocol/handlers/TemplateHandler.mjs +66 -0
- package/build/protocol/handlers/TemplateHandler.mjs.map +1 -0
- package/build/protocol/messages/AdvanceMessage.d.mts +22 -0
- package/build/protocol/messages/AdvanceMessage.d.mts.map +1 -0
- package/build/protocol/messages/AdvanceMessage.mjs +25 -0
- package/build/protocol/messages/AdvanceMessage.mjs.map +1 -0
- package/build/protocol/messages/CancelMessage.d.mts +20 -0
- package/build/protocol/messages/CancelMessage.d.mts.map +1 -0
- package/build/protocol/messages/CancelMessage.mjs +25 -0
- package/build/protocol/messages/CancelMessage.mjs.map +1 -0
- package/build/protocol/messages/CompleteMessage.d.mts +20 -0
- package/build/protocol/messages/CompleteMessage.d.mts.map +1 -0
- package/build/protocol/messages/CompleteMessage.mjs +25 -0
- package/build/protocol/messages/CompleteMessage.mjs.map +1 -0
- package/build/protocol/messages/DiscoverMessage.d.mts +29 -0
- package/build/protocol/messages/DiscoverMessage.d.mts.map +1 -0
- package/build/protocol/messages/DiscoverMessage.mjs +25 -0
- package/build/protocol/messages/DiscoverMessage.mjs.map +1 -0
- package/build/protocol/messages/FetchTemplateMessage.d.mts +21 -0
- package/build/protocol/messages/FetchTemplateMessage.d.mts.map +1 -0
- package/build/protocol/messages/FetchTemplateMessage.mjs +31 -0
- package/build/protocol/messages/FetchTemplateMessage.mjs.map +1 -0
- package/build/protocol/messages/PauseMessage.d.mts +20 -0
- package/build/protocol/messages/PauseMessage.d.mts.map +1 -0
- package/build/protocol/messages/PauseMessage.mjs +25 -0
- package/build/protocol/messages/PauseMessage.mjs.map +1 -0
- package/build/protocol/messages/ProblemReportMessage.d.mts +21 -0
- package/build/protocol/messages/ProblemReportMessage.d.mts.map +1 -0
- package/build/protocol/messages/ProblemReportMessage.mjs +25 -0
- package/build/protocol/messages/ProblemReportMessage.mjs.map +1 -0
- package/build/protocol/messages/PublishTemplateMessage.d.mts +23 -0
- package/build/protocol/messages/PublishTemplateMessage.d.mts.map +1 -0
- package/build/protocol/messages/PublishTemplateMessage.mjs +24 -0
- package/build/protocol/messages/PublishTemplateMessage.mjs.map +1 -0
- package/build/protocol/messages/ResumeMessage.d.mts +20 -0
- package/build/protocol/messages/ResumeMessage.d.mts.map +1 -0
- package/build/protocol/messages/ResumeMessage.mjs +25 -0
- package/build/protocol/messages/ResumeMessage.mjs.map +1 -0
- package/build/protocol/messages/StartMessage.d.mts +27 -0
- package/build/protocol/messages/StartMessage.d.mts.map +1 -0
- package/build/protocol/messages/StartMessage.mjs +25 -0
- package/build/protocol/messages/StartMessage.mjs.map +1 -0
- package/build/protocol/messages/StatusMessage.d.mts +35 -0
- package/build/protocol/messages/StatusMessage.d.mts.map +1 -0
- package/build/protocol/messages/StatusMessage.mjs +25 -0
- package/build/protocol/messages/StatusMessage.mjs.map +1 -0
- package/build/protocol/messages/StatusRequestMessage.d.mts +29 -0
- package/build/protocol/messages/StatusRequestMessage.d.mts.map +1 -0
- package/build/protocol/messages/StatusRequestMessage.mjs +25 -0
- package/build/protocol/messages/StatusRequestMessage.mjs.map +1 -0
- package/build/protocol/messages/TemplateMessage.d.mts +20 -0
- package/build/protocol/messages/TemplateMessage.d.mts.map +1 -0
- package/build/protocol/messages/TemplateMessage.mjs +25 -0
- package/build/protocol/messages/TemplateMessage.mjs.map +1 -0
- package/build/protocol/messages/WorkflowsMessage.d.mts +28 -0
- package/build/protocol/messages/WorkflowsMessage.d.mts.map +1 -0
- package/build/protocol/messages/WorkflowsMessage.mjs +25 -0
- package/build/protocol/messages/WorkflowsMessage.mjs.map +1 -0
- package/build/queue/CommandQueue.d.mts +22 -0
- package/build/queue/CommandQueue.d.mts.map +1 -0
- package/build/queue/CommandQueue.mjs +6 -0
- package/build/queue/CommandQueue.mjs.map +1 -0
- package/build/queue/PersistentCommandQueue.d.mts +56 -0
- package/build/queue/PersistentCommandQueue.d.mts.map +1 -0
- package/build/queue/PersistentCommandQueue.mjs +273 -0
- package/build/queue/PersistentCommandQueue.mjs.map +1 -0
- package/build/repository/WorkflowCommandRecord.d.mts +50 -0
- package/build/repository/WorkflowCommandRecord.d.mts.map +1 -0
- package/build/repository/WorkflowCommandRecord.mjs +48 -0
- package/build/repository/WorkflowCommandRecord.mjs.map +1 -0
- package/build/repository/WorkflowCommandRepository.d.mts +59 -0
- package/build/repository/WorkflowCommandRepository.d.mts.map +1 -0
- package/build/repository/WorkflowCommandRepository.mjs +136 -0
- package/build/repository/WorkflowCommandRepository.mjs.map +1 -0
- package/build/repository/WorkflowInstanceRecord.d.mts +65 -0
- package/build/repository/WorkflowInstanceRecord.d.mts.map +1 -0
- package/build/repository/WorkflowInstanceRecord.mjs +44 -0
- package/build/repository/WorkflowInstanceRecord.mjs.map +1 -0
- package/build/repository/WorkflowInstanceRepository.d.mts +15 -0
- package/build/repository/WorkflowInstanceRepository.d.mts.map +1 -0
- package/build/repository/WorkflowInstanceRepository.mjs +48 -0
- package/build/repository/WorkflowInstanceRepository.mjs.map +1 -0
- package/build/repository/WorkflowTemplateRecord.d.mts +27 -0
- package/build/repository/WorkflowTemplateRecord.d.mts.map +1 -0
- package/build/repository/WorkflowTemplateRecord.mjs +29 -0
- package/build/repository/WorkflowTemplateRecord.mjs.map +1 -0
- package/build/repository/WorkflowTemplateRepository.d.mts +11 -0
- package/build/repository/WorkflowTemplateRepository.d.mts.map +1 -0
- package/build/repository/WorkflowTemplateRepository.mjs +43 -0
- package/build/repository/WorkflowTemplateRepository.mjs.map +1 -0
- package/build/services/WorkflowService.d.mts +107 -0
- package/build/services/WorkflowService.d.mts.map +1 -0
- package/build/services/WorkflowService.mjs +582 -0
- package/build/services/WorkflowService.mjs.map +1 -0
- package/build/ui/UiFilter.mjs +85 -0
- package/build/ui/UiFilter.mjs.map +1 -0
- package/package.json +27 -33
- package/build/WorkflowEvents.d.ts +0 -35
- package/build/WorkflowEvents.js +0 -10
- package/build/WorkflowEvents.js.map +0 -1
- package/build/WorkflowModule.d.ts +0 -13
- package/build/WorkflowModule.js +0 -647
- package/build/WorkflowModule.js.map +0 -1
- package/build/WorkflowModuleConfig.d.ts +0 -35
- package/build/WorkflowModuleConfig.js +0 -19
- package/build/WorkflowModuleConfig.js.map +0 -1
- package/build/actions/ActionRegistry.d.ts +0 -59
- package/build/actions/ActionRegistry.js +0 -367
- package/build/actions/ActionRegistry.js.map +0 -1
- package/build/api/WorkflowApi.d.ts +0 -94
- package/build/api/WorkflowApi.js +0 -241
- package/build/api/WorkflowApi.js.map +0 -1
- package/build/engine/AttributePlanner.d.ts +0 -7
- package/build/engine/AttributePlanner.js +0 -81
- package/build/engine/AttributePlanner.js.map +0 -1
- package/build/engine/GuardEvaluator.d.ts +0 -11
- package/build/engine/GuardEvaluator.js +0 -40
- package/build/engine/GuardEvaluator.js.map +0 -1
- package/build/index.d.ts +0 -45
- package/build/index.js +0 -69
- package/build/index.js.map +0 -1
- package/build/model/TemplateValidation.d.ts +0 -3
- package/build/model/TemplateValidation.js +0 -231
- package/build/model/TemplateValidation.js.map +0 -1
- package/build/model/types.d.ts +0 -116
- package/build/model/types.js +0 -15
- package/build/model/types.js.map +0 -1
- package/build/protocol/WorkflowMessageTypes.d.ts +0 -15
- package/build/protocol/WorkflowMessageTypes.js +0 -22
- package/build/protocol/WorkflowMessageTypes.js.map +0 -1
- package/build/protocol/handlers/AdvanceHandler.d.ts +0 -12
- package/build/protocol/handlers/AdvanceHandler.js +0 -149
- package/build/protocol/handlers/AdvanceHandler.js.map +0 -1
- package/build/protocol/handlers/CancelHandler.d.ts +0 -12
- package/build/protocol/handlers/CancelHandler.js +0 -124
- package/build/protocol/handlers/CancelHandler.js.map +0 -1
- package/build/protocol/handlers/CompleteHandler.d.ts +0 -12
- package/build/protocol/handlers/CompleteHandler.js +0 -125
- package/build/protocol/handlers/CompleteHandler.js.map +0 -1
- package/build/protocol/handlers/DiscoverHandler.d.ts +0 -11
- package/build/protocol/handlers/DiscoverHandler.js +0 -71
- package/build/protocol/handlers/DiscoverHandler.js.map +0 -1
- package/build/protocol/handlers/FetchTemplateHandler.d.ts +0 -12
- package/build/protocol/handlers/FetchTemplateHandler.js +0 -71
- package/build/protocol/handlers/FetchTemplateHandler.js.map +0 -1
- package/build/protocol/handlers/PauseHandler.d.ts +0 -12
- package/build/protocol/handlers/PauseHandler.js +0 -124
- package/build/protocol/handlers/PauseHandler.js.map +0 -1
- package/build/protocol/handlers/ProblemReportHandler.d.ts +0 -6
- package/build/protocol/handlers/ProblemReportHandler.js +0 -28
- package/build/protocol/handlers/ProblemReportHandler.js.map +0 -1
- package/build/protocol/handlers/PublishTemplateHandler.d.ts +0 -11
- package/build/protocol/handlers/PublishTemplateHandler.js +0 -53
- package/build/protocol/handlers/PublishTemplateHandler.js.map +0 -1
- package/build/protocol/handlers/ResumeHandler.d.ts +0 -12
- package/build/protocol/handlers/ResumeHandler.js +0 -124
- package/build/protocol/handlers/ResumeHandler.js.map +0 -1
- package/build/protocol/handlers/StartHandler.d.ts +0 -12
- package/build/protocol/handlers/StartHandler.js +0 -274
- package/build/protocol/handlers/StartHandler.js.map +0 -1
- package/build/protocol/handlers/StatusHandler.d.ts +0 -12
- package/build/protocol/handlers/StatusHandler.js +0 -202
- package/build/protocol/handlers/StatusHandler.js.map +0 -1
- package/build/protocol/handlers/TemplateHandler.d.ts +0 -9
- package/build/protocol/handlers/TemplateHandler.js +0 -83
- package/build/protocol/handlers/TemplateHandler.js.map +0 -1
- package/build/protocol/messages/AdvanceMessage.d.ts +0 -16
- package/build/protocol/messages/AdvanceMessage.js +0 -33
- package/build/protocol/messages/AdvanceMessage.js.map +0 -1
- package/build/protocol/messages/CancelMessage.d.ts +0 -14
- package/build/protocol/messages/CancelMessage.js +0 -33
- package/build/protocol/messages/CancelMessage.js.map +0 -1
- package/build/protocol/messages/CompleteMessage.d.ts +0 -14
- package/build/protocol/messages/CompleteMessage.js +0 -33
- package/build/protocol/messages/CompleteMessage.js.map +0 -1
- package/build/protocol/messages/DiscoverMessage.d.ts +0 -23
- package/build/protocol/messages/DiscoverMessage.js +0 -33
- package/build/protocol/messages/DiscoverMessage.js.map +0 -1
- package/build/protocol/messages/FetchTemplateMessage.d.ts +0 -15
- package/build/protocol/messages/FetchTemplateMessage.js +0 -33
- package/build/protocol/messages/FetchTemplateMessage.js.map +0 -1
- package/build/protocol/messages/PauseMessage.d.ts +0 -14
- package/build/protocol/messages/PauseMessage.js +0 -33
- package/build/protocol/messages/PauseMessage.js.map +0 -1
- package/build/protocol/messages/ProblemReportMessage.d.ts +0 -15
- package/build/protocol/messages/ProblemReportMessage.js +0 -33
- package/build/protocol/messages/ProblemReportMessage.js.map +0 -1
- package/build/protocol/messages/PublishTemplateMessage.d.ts +0 -17
- package/build/protocol/messages/PublishTemplateMessage.js +0 -31
- package/build/protocol/messages/PublishTemplateMessage.js.map +0 -1
- package/build/protocol/messages/ResumeMessage.d.ts +0 -14
- package/build/protocol/messages/ResumeMessage.js +0 -33
- package/build/protocol/messages/ResumeMessage.js.map +0 -1
- package/build/protocol/messages/StartMessage.d.ts +0 -21
- package/build/protocol/messages/StartMessage.js +0 -33
- package/build/protocol/messages/StartMessage.js.map +0 -1
- package/build/protocol/messages/StatusMessage.d.ts +0 -29
- package/build/protocol/messages/StatusMessage.js +0 -33
- package/build/protocol/messages/StatusMessage.js.map +0 -1
- package/build/protocol/messages/StatusRequestMessage.d.ts +0 -23
- package/build/protocol/messages/StatusRequestMessage.js +0 -33
- package/build/protocol/messages/StatusRequestMessage.js.map +0 -1
- package/build/protocol/messages/TemplateMessage.d.ts +0 -14
- package/build/protocol/messages/TemplateMessage.js +0 -33
- package/build/protocol/messages/TemplateMessage.js.map +0 -1
- package/build/protocol/messages/WorkflowsMessage.d.ts +0 -22
- package/build/protocol/messages/WorkflowsMessage.js +0 -33
- package/build/protocol/messages/WorkflowsMessage.js.map +0 -1
- package/build/queue/CommandQueue.d.ts +0 -18
- package/build/queue/CommandQueue.js +0 -8
- package/build/queue/CommandQueue.js.map +0 -1
- package/build/queue/PersistentCommandQueue.d.ts +0 -51
- package/build/queue/PersistentCommandQueue.js +0 -348
- package/build/queue/PersistentCommandQueue.js.map +0 -1
- package/build/repository/WorkflowCommandRecord.d.ts +0 -46
- package/build/repository/WorkflowCommandRecord.js +0 -52
- package/build/repository/WorkflowCommandRecord.js.map +0 -1
- package/build/repository/WorkflowCommandRepository.d.ts +0 -55
- package/build/repository/WorkflowCommandRepository.js +0 -149
- package/build/repository/WorkflowCommandRepository.js.map +0 -1
- package/build/repository/WorkflowInstanceRecord.d.ts +0 -61
- package/build/repository/WorkflowInstanceRecord.js +0 -43
- package/build/repository/WorkflowInstanceRecord.js.map +0 -1
- package/build/repository/WorkflowInstanceRepository.d.ts +0 -10
- package/build/repository/WorkflowInstanceRepository.js +0 -52
- package/build/repository/WorkflowInstanceRepository.js.map +0 -1
- package/build/repository/WorkflowTemplateRecord.d.ts +0 -23
- package/build/repository/WorkflowTemplateRecord.js +0 -28
- package/build/repository/WorkflowTemplateRecord.js.map +0 -1
- package/build/repository/WorkflowTemplateRepository.d.ts +0 -6
- package/build/repository/WorkflowTemplateRepository.js +0 -56
- package/build/repository/WorkflowTemplateRepository.js.map +0 -1
- package/build/services/WorkflowService.d.ts +0 -102
- package/build/services/WorkflowService.js +0 -704
- package/build/services/WorkflowService.js.map +0 -1
- package/build/ui/UiFilter.d.ts +0 -5
- package/build/ui/UiFilter.js +0 -104
- package/build/ui/UiFilter.js.map +0 -1
- package/build/ui/UiTypes.d.ts +0 -28
- package/build/ui/UiTypes.js +0 -3
- package/build/ui/UiTypes.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CommandQueue.mjs","names":[],"sources":["../../src/queue/CommandQueue.ts"],"sourcesContent":["import type { AgentContext } from '@credo-ts/core'\n\nexport type WorkflowCommandJob = {\n cmd: 'start' | 'advance' | 'pause' | 'resume' | 'cancel' | 'complete'\n thid: string\n connectionId?: string\n idempotency_key?: string\n payload: Record<string, unknown>\n contextCorrelationId: string\n}\n\nexport interface CommandQueue {\n enqueue(agentContext: AgentContext, job: WorkflowCommandJob): Promise<void>\n startWorker(onJob: (job: WorkflowCommandJob) => Promise<void>): Promise<void>\n stop(): Promise<void>\n isReady(): Promise<boolean>\n // Hint the queue to poll immediately (best-effort)\n triggerPoll?(): void\n}\n\n// DI token for the queue instance\nexport class CommandQueueService {}\n"],"mappings":";AAqBA,IAAa,sBAAb,MAAiC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { WorkflowCommandRepository } from "../repository/WorkflowCommandRepository.mjs";
|
|
2
|
+
import { CommandQueue, WorkflowCommandJob } from "./CommandQueue.mjs";
|
|
3
|
+
import { AgentContext, AgentContextProvider } from "@credo-ts/core";
|
|
4
|
+
|
|
5
|
+
//#region src/queue/PersistentCommandQueue.d.ts
|
|
6
|
+
interface PersistentCommandQueueOptions {
|
|
7
|
+
pollIntervalMs?: number;
|
|
8
|
+
concurrency?: number;
|
|
9
|
+
processingTimeoutMs?: number;
|
|
10
|
+
staleCheckIntervalMs?: number;
|
|
11
|
+
cleanupIntervalMs?: number;
|
|
12
|
+
commandRetentionMs?: number;
|
|
13
|
+
failedRetentionMs?: number;
|
|
14
|
+
maxAttempts?: number;
|
|
15
|
+
}
|
|
16
|
+
declare class PersistentCommandQueue implements CommandQueue {
|
|
17
|
+
private readonly pollIntervalMs;
|
|
18
|
+
private readonly concurrency;
|
|
19
|
+
private readonly processingTimeoutMs;
|
|
20
|
+
private readonly staleCheckIntervalMs;
|
|
21
|
+
private readonly cleanupIntervalMs;
|
|
22
|
+
private readonly commandRetentionMs;
|
|
23
|
+
private readonly failedRetentionMs;
|
|
24
|
+
private readonly maxAttempts;
|
|
25
|
+
private running;
|
|
26
|
+
private activeCount;
|
|
27
|
+
private onJobHandler?;
|
|
28
|
+
private readonly repository;
|
|
29
|
+
private readonly contextProvider;
|
|
30
|
+
private readonly rootContext;
|
|
31
|
+
private readonly logger;
|
|
32
|
+
private readonly pendingSleeps;
|
|
33
|
+
constructor(repository: WorkflowCommandRepository, contextProvider: AgentContextProvider, rootContext: AgentContext, options?: PersistentCommandQueueOptions);
|
|
34
|
+
isReady(): Promise<boolean>;
|
|
35
|
+
enqueue(agentContext: AgentContext, job: WorkflowCommandJob): Promise<void>;
|
|
36
|
+
triggerPoll(): void;
|
|
37
|
+
startWorker(onJob: (job: WorkflowCommandJob) => Promise<void>): Promise<void>;
|
|
38
|
+
stop(): Promise<void>;
|
|
39
|
+
private pollLoop;
|
|
40
|
+
private poll;
|
|
41
|
+
private processCommand;
|
|
42
|
+
private staleCheckLoop;
|
|
43
|
+
private cleanupLoop;
|
|
44
|
+
private resolveContext;
|
|
45
|
+
private sleep;
|
|
46
|
+
getMetrics(): Promise<{
|
|
47
|
+
pending: number;
|
|
48
|
+
processing: number;
|
|
49
|
+
completed: number;
|
|
50
|
+
failed: number;
|
|
51
|
+
active: number;
|
|
52
|
+
}>;
|
|
53
|
+
}
|
|
54
|
+
//#endregion
|
|
55
|
+
export { PersistentCommandQueue, PersistentCommandQueueOptions };
|
|
56
|
+
//# sourceMappingURL=PersistentCommandQueue.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PersistentCommandQueue.d.mts","names":[],"sources":["../../src/queue/PersistentCommandQueue.ts"],"sourcesContent":[],"mappings":";;;;;UAOiB,6BAAA;;EAAA,WAAA,CAAA,EAAA,MAAA;EAWJ,mBAAA,CAAA,EAAA,MAAuB;EAqBpB,oBAAA,CAAA,EAAA,MAAA;EACK,iBAAA,CAAA,EAAA,MAAA;EACJ,kBAAA,CAAA,EAAA,MAAA;EACH,iBAAA,CAAA,EAAA,MAAA;EAiBY,WAAA,CAAA,EAAA,MAAA;;AAI8B,cA7C3C,sBAAA,YAAkC,YA6CS,CAAA;EAAqB,iBAAA,cAAA;EAgDrC,iBAAA,WAAA;EAAuB,iBAAA,mBAAA;EAAgB,iBAAA,oBAAA;EAgBxD,iBAAA,iBAAA;EA4QM,iBAAA,kBAAA;EAzXkB,iBAAA,iBAAA;EAAY,iBAAA,WAAA;;;;;;;;;0BAqB3C,4CACK,mCACJ,wBACH;aAiBY;wBAIW,mBAAmB,qBAAqB;;2BAgDrC,uBAAuB,gBAAgB;UAgBxD;;;;;;;;gBA4QM"}
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import { WorkflowCommandRecord } from "../repository/WorkflowCommandRecord.mjs";
|
|
2
|
+
import "../repository/WorkflowCommandRepository.mjs";
|
|
3
|
+
import { AgentConfig, InjectionSymbols } from "@credo-ts/core";
|
|
4
|
+
|
|
5
|
+
//#region src/queue/PersistentCommandQueue.ts
|
|
6
|
+
var PersistentCommandQueue = class {
|
|
7
|
+
constructor(repository, contextProvider, rootContext, options) {
|
|
8
|
+
this.running = false;
|
|
9
|
+
this.activeCount = 0;
|
|
10
|
+
this.pendingSleeps = /* @__PURE__ */ new Set();
|
|
11
|
+
this.repository = repository;
|
|
12
|
+
this.contextProvider = contextProvider;
|
|
13
|
+
this.rootContext = rootContext;
|
|
14
|
+
this.logger = rootContext.dependencyManager.resolve(AgentConfig).logger;
|
|
15
|
+
this.pollIntervalMs = options?.pollIntervalMs ?? 100;
|
|
16
|
+
this.concurrency = Math.max(1, options?.concurrency ?? 3);
|
|
17
|
+
this.processingTimeoutMs = options?.processingTimeoutMs ?? 3e4;
|
|
18
|
+
this.staleCheckIntervalMs = options?.staleCheckIntervalMs ?? 5e3;
|
|
19
|
+
this.cleanupIntervalMs = options?.cleanupIntervalMs ?? 6e4;
|
|
20
|
+
this.commandRetentionMs = options?.commandRetentionMs ?? 36e5;
|
|
21
|
+
this.failedRetentionMs = options?.failedRetentionMs ?? 864e5;
|
|
22
|
+
this.maxAttempts = options?.maxAttempts ?? 3;
|
|
23
|
+
}
|
|
24
|
+
async isReady() {
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
async enqueue(agentContext, job) {
|
|
28
|
+
try {
|
|
29
|
+
if ((await this.repository.findByQuery(this.rootContext, { thid: job.thid }))?.some?.((r) => r.cmd === job.cmd && (r.status === "pending" || r.status === "processing"))) {
|
|
30
|
+
this.logger.debug(`[PersistentQueue] Dedup enqueue: command already queued (${job.cmd}) for ${job.thid}`);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
} catch {}
|
|
34
|
+
const record = new WorkflowCommandRecord({
|
|
35
|
+
cmd: job.cmd,
|
|
36
|
+
thid: job.thid,
|
|
37
|
+
connectionId: job.connectionId,
|
|
38
|
+
idempotencyKey: job.idempotency_key,
|
|
39
|
+
payload: job.payload,
|
|
40
|
+
contextCorrelationId: job.contextCorrelationId,
|
|
41
|
+
status: "pending",
|
|
42
|
+
attempts: 0,
|
|
43
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
44
|
+
});
|
|
45
|
+
await this.repository.save(this.rootContext, record);
|
|
46
|
+
this.logger.debug(`[PersistentQueue] Enqueued command: ${job.cmd} for ${job.thid}`);
|
|
47
|
+
setImmediate(() => void this.poll());
|
|
48
|
+
}
|
|
49
|
+
triggerPoll() {
|
|
50
|
+
try {
|
|
51
|
+
setImmediate(() => void this.poll());
|
|
52
|
+
} catch {}
|
|
53
|
+
}
|
|
54
|
+
async startWorker(onJob) {
|
|
55
|
+
this.onJobHandler = onJob;
|
|
56
|
+
this.running = true;
|
|
57
|
+
this.logger.info("[PersistentQueue] Starting worker loops", {
|
|
58
|
+
pollIntervalMs: this.pollIntervalMs,
|
|
59
|
+
concurrency: this.concurrency,
|
|
60
|
+
processingTimeoutMs: this.processingTimeoutMs
|
|
61
|
+
});
|
|
62
|
+
this.pollLoop();
|
|
63
|
+
this.staleCheckLoop();
|
|
64
|
+
this.cleanupLoop();
|
|
65
|
+
}
|
|
66
|
+
async stop() {
|
|
67
|
+
this.logger.info("[PersistentQueue] Stopping worker...");
|
|
68
|
+
this.running = false;
|
|
69
|
+
for (const entry of Array.from(this.pendingSleeps)) {
|
|
70
|
+
try {
|
|
71
|
+
clearTimeout(entry.timer);
|
|
72
|
+
} catch {}
|
|
73
|
+
try {
|
|
74
|
+
entry.resolve();
|
|
75
|
+
} catch {}
|
|
76
|
+
this.pendingSleeps.delete(entry);
|
|
77
|
+
}
|
|
78
|
+
const maxWait = 1e4;
|
|
79
|
+
const start = Date.now();
|
|
80
|
+
while (this.activeCount > 0 && Date.now() - start < maxWait) await this.sleep(100);
|
|
81
|
+
if (this.activeCount > 0) this.logger.warn(`[PersistentQueue] Stopped with ${this.activeCount} active jobs`);
|
|
82
|
+
else this.logger.info("[PersistentQueue] Stopped cleanly");
|
|
83
|
+
}
|
|
84
|
+
async pollLoop() {
|
|
85
|
+
while (this.running) {
|
|
86
|
+
try {
|
|
87
|
+
await this.poll();
|
|
88
|
+
} catch (err) {
|
|
89
|
+
if (this.running && this.logger && typeof this.logger.error === "function") this.logger.error("[PersistentQueue] Poll error", { error: err.message });
|
|
90
|
+
}
|
|
91
|
+
await this.sleep(this.pollIntervalMs);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
async poll() {
|
|
95
|
+
if (this.activeCount >= this.concurrency) return;
|
|
96
|
+
if (!this.onJobHandler) return;
|
|
97
|
+
const limit = this.concurrency - this.activeCount;
|
|
98
|
+
const pending = await this.repository.findPending(this.rootContext, limit);
|
|
99
|
+
if (pending.length > 0) try {
|
|
100
|
+
this.logger.info("[PersistentQueue] Pending commands fetched", { count: pending.length });
|
|
101
|
+
} catch {}
|
|
102
|
+
for (const record of pending) {
|
|
103
|
+
if (record.attempts >= this.maxAttempts) {
|
|
104
|
+
await this.repository.markFailed(this.rootContext, record, `Max attempts (${this.maxAttempts}) exceeded`);
|
|
105
|
+
this.logger.warn(`[PersistentQueue] Command ${record.id} failed after ${this.maxAttempts} attempts`);
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
await this.repository.markProcessing(this.rootContext, record);
|
|
109
|
+
this.activeCount++;
|
|
110
|
+
this.processCommand(record);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
async processCommand(record) {
|
|
114
|
+
let scoped = null;
|
|
115
|
+
try {
|
|
116
|
+
scoped = await this.resolveContext(record.contextCorrelationId);
|
|
117
|
+
if (!scoped) throw new Error(`Unable to resolve context: ${record.contextCorrelationId}`);
|
|
118
|
+
const job = {
|
|
119
|
+
cmd: record.cmd,
|
|
120
|
+
thid: record.thid,
|
|
121
|
+
connectionId: record.connectionId,
|
|
122
|
+
idempotency_key: record.idempotencyKey,
|
|
123
|
+
payload: record.payload,
|
|
124
|
+
contextCorrelationId: record.contextCorrelationId
|
|
125
|
+
};
|
|
126
|
+
try {
|
|
127
|
+
this.logger.info("[PersistentQueue] Processing command", {
|
|
128
|
+
cmd: record.cmd,
|
|
129
|
+
thid: record.thid,
|
|
130
|
+
attempts: record.attempts
|
|
131
|
+
});
|
|
132
|
+
} catch {}
|
|
133
|
+
await this.onJobHandler(job);
|
|
134
|
+
await this.repository.markCompleted(this.rootContext, record);
|
|
135
|
+
try {
|
|
136
|
+
this.logger.info("[PersistentQueue] Completed command", {
|
|
137
|
+
cmd: record.cmd,
|
|
138
|
+
thid: record.thid
|
|
139
|
+
});
|
|
140
|
+
} catch {}
|
|
141
|
+
} catch (err) {
|
|
142
|
+
const errorMsg = err.message || "Unknown error";
|
|
143
|
+
const errCode = err?.code;
|
|
144
|
+
if (this.running && this.logger && typeof this.logger.error === "function") this.logger.error(`[PersistentQueue] Command processing failed: ${record.cmd} for ${record.thid}`, {
|
|
145
|
+
error: errorMsg,
|
|
146
|
+
attempts: record.attempts
|
|
147
|
+
});
|
|
148
|
+
if (errCode === "invalid_template") {
|
|
149
|
+
try {
|
|
150
|
+
await this.sleep(Math.min(1e3, this.pollIntervalMs * 10));
|
|
151
|
+
} catch {}
|
|
152
|
+
try {
|
|
153
|
+
if (record.attempts > 0) record.attempts -= 1;
|
|
154
|
+
} catch {}
|
|
155
|
+
await this.repository.resetToPending(this.rootContext, record);
|
|
156
|
+
try {
|
|
157
|
+
this.logger.info("[PersistentQueue] Deferred command due to missing template; reset to pending", {
|
|
158
|
+
cmd: record.cmd,
|
|
159
|
+
thid: record.thid
|
|
160
|
+
});
|
|
161
|
+
} catch {}
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
if (record.attempts >= this.maxAttempts) await this.repository.markFailed(this.rootContext, record, errorMsg);
|
|
165
|
+
else {
|
|
166
|
+
await this.repository.resetToPending(this.rootContext, record);
|
|
167
|
+
try {
|
|
168
|
+
this.logger.info("[PersistentQueue] Resetting command to pending for retry", {
|
|
169
|
+
cmd: record.cmd,
|
|
170
|
+
thid: record.thid,
|
|
171
|
+
attempts: record.attempts
|
|
172
|
+
});
|
|
173
|
+
} catch {}
|
|
174
|
+
}
|
|
175
|
+
} finally {
|
|
176
|
+
try {
|
|
177
|
+
await scoped?.release?.();
|
|
178
|
+
} catch {}
|
|
179
|
+
this.activeCount--;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
async staleCheckLoop() {
|
|
183
|
+
while (this.running) {
|
|
184
|
+
await this.sleep(this.staleCheckIntervalMs);
|
|
185
|
+
try {
|
|
186
|
+
const stale = await this.repository.findStale(this.rootContext, this.processingTimeoutMs);
|
|
187
|
+
for (const record of stale) {
|
|
188
|
+
this.logger.warn(`[PersistentQueue] Resetting stale command: ${record.cmd} for ${record.thid}`, {
|
|
189
|
+
attempts: record.attempts,
|
|
190
|
+
lastAttempt: record.lastAttemptAt?.toISOString()
|
|
191
|
+
});
|
|
192
|
+
if (record.attempts >= this.maxAttempts) await this.repository.markFailed(this.rootContext, record, "Stale after max attempts");
|
|
193
|
+
else await this.repository.resetToPending(this.rootContext, record);
|
|
194
|
+
}
|
|
195
|
+
} catch (err) {
|
|
196
|
+
if (this.running && this.logger && typeof this.logger.error === "function") this.logger.error("[PersistentQueue] Stale check error", { error: err.message });
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
async cleanupLoop() {
|
|
201
|
+
while (this.running) {
|
|
202
|
+
await this.sleep(this.cleanupIntervalMs);
|
|
203
|
+
try {
|
|
204
|
+
const completedCutoff = new Date(Date.now() - this.commandRetentionMs);
|
|
205
|
+
const failedCutoff = new Date(Date.now() - this.failedRetentionMs);
|
|
206
|
+
const [completedDeleted, failedDeleted] = await Promise.all([this.repository.deleteCompleted(this.rootContext, completedCutoff), this.repository.deleteFailed(this.rootContext, failedCutoff)]);
|
|
207
|
+
if (completedDeleted > 0 || failedDeleted > 0) this.logger.debug(`[PersistentQueue] Cleanup: deleted ${completedDeleted} completed, ${failedDeleted} failed`);
|
|
208
|
+
} catch (err) {
|
|
209
|
+
if (this.running && this.logger && typeof this.logger.error === "function") this.logger.error("[PersistentQueue] Cleanup error", { error: err.message });
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
async resolveContext(correlationId) {
|
|
214
|
+
const rootId = this.rootContext.contextCorrelationId;
|
|
215
|
+
if (!correlationId || correlationId === rootId) return {
|
|
216
|
+
context: this.rootContext,
|
|
217
|
+
release: async () => {}
|
|
218
|
+
};
|
|
219
|
+
try {
|
|
220
|
+
const scopedContext = await this.contextProvider.getAgentContextForContextCorrelationId(correlationId);
|
|
221
|
+
return {
|
|
222
|
+
context: scopedContext,
|
|
223
|
+
release: async () => {
|
|
224
|
+
try {
|
|
225
|
+
await this.contextProvider.endSessionForAgentContext(scopedContext);
|
|
226
|
+
} catch (error) {
|
|
227
|
+
this.logger.debug("[PersistentQueue] Failed to end tenant session", {
|
|
228
|
+
contextCorrelationId: correlationId,
|
|
229
|
+
error: error.message
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
} catch (error) {
|
|
235
|
+
if (this.running && this.logger && typeof this.logger.error === "function") this.logger.error("[PersistentQueue] Unable to resolve context, falling back to root", {
|
|
236
|
+
contextCorrelationId: correlationId,
|
|
237
|
+
error: error.message
|
|
238
|
+
});
|
|
239
|
+
return {
|
|
240
|
+
context: this.rootContext,
|
|
241
|
+
release: async () => {}
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
sleep(ms) {
|
|
246
|
+
return new Promise((outerResolve) => {
|
|
247
|
+
const entry = {
|
|
248
|
+
timer: void 0,
|
|
249
|
+
resolve: () => {}
|
|
250
|
+
};
|
|
251
|
+
const resolve = () => {
|
|
252
|
+
try {
|
|
253
|
+
outerResolve();
|
|
254
|
+
} finally {
|
|
255
|
+
this.pendingSleeps.delete(entry);
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
entry.resolve = resolve;
|
|
259
|
+
entry.timer = setTimeout(resolve, ms);
|
|
260
|
+
this.pendingSleeps.add(entry);
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
async getMetrics() {
|
|
264
|
+
return {
|
|
265
|
+
...await this.repository.getMetrics(this.rootContext),
|
|
266
|
+
active: this.activeCount
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
//#endregion
|
|
272
|
+
export { PersistentCommandQueue };
|
|
273
|
+
//# sourceMappingURL=PersistentCommandQueue.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PersistentCommandQueue.mjs","names":["scoped: { context: AgentContext; release: () => Promise<void> } | null","job: WorkflowCommandJob"],"sources":["../../src/queue/PersistentCommandQueue.ts"],"sourcesContent":["import type { AgentContext, AgentContextProvider } from '@credo-ts/core'\nimport type { CommandQueue, WorkflowCommandJob } from './CommandQueue'\n\nimport { AgentConfig, InjectionSymbols } from '@credo-ts/core'\nimport { WorkflowCommandRecord } from '../repository/WorkflowCommandRecord'\nimport { WorkflowCommandRepository } from '../repository/WorkflowCommandRepository'\n\nexport interface PersistentCommandQueueOptions {\n pollIntervalMs?: number\n concurrency?: number\n processingTimeoutMs?: number\n staleCheckIntervalMs?: number\n cleanupIntervalMs?: number\n commandRetentionMs?: number\n failedRetentionMs?: number\n maxAttempts?: number\n}\n\nexport class PersistentCommandQueue implements CommandQueue {\n private readonly pollIntervalMs: number\n private readonly concurrency: number\n private readonly processingTimeoutMs: number\n private readonly staleCheckIntervalMs: number\n private readonly cleanupIntervalMs: number\n private readonly commandRetentionMs: number\n private readonly failedRetentionMs: number\n private readonly maxAttempts: number\n\n private running = false\n private activeCount = 0\n private onJobHandler?: (job: WorkflowCommandJob) => Promise<void>\n\n private readonly repository: WorkflowCommandRepository\n private readonly contextProvider: AgentContextProvider\n private readonly rootContext: AgentContext\n private readonly logger: AgentConfig['logger']\n private readonly pendingSleeps = new Set<{ timer: NodeJS.Timeout; resolve: () => void }>()\n\n public constructor(\n repository: WorkflowCommandRepository,\n contextProvider: AgentContextProvider,\n rootContext: AgentContext,\n options?: PersistentCommandQueueOptions\n ) {\n this.repository = repository\n this.contextProvider = contextProvider\n this.rootContext = rootContext\n this.logger = rootContext.dependencyManager.resolve(AgentConfig).logger\n\n this.pollIntervalMs = options?.pollIntervalMs ?? 100\n this.concurrency = Math.max(1, options?.concurrency ?? 3)\n this.processingTimeoutMs = options?.processingTimeoutMs ?? 30000\n this.staleCheckIntervalMs = options?.staleCheckIntervalMs ?? 5000\n this.cleanupIntervalMs = options?.cleanupIntervalMs ?? 60000\n this.commandRetentionMs = options?.commandRetentionMs ?? 3600000 // 1 hour\n this.failedRetentionMs = options?.failedRetentionMs ?? 86400000 // 24 hours\n this.maxAttempts = options?.maxAttempts ?? 3\n }\n\n public async isReady(): Promise<boolean> {\n return true // Always ready (uses existing storage)\n }\n\n public async enqueue(agentContext: AgentContext, job: WorkflowCommandJob): Promise<void> {\n // Always persist commands in the root context so a single worker can process\n // commands across tenants and resolve the proper context per job.\n // Deduplicate by (cmd, thid) when a command is already pending/processing\n try {\n const existing = await this.repository.findByQuery(this.rootContext, { thid: job.thid })\n if (\n existing?.some?.(\n (r) => r.cmd === job.cmd && (r.status === 'pending' || r.status === 'processing')\n )\n ) {\n this.logger.debug(\n `[PersistentQueue] Dedup enqueue: command already queued (${job.cmd}) for ${job.thid}`\n )\n return\n }\n } catch {\n // swallow and proceed to enqueue\n }\n\n const record = new WorkflowCommandRecord({\n cmd: job.cmd,\n thid: job.thid,\n connectionId: job.connectionId,\n idempotencyKey: job.idempotency_key,\n payload: job.payload,\n contextCorrelationId: job.contextCorrelationId,\n status: 'pending',\n attempts: 0,\n createdAt: new Date(),\n })\n\n await this.repository.save(this.rootContext, record)\n this.logger.debug(`[PersistentQueue] Enqueued command: ${job.cmd} for ${job.thid}`)\n\n // Trigger immediate poll (non-blocking)\n setImmediate(() => void this.poll())\n }\n\n public triggerPoll(): void {\n // Non-blocking immediate poll hint\n try {\n setImmediate(() => void this.poll())\n } catch {\n // best-effort only\n }\n }\n\n public async startWorker(onJob: (job: WorkflowCommandJob) => Promise<void>): Promise<void> {\n this.onJobHandler = onJob\n this.running = true\n\n this.logger.info('[PersistentQueue] Starting worker loops', {\n pollIntervalMs: this.pollIntervalMs,\n concurrency: this.concurrency,\n processingTimeoutMs: this.processingTimeoutMs,\n })\n\n // Start background loops (non-blocking)\n void this.pollLoop()\n void this.staleCheckLoop()\n void this.cleanupLoop()\n }\n\n public async stop(): Promise<void> {\n this.logger.info('[PersistentQueue] Stopping worker...')\n this.running = false\n\n // Cancel any pending sleep timers and resolve sleepers\n for (const entry of Array.from(this.pendingSleeps)) {\n try {\n clearTimeout(entry.timer)\n } catch {}\n try {\n entry.resolve()\n } catch {}\n this.pendingSleeps.delete(entry)\n }\n\n // Wait for active jobs to complete (with timeout)\n const maxWait = 10000\n const start = Date.now()\n while (this.activeCount > 0 && Date.now() - start < maxWait) {\n await this.sleep(100)\n }\n\n if (this.activeCount > 0) {\n this.logger.warn(`[PersistentQueue] Stopped with ${this.activeCount} active jobs`)\n } else {\n this.logger.info('[PersistentQueue] Stopped cleanly')\n }\n }\n\n private async pollLoop(): Promise<void> {\n while (this.running) {\n try {\n await this.poll()\n } catch (err) {\n if (this.running && this.logger && typeof this.logger.error === 'function') {\n this.logger.error('[PersistentQueue] Poll error', { error: (err as Error).message })\n }\n }\n await this.sleep(this.pollIntervalMs)\n }\n }\n\n private async poll(): Promise<void> {\n if (this.activeCount >= this.concurrency) return\n if (!this.onJobHandler) return\n\n const limit = this.concurrency - this.activeCount\n const pending = await this.repository.findPending(this.rootContext, limit)\n if (pending.length > 0) {\n try {\n this.logger.info('[PersistentQueue] Pending commands fetched', {\n count: pending.length,\n })\n } catch {}\n }\n\n for (const record of pending) {\n // Check max attempts before processing\n if (record.attempts >= this.maxAttempts) {\n await this.repository.markFailed(\n this.rootContext,\n record,\n `Max attempts (${this.maxAttempts}) exceeded`\n )\n this.logger.warn(`[PersistentQueue] Command ${record.id} failed after ${this.maxAttempts} attempts`)\n continue\n }\n\n // Mark as processing\n await this.repository.markProcessing(this.rootContext, record)\n this.activeCount++\n\n // Process in background\n void this.processCommand(record)\n }\n }\n\n private async processCommand(record: WorkflowCommandRecord): Promise<void> {\n let scoped: { context: AgentContext; release: () => Promise<void> } | null = null\n try {\n // Resolve tenant context\n scoped = await this.resolveContext(record.contextCorrelationId)\n\n if (!scoped) {\n throw new Error(`Unable to resolve context: ${record.contextCorrelationId}`)\n }\n\n const job: WorkflowCommandJob = {\n cmd: record.cmd,\n thid: record.thid,\n connectionId: record.connectionId,\n idempotency_key: record.idempotencyKey,\n payload: record.payload,\n contextCorrelationId: record.contextCorrelationId,\n }\n\n try {\n this.logger.info('[PersistentQueue] Processing command', {\n cmd: record.cmd,\n thid: record.thid,\n attempts: record.attempts,\n })\n } catch {}\n await this.onJobHandler!(job)\n\n // Mark as completed in root context (commands are stored centrally)\n await this.repository.markCompleted(this.rootContext, record)\n try {\n this.logger.info('[PersistentQueue] Completed command', {\n cmd: record.cmd,\n thid: record.thid,\n })\n } catch {}\n } catch (err) {\n const errorMsg = (err as Error).message || 'Unknown error'\n const errCode = (err as unknown as { code?: string })?.code\n if (this.running && this.logger && typeof this.logger.error === 'function') {\n this.logger.error(`[PersistentQueue] Command processing failed: ${record.cmd} for ${record.thid}`, {\n error: errorMsg,\n attempts: record.attempts,\n })\n }\n // Special deferral for missing template: keep retrying without exhausting attempts\n if (errCode === 'invalid_template') {\n try {\n // Small backoff to avoid tight retry loop\n await this.sleep(Math.min(1000, this.pollIntervalMs * 10))\n } catch {}\n try {\n // Undo the attempt increment performed when marking processing\n if (record.attempts > 0) record.attempts -= 1\n } catch {}\n await this.repository.resetToPending(this.rootContext, record)\n try {\n this.logger.info('[PersistentQueue] Deferred command due to missing template; reset to pending', {\n cmd: record.cmd,\n thid: record.thid,\n })\n } catch {}\n return\n }\n\n // Mark as failed if max attempts reached, otherwise reset to pending for retry\n if (record.attempts >= this.maxAttempts) {\n await this.repository.markFailed(this.rootContext, record, errorMsg)\n } else {\n await this.repository.resetToPending(this.rootContext, record)\n try {\n this.logger.info('[PersistentQueue] Resetting command to pending for retry', {\n cmd: record.cmd,\n thid: record.thid,\n attempts: record.attempts,\n })\n } catch {}\n }\n } finally {\n // Always release scoped context if obtained\n try {\n await scoped?.release?.()\n } catch {}\n this.activeCount--\n }\n }\n\n private async staleCheckLoop(): Promise<void> {\n while (this.running) {\n await this.sleep(this.staleCheckIntervalMs)\n try {\n const stale = await this.repository.findStale(this.rootContext, this.processingTimeoutMs)\n\n for (const record of stale) {\n this.logger.warn(`[PersistentQueue] Resetting stale command: ${record.cmd} for ${record.thid}`, {\n attempts: record.attempts,\n lastAttempt: record.lastAttemptAt?.toISOString(),\n })\n\n if (record.attempts >= this.maxAttempts) {\n await this.repository.markFailed(this.rootContext, record, 'Stale after max attempts')\n } else {\n await this.repository.resetToPending(this.rootContext, record)\n }\n }\n } catch (err) {\n if (this.running && this.logger && typeof this.logger.error === 'function') {\n this.logger.error('[PersistentQueue] Stale check error', { error: (err as Error).message })\n }\n }\n }\n }\n\n private async cleanupLoop(): Promise<void> {\n while (this.running) {\n await this.sleep(this.cleanupIntervalMs)\n try {\n const completedCutoff = new Date(Date.now() - this.commandRetentionMs)\n const failedCutoff = new Date(Date.now() - this.failedRetentionMs)\n\n const [completedDeleted, failedDeleted] = await Promise.all([\n this.repository.deleteCompleted(this.rootContext, completedCutoff),\n this.repository.deleteFailed(this.rootContext, failedCutoff),\n ])\n\n if (completedDeleted > 0 || failedDeleted > 0) {\n this.logger.debug(`[PersistentQueue] Cleanup: deleted ${completedDeleted} completed, ${failedDeleted} failed`)\n }\n } catch (err) {\n if (this.running && this.logger && typeof this.logger.error === 'function') {\n this.logger.error('[PersistentQueue] Cleanup error', { error: (err as Error).message })\n }\n }\n }\n }\n\n private async resolveContext(\n correlationId: string\n ): Promise<{ context: AgentContext; release: () => Promise<void> } | null> {\n const rootId = this.rootContext.contextCorrelationId\n\n if (!correlationId || correlationId === rootId) {\n return { context: this.rootContext, release: async () => {} }\n }\n\n try {\n // Some inbound paths may enqueue with base context id (e.g., 'default').\n // If we can resolve it, do so; otherwise, fall back to root tenant context so\n // jobs in this queue are still processed under the tenant.\n const scopedContext = await this.contextProvider.getAgentContextForContextCorrelationId(correlationId)\n return {\n context: scopedContext,\n release: async () => {\n try {\n await this.contextProvider.endSessionForAgentContext(scopedContext)\n } catch (error) {\n this.logger.debug('[PersistentQueue] Failed to end tenant session', {\n contextCorrelationId: correlationId,\n error: (error as Error).message,\n })\n }\n },\n }\n } catch (error) {\n if (this.running && this.logger && typeof this.logger.error === 'function') {\n this.logger.error('[PersistentQueue] Unable to resolve context, falling back to root', {\n contextCorrelationId: correlationId,\n error: (error as Error).message,\n })\n }\n // Fallback: use the root agent context bound to this queue\n return { context: this.rootContext, release: async () => {} }\n }\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((outerResolve) => {\n const entry = { timer: undefined as unknown as NodeJS.Timeout, resolve: () => {} }\n const resolve = () => {\n try {\n outerResolve()\n } finally {\n this.pendingSleeps.delete(entry)\n }\n }\n entry.resolve = resolve\n entry.timer = setTimeout(resolve, ms)\n this.pendingSleeps.add(entry)\n })\n }\n\n public async getMetrics(): Promise<{\n pending: number\n processing: number\n completed: number\n failed: number\n active: number\n }> {\n const repoMetrics = await this.repository.getMetrics(this.rootContext)\n return {\n ...repoMetrics,\n active: this.activeCount,\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { BaseRecord, TagsBase } from "@credo-ts/core";
|
|
2
|
+
|
|
3
|
+
//#region src/repository/WorkflowCommandRecord.d.ts
|
|
4
|
+
type WorkflowCommandType = 'start' | 'advance' | 'pause' | 'resume' | 'cancel' | 'complete';
|
|
5
|
+
type WorkflowCommandStatus = 'pending' | 'processing' | 'completed' | 'failed';
|
|
6
|
+
interface WorkflowCommandRecordProps {
|
|
7
|
+
id?: string;
|
|
8
|
+
cmd: WorkflowCommandType;
|
|
9
|
+
thid: string;
|
|
10
|
+
connectionId?: string;
|
|
11
|
+
idempotencyKey?: string;
|
|
12
|
+
payload: Record<string, unknown>;
|
|
13
|
+
contextCorrelationId: string;
|
|
14
|
+
status?: WorkflowCommandStatus;
|
|
15
|
+
attempts?: number;
|
|
16
|
+
lastAttemptAt?: Date;
|
|
17
|
+
error?: string;
|
|
18
|
+
createdAt?: Date;
|
|
19
|
+
completedAt?: Date;
|
|
20
|
+
}
|
|
21
|
+
type WorkflowCommandRecordTags = TagsBase & {
|
|
22
|
+
status: WorkflowCommandStatus;
|
|
23
|
+
thid: string;
|
|
24
|
+
connectionId: string;
|
|
25
|
+
contextCorrelationId: string;
|
|
26
|
+
cmd: WorkflowCommandType;
|
|
27
|
+
templateId?: string;
|
|
28
|
+
templateVersion?: string;
|
|
29
|
+
};
|
|
30
|
+
declare class WorkflowCommandRecord extends BaseRecord<WorkflowCommandRecordTags, TagsBase> {
|
|
31
|
+
static readonly type: "WorkflowCommandRecord";
|
|
32
|
+
readonly type: "WorkflowCommandRecord";
|
|
33
|
+
cmd: WorkflowCommandType;
|
|
34
|
+
thid: string;
|
|
35
|
+
connectionId?: string;
|
|
36
|
+
idempotencyKey?: string;
|
|
37
|
+
payload: Record<string, unknown>;
|
|
38
|
+
contextCorrelationId: string;
|
|
39
|
+
status: WorkflowCommandStatus;
|
|
40
|
+
attempts: number;
|
|
41
|
+
lastAttemptAt?: Date;
|
|
42
|
+
error?: string;
|
|
43
|
+
createdAt: Date;
|
|
44
|
+
completedAt?: Date;
|
|
45
|
+
constructor(props: WorkflowCommandRecordProps);
|
|
46
|
+
getTags(): WorkflowCommandRecordTags;
|
|
47
|
+
}
|
|
48
|
+
//#endregion
|
|
49
|
+
export { WorkflowCommandRecord, WorkflowCommandRecordProps, WorkflowCommandRecordTags, WorkflowCommandStatus, WorkflowCommandType };
|
|
50
|
+
//# sourceMappingURL=WorkflowCommandRecord.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkflowCommandRecord.d.mts","names":[],"sources":["../../src/repository/WorkflowCommandRecord.ts"],"sourcesContent":[],"mappings":";;;KAIY,mBAAA;AAAA,KACA,qBAAA,GADmB,SAAA,GAAA,YAAA,GAAA,WAAA,GAAA,QAAA;AACnB,UAEK,0BAAA,CAFgB;EAEhB,EAAA,CAAA,EAAA,MAAA;EAEV,GAAA,EAAA,mBAAA;EAII,IAAA,EAAA,MAAA;EAGA,YAAA,CAAA,EAAA,MAAA;EAEO,cAAA,CAAA,EAAA,MAAA;EAGJ,OAAA,EARH,MAQG,CAAA,MAAA,EAAA,OAAA,CAAA;EACE,oBAAA,EAAA,MAAA;EAAI,MAAA,CAAA,EANT,qBAMS;EAGR,QAAA,CAAA,EAAA,MAAA;EAA4B,aAAA,CAAA,EAPtB,IAOsB;EAC9B,KAAA,CAAA,EAAA,MAAA;EAIH,SAAA,CAAA,EATO,IASP;EAAmB,WAAA,CAAA,EARV,IAQU;AAM1B;AAAsD,KAX1C,yBAAA,GAA4B,QAWc,GAAA;EAA2B,MAAA,EAVvE,qBAUuE;EAIlE,IAAA,EAAA,MAAA;EAII,YAAA,EAAA,MAAA;EAGD,oBAAA,EAAA,MAAA;EAEO,GAAA,EAnBlB,mBAmBkB;EAGJ,UAAA,CAAA,EAAA,MAAA;EACE,eAAA,CAAA,EAAA,MAAA;CAEK;AAsBR,cAzCP,qBAAA,SAA8B,UAyCvB,CAzCkC,yBAyClC,EAzC6D,QAyC7D,CAAA,CAAA;EAzCuB,gBAAA,IAAA,EAAA,uBAAA;EAAU,SAAA,IAAA,EAAA,uBAAA;OAItC;;;;WAII;;UAGD;;kBAEO;;aAGJ;gBACE;qBAEK;aAsBR"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { BaseRecord, utils } from "@credo-ts/core";
|
|
2
|
+
|
|
3
|
+
//#region src/repository/WorkflowCommandRecord.ts
|
|
4
|
+
var WorkflowCommandRecord = class WorkflowCommandRecord extends BaseRecord {
|
|
5
|
+
constructor(props) {
|
|
6
|
+
super();
|
|
7
|
+
this.type = WorkflowCommandRecord.type;
|
|
8
|
+
if (props) {
|
|
9
|
+
this.id = props.id ?? utils.uuid();
|
|
10
|
+
this.cmd = props.cmd;
|
|
11
|
+
this.thid = props.thid;
|
|
12
|
+
this.connectionId = props.connectionId;
|
|
13
|
+
this.idempotencyKey = props.idempotencyKey;
|
|
14
|
+
this.payload = props.payload;
|
|
15
|
+
this.contextCorrelationId = props.contextCorrelationId;
|
|
16
|
+
this.status = props.status ?? "pending";
|
|
17
|
+
this.attempts = props.attempts ?? 0;
|
|
18
|
+
this.lastAttemptAt = props.lastAttemptAt;
|
|
19
|
+
this.error = props.error;
|
|
20
|
+
this.createdAt = props.createdAt ?? /* @__PURE__ */ new Date();
|
|
21
|
+
this.completedAt = props.completedAt;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
getTags() {
|
|
25
|
+
const base = {
|
|
26
|
+
...this._tags,
|
|
27
|
+
status: this.status,
|
|
28
|
+
thid: this.thid,
|
|
29
|
+
connectionId: this.connectionId ?? "",
|
|
30
|
+
contextCorrelationId: this.contextCorrelationId,
|
|
31
|
+
cmd: this.cmd
|
|
32
|
+
};
|
|
33
|
+
try {
|
|
34
|
+
if (this.cmd === "start") {
|
|
35
|
+
const tId = this.payload?.template_id;
|
|
36
|
+
const tVer = this.payload?.template_version;
|
|
37
|
+
if (tId) base.templateId = tId;
|
|
38
|
+
if (tVer) base.templateVersion = tVer;
|
|
39
|
+
}
|
|
40
|
+
} catch {}
|
|
41
|
+
return base;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
WorkflowCommandRecord.type = "WorkflowCommandRecord";
|
|
45
|
+
|
|
46
|
+
//#endregion
|
|
47
|
+
export { WorkflowCommandRecord };
|
|
48
|
+
//# sourceMappingURL=WorkflowCommandRecord.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkflowCommandRecord.mjs","names":["base: WorkflowCommandRecordTags"],"sources":["../../src/repository/WorkflowCommandRecord.ts"],"sourcesContent":["import type { TagsBase } from '@credo-ts/core'\n\nimport { BaseRecord, utils } from '@credo-ts/core'\n\nexport type WorkflowCommandType = 'start' | 'advance' | 'pause' | 'resume' | 'cancel' | 'complete'\nexport type WorkflowCommandStatus = 'pending' | 'processing' | 'completed' | 'failed'\n\nexport interface WorkflowCommandRecordProps {\n id?: string\n cmd: WorkflowCommandType\n thid: string\n connectionId?: string\n idempotencyKey?: string\n payload: Record<string, unknown>\n contextCorrelationId: string\n\n status?: WorkflowCommandStatus\n attempts?: number\n lastAttemptAt?: Date\n error?: string\n\n createdAt?: Date\n completedAt?: Date\n}\n\nexport type WorkflowCommandRecordTags = TagsBase & {\n status: WorkflowCommandStatus\n thid: string\n connectionId: string\n contextCorrelationId: string\n cmd: WorkflowCommandType\n // Optional filtering tags (populated for 'start' commands)\n templateId?: string\n templateVersion?: string\n}\n\nexport class WorkflowCommandRecord extends BaseRecord<WorkflowCommandRecordTags, TagsBase> {\n public static readonly type = 'WorkflowCommandRecord' as const\n public readonly type = WorkflowCommandRecord.type\n\n public cmd!: WorkflowCommandType\n public thid!: string\n public connectionId?: string\n public idempotencyKey?: string\n public payload!: Record<string, unknown>\n public contextCorrelationId!: string\n\n public status!: WorkflowCommandStatus\n public attempts!: number\n public lastAttemptAt?: Date\n public error?: string\n\n public createdAt!: Date\n public completedAt?: Date\n\n public constructor(props: WorkflowCommandRecordProps) {\n super()\n\n if (props) {\n this.id = props.id ?? utils.uuid()\n this.cmd = props.cmd\n this.thid = props.thid\n this.connectionId = props.connectionId\n this.idempotencyKey = props.idempotencyKey\n this.payload = props.payload\n this.contextCorrelationId = props.contextCorrelationId\n\n this.status = props.status ?? 'pending'\n this.attempts = props.attempts ?? 0\n this.lastAttemptAt = props.lastAttemptAt\n this.error = props.error\n\n this.createdAt = props.createdAt ?? new Date()\n this.completedAt = props.completedAt\n }\n }\n\n public getTags(): WorkflowCommandRecordTags {\n const base: WorkflowCommandRecordTags = {\n ...this._tags,\n status: this.status,\n thid: this.thid,\n connectionId: this.connectionId ?? '',\n contextCorrelationId: this.contextCorrelationId,\n cmd: this.cmd,\n }\n try {\n if (this.cmd === 'start') {\n const tId = (this.payload as { template_id?: string })?.template_id\n const tVer = (this.payload as { template_version?: string })?.template_version\n if (tId) (base as unknown as { templateId?: string }).templateId = tId\n if (tVer) (base as unknown as { templateVersion?: string }).templateVersion = tVer\n }\n } catch {\n /* noop */\n }\n return base\n }\n}\n"],"mappings":";;;AAoCA,IAAa,wBAAb,MAAa,8BAA8B,WAAgD;CAmBzF,AAAO,YAAY,OAAmC;AACpD,SAAO;OAlBO,OAAO,sBAAsB;AAoB3C,MAAI,OAAO;AACT,QAAK,KAAK,MAAM,MAAM,MAAM,MAAM;AAClC,QAAK,MAAM,MAAM;AACjB,QAAK,OAAO,MAAM;AAClB,QAAK,eAAe,MAAM;AAC1B,QAAK,iBAAiB,MAAM;AAC5B,QAAK,UAAU,MAAM;AACrB,QAAK,uBAAuB,MAAM;AAElC,QAAK,SAAS,MAAM,UAAU;AAC9B,QAAK,WAAW,MAAM,YAAY;AAClC,QAAK,gBAAgB,MAAM;AAC3B,QAAK,QAAQ,MAAM;AAEnB,QAAK,YAAY,MAAM,6BAAa,IAAI,MAAM;AAC9C,QAAK,cAAc,MAAM;;;CAI7B,AAAO,UAAqC;EAC1C,MAAMA,OAAkC;GACtC,GAAG,KAAK;GACR,QAAQ,KAAK;GACb,MAAM,KAAK;GACX,cAAc,KAAK,gBAAgB;GACnC,sBAAsB,KAAK;GAC3B,KAAK,KAAK;GACX;AACD,MAAI;AACF,OAAI,KAAK,QAAQ,SAAS;IACxB,MAAM,MAAO,KAAK,SAAsC;IACxD,MAAM,OAAQ,KAAK,SAA2C;AAC9D,QAAI,IAAK,CAAC,KAA4C,aAAa;AACnE,QAAI,KAAM,CAAC,KAAiD,kBAAkB;;UAE1E;AAGR,SAAO;;;sBA3Dc,OAAO"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { WorkflowCommandRecord } from "./WorkflowCommandRecord.mjs";
|
|
2
|
+
import { AgentContext, EventEmitter, Repository, StorageService } from "@credo-ts/core";
|
|
3
|
+
|
|
4
|
+
//#region src/repository/WorkflowCommandRepository.d.ts
|
|
5
|
+
declare class WorkflowCommandRepository extends Repository<WorkflowCommandRecord> {
|
|
6
|
+
constructor(storageService: StorageService<WorkflowCommandRecord>, eventEmitter: EventEmitter);
|
|
7
|
+
/**
|
|
8
|
+
* Find pending commands (status='pending'), ordered by creation time
|
|
9
|
+
*/
|
|
10
|
+
findPending(agentContext: AgentContext, limit?: number): Promise<WorkflowCommandRecord[]>;
|
|
11
|
+
/**
|
|
12
|
+
* Find pending 'start' commands for a specific template (and optional version)
|
|
13
|
+
*/
|
|
14
|
+
findPendingStartsByTemplate(agentContext: AgentContext, templateId: string, version?: string): Promise<WorkflowCommandRecord[]>;
|
|
15
|
+
/**
|
|
16
|
+
* Find commands stuck in 'processing' state longer than timeoutMs
|
|
17
|
+
*/
|
|
18
|
+
findStale(agentContext: AgentContext, timeoutMs: number): Promise<WorkflowCommandRecord[]>;
|
|
19
|
+
/**
|
|
20
|
+
* Find command by thid (thread ID / instance ID)
|
|
21
|
+
*/
|
|
22
|
+
findByThid(agentContext: AgentContext, thid: string): Promise<WorkflowCommandRecord[]>;
|
|
23
|
+
/**
|
|
24
|
+
* Mark command as processing
|
|
25
|
+
*/
|
|
26
|
+
markProcessing(agentContext: AgentContext, record: WorkflowCommandRecord): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Mark command as completed
|
|
29
|
+
*/
|
|
30
|
+
markCompleted(agentContext: AgentContext, record: WorkflowCommandRecord): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Mark command as failed
|
|
33
|
+
*/
|
|
34
|
+
markFailed(agentContext: AgentContext, record: WorkflowCommandRecord, error: string): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* Delete completed commands older than given date
|
|
37
|
+
*/
|
|
38
|
+
deleteCompleted(agentContext: AgentContext, olderThan: Date): Promise<number>;
|
|
39
|
+
/**
|
|
40
|
+
* Delete failed commands older than given date
|
|
41
|
+
*/
|
|
42
|
+
deleteFailed(agentContext: AgentContext, olderThan: Date): Promise<number>;
|
|
43
|
+
/**
|
|
44
|
+
* Reset stale command to pending for retry
|
|
45
|
+
*/
|
|
46
|
+
resetToPending(agentContext: AgentContext, record: WorkflowCommandRecord): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Get queue metrics
|
|
49
|
+
*/
|
|
50
|
+
getMetrics(agentContext: AgentContext): Promise<{
|
|
51
|
+
pending: number;
|
|
52
|
+
processing: number;
|
|
53
|
+
completed: number;
|
|
54
|
+
failed: number;
|
|
55
|
+
}>;
|
|
56
|
+
}
|
|
57
|
+
//#endregion
|
|
58
|
+
export { WorkflowCommandRepository };
|
|
59
|
+
//# sourceMappingURL=WorkflowCommandRepository.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkflowCommandRepository.d.mts","names":[],"sources":["../../src/repository/WorkflowCommandRepository.ts"],"sourcesContent":[],"mappings":";;;;cAOa,yBAAA,SAAkC,WAAW;EAA7C,WAAA,CAAA,cAAA,EAEgD,cAFtB,CAEqC,qBAFrC,CAAA,EAAA,YAAA,EAGrB,YAHqB;EAAmB;;;EAGxC,WAAA,CAAA,YAAA,EAQuB,YARvB,EAAA,KAAA,CAAA,EAAA,MAAA,CAAA,EAQkD,OARlD,CAQ0D,qBAR1D,EAAA,CAAA;EAQuB;;;EAWvB,2BAAA,CAAA,YAAA,EAAA,YAAA,EAAA,UAAA,EAAA,MAAA,EAAA,OAAA,CAAA,EAAA,MAAA,CAAA,EAGb,OAHa,CAGL,qBAHK,EAAA,CAAA;EAGL;;;EAeoE,SAAA,CAAA,YAAA,EAA1C,YAA0C,EAAA,SAAA,EAAA,MAAA,CAAA,EAAR,OAAQ,CAAA,qBAAA,EAAA,CAAA;EAAR;;;EAaJ,UAAA,CAAA,YAAA,EAA7B,YAA6B,EAAA,IAAA,EAAA,MAAA,CAAA,EAAA,OAAA,CAAQ,qBAAR,EAAA,CAAA;EAOzB;;;EAUD,cAAA,CAAA,YAAA,EAVC,YAUD,EAAA,MAAA,EAVuB,qBAUvB,CAAA,EAV+C,OAU/C,CAAA,IAAA,CAAA;EAAsB;;;EAWrD,aAAA,CAAA,YAAA,EAX+B,YAW/B,EAAA,MAAA,EAXqD,qBAWrD,CAAA,EAX6E,OAW7E,CAAA,IAAA,CAAA;EAEP;;;EAUwE,UAAA,CAAA,YAAA,EAb3D,YAa2D,EAAA,MAAA,EAZjE,qBAYiE,EAAA,KAAA,EAAA,MAAA,CAAA,EAVxE,OAUwE,CAAA,IAAA,CAAA;EAiBnC;;;EAiBE,eAAA,CAAA,YAAA,EAlCC,YAkCD,EAAA,SAAA,EAlC0B,IAkC1B,CAAA,EAlCiC,OAkCjC,CAAA,MAAA,CAAA;EAAsB;;;EASX,YAAA,CAAA,YAAA,EA1Bb,YA0Ba,EAAA,SAAA,EA1BY,IA0BZ,CAAA,EA1BmB,OA0BnB,CAAA,MAAA,CAAA;EAxIR;;;+BA+HH,sBAAsB,wBAAwB;;;;2BASlD,eAAe"}
|