@sema-agent/server 7.136.0 → 7.138.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 +501 -139
- package/README.md +1 -0
- package/README.zh-CN.md +1 -0
- package/USAGE.md +149 -34
- package/deploy/sema-up/README.md +14 -0
- package/deploy/sema-up/chart/templates/sandbox-rbac.yaml +7 -1
- package/deploy/sema-up/stack/sema-stack-cluster.yaml +7 -1
- package/dist/approval-card.d.ts +21 -14
- package/dist/approval-card.js +1 -0
- package/dist/approval-content-kind.d.ts +6 -0
- package/dist/approval-content-kind.js +7 -0
- package/dist/approval-gate-currency.d.ts +48 -6
- package/dist/approval-gate-currency.js +16 -9
- package/dist/approval-hmac.d.ts +13 -1
- package/dist/approval-hmac.js +1 -1
- package/dist/approval.js +3 -3
- package/dist/audit.js +1 -0
- package/dist/auth-bridge.js +2 -2
- package/dist/background-agent-name.d.ts +5 -0
- package/dist/background-agent-name.js +5 -0
- package/dist/boot/budget-tracing.d.ts +1 -12
- package/dist/boot/deployment-mods.d.ts +46 -16
- package/dist/boot/deployment-mods.js +82 -6
- package/dist/boot/execution-env.d.ts +24 -1
- package/dist/boot/execution-env.js +69 -6
- package/dist/boot/governance-seams.d.ts +10 -17
- package/dist/boot/governance-seams.js +5 -17
- package/dist/boot/leader.d.ts +3 -0
- package/dist/boot/leader.js +1 -0
- package/dist/boot/org-delivery.js +15 -2
- package/dist/boot/reapers.d.ts +3 -0
- package/dist/boot/reapers.js +15 -1
- package/dist/boot/resolve-spec.d.ts +7 -0
- package/dist/boot/resolve-spec.js +36 -26
- package/dist/boot/retention-lane.d.ts +11 -5
- package/dist/boot/retention-lane.js +2 -2
- package/dist/boot/runner-deps.d.ts +7 -3
- package/dist/boot/runner-deps.js +1 -0
- package/dist/boot/stage-03-store-backend.d.ts +1 -1
- package/dist/boot/stage-04-stores.d.ts +2 -13
- package/dist/boot/stage-05-execution-env.d.ts +6 -13
- package/dist/boot/stage-05-execution-env.js +17 -5
- package/dist/boot/stage-06-runners.d.ts +6 -13
- package/dist/boot/stage-06-runners.js +10 -3
- package/dist/boot/stage-07-capability-layer.d.ts +7 -13
- package/dist/boot/stage-07-capability-layer.js +3 -3
- package/dist/boot/stage-08-reapers.d.ts +7 -13
- package/dist/boot/stage-08-reapers.js +2 -1
- package/dist/boot/stage-09-leader.d.ts +7 -13
- package/dist/boot/stage-09-leader.js +2 -2
- package/dist/boot/stage-10-http-server.d.ts +7 -13
- package/dist/boot/stage-10-http-server.js +6 -3
- package/dist/boot/stores.d.ts +1 -1
- package/dist/boot/web-admin.d.ts +5 -2
- package/dist/boot/web-admin.js +3 -3
- package/dist/brain.js +5 -5
- package/dist/broker/broker.d.ts +89 -0
- package/dist/broker/broker.js +287 -0
- package/dist/broker/constants.d.ts +39 -0
- package/dist/broker/constants.js +15 -0
- package/dist/broker/http1.d.ts +111 -0
- package/dist/broker/http1.js +256 -0
- package/dist/broker/lease-book.d.ts +87 -0
- package/dist/broker/lease-book.js +142 -0
- package/dist/broker/lease-file.d.ts +60 -0
- package/dist/broker/lease-file.js +127 -0
- package/dist/broker/main.d.ts +2 -0
- package/dist/broker/main.js +20 -0
- package/dist/budget.d.ts +17 -15
- package/dist/budget.js +2 -2
- package/dist/capabilities/composite-members.d.ts +2 -1
- package/dist/capabilities/composite-members.js +2 -1
- package/dist/capabilities/engine-capabilities.js +1 -0
- package/dist/capabilities/mcp-probe.d.ts +36 -11
- package/dist/capabilities/mcp-probe.js +44 -5
- package/dist/capabilities/scenarios.d.ts +23 -8
- package/dist/capabilities/scenarios.js +13 -8
- package/dist/capabilities/skills.d.ts +28 -5
- package/dist/capabilities/skills.js +8 -0
- package/dist/capability-facts.d.ts +6 -0
- package/dist/capability-facts.js +5 -0
- package/dist/center-credential-renewer.js +5 -1
- package/dist/checkpoint-ctx-seal-m28.d.ts +3 -10
- package/dist/checkpoint-ctx-seal-m28.js +1 -1
- package/dist/checkpoint-identity.d.ts +13 -6
- package/dist/config-catalog.js +16 -7
- package/dist/config-types.d.ts +24 -7
- package/dist/config.d.ts +1 -1
- package/dist/config.js +42 -13
- package/dist/deployment-governance.d.ts +2 -2
- package/dist/deployment-governance.js +7 -9
- package/dist/deployment-shape.d.ts +6 -6
- package/dist/device-ws-protocol.d.ts +1 -0
- package/dist/device-ws-protocol.js +2 -1
- package/dist/file-history-disclosure.d.ts +4 -2
- package/dist/file-history-disclosure.js +2 -0
- package/dist/gate-settlement.d.ts +71 -0
- package/dist/gate-settlement.js +40 -0
- package/dist/hooks/classic-stations.d.ts +12 -54
- package/dist/hooks/classic-stations.js +1 -0
- package/dist/hooks/command-spawn.d.ts +2 -2
- package/dist/hooks/hook-runner.js +14 -14
- package/dist/http/admission.js +14 -9
- package/dist/http/approval-sweeps.js +4 -3
- package/dist/http/caller-trust.d.ts +2 -1
- package/dist/http/caller-trust.js +1 -3
- package/dist/http/checkpoint-ctx.d.ts +48 -7
- package/dist/http/checkpoint-ctx.js +40 -0
- package/dist/http/dispatch.d.ts +4 -0
- package/dist/http/dispatch.js +18 -10
- package/dist/http/durable-run-leg.d.ts +5 -1
- package/dist/http/durable-run-leg.js +5 -3
- package/dist/http/health-self-report.d.ts +2 -2
- package/dist/http/memory-compliance-failure-reply.js +3 -0
- package/dist/http/principal-gate.d.ts +15 -10
- package/dist/http/principal-gate.js +48 -9
- package/dist/http/resume-legs.d.ts +7 -31
- package/dist/http/resume-legs.js +185 -126
- package/dist/http/route-ctx.d.ts +38 -53
- package/dist/http/route-ctx.js +2 -5
- package/dist/http/routes/a2a-serve.js +10 -4
- package/dist/http/routes/agents-roster.d.ts +1 -1
- package/dist/http/routes/agents-roster.js +5 -1
- package/dist/http/routes/approvals-assistant.js +24 -10
- package/dist/http/routes/capabilities.js +23 -11
- package/dist/http/routes/mcp-reconnect.d.ts +3 -2
- package/dist/http/routes/mcp-reconnect.js +7 -7
- package/dist/http/routes/memory-consolidation.d.ts +1 -1
- package/dist/http/routes/memory-origin.d.ts +1 -1
- package/dist/http/routes/rules.js +3 -3
- package/dist/http/routes/runs.js +13 -8
- package/dist/http/routes/session-sync.js +42 -6
- package/dist/http/routes/sessions.js +6 -3
- package/dist/http/routes/side-query.js +2 -3
- package/dist/http/routes/tasks.js +794 -780
- package/dist/http/server.d.ts +35 -25
- package/dist/http/stored-body-replay.d.ts +3 -3
- package/dist/http/stored-body-replay.js +6 -1
- package/dist/http/wire-types.d.ts +66 -33
- package/dist/identity-source.d.ts +65 -0
- package/dist/identity-source.js +45 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/leader/wire.d.ts +7 -0
- package/dist/leader/wire.js +5 -4
- package/dist/mcp-assertion-header.d.ts +51 -40
- package/dist/mcp-assertion-header.js +10 -11
- package/dist/mcp-authorization-face.d.ts +27 -0
- package/dist/mcp-authorization-face.js +15 -0
- package/dist/memory-operator-faces.d.ts +13 -4
- package/dist/memory-operator-faces.js +1 -17
- package/dist/memory-store-refusal.d.ts +3 -3
- package/dist/memory-sync-client.js +72 -57
- package/dist/memory-sync.d.ts +1 -1
- package/dist/model-entry-refusal.d.ts +2 -0
- package/dist/model-entry-refusal.js +11 -0
- package/dist/model-route-gap.d.ts +6 -22
- package/dist/model-route-gap.js +7 -5
- package/dist/model-select.d.ts +6 -17
- package/dist/model-select.js +0 -3
- package/dist/mods-declaration.d.ts +110 -0
- package/dist/mods-declaration.js +109 -0
- package/dist/namespaced-rule-name.d.ts +1 -1
- package/dist/observability/err-text.d.ts +5 -0
- package/dist/observability/err-text.js +9 -0
- package/dist/observability/fail-open.d.ts +17 -1
- package/dist/observability/fail-open.js +17 -1
- package/dist/observability/metrics.js +1 -1
- package/dist/observability/run-terminal.js +1 -0
- package/dist/observability/secret-env-scrub.d.ts +1 -1
- package/dist/observability/secret-env-scrub.js +1 -1
- package/dist/operator-ask.d.ts +2 -2
- package/dist/org-delivery-gate.js +1 -1
- package/dist/org-memory-admission.d.ts +2 -2
- package/dist/org-memory-admission.js +39 -2
- package/dist/parked-decide.d.ts +15 -2
- package/dist/parked-decide.js +17 -10
- package/dist/peer-directory.js +2 -0
- package/dist/peer-seat.d.ts +150 -0
- package/dist/peer-seat.js +239 -0
- package/dist/permission-rule-list.d.ts +2 -2
- package/dist/permission-rule-vocab.d.ts +7 -7
- package/dist/permission-rule-vocab.js +3 -3
- package/dist/plain-string-record.d.ts +38 -0
- package/dist/plain-string-record.js +38 -0
- package/dist/plugins/background-agent-store-sql.js +6 -3
- package/dist/plugins/caching-session-store.d.ts +5 -0
- package/dist/plugins/caching-session-store.js +6 -0
- package/dist/plugins/checkpoint-store-sql.d.ts +34 -29
- package/dist/plugins/checkpoint-store-sql.js +14 -14
- package/dist/plugins/file-history-store-sql.js +10 -16
- package/dist/plugins/file-run-store.js +8 -2
- package/dist/plugins/k8s-exec-protocol.d.ts +69 -13
- package/dist/plugins/k8s-exec-protocol.js +116 -28
- package/dist/plugins/k8s-pod-delete-failure.d.ts +25 -0
- package/dist/plugins/k8s-pod-delete-failure.js +17 -0
- package/dist/plugins/k8s-pod-reaper.d.ts +106 -0
- package/dist/plugins/k8s-pod-reaper.js +122 -0
- package/dist/plugins/local-checkpoint-store.d.ts +4 -17
- package/dist/plugins/local-checkpoint-store.js +3 -4
- package/dist/plugins/local-session-store.d.ts +66 -27
- package/dist/plugins/local-session-store.js +60 -28
- package/dist/plugins/mailbox-store-sql.d.ts +11 -3
- package/dist/plugins/mailbox-store-sql.js +103 -15
- package/dist/plugins/memory-run-store.js +2 -0
- package/dist/plugins/memory-sync-store-pg.d.ts +16 -5
- package/dist/plugins/memory-sync-store-tidb.d.ts +3 -3
- package/dist/plugins/one-time-migrations.d.ts +34 -12
- package/dist/plugins/one-time-migrations.js +51 -9
- package/dist/plugins/permission-rule-store-file.js +2 -2
- package/dist/plugins/permission-rule-store-sql.d.ts +17 -17
- package/dist/plugins/permission-rule-store-sql.js +37 -30
- package/dist/plugins/pg-pool.js +4 -0
- package/dist/plugins/pg-session-storage.d.ts +10 -2
- package/dist/plugins/pg-session-storage.js +20 -7
- package/dist/plugins/remote-env-adb.d.ts +6 -1
- package/dist/plugins/remote-env-adb.js +2 -1
- package/dist/plugins/remote-env-device.d.ts +6 -1
- package/dist/plugins/remote-env-device.js +5 -1
- package/dist/plugins/remote-env-e2b.d.ts +5 -0
- package/dist/plugins/remote-env-e2b.js +2 -1
- package/dist/plugins/remote-env-file-error.d.ts +8 -1
- package/dist/plugins/remote-env-file-error.js +7 -1
- package/dist/plugins/remote-env-host.d.ts +10 -2
- package/dist/plugins/remote-env-host.js +8 -2
- package/dist/plugins/remote-env-k8s.d.ts +140 -11
- package/dist/plugins/remote-env-k8s.js +277 -15
- package/dist/plugins/remote-env-local-docker.d.ts +5 -0
- package/dist/plugins/remote-env-local-docker.js +2 -1
- package/dist/plugins/remote-env-ssh.d.ts +6 -1
- package/dist/plugins/remote-env-ssh.js +2 -1
- package/dist/plugins/retention-store-sql.d.ts +14 -2
- package/dist/plugins/retention-store-sql.js +6 -0
- package/dist/plugins/run-store-sql.js +10 -4
- package/dist/plugins/session-fork.d.ts +10 -13
- package/dist/plugins/session-fork.js +5 -25
- package/dist/plugins/session-ownership.d.ts +24 -3
- package/dist/plugins/session-ownership.js +24 -5
- package/dist/plugins/session-workspace-cell.d.ts +17 -0
- package/dist/plugins/session-workspace-cell.js +38 -0
- package/dist/plugins/sql-errors.d.ts +23 -2
- package/dist/plugins/sql-errors.js +15 -0
- package/dist/plugins/store-backend.js +7 -7
- package/dist/plugins/store-contracts.d.ts +10 -1
- package/dist/plugins/store-fault.d.ts +2 -2
- package/dist/plugins/store-fault.js +4 -2
- package/dist/plugins/tidb-pool.js +13 -0
- package/dist/plugins/tidb-session-store.d.ts +17 -2
- package/dist/plugins/tidb-session-store.js +18 -7
- package/dist/plugins/tool-result-store-sql.d.ts +13 -6
- package/dist/plugins/tool-result-store-sql.js +8 -7
- package/dist/plugins/worktree-isolation.d.ts +3 -2
- package/dist/plugins/worktree-isolation.js +1 -7
- package/dist/project-identity.d.ts +1 -14
- package/dist/project-identity.js +0 -4
- package/dist/request-key-closure.js +1 -1
- package/dist/request-value-closure.d.ts +31 -2
- package/dist/request-value-closure.js +7 -1
- package/dist/rule-entry-list.d.ts +3 -2
- package/dist/rule-entry-list.js +2 -2
- package/dist/rules-consent.js +12 -7
- package/dist/run-local.d.ts +2 -2
- package/dist/run-local.js +12 -6
- package/dist/runs.d.ts +7 -1
- package/dist/runs.js +8 -2
- package/dist/runtime-governance.d.ts +5 -5
- package/dist/sandbox-git-lease.d.ts +49 -0
- package/dist/sandbox-git-lease.js +60 -0
- package/dist/sandbox-git-plane.d.ts +84 -0
- package/dist/sandbox-git-plane.js +105 -0
- package/dist/security.d.ts +16 -4
- package/dist/security.js +8 -3
- package/dist/server-secret-env.d.ts +12 -3
- package/dist/server-secret-env.js +18 -2
- package/dist/session-error-wire.d.ts +14 -6
- package/dist/session-error-wire.js +2 -1
- package/dist/session-incarnation.d.ts +4 -5
- package/dist/session-incarnation.js +2 -2
- package/dist/session-policy-wire.d.ts +1 -1
- package/dist/session-policy-wire.js +2 -2
- package/dist/session-sync.d.ts +1 -1
- package/dist/session-workspace.d.ts +130 -0
- package/dist/session-workspace.js +83 -0
- package/dist/spec-fields.d.ts +44 -14
- package/dist/spec-fields.js +33 -12
- package/dist/standing-answer-grant.d.ts +2 -13
- package/dist/standing-answer-grant.js +0 -7
- package/dist/stored-request-prompt-profile-m30.d.ts +49 -0
- package/dist/stored-request-prompt-profile-m30.js +25 -0
- package/dist/task-a2a.d.ts +44 -14
- package/dist/task-a2a.js +46 -20
- package/dist/task-mcp.d.ts +34 -21
- package/dist/task-mcp.js +46 -22
- package/dist/task-settings.d.ts +2 -2
- package/dist/tool-approval.d.ts +43 -9
- package/dist/tool-approval.js +57 -15
- package/dist/tool-rule-names.d.ts +5 -0
- package/dist/trace/core-keyset-guard.d.ts +34 -19
- package/dist/trace/engine-notice-wire.d.ts +1 -1
- package/dist/trace/engine-notice-wire.js +4 -0
- package/dist/trace/exit-seat.d.ts +20 -1
- package/dist/trace/exit-seat.js +5 -2
- package/dist/trace/extension-call-face.d.ts +33 -0
- package/dist/trace/extension-call-face.js +39 -0
- package/dist/trace/ledger-sink.d.ts +4 -5
- package/dist/trace/ledger-sink.js +3 -7
- package/dist/trace/project.d.ts +62 -10
- package/dist/trace/project.js +49 -9
- package/dist/trace/redact.d.ts +18 -6
- package/dist/trace/redact.js +154 -60
- package/dist/trace/self-minted-wire.d.ts +500 -7
- package/dist/trace/self-minted-wire.js +182 -1
- package/dist/trace/wire-projection-faces.d.ts +7 -5
- package/dist/trace/wire-projection-faces.js +9 -4
- package/dist/user-authored-text.d.ts +2 -2
- package/dist/user-authored-text.js +16 -1
- package/dist/web-admin-client/apply-effective.js +0 -1
- package/dist/web-admin-client/center-request.d.ts +23 -4
- package/dist/web-admin-client/center-request.js +42 -8
- package/dist/web-admin-client/http-client.js +6 -6
- package/dist/web-admin-client/skills-mcp.d.ts +8 -4
- package/dist/web-admin-client/skills-mcp.js +31 -18
- package/dist/web-admin-client/types.d.ts +10 -5
- package/docs/DEVICE-EXECUTOR-PROTOCOL.md +11 -5
- package/package.json +3 -3
- package/wire-changes/server@7.137.0.json +825 -0
- package/wire-changes/server@7.138.0.json +446 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { recordFailOpen } from "./observability/fail-open.js";
|
|
2
|
+
import { readSessionWorkspaceCell, SESSION_WORKSPACE_DEGRADED } from "./plugins/session-workspace-cell.js";
|
|
3
|
+
import { projectByTable } from "./trace/projection-table.js";
|
|
4
|
+
export const SESSION_WORKSPACE_DISPOSITIONS = {
|
|
5
|
+
type: "strip",
|
|
6
|
+
cwd: "forward",
|
|
7
|
+
root: "forward",
|
|
8
|
+
entered: { nested: { dir: "forward", byPath: "forward" } },
|
|
9
|
+
project: { nested: { id: "forward", source: "forward" } },
|
|
10
|
+
remote: "forward",
|
|
11
|
+
eventId: "strip",
|
|
12
|
+
parentToolCallId: "strip",
|
|
13
|
+
sourceTaskId: "strip",
|
|
14
|
+
bgAgentId: "strip",
|
|
15
|
+
};
|
|
16
|
+
export function sessionWorkspaceStoreOf(store) {
|
|
17
|
+
const s = store;
|
|
18
|
+
if (typeof s?.readSessionWorkspace !== "function" || typeof s.recordSessionWorkspace !== "function")
|
|
19
|
+
return undefined;
|
|
20
|
+
return { readSessionWorkspace: s.readSessionWorkspace.bind(s), recordSessionWorkspace: s.recordSessionWorkspace.bind(s) };
|
|
21
|
+
}
|
|
22
|
+
export const LEG_SESSION_WITNESS_FIELD = Symbol("sema-server.legSessionWitness");
|
|
23
|
+
export function stampLegSessionWitness(spec, witness) {
|
|
24
|
+
if (witness !== undefined)
|
|
25
|
+
Object.defineProperty(spec, LEG_SESSION_WITNESS_FIELD, { value: Object.freeze({ ...witness }), enumerable: true, writable: false, configurable: false });
|
|
26
|
+
return spec;
|
|
27
|
+
}
|
|
28
|
+
export function legSessionWitnessOf(spec) {
|
|
29
|
+
return spec[LEG_SESSION_WITNESS_FIELD];
|
|
30
|
+
}
|
|
31
|
+
export function sessionWorkspaceOfFrame(ev) {
|
|
32
|
+
if (ev.type !== "workspace_changed")
|
|
33
|
+
return undefined;
|
|
34
|
+
if (ev.parentToolCallId !== undefined || ev.sourceTaskId !== undefined || ev.bgAgentId !== undefined)
|
|
35
|
+
return undefined;
|
|
36
|
+
const shape = readSessionWorkspaceCell(projectByTable("session_workspace", SESSION_WORKSPACE_DISPOSITIONS, ev, ev));
|
|
37
|
+
if (shape.problem !== undefined) {
|
|
38
|
+
recordFailOpen(SESSION_WORKSPACE_DEGRADED, `op=frame problem=${shape.problem.slice(0, 200)}`);
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
return shape.value;
|
|
42
|
+
}
|
|
43
|
+
const SETTLED = Promise.resolve();
|
|
44
|
+
const NO_RECORD = { observe: () => SETTLED };
|
|
45
|
+
export function createSessionWorkspaceRecorder(store, witness) {
|
|
46
|
+
if (store === undefined || witness === undefined || witness.incarnation === null)
|
|
47
|
+
return NO_RECORD;
|
|
48
|
+
const { sessionId, incarnation } = witness;
|
|
49
|
+
return {
|
|
50
|
+
async observe(ev) {
|
|
51
|
+
const snapshot = sessionWorkspaceOfFrame(ev);
|
|
52
|
+
if (snapshot === undefined)
|
|
53
|
+
return;
|
|
54
|
+
try {
|
|
55
|
+
await store.recordSessionWorkspace(sessionId, incarnation, snapshot);
|
|
56
|
+
}
|
|
57
|
+
catch (e) {
|
|
58
|
+
recordFailOpen(SESSION_WORKSPACE_DEGRADED, `op=write session=${sessionId} ${(e instanceof Error ? e.message : String(e)).slice(0, 200)}`);
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
export async function legProjectIdOf(submitted, store, sessionId) {
|
|
64
|
+
if (submitted !== undefined)
|
|
65
|
+
return submitted;
|
|
66
|
+
if (store === undefined || sessionId === undefined)
|
|
67
|
+
return undefined;
|
|
68
|
+
const project = (await store.readSessionWorkspace(sessionId))?.project;
|
|
69
|
+
return project === undefined ? undefined : replayedProjectIdOf(project);
|
|
70
|
+
}
|
|
71
|
+
function replayedProjectIdOf(project) {
|
|
72
|
+
switch (project.source) {
|
|
73
|
+
case "declared":
|
|
74
|
+
return project.id;
|
|
75
|
+
case "marker":
|
|
76
|
+
return undefined;
|
|
77
|
+
default: {
|
|
78
|
+
const unknownSource = project.source;
|
|
79
|
+
throw new Error(`session workspace: unknown project source word ${JSON.stringify(unknownSource)} (the row reader admits only marker / declared)`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=session-workspace.js.map
|
package/dist/spec-fields.d.ts
CHANGED
|
@@ -21,6 +21,32 @@ export declare function normalizeSuggestNextPrompts(v: unknown): TaskSpec["sugge
|
|
|
21
21
|
* undefined (never an empty object — keeps the spec byte-identical for non-users).
|
|
22
22
|
*/
|
|
23
23
|
export declare function normalizeResilience(v: unknown, operator: boolean): TaskSpec["resilience"];
|
|
24
|
+
/**
|
|
25
|
+
* 请求体 `attachments` 的子键**只有这一张表**(键 → 受理类别)。三处读它,不再各抄一份键名:
|
|
26
|
+
* · 导出类型 `TaskRequestAttachments`(`http/wire-types.ts`)—— 与本表互为差集门(下面两只 `_GuardAttachmentKeys*`:类型加 / 删一个键而本表没跟 ⇒ tsc 红);
|
|
27
|
+
* · 受理门(`http/admission.ts`)—— 非对象那一句列的键、布尔类键的逐键 `must be a boolean` 检查都从这里取;
|
|
28
|
+
* · 重放翻译口 {@link normalizeAttachments} —— 入参形与逐键赋值的键集都是本表(`parts` 记录对 {@link AttachmentKey} 穷举,少一个键 ⇒ tsc 红)。
|
|
29
|
+
* 类别只回答受理门一个问题:`boolean` = 值必须是布尔(literal-true 键与布尔透传键的差别在翻译口,不在门);`mode` = `todoReminderMode` 的枚举;
|
|
30
|
+
* `changedFiles` = 布尔或 `{ maxFiles }`。后两类各有自己的门。键的**顺序**就是受理门那一句里的顺序(句子字面另由错误文案冻结钉守)。
|
|
31
|
+
*/
|
|
32
|
+
export type AttachmentKeyKind = "boolean" | "mode" | "changedFiles";
|
|
33
|
+
export declare const ATTACHMENT_KEY_KINDS: {
|
|
34
|
+
readonly todoReminder: "boolean";
|
|
35
|
+
readonly todoReminderMode: "mode";
|
|
36
|
+
readonly changedFiles: "changedFiles";
|
|
37
|
+
readonly budgetUsd: "boolean";
|
|
38
|
+
readonly backgroundTasks: "boolean";
|
|
39
|
+
readonly toolsDelta: "boolean";
|
|
40
|
+
readonly agentListing: "boolean";
|
|
41
|
+
readonly skillsListing: "boolean";
|
|
42
|
+
readonly mcpInstructions: "boolean";
|
|
43
|
+
readonly mcpUnavailable: "boolean";
|
|
44
|
+
};
|
|
45
|
+
export type AttachmentKey = keyof typeof ATTACHMENT_KEY_KINDS;
|
|
46
|
+
/** 表的键,原序。 */
|
|
47
|
+
export declare const ATTACHMENT_KEYS: readonly AttachmentKey[];
|
|
48
|
+
/** 受理门要验「值必须是布尔」的键(= 类别 `boolean`),原序。 */
|
|
49
|
+
export declare const ATTACHMENT_BOOLEAN_KEYS: readonly AttachmentKey[];
|
|
24
50
|
/**
|
|
25
51
|
* [ref] (core 1.251) — normalize `body.attachments` → `TaskSpec.attachments`. Core's contract is
|
|
26
52
|
* literal-true unions ("关闭=删 key,勿传 false"): only `true` (or, for changedFiles, an object with a sane
|
|
@@ -82,7 +108,7 @@ export interface TaskAgentsRefusal {
|
|
|
82
108
|
* 定义被悄悄削(一个丢掉的 isolation 就是放宽),比 400 更危险,故整条拒。`allowTools` / `denyTools` 本门只判形与条数(`toolList`),
|
|
83
109
|
* **名字归引擎一只判**(core 7.49.0 [ref] / [ref] 第二步起与根 run 的 `allowTools` / `excludeTools` 是同一只选择器,开跑前,三来源同判):core 7.51.0 [ref] 起
|
|
84
110
|
* 没有任何工具答应的名字(无人挂的名、大小写孪生 / 退役名 `bash` / `BASH`)**引擎不拒 run** —— 条目原样保留、经 onError(config)告知一次(带该写的拼法);
|
|
85
|
-
* 其中**写错现名的**(`denyTools:["BASH"]` 想禁的照用 = 静默放行;`allowTools:["BASH"]` 想放的什么也没放 = 静默收窄)由 `resolveSpec` 前置拒:**限制侧**(`denyTools`)
|
|
111
|
+
* 其中**写错现名的**(`denyTools:["BASH"]` 想禁的照用 = 静默放行;`allowTools:["BASH"]` 想放的什么也没放 = 静默收窄)由 `resolveSpec` 前置拒:**限制侧**(`denyTools`)三类全拒(近似名 · 退役名 · 文法读不出);名内的 `*` 自 7.137.0 起是整名 glob、受理(孤 `*` = 每一只工具),`Tool(content)` 引擎读成整只工具、同样受理,
|
|
86
112
|
* **放行侧**(`allowTools`)只拒近似名 —— 放行侧的内容形 / 没有后继的退役名 / 文法读不出照 7.130.0 受理、交引擎既有通告(有后继的退役名〔`bash` · `Task`〕与文法读不出的放行条目引擎在子代 prepare 整 run 拒 `config.agent.unknown_tool`,根 `allowTools` 拒 `config.tool_face_control`,同步腿两码同为 400〔`runs.ts` `PREPARE_REFUSAL_HTTP_STATUS`〕;`rule-entry-list.ts` `inertToolListEntryOf`:近似名提交 400 `config.agent.unknown_tool` 点名现名、续跑按方向分流;
|
|
87
113
|
* 判官仍是引擎的条目读法,不是第二个判官);
|
|
88
114
|
* **真未知名**(没有近似也没有退役对应:懒挂载的合法形)照旧只告运维、不拒。
|
|
@@ -163,21 +189,25 @@ export declare function toolNameListFromBody(raw: unknown): string[] | undefined
|
|
|
163
189
|
export declare function allowToolsSpecFragment(raw: unknown): {
|
|
164
190
|
allowTools?: string[];
|
|
165
191
|
};
|
|
166
|
-
/** [ref]
|
|
167
|
-
*
|
|
168
|
-
* ⇒ 无租户门(deferTools 同姿势);全委托树继承由 core 管。缺省不挂键(引擎缺省 simple,byte-compat)。
|
|
192
|
+
/** core 7.56.0 [ref] — body.promptLean → `TaskSpec.promptLean`(提示词形的唯一任务开关:`true` 加 `lean_prompt` 特征、`false` 去掉它、
|
|
193
|
+
* 缺省 = 模型声明)。纯呈现轴不碰策略 ⇒ 无租户门(deferTools 同姿势);全委托树继承由 core 管。缺省不挂键(模型目录条目的声明说话)。
|
|
169
194
|
*
|
|
170
|
-
* ⚠️ **这不是一条 defer
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
-
|
|
195
|
+
* ⚠️ **这不是一条 defer 注**:本段说的是提示词形这根**呈现**轴,它与 `deferMode` / `deferTools` 的延迟披露轴**无耦合** —— 上一行提
|
|
196
|
+
* deferTools 只是在借它的「无租户门」姿势作类比。真正的 defer 轴对表记在 `src/capabilities/tool-defer.ts` 的头注 —— 别把两根轴的结论写到一处。
|
|
197
|
+
* DEFENSIVE(resume 重放不过 HTTP 400 门):非布尔 ⇒ undefined;提交面另有 fail-loud 400(邻居姿势)。 */
|
|
198
|
+
export declare function promptLeanFromBody(raw: unknown): boolean | undefined;
|
|
199
|
+
/**
|
|
200
|
+
* `TaskSpec.promptLean` 的座位片段:体里的 `promptLean`(布尔才算,见 {@link promptLeanFromBody})是唯一读数;缺席 ⇒ 不挂键。两条腿同一读法:
|
|
201
|
+
* 退役键 `promptProfile` 不读 —— 新提交带它在键闭集门 400;7.136.x 存体里的它由一次性迁移 M30 在起服时改写成 `promptLean`(`stored-request-prompt-profile-m30.ts`),
|
|
202
|
+
* 改写不到的残留行在续跑判据上拒(`http/stored-body-replay.ts` 第四问),到不了这里。
|
|
203
|
+
*/
|
|
204
|
+
export declare function promptLeanSpecFragment(body: {
|
|
205
|
+
readonly promptLean?: unknown;
|
|
206
|
+
}): {
|
|
207
|
+
promptLean?: boolean;
|
|
208
|
+
};
|
|
179
209
|
/** [ref]②(core 5.14.0 `TaskSpec.toolMaterializeStrategy`):deferred 工具激活后的 schema 供给策略。
|
|
180
|
-
* 与 {@link
|
|
210
|
+
* 与 {@link promptLeanFromBody} 同姿势的**防御性归一**——提交面的 fail-loud 400 在 HTTP 门,这里
|
|
181
211
|
* 只负责 resume 重放存量 body 时把不认识的值静默 DROP(回落 core 的 env/缺省链),而不是把它带上 spec。 */
|
|
182
212
|
export declare function toolMaterializeStrategyFromBody(raw: unknown): "static" | "swap" | undefined;
|
|
183
213
|
/** [ref]④ — 每键的运营方上限旋钮(env,缺省不设=不封顶)。 */
|
package/dist/spec-fields.js
CHANGED
|
@@ -25,6 +25,20 @@ export function normalizeResilience(v, operator) {
|
|
|
25
25
|
};
|
|
26
26
|
return Object.keys(out).length > 0 ? out : undefined;
|
|
27
27
|
}
|
|
28
|
+
export const ATTACHMENT_KEY_KINDS = {
|
|
29
|
+
todoReminder: "boolean",
|
|
30
|
+
todoReminderMode: "mode",
|
|
31
|
+
changedFiles: "changedFiles",
|
|
32
|
+
budgetUsd: "boolean",
|
|
33
|
+
backgroundTasks: "boolean",
|
|
34
|
+
toolsDelta: "boolean",
|
|
35
|
+
agentListing: "boolean",
|
|
36
|
+
skillsListing: "boolean",
|
|
37
|
+
mcpInstructions: "boolean",
|
|
38
|
+
mcpUnavailable: "boolean",
|
|
39
|
+
};
|
|
40
|
+
export const ATTACHMENT_KEYS = Object.keys(ATTACHMENT_KEY_KINDS);
|
|
41
|
+
export const ATTACHMENT_BOOLEAN_KEYS = ATTACHMENT_KEYS.filter((k) => ATTACHMENT_KEY_KINDS[k] === "boolean");
|
|
28
42
|
export function normalizeAttachments(v) {
|
|
29
43
|
if (v == null || typeof v !== "object" || Array.isArray(v))
|
|
30
44
|
return undefined;
|
|
@@ -37,17 +51,19 @@ export function normalizeAttachments(v) {
|
|
|
37
51
|
changedFiles =
|
|
38
52
|
typeof mf === "number" && Number.isFinite(mf) && mf >= 1 ? { maxFiles: Math.min(100, Math.floor(mf)) } : true;
|
|
39
53
|
}
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
54
|
+
const parts = {
|
|
55
|
+
todoReminder: o.todoReminder === true ? { todoReminder: true } : {},
|
|
56
|
+
todoReminderMode: o.todoReminderMode === "baseline" || o.todoReminderMode === "off" ? { todoReminderMode: o.todoReminderMode } : {},
|
|
57
|
+
changedFiles: changedFiles !== undefined ? { changedFiles } : {},
|
|
58
|
+
budgetUsd: o.budgetUsd === true ? { budgetUsd: true } : {},
|
|
59
|
+
backgroundTasks: typeof o.backgroundTasks === "boolean" ? { backgroundTasks: o.backgroundTasks } : {},
|
|
60
|
+
toolsDelta: o.toolsDelta === true ? { toolsDelta: true } : {},
|
|
61
|
+
agentListing: typeof o.agentListing === "boolean" ? { agentListing: o.agentListing } : {},
|
|
62
|
+
skillsListing: typeof o.skillsListing === "boolean" ? { skillsListing: o.skillsListing } : {},
|
|
63
|
+
mcpInstructions: o.mcpInstructions === true ? { mcpInstructions: true } : {},
|
|
64
|
+
mcpUnavailable: typeof o.mcpUnavailable === "boolean" ? { mcpUnavailable: o.mcpUnavailable } : {},
|
|
50
65
|
};
|
|
66
|
+
const out = Object.assign({}, ...ATTACHMENT_KEYS.map((k) => parts[k]));
|
|
51
67
|
return Object.keys(out).length > 0 ? out : undefined;
|
|
52
68
|
}
|
|
53
69
|
export function normalizeResumeAtMode(v, resumeAtResolved) {
|
|
@@ -90,6 +106,7 @@ const SKILL_FIELD_SHAPES = {
|
|
|
90
106
|
disallowedTools: { required: false, ok: skillToolListOk },
|
|
91
107
|
files: { required: false, ok: skillFilesOk },
|
|
92
108
|
baseDir: { required: false, ok: isAbsoluteHostPath },
|
|
109
|
+
mods: { required: false, ok: () => false },
|
|
93
110
|
};
|
|
94
111
|
const skillOk = (s) => {
|
|
95
112
|
if (!plainObject(s))
|
|
@@ -301,8 +318,12 @@ export function toolNameListFromBody(raw) {
|
|
|
301
318
|
export function allowToolsSpecFragment(raw) {
|
|
302
319
|
return raw === undefined ? {} : { allowTools: raw };
|
|
303
320
|
}
|
|
304
|
-
export function
|
|
305
|
-
return
|
|
321
|
+
export function promptLeanFromBody(raw) {
|
|
322
|
+
return typeof raw === "boolean" ? raw : undefined;
|
|
323
|
+
}
|
|
324
|
+
export function promptLeanSpecFragment(body) {
|
|
325
|
+
const lean = promptLeanFromBody(body.promptLean);
|
|
326
|
+
return lean !== undefined ? { promptLean: lean } : {};
|
|
306
327
|
}
|
|
307
328
|
export function toolMaterializeStrategyFromBody(raw) {
|
|
308
329
|
return raw === "static" || raw === "swap" ? raw : undefined;
|
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/** 载体:引擎给一次调用盖过绑定词的任何形(活的 `AskRequest`、停驻行的 `tool_approval` 臂、运维队列行、策略层的 `ToolCallRequest` 都结构上满足)。 */
|
|
2
2
|
export interface StandingAnswerCard {
|
|
3
3
|
readonly boundGrantDigest?: unknown;
|
|
4
4
|
readonly boundGrantAbsence?: unknown;
|
|
5
5
|
}
|
|
6
|
-
/** 调用载体:策略层的 `ToolCallRequest`、豁免店的行(只有工具名)。 */
|
|
7
|
-
export interface StandingAnswerCall {
|
|
8
|
-
readonly toolName?: unknown;
|
|
9
|
-
}
|
|
10
6
|
/** 一问的授予绑定(闭集):`none` = 应答只覆盖这一次调用;`bound` = 授予、绑定可读;`unreadable` = 授予或说不清、绑定读不出。 */
|
|
11
7
|
export type GrantBinding = {
|
|
12
8
|
readonly kind: "none";
|
|
@@ -16,13 +12,6 @@ export type GrantBinding = {
|
|
|
16
12
|
} | {
|
|
17
13
|
readonly kind: "unreadable";
|
|
18
14
|
};
|
|
19
|
-
/**
|
|
15
|
+
/** 载体上的授予绑定 —— 只读引擎的词(读法见文件头注):摘要是串 ⇒ bound;摘要不在且词是 `not_bindable` ⇒ none;其余 ⇒ unreadable。 */
|
|
20
16
|
export declare function grantBindingOf(card: StandingAnswerCard): GrantBinding;
|
|
21
|
-
/** 调用上的授予绑定 —— 调用上没有引擎的词,读引擎绑定工厂的那一条规则(见文件头注;🚧 引擎在调用上盖词之后退役)。 */
|
|
22
|
-
export declare function callGrantBindingOf(call: StandingAnswerCall): GrantBinding;
|
|
23
|
-
/**
|
|
24
|
-
* 一问的授予绑定的**唯一折点**:读哪个载体由**问的属主**定 —— 名单自己的问(`deploymentListQuestion`,即 `standingAnswerHome` 的 `server_store` 家)读调用口,
|
|
25
|
-
* 引擎铸的问读卡口(载体与理由见文件头注)。所有把「一张卡」折成 {@link StandingAnswerFacts} 的读者(活的问、待决条目、停驻行、运维队列行)经它取绑定,不各自选口。
|
|
26
|
-
*/
|
|
27
|
-
export declare function questionGrantBindingOf(carrier: StandingAnswerCard & StandingAnswerCall, deploymentListQuestion: boolean): GrantBinding;
|
|
28
17
|
//# sourceMappingURL=standing-answer-grant.d.ts.map
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { SKILL_TOOL_NAME } from "@sema-agent/core";
|
|
2
1
|
const NOT_BINDABLE = "not_bindable";
|
|
3
2
|
export function grantBindingOf(card) {
|
|
4
3
|
const digest = card.boundGrantDigest;
|
|
@@ -6,10 +5,4 @@ export function grantBindingOf(card) {
|
|
|
6
5
|
return { kind: "bound", digest };
|
|
7
6
|
return digest === undefined && card.boundGrantAbsence === NOT_BINDABLE ? { kind: "none" } : { kind: "unreadable" };
|
|
8
7
|
}
|
|
9
|
-
export function callGrantBindingOf(call) {
|
|
10
|
-
return call.toolName === SKILL_TOOL_NAME ? { kind: "unreadable" } : { kind: "none" };
|
|
11
|
-
}
|
|
12
|
-
export function questionGrantBindingOf(carrier, deploymentListQuestion) {
|
|
13
|
-
return deploymentListQuestion ? callGrantBindingOf(carrier) : grantBindingOf(carrier);
|
|
14
|
-
}
|
|
15
8
|
//# sourceMappingURL=standing-answer-grant.js.map
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 一次性迁移 M30 —— 升级之前停驻的行(`checkpoint_ctx`)里请求体的退役键 `promptProfile`,起服**原地改写**成 `promptLean`。
|
|
3
|
+
* 🔴 M30 · 窗口见 `plugins/one-time-migrations.ts` 的 ONE_TIME_MIGRATIONS 登记表(窗、删法、删后由谁接住只写在那一行)。
|
|
4
|
+
*
|
|
5
|
+
* ## 为什么要它(持久数据面)
|
|
6
|
+
* 引擎 7.56.0 把提示词形收成一个布尔(`TaskSpec.promptLean`),双形词 `promptProfile`(`"simple" | "classic"`)整键退役;新提交带它在键闭集门 400。
|
|
7
|
+
* 7.136.x 及以前停驻的任务,`checkpoint_ctx` 存着的请求体带的是旧键 —— 续跑腿重放它,没有读者 ⇒ `"classic"`(要长形)静默回到模型声明的短形。
|
|
8
|
+
* 持久数据面 = 一次性迁移把旧表示消灭(不是续跑时按日历再读一遍:那样存体从不改,窗内续跑过一次、再停驻、窗关后再续跑,意图照样静默丢)。
|
|
9
|
+
*
|
|
10
|
+
* ## 法(一条映射,与 MIGRATION 写给调用方的同一张)
|
|
11
|
+
* 窗内每次起服扫一遍 `checkpoint_ctx`(两孪生共有的 ctx 行改写店腿 `rewriteCtxRows`,与 M28 同一只;SQL 按原文 CAS、`updated_at_ms` 不动;local 信封的 `updatedAt` 不动),
|
|
12
|
+
* 体里带自有键 `promptProfile` 的行:删掉它;`"classic"` 且体里没有布尔 `promptLean` ⇒ 写 `promptLean: false`(长形的意图);`"simple"`(当年的缺省形)/ 词表外的值 ⇒
|
|
13
|
+
* 只删键;体里已有布尔 `promptLean`(它说了算)⇒ 只删键。体的其余键、行上的读法记号与凭据位原样随行(行改写 = `http/checkpoint-ctx.ts` `rewriteStoredBodyKeys`)。
|
|
14
|
+
* 已改写 / 不带旧键的行零写;读不出的行计数、不动(留给读口的响亮臂)。读数一行 info `checkpoint_ctx_prompt_profile_rewritten`(行数,不带值),不进
|
|
15
|
+
* `OneTimeMigrationReport`(登记行 `reportKeys` 空,与 M28 同形)。窗外不扫。
|
|
16
|
+
*
|
|
17
|
+
* ## 改写不到的行(响亮拒,不是第二种读法)
|
|
18
|
+
* 续跑腿不读旧键(`resolveSpec` 只读布尔 `promptLean`)。存体里仍带 `promptProfile` 的行 —— 窗内从没起过本版的部署,或滚动升级里旧副本在本版起服扫描之后才写下的行 ——
|
|
19
|
+
* 在五个续跑问点的同一只判据上拒(`http/stored-body-replay.ts` 第四问,409 `checkpoint.unsupported_version`);窗内再起一次本版即改写它。
|
|
20
|
+
*
|
|
21
|
+
* ## 为什么不在 `one-time-migrations.ts` 的迁移段里
|
|
22
|
+
* 那一段跑在店层(起服第 3 段),checkpoint 店还没建;本条与 M28 同在起服第 6 段 checkpoint 店建成之后、任何路由装配之前调一次。
|
|
23
|
+
*/
|
|
24
|
+
import { type SealedCheckpointCtx } from "./http/checkpoint-ctx.js";
|
|
25
|
+
import { type OneTimeMigrationWindow } from "./plugins/one-time-migrations.js";
|
|
26
|
+
import type { CheckpointCtxRowsRewriter } from "./plugins/checkpoint-store-sql.js";
|
|
27
|
+
/** M30 一次起服的读数(起服 info 行逐键打出;测试按它断言)。`window: "closed"` ⇒ 一行都没读(其余全 0)。`rowsLongFormKept` = 改写成 `promptLean: false` 的行。 */
|
|
28
|
+
export interface PromptProfileRetireM30Report {
|
|
29
|
+
readonly window: "open" | "closed";
|
|
30
|
+
readonly rowsScanned: number;
|
|
31
|
+
readonly rowsRewritten: number;
|
|
32
|
+
readonly rowsLongFormKept: number;
|
|
33
|
+
readonly rowsUnreadable: number;
|
|
34
|
+
readonly rowsTooLarge: number;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* 一行存量 ctx 的 M30 改写(纯函数;店腿逐行调):体里没有自有键 `promptProfile`(或体不是对象)⇒ `undefined`(不写);否则交回改写后的落盘形与改动数
|
|
38
|
+
* (写了 `promptLean: false` 记 1,只删键记 0)。导出给两孪生的真库钉(`checkpoint-ctx-credential-seal-db-integration.test.ts`)直接喂店腿。
|
|
39
|
+
*/
|
|
40
|
+
export declare function retirePromptProfileRowM30(stored: object): {
|
|
41
|
+
readonly ctx: SealedCheckpointCtx;
|
|
42
|
+
readonly values: number;
|
|
43
|
+
} | undefined;
|
|
44
|
+
/** 跑一次 M30(`today` = UTC 日历日 YYYY-MM-DD;`window` 缺省 = 登记表 M30 那一行 —— 只有测试递别的窗)。窗关 ⇒ 不扫。 */
|
|
45
|
+
export declare function retirePromptProfileM30(store: CheckpointCtxRowsRewriter, opts: {
|
|
46
|
+
readonly today: string;
|
|
47
|
+
readonly window?: Pick<OneTimeMigrationWindow, "removableAfter">;
|
|
48
|
+
}): Promise<PromptProfileRetireM30Report>;
|
|
49
|
+
//# sourceMappingURL=stored-request-prompt-profile-m30.d.ts.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { rewriteStoredBodyKeys } from "./http/checkpoint-ctx.js";
|
|
2
|
+
import { ONE_TIME_MIGRATIONS, migrationWindowOpen } from "./plugins/one-time-migrations.js";
|
|
3
|
+
const RETIRED_KEY = "promptProfile";
|
|
4
|
+
export function retirePromptProfileRowM30(stored) {
|
|
5
|
+
const body = stored.body;
|
|
6
|
+
if (body === null || typeof body !== "object" || Array.isArray(body) || !Object.hasOwn(body, RETIRED_KEY))
|
|
7
|
+
return undefined;
|
|
8
|
+
const fields = body;
|
|
9
|
+
const keepsLongForm = fields[RETIRED_KEY] === "classic" && typeof fields["promptLean"] !== "boolean";
|
|
10
|
+
return { ctx: rewriteStoredBodyKeys(stored, { drop: [RETIRED_KEY], ...(keepsLongForm ? { set: { promptLean: false } } : {}) }), values: keepsLongForm ? 1 : 0 };
|
|
11
|
+
}
|
|
12
|
+
function m30Window() {
|
|
13
|
+
const row = ONE_TIME_MIGRATIONS.find((w) => w.id === "M30");
|
|
14
|
+
if (row === undefined)
|
|
15
|
+
throw new Error("stored-request-prompt-profile-m30: the one-time migration registry has no M30 row — this migration outlived its registry row; delete it with that row");
|
|
16
|
+
return row;
|
|
17
|
+
}
|
|
18
|
+
export async function retirePromptProfileM30(store, opts) {
|
|
19
|
+
if (!migrationWindowOpen(opts.window ?? m30Window(), opts.today)) {
|
|
20
|
+
return { window: "closed", rowsScanned: 0, rowsRewritten: 0, rowsLongFormKept: 0, rowsUnreadable: 0, rowsTooLarge: 0 };
|
|
21
|
+
}
|
|
22
|
+
const r = await store.rewriteCtxRows((_sessionId, ctx) => retirePromptProfileRowM30(ctx));
|
|
23
|
+
return { window: "open", rowsScanned: r.scanned, rowsRewritten: r.rewritten, rowsLongFormKept: r.valuesRewritten, rowsUnreadable: r.unreadable, rowsTooLarge: r.tooLarge };
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=stored-request-prompt-profile-m30.js.map
|
package/dist/task-a2a.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type A2aServerSpec, type CompliancePosture, type LockedKey } from "@sema-agent/core";
|
|
2
|
+
import { type A2aDraft, type PeerDesk, type PeerLease } from "./peer-seat.js";
|
|
2
3
|
import { type DeclarationRefusal } from "./request-declaration-refusal.js";
|
|
3
4
|
import type { StoredToolAxesRereadM19 } from "./stored-request-tool-axes-m19.js";
|
|
4
5
|
import { type PrincipalAxisInput } from "./deployment-shape.js";
|
|
@@ -21,18 +22,42 @@ export interface A2aInjectionDrop {
|
|
|
21
22
|
readonly reason: string;
|
|
22
23
|
readonly field: string;
|
|
23
24
|
}
|
|
24
|
-
/** The deployment-facing shape this module reads: the principal axis
|
|
25
|
-
export type A2aGateConfig = PrincipalAxisInput
|
|
25
|
+
/** The deployment-facing shape this module reads: the principal axis, the operator locks and the compliance posture. */
|
|
26
|
+
export type A2aGateConfig = PrincipalAxisInput & {
|
|
27
|
+
readonly lockedConfigKeys?: readonly LockedKey[];
|
|
28
|
+
readonly compliancePosture?: CompliancePosture;
|
|
29
|
+
};
|
|
26
30
|
/**
|
|
27
|
-
* Does THIS deployment honor caller-supplied per-request A2A peers?
|
|
28
|
-
*
|
|
31
|
+
* Does THIS deployment honor caller-supplied per-request A2A peers? The same three vetoes as `task-mcp.ts mcpInjectionHonored`, each with its own
|
|
32
|
+
* engine word: multi-tenant (deployment-shape row `multiTenant`: a tenant cannot point the shared worker at an agent), the operator lock `a2a`, and a
|
|
33
|
+
* compliance posture that denies `a2a_peers` (the engine refuses a task that declares a peer under either at prepare — advertising the bit would be
|
|
34
|
+
* "says yes, every use refused"). The capability bit and the request leg both read this predicate, so there is exactly one place where the answer can be wrong.
|
|
35
|
+
* A posture that cannot be resolved throws here (validated twice before this site; loud beats a quiet boolean, same as the MCP gate).
|
|
29
36
|
*/
|
|
30
37
|
export declare function a2aInjectionHonored(config: A2aGateConfig): boolean;
|
|
31
38
|
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
39
|
+
* 请求面一条 `a2aPeers[]` 对端在 wire 上的形(= `TaskRequestBody.a2aPeers` 的元素型):引擎的 `A2aServerSpec` 去掉凭据引用位、加上 `headers`(件)。
|
|
40
|
+
* 交给引擎之前一律经 {@link toA2aDraft} 拆成草稿 —— 引擎的声明收据对带 `headers` 的声明整条拒,件由部署的对端座在每次发送时作答。
|
|
34
41
|
*/
|
|
35
|
-
export
|
|
42
|
+
export type RequestA2aPeer = Omit<A2aServerSpec, "credentials"> & {
|
|
43
|
+
headers?: Record<string, string>;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* 请求体 `a2aPeers[i]` 的**处置表** —— 同时是键闭集(判序 = 书写序:名 → 对端地址 → 它的 agent card 地址 → 凭据头 → 身份头 → 技能收窄 → 轴覆写)与每个键的去处:
|
|
47
|
+
* `headers` 是件(进草稿,交给引擎的声明里不带),其余进声明。三道编译格:对请求形两向(`satisfies`:请求形多一个键而表没写 / 表里写一个请求形上没有的词 ⇒ 红);
|
|
48
|
+
* 对引擎的 `A2aServerSpec` 两道(引擎长出 / 退役一个键,或退役凭据引用位 ⇒ 红)。于是这张表是从型**派生**出来的数据,而不是谁记得去同步的清单。
|
|
49
|
+
*/
|
|
50
|
+
export declare const A2A_PEER_DISPOSITION: {
|
|
51
|
+
readonly name: "engine";
|
|
52
|
+
readonly url: "engine";
|
|
53
|
+
readonly cardUrl: "engine";
|
|
54
|
+
readonly headers: "seat";
|
|
55
|
+
readonly principalHeader: "engine";
|
|
56
|
+
readonly allowSkills: "engine";
|
|
57
|
+
readonly toolAxes: "engine";
|
|
58
|
+
};
|
|
59
|
+
/** 请求体 `a2aPeers[i]` 的键闭集 = 处置表的键(书写序即判序)。 */
|
|
60
|
+
export declare const A2A_PEER_ENTRY_KEYS: readonly ("name" | "toolAxes" | "url" | "principalHeader" | "cardUrl" | "allowSkills" | "headers")[];
|
|
36
61
|
/**
|
|
37
62
|
* **请求入口的一次读**(`boot/resolve-spec.ts` 在腿首铸一份,受理门与读器——续跑重放腿只有读器——都吃这一份):`body.a2aPeers` 若是数组,返回同形数组
|
|
38
63
|
* (每个对象条目换成它的 {@link PeerSnapshot};非对象条目原样;长度保真 —— 界外的条数仍是受理门撞帽拒与读器丢弃留声的依据,只快照界内的条目);不是数组(缺席 / `null` / 别的形)原样返回。
|
|
@@ -45,12 +70,14 @@ export declare function snapshotRequestA2a(raw: unknown, options: {
|
|
|
45
70
|
}): unknown;
|
|
46
71
|
/** 读这条对端的是哪条腿:`fresh` = 新提交;`resume` = 续跑重放升级前存下的请求体(`boot/resolve-spec.ts` 的 `opts.leg` 分流,同一个读法)。 */
|
|
47
72
|
type A2aRequestLeg = "fresh" | "resume";
|
|
73
|
+
/** 请求面对端 → 草稿:按 {@link A2A_PEER_DISPOSITION} 拆(`headers` 进件,其余进声明;拆法与 MCP 请求腿同一只 `splitDeclaration`)。件缺席或空 ⇒ 草稿不带件。纯函数,不登记。 */
|
|
74
|
+
export declare function toA2aDraft(peer: RequestA2aPeer): A2aDraft;
|
|
48
75
|
/**
|
|
49
76
|
* Shape-check the raw `body.a2aPeers`. `null` → a non-array (caller error; the route may 400). Otherwise the
|
|
50
|
-
* valid subset + the dropped (malformed/over-cap) entries as {@link A2aInjectionDrop} facts (peer name · reason · body coordinate).
|
|
77
|
+
* valid subset as drafts (nothing registered) + the dropped (malformed/over-cap) entries as {@link A2aInjectionDrop} facts (peer name · reason · body coordinate).
|
|
51
78
|
*/
|
|
52
79
|
export declare function validateRequestA2a(raw: unknown): {
|
|
53
|
-
ok:
|
|
80
|
+
ok: A2aDraft[];
|
|
54
81
|
dropped: A2aInjectionDrop[];
|
|
55
82
|
} | null;
|
|
56
83
|
/**
|
|
@@ -69,13 +96,14 @@ export declare function requestA2aDeclarationRefusal(list: unknown): Declaration
|
|
|
69
96
|
/** fresh 提交腿的 `a2aPeers` 门:{@link requestA2aDeclarationRefusal} 有答案 ⇒ 同步 400(码 / 句 / `unknownKeys` / 机读位原样)。 */
|
|
70
97
|
export declare function assertRequestA2aEntries(bodyA2a: unknown): void;
|
|
71
98
|
/**
|
|
72
|
-
* Merge GATED per-request
|
|
99
|
+
* Merge GATED per-request peer drafts OVER the deployment baseline (center/config): **select first, then mint**. The baseline WINS on a name
|
|
73
100
|
* clash — a caller can ADD a peer but can never SHADOW a configured one. This is load-bearing on THIS lane
|
|
74
101
|
* specifically: the peer name is the tool-namespace segment (`a2a__<peer>__<skill>`), so shadowing would let
|
|
75
|
-
* a caller keep the tool NAMES the model was told about while swapping the agent behind them.
|
|
102
|
+
* a caller keep the tool NAMES the model was told about while swapping the agent behind them. A draft that loses to the baseline never reaches
|
|
103
|
+
* the desk; each winner is minted once on `desk` under `lease` (`peer-seat.ts` `mintDeclaration`: the reference at the top level, zero header values).
|
|
76
104
|
* Returns the baseline unchanged when there is nothing to add.
|
|
77
105
|
*/
|
|
78
|
-
export declare function mergeRequestA2a(baseline: A2aServerSpec[] | undefined,
|
|
106
|
+
export declare function mergeRequestA2a(baseline: A2aServerSpec[] | undefined, drafts: readonly A2aDraft[], desk: Pick<PeerDesk, "declare">, lease: PeerLease): A2aServerSpec[] | undefined;
|
|
79
107
|
/**
|
|
80
108
|
* The single entry point the spec-builder calls: compute the effective `TaskSpec.a2a` = deployment baseline
|
|
81
109
|
* (`a2aForScenario(config.a2aPeers, scenario)`) + the caller's gated per-request peers. Off the honored lane
|
|
@@ -83,7 +111,9 @@ export declare function mergeRequestA2a(baseline: A2aServerSpec[] | undefined, g
|
|
|
83
111
|
* peers a closed gate dropped, so a shell never silently believes its declaration took effect (it also reads
|
|
84
112
|
* `capabilities.a2aInjection`).
|
|
85
113
|
*/
|
|
86
|
-
export declare function resolveRequestA2a(baseline: A2aServerSpec[] | undefined, bodyA2a: unknown, config: A2aGateConfig,
|
|
114
|
+
export declare function resolveRequestA2a(baseline: A2aServerSpec[] | undefined, bodyA2a: unknown, config: A2aGateConfig,
|
|
115
|
+
/** 对端座的 desk 与本腿的宿主租约(必填,与 MCP 请求腿同一对):胜出草稿在它下面铸成带引用的声明。 */
|
|
116
|
+
desk: Pick<PeerDesk, "declare">, lease: PeerLease, logger?: {
|
|
87
117
|
info?(m: string, meta?: unknown): void;
|
|
88
118
|
warn(m: string, meta?: unknown): void;
|
|
89
119
|
},
|
package/dist/task-a2a.js
CHANGED
|
@@ -1,18 +1,36 @@
|
|
|
1
1
|
import { types } from "node:util";
|
|
2
|
+
import { resolveComplianceDenies } from "@sema-agent/core";
|
|
2
3
|
import { describeNotStringArray, describeValueShape, findUrlCredential, isStringArray } from "@sema-agent/settings-schema";
|
|
3
4
|
import { errorKindOf } from "./observability/err-text.js";
|
|
4
|
-
import { readPlainStringRecord } from "./plain-string-record.js";
|
|
5
|
+
import { declarationKeys, readPlainStringRecord, splitDeclaration } from "./plain-string-record.js";
|
|
6
|
+
import { mintDeclaration, peerSentence } from "./peer-seat.js";
|
|
5
7
|
import { readRequestToolAxes } from "./request-tool-axes.js";
|
|
6
8
|
import { MAX_KEY_ECHO, echoKeyName, keyClosureClause, scanKeyNames } from "./request-key-closure.js";
|
|
7
9
|
import { urlCredentialHeaderExit, urlCredentialRefusalReason } from "./url-credential-refusal.js";
|
|
8
10
|
import { declarationEntryNotObject, declarationIssueFacts, declarationNameIssue, declarationOverCapFacts, declaredName, judgeDeclarationKeys, requestDeclarationRefusal, throwDeclarationRefusal, } from "./request-declaration-refusal.js";
|
|
11
|
+
import { principalHeaderOwnershipIssue } from "./task-mcp.js";
|
|
9
12
|
import { DEPLOYMENT_SHAPE_PREDICATES } from "./deployment-shape.js";
|
|
10
13
|
export const MAX_REQUEST_A2A_PEERS = 32;
|
|
11
14
|
export function a2aInjectionHonored(config) {
|
|
15
|
+
if (config.lockedConfigKeys?.includes(A2A_LOCK_WORD) === true)
|
|
16
|
+
return false;
|
|
17
|
+
if (config.compliancePosture !== undefined && resolveComplianceDenies(config.compliancePosture).has(A2A_COMPLIANCE_WORD))
|
|
18
|
+
return false;
|
|
12
19
|
return !DEPLOYMENT_SHAPE_PREDICATES.multiTenant.holds(config);
|
|
13
20
|
}
|
|
21
|
+
const A2A_LOCK_WORD = "a2a";
|
|
22
|
+
const A2A_COMPLIANCE_WORD = "a2a_peers";
|
|
14
23
|
const HTTP_URL_RE = /^https?:\/\//i;
|
|
15
|
-
export const
|
|
24
|
+
export const A2A_PEER_DISPOSITION = {
|
|
25
|
+
name: "engine",
|
|
26
|
+
url: "engine",
|
|
27
|
+
cardUrl: "engine",
|
|
28
|
+
headers: "seat",
|
|
29
|
+
principalHeader: "engine",
|
|
30
|
+
allowSkills: "engine",
|
|
31
|
+
toolAxes: "engine",
|
|
32
|
+
};
|
|
33
|
+
export const A2A_PEER_ENTRY_KEYS = declarationKeys(A2A_PEER_DISPOSITION);
|
|
16
34
|
const A2A_PEER_ENTRY_KEY_SET = new Set(A2A_PEER_ENTRY_KEYS);
|
|
17
35
|
const NO_TOLERATED_KEYS = new Set();
|
|
18
36
|
const A2A_SEAT = {
|
|
@@ -133,11 +151,11 @@ export function snapshotRequestA2a(raw, options) {
|
|
|
133
151
|
return kept;
|
|
134
152
|
}
|
|
135
153
|
function toolAxesIssue(read) {
|
|
136
|
-
return { path: "toolAxes", reason: read.problem };
|
|
154
|
+
return { path: "toolAxes", reason: peerSentence(read.problem) };
|
|
137
155
|
}
|
|
138
156
|
function toolAxesNotCloneableIssue(read, clone) {
|
|
139
157
|
const because = clone === undefined || clone.ok ? "unavailable" : clone.because;
|
|
140
|
-
return { path: "toolAxes", reason: `declaration not cloneable (${because}) — the one-time migration re-reads the stored declaration as plain JSON data and this one is not; ${read.problem}` };
|
|
158
|
+
return { path: "toolAxes", reason: `declaration not cloneable (${because}) — the one-time migration re-reads the stored declaration as plain JSON data and this one is not; ${peerSentence(read.problem)}` };
|
|
141
159
|
}
|
|
142
160
|
const A2A_PEER_KEY_JUDGES = {
|
|
143
161
|
name: declarationNameIssue,
|
|
@@ -152,7 +170,11 @@ const A2A_PEER_KEY_JUDGES = {
|
|
|
152
170
|
const reserved = read.stripped[0];
|
|
153
171
|
return reserved === undefined ? undefined : { path: HEADERS_RESERVED_MEMBER_PATH, reason: reserved.fault };
|
|
154
172
|
},
|
|
155
|
-
principalHeader: (o) =>
|
|
173
|
+
principalHeader: (o) => o.principalHeader === undefined
|
|
174
|
+
? undefined
|
|
175
|
+
: typeof o.principalHeader !== "string"
|
|
176
|
+
? { path: "principalHeader", reason: `must be a string (a header name) — got ${describeValueShape(o.principalHeader)}` }
|
|
177
|
+
: principalHeaderOwnershipIssue(o.principalHeader, "a2a", "principalHeader"),
|
|
156
178
|
allowSkills: (o) => o.allowSkills === undefined || isStringArray(o.allowSkills)
|
|
157
179
|
? undefined
|
|
158
180
|
: { path: "allowSkills", reason: `must be an array of strings (omit the key to leave the peer's skills unrestricted) — got ${describeNotStringArray(o.allowSkills)}` },
|
|
@@ -162,10 +184,10 @@ const A2A_PEER_KEY_JUDGES = {
|
|
|
162
184
|
},
|
|
163
185
|
};
|
|
164
186
|
function normalizeA2aPeer(e, leg, at, storedToolAxes) {
|
|
165
|
-
const dropBecause = (issue) => ({
|
|
187
|
+
const dropBecause = (issue) => ({ draft: null, because: declarationIssueFacts(at, issue) });
|
|
166
188
|
const notObject = declarationEntryNotObject(A2A_SEAT, e, at);
|
|
167
189
|
if (notObject !== undefined)
|
|
168
|
-
return {
|
|
190
|
+
return { draft: null, because: { field: at, reason: notObject } };
|
|
169
191
|
const o = snapshotPeer(e, storedToolAxes !== undefined);
|
|
170
192
|
for (const key of A2A_PEER_ENTRY_KEYS) {
|
|
171
193
|
const issue = A2A_PEER_KEY_JUDGES[key](o, at);
|
|
@@ -206,12 +228,16 @@ function normalizeA2aPeer(e, leg, at, storedToolAxes) {
|
|
|
206
228
|
return unread;
|
|
207
229
|
if (again.toolAxes !== undefined)
|
|
208
230
|
spec.toolAxes = again.toolAxes;
|
|
209
|
-
return { spec, toolAxesReread: axes.problem, ...lost };
|
|
231
|
+
return { draft: toA2aDraft(spec), toolAxesReread: peerSentence(axes.problem), ...lost };
|
|
210
232
|
}
|
|
211
233
|
if (axes.toolAxes !== undefined)
|
|
212
234
|
spec.toolAxes = axes.toolAxes;
|
|
213
235
|
}
|
|
214
|
-
return { spec, ...lost };
|
|
236
|
+
return { draft: toA2aDraft(spec), ...lost };
|
|
237
|
+
}
|
|
238
|
+
export function toA2aDraft(peer) {
|
|
239
|
+
const split = splitDeclaration(peer, A2A_PEER_DISPOSITION);
|
|
240
|
+
return { spec: split.engine, ...(split.pieces === undefined ? {} : { pieces: split.pieces }) };
|
|
215
241
|
}
|
|
216
242
|
export function validateRequestA2a(raw) {
|
|
217
243
|
const v = validateRequestA2aEntries(raw, "fresh");
|
|
@@ -228,12 +254,12 @@ function validateRequestA2aEntries(raw, leg, storedToolAxes) {
|
|
|
228
254
|
const headersLost = [];
|
|
229
255
|
for (const [i, e] of raw.slice(0, MAX_REQUEST_A2A_PEERS).entries()) {
|
|
230
256
|
const read = normalizeA2aPeer(e, leg, `${A2A_SEAT.list}[${i}]`, storedToolAxes);
|
|
231
|
-
if (read.
|
|
232
|
-
ok.push(read.
|
|
257
|
+
if (read.draft !== null) {
|
|
258
|
+
ok.push(read.draft);
|
|
233
259
|
if (read.toolAxesReread !== undefined)
|
|
234
|
-
toolAxesReread.push({ peer: read.spec.name,
|
|
260
|
+
toolAxesReread.push({ peer: read.draft.spec.name, sentence: read.toolAxesReread });
|
|
235
261
|
if (read.headersLost !== undefined)
|
|
236
|
-
headersLost.push({ peer: read.spec.name, lost: read.headersLost });
|
|
262
|
+
headersLost.push({ peer: read.draft.spec.name, lost: read.headersLost });
|
|
237
263
|
}
|
|
238
264
|
else
|
|
239
265
|
dropped.push({ peer: declaredName(e).slice(0, 128), ...read.because });
|
|
@@ -265,14 +291,14 @@ export function requestA2aDeclarationRefusal(list) {
|
|
|
265
291
|
export function assertRequestA2aEntries(bodyA2a) {
|
|
266
292
|
throwDeclarationRefusal(requestA2aDeclarationRefusal(bodyA2a));
|
|
267
293
|
}
|
|
268
|
-
export function mergeRequestA2a(baseline,
|
|
269
|
-
if (
|
|
294
|
+
export function mergeRequestA2a(baseline, drafts, desk, lease) {
|
|
295
|
+
if (drafts.length === 0)
|
|
270
296
|
return baseline;
|
|
271
297
|
const taken = new Set((baseline ?? []).map((p) => p.name));
|
|
272
|
-
const
|
|
273
|
-
return
|
|
298
|
+
const winners = drafts.filter((d) => !taken.has(d.spec.name));
|
|
299
|
+
return winners.length === 0 ? baseline : [...(baseline ?? []), ...winners.map((d) => mintDeclaration(desk, d, lease))];
|
|
274
300
|
}
|
|
275
|
-
export function resolveRequestA2a(baseline, bodyA2a, config, logger, leg = "fresh", storedToolAxes) {
|
|
301
|
+
export function resolveRequestA2a(baseline, bodyA2a, config, desk, lease, logger, leg = "fresh", storedToolAxes) {
|
|
276
302
|
if (bodyA2a === undefined || bodyA2a === null)
|
|
277
303
|
return baseline;
|
|
278
304
|
if (!a2aInjectionHonored(config)) {
|
|
@@ -286,7 +312,7 @@ export function resolveRequestA2a(baseline, bodyA2a, config, logger, leg = "fres
|
|
|
286
312
|
}
|
|
287
313
|
if (v.dropped.length > 0)
|
|
288
314
|
logger?.warn("a2a_injection_dropped", { dropped: v.dropped });
|
|
289
|
-
const merged = mergeRequestA2a(baseline, v.ok);
|
|
315
|
+
const merged = mergeRequestA2a(baseline, v.ok, desk, lease);
|
|
290
316
|
const baselineNames = new Set((baseline ?? []).map((p) => p.name));
|
|
291
317
|
for (const r of v.toolAxesReread) {
|
|
292
318
|
if (baselineNames.has(r.peer))
|
|
@@ -294,7 +320,7 @@ export function resolveRequestA2a(baseline, bodyA2a, config, logger, leg = "fres
|
|
|
294
320
|
logger?.warn("a2a_tool_axes_read_as_before_upgrade", {
|
|
295
321
|
peer: r.peer,
|
|
296
322
|
migration: "M19",
|
|
297
|
-
problem: r.
|
|
323
|
+
problem: r.sentence,
|
|
298
324
|
note: "this replayed request was stored before the upgrade and the peer's toolAxes declaration does not pass the engine's reader; while one-time migration M19 is open it is read the way the pre-upgrade reader reads it (members that do not fit are dropped) and the peer stays mounted — once the window closes the same request leaves this peer unmounted",
|
|
299
325
|
});
|
|
300
326
|
}
|