@cuylabs/agent-runtime-dapr 0.9.0 → 0.10.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.
- package/README.md +154 -19
- package/dist/{chunk-2CEICSJH.js → chunk-5CJIC4YB.js} +184 -38
- package/dist/chunk-MJKJT3ZO.js +11219 -0
- package/dist/{chunk-A34CHK2E.js → chunk-MQJ4LZOX.js} +30 -4
- package/dist/chunk-YQQTUE6B.js +993 -0
- package/dist/chunk-YS2CWYBQ.js +1358 -0
- package/dist/client-UsEIzDF6.d.ts +322 -0
- package/dist/dispatch/index.d.ts +9 -0
- package/dist/dispatch/index.js +17 -0
- package/dist/execution/index.d.ts +5 -4
- package/dist/execution/index.js +2 -2
- package/dist/host/index.d.ts +8 -4
- package/dist/host/index.js +28 -8
- package/dist/index-BEOwKSPI.d.ts +101 -0
- package/dist/{index-BCMkUMAf.d.ts → index-BmM58WZa.d.ts} +390 -182
- package/dist/index-CFm5LORU.d.ts +63 -0
- package/dist/index.d.ts +62 -14
- package/dist/index.js +76 -6
- package/dist/invoker-B1jvz9DG.d.ts +52 -0
- package/dist/{store-pRLGfYhN.d.ts → store-BXBIDz40.d.ts} +24 -3
- package/dist/team/index.d.ts +612 -0
- package/dist/team/index.js +30 -0
- package/dist/worker-CXq0IFGX.d.ts +42 -0
- package/dist/workflow/index.d.ts +4 -225
- package/dist/workflow/index.js +2 -2
- package/dist/{workflow-bridge-C8Z1yr0Y.d.ts → workflow-bridge-BcicHH1Y.d.ts} +4 -2
- package/dist/workflow-host-D6W6fXoL.d.ts +459 -0
- package/package.json +16 -6
- package/dist/chunk-DILON56B.js +0 -668
- package/dist/chunk-R47X4FG2.js +0 -2009
|
@@ -0,0 +1,1358 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DaprSidecarClient
|
|
3
|
+
} from "./chunk-MQJ4LZOX.js";
|
|
4
|
+
|
|
5
|
+
// src/workflow/types.ts
|
|
6
|
+
var TERMINAL_DAPR_WORKFLOW_STATUSES = /* @__PURE__ */ new Set([
|
|
7
|
+
"COMPLETED",
|
|
8
|
+
"FAILED",
|
|
9
|
+
"TERMINATED"
|
|
10
|
+
]);
|
|
11
|
+
function isTerminalDaprWorkflowStatus(status) {
|
|
12
|
+
return TERMINAL_DAPR_WORKFLOW_STATUSES.has(status);
|
|
13
|
+
}
|
|
14
|
+
function hasStartedDaprWorkflow(status) {
|
|
15
|
+
return status !== "PENDING";
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// src/workflow/client.ts
|
|
19
|
+
var DEFAULT_WORKFLOW_API_VERSION = "v1.0";
|
|
20
|
+
var DEFAULT_WORKFLOW_POLL_INTERVAL_MS = 1e3;
|
|
21
|
+
var MIN_WORKFLOW_POLL_INTERVAL_MS = 50;
|
|
22
|
+
var DEFAULT_WORKFLOW_WAIT_TIMEOUT_MS = 6e4;
|
|
23
|
+
function ensureNonEmpty(input, label) {
|
|
24
|
+
const trimmed = input.trim();
|
|
25
|
+
if (!trimmed) {
|
|
26
|
+
throw new Error(`${label} must not be empty`);
|
|
27
|
+
}
|
|
28
|
+
return trimmed;
|
|
29
|
+
}
|
|
30
|
+
function normalizePollInterval(input) {
|
|
31
|
+
if (input === void 0) {
|
|
32
|
+
return DEFAULT_WORKFLOW_POLL_INTERVAL_MS;
|
|
33
|
+
}
|
|
34
|
+
if (!Number.isFinite(input)) {
|
|
35
|
+
throw new Error("workflowPollIntervalMs must be a finite number");
|
|
36
|
+
}
|
|
37
|
+
return Math.max(MIN_WORKFLOW_POLL_INTERVAL_MS, Math.floor(input));
|
|
38
|
+
}
|
|
39
|
+
function normalizeTimeout(input) {
|
|
40
|
+
if (input === void 0) {
|
|
41
|
+
return DEFAULT_WORKFLOW_WAIT_TIMEOUT_MS;
|
|
42
|
+
}
|
|
43
|
+
if (!Number.isFinite(input)) {
|
|
44
|
+
throw new Error("timeoutMs must be a finite number");
|
|
45
|
+
}
|
|
46
|
+
return Math.max(0, Math.floor(input));
|
|
47
|
+
}
|
|
48
|
+
function sleep(ms) {
|
|
49
|
+
return new Promise((resolve) => {
|
|
50
|
+
setTimeout(resolve, ms);
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
function serializeWorkflowBody(value) {
|
|
54
|
+
if (value === void 0) {
|
|
55
|
+
return void 0;
|
|
56
|
+
}
|
|
57
|
+
if (typeof value === "string") {
|
|
58
|
+
return value;
|
|
59
|
+
}
|
|
60
|
+
return JSON.stringify(value);
|
|
61
|
+
}
|
|
62
|
+
function normalizeWorkflowState(payload) {
|
|
63
|
+
return {
|
|
64
|
+
instanceId: payload.instanceId ?? payload.instanceID ?? "",
|
|
65
|
+
workflowName: payload.workflowName ?? "",
|
|
66
|
+
createdAt: payload.createdAt,
|
|
67
|
+
lastUpdatedAt: payload.lastUpdatedAt,
|
|
68
|
+
runtimeStatus: payload.runtimeStatus ?? "PENDING",
|
|
69
|
+
properties: payload.properties ?? {}
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
var DaprWorkflowClient = class {
|
|
73
|
+
client;
|
|
74
|
+
workflowComponent;
|
|
75
|
+
workflowApiVersion;
|
|
76
|
+
workflowPollIntervalMs;
|
|
77
|
+
constructor(options) {
|
|
78
|
+
this.client = new DaprSidecarClient(options);
|
|
79
|
+
this.workflowComponent = ensureNonEmpty(
|
|
80
|
+
options.workflowComponent,
|
|
81
|
+
"workflowComponent"
|
|
82
|
+
);
|
|
83
|
+
this.workflowApiVersion = options.workflowApiVersion ?? DEFAULT_WORKFLOW_API_VERSION;
|
|
84
|
+
this.workflowPollIntervalMs = normalizePollInterval(
|
|
85
|
+
options.workflowPollIntervalMs
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
async verifySidecar() {
|
|
89
|
+
await this.client.verifySidecar();
|
|
90
|
+
}
|
|
91
|
+
async startWorkflow(workflowName, options = {}) {
|
|
92
|
+
const normalizedWorkflowName = ensureNonEmpty(workflowName, "workflowName");
|
|
93
|
+
const query = options.instanceId ? `?instanceID=${encodeURIComponent(options.instanceId)}` : "";
|
|
94
|
+
const payload = serializeWorkflowBody(options.input);
|
|
95
|
+
const response = await this.client.requestJson(
|
|
96
|
+
`/${this.workflowApiVersion}/workflows/${encodeURIComponent(this.workflowComponent)}/${encodeURIComponent(normalizedWorkflowName)}/start${query}`,
|
|
97
|
+
{
|
|
98
|
+
method: "POST",
|
|
99
|
+
...payload !== void 0 ? { body: payload } : {}
|
|
100
|
+
},
|
|
101
|
+
[202]
|
|
102
|
+
);
|
|
103
|
+
const instanceId = response?.instanceId ?? response?.instanceID ?? options.instanceId;
|
|
104
|
+
if (!instanceId) {
|
|
105
|
+
throw new Error(
|
|
106
|
+
`Dapr workflow start did not return an instanceId for workflow '${normalizedWorkflowName}'`
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
return { instanceId };
|
|
110
|
+
}
|
|
111
|
+
async getWorkflow(instanceId) {
|
|
112
|
+
const normalizedInstanceId = ensureNonEmpty(instanceId, "instanceId");
|
|
113
|
+
const response = await this.client.requestJson(
|
|
114
|
+
`/${this.workflowApiVersion}/workflows/${encodeURIComponent(this.workflowComponent)}/${encodeURIComponent(normalizedInstanceId)}`,
|
|
115
|
+
{ method: "GET" },
|
|
116
|
+
[200, 404]
|
|
117
|
+
);
|
|
118
|
+
if (!response) {
|
|
119
|
+
return void 0;
|
|
120
|
+
}
|
|
121
|
+
if (response.errorCode) {
|
|
122
|
+
return void 0;
|
|
123
|
+
}
|
|
124
|
+
if (!response.instanceId && !response.instanceID && !response.workflowName && !response.runtimeStatus) {
|
|
125
|
+
return void 0;
|
|
126
|
+
}
|
|
127
|
+
return normalizeWorkflowState(response);
|
|
128
|
+
}
|
|
129
|
+
async waitForWorkflowStart(instanceId, options = {}) {
|
|
130
|
+
return this.waitForWorkflowState(instanceId, {
|
|
131
|
+
...options,
|
|
132
|
+
predicate: (state) => hasStartedDaprWorkflow(state.runtimeStatus)
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
async waitForWorkflowCompletion(instanceId, options = {}) {
|
|
136
|
+
return this.waitForWorkflowState(instanceId, {
|
|
137
|
+
...options,
|
|
138
|
+
predicate: (state) => isTerminalDaprWorkflowStatus(state.runtimeStatus)
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
async pauseWorkflow(instanceId) {
|
|
142
|
+
await this.controlWorkflow(instanceId, "pause");
|
|
143
|
+
}
|
|
144
|
+
async resumeWorkflow(instanceId) {
|
|
145
|
+
await this.controlWorkflow(instanceId, "resume");
|
|
146
|
+
}
|
|
147
|
+
async terminateWorkflow(instanceId) {
|
|
148
|
+
await this.controlWorkflow(instanceId, "terminate");
|
|
149
|
+
}
|
|
150
|
+
async purgeWorkflow(instanceId) {
|
|
151
|
+
await this.controlWorkflow(instanceId, "purge");
|
|
152
|
+
}
|
|
153
|
+
async raiseWorkflowEvent(instanceId, eventName, options = {}) {
|
|
154
|
+
const normalizedInstanceId = ensureNonEmpty(instanceId, "instanceId");
|
|
155
|
+
const normalizedEventName = ensureNonEmpty(eventName, "eventName");
|
|
156
|
+
const payload = serializeWorkflowBody(options.eventData);
|
|
157
|
+
await this.client.request(
|
|
158
|
+
`/${this.workflowApiVersion}/workflows/${encodeURIComponent(this.workflowComponent)}/${encodeURIComponent(normalizedInstanceId)}/raiseEvent/${encodeURIComponent(normalizedEventName)}`,
|
|
159
|
+
{
|
|
160
|
+
method: "POST",
|
|
161
|
+
...payload !== void 0 ? { body: payload } : {}
|
|
162
|
+
},
|
|
163
|
+
[202]
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
async controlWorkflow(instanceId, action) {
|
|
167
|
+
const normalizedInstanceId = ensureNonEmpty(instanceId, "instanceId");
|
|
168
|
+
await this.client.request(
|
|
169
|
+
`/${this.workflowApiVersion}/workflows/${encodeURIComponent(this.workflowComponent)}/${encodeURIComponent(normalizedInstanceId)}/${action}`,
|
|
170
|
+
{ method: "POST" },
|
|
171
|
+
[202]
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
async waitForWorkflowState(instanceId, options) {
|
|
175
|
+
const timeoutMs = normalizeTimeout(options.timeoutMs);
|
|
176
|
+
const pollIntervalMs = normalizePollInterval(
|
|
177
|
+
options.pollIntervalMs ?? this.workflowPollIntervalMs
|
|
178
|
+
);
|
|
179
|
+
const deadline = Date.now() + timeoutMs;
|
|
180
|
+
while (Date.now() <= deadline) {
|
|
181
|
+
const state = await this.getWorkflow(instanceId);
|
|
182
|
+
if (state && options.predicate(state)) {
|
|
183
|
+
return state;
|
|
184
|
+
}
|
|
185
|
+
if (Date.now() >= deadline) {
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
await sleep(pollIntervalMs);
|
|
189
|
+
}
|
|
190
|
+
return void 0;
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
// src/workflow/runtime-activities.ts
|
|
195
|
+
import {
|
|
196
|
+
advanceAgentTurnState,
|
|
197
|
+
convertAgentMessagesToModelMessages,
|
|
198
|
+
createAgentTurnEngine,
|
|
199
|
+
createAgentTurnStepCommitBatch,
|
|
200
|
+
executeAgentToolCall,
|
|
201
|
+
normalizeToolReplayPolicy,
|
|
202
|
+
prepareModelStep,
|
|
203
|
+
restoreAgentWorkflowMessages,
|
|
204
|
+
runModelStep,
|
|
205
|
+
snapshotAgentWorkflowMessages
|
|
206
|
+
} from "@cuylabs/agent-core";
|
|
207
|
+
function normalizeError(error) {
|
|
208
|
+
if (error instanceof Error) return error;
|
|
209
|
+
if (typeof error === "string") return new Error(error);
|
|
210
|
+
if (error && typeof error === "object") {
|
|
211
|
+
if ("message" in error && typeof error.message === "string") {
|
|
212
|
+
return new Error(error.message);
|
|
213
|
+
}
|
|
214
|
+
try {
|
|
215
|
+
return new Error(JSON.stringify(error));
|
|
216
|
+
} catch {
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return new Error(String(error));
|
|
220
|
+
}
|
|
221
|
+
function resolveOption(value) {
|
|
222
|
+
return typeof value === "function" ? value() : value;
|
|
223
|
+
}
|
|
224
|
+
async function* emptyCommitApplier() {
|
|
225
|
+
yield* [];
|
|
226
|
+
}
|
|
227
|
+
function createDaprAgentTurnSteerDrainActivity(options) {
|
|
228
|
+
return {
|
|
229
|
+
name: "steer-drain",
|
|
230
|
+
handler: async (_context, input) => options.drain(input)
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
async function withObserverContext(bridge, sessionId, fn) {
|
|
234
|
+
const parentCtx = bridge?.getOtelContext(sessionId);
|
|
235
|
+
if (!parentCtx) return fn();
|
|
236
|
+
try {
|
|
237
|
+
const otelApi = await import("@opentelemetry/api");
|
|
238
|
+
return await otelApi.context.with(
|
|
239
|
+
parentCtx,
|
|
240
|
+
fn
|
|
241
|
+
);
|
|
242
|
+
} catch {
|
|
243
|
+
return fn();
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
function createDaprAgentTurnModelStepActivity(options) {
|
|
247
|
+
const now = options.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
|
|
248
|
+
return {
|
|
249
|
+
name: "model-step",
|
|
250
|
+
handler: async (_context, plan) => {
|
|
251
|
+
const runActivity = async () => {
|
|
252
|
+
const runtime = resolveOption(options.runtime);
|
|
253
|
+
const tools = resolveOption(options.tools);
|
|
254
|
+
const host = options.host ? resolveOption(options.host) : void 0;
|
|
255
|
+
const middleware = options.middleware ? resolveOption(options.middleware) : void 0;
|
|
256
|
+
const reasoningLevel = options.reasoningLevel ? resolveOption(options.reasoningLevel) : void 0;
|
|
257
|
+
if (middleware?.hasMiddleware) {
|
|
258
|
+
await middleware.runChatStart(
|
|
259
|
+
plan.sessionId,
|
|
260
|
+
`[workflow model-step ${plan.step}]`
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
let stepResult;
|
|
264
|
+
let stepError;
|
|
265
|
+
try {
|
|
266
|
+
const systemPrompts = options.resolveSystemPrompts ? await options.resolveSystemPrompts(
|
|
267
|
+
plan.sessionId,
|
|
268
|
+
plan.systemPrompts
|
|
269
|
+
) : plan.systemPrompts;
|
|
270
|
+
const restoredMessages = restoreAgentWorkflowMessages(plan.messages);
|
|
271
|
+
const turnEngine = createAgentTurnEngine({
|
|
272
|
+
sessionId: plan.sessionId,
|
|
273
|
+
startedAt: now(),
|
|
274
|
+
getToolReplayPolicy: (toolName) => tools[toolName]?.replayPolicy ? normalizeToolReplayPolicy(tools[toolName].replayPolicy) : void 0
|
|
275
|
+
});
|
|
276
|
+
const preparedStep = prepareModelStep({
|
|
277
|
+
sessionId: plan.sessionId,
|
|
278
|
+
step: plan.step,
|
|
279
|
+
systemPrompts,
|
|
280
|
+
messages: restoredMessages,
|
|
281
|
+
toModelMessages: options.toModelMessages ?? convertAgentMessagesToModelMessages,
|
|
282
|
+
abort: options.createAbortSignal?.() ?? new AbortController().signal,
|
|
283
|
+
tools,
|
|
284
|
+
mcpTools: typeof options.mcpTools === "function" ? await options.mcpTools() : options.mcpTools,
|
|
285
|
+
config: runtime,
|
|
286
|
+
...host ? { host } : {},
|
|
287
|
+
...options.turnTracker ? { turnTracker: options.turnTracker } : {},
|
|
288
|
+
...middleware ? { middleware } : {},
|
|
289
|
+
...reasoningLevel ? { reasoningLevel } : {},
|
|
290
|
+
toolExecutionMode: "plan"
|
|
291
|
+
});
|
|
292
|
+
const iterator = runModelStep({
|
|
293
|
+
preparedStep,
|
|
294
|
+
turnEngine,
|
|
295
|
+
applyCommitBatch: () => emptyCommitApplier()
|
|
296
|
+
});
|
|
297
|
+
while (true) {
|
|
298
|
+
const item = await iterator.next();
|
|
299
|
+
if (item.done) {
|
|
300
|
+
const stepCommit = turnEngine.createStepCommitSnapshot();
|
|
301
|
+
stepResult = {
|
|
302
|
+
text: item.value.text,
|
|
303
|
+
...item.value.usage ? { usage: item.value.usage } : {},
|
|
304
|
+
...item.value.finishReason ? { finishReason: item.value.finishReason } : {},
|
|
305
|
+
turnState: turnEngine.getState(),
|
|
306
|
+
...stepCommit ? { stepCommit } : {}
|
|
307
|
+
};
|
|
308
|
+
break;
|
|
309
|
+
}
|
|
310
|
+
if (options.onEvent) {
|
|
311
|
+
await options.onEvent(plan.sessionId, item.value);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
} catch (err) {
|
|
315
|
+
stepError = normalizeError(err);
|
|
316
|
+
}
|
|
317
|
+
if (middleware?.hasMiddleware) {
|
|
318
|
+
await middleware.runChatEnd(plan.sessionId, {
|
|
319
|
+
usage: stepResult?.usage,
|
|
320
|
+
error: stepError,
|
|
321
|
+
output: stepResult?.text
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
if (stepError) throw stepError;
|
|
325
|
+
return stepResult;
|
|
326
|
+
};
|
|
327
|
+
return withObserverContext(
|
|
328
|
+
options.observerBridge,
|
|
329
|
+
plan.sessionId,
|
|
330
|
+
runActivity
|
|
331
|
+
);
|
|
332
|
+
}
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
function createDaprAgentTurnToolCallActivity(options) {
|
|
336
|
+
const now = options.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
|
|
337
|
+
return {
|
|
338
|
+
name: "tool-call",
|
|
339
|
+
handler: async (_context, plan) => {
|
|
340
|
+
const runActivity = async () => {
|
|
341
|
+
const tools = resolveOption(options.tools);
|
|
342
|
+
const host = options.host ? resolveOption(options.host) : void 0;
|
|
343
|
+
const middleware = options.middleware ? resolveOption(options.middleware) : void 0;
|
|
344
|
+
if (plan.replayDecision?.action === "skip") {
|
|
345
|
+
throw new Error(
|
|
346
|
+
`Tool call '${plan.toolCall.toolCallId}' cannot be skipped without a persisted result`
|
|
347
|
+
);
|
|
348
|
+
}
|
|
349
|
+
const updatedAt = now();
|
|
350
|
+
const tool = tools[plan.toolCall.toolName];
|
|
351
|
+
if (!tool) {
|
|
352
|
+
const event = {
|
|
353
|
+
type: "tool-error",
|
|
354
|
+
toolName: plan.toolCall.toolName,
|
|
355
|
+
toolCallId: plan.toolCall.toolCallId,
|
|
356
|
+
error: `Tool '${plan.toolCall.toolName}' is not registered`
|
|
357
|
+
};
|
|
358
|
+
return {
|
|
359
|
+
toolResult: {
|
|
360
|
+
toolCallId: plan.toolCall.toolCallId,
|
|
361
|
+
toolName: plan.toolCall.toolName,
|
|
362
|
+
result: `Error: Tool '${plan.toolCall.toolName}' is not registered`,
|
|
363
|
+
...plan.toolCall.replayPolicy ? { replayPolicy: plan.toolCall.replayPolicy } : {}
|
|
364
|
+
},
|
|
365
|
+
...plan.turnState ? {
|
|
366
|
+
turnState: advanceAgentTurnState(
|
|
367
|
+
plan.turnState,
|
|
368
|
+
event,
|
|
369
|
+
updatedAt,
|
|
370
|
+
{
|
|
371
|
+
...plan.toolCall.replayPolicy ? { toolReplayPolicy: plan.toolCall.replayPolicy } : {}
|
|
372
|
+
}
|
|
373
|
+
)
|
|
374
|
+
} : {}
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
try {
|
|
378
|
+
const executed = await executeAgentToolCall({
|
|
379
|
+
toolName: plan.toolCall.toolName,
|
|
380
|
+
tool,
|
|
381
|
+
params: plan.toolCall.args,
|
|
382
|
+
cwd: options.cwd,
|
|
383
|
+
abort: options.createAbortSignal?.() ?? new AbortController().signal,
|
|
384
|
+
sessionID: plan.sessionId,
|
|
385
|
+
messageID: plan.toolCall.toolCallId,
|
|
386
|
+
...host ? { host } : {},
|
|
387
|
+
...options.turnTracker ? { turnTracker: options.turnTracker } : {},
|
|
388
|
+
...middleware ? { middleware } : {}
|
|
389
|
+
});
|
|
390
|
+
const event = {
|
|
391
|
+
type: "tool-result",
|
|
392
|
+
toolName: plan.toolCall.toolName,
|
|
393
|
+
toolCallId: plan.toolCall.toolCallId,
|
|
394
|
+
result: executed.output
|
|
395
|
+
};
|
|
396
|
+
return {
|
|
397
|
+
toolResult: {
|
|
398
|
+
toolCallId: plan.toolCall.toolCallId,
|
|
399
|
+
toolName: plan.toolCall.toolName,
|
|
400
|
+
result: executed.output,
|
|
401
|
+
...plan.toolCall.replayPolicy ? { replayPolicy: plan.toolCall.replayPolicy } : {}
|
|
402
|
+
},
|
|
403
|
+
...plan.turnState ? {
|
|
404
|
+
turnState: advanceAgentTurnState(
|
|
405
|
+
plan.turnState,
|
|
406
|
+
event,
|
|
407
|
+
updatedAt,
|
|
408
|
+
{
|
|
409
|
+
...plan.toolCall.replayPolicy ? { toolReplayPolicy: plan.toolCall.replayPolicy } : {}
|
|
410
|
+
}
|
|
411
|
+
)
|
|
412
|
+
} : {}
|
|
413
|
+
};
|
|
414
|
+
} catch (error) {
|
|
415
|
+
const message = normalizeError(error).message;
|
|
416
|
+
const event = {
|
|
417
|
+
type: "tool-error",
|
|
418
|
+
toolName: plan.toolCall.toolName,
|
|
419
|
+
toolCallId: plan.toolCall.toolCallId,
|
|
420
|
+
error: message
|
|
421
|
+
};
|
|
422
|
+
return {
|
|
423
|
+
toolResult: {
|
|
424
|
+
toolCallId: plan.toolCall.toolCallId,
|
|
425
|
+
toolName: plan.toolCall.toolName,
|
|
426
|
+
result: `Error: ${message}`,
|
|
427
|
+
...plan.toolCall.replayPolicy ? { replayPolicy: plan.toolCall.replayPolicy } : {}
|
|
428
|
+
},
|
|
429
|
+
...plan.turnState ? {
|
|
430
|
+
turnState: advanceAgentTurnState(
|
|
431
|
+
plan.turnState,
|
|
432
|
+
event,
|
|
433
|
+
updatedAt,
|
|
434
|
+
{
|
|
435
|
+
...plan.toolCall.replayPolicy ? { toolReplayPolicy: plan.toolCall.replayPolicy } : {}
|
|
436
|
+
}
|
|
437
|
+
)
|
|
438
|
+
} : {}
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
};
|
|
442
|
+
return withObserverContext(
|
|
443
|
+
options.observerBridge,
|
|
444
|
+
plan.sessionId,
|
|
445
|
+
runActivity
|
|
446
|
+
);
|
|
447
|
+
}
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
function createDaprAgentTurnApprovalCheckActivity(options) {
|
|
451
|
+
return {
|
|
452
|
+
name: "approval-check",
|
|
453
|
+
handler: async (_context, input) => await options.check(input)
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
function createDaprAgentTurnHumanInputCheckActivity(options) {
|
|
457
|
+
return {
|
|
458
|
+
name: "human-input-check",
|
|
459
|
+
handler: async (_context, input) => await options.check(input)
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
function createDaprAgentTurnStepCommitActivity(options) {
|
|
463
|
+
return {
|
|
464
|
+
name: "step-commit",
|
|
465
|
+
handler: async (_context, plan) => {
|
|
466
|
+
if (plan.kind === "input-commit") {
|
|
467
|
+
const messages = restoreAgentWorkflowMessages(plan.messages);
|
|
468
|
+
await options.persistMessages(plan.sessionId, messages);
|
|
469
|
+
return {
|
|
470
|
+
messages: plan.messages.map((message) => structuredClone(message))
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
const batch = createAgentTurnStepCommitBatch(plan.step, plan.snapshot);
|
|
474
|
+
if (!batch) {
|
|
475
|
+
return { messages: [] };
|
|
476
|
+
}
|
|
477
|
+
await options.persistMessages(plan.sessionId, batch.messages);
|
|
478
|
+
return { messages: snapshotAgentWorkflowMessages(batch.messages) };
|
|
479
|
+
}
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
function createDaprAgentTurnOutputCommitActivity(options) {
|
|
483
|
+
const now = options.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
|
|
484
|
+
return {
|
|
485
|
+
name: "output-commit",
|
|
486
|
+
handler: async (_context, plan) => {
|
|
487
|
+
const turnEngine = createAgentTurnEngine({
|
|
488
|
+
sessionId: plan.sessionId,
|
|
489
|
+
startedAt: now()
|
|
490
|
+
});
|
|
491
|
+
const batch = turnEngine.createOutputCommit({
|
|
492
|
+
text: plan.text,
|
|
493
|
+
usage: plan.usage
|
|
494
|
+
});
|
|
495
|
+
if (!batch) {
|
|
496
|
+
return { messages: [] };
|
|
497
|
+
}
|
|
498
|
+
await options.persistMessages(plan.sessionId, batch.messages);
|
|
499
|
+
return { messages: snapshotAgentWorkflowMessages(batch.messages) };
|
|
500
|
+
}
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
// src/workflow/runtime.ts
|
|
505
|
+
import {
|
|
506
|
+
advanceAgentTurnState as advanceAgentTurnState2,
|
|
507
|
+
applyWorkflowInterventions,
|
|
508
|
+
applyAgentWorkflowCommitResult,
|
|
509
|
+
applyAgentWorkflowModelStepResult,
|
|
510
|
+
applyAgentWorkflowToolCallResult,
|
|
511
|
+
createApprovalCorrection,
|
|
512
|
+
failAgentWorkflowTurnState,
|
|
513
|
+
formatApprovalDeniedReason,
|
|
514
|
+
planNextAgentWorkflowOperation,
|
|
515
|
+
recordAgentWorkflowReplayDecision
|
|
516
|
+
} from "@cuylabs/agent-core";
|
|
517
|
+
var MAX_CONTROL_EVENTS_PER_BOUNDARY = 32;
|
|
518
|
+
var DEFAULT_WORKFLOW_NAME = "agent-turn";
|
|
519
|
+
function defaultActivityNames(workflowName, overrides = {}, options = {}) {
|
|
520
|
+
return {
|
|
521
|
+
...options.includeSteerDrain || overrides.steerDrain ? {
|
|
522
|
+
steerDrain: overrides.steerDrain ?? `${workflowName}:steer-drain`
|
|
523
|
+
} : {},
|
|
524
|
+
modelStep: overrides.modelStep ?? `${workflowName}:model-step`,
|
|
525
|
+
...options.includeHumanInputCheck || overrides.humanInputCheck ? {
|
|
526
|
+
humanInputCheck: overrides.humanInputCheck ?? `${workflowName}:human-input-check`
|
|
527
|
+
} : {},
|
|
528
|
+
...options.includeApprovalCheck || overrides.approvalCheck ? {
|
|
529
|
+
approvalCheck: overrides.approvalCheck ?? `${workflowName}:approval-check`
|
|
530
|
+
} : {},
|
|
531
|
+
toolCall: overrides.toolCall ?? `${workflowName}:tool-call`,
|
|
532
|
+
stepCommit: overrides.stepCommit ?? `${workflowName}:step-commit`,
|
|
533
|
+
outputCommit: overrides.outputCommit ?? `${workflowName}:output-commit`
|
|
534
|
+
};
|
|
535
|
+
}
|
|
536
|
+
function normalizeError2(error) {
|
|
537
|
+
if (error instanceof Error) return error;
|
|
538
|
+
if (typeof error === "string") return new Error(error);
|
|
539
|
+
if (error && typeof error === "object") {
|
|
540
|
+
if ("message" in error && typeof error.message === "string") {
|
|
541
|
+
return new Error(error.message);
|
|
542
|
+
}
|
|
543
|
+
try {
|
|
544
|
+
return new Error(JSON.stringify(error));
|
|
545
|
+
} catch {
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
return new Error(String(error));
|
|
549
|
+
}
|
|
550
|
+
function renameActivity(activity, name) {
|
|
551
|
+
return {
|
|
552
|
+
name,
|
|
553
|
+
handler: activity.handler
|
|
554
|
+
};
|
|
555
|
+
}
|
|
556
|
+
function summarizeWorkflowState(state) {
|
|
557
|
+
return JSON.stringify({
|
|
558
|
+
sessionId: state.sessionId,
|
|
559
|
+
phase: state.phase,
|
|
560
|
+
step: state.step,
|
|
561
|
+
finalResponse: state.finalResponse,
|
|
562
|
+
error: state.error
|
|
563
|
+
});
|
|
564
|
+
}
|
|
565
|
+
function ensureReplayDecision(state, plan, now) {
|
|
566
|
+
if (plan.replayDecision) {
|
|
567
|
+
return { state, decision: plan.replayDecision };
|
|
568
|
+
}
|
|
569
|
+
const mode = plan.toolCall.replayPolicy?.mode;
|
|
570
|
+
if (!mode) {
|
|
571
|
+
return { state };
|
|
572
|
+
}
|
|
573
|
+
if (mode === "manual") {
|
|
574
|
+
const decision2 = {
|
|
575
|
+
toolCallId: plan.toolCall.toolCallId,
|
|
576
|
+
toolName: plan.toolCall.toolName,
|
|
577
|
+
action: "replay",
|
|
578
|
+
source: "runtime",
|
|
579
|
+
decidedAt: now,
|
|
580
|
+
reason: "auto-decided by Dapr workflow runtime (activity-level checkpoint)"
|
|
581
|
+
};
|
|
582
|
+
return {
|
|
583
|
+
state: recordAgentWorkflowReplayDecision(state, decision2, now),
|
|
584
|
+
decision: decision2
|
|
585
|
+
};
|
|
586
|
+
}
|
|
587
|
+
const decision = {
|
|
588
|
+
toolCallId: plan.toolCall.toolCallId,
|
|
589
|
+
toolName: plan.toolCall.toolName,
|
|
590
|
+
action: mode === "skip" ? "skip" : "replay",
|
|
591
|
+
source: "policy",
|
|
592
|
+
decidedAt: now,
|
|
593
|
+
...plan.toolCall.replayPolicy?.reason ? { reason: plan.toolCall.replayPolicy.reason } : {}
|
|
594
|
+
};
|
|
595
|
+
return {
|
|
596
|
+
state: recordAgentWorkflowReplayDecision(state, decision, now),
|
|
597
|
+
decision
|
|
598
|
+
};
|
|
599
|
+
}
|
|
600
|
+
function extractApprovalDecision(value) {
|
|
601
|
+
if (value === "allow" || value === "deny" || value === "remember") {
|
|
602
|
+
return { action: value };
|
|
603
|
+
}
|
|
604
|
+
if (value && typeof value === "object" && "action" in value && (value.action === "allow" || value.action === "deny" || value.action === "remember")) {
|
|
605
|
+
const decision = value;
|
|
606
|
+
return {
|
|
607
|
+
action: decision.action,
|
|
608
|
+
...typeof decision.feedback === "string" ? { feedback: decision.feedback } : {},
|
|
609
|
+
...decision.rememberScope === "session" || decision.rememberScope === "project" || decision.rememberScope === "user" ? { rememberScope: decision.rememberScope } : {}
|
|
610
|
+
};
|
|
611
|
+
}
|
|
612
|
+
throw new Error("Approval decision event is missing a valid action");
|
|
613
|
+
}
|
|
614
|
+
function extractHumanInputResponse(value) {
|
|
615
|
+
if (value && typeof value === "object" && "kind" in value && typeof value.kind === "string" && "text" in value && typeof value.text === "string") {
|
|
616
|
+
const response = value;
|
|
617
|
+
if (response.kind === "text") {
|
|
618
|
+
return response;
|
|
619
|
+
}
|
|
620
|
+
if (response.kind === "confirm" && "confirmed" in response) {
|
|
621
|
+
return response;
|
|
622
|
+
}
|
|
623
|
+
if (response.kind === "choice" && "selected" in response && Array.isArray(response.selected)) {
|
|
624
|
+
return response;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
throw new Error("Human input response event is missing a valid response");
|
|
628
|
+
}
|
|
629
|
+
function createDeniedToolCallResult(plan, reason, updatedAt, feedback) {
|
|
630
|
+
const resultText = reason || formatApprovalDeniedReason(plan.toolCall.toolName);
|
|
631
|
+
const correction = createApprovalCorrection(
|
|
632
|
+
plan.toolCall.toolName,
|
|
633
|
+
feedback
|
|
634
|
+
);
|
|
635
|
+
const toolResult = {
|
|
636
|
+
toolCallId: plan.toolCall.toolCallId,
|
|
637
|
+
toolName: plan.toolCall.toolName,
|
|
638
|
+
result: resultText,
|
|
639
|
+
metadata: {
|
|
640
|
+
approvalCorrection: correction
|
|
641
|
+
},
|
|
642
|
+
...plan.toolCall.replayPolicy ? { replayPolicy: plan.toolCall.replayPolicy } : {}
|
|
643
|
+
};
|
|
644
|
+
if (!plan.turnState) {
|
|
645
|
+
return { toolResult };
|
|
646
|
+
}
|
|
647
|
+
return {
|
|
648
|
+
toolResult,
|
|
649
|
+
turnState: advanceAgentTurnState2(
|
|
650
|
+
plan.turnState,
|
|
651
|
+
{
|
|
652
|
+
type: "tool-result",
|
|
653
|
+
toolName: plan.toolCall.toolName,
|
|
654
|
+
toolCallId: plan.toolCall.toolCallId,
|
|
655
|
+
result: resultText,
|
|
656
|
+
metadata: {
|
|
657
|
+
approvalCorrection: correction
|
|
658
|
+
}
|
|
659
|
+
},
|
|
660
|
+
updatedAt,
|
|
661
|
+
{
|
|
662
|
+
...plan.toolCall.replayPolicy ? { toolReplayPolicy: plan.toolCall.replayPolicy } : {}
|
|
663
|
+
}
|
|
664
|
+
)
|
|
665
|
+
};
|
|
666
|
+
}
|
|
667
|
+
function createHumanInputToolCallResult(plan, response, updatedAt) {
|
|
668
|
+
const resultText = response.text;
|
|
669
|
+
const toolResult = {
|
|
670
|
+
toolCallId: plan.toolCall.toolCallId,
|
|
671
|
+
toolName: plan.toolCall.toolName,
|
|
672
|
+
result: resultText,
|
|
673
|
+
...plan.toolCall.replayPolicy ? { replayPolicy: plan.toolCall.replayPolicy } : {}
|
|
674
|
+
};
|
|
675
|
+
if (!plan.turnState) {
|
|
676
|
+
return { toolResult };
|
|
677
|
+
}
|
|
678
|
+
return {
|
|
679
|
+
toolResult,
|
|
680
|
+
turnState: advanceAgentTurnState2(
|
|
681
|
+
plan.turnState,
|
|
682
|
+
{
|
|
683
|
+
type: "tool-result",
|
|
684
|
+
toolName: plan.toolCall.toolName,
|
|
685
|
+
toolCallId: plan.toolCall.toolCallId,
|
|
686
|
+
result: resultText
|
|
687
|
+
},
|
|
688
|
+
updatedAt,
|
|
689
|
+
{
|
|
690
|
+
...plan.toolCall.replayPolicy ? { toolReplayPolicy: plan.toolCall.replayPolicy } : {}
|
|
691
|
+
}
|
|
692
|
+
)
|
|
693
|
+
};
|
|
694
|
+
}
|
|
695
|
+
function normalizeSteerSnapshots(payload) {
|
|
696
|
+
if (!Array.isArray(payload)) {
|
|
697
|
+
return [];
|
|
698
|
+
}
|
|
699
|
+
return payload.flatMap((candidate) => {
|
|
700
|
+
if (!candidate || typeof candidate !== "object") {
|
|
701
|
+
return [];
|
|
702
|
+
}
|
|
703
|
+
const steer = candidate;
|
|
704
|
+
if (typeof steer.id !== "string" || !steer.id.trim() || typeof steer.message !== "string" || !steer.message.trim() || typeof steer.createdAt !== "string" || !steer.createdAt.trim()) {
|
|
705
|
+
return [];
|
|
706
|
+
}
|
|
707
|
+
return [{
|
|
708
|
+
id: steer.id.trim(),
|
|
709
|
+
message: steer.message.trim(),
|
|
710
|
+
createdAt: steer.createdAt.trim()
|
|
711
|
+
}];
|
|
712
|
+
});
|
|
713
|
+
}
|
|
714
|
+
var EXTERNAL_EVENT_TIMEOUT = /* @__PURE__ */ Symbol("EXTERNAL_EVENT_TIMEOUT");
|
|
715
|
+
function* waitForExternalEventWithTimeout(context, eventName, timeoutMs) {
|
|
716
|
+
if (!context.waitForExternalEvent) {
|
|
717
|
+
throw new Error(
|
|
718
|
+
"Workflow context does not support waitForExternalEvent"
|
|
719
|
+
);
|
|
720
|
+
}
|
|
721
|
+
const eventTask = context.waitForExternalEvent(eventName);
|
|
722
|
+
if (timeoutMs && timeoutMs > 0 && context.createTimer && context.whenAny) {
|
|
723
|
+
const timerTask = context.createTimer(timeoutMs);
|
|
724
|
+
const winner = yield context.whenAny([eventTask, timerTask]);
|
|
725
|
+
if (winner === timerTask) {
|
|
726
|
+
return EXTERNAL_EVENT_TIMEOUT;
|
|
727
|
+
}
|
|
728
|
+
const eventHandle = eventTask;
|
|
729
|
+
if (typeof eventHandle.getResult === "function") {
|
|
730
|
+
return eventHandle.getResult();
|
|
731
|
+
}
|
|
732
|
+
return winner;
|
|
733
|
+
}
|
|
734
|
+
return yield eventTask;
|
|
735
|
+
}
|
|
736
|
+
function createDaprAgentTurnWorkflowDefinition(options) {
|
|
737
|
+
const workflowName = options.workflowName ?? DEFAULT_WORKFLOW_NAME;
|
|
738
|
+
const activityNames = defaultActivityNames(
|
|
739
|
+
workflowName,
|
|
740
|
+
options.activityNames,
|
|
741
|
+
{
|
|
742
|
+
includeSteerDrain: Boolean(options.steerDrain),
|
|
743
|
+
includeHumanInputCheck: Boolean(options.humanInputCheck),
|
|
744
|
+
includeApprovalCheck: Boolean(options.approvalCheck)
|
|
745
|
+
}
|
|
746
|
+
);
|
|
747
|
+
const now = options.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
|
|
748
|
+
const steeringEnabled = options.steeringEnabled ?? false;
|
|
749
|
+
const continueAsNewThreshold = options.continueAsNewThreshold;
|
|
750
|
+
const workflow = async function* (context, input) {
|
|
751
|
+
const bridge = options.observerBridge;
|
|
752
|
+
let state = structuredClone(input);
|
|
753
|
+
if (!context.isReplaying?.()) {
|
|
754
|
+
await bridge?.notifyTaskStart(state);
|
|
755
|
+
}
|
|
756
|
+
try {
|
|
757
|
+
while (true) {
|
|
758
|
+
context.setCustomStatus?.(summarizeWorkflowState(state));
|
|
759
|
+
if (state.phase === "model-step" && steeringEnabled && activityNames.steerDrain && options.steerDrain) {
|
|
760
|
+
const controlEvents = normalizeSteerSnapshots(
|
|
761
|
+
yield context.callActivity(
|
|
762
|
+
activityNames.steerDrain,
|
|
763
|
+
{
|
|
764
|
+
workflowInstanceId: context.getWorkflowInstanceId?.() ?? "",
|
|
765
|
+
sessionId: state.sessionId,
|
|
766
|
+
step: state.step,
|
|
767
|
+
maxItems: MAX_CONTROL_EVENTS_PER_BOUNDARY
|
|
768
|
+
}
|
|
769
|
+
)
|
|
770
|
+
);
|
|
771
|
+
if (controlEvents.length > 0) {
|
|
772
|
+
state = applyWorkflowInterventions(state, controlEvents, now());
|
|
773
|
+
if (!context.isReplaying?.()) {
|
|
774
|
+
for (const steerEvent of controlEvents) {
|
|
775
|
+
await options.onEvent?.(state.sessionId, {
|
|
776
|
+
type: "intervention-applied",
|
|
777
|
+
id: steerEvent.id,
|
|
778
|
+
message: steerEvent.message
|
|
779
|
+
});
|
|
780
|
+
}
|
|
781
|
+
await bridge?.notifyCheckpoint("intervention-commit-finish", state);
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
const plan = planNextAgentWorkflowOperation(state);
|
|
786
|
+
if (!plan) {
|
|
787
|
+
if (!context.isReplaying?.()) {
|
|
788
|
+
await bridge?.notifyTaskComplete(state);
|
|
789
|
+
}
|
|
790
|
+
return state;
|
|
791
|
+
}
|
|
792
|
+
switch (plan.kind) {
|
|
793
|
+
case "input-commit": {
|
|
794
|
+
const result = yield context.callActivity(
|
|
795
|
+
activityNames.stepCommit,
|
|
796
|
+
plan
|
|
797
|
+
);
|
|
798
|
+
state = applyAgentWorkflowCommitResult(state, result, now());
|
|
799
|
+
if (!context.isReplaying?.()) {
|
|
800
|
+
await bridge?.notifyCheckpoint("input-commit-finish", state);
|
|
801
|
+
}
|
|
802
|
+
break;
|
|
803
|
+
}
|
|
804
|
+
case "model-step": {
|
|
805
|
+
const result = yield context.callActivity(
|
|
806
|
+
activityNames.modelStep,
|
|
807
|
+
plan
|
|
808
|
+
);
|
|
809
|
+
state = applyAgentWorkflowModelStepResult(state, result, now());
|
|
810
|
+
if (!context.isReplaying?.()) {
|
|
811
|
+
await bridge?.notifyCheckpoint("step-finish", state);
|
|
812
|
+
}
|
|
813
|
+
break;
|
|
814
|
+
}
|
|
815
|
+
case "tool-call": {
|
|
816
|
+
const decisionState = ensureReplayDecision(state, plan, now());
|
|
817
|
+
state = decisionState.state;
|
|
818
|
+
if (decisionState.decision?.action === "skip") {
|
|
819
|
+
throw new Error(
|
|
820
|
+
`Cannot skip unresolved tool call '${plan.toolCall.toolCallId}' without a previously persisted tool result`
|
|
821
|
+
);
|
|
822
|
+
}
|
|
823
|
+
if (activityNames.humanInputCheck && options.humanInputCheck) {
|
|
824
|
+
const humanInput = yield context.callActivity(
|
|
825
|
+
activityNames.humanInputCheck,
|
|
826
|
+
{
|
|
827
|
+
workflowInstanceId: context.getWorkflowInstanceId?.() ?? "",
|
|
828
|
+
sessionId: plan.sessionId,
|
|
829
|
+
step: plan.step,
|
|
830
|
+
toolCall: structuredClone(plan.toolCall)
|
|
831
|
+
}
|
|
832
|
+
);
|
|
833
|
+
if (humanInput.action === "deny") {
|
|
834
|
+
state = applyAgentWorkflowToolCallResult(
|
|
835
|
+
state,
|
|
836
|
+
createDeniedToolCallResult(plan, humanInput.reason, now()),
|
|
837
|
+
now()
|
|
838
|
+
);
|
|
839
|
+
if (!context.isReplaying?.()) {
|
|
840
|
+
await bridge?.notifyCheckpoint("tool-result", state);
|
|
841
|
+
}
|
|
842
|
+
break;
|
|
843
|
+
}
|
|
844
|
+
if (humanInput.action === "request") {
|
|
845
|
+
if (!context.waitForExternalEvent) {
|
|
846
|
+
throw new Error(
|
|
847
|
+
"Workflow context does not support waitForExternalEvent for human input requests"
|
|
848
|
+
);
|
|
849
|
+
}
|
|
850
|
+
context.setCustomStatus?.(
|
|
851
|
+
JSON.stringify({
|
|
852
|
+
sessionId: state.sessionId,
|
|
853
|
+
phase: "waiting-input",
|
|
854
|
+
step: state.step,
|
|
855
|
+
toolCallId: plan.toolCall.toolCallId,
|
|
856
|
+
request: humanInput.request
|
|
857
|
+
})
|
|
858
|
+
);
|
|
859
|
+
const eventPayload = yield* waitForExternalEventWithTimeout(
|
|
860
|
+
context,
|
|
861
|
+
humanInput.eventName,
|
|
862
|
+
options.humanInputTimeoutMs
|
|
863
|
+
);
|
|
864
|
+
if (eventPayload === EXTERNAL_EVENT_TIMEOUT) {
|
|
865
|
+
state = applyAgentWorkflowToolCallResult(
|
|
866
|
+
state,
|
|
867
|
+
createDeniedToolCallResult(
|
|
868
|
+
plan,
|
|
869
|
+
`Human input request timed out after ${options.humanInputTimeoutMs}ms`,
|
|
870
|
+
now()
|
|
871
|
+
),
|
|
872
|
+
now()
|
|
873
|
+
);
|
|
874
|
+
if (!context.isReplaying?.()) {
|
|
875
|
+
await bridge?.notifyCheckpoint("tool-result", state);
|
|
876
|
+
}
|
|
877
|
+
break;
|
|
878
|
+
}
|
|
879
|
+
const response = extractHumanInputResponse(eventPayload);
|
|
880
|
+
state = applyAgentWorkflowToolCallResult(
|
|
881
|
+
state,
|
|
882
|
+
createHumanInputToolCallResult(plan, response, now()),
|
|
883
|
+
now()
|
|
884
|
+
);
|
|
885
|
+
if (!context.isReplaying?.()) {
|
|
886
|
+
await bridge?.notifyCheckpoint("tool-result", state);
|
|
887
|
+
}
|
|
888
|
+
break;
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
if (activityNames.approvalCheck && options.approvalCheck) {
|
|
892
|
+
const approval = yield context.callActivity(
|
|
893
|
+
activityNames.approvalCheck,
|
|
894
|
+
{
|
|
895
|
+
workflowInstanceId: context.getWorkflowInstanceId?.() ?? "",
|
|
896
|
+
sessionId: plan.sessionId,
|
|
897
|
+
step: plan.step,
|
|
898
|
+
toolCall: structuredClone(plan.toolCall)
|
|
899
|
+
}
|
|
900
|
+
);
|
|
901
|
+
if (approval.action === "deny") {
|
|
902
|
+
state = applyAgentWorkflowToolCallResult(
|
|
903
|
+
state,
|
|
904
|
+
createDeniedToolCallResult(plan, approval.reason, now()),
|
|
905
|
+
now()
|
|
906
|
+
);
|
|
907
|
+
if (!context.isReplaying?.()) {
|
|
908
|
+
await bridge?.notifyCheckpoint("tool-result", state);
|
|
909
|
+
}
|
|
910
|
+
break;
|
|
911
|
+
}
|
|
912
|
+
if (approval.action === "request") {
|
|
913
|
+
if (!context.waitForExternalEvent) {
|
|
914
|
+
throw new Error(
|
|
915
|
+
"Workflow context does not support waitForExternalEvent for approval requests"
|
|
916
|
+
);
|
|
917
|
+
}
|
|
918
|
+
context.setCustomStatus?.(
|
|
919
|
+
JSON.stringify({
|
|
920
|
+
sessionId: state.sessionId,
|
|
921
|
+
phase: "waiting-approval",
|
|
922
|
+
step: state.step,
|
|
923
|
+
toolCallId: plan.toolCall.toolCallId,
|
|
924
|
+
request: approval.request
|
|
925
|
+
})
|
|
926
|
+
);
|
|
927
|
+
const eventPayload = yield* waitForExternalEventWithTimeout(
|
|
928
|
+
context,
|
|
929
|
+
approval.eventName,
|
|
930
|
+
options.approvalTimeoutMs
|
|
931
|
+
);
|
|
932
|
+
if (eventPayload === EXTERNAL_EVENT_TIMEOUT) {
|
|
933
|
+
state = applyAgentWorkflowToolCallResult(
|
|
934
|
+
state,
|
|
935
|
+
createDeniedToolCallResult(
|
|
936
|
+
plan,
|
|
937
|
+
`Approval request timed out after ${options.approvalTimeoutMs}ms`,
|
|
938
|
+
now()
|
|
939
|
+
),
|
|
940
|
+
now()
|
|
941
|
+
);
|
|
942
|
+
if (!context.isReplaying?.()) {
|
|
943
|
+
await bridge?.notifyCheckpoint("tool-result", state);
|
|
944
|
+
}
|
|
945
|
+
break;
|
|
946
|
+
}
|
|
947
|
+
const decision = extractApprovalDecision(eventPayload);
|
|
948
|
+
if (decision.action === "deny") {
|
|
949
|
+
state = applyAgentWorkflowToolCallResult(
|
|
950
|
+
state,
|
|
951
|
+
createDeniedToolCallResult(
|
|
952
|
+
plan,
|
|
953
|
+
formatApprovalDeniedReason(
|
|
954
|
+
plan.toolCall.toolName,
|
|
955
|
+
decision.feedback
|
|
956
|
+
),
|
|
957
|
+
now(),
|
|
958
|
+
decision.feedback
|
|
959
|
+
),
|
|
960
|
+
now()
|
|
961
|
+
);
|
|
962
|
+
if (!context.isReplaying?.()) {
|
|
963
|
+
await bridge?.notifyCheckpoint("tool-result", state);
|
|
964
|
+
}
|
|
965
|
+
break;
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
let handledToolCall = false;
|
|
970
|
+
for (const handler of options.workflowToolHandlers ?? []) {
|
|
971
|
+
const handled = yield* handler({
|
|
972
|
+
context,
|
|
973
|
+
plan,
|
|
974
|
+
now: now(),
|
|
975
|
+
isReplaying: context.isReplaying?.() ?? false
|
|
976
|
+
});
|
|
977
|
+
if (!handled) {
|
|
978
|
+
continue;
|
|
979
|
+
}
|
|
980
|
+
state = applyAgentWorkflowToolCallResult(state, handled, now());
|
|
981
|
+
if (!context.isReplaying?.()) {
|
|
982
|
+
await bridge?.notifyCheckpoint("tool-result", state);
|
|
983
|
+
}
|
|
984
|
+
handledToolCall = true;
|
|
985
|
+
break;
|
|
986
|
+
}
|
|
987
|
+
if (handledToolCall) {
|
|
988
|
+
break;
|
|
989
|
+
}
|
|
990
|
+
const result = yield context.callActivity(activityNames.toolCall, {
|
|
991
|
+
...plan,
|
|
992
|
+
...decisionState.decision ? { replayDecision: decisionState.decision } : {}
|
|
993
|
+
});
|
|
994
|
+
state = applyAgentWorkflowToolCallResult(state, result, now());
|
|
995
|
+
if (!context.isReplaying?.()) {
|
|
996
|
+
await bridge?.notifyCheckpoint("tool-result", state);
|
|
997
|
+
}
|
|
998
|
+
break;
|
|
999
|
+
}
|
|
1000
|
+
case "tool-batch": {
|
|
1001
|
+
const clearedToolCalls = [];
|
|
1002
|
+
for (const toolCall of plan.toolCalls) {
|
|
1003
|
+
const singlePlan = {
|
|
1004
|
+
kind: "tool-call",
|
|
1005
|
+
step: plan.step,
|
|
1006
|
+
sessionId: plan.sessionId,
|
|
1007
|
+
toolCall,
|
|
1008
|
+
turnState: plan.turnState,
|
|
1009
|
+
replayDecision: plan.replayDecisions[toolCall.toolCallId]
|
|
1010
|
+
};
|
|
1011
|
+
let gateHandled = false;
|
|
1012
|
+
if (activityNames.humanInputCheck && options.humanInputCheck) {
|
|
1013
|
+
const humanInput = yield context.callActivity(
|
|
1014
|
+
activityNames.humanInputCheck,
|
|
1015
|
+
{
|
|
1016
|
+
workflowInstanceId: context.getWorkflowInstanceId?.() ?? "",
|
|
1017
|
+
sessionId: singlePlan.sessionId,
|
|
1018
|
+
step: singlePlan.step,
|
|
1019
|
+
toolCall: structuredClone(singlePlan.toolCall)
|
|
1020
|
+
}
|
|
1021
|
+
);
|
|
1022
|
+
if (humanInput.action === "deny") {
|
|
1023
|
+
state = applyAgentWorkflowToolCallResult(
|
|
1024
|
+
state,
|
|
1025
|
+
createDeniedToolCallResult(
|
|
1026
|
+
singlePlan,
|
|
1027
|
+
humanInput.reason,
|
|
1028
|
+
now()
|
|
1029
|
+
),
|
|
1030
|
+
now()
|
|
1031
|
+
);
|
|
1032
|
+
gateHandled = true;
|
|
1033
|
+
}
|
|
1034
|
+
if (!gateHandled && humanInput.action === "request") {
|
|
1035
|
+
if (!context.waitForExternalEvent) {
|
|
1036
|
+
throw new Error(
|
|
1037
|
+
"Workflow context does not support waitForExternalEvent for human input requests"
|
|
1038
|
+
);
|
|
1039
|
+
}
|
|
1040
|
+
context.setCustomStatus?.(
|
|
1041
|
+
JSON.stringify({
|
|
1042
|
+
sessionId: state.sessionId,
|
|
1043
|
+
phase: "waiting-input",
|
|
1044
|
+
step: state.step,
|
|
1045
|
+
toolCallId: singlePlan.toolCall.toolCallId,
|
|
1046
|
+
request: humanInput.request
|
|
1047
|
+
})
|
|
1048
|
+
);
|
|
1049
|
+
const eventPayload = yield* waitForExternalEventWithTimeout(
|
|
1050
|
+
context,
|
|
1051
|
+
humanInput.eventName,
|
|
1052
|
+
options.humanInputTimeoutMs
|
|
1053
|
+
);
|
|
1054
|
+
if (eventPayload === EXTERNAL_EVENT_TIMEOUT) {
|
|
1055
|
+
state = applyAgentWorkflowToolCallResult(
|
|
1056
|
+
state,
|
|
1057
|
+
createDeniedToolCallResult(
|
|
1058
|
+
singlePlan,
|
|
1059
|
+
`Human input request timed out after ${options.humanInputTimeoutMs}ms`,
|
|
1060
|
+
now()
|
|
1061
|
+
),
|
|
1062
|
+
now()
|
|
1063
|
+
);
|
|
1064
|
+
} else {
|
|
1065
|
+
const response = extractHumanInputResponse(eventPayload);
|
|
1066
|
+
state = applyAgentWorkflowToolCallResult(
|
|
1067
|
+
state,
|
|
1068
|
+
createHumanInputToolCallResult(
|
|
1069
|
+
singlePlan,
|
|
1070
|
+
response,
|
|
1071
|
+
now()
|
|
1072
|
+
),
|
|
1073
|
+
now()
|
|
1074
|
+
);
|
|
1075
|
+
}
|
|
1076
|
+
gateHandled = true;
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
if (!gateHandled && activityNames.approvalCheck && options.approvalCheck) {
|
|
1080
|
+
const approval = yield context.callActivity(
|
|
1081
|
+
activityNames.approvalCheck,
|
|
1082
|
+
{
|
|
1083
|
+
workflowInstanceId: context.getWorkflowInstanceId?.() ?? "",
|
|
1084
|
+
sessionId: singlePlan.sessionId,
|
|
1085
|
+
step: singlePlan.step,
|
|
1086
|
+
toolCall: structuredClone(singlePlan.toolCall)
|
|
1087
|
+
}
|
|
1088
|
+
);
|
|
1089
|
+
if (approval.action === "deny") {
|
|
1090
|
+
state = applyAgentWorkflowToolCallResult(
|
|
1091
|
+
state,
|
|
1092
|
+
createDeniedToolCallResult(
|
|
1093
|
+
singlePlan,
|
|
1094
|
+
approval.reason,
|
|
1095
|
+
now()
|
|
1096
|
+
),
|
|
1097
|
+
now()
|
|
1098
|
+
);
|
|
1099
|
+
gateHandled = true;
|
|
1100
|
+
}
|
|
1101
|
+
if (!gateHandled && approval.action === "request") {
|
|
1102
|
+
if (!context.waitForExternalEvent) {
|
|
1103
|
+
throw new Error(
|
|
1104
|
+
"Workflow context does not support waitForExternalEvent for approval requests"
|
|
1105
|
+
);
|
|
1106
|
+
}
|
|
1107
|
+
context.setCustomStatus?.(
|
|
1108
|
+
JSON.stringify({
|
|
1109
|
+
sessionId: state.sessionId,
|
|
1110
|
+
phase: "waiting-approval",
|
|
1111
|
+
step: state.step,
|
|
1112
|
+
toolCallId: singlePlan.toolCall.toolCallId,
|
|
1113
|
+
request: approval.request
|
|
1114
|
+
})
|
|
1115
|
+
);
|
|
1116
|
+
const eventPayload = yield* waitForExternalEventWithTimeout(
|
|
1117
|
+
context,
|
|
1118
|
+
approval.eventName,
|
|
1119
|
+
options.approvalTimeoutMs
|
|
1120
|
+
);
|
|
1121
|
+
if (eventPayload === EXTERNAL_EVENT_TIMEOUT) {
|
|
1122
|
+
state = applyAgentWorkflowToolCallResult(
|
|
1123
|
+
state,
|
|
1124
|
+
createDeniedToolCallResult(
|
|
1125
|
+
singlePlan,
|
|
1126
|
+
`Approval request timed out after ${options.approvalTimeoutMs}ms`,
|
|
1127
|
+
now()
|
|
1128
|
+
),
|
|
1129
|
+
now()
|
|
1130
|
+
);
|
|
1131
|
+
gateHandled = true;
|
|
1132
|
+
} else {
|
|
1133
|
+
const decision = extractApprovalDecision(eventPayload);
|
|
1134
|
+
if (decision.action === "deny") {
|
|
1135
|
+
state = applyAgentWorkflowToolCallResult(
|
|
1136
|
+
state,
|
|
1137
|
+
createDeniedToolCallResult(
|
|
1138
|
+
singlePlan,
|
|
1139
|
+
formatApprovalDeniedReason(
|
|
1140
|
+
singlePlan.toolCall.toolName,
|
|
1141
|
+
decision.feedback
|
|
1142
|
+
),
|
|
1143
|
+
now(),
|
|
1144
|
+
decision.feedback
|
|
1145
|
+
),
|
|
1146
|
+
now()
|
|
1147
|
+
);
|
|
1148
|
+
gateHandled = true;
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
if (!gateHandled) {
|
|
1154
|
+
clearedToolCalls.push({
|
|
1155
|
+
toolCall,
|
|
1156
|
+
replayDecision: plan.replayDecisions[toolCall.toolCallId]
|
|
1157
|
+
});
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
if (clearedToolCalls.length > 0) {
|
|
1161
|
+
if (context.whenAll && clearedToolCalls.length > 1) {
|
|
1162
|
+
const tasks = clearedToolCalls.map(
|
|
1163
|
+
({ toolCall, replayDecision }) => context.callActivity(activityNames.toolCall, {
|
|
1164
|
+
kind: "tool-call",
|
|
1165
|
+
step: plan.step,
|
|
1166
|
+
sessionId: plan.sessionId,
|
|
1167
|
+
toolCall,
|
|
1168
|
+
turnState: plan.turnState,
|
|
1169
|
+
...replayDecision ? { replayDecision } : {}
|
|
1170
|
+
})
|
|
1171
|
+
);
|
|
1172
|
+
const results = yield context.whenAll(
|
|
1173
|
+
tasks
|
|
1174
|
+
);
|
|
1175
|
+
for (const result of results) {
|
|
1176
|
+
state = applyAgentWorkflowToolCallResult(
|
|
1177
|
+
state,
|
|
1178
|
+
result,
|
|
1179
|
+
now()
|
|
1180
|
+
);
|
|
1181
|
+
}
|
|
1182
|
+
} else {
|
|
1183
|
+
for (const { toolCall, replayDecision } of clearedToolCalls) {
|
|
1184
|
+
const result = yield context.callActivity(
|
|
1185
|
+
activityNames.toolCall,
|
|
1186
|
+
{
|
|
1187
|
+
kind: "tool-call",
|
|
1188
|
+
step: plan.step,
|
|
1189
|
+
sessionId: plan.sessionId,
|
|
1190
|
+
toolCall,
|
|
1191
|
+
turnState: plan.turnState,
|
|
1192
|
+
...replayDecision ? { replayDecision } : {}
|
|
1193
|
+
}
|
|
1194
|
+
);
|
|
1195
|
+
state = applyAgentWorkflowToolCallResult(
|
|
1196
|
+
state,
|
|
1197
|
+
result,
|
|
1198
|
+
now()
|
|
1199
|
+
);
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
if (!context.isReplaying?.()) {
|
|
1204
|
+
await bridge?.notifyCheckpoint("tool-result", state);
|
|
1205
|
+
}
|
|
1206
|
+
break;
|
|
1207
|
+
}
|
|
1208
|
+
case "step-commit": {
|
|
1209
|
+
const result = yield context.callActivity(
|
|
1210
|
+
activityNames.stepCommit,
|
|
1211
|
+
plan
|
|
1212
|
+
);
|
|
1213
|
+
state = applyAgentWorkflowCommitResult(state, result, now());
|
|
1214
|
+
if (!context.isReplaying?.()) {
|
|
1215
|
+
await bridge?.notifyCheckpoint("step-commit-finish", state);
|
|
1216
|
+
}
|
|
1217
|
+
if (continueAsNewThreshold && state.step > 0 && state.step % continueAsNewThreshold === 0 && context.continueAsNew) {
|
|
1218
|
+
context.continueAsNew(
|
|
1219
|
+
state,
|
|
1220
|
+
/* preserveUnprocessedEvents */
|
|
1221
|
+
true
|
|
1222
|
+
);
|
|
1223
|
+
}
|
|
1224
|
+
break;
|
|
1225
|
+
}
|
|
1226
|
+
case "output-commit": {
|
|
1227
|
+
const result = yield context.callActivity(
|
|
1228
|
+
activityNames.outputCommit,
|
|
1229
|
+
plan
|
|
1230
|
+
);
|
|
1231
|
+
state = applyAgentWorkflowCommitResult(state, result, now());
|
|
1232
|
+
if (!context.isReplaying?.()) {
|
|
1233
|
+
await bridge?.notifyCheckpoint("output-commit-finish", state);
|
|
1234
|
+
}
|
|
1235
|
+
break;
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
} catch (error) {
|
|
1240
|
+
const normalized = normalizeError2(error);
|
|
1241
|
+
state = failAgentWorkflowTurnState(state, normalized, now());
|
|
1242
|
+
context.setCustomStatus?.(summarizeWorkflowState(state));
|
|
1243
|
+
if (!context.isReplaying?.()) {
|
|
1244
|
+
await bridge?.notifyTaskError(state, normalized);
|
|
1245
|
+
}
|
|
1246
|
+
throw normalized;
|
|
1247
|
+
}
|
|
1248
|
+
};
|
|
1249
|
+
return {
|
|
1250
|
+
workflowName,
|
|
1251
|
+
activityNames,
|
|
1252
|
+
workflow
|
|
1253
|
+
};
|
|
1254
|
+
}
|
|
1255
|
+
function createDaprAgentTurnWorkflowKit(options) {
|
|
1256
|
+
const getBridge = () => options.observerBridge;
|
|
1257
|
+
const steerDrainActivity = options.steerDrainActivity ? createDaprAgentTurnSteerDrainActivity(options.steerDrainActivity) : void 0;
|
|
1258
|
+
const humanInputCheckActivity = options.humanInputCheckActivity ? createDaprAgentTurnHumanInputCheckActivity(
|
|
1259
|
+
options.humanInputCheckActivity
|
|
1260
|
+
) : void 0;
|
|
1261
|
+
const approvalCheckActivity = options.approvalCheckActivity ? createDaprAgentTurnApprovalCheckActivity(options.approvalCheckActivity) : void 0;
|
|
1262
|
+
const modelStepActivity = createDaprAgentTurnModelStepActivity({
|
|
1263
|
+
...options.modelStepActivity,
|
|
1264
|
+
get observerBridge() {
|
|
1265
|
+
return getBridge();
|
|
1266
|
+
}
|
|
1267
|
+
});
|
|
1268
|
+
const toolCallActivity = createDaprAgentTurnToolCallActivity({
|
|
1269
|
+
...options.toolCallActivity,
|
|
1270
|
+
get observerBridge() {
|
|
1271
|
+
return getBridge();
|
|
1272
|
+
}
|
|
1273
|
+
});
|
|
1274
|
+
const stepCommitActivity = createDaprAgentTurnStepCommitActivity(
|
|
1275
|
+
options.commitActivity
|
|
1276
|
+
);
|
|
1277
|
+
const outputCommitActivity = createDaprAgentTurnOutputCommitActivity(
|
|
1278
|
+
options.commitActivity
|
|
1279
|
+
);
|
|
1280
|
+
const registration = createDaprAgentTurnWorkflowDefinition({
|
|
1281
|
+
workflowName: options.workflowName,
|
|
1282
|
+
activityNames: options.activityNames,
|
|
1283
|
+
steeringEnabled: options.steeringEnabled,
|
|
1284
|
+
now: options.now,
|
|
1285
|
+
get observerBridge() {
|
|
1286
|
+
return getBridge();
|
|
1287
|
+
},
|
|
1288
|
+
onEvent: options.onEvent,
|
|
1289
|
+
...steerDrainActivity ? {
|
|
1290
|
+
steerDrain: (input) => steerDrainActivity.handler(void 0, input)
|
|
1291
|
+
} : {},
|
|
1292
|
+
modelStep: (input) => modelStepActivity.handler(void 0, input),
|
|
1293
|
+
...humanInputCheckActivity ? {
|
|
1294
|
+
humanInputCheck: (input) => humanInputCheckActivity.handler(void 0, input)
|
|
1295
|
+
} : {},
|
|
1296
|
+
...approvalCheckActivity ? {
|
|
1297
|
+
approvalCheck: (input) => approvalCheckActivity.handler(void 0, input)
|
|
1298
|
+
} : {},
|
|
1299
|
+
toolCall: (input) => toolCallActivity.handler(void 0, input),
|
|
1300
|
+
stepCommit: (input) => stepCommitActivity.handler(void 0, input),
|
|
1301
|
+
outputCommit: (input) => outputCommitActivity.handler(void 0, input),
|
|
1302
|
+
workflowToolHandlers: options.workflowToolHandlers
|
|
1303
|
+
});
|
|
1304
|
+
return {
|
|
1305
|
+
...registration,
|
|
1306
|
+
activities: {
|
|
1307
|
+
...steerDrainActivity && registration.activityNames.steerDrain ? {
|
|
1308
|
+
steerDrain: renameActivity(
|
|
1309
|
+
steerDrainActivity,
|
|
1310
|
+
registration.activityNames.steerDrain
|
|
1311
|
+
)
|
|
1312
|
+
} : {},
|
|
1313
|
+
modelStep: renameActivity(
|
|
1314
|
+
modelStepActivity,
|
|
1315
|
+
registration.activityNames.modelStep
|
|
1316
|
+
),
|
|
1317
|
+
...humanInputCheckActivity && registration.activityNames.humanInputCheck ? {
|
|
1318
|
+
humanInputCheck: renameActivity(
|
|
1319
|
+
humanInputCheckActivity,
|
|
1320
|
+
registration.activityNames.humanInputCheck
|
|
1321
|
+
)
|
|
1322
|
+
} : {},
|
|
1323
|
+
...approvalCheckActivity && registration.activityNames.approvalCheck ? {
|
|
1324
|
+
approvalCheck: renameActivity(
|
|
1325
|
+
approvalCheckActivity,
|
|
1326
|
+
registration.activityNames.approvalCheck
|
|
1327
|
+
)
|
|
1328
|
+
} : {},
|
|
1329
|
+
toolCall: renameActivity(
|
|
1330
|
+
toolCallActivity,
|
|
1331
|
+
registration.activityNames.toolCall
|
|
1332
|
+
),
|
|
1333
|
+
stepCommit: renameActivity(
|
|
1334
|
+
stepCommitActivity,
|
|
1335
|
+
registration.activityNames.stepCommit
|
|
1336
|
+
),
|
|
1337
|
+
outputCommit: renameActivity(
|
|
1338
|
+
outputCommitActivity,
|
|
1339
|
+
registration.activityNames.outputCommit
|
|
1340
|
+
)
|
|
1341
|
+
}
|
|
1342
|
+
};
|
|
1343
|
+
}
|
|
1344
|
+
|
|
1345
|
+
export {
|
|
1346
|
+
isTerminalDaprWorkflowStatus,
|
|
1347
|
+
hasStartedDaprWorkflow,
|
|
1348
|
+
DaprWorkflowClient,
|
|
1349
|
+
createDaprAgentTurnSteerDrainActivity,
|
|
1350
|
+
createDaprAgentTurnModelStepActivity,
|
|
1351
|
+
createDaprAgentTurnToolCallActivity,
|
|
1352
|
+
createDaprAgentTurnApprovalCheckActivity,
|
|
1353
|
+
createDaprAgentTurnHumanInputCheckActivity,
|
|
1354
|
+
createDaprAgentTurnStepCommitActivity,
|
|
1355
|
+
createDaprAgentTurnOutputCommitActivity,
|
|
1356
|
+
createDaprAgentTurnWorkflowDefinition,
|
|
1357
|
+
createDaprAgentTurnWorkflowKit
|
|
1358
|
+
};
|