@sema-agent/server 7.127.2 → 7.129.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 (112) hide show
  1. package/MIGRATION.md +130 -0
  2. package/USAGE.md +137 -20
  3. package/dist/approval-card.d.ts +53 -26
  4. package/dist/approval-card.js +40 -11
  5. package/dist/approval-crash-convergence.js +4 -4
  6. package/dist/audit.js +4 -1
  7. package/dist/bake-runner/main.js +2 -1
  8. package/dist/boot/execution-lane.d.ts +11 -0
  9. package/dist/boot/execution-lane.js +6 -0
  10. package/dist/boot/memory-consolidation.d.ts +46 -16
  11. package/dist/boot/memory-consolidation.js +15 -8
  12. package/dist/boot/resolve-spec.js +3 -1
  13. package/dist/boot/side-query-lane.d.ts +7 -20
  14. package/dist/boot/side-query-lane.js +0 -24
  15. package/dist/boot/stage-01-config.js +3 -0
  16. package/dist/boot/stage-06-runners.js +1 -1
  17. package/dist/boot/stores.js +2 -2
  18. package/dist/boot/web-admin.js +31 -20
  19. package/dist/boot/webfetch-summarize-lane.d.ts +10 -7
  20. package/dist/boot/webfetch-summarize-lane.js +2 -3
  21. package/dist/brain.js +6 -9
  22. package/dist/capabilities/builtin-tools.d.ts +2 -2
  23. package/dist/capabilities/engine-capabilities.d.ts +14 -0
  24. package/dist/capabilities/engine-capabilities.js +12 -0
  25. package/dist/capabilities/mcp-probe.js +11 -5
  26. package/dist/capability-facts.d.ts +3 -1
  27. package/dist/capability-facts.js +1 -0
  28. package/dist/config-catalog.js +1 -1
  29. package/dist/config-provider.d.ts +17 -4
  30. package/dist/config-provider.js +8 -6
  31. package/dist/config-types.d.ts +6 -5
  32. package/dist/egress-redirect.d.ts +12 -0
  33. package/dist/egress-redirect.js +7 -0
  34. package/dist/entry-mode-clamp-notice.d.ts +30 -0
  35. package/dist/entry-mode-clamp-notice.js +13 -0
  36. package/dist/fleet/fleet-bus.d.ts +7 -0
  37. package/dist/fleet/fleet-bus.js +1 -0
  38. package/dist/hooks/hook-llm.js +6 -2
  39. package/dist/hooks/hook-runner.d.ts +1 -0
  40. package/dist/hooks/hook-runner.js +10 -4
  41. package/dist/host-lsp-manager.d.ts +3 -3
  42. package/dist/http/admission.js +5 -2
  43. package/dist/http/resume-legs.js +46 -27
  44. package/dist/http/route-ctx.d.ts +1 -1
  45. package/dist/http/routes/approvals-assistant.js +6 -4
  46. package/dist/http/routes/capabilities.js +1 -0
  47. package/dist/http/routes/session-sync.js +3 -4
  48. package/dist/http/routes/sessions.js +4 -17
  49. package/dist/http/send.d.ts +1 -1
  50. package/dist/http/send.js +4 -3
  51. package/dist/http/wire-types.d.ts +14 -5
  52. package/dist/index.d.ts +1 -1
  53. package/dist/index.js +1 -1
  54. package/dist/main.js +2 -0
  55. package/dist/mcp-assertion-header.d.ts +89 -0
  56. package/dist/mcp-assertion-header.js +49 -0
  57. package/dist/observability/fail-open.d.ts +7 -3
  58. package/dist/observability/fail-open.js +7 -3
  59. package/dist/observability/secret-env-scrub.d.ts +37 -3
  60. package/dist/observability/secret-env-scrub.js +2 -2
  61. package/dist/parked-decide.js +5 -2
  62. package/dist/plugins/host-platform.d.ts +43 -13
  63. package/dist/plugins/host-platform.js +67 -18
  64. package/dist/plugins/memory-embedder.js +5 -0
  65. package/dist/plugins/one-time-migrations.d.ts +180 -9
  66. package/dist/plugins/one-time-migrations.js +315 -3
  67. package/dist/plugins/pg-pool.js +3 -1
  68. package/dist/plugins/remote-env-host.d.ts +17 -20
  69. package/dist/plugins/remote-env-host.js +16 -28
  70. package/dist/plugins/session-policy-store-sql.d.ts +16 -4
  71. package/dist/plugins/session-policy-store-sql.js +17 -20
  72. package/dist/plugins/session-rules-column.d.ts +16 -0
  73. package/dist/plugins/session-rules-column.js +6 -0
  74. package/dist/plugins/tidb-pool.js +4 -1
  75. package/dist/read-face-posture.d.ts +2 -1
  76. package/dist/request-value-closure.js +1 -1
  77. package/dist/retired-card-words.d.ts +17 -0
  78. package/dist/retired-card-words.js +49 -0
  79. package/dist/rule-entry-list.js +2 -0
  80. package/dist/run-local.js +15 -6
  81. package/dist/server-secret-env.d.ts +77 -85
  82. package/dist/server-secret-env.js +40 -26
  83. package/dist/session-policy-wire.d.ts +61 -124
  84. package/dist/session-policy-wire.js +59 -121
  85. package/dist/session-sync.d.ts +8 -6
  86. package/dist/session-sync.js +6 -5
  87. package/dist/spec-fields.d.ts +3 -2
  88. package/dist/standing-answer-grant.d.ts +17 -9
  89. package/dist/standing-answer-grant.js +11 -8
  90. package/dist/task-mcp.d.ts +31 -3
  91. package/dist/task-mcp.js +42 -4
  92. package/dist/task-settings.d.ts +6 -1
  93. package/dist/task-settings.js +1 -1
  94. package/dist/tool-approval.d.ts +14 -7
  95. package/dist/tool-approval.js +23 -18
  96. package/dist/trace/core-keyset-guard.d.ts +3 -3
  97. package/dist/trace/engine-notice-wire.d.ts +1 -1
  98. package/dist/trace/engine-notice-wire.js +1 -0
  99. package/dist/trace/project.d.ts +7 -4
  100. package/dist/trace/project.js +7 -76
  101. package/dist/trace/tool-output-media.d.ts +10 -4
  102. package/dist/trace/tool-output-media.js +7 -29
  103. package/dist/web-admin-client/apply-effective.js +28 -11
  104. package/dist/web-admin-client/facade.d.ts +2 -2
  105. package/dist/web-admin-client/facade.js +2 -2
  106. package/dist/web-admin-client/http-client.d.ts +2 -2
  107. package/dist/web-admin-client/read-face.d.ts +73 -20
  108. package/dist/web-admin-client/read-face.js +76 -36
  109. package/dist/web-admin-client/skills-mcp.d.ts +20 -17
  110. package/dist/web-admin-client/skills-mcp.js +27 -8
  111. package/dist/web-admin-client/types.d.ts +18 -0
  112. package/package.json +3 -3
@@ -1,31 +1,34 @@
1
- import type { A2aServerSpec, McpServerSpec } from "@sema-agent/core";
1
+ import { type A2aServerSpec, type McpServerSpec } from "@sema-agent/core";
2
2
  import type { CenterMcp, ScopedA2aPeer } from "../config-types.js";
3
3
  import type { Logger } from "../observability/logger.js";
4
4
  import type { LoadedSkill } from "../capabilities/skills.js";
5
- import type { CenterEndpoint } from "./center-request.js";
5
+ import type { ConfigProvider } from "../config-provider.js";
6
6
  import type { CenterA2aPeer, CenterMcpServer, CenterSkillManifest } from "./types.js";
7
7
  /**
8
- * Merge center skills OVER the image baseline ([ref]-sibling B1; `web-admin docs/MCP-SKILLS.md`). Load order =
9
- * `loadSkills(SKILLS_DIR)` baseline → center skills lazily fetched by hash and overlaid BY NAME (center
10
- * wins on a clash → can override a built-in; guarded center-side by publisher RBAC + the publish gate).
11
- * `enabled:false` is skipped. Content is verified + cached by hash (same hash fetched once). A skill whose
12
- * content fetch/verify fails is skipped (the baseline version, if any, stays) — never blocks startup.
8
+ * 技能正文的来源 = **拉到这份清单的配置源自己**(S-1556):`fetchSkillContent(contentHash)` 按 hash 答正文 —— 远程 = 中心内容端点
9
+ * (传输自验 hash;未知 hash ⇒ `undefined`),本地 = config.d 里内联的正文(与清单同一种容错读);`skillBodyCacheDir` = 这只配置源
10
+ * 声明的正文盘缓存目录(远程且开着 LKG 才有;本地恒缺席 —— 正文本就在这块盘上)。本函数不知道、也不问是哪一种。
11
+ */
12
+ export type SkillBodySource = Pick<ConfigProvider, "fetchSkillContent" | "skillBodyCacheDir">;
13
+ /**
14
+ * The skills domain's ONE read port (S-1556; [ref]-sibling B1; `web-admin docs/MCP-SKILLS.md`). Load order =
15
+ * `loadSkills(SKILLS_DIR)` baseline → the config source's skills (web-admin center OR local `config.d` — same manifest
16
+ * shape, same code path) overlaid BY NAME (config wins on a clash → can override a built-in; guarded center-side by
17
+ * publisher RBAC + the publish gate). `enabled:false` is skipped and never fetched. Bodies come from `bodies` by content
18
+ * hash, deduped in memory (same hash read once). A skill whose body is absent at the source or fails to read (incl. the
19
+ * remote transport's hash check) is NOT installed — exactly one `web_admin_skill_failed` warn names it (`reason`:
20
+ * `body_absent` | `read_failed`), the baseline of that name (if any) stays, and boot is never blocked.
13
21
  * Restart-to-apply: this runs at boot, before `buildScenarios` bakes skills into scenarios.
14
22
  */
15
- export declare function applyCenterSkills(baseline: LoadedSkill[], manifest: {
23
+ export declare function applySkillsManifest(baseline: LoadedSkill[], manifest: {
16
24
  skills: CenterSkillManifest[];
17
- },
18
- /** S-651:中心端点(基址 + 凭证来源;每次正文拉取取一次值)。 */
19
- center: CenterEndpoint, logger?: Logger, fetchImpl?: typeof fetch,
20
- /** LKG 姊妹面(clay 拍 2026-07-18):skill 正文的 content-addressed 盘缓存目录。读序=内存→盘(验
21
- * hash,坏文件忽略)→中心(成功后 best-effort 回写)。让 LKG-boot 在中心不可达时不再于正文拉取上
22
- * 挂数秒(live 实测黑洞 +5.3s/skill 批),顺带省正常 refresh 的重复拉取。undefined=无盘缓存(原行为)。 */
23
- diskCacheDir?: string): Promise<LoadedSkill[]>;
25
+ }, bodies: SkillBodySource, logger?: Logger): Promise<LoadedSkill[]>;
24
26
  /**
25
27
  * Resolve center MCP servers (`/effective.mcp`) into core `McpServerSpec`s + the scenarios each applies to.
26
28
  * env-NAME refs → real values from THIS service's env (secret boundary unchanged); a server with any missing
27
- * ref is skipped (`resolveRefs` → null). `enabled:false` skipped. Restart-to-apply (filtered per scenario in
28
- * `resolveSpec` via `mcpForScenario`).
29
+ * ref is skipped (`resolveRefs` → null). `enabled:false` skipped. A server whose `toolFaces` / `toolAxes` declaration is
30
+ * malformed is skipped whole (both are trust-root declarations — see `mcp-tool-faces.ts` / `mcp-tool-axes.ts`). Restart-to-apply
31
+ * (filtered per scenario in `resolveSpec` via `mcpForScenario`).
29
32
  */
30
33
  export declare function resolveMcpServers(mcp: {
31
34
  servers: CenterMcpServer[];
@@ -1,11 +1,13 @@
1
1
  import { readMcpSourceLabel } from "../mcp-source-label.js";
2
2
  import { readMcpToolFaces } from "../mcp-tool-faces.js";
3
3
  import { skillContentHash } from "@sema-agent/settings-schema";
4
+ import { readMcpToolAxes } from "@sema-agent/core";
4
5
  import { CONTENT_ORIGIN_WORDS, describeBadContentOrigin, isContentOriginWord } from "../mcp-content-origin.js";
5
- import { fetchSkillContent } from "./http-client.js";
6
+ import { noteMcpAssertionHeaderNotSent } from "../mcp-assertion-header.js";
6
7
  import { SHA256_HEX_RE } from "../digest-form.js";
7
8
  import { describeBadWireName, isUsableWireName } from "../wire-name-bound.js";
8
- export async function applyCenterSkills(baseline, manifest, center, logger, fetchImpl = fetch, diskCacheDir) {
9
+ export async function applySkillsManifest(baseline, manifest, bodies, logger) {
10
+ const diskCacheDir = bodies.skillBodyCacheDir;
9
11
  const { promises: fsp } = await import("node:fs");
10
12
  const { join: joinPath } = await import("node:path");
11
13
  const diskRead = async (hash) => {
@@ -18,7 +20,7 @@ export async function applyCenterSkills(baseline, manifest, center, logger, fetc
18
20
  const text = await fsp.readFile(joinPath(diskCacheDir, hex), "utf8");
19
21
  if (skillContentHash(text) === hash)
20
22
  return text;
21
- logger?.warn("web_admin_skill_cache_corrupt", { hash, note: "on-disk body fails its own hash — ignored, refetching from center" });
23
+ logger?.warn("web_admin_skill_cache_corrupt", { hash, note: "on-disk body fails its own hash — ignored, re-reading from the config source" });
22
24
  }
23
25
  catch {
24
26
  }
@@ -43,14 +45,19 @@ export async function applyCenterSkills(baseline, manifest, center, logger, fetc
43
45
  if (m.enabled === false)
44
46
  continue;
45
47
  if (seenNames.has(m.name))
46
- logger?.warn("web_admin_skill_duplicate_name", { name: m.name, note: "duplicate name in center manifest — last entry wins" });
48
+ logger?.warn("web_admin_skill_duplicate_name", { name: m.name, note: "duplicate name in the skills manifest — last entry wins" });
47
49
  seenNames.add(m.name);
48
50
  try {
49
51
  let content = contentCache.get(m.contentHash);
50
52
  if (content === undefined)
51
53
  content = await diskRead(m.contentHash);
52
54
  if (content === undefined) {
53
- content = await fetchSkillContent(center, m.contentHash, fetchImpl);
55
+ const answered = await bodies.fetchSkillContent(m.contentHash);
56
+ if (answered === undefined) {
57
+ logger?.warn("web_admin_skill_failed", { name: m.name, hash: m.contentHash, reason: "body_absent", note: "the config source holds no body for this hash — this entry is NOT installed; the baseline skill of this name (if any) stays" });
58
+ continue;
59
+ }
60
+ content = answered;
54
61
  diskWrite(m.contentHash, content);
55
62
  }
56
63
  contentCache.set(m.contentHash, content);
@@ -59,7 +66,7 @@ export async function applyCenterSkills(baseline, manifest, center, logger, fetc
59
66
  logger?.info("web_admin_skill", { name: m.name, hash: m.contentHash, scenarios: m.scenarios, overrodeBuiltin });
60
67
  }
61
68
  catch (err) {
62
- logger?.warn("web_admin_skill_failed", { name: m.name, hash: m.contentHash, err: String(err), note: "keeping baseline if any; skipping center version" });
69
+ logger?.warn("web_admin_skill_failed", { name: m.name, hash: m.contentHash, reason: "read_failed", err: String(err), note: "reading the body from the config source failed — this entry is NOT installed; the baseline skill of this name (if any) stays" });
63
70
  }
64
71
  }
65
72
  await Promise.all(pendingWrites);
@@ -117,22 +124,34 @@ export function resolveMcpServers(mcp, logger) {
117
124
  continue;
118
125
  }
119
126
  const toolFaces = facesRead.faces === undefined ? {} : { toolFaces: facesRead.faces };
127
+ const axesRead = readMcpToolAxes(s.toolAxes);
128
+ if (!axesRead.ok) {
129
+ logger?.warn("web_admin_mcp_tool_axes_invalid", {
130
+ server: s.name,
131
+ problem: axesRead.problem,
132
+ note: "server SKIPPED — a toolAxes declaration is a TRUST-ROOT declaration (it can lower an effect so a call skips the approval fence, or raise one); mounting the server without it, or with a half of it, would silently change what you declared. Fix the entry and republish.",
133
+ });
134
+ continue;
135
+ }
136
+ const toolAxes = axesRead.toolAxes === undefined ? {} : { toolAxes: axesRead.toolAxes };
120
137
  if (s.transport.kind === "stdio") {
121
138
  const env = resolveRefs(s.transport.envRefs, s.name, "env", logger);
122
139
  if (env === null)
123
140
  continue;
124
141
  out.push({
125
142
  scenarios: s.scenarios ?? [],
126
- spec: { name: s.name, transport: { kind: "stdio", command: s.transport.command, args: s.transport.args, ...(Object.keys(env).length ? { env } : {}) }, ...allow, ...elicit, ...contentOrigin, ...source, ...toolFaces },
143
+ spec: { name: s.name, transport: { kind: "stdio", command: s.transport.command, args: s.transport.args, ...(Object.keys(env).length ? { env } : {}) }, ...allow, ...elicit, ...contentOrigin, ...source, ...toolFaces, ...toolAxes },
127
144
  });
128
145
  }
129
146
  else {
130
147
  const headers = resolveRefs(s.transport.headerRefs, s.name, "header", logger);
131
148
  if (headers === null)
132
149
  continue;
150
+ if (s.transport.assertionHeader !== undefined)
151
+ noteMcpAssertionHeaderNotSent(logger, s.name);
133
152
  out.push({
134
153
  scenarios: s.scenarios ?? [],
135
- spec: { name: s.name, transport: { kind: "http", url: s.transport.url, ...(Object.keys(headers).length ? { headers } : {}), ...(s.transport.principalHeader ? { principalHeader: s.transport.principalHeader } : {}) }, ...allow, ...elicit, ...contentOrigin, ...source, ...toolFaces },
154
+ spec: { name: s.name, transport: { kind: "http", url: s.transport.url, ...(Object.keys(headers).length ? { headers } : {}), ...(s.transport.principalHeader ? { principalHeader: s.transport.principalHeader } : {}) }, ...allow, ...elicit, ...contentOrigin, ...source, ...toolFaces, ...toolAxes },
136
155
  });
137
156
  }
138
157
  }
@@ -151,6 +151,18 @@ export interface CenterMcpServer {
151
151
  * 形上先写一个结构,等于把同一张判据表抄成两份(而其中一份没有执行力)。
152
152
  */
153
153
  toolFaces?: unknown;
154
+ /**
155
+ * S-1475(settings-schema 12.2.x `McpServerSpec.toolAxes`,解析透明 `z.unknown()`)—— 部署侧为这台 server 的**每只工具**声明的
156
+ * 风险轴(`effect` / `egress` / `irreversibility`),键 = server 的**原始(未加命名空间)**工具名,上 core
157
+ * `McpServerSpec.toolAxes`。
158
+ *
159
+ * 🔴 类型是 `unknown` 而不是那个结构,**刻意的**(与 {@link CenterMcpServer.toolFaces} 逐字同姿):本类型是两条部署腿的**承载形**
160
+ * (本地 config.d 经 `z.unknown()` 解析透明地过来、远端 /effective 是直读 JSON),形判与投影的单一属主是**引擎**根导出的
161
+ * `readMcpToolAxes`(core 7.51.2 #1763;`resolveMcpServers` 在铸 spec 那一刻调它;产出的型是引擎的 `McpServerSpec["toolAxes"]`;本仓自铸的那一只
162
+ * 7.129.0 退役)。坏形 ⇒ 整条 server 不进 + 一行 `web_admin_mcp_tool_axes_invalid`。
163
+ * (同批解析透明键 `authForm` / `entryKind` 的语义归连接器,本层仍只承载。)
164
+ */
165
+ toolAxes?: unknown;
154
166
  transport: {
155
167
  kind: "stdio";
156
168
  command: string;
@@ -160,11 +172,17 @@ export interface CenterMcpServer {
160
172
  /** `principalHeader` ([ref]): the header name into which the runner injects the task's authenticated
161
173
  * end-user principal per-task, so a consumer MCP (e.g. oa-mcp) can enforce per-user RBAC. Not a ref — a
162
174
  * literal header name. The runner fills the value (never the model). */
175
+ /** `assertionHeader` (settings-schema ≥12.2.0): the header NAME a hosted connector's assertion travels in. Mutually exclusive with
176
+ * `principalHeader` (both answer "which header carries the identity this server sends"; the contract package refuses both-set at parse
177
+ * time — the request face enforces the same rule at acceptance, see `mcp-assertion-header.ts`). A literal header name, not a ref.
178
+ * This version CARRIES it up to the minting of the engine spec and does not send it (the engine's http transport has no seat yet):
179
+ * `resolveMcpServers` leaves it off the spec and says one info line per mounted server. */
163
180
  | {
164
181
  kind: "http";
165
182
  url: string;
166
183
  headerRefs?: Record<string, string>;
167
184
  principalHeader?: string;
185
+ assertionHeader?: string;
168
186
  };
169
187
  }
170
188
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sema-agent/server",
3
- "version": "7.127.2",
3
+ "version": "7.129.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",
@@ -64,7 +64,7 @@
64
64
  "build:binary:run-local:darwin-arm64": "bun build --compile --target=bun-darwin-arm64 src/run-local.ts --outfile dist/run-local-darwin-arm64"
65
65
  },
66
66
  "dependencies": {
67
- "@sema-agent/core": "7.50.2",
67
+ "@sema-agent/core": "7.51.2",
68
68
  "@sema-agent/settings-schema": "12.2.1",
69
69
  "e2b": "^2.28.0",
70
70
  "libsodium-wrappers": "^0.8.4",
@@ -80,7 +80,7 @@
80
80
  "sharp": "^0.35.3"
81
81
  },
82
82
  "devDependencies": {
83
- "@sema-agent/sdk": "21.1.0",
83
+ "@sema-agent/sdk": "23.0.0",
84
84
  "@types/libsodium-wrappers": "^0.7.14",
85
85
  "@types/node": "22.10.2",
86
86
  "@types/pg": "^8.20.0",