@aiden-ade/sandbox-agent 0.1.24 → 0.1.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.cjs +88 -11
  2. package/package.json +3 -3
package/dist/index.cjs CHANGED
@@ -9598,7 +9598,7 @@ var PRIORITY_OPTIONS = [
9598
9598
  detail: "Low",
9599
9599
  color: CATEGORICAL_COLORS.blueBright,
9600
9600
  iconClass: "text-blue-500/70 dark:text-blue-400/70",
9601
- flagClass: "text-primary"
9601
+ flagClass: "text-blue-600 dark:text-blue-400"
9602
9602
  },
9603
9603
  {
9604
9604
  value: "none",
@@ -10251,6 +10251,10 @@ function createImageTempDirectory(cwd) {
10251
10251
  }
10252
10252
  return (0, import_fs2.mkdtempSync)((0, import_path2.join)((0, import_os2.tmpdir)(), "aiden-images-"));
10253
10253
  }
10254
+ function safeFilename(filename) {
10255
+ const safe = filename.replace(/[^a-zA-Z0-9._-]/g, "_").replace(/^_+/, "");
10256
+ return safe || "attachment";
10257
+ }
10254
10258
  function writeImagesToTempFiles(images, cwd) {
10255
10259
  if (!images?.length) return { paths: [], files: [], cleanup: () => {
10256
10260
  } };
@@ -10281,6 +10285,48 @@ function writeImagesToTempFiles(images, cwd) {
10281
10285
  }
10282
10286
  };
10283
10287
  }
10288
+ function writeFilesToTempFiles(files, cwd) {
10289
+ if (!files?.length) return { paths: [], files: [], cleanup: () => {
10290
+ } };
10291
+ const dataFiles = files.filter((file) => file.data !== void 0);
10292
+ const existingFiles = files.filter((file) => file.tempPath && file.data === void 0);
10293
+ const directory = dataFiles.length > 0 ? createImageTempDirectory(cwd) : null;
10294
+ const paths = [];
10295
+ const tempFiles = [];
10296
+ for (const file of existingFiles) {
10297
+ if (!file.tempPath) continue;
10298
+ paths.push(file.tempPath);
10299
+ tempFiles.push({
10300
+ filename: file.filename,
10301
+ mimeType: file.mimeType,
10302
+ label: file.label,
10303
+ path: file.tempPath
10304
+ });
10305
+ }
10306
+ for (const file of dataFiles) {
10307
+ if (!directory || file.data === void 0) continue;
10308
+ const filePath = (0, import_path2.join)(directory, `${file.id}-${safeFilename(file.filename)}`);
10309
+ (0, import_fs2.writeFileSync)(filePath, Buffer.from(file.data, "base64"));
10310
+ paths.push(filePath);
10311
+ tempFiles.push({
10312
+ filename: file.filename,
10313
+ mimeType: file.mimeType,
10314
+ label: file.label,
10315
+ path: filePath
10316
+ });
10317
+ }
10318
+ return {
10319
+ paths,
10320
+ files: tempFiles,
10321
+ cleanup: () => {
10322
+ if (!directory) return;
10323
+ try {
10324
+ (0, import_fs2.rmSync)(directory, { recursive: true, force: true });
10325
+ } catch {
10326
+ }
10327
+ }
10328
+ };
10329
+ }
10284
10330
  function appendImagePathReferences(prompt, images) {
10285
10331
  if (images.length === 0) return prompt;
10286
10332
  const imageLines = images.map((img) => {
@@ -11452,6 +11498,17 @@ function isOpenCodeToolError(parsed, part) {
11452
11498
  const state = getRecord(part?.state) ?? getRecord(parsed.state);
11453
11499
  return part?.is_error === true || part?.isError === true || state?.status === "error" || Boolean(getOpenCodeToolError(parsed, part));
11454
11500
  }
11501
+ function getOpenCodePartId(parsed, part) {
11502
+ return getString(part?.id) || getString(parsed.id) || getString(parsed.partID);
11503
+ }
11504
+ function resolveOpenCodeTextDelta(text, partId, state) {
11505
+ if (!partId) return text;
11506
+ state.opencodeTextByPartId ??= /* @__PURE__ */ new Map();
11507
+ const previous = state.opencodeTextByPartId.get(partId) ?? "";
11508
+ state.opencodeTextByPartId.set(partId, text);
11509
+ if (!previous || !text.startsWith(previous)) return text;
11510
+ return text.slice(previous.length);
11511
+ }
11455
11512
  function parseOpencodeStructuredLine(line, context, state) {
11456
11513
  const presenter = context.presenter;
11457
11514
  let parsed = null;
@@ -11475,8 +11532,10 @@ function parseOpencodeStructuredLine(line, context, state) {
11475
11532
  case "text": {
11476
11533
  const text = part && typeof part.text === "string" ? part.text : "";
11477
11534
  if (text) {
11478
- state.summary += text;
11479
- void presenter.onAssistantText(text);
11535
+ const delta = resolveOpenCodeTextDelta(text, getOpenCodePartId(parsed, part), state);
11536
+ if (!delta) break;
11537
+ state.summary += delta;
11538
+ void presenter.onAssistantText(delta);
11480
11539
  }
11481
11540
  break;
11482
11541
  }
@@ -11614,6 +11673,10 @@ function createOpencodeCliBackend(command = "opencode", defaultArgs = []) {
11614
11673
  context.config.images,
11615
11674
  context.cwd
11616
11675
  );
11676
+ const { paths: filePaths, cleanup: cleanupFiles } = writeFilesToTempFiles(
11677
+ context.config.files,
11678
+ context.cwd
11679
+ );
11617
11680
  try {
11618
11681
  const runContext = withAutonomousOpenCodePermissions(context);
11619
11682
  return await createGenericCliBackend({
@@ -11630,7 +11693,8 @@ function createOpencodeCliBackend(command = "opencode", defaultArgs = []) {
11630
11693
  if (resumeId) args.push("--session", resumeId);
11631
11694
  const model = ctx.config.selectedModel?.trim();
11632
11695
  if (model?.includes("/")) args.push("--model", model);
11633
- const fileArgs = imagePaths.flatMap((p) => ["--file", p]);
11696
+ const attachmentPaths = [...imagePaths, ...filePaths];
11697
+ const fileArgs = attachmentPaths.flatMap((p) => ["--file", p]);
11634
11698
  if (fileArgs.length > 0) {
11635
11699
  return [...args, ...fileArgs, ...defaultArgs, "--", prompt];
11636
11700
  }
@@ -11644,6 +11708,7 @@ function createOpencodeCliBackend(command = "opencode", defaultArgs = []) {
11644
11708
  }).run(runContext);
11645
11709
  } finally {
11646
11710
  cleanup();
11711
+ cleanupFiles();
11647
11712
  }
11648
11713
  }
11649
11714
  };
@@ -11849,7 +11914,8 @@ function canonicalizePath(inputPath) {
11849
11914
  }
11850
11915
  function buildPromptWithFiles(task, files) {
11851
11916
  if (!files || files.length === 0) return task;
11852
- const fileList = files.map((file) => `- ${file.filename} (${file.label}): ${file.tempPath}`).join("\n");
11917
+ const fileList = files.filter((file) => file.tempPath).map((file) => `- ${file.filename} (${file.label}): ${file.tempPath}`).join("\n");
11918
+ if (!fileList) return task;
11853
11919
  return `${task}
11854
11920
 
11855
11921
  The user has attached the following files. You can read them using your available tools:
@@ -12607,7 +12673,7 @@ function extractGeneratedImagesFromToolResult(toolId, content, cwd, toolName) {
12607
12673
  }
12608
12674
 
12609
12675
  // src/version.ts
12610
- var AGENT_VERSION = "0.1.24";
12676
+ var AGENT_VERSION = "0.1.25";
12611
12677
 
12612
12678
  // src/daemon.ts
12613
12679
  var OPENCODE_FREE_MODEL_IDS = [
@@ -12957,7 +13023,6 @@ async function setupDaemon(args) {
12957
13023
  const setupToken = argValue(args, "--setup-token") ?? process.env.AIDEN_RUNTIME_SETUP_TOKEN;
12958
13024
  const token = argValue(args, "--token") ?? process.env.AIDEN_SETUP_TOKEN;
12959
13025
  const displayName = argValue(args, "--name") ?? (0, import_node_os4.hostname)();
12960
- const legacyLocalMachineId = argValue(args, "--legacy-local-machine-id") ?? process.env.AIDEN_LEGACY_LOCAL_MACHINE_ID;
12961
13026
  const scope = argValue(args, "--scope") ?? process.env.AIDEN_RUNTIME_SCOPE ?? "team";
12962
13027
  if (scope !== "team" && scope !== "user") {
12963
13028
  throw new Error("setup --scope must be either 'team' or 'user'");
@@ -12980,7 +13045,6 @@ async function setupDaemon(args) {
12980
13045
  ...setupToken ? { setupToken } : {},
12981
13046
  displayName,
12982
13047
  hostname: (0, import_node_os4.hostname)(),
12983
- ...legacyLocalMachineId ? { legacyLocalMachineId } : {},
12984
13048
  runtimeKind: "machine",
12985
13049
  managementKind: "user_managed",
12986
13050
  hostKind: "daemon",
@@ -13194,7 +13258,8 @@ async function startDaemon(args) {
13194
13258
  teamId: payload.teamId,
13195
13259
  currentUser: payload.currentUser,
13196
13260
  workflowTools: payload.workflowTools,
13197
- images: payload.images
13261
+ images: payload.images,
13262
+ files: payload.files
13198
13263
  }).catch((error) => {
13199
13264
  const message = error instanceof Error ? error.message : String(error);
13200
13265
  pushLog(`failed run=${payload.runId} ${message}`);
@@ -13724,6 +13789,7 @@ var WSClient = class {
13724
13789
  callbacks.onUserMessage({
13725
13790
  text: data.text,
13726
13791
  images: data.images,
13792
+ files: data.files,
13727
13793
  providerSessionId: data.providerSessionId,
13728
13794
  backendKind: data.backendKind,
13729
13795
  agentId: data.agentId,
@@ -13763,8 +13829,10 @@ var WSClient = class {
13763
13829
  async function runSandbox(config) {
13764
13830
  let currentTask = config.task;
13765
13831
  let currentImages = [];
13832
+ let currentFiles = [];
13766
13833
  const stopped = false;
13767
13834
  let pendingMessageResolve = null;
13835
+ const queuedMessages = [];
13768
13836
  let currentAgent = null;
13769
13837
  let currentTaskMeta;
13770
13838
  let currentPrMeta;
@@ -13794,7 +13862,7 @@ async function runSandbox(config) {
13794
13862
  pendingMessageResolve = null;
13795
13863
  resolve2(payload);
13796
13864
  } else {
13797
- console.warn("[sandbox] No handler for user message \u2014 dropped");
13865
+ queuedMessages.push(payload);
13798
13866
  }
13799
13867
  },
13800
13868
  onStop: () => {
@@ -13874,6 +13942,14 @@ async function runSandbox(config) {
13874
13942
  filename: img.filename,
13875
13943
  width: 0,
13876
13944
  height: 0
13945
+ })) : void 0,
13946
+ files: currentFiles.length > 0 ? currentFiles.map((file) => ({
13947
+ id: file.id,
13948
+ data: file.data,
13949
+ mimeType: file.mimeType,
13950
+ filename: file.filename,
13951
+ size: file.size,
13952
+ label: file.label
13877
13953
  })) : void 0
13878
13954
  });
13879
13955
  } catch (error) {
@@ -13894,7 +13970,7 @@ async function runSandbox(config) {
13894
13970
  }
13895
13971
  if (stopped) break;
13896
13972
  }
13897
- const nextPayload = await new Promise((resolve2) => {
13973
+ const nextPayload = queuedMessages.shift() ?? await new Promise((resolve2) => {
13898
13974
  pendingMessageResolve = resolve2;
13899
13975
  });
13900
13976
  if (nextPayload === null || stopped) {
@@ -13902,6 +13978,7 @@ async function runSandbox(config) {
13902
13978
  }
13903
13979
  currentTask = nextPayload.text;
13904
13980
  currentImages = nextPayload.images ?? [];
13981
+ currentFiles = nextPayload.files ?? [];
13905
13982
  if (nextPayload.providerSessionId) {
13906
13983
  lastProviderSessionId = nextPayload.providerSessionId;
13907
13984
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiden-ade/sandbox-agent",
3
- "version": "0.1.24",
3
+ "version": "0.1.25",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "aiden-agent": "./dist/index.cjs"
@@ -19,8 +19,8 @@
19
19
  "tsup": "^8.5.1",
20
20
  "tsx": "^4.19.0",
21
21
  "typescript": "~5.9.3",
22
- "@aiden/agent-core": "0.1.0",
23
- "@aiden/shared": "0.1.0"
22
+ "@aiden/shared": "0.1.0",
23
+ "@aiden/agent-core": "0.1.0"
24
24
  },
25
25
  "scripts": {
26
26
  "build": "tsup",