@polos/sdk 0.2.0 → 0.2.2

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.
package/dist/index.cjs CHANGED
@@ -318,7 +318,7 @@ var OrchestratorClient = class {
318
318
  }
319
319
  if (attempt < retries) {
320
320
  const delay = Math.min(1e3 * Math.pow(2, attempt), 16e3);
321
- await new Promise((resolve8) => setTimeout(resolve8, delay));
321
+ await new Promise((resolve10) => setTimeout(resolve10, delay));
322
322
  }
323
323
  }
324
324
  }
@@ -770,7 +770,7 @@ var OrchestratorClient = class {
770
770
  if (execution.status === "completed" || execution.status === "failed" || execution.status === "cancelled") {
771
771
  return execution;
772
772
  }
773
- await new Promise((resolve8) => setTimeout(resolve8, pollInterval));
773
+ await new Promise((resolve10) => setTimeout(resolve10, pollInterval));
774
774
  }
775
775
  throw new Error(`Execution ${executionId} timed out after ${String(timeout)}ms`);
776
776
  }
@@ -1696,7 +1696,7 @@ function calculateDelay(attempt, options) {
1696
1696
  return Math.round(delay);
1697
1697
  }
1698
1698
  function sleep(ms) {
1699
- return new Promise((resolve8) => setTimeout(resolve8, ms));
1699
+ return new Promise((resolve10) => setTimeout(resolve10, ms));
1700
1700
  }
1701
1701
  async function retry(fn, options = {}) {
1702
1702
  const opts = { ...DEFAULT_OPTIONS, ...options };
@@ -1882,7 +1882,7 @@ function createStepHelper(options) {
1882
1882
  if (options2.days) totalSeconds += options2.days * 86400;
1883
1883
  if (options2.weeks) totalSeconds += options2.weeks * 604800;
1884
1884
  const totalMs = totalSeconds * 1e3;
1885
- await new Promise((resolve8) => setTimeout(resolve8, totalMs));
1885
+ await new Promise((resolve10) => setTimeout(resolve10, totalMs));
1886
1886
  store.set(key, { wait_until: new Date(Date.now() + totalMs).toISOString() });
1887
1887
  },
1888
1888
  async waitUntil(key, date) {
@@ -1890,7 +1890,7 @@ function createStepHelper(options) {
1890
1890
  if (cached) return;
1891
1891
  const now = Date.now();
1892
1892
  const waitMs = Math.max(0, date.getTime() - now);
1893
- await new Promise((resolve8) => setTimeout(resolve8, waitMs));
1893
+ await new Promise((resolve10) => setTimeout(resolve10, waitMs));
1894
1894
  store.set(key, { wait_until: date.toISOString() });
1895
1895
  },
1896
1896
  // eslint-disable-next-line @typescript-eslint/require-await -- stub implementation
@@ -4530,7 +4530,7 @@ function createOrchestratorStepHelper(orchestratorClient, cachedSteps, execCtx,
4530
4530
  });
4531
4531
  const waitThreshold = Number(process.env["POLOS_WAIT_THRESHOLD_SECONDS"] ?? "10");
4532
4532
  if (totalSeconds <= waitThreshold) {
4533
- await new Promise((resolve8) => setTimeout(resolve8, totalSeconds * 1e3));
4533
+ await new Promise((resolve10) => setTimeout(resolve10, totalSeconds * 1e3));
4534
4534
  await saveStepOutput(key, { wait_until: waitUntil.toISOString() });
4535
4535
  return;
4536
4536
  }
@@ -4566,7 +4566,7 @@ function createOrchestratorStepHelper(orchestratorClient, cachedSteps, execCtx,
4566
4566
  });
4567
4567
  const waitThreshold = Number(process.env["POLOS_WAIT_THRESHOLD_SECONDS"] ?? "10");
4568
4568
  if (waitSeconds <= waitThreshold) {
4569
- await new Promise((resolve8) => setTimeout(resolve8, waitSeconds * 1e3));
4569
+ await new Promise((resolve10) => setTimeout(resolve10, waitSeconds * 1e3));
4570
4570
  await saveStepOutput(key, { wait_until: date.toISOString() });
4571
4571
  return;
4572
4572
  }
@@ -5319,7 +5319,7 @@ var DEFAULT_CONTAINER_WORKDIR = "/workspace";
5319
5319
  var DEFAULT_TIMEOUT_SECONDS = 300;
5320
5320
  var DEFAULT_MAX_OUTPUT_CHARS = 1e5;
5321
5321
  function spawnCommand(command, args, options) {
5322
- return new Promise((resolve8, reject) => {
5322
+ return new Promise((resolve10, reject) => {
5323
5323
  let settled = false;
5324
5324
  const settle = (fn) => {
5325
5325
  if (!settled) {
@@ -5348,21 +5348,42 @@ function spawnCommand(command, args, options) {
5348
5348
  killed = true;
5349
5349
  proc.kill("SIGKILL");
5350
5350
  }, timeoutMs);
5351
+ let exitGraceTimer = null;
5352
+ let exitCode = null;
5353
+ proc.on("exit", (code) => {
5354
+ exitCode = code;
5355
+ exitGraceTimer = setTimeout(() => {
5356
+ clearTimeout(timer);
5357
+ settle(() => {
5358
+ if (killed) {
5359
+ resolve10({
5360
+ exitCode: 137,
5361
+ stdout,
5362
+ stderr: stderr + "\n[Process killed: timeout exceeded]"
5363
+ });
5364
+ } else {
5365
+ resolve10({ exitCode: exitCode ?? 1, stdout, stderr });
5366
+ }
5367
+ });
5368
+ }, 2e3);
5369
+ });
5351
5370
  proc.on("close", (code) => {
5371
+ if (exitGraceTimer) clearTimeout(exitGraceTimer);
5352
5372
  clearTimeout(timer);
5353
5373
  settle(() => {
5354
5374
  if (killed) {
5355
- resolve8({
5375
+ resolve10({
5356
5376
  exitCode: 137,
5357
5377
  stdout,
5358
5378
  stderr: stderr + "\n[Process killed: timeout exceeded]"
5359
5379
  });
5360
5380
  } else {
5361
- resolve8({ exitCode: code ?? 1, stdout, stderr });
5381
+ resolve10({ exitCode: code ?? exitCode ?? 1, stdout, stderr });
5362
5382
  }
5363
5383
  });
5364
5384
  });
5365
5385
  proc.on("error", (err) => {
5386
+ if (exitGraceTimer) clearTimeout(exitGraceTimer);
5366
5387
  clearTimeout(timer);
5367
5388
  settle(() => {
5368
5389
  reject(err);
@@ -5575,7 +5596,7 @@ var DockerEnvironment = class {
5575
5596
  var DEFAULT_TIMEOUT_SECONDS2 = 300;
5576
5597
  var DEFAULT_MAX_OUTPUT_CHARS2 = 1e5;
5577
5598
  function spawnLocal(command, options) {
5578
- return new Promise((resolve8, reject) => {
5599
+ return new Promise((resolve10, reject) => {
5579
5600
  let settled = false;
5580
5601
  const settle = (fn) => {
5581
5602
  if (!settled) {
@@ -5608,21 +5629,42 @@ function spawnLocal(command, options) {
5608
5629
  killed = true;
5609
5630
  proc.kill("SIGKILL");
5610
5631
  }, timeoutMs);
5632
+ let exitGraceTimer = null;
5633
+ let exitCode = null;
5634
+ proc.on("exit", (code) => {
5635
+ exitCode = code;
5636
+ exitGraceTimer = setTimeout(() => {
5637
+ clearTimeout(timer);
5638
+ settle(() => {
5639
+ if (killed) {
5640
+ resolve10({
5641
+ exitCode: 137,
5642
+ stdout,
5643
+ stderr: stderr + "\n[Process killed: timeout exceeded]"
5644
+ });
5645
+ } else {
5646
+ resolve10({ exitCode: exitCode ?? 1, stdout, stderr });
5647
+ }
5648
+ });
5649
+ }, 2e3);
5650
+ });
5611
5651
  proc.on("close", (code) => {
5652
+ if (exitGraceTimer) clearTimeout(exitGraceTimer);
5612
5653
  clearTimeout(timer);
5613
5654
  settle(() => {
5614
5655
  if (killed) {
5615
- resolve8({
5656
+ resolve10({
5616
5657
  exitCode: 137,
5617
5658
  stdout,
5618
5659
  stderr: stderr + "\n[Process killed: timeout exceeded]"
5619
5660
  });
5620
5661
  } else {
5621
- resolve8({ exitCode: code ?? 1, stdout, stderr });
5662
+ resolve10({ exitCode: code ?? exitCode ?? 1, stdout, stderr });
5622
5663
  }
5623
5664
  });
5624
5665
  });
5625
5666
  proc.on("error", (err) => {
5667
+ if (exitGraceTimer) clearTimeout(exitGraceTimer);
5626
5668
  clearTimeout(timer);
5627
5669
  settle(() => {
5628
5670
  reject(err);
@@ -6026,8 +6068,8 @@ var SandboxManager = class {
6026
6068
  }
6027
6069
  let resolveLock;
6028
6070
  let rejectLock;
6029
- const lockPromise = new Promise((resolve8, reject) => {
6030
- resolveLock = resolve8;
6071
+ const lockPromise = new Promise((resolve10, reject) => {
6072
+ resolveLock = resolve10;
6031
6073
  rejectLock = reject;
6032
6074
  });
6033
6075
  this.sessionCreationLocks.set(ctx.sessionId, lockPromise);
@@ -6219,7 +6261,7 @@ var SandboxManager = class {
6219
6261
  }
6220
6262
  };
6221
6263
  function spawnSimple(command, args) {
6222
- return new Promise((resolve8, reject) => {
6264
+ return new Promise((resolve10, reject) => {
6223
6265
  const proc = child_process.spawn(command, args, { stdio: ["pipe", "pipe", "pipe"] });
6224
6266
  let stdout = "";
6225
6267
  let stderr = "";
@@ -6230,7 +6272,7 @@ function spawnSimple(command, args) {
6230
6272
  stderr += data.toString();
6231
6273
  });
6232
6274
  proc.on("close", (code) => {
6233
- resolve8({ exitCode: code ?? 1, stdout, stderr });
6275
+ resolve10({ exitCode: code ?? 1, stdout, stderr });
6234
6276
  });
6235
6277
  proc.on("error", reject);
6236
6278
  });
@@ -6365,10 +6407,10 @@ var Worker = class {
6365
6407
  process.on("SIGINT", signalHandler);
6366
6408
  process.on("SIGTERM", signalHandler);
6367
6409
  this.signalHandler = signalHandler;
6368
- await new Promise((resolve8) => {
6410
+ await new Promise((resolve10) => {
6369
6411
  const checkState = () => {
6370
6412
  if (this.state === "stopping" || this.state === "stopped") {
6371
- resolve8();
6413
+ resolve10();
6372
6414
  } else {
6373
6415
  setTimeout(checkState, 100);
6374
6416
  }
@@ -6402,7 +6444,7 @@ var Worker = class {
6402
6444
  const waitTimeout = 3e4;
6403
6445
  const waitStart = Date.now();
6404
6446
  while (this.activeExecutions.size > 0 && Date.now() - waitStart < waitTimeout) {
6405
- await new Promise((resolve8) => setTimeout(resolve8, 100));
6447
+ await new Promise((resolve10) => setTimeout(resolve10, 100));
6406
6448
  }
6407
6449
  if (this.activeExecutions.size > 0) {
6408
6450
  logger9.warn(`${String(this.activeExecutions.size)} executions did not complete in time`);
@@ -7507,7 +7549,7 @@ function createReadTool(getEnv, pathConfig) {
7507
7549
  }
7508
7550
  );
7509
7551
  }
7510
- function createWriteTool(getEnv, approval) {
7552
+ function createWriteTool(getEnv, config) {
7511
7553
  return defineTool(
7512
7554
  {
7513
7555
  id: "write",
@@ -7516,16 +7558,23 @@ function createWriteTool(getEnv, approval) {
7516
7558
  path: zod.z.string().describe("Path to the file to write"),
7517
7559
  content: zod.z.string().describe("Content to write to the file")
7518
7560
  }),
7519
- approval
7561
+ // Only use blanket approval if explicitly set to 'always'
7562
+ approval: config?.approval === "always" ? "always" : void 0
7520
7563
  },
7521
- async (_ctx, input) => {
7564
+ async (ctx, input) => {
7522
7565
  const env = await getEnv();
7566
+ if (!config?.approval && config?.pathConfig?.pathRestriction) {
7567
+ const resolved = path.resolve(env.getCwd(), input.path);
7568
+ if (!isPathAllowed(resolved, config.pathConfig.pathRestriction)) {
7569
+ await requirePathApproval(ctx, "write", resolved, config.pathConfig.pathRestriction);
7570
+ }
7571
+ }
7523
7572
  await env.writeFile(input.path, input.content);
7524
7573
  return { success: true, path: input.path };
7525
7574
  }
7526
7575
  );
7527
7576
  }
7528
- function createEditTool(getEnv, approval) {
7577
+ function createEditTool(getEnv, config) {
7529
7578
  return defineTool(
7530
7579
  {
7531
7580
  id: "edit",
@@ -7535,10 +7584,17 @@ function createEditTool(getEnv, approval) {
7535
7584
  old_text: zod.z.string().describe("Exact text to find and replace"),
7536
7585
  new_text: zod.z.string().describe("Text to replace the old_text with")
7537
7586
  }),
7538
- approval
7587
+ // Only use blanket approval if explicitly set to 'always'
7588
+ approval: config?.approval === "always" ? "always" : void 0
7539
7589
  },
7540
- async (_ctx, input) => {
7590
+ async (ctx, input) => {
7541
7591
  const env = await getEnv();
7592
+ if (!config?.approval && config?.pathConfig?.pathRestriction) {
7593
+ const resolved = path.resolve(env.getCwd(), input.path);
7594
+ if (!isPathAllowed(resolved, config.pathConfig.pathRestriction)) {
7595
+ await requirePathApproval(ctx, "edit", resolved, config.pathConfig.pathRestriction);
7596
+ }
7597
+ }
7542
7598
  const content = await env.readFile(input.path);
7543
7599
  if (!content.includes(input.old_text)) {
7544
7600
  throw new Error(
@@ -7643,16 +7699,17 @@ function sandboxTools(config) {
7643
7699
  throw new Error("E2B environment is not yet implemented.");
7644
7700
  }
7645
7701
  const effectiveExecConfig = envType === "local" && !config?.exec?.security ? { ...config?.exec, security: "approval-always" } : config?.exec;
7646
- const fileApproval = config?.fileApproval ?? (envType === "local" ? "always" : void 0);
7647
7702
  const pathConfig = config?.local?.pathRestriction ? { pathRestriction: config.local.pathRestriction } : void 0;
7703
+ const fileApproval = config?.fileApproval;
7704
+ const writeEditConfig = fileApproval ? { approval: fileApproval } : pathConfig ? { pathConfig } : void 0;
7648
7705
  const include = new Set(
7649
7706
  config?.tools ?? ["exec", "read", "write", "edit", "glob", "grep"]
7650
7707
  );
7651
7708
  const tools = [];
7652
7709
  if (include.has("exec")) tools.push(createExecTool(getEnv, effectiveExecConfig));
7653
7710
  if (include.has("read")) tools.push(createReadTool(getEnv, pathConfig));
7654
- if (include.has("write")) tools.push(createWriteTool(getEnv, fileApproval));
7655
- if (include.has("edit")) tools.push(createEditTool(getEnv, fileApproval));
7711
+ if (include.has("write")) tools.push(createWriteTool(getEnv, writeEditConfig));
7712
+ if (include.has("edit")) tools.push(createEditTool(getEnv, writeEditConfig));
7656
7713
  if (include.has("glob")) tools.push(createGlobTool(getEnv, pathConfig));
7657
7714
  if (include.has("grep")) tools.push(createGrepTool(getEnv, pathConfig));
7658
7715
  return tools;