@ekairos/events 1.22.35-beta.development.0 → 1.22.35

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.
Files changed (73) hide show
  1. package/README.md +5 -3
  2. package/dist/codex.d.ts +11 -2
  3. package/dist/codex.js +16 -8
  4. package/dist/context.action-calls.d.ts +48 -0
  5. package/dist/context.action-calls.js +123 -0
  6. package/dist/context.action.d.ts +55 -0
  7. package/dist/context.action.js +25 -0
  8. package/dist/context.builder.d.ts +71 -43
  9. package/dist/context.builder.js +123 -28
  10. package/dist/context.config.d.ts +2 -1
  11. package/dist/context.config.js +8 -3
  12. package/dist/context.contract.d.ts +2 -4
  13. package/dist/context.contract.js +3 -9
  14. package/dist/context.d.ts +3 -2
  15. package/dist/context.engine.d.ts +60 -52
  16. package/dist/context.engine.js +506 -297
  17. package/dist/context.events.js +28 -87
  18. package/dist/context.js +1 -0
  19. package/dist/context.part-identity.d.ts +40 -0
  20. package/dist/context.part-identity.js +270 -0
  21. package/dist/context.parts.d.ts +389 -164
  22. package/dist/context.parts.js +343 -218
  23. package/dist/context.registry.d.ts +1 -1
  24. package/dist/context.runtime.d.ts +14 -4
  25. package/dist/context.runtime.js +21 -3
  26. package/dist/context.step-stream.d.ts +16 -2
  27. package/dist/context.step-stream.js +58 -16
  28. package/dist/context.store.d.ts +55 -10
  29. package/dist/context.stream.d.ts +14 -4
  30. package/dist/context.stream.js +31 -3
  31. package/dist/domain.d.ts +1 -0
  32. package/dist/domain.js +1 -0
  33. package/dist/index.d.ts +13 -10
  34. package/dist/index.js +7 -6
  35. package/dist/react.context-event-parts.d.ts +18 -0
  36. package/dist/react.context-event-parts.js +509 -0
  37. package/dist/react.d.ts +7 -42
  38. package/dist/react.js +4 -87
  39. package/dist/react.step-stream.d.ts +39 -0
  40. package/dist/react.step-stream.js +625 -0
  41. package/dist/react.types.d.ts +121 -0
  42. package/dist/react.types.js +2 -0
  43. package/dist/react.use-context.d.ts +7 -0
  44. package/dist/react.use-context.js +867 -0
  45. package/dist/reactors/ai-sdk.chunk-map.d.ts +1 -0
  46. package/dist/reactors/ai-sdk.chunk-map.js +56 -5
  47. package/dist/reactors/ai-sdk.reactor.d.ts +8 -9
  48. package/dist/reactors/ai-sdk.reactor.js +6 -9
  49. package/dist/reactors/ai-sdk.step.d.ts +4 -5
  50. package/dist/reactors/ai-sdk.step.js +24 -17
  51. package/dist/reactors/scripted.reactor.d.ts +7 -4
  52. package/dist/reactors/types.d.ts +19 -10
  53. package/dist/runtime.d.ts +6 -0
  54. package/dist/runtime.js +9 -0
  55. package/dist/runtime.step.js +1 -1
  56. package/dist/schema.d.ts +268 -2
  57. package/dist/schema.js +4 -9
  58. package/dist/steps/do-context-stream-step.js +4 -4
  59. package/dist/steps/durable.steps.d.ts +28 -0
  60. package/dist/steps/durable.steps.js +34 -0
  61. package/dist/steps/store.steps.d.ts +64 -22
  62. package/dist/steps/store.steps.js +192 -35
  63. package/dist/steps/stream.steps.d.ts +32 -0
  64. package/dist/steps/stream.steps.js +124 -6
  65. package/dist/steps/trace.steps.d.ts +4 -4
  66. package/dist/steps/trace.steps.js +21 -6
  67. package/dist/stores/instant.store.d.ts +11 -11
  68. package/dist/stores/instant.store.js +136 -6
  69. package/dist/tools-to-model-tools.d.ts +4 -2
  70. package/dist/tools-to-model-tools.js +30 -11
  71. package/package.json +18 -7
  72. package/dist/context.toolcalls.d.ts +0 -60
  73. package/dist/context.toolcalls.js +0 -117
@@ -2,6 +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, writeActionResultPartChunksToSession, } from "./stream.steps.js";
5
6
  async function getRuntimeAndEnv(params) {
6
7
  const env = params.runtime.env;
7
8
  const runtime = await getContextRuntimeServices(params.runtime);
@@ -142,6 +143,16 @@ export async function updateContextContent(params) {
142
143
  const { runtime } = await getRuntimeAndEnv(params);
143
144
  return await runtime.store.updateContextContent(params.contextIdentifier, params.content);
144
145
  }
146
+ export async function updateContextDefinition(params) {
147
+ "use step";
148
+ const { runtime } = await getRuntimeAndEnv(params);
149
+ return await runtime.store.updateContextDefinition(params.contextIdentifier, params.definition);
150
+ }
151
+ export async function upsertContextResources(params) {
152
+ "use step";
153
+ const { runtime } = await getRuntimeAndEnv(params);
154
+ return await runtime.store.upsertContextResources(params.contextIdentifier, params.resources);
155
+ }
145
156
  export async function updateContextReactor(params) {
146
157
  "use step";
147
158
  const { runtime } = await getRuntimeAndEnv(params);
@@ -157,11 +168,11 @@ export async function saveTriggerItem(params) {
157
168
  const { runtime } = await getRuntimeAndEnv(params);
158
169
  return await runtime.store.saveItem(params.contextIdentifier, params.event);
159
170
  }
160
- export async function saveTriggerAndCreateExecution(params) {
171
+ export async function openExecution(params) {
161
172
  "use step";
162
173
  const { runtime, env } = await getRuntimeAndEnv(params);
163
174
  const { store, db } = runtime;
164
- logStepDebug("saveTriggerAndCreateExecution:start", {
175
+ logStepDebug("openExecution:start", {
165
176
  contextIdentifier: summarizeContextIdentifierForLog(params.contextIdentifier),
166
177
  triggerEventId: params.triggerEvent?.id,
167
178
  triggerEventType: params.triggerEvent?.type,
@@ -173,7 +184,7 @@ export async function saveTriggerAndCreateExecution(params) {
173
184
  saved = await store.saveItem(params.contextIdentifier, params.triggerEvent);
174
185
  }
175
186
  catch (error) {
176
- logStepDebug("saveTriggerAndCreateExecution:saveItem:error", {
187
+ logStepDebug("openExecution:saveItem:error", {
177
188
  contextIdentifier: summarizeContextIdentifierForLog(params.contextIdentifier),
178
189
  triggerEventId: params.triggerEvent?.id,
179
190
  error: summarizeStepError(error),
@@ -205,7 +216,7 @@ export async function saveTriggerAndCreateExecution(params) {
205
216
  });
206
217
  }
207
218
  catch (error) {
208
- logStepDebug("saveTriggerAndCreateExecution:saveReaction:error", {
219
+ logStepDebug("openExecution:saveReaction:error", {
209
220
  contextIdentifier: summarizeContextIdentifierForLog(params.contextIdentifier),
210
221
  reactionEventId,
211
222
  error: summarizeStepError(error),
@@ -217,7 +228,7 @@ export async function saveTriggerAndCreateExecution(params) {
217
228
  execution = await store.createExecution(params.contextIdentifier, saved.id, savedReaction.id);
218
229
  }
219
230
  catch (error) {
220
- logStepDebug("saveTriggerAndCreateExecution:createExecution:error", {
231
+ logStepDebug("openExecution:createExecution:error", {
221
232
  contextIdentifier: summarizeContextIdentifierForLog(params.contextIdentifier),
222
233
  triggerEventId: saved.id,
223
234
  reactionEventId: savedReaction.id,
@@ -236,7 +247,7 @@ export async function saveTriggerAndCreateExecution(params) {
236
247
  });
237
248
  }
238
249
  catch (error) {
239
- logStepDebug("saveTriggerAndCreateExecution:linkItemsToExecution:error", {
250
+ logStepDebug("openExecution:linkItemsToExecution:error", {
240
251
  contextIdentifier: summarizeContextIdentifierForLog(params.contextIdentifier),
241
252
  triggerEventId: saved.id,
242
253
  reactionEventId: savedReaction.id,
@@ -417,6 +428,11 @@ export async function saveReactionItem(params) {
417
428
  }
418
429
  return saved;
419
430
  }
431
+ export async function getContextItems(params) {
432
+ "use step";
433
+ const { runtime } = await getRuntimeAndEnv(params);
434
+ return await runtime.store.getItems(params.contextIdentifier);
435
+ }
420
436
  export async function updateItem(params) {
421
437
  "use step";
422
438
  const { runtime, env } = await getRuntimeAndEnv(params);
@@ -468,16 +484,22 @@ export async function completeExecution(params) {
468
484
  const { runtime, env } = await getRuntimeAndEnv(params);
469
485
  const { store, db } = runtime;
470
486
  await store.completeExecution(params.contextIdentifier, params.executionId, params.status);
471
- const contextId = typeof params.contextIdentifier?.id === "string"
472
- ? String(params.contextIdentifier.id)
473
- : undefined;
487
+ let savedReaction;
488
+ if (params.reactionEventId && params.reactionEvent) {
489
+ savedReaction = await store.updateItem(params.reactionEventId, params.reactionEvent);
490
+ }
491
+ const contextId = typeof params.contextId === "string"
492
+ ? params.contextId
493
+ : typeof params.contextIdentifier?.id === "string"
494
+ ? String(params.contextIdentifier.id)
495
+ : undefined;
474
496
  const { runId } = await resolveWorkflowRunId({
475
497
  env,
476
498
  db,
477
499
  executionId: params.executionId,
478
500
  });
479
501
  if (runId) {
480
- await maybeWriteTraceEvents(env, [
502
+ const events = [
481
503
  {
482
504
  workflowRunId: runId,
483
505
  eventId: `context_execution:${String(params.executionId)}:${params.status}`,
@@ -489,8 +511,25 @@ export async function completeExecution(params) {
489
511
  status: params.status,
490
512
  },
491
513
  },
492
- ]);
514
+ ];
515
+ if (savedReaction) {
516
+ events.push({
517
+ workflowRunId: runId,
518
+ eventId: `context_item:${String(savedReaction.id)}`,
519
+ eventKind: "context.item",
520
+ eventAt: new Date().toISOString(),
521
+ contextId,
522
+ executionId: String(params.executionId),
523
+ contextEventId: String(savedReaction.id),
524
+ payload: {
525
+ ...savedReaction,
526
+ direction: inferDirection(savedReaction),
527
+ },
528
+ });
529
+ }
530
+ await maybeWriteTraceEvents(env, events);
493
531
  }
532
+ return { reactionEvent: savedReaction };
494
533
  }
495
534
  export async function updateExecutionWorkflowRun(params) {
496
535
  "use step";
@@ -505,6 +544,27 @@ export async function updateExecutionWorkflowRun(params) {
505
544
  ]);
506
545
  }
507
546
  }
547
+ export async function openExecutionStep(params) {
548
+ "use step";
549
+ const { runtime } = await getRuntimeAndEnv(params);
550
+ const { store } = runtime;
551
+ const step = await store.createStep({
552
+ executionId: params.executionId,
553
+ iteration: params.iteration,
554
+ });
555
+ const stream = await createPersistedContextStepStreamForRuntime(runtime, {
556
+ executionId: params.executionId,
557
+ stepId: step.id,
558
+ });
559
+ const context = await store.updateContextContent(params.contextIdentifier, params.content);
560
+ const events = await store.getItems(params.contextIdentifier);
561
+ return {
562
+ stepId: step.id,
563
+ stream,
564
+ context,
565
+ events,
566
+ };
567
+ }
508
568
  export async function createContextStep(params) {
509
569
  "use step";
510
570
  const { runtime } = await getRuntimeAndEnv(params);
@@ -540,54 +600,151 @@ export async function updateContextStep(params) {
540
600
  stepId: String(params.stepId),
541
601
  payload: {
542
602
  status: params.patch.status,
543
- kind: params.patch.kind,
544
- actionName: params.patch.actionName,
545
- actionInput: params.patch.actionInput,
546
- actionOutput: params.patch.actionOutput,
547
- actionError: params.patch.actionError,
548
603
  iteration: params.iteration,
549
- actionRequests: params.patch.actionRequests,
550
- actionResults: params.patch.actionResults,
551
- continueLoop: params.patch.continueLoop,
552
604
  errorText: params.patch.errorText,
553
605
  },
554
606
  },
555
607
  ]);
556
608
  }
557
609
  }
610
+ export async function completeExecutionStep(params) {
611
+ "use step";
612
+ const { runtime, env } = await getRuntimeAndEnv(params);
613
+ const { store, db } = runtime;
614
+ const actionResultChunkEvents = await writeActionResultPartChunksToSession({
615
+ session: params.session,
616
+ contextId: String(params.contextId ?? ""),
617
+ executionId: String(params.executionId ?? ""),
618
+ itemId: String(params.reactionEventId ?? ""),
619
+ actionResults: params.actionResults ?? [],
620
+ });
621
+ if (params.parts) {
622
+ await store.saveStepParts({ stepId: params.stepId, parts: params.parts });
623
+ }
624
+ if (params.session) {
625
+ await finalizePersistedContextStepStreamForRuntime({
626
+ runtime,
627
+ session: params.session,
628
+ mode: "close",
629
+ });
630
+ }
631
+ await store.updateStep(params.stepId, {
632
+ status: params.stepStatus ?? "completed",
633
+ ...(params.errorText !== undefined ? { errorText: params.errorText } : {}),
634
+ updatedAt: new Date(),
635
+ });
636
+ let savedReaction;
637
+ if (params.reactionEventId && params.reactionEvent) {
638
+ savedReaction = await store.updateItem(params.reactionEventId, params.reactionEvent);
639
+ }
640
+ const { runId } = await resolveWorkflowRunId({
641
+ env,
642
+ db,
643
+ executionId: params.executionId,
644
+ });
645
+ if (runId) {
646
+ const events = [
647
+ {
648
+ workflowRunId: runId,
649
+ eventId: `context_step:${String(params.stepId)}`,
650
+ eventKind: "context.step",
651
+ eventAt: new Date().toISOString(),
652
+ contextId: params.contextId,
653
+ executionId: params.executionId,
654
+ stepId: String(params.stepId),
655
+ payload: {
656
+ status: params.stepStatus ?? "completed",
657
+ iteration: params.iteration,
658
+ errorText: params.errorText,
659
+ },
660
+ },
661
+ ];
662
+ if (params.parts?.length) {
663
+ for (let idx = 0; idx < params.parts.length; idx += 1) {
664
+ const part = params.parts[idx];
665
+ events.push({
666
+ workflowRunId: runId,
667
+ eventId: `context_part:${String(params.stepId)}:${idx}`,
668
+ eventKind: "context.part",
669
+ eventAt: new Date().toISOString(),
670
+ contextId: params.contextId,
671
+ executionId: params.executionId,
672
+ stepId: String(params.stepId),
673
+ partKey: `${String(params.stepId)}:${idx}`,
674
+ partIdx: idx,
675
+ payload: part,
676
+ });
677
+ }
678
+ }
679
+ if (savedReaction) {
680
+ events.push({
681
+ workflowRunId: runId,
682
+ eventId: `context_item:${String(savedReaction.id)}`,
683
+ eventKind: "context.item",
684
+ eventAt: new Date().toISOString(),
685
+ contextId: params.contextId,
686
+ executionId: params.executionId,
687
+ contextEventId: String(savedReaction.id),
688
+ payload: {
689
+ ...savedReaction,
690
+ direction: inferDirection(savedReaction),
691
+ },
692
+ });
693
+ }
694
+ await maybeWriteTraceEvents(env, events);
695
+ }
696
+ return { reactionEvent: savedReaction, actionResultChunkEvents };
697
+ }
558
698
  export async function linkItemToExecutionStep(params) {
559
699
  "use step";
560
700
  const { runtime } = await getRuntimeAndEnv(params);
561
701
  const { store } = runtime;
562
702
  await store.linkItemToExecution({ itemId: params.itemId, executionId: params.executionId });
563
703
  }
564
- export async function saveContextPartsStep(params) {
704
+ export async function saveExecutionStepOutput(params) {
565
705
  "use step";
566
706
  const { runtime, env } = await getRuntimeAndEnv(params);
567
707
  const { store, db } = runtime;
568
708
  await store.saveStepParts({ stepId: params.stepId, parts: params.parts });
709
+ const savedReaction = await store.updateItem(params.reactionEventId, params.reactionEvent);
569
710
  const { runId } = await resolveWorkflowRunId({
570
711
  env,
571
712
  db,
572
713
  executionId: params.executionId,
573
714
  });
574
- if (runId && params.parts?.length) {
715
+ if (runId) {
575
716
  const events = [];
576
- for (let idx = 0; idx < params.parts.length; idx += 1) {
577
- const part = params.parts[idx];
578
- events.push({
579
- workflowRunId: runId,
580
- eventId: `context_part:${String(params.stepId)}:${idx}`,
581
- eventKind: "context.part",
582
- eventAt: new Date().toISOString(),
583
- contextId: params.contextId,
584
- executionId: params.executionId,
585
- stepId: String(params.stepId),
586
- partKey: `${String(params.stepId)}:${idx}`,
587
- partIdx: idx,
588
- payload: part,
589
- });
717
+ if (params.parts?.length) {
718
+ for (let idx = 0; idx < params.parts.length; idx += 1) {
719
+ const part = params.parts[idx];
720
+ events.push({
721
+ workflowRunId: runId,
722
+ eventId: `context_part:${String(params.stepId)}:${idx}`,
723
+ eventKind: "context.part",
724
+ eventAt: new Date().toISOString(),
725
+ contextId: params.contextId,
726
+ executionId: params.executionId,
727
+ stepId: String(params.stepId),
728
+ partKey: `${String(params.stepId)}:${idx}`,
729
+ partIdx: idx,
730
+ payload: part,
731
+ });
732
+ }
590
733
  }
734
+ events.push({
735
+ workflowRunId: runId,
736
+ eventId: `context_item:${String(savedReaction.id)}`,
737
+ eventKind: "context.item",
738
+ eventAt: new Date().toISOString(),
739
+ contextId: params.contextId,
740
+ executionId: params.executionId,
741
+ contextEventId: String(savedReaction.id),
742
+ payload: {
743
+ ...savedReaction,
744
+ direction: inferDirection(savedReaction),
745
+ },
746
+ });
591
747
  await maybeWriteTraceEvents(env, events);
592
748
  }
749
+ return { reactionEvent: savedReaction };
593
750
  }
@@ -20,12 +20,27 @@ export type PersistedContextStepStreamSession = {
20
20
  executionId: string;
21
21
  stepId: string;
22
22
  };
23
+ export declare function createPersistedContextStepStreamForRuntime(runtime: {
24
+ db?: any;
25
+ }, params: {
26
+ executionId: string;
27
+ stepId: string;
28
+ clientId?: string;
29
+ }): Promise<PersistedContextStepStreamSession>;
23
30
  export declare function createPersistedContextStepStream(params: {
24
31
  runtime: ContextRuntime<ContextEnvironment>;
25
32
  executionId: string;
26
33
  stepId: string;
27
34
  clientId?: string;
28
35
  }): Promise<PersistedContextStepStreamSession>;
36
+ export declare function finalizePersistedContextStepStreamForRuntime(params: {
37
+ runtime: {
38
+ db?: any;
39
+ };
40
+ session: PersistedContextStepStreamSession;
41
+ mode: "close" | "abort";
42
+ abortReason?: string | null;
43
+ }): Promise<void>;
29
44
  export declare function closePersistedContextStepStream(params: {
30
45
  runtime: ContextRuntime<ContextEnvironment>;
31
46
  session: PersistedContextStepStreamSession;
@@ -35,6 +50,23 @@ export declare function abortPersistedContextStepStream(params: {
35
50
  session: PersistedContextStepStreamSession;
36
51
  reason?: string | null;
37
52
  }): Promise<void>;
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: {
64
+ session?: PersistedContextStepStreamSession | null;
65
+ contextId: string;
66
+ executionId: string;
67
+ itemId: string;
68
+ actionResults: ContextActionResultForStream[];
69
+ }): Promise<ContextStreamEvent[]>;
38
70
  export declare function readPersistedContextStepStream(params: {
39
71
  db: any;
40
72
  clientId?: string;
@@ -1,5 +1,6 @@
1
1
  import { getContextRuntimeServices } from "../context.runtime.js";
2
- import { contextStreamByteLength, parseContextStepStreamChunk, } from "../context.step-stream.js";
2
+ import { createContextStepStreamChunk, contextStreamByteLength, encodeContextStepStreamChunk, parseContextStepStreamChunk, } from "../context.step-stream.js";
3
+ import { resolveContextPartChunkIdentity } from "../context.part-identity.js";
3
4
  export async function writeContextEvents(params) {
4
5
  "use step";
5
6
  const writable = params.writable;
@@ -48,6 +49,19 @@ function asRecord(value) {
48
49
  function asString(value) {
49
50
  return typeof value === "string" ? value.trim() : "";
50
51
  }
52
+ function toJsonSafeRecord(value) {
53
+ if (typeof value === "undefined")
54
+ return undefined;
55
+ try {
56
+ const json = JSON.parse(JSON.stringify(value));
57
+ return json && typeof json === "object"
58
+ ? json
59
+ : { value: json };
60
+ }
61
+ catch {
62
+ return undefined;
63
+ }
64
+ }
51
65
  function createUnsetStreamLinkTx(db, executionId, label, streamId) {
52
66
  try {
53
67
  return db.tx.event_executions[executionId].unlink({ [label]: streamId });
@@ -63,9 +77,7 @@ export function createContextStepStreamClientId(stepId) {
63
77
  }
64
78
  return `event-step:${normalized}`;
65
79
  }
66
- export async function createPersistedContextStepStream(params) {
67
- "use step";
68
- const runtime = await getContextRuntimeServices(params.runtime);
80
+ export async function createPersistedContextStepStreamForRuntime(runtime, params) {
69
81
  const db = runtime?.db;
70
82
  if (!db?.streams?.createWriteStream) {
71
83
  throw new Error("InstantDB streams are not available on the configured runtime. Upgrade @instantdb/admin to a streams-capable version.");
@@ -105,10 +117,13 @@ export async function createPersistedContextStepStream(params) {
105
117
  stepId: params.stepId,
106
118
  };
107
119
  }
108
- async function finalizePersistedContextStepStream(params) {
120
+ export async function createPersistedContextStepStream(params) {
109
121
  "use step";
110
122
  const runtime = await getContextRuntimeServices(params.runtime);
111
- const db = runtime?.db;
123
+ return await createPersistedContextStepStreamForRuntime(runtime, params);
124
+ }
125
+ export async function finalizePersistedContextStepStreamForRuntime(params) {
126
+ const db = params.runtime?.db;
112
127
  const writer = params.session.stream.getWriter();
113
128
  try {
114
129
  if (params.mode === "abort") {
@@ -143,6 +158,16 @@ async function finalizePersistedContextStepStream(params) {
143
158
  txs.push(unsetActive);
144
159
  await db.transact(txs);
145
160
  }
161
+ async function finalizePersistedContextStepStream(params) {
162
+ "use step";
163
+ const runtime = await getContextRuntimeServices(params.runtime);
164
+ return await finalizePersistedContextStepStreamForRuntime({
165
+ runtime,
166
+ session: params.session,
167
+ mode: params.mode,
168
+ abortReason: params.abortReason,
169
+ });
170
+ }
146
171
  export async function closePersistedContextStepStream(params) {
147
172
  return await finalizePersistedContextStepStream({
148
173
  runtime: params.runtime,
@@ -158,6 +183,99 @@ export async function abortPersistedContextStepStream(params) {
158
183
  abortReason: params.reason,
159
184
  });
160
185
  }
186
+ export async function writeActionResultPartChunksToSession(params) {
187
+ if (!params.session || params.actionResults.length === 0)
188
+ return [];
189
+ const writer = params.session.stream.getWriter();
190
+ const events = [];
191
+ const sequenceBase = Date.now();
192
+ try {
193
+ for (let index = 0; index < params.actionResults.length; index += 1) {
194
+ const result = params.actionResults[index];
195
+ const actionRef = String(result.actionRequest.actionRef || "");
196
+ const actionName = String(result.actionRequest.actionName || "");
197
+ if (!actionRef || !actionName)
198
+ continue;
199
+ const chunkType = result.success
200
+ ? "chunk.action_completed"
201
+ : "chunk.action_failed";
202
+ const identity = resolveContextPartChunkIdentity({
203
+ stepId: params.session.stepId,
204
+ provider: "ekairos",
205
+ providerPartId: actionRef,
206
+ chunkType,
207
+ });
208
+ if (!identity)
209
+ continue;
210
+ const data = result.success
211
+ ? {
212
+ actionRef,
213
+ actionCallId: actionRef,
214
+ actionName,
215
+ toolCallId: actionRef,
216
+ toolName: actionName,
217
+ output: toJsonSafeRecord(result.output),
218
+ }
219
+ : {
220
+ actionRef,
221
+ actionCallId: actionRef,
222
+ actionName,
223
+ toolCallId: actionRef,
224
+ toolName: actionName,
225
+ error: {
226
+ message: String(result.errorText || "Action failed."),
227
+ },
228
+ };
229
+ const at = new Date().toISOString();
230
+ const sequence = sequenceBase + index;
231
+ const persistedChunk = createContextStepStreamChunk({
232
+ at,
233
+ sequence,
234
+ chunkType,
235
+ stepId: params.session.stepId,
236
+ partId: identity.partId,
237
+ providerPartId: identity.providerPartId,
238
+ partType: identity.partType,
239
+ partSlot: identity.partSlot,
240
+ provider: "ekairos",
241
+ providerChunkType: result.success
242
+ ? "action_completed"
243
+ : "action_failed",
244
+ actionRef,
245
+ data,
246
+ });
247
+ await writer.write(encodeContextStepStreamChunk(persistedChunk, {
248
+ stepId: params.session.stepId,
249
+ }));
250
+ events.push({
251
+ type: "chunk.emitted",
252
+ at,
253
+ chunkType,
254
+ contextId: params.contextId,
255
+ executionId: params.executionId,
256
+ stepId: params.session.stepId,
257
+ itemId: params.itemId,
258
+ sequence,
259
+ provider: "ekairos",
260
+ providerChunkType: result.success
261
+ ? "action_completed"
262
+ : "action_failed",
263
+ actionRef,
264
+ partId: identity.partId,
265
+ providerPartId: identity.providerPartId,
266
+ partType: identity.partType,
267
+ partSlot: identity.partSlot,
268
+ data,
269
+ });
270
+ }
271
+ }
272
+ finally {
273
+ if (typeof writer?.releaseLock === "function") {
274
+ writer.releaseLock();
275
+ }
276
+ }
277
+ return events;
278
+ }
161
279
  export async function readPersistedContextStepStream(params) {
162
280
  if (!params.db?.streams?.createReadStream) {
163
281
  throw new Error("InstantDB streams are not available on the provided runtime.");
@@ -1,6 +1,6 @@
1
1
  import "../polyfills/dom-events.js";
2
2
  import type { ContextEnvironment } from "../context.config.js";
3
- import type { ContextRuntime } from "../context.runtime.js";
3
+ import type { ContextRuntimeServiceHandle } from "../context.runtime.js";
4
4
  import type { TraceEventKind } from "../context.contract.js";
5
5
  export type ContextTraceEventWrite = {
6
6
  workflowRunId: string;
@@ -33,8 +33,8 @@ export type ContextTraceEventWrite = {
33
33
  payload?: unknown;
34
34
  testId?: string;
35
35
  };
36
- export declare function writeContextTraceEvents(params: {
37
- runtime?: ContextRuntime<ContextEnvironment>;
38
- env: ContextEnvironment;
36
+ export declare function writeContextTraceEvents<Env extends ContextEnvironment = ContextEnvironment>(params: {
37
+ runtime?: ContextRuntimeServiceHandle;
38
+ env?: Env;
39
39
  events: ContextTraceEventWrite[];
40
40
  }): Promise<void>;
@@ -18,6 +18,20 @@ function requireToken() {
18
18
  throw new Error("[context/trace] Missing EKAIROS_CLERK_API_KEY");
19
19
  }
20
20
  let jwtCache = null;
21
+ function asRecord(value) {
22
+ return value && typeof value === "object" ? value : {};
23
+ }
24
+ function asTraceEnv(value) {
25
+ const record = asRecord(value);
26
+ if (Object.keys(record).length === 0)
27
+ return undefined;
28
+ return {
29
+ baseUrl: typeof record.baseUrl === "string" ? record.baseUrl : undefined,
30
+ apiKey: typeof record.apiKey === "string" ? record.apiKey : undefined,
31
+ projectId: typeof record.projectId === "string" ? record.projectId : undefined,
32
+ strict: record.strict === true,
33
+ };
34
+ }
21
35
  function parseJwtExpMs(token) {
22
36
  const parts = token.split(".");
23
37
  if (parts.length !== 3)
@@ -47,8 +61,8 @@ async function getTraceAuthHeader(baseUrl, projectId) {
47
61
  body: JSON.stringify({ projectId }),
48
62
  });
49
63
  if (res.ok) {
50
- const json = (await res.json());
51
- const token = typeof json?.token === "string" ? json.token : "";
64
+ const json = asRecord(await res.json());
65
+ const token = typeof json.token === "string" ? json.token : "";
52
66
  const expMs = parseJwtExpMs(token) ?? now + 60 * 60 * 1000;
53
67
  if (token) {
54
68
  jwtCache = { token, expMs };
@@ -79,7 +93,8 @@ async function readProjectId() {
79
93
  export async function writeContextTraceEvents(params) {
80
94
  if (!params.events?.length)
81
95
  return;
82
- const envTrace = params.env?.traces;
96
+ const envRecord = asRecord(params.env);
97
+ const envTrace = asTraceEnv(envRecord.traces);
83
98
  // Tracing must NEVER break workflows by default.
84
99
  // Use EKAIROS_TRACES_STRICT=1 if you want to fail hard.
85
100
  const strict = envTrace?.strict === true || process.env.EKAIROS_TRACES_STRICT === "1";
@@ -89,11 +104,11 @@ export async function writeContextTraceEvents(params) {
89
104
  throw new Error("[context/trace] runtime is required");
90
105
  }
91
106
  const runtime = await getContextRuntimeServices(params.runtime);
92
- const db = runtime?.db;
107
+ const db = runtime.db;
93
108
  if (db) {
94
109
  const now = new Date();
95
- const orgId = typeof params.env?.orgId === "string"
96
- ? String(params.env.orgId)
110
+ const orgId = typeof envRecord.orgId === "string"
111
+ ? String(envRecord.orgId)
97
112
  : "";
98
113
  const projectId = await readProjectId();
99
114
  const byRun = new Map();