@bratsos/workflow-engine 0.3.0 → 0.4.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.
Files changed (36) hide show
  1. package/dist/{chunk-WZ533CPU.js → chunk-3NEGRI4M.js} +177 -72
  2. package/dist/chunk-3NEGRI4M.js.map +1 -0
  3. package/dist/{chunk-NYKMT46J.js → chunk-PHLNTR5Z.js} +19 -3
  4. package/dist/chunk-PHLNTR5Z.js.map +1 -0
  5. package/dist/{chunk-SPXBCZLB.js → chunk-RZY5YRGL.js} +2 -2
  6. package/dist/{chunk-SPXBCZLB.js.map → chunk-RZY5YRGL.js.map} +1 -1
  7. package/dist/{chunk-QBYB2PJJ.js → chunk-XS3ZX4KW.js} +12 -4
  8. package/dist/chunk-XS3ZX4KW.js.map +1 -0
  9. package/dist/{client-D4PoxADF.d.ts → client-DSrhYb7Q.d.ts} +20 -3
  10. package/dist/client.d.ts +3 -2
  11. package/dist/client.js +1 -1
  12. package/dist/{index-DAzCfO1R.d.ts → index-CVkkGnxx.d.ts} +2 -1
  13. package/dist/index.d.ts +7 -6
  14. package/dist/index.js +5 -5
  15. package/dist/{interface-MMqhfQQK.d.ts → interface-TsryH4d7.d.ts} +1 -0
  16. package/dist/kernel/index.d.ts +4 -4
  17. package/dist/kernel/index.js +1 -1
  18. package/dist/kernel/testing/index.d.ts +2 -2
  19. package/dist/persistence/index.d.ts +2 -2
  20. package/dist/persistence/index.js +2 -2
  21. package/dist/persistence/prisma/index.d.ts +2 -2
  22. package/dist/persistence/prisma/index.js +2 -2
  23. package/dist/{plugins-CPC-X0rR.d.ts → plugins-DW266bhT.d.ts} +13 -3
  24. package/dist/{ports-tU3rzPXJ.d.ts → ports-855bktyD.d.ts} +2 -1
  25. package/dist/testing/index.d.ts +2 -1
  26. package/dist/testing/index.js +19 -1
  27. package/dist/testing/index.js.map +1 -1
  28. package/package.json +2 -1
  29. package/skills/workflow-engine/SKILL.md +13 -3
  30. package/skills/workflow-engine/references/03-runtime-setup.md +3 -1
  31. package/skills/workflow-engine/references/04-ai-integration.md +34 -1
  32. package/skills/workflow-engine/references/08-common-patterns.md +29 -0
  33. package/skills/workflow-engine/references/09-troubleshooting.md +93 -0
  34. package/dist/chunk-NYKMT46J.js.map +0 -1
  35. package/dist/chunk-QBYB2PJJ.js.map +0 -1
  36. package/dist/chunk-WZ533CPU.js.map +0 -1
package/dist/index.d.ts CHANGED
@@ -1,13 +1,14 @@
1
- import { M as ModelKey } from './client-D4PoxADF.js';
2
- export { A as AIBatch, a as AIBatchHandle, b as AIBatchProvider, c as AIBatchRequest, d as AIBatchResult, e as AICallType, f as AIEmbedResult, g as AIHelper, h as AIObjectResult, i as AIStreamResult, j as AITextResult, k as AVAILABLE_MODELS, l as AsyncBatchStageDefinition, B as BatchLogFn, D as DEFAULT_MODEL_KEY, E as EmbedOptions, m as EnhancedStageContext, I as InferInput, L as LogContext, n as ModelConfig, o as ModelRegistry, p as ModelStats, q as ModelStatsTracker, r as ModelSyncConfig, N as NoInputSchema, O as ObjectOptions, R as RecordCallParams, S as SimpleStageResult, s as StreamOptions, t as SyncStageDefinition, T as TextOptions, W as WorkflowEventType, u as WorkflowSSEEvent, v as calculateCost, w as createAIHelper, x as defineAsyncBatchStage, y as defineStage, z as getDefaultModel, C as getModel, F as getModelById, G as getRegisteredModel, H as listModels, J as listRegisteredModels, K as modelSupportsBatch, P as printAvailableModels, Q as registerModels, U as requireStageOutput } from './client-D4PoxADF.js';
1
+ import { M as ModelKey } from './client-DSrhYb7Q.js';
2
+ export { A as AIBatch, a as AIBatchHandle, b as AIBatchProvider, c as AIBatchRequest, d as AIBatchResult, e as AICallType, f as AIEmbedResult, g as AIHelper, h as AIObjectResult, i as AIStreamResult, j as AITextResult, k as AVAILABLE_MODELS, l as AsyncBatchStageDefinition, B as BatchLogFn, D as DEFAULT_MODEL_KEY, E as EmbedOptions, m as EnhancedStageContext, I as InferInput, L as LogContext, n as ModelConfig, o as ModelRegistry, p as ModelStats, q as ModelStatsTracker, r as ModelSyncConfig, N as NoInputSchema, O as ObjectOptions, R as RecordCallParams, S as SimpleStageResult, s as StreamOptions, t as SyncStageDefinition, T as TextOptions, W as WorkflowEventType, u as WorkflowSSEEvent, v as calculateCost, w as createAIHelper, x as defineAsyncBatchStage, y as defineStage, z as getDefaultModel, C as getModel, F as getModelById, G as getRegisteredModel, H as listModels, J as listRegisteredModels, K as modelSupportsBatch, P as printAvailableModels, Q as registerEmbeddingProvider, U as registerModels, V as requireStageOutput } from './client-DSrhYb7Q.js';
3
3
  import { L as LogLevel } from './stage-BPw7m9Wx.js';
4
4
  export { S as Stage, a as StageResult } from './stage-BPw7m9Wx.js';
5
- export { C as CommandResult, I as IdempotencyInProgressError, y as InferWorkflowStageIds, J as JobExecuteCommand, a as JobExecuteResult, b as Kernel, c as KernelCommand, d as KernelCommandType, e as KernelConfig, W as KernelWorkflowRegistry, L as LeaseReapStaleCommand, f as LeaseReapStaleResult, O as OutboxFlushCommand, g as OutboxFlushResult, P as PluginDefinition, h as PluginReplayDLQCommand, i as PluginReplayDLQResult, j as PluginRunner, k as PluginRunnerConfig, R as RunCancelCommand, l as RunCancelResult, m as RunClaimPendingCommand, n as RunClaimPendingResult, o as RunCreateCommand, p as RunCreateResult, q as RunRerunFromCommand, r as RunRerunFromResult, s as RunTransitionCommand, t as RunTransitionResult, S as StagePollSuspendedCommand, u as StagePollSuspendedResult, z as Workflow, A as WorkflowBuilder, v as createKernel, w as createPluginRunner, x as definePlugin } from './plugins-CPC-X0rR.js';
5
+ export { C as CommandResult, I as IdempotencyInProgressError, y as InferWorkflowStageIds, J as JobExecuteCommand, a as JobExecuteResult, b as Kernel, c as KernelCommand, d as KernelCommandType, e as KernelConfig, W as KernelWorkflowRegistry, L as LeaseReapStaleCommand, f as LeaseReapStaleResult, O as OutboxFlushCommand, g as OutboxFlushResult, P as PluginDefinition, h as PluginReplayDLQCommand, i as PluginReplayDLQResult, j as PluginRunner, k as PluginRunnerConfig, R as RunCancelCommand, l as RunCancelResult, m as RunClaimPendingCommand, n as RunClaimPendingResult, o as RunCreateCommand, p as RunCreateResult, q as RunRerunFromCommand, r as RunRerunFromResult, s as RunTransitionCommand, t as RunTransitionResult, S as StagePollSuspendedCommand, u as StagePollSuspendedResult, z as Workflow, A as WorkflowBuilder, v as createKernel, w as createPluginRunner, x as definePlugin } from './plugins-DW266bhT.js';
6
6
  import z$1, { z } from 'zod';
7
- export { A as AICallLogger, i as AICallRecord, h as AIHelperStats, r as ArtifactType, g as CreateAICallInput, f as CreateLogInput, C as CreateOutboxEventInput, a as CreateRunInput, b as CreateStageInput, D as DequeueResult, E as EnqueueJobInput, I as IdempotencyRecord, J as JobQueue, j as JobRecord, k as JobStatus, L as LogLevel, O as OutboxRecord, o as SaveArtifactInput, s as StaleVersionError, S as Status, U as UpdateRunInput, e as UpdateStageInput, d as UpsertStageInput, p as WorkflowArtifactRecord, q as WorkflowLogRecord, l as WorkflowPersistence, W as WorkflowRunRecord, c as WorkflowStageRecord, n as WorkflowStageStatus, m as WorkflowStatus } from './interface-MMqhfQQK.js';
8
- export { P as PrismaAICallLogger, a as PrismaJobQueue, c as PrismaWorkflowPersistence, e as createPrismaAICallLogger, f as createPrismaJobQueue, g as createPrismaWorkflowPersistence } from './index-DAzCfO1R.js';
7
+ export { A as AICallLogger, i as AICallRecord, h as AIHelperStats, r as ArtifactType, g as CreateAICallInput, f as CreateLogInput, C as CreateOutboxEventInput, a as CreateRunInput, b as CreateStageInput, D as DequeueResult, E as EnqueueJobInput, I as IdempotencyRecord, J as JobQueue, j as JobRecord, k as JobStatus, L as LogLevel, O as OutboxRecord, o as SaveArtifactInput, s as StaleVersionError, S as Status, U as UpdateRunInput, e as UpdateStageInput, d as UpsertStageInput, p as WorkflowArtifactRecord, q as WorkflowLogRecord, l as WorkflowPersistence, W as WorkflowRunRecord, c as WorkflowStageRecord, n as WorkflowStageStatus, m as WorkflowStatus } from './interface-TsryH4d7.js';
8
+ export { P as PrismaAICallLogger, a as PrismaJobQueue, c as PrismaWorkflowPersistence, e as createPrismaAICallLogger, f as createPrismaJobQueue, g as createPrismaWorkflowPersistence } from './index-CVkkGnxx.js';
9
9
  import { ToolSet } from 'ai';
10
- export { B as BlobStore, C as Clock, E as EventSink, J as JobTransport, K as KernelEvent, a as KernelEventType, P as Persistence, S as Scheduler } from './ports-tU3rzPXJ.js';
10
+ export { B as BlobStore, C as Clock, E as EventSink, J as JobTransport, K as KernelEvent, a as KernelEventType, P as Persistence, S as Scheduler } from './ports-855bktyD.js';
11
+ import '@ai-sdk/provider';
11
12
 
12
13
  /**
13
14
  * Config Presets - Common configuration patterns for workflow stages
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
- import { ModelKey } from './chunk-QBYB2PJJ.js';
2
- export { AVAILABLE_MODELS, AnthropicBatchProvider, DEFAULT_MODEL_KEY, GoogleBatchProvider, ModelKey, ModelStatsTracker, NoInputSchema, OpenAIBatchProvider, calculateCost, createAIHelper, defineAsyncBatchStage, defineStage, getBestProviderForModel, getDefaultModel, getModel, getModelById, getRegisteredModel, listModels, listRegisteredModels, modelSupportsBatch, printAvailableModels, registerModels, requireStageOutput, resolveModelForProvider } from './chunk-QBYB2PJJ.js';
1
+ import { ModelKey } from './chunk-XS3ZX4KW.js';
2
+ export { AVAILABLE_MODELS, AnthropicBatchProvider, DEFAULT_MODEL_KEY, GoogleBatchProvider, ModelKey, ModelStatsTracker, NoInputSchema, OpenAIBatchProvider, calculateCost, createAIHelper, defineAsyncBatchStage, defineStage, getBestProviderForModel, getDefaultModel, getModel, getModelById, getRegisteredModel, listModels, listRegisteredModels, modelSupportsBatch, printAvailableModels, registerEmbeddingProvider, registerModels, requireStageOutput, resolveModelForProvider } from './chunk-XS3ZX4KW.js';
3
3
  import './chunk-D7RVRRM2.js';
4
- export { PrismaAICallLogger, PrismaJobQueue, PrismaWorkflowPersistence, createPrismaAICallLogger, createPrismaJobQueue, createPrismaWorkflowPersistence } from './chunk-NYKMT46J.js';
4
+ export { PrismaAICallLogger, PrismaJobQueue, PrismaWorkflowPersistence, createPrismaAICallLogger, createPrismaJobQueue, createPrismaWorkflowPersistence } from './chunk-PHLNTR5Z.js';
5
5
  import './chunk-MUWP5SF2.js';
6
- export { StaleVersionError } from './chunk-SPXBCZLB.js';
7
- export { IdempotencyInProgressError, createKernel, createPluginRunner, definePlugin } from './chunk-WZ533CPU.js';
6
+ export { StaleVersionError } from './chunk-RZY5YRGL.js';
7
+ export { IdempotencyInProgressError, createKernel, createPluginRunner, definePlugin } from './chunk-3NEGRI4M.js';
8
8
  import { z } from 'zod';
9
9
 
10
10
  var Workflow = class {
@@ -271,6 +271,7 @@ interface WorkflowPersistence {
271
271
  getRun(id: string): Promise<WorkflowRunRecord | null>;
272
272
  getRunStatus(id: string): Promise<WorkflowStatus | null>;
273
273
  getRunsByStatus(status: WorkflowStatus): Promise<WorkflowRunRecord[]>;
274
+ getStuckRuns(stuckSince: Date): Promise<WorkflowRunRecord[]>;
274
275
  /**
275
276
  * Atomically claim a pending workflow run for processing.
276
277
  * Uses atomic update with WHERE status = 'PENDING' to prevent race conditions.
@@ -1,7 +1,7 @@
1
- import { K as KernelDeps } from '../plugins-CPC-X0rR.js';
2
- export { C as CommandResult, I as IdempotencyInProgressError, J as JobExecuteCommand, a as JobExecuteResult, b as Kernel, c as KernelCommand, d as KernelCommandType, e as KernelConfig, L as LeaseReapStaleCommand, f as LeaseReapStaleResult, O as OutboxFlushCommand, g as OutboxFlushResult, P as PluginDefinition, h as PluginReplayDLQCommand, i as PluginReplayDLQResult, j as PluginRunner, k as PluginRunnerConfig, R as RunCancelCommand, l as RunCancelResult, m as RunClaimPendingCommand, n as RunClaimPendingResult, o as RunCreateCommand, p as RunCreateResult, q as RunRerunFromCommand, r as RunRerunFromResult, s as RunTransitionCommand, t as RunTransitionResult, S as StagePollSuspendedCommand, u as StagePollSuspendedResult, W as WorkflowRegistry, v as createKernel, w as createPluginRunner, x as definePlugin } from '../plugins-CPC-X0rR.js';
3
- export { B as BlobStore, C as Clock, E as EventSink, J as JobTransport, K as KernelEvent, a as KernelEventType, P as Persistence, S as Scheduler, b as StageCompletedEvent, c as StageFailedEvent, d as StageProgressEvent, e as StageStartedEvent, f as StageSuspendedEvent, W as WorkflowCancelledEvent, g as WorkflowCompletedEvent, h as WorkflowCreatedEvent, i as WorkflowFailedEvent, j as WorkflowStartedEvent, k as WorkflowSuspendedEvent } from '../ports-tU3rzPXJ.js';
4
- export { C as CreateOutboxEventInput, I as IdempotencyRecord, O as OutboxRecord } from '../interface-MMqhfQQK.js';
1
+ import { K as KernelDeps } from '../plugins-DW266bhT.js';
2
+ export { C as CommandResult, I as IdempotencyInProgressError, J as JobExecuteCommand, a as JobExecuteResult, b as Kernel, c as KernelCommand, d as KernelCommandType, e as KernelConfig, L as LeaseReapStaleCommand, f as LeaseReapStaleResult, O as OutboxFlushCommand, g as OutboxFlushResult, P as PluginDefinition, h as PluginReplayDLQCommand, i as PluginReplayDLQResult, j as PluginRunner, k as PluginRunnerConfig, R as RunCancelCommand, l as RunCancelResult, m as RunClaimPendingCommand, n as RunClaimPendingResult, o as RunCreateCommand, p as RunCreateResult, q as RunRerunFromCommand, r as RunRerunFromResult, s as RunTransitionCommand, t as RunTransitionResult, S as StagePollSuspendedCommand, u as StagePollSuspendedResult, W as WorkflowRegistry, v as createKernel, w as createPluginRunner, x as definePlugin } from '../plugins-DW266bhT.js';
3
+ export { B as BlobStore, C as Clock, E as EventSink, J as JobTransport, K as KernelEvent, a as KernelEventType, P as Persistence, S as Scheduler, b as StageCompletedEvent, c as StageFailedEvent, d as StageProgressEvent, e as StageStartedEvent, f as StageSuspendedEvent, W as WorkflowCancelledEvent, g as WorkflowCompletedEvent, h as WorkflowCreatedEvent, i as WorkflowFailedEvent, j as WorkflowStartedEvent, k as WorkflowSuspendedEvent } from '../ports-855bktyD.js';
4
+ export { C as CreateOutboxEventInput, I as IdempotencyRecord, O as OutboxRecord } from '../interface-TsryH4d7.js';
5
5
  import 'zod';
6
6
  import '../stage-BPw7m9Wx.js';
7
7
 
@@ -1,3 +1,3 @@
1
- export { IdempotencyInProgressError, createKernel, createPluginRunner, definePlugin, loadWorkflowContext, saveStageOutput } from '../chunk-WZ533CPU.js';
1
+ export { IdempotencyInProgressError, createKernel, createPluginRunner, definePlugin, loadWorkflowContext, saveStageOutput } from '../chunk-3NEGRI4M.js';
2
2
  //# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map
@@ -1,5 +1,5 @@
1
- import { E as EventSink, K as KernelEvent, a as KernelEventType, C as Clock, B as BlobStore, S as Scheduler } from '../../ports-tU3rzPXJ.js';
2
- import '../../interface-MMqhfQQK.js';
1
+ import { E as EventSink, K as KernelEvent, a as KernelEventType, C as Clock, B as BlobStore, S as Scheduler } from '../../ports-855bktyD.js';
2
+ import '../../interface-TsryH4d7.js';
3
3
 
4
4
  declare class CollectingEventSink implements EventSink {
5
5
  readonly events: KernelEvent[];
@@ -1,2 +1,2 @@
1
- export { A as AICallLogger, i as AICallRecord, h as AIHelperStats, r as ArtifactType, g as CreateAICallInput, f as CreateLogInput, a as CreateRunInput, b as CreateStageInput, D as DequeueResult, E as EnqueueJobInput, J as JobQueue, j as JobRecord, k as JobStatus, L as LogLevel, o as SaveArtifactInput, S as Status, U as UpdateRunInput, e as UpdateStageInput, d as UpsertStageInput, p as WorkflowArtifactRecord, q as WorkflowLogRecord, l as WorkflowPersistence, W as WorkflowRunRecord, c as WorkflowStageRecord, n as WorkflowStageStatus, m as WorkflowStatus } from '../interface-MMqhfQQK.js';
2
- export { P as PrismaAICallLogger, a as PrismaJobQueue, c as PrismaWorkflowPersistence, e as createPrismaAICallLogger, f as createPrismaJobQueue, g as createPrismaWorkflowPersistence } from '../index-DAzCfO1R.js';
1
+ export { A as AICallLogger, i as AICallRecord, h as AIHelperStats, r as ArtifactType, g as CreateAICallInput, f as CreateLogInput, a as CreateRunInput, b as CreateStageInput, D as DequeueResult, E as EnqueueJobInput, J as JobQueue, j as JobRecord, k as JobStatus, L as LogLevel, o as SaveArtifactInput, S as Status, U as UpdateRunInput, e as UpdateStageInput, d as UpsertStageInput, p as WorkflowArtifactRecord, q as WorkflowLogRecord, l as WorkflowPersistence, W as WorkflowRunRecord, c as WorkflowStageRecord, n as WorkflowStageStatus, m as WorkflowStatus } from '../interface-TsryH4d7.js';
2
+ export { P as PrismaAICallLogger, a as PrismaJobQueue, c as PrismaWorkflowPersistence, e as createPrismaAICallLogger, f as createPrismaJobQueue, g as createPrismaWorkflowPersistence } from '../index-CVkkGnxx.js';
@@ -1,6 +1,6 @@
1
1
  import '../chunk-D7RVRRM2.js';
2
- export { PrismaAICallLogger, PrismaJobQueue, PrismaWorkflowPersistence, createPrismaAICallLogger, createPrismaJobQueue, createPrismaWorkflowPersistence } from '../chunk-NYKMT46J.js';
2
+ export { PrismaAICallLogger, PrismaJobQueue, PrismaWorkflowPersistence, createPrismaAICallLogger, createPrismaJobQueue, createPrismaWorkflowPersistence } from '../chunk-PHLNTR5Z.js';
3
3
  import '../chunk-MUWP5SF2.js';
4
- import '../chunk-SPXBCZLB.js';
4
+ import '../chunk-RZY5YRGL.js';
5
5
  //# sourceMappingURL=index.js.map
6
6
  //# sourceMappingURL=index.js.map
@@ -1,5 +1,5 @@
1
- export { D as DatabaseType, P as PrismaAICallLogger, a as PrismaJobQueue, b as PrismaJobQueueOptions, c as PrismaWorkflowPersistence, d as PrismaWorkflowPersistenceOptions, e as createPrismaAICallLogger, f as createPrismaJobQueue, g as createPrismaWorkflowPersistence } from '../../index-DAzCfO1R.js';
2
- import '../../interface-MMqhfQQK.js';
1
+ export { D as DatabaseType, P as PrismaAICallLogger, a as PrismaJobQueue, b as PrismaJobQueueOptions, c as PrismaWorkflowPersistence, d as PrismaWorkflowPersistenceOptions, e as createPrismaAICallLogger, f as createPrismaJobQueue, g as createPrismaWorkflowPersistence } from '../../index-CVkkGnxx.js';
2
+ import '../../interface-TsryH4d7.js';
3
3
 
4
4
  /**
5
5
  * Prisma Enum Compatibility Layer
@@ -1,5 +1,5 @@
1
- export { PrismaAICallLogger, PrismaJobQueue, PrismaWorkflowPersistence, createEnumHelper, createPrismaAICallLogger, createPrismaJobQueue, createPrismaWorkflowPersistence } from '../../chunk-NYKMT46J.js';
1
+ export { PrismaAICallLogger, PrismaJobQueue, PrismaWorkflowPersistence, createEnumHelper, createPrismaAICallLogger, createPrismaJobQueue, createPrismaWorkflowPersistence } from '../../chunk-PHLNTR5Z.js';
2
2
  import '../../chunk-MUWP5SF2.js';
3
- import '../../chunk-SPXBCZLB.js';
3
+ import '../../chunk-RZY5YRGL.js';
4
4
  //# sourceMappingURL=index.js.map
5
5
  //# sourceMappingURL=index.js.map
@@ -1,6 +1,6 @@
1
1
  import { z } from 'zod';
2
2
  import { S as Stage } from './stage-BPw7m9Wx.js';
3
- import { P as Persistence, B as BlobStore, J as JobTransport, E as EventSink, S as Scheduler, C as Clock, a as KernelEventType, K as KernelEvent } from './ports-tU3rzPXJ.js';
3
+ import { P as Persistence, B as BlobStore, J as JobTransport, E as EventSink, S as Scheduler, C as Clock, a as KernelEventType, K as KernelEvent } from './ports-855bktyD.js';
4
4
 
5
5
  /**
6
6
  * Workflow Builder - Fluent API for composing type-safe workflows
@@ -333,12 +333,22 @@ interface PluginReplayDLQCommand {
333
333
  interface PluginReplayDLQResult {
334
334
  readonly replayed: number;
335
335
  }
336
+ /** Detects and handles RUNNING runs with no recent activity. */
337
+ interface RunReapStuckCommand {
338
+ readonly type: "run.reapStuck";
339
+ readonly stuckThresholdMs: number;
340
+ }
341
+ /** Result of a `run.reapStuck` command. */
342
+ interface RunReapStuckResult {
343
+ readonly transitioned: number;
344
+ readonly failed: number;
345
+ }
336
346
  /** Discriminated union of every kernel command. */
337
- type KernelCommand = RunCreateCommand | RunClaimPendingCommand | RunTransitionCommand | RunCancelCommand | RunRerunFromCommand | JobExecuteCommand | StagePollSuspendedCommand | LeaseReapStaleCommand | OutboxFlushCommand | PluginReplayDLQCommand;
347
+ type KernelCommand = RunCreateCommand | RunClaimPendingCommand | RunTransitionCommand | RunCancelCommand | RunRerunFromCommand | JobExecuteCommand | StagePollSuspendedCommand | LeaseReapStaleCommand | OutboxFlushCommand | PluginReplayDLQCommand | RunReapStuckCommand;
338
348
  /** String literal union of all kernel command type discriminants. */
339
349
  type KernelCommandType = KernelCommand["type"];
340
350
  /** Maps a `KernelCommand` to its corresponding result type. */
341
- type CommandResult<T extends KernelCommand> = T extends RunCreateCommand ? RunCreateResult : T extends RunClaimPendingCommand ? RunClaimPendingResult : T extends RunTransitionCommand ? RunTransitionResult : T extends RunCancelCommand ? RunCancelResult : T extends RunRerunFromCommand ? RunRerunFromResult : T extends JobExecuteCommand ? JobExecuteResult : T extends StagePollSuspendedCommand ? StagePollSuspendedResult : T extends LeaseReapStaleCommand ? LeaseReapStaleResult : T extends OutboxFlushCommand ? OutboxFlushResult : T extends PluginReplayDLQCommand ? PluginReplayDLQResult : never;
351
+ type CommandResult<T extends KernelCommand> = T extends RunCreateCommand ? RunCreateResult : T extends RunClaimPendingCommand ? RunClaimPendingResult : T extends RunTransitionCommand ? RunTransitionResult : T extends RunCancelCommand ? RunCancelResult : T extends RunRerunFromCommand ? RunRerunFromResult : T extends JobExecuteCommand ? JobExecuteResult : T extends StagePollSuspendedCommand ? StagePollSuspendedResult : T extends LeaseReapStaleCommand ? LeaseReapStaleResult : T extends OutboxFlushCommand ? OutboxFlushResult : T extends PluginReplayDLQCommand ? PluginReplayDLQResult : T extends RunReapStuckCommand ? RunReapStuckResult : never;
342
352
 
343
353
  declare class IdempotencyInProgressError extends Error {
344
354
  readonly key: string;
@@ -1,4 +1,4 @@
1
- import { E as EnqueueJobInput, D as DequeueResult, a as CreateRunInput, W as WorkflowRunRecord, U as UpdateRunInput, S as Status, b as CreateStageInput, c as WorkflowStageRecord, d as UpsertStageInput, e as UpdateStageInput, f as CreateLogInput, C as CreateOutboxEventInput, O as OutboxRecord } from './interface-MMqhfQQK.js';
1
+ import { E as EnqueueJobInput, D as DequeueResult, a as CreateRunInput, W as WorkflowRunRecord, U as UpdateRunInput, S as Status, b as CreateStageInput, c as WorkflowStageRecord, d as UpsertStageInput, e as UpdateStageInput, f as CreateLogInput, C as CreateOutboxEventInput, O as OutboxRecord } from './interface-TsryH4d7.js';
2
2
 
3
3
  /**
4
4
  * Kernel Event Types
@@ -139,6 +139,7 @@ interface Persistence {
139
139
  getRun(id: string): Promise<WorkflowRunRecord | null>;
140
140
  getRunStatus(id: string): Promise<Status | null>;
141
141
  getRunsByStatus(status: Status): Promise<WorkflowRunRecord[]>;
142
+ getStuckRuns(stuckSince: Date): Promise<WorkflowRunRecord[]>;
142
143
  /**
143
144
  * Atomically claim a pending workflow run for processing.
144
145
  * Uses atomic update with WHERE status = 'PENDING' to prevent race conditions.
@@ -1,4 +1,4 @@
1
- import { A as AICallLogger, g as CreateAICallInput, h as AIHelperStats, i as AICallRecord, J as JobQueue, E as EnqueueJobInput, D as DequeueResult, j as JobRecord, k as JobStatus, l as WorkflowPersistence, a as CreateRunInput, W as WorkflowRunRecord, U as UpdateRunInput, m as WorkflowStatus, b as CreateStageInput, c as WorkflowStageRecord, d as UpsertStageInput, e as UpdateStageInput, n as WorkflowStageStatus, f as CreateLogInput, C as CreateOutboxEventInput, O as OutboxRecord, o as SaveArtifactInput, p as WorkflowArtifactRecord, q as WorkflowLogRecord } from '../interface-MMqhfQQK.js';
1
+ import { A as AICallLogger, g as CreateAICallInput, h as AIHelperStats, i as AICallRecord, J as JobQueue, E as EnqueueJobInput, D as DequeueResult, j as JobRecord, k as JobStatus, l as WorkflowPersistence, a as CreateRunInput, W as WorkflowRunRecord, U as UpdateRunInput, m as WorkflowStatus, b as CreateStageInput, c as WorkflowStageRecord, d as UpsertStageInput, e as UpdateStageInput, n as WorkflowStageStatus, f as CreateLogInput, C as CreateOutboxEventInput, O as OutboxRecord, o as SaveArtifactInput, p as WorkflowArtifactRecord, q as WorkflowLogRecord } from '../interface-TsryH4d7.js';
2
2
 
3
3
  /**
4
4
  * In-Memory AI Call Logger
@@ -197,6 +197,7 @@ declare class InMemoryWorkflowPersistence implements WorkflowPersistence {
197
197
  getRun(id: string): Promise<WorkflowRunRecord | null>;
198
198
  getRunStatus(id: string): Promise<WorkflowStatus | null>;
199
199
  getRunsByStatus(status: WorkflowStatus): Promise<WorkflowRunRecord[]>;
200
+ getStuckRuns(stuckSince: Date): Promise<WorkflowRunRecord[]>;
200
201
  claimPendingRun(id: string): Promise<boolean>;
201
202
  claimNextPendingRun(): Promise<WorkflowRunRecord | null>;
202
203
  createStage(data: CreateStageInput): Promise<WorkflowStageRecord>;
@@ -1,4 +1,4 @@
1
- import { StaleVersionError } from '../chunk-SPXBCZLB.js';
1
+ import { StaleVersionError } from '../chunk-RZY5YRGL.js';
2
2
  import { randomUUID } from 'crypto';
3
3
 
4
4
  var InMemoryAICallLogger = class {
@@ -507,6 +507,24 @@ var InMemoryWorkflowPersistence = class {
507
507
  async getRunsByStatus(status) {
508
508
  return Array.from(this.runs.values()).filter((run) => run.status === status).map((run) => ({ ...run }));
509
509
  }
510
+ async getStuckRuns(stuckSince) {
511
+ const runningRuns = await this.getRunsByStatus("RUNNING");
512
+ return runningRuns.filter((run) => {
513
+ const seenIds = /* @__PURE__ */ new Set();
514
+ const stages = Array.from(this.stages.values()).filter((s) => {
515
+ if (s.workflowRunId !== run.id) return false;
516
+ if (seenIds.has(s.id)) return false;
517
+ seenIds.add(s.id);
518
+ return true;
519
+ });
520
+ const lastStageUpdate = stages.reduce(
521
+ (max, s) => s.updatedAt > max ? s.updatedAt : max,
522
+ /* @__PURE__ */ new Date(0)
523
+ );
524
+ const lastActivity = run.updatedAt > lastStageUpdate ? run.updatedAt : lastStageUpdate;
525
+ return lastActivity <= stuckSince;
526
+ });
527
+ }
510
528
  async claimPendingRun(id) {
511
529
  const run = this.runs.get(id);
512
530
  if (!run || run.status !== "PENDING") {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/testing/in-memory-ai-logger.ts","../../src/testing/in-memory-job-queue.ts","../../src/testing/in-memory-persistence.ts"],"names":["randomUUID"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * In-Memory AI Call Logger\n *\n * A complete in-memory implementation of AICallLogger for testing.\n * Tracks all AI calls with full cost/token tracking and topic-based aggregation.\n *\n * @example\n * ```typescript\n * import { InMemoryAICallLogger } from '@bratsos/workflow-engine/testing';\n *\n * const aiLogger = new InMemoryAICallLogger();\n * // Use in tests...\n * aiLogger.clear(); // Reset between tests\n * ```\n */\n\nimport { randomUUID } from \"crypto\";\nimport type {\n AICallLogger,\n AICallRecord,\n AIHelperStats,\n CreateAICallInput,\n} from \"../persistence/interface.js\";\n\nexport class InMemoryAICallLogger implements AICallLogger {\n private calls = new Map<string, AICallRecord>();\n private recordedBatches = new Set<string>();\n\n // ============================================================================\n // Core Operations\n // ============================================================================\n\n /**\n * Log a single AI call (fire and forget)\n */\n logCall(call: CreateAICallInput): void {\n const id = randomUUID();\n const record: AICallRecord = {\n id,\n createdAt: new Date(),\n topic: call.topic,\n callType: call.callType,\n modelKey: call.modelKey,\n modelId: call.modelId,\n prompt: call.prompt,\n response: call.response,\n inputTokens: call.inputTokens,\n outputTokens: call.outputTokens,\n cost: call.cost,\n metadata: call.metadata ?? null,\n };\n this.calls.set(id, record);\n }\n\n /**\n * Log batch results (for recording batch API results)\n */\n async logBatchResults(\n batchId: string,\n results: CreateAICallInput[],\n ): Promise<void> {\n // Mark batch as recorded\n this.recordedBatches.add(batchId);\n\n // Log each result\n for (const result of results) {\n this.logCall({\n ...result,\n metadata: {\n ...(result.metadata as Record<string, unknown> | undefined),\n batchId,\n },\n });\n }\n }\n\n /**\n * Get aggregated stats for a topic prefix\n */\n async getStats(topicPrefix: string): Promise<AIHelperStats> {\n const matchingCalls = Array.from(this.calls.values()).filter((call) =>\n call.topic.startsWith(topicPrefix),\n );\n\n const stats: AIHelperStats = {\n totalCalls: matchingCalls.length,\n totalInputTokens: 0,\n totalOutputTokens: 0,\n totalCost: 0,\n perModel: {},\n };\n\n for (const call of matchingCalls) {\n stats.totalInputTokens += call.inputTokens;\n stats.totalOutputTokens += call.outputTokens;\n stats.totalCost += call.cost;\n\n // Aggregate per model\n if (!stats.perModel[call.modelKey]) {\n stats.perModel[call.modelKey] = {\n calls: 0,\n inputTokens: 0,\n outputTokens: 0,\n cost: 0,\n };\n }\n stats.perModel[call.modelKey]!.calls++;\n stats.perModel[call.modelKey]!.inputTokens += call.inputTokens;\n stats.perModel[call.modelKey]!.outputTokens += call.outputTokens;\n stats.perModel[call.modelKey]!.cost += call.cost;\n }\n\n return stats;\n }\n\n /**\n * Check if batch results are already recorded\n */\n async isRecorded(batchId: string): Promise<boolean> {\n return this.recordedBatches.has(batchId);\n }\n\n // ============================================================================\n // Test Helpers\n // ============================================================================\n\n /**\n * Clear all data - useful between tests\n */\n clear(): void {\n this.calls.clear();\n this.recordedBatches.clear();\n }\n\n /**\n * Get all calls for inspection\n */\n getAllCalls(): AICallRecord[] {\n return Array.from(this.calls.values()).map((c) => ({ ...c }));\n }\n\n /**\n * Get calls by topic for inspection\n */\n getCallsByTopic(topic: string): AICallRecord[] {\n return Array.from(this.calls.values())\n .filter((c) => c.topic === topic)\n .map((c) => ({ ...c }));\n }\n\n /**\n * Get calls by topic prefix for inspection\n */\n getCallsByTopicPrefix(prefix: string): AICallRecord[] {\n return Array.from(this.calls.values())\n .filter((c) => c.topic.startsWith(prefix))\n .map((c) => ({ ...c }));\n }\n\n /**\n * Get calls by model for inspection\n */\n getCallsByModel(modelKey: string): AICallRecord[] {\n return Array.from(this.calls.values())\n .filter((c) => c.modelKey === modelKey)\n .map((c) => ({ ...c }));\n }\n\n /**\n * Get calls by call type for inspection\n */\n getCallsByType(callType: string): AICallRecord[] {\n return Array.from(this.calls.values())\n .filter((c) => c.callType === callType)\n .map((c) => ({ ...c }));\n }\n\n /**\n * Get total cost across all calls\n */\n getTotalCost(): number {\n let total = 0;\n for (const call of this.calls.values()) {\n total += call.cost;\n }\n return total;\n }\n\n /**\n * Get total tokens across all calls\n */\n getTotalTokens(): { input: number; output: number } {\n let input = 0;\n let output = 0;\n for (const call of this.calls.values()) {\n input += call.inputTokens;\n output += call.outputTokens;\n }\n return { input, output };\n }\n\n /**\n * Get call count\n */\n getCallCount(): number {\n return this.calls.size;\n }\n\n /**\n * Get all recorded batch IDs\n */\n getRecordedBatchIds(): string[] {\n return Array.from(this.recordedBatches);\n }\n\n /**\n * Get the last call made (useful for assertions)\n */\n getLastCall(): AICallRecord | null {\n const calls = Array.from(this.calls.values());\n if (calls.length === 0) return null;\n\n // Sort by createdAt descending\n calls.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());\n return { ...calls[0]! };\n }\n\n /**\n * Assert a call was made with specific properties\n */\n hasCallMatching(predicate: (call: AICallRecord) => boolean): boolean {\n return Array.from(this.calls.values()).some(predicate);\n }\n}\n","/**\n * In-Memory Job Queue\n *\n * A complete in-memory implementation of JobQueue for testing.\n * Supports priority ordering, locking, and stale job recovery.\n *\n * @example\n * ```typescript\n * import { InMemoryJobQueue } from '@bratsos/workflow-engine/testing';\n *\n * const jobQueue = new InMemoryJobQueue();\n * // Use in tests...\n * jobQueue.clear(); // Reset between tests\n * ```\n */\n\nimport { randomUUID } from \"crypto\";\nimport type {\n DequeueResult,\n EnqueueJobInput,\n JobQueue,\n JobRecord,\n JobStatus,\n} from \"../persistence/interface.js\";\n\nexport class InMemoryJobQueue implements JobQueue {\n private jobs = new Map<string, JobRecord>();\n private workerId: string;\n private defaultMaxAttempts = 3;\n\n constructor(workerId?: string) {\n this.workerId = workerId ?? `worker-${randomUUID().slice(0, 8)}`;\n }\n\n // ============================================================================\n // Core Operations\n // ============================================================================\n\n async enqueue(options: EnqueueJobInput): Promise<string> {\n const now = new Date();\n const id = randomUUID();\n\n const job: JobRecord = {\n id,\n createdAt: now,\n updatedAt: now,\n workflowRunId: options.workflowRunId,\n workflowId: options.workflowId,\n stageId: options.stageId,\n status: \"PENDING\",\n priority: options.priority ?? 5,\n workerId: null,\n lockedAt: null,\n startedAt: null,\n completedAt: null,\n attempt: 1,\n maxAttempts: this.defaultMaxAttempts,\n lastError: null,\n nextPollAt: options.scheduledFor ?? null,\n payload: options.payload ?? {},\n };\n\n this.jobs.set(id, job);\n return id;\n }\n\n async enqueueParallel(jobs: EnqueueJobInput[]): Promise<string[]> {\n const ids: string[] = [];\n for (const job of jobs) {\n const id = await this.enqueue(job);\n ids.push(id);\n }\n return ids;\n }\n\n async dequeue(): Promise<DequeueResult | null> {\n // Find the highest priority PENDING job\n const now = new Date();\n const pendingJobs = Array.from(this.jobs.values())\n .filter(\n (j) =>\n j.status === \"PENDING\" &&\n (j.nextPollAt === null || j.nextPollAt <= now),\n )\n .sort((a, b) => {\n // Higher priority first\n if (b.priority !== a.priority) {\n return b.priority - a.priority;\n }\n // Earlier creation first (FIFO for same priority)\n return a.createdAt.getTime() - b.createdAt.getTime();\n });\n\n if (pendingJobs.length === 0) {\n return null;\n }\n\n const job = pendingJobs[0]!;\n\n // Lock the job\n const updated: JobRecord = {\n ...job,\n status: \"RUNNING\",\n workerId: this.workerId,\n lockedAt: now,\n startedAt: now,\n updatedAt: now,\n };\n this.jobs.set(job.id, updated);\n\n return {\n jobId: job.id,\n workflowRunId: job.workflowRunId,\n workflowId: job.workflowId,\n stageId: job.stageId,\n priority: job.priority,\n attempt: job.attempt,\n maxAttempts: job.maxAttempts,\n payload: job.payload,\n };\n }\n\n async complete(jobId: string): Promise<void> {\n const job = this.jobs.get(jobId);\n if (!job) {\n throw new Error(`Job not found: ${jobId}`);\n }\n\n const now = new Date();\n const updated: JobRecord = {\n ...job,\n status: \"COMPLETED\",\n completedAt: now,\n updatedAt: now,\n };\n this.jobs.set(jobId, updated);\n }\n\n async suspend(jobId: string, nextPollAt: Date): Promise<void> {\n const job = this.jobs.get(jobId);\n if (!job) {\n throw new Error(`Job not found: ${jobId}`);\n }\n\n const updated: JobRecord = {\n ...job,\n status: \"SUSPENDED\",\n nextPollAt,\n workerId: null,\n lockedAt: null,\n updatedAt: new Date(),\n };\n this.jobs.set(jobId, updated);\n }\n\n async fail(\n jobId: string,\n error: string,\n shouldRetry: boolean = true,\n ): Promise<void> {\n const job = this.jobs.get(jobId);\n if (!job) {\n throw new Error(`Job not found: ${jobId}`);\n }\n\n const now = new Date();\n\n if (shouldRetry && job.attempt < job.maxAttempts) {\n // Retry: move back to PENDING with incremented attempt\n const updated: JobRecord = {\n ...job,\n status: \"PENDING\",\n attempt: job.attempt + 1,\n lastError: error,\n workerId: null,\n lockedAt: null,\n updatedAt: now,\n };\n this.jobs.set(jobId, updated);\n } else {\n // No more retries: mark as FAILED\n const updated: JobRecord = {\n ...job,\n status: \"FAILED\",\n lastError: error,\n completedAt: now,\n updatedAt: now,\n };\n this.jobs.set(jobId, updated);\n }\n }\n\n async getSuspendedJobsReadyToPoll(): Promise<\n Array<{ jobId: string; stageId: string; workflowRunId: string }>\n > {\n const now = new Date();\n return Array.from(this.jobs.values())\n .filter(\n (j) => j.status === \"SUSPENDED\" && j.nextPollAt && j.nextPollAt <= now,\n )\n .map((j) => ({\n jobId: j.id,\n stageId: j.stageId,\n workflowRunId: j.workflowRunId,\n }));\n }\n\n async releaseStaleJobs(staleThresholdMs: number = 60000): Promise<number> {\n const now = new Date();\n const threshold = new Date(now.getTime() - staleThresholdMs);\n let released = 0;\n\n for (const job of this.jobs.values()) {\n if (\n job.status === \"RUNNING\" &&\n job.lockedAt &&\n job.lockedAt < threshold\n ) {\n // Release the stale lock\n const updated: JobRecord = {\n ...job,\n status: \"PENDING\",\n workerId: null,\n lockedAt: null,\n updatedAt: now,\n };\n this.jobs.set(job.id, updated);\n released++;\n }\n }\n\n return released;\n }\n\n // ============================================================================\n // Test Helpers\n // ============================================================================\n\n /**\n * Clear all jobs - useful between tests\n */\n clear(): void {\n this.jobs.clear();\n }\n\n /**\n * Get all jobs for inspection\n */\n getAllJobs(): JobRecord[] {\n return Array.from(this.jobs.values()).map((j) => ({ ...j }));\n }\n\n /**\n * Get jobs by status for inspection\n */\n getJobsByStatus(status: JobStatus): JobRecord[] {\n return Array.from(this.jobs.values())\n .filter((j) => j.status === status)\n .map((j) => ({ ...j }));\n }\n\n /**\n * Get a specific job by ID\n */\n getJob(jobId: string): JobRecord | null {\n const job = this.jobs.get(jobId);\n return job ? { ...job } : null;\n }\n\n /**\n * Get the worker ID for this queue instance\n */\n getWorkerId(): string {\n return this.workerId;\n }\n\n /**\n * Set max attempts for new jobs\n */\n setDefaultMaxAttempts(maxAttempts: number): void {\n this.defaultMaxAttempts = maxAttempts;\n }\n\n /**\n * Simulate a worker crash by releasing a job's lock without completing it\n */\n simulateCrash(jobId: string): void {\n const job = this.jobs.get(jobId);\n if (job && job.status === \"RUNNING\") {\n // Don't change status - just leave it locked by the \"crashed\" worker\n // releaseStaleJobs() will clean it up\n }\n }\n\n /**\n * Move a suspended job back to pending (for manual resume testing)\n */\n resumeJob(jobId: string): void {\n const job = this.jobs.get(jobId);\n if (job && job.status === \"SUSPENDED\") {\n const updated: JobRecord = {\n ...job,\n status: \"PENDING\",\n nextPollAt: null,\n updatedAt: new Date(),\n };\n this.jobs.set(jobId, updated);\n }\n }\n\n /**\n * Set lockedAt for testing stale job scenarios\n */\n setJobLockedAt(jobId: string, lockedAt: Date): void {\n const job = this.jobs.get(jobId);\n if (job) {\n const updated: JobRecord = {\n ...job,\n lockedAt,\n };\n this.jobs.set(jobId, updated);\n }\n }\n\n /**\n * Set nextPollAt for testing suspended job polling\n */\n setJobNextPollAt(jobId: string, nextPollAt: Date | null): void {\n const job = this.jobs.get(jobId);\n if (job) {\n const updated: JobRecord = {\n ...job,\n nextPollAt,\n };\n this.jobs.set(jobId, updated);\n }\n }\n}\n","/**\n * In-Memory Workflow Persistence\n *\n * A complete in-memory implementation of WorkflowPersistence for testing.\n * All data is stored in Maps and lost when the instance is garbage collected.\n *\n * @example\n * ```typescript\n * import { InMemoryWorkflowPersistence } from '@bratsos/workflow-engine/testing';\n *\n * const persistence = new InMemoryWorkflowPersistence();\n * // Use in tests...\n * persistence.clear(); // Reset between tests\n * ```\n */\n\nimport { randomUUID } from \"crypto\";\nimport {\n type CreateLogInput,\n type CreateOutboxEventInput,\n type CreateRunInput,\n type CreateStageInput,\n type IdempotencyRecord,\n type OutboxRecord,\n type SaveArtifactInput,\n StaleVersionError,\n type UpdateRunInput,\n type UpdateStageInput,\n type UpsertStageInput,\n type WorkflowArtifactRecord,\n type WorkflowLogRecord,\n type WorkflowPersistence,\n type WorkflowRunRecord,\n type WorkflowStageRecord,\n type WorkflowStageStatus,\n type WorkflowStatus,\n} from \"../persistence/interface.js\";\n\nexport class InMemoryWorkflowPersistence implements WorkflowPersistence {\n private runs = new Map<string, WorkflowRunRecord>();\n private stages = new Map<string, WorkflowStageRecord>();\n private logs = new Map<string, WorkflowLogRecord>();\n private artifacts = new Map<string, WorkflowArtifactRecord>();\n private outbox: OutboxRecord[] = [];\n private idempotencyKeys = new Map<string, IdempotencyRecord>();\n private idempotencyInProgress = new Set<string>();\n private outboxSequences = new Map<string, number>();\n\n // Helper to generate composite keys for stages\n private stageKey(runId: string, stageId: string): string {\n return `${runId}:${stageId}`;\n }\n\n // Helper to generate composite keys for artifacts\n private artifactKey(runId: string, key: string): string {\n return `${runId}:${key}`;\n }\n\n private idempotencyCompositeKey(commandType: string, key: string): string {\n return `${commandType}:${key}`;\n }\n\n async withTransaction<T>(\n fn: (tx: WorkflowPersistence) => Promise<T>,\n ): Promise<T> {\n return fn(this);\n }\n\n // ============================================================================\n // WorkflowRun Operations\n // ============================================================================\n\n async createRun(data: CreateRunInput): Promise<WorkflowRunRecord> {\n const now = new Date();\n const record: WorkflowRunRecord = {\n id: data.id ?? randomUUID(),\n createdAt: now,\n updatedAt: now,\n version: 1,\n workflowId: data.workflowId,\n workflowName: data.workflowName,\n workflowType: data.workflowType,\n status: \"PENDING\",\n startedAt: null,\n completedAt: null,\n duration: null,\n input: data.input,\n output: null,\n config: data.config ?? {},\n totalCost: 0,\n totalTokens: 0,\n priority: data.priority ?? 5,\n };\n this.runs.set(record.id, record);\n return { ...record };\n }\n\n async updateRun(id: string, data: UpdateRunInput): Promise<void> {\n const run = this.runs.get(id);\n if (!run) {\n throw new Error(`WorkflowRun not found: ${id}`);\n }\n\n if (\n data.expectedVersion !== undefined &&\n run.version !== data.expectedVersion\n ) {\n throw new StaleVersionError(\n \"WorkflowRun\",\n id,\n data.expectedVersion,\n run.version,\n );\n }\n\n const { expectedVersion: _, ...rest } = data;\n const updated: WorkflowRunRecord = {\n ...run,\n ...rest,\n updatedAt: new Date(),\n version: run.version + 1,\n };\n this.runs.set(id, updated);\n }\n\n async getRun(id: string): Promise<WorkflowRunRecord | null> {\n const run = this.runs.get(id);\n return run ? { ...run } : null;\n }\n\n async getRunStatus(id: string): Promise<WorkflowStatus | null> {\n const run = this.runs.get(id);\n return run?.status ?? null;\n }\n\n async getRunsByStatus(status: WorkflowStatus): Promise<WorkflowRunRecord[]> {\n return Array.from(this.runs.values())\n .filter((run) => run.status === status)\n .map((run) => ({ ...run }));\n }\n\n async claimPendingRun(id: string): Promise<boolean> {\n const run = this.runs.get(id);\n if (!run || run.status !== \"PENDING\") {\n return false;\n }\n\n // Atomically update status to RUNNING\n const updated: WorkflowRunRecord = {\n ...run,\n status: \"RUNNING\",\n startedAt: new Date(),\n updatedAt: new Date(),\n version: run.version + 1,\n };\n this.runs.set(id, updated);\n return true;\n }\n\n async claimNextPendingRun(): Promise<WorkflowRunRecord | null> {\n // Find all pending runs\n const pendingRuns = Array.from(this.runs.values())\n .filter((run) => run.status === \"PENDING\")\n // Sort by priority (highest first), then by createdAt (oldest first - FIFO)\n .sort((a, b) => {\n if (a.priority !== b.priority) {\n return b.priority - a.priority; // Higher priority first\n }\n return a.createdAt.getTime() - b.createdAt.getTime(); // Oldest first\n });\n\n if (pendingRuns.length === 0) {\n return null;\n }\n\n // Get the first one and atomically claim it\n const runToClaim = pendingRuns[0];\n\n // Double-check it's still pending (simulates FOR UPDATE SKIP LOCKED behavior)\n const currentRun = this.runs.get(runToClaim.id);\n if (!currentRun || currentRun.status !== \"PENDING\") {\n // Another worker claimed it between our query and now\n // In real FOR UPDATE SKIP LOCKED, this row would be skipped\n // Try the next one recursively\n return this.claimNextPendingRun();\n }\n\n // Atomically update status to RUNNING\n const claimed: WorkflowRunRecord = {\n ...currentRun,\n status: \"RUNNING\",\n startedAt: new Date(),\n updatedAt: new Date(),\n version: currentRun.version + 1,\n };\n this.runs.set(claimed.id, claimed);\n\n return { ...claimed };\n }\n\n // ============================================================================\n // WorkflowStage Operations\n // ============================================================================\n\n async createStage(data: CreateStageInput): Promise<WorkflowStageRecord> {\n const now = new Date();\n const id = randomUUID();\n const record: WorkflowStageRecord = {\n id,\n createdAt: now,\n updatedAt: now,\n version: 1,\n workflowRunId: data.workflowRunId,\n stageId: data.stageId,\n stageName: data.stageName,\n stageNumber: data.stageNumber,\n executionGroup: data.executionGroup,\n status: data.status ?? \"PENDING\",\n startedAt: data.startedAt ?? null,\n completedAt: null,\n duration: null,\n inputData: data.inputData ?? null,\n outputData: null,\n config: data.config ?? null,\n suspendedState: null,\n resumeData: null,\n nextPollAt: null,\n pollInterval: null,\n maxWaitUntil: null,\n metrics: null,\n embeddingInfo: null,\n errorMessage: null,\n };\n\n this.stages.set(id, record);\n // Also index by composite key for lookups\n this.stages.set(this.stageKey(data.workflowRunId, data.stageId), record);\n return { ...record };\n }\n\n async upsertStage(data: UpsertStageInput): Promise<WorkflowStageRecord> {\n const key = this.stageKey(data.workflowRunId, data.stageId);\n const existing = this.stages.get(key);\n\n if (existing) {\n const updated: WorkflowStageRecord = {\n ...existing,\n ...data.update,\n updatedAt: new Date(),\n version: existing.version + 1,\n };\n this.stages.set(existing.id, updated);\n this.stages.set(key, updated);\n return { ...updated };\n } else {\n return this.createStage(data.create);\n }\n }\n\n async updateStage(id: string, data: UpdateStageInput): Promise<void> {\n const stage = this.stages.get(id);\n if (!stage) {\n throw new Error(`WorkflowStage not found: ${id}`);\n }\n\n if (\n data.expectedVersion !== undefined &&\n stage.version !== data.expectedVersion\n ) {\n throw new StaleVersionError(\n \"WorkflowStage\",\n id,\n data.expectedVersion,\n stage.version,\n );\n }\n\n const { expectedVersion: _, ...rest } = data;\n const updated: WorkflowStageRecord = {\n ...stage,\n ...rest,\n updatedAt: new Date(),\n version: stage.version + 1,\n };\n this.stages.set(id, updated);\n this.stages.set(this.stageKey(stage.workflowRunId, stage.stageId), updated);\n }\n\n async updateStageByRunAndStageId(\n workflowRunId: string,\n stageId: string,\n data: UpdateStageInput,\n ): Promise<void> {\n const key = this.stageKey(workflowRunId, stageId);\n const stage = this.stages.get(key);\n if (!stage) {\n throw new Error(`WorkflowStage not found: ${workflowRunId}/${stageId}`);\n }\n\n if (\n data.expectedVersion !== undefined &&\n stage.version !== data.expectedVersion\n ) {\n throw new StaleVersionError(\n \"WorkflowStage\",\n `${workflowRunId}/${stageId}`,\n data.expectedVersion,\n stage.version,\n );\n }\n\n const { expectedVersion: _, ...rest } = data;\n const updated: WorkflowStageRecord = {\n ...stage,\n ...rest,\n updatedAt: new Date(),\n version: stage.version + 1,\n };\n this.stages.set(stage.id, updated);\n this.stages.set(key, updated);\n }\n\n async getStage(\n runId: string,\n stageId: string,\n ): Promise<WorkflowStageRecord | null> {\n const key = this.stageKey(runId, stageId);\n const stage = this.stages.get(key);\n return stage ? { ...stage } : null;\n }\n\n async getStageById(id: string): Promise<WorkflowStageRecord | null> {\n const stage = this.stages.get(id);\n return stage ? { ...stage } : null;\n }\n\n async getStagesByRun(\n runId: string,\n options?: { status?: WorkflowStageStatus; orderBy?: \"asc\" | \"desc\" },\n ): Promise<WorkflowStageRecord[]> {\n // Use a Set to track seen IDs and avoid duplicates from composite keys\n const seenIds = new Set<string>();\n let stages = Array.from(this.stages.values()).filter((s) => {\n if (s.workflowRunId !== runId) return false;\n if (seenIds.has(s.id)) return false;\n seenIds.add(s.id);\n return true;\n });\n\n if (options?.status) {\n stages = stages.filter((s) => s.status === options.status);\n }\n\n // Sort by stageNumber\n stages.sort((a, b) => {\n const diff = a.stageNumber - b.stageNumber;\n return options?.orderBy === \"desc\" ? -diff : diff;\n });\n\n return stages.map((s) => ({ ...s }));\n }\n\n async getSuspendedStages(beforeDate: Date): Promise<WorkflowStageRecord[]> {\n const seenIds = new Set<string>();\n return Array.from(this.stages.values())\n .filter((s) => {\n if (seenIds.has(s.id)) return false;\n seenIds.add(s.id);\n return (\n s.status === \"SUSPENDED\" &&\n s.nextPollAt !== null &&\n s.nextPollAt <= beforeDate\n );\n })\n .map((s) => ({ ...s }));\n }\n\n async getFirstSuspendedStageReadyToResume(\n runId: string,\n ): Promise<WorkflowStageRecord | null> {\n const stages = await this.getStagesByRun(runId, { status: \"SUSPENDED\" });\n const now = new Date();\n const ready = stages.find((s) => s.nextPollAt && s.nextPollAt <= now);\n return ready ?? null;\n }\n\n async getFirstFailedStage(\n runId: string,\n ): Promise<WorkflowStageRecord | null> {\n const stages = await this.getStagesByRun(runId, { status: \"FAILED\" });\n return stages[0] ?? null;\n }\n\n async getLastCompletedStage(\n runId: string,\n ): Promise<WorkflowStageRecord | null> {\n const stages = await this.getStagesByRun(runId, {\n status: \"COMPLETED\",\n orderBy: \"desc\",\n });\n return stages[0] ?? null;\n }\n\n async getLastCompletedStageBefore(\n runId: string,\n executionGroup: number,\n ): Promise<WorkflowStageRecord | null> {\n const stages = await this.getStagesByRun(runId, {\n status: \"COMPLETED\",\n orderBy: \"desc\",\n });\n const before = stages.filter((s) => s.executionGroup < executionGroup);\n return before[0] ?? null;\n }\n\n async deleteStage(id: string): Promise<void> {\n const stage = this.stages.get(id);\n if (stage) {\n this.stages.delete(id);\n this.stages.delete(this.stageKey(stage.workflowRunId, stage.stageId));\n }\n }\n\n // ============================================================================\n // WorkflowLog Operations\n // ============================================================================\n\n async createLog(data: CreateLogInput): Promise<void> {\n const record: WorkflowLogRecord = {\n id: randomUUID(),\n createdAt: new Date(),\n workflowRunId: data.workflowRunId ?? null,\n workflowStageId: data.workflowStageId ?? null,\n level: data.level,\n message: data.message,\n metadata: data.metadata ?? null,\n };\n this.logs.set(record.id, record);\n }\n\n // ============================================================================\n // Outbox Operations\n // ============================================================================\n\n async appendOutboxEvents(events: CreateOutboxEventInput[]): Promise<void> {\n for (const event of events) {\n const currentSeq = this.outboxSequences.get(event.workflowRunId) ?? 0;\n const nextSeq = currentSeq + 1;\n this.outboxSequences.set(event.workflowRunId, nextSeq);\n\n const record: OutboxRecord = {\n id: randomUUID(),\n workflowRunId: event.workflowRunId,\n sequence: nextSeq,\n eventType: event.eventType,\n payload: event.payload,\n causationId: event.causationId,\n occurredAt: event.occurredAt,\n publishedAt: null,\n retryCount: 0,\n dlqAt: null,\n };\n this.outbox.push(record);\n }\n }\n\n async getUnpublishedOutboxEvents(limit?: number): Promise<OutboxRecord[]> {\n const effectiveLimit = limit ?? 100;\n return this.outbox\n .filter((r) => r.publishedAt === null && r.dlqAt === null)\n .sort((a, b) => {\n const runCmp = a.workflowRunId.localeCompare(b.workflowRunId);\n if (runCmp !== 0) return runCmp;\n return a.sequence - b.sequence;\n })\n .slice(0, effectiveLimit)\n .map((r) => ({ ...r }));\n }\n\n async markOutboxEventsPublished(ids: string[]): Promise<void> {\n const idSet = new Set(ids);\n for (const record of this.outbox) {\n if (idSet.has(record.id)) {\n record.publishedAt = new Date();\n }\n }\n }\n\n async incrementOutboxRetryCount(id: string): Promise<number> {\n const record = this.outbox.find((r) => r.id === id);\n if (!record) throw new Error(`Outbox event not found: ${id}`);\n record.retryCount++;\n return record.retryCount;\n }\n\n async moveOutboxEventToDLQ(id: string): Promise<void> {\n const record = this.outbox.find((r) => r.id === id);\n if (!record) throw new Error(`Outbox event not found: ${id}`);\n record.dlqAt = new Date();\n }\n\n async replayDLQEvents(maxEvents: number): Promise<number> {\n const dlqEvents = this.outbox\n .filter((r) => r.dlqAt !== null)\n .slice(0, maxEvents);\n for (const record of dlqEvents) {\n record.dlqAt = null;\n record.retryCount = 0;\n }\n return dlqEvents.length;\n }\n\n // ============================================================================\n // Idempotency Operations\n // ============================================================================\n\n async acquireIdempotencyKey(\n key: string,\n commandType: string,\n ): Promise<\n | { status: \"acquired\" }\n | { status: \"replay\"; result: unknown }\n | { status: \"in_progress\" }\n > {\n const compositeKey = this.idempotencyCompositeKey(commandType, key);\n const record = this.idempotencyKeys.get(compositeKey);\n if (record) {\n return { status: \"replay\", result: record.result };\n }\n if (this.idempotencyInProgress.has(compositeKey)) {\n return { status: \"in_progress\" };\n }\n this.idempotencyInProgress.add(compositeKey);\n return { status: \"acquired\" };\n }\n\n async completeIdempotencyKey(\n key: string,\n commandType: string,\n result: unknown,\n ): Promise<void> {\n const compositeKey = this.idempotencyCompositeKey(commandType, key);\n this.idempotencyInProgress.delete(compositeKey);\n this.idempotencyKeys.set(compositeKey, {\n key,\n commandType,\n result,\n createdAt: new Date(),\n });\n }\n\n async releaseIdempotencyKey(key: string, commandType: string): Promise<void> {\n this.idempotencyInProgress.delete(\n this.idempotencyCompositeKey(commandType, key),\n );\n }\n\n // ============================================================================\n // WorkflowArtifact Operations\n // ============================================================================\n\n async saveArtifact(data: SaveArtifactInput): Promise<void> {\n const now = new Date();\n const key = this.artifactKey(data.workflowRunId, data.key);\n const existing = this.artifacts.get(key);\n\n const record: WorkflowArtifactRecord = {\n id: existing?.id ?? randomUUID(),\n createdAt: existing?.createdAt ?? now,\n updatedAt: now,\n workflowRunId: data.workflowRunId,\n workflowStageId: data.workflowStageId ?? null,\n key: data.key,\n type: data.type,\n data: data.data,\n size: data.size,\n metadata: data.metadata ?? null,\n };\n this.artifacts.set(key, record);\n }\n\n async loadArtifact(runId: string, key: string): Promise<unknown> {\n const artifact = this.artifacts.get(this.artifactKey(runId, key));\n if (!artifact) {\n throw new Error(`Artifact not found: ${runId}/${key}`);\n }\n return artifact.data;\n }\n\n async hasArtifact(runId: string, key: string): Promise<boolean> {\n return this.artifacts.has(this.artifactKey(runId, key));\n }\n\n async deleteArtifact(runId: string, key: string): Promise<void> {\n this.artifacts.delete(this.artifactKey(runId, key));\n }\n\n async listArtifacts(runId: string): Promise<WorkflowArtifactRecord[]> {\n return Array.from(this.artifacts.values())\n .filter((a) => a.workflowRunId === runId)\n .map((a) => ({ ...a }));\n }\n\n async getStageIdForArtifact(\n runId: string,\n stageId: string,\n ): Promise<string | null> {\n const stage = await this.getStage(runId, stageId);\n return stage?.id ?? null;\n }\n\n // ============================================================================\n // Stage Output Convenience Method\n // ============================================================================\n\n async saveStageOutput(\n runId: string,\n workflowType: string,\n stageId: string,\n output: unknown,\n ): Promise<string> {\n const key = `workflow-v2/${workflowType}/${runId}/${stageId}/output.json`;\n const stageDbId = await this.getStageIdForArtifact(runId, stageId);\n\n await this.saveArtifact({\n workflowRunId: runId,\n workflowStageId: stageDbId ?? undefined,\n key,\n type: \"STAGE_OUTPUT\",\n data: output,\n size: JSON.stringify(output).length,\n });\n\n return key;\n }\n\n // ============================================================================\n // Test Helpers\n // ============================================================================\n\n /**\n * Clear all data - useful between tests\n */\n clear(): void {\n this.runs.clear();\n this.stages.clear();\n this.logs.clear();\n this.artifacts.clear();\n this.outbox = [];\n this.idempotencyKeys.clear();\n this.idempotencyInProgress.clear();\n this.outboxSequences.clear();\n }\n\n /**\n * Get all runs for inspection\n */\n getAllRuns(): WorkflowRunRecord[] {\n return Array.from(this.runs.values()).map((r) => ({ ...r }));\n }\n\n /**\n * Get all stages for inspection\n */\n getAllStages(): WorkflowStageRecord[] {\n // Filter out composite key duplicates\n return Array.from(this.stages.values())\n .filter((s) => this.stages.get(s.id) === s)\n .map((s) => ({ ...s }));\n }\n\n /**\n * Get all logs for inspection\n */\n getAllLogs(): WorkflowLogRecord[] {\n return Array.from(this.logs.values()).map((l) => ({ ...l }));\n }\n\n /**\n * Get all artifacts for inspection\n */\n getAllArtifacts(): WorkflowArtifactRecord[] {\n return Array.from(this.artifacts.values()).map((a) => ({ ...a }));\n }\n}\n"]}
1
+ {"version":3,"sources":["../../src/testing/in-memory-ai-logger.ts","../../src/testing/in-memory-job-queue.ts","../../src/testing/in-memory-persistence.ts"],"names":["randomUUID"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * In-Memory AI Call Logger\n *\n * A complete in-memory implementation of AICallLogger for testing.\n * Tracks all AI calls with full cost/token tracking and topic-based aggregation.\n *\n * @example\n * ```typescript\n * import { InMemoryAICallLogger } from '@bratsos/workflow-engine/testing';\n *\n * const aiLogger = new InMemoryAICallLogger();\n * // Use in tests...\n * aiLogger.clear(); // Reset between tests\n * ```\n */\n\nimport { randomUUID } from \"crypto\";\nimport type {\n AICallLogger,\n AICallRecord,\n AIHelperStats,\n CreateAICallInput,\n} from \"../persistence/interface.js\";\n\nexport class InMemoryAICallLogger implements AICallLogger {\n private calls = new Map<string, AICallRecord>();\n private recordedBatches = new Set<string>();\n\n // ============================================================================\n // Core Operations\n // ============================================================================\n\n /**\n * Log a single AI call (fire and forget)\n */\n logCall(call: CreateAICallInput): void {\n const id = randomUUID();\n const record: AICallRecord = {\n id,\n createdAt: new Date(),\n topic: call.topic,\n callType: call.callType,\n modelKey: call.modelKey,\n modelId: call.modelId,\n prompt: call.prompt,\n response: call.response,\n inputTokens: call.inputTokens,\n outputTokens: call.outputTokens,\n cost: call.cost,\n metadata: call.metadata ?? null,\n };\n this.calls.set(id, record);\n }\n\n /**\n * Log batch results (for recording batch API results)\n */\n async logBatchResults(\n batchId: string,\n results: CreateAICallInput[],\n ): Promise<void> {\n // Mark batch as recorded\n this.recordedBatches.add(batchId);\n\n // Log each result\n for (const result of results) {\n this.logCall({\n ...result,\n metadata: {\n ...(result.metadata as Record<string, unknown> | undefined),\n batchId,\n },\n });\n }\n }\n\n /**\n * Get aggregated stats for a topic prefix\n */\n async getStats(topicPrefix: string): Promise<AIHelperStats> {\n const matchingCalls = Array.from(this.calls.values()).filter((call) =>\n call.topic.startsWith(topicPrefix),\n );\n\n const stats: AIHelperStats = {\n totalCalls: matchingCalls.length,\n totalInputTokens: 0,\n totalOutputTokens: 0,\n totalCost: 0,\n perModel: {},\n };\n\n for (const call of matchingCalls) {\n stats.totalInputTokens += call.inputTokens;\n stats.totalOutputTokens += call.outputTokens;\n stats.totalCost += call.cost;\n\n // Aggregate per model\n if (!stats.perModel[call.modelKey]) {\n stats.perModel[call.modelKey] = {\n calls: 0,\n inputTokens: 0,\n outputTokens: 0,\n cost: 0,\n };\n }\n stats.perModel[call.modelKey]!.calls++;\n stats.perModel[call.modelKey]!.inputTokens += call.inputTokens;\n stats.perModel[call.modelKey]!.outputTokens += call.outputTokens;\n stats.perModel[call.modelKey]!.cost += call.cost;\n }\n\n return stats;\n }\n\n /**\n * Check if batch results are already recorded\n */\n async isRecorded(batchId: string): Promise<boolean> {\n return this.recordedBatches.has(batchId);\n }\n\n // ============================================================================\n // Test Helpers\n // ============================================================================\n\n /**\n * Clear all data - useful between tests\n */\n clear(): void {\n this.calls.clear();\n this.recordedBatches.clear();\n }\n\n /**\n * Get all calls for inspection\n */\n getAllCalls(): AICallRecord[] {\n return Array.from(this.calls.values()).map((c) => ({ ...c }));\n }\n\n /**\n * Get calls by topic for inspection\n */\n getCallsByTopic(topic: string): AICallRecord[] {\n return Array.from(this.calls.values())\n .filter((c) => c.topic === topic)\n .map((c) => ({ ...c }));\n }\n\n /**\n * Get calls by topic prefix for inspection\n */\n getCallsByTopicPrefix(prefix: string): AICallRecord[] {\n return Array.from(this.calls.values())\n .filter((c) => c.topic.startsWith(prefix))\n .map((c) => ({ ...c }));\n }\n\n /**\n * Get calls by model for inspection\n */\n getCallsByModel(modelKey: string): AICallRecord[] {\n return Array.from(this.calls.values())\n .filter((c) => c.modelKey === modelKey)\n .map((c) => ({ ...c }));\n }\n\n /**\n * Get calls by call type for inspection\n */\n getCallsByType(callType: string): AICallRecord[] {\n return Array.from(this.calls.values())\n .filter((c) => c.callType === callType)\n .map((c) => ({ ...c }));\n }\n\n /**\n * Get total cost across all calls\n */\n getTotalCost(): number {\n let total = 0;\n for (const call of this.calls.values()) {\n total += call.cost;\n }\n return total;\n }\n\n /**\n * Get total tokens across all calls\n */\n getTotalTokens(): { input: number; output: number } {\n let input = 0;\n let output = 0;\n for (const call of this.calls.values()) {\n input += call.inputTokens;\n output += call.outputTokens;\n }\n return { input, output };\n }\n\n /**\n * Get call count\n */\n getCallCount(): number {\n return this.calls.size;\n }\n\n /**\n * Get all recorded batch IDs\n */\n getRecordedBatchIds(): string[] {\n return Array.from(this.recordedBatches);\n }\n\n /**\n * Get the last call made (useful for assertions)\n */\n getLastCall(): AICallRecord | null {\n const calls = Array.from(this.calls.values());\n if (calls.length === 0) return null;\n\n // Sort by createdAt descending\n calls.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());\n return { ...calls[0]! };\n }\n\n /**\n * Assert a call was made with specific properties\n */\n hasCallMatching(predicate: (call: AICallRecord) => boolean): boolean {\n return Array.from(this.calls.values()).some(predicate);\n }\n}\n","/**\n * In-Memory Job Queue\n *\n * A complete in-memory implementation of JobQueue for testing.\n * Supports priority ordering, locking, and stale job recovery.\n *\n * @example\n * ```typescript\n * import { InMemoryJobQueue } from '@bratsos/workflow-engine/testing';\n *\n * const jobQueue = new InMemoryJobQueue();\n * // Use in tests...\n * jobQueue.clear(); // Reset between tests\n * ```\n */\n\nimport { randomUUID } from \"crypto\";\nimport type {\n DequeueResult,\n EnqueueJobInput,\n JobQueue,\n JobRecord,\n JobStatus,\n} from \"../persistence/interface.js\";\n\nexport class InMemoryJobQueue implements JobQueue {\n private jobs = new Map<string, JobRecord>();\n private workerId: string;\n private defaultMaxAttempts = 3;\n\n constructor(workerId?: string) {\n this.workerId = workerId ?? `worker-${randomUUID().slice(0, 8)}`;\n }\n\n // ============================================================================\n // Core Operations\n // ============================================================================\n\n async enqueue(options: EnqueueJobInput): Promise<string> {\n const now = new Date();\n const id = randomUUID();\n\n const job: JobRecord = {\n id,\n createdAt: now,\n updatedAt: now,\n workflowRunId: options.workflowRunId,\n workflowId: options.workflowId,\n stageId: options.stageId,\n status: \"PENDING\",\n priority: options.priority ?? 5,\n workerId: null,\n lockedAt: null,\n startedAt: null,\n completedAt: null,\n attempt: 1,\n maxAttempts: this.defaultMaxAttempts,\n lastError: null,\n nextPollAt: options.scheduledFor ?? null,\n payload: options.payload ?? {},\n };\n\n this.jobs.set(id, job);\n return id;\n }\n\n async enqueueParallel(jobs: EnqueueJobInput[]): Promise<string[]> {\n const ids: string[] = [];\n for (const job of jobs) {\n const id = await this.enqueue(job);\n ids.push(id);\n }\n return ids;\n }\n\n async dequeue(): Promise<DequeueResult | null> {\n // Find the highest priority PENDING job\n const now = new Date();\n const pendingJobs = Array.from(this.jobs.values())\n .filter(\n (j) =>\n j.status === \"PENDING\" &&\n (j.nextPollAt === null || j.nextPollAt <= now),\n )\n .sort((a, b) => {\n // Higher priority first\n if (b.priority !== a.priority) {\n return b.priority - a.priority;\n }\n // Earlier creation first (FIFO for same priority)\n return a.createdAt.getTime() - b.createdAt.getTime();\n });\n\n if (pendingJobs.length === 0) {\n return null;\n }\n\n const job = pendingJobs[0]!;\n\n // Lock the job\n const updated: JobRecord = {\n ...job,\n status: \"RUNNING\",\n workerId: this.workerId,\n lockedAt: now,\n startedAt: now,\n updatedAt: now,\n };\n this.jobs.set(job.id, updated);\n\n return {\n jobId: job.id,\n workflowRunId: job.workflowRunId,\n workflowId: job.workflowId,\n stageId: job.stageId,\n priority: job.priority,\n attempt: job.attempt,\n maxAttempts: job.maxAttempts,\n payload: job.payload,\n };\n }\n\n async complete(jobId: string): Promise<void> {\n const job = this.jobs.get(jobId);\n if (!job) {\n throw new Error(`Job not found: ${jobId}`);\n }\n\n const now = new Date();\n const updated: JobRecord = {\n ...job,\n status: \"COMPLETED\",\n completedAt: now,\n updatedAt: now,\n };\n this.jobs.set(jobId, updated);\n }\n\n async suspend(jobId: string, nextPollAt: Date): Promise<void> {\n const job = this.jobs.get(jobId);\n if (!job) {\n throw new Error(`Job not found: ${jobId}`);\n }\n\n const updated: JobRecord = {\n ...job,\n status: \"SUSPENDED\",\n nextPollAt,\n workerId: null,\n lockedAt: null,\n updatedAt: new Date(),\n };\n this.jobs.set(jobId, updated);\n }\n\n async fail(\n jobId: string,\n error: string,\n shouldRetry: boolean = true,\n ): Promise<void> {\n const job = this.jobs.get(jobId);\n if (!job) {\n throw new Error(`Job not found: ${jobId}`);\n }\n\n const now = new Date();\n\n if (shouldRetry && job.attempt < job.maxAttempts) {\n // Retry: move back to PENDING with incremented attempt\n const updated: JobRecord = {\n ...job,\n status: \"PENDING\",\n attempt: job.attempt + 1,\n lastError: error,\n workerId: null,\n lockedAt: null,\n updatedAt: now,\n };\n this.jobs.set(jobId, updated);\n } else {\n // No more retries: mark as FAILED\n const updated: JobRecord = {\n ...job,\n status: \"FAILED\",\n lastError: error,\n completedAt: now,\n updatedAt: now,\n };\n this.jobs.set(jobId, updated);\n }\n }\n\n async getSuspendedJobsReadyToPoll(): Promise<\n Array<{ jobId: string; stageId: string; workflowRunId: string }>\n > {\n const now = new Date();\n return Array.from(this.jobs.values())\n .filter(\n (j) => j.status === \"SUSPENDED\" && j.nextPollAt && j.nextPollAt <= now,\n )\n .map((j) => ({\n jobId: j.id,\n stageId: j.stageId,\n workflowRunId: j.workflowRunId,\n }));\n }\n\n async releaseStaleJobs(staleThresholdMs: number = 60000): Promise<number> {\n const now = new Date();\n const threshold = new Date(now.getTime() - staleThresholdMs);\n let released = 0;\n\n for (const job of this.jobs.values()) {\n if (\n job.status === \"RUNNING\" &&\n job.lockedAt &&\n job.lockedAt < threshold\n ) {\n // Release the stale lock\n const updated: JobRecord = {\n ...job,\n status: \"PENDING\",\n workerId: null,\n lockedAt: null,\n updatedAt: now,\n };\n this.jobs.set(job.id, updated);\n released++;\n }\n }\n\n return released;\n }\n\n // ============================================================================\n // Test Helpers\n // ============================================================================\n\n /**\n * Clear all jobs - useful between tests\n */\n clear(): void {\n this.jobs.clear();\n }\n\n /**\n * Get all jobs for inspection\n */\n getAllJobs(): JobRecord[] {\n return Array.from(this.jobs.values()).map((j) => ({ ...j }));\n }\n\n /**\n * Get jobs by status for inspection\n */\n getJobsByStatus(status: JobStatus): JobRecord[] {\n return Array.from(this.jobs.values())\n .filter((j) => j.status === status)\n .map((j) => ({ ...j }));\n }\n\n /**\n * Get a specific job by ID\n */\n getJob(jobId: string): JobRecord | null {\n const job = this.jobs.get(jobId);\n return job ? { ...job } : null;\n }\n\n /**\n * Get the worker ID for this queue instance\n */\n getWorkerId(): string {\n return this.workerId;\n }\n\n /**\n * Set max attempts for new jobs\n */\n setDefaultMaxAttempts(maxAttempts: number): void {\n this.defaultMaxAttempts = maxAttempts;\n }\n\n /**\n * Simulate a worker crash by releasing a job's lock without completing it\n */\n simulateCrash(jobId: string): void {\n const job = this.jobs.get(jobId);\n if (job && job.status === \"RUNNING\") {\n // Don't change status - just leave it locked by the \"crashed\" worker\n // releaseStaleJobs() will clean it up\n }\n }\n\n /**\n * Move a suspended job back to pending (for manual resume testing)\n */\n resumeJob(jobId: string): void {\n const job = this.jobs.get(jobId);\n if (job && job.status === \"SUSPENDED\") {\n const updated: JobRecord = {\n ...job,\n status: \"PENDING\",\n nextPollAt: null,\n updatedAt: new Date(),\n };\n this.jobs.set(jobId, updated);\n }\n }\n\n /**\n * Set lockedAt for testing stale job scenarios\n */\n setJobLockedAt(jobId: string, lockedAt: Date): void {\n const job = this.jobs.get(jobId);\n if (job) {\n const updated: JobRecord = {\n ...job,\n lockedAt,\n };\n this.jobs.set(jobId, updated);\n }\n }\n\n /**\n * Set nextPollAt for testing suspended job polling\n */\n setJobNextPollAt(jobId: string, nextPollAt: Date | null): void {\n const job = this.jobs.get(jobId);\n if (job) {\n const updated: JobRecord = {\n ...job,\n nextPollAt,\n };\n this.jobs.set(jobId, updated);\n }\n }\n}\n","/**\n * In-Memory Workflow Persistence\n *\n * A complete in-memory implementation of WorkflowPersistence for testing.\n * All data is stored in Maps and lost when the instance is garbage collected.\n *\n * @example\n * ```typescript\n * import { InMemoryWorkflowPersistence } from '@bratsos/workflow-engine/testing';\n *\n * const persistence = new InMemoryWorkflowPersistence();\n * // Use in tests...\n * persistence.clear(); // Reset between tests\n * ```\n */\n\nimport { randomUUID } from \"crypto\";\nimport {\n type CreateLogInput,\n type CreateOutboxEventInput,\n type CreateRunInput,\n type CreateStageInput,\n type IdempotencyRecord,\n type OutboxRecord,\n type SaveArtifactInput,\n StaleVersionError,\n type UpdateRunInput,\n type UpdateStageInput,\n type UpsertStageInput,\n type WorkflowArtifactRecord,\n type WorkflowLogRecord,\n type WorkflowPersistence,\n type WorkflowRunRecord,\n type WorkflowStageRecord,\n type WorkflowStageStatus,\n type WorkflowStatus,\n} from \"../persistence/interface.js\";\n\nexport class InMemoryWorkflowPersistence implements WorkflowPersistence {\n private runs = new Map<string, WorkflowRunRecord>();\n private stages = new Map<string, WorkflowStageRecord>();\n private logs = new Map<string, WorkflowLogRecord>();\n private artifacts = new Map<string, WorkflowArtifactRecord>();\n private outbox: OutboxRecord[] = [];\n private idempotencyKeys = new Map<string, IdempotencyRecord>();\n private idempotencyInProgress = new Set<string>();\n private outboxSequences = new Map<string, number>();\n\n // Helper to generate composite keys for stages\n private stageKey(runId: string, stageId: string): string {\n return `${runId}:${stageId}`;\n }\n\n // Helper to generate composite keys for artifacts\n private artifactKey(runId: string, key: string): string {\n return `${runId}:${key}`;\n }\n\n private idempotencyCompositeKey(commandType: string, key: string): string {\n return `${commandType}:${key}`;\n }\n\n async withTransaction<T>(\n fn: (tx: WorkflowPersistence) => Promise<T>,\n ): Promise<T> {\n return fn(this);\n }\n\n // ============================================================================\n // WorkflowRun Operations\n // ============================================================================\n\n async createRun(data: CreateRunInput): Promise<WorkflowRunRecord> {\n const now = new Date();\n const record: WorkflowRunRecord = {\n id: data.id ?? randomUUID(),\n createdAt: now,\n updatedAt: now,\n version: 1,\n workflowId: data.workflowId,\n workflowName: data.workflowName,\n workflowType: data.workflowType,\n status: \"PENDING\",\n startedAt: null,\n completedAt: null,\n duration: null,\n input: data.input,\n output: null,\n config: data.config ?? {},\n totalCost: 0,\n totalTokens: 0,\n priority: data.priority ?? 5,\n };\n this.runs.set(record.id, record);\n return { ...record };\n }\n\n async updateRun(id: string, data: UpdateRunInput): Promise<void> {\n const run = this.runs.get(id);\n if (!run) {\n throw new Error(`WorkflowRun not found: ${id}`);\n }\n\n if (\n data.expectedVersion !== undefined &&\n run.version !== data.expectedVersion\n ) {\n throw new StaleVersionError(\n \"WorkflowRun\",\n id,\n data.expectedVersion,\n run.version,\n );\n }\n\n const { expectedVersion: _, ...rest } = data;\n const updated: WorkflowRunRecord = {\n ...run,\n ...rest,\n updatedAt: new Date(),\n version: run.version + 1,\n };\n this.runs.set(id, updated);\n }\n\n async getRun(id: string): Promise<WorkflowRunRecord | null> {\n const run = this.runs.get(id);\n return run ? { ...run } : null;\n }\n\n async getRunStatus(id: string): Promise<WorkflowStatus | null> {\n const run = this.runs.get(id);\n return run?.status ?? null;\n }\n\n async getRunsByStatus(status: WorkflowStatus): Promise<WorkflowRunRecord[]> {\n return Array.from(this.runs.values())\n .filter((run) => run.status === status)\n .map((run) => ({ ...run }));\n }\n\n async getStuckRuns(stuckSince: Date): Promise<WorkflowRunRecord[]> {\n const runningRuns = await this.getRunsByStatus(\"RUNNING\");\n return runningRuns.filter((run) => {\n // Find all stages for this run (deduplicate by ID since stages are stored with composite keys)\n const seenIds = new Set<string>();\n const stages = Array.from(this.stages.values()).filter((s) => {\n if (s.workflowRunId !== run.id) return false;\n if (seenIds.has(s.id)) return false;\n seenIds.add(s.id);\n return true;\n });\n const lastStageUpdate = stages.reduce(\n (max, s) => (s.updatedAt > max ? s.updatedAt : max),\n new Date(0),\n );\n const lastActivity =\n run.updatedAt > lastStageUpdate ? run.updatedAt : lastStageUpdate;\n return lastActivity <= stuckSince;\n });\n }\n\n async claimPendingRun(id: string): Promise<boolean> {\n const run = this.runs.get(id);\n if (!run || run.status !== \"PENDING\") {\n return false;\n }\n\n // Atomically update status to RUNNING\n const updated: WorkflowRunRecord = {\n ...run,\n status: \"RUNNING\",\n startedAt: new Date(),\n updatedAt: new Date(),\n version: run.version + 1,\n };\n this.runs.set(id, updated);\n return true;\n }\n\n async claimNextPendingRun(): Promise<WorkflowRunRecord | null> {\n // Find all pending runs\n const pendingRuns = Array.from(this.runs.values())\n .filter((run) => run.status === \"PENDING\")\n // Sort by priority (highest first), then by createdAt (oldest first - FIFO)\n .sort((a, b) => {\n if (a.priority !== b.priority) {\n return b.priority - a.priority; // Higher priority first\n }\n return a.createdAt.getTime() - b.createdAt.getTime(); // Oldest first\n });\n\n if (pendingRuns.length === 0) {\n return null;\n }\n\n // Get the first one and atomically claim it\n const runToClaim = pendingRuns[0];\n\n // Double-check it's still pending (simulates FOR UPDATE SKIP LOCKED behavior)\n const currentRun = this.runs.get(runToClaim.id);\n if (!currentRun || currentRun.status !== \"PENDING\") {\n // Another worker claimed it between our query and now\n // In real FOR UPDATE SKIP LOCKED, this row would be skipped\n // Try the next one recursively\n return this.claimNextPendingRun();\n }\n\n // Atomically update status to RUNNING\n const claimed: WorkflowRunRecord = {\n ...currentRun,\n status: \"RUNNING\",\n startedAt: new Date(),\n updatedAt: new Date(),\n version: currentRun.version + 1,\n };\n this.runs.set(claimed.id, claimed);\n\n return { ...claimed };\n }\n\n // ============================================================================\n // WorkflowStage Operations\n // ============================================================================\n\n async createStage(data: CreateStageInput): Promise<WorkflowStageRecord> {\n const now = new Date();\n const id = randomUUID();\n const record: WorkflowStageRecord = {\n id,\n createdAt: now,\n updatedAt: now,\n version: 1,\n workflowRunId: data.workflowRunId,\n stageId: data.stageId,\n stageName: data.stageName,\n stageNumber: data.stageNumber,\n executionGroup: data.executionGroup,\n status: data.status ?? \"PENDING\",\n startedAt: data.startedAt ?? null,\n completedAt: null,\n duration: null,\n inputData: data.inputData ?? null,\n outputData: null,\n config: data.config ?? null,\n suspendedState: null,\n resumeData: null,\n nextPollAt: null,\n pollInterval: null,\n maxWaitUntil: null,\n metrics: null,\n embeddingInfo: null,\n errorMessage: null,\n };\n\n this.stages.set(id, record);\n // Also index by composite key for lookups\n this.stages.set(this.stageKey(data.workflowRunId, data.stageId), record);\n return { ...record };\n }\n\n async upsertStage(data: UpsertStageInput): Promise<WorkflowStageRecord> {\n const key = this.stageKey(data.workflowRunId, data.stageId);\n const existing = this.stages.get(key);\n\n if (existing) {\n const updated: WorkflowStageRecord = {\n ...existing,\n ...data.update,\n updatedAt: new Date(),\n version: existing.version + 1,\n };\n this.stages.set(existing.id, updated);\n this.stages.set(key, updated);\n return { ...updated };\n } else {\n return this.createStage(data.create);\n }\n }\n\n async updateStage(id: string, data: UpdateStageInput): Promise<void> {\n const stage = this.stages.get(id);\n if (!stage) {\n throw new Error(`WorkflowStage not found: ${id}`);\n }\n\n if (\n data.expectedVersion !== undefined &&\n stage.version !== data.expectedVersion\n ) {\n throw new StaleVersionError(\n \"WorkflowStage\",\n id,\n data.expectedVersion,\n stage.version,\n );\n }\n\n const { expectedVersion: _, ...rest } = data;\n const updated: WorkflowStageRecord = {\n ...stage,\n ...rest,\n updatedAt: new Date(),\n version: stage.version + 1,\n };\n this.stages.set(id, updated);\n this.stages.set(this.stageKey(stage.workflowRunId, stage.stageId), updated);\n }\n\n async updateStageByRunAndStageId(\n workflowRunId: string,\n stageId: string,\n data: UpdateStageInput,\n ): Promise<void> {\n const key = this.stageKey(workflowRunId, stageId);\n const stage = this.stages.get(key);\n if (!stage) {\n throw new Error(`WorkflowStage not found: ${workflowRunId}/${stageId}`);\n }\n\n if (\n data.expectedVersion !== undefined &&\n stage.version !== data.expectedVersion\n ) {\n throw new StaleVersionError(\n \"WorkflowStage\",\n `${workflowRunId}/${stageId}`,\n data.expectedVersion,\n stage.version,\n );\n }\n\n const { expectedVersion: _, ...rest } = data;\n const updated: WorkflowStageRecord = {\n ...stage,\n ...rest,\n updatedAt: new Date(),\n version: stage.version + 1,\n };\n this.stages.set(stage.id, updated);\n this.stages.set(key, updated);\n }\n\n async getStage(\n runId: string,\n stageId: string,\n ): Promise<WorkflowStageRecord | null> {\n const key = this.stageKey(runId, stageId);\n const stage = this.stages.get(key);\n return stage ? { ...stage } : null;\n }\n\n async getStageById(id: string): Promise<WorkflowStageRecord | null> {\n const stage = this.stages.get(id);\n return stage ? { ...stage } : null;\n }\n\n async getStagesByRun(\n runId: string,\n options?: { status?: WorkflowStageStatus; orderBy?: \"asc\" | \"desc\" },\n ): Promise<WorkflowStageRecord[]> {\n // Use a Set to track seen IDs and avoid duplicates from composite keys\n const seenIds = new Set<string>();\n let stages = Array.from(this.stages.values()).filter((s) => {\n if (s.workflowRunId !== runId) return false;\n if (seenIds.has(s.id)) return false;\n seenIds.add(s.id);\n return true;\n });\n\n if (options?.status) {\n stages = stages.filter((s) => s.status === options.status);\n }\n\n // Sort by stageNumber\n stages.sort((a, b) => {\n const diff = a.stageNumber - b.stageNumber;\n return options?.orderBy === \"desc\" ? -diff : diff;\n });\n\n return stages.map((s) => ({ ...s }));\n }\n\n async getSuspendedStages(beforeDate: Date): Promise<WorkflowStageRecord[]> {\n const seenIds = new Set<string>();\n return Array.from(this.stages.values())\n .filter((s) => {\n if (seenIds.has(s.id)) return false;\n seenIds.add(s.id);\n return (\n s.status === \"SUSPENDED\" &&\n s.nextPollAt !== null &&\n s.nextPollAt <= beforeDate\n );\n })\n .map((s) => ({ ...s }));\n }\n\n async getFirstSuspendedStageReadyToResume(\n runId: string,\n ): Promise<WorkflowStageRecord | null> {\n const stages = await this.getStagesByRun(runId, { status: \"SUSPENDED\" });\n const now = new Date();\n const ready = stages.find((s) => s.nextPollAt && s.nextPollAt <= now);\n return ready ?? null;\n }\n\n async getFirstFailedStage(\n runId: string,\n ): Promise<WorkflowStageRecord | null> {\n const stages = await this.getStagesByRun(runId, { status: \"FAILED\" });\n return stages[0] ?? null;\n }\n\n async getLastCompletedStage(\n runId: string,\n ): Promise<WorkflowStageRecord | null> {\n const stages = await this.getStagesByRun(runId, {\n status: \"COMPLETED\",\n orderBy: \"desc\",\n });\n return stages[0] ?? null;\n }\n\n async getLastCompletedStageBefore(\n runId: string,\n executionGroup: number,\n ): Promise<WorkflowStageRecord | null> {\n const stages = await this.getStagesByRun(runId, {\n status: \"COMPLETED\",\n orderBy: \"desc\",\n });\n const before = stages.filter((s) => s.executionGroup < executionGroup);\n return before[0] ?? null;\n }\n\n async deleteStage(id: string): Promise<void> {\n const stage = this.stages.get(id);\n if (stage) {\n this.stages.delete(id);\n this.stages.delete(this.stageKey(stage.workflowRunId, stage.stageId));\n }\n }\n\n // ============================================================================\n // WorkflowLog Operations\n // ============================================================================\n\n async createLog(data: CreateLogInput): Promise<void> {\n const record: WorkflowLogRecord = {\n id: randomUUID(),\n createdAt: new Date(),\n workflowRunId: data.workflowRunId ?? null,\n workflowStageId: data.workflowStageId ?? null,\n level: data.level,\n message: data.message,\n metadata: data.metadata ?? null,\n };\n this.logs.set(record.id, record);\n }\n\n // ============================================================================\n // Outbox Operations\n // ============================================================================\n\n async appendOutboxEvents(events: CreateOutboxEventInput[]): Promise<void> {\n for (const event of events) {\n const currentSeq = this.outboxSequences.get(event.workflowRunId) ?? 0;\n const nextSeq = currentSeq + 1;\n this.outboxSequences.set(event.workflowRunId, nextSeq);\n\n const record: OutboxRecord = {\n id: randomUUID(),\n workflowRunId: event.workflowRunId,\n sequence: nextSeq,\n eventType: event.eventType,\n payload: event.payload,\n causationId: event.causationId,\n occurredAt: event.occurredAt,\n publishedAt: null,\n retryCount: 0,\n dlqAt: null,\n };\n this.outbox.push(record);\n }\n }\n\n async getUnpublishedOutboxEvents(limit?: number): Promise<OutboxRecord[]> {\n const effectiveLimit = limit ?? 100;\n return this.outbox\n .filter((r) => r.publishedAt === null && r.dlqAt === null)\n .sort((a, b) => {\n const runCmp = a.workflowRunId.localeCompare(b.workflowRunId);\n if (runCmp !== 0) return runCmp;\n return a.sequence - b.sequence;\n })\n .slice(0, effectiveLimit)\n .map((r) => ({ ...r }));\n }\n\n async markOutboxEventsPublished(ids: string[]): Promise<void> {\n const idSet = new Set(ids);\n for (const record of this.outbox) {\n if (idSet.has(record.id)) {\n record.publishedAt = new Date();\n }\n }\n }\n\n async incrementOutboxRetryCount(id: string): Promise<number> {\n const record = this.outbox.find((r) => r.id === id);\n if (!record) throw new Error(`Outbox event not found: ${id}`);\n record.retryCount++;\n return record.retryCount;\n }\n\n async moveOutboxEventToDLQ(id: string): Promise<void> {\n const record = this.outbox.find((r) => r.id === id);\n if (!record) throw new Error(`Outbox event not found: ${id}`);\n record.dlqAt = new Date();\n }\n\n async replayDLQEvents(maxEvents: number): Promise<number> {\n const dlqEvents = this.outbox\n .filter((r) => r.dlqAt !== null)\n .slice(0, maxEvents);\n for (const record of dlqEvents) {\n record.dlqAt = null;\n record.retryCount = 0;\n }\n return dlqEvents.length;\n }\n\n // ============================================================================\n // Idempotency Operations\n // ============================================================================\n\n async acquireIdempotencyKey(\n key: string,\n commandType: string,\n ): Promise<\n | { status: \"acquired\" }\n | { status: \"replay\"; result: unknown }\n | { status: \"in_progress\" }\n > {\n const compositeKey = this.idempotencyCompositeKey(commandType, key);\n const record = this.idempotencyKeys.get(compositeKey);\n if (record) {\n return { status: \"replay\", result: record.result };\n }\n if (this.idempotencyInProgress.has(compositeKey)) {\n return { status: \"in_progress\" };\n }\n this.idempotencyInProgress.add(compositeKey);\n return { status: \"acquired\" };\n }\n\n async completeIdempotencyKey(\n key: string,\n commandType: string,\n result: unknown,\n ): Promise<void> {\n const compositeKey = this.idempotencyCompositeKey(commandType, key);\n this.idempotencyInProgress.delete(compositeKey);\n this.idempotencyKeys.set(compositeKey, {\n key,\n commandType,\n result,\n createdAt: new Date(),\n });\n }\n\n async releaseIdempotencyKey(key: string, commandType: string): Promise<void> {\n this.idempotencyInProgress.delete(\n this.idempotencyCompositeKey(commandType, key),\n );\n }\n\n // ============================================================================\n // WorkflowArtifact Operations\n // ============================================================================\n\n async saveArtifact(data: SaveArtifactInput): Promise<void> {\n const now = new Date();\n const key = this.artifactKey(data.workflowRunId, data.key);\n const existing = this.artifacts.get(key);\n\n const record: WorkflowArtifactRecord = {\n id: existing?.id ?? randomUUID(),\n createdAt: existing?.createdAt ?? now,\n updatedAt: now,\n workflowRunId: data.workflowRunId,\n workflowStageId: data.workflowStageId ?? null,\n key: data.key,\n type: data.type,\n data: data.data,\n size: data.size,\n metadata: data.metadata ?? null,\n };\n this.artifacts.set(key, record);\n }\n\n async loadArtifact(runId: string, key: string): Promise<unknown> {\n const artifact = this.artifacts.get(this.artifactKey(runId, key));\n if (!artifact) {\n throw new Error(`Artifact not found: ${runId}/${key}`);\n }\n return artifact.data;\n }\n\n async hasArtifact(runId: string, key: string): Promise<boolean> {\n return this.artifacts.has(this.artifactKey(runId, key));\n }\n\n async deleteArtifact(runId: string, key: string): Promise<void> {\n this.artifacts.delete(this.artifactKey(runId, key));\n }\n\n async listArtifacts(runId: string): Promise<WorkflowArtifactRecord[]> {\n return Array.from(this.artifacts.values())\n .filter((a) => a.workflowRunId === runId)\n .map((a) => ({ ...a }));\n }\n\n async getStageIdForArtifact(\n runId: string,\n stageId: string,\n ): Promise<string | null> {\n const stage = await this.getStage(runId, stageId);\n return stage?.id ?? null;\n }\n\n // ============================================================================\n // Stage Output Convenience Method\n // ============================================================================\n\n async saveStageOutput(\n runId: string,\n workflowType: string,\n stageId: string,\n output: unknown,\n ): Promise<string> {\n const key = `workflow-v2/${workflowType}/${runId}/${stageId}/output.json`;\n const stageDbId = await this.getStageIdForArtifact(runId, stageId);\n\n await this.saveArtifact({\n workflowRunId: runId,\n workflowStageId: stageDbId ?? undefined,\n key,\n type: \"STAGE_OUTPUT\",\n data: output,\n size: JSON.stringify(output).length,\n });\n\n return key;\n }\n\n // ============================================================================\n // Test Helpers\n // ============================================================================\n\n /**\n * Clear all data - useful between tests\n */\n clear(): void {\n this.runs.clear();\n this.stages.clear();\n this.logs.clear();\n this.artifacts.clear();\n this.outbox = [];\n this.idempotencyKeys.clear();\n this.idempotencyInProgress.clear();\n this.outboxSequences.clear();\n }\n\n /**\n * Get all runs for inspection\n */\n getAllRuns(): WorkflowRunRecord[] {\n return Array.from(this.runs.values()).map((r) => ({ ...r }));\n }\n\n /**\n * Get all stages for inspection\n */\n getAllStages(): WorkflowStageRecord[] {\n // Filter out composite key duplicates\n return Array.from(this.stages.values())\n .filter((s) => this.stages.get(s.id) === s)\n .map((s) => ({ ...s }));\n }\n\n /**\n * Get all logs for inspection\n */\n getAllLogs(): WorkflowLogRecord[] {\n return Array.from(this.logs.values()).map((l) => ({ ...l }));\n }\n\n /**\n * Get all artifacts for inspection\n */\n getAllArtifacts(): WorkflowArtifactRecord[] {\n return Array.from(this.artifacts.values()).map((a) => ({ ...a }));\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bratsos/workflow-engine",
3
- "version": "0.3.0",
3
+ "version": "0.4.1",
4
4
  "description": "Type-safe, distributed workflow engine for AI-orchestrated processes with suspend/resume, parallel execution, and cost tracking",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -78,6 +78,7 @@
78
78
  ],
79
79
  "dependencies": {
80
80
  "@ai-sdk/google": "^3.0.1",
81
+ "@ai-sdk/provider": "^3.0.0",
81
82
  "@openrouter/ai-sdk-provider": "^2.1.1",
82
83
  "ai": "^6.0.3",
83
84
  "js-tiktoken": "^1.0.21",