@effect-agent/workflow 0.1.0-beta.46

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.
@@ -0,0 +1,118 @@
1
+ import { SettlementId } from "@effect-agent/core/Identifiers";
2
+ import { Receipt } from "@effect-agent/thread/DurableAgentRuntime";
3
+ import { DeploymentId } from "@effect-agent/thread/Records";
4
+ import { Context, Effect, Schema, type Scope } from "effect";
5
+ import { DurableDeferred } from "effect/unstable/workflow";
6
+
7
+ /** Only identities cross the Workflow boundary; the agent journal owns the outcome. */
8
+ export class WorkflowSubmission extends Schema.Class<WorkflowSubmission>(
9
+ "@effect-agent/workflow/WorkflowSubmission",
10
+ )({
11
+ version: Schema.Literal(1),
12
+ deploymentId: DeploymentId,
13
+ receipt: Receipt,
14
+ }) {}
15
+
16
+ export class WorkflowSettlementReference extends Schema.Class<WorkflowSettlementReference>(
17
+ "@effect-agent/workflow/WorkflowSettlementReference",
18
+ )({
19
+ version: Schema.Literal(1),
20
+ submissionId: Receipt.fields.submissionId,
21
+ threadId: Receipt.fields.threadId,
22
+ settlementId: SettlementId,
23
+ }) {}
24
+
25
+ /** Retained until native success has been checked against the canonical Settlement. */
26
+ export class WorkflowDispatchIntent extends Schema.Class<WorkflowDispatchIntent>(
27
+ "@effect-agent/workflow/WorkflowDispatchIntent",
28
+ )({
29
+ ...WorkflowSubmission.fields,
30
+ workflowName: Schema.NonEmptyString,
31
+ executionId: Schema.NonEmptyString,
32
+ /** One workflow step owns this submission. Repair must notify it before removing the intent. */
33
+ completionToken: Schema.optionalKey(DurableDeferred.Token),
34
+ }) {}
35
+
36
+ export class WorkflowDispatchError extends Schema.TaggedError<WorkflowDispatchError>()(
37
+ "WorkflowDispatchError",
38
+ {
39
+ operation: Schema.String,
40
+ message: Schema.String,
41
+ cause: Schema.optionalKey(Schema.Defect()),
42
+ },
43
+ ) {}
44
+
45
+ export class WorkflowDispatchScan extends Schema.Class<WorkflowDispatchScan>(
46
+ "@effect-agent/workflow/WorkflowDispatchScan",
47
+ )({
48
+ deploymentId: DeploymentId,
49
+ workflowName: Schema.NonEmptyString,
50
+ after: Schema.optionalKey(Schema.String),
51
+ limit: Schema.Int.check(Schema.isBetween({ minimum: 1, maximum: 1000 })),
52
+ }) {}
53
+
54
+ /**
55
+ * Adapter-private outbox. `put` returns the stored intent, preserving an existing completion
56
+ * token when omitted and allowing its one-time attachment. Different identities or tokens
57
+ * conflict. `remove` must compare the entire intent, so a concurrent token attachment cannot
58
+ * be lost. `scan` returns at most limit rows in executionId order, after
59
+ * the exclusive cursor, filtered by deployment and workflow. All writes are durable
60
+ * before returning. No transcript, outcome, or native engine storage belongs here.
61
+ */
62
+ export class WorkflowDispatchStore extends Context.Service<
63
+ WorkflowDispatchStore,
64
+ {
65
+ readonly put: (
66
+ intent: WorkflowDispatchIntent,
67
+ ) => Effect.Effect<WorkflowDispatchIntent, WorkflowDispatchError>;
68
+ readonly scan: (
69
+ request: WorkflowDispatchScan,
70
+ ) => Effect.Effect<ReadonlyArray<WorkflowDispatchIntent>, WorkflowDispatchError>;
71
+ readonly remove: (intent: WorkflowDispatchIntent) => Effect.Effect<void, WorkflowDispatchError>;
72
+ }
73
+ >()("@effect-agent/workflow/WorkflowDispatchStore") {}
74
+
75
+ /**
76
+ * Host-owned durable repair trigger. Register before admission opens. The host must
77
+ * invoke repair at startup and repeatedly after lost hints or process loss. A Node
78
+ * deployment may use a scoped poller; other hosts may use alarms or durable jobs.
79
+ * Stop invoking the callback when this Scope closes. The shared driver starts no loop.
80
+ */
81
+ export class WorkflowRepairTrigger extends Context.Service<
82
+ WorkflowRepairTrigger,
83
+ {
84
+ readonly register: (repair: Effect.Effect<void>) => Effect.Effect<void, never, Scope.Scope>;
85
+ }
86
+ >()("@effect-agent/workflow/WorkflowRepairTrigger") {}
87
+
88
+ export const WorkflowDispatchFailpointLocation = Schema.Literals([
89
+ "intent:before-persist",
90
+ "intent:after-persist",
91
+ "launch:before",
92
+ "launch:after",
93
+ "completion:before-observe",
94
+ "completion:after-observe",
95
+ "completion:before-notify",
96
+ "completion:after-notify",
97
+ "cleanup:before",
98
+ "cleanup:after",
99
+ ]);
100
+
101
+ export type WorkflowDispatchFailpointLocation = typeof WorkflowDispatchFailpointLocation.Type;
102
+
103
+ export const WorkflowDispatchFailpoint = Context.Reference<{
104
+ readonly hit: (
105
+ location: WorkflowDispatchFailpointLocation,
106
+ intent: WorkflowDispatchIntent,
107
+ ) => Effect.Effect<void, WorkflowDispatchError>;
108
+ }>("@effect-agent/workflow/WorkflowDispatchFailpoint", {
109
+ defaultValue: () => ({ hit: () => Effect.void }),
110
+ });
111
+
112
+ export class WorkflowRepairReport extends Schema.Class<WorkflowRepairReport>(
113
+ "@effect-agent/workflow/WorkflowRepairReport",
114
+ )({
115
+ discovered: Schema.Int,
116
+ inspected: Schema.Int,
117
+ completed: Schema.Int,
118
+ }) {}
@@ -0,0 +1,33 @@
1
+ import type { AgentId } from "@effect-agent/core/Identifiers";
2
+ import { Receipt } from "@effect-agent/thread/DurableAgentRuntime";
3
+ import { SettlementFailureDiagnostic } from "@effect-agent/thread/Records";
4
+ import { Schema } from "effect";
5
+
6
+ /** Must be the exact registered Definition instance; its model and tool services belong to registration. */
7
+ export interface WorkflowAgent<Input extends Schema.Top, Output extends Schema.Top> {
8
+ readonly id: typeof AgentId.Type;
9
+ readonly input: Input;
10
+ readonly output: Output;
11
+ }
12
+
13
+ export interface WorkflowExecuteOptions {
14
+ /** Stable, nonempty step name, unique within one parent execution. Use item IDs in loops. */
15
+ readonly name: string;
16
+ }
17
+
18
+ /** A terminal agent outcome or invalid invocation, distinct from retriable infrastructure errors. */
19
+ export class WorkflowExecutionFailure extends Schema.TaggedError<WorkflowExecutionFailure>()(
20
+ "WorkflowExecutionFailure",
21
+ {
22
+ reason: Schema.Literals([
23
+ "invalid-name",
24
+ "engine-mismatch",
25
+ "failed",
26
+ "aborted",
27
+ "missing-output",
28
+ ]),
29
+ message: Schema.String,
30
+ receipt: Schema.optionalKey(Receipt),
31
+ failure: Schema.optionalKey(SettlementFailureDiagnostic),
32
+ },
33
+ ) {}
package/src/index.ts ADDED
@@ -0,0 +1,4 @@
1
+ export * as AgentWorkflow from "./AgentWorkflow.ts";
2
+ export * as WorkflowAgentHost from "./WorkflowAgentHost.ts";
3
+ export * as WorkflowDispatch from "./WorkflowDispatch.ts";
4
+ export * as WorkflowExecution from "./WorkflowExecution.ts";
@@ -0,0 +1,7 @@
1
+ import { DurableDeferred } from "effect/unstable/workflow";
2
+
3
+ import { WorkflowSettlementReference } from "../WorkflowDispatch.ts";
4
+
5
+ /** Native deferred results contain only canonical identities, never a second agent result. */
6
+ export const workflowCompletion = (name: string) =>
7
+ DurableDeferred.make(name, { success: WorkflowSettlementReference });