@ekairos/structure 1.22.9-beta.feature-registry-sync-esolbay-agent.0 → 1.22.10-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.
@@ -0,0 +1,29 @@
1
+ declare const STRUCTURE_CONTEXT_ENTITIES: readonly ["event_contexts"];
2
+ type StructureContextEntity = (typeof STRUCTURE_CONTEXT_ENTITIES)[number];
3
+ type FindStructureContextParams = {
4
+ includeOutputFile?: boolean;
5
+ };
6
+ type FindStructureContextResult = {
7
+ entity: StructureContextEntity;
8
+ row: any;
9
+ };
10
+ export declare function findStructureContextByKey(db: any, key: string, params?: FindStructureContextParams): Promise<FindStructureContextResult | null>;
11
+ export declare function createStructureContext(db: any, params: {
12
+ id: string;
13
+ key: string;
14
+ content?: Record<string, unknown>;
15
+ status?: string;
16
+ createdAt?: Date;
17
+ }): Promise<{
18
+ entity: "event_contexts";
19
+ id: string;
20
+ }>;
21
+ export declare function linkStructureOutputFileToContextByKey(db: any, params: {
22
+ contextKey: string;
23
+ fileId: string;
24
+ }): Promise<void>;
25
+ export declare function unlinkStructureOutputFileFromContextByKey(db: any, params: {
26
+ contextKey: string;
27
+ fileId: string;
28
+ }): Promise<void>;
29
+ export {};
@@ -0,0 +1,62 @@
1
+ const STRUCTURE_CONTEXT_ENTITIES = ["event_contexts"];
2
+ function buildContextQuery(entity, key, includeOutputFile) {
3
+ return {
4
+ [entity]: {
5
+ $: { where: { key }, limit: 1 },
6
+ ...(includeOutputFile ? { structure_output_file: {} } : {}),
7
+ },
8
+ };
9
+ }
10
+ function preferredContextEntity(db) {
11
+ if (db?.tx?.event_contexts)
12
+ return "event_contexts";
13
+ throw new Error("No persisted context collection is available");
14
+ }
15
+ export async function findStructureContextByKey(db, key, params = {}) {
16
+ let lastError = null;
17
+ let queried = false;
18
+ for (const entity of STRUCTURE_CONTEXT_ENTITIES) {
19
+ try {
20
+ const res = await db.query(buildContextQuery(entity, key, Boolean(params.includeOutputFile)));
21
+ queried = true;
22
+ const row = res?.[entity]?.[0];
23
+ if (row)
24
+ return { entity, row };
25
+ }
26
+ catch (error) {
27
+ lastError = error;
28
+ }
29
+ }
30
+ if (!queried && lastError) {
31
+ throw lastError;
32
+ }
33
+ return null;
34
+ }
35
+ export async function createStructureContext(db, params) {
36
+ const entity = preferredContextEntity(db);
37
+ await db.transact([
38
+ db.tx[entity][params.id].create({
39
+ createdAt: params.createdAt ?? new Date(),
40
+ content: params.content ?? {},
41
+ key: params.key,
42
+ status: params.status ?? "open",
43
+ }),
44
+ ]);
45
+ return { entity, id: params.id };
46
+ }
47
+ export async function linkStructureOutputFileToContextByKey(db, params) {
48
+ const context = await findStructureContextByKey(db, params.contextKey);
49
+ const ctxId = context?.row?.id;
50
+ if (!context || !ctxId) {
51
+ throw new Error("Context not found");
52
+ }
53
+ await db.transact([db.tx[context.entity][ctxId].link({ structure_output_file: params.fileId })]);
54
+ }
55
+ export async function unlinkStructureOutputFileFromContextByKey(db, params) {
56
+ const context = await findStructureContextByKey(db, params.contextKey);
57
+ const ctxId = context?.row?.id;
58
+ if (!context || !ctxId) {
59
+ throw new Error("Context not found");
60
+ }
61
+ await db.transact([db.tx[context.entity][ctxId].unlink({ structure_output_file: params.fileId })]);
62
+ }
@@ -1,8 +1,9 @@
1
+ import { findStructureContextByKey, linkStructureOutputFileToContextByKey, unlinkStructureOutputFileFromContextByKey, } from "../contextPersistence.js";
1
2
  export async function structureGetOrCreateContextStep(params) {
2
3
  "use step";
3
4
  try {
4
- const { getThreadRuntime } = await import("@ekairos/thread/runtime");
5
- const runtime = await getThreadRuntime(params.env);
5
+ const { getContextRuntime } = await import("@ekairos/events/runtime");
6
+ const runtime = await getContextRuntime(params.env);
6
7
  const ctx = await runtime.store.getOrCreateContext({ key: params.contextKey });
7
8
  return { ok: true, data: ctx };
8
9
  }
@@ -14,8 +15,8 @@ export async function structureGetOrCreateContextStep(params) {
14
15
  export async function structureGetContextStep(params) {
15
16
  "use step";
16
17
  try {
17
- const { getThreadRuntime } = await import("@ekairos/thread/runtime");
18
- const runtime = await getThreadRuntime(params.env);
18
+ const { getContextRuntime } = await import("@ekairos/events/runtime");
19
+ const runtime = await getContextRuntime(params.env);
19
20
  const ctx = await runtime.store.getContext({ key: params.contextKey });
20
21
  if (!ctx)
21
22
  return { ok: false, error: "Context not found" };
@@ -29,8 +30,8 @@ export async function structureGetContextStep(params) {
29
30
  export async function structureUpdateContextContentStep(params) {
30
31
  "use step";
31
32
  try {
32
- const { getThreadRuntime } = await import("@ekairos/thread/runtime");
33
- const runtime = await getThreadRuntime(params.env);
33
+ const { getContextRuntime } = await import("@ekairos/events/runtime");
34
+ const runtime = await getContextRuntime(params.env);
34
35
  const updated = await runtime.store.updateContextContent({ key: params.contextKey }, params.content);
35
36
  return { ok: true, data: updated };
36
37
  }
@@ -42,8 +43,8 @@ export async function structureUpdateContextContentStep(params) {
42
43
  export async function structurePatchContextContentStep(params) {
43
44
  "use step";
44
45
  try {
45
- const { getThreadRuntime } = await import("@ekairos/thread/runtime");
46
- const runtime = await getThreadRuntime(params.env);
46
+ const { getContextRuntime } = await import("@ekairos/events/runtime");
47
+ const runtime = await getContextRuntime(params.env);
47
48
  const existing = await runtime.store.getOrCreateContext({ key: params.contextKey });
48
49
  const existingContent = (existing?.content ?? {});
49
50
  const existingStructure = (existingContent?.structure ?? {});
@@ -65,8 +66,8 @@ export async function structureUploadRowsOutputJsonlStep(params) {
65
66
  "use step";
66
67
  const startedAt = Date.now();
67
68
  try {
68
- const { getThreadRuntime } = await import("@ekairos/thread/runtime");
69
- const runtime = await getThreadRuntime(params.env);
69
+ const { getContextRuntime } = await import("@ekairos/events/runtime");
70
+ const runtime = await getContextRuntime(params.env);
70
71
  const db = runtime.db;
71
72
  const storagePath = `/structure/${params.structureId}/output.jsonl`;
72
73
  const fileBuffer = Buffer.from(params.contentBase64 ?? "", "base64");
@@ -89,15 +90,12 @@ export async function structureLinkRowsOutputFileToContextStep(params) {
89
90
  "use step";
90
91
  const startedAt = Date.now();
91
92
  try {
92
- const { getThreadRuntime } = await import("@ekairos/thread/runtime");
93
- const runtime = await getThreadRuntime(params.env);
93
+ const { getContextRuntime } = await import("@ekairos/events/runtime");
94
+ const runtime = await getContextRuntime(params.env);
94
95
  const store = runtime.store;
95
96
  const db = runtime.db;
96
- const ctx = await store.getOrCreateContext({ key: params.contextKey });
97
- const ctxId = ctx?.id;
98
- if (!ctxId)
99
- return { ok: false, error: "Context not found" };
100
- await db.transact([db.tx.thread_contexts[ctxId].link({ structure_output_file: params.fileId })]);
97
+ await store.getOrCreateContext({ key: params.contextKey });
98
+ await linkStructureOutputFileToContextByKey(db, { contextKey: params.contextKey, fileId: params.fileId });
101
99
  console.log(`[structure:link-jsonl] contextKey=${params.contextKey} fileId=${params.fileId} elapsedMs=${Date.now() - startedAt}`);
102
100
  return { ok: true };
103
101
  }
@@ -109,15 +107,12 @@ export async function structureLinkRowsOutputFileToContextStep(params) {
109
107
  export async function structureUnlinkRowsOutputFileFromContextStep(params) {
110
108
  "use step";
111
109
  try {
112
- const { getThreadRuntime } = await import("@ekairos/thread/runtime");
113
- const runtime = await getThreadRuntime(params.env);
110
+ const { getContextRuntime } = await import("@ekairos/events/runtime");
111
+ const runtime = await getContextRuntime(params.env);
114
112
  const store = runtime.store;
115
113
  const db = runtime.db;
116
- const ctx = await store.getOrCreateContext({ key: params.contextKey });
117
- const ctxId = ctx?.id;
118
- if (!ctxId)
119
- return { ok: false, error: "Context not found" };
120
- await db.transact([db.tx.thread_contexts[ctxId].unlink({ structure_output_file: params.fileId })]);
114
+ await store.getOrCreateContext({ key: params.contextKey });
115
+ await unlinkStructureOutputFileFromContextByKey(db, { contextKey: params.contextKey, fileId: params.fileId });
121
116
  return { ok: true };
122
117
  }
123
118
  catch (error) {
@@ -128,16 +123,11 @@ export async function structureUnlinkRowsOutputFileFromContextStep(params) {
128
123
  export async function structureGetContextWithRowsOutputFileStep(params) {
129
124
  "use step";
130
125
  try {
131
- const { getThreadRuntime } = await import("@ekairos/thread/runtime");
132
- const runtime = await getThreadRuntime(params.env);
126
+ const { getContextRuntime } = await import("@ekairos/events/runtime");
127
+ const runtime = await getContextRuntime(params.env);
133
128
  const db = runtime.db;
134
- const query = (await db.query({
135
- thread_contexts: {
136
- $: { where: { key: params.contextKey }, limit: 1 },
137
- structure_output_file: {},
138
- },
139
- }));
140
- const row = query.thread_contexts?.[0];
129
+ const persisted = await findStructureContextByKey(db, params.contextKey, { includeOutputFile: true });
130
+ const row = persisted?.row;
141
131
  if (!row)
142
132
  return { ok: false, error: "Context not found" };
143
133
  return { ok: true, data: row };
@@ -152,16 +142,11 @@ export async function structureReadRowsOutputJsonlStep(params) {
152
142
  const startedAt = Date.now();
153
143
  try {
154
144
  const contextKey = `structure:${params.structureId}`;
155
- const { getThreadRuntime } = await import("@ekairos/thread/runtime");
156
- const runtime = await getThreadRuntime(params.env);
145
+ const { getContextRuntime } = await import("@ekairos/events/runtime");
146
+ const runtime = await getContextRuntime(params.env);
157
147
  const db = runtime.db;
158
- const query = (await db.query({
159
- thread_contexts: {
160
- $: { where: { key: contextKey }, limit: 1 },
161
- structure_output_file: {},
162
- },
163
- }));
164
- const ctx = query.thread_contexts?.[0];
148
+ const persisted = await findStructureContextByKey(db, contextKey, { includeOutputFile: true });
149
+ const ctx = persisted?.row;
165
150
  if (!ctx)
166
151
  return { ok: false, error: "Context not found" };
167
152
  const linked = Array.isArray(ctx?.structure_output_file) ? ctx.structure_output_file[0] : ctx.structure_output_file;
@@ -1,7 +1,7 @@
1
1
  export async function readInstantFileStep(params) {
2
2
  "use step";
3
- const { getThreadRuntime } = await import("@ekairos/thread/runtime");
4
- const runtime = (await getThreadRuntime(params.env));
3
+ const { getContextRuntime } = await import("@ekairos/events/runtime");
4
+ const runtime = (await getContextRuntime(params.env));
5
5
  const db = runtime.db;
6
6
  const { DatasetService } = await import("../service.js");
7
7
  const service = new DatasetService(db);
@@ -1,6 +1,7 @@
1
1
  import { getDatasetOutputPath, getDatasetWorkstation } from "./datasetFiles.js";
2
2
  import { createDatasetSandboxStep, runDatasetSandboxCommandStep } from "./sandbox/steps.js";
3
- import { getThreadRuntime } from "./runtime.js";
3
+ import { findStructureContextByKey } from "./contextPersistence.js";
4
+ import { getContextRuntime } from "./runtime.js";
4
5
  /**
5
6
  * Step 1/2:
6
7
  * Download the rows output.jsonl from Instant storage into a sandbox file.
@@ -37,16 +38,11 @@ export async function structureDownloadRowsOutputToSandboxStep(params) {
37
38
  if (exists.exitCode === 0) {
38
39
  return { sandboxId, localPath };
39
40
  }
40
- const storyRuntime = await getThreadRuntime(params.env);
41
+ const storyRuntime = await getContextRuntime(params.env);
41
42
  const db = storyRuntime.db;
42
43
  const contextKey = `structure:${params.structureId}`;
43
- const query = (await db.query({
44
- thread_contexts: {
45
- $: { where: { key: contextKey }, limit: 1 },
46
- structure_output_file: {},
47
- },
48
- }));
49
- const ctx = query.thread_contexts?.[0];
44
+ const persisted = await findStructureContextByKey(db, contextKey, { includeOutputFile: true });
45
+ const ctx = persisted?.row;
50
46
  const linked = Array.isArray(ctx?.structure_output_file) ? ctx.structure_output_file[0] : ctx.structure_output_file;
51
47
  const url = linked?.url;
52
48
  if (!url) {
@@ -1,6 +1,7 @@
1
1
  import { getDatasetOutputPath, getDatasetWorkstation } from "./datasetFiles.js";
2
2
  import { readDatasetSandboxFileStep, runDatasetSandboxCommandStep } from "./sandbox/steps.js";
3
- import { getThreadRuntime } from "./runtime.js";
3
+ import { linkStructureOutputFileToContextByKey } from "./contextPersistence.js";
4
+ import { getContextRuntime } from "./runtime.js";
4
5
  /**
5
6
  * Step:
6
7
  * Split a sandbox-local `output.jsonl` into a child dataset (also `output.jsonl`) of up to `limit` ROW entries.
@@ -84,7 +85,7 @@ export async function structureSplitRowsOutputToDatasetStep(params) {
84
85
  sandboxId: params.sandboxId,
85
86
  path: outPath,
86
87
  });
87
- const storyRuntime = await getThreadRuntime(params.env);
88
+ const storyRuntime = await getContextRuntime(params.env);
88
89
  const db = storyRuntime.db;
89
90
  const store = storyRuntime.store;
90
91
  const storagePath = `/structure/${params.childDatasetId}/output.jsonl`;
@@ -102,7 +103,7 @@ export async function structureSplitRowsOutputToDatasetStep(params) {
102
103
  if (!ctxId)
103
104
  throw new Error("Failed to create child dataset context");
104
105
  // Link the output file to the context (used by DatasetService.readRecordsFromFile).
105
- await db.transact([db.tx.thread_contexts[ctxId].link({ structure_output_file: fileId })]);
106
+ await linkStructureOutputFileToContextByKey(db, { contextKey, fileId });
106
107
  // Patch metadata under `structure` namespace (never clobber Story runtime keys).
107
108
  const existingContent = (ctx?.content ?? {});
108
109
  const existingStructure = (existingContent?.structure ?? {});
package/dist/runtime.d.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Why dynamic import?
5
5
  * - Some bundlers (notably Turbopack step bundles) can drop/hoist static imports in "use-step" modules,
6
- * causing `ReferenceError: getThreadRuntime is not defined`.
6
+ * causing `ReferenceError: getContextRuntime is not defined`.
7
7
  * - Using a dynamic import keeps the symbol resolution local to the step runtime.
8
8
  */
9
- export declare function getThreadRuntime(env: any): Promise<import("@ekairos/thread/runtime").ThreadRuntime>;
9
+ export declare function getContextRuntime(env: any): Promise<import("@ekairos/events/runtime").ContextRuntime>;
package/dist/runtime.js CHANGED
@@ -3,10 +3,10 @@
3
3
  *
4
4
  * Why dynamic import?
5
5
  * - Some bundlers (notably Turbopack step bundles) can drop/hoist static imports in "use-step" modules,
6
- * causing `ReferenceError: getThreadRuntime is not defined`.
6
+ * causing `ReferenceError: getContextRuntime is not defined`.
7
7
  * - Using a dynamic import keeps the symbol resolution local to the step runtime.
8
8
  */
9
- export async function getThreadRuntime(env) {
10
- const { getThreadRuntime } = await import("@ekairos/thread/runtime");
11
- return await getThreadRuntime(env);
9
+ export async function getContextRuntime(env) {
10
+ const { getContextRuntime } = await import("@ekairos/events/runtime");
11
+ return await getContextRuntime(env);
12
12
  }
@@ -104,8 +104,8 @@ export async function createDatasetSandboxStep(params) {
104
104
  "use step";
105
105
  const startedAt = Date.now();
106
106
  const { env, ...configInput } = params;
107
- const { getThreadRuntime } = await import("@ekairos/thread/runtime");
108
- const db = (await getThreadRuntime(env)).db;
107
+ const { getContextRuntime } = await import("@ekairos/events/runtime");
108
+ const db = (await getContextRuntime(env)).db;
109
109
  const { SandboxService } = (await import("@ekairos/sandbox"));
110
110
  const service = new SandboxService(db);
111
111
  const daytonaDefaults = getStructureDaytonaDefaults();
@@ -181,8 +181,8 @@ export async function createDatasetSandboxStep(params) {
181
181
  export async function runDatasetSandboxCommandStep(params) {
182
182
  "use step";
183
183
  const startedAt = Date.now();
184
- const { getThreadRuntime } = await import("@ekairos/thread/runtime");
185
- const db = (await getThreadRuntime(params.env)).db;
184
+ const { getContextRuntime } = await import("@ekairos/events/runtime");
185
+ const db = (await getContextRuntime(params.env)).db;
186
186
  const { SandboxService } = (await import("@ekairos/sandbox"));
187
187
  const service = new SandboxService(db);
188
188
  const result = await service.runCommand(params.sandboxId, params.cmd, params.args ?? []);
@@ -202,8 +202,8 @@ export async function runDatasetSandboxCommandStep(params) {
202
202
  export async function writeDatasetSandboxFilesStep(params) {
203
203
  "use step";
204
204
  const startedAt = Date.now();
205
- const { getThreadRuntime } = await import("@ekairos/thread/runtime");
206
- const db = (await getThreadRuntime(params.env)).db;
205
+ const { getContextRuntime } = await import("@ekairos/events/runtime");
206
+ const db = (await getContextRuntime(params.env)).db;
207
207
  const { SandboxService } = (await import("@ekairos/sandbox"));
208
208
  const service = new SandboxService(db);
209
209
  const result = await service.writeFiles(params.sandboxId, params.files);
@@ -233,8 +233,8 @@ export async function writeDatasetSandboxTextFileStep(params) {
233
233
  export async function readDatasetSandboxFileStep(params) {
234
234
  "use step";
235
235
  const startedAt = Date.now();
236
- const { getThreadRuntime } = await import("@ekairos/thread/runtime");
237
- const db = (await getThreadRuntime(params.env)).db;
236
+ const { getContextRuntime } = await import("@ekairos/events/runtime");
237
+ const db = (await getContextRuntime(params.env)).db;
238
238
  const { SandboxService } = (await import("@ekairos/sandbox"));
239
239
  const service = new SandboxService(db);
240
240
  const result = await service.readFile(params.sandboxId, params.path);
@@ -262,8 +262,8 @@ export async function readDatasetSandboxTextFileStep(params) {
262
262
  export async function stopDatasetSandboxStep(params) {
263
263
  "use step";
264
264
  const startedAt = Date.now();
265
- const { getThreadRuntime } = await import("@ekairos/thread/runtime");
266
- const db = (await getThreadRuntime(params.env)).db;
265
+ const { getContextRuntime } = await import("@ekairos/events/runtime");
266
+ const db = (await getContextRuntime(params.env)).db;
267
267
  const { SandboxService } = (await import("@ekairos/sandbox"));
268
268
  const service = new SandboxService(db);
269
269
  const result = await service.stopSandbox(params.sandboxId);
package/dist/schema.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { i } from "@instantdb/core";
2
2
  import { domain } from "@ekairos/domain";
3
- import { threadDomain } from "@ekairos/thread/schema";
3
+ import { eventsDomain } from "@ekairos/events/schema";
4
4
  import { sandboxDomain } from "@ekairos/sandbox/schema";
5
5
  const entities = {
6
6
  // Keep $files compatible with Instant's base file fields used by structure flows.
@@ -19,16 +19,16 @@ const links = {
19
19
  /**
20
20
  * Structure output link (rows):
21
21
  *
22
- * - `thread_contexts.structure_output_file` points to the `$files` record for `output.jsonl`.
22
+ * - `event_contexts.structure_output_file` points to the `$files` record for `output.jsonl`.
23
23
  * - Reverse label is prefixed to avoid collisions across domains.
24
24
  */
25
25
  structureContextOutputFile: {
26
- forward: { on: "thread_contexts", has: "one", label: "structure_output_file" },
26
+ forward: { on: "event_contexts", has: "one", label: "structure_output_file" },
27
27
  reverse: { on: "$files", has: "many", label: "structure_contexts" },
28
28
  },
29
29
  };
30
30
  const rooms = {};
31
31
  export const structureDomain = domain("structure")
32
- .includes(threadDomain)
32
+ .includes(eventsDomain)
33
33
  .includes(sandboxDomain)
34
34
  .schema({ entities, links, rooms });
package/dist/service.d.ts CHANGED
@@ -8,7 +8,7 @@ export type ServiceResult<T = any> = {
8
8
  /**
9
9
  * Back-compat helper for reading structure outputs outside the workflow runtime.
10
10
  *
11
- * IMPORTANT: The source of truth is `thread_contexts` (Story context) keyed by `structure:<id>`.
11
+ * IMPORTANT: The source of truth is the persisted Story/Event context keyed by `structure:<id>`.
12
12
  */
13
13
  export declare class DatasetService {
14
14
  private readonly db;
package/dist/service.js CHANGED
@@ -1,7 +1,8 @@
1
+ import { createStructureContext, findStructureContextByKey, linkStructureOutputFileToContextByKey, } from "./contextPersistence.js";
1
2
  /**
2
3
  * Back-compat helper for reading structure outputs outside the workflow runtime.
3
4
  *
4
- * IMPORTANT: The source of truth is `thread_contexts` (Story context) keyed by `structure:<id>`.
5
+ * IMPORTANT: The source of truth is the persisted Story/Event context keyed by `structure:<id>`.
5
6
  */
6
7
  export class DatasetService {
7
8
  constructor(db) {
@@ -13,13 +14,8 @@ export class DatasetService {
13
14
  async getDatasetById(datasetId) {
14
15
  try {
15
16
  const key = this.contextKey(datasetId);
16
- const res = await this.db.query({
17
- thread_contexts: {
18
- $: { where: { key }, limit: 1 },
19
- structure_output_file: {},
20
- },
21
- });
22
- const ctx = res.thread_contexts?.[0];
17
+ const persisted = await findStructureContextByKey(this.db, key, { includeOutputFile: true });
18
+ const ctx = persisted?.row;
23
19
  if (!ctx)
24
20
  return { ok: false, error: "Context not found" };
25
21
  return { ok: true, data: ctx };
@@ -43,13 +39,8 @@ export class DatasetService {
43
39
  async readRecordsFromFile(datasetId) {
44
40
  try {
45
41
  const key = this.contextKey(datasetId);
46
- const res = await this.db.query({
47
- thread_contexts: {
48
- $: { where: { key }, limit: 1 },
49
- structure_output_file: {},
50
- },
51
- });
52
- const ctx = res.thread_contexts?.[0];
42
+ const persisted = await findStructureContextByKey(this.db, key, { includeOutputFile: true });
43
+ const ctx = persisted?.row;
53
44
  const linked = Array.isArray(ctx?.structure_output_file) ? ctx.structure_output_file[0] : ctx?.structure_output_file;
54
45
  const url = linked?.url;
55
46
  if (!url)
@@ -89,20 +80,14 @@ export class DatasetService {
89
80
  try {
90
81
  const datasetId = params.id ?? createUuidV4();
91
82
  const key = this.contextKey(datasetId);
92
- const existing = await this.db.query({
93
- thread_contexts: { $: { where: { key }, limit: 1 } },
94
- });
95
- const ctx = existing.thread_contexts?.[0];
83
+ const existing = await findStructureContextByKey(this.db, key);
84
+ const ctx = existing?.row;
96
85
  if (ctx)
97
86
  return { ok: true, data: { datasetId } };
98
- await this.db.transact([
99
- this.db.tx.thread_contexts[createUuidV4()].create({
100
- createdAt: new Date(),
101
- content: {},
102
- key,
103
- status: "open",
104
- }),
105
- ]);
87
+ await createStructureContext(this.db, {
88
+ id: createUuidV4(),
89
+ key,
90
+ });
106
91
  return { ok: true, data: { datasetId } };
107
92
  }
108
93
  catch (error) {
@@ -133,14 +118,10 @@ export class DatasetService {
133
118
  async linkFileToDataset(params) {
134
119
  try {
135
120
  const key = this.contextKey(params.datasetId);
136
- const res = await this.db.query({
137
- thread_contexts: { $: { where: { key }, limit: 1 } },
138
- });
139
- const ctx = res?.thread_contexts?.[0];
140
- const ctxId = ctx?.id;
141
- if (!ctxId)
121
+ const persisted = await findStructureContextByKey(this.db, key);
122
+ if (!persisted?.row?.id)
142
123
  return { ok: false, error: "Context not found" };
143
- await this.db.transact([this.db.tx.thread_contexts[ctxId].link({ structure_output_file: params.fileId })]);
124
+ await linkStructureOutputFileToContextByKey(this.db, { contextKey: key, fileId: params.fileId });
144
125
  return { ok: true, data: undefined };
145
126
  }
146
127
  catch (error) {
@@ -1,3 +1,4 @@
1
+ import { linkStructureOutputFileToContextByKey } from "../contextPersistence.js";
1
2
  function isToolCompletePart(value) {
2
3
  if (!value || typeof value !== "object")
3
4
  return false;
@@ -22,8 +23,8 @@ export async function structureCommitFromEventsStep(params) {
22
23
  "use step";
23
24
  const contextKey = `structure:${params.structureId}`;
24
25
  try {
25
- const { getThreadRuntime } = await import("@ekairos/thread/runtime");
26
- const runtime = (await getThreadRuntime(params.env));
26
+ const { getContextRuntime } = await import("@ekairos/events/runtime");
27
+ const runtime = (await getContextRuntime(params.env));
27
28
  const store = runtime.store;
28
29
  const db = runtime.db;
29
30
  const events = await store.getItems({ key: contextKey });
@@ -66,10 +67,9 @@ export async function structureCommitFromEventsStep(params) {
66
67
  },
67
68
  };
68
69
  // Link output file to context (domain-prefixed link)
69
- const ctxId = ctx?.id;
70
- if (!ctxId)
70
+ if (!ctx?.id)
71
71
  return { ok: false, error: "Context not found" };
72
- await db.transact(db.tx.thread_contexts[ctxId].link({ structure_output_file: out.fileId }));
72
+ await linkStructureOutputFileToContextByKey(db, { contextKey, fileId: out.fileId });
73
73
  }
74
74
  await store.updateContextContent({ key: contextKey }, { ...prevContent, structure: nextStructure });
75
75
  return { ok: true, data: { committed: true } };
@@ -0,0 +1,11 @@
1
+ type EnsureExecutionTrailParams = {
2
+ env: any;
3
+ contextKey: string;
4
+ datasetId: string;
5
+ output: "rows" | "object";
6
+ requestItemId: string;
7
+ status: "success" | "failed";
8
+ error?: unknown;
9
+ };
10
+ export declare function ensureExecutionTrailStep(params: EnsureExecutionTrailParams): Promise<void>;
11
+ export {};
@@ -0,0 +1,100 @@
1
+ function createTraceItemId(seed) {
2
+ let hashA = 2166136261;
3
+ let hashB = 2166136261;
4
+ for (let i = 0; i < seed.length; i += 1) {
5
+ const code = seed.charCodeAt(i);
6
+ hashA ^= code;
7
+ hashA = Math.imul(hashA, 16777619);
8
+ hashB ^= code + (i % 13);
9
+ hashB = Math.imul(hashB, 16777619);
10
+ }
11
+ const partA = (hashA >>> 0).toString(16).padStart(8, "0");
12
+ const partB = (hashB >>> 0).toString(16).padStart(8, "0");
13
+ const hex = `${partA}${partB}${partA}${partB}`;
14
+ const chars = hex.slice(0, 32).split("");
15
+ chars[12] = "4";
16
+ const variant = parseInt(chars[16], 16);
17
+ chars[16] = ((variant & 0x3) | 0x8).toString(16);
18
+ const normalized = chars.join("");
19
+ return `${normalized.slice(0, 8)}-${normalized.slice(8, 12)}-${normalized.slice(12, 16)}-${normalized.slice(16, 20)}-${normalized.slice(20, 32)}`;
20
+ }
21
+ function toSerializableError(error) {
22
+ if (!error)
23
+ return undefined;
24
+ if (typeof error === "string")
25
+ return error;
26
+ if (error instanceof Error) {
27
+ return {
28
+ name: error.name,
29
+ message: error.message,
30
+ };
31
+ }
32
+ return String(error);
33
+ }
34
+ export async function ensureExecutionTrailStep(params) {
35
+ "use step";
36
+ const { getContextRuntime } = await import("@ekairos/events/runtime");
37
+ const runtime = (await getContextRuntime(params.env));
38
+ const store = runtime.store;
39
+ if (!store?.saveItem ||
40
+ !store?.createExecution ||
41
+ !store?.linkItemToExecution ||
42
+ !store?.getItems) {
43
+ return;
44
+ }
45
+ const items = await store.getItems({ key: params.contextKey });
46
+ const hasRequest = items.some((item) => item?.id === params.requestItemId);
47
+ let requestItemId = params.requestItemId;
48
+ if (!hasRequest) {
49
+ const recreatedRequestItemId = createTraceItemId(`structure-trace:request:${params.contextKey}:${params.datasetId}:${params.requestItemId}`);
50
+ const requestItem = await store.saveItem({ key: params.contextKey }, {
51
+ id: recreatedRequestItemId,
52
+ type: "input",
53
+ channel: "web",
54
+ createdAt: new Date().toISOString(),
55
+ content: {
56
+ parts: [{ type: "text", text: "[structure-trace] request (recreated)" }],
57
+ structure_build: {
58
+ datasetId: params.datasetId,
59
+ status: "input",
60
+ },
61
+ },
62
+ });
63
+ if (!requestItem?.id)
64
+ return;
65
+ requestItemId = requestItem.id;
66
+ }
67
+ const outputItemId = createTraceItemId(`structure-trace:output:${params.contextKey}:${params.datasetId}:${params.status}:${params.output}`);
68
+ const outputItem = await store.saveItem({ key: params.contextKey }, {
69
+ id: outputItemId,
70
+ type: "output",
71
+ channel: "web",
72
+ createdAt: new Date().toISOString(),
73
+ content: {
74
+ parts: [
75
+ { type: "text", text: `structure:${params.datasetId} ${params.status}` },
76
+ ],
77
+ structure_build: {
78
+ datasetId: params.datasetId,
79
+ status: params.status,
80
+ output: params.output,
81
+ orgId: params.env?.orgId,
82
+ error: toSerializableError(params.error),
83
+ },
84
+ },
85
+ });
86
+ if (!outputItem?.id)
87
+ return;
88
+ const execution = await store.createExecution({ key: params.contextKey }, requestItemId, outputItem.id);
89
+ await store.linkItemToExecution({
90
+ itemId: requestItemId,
91
+ executionId: execution.id,
92
+ });
93
+ await store.linkItemToExecution({
94
+ itemId: outputItem.id,
95
+ executionId: execution.id,
96
+ });
97
+ if (store?.completeExecution) {
98
+ await store.completeExecution({ key: params.contextKey }, execution.id, "completed");
99
+ }
100
+ }
@@ -36,8 +36,8 @@ function extractJsonObject(text) {
36
36
  }
37
37
  export async function persistObjectResultFromStoryStep(params) {
38
38
  "use step";
39
- const { getThreadRuntime } = await import("@ekairos/thread/runtime");
40
- const runtime = (await getThreadRuntime(params.env));
39
+ const { getContextRuntime } = await import("@ekairos/events/runtime");
40
+ const runtime = (await getContextRuntime(params.env));
41
41
  const store = runtime.store;
42
42
  const contextKey = `structure:${params.datasetId}`;
43
43
  const events = await store.getEvents({ key: contextKey });
package/dist/structure.js CHANGED
@@ -1,10 +1,10 @@
1
- import { createThread, didToolExecute, INPUT_TEXT_ITEM_TYPE, WEB_CHANNEL } from "@ekairos/thread";
1
+ import { createContext, didToolExecute, INPUT_TEXT_ITEM_TYPE, WEB_CHANNEL } from "@ekairos/events";
2
2
  import { getDatasetOutputPath, getDatasetOutputSchemaPath, getDatasetWorkstation, getDaytonaVolumeMountPath, getDaytonaVolumeName, } from "./datasetFiles.js";
3
3
  import { structureDownloadRowsOutputToSandboxStep, structureReadRowsOutputPageFromSandboxStep, } from "./rowsOutputPaging.js";
4
4
  import { structureSplitRowsOutputToDatasetStep } from "./rowsOutputSplit.js";
5
5
  import { createDatasetSandboxStep, readDatasetSandboxFileStep, readDatasetSandboxTextFileStep, runDatasetSandboxCommandStep, writeDatasetSandboxFilesStep, writeDatasetSandboxTextFileStep, } from "./sandbox/steps.js";
6
6
  import { readInstantFileStep } from "./file/steps.js";
7
- import { structureGetContextStep, structureGetContextWithRowsOutputFileStep, structureReadRowsOutputJsonlStep, } from "./dataset/steps.js";
7
+ import { structureGetContextStep, structureGetContextWithRowsOutputFileStep, structurePatchContextContentStep, structureReadRowsOutputJsonlStep, } from "./dataset/steps.js";
8
8
  import { getWorkflowMetadata } from "workflow";
9
9
  import { buildStructurePrompt } from "./prompts.js";
10
10
  import { createExecuteCommandTool } from "./executeCommand.tool.js";
@@ -14,6 +14,7 @@ import { createCompleteRowsTool } from "./completeRows.tool.js";
14
14
  import { createCompleteObjectTool } from "./completeObject.tool.js";
15
15
  import { persistObjectResultFromStoryStep } from "./steps/persistObjectFromStory.step.js";
16
16
  import { structureCommitFromEventsStep } from "./steps/commitFromEvents.step.js";
17
+ import { ensureExecutionTrailStep } from "./steps/ensureExecutionTrail.step.js";
17
18
  function createUuidV4() {
18
19
  // Pure JS uuidv4 (workflow-safe: avoids Node built-ins and @instantdb/admin)
19
20
  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
@@ -22,6 +23,20 @@ function createUuidV4() {
22
23
  return v.toString(16);
23
24
  });
24
25
  }
26
+ function toSerializableStructureError(error) {
27
+ if (!error)
28
+ return undefined;
29
+ if (typeof error === "string")
30
+ return error;
31
+ if (error instanceof Error) {
32
+ return {
33
+ name: error.name,
34
+ message: error.message,
35
+ stack: error.stack ? String(error.stack).slice(0, 2000) : undefined,
36
+ };
37
+ }
38
+ return String(error);
39
+ }
25
40
  function assertRunningInsideWorkflow(params) {
26
41
  const bypassRaw = String(process.env.STRUCTURE_ALLOW_NON_WORKFLOW ?? "")
27
42
  .trim()
@@ -266,7 +281,7 @@ function createStructureStoryDefinition(config) {
266
281
  const model = config.model ?? "openai/gpt-5.2";
267
282
  const defaultSandboxConfig = getDefaultSandboxConfig(datasetId);
268
283
  const resolvedSandboxConfig = mergeSandboxConfig(defaultSandboxConfig, config.sandboxConfig);
269
- const story = createThread("ekairos.structure")
284
+ const story = createContext("ekairos.structure")
270
285
  .context(async (stored, env) => {
271
286
  const prev = stored?.content ?? {};
272
287
  const sandboxState = prev.sandboxState ?? { initialized: false, sources: [] };
@@ -455,6 +470,30 @@ export function structure(env, opts) {
455
470
  content: { parts: [{ type: "text", text }] },
456
471
  };
457
472
  }
473
+ async function markBuildFailed(error) {
474
+ try {
475
+ await structurePatchContextContentStep({
476
+ env,
477
+ contextKey,
478
+ patch: {
479
+ structure: {
480
+ kind: "ekairos.structure",
481
+ version: 1,
482
+ structureId: datasetId,
483
+ updatedAt: Date.now(),
484
+ state: "failed",
485
+ error: {
486
+ message: error instanceof Error ? error.message : String(error),
487
+ stage: "structure.build",
488
+ },
489
+ },
490
+ },
491
+ });
492
+ }
493
+ catch {
494
+ // keep failure explicit even if persistence is partially unavailable
495
+ }
496
+ }
458
497
  async function runStory(evt) {
459
498
  await story.react(evt, {
460
499
  env,
@@ -464,6 +503,7 @@ export function structure(env, opts) {
464
503
  // Tools are intentionally pure: persist completion outputs post-react by reading tool results from events.
465
504
  const commit = await structureCommitFromEventsStep({ env, structureId: datasetId });
466
505
  if (!commit.ok) {
506
+ throw new Error(commit.error);
467
507
  }
468
508
  }
469
509
  async function getContextOrThrow() {
@@ -485,115 +525,137 @@ export function structure(env, opts) {
485
525
  return (content?.structure?.outputs?.object?.value !== undefined &&
486
526
  content?.structure?.outputs?.object?.value !== null);
487
527
  }
488
- await runStory(makeUserMessageEvent(userPrompt ?? "produce structured output"));
489
- let ctx = await getContextOrThrow();
490
- // Auto-mode: if schema is missing after the first pass, explicitly request investigation + generateSchema.
491
- if (mode === "auto") {
492
- const content = (ctx?.content ?? {});
493
- const hasSchema = Boolean(content?.structure?.outputSchema?.schema);
494
- if (!hasSchema) {
495
- await runStory(makeUserMessageEvent([
496
- "CRITICAL: You did not generate a schema yet.",
497
- "1) Investigate Sources using executeCommand (inspect paths, read files, infer structure).",
498
- "2) Call generateSchema.",
499
- "3) After schema is saved, produce the final output and call complete.",
500
- ].join("\n")));
528
+ const initialRequestEvent = makeUserMessageEvent(userPrompt ?? "produce structured output");
529
+ try {
530
+ await runStory(initialRequestEvent);
531
+ let ctx = await getContextOrThrow();
532
+ // Auto-mode: if schema is missing after the first pass, explicitly request investigation + generateSchema.
533
+ if (mode === "auto") {
534
+ const content = (ctx?.content ?? {});
535
+ const hasSchema = Boolean(content?.structure?.outputSchema?.schema);
536
+ if (!hasSchema) {
537
+ await runStory(makeUserMessageEvent([
538
+ "CRITICAL: You did not generate a schema yet.",
539
+ "1) Investigate Sources using executeCommand (inspect paths, read files, infer structure).",
540
+ "2) Call generateSchema.",
541
+ "3) After schema is saved, produce the final output and call complete.",
542
+ ].join("\n")));
543
+ ctx = await getContextOrThrow();
544
+ }
545
+ }
546
+ const needsSecondPass = output === "rows" ? !(await isRowsCompleted()) : !isObjectCompleted(ctx);
547
+ if (needsSecondPass) {
548
+ const followUpText = output === "rows"
549
+ ? "Finalize now: write output.jsonl to OutputPath and call complete."
550
+ : "Finalize now: call complete with summary and resultJson (inline JSON).";
551
+ await runStory(makeUserMessageEvent(followUpText));
501
552
  ctx = await getContextOrThrow();
502
553
  }
503
- }
504
- const needsSecondPass = output === "rows" ? !(await isRowsCompleted()) : !isObjectCompleted(ctx);
505
- if (needsSecondPass) {
506
- const followUpText = output === "rows"
507
- ? "Finalize now: write output.jsonl to OutputPath and call complete."
508
- : "Finalize now: call complete with summary and resultJson (inline JSON).";
509
- await runStory(makeUserMessageEvent(followUpText));
510
- ctx = await getContextOrThrow();
511
- }
512
- const stillIncompleteAfterSecondPass = output === "rows" ? !(await isRowsCompleted()) : !isObjectCompleted(ctx);
513
- if (stillIncompleteAfterSecondPass) {
514
- const finalText = output === "rows"
515
- ? "CRITICAL: Do not do anything else. Ensure output.jsonl exists at OutputPath and immediately call complete."
516
- : "CRITICAL: Do not do anything else. Immediately call complete with summary and resultJson (inline JSON).";
517
- await runStory(makeUserMessageEvent(finalText));
518
- ctx = await getContextOrThrow();
519
- }
520
- if (output === "rows" && !(await isRowsCompleted())) {
521
- throw new Error("Rows output not completed");
522
- }
523
- if (output === "object" && !isObjectCompleted(ctx)) {
524
- const persisted = await persistObjectResultFromStoryStep({ env, datasetId });
525
- if (persisted.ok) {
554
+ const stillIncompleteAfterSecondPass = output === "rows" ? !(await isRowsCompleted()) : !isObjectCompleted(ctx);
555
+ if (stillIncompleteAfterSecondPass) {
556
+ const finalText = output === "rows"
557
+ ? "CRITICAL: Do not do anything else. Ensure output.jsonl exists at OutputPath and immediately call complete."
558
+ : "CRITICAL: Do not do anything else. Immediately call complete with summary and resultJson (inline JSON).";
559
+ await runStory(makeUserMessageEvent(finalText));
526
560
  ctx = await getContextOrThrow();
527
561
  }
528
- else {
562
+ if (output === "rows" && !(await isRowsCompleted())) {
563
+ throw new Error("Rows output not completed");
529
564
  }
530
- }
531
- if (output === "object" && !isObjectCompleted(ctx)) {
532
- throw new Error("Object output not completed");
533
- }
534
- let rowsSandboxRef = null;
535
- const reader = {
536
- read: async (cursorOrParams, limit) => {
537
- if (output !== "rows") {
538
- throw new Error("reader.read() is only supported for output=rows");
565
+ if (output === "object" && !isObjectCompleted(ctx)) {
566
+ const persisted = await persistObjectResultFromStoryStep({ env, datasetId });
567
+ if (persisted.ok) {
568
+ ctx = await getContextOrThrow();
539
569
  }
540
- if (!rowsSandboxRef) {
541
- rowsSandboxRef = await structureDownloadRowsOutputToSandboxStep({
570
+ }
571
+ if (output === "object" && !isObjectCompleted(ctx)) {
572
+ throw new Error("Object output not completed");
573
+ }
574
+ await ensureExecutionTrailStep({
575
+ env,
576
+ contextKey,
577
+ datasetId,
578
+ output,
579
+ status: "success",
580
+ requestItemId: initialRequestEvent.id,
581
+ });
582
+ let rowsSandboxRef = null;
583
+ const reader = {
584
+ read: async (cursorOrParams, limit) => {
585
+ if (output !== "rows") {
586
+ throw new Error("reader.read() is only supported for output=rows");
587
+ }
588
+ if (!rowsSandboxRef) {
589
+ rowsSandboxRef = await structureDownloadRowsOutputToSandboxStep({
590
+ env,
591
+ structureId: datasetId,
592
+ });
593
+ }
594
+ const params = cursorOrParams && typeof cursorOrParams === "object" && ("cursor" in cursorOrParams || "limit" in cursorOrParams)
595
+ ? cursorOrParams
596
+ : { cursor: cursorOrParams, limit };
597
+ const page = await structureReadRowsOutputPageFromSandboxStep({
542
598
  env,
543
- structureId: datasetId,
599
+ sandboxId: rowsSandboxRef.sandboxId,
600
+ localPath: rowsSandboxRef.localPath,
601
+ cursor: params?.cursor,
602
+ limit: params?.limit ?? 200,
544
603
  });
545
- }
546
- const params = cursorOrParams && typeof cursorOrParams === "object" && ("cursor" in cursorOrParams || "limit" in cursorOrParams)
547
- ? cursorOrParams
548
- : { cursor: cursorOrParams, limit };
549
- const page = await structureReadRowsOutputPageFromSandboxStep({
550
- env,
551
- sandboxId: rowsSandboxRef.sandboxId,
552
- localPath: rowsSandboxRef.localPath,
553
- cursor: params?.cursor,
554
- limit: params?.limit ?? 200,
555
- });
556
- return {
557
- rows: page.rows,
558
- cursor: page.nextCursor,
559
- done: page.done,
560
- };
561
- },
562
- split: async (cursorOrParams, limit) => {
563
- if (output !== "rows") {
564
- throw new Error("reader.split() is only supported for output=rows");
565
- }
566
- if (!rowsSandboxRef) {
567
- rowsSandboxRef = await structureDownloadRowsOutputToSandboxStep({
604
+ return {
605
+ rows: page.rows,
606
+ cursor: page.nextCursor,
607
+ done: page.done,
608
+ };
609
+ },
610
+ split: async (cursorOrParams, limit) => {
611
+ if (output !== "rows") {
612
+ throw new Error("reader.split() is only supported for output=rows");
613
+ }
614
+ if (!rowsSandboxRef) {
615
+ rowsSandboxRef = await structureDownloadRowsOutputToSandboxStep({
616
+ env,
617
+ structureId: datasetId,
618
+ });
619
+ }
620
+ const params = cursorOrParams && typeof cursorOrParams === "object" && ("cursor" in cursorOrParams || "limit" in cursorOrParams)
621
+ ? cursorOrParams
622
+ : {
623
+ cursor: cursorOrParams,
624
+ limit,
625
+ datasetId: undefined,
626
+ };
627
+ const childDatasetId = params?.datasetId ?? createUuidV4();
628
+ const res = await structureSplitRowsOutputToDatasetStep({
568
629
  env,
569
- structureId: datasetId,
630
+ sandboxId: rowsSandboxRef.sandboxId,
631
+ localPath: rowsSandboxRef.localPath,
632
+ cursor: params?.cursor,
633
+ limit: params?.limit ?? 300,
634
+ childDatasetId,
570
635
  });
571
- }
572
- const params = cursorOrParams && typeof cursorOrParams === "object" && ("cursor" in cursorOrParams || "limit" in cursorOrParams)
573
- ? cursorOrParams
574
- : {
575
- cursor: cursorOrParams,
576
- limit,
577
- datasetId: undefined,
636
+ return {
637
+ datasetId: res.datasetId,
638
+ rowsWritten: res.rowsWritten,
639
+ cursor: res.nextCursor,
640
+ done: res.done,
578
641
  };
579
- const childDatasetId = params?.datasetId ?? createUuidV4();
580
- const res = await structureSplitRowsOutputToDatasetStep({
581
- env,
582
- sandboxId: rowsSandboxRef.sandboxId,
583
- localPath: rowsSandboxRef.localPath,
584
- cursor: params?.cursor,
585
- limit: params?.limit ?? 300,
586
- childDatasetId,
587
- });
588
- return {
589
- datasetId: res.datasetId,
590
- rowsWritten: res.rowsWritten,
591
- cursor: res.nextCursor,
592
- done: res.done,
593
- };
594
- },
595
- };
596
- return output === "object" ? { datasetId, reader, dataset: ctx } : { datasetId, reader };
642
+ },
643
+ };
644
+ return output === "object" ? { datasetId, reader, dataset: ctx } : { datasetId, reader };
645
+ }
646
+ catch (error) {
647
+ await markBuildFailed(error);
648
+ await ensureExecutionTrailStep({
649
+ env,
650
+ contextKey,
651
+ datasetId,
652
+ output,
653
+ status: "failed",
654
+ requestItemId: initialRequestEvent.id,
655
+ error: toSerializableStructureError(error),
656
+ });
657
+ throw error;
658
+ }
597
659
  },
598
660
  };
599
661
  return api;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ekairos/structure",
3
- "version": "1.22.9-beta.feature-registry-sync-esolbay-agent.0",
3
+ "version": "1.22.10-beta.development.0",
4
4
  "description": "Ekairos Structure - Unified structured extraction (rows or object) from file/text/dataset inputs",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -36,21 +36,21 @@
36
36
  "typecheck": "tsc --noEmit"
37
37
  },
38
38
  "dependencies": {
39
- "@ekairos/domain": "^1.22.9-beta.feature-registry-sync-esolbay-agent.0",
40
- "@ekairos/sandbox": "^1.22.9-beta.feature-registry-sync-esolbay-agent.0",
39
+ "@ekairos/domain": "^1.22.10-beta.development.0",
40
+ "@ekairos/sandbox": "^1.22.10-beta.development.0",
41
41
  "@instantdb/admin": "0.22.126",
42
42
  "@instantdb/core": "0.22.126",
43
43
  "ai": "^5.0.95",
44
44
  "ajv": "^8.17.1",
45
- "workflow": "4.1.0-beta.55",
46
- "zod": "^4.1.8"
45
+ "workflow": "5.0.0-beta.1",
46
+ "zod": "^4.3.6"
47
47
  },
48
48
  "peerDependencies": {
49
- "@ekairos/thread": "workspace:*"
49
+ "@ekairos/events": "workspace:*"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@ekairos/sandbox": "workspace:*",
53
- "@ekairos/thread": "workspace:*",
53
+ "@ekairos/events": "workspace:*",
54
54
  "@ekairos/tsconfig": "workspace:*",
55
55
  "@types/node": "^24.5.0",
56
56
  "dotenv": "^17.2.2",