@ekairos/events 1.22.49-beta.development.0 → 1.22.51-beta.development.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/dist/context.engine.d.ts +5 -0
- package/dist/context.engine.js +102 -34
- package/dist/schema.d.ts +3 -3
- package/dist/steps/durable.steps.d.ts +28 -0
- package/dist/steps/durable.steps.js +34 -0
- package/package.json +2 -2
package/dist/context.engine.d.ts
CHANGED
|
@@ -93,6 +93,7 @@ export type ContextReactParams<Env extends ContextEnvironment = ContextEnvironme
|
|
|
93
93
|
trigger: ContextItem;
|
|
94
94
|
reaction: ContextItem;
|
|
95
95
|
execution: ContextExecution;
|
|
96
|
+
returnValueHookToken?: string | null;
|
|
96
97
|
};
|
|
97
98
|
__benchmark?: ContextBenchmarkRecorder;
|
|
98
99
|
};
|
|
@@ -114,6 +115,10 @@ export type ContextWorkflowRun<Context = any> = {
|
|
|
114
115
|
runId: string;
|
|
115
116
|
status: Promise<"pending" | "running" | "completed" | "failed" | "cancelled">;
|
|
116
117
|
returnValue: Promise<ContextReactFinalResult<Context>>;
|
|
118
|
+
returnValueHook?: {
|
|
119
|
+
token: string;
|
|
120
|
+
parentWorkflowRunId: string;
|
|
121
|
+
} | null;
|
|
117
122
|
};
|
|
118
123
|
export type ContextReactRun<Context = any> = ContextWorkflowRun<Context> | ContextDirectRun<Context>;
|
|
119
124
|
export type ContextReactResult<Context = any, Run extends ContextReactRun<Context> = ContextReactRun<Context>> = ContextReactBase<Context> & {
|
package/dist/context.engine.js
CHANGED
|
@@ -4,7 +4,8 @@ import { applyToolExecutionResultToParts } from "./context.toolcalls.js";
|
|
|
4
4
|
import { isContextPartEnvelope, normalizePartsForPersistence, } from "./context.parts.js";
|
|
5
5
|
import { createAiSdkReactor, } from "./context.reactor.js";
|
|
6
6
|
import { abortPersistedContextStepStream, closeContextStream, createPersistedContextStepStreamForRuntime, finalizePersistedContextStepStreamForRuntime, writeActionResultPartChunks, } from "./steps/stream.steps.js";
|
|
7
|
-
import { completeExecution, createContextStep, finalizeReactionStep, getContextItems, initializeContext, openReactionStep, saveTriggerAndCreateExecution, saveContextPartsAndUpdateReaction, saveContextPartsStep, updateContextContent, updateContextReactor, updateContextStatus, updateItem, updateContextStep, } from "./steps/store.steps.js";
|
|
7
|
+
import { completeExecution, createContextStep, finalizeReactionStep, getContextItems, initializeContext, openReactionStep, saveTriggerAndCreateExecution, saveContextPartsAndUpdateReaction, saveContextPartsStep, updateContextContent, updateContextReactor, updateContextStatus, updateItem, updateContextStep, updateExecutionWorkflowRun, } from "./steps/store.steps.js";
|
|
8
|
+
import { readContextDurableWorkflowReturnValue, readContextDurableWorkflowStatus, resumeContextReturnValueHook, startContextDurableWorkflow, } from "./steps/durable.steps.js";
|
|
8
9
|
import { getClientResumeHookUrl, toolApprovalHookToken, toolApprovalWebhookToken, } from "./context.hooks.js";
|
|
9
10
|
import { getContextDurableWorkflow } from "./context.durable.js";
|
|
10
11
|
export async function runContextReactionDirect(context, triggerEvent, params) {
|
|
@@ -101,6 +102,30 @@ async function readActiveWorkflowRunId() {
|
|
|
101
102
|
return null;
|
|
102
103
|
}
|
|
103
104
|
}
|
|
105
|
+
function serializeContextReturnValueError(error) {
|
|
106
|
+
if (error instanceof Error) {
|
|
107
|
+
return {
|
|
108
|
+
name: error.name,
|
|
109
|
+
message: error.message,
|
|
110
|
+
stack: error.stack,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
message: String(error),
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
function unwrapContextReturnValueHookPayload(payload) {
|
|
118
|
+
if (payload.ok)
|
|
119
|
+
return payload.result;
|
|
120
|
+
const error = new Error(payload.error.message);
|
|
121
|
+
if (payload.error.name) {
|
|
122
|
+
error.name = payload.error.name;
|
|
123
|
+
}
|
|
124
|
+
if (payload.error.stack) {
|
|
125
|
+
error.stack = payload.error.stack;
|
|
126
|
+
}
|
|
127
|
+
throw error;
|
|
128
|
+
}
|
|
104
129
|
async function createRuntimeOps(runtimeHandle, benchmark) {
|
|
105
130
|
const runtime = await getContextRuntimeServices(runtimeHandle);
|
|
106
131
|
const { db } = runtime;
|
|
@@ -461,47 +486,73 @@ export class ContextEngine {
|
|
|
461
486
|
}
|
|
462
487
|
const workflow = getContextDurableWorkflow();
|
|
463
488
|
if (typeof workflow !== "function") {
|
|
464
|
-
|
|
489
|
+
const contextKeyLabel = contextKey || "(missing)";
|
|
490
|
+
throw new Error([
|
|
491
|
+
"ContextEngine.react(..., { durable: true }) needs a registered durable context workflow.",
|
|
492
|
+
"Call configureContextDurableWorkflow(contextDurableWorkflow) during server/workflow bootstrap.",
|
|
493
|
+
"If you want inline execution inside the current workflow step, pass durable: false.",
|
|
494
|
+
`Context key: ${contextKeyLabel}.`,
|
|
495
|
+
].join(" "));
|
|
465
496
|
}
|
|
466
497
|
const shell = await ContextEngine.prepareExecutionShell(story, triggerEvent, params);
|
|
467
498
|
let run;
|
|
468
499
|
try {
|
|
469
|
-
const
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
{
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
options: {
|
|
479
|
-
maxIterations: params.options?.maxIterations,
|
|
480
|
-
maxModelSteps: params.options?.maxModelSteps,
|
|
481
|
-
preventClose: params.options?.preventClose,
|
|
482
|
-
sendFinish: params.options?.sendFinish,
|
|
483
|
-
silent: params.options?.silent,
|
|
484
|
-
},
|
|
485
|
-
bootstrap: {
|
|
500
|
+
const parentWorkflowRunId = await readActiveWorkflowRunId();
|
|
501
|
+
let returnValueHook = null;
|
|
502
|
+
let returnValueHookPromise = null;
|
|
503
|
+
if (parentWorkflowRunId) {
|
|
504
|
+
const { createHook } = await import("workflow");
|
|
505
|
+
const hook = createHook({
|
|
506
|
+
token: `context:return:${shell.execution.id}`,
|
|
507
|
+
metadata: {
|
|
508
|
+
kind: "context.returnValue",
|
|
486
509
|
contextId: shell.currentContext.id,
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
execution: shell.execution,
|
|
510
|
+
executionId: shell.execution.id,
|
|
511
|
+
parentWorkflowRunId,
|
|
490
512
|
},
|
|
513
|
+
});
|
|
514
|
+
returnValueHook = {
|
|
515
|
+
token: hook.token,
|
|
516
|
+
parentWorkflowRunId,
|
|
517
|
+
};
|
|
518
|
+
returnValueHookPromise = Promise.resolve(hook);
|
|
519
|
+
}
|
|
520
|
+
const payload = {
|
|
521
|
+
contextKey,
|
|
522
|
+
runtime: runtimeHandle,
|
|
523
|
+
context: params.context ?? null,
|
|
524
|
+
triggerEvent,
|
|
525
|
+
options: {
|
|
526
|
+
maxIterations: params.options?.maxIterations,
|
|
527
|
+
maxModelSteps: params.options?.maxModelSteps,
|
|
528
|
+
preventClose: params.options?.preventClose,
|
|
529
|
+
sendFinish: params.options?.sendFinish,
|
|
530
|
+
silent: params.options?.silent,
|
|
531
|
+
},
|
|
532
|
+
bootstrap: {
|
|
533
|
+
contextId: shell.currentContext.id,
|
|
534
|
+
trigger: shell.trigger,
|
|
535
|
+
reaction: shell.reaction,
|
|
536
|
+
execution: shell.execution,
|
|
537
|
+
returnValueHookToken: returnValueHook?.token ?? null,
|
|
491
538
|
},
|
|
492
|
-
|
|
539
|
+
};
|
|
540
|
+
const startedRun = await measureBenchmark(params.__benchmark, "react.durable.startWorkflowMs", async () => await startContextDurableWorkflow({ payload }));
|
|
493
541
|
run = {
|
|
494
542
|
runId: String(startedRun.runId),
|
|
495
|
-
status: startedRun.
|
|
496
|
-
returnValue:
|
|
543
|
+
status: readContextDurableWorkflowStatus({ runId: String(startedRun.runId) }),
|
|
544
|
+
returnValue: returnValueHookPromise
|
|
545
|
+
? returnValueHookPromise.then(unwrapContextReturnValueHookPayload)
|
|
546
|
+
: readContextDurableWorkflowReturnValue({
|
|
547
|
+
runId: String(startedRun.runId),
|
|
548
|
+
}),
|
|
549
|
+
returnValueHook,
|
|
497
550
|
};
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
}),
|
|
504
|
-
]));
|
|
551
|
+
await measureBenchmark(params.__benchmark, "react.durable.persistWorkflowRunIdMs", async () => await updateExecutionWorkflowRun({
|
|
552
|
+
runtime: runtimeHandle,
|
|
553
|
+
executionId: shell.execution.id,
|
|
554
|
+
workflowRunId: String(startedRun.runId),
|
|
555
|
+
}));
|
|
505
556
|
}
|
|
506
557
|
catch (error) {
|
|
507
558
|
const ops = await getContextEngineOps(runtimeHandle, params.__benchmark);
|
|
@@ -547,6 +598,15 @@ export class ContextEngine {
|
|
|
547
598
|
const silent = params.options?.silent ?? false;
|
|
548
599
|
const writable = params.options?.writable;
|
|
549
600
|
const bootstrapped = params.__bootstrap;
|
|
601
|
+
const returnValueHookToken = bootstrapped?.returnValueHookToken ?? null;
|
|
602
|
+
const resumeReturnValueHook = async (payload) => {
|
|
603
|
+
if (!returnValueHookToken)
|
|
604
|
+
return;
|
|
605
|
+
await resumeContextReturnValueHook({
|
|
606
|
+
token: returnValueHookToken,
|
|
607
|
+
payload,
|
|
608
|
+
});
|
|
609
|
+
};
|
|
550
610
|
const shell = bootstrapped
|
|
551
611
|
? {
|
|
552
612
|
contextSelector: { id: String(bootstrapped.contextId) },
|
|
@@ -880,12 +940,14 @@ export class ContextEngine {
|
|
|
880
940
|
if (!silent) {
|
|
881
941
|
await closeContextStream({ preventClose, sendFinish, writable });
|
|
882
942
|
}
|
|
883
|
-
|
|
943
|
+
const result = {
|
|
884
944
|
context: updatedContext,
|
|
885
945
|
trigger,
|
|
886
946
|
reaction: reactionEvent,
|
|
887
947
|
execution,
|
|
888
948
|
};
|
|
949
|
+
await resumeReturnValueHook({ ok: true, result });
|
|
950
|
+
return result;
|
|
889
951
|
}
|
|
890
952
|
}
|
|
891
953
|
// Execute actions (workflow context; action implementations decide step vs workflow)
|
|
@@ -1115,12 +1177,14 @@ export class ContextEngine {
|
|
|
1115
1177
|
if (!silent) {
|
|
1116
1178
|
await closeContextStream({ preventClose, sendFinish, writable });
|
|
1117
1179
|
}
|
|
1118
|
-
|
|
1180
|
+
const result = {
|
|
1119
1181
|
context: updatedContext,
|
|
1120
1182
|
trigger,
|
|
1121
1183
|
reaction: reactionEvent,
|
|
1122
1184
|
execution,
|
|
1123
1185
|
};
|
|
1186
|
+
await resumeReturnValueHook({ ok: true, result });
|
|
1187
|
+
return result;
|
|
1124
1188
|
}
|
|
1125
1189
|
}
|
|
1126
1190
|
throw new Error(`ContextEngine: maxIterations reached (${maxIterations}) without completion`);
|
|
@@ -1174,6 +1238,10 @@ export class ContextEngine {
|
|
|
1174
1238
|
}
|
|
1175
1239
|
}
|
|
1176
1240
|
await failExecution();
|
|
1241
|
+
await resumeReturnValueHook({
|
|
1242
|
+
ok: false,
|
|
1243
|
+
error: serializeContextReturnValueError(error),
|
|
1244
|
+
}).catch(() => null);
|
|
1177
1245
|
throw error;
|
|
1178
1246
|
}
|
|
1179
1247
|
}
|
package/dist/schema.d.ts
CHANGED
|
@@ -221,7 +221,7 @@ export declare const eventsDomain: import("@ekairos/domain").DomainSchemaResult<
|
|
|
221
221
|
readonly label: "stream";
|
|
222
222
|
};
|
|
223
223
|
readonly reverse: {
|
|
224
|
-
readonly on:
|
|
224
|
+
readonly on: "$streams";
|
|
225
225
|
readonly has: "many";
|
|
226
226
|
readonly label: "step";
|
|
227
227
|
};
|
|
@@ -233,7 +233,7 @@ export declare const eventsDomain: import("@ekairos/domain").DomainSchemaResult<
|
|
|
233
233
|
readonly label: "activeStream";
|
|
234
234
|
};
|
|
235
235
|
readonly reverse: {
|
|
236
|
-
readonly on:
|
|
236
|
+
readonly on: "$streams";
|
|
237
237
|
readonly has: "many";
|
|
238
238
|
readonly label: "activeOf";
|
|
239
239
|
};
|
|
@@ -245,7 +245,7 @@ export declare const eventsDomain: import("@ekairos/domain").DomainSchemaResult<
|
|
|
245
245
|
readonly label: "lastStream";
|
|
246
246
|
};
|
|
247
247
|
readonly reverse: {
|
|
248
|
-
readonly on:
|
|
248
|
+
readonly on: "$streams";
|
|
249
249
|
readonly has: "many";
|
|
250
250
|
readonly label: "lastOf";
|
|
251
251
|
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ContextDurableWorkflowPayload, ContextReactFinalResult } from "../context.engine.js";
|
|
2
|
+
export type ContextDurableWorkflowStatus = "pending" | "running" | "completed" | "failed" | "cancelled";
|
|
3
|
+
export type ContextReturnValueHookPayload<Context = any> = {
|
|
4
|
+
ok: true;
|
|
5
|
+
result: ContextReactFinalResult<Context>;
|
|
6
|
+
} | {
|
|
7
|
+
ok: false;
|
|
8
|
+
error: {
|
|
9
|
+
name?: string;
|
|
10
|
+
message: string;
|
|
11
|
+
stack?: string;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
export declare function startContextDurableWorkflow(params: {
|
|
15
|
+
payload: ContextDurableWorkflowPayload<any, any, any>;
|
|
16
|
+
}): Promise<{
|
|
17
|
+
runId: string;
|
|
18
|
+
}>;
|
|
19
|
+
export declare function readContextDurableWorkflowStatus(params: {
|
|
20
|
+
runId: string;
|
|
21
|
+
}): Promise<ContextDurableWorkflowStatus>;
|
|
22
|
+
export declare function readContextDurableWorkflowReturnValue(params: {
|
|
23
|
+
runId: string;
|
|
24
|
+
}): Promise<ContextReactFinalResult<any>>;
|
|
25
|
+
export declare function resumeContextReturnValueHook(params: {
|
|
26
|
+
token: string;
|
|
27
|
+
payload: ContextReturnValueHookPayload;
|
|
28
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { getContextDurableWorkflow } from "../context.durable.js";
|
|
2
|
+
export async function startContextDurableWorkflow(params) {
|
|
3
|
+
"use step";
|
|
4
|
+
const workflow = getContextDurableWorkflow();
|
|
5
|
+
if (typeof workflow !== "function") {
|
|
6
|
+
const contextKey = String(params.payload.contextKey || "(missing)");
|
|
7
|
+
throw new Error([
|
|
8
|
+
"ContextEngine.react(..., { durable: true }) needs a registered durable context workflow.",
|
|
9
|
+
"Call configureContextDurableWorkflow(contextDurableWorkflow) during server/workflow bootstrap.",
|
|
10
|
+
"If you want inline execution inside the current workflow step, pass durable: false.",
|
|
11
|
+
`Context key: ${contextKey}.`,
|
|
12
|
+
].join(" "));
|
|
13
|
+
}
|
|
14
|
+
const { start } = await import("workflow/api");
|
|
15
|
+
const run = await start(workflow, [params.payload]);
|
|
16
|
+
return { runId: String(run.runId) };
|
|
17
|
+
}
|
|
18
|
+
export async function readContextDurableWorkflowStatus(params) {
|
|
19
|
+
"use step";
|
|
20
|
+
const { getRun } = await import("workflow/api");
|
|
21
|
+
const run = getRun(params.runId);
|
|
22
|
+
return (await run.status);
|
|
23
|
+
}
|
|
24
|
+
export async function readContextDurableWorkflowReturnValue(params) {
|
|
25
|
+
"use step";
|
|
26
|
+
const { getRun } = await import("workflow/api");
|
|
27
|
+
const run = getRun(params.runId);
|
|
28
|
+
return (await run.returnValue);
|
|
29
|
+
}
|
|
30
|
+
export async function resumeContextReturnValueHook(params) {
|
|
31
|
+
"use step";
|
|
32
|
+
const { resumeHook } = await import("workflow/api");
|
|
33
|
+
await resumeHook(params.token, params.payload);
|
|
34
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ekairos/events",
|
|
3
|
-
"version": "1.22.
|
|
3
|
+
"version": "1.22.51-beta.development.0",
|
|
4
4
|
"description": "Ekairos Events - Context-first workflow runtime",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -127,7 +127,7 @@
|
|
|
127
127
|
},
|
|
128
128
|
"dependencies": {
|
|
129
129
|
"@ai-sdk/openai": "^2.0.52",
|
|
130
|
-
"@ekairos/domain": "^1.22.
|
|
130
|
+
"@ekairos/domain": "^1.22.51-beta.development.0",
|
|
131
131
|
"@instantdb/admin": "0.22.158",
|
|
132
132
|
"@instantdb/core": "0.22.142",
|
|
133
133
|
"@vercel/mcp-adapter": "^1.0.0",
|