@sema-agent/server 7.6.0 → 7.7.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/USAGE.md +85 -23
- package/dist/boot/budget-tracing.js +1 -1
- package/dist/boot/config-center.js +2 -1
- package/dist/boot/resolve-spec.d.ts +5 -0
- package/dist/boot/resolve-spec.js +15 -6
- package/dist/capabilities/hands-lane.d.ts +91 -0
- package/dist/capabilities/hands-lane.js +104 -0
- package/dist/capabilities/scenarios.d.ts +49 -2
- package/dist/capabilities/scenarios.js +84 -16
- package/dist/fleet/fleet-terminal-window.js +9 -6
- package/dist/hooks/hook-runner.js +11 -0
- package/dist/http/route-ctx.d.ts +7 -1
- package/dist/http/routes/fleet.js +6 -2
- package/dist/http/routes/runs.js +2 -1
- package/dist/http/routes/tasks.js +5 -4
- package/dist/http/server.d.ts +6 -0
- package/dist/http/server.js +23 -10
- package/dist/main.js +58 -7
- package/dist/observability/tool-trace.d.ts +13 -0
- package/dist/observability/tool-trace.js +14 -0
- package/dist/run-local.js +15 -5
- package/package.json +2 -2
|
@@ -25,6 +25,19 @@ export declare function createPermissionDeniedMeter(metrics: Pick<Metrics, "inc"
|
|
|
25
25
|
*
|
|
26
26
|
* Pure observation: every hook returns `undefined`, so it never rewrites args, never gates, never alters
|
|
27
27
|
* the result (and per core's hooks invariant a hook's `allow` can't bypass the policy gate anyway).
|
|
28
|
+
*
|
|
29
|
+
* 🔴 core 5.20.0 起这条「纯观察」性质必须**声明**出来(`preToolUseObservational`),不能只写在注释里:
|
|
30
|
+
* core 5.19.0 的委派折叠按「PreToolUse 席位在不在」把父的 screening 面折进子代的祖先约束链——它分不出
|
|
31
|
+
* 诊断 tracer 与真裁决者。后果是**这个默认关的诊断旋钮**一开,该部署所有 hook-wired 父的 parked 子代
|
|
32
|
+
* checkpoint 就记 `parentConstraintCount=2`,而跨副本赎回腿(`boot/parked-revive-gate.ts`)恒供 1 ⇒
|
|
33
|
+
* core pre-CAS 响亮拒、行永久 pending(层数 park 时写死,事后关旋钮/重批/回滚都不改)。
|
|
34
|
+
* 声明之后该面不铸链条目,count 回到 1,病路消灭。
|
|
35
|
+
* ⛔ 打这个标的前提是**真的一条裁决都不出**:core 对声明了却返回判词的面是「拒绝采纳 + onError 告警」
|
|
36
|
+
* (classification `observational-hook-verdict-ignored`),即判词被静默丢弃——把标打到会裁决的面上比原
|
|
37
|
+
* 缺陷更坏。本文件三个 pre/post 回调恒返 `undefined`,`permissionDenied` 本就是 void 观察槽。
|
|
38
|
+
* 📎 连带的**可观测**变化(不是回归):core 的「可写工具面无 effect-aware 门」启动告警此前把本 tracer
|
|
39
|
+
* 算作一道门而被抑制;声明之后它不再算,于是「没配任何 policy 层 + 开着 TOOL_TRACE」的部署升级后会
|
|
40
|
+
* 多出那行告警。方向正确——tracer 从来没有门住任何东西,原先的抑制本身就是一次静默 fail-open。
|
|
28
41
|
*/
|
|
29
42
|
export declare function createToolTracer(logger: Logger): Hooks;
|
|
30
43
|
//# sourceMappingURL=tool-trace.d.ts.map
|
|
@@ -33,9 +33,23 @@ export function createPermissionDeniedMeter(metrics) {
|
|
|
33
33
|
*
|
|
34
34
|
* Pure observation: every hook returns `undefined`, so it never rewrites args, never gates, never alters
|
|
35
35
|
* the result (and per core's hooks invariant a hook's `allow` can't bypass the policy gate anyway).
|
|
36
|
+
*
|
|
37
|
+
* 🔴 core 5.20.0 起这条「纯观察」性质必须**声明**出来(`preToolUseObservational`),不能只写在注释里:
|
|
38
|
+
* core 5.19.0 的委派折叠按「PreToolUse 席位在不在」把父的 screening 面折进子代的祖先约束链——它分不出
|
|
39
|
+
* 诊断 tracer 与真裁决者。后果是**这个默认关的诊断旋钮**一开,该部署所有 hook-wired 父的 parked 子代
|
|
40
|
+
* checkpoint 就记 `parentConstraintCount=2`,而跨副本赎回腿(`boot/parked-revive-gate.ts`)恒供 1 ⇒
|
|
41
|
+
* core pre-CAS 响亮拒、行永久 pending(层数 park 时写死,事后关旋钮/重批/回滚都不改)。
|
|
42
|
+
* 声明之后该面不铸链条目,count 回到 1,病路消灭。
|
|
43
|
+
* ⛔ 打这个标的前提是**真的一条裁决都不出**:core 对声明了却返回判词的面是「拒绝采纳 + onError 告警」
|
|
44
|
+
* (classification `observational-hook-verdict-ignored`),即判词被静默丢弃——把标打到会裁决的面上比原
|
|
45
|
+
* 缺陷更坏。本文件三个 pre/post 回调恒返 `undefined`,`permissionDenied` 本就是 void 观察槽。
|
|
46
|
+
* 📎 连带的**可观测**变化(不是回归):core 的「可写工具面无 effect-aware 门」启动告警此前把本 tracer
|
|
47
|
+
* 算作一道门而被抑制;声明之后它不再算,于是「没配任何 policy 层 + 开着 TOOL_TRACE」的部署升级后会
|
|
48
|
+
* 多出那行告警。方向正确——tracer 从来没有门住任何东西,原先的抑制本身就是一次静默 fail-open。
|
|
36
49
|
*/
|
|
37
50
|
export function createToolTracer(logger) {
|
|
38
51
|
return {
|
|
52
|
+
preToolUseObservational: true,
|
|
39
53
|
preToolUse(toolName, input, ctx) {
|
|
40
54
|
logger.info("tool_trace", { phase: "pre", id: ctx.toolCallId, tool: toolName, arg: summarize(input) });
|
|
41
55
|
return undefined;
|
package/dist/run-local.js
CHANGED
|
@@ -56,6 +56,7 @@ import { loadSkills } from "./capabilities/skills.js";
|
|
|
56
56
|
import { GiteaClient } from "./capabilities/repo-tools.js";
|
|
57
57
|
import { webSearchConfigFromEnv, createWebSearchBackend } from "./plugins/web-search.js";
|
|
58
58
|
import { buildScenarios, selectScenario, centerScenarios } from "./capabilities/scenarios.js";
|
|
59
|
+
import { pickHandsRunner, withoutExecutionEnv } from "./capabilities/hands-lane.js";
|
|
59
60
|
import { HttpError } from "./security.js";
|
|
60
61
|
import { memoryEngineBackendFor, memorySpecForRequest } from "./memory-scope.js";
|
|
61
62
|
import { createMemorySyncRunner, createMemorySyncTransport } from "./memory-sync-client.js";
|
|
@@ -495,7 +496,7 @@ export async function runLocal(argv, deps = {}) {
|
|
|
495
496
|
...(ctx.classification !== undefined ? { classification: ctx.classification } : {}),
|
|
496
497
|
err: String(err),
|
|
497
498
|
});
|
|
498
|
-
const
|
|
499
|
+
const runnerDeps = {
|
|
499
500
|
brain,
|
|
500
501
|
models: config.models,
|
|
501
502
|
roles: config.roles,
|
|
@@ -521,14 +522,21 @@ export async function runLocal(argv, deps = {}) {
|
|
|
521
522
|
...(config.projectMemoryEnabled
|
|
522
523
|
? { loadProjectMemory: makeLoadProjectMemory({ logger }), probeInstructionSources: makeProbeInstructionSources() }
|
|
523
524
|
: {}),
|
|
524
|
-
}
|
|
525
|
+
};
|
|
526
|
+
const runner = new Runner(runnerDeps);
|
|
525
527
|
// Sub-task runner (council lenses/team) — mirrors main.ts's subRunner, INCLUDING executionEnvFactory so a delegated
|
|
526
528
|
// child gets hands (Bash/Read/Edit) on the host lane. Without it the child's handsEnabled is false — the exact
|
|
527
529
|
// "subagent couldn't run pwd" defect fixed at main.ts:799; this is its run-local twin, caught by the systematic audit.
|
|
528
530
|
// [1367]① fork server half(main.ts subRunner 同款):ForkRoutingSessionStore——fork/resume 形
|
|
529
531
|
// (requireExisting)→ host 文件店优先(core 1.350 hostSessionFork 在宿主店 fork,拆店=响亮
|
|
530
532
|
// resume.session_not_found),普通子任务 → 私有 TTL 店(throwaway 姿势保留)。
|
|
531
|
-
const
|
|
533
|
+
const subRunnerDeps = { brain, models: config.models, roles: config.roles, pricing, promptSource, sessionStore: new ForkRoutingSessionStore(sessionStore, new TtlSessionStore({ defaultTtlDays: 1 / 24 })), onError: engineOnError, onAsk, ...(executionEnvFactory ? { executionEnvFactory } : {}), ...(lspManager ? { lspManager } : {}) };
|
|
534
|
+
const subRunner = new Runner(subRunnerDeps);
|
|
535
|
+
// #196:无手孪生一对 —— **mirrors main.ts**(那边是 `handslessRunner` / `handslessSubRunner` 两只,同 deps
|
|
536
|
+
// 摘掉 executionEnvFactory)。run-local 是同形装配点,漏这一对 = 本地 lane 上 scan/council/team 的最终
|
|
537
|
+
// roster 仍被并集进全量可写手(server 修了、CLI 静默留病 —— 这条腿的 subRunner 当年就是这么漏配的)。
|
|
538
|
+
const handslessRunner = new Runner(withoutExecutionEnv(runnerDeps));
|
|
539
|
+
const handslessSubRunner = new Runner(withoutExecutionEnv(subRunnerDeps));
|
|
532
540
|
// Capability layer (loadSkills + buildScenarios + selectScenario) — assembled exactly like main.ts.
|
|
533
541
|
const skills = loadSkills(config.skillsDir);
|
|
534
542
|
const repoClient = config.gitApiBaseUrl ? new GiteaClient(config.gitApiBaseUrl, config.gitApiToken) : undefined;
|
|
@@ -537,7 +545,7 @@ export async function runLocal(argv, deps = {}) {
|
|
|
537
545
|
const webSearchCfg = webSearchConfigFromEnv();
|
|
538
546
|
const webSearch = webSearchCfg ? createWebSearchBackend(webSearchCfg) : undefined;
|
|
539
547
|
const scenarioDeps = {
|
|
540
|
-
runner, subRunner, model: "default", skills, repoClient, metrics, logger,
|
|
548
|
+
runner, subRunner, handslessSubRunner, model: "default", skills, repoClient, metrics, logger,
|
|
541
549
|
...(webSearch ? { webSearch } : {}),
|
|
542
550
|
brandIdentity: true, // run-local is always a local/TOC deployment → brand the default scenario as Sema.
|
|
543
551
|
};
|
|
@@ -617,8 +625,10 @@ export async function runLocal(argv, deps = {}) {
|
|
|
617
625
|
// ── Run ONE task to completion (the sync /v1/tasks path: plain runTask, no verify/cascade). ──
|
|
618
626
|
let result;
|
|
619
627
|
let exitCode = 0;
|
|
628
|
+
// #196:与 HTTP 腿同一条选路 —— 场景声明 hands:"none" 时任务跑无手 Runner(band 不 mount)。
|
|
629
|
+
const taskRunner = pickHandsRunner(cap.hands, { full: runner, handsless: handslessRunner });
|
|
620
630
|
try {
|
|
621
|
-
result = await
|
|
631
|
+
result = await taskRunner.runTask(spec);
|
|
622
632
|
}
|
|
623
633
|
catch (err) {
|
|
624
634
|
printErr(`task crashed: ${err instanceof Error ? err.message : String(err)}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sema-agent/server",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.7.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",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"build:binary:run-local:darwin-arm64": "bun build --compile --target=bun-darwin-arm64 src/run-local.ts --outfile dist/run-local-darwin-arm64"
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@sema-agent/core": "^5.
|
|
57
|
+
"@sema-agent/core": "^5.21.0",
|
|
58
58
|
"@sema-agent/registry-core": "^0.16.0",
|
|
59
59
|
"e2b": "^2.28.0",
|
|
60
60
|
"libsodium-wrappers": "^0.8.4",
|