@sema-agent/server 3.4.0 → 3.4.1

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.
@@ -3,7 +3,7 @@ import { principalFrom, verifyDirectDoorProof, MAX_APPROVAL_REASON_CHARS } from
3
3
  import { redactedPreview } from "../../trace/redact.js";
4
4
  import { sleep } from "../sse-log.js";
5
5
  import { sendJson, sendError, sseHeaders } from "../send.js";
6
- import { gatedPrincipal, explicitOperatorOk, isOperator, explicitOperator } from "../principal-gate.js";
6
+ import { gatedPrincipal, explicitOperatorOk, isOperator } from "../principal-gate.js";
7
7
  // design/80 seam #2 (assistant-scheduler): graceful preempt (durable yield) + resource_limit resume of one task.
8
8
  export const ASSISTANT_PREEMPT_RE = /^\/v1\/assistant\/tasks\/([^/]+)\/preempt$/;
9
9
  export const ASSISTANT_RESUME_RE = /^\/v1\/assistant\/tasks\/([^/]+)\/resume$/;
@@ -174,7 +174,16 @@ async function handleApprovalsAssistantBody(req, res, url, ctx, miss) {
174
174
  objective: ctx?.body?.objective ?? null,
175
175
  input,
176
176
  };
177
- }))).sort((a, b) => (b.severity ?? 0) - (a.severity ?? 0)); // severity DESC (listByScope is created_at ASC; stable → oldest-first within a tier)
177
+ }))
178
+ // severity DESC, then **explicitly** oldest-first within a tier ([2027] 第五节欠单②,红先绿后:
179
+ // test/assistant-triage-ordering.test.ts)。旧姿势只比 severity,靠「listByScope 是 created_at ASC
180
+ // + Array#sort 稳定」来兑现 §2 那句 oldest-first —— 而那个前提**只在本仓的 SQL 后端成立**
181
+ // (checkpoint-store-sql.ts 的 `ORDER BY created_at ASC`):core 的 `CheckpointStore.listByScope` 接口
182
+ // 零顺序声明,InMemory/File 两个实现直接遍历 Map(LOCAL 车道包的正是 File store)⇒ 那句承诺过去是
183
+ // **后端相关**的。比较器自带兜底后它与 store 顺序无关。形与 listPending 的同族 sort 逐字一致
184
+ // (checkpoint-store-sql.ts `|| a.createdAt - b.createdAt`)。createdAt 缺席(pre-1.116 投影的老行)
185
+ // 计 0 = 档内最老:确定性优于「看它恰好落在哪」。
186
+ ).sort((a, b) => (b.severity ?? 0) - (a.severity ?? 0) || (a.createdAt ?? 0) - (b.createdAt ?? 0));
178
187
  sendJson(res, 200, { inbox }); // CheckpointSummary (token-stripped) + objective, severity-prioritized — the assistant single inbox
179
188
  return;
180
189
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sema-agent/server",
3
- "version": "3.4.0",
3
+ "version": "3.4.1",
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",
@@ -1,34 +0,0 @@
1
- export interface InfraCostRates {
2
- toolCallMicroUsd: number;
3
- sandboxSecMicroUsd: number;
4
- egressGbMicroUsd: number;
5
- }
6
- export interface InfraUsage {
7
- toolCalls: number;
8
- sandboxWalltimeMs: number;
9
- egressBytes: number;
10
- }
11
- export interface InfraCostBreakdown {
12
- toolCallMicroUsd: number;
13
- sandboxWalltimeMicroUsd: number;
14
- egressMicroUsd: number;
15
- totalMicroUsd: number;
16
- }
17
- export interface LlmCostBreakdown {
18
- llmRootMicroUsd: number;
19
- nestedSubagentMicroUsd: number;
20
- memoryConsolidationMicroUsd: number;
21
- compactionMicroUsd: number;
22
- }
23
- export interface SupervisorCostBreakdown {
24
- llm: LlmCostBreakdown | null;
25
- infra: InfraCostBreakdown;
26
- totalMicroUsd: number;
27
- }
28
- export declare function infraCost(usage: InfraUsage, rates: InfraCostRates): InfraCostBreakdown;
29
- export declare function composeSupervisorCost(llm: LlmCostBreakdown | null, llmTotalMicroUsd: number, infra: InfraCostBreakdown): SupervisorCostBreakdown;
30
- export declare function hasInfraPricing(r: InfraCostRates): boolean;
31
- export declare function infraUsageFromEvents(events: ReadonlyArray<{
32
- type?: string;
33
- }>, runDurationMs: number): InfraUsage;
34
- //# sourceMappingURL=cost-taxonomy.d.ts.map
@@ -1,26 +0,0 @@
1
- const nonNeg = (n) => (Number.isFinite(n) && n > 0 ? n : 0);
2
- export function infraCost(usage, rates) {
3
- const toolCallMicroUsd = nonNeg(usage.toolCalls) * nonNeg(rates.toolCallMicroUsd);
4
- const sandboxWalltimeMicroUsd = (nonNeg(usage.sandboxWalltimeMs) / 1000) * nonNeg(rates.sandboxSecMicroUsd);
5
- const egressMicroUsd = (nonNeg(usage.egressBytes) / 1_000_000_000) * nonNeg(rates.egressGbMicroUsd);
6
- return {
7
- toolCallMicroUsd,
8
- sandboxWalltimeMicroUsd,
9
- egressMicroUsd,
10
- totalMicroUsd: toolCallMicroUsd + sandboxWalltimeMicroUsd + egressMicroUsd,
11
- };
12
- }
13
- export function composeSupervisorCost(llm, llmTotalMicroUsd, infra) {
14
- return { llm, infra, totalMicroUsd: nonNeg(llmTotalMicroUsd) + infra.totalMicroUsd };
15
- }
16
- export function hasInfraPricing(r) {
17
- return r.toolCallMicroUsd > 0 || r.sandboxSecMicroUsd > 0 || r.egressGbMicroUsd > 0;
18
- }
19
- export function infraUsageFromEvents(events, runDurationMs) {
20
- return {
21
- toolCalls: events.reduce((n, e) => (e.type === "tool_start" ? n + 1 : n), 0),
22
- sandboxWalltimeMs: nonNeg(runDurationMs),
23
- egressBytes: 0,
24
- };
25
- }
26
- //# sourceMappingURL=cost-taxonomy.js.map
@@ -1,41 +0,0 @@
1
- /**
2
- * Sema-registry adapter — pull the effective config from sema-registry and apply it OVER the
3
- * env-derived defaults (env = fallback, center = override). Follows the "universal internal
4
- * schema → translate at the boundary" pattern, with our security boundary kept:
5
- *
6
- * - the CENTER owns the LOGICAL config: the model roster (names/capabilities/tier), the role map,
7
- * and team templates;
8
- * - the SERVICE env still owns the SECRETS: API keys stay in env (the center never stores a secret);
9
- * keys are per-model via `apiKeyEnv` → `config.modelApiKeyEnv` → the spec's `getApiKeyAndHeaders`
10
- * (core 1.45), so each model/cascade-rung authenticates with its own upstream key.
11
- *
12
- * Per-model `baseUrl` IS transported (a catalog model may live on a different gateway;
13
- * core brain honors model.baseUrl, absent = "" = boot-env endpoint).
14
- *
15
- * Hot-reload status (复审 2026-07-29 P1-11 — 亲读判定,取代此处旧的 "models/roles are restart-to-apply"
16
- * TODO, which went stale when `mutateInPlace` landed):
17
- * - models/roles/roster/teams/projects/autonomy — **HOT**. `applyEffective` mutates `config.models`/
18
- * `config.roles` IN PLACE, and core's Runner reads `this.deps.models/roles` per task off that very
19
- * reference. Both brains re-resolve `model.baseUrl || config.baseUrl` inside `buildRequest()` on every
20
- * call (core 2.1.0 `brain/openai.js` + `brain/anthropic.js`), so a moved gateway takes effect on the
21
- * next task with no restart.
22
- * - the same plane under a **tier-frozen** Runner — deferred, not hot: core expands a PRIVATE catalog copy
23
- * at construction, so `main` defers the whole plane and the `models-tiers` restart slice signals.
24
- * - **`degrade-route`** — the one genuinely boot-frozen catalog consumer left: reactive degrade
25
- * (`MODEL_DEGRADE_REACTIVE`) bakes the target Model + its gateway + its key into the brain composition
26
- * at boot. It cannot be hot-applied without rebuilding the brain, so it is registered on the existing
27
- * restartRequired /health contract instead (see `restart-signal.ts`). Fail-loud beats serving a stale
28
- * gateway silently on the rate-limit path.
29
- * - skills/mcp/scenarios/runtime-gates — restart-to-apply by construction (baked into the boot wiring).
30
- *
31
- * (design/158 A13, internal-lossless) This module is now a FACADE: the implementation lives in
32
- * `src/config-center/` split by responsibility group (HTTP client / EffectiveConfig application /
33
- * restart-signal detection / skills+MCP consumption). Every symbol below is re-exported UNCHANGED —
34
- * existing `from "./sema-registry.js"` / `from "../sema-registry.js"` imports need zero changes.
35
- */
36
- export { fetchEffective, fetchPrincipalCaps, ConfigCenterHttpError, fetchSkillContent, fetchPromptArtifact, fetchPromptBlob, } from "./config-center/http-client.js";
37
- export { mutateInPlace, applyEffective, applyRuntimeGates, applyRuntimeHot, resolveDefaultModelName, logEffectiveDiff, runtimeHasActiveGate, } from "./config-center/apply-effective.js";
38
- export { restartReasons, planeHasActiveTiers, modelPlaneChanged, type RestartSlice, type RestartSliceCtx, type RestartSignal, } from "./config-center/restart-signal.js";
39
- export { applyCenterSkills, resolveMcpServers, mcpForScenario } from "./config-center/skills-mcp.js";
40
- export type { CenterSkillManifest, CenterMcpServer, EffectiveConfig, ExecutionRuling, SessionMirrorRuling, } from "./config-center/types.js";
41
- //# sourceMappingURL=sema-registry.d.ts.map
@@ -1,40 +0,0 @@
1
- /**
2
- * Sema-registry adapter — pull the effective config from sema-registry and apply it OVER the
3
- * env-derived defaults (env = fallback, center = override). Follows the "universal internal
4
- * schema → translate at the boundary" pattern, with our security boundary kept:
5
- *
6
- * - the CENTER owns the LOGICAL config: the model roster (names/capabilities/tier), the role map,
7
- * and team templates;
8
- * - the SERVICE env still owns the SECRETS: API keys stay in env (the center never stores a secret);
9
- * keys are per-model via `apiKeyEnv` → `config.modelApiKeyEnv` → the spec's `getApiKeyAndHeaders`
10
- * (core 1.45), so each model/cascade-rung authenticates with its own upstream key.
11
- *
12
- * Per-model `baseUrl` IS transported (a catalog model may live on a different gateway;
13
- * core brain honors model.baseUrl, absent = "" = boot-env endpoint).
14
- *
15
- * Hot-reload status (复审 2026-07-29 P1-11 — 亲读判定,取代此处旧的 "models/roles are restart-to-apply"
16
- * TODO, which went stale when `mutateInPlace` landed):
17
- * - models/roles/roster/teams/projects/autonomy — **HOT**. `applyEffective` mutates `config.models`/
18
- * `config.roles` IN PLACE, and core's Runner reads `this.deps.models/roles` per task off that very
19
- * reference. Both brains re-resolve `model.baseUrl || config.baseUrl` inside `buildRequest()` on every
20
- * call (core 2.1.0 `brain/openai.js` + `brain/anthropic.js`), so a moved gateway takes effect on the
21
- * next task with no restart.
22
- * - the same plane under a **tier-frozen** Runner — deferred, not hot: core expands a PRIVATE catalog copy
23
- * at construction, so `main` defers the whole plane and the `models-tiers` restart slice signals.
24
- * - **`degrade-route`** — the one genuinely boot-frozen catalog consumer left: reactive degrade
25
- * (`MODEL_DEGRADE_REACTIVE`) bakes the target Model + its gateway + its key into the brain composition
26
- * at boot. It cannot be hot-applied without rebuilding the brain, so it is registered on the existing
27
- * restartRequired /health contract instead (see `restart-signal.ts`). Fail-loud beats serving a stale
28
- * gateway silently on the rate-limit path.
29
- * - skills/mcp/scenarios/runtime-gates — restart-to-apply by construction (baked into the boot wiring).
30
- *
31
- * (design/158 A13, internal-lossless) This module is now a FACADE: the implementation lives in
32
- * `src/config-center/` split by responsibility group (HTTP client / EffectiveConfig application /
33
- * restart-signal detection / skills+MCP consumption). Every symbol below is re-exported UNCHANGED —
34
- * existing `from "./sema-registry.js"` / `from "../sema-registry.js"` imports need zero changes.
35
- */
36
- export { fetchEffective, fetchPrincipalCaps, ConfigCenterHttpError, fetchSkillContent, fetchPromptArtifact, fetchPromptBlob, } from "./config-center/http-client.js";
37
- export { mutateInPlace, applyEffective, applyRuntimeGates, applyRuntimeHot, resolveDefaultModelName, logEffectiveDiff, runtimeHasActiveGate, } from "./config-center/apply-effective.js";
38
- export { restartReasons, planeHasActiveTiers, modelPlaneChanged, } from "./config-center/restart-signal.js";
39
- export { applyCenterSkills, resolveMcpServers, mcpForScenario } from "./config-center/skills-mcp.js";
40
- //# sourceMappingURL=sema-registry.js.map