@ekairos/events 1.22.34-beta.development.0 → 1.22.35-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.
@@ -1,6 +1,12 @@
1
+ import { getContextRuntimeServices } from "../context.runtime.js";
1
2
  import { OUTPUT_ITEM_TYPE, WEB_CHANNEL } from "../context.events.js";
2
3
  import { writeContextTraceEvents } from "./trace.steps.js";
3
4
  import { getClientResumeHookUrl, toolApprovalHookToken, toolApprovalWebhookToken, } from "../context.hooks.js";
5
+ async function getRuntimeAndEnv(params) {
6
+ const env = params.runtime.env;
7
+ const runtime = await getContextRuntimeServices(params.runtime);
8
+ return { runtime, env };
9
+ }
4
10
  async function maybeWriteTraceEvents(env, traceEvents) {
5
11
  if (!traceEvents?.length)
6
12
  return;
@@ -92,24 +98,23 @@ function logStepDebug(message, payload) {
92
98
  *
93
99
  * This is the "context init" boundary for the story engine.
94
100
  */
95
- export async function initializeContext(env, contextIdentifier, opts) {
101
+ export async function initializeContext(params) {
96
102
  "use step";
97
- const { getContextRuntime } = await import("../runtime.js");
98
- const runtime = await getContextRuntime(env);
103
+ const { runtime, env } = await getRuntimeAndEnv(params);
99
104
  const { store, db } = runtime;
100
105
  // Detect creation explicitly so the engine can run onContextCreated hooks.
101
106
  let result;
102
- if (!contextIdentifier) {
107
+ if (!params.contextIdentifier) {
103
108
  const context = await store.getOrCreateContext(null);
104
109
  result = { context, isNew: true };
105
110
  }
106
111
  else {
107
- const existing = await store.getContext(contextIdentifier);
112
+ const existing = await store.getContext(params.contextIdentifier);
108
113
  if (existing) {
109
114
  result = { context: existing, isNew: false };
110
115
  }
111
116
  else {
112
- const created = await store.getOrCreateContext(contextIdentifier);
117
+ const created = await store.getOrCreateContext(params.contextIdentifier);
113
118
  result = { context: created, isNew: true };
114
119
  }
115
120
  }
@@ -132,29 +137,29 @@ export async function initializeContext(env, contextIdentifier, opts) {
132
137
  }
133
138
  return result;
134
139
  }
135
- export async function updateContextContent(env, contextIdentifier, content) {
140
+ export async function updateContextContent(params) {
136
141
  "use step";
137
- const { getContextRuntime } = await import("../runtime.js");
138
- const { store } = await getContextRuntime(env);
139
- return await store.updateContextContent(contextIdentifier, content);
142
+ const { runtime } = await getRuntimeAndEnv(params);
143
+ return await runtime.store.updateContextContent(params.contextIdentifier, params.content);
140
144
  }
141
- export async function updateContextStatus(env, contextIdentifier, status) {
145
+ export async function updateContextReactor(params) {
142
146
  "use step";
143
- const { getContextRuntime } = await import("../runtime.js");
144
- const { store } = await getContextRuntime(env);
145
- await store.updateContextStatus(contextIdentifier, status);
147
+ const { runtime } = await getRuntimeAndEnv(params);
148
+ return await runtime.store.updateContextReactor(params.contextIdentifier, params.reactor);
146
149
  }
147
- export async function saveTriggerItem(env, contextIdentifier, event) {
150
+ export async function updateContextStatus(params) {
148
151
  "use step";
149
- const { getContextRuntime } = await import("../runtime.js");
150
- const { store } = await getContextRuntime(env);
151
- const saved = await store.saveItem(contextIdentifier, event);
152
- return saved;
152
+ const { runtime } = await getRuntimeAndEnv(params);
153
+ await runtime.store.updateContextStatus(params.contextIdentifier, params.status);
154
+ }
155
+ export async function saveTriggerItem(params) {
156
+ "use step";
157
+ const { runtime } = await getRuntimeAndEnv(params);
158
+ return await runtime.store.saveItem(params.contextIdentifier, params.event);
153
159
  }
154
160
  export async function saveTriggerAndCreateExecution(params) {
155
161
  "use step";
156
- const { getContextRuntime } = await import("../runtime.js");
157
- const runtime = await getContextRuntime(params.env);
162
+ const { runtime, env } = await getRuntimeAndEnv(params);
158
163
  const { store, db } = runtime;
159
164
  logStepDebug("saveTriggerAndCreateExecution:start", {
160
165
  contextIdentifier: summarizeContextIdentifierForLog(params.contextIdentifier),
@@ -241,7 +246,7 @@ export async function saveTriggerAndCreateExecution(params) {
241
246
  throw error;
242
247
  }
243
248
  const { runId, meta } = await resolveWorkflowRunId({
244
- env: params.env,
249
+ env,
245
250
  db,
246
251
  executionId: execution.id,
247
252
  });
@@ -329,7 +334,7 @@ export async function saveTriggerAndCreateExecution(params) {
329
334
  },
330
335
  },
331
336
  ];
332
- await maybeWriteTraceEvents(params.env, events);
337
+ await maybeWriteTraceEvents(env, events);
333
338
  }
334
339
  return {
335
340
  triggerEvent: saved,
@@ -340,26 +345,25 @@ export async function saveTriggerAndCreateExecution(params) {
340
345
  },
341
346
  };
342
347
  }
343
- export async function saveReactionItem(env, contextIdentifier, event, opts) {
348
+ export async function saveReactionItem(params) {
344
349
  "use step";
345
- const { getContextRuntime } = await import("../runtime.js");
346
- const runtime = await getContextRuntime(env);
350
+ const { runtime, env } = await getRuntimeAndEnv(params);
347
351
  const { store, db } = runtime;
348
- const saved = await store.saveItem(contextIdentifier, event);
349
- if (opts?.executionId) {
352
+ const saved = await store.saveItem(params.contextIdentifier, params.event);
353
+ if (params.opts?.executionId) {
350
354
  await store.linkItemToExecution({
351
355
  itemId: saved.id,
352
- executionId: opts.executionId,
356
+ executionId: params.opts.executionId,
353
357
  });
354
358
  }
355
- const contextId = opts?.contextId ??
356
- (typeof contextIdentifier?.id === "string"
357
- ? String(contextIdentifier.id)
359
+ const contextId = params.opts?.contextId ??
360
+ (typeof params.contextIdentifier?.id === "string"
361
+ ? String(params.contextIdentifier.id)
358
362
  : undefined);
359
363
  const { runId, meta } = await resolveWorkflowRunId({
360
364
  env,
361
365
  db,
362
- executionId: opts?.executionId,
366
+ executionId: params.opts?.executionId,
363
367
  });
364
368
  if (runId) {
365
369
  const events = [
@@ -369,7 +373,7 @@ export async function saveReactionItem(env, contextIdentifier, event, opts) {
369
373
  eventKind: "context.item",
370
374
  eventAt: new Date().toISOString(),
371
375
  contextId,
372
- executionId: opts?.executionId,
376
+ executionId: params.opts?.executionId,
373
377
  contextEventId: String(saved.id),
374
378
  payload: {
375
379
  ...saved,
@@ -377,30 +381,30 @@ export async function saveReactionItem(env, contextIdentifier, event, opts) {
377
381
  },
378
382
  },
379
383
  ];
380
- if (opts?.executionId && opts.reviewRequests?.length) {
384
+ if (params.opts?.executionId && params.opts.reviewRequests?.length) {
381
385
  const resumeHookUrl = getClientResumeHookUrl();
382
386
  const workflowUrl = meta && typeof meta.url === "string" && meta.url.trim()
383
387
  ? String(meta.url)
384
388
  : undefined;
385
- for (const rr of opts.reviewRequests) {
389
+ for (const rr of params.opts.reviewRequests) {
386
390
  const toolCallId = String(rr.toolCallId);
387
391
  events.push({
388
392
  workflowRunId: runId,
389
- eventId: `context_review:${String(opts.executionId)}:${toolCallId}`,
393
+ eventId: `context_review:${String(params.opts.executionId)}:${toolCallId}`,
390
394
  eventKind: "context.review",
391
395
  eventAt: new Date().toISOString(),
392
396
  contextId,
393
- executionId: String(opts.executionId),
397
+ executionId: String(params.opts.executionId),
394
398
  toolCallId,
395
399
  payload: {
396
400
  status: "in_review",
397
401
  toolName: rr.toolName ?? "",
398
402
  hookToken: toolApprovalHookToken({
399
- executionId: String(opts.executionId),
403
+ executionId: String(params.opts.executionId),
400
404
  toolCallId,
401
405
  }),
402
406
  webhookToken: toolApprovalWebhookToken({
403
- executionId: String(opts.executionId),
407
+ executionId: String(params.opts.executionId),
404
408
  toolCallId,
405
409
  }),
406
410
  resumeHookUrl,
@@ -413,16 +417,15 @@ export async function saveReactionItem(env, contextIdentifier, event, opts) {
413
417
  }
414
418
  return saved;
415
419
  }
416
- export async function updateItem(env, eventId, event, opts) {
420
+ export async function updateItem(params) {
417
421
  "use step";
418
- const { getContextRuntime } = await import("../runtime.js");
419
- const runtime = await getContextRuntime(env);
422
+ const { runtime, env } = await getRuntimeAndEnv(params);
420
423
  const { store, db } = runtime;
421
- const saved = await store.updateItem(eventId, event);
424
+ const saved = await store.updateItem(params.eventId, params.event);
422
425
  const { runId } = await resolveWorkflowRunId({
423
426
  env,
424
427
  db,
425
- executionId: opts?.executionId,
428
+ executionId: params.opts?.executionId,
426
429
  });
427
430
  if (runId) {
428
431
  await maybeWriteTraceEvents(env, [
@@ -431,8 +434,8 @@ export async function updateItem(env, eventId, event, opts) {
431
434
  eventId: `context_item:${String(saved.id)}`,
432
435
  eventKind: "context.item",
433
436
  eventAt: new Date().toISOString(),
434
- contextId: opts?.contextId,
435
- executionId: opts?.executionId,
437
+ contextId: params.opts?.contextId,
438
+ executionId: params.opts?.executionId,
436
439
  contextEventId: String(saved.id),
437
440
  payload: {
438
441
  ...saved,
@@ -443,16 +446,15 @@ export async function updateItem(env, eventId, event, opts) {
443
446
  }
444
447
  return saved;
445
448
  }
446
- export async function createExecution(env, contextIdentifier, triggerEventId, reactionEventId) {
449
+ export async function createExecution(params) {
447
450
  "use step";
448
- const { getContextRuntime } = await import("../runtime.js");
449
- const { store } = await getContextRuntime(env);
450
- return await store.createExecution(contextIdentifier, triggerEventId, reactionEventId);
451
+ const { runtime } = await getRuntimeAndEnv(params);
452
+ return await runtime.store.createExecution(params.contextIdentifier, params.triggerEventId, params.reactionEventId);
451
453
  }
452
454
  export async function createReactionItem(params) {
453
455
  "use step";
454
- const { getContextRuntime } = await import("../runtime.js");
455
- const { store } = await getContextRuntime(params.env);
456
+ const { runtime } = await getRuntimeAndEnv(params);
457
+ const { store } = runtime;
456
458
  // Generate a new reaction event id inside the step boundary.
457
459
  const uuid = globalThis.crypto?.randomUUID?.();
458
460
  const reactionEventId = typeof uuid === "string"
@@ -461,31 +463,30 @@ export async function createReactionItem(params) {
461
463
  const execution = await store.createExecution(params.contextIdentifier, params.triggerEventId, reactionEventId);
462
464
  return { reactionEventId, executionId: execution.id };
463
465
  }
464
- export async function completeExecution(env, contextIdentifier, executionId, status) {
466
+ export async function completeExecution(params) {
465
467
  "use step";
466
- const { getContextRuntime } = await import("../runtime.js");
467
- const runtime = await getContextRuntime(env);
468
+ const { runtime, env } = await getRuntimeAndEnv(params);
468
469
  const { store, db } = runtime;
469
- await store.completeExecution(contextIdentifier, executionId, status);
470
- const contextId = typeof contextIdentifier?.id === "string"
471
- ? String(contextIdentifier.id)
470
+ await store.completeExecution(params.contextIdentifier, params.executionId, params.status);
471
+ const contextId = typeof params.contextIdentifier?.id === "string"
472
+ ? String(params.contextIdentifier.id)
472
473
  : undefined;
473
474
  const { runId } = await resolveWorkflowRunId({
474
475
  env,
475
476
  db,
476
- executionId,
477
+ executionId: params.executionId,
477
478
  });
478
479
  if (runId) {
479
480
  await maybeWriteTraceEvents(env, [
480
481
  {
481
482
  workflowRunId: runId,
482
- eventId: `context_execution:${String(executionId)}:${status}`,
483
+ eventId: `context_execution:${String(params.executionId)}:${params.status}`,
483
484
  eventKind: "context.execution",
484
485
  eventAt: new Date().toISOString(),
485
486
  contextId,
486
- executionId: String(executionId),
487
+ executionId: String(params.executionId),
487
488
  payload: {
488
- status,
489
+ status: params.status,
489
490
  },
490
491
  },
491
492
  ]);
@@ -493,9 +494,8 @@ export async function completeExecution(env, contextIdentifier, executionId, sta
493
494
  }
494
495
  export async function updateExecutionWorkflowRun(params) {
495
496
  "use step";
496
- const { getContextRuntime } = await import("../runtime.js");
497
- const runtime = await getContextRuntime(params.env);
498
- const db = runtime?.db;
497
+ const { runtime } = await getRuntimeAndEnv(params);
498
+ const db = runtime.db;
499
499
  if (db) {
500
500
  await db.transact([
501
501
  db.tx.event_executions[params.executionId].update({
@@ -507,8 +507,8 @@ export async function updateExecutionWorkflowRun(params) {
507
507
  }
508
508
  export async function createContextStep(params) {
509
509
  "use step";
510
- const { getContextRuntime } = await import("../runtime.js");
511
- const { store } = await getContextRuntime(params.env);
510
+ const { runtime } = await getRuntimeAndEnv(params);
511
+ const { store } = runtime;
512
512
  const res = await store.createStep({
513
513
  executionId: params.executionId,
514
514
  iteration: params.iteration,
@@ -517,20 +517,19 @@ export async function createContextStep(params) {
517
517
  }
518
518
  export async function updateContextStep(params) {
519
519
  "use step";
520
- const { getContextRuntime } = await import("../runtime.js");
521
- const runtime = await getContextRuntime(params.env);
520
+ const { runtime, env } = await getRuntimeAndEnv(params);
522
521
  const { store, db } = runtime;
523
522
  await store.updateStep(params.stepId, {
524
523
  ...params.patch,
525
524
  updatedAt: new Date(),
526
525
  });
527
526
  const { runId } = await resolveWorkflowRunId({
528
- env: params.env,
527
+ env,
529
528
  db,
530
529
  executionId: params.executionId,
531
530
  });
532
531
  if (runId) {
533
- await maybeWriteTraceEvents(params.env, [
532
+ await maybeWriteTraceEvents(env, [
534
533
  {
535
534
  workflowRunId: runId,
536
535
  eventId: `context_step:${String(params.stepId)}`,
@@ -558,18 +557,17 @@ export async function updateContextStep(params) {
558
557
  }
559
558
  export async function linkItemToExecutionStep(params) {
560
559
  "use step";
561
- const { getContextRuntime } = await import("../runtime.js");
562
- const { store } = await getContextRuntime(params.env);
560
+ const { runtime } = await getRuntimeAndEnv(params);
561
+ const { store } = runtime;
563
562
  await store.linkItemToExecution({ itemId: params.itemId, executionId: params.executionId });
564
563
  }
565
564
  export async function saveContextPartsStep(params) {
566
565
  "use step";
567
- const { getContextRuntime } = await import("../runtime.js");
568
- const runtime = await getContextRuntime(params.env);
566
+ const { runtime, env } = await getRuntimeAndEnv(params);
569
567
  const { store, db } = runtime;
570
568
  await store.saveStepParts({ stepId: params.stepId, parts: params.parts });
571
569
  const { runId } = await resolveWorkflowRunId({
572
- env: params.env,
570
+ env,
573
571
  db,
574
572
  executionId: params.executionId,
575
573
  });
@@ -590,6 +588,6 @@ export async function saveContextPartsStep(params) {
590
588
  payload: part,
591
589
  });
592
590
  }
593
- await maybeWriteTraceEvents(params.env, events);
591
+ await maybeWriteTraceEvents(env, events);
594
592
  }
595
593
  }
@@ -1,5 +1,6 @@
1
1
  import type { UIMessageChunk } from "ai";
2
2
  import type { ContextEnvironment } from "../context.config.js";
3
+ import type { ContextRuntime } from "../context.runtime.js";
3
4
  import { type ContextStepStreamChunk } from "../context.step-stream.js";
4
5
  import type { ContextStreamEvent } from "../context.stream.js";
5
6
  export declare function writeContextEvents(params: {
@@ -20,17 +21,17 @@ export type PersistedContextStepStreamSession = {
20
21
  stepId: string;
21
22
  };
22
23
  export declare function createPersistedContextStepStream(params: {
23
- env: ContextEnvironment;
24
+ runtime: ContextRuntime<ContextEnvironment>;
24
25
  executionId: string;
25
26
  stepId: string;
26
27
  clientId?: string;
27
28
  }): Promise<PersistedContextStepStreamSession>;
28
29
  export declare function closePersistedContextStepStream(params: {
29
- env: ContextEnvironment;
30
+ runtime: ContextRuntime<ContextEnvironment>;
30
31
  session: PersistedContextStepStreamSession;
31
32
  }): Promise<void>;
32
33
  export declare function abortPersistedContextStepStream(params: {
33
- env: ContextEnvironment;
34
+ runtime: ContextRuntime<ContextEnvironment>;
34
35
  session: PersistedContextStepStreamSession;
35
36
  reason?: string | null;
36
37
  }): Promise<void>;
@@ -1,3 +1,4 @@
1
+ import { getContextRuntimeServices } from "../context.runtime.js";
1
2
  import { contextStreamByteLength, parseContextStepStreamChunk, } from "../context.step-stream.js";
2
3
  export async function writeContextEvents(params) {
3
4
  "use step";
@@ -14,7 +15,9 @@ export async function writeContextEvents(params) {
14
15
  }
15
16
  }
16
17
  finally {
17
- writer.releaseLock();
18
+ if (typeof writer?.releaseLock === "function") {
19
+ writer.releaseLock();
20
+ }
18
21
  }
19
22
  }
20
23
  export async function closeContextStream(params) {
@@ -30,7 +33,9 @@ export async function closeContextStream(params) {
30
33
  await writer.write({ type: "finish" });
31
34
  }
32
35
  finally {
33
- writer.releaseLock();
36
+ if (typeof writer?.releaseLock === "function") {
37
+ writer.releaseLock();
38
+ }
34
39
  }
35
40
  }
36
41
  if (!preventClose) {
@@ -60,8 +65,7 @@ export function createContextStepStreamClientId(stepId) {
60
65
  }
61
66
  export async function createPersistedContextStepStream(params) {
62
67
  "use step";
63
- const { getContextRuntime } = await import("../runtime.js");
64
- const runtime = await getContextRuntime(params.env);
68
+ const runtime = await getContextRuntimeServices(params.runtime);
65
69
  const db = runtime?.db;
66
70
  if (!db?.streams?.createWriteStream) {
67
71
  throw new Error("InstantDB streams are not available on the configured runtime. Upgrade @instantdb/admin to a streams-capable version.");
@@ -103,8 +107,7 @@ export async function createPersistedContextStepStream(params) {
103
107
  }
104
108
  async function finalizePersistedContextStepStream(params) {
105
109
  "use step";
106
- const { getContextRuntime } = await import("../runtime.js");
107
- const runtime = await getContextRuntime(params.env);
110
+ const runtime = await getContextRuntimeServices(params.runtime);
108
111
  const db = runtime?.db;
109
112
  const writer = params.session.stream.getWriter();
110
113
  try {
@@ -116,7 +119,9 @@ async function finalizePersistedContextStepStream(params) {
116
119
  }
117
120
  }
118
121
  finally {
119
- writer.releaseLock();
122
+ if (typeof writer?.releaseLock === "function") {
123
+ writer.releaseLock();
124
+ }
120
125
  }
121
126
  const now = new Date();
122
127
  const txs = [
@@ -140,14 +145,14 @@ async function finalizePersistedContextStepStream(params) {
140
145
  }
141
146
  export async function closePersistedContextStepStream(params) {
142
147
  return await finalizePersistedContextStepStream({
143
- env: params.env,
148
+ runtime: params.runtime,
144
149
  session: params.session,
145
150
  mode: "close",
146
151
  });
147
152
  }
148
153
  export async function abortPersistedContextStepStream(params) {
149
154
  return await finalizePersistedContextStepStream({
150
- env: params.env,
155
+ runtime: params.runtime,
151
156
  session: params.session,
152
157
  mode: "abort",
153
158
  abortReason: params.reason,
@@ -1,5 +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
4
  import type { TraceEventKind } from "../context.contract.js";
4
5
  export type ContextTraceEventWrite = {
5
6
  workflowRunId: string;
@@ -33,6 +34,7 @@ export type ContextTraceEventWrite = {
33
34
  testId?: string;
34
35
  };
35
36
  export declare function writeContextTraceEvents(params: {
37
+ runtime?: ContextRuntime<ContextEnvironment>;
36
38
  env: ContextEnvironment;
37
39
  events: ContextTraceEventWrite[];
38
40
  }): Promise<void>;
@@ -1,4 +1,5 @@
1
1
  import "../polyfills/dom-events.js";
2
+ import { getContextRuntimeServices } from "../context.runtime.js";
2
3
  import { lookup } from "@instantdb/admin";
3
4
  function requireBaseUrl() {
4
5
  const baseUrl = process.env.EKAIROS_CORE_BASE_URL ||
@@ -84,8 +85,10 @@ export async function writeContextTraceEvents(params) {
84
85
  const strict = envTrace?.strict === true || process.env.EKAIROS_TRACES_STRICT === "1";
85
86
  // 1) Local trace persistence (InstantDB source of truth).
86
87
  try {
87
- const { getContextRuntime } = await import("../runtime.js");
88
- const runtime = await getContextRuntime(params.env);
88
+ if (!params.runtime) {
89
+ throw new Error("[context/trace] runtime is required");
90
+ }
91
+ const runtime = await getContextRuntimeServices(params.runtime);
89
92
  const db = runtime?.db;
90
93
  if (db) {
91
94
  const now = new Date();
@@ -14,6 +14,10 @@ export declare class InstantStore implements ContextStore {
14
14
  getOrCreateContext<C>(contextIdentifier: ContextIdentifier | null): Promise<StoredContext<C>>;
15
15
  getContext<C>(contextIdentifier: ContextIdentifier): Promise<StoredContext<C> | null>;
16
16
  updateContextContent<C>(contextIdentifier: ContextIdentifier, content: C): Promise<StoredContext<C>>;
17
+ updateContextReactor<C>(contextIdentifier: ContextIdentifier, reactor: {
18
+ kind: string;
19
+ state?: Record<string, unknown> | null;
20
+ }): Promise<StoredContext<C>>;
17
21
  updateContextStatus(contextIdentifier: ContextIdentifier, status: ContextStatus): Promise<void>;
18
22
  private resolveContext;
19
23
  saveItem(contextIdentifier: ContextIdentifier, event: ContextItem): Promise<ContextItem>;
@@ -118,6 +118,9 @@ export class InstantStore {
118
118
  ? new Date(row.updatedAt)
119
119
  : undefined,
120
120
  content: row?.content ?? null,
121
+ reactor: row?.reactor && typeof row.reactor === "object"
122
+ ? row.reactor
123
+ : null,
121
124
  };
122
125
  }
123
126
  async ensureContextKey(context, expectedKey) {
@@ -144,6 +147,7 @@ export class InstantStore {
144
147
  key,
145
148
  status: "open_idle",
146
149
  content: {},
150
+ reactor: undefined,
147
151
  }),
148
152
  ]);
149
153
  const context = await this.getContext({ id: contextId });
@@ -203,6 +207,21 @@ export class InstantStore {
203
207
  throw new Error("InstantStore: context not found after update");
204
208
  return updated;
205
209
  }
210
+ async updateContextReactor(contextIdentifier, reactor) {
211
+ const context = await this.getContext(contextIdentifier);
212
+ if (!context?.id)
213
+ throw new Error("InstantStore: context not found");
214
+ await this.db.transact([
215
+ this.db.tx.event_contexts[context.id].update({
216
+ reactor: reactor,
217
+ updatedAt: new Date(),
218
+ }),
219
+ ]);
220
+ const updated = await this.getContext({ id: context.id });
221
+ if (!updated)
222
+ throw new Error("InstantStore: context not found after reactor update");
223
+ return updated;
224
+ }
206
225
  async updateContextStatus(contextIdentifier, status) {
207
226
  const context = await this.getContext(contextIdentifier);
208
227
  if (!context?.id)
@@ -6,14 +6,48 @@ import { type Tool } from "ai";
6
6
  * - Keep Zod/function values out of step arguments
7
7
  * - Convert tool input schemas to plain JSON Schema in workflow context
8
8
  */
9
- export type SerializableToolForModel = {
9
+ export type SerializableFunctionActionSpec = {
10
+ type?: "function";
10
11
  description?: string;
11
12
  inputSchema: unknown;
13
+ providerOptions?: unknown;
12
14
  };
15
+ export type SerializableProviderDefinedActionSpec = {
16
+ type: "provider-defined";
17
+ id: string;
18
+ name?: string;
19
+ args?: Record<string, unknown>;
20
+ };
21
+ export type SerializableActionSpec = SerializableFunctionActionSpec | SerializableProviderDefinedActionSpec;
22
+ /**
23
+ * @deprecated Use SerializableActionSpec.
24
+ */
25
+ export type SerializableToolForModel = SerializableActionSpec;
13
26
  /**
14
27
  * Convert AI SDK tools to a serializable representation that can be passed to `"use-step"` functions.
15
28
  *
16
29
  * This matches DurableAgent's internal `toolsToModelTools` behavior:
17
30
  * `inputSchema: asSchema(tool.inputSchema).jsonSchema`
18
31
  */
19
- export declare function toolsToModelTools(tools: Record<string, Tool>): Record<string, SerializableToolForModel>;
32
+ export declare function actionsToActionSpecs(tools: Record<string, Tool>): Record<string, SerializableActionSpec>;
33
+ export declare function actionSpecToAiSdkTool(name: string, spec: SerializableActionSpec, wrapJsonSchema: (schema: unknown) => unknown): {
34
+ type: "provider-defined";
35
+ id: string;
36
+ name: string;
37
+ args: Record<string, unknown>;
38
+ description?: undefined;
39
+ inputSchema?: undefined;
40
+ providerOptions?: undefined;
41
+ } | {
42
+ type: "function";
43
+ description: string | undefined;
44
+ inputSchema: unknown;
45
+ providerOptions: unknown;
46
+ id?: undefined;
47
+ name?: undefined;
48
+ args?: undefined;
49
+ };
50
+ /**
51
+ * @deprecated Use actionsToActionSpecs.
52
+ */
53
+ export declare const toolsToModelTools: typeof actionsToActionSpecs;
@@ -1,21 +1,59 @@
1
1
  import { asSchema } from "ai";
2
+ function isProviderDefinedTool(tool) {
3
+ return (Boolean(tool) &&
4
+ typeof tool === "object" &&
5
+ tool.type === "provider-defined" &&
6
+ typeof tool.id === "string" &&
7
+ tool.id.trim().length > 0);
8
+ }
2
9
  /**
3
10
  * Convert AI SDK tools to a serializable representation that can be passed to `"use-step"` functions.
4
11
  *
5
12
  * This matches DurableAgent's internal `toolsToModelTools` behavior:
6
13
  * `inputSchema: asSchema(tool.inputSchema).jsonSchema`
7
14
  */
8
- export function toolsToModelTools(tools) {
15
+ export function actionsToActionSpecs(tools) {
9
16
  const out = {};
10
17
  for (const [name, tool] of Object.entries(tools)) {
18
+ if (isProviderDefinedTool(tool)) {
19
+ out[name] = {
20
+ type: "provider-defined",
21
+ id: tool.id,
22
+ name: tool.name,
23
+ args: tool.args,
24
+ };
25
+ continue;
26
+ }
11
27
  const inputSchema = tool?.inputSchema;
12
28
  if (!inputSchema) {
13
29
  throw new Error(`Context: tool "${name}" is missing inputSchema (required for model tool calls)`);
14
30
  }
15
31
  out[name] = {
32
+ type: "function",
16
33
  description: tool?.description,
17
34
  inputSchema: asSchema(inputSchema).jsonSchema,
35
+ providerOptions: tool?.providerOptions,
18
36
  };
19
37
  }
20
38
  return out;
21
39
  }
40
+ export function actionSpecToAiSdkTool(name, spec, wrapJsonSchema) {
41
+ if (spec.type === "provider-defined") {
42
+ return {
43
+ type: "provider-defined",
44
+ id: spec.id,
45
+ name: spec.name ?? name,
46
+ args: spec.args ?? {},
47
+ };
48
+ }
49
+ return {
50
+ type: "function",
51
+ description: spec.description,
52
+ inputSchema: wrapJsonSchema(spec.inputSchema),
53
+ providerOptions: spec.providerOptions,
54
+ };
55
+ }
56
+ /**
57
+ * @deprecated Use actionsToActionSpecs.
58
+ */
59
+ export const toolsToModelTools = actionsToActionSpecs;