@bratsos/workflow-engine 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +93 -0
  2. package/dist/{chunk-2HEV5ZJL.js → chunk-NANAXHS5.js} +2 -2
  3. package/dist/chunk-NANAXHS5.js.map +1 -0
  4. package/dist/{chunk-Q2XDO3UF.js → chunk-TWYPSP7P.js} +92 -3
  5. package/dist/chunk-TWYPSP7P.js.map +1 -0
  6. package/dist/{chunk-5C7LRNM7.js → chunk-XPWAEYOO.js} +449 -59
  7. package/dist/chunk-XPWAEYOO.js.map +1 -0
  8. package/dist/{client-DYs5wlHp.d.ts → client-YFKVt4p7.d.ts} +3 -3
  9. package/dist/client.d.ts +4 -4
  10. package/dist/conventions/index.d.ts +114 -0
  11. package/dist/conventions/index.js +95 -0
  12. package/dist/conventions/index.js.map +1 -0
  13. package/dist/{events-D_P24UaY.d.ts → events-B3XPPu0c.d.ts} +23 -1
  14. package/dist/{index-aNuJ2QgN.d.ts → index-CL0KmlyW.d.ts} +4 -1
  15. package/dist/index.d.ts +10 -10
  16. package/dist/index.js +3 -3
  17. package/dist/{interface-BeEPzTFy.d.ts → interface-BPz138Hf.d.ts} +108 -1
  18. package/dist/kernel/index.d.ts +6 -6
  19. package/dist/kernel/index.js +2 -2
  20. package/dist/kernel/testing/index.d.ts +3 -3
  21. package/dist/persistence/index.d.ts +2 -2
  22. package/dist/persistence/index.js +2 -2
  23. package/dist/persistence/prisma/index.d.ts +2 -2
  24. package/dist/persistence/prisma/index.js +2 -2
  25. package/dist/{plugins-Cl0WVVrE.d.ts → plugins-zT-aIcEZ.d.ts} +63 -4
  26. package/dist/{ports-swhiWFw4.d.ts → ports-DUL4hlQr.d.ts} +11 -2
  27. package/dist/{stage-_7BKqqUG.d.ts → stage-WuK0mfrC.d.ts} +81 -1
  28. package/dist/testing/index.d.ts +8 -1
  29. package/dist/testing/index.js +86 -1
  30. package/dist/testing/index.js.map +1 -1
  31. package/package.json +6 -1
  32. package/skills/workflow-engine/SKILL.md +58 -1
  33. package/skills/workflow-engine/migrations/README.md +275 -0
  34. package/skills/workflow-engine/migrations/migrate-0.7-to-0.8.md +528 -0
  35. package/skills/workflow-engine/references/10-annotations.md +479 -0
  36. package/dist/chunk-2HEV5ZJL.js.map +0 -1
  37. package/dist/chunk-5C7LRNM7.js.map +0 -1
  38. package/dist/chunk-Q2XDO3UF.js.map +0 -1
@@ -0,0 +1,95 @@
1
+ // src/conventions/index.ts
2
+ function typedKey(key, meta) {
3
+ return {
4
+ key,
5
+ stability: meta?.stability ?? "experimental",
6
+ description: meta?.description
7
+ };
8
+ }
9
+ var Trigger = {
10
+ /** What system or path initiated the run, e.g. `"webhook:zendesk"`, `"manual:cli"`, `"schedule:cron"`. */
11
+ source: typedKey("trigger.source", {
12
+ stability: "stable",
13
+ description: "What system or path initiated this run."
14
+ }),
15
+ /** Run ID of the prior run when this run is a follow-up / retry / chained execution. */
16
+ parentRunId: typedKey("trigger.parent_run_id", {
17
+ stability: "stable",
18
+ description: "Run ID of the prior run when this is a follow-up."
19
+ }),
20
+ /** Free-text reason — `"auto-triage on ticket create"`, `"manual rerun after policy change"`, etc. */
21
+ reason: typedKey("trigger.reason", {
22
+ stability: "stable",
23
+ description: "Free-text rationale for triggering this run."
24
+ }),
25
+ /** Actor kind discriminator — recommended values: `"user"`, `"agent"`, `"system"`. Open string. */
26
+ actorKind: typedKey("trigger.actor.kind", {
27
+ stability: "stable",
28
+ description: "Open string. Recommended: 'user' | 'agent' | 'system'. Use the envelope `actor.kind` for the equivalent on stage-scope annotations."
29
+ }),
30
+ /** Stable identifier for the actor — user email, agent name, service identifier. */
31
+ actorId: typedKey("trigger.actor.id", {
32
+ stability: "stable",
33
+ description: "Stable identifier for the triggering actor."
34
+ })
35
+ };
36
+ var Decision = {
37
+ /** The chosen outcome. Shape is consumer-defined; `unknown` here for flexibility. */
38
+ outcome: typedKey("decision.outcome", {
39
+ stability: "stable",
40
+ description: "The chosen outcome of this decision. Shape is consumer-defined."
41
+ }),
42
+ /** Free-text rationale — why the agent picked this outcome. */
43
+ rationale: typedKey("decision.rationale", {
44
+ stability: "stable",
45
+ description: "Human-readable reason for the decision."
46
+ }),
47
+ /** Confidence score, typically `0`–`1`. */
48
+ confidence: typedKey("decision.confidence", {
49
+ stability: "stable",
50
+ description: "Confidence score for the decision, typically 0\u20131."
51
+ }),
52
+ /** Alternative outcomes that were considered but not selected. */
53
+ alternatives: typedKey("decision.alternatives", {
54
+ stability: "stable",
55
+ description: "Alternative outcomes considered but not selected."
56
+ }),
57
+ /** Whether a fallback heuristic was used (e.g., AI confidence below threshold). */
58
+ usedFallback: typedKey("decision.used_fallback", {
59
+ stability: "experimental",
60
+ description: "Whether the agent fell back to a heuristic after the primary signal was inconclusive."
61
+ })
62
+ };
63
+ var Approval = {
64
+ /** Identifiers of all approvers. Always an array — `["alice"]` for a single approver. */
65
+ approvers: typedKey("approval.approvers", {
66
+ stability: "stable",
67
+ description: "Identifiers of all approvers (always an array, plural-rule)."
68
+ }),
69
+ /** When the approval was recorded. ISO 8601. */
70
+ timestamp: typedKey("approval.timestamp", {
71
+ stability: "stable",
72
+ description: "ISO 8601 timestamp when approval was recorded."
73
+ }),
74
+ /** Version of the policy the approval was checked against. */
75
+ policyVersion: typedKey("approval.policy.version", {
76
+ stability: "experimental",
77
+ description: "Version of the policy the approval was checked against."
78
+ })
79
+ };
80
+ var Revision = {
81
+ /** Run ID this revision supersedes. */
82
+ previousRunId: typedKey("revision.previous_run_id", {
83
+ stability: "stable",
84
+ description: "Run ID this revision explicitly supersedes."
85
+ }),
86
+ /** Why this revision was created. */
87
+ reason: typedKey("revision.reason", {
88
+ stability: "stable",
89
+ description: "Why this revision was created."
90
+ })
91
+ };
92
+
93
+ export { Approval, Decision, Revision, Trigger, typedKey };
94
+ //# sourceMappingURL=index.js.map
95
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/conventions/index.ts"],"names":[],"mappings":";AA2CO,SAAS,QAAA,CACd,KACA,IAAA,EACa;AACb,EAAA,OAAO;AAAA,IACL,GAAA;AAAA,IACA,SAAA,EAAW,MAAM,SAAA,IAAa,cAAA;AAAA,IAC9B,aAAa,IAAA,EAAM;AAAA,GACrB;AACF;AAYO,IAAM,OAAA,GAAU;AAAA;AAAA,EAErB,MAAA,EAAQ,SAAiB,gBAAA,EAAkB;AAAA,IACzC,SAAA,EAAW,QAAA;AAAA,IACX,WAAA,EAAa;AAAA,GACd,CAAA;AAAA;AAAA,EAGD,WAAA,EAAa,SAAiB,uBAAA,EAAyB;AAAA,IACrD,SAAA,EAAW,QAAA;AAAA,IACX,WAAA,EAAa;AAAA,GACd,CAAA;AAAA;AAAA,EAGD,MAAA,EAAQ,SAAiB,gBAAA,EAAkB;AAAA,IACzC,SAAA,EAAW,QAAA;AAAA,IACX,WAAA,EAAa;AAAA,GACd,CAAA;AAAA;AAAA,EAGD,SAAA,EAAW,SAAiB,oBAAA,EAAsB;AAAA,IAChD,SAAA,EAAW,QAAA;AAAA,IACX,WAAA,EACE;AAAA,GACH,CAAA;AAAA;AAAA,EAGD,OAAA,EAAS,SAAiB,kBAAA,EAAoB;AAAA,IAC5C,SAAA,EAAW,QAAA;AAAA,IACX,WAAA,EAAa;AAAA,GACd;AACH;AAaO,IAAM,QAAA,GAAW;AAAA;AAAA,EAEtB,OAAA,EAAS,SAAkB,kBAAA,EAAoB;AAAA,IAC7C,SAAA,EAAW,QAAA;AAAA,IACX,WAAA,EACE;AAAA,GACH,CAAA;AAAA;AAAA,EAGD,SAAA,EAAW,SAAiB,oBAAA,EAAsB;AAAA,IAChD,SAAA,EAAW,QAAA;AAAA,IACX,WAAA,EAAa;AAAA,GACd,CAAA;AAAA;AAAA,EAGD,UAAA,EAAY,SAAiB,qBAAA,EAAuB;AAAA,IAClD,SAAA,EAAW,QAAA;AAAA,IACX,WAAA,EAAa;AAAA,GACd,CAAA;AAAA;AAAA,EAGD,YAAA,EAAc,SAAoB,uBAAA,EAAyB;AAAA,IACzD,SAAA,EAAW,QAAA;AAAA,IACX,WAAA,EAAa;AAAA,GACd,CAAA;AAAA;AAAA,EAGD,YAAA,EAAc,SAAkB,wBAAA,EAA0B;AAAA,IACxD,SAAA,EAAW,cAAA;AAAA,IACX,WAAA,EACE;AAAA,GACH;AACH;AAYO,IAAM,QAAA,GAAW;AAAA;AAAA,EAEtB,SAAA,EAAW,SAAmB,oBAAA,EAAsB;AAAA,IAClD,SAAA,EAAW,QAAA;AAAA,IACX,WAAA,EAAa;AAAA,GACd,CAAA;AAAA;AAAA,EAGD,SAAA,EAAW,SAAiB,oBAAA,EAAsB;AAAA,IAChD,SAAA,EAAW,QAAA;AAAA,IACX,WAAA,EAAa;AAAA,GACd,CAAA;AAAA;AAAA,EAGD,aAAA,EAAe,SAAiB,yBAAA,EAA2B;AAAA,IACzD,SAAA,EAAW,cAAA;AAAA,IACX,WAAA,EAAa;AAAA,GACd;AACH;AAcO,IAAM,QAAA,GAAW;AAAA;AAAA,EAEtB,aAAA,EAAe,SAAiB,0BAAA,EAA4B;AAAA,IAC1D,SAAA,EAAW,QAAA;AAAA,IACX,WAAA,EAAa;AAAA,GACd,CAAA;AAAA;AAAA,EAGD,MAAA,EAAQ,SAAiB,iBAAA,EAAmB;AAAA,IAC1C,SAAA,EAAW,QAAA;AAAA,IACX,WAAA,EAAa;AAAA,GACd;AACH","file":"index.js","sourcesContent":["/**\n * @bratsos/workflow-engine/conventions\n *\n * Well-known annotation keys for common provenance scenarios — trigger\n * context, decisions, approvals, revisions. Inspired by OpenTelemetry\n * semantic conventions: dot-namespaced flat keys, value type linked to\n * the key via TypeScript phantom-type inference.\n *\n * ## Usage\n *\n * ```ts\n * import { Trigger, Decision } from \"@bratsos/workflow-engine/conventions\";\n *\n * // Type-checked: value must match the TypedKey<T> parameter.\n * ctx.annotate(Decision.outcome, \"low\");\n * ctx.annotate(Decision.confidence, 0.42);\n * ctx.annotate(Decision.confidence, \"high\"); // ❌ TS error\n *\n * // Custom org-defined keys keep working with the string form:\n * ctx.annotate(\"acme.compliance.signoff\", \"alice@acme.com\");\n * ```\n *\n * ## Versioning policy\n *\n * - Keys are **immutable once `stable`**. Additions only.\n * - Renames and value-type changes ship as **new keys**; the old key\n * gets a `@deprecated` JSDoc tag.\n * - We deliberately do **not** copy OpenTelemetry's\n * `OTEL_SEMCONV_STABILITY_OPT_IN` env-var dance — versioning is\n * handled through semver and JSDoc.\n *\n * See `src/conventions/README.md` for the full policy.\n */\n\nimport type { Stability, TypedKey } from \"../core/stage\";\n\nexport type { Stability, TypedKey } from \"../core/stage\";\n\n/**\n * Define a well-known annotation key. The value-type parameter `T` is\n * phantom — never set at runtime, used only for TypeScript inference\n * when the key is passed to `ctx.annotate(key, value)`.\n */\nexport function typedKey<T = unknown>(\n key: string,\n meta?: { stability?: Stability; description?: string },\n): TypedKey<T> {\n return {\n key,\n stability: meta?.stability ?? \"experimental\",\n description: meta?.description,\n };\n}\n\n// ============================================================================\n// Trigger — what initiated the run\n// ============================================================================\n\n/**\n * Trigger conventions describe how a workflow run was initiated:\n * caller identity, source system, parent run, free-text reason.\n *\n * Attach at `run.create` time via the `annotations` parameter.\n */\nexport const Trigger = {\n /** What system or path initiated the run, e.g. `\"webhook:zendesk\"`, `\"manual:cli\"`, `\"schedule:cron\"`. */\n source: typedKey<string>(\"trigger.source\", {\n stability: \"stable\",\n description: \"What system or path initiated this run.\",\n }),\n\n /** Run ID of the prior run when this run is a follow-up / retry / chained execution. */\n parentRunId: typedKey<string>(\"trigger.parent_run_id\", {\n stability: \"stable\",\n description: \"Run ID of the prior run when this is a follow-up.\",\n }),\n\n /** Free-text reason — `\"auto-triage on ticket create\"`, `\"manual rerun after policy change\"`, etc. */\n reason: typedKey<string>(\"trigger.reason\", {\n stability: \"stable\",\n description: \"Free-text rationale for triggering this run.\",\n }),\n\n /** Actor kind discriminator — recommended values: `\"user\"`, `\"agent\"`, `\"system\"`. Open string. */\n actorKind: typedKey<string>(\"trigger.actor.kind\", {\n stability: \"stable\",\n description:\n \"Open string. Recommended: 'user' | 'agent' | 'system'. Use the envelope `actor.kind` for the equivalent on stage-scope annotations.\",\n }),\n\n /** Stable identifier for the actor — user email, agent name, service identifier. */\n actorId: typedKey<string>(\"trigger.actor.id\", {\n stability: \"stable\",\n description: \"Stable identifier for the triggering actor.\",\n }),\n} as const;\n\n// ============================================================================\n// Decision — choices made during execution\n// ============================================================================\n\n/**\n * Decision conventions describe choices an agent or stage made\n * during execution: the chosen outcome, the reasoning, evidence,\n * alternatives that were considered.\n *\n * Attach from inside `ctx.annotate(...)` within a stage's `execute()`.\n */\nexport const Decision = {\n /** The chosen outcome. Shape is consumer-defined; `unknown` here for flexibility. */\n outcome: typedKey<unknown>(\"decision.outcome\", {\n stability: \"stable\",\n description:\n \"The chosen outcome of this decision. Shape is consumer-defined.\",\n }),\n\n /** Free-text rationale — why the agent picked this outcome. */\n rationale: typedKey<string>(\"decision.rationale\", {\n stability: \"stable\",\n description: \"Human-readable reason for the decision.\",\n }),\n\n /** Confidence score, typically `0`–`1`. */\n confidence: typedKey<number>(\"decision.confidence\", {\n stability: \"stable\",\n description: \"Confidence score for the decision, typically 0–1.\",\n }),\n\n /** Alternative outcomes that were considered but not selected. */\n alternatives: typedKey<unknown[]>(\"decision.alternatives\", {\n stability: \"stable\",\n description: \"Alternative outcomes considered but not selected.\",\n }),\n\n /** Whether a fallback heuristic was used (e.g., AI confidence below threshold). */\n usedFallback: typedKey<boolean>(\"decision.used_fallback\", {\n stability: \"experimental\",\n description:\n \"Whether the agent fell back to a heuristic after the primary signal was inconclusive.\",\n }),\n} as const;\n\n// ============================================================================\n// Approval — sign-off events\n// ============================================================================\n\n/**\n * Approval conventions describe sign-off events on runs or stages.\n * Pluralization follows the OTel rule: `approvers` is plural because a\n * single approval can have multiple approvers; the value type is\n * always `string[]`, even with one approver.\n */\nexport const Approval = {\n /** Identifiers of all approvers. Always an array — `[\"alice\"]` for a single approver. */\n approvers: typedKey<string[]>(\"approval.approvers\", {\n stability: \"stable\",\n description: \"Identifiers of all approvers (always an array, plural-rule).\",\n }),\n\n /** When the approval was recorded. ISO 8601. */\n timestamp: typedKey<string>(\"approval.timestamp\", {\n stability: \"stable\",\n description: \"ISO 8601 timestamp when approval was recorded.\",\n }),\n\n /** Version of the policy the approval was checked against. */\n policyVersion: typedKey<string>(\"approval.policy.version\", {\n stability: \"experimental\",\n description: \"Version of the policy the approval was checked against.\",\n }),\n} as const;\n\n// ============================================================================\n// Revision — chained/related runs\n// ============================================================================\n\n/**\n * Revision conventions describe a run as a revision of a prior run:\n * a deliberate redo, a corrected attempt, a manual override.\n *\n * Distinct from `Trigger.parentRunId` — that's any causal parent\n * (including independent follow-ups), revision is specifically\n * \"this run supersedes that one.\"\n */\nexport const Revision = {\n /** Run ID this revision supersedes. */\n previousRunId: typedKey<string>(\"revision.previous_run_id\", {\n stability: \"stable\",\n description: \"Run ID this revision explicitly supersedes.\",\n }),\n\n /** Why this revision was created. */\n reason: typedKey<string>(\"revision.reason\", {\n stability: \"stable\",\n description: \"Why this revision was created.\",\n }),\n} as const;\n"]}
@@ -97,8 +97,30 @@ interface StageProgressEvent {
97
97
  readonly message: string;
98
98
  readonly details?: Record<string, unknown>;
99
99
  }
100
+ /**
101
+ * Emitted when an annotation is written with `emitEvent: true`. Lets
102
+ * plugins and external systems react to provenance writes in real time
103
+ * (audit pipelines, SIEM, live dashboards) without polling
104
+ * `kernel.annotations.list`.
105
+ *
106
+ * Off by default — annotations are primarily a queryable provenance
107
+ * surface, not an event stream. Most consumers won't need this.
108
+ */
109
+ interface AnnotationCreatedEvent {
110
+ readonly type: "annotation:created";
111
+ readonly timestamp: Date;
112
+ readonly workflowRunId: string;
113
+ readonly key: string;
114
+ readonly value: unknown;
115
+ readonly scope: string;
116
+ readonly scopeId?: string;
117
+ readonly attempt?: number;
118
+ readonly actorKind?: string;
119
+ readonly actorId?: string;
120
+ readonly actorVersion?: string;
121
+ }
100
122
  /** Discriminated union of every kernel event. */
101
- type KernelEvent = WorkflowCreatedEvent | WorkflowStartedEvent | WorkflowCompletedEvent | WorkflowFailedEvent | WorkflowCancelledEvent | WorkflowSuspendedEvent | StageStartedEvent | StageCompletedEvent | StageSuspendedEvent | StageFailedEvent | StageProgressEvent;
123
+ type KernelEvent = WorkflowCreatedEvent | WorkflowStartedEvent | WorkflowCompletedEvent | WorkflowFailedEvent | WorkflowCancelledEvent | WorkflowSuspendedEvent | StageStartedEvent | StageCompletedEvent | StageSuspendedEvent | StageFailedEvent | StageProgressEvent | AnnotationCreatedEvent;
102
124
  /** String literal union of all kernel event type discriminants. */
103
125
  type KernelEventType = KernelEvent["type"];
104
126
 
@@ -1,4 +1,4 @@
1
- import { A as AICallLogger, g as CreateAICallInput, h as AIHelperStats, l as WorkflowPersistence, C as CreateRunInput, W as WorkflowRunRecord, U as UpdateRunInput, m as WorkflowStatus, a as CreateStageInput, b as WorkflowStageRecord, c as UpsertStageInput, d as UpdateStageInput, n as WorkflowStageStatus, e as CreateLogInput, o as SaveArtifactInput, p as WorkflowArtifactRecord, f as CreateOutboxEventInput, O as OutboxRecord, J as JobQueue, E as EnqueueJobInput, D as DequeueResult } from './interface-BeEPzTFy.js';
1
+ import { k as AICallLogger, l as CreateAICallInput, m as AIHelperStats, q as WorkflowPersistence, C as CreateRunInput, W as WorkflowRunRecord, U as UpdateRunInput, r as WorkflowStatus, a as CreateStageInput, b as WorkflowStageRecord, c as UpsertStageInput, d as UpdateStageInput, s as WorkflowStageStatus, e as CreateLogInput, t as SaveArtifactInput, u as WorkflowArtifactRecord, f as CreateAnnotationInput, A as AnnotationFilters, g as WorkflowAnnotationRecord, h as CreateOutboxEventInput, O as OutboxRecord, J as JobQueue, E as EnqueueJobInput, D as DequeueResult } from './interface-BPz138Hf.js';
2
2
 
3
3
  /**
4
4
  * PrismaAICallLogger - Prisma implementation of AICallLogger
@@ -109,6 +109,9 @@ declare class PrismaWorkflowPersistence implements WorkflowPersistence {
109
109
  deleteArtifact(runId: string, key: string): Promise<void>;
110
110
  listArtifacts(runId: string): Promise<WorkflowArtifactRecord[]>;
111
111
  getStageIdForArtifact(runId: string, stageId: string): Promise<string | null>;
112
+ appendAnnotations(inputs: CreateAnnotationInput[]): Promise<void>;
113
+ listAnnotations(workflowRunId: string, filters?: AnnotationFilters): Promise<WorkflowAnnotationRecord[]>;
114
+ private mapWorkflowAnnotation;
112
115
  saveStageOutput(runId: string, workflowType: string, stageId: string, output: unknown): Promise<string>;
113
116
  appendOutboxEvents(events: CreateOutboxEventInput[]): Promise<void>;
114
117
  getUnpublishedOutboxEvents(limit?: number): Promise<OutboxRecord[]>;
package/dist/index.d.ts CHANGED
@@ -1,15 +1,15 @@
1
- import { M as ModelKey } from './client-DYs5wlHp.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, u as calculateCost, v as createAIHelper, w as defineAsyncBatchStage, x as defineStage, y as getDefaultModel, z as getModel, C as getModelById, F as getRegisteredModel, G as listModels, H as listRegisteredModels, J as modelSupportsBatch, K as printAvailableModels, P as registerEmbeddingProvider, Q as registerModels, U as requireStageOutput } from './client-DYs5wlHp.js';
3
- import { L as LogLevel } from './stage-_7BKqqUG.js';
4
- export { S as Stage, a as StageResult } from './stage-_7BKqqUG.js';
5
- import { y as Workflow } from './plugins-Cl0WVVrE.js';
6
- export { C as CommandResult, I as IdempotencyInProgressError, z 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, A as WorkflowBuilder, v as createKernel, w as createPluginRunner, x as definePlugin } from './plugins-Cl0WVVrE.js';
1
+ import { M as ModelKey } from './client-YFKVt4p7.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, u as calculateCost, v as createAIHelper, w as defineAsyncBatchStage, x as defineStage, y as getDefaultModel, z as getModel, C as getModelById, F as getRegisteredModel, G as listModels, H as listRegisteredModels, J as modelSupportsBatch, K as printAvailableModels, P as registerEmbeddingProvider, Q as registerModels, U as requireStageOutput } from './client-YFKVt4p7.js';
3
+ import { L as LogLevel } from './stage-WuK0mfrC.js';
4
+ export { a as Stage, b as StageResult } from './stage-WuK0mfrC.js';
5
+ import { B as Workflow } from './plugins-zT-aIcEZ.js';
6
+ export { C as CommandResult, I as IdempotencyInProgressError, D as InferWorkflowStageIds, J as JobExecuteCommand, a as JobExecuteResult, b as Kernel, d as KernelCommand, e as KernelCommandType, f as KernelConfig, W as KernelWorkflowRegistry, L as LeaseReapStaleCommand, g as LeaseReapStaleResult, O as OutboxFlushCommand, h as OutboxFlushResult, P as PluginDefinition, i as PluginReplayDLQCommand, j as PluginReplayDLQResult, k as PluginRunner, l as PluginRunnerConfig, R as RunCancelCommand, m as RunCancelResult, n as RunClaimPendingCommand, o as RunClaimPendingResult, q as RunCreateCommand, r as RunCreateResult, s as RunRerunFromCommand, t as RunRerunFromResult, u as RunTransitionCommand, v as RunTransitionResult, S as StagePollSuspendedCommand, w as StagePollSuspendedResult, E as WorkflowBuilder, x as createKernel, y as createPluginRunner, z as definePlugin } from './plugins-zT-aIcEZ.js';
7
7
  import z$1, { z } from 'zod';
8
- export { A as AICallLogger, i as AICallRecord, h as AIHelperStats, r as ArtifactType, g as CreateAICallInput, e as CreateLogInput, f as CreateOutboxEventInput, C as CreateRunInput, a as CreateStageInput, D as DequeueResult, E as EnqueueJobInput, I as IdempotencyRecord, J as JobQueue, j as JobRecord, L as LogLevel, O as OutboxRecord, o as SaveArtifactInput, s as StaleVersionError, S as Status, U as UpdateRunInput, d as UpdateStageInput, c as UpsertStageInput, p as WorkflowArtifactRecord, q as WorkflowLogRecord, l as WorkflowPersistence, W as WorkflowRunRecord, b as WorkflowStageRecord } from './interface-BeEPzTFy.js';
9
- export { P as PrismaAICallLogger, a as PrismaJobQueue, c as PrismaWorkflowPersistence, e as createPrismaAICallLogger, f as createPrismaJobQueue, g as createPrismaWorkflowPersistence } from './index-aNuJ2QgN.js';
8
+ export { k as AICallLogger, n as AICallRecord, m as AIHelperStats, w as ArtifactType, l as CreateAICallInput, e as CreateLogInput, h as CreateOutboxEventInput, C as CreateRunInput, a as CreateStageInput, D as DequeueResult, E as EnqueueJobInput, I as IdempotencyRecord, J as JobQueue, o as JobRecord, L as LogLevel, O as OutboxRecord, t as SaveArtifactInput, x as StaleVersionError, S as Status, U as UpdateRunInput, d as UpdateStageInput, c as UpsertStageInput, u as WorkflowArtifactRecord, v as WorkflowLogRecord, q as WorkflowPersistence, W as WorkflowRunRecord, b as WorkflowStageRecord } from './interface-BPz138Hf.js';
9
+ export { P as PrismaAICallLogger, a as PrismaJobQueue, c as PrismaWorkflowPersistence, e as createPrismaAICallLogger, f as createPrismaJobQueue, g as createPrismaWorkflowPersistence } from './index-CL0KmlyW.js';
10
10
  import { ToolSet } from 'ai';
11
- export { K as KernelEvent, a as KernelEventType } from './events-D_P24UaY.js';
12
- export { B as BlobStore, C as Clock, E as EventSink, J as JobTransport, P as Persistence, S as Scheduler } from './ports-swhiWFw4.js';
11
+ export { K as KernelEvent, a as KernelEventType } from './events-B3XPPu0c.js';
12
+ export { B as BlobStore, C as Clock, E as EventSink, J as JobTransport, P as Persistence, S as Scheduler } from './ports-DUL4hlQr.js';
13
13
  import '@ai-sdk/provider';
14
14
 
15
15
  /**
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import { ModelKey } from './chunk-WWK2SPN7.js';
2
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-WWK2SPN7.js';
3
3
  import './chunk-D7RVRRM2.js';
4
- export { PrismaAICallLogger, PrismaJobQueue, PrismaWorkflowPersistence, createPrismaAICallLogger, createPrismaJobQueue, createPrismaWorkflowPersistence } from './chunk-Q2XDO3UF.js';
4
+ export { PrismaAICallLogger, PrismaJobQueue, PrismaWorkflowPersistence, createPrismaAICallLogger, createPrismaJobQueue, createPrismaWorkflowPersistence } from './chunk-TWYPSP7P.js';
5
5
  import './chunk-MUWP5SF2.js';
6
- export { IdempotencyInProgressError, createKernel, createPluginRunner, definePlugin } from './chunk-5C7LRNM7.js';
7
- export { StaleVersionError } from './chunk-2HEV5ZJL.js';
6
+ export { IdempotencyInProgressError, createKernel, createPluginRunner, definePlugin } from './chunk-XPWAEYOO.js';
7
+ export { StaleVersionError } from './chunk-NANAXHS5.js';
8
8
  import { z } from 'zod';
9
9
 
10
10
  // src/core/stage-ids.ts
@@ -67,6 +67,14 @@ interface WorkflowStageRecord {
67
67
  stageName: string;
68
68
  stageNumber: number;
69
69
  executionGroup: number;
70
+ /**
71
+ * Rerun generation. 0 for the original execution; incremented each
72
+ * time `run.rerunFrom` recreates this stage. Annotations written by
73
+ * `ctx.annotate(...)` during this stage inherit this value so a
74
+ * future agent can distinguish decisions made on different attempts
75
+ * of the same logical stage.
76
+ */
77
+ attempt: number;
70
78
  status: WorkflowStageStatus;
71
79
  startedAt: Date | null;
72
80
  completedAt: Date | null;
@@ -104,6 +112,41 @@ interface WorkflowArtifactRecord {
104
112
  size: number;
105
113
  metadata: unknown | null;
106
114
  }
115
+ /**
116
+ * Annotation actor — who or what produced this annotation.
117
+ * `kind` is open (recommended values: "agent", "user", "system") so consumers
118
+ * can introduce custom kinds. `id` and `version` are indexed individually for
119
+ * cross-version queries.
120
+ */
121
+ interface AnnotationActor {
122
+ kind?: string;
123
+ id?: string;
124
+ version?: string;
125
+ }
126
+ /**
127
+ * Annotation scope — which entity within a run this annotation describes.
128
+ * - "run": run-level (e.g., trigger context)
129
+ * - "stage": tied to a specific stage execution (linked via workflowStageRecordId)
130
+ * - "ai_call": tied to a specific AI call (custom; not used by the engine itself)
131
+ * - other strings allowed for consumer-defined scopes
132
+ */
133
+ type AnnotationScope = "run" | "stage" | "ai_call" | (string & {});
134
+ interface WorkflowAnnotationRecord {
135
+ id: string;
136
+ createdAt: Date;
137
+ workflowRunId: string;
138
+ workflowStageRecordId: string | null;
139
+ attempt: number;
140
+ scope: AnnotationScope;
141
+ scopeId: string | null;
142
+ actorKind: string | null;
143
+ actorId: string | null;
144
+ actorVersion: string | null;
145
+ key: string;
146
+ value: unknown;
147
+ payload: unknown | null;
148
+ idempotencyKey: string | null;
149
+ }
107
150
  interface OutboxRecord {
108
151
  id: string;
109
152
  workflowRunId: string;
@@ -189,6 +232,8 @@ interface CreateStageInput {
189
232
  stageName: string;
190
233
  stageNumber: number;
191
234
  executionGroup: number;
235
+ /** Rerun generation. Defaults to 0. Set by `run.rerunFrom` for recreated stages. */
236
+ attempt?: number;
192
237
  status?: WorkflowStageStatus;
193
238
  startedAt?: Date;
194
239
  config?: unknown;
@@ -234,6 +279,53 @@ interface SaveArtifactInput {
234
279
  size: number;
235
280
  metadata?: unknown;
236
281
  }
282
+ /**
283
+ * Input for appending an annotation. `attempt` defaults to 0; callers from
284
+ * `job-execute.ts` / `stage-poll-suspended.ts` are responsible for computing
285
+ * the correct attempt value (incremented when a stage is rerun).
286
+ *
287
+ * When `idempotencyKey` is set, the unique constraint on
288
+ * `(workflowRunId, key, idempotencyKey)` ensures duplicates are skipped on
289
+ * retry. When `idempotencyKey` is null, the constraint does not apply.
290
+ */
291
+ interface CreateAnnotationInput {
292
+ workflowRunId: string;
293
+ workflowStageRecordId?: string | null;
294
+ attempt?: number;
295
+ scope: AnnotationScope;
296
+ scopeId?: string | null;
297
+ actor?: AnnotationActor;
298
+ key: string;
299
+ value: unknown;
300
+ payload?: unknown;
301
+ idempotencyKey?: string | null;
302
+ /**
303
+ * If true, the engine emits an `annotation:created` outbox event when
304
+ * this row is persisted. Plumbed through the buffered-flush path so
305
+ * the event lands in the same transaction as the annotation row.
306
+ * Off by default — most provenance is read-only and doesn't need to
307
+ * be a real-time event.
308
+ */
309
+ emitEvent?: boolean;
310
+ }
311
+ /**
312
+ * Filters for `listAnnotations`. All filters are AND-combined.
313
+ * `keyPrefix` is implemented with `startsWith` (Postgres uses the
314
+ * `(workflowRunId, key)` index; SQLite may table-scan unless the engine
315
+ * branches to GLOB — see PrismaWorkflowPersistence).
316
+ */
317
+ interface AnnotationFilters {
318
+ key?: string;
319
+ keyPrefix?: string;
320
+ scope?: AnnotationScope;
321
+ scopeId?: string | null;
322
+ actorId?: string;
323
+ actorKind?: string;
324
+ attempt?: number;
325
+ since?: Date;
326
+ until?: Date;
327
+ limit?: number;
328
+ }
237
329
  interface CreateAICallInput {
238
330
  topic: string;
239
331
  callType: string;
@@ -314,6 +406,21 @@ interface WorkflowPersistence {
314
406
  deleteArtifact(runId: string, key: string): Promise<void>;
315
407
  listArtifacts(runId: string): Promise<WorkflowArtifactRecord[]>;
316
408
  getStageIdForArtifact(runId: string, stageId: string): Promise<string | null>;
409
+ /**
410
+ * Append one or more annotations. Designed to be called both standalone
411
+ * (fire-and-forget from external attach) and inside an existing
412
+ * transaction (buffered during stage execution, flushed in the
413
+ * stage-completion transaction).
414
+ *
415
+ * Rows with the same `(workflowRunId, key, idempotencyKey)` are deduped
416
+ * via the unique constraint; duplicates are silently skipped.
417
+ */
418
+ appendAnnotations(inputs: CreateAnnotationInput[]): Promise<void>;
419
+ /**
420
+ * List annotations for a run, optionally filtered. Returns rows ordered
421
+ * by `createdAt` ascending (so consumers get a timeline by default).
422
+ */
423
+ listAnnotations(workflowRunId: string, filters?: AnnotationFilters): Promise<WorkflowAnnotationRecord[]>;
317
424
  saveStageOutput(runId: string, workflowType: string, stageId: string, output: unknown): Promise<string>;
318
425
  /** Increment retry count for a failed outbox event. Returns new count. */
319
426
  incrementOutboxRetryCount(id: string): Promise<number>;
@@ -415,4 +522,4 @@ interface JobQueue {
415
522
  cancelByRun(workflowRunId: string): Promise<number>;
416
523
  }
417
524
 
418
- export { type AICallLogger as A, type CreateRunInput as C, type DequeueResult as D, type EnqueueJobInput as E, type IdempotencyRecord as I, type JobQueue as J, type LogLevel as L, type OutboxRecord as O, type Status as S, type UpdateRunInput as U, type WorkflowRunRecord as W, type CreateStageInput as a, type WorkflowStageRecord as b, type UpsertStageInput as c, type UpdateStageInput as d, type CreateLogInput as e, type CreateOutboxEventInput as f, type CreateAICallInput as g, type AIHelperStats as h, type AICallRecord as i, type JobRecord as j, type JobStatus as k, type WorkflowPersistence as l, type WorkflowStatus as m, type WorkflowStageStatus as n, type SaveArtifactInput as o, type WorkflowArtifactRecord as p, type WorkflowLogRecord as q, type ArtifactType as r, StaleVersionError as s };
525
+ export { type AnnotationFilters as A, type CreateRunInput as C, type DequeueResult as D, type EnqueueJobInput as E, type IdempotencyRecord as I, type JobQueue as J, type LogLevel as L, type OutboxRecord as O, type Status as S, type UpdateRunInput as U, type WorkflowRunRecord as W, type CreateStageInput as a, type WorkflowStageRecord as b, type UpsertStageInput as c, type UpdateStageInput as d, type CreateLogInput as e, type CreateAnnotationInput as f, type WorkflowAnnotationRecord as g, type CreateOutboxEventInput as h, type AnnotationActor as i, type AnnotationScope as j, type AICallLogger as k, type CreateAICallInput as l, type AIHelperStats as m, type AICallRecord as n, type JobRecord as o, type JobStatus as p, type WorkflowPersistence as q, type WorkflowStatus as r, type WorkflowStageStatus as s, type SaveArtifactInput as t, type WorkflowArtifactRecord as u, type WorkflowLogRecord as v, type ArtifactType as w, StaleVersionError as x };
@@ -1,10 +1,10 @@
1
- import { K as KernelDeps } from '../plugins-Cl0WVVrE.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-Cl0WVVrE.js';
3
- export { K as KernelEvent, a as KernelEventType, S as StageCompletedEvent, b as StageFailedEvent, c as StageProgressEvent, d as StageStartedEvent, e as StageSuspendedEvent, W as WorkflowCancelledEvent, f as WorkflowCompletedEvent, g as WorkflowCreatedEvent, h as WorkflowFailedEvent, i as WorkflowStartedEvent, j as WorkflowSuspendedEvent } from '../events-D_P24UaY.js';
4
- export { B as BlobStore, C as Clock, E as EventSink, J as JobTransport, P as Persistence, S as Scheduler } from '../ports-swhiWFw4.js';
5
- export { f as CreateOutboxEventInput, I as IdempotencyRecord, O as OutboxRecord } from '../interface-BeEPzTFy.js';
1
+ import { K as KernelDeps } from '../plugins-zT-aIcEZ.js';
2
+ export { A as AnnotateAttachInput, C as CommandResult, I as IdempotencyInProgressError, J as JobExecuteCommand, a as JobExecuteResult, b as Kernel, c as KernelAnnotations, d as KernelCommand, e as KernelCommandType, f as KernelConfig, L as LeaseReapStaleCommand, g as LeaseReapStaleResult, O as OutboxFlushCommand, h as OutboxFlushResult, P as PluginDefinition, i as PluginReplayDLQCommand, j as PluginReplayDLQResult, k as PluginRunner, l as PluginRunnerConfig, R as RunCancelCommand, m as RunCancelResult, n as RunClaimPendingCommand, o as RunClaimPendingResult, p as RunCreateAnnotation, q as RunCreateCommand, r as RunCreateResult, s as RunRerunFromCommand, t as RunRerunFromResult, u as RunTransitionCommand, v as RunTransitionResult, S as StagePollSuspendedCommand, w as StagePollSuspendedResult, W as WorkflowRegistry, x as createKernel, y as createPluginRunner, z as definePlugin } from '../plugins-zT-aIcEZ.js';
3
+ export { K as KernelEvent, a as KernelEventType, S as StageCompletedEvent, b as StageFailedEvent, c as StageProgressEvent, d as StageStartedEvent, e as StageSuspendedEvent, W as WorkflowCancelledEvent, f as WorkflowCompletedEvent, g as WorkflowCreatedEvent, h as WorkflowFailedEvent, i as WorkflowStartedEvent, j as WorkflowSuspendedEvent } from '../events-B3XPPu0c.js';
4
+ export { i as AnnotationActor, A as AnnotationFilters, j as AnnotationScope, f as CreateAnnotationInput, h as CreateOutboxEventInput, I as IdempotencyRecord, O as OutboxRecord, g as WorkflowAnnotationRecord } from '../interface-BPz138Hf.js';
5
+ export { B as BlobStore, C as Clock, E as EventSink, J as JobTransport, P as Persistence, S as Scheduler } from '../ports-DUL4hlQr.js';
6
6
  import 'zod';
7
- import '../stage-_7BKqqUG.js';
7
+ import '../stage-WuK0mfrC.js';
8
8
 
9
9
  /**
10
10
  * Load workflow context from completed stages.
@@ -1,4 +1,4 @@
1
- export { IdempotencyInProgressError, createKernel, createPluginRunner, definePlugin, loadWorkflowContext, saveStageOutput } from '../chunk-5C7LRNM7.js';
2
- import '../chunk-2HEV5ZJL.js';
1
+ export { IdempotencyInProgressError, createKernel, createPluginRunner, definePlugin, loadWorkflowContext, saveStageOutput } from '../chunk-XPWAEYOO.js';
2
+ import '../chunk-NANAXHS5.js';
3
3
  //# sourceMappingURL=index.js.map
4
4
  //# sourceMappingURL=index.js.map
@@ -1,6 +1,6 @@
1
- import { K as KernelEvent, a as KernelEventType } from '../../events-D_P24UaY.js';
2
- import { E as EventSink, C as Clock, B as BlobStore, S as Scheduler } from '../../ports-swhiWFw4.js';
3
- import '../../interface-BeEPzTFy.js';
1
+ import { K as KernelEvent, a as KernelEventType } from '../../events-B3XPPu0c.js';
2
+ import { E as EventSink, C as Clock, B as BlobStore, S as Scheduler } from '../../ports-DUL4hlQr.js';
3
+ import '../../interface-BPz138Hf.js';
4
4
 
5
5
  declare class CollectingEventSink implements EventSink {
6
6
  readonly events: KernelEvent[];
@@ -1,2 +1,2 @@
1
- export { A as AICallLogger, i as AICallRecord, h as AIHelperStats, r as ArtifactType, g as CreateAICallInput, e as CreateLogInput, C as CreateRunInput, a 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, d as UpdateStageInput, c as UpsertStageInput, p as WorkflowArtifactRecord, q as WorkflowLogRecord, l as WorkflowPersistence, W as WorkflowRunRecord, b as WorkflowStageRecord, n as WorkflowStageStatus, m as WorkflowStatus } from '../interface-BeEPzTFy.js';
2
- export { P as PrismaAICallLogger, a as PrismaJobQueue, c as PrismaWorkflowPersistence, e as createPrismaAICallLogger, f as createPrismaJobQueue, g as createPrismaWorkflowPersistence } from '../index-aNuJ2QgN.js';
1
+ export { k as AICallLogger, n as AICallRecord, m as AIHelperStats, w as ArtifactType, l as CreateAICallInput, e as CreateLogInput, C as CreateRunInput, a as CreateStageInput, D as DequeueResult, E as EnqueueJobInput, J as JobQueue, o as JobRecord, p as JobStatus, L as LogLevel, t as SaveArtifactInput, S as Status, U as UpdateRunInput, d as UpdateStageInput, c as UpsertStageInput, u as WorkflowArtifactRecord, v as WorkflowLogRecord, q as WorkflowPersistence, W as WorkflowRunRecord, b as WorkflowStageRecord, s as WorkflowStageStatus, r as WorkflowStatus } from '../interface-BPz138Hf.js';
2
+ export { P as PrismaAICallLogger, a as PrismaJobQueue, c as PrismaWorkflowPersistence, e as createPrismaAICallLogger, f as createPrismaJobQueue, g as createPrismaWorkflowPersistence } from '../index-CL0KmlyW.js';
@@ -1,6 +1,6 @@
1
1
  import '../chunk-D7RVRRM2.js';
2
- export { PrismaAICallLogger, PrismaJobQueue, PrismaWorkflowPersistence, createPrismaAICallLogger, createPrismaJobQueue, createPrismaWorkflowPersistence } from '../chunk-Q2XDO3UF.js';
2
+ export { PrismaAICallLogger, PrismaJobQueue, PrismaWorkflowPersistence, createPrismaAICallLogger, createPrismaJobQueue, createPrismaWorkflowPersistence } from '../chunk-TWYPSP7P.js';
3
3
  import '../chunk-MUWP5SF2.js';
4
- import '../chunk-2HEV5ZJL.js';
4
+ import '../chunk-NANAXHS5.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-aNuJ2QgN.js';
2
- import '../../interface-BeEPzTFy.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-CL0KmlyW.js';
2
+ import '../../interface-BPz138Hf.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-Q2XDO3UF.js';
1
+ export { PrismaAICallLogger, PrismaJobQueue, PrismaWorkflowPersistence, createEnumHelper, createPrismaAICallLogger, createPrismaJobQueue, createPrismaWorkflowPersistence } from '../../chunk-TWYPSP7P.js';
2
2
  import '../../chunk-MUWP5SF2.js';
3
- import '../../chunk-2HEV5ZJL.js';
3
+ import '../../chunk-NANAXHS5.js';
4
4
  //# sourceMappingURL=index.js.map
5
5
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,8 @@
1
1
  import { z } from 'zod';
2
- import { S as Stage } from './stage-_7BKqqUG.js';
3
- import { P as Persistence, B as BlobStore, J as JobTransport, E as EventSink, S as Scheduler, C as Clock } from './ports-swhiWFw4.js';
4
- import { a as KernelEventType, K as KernelEvent } from './events-D_P24UaY.js';
2
+ import { a as Stage } from './stage-WuK0mfrC.js';
3
+ import { i as AnnotationActor, j as AnnotationScope, A as AnnotationFilters, g as WorkflowAnnotationRecord } from './interface-BPz138Hf.js';
4
+ import { P as Persistence, B as BlobStore, J as JobTransport, E as EventSink, S as Scheduler, C as Clock } from './ports-DUL4hlQr.js';
5
+ import { a as KernelEventType, K as KernelEvent } from './events-B3XPPu0c.js';
5
6
 
6
7
  /**
7
8
  * Workflow Builder - Fluent API for composing type-safe workflows
@@ -218,6 +219,20 @@ type InferWorkflowStageIds<W> = W extends Workflow<any, any, infer C> ? keyof C
218
219
  *
219
220
  * This file contains ONLY types -- no runtime code.
220
221
  */
222
+
223
+ /** Annotation to attach at run-creation time. */
224
+ interface RunCreateAnnotation {
225
+ readonly attributes: Record<string, unknown>;
226
+ readonly actor?: AnnotationActor;
227
+ readonly payload?: Record<string, unknown>;
228
+ readonly idempotencyKey?: string;
229
+ /**
230
+ * If true, the engine writes an `annotation:created` outbox event for
231
+ * each attribute in this batch, in the same transaction as the run
232
+ * creation. Off by default.
233
+ */
234
+ readonly emitEvent?: boolean;
235
+ }
221
236
  /** Creates a new workflow run. */
222
237
  interface RunCreateCommand {
223
238
  readonly type: "run.create";
@@ -226,7 +241,18 @@ interface RunCreateCommand {
226
241
  readonly input: Record<string, unknown>;
227
242
  readonly config?: Record<string, unknown>;
228
243
  readonly priority?: number;
244
+ /**
245
+ * @deprecated since 0.8.0. Use `annotations` instead — annotations are
246
+ * queryable, indexed, and follow stable conventions. `metadata` will be
247
+ * removed in 1.0.
248
+ */
229
249
  readonly metadata?: Record<string, unknown>;
250
+ /**
251
+ * Annotations to attach at run creation time. Each entry becomes one
252
+ * row per attribute, sharing the supplied envelope (actor / payload /
253
+ * idempotencyKey). Written inside the same transaction as the run.
254
+ */
255
+ readonly annotations?: ReadonlyArray<RunCreateAnnotation>;
230
256
  }
231
257
  /** Result of a `run.create` command. */
232
258
  interface RunCreateResult {
@@ -392,8 +418,41 @@ interface KernelConfig {
392
418
  clock: Clock;
393
419
  registry: WorkflowRegistry;
394
420
  }
421
+ /** Input for the public `kernel.annotations.attach` helper. */
422
+ interface AnnotateAttachInput {
423
+ attributes: Record<string, unknown>;
424
+ actor?: AnnotationActor;
425
+ /**
426
+ * Defaults to "run". Set to "stage" with `scopeId` to scope an
427
+ * annotation to a specific stage (e.g., from a plugin observing
428
+ * stage events).
429
+ */
430
+ scope?: AnnotationScope;
431
+ scopeId?: string | null;
432
+ workflowStageRecordId?: string | null;
433
+ attempt?: number;
434
+ payload?: Record<string, unknown>;
435
+ idempotencyKey?: string;
436
+ /**
437
+ * If true, the engine writes an `annotation:created` outbox event
438
+ * for each attribute in this batch, in the same transaction as the
439
+ * annotation rows. Off by default.
440
+ */
441
+ emitEvent?: boolean;
442
+ }
443
+ /**
444
+ * Public helpers for working with annotations directly — for plugins,
445
+ * post-hoc reviews, external integrations, and query tooling. The
446
+ * `attach` path commits in a single transaction; the `list` path is a
447
+ * read-only query honoring the persistence-port filters.
448
+ */
449
+ interface KernelAnnotations {
450
+ attach(workflowRunId: string, input: AnnotateAttachInput): Promise<void>;
451
+ list(workflowRunId: string, filters?: AnnotationFilters): Promise<WorkflowAnnotationRecord[]>;
452
+ }
395
453
  interface Kernel {
396
454
  dispatch<T extends KernelCommand>(command: T): Promise<CommandResult<T>>;
455
+ annotations: KernelAnnotations;
397
456
  }
398
457
  interface KernelDeps {
399
458
  persistence: Persistence;
@@ -434,4 +493,4 @@ interface PluginRunner extends EventSink {
434
493
  declare function definePlugin<T extends KernelEventType>(definition: PluginDefinition<T>): PluginDefinition<T>;
435
494
  declare function createPluginRunner(config: PluginRunnerConfig): PluginRunner;
436
495
 
437
- export { WorkflowBuilder as A, type CommandResult as C, IdempotencyInProgressError as I, type JobExecuteCommand as J, type KernelDeps as K, type LeaseReapStaleCommand as L, type OutboxFlushCommand as O, type PluginDefinition as P, type RunCancelCommand as R, type StagePollSuspendedCommand as S, type WorkflowRegistry as W, type JobExecuteResult as a, type Kernel as b, type KernelCommand as c, type KernelCommandType as d, type KernelConfig as e, type LeaseReapStaleResult as f, type OutboxFlushResult as g, type PluginReplayDLQCommand as h, type PluginReplayDLQResult as i, type PluginRunner as j, type PluginRunnerConfig as k, type RunCancelResult as l, type RunClaimPendingCommand as m, type RunClaimPendingResult as n, type RunCreateCommand as o, type RunCreateResult as p, type RunRerunFromCommand as q, type RunRerunFromResult as r, type RunTransitionCommand as s, type RunTransitionResult as t, type StagePollSuspendedResult as u, createKernel as v, createPluginRunner as w, definePlugin as x, Workflow as y, type InferWorkflowStageIds as z };
496
+ export { type AnnotateAttachInput as A, Workflow as B, type CommandResult as C, type InferWorkflowStageIds as D, WorkflowBuilder as E, IdempotencyInProgressError as I, type JobExecuteCommand as J, type KernelDeps as K, type LeaseReapStaleCommand as L, type OutboxFlushCommand as O, type PluginDefinition as P, type RunCancelCommand as R, type StagePollSuspendedCommand as S, type WorkflowRegistry as W, type JobExecuteResult as a, type Kernel as b, type KernelAnnotations as c, type KernelCommand as d, type KernelCommandType as e, type KernelConfig as f, type LeaseReapStaleResult as g, type OutboxFlushResult as h, type PluginReplayDLQCommand as i, type PluginReplayDLQResult as j, type PluginRunner as k, type PluginRunnerConfig as l, type RunCancelResult as m, type RunClaimPendingCommand as n, type RunClaimPendingResult as o, type RunCreateAnnotation as p, type RunCreateCommand as q, type RunCreateResult as r, type RunRerunFromCommand as s, type RunRerunFromResult as t, type RunTransitionCommand as u, type RunTransitionResult as v, type StagePollSuspendedResult as w, createKernel as x, createPluginRunner as y, definePlugin as z };
@@ -1,5 +1,5 @@
1
- import { E as EnqueueJobInput, D as DequeueResult, C as CreateRunInput, W as WorkflowRunRecord, U as UpdateRunInput, S as Status, a as CreateStageInput, b as WorkflowStageRecord, c as UpsertStageInput, d as UpdateStageInput, e as CreateLogInput, f as CreateOutboxEventInput, O as OutboxRecord } from './interface-BeEPzTFy.js';
2
- import { K as KernelEvent } from './events-D_P24UaY.js';
1
+ import { E as EnqueueJobInput, D as DequeueResult, C as CreateRunInput, W as WorkflowRunRecord, U as UpdateRunInput, S as Status, a as CreateStageInput, b as WorkflowStageRecord, c as UpsertStageInput, d as UpdateStageInput, e as CreateLogInput, f as CreateAnnotationInput, A as AnnotationFilters, g as WorkflowAnnotationRecord, h as CreateOutboxEventInput, O as OutboxRecord } from './interface-BPz138Hf.js';
2
+ import { K as KernelEvent } from './events-B3XPPu0c.js';
3
3
 
4
4
  /**
5
5
  * Kernel Port Interfaces
@@ -67,6 +67,15 @@ interface Persistence {
67
67
  getLastCompletedStageBefore(runId: string, executionGroup: number): Promise<WorkflowStageRecord | null>;
68
68
  deleteStage(id: string): Promise<void>;
69
69
  createLog(data: CreateLogInput): Promise<void>;
70
+ /**
71
+ * Append annotations. Called both from outside transactions (run.create,
72
+ * external attach) and inside the stage-completion transactions in
73
+ * job-execute and stage-poll-suspended. Duplicates with the same
74
+ * `(workflowRunId, key, idempotencyKey)` are silently skipped.
75
+ */
76
+ appendAnnotations(inputs: CreateAnnotationInput[]): Promise<void>;
77
+ /** List annotations for a run, ordered by `createdAt` ascending. */
78
+ listAnnotations(workflowRunId: string, filters?: AnnotationFilters): Promise<WorkflowAnnotationRecord[]>;
70
79
  /** Write events to the outbox. Sequences are auto-assigned per workflowRunId. */
71
80
  appendOutboxEvents(events: CreateOutboxEventInput[]): Promise<void>;
72
81
  /** Read unpublished events ordered by (workflowRunId, sequence). */