@ekairos/events 1.22.79-beta.development.0 → 1.22.80-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.js +93 -87
- package/dist/steps/store.steps.d.ts +17 -15
- package/dist/steps/store.steps.js +70 -49
- package/dist/steps/stream.steps.d.ts +12 -11
- package/dist/steps/stream.steps.js +1 -2
- package/dist/stores/instant.store.js +44 -5
- package/package.json +2 -2
package/dist/context.engine.js
CHANGED
|
@@ -3,8 +3,8 @@ import { OUTPUT_ITEM_TYPE, WEB_CHANNEL } from "./context.events.js";
|
|
|
3
3
|
import { applyToolExecutionResultToParts } from "./context.toolcalls.js";
|
|
4
4
|
import { isContextPartEnvelope, normalizePartsForPersistence, } from "./context.parts.js";
|
|
5
5
|
import { createAiSdkReactor, } from "./context.reactor.js";
|
|
6
|
-
import { abortPersistedContextStepStream, closeContextStream, createPersistedContextStepStreamForRuntime, finalizePersistedContextStepStreamForRuntime,
|
|
7
|
-
import { completeExecution,
|
|
6
|
+
import { abortPersistedContextStepStream, closeContextStream, createPersistedContextStepStreamForRuntime, finalizePersistedContextStepStreamForRuntime, writeActionResultPartChunksToSession, } from "./steps/stream.steps.js";
|
|
7
|
+
import { completeExecution, completeExecutionStep, createContextStep, getContextItems, initializeContext, openExecutionStep, openExecution, saveExecutionStepOutput, updateContextContent, updateContextReactor, updateContextStatus, updateItem, updateContextStep, updateExecutionWorkflowRun, } from "./steps/store.steps.js";
|
|
8
8
|
import { readContextDurableWorkflowReturnValue, readContextDurableWorkflowStatus, resumeContextReturnValueHook, startContextDurableWorkflow, } from "./steps/durable.steps.js";
|
|
9
9
|
import { getClientResumeHookUrl, toolApprovalHookToken, toolApprovalWebhookToken, } from "./context.hooks.js";
|
|
10
10
|
import { getContextDurableWorkflow } from "./context.durable.js";
|
|
@@ -195,7 +195,7 @@ async function createRuntimeOps(runtimeHandle, benchmark) {
|
|
|
195
195
|
updatedAt: new Date(),
|
|
196
196
|
}),
|
|
197
197
|
]),
|
|
198
|
-
|
|
198
|
+
openExecution: async ({ contextIdentifier, triggerEvent }) => {
|
|
199
199
|
const contextId = requireContextId(contextIdentifier);
|
|
200
200
|
const triggerId = String(triggerEvent.id);
|
|
201
201
|
const reactionId = makeRuntimeId();
|
|
@@ -253,7 +253,7 @@ async function createRuntimeOps(runtimeHandle, benchmark) {
|
|
|
253
253
|
},
|
|
254
254
|
};
|
|
255
255
|
},
|
|
256
|
-
|
|
256
|
+
openExecutionStep: async ({ contextIdentifier, content, executionId, iteration }) => {
|
|
257
257
|
const stepId = makeRuntimeId();
|
|
258
258
|
const now = new Date();
|
|
259
259
|
await instrumentedDb.transact([
|
|
@@ -301,7 +301,17 @@ async function createRuntimeOps(runtimeHandle, benchmark) {
|
|
|
301
301
|
instrumentedDb.tx.event_steps[params.stepId].update(update),
|
|
302
302
|
]);
|
|
303
303
|
},
|
|
304
|
-
|
|
304
|
+
completeExecutionStep: async (params) => {
|
|
305
|
+
const actionResultChunkEvents = await writeActionResultPartChunksToSession({
|
|
306
|
+
session: params.session,
|
|
307
|
+
contextId: String(params.contextId ?? ""),
|
|
308
|
+
executionId: String(params.executionId ?? ""),
|
|
309
|
+
itemId: String(params.reactionEventId ?? ""),
|
|
310
|
+
actionResults: params.actionResults ?? [],
|
|
311
|
+
});
|
|
312
|
+
if (params.parts) {
|
|
313
|
+
await store.saveStepParts({ stepId: params.stepId, parts: params.parts });
|
|
314
|
+
}
|
|
305
315
|
if (params.session) {
|
|
306
316
|
await finalizePersistedContextStepStreamForRuntime({
|
|
307
317
|
runtime: { db: instrumentedDb },
|
|
@@ -310,15 +320,14 @@ async function createRuntimeOps(runtimeHandle, benchmark) {
|
|
|
310
320
|
});
|
|
311
321
|
}
|
|
312
322
|
const update = { updatedAt: new Date() };
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
update.errorText = params.patch.errorText;
|
|
323
|
+
update.status = params.stepStatus ?? "completed";
|
|
324
|
+
if (params.errorText !== undefined)
|
|
325
|
+
update.errorText = params.errorText;
|
|
317
326
|
await instrumentedDb.transact([
|
|
318
327
|
instrumentedDb.tx.event_steps[params.stepId].update(update),
|
|
319
328
|
]);
|
|
320
329
|
if (!params.reactionEventId || !params.reactionEvent) {
|
|
321
|
-
return {};
|
|
330
|
+
return { actionResultChunkEvents };
|
|
322
331
|
}
|
|
323
332
|
await instrumentedDb.transact([
|
|
324
333
|
instrumentedDb.tx.event_items[params.reactionEventId].update(params.reactionEvent),
|
|
@@ -328,12 +337,10 @@ async function createRuntimeOps(runtimeHandle, benchmark) {
|
|
|
328
337
|
...params.reactionEvent,
|
|
329
338
|
id: params.reactionEventId,
|
|
330
339
|
},
|
|
340
|
+
actionResultChunkEvents,
|
|
331
341
|
};
|
|
332
342
|
},
|
|
333
|
-
|
|
334
|
-
await store.saveStepParts({ stepId: params.stepId, parts: params.parts });
|
|
335
|
-
},
|
|
336
|
-
saveContextPartsAndUpdateReaction: async (params) => {
|
|
343
|
+
saveExecutionStepOutput: async (params) => {
|
|
337
344
|
await store.saveStepParts({ stepId: params.stepId, parts: params.parts });
|
|
338
345
|
await instrumentedDb.transact([
|
|
339
346
|
instrumentedDb.tx.event_items[params.reactionEventId].update(params.reactionEvent),
|
|
@@ -353,9 +360,9 @@ async function createRuntimeOps(runtimeHandle, benchmark) {
|
|
|
353
360
|
id: itemId,
|
|
354
361
|
};
|
|
355
362
|
},
|
|
356
|
-
completeExecution: async (contextIdentifier, executionId, status) => {
|
|
363
|
+
completeExecution: async (contextIdentifier, executionId, status, opts) => {
|
|
357
364
|
const contextId = requireContextId(contextIdentifier);
|
|
358
|
-
|
|
365
|
+
const txs = [
|
|
359
366
|
instrumentedDb.tx.event_executions[executionId].update({
|
|
360
367
|
status,
|
|
361
368
|
updatedAt: new Date(),
|
|
@@ -364,7 +371,19 @@ async function createRuntimeOps(runtimeHandle, benchmark) {
|
|
|
364
371
|
status: "closed",
|
|
365
372
|
updatedAt: new Date(),
|
|
366
373
|
}),
|
|
367
|
-
]
|
|
374
|
+
];
|
|
375
|
+
if (opts?.reactionEventId && opts.reactionEvent) {
|
|
376
|
+
txs.push(instrumentedDb.tx.event_items[opts.reactionEventId].update(opts.reactionEvent));
|
|
377
|
+
}
|
|
378
|
+
await instrumentedDb.transact(txs);
|
|
379
|
+
return opts?.reactionEventId && opts.reactionEvent
|
|
380
|
+
? {
|
|
381
|
+
reactionEvent: {
|
|
382
|
+
...opts.reactionEvent,
|
|
383
|
+
id: opts.reactionEventId,
|
|
384
|
+
},
|
|
385
|
+
}
|
|
386
|
+
: {};
|
|
368
387
|
},
|
|
369
388
|
};
|
|
370
389
|
}
|
|
@@ -375,16 +394,15 @@ async function createWorkflowOps(runtime) {
|
|
|
375
394
|
updateContextContent: async (contextIdentifier, content) => await updateContextContent({ runtime, contextIdentifier, content }),
|
|
376
395
|
updateContextReactor: async (contextIdentifier, reactor) => await updateContextReactor({ runtime, contextIdentifier, reactor }),
|
|
377
396
|
updateContextStatus: async (contextIdentifier, status) => await updateContextStatus({ runtime, contextIdentifier, status }),
|
|
378
|
-
|
|
379
|
-
|
|
397
|
+
openExecution: async ({ contextIdentifier, triggerEvent }) => await openExecution({ runtime, contextIdentifier, triggerEvent }),
|
|
398
|
+
openExecutionStep: async (params) => await openExecutionStep({ runtime, ...params }),
|
|
380
399
|
createContextStep: async ({ executionId, iteration }) => await createContextStep({ runtime, executionId, iteration }),
|
|
381
400
|
updateContextStep: async (params) => await updateContextStep({ runtime, ...params }),
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
saveContextPartsAndUpdateReaction: async (params) => await saveContextPartsAndUpdateReaction({ runtime, ...params }),
|
|
401
|
+
completeExecutionStep: async (params) => await completeExecutionStep({ runtime, ...params }),
|
|
402
|
+
saveExecutionStepOutput: async (params) => await saveExecutionStepOutput({ runtime, ...params }),
|
|
385
403
|
getItems: async (contextIdentifier) => await getContextItems({ runtime, contextIdentifier }),
|
|
386
404
|
updateItem: async (itemId, item, opts) => await updateItem({ runtime, eventId: itemId, event: item, opts }),
|
|
387
|
-
completeExecution: async (contextIdentifier, executionId, status) => await completeExecution({ runtime, contextIdentifier, executionId, status }),
|
|
405
|
+
completeExecution: async (contextIdentifier, executionId, status, opts) => await completeExecution({ runtime, contextIdentifier, executionId, status, ...opts }),
|
|
388
406
|
};
|
|
389
407
|
}
|
|
390
408
|
async function getContextEngineOps(runtime, benchmark) {
|
|
@@ -467,7 +485,7 @@ export class ContextEngine {
|
|
|
467
485
|
await measureBenchmark(params.__benchmark, "react.reopenClosedContextMs", async () => await ops.updateContextStatus(contextSelector, "open_idle"));
|
|
468
486
|
currentContext = { ...currentContext, status: "open_idle" };
|
|
469
487
|
}
|
|
470
|
-
const shell = await measureBenchmark(params.__benchmark, "react.
|
|
488
|
+
const shell = await measureBenchmark(params.__benchmark, "react.openExecutionMs", async () => await ops.openExecution({
|
|
471
489
|
contextIdentifier: contextSelector,
|
|
472
490
|
triggerEvent,
|
|
473
491
|
}));
|
|
@@ -690,7 +708,7 @@ export class ContextEngine {
|
|
|
690
708
|
const stagePrefix = `react.iteration.${iter}`;
|
|
691
709
|
// Hook: Context DSL `context()` (implemented by subclasses via `initialize()`)
|
|
692
710
|
const nextContent = await measureBenchmark(params.__benchmark, `${stagePrefix}.contextMs`, async () => await story.initialize(updatedContext, env, runtimeHandle));
|
|
693
|
-
const openedStep = await measureBenchmark(params.__benchmark, `${stagePrefix}.
|
|
711
|
+
const openedStep = await measureBenchmark(params.__benchmark, `${stagePrefix}.openExecutionStepMs`, async () => await ops.openExecutionStep({
|
|
694
712
|
contextIdentifier: activeContextSelector,
|
|
695
713
|
content: nextContent,
|
|
696
714
|
executionId,
|
|
@@ -748,7 +766,7 @@ export class ContextEngine {
|
|
|
748
766
|
if (nextSignature === persistedReactionPartsSignature)
|
|
749
767
|
return;
|
|
750
768
|
persistedReactionPartsSignature = nextSignature;
|
|
751
|
-
const saved = await ops.
|
|
769
|
+
const saved = await ops.saveExecutionStepOutput({
|
|
752
770
|
stepId: openedStep.stepId,
|
|
753
771
|
parts: normalizedParts,
|
|
754
772
|
reactionEventId: reactionEvent.id,
|
|
@@ -829,7 +847,7 @@ export class ContextEngine {
|
|
|
829
847
|
},
|
|
830
848
|
status: "pending",
|
|
831
849
|
};
|
|
832
|
-
const appendedReactorOutput = await measureBenchmark(params.__benchmark, `${stagePrefix}.
|
|
850
|
+
const appendedReactorOutput = await measureBenchmark(params.__benchmark, `${stagePrefix}.saveExecutionStepOutputMs`, async () => await ops.saveExecutionStepOutput({
|
|
833
851
|
stepId: openedStep.stepId,
|
|
834
852
|
parts: stepParts,
|
|
835
853
|
reactionEventId: reactionEvent.id,
|
|
@@ -886,12 +904,10 @@ export class ContextEngine {
|
|
|
886
904
|
...reactionEvent,
|
|
887
905
|
status: "completed",
|
|
888
906
|
};
|
|
889
|
-
const finalized = await measureBenchmark(params.__benchmark, `${stagePrefix}.
|
|
907
|
+
const finalized = await measureBenchmark(params.__benchmark, `${stagePrefix}.completeExecutionStepMs`, async () => await ops.completeExecutionStep({
|
|
890
908
|
session: currentStepStream,
|
|
891
909
|
stepId: openedStep.stepId,
|
|
892
|
-
|
|
893
|
-
status: "completed",
|
|
894
|
-
},
|
|
910
|
+
stepStatus: "completed",
|
|
895
911
|
reactionEventId,
|
|
896
912
|
reactionEvent: completedReactionEvent,
|
|
897
913
|
executionId,
|
|
@@ -899,6 +915,7 @@ export class ContextEngine {
|
|
|
899
915
|
iteration: iter,
|
|
900
916
|
}));
|
|
901
917
|
currentStepStream = null;
|
|
918
|
+
currentStepId = null;
|
|
902
919
|
reactionEvent = finalized.reactionEvent ?? completedReactionEvent;
|
|
903
920
|
await emitContextEvents({
|
|
904
921
|
silent,
|
|
@@ -1037,19 +1054,7 @@ export class ContextEngine {
|
|
|
1037
1054
|
};
|
|
1038
1055
|
}
|
|
1039
1056
|
})));
|
|
1040
|
-
|
|
1041
|
-
session: currentStepStream,
|
|
1042
|
-
contextId: String(currentContext.id),
|
|
1043
|
-
executionId,
|
|
1044
|
-
itemId: reactionEventId,
|
|
1045
|
-
actionResults: actionResults,
|
|
1046
|
-
}));
|
|
1047
|
-
await emitContextEvents({
|
|
1048
|
-
silent,
|
|
1049
|
-
writable,
|
|
1050
|
-
events: actionResultChunkEvents,
|
|
1051
|
-
});
|
|
1052
|
-
// Merge action results into persisted parts (so next LLM call can see them)
|
|
1057
|
+
// Merge action results into step parts so the next reaction can see them.
|
|
1053
1058
|
let finalizedStepParts = Array.isArray(stepParts) ? [...stepParts] : [];
|
|
1054
1059
|
for (const r of actionResults) {
|
|
1055
1060
|
finalizedStepParts = applyToolExecutionResultToParts(finalizedStepParts, {
|
|
@@ -1061,14 +1066,7 @@ export class ContextEngine {
|
|
|
1061
1066
|
message: r.errorText,
|
|
1062
1067
|
});
|
|
1063
1068
|
}
|
|
1064
|
-
|
|
1065
|
-
stepId: openedStep.stepId,
|
|
1066
|
-
parts: finalizedStepParts,
|
|
1067
|
-
executionId,
|
|
1068
|
-
contextId: String(currentContext.id),
|
|
1069
|
-
iteration: iter,
|
|
1070
|
-
}));
|
|
1071
|
-
reactionEvent = {
|
|
1069
|
+
const pendingReactionEvent = {
|
|
1072
1070
|
...reactionEvent,
|
|
1073
1071
|
content: {
|
|
1074
1072
|
...reactionEvent.content,
|
|
@@ -1078,48 +1076,26 @@ export class ContextEngine {
|
|
|
1078
1076
|
},
|
|
1079
1077
|
status: "pending",
|
|
1080
1078
|
};
|
|
1081
|
-
|
|
1082
|
-
for (const r of actionResults) {
|
|
1083
|
-
await story.opts.onActionExecuted?.({
|
|
1084
|
-
actionRequest: r.actionRequest,
|
|
1085
|
-
success: r.success,
|
|
1086
|
-
output: r.output,
|
|
1087
|
-
errorText: r.errorText,
|
|
1088
|
-
eventId: reactionEventId,
|
|
1089
|
-
executionId,
|
|
1090
|
-
});
|
|
1091
|
-
}
|
|
1092
|
-
// Stop/continue boundary: allow the Context to decide if the loop should continue.
|
|
1093
|
-
// IMPORTANT: we call this after tool results have been merged into the persisted `reactionEvent`,
|
|
1094
|
-
// so stories can inspect `reactionEvent.content.parts` deterministically.
|
|
1095
|
-
const continueLoop = await measureBenchmark(params.__benchmark, `${stagePrefix}.shouldContinueMs`, async () => await story.shouldContinue({
|
|
1096
|
-
env,
|
|
1097
|
-
runtime: runtimeHandle,
|
|
1098
|
-
context: updatedContext,
|
|
1099
|
-
reactionEvent,
|
|
1100
|
-
assistantEvent: assistantEventEffective,
|
|
1101
|
-
actionRequests,
|
|
1102
|
-
actionResults: actionResults,
|
|
1103
|
-
}));
|
|
1104
|
-
const finalizedReactionStatus = continueLoop === false ? "completed" : "pending";
|
|
1105
|
-
const finalizedReactionEvent = {
|
|
1106
|
-
...reactionEvent,
|
|
1107
|
-
status: finalizedReactionStatus,
|
|
1108
|
-
};
|
|
1109
|
-
const finalizedStep = await measureBenchmark(params.__benchmark, `${stagePrefix}.finalizeReactionStepMs`, async () => await ops.finalizeReactionStep({
|
|
1079
|
+
const completedStep = await measureBenchmark(params.__benchmark, `${stagePrefix}.completeExecutionStepMs`, async () => await ops.completeExecutionStep({
|
|
1110
1080
|
session: currentStepStream,
|
|
1111
1081
|
stepId: openedStep.stepId,
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1082
|
+
parts: finalizedStepParts,
|
|
1083
|
+
actionResults: actionResults,
|
|
1084
|
+
stepStatus: "completed",
|
|
1115
1085
|
reactionEventId,
|
|
1116
|
-
reactionEvent:
|
|
1086
|
+
reactionEvent: pendingReactionEvent,
|
|
1117
1087
|
executionId,
|
|
1118
1088
|
contextId: String(currentContext.id),
|
|
1119
1089
|
iteration: iter,
|
|
1120
1090
|
}));
|
|
1121
1091
|
currentStepStream = null;
|
|
1122
|
-
|
|
1092
|
+
currentStepId = null;
|
|
1093
|
+
reactionEvent = completedStep.reactionEvent ?? pendingReactionEvent;
|
|
1094
|
+
await emitContextEvents({
|
|
1095
|
+
silent,
|
|
1096
|
+
writable,
|
|
1097
|
+
events: completedStep.actionResultChunkEvents,
|
|
1098
|
+
});
|
|
1123
1099
|
await emitContextEvents({
|
|
1124
1100
|
silent,
|
|
1125
1101
|
writable,
|
|
@@ -1142,6 +1118,28 @@ export class ContextEngine {
|
|
|
1142
1118
|
},
|
|
1143
1119
|
],
|
|
1144
1120
|
});
|
|
1121
|
+
// Callback for observability/integration
|
|
1122
|
+
for (const r of actionResults) {
|
|
1123
|
+
await story.opts.onActionExecuted?.({
|
|
1124
|
+
actionRequest: r.actionRequest,
|
|
1125
|
+
success: r.success,
|
|
1126
|
+
output: r.output,
|
|
1127
|
+
errorText: r.errorText,
|
|
1128
|
+
eventId: reactionEventId,
|
|
1129
|
+
executionId,
|
|
1130
|
+
});
|
|
1131
|
+
}
|
|
1132
|
+
// Stop/continue boundary: allow the Context to decide if the loop should continue.
|
|
1133
|
+
// Tool results are already persisted in the completed reaction step here.
|
|
1134
|
+
const continueLoop = await measureBenchmark(params.__benchmark, `${stagePrefix}.shouldContinueMs`, async () => await story.shouldContinue({
|
|
1135
|
+
env,
|
|
1136
|
+
runtime: runtimeHandle,
|
|
1137
|
+
context: updatedContext,
|
|
1138
|
+
reactionEvent,
|
|
1139
|
+
assistantEvent: assistantEventEffective,
|
|
1140
|
+
actionRequests,
|
|
1141
|
+
actionResults: actionResults,
|
|
1142
|
+
}));
|
|
1145
1143
|
if (continueLoop !== false) {
|
|
1146
1144
|
await emitContextEvents({
|
|
1147
1145
|
silent,
|
|
@@ -1159,6 +1157,10 @@ export class ContextEngine {
|
|
|
1159
1157
|
});
|
|
1160
1158
|
}
|
|
1161
1159
|
if (continueLoop === false) {
|
|
1160
|
+
reactionEvent = {
|
|
1161
|
+
...reactionEvent,
|
|
1162
|
+
status: "completed",
|
|
1163
|
+
};
|
|
1162
1164
|
await emitContextEvents({
|
|
1163
1165
|
silent,
|
|
1164
1166
|
writable,
|
|
@@ -1173,7 +1175,11 @@ export class ContextEngine {
|
|
|
1173
1175
|
},
|
|
1174
1176
|
],
|
|
1175
1177
|
});
|
|
1176
|
-
await measureBenchmark(params.__benchmark, `${stagePrefix}.completeExecutionMs`, async () => await ops.completeExecution(activeContextSelector, executionId, "completed"
|
|
1178
|
+
await measureBenchmark(params.__benchmark, `${stagePrefix}.completeExecutionMs`, async () => await ops.completeExecution(activeContextSelector, executionId, "completed", {
|
|
1179
|
+
contextId: String(currentContext.id),
|
|
1180
|
+
reactionEventId,
|
|
1181
|
+
reactionEvent,
|
|
1182
|
+
}));
|
|
1177
1183
|
execution = { ...execution, status: "completed" };
|
|
1178
1184
|
updatedContext = { ...updatedContext, status: "closed" };
|
|
1179
1185
|
await emitContextEvents({
|
|
@@ -2,7 +2,8 @@ import type { UIMessageChunk } from "ai";
|
|
|
2
2
|
import type { ContextEnvironment } from "../context.config.js";
|
|
3
3
|
import type { ContextRuntime } from "../context.runtime.js";
|
|
4
4
|
import type { ContextExecution, ContextItem, ContextIdentifier, StoredContext, ContextStatus } from "../context.store.js";
|
|
5
|
-
import {
|
|
5
|
+
import type { ContextStreamEvent } from "../context.stream.js";
|
|
6
|
+
import { type ContextActionResultForStream, type PersistedContextStepStreamSession } from "./stream.steps.js";
|
|
6
7
|
type RuntimeParams<Env extends ContextEnvironment = ContextEnvironment> = {
|
|
7
8
|
runtime: ContextRuntime<Env>;
|
|
8
9
|
};
|
|
@@ -48,7 +49,7 @@ export declare function saveTriggerItem(params: RuntimeParams & {
|
|
|
48
49
|
contextIdentifier: ContextIdentifier;
|
|
49
50
|
event: ContextItem;
|
|
50
51
|
}): Promise<ContextItem>;
|
|
51
|
-
export declare function
|
|
52
|
+
export declare function openExecution(params: {
|
|
52
53
|
runtime: ContextRuntime<ContextEnvironment>;
|
|
53
54
|
contextIdentifier: ContextIdentifier;
|
|
54
55
|
triggerEvent: ContextItem;
|
|
@@ -96,13 +97,18 @@ export declare function completeExecution(params: RuntimeParams & {
|
|
|
96
97
|
contextIdentifier: ContextIdentifier;
|
|
97
98
|
executionId: string;
|
|
98
99
|
status: "completed" | "failed";
|
|
99
|
-
|
|
100
|
+
contextId?: string;
|
|
101
|
+
reactionEventId?: string;
|
|
102
|
+
reactionEvent?: ContextItem;
|
|
103
|
+
}): Promise<{
|
|
104
|
+
reactionEvent?: ContextItem;
|
|
105
|
+
}>;
|
|
100
106
|
export declare function updateExecutionWorkflowRun(params: {
|
|
101
107
|
runtime: ContextRuntime<ContextEnvironment>;
|
|
102
108
|
executionId: string;
|
|
103
109
|
workflowRunId: string;
|
|
104
110
|
}): Promise<void>;
|
|
105
|
-
export declare function
|
|
111
|
+
export declare function openExecutionStep<C>(params: {
|
|
106
112
|
runtime: ContextRuntime<ContextEnvironment>;
|
|
107
113
|
contextIdentifier: ContextIdentifier;
|
|
108
114
|
content: C;
|
|
@@ -129,33 +135,29 @@ export declare function updateContextStep(params: {
|
|
|
129
135
|
iteration?: number;
|
|
130
136
|
patch: ContextStepPatch;
|
|
131
137
|
}): Promise<void>;
|
|
132
|
-
export declare function
|
|
138
|
+
export declare function completeExecutionStep(params: {
|
|
133
139
|
runtime: ContextRuntime<ContextEnvironment>;
|
|
134
140
|
session?: PersistedContextStepStreamSession | null;
|
|
135
141
|
stepId: string;
|
|
136
142
|
executionId?: string;
|
|
137
143
|
contextId?: string;
|
|
138
144
|
iteration?: number;
|
|
139
|
-
|
|
145
|
+
parts?: any[];
|
|
146
|
+
actionResults?: ContextActionResultForStream[];
|
|
147
|
+
stepStatus?: ContextStepPatch["status"];
|
|
148
|
+
errorText?: string;
|
|
140
149
|
reactionEventId?: string;
|
|
141
150
|
reactionEvent?: ContextItem;
|
|
142
151
|
}): Promise<{
|
|
143
152
|
reactionEvent?: ContextItem;
|
|
153
|
+
actionResultChunkEvents: ContextStreamEvent[];
|
|
144
154
|
}>;
|
|
145
155
|
export declare function linkItemToExecutionStep(params: {
|
|
146
156
|
runtime: ContextRuntime<ContextEnvironment>;
|
|
147
157
|
itemId: string;
|
|
148
158
|
executionId: string;
|
|
149
159
|
}): Promise<void>;
|
|
150
|
-
export declare function
|
|
151
|
-
runtime: ContextRuntime<ContextEnvironment>;
|
|
152
|
-
stepId: string;
|
|
153
|
-
executionId?: string;
|
|
154
|
-
contextId?: string;
|
|
155
|
-
iteration?: number;
|
|
156
|
-
parts: any[];
|
|
157
|
-
}): Promise<void>;
|
|
158
|
-
export declare function saveContextPartsAndUpdateReaction(params: {
|
|
160
|
+
export declare function saveExecutionStepOutput(params: {
|
|
159
161
|
runtime: ContextRuntime<ContextEnvironment>;
|
|
160
162
|
stepId: string;
|
|
161
163
|
executionId?: string;
|
|
@@ -2,7 +2,7 @@ import { getContextRuntimeServices } from "../context.runtime.js";
|
|
|
2
2
|
import { OUTPUT_ITEM_TYPE, WEB_CHANNEL } from "../context.events.js";
|
|
3
3
|
import { writeContextTraceEvents } from "./trace.steps.js";
|
|
4
4
|
import { getClientResumeHookUrl, toolApprovalHookToken, toolApprovalWebhookToken, } from "../context.hooks.js";
|
|
5
|
-
import { createPersistedContextStepStreamForRuntime, finalizePersistedContextStepStreamForRuntime, } from "./stream.steps.js";
|
|
5
|
+
import { createPersistedContextStepStreamForRuntime, finalizePersistedContextStepStreamForRuntime, writeActionResultPartChunksToSession, } from "./stream.steps.js";
|
|
6
6
|
async function getRuntimeAndEnv(params) {
|
|
7
7
|
const env = params.runtime.env;
|
|
8
8
|
const runtime = await getContextRuntimeServices(params.runtime);
|
|
@@ -158,11 +158,11 @@ export async function saveTriggerItem(params) {
|
|
|
158
158
|
const { runtime } = await getRuntimeAndEnv(params);
|
|
159
159
|
return await runtime.store.saveItem(params.contextIdentifier, params.event);
|
|
160
160
|
}
|
|
161
|
-
export async function
|
|
161
|
+
export async function openExecution(params) {
|
|
162
162
|
"use step";
|
|
163
163
|
const { runtime, env } = await getRuntimeAndEnv(params);
|
|
164
164
|
const { store, db } = runtime;
|
|
165
|
-
logStepDebug("
|
|
165
|
+
logStepDebug("openExecution:start", {
|
|
166
166
|
contextIdentifier: summarizeContextIdentifierForLog(params.contextIdentifier),
|
|
167
167
|
triggerEventId: params.triggerEvent?.id,
|
|
168
168
|
triggerEventType: params.triggerEvent?.type,
|
|
@@ -174,7 +174,7 @@ export async function saveTriggerAndCreateExecution(params) {
|
|
|
174
174
|
saved = await store.saveItem(params.contextIdentifier, params.triggerEvent);
|
|
175
175
|
}
|
|
176
176
|
catch (error) {
|
|
177
|
-
logStepDebug("
|
|
177
|
+
logStepDebug("openExecution:saveItem:error", {
|
|
178
178
|
contextIdentifier: summarizeContextIdentifierForLog(params.contextIdentifier),
|
|
179
179
|
triggerEventId: params.triggerEvent?.id,
|
|
180
180
|
error: summarizeStepError(error),
|
|
@@ -206,7 +206,7 @@ export async function saveTriggerAndCreateExecution(params) {
|
|
|
206
206
|
});
|
|
207
207
|
}
|
|
208
208
|
catch (error) {
|
|
209
|
-
logStepDebug("
|
|
209
|
+
logStepDebug("openExecution:saveReaction:error", {
|
|
210
210
|
contextIdentifier: summarizeContextIdentifierForLog(params.contextIdentifier),
|
|
211
211
|
reactionEventId,
|
|
212
212
|
error: summarizeStepError(error),
|
|
@@ -218,7 +218,7 @@ export async function saveTriggerAndCreateExecution(params) {
|
|
|
218
218
|
execution = await store.createExecution(params.contextIdentifier, saved.id, savedReaction.id);
|
|
219
219
|
}
|
|
220
220
|
catch (error) {
|
|
221
|
-
logStepDebug("
|
|
221
|
+
logStepDebug("openExecution:createExecution:error", {
|
|
222
222
|
contextIdentifier: summarizeContextIdentifierForLog(params.contextIdentifier),
|
|
223
223
|
triggerEventId: saved.id,
|
|
224
224
|
reactionEventId: savedReaction.id,
|
|
@@ -237,7 +237,7 @@ export async function saveTriggerAndCreateExecution(params) {
|
|
|
237
237
|
});
|
|
238
238
|
}
|
|
239
239
|
catch (error) {
|
|
240
|
-
logStepDebug("
|
|
240
|
+
logStepDebug("openExecution:linkItemsToExecution:error", {
|
|
241
241
|
contextIdentifier: summarizeContextIdentifierForLog(params.contextIdentifier),
|
|
242
242
|
triggerEventId: saved.id,
|
|
243
243
|
reactionEventId: savedReaction.id,
|
|
@@ -474,16 +474,22 @@ export async function completeExecution(params) {
|
|
|
474
474
|
const { runtime, env } = await getRuntimeAndEnv(params);
|
|
475
475
|
const { store, db } = runtime;
|
|
476
476
|
await store.completeExecution(params.contextIdentifier, params.executionId, params.status);
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
477
|
+
let savedReaction;
|
|
478
|
+
if (params.reactionEventId && params.reactionEvent) {
|
|
479
|
+
savedReaction = await store.updateItem(params.reactionEventId, params.reactionEvent);
|
|
480
|
+
}
|
|
481
|
+
const contextId = typeof params.contextId === "string"
|
|
482
|
+
? params.contextId
|
|
483
|
+
: typeof params.contextIdentifier?.id === "string"
|
|
484
|
+
? String(params.contextIdentifier.id)
|
|
485
|
+
: undefined;
|
|
480
486
|
const { runId } = await resolveWorkflowRunId({
|
|
481
487
|
env,
|
|
482
488
|
db,
|
|
483
489
|
executionId: params.executionId,
|
|
484
490
|
});
|
|
485
491
|
if (runId) {
|
|
486
|
-
|
|
492
|
+
const events = [
|
|
487
493
|
{
|
|
488
494
|
workflowRunId: runId,
|
|
489
495
|
eventId: `context_execution:${String(params.executionId)}:${params.status}`,
|
|
@@ -495,8 +501,25 @@ export async function completeExecution(params) {
|
|
|
495
501
|
status: params.status,
|
|
496
502
|
},
|
|
497
503
|
},
|
|
498
|
-
]
|
|
504
|
+
];
|
|
505
|
+
if (savedReaction) {
|
|
506
|
+
events.push({
|
|
507
|
+
workflowRunId: runId,
|
|
508
|
+
eventId: `context_item:${String(savedReaction.id)}`,
|
|
509
|
+
eventKind: "context.item",
|
|
510
|
+
eventAt: new Date().toISOString(),
|
|
511
|
+
contextId,
|
|
512
|
+
executionId: String(params.executionId),
|
|
513
|
+
contextEventId: String(savedReaction.id),
|
|
514
|
+
payload: {
|
|
515
|
+
...savedReaction,
|
|
516
|
+
direction: inferDirection(savedReaction),
|
|
517
|
+
},
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
await maybeWriteTraceEvents(env, events);
|
|
499
521
|
}
|
|
522
|
+
return { reactionEvent: savedReaction };
|
|
500
523
|
}
|
|
501
524
|
export async function updateExecutionWorkflowRun(params) {
|
|
502
525
|
"use step";
|
|
@@ -511,7 +534,7 @@ export async function updateExecutionWorkflowRun(params) {
|
|
|
511
534
|
]);
|
|
512
535
|
}
|
|
513
536
|
}
|
|
514
|
-
export async function
|
|
537
|
+
export async function openExecutionStep(params) {
|
|
515
538
|
"use step";
|
|
516
539
|
const { runtime } = await getRuntimeAndEnv(params);
|
|
517
540
|
const { store } = runtime;
|
|
@@ -574,10 +597,20 @@ export async function updateContextStep(params) {
|
|
|
574
597
|
]);
|
|
575
598
|
}
|
|
576
599
|
}
|
|
577
|
-
export async function
|
|
600
|
+
export async function completeExecutionStep(params) {
|
|
578
601
|
"use step";
|
|
579
602
|
const { runtime, env } = await getRuntimeAndEnv(params);
|
|
580
603
|
const { store, db } = runtime;
|
|
604
|
+
const actionResultChunkEvents = await writeActionResultPartChunksToSession({
|
|
605
|
+
session: params.session,
|
|
606
|
+
contextId: String(params.contextId ?? ""),
|
|
607
|
+
executionId: String(params.executionId ?? ""),
|
|
608
|
+
itemId: String(params.reactionEventId ?? ""),
|
|
609
|
+
actionResults: params.actionResults ?? [],
|
|
610
|
+
});
|
|
611
|
+
if (params.parts) {
|
|
612
|
+
await store.saveStepParts({ stepId: params.stepId, parts: params.parts });
|
|
613
|
+
}
|
|
581
614
|
if (params.session) {
|
|
582
615
|
await finalizePersistedContextStepStreamForRuntime({
|
|
583
616
|
runtime,
|
|
@@ -586,7 +619,8 @@ export async function finalizeReactionStep(params) {
|
|
|
586
619
|
});
|
|
587
620
|
}
|
|
588
621
|
await store.updateStep(params.stepId, {
|
|
589
|
-
|
|
622
|
+
status: params.stepStatus ?? "completed",
|
|
623
|
+
...(params.errorText !== undefined ? { errorText: params.errorText } : {}),
|
|
590
624
|
updatedAt: new Date(),
|
|
591
625
|
});
|
|
592
626
|
let savedReaction;
|
|
@@ -609,12 +643,29 @@ export async function finalizeReactionStep(params) {
|
|
|
609
643
|
executionId: params.executionId,
|
|
610
644
|
stepId: String(params.stepId),
|
|
611
645
|
payload: {
|
|
612
|
-
status: params.
|
|
646
|
+
status: params.stepStatus ?? "completed",
|
|
613
647
|
iteration: params.iteration,
|
|
614
|
-
errorText: params.
|
|
648
|
+
errorText: params.errorText,
|
|
615
649
|
},
|
|
616
650
|
},
|
|
617
651
|
];
|
|
652
|
+
if (params.parts?.length) {
|
|
653
|
+
for (let idx = 0; idx < params.parts.length; idx += 1) {
|
|
654
|
+
const part = params.parts[idx];
|
|
655
|
+
events.push({
|
|
656
|
+
workflowRunId: runId,
|
|
657
|
+
eventId: `context_part:${String(params.stepId)}:${idx}`,
|
|
658
|
+
eventKind: "context.part",
|
|
659
|
+
eventAt: new Date().toISOString(),
|
|
660
|
+
contextId: params.contextId,
|
|
661
|
+
executionId: params.executionId,
|
|
662
|
+
stepId: String(params.stepId),
|
|
663
|
+
partKey: `${String(params.stepId)}:${idx}`,
|
|
664
|
+
partIdx: idx,
|
|
665
|
+
payload: part,
|
|
666
|
+
});
|
|
667
|
+
}
|
|
668
|
+
}
|
|
618
669
|
if (savedReaction) {
|
|
619
670
|
events.push({
|
|
620
671
|
workflowRunId: runId,
|
|
@@ -632,7 +683,7 @@ export async function finalizeReactionStep(params) {
|
|
|
632
683
|
}
|
|
633
684
|
await maybeWriteTraceEvents(env, events);
|
|
634
685
|
}
|
|
635
|
-
return { reactionEvent: savedReaction };
|
|
686
|
+
return { reactionEvent: savedReaction, actionResultChunkEvents };
|
|
636
687
|
}
|
|
637
688
|
export async function linkItemToExecutionStep(params) {
|
|
638
689
|
"use step";
|
|
@@ -640,37 +691,7 @@ export async function linkItemToExecutionStep(params) {
|
|
|
640
691
|
const { store } = runtime;
|
|
641
692
|
await store.linkItemToExecution({ itemId: params.itemId, executionId: params.executionId });
|
|
642
693
|
}
|
|
643
|
-
export async function
|
|
644
|
-
"use step";
|
|
645
|
-
const { runtime, env } = await getRuntimeAndEnv(params);
|
|
646
|
-
const { store, db } = runtime;
|
|
647
|
-
await store.saveStepParts({ stepId: params.stepId, parts: params.parts });
|
|
648
|
-
const { runId } = await resolveWorkflowRunId({
|
|
649
|
-
env,
|
|
650
|
-
db,
|
|
651
|
-
executionId: params.executionId,
|
|
652
|
-
});
|
|
653
|
-
if (runId && params.parts?.length) {
|
|
654
|
-
const events = [];
|
|
655
|
-
for (let idx = 0; idx < params.parts.length; idx += 1) {
|
|
656
|
-
const part = params.parts[idx];
|
|
657
|
-
events.push({
|
|
658
|
-
workflowRunId: runId,
|
|
659
|
-
eventId: `context_part:${String(params.stepId)}:${idx}`,
|
|
660
|
-
eventKind: "context.part",
|
|
661
|
-
eventAt: new Date().toISOString(),
|
|
662
|
-
contextId: params.contextId,
|
|
663
|
-
executionId: params.executionId,
|
|
664
|
-
stepId: String(params.stepId),
|
|
665
|
-
partKey: `${String(params.stepId)}:${idx}`,
|
|
666
|
-
partIdx: idx,
|
|
667
|
-
payload: part,
|
|
668
|
-
});
|
|
669
|
-
}
|
|
670
|
-
await maybeWriteTraceEvents(env, events);
|
|
671
|
-
}
|
|
672
|
-
}
|
|
673
|
-
export async function saveContextPartsAndUpdateReaction(params) {
|
|
694
|
+
export async function saveExecutionStepOutput(params) {
|
|
674
695
|
"use step";
|
|
675
696
|
const { runtime, env } = await getRuntimeAndEnv(params);
|
|
676
697
|
const { store, db } = runtime;
|
|
@@ -50,21 +50,22 @@ export declare function abortPersistedContextStepStream(params: {
|
|
|
50
50
|
session: PersistedContextStepStreamSession;
|
|
51
51
|
reason?: string | null;
|
|
52
52
|
}): Promise<void>;
|
|
53
|
-
export
|
|
53
|
+
export type ContextActionResultForStream = {
|
|
54
|
+
actionRequest: {
|
|
55
|
+
actionRef: string;
|
|
56
|
+
actionName: string;
|
|
57
|
+
input: unknown;
|
|
58
|
+
};
|
|
59
|
+
success: boolean;
|
|
60
|
+
output: unknown;
|
|
61
|
+
errorText?: string;
|
|
62
|
+
};
|
|
63
|
+
export declare function writeActionResultPartChunksToSession(params: {
|
|
54
64
|
session?: PersistedContextStepStreamSession | null;
|
|
55
65
|
contextId: string;
|
|
56
66
|
executionId: string;
|
|
57
67
|
itemId: string;
|
|
58
|
-
actionResults:
|
|
59
|
-
actionRequest: {
|
|
60
|
-
actionRef: string;
|
|
61
|
-
actionName: string;
|
|
62
|
-
input: unknown;
|
|
63
|
-
};
|
|
64
|
-
success: boolean;
|
|
65
|
-
output: unknown;
|
|
66
|
-
errorText?: string;
|
|
67
|
-
}>;
|
|
68
|
+
actionResults: ContextActionResultForStream[];
|
|
68
69
|
}): Promise<ContextStreamEvent[]>;
|
|
69
70
|
export declare function readPersistedContextStepStream(params: {
|
|
70
71
|
db: any;
|
|
@@ -183,8 +183,7 @@ export async function abortPersistedContextStepStream(params) {
|
|
|
183
183
|
abortReason: params.reason,
|
|
184
184
|
});
|
|
185
185
|
}
|
|
186
|
-
export async function
|
|
187
|
-
"use step";
|
|
186
|
+
export async function writeActionResultPartChunksToSession(params) {
|
|
188
187
|
if (!params.session || params.actionResults.length === 0)
|
|
189
188
|
return [];
|
|
190
189
|
const writer = params.session.stream.getWriter();
|
|
@@ -71,6 +71,43 @@ function ensureValidEntityId(value, label) {
|
|
|
71
71
|
}
|
|
72
72
|
return normalized;
|
|
73
73
|
}
|
|
74
|
+
function sanitizeInstantString(value) {
|
|
75
|
+
return value.includes("\u0000") ? value.replace(/\u0000/g, "") : value;
|
|
76
|
+
}
|
|
77
|
+
function isOpaqueJsonValue(value) {
|
|
78
|
+
return (value instanceof Date ||
|
|
79
|
+
value instanceof ArrayBuffer ||
|
|
80
|
+
ArrayBuffer.isView(value));
|
|
81
|
+
}
|
|
82
|
+
function sanitizeInstantValue(value, seen = new WeakMap()) {
|
|
83
|
+
if (typeof value === "string") {
|
|
84
|
+
return sanitizeInstantString(value);
|
|
85
|
+
}
|
|
86
|
+
if (value === null || value === undefined || typeof value !== "object") {
|
|
87
|
+
return value;
|
|
88
|
+
}
|
|
89
|
+
if (isOpaqueJsonValue(value)) {
|
|
90
|
+
return value;
|
|
91
|
+
}
|
|
92
|
+
const cached = seen.get(value);
|
|
93
|
+
if (cached) {
|
|
94
|
+
return cached;
|
|
95
|
+
}
|
|
96
|
+
if (Array.isArray(value)) {
|
|
97
|
+
const out = [];
|
|
98
|
+
seen.set(value, out);
|
|
99
|
+
for (const item of value) {
|
|
100
|
+
out.push(sanitizeInstantValue(item, seen));
|
|
101
|
+
}
|
|
102
|
+
return out;
|
|
103
|
+
}
|
|
104
|
+
const out = {};
|
|
105
|
+
seen.set(value, out);
|
|
106
|
+
for (const [key, entryValue] of Object.entries(value)) {
|
|
107
|
+
out[sanitizeInstantString(key)] = sanitizeInstantValue(entryValue, seen);
|
|
108
|
+
}
|
|
109
|
+
return out;
|
|
110
|
+
}
|
|
74
111
|
function logInstantTransactFailure(params) {
|
|
75
112
|
if (!shouldDebugInstantStore())
|
|
76
113
|
return;
|
|
@@ -244,6 +281,7 @@ export class InstantStore {
|
|
|
244
281
|
}
|
|
245
282
|
async saveItem(contextIdentifier, event) {
|
|
246
283
|
const eventId = ensureValidEntityId(event?.id, "event.id");
|
|
284
|
+
const sanitizedEvent = sanitizeInstantValue(event);
|
|
247
285
|
const context = await this.resolveContext(contextIdentifier);
|
|
248
286
|
const existing = await this.getItem(eventId);
|
|
249
287
|
if (existing?.status && existing.status !== "stored") {
|
|
@@ -251,7 +289,7 @@ export class InstantStore {
|
|
|
251
289
|
}
|
|
252
290
|
const txs = [
|
|
253
291
|
this.db.tx.event_items[eventId].update({
|
|
254
|
-
...
|
|
292
|
+
...sanitizedEvent,
|
|
255
293
|
id: eventId,
|
|
256
294
|
status: "stored",
|
|
257
295
|
}),
|
|
@@ -277,7 +315,7 @@ export class InstantStore {
|
|
|
277
315
|
throw error;
|
|
278
316
|
}
|
|
279
317
|
return {
|
|
280
|
-
...
|
|
318
|
+
...sanitizedEvent,
|
|
281
319
|
id: eventId,
|
|
282
320
|
status: "stored",
|
|
283
321
|
};
|
|
@@ -287,10 +325,11 @@ export class InstantStore {
|
|
|
287
325
|
if (current?.status && event.status && current.status !== event.status) {
|
|
288
326
|
assertItemTransition(current.status, event.status);
|
|
289
327
|
}
|
|
290
|
-
|
|
328
|
+
const sanitizedEvent = sanitizeInstantValue(event);
|
|
329
|
+
await this.db.transact([this.db.tx.event_items[eventId].update(sanitizedEvent)]);
|
|
291
330
|
return {
|
|
292
331
|
...current,
|
|
293
|
-
...
|
|
332
|
+
...sanitizedEvent,
|
|
294
333
|
id: eventId,
|
|
295
334
|
};
|
|
296
335
|
}
|
|
@@ -531,7 +570,7 @@ export class InstantStore {
|
|
|
531
570
|
]);
|
|
532
571
|
}
|
|
533
572
|
async saveStepParts(params) {
|
|
534
|
-
const parts = normalizePartsForPersistence(Array.isArray(params.parts) ? params.parts : []);
|
|
573
|
+
const parts = sanitizeInstantValue(normalizePartsForPersistence(Array.isArray(params.parts) ? params.parts : []));
|
|
535
574
|
if (parts.length === 0)
|
|
536
575
|
return;
|
|
537
576
|
const txs = parts.map((part, idx) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ekairos/events",
|
|
3
|
-
"version": "1.22.
|
|
3
|
+
"version": "1.22.80-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.80-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",
|