@sema-agent/server 7.149.0 → 7.150.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 +122 -9
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/USAGE.md +39 -15
- package/dist/approval-card.d.ts +1 -1
- package/dist/approval-gate-currency.d.ts +1 -1
- package/dist/audit.d.ts +1 -1
- package/dist/audit.js +2 -2
- package/dist/background-session-reap.d.ts +1 -1
- package/dist/boot/deferred-sandbox-path-env.d.ts +5 -3
- package/dist/boot/deferred-sandbox-path-env.js +1 -2
- package/dist/boot/parked-revive-gate.d.ts +5 -5
- package/dist/boot/parked-revive-gate.js +2 -3
- package/dist/boot/resolve-spec.d.ts +4 -5
- package/dist/boot/resolve-spec.js +61 -25
- package/dist/boot/retention-lane.d.ts +1 -1
- package/dist/boot/session-faces.js +21 -21
- package/dist/boot/stage-03-store-backend.js +2 -2
- package/dist/boot/stage-06-runners.js +1 -2
- package/dist/boot/stage-07-capability-layer.js +1 -1
- package/dist/boot/stage-10-http-server.d.ts +33 -1
- package/dist/boot/stage-10-http-server.js +9 -4
- package/dist/boot/web-admin.d.ts +1 -1
- package/dist/capability-facts.d.ts +65 -56
- package/dist/capability-facts.js +42 -35
- package/dist/config-catalog.js +1 -1
- package/dist/config-types.d.ts +12 -11
- package/dist/deployment-governance.d.ts +7 -28
- package/dist/deployment-governance.js +1 -14
- package/dist/device-ws-hub.d.ts +1 -0
- package/dist/device-ws-hub.js +64 -28
- package/dist/device-ws-protocol.d.ts +20 -6
- package/dist/device-ws-protocol.js +9 -2
- package/dist/engine-identity.d.ts +7 -1
- package/dist/engine-identity.js +5 -0
- package/dist/field-conflict.d.ts +2 -2
- package/dist/fleet/engine-signal.d.ts +14 -1
- package/dist/fleet/engine-signal.js +5 -1
- package/dist/fleet/fleet-reconciler.d.ts +1 -1
- package/dist/fleet/serving-lease.d.ts +18 -3
- package/dist/fleet/serving-lease.js +81 -35
- package/dist/fleet-client.d.ts +13 -11
- package/dist/fleet-client.js +53 -33
- package/dist/history-anchor.js +1 -1
- package/dist/hitl-delivery.d.ts +1 -3
- package/dist/hitl-delivery.js +1 -1
- package/dist/http/active-run-conflict.d.ts +3 -7
- package/dist/http/active-run-conflict.js +2 -2
- package/dist/http/admission.js +2 -2
- package/dist/http/approval-sweeps.js +2 -1
- package/dist/http/caller-trust.d.ts +2 -2
- package/dist/http/caller-trust.js +3 -3
- package/dist/http/checkpoint-ctx.d.ts +18 -63
- package/dist/http/checkpoint-ctx.js +1 -24
- package/dist/http/claim-heartbeat.d.ts +4 -4
- package/dist/http/claim-heartbeat.js +3 -3
- package/dist/http/dispatch.js +2 -2
- package/dist/http/durable-run-leg.js +4 -4
- package/dist/http/owner-access.d.ts +243 -19
- package/dist/http/owner-access.js +184 -5
- package/dist/http/readiness.d.ts +4 -2
- package/dist/http/resume-ctx-read.js +16 -1
- package/dist/http/resume-legs.js +18 -14
- package/dist/http/route-ctx.d.ts +23 -11
- package/dist/http/routes/a2a-serve.js +15 -14
- package/dist/http/routes/approvals-assistant.d.ts +3 -2
- package/dist/http/routes/approvals-assistant.js +8 -9
- package/dist/http/routes/capabilities.js +4 -3
- package/dist/http/routes/config-catalog.d.ts +1 -1
- package/dist/http/routes/mcp-reconnect.js +2 -2
- package/dist/http/routes/memory-origin.d.ts +1 -1
- package/dist/http/routes/notify-wake.js +2 -3
- package/dist/http/routes/projects.d.ts +1 -0
- package/dist/http/routes/projects.js +5 -3
- package/dist/http/routes/retention-ops.d.ts +1 -1
- package/dist/http/routes/run-permission-mode.d.ts +1 -1
- package/dist/http/routes/run-permission-mode.js +2 -2
- package/dist/http/routes/runs.d.ts +1 -1
- package/dist/http/routes/runs.js +23 -30
- package/dist/http/routes/session-memory-sync.js +4 -5
- package/dist/http/routes/session-sync.js +3 -7
- package/dist/http/routes/sessions.d.ts +1 -1
- package/dist/http/routes/sessions.js +18 -44
- package/dist/http/routes/tasks.js +9 -8
- package/dist/http/routes/trace-usage.js +14 -14
- package/dist/http/routes/workflows.d.ts +1 -0
- package/dist/http/routes/workflows.js +20 -38
- package/dist/http/server.d.ts +8 -4
- package/dist/http/server.js +5 -1
- package/dist/http/stored-body-replay.d.ts +3 -24
- package/dist/http/stored-body-replay.js +2 -12
- package/dist/http/submit-ctx.d.ts +1 -2
- package/dist/http/submit-ctx.js +3 -2
- package/dist/http/submit-replay.d.ts +15 -2
- package/dist/http/submit-replay.js +10 -4
- package/dist/http/wire-types.d.ts +6 -3
- package/dist/leader/endpoint.js +9 -8
- package/dist/leg-facts.d.ts +8 -2
- package/dist/leg-facts.js +1 -0
- package/dist/mcp-authorization-face.d.ts +18 -14
- package/dist/mcp-authorization-face.js +3 -2
- package/dist/memory-store-refusal.d.ts +1 -1
- package/dist/observability/corrupt-read-seat.d.ts +1 -1
- package/dist/observability/fail-open.d.ts +5 -5
- package/dist/observability/fail-open.js +5 -5
- package/dist/observability/logger.d.ts +7 -0
- package/dist/observability/logger.js +3 -1
- package/dist/observability/run-terminal.d.ts +1 -1
- package/dist/owner-faces.d.ts +27 -3
- package/dist/owner-faces.js +2 -0
- package/dist/peer-seat.d.ts +1 -1
- package/dist/peer-seat.js +52 -59
- package/dist/plugins/exec-path-law.d.ts +34 -0
- package/dist/plugins/exec-path-law.js +13 -0
- package/dist/plugins/file-run-store.js +1 -1
- package/dist/plugins/local-checkpoint-store.d.ts +4 -1
- package/dist/plugins/local-checkpoint-store.js +3 -0
- package/dist/plugins/memory-run-store.js +1 -1
- package/dist/plugins/one-time-migrations.d.ts +74 -49
- package/dist/plugins/one-time-migrations.js +134 -69
- package/dist/plugins/pg-pool.js +4 -0
- package/dist/plugins/posix-shell-fs.js +4 -2
- package/dist/plugins/remote-env-adb.js +3 -2
- package/dist/plugins/remote-env-device.js +8 -6
- package/dist/plugins/remote-env-e2b.d.ts +3 -1
- package/dist/plugins/remote-env-e2b.js +11 -8
- package/dist/plugins/remote-env-host.d.ts +1 -1
- package/dist/plugins/remote-env-host.js +20 -11
- package/dist/plugins/remote-env-k8s.js +3 -2
- package/dist/plugins/remote-env-local-docker.js +3 -2
- package/dist/plugins/remote-env-ssh.js +4 -3
- package/dist/plugins/remote-shell.d.ts +3 -1
- package/dist/plugins/remote-shell.js +3 -3
- package/dist/plugins/replica-registration.d.ts +35 -0
- package/dist/plugins/replica-registration.js +48 -0
- package/dist/plugins/retention-lane-store-sql.d.ts +1 -1
- package/dist/plugins/run-store-sql.d.ts +1 -1
- package/dist/plugins/run-store-sql.js +2 -2
- package/dist/plugins/scenario-prefix-switch-m42.d.ts +6 -12
- package/dist/plugins/scenario-prefix-switch-m42.js +7 -5
- package/dist/plugins/schema-consistency.d.ts +7 -5
- package/dist/plugins/schema-consistency.js +29 -16
- package/dist/plugins/schema-drift-sentence.js +1 -1
- package/dist/plugins/serving-requirement.d.ts +49 -0
- package/dist/plugins/serving-requirement.js +53 -0
- package/dist/plugins/stop-then-start-sentence.d.ts +42 -3
- package/dist/plugins/stop-then-start-sentence.js +44 -0
- package/dist/plugins/store-backend.d.ts +1 -1
- package/dist/plugins/store-contracts.d.ts +12 -2
- package/dist/plugins/store-contracts.js +3 -0
- package/dist/plugins/tidb-pool.js +4 -0
- package/dist/process-instance.d.ts +3 -0
- package/dist/process-instance.js +7 -0
- package/dist/project-context.d.ts +66 -0
- package/dist/project-context.js +70 -0
- package/dist/question.d.ts +9 -21
- package/dist/question.js +28 -19
- package/dist/run-cancel-card.d.ts +1 -1
- package/dist/run-cancel-card.js +2 -1
- package/dist/security.d.ts +1 -1
- package/dist/session-agent.d.ts +1 -10
- package/dist/session-agent.js +0 -6
- package/dist/session-incarnation.d.ts +18 -4
- package/dist/session-incarnation.js +4 -1
- package/dist/session-notify-door.d.ts +4 -4
- package/dist/session-notify-door.js +5 -6
- package/dist/session-rules-seat.d.ts +4 -3
- package/dist/session-rules-seat.js +3 -11
- package/dist/session-sync.js +3 -3
- package/dist/stores-sql/checkpoint-store-sql.d.ts +21 -2
- package/dist/stores-sql/checkpoint-store-sql.js +106 -18
- package/dist/stores-sql/retention-store-sql.d.ts +1 -1
- package/dist/task-cwd.d.ts +4 -3
- package/dist/task-settings.d.ts +13 -0
- package/dist/task-settings.js +13 -7
- package/dist/tool-approval.d.ts +7 -6
- package/dist/tool-approval.js +41 -37
- package/dist/trace/engine-notice-wire.d.ts +14 -0
- package/dist/trace/engine-notice-wire.js +18 -1
- package/dist/trace/project.d.ts +4 -3
- package/dist/trace/project.js +3 -2
- package/dist/trace/projection-table.d.ts +33 -2
- package/dist/trace/self-minted-wire.d.ts +150 -17
- package/dist/trace/self-minted-wire.js +54 -16
- package/dist/trace/tool-card.d.ts +3 -0
- package/dist/trace/tool-card.js +24 -0
- package/dist/trace/tool-output-media.d.ts +2 -1
- package/dist/unattended-permission-mode.d.ts +1 -1
- package/dist/web-admin-client/apply-effective.d.ts +1 -1
- package/dist/web-admin-client/effective-keys.d.ts +1 -1
- package/dist/web-admin-client/skills-mcp.d.ts +1 -1
- package/docs/DEVICE-EXECUTOR-PROTOCOL.md +57 -29
- package/package.json +2 -2
- package/wire-changes/server@7.150.0.json +335 -0
|
@@ -13,7 +13,7 @@ function hostGateCwd(config, localRoot) {
|
|
|
13
13
|
return join(config.localDataRoot ?? localRoot, "parked-revive-unrooted");
|
|
14
14
|
}
|
|
15
15
|
export function createParkedReviveInheritedGate(deps) {
|
|
16
|
-
const { config,
|
|
16
|
+
const { config, approvalExemptionStore, logger, localRoot, approverSeat } = deps;
|
|
17
17
|
const slots = deps.slots ?? sandboxPathEnvSlots;
|
|
18
18
|
return async (row, identity) => {
|
|
19
19
|
const metadata = await chainMetadataOf(deps, row, identity);
|
|
@@ -32,7 +32,6 @@ export function createParkedReviveInheritedGate(deps) {
|
|
|
32
32
|
const rootSessionId = row.rootSessionId;
|
|
33
33
|
const baseline = createApprovalBaselinePolicy(config, {
|
|
34
34
|
kind: "durable",
|
|
35
|
-
question,
|
|
36
35
|
...(approvalExemptionStore !== undefined && rootSessionId ? { exemption: createSessionExemptionRead(approvalExemptionStore, rootSessionId, logger, "deployment_list", "parked_revive") } : {}),
|
|
37
36
|
});
|
|
38
37
|
const governed = applyRuntimeGovernance({ objective: "", toolPolicy: baseline }, createDeploymentGovernanceInputs(config, pathAdjudication));
|
|
@@ -53,7 +52,7 @@ async function chainMetadataOf(deps, row, identity) {
|
|
|
53
52
|
const forced = caps?.forceDurableGate === true;
|
|
54
53
|
return {
|
|
55
54
|
...(forced || deps.approverSeat === undefined ? { durableMandate: true } : {}),
|
|
56
|
-
...(forced || deps.
|
|
55
|
+
...(forced || !deps.questionSeat ? { contentMandate: true } : {}),
|
|
57
56
|
...autoModePostureOf(deps, row, caps),
|
|
58
57
|
};
|
|
59
58
|
}
|
|
@@ -3,7 +3,6 @@ import { sendUserFileTool } from "../capabilities/send-user-file-tool.js";
|
|
|
3
3
|
import { selectScenario } from "../capabilities/scenarios.js";
|
|
4
4
|
import type { LoadedSkill } from "../capabilities/skills.js";
|
|
5
5
|
import type { ServiceConfig } from "../config.js";
|
|
6
|
-
import { type LiveQuestionFace } from "../deployment-governance.js";
|
|
7
6
|
import { FleetEventBus } from "../fleet/fleet-bus.js";
|
|
8
7
|
import { type HookLlmCall } from "../hooks/hook-runner.js";
|
|
9
8
|
import type { createHookLlm } from "../hooks/hook-llm.js";
|
|
@@ -64,10 +63,10 @@ export interface ResolveSpecCtx {
|
|
|
64
63
|
/** [ref]:记忆同步腿(开 `MEMORY_SYNC_*` 且记忆引擎接线时在场)—— 项目层准备一步把本任务的项目层交给它跟踪(`memory-project-layer.ts`)。 */
|
|
65
64
|
memorySyncRunner: MemorySyncRunner | undefined;
|
|
66
65
|
durableEnabled: boolean;
|
|
67
|
-
/**
|
|
68
|
-
*
|
|
69
|
-
* (否则 spec.onQuestion 恒遮蔽 RunnerDeps.onQuestion
|
|
70
|
-
|
|
66
|
+
/** 问题席在场(= `ASK_QUESTION_ENABLED` 装了 `QuestionCoordinator`,`RunnerDeps.onQuestion` 是它):本仓「问题席在不在」这一事实的**一位**,
|
|
67
|
+
* 三个读者同读 —— 本文件的 posture 判据与 sentinel 铸不铸、赎回链的 `contentMandate`(`parked-revive-gate.ts`)。在场 ⇒ spec 不铸
|
|
68
|
+
* `QUESTION_AWAITS_RESUME`(否则 `spec.onQuestion` 恒遮蔽 `RunnerDeps.onQuestion` 的问题席);落点归 core 的同步优先。 */
|
|
69
|
+
questionSeat: boolean;
|
|
71
70
|
/**
|
|
72
71
|
* [ref] 件C —— 部署级**活体审批席**(`RunnerDeps.onAsk` 的同源铸法,main.ts 递
|
|
73
72
|
* `createRunnerDepsOnAsk(toolApproval)`;单一属主同 `boot/runner-deps.ts`,与 `parked-revive-gate.ts`
|
|
@@ -15,6 +15,9 @@ import { acceptShellScratchpadDir, buildEnvFacts, egressForRemoteExec, ensureScr
|
|
|
15
15
|
import { FleetEventBus } from "../fleet/fleet-bus.js";
|
|
16
16
|
import { createSettingsHooksRegistrations, settingsHooksBudgetMs } from "../hooks/hook-runner.js";
|
|
17
17
|
import { headerStr } from "../http/principal-gate.js";
|
|
18
|
+
import { routeListFilter } from "../http/owner-access.js";
|
|
19
|
+
import { projectRegistry } from "../capability-facts.js";
|
|
20
|
+
import { projectContextOf } from "../project-context.js";
|
|
18
21
|
import { explicitOperatorOk } from "../http/server.js";
|
|
19
22
|
import { isAtMentionable, matchCatalogModel, pickUserModel, refusedCatalogEntry, terminalCatalogName } from "../model-select.js";
|
|
20
23
|
import { echoModelRef, modelNotAllowedMessage, modelUnavailableMessage, refusedNameLogField } from "../model-entry-refusal.js";
|
|
@@ -48,7 +51,7 @@ import { storedToolAxesRereadM19 } from "../stored-request-tool-axes-m19.js";
|
|
|
48
51
|
import { storedHooksRereadM20 } from "../stored-request-hooks-m20.js";
|
|
49
52
|
import { storedEnvCredentialsDropM38 } from "../stored-request-env-credentials-m38.js";
|
|
50
53
|
import { serverCredentialValueSources } from "../server-secret-env.js";
|
|
51
|
-
import { MAX_SETTINGS_OUTPUT_STYLE_CHARS, REQUEST_SETTINGS_REFUSAL_PREFIX, SETTINGS_RULE_REFUSAL_CODE, SettingsRuleRefusalError, acceptAppendSystemPrompt, applyTaskSettings, createWorkflowAskPolicy, effectivePermissionMode, effectiveThinking, parseTaskSettings, readSettingsEnv, taskHooksHonored, settingsEnvCredentialIssue, settingsPermissionBucketIssue, withoutKeys } from "../task-settings.js";
|
|
54
|
+
import { MAX_SETTINGS_OUTPUT_STYLE_CHARS, REQUEST_SETTINGS_REFUSAL_PREFIX, SETTINGS_RULE_REFUSAL_CODE, SettingsRuleRefusalError, acceptAppendSystemPrompt, acceptOutputStyle, appendFold, applyTaskSettings, createWorkflowAskPolicy, effectivePermissionMode, effectiveThinking, parseTaskSettings, readSettingsEnv, taskHooksHonored, settingsEnvCredentialIssue, settingsPermissionBucketIssue, withoutKeys } from "../task-settings.js";
|
|
52
55
|
import { tightenOnlySeatIssue } from "../tighten-only-seats.js";
|
|
53
56
|
import { buildNeverAutoRetiredNotice } from "../retired-name-host-notice.js";
|
|
54
57
|
import { entryProblemsFacts } from "../entry-problems.js";
|
|
@@ -71,7 +74,7 @@ function unrooted(spec) {
|
|
|
71
74
|
return resolved;
|
|
72
75
|
}
|
|
73
76
|
export function createResolveSpec(ctx) {
|
|
74
|
-
const { config, logger, metrics, localRoot, scenarios, principalCaps, centerRuntimeCapsResolver, getKeyResolver, taskAttachmentStore, perSessionCwd, setSessionCwd, setSessionShellEnv, fenceSessionOwner, hookLlm, hookAgent, belowTaskChainPatterns, fleetBus, hookWakeBus, historyAnchors, ownerAware, taskLimitCaps, taskTimeoutSec, selectEnvTool, sendUserFileToolSpec, memoryEngine, memorySyncRunner, durableEnabled, approvalExemptionStore, checkpointStore, imageIndex, perTaskImage, sessionEnvSelection,
|
|
77
|
+
const { config, logger, metrics, localRoot, scenarios, principalCaps, centerRuntimeCapsResolver, getKeyResolver, taskAttachmentStore, perSessionCwd, setSessionCwd, setSessionShellEnv, fenceSessionOwner, hookLlm, hookAgent, belowTaskChainPatterns, fleetBus, hookWakeBus, historyAnchors, ownerAware, taskLimitCaps, taskTimeoutSec, selectEnvTool, sendUserFileToolSpec, memoryEngine, memorySyncRunner, durableEnabled, approvalExemptionStore, checkpointStore, imageIndex, perTaskImage, sessionEnvSelection, questionSeat, approverSeat, lockedKeys, loadedSkills, peerDesk, } = ctx;
|
|
75
78
|
const deploymentSkillSources = new Map(loadedSkills.map((k) => [k.spec.name, k.source]));
|
|
76
79
|
const scenarioGate = createScenarioGate({ config, scenarios, principalCaps, logger }, "enforce");
|
|
77
80
|
const sessionHeadOf = headReadOf(ownerAware);
|
|
@@ -109,9 +112,40 @@ export function createResolveSpec(ctx) {
|
|
|
109
112
|
}
|
|
110
113
|
if (opts?.leg === "fresh")
|
|
111
114
|
assertRequestMcpEntries(body.mcpServers);
|
|
115
|
+
const submittedProjectId = auth?.resolvedProjectId ?? (typeof body.projectId === "string" && body.projectId ? body.projectId.toLowerCase() : undefined);
|
|
116
|
+
const legProjectId = await legProjectIdOf(submittedProjectId, sessionWorkspace, root);
|
|
117
|
+
let projectContext;
|
|
118
|
+
if (opts?.leg === "fresh") {
|
|
119
|
+
const registry = projectRegistry({ config });
|
|
120
|
+
const decision = projectContextOf({
|
|
121
|
+
projectId: legProjectId,
|
|
122
|
+
registry: registry.available ? registry.registry : undefined,
|
|
123
|
+
viewer: req === undefined ? undefined : routeListFilter(req, { config }, "project-get"),
|
|
124
|
+
pathsHonored: DEPLOYMENT_SHAPE_PREDICATES.callerOwnsWorkerDisk.holds(config),
|
|
125
|
+
requestCwd: typeof body.cwd === "string" && body.cwd.length > 0,
|
|
126
|
+
projectMemoryOff: body.projectMemory === "disabled",
|
|
127
|
+
});
|
|
128
|
+
projectContext = decision.context;
|
|
129
|
+
if (decision.withheldPathItems > 0)
|
|
130
|
+
logger.warn("task_project_paths_ignored", { lane: config.remoteExec.provider, pathItems: decision.withheldPathItems, sessionId: root });
|
|
131
|
+
if (projectContext?.brief !== undefined) {
|
|
132
|
+
const append = acceptAppendSystemPrompt(body.appendSystemPrompt);
|
|
133
|
+
const style = acceptOutputStyle(body.settings?.outputStyle);
|
|
134
|
+
const fold = appendFold([append, projectContext.brief, style]);
|
|
135
|
+
if (fold.chars > MAX_SETTINGS_OUTPUT_STYLE_CHARS) {
|
|
136
|
+
const members = append !== undefined ? ["appendSystemPrompt", "projectId"] : ["projectId"];
|
|
137
|
+
if (style !== undefined)
|
|
138
|
+
members.push("settings.outputStyle");
|
|
139
|
+
throw new HttpError(400, `the project brief this run inherits from project ${projectContext.projectId} (its goal, notes and context items) folds into one system-prompt block with appendSystemPrompt and settings.outputStyle — combined they must be at most ${MAX_SETTINGS_OUTPUT_STYLE_CHARS} characters (including the 2-char joiners), and they are ${fold.chars}. Shorten what you send, send projectMemory: "disabled" to run without the project's context, or have the project's goal / notes shortened in the registry.`, { code: "request.field_conflict", extra: { ...fieldConflictFacts("system_prompt_fold", members, { count: fold.chars, cap: MAX_SETTINGS_OUTPUT_STYLE_CHARS }) } });
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
else
|
|
144
|
+
projectContext = opts?.projectContext;
|
|
145
|
+
const legCwd = projectContext?.cwd ?? body.cwd;
|
|
112
146
|
if (opts?.leg === "fresh") {
|
|
113
147
|
const conflict = scratchpadCoveringTaskRoot({
|
|
114
|
-
cwd:
|
|
148
|
+
cwd: legCwd,
|
|
115
149
|
shellScratchpadDir: body.scratchpadDir,
|
|
116
150
|
localDataRoot: config.localDataRoot ?? localRoot,
|
|
117
151
|
sessionId: root,
|
|
@@ -119,7 +153,11 @@ export function createResolveSpec(ctx) {
|
|
|
119
153
|
callerOwnsWorkerDisk: DEPLOYMENT_SHAPE_PREDICATES.callerOwnsWorkerDisk.holds(config),
|
|
120
154
|
});
|
|
121
155
|
if (conflict) {
|
|
122
|
-
|
|
156
|
+
const cwdCoordinate = projectContext?.cwd !== undefined ? "projectId" : "cwd";
|
|
157
|
+
const fields = body.scratchpadDir === conflict.scratchpadDir.asSpelled ? [cwdCoordinate, "scratchpadDir"] : [cwdCoordinate];
|
|
158
|
+
throw new HttpError(400, cwdCoordinate === "projectId"
|
|
159
|
+
? `the working directory "${conflict.cwd.asSpelled}" this run inherits from project ${projectContext?.projectId} (its first folder) is inside this session's scratchpad "${conflict.scratchpadDir.asSpelled}" — the scratchpad is the fs-write gate's EXEMPT directory, so a task rooted there would auto-approve every write under its own root and the engine refuses to build the gate at all (config.write_exempt_dir_covers_root). Send a cwd outside the scratchpad with this request, or have the project's first folder moved out of it in the registry.`
|
|
160
|
+
: `cwd "${conflict.cwd.asSpelled}" is inside this session's scratchpad "${conflict.scratchpadDir.asSpelled}" — the scratchpad is the fs-write gate's EXEMPT directory, so a task rooted there would auto-approve every write under its own root and the engine refuses to build the gate at all (config.write_exempt_dir_covers_root). Point cwd at the project directory instead (or send no cwd and let the session keep the one it has): this session registers the cwd you send, so a task that happens not to mount the write gate would still leave every LATER task on this session rooted in the exemption. A workflow that really is meant to write without prompts says so with a knob that means it (a permission mode, an open write face) and still keeps its root outside the scratchpad — those knobs do not lift this refusal, because the conflict is between two fields of this request, not a permission level.`, { code: "request.field_conflict", extra: { ...fieldConflictFacts("scratchpad_root", fields), cwd: conflict.cwd, scratchpadDir: conflict.scratchpadDir } });
|
|
123
161
|
}
|
|
124
162
|
}
|
|
125
163
|
const offFieldIssue = singleMemberOffFieldIssue(body);
|
|
@@ -191,12 +229,12 @@ export function createResolveSpec(ctx) {
|
|
|
191
229
|
const gated = await gateScenarioAndAppend(body, auth, root, opts, settingsEnv);
|
|
192
230
|
const effMode = effectivePermissionMode(body, gated.parsedSettings.settings);
|
|
193
231
|
assertWriteFaceAdmitted(effMode, config);
|
|
194
|
-
const lane = bindSettingsCwdEnvAndModel(body, auth, root, gated, opts);
|
|
195
|
-
const anchors = await resolveHistoryAnchors(body, req, auth, root);
|
|
232
|
+
const lane = bindSettingsCwdEnvAndModel(body, auth, root, gated, opts, legCwd);
|
|
233
|
+
const anchors = await resolveHistoryAnchors(body, req, auth, root, submittedProjectId, legProjectId);
|
|
196
234
|
const projectKey = memoryEngine ? await memoryProjectLayers.prepare(config, auth?.memoryScope, realTaskRootOf(root)) : undefined;
|
|
197
235
|
const runSkills = buildRunSkills({ scenario: gated.cap.skills, request: body.skills, disable: body.disableSkills === true, deploymentSources: deploymentSkillSources }, logger);
|
|
198
|
-
const spec = assembleSpecLiteral(body, auth, root, req, opts, { ...gated, ...lane, ...anchors, projectKey, a2aPeers, storedToolAxes, runSkills }, effMode);
|
|
199
|
-
const folded = await foldGovernanceAndSettings(body, auth, root, spec, gated);
|
|
236
|
+
const spec = assembleSpecLiteral(body, auth, root, req, opts, { ...gated, ...lane, ...anchors, projectKey, a2aPeers, storedToolAxes, runSkills, projectBrief: projectContext?.brief }, effMode);
|
|
237
|
+
const folded = await foldGovernanceAndSettings(body, auth, root, spec, gated, projectContext?.brief);
|
|
200
238
|
const retiredNotice = opts.onNotice !== undefined ? buildNeverAutoRetiredNotice(gated.parsedSettings.settings?.tightenOnly?.neverAuto, root) : undefined;
|
|
201
239
|
if (retiredNotice !== undefined)
|
|
202
240
|
opts.onNotice?.(retiredNotice);
|
|
@@ -206,7 +244,7 @@ export function createResolveSpec(ctx) {
|
|
|
206
244
|
hostSemanticsLane: folded.hostSemanticsLane,
|
|
207
245
|
});
|
|
208
246
|
const registeredCwd = perSessionCwd.get(root);
|
|
209
|
-
return { spec: final, facts: { hands: gated.hands, skills: runSkills.roster, sessionWitness: gated.sessionWitness, ...(registeredCwd !== undefined ? { registeredCwd } : {}) } };
|
|
247
|
+
return { spec: final, facts: { hands: gated.hands, skills: runSkills.roster, sessionWitness: gated.sessionWitness, ...(registeredCwd !== undefined ? { registeredCwd } : {}), ...(projectContext !== undefined ? { projectContext } : {}) } };
|
|
210
248
|
};
|
|
211
249
|
const gateScenarioAndAppend = async (body, auth, root, opts, settingsEnv) => {
|
|
212
250
|
const { parts: subjectParts, person } = identityAxesOf(auth);
|
|
@@ -264,15 +302,15 @@ export function createResolveSpec(ctx) {
|
|
|
264
302
|
}
|
|
265
303
|
return { scenarioName, cap, hands: cap.hands, acceptedAppend, objective, parsedSettings, attachmentNotice, sessionWitness };
|
|
266
304
|
};
|
|
267
|
-
const bindSettingsCwdEnvAndModel = (body, auth, root, gated, opts) => {
|
|
305
|
+
const bindSettingsCwdEnvAndModel = (body, auth, root, gated, opts, cwd) => {
|
|
268
306
|
const { objective, parsedSettings } = gated;
|
|
269
307
|
const cwdWriteGate = DEPLOYMENT_SHAPE_PREDICATES.callerCwd.holds(config);
|
|
270
308
|
const execLane = config.remoteExec.provider;
|
|
271
309
|
fenceSessionOwner(root, auth?.subject ?? null, opts.execution.occupant?.incarnation);
|
|
272
|
-
if (typeof
|
|
273
|
-
if (cwdWriteGate && isAbsoluteHostPath(
|
|
274
|
-
setSessionCwd(root,
|
|
275
|
-
else if (DEPLOYMENT_SHAPE_PREDICATES.noHandsSingleUser.holds(config) && isAbsoluteHostPath(
|
|
310
|
+
if (typeof cwd === "string" && cwd.length > 0) {
|
|
311
|
+
if (cwdWriteGate && isAbsoluteHostPath(cwd))
|
|
312
|
+
setSessionCwd(root, cwd);
|
|
313
|
+
else if (DEPLOYMENT_SHAPE_PREDICATES.noHandsSingleUser.holds(config) && isAbsoluteHostPath(cwd) && satisfiedByProcessCwd(cwd, realpathSync))
|
|
276
314
|
logger.debug("task_cwd_inherited", { lane: execLane, sessionId: root });
|
|
277
315
|
else
|
|
278
316
|
logger.warn("task_cwd_ignored", { honored: cwdWriteGate, lane: execLane, sessionId: root });
|
|
@@ -354,7 +392,7 @@ export function createResolveSpec(ctx) {
|
|
|
354
392
|
}
|
|
355
393
|
return { taskHooks, additionalDirectories, additionalReadDirectories, wireCatalog, picked };
|
|
356
394
|
};
|
|
357
|
-
const resolveHistoryAnchors = async (body, req, auth, root) => {
|
|
395
|
+
const resolveHistoryAnchors = async (body, req, auth, root, submittedProjectId, legProjectId) => {
|
|
358
396
|
const anchorReader = req === undefined ? undefined : anchorReaderOf(req, { config, logger }, claimCallerOf(identityAxesOf(auth).subject, config));
|
|
359
397
|
let resumeAtEntryId;
|
|
360
398
|
if (typeof body.resumeAt === "string" && body.resumeAt.length > 0) {
|
|
@@ -368,9 +406,7 @@ export function createResolveSpec(ctx) {
|
|
|
368
406
|
throw new HttpError(501, "rewind-files-to is not available on this worker (no session-store backend for the anchor map)");
|
|
369
407
|
rewindFilesToEntryId = await resolveHistoryAnchor("rewindFilesTo", anchorsResolvable, anchorReader, root, body.rewindFilesTo, auth?.subject ?? null, "rewindFilesTo");
|
|
370
408
|
}
|
|
371
|
-
const submittedProjectId = auth?.resolvedProjectId ?? (typeof body.projectId === "string" && body.projectId ? body.projectId.toLowerCase() : undefined);
|
|
372
409
|
const s4DefaultScopes = submittedProjectId ? config.projects[submittedProjectId]?.defaultScopes : undefined;
|
|
373
|
-
const legProjectId = await legProjectIdOf(submittedProjectId, sessionWorkspace, root);
|
|
374
410
|
return { resumeAtEntryId, rewindFilesToEntryId, s4DefaultScopes, legProjectId };
|
|
375
411
|
};
|
|
376
412
|
const declaresInteractivePosture = (body, req, opts) => {
|
|
@@ -378,7 +414,7 @@ export function createResolveSpec(ctx) {
|
|
|
378
414
|
return false;
|
|
379
415
|
if (body.verify === true || body.cascade === true)
|
|
380
416
|
return false;
|
|
381
|
-
if (
|
|
417
|
+
if (!questionSeat)
|
|
382
418
|
return false;
|
|
383
419
|
if (body.interactiveTools === false)
|
|
384
420
|
return false;
|
|
@@ -389,11 +425,11 @@ export function createResolveSpec(ctx) {
|
|
|
389
425
|
};
|
|
390
426
|
const assembleSpecLiteral = (body, auth, root, req, opts, parts, effMode) => {
|
|
391
427
|
const { parts: subjectParts, person } = identityAxesOf(auth);
|
|
392
|
-
const { scenarioName, cap, hands, acceptedAppend, parsedSettings, attachmentNotice, taskHooks, additionalDirectories, additionalReadDirectories, wireCatalog, picked, resumeAtEntryId, rewindFilesToEntryId, s4DefaultScopes, legProjectId, projectKey, a2aPeers, storedToolAxes, runSkills, } = parts;
|
|
428
|
+
const { scenarioName, cap, hands, acceptedAppend, parsedSettings, attachmentNotice, taskHooks, additionalDirectories, additionalReadDirectories, wireCatalog, picked, resumeAtEntryId, rewindFilesToEntryId, s4DefaultScopes, legProjectId, projectKey, a2aPeers, storedToolAxes, runSkills, projectBrief, } = parts;
|
|
393
429
|
const spec = {
|
|
394
430
|
objective: attachmentNotice ? `${picked.cleanedObjective}\n\n${attachmentNotice}` : picked.cleanedObjective,
|
|
395
431
|
...buildPromptSeats(scenarioName, cap.prompt, typeof body.systemPrompt === "string" ? body.systemPrompt : undefined),
|
|
396
|
-
appendSystemPrompt: acceptedAppend,
|
|
432
|
+
appendSystemPrompt: appendFold([acceptedAppend, projectBrief]).text,
|
|
397
433
|
...(body.outputStyle !== undefined ? { outputStyle: body.outputStyle } : {}),
|
|
398
434
|
...(body.projectMemory !== undefined ? { projectMemory: body.projectMemory } : {}),
|
|
399
435
|
...(legProjectId !== undefined ? { projectId: legProjectId } : {}),
|
|
@@ -522,7 +558,6 @@ export function createResolveSpec(ctx) {
|
|
|
522
558
|
toolPolicy: toolPolicyForHands(hands, durableEnabled
|
|
523
559
|
? createApprovalBaselinePolicy(config, {
|
|
524
560
|
kind: "durable",
|
|
525
|
-
question: liveQuestionFace,
|
|
526
561
|
...(approvalExemptionStore !== undefined ? { exemption: createSessionExemptionRead(approvalExemptionStore, root, logger, "deployment_list") } : {}),
|
|
527
562
|
})
|
|
528
563
|
: singleUserAutoAcceptBaselineApplies(config)
|
|
@@ -543,13 +578,13 @@ export function createResolveSpec(ctx) {
|
|
|
543
578
|
totalBudgetUsd: config.resourceSuspendTotalBudgetUsd,
|
|
544
579
|
maxSlices: config.resourceSuspendMaxSlices,
|
|
545
580
|
})),
|
|
546
|
-
...(
|
|
581
|
+
...(questionSeat ? {} : { onQuestion: QUESTION_AWAITS_RESUME }),
|
|
547
582
|
}
|
|
548
583
|
: {}),
|
|
549
584
|
};
|
|
550
585
|
return spec;
|
|
551
586
|
};
|
|
552
|
-
const foldGovernanceAndSettings = async (body, auth, root, spec, gated) => {
|
|
587
|
+
const foldGovernanceAndSettings = async (body, auth, root, spec, gated, projectBrief) => {
|
|
553
588
|
const { acceptedAppend, parsedSettings } = gated;
|
|
554
589
|
const hostSemanticsLane = !DEPLOYMENT_SHAPE_PREDICATES.sandboxPathAdjudication.holds(config);
|
|
555
590
|
const laneHomeBase = () => {
|
|
@@ -578,8 +613,9 @@ export function createResolveSpec(ctx) {
|
|
|
578
613
|
const governedBase = applyRuntimeGovernance(spec, createDeploymentGovernanceInputs(config, pathAdjudication));
|
|
579
614
|
let governed = governedBase;
|
|
580
615
|
let effectiveSettings = parsedSettings.settings;
|
|
581
|
-
|
|
582
|
-
|
|
616
|
+
const foldedChars = effectiveSettings?.outputStyle ? appendFold([acceptedAppend, projectBrief, effectiveSettings.outputStyle]).chars : 0;
|
|
617
|
+
if (effectiveSettings?.outputStyle && foldedChars > MAX_SETTINGS_OUTPUT_STYLE_CHARS) {
|
|
618
|
+
logger.warn("output_style_dropped", { detail: `combined append carriers exceed the ${MAX_SETTINGS_OUTPUT_STYLE_CHARS} cap (rider ${acceptedAppend?.length ?? 0} + project brief ${projectBrief?.length ?? 0} + style ${effectiveSettings.outputStyle.length}, ${foldedChars} with joiners) — style dropped (pre-cap stored body on a resume leg?)`, sessionId: root });
|
|
583
619
|
const { outputStyle: _dropped2, ...rest2 } = effectiveSettings;
|
|
584
620
|
effectiveSettings = Object.keys(rest2).length > 0 ? rest2 : undefined;
|
|
585
621
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* [ref] 车2 —— 托管留存的 **sweep lane**(设计稿 `docs/
|
|
2
|
+
* [ref] 车2 —— 托管留存的 **sweep lane**(设计稿 `docs/[ref]-retention-lane.md` v1.3 §3/§4/§7)。
|
|
3
3
|
*
|
|
4
4
|
* ── 为什么是独立文件、独立定时器,而不是折进 `startReapers()`(设计稿 §3 首条)───────────────────
|
|
5
5
|
* `boot/reapers.ts` 里那二十条腿全都是**容忍多副本**的幂等清理:每台副本各扫各的,重复扫一遍只是浪费。
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { buildRewindHandles, buildSessionAudit, buildSessionAuditLocal, buildSessionAuditPg } from "../audit.js";
|
|
2
|
-
import { readSessionAgent } from "../
|
|
2
|
+
import { readSessionAgent } from "../http/owner-access.js";
|
|
3
3
|
import { readSessionProjectId, sessionWorkspaceStoreOf } from "../session-workspace.js";
|
|
4
4
|
import { makeDegenerateInstrument } from "../degenerate-instrument.js";
|
|
5
5
|
import { PlanCacheProbe } from "../plan-cache-probe.js";
|
|
@@ -24,27 +24,27 @@ export function createSessionFaces(ctx) {
|
|
|
24
24
|
const ownerAware = sessionStore;
|
|
25
25
|
const headOf = headReadOf(sessionStore);
|
|
26
26
|
const workspaceStore = sessionWorkspaceStoreOf(sessionStore);
|
|
27
|
-
const
|
|
28
|
-
?
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
27
|
+
const readSessionView = async (sessionId, opts) => {
|
|
28
|
+
const handles = opts !== undefined && resumeAnchorStore !== undefined ? buildRewindHandles(await resumeAnchorStore.listBySession(sessionId), opts.reader) : undefined;
|
|
29
|
+
const audit = mysqlPool
|
|
30
|
+
? await buildSessionAudit(mysqlPool, sessionId, handles)
|
|
31
|
+
: auditPgPool
|
|
32
|
+
? await buildSessionAuditPg(auditPgPool, sessionId, handles)
|
|
33
|
+
: await buildSessionAuditLocal(auditLocalRows, sessionId, handles);
|
|
34
|
+
if (!audit)
|
|
35
|
+
return undefined;
|
|
36
|
+
const [head, agent, projectId] = await Promise.all([
|
|
37
|
+
headOf?.(sessionId),
|
|
38
|
+
opts !== undefined ? readSessionAgent(ownerAware, sessionId) : undefined,
|
|
39
|
+
opts !== undefined ? readSessionProjectId(workspaceStore, sessionId) : undefined,
|
|
40
|
+
]);
|
|
41
|
+
const owner = head?.owner;
|
|
42
|
+
return { ...audit, owner: owner ?? null, ...(agent !== undefined ? { agent } : {}), ...(projectId !== undefined ? { projectId } : {}) };
|
|
43
|
+
};
|
|
44
|
+
const sessionAudit = mysqlPool || auditPgPool || auditLocalRows ? readSessionView : undefined;
|
|
45
|
+
const probeWatchedHead = async (sid) => (headOf === undefined ? { owner: undefined, leafId: null } : ((await headOf(sid)) ?? { owner: undefined, leafId: null }));
|
|
46
46
|
const sessionWatchRegistry = headOf
|
|
47
|
-
? new SessionWatchRegistry(
|
|
47
|
+
? new SessionWatchRegistry(probeWatchedHead, {
|
|
48
48
|
hotMs: posIntEnv(process.env.SESSION_EVENTS_HOT_MS, 200),
|
|
49
49
|
warmMs: posIntEnv(process.env.SESSION_EVENTS_WARM_MS, 2000),
|
|
50
50
|
maxWatchedSessions: posIntEnv(process.env.SESSION_EVENTS_MAX_PROBES, 512, 100_000),
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { processInstanceId } from "../process-instance.js";
|
|
2
2
|
import { openStores } from "./stores.js";
|
|
3
3
|
export async function runStage03(ctx) {
|
|
4
4
|
const { config, localAdmission, localRoot, logger, metrics, storeEvidence } = ctx;
|
|
5
5
|
const { backend, storePosture, memoryEngine, engineDataRoot, memorySyncCursors, rosterStore, backgroundAgentStore, sessionCaptureRecords, taskAttachmentStore, mailboxStore, mailboxRecipientLifecycle, memoryExportStores, memorySyncRunner, sessionStore, breakerState, usageWindowStore, memoryPosture, taskListLane, sqlEngine, storeSweep, } = await openStores({ config, logger, metrics, localRoot, storeEvidence, localAdmission });
|
|
6
6
|
const adoptionWiring = { memoryEngine: memoryExportStores !== undefined, taskAttachment: taskAttachmentStore !== undefined };
|
|
7
|
-
const instanceId =
|
|
7
|
+
const instanceId = processInstanceId();
|
|
8
8
|
return { ...ctx, adoptionWiring, backend, backgroundAgentStore, breakerState, engineDataRoot, instanceId, mailboxRecipientLifecycle, mailboxStore, memoryEngine, memoryExportStores, memoryPosture, memorySyncCursors, memorySyncRunner, rosterStore, sessionCaptureRecords, sessionStore, sqlEngine, storePosture, storeSweep, taskAttachmentStore, taskListLane, usageWindowStore };
|
|
9
9
|
}
|
|
10
10
|
//# sourceMappingURL=stage-03-store-backend.js.map
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { createSessionEraseSettler } from "../session-erase.js";
|
|
2
2
|
import { Runner, InMemoryToolResultStore, TtlSessionStore, uuidv7, createAllowDenyPolicy, workflowsCapability } from "@sema-agent/core";
|
|
3
3
|
import { createEngineSessionRulesSeat } from "../session-rules-seat.js";
|
|
4
|
-
import { headReadOf } from "../session-incarnation.js";
|
|
5
4
|
import { outwardPlane } from "../terminal.js";
|
|
6
5
|
import { createSessionTitler } from "../session-titler.js";
|
|
7
6
|
import { cardRuleScopeRoot } from "../task-cwd.js";
|
|
@@ -133,7 +132,7 @@ export async function runStage06(ctx) {
|
|
|
133
132
|
}
|
|
134
133
|
const mcpRevocations = webAdmin.takeMcpRevocations();
|
|
135
134
|
const workflowModelAllowlistSnapshot = workflowModelAllowlistFor(config) ?? [];
|
|
136
|
-
const engineSessionRules = sessionPolicyStore ? createEngineSessionRulesSeat(sessionPolicyStore,
|
|
135
|
+
const engineSessionRules = sessionPolicyStore ? createEngineSessionRulesSeat(sessionPolicyStore, sessionStore) : undefined;
|
|
137
136
|
const runnerDeps = createRunnerDeps({
|
|
138
137
|
consolidationSeat,
|
|
139
138
|
commitCoAuthor,
|
|
@@ -193,7 +193,7 @@ export async function runStage07(ctx) {
|
|
|
193
193
|
const parkedReviveSurface = checkpointStore && backgroundAgentStore && builtinDefaultScenario ? createParkedReviveSurface(builtinDefaultScenario, { onBackgroundChildEvent: runnerDeps.onBackgroundChildEvent }) : undefined;
|
|
194
194
|
const parkedReviveInheritedGate = parkedReviveSurface && config.durableApproval
|
|
195
195
|
? createParkedReviveInheritedGate({
|
|
196
|
-
config, question, logger, localRoot,
|
|
196
|
+
config, questionSeat: question !== undefined, logger, localRoot,
|
|
197
197
|
approverSeat: createRunnerDepsOnAsk(toolApproval),
|
|
198
198
|
approvalExemptionStore,
|
|
199
199
|
...(runnerDeps.runtimeCapsResolver ? { resolveRuntimeCaps: runnerDeps.runtimeCapsResolver } : {}),
|
|
@@ -1,4 +1,36 @@
|
|
|
1
|
+
import { brainSummary } from "../brain.js";
|
|
2
|
+
import { type ServiceConfig } from "../config.js";
|
|
1
3
|
import type { runStage09 } from "./stage-09-leader.js";
|
|
4
|
+
/**
|
|
5
|
+
* 启动协议行 `listening` 的字段(行本身是 `observability/logger.ts` 的 {@link import("../observability/logger.js").STARTUP_PROTOCOL_EVENTS} 一员:不随 `LOG_LEVEL`)。
|
|
6
|
+
* 铸点 = 本文件 listen 之后那一行(全仓唯一,`test/source-hygiene-gate.test.ts` M7),字面量过 {@link exactListeningLine}(键集恰等于本型,可选键与条件展开同算);
|
|
7
|
+
* 键集登记在自铸登记表 `listeningLineKey`(`satisfies Record<keyof ListeningLine, …>`:键加一个而登记表没跟 / 多一个 ⇒ tsc 红)。只登顶层键;`brain` 段里的键随 `brainSummary` 走,不在本型。
|
|
8
|
+
*
|
|
9
|
+
* 绑址两格,一格一个事实:`bindHost` = 本进程**请求**绑的地址(`resolveBindHost` 的答案 —— `BIND_HOST` 经无鉴权自收窄之后的那一只;答案缺席 = 全接口时是说明串);`boundAddress` = 内核**实际**绑上的地址
|
|
10
|
+
* (`server.address().address` 原样:`::` / `0.0.0.0` / `127.0.0.1` / `::1` …;配置写 `localhost` 时它是解析出的那一只)。口同理:`port` 读的也是绑定者自己的答案。
|
|
11
|
+
*/
|
|
12
|
+
export interface ListeningLine {
|
|
13
|
+
readonly port: number;
|
|
14
|
+
readonly bindHost: string;
|
|
15
|
+
readonly bindHostNote?: string;
|
|
16
|
+
readonly boundAddress: string;
|
|
17
|
+
readonly model: ServiceConfig["model"]["id"];
|
|
18
|
+
readonly brain: ReturnType<typeof brainSummary>;
|
|
19
|
+
readonly breakerState: string;
|
|
20
|
+
readonly session: string;
|
|
21
|
+
readonly memory: string;
|
|
22
|
+
readonly instanceId: string;
|
|
23
|
+
readonly rateLimitPerMin: number;
|
|
24
|
+
readonly rateLimit: string;
|
|
25
|
+
readonly maxPrincipalCostUsd: number | null;
|
|
26
|
+
readonly costQuota: string;
|
|
27
|
+
readonly toolResultStore: string;
|
|
28
|
+
readonly otel: string | null;
|
|
29
|
+
readonly perModelKeys: number;
|
|
30
|
+
readonly sealedModelKeys: number;
|
|
31
|
+
readonly sealedPoisonedModels: number;
|
|
32
|
+
readonly workflowRunStore: string;
|
|
33
|
+
}
|
|
2
34
|
export declare function runStage10(ctx: Awaited<ReturnType<typeof runStage09>>): Promise<{
|
|
3
35
|
drainState: import("../fleet/drain-entry.js").DrainState;
|
|
4
36
|
hookWakeBus: {
|
|
@@ -186,7 +218,7 @@ export declare function runStage10(ctx: Awaited<ReturnType<typeof runStage09>>):
|
|
|
186
218
|
taskAttachmentStore: import("../plugins/task-attachment-store.js").TaskAttachmentStore | undefined;
|
|
187
219
|
taskListLane: import("./task-list-lane.js").TaskListLane;
|
|
188
220
|
usageWindowStore: import("@sema-agent/core").UsageWindowStore | undefined;
|
|
189
|
-
config:
|
|
221
|
+
config: ServiceConfig;
|
|
190
222
|
ceilingVerdict: import("./unpriced-ceiling-verdict.js").UnpricedCeilingVerdict;
|
|
191
223
|
storeEvidence: import("../store-posture.js").StoreEvidence;
|
|
192
224
|
webAdmin: import("./web-admin.js").WebAdminRuntime;
|
|
@@ -31,6 +31,9 @@ import { bindServerLateSeats } from "./late-binds.js";
|
|
|
31
31
|
import { serviceVersion } from "../service-version.js";
|
|
32
32
|
import { buildDisplaySafeUrl } from "../trace/redact.js";
|
|
33
33
|
import { seatText } from "../trace/exit-seat.js";
|
|
34
|
+
function exactListeningLine(line) {
|
|
35
|
+
return line;
|
|
36
|
+
}
|
|
34
37
|
export async function runStage10(ctx) {
|
|
35
38
|
const { peerDesk, approvalAskAudit, approvalExemptionStore, approvalNonceStore, authorize, backend, backgroundAgentStore, brain, breakerState, centerRuntimeCapsResolver, checkpointStore, checkpointCtxSealing, parkCommits, config, webAdmin, consolidationValve, costQuota, belowTaskChainPatterns, deploymentMods, deploymentModsLoaded, deviceLane, drainState, dropSessionScopedOf, durableEnabled, elicitation, fenceSessionOwner, fileHistoryStore, fleetBus, fleetLease, fleetUsage, governanceSeams, handslessRunner, hookAgent, hookLlm, hookWakeBus, imageBakes, imageIndex, instanceId, instrumentDegenerate, leaderEndpoint, loadedSkills, localRoot, logger, lspManager, mcpRevocations, sandboxCapacity, memoryBundleFaces, memoryComplianceFaces, memoryConsolidationFaces, memoryEngine, memoryExportStores, memoryOptOutGrantStore, memoryOriginFaces, memoryPosture, memorySyncCursors, memorySyncRunner, metrics, modelUsageTracker, orgMemoryAdmission, otelExporter, outcomeSink, ownerAware, parkedReviveInheritedGate, parkedReviveSurface, perSessionCwd, perTaskImage, planCacheProbe, pricing, principalCaps, promptManifestTracker, purgeSession, question, rateLimiter, reaper, webAdminJwtVerifier, resumeAnchorStore, retentionLaneStarted, retentionLaneStore, ruleConsent, runStore, runner, runnerDeps, runtimeCapsPeekReading, sandboxGitPlane, scenarioDetails, scenarios, selectEnvTool, sendFileLedger, sendUserFileEmitter, sendUserFileToolSpec, sessionAudit, sessionEnvSelection, sessionMemoryStatusFace, sessionPolicyStore, sessionTitler, sessionWatchRegistry, setSessionCwd, setSessionInheritEnv, setSessionShellEnv, sessionResidentBackground, sharedMemoryStore, sideQueryAccounting, sqlEngine, sqlWorkflowRunStore, staticWiring, storePosture, subRunner, subagentSteerRegistry, taskAttachmentStore, taskLimitCaps, taskTimeoutSec, toolApproval, toolResultStore, usageWindowStore, userInputLedger, webSearchProvider, workflowAgentRegistry, workflowAgentSessionIndex, workflowParkDecisions, workflowCompletionInbox, workflowJournalStore, workflowModelAllowlistSnapshot, workflowNotifyGate, workflowNotifyJournal, workflowRecoverOpts, workflowRunStore, workflowsCapable, orgDeliveryGate } = ctx;
|
|
36
39
|
const stores = {
|
|
@@ -218,7 +221,7 @@ export async function runStage10(ctx) {
|
|
|
218
221
|
checkpointStore, imageIndex, perTaskImage,
|
|
219
222
|
sessionEnvSelection,
|
|
220
223
|
lockedKeys: governanceSeams.lockedKeys,
|
|
221
|
-
|
|
224
|
+
questionSeat: question !== undefined,
|
|
222
225
|
approverSeat: createRunnerDepsOnAsk(toolApproval),
|
|
223
226
|
});
|
|
224
227
|
const runnerFor = createHandsRunnerSelector({ full: runner, handsless: handslessRunner });
|
|
@@ -284,11 +287,12 @@ export async function runStage10(ctx) {
|
|
|
284
287
|
version: serviceVersion(),
|
|
285
288
|
signal: () => mintEngineSignal({ ...deployment, config }),
|
|
286
289
|
modelRefusals: () => deployment.modelRefusalsState?.(),
|
|
287
|
-
...(servingLease ? {
|
|
290
|
+
...(servingLease ? { onHeartbeat: (hearing) => servingLease.noteHeartbeat(hearing) } : {}),
|
|
288
291
|
...(fleetUsage ? { usage: fleetUsage } : {}),
|
|
289
292
|
logger: { info: (m, d) => logger.info(m, d ?? {}), warn: (m, d) => logger.warn(m, d ?? {}) },
|
|
290
293
|
});
|
|
291
294
|
webAdmin.onSelfReportChange(() => void fleetClient?.announceNow());
|
|
295
|
+
servingLease?.onViewChange(() => void fleetClient?.announceNow());
|
|
292
296
|
if (fleetClient) {
|
|
293
297
|
const advertised = config.fleetAdvertiseAddress;
|
|
294
298
|
logger.info("fleet_client_started", { worker: config.webAdmin?.worker, usageReport: fleetUsage !== undefined, announce: advertised !== undefined, ...(advertised !== undefined ? { address: buildDisplaySafeUrl(advertised) } : {}) });
|
|
@@ -299,12 +303,13 @@ export async function runStage10(ctx) {
|
|
|
299
303
|
const bound = server.address();
|
|
300
304
|
if (bound === null || typeof bound === "string")
|
|
301
305
|
throw new Error(`http server listening without a TCP address (server.address() = ${JSON.stringify(bound)})`);
|
|
302
|
-
logger.info("listening", {
|
|
306
|
+
logger.info("listening", exactListeningLine({
|
|
303
307
|
port: bound.port,
|
|
304
308
|
bindHost: bindHost ?? "0.0.0.0/::(all interfaces)",
|
|
305
309
|
...(bindHost === "127.0.0.1" && !config.bindHost
|
|
306
310
|
? { bindHostNote: "auto-narrowed to loopback: write face is unauthenticated (ALLOW_UNAUTHED_WRITES with no service token). Set BIND_HOST explicitly to override." }
|
|
307
311
|
: {}),
|
|
312
|
+
boundAddress: bound.address,
|
|
308
313
|
model: config.model.id,
|
|
309
314
|
brain: brainSummary(config),
|
|
310
315
|
breakerState: config.resilience.circuitBreaker ? (breakerState ? `shared(${backend.kind})` : "in-process") : "off",
|
|
@@ -327,7 +332,7 @@ export async function runStage10(ctx) {
|
|
|
327
332
|
? `db(${backend.kind})`
|
|
328
333
|
: "file"
|
|
329
334
|
: "off",
|
|
330
|
-
});
|
|
335
|
+
}));
|
|
331
336
|
if (workflowNotifyGate) {
|
|
332
337
|
void workflowNotifyGate
|
|
333
338
|
.recover(workflowRecoverOpts)
|
package/dist/boot/web-admin.d.ts
CHANGED
|
@@ -144,7 +144,7 @@ export interface WebAdminRuntime {
|
|
|
144
144
|
/** [ref] ②:caps `centerWiring.effectivePull` / `effectiveRevision` 的取值口 —— `lastPull`(新状态,只此一枚:boot 实拉 / 迟到 boot 到货 /
|
|
145
145
|
* refresh 拍收尾写)+ 与 `configApplyState()` **同一只** ledger 视图的已应用修订号。形与词表见 `web-admin-client/pull-state.ts`。 */
|
|
146
146
|
centerPullState(): CenterPullView;
|
|
147
|
-
/**
|
|
147
|
+
/** [ref] §5 S2([ref]):center **当前在管**的 ServiceConfig 键集 —— `GET /v1/config/catalog` 判
|
|
148
148
|
* `effectiveLane` 的 center 半场。投影自最近一次成功应用的候选(`latestEffective`,LKG/refresh 同一
|
|
149
149
|
* 份推进点;判据单源 = apply-effective.ts `centerManagedConfigKeys`)。`undefined` = 没有配置管道。
|
|
150
150
|
* ⚠️ 部分应用窗(codex R2-F2 登记):某组整拒时 live config 已吃进其它组而 latestEffective 不推进,
|