@sema-agent/server 7.103.2 → 7.104.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 +346 -2
- package/README.md +6 -1
- package/README.zh-CN.md +5 -1
- package/USAGE.md +271 -16
- package/deploy/sema-up/README.md +57 -7
- package/deploy/sema-up/cluster-up.sh +18 -4
- package/deploy/sema-up/kube-up.sh +16 -0
- package/deploy/sema-up/lib/dataroot.sh +142 -0
- package/deploy/sema-up/lib/flagshape.sh +69 -0
- package/deploy/sema-up/lib/lanes.py +14 -4
- package/deploy/sema-up/lib/shell-access.sh +41 -0
- package/deploy/sema-up/preflight.sh +14 -1
- package/deploy/sema-up/sema-up.sh +134 -37
- package/deploy/sema-up/smoke.sh +5 -0
- package/dist/auto-mode-face.js +3 -4
- package/dist/boot/budget-tracing.js +1 -1
- package/dist/boot/config-center.d.ts +6 -2
- package/dist/boot/config-center.js +5 -59
- package/dist/boot/execution-env.d.ts +11 -0
- package/dist/boot/execution-env.js +14 -0
- package/dist/boot/execution-lane.d.ts +25 -0
- package/dist/boot/execution-lane.js +95 -0
- package/dist/boot/memory-consolidation.d.ts +185 -9
- package/dist/boot/memory-consolidation.js +192 -32
- package/dist/boot/resolve-spec.d.ts +2 -0
- package/dist/boot/resolve-spec.js +28 -24
- package/dist/boot/runner-deps.d.ts +6 -2
- package/dist/boot/runner-deps.js +4 -0
- package/dist/boot/session-faces.d.ts +5 -0
- package/dist/boot/session-faces.js +18 -2
- package/dist/boot/session-incarnation-seat.d.ts +41 -0
- package/dist/boot/session-incarnation-seat.js +69 -0
- package/dist/boot/stage-01-config.js +2 -2
- package/dist/boot/stage-02-registry-pull.js +3 -1
- package/dist/boot/stage-04-stores.d.ts +2 -0
- package/dist/boot/stage-04-stores.js +3 -1
- package/dist/boot/stage-05-execution-env.d.ts +4 -0
- package/dist/boot/stage-05-execution-env.js +2 -2
- package/dist/boot/stage-06-runners.d.ts +4 -1
- package/dist/boot/stage-06-runners.js +7 -14
- package/dist/boot/stage-07-capability-layer.d.ts +4 -1
- package/dist/boot/stage-08-reapers.d.ts +4 -1
- package/dist/boot/stage-09-leader.d.ts +6 -1
- package/dist/boot/stage-09-leader.js +2 -1
- package/dist/boot/stage-10-http-server.d.ts +6 -1
- package/dist/boot/stage-10-http-server.js +4 -1
- package/dist/brain.d.ts +1 -1
- package/dist/config-catalog.d.ts +16 -1
- package/dist/config-catalog.js +9 -9
- package/dist/config-center/restart-signal.d.ts +4 -4
- package/dist/config-invariants.d.ts +7 -1
- package/dist/config-invariants.js +37 -6
- package/dist/config-provider.d.ts +42 -10
- package/dist/config-provider.js +18 -16
- package/dist/config-types.d.ts +37 -16
- package/dist/config-types.js +1 -0
- package/dist/config.d.ts +13 -28
- package/dist/config.js +53 -70
- package/dist/env-facts.d.ts +13 -3
- package/dist/env-facts.js +15 -3
- package/dist/execution-lane-caps.d.ts +15 -0
- package/dist/execution-lane-caps.js +8 -0
- package/dist/file-history-capture.d.ts +42 -35
- package/dist/file-history-capture.js +15 -10
- package/dist/http/admission.d.ts +11 -4
- package/dist/http/admission.js +5 -1
- package/dist/http/dispatch.js +3 -3
- package/dist/http/principal-gate.d.ts +22 -0
- package/dist/http/principal-gate.js +20 -0
- package/dist/http/resume-legs.js +9 -5
- package/dist/http/routes/agents-roster.d.ts +7 -0
- package/dist/http/routes/agents-roster.js +6 -2
- package/dist/http/routes/approvals-assistant.d.ts +48 -19
- package/dist/http/routes/approvals-assistant.js +117 -50
- package/dist/http/routes/capabilities.js +3 -2
- package/dist/http/routes/config-catalog.js +1 -0
- package/dist/http/routes/memory-consolidation.d.ts +3 -2
- package/dist/http/routes/memory-policy.js +3 -3
- package/dist/http/routes/rules.js +2 -2
- package/dist/http/routes/runs.js +27 -2
- package/dist/http/routes/session-sync.js +8 -14
- package/dist/http/routes/sessions-list.js +3 -2
- package/dist/http/routes/sessions.js +44 -23
- package/dist/http/routes/shared-memory.js +2 -2
- package/dist/http/routes/tasks.js +22 -19
- package/dist/http/routes/trace-usage.js +4 -4
- package/dist/http/send.d.ts +12 -0
- package/dist/http/send.js +12 -1
- package/dist/http/server.d.ts +21 -4
- package/dist/http/server.js +7 -4
- package/dist/http/sync-submit-body.d.ts +43 -0
- package/dist/http/sync-submit-body.js +4 -0
- package/dist/http/wire-types.d.ts +23 -5
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/leader/merge.d.ts +8 -3
- package/dist/memory-incident-sink.js +2 -1
- package/dist/model-select.d.ts +9 -0
- package/dist/model-select.js +5 -1
- package/dist/observability/corrupt-read-seat.d.ts +151 -16
- package/dist/observability/corrupt-read-seat.js +158 -15
- package/dist/observability/fail-open.d.ts +12 -0
- package/dist/observability/fail-open.js +12 -0
- package/dist/observability/run-terminal.d.ts +15 -1
- package/dist/observability/run-terminal.js +4 -0
- package/dist/parked-decide.d.ts +8 -3
- package/dist/parked-decide.js +56 -20
- package/dist/parked-revive-surface.d.ts +14 -7
- package/dist/parked-revive-surface.js +5 -1
- package/dist/plugins/approval-ask-store-file.d.ts +4 -1
- package/dist/plugins/approval-ask-store-file.js +9 -12
- package/dist/plugins/approval-ask-store-sql.d.ts +4 -0
- package/dist/plugins/approval-ask-store-sql.js +4 -1
- package/dist/plugins/approval-exemption-store.d.ts +21 -1
- package/dist/plugins/approval-exemption-store.js +36 -7
- package/dist/plugins/approval-nonce-store.d.ts +16 -2
- package/dist/plugins/approval-nonce-store.js +17 -7
- package/dist/plugins/caching-session-store.d.ts +5 -0
- package/dist/plugins/caching-session-store.js +3 -0
- package/dist/plugins/file-resume-anchor-store.d.ts +7 -2
- package/dist/plugins/file-resume-anchor-store.js +19 -5
- package/dist/plugins/file-run-store.d.ts +21 -8
- package/dist/plugins/file-run-store.js +60 -38
- package/dist/plugins/local-session-store.d.ts +22 -0
- package/dist/plugins/local-session-store.js +74 -11
- package/dist/plugins/memory-run-store.d.ts +7 -5
- package/dist/plugins/memory-run-store.js +11 -4
- package/dist/plugins/one-time-migrations.d.ts +38 -1
- package/dist/plugins/one-time-migrations.js +143 -15
- package/dist/plugins/permission-rule-store-file.d.ts +9 -2
- package/dist/plugins/permission-rule-store-file.js +37 -51
- package/dist/plugins/pg-session-storage.d.ts +3 -0
- package/dist/plugins/pg-session-storage.js +19 -10
- package/dist/plugins/run-store-sql.d.ts +12 -4
- package/dist/plugins/run-store-sql.js +15 -13
- package/dist/plugins/send-file-ledger.d.ts +5 -1
- package/dist/plugins/send-file-ledger.js +11 -6
- package/dist/plugins/session-event-payload.d.ts +14 -4
- package/dist/plugins/session-event-payload.js +5 -2
- package/dist/plugins/store-backend.d.ts +7 -3
- package/dist/plugins/store-backend.js +10 -6
- package/dist/plugins/store-contracts.d.ts +7 -2
- package/dist/plugins/tidb-pool.js +8 -2
- package/dist/plugins/tidb-session-store.d.ts +6 -1
- package/dist/plugins/tidb-session-store.js +17 -10
- package/dist/project-identity.d.ts +4 -6
- package/dist/request-key-closure.js +1 -1
- package/dist/request-value-closure.d.ts +72 -3
- package/dist/request-value-closure.js +12 -4
- package/dist/roster-bound-http-status.d.ts +6 -0
- package/dist/roster-bound-http-status.js +6 -0
- package/dist/run-local.js +22 -27
- package/dist/runs.d.ts +22 -2
- package/dist/runs.js +29 -7
- package/dist/sealed-key.d.ts +31 -4
- package/dist/sealed-key.js +9 -0
- package/dist/security.d.ts +5 -1
- package/dist/session-children-retire.d.ts +92 -0
- package/dist/session-children-retire.js +85 -0
- package/dist/session-error-wire.d.ts +58 -0
- package/dist/session-error-wire.js +38 -0
- package/dist/session-incarnation.d.ts +61 -0
- package/dist/session-incarnation.js +43 -0
- package/dist/session-records-skipped-notice.d.ts +20 -0
- package/dist/session-records-skipped-notice.js +27 -0
- package/dist/tool-approval.d.ts +65 -0
- package/dist/tool-approval.js +36 -9
- package/dist/trace/core-keyset-guard.d.ts +8 -7
- package/dist/trace/engine-notice-wire.d.ts +3 -1
- package/dist/trace/engine-notice-wire.js +2 -0
- package/dist/trace/project.d.ts +1 -1
- package/dist/trace/project.js +9 -0
- package/dist/trace/wire-projection-faces.d.ts +10 -3
- package/dist/trace/wire-projection-faces.js +8 -2
- package/package.json +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { redactErrorMessage, redactHead, redactTerminalResult } from "../../observability/run-terminal.js";
|
|
2
2
|
import { runWithVerification, runCascade, taskNotificationDedupKey, uuidv7 } from "@sema-agent/core";
|
|
3
|
-
import { graftParkToolCallId, markChildrenStoppedByUserOnAbort,
|
|
3
|
+
import { graftParkToolCallId, markChildrenStoppedByUserOnAbort, syncRefusalHttpStatus, HEARTBEAT_MS } from "../../runs.js";
|
|
4
4
|
import { sealResultForExit, outwardPlane } from "../../terminal.js";
|
|
5
5
|
import { withPrincipal } from "../../observability/principal-context.js";
|
|
6
6
|
import { fleetRunPublisher, fleetRunLabels, fleetRunResiduals, isFleetAgentTerminalNotification } from "../../fleet/fleet-bus.js";
|
|
@@ -24,6 +24,7 @@ import { buildActiveRunConflict, toDoneFrameResult } from "../active-run-conflic
|
|
|
24
24
|
import { commitPlacement, devicePlacementErrorBody } from "../device-placement.js";
|
|
25
25
|
import { headerStr, gatedPrincipal, explicitOperatorOk } from "../principal-gate.js";
|
|
26
26
|
import { failOpenTagForDroppedFrame, recordFailOpen } from "../../observability/fail-open.js";
|
|
27
|
+
import { buildSyncSubmitBody } from "../sync-submit-body.js";
|
|
27
28
|
import { assertNever } from "../route-ctx.js";
|
|
28
29
|
const DISCONNECT_PARK_GRACE_MS = 10_000;
|
|
29
30
|
function sseData(res, payload) {
|
|
@@ -31,6 +32,9 @@ function sseData(res, payload) {
|
|
|
31
32
|
const idLine = typeof anchor === "string" && anchor.length > 0 ? `id: ${anchor}\n` : "";
|
|
32
33
|
res.write(`${idLine}data: ${JSON.stringify(payload)}\n\n`);
|
|
33
34
|
}
|
|
35
|
+
async function mintSubmitExitResult(result, checkpoints) {
|
|
36
|
+
return redactTerminalResult(sealResultForExit(await graftParkToolCallId(result, checkpoints)));
|
|
37
|
+
}
|
|
34
38
|
function sendSubmitResult(res, resp) {
|
|
35
39
|
const raw = resp.body;
|
|
36
40
|
if (typeof raw === "object" && raw !== null && Object.hasOwn(raw, "retryAfterSec") && "retryAfterSec" in raw) {
|
|
@@ -421,7 +425,7 @@ export async function handleTasks(req, res, match, ctx) {
|
|
|
421
425
|
userMsgEntryId = ev.entryId;
|
|
422
426
|
const cancelVerbAtDone = ev.type === "done" && durableTaskId !== undefined && cancelledViaVerb.has(durableTaskId);
|
|
423
427
|
if (ev.type === "done") {
|
|
424
|
-
finalResult =
|
|
428
|
+
finalResult = await mintSubmitExitResult(ev.result, deps.checkpointStore);
|
|
425
429
|
if (durableTaskId && finalResult)
|
|
426
430
|
finalResult = { ...finalResult, taskId: durableTaskId };
|
|
427
431
|
if (cancelVerbAtDone && finalResult !== undefined) {
|
|
@@ -652,10 +656,10 @@ export async function handleTasks(req, res, match, ctx) {
|
|
|
652
656
|
: withApproval());
|
|
653
657
|
if (durableTaskId && deps.runStore) {
|
|
654
658
|
const finalPlane = finalResult ? outwardPlane(finalResult.terminal) : undefined;
|
|
655
|
-
if (finalPlane?.status === "suspended" && deps.checkpointStore)
|
|
656
|
-
await deps.runStore.setSuspended(durableTaskId);
|
|
657
|
-
else if (finalPlane?.status === "needs_review" && deps.checkpointStore)
|
|
658
|
-
await deps.runStore.setNeedsReview(durableTaskId);
|
|
659
|
+
if (finalResult && finalPlane?.status === "suspended" && deps.checkpointStore)
|
|
660
|
+
await deps.runStore.setSuspended(durableTaskId, finalResult);
|
|
661
|
+
else if (finalResult && finalPlane?.status === "needs_review" && deps.checkpointStore)
|
|
662
|
+
await deps.runStore.setNeedsReview(durableTaskId, finalResult);
|
|
659
663
|
else if (finalResult && finalPlane)
|
|
660
664
|
await deps.runStore.setTerminal(durableTaskId, finalPlane.status, finalResult, finalPlane.errorMessage ?? null);
|
|
661
665
|
else {
|
|
@@ -667,7 +671,7 @@ export async function handleTasks(req, res, match, ctx) {
|
|
|
667
671
|
await ledgerSink.flush().catch(() => undefined);
|
|
668
672
|
await ledgerSink.appendParked("suspended", {}).catch(() => undefined);
|
|
669
673
|
}
|
|
670
|
-
await deps.runStore.setSuspended(durableTaskId);
|
|
674
|
+
await deps.runStore.setSuspended(durableTaskId, null);
|
|
671
675
|
settleFleet("suspended");
|
|
672
676
|
}
|
|
673
677
|
else {
|
|
@@ -710,7 +714,7 @@ export async function handleTasks(req, res, match, ctx) {
|
|
|
710
714
|
await ledgerSink.flush().catch(() => undefined);
|
|
711
715
|
await ledgerSink.appendParked("suspended", {}).catch(() => undefined);
|
|
712
716
|
}
|
|
713
|
-
await deps.runStore.setSuspended(durableTaskId);
|
|
717
|
+
await deps.runStore.setSuspended(durableTaskId, null);
|
|
714
718
|
settleFleet("suspended");
|
|
715
719
|
}
|
|
716
720
|
else if (finalResult) {
|
|
@@ -859,7 +863,7 @@ export async function handleTasks(req, res, match, ctx) {
|
|
|
859
863
|
engineResult: result,
|
|
860
864
|
});
|
|
861
865
|
}
|
|
862
|
-
const resumeAtStatus =
|
|
866
|
+
const resumeAtStatus = syncRefusalHttpStatus(result);
|
|
863
867
|
if (resumeAtStatus) {
|
|
864
868
|
const resumeAtPlane = outwardPlane(result.terminal);
|
|
865
869
|
if (durableTaskId && deps.runStore)
|
|
@@ -869,22 +873,21 @@ export async function handleTasks(req, res, match, ctx) {
|
|
|
869
873
|
: undefined;
|
|
870
874
|
return { status: resumeAtStatus, body: { errorCode: resumeAtPlane.errorCode, error: redactErrorMessage(resumeAtPlane.errorMessage) ?? "resume-at failed", ...(retryAfterSec !== undefined ? { retryAfterSec } : {}) } };
|
|
871
875
|
}
|
|
876
|
+
const exitResult = await mintSubmitExitResult(result, deps.checkpointStore);
|
|
872
877
|
const syncPlane = outwardPlane(result.terminal);
|
|
873
|
-
if (syncPlane.status === "suspended" && deps.checkpointStore && deps.runStore && prepared.spec.sessionId) {
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
return { status: 200, body: withSyncSubmitKeys({ taskId: durableTaskId, sessionId: prepared.spec.sessionId, status: "suspended" }) };
|
|
878
|
+
if (syncPlane.status === "suspended" && deps.checkpointStore && deps.runStore && durableTaskId && prepared.spec.sessionId) {
|
|
879
|
+
await deps.runStore.setSuspended(durableTaskId, exitResult);
|
|
880
|
+
return { status: 200, body: withSyncSubmitKeys(buildSyncSubmitBody(exitResult, { taskId: durableTaskId, sessionId: prepared.spec.sessionId, status: "suspended" })) };
|
|
877
881
|
}
|
|
878
|
-
if (syncPlane.status === "needs_review" && deps.checkpointStore && deps.runStore && prepared.spec.sessionId) {
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
return { status: 200, body: withSyncSubmitKeys({ taskId: durableTaskId, sessionId: prepared.spec.sessionId, status: "needs_review" }) };
|
|
882
|
+
if (syncPlane.status === "needs_review" && deps.checkpointStore && deps.runStore && durableTaskId && prepared.spec.sessionId) {
|
|
883
|
+
await deps.runStore.setNeedsReview(durableTaskId, exitResult);
|
|
884
|
+
return { status: 200, body: withSyncSubmitKeys(buildSyncSubmitBody(exitResult, { taskId: durableTaskId, sessionId: prepared.spec.sessionId, status: "needs_review" })) };
|
|
882
885
|
}
|
|
883
886
|
if (durableTaskId && deps.runStore)
|
|
884
|
-
await deps.runStore.setTerminal(durableTaskId, syncPlane.status,
|
|
887
|
+
await deps.runStore.setTerminal(durableTaskId, syncPlane.status, exitResult, syncPlane.errorMessage ?? null);
|
|
885
888
|
finalizeTaskResult(result, principal, prepared.spec.objective, prepared.spec.sessionId);
|
|
886
889
|
noteRunOutcome(result);
|
|
887
|
-
return { status: 200, body: withSyncSubmitKeys(
|
|
890
|
+
return { status: 200, body: withSyncSubmitKeys(buildSyncSubmitBody(exitResult)) };
|
|
888
891
|
};
|
|
889
892
|
const resp = await idemCache.run(idemKey, async () => withRunReceipt(await runSyncSubmitLeg()), (r) => r.status < 400);
|
|
890
893
|
sendSubmitResult(res, resp);
|
|
@@ -5,7 +5,7 @@ import { sleep } from "../sse-log.js";
|
|
|
5
5
|
import { bindSseLifecycle } from "../sse-lifecycle.js";
|
|
6
6
|
import { sendJson, sendError, sseHeaders, SSE_MAX_STREAM_MS, SSE_HEARTBEAT_IDLE_MS } from "../send.js";
|
|
7
7
|
import { filterFingerprint } from "../cursor-fingerprint.js";
|
|
8
|
-
import { gatedPrincipal } from "../principal-gate.js";
|
|
8
|
+
import { gatedPrincipal, sendUnauthorized } from "../principal-gate.js";
|
|
9
9
|
import { assertNever } from "../route-ctx.js";
|
|
10
10
|
const TOOL_RESULT_LIMIT_CAP = 262_144;
|
|
11
11
|
const TOOL_RESULT_OFFSET_CAP = 2_147_483_646;
|
|
@@ -14,7 +14,7 @@ export async function handleTraceUsage(req, res, match, ctx) {
|
|
|
14
14
|
const { isFleetWide, safeDecode } = ctx.helpers;
|
|
15
15
|
if (match.decl.id === "tasks-source-summary") {
|
|
16
16
|
if (!isFleetWide(req)) {
|
|
17
|
-
|
|
17
|
+
sendUnauthorized(res, "operator");
|
|
18
18
|
return;
|
|
19
19
|
}
|
|
20
20
|
if (!deps.runStore) {
|
|
@@ -34,7 +34,7 @@ export async function handleTraceUsage(req, res, match, ctx) {
|
|
|
34
34
|
const fleetWide = isFleetWide(req);
|
|
35
35
|
const gateOwner = fleetWide ? null : (gatedPrincipal(req, deps.config) || null);
|
|
36
36
|
if (!fleetWide && gateOwner === null) {
|
|
37
|
-
|
|
37
|
+
sendUnauthorized(res, "identity");
|
|
38
38
|
return;
|
|
39
39
|
}
|
|
40
40
|
if (!deps.runStore) {
|
|
@@ -84,7 +84,7 @@ export async function handleTraceUsage(req, res, match, ctx) {
|
|
|
84
84
|
const fleetWide = isFleetWide(req);
|
|
85
85
|
const jwtOwner = fleetWide ? undefined : gatedPrincipal(req, deps.config);
|
|
86
86
|
if (!fleetWide && !jwtOwner) {
|
|
87
|
-
|
|
87
|
+
sendUnauthorized(res, "identity");
|
|
88
88
|
return;
|
|
89
89
|
}
|
|
90
90
|
const q = new URLSearchParams(match.search);
|
package/dist/http/send.d.ts
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* now imports them from here, so all ~500 existing `sendJson(...)` call sites are unchanged text.
|
|
9
9
|
*/
|
|
10
10
|
import type { ServerResponse } from "node:http";
|
|
11
|
+
import { type SessionErrorFace } from "../session-error-wire.js";
|
|
11
12
|
/**
|
|
12
13
|
* [ref](黑板 [ref]②)—— 一条响应「是 SSE 流」的**在场标记**。
|
|
13
14
|
*
|
|
@@ -71,5 +72,16 @@ export declare function httpErrorCode(status: number, code?: string): string;
|
|
|
71
72
|
* `500 corrupt` 并点名那一列)。一只腿之后,新站点只会忘记调它,不会再各自发明一份映射。
|
|
72
73
|
*/
|
|
73
74
|
export declare function sendSessionPolicyError(res: ServerResponse, e: unknown): boolean;
|
|
75
|
+
/**
|
|
76
|
+
* S-612 —— core `SessionError` → 应答,经 {@link sessionErrorHttp} 那**一只**映射(`src/session-error-wire.ts`)。
|
|
77
|
+
* 回 `true` = 已应答,调用点 `return`;`false` = 不是 `SessionError`,或这个词在这一面上是登记过的留白(站点的既有
|
|
78
|
+
* 处置照旧 —— 通常是继续上抛到全局兜底)。
|
|
79
|
+
*
|
|
80
|
+
* 句子:属主给了固定句就发它(import 面 `invalid_session` 那一句),否则发 core 的原句过既有脱敏(`redactErrorMessage`:
|
|
81
|
+
* 不抛、有上限)。core 的 `corrupt_session` 原句只点名会话 id 与跳过计数(「Session <id> is unreadable: its log has no
|
|
82
|
+
* meta header (N of M records skipped as corrupt)」),SQL 两店的原句点名 `<表>.<列>` 与行号 —— 两者都不含盘上路径
|
|
83
|
+
* (路径只进运维日志:`session_repo_corrupt_read` 行)。
|
|
84
|
+
*/
|
|
85
|
+
export declare function sendSessionError(res: ServerResponse, e: unknown, face: SessionErrorFace): boolean;
|
|
74
86
|
export declare function msg(e: unknown): string;
|
|
75
87
|
//# sourceMappingURL=send.d.ts.map
|
package/dist/http/send.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { SessionPolicyError } from "@sema-agent/core";
|
|
1
|
+
import { SessionError, SessionPolicyError } from "@sema-agent/core";
|
|
2
2
|
import { sessionPolicyErrorHttp } from "../session-policy-wire.js";
|
|
3
|
+
import { sessionErrorHttp } from "../session-error-wire.js";
|
|
4
|
+
import { redactErrorMessage } from "../observability/run-terminal.js";
|
|
3
5
|
export const SSE_RESPONSE_MARK = Symbol("sema.http.sse-response");
|
|
4
6
|
export function isSseResponse(res) {
|
|
5
7
|
return res[SSE_RESPONSE_MARK] === true;
|
|
@@ -44,6 +46,15 @@ export function sendSessionPolicyError(res, e) {
|
|
|
44
46
|
sendError(res, h.status, h.errorCode, e.message);
|
|
45
47
|
return true;
|
|
46
48
|
}
|
|
49
|
+
export function sendSessionError(res, e, face) {
|
|
50
|
+
if (!(e instanceof SessionError))
|
|
51
|
+
return false;
|
|
52
|
+
const wire = sessionErrorHttp(e.code, face);
|
|
53
|
+
if (wire === undefined)
|
|
54
|
+
return false;
|
|
55
|
+
sendError(res, wire.status, wire.errorCode, wire.sentence ?? redactErrorMessage(e.message) ?? "session store error");
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
47
58
|
export function msg(e) {
|
|
48
59
|
return e instanceof Error ? e.message : String(e);
|
|
49
60
|
}
|
package/dist/http/server.d.ts
CHANGED
|
@@ -28,7 +28,7 @@ import type { QuotaTracker } from "../observability/cost-quota.js";
|
|
|
28
28
|
import type { ModelUsageTracker, PromptManifestTracker } from "../budget.js";
|
|
29
29
|
import { scopedIdempotencyKey } from "./idempotency.js";
|
|
30
30
|
export { scopedIdempotencyKey };
|
|
31
|
-
import type { ConsolidationSeatLabel } from "../boot/memory-consolidation.js";
|
|
31
|
+
import type { ConsolidationSeatLabel, ConsolidationValve } from "../boot/memory-consolidation.js";
|
|
32
32
|
import { streamApprovals, checkQuestionAnswer } from "./routes/approvals-assistant.js";
|
|
33
33
|
export { streamApprovals, checkQuestionAnswer };
|
|
34
34
|
import { cascadeConfig } from "./run-meta.js";
|
|
@@ -148,8 +148,9 @@ export interface ServiceStoreDeps {
|
|
|
148
148
|
/** [ref] per-edited-file rewind history store. Present ⇒ the rewind capabilities are advertised; core uses it
|
|
149
149
|
* via RunnerDeps.fileHistoryStore (first-touch tracking + per-turn boundaries + tracked-set restore, ANY
|
|
150
150
|
* env). Also the 2c history-transfer store (exportHistory/importHistory + blob negotiation faces).
|
|
151
|
-
* 🔴 S-
|
|
152
|
-
*
|
|
151
|
+
* 🔴 S-724:这是装配单点 `assembleFileHistory` 的**店**(后端在即在,与 `FILE_HISTORY_CAPTURE` 无关 —— 旋钮只关捕获,
|
|
152
|
+
* 落在 core 的 `RunnerDeps.fileHistoryCapture` 上)。rewind 族四位与 2c sync 路由族跟它走;能力词 `fileHistoryCapture`
|
|
153
|
+
* = `fileHistoryCaptureOf(本键, config.fileHistoryCapture)`(与 core 捕获位同一只判定)。
|
|
153
154
|
* 擦除(E21 / 孤儿 blob GC)不读本键,读 boot 侧的擦除脸。 */
|
|
154
155
|
fileHistoryStore?: ServiceFileHistoryStore;
|
|
155
156
|
/** D-1 通用文件上传(clay 拍 2026-07-27:独立附件 store,不骑 snapshot blob 面):enables
|
|
@@ -341,10 +342,14 @@ export interface ServiceSeamDeps {
|
|
|
341
342
|
* run-ledger/checkpoint/tool-result rows, owner-guarded, in one call. Returns `{ deleted }` (idempotent) — or
|
|
342
343
|
* `{ active }` when the runs-ledger TX re-asserted a still-live run (a concurrent createRun raced the route's
|
|
343
344
|
* pre-check), which the route maps to 409. Enables DELETE /v1/sessions/:id. Wired by main.ts (all the stores). */
|
|
345
|
+
/** E21 删除协调器。三种结局:删了 / 有活跑(`{active}`,409 `conflict.session_active_run`)/ S-790:以本会话为根的后台子代没停干净
|
|
346
|
+
* (`{childrenAlive}` = 仍活着的子代句柄,409 `conflict.session_children_alive` 的 `remaining[]`;会话记录不动)。 */
|
|
344
347
|
purgeSession?: (sessionId: string, owner: string | null) => Promise<{
|
|
345
348
|
deleted: boolean;
|
|
346
349
|
} | {
|
|
347
350
|
active: string;
|
|
351
|
+
} | {
|
|
352
|
+
childrenAlive: readonly string[];
|
|
348
353
|
}>;
|
|
349
354
|
/** [ref]③(b): read a BACKGROUND agent-handle child's final report / current status out of the core
|
|
350
355
|
* TaskRegistry (the same face the TaskOutput tool reads — agent handles are NEVER in the run store).
|
|
@@ -460,6 +465,12 @@ export interface ServiceSeamDeps {
|
|
|
460
465
|
* 装配漏接 ⇒ tsc 红(本行就是通知);测试桩在 `test/helpers/boot.ts` 显式给 false。
|
|
461
466
|
*/
|
|
462
467
|
memoryAutoConsolidationArmed: boolean;
|
|
468
|
+
/**
|
|
469
|
+
* S-824 / [ref] + 车PI 修复轮 ④ —— 记忆整理阀门的**生效判决**(boot 第 4 段 `createConsolidationValve`:显式词,或出厂缺省按
|
|
470
|
+
* 装配结果派生)。配置目录那一行(`GET /v1/config/catalog` 的 `MEMORY_CONSOLIDATION_DRIVER` `effectiveValue`)读它 —— 那一列的契约是
|
|
471
|
+
* 「本进程实际生效值」,而这根旋钮的生效值只有装配期才知道。🔴 **必填**:装配漏接 ⇒ tsc 红;测试桩在 `test/helpers/boot.ts` 显式给。
|
|
472
|
+
*/
|
|
473
|
+
memoryConsolidationValve: Pick<ConsolidationValve, "enabled" | "source">;
|
|
463
474
|
/** [ref] 件②(core 5.59.0 `MemoryEngine.listExternalOriginEntries` / `listOriginClearances` /
|
|
464
475
|
* `clearEntryOrigin`):**外源标记人面**。启用 `GET /v1/memory/origin/external`、
|
|
465
476
|
* `GET /v1/memory/origin/clearances`、`POST /v1/memory/origin/entries/:entryId/clear`(三口 operator-only)。
|
|
@@ -493,7 +504,8 @@ export interface ServiceSeamDeps {
|
|
|
493
504
|
/** [ref](core 5.58.0 `runMemoryConsolidationDriver`):记忆 **consolidation 阀门**的操作面。
|
|
494
505
|
* 启用 `POST /v1/admin/memory/consolidation/run` 与 `GET /v1/admin/memory/consolidation`(两口 operator-only)。
|
|
495
506
|
* main.ts 把它接到 `createMemoryConsolidationFaces` 的产物上。
|
|
496
|
-
* 🔴 缺席的**唯一**成因是「阀门没开」(`MEMORY_CONSOLIDATION_DRIVER
|
|
507
|
+
* 🔴 缺席的**唯一**成因是「阀门没开」(显式 `MEMORY_CONSOLIDATION_DRIVER=off`,或未设而出厂缺省派生成关 ——
|
|
508
|
+
* S-824 / [ref]:整理座落主模型 / 结构上跑不起来;判决属主 `boot/memory-consolidation.ts` `resolveConsolidationValve`):
|
|
497
509
|
* 阀门开着却结构上跑不了的三种形(引擎没接线 / 后端没有控制面归属 / `MEMORY_PROVENANCE=off`)在
|
|
498
510
|
* **启动期**就被拒了(`boot/memory-consolidation.ts`),那些机器根本起不来。⇒ 缺席形是 **404 族**
|
|
499
511
|
* (整域不挂),刻意**不是** 501:501 说「换部署形态」,这里的动作是「把旋钮打开」。全文见
|
|
@@ -755,6 +767,11 @@ export interface ServiceDeploymentDeps {
|
|
|
755
767
|
* ⚠️ 席位只承载**部署默认**:单用户车道上每请求的 `settings.webSearch` 压过它,但那条腿**不经过本席**
|
|
756
768
|
* (它在场景装配里每请求现算),所以本位不会随调用方漂。 */
|
|
757
769
|
webSearchProvider?: import("../plugins/web-search.js").WebSearchProvider;
|
|
770
|
+
/** S-737:本进程模型钥匙保管店的**公钥面** —— `GET /v1/capabilities` 的 `sealedKey` 段唯一席位。值**逐字**取自
|
|
771
|
+
* config-center 运行时(`boot/config-center.ts` 的 `sealedKeyPublic`,boot 期建的那一只店),路由里不再建店、不读全局。
|
|
772
|
+
* 类型只有最新那把公钥(`sealed-key.ts` `SealedKeyPublicFace`):私钥、保管路径、持有的旧 id 列表从这一层结构上够不着。
|
|
773
|
+
* 缺席 = 本进程没有保管店(boot 建店失败,或不是由 composition root 装起来的测试夹具形)⇒ caps 的 `sealedKey` 键缺席。 */
|
|
774
|
+
sealedKeyPublic?: import("../sealed-key.js").SealedKeyPublicFace;
|
|
758
775
|
/** ① core ruling — SPLIT: `capabilities.workflows` = the ENGINE-CAN axis, boot-computed from core's own
|
|
759
776
|
* `workflowsCapability(deps)` (hardened script runner ∧ governance), NOT the `Boolean(workflowRunStore)` store
|
|
760
777
|
* proxy. Orthogonal to `workflowsList` (the durable-list axis = `workflowRunStore`). Falls back to the store
|
package/dist/http/server.js
CHANGED
|
@@ -19,7 +19,7 @@ import { cascadeConfig } from "./run-meta.js";
|
|
|
19
19
|
export { cascadeConfig };
|
|
20
20
|
import { coarseStatusForState, errorCodeForExit } from "./routes/images.js";
|
|
21
21
|
export { coarseStatusForState, errorCodeForExit };
|
|
22
|
-
import { sendError, httpErrorCode, msg } from "./send.js";
|
|
22
|
+
import { sendError, sendSessionError, httpErrorCode, msg } from "./send.js";
|
|
23
23
|
import { createRequestGuards } from "./request-guards.js";
|
|
24
24
|
import { createAdmission, MAX_SKILL_CONTENT_CHARS, MAX_SYSTEM_PROMPT_CHARS, MAX_OUTPUT_SCHEMA_CHARS, validateUserSkills } from "./admission.js";
|
|
25
25
|
import { createResumeLegs } from "./resume-legs.js";
|
|
@@ -107,10 +107,13 @@ export function createHttpServer(rawDeps) {
|
|
|
107
107
|
return;
|
|
108
108
|
}
|
|
109
109
|
deps.logger?.error("request_error", { method: req.method, url: req.url, err: redactHead(msg(err), 2000) });
|
|
110
|
-
if (
|
|
111
|
-
sendError(res, 500, "internal.error", "internal error");
|
|
112
|
-
else
|
|
110
|
+
if (res.headersSent) {
|
|
113
111
|
res.end();
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
if (sendSessionError(res, err, "open"))
|
|
115
|
+
return;
|
|
116
|
+
sendError(res, 500, "internal.error", "internal error");
|
|
114
117
|
});
|
|
115
118
|
});
|
|
116
119
|
deps.deviceHub?.attach(server);
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* S-173 —— 非流式 `POST /v1/tasks` 的 200 体的**唯一铸点**。
|
|
3
|
+
*
|
|
4
|
+
* ## 一条规则
|
|
5
|
+
* 同步 200 体恒 = **「出口封口 + 脱敏后的引擎结果」**(调用方先 `redactTerminalResult(sealResultForExit(result))`
|
|
6
|
+
* 铸**一次**,同一份对象既落 run 行、又进本体 —— 两个载体同一只来源);run 还停在门上(park)⇒ 再带
|
|
7
|
+
* **poll 回执三键** {@link SyncParkReceipt}。park 不是例外:三个 200 出口(终局 / suspended / needs_review)都经本函数。
|
|
8
|
+
*
|
|
9
|
+
* ## 修前的病
|
|
10
|
+
* park 两臂自造 `{ taskId, sessionId, status }`,**没有** `terminal`;同一次 park 在 `/v1/tasks/stream` 的
|
|
11
|
+
* `done.result` 上是 `terminal.kind === "paused"`,在本腿上是一个状态词 —— 同一事实两形。
|
|
12
|
+
*
|
|
13
|
+
* ## 回执三键为什么还在(additive,不是 BREAKING)
|
|
14
|
+
* 修前的消费方按这三键判读(`status` 词 → 转去 `GET /v1/runs/:taskId` poll)。三键**原值原样**叠在结果之上:
|
|
15
|
+
* · `taskId` = 同步腿提交时铸的 durable run id(= 结果自带的 `taskId`:同步腿把它经 `spec.taskId` 交给引擎);
|
|
16
|
+
* · `sessionId` = 提交的会话(= 结果自带的 `sessionId`);
|
|
17
|
+
* · `status` = **对外词**,即 `GET /v1/runs/:id` 行上的那个词(`outwardPlane(result.terminal).status`,词由 core
|
|
18
|
+
* pause registry 的 `taskStatus` 列给)。引擎结果自 core 7.6.0 起**没有** `status` 键(D-8),所以不存在「两个
|
|
19
|
+
* status 打架」;这一键只在 park 时在场 —— 终局体上它从 7.64.0 起就不在,本件不把它加回去(那会给终局体
|
|
20
|
+
* 重新造一个 `terminal.kind` 之外的第二真源)。
|
|
21
|
+
* 回执叠在结果**之后**:三键的值恒等于修前,消费方读到的字节与修前逐字相同(R5 正控)。
|
|
22
|
+
*
|
|
23
|
+
* ## 安全轴
|
|
24
|
+
* 本函数**不**做封口 / 脱敏 —— 那两件事的属主是 `sealResultForExit`(`terminal.ts`)与 `redactTerminalResult`
|
|
25
|
+
* (`observability/run-terminal.ts`),调用方铸一次交进来;本函数只负责「体长什么样」。凭据(`paused.token` /
|
|
26
|
+
* `failed.nestedPause.token`)因此在进本函数之前就已摘掉,幂等缓存存的正是本函数的产物,重放体同体同脱。
|
|
27
|
+
*/
|
|
28
|
+
import type { ParkedRunStatus, PersistedTaskResult } from "../plugins/store-contracts.js";
|
|
29
|
+
/** park 中的 run 在同步 200 体上带的 poll 回执三键(修前 park 体的全部内容,值逐字不变)。 */
|
|
30
|
+
export interface SyncParkReceipt {
|
|
31
|
+
/** 同步腿提交时铸的 durable run id —— `GET /v1/runs/:taskId` 的 poll 键。 */
|
|
32
|
+
taskId: string;
|
|
33
|
+
/** 提交的会话。 */
|
|
34
|
+
sessionId: string;
|
|
35
|
+
/** 对外词 = `GET /v1/runs/:id` 行上的 `status`(park 两词之一,闭集从 `RUN_STATUS_CLASS` 派生)。 */
|
|
36
|
+
status: ParkedRunStatus;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* 铸同步 200 体。`exitResult` = 已封口已脱敏的引擎结果(与 run 行落的是同一份对象);`parkReceipt` 在场 ⇔ run 停在门上。
|
|
40
|
+
* 返回的是纯数据(无方法、无闭包)⇒ `build*`。
|
|
41
|
+
*/
|
|
42
|
+
export declare function buildSyncSubmitBody<R extends PersistedTaskResult>(exitResult: R, parkReceipt?: SyncParkReceipt): R | (R & SyncParkReceipt);
|
|
43
|
+
//# sourceMappingURL=sync-submit-body.d.ts.map
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import type { A2aServerSpec, AgentDefinition, ApproverPosture, McpServerSpec, SkillSpec } from "@sema-agent/core";
|
|
10
10
|
import type { SettingsPermissionMode } from "../task-settings.js";
|
|
11
11
|
import type { wiringManifestFaceEventData } from "../trace/project.js";
|
|
12
|
+
import type { buildSyncSubmitBody } from "./sync-submit-body.js";
|
|
12
13
|
export interface TaskRequestBody {
|
|
13
14
|
objective: string;
|
|
14
15
|
sessionId?: string;
|
|
@@ -173,8 +174,10 @@ export interface TaskRequestBody {
|
|
|
173
174
|
};
|
|
174
175
|
/** [ref] file restore ([ref]): with `resumeAt`, ALSO converge the working tree's **agent-edited files**
|
|
175
176
|
* (the tracked set — nothing else is visible to the history, so a user's parallel work is structurally
|
|
176
|
-
* untouchable) to that entry's history boundary. Capture needs no request
|
|
177
|
-
*
|
|
177
|
+
* untouchable) to that entry's history boundary. Capture needs no request: first-touch tracking is on
|
|
178
|
+
* whenever the deployment wires a history store, unless `FILE_HISTORY_CAPTURE=false` (the deployment's capture
|
|
179
|
+
* switch) or this request's {@link fileHistory} turns it off — restore reads what the store already holds
|
|
180
|
+
* either way. Requires a FileHistoryStore. */
|
|
178
181
|
restoreFiles?: boolean;
|
|
179
182
|
/** DV-15: opt-in tolerance for a PARTIAL file restore (default = loud terminal failure carrying the per-file
|
|
180
183
|
* ledger; `true` = keep going and disclose the same ledger on the result's rewindNotes). */
|
|
@@ -189,6 +192,17 @@ export interface TaskRequestBody {
|
|
|
189
192
|
* value is the same handle as `resumeAt` (the prompt's taskId); the service resolves it → the entry id. Honored ONLY
|
|
190
193
|
* when `resumeAt` is ABSENT (the two modes are mutually exclusive). Requires the anchor map + a FileHistoryStore. */
|
|
191
194
|
rewindFilesTo?: string;
|
|
195
|
+
/** S-724(core 7.31.0 #1048 `TaskSpec.fileHistory`)—— 请求级的**文件历史关断词**,唯一词 `"disabled"`(core 的拼法,
|
|
196
|
+
* 与 `checkpointStore` 同;没有 `"enabled"` —— 缺席就是「部署说了算」的唯一形,声明只能单向收紧)。`"disabled"` ⇒
|
|
197
|
+
* 这条 run 零历史店调用:编辑照常落盘,但不做首次触碰备份、不铸回合边界、不做 fork 携带;委派出去的子代继承
|
|
198
|
+
* (core `ParentSpecSeat` 从本位铸,本仓零接线)。`wiring_manifest.fileHistory` 报 `"disabled"`。
|
|
199
|
+
* 同一个提交里再要还原(`restoreFiles` / `rewindFilesTo` / 退役 `rewindFiles`)= 体内矛盾 ⇒ **受理时** 400
|
|
200
|
+
* `request.field_conflict`(`request-value-closure.ts` 的 `FILE_HISTORY_DISABLED_NO_RESTORE`):core 的 `rewind.capture_disabled`
|
|
201
|
+
* 落在会话按 `resumeAt` 分叉之后、拒后不回滚,所以本层在副作用之前拒。续跑腿不过这道门。
|
|
202
|
+
* ⚠️ 拼写门**两腿同判、响亮拒**:fresh 400 `request.field_invalid`;resume 重放同判(与 `memoryCapture` / `memory`
|
|
203
|
+
* 同一张单成员闭集表,`request-value-closure.ts` 的 `singleMemberOffFieldIssue`)。
|
|
204
|
+
* Rides the persisted body onto resume legs —— 它是这条 run 的策略,不是一次性历史动作(与 `rewindFilesTo` 不同,续跑不剥)。 */
|
|
205
|
+
fileHistory?: "disabled";
|
|
192
206
|
/** [ref] (core 1.246): per-task resilience INTENT flags. allowDegrade/allowFailover are caller-facing;
|
|
193
207
|
* bypassBreaker is operator-only (resolveSpec drops it for non-operators — a permission downgrade, not a 400). */
|
|
194
208
|
resilience?: {
|
|
@@ -238,8 +252,8 @@ export interface TaskRequestBody {
|
|
|
238
252
|
* behavior). Purely a render channel — core never merges the child stream into the parent's model context. */
|
|
239
253
|
forwardSubagentEvents?: boolean;
|
|
240
254
|
/** G3([ref] 壳侧承诺③/[ref]③):壳供 per-session scratchpad 路径(壳 vendored getScratchpadDir 的
|
|
241
|
-
* 约定路径)。接受后优先于 server 自算,同源喂 envFacts.scratchpadDir
|
|
242
|
-
*
|
|
255
|
+
* 约定路径)。接受后优先于 server 自算,同源喂 envFacts.scratchpadDir 宣告(core 据它开根围栏的洞,
|
|
256
|
+
* S-842 起是唯一写者)+ fs-write gate exemptDirs——壳提示词与 server 写门指同一个目录。验收 fail-closed(单用户 +
|
|
243
257
|
* host-semantics lane + 绝对路径/深度/长度门,规则在 env-facts.acceptShellScratchpadDir),拒收形
|
|
244
258
|
* warn 后回落自算——「没到货引擎忽略 = 无害 additive」的对偶:异形键忽略,任务照跑。 */
|
|
245
259
|
scratchpadDir?: string;
|
|
@@ -546,7 +560,11 @@ export type ApprovalStaleCurrentPending = {
|
|
|
546
560
|
* `unknown`,产物按段 present-iff 铸)。所以这一行**不**声称「wire 上的每一段都有静态型」;它声称的是
|
|
547
561
|
* 「这一键的值恒等于那只投影器的产物」,而那正是消费端唯一需要的那句话。段级判据的属主在 core。 */
|
|
548
562
|
export type WiringManifestReceipt = ReturnType<typeof wiringManifestFaceEventData>;
|
|
549
|
-
/** S-
|
|
563
|
+
/** S-173 —— `POST /v1/tasks`(**非流式**)200 体的值形(不含下方 {@link SyncSubmitExtraKeys}),**从铸点返回型派生**:
|
|
564
|
+
* 「封口脱敏后的引擎结果」,park 时再叠 poll 回执三键 `{taskId, sessionId, status}`。键表的唯一属主是
|
|
565
|
+
* `http/sync-submit-body.ts` 的 `buildSyncSubmitBody`(结果的键集属主是 core `TaskResult`),这里不手抄一张。 */
|
|
566
|
+
export type SyncSubmitBody = ReturnType<typeof buildSyncSubmitBody>;
|
|
567
|
+
/** S-528 —— `POST /v1/tasks`(**非流式**)200 体在 {@link SyncSubmitBody}(引擎结果 / park 回执)之外带的**附加键**。
|
|
550
568
|
*
|
|
551
569
|
* 两键都是 **additive + present-iff**,同一只装饰点铸(`routes/tasks.ts` 的 `withSyncSubmitKeys`),
|
|
552
570
|
* 所以三处 200 出口(终局 / suspended / needs_review)与幂等重放腿自动同形:
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { loadConfig, type ServiceConfig } from "./config.js";
|
|
2
|
+
export { composeExecutionLane, assertExecutionLaneInvariants } from "./boot/execution-lane.js";
|
|
2
3
|
export { createBrain } from "./brain.js";
|
|
3
4
|
export { createSessionStore } from "./plugins/session-store.js";
|
|
4
5
|
export { createStoreBackend, type StoreBackend, type SessionCaptureRecordSource } from "./plugins/store-backend.js";
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { loadConfig } from "./config.js";
|
|
2
|
+
export { composeExecutionLane, assertExecutionLaneInvariants } from "./boot/execution-lane.js";
|
|
2
3
|
export { createBrain } from "./brain.js";
|
|
3
4
|
export { createSessionStore } from "./plugins/session-store.js";
|
|
4
5
|
export { createStoreBackend } from "./plugins/store-backend.js";
|
package/dist/leader/merge.d.ts
CHANGED
|
@@ -60,9 +60,14 @@ export interface IntegrationRepair {
|
|
|
60
60
|
/**
|
|
61
61
|
* S-113 / clay [ref] ④ — **合不上 = 交给用户**(对齐 CC 形)。`git apply --3way` 冲突时的产出:冲突**路径**
|
|
62
62
|
* (不含内容)+ 哪几只 worker 的补丁已经进树,由 leader 铸成 `LeaderResult.conflict` 段交到用户手上。
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
63
|
+
* 本段刻意**只有路径与身份**,不把任何 worker 的 diff 交给模型。CC 对照(2.1.280 语料):`conflict resolution` 零命中,
|
|
64
|
+
* `collapse` 的 169 处命中里没有一处与「把并行 worker 收成一个」相关(UI 折叠 / context collapse 一类);teammates 各一个
|
|
65
|
+
* worktree,团队收尾对每个成员的 worktree 只做移除(移不掉就保留),这条路径上没有 merge / 重放回用户 HEAD(cli280.js:214129
|
|
66
|
+
* `swarm_team_cleanup` / `le`);`/batch` 是每个隔离 worktree agent 各开一个 PR(cli280.js:224700)。旧引的
|
|
67
|
+
* `cli259.js @2303113` 不是 teammates,而是 Directory sync:agent 未发布的 commit 重建到用户 HEAD 上,重放冲突时 commit
|
|
68
|
+
* 停到一个 ref、改动以未提交编辑留在工作树且用户的行胜出 —— 冲突是告诉**模型**的(路径 + blob id,不含 diff 正文;
|
|
69
|
+
* cli280.js:247957)。「CC 里没有模型读别的 worker 的 diff」只有缺席证据,未闭环(车LZ X2)。
|
|
70
|
+
* 7.83.0 删掉的那条「冲突解决模型」通道(它的类型面与 `LEADER_CONFLICT_ROUNDS` 旋钮)正是此意。
|
|
66
71
|
*/
|
|
67
72
|
export interface MergeConflict {
|
|
68
73
|
/** 有冲突标记或 `.rej` 的路径(**不含内容**;`.rej` 后缀已剥,指向源文件)。 */
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { redactIncarnations } from "./session-incarnation.js";
|
|
1
2
|
export function createMemoryEngineIncidentSink(deps) {
|
|
2
3
|
return (err, ctx) => {
|
|
3
4
|
const code = err?.code;
|
|
@@ -5,7 +6,7 @@ export function createMemoryEngineIncidentSink(deps) {
|
|
|
5
6
|
deps.logger.warn("memory_engine_incident", {
|
|
6
7
|
...(ctx?.sessionId !== undefined ? { sessionId: ctx.sessionId } : {}),
|
|
7
8
|
code: codeText ?? null,
|
|
8
|
-
detail: String(err),
|
|
9
|
+
detail: redactIncarnations(String(err)),
|
|
9
10
|
});
|
|
10
11
|
deps.metrics?.inc("memory_engine_incident_total", { code: codeText ?? "none" });
|
|
11
12
|
};
|
package/dist/model-select.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type Model, type RunnerDeps } from "@sema-agent/core";
|
|
1
2
|
import type { ModelEntryRefusal } from "./model-entry-refusal.js";
|
|
2
3
|
/**
|
|
3
4
|
* Resolve the model ref for a task spec from the request (CLI `/model` picker + `run --model`).
|
|
@@ -28,6 +29,14 @@ import type { ModelEntryRefusal } from "./model-entry-refusal.js";
|
|
|
28
29
|
* `resolveModel("default", catalog)` 解它)。**单点**:读面要说「这台部署的主模型是谁」时读同一个词
|
|
29
30
|
* (`auto-mode-face.ts` 的席解析器入参),两处各写一个 `"default"` 字面串正是漂移的成因。 */
|
|
30
31
|
export declare const DEFAULT_MODEL_REF = "default";
|
|
32
|
+
/**
|
|
33
|
+
* 本仓给一条**没选模型**的 task 铸的主模型 —— {@link DEFAULT_MODEL_REF} 在**展开**目录上(与引擎构造期 `expandTiers(models, tiers)`
|
|
34
|
+
* 之后再解逐字同源)解到的那只**目录条目**(对象引用)。`boot/resolve-spec.ts` 每条 spec 都盖 `spec.model`,所以引擎眼里的 main
|
|
35
|
+
* 恒是它,**不是** core 的 `default` **角色**链。解不出 ⇒ 抛(core 的拒句);调用方决定披露形。
|
|
36
|
+
* 读它的两处(`auto-mode-face.ts` 的分类器席 / `boot/memory-consolidation.ts` 的整理座是否落主模型)调这同一只 —— 车PI 修复轮 ⑦(h)
|
|
37
|
+
* 起不再各抄一份「展开 + 解」。
|
|
38
|
+
*/
|
|
39
|
+
export declare function resolveMainModel(plane: Pick<RunnerDeps, "models" | "tiers">): Model;
|
|
31
40
|
export declare function resolveTaskModel(bodyModel: unknown, objective: string, catalog: Record<string, unknown>, allowlist?: readonly string[], refusals?: Readonly<Record<string, ModelEntryRefusal>>): {
|
|
32
41
|
model: string;
|
|
33
42
|
cleanedObjective: string;
|
package/dist/model-select.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import { expandTiers, parseModelMention } from "@sema-agent/core";
|
|
1
|
+
import { expandTiers, parseModelMention, resolveTaskModel as coreResolveTaskModel } from "@sema-agent/core";
|
|
2
2
|
export const DEFAULT_MODEL_REF = "default";
|
|
3
|
+
export function resolveMainModel(plane) {
|
|
4
|
+
const expanded = expandTiers(plane.models, plane.tiers ?? {}) ?? plane.models;
|
|
5
|
+
return coreResolveTaskModel({ model: DEFAULT_MODEL_REF }, { ...(expanded !== undefined ? { models: expanded } : {}) }).model;
|
|
6
|
+
}
|
|
3
7
|
export function resolveTaskModel(bodyModel, objective, catalog, allowlist, refusals) {
|
|
4
8
|
const mention = parseModelMention(objective, [...Object.keys(refusals ?? {}), ...Object.keys(catalog)]);
|
|
5
9
|
const mentionUsable = mention.model !== undefined && Object.hasOwn(catalog, mention.model) ? mention.model : undefined;
|