@sema-agent/server 7.91.2 → 7.92.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.
Files changed (71) hide show
  1. package/README.md +1 -1
  2. package/USAGE.md +8 -0
  3. package/dist/approval-ask-machine.d.ts +1 -1
  4. package/dist/approval-reconciler.d.ts +1 -1
  5. package/dist/approval.d.ts +1 -1
  6. package/dist/bench/s1/repair-oracle-adapter.d.ts +1 -1
  7. package/dist/bench/s1/runner-ctx.d.ts +1 -1
  8. package/dist/boot/runner-deps.d.ts +9 -9
  9. package/dist/capabilities/memory-notice.d.ts +27 -10
  10. package/dist/capabilities/memory-notice.js +21 -2
  11. package/dist/config-catalog.js +2 -1
  12. package/dist/config-center/types.d.ts +1 -1
  13. package/dist/config.d.ts +1 -1
  14. package/dist/env-facts.d.ts +1 -1
  15. package/dist/execution-lane-caps.d.ts +1 -1
  16. package/dist/file-history-disclosure.d.ts +2 -2
  17. package/dist/fleet/fleet-bus.d.ts +7 -1
  18. package/dist/fleet/fleet-bus.js +5 -3
  19. package/dist/http/admission.d.ts +1 -1
  20. package/dist/http/idempotency.d.ts +27 -0
  21. package/dist/http/route-ctx.d.ts +2 -5
  22. package/dist/http/routes/memory-compliance.d.ts +1 -1
  23. package/dist/http/routes/memory-origin.d.ts +2 -2
  24. package/dist/http/routes/rules.js +3 -1
  25. package/dist/http/routes/runs.js +3 -6
  26. package/dist/http/routes/session-sync.js +3 -2
  27. package/dist/http/routes/sessions.js +3 -2
  28. package/dist/http/routes/tasks.js +35 -19
  29. package/dist/http/wire-types.d.ts +29 -2
  30. package/dist/leader/wire.d.ts +1 -1
  31. package/dist/lsp/manager.d.ts +2 -2
  32. package/dist/memory-operator-faces.d.ts +13 -13
  33. package/dist/memory-scope.d.ts +2 -2
  34. package/dist/observability/fail-open.d.ts +1 -1
  35. package/dist/observability/fail-open.js +1 -1
  36. package/dist/observability/metrics.js +2 -1
  37. package/dist/orchestration/workflow-agent-session-index.d.ts +2 -2
  38. package/dist/peer-directory.d.ts +3 -2
  39. package/dist/permission-rule-vocab.d.ts +16 -1
  40. package/dist/plugins/file-run-store.d.ts +1 -1
  41. package/dist/plugins/local-session-store.d.ts +1 -1
  42. package/dist/plugins/memory-session-policy-store.d.ts +22 -3
  43. package/dist/plugins/memory-session-policy-store.js +11 -4
  44. package/dist/plugins/permission-rule-store-sql.js +16 -7
  45. package/dist/plugins/pg-pool.js +11 -0
  46. package/dist/plugins/session-policy-store-sql.d.ts +51 -3
  47. package/dist/plugins/session-policy-store-sql.js +77 -38
  48. package/dist/plugins/sql-errors.d.ts +25 -0
  49. package/dist/plugins/sql-errors.js +10 -0
  50. package/dist/plugins/store-backend.d.ts +5 -5
  51. package/dist/plugins/store-contracts.d.ts +2 -2
  52. package/dist/plugins/tidb-pool.d.ts +1 -1
  53. package/dist/plugins/tidb-pool.js +19 -0
  54. package/dist/rules-consent.d.ts +16 -9
  55. package/dist/rules-consent.js +14 -35
  56. package/dist/run-cancel-context.d.ts +1 -1
  57. package/dist/run-local.d.ts +1 -1
  58. package/dist/runtime-caps-resolver.d.ts +10 -10
  59. package/dist/runtime-governance.d.ts +2 -2
  60. package/dist/session-policy-wire.d.ts +25 -1
  61. package/dist/session-policy-wire.js +11 -0
  62. package/dist/spec-fields.d.ts +4 -4
  63. package/dist/task-cwd.d.ts +1 -1
  64. package/dist/task-settings.d.ts +2 -2
  65. package/dist/tool-approval.d.ts +1 -1
  66. package/dist/trace/core-keyset-guard.d.ts +1 -1
  67. package/dist/trace/project.d.ts +25 -1
  68. package/dist/trace/project.js +4 -0
  69. package/dist/trace/redact.d.ts +1 -1
  70. package/dist/trace/redact.js +8 -3
  71. package/package.json +3 -3
@@ -63,4 +63,15 @@ export function describeSessionRulesRecordProblem(p) {
63
63
  }
64
64
  }
65
65
  }
66
+ export function sessionPolicyErrorHttp(code) {
67
+ switch (code) {
68
+ case "conflict": return { status: 409, errorCode: "conflict" };
69
+ case "loosen_forbidden": return { status: 403, errorCode: "loosen_forbidden" };
70
+ case "corrupt": return { status: 500, errorCode: "corrupt" };
71
+ default: {
72
+ const unhandled = code;
73
+ throw new Error(`unhandled SessionPolicyError code: ${JSON.stringify(unhandled)}`);
74
+ }
75
+ }
76
+ }
66
77
  //# sourceMappingURL=session-policy-wire.js.map
@@ -65,15 +65,15 @@ export declare function taskAgentsFromBody(raw: unknown, requirePrincipal: boole
65
65
  /** [ref]②/[ref](cli 认领消费)—— fresh-submit 的 agents[].model **目录成员资格**门(形状门
66
66
  * {@link validateTaskAgents} 通过之后跑;调用方铸 400 `request.unknown_reference` + `available` 枚举)。
67
67
  * 病灶=报错太晚太远:server 持目录却不查,错到 core prepare 才炸 `config.agent.unknown_model`
68
- * (dist/agents/subagent.js:1258),以「run failed」形出现而非 400;cli resolver 只挡词法形,目录
68
+ * (dist/agents/subagent.js),以「run failed」形出现而非 400;cli resolver 只挡词法形,目录
69
69
  * 成员资格只有 server 持有。
70
70
  * 三条判定纪律(全部 core dist 亲读):
71
- * - **只查 string 形**:core 只对 `typeof a.model === "string"` 走 `resolveModel`(subagent.js:1253);
71
+ * - **只查 string 形**:core 只对 `typeof a.model === "string"` 走 `resolveModel`(subagent.js);
72
72
  * Model 对象形 core 原样信任不查目录([ref]④ 契约:自带完整 Model 配置,其 id 本就不必在目录)——
73
73
  * 对象形没有「晚失败」病灶,这里同拒会是射程外的行为收紧,不做。
74
74
  * - **`catalog` 必须是 tier 展开形**(调用方传 `expandTiers(config.models, config.tiers) ?? config.models`,
75
75
  * resolve-spec.ts wireCatalog 同源纪律):core Runner 构造期把 deps.models 换成展开目录
76
- * (runtask.js:1472),agentCatalog.models 即它 —— 裸 config.models 会把合法档位词/CC 别名误杀 400。
76
+ * (runtask.js),agentCatalog.models 即它 —— 裸 config.models 会把合法档位词/CC 别名误杀 400。
77
77
  * - **判定=`Object.hasOwn` 纯键查**,刻意不用 `matchCatalogModel`:那是 body.model 门的四形判
78
78
  * (name/tier/alias/**id**),而 core 的 `resolveModel` 是纯键查(roles.js:`models?.[ref]`)——
79
79
  * 多认 id 形会放行一个 core prepare 必炸的值(门假绿,病灶照旧)。hasOwn 顺带挡原型链键。
@@ -111,7 +111,7 @@ export declare function toolNameListFromBody(raw: unknown): string[] | undefined
111
111
  * ⚠️ **这不是一条 defer 注**([ref] 件⑤ 对表结论,core [ref] 同判):本段说的是 `promptProfile` 这根
112
112
  * **呈现**轴,它与 `deferMode` / `deferTools` 的延迟披露轴**无耦合** —— 上一行提 deferTools 只是在借它
113
113
  * 的「无租户门」姿势作类比。「引擎缺省 simple」这句本身在 core 5.40.0 上仍逐字为真
114
- * (`core/types.d.ts:133`:default "simple"),本批亲验未变。
114
+ * (`core/types.d.ts`:default "simple"),本批亲验未变。
115
115
  * 真正的 defer 轴对表(core 5.40.0 起 `deferMode:"auto"` 不再 sweep 内建;7.15.0 起它不再是第二道门,
116
116
  * 只是把候选集拓宽后走同一道阈值门)记在
117
117
  * `src/capabilities/tool-defer.ts` 的头注 —— 别把两根轴的结论写到一处。
@@ -35,7 +35,7 @@ export declare function normalizeAbsolutePathLexically(p: string): string;
35
35
  * **词法**判域:`dir` 是不是 `target` 本身或它的祖先(= `target` ⊆ `dir`,「等于 ∪ 后代」)。
36
36
  *
37
37
  * 这是 core `assertExemptDirsDoNotCoverRoot` 那条律的本仓同形(亲读安装树
38
- * `dist/core/fs-write-gate-policy.js:11-28` → `swallowedFenceRoot` → `isWithin(root, p)`:
38
+ * `dist/core/fs-write-gate-policy.js` → `swallowedFenceRoot` → `isWithin(root, p)`:
39
39
  * 先各自词法归一,再判 `p === root` 或 `p` 以 `root + "/"` 起头)。**两端都只做词法**,不 realpath ——
40
40
  * 写门的构造期本来就没有 I/O(core 同理),承诺 canonical 是承诺一件此刻做不到的事。
41
41
  *
@@ -396,8 +396,8 @@ export interface FsWriteGateWiring {
396
396
  * `boot/resolve-spec.ts` / `boot/parked-revive-gate.ts` 把**同一个值**递成本字段。两处同源是承重的:
397
397
  * 各算一份就会出现「422 门放行而引擎判 unreadable」或反过来。
398
398
  *
399
- * 🔴 **S-213⑦ 改真话**(亲读 core 7.12.0 `dist/core/permission-rule-model.js:365-372` /
400
- * `:340-350`,推翻本注此前的两句):
399
+ * 🔴 **S-213⑦ 改真话**(亲读 core 7.12.0 `dist/core/permission-rule-model.js` /
400
+ * 的 `resolvePathPattern`,推翻本注此前的两句):
401
401
  * · core 对缺席的 `home` **不**回落 `os.homedir()` —— `resolvePathPattern` 走
402
402
  * `lexicalNormalAbsolutePathOf(baseValueOf("home", bases) ?? "")`,base 缺席 ⇒ `undefined` ⇒ 直接回
403
403
  * `{missingBase:"home"}`,该调用的射程判 `unreadable`(fail-closed 的 ask,人来清),从不猜一个目录。
@@ -653,7 +653,7 @@ export declare function resolveStreamApprovalGate(input: StreamApprovalGateInput
653
653
  *
654
654
  * 三源(§8.3)里本仓可执行的是后两源;第一源 `forceDurableGate` 在 HTTP 装配时刻不可解析(§14 §12-5
655
655
  * 亲裁:不可读则该源不做,core 自身的 `runtimeCaps?.forceDurableGate` 消费臂结构性兜底——7.0.1
656
- * `prepare-task.js` 的 durableMandate/contentMandate(:1415/:1417)与 durableQuestionFace(:2136)等),
656
+ * `prepare-task.js` 的 durableMandate/contentMandate 与 durableQuestionFace 等),
657
657
  * 故不在本函数内。
658
658
  *
659
659
  * 🔴 **[ref](半接线旋钮族)**:`windowZero` 的第一源(`STREAM_ASK_WINDOW_MS=0`)自此**不再挂在
@@ -36,7 +36,7 @@ type _GuardProvenanceReverse = AssertAllKeysHandled<Exclude<ProvenanceProjected
36
36
  type AgentMessageProjected = "from" | "body";
37
37
  type _GuardAgentMessage = AssertAllKeysHandled<Exclude<keyof NonNullable<TaskNotificationPayload["agentMessage"]>, AgentMessageProjected>>;
38
38
  type _GuardAgentMessageReverse = AssertAllKeysHandled<Exclude<AgentMessageProjected, keyof NonNullable<TaskNotificationPayload["agentMessage"]>>>;
39
- type BgNotifProjected = "taskId" | "sessionId" | "seq" | "status" | "summary" | "stoppedBy" | "resumable" | "recentSteps" | "editedFiles" | "usage" | "transcriptId" | "rootSessionId" | "parentTaskId" | "parentToolCallId" | "completionId";
39
+ type BgNotifProjected = "taskId" | "sessionId" | "seq" | "status" | "summary" | "stoppedBy" | "resumable" | "recentSteps" | "editedFiles" | "usage" | "transcriptId" | "rootSessionId" | "parentTaskId" | "parentToolCallId" | "completionId" | "spawnName";
40
40
  type BgNotifExcluded = "kind" | "sessionScoped" | "owner" | "scope" | "description" | "agentType" | "name" | "currentAction" | "currentTool" | "parentSessionId" | "startedAt" | "workflowRunId" | "progressTaskId" | "progressParentTaskId" | "model";
41
41
  type _GuardBgNotif = AssertAllKeysHandled<Exclude<keyof BackgroundChildEvent, BgNotifProjected | BgNotifExcluded>>;
42
42
  type _GuardBgNotifReverse = AssertAllKeysHandled<Exclude<BgNotifProjected | BgNotifExcluded, keyof BackgroundChildEvent>>;
@@ -331,7 +331,9 @@ export declare function toolDisclosureEventData(ev: {
331
331
  /** The `task_progress` payload (a subagent's live progress tick) — EXPLICIT WHITELIST shared by all
332
332
  * three legs (bg runs.ts + resume append + the sync live SSE frame): taskId/parent linkage/token rollup verbatim,
333
333
  * `name` UNTRUSTED (core sanitizes for rendering, does NOT secret-redact — a taskName can be secret-shaped) →
334
- * `redactSecrets`. Never the delegated objective/args. E2 identity rides (eventId/
334
+ * `redactSecrets`; `spawnName` is the TRUSTED-chain teammate KEY beside it (core 7.25.0 [ref] S0 — validated at the
335
+ * spawn, so it is an identity, not a label) and rides VERBATIM: redacting an identity key does not make it safe,
336
+ * it makes it WRONG (two legal names collapsing onto one value — see the key's own note). Never the delegated objective/args. E2 identity rides (eventId/
335
337
  * parentToolCallId are core-mint uuidv7 identifiers, not content — consumers bind concurrent subagent ticks
336
338
  * exactly by them; the 1.72 whitelist dropped them, leaving a FIFO heuristic). */
337
339
  export declare function taskProgressEventData(ev: {
@@ -339,6 +341,7 @@ export declare function taskProgressEventData(ev: {
339
341
  taskType?: string;
340
342
  parentTaskId?: string;
341
343
  name?: string;
344
+ spawnName?: string;
342
345
  status?: string;
343
346
  usage?: unknown;
344
347
  currentAction?: string;
@@ -715,6 +718,27 @@ export declare function wiringManifestOperatorEventData(ev: {
715
718
  eventId?: unknown;
716
719
  parentToolCallId?: unknown;
717
720
  }): Record<string, unknown>;
721
+ /**
722
+ * `wiring_manifest` 的**唯一分叉点**(S-528)—— 两条知道调用方身份的 live 消费腿共用它:
723
+ * `/v1/tasks/stream` 的 SSE 帧,与 `POST /v1/tasks`(非流式)200 体里的 `wiringManifest` 起手回执。
724
+ *
725
+ * 🔴 **为什么是一只函数,而不是两处 `cond ? operator : tenant`**:那个三元判的是「这份产物给谁看」——
726
+ * 一件治理面的事([ref] 件一)。写两份就有漂的位置:core 往 operator 面加第 N 段时,跟上的那一处与没跟上
727
+ * 的那一处会让**同一次提交**在两条腿上投出两种宽度,而错的方向是把 operator-only 面发给租户。两条腿从此
728
+ * 只认这一只,新的第三条腿照抄它即可(禁再写一次三元)。
729
+ *
730
+ * 判据本身(`explicitOperatorOk`)仍由调用腿**每请求求一次**再传进来:身份解析要读请求凭据与部署名单,
731
+ * 那是 http 层的事,本文件(投影层)不认识 `req`,也不该认识。
732
+ *
733
+ * `operatorFace` 的两个值都是**正面事实**,没有第三态(所以是 boolean 不是三值):
734
+ * · `true` = 本请求的调用方经 `explicitOperatorOk` 判为 operator ⇒ 投 {@link wiringManifestOperatorEventData};
735
+ * · `false` = 其余全部(**含**「本部署根本没配 operator 名单」)⇒ 投 {@link wiringManifestEventData} 的租户形。
736
+ */
737
+ export declare function wiringManifestFaceEventData(ev: {
738
+ manifest?: unknown;
739
+ eventId?: unknown;
740
+ parentToolCallId?: unknown;
741
+ }, operatorFace: boolean): Record<string, unknown>;
718
742
  /**
719
743
  * `human_input`(core 5.14.0 [ref] 新 `TaskEvent` 臂)—— 「谁把什么喂进了这条 run」的生命周期账本
720
744
  * 帧(objective / 实时 steer / nextTurn / parked-steer 续跑 / wake 五个载体共用一个投影点)。
@@ -273,6 +273,7 @@ export function taskProgressEventData(ev) {
273
273
  ...(typeof ev.taskType === "string" && ev.taskType.length > 0 ? { taskType: ev.taskType } : {}),
274
274
  ...(ev.parentTaskId ? { parentTaskId: ev.parentTaskId } : {}),
275
275
  ...(ev.name ? { name: redactSecrets(ev.name) } : {}),
276
+ ...(ev.spawnName ? { spawnName: ev.spawnName } : {}),
276
277
  ...(typeof ev.model === "string" && ev.model.length > 0 ? { model: ev.model } : {}),
277
278
  ...(ev.status !== undefined ? { status: ev.status } : {}),
278
279
  ...(ev.usage ? { usage: ev.usage } : {}),
@@ -597,6 +598,9 @@ export function wiringManifestOperatorEventData(ev) {
597
598
  ...(str(m.configFingerprint) !== undefined ? { configFingerprint: m.configFingerprint } : {}),
598
599
  };
599
600
  }
601
+ export function wiringManifestFaceEventData(ev, operatorFace) {
602
+ return operatorFace ? wiringManifestOperatorEventData(ev) : wiringManifestEventData(ev);
603
+ }
600
604
  export function humanInputEventData(ev) {
601
605
  const str = (v) => (typeof v === "string" && v.length > 0 ? v : undefined);
602
606
  const a = typeof ev.actor === "object" && ev.actor !== null && !Array.isArray(ev.actor) ? { ...ev.actor } : {};
@@ -74,7 +74,7 @@ export declare function resetPpkScanBytesForTest(): void;
74
74
  *
75
75
  * 🔴 **词义如实**(codex r1 [medium] 三,采纳):这一维说的是「命中的是**哪一条臂**」,**不是**
76
76
  * 「这段文本真的被上游截过」—— server 收到的是纯字节,core 的 `clip()` 是 `slice(0, 80)` **不留标记**
77
- * (亲读 `@sema-agent/core/dist/agents/subagent-steps.js:9-11`),截过与天生就短在 wire 上不可区分。
77
+ * (亲读 `@sema-agent/core/dist/agents/subagent-steps.js`),截过与天生就短在 wire 上不可区分。
78
78
  * 所以一个 `arm="fragment"` 计数可能来自残片,也可能来自一个恰好落在阈值之上的 look-alike;
79
79
  * core [ref] 落地后这一支**趋零是证据、不归零不是证明**。别把它当截断事实的度量用。 */
80
80
  /**
@@ -1774,6 +1774,9 @@ function decodeToFixedPoint(s, maxRounds = 3) {
1774
1774
  }
1775
1775
  return { text: cur, residue: cur.includes("%") };
1776
1776
  }
1777
+ const MARKER_CHARS = ["«", "»"];
1778
+ const MARKER_BYTE_SPELLINGS = MARKER_CHARS.map((ch) => String.fromCharCode(...new TextEncoder().encode(ch)));
1779
+ const carriesRedactionMarker = (spelled, byteView) => MARKER_CHARS.some((ch) => spelled.includes(ch)) || MARKER_BYTE_SPELLINGS.some((b) => byteView.includes(b));
1777
1780
  const VIEW_FILLER_PREFERENCE = ["a", "z", "_", "-", "0"];
1778
1781
  let armValueClassViewsCache;
1779
1782
  function armValueClassViews() {
@@ -1794,13 +1797,15 @@ function boundedUnitView(unit, inClass, filler) {
1794
1797
  }
1795
1798
  function unitCarriesCredential(unit) {
1796
1799
  const decoded = decodeToFixedPoint(unit);
1800
+ if (carriesRedactionMarker(unit, decoded.text))
1801
+ return { hit: false, unreadable: true };
1797
1802
  const views = new Set();
1798
1803
  for (const spelling of [unit, decoded.text])
1799
1804
  for (const v of armValueClassViews())
1800
1805
  views.add(boundedUnitView(spelling, v.inClass, v.filler));
1801
1806
  views.delete("");
1802
1807
  const hit = [...views].some((view) => runRedaction(view, true, false, false, "bounded-unit").text !== view);
1803
- return { hit, residue: decoded.residue };
1808
+ return { hit, unreadable: decoded.residue };
1804
1809
  }
1805
1810
  function displaySafePathname(pathname) {
1806
1811
  const parts = pathname.split("/");
@@ -1810,7 +1815,7 @@ function displaySafePathname(pathname) {
1810
1815
  if (seg === "")
1811
1816
  continue;
1812
1817
  const verdict = unitCarriesCredential(seg);
1813
- if (!verdict.hit && !verdict.residue)
1818
+ if (!verdict.hit && !verdict.unreadable)
1814
1819
  continue;
1815
1820
  if (isAllRedactionTokens(redactSecrets(seg)))
1816
1821
  continue;
@@ -1839,7 +1844,7 @@ function shapeLawCredentialInQueryOrFragment(canonical) {
1839
1844
  if (unit === "")
1840
1845
  continue;
1841
1846
  const verdict = unitCarriesCredential(unit);
1842
- if (verdict.hit || verdict.residue)
1847
+ if (verdict.hit || verdict.unreadable)
1843
1848
  return true;
1844
1849
  const decoded = decodeToFixedPoint(unit).text;
1845
1850
  if (decoded.includes("://") || decoded.includes("@"))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sema-agent/server",
3
- "version": "7.91.2",
3
+ "version": "7.92.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",
@@ -59,7 +59,7 @@
59
59
  "build:binary:run-local:darwin-arm64": "bun build --compile --target=bun-darwin-arm64 src/run-local.ts --outfile dist/run-local-darwin-arm64"
60
60
  },
61
61
  "dependencies": {
62
- "@sema-agent/core": "7.24.4",
62
+ "@sema-agent/core": "7.25.0",
63
63
  "@sema-agent/settings-schema": "3.0.0",
64
64
  "e2b": "^2.28.0",
65
65
  "libsodium-wrappers": "^0.8.4",
@@ -74,7 +74,7 @@
74
74
  "sharp": "^0.35.3"
75
75
  },
76
76
  "devDependencies": {
77
- "@sema-agent/sdk": "9.11.0",
77
+ "@sema-agent/sdk": "10.0.0",
78
78
  "@types/libsodium-wrappers": "^0.7.14",
79
79
  "@types/node": "22.10.2",
80
80
  "@types/pg": "^8.20.0",