@yolk-sdk/vercel-workflows 0.1.0-canary.100
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/LICENSE +21 -0
- package/README.md +340 -0
- package/dist/effect.d.mts +56 -0
- package/dist/effect.d.mts.map +1 -0
- package/dist/effect.mjs +58 -0
- package/dist/effect.mjs.map +1 -0
- package/dist/index.d.mts +4 -0
- package/dist/index.mjs +4 -0
- package/dist/testing/index.d.mts +97 -0
- package/dist/testing/index.d.mts.map +1 -0
- package/dist/testing/index.mjs +285 -0
- package/dist/testing/index.mjs.map +1 -0
- package/dist/workflow-children.d.mts +42 -0
- package/dist/workflow-children.d.mts.map +1 -0
- package/dist/workflow-children.mjs +54 -0
- package/dist/workflow-children.mjs.map +1 -0
- package/dist/workflow-events.d.mts +210 -0
- package/dist/workflow-events.d.mts.map +1 -0
- package/dist/workflow-events.mjs +54 -0
- package/dist/workflow-events.mjs.map +1 -0
- package/dist/workflow-loop.d.mts +416 -0
- package/dist/workflow-loop.d.mts.map +1 -0
- package/dist/workflow-loop.mjs +177 -0
- package/dist/workflow-loop.mjs.map +1 -0
- package/dist/workflow.d.mts +4 -0
- package/dist/workflow.mjs +4 -0
- package/package.json +77 -0
- package/src/effect.ts +232 -0
- package/src/index.ts +36 -0
- package/src/testing/index.ts +503 -0
- package/src/workflow-children.ts +81 -0
- package/src/workflow-events.ts +202 -0
- package/src/workflow-loop.ts +404 -0
- package/src/workflow.ts +42 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Data, Effect } from "effect";
|
|
2
|
+
//#region src/workflow-events.ts
|
|
3
|
+
const CommitThenWriteTerminalEventResult = Data.taggedEnum();
|
|
4
|
+
const textEncoder = new TextEncoder();
|
|
5
|
+
const makeDurableAgentEventSequencerState = (eventSequence = 0) => ({ eventSequence });
|
|
6
|
+
const durableAgentEventId = (input) => `${input.streamId}:${input.turn}:${input.eventSequence}`;
|
|
7
|
+
const sequenceDurableAgentEvent = (input) => {
|
|
8
|
+
const eventSequence = input.state.eventSequence;
|
|
9
|
+
const nextEventSequence = eventSequence + 1;
|
|
10
|
+
const event = {
|
|
11
|
+
...input.event,
|
|
12
|
+
eventId: durableAgentEventId({
|
|
13
|
+
streamId: input.streamId,
|
|
14
|
+
turn: input.turn,
|
|
15
|
+
eventSequence
|
|
16
|
+
})
|
|
17
|
+
};
|
|
18
|
+
if (input.createdAtMs !== void 0) event.createdAtMs = input.createdAtMs;
|
|
19
|
+
return {
|
|
20
|
+
event,
|
|
21
|
+
eventSequence,
|
|
22
|
+
nextEventSequence,
|
|
23
|
+
nextState: makeDurableAgentEventSequencerState(nextEventSequence)
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
const encodeDurableAgentEventNdjson = (event) => textEncoder.encode(`${JSON.stringify(event)}\n`);
|
|
27
|
+
const writeDurableAgentEvent = (input) => Effect.gen(function* () {
|
|
28
|
+
const sequenced = sequenceDurableAgentEvent(input);
|
|
29
|
+
yield* Effect.tryPromise({
|
|
30
|
+
try: () => input.writer.write(encodeDurableAgentEventNdjson(sequenced.event)),
|
|
31
|
+
catch: (cause) => cause
|
|
32
|
+
});
|
|
33
|
+
return sequenced;
|
|
34
|
+
});
|
|
35
|
+
const commitThenWriteTerminalEvent = (input) => input.commit.pipe(Effect.matchEffect({
|
|
36
|
+
onFailure: (commitError) => input.writeCommitError(commitError).pipe(Effect.match({
|
|
37
|
+
onFailure: (error) => CommitThenWriteTerminalEventResult.CommitErrorWriteFailed({
|
|
38
|
+
commitError,
|
|
39
|
+
error
|
|
40
|
+
}),
|
|
41
|
+
onSuccess: (writeResult) => CommitThenWriteTerminalEventResult.CommitFailed({
|
|
42
|
+
commitError,
|
|
43
|
+
writeResult
|
|
44
|
+
})
|
|
45
|
+
})),
|
|
46
|
+
onSuccess: () => input.write(input.terminal).pipe(Effect.match({
|
|
47
|
+
onFailure: (error) => CommitThenWriteTerminalEventResult.TerminalWriteFailed({ error }),
|
|
48
|
+
onSuccess: (writeResult) => CommitThenWriteTerminalEventResult.Committed({ writeResult })
|
|
49
|
+
}))
|
|
50
|
+
}));
|
|
51
|
+
//#endregion
|
|
52
|
+
export { CommitThenWriteTerminalEventResult, commitThenWriteTerminalEvent, durableAgentEventId, makeDurableAgentEventSequencerState, sequenceDurableAgentEvent, writeDurableAgentEvent };
|
|
53
|
+
|
|
54
|
+
//# sourceMappingURL=workflow-events.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-events.mjs","names":[],"sources":["../src/workflow-events.ts"],"sourcesContent":["import { Data, Effect } from 'effect'\n\nexport 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 /**\n * Stable id namespace for one independent durable stream.\n *\n * Include the workflow/session/run id when multiple logical runs can be\n * projected in the same client. Replay-safe clients de-dupe by `eventId`, so\n * reusing a stream id across runs can drop legitimate follow-up events.\n */\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 CommitThenWriteTerminalEventInput<\n TerminalEvent extends object,\n TerminalWriteResult,\n CommitErrorWriteResult,\n CommitError,\n TerminalWriteError,\n CommitErrorWriteError\n> = {\n readonly commit: Effect.Effect<void, CommitError>\n readonly terminal: TerminalEvent\n readonly write: (event: TerminalEvent) => Effect.Effect<TerminalWriteResult, TerminalWriteError>\n readonly writeCommitError: (\n error: CommitError\n ) => Effect.Effect<CommitErrorWriteResult, CommitErrorWriteError>\n}\n\nexport type CommitThenWriteTerminalEventResult<TerminalWriteResult, CommitErrorWriteResult> =\n Data.TaggedEnum<{\n Committed: {\n readonly writeResult: TerminalWriteResult\n }\n CommitFailed: {\n readonly commitError: unknown\n readonly writeResult: CommitErrorWriteResult\n }\n TerminalWriteFailed: {\n readonly error: unknown\n }\n CommitErrorWriteFailed: {\n readonly commitError: unknown\n readonly error: unknown\n }\n }>\n\ninterface CommitThenWriteTerminalEventResultDefinition extends Data.TaggedEnum.WithGenerics<2> {\n readonly taggedEnum: CommitThenWriteTerminalEventResult<this['A'], this['B']>\n}\n\nexport const CommitThenWriteTerminalEventResult =\n Data.taggedEnum<CommitThenWriteTerminalEventResultDefinition>()\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\n type SequencedDurableAgentEventFields = Event & {\n eventId: string\n createdAtMs?: number\n }\n\n const event: SequencedDurableAgentEventFields = {\n ...input.event,\n eventId: durableAgentEventId({\n streamId: input.streamId,\n turn: input.turn,\n eventSequence\n })\n }\n\n if (input.createdAtMs !== undefined) {\n event.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>(event: DurableAgentEvent<Event>) =>\n textEncoder.encode(`${JSON.stringify(event)}\\n`)\n\nexport const writeDurableAgentEvent = <Event extends object>(\n input: WriteDurableAgentEventInput<Event>\n): Effect.Effect<SequencedDurableAgentEvent<Event>, unknown> =>\n Effect.gen(function* () {\n const sequenced = sequenceDurableAgentEvent(input)\n yield* Effect.tryPromise({\n try: () => input.writer.write(encodeDurableAgentEventNdjson(sequenced.event)),\n catch: cause => cause\n })\n\n return sequenced\n })\n\nexport const commitThenWriteTerminalEvent = <\n TerminalEvent extends object,\n TerminalWriteResult,\n CommitErrorWriteResult,\n CommitError,\n TerminalWriteError,\n CommitErrorWriteError\n>(\n input: CommitThenWriteTerminalEventInput<\n TerminalEvent,\n TerminalWriteResult,\n CommitErrorWriteResult,\n CommitError,\n TerminalWriteError,\n CommitErrorWriteError\n >\n): Effect.Effect<\n CommitThenWriteTerminalEventResult<TerminalWriteResult, CommitErrorWriteResult>,\n never\n> =>\n input.commit.pipe(\n Effect.matchEffect({\n onFailure: commitError =>\n input.writeCommitError(commitError).pipe(\n Effect.match({\n onFailure: error =>\n CommitThenWriteTerminalEventResult.CommitErrorWriteFailed<\n TerminalWriteResult,\n CommitErrorWriteResult\n >({\n commitError,\n error\n }),\n onSuccess: writeResult =>\n CommitThenWriteTerminalEventResult.CommitFailed<\n TerminalWriteResult,\n CommitErrorWriteResult\n >({\n commitError,\n writeResult\n })\n })\n ),\n onSuccess: () =>\n input.write(input.terminal).pipe(\n Effect.match({\n onFailure: error =>\n CommitThenWriteTerminalEventResult.TerminalWriteFailed<\n TerminalWriteResult,\n CommitErrorWriteResult\n >({ error }),\n onSuccess: writeResult =>\n CommitThenWriteTerminalEventResult.Committed<\n TerminalWriteResult,\n CommitErrorWriteResult\n >({ writeResult })\n })\n )\n })\n )\n"],"mappings":";;AAkFA,MAAa,qCACX,KAAK,WAAyD;AAEhE,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;CAO1C,MAAM,QAA0C;EAC9C,GAAG,MAAM;EACT,SAAS,oBAAoB;GAC3B,UAAU,MAAM;GAChB,MAAM,MAAM;GACZ;EACF,CAAC;CACH;CAEA,IAAI,MAAM,gBAAgB,KAAA,GACxB,MAAM,cAAc,MAAM;CAG5B,OAAO;EACL;EACA;EACA;EACA,WAAW,oCAAoC,iBAAiB;CAClE;AACF;AAEA,MAAM,iCAAuD,UAC3D,YAAY,OAAO,GAAG,KAAK,UAAU,KAAK,EAAE,GAAG;AAEjD,MAAa,0BACX,UAEA,OAAO,IAAI,aAAa;CACtB,MAAM,YAAY,0BAA0B,KAAK;CACjD,OAAO,OAAO,WAAW;EACvB,WAAW,MAAM,OAAO,MAAM,8BAA8B,UAAU,KAAK,CAAC;EAC5E,QAAO,UAAS;CAClB,CAAC;CAED,OAAO;AACT,CAAC;AAEH,MAAa,gCAQX,UAYA,MAAM,OAAO,KACX,OAAO,YAAY;CACjB,YAAW,gBACT,MAAM,iBAAiB,WAAW,EAAE,KAClC,OAAO,MAAM;EACX,YAAW,UACT,mCAAmC,uBAGjC;GACA;GACA;EACF,CAAC;EACH,YAAW,gBACT,mCAAmC,aAGjC;GACA;GACA;EACF,CAAC;CACL,CAAC,CACH;CACF,iBACE,MAAM,MAAM,MAAM,QAAQ,EAAE,KAC1B,OAAO,MAAM;EACX,YAAW,UACT,mCAAmC,oBAGjC,EAAE,MAAM,CAAC;EACb,YAAW,gBACT,mCAAmC,UAGjC,EAAE,YAAY,CAAC;CACrB,CAAC,CACH;AACJ,CAAC,CACH"}
|
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
import { Data } from "effect";
|
|
2
|
+
|
|
3
|
+
//#region src/workflow-loop.d.ts
|
|
4
|
+
type VercelAgentWorkflowInput = {
|
|
5
|
+
readonly request: unknown;
|
|
6
|
+
readonly context: unknown;
|
|
7
|
+
};
|
|
8
|
+
type SerializableWorkflowState = {
|
|
9
|
+
readonly request: unknown;
|
|
10
|
+
readonly messages?: ReadonlyArray<unknown>;
|
|
11
|
+
readonly createdMessages: ReadonlyArray<unknown>;
|
|
12
|
+
readonly usage?: unknown;
|
|
13
|
+
readonly turn: number;
|
|
14
|
+
readonly eventSequence?: number;
|
|
15
|
+
};
|
|
16
|
+
type VercelAgentWorkflowModelStepInput = {
|
|
17
|
+
readonly context: unknown;
|
|
18
|
+
readonly state: SerializableWorkflowState;
|
|
19
|
+
};
|
|
20
|
+
type VercelAgentWorkflowModelStepResult = {
|
|
21
|
+
readonly done: boolean;
|
|
22
|
+
readonly messages: ReadonlyArray<unknown>;
|
|
23
|
+
readonly createdMessages: ReadonlyArray<unknown>;
|
|
24
|
+
readonly toolCalls: ReadonlyArray<unknown>;
|
|
25
|
+
readonly usage: unknown;
|
|
26
|
+
readonly turn: number;
|
|
27
|
+
readonly eventSequence?: number;
|
|
28
|
+
};
|
|
29
|
+
type VercelAgentWorkflowToolBatchStepInput = {
|
|
30
|
+
readonly context: unknown;
|
|
31
|
+
readonly request: unknown;
|
|
32
|
+
readonly calls: ReadonlyArray<unknown>;
|
|
33
|
+
readonly createdMessages: ReadonlyArray<unknown>;
|
|
34
|
+
readonly hitlResponses?: ReadonlyArray<unknown>;
|
|
35
|
+
readonly usage?: unknown;
|
|
36
|
+
readonly turn?: number;
|
|
37
|
+
readonly eventSequence?: number;
|
|
38
|
+
};
|
|
39
|
+
type VercelAgentWorkflowAwaitingInput = {
|
|
40
|
+
readonly hookToken: string;
|
|
41
|
+
readonly requests: ReadonlyArray<unknown>;
|
|
42
|
+
readonly messages: ReadonlyArray<unknown>;
|
|
43
|
+
readonly usage: unknown;
|
|
44
|
+
readonly turns: number;
|
|
45
|
+
readonly eventSequence?: number;
|
|
46
|
+
};
|
|
47
|
+
type VercelAgentWorkflowToolBatchStepResult = {
|
|
48
|
+
readonly messages: ReadonlyArray<unknown>;
|
|
49
|
+
readonly createdMessages: ReadonlyArray<unknown>; /** Updated cumulative usage when tools run nested model work such as subagents. */
|
|
50
|
+
readonly usage?: unknown;
|
|
51
|
+
readonly awaitingInput?: VercelAgentWorkflowAwaitingInput;
|
|
52
|
+
readonly eventSequence?: number;
|
|
53
|
+
/**
|
|
54
|
+
* A plain wire-safe failure captured after partial progress. Returning it instead of rejecting
|
|
55
|
+
* lets orchestration retain usage and event sequencing from completed sibling tools.
|
|
56
|
+
*/
|
|
57
|
+
readonly failure?: unknown;
|
|
58
|
+
};
|
|
59
|
+
type WorkflowStepResult<A> = Data.TaggedEnum<{
|
|
60
|
+
Success: {
|
|
61
|
+
readonly value: A;
|
|
62
|
+
};
|
|
63
|
+
Failure: {
|
|
64
|
+
readonly error: unknown;
|
|
65
|
+
};
|
|
66
|
+
}>;
|
|
67
|
+
declare const WorkflowStepResult: {
|
|
68
|
+
readonly Success: <A>(args: {
|
|
69
|
+
readonly value: A;
|
|
70
|
+
}) => {
|
|
71
|
+
readonly _tag: "Success";
|
|
72
|
+
readonly value: A;
|
|
73
|
+
};
|
|
74
|
+
readonly Failure: <A>(args: {
|
|
75
|
+
readonly error: unknown;
|
|
76
|
+
}) => {
|
|
77
|
+
readonly _tag: "Failure";
|
|
78
|
+
readonly error: unknown;
|
|
79
|
+
};
|
|
80
|
+
readonly $is: <Tag extends "Success" | "Failure">(tag: Tag) => {
|
|
81
|
+
<T extends {
|
|
82
|
+
readonly _tag: "Success";
|
|
83
|
+
readonly value: any;
|
|
84
|
+
} | {
|
|
85
|
+
readonly _tag: "Failure";
|
|
86
|
+
readonly error: unknown;
|
|
87
|
+
}>(u: T): u is T & {
|
|
88
|
+
readonly _tag: Tag;
|
|
89
|
+
};
|
|
90
|
+
(u: unknown): u is Extract<{
|
|
91
|
+
readonly _tag: "Success";
|
|
92
|
+
readonly value: unknown;
|
|
93
|
+
}, {
|
|
94
|
+
readonly _tag: Tag;
|
|
95
|
+
}> | Extract<{
|
|
96
|
+
readonly _tag: "Failure";
|
|
97
|
+
readonly error: unknown;
|
|
98
|
+
}, {
|
|
99
|
+
readonly _tag: Tag;
|
|
100
|
+
}>;
|
|
101
|
+
};
|
|
102
|
+
readonly $match: {
|
|
103
|
+
<A, B, C, D, Cases extends {
|
|
104
|
+
readonly Success: (args: {
|
|
105
|
+
readonly _tag: "Success";
|
|
106
|
+
readonly value: A;
|
|
107
|
+
}) => any;
|
|
108
|
+
readonly Failure: (args: {
|
|
109
|
+
readonly _tag: "Failure";
|
|
110
|
+
readonly error: unknown;
|
|
111
|
+
}) => any;
|
|
112
|
+
}>(cases: Cases): (self: {
|
|
113
|
+
readonly _tag: "Success";
|
|
114
|
+
readonly value: A;
|
|
115
|
+
} | {
|
|
116
|
+
readonly _tag: "Failure";
|
|
117
|
+
readonly error: unknown;
|
|
118
|
+
}) => import("effect/Unify").Unify<ReturnType<Cases["Success" | "Failure"]>>;
|
|
119
|
+
<A, B, C, D, Cases extends {
|
|
120
|
+
readonly Success: (args: {
|
|
121
|
+
readonly _tag: "Success";
|
|
122
|
+
readonly value: A;
|
|
123
|
+
}) => any;
|
|
124
|
+
readonly Failure: (args: {
|
|
125
|
+
readonly _tag: "Failure";
|
|
126
|
+
readonly error: unknown;
|
|
127
|
+
}) => any;
|
|
128
|
+
}>(self: {
|
|
129
|
+
readonly _tag: "Success";
|
|
130
|
+
readonly value: A;
|
|
131
|
+
} | {
|
|
132
|
+
readonly _tag: "Failure";
|
|
133
|
+
readonly error: unknown;
|
|
134
|
+
}, cases: Cases): import("effect/Unify").Unify<ReturnType<Cases["Success" | "Failure"]>>;
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
type VercelAgentWorkflowStepRetryPolicy = {
|
|
138
|
+
readonly maxAttempts: number;
|
|
139
|
+
};
|
|
140
|
+
type VercelAgentWorkflowRunResult = Data.TaggedEnum<{
|
|
141
|
+
Completed: {
|
|
142
|
+
readonly turns: number;
|
|
143
|
+
readonly state: SerializableWorkflowState;
|
|
144
|
+
};
|
|
145
|
+
ModelStepFailed: {
|
|
146
|
+
readonly turn: number;
|
|
147
|
+
readonly error: unknown;
|
|
148
|
+
readonly state: SerializableWorkflowState;
|
|
149
|
+
};
|
|
150
|
+
ToolBatchStepFailed: {
|
|
151
|
+
readonly turn: number;
|
|
152
|
+
readonly error: unknown;
|
|
153
|
+
readonly state: SerializableWorkflowState;
|
|
154
|
+
};
|
|
155
|
+
AwaitInputFailed: {
|
|
156
|
+
readonly turn: number;
|
|
157
|
+
readonly error: unknown;
|
|
158
|
+
readonly awaitingInput: VercelAgentWorkflowAwaitingInput;
|
|
159
|
+
readonly state: SerializableWorkflowState;
|
|
160
|
+
};
|
|
161
|
+
CloseStreamFailed: {
|
|
162
|
+
readonly turns: number;
|
|
163
|
+
readonly error: unknown;
|
|
164
|
+
readonly state: SerializableWorkflowState;
|
|
165
|
+
};
|
|
166
|
+
MaxTurnsExceeded: {
|
|
167
|
+
readonly maxTurns: number;
|
|
168
|
+
readonly error: Error;
|
|
169
|
+
readonly state: SerializableWorkflowState;
|
|
170
|
+
};
|
|
171
|
+
}>;
|
|
172
|
+
declare const VercelAgentWorkflowRunResult: {
|
|
173
|
+
readonly Completed: Data.TaggedEnum.ConstructorFrom<{
|
|
174
|
+
readonly _tag: "Completed";
|
|
175
|
+
readonly turns: number;
|
|
176
|
+
readonly state: SerializableWorkflowState;
|
|
177
|
+
}, "_tag">;
|
|
178
|
+
readonly ModelStepFailed: Data.TaggedEnum.ConstructorFrom<{
|
|
179
|
+
readonly _tag: "ModelStepFailed";
|
|
180
|
+
readonly turn: number;
|
|
181
|
+
readonly error: unknown;
|
|
182
|
+
readonly state: SerializableWorkflowState;
|
|
183
|
+
}, "_tag">;
|
|
184
|
+
readonly ToolBatchStepFailed: Data.TaggedEnum.ConstructorFrom<{
|
|
185
|
+
readonly _tag: "ToolBatchStepFailed";
|
|
186
|
+
readonly turn: number;
|
|
187
|
+
readonly error: unknown;
|
|
188
|
+
readonly state: SerializableWorkflowState;
|
|
189
|
+
}, "_tag">;
|
|
190
|
+
readonly AwaitInputFailed: Data.TaggedEnum.ConstructorFrom<{
|
|
191
|
+
readonly _tag: "AwaitInputFailed";
|
|
192
|
+
readonly turn: number;
|
|
193
|
+
readonly error: unknown;
|
|
194
|
+
readonly awaitingInput: VercelAgentWorkflowAwaitingInput;
|
|
195
|
+
readonly state: SerializableWorkflowState;
|
|
196
|
+
}, "_tag">;
|
|
197
|
+
readonly CloseStreamFailed: Data.TaggedEnum.ConstructorFrom<{
|
|
198
|
+
readonly _tag: "CloseStreamFailed";
|
|
199
|
+
readonly turns: number;
|
|
200
|
+
readonly error: unknown;
|
|
201
|
+
readonly state: SerializableWorkflowState;
|
|
202
|
+
}, "_tag">;
|
|
203
|
+
readonly MaxTurnsExceeded: Data.TaggedEnum.ConstructorFrom<{
|
|
204
|
+
readonly _tag: "MaxTurnsExceeded";
|
|
205
|
+
readonly maxTurns: number;
|
|
206
|
+
readonly error: Error;
|
|
207
|
+
readonly state: SerializableWorkflowState;
|
|
208
|
+
}, "_tag">;
|
|
209
|
+
readonly $is: <Tag extends "Completed" | "ModelStepFailed" | "ToolBatchStepFailed" | "AwaitInputFailed" | "CloseStreamFailed" | "MaxTurnsExceeded">(tag: Tag) => (u: unknown) => u is Extract<{
|
|
210
|
+
readonly _tag: "Completed";
|
|
211
|
+
readonly turns: number;
|
|
212
|
+
readonly state: SerializableWorkflowState;
|
|
213
|
+
}, {
|
|
214
|
+
readonly _tag: Tag;
|
|
215
|
+
}> | Extract<{
|
|
216
|
+
readonly _tag: "ModelStepFailed";
|
|
217
|
+
readonly turn: number;
|
|
218
|
+
readonly error: unknown;
|
|
219
|
+
readonly state: SerializableWorkflowState;
|
|
220
|
+
}, {
|
|
221
|
+
readonly _tag: Tag;
|
|
222
|
+
}> | Extract<{
|
|
223
|
+
readonly _tag: "ToolBatchStepFailed";
|
|
224
|
+
readonly turn: number;
|
|
225
|
+
readonly error: unknown;
|
|
226
|
+
readonly state: SerializableWorkflowState;
|
|
227
|
+
}, {
|
|
228
|
+
readonly _tag: Tag;
|
|
229
|
+
}> | Extract<{
|
|
230
|
+
readonly _tag: "AwaitInputFailed";
|
|
231
|
+
readonly turn: number;
|
|
232
|
+
readonly error: unknown;
|
|
233
|
+
readonly awaitingInput: VercelAgentWorkflowAwaitingInput;
|
|
234
|
+
readonly state: SerializableWorkflowState;
|
|
235
|
+
}, {
|
|
236
|
+
readonly _tag: Tag;
|
|
237
|
+
}> | Extract<{
|
|
238
|
+
readonly _tag: "CloseStreamFailed";
|
|
239
|
+
readonly turns: number;
|
|
240
|
+
readonly error: unknown;
|
|
241
|
+
readonly state: SerializableWorkflowState;
|
|
242
|
+
}, {
|
|
243
|
+
readonly _tag: Tag;
|
|
244
|
+
}> | Extract<{
|
|
245
|
+
readonly _tag: "MaxTurnsExceeded";
|
|
246
|
+
readonly maxTurns: number;
|
|
247
|
+
readonly error: Error;
|
|
248
|
+
readonly state: SerializableWorkflowState;
|
|
249
|
+
}, {
|
|
250
|
+
readonly _tag: Tag;
|
|
251
|
+
}>;
|
|
252
|
+
readonly $match: {
|
|
253
|
+
<Cases extends {
|
|
254
|
+
readonly Completed: (args: {
|
|
255
|
+
readonly _tag: "Completed";
|
|
256
|
+
readonly turns: number;
|
|
257
|
+
readonly state: SerializableWorkflowState;
|
|
258
|
+
}) => any;
|
|
259
|
+
readonly ModelStepFailed: (args: {
|
|
260
|
+
readonly _tag: "ModelStepFailed";
|
|
261
|
+
readonly turn: number;
|
|
262
|
+
readonly error: unknown;
|
|
263
|
+
readonly state: SerializableWorkflowState;
|
|
264
|
+
}) => any;
|
|
265
|
+
readonly ToolBatchStepFailed: (args: {
|
|
266
|
+
readonly _tag: "ToolBatchStepFailed";
|
|
267
|
+
readonly turn: number;
|
|
268
|
+
readonly error: unknown;
|
|
269
|
+
readonly state: SerializableWorkflowState;
|
|
270
|
+
}) => any;
|
|
271
|
+
readonly AwaitInputFailed: (args: {
|
|
272
|
+
readonly _tag: "AwaitInputFailed";
|
|
273
|
+
readonly turn: number;
|
|
274
|
+
readonly error: unknown;
|
|
275
|
+
readonly awaitingInput: VercelAgentWorkflowAwaitingInput;
|
|
276
|
+
readonly state: SerializableWorkflowState;
|
|
277
|
+
}) => any;
|
|
278
|
+
readonly CloseStreamFailed: (args: {
|
|
279
|
+
readonly _tag: "CloseStreamFailed";
|
|
280
|
+
readonly turns: number;
|
|
281
|
+
readonly error: unknown;
|
|
282
|
+
readonly state: SerializableWorkflowState;
|
|
283
|
+
}) => any;
|
|
284
|
+
readonly MaxTurnsExceeded: (args: {
|
|
285
|
+
readonly _tag: "MaxTurnsExceeded";
|
|
286
|
+
readonly maxTurns: number;
|
|
287
|
+
readonly error: Error;
|
|
288
|
+
readonly state: SerializableWorkflowState;
|
|
289
|
+
}) => any;
|
|
290
|
+
}>(cases: Cases): (value: {
|
|
291
|
+
readonly _tag: "Completed";
|
|
292
|
+
readonly turns: number;
|
|
293
|
+
readonly state: SerializableWorkflowState;
|
|
294
|
+
} | {
|
|
295
|
+
readonly _tag: "ModelStepFailed";
|
|
296
|
+
readonly turn: number;
|
|
297
|
+
readonly error: unknown;
|
|
298
|
+
readonly state: SerializableWorkflowState;
|
|
299
|
+
} | {
|
|
300
|
+
readonly _tag: "ToolBatchStepFailed";
|
|
301
|
+
readonly turn: number;
|
|
302
|
+
readonly error: unknown;
|
|
303
|
+
readonly state: SerializableWorkflowState;
|
|
304
|
+
} | {
|
|
305
|
+
readonly _tag: "AwaitInputFailed";
|
|
306
|
+
readonly turn: number;
|
|
307
|
+
readonly error: unknown;
|
|
308
|
+
readonly awaitingInput: VercelAgentWorkflowAwaitingInput;
|
|
309
|
+
readonly state: SerializableWorkflowState;
|
|
310
|
+
} | {
|
|
311
|
+
readonly _tag: "CloseStreamFailed";
|
|
312
|
+
readonly turns: number;
|
|
313
|
+
readonly error: unknown;
|
|
314
|
+
readonly state: SerializableWorkflowState;
|
|
315
|
+
} | {
|
|
316
|
+
readonly _tag: "MaxTurnsExceeded";
|
|
317
|
+
readonly maxTurns: number;
|
|
318
|
+
readonly error: Error;
|
|
319
|
+
readonly state: SerializableWorkflowState;
|
|
320
|
+
}) => import("effect/Unify").Unify<ReturnType<Cases["Completed" | "ModelStepFailed" | "ToolBatchStepFailed" | "AwaitInputFailed" | "CloseStreamFailed" | "MaxTurnsExceeded"]>>;
|
|
321
|
+
<Cases extends {
|
|
322
|
+
readonly Completed: (args: {
|
|
323
|
+
readonly _tag: "Completed";
|
|
324
|
+
readonly turns: number;
|
|
325
|
+
readonly state: SerializableWorkflowState;
|
|
326
|
+
}) => any;
|
|
327
|
+
readonly ModelStepFailed: (args: {
|
|
328
|
+
readonly _tag: "ModelStepFailed";
|
|
329
|
+
readonly turn: number;
|
|
330
|
+
readonly error: unknown;
|
|
331
|
+
readonly state: SerializableWorkflowState;
|
|
332
|
+
}) => any;
|
|
333
|
+
readonly ToolBatchStepFailed: (args: {
|
|
334
|
+
readonly _tag: "ToolBatchStepFailed";
|
|
335
|
+
readonly turn: number;
|
|
336
|
+
readonly error: unknown;
|
|
337
|
+
readonly state: SerializableWorkflowState;
|
|
338
|
+
}) => any;
|
|
339
|
+
readonly AwaitInputFailed: (args: {
|
|
340
|
+
readonly _tag: "AwaitInputFailed";
|
|
341
|
+
readonly turn: number;
|
|
342
|
+
readonly error: unknown;
|
|
343
|
+
readonly awaitingInput: VercelAgentWorkflowAwaitingInput;
|
|
344
|
+
readonly state: SerializableWorkflowState;
|
|
345
|
+
}) => any;
|
|
346
|
+
readonly CloseStreamFailed: (args: {
|
|
347
|
+
readonly _tag: "CloseStreamFailed";
|
|
348
|
+
readonly turns: number;
|
|
349
|
+
readonly error: unknown;
|
|
350
|
+
readonly state: SerializableWorkflowState;
|
|
351
|
+
}) => any;
|
|
352
|
+
readonly MaxTurnsExceeded: (args: {
|
|
353
|
+
readonly _tag: "MaxTurnsExceeded";
|
|
354
|
+
readonly maxTurns: number;
|
|
355
|
+
readonly error: Error;
|
|
356
|
+
readonly state: SerializableWorkflowState;
|
|
357
|
+
}) => any;
|
|
358
|
+
}>(value: {
|
|
359
|
+
readonly _tag: "Completed";
|
|
360
|
+
readonly turns: number;
|
|
361
|
+
readonly state: SerializableWorkflowState;
|
|
362
|
+
} | {
|
|
363
|
+
readonly _tag: "ModelStepFailed";
|
|
364
|
+
readonly turn: number;
|
|
365
|
+
readonly error: unknown;
|
|
366
|
+
readonly state: SerializableWorkflowState;
|
|
367
|
+
} | {
|
|
368
|
+
readonly _tag: "ToolBatchStepFailed";
|
|
369
|
+
readonly turn: number;
|
|
370
|
+
readonly error: unknown;
|
|
371
|
+
readonly state: SerializableWorkflowState;
|
|
372
|
+
} | {
|
|
373
|
+
readonly _tag: "AwaitInputFailed";
|
|
374
|
+
readonly turn: number;
|
|
375
|
+
readonly error: unknown;
|
|
376
|
+
readonly awaitingInput: VercelAgentWorkflowAwaitingInput;
|
|
377
|
+
readonly state: SerializableWorkflowState;
|
|
378
|
+
} | {
|
|
379
|
+
readonly _tag: "CloseStreamFailed";
|
|
380
|
+
readonly turns: number;
|
|
381
|
+
readonly error: unknown;
|
|
382
|
+
readonly state: SerializableWorkflowState;
|
|
383
|
+
} | {
|
|
384
|
+
readonly _tag: "MaxTurnsExceeded";
|
|
385
|
+
readonly maxTurns: number;
|
|
386
|
+
readonly error: Error;
|
|
387
|
+
readonly state: SerializableWorkflowState;
|
|
388
|
+
}, cases: Cases): import("effect/Unify").Unify<ReturnType<Cases["Completed" | "ModelStepFailed" | "ToolBatchStepFailed" | "AwaitInputFailed" | "CloseStreamFailed" | "MaxTurnsExceeded"]>>;
|
|
389
|
+
};
|
|
390
|
+
};
|
|
391
|
+
type VercelAgentWorkflowLoopConfig = {
|
|
392
|
+
readonly input: VercelAgentWorkflowInput;
|
|
393
|
+
readonly maxTurns?: number;
|
|
394
|
+
readonly runModelStep: (input: VercelAgentWorkflowModelStepInput) => Promise<VercelAgentWorkflowModelStepResult>;
|
|
395
|
+
readonly runToolBatchStep: (input: VercelAgentWorkflowToolBatchStepInput) => Promise<VercelAgentWorkflowToolBatchStepResult>; /** Called only after a model step returns `done: true`. */
|
|
396
|
+
readonly closeStream: () => Promise<void>;
|
|
397
|
+
/**
|
|
398
|
+
* Best-effort final failure handler. It must write a safe final error and
|
|
399
|
+
* close the failure stream; rejection is suppressed in favor of the
|
|
400
|
+
* original structured run result.
|
|
401
|
+
*/
|
|
402
|
+
readonly writeError: (error: unknown) => Promise<void>; /** A successful await suspends/resumes without invoking either finalizer. */
|
|
403
|
+
readonly awaitInput?: (input: VercelAgentWorkflowAwaitingInput) => Promise<unknown>;
|
|
404
|
+
readonly modelStepRetry?: VercelAgentWorkflowStepRetryPolicy;
|
|
405
|
+
readonly toolBatchStepRetry?: VercelAgentWorkflowStepRetryPolicy;
|
|
406
|
+
readonly awaitInputRetry?: VercelAgentWorkflowStepRetryPolicy;
|
|
407
|
+
readonly closeStreamRetry?: VercelAgentWorkflowStepRetryPolicy;
|
|
408
|
+
};
|
|
409
|
+
declare const defaultMaxWorkflowTurns = 500;
|
|
410
|
+
declare const noWorkflowStepRetry: VercelAgentWorkflowStepRetryPolicy;
|
|
411
|
+
declare const settleWorkflowStep: <A>(promise: Promise<A>) => Promise<WorkflowStepResult<A>>;
|
|
412
|
+
declare function retryWorkflowStep<A>(runStep: () => Promise<A>, policy?: VercelAgentWorkflowStepRetryPolicy): Promise<A>;
|
|
413
|
+
declare function runVercelAgentWorkflow(config: VercelAgentWorkflowLoopConfig): Promise<VercelAgentWorkflowRunResult>;
|
|
414
|
+
//#endregion
|
|
415
|
+
export { SerializableWorkflowState, VercelAgentWorkflowAwaitingInput, VercelAgentWorkflowInput, VercelAgentWorkflowLoopConfig, VercelAgentWorkflowModelStepInput, VercelAgentWorkflowModelStepResult, VercelAgentWorkflowRunResult, VercelAgentWorkflowStepRetryPolicy, VercelAgentWorkflowToolBatchStepInput, VercelAgentWorkflowToolBatchStepResult, WorkflowStepResult, defaultMaxWorkflowTurns, noWorkflowStepRetry, retryWorkflowStep, runVercelAgentWorkflow, settleWorkflowStep };
|
|
416
|
+
//# sourceMappingURL=workflow-loop.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow-loop.d.mts","names":[],"sources":["../src/workflow-loop.ts"],"mappings":"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"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { Data, Predicate } from "effect";
|
|
2
|
+
//#region src/workflow-loop.ts
|
|
3
|
+
const WorkflowStepResult = Data.taggedEnum();
|
|
4
|
+
const VercelAgentWorkflowRunResult = Data.taggedEnum();
|
|
5
|
+
const defaultMaxWorkflowTurns = 500;
|
|
6
|
+
const noWorkflowStepRetry = { maxAttempts: 1 };
|
|
7
|
+
const settleWorkflowStep = (promise) => promise.then((value) => WorkflowStepResult.Success({ value }), (error) => WorkflowStepResult.Failure({ error }));
|
|
8
|
+
const workflowMaxTurnsError = (maxTurns) => /* @__PURE__ */ new Error(`Vercel agent workflow exceeded max turns: ${maxTurns}`);
|
|
9
|
+
const writeErrorSafely = (writeError, error) => writeError(error).catch(() => void 0);
|
|
10
|
+
const missingAwaitInputHandlerError = () => /* @__PURE__ */ new Error("Vercel agent workflow awaiting input requested but no awaitInput handler is configured");
|
|
11
|
+
const maxRetryAttempts = (policy) => {
|
|
12
|
+
const configured = policy?.maxAttempts ?? noWorkflowStepRetry.maxAttempts;
|
|
13
|
+
return Number.isFinite(configured) ? Math.max(1, Math.floor(configured)) : 1;
|
|
14
|
+
};
|
|
15
|
+
const maxWorkflowTurns = (configured) => {
|
|
16
|
+
if (configured === void 0 || !Number.isFinite(configured)) return 500;
|
|
17
|
+
return Math.max(1, Math.floor(configured));
|
|
18
|
+
};
|
|
19
|
+
async function retryWorkflowStep(runStep, policy) {
|
|
20
|
+
const maxAttempts = maxRetryAttempts(policy);
|
|
21
|
+
let attempt = 1;
|
|
22
|
+
for (;;) try {
|
|
23
|
+
return await runStep();
|
|
24
|
+
} catch (error) {
|
|
25
|
+
if (attempt >= maxAttempts) throw error;
|
|
26
|
+
attempt += 1;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
async function runVercelAgentWorkflow(config) {
|
|
30
|
+
const { input, maxTurns: configuredMaxTurns, runModelStep, runToolBatchStep, closeStream, writeError, awaitInput, modelStepRetry, toolBatchStepRetry, awaitInputRetry, closeStreamRetry } = config;
|
|
31
|
+
let state = {
|
|
32
|
+
request: input.request,
|
|
33
|
+
createdMessages: [],
|
|
34
|
+
turn: 1,
|
|
35
|
+
eventSequence: 0
|
|
36
|
+
};
|
|
37
|
+
const maxTurns = maxWorkflowTurns(configuredMaxTurns);
|
|
38
|
+
for (let step = 0; step < maxTurns; step++) {
|
|
39
|
+
const modelResult = await settleWorkflowStep(retryWorkflowStep(() => runModelStep({
|
|
40
|
+
context: input.context,
|
|
41
|
+
state
|
|
42
|
+
}), modelStepRetry));
|
|
43
|
+
if (Predicate.isTagged(modelResult, "Failure")) {
|
|
44
|
+
await writeErrorSafely(writeError, modelResult.error);
|
|
45
|
+
return VercelAgentWorkflowRunResult.ModelStepFailed({
|
|
46
|
+
turn: state.turn,
|
|
47
|
+
error: modelResult.error,
|
|
48
|
+
state
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
if (modelResult.value.done) {
|
|
52
|
+
const terminalState = {
|
|
53
|
+
request: input.request,
|
|
54
|
+
messages: modelResult.value.messages,
|
|
55
|
+
createdMessages: modelResult.value.createdMessages,
|
|
56
|
+
usage: modelResult.value.usage,
|
|
57
|
+
turn: modelResult.value.turn,
|
|
58
|
+
eventSequence: modelResult.value.eventSequence ?? state.eventSequence
|
|
59
|
+
};
|
|
60
|
+
const closeResult = await settleWorkflowStep(retryWorkflowStep(closeStream, closeStreamRetry));
|
|
61
|
+
if (Predicate.isTagged(closeResult, "Failure")) {
|
|
62
|
+
await writeErrorSafely(writeError, closeResult.error);
|
|
63
|
+
return VercelAgentWorkflowRunResult.CloseStreamFailed({
|
|
64
|
+
turns: modelResult.value.turn,
|
|
65
|
+
error: closeResult.error,
|
|
66
|
+
state: terminalState
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
return VercelAgentWorkflowRunResult.Completed({
|
|
70
|
+
turns: modelResult.value.turn,
|
|
71
|
+
state: terminalState
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
if (modelResult.value.toolCalls.length === 0) {
|
|
75
|
+
state = {
|
|
76
|
+
request: input.request,
|
|
77
|
+
messages: modelResult.value.messages,
|
|
78
|
+
createdMessages: modelResult.value.createdMessages,
|
|
79
|
+
usage: modelResult.value.usage,
|
|
80
|
+
turn: modelResult.value.turn + 1,
|
|
81
|
+
eventSequence: modelResult.value.eventSequence ?? state.eventSequence
|
|
82
|
+
};
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
let completedToolsResult;
|
|
86
|
+
const toolHitlResponses = [];
|
|
87
|
+
let cumulativeUsage = modelResult.value.usage;
|
|
88
|
+
let toolEventSequence = modelResult.value.eventSequence ?? state.eventSequence;
|
|
89
|
+
const currentTurnState = (toolResult) => ({
|
|
90
|
+
request: input.request,
|
|
91
|
+
messages: toolResult === void 0 ? modelResult.value.messages : [...modelResult.value.messages, ...toolResult.messages],
|
|
92
|
+
createdMessages: toolResult?.createdMessages ?? modelResult.value.createdMessages,
|
|
93
|
+
usage: cumulativeUsage,
|
|
94
|
+
turn: modelResult.value.turn,
|
|
95
|
+
eventSequence: toolEventSequence
|
|
96
|
+
});
|
|
97
|
+
for (;;) {
|
|
98
|
+
const toolsResult = await settleWorkflowStep(retryWorkflowStep(() => runToolBatchStep({
|
|
99
|
+
context: input.context,
|
|
100
|
+
request: input.request,
|
|
101
|
+
calls: modelResult.value.toolCalls,
|
|
102
|
+
createdMessages: modelResult.value.createdMessages,
|
|
103
|
+
hitlResponses: toolHitlResponses.slice(),
|
|
104
|
+
usage: cumulativeUsage,
|
|
105
|
+
turn: modelResult.value.turn,
|
|
106
|
+
eventSequence: toolEventSequence
|
|
107
|
+
}), toolBatchStepRetry));
|
|
108
|
+
if (Predicate.isTagged(toolsResult, "Failure")) {
|
|
109
|
+
await writeErrorSafely(writeError, toolsResult.error);
|
|
110
|
+
return VercelAgentWorkflowRunResult.ToolBatchStepFailed({
|
|
111
|
+
turn: modelResult.value.turn,
|
|
112
|
+
error: toolsResult.error,
|
|
113
|
+
state: currentTurnState()
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
cumulativeUsage = toolsResult.value.usage ?? cumulativeUsage;
|
|
117
|
+
toolEventSequence = toolsResult.value.eventSequence ?? toolEventSequence;
|
|
118
|
+
if (toolsResult.value.failure !== void 0) {
|
|
119
|
+
await writeErrorSafely(writeError, toolsResult.value.failure);
|
|
120
|
+
return VercelAgentWorkflowRunResult.ToolBatchStepFailed({
|
|
121
|
+
turn: modelResult.value.turn,
|
|
122
|
+
error: toolsResult.value.failure,
|
|
123
|
+
state: currentTurnState(toolsResult.value)
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
if (toolsResult.value.awaitingInput === void 0) {
|
|
127
|
+
completedToolsResult = toolsResult.value;
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
const awaitingInput = toolsResult.value.awaitingInput;
|
|
131
|
+
cumulativeUsage = toolsResult.value.usage ?? awaitingInput.usage ?? cumulativeUsage;
|
|
132
|
+
toolEventSequence = awaitingInput.eventSequence ?? toolEventSequence;
|
|
133
|
+
const hitlResponse = await settleWorkflowStep(retryWorkflowStep(() => {
|
|
134
|
+
if (awaitInput === void 0) return Promise.reject(missingAwaitInputHandlerError());
|
|
135
|
+
return awaitInput(awaitingInput);
|
|
136
|
+
}, awaitInputRetry));
|
|
137
|
+
if (Predicate.isTagged(hitlResponse, "Failure")) {
|
|
138
|
+
await writeErrorSafely(writeError, hitlResponse.error);
|
|
139
|
+
return VercelAgentWorkflowRunResult.AwaitInputFailed({
|
|
140
|
+
turn: modelResult.value.turn,
|
|
141
|
+
error: hitlResponse.error,
|
|
142
|
+
awaitingInput,
|
|
143
|
+
state: currentTurnState(toolsResult.value)
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
toolHitlResponses.push(hitlResponse.value);
|
|
147
|
+
}
|
|
148
|
+
if (completedToolsResult === void 0) {
|
|
149
|
+
const error = /* @__PURE__ */ new Error("Vercel agent workflow tool batch did not complete");
|
|
150
|
+
await writeErrorSafely(writeError, error);
|
|
151
|
+
return VercelAgentWorkflowRunResult.ToolBatchStepFailed({
|
|
152
|
+
turn: modelResult.value.turn,
|
|
153
|
+
error,
|
|
154
|
+
state
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
state = {
|
|
158
|
+
request: input.request,
|
|
159
|
+
messages: [...modelResult.value.messages, ...completedToolsResult.messages],
|
|
160
|
+
createdMessages: completedToolsResult.createdMessages,
|
|
161
|
+
usage: completedToolsResult.usage ?? cumulativeUsage,
|
|
162
|
+
turn: modelResult.value.turn + 1,
|
|
163
|
+
eventSequence: completedToolsResult.eventSequence ?? toolEventSequence
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
const error = workflowMaxTurnsError(maxTurns);
|
|
167
|
+
await writeErrorSafely(writeError, error);
|
|
168
|
+
return VercelAgentWorkflowRunResult.MaxTurnsExceeded({
|
|
169
|
+
maxTurns,
|
|
170
|
+
error,
|
|
171
|
+
state
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
//#endregion
|
|
175
|
+
export { VercelAgentWorkflowRunResult, WorkflowStepResult, defaultMaxWorkflowTurns, noWorkflowStepRetry, retryWorkflowStep, runVercelAgentWorkflow, settleWorkflowStep };
|
|
176
|
+
|
|
177
|
+
//# sourceMappingURL=workflow-loop.mjs.map
|