@sema-agent/server 7.139.0 → 7.140.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 +181 -0
- package/USAGE.md +19 -13
- package/dist/adoption/runner.js +1 -1
- package/dist/adoption/sql.js +1 -1
- package/dist/approval-card.d.ts +6 -6
- package/dist/bench/s1/live-deps.js +3 -2
- package/dist/bench/s1/row.d.ts +5 -2
- package/dist/bench/s1/row.js +2 -22
- package/dist/boot/adoption.js +1 -1
- package/dist/boot/execution-env.js +12 -10
- package/dist/boot/execution-lane.d.ts +8 -0
- package/dist/boot/execution-lane.js +6 -1
- package/dist/boot/memory-boundary.d.ts +14 -51
- package/dist/boot/memory-boundary.js +10 -20
- package/dist/boot/memory-consolidation.d.ts +15 -11
- package/dist/boot/memory-consolidation.js +23 -12
- package/dist/boot/resolve-spec.d.ts +3 -5
- package/dist/boot/resolve-spec.js +2 -4
- package/dist/boot/runner-deps.d.ts +3 -3
- package/dist/boot/runner-deps.js +1 -0
- package/dist/boot/stage-03-store-backend.d.ts +2 -6
- package/dist/boot/stage-03-store-backend.js +2 -3
- package/dist/boot/stage-04-stores.d.ts +2 -6
- package/dist/boot/stage-04-stores.js +5 -5
- package/dist/boot/stage-05-execution-env.d.ts +2 -6
- package/dist/boot/stage-06-runners.d.ts +2 -6
- package/dist/boot/stage-06-runners.js +2 -2
- package/dist/boot/stage-07-capability-layer.d.ts +2 -6
- package/dist/boot/stage-08-reapers.d.ts +2 -6
- package/dist/boot/stage-09-leader.d.ts +2 -6
- package/dist/boot/stage-10-http-server.d.ts +2 -6
- package/dist/boot/stage-10-http-server.js +5 -4
- package/dist/boot/stores.d.ts +3 -6
- package/dist/boot/stores.js +27 -40
- package/dist/boot/task-list-lane.d.ts +1 -1
- package/dist/boot/task-list-lane.js +1 -1
- package/dist/boot/web-admin.js +35 -9
- package/dist/capabilities/execution-lane.d.ts +2 -2
- package/dist/config-catalog.js +2 -1
- package/dist/config-provider.d.ts +14 -13
- package/dist/config-provider.js +24 -18
- package/dist/config-types.d.ts +11 -2
- package/dist/config.js +2 -1
- package/dist/delegated-session-owner.d.ts +2 -1
- package/dist/delegated-session-owner.js +1 -1
- package/dist/deployment-shape.d.ts +9 -8
- package/dist/deployment-shape.js +4 -4
- package/dist/execution-lane-caps.d.ts +97 -106
- package/dist/execution-lane-caps.js +67 -83
- package/dist/http/memory-compliance-failure-reply.d.ts +3 -1
- package/dist/http/memory-compliance-failure-reply.js +5 -0
- package/dist/http/memory-layer-reply.d.ts +30 -0
- package/dist/http/memory-layer-reply.js +24 -0
- package/dist/http/resume-legs.js +13 -16
- package/dist/http/retired-service-deps.d.ts +1 -1
- package/dist/http/retired-service-deps.js +1 -1
- package/dist/http/routes/adoption.js +1 -1
- package/dist/http/routes/memory-bundle.js +3 -0
- package/dist/http/routes/memory-compliance.js +8 -1
- package/dist/http/routes/memory-consolidation.js +12 -1
- package/dist/http/routes/memory-origin.js +14 -2
- package/dist/http/routes/memory-policy.js +5 -0
- package/dist/http/routes/sessions.js +28 -11
- package/dist/http/routes/tasks.js +4 -2
- package/dist/http/server.d.ts +5 -25
- package/dist/http/server.js +2 -2
- package/dist/identity-source.d.ts +1 -1
- package/dist/identity-source.js +1 -1
- package/dist/lane-home-probe.d.ts +68 -42
- package/dist/lane-home-probe.js +53 -30
- package/dist/leader/wire.js +5 -4
- package/dist/memory-bundle-engine.d.ts +16 -9
- package/dist/memory-bundle-engine.js +29 -6
- package/dist/memory-operator-faces.d.ts +85 -30
- package/dist/memory-operator-faces.js +136 -30
- package/dist/memory-project-layer.d.ts +3 -21
- package/dist/memory-project-layer.js +11 -8
- package/dist/memory-scope-stores.d.ts +73 -0
- package/dist/memory-scope-stores.js +86 -0
- package/dist/memory-scope.d.ts +29 -5
- package/dist/memory-scope.js +16 -4
- package/dist/memory-sync-client.d.ts +20 -7
- package/dist/memory-sync-client.js +31 -13
- package/dist/plugins/adoption-log-sql.js +4 -4
- package/dist/plugins/approval-ask-store-sql.js +14 -14
- package/dist/plugins/approval-nonce-store.js +4 -4
- package/dist/plugins/blob-backend.d.ts +4 -4
- package/dist/plugins/blob-backend.js +7 -7
- package/dist/plugins/breaker-state-sql.js +2 -2
- package/dist/plugins/checkpoint-index-columns.js +2 -2
- package/dist/plugins/checkpoint-store-sql.js +16 -16
- package/dist/plugins/device-store-sql.js +19 -19
- package/dist/plugins/ensure-index.d.ts +1 -2
- package/dist/plugins/execution-placement-sql.d.ts +8 -8
- package/dist/plugins/execution-placement-sql.js +8 -8
- package/dist/plugins/file-history-store-sql.d.ts +2 -2
- package/dist/plugins/file-history-store-sql.js +4 -4
- package/dist/plugins/image-bake-store-sql.js +9 -9
- package/dist/plugins/image-index-sql.js +11 -11
- package/dist/plugins/leader-run-store-sql.js +4 -4
- package/dist/plugins/mailbox-store-sql.d.ts +2 -1
- package/dist/plugins/mailbox-store-sql.js +4 -4
- package/dist/plugins/memory-engine-tidb.js +5 -5
- package/dist/plugins/memory-optout-grant-store-sql.js +1 -1
- package/dist/plugins/memory-sync-store-tidb.js +3 -3
- package/dist/plugins/one-time-migrations.d.ts +10 -9
- package/dist/plugins/one-time-migrations.js +36 -36
- package/dist/plugins/org-delivery-quota-store.js +2 -2
- package/dist/plugins/outcome-ledger-sql.js +2 -2
- package/dist/plugins/permission-rule-store-sql.d.ts +4 -4
- package/dist/plugins/permission-rule-store-sql.js +16 -16
- package/dist/plugins/remote-env-adb.d.ts +7 -24
- package/dist/plugins/remote-env-adb.js +22 -5
- package/dist/plugins/remote-env-device.d.ts +2 -28
- package/dist/plugins/remote-env-device.js +2 -1
- package/dist/plugins/remote-env-e2b.d.ts +18 -26
- package/dist/plugins/remote-env-e2b.js +51 -4
- package/dist/plugins/remote-env-file-error.d.ts +1 -1
- package/dist/plugins/remote-env-file-error.js +8 -2
- package/dist/plugins/remote-env-host.d.ts +19 -35
- package/dist/plugins/remote-env-host.js +26 -3
- package/dist/plugins/remote-env-k8s.d.ts +3 -14
- package/dist/plugins/remote-env-k8s.js +3 -2
- package/dist/plugins/remote-env-local-docker.d.ts +4 -15
- package/dist/plugins/remote-env-local-docker.js +5 -4
- package/dist/plugins/remote-env-ssh.d.ts +4 -24
- package/dist/plugins/remote-env-ssh.js +4 -3
- package/dist/plugins/resume-anchor-store-sql.js +2 -2
- package/dist/plugins/retention-lane-store-sql.d.ts +1 -1
- package/dist/plugins/retention-lane-store-sql.js +2 -2
- package/dist/plugins/retention-store-sql.d.ts +1 -1
- package/dist/plugins/retention-store-sql.js +6 -6
- package/dist/plugins/run-store-sql.js +15 -15
- package/dist/plugins/schema-consistency.d.ts +6 -6
- package/dist/plugins/schema-consistency.js +1 -1
- package/dist/plugins/schema-ensure-legs.d.ts +2 -3
- package/dist/plugins/schema-ensure-legs.js +2 -2
- package/dist/plugins/schema-live-columns.d.ts +1 -1
- package/dist/plugins/session-capture-record-store-sql.js +1 -1
- package/dist/plugins/session-rules-column.d.ts +1 -1
- package/dist/plugins/session-rules-column.js +1 -1
- package/dist/plugins/session-workspace-cell.d.ts +1 -1
- package/dist/plugins/session-workspace-cell.js +1 -1
- package/dist/plugins/shared-memory-store-sql.js +2 -2
- package/dist/plugins/sql-driver.d.ts +10 -5
- package/dist/plugins/sql-driver.js +6 -6
- package/dist/plugins/sql-errors.js +1 -1
- package/dist/plugins/store-backend.d.ts +4 -6
- package/dist/plugins/store-backend.js +6 -6
- package/dist/plugins/task-list-store-sql.js +11 -11
- package/dist/plugins/tidb-pool.js +5 -5
- package/dist/plugins/tidb-session-storage.js +4 -4
- package/dist/plugins/tidb-session-store.js +13 -13
- package/dist/plugins/tool-result-store-sql.d.ts +2 -2
- package/dist/plugins/tool-result-store-sql.js +3 -3
- package/dist/plugins/user-input-ledger-sql.js +2 -2
- package/dist/plugins/workflow-journal-store-sql.js +5 -5
- package/dist/plugins/workflow-run-store-sql.js +19 -19
- package/dist/plugins/write-behind-counter.d.ts +2 -3
- package/dist/plugins/write-behind-counter.js +5 -5
- package/dist/resource-suspend.d.ts +14 -12
- package/dist/resource-suspend.js +1 -1
- package/dist/resource-window.d.ts +4 -3
- package/dist/run-local.js +14 -19
- package/dist/runs.d.ts +8 -4
- package/dist/runs.js +49 -65
- package/dist/session-incarnation.d.ts +1 -1
- package/dist/session-incarnation.js +1 -1
- package/dist/session-policy-wire.d.ts +1 -1
- package/dist/sql-engine-posture.d.ts +1 -1
- package/dist/sql-engine-posture.js +1 -1
- package/dist/{plugins → stores-sql}/background-agent-store-sql.d.ts +2 -2
- package/dist/{plugins → stores-sql}/background-agent-store-sql.js +8 -8
- package/dist/{plugins → stores-sql}/session-policy-store-sql.d.ts +7 -5
- package/dist/{plugins → stores-sql}/session-policy-store-sql.js +12 -12
- package/dist/{plugins → stores-sql}/usage-window-store-sql.d.ts +1 -1
- package/dist/{plugins → stores-sql}/usage-window-store-sql.js +3 -3
- package/dist/task-a2a.js +5 -6
- package/dist/task-mcp.d.ts +20 -7
- package/dist/task-mcp.js +17 -9
- package/dist/terminal.d.ts +27 -0
- package/dist/terminal.js +6 -0
- package/dist/trace/redact.d.ts +3 -1
- package/dist/trace/redact.js +80 -28
- package/dist/trace/self-minted-wire.d.ts +58 -0
- package/dist/trace/self-minted-wire.js +16 -0
- package/dist/web-admin-client/candidate-gate.d.ts +11 -7
- package/dist/web-admin-client/candidate-gate.js +1 -1
- package/dist/web-admin-client/http-client.d.ts +5 -4
- package/dist/web-admin-client/http-client.js +2 -2
- package/dist/web-admin-client/read-warnings.d.ts +7 -17
- package/dist/web-admin-client/read-warnings.js +5 -9
- package/package.json +2 -2
- package/wire-changes/server@7.140.0.json +184 -0
|
@@ -3,6 +3,7 @@ import { logStoreFormRefusal, storeFormRefusalOf } from "../memory-store-refusal
|
|
|
3
3
|
import { sentMemoryStoreRefusal } from "./memory-store-refusal-reply.js";
|
|
4
4
|
import { sendError } from "./send.js";
|
|
5
5
|
import { assertNever } from "./route-ctx.js";
|
|
6
|
+
import { MemoryErasureStoreUnjudged } from "../memory-operator-faces.js";
|
|
6
7
|
function sentCoreCode(res, coreCode, coreMessage, audience) {
|
|
7
8
|
switch (coreCode) {
|
|
8
9
|
case "config.memory_erasure_request":
|
|
@@ -42,6 +43,10 @@ function codeOf(err) {
|
|
|
42
43
|
return typeof code === "string" ? code : undefined;
|
|
43
44
|
}
|
|
44
45
|
export function sentMemoryComplianceFailure(res, err, audience, logger) {
|
|
46
|
+
if (err instanceof MemoryErasureStoreUnjudged) {
|
|
47
|
+
sendError(res, 409, "memory.erasure_store_unjudged", textFor(audience, err.message, "session memory erasure refused — this erasure reaches memory kept in this deployment's second memory store, which this build does not erase from (an erasure requestId is judged on the deployment's main store only); nothing was erased — it becomes available with the next engine update, or ask the operator"));
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
45
50
|
const coreCode = codeOf(err);
|
|
46
51
|
if (coreCode !== undefined && sentCoreCode(res, coreCode, err instanceof Error ? err.message : String(err), audience))
|
|
47
52
|
return true;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 记忆动词的**层座**与「这次请求落不到一只记忆店」的拒 —— 两件的 HTTP 半场,唯一一处。
|
|
3
|
+
*
|
|
4
|
+
* ## 规则(店的那一半在 `src/memory-scope-stores.ts`)
|
|
5
|
+
* 一次记忆请求只落一只店:请求点名的层住的那一只;不点名层的动词(条目 id / 店级账本)答在本部署点名的层与部署的店共处的那一只上,
|
|
6
|
+
* 两只店分住时不猜、拒。会话 id 的两口不点名层时不拒:记忆状态读本部署的每一只店再折成一份,按会话抹除落部署的店(`memory-operator-faces.ts`)。
|
|
7
|
+
* 不点名层的动词因此多一个可选的**层座** `scope`:GET 口在查询串(`?scope=<层键>`),POST 口在体里(`"scope": "<层键>"`);
|
|
8
|
+
* 点名的层只用来定店,动词本身的语义不变。点名层的动词(导出 / 导入 / 外源列表 / 整理 / operator 抹除的 `select.scope` 与 `expectedScopes`)
|
|
9
|
+
* 本来就点名,不加座。
|
|
10
|
+
*
|
|
11
|
+
* ## 层座的读法({@link readLayerSeat})
|
|
12
|
+
* 缺席 ⇒ 没点名;在场 ⇒ 必须是非空串,否则 400 `request.field_invalid`、面一次都不调(空串与非串不是「没点名」—— 静默当缺席会把请求答在
|
|
13
|
+
* 另一只店上)。
|
|
14
|
+
*
|
|
15
|
+
* ## 拒的映射({@link sentMemoryLayerRefusal})
|
|
16
|
+
* `MemoryLayerRefusal` ⇒ 400 `request.memory_layer`:请求可以改对(点名层 / 按店拆成几次),服务器没坏,也不是盘形问题。
|
|
17
|
+
* 文案按受众分(与 `memory-compliance-failure-reply.ts` 同一条规则):operator ⇒ 原句(点名部署配置的层、哪几层住在哪只店 —— 运维要的就是它);
|
|
18
|
+
* 会话所有者 ⇒ 固定一句(只说怎么办),原句交 `withheld` 落运维行 —— 部署配置的层键不是这个受众的材料。
|
|
19
|
+
*/
|
|
20
|
+
import type { ServerResponse } from "node:http";
|
|
21
|
+
import type { MemoryLayerSeat } from "../memory-operator-faces.js";
|
|
22
|
+
import type { MemoryComplianceAudience } from "./memory-compliance-failure-reply.js";
|
|
23
|
+
/**
|
|
24
|
+
* 层座:`present` = 键在不在(查询串 `has` / 体 `in`),`value` = 它的值。缺席 ⇒ `undefined`;非空串 ⇒ `{ layer }`;
|
|
25
|
+
* 其余 ⇒ 已答 400 `request.field_invalid`,返回 `null`(调用方 `return`)。
|
|
26
|
+
*/
|
|
27
|
+
export declare function readLayerSeat(res: ServerResponse, present: boolean, value: unknown): MemoryLayerSeat | undefined | null;
|
|
28
|
+
/** `err` 是本服务的层拒 ⇒ 400 `request.memory_layer`(文案按受众),返回 true;否则 false,一个字节都不写。 */
|
|
29
|
+
export declare function sentMemoryLayerRefusal(res: ServerResponse, err: unknown, audience: MemoryComplianceAudience): boolean;
|
|
30
|
+
//# sourceMappingURL=memory-layer-reply.d.ts.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { MemoryLayerRefusal } from "../memory-scope-stores.js";
|
|
2
|
+
import { sendError } from "./send.js";
|
|
3
|
+
export function readLayerSeat(res, present, value) {
|
|
4
|
+
if (!present)
|
|
5
|
+
return undefined;
|
|
6
|
+
if (typeof value === "string" && value.length > 0)
|
|
7
|
+
return { layer: value };
|
|
8
|
+
sendError(res, 400, "request.field_invalid", "scope must be a non-empty memory layer key when present — it names the layer whose memory store this request is answered on");
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
export function sentMemoryLayerRefusal(res, err, audience) {
|
|
12
|
+
if (!(err instanceof MemoryLayerRefusal))
|
|
13
|
+
return false;
|
|
14
|
+
switch (audience.kind) {
|
|
15
|
+
case "operator":
|
|
16
|
+
sendError(res, 400, "request.memory_layer", err.message);
|
|
17
|
+
return true;
|
|
18
|
+
case "session_owner":
|
|
19
|
+
audience.withheld(err.message);
|
|
20
|
+
sendError(res, 400, "request.memory_layer", "the memory store this request reaches cannot be told — the `scope` in the request is not a memory layer this deployment can read, or this deployment's own memory layer configuration cannot be read; resend without `scope` (or with a readable layer), or ask the operator");
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=memory-layer-reply.js.map
|
package/dist/http/resume-legs.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { redactErrorMessage, redactHead } from "../observability/run-terminal.js";
|
|
2
2
|
import { createHash } from "node:crypto";
|
|
3
|
-
import { uuidv7, resumeWithVerification, CheckpointError, defaultTaskRegistry, taskNotificationDedupKey, validatePendingSteer, GLOBAL_USAGE_KEY
|
|
3
|
+
import { uuidv7, resumeWithVerification, CheckpointError, defaultTaskRegistry, taskNotificationDedupKey, validatePendingSteer, GLOBAL_USAGE_KEY } from "@sema-agent/core";
|
|
4
4
|
import { decideParkedAgent, denyWorkflowParkForked, denyWorkflowParksUnreadable, findParkOrigin, heldWorkflowParkDecisions, planWorkflowParkedDecide } from "../parked-decide.js";
|
|
5
5
|
import { parkDecisionFingerprint } from "../orchestration/workflow-park-decision.js";
|
|
6
6
|
import { headReadOf } from "../session-incarnation.js";
|
|
@@ -8,7 +8,7 @@ import { createSessionWorkspaceRecorder, legSessionWitnessOf, sessionWorkspaceSt
|
|
|
8
8
|
const DELIVERY_NOT_RECORDED = "workflow park decide: this delivery no longer holds the host session (its claim was released) — the decision was not recorded and this delivery was not started";
|
|
9
9
|
import { HttpError, decodeCheckpointScope, CHECKPOINT_PUBLIC_SCOPE } from "../security.js";
|
|
10
10
|
import { graftParkToolCallId, parkToolCallId, TurnAnchorCapture, HEARTBEAT_MS, markChildrenStoppedByUserOnAbort } from "../runs.js";
|
|
11
|
-
import { failureCodeOf, nestedPauseOf, sealResultForExit, outwardPlane } from "../terminal.js";
|
|
11
|
+
import { atHostBoundary, failureCodeOf, nestedPauseOf, sealResultForExit, outwardPlane } from "../terminal.js";
|
|
12
12
|
import { buildCancelledLedgerRow, createRunAbort, mintCancelledResult } from "../run-cancel-context.js";
|
|
13
13
|
import { isTerminalRunStatus } from "../plugins/store-contracts.js";
|
|
14
14
|
import { readTurnActivityMs, recordTurnActivity } from "../turn-activity.js";
|
|
@@ -51,6 +51,7 @@ import { commitExecutionContext, isRootSessionGoneError, resolveExecutionContext
|
|
|
51
51
|
import { commitSessionInheritEnv } from "./session-inherit-env.js";
|
|
52
52
|
import { ASK_USER_QUESTION_TOOL_NAME, isApprovalGateKind, isEngineQuestionRow } from "../approval-content-kind.js";
|
|
53
53
|
import { deploymentListAsks } from "../approval.js";
|
|
54
|
+
import { isParkLedgerEventType } from "../trace/ledger-events.js";
|
|
54
55
|
import { readResumeCtx, resumeCtxCorruptAnswer, resumeCtxUnsealableAnswer } from "./resume-ctx-read.js";
|
|
55
56
|
import { buildCheckpointVersionKeys, resumeBlockedByPolicyAnswer, resumeRefusalWithCard, sealCheckpointCtx, storedBodyReplayAnswer, storedBodyReplayLogFields, withPermissionModeRewritten } from "./checkpoint-ctx.js";
|
|
56
57
|
import { refusalBody, resumeRefusalFacts } from "./refusal-body.js";
|
|
@@ -61,12 +62,6 @@ import { fieldConflictFacts } from "../field-conflict.js";
|
|
|
61
62
|
function legMayHaveReopenedCheckpoint(r) {
|
|
62
63
|
return r.terminal.kind === "failed" && nestedPauseOf(r.terminal) === undefined;
|
|
63
64
|
}
|
|
64
|
-
function nestedParkStatusOf(r) {
|
|
65
|
-
const paused = nestedPauseOf(r.terminal);
|
|
66
|
-
if (paused === undefined)
|
|
67
|
-
return undefined;
|
|
68
|
-
return PAUSE_REGISTRY[paused.gate.kind].taskStatus;
|
|
69
|
-
}
|
|
70
65
|
const WORKER_SWAP_REDEEMABLE = {
|
|
71
66
|
version_newer: true,
|
|
72
67
|
env_factory_missing: true,
|
|
@@ -855,12 +850,14 @@ export function createResumeLegs(ctx) {
|
|
|
855
850
|
resumeLegLive = true;
|
|
856
851
|
const vrEngine = await resumeWithVerification(legRunner, token, outcome, { ...resumeTaskConfig, signal: cancelCtrl.signal, preemptSignal: preemptCtrl.signal }, resumeObjective, verifyRounds, verifyInternals);
|
|
857
852
|
const vrCause = cancelCtrl.cause();
|
|
858
|
-
const
|
|
853
|
+
const vrJudged = atHostBoundary(vrEngine, sessionId);
|
|
854
|
+
const vr = vrCause !== undefined && taskId !== undefined ? mintCancelledResult({ taskId, sessionId, startedAtMs: resumeLegStartedAt, message: "cancelled by user", engineResult: vrJudged, cause: vrCause }) : vrJudged;
|
|
859
855
|
await commitResumeCtx();
|
|
860
856
|
let safe = sealResultForExit(vr);
|
|
861
|
-
const
|
|
862
|
-
const
|
|
863
|
-
const
|
|
857
|
+
const vrPaused = vr.terminal.kind === "paused" ? vr.terminal : undefined;
|
|
858
|
+
const vrParkWord = vrPaused !== undefined ? outwardPlane(vrPaused).status : undefined;
|
|
859
|
+
const reParkEvent = vrParkWord !== undefined && isParkLedgerEventType(vrParkWord) ? vrParkWord : undefined;
|
|
860
|
+
const reSuspended = reParkEvent !== undefined;
|
|
864
861
|
const vrReopened = await reopenedAfterLeg(vr, vrCause !== undefined);
|
|
865
862
|
if (vrReopened)
|
|
866
863
|
reopenConfirmedPark = true;
|
|
@@ -871,8 +868,8 @@ export function createResumeLegs(ctx) {
|
|
|
871
868
|
await appendPromptManifest(ap, deps.promptManifests, taskId);
|
|
872
869
|
if (reSuspended || vrReopened) {
|
|
873
870
|
await appendModelUsageDelta(ap, deps.modelUsage, taskId);
|
|
874
|
-
const vrParkCallId =
|
|
875
|
-
await ap(
|
|
871
|
+
const vrParkCallId = reSuspended ? await parkToolCallId(vr, deps.checkpointStore) : undefined;
|
|
872
|
+
await ap(reParkEvent ?? reparkStatus, parkEventData({ terminal: vrPaused, ...(vrParkCallId !== undefined ? { toolCallId: vrParkCallId } : {}) }, vrReopened ? (failureCodeOf(vr.terminal) ?? null) : undefined));
|
|
876
873
|
}
|
|
877
874
|
else {
|
|
878
875
|
safe = await attachModelUsage(safe, { append: ap, getEvents: (id, a) => rs2.getEvents(id, a), modelUsage: deps.modelUsage, taskId });
|
|
@@ -884,8 +881,8 @@ export function createResumeLegs(ctx) {
|
|
|
884
881
|
throw e;
|
|
885
882
|
}
|
|
886
883
|
}
|
|
887
|
-
if (
|
|
888
|
-
return
|
|
884
|
+
if (reSuspended)
|
|
885
|
+
return safe;
|
|
889
886
|
if (vr.verification?.verdict)
|
|
890
887
|
deps.metrics?.inc("verifications_total", { verdict: vr.verification.verdict });
|
|
891
888
|
return safe;
|
|
@@ -22,7 +22,7 @@ export interface RetiredServiceDep {
|
|
|
22
22
|
export declare const RETIRED_SERVICE_DEPS: {
|
|
23
23
|
readonly sqlEngineFacts: {
|
|
24
24
|
readonly retiredIn: "7.132.0";
|
|
25
|
-
readonly wayOut: "replaced by sqlEngine — pass the SQL pool's engine reading as sqlEngine: `{ dialect: \"
|
|
25
|
+
readonly wayOut: "replaced by sqlEngine — pass the SQL pool's engine reading as sqlEngine: `{ dialect: \"mysql\" | \"pg\", facts }` where `facts` is read live (a getter) and is null while the pool's connection setup has not succeeded, or leave both unset when there is no SQL store";
|
|
26
26
|
};
|
|
27
27
|
readonly snapshotBlobSqlCapBytes: {
|
|
28
28
|
readonly retiredIn: "7.132.0";
|
|
@@ -2,7 +2,7 @@ const BLOB_CAP_WAY_OUT = "the HTTP surface no longer holds a blob cap of its own
|
|
|
2
2
|
export const RETIRED_SERVICE_DEPS = {
|
|
3
3
|
sqlEngineFacts: {
|
|
4
4
|
retiredIn: "7.132.0",
|
|
5
|
-
wayOut: "replaced by sqlEngine — pass the SQL pool's engine reading as sqlEngine: `{ dialect: \"
|
|
5
|
+
wayOut: "replaced by sqlEngine — pass the SQL pool's engine reading as sqlEngine: `{ dialect: \"mysql\" | \"pg\", facts }` where `facts` is read live (a getter) and is null while the pool's connection setup has not succeeded, or leave both unset when there is no SQL store",
|
|
6
6
|
},
|
|
7
7
|
snapshotBlobSqlCapBytes: { retiredIn: "7.132.0", wayOut: BLOB_CAP_WAY_OUT },
|
|
8
8
|
snapshotBlobSqlCap: { retiredIn: "7.133.0", wayOut: BLOB_CAP_WAY_OUT },
|
|
@@ -69,7 +69,7 @@ export async function handleAdoption(req, res, match, ctx) {
|
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
const store = fact.backend.adoptionLog();
|
|
72
|
-
const runner = createAdoptionRunner({ store, dialect: deps.backend?.kind === "pg" ? "pg" : "
|
|
72
|
+
const runner = createAdoptionRunner({ store, dialect: deps.backend?.kind === "pg" ? "pg" : "mysql", now: Date.now, logger: deps.logger });
|
|
73
73
|
switch (match.decl.id) {
|
|
74
74
|
case "adoption-detail": {
|
|
75
75
|
const id = ctx.helpers.safeDecode(match.params.id);
|
|
@@ -4,6 +4,7 @@ import { sentMemoryStoreRefusal } from "../memory-store-refusal-reply.js";
|
|
|
4
4
|
import { buildOriginFencedBundle, readOriginAware } from "../../memory-origin-fence.js";
|
|
5
5
|
import { gatedPrincipal, explicitOperatorOk, sendOperatorPrincipalsRequired, sendPrincipalRefusal } from "../principal-gate.js";
|
|
6
6
|
import { assertNever } from "../route-ctx.js";
|
|
7
|
+
import { sentMemoryLayerRefusal } from "../memory-layer-reply.js";
|
|
7
8
|
import * as facts from "../../capability-facts.js";
|
|
8
9
|
export const MEMORY_BUNDLE_EXPORT_PATH = "/v1/memory/export";
|
|
9
10
|
export const MEMORY_BUNDLE_IMPORT_PATH = "/v1/memory/import";
|
|
@@ -34,6 +35,8 @@ function codeOf(err) {
|
|
|
34
35
|
return typeof code === "string" ? code : undefined;
|
|
35
36
|
}
|
|
36
37
|
function sentClassifiedFailure(res, ctx, face, err) {
|
|
38
|
+
if (sentMemoryLayerRefusal(res, err, { kind: "operator" }))
|
|
39
|
+
return true;
|
|
37
40
|
const code = codeOf(err);
|
|
38
41
|
if (code !== undefined && sentCoreCode(res, code, err instanceof Error ? err.message : String(err)))
|
|
39
42
|
return true;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { erasureInputSmugglesPrototypeKey } from "../../memory-operator-faces.js";
|
|
3
3
|
import { sentMemoryComplianceFailure } from "../memory-compliance-failure-reply.js";
|
|
4
|
+
import { readLayerSeat, sentMemoryLayerRefusal } from "../memory-layer-reply.js";
|
|
4
5
|
import { sendJson, sendError } from "../send.js";
|
|
5
6
|
import { gatedPrincipal, explicitOperatorOk, sendOperatorPrincipalsRequired, sendPrincipalRefusal } from "../principal-gate.js";
|
|
6
7
|
import { assertNever } from "../route-ctx.js";
|
|
@@ -12,6 +13,8 @@ const EraseRequestSchema = z.object({
|
|
|
12
13
|
allowUnevidenced: z.boolean().optional(),
|
|
13
14
|
});
|
|
14
15
|
function sentClassifiedFailure(res, ctx, face, err) {
|
|
16
|
+
if (sentMemoryLayerRefusal(res, err, { kind: "operator" }))
|
|
17
|
+
return true;
|
|
15
18
|
if (sentMemoryComplianceFailure(res, err, { kind: "operator" }, ctx.deps.logger))
|
|
16
19
|
return true;
|
|
17
20
|
ctx.deps.logger?.warn?.(`memory_compliance_${face}_failed`, { err: String(err) });
|
|
@@ -53,8 +56,12 @@ export async function handleMemoryCompliance(req, res, match, ctx) {
|
|
|
53
56
|
sendError(res, 400, "request.id_invalid", "invalid memory entry id");
|
|
54
57
|
return;
|
|
55
58
|
}
|
|
59
|
+
const query = new URLSearchParams(match.search);
|
|
60
|
+
const at = readLayerSeat(res, query.has("scope"), query.get("scope"));
|
|
61
|
+
if (at === null)
|
|
62
|
+
return;
|
|
56
63
|
try {
|
|
57
|
-
sendJson(res, 200, await faces.provenanceOf(entryId));
|
|
64
|
+
sendJson(res, 200, await (at !== undefined ? faces.provenanceOf(entryId, at) : faces.provenanceOf(entryId)));
|
|
58
65
|
}
|
|
59
66
|
catch (err) {
|
|
60
67
|
if (!sentClassifiedFailure(res, ctx, "provenance", err))
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { ControlPlaneCorruptError } from "@sema-agent/core";
|
|
3
3
|
import { sendJson, sendError } from "../send.js";
|
|
4
|
+
import { sentMemoryLayerRefusal } from "../memory-layer-reply.js";
|
|
4
5
|
import { gatedPrincipal, explicitOperatorOk, sendPrincipalRefusal, sendOperatorPrincipalsRequired } from "../principal-gate.js";
|
|
5
6
|
import { assertNever } from "../route-ctx.js";
|
|
6
7
|
import * as facts from "../../capability-facts.js";
|
|
@@ -101,7 +102,15 @@ export async function handleMemoryConsolidation(req, res, match, ctx) {
|
|
|
101
102
|
const q = new URLSearchParams(match.search).get("scope") ?? undefined;
|
|
102
103
|
const decided = decideScope(q, faces.scopes);
|
|
103
104
|
const scope = "scope" in decided ? decided.scope : undefined;
|
|
104
|
-
|
|
105
|
+
let row;
|
|
106
|
+
try {
|
|
107
|
+
row = scope !== undefined ? faces.lastRun(scope) : undefined;
|
|
108
|
+
}
|
|
109
|
+
catch (err) {
|
|
110
|
+
if (sentMemoryLayerRefusal(res, err, { kind: "operator" }))
|
|
111
|
+
return;
|
|
112
|
+
throw err;
|
|
113
|
+
}
|
|
105
114
|
sendJson(res, 200, {
|
|
106
115
|
enabled: true,
|
|
107
116
|
seat: faces.seat,
|
|
@@ -144,6 +153,8 @@ export async function handleMemoryConsolidation(req, res, match, ctx) {
|
|
|
144
153
|
sendJson(res, 200, buildRunSummary(r));
|
|
145
154
|
}
|
|
146
155
|
catch (err) {
|
|
156
|
+
if (sentMemoryLayerRefusal(res, err, { kind: "operator" }))
|
|
157
|
+
return;
|
|
147
158
|
const coreCode = codeOf(err);
|
|
148
159
|
if (coreCode !== undefined) {
|
|
149
160
|
sendError(res, 409, "memory.consolidation_refused", `memory consolidation refused (${coreCode}): ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -3,6 +3,7 @@ import { ControlPlaneCorruptError } from "@sema-agent/core";
|
|
|
3
3
|
import { sendJson, sendError } from "../send.js";
|
|
4
4
|
import { sentMemoryStoreRefusal } from "../memory-store-refusal-reply.js";
|
|
5
5
|
import { buildOriginFence, readOriginAware } from "../../memory-origin-fence.js";
|
|
6
|
+
import { readLayerSeat, sentMemoryLayerRefusal } from "../memory-layer-reply.js";
|
|
6
7
|
import { gatedPrincipal, explicitOperatorOk, sendOperatorPrincipalsRequired, sendPrincipalRefusal } from "../principal-gate.js";
|
|
7
8
|
import { assertNever } from "../route-ctx.js";
|
|
8
9
|
import * as facts from "../../capability-facts.js";
|
|
@@ -49,6 +50,8 @@ function codeOf(err) {
|
|
|
49
50
|
return typeof code === "string" ? code : undefined;
|
|
50
51
|
}
|
|
51
52
|
function sentClassifiedFailure(res, ctx, face, err) {
|
|
53
|
+
if (sentMemoryLayerRefusal(res, err, { kind: "operator" }))
|
|
54
|
+
return true;
|
|
52
55
|
if (face === "clear") {
|
|
53
56
|
const coreCode = codeOf(err);
|
|
54
57
|
if (coreCode !== undefined && sentClearCode(res, coreCode, err instanceof Error ? err.message : String(err)))
|
|
@@ -157,8 +160,12 @@ export async function handleMemoryOrigin(req, res, match, ctx) {
|
|
|
157
160
|
return;
|
|
158
161
|
}
|
|
159
162
|
case "memory-origin-clearances": {
|
|
163
|
+
const query = new URLSearchParams(match.search);
|
|
164
|
+
const at = readLayerSeat(res, query.has("scope"), query.get("scope"));
|
|
165
|
+
if (at === null)
|
|
166
|
+
return;
|
|
160
167
|
try {
|
|
161
|
-
sendJson(res, 200, { clearances: faces.listClearances().map(buildClearanceRowWire) });
|
|
168
|
+
sendJson(res, 200, { clearances: (at !== undefined ? faces.listClearances(at) : faces.listClearances()).map(buildClearanceRowWire) });
|
|
162
169
|
}
|
|
163
170
|
catch (err) {
|
|
164
171
|
if (!sentClassifiedFailure(res, ctx, "clearances", err))
|
|
@@ -182,8 +189,13 @@ export async function handleMemoryOrigin(req, res, match, ctx) {
|
|
|
182
189
|
sendError(res, 400, "request.body_shape", "invalid memory origin clearance request — expected an object with a non-empty `requestId` and a `reason` string (whether an EMPTY reason is acceptable is the engine's judgment, not this layer's)");
|
|
183
190
|
return;
|
|
184
191
|
}
|
|
192
|
+
const body = raw;
|
|
193
|
+
const at = readLayerSeat(res, Object.prototype.hasOwnProperty.call(body, "scope"), body.scope);
|
|
194
|
+
if (at === null)
|
|
195
|
+
return;
|
|
185
196
|
try {
|
|
186
|
-
const
|
|
197
|
+
const input = { requestId: parsed.data.requestId, reason: parsed.data.reason };
|
|
198
|
+
const receipt = await (at !== undefined ? faces.clear(entryId, input, at) : faces.clear(entryId, input));
|
|
187
199
|
ctx.deps.logger?.info?.("memory_origin_cleared", {
|
|
188
200
|
principal: principal ?? null,
|
|
189
201
|
entryId,
|
|
@@ -5,6 +5,7 @@ import { buildOriginFence, readOriginAware } from "../../memory-origin-fence.js"
|
|
|
5
5
|
import { parseProjectLayerKey } from "../../project-layer-key.js";
|
|
6
6
|
import { gatedPrincipal, explicitOperatorOk, sendPrincipalRefusal, sendUnauthorized } from "../principal-gate.js";
|
|
7
7
|
import { assertNever } from "../route-ctx.js";
|
|
8
|
+
import { sentMemoryLayerRefusal } from "../memory-layer-reply.js";
|
|
8
9
|
const ORG_PREFIX = "org:";
|
|
9
10
|
export const MEMORY_EXPORT_MAX_LIMIT = 500;
|
|
10
11
|
function encodeExportCursor(c) {
|
|
@@ -121,6 +122,8 @@ export async function handleMemoryPolicy(req, res, match, ctx) {
|
|
|
121
122
|
});
|
|
122
123
|
}
|
|
123
124
|
catch (err) {
|
|
125
|
+
if (sentMemoryLayerRefusal(res, err, { kind: "operator" }))
|
|
126
|
+
return;
|
|
124
127
|
deps.logger?.warn?.("memory_export_failed", { scope, err: String(err) });
|
|
125
128
|
sendError(res, 500, "internal.error", "memory export failed");
|
|
126
129
|
}
|
|
@@ -158,6 +161,8 @@ export async function handleMemoryPolicy(req, res, match, ctx) {
|
|
|
158
161
|
sendJson(res, 200, out);
|
|
159
162
|
}
|
|
160
163
|
catch (err) {
|
|
164
|
+
if (sentMemoryLayerRefusal(res, err, { kind: "operator" }))
|
|
165
|
+
return;
|
|
161
166
|
deps.logger?.warn?.("memory_sync_failed", { scope, peer: parsed.value.peer, err: String(err) });
|
|
162
167
|
sendError(res, 500, "internal.error", "memory sync failed");
|
|
163
168
|
}
|
|
@@ -7,6 +7,8 @@ import { seatText } from "../../trace/exit-seat.js";
|
|
|
7
7
|
import { recordFailOpen } from "../../observability/fail-open.js";
|
|
8
8
|
import { MCP_DIAL_DEADLINE_MS, raceDeadline } from "../mcp-dial-deadline.js";
|
|
9
9
|
import { sentMemoryComplianceFailure } from "../memory-compliance-failure-reply.js";
|
|
10
|
+
import { readLayerSeat, sentMemoryLayerRefusal } from "../memory-layer-reply.js";
|
|
11
|
+
import { foldPlaneStatuses } from "../../memory-operator-faces.js";
|
|
10
12
|
import { MAX_SETTINGS_OUTPUT_STYLE_CHARS, MAX_SETTINGS_ENV_VARS, MAX_SETTINGS_ENV_KEY_CHARS, MAX_SETTINGS_ENV_VALUE_CHARS } from "../../task-settings.js";
|
|
11
13
|
import { readWritableSessionPermissionRules } from "../../session-policy-wire.js";
|
|
12
14
|
import { sendJson, sendError, sendSessionError, sendSessionPolicyError, sseHeaders, httpErrorBody } from "../send.js";
|
|
@@ -551,11 +553,17 @@ export async function handleSessions(req, res, match, ctx) {
|
|
|
551
553
|
sendError(res, 400, "request.field_invalid", "allowUnevidenced must be a boolean when present");
|
|
552
554
|
return;
|
|
553
555
|
}
|
|
556
|
+
const at = readLayerSeat(res, Object.prototype.hasOwnProperty.call(raw, "scope"), raw.scope);
|
|
557
|
+
if (at === null)
|
|
558
|
+
return;
|
|
559
|
+
const withheld = (coreMessage) => deps.logger?.warn?.("session_memory_erase_refused", { sessionId, err: coreMessage });
|
|
554
560
|
try {
|
|
555
|
-
|
|
561
|
+
const input = { requestId: raw.requestId, select: { sessionId }, ...(raw.allowUnevidenced !== undefined ? { allowUnevidenced: raw.allowUnevidenced } : {}) };
|
|
562
|
+
sendJson(res, 200, await (at !== undefined ? faces.erase(input, at) : faces.erase(input)));
|
|
556
563
|
}
|
|
557
564
|
catch (err) {
|
|
558
|
-
|
|
565
|
+
if (sentMemoryLayerRefusal(res, err, { kind: "session_owner", withheld }))
|
|
566
|
+
return;
|
|
559
567
|
if (sentMemoryComplianceFailure(res, err, { kind: "session_owner", withheld }, deps.logger))
|
|
560
568
|
return;
|
|
561
569
|
deps.logger?.warn?.("session_memory_erase_failed", { sessionId, err: String(err) });
|
|
@@ -587,20 +595,27 @@ export async function handleSessions(req, res, match, ctx) {
|
|
|
587
595
|
sendError(res, 501, "capability.memory_engine_required", "session memory status is not available on this deployment — it requires a wired memory engine (MEMORY_ENGINE=on) whose backend owns the engine control plane (controlPlaneRoot); the file memory backend does, the pg/tidb memory backends do not (their control plane would land on a replica's local disk)");
|
|
588
596
|
return;
|
|
589
597
|
}
|
|
598
|
+
const query = new URLSearchParams(match.search);
|
|
599
|
+
const at = readLayerSeat(res, query.has("scope"), query.get("scope"));
|
|
600
|
+
if (at === null)
|
|
601
|
+
return;
|
|
590
602
|
try {
|
|
591
603
|
const { memoryStatusCache } = ctx.local.sessions;
|
|
592
|
-
|
|
593
|
-
|
|
604
|
+
const statusOf = (store) => {
|
|
605
|
+
const cacheKey = JSON.stringify([sessionId, store.controlPlane]);
|
|
606
|
+
const cached = memoryStatusCache.get(cacheKey);
|
|
607
|
+
if (cached && Date.now() - cached.at <= MEMORY_STATUS_TTL_MS)
|
|
608
|
+
return cached.status;
|
|
594
609
|
if (memoryStatusCache.size > 1024)
|
|
595
610
|
memoryStatusCache.clear();
|
|
596
|
-
const status =
|
|
611
|
+
const status = store.status(sessionId);
|
|
597
612
|
const fresh = { at: Date.now(), status };
|
|
598
|
-
memoryStatusCache.set(
|
|
599
|
-
status.catch(() => { if (memoryStatusCache.get(
|
|
600
|
-
memoryStatusCache.delete(
|
|
601
|
-
|
|
602
|
-
}
|
|
603
|
-
const s = await
|
|
613
|
+
memoryStatusCache.set(cacheKey, fresh);
|
|
614
|
+
status.catch(() => { if (memoryStatusCache.get(cacheKey) === fresh)
|
|
615
|
+
memoryStatusCache.delete(cacheKey); });
|
|
616
|
+
return status;
|
|
617
|
+
};
|
|
618
|
+
const s = foldPlaneStatuses(await Promise.all(face.storesAt(at).map(statusOf)));
|
|
604
619
|
sendJson(res, 200, {
|
|
605
620
|
sessionId,
|
|
606
621
|
autoConsolidationArmed: deps.memoryAutoConsolidationArmed,
|
|
@@ -612,6 +627,8 @@ export async function handleSessions(req, res, match, ctx) {
|
|
|
612
627
|
});
|
|
613
628
|
}
|
|
614
629
|
catch (err) {
|
|
630
|
+
if (sentMemoryLayerRefusal(res, err, { kind: "session_owner", withheld: (message) => deps.logger?.warn?.("session_memory_status_refused", { sessionId, err: message }) }))
|
|
631
|
+
return;
|
|
615
632
|
deps.logger?.warn?.("session_memory_status_failed", { sessionId, err: String(err) });
|
|
616
633
|
sendError(res, 500, "internal.error", "session memory status read failed");
|
|
617
634
|
}
|
|
@@ -2,7 +2,7 @@ import { redactErrorMessage, redactHead, redactTerminalResult } from "../../obse
|
|
|
2
2
|
import { runWithVerification, runCascade, taskNotificationDedupKey, uuidv7 } from "@sema-agent/core";
|
|
3
3
|
import { heldFor } from "../../peer-seat.js";
|
|
4
4
|
import { graftParkToolCallId, markChildrenStoppedByUserOnAbort, syncRefusalHttpStatus, zeroWorkRefusalFacts, releaseKeyIfZeroWorkRefusal, createPromptCommitReader, HEARTBEAT_MS } from "../../runs.js";
|
|
5
|
-
import { sealResultForExit, outwardPlane } from "../../terminal.js";
|
|
5
|
+
import { atHostBoundary, sealResultForExit, outwardPlane } from "../../terminal.js";
|
|
6
6
|
import { withPrincipal } from "../../observability/principal-context.js";
|
|
7
7
|
import { fleetRunPublisher, fleetRunLabels, fleetRunResiduals, isFleetAgentTerminalNotification } from "../../fleet/fleet-bus.js";
|
|
8
8
|
import { defaultSubagentTailBus } from "../../fleet/subagent-tail-bus.js";
|
|
@@ -969,7 +969,7 @@ export async function handleTasks(req, res, match, ctx) {
|
|
|
969
969
|
}
|
|
970
970
|
return stream.result();
|
|
971
971
|
};
|
|
972
|
-
result = await instructionLeg.run(prepared.spec.sessionId, () => withPrincipal(principal, () => prepared.verify ? verifyLeg(prepared.verify) : prepared.cascade ? cascadeLeg() : plainLeg()));
|
|
972
|
+
result = atHostBoundary(await instructionLeg.run(prepared.spec.sessionId, () => withPrincipal(principal, () => prepared.verify ? verifyLeg(prepared.verify) : prepared.cascade ? cascadeLeg() : plainLeg())), prepared.spec.sessionId);
|
|
973
973
|
}
|
|
974
974
|
finally {
|
|
975
975
|
counters.uncountedBillableInflight--;
|
|
@@ -1006,10 +1006,12 @@ export async function handleTasks(req, res, match, ctx) {
|
|
|
1006
1006
|
const syncPlane = outwardPlane(result.terminal);
|
|
1007
1007
|
if (syncPlane.status === "suspended" && deps.checkpointStore && deps.runStore && durableTaskId) {
|
|
1008
1008
|
await deps.runStore.setSuspended(durableTaskId, exitResult);
|
|
1009
|
+
prepared.acceptance.settle(result);
|
|
1009
1010
|
return { status: 200, body: withSyncSubmitKeys(buildSyncSubmitBody(exitResult, { taskId: durableTaskId, sessionId: prepared.spec.sessionId, status: "suspended" })) };
|
|
1010
1011
|
}
|
|
1011
1012
|
if (syncPlane.status === "needs_review" && deps.checkpointStore && deps.runStore && durableTaskId) {
|
|
1012
1013
|
await deps.runStore.setNeedsReview(durableTaskId, exitResult);
|
|
1014
|
+
prepared.acceptance.settle(result);
|
|
1013
1015
|
return { status: 200, body: withSyncSubmitKeys(buildSyncSubmitBody(exitResult, { taskId: durableTaskId, sessionId: prepared.spec.sessionId, status: "needs_review" })) };
|
|
1014
1016
|
}
|
|
1015
1017
|
if (durableTaskId && deps.runStore)
|
package/dist/http/server.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import http from "node:http";
|
|
2
|
-
import type { MemoryComplianceFaces } from "../memory-operator-faces.js";
|
|
2
|
+
import type { MemoryComplianceFaces, MemoryOriginFaces, SessionMemoryStatusFace } from "../memory-operator-faces.js";
|
|
3
3
|
import type { SideQueryAccounting } from "../budget.js";
|
|
4
4
|
import type { IncomingMessage } from "node:http";
|
|
5
|
-
import { type Runner, type TaskSpec, type TaskResult, type WorkflowRunStore, type MemoryEntry, type MemoryExportBundle, type MemoryImportReport, type
|
|
5
|
+
import { type Runner, type TaskSpec, type TaskResult, type WorkflowRunStore, type MemoryEntry, type MemoryExportBundle, type MemoryImportReport, type ConsolidationRunReceipt, type ConsolidationDriverRunRow, type SideQuerySpec, type SideQueryResult, type Brain, type EngineNotice } from "@sema-agent/core";
|
|
6
6
|
import type { TaskRequestBody } from "./wire-types.js";
|
|
7
7
|
import type { ServiceConfig } from "../config-types.js";
|
|
8
8
|
import { type SessionMirrorRuling } from "../web-admin-client/facade.js";
|
|
@@ -518,9 +518,7 @@ export interface ServiceSeamDeps {
|
|
|
518
518
|
* (工厂返 undefined),与 compliance/origin 两族同一条 F-9 裁。
|
|
519
519
|
* 🔴 face 的五键**全可选**(core `SessionMemoryStatus`):absent = 该事实源不可读,路由逐键透传缺席,
|
|
520
520
|
* 恒不铸 false/0 替身;`optOutSource:"fault"` = capture 态 indeterminate(383 片2/3 轴直投)。 */
|
|
521
|
-
sessionMemoryStatus?:
|
|
522
|
-
status: (sessionId: string) => Promise<SessionMemoryStatus>;
|
|
523
|
-
};
|
|
521
|
+
sessionMemoryStatus?: SessionMemoryStatusFace;
|
|
524
522
|
/**
|
|
525
523
|
* [ref](core 7.22.0 [ref] W1)—— 本**部署**的自动整理武装事实,`GET /v1/sessions/:id/memory-status`
|
|
526
524
|
* 的 `autoConsolidationArmed` 格。
|
|
@@ -552,25 +550,7 @@ export interface ServiceSeamDeps {
|
|
|
552
550
|
* ——落在副本本地盘上 = pod 重建即永久丢失。全文见 src/memory-operator-faces.ts 头注。
|
|
553
551
|
* 🔴 `listClearances` 是**同步**的(core 的读面就是一次严格 sidecar 读),且账本损坏时**抛**
|
|
554
552
|
* `ControlPlaneCorruptError` —— 那是 fail-closed 信号,不是空数组。 */
|
|
555
|
-
memoryOriginFace?:
|
|
556
|
-
listExternal: (scopes: readonly string[]) => Promise<Array<{
|
|
557
|
-
id: string;
|
|
558
|
-
slug: string;
|
|
559
|
-
scope: string;
|
|
560
|
-
origin: MemoryEntryOrigin;
|
|
561
|
-
provenance: EntryProvenanceAccount;
|
|
562
|
-
}>>;
|
|
563
|
-
listClearances: () => OriginClearanceRow[];
|
|
564
|
-
clear: (entryId: string, input: {
|
|
565
|
-
requestId: string;
|
|
566
|
-
reason: string;
|
|
567
|
-
}) => Promise<{
|
|
568
|
-
entryId: string;
|
|
569
|
-
clearanceId: string;
|
|
570
|
-
origin: MemoryEntryOrigin;
|
|
571
|
-
landedSlug: string;
|
|
572
|
-
}>;
|
|
573
|
-
};
|
|
553
|
+
memoryOriginFace?: MemoryOriginFaces;
|
|
574
554
|
/** [ref](core 5.58.0 `runMemoryConsolidationDriver`):记忆 **consolidation 阀门**的操作面。
|
|
575
555
|
* 启用 `POST /v1/admin/memory/consolidation/run` 与 `GET /v1/admin/memory/consolidation`(两口 operator-only)。
|
|
576
556
|
* main.ts 把它接到 `createMemoryConsolidationFaces` 的产物上。
|
|
@@ -827,7 +807,7 @@ export interface ServiceDeploymentDeps {
|
|
|
827
807
|
* 7.132.0 前这一席是 `sqlEngineFacts: () => SqlEngineFacts | null`(只给事实、不给方言);照旧传它 ⇒ `createHttpServer` 起服拒。
|
|
828
808
|
* 🔴 **SQL 后端在场(`backend` 交出了 `mysqlPool()` / `pgPool()`)⇒ 本席必填**,缺席 ⇒ `createHttpServer` 起服拒(席缺席只表示「没有 SQL 后端」,不能是「忘了给」);
|
|
829
809
|
* 本服务自己的装配(`boot/stores.ts` → `stage-10`)按同一个谓词(`sqlPoolsOf`)建立它,恒给。值形也在起服时判(同一只判官 `sqlEngineSeatIssue` 的另一臂):
|
|
830
|
-
* `{ dialect: "
|
|
810
|
+
* `{ dialect: "mysql" | "pg", facts }`,`facts` 是 `null` 或带 `maxRowBytes` / `maxPacketBytes` / `wallSources` 的引擎事实;只改了键名的 `() => facts` 之类 ⇒ 起服拒。 */
|
|
831
811
|
sqlEngine?: import("../plugins/sql-driver.js").SqlEngineReading;
|
|
832
812
|
/** [ref]:**写保护名表**的姿态(`write-protection.ts` 的 boot 期单一推导点 —— 与递给每只 Runner 的
|
|
833
813
|
* `writeProtectedPaths` 座同一份 config 决定)。两个读面共用:`GET /v1/diagnostics/wiring` 的
|
package/dist/http/server.js
CHANGED
|
@@ -76,9 +76,9 @@ export function createHttpServer(rawDeps) {
|
|
|
76
76
|
if (issue !== undefined) {
|
|
77
77
|
switch (issue) {
|
|
78
78
|
case "required":
|
|
79
|
-
throw new Error("createHttpServer: sqlEngine is required when a SQL store backend is wired (the backend hands out a SQL pool) — pass the pool's engine reading as sqlEngine: `{ dialect: \"
|
|
79
|
+
throw new Error("createHttpServer: sqlEngine is required when a SQL store backend is wired (the backend hands out a SQL pool) — pass the pool's engine reading as sqlEngine: `{ dialect: \"mysql\" | \"pg\", facts }` where `facts` is read live (a getter) and is null while the pool's connection setup has not succeeded; refusing to start rather than read the database's row and statement limits as absent and admit task bodies the database cannot store");
|
|
80
80
|
case "bad_shape":
|
|
81
|
-
throw new Error(`createHttpServer: sqlEngine must be the SQL pool's engine reading \`{ dialect: "
|
|
81
|
+
throw new Error(`createHttpServer: sqlEngine must be the SQL pool's engine reading \`{ dialect: "mysql" | "pg", facts }\` where \`facts\` is read live (a getter) and is null while the pool's connection setup has not succeeded, otherwise the engine facts object (maxRowBytes, maxPacketBytes and wallSources included) — got ${typeof deps.sqlEngine === "function" ? "a function (the 7.131.x reader \`() => facts\` goes in as \`{ dialect, get facts() { return f(); } }\`)" : describeValueShape(deps.sqlEngine)}; refusing to start rather than answer every task submission with a 500`);
|
|
82
82
|
default: {
|
|
83
83
|
const unhandled = issue;
|
|
84
84
|
throw new Error(`sqlEngine seat issue without a refusal: ${String(unhandled)}`);
|
|
@@ -43,7 +43,7 @@ export declare const RUN_IDENTITY_PRINCIPAL_INC_MAX_CHARS = 64;
|
|
|
43
43
|
* (身份键按字节判等,与 MySQL 协议表级 `utf8mb4_bin` 同形)。
|
|
44
44
|
*/
|
|
45
45
|
export declare const RUN_IDENTITY_COLUMNS: {
|
|
46
|
-
readonly
|
|
46
|
+
readonly mysql: string;
|
|
47
47
|
readonly pg: string;
|
|
48
48
|
};
|
|
49
49
|
/** 元组落盘的三格(SQL 三列 / File 车道 run.json 的三键,同名同义)。 */
|
package/dist/identity-source.js
CHANGED
|
@@ -2,7 +2,7 @@ export const IDENTITY_SOURCES = ["service_token", "sso", "direct_door_jwt"];
|
|
|
2
2
|
export const RUN_IDENTITY_SCOPE_MAX_CHARS = 190;
|
|
3
3
|
export const RUN_IDENTITY_PRINCIPAL_INC_MAX_CHARS = 64;
|
|
4
4
|
export const RUN_IDENTITY_COLUMNS = {
|
|
5
|
-
|
|
5
|
+
mysql: [
|
|
6
6
|
"identity_source VARCHAR(32) NULL",
|
|
7
7
|
`identity_scope VARCHAR(${RUN_IDENTITY_SCOPE_MAX_CHARS}) NULL`,
|
|
8
8
|
`identity_principal_inc VARCHAR(${RUN_IDENTITY_PRINCIPAL_INC_MAX_CHARS}) NULL`,
|