@yolk-sdk/vercel-workflows 0.1.0-canary.27 → 0.1.0-canary.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +2 -2
- package/dist/workflow-events.d.mts +34 -1
- package/dist/workflow-events.d.mts.map +1 -1
- package/dist/workflow-events.mjs +46 -1
- package/dist/workflow-events.mjs.map +1 -1
- package/dist/workflow.d.mts +2 -2
- package/dist/workflow.mjs +2 -2
- package/package.json +1 -1
- package/src/index.ts +4 -0
- package/src/workflow-events.ts +90 -0
- package/src/workflow.ts +4 -0
package/README.md
CHANGED
|
@@ -23,6 +23,7 @@ Import Workflow APIs from the package root:
|
|
|
23
23
|
|
|
24
24
|
```ts
|
|
25
25
|
import {
|
|
26
|
+
commitThenWriteTerminalEvent,
|
|
26
27
|
makeDurableAgentEventSequencerState,
|
|
27
28
|
noWorkflowStepRetry,
|
|
28
29
|
runVercelAgentWorkflow,
|
|
@@ -118,6 +119,37 @@ The id format is `${streamId}:${turn}:${eventSequence}`. Keep `eventSequence` in
|
|
|
118
119
|
Resume route reads should use `startIndex` when available. Host apps still own active-run locking,
|
|
119
120
|
stale-run guards, and cancellation behavior.
|
|
120
121
|
|
|
122
|
+
## Terminal barriers
|
|
123
|
+
|
|
124
|
+
For durable host streams, terminal events are commit barriers. Emit live/progress events first,
|
|
125
|
+
commit canonical host state, then write the terminal event, then close the writer:
|
|
126
|
+
|
|
127
|
+
```txt
|
|
128
|
+
live events -> host durable commit -> terminal event -> close
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
This lets clients stop consuming at a protocol-terminal event and immediately revalidate or reconnect
|
|
132
|
+
from durable state. Hosts that emit terminal events before persistence should not rely on
|
|
133
|
+
`streamAgentEventsUntilTerminal()` as a durable-settled signal.
|
|
134
|
+
|
|
135
|
+
Use `commitThenWriteTerminalEvent` when a step must commit host state before writing its terminal
|
|
136
|
+
event:
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
const result = await commitThenWriteTerminalEvent({
|
|
140
|
+
terminal,
|
|
141
|
+
commit: () => persistState(),
|
|
142
|
+
write: event => writeDurableAgentEvent({ writer, event, streamId, turn, state }),
|
|
143
|
+
writeCommitError: error =>
|
|
144
|
+
writeDurableAgentEvent({ writer, event: commitErrorEvent(error), streamId, turn, state }),
|
|
145
|
+
close: () => writer.close()
|
|
146
|
+
})
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
The helper never writes the success terminal before `commit` succeeds. If `commit` fails, it writes
|
|
150
|
+
the host-provided terminal error event instead. Terminal write failures still attempt `close`; close
|
|
151
|
+
failures are returned separately and do not turn a successful durable commit into a failed commit.
|
|
152
|
+
|
|
121
153
|
## Host responsibilities
|
|
122
154
|
|
|
123
155
|
- Own Next/Vercel routes, auth, providers, tools, persistence, and telemetry.
|
|
@@ -126,6 +158,7 @@ stale-run guards, and cancellation behavior.
|
|
|
126
158
|
- Decide cancellation/resume/conflict UX.
|
|
127
159
|
- Own hook tokens and response validation for HITL resume.
|
|
128
160
|
- Emit replay-safe event ids for durable streams and de-dupe by `eventId` client-side.
|
|
161
|
+
- Write durable terminal events only after host persistence has settled.
|
|
129
162
|
- Test directive behavior with `@workflow/vitest` when changing package-owned Workflow files.
|
|
130
163
|
|
|
131
164
|
## Boundaries
|
package/dist/index.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { SerializableWorkflowState, VercelAgentWorkflowAwaitingInput, VercelAgentWorkflowInput, VercelAgentWorkflowLoopConfig, VercelAgentWorkflowModelStepInput, VercelAgentWorkflowModelStepResult, VercelAgentWorkflowRunResult, VercelAgentWorkflowStepRetryPolicy, VercelAgentWorkflowToolBatchStepInput, VercelAgentWorkflowToolBatchStepResult, WorkflowStepResult, defaultMaxWorkflowTurns, noWorkflowStepRetry, retryWorkflowStep, runVercelAgentWorkflow, settleWorkflowStep } from "./workflow-loop.mjs";
|
|
2
|
-
import { DurableAgentEvent, DurableAgentEventIdInput, DurableAgentEventSequencerState, SequenceDurableAgentEventInput, SequencedDurableAgentEvent, WriteDurableAgentEventInput, durableAgentEventId, makeDurableAgentEventSequencerState, sequenceDurableAgentEvent, writeDurableAgentEvent } from "./workflow-events.mjs";
|
|
3
|
-
export { type DurableAgentEvent, type DurableAgentEventIdInput, type DurableAgentEventSequencerState, type SequenceDurableAgentEventInput, type SequencedDurableAgentEvent, type SerializableWorkflowState, type VercelAgentWorkflowAwaitingInput, type VercelAgentWorkflowInput, type VercelAgentWorkflowLoopConfig, type VercelAgentWorkflowModelStepInput, type VercelAgentWorkflowModelStepResult, type VercelAgentWorkflowRunResult, type VercelAgentWorkflowStepRetryPolicy, type VercelAgentWorkflowToolBatchStepInput, type VercelAgentWorkflowToolBatchStepResult, type WorkflowStepResult, type WriteDurableAgentEventInput, defaultMaxWorkflowTurns, durableAgentEventId, makeDurableAgentEventSequencerState, noWorkflowStepRetry, retryWorkflowStep, runVercelAgentWorkflow, sequenceDurableAgentEvent, settleWorkflowStep, writeDurableAgentEvent };
|
|
2
|
+
import { CommitThenWriteTerminalEventInput, CommitThenWriteTerminalEventResult, DurableAgentEvent, DurableAgentEventIdInput, DurableAgentEventSequencerState, SequenceDurableAgentEventInput, SequencedDurableAgentEvent, TerminalEventCloseResult, WriteDurableAgentEventInput, commitThenWriteTerminalEvent, durableAgentEventId, makeDurableAgentEventSequencerState, sequenceDurableAgentEvent, writeDurableAgentEvent } from "./workflow-events.mjs";
|
|
3
|
+
export { type CommitThenWriteTerminalEventInput, type CommitThenWriteTerminalEventResult, type DurableAgentEvent, type DurableAgentEventIdInput, type DurableAgentEventSequencerState, type SequenceDurableAgentEventInput, type SequencedDurableAgentEvent, type SerializableWorkflowState, type TerminalEventCloseResult, type VercelAgentWorkflowAwaitingInput, type VercelAgentWorkflowInput, type VercelAgentWorkflowLoopConfig, type VercelAgentWorkflowModelStepInput, type VercelAgentWorkflowModelStepResult, type VercelAgentWorkflowRunResult, type VercelAgentWorkflowStepRetryPolicy, type VercelAgentWorkflowToolBatchStepInput, type VercelAgentWorkflowToolBatchStepResult, type WorkflowStepResult, type WriteDurableAgentEventInput, commitThenWriteTerminalEvent, defaultMaxWorkflowTurns, durableAgentEventId, makeDurableAgentEventSequencerState, noWorkflowStepRetry, retryWorkflowStep, runVercelAgentWorkflow, sequenceDurableAgentEvent, settleWorkflowStep, writeDurableAgentEvent };
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { defaultMaxWorkflowTurns, noWorkflowStepRetry, retryWorkflowStep, runVercelAgentWorkflow, settleWorkflowStep } from "./workflow-loop.mjs";
|
|
2
|
-
import { durableAgentEventId, makeDurableAgentEventSequencerState, sequenceDurableAgentEvent, writeDurableAgentEvent } from "./workflow-events.mjs";
|
|
3
|
-
export { defaultMaxWorkflowTurns, durableAgentEventId, makeDurableAgentEventSequencerState, noWorkflowStepRetry, retryWorkflowStep, runVercelAgentWorkflow, sequenceDurableAgentEvent, settleWorkflowStep, writeDurableAgentEvent };
|
|
2
|
+
import { commitThenWriteTerminalEvent, durableAgentEventId, makeDurableAgentEventSequencerState, sequenceDurableAgentEvent, writeDurableAgentEvent } from "./workflow-events.mjs";
|
|
3
|
+
export { commitThenWriteTerminalEvent, defaultMaxWorkflowTurns, durableAgentEventId, makeDurableAgentEventSequencerState, noWorkflowStepRetry, retryWorkflowStep, runVercelAgentWorkflow, sequenceDurableAgentEvent, settleWorkflowStep, writeDurableAgentEvent };
|
|
@@ -27,10 +27,43 @@ type SequencedDurableAgentEvent<Event extends object = object> = {
|
|
|
27
27
|
type WriteDurableAgentEventInput<Event extends object = object> = SequenceDurableAgentEventInput<Event> & {
|
|
28
28
|
readonly writer: WritableStreamDefaultWriter<Uint8Array>;
|
|
29
29
|
};
|
|
30
|
+
type TerminalEventCloseResult = {
|
|
31
|
+
readonly _tag: 'Closed';
|
|
32
|
+
} | {
|
|
33
|
+
readonly _tag: 'CloseFailed';
|
|
34
|
+
readonly error: unknown;
|
|
35
|
+
};
|
|
36
|
+
type CommitThenWriteTerminalEventInput<TerminalEvent extends object, TerminalWriteResult, CommitErrorWriteResult> = {
|
|
37
|
+
readonly commit: () => Promise<void>;
|
|
38
|
+
readonly terminal: TerminalEvent;
|
|
39
|
+
readonly write: (event: TerminalEvent) => Promise<TerminalWriteResult>;
|
|
40
|
+
readonly writeCommitError: (error: unknown) => Promise<CommitErrorWriteResult>;
|
|
41
|
+
readonly close: () => Promise<void>;
|
|
42
|
+
};
|
|
43
|
+
type CommitThenWriteTerminalEventResult<TerminalWriteResult, CommitErrorWriteResult> = {
|
|
44
|
+
readonly _tag: 'Committed';
|
|
45
|
+
readonly writeResult: TerminalWriteResult;
|
|
46
|
+
readonly closeResult: TerminalEventCloseResult;
|
|
47
|
+
} | {
|
|
48
|
+
readonly _tag: 'CommitFailed';
|
|
49
|
+
readonly commitError: unknown;
|
|
50
|
+
readonly writeResult: CommitErrorWriteResult;
|
|
51
|
+
readonly closeResult: TerminalEventCloseResult;
|
|
52
|
+
} | {
|
|
53
|
+
readonly _tag: 'TerminalWriteFailed';
|
|
54
|
+
readonly error: unknown;
|
|
55
|
+
readonly closeResult: TerminalEventCloseResult;
|
|
56
|
+
} | {
|
|
57
|
+
readonly _tag: 'CommitErrorWriteFailed';
|
|
58
|
+
readonly commitError: unknown;
|
|
59
|
+
readonly error: unknown;
|
|
60
|
+
readonly closeResult: TerminalEventCloseResult;
|
|
61
|
+
};
|
|
30
62
|
declare const makeDurableAgentEventSequencerState: (eventSequence?: number) => DurableAgentEventSequencerState;
|
|
31
63
|
declare const durableAgentEventId: (input: DurableAgentEventIdInput) => string;
|
|
32
64
|
declare const sequenceDurableAgentEvent: <Event extends object>(input: SequenceDurableAgentEventInput<Event>) => SequencedDurableAgentEvent<Event>;
|
|
33
65
|
declare const writeDurableAgentEvent: <Event extends object>(input: WriteDurableAgentEventInput<Event>) => Promise<SequencedDurableAgentEvent<Event>>;
|
|
66
|
+
declare const commitThenWriteTerminalEvent: <TerminalEvent extends object, TerminalWriteResult, CommitErrorWriteResult>(input: CommitThenWriteTerminalEventInput<TerminalEvent, TerminalWriteResult, CommitErrorWriteResult>) => Promise<CommitThenWriteTerminalEventResult<TerminalWriteResult, CommitErrorWriteResult>>;
|
|
34
67
|
//#endregion
|
|
35
|
-
export { DurableAgentEvent, DurableAgentEventIdInput, DurableAgentEventSequencerState, SequenceDurableAgentEventInput, SequencedDurableAgentEvent, WriteDurableAgentEventInput, durableAgentEventId, makeDurableAgentEventSequencerState, sequenceDurableAgentEvent, writeDurableAgentEvent };
|
|
68
|
+
export { CommitThenWriteTerminalEventInput, CommitThenWriteTerminalEventResult, DurableAgentEvent, DurableAgentEventIdInput, DurableAgentEventSequencerState, SequenceDurableAgentEventInput, SequencedDurableAgentEvent, TerminalEventCloseResult, WriteDurableAgentEventInput, commitThenWriteTerminalEvent, durableAgentEventId, makeDurableAgentEventSequencerState, sequenceDurableAgentEvent, writeDurableAgentEvent };
|
|
36
69
|
//# sourceMappingURL=workflow-events.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflow-events.d.mts","names":[],"sources":["../src/workflow-events.ts"],"mappings":";KAAY,+BAAA;EAAA,SACD,aAAa;AAAA;AAAA,KAGZ,iBAAA,kCAAmD,KAAK;EAAA,SACzD,OAAA;EAAA,SACA,WAAA;AAAA;AAAA,KAGC,wBAAA;EAAA,SACD,QAAA;EAAA,SACA,IAAA;EAAA,SACA,aAAA;AAAA;AAAA,KAGC,8BAAA;EAAA,SACD,KAAA,EAAO,+BAAA;EAAA,SACP,QAAA;EAAA,SACA,IAAA;EAAA,SACA,KAAA,EAAO,KAAK;EAAA,SACZ,WAAA;AAAA;AAAA,KAGC,0BAAA;EAAA,SACD,KAAA,EAAO,iBAAA,CAAkB,KAAA;EAAA,SACzB,aAAA;EAAA,SACA,iBAAA;EAAA,SACA,SAAA,EAAW,+BAAA;AAAA;AAAA,KAGV,2BAAA,kCACV,8BAAA,CAA+B,KAAA;EAAA,SACpB,MAAA,EAAQ,2BAAA,CAA4B,UAAA;AAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"workflow-events.d.mts","names":[],"sources":["../src/workflow-events.ts"],"mappings":";KAAY,+BAAA;EAAA,SACD,aAAa;AAAA;AAAA,KAGZ,iBAAA,kCAAmD,KAAK;EAAA,SACzD,OAAA;EAAA,SACA,WAAA;AAAA;AAAA,KAGC,wBAAA;EAAA,SACD,QAAA;EAAA,SACA,IAAA;EAAA,SACA,aAAA;AAAA;AAAA,KAGC,8BAAA;EAAA,SACD,KAAA,EAAO,+BAAA;EAAA,SACP,QAAA;EAAA,SACA,IAAA;EAAA,SACA,KAAA,EAAO,KAAK;EAAA,SACZ,WAAA;AAAA;AAAA,KAGC,0BAAA;EAAA,SACD,KAAA,EAAO,iBAAA,CAAkB,KAAA;EAAA,SACzB,aAAA;EAAA,SACA,iBAAA;EAAA,SACA,SAAA,EAAW,+BAAA;AAAA;AAAA,KAGV,2BAAA,kCACV,8BAAA,CAA+B,KAAA;EAAA,SACpB,MAAA,EAAQ,2BAAA,CAA4B,UAAA;AAAA;AAAA,KAGrC,wBAAA;EAAA,SACG,IAAA;AAAA;EAAA,SACA,IAAA;EAAA,SAA8B,KAAA;AAAA;AAAA,KAEjC,iCAAA;EAAA,SAKD,MAAA,QAAc,OAAA;EAAA,SACd,QAAA,EAAU,aAAA;EAAA,SACV,KAAA,GAAQ,KAAA,EAAO,aAAA,KAAkB,OAAA,CAAQ,mBAAA;EAAA,SACzC,gBAAA,GAAmB,KAAA,cAAmB,OAAA,CAAQ,sBAAA;EAAA,SAC9C,KAAA,QAAa,OAAA;AAAA;AAAA,KAGZ,kCAAA;EAAA,SAEG,IAAA;EAAA,SACA,WAAA,EAAa,mBAAA;EAAA,SACb,WAAA,EAAa,wBAAA;AAAA;EAAA,SAGb,IAAA;EAAA,SACA,WAAA;EAAA,SACA,WAAA,EAAa,sBAAA;EAAA,SACb,WAAA,EAAa,wBAAA;AAAA;EAAA,SAGb,IAAA;EAAA,SACA,KAAA;EAAA,SACA,WAAA,EAAa,wBAAA;AAAA;EAAA,SAGb,IAAA;EAAA,SACA,WAAA;EAAA,SACA,KAAA;EAAA,SACA,WAAA,EAAa,wBAAA;AAAA;AAAA,cAKf,mCAAA,GACX,aAAA,cACC,+BAAsD;AAAA,cAE5C,mBAAA,GAAuB,KAA+B,EAAxB,wBAAwB;AAAA,cAGtD,yBAAA,yBACX,KAAA,EAAO,8BAAA,CAA+B,KAAA,MACrC,0BAAA,CAA2B,KAAA;AAAA,cA0BjB,sBAAA,yBACX,KAAA,EAAO,2BAAA,CAA4B,KAAA,MAClC,OAAA,CAAQ,0BAAA,CAA2B,KAAA;AAAA,cAmBzB,4BAAA,8EAKX,KAAA,EAAO,iCAAA,CACL,aAAA,EACA,mBAAA,EACA,sBAAA,MAED,OAAA,CAAQ,kCAAA,CAAmC,mBAAA,EAAqB,sBAAA"}
|
package/dist/workflow-events.mjs
CHANGED
|
@@ -26,7 +26,52 @@ const writeDurableAgentEvent = async (input) => {
|
|
|
26
26
|
await input.writer.write(encodeDurableAgentEventNdjson(sequenced.event));
|
|
27
27
|
return sequenced;
|
|
28
28
|
};
|
|
29
|
+
const closeTerminalEventWriter = async (close) => {
|
|
30
|
+
try {
|
|
31
|
+
await close();
|
|
32
|
+
return { _tag: "Closed" };
|
|
33
|
+
} catch (error) {
|
|
34
|
+
return {
|
|
35
|
+
_tag: "CloseFailed",
|
|
36
|
+
error
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
const commitThenWriteTerminalEvent = async (input) => {
|
|
41
|
+
try {
|
|
42
|
+
await input.commit();
|
|
43
|
+
} catch (commitError) {
|
|
44
|
+
try {
|
|
45
|
+
return {
|
|
46
|
+
_tag: "CommitFailed",
|
|
47
|
+
commitError,
|
|
48
|
+
writeResult: await input.writeCommitError(commitError),
|
|
49
|
+
closeResult: await closeTerminalEventWriter(input.close)
|
|
50
|
+
};
|
|
51
|
+
} catch (error) {
|
|
52
|
+
return {
|
|
53
|
+
_tag: "CommitErrorWriteFailed",
|
|
54
|
+
commitError,
|
|
55
|
+
error,
|
|
56
|
+
closeResult: await closeTerminalEventWriter(input.close)
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
try {
|
|
61
|
+
return {
|
|
62
|
+
_tag: "Committed",
|
|
63
|
+
writeResult: await input.write(input.terminal),
|
|
64
|
+
closeResult: await closeTerminalEventWriter(input.close)
|
|
65
|
+
};
|
|
66
|
+
} catch (error) {
|
|
67
|
+
return {
|
|
68
|
+
_tag: "TerminalWriteFailed",
|
|
69
|
+
error,
|
|
70
|
+
closeResult: await closeTerminalEventWriter(input.close)
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
};
|
|
29
74
|
//#endregion
|
|
30
|
-
export { durableAgentEventId, makeDurableAgentEventSequencerState, sequenceDurableAgentEvent, writeDurableAgentEvent };
|
|
75
|
+
export { commitThenWriteTerminalEvent, durableAgentEventId, makeDurableAgentEventSequencerState, sequenceDurableAgentEvent, writeDurableAgentEvent };
|
|
31
76
|
|
|
32
77
|
//# sourceMappingURL=workflow-events.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflow-events.mjs","names":[],"sources":["../src/workflow-events.ts"],"sourcesContent":["export type DurableAgentEventSequencerState = {\n readonly eventSequence: number\n}\n\nexport type DurableAgentEvent<Event extends object = object> = Event & {\n readonly eventId: string\n readonly createdAtMs?: number\n}\n\nexport type DurableAgentEventIdInput = {\n readonly streamId: string\n readonly turn: number\n readonly eventSequence: number\n}\n\nexport type SequenceDurableAgentEventInput<Event extends object = object> = {\n readonly state: DurableAgentEventSequencerState\n readonly streamId: string\n readonly turn: number\n readonly event: Event\n readonly createdAtMs?: number\n}\n\nexport type SequencedDurableAgentEvent<Event extends object = object> = {\n readonly event: DurableAgentEvent<Event>\n readonly eventSequence: number\n readonly nextEventSequence: number\n readonly nextState: DurableAgentEventSequencerState\n}\n\nexport type WriteDurableAgentEventInput<Event extends object = object> =\n SequenceDurableAgentEventInput<Event> & {\n readonly writer: WritableStreamDefaultWriter<Uint8Array>\n }\n\nconst textEncoder = new TextEncoder()\n\nexport const makeDurableAgentEventSequencerState = (\n eventSequence = 0\n): DurableAgentEventSequencerState => ({ eventSequence })\n\nexport const durableAgentEventId = (input: DurableAgentEventIdInput) =>\n `${input.streamId}:${input.turn}:${input.eventSequence}`\n\nexport const sequenceDurableAgentEvent = <Event extends object>(\n input: SequenceDurableAgentEventInput<Event>\n): SequencedDurableAgentEvent<Event> => {\n const eventSequence = input.state.eventSequence\n const nextEventSequence = eventSequence + 1\n const event = {\n ...input.event,\n eventId: durableAgentEventId({\n streamId: input.streamId,\n turn: input.turn,\n eventSequence\n }),\n ...(input.createdAtMs === undefined ? {} : { createdAtMs: input.createdAtMs })\n }\n\n return {\n event,\n eventSequence,\n nextEventSequence,\n nextState: makeDurableAgentEventSequencerState(nextEventSequence)\n }\n}\n\nconst encodeDurableAgentEventNdjson = <Event extends object>(\n event: DurableAgentEvent<Event>\n) =>\n textEncoder.encode(`${JSON.stringify(event)}\\n`)\n\nexport const writeDurableAgentEvent = async <Event extends object>(\n input: WriteDurableAgentEventInput<Event>\n): Promise<SequencedDurableAgentEvent<Event>> => {\n const sequenced = sequenceDurableAgentEvent(input)\n await input.writer.write(encodeDurableAgentEventNdjson(sequenced.event))\n\n return sequenced\n}\n"],"mappings":";
|
|
1
|
+
{"version":3,"file":"workflow-events.mjs","names":[],"sources":["../src/workflow-events.ts"],"sourcesContent":["export type DurableAgentEventSequencerState = {\n readonly eventSequence: number\n}\n\nexport type DurableAgentEvent<Event extends object = object> = Event & {\n readonly eventId: string\n readonly createdAtMs?: number\n}\n\nexport type DurableAgentEventIdInput = {\n readonly streamId: string\n readonly turn: number\n readonly eventSequence: number\n}\n\nexport type SequenceDurableAgentEventInput<Event extends object = object> = {\n readonly state: DurableAgentEventSequencerState\n readonly streamId: string\n readonly turn: number\n readonly event: Event\n readonly createdAtMs?: number\n}\n\nexport type SequencedDurableAgentEvent<Event extends object = object> = {\n readonly event: DurableAgentEvent<Event>\n readonly eventSequence: number\n readonly nextEventSequence: number\n readonly nextState: DurableAgentEventSequencerState\n}\n\nexport type WriteDurableAgentEventInput<Event extends object = object> =\n SequenceDurableAgentEventInput<Event> & {\n readonly writer: WritableStreamDefaultWriter<Uint8Array>\n }\n\nexport type TerminalEventCloseResult =\n | { readonly _tag: 'Closed' }\n | { readonly _tag: 'CloseFailed'; readonly error: unknown }\n\nexport type CommitThenWriteTerminalEventInput<\n TerminalEvent extends object,\n TerminalWriteResult,\n CommitErrorWriteResult\n> = {\n readonly commit: () => Promise<void>\n readonly terminal: TerminalEvent\n readonly write: (event: TerminalEvent) => Promise<TerminalWriteResult>\n readonly writeCommitError: (error: unknown) => Promise<CommitErrorWriteResult>\n readonly close: () => Promise<void>\n}\n\nexport type CommitThenWriteTerminalEventResult<TerminalWriteResult, CommitErrorWriteResult> =\n | {\n readonly _tag: 'Committed'\n readonly writeResult: TerminalWriteResult\n readonly closeResult: TerminalEventCloseResult\n }\n | {\n readonly _tag: 'CommitFailed'\n readonly commitError: unknown\n readonly writeResult: CommitErrorWriteResult\n readonly closeResult: TerminalEventCloseResult\n }\n | {\n readonly _tag: 'TerminalWriteFailed'\n readonly error: unknown\n readonly closeResult: TerminalEventCloseResult\n }\n | {\n readonly _tag: 'CommitErrorWriteFailed'\n readonly commitError: unknown\n readonly error: unknown\n readonly closeResult: TerminalEventCloseResult\n }\n\nconst textEncoder = new TextEncoder()\n\nexport const makeDurableAgentEventSequencerState = (\n eventSequence = 0\n): DurableAgentEventSequencerState => ({ eventSequence })\n\nexport const durableAgentEventId = (input: DurableAgentEventIdInput) =>\n `${input.streamId}:${input.turn}:${input.eventSequence}`\n\nexport const sequenceDurableAgentEvent = <Event extends object>(\n input: SequenceDurableAgentEventInput<Event>\n): SequencedDurableAgentEvent<Event> => {\n const eventSequence = input.state.eventSequence\n const nextEventSequence = eventSequence + 1\n const event = {\n ...input.event,\n eventId: durableAgentEventId({\n streamId: input.streamId,\n turn: input.turn,\n eventSequence\n }),\n ...(input.createdAtMs === undefined ? {} : { createdAtMs: input.createdAtMs })\n }\n\n return {\n event,\n eventSequence,\n nextEventSequence,\n nextState: makeDurableAgentEventSequencerState(nextEventSequence)\n }\n}\n\nconst encodeDurableAgentEventNdjson = <Event extends object>(\n event: DurableAgentEvent<Event>\n) =>\n textEncoder.encode(`${JSON.stringify(event)}\\n`)\n\nexport const writeDurableAgentEvent = async <Event extends object>(\n input: WriteDurableAgentEventInput<Event>\n): Promise<SequencedDurableAgentEvent<Event>> => {\n const sequenced = sequenceDurableAgentEvent(input)\n await input.writer.write(encodeDurableAgentEventNdjson(sequenced.event))\n\n return sequenced\n}\n\nconst closeTerminalEventWriter = async (\n close: () => Promise<void>\n): Promise<TerminalEventCloseResult> => {\n try {\n await close()\n\n return { _tag: 'Closed' }\n } catch (error) {\n return { _tag: 'CloseFailed', error }\n }\n}\n\nexport const commitThenWriteTerminalEvent = async <\n TerminalEvent extends object,\n TerminalWriteResult,\n CommitErrorWriteResult\n>(\n input: CommitThenWriteTerminalEventInput<\n TerminalEvent,\n TerminalWriteResult,\n CommitErrorWriteResult\n >\n): Promise<CommitThenWriteTerminalEventResult<TerminalWriteResult, CommitErrorWriteResult>> => {\n try {\n await input.commit()\n } catch (commitError) {\n try {\n const writeResult = await input.writeCommitError(commitError)\n const closeResult = await closeTerminalEventWriter(input.close)\n\n return { _tag: 'CommitFailed', commitError, writeResult, closeResult }\n } catch (error) {\n const closeResult = await closeTerminalEventWriter(input.close)\n\n return { _tag: 'CommitErrorWriteFailed', commitError, error, closeResult }\n }\n }\n\n try {\n const writeResult = await input.write(input.terminal)\n const closeResult = await closeTerminalEventWriter(input.close)\n\n return { _tag: 'Committed', writeResult, closeResult }\n } catch (error) {\n const closeResult = await closeTerminalEventWriter(input.close)\n\n return { _tag: 'TerminalWriteFailed', error, closeResult }\n }\n}\n"],"mappings":";AA2EA,MAAM,cAAc,IAAI,YAAY;AAEpC,MAAa,uCACX,gBAAgB,OACqB,EAAE,cAAc;AAEvD,MAAa,uBAAuB,UAClC,GAAG,MAAM,SAAS,GAAG,MAAM,KAAK,GAAG,MAAM;AAE3C,MAAa,6BACX,UACsC;CACtC,MAAM,gBAAgB,MAAM,MAAM;CAClC,MAAM,oBAAoB,gBAAgB;CAW1C,OAAO;EACL,OAAA;GAVA,GAAG,MAAM;GACT,SAAS,oBAAoB;IAC3B,UAAU,MAAM;IAChB,MAAM,MAAM;IACZ;GACF,CAAC;GACD,GAAI,MAAM,gBAAgB,KAAA,IAAY,CAAC,IAAI,EAAE,aAAa,MAAM,YAAY;EAIxE;EACJ;EACA;EACA,WAAW,oCAAoC,iBAAiB;CAClE;AACF;AAEA,MAAM,iCACJ,UAEA,YAAY,OAAO,GAAG,KAAK,UAAU,KAAK,EAAE,GAAG;AAEjD,MAAa,yBAAyB,OACpC,UAC+C;CAC/C,MAAM,YAAY,0BAA0B,KAAK;CACjD,MAAM,MAAM,OAAO,MAAM,8BAA8B,UAAU,KAAK,CAAC;CAEvE,OAAO;AACT;AAEA,MAAM,2BAA2B,OAC/B,UACsC;CACtC,IAAI;EACF,MAAM,MAAM;EAEZ,OAAO,EAAE,MAAM,SAAS;CAC1B,SAAS,OAAO;EACd,OAAO;GAAE,MAAM;GAAe;EAAM;CACtC;AACF;AAEA,MAAa,+BAA+B,OAK1C,UAK6F;CAC7F,IAAI;EACF,MAAM,MAAM,OAAO;CACrB,SAAS,aAAa;EACpB,IAAI;GAIF,OAAO;IAAE,MAAM;IAAgB;IAAa,aAAA,MAHlB,MAAM,iBAAiB,WAAW;IAGH,aAAA,MAF/B,yBAAyB,MAAM,KAAK;GAEO;EACvE,SAAS,OAAO;GAGd,OAAO;IAAE,MAAM;IAA0B;IAAa;IAAO,aAAA,MAFnC,yBAAyB,MAAM,KAAK;GAEW;EAC3E;CACF;CAEA,IAAI;EAIF,OAAO;GAAE,MAAM;GAAa,aAAA,MAHF,MAAM,MAAM,MAAM,QAAQ;GAGX,aAAA,MAFf,yBAAyB,MAAM,KAAK;EAET;CACvD,SAAS,OAAO;EAGd,OAAO;GAAE,MAAM;GAAuB;GAAO,aAAA,MAFnB,yBAAyB,MAAM,KAAK;EAEL;CAC3D;AACF"}
|
package/dist/workflow.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { SerializableWorkflowState, VercelAgentWorkflowAwaitingInput, VercelAgentWorkflowInput, VercelAgentWorkflowLoopConfig, VercelAgentWorkflowModelStepInput, VercelAgentWorkflowModelStepResult, VercelAgentWorkflowRunResult, VercelAgentWorkflowStepRetryPolicy, VercelAgentWorkflowToolBatchStepInput, VercelAgentWorkflowToolBatchStepResult, WorkflowStepResult, defaultMaxWorkflowTurns, noWorkflowStepRetry, retryWorkflowStep, runVercelAgentWorkflow, settleWorkflowStep } from "./workflow-loop.mjs";
|
|
2
|
-
import { DurableAgentEvent, DurableAgentEventIdInput, DurableAgentEventSequencerState, SequenceDurableAgentEventInput, SequencedDurableAgentEvent, WriteDurableAgentEventInput, durableAgentEventId, makeDurableAgentEventSequencerState, sequenceDurableAgentEvent, writeDurableAgentEvent } from "./workflow-events.mjs";
|
|
3
|
-
export { type DurableAgentEvent, type DurableAgentEventIdInput, type DurableAgentEventSequencerState, type SequenceDurableAgentEventInput, type SequencedDurableAgentEvent, type SerializableWorkflowState, type VercelAgentWorkflowAwaitingInput, type VercelAgentWorkflowInput, type VercelAgentWorkflowLoopConfig, type VercelAgentWorkflowModelStepInput, type VercelAgentWorkflowModelStepResult, type VercelAgentWorkflowRunResult, type VercelAgentWorkflowStepRetryPolicy, type VercelAgentWorkflowToolBatchStepInput, type VercelAgentWorkflowToolBatchStepResult, type WorkflowStepResult, type WriteDurableAgentEventInput, defaultMaxWorkflowTurns, durableAgentEventId, makeDurableAgentEventSequencerState, noWorkflowStepRetry, retryWorkflowStep, runVercelAgentWorkflow, sequenceDurableAgentEvent, settleWorkflowStep, writeDurableAgentEvent };
|
|
2
|
+
import { CommitThenWriteTerminalEventInput, CommitThenWriteTerminalEventResult, DurableAgentEvent, DurableAgentEventIdInput, DurableAgentEventSequencerState, SequenceDurableAgentEventInput, SequencedDurableAgentEvent, TerminalEventCloseResult, WriteDurableAgentEventInput, commitThenWriteTerminalEvent, durableAgentEventId, makeDurableAgentEventSequencerState, sequenceDurableAgentEvent, writeDurableAgentEvent } from "./workflow-events.mjs";
|
|
3
|
+
export { type CommitThenWriteTerminalEventInput, type CommitThenWriteTerminalEventResult, type DurableAgentEvent, type DurableAgentEventIdInput, type DurableAgentEventSequencerState, type SequenceDurableAgentEventInput, type SequencedDurableAgentEvent, type SerializableWorkflowState, type TerminalEventCloseResult, type VercelAgentWorkflowAwaitingInput, type VercelAgentWorkflowInput, type VercelAgentWorkflowLoopConfig, type VercelAgentWorkflowModelStepInput, type VercelAgentWorkflowModelStepResult, type VercelAgentWorkflowRunResult, type VercelAgentWorkflowStepRetryPolicy, type VercelAgentWorkflowToolBatchStepInput, type VercelAgentWorkflowToolBatchStepResult, type WorkflowStepResult, type WriteDurableAgentEventInput, commitThenWriteTerminalEvent, defaultMaxWorkflowTurns, durableAgentEventId, makeDurableAgentEventSequencerState, noWorkflowStepRetry, retryWorkflowStep, runVercelAgentWorkflow, sequenceDurableAgentEvent, settleWorkflowStep, writeDurableAgentEvent };
|
package/dist/workflow.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { defaultMaxWorkflowTurns, noWorkflowStepRetry, retryWorkflowStep, runVercelAgentWorkflow, settleWorkflowStep } from "./workflow-loop.mjs";
|
|
2
|
-
import { durableAgentEventId, makeDurableAgentEventSequencerState, sequenceDurableAgentEvent, writeDurableAgentEvent } from "./workflow-events.mjs";
|
|
3
|
-
export { defaultMaxWorkflowTurns, durableAgentEventId, makeDurableAgentEventSequencerState, noWorkflowStepRetry, retryWorkflowStep, runVercelAgentWorkflow, sequenceDurableAgentEvent, settleWorkflowStep, writeDurableAgentEvent };
|
|
2
|
+
import { commitThenWriteTerminalEvent, durableAgentEventId, makeDurableAgentEventSequencerState, sequenceDurableAgentEvent, writeDurableAgentEvent } from "./workflow-events.mjs";
|
|
3
|
+
export { commitThenWriteTerminalEvent, defaultMaxWorkflowTurns, durableAgentEventId, makeDurableAgentEventSequencerState, noWorkflowStepRetry, retryWorkflowStep, runVercelAgentWorkflow, sequenceDurableAgentEvent, settleWorkflowStep, writeDurableAgentEvent };
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export {
|
|
2
|
+
commitThenWriteTerminalEvent,
|
|
2
3
|
durableAgentEventId,
|
|
3
4
|
defaultMaxWorkflowTurns,
|
|
4
5
|
makeDurableAgentEventSequencerState,
|
|
@@ -10,6 +11,8 @@ export {
|
|
|
10
11
|
writeDurableAgentEvent
|
|
11
12
|
} from './workflow.ts'
|
|
12
13
|
export type {
|
|
14
|
+
CommitThenWriteTerminalEventInput,
|
|
15
|
+
CommitThenWriteTerminalEventResult,
|
|
13
16
|
DurableAgentEvent,
|
|
14
17
|
DurableAgentEventIdInput,
|
|
15
18
|
DurableAgentEventSequencerState,
|
|
@@ -25,6 +28,7 @@ export type {
|
|
|
25
28
|
VercelAgentWorkflowStepRetryPolicy,
|
|
26
29
|
VercelAgentWorkflowToolBatchStepInput,
|
|
27
30
|
VercelAgentWorkflowToolBatchStepResult,
|
|
31
|
+
TerminalEventCloseResult,
|
|
28
32
|
WorkflowStepResult,
|
|
29
33
|
WriteDurableAgentEventInput
|
|
30
34
|
} from './workflow.ts'
|
package/src/workflow-events.ts
CHANGED
|
@@ -33,6 +33,46 @@ export type WriteDurableAgentEventInput<Event extends object = object> =
|
|
|
33
33
|
readonly writer: WritableStreamDefaultWriter<Uint8Array>
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
export type TerminalEventCloseResult =
|
|
37
|
+
| { readonly _tag: 'Closed' }
|
|
38
|
+
| { readonly _tag: 'CloseFailed'; readonly error: unknown }
|
|
39
|
+
|
|
40
|
+
export type CommitThenWriteTerminalEventInput<
|
|
41
|
+
TerminalEvent extends object,
|
|
42
|
+
TerminalWriteResult,
|
|
43
|
+
CommitErrorWriteResult
|
|
44
|
+
> = {
|
|
45
|
+
readonly commit: () => Promise<void>
|
|
46
|
+
readonly terminal: TerminalEvent
|
|
47
|
+
readonly write: (event: TerminalEvent) => Promise<TerminalWriteResult>
|
|
48
|
+
readonly writeCommitError: (error: unknown) => Promise<CommitErrorWriteResult>
|
|
49
|
+
readonly close: () => Promise<void>
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export type CommitThenWriteTerminalEventResult<TerminalWriteResult, CommitErrorWriteResult> =
|
|
53
|
+
| {
|
|
54
|
+
readonly _tag: 'Committed'
|
|
55
|
+
readonly writeResult: TerminalWriteResult
|
|
56
|
+
readonly closeResult: TerminalEventCloseResult
|
|
57
|
+
}
|
|
58
|
+
| {
|
|
59
|
+
readonly _tag: 'CommitFailed'
|
|
60
|
+
readonly commitError: unknown
|
|
61
|
+
readonly writeResult: CommitErrorWriteResult
|
|
62
|
+
readonly closeResult: TerminalEventCloseResult
|
|
63
|
+
}
|
|
64
|
+
| {
|
|
65
|
+
readonly _tag: 'TerminalWriteFailed'
|
|
66
|
+
readonly error: unknown
|
|
67
|
+
readonly closeResult: TerminalEventCloseResult
|
|
68
|
+
}
|
|
69
|
+
| {
|
|
70
|
+
readonly _tag: 'CommitErrorWriteFailed'
|
|
71
|
+
readonly commitError: unknown
|
|
72
|
+
readonly error: unknown
|
|
73
|
+
readonly closeResult: TerminalEventCloseResult
|
|
74
|
+
}
|
|
75
|
+
|
|
36
76
|
const textEncoder = new TextEncoder()
|
|
37
77
|
|
|
38
78
|
export const makeDurableAgentEventSequencerState = (
|
|
@@ -78,3 +118,53 @@ export const writeDurableAgentEvent = async <Event extends object>(
|
|
|
78
118
|
|
|
79
119
|
return sequenced
|
|
80
120
|
}
|
|
121
|
+
|
|
122
|
+
const closeTerminalEventWriter = async (
|
|
123
|
+
close: () => Promise<void>
|
|
124
|
+
): Promise<TerminalEventCloseResult> => {
|
|
125
|
+
try {
|
|
126
|
+
await close()
|
|
127
|
+
|
|
128
|
+
return { _tag: 'Closed' }
|
|
129
|
+
} catch (error) {
|
|
130
|
+
return { _tag: 'CloseFailed', error }
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export const commitThenWriteTerminalEvent = async <
|
|
135
|
+
TerminalEvent extends object,
|
|
136
|
+
TerminalWriteResult,
|
|
137
|
+
CommitErrorWriteResult
|
|
138
|
+
>(
|
|
139
|
+
input: CommitThenWriteTerminalEventInput<
|
|
140
|
+
TerminalEvent,
|
|
141
|
+
TerminalWriteResult,
|
|
142
|
+
CommitErrorWriteResult
|
|
143
|
+
>
|
|
144
|
+
): Promise<CommitThenWriteTerminalEventResult<TerminalWriteResult, CommitErrorWriteResult>> => {
|
|
145
|
+
try {
|
|
146
|
+
await input.commit()
|
|
147
|
+
} catch (commitError) {
|
|
148
|
+
try {
|
|
149
|
+
const writeResult = await input.writeCommitError(commitError)
|
|
150
|
+
const closeResult = await closeTerminalEventWriter(input.close)
|
|
151
|
+
|
|
152
|
+
return { _tag: 'CommitFailed', commitError, writeResult, closeResult }
|
|
153
|
+
} catch (error) {
|
|
154
|
+
const closeResult = await closeTerminalEventWriter(input.close)
|
|
155
|
+
|
|
156
|
+
return { _tag: 'CommitErrorWriteFailed', commitError, error, closeResult }
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
try {
|
|
161
|
+
const writeResult = await input.write(input.terminal)
|
|
162
|
+
const closeResult = await closeTerminalEventWriter(input.close)
|
|
163
|
+
|
|
164
|
+
return { _tag: 'Committed', writeResult, closeResult }
|
|
165
|
+
} catch (error) {
|
|
166
|
+
const closeResult = await closeTerminalEventWriter(input.close)
|
|
167
|
+
|
|
168
|
+
return { _tag: 'TerminalWriteFailed', error, closeResult }
|
|
169
|
+
}
|
|
170
|
+
}
|
package/src/workflow.ts
CHANGED
|
@@ -6,6 +6,7 @@ export {
|
|
|
6
6
|
settleWorkflowStep
|
|
7
7
|
} from './workflow-loop.ts'
|
|
8
8
|
export {
|
|
9
|
+
commitThenWriteTerminalEvent,
|
|
9
10
|
durableAgentEventId,
|
|
10
11
|
makeDurableAgentEventSequencerState,
|
|
11
12
|
sequenceDurableAgentEvent,
|
|
@@ -28,7 +29,10 @@ export type {
|
|
|
28
29
|
DurableAgentEvent,
|
|
29
30
|
DurableAgentEventIdInput,
|
|
30
31
|
DurableAgentEventSequencerState,
|
|
32
|
+
CommitThenWriteTerminalEventInput,
|
|
33
|
+
CommitThenWriteTerminalEventResult,
|
|
31
34
|
SequenceDurableAgentEventInput,
|
|
32
35
|
SequencedDurableAgentEvent,
|
|
36
|
+
TerminalEventCloseResult,
|
|
33
37
|
WriteDurableAgentEventInput
|
|
34
38
|
} from './workflow-events.ts'
|