@sema-agent/server 1.291.0 → 1.293.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.
package/README.md CHANGED
@@ -134,7 +134,7 @@ The server is configured entirely through environment variables. The most import
134
134
  | `MODEL_ID` | `Qwen3.5-35B` | Default model id |
135
135
  | `MODEL_API_KEY` | — | Gateway API key (optional) |
136
136
  | `SERVICE_AUTH_TOKEN` | — | Callers must send `Authorization: Bearer <token>` |
137
- | `DB_BACKEND` | `mysql` | SQL engine: `mysql` (any MySQL-protocol DB: MySQL/TiDB/MariaDB; `tidb` is an alias) / `pg` (PostgreSQL) / `local` (file-backed, no DB). Setting `mysql`/`pg` explicitly also switches sessions to durable |
137
+ | `DB_BACKEND` | `local`* | `mysql` (any MySQL-protocol DB: MySQL/TiDB/MariaDB; `tidb` alias) / `pg` (PostgreSQL) / `local` (file-backed, no DB) / `memory` (explicit in-memory: nothing survives a restart, durable-runs faces 501). *Bare boot (no DB env at all) defaults to `local` so a single-user machine keeps its runs across restarts; any SQL signal (`SESSION_BACKEND` or `TIDB_/MYSQL_/PG_HOST`) keeps the `mysql` engine default, and `REQUIRE_PRINCIPAL=true` bare boots stay `memory` (the local file store has no tenant isolation — a warning says so). A DEFAULT-derived `local` that cannot create its data root degrades to memory with a warning + the `store_backend_degraded` gauge; an EXPLICIT `DB_BACKEND=local` fails loud instead. Setting `mysql`/`pg` explicitly also switches sessions to durable |
138
138
  | `SESSION_BACKEND` | `memory`* | `memory` / `mysql` (durable session center; `tidb` alias) / `auto`. *Defaults to durable when `DB_BACKEND` is explicitly `mysql`/`pg` |
139
139
  | `REMOTE_EXEC` | unset | Sandbox execution lane: `host` / `local-docker` / `e2b` / `k8s` / `ssh` / `adb`; unset = in-process stub (with `CONFIG_PROVIDER=local` the default becomes `host`) |
140
140
  | `CONFIG_PROVIDER` | unset | Config source: `local` (file-backed `config.d/`, single machine) / `remote` (registry control plane) |
package/dist/config.d.ts CHANGED
@@ -141,7 +141,8 @@ export interface ServiceConfig {
141
141
  database: string;
142
142
  connectionLimit?: number;
143
143
  };
144
- dbBackend: "mysql" | "pg" | "local";
144
+ dbBackend: "mysql" | "pg" | "local" | "memory";
145
+ dbBackendExplicit: boolean;
145
146
  localDataRoot?: string;
146
147
  pg?: {
147
148
  host: string;
package/dist/config.js CHANGED
@@ -168,9 +168,22 @@ export function loadConfig() {
168
168
  const modelId = env("MODEL_ID", "Qwen3.5-35B");
169
169
  const singleUserTurnkey = process.env.REQUIRE_PRINCIPAL !== "true";
170
170
  const postureOn = (envVal, infraReady = true) => envVal === "true" ? true : envVal === "false" ? false : singleUserTurnkey && infraReady;
171
- const dbBackendRaw = enumEnv("DB_BACKEND", "mysql", ["mysql", "tidb", "pg", "local"]);
171
+ const dbBackendSet = !!process.env.DB_BACKEND;
172
+ const sqlSignal = (!!process.env.SESSION_BACKEND && process.env.SESSION_BACKEND !== "memory") ||
173
+ !!(process.env.TIDB_HOST || process.env.MYSQL_HOST || process.env.PG_HOST);
174
+ const bareBoot = !dbBackendSet && !sqlSignal;
175
+ const multiTenantBareBoot = bareBoot && process.env.REQUIRE_PRINCIPAL === "true";
176
+ const dbBackendRaw = enumEnv("DB_BACKEND", bareBoot ? (multiTenantBareBoot ? "memory" : "local") : "mysql", ["mysql", "tidb", "pg", "local", "memory"]);
172
177
  const dbBackend = dbBackendRaw === "tidb" ? "mysql" : dbBackendRaw;
173
- const sqlEngineExplicit = !!process.env.DB_BACKEND && dbBackend !== "local";
178
+ if (multiTenantBareBoot) {
179
+ CONFIG_NOTICES.push({
180
+ event: "db_backend_default_memory_multi_tenant",
181
+ fields: {
182
+ note: "REQUIRE_PRINCIPAL=true with no DB_BACKEND — the single-user default (local file store) is incompatible with multi-tenant (no tenant isolation in the file owner map), so this deployment runs IN-MEMORY (runs/sessions lost on restart, durable runs 501). Configure DB_BACKEND=mysql|pg for a durable multi-tenant deployment.",
183
+ },
184
+ });
185
+ }
186
+ const sqlEngineExplicit = !!process.env.DB_BACKEND && dbBackend !== "local" && dbBackend !== "memory";
174
187
  const sessionBackendRaw = enumEnv("SESSION_BACKEND", sqlEngineExplicit ? "mysql" : "memory", ["memory", "mysql", "tidb", "auto"]);
175
188
  const sessionBackend = sessionBackendRaw === "mysql" ? "tidb" : sessionBackendRaw;
176
189
  const memoryEngineEnabled = process.env.MEMORY_ENGINE !== "off";
@@ -487,6 +500,7 @@ export function loadConfig() {
487
500
  }
488
501
  : undefined,
489
502
  dbBackend,
503
+ dbBackendExplicit: dbBackendSet,
490
504
  localDataRoot,
491
505
  tidb: needsDb && dbBackend === "mysql"
492
506
  ? {
@@ -1138,6 +1138,23 @@ export function createHttpServer(deps) {
1138
1138
  else if (ev.type === "workspace_changed") {
1139
1139
  res.write(`data: ${JSON.stringify({ type: "workspace_changed", ...workspaceChangedEventData(ev) })}\n\n`);
1140
1140
  }
1141
+ else if (ev.type === "text_delta" || ev.type === "turn_end" || ev.type === "message_committed" || ev.type === "context_usage") {
1142
+ const e = ev;
1143
+ const ident = {
1144
+ ...(e.eventId !== undefined ? { eventId: e.eventId } : {}),
1145
+ ...(e.parentToolCallId !== undefined ? { parentToolCallId: e.parentToolCallId } : {}),
1146
+ ...(e.sourceTaskId !== undefined ? { sourceTaskId: e.sourceTaskId } : {}),
1147
+ ...(e.bgAgentId !== undefined ? { bgAgentId: e.bgAgentId } : {}),
1148
+ };
1149
+ const arm = ev.type === "text_delta"
1150
+ ? { type: "text_delta", delta: e.delta, ...ident }
1151
+ : ev.type === "turn_end"
1152
+ ? { type: "turn_end", ...(e.usage !== undefined ? { usage: e.usage } : {}), ...(e.usageMissing !== undefined ? { usageMissing: e.usageMissing } : {}), ...(e.stopReason !== undefined ? { stopReason: e.stopReason } : {}), ...ident }
1153
+ : ev.type === "message_committed"
1154
+ ? { type: "message_committed", entryId: e.entryId, role: e.role, ...(e.toolCallId !== undefined ? { toolCallId: e.toolCallId } : {}), ...ident }
1155
+ : { type: "context_usage", ...contextUsageEventData(ev), ...ident };
1156
+ res.write(`data: ${JSON.stringify(arm)}\n\n`);
1157
+ }
1141
1158
  else {
1142
1159
  res.write(`data: ${JSON.stringify(ev)}\n\n`);
1143
1160
  }
package/dist/main.js CHANGED
@@ -434,7 +434,7 @@ async function main() {
434
434
  await backend.ensureSchema();
435
435
  }
436
436
  catch (err) {
437
- if (config.sessionBackend === "auto") {
437
+ if (config.sessionBackend === "auto" || (config.dbBackend === "local" && !config.dbBackendExplicit)) {
438
438
  logger.warn("store_db_unreachable_fallback_memory", { backend: backend.kind, error: err instanceof Error ? err.message : String(err) });
439
439
  storeBackendDegraded = true;
440
440
  await backend.close().catch(() => undefined);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sema-agent/server",
3
- "version": "1.291.0",
3
+ "version": "1.293.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",