@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.
- package/MIGRATION.md +130 -0
- package/USAGE.md +137 -20
- package/dist/approval-card.d.ts +53 -26
- package/dist/approval-card.js +40 -11
- package/dist/approval-crash-convergence.js +4 -4
- package/dist/audit.js +4 -1
- package/dist/bake-runner/main.js +2 -1
- package/dist/boot/execution-lane.d.ts +11 -0
- package/dist/boot/execution-lane.js +6 -0
- package/dist/boot/memory-consolidation.d.ts +46 -16
- package/dist/boot/memory-consolidation.js +15 -8
- package/dist/boot/resolve-spec.js +3 -1
- package/dist/boot/side-query-lane.d.ts +7 -20
- package/dist/boot/side-query-lane.js +0 -24
- package/dist/boot/stage-01-config.js +3 -0
- package/dist/boot/stage-06-runners.js +1 -1
- package/dist/boot/stores.js +2 -2
- package/dist/boot/web-admin.js +31 -20
- package/dist/boot/webfetch-summarize-lane.d.ts +10 -7
- package/dist/boot/webfetch-summarize-lane.js +2 -3
- package/dist/brain.js +6 -9
- package/dist/capabilities/builtin-tools.d.ts +2 -2
- package/dist/capabilities/engine-capabilities.d.ts +14 -0
- package/dist/capabilities/engine-capabilities.js +12 -0
- package/dist/capabilities/mcp-probe.js +11 -5
- package/dist/capability-facts.d.ts +3 -1
- package/dist/capability-facts.js +1 -0
- package/dist/config-catalog.js +1 -1
- package/dist/config-provider.d.ts +17 -4
- package/dist/config-provider.js +8 -6
- package/dist/config-types.d.ts +6 -5
- package/dist/egress-redirect.d.ts +12 -0
- package/dist/egress-redirect.js +7 -0
- package/dist/entry-mode-clamp-notice.d.ts +30 -0
- package/dist/entry-mode-clamp-notice.js +13 -0
- package/dist/fleet/fleet-bus.d.ts +7 -0
- package/dist/fleet/fleet-bus.js +1 -0
- package/dist/hooks/hook-llm.js +6 -2
- package/dist/hooks/hook-runner.d.ts +1 -0
- package/dist/hooks/hook-runner.js +10 -4
- package/dist/host-lsp-manager.d.ts +3 -3
- package/dist/http/admission.js +5 -2
- package/dist/http/resume-legs.js +46 -27
- package/dist/http/route-ctx.d.ts +1 -1
- package/dist/http/routes/approvals-assistant.js +6 -4
- package/dist/http/routes/capabilities.js +1 -0
- package/dist/http/routes/session-sync.js +3 -4
- package/dist/http/routes/sessions.js +4 -17
- package/dist/http/send.d.ts +1 -1
- package/dist/http/send.js +4 -3
- package/dist/http/wire-types.d.ts +14 -5
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/main.js +2 -0
- package/dist/mcp-assertion-header.d.ts +89 -0
- package/dist/mcp-assertion-header.js +49 -0
- package/dist/observability/fail-open.d.ts +7 -3
- package/dist/observability/fail-open.js +7 -3
- package/dist/observability/secret-env-scrub.d.ts +37 -3
- package/dist/observability/secret-env-scrub.js +2 -2
- package/dist/parked-decide.js +5 -2
- package/dist/plugins/host-platform.d.ts +43 -13
- package/dist/plugins/host-platform.js +67 -18
- package/dist/plugins/memory-embedder.js +5 -0
- package/dist/plugins/one-time-migrations.d.ts +180 -9
- package/dist/plugins/one-time-migrations.js +315 -3
- package/dist/plugins/pg-pool.js +3 -1
- package/dist/plugins/remote-env-host.d.ts +17 -20
- package/dist/plugins/remote-env-host.js +16 -28
- package/dist/plugins/session-policy-store-sql.d.ts +16 -4
- package/dist/plugins/session-policy-store-sql.js +17 -20
- package/dist/plugins/session-rules-column.d.ts +16 -0
- package/dist/plugins/session-rules-column.js +6 -0
- package/dist/plugins/tidb-pool.js +4 -1
- package/dist/read-face-posture.d.ts +2 -1
- package/dist/request-value-closure.js +1 -1
- package/dist/retired-card-words.d.ts +17 -0
- package/dist/retired-card-words.js +49 -0
- package/dist/rule-entry-list.js +2 -0
- package/dist/run-local.js +15 -6
- package/dist/server-secret-env.d.ts +77 -85
- package/dist/server-secret-env.js +40 -26
- package/dist/session-policy-wire.d.ts +61 -124
- package/dist/session-policy-wire.js +59 -121
- package/dist/session-sync.d.ts +8 -6
- package/dist/session-sync.js +6 -5
- package/dist/spec-fields.d.ts +3 -2
- package/dist/standing-answer-grant.d.ts +17 -9
- package/dist/standing-answer-grant.js +11 -8
- package/dist/task-mcp.d.ts +31 -3
- package/dist/task-mcp.js +42 -4
- package/dist/task-settings.d.ts +6 -1
- package/dist/task-settings.js +1 -1
- package/dist/tool-approval.d.ts +14 -7
- package/dist/tool-approval.js +23 -18
- package/dist/trace/core-keyset-guard.d.ts +3 -3
- package/dist/trace/engine-notice-wire.d.ts +1 -1
- package/dist/trace/engine-notice-wire.js +1 -0
- package/dist/trace/project.d.ts +7 -4
- package/dist/trace/project.js +7 -76
- package/dist/trace/tool-output-media.d.ts +10 -4
- package/dist/trace/tool-output-media.js +7 -29
- package/dist/web-admin-client/apply-effective.js +28 -11
- package/dist/web-admin-client/facade.d.ts +2 -2
- package/dist/web-admin-client/facade.js +2 -2
- package/dist/web-admin-client/http-client.d.ts +2 -2
- package/dist/web-admin-client/read-face.d.ts +73 -20
- package/dist/web-admin-client/read-face.js +76 -36
- package/dist/web-admin-client/skills-mcp.d.ts +20 -17
- package/dist/web-admin-client/skills-mcp.js +27 -8
- package/dist/web-admin-client/types.d.ts +18 -0
- package/package.json +3 -3
|
@@ -1,31 +1,34 @@
|
|
|
1
|
-
import type
|
|
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 {
|
|
5
|
+
import type { ConfigProvider } from "../config-provider.js";
|
|
6
6
|
import type { CenterA2aPeer, CenterMcpServer, CenterSkillManifest } from "./types.js";
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
|
|
12
|
-
|
|
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
|
|
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.
|
|
28
|
-
* `
|
|
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 {
|
|
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
|
|
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,
|
|
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
|
|
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
|
-
|
|
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: "
|
|
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.
|
|
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.
|
|
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": "
|
|
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",
|