@sema-agent/server 7.99.0 → 7.101.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 +35 -1
- package/README.md +12 -1
- package/README.zh-CN.md +9 -1
- package/USAGE.md +150 -56
- package/dist/approval-ask-machine.d.ts +10 -0
- package/dist/approval-ask-machine.js +3 -0
- package/dist/approval-card.d.ts +86 -1
- package/dist/approval-card.js +42 -8
- package/dist/approval-policy-settlement.d.ts +31 -0
- package/dist/approval-policy-settlement.js +16 -0
- package/dist/approval-reconciler.d.ts +8 -1
- package/dist/approval-reconciler.js +5 -4
- package/dist/approval.d.ts +44 -20
- package/dist/approval.js +14 -6
- package/dist/boot/config-center.d.ts +16 -8
- package/dist/boot/config-center.js +114 -90
- package/dist/boot/execution-env.d.ts +1 -2
- package/dist/boot/execution-env.js +21 -3
- package/dist/boot/leader.js +12 -9
- package/dist/boot/memory-consolidation.d.ts +38 -0
- package/dist/boot/memory-consolidation.js +35 -0
- package/dist/boot/parked-revive-gate.js +1 -0
- package/dist/boot/reapers.js +1 -0
- package/dist/boot/resolve-spec.d.ts +0 -1
- package/dist/boot/resolve-spec.js +28 -10
- package/dist/boot/runner-deps.d.ts +2 -2
- package/dist/boot/runner-deps.js +9 -3
- package/dist/boot/stage-02-registry-pull.js +9 -0
- package/dist/boot/stage-05-execution-env.d.ts +1 -1
- package/dist/boot/stage-06-runners.d.ts +2 -2
- package/dist/boot/stage-06-runners.js +3 -3
- package/dist/boot/stage-07-capability-layer.d.ts +2 -3
- package/dist/boot/stage-07-capability-layer.js +6 -6
- package/dist/boot/stage-08-reapers.d.ts +3 -4
- package/dist/boot/stage-08-reapers.js +2 -2
- package/dist/boot/stage-09-leader.d.ts +2 -3
- package/dist/boot/stage-10-http-server.d.ts +2 -3
- package/dist/boot/stage-10-http-server.js +2 -2
- package/dist/boot/stores.js +4 -0
- package/dist/capabilities/center-plugins.d.ts +14 -2
- package/dist/capabilities/center-plugins.js +13 -5
- package/dist/capabilities/hands-lane.js +2 -1
- package/dist/capabilities/scenarios.js +18 -5
- package/dist/capabilities/tool-defer.d.ts +2 -2
- package/dist/config-catalog.d.ts +2 -2
- package/dist/config-catalog.js +16 -15
- package/dist/config-center/apply-effective.d.ts +59 -39
- package/dist/config-center/apply-effective.js +231 -120
- package/dist/config-center/apply-ledger.d.ts +45 -16
- package/dist/config-center/apply-ledger.js +28 -18
- package/dist/config-center/facade.d.ts +12 -6
- package/dist/config-center/facade.js +2 -2
- package/dist/config-center/hot-keys-registry.d.ts +11 -4
- package/dist/config-center/hot-keys-registry.js +11 -7
- package/dist/config-center/http-client.d.ts +4 -1
- package/dist/config-center/http-client.js +15 -10
- package/dist/config-center/read-warnings.d.ts +115 -6
- package/dist/config-center/read-warnings.js +115 -5
- package/dist/config-center/restart-signal.d.ts +21 -14
- package/dist/config-center/restart-signal.js +16 -22
- package/dist/config-center/types.d.ts +9 -3
- package/dist/config-invariants.d.ts +2 -2
- package/dist/config-invariants.js +15 -0
- package/dist/config-provider.d.ts +4 -0
- package/dist/config-provider.js +64 -9
- package/dist/config-types.d.ts +57 -13
- package/dist/config.js +87 -22
- package/dist/cross-session-settings.js +1 -1
- package/dist/deployment-governance.d.ts +45 -12
- package/dist/deployment-governance.js +37 -9
- package/dist/env-name-allowlist-knobs.d.ts +37 -0
- package/dist/env-name-allowlist-knobs.js +24 -0
- package/dist/fleet-client.d.ts +2 -1
- package/dist/hooks/hook-llm.js +13 -4
- package/dist/host-lsp-manager.d.ts +41 -0
- package/dist/host-lsp-manager.js +15 -0
- package/dist/http/active-run-conflict.d.ts +2 -12
- package/dist/http/active-run-conflict.js +1 -6
- package/dist/http/admission.js +30 -7
- package/dist/http/memory-store-refusal-reply.d.ts +24 -0
- package/dist/http/memory-store-refusal-reply.js +10 -0
- package/dist/http/resume-legs.d.ts +1 -1
- package/dist/http/resume-legs.js +14 -10
- package/dist/http/route-ctx.d.ts +2 -2
- package/dist/http/routes/approvals-assistant.d.ts +1 -1
- package/dist/http/routes/approvals-assistant.js +3 -2
- package/dist/http/routes/capabilities.js +3 -3
- package/dist/http/routes/memory-bundle.js +3 -0
- package/dist/http/routes/memory-compliance.js +3 -0
- package/dist/http/routes/memory-origin.js +3 -0
- package/dist/http/routes/sessions.js +7 -0
- package/dist/http/routes/side-query.js +10 -4
- package/dist/http/routes/tasks.js +7 -6
- package/dist/http/server.d.ts +6 -5
- package/dist/http/wire-types.d.ts +6 -3
- package/dist/instruction-source-notice.d.ts +97 -0
- package/dist/instruction-source-notice.js +78 -0
- package/dist/leader/wire.d.ts +20 -12
- package/dist/leader/wire.js +7 -6
- package/dist/memory-layer-legacy-lock.d.ts +14 -0
- package/dist/memory-layer-legacy-lock.js +74 -0
- package/dist/memory-store-refusal.d.ts +37 -0
- package/dist/memory-store-refusal.js +14 -0
- package/dist/model-entry-refusal.d.ts +130 -0
- package/dist/model-entry-refusal.js +157 -0
- package/dist/model-provider.d.ts +9 -3
- package/dist/model-route-endpoint.d.ts +1 -1
- package/dist/model-select.d.ts +49 -4
- package/dist/model-select.js +48 -17
- package/dist/observability/corrupt-read-seat.d.ts +21 -4
- package/dist/observability/corrupt-read-seat.js +31 -0
- package/dist/observability/fail-open.d.ts +16 -4
- package/dist/observability/fail-open.js +16 -4
- package/dist/observability/metrics.js +1 -0
- package/dist/observability/run-terminal.js +1 -0
- package/dist/observability/secret-env-scrub.d.ts +27 -3
- package/dist/observability/secret-env-scrub.js +22 -6
- package/dist/orchestration/workflow-completion-inbox.d.ts +31 -23
- package/dist/orchestration/workflow-completion-inbox.js +8 -3
- package/dist/plugins/approval-ask-store-file.d.ts +20 -2
- package/dist/plugins/approval-ask-store-file.js +21 -3
- package/dist/plugins/approval-ask-store-memory.d.ts +2 -0
- package/dist/plugins/approval-ask-store-memory.js +39 -13
- package/dist/plugins/approval-ask-store-sql.d.ts +24 -5
- package/dist/plugins/approval-ask-store-sql.js +27 -3
- package/dist/plugins/caching-session-store.d.ts +6 -0
- package/dist/plugins/caching-session-store.js +6 -0
- package/dist/plugins/checkpoint-store-sql.d.ts +9 -3
- package/dist/plugins/checkpoint-store-sql.js +19 -2
- package/dist/plugins/local-checkpoint-store.js +2 -0
- package/dist/plugins/local-session-store.d.ts +20 -25
- package/dist/plugins/local-session-store.js +111 -64
- package/dist/plugins/mailbox-store-sql.d.ts +7 -5
- package/dist/plugins/mailbox-store-sql.js +6 -4
- package/dist/plugins/permission-rule-store-file.js +3 -2
- package/dist/plugins/pg-session-storage.d.ts +7 -0
- package/dist/plugins/pg-session-storage.js +19 -0
- package/dist/plugins/remote-env-host.d.ts +3 -1
- package/dist/plugins/remote-env-host.js +3 -6
- package/dist/plugins/sql-json-column.d.ts +16 -3
- package/dist/plugins/sql-json-column.js +15 -4
- package/dist/plugins/tidb-pool.js +5 -0
- package/dist/plugins/tidb-session-store.d.ts +13 -0
- package/dist/plugins/tidb-session-store.js +14 -0
- package/dist/plugins/web-search.d.ts +44 -23
- package/dist/plugins/web-search.js +161 -50
- package/dist/project-memory.d.ts +10 -0
- package/dist/project-memory.js +28 -14
- package/dist/run-local.d.ts +17 -15
- package/dist/run-local.js +119 -18
- package/dist/runs.js +6 -5
- package/dist/runtime-governance.d.ts +50 -3
- package/dist/runtime-governance.js +5 -0
- package/dist/sealed-key.d.ts +5 -2
- package/dist/server-secret-env.d.ts +26 -2
- package/dist/server-secret-env.js +9 -0
- package/dist/task-settings.d.ts +1 -1
- package/dist/tool-approval.d.ts +150 -28
- package/dist/tool-approval.js +150 -54
- package/dist/trace/core-keyset-guard.d.ts +30 -8
- package/dist/trace/engine-notice-wire.d.ts +27 -1
- package/dist/trace/engine-notice-wire.js +8 -0
- package/dist/trace/ledger-sink.js +2 -2
- package/dist/trace/project.d.ts +13 -0
- package/dist/trace/project.js +22 -5
- package/dist/trace/projection-drop.d.ts +2 -0
- package/dist/trace/projection-drop.js +6 -0
- package/dist/trace/sema-provenance.d.ts +4 -1
- package/dist/trace/sema-provenance.js +1 -1
- package/dist/trace/task-notification-facets.d.ts +65 -0
- package/dist/trace/task-notification-facets.js +31 -0
- package/dist/trace/wire-projection-faces.d.ts +3 -3
- package/dist/trace/wire-projection-faces.js +3 -3
- package/package.json +3 -3
|
@@ -18,10 +18,18 @@ import { createConfigProvider, raceBootFetch, BOOT_FETCH_DEFERRED } from "../con
|
|
|
18
18
|
import { executionLaneCaps, executionLaneOf } from "../execution-lane-caps.js";
|
|
19
19
|
import { createKeyResolver } from "../key-resolver.js";
|
|
20
20
|
import { ensureSealedKeyStore, reportExecutionPublicKey } from "../sealed-key.js";
|
|
21
|
-
import { applyEffective, applyCenterReadFace, mutateInPlace, logEffectiveDiff, applyCenterSkills, resolveMcpServers, resolveA2aPeers, restartReasons, modelPlaneChanged,
|
|
21
|
+
import { applyEffective, applyCenterReadFace, mutateInPlace, logEffectiveDiff, applyCenterSkills, resolveMcpServers, resolveA2aPeers, restartReasons, modelPlaneChanged, withModelPlaneOf, buildEnvOnlyModelPlane, fetchPromptArtifact } from "../config-center/facade.js";
|
|
22
22
|
import { createMcpRevocationLedger, enabledMcpEntries } from "../config-center/mcp-revocation.js";
|
|
23
23
|
import { SHA256_HEX_RE } from "../digest-form.js";
|
|
24
|
-
import { createConfigApplyLedger } from "../config-center/apply-ledger.js";
|
|
24
|
+
import { createConfigApplyLedger, modelPlaneCommitted, refusedGroups } from "../config-center/apply-ledger.js";
|
|
25
|
+
function lkgReadNote(scope) {
|
|
26
|
+
switch (scope) {
|
|
27
|
+
case "whole":
|
|
28
|
+
return "booting from the persisted last-known-good (all restart-to-apply faces included) — the live pull continues in the background and reconciles on arrival";
|
|
29
|
+
case "model-plane":
|
|
30
|
+
return "the live candidate's model plane was refused at boot — the persisted last-known-good supplies the model plane only (catalog and the collab templates that reference it); every other group and every restart-to-apply face stays the live candidate's";
|
|
31
|
+
}
|
|
32
|
+
}
|
|
25
33
|
export async function createConfigCenterRuntime(ctx) {
|
|
26
34
|
const { config, logger, metrics, localRoot } = ctx;
|
|
27
35
|
let ccEtag;
|
|
@@ -114,6 +122,18 @@ export async function createConfigCenterRuntime(ctx) {
|
|
|
114
122
|
: undefined;
|
|
115
123
|
const rosterGateArmed = isRosterGateArmed(cc);
|
|
116
124
|
const modelReadyState = { ready: !rosterGateArmed };
|
|
125
|
+
const warnDroppedEntries = (r, phase) => {
|
|
126
|
+
for (const d of r.droppedEntries ?? []) {
|
|
127
|
+
logger.warn("config_entry_dropped", {
|
|
128
|
+
domain: d.domain,
|
|
129
|
+
entry: d.entry,
|
|
130
|
+
error: d.error,
|
|
131
|
+
version: r.effective.version,
|
|
132
|
+
phase,
|
|
133
|
+
note: "this one entry failed its domain schema and was dropped on its own — the rest of the candidate applies (per-entry tolerance); fix the named entry to bring it back",
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
};
|
|
117
137
|
const markRosterLanded = (eff) => {
|
|
118
138
|
if (!modelReadyState.ready && (eff.models?.models ?? []).some((m) => m.enabled !== false)) {
|
|
119
139
|
modelReadyState.ready = true;
|
|
@@ -312,7 +332,7 @@ export async function createConfigCenterRuntime(ctx) {
|
|
|
312
332
|
};
|
|
313
333
|
if (configProvider) {
|
|
314
334
|
const dryRun = cc?.dryRun ?? false;
|
|
315
|
-
const bootFromLkg = async (why) => {
|
|
335
|
+
const bootFromLkg = async (why, scope) => {
|
|
316
336
|
if (!lkgEnabled || dryRun)
|
|
317
337
|
return null;
|
|
318
338
|
const identity = currentIdentity();
|
|
@@ -344,7 +364,7 @@ export async function createConfigCenterRuntime(ctx) {
|
|
|
344
364
|
logger.warn("config_lkg_unusable", { path: lkgPath, reason: "center credential identity changed while the LKG was being read — not used", note: "env fallback serves; the current identity's next pull re-establishes its own LKG" });
|
|
345
365
|
return null;
|
|
346
366
|
}
|
|
347
|
-
logger.info("config_loaded_lkg", { path: lkgPath, savedAt: read.lkg.savedAt, why, note:
|
|
367
|
+
logger.info("config_loaded_lkg", { path: lkgPath, savedAt: read.lkg.savedAt, why, scope, note: lkgReadNote(scope) });
|
|
348
368
|
const lkgEffective = read.lkg.effective;
|
|
349
369
|
candidateIdentity.set(lkgEffective, identity);
|
|
350
370
|
bindValidator(read.lkg.etag, identity);
|
|
@@ -353,18 +373,31 @@ export async function createConfigCenterRuntime(ctx) {
|
|
|
353
373
|
const bootApplyLkgInline = async (lkgR) => {
|
|
354
374
|
const lkgGen = generationOf(lkgR.effective.version);
|
|
355
375
|
applyLedger.seenTarget(lkgGen, lkgR.effective.version);
|
|
356
|
-
|
|
376
|
+
let lkgReport;
|
|
377
|
+
applyEffective(config, lkgR.effective, logger, {
|
|
378
|
+
leg: "boot",
|
|
379
|
+
sealedKeys,
|
|
380
|
+
generation: lkgGen,
|
|
381
|
+
report: (rep) => {
|
|
382
|
+
lkgReport = rep;
|
|
383
|
+
applyLedger.recordApply(rep);
|
|
384
|
+
},
|
|
385
|
+
});
|
|
357
386
|
applyLedger.applied(lkgGen, lkgR.effective.version);
|
|
358
387
|
await adoptCenterPrompts(lkgR.effective, "boot-lkg");
|
|
359
|
-
|
|
388
|
+
const lkgPlane = modelPlaneCommitted(lkgReport);
|
|
389
|
+
if (lkgPlane)
|
|
390
|
+
markRosterLanded(lkgR.effective);
|
|
360
391
|
effective = lkgR.effective;
|
|
361
|
-
|
|
392
|
+
if (lkgPlane)
|
|
393
|
+
appliedPlaneEff = lkgR.effective;
|
|
362
394
|
latestEffective = lkgR.effective;
|
|
363
395
|
if (lkgR.etag !== undefined)
|
|
364
396
|
ccEtag = lkgR.etag;
|
|
365
397
|
const cfgModels = (lkgR.effective.models?.models ?? []).filter((m) => m.enabled !== false).length;
|
|
366
398
|
logger.info("config_loaded", { source: "lkg", version: lkgR.effective.version, worker: cc?.worker ?? "(global)", models: cfgModels });
|
|
367
399
|
};
|
|
400
|
+
let bootApplyPhase = false;
|
|
368
401
|
try {
|
|
369
402
|
const bootFetch = pullEffective(configProvider, undefined);
|
|
370
403
|
const raced = await raceBootFetch(bootFetch, config.configBootFetchBudgetMs);
|
|
@@ -372,7 +405,7 @@ export async function createConfigCenterRuntime(ctx) {
|
|
|
372
405
|
if (raced === BOOT_FETCH_DEFERRED) {
|
|
373
406
|
bootConfigPending = bootFetch;
|
|
374
407
|
bootFetch.catch(() => { });
|
|
375
|
-
lkgFallback = await bootFromLkg("boot fetch deferred (budget exceeded)");
|
|
408
|
+
lkgFallback = await bootFromLkg("boot fetch deferred (budget exceeded)", "whole");
|
|
376
409
|
lkgBooted = lkgFallback !== null;
|
|
377
410
|
logger.warn("config_boot_fetch_deferred", {
|
|
378
411
|
source: configProvider.kind,
|
|
@@ -394,11 +427,13 @@ export async function createConfigCenterRuntime(ctx) {
|
|
|
394
427
|
}
|
|
395
428
|
const r = raced === BOOT_FETCH_DEFERRED ? null : raced;
|
|
396
429
|
if (r) {
|
|
430
|
+
bootApplyPhase = true;
|
|
397
431
|
const bootPromptsRaw = r.effective.prompts;
|
|
398
432
|
const bootPromptsOk = bootPromptsRaw === undefined || validatePromptsDomain(bootPromptsRaw).ok;
|
|
399
433
|
let bootClean = (r.domainErrors ?? []).length === 0 && bootPromptsOk;
|
|
400
434
|
for (const de of r.domainErrors ?? [])
|
|
401
435
|
logger.warn("config_domain_invalid", { domain: de.domain, error: de.error, note: "tolerated at BOOT (corrupt file → schema defaults; dangling ref → reported as-is); the refresh path rejects such a candidate whole and keeps the LKG (§9.5-5)" });
|
|
436
|
+
warnDroppedEntries(r, "boot");
|
|
402
437
|
if (dryRun) {
|
|
403
438
|
logEffectiveDiff(config, r.effective, logger);
|
|
404
439
|
if (bootClean)
|
|
@@ -409,6 +444,7 @@ export async function createConfigCenterRuntime(ctx) {
|
|
|
409
444
|
applyLedger.seenTarget(bootGen, r.effective.version);
|
|
410
445
|
let bootReport;
|
|
411
446
|
applyEffective(config, r.effective, logger, {
|
|
447
|
+
leg: "boot",
|
|
412
448
|
sealedKeys,
|
|
413
449
|
generation: bootGen,
|
|
414
450
|
report: (rep) => {
|
|
@@ -422,9 +458,23 @@ export async function createConfigCenterRuntime(ctx) {
|
|
|
422
458
|
if (bootClean)
|
|
423
459
|
ccEtag = r.etag;
|
|
424
460
|
await adoptCenterPrompts(r.effective, "boot");
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
461
|
+
let bootPlaneEff = modelPlaneCommitted(bootReport) ? r.effective : undefined;
|
|
462
|
+
if (bootPlaneEff === undefined) {
|
|
463
|
+
const lkgPlane = await bootFromLkg("boot candidate's model plane was refused", "model-plane");
|
|
464
|
+
if (lkgPlane) {
|
|
465
|
+
let planeReport;
|
|
466
|
+
applyEffective(config, withModelPlaneOf(r.effective, lkgPlane.effective), logger, { leg: "boot", sealedKeys, generation: bootGen, report: (rep) => (planeReport = rep) });
|
|
467
|
+
if (modelPlaneCommitted(planeReport)) {
|
|
468
|
+
bootPlaneEff = lkgPlane.effective;
|
|
469
|
+
logger.warn("config_model_plane_from_lkg", { version: r.effective.version, lkgVersion: lkgPlane.effective.version, note: "the live candidate's model plane was refused at boot — serving the LKG's model plane (catalog and the collab templates that reference it) with the live candidate's other groups; the refresh cadence re-judges the candidate" });
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
if (bootPlaneEff !== undefined)
|
|
474
|
+
markRosterLanded(bootPlaneEff);
|
|
475
|
+
effective = bootPlaneEff === r.effective ? r.effective : withModelPlaneOf(r.effective, bootPlaneEff ?? buildEnvOnlyModelPlane());
|
|
476
|
+
if (bootPlaneEff !== undefined)
|
|
477
|
+
appliedPlaneEff = bootPlaneEff;
|
|
428
478
|
if (bootClean)
|
|
429
479
|
latestEffective = r.effective;
|
|
430
480
|
if (bootClean && !lkgBooted)
|
|
@@ -434,23 +484,30 @@ export async function createConfigCenterRuntime(ctx) {
|
|
|
434
484
|
logger.info("config_loaded", { source: configProvider.kind, version: r.effective.version, worker: cc?.worker ?? "(global)", models: cfgModels, ...cfgDir });
|
|
435
485
|
if (configProvider.kind === "local" && cfgModels === 0) {
|
|
436
486
|
const modelsDomainErr = (r.domainErrors ?? []).find((de) => de.domain === "models");
|
|
487
|
+
const modelsDropped = (r.droppedEntries ?? []).filter((d) => d.domain === "models");
|
|
437
488
|
const totalModels = (r.effective.models?.models ?? []).length;
|
|
438
489
|
logger.warn("config_local_no_models", {
|
|
439
490
|
...cfgDir,
|
|
440
491
|
...(modelsDomainErr ? { domainError: modelsDomainErr.error } : {}),
|
|
492
|
+
...(modelsDropped.length > 0 ? { droppedEntries: modelsDropped.map((d) => d.entry) } : {}),
|
|
441
493
|
hint: modelsDomainErr
|
|
442
494
|
? "config.d/models.json 在场但 models 域判形失败落 default(真因见本行 domainError)— 模型继续走 env 兜底"
|
|
443
|
-
:
|
|
444
|
-
?
|
|
445
|
-
:
|
|
495
|
+
: modelsDropped.length > 0 && totalModels === 0
|
|
496
|
+
? "config.d/models.json 的条目全部被逐条丢弃(逐条真因见 config_entry_dropped)— 模型继续走 env 兜底"
|
|
497
|
+
: totalModels > 0
|
|
498
|
+
? `config.d/models.json 有 ${totalModels} 条模型但全部 enabled:false — 模型继续走 env 兜底`
|
|
499
|
+
: "config.d/models.json 空或 CONFIG_LOCAL_DIR 指错目录(选目录旋钮是 CONFIG_LOCAL_DIR,不是 LOCAL_DATA_ROOT)— 模型继续走 env 兜底",
|
|
446
500
|
});
|
|
447
501
|
}
|
|
448
502
|
}
|
|
449
503
|
}
|
|
450
504
|
}
|
|
451
505
|
catch (err) {
|
|
452
|
-
|
|
453
|
-
|
|
506
|
+
if (bootApplyPhase)
|
|
507
|
+
logger.warn("config_apply_refused", { source: configProvider.kind, err: String(err), note: "the pulled candidate failed to apply at boot — falling back to the LKG / env; this is not a reachability failure" });
|
|
508
|
+
else
|
|
509
|
+
logger.warn("config_source_unreachable_using_env", { source: configProvider.kind, err: String(err) });
|
|
510
|
+
const lkgFallback = await bootFromLkg(`${bootApplyPhase ? "boot apply refused" : "boot fetch failed"}: ${String(err).slice(0, 120)}`, "whole");
|
|
454
511
|
if (lkgFallback) {
|
|
455
512
|
lkgBooted = true;
|
|
456
513
|
try {
|
|
@@ -474,8 +531,10 @@ export async function createConfigCenterRuntime(ctx) {
|
|
|
474
531
|
let keyResolver;
|
|
475
532
|
const mcpRevocations = createMcpRevocationLedger((ev) => logger.info("mcp_revocation_ledger", { ...(ev.revoked.length > 0 ? { revoked: ev.revoked } : {}), ...(ev.restored.length > 0 ? { restored: ev.restored } : {}) }));
|
|
476
533
|
let mcpRevocationWired = false;
|
|
477
|
-
const restartCtx = () => ({
|
|
534
|
+
const restartCtx = (consolidationSeat) => ({
|
|
478
535
|
...(config.degrade?.reactive ? { reactiveDegradeTo: config.degrade.to } : {}),
|
|
536
|
+
pluginsAllowHosts: config.pluginsAllowHosts,
|
|
537
|
+
...(consolidationSeat !== undefined ? { consolidationSeat } : {}),
|
|
479
538
|
...(readFaceEnvHeld.length > 0 ? { readFaceEnvHeld } : {}),
|
|
480
539
|
...(mcpRevocationWired && mcpRevocations.hasBaseline() ? { mcpRevocationLive: true } : {}),
|
|
481
540
|
});
|
|
@@ -485,10 +544,6 @@ export async function createConfigCenterRuntime(ctx) {
|
|
|
485
544
|
const { faceChanged } = applyCenterReadFace(config, eff, logger, { phase: "live", baseline: readFaceBaseline });
|
|
486
545
|
if (!faceChanged)
|
|
487
546
|
return;
|
|
488
|
-
if (swap === undefined) {
|
|
489
|
-
logger.warn("read_face_swap_unwired", { face: config.readFace ?? null, phase, note: "the center's read FACE changed but no Runner swap door was wired — the value landed in config while the engine keeps the seat it booted with" });
|
|
490
|
-
return;
|
|
491
|
-
}
|
|
492
547
|
try {
|
|
493
548
|
swap({ readFace: config.readFace });
|
|
494
549
|
logger.info("read_face_swapped", { from: before ?? null, to: config.readFace ?? null, phase, note: "hot seat (core swapDeps) — legs that already prepared keep the face they prepared under" });
|
|
@@ -644,7 +699,7 @@ export async function createConfigCenterRuntime(ctx) {
|
|
|
644
699
|
}
|
|
645
700
|
},
|
|
646
701
|
startRefreshLoop(a) {
|
|
647
|
-
const {
|
|
702
|
+
const { pricing, limitSync, swapRunnerDeps, ceilingVerdict, consolidationSeat, checkpointStorePresent } = a;
|
|
648
703
|
if (configProvider) {
|
|
649
704
|
const ccRef = config.configCenter;
|
|
650
705
|
let refreshInFlight = false;
|
|
@@ -662,14 +717,14 @@ export async function createConfigCenterRuntime(ctx) {
|
|
|
662
717
|
if (r === null && planeDeferredNoHandoff) {
|
|
663
718
|
const skillsDebt = (planeDeferredNoHandoff.blocked ?? []).includes("skills");
|
|
664
719
|
const promoted = lkgSurvivesRestart || skillsDebt ? await persistLkgDurable(planeDeferredNoHandoff.candidate, planeDeferredNoHandoff.candidateEtag) : false;
|
|
665
|
-
const skillsProofPromotion = !promoted && !lkgSurvivesRestart && skillsDebt && lastPrewarmBodiesVerified
|
|
720
|
+
const skillsProofPromotion = !promoted && !lkgSurvivesRestart && skillsDebt && lastPrewarmBodiesVerified;
|
|
666
721
|
if (skillsProofPromotion) {
|
|
667
722
|
pendingRestart = { restartRequired: true, reasons: ["skills"], version: planeDeferredNoHandoff.version, since: Date.now() };
|
|
668
723
|
logger.info("config_boot_skill_debt_promoted", { version: planeDeferredNoHandoff.version, note: "skill bodies verified on a source-confirmed-current candidate — the withheld skills restart is now published (non-durable lane, repair proven)" });
|
|
669
724
|
planeDeferredNoHandoff = undefined;
|
|
670
725
|
}
|
|
671
726
|
else if (promoted) {
|
|
672
|
-
const promotedReasons = [...new Set(
|
|
727
|
+
const promotedReasons = [...new Set(planeDeferredNoHandoff.blocked ?? [])];
|
|
673
728
|
if (promotedReasons.length > 0) {
|
|
674
729
|
pendingRestart = { restartRequired: true, reasons: promotedReasons, version: planeDeferredNoHandoff.version, since: Date.now() };
|
|
675
730
|
}
|
|
@@ -697,6 +752,7 @@ export async function createConfigCenterRuntime(ctx) {
|
|
|
697
752
|
...(r.domainErrors ?? []).map((de) => ({ domain: de.domain, error: de.error })),
|
|
698
753
|
...(promptsGate.ok ? [] : [{ domain: "prompts", error: promptsGate.error }]),
|
|
699
754
|
],
|
|
755
|
+
...(r.droppedEntries !== undefined ? { droppedEntries: r.droppedEntries } : {}),
|
|
700
756
|
lkgVersion: latestEffective?.version ?? "(env)",
|
|
701
757
|
note: "candidate rejected whole (§9.5-5) — live config keeps the last-known-good; fix the named files to unblock",
|
|
702
758
|
});
|
|
@@ -704,24 +760,24 @@ export async function createConfigCenterRuntime(ctx) {
|
|
|
704
760
|
return "ok";
|
|
705
761
|
}
|
|
706
762
|
lastRejectedCandidate = undefined;
|
|
763
|
+
warnDroppedEntries(r, "refresh");
|
|
707
764
|
if (ccRef?.dryRun) {
|
|
708
765
|
logEffectiveDiff(config, r.effective, logger);
|
|
709
766
|
ccEtag = r.etag;
|
|
710
767
|
}
|
|
711
768
|
else {
|
|
712
769
|
const planeChanged = modelPlaneChanged(appliedPlaneEff, r.effective);
|
|
713
|
-
const planeDeferred = swapRunnerDeps === undefined && (runnerTierFrozen || planeHasActiveTiers(r.effective)) && planeChanged;
|
|
714
770
|
let applyReport;
|
|
715
771
|
const committed = applyEffective(config, r.effective, logger, {
|
|
716
|
-
|
|
772
|
+
leg: "hot",
|
|
773
|
+
checkpointStorePresent,
|
|
717
774
|
sealedKeys,
|
|
718
775
|
generation: tickGen,
|
|
719
776
|
report: (rep) => {
|
|
720
777
|
applyReport = rep;
|
|
721
778
|
applyLedger.recordApply(rep);
|
|
722
779
|
},
|
|
723
|
-
...(
|
|
724
|
-
...(swapRunnerDeps !== undefined && planeChanged ? { swapPlane: swapRunnerDeps } : {}),
|
|
780
|
+
...(planeChanged ? { swapPlane: swapRunnerDeps } : {}),
|
|
725
781
|
});
|
|
726
782
|
if (!committed)
|
|
727
783
|
return "ok";
|
|
@@ -732,57 +788,40 @@ export async function createConfigCenterRuntime(ctx) {
|
|
|
732
788
|
mcpRevocations.applyEnabledEntries(enabledMcpEntries(r.effective.mcp));
|
|
733
789
|
applyLiveReadFace(r.effective, swapRunnerDeps, "refresh");
|
|
734
790
|
applyLedger.applied(tickGen, r.effective.version);
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
}
|
|
738
|
-
else {
|
|
791
|
+
const tickPlane = modelPlaneCommitted(applyReport);
|
|
792
|
+
if (tickPlane)
|
|
739
793
|
appliedPlaneEff = r.effective;
|
|
740
|
-
|
|
741
|
-
}
|
|
794
|
+
planeDeferredNoHandoff = undefined;
|
|
742
795
|
await adoptCenterPrompts(r.effective, "refresh");
|
|
743
|
-
if (
|
|
796
|
+
if (tickPlane)
|
|
744
797
|
markRosterLanded(r.effective);
|
|
745
798
|
const fullyApplied = applyReport?.fullyApplied !== false;
|
|
746
799
|
if (!fullyApplied) {
|
|
800
|
+
ccEtag = undefined;
|
|
801
|
+
const refused = applyReport ? refusedGroups(applyReport) : [];
|
|
747
802
|
logger.warn("config_candidate_partially_applied", {
|
|
748
803
|
version: r.effective.version,
|
|
749
|
-
rejected:
|
|
804
|
+
rejected: refused.flatMap((g) => g.keys),
|
|
805
|
+
groups: refused.map((g) => g.group),
|
|
750
806
|
note: "a group of this candidate was refused — the live config keeps serving the prior values for it; the LKG and the ETag stay on the last FULLY applied generation (this tree is re-judged next tick)",
|
|
751
807
|
});
|
|
752
808
|
return "ok";
|
|
753
809
|
}
|
|
754
810
|
const lkgPersisted = await persistLkgDurable(r.effective, r.etag);
|
|
755
|
-
const reasons = restartReasons(effective, r.effective, restartCtx());
|
|
756
|
-
if (swapRunnerDeps !== undefined) {
|
|
757
|
-
const mi = reasons.indexOf("models-tiers");
|
|
758
|
-
if (mi >= 0)
|
|
759
|
-
reasons.splice(mi, 1);
|
|
760
|
-
}
|
|
811
|
+
const reasons = restartReasons(effective, r.effective, restartCtx(consolidationSeat?.read()));
|
|
761
812
|
const skillsChangeDetected = reasons.includes("skills");
|
|
762
813
|
if (bootSkillStale && !skillsChangeDetected)
|
|
763
814
|
reasons.push("skills");
|
|
764
|
-
if (
|
|
765
|
-
if (lkgPersisted) {
|
|
766
|
-
if (!reasons.includes("models-tiers"))
|
|
767
|
-
reasons.push("models-tiers");
|
|
768
|
-
planeDeferredNoHandoff = undefined;
|
|
769
|
-
}
|
|
770
|
-
else {
|
|
771
|
-
const blocked = reasons.splice(0, reasons.length);
|
|
772
|
-
planeDeferredNoHandoff = { version: r.effective.version, since: planeDeferredNoHandoff?.since ?? Date.now(), ...(blocked.length > 0 ? { blocked } : {}), planeDeferred: true, candidate: r.effective, ...(r.etag !== undefined ? { candidateEtag: r.etag } : {}) };
|
|
773
|
-
logger.warn("models_tiers_deferred_no_handoff", { version: r.effective.version, blockedReasons: blocked, note: "plane deferred but no NEXT-BOOT handoff (LKG disabled/unwritable, or storage not declared restart-surviving — set CONFIG_LKG_DURABLE=true) — the WHOLE restart signal is withheld (it would loop); the old generation keeps serving" });
|
|
774
|
-
}
|
|
775
|
-
}
|
|
776
|
-
else if (lkgSurvivesRestart && !lkgPersisted) {
|
|
815
|
+
if (lkgSurvivesRestart && !lkgPersisted) {
|
|
777
816
|
const blocked = reasons.splice(0, reasons.length);
|
|
778
|
-
planeDeferredNoHandoff = { version: r.effective.version, since:
|
|
817
|
+
planeDeferredNoHandoff = { version: r.effective.version, since: Date.now(), blocked, candidate: r.effective, ...(r.etag !== undefined ? { candidateEtag: r.etag } : {}) };
|
|
779
818
|
logger.warn("restart_candidate_publication_incomplete", { version: r.effective.version, blockedReasons: blocked, note: "durable LKG declared but the candidate's publication is incomplete (skill bodies unverified) — restart signal withheld; retried every tick until the cache completes" });
|
|
780
819
|
}
|
|
781
|
-
else if (!
|
|
820
|
+
else if (!lkgSurvivesRestart && bootSkillStale && !skillsChangeDetected && !lastPrewarmBodiesVerified) {
|
|
782
821
|
const i = reasons.indexOf("skills");
|
|
783
822
|
if (i >= 0) {
|
|
784
823
|
reasons.splice(i, 1);
|
|
785
|
-
planeDeferredNoHandoff = { version: r.effective.version, since:
|
|
824
|
+
planeDeferredNoHandoff = { version: r.effective.version, since: Date.now(), blocked: ["skills"], candidate: r.effective, ...(r.etag !== undefined ? { candidateEtag: r.etag } : {}) };
|
|
786
825
|
logger.warn("config_boot_skill_debt_withheld", { version: r.effective.version, note: "boot skill debt still unproven on a non-durable deployment (body cache does not verify) — skills restart withheld this tick; re-verified each tick and published once the bodies prove fetchable" });
|
|
787
826
|
}
|
|
788
827
|
}
|
|
@@ -797,7 +836,7 @@ export async function createConfigCenterRuntime(ctx) {
|
|
|
797
836
|
}
|
|
798
837
|
logger.info("sema_registry_refreshed", {
|
|
799
838
|
version: r.effective.version,
|
|
800
|
-
note: "collab + runtime governance + limits + models/roles/roster hot-applied; skills/mcp/
|
|
839
|
+
note: "collab + runtime governance (incl. approvalRequire) + limits + models/roles/roster hot-applied; skills/mcp/a2a/scenarios are restart-to-apply",
|
|
801
840
|
...(pendingRestart ? { restartRequired: true, restartReasons: pendingRestart.reasons } : {}),
|
|
802
841
|
});
|
|
803
842
|
latestEffective = r.effective;
|
|
@@ -848,28 +887,29 @@ export async function createConfigCenterRuntime(ctx) {
|
|
|
848
887
|
logger.warn("config_boot_deferred_candidate_rejected", {
|
|
849
888
|
version: r.effective.version,
|
|
850
889
|
errors: [...(r.domainErrors ?? []).map((de) => ({ domain: de.domain, error: de.error })), ...(promptsGate.ok ? [] : [{ domain: "prompts", error: promptsGate.error }])],
|
|
890
|
+
...(r.droppedEntries !== undefined ? { droppedEntries: r.droppedEntries } : {}),
|
|
851
891
|
note: "late boot pull carried an invalid candidate — env fallback keeps serving; the refresh cadence re-judges the same tree (etag not advanced)",
|
|
852
892
|
});
|
|
853
893
|
return;
|
|
854
894
|
}
|
|
895
|
+
warnDroppedEntries(r, "boot-deferred");
|
|
855
896
|
if (ccRef?.dryRun) {
|
|
856
897
|
logEffectiveDiff(config, r.effective, logger);
|
|
857
898
|
ccEtag = r.etag;
|
|
858
899
|
return;
|
|
859
900
|
}
|
|
860
901
|
const planeChangedLate = modelPlaneChanged(appliedPlaneEff, r.effective);
|
|
861
|
-
const planeDeferredLate = swapRunnerDeps === undefined && (runnerTierFrozen || planeHasActiveTiers(r.effective)) && planeChangedLate;
|
|
862
902
|
let applyReportLate;
|
|
863
903
|
const committedLate = applyEffective(config, r.effective, logger, {
|
|
864
|
-
|
|
904
|
+
leg: "hot",
|
|
905
|
+
checkpointStorePresent,
|
|
865
906
|
sealedKeys,
|
|
866
907
|
generation: lateGen,
|
|
867
908
|
report: (rep) => {
|
|
868
909
|
applyReportLate = rep;
|
|
869
910
|
applyLedger.recordApply(rep);
|
|
870
911
|
},
|
|
871
|
-
...(
|
|
872
|
-
...(swapRunnerDeps !== undefined && planeChangedLate ? { swapPlane: swapRunnerDeps } : {}),
|
|
912
|
+
...(planeChangedLate ? { swapPlane: swapRunnerDeps } : {}),
|
|
873
913
|
});
|
|
874
914
|
if (!committedLate)
|
|
875
915
|
return;
|
|
@@ -879,20 +919,21 @@ export async function createConfigCenterRuntime(ctx) {
|
|
|
879
919
|
ceilingVerdict?.judge();
|
|
880
920
|
applyLiveReadFace(r.effective, swapRunnerDeps, "boot-deferred");
|
|
881
921
|
applyLedger.applied(lateGen, r.effective.version);
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
else {
|
|
922
|
+
const latePlane = modelPlaneCommitted(applyReportLate);
|
|
923
|
+
if (latePlane)
|
|
885
924
|
appliedPlaneEff = r.effective;
|
|
886
|
-
|
|
887
|
-
}
|
|
925
|
+
planeDeferredNoHandoff = undefined;
|
|
888
926
|
await adoptCenterPrompts(r.effective, "boot-deferred");
|
|
889
|
-
if (
|
|
927
|
+
if (latePlane)
|
|
890
928
|
markRosterLanded(r.effective);
|
|
891
929
|
const fullyAppliedLate = applyReportLate?.fullyApplied !== false;
|
|
892
930
|
if (!fullyAppliedLate) {
|
|
931
|
+
ccEtag = undefined;
|
|
932
|
+
const refusedLate = applyReportLate ? refusedGroups(applyReportLate) : [];
|
|
893
933
|
logger.warn("config_candidate_partially_applied", {
|
|
894
934
|
version: r.effective.version,
|
|
895
|
-
rejected:
|
|
935
|
+
rejected: refusedLate.flatMap((g) => g.keys),
|
|
936
|
+
groups: refusedLate.map((g) => g.group),
|
|
896
937
|
note: "late-boot candidate had a refused group — the LKG/ETag stay on the last FULLY applied generation; the refresh cadence re-judges the same tree",
|
|
897
938
|
});
|
|
898
939
|
return;
|
|
@@ -901,27 +942,10 @@ export async function createConfigCenterRuntime(ctx) {
|
|
|
901
942
|
latestEffective = r.effective;
|
|
902
943
|
ccEtag = r.etag;
|
|
903
944
|
const lkgPersistedLate = await persistLkgDurable(r.effective, r.etag);
|
|
904
|
-
const reasons = restartReasons(undefined, r.effective, restartCtx());
|
|
905
|
-
if (
|
|
906
|
-
const miLate = reasons.indexOf("models-tiers");
|
|
907
|
-
if (miLate >= 0)
|
|
908
|
-
reasons.splice(miLate, 1);
|
|
909
|
-
}
|
|
910
|
-
if (planeDeferredLate) {
|
|
911
|
-
if (lkgPersistedLate) {
|
|
912
|
-
if (!reasons.includes("models-tiers"))
|
|
913
|
-
reasons.push("models-tiers");
|
|
914
|
-
planeDeferredNoHandoff = undefined;
|
|
915
|
-
}
|
|
916
|
-
else {
|
|
917
|
-
const blocked = reasons.splice(0, reasons.length);
|
|
918
|
-
planeDeferredNoHandoff = { version: r.effective.version, since: planeDeferredNoHandoff?.since ?? Date.now(), ...(blocked.length > 0 ? { blocked } : {}), planeDeferred: true, candidate: r.effective, ...(r.etag !== undefined ? { candidateEtag: r.etag } : {}) };
|
|
919
|
-
logger.warn("models_tiers_deferred_no_handoff", { version: r.effective.version, blockedReasons: blocked, note: "late-boot plane deferred but no NEXT-BOOT handoff (see CONFIG_LKG_DURABLE) — the WHOLE restart signal is withheld (it would loop); old generation keeps serving" });
|
|
920
|
-
}
|
|
921
|
-
}
|
|
922
|
-
else if (planeDeferredLate === false && lkgSurvivesRestart && !lkgPersistedLate) {
|
|
945
|
+
const reasons = restartReasons(undefined, r.effective, restartCtx(consolidationSeat?.read()));
|
|
946
|
+
if (lkgSurvivesRestart && !lkgPersistedLate) {
|
|
923
947
|
const blocked = reasons.splice(0, reasons.length);
|
|
924
|
-
planeDeferredNoHandoff = { version: r.effective.version, since:
|
|
948
|
+
planeDeferredNoHandoff = { version: r.effective.version, since: Date.now(), blocked, candidate: r.effective, ...(r.etag !== undefined ? { candidateEtag: r.etag } : {}) };
|
|
925
949
|
logger.warn("restart_candidate_publication_incomplete", { version: r.effective.version, blockedReasons: blocked, note: "late-boot candidate publication incomplete on a durable-declared deployment — restart signal withheld; retried every tick" });
|
|
926
950
|
}
|
|
927
951
|
if (reasons.length > 0)
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { NodeLspManager } from "@sema-agent/core";
|
|
2
1
|
import { TaskEnvRegistry } from "../capabilities/sandbox-file-send.js";
|
|
3
2
|
import { SessionEnvironmentSelection } from "../capabilities/select-environment-tool.js";
|
|
4
3
|
import type { ServiceConfig } from "../config.js";
|
|
@@ -67,6 +66,6 @@ export declare function createExecutionEnv(ctx: ExecutionEnvCtx): {
|
|
|
67
66
|
executionEnvFactory: import("@sema-agent/core").ExecutionEnvFactory | undefined;
|
|
68
67
|
worktreeReap: (() => Promise<void>) | undefined;
|
|
69
68
|
sendUserFileTaskEnvs: TaskEnvRegistry | undefined;
|
|
70
|
-
lspManager: import("../lsp/manager.js").E2bLspManager |
|
|
69
|
+
lspManager: import("@sema-agent/core").NodeLspManager | import("../lsp/manager.js").E2bLspManager | undefined;
|
|
71
70
|
};
|
|
72
71
|
//# sourceMappingURL=execution-env.d.ts.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
-
import {
|
|
3
|
+
import { createHostLspManager } from "../host-lsp-manager.js";
|
|
4
4
|
import { sandboxSendLaneEnabled, TaskEnvRegistry } from "../capabilities/sandbox-file-send.js";
|
|
5
5
|
import { SessionEnvironmentSelection } from "../capabilities/select-environment-tool.js";
|
|
6
6
|
import { createE2bLspManager } from "../lsp/e2b-manager.js";
|
|
@@ -29,6 +29,24 @@ function boundedSessionSetter(map, maxEntries) {
|
|
|
29
29
|
map.delete(map.keys().next().value);
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
|
+
function forwardedSandboxEnvKeys(remoteExec) {
|
|
33
|
+
switch (remoteExec.provider) {
|
|
34
|
+
case "e2b":
|
|
35
|
+
return Object.keys(remoteExec.sandboxEnv ?? {}).sort();
|
|
36
|
+
case "local-docker":
|
|
37
|
+
return Object.keys(remoteExec.env ?? {}).sort();
|
|
38
|
+
case "k8s":
|
|
39
|
+
case "ssh":
|
|
40
|
+
case "adb":
|
|
41
|
+
case "host":
|
|
42
|
+
case "device":
|
|
43
|
+
return [];
|
|
44
|
+
default: {
|
|
45
|
+
const unreachable = remoteExec;
|
|
46
|
+
throw new Error(`unhandled remote-exec provider: ${String(unreachable.provider)}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
32
50
|
const MAX_CWD_SESSIONS = 4096;
|
|
33
51
|
export function createSessionScopedRegistries(maxEntries = MAX_CWD_SESSIONS) {
|
|
34
52
|
const perSessionCwd = new Map();
|
|
@@ -275,7 +293,7 @@ export function createExecutionEnv(ctx) {
|
|
|
275
293
|
config.remoteExec.provider === "local-docker";
|
|
276
294
|
const suspendable = config.remoteExec.provider === "e2b" ||
|
|
277
295
|
(config.remoteExec.provider === "k8s" && !!config.remoteExec.s3Snapshot);
|
|
278
|
-
const sandboxEnvKeys =
|
|
296
|
+
const sandboxEnvKeys = forwardedSandboxEnvKeys(config.remoteExec);
|
|
279
297
|
logger.info("remote_exec_enabled", { provider: config.remoteExec.provider, isolated, suspendable, ...(sandboxEnvKeys.length > 0 ? { sandboxEnvKeys } : {}) });
|
|
280
298
|
if (!isolated)
|
|
281
299
|
logger.warn("remote_exec_real_system", { provider: config.remoteExec.provider, note: "non-isolated target — actions are permanent; rely on the policy gate + HITL (design/61 §5)" });
|
|
@@ -290,7 +308,7 @@ export function createExecutionEnv(ctx) {
|
|
|
290
308
|
})
|
|
291
309
|
:
|
|
292
310
|
lspProvider === "host" && config.lspHostEnabled && config.requirePrincipal !== true
|
|
293
|
-
?
|
|
311
|
+
? createHostLspManager(config, (event, fields) => logger.info(event, fields))
|
|
294
312
|
: undefined;
|
|
295
313
|
if (lspManager)
|
|
296
314
|
logger.info("lsp_enabled", { provider: lspProvider });
|
package/dist/boot/leader.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createLeaderEndpoint } from "../leader/endpoint.js";
|
|
2
2
|
import { createLeaderRunner } from "../leader/wire.js";
|
|
3
3
|
import { buildDeploymentPostureSeats } from "./runner-deps.js";
|
|
4
|
+
import { hasApprovalListIntent } from "../approval.js";
|
|
4
5
|
export function leaderK8sMinioGap(leaderEnabled, leaderProvider, hasS3) {
|
|
5
6
|
if (!(leaderEnabled && leaderProvider === "k8s" && !hasS3))
|
|
6
7
|
return null;
|
|
@@ -67,16 +68,18 @@ export function createLeaderFace(ctx) {
|
|
|
67
68
|
...(toolResultStore ? { toolResultStore } : {}),
|
|
68
69
|
...(leaderProvider === "k8s" ? { workspace: "/workspace" } : {}),
|
|
69
70
|
sessionStore,
|
|
70
|
-
...(checkpointStore
|
|
71
|
+
...(checkpointStore
|
|
71
72
|
? {
|
|
72
|
-
durable:
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
73
|
+
durable: () => hasApprovalListIntent(config)
|
|
74
|
+
? {
|
|
75
|
+
checkpointStore,
|
|
76
|
+
requireApproval: config.approvalRequire,
|
|
77
|
+
deny: config.approvalDeny,
|
|
78
|
+
autoBudget: config.approvalAutoBudget,
|
|
79
|
+
neverAuto: config.approvalNeverAuto,
|
|
80
|
+
...(config.approvalTimeoutSec > 0 ? { ttlMs: config.approvalTimeoutSec * 1000 } : {}),
|
|
81
|
+
}
|
|
82
|
+
: undefined,
|
|
80
83
|
}
|
|
81
84
|
: {}),
|
|
82
85
|
}), {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { RestartSliceCtx } from "../config-center/restart-signal.js";
|
|
1
2
|
import { type ConsolidationDriverRunRow, type ConsolidationRunReceipt, type MemoryBackend, type MemoryConsolidationDriverDeps, type RunMemoryConsolidationOptions, type SessionCaptureRecordStore } from "@sema-agent/core";
|
|
2
3
|
/** D3 投影的座标签闭集。`role:<name>` 里的 name 只可能是 core 的 role 链两跳之一。 */
|
|
3
4
|
export type ConsolidationSeatLabel = "explicit" | "role:consolidate" | "role:summarize";
|
|
@@ -30,6 +31,43 @@ export interface ConsolidationDriverSeat {
|
|
|
30
31
|
* (探针只构造闭包、不发任何请求、无副作用。)
|
|
31
32
|
*/
|
|
32
33
|
export declare function resolveConsolidationDriverSeat(deps: MemoryConsolidationDriverDeps): ConsolidationDriverSeat;
|
|
34
|
+
/**
|
|
35
|
+
* S-668 波 0([ref] §3)—— 整理驱动席的 **restart 读数**。过渡件:**波 1 转热后删**(那时每轮 run 起手
|
|
36
|
+
* 现取当前代的席,不再有 boot 烤死的席,这只表也就没有要比的东西了)。
|
|
37
|
+
*
|
|
38
|
+
* ## 为什么要它
|
|
39
|
+
*
|
|
40
|
+
* 席位在 boot 期解析一次(本模块头注「座在启动期解析一次」),core 的解析器把它选中的那只 `Model` 对象焊进
|
|
41
|
+
* chat 闭包。refresh 拍对模型面的热换(`mutateInPlace` + `swapDeps`)换的是目录里的**值**,够不到那只对象
|
|
42
|
+
* ⇒ 中心改了 roles / 档位绑定 / 那条目录条目之后,整理跑仍打 boot 那一代。修前没有任何一片签它 —— 它唯一
|
|
43
|
+
* 沾边的 `models-tiers` 片在生产上恒被摘除(今已退役)—— 于是这块是「静默冷」:既不热应用、也不报重启。
|
|
44
|
+
*
|
|
45
|
+
* ## 读法:问 core 的**同一只**解析器,不抄它的 role 链
|
|
46
|
+
*
|
|
47
|
+
* 席位 = `consolidate → summarize(含 flash 档位缺省)` 那条链对「env 角色底 + 中心目录 + 档位表」解出来的
|
|
48
|
+
* 那只 Model;本层抄一份链就是第二真源({@link seatLabel} 注里同一条理由)。做法:拿活配置调
|
|
49
|
+
* `resolveMemoryConsolidationDriver`,brain 与 per-model 凭据席都换成探针,再调一次它交回的 `chat` ——
|
|
50
|
+
* core 的 chat 第一件事就是拿**它选中的那只 Model** 问凭据席(`deps.getApiKeyAndHeaders?.(resolved)`,在
|
|
51
|
+
* 第一个 await 之前同步求值),探针在那一刻记下它并抛停:零请求、零副作用。
|
|
52
|
+
* ⚠️ 这一步依赖 core chat 闭包的**行为次序**:哪天 core 改成先做别的再问凭据席,探针就截不到 —— 那一刻本函数
|
|
53
|
+
* **响亮抛**(boot 期抛 = 阀门开着的部署拒启,句子说清原因),不退化成「读不到就当没变」(那正是本件要消灭的
|
|
54
|
+
* 静默)。钉:test/memory-consolidation-driver.test.ts 的探针格对真 core 跑,提货批当场红。
|
|
55
|
+
*
|
|
56
|
+
* ## 指纹里有什么
|
|
57
|
+
*
|
|
58
|
+
* 整只 Model 减掉 `cost`:整理跑只读 usage 的 token 数、零处读价目(core 7.29.0 的 driver 实现零 `cost` /
|
|
59
|
+
* `pricing` 读点),纯改价不该造一次重启。解不出来(中心撤掉了 consolidate / summarize 两跳)⇒ 记成
|
|
60
|
+
* `{ unresolvable: <core 原句> }`,与 boot 那只不等 ⇒ 签重启;重启会在 D1 拒启、把同一句原句写进拒因 ——
|
|
61
|
+
* 那正是运维该看见的话,比「这台还在用一只中心已经撤掉的席」诚实。
|
|
62
|
+
*/
|
|
63
|
+
export interface ConsolidationSeatWatch {
|
|
64
|
+
/** boot 烤进去的席 vs 活配置此刻会解出的席(`restartReasons` 的 `memory-consolidation` 片两侧读数)。 */
|
|
65
|
+
read(): NonNullable<RestartSliceCtx["consolidationSeat"]>;
|
|
66
|
+
}
|
|
67
|
+
/** 解席的输入面 = boot 期真席用的同三件(活引用:refresh 就地换代,`read()` 每次现取)。 */
|
|
68
|
+
export type ConsolidationSeatPlane = Pick<MemoryConsolidationDriverDeps, "models" | "tiers" | "roles">;
|
|
69
|
+
/** `create*`:返回带捕获状态(boot 那只指纹)的活对象。须在真席解析的**同一时刻**调(同一份输入)。 */
|
|
70
|
+
export declare function createConsolidationSeatWatch(plane: () => ConsolidationSeatPlane): ConsolidationSeatWatch;
|
|
33
71
|
/**
|
|
34
72
|
* **每 scope 单飞**(codex 交叉复审 [high],验真后修)—— 同一 scope 上在飞的那一轮被后来者**并入**,
|
|
35
73
|
* 而不是各起一轮。`create*`:返回带状态的活对象。
|