@sema-agent/server 1.319.0 → 1.321.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,4 +1,4 @@
1
- import { projectEvents, runSummary, mapTraceEvent } from "../../trace/project.js";
1
+ import { projectEvents, taskSummary, mapTraceEvent } from "../../trace/project.js";
2
2
  import { projectArtifacts } from "../../trace/artifacts.js";
3
3
  import { usageSummary, usageSeries, usageBreakdown } from "../../usage-analytics.js";
4
4
  import { sleep } from "../sse-log.js";
@@ -146,7 +146,7 @@ async function handleTaskList(res, runStore, query, forceOwner) {
146
146
  const rows = await runStore.listRuns({ ...(status ? { status } : {}), ...(jobId ? { jobId } : {}), ...(source ? { source } : {}), ...(owner ? { owner } : {}), ...(cursor ? { cursor } : {}), limit: limit + 1 });
147
147
  const hasMore = rows.length > limit;
148
148
  const page = hasMore ? rows.slice(0, limit) : rows;
149
- const tasks = page.map((r) => runSummary(r));
149
+ const tasks = page.map((r) => taskSummary(r));
150
150
  const last = page[page.length - 1];
151
151
  const nextCursor = hasMore && last ? encodeCursor({ createdAt: last.createdAt, taskId: last.taskId }) : undefined;
152
152
  sendJson(res, 200, { tasks, ...(nextCursor ? { nextCursor } : {}) });
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export { loadConfig, type ServiceConfig } from "./config.js";
2
2
  export { createBrain } from "./brain.js";
3
3
  export { createSessionStore } from "./plugins/session-store.js";
4
+ export { createStoreBackend, type StoreBackend } from "./plugins/store-backend.js";
4
5
  export { createTidbPool, ensureSchema, SCHEMA_STATEMENTS } from "./plugins/tidb-pool.js";
5
6
  export { TiDBSessionStore } from "./plugins/tidb-session-store.js";
6
7
  export { TiDBSessionStorage } from "./plugins/tidb-session-storage.js";
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  export { loadConfig } from "./config.js";
2
2
  export { createBrain } from "./brain.js";
3
3
  export { createSessionStore } from "./plugins/session-store.js";
4
+ export { createStoreBackend } from "./plugins/store-backend.js";
4
5
  export { createTidbPool, ensureSchema, SCHEMA_STATEMENTS } from "./plugins/tidb-pool.js";
5
6
  export { TiDBSessionStore } from "./plugins/tidb-session-store.js";
6
7
  export { TiDBSessionStorage } from "./plugins/tidb-session-storage.js";
package/dist/main.js CHANGED
@@ -25,6 +25,7 @@ import { acceptShellScratchpadDir, buildEnvFacts, egressForRemoteExec, ensureScr
25
25
  import { normalizeSuggestNextPrompts, normalizeResilience, normalizeAttachments, normalizeResumeAtMode, resolveTaskLimits, taskAgentsSpecFragment, retainBackgroundProcessesFromBody, toolNameListFromBody, promptProfileFromBody } from "./spec-fields.js";
26
26
  import { createBrain, brainSummary } from "./brain.js";
27
27
  import { configLkgEnabled, loadConfig, logConfigDiagnostics, resolveBindHost } from "./config.js";
28
+ import { drainNumEnvWarnings } from "./plugins/remote-shell.js";
28
29
  import { resourceSuspendOptIn } from "./resource-suspend.js";
29
30
  import { createSessionStore, ensureChildSessionDurableWithPromotion } from "./plugins/session-store.js";
30
31
  import { ForkRoutingSessionStore } from "./plugins/fork-routing-session-store.js";
@@ -122,6 +123,8 @@ async function main() {
122
123
  const logger = createLogger(config.logLevel);
123
124
  const metrics = createMetrics();
124
125
  logConfigDiagnostics(logger);
126
+ for (const w of drainNumEnvWarnings())
127
+ logger.warn("config_env_invalid_using_default", { env: w.env, raw: w.raw });
125
128
  if ((config.roles?.verifier ?? "default") === "default") {
126
129
  logger.warn("verify_decorrelation_unavailable", {
127
130
  hint: "verifier role = default (= implementer) — adversarial verification grades its own work; set MODEL_VERIFIER=<catalog model id> to a heterogeneous model",
@@ -2,17 +2,18 @@ import path from "node:path";
2
2
  import { Sandbox, CommandExitError, FileType } from "e2b";
3
3
  import { FileError, ExecutionError, RemoteExecutionError, RollingTailBuffer, markTruncated, } from "@sema-agent/core";
4
4
  import { fileErrorFromExec } from "./remote-env-file-error.js";
5
+ import { numEnvOr } from "./remote-shell.js";
5
6
  import { BackgroundShellManager } from "./background-shell-support.js";
6
7
  const PROVIDER = "e2b";
7
8
  const DEFAULT_MOUNT_PATH = "/home/user";
8
9
  const DEFAULT_TIMEOUT_MS = 5 * 60_000;
9
- const E2B_SANDBOX_MAX_MS = Math.max(60_000, Math.floor(Number(process.env.E2B_SANDBOX_MAX_MS ?? "")) || 3_600_000);
10
+ const E2B_SANDBOX_MAX_MS = numEnvOr("E2B_SANDBOX_MAX_MS", 3_600_000, 60_000);
10
11
  const DEFAULT_RPC_TIMEOUT_MS = 60_000;
11
12
  const DEFAULT_LIVENESS_MS = 120_000;
12
13
  const DEFAULT_DATA_TIMEOUT_MS = 5 * 60_000;
13
- const E2B_BG_MAX_CONCURRENT = Math.max(1, Math.floor(Number(process.env.E2B_BG_MAX_CONCURRENT ?? "")) || 8);
14
- const E2B_BG_DEFAULT_TIMEOUT_SEC = Math.max(1, Math.floor(Number(process.env.E2B_BG_DEFAULT_TIMEOUT_SEC ?? "")) || 300);
15
- const E2B_BG_MAX_TIMEOUT_SEC = Math.max(E2B_BG_DEFAULT_TIMEOUT_SEC, Math.floor(Number(process.env.E2B_BG_MAX_TIMEOUT_SEC ?? "")) || 1800);
14
+ const E2B_BG_MAX_CONCURRENT = numEnvOr("E2B_BG_MAX_CONCURRENT", 8, 1);
15
+ const E2B_BG_DEFAULT_TIMEOUT_SEC = numEnvOr("E2B_BG_DEFAULT_TIMEOUT_SEC", 300, 1);
16
+ const E2B_BG_MAX_TIMEOUT_SEC = numEnvOr("E2B_BG_MAX_TIMEOUT_SEC", 1800, E2B_BG_DEFAULT_TIMEOUT_SEC);
16
17
  const E2B_BG_PROVIDER_BACKSTOP_PAD_SEC = 30;
17
18
  const ok = (value) => ({ ok: true, value });
18
19
  export class RemoteContainerExecutionEnv {
@@ -5,20 +5,20 @@ import fs from "node:fs/promises";
5
5
  import { randomBytes } from "node:crypto";
6
6
  import { openSync, closeSync, readSync, statSync, truncateSync, unlinkSync, mkdirSync, rmdirSync, mkdtempSync, existsSync, realpathSync } from "node:fs";
7
7
  import { StringDecoder } from "node:string_decoder";
8
- import { armPipeDestroyGrace } from "./remote-shell.js";
8
+ import { armPipeDestroyGrace, numEnvOr } from "./remote-shell.js";
9
9
  import { hostBackgroundShellEnabled, hostExecSpoolEnabled } from "../config.js";
10
10
  import { resolveHostShell, hostShell, spawnGroupOptions, killTreeHard, killTreeSoft, collapseWin32EnvKeys } from "./host-platform.js";
11
11
  import { BackgroundShellManager, seedMemStream, feedMemStream, drainMemStream } from "./background-shell-support.js";
12
12
  import { FileError, ExecutionError, RemoteExecutionError, scrubSecretEnv, RollingTailBuffer, markTruncated, SchedulerError, BackgroundShellError, } from "@sema-agent/core";
13
13
  const PROVIDER = "host";
14
14
  const DEFAULT_COMMAND_TIMEOUT_MS = 30 * 60_000;
15
- const HOST_BG_MAX_CONCURRENT = Math.max(1, Math.floor(Number(process.env.HOST_BG_MAX_CONCURRENT ?? "")) || 8);
16
- const HOST_BG_DEFAULT_TIMEOUT_SEC = Math.max(1, Math.floor(Number(process.env.HOST_BG_DEFAULT_TIMEOUT_SEC ?? "")) || 300);
17
- const HOST_BG_MAX_TIMEOUT_SEC = Math.max(HOST_BG_DEFAULT_TIMEOUT_SEC, Math.floor(Number(process.env.HOST_BG_MAX_TIMEOUT_SEC ?? "")) || 1800);
18
- const HOST_BG_READ_CAP = Math.max(64 * 1024, Math.floor(Number(process.env.HOST_BG_READ_CAP ?? "")) || 1024 * 1024);
19
- const HOST_BG_FILE_CAP = Math.max(HOST_BG_READ_CAP, Math.floor(Number(process.env.HOST_BG_FILE_CAP ?? "")) || 64 * 1024 * 1024);
20
- const HOST_BG_KILL_GRACE_MS = Math.max(0, Math.floor(Number(process.env.HOST_BG_KILL_GRACE_MS ?? "")) || 1000);
21
- const HOST_BG_MEM_CAP = Math.max(64 * 1024, Math.floor(Number(process.env.HOST_BG_MEM_CAP ?? "")) || 8 * 1024 * 1024);
15
+ const HOST_BG_MAX_CONCURRENT = numEnvOr("HOST_BG_MAX_CONCURRENT", 8, 1);
16
+ const HOST_BG_DEFAULT_TIMEOUT_SEC = numEnvOr("HOST_BG_DEFAULT_TIMEOUT_SEC", 300, 1);
17
+ const HOST_BG_MAX_TIMEOUT_SEC = numEnvOr("HOST_BG_MAX_TIMEOUT_SEC", 1800, HOST_BG_DEFAULT_TIMEOUT_SEC);
18
+ const HOST_BG_READ_CAP = numEnvOr("HOST_BG_READ_CAP", 1024 * 1024, 64 * 1024);
19
+ const HOST_BG_FILE_CAP = numEnvOr("HOST_BG_FILE_CAP", 64 * 1024 * 1024, HOST_BG_READ_CAP);
20
+ const HOST_BG_KILL_GRACE_MS = numEnvOr("HOST_BG_KILL_GRACE_MS", 1000, 0);
21
+ const HOST_BG_MEM_CAP = numEnvOr("HOST_BG_MEM_CAP", 8 * 1024 * 1024, 64 * 1024);
22
22
  const ok = (value) => ({ ok: true, value });
23
23
  const unsupported = (op) => ({
24
24
  ok: false,
@@ -4,7 +4,7 @@ import https from "node:https";
4
4
  import http from "node:http";
5
5
  import { StringDecoder } from "node:string_decoder";
6
6
  import WebSocket from "ws";
7
- import { shellQuote, kindFromMode } from "./remote-shell.js";
7
+ import { shellQuote, kindFromMode, numEnvOr } from "./remote-shell.js";
8
8
  import { presignS3Url } from "./s3-presign.js";
9
9
  import { FileError, ExecutionError, RemoteExecutionError, withRetry, RollingTailBuffer, markTruncated, } from "@sema-agent/core";
10
10
  import { fileErrorFromExec, classifyFsStderr } from "./remote-env-file-error.js";
@@ -13,12 +13,12 @@ import { randomUUID } from "node:crypto";
13
13
  import { BackgroundShellManager, seedMemStream, feedMemStream, drainMemStream } from "./background-shell-support.js";
14
14
  const PROVIDER = "k8s";
15
15
  const K8S_BG_DIR_ROOT = "/tmp/.sema-bg";
16
- const K8S_BG_MAX_CONCURRENT = Math.max(1, Math.floor(Number(process.env.K8S_BG_MAX_CONCURRENT ?? "")) || 8);
17
- const K8S_BG_DEFAULT_TIMEOUT_SEC = Math.max(1, Math.floor(Number(process.env.K8S_BG_DEFAULT_TIMEOUT_SEC ?? "")) || 300);
18
- const K8S_BG_MAX_TIMEOUT_SEC = Math.max(K8S_BG_DEFAULT_TIMEOUT_SEC, Math.floor(Number(process.env.K8S_BG_MAX_TIMEOUT_SEC ?? "")) || 1800);
19
- const K8S_BG_READ_CAP = Math.max(64 * 1024, Math.floor(Number(process.env.K8S_BG_READ_CAP ?? "")) || 1024 * 1024);
20
- const K8S_BG_FILE_CAP = Math.max(K8S_BG_READ_CAP, Math.floor(Number(process.env.K8S_BG_FILE_CAP ?? "")) || 64 * 1024 * 1024);
21
- const K8S_BG_MEM_CAP = Math.max(64 * 1024, Math.floor(Number(process.env.K8S_BG_MEM_CAP ?? "")) || 8 * 1024 * 1024);
16
+ const K8S_BG_MAX_CONCURRENT = numEnvOr("K8S_BG_MAX_CONCURRENT", 8, 1);
17
+ const K8S_BG_DEFAULT_TIMEOUT_SEC = numEnvOr("K8S_BG_DEFAULT_TIMEOUT_SEC", 300, 1);
18
+ const K8S_BG_MAX_TIMEOUT_SEC = numEnvOr("K8S_BG_MAX_TIMEOUT_SEC", 1800, K8S_BG_DEFAULT_TIMEOUT_SEC);
19
+ const K8S_BG_READ_CAP = numEnvOr("K8S_BG_READ_CAP", 1024 * 1024, 64 * 1024);
20
+ const K8S_BG_FILE_CAP = numEnvOr("K8S_BG_FILE_CAP", 64 * 1024 * 1024, K8S_BG_READ_CAP);
21
+ const K8S_BG_MEM_CAP = numEnvOr("K8S_BG_MEM_CAP", 8 * 1024 * 1024, 64 * 1024);
22
22
  import { buildBgRunnerScript, buildBgLauncherScript, buildBgPollScript, buildBgKillScript, buildBgDisposeScript, buildDetachCapableExec, parseBgPollOutput, } from "./k8s-bg-scripts.js";
23
23
  export { buildBgRunnerScript, buildBgLauncherScript, buildBgPollScript, buildBgKillScript, buildBgDisposeScript, buildDetachCapableExec, parseBgPollOutput, } from "./k8s-bg-scripts.js";
24
24
  const ok = (value) => ({ ok: true, value });
@@ -4,4 +4,9 @@ export declare const EXEC_FORCE_SETTLE_GRACE_MS = 3000;
4
4
  export declare function armPipeDestroyGrace(child: ChildProcess): ReturnType<typeof setTimeout>;
5
5
  export declare function shellQuote(s: string): string;
6
6
  export declare function kindFromMode(mode?: number): FileInfo["kind"];
7
+ export declare function drainNumEnvWarnings(): Array<{
8
+ env: string;
9
+ raw: string;
10
+ }>;
11
+ export declare function numEnvOr(name: string, def: number, min: number): number;
7
12
  //# sourceMappingURL=remote-shell.d.ts.map
@@ -22,4 +22,18 @@ export function kindFromMode(mode) {
22
22
  return "symlink";
23
23
  return "file";
24
24
  }
25
+ const NUM_ENV_WARNINGS = [];
26
+ const NUM_ENV_SEEN = new Set();
27
+ export function drainNumEnvWarnings() {
28
+ return NUM_ENV_WARNINGS.splice(0, NUM_ENV_WARNINGS.length);
29
+ }
30
+ export function numEnvOr(name, def, min) {
31
+ const raw = process.env[name] ?? "";
32
+ const n = Math.floor(Number(raw));
33
+ if (raw !== "" && Number.isNaN(n) && !NUM_ENV_SEEN.has(name)) {
34
+ NUM_ENV_SEEN.add(name);
35
+ NUM_ENV_WARNINGS.push({ env: name, raw });
36
+ }
37
+ return Math.max(min, n || def);
38
+ }
25
39
  //# sourceMappingURL=remote-shell.js.map
@@ -220,7 +220,7 @@ export interface TaskSummary {
220
220
  label?: string;
221
221
  };
222
222
  }
223
- export declare function runSummary(run: RunRecord, latestEventType?: string): TaskSummary;
223
+ export declare function taskSummary(run: RunRecord, latestEventType?: string): TaskSummary;
224
224
  export declare function normalizeRunEventType(type: string): string;
225
225
  export declare function mapTraceEvent(type: string, seq: number, data: Record<string, unknown>): {
226
226
  event: string;
@@ -281,7 +281,7 @@ export function lastStep(latestEventType, status) {
281
281
  return { type: "responding" };
282
282
  }
283
283
  }
284
- export function runSummary(run, latestEventType) {
284
+ export function taskSummary(run, latestEventType) {
285
285
  const stats = (run.result?.stats ?? {});
286
286
  const terminal = run.status !== "running";
287
287
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sema-agent/server",
3
- "version": "1.319.0",
3
+ "version": "1.321.0",
4
4
  "description": "Sema Server — the server/API implementation layer for Sema, wiring core, registry, model providers, and cloud agent execution. Built on @sema-agent/core.",
5
5
  "type": "module",
6
6
  "license": "BUSL-1.1",