@sema-agent/server 7.130.0 → 7.132.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 +396 -0
- package/README.md +13 -6
- package/README.zh-CN.md +9 -5
- package/USAGE.md +187 -50
- package/dist/approval-card.d.ts +3 -1
- package/dist/approval-card.js +2 -3
- package/dist/audit.d.ts +7 -10
- package/dist/audit.js +4 -1
- package/dist/auth-bridge.d.ts +4 -0
- package/dist/auth-bridge.js +10 -11
- package/dist/bench/s1/live-deps.js +2 -0
- package/dist/boot/deployment-mods.d.ts +31 -0
- package/dist/boot/deployment-mods.js +26 -0
- package/dist/boot/execution-env.d.ts +1 -1
- package/dist/boot/execution-env.js +19 -6
- package/dist/boot/memory-boundary.d.ts +2 -2
- package/dist/boot/read-deny-anchor-audit.d.ts +17 -0
- package/dist/boot/read-deny-anchor-audit.js +36 -0
- package/dist/boot/resolve-spec.d.ts +1 -5
- package/dist/boot/resolve-spec.js +56 -61
- package/dist/boot/runner-deps.d.ts +19 -8
- package/dist/boot/runner-deps.js +14 -2
- package/dist/boot/session-faces.d.ts +1 -7
- package/dist/boot/stage-02-web-admin-pull.js +9 -1
- package/dist/boot/stage-03-store-backend.d.ts +1 -1
- package/dist/boot/stage-03-store-backend.js +2 -2
- package/dist/boot/stage-04-stores.d.ts +1 -1
- package/dist/boot/stage-05-execution-env.d.ts +4 -4
- package/dist/boot/stage-05-execution-env.js +7 -10
- package/dist/boot/stage-06-runners.d.ts +2 -2
- package/dist/boot/stage-06-runners.js +5 -4
- package/dist/boot/stage-07-capability-layer.d.ts +2 -2
- package/dist/boot/stage-07-capability-layer.js +3 -3
- package/dist/boot/stage-08-reapers.d.ts +2 -2
- package/dist/boot/stage-09-leader.d.ts +3 -9
- package/dist/boot/stage-10-http-server.d.ts +3 -9
- package/dist/boot/stage-10-http-server.js +12 -10
- package/dist/boot/stores.d.ts +1 -1
- package/dist/boot/stores.js +5 -6
- package/dist/boot/web-admin.d.ts +0 -3
- package/dist/boot/web-admin.js +35 -35
- package/dist/brain.js +17 -22
- package/dist/budget.js +5 -4
- package/dist/caller-text-echo.d.ts +20 -0
- package/dist/caller-text-echo.js +24 -0
- package/dist/capabilities/brand-identity.d.ts +26 -0
- package/dist/capabilities/brand-identity.js +27 -0
- package/dist/capabilities/builtin-tools.js +2 -1
- package/dist/capabilities/center-plugins.js +1 -1
- package/dist/capabilities/center-prompts.d.ts +32 -59
- package/dist/capabilities/center-prompts.js +18 -32
- package/dist/capabilities/composite-members.d.ts +1 -0
- package/dist/capabilities/composite-members.js +1 -0
- package/dist/capabilities/engine-capabilities.js +2 -1
- package/dist/capabilities/hands-lane.d.ts +9 -6
- package/dist/capabilities/hands-lane.js +3 -3
- package/dist/capabilities/host-tool-names.d.ts +17 -0
- package/dist/capabilities/host-tool-names.js +15 -0
- package/dist/capabilities/mcp-probe.d.ts +14 -1
- package/dist/capabilities/mcp-probe.js +22 -133
- package/dist/capabilities/repo-tools.js +4 -3
- package/dist/capabilities/scenarios.d.ts +42 -47
- package/dist/capabilities/scenarios.js +19 -35
- package/dist/capabilities/select-environment-tool.js +2 -1
- package/dist/capabilities/send-user-file-tool.d.ts +0 -1
- package/dist/capabilities/send-user-file-tool.js +2 -2
- package/dist/capabilities/skills.d.ts +19 -4
- package/dist/capabilities/skills.js +30 -10
- package/dist/capabilities/tool-defer.js +2 -1
- package/dist/config-catalog.js +22 -11
- package/dist/config-invariants.js +2 -2
- package/dist/config-lkg.d.ts +9 -9
- package/dist/config-lkg.js +20 -4
- package/dist/config-provider.d.ts +3 -1
- package/dist/config-provider.js +14 -6
- package/dist/config-types.d.ts +13 -9
- package/dist/config.d.ts +2 -2
- package/dist/config.js +34 -20
- package/dist/device-ws-protocol.d.ts +1 -1
- package/dist/device-ws-protocol.js +1 -0
- package/dist/elicitation.d.ts +7 -0
- package/dist/elicitation.js +20 -5
- package/dist/env-name-allowlist-knobs.d.ts +12 -2
- package/dist/env-name-allowlist-knobs.js +5 -4
- package/dist/exec-bounds.d.ts +15 -3
- package/dist/exec-bounds.js +4 -0
- package/dist/execution-lane-caps.d.ts +9 -2
- package/dist/execution-lane-caps.js +11 -0
- package/dist/hooks/classic-stations.d.ts +86 -0
- package/dist/hooks/classic-stations.js +27 -0
- package/dist/hooks/hook-llm.d.ts +8 -5
- package/dist/hooks/hook-llm.js +80 -37
- package/dist/hooks/hook-runner.d.ts +273 -75
- package/dist/hooks/hook-runner.js +293 -317
- package/dist/http/admission.d.ts +8 -2
- package/dist/http/admission.js +103 -59
- package/dist/http/approval-sweeps.js +59 -18
- package/dist/http/checkpoint-ctx.d.ts +36 -18
- package/dist/http/checkpoint-ctx.js +14 -10
- package/dist/http/claimed-run.d.ts +13 -0
- package/dist/http/claimed-run.js +15 -0
- package/dist/http/device-placement.js +5 -10
- package/dist/http/dispatch.d.ts +0 -4
- package/dist/http/dispatch.js +6 -10
- package/dist/http/durable-run-leg.d.ts +2 -1
- package/dist/http/durable-run-leg.js +5 -3
- package/dist/http/health-self-report.d.ts +7 -5
- package/dist/http/health-self-report.js +4 -18
- package/dist/http/principal-gate.d.ts +23 -6
- package/dist/http/principal-gate.js +24 -5
- package/dist/http/refusal-body.d.ts +21 -0
- package/dist/http/refusal-body.js +4 -0
- package/dist/http/request-guards.d.ts +27 -0
- package/dist/http/request-guards.js +24 -3
- package/dist/http/resume-legs.d.ts +25 -0
- package/dist/http/resume-legs.js +48 -26
- package/dist/http/routes/approvals-assistant.js +1 -1
- package/dist/http/routes/capabilities.js +7 -17
- package/dist/http/routes/diagnostics.js +1 -1
- package/dist/http/routes/rules.js +2 -2
- package/dist/http/routes/runs.js +13 -17
- package/dist/http/routes/session-sync.js +4 -2
- package/dist/http/routes/sessions.js +23 -11
- package/dist/http/routes/shared-memory.js +2 -13
- package/dist/http/routes/side-query.js +2 -3
- package/dist/http/routes/tasks.js +34 -19
- package/dist/http/scenario-read-face.d.ts +14 -0
- package/dist/http/scenario-read-face.js +5 -0
- package/dist/http/send.d.ts +13 -1
- package/dist/http/send.js +12 -1
- package/dist/http/server.d.ts +37 -23
- package/dist/http/server.js +30 -4
- package/dist/http/stored-body-replay.d.ts +10 -3
- package/dist/http/stored-body-replay.js +27 -6
- package/dist/http/submit-ctx.d.ts +25 -0
- package/dist/http/submit-ctx.js +39 -0
- package/dist/http/wire-types.d.ts +18 -5
- package/dist/index.d.ts +3 -2
- package/dist/index.js +3 -2
- package/dist/lane-home-probe.d.ts +43 -0
- package/dist/lane-home-probe.js +35 -0
- package/dist/limit-refusal.d.ts +47 -0
- package/dist/limit-refusal.js +12 -0
- package/dist/main.js +1 -1
- package/dist/mcp-assertion-header.d.ts +3 -11
- package/dist/mcp-assertion-header.js +3 -9
- package/dist/mcp-tool-faces.d.ts +5 -0
- package/dist/mcp-tool-faces.js +5 -1
- package/dist/memory-scope.d.ts +1 -1
- package/dist/model-entry-refusal.d.ts +1 -7
- package/dist/model-provider.d.ts +39 -12
- package/dist/model-provider.js +19 -2
- package/dist/model-route-endpoint.d.ts +52 -12
- package/dist/model-route-endpoint.js +48 -26
- package/dist/model-route-gap.d.ts +5 -4
- package/dist/model-route-gap.js +1 -1
- package/dist/model-select.d.ts +58 -0
- package/dist/model-select.js +31 -0
- package/dist/namespaced-rule-name.d.ts +7 -4
- package/dist/namespaced-rule-name.js +4 -3
- package/dist/observability/cost-taxonomy.d.ts +7 -7
- package/dist/observability/fail-open.d.ts +53 -12
- package/dist/observability/fail-open.js +47 -7
- package/dist/observability/metrics.js +3 -1
- package/dist/observability/prompt-manifest.d.ts +47 -82
- package/dist/observability/prompt-manifest.js +119 -17
- package/dist/observability/run-terminal.js +14 -6
- package/dist/observability/secret-env-scrub.d.ts +13 -1
- package/dist/observability/secret-env-scrub.js +13 -1
- package/dist/observability/tool-trace.d.ts +16 -21
- package/dist/observability/tool-trace.js +51 -42
- package/dist/per-task-image.d.ts +7 -1
- package/dist/per-task-image.js +3 -3
- package/dist/plain-string-record.d.ts +25 -0
- package/dist/plain-string-record.js +32 -0
- package/dist/plugins/blob-backend.d.ts +68 -13
- package/dist/plugins/blob-backend.js +53 -10
- package/dist/plugins/checkpoint-store-sql.d.ts +14 -4
- package/dist/plugins/checkpoint-store-sql.js +39 -26
- package/dist/plugins/k8s-bg-scripts.d.ts +11 -0
- package/dist/plugins/k8s-bg-scripts.js +22 -0
- package/dist/plugins/local-checkpoint-store.js +5 -2
- package/dist/plugins/local-session-store.js +3 -3
- package/dist/plugins/one-time-migrations.d.ts +147 -91
- package/dist/plugins/one-time-migrations.js +372 -208
- package/dist/plugins/permission-rule-store-sql.d.ts +13 -7
- package/dist/plugins/permission-rule-store-sql.js +4 -18
- package/dist/plugins/pg-session-storage.d.ts +4 -5
- package/dist/plugins/pg-session-storage.js +7 -17
- package/dist/plugins/remote-env-adb.d.ts +6 -0
- package/dist/plugins/remote-env-adb.js +9 -4
- package/dist/plugins/remote-env-device.js +3 -0
- package/dist/plugins/remote-env-e2b.d.ts +1 -1
- package/dist/plugins/remote-env-e2b.js +21 -9
- package/dist/plugins/remote-env-host.d.ts +9 -9
- package/dist/plugins/remote-env-host.js +10 -32
- package/dist/plugins/remote-env-k8s.d.ts +95 -26
- package/dist/plugins/remote-env-k8s.js +265 -90
- package/dist/plugins/remote-env-local-docker.d.ts +20 -1
- package/dist/plugins/remote-env-local-docker.js +77 -9
- package/dist/plugins/remote-env-ssh.d.ts +15 -0
- package/dist/plugins/remote-env-ssh.js +109 -3
- package/dist/plugins/remote-shell.d.ts +0 -1
- package/dist/plugins/remote-shell.js +1 -2
- package/dist/plugins/retention-store-sql.js +6 -2
- package/dist/plugins/schema-consistency.d.ts +54 -0
- package/dist/plugins/schema-consistency.js +52 -0
- package/dist/plugins/session-epoch-anchor.d.ts +13 -0
- package/dist/plugins/session-epoch-anchor.js +23 -0
- package/dist/plugins/shared-memory-store-sql.d.ts +9 -3
- package/dist/plugins/shared-memory-store-sql.js +5 -16
- package/dist/plugins/sql-driver.d.ts +141 -0
- package/dist/plugins/sql-driver.js +115 -1
- package/dist/plugins/sql-errors.d.ts +41 -0
- package/dist/plugins/sql-errors.js +36 -0
- package/dist/plugins/store-backend.js +2 -1
- package/dist/plugins/tidb-session-storage.d.ts +7 -11
- package/dist/plugins/tidb-session-storage.js +6 -16
- package/dist/plugins/tidb-session-store.js +1 -1
- package/dist/prompts-domain-validate.d.ts +17 -61
- package/dist/prompts-domain-validate.js +9 -119
- package/dist/question.d.ts +18 -9
- package/dist/question.js +21 -13
- package/dist/request-key-closure.d.ts +4 -4
- package/dist/request-key-closure.js +18 -13
- package/dist/rule-entry-list.d.ts +134 -24
- package/dist/rule-entry-list.js +162 -30
- package/dist/run-local.d.ts +3 -3
- package/dist/run-local.js +26 -25
- package/dist/runs.d.ts +48 -2
- package/dist/runs.js +61 -2
- package/dist/server-secret-env.d.ts +44 -18
- package/dist/server-secret-env.js +49 -8
- package/dist/session-incarnation.d.ts +15 -5
- package/dist/session-incarnation.js +16 -9
- package/dist/session-titler.js +12 -2
- package/dist/spec-fields.d.ts +34 -18
- package/dist/spec-fields.js +46 -53
- package/dist/sql-engine-posture.d.ts +29 -4
- package/dist/sql-engine-posture.js +36 -1
- package/dist/stored-request-hooks-m20.d.ts +23 -0
- package/dist/stored-request-hooks-m20.js +124 -0
- package/dist/stored-request-tool-axes-m19.d.ts +20 -5
- package/dist/stored-request-tool-axes-m19.js +30 -2
- package/dist/task-a2a.d.ts +9 -1
- package/dist/task-a2a.js +73 -47
- package/dist/task-mcp.d.ts +54 -102
- package/dist/task-mcp.js +194 -92
- package/dist/task-settings.d.ts +47 -25
- package/dist/task-settings.js +46 -61
- package/dist/text-bidi.d.ts +3 -46
- package/dist/text-bidi.js +3 -3
- package/dist/tool-approval.d.ts +1 -1
- package/dist/trace/core-keyset-guard.d.ts +24 -4
- package/dist/trace/engine-notice-wire.d.ts +11 -3
- package/dist/trace/engine-notice-wire.js +8 -1
- package/dist/trace/ledger-events.d.ts +3 -1
- package/dist/trace/ledger-sink.d.ts +29 -0
- package/dist/trace/ledger-sink.js +15 -1
- package/dist/trace/model-segment.js +1 -1
- package/dist/trace/project.d.ts +25 -6
- package/dist/trace/project.js +68 -22
- package/dist/trace/wire-projection-faces.d.ts +80 -2
- package/dist/trace/wire-projection-faces.js +23 -1
- package/dist/user-authored-text.d.ts +7 -0
- package/dist/user-authored-text.js +3 -0
- package/dist/web-admin-client/apply-effective.js +10 -5
- package/dist/web-admin-client/candidate-gate.d.ts +6 -6
- package/dist/web-admin-client/candidate-gate.js +3 -3
- package/dist/web-admin-client/http-client.js +0 -6
- package/dist/web-admin-client/read-warnings.d.ts +13 -0
- package/dist/web-admin-client/read-warnings.js +10 -0
- package/dist/web-admin-client/skills-mcp.d.ts +3 -0
- package/dist/web-admin-client/skills-mcp.js +9 -6
- package/dist/web-admin-client/types.d.ts +3 -4
- package/dist/workspace-cache.d.ts +35 -0
- package/dist/workspace-cache.js +36 -0
- package/dist/workspace-space.d.ts +3 -2
- package/dist/workspace-space.js +2 -0
- package/docs/DEVICE-EXECUTOR-PROTOCOL.md +8 -1
- package/package.json +4 -4
- package/scripts/drain-check-local.mjs +37 -3
- package/scripts/drain-check.mysql.sql +30 -2
- package/scripts/drain-check.pg.sql +29 -2
- package/dist/capabilities/memory-notice.d.ts +0 -138
- package/dist/capabilities/memory-notice.js +0 -64
- package/dist/capabilities/prompt.d.ts +0 -17
- package/dist/capabilities/prompt.js +0 -6
- package/dist/mcp-content-origin.d.ts +0 -34
- package/dist/mcp-content-origin.js +0 -10
- package/dist/tool-axis-words.d.ts +0 -27
- package/dist/tool-axis-words.js +0 -9
- package/dist/wire-name-bound.d.ts +0 -14
- package/dist/wire-name-bound.js +0 -13
|
@@ -1,85 +1,49 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
*
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
id: string;
|
|
48
|
-
chars: number;
|
|
49
|
-
hash: string;
|
|
50
|
-
}>;
|
|
51
|
-
sections?: Array<{
|
|
52
|
-
id: string;
|
|
53
|
-
slot: string;
|
|
54
|
-
carrier: string;
|
|
55
|
-
cadence: string;
|
|
56
|
-
cacheClass: string;
|
|
57
|
-
chars: number;
|
|
58
|
-
hash: string;
|
|
59
|
-
contentHash?: string;
|
|
60
|
-
}>;
|
|
61
|
-
tools?: Array<{
|
|
62
|
-
wireName: string;
|
|
63
|
-
aliases: string[];
|
|
64
|
-
contractId: string;
|
|
65
|
-
implementationRevision: string;
|
|
66
|
-
cardId: string;
|
|
67
|
-
shapeDigest: string;
|
|
68
|
-
wireSchemaDigest: string;
|
|
69
|
-
}>;
|
|
70
|
-
/** core 5.15.0([ref],[ref] 提货②):deferred 工具的披露策略自证——{deferredTools(数), strategy
|
|
71
|
-
* ("static"|"swap"), source(四值:`spec` / `env` / `default` / `degraded_no_direct_lane`)}。
|
|
72
|
-
* 诊断三键(数 + 两闭集词,零内容)。词表属主是 core(`core/trace.d.ts` 的 `source` 联合),本仓宽收
|
|
73
|
-
* ⇒ 词错不会红,所以照抄时务必对表:`degraded_no_direct_lane` = 直呼车道联锁把 `static` 请求收窄成
|
|
74
|
-
* `swap` 的那一格,正是运维最需要认出来的一格(本注上一版把它写成了不存在的 `api-default`,下游看板
|
|
75
|
-
* 照抄就会把真实的 degraded 读成未知词)。 */
|
|
76
|
-
toolDisclosure?: {
|
|
77
|
-
deferredTools: number;
|
|
78
|
-
strategy: string;
|
|
79
|
-
source: string;
|
|
80
|
-
};
|
|
81
|
-
totalChars: number;
|
|
82
|
-
}): PromptManifestRecord;
|
|
1
|
+
import type { TraceEvent } from "@sema-agent/core";
|
|
2
|
+
/**
|
|
3
|
+
* 引擎的清单帧 `prompt.assembled`(引擎 7.52.0 起 `version: 3`):这条腿的提示**是哪一份**(`identity` + 它的选择器值 `selectors`)、
|
|
4
|
+
* 由哪些块与段组成、每一段的文本从哪里来(`chain`,被取代的 overlay 另在 `superseded`)。只有 id / 尺寸 / 摘要,没有提示正文。
|
|
5
|
+
*/
|
|
6
|
+
export type PromptAssembledEvent = Extract<TraceEvent, {
|
|
7
|
+
kind: "prompt.assembled";
|
|
8
|
+
}>;
|
|
9
|
+
/** 帧上**不上行**的键。唯一一簿在 `trace/wire-projection-faces.ts` 的 `prompt_manifest` 行(逐键理由在那里);这里只做类型查询。 */
|
|
10
|
+
type NotOnTheRow = (typeof import("../trace/wire-projection-faces.js").WIRE_PROJECTION_FACES)["prompt_manifest"]["excluded"][number];
|
|
11
|
+
/** 引擎的型,**词读成开集串**:投影判形,不判词表(档名、激活方式、来源类、渲染器……每一张词表的属主都是引擎,新词原样过境)。 */
|
|
12
|
+
type OpenWords<T> = T extends string ? string : T extends readonly (infer U)[] ? OpenWords<U>[] : T extends object ? {
|
|
13
|
+
[K in keyof T]: OpenWords<T[K]>;
|
|
14
|
+
} : T;
|
|
15
|
+
/**
|
|
16
|
+
* 耐久 `prompt_assembled` 行(turns 的 `prompt-assembled` 块与 trace SSE 的同名帧按它原样交出)= **引擎帧减不上行的键**,
|
|
17
|
+
* 由引擎的型派生,本仓不另写成员表。每个成员都可能缺席:引擎型里可选的成员缺席即缺席;在场却读不出的成员被丢并计数。
|
|
18
|
+
*/
|
|
19
|
+
export type PromptManifestRecord = {
|
|
20
|
+
[K in Exclude<keyof PromptAssembledEvent, NotOnTheRow>]?: OpenWords<PromptAssembledEvent[K]>;
|
|
21
|
+
};
|
|
22
|
+
/** 投影器的入参:引擎帧的键,值一律当未知读 —— 逐层判形在投影器里做,第三方 producer / 坏世代的帧走同一道门。 */
|
|
23
|
+
export type PromptManifestInput = {
|
|
24
|
+
readonly [K in keyof PromptAssembledEvent]?: unknown;
|
|
25
|
+
};
|
|
26
|
+
/** 读一个值:读得出 ⇒ 值;读不出 ⇒ `undefined`;可选成员缺席 ⇒ {@link ABSENT}(不铸、不计)。 */
|
|
27
|
+
type Read<V> = (v: unknown) => V | undefined;
|
|
28
|
+
declare const ABSENT: unique symbol;
|
|
29
|
+
/** 可选格的记号:只有 {@link optional} 铸得出带它的读器 —— 一只裸读器的回值型是可选格回值型的子型,单靠回值型拦不住它。 */
|
|
30
|
+
declare const OPTIONAL_CELL: unique symbol;
|
|
31
|
+
type OptionalRead<V> = Read<V | typeof ABSENT> & {
|
|
32
|
+
readonly [OPTIONAL_CELL]: true;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* 每张读表按引擎型的**每一个键**写一格(`-?`:可选键也必须有格,引擎给哪一层加成员 ⇒ 这里编译红);可选键的格必须经 {@link optional} —— 格型要求
|
|
36
|
+
* {@link OPTIONAL_CELL} 记号,裸读器写进可选键 ⇒ 编译红(否则缺席的成员被裸读器读成「读不出」,整句被丢)。
|
|
37
|
+
*/
|
|
38
|
+
export type ReadTable<T> = {
|
|
39
|
+
[K in keyof T]-?: undefined extends T[K] ? OptionalRead<Exclude<T[K], undefined>> : Read<T[K]>;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* 把一帧 `prompt.assembled` 读成耐久行(记录时白名单:tracer 同步、无 IO,未来的引擎键不随帧上行)。
|
|
43
|
+
* 规则一句:**只挑引擎型里有的键,逐层判形;在场却读不出 ⇒ 计一次 `server.trace.projection-input-malformed` 并丢;缺席从不计数**。
|
|
44
|
+
* 词原样过境(不判词表);`identity` 是这条腿的提示身份的唯一读法 —— 本仓不另铸第二种(v2 的 `constitution` 随引擎退役)。
|
|
45
|
+
*/
|
|
46
|
+
export declare function promptManifestRecordOf(e: PromptManifestInput): PromptManifestRecord;
|
|
83
47
|
/**
|
|
84
48
|
* [ref]② per-task prompt-manifest accumulator — the `ModelUsageTracker`(budget.ts)pattern: the
|
|
85
49
|
* `prompt.assembled` tracer hook is SYNC/no-IO, so it cannot persist; it RECORDS here (registered
|
|
@@ -126,4 +90,5 @@ export declare class PromptManifestTracker {
|
|
|
126
90
|
* a stale leg's teardown after a fast re-register is a no-op (the new leg owns it now). */
|
|
127
91
|
clear(taskId: string, lease: number): void;
|
|
128
92
|
}
|
|
93
|
+
export {};
|
|
129
94
|
//# sourceMappingURL=prompt-manifest.d.ts.map
|
|
@@ -1,22 +1,124 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
1
|
+
import { dropProjectedFace } from "../trace/projection-drop.js";
|
|
2
|
+
const ABSENT = Symbol("absent");
|
|
3
|
+
const OPTIONAL_CELL = Symbol("optional-cell");
|
|
4
|
+
const text = (v) => (typeof v === "string" ? v : undefined);
|
|
5
|
+
const finite = (v) => (typeof v === "number" && Number.isFinite(v) ? v : undefined);
|
|
6
|
+
const flag = (v) => (typeof v === "boolean" ? v : undefined);
|
|
7
|
+
const onlyTrue = (v) => (v === true ? true : undefined);
|
|
8
|
+
const plainObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v) ? v : undefined;
|
|
9
|
+
function optional(read) {
|
|
10
|
+
return Object.assign((v) => (v === undefined ? ABSENT : read(v)), { [OPTIONAL_CELL]: true });
|
|
11
|
+
}
|
|
12
|
+
function objectOf(table) {
|
|
13
|
+
return (v) => {
|
|
14
|
+
const o = plainObject(v);
|
|
15
|
+
if (o === undefined)
|
|
16
|
+
return undefined;
|
|
17
|
+
const out = {};
|
|
18
|
+
for (const [key, read] of Object.entries(table)) {
|
|
19
|
+
const r = read(o[key]);
|
|
20
|
+
if (r === undefined)
|
|
21
|
+
return undefined;
|
|
22
|
+
if (r !== ABSENT)
|
|
23
|
+
out[key] = r;
|
|
24
|
+
}
|
|
25
|
+
return out;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function listOf(read) {
|
|
29
|
+
return (v) => {
|
|
30
|
+
if (!Array.isArray(v))
|
|
31
|
+
return undefined;
|
|
32
|
+
const out = [];
|
|
33
|
+
for (const x of v) {
|
|
34
|
+
const r = read(x);
|
|
35
|
+
if (r === undefined)
|
|
36
|
+
return undefined;
|
|
37
|
+
out.push(r);
|
|
38
|
+
}
|
|
39
|
+
return out;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function entriesOf(read) {
|
|
43
|
+
return (v) => {
|
|
44
|
+
const o = plainObject(v);
|
|
45
|
+
if (o === undefined)
|
|
46
|
+
return undefined;
|
|
47
|
+
const out = [];
|
|
48
|
+
for (const [k, x] of Object.entries(o)) {
|
|
49
|
+
const r = read(x);
|
|
50
|
+
if (r === undefined)
|
|
51
|
+
return undefined;
|
|
52
|
+
out.push([k, r]);
|
|
53
|
+
}
|
|
54
|
+
return Object.fromEntries(out);
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function drop(member, why) {
|
|
58
|
+
return dropProjectedFace("prompt_assembled." + member + " " + why);
|
|
59
|
+
}
|
|
60
|
+
function rowsOf(member, read) {
|
|
61
|
+
return (v) => {
|
|
62
|
+
if (!Array.isArray(v))
|
|
63
|
+
return undefined;
|
|
64
|
+
const out = [];
|
|
65
|
+
for (const x of v) {
|
|
66
|
+
const r = read(x);
|
|
67
|
+
if (r === undefined)
|
|
68
|
+
drop(`${member}[]`, "element does not read as the engine's type");
|
|
69
|
+
else
|
|
70
|
+
out.push(r);
|
|
71
|
+
}
|
|
72
|
+
return v.length > 0 && out.length === 0 ? ABSENT : out;
|
|
18
73
|
};
|
|
19
74
|
}
|
|
75
|
+
const readIdentity = objectOf({
|
|
76
|
+
artifact: text,
|
|
77
|
+
layers: objectOf({ catalog: text, renderers: entriesOf(finite), center: optional(text), deploy: optional(text), task: optional(text), binding: text }),
|
|
78
|
+
epoch: finite,
|
|
79
|
+
activatedBy: text,
|
|
80
|
+
});
|
|
81
|
+
const readSelectors = objectOf({
|
|
82
|
+
binding: optional(text),
|
|
83
|
+
traits: listOf(text),
|
|
84
|
+
host: objectOf({ role: text, form: text }),
|
|
85
|
+
facts: entriesOf(flag),
|
|
86
|
+
});
|
|
87
|
+
const readSection = objectOf({
|
|
88
|
+
id: text,
|
|
89
|
+
band: text,
|
|
90
|
+
rank: finite,
|
|
91
|
+
variant: optional(text),
|
|
92
|
+
renderer: optional(objectOf({ id: text, version: finite })),
|
|
93
|
+
chars: finite,
|
|
94
|
+
locale: text,
|
|
95
|
+
contentHash: text,
|
|
96
|
+
chain: listOf(objectOf({ source: text, overlay: optional(text), op: optional(text), superseded: optional(onlyTrue) })),
|
|
97
|
+
});
|
|
98
|
+
const ROW = {
|
|
99
|
+
identity: readIdentity,
|
|
100
|
+
selectors: readSelectors,
|
|
101
|
+
blocks: rowsOf("blocks", objectOf({ id: text, chars: finite, hash: text })),
|
|
102
|
+
sections: rowsOf("sections", readSection),
|
|
103
|
+
superseded: rowsOf("superseded", objectOf({ id: text, source: text, by: text, target: text, supersededBy: text })),
|
|
104
|
+
tools: rowsOf("tools", objectOf({ wireName: text, aliases: listOf(text), contractId: text, implementationRevision: text, cardId: text, shapeDigest: text, wireSchemaDigest: text })),
|
|
105
|
+
toolDisclosure: objectOf({ deferredTools: finite, strategy: text, source: text }),
|
|
106
|
+
totalChars: finite,
|
|
107
|
+
};
|
|
108
|
+
export function promptManifestRecordOf(e) {
|
|
109
|
+
const out = {};
|
|
110
|
+
for (const [member, read] of Object.entries(ROW)) {
|
|
111
|
+
const v = e[member];
|
|
112
|
+
if (v === undefined)
|
|
113
|
+
continue;
|
|
114
|
+
const r = read(v);
|
|
115
|
+
if (r === undefined)
|
|
116
|
+
drop(member, "does not read as the engine's type");
|
|
117
|
+
else if (r !== ABSENT)
|
|
118
|
+
out[member] = r;
|
|
119
|
+
}
|
|
120
|
+
return out;
|
|
121
|
+
}
|
|
20
122
|
export function configAssembledRecordOf(e) {
|
|
21
123
|
const rec = {
|
|
22
124
|
catalogVersion: e.catalogVersion,
|
|
@@ -206,19 +206,20 @@ function redactStringLeaves(node, depth = 0) {
|
|
|
206
206
|
}
|
|
207
207
|
return out ?? node;
|
|
208
208
|
}
|
|
209
|
+
const OFF_ARM_MEMBER_TREATMENT = "free-text-tree";
|
|
210
|
+
const redactDetailMember = (v) => redactStringLeaves(v, 1);
|
|
209
211
|
function shapeTerminalFailureDetail(detail) {
|
|
210
212
|
if (detail === null || typeof detail !== "object" || Array.isArray(detail))
|
|
211
213
|
return detail;
|
|
212
214
|
const d = detail;
|
|
213
215
|
const kind = d.kind;
|
|
214
|
-
const
|
|
215
|
-
if (table === undefined)
|
|
216
|
-
return redactStringLeaves(d);
|
|
216
|
+
const arm = typeof kind === "string" && Object.hasOwn(TERMINAL_FAILURE_DETAIL_TREATMENT, kind) ? TERMINAL_FAILURE_DETAIL_TREATMENT[kind] : {};
|
|
217
217
|
let out;
|
|
218
|
-
for (const
|
|
218
|
+
for (const key of Object.keys(d)) {
|
|
219
219
|
const v = d[key];
|
|
220
220
|
if (v === undefined)
|
|
221
221
|
continue;
|
|
222
|
+
const treatment = Object.hasOwn(arm, key) ? arm[key] : OFF_ARM_MEMBER_TREATMENT;
|
|
222
223
|
switch (treatment) {
|
|
223
224
|
case "verbatim":
|
|
224
225
|
case "provider-join-key":
|
|
@@ -228,7 +229,7 @@ function shapeTerminalFailureDetail(detail) {
|
|
|
228
229
|
delete (out ??= { ...d })[key];
|
|
229
230
|
break;
|
|
230
231
|
case "free-text-tree": {
|
|
231
|
-
const nv =
|
|
232
|
+
const nv = redactDetailMember(v);
|
|
232
233
|
if (nv !== v)
|
|
233
234
|
(out ??= { ...d })[key] = nv;
|
|
234
235
|
break;
|
|
@@ -251,10 +252,11 @@ function shapeTerminalBlockedDetail(detail) {
|
|
|
251
252
|
return detail;
|
|
252
253
|
const d = detail;
|
|
253
254
|
let out;
|
|
254
|
-
for (const
|
|
255
|
+
for (const key of Object.keys(d)) {
|
|
255
256
|
const v = d[key];
|
|
256
257
|
if (v === undefined)
|
|
257
258
|
continue;
|
|
259
|
+
const treatment = Object.hasOwn(TERMINAL_BLOCKED_DETAIL_TREATMENT, key) ? TERMINAL_BLOCKED_DETAIL_TREATMENT[key] : OFF_ARM_MEMBER_TREATMENT;
|
|
258
260
|
switch (treatment) {
|
|
259
261
|
case "verbatim":
|
|
260
262
|
break;
|
|
@@ -265,6 +267,12 @@ function shapeTerminalBlockedDetail(detail) {
|
|
|
265
267
|
(out ??= { ...d })[key] = next;
|
|
266
268
|
}
|
|
267
269
|
break;
|
|
270
|
+
case "free-text-tree": {
|
|
271
|
+
const nv = redactDetailMember(v);
|
|
272
|
+
if (nv !== v)
|
|
273
|
+
(out ??= { ...d })[key] = nv;
|
|
274
|
+
break;
|
|
275
|
+
}
|
|
268
276
|
default: {
|
|
269
277
|
const unhandled = treatment;
|
|
270
278
|
throw new Error(`unhandled blocked-detail treatment: ${String(unhandled)}`);
|
|
@@ -49,10 +49,22 @@ export interface SecretEnvScrubSiteSpec {
|
|
|
49
49
|
}
|
|
50
50
|
/** 登记过的剥除现场。闭集:未登记的 site 传不进 {@link recordSecretEnvScrub}(编译期拒,同 FAIL_OPEN_TAGS 纪律)。 */
|
|
51
51
|
export declare const SECRET_ENV_SCRUB_SITES: {
|
|
52
|
-
readonly "server.remote-env-host.
|
|
52
|
+
readonly "server.remote-env-host.spawn-env": {
|
|
53
53
|
readonly note: "模型可驱动的 host shell 继承 env(`inheritEnv` 三词任一,缺省 `\"scrub\"`;`\"all\"` 词下扣的只有本服务自己的凭据名)——这条腿上的一次泄漏等于把编排器的脑钥/仓库令牌交给模型选的命令";
|
|
54
54
|
readonly remedy: null;
|
|
55
55
|
};
|
|
56
|
+
readonly "server.remote-env-local-docker.spawn-env": {
|
|
57
|
+
readonly note: "local-docker 车道交给宿主 `docker` CLI 的 env(它拉起的凭据助手 / CLI 插件同读)—— 继承词 `\"all\"`,扣的只有本服务自己的凭据;一次泄漏等于把本服务凭据交给宿主上的第三方助手";
|
|
58
|
+
readonly remedy: null;
|
|
59
|
+
};
|
|
60
|
+
readonly "server.remote-env-adb.spawn-env": {
|
|
61
|
+
readonly note: "adb 车道交给宿主 `adb` CLI 的 env(首次调用起的常驻 adb server 继承同一份并一直活着)—— 继承词 `\"all\"`,扣的只有本服务自己的凭据;一次泄漏等于把本服务凭据留在一只常驻进程的环境里";
|
|
62
|
+
readonly remedy: null;
|
|
63
|
+
};
|
|
64
|
+
readonly "server.hooks.spawn-env": {
|
|
65
|
+
readonly note: "settings hooks 的命令腿(请求带来的命令跑在宿主上)的 env —— 严格名单(`PATH` / `HOME` / 终端 / locale 等十二名)经引擎组合,名单外一律不交;请求显式给的 `settings.env` 另叠在上面";
|
|
66
|
+
readonly remedy: null;
|
|
67
|
+
};
|
|
56
68
|
readonly "server.project-memory.git-subprocess": {
|
|
57
69
|
readonly note: "project-memory 读仓叙事时的 git 子进程 env —— 仓内的钩子/凭证助手会以本进程身份运行";
|
|
58
70
|
readonly remedy: null;
|
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
import { summarizeRedactions } from "@sema-agent/core";
|
|
2
2
|
import { describeAllowlistPostures } from "../env-name-allowlist-knobs.js";
|
|
3
3
|
export const SECRET_ENV_SCRUB_SITES = {
|
|
4
|
-
"server.remote-env-host.
|
|
4
|
+
"server.remote-env-host.spawn-env": {
|
|
5
5
|
note: "模型可驱动的 host shell 继承 env(`inheritEnv` 三词任一,缺省 `\"scrub\"`;`\"all\"` 词下扣的只有本服务自己的凭据名)——这条腿上的一次泄漏等于把编排器的脑钥/仓库令牌交给模型选的命令",
|
|
6
6
|
remedy: null,
|
|
7
7
|
},
|
|
8
|
+
"server.remote-env-local-docker.spawn-env": {
|
|
9
|
+
note: "local-docker 车道交给宿主 `docker` CLI 的 env(它拉起的凭据助手 / CLI 插件同读)—— 继承词 `\"all\"`,扣的只有本服务自己的凭据;一次泄漏等于把本服务凭据交给宿主上的第三方助手",
|
|
10
|
+
remedy: null,
|
|
11
|
+
},
|
|
12
|
+
"server.remote-env-adb.spawn-env": {
|
|
13
|
+
note: "adb 车道交给宿主 `adb` CLI 的 env(首次调用起的常驻 adb server 继承同一份并一直活着)—— 继承词 `\"all\"`,扣的只有本服务自己的凭据;一次泄漏等于把本服务凭据留在一只常驻进程的环境里",
|
|
14
|
+
remedy: null,
|
|
15
|
+
},
|
|
16
|
+
"server.hooks.spawn-env": {
|
|
17
|
+
note: "settings hooks 的命令腿(请求带来的命令跑在宿主上)的 env —— 严格名单(`PATH` / `HOME` / 终端 / locale 等十二名)经引擎组合,名单外一律不交;请求显式给的 `settings.env` 另叠在上面",
|
|
18
|
+
remedy: null,
|
|
19
|
+
},
|
|
8
20
|
"server.project-memory.git-subprocess": {
|
|
9
21
|
note: "project-memory 读仓叙事时的 git 子进程 env —— 仓内的钩子/凭证助手会以本进程身份运行",
|
|
10
22
|
remedy: null,
|
|
@@ -1,15 +1,18 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type EngineDollar, type ModRegistration } from "@sema-agent/core";
|
|
2
2
|
import type { Logger } from "./logger.js";
|
|
3
3
|
import type { Metrics } from "./metrics.js";
|
|
4
|
+
/** 两张部署注册的名字 —— wire 可见(`wiring_manifest.mods[].name`);名字中性、稳定、不含部署信息。 */
|
|
5
|
+
export declare const PERMISSION_DENIED_METER_REGISTRATION = "server.permission-denied-meter";
|
|
6
|
+
export declare const TOOL_TRACE_REGISTRATION = "server.tool-trace";
|
|
4
7
|
/**
|
|
5
8
|
* ALWAYS-ON gate-deny meter (goal B4, 2026-07-08): `permission_denied_total{deniedBy}` — how often the
|
|
6
9
|
* adjudicate chain DENIES a tool call, by the LAYER whose verdict is the deny. Deliberately SEPARATE from
|
|
7
10
|
* {@link createToolTracer}: the tracer is a default-OFF diagnostic (TOOL_TRACE=true), but deny frequency is an
|
|
8
11
|
* operational/security signal that must reach /metrics on every deployment — a spike in `deniedBy="policy"`
|
|
9
12
|
* means a task keeps asking for something the operator forbids; `deniedBy="org"` is the organization layer
|
|
10
|
-
* refusing, the one class an operator most wants to see on its own.
|
|
11
|
-
*
|
|
12
|
-
* deployment
|
|
13
|
+
* refusing, the one class an operator most wants to see on its own. It is the deployment seat's first registration
|
|
14
|
+
* (`createDeploymentMods`, `boot/deployment-mods.ts`): an observer on `classic.PermissionDenied`, run before the tracer's observer on the same
|
|
15
|
+
* event (the engine runs observers by tier, then deployment before task, then each seat's own order).
|
|
13
16
|
*
|
|
14
17
|
* 🔴 BREAKING(server 7.64.0,core 7.6.0 提货):标签名 `source` → `deniedBy`,词表从七词
|
|
15
18
|
* (`policy/hook/safety/shellGate/planMode/classifier/org`)换成八词
|
|
@@ -46,7 +49,7 @@ import type { Metrics } from "./metrics.js";
|
|
|
46
49
|
* · **计数总量方向**:新座只在「分类器那一轮没有裁决」时在场(`<block>yes` 的真裁决恒缺席),与旧座的
|
|
47
50
|
* 「分类器停摆」同向;多出来的那一格是 `parse_error`,它也确实是「分类器没正常工作」的一种。
|
|
48
51
|
*/
|
|
49
|
-
export declare function createPermissionDeniedMeter(metrics: Pick<Metrics, "inc">):
|
|
52
|
+
export declare function createPermissionDeniedMeter(metrics: Pick<Metrics, "inc">): ModRegistration<EngineDollar>;
|
|
50
53
|
/**
|
|
51
54
|
* prove-before-scale stopgap ([ref]): a no-op observer hook that logs every tool call (pre + post)
|
|
52
55
|
* to the worker log — INCLUDING resumed legs that `GET /v1/runs/:id/events` does NOT surface (the
|
|
@@ -59,21 +62,13 @@ export declare function createPermissionDeniedMeter(metrics: Pick<Metrics, "inc"
|
|
|
59
62
|
* the full sequence: a repeated `write_file path=X contentLen=Y` across resumes ⇒ restart-loop;
|
|
60
63
|
* write X → write Y → bash ⇒ iteration.
|
|
61
64
|
*
|
|
62
|
-
* Pure observation: every
|
|
63
|
-
* the
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
* core pre-CAS 响亮拒、行永久 pending(层数 park 时写死,事后关旋钮/重批/回滚都不改)。
|
|
70
|
-
* 声明之后该面不铸链条目,count 回到 1,病路消灭。
|
|
71
|
-
* ⛔ 打这个标的前提是**真的一条裁决都不出**:core 对声明了却返回判词的面是「拒绝采纳 + onError 告警」
|
|
72
|
-
* (classification `observational-hook-verdict-ignored`),即判词被静默丢弃——把标打到会裁决的面上比原
|
|
73
|
-
* 缺陷更坏。本文件三个 pre/post 回调恒返 `undefined`,`permissionDenied` 本就是 void 观察槽。
|
|
74
|
-
* 📎 连带的**可观测**变化(不是回归):core 的「可写工具面无 effect-aware 门」启动告警此前把本 tracer
|
|
75
|
-
* 算作一道门而被抑制;声明之后它不再算,于是「没配任何 policy 层 + 开着 TOOL_TRACE」的部署升级后会
|
|
76
|
-
* 多出那行告警。方向正确——tracer 从来没有门住任何东西,原先的抑制本身就是一次静默 fail-open。
|
|
65
|
+
* Pure observation: every handler is an observer (`{ observe: true }`, via {@link observeClassic}) — a detached copy of
|
|
66
|
+
* the event, outside the chain, its answer never adopted — so it never rewrites args, never gates, never alters the result.
|
|
67
|
+
* Being an observer is also what keeps it out of a delegated child's inherited constraint: the engine mints a screening
|
|
68
|
+
* entry only from a chain that JUDGES, so turning this diagnostic switch on adds no `parentConstraintCount` to a parked
|
|
69
|
+
* child of a hook-wired parent (the cross-replica revive leg, `boot/parked-revive-gate.ts`, supplies the caller policy only).
|
|
70
|
+
* 📎 Not a gate either for the engine's "writable tool face without an effect-aware gate" startup warning: a deployment with
|
|
71
|
+
* no policy layer and `TOOL_TRACE` on still gets that warning — the tracer never gated anything.
|
|
77
72
|
*/
|
|
78
|
-
export declare function createToolTracer(logger: Logger):
|
|
73
|
+
export declare function createToolTracer(logger: Logger): ModRegistration<EngineDollar>;
|
|
79
74
|
//# sourceMappingURL=tool-trace.d.ts.map
|
|
@@ -1,60 +1,69 @@
|
|
|
1
1
|
import { isClassifierDenyCause, isDeniedBy } from "@sema-agent/core";
|
|
2
|
+
import { observeClassic } from "../hooks/classic-stations.js";
|
|
2
3
|
import { redactSecrets } from "../trace/redact.js";
|
|
4
|
+
export const PERMISSION_DENIED_METER_REGISTRATION = "server.permission-denied-meter";
|
|
5
|
+
export const TOOL_TRACE_REGISTRATION = "server.tool-trace";
|
|
3
6
|
function deniedByLabel(gate) {
|
|
4
7
|
const d = gate.disposition;
|
|
5
8
|
return d.kind === "denied" && isDeniedBy(d.deniedBy) ? d.deniedBy : "other";
|
|
6
9
|
}
|
|
7
10
|
export function createPermissionDeniedMeter(metrics) {
|
|
8
11
|
return {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
metrics.inc("
|
|
15
|
-
|
|
12
|
+
name: PERMISSION_DENIED_METER_REGISTRATION,
|
|
13
|
+
tier: "prepend",
|
|
14
|
+
uses: { events: ["classic.PermissionDenied"], calls: [] },
|
|
15
|
+
register(on) {
|
|
16
|
+
observeClassic(on, "classic.PermissionDenied", (payload) => {
|
|
17
|
+
metrics.inc("permission_denied_total", { deniedBy: deniedByLabel(payload.gate) });
|
|
18
|
+
const disposition = payload.gate?.disposition;
|
|
19
|
+
const cause = disposition?.kind === "denied" ? disposition.cause : undefined;
|
|
20
|
+
if (cause !== undefined) {
|
|
21
|
+
metrics.inc("auto_mode_classifier_deny_cause_total", { cause: isClassifierDenyCause(cause) ? cause : "other" });
|
|
22
|
+
}
|
|
23
|
+
});
|
|
16
24
|
},
|
|
17
25
|
};
|
|
18
26
|
}
|
|
19
27
|
export function createToolTracer(logger) {
|
|
20
28
|
return {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
logger.info("tool_trace", {
|
|
28
|
-
phase: "post",
|
|
29
|
-
id: ctx.toolCallId,
|
|
30
|
-
tool: toolName,
|
|
31
|
-
isError: output.isError,
|
|
32
|
-
out: textOf(output.content),
|
|
29
|
+
name: TOOL_TRACE_REGISTRATION,
|
|
30
|
+
tier: "prepend",
|
|
31
|
+
uses: { events: ["classic.PreToolUse", "classic.PostToolUse", "classic.PostToolUseFailure", "classic.PermissionDenied"], calls: [] },
|
|
32
|
+
register(on) {
|
|
33
|
+
observeClassic(on, "classic.PreToolUse", (e) => {
|
|
34
|
+
logger.info("tool_trace", { phase: "pre", id: e.tool_use_id, tool: e.tool, arg: summarize(e.input) });
|
|
33
35
|
});
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
isInterrupt: failure.isInterrupt,
|
|
43
|
-
...(failure.durationMs !== undefined ? { durationMs: failure.durationMs } : {}),
|
|
44
|
-
out: clip(redactSecrets(failure.error), 200),
|
|
36
|
+
observeClassic(on, "classic.PostToolUse", (e) => {
|
|
37
|
+
logger.info("tool_trace", {
|
|
38
|
+
phase: "post",
|
|
39
|
+
id: e.tool_use_id,
|
|
40
|
+
tool: e.tool,
|
|
41
|
+
isError: e.output.isError,
|
|
42
|
+
out: textOf(e.output.content),
|
|
43
|
+
});
|
|
45
44
|
});
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
45
|
+
observeClassic(on, "classic.PostToolUseFailure", (e) => {
|
|
46
|
+
logger.info("tool_trace", {
|
|
47
|
+
phase: "post",
|
|
48
|
+
id: e.tool_use_id,
|
|
49
|
+
tool: e.tool,
|
|
50
|
+
isError: true,
|
|
51
|
+
isInterrupt: e.failure.isInterrupt,
|
|
52
|
+
...(e.failure.durationMs !== undefined ? { durationMs: e.failure.durationMs } : {}),
|
|
53
|
+
out: clip(redactSecrets(e.failure.error), 200),
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
observeClassic(on, "classic.PermissionDenied", (payload) => {
|
|
57
|
+
logger.info("tool_trace", {
|
|
58
|
+
phase: "denied",
|
|
59
|
+
id: payload.toolCallId,
|
|
60
|
+
tool: payload.toolName,
|
|
61
|
+
deniedBy: deniedByLabel(payload.gate),
|
|
62
|
+
...(payload.gate.origin === undefined ? {} : { origin: payload.gate.origin }),
|
|
63
|
+
...(payload.gate.settlement === undefined ? {} : { settlement: payload.gate.settlement.kind }),
|
|
64
|
+
reason: clip(redactSecrets(payload.reason), 200),
|
|
65
|
+
arg: summarize(payload.input),
|
|
66
|
+
});
|
|
58
67
|
});
|
|
59
68
|
},
|
|
60
69
|
};
|
package/dist/per-task-image.d.ts
CHANGED
|
@@ -4,13 +4,19 @@ import type { ImageViewer, ImageIndexEntry } from "./plugins/store-contracts.js"
|
|
|
4
4
|
export interface SandboxImageResolver {
|
|
5
5
|
latestPublished(profile: string, viewer: ImageViewer): Promise<Pick<ImageIndexEntry, "repo" | "digest" | "capabilities"> | null>;
|
|
6
6
|
}
|
|
7
|
+
/**
|
|
8
|
+
* 解析失败的机读码(闭集):`not_found.image` = 按调用方的约束(档案 · 本主体可见 · 已发布 · 所需能力)找不到镜像 —— 与 `POST /v1/images/select`
|
|
9
|
+
* 「没有可见的已发布镜像」同一个码(同一个事实);`request.field_invalid` = `capabilitiesNeeded` 里有不认识的能力词。状态随码,一码一状态。
|
|
10
|
+
*/
|
|
11
|
+
export type SandboxImageRefusalCode = "not_found.image" | "request.field_invalid";
|
|
7
12
|
export type SandboxImageResolution = {
|
|
8
13
|
ok: true;
|
|
9
14
|
ref: string;
|
|
10
15
|
capabilities?: import("./plugins/store-contracts.js").ImageCapabilities;
|
|
11
16
|
} | {
|
|
12
17
|
ok: false;
|
|
13
|
-
status:
|
|
18
|
+
status: 404 | 400;
|
|
19
|
+
errorCode: SandboxImageRefusalCode;
|
|
14
20
|
message: string;
|
|
15
21
|
};
|
|
16
22
|
/**
|
package/dist/per-task-image.js
CHANGED
|
@@ -3,15 +3,15 @@ const REQUESTABLE_CAPS = new Set(["browser", "db", "nestedBuild"]);
|
|
|
3
3
|
export async function resolveSandboxImageRef(opts) {
|
|
4
4
|
const entry = await opts.index.latestPublished(opts.profile, opts.viewer);
|
|
5
5
|
if (!entry) {
|
|
6
|
-
return { ok: false, status: 404, message: `no published sandbox image for profile "${opts.profile}" visible to this principal` };
|
|
6
|
+
return { ok: false, status: 404, errorCode: "not_found.image", message: `no published sandbox image for profile "${opts.profile}" visible to this principal` };
|
|
7
7
|
}
|
|
8
8
|
const caps = entry.capabilities;
|
|
9
9
|
for (const cap of opts.capabilitiesNeeded ?? []) {
|
|
10
10
|
if (!REQUESTABLE_CAPS.has(cap)) {
|
|
11
|
-
return { ok: false, status: 400, message: `unknown sandbox capability "${cap}" (allowed: ${[...REQUESTABLE_CAPS].join(", ")})` };
|
|
11
|
+
return { ok: false, status: 400, errorCode: "request.field_invalid", message: `unknown sandbox capability "${cap}" (allowed: ${[...REQUESTABLE_CAPS].join(", ")})` };
|
|
12
12
|
}
|
|
13
13
|
if (caps[cap] !== true) {
|
|
14
|
-
return { ok: false, status: 404, message: `sandbox image for profile "${opts.profile}" does not provide capability "${cap}"` };
|
|
14
|
+
return { ok: false, status: 404, errorCode: "not_found.image", message: `sandbox image for profile "${opts.profile}" does not provide capability "${cap}"` };
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
17
|
return { ok: true, ref: `${entry.repo}@${entry.digest}`, capabilities: entry.capabilities };
|