@ekairos/dataset 1.22.100-beta.development.0 → 1.22.101-beta.feature-lab-task-sandbox-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.
@@ -112,17 +112,20 @@ async function tryMaterializeRawPdfFileResource(state, resource, targetDatasetId
112
112
  await runDatasetSandboxCommandStep({
113
113
  runtime: state.runtime,
114
114
  sandboxId,
115
+ sandbox: state.sandbox,
115
116
  cmd: "mkdir",
116
117
  args: ["-p", ...getDatasetStandardDirs(targetDatasetId)],
117
118
  });
118
119
  await writeDatasetSandboxFilesStep({
119
120
  runtime: state.runtime,
120
121
  sandboxId,
122
+ sandbox: state.sandbox,
121
123
  files: [{ path: resourcePath, contentBase64: file.contentBase64 }],
122
124
  });
123
125
  const install = await runDatasetSandboxCommandStep({
124
126
  runtime: state.runtime,
125
127
  sandboxId,
128
+ sandbox: state.sandbox,
126
129
  cmd: "python",
127
130
  args: ["-m", "pip", "install", "pypdf", "--quiet"],
128
131
  });
@@ -132,6 +135,7 @@ async function tryMaterializeRawPdfFileResource(state, resource, targetDatasetId
132
135
  await writeDatasetSandboxTextFilesStep({
133
136
  runtime: state.runtime,
134
137
  sandboxId,
138
+ sandbox: state.sandbox,
135
139
  files: [
136
140
  {
137
141
  path: scriptPath,
@@ -174,6 +178,7 @@ async function tryMaterializeRawPdfFileResource(state, resource, targetDatasetId
174
178
  const extraction = await runDatasetSandboxCommandStep({
175
179
  runtime: state.runtime,
176
180
  sandboxId,
181
+ sandbox: state.sandbox,
177
182
  cmd: "python",
178
183
  args: [scriptPath, resourcePath, outputPath, resource.fileId, fileName],
179
184
  });
@@ -183,6 +188,7 @@ async function tryMaterializeRawPdfFileResource(state, resource, targetDatasetId
183
188
  const output = await readDatasetSandboxTextFileStep({
184
189
  runtime: state.runtime,
185
190
  sandboxId,
191
+ sandbox: state.sandbox,
186
192
  path: outputPath,
187
193
  });
188
194
  const rows = parseJsonlDataRows(output.content);
@@ -223,12 +229,14 @@ async function writePreparedFileResourceToSandbox(params) {
223
229
  await runDatasetSandboxCommandStep({
224
230
  runtime: params.runtime,
225
231
  sandboxId: params.sandboxId,
232
+ sandbox: params.sandbox,
226
233
  cmd: "mkdir",
227
234
  args: ["-p", ...getDatasetStandardDirs(params.datasetId)],
228
235
  });
229
236
  await writeDatasetSandboxFilesStep({
230
237
  runtime: params.runtime,
231
238
  sandboxId: params.sandboxId,
239
+ sandbox: params.sandbox,
232
240
  files: [{ path: resourcePath, contentBase64: file.contentBase64 }],
233
241
  });
234
242
  return { fileName, resourcePath };
@@ -237,6 +245,8 @@ function resolveDatasetSandboxId(state, _targetDatasetId) {
237
245
  const sandboxId = String(state.sandboxId ?? "").trim();
238
246
  if (sandboxId)
239
247
  return sandboxId;
248
+ if (state.sandbox?.id)
249
+ return state.sandbox.id;
240
250
  throw new Error("dataset_sandbox_required");
241
251
  }
242
252
  export async function resolveDatasetAgentDurable(requestedDurable) {
@@ -393,6 +403,7 @@ export async function materializeSingleFileLikeResource(state, resource, targetD
393
403
  const preparedFile = await writePreparedFileResourceToSandbox({
394
404
  runtime: state.runtime,
395
405
  sandboxId,
406
+ sandbox: state.sandbox,
396
407
  datasetId: targetDatasetId,
397
408
  fileId: prepared.fileId,
398
409
  filename: prepared.filename,
@@ -1,7 +1,9 @@
1
1
  import type { InstaQLParams, ValidQuery } from "@instantdb/core";
2
2
  import type { DomainInstantSchema, DomainSchemaResult } from "@ekairos/domain";
3
3
  import type { EkairosRuntime, RuntimeForDomain } from "@ekairos/domain/runtime";
4
- import type { ContextIdentifier, ContextReactor, StoredContextResource } from "@ekairos/events";
4
+ import type { ContextIdentifier, StoredContextResource } from "@ekairos/events";
5
+ import type { ContextReactor } from "@ekairos/reactor/context";
6
+ import type { SandboxSession } from "@ekairos/sandbox";
5
7
  import { datasetDomain } from "../schema.js";
6
8
  import type { DatasetNotation } from "../notation.js";
7
9
  export type DatasetQueryResourceInput<D extends DomainSchemaResult = DomainSchemaResult> = {
@@ -99,6 +101,7 @@ export type DatasetBuilderState<Runtime extends AnyDatasetRuntime> = {
99
101
  contextResources?: StoredContextResource[];
100
102
  title?: string;
101
103
  sandboxId?: string;
104
+ sandbox?: SandboxSession;
102
105
  contextId?: string;
103
106
  outputSchema?: DatasetSchemaInput;
104
107
  output: DatasetOutput;
@@ -131,7 +134,7 @@ export type DatasetBuilder<Runtime extends AnyDatasetRuntime> = {
131
134
  title(title: string): DatasetBuilder<Runtime>;
132
135
  sandbox(input: {
133
136
  sandboxId: string;
134
- }): DatasetBuilder<Runtime>;
137
+ } | SandboxSession): DatasetBuilder<Runtime>;
135
138
  schema(schema: DatasetSchemaInput): DatasetBuilder<Runtime>;
136
139
  inferSchema(): DatasetBuilder<Runtime>;
137
140
  auto(): DatasetBuilder<Runtime>;
package/dist/dataset.js CHANGED
@@ -65,6 +65,11 @@ export function dataset(runtime, options = {}) {
65
65
  return api;
66
66
  },
67
67
  sandbox(input) {
68
+ if (isSandboxSession(input)) {
69
+ state.sandbox = input;
70
+ state.sandboxId = input.id;
71
+ return api;
72
+ }
68
73
  state.sandboxId = String(input?.sandboxId ?? "").trim();
69
74
  return api;
70
75
  },
@@ -126,6 +131,9 @@ export function dataset(runtime, options = {}) {
126
131
  instructions: buildObjectOutputInstructions(stateWithBuildOptions.instructions),
127
132
  }
128
133
  : stateWithBuildOptions;
134
+ if (effectiveState.sandbox && effectiveState.durable) {
135
+ throw new Error("dataset_sandbox_session_not_durable");
136
+ }
129
137
  const onlyResource = effectiveState.resources[0];
130
138
  const isSingleResource = effectiveState.resources.length === 1;
131
139
  const hasInstructions = Boolean(String(effectiveState.instructions ?? "").trim());
@@ -169,6 +177,14 @@ export function dataset(runtime, options = {}) {
169
177
  };
170
178
  return api;
171
179
  }
180
+ function isSandboxSession(value) {
181
+ return Boolean(value &&
182
+ typeof value === "object" &&
183
+ typeof value.id === "string" &&
184
+ typeof value.workspaceRoot === "string" &&
185
+ typeof value.writeFile === "function" &&
186
+ typeof value.exec === "function");
187
+ }
172
188
  function normalizeDatasetId(datasetId) {
173
189
  const normalized = String(datasetId ?? createDatasetId()).trim();
174
190
  if (!normalized) {
@@ -1,4 +1,4 @@
1
- import { defineAction } from "@ekairos/events";
1
+ import { defineAction } from "@ekairos/reactor/context";
2
2
  import { z } from "zod";
3
3
  import { materializeContextResourcesStep } from "./contextResources.js";
4
4
  import { getDatasetScriptsDir, getDatasetStandardDirs } from "./datasetFiles.js";
@@ -1,4 +1,4 @@
1
- import { type ContextReactor } from "@ekairos/events";
1
+ import { type ContextReactor } from "@ekairos/reactor/context";
2
2
  import type { FileParseContext, FileParseRunOptions, SandboxState } from "./file-dataset.types.js";
3
3
  export type { DatasetResult, FileParseContext, FileParseContextBuilder, FileParseContextParams, FileParseRunOptions, SandboxState, } from "./file-dataset.types.js";
4
4
  export declare function createFileParseContext<Env extends {
@@ -1,4 +1,5 @@
1
- import { createContext, INPUT_TEXT_ITEM_TYPE, WEB_CHANNEL, } from "@ekairos/events";
1
+ import { INPUT_TEXT_ITEM_TYPE, WEB_CHANNEL, } from "@ekairos/events";
2
+ import { createContext } from "@ekairos/reactor/context";
2
3
  import { createClearDatasetTool } from "../clearDataset.tool.js";
3
4
  import { createCompleteDatasetTool, didCompleteDatasetSucceed, getDatasetFatalFailure, } from "../completeDataset.tool.js";
4
5
  import { datasetGetByIdStep } from "../dataset/steps.js";
@@ -1,4 +1,4 @@
1
- import type { ContextReactor } from "@ekairos/events";
1
+ import type { ContextReactor } from "@ekairos/reactor/context";
2
2
  import type { FilePreviewContext } from "./filepreview.types.js";
3
3
  export type SandboxState = {
4
4
  initialized: boolean;
@@ -1,7 +1,7 @@
1
1
  import { z } from "zod";
2
2
  import type { DomainSchemaResult } from "@ekairos/domain";
3
3
  import type { EkairosRuntime, RuntimeForDomain } from "@ekairos/domain/runtime";
4
- import type { ContextReactor } from "@ekairos/events";
4
+ import type { ContextReactor } from "@ekairos/reactor/context";
5
5
  import { datasetDomain } from "./schema.js";
6
6
  declare const materializeDatasetToolInputSchema: z.ZodObject<{
7
7
  datasetId: z.ZodOptional<z.ZodString>;
@@ -1,4 +1,4 @@
1
- import { type SandboxConfig } from "@ekairos/sandbox";
1
+ import { type SandboxConfig, type SandboxSession } from "@ekairos/sandbox";
2
2
  export type DatasetSandboxId = string;
3
3
  export type CreateDatasetSandboxParams = Pick<SandboxConfig, "provider" | "timeoutMs" | "ports" | "resources" | "purpose" | "params" | "env" | "domain" | "dataset" | "vercel"> & {
4
4
  sandboxRuntime?: string;
@@ -16,12 +16,14 @@ export declare function createDatasetSandboxStep(params: {
16
16
  export declare function runDatasetSandboxCommandStep(params: {
17
17
  runtime: any;
18
18
  sandboxId: DatasetSandboxId;
19
+ sandbox?: SandboxSession;
19
20
  cmd: string;
20
21
  args?: string[];
21
22
  }): Promise<DatasetSandboxRunCommandResult>;
22
23
  export declare function writeDatasetSandboxFilesStep(params: {
23
24
  runtime: any;
24
25
  sandboxId: DatasetSandboxId;
26
+ sandbox?: SandboxSession;
25
27
  files: Array<{
26
28
  path: string;
27
29
  contentBase64: string;
@@ -30,6 +32,7 @@ export declare function writeDatasetSandboxFilesStep(params: {
30
32
  export declare function writeDatasetSandboxTextFilesStep(params: {
31
33
  runtime: any;
32
34
  sandboxId: DatasetSandboxId;
35
+ sandbox?: SandboxSession;
33
36
  files: Array<{
34
37
  path: string;
35
38
  content: string;
@@ -38,6 +41,7 @@ export declare function writeDatasetSandboxTextFilesStep(params: {
38
41
  export declare function readDatasetSandboxFileStep(params: {
39
42
  runtime: any;
40
43
  sandboxId: DatasetSandboxId;
44
+ sandbox?: SandboxSession;
41
45
  path: string;
42
46
  }): Promise<{
43
47
  contentBase64: string;
@@ -45,6 +49,7 @@ export declare function readDatasetSandboxFileStep(params: {
45
49
  export declare function readDatasetSandboxTextFileStep(params: {
46
50
  runtime: any;
47
51
  sandboxId: DatasetSandboxId;
52
+ sandbox?: SandboxSession;
48
53
  path: string;
49
54
  }): Promise<{
50
55
  content: string;
@@ -52,4 +57,5 @@ export declare function readDatasetSandboxTextFileStep(params: {
52
57
  export declare function stopDatasetSandboxStep(params: {
53
58
  runtime: any;
54
59
  sandboxId: DatasetSandboxId;
60
+ sandbox?: SandboxSession;
55
61
  }): Promise<void>;
@@ -5,6 +5,13 @@ import { promisify } from "node:util";
5
5
  import { SandboxService } from "@ekairos/sandbox";
6
6
  const execFileAsync = promisify(execFile);
7
7
  const localSandboxRoots = new Map();
8
+ function commandResultFromSession(result) {
9
+ return {
10
+ exitCode: Number(result?.exitCode ?? (result?.success === false ? 1 : 0)),
11
+ stdout: String(result?.output ?? result?.stdout ?? ""),
12
+ stderr: String(result?.error ?? result?.stderr ?? ""),
13
+ };
14
+ }
8
15
  function isLocalDatasetSandboxMode() {
9
16
  return String(process.env.DATASET_TEST_LOCAL_SANDBOX ?? "").trim() === "1";
10
17
  }
@@ -86,6 +93,13 @@ export async function createDatasetSandboxStep(params) {
86
93
  }
87
94
  export async function runDatasetSandboxCommandStep(params) {
88
95
  "use step";
96
+ if (params.sandbox) {
97
+ const result = await params.sandbox.exec({
98
+ command: params.cmd,
99
+ args: params.args ?? [],
100
+ });
101
+ return commandResultFromSession(result);
102
+ }
89
103
  if (isLocalDatasetSandboxMode()) {
90
104
  return await runLocalSandboxCommand({
91
105
  sandboxId: params.sandboxId,
@@ -106,6 +120,14 @@ export async function runDatasetSandboxCommandStep(params) {
106
120
  }
107
121
  export async function writeDatasetSandboxFilesStep(params) {
108
122
  "use step";
123
+ if (params.sandbox) {
124
+ await params.sandbox.writeFiles(params.files.map((file) => ({
125
+ path: file.path,
126
+ content: file.contentBase64,
127
+ encoding: "base64",
128
+ })));
129
+ return;
130
+ }
109
131
  if (isLocalDatasetSandboxMode()) {
110
132
  for (const file of params.files) {
111
133
  await fs.mkdir(path.dirname(file.path), { recursive: true });
@@ -121,6 +143,13 @@ export async function writeDatasetSandboxFilesStep(params) {
121
143
  }
122
144
  export async function writeDatasetSandboxTextFilesStep(params) {
123
145
  "use step";
146
+ if (params.sandbox) {
147
+ await params.sandbox.writeFiles(params.files.map((file) => ({
148
+ path: file.path,
149
+ content: file.content,
150
+ })));
151
+ return;
152
+ }
124
153
  if (isLocalDatasetSandboxMode()) {
125
154
  for (const file of params.files) {
126
155
  await fs.mkdir(path.dirname(file.path), { recursive: true });
@@ -140,6 +169,10 @@ export async function writeDatasetSandboxTextFilesStep(params) {
140
169
  }
141
170
  export async function readDatasetSandboxFileStep(params) {
142
171
  "use step";
172
+ if (params.sandbox) {
173
+ const content = await params.sandbox.readFile(params.path);
174
+ return { contentBase64: Buffer.from(content).toString("base64") };
175
+ }
143
176
  if (isLocalDatasetSandboxMode()) {
144
177
  const content = await fs.readFile(params.path);
145
178
  return { contentBase64: Buffer.from(content).toString("base64") };
@@ -153,6 +186,10 @@ export async function readDatasetSandboxFileStep(params) {
153
186
  }
154
187
  export async function readDatasetSandboxTextFileStep(params) {
155
188
  "use step";
189
+ if (params.sandbox) {
190
+ const content = await params.sandbox.readFile(params.path);
191
+ return { content: Buffer.from(content).toString("utf-8") };
192
+ }
156
193
  if (isLocalDatasetSandboxMode()) {
157
194
  const content = await fs.readFile(params.path, "utf-8");
158
195
  return { content };
@@ -166,6 +203,10 @@ export async function readDatasetSandboxTextFileStep(params) {
166
203
  }
167
204
  export async function stopDatasetSandboxStep(params) {
168
205
  "use step";
206
+ if (params.sandbox) {
207
+ await params.sandbox.stop();
208
+ return;
209
+ }
169
210
  if (isLocalDatasetSandboxMode()) {
170
211
  const root = getLocalSandboxRoot(params.sandboxId);
171
212
  await fs.rm(root, { recursive: true, force: true });
@@ -1,4 +1,4 @@
1
- import { type ContextReactor } from "@ekairos/events";
1
+ import { type ContextReactor } from "@ekairos/reactor/context";
2
2
  import type { TransformDatasetRunOptions, TransformSandboxState, TransformInputPreviewContext } from "./transform-dataset.types.js";
3
3
  export type { TransformDatasetAgentParams, TransformDatasetContext, TransformDatasetResult, TransformDatasetRunOptions, TransformPromptContext, TransformSandboxState, } from "./transform-dataset.types.js";
4
4
  export declare function createTransformDatasetContext<Env extends {
@@ -1,4 +1,5 @@
1
- import { createContext, INPUT_TEXT_ITEM_TYPE, WEB_CHANNEL, } from "@ekairos/events";
1
+ import { INPUT_TEXT_ITEM_TYPE, WEB_CHANNEL, } from "@ekairos/events";
2
+ import { createContext } from "@ekairos/reactor/context";
2
3
  import { createClearDatasetTool } from "../clearDataset.tool.js";
3
4
  import { createCompleteDatasetTool, didCompleteDatasetSucceed, getDatasetFatalFailure, } from "../completeDataset.tool.js";
4
5
  import { datasetUpdateSchemaStep } from "../dataset/steps.js";
@@ -1,4 +1,5 @@
1
- import type { ContextReactor, StoredContextResource } from "@ekairos/events";
1
+ import type { StoredContextResource } from "@ekairos/events";
2
+ import type { ContextReactor } from "@ekairos/reactor/context";
2
3
  import type { TransformInputPreviewContext } from "./filepreview.js";
3
4
  export type { TransformInputPreviewContext } from "./filepreview.js";
4
5
  export type TransformSandboxState = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ekairos/dataset",
3
- "version": "1.22.100-beta.development.0",
3
+ "version": "1.22.101-beta.feature-lab-task-sandbox-beta.0",
4
4
  "description": "Pulzar Dataset Tools",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -65,9 +65,10 @@
65
65
  "test:ai-sdk:instant": "vitest run -c vitest.codex.config.mts src/tests/materializeDataset.ai-sdk.instant.test.ts"
66
66
  },
67
67
  "dependencies": {
68
- "@ekairos/domain": "^1.22.100-beta.development.0",
69
- "@ekairos/events": "^1.22.100-beta.development.0",
70
- "@ekairos/sandbox": "^1.22.100-beta.development.0",
68
+ "@ekairos/domain": "^1.22.101-beta.feature-lab-task-sandbox-beta.0",
69
+ "@ekairos/events": "^1.22.101-beta.feature-lab-task-sandbox-beta.0",
70
+ "@ekairos/reactor": "^1.22.101-beta.feature-lab-task-sandbox-beta.0",
71
+ "@ekairos/sandbox": "^1.22.101-beta.feature-lab-task-sandbox-beta.0",
71
72
  "@instantdb/admin": "0.22.158",
72
73
  "@instantdb/core": "0.22.142",
73
74
  "ai": "^5.0.44",