@ekairos/structure 1.21.77-beta.0 → 1.21.78-beta.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,7 +1,7 @@
1
1
  import { tool } from "ai";
2
2
  import { z } from "zod/v4";
3
- import { runDatasetSandboxCommandStep } from "./sandbox/steps";
4
- import { getDatasetOutputPath } from "./datasetFiles";
3
+ import { runDatasetSandboxCommandStep } from "./sandbox/steps.js";
4
+ import { getDatasetOutputPath } from "./datasetFiles.js";
5
5
  export function createClearDatasetTool({ datasetId, sandboxId, env }) {
6
6
  return tool({
7
7
  description: "Clear output files and reset dataset status.",
@@ -1,8 +1,8 @@
1
1
  import { tool } from "ai";
2
2
  import { z } from "zod/v4";
3
3
  import Ajv from "ajv";
4
- import { structureGetContextStep } from "./dataset/steps";
5
- import { readDatasetSandboxTextFileStep } from "./sandbox/steps";
4
+ import { structureGetContextStep } from "./dataset/steps.js";
5
+ import { readDatasetSandboxTextFileStep } from "./sandbox/steps.js";
6
6
  let ajvInstance = null;
7
7
  function getAjv() {
8
8
  if (!ajvInstance) {
@@ -1,9 +1,9 @@
1
1
  import { tool } from "ai";
2
2
  import { z } from "zod/v4";
3
3
  import Ajv from "ajv";
4
- import { readDatasetSandboxFileStep, readDatasetSandboxTextFileStep, runDatasetSandboxCommandStep } from "./sandbox/steps";
5
- import { getDatasetOutputPath } from "./datasetFiles";
6
- import { structureGetContextStep, structureUploadRowsOutputJsonlStep } from "./dataset/steps";
4
+ import { readDatasetSandboxFileStep, readDatasetSandboxTextFileStep, runDatasetSandboxCommandStep } from "./sandbox/steps.js";
5
+ import { getDatasetOutputPath } from "./datasetFiles.js";
6
+ import { structureGetContextStep, structureUploadRowsOutputJsonlStep } from "./dataset/steps.js";
7
7
  let ajvInstance = null;
8
8
  function getAjv() {
9
9
  if (!ajvInstance) {
package/dist/domain.d.ts CHANGED
@@ -1 +1 @@
1
- export { structureDomain } from "./schema";
1
+ export { structureDomain } from "./schema.js";
package/dist/domain.js CHANGED
@@ -1 +1 @@
1
- export { structureDomain } from "./schema";
1
+ export { structureDomain } from "./schema.js";
@@ -1,7 +1,7 @@
1
1
  import { tool } from "ai";
2
2
  import { z } from "zod/v4";
3
- import { runDatasetSandboxCommandStep, writeDatasetSandboxTextFileStep } from "./sandbox/steps";
4
- import { getDatasetWorkstation } from "./datasetFiles";
3
+ import { runDatasetSandboxCommandStep, writeDatasetSandboxTextFileStep } from "./sandbox/steps.js";
4
+ import { getDatasetWorkstation } from "./datasetFiles.js";
5
5
  const MAX_STDOUT_CHARS = 20000;
6
6
  const MAX_STDERR_CHARS = 5000;
7
7
  function normalizeScriptName(scriptName) {
@@ -3,7 +3,7 @@ export async function readInstantFileStep(params) {
3
3
  const { resolveStoryRuntime } = await import("@ekairos/story/runtime");
4
4
  const runtime = (await resolveStoryRuntime(params.env));
5
5
  const db = runtime.db;
6
- const { DatasetService } = await import("../service");
6
+ const { DatasetService } = await import("../service.js");
7
7
  const service = new DatasetService(db);
8
8
  const file = await service.getFileById(params.fileId);
9
9
  const fileRow = file?.$files?.[0];
@@ -1,7 +1,7 @@
1
1
  import { tool } from "ai";
2
2
  import { z } from "zod/v4";
3
- import { writeDatasetSandboxTextFileStep } from "./sandbox/steps";
4
- import { getDatasetOutputSchemaPath } from "./datasetFiles";
3
+ import { writeDatasetSandboxTextFileStep } from "./sandbox/steps.js";
4
+ import { getDatasetOutputSchemaPath } from "./datasetFiles.js";
5
5
  export function createGenerateSchemaTool({ datasetId, sandboxId, env }) {
6
6
  return tool({
7
7
  description: "Write the output JSON Schema to the sandbox so the story loop can lift it into context state. IMPORTANT: Field names must be lowerCamelCase. For rows output, schema should describe a single record. For object output, schema should describe the whole object.",
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- export * from "./structure";
2
- export * from "./schema";
3
- export * from "./service";
4
- export * from "./datasetFiles";
5
- export * from "./rowsOutputPaging";
1
+ export * from "./structure.js";
2
+ export * from "./schema.js";
3
+ export * from "./service.js";
4
+ export * from "./datasetFiles.js";
5
+ export * from "./rowsOutputPaging.js";
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- export * from "./structure";
2
- export * from "./schema";
3
- export * from "./service";
4
- export * from "./datasetFiles";
5
- export * from "./rowsOutputPaging";
1
+ export * from "./structure.js";
2
+ export * from "./schema.js";
3
+ export * from "./service.js";
4
+ export * from "./datasetFiles.js";
5
+ export * from "./rowsOutputPaging.js";
@@ -1,6 +1,6 @@
1
- import { getDatasetOutputPath, getDatasetWorkstation } from "./datasetFiles";
2
- import { createDatasetSandboxStep, runDatasetSandboxCommandStep } from "./sandbox/steps";
3
- import { getStoryRuntime } from "./runtime";
1
+ import { getDatasetOutputPath, getDatasetWorkstation } from "./datasetFiles.js";
2
+ import { createDatasetSandboxStep, runDatasetSandboxCommandStep } from "./sandbox/steps.js";
3
+ import { getStoryRuntime } from "./runtime.js";
4
4
  /**
5
5
  * Step 1/2:
6
6
  * Download the rows output.jsonl from Instant storage into a sandbox file.
@@ -1,4 +1,4 @@
1
- import type { StructureRowsOutputPagingCursor } from "./rowsOutputPaging";
1
+ import type { StructureRowsOutputPagingCursor } from "./rowsOutputPaging.js";
2
2
  export type StructureSplitRowsOutputToDatasetResult = {
3
3
  datasetId?: string;
4
4
  rowsWritten: number;
@@ -1,6 +1,6 @@
1
- import { getDatasetOutputPath, getDatasetWorkstation } from "./datasetFiles";
2
- import { readDatasetSandboxFileStep, runDatasetSandboxCommandStep } from "./sandbox/steps";
3
- import { getStoryRuntime } from "./runtime";
1
+ import { getDatasetOutputPath, getDatasetWorkstation } from "./datasetFiles.js";
2
+ import { readDatasetSandboxFileStep, runDatasetSandboxCommandStep } from "./sandbox/steps.js";
3
+ import { getStoryRuntime } from "./runtime.js";
4
4
  /**
5
5
  * Step:
6
6
  * Split a sandbox-local `output.jsonl` into a child dataset (also `output.jsonl`) of up to `limit` ROW entries.
@@ -1,4 +1,4 @@
1
- import { getDatasetWorkdirBase, getDaytonaVolumeMountPath, getDaytonaVolumeName } from "../datasetFiles";
1
+ import { getDatasetWorkdirBase, getDaytonaVolumeMountPath, getDaytonaVolumeName } from "../datasetFiles.js";
2
2
  function parseOptionalNumber(value) {
3
3
  const parsed = Number(value);
4
4
  if (!Number.isFinite(parsed))
@@ -41,7 +41,7 @@ export async function persistObjectResultFromStoryStep(params) {
41
41
  const store = runtime.store;
42
42
  const contextKey = `structure:${params.datasetId}`;
43
43
  const events = await store.getEvents({ key: contextKey });
44
- const { structurePatchContextContentStep, structureGetContextStep } = await import("../dataset/steps");
44
+ const { structurePatchContextContentStep, structureGetContextStep } = await import("../dataset/steps.js");
45
45
  const ctxResult = await structureGetContextStep({ env: params.env, contextKey });
46
46
  const existingContent = ctxResult.ok ? (ctxResult.data?.content ?? {}) : {};
47
47
  for (let i = events.length - 1; i >= 0; i--) {
@@ -1,4 +1,4 @@
1
- import { type StructureRowsOutputPagingCursor } from "./rowsOutputPaging";
1
+ import { type StructureRowsOutputPagingCursor } from "./rowsOutputPaging.js";
2
2
  import type { SandboxConfig } from "@ekairos/sandbox";
3
3
  export type StructureSource = {
4
4
  kind: "file";
package/dist/structure.js CHANGED
@@ -1,19 +1,19 @@
1
1
  import { createStory, didToolExecute, USER_MESSAGE_TYPE, WEB_CHANNEL } from "@ekairos/story";
2
- import { getDatasetOutputPath, getDatasetOutputSchemaPath, getDatasetWorkstation, getDaytonaVolumeMountPath, getDaytonaVolumeName, } from "./datasetFiles";
3
- import { structureDownloadRowsOutputToSandboxStep, structureReadRowsOutputPageFromSandboxStep, } from "./rowsOutputPaging";
4
- import { structureSplitRowsOutputToDatasetStep } from "./rowsOutputSplit";
5
- import { createDatasetSandboxStep, readDatasetSandboxFileStep, readDatasetSandboxTextFileStep, runDatasetSandboxCommandStep, writeDatasetSandboxFilesStep, writeDatasetSandboxTextFileStep, } from "./sandbox/steps";
6
- import { readInstantFileStep } from "./file/steps";
7
- import { structureGetContextStep, structureGetContextWithRowsOutputFileStep, structureReadRowsOutputJsonlStep, } from "./dataset/steps";
2
+ import { getDatasetOutputPath, getDatasetOutputSchemaPath, getDatasetWorkstation, getDaytonaVolumeMountPath, getDaytonaVolumeName, } from "./datasetFiles.js";
3
+ import { structureDownloadRowsOutputToSandboxStep, structureReadRowsOutputPageFromSandboxStep, } from "./rowsOutputPaging.js";
4
+ import { structureSplitRowsOutputToDatasetStep } from "./rowsOutputSplit.js";
5
+ import { createDatasetSandboxStep, readDatasetSandboxFileStep, readDatasetSandboxTextFileStep, runDatasetSandboxCommandStep, writeDatasetSandboxFilesStep, writeDatasetSandboxTextFileStep, } from "./sandbox/steps.js";
6
+ import { readInstantFileStep } from "./file/steps.js";
7
+ import { structureGetContextStep, structureGetContextWithRowsOutputFileStep, structureReadRowsOutputJsonlStep, } from "./dataset/steps.js";
8
8
  import { getWorkflowMetadata } from "workflow";
9
- import { buildStructurePrompt } from "./prompts";
10
- import { createExecuteCommandTool } from "./executeCommand.tool";
11
- import { createGenerateSchemaTool } from "./generateSchema.tool";
12
- import { createClearDatasetTool } from "./clearDataset.tool";
13
- import { createCompleteRowsTool } from "./completeRows.tool";
14
- import { createCompleteObjectTool } from "./completeObject.tool";
15
- import { persistObjectResultFromStoryStep } from "./steps/persistObjectFromStory.step";
16
- import { structureCommitFromEventsStep } from "./steps/commitFromEvents.step";
9
+ import { buildStructurePrompt } from "./prompts.js";
10
+ import { createExecuteCommandTool } from "./executeCommand.tool.js";
11
+ import { createGenerateSchemaTool } from "./generateSchema.tool.js";
12
+ import { createClearDatasetTool } from "./clearDataset.tool.js";
13
+ import { createCompleteRowsTool } from "./completeRows.tool.js";
14
+ import { createCompleteObjectTool } from "./completeObject.tool.js";
15
+ import { persistObjectResultFromStoryStep } from "./steps/persistObjectFromStory.step.js";
16
+ import { structureCommitFromEventsStep } from "./steps/commitFromEvents.step.js";
17
17
  function createUuidV4() {
18
18
  // Pure JS uuidv4 (workflow-safe: avoids Node built-ins and @instantdb/admin)
19
19
  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
@@ -23,6 +23,12 @@ function createUuidV4() {
23
23
  });
24
24
  }
25
25
  function assertRunningInsideWorkflow(params) {
26
+ const bypassRaw = String(process.env.STRUCTURE_ALLOW_NON_WORKFLOW ?? "")
27
+ .trim()
28
+ .toLowerCase();
29
+ if (bypassRaw === "1" || bypassRaw === "true" || bypassRaw === "yes") {
30
+ return { workflowRunId: `test-${Date.now()}` };
31
+ }
26
32
  try {
27
33
  const meta = getWorkflowMetadata();
28
34
  const runId = meta?.workflowRunId;
@@ -50,7 +56,7 @@ function guessTextFileExtension(mimeType, name) {
50
56
  return ".yaml";
51
57
  return ".txt";
52
58
  }
53
- function shouldSkipPipInstall() {
59
+ function shouldSkipPipInstall(config) {
54
60
  const explicit = String(process.env.STRUCTURE_DAYTONA_SKIP_PIP_INSTALL ?? "").trim().toLowerCase();
55
61
  if (explicit === "1" || explicit === "true" || explicit === "yes")
56
62
  return true;
@@ -58,7 +64,16 @@ function shouldSkipPipInstall() {
58
64
  if (declarative === "1" || declarative === "true" || declarative === "yes")
59
65
  return true;
60
66
  const snapshot = String(process.env.STRUCTURE_DAYTONA_SNAPSHOT ?? "").trim();
61
- return Boolean(snapshot);
67
+ if (snapshot)
68
+ return true;
69
+ const image = config?.daytona?.image;
70
+ if (typeof image === "string" && image.trim().toLowerCase().startsWith("declarative"))
71
+ return true;
72
+ if (image && typeof image === "object")
73
+ return true;
74
+ if (config?.daytona?.snapshot)
75
+ return true;
76
+ return false;
62
77
  }
63
78
  function getDefaultSandboxConfig(datasetId) {
64
79
  const volumeName = getDaytonaVolumeName();
@@ -78,6 +93,7 @@ function getDefaultSandboxConfig(datasetId) {
78
93
  purpose: "structure.dataset",
79
94
  params: { datasetId },
80
95
  daytona: {
96
+ image: "declarative",
81
97
  ephemeral: true,
82
98
  autoStopIntervalMin: 5,
83
99
  volumes,
@@ -95,6 +111,9 @@ function mergeSandboxConfig(base, override) {
95
111
  ...(base.daytona ?? {}),
96
112
  ...(override.daytona ?? {}),
97
113
  };
114
+ if (override.daytona?.snapshot && !override.daytona?.image) {
115
+ mergedDaytona.image = undefined;
116
+ }
98
117
  if (override.daytona && "volumes" in override.daytona) {
99
118
  mergedDaytona.volumes = override.daytona?.volumes;
100
119
  }
@@ -142,7 +161,7 @@ async function ensureSandboxPrepared(params) {
142
161
  const mkdirRes = await runDatasetSandboxCommandStep({ env, sandboxId, cmd: "mkdir", args: ["-p", workstation] });
143
162
  // Align with dataset sandbox behavior: install python deps up-front (once per dataset sandbox).
144
163
  // This avoids tool-level "install if used" heuristics and ensures scripts can import pandas.
145
- if (!shouldSkipPipInstall()) {
164
+ if (!shouldSkipPipInstall(params.sandboxConfig)) {
146
165
  const pipInstall = await runDatasetSandboxCommandStep({
147
166
  env,
148
167
  sandboxId,
@@ -266,6 +285,7 @@ function createStructureStoryDefinition(config) {
266
285
  sandboxId,
267
286
  sources: config.sources,
268
287
  state: sandboxState,
288
+ sandboxConfig: resolvedSandboxConfig,
269
289
  });
270
290
  if (config.mode === "schema" && config.outputSchema) {
271
291
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ekairos/structure",
3
- "version": "1.21.77-beta.0",
3
+ "version": "1.21.78-beta.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,7 +36,7 @@
36
36
  "typecheck": "tsc --noEmit"
37
37
  },
38
38
  "dependencies": {
39
- "@ekairos/domain": "^1.21.77-beta.0",
39
+ "@ekairos/domain": "^1.21.78-beta.0",
40
40
  "@ekairos/sandbox": "^1.21.60-beta.0",
41
41
  "@instantdb/admin": "^0.22.13",
42
42
  "@instantdb/core": "^0.22.13",