@sema-agent/server 7.125.1 → 7.127.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 +229 -2
- package/README.md +2 -2
- package/README.zh-CN.md +2 -2
- package/USAGE.md +346 -145
- package/deploy/sema-up/README.md +1 -1
- package/deploy/sema-up/chart/templates/networkpolicy-sandbox.yaml +57 -0
- package/deploy/sema-up/chart/templates/sandbox-rbac.yaml +32 -1
- package/deploy/sema-up/chart/templates/server-v4pro.yaml +3 -2
- package/deploy/sema-up/chart/templates/server.yaml +2 -1
- package/deploy/sema-up/chart/values.yaml +22 -0
- package/deploy/sema-up/cluster-up.sh +10 -10
- package/deploy/sema-up/kube-up.sh +20 -13
- package/deploy/sema-up/lib/dataroot.sh +1 -1
- package/deploy/sema-up/lib/envf.sh +5 -5
- package/deploy/sema-up/lib/flagshape.sh +5 -5
- package/deploy/sema-up/lib/lanes.py +1 -1
- package/deploy/sema-up/lib/node-addrs.sh +42 -0
- package/deploy/sema-up/lib/parse-machines.py +2 -2
- package/deploy/sema-up/lib/shell-access.sh +1 -1
- package/deploy/sema-up/preflight.sh +4 -4
- package/deploy/sema-up/sema-up.sh +33 -33
- package/deploy/sema-up/smoke.sh +3 -3
- package/deploy/sema-up/stack/compose.yaml +1 -1
- package/deploy/sema-up/stack/sema-stack-cluster.yaml +26 -3
- package/dist/approval-card.d.ts +20 -4
- package/dist/approval-content-kind.d.ts +38 -22
- package/dist/approval-content-kind.js +20 -4
- package/dist/audit.js +3 -0
- package/dist/bench/s1/arms.d.ts +9 -37
- package/dist/bench/s1/arms.js +4 -61
- package/dist/bench/s1/live-deps.d.ts +4 -10
- package/dist/bench/s1/live-deps.js +1 -222
- package/dist/bench/s1/oracle.d.ts +1 -1
- package/dist/bench/s1/reviewer.d.ts +1 -1
- package/dist/bench/s1/row.d.ts +5 -7
- package/dist/bench/s1/row.js +0 -2
- package/dist/bench/s1/run-firm.d.ts +2 -2
- package/dist/bench/s1/run-firm.js +1 -4
- package/dist/bench/s1/runner-ctx.d.ts +17 -29
- package/dist/bench/s1/runner-ctx.js +3 -7
- package/dist/bench/s1/tasks.d.ts +9 -46
- package/dist/bench/s1/tasks.js +4 -63
- package/dist/boot/execution-env.d.ts +38 -26
- package/dist/boot/execution-env.js +87 -41
- package/dist/boot/leader.d.ts +2 -1
- package/dist/boot/memory-boundary.d.ts +1 -1
- package/dist/boot/memory-consolidation.d.ts +37 -3
- package/dist/boot/memory-consolidation.js +18 -2
- package/dist/boot/parked-revive-gate.d.ts +0 -3
- package/dist/boot/parked-revive-gate.js +2 -2
- package/dist/boot/resolve-spec.d.ts +0 -2
- package/dist/boot/resolve-spec.js +12 -17
- package/dist/boot/retention-lane.d.ts +12 -1
- package/dist/boot/retention-lane.js +2 -0
- package/dist/boot/runner-deps.d.ts +7 -6
- package/dist/boot/runner-deps.js +5 -16
- package/dist/boot/session-faces.d.ts +7 -2
- package/dist/boot/session-faces.js +37 -1
- package/dist/boot/stage-03-store-backend.d.ts +1 -0
- package/dist/boot/stage-03-store-backend.js +2 -2
- package/dist/boot/stage-04-stores.d.ts +1 -0
- package/dist/boot/stage-05-execution-env.d.ts +2 -2
- package/dist/boot/stage-05-execution-env.js +7 -4
- package/dist/boot/stage-06-runners.d.ts +2 -3
- package/dist/boot/stage-06-runners.js +13 -9
- package/dist/boot/stage-07-capability-layer.d.ts +2 -3
- package/dist/boot/stage-07-capability-layer.js +3 -4
- package/dist/boot/stage-08-reapers.d.ts +2 -3
- package/dist/boot/stage-08-reapers.js +2 -2
- package/dist/boot/stage-09-leader.d.ts +2 -3
- package/dist/boot/stage-09-leader.js +2 -1
- package/dist/boot/stage-10-http-server.d.ts +2 -3
- package/dist/boot/stage-10-http-server.js +2 -2
- package/dist/boot/stores.d.ts +1 -0
- package/dist/boot/stores.js +4 -3
- package/dist/boot/web-admin.d.ts +5 -0
- package/dist/boot/web-admin.js +28 -14
- package/dist/brain.d.ts +2 -2
- package/dist/brain.js +1 -1
- package/dist/capabilities/builtin-tools.d.ts +2 -1
- package/dist/capabilities/composite-members.d.ts +1 -1
- package/dist/capabilities/composite-members.js +1 -1
- package/dist/capabilities/hands-lane.d.ts +9 -6
- package/dist/capabilities/hands-lane.js +2 -2
- package/dist/capabilities/memory-notice.d.ts +27 -22
- package/dist/capabilities/memory-notice.js +15 -17
- package/dist/capabilities/scenarios.d.ts +9 -14
- package/dist/capabilities/scenarios.js +5 -50
- package/dist/capability-facts.d.ts +22 -11
- package/dist/capability-facts.js +13 -6
- package/dist/config-catalog.js +14 -5
- package/dist/config-provider.d.ts +5 -1
- package/dist/config-provider.js +23 -4
- package/dist/config-types.d.ts +19 -2
- package/dist/config.js +41 -6
- package/dist/deployment-governance.d.ts +19 -21
- package/dist/deployment-governance.js +7 -8
- package/dist/env-name-allowlist-knobs.d.ts +5 -5
- package/dist/env-name-allowlist-knobs.js +1 -0
- package/dist/execution-lane-caps.d.ts +12 -0
- package/dist/execution-lane-caps.js +18 -4
- package/dist/fleet/subagent-tail-bus.js +15 -5
- package/dist/hooks/hook-runner.d.ts +84 -30
- package/dist/hooks/hook-runner.js +74 -41
- package/dist/http/admission.js +17 -10
- package/dist/http/durable-run-leg.d.ts +5 -4
- package/dist/http/durable-run-leg.js +2 -4
- package/dist/http/idempotency.d.ts +28 -6
- package/dist/http/idempotency.js +10 -2
- package/dist/http/principal-gate.d.ts +14 -0
- package/dist/http/principal-gate.js +7 -0
- package/dist/http/request-guards.d.ts +2 -1
- package/dist/http/request-guards.js +14 -14
- package/dist/http/resume-legs.d.ts +2 -2
- package/dist/http/resume-legs.js +20 -10
- package/dist/http/route-ctx.d.ts +15 -7
- package/dist/http/routes/a2a-serve.js +11 -7
- package/dist/http/routes/approvals-assistant.js +18 -3
- package/dist/http/routes/background.d.ts +1 -1
- package/dist/http/routes/background.js +1 -1
- package/dist/http/routes/capabilities.js +10 -2
- package/dist/http/routes/mcp-reconnect.js +1 -1
- package/dist/http/routes/runs.d.ts +4 -3
- package/dist/http/routes/runs.js +35 -14
- package/dist/http/routes/session-sync.js +14 -11
- package/dist/http/routes/sessions.js +9 -9
- package/dist/http/routes/side-query.js +6 -19
- package/dist/http/routes/tasks.js +29 -19
- package/dist/http/routes/workflows.js +8 -0
- package/dist/http/server.d.ts +4 -0
- package/dist/http/server.js +3 -5
- package/dist/http/submit-replay.d.ts +15 -8
- package/dist/http/submit-replay.js +6 -0
- package/dist/http/wire-types.d.ts +7 -9
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/internal-run-env.d.ts +30 -0
- package/dist/internal-run-env.js +11 -0
- package/dist/leader/wire.js +3 -2
- package/dist/lsp/manager.js +1 -1
- package/dist/memory-scope.d.ts +19 -7
- package/dist/memory-scope.js +25 -8
- package/dist/observability/fail-open.d.ts +31 -3
- package/dist/observability/fail-open.js +31 -3
- package/dist/observability/metrics.d.ts +0 -1
- package/dist/observability/metrics.js +1 -4
- package/dist/observability/run-terminal.js +72 -4
- package/dist/permission-rule-vocab.d.ts +3 -2
- package/dist/permission-rule-vocab.js +1 -1
- package/dist/plan-cache-probe.d.ts +3 -2
- package/dist/plugins/approval-ask-store-sql.d.ts +1 -1
- package/dist/plugins/caching-session-store.d.ts +42 -22
- package/dist/plugins/caching-session-store.js +19 -9
- package/dist/plugins/checkpoint-store-sql.d.ts +42 -28
- package/dist/plugins/checkpoint-store-sql.js +57 -11
- package/dist/plugins/file-run-store.d.ts +25 -21
- package/dist/plugins/file-run-store.js +70 -34
- package/dist/plugins/k8s-exec-protocol.js +3 -0
- package/dist/plugins/local-checkpoint-store.d.ts +8 -5
- package/dist/plugins/local-checkpoint-store.js +5 -15
- package/dist/plugins/local-session-store.d.ts +66 -7
- package/dist/plugins/local-session-store.js +168 -101
- package/dist/plugins/mailbox-recipient-lifecycle.d.ts +1 -1
- package/dist/plugins/memory-run-store.d.ts +19 -3
- package/dist/plugins/memory-run-store.js +38 -3
- package/dist/plugins/one-time-migrations.d.ts +165 -39
- package/dist/plugins/one-time-migrations.js +51 -144
- package/dist/plugins/pg-pool.js +11 -1
- package/dist/plugins/pg-session-storage.d.ts +2 -0
- package/dist/plugins/pg-session-storage.js +9 -5
- package/dist/plugins/remote-env-adb.d.ts +3 -0
- package/dist/plugins/remote-env-adb.js +1 -0
- package/dist/plugins/remote-env-device.d.ts +3 -0
- package/dist/plugins/remote-env-device.js +1 -0
- package/dist/plugins/remote-env-e2b.d.ts +4 -0
- package/dist/plugins/remote-env-e2b.js +2 -1
- package/dist/plugins/remote-env-host.d.ts +23 -1
- package/dist/plugins/remote-env-host.js +20 -2
- package/dist/plugins/remote-env-k8s.d.ts +264 -41
- package/dist/plugins/remote-env-k8s.js +551 -82
- package/dist/plugins/remote-env-local-docker.d.ts +4 -0
- package/dist/plugins/remote-env-local-docker.js +2 -1
- package/dist/plugins/remote-env-ssh.d.ts +3 -0
- package/dist/plugins/remote-env-ssh.js +1 -0
- package/dist/plugins/retention-store-sql.d.ts +4 -1
- package/dist/plugins/retention-store-sql.js +11 -9
- package/dist/plugins/run-store-sql.d.ts +44 -6
- package/dist/plugins/run-store-sql.js +92 -27
- package/dist/plugins/session-capture-record-store-sql.d.ts +2 -3
- package/dist/plugins/session-store.d.ts +4 -3
- package/dist/plugins/session-store.js +1 -1
- package/dist/plugins/sql-driver.d.ts +2 -1
- package/dist/plugins/store-backend.d.ts +12 -5
- package/dist/plugins/store-backend.js +13 -4
- package/dist/plugins/store-contracts.d.ts +20 -3
- package/dist/plugins/store-open-wait.js +3 -0
- package/dist/plugins/tidb-pool.js +15 -3
- package/dist/plugins/tidb-session-storage.js +3 -2
- package/dist/plugins/tidb-session-store.d.ts +2 -0
- package/dist/plugins/tidb-session-store.js +6 -2
- package/dist/request-key-closure.d.ts +32 -7
- package/dist/request-key-closure.js +25 -9
- package/dist/router/route-orchestration.d.ts +3 -11
- package/dist/router/route-orchestration.js +0 -4
- package/dist/rule-entry-list.js +0 -4
- package/dist/rules-consent.js +3 -0
- package/dist/run-acceptance.d.ts +51 -0
- package/dist/run-acceptance.js +27 -0
- package/dist/run-local.d.ts +5 -4
- package/dist/run-local.js +23 -17
- package/dist/runs.d.ts +7 -11
- package/dist/runs.js +6 -16
- package/dist/sandbox-egress-policy.d.ts +61 -0
- package/dist/sandbox-egress-policy.js +235 -0
- package/dist/security.d.ts +7 -0
- package/dist/security.js +5 -0
- package/dist/server-secret-env.d.ts +10 -4
- package/dist/server-secret-env.js +4 -1
- package/dist/session-error-wire.d.ts +2 -2
- package/dist/session-incarnation.d.ts +46 -2
- package/dist/session-incarnation.js +14 -3
- package/dist/session-sync-kernel.d.ts +10 -3
- package/dist/session-titler.d.ts +5 -3
- package/dist/spec-fields.d.ts +24 -8
- package/dist/spec-fields.js +21 -2
- package/dist/task-workflow.d.ts +6 -4
- package/dist/task-workflow.js +3 -2
- package/dist/tool-approval.d.ts +78 -6
- package/dist/tool-approval.js +7 -3
- package/dist/trace/core-keyset-guard.d.ts +6 -5
- package/dist/trace/engine-notice-wire.d.ts +26 -1
- package/dist/trace/engine-notice-wire.js +7 -2
- package/dist/trace/ledger-events.d.ts +9 -3
- package/dist/trace/ledger-sink.d.ts +7 -0
- package/dist/trace/ledger-sink.js +14 -4
- package/dist/trace/project.d.ts +57 -11
- package/dist/trace/project.js +54 -8
- package/dist/trace/self-minted-wire.d.ts +94 -2
- package/dist/trace/self-minted-wire.js +28 -0
- package/dist/trace/tool-output-media.d.ts +26 -0
- package/dist/trace/tool-output-media.js +57 -0
- package/dist/trace/wire-projection-faces.d.ts +7 -1
- package/dist/trace/wire-projection-faces.js +2 -1
- package/dist/web-admin-client/apply-effective.d.ts +13 -7
- package/dist/web-admin-client/apply-effective.js +11 -26
- package/dist/web-admin-client/apply-ledger.d.ts +2 -2
- package/dist/web-admin-client/candidate-gate.d.ts +39 -4
- package/dist/web-admin-client/candidate-gate.js +9 -2
- package/dist/web-admin-client/facade.d.ts +2 -2
- package/dist/web-admin-client/http-client.d.ts +3 -1
- package/dist/web-admin-client/http-client.js +4 -3
- package/dist/web-admin-client/read-warnings.d.ts +33 -5
- package/dist/web-admin-client/read-warnings.js +41 -6
- package/dist/web-admin-client/types.d.ts +11 -5
- package/dist/workspace-cache.d.ts +45 -0
- package/dist/workspace-cache.js +30 -0
- package/dist/workspace-space-commit.d.ts +116 -0
- package/dist/workspace-space-commit.js +117 -0
- package/dist/workspace-space.d.ts +75 -9
- package/dist/workspace-space.js +52 -1
- package/package.json +4 -4
- package/dist/boot/session-incarnation-seat.d.ts +0 -41
- package/dist/boot/session-incarnation-seat.js +0 -69
- package/dist/capabilities/code-review-council.d.ts +0 -49
- package/dist/capabilities/code-review-council.js +0 -111
- package/dist/capabilities/collab-wire.d.ts +0 -36
- package/dist/capabilities/collab-wire.js +0 -2
- package/dist/capabilities/collab-workflows.d.ts +0 -47
- package/dist/capabilities/collab-workflows.js +0 -90
- package/dist/capabilities/prompts/code-review.d.ts +0 -25
- package/dist/capabilities/prompts/code-review.js +0 -39
- package/dist/capabilities/prompts/team.d.ts +0 -10
- package/dist/capabilities/prompts/team.js +0 -6
- package/dist/capabilities/team.d.ts +0 -113
- package/dist/capabilities/team.js +0 -70
|
@@ -10,8 +10,9 @@ import { adbExecutionEnvFactory } from "../plugins/remote-env-adb.js";
|
|
|
10
10
|
import { deviceExecutionEnvFactory } from "../plugins/remote-env-device.js";
|
|
11
11
|
import { e2bExecutionEnvFactory } from "../plugins/remote-env-e2b.js";
|
|
12
12
|
import { hostExecutionEnvFactory, RemoteHostExecutionEnv } from "../plugins/remote-env-host.js";
|
|
13
|
-
import { k8sExecutionEnvFactory } from "../plugins/remote-env-k8s.js";
|
|
13
|
+
import { checkSandboxEgressPolicy, createSpaceReclaimer, K8S_SANDBOX_NAMESPACE_DEFAULT, k8sExecutionEnvFactory } from "../plugins/remote-env-k8s.js";
|
|
14
14
|
import { createRunWorkspaceSnapshotSeat } from "../fleet/workspace-snapshot-residual.js";
|
|
15
|
+
import { createSpaceCommitFence } from "../workspace-space-commit.js";
|
|
15
16
|
import { localDockerExecutionEnvFactory } from "../plugins/remote-env-local-docker.js";
|
|
16
17
|
import { sshExecutionEnvFactory } from "../plugins/remote-env-ssh.js";
|
|
17
18
|
import { isRemoteScratchpadLane, withRemoteScratchpad } from "../plugins/remote-scratchpad.js";
|
|
@@ -22,8 +23,10 @@ import { reapOrphanWorktrees, withWorktreeIsolation } from "../plugins/worktree-
|
|
|
22
23
|
import { customPkgSourceFromEnv, derivePkgSourceEnv } from "../sandbox-pkg-source.js";
|
|
23
24
|
import { effectiveHostWorkspace } from "../task-cwd.js";
|
|
24
25
|
import { taskInheritEnvRefusal } from "../hosted-posture.js";
|
|
26
|
+
import { workspaceSnapshotTimeoutOf } from "../workspace-space.js";
|
|
27
|
+
import { sayEgressPolicyReading } from "../sandbox-egress-policy.js";
|
|
25
28
|
import { isSandboxPathAdjudicationLane, sandboxPathEnvSlots, withSandboxPathEnvSlot } from "./deferred-sandbox-path-env.js";
|
|
26
|
-
import { REMOTE_EXEC_PROVIDER_WORDS, executionLaneHomeDir, executionLaneOf, isSingleMachineDefaultLane, laneIsolated } from "../execution-lane-caps.js";
|
|
29
|
+
import { REMOTE_EXEC_PROVIDER_WORDS, executionLaneHomeDir, executionLaneOf, isSingleMachineDefaultLane, laneBindsReads, laneIsolated } from "../execution-lane-caps.js";
|
|
27
30
|
function boundedSessionSetter(map, maxEntries) {
|
|
28
31
|
return (sid, value) => {
|
|
29
32
|
map.delete(sid);
|
|
@@ -35,10 +38,10 @@ function boundedSessionSetter(map, maxEntries) {
|
|
|
35
38
|
function forwardedSandboxEnvKeys(remoteExec) {
|
|
36
39
|
switch (remoteExec.provider) {
|
|
37
40
|
case "e2b":
|
|
41
|
+
case "k8s":
|
|
38
42
|
return Object.keys(remoteExec.sandboxEnv ?? {}).sort();
|
|
39
43
|
case "local-docker":
|
|
40
44
|
return Object.keys(remoteExec.env ?? {}).sort();
|
|
41
|
-
case "k8s":
|
|
42
45
|
case "ssh":
|
|
43
46
|
case "adb":
|
|
44
47
|
case "host":
|
|
@@ -50,18 +53,20 @@ function forwardedSandboxEnvKeys(remoteExec) {
|
|
|
50
53
|
}
|
|
51
54
|
}
|
|
52
55
|
}
|
|
56
|
+
function buildSandboxLaneEnv(config, explicit) {
|
|
57
|
+
const merged = { ...derivePkgSourceEnv(config.sandboxPkgSource, customPkgSourceFromEnv()), ...(explicit ?? {}) };
|
|
58
|
+
return Object.keys(merged).length > 0 ? merged : undefined;
|
|
59
|
+
}
|
|
53
60
|
const MAX_CWD_SESSIONS = 4096;
|
|
54
61
|
export function createSessionScopedRegistries(maxEntries = MAX_CWD_SESSIONS) {
|
|
55
62
|
const perSessionCwd = new Map();
|
|
56
63
|
const perSessionShellEnv = new Map();
|
|
57
64
|
const perSessionInheritEnv = new Map();
|
|
58
|
-
const perSessionIncarnation = new Map();
|
|
59
65
|
const owners = new Map();
|
|
60
66
|
const dropSession = (sid) => {
|
|
61
67
|
perSessionCwd.delete(sid);
|
|
62
68
|
perSessionShellEnv.delete(sid);
|
|
63
69
|
perSessionInheritEnv.delete(sid);
|
|
64
|
-
perSessionIncarnation.delete(sid);
|
|
65
70
|
owners.delete(sid);
|
|
66
71
|
};
|
|
67
72
|
const touch = (sid, owner) => {
|
|
@@ -96,40 +101,71 @@ export function createSessionScopedRegistries(maxEntries = MAX_CWD_SESSIONS) {
|
|
|
96
101
|
perSessionCwd.delete(sid);
|
|
97
102
|
perSessionShellEnv.delete(sid);
|
|
98
103
|
perSessionInheritEnv.delete(sid);
|
|
99
|
-
perSessionIncarnation.delete(sid);
|
|
100
104
|
}
|
|
101
105
|
touch(sid, owner);
|
|
102
106
|
},
|
|
103
107
|
dropSession,
|
|
104
|
-
noteSessionIncarnation: (sid, incarnation) => {
|
|
105
|
-
if (incarnation === undefined) {
|
|
106
|
-
perSessionIncarnation.delete(sid);
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
perSessionIncarnation.set(sid, incarnation);
|
|
110
|
-
touch(sid, undefined);
|
|
111
|
-
},
|
|
112
|
-
sessionIncarnationOf: (sid) => perSessionIncarnation.get(sid),
|
|
113
108
|
};
|
|
114
109
|
}
|
|
115
110
|
export function createK8sRunEnvFactory(k8sCfg, seats, deps) {
|
|
116
|
-
return (ctx) => {
|
|
117
|
-
const
|
|
111
|
+
return async (ctx) => {
|
|
112
|
+
const onWorkspaceSnapshot = createRunWorkspaceSnapshotSeat(ctx.sessionId);
|
|
113
|
+
const child = ctx.placementRootSessionId !== ctx.sessionId;
|
|
114
|
+
const s3Snapshot = child && k8sCfg.s3Snapshot !== undefined ? spaceOff(k8sCfg.s3Snapshot) : k8sCfg.s3Snapshot;
|
|
115
|
+
const spaceOccupant = child ? undefined : await occupantOf(seats, ctx.sessionId, ctx.taskId);
|
|
116
|
+
const { cache, ...deploymentCfg } = k8sCfg;
|
|
118
117
|
return k8sExecutionEnvFactory({
|
|
119
|
-
...
|
|
118
|
+
...deploymentCfg,
|
|
119
|
+
...(cache !== undefined && !child ? { cache } : {}),
|
|
120
|
+
...(s3Snapshot !== undefined ? { s3Snapshot } : {}),
|
|
120
121
|
image: seats.imageOf(ctx.sessionId) ?? k8sCfg.image,
|
|
121
|
-
...(
|
|
122
|
-
onWorkspaceSnapshot
|
|
122
|
+
...(spaceOccupant !== undefined ? { spaceOccupant } : {}),
|
|
123
|
+
onWorkspaceSnapshot,
|
|
123
124
|
}, deps)(ctx);
|
|
124
125
|
};
|
|
125
126
|
}
|
|
126
|
-
|
|
127
|
-
|
|
127
|
+
const STORE_ERROR_CODE = /^[A-Za-z0-9_.:-]{1,64}$/;
|
|
128
|
+
async function occupantOf(seats, sessionId, taskId) {
|
|
129
|
+
let answer;
|
|
130
|
+
try {
|
|
131
|
+
answer = await seats.incarnationOf?.(sessionId);
|
|
132
|
+
}
|
|
133
|
+
catch (e) {
|
|
134
|
+
const code = e?.code;
|
|
135
|
+
return { fault: typeof code === "string" && STORE_ERROR_CODE.test(code) ? code : "incarnation_read_failed" };
|
|
136
|
+
}
|
|
137
|
+
if (answer === undefined)
|
|
138
|
+
return { unread: "incarnation_unknown" };
|
|
139
|
+
if (typeof answer !== "string" || answer === "")
|
|
140
|
+
return { fault: "incarnation_read_failed" };
|
|
141
|
+
const rows = seats.spaceCommits();
|
|
142
|
+
return rows !== undefined ? { incarnation: answer, fence: createSpaceCommitFence(rows, answer, taskId) } : { unread: "incarnation_unknown" };
|
|
143
|
+
}
|
|
144
|
+
function spaceOff(store) {
|
|
145
|
+
const { space: _off, ...parkOnly } = store;
|
|
146
|
+
return parkOnly;
|
|
147
|
+
}
|
|
148
|
+
export function assertWorkspaceSpaceReadable(space, seats, cache, sessionStoreLabel) {
|
|
149
|
+
if (space.available && persistNeedsOccupant(space.policy.persist)) {
|
|
150
|
+
const missing = seats.incarnationOf === undefined ? `the session store (${sessionStoreLabel}) has no by-id occupant read (incarnationOf)`
|
|
151
|
+
: seats.spaceCommits === undefined ? `this deployment has no store backend to hold the space's commit rows (the session store is ${sessionStoreLabel})`
|
|
152
|
+
: undefined;
|
|
153
|
+
if (missing === undefined)
|
|
154
|
+
return;
|
|
155
|
+
throw new Error(`WORKSPACE_PERSIST=space but ${missing} [workspace-space-unreadable]: ` +
|
|
156
|
+
"the k8s workspace space is partitioned by the session occupant and committed under a run-store row, so here no run would restore or save " +
|
|
157
|
+
'/workspace while GET /v1/capabilities.workspaceSync reports persist "space". Use a store backend (DB_BACKEND=local or DB_BACKEND=mysql|pg; ' +
|
|
158
|
+
"DB_BACKEND=memory has none), or set WORKSPACE_PERSIST=off (the default is space), and restart");
|
|
128
159
|
return;
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
160
|
+
}
|
|
161
|
+
if (cache.available && (seats.incarnationOf === undefined || seats.spaceCommits === undefined)) {
|
|
162
|
+
const missing = seats.incarnationOf === undefined
|
|
163
|
+
? `the session store (${sessionStoreLabel}) has no by-id occupant read (incarnationOf)`
|
|
164
|
+
: `this deployment has no store backend to hold the space durably (the session store is ${sessionStoreLabel})`;
|
|
165
|
+
throw new Error(`WORKSPACE_CACHE=volume but ${missing} [workspace-space-unreadable]: ` +
|
|
166
|
+
"the k8s build-cache volume belongs to the workspace space, which is keyed by the session occupant, so here no run would get its volume while " +
|
|
167
|
+
"GET /v1/capabilities.workspaceSync reports cache. Use a store backend (DB_BACKEND=local or DB_BACKEND=mysql|pg; DB_BACKEND=memory has none), or set WORKSPACE_CACHE=off, and restart");
|
|
168
|
+
}
|
|
133
169
|
}
|
|
134
170
|
function persistNeedsOccupant(persist) {
|
|
135
171
|
switch (persist) {
|
|
@@ -158,6 +194,7 @@ export function createExecutionEnv(ctx) {
|
|
|
158
194
|
const { perSessionShellEnv, setSessionShellEnv } = sessionScoped;
|
|
159
195
|
const { perSessionInheritEnv, setSessionInheritEnv } = sessionScoped;
|
|
160
196
|
let executionEnvFactory;
|
|
197
|
+
let spaceReclaimer;
|
|
161
198
|
let worktreeReap;
|
|
162
199
|
if (config.remoteExec?.provider === "e2b") {
|
|
163
200
|
executionEnvFactory = e2bExecutionEnvFactory({
|
|
@@ -168,10 +205,7 @@ export function createExecutionEnv(ctx) {
|
|
|
168
205
|
...(config.remoteExec.livenessMs != null ? { livenessMs: config.remoteExec.livenessMs } : {}),
|
|
169
206
|
...(config.remoteExec.allowInternetAccess != null ? { allowInternetAccess: config.remoteExec.allowInternetAccess } : {}),
|
|
170
207
|
...(config.remoteExec.mountPath ? { mountPath: config.remoteExec.mountPath } : {}),
|
|
171
|
-
...(() => {
|
|
172
|
-
const merged = { ...derivePkgSourceEnv(config.sandboxPkgSource, customPkgSourceFromEnv()), ...(config.remoteExec.sandboxEnv ?? {}) };
|
|
173
|
-
return Object.keys(merged).length > 0 ? { sandboxEnv: merged } : {};
|
|
174
|
-
})(),
|
|
208
|
+
...((env) => (env !== undefined ? { sandboxEnv: env } : {}))(buildSandboxLaneEnv(config, config.remoteExec.sandboxEnv)),
|
|
175
209
|
logger,
|
|
176
210
|
metrics,
|
|
177
211
|
});
|
|
@@ -188,16 +222,22 @@ export function createExecutionEnv(ctx) {
|
|
|
188
222
|
...(config.remoteExec.runtimeClass != null ? { runtimeClass: config.remoteExec.runtimeClass } : {}),
|
|
189
223
|
...(config.remoteExec.mountPath ? { mountPath: config.remoteExec.mountPath } : {}),
|
|
190
224
|
...(config.remoteExec.timeoutMs != null ? { timeoutMs: config.remoteExec.timeoutMs } : {}),
|
|
225
|
+
dataTimeoutMs: workspaceSnapshotTimeoutOf(config.remoteExec),
|
|
191
226
|
...(config.remoteExec.memory ? { memory: config.remoteExec.memory } : {}),
|
|
192
227
|
...(config.remoteExec.cpu ? { cpu: config.remoteExec.cpu } : {}),
|
|
193
|
-
...(config.remoteExec.
|
|
228
|
+
...(config.remoteExec.sandboxIpv6 !== undefined ? { ipv6: config.remoteExec.sandboxIpv6 } : {}),
|
|
229
|
+
...(config.remoteExec.s3Snapshot ? { s3Snapshot: { ...config.remoteExec.s3Snapshot, ...((f) => (f.available ? { space: { persist: f.policy.persist, keep: f.policy.keep } } : {}))(facts.workspaceSpace(config)) } } : {}),
|
|
230
|
+
...((f) => (f.available ? { cache: f.cache } : {}))(facts.workspaceCache(config)),
|
|
231
|
+
...(config.remoteExec.workspaceSnapshotExclude ? { snapshotExclude: config.remoteExec.workspaceSnapshotExclude } : {}),
|
|
194
232
|
logger,
|
|
195
|
-
...(() => {
|
|
196
|
-
const derived = derivePkgSourceEnv(config.sandboxPkgSource, customPkgSourceFromEnv());
|
|
197
|
-
return Object.keys(derived).length > 0 ? { podEnv: derived } : {};
|
|
198
|
-
})(),
|
|
233
|
+
...((env) => (env !== undefined ? { podEnv: env } : {}))(buildSandboxLaneEnv(config, config.remoteExec.sandboxEnv)),
|
|
199
234
|
};
|
|
200
|
-
executionEnvFactory = createK8sRunEnvFactory(k8sCfg, { imageOf: (sid) => perTaskImage.get(sid), incarnationOf:
|
|
235
|
+
executionEnvFactory = createK8sRunEnvFactory(k8sCfg, { imageOf: (sid) => perTaskImage.get(sid), incarnationOf: ctx.incarnationOf, spaceCommits: ctx.spaceCommits ?? (() => undefined) });
|
|
236
|
+
if (k8sCfg.cache !== undefined || k8sCfg.s3Snapshot !== undefined)
|
|
237
|
+
spaceReclaimer = createSpaceReclaimer(k8sCfg);
|
|
238
|
+
void checkSandboxEgressPolicy(k8sCfg)
|
|
239
|
+
.then((gaps) => sayEgressPolicyReading(gaps, logger, k8sCfg.namespace ?? K8S_SANDBOX_NAMESPACE_DEFAULT))
|
|
240
|
+
.catch((e) => logger.error("sandbox_egress_policy_check_crashed", { error: e instanceof Error ? e.message : String(e), effect: "the sandbox egress self-check did not complete this boot — the lane runs; the egress policy was not read" }));
|
|
201
241
|
}
|
|
202
242
|
else if (config.remoteExec?.provider === "ssh") {
|
|
203
243
|
executionEnvFactory = sshExecutionEnvFactory({
|
|
@@ -367,7 +407,15 @@ export function createExecutionEnv(ctx) {
|
|
|
367
407
|
logger.info("task_inherit_env_honored", { honored: taskInheritEnvRefusal(config) === undefined });
|
|
368
408
|
}
|
|
369
409
|
const lspProvider = config.remoteExec?.provider;
|
|
370
|
-
const
|
|
410
|
+
const lspLane = executionLaneOf(lspProvider);
|
|
411
|
+
const lspLaneBindsReads = lspLane !== undefined && laneBindsReads(lspLane);
|
|
412
|
+
if ((lspProvider === "e2b" || lspProvider === "k8s") && config.lspEnabled && !lspLaneBindsReads) {
|
|
413
|
+
logger.warn("lsp_not_mounted", {
|
|
414
|
+
provider: lspProvider,
|
|
415
|
+
reason: "LSP_ENABLED is set, but this lane's execution environment cannot bind a read to the file that was checked (openBound), so every language-server file sync would be refused; the LSP tool is not mounted on this lane in this version",
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
const lspManager = (lspProvider === "e2b" || lspProvider === "k8s") && config.lspEnabled && lspLaneBindsReads
|
|
371
419
|
? createE2bLspManager({
|
|
372
420
|
log: (event, fields) => logger.info(event, fields),
|
|
373
421
|
scheme: lspProvider === "k8s" ? "ws" : "wss",
|
|
@@ -375,7 +423,7 @@ export function createExecutionEnv(ctx) {
|
|
|
375
423
|
metrics,
|
|
376
424
|
})
|
|
377
425
|
:
|
|
378
|
-
lspProvider === "host" && config.lspHostEnabled && config.requirePrincipal !== true
|
|
426
|
+
lspProvider === "host" && config.lspHostEnabled && config.requirePrincipal !== true && lspLaneBindsReads
|
|
379
427
|
? createHostLspManager(config, (event, fields) => logger.info(event, fields))
|
|
380
428
|
: undefined;
|
|
381
429
|
if (lspManager)
|
|
@@ -384,9 +432,7 @@ export function createExecutionEnv(ctx) {
|
|
|
384
432
|
perTaskImage, sessionEnvSelection, perSessionCwd, setSessionCwd, setSessionShellEnv, setSessionInheritEnv,
|
|
385
433
|
fenceSessionOwner: sessionScoped.fenceSessionOwner,
|
|
386
434
|
dropSessionScoped: sessionScoped.dropSession,
|
|
387
|
-
|
|
388
|
-
sessionIncarnationOf: sessionScoped.sessionIncarnationOf,
|
|
389
|
-
executionEnvFactory, worktreeReap, sendUserFileTaskEnvs, lspManager,
|
|
435
|
+
executionEnvFactory, worktreeReap, sendUserFileTaskEnvs, lspManager, spaceReclaimer,
|
|
390
436
|
};
|
|
391
437
|
}
|
|
392
438
|
//# sourceMappingURL=execution-env.js.map
|
package/dist/boot/leader.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ import type { buildPricing } from "../budget.js";
|
|
|
12
12
|
import { createLeaderEndpoint } from "../leader/endpoint.js";
|
|
13
13
|
import type { Logger } from "../observability/logger.js";
|
|
14
14
|
import type { CheckpointStoreFull, StoreBackend, ToolResultStoreFull } from "../plugins/store-backend.js";
|
|
15
|
+
import type { createSessionStore } from "../plugins/session-store.js";
|
|
15
16
|
import type { RunnerDeps } from "@sema-agent/core";
|
|
16
17
|
export interface LeaderCtx {
|
|
17
18
|
config: ServiceConfig;
|
|
@@ -20,7 +21,7 @@ export interface LeaderCtx {
|
|
|
20
21
|
pricing: ReturnType<typeof buildPricing>;
|
|
21
22
|
executionEnvFactory: RunnerDeps["executionEnvFactory"];
|
|
22
23
|
toolResultStore: ToolResultStoreFull | undefined;
|
|
23
|
-
sessionStore: ReturnType<
|
|
24
|
+
sessionStore: ReturnType<typeof createSessionStore>;
|
|
24
25
|
checkpointStore: CheckpointStoreFull | undefined;
|
|
25
26
|
/** [ref] 件B/C/D([ref],codex R2-F1):部署治理三座席 —— leader 车道的每一只 Runner 都要带上它,
|
|
26
27
|
* 否则开了 leader 端点的部署就有一条在部署治理**之外**的执行面(合规否决/锁都够不着)。 */
|
|
@@ -75,7 +75,7 @@ import type { MemoryEngineBackend } from "@sema-agent/settings-schema/execution-
|
|
|
75
75
|
* 而且它断言的是 per-task 事实,不是本键的车道级语义。
|
|
76
76
|
*
|
|
77
77
|
* ## 位置与纪律
|
|
78
|
-
* 单源:resolve-spec 的 spec 直通、`
|
|
78
|
+
* 单源:resolve-spec 的 spec 直通、`noPersistentMemoryNotice` 判别式、boot 审计的 declared 位
|
|
79
79
|
* 三处都必须读本函数,禁各自重算(operator-knob 律:显式 env 的优先权在这一个函数里执法一次)。
|
|
80
80
|
* 自动补位在 boot 日志上必须可见(stores.ts 的 info 行),部署方随时可用显式 env 覆盖。
|
|
81
81
|
*/
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import type { RestartSliceCtx } from "../web-admin-client/restart-signal.js";
|
|
2
2
|
import type { MemoryConsolidationDriverConfig, ServiceConfig } from "../config-types.js";
|
|
3
|
-
import { type ConsolidationDriverRunRow, type ConsolidationRunReceipt, type MemoryBackend, type MemoryConsolidationDriverDeps, type
|
|
3
|
+
import { resolveMemoryConsolidationDriver, type ConsolidationWriteJudge, type EngineNotice, type ConsolidationDriverRunRow, type ConsolidationRunReceipt, type MemoryBackend, type MemoryConsolidationDriverDeps, type SessionCaptureRecordStore } from "@sema-agent/core";
|
|
4
|
+
/**
|
|
5
|
+
* 座解析的 options 形 = core 解析器交回的那只(core 7.50.0 起它**不含** `writeJudge`:判官不是模型席的一部分,由调用方在动词上带)。
|
|
6
|
+
* 取解析器的返回型而不是自己写 `Omit<…>`:形的属主是 core 的解析器,本仓不持第二份。
|
|
7
|
+
*/
|
|
8
|
+
type ConsolidationSeatOptions = ReturnType<typeof resolveMemoryConsolidationDriver>;
|
|
4
9
|
/** D3 投影的座标签闭集。`role:<name>` 里的 name 只可能是 core 的 role 链两跳之一。 */
|
|
5
10
|
export type ConsolidationSeatLabel = "explicit" | "role:consolidate" | "role:summarize";
|
|
6
11
|
/** {@link buildConsolidationValveAudit} 的告警名闭集(事件名进日志 ⇒ 运维可按名过滤/告警)。 */
|
|
@@ -48,8 +53,8 @@ export type ConsolidationSeatBilling = {
|
|
|
48
53
|
};
|
|
49
54
|
/** 座解析的产物:core 的 options 原样 + 给投影用的两位自证。 */
|
|
50
55
|
export interface ConsolidationDriverSeat {
|
|
51
|
-
/** `runMemoryConsolidationDriver`
|
|
52
|
-
readonly options:
|
|
56
|
+
/** `runMemoryConsolidationDriver` 第三参的**模型席那一半**,core 的 `resolveMemoryConsolidationDriver` 原样产出(写判官另由操作面的座给)。 */
|
|
57
|
+
readonly options: ConsolidationSeatOptions;
|
|
53
58
|
/** D3 的 `seat` 位。 */
|
|
54
59
|
readonly seat: ConsolidationSeatLabel;
|
|
55
60
|
/** 真正会被记进 run 行与 mint 归档的模型 id(= `options.model`,单独拎出来是投影面的便利)。 */
|
|
@@ -390,6 +395,27 @@ export declare function assertAutoConsolidationWirable(input: {
|
|
|
390
395
|
/** 铸好的 `RunnerDeps` 上**真的**有整理席吗(`deps.memoryConsolidation !== undefined`)。 */
|
|
391
396
|
memoryConsolidationWired: boolean;
|
|
392
397
|
}): void;
|
|
398
|
+
/**
|
|
399
|
+
* 运维阀门腿的写判官座(core 7.50.0 起驱动动词必带)。
|
|
400
|
+
*
|
|
401
|
+
* ## 判官只有一只,这条腿拿不到它
|
|
402
|
+
*
|
|
403
|
+
* 「这条路径能不能写」在引擎里只有**一只**判官(合成写判官:技能拒行 / 收窄折叠 / 调用方与继承策略 / 人的持久规则车道 /
|
|
404
|
+
* 组织车道,一条走法一个优先序);引擎的自动整理腿把**腿自己的**那只交给驱动。本腿(运维手动阀门)没有腿:没有名册上的
|
|
405
|
+
* `Write` 脸、没有引擎盖的豁免根与工作目录、没有持久规则车道 —— 而引擎包今天不导出那只判官的构造器。在本仓手搭一只
|
|
406
|
+
* 「对部署策略问一次合成 `Write`」的判官 = 把引擎判官的层走法、脸、豁免根、已中止信号的约定与判词读法**再写一份**
|
|
407
|
+
* (第二个读者,与引擎那只迟早分歧,而且分歧是静默的)。所以本腿不造第二只。
|
|
408
|
+
*
|
|
409
|
+
* ## 于是它是一只**响亮的放行座**,登记为保护型欠账
|
|
410
|
+
*
|
|
411
|
+
* 答 `no_objection` —— 与 v7.49.x 本腿的行为逐字同(那时驱动根本不问),不回退任何现网能力;每被问一次记一次
|
|
412
|
+
* `server.memory-consolidation.operator-valve-unjudged`(P-DEBT:计数 + 探针行 + 一次性告警),债在遥测里显形。
|
|
413
|
+
* 自动整理腿不受影响:它走引擎腿自己的判官,人的持久规则与部署策略照判。
|
|
414
|
+
* 退役条件:引擎导出宿主可用的写判官构造器(收部署策略 + 一只规则店主体)那一版,本函数换成它、本 tag 删。
|
|
415
|
+
* scope 与人:本仓的文件后端不按请求主体铸 scope(单用户形是部署声明的全局层 `MEMORY_SCOPE` 与按任务根派生的项目层),
|
|
416
|
+
* 所以从 scope 读不出「这是谁的库」;匿名 run 读不读本地属主那只规则桶另候裁定 —— 两件都不在本座里猜。
|
|
417
|
+
*/
|
|
418
|
+
export declare function createOperatorValveWriteJudge(): ConsolidationWriteJudge;
|
|
393
419
|
/** 两个 admin 口消费的窄能力面(`ServiceDeps.memoryConsolidation` 的实参来源)。 */
|
|
394
420
|
export interface MemoryConsolidationFaces {
|
|
395
421
|
/** D3 的座位自证(投影用;boot 期解析一次,restart-to-apply)。 */
|
|
@@ -446,5 +472,13 @@ export declare function createMemoryConsolidationFaces(store: {
|
|
|
446
472
|
* 机器钉 capture-optout-lane ②)。S-215 起 local 车道在引擎接线时也供(core 文件三腿,同一只控制面);
|
|
447
473
|
* 缺席 ⇒ 记忆面暗(引擎未接线),与 Runner 同本。 */
|
|
448
474
|
captureRecordStore?: SessionCaptureRecordStore;
|
|
475
|
+
/** core 7.50.0:整理跑的**写判官座**(必填 —— 缺席不是「没有规则」,core 也拒)。操作面不判任何东西,只把它原样递给驱动动词:
|
|
476
|
+
* 早问库目录一次、应用时问每个产物文件,答 `no_objection` 以外一律拒写。装配层给哪一只见 {@link createOperatorValveWriteJudge}。 */
|
|
477
|
+
writeJudge: ConsolidationWriteJudge;
|
|
478
|
+
/** 引擎通告的**运维行**座(与 Runner 的 `onNotice` 同一只转发器)。缺席 ⇒ 通告只在回执上。判官拒的两种时机都经它走一次:
|
|
479
|
+
* 应用时拒 = 引擎在驱动里铸的 `memory.consolidation_incomplete`;早问拒 = 驱动抛出的拒绝经引擎导出的构造器转成的
|
|
480
|
+
* `memory.consolidation_refused`(本仓不读通告名、不自铸通告形)。 */
|
|
481
|
+
onNotice?: (notice: EngineNotice) => void;
|
|
449
482
|
}): MemoryConsolidationFaces;
|
|
483
|
+
export {};
|
|
450
484
|
//# sourceMappingURL=memory-consolidation.d.ts.map
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { redactSecrets } from "../trace/redact.js";
|
|
2
|
+
import { recordFailOpen } from "../observability/fail-open.js";
|
|
2
3
|
import { memoryMountRootOf } from "../memory-scope.js";
|
|
3
4
|
import { DEFAULT_MODEL_REF, resolveMainModel } from "../model-select.js";
|
|
4
5
|
import { backendOwnsControlPlane } from "../memory-operator-faces.js";
|
|
5
|
-
import { expandTiers, MemoryEngine, readConsolidationDriverRun, resolveMemoryConsolidationDriver, runMemoryConsolidationDriver, } from "@sema-agent/core";
|
|
6
|
+
import { CONSOLIDATION_WRITE_REFUSED_CODE, ConsolidationRefusedError, expandTiers, MemoryEngine, memoryConsolidationRefusedNotice, readConsolidationDriverRun, resolveMemoryConsolidationDriver, runMemoryConsolidationDriver, } from "@sema-agent/core";
|
|
6
7
|
export function resolveConsolidationDriverSeat(deps) {
|
|
7
8
|
let options;
|
|
8
9
|
try {
|
|
@@ -316,6 +317,12 @@ export function assertAutoConsolidationWirable(input) {
|
|
|
316
317
|
`unset, or set MEMORY_AUTO_CONSOLIDATION=off (unsetting it is NOT the same: the engine's named default is ON as of ` +
|
|
317
318
|
`core 7.21.1).`);
|
|
318
319
|
}
|
|
320
|
+
export function createOperatorValveWriteJudge() {
|
|
321
|
+
return () => {
|
|
322
|
+
recordFailOpen("server.memory-consolidation.operator-valve-unjudged");
|
|
323
|
+
return { verdict: "no_objection" };
|
|
324
|
+
};
|
|
325
|
+
}
|
|
319
326
|
export function createMemoryConsolidationFaces(store, input) {
|
|
320
327
|
const engine = new MemoryEngine({
|
|
321
328
|
backend: store.backend,
|
|
@@ -331,7 +338,16 @@ export function createMemoryConsolidationFaces(store, input) {
|
|
|
331
338
|
model: input.seat.model,
|
|
332
339
|
scopes: input.scopes,
|
|
333
340
|
run: (scope) => flight(scope, async () => {
|
|
334
|
-
const receipt = await runMemoryConsolidationDriver(engine, scope,
|
|
341
|
+
const receipt = await runMemoryConsolidationDriver(engine, scope, {
|
|
342
|
+
...input.seat.options,
|
|
343
|
+
writeJudge: input.writeJudge,
|
|
344
|
+
...(input.onNotice !== undefined ? { onNotice: input.onNotice } : {}),
|
|
345
|
+
}).catch((err) => {
|
|
346
|
+
if (input.onNotice !== undefined && err instanceof ConsolidationRefusedError && err.code === CONSOLIDATION_WRITE_REFUSED_CODE) {
|
|
347
|
+
input.onNotice(memoryConsolidationRefusedNotice({ code: err.code, scope, reason: err.message, ...(err.occurrenceId !== undefined ? { occurrenceId: err.occurrenceId } : {}) }));
|
|
348
|
+
}
|
|
349
|
+
throw err;
|
|
350
|
+
});
|
|
335
351
|
if (receipt.stopDetail !== undefined) {
|
|
336
352
|
input.onStopDetail?.(buildStopDetailAudit({ scope, runId: receipt.runId, outcome: receipt.outcome, stopDetail: receipt.stopDetail }));
|
|
337
353
|
}
|
|
@@ -72,9 +72,6 @@ export interface ParkedReviveGateDeps {
|
|
|
72
72
|
};
|
|
73
73
|
/** host 腿 cwd 占位的落地根(main.ts 的 `localRoot`;`config.localDataRoot` 优先)。 */
|
|
74
74
|
readonly localRoot: string;
|
|
75
|
-
/** S-133:守卫集 `dataRoot` = boot 已铸的引擎记忆根(`memoryEngine.root`,boot/stores.ts 单一写者),不在本腿重推导
|
|
76
|
-
* (重推导 = 第二个写者,7.59.0 重扫 codex 轮抓到 HTTP 腿 fallback 与 stores 不同源正是这一形)。`undefined` = 引擎未接。 */
|
|
77
|
-
readonly memoryEngineRoot: string | undefined;
|
|
78
75
|
/** 沙箱 lane 的真 env 登记簿。缺省 = 进程内唯一那只(工厂装饰器写的同一个);测试注入自建实例。 */
|
|
79
76
|
readonly slots?: SandboxPathEnvSlots;
|
|
80
77
|
}
|
|
@@ -11,7 +11,7 @@ function hostGateCwd(config, localRoot) {
|
|
|
11
11
|
return join(config.localDataRoot ?? localRoot, "parked-revive-unrooted");
|
|
12
12
|
}
|
|
13
13
|
export function createParkedReviveInheritedGate(deps) {
|
|
14
|
-
const { config, question, approvalExemptionStore, logger, localRoot, approverSeat
|
|
14
|
+
const { config, question, approvalExemptionStore, logger, localRoot, approverSeat } = deps;
|
|
15
15
|
const slots = deps.slots ?? sandboxPathEnvSlots;
|
|
16
16
|
return async (row, identity) => {
|
|
17
17
|
const metadata = await chainMetadataOf(deps, row, identity);
|
|
@@ -33,7 +33,7 @@ export function createParkedReviveInheritedGate(deps) {
|
|
|
33
33
|
question,
|
|
34
34
|
...(approvalExemptionStore !== undefined && rootSessionId ? { exemption: createDeploymentListExemption(approvalExemptionStore, rootSessionId, logger, "parked_revive") } : {}),
|
|
35
35
|
});
|
|
36
|
-
const governed = applyRuntimeGovernance({ objective: "", toolPolicy: baseline }, createDeploymentGovernanceInputs(config, pathAdjudication
|
|
36
|
+
const governed = applyRuntimeGovernance({ objective: "", toolPolicy: baseline }, createDeploymentGovernanceInputs(config, pathAdjudication));
|
|
37
37
|
return {
|
|
38
38
|
parentConstraints: [
|
|
39
39
|
{
|
|
@@ -39,8 +39,6 @@ export interface ResolveSpecCtx {
|
|
|
39
39
|
/** 两张 per-session 登记簿的**租户围栏**(codex R1-F1):每次提交对拍本会话的主人,换主即清。
|
|
40
40
|
* 论证(为什么 device lane 把这条从「不需要」变成「必需」)逐字见 `createSessionScopedRegistries` 头注。 */
|
|
41
41
|
fenceSessionOwner: (sid: string, owner: string | null) => void;
|
|
42
|
-
/** S-506([ref] §5):装配期化身读数的写腿(per-session 登记簿,与围栏同一只;记忆座同步从那里读)。 */
|
|
43
|
-
noteSessionIncarnation: (sid: string, incarnation: string | undefined) => void;
|
|
44
42
|
hookLlm: ReturnType<typeof createHookLlm>["hookLlm"];
|
|
45
43
|
hookAgent: HookLlmCall;
|
|
46
44
|
fleetBus: FleetEventBus;
|
|
@@ -7,7 +7,7 @@ import { SessionEnvironmentSelection, selectEnvironmentTool } from "../capabilit
|
|
|
7
7
|
import { sendUserFileTool } from "../capabilities/send-user-file-tool.js";
|
|
8
8
|
import { gateScenarioRequest, mergeUserSkills, selectScenario } from "../capabilities/scenarios.js";
|
|
9
9
|
import { stampHandsLane, toolPolicyForHands } from "../capabilities/hands-lane.js";
|
|
10
|
-
import { buildNoticeLaneFacts,
|
|
10
|
+
import { buildNoticeLaneFacts, noPersistentMemoryNotice, withNoPersistentMemoryNotice } from "../capabilities/memory-notice.js";
|
|
11
11
|
import { applyLongtailDefer } from "../capabilities/tool-defer.js";
|
|
12
12
|
import { assertGuardPatternsUsable, buildApprovalGrantNotice, buildOnlySensitiveBaselineWarning, createApprovalBaselinePolicy, createDeploymentGovernanceInputs } from "../deployment-governance.js";
|
|
13
13
|
import { createDeploymentListExemption, gateIntentUnserviceableReason, singleUserAutoAcceptBaselineApplies } from "../approval.js";
|
|
@@ -31,25 +31,23 @@ import { HttpError, createCodedHttpError, encodeCheckpointScope } from "../secur
|
|
|
31
31
|
import { memoryProjectKeyFor, memorySpecForRequest } from "../memory-scope.js";
|
|
32
32
|
import { inheritEnvFieldIssue, singleMemberOffFieldIssue } from "../request-value-closure.js";
|
|
33
33
|
import { a2aForScenario, mcpForScenario } from "../web-admin-client/facade.js";
|
|
34
|
-
import { normalizeAttachments, normalizeResilience, normalizeResumeAtMode, normalizeSuggestNextPrompts, promptProfileFromBody, resolveTaskLimits, retainBackgroundProcessesFromBody, taskAgentsSpecFragment, toolMaterializeStrategyFromBody, toolNameListFromBody } from "../spec-fields.js";
|
|
34
|
+
import { normalizeAttachments, normalizeResilience, normalizeResumeAtMode, normalizeSuggestNextPrompts, promptProfileFromBody, resolveTaskLimits, retainBackgroundProcessesFromBody, taskAgentsSpecFragment, toolMaterializeStrategyFromBody, allowToolsSpecFragment, toolNameListFromBody } from "../spec-fields.js";
|
|
35
35
|
import { isAbsoluteHostPath } from "@sema-agent/settings-schema";
|
|
36
36
|
import { cwdHonored, deviceCwdHonored, effectiveHostWorkspace, inProcessSingleUserLane, parseAdditionalDirectories, satisfiedByProcessCwd, shellEnvMismatchCount } from "../task-cwd.js";
|
|
37
37
|
import { assertRequestA2aUnlocked, resolveRequestA2a } from "../task-a2a.js";
|
|
38
38
|
import { assertRequestMcpContentOrigin, assertRequestMcpUnlocked, resolveRequestMcp } from "../task-mcp.js";
|
|
39
39
|
import { MAX_SETTINGS_OUTPUT_STYLE_CHARS, acceptAppendSystemPrompt, applyTaskSettings, effectivePermissionMode, effectiveThinking, hasConstitutionAnchors, parseTaskSettings, taskHooksHonored, providerDropsAppend, settingsPermissionBucketIssue, withPermissionMode } from "../task-settings.js";
|
|
40
40
|
import { skillDenyInertEntryOf } from "../rule-entry-list.js";
|
|
41
|
-
import { enableForkFromBody, normalizeRetainSubagentSessions, selfOrchestrationFromBody } from "../task-workflow.js";
|
|
41
|
+
import { TENANCY_WALL_CLOCK_BASE_SEC, enableForkFromBody, normalizeRetainSubagentSessions, selfOrchestrationFromBody } from "../task-workflow.js";
|
|
42
42
|
import { redactSecrets } from "../trace/redact.js";
|
|
43
43
|
import { DeferredSandboxPathEnv, isSandboxPathAdjudicationLane, sandboxPathEnvSlots } from "./deferred-sandbox-path-env.js";
|
|
44
44
|
import { executionLaneCaps, executionLaneHomeDir, executionLaneOf } from "../execution-lane-caps.js";
|
|
45
45
|
import { effectiveMemoryPersistenceCapable } from "./memory-boundary.js";
|
|
46
46
|
import { withUnattendedLeg } from "../unattended-permission-mode.js";
|
|
47
47
|
import { memoryFaceMounted } from "../memory-scope.js";
|
|
48
|
-
import { createAssemblyIncarnationRead, sessionFaceReaderOf } from "./session-incarnation-seat.js";
|
|
49
48
|
export function createResolveSpec(ctx) {
|
|
50
|
-
const { config, logger, metrics, localRoot, scenarios, principalCaps, centerRuntimeCapsResolver, getCenterPrompts, getKeyResolver, taskAttachmentStore, perSessionCwd, setSessionCwd, setSessionShellEnv, fenceSessionOwner,
|
|
49
|
+
const { config, logger, metrics, localRoot, scenarios, principalCaps, centerRuntimeCapsResolver, getCenterPrompts, getKeyResolver, taskAttachmentStore, perSessionCwd, setSessionCwd, setSessionShellEnv, fenceSessionOwner, hookLlm, hookAgent, fleetBus, hookWakeBus, resumeAnchorStore, ownerAware, taskLimitCaps, taskTimeoutSec, selectEnvTool, sendUserFileToolSpec, memoryEngine, durableEnabled, approvalExemptionStore, checkpointStore, deploymentHooks, imageIndex, perTaskImage, sessionEnvSelection, liveQuestionFace, approverSeat, lockedKeys, } = ctx;
|
|
51
50
|
assertGuardPatternsUsable(config);
|
|
52
|
-
const assemblyIncarnationRead = createAssemblyIncarnationRead(sessionFaceReaderOf(ownerAware), (e, f) => logger.warn(e, f));
|
|
53
51
|
const onlySensitiveBaseline = buildOnlySensitiveBaselineWarning(config, {
|
|
54
52
|
approvalSeat: durableEnabled ? "durable" : "absent",
|
|
55
53
|
singleUserAutoAcceptBaseline: singleUserAutoAcceptBaselineApplies(config),
|
|
@@ -124,8 +122,6 @@ export function createResolveSpec(ctx) {
|
|
|
124
122
|
throw new HttpError(422, why, { code: HOST_POSTURE_REFUSED_CODE });
|
|
125
123
|
}
|
|
126
124
|
const lane = bindSettingsCwdEnvAndModel(body, auth, gated, opts);
|
|
127
|
-
if (auth?.sessionId && assemblyIncarnationRead)
|
|
128
|
-
noteSessionIncarnation(auth.sessionId, await assemblyIncarnationRead(auth.sessionId));
|
|
129
125
|
const anchors = await resolveHistoryAnchors(body, auth);
|
|
130
126
|
const spec = assembleSpecLiteral(body, auth, req, opts, { ...gated, ...lane, ...anchors }, effMode);
|
|
131
127
|
const folded = await foldGovernanceAndSettings(body, auth, spec, gated, effMode);
|
|
@@ -368,6 +364,7 @@ export function createResolveSpec(ctx) {
|
|
|
368
364
|
: {}),
|
|
369
365
|
...(body.excludeAllTools === true ? { excludeAllTools: true } : {}),
|
|
370
366
|
...(() => { const v = toolNameListFromBody(body.excludeTools); return v ? { excludeTools: v } : {}; })(),
|
|
367
|
+
...allowToolsSpecFragment(body.allowTools),
|
|
371
368
|
...(() => { const v = toolNameListFromBody(body.deferTools); return v ? { deferTools: v } : {}; })(),
|
|
372
369
|
...(() => { const v = promptProfileFromBody(body.promptProfile); return v ? { promptProfile: v } : {}; })(),
|
|
373
370
|
...(() => { const v = toolMaterializeStrategyFromBody(body.toolMaterializeStrategy); return v ? { toolMaterializeStrategy: v } : {}; })(),
|
|
@@ -409,7 +406,7 @@ export function createResolveSpec(ctx) {
|
|
|
409
406
|
thinking: effectiveThinking(body.reasoningEffort, parsedSettings.settings?.ultracode === true),
|
|
410
407
|
getApiKeyAndHeaders: getKeyResolver(),
|
|
411
408
|
...(() => {
|
|
412
|
-
const limits = resolveTaskLimits(body.limits, taskLimitCaps, taskTimeoutSec, config.requirePrincipal,
|
|
409
|
+
const limits = resolveTaskLimits(body.limits, taskLimitCaps, taskTimeoutSec, config.requirePrincipal, (event, fields) => logger.warn(event, { ...fields, sessionId: auth?.sessionId ?? null }));
|
|
413
410
|
const declarations = [];
|
|
414
411
|
if (taskLimitCaps.timeoutSec !== undefined)
|
|
415
412
|
declarations.push({ key: "server.limits.timeoutSecCap", value: String(taskLimitCaps.timeoutSec), reason: "env TASK_TIMEOUT_MAX_SEC (seconds; operator ceiling applied to caller limits.maxWalltimeMs as cap×1000)" });
|
|
@@ -422,7 +419,7 @@ export function createResolveSpec(ctx) {
|
|
|
422
419
|
if (config.maxTaskTokens > 0)
|
|
423
420
|
declarations.push({ key: "server.budget.maxTokensCap", value: String(config.maxTaskTokens), reason: "env MAX_TASK_TOKENS_MAX (operator ceiling; becomes the effective value when the caller sends none)" });
|
|
424
421
|
if (config.requirePrincipal === true)
|
|
425
|
-
declarations.push({ key: "server.limits.wallClockBaseSec", value:
|
|
422
|
+
declarations.push({ key: "server.limits.wallClockBaseSec", value: String(TENANCY_WALL_CLOCK_BASE_SEC), reason: "tenancy wall-clock base (multi-tenant) — TASK_TIMEOUT_SEC raises, never shrinks" });
|
|
426
423
|
const maxCostUsd = cappedCeiling(body.maxCostUsd, config.maxTaskCostUsd);
|
|
427
424
|
const maxTokens = cappedCeiling(body.maxTokens, config.maxTaskTokens);
|
|
428
425
|
const degrade = (() => {
|
|
@@ -518,7 +515,7 @@ export function createResolveSpec(ctx) {
|
|
|
518
515
|
}),
|
|
519
516
|
...laneHomeBase(),
|
|
520
517
|
};
|
|
521
|
-
const governedBase = applyRuntimeGovernance(spec, createDeploymentGovernanceInputs(config, pathAdjudication
|
|
518
|
+
const governedBase = applyRuntimeGovernance(spec, createDeploymentGovernanceInputs(config, pathAdjudication));
|
|
522
519
|
let governed = governedBase;
|
|
523
520
|
let effectiveSettings = effMode ? withPermissionMode(parsedSettings.settings, effMode) : parsedSettings.settings;
|
|
524
521
|
if (appendLessPack && effectiveSettings?.outputStyle) {
|
|
@@ -600,16 +597,15 @@ export function createResolveSpec(ctx) {
|
|
|
600
597
|
throw new HttpError(422, `request settings cannot be applied as written: ${e.message}`);
|
|
601
598
|
}
|
|
602
599
|
}
|
|
603
|
-
|
|
600
|
+
const notice = noPersistentMemoryNotice({
|
|
604
601
|
memoryFaceMounted: memoryFaceMounted(governed.memory),
|
|
605
602
|
declaredCapable: effectiveMemoryPersistenceCapable(config),
|
|
606
603
|
hands: gated.hands,
|
|
607
604
|
handsReadOnly: governed.handsReadOnly === true,
|
|
608
|
-
excludeAllTools: governed.excludeAllTools === true,
|
|
609
|
-
excludeTools: governed.excludeTools,
|
|
610
605
|
...buildNoticeLaneFacts(executionLaneOf(config.remoteExec?.provider)),
|
|
611
|
-
})
|
|
612
|
-
|
|
606
|
+
});
|
|
607
|
+
if (notice !== "silent") {
|
|
608
|
+
governed = { ...governed, promptProvider: withNoPersistentMemoryNotice(governed.promptProvider, notice) };
|
|
613
609
|
}
|
|
614
610
|
return { governed, scratchpadDir, hostSemanticsLane };
|
|
615
611
|
};
|
|
@@ -667,7 +663,6 @@ export function createResolveSpec(ctx) {
|
|
|
667
663
|
isolatedExecEnv,
|
|
668
664
|
hasExecutionEnv: executionLaneCaps(executionLaneOf(config.remoteExec?.provider)).coreRemoteExecutionEnv === "supported",
|
|
669
665
|
...(config.autonomy ? { autonomy: config.autonomy } : {}),
|
|
670
|
-
explicitTeam: body.council === true || body.debate === true || scenarioName === "discuss",
|
|
671
666
|
});
|
|
672
667
|
logger.info("orchestration_routed", { mode: decision.mode, reason: decision.reason, sessionId: auth?.sessionId ?? null });
|
|
673
668
|
if (decision.mode === "supervisor") {
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
*/
|
|
32
32
|
import type { RetentionPolicy, RetentionReceipt } from "@sema-agent/core";
|
|
33
33
|
import type { RetentionMode } from "../config-types.js";
|
|
34
|
+
import type { EndedSpace, SpaceReclaimer } from "../workspace-space.js";
|
|
34
35
|
/** 同 domain 连续失败多少次算「卡住了」(fail-loud 的阈值)。`5` 与 reaper 家族的
|
|
35
36
|
* `REAPER_FAILURE_WARN_THRESHOLD` 同值同理由:一次抖动(一次重连、一次超时)正是容错要吸收的,
|
|
36
37
|
* 只有**连败**才越过「可诊断」这条线。 */
|
|
@@ -56,7 +57,7 @@ export interface RetentionExecutor {
|
|
|
56
57
|
toolResults: number;
|
|
57
58
|
}>;
|
|
58
59
|
expireCheckpoints(input: RetentionDestructiveInput): Promise<RetentionReceipt>;
|
|
59
|
-
deleteExpiredSessions(input: RetentionDestructiveInput): Promise<
|
|
60
|
+
deleteExpiredSessions(input: RetentionDestructiveInput): Promise<RetentionSessionsReceipt>;
|
|
60
61
|
deleteOrphanToolResults(input: RetentionDestructiveInput): Promise<RetentionReceipt>;
|
|
61
62
|
}
|
|
62
63
|
/** 破坏性调用的入参(判定时点的三格随行 —— 理由逐字见车1 `RetentionAuditContext` 的头注)。 */
|
|
@@ -127,7 +128,17 @@ export interface RetentionSweepCtx {
|
|
|
127
128
|
* `createThrottledReaperCatch` 必须建在 `setInterval` 之外是同一条理由。
|
|
128
129
|
*/
|
|
129
130
|
streaks?: Map<string, number>;
|
|
131
|
+
/** 结束的空间的回收座(k8s 车道 ∧ 配了缓存卷或快照存储时在场;与会话删除协调器同一只):enforce 删掉会话树之后,把回执里结束了的空间交给它
|
|
132
|
+
* (缓存卷、`space/` 快照、该会话停驻车道的快照一并回收)。它从不抛(失败 = 一行 + fail-open 计数);缺席 = 本部署没有可回收的东西。 */
|
|
133
|
+
spaceReclaimer?: SpaceReclaimer;
|
|
130
134
|
}
|
|
135
|
+
/**
|
|
136
|
+
* 会话树 sweep 的回执 = core 契约的 `RetentionReceipt` + 本仓一位:`endedSpaces` = 本次删掉的会话树里**结束了的空间**(会话 id + 住客空间键 = 会话化身;
|
|
137
|
+
* 读不出住客的空化身不算),present-iff 非空。lane 把它交给空间的回收座(与会话删除协调器同一只),缓存卷与快照随空间的终结回收。
|
|
138
|
+
*/
|
|
139
|
+
export type RetentionSessionsReceipt = RetentionReceipt & {
|
|
140
|
+
readonly endedSpaces?: readonly EndedSpace[];
|
|
141
|
+
};
|
|
131
142
|
/** 一轮的读数(给日志与判据用;lane 自己不做任何决策依赖它)。 */
|
|
132
143
|
export interface RetentionSweepOutcome {
|
|
133
144
|
/** 本轮真正处理完的 domain 数(丢租中止时 = 中止之前那些)。 */
|
|
@@ -99,6 +99,8 @@ async function sweepDomainEnforce(ctx, d) {
|
|
|
99
99
|
};
|
|
100
100
|
const checkpoints = await ctx.executor.expireCheckpoints(input);
|
|
101
101
|
const sessions = await ctx.executor.deleteExpiredSessions(input);
|
|
102
|
+
if (sessions.endedSpaces !== undefined && ctx.spaceReclaimer !== undefined)
|
|
103
|
+
await ctx.spaceReclaimer.reclaim(sessions.endedSpaces);
|
|
102
104
|
const toolResults = await ctx.executor.deleteOrphanToolResults(input);
|
|
103
105
|
const touched = checkpoints.deleted + sessions.deleted + toolResults.deleted;
|
|
104
106
|
if (touched > 0) {
|