@sandagent/daemon 0.9.8 → 0.9.9-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.
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Merge `POST /api/coding/run` body `env` into the daemon process environment.
3
+ * Kept in-package so `@sandagent/daemon` does not depend on `@sandagent/manager`.
4
+ * Only string values and valid env-style keys are accepted.
5
+ */
6
+ /**
7
+ * Normalize `body.env` from JSON (string keys and string values only).
8
+ */
9
+ export declare function sanitizeCodingRunBodyEnv(parsed: unknown): Record<string, string> | undefined;
10
+ export interface CodingRunBodyWithEnv {
11
+ env?: unknown;
12
+ }
13
+ /**
14
+ * Merge daemon `process.env` with optional inline `env` from the request JSON.
15
+ */
16
+ export declare function mergeCodingRunProcessEnv(daemonEnv: Record<string, string>, body: CodingRunBodyWithEnv): Record<string, string>;
17
+ //# sourceMappingURL=coding-run-env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coding-run-env.d.ts","sourceRoot":"","sources":["../src/coding-run-env.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,OAAO,GACd,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAUpC;AAED,MAAM,WAAW,oBAAoB;IACnC,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACjC,IAAI,EAAE,oBAAoB,GACzB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAKxB"}
package/dist/index.js CHANGED
@@ -206788,6 +206788,28 @@ var DaemonRouter = class {
206788
206788
  import * as http3 from "node:http";
206789
206789
  import { URL as URL2 } from "node:url";
206790
206790
 
206791
+ // src/coding-run-env.ts
206792
+ function isValidEnvKey(key) {
206793
+ return /^[A-Za-z_][A-Za-z0-9_]*$/.test(key);
206794
+ }
206795
+ function sanitizeCodingRunBodyEnv(parsed) {
206796
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
206797
+ return void 0;
206798
+ }
206799
+ const out = {};
206800
+ for (const [k2, v2] of Object.entries(parsed)) {
206801
+ if (!isValidEnvKey(k2)) continue;
206802
+ if (typeof v2 === "string") out[k2] = v2;
206803
+ }
206804
+ return Object.keys(out).length > 0 ? out : void 0;
206805
+ }
206806
+ function mergeCodingRunProcessEnv(daemonEnv, body) {
206807
+ let merged = { ...daemonEnv };
206808
+ const inline2 = sanitizeCodingRunBodyEnv(body.env);
206809
+ if (inline2) merged = { ...merged, ...inline2 };
206810
+ return merged;
206811
+ }
206812
+
206791
206813
  // src/multipart.ts
206792
206814
  function parseMultipart(contentType, body) {
206793
206815
  const match2 = contentType.match(/boundary=(?:"([^"]+)"|([^\s;]+))/);
@@ -262142,7 +262164,7 @@ function createPiRunner(options2 = {}) {
262142
262164
  if (model == null) {
262143
262165
  const baseUrlEnvKey = `${provider.toUpperCase().replace(/-/g, "_")}_BASE_URL`;
262144
262166
  const apiKeyEnvKey = `${provider.toUpperCase().replace(/-/g, "_")}_API_KEY`;
262145
- const baseUrl = process.env[baseUrlEnvKey] ?? process.env.OPENAI_BASE_URL;
262167
+ const baseUrl = getEnvValue(options2.env, baseUrlEnvKey) ?? getEnvValue(options2.env, "OPENAI_BASE_URL");
262146
262168
  if (!baseUrl) {
262147
262169
  throw new Error(`Pi runner: model "${modelSpec}" not found in built-in catalog. Set ${baseUrlEnvKey} (or OPENAI_BASE_URL) to auto-register it.`);
262148
262170
  }
@@ -262458,7 +262480,16 @@ async function sandagentRun(req, res, env2) {
262458
262480
  }
262459
262481
  } catch (err) {
262460
262482
  const msg = err instanceof Error ? err.message : String(err);
262461
- res.write(`${JSON.stringify({ error: msg })}
262483
+ res.write(`data: ${JSON.stringify({ type: "error", errorText: msg })}
262484
+
262485
+ `);
262486
+ res.write(
262487
+ `data: ${JSON.stringify({ type: "finish", finishReason: "error" })}
262488
+
262489
+ `
262490
+ );
262491
+ res.write(`data: [DONE]
262492
+
262462
262493
  `);
262463
262494
  } finally {
262464
262495
  res.end();
@@ -262483,10 +262514,11 @@ function createDaemon(config) {
262483
262514
  const pathname = url.pathname;
262484
262515
  if (method === "POST" && pathname === "/api/coding/run") {
262485
262516
  const body2 = safeJsonParse(await readBody(req));
262517
+ const mergedEnv = mergeCodingRunProcessEnv(env2, body2);
262486
262518
  return sandagentRun(
262487
262519
  body2,
262488
262520
  res,
262489
- env2
262521
+ mergedEnv
262490
262522
  );
262491
262523
  }
262492
262524
  if (method === "POST" && pathname === "/api/fs/upload") {
@@ -1 +1 @@
1
- {"version":3,"file":"nextjs.d.ts","sourceRoot":"","sources":["../src/nextjs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAQH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,IASzD,KAAK,OAAO,KAAG,OAAO,CAAC,QAAQ,CAAC,CAkD/C"}
1
+ {"version":3,"file":"nextjs.d.ts","sourceRoot":"","sources":["../src/nextjs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AASH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,IASzD,KAAK,OAAO,KAAG,OAAO,CAAC,QAAQ,CAAC,CAmD/C"}
package/dist/nextjs.js CHANGED
@@ -206415,6 +206415,28 @@ var require_lib4 = __commonJS({
206415
206415
  }
206416
206416
  });
206417
206417
 
206418
+ // src/coding-run-env.ts
206419
+ function isValidEnvKey(key) {
206420
+ return /^[A-Za-z_][A-Za-z0-9_]*$/.test(key);
206421
+ }
206422
+ function sanitizeCodingRunBodyEnv(parsed) {
206423
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
206424
+ return void 0;
206425
+ }
206426
+ const out = {};
206427
+ for (const [k2, v2] of Object.entries(parsed)) {
206428
+ if (!isValidEnvKey(k2)) continue;
206429
+ if (typeof v2 === "string") out[k2] = v2;
206430
+ }
206431
+ return Object.keys(out).length > 0 ? out : void 0;
206432
+ }
206433
+ function mergeCodingRunProcessEnv(daemonEnv, body) {
206434
+ let merged = { ...daemonEnv };
206435
+ const inline2 = sanitizeCodingRunBodyEnv(body.env);
206436
+ if (inline2) merged = { ...merged, ...inline2 };
206437
+ return merged;
206438
+ }
206439
+
206418
206440
  // src/multipart.ts
206419
206441
  function parseMultipart(contentType, body) {
206420
206442
  const match2 = contentType.match(/boundary=(?:"([^"]+)"|([^\s;]+))/);
@@ -262138,7 +262160,7 @@ function createPiRunner(options2 = {}) {
262138
262160
  if (model == null) {
262139
262161
  const baseUrlEnvKey = `${provider.toUpperCase().replace(/-/g, "_")}_BASE_URL`;
262140
262162
  const apiKeyEnvKey = `${provider.toUpperCase().replace(/-/g, "_")}_API_KEY`;
262141
- const baseUrl = process.env[baseUrlEnvKey] ?? process.env.OPENAI_BASE_URL;
262163
+ const baseUrl = getEnvValue(options2.env, baseUrlEnvKey) ?? getEnvValue(options2.env, "OPENAI_BASE_URL");
262142
262164
  if (!baseUrl) {
262143
262165
  throw new Error(`Pi runner: model "${modelSpec}" not found in built-in catalog. Set ${baseUrlEnvKey} (or OPENAI_BASE_URL) to auto-register it.`);
262144
262166
  }
@@ -262451,8 +262473,15 @@ function codingRunStream(req, env2) {
262451
262473
  } catch (err) {
262452
262474
  const msg = err instanceof Error ? err.message : String(err);
262453
262475
  controller.enqueue(
262454
- new TextEncoder().encode(`${JSON.stringify({ error: msg })}
262455
- `)
262476
+ new TextEncoder().encode(
262477
+ `data: ${JSON.stringify({ type: "error", errorText: msg })}
262478
+
262479
+ data: ${JSON.stringify({ type: "finish", finishReason: "error" })}
262480
+
262481
+ data: [DONE]
262482
+
262483
+ `
262484
+ )
262456
262485
  );
262457
262486
  } finally {
262458
262487
  controller.close();
@@ -262485,7 +262514,8 @@ function createNextHandler(opts) {
262485
262514
  const method = req.method ?? "GET";
262486
262515
  if (method === "POST" && pathname === "/api/coding/run") {
262487
262516
  const body = await req.json().catch(() => ({}));
262488
- return codingRunStream(body, env2);
262517
+ const mergedEnv = mergeCodingRunProcessEnv(env2, body);
262518
+ return codingRunStream(body, mergedEnv);
262489
262519
  }
262490
262520
  if (method === "POST" && pathname === "/api/fs/upload") {
262491
262521
  try {
@@ -9,6 +9,8 @@ export interface RunRequest {
9
9
  resume?: string;
10
10
  skillPaths?: string[];
11
11
  cwd?: string;
12
+ /** Inline runner env (string map); same keys override. */
13
+ env?: Record<string, string>;
12
14
  }
13
15
  /**
14
16
  * POST /api/coding/run — Node http.ServerResponse version (standalone daemon)
@@ -1 +1 @@
1
- {"version":3,"file":"coding.d.ts","sourceRoot":"","sources":["../../src/routes/coding.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,IAAI,MAAM,WAAW,CAAC;AAGvC,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,UAAU,EACf,GAAG,EAAE,IAAI,CAAC,cAAc,EACxB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC1B,OAAO,CAAC,IAAI,CAAC,CAkCf;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,UAAU,EACf,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC1B,QAAQ,CA0CV"}
1
+ {"version":3,"file":"coding.d.ts","sourceRoot":"","sources":["../../src/routes/coding.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,IAAI,MAAM,WAAW,CAAC;AAGvC,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,UAAU,EACf,GAAG,EAAE,IAAI,CAAC,cAAc,EACxB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC1B,OAAO,CAAC,IAAI,CAAC,CAwCf;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,UAAU,EACf,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC1B,QAAQ,CA8CV"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAQlC,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC,MAAM,CAgG9D"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AASlC,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC,MAAM,CAiG9D"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sandagent/daemon",
3
- "version": "0.9.8",
3
+ "version": "0.9.9-beta.0",
4
4
  "description": "SandAgent Daemon - Unified API gateway for sandbox services (file, git, volumes)",
5
5
  "type": "module",
6
6
  "bin": {