@sema-agent/server 7.125.1 → 7.126.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 +195 -2
- package/README.md +2 -2
- package/README.zh-CN.md +2 -2
- package/USAGE.md +263 -140
- package/deploy/sema-up/README.md +1 -1
- package/deploy/sema-up/chart/templates/networkpolicy-sandbox.yaml +47 -0
- package/deploy/sema-up/chart/templates/sandbox-rbac.yaml +5 -1
- package/deploy/sema-up/chart/templates/server-v4pro.yaml +2 -2
- package/deploy/sema-up/chart/templates/server.yaml +1 -1
- package/deploy/sema-up/chart/values.yaml +12 -0
- package/deploy/sema-up/cluster-up.sh +10 -10
- package/deploy/sema-up/kube-up.sh +11 -10
- package/deploy/sema-up/lib/dataroot.sh +1 -1
- package/deploy/sema-up/lib/envf.sh +5 -5
- package/deploy/sema-up/lib/flagshape.sh +5 -5
- package/deploy/sema-up/lib/lanes.py +1 -1
- package/deploy/sema-up/lib/parse-machines.py +2 -2
- package/deploy/sema-up/lib/shell-access.sh +1 -1
- package/deploy/sema-up/preflight.sh +4 -4
- package/deploy/sema-up/sema-up.sh +33 -33
- package/deploy/sema-up/smoke.sh +3 -3
- package/deploy/sema-up/stack/compose.yaml +1 -1
- package/deploy/sema-up/stack/sema-stack-cluster.yaml +6 -2
- package/dist/approval-card.d.ts +20 -4
- package/dist/approval-content-kind.d.ts +38 -22
- package/dist/approval-content-kind.js +20 -4
- package/dist/audit.js +2 -0
- package/dist/bench/s1/arms.d.ts +9 -37
- package/dist/bench/s1/arms.js +4 -61
- package/dist/bench/s1/live-deps.d.ts +4 -10
- package/dist/bench/s1/live-deps.js +1 -222
- package/dist/bench/s1/oracle.d.ts +1 -1
- package/dist/bench/s1/reviewer.d.ts +1 -1
- package/dist/bench/s1/row.d.ts +5 -7
- package/dist/bench/s1/row.js +0 -2
- package/dist/bench/s1/run-firm.d.ts +2 -2
- package/dist/bench/s1/run-firm.js +1 -4
- package/dist/bench/s1/runner-ctx.d.ts +17 -29
- package/dist/bench/s1/runner-ctx.js +3 -7
- package/dist/bench/s1/tasks.d.ts +9 -46
- package/dist/bench/s1/tasks.js +4 -63
- package/dist/boot/execution-env.d.ts +38 -26
- package/dist/boot/execution-env.js +71 -38
- package/dist/boot/memory-boundary.d.ts +1 -1
- package/dist/boot/parked-revive-gate.d.ts +0 -3
- package/dist/boot/parked-revive-gate.js +2 -2
- package/dist/boot/resolve-spec.d.ts +0 -2
- package/dist/boot/resolve-spec.js +12 -17
- package/dist/boot/retention-lane.d.ts +12 -1
- package/dist/boot/retention-lane.js +2 -0
- package/dist/boot/runner-deps.d.ts +5 -5
- package/dist/boot/runner-deps.js +5 -16
- package/dist/boot/session-faces.d.ts +5 -1
- package/dist/boot/session-faces.js +37 -1
- package/dist/boot/stage-03-store-backend.d.ts +1 -0
- package/dist/boot/stage-03-store-backend.js +2 -2
- package/dist/boot/stage-04-stores.d.ts +1 -0
- package/dist/boot/stage-05-execution-env.d.ts +2 -2
- package/dist/boot/stage-05-execution-env.js +7 -4
- package/dist/boot/stage-06-runners.d.ts +2 -3
- package/dist/boot/stage-06-runners.js +8 -7
- package/dist/boot/stage-07-capability-layer.d.ts +2 -3
- package/dist/boot/stage-07-capability-layer.js +3 -4
- package/dist/boot/stage-08-reapers.d.ts +2 -3
- package/dist/boot/stage-08-reapers.js +2 -2
- package/dist/boot/stage-09-leader.d.ts +2 -3
- package/dist/boot/stage-09-leader.js +2 -1
- package/dist/boot/stage-10-http-server.d.ts +2 -3
- package/dist/boot/stage-10-http-server.js +2 -2
- package/dist/boot/stores.d.ts +1 -0
- package/dist/boot/stores.js +4 -3
- package/dist/boot/web-admin.d.ts +5 -0
- package/dist/boot/web-admin.js +28 -14
- package/dist/brain.d.ts +2 -2
- package/dist/brain.js +1 -1
- package/dist/capabilities/builtin-tools.d.ts +2 -1
- package/dist/capabilities/composite-members.d.ts +1 -1
- package/dist/capabilities/composite-members.js +1 -1
- package/dist/capabilities/hands-lane.d.ts +9 -6
- package/dist/capabilities/hands-lane.js +2 -2
- package/dist/capabilities/memory-notice.d.ts +27 -22
- package/dist/capabilities/memory-notice.js +15 -17
- package/dist/capabilities/scenarios.d.ts +9 -14
- package/dist/capabilities/scenarios.js +5 -50
- package/dist/capability-facts.d.ts +22 -11
- package/dist/capability-facts.js +13 -6
- package/dist/config-catalog.js +11 -4
- package/dist/config-provider.d.ts +5 -1
- package/dist/config-provider.js +23 -4
- package/dist/config-types.d.ts +14 -1
- package/dist/config.js +39 -6
- package/dist/deployment-governance.d.ts +19 -21
- package/dist/deployment-governance.js +7 -8
- package/dist/env-name-allowlist-knobs.d.ts +5 -5
- package/dist/env-name-allowlist-knobs.js +1 -0
- package/dist/execution-lane-caps.js +2 -2
- package/dist/hooks/hook-runner.d.ts +84 -30
- package/dist/hooks/hook-runner.js +74 -41
- package/dist/http/admission.js +12 -9
- package/dist/http/durable-run-leg.d.ts +5 -4
- package/dist/http/durable-run-leg.js +1 -1
- package/dist/http/idempotency.d.ts +28 -6
- package/dist/http/idempotency.js +10 -2
- package/dist/http/principal-gate.d.ts +14 -0
- package/dist/http/principal-gate.js +7 -0
- package/dist/http/request-guards.d.ts +2 -1
- package/dist/http/request-guards.js +14 -14
- package/dist/http/resume-legs.d.ts +2 -2
- package/dist/http/resume-legs.js +5 -4
- package/dist/http/route-ctx.d.ts +8 -6
- package/dist/http/routes/a2a-serve.js +11 -7
- package/dist/http/routes/approvals-assistant.js +18 -3
- package/dist/http/routes/background.d.ts +1 -1
- package/dist/http/routes/background.js +1 -1
- package/dist/http/routes/capabilities.js +10 -2
- package/dist/http/routes/mcp-reconnect.js +1 -1
- package/dist/http/routes/runs.d.ts +4 -3
- package/dist/http/routes/runs.js +12 -13
- package/dist/http/routes/session-sync.js +14 -11
- package/dist/http/routes/sessions.js +9 -9
- package/dist/http/routes/side-query.js +6 -19
- package/dist/http/routes/tasks.js +12 -11
- package/dist/http/server.d.ts +4 -0
- package/dist/http/server.js +2 -2
- package/dist/http/submit-replay.d.ts +15 -8
- package/dist/http/submit-replay.js +6 -0
- package/dist/http/wire-types.d.ts +7 -9
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/internal-run-env.d.ts +30 -0
- package/dist/internal-run-env.js +11 -0
- package/dist/leader/wire.js +3 -2
- package/dist/memory-scope.d.ts +19 -7
- package/dist/memory-scope.js +25 -8
- package/dist/observability/fail-open.d.ts +15 -3
- package/dist/observability/fail-open.js +15 -3
- package/dist/observability/metrics.d.ts +0 -1
- package/dist/observability/metrics.js +0 -3
- package/dist/observability/run-terminal.js +69 -4
- package/dist/permission-rule-vocab.d.ts +3 -2
- package/dist/permission-rule-vocab.js +1 -1
- package/dist/plan-cache-probe.d.ts +3 -2
- package/dist/plugins/approval-ask-store-sql.d.ts +1 -1
- package/dist/plugins/caching-session-store.d.ts +3 -0
- package/dist/plugins/caching-session-store.js +3 -0
- package/dist/plugins/checkpoint-store-sql.d.ts +42 -28
- package/dist/plugins/checkpoint-store-sql.js +57 -11
- package/dist/plugins/file-run-store.d.ts +25 -21
- package/dist/plugins/file-run-store.js +70 -34
- package/dist/plugins/local-checkpoint-store.d.ts +8 -5
- package/dist/plugins/local-checkpoint-store.js +5 -15
- package/dist/plugins/local-session-store.d.ts +66 -7
- package/dist/plugins/local-session-store.js +168 -101
- package/dist/plugins/mailbox-recipient-lifecycle.d.ts +1 -1
- package/dist/plugins/memory-run-store.d.ts +19 -3
- package/dist/plugins/memory-run-store.js +38 -3
- package/dist/plugins/one-time-migrations.d.ts +141 -39
- package/dist/plugins/one-time-migrations.js +32 -143
- package/dist/plugins/pg-pool.js +11 -1
- package/dist/plugins/pg-session-storage.d.ts +2 -0
- package/dist/plugins/pg-session-storage.js +9 -5
- package/dist/plugins/remote-env-adb.d.ts +3 -0
- package/dist/plugins/remote-env-adb.js +1 -0
- package/dist/plugins/remote-env-device.d.ts +3 -0
- package/dist/plugins/remote-env-device.js +1 -0
- package/dist/plugins/remote-env-e2b.d.ts +4 -0
- package/dist/plugins/remote-env-e2b.js +2 -1
- package/dist/plugins/remote-env-host.d.ts +12 -0
- package/dist/plugins/remote-env-host.js +11 -1
- package/dist/plugins/remote-env-k8s.d.ts +227 -39
- package/dist/plugins/remote-env-k8s.js +450 -75
- package/dist/plugins/remote-env-local-docker.d.ts +4 -0
- package/dist/plugins/remote-env-local-docker.js +2 -1
- package/dist/plugins/remote-env-ssh.d.ts +3 -0
- package/dist/plugins/remote-env-ssh.js +1 -0
- package/dist/plugins/retention-store-sql.d.ts +4 -1
- package/dist/plugins/retention-store-sql.js +11 -9
- package/dist/plugins/run-store-sql.d.ts +44 -6
- package/dist/plugins/run-store-sql.js +92 -27
- package/dist/plugins/session-capture-record-store-sql.d.ts +2 -3
- package/dist/plugins/sql-driver.d.ts +2 -1
- package/dist/plugins/store-backend.js +1 -1
- package/dist/plugins/store-contracts.d.ts +17 -3
- package/dist/plugins/tidb-pool.js +15 -3
- package/dist/plugins/tidb-session-storage.js +3 -2
- package/dist/plugins/tidb-session-store.d.ts +2 -0
- package/dist/plugins/tidb-session-store.js +6 -2
- package/dist/request-key-closure.d.ts +12 -0
- package/dist/request-key-closure.js +3 -3
- package/dist/router/route-orchestration.d.ts +3 -11
- package/dist/router/route-orchestration.js +0 -4
- package/dist/rule-entry-list.js +0 -4
- package/dist/rules-consent.js +3 -0
- package/dist/run-local.d.ts +5 -4
- package/dist/run-local.js +23 -17
- package/dist/runs.js +1 -0
- package/dist/security.d.ts +7 -0
- package/dist/security.js +5 -0
- package/dist/server-secret-env.d.ts +10 -4
- package/dist/server-secret-env.js +4 -1
- package/dist/session-incarnation.d.ts +46 -2
- package/dist/session-incarnation.js +14 -3
- package/dist/session-sync-kernel.d.ts +10 -3
- package/dist/spec-fields.d.ts +24 -8
- package/dist/spec-fields.js +21 -2
- package/dist/task-workflow.d.ts +6 -4
- package/dist/task-workflow.js +3 -2
- package/dist/tool-approval.d.ts +78 -6
- package/dist/tool-approval.js +7 -3
- package/dist/trace/core-keyset-guard.d.ts +4 -4
- package/dist/trace/engine-notice-wire.d.ts +26 -1
- package/dist/trace/engine-notice-wire.js +7 -2
- package/dist/trace/project.d.ts +8 -3
- package/dist/trace/project.js +15 -1
- package/dist/trace/self-minted-wire.d.ts +104 -2
- package/dist/trace/self-minted-wire.js +35 -0
- package/dist/web-admin-client/apply-effective.d.ts +13 -7
- package/dist/web-admin-client/apply-effective.js +11 -26
- package/dist/web-admin-client/apply-ledger.d.ts +2 -2
- package/dist/web-admin-client/candidate-gate.d.ts +39 -4
- package/dist/web-admin-client/candidate-gate.js +9 -2
- package/dist/web-admin-client/facade.d.ts +2 -2
- package/dist/web-admin-client/http-client.d.ts +3 -1
- package/dist/web-admin-client/http-client.js +4 -3
- package/dist/web-admin-client/read-warnings.d.ts +33 -5
- package/dist/web-admin-client/read-warnings.js +41 -6
- package/dist/web-admin-client/types.d.ts +11 -5
- package/dist/workspace-cache.d.ts +45 -0
- package/dist/workspace-cache.js +30 -0
- package/dist/workspace-space-commit.d.ts +116 -0
- package/dist/workspace-space-commit.js +117 -0
- package/dist/workspace-space.d.ts +75 -9
- package/dist/workspace-space.js +52 -1
- package/package.json +4 -4
- package/dist/boot/session-incarnation-seat.d.ts +0 -41
- package/dist/boot/session-incarnation-seat.js +0 -69
- package/dist/capabilities/code-review-council.d.ts +0 -49
- package/dist/capabilities/code-review-council.js +0 -111
- package/dist/capabilities/collab-wire.d.ts +0 -36
- package/dist/capabilities/collab-wire.js +0 -2
- package/dist/capabilities/collab-workflows.d.ts +0 -47
- package/dist/capabilities/collab-workflows.js +0 -90
- package/dist/capabilities/prompts/code-review.d.ts +0 -25
- package/dist/capabilities/prompts/code-review.js +0 -39
- package/dist/capabilities/prompts/team.d.ts +0 -10
- package/dist/capabilities/prompts/team.js +0 -6
- package/dist/capabilities/team.d.ts +0 -113
- package/dist/capabilities/team.js +0 -70
|
@@ -6,7 +6,6 @@ import { applyAutoCompactWindow, buildModelCostKey, parseAutonomy, unmatchableTo
|
|
|
6
6
|
import { buildModelCompat, readModelCompat } from "../model-compat.js";
|
|
7
7
|
import { buildModelHeadersKey } from "../model-entry-headers.js";
|
|
8
8
|
import { validateCommandRules } from "../runtime-governance.js";
|
|
9
|
-
import { projectCollabToWorkflows, registerCollabWorkflows } from "../capabilities/collab-workflows.js";
|
|
10
9
|
import { stageLimits } from "./stage-limits.js";
|
|
11
10
|
import { APPROVAL_GROUP_KEYS, BATCH1_LIMIT_KEYS } from "./hot-keys-registry.js";
|
|
12
11
|
import { buildDisplaySafeUrl } from "../trace/redact.js";
|
|
@@ -138,12 +137,6 @@ export function applyEffective(config, eff, logger, opts) {
|
|
|
138
137
|
logger?.info("web_admin_runtime", { version: staged.version, approvalRequire: staged.approvalGate.next });
|
|
139
138
|
if (Object.keys(staged.hot.infoLine).length > 0)
|
|
140
139
|
logger?.info("web_admin_runtime_hot", staged.hot.infoLine);
|
|
141
|
-
for (const n of staged.modelPlaneGroup.stages.collab?.notices ?? []) {
|
|
142
|
-
if (n.level === "warn")
|
|
143
|
-
logger?.warn(n.msg, n.fields);
|
|
144
|
-
else
|
|
145
|
-
logger?.info(n.msg, n.fields);
|
|
146
|
-
}
|
|
147
140
|
if (Object.keys(staged.projects).length > 0)
|
|
148
141
|
logger?.info("web_admin_projects", { projects: Object.keys(staged.projects) });
|
|
149
142
|
return true;
|
|
@@ -172,15 +165,11 @@ function commitStaged(config, staged) {
|
|
|
172
165
|
config.autonomy = staged.hot.autonomyNext;
|
|
173
166
|
if (staged.hot.setCommandPolicy)
|
|
174
167
|
config.commandPolicy = staged.hot.commandPolicyNext;
|
|
175
|
-
const collab = staged.modelPlaneGroup.stages.collab;
|
|
176
|
-
if (collab !== undefined)
|
|
177
|
-
registerCollabWorkflows(collab.workflows);
|
|
178
168
|
mutateInPlace(config.projects, staged.projects);
|
|
179
169
|
}
|
|
180
|
-
export const MODEL_PLANE_DOMAINS = ["models"
|
|
170
|
+
export const MODEL_PLANE_DOMAINS = ["models"];
|
|
181
171
|
const MODEL_PLANE_SURFACES = {
|
|
182
172
|
models: ["models", "model", "modelRefusals", "droppedCatalogEntries", "modelApiKeyEnv", "modelApiKeys", "modelQuotaWeights", "roles", "tiers", "atMention"],
|
|
183
|
-
collab: ["collabWorkflows"],
|
|
184
173
|
};
|
|
185
174
|
const MODEL_PLANE_GROUP_KEYS = MODEL_PLANE_DOMAINS.flatMap((d) => MODEL_PLANE_SURFACES[d]);
|
|
186
175
|
export function withModelPlaneOf(target, source) {
|
|
@@ -220,7 +209,7 @@ function stageModelPlane(config, eff, logger, sealedKeys) {
|
|
|
220
209
|
const enabled = (eff.models?.models ?? []).filter((m) => m.enabled !== false);
|
|
221
210
|
const verdict = judgeCatalogEntries(enabled, { anthropicRouteMounted: config.anthropic !== undefined }, eff.models?.droppedCatalogEntries);
|
|
222
211
|
if (enabled.length === 0 && verdict.malformed.length === 0 && verdict.dropped.every((row) => row.identity?.enabled === false))
|
|
223
|
-
return { stages: {
|
|
212
|
+
return { stages: {} };
|
|
224
213
|
{
|
|
225
214
|
for (const [name, r] of Object.entries(verdict.refused))
|
|
226
215
|
logger?.warn(refusalEventOf(r.reason), refusalWarnFields(name, r));
|
|
@@ -231,7 +220,7 @@ function stageModelPlane(config, eff, logger, sealedKeys) {
|
|
|
231
220
|
invariant,
|
|
232
221
|
reason,
|
|
233
222
|
...detail,
|
|
234
|
-
kept: "the model plane of this candidate is refused as a group — the current model plane (catalog / roles / tiers / refusals / allowlist
|
|
223
|
+
kept: "the model plane of this candidate is refused as a group — the current model plane (catalog / roles / tiers / refusals / allowlist) keeps serving and the other groups of this candidate still apply; the candidate is not fully applied (LKG / ETag stay on the last fully applied generation) and is re-judged next pull",
|
|
235
224
|
});
|
|
236
225
|
return { stages: {}, rejected: { keys: MODEL_PLANE_GROUP_KEYS, reason, invariant, code }, refused: verdict.refused };
|
|
237
226
|
};
|
|
@@ -364,20 +353,13 @@ function stageModelPlane(config, eff, logger, sealedKeys) {
|
|
|
364
353
|
atMention,
|
|
365
354
|
infoLine: { count: usable.length, ...(Object.keys(verdict.refused).length > 0 ? refusedNamesLogFields("unavailable", Object.keys(verdict.refused)) : {}), default: defaultModel.id, defaultSource: picked.source, roles: Object.keys(roles), tiers: Object.keys(activeTiers), atMention: atMention.mode, sealedKeys: Object.values(modelApiKeys).filter((v) => typeof v === "string").length, sealedPoisoned: Object.values(modelApiKeys).filter((v) => typeof v !== "string").length },
|
|
366
355
|
};
|
|
367
|
-
return { stages: { models: plane
|
|
356
|
+
return { stages: { models: plane }, defaultName: picked.name, refused: verdict.refused };
|
|
368
357
|
}
|
|
369
358
|
}
|
|
370
|
-
function
|
|
371
|
-
|
|
372
|
-
const notices = [];
|
|
373
|
-
if (Object.keys(projected.workflows).length > 0)
|
|
374
|
-
notices.push({ level: "info", msg: "web_admin_collab_workflows", fields: { workflows: Object.keys(projected.workflows) } });
|
|
375
|
-
if (projected.skipped.length > 0)
|
|
376
|
-
notices.push({ level: "warn", msg: "web_admin_collab_skipped", fields: { skipped: projected.skipped } });
|
|
377
|
-
if (projected.notes.length > 0)
|
|
378
|
-
notices.push({ level: "info", msg: "web_admin_collab_notes", fields: { notes: projected.notes } });
|
|
379
|
-
return { workflows: projected.workflows, notices };
|
|
359
|
+
export function collabTemplatesNotExecuted(eff) {
|
|
360
|
+
return (eff.collab?.templates ?? []).filter((t) => t.enabled !== false).map((t) => t.id);
|
|
380
361
|
}
|
|
362
|
+
const COLLAB_NOT_EXECUTED_NOTE = "collab templates are accepted by the config store but nothing on this server executes them — the engine no longer ships a team-discussion runtime (core 7.49.0); run multi-member work as Agent sub-runs, or register a Workflow script in the deployment's workflow-scripts store";
|
|
381
363
|
function stageEffective(config, eff, logger, opts) {
|
|
382
364
|
if (opts.leg === "boot" && !eff.version) {
|
|
383
365
|
logger?.warn("web_admin_unpublished", {
|
|
@@ -386,6 +368,9 @@ function stageEffective(config, eff, logger, opts) {
|
|
|
386
368
|
});
|
|
387
369
|
}
|
|
388
370
|
const modelPlaneGroup = stageModelPlane(config, eff, logger, opts.sealedKeys);
|
|
371
|
+
const notExecuted = collabTemplatesNotExecuted(eff);
|
|
372
|
+
if (notExecuted.length > 0)
|
|
373
|
+
logger?.warn("web_admin_collab_not_executed", { version: eff.version, templates: notExecuted, note: COLLAB_NOT_EXECUTED_NOTE });
|
|
389
374
|
const approvalGate = stageApprovalGate(config, eff.governance, opts, logger);
|
|
390
375
|
const limits = stageLimits(config, { version: typeof eff.version === "number" ? eff.version : 0, ...("limits" in eff ? { limits: eff.limits } : {}) }, logger);
|
|
391
376
|
const hot = stageRuntimeHot(config, eff.governance, logger);
|
|
@@ -598,7 +583,7 @@ export function logEffectiveDiff(config, eff, logger) {
|
|
|
598
583
|
currentDefaultModel: config.model.id,
|
|
599
584
|
models: { center: centerModels, envDerived: envModels },
|
|
600
585
|
roles: { center: centerRoles, current: config.roles },
|
|
601
|
-
collab: {
|
|
586
|
+
collab: { notExecuted: collabTemplatesNotExecuted(eff) },
|
|
602
587
|
skills: { centerWouldLoad: (eff.skills?.skills ?? []).filter((s) => s.enabled !== false).map((s) => s.name) },
|
|
603
588
|
mcp: { centerWouldRegister: (eff.mcp?.servers ?? []).filter((s) => s.enabled !== false).map((s) => s.name) },
|
|
604
589
|
limits: {
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
* · `approvalGate` —— S-668 波 2 审批组(`governance.approvalRequire`;属主 `apply-effective.ts` 的
|
|
27
27
|
* `stageApprovalGate`:坏形 / 工具名匹配不到 / ④ 门意图不可服务 ⇒ 整组拒)。
|
|
28
28
|
* · `modelPlane` —— 模型面组(组内有哪些 effective 域的**唯一定义** = `apply-effective.ts` 的 `MODEL_PLANE_DOMAINS`:models 域 =
|
|
29
|
-
* 目录 / roles / tiers / 拒因表 / 名单 /
|
|
29
|
+
* 目录 / roles / tiers / 拒因表 / 名单 / 钥匙表(今天组内只此一域);属主 `stageModelPlane`:
|
|
30
30
|
* 模型面三条跨键不变量 `default-model-resolvable` / `model-route-endpoint` / `refused-names-not-minted` 任一不成立 ⇒ 整组拒,
|
|
31
31
|
* 组内各域都停在上一代。opus 腿 O3(7.101.0 合并复审):此前这三条是 stage 抛 = 整份候选中止,同候选其余组陪葬)。
|
|
32
32
|
* 各组同姿势、各用各的判据表(审批组**不**复用限额组的跨键不变量表 —— 那张表的候选视图只叠限额键)。
|
|
@@ -110,7 +110,7 @@ export declare function refusedGroups(report: ConfigApplyReport): Array<{
|
|
|
110
110
|
readonly reason: string;
|
|
111
111
|
}>;
|
|
112
112
|
/**
|
|
113
|
-
* O3:这一次 apply 的**模型面组**(组内各域 = `MODEL_PLANE_DOMAINS
|
|
113
|
+
* O3:这一次 apply 的**模型面组**(组内各域 = `MODEL_PLANE_DOMAINS`)落地了没有(整组被拒 ⇒
|
|
114
114
|
* false;报告缺席 = 没走到 commit ⇒ false,如实)。调用方据此决定「Runner 现在跑的是哪一代模型面」(`appliedPlaneEff`,swap 判据的
|
|
115
115
|
* 基准)、名册门开不开、以及 boot 要不要按组回落 LKG —— 都只许从真落地的模型面推进。
|
|
116
116
|
*/
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 配置候选的**唯一判官**:一份候选(中心有效视图,或本地 `config.d` 读出的那份)能不能收 —— 只有这一种判法。
|
|
3
3
|
*
|
|
4
|
-
* 判据(
|
|
5
|
-
* (`validatePromptsDomain`;坏形的 pack 会让 core 在每个任务的装配期抛)
|
|
4
|
+
* 判据(三件,任一即拒;每条拒因带成因词,闭集 {@link CandidateRejectReason}):读腿交出的 `domainErrors`(某个域读不懂 / 拼错键 / 坏文件:那个域已落
|
|
5
|
+
* schema 缺省)与 prompts 面的判形(`validatePromptsDomain`;坏形的 pack 会让 core 在每个任务的装配期抛)—— 成因 `domain_invalid`;读腿交出的
|
|
6
|
+
* `retiredDomains`(带事实的退役域文档,契约包的墓碑;拒句点名退役版本与一次性迁移)—— 成因 `retired_domain`。任一 ⇒ `rejected`:
|
|
7
|
+
* **整份候选不收**,一个域都不应用。退役域此前在读腿整包抛、走「源不可达」那条臂(版本读不到、没有拒判行、刷新拍算失败);现在读腿只交数据,
|
|
8
|
+
* 坏候选只有本判官一种判法。
|
|
6
9
|
* 读腿的逐条丢弃(`droppedEntries`)不在这里 —— 颗粒是条目的失效留在条目上,候选照收(调用方响亮点名)。
|
|
7
10
|
*
|
|
8
11
|
* 调用面(全部只调这一只,不内联第二份):
|
|
@@ -30,10 +33,17 @@ export interface CandidateDomainError {
|
|
|
30
33
|
readonly domain: string;
|
|
31
34
|
readonly error: string;
|
|
32
35
|
}
|
|
33
|
-
/**
|
|
36
|
+
/** 判官拒一份候选的成因(闭集):某个域判形失败(含 prompts 面)/ 带事实的退役域文档(墓碑)。 */
|
|
37
|
+
export type CandidateRejectReason = "domain_invalid" | "retired_domain";
|
|
38
|
+
/** 拒判里的一条:哪一域、为什么(读腿 / 契约包的原句)、成因词。`config_candidate_rejected` 行的 `errors` 就是这一列。 */
|
|
39
|
+
export interface CandidateDomainRejection extends CandidateDomainError {
|
|
40
|
+
readonly reason: CandidateRejectReason;
|
|
41
|
+
}
|
|
42
|
+
/** 判官的输入:一份读出来的候选。`retiredDomains` = 读腿交出的退役域发现(两条读腿同形,见 `read-warnings.ts` 的 `RetiredDomainFinding`)。 */
|
|
34
43
|
export interface ConfigCandidateRead {
|
|
35
44
|
readonly effective: EffectiveConfig;
|
|
36
45
|
readonly domainErrors?: readonly CandidateDomainError[];
|
|
46
|
+
readonly retiredDomains?: readonly CandidateDomainError[];
|
|
37
47
|
}
|
|
38
48
|
export type ConfigCandidateVerdict =
|
|
39
49
|
/** `prompts` = 候选 prompts 面的已判形值(候选不带 prompts 键 ⇒ `undefined` = 撤回中心包、内置提示词服务)。 */
|
|
@@ -43,7 +53,7 @@ export type ConfigCandidateVerdict =
|
|
|
43
53
|
} | {
|
|
44
54
|
readonly verdict: "rejected";
|
|
45
55
|
readonly domains: readonly string[];
|
|
46
|
-
readonly errors: readonly
|
|
56
|
+
readonly errors: readonly CandidateDomainRejection[];
|
|
47
57
|
};
|
|
48
58
|
export declare function judgeConfigCandidate(r: ConfigCandidateRead): ConfigCandidateVerdict;
|
|
49
59
|
/** `config_candidate_rejected` 的 `leg`(闭集):被判官整拒的候选是**哪一拉**的 —— 起服那一拉 / 起服超窗、到货才判的那一拉 / 刷新拍的一拉 /
|
|
@@ -64,6 +74,31 @@ export declare function buildCandidateRejectedFields(r: {
|
|
|
64
74
|
readonly lkgVersion: number | "(env)";
|
|
65
75
|
readonly dir?: string;
|
|
66
76
|
}): Record<string, unknown>;
|
|
77
|
+
/**
|
|
78
|
+
* 最近一次被判官整拒的候选的**结论**(纯数据)—— 判官判决的持有形:`domains` 就是 {@link judgeConfigCandidate} 交出的 `rejected.domains`(排序去重的域名集),
|
|
79
|
+
* 一个字没改写;`source` = 这份候选是哪种配置源读出来的(`"local"` 本地 `config.d` / `"remote"` 中心);`at` = 判官判下这份候选的时刻(毫秒)。
|
|
80
|
+
* 持有者(`boot/web-admin.ts` 的 `candidateRejection`)是它的**唯一**座:`config_candidate_rejected` 日志行的去重键与 `GET /v1/models.candidateRejected`
|
|
81
|
+
* 的投影({@link buildCandidateRejectedWire})读的是同一份 —— 拒因文案(`errors`)与文件路径(`dir`)只走日志,不进这份结论,也就不上 wire。
|
|
82
|
+
*/
|
|
83
|
+
export interface CandidateRejection {
|
|
84
|
+
readonly version: number;
|
|
85
|
+
readonly domains: readonly string[];
|
|
86
|
+
readonly source: "local" | "remote";
|
|
87
|
+
readonly at: number;
|
|
88
|
+
}
|
|
89
|
+
export declare function candidateRejectionOf(r: {
|
|
90
|
+
readonly effective: EffectiveConfig;
|
|
91
|
+
}, verdict: Extract<ConfigCandidateVerdict, {
|
|
92
|
+
verdict: "rejected";
|
|
93
|
+
}>, source: CandidateRejection["source"], at: number): CandidateRejection;
|
|
94
|
+
/** `GET /v1/models` 顶层 `candidateRejected` 的 wire 形(契约 §A.1d「`GET /v1/models` 的 `candidateRejected`」):域名闭集词 + ISO 时刻 + 源形态,零自由文本。 */
|
|
95
|
+
export interface CandidateRejectedWire {
|
|
96
|
+
readonly domains: string[];
|
|
97
|
+
readonly at: string;
|
|
98
|
+
readonly source: "local" | "remote";
|
|
99
|
+
}
|
|
100
|
+
/** {@link CandidateRejection} → wire:**唯一**出口投影(纯函数;present-iff 由调用方——座里有结论才调——保证)。 */
|
|
101
|
+
export declare function buildCandidateRejectedWire(rejection: CandidateRejection): CandidateRejectedWire;
|
|
67
102
|
/** `config_domain_invalid` 逐域坐标行的 note(各入口同一句):这一行说「哪一域、为什么坏」,判决只有 `config_candidate_rejected` 一行。 */
|
|
68
103
|
export declare const CONFIG_DOMAIN_INVALID_NOTE = "this domain failed its schema \u2014 the candidate judge rejects the whole candidate (see config_candidate_rejected); fix the named file / center data";
|
|
69
104
|
//# sourceMappingURL=candidate-gate.d.ts.map
|
|
@@ -3,8 +3,9 @@ export function judgeConfigCandidate(r) {
|
|
|
3
3
|
const prompts = r.effective.prompts;
|
|
4
4
|
const promptsGate = prompts === undefined ? undefined : validatePromptsDomain(prompts);
|
|
5
5
|
const errors = [
|
|
6
|
-
...(r.domainErrors ?? []).map((de) => ({ domain: de.domain, error: de.error })),
|
|
7
|
-
...(promptsGate !== undefined && !promptsGate.ok ? [{ domain: "prompts", error: promptsGate.error }] : []),
|
|
6
|
+
...(r.domainErrors ?? []).map((de) => ({ domain: de.domain, error: de.error, reason: "domain_invalid" })),
|
|
7
|
+
...(promptsGate !== undefined && !promptsGate.ok ? [{ domain: "prompts", error: promptsGate.error, reason: "domain_invalid" }] : []),
|
|
8
|
+
...(r.retiredDomains ?? []).map((rd) => ({ domain: rd.domain, error: rd.error, reason: "retired_domain" })),
|
|
8
9
|
];
|
|
9
10
|
if (errors.length === 0)
|
|
10
11
|
return { verdict: "clean", prompts: promptsGate?.ok ? promptsGate.value : undefined };
|
|
@@ -23,5 +24,11 @@ export function buildCandidateRejectedFields(r, verdict, leg, ctx) {
|
|
|
23
24
|
note: "candidate rejected whole (§9.5-5) — live config keeps the last-known-good; fix the named files to unblock",
|
|
24
25
|
};
|
|
25
26
|
}
|
|
27
|
+
export function candidateRejectionOf(r, verdict, source, at) {
|
|
28
|
+
return { version: r.effective.version, domains: verdict.domains, source, at };
|
|
29
|
+
}
|
|
30
|
+
export function buildCandidateRejectedWire(rejection) {
|
|
31
|
+
return { domains: [...rejection.domains], at: new Date(rejection.at).toISOString(), source: rejection.source };
|
|
32
|
+
}
|
|
26
33
|
export const CONFIG_DOMAIN_INVALID_NOTE = "this domain failed its schema — the candidate judge rejects the whole candidate (see config_candidate_rejected); fix the named file / center data";
|
|
27
34
|
//# sourceMappingURL=candidate-gate.js.map
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
* this note listed "planned sema-admin" as the next step). The module itself keeps a neutral, product-name-free
|
|
9
9
|
* identifier ("web-admin") and does not chase the rename.)
|
|
10
10
|
*
|
|
11
|
-
* - the CENTER owns the LOGICAL config: the model roster (names/capabilities/tier)
|
|
12
|
-
*
|
|
11
|
+
* - the CENTER owns the LOGICAL config: the model roster (names/capabilities/tier) and the role map
|
|
12
|
+
* (its collab templates are reported as not executed — this server runs no team orchestration);
|
|
13
13
|
* - the SERVICE env still owns the SECRETS: API keys stay in env (the center never stores a secret);
|
|
14
14
|
* keys are per-model via `apiKeyEnv` → `config.modelApiKeyEnv` → the spec's `getApiKeyAndHeaders`
|
|
15
15
|
* (core 1.45), so each model/cascade-rung authenticates with its own upstream key.
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { type EffectiveReadWarning, type EntitlementRuntimeCaps } from "@sema-agent/settings-schema";
|
|
2
2
|
import type { ScenarioRuling } from "../capabilities/scenarios.js";
|
|
3
3
|
import type { EffectiveConfig, ExecutionRuling } from "./types.js";
|
|
4
|
-
import { type DroppedConfigEntry, type UnreadConfigFile } from "./read-warnings.js";
|
|
4
|
+
import { type DroppedConfigEntry, type RetiredDomainFinding, type UnreadConfigFile } from "./read-warnings.js";
|
|
5
5
|
import { type CenterEndpoint } from "./center-request.js";
|
|
6
6
|
/** GET the effective config (Bearer + ETag). null = 304 (unchanged). Throws on transport/HTTP error, and on a
|
|
7
7
|
* payload that is not an effective config at all(非对象 / version 非有限数 / gate 域坏形——[ref] 裁B)。
|
|
8
|
+
* `retiredDomains`(S-1456):wire 上带事实的退役域(墓碑)不抛 —— 交成发现、那一键不进 effective,候选判官整拒这份候选(与本地腿同键同义)。
|
|
8
9
|
* `domainErrors`:坏 catalog 域(schema default 已落)逐域单列——与本地腿 `FetchEffectiveResult` 同键同义,
|
|
9
10
|
* boot/refresh 的候选门直接消费。`droppedEntries`(S-704 ②):schema 逐条丢掉的条目(坐标 + 字段诊断)——
|
|
10
11
|
* **不**进候选门,调用方响亮点名、其余照用(分面单点 `splitFoldedReadWarnings`,与本地腿同一只)。
|
|
@@ -24,6 +25,7 @@ export declare function fetchEffective(center: CenterEndpoint, etag: string | un
|
|
|
24
25
|
}>;
|
|
25
26
|
droppedEntries?: DroppedConfigEntry[];
|
|
26
27
|
unreadFiles?: UnreadConfigFile[];
|
|
28
|
+
retiredDomains?: RetiredDomainFinding[];
|
|
27
29
|
readWarnings: readonly EffectiveReadWarning[];
|
|
28
30
|
credentialIdentity: string;
|
|
29
31
|
} | null>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { readEffectiveWire, PrincipalCapsWire } from "@sema-agent/settings-schema";
|
|
3
3
|
import { centerPromptsFromEffective } from "../prompts-domain-validate.js";
|
|
4
|
-
import { splitFoldedReadWarnings, withDroppedCatalogEntries } from "./read-warnings.js";
|
|
4
|
+
import { separateRetiredDomains, splitFoldedReadWarnings, withDroppedCatalogEntries } from "./read-warnings.js";
|
|
5
5
|
import { CENTER_PULL_TIMEOUT_MS, centerFetch } from "./center-request.js";
|
|
6
6
|
import { answerStillCurrent } from "../center-credential.js";
|
|
7
7
|
export async function fetchEffective(center, etag, fetchImpl = fetch, worker) {
|
|
@@ -11,14 +11,14 @@ export async function fetchEffective(center, etag, fetchImpl = fetch, worker) {
|
|
|
11
11
|
if (!res.ok)
|
|
12
12
|
throw new Error(`web-admin HTTP ${res.status}`);
|
|
13
13
|
const warnings = [];
|
|
14
|
-
const body = await res.json();
|
|
14
|
+
const { body, retiredDomains } = separateRetiredDomains(await res.json());
|
|
15
15
|
const wire = readEffectiveWire(body, (w) => warnings.push(w));
|
|
16
16
|
const centerPrompts = centerPromptsFromEffective(wire);
|
|
17
17
|
if (centerPrompts === undefined)
|
|
18
18
|
delete wire.prompts;
|
|
19
19
|
else
|
|
20
20
|
wire.prompts = centerPrompts;
|
|
21
|
-
const { domainErrors, droppedEntries, droppedCatalogEntries, unreadFiles } = splitFoldedReadWarnings(warnings);
|
|
21
|
+
const { domainErrors, droppedEntries, droppedCatalogEntries, unreadFiles } = splitFoldedReadWarnings(warnings, "center");
|
|
22
22
|
const effective = withDroppedCatalogEntries(wire, droppedCatalogEntries);
|
|
23
23
|
return {
|
|
24
24
|
effective,
|
|
@@ -28,6 +28,7 @@ export async function fetchEffective(center, etag, fetchImpl = fetch, worker) {
|
|
|
28
28
|
...(domainErrors.length > 0 ? { domainErrors } : {}),
|
|
29
29
|
...(droppedEntries.length > 0 ? { droppedEntries } : {}),
|
|
30
30
|
...(unreadFiles.length > 0 ? { unreadFiles } : {}),
|
|
31
|
+
...(retiredDomains.length > 0 ? { retiredDomains: [...retiredDomains] } : {}),
|
|
31
32
|
};
|
|
32
33
|
}
|
|
33
34
|
export async function fetchPrincipalCaps(center, principal, etag, fetchImpl = fetch, worker) {
|
|
@@ -25,7 +25,30 @@
|
|
|
25
25
|
* 留在条目上,只有颗粒更粗的失效才动候选。
|
|
26
26
|
*/
|
|
27
27
|
import { z } from "zod";
|
|
28
|
-
import { type DroppedEntryIdentity, type DroppedEntryReasonCode, type EffectiveReadWarning } from "@sema-agent/settings-schema";
|
|
28
|
+
import { type DroppedEntryIdentity, type DroppedEntryReasonCode, type EffectiveReadWarning, type RetiredDomainName } from "@sema-agent/settings-schema";
|
|
29
|
+
/**
|
|
30
|
+
* 退役域的一条**发现**(两条读腿同形)。读腿只把契约包的墓碑(`RetiredDomainError`)换成数据交出去 —— 判决只在候选判官
|
|
31
|
+
* (`candidate-gate.ts` 的 `judgeConfigCandidate`,成因 `retired_domain`):与域判形失败同一条回落链(候选 → 盘上 LKG → env)、同一行
|
|
32
|
+
* `config_candidate_rejected`、刷新拍同形(拍跑完,候选被判拒是结论)。拉取层的抛只剩 I/O 与载荷形(不是一份 effective)两种。
|
|
33
|
+
* `error` = 契约包铸的整句(墓碑表那一行:退役版本、事实今天住哪、一次性迁移 id)—— 模板句,不含任何配置值,所以不过 `redactConfigError`
|
|
34
|
+
* (那道脱敏把引号段换成指纹,会把句中点名的域名换掉)。
|
|
35
|
+
*/
|
|
36
|
+
export type RetiredDomainFinding = {
|
|
37
|
+
readonly domain: RetiredDomainName;
|
|
38
|
+
readonly error: string;
|
|
39
|
+
readonly migration: string;
|
|
40
|
+
};
|
|
41
|
+
/** 墓碑 → 发现;不是墓碑 ⇒ `undefined`(调用方照原样抛)。两条读腿的唯一换装点。 */
|
|
42
|
+
export declare function retiredDomainFindingOf(e: unknown): RetiredDomainFinding | undefined;
|
|
43
|
+
/**
|
|
44
|
+
* 远端读腿在过契约读腿(`readEffectiveWire`)**之前**把退役域键分出去:wire 体上每个退役域键过契约的同一只墓碑(`refuseRetiredDomain`)——
|
|
45
|
+
* 带事实 ⇒ 一条发现、这一键从体上拿掉(其余域照读、版本照读,判官整拒这份候选);缺席 / `{}` ⇒ 不理会(契约读腿自己丢 `{}`)。
|
|
46
|
+
* 体不是对象 ⇒ 原样交回、不判(载荷形错,契约读腿抛)。墓碑判据只在契约包,这里只分键。
|
|
47
|
+
*/
|
|
48
|
+
export declare function separateRetiredDomains(body: unknown): {
|
|
49
|
+
readonly body: unknown;
|
|
50
|
+
readonly retiredDomains: readonly RetiredDomainFinding[];
|
|
51
|
+
};
|
|
29
52
|
/** 折叠产物:`scope` 决定消费方做什么 —— `"domain"` 进候选门(`domainErrors`),`"entry"` 进逐条丢弃面(`droppedEntries`),
|
|
30
53
|
* `"unread"` 进读腿不读的文件面(`unreadFiles`;点名不判拒)。 */
|
|
31
54
|
export type FoldedReadWarning = {
|
|
@@ -79,18 +102,23 @@ export declare const SCHEMA_OPERAND_HOLE = "\u00ABvalue\u00BB";
|
|
|
79
102
|
* 引号到最后一个引号整段吞掉,契约拒句里点名的迁移 id(「旧形读写两面响亮拒、拒句点名迁移 id」)就到不了运维眼前。
|
|
80
103
|
*/
|
|
81
104
|
export declare function describeDomainIssues(error: unknown): string;
|
|
105
|
+
/**
|
|
106
|
+
* 读告警来自哪条读腿:`center` = 配置中心(web-admin)下发的有效配置(`http-client.ts`);`local` = 本副本自己的 `config.d` / LKG
|
|
107
|
+
* (`config-provider.ts`)。只有一处读它:**角色词**被丢时的出路句(见 {@link centerRoleWordSentence})。
|
|
108
|
+
*/
|
|
109
|
+
export type ReadWarningLeg = "center" | "local";
|
|
82
110
|
/** 一条读告警 → 它的诊断面(每一种都进:见文件头「归族判据」)。按 kind 的重载只是让调用方拿到窄型(`unread` 一面没有 `error` 句)。 */
|
|
83
111
|
export declare function foldEffectiveReadWarning(w: Extract<EffectiveReadWarning, {
|
|
84
112
|
kind: "unread-config-file";
|
|
85
|
-
}
|
|
113
|
+
}>, leg: ReadWarningLeg): Extract<FoldedReadWarning, {
|
|
86
114
|
scope: "unread";
|
|
87
115
|
}>;
|
|
88
116
|
export declare function foldEffectiveReadWarning(w: Exclude<EffectiveReadWarning, {
|
|
89
117
|
kind: "unread-config-file";
|
|
90
|
-
}
|
|
118
|
+
}>, leg: ReadWarningLeg): Exclude<FoldedReadWarning, {
|
|
91
119
|
scope: "unread";
|
|
92
120
|
}>;
|
|
93
|
-
export declare function foldEffectiveReadWarning(w: EffectiveReadWarning): FoldedReadWarning;
|
|
121
|
+
export declare function foldEffectiveReadWarning(w: EffectiveReadWarning, leg: ReadWarningLeg): FoldedReadWarning;
|
|
94
122
|
/**
|
|
95
123
|
* 🔴 S-712 / S-1295 —— **被丢目录条目的载体行**(载体 = `EffectiveConfig.models.droppedCatalogEntries`,读腿铸,随 effective 走 —— 盘上 LKG
|
|
96
124
|
* 从同一个对象落盘,重启从 LKG 起服时它还在)。形的**唯一定义**(型由它推出;判据按它判盘上来的行)。
|
|
@@ -130,7 +158,7 @@ export type DroppedCatalogEntry = z.infer<typeof DroppedCatalogEntryRow>;
|
|
|
130
158
|
* (键名坐标 + 类型词 + 契约整句,值位是洞)、不含配置里的值,只过 `redactSecrets`(契约句的固定词里有引号 / 撇号,引号段读法会把迁移指路整段吞掉)。
|
|
131
159
|
* 坏行本身照样走 `droppedEntries`(坐标 + 字段 + 词,不带值)。
|
|
132
160
|
*/
|
|
133
|
-
export declare function splitFoldedReadWarnings(warnings: readonly EffectiveReadWarning[]): {
|
|
161
|
+
export declare function splitFoldedReadWarnings(warnings: readonly EffectiveReadWarning[], leg: ReadWarningLeg): {
|
|
134
162
|
domainErrors: Array<{
|
|
135
163
|
domain: string;
|
|
136
164
|
error: string;
|
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { DROPPED_ENTRY_REASON_CODES, formatConfigPath, isDisclosableIdentity, renderQuotedSentence, } from "@sema-agent/settings-schema";
|
|
2
|
+
import { DROPPED_ENTRY_REASON_CODES, ModelRole, RETIRED_DOMAINS, RetiredDomainError, formatConfigPath, isDisclosableIdentity, isRetiredDomainName, refuseRetiredDomain, renderQuotedSentence, } from "@sema-agent/settings-schema";
|
|
3
|
+
export function retiredDomainFindingOf(e) {
|
|
4
|
+
return e instanceof RetiredDomainError ? { domain: e.domain, error: e.message, migration: e.migration } : undefined;
|
|
5
|
+
}
|
|
6
|
+
export function separateRetiredDomains(body) {
|
|
7
|
+
if (body === null || typeof body !== "object" || Array.isArray(body))
|
|
8
|
+
return { body, retiredDomains: [] };
|
|
9
|
+
const findings = [];
|
|
10
|
+
const rest = { ...body };
|
|
11
|
+
for (const domain of Object.keys(RETIRED_DOMAINS).filter(isRetiredDomainName)) {
|
|
12
|
+
try {
|
|
13
|
+
refuseRetiredDomain(domain, rest[domain]);
|
|
14
|
+
}
|
|
15
|
+
catch (e) {
|
|
16
|
+
const finding = retiredDomainFindingOf(e);
|
|
17
|
+
if (finding === undefined)
|
|
18
|
+
throw e;
|
|
19
|
+
findings.push(finding);
|
|
20
|
+
delete rest[domain];
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return findings.length === 0 ? { body, retiredDomains: [] } : { body: rest, retiredDomains: findings };
|
|
24
|
+
}
|
|
3
25
|
export function buildUnreadConfigFileFields(f, dir) {
|
|
4
26
|
return {
|
|
5
27
|
...(dir !== undefined ? { dir } : {}),
|
|
@@ -77,12 +99,25 @@ const keyList = (prefix, keys, truncatedFrom) => {
|
|
|
77
99
|
}
|
|
78
100
|
return `${prefix}${shown.join(", ")}${suffixFor(shown.length)}`;
|
|
79
101
|
};
|
|
80
|
-
|
|
102
|
+
function droppedRoleWordOf(w) {
|
|
103
|
+
const p = w.path;
|
|
104
|
+
const word = p[p.length - 1];
|
|
105
|
+
return p.length >= 2 && p[p.length - 2] === "roles" && typeof word === "string" && !ModelRole.options.includes(word) ? word : undefined;
|
|
106
|
+
}
|
|
107
|
+
function centerRoleWordSentence(word) {
|
|
108
|
+
return (`role word ${JSON.stringify(word.slice(0, 40))} published by the configuration center is not one of ${ModelRole.options.join(" / ")} ` +
|
|
109
|
+
`(settings-schema 12 / core 7.49.0 removed team / synthesize) — the center is on an older settings-schema: upgrade web-admin to settings-schema 12 ` +
|
|
110
|
+
`(its store migrates on upgrade); this server binds nothing to that role`);
|
|
111
|
+
}
|
|
112
|
+
export function foldEffectiveReadWarning(w, leg) {
|
|
81
113
|
switch (w.kind) {
|
|
82
114
|
case "domain-defaulted":
|
|
83
115
|
return { scope: "domain", domain: w.domain, error: cap(describeDomainIssues(w.error)) };
|
|
84
|
-
case "entry-dropped":
|
|
85
|
-
|
|
116
|
+
case "entry-dropped": {
|
|
117
|
+
const roleWord = leg === "center" ? droppedRoleWordOf(w) : undefined;
|
|
118
|
+
const error = roleWord !== undefined ? centerRoleWordSentence(roleWord) : `entry dropped by domain schema: ${describeSchemaIssues(w.error) ?? errorText(w.error)}`;
|
|
119
|
+
return { scope: "entry", domain: w.domain, entry: formatConfigPath(w.path), error: cap(error), reasonCode: droppedReasonCodeOf(w) };
|
|
120
|
+
}
|
|
86
121
|
case "unknown-keys-dropped":
|
|
87
122
|
return { scope: "domain", domain: w.domain, error: keyList("unknown keys dropped by domain schema: ", w.keys, w.truncatedFrom) };
|
|
88
123
|
case "unknown-keys-carried":
|
|
@@ -119,13 +154,13 @@ function identityOf(i) {
|
|
|
119
154
|
const out = { ...(i.name !== undefined ? { name: i.name } : {}), ...(i.id !== undefined ? { id: i.id } : {}), ...(i.enabled !== undefined ? { enabled: i.enabled } : {}) };
|
|
120
155
|
return Object.keys(out).length > 0 ? out : undefined;
|
|
121
156
|
}
|
|
122
|
-
export function splitFoldedReadWarnings(warnings) {
|
|
157
|
+
export function splitFoldedReadWarnings(warnings, leg) {
|
|
123
158
|
const domainErrors = [];
|
|
124
159
|
const droppedEntries = [];
|
|
125
160
|
const droppedCatalogEntries = [];
|
|
126
161
|
const unreadFiles = [];
|
|
127
162
|
for (const w of warnings) {
|
|
128
|
-
const f = foldEffectiveReadWarning(w);
|
|
163
|
+
const f = foldEffectiveReadWarning(w, leg);
|
|
129
164
|
switch (f.scope) {
|
|
130
165
|
case "domain":
|
|
131
166
|
domainErrors.push({ domain: f.domain, error: f.error });
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
* internal-lossless: the facade re-exports every symbol below unchanged).
|
|
7
7
|
*/
|
|
8
8
|
import type { ToolContentOrigin } from "@sema-agent/core";
|
|
9
|
-
import type { CollabTemplateWire } from "../capabilities/collab-wire.js";
|
|
10
9
|
import type { Autonomy, CommandRule } from "../runtime-governance.js";
|
|
11
10
|
import type { DroppedCatalogEntry } from "./read-warnings.js";
|
|
12
11
|
export interface CenterModel {
|
|
@@ -280,11 +279,18 @@ export interface EffectiveConfig {
|
|
|
280
279
|
* 挂在 effective 上(而不是读结果旁边)是为了**随 effective 落 LKG**:重启从 LKG 起服时它还在。盘上形不对 ⇒ 模型面整组拒。 */
|
|
281
280
|
droppedCatalogEntries?: DroppedCatalogEntry[];
|
|
282
281
|
};
|
|
283
|
-
/**
|
|
284
|
-
*
|
|
285
|
-
*
|
|
282
|
+
/** The center's collab domain (multi-member discussion templates). **Nothing on this server executes it**: the
|
|
283
|
+
* only executor was the engine's team-discussion script, which core 7.49.0 removed. The server reads exactly one
|
|
284
|
+
* fact from it — which enabled template ids were published — and reports them as not executed
|
|
285
|
+
* (`collabTemplatesNotExecuted`, one warn per apply; the dry-run line reads the same list). Both lanes carry the
|
|
286
|
+
* domain (remote /effective ships it; local FileConfigStore reads config.d/collab.json), so the warn fires on both. The template's
|
|
287
|
+
* other members (slots / rounds / finalizer …, settings-schema's shape) ride through unread — hence the open index. */
|
|
286
288
|
collab?: {
|
|
287
|
-
templates:
|
|
289
|
+
templates: ReadonlyArray<{
|
|
290
|
+
readonly id: string;
|
|
291
|
+
readonly enabled?: boolean;
|
|
292
|
+
readonly [member: string]: unknown;
|
|
293
|
+
}>;
|
|
288
294
|
};
|
|
289
295
|
skills?: {
|
|
290
296
|
skills: CenterSkillManifest[];
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/** `WORKSPACE_CACHE` closed set. `volume` = one cache volume per space; `off` = no volume (the pod as before). */
|
|
2
|
+
export declare const WORKSPACE_CACHE_WORDS: readonly ["volume", "off"];
|
|
3
|
+
export type WorkspaceCacheWord = (typeof WORKSPACE_CACHE_WORDS)[number];
|
|
4
|
+
export declare const WORKSPACE_CACHE_DEFAULT: WorkspaceCacheWord;
|
|
5
|
+
/** `WORKSPACE_CACHE_SIZE` default (a k8s quantity; the claim's requested storage). */
|
|
6
|
+
export declare const WORKSPACE_CACHE_SIZE_DEFAULT = "20Gi";
|
|
7
|
+
/** `WORKSPACE_CACHE_MOUNT` default (an absolute path outside the workspace mount). */
|
|
8
|
+
export declare const WORKSPACE_CACHE_MOUNT_DEFAULT = "/cache";
|
|
9
|
+
/** The label key every cache claim carries (value = the space's 20-hex digest) — the one handle a cleanup selects by. */
|
|
10
|
+
export declare const WORKSPACE_CACHE_SPACE_LABEL = "sema.space";
|
|
11
|
+
/** The effective cache policy — the `workspaceCache` fact's witness and the value of `GET /v1/capabilities.workspaceSync.cache`. */
|
|
12
|
+
export interface WorkspaceCacheCapability {
|
|
13
|
+
mount: string;
|
|
14
|
+
size: string;
|
|
15
|
+
}
|
|
16
|
+
/** A k8s resource quantity as a claim size: a positive decimal with an optional binary (`Ki`…`Ei`) or decimal (`k`…`E`) suffix. */
|
|
17
|
+
export declare function isK8sQuantity(v: string): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* The cache env CLOSED table — one row per tool, the value its cache directory under the mount. Injected only when this
|
|
20
|
+
* run's pod really carries the volume; an explicit operator value of the same name wins (the pod env merge seat).
|
|
21
|
+
* Rust is not covered: Cargo has no download-cache-only env — `CARGO_HOME` is its whole home (the rust band bakes its
|
|
22
|
+
* toolchain proxies and the registry mirror `config.toml` there), so pointing it at the volume would lose both.
|
|
23
|
+
*/
|
|
24
|
+
declare const CACHE_ENV_ROWS: {
|
|
25
|
+
readonly GRADLE_USER_HOME: (mount: string) => string;
|
|
26
|
+
readonly MAVEN_OPTS: (mount: string) => string;
|
|
27
|
+
readonly npm_config_cache: (mount: string) => string;
|
|
28
|
+
readonly PIP_CACHE_DIR: (mount: string) => string;
|
|
29
|
+
readonly UV_CACHE_DIR: (mount: string) => string;
|
|
30
|
+
readonly GOMODCACHE: (mount: string) => string;
|
|
31
|
+
};
|
|
32
|
+
export type WorkspaceCacheEnvName = keyof typeof CACHE_ENV_ROWS;
|
|
33
|
+
export declare const WORKSPACE_CACHE_ENV_NAMES: readonly WorkspaceCacheEnvName[];
|
|
34
|
+
/** The cache env for a volume mounted at `mount` (every row of the closed table). */
|
|
35
|
+
export declare function workspaceCacheEnv(mount: string): Record<WorkspaceCacheEnvName, string>;
|
|
36
|
+
/** The space's cache claim — the ONE place its name and label are spelled. `spaceKey` = the space partition (the occupant's
|
|
37
|
+
* incarnation); only a one-way 20-hex digest of it reaches the cluster (a claim name / label is visible to cluster operators). */
|
|
38
|
+
export declare function workspaceCacheClaimOf(spaceKey: string): {
|
|
39
|
+
name: string;
|
|
40
|
+
label: string;
|
|
41
|
+
};
|
|
42
|
+
/** Does the cache mount overlap the workspace mount (equal, or one inside the other)? Both are absolute, normalized paths. */
|
|
43
|
+
export declare function mountsOverlap(a: string, b: string): boolean;
|
|
44
|
+
export {};
|
|
45
|
+
//# sourceMappingURL=workspace-cache.d.ts.map
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
export const WORKSPACE_CACHE_WORDS = ["volume", "off"];
|
|
3
|
+
export const WORKSPACE_CACHE_DEFAULT = "off";
|
|
4
|
+
export const WORKSPACE_CACHE_SIZE_DEFAULT = "20Gi";
|
|
5
|
+
export const WORKSPACE_CACHE_MOUNT_DEFAULT = "/cache";
|
|
6
|
+
export const WORKSPACE_CACHE_SPACE_LABEL = "sema.space";
|
|
7
|
+
export function isK8sQuantity(v) {
|
|
8
|
+
return /^(?=.*[1-9])[0-9]+(\.[0-9]+)?(Ki|Mi|Gi|Ti|Pi|Ei|k|M|G|T|P|E)?$/.test(v);
|
|
9
|
+
}
|
|
10
|
+
const CACHE_ENV_ROWS = {
|
|
11
|
+
GRADLE_USER_HOME: (mount) => `${mount}/gradle`,
|
|
12
|
+
MAVEN_OPTS: (mount) => `-Dmaven.repo.local=${mount}/m2`,
|
|
13
|
+
npm_config_cache: (mount) => `${mount}/npm`,
|
|
14
|
+
PIP_CACHE_DIR: (mount) => `${mount}/pip`,
|
|
15
|
+
UV_CACHE_DIR: (mount) => `${mount}/uv`,
|
|
16
|
+
GOMODCACHE: (mount) => `${mount}/go`,
|
|
17
|
+
};
|
|
18
|
+
export const WORKSPACE_CACHE_ENV_NAMES = Object.keys(CACHE_ENV_ROWS);
|
|
19
|
+
export function workspaceCacheEnv(mount) {
|
|
20
|
+
return Object.fromEntries(WORKSPACE_CACHE_ENV_NAMES.map((name) => [name, CACHE_ENV_ROWS[name](mount)]));
|
|
21
|
+
}
|
|
22
|
+
export function workspaceCacheClaimOf(spaceKey) {
|
|
23
|
+
const digest = createHash("sha256").update(spaceKey).digest("hex").slice(0, 20);
|
|
24
|
+
return { name: `ws-cache-${digest}`, label: digest };
|
|
25
|
+
}
|
|
26
|
+
export function mountsOverlap(a, b) {
|
|
27
|
+
const inside = (x, y) => x === y || x.startsWith(y.endsWith("/") ? y : `${y}/`);
|
|
28
|
+
return inside(a, b) || inside(b, a);
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=workspace-cache.js.map
|