@sema-agent/server 7.122.0 → 7.124.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 +209 -0
- package/README.md +7 -2
- package/README.zh-CN.md +5 -2
- package/USAGE.md +76 -56
- package/dist/approval-ask-audit-store.d.ts +27 -32
- package/dist/approval-ask-audit-store.js +10 -9
- package/dist/approval-crash-convergence.d.ts +2 -2
- package/dist/approval-crash-convergence.js +5 -5
- package/dist/approval-deny-reasons.d.ts +163 -51
- package/dist/approval-deny-reasons.js +79 -8
- package/dist/approval-policy-settlement.d.ts +4 -1
- package/dist/approval-policy-settlement.js +3 -2
- package/dist/approval-reconciler.d.ts +3 -3
- package/dist/approval-reconciler.js +10 -10
- package/dist/approval.d.ts +1 -1
- package/dist/approval.js +1 -1
- package/dist/audit.d.ts +1 -1
- package/dist/audit.js +53 -23
- package/dist/auth-bridge.d.ts +8 -8
- package/dist/auth-bridge.js +6 -6
- package/dist/auth-keys.d.ts +2 -2
- package/dist/auto-mode-face.d.ts +13 -9
- package/dist/auto-mode-face.js +8 -7
- package/dist/boot/budget-tracing.js +1 -1
- package/dist/boot/execution-env.js +1 -0
- package/dist/boot/leader.d.ts +1 -1
- package/dist/boot/memory-consolidation.d.ts +4 -4
- package/dist/boot/org-memory.d.ts +3 -3
- package/dist/boot/org-memory.js +5 -5
- package/dist/boot/resolve-spec.js +7 -7
- package/dist/boot/runner-deps.d.ts +1 -1
- package/dist/boot/runtime-caps.d.ts +1 -1
- package/dist/boot/runtime-caps.js +10 -10
- package/dist/boot/shutdown.d.ts +2 -2
- package/dist/boot/shutdown.js +2 -2
- package/dist/boot/side-query-lane.d.ts +3 -3
- package/dist/boot/{stage-02-registry-pull.d.ts → stage-02-web-admin-pull.d.ts} +2 -2
- package/dist/boot/{stage-02-registry-pull.js → stage-02-web-admin-pull.js} +4 -4
- package/dist/boot/stage-03-store-backend.d.ts +2 -2
- package/dist/boot/stage-04-stores.d.ts +1 -1
- 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 +6 -6
- package/dist/boot/stage-07-capability-layer.d.ts +2 -2
- package/dist/boot/stage-07-capability-layer.js +6 -5
- package/dist/boot/stage-08-reapers.d.ts +3 -3
- package/dist/boot/stage-08-reapers.js +3 -3
- package/dist/boot/stage-09-leader.d.ts +3 -3
- package/dist/boot/stage-09-leader.js +7 -7
- package/dist/boot/stage-10-http-server.d.ts +3 -3
- package/dist/boot/stage-10-http-server.js +19 -19
- package/dist/boot/unpriced-ceiling-verdict.d.ts +1 -1
- package/dist/boot/{config-center.d.ts → web-admin.d.ts} +11 -11
- package/dist/boot/{config-center.js → web-admin.js} +39 -20
- package/dist/boot/webfetch-summarize-lane.d.ts +2 -2
- package/dist/brain.d.ts +1 -1
- package/dist/brain.js +1 -1
- package/dist/budget.d.ts +3 -3
- package/dist/canonical-json.d.ts +2 -2
- package/dist/capabilities/center-plugins.d.ts +1 -1
- package/dist/capabilities/center-wiring.d.ts +12 -5
- package/dist/capabilities/center-wiring.js +11 -2
- package/dist/capabilities/composite-members.d.ts +1 -1
- package/dist/capabilities/composite-members.js +1 -1
- package/dist/capabilities/scenarios.js +2 -2
- package/dist/capabilities/team.d.ts +1 -1
- package/dist/capabilities/tool-defer.d.ts +1 -1
- package/dist/center-credential-renewer.d.ts +1 -1
- package/dist/center-credential-renewer.js +7 -7
- package/dist/center-credential.d.ts +9 -9
- package/dist/center-credential.js +6 -6
- package/dist/config-catalog.d.ts +7 -10
- package/dist/config-catalog.js +16 -16
- package/dist/config-d-migration.d.ts +32 -0
- package/dist/config-d-migration.js +59 -0
- package/dist/config-invariants.d.ts +14 -4
- package/dist/config-invariants.js +31 -2
- package/dist/config-lkg.d.ts +34 -11
- package/dist/config-lkg.js +76 -48
- package/dist/config-provider.d.ts +26 -21
- package/dist/config-provider.js +25 -27
- package/dist/config-types.d.ts +59 -50
- package/dist/config.d.ts +17 -54
- package/dist/config.js +99 -181
- package/dist/execution-lane-caps.d.ts +1 -1
- package/dist/fleet/drain-entry.d.ts +1 -1
- package/dist/fleet/engine-signal.d.ts +61 -30
- package/dist/fleet/engine-signal.js +29 -5
- package/dist/fleet/fleet-bus.d.ts +12 -3
- package/dist/fleet/fleet-bus.js +13 -9
- package/dist/fleet/serving-lease.d.ts +3 -3
- package/dist/fleet/serving-lease.js +1 -1
- package/dist/fleet-client.d.ts +15 -13
- package/dist/fleet-client.js +9 -7
- package/dist/fleet-lease.d.ts +3 -3
- package/dist/fleet-lease.js +2 -2
- package/dist/host-lsp-manager.d.ts +1 -1
- package/dist/hosted-posture.d.ts +4 -4
- package/dist/http/admission.js +4 -4
- package/dist/http/checkpoint-ctx.d.ts +20 -3
- package/dist/http/checkpoint-ctx.js +13 -5
- package/dist/http/dispatch.js +7 -16
- package/dist/http/durable-run-leg.js +2 -1
- package/dist/http/health-self-report.d.ts +7 -4
- package/dist/http/health-self-report.js +3 -3
- package/dist/http/idempotency.d.ts +1 -1
- package/dist/http/resume-legs.d.ts +4 -3
- package/dist/http/resume-legs.js +31 -18
- package/dist/http/route-ctx.d.ts +8 -0
- package/dist/http/routes/admin-config-refresh.d.ts +1 -1
- package/dist/http/routes/admin-config-refresh.js +1 -1
- package/dist/http/routes/admin-drain.d.ts +1 -1
- package/dist/http/routes/admin-drain.js +5 -4
- package/dist/http/routes/approvals-assistant.js +4 -4
- package/dist/http/routes/capabilities.js +6 -5
- package/dist/http/routes/config-catalog.js +2 -3
- package/dist/http/routes/diagnostics.js +1 -1
- package/dist/http/routes/runs.js +8 -4
- package/dist/http/routes/sessions-list.js +2 -1
- package/dist/http/routes/sessions.js +2 -5
- package/dist/http/routes/side-query.js +3 -3
- package/dist/http/routes/tasks.js +3 -2
- package/dist/http/run-meta.d.ts +1 -1
- package/dist/http/run-meta.js +2 -2
- package/dist/http/server.d.ts +7 -7
- package/dist/http/server.js +1 -1
- package/dist/http/stored-body-replay.d.ts +4 -3
- package/dist/http/stored-body-replay.js +5 -5
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -1
- package/dist/key-resolver.d.ts +1 -1
- package/dist/leader/leader.d.ts +7 -6
- package/dist/leader/leader.js +3 -1
- package/dist/leader/run-entry.d.ts +2 -2
- package/dist/leader/run-entry.js +3 -3
- package/dist/leader/wire.d.ts +4 -4
- package/dist/leader/wire.js +2 -1
- package/dist/main.js +1 -1
- package/dist/mcp-tool-faces.d.ts +2 -2
- package/dist/model-entry-refusal.d.ts +20 -11
- package/dist/model-entry-refusal.js +22 -17
- package/dist/model-provider.d.ts +2 -2
- package/dist/model-route-endpoint.d.ts +22 -2
- package/dist/model-route-endpoint.js +9 -3
- package/dist/model-route-gap.d.ts +103 -0
- package/dist/model-route-gap.js +80 -0
- package/dist/model-route-url.d.ts +1 -1
- package/dist/model-route-url.js +2 -1
- package/dist/model-select.d.ts +24 -21
- package/dist/model-select.js +22 -17
- package/dist/namespaced-rule-name.d.ts +16 -30
- package/dist/namespaced-rule-name.js +2 -20
- package/dist/observability/fail-open.d.ts +0 -4
- package/dist/observability/fail-open.js +0 -4
- package/dist/observability/metrics.d.ts +1 -1
- package/dist/org-memory-admission.d.ts +1 -1
- package/dist/plugins/approval-ask-store-file.d.ts +4 -2
- package/dist/plugins/approval-ask-store-file.js +3 -3
- package/dist/plugins/approval-ask-store-memory.d.ts +4 -3
- package/dist/plugins/approval-ask-store-memory.js +10 -4
- package/dist/plugins/approval-ask-store-sql.d.ts +16 -2
- package/dist/plugins/approval-ask-store-sql.js +20 -13
- package/dist/plugins/caching-session-store.d.ts +0 -10
- package/dist/plugins/caching-session-store.js +0 -3
- package/dist/plugins/file-run-store.js +9 -3
- package/dist/plugins/leader-run-store-sql.d.ts +3 -2
- package/dist/plugins/leader-run-store-sql.js +3 -2
- package/dist/plugins/local-session-store.d.ts +20 -27
- package/dist/plugins/local-session-store.js +19 -17
- package/dist/plugins/memory-run-store.js +9 -3
- package/dist/plugins/one-time-migrations.js +51 -0
- package/dist/plugins/scheduler-support.d.ts +26 -7
- package/dist/plugins/scheduler-support.js +96 -53
- package/dist/plugins/session-policy-store-sql.js +1 -2
- package/dist/plugins/store-backend.js +1 -1
- package/dist/plugins/store-contracts.d.ts +20 -4
- package/dist/plugins/web-search.d.ts +1 -1
- package/dist/plugins/web-search.js +2 -1
- package/dist/plugins/workflow-run-store-sql.d.ts +4 -2
- package/dist/posture-source.d.ts +1 -1
- package/dist/read-face-posture.d.ts +3 -3
- package/dist/read-face-posture.js +1 -1
- package/dist/rule-entry-list.d.ts +3 -13
- package/dist/rule-entry-list.js +1 -12
- package/dist/run-local.js +10 -7
- package/dist/runtime-caps-resolver.d.ts +4 -4
- package/dist/runtime-caps-resolver.js +2 -2
- package/dist/runtime-governance.d.ts +36 -13
- package/dist/runtime-governance.js +7 -2
- package/dist/sealed-key.d.ts +4 -4
- package/dist/sealed-key.js +3 -2
- package/dist/security.d.ts +3 -3
- package/dist/service-version.d.ts +1 -1
- package/dist/service-version.js +5 -0
- package/dist/session-policy-wire.d.ts +47 -49
- package/dist/session-policy-wire.js +41 -36
- package/dist/session-sync.d.ts +5 -1
- package/dist/session-sync.js +2 -1
- package/dist/session-titler.d.ts +0 -11
- package/dist/session-titler.js +3 -5
- package/dist/shared-memory-scope-authorizer.d.ts +4 -4
- package/dist/spec-fields.d.ts +4 -4
- package/dist/spec-fields.js +1 -4
- package/dist/task-a2a.d.ts +1 -1
- package/dist/task-settings.d.ts +4 -5
- package/dist/task-settings.js +5 -8
- package/dist/tool-approval.d.ts +43 -4
- package/dist/tool-approval.js +147 -98
- package/dist/trace/core-keyset-guard.d.ts +1 -1
- package/dist/trace/project.d.ts +3 -3
- package/dist/trace/redact.d.ts +2 -23
- package/dist/trace/redact.js +1 -6
- package/dist/trace/self-minted-wire.d.ts +147 -3
- package/dist/trace/self-minted-wire.js +50 -9
- package/dist/unattended-permission-mode.d.ts +3 -3
- package/dist/unattended-permission-mode.js +2 -2
- package/dist/url-refusal.d.ts +35 -0
- package/dist/url-refusal.js +15 -0
- package/dist/user-authored-text.d.ts +31 -0
- package/dist/user-authored-text.js +18 -0
- package/dist/{config-center → web-admin-client}/apply-effective.d.ts +13 -70
- package/dist/{config-center → web-admin-client}/apply-effective.js +104 -121
- package/dist/{config-center → web-admin-client}/apply-ledger.d.ts +2 -2
- package/dist/{config-center → web-admin-client}/center-request.d.ts +7 -7
- package/dist/{config-center → web-admin-client}/center-request.js +5 -4
- package/dist/{config-center → web-admin-client}/effective-keys.d.ts +1 -3
- package/dist/{config-center → web-admin-client}/effective-keys.js +0 -9
- package/dist/{config-center → web-admin-client}/facade.d.ts +6 -6
- package/dist/{config-center → web-admin-client}/facade.js +2 -2
- package/dist/{config-center → web-admin-client}/http-client.d.ts +6 -10
- package/dist/{config-center → web-admin-client}/http-client.js +15 -15
- package/dist/{config-center → web-admin-client}/pull-state.d.ts +1 -1
- package/dist/{config-center → web-admin-client}/read-face.js +4 -4
- package/dist/web-admin-client/read-warnings.d.ts +137 -0
- package/dist/web-admin-client/read-warnings.js +168 -0
- package/dist/{config-center → web-admin-client}/restart-signal.d.ts +5 -3
- package/dist/{config-center → web-admin-client}/restart-signal.js +3 -4
- package/dist/{config-center → web-admin-client}/skills-mcp.d.ts +1 -1
- package/dist/{config-center → web-admin-client}/skills-mcp.js +13 -13
- package/dist/{config-center → web-admin-client}/stage-limits.d.ts +1 -7
- package/dist/{config-center → web-admin-client}/stage-limits.js +6 -7
- package/dist/{config-center → web-admin-client}/types.d.ts +19 -47
- package/package.json +3 -3
- package/skills/find-skills.md +2 -2
- package/dist/config-center/read-warnings.d.ts +0 -109
- package/dist/config-center/read-warnings.js +0 -110
- package/dist/url-shape.d.ts +0 -31
- package/dist/url-shape.js +0 -41
- /package/dist/{config-center → web-admin-client}/apply-ledger.js +0 -0
- /package/dist/{config-center → web-admin-client}/hot-keys-registry.d.ts +0 -0
- /package/dist/{config-center → web-admin-client}/hot-keys-registry.js +0 -0
- /package/dist/{config-center → web-admin-client}/mcp-revocation.d.ts +0 -0
- /package/dist/{config-center → web-admin-client}/mcp-revocation.js +0 -0
- /package/dist/{config-center → web-admin-client}/pull-state.js +0 -0
- /package/dist/{config-center → web-admin-client}/read-face.d.ts +0 -0
- /package/dist/{config-center → web-admin-client}/types.js +0 -0
package/dist/config.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
|
-
import { DEFAULT_MODEL_REF } from "./model-select.js";
|
|
2
|
+
import { DEFAULT_AT_MENTION, DEFAULT_MODEL_REF } from "./model-select.js";
|
|
3
3
|
import { homedir } from "node:os";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
6
|
import { BUILTIN_COMPLIANCE_DENIES, COMPLIANCE_CAPABILITIES, CROSS_SESSION_INBOUND_SETTINGS, CROSS_SESSION_DIALOG_EXPIRY_VALUES, compileReadDeny, resolveReadDenyBuiltins, CODE_AGENT_PROMPT, isModelPriced, PROTOCOL_TABLE, RECOMMENDED_SENSITIVE_PATTERNS, judgeRuleToolName, resolveFileHistoryRetention, resolveLockedKeys, validatePermissionRules, WRITE_PROTECTED_DEFAULT_TABLE, resolveWriteProtectedTable } from "@sema-agent/core";
|
|
7
|
-
import { ROSTER_PRIMARY_ROLES, ROSTER_CHEAP_ROLES,
|
|
7
|
+
import { ROSTER_PRIMARY_ROLES, ROSTER_CHEAP_ROLES, WEB_ADMIN_ENV, retiredEnvRefusal } from "@sema-agent/settings-schema";
|
|
8
8
|
import { parseApprovalHmacKeys, parsePrincipalJwks } from "./auth-keys.js";
|
|
9
9
|
import { DEFAULT_ELICITATION_THROTTLE } from "./elicitation.js";
|
|
10
10
|
import { isV2ScopeKey, memoryReplicationCoverage, replicationCovers } from "./memory-scope.js";
|
|
@@ -13,7 +13,7 @@ import { GIT_API_KINDS, isGitApiKind } from "./git-api-kind.js";
|
|
|
13
13
|
import { CONFIG_PROVIDER_WORDS, RETENTION_MODES, MEMORY_CONSOLIDATION_MIN_INTERVAL_SEC, RESILIENCE_DEFAULTS, TASK_WRITE_FACE_ESCALATIONS, MAX_TIMER_DELAY_MS, AUTO_MODE_CLASSIFIER_TIMEOUT_BOUNDS, DRAIN_GRACE_FLOOR_MS, DRAIN_SECOND_SIGNAL_MIN_GAP_BOUNDS, DRAIN_SECOND_SIGNAL_MIN_GAP_DEFAULT_MS, FIRST_BYTE_TIMEOUT_BOUNDS, FLEET_LEASE_OUTAGE_MAX_DEFAULT_MS, fleetScopeOf } from "./config-types.js";
|
|
14
14
|
import { FLEET_GENERATION_ENV, FLEET_SCOPE_ENV, SERVING_LEASE_TTL_FLOOR_MS, isCanonicalGeneration } from "@sema-agent/settings-schema/fleet";
|
|
15
15
|
import { ScopeId } from "@sema-agent/settings-schema/api/scopes";
|
|
16
|
-
import { centerLaneConfigured, pathBaseUrlRefusal } from "./
|
|
16
|
+
import { centerLaneConfigured, pathBaseUrlRefusal } from "./web-admin-client/center-request.js";
|
|
17
17
|
import { resolveLocalDataRoot } from "./local-data-root.js";
|
|
18
18
|
import { buildWriteProtectionPosture } from "./write-protection.js";
|
|
19
19
|
import { normalizeSshFingerprint } from "./ssh-host-key.js";
|
|
@@ -22,29 +22,27 @@ import { THINKING_LEVELS, THINKING_FORMATS, buildModelCompat, isThinkingFormat,
|
|
|
22
22
|
import {} from "./posture-source.js";
|
|
23
23
|
import { CONTROL_AND_BIDI_STRIP_RE } from "./text-bidi.js";
|
|
24
24
|
import { describeUnmatchableRuleName, ruleEntryToolName, unmatchableRuleNameOf } from "./namespaced-rule-name.js";
|
|
25
|
-
import { bakeOperatorPrincipalsRefusal, bakeRunnerCredentialRefusal, halfOpenDirectDoorRefusal, leaderDurableStoreRefusal, operatorPrincipalsRequiredRefusal } from "./config-invariants.js";
|
|
25
|
+
import { bakeOperatorPrincipalsRefusal, bakeRunnerCredentialRefusal, centerIdentityRefusal, halfOpenDirectDoorRefusal, leaderDurableStoreRefusal, operatorPrincipalsRequiredRefusal } from "./config-invariants.js";
|
|
26
26
|
import { declaredSemaConfigDir } from "./sema-config-dir.js";
|
|
27
27
|
import { lkgPathOverrideOf } from "./config-lkg.js";
|
|
28
28
|
import { REMOTE_EXEC_PROVIDER_WORDS, executionLaneOf, executionLaneRequiredRefusal, isSingleMachineDefaultLane, laneRequiredEnv } from "./execution-lane-caps.js";
|
|
29
29
|
import { MEMORY_ENGINE_BACKENDS, SESSION_BACKENDS, STORE_BACKENDS } from "@sema-agent/settings-schema/execution-lanes";
|
|
30
30
|
import { AUTONOMY_MODES } from "./runtime-governance.js";
|
|
31
|
-
import { allowLayerEntryCountIssue,
|
|
31
|
+
import { allowLayerEntryCountIssue, describeInertRuleEntries, inertRuleEntriesOf, ruleEntryListShapeOk } from "./rule-entry-list.js";
|
|
32
32
|
import { createCenterCredentialSource, readCenterCredentialDeclaration } from "./center-credential.js";
|
|
33
33
|
import { parseCenterCredentialRenewLeadMs } from "./center-credential-renewer.js";
|
|
34
34
|
import { modelProviderRefusal } from "./model-provider.js";
|
|
35
35
|
import { modelRouteUrlRefusal } from "./model-route-url.js";
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
36
|
+
import { httpUrlFlaws } from "@sema-agent/settings-schema";
|
|
37
|
+
import { buildHttpUrlRefusal } from "./url-refusal.js";
|
|
38
|
+
import { csvOf, envLaneTable, judgeModelRouteGap, mintedCheapId, readModelRouteEnv } from "./model-route-gap.js";
|
|
38
39
|
import { displayListEntry } from "./list-entry-display.js";
|
|
39
40
|
import { buildDisplaySafeUrl, redactSecrets } from "./trace/redact.js";
|
|
40
41
|
import { allowlistedEnv } from "./server-secret-env.js";
|
|
41
42
|
import { ENV_NAME_ALLOWLIST_KNOBS, ENV_NAME_ALLOWLIST_KNOB_NAMES, describeAllowlistPostures } from "./env-name-allowlist-knobs.js";
|
|
42
43
|
export { RETENTION_MODES, MEMORY_CONSOLIDATION_MIN_INTERVAL_SEC } from "./config-types.js";
|
|
43
44
|
function csv(name) {
|
|
44
|
-
return (process.env[name]
|
|
45
|
-
.split(",")
|
|
46
|
-
.map((s) => s.trim())
|
|
47
|
-
.filter(Boolean);
|
|
45
|
+
return csvOf(process.env[name]);
|
|
48
46
|
}
|
|
49
47
|
export function parseAutonomy(raw) {
|
|
50
48
|
const v = raw?.trim();
|
|
@@ -116,74 +114,10 @@ function defaultSkillsDir() {
|
|
|
116
114
|
return "skills";
|
|
117
115
|
}
|
|
118
116
|
}
|
|
119
|
-
export const RETIRED_ENV_REFUSAL_CODE = "config.env_key_retired";
|
|
120
|
-
export const RETIRED_ENVS = [
|
|
121
|
-
["TIDB_HOST", "MYSQL_HOST", "renamed"], ["TIDB_PORT", "MYSQL_PORT", "renamed"], ["TIDB_USER", "MYSQL_USER", "renamed"],
|
|
122
|
-
["TIDB_PASSWORD", "MYSQL_PASSWORD", "renamed"], ["TIDB_DATABASE", "MYSQL_DATABASE", "renamed"], ["TIDB_POOL_SIZE", "MYSQL_POOL_SIZE", "renamed"],
|
|
123
|
-
["CONFIG_CENTER_URL", "SEMA_REGISTRY_URL", "renamed"], ["CONFIG_CENTER_TOKEN", CENTER_CREDENTIAL_ENV.token, "renamed"],
|
|
124
|
-
["CONFIG_CENTER_DRY_RUN", "SEMA_REGISTRY_DRY_RUN", "renamed"], ["CONFIG_CENTER_WORKER", "SEMA_REGISTRY_WORKER", "renamed"],
|
|
125
|
-
["ANTHROPIC_BASEURL", "ANTHROPIC_BASE_URL", "renamed"],
|
|
126
|
-
["REGISTRY_ADMIN_TOKEN", "SEMA_REGISTRY_ADMIN_TOKEN", "renamed"],
|
|
127
|
-
["OA_API_BASEURL", "the OA scenario was removed in 5.0.0", "removed"],
|
|
128
|
-
["OA_SERVICE_TOKEN", "the OA scenario was removed in 5.0.0", "removed"],
|
|
129
|
-
["OA_ISSUE_TOKEN", "the OA scenario was removed in 5.0.0", "removed"],
|
|
130
|
-
["OA_ISSUE_BASEURL", "the OA scenario was removed in 5.0.0", "removed"],
|
|
131
|
-
["OA_ISSUE_OWNER", "the OA scenario was removed in 5.0.0", "removed"],
|
|
132
|
-
["OA_ISSUE_REPO", "the OA scenario was removed in 5.0.0", "removed"],
|
|
133
|
-
["OA_ISSUE_LABELS", "the OA scenario was removed in 5.0.0", "removed"],
|
|
134
|
-
["APPROVAL_POLL_MS", "the OA poll-approval lane was removed in 5.0.0; the durable checkpoint lane is the only gate", "removed"],
|
|
135
|
-
["LEADER_CONFLICT_ROUNDS", "the bounded merge-conflict-resolution agent was deleted in 7.83.0 按 C-R63 删除,合不上交用户:leader 交回 result.conflict(分支 + 冲突文件),run 状态 needs_human", "removed"],
|
|
136
|
-
[
|
|
137
|
-
"MODEL_CONNECT_TIMEOUT_MS",
|
|
138
|
-
"MODEL_FIRST_BYTE_TIMEOUT_MS",
|
|
139
|
-
"replaced",
|
|
140
|
-
"since core 7.33.0 the TCP + TLS connect clock is the transport's own; the wait from sending the request to its response headers — " +
|
|
141
|
-
"what this key really bounded — is MODEL_FIRST_BYTE_TIMEOUT_MS (unset = core's own default, plus an upload allowance and one " +
|
|
142
|
-
"widened retry; 0 = no engine clock on that segment and the transport's header / body clocks off too — the TCP + TLS connect " +
|
|
143
|
-
"keeps the transport's own clock)",
|
|
144
|
-
],
|
|
145
|
-
["PROJECT_MEMORY_DISABLED", "PROJECT_MEMORY_ENABLED", "replaced", "negative-name alias retired in server 3.0.0 — unset it; the polarity is inverted: PROJECT_MEMORY_DISABLED=true is PROJECT_MEMORY_ENABLED=false (the positive name defaults on)"],
|
|
146
|
-
["CONFIG_LKG_DISABLED", "CONFIG_LKG_ENABLED", "replaced", "negative-name alias retired in server 3.0.0 — unset it; the polarity is inverted: CONFIG_LKG_DISABLED=true is CONFIG_LKG_ENABLED=false (the positive name defaults on)"],
|
|
147
|
-
["HOST_BG_DISABLED", "HOST_BG_ENABLED", "replaced", "negative-name alias retired in server 3.0.0 — unset it; the polarity is inverted: HOST_BG_DISABLED=true is HOST_BG_ENABLED=false (the positive name defaults on)"],
|
|
148
|
-
["HOST_EXEC_SPOOL_DISABLED", "HOST_EXEC_SPOOL_ENABLED", "replaced", "negative-name alias retired in server 3.0.0 — unset it; the polarity is inverted: HOST_EXEC_SPOOL_DISABLED=true is HOST_EXEC_SPOOL_ENABLED=false (the positive name defaults on)"],
|
|
149
|
-
["UNATTENDED_PERMISSION_MODE", "since server 7.109.0 the unattended legs (leader workers and their repair legs, run-local, and their durable resumes) always run permissionMode \"default\" with an approver that answers by ask class: a machine answers only \"ordinary\" asks, and every other class goes to the leg's approver seat (run-local's terminal prompt) or parks / is refused — there is no mode to choose", "removed"],
|
|
150
|
-
];
|
|
151
|
-
for (const row of RETIRED_ENVS)
|
|
152
|
-
Object.freeze(row);
|
|
153
|
-
Object.freeze(RETIRED_ENVS);
|
|
154
|
-
export function buildRetiredEnvWire() {
|
|
155
|
-
return RETIRED_ENVS.map((row) => {
|
|
156
|
-
switch (row[2]) {
|
|
157
|
-
case "renamed":
|
|
158
|
-
return { name: row[0], kind: row[2], replacement: row[1] };
|
|
159
|
-
case "replaced":
|
|
160
|
-
return { name: row[0], kind: row[2], replacement: row[1], reason: row[3] };
|
|
161
|
-
case "removed":
|
|
162
|
-
return { name: row[0], kind: row[2], reason: row[1] };
|
|
163
|
-
default: {
|
|
164
|
-
const unhandled = row;
|
|
165
|
-
throw new Error(`unhandled retired-env kind: ${String(unhandled[2])}`);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
const RETIRED_ENV_SENTENCE = {
|
|
171
|
-
renamed: (hits) => `${hits.map(([old, to]) => `${old} → use ${to}`).join("; ")} — rename the env key(s); the value semantics are unchanged`,
|
|
172
|
-
replaced: (hits) => `${hits.map(([old, to, , why]) => `${old} → ${to} (${why})`).join("; ")} — set the replacement deliberately: ` +
|
|
173
|
-
`its value semantics differ from the retired key's, so do not copy the old value across unread`,
|
|
174
|
-
removed: (hits) => `${hits.map(([old, why]) => `${old} (${why})`).join("; ")} — remove the env key(s): the capability itself was retired, ` +
|
|
175
|
-
`there is no replacement name and no rename that restores it`,
|
|
176
|
-
};
|
|
177
|
-
function retiredEnvSentence(kind, hit) {
|
|
178
|
-
const ofKind = hit.filter((h) => h[2] === kind);
|
|
179
|
-
return ofKind.length > 0 ? [RETIRED_ENV_SENTENCE[kind](ofKind)] : [];
|
|
180
|
-
}
|
|
181
117
|
function rejectRetiredEnvs() {
|
|
182
|
-
const
|
|
183
|
-
if (
|
|
184
|
-
|
|
185
|
-
const parts = Object.keys(RETIRED_ENV_SENTENCE).flatMap((kind) => retiredEnvSentence(kind, hit));
|
|
186
|
-
throw new Error(`retired env name(s) set [${RETIRED_ENV_REFUSAL_CODE}] — refused while present, whether or not the replacement is also set: ${parts.join(" | ")}.`);
|
|
118
|
+
const refusal = retiredEnvRefusal(process.env);
|
|
119
|
+
if (refusal !== undefined)
|
|
120
|
+
throw new Error(refusal);
|
|
187
121
|
}
|
|
188
122
|
export function numEnv(name, fallback) {
|
|
189
123
|
return parseNumOrFail(name, env(name, fallback));
|
|
@@ -250,7 +184,7 @@ function parseConfigProvider() {
|
|
|
250
184
|
return undefined;
|
|
251
185
|
const word = CONFIG_PROVIDER_WORDS.find((w) => w === raw);
|
|
252
186
|
if (word === undefined) {
|
|
253
|
-
throw new Error(`env CONFIG_PROVIDER="${raw.slice(0, 120)}" must be one of: ${CONFIG_PROVIDER_WORDS.join(", ")} — or leave it unset (then
|
|
187
|
+
throw new Error(`env CONFIG_PROVIDER="${raw.slice(0, 120)}" must be one of: ${CONFIG_PROVIDER_WORDS.join(", ")} — or leave it unset (then ${WEB_ADMIN_ENV.url}, if set, selects the center as the config source; otherwise this worker is env-only). ` +
|
|
254
188
|
`The word is matched exactly (no trimming, no case folding). Refusing to boot rather than guessing: the config source, the execution-lane default and the local config root all key on this one word.`);
|
|
255
189
|
}
|
|
256
190
|
return word;
|
|
@@ -312,14 +246,6 @@ export function logConfigDiagnostics(logger) {
|
|
|
312
246
|
}
|
|
313
247
|
}
|
|
314
248
|
}
|
|
315
|
-
function firstSetEnv(...names) {
|
|
316
|
-
for (const n of names) {
|
|
317
|
-
const v = process.env[n];
|
|
318
|
-
if (v !== undefined && v !== "")
|
|
319
|
-
return v;
|
|
320
|
-
}
|
|
321
|
-
return undefined;
|
|
322
|
-
}
|
|
323
249
|
function clampEnvWithWarn(name, fallback, min, max = Number.POSITIVE_INFINITY) {
|
|
324
250
|
const n = numEnv(name, fallback);
|
|
325
251
|
const used = Math.min(max, Math.max(min, n));
|
|
@@ -948,48 +874,41 @@ function parseStoreDomain(ctx) {
|
|
|
948
874
|
: undefined,
|
|
949
875
|
};
|
|
950
876
|
}
|
|
951
|
-
export function isRosterGateArmed(
|
|
952
|
-
return
|
|
877
|
+
export function isRosterGateArmed(webAdmin) {
|
|
878
|
+
return webAdmin !== undefined && !webAdmin.dryRun && process.env.CONFIG_REQUIRE_ROSTER === "true";
|
|
953
879
|
}
|
|
954
880
|
function parseModelDomain() {
|
|
955
|
-
const
|
|
956
|
-
const
|
|
957
|
-
const
|
|
958
|
-
if (
|
|
959
|
-
const refusal = modelProviderRefusal(
|
|
881
|
+
const route = readModelRouteEnv(process.env);
|
|
882
|
+
const gatewayBaseUrl = route.gatewayBaseUrl;
|
|
883
|
+
const modelId = route.mainId;
|
|
884
|
+
if (route.providerSource === "explicit") {
|
|
885
|
+
const refusal = modelProviderRefusal(route.provider);
|
|
960
886
|
if (refusal !== undefined) {
|
|
961
887
|
throw new Error(refusal);
|
|
962
888
|
}
|
|
963
889
|
}
|
|
964
890
|
for (const [envKey, raw, knob] of [
|
|
965
891
|
["MODEL_GATEWAY_BASEURL", gatewayBaseUrl ?? "", "MODEL_API_KEY"],
|
|
966
|
-
...
|
|
967
|
-
["ANTHROPIC_BASE_URL",
|
|
892
|
+
...route.gatewayFallbackUrls.map((u, i) => [`MODEL_GATEWAY_FALLBACK_URLS[${i}]`, u, "MODEL_API_KEY"]),
|
|
893
|
+
["ANTHROPIC_BASE_URL", route.anthropicBaseUrl ?? "", "ANTHROPIC_API_KEY"],
|
|
968
894
|
]) {
|
|
969
895
|
const refusal = modelRouteUrlRefusal(envKey, raw, knob);
|
|
970
896
|
if (refusal !== undefined) {
|
|
971
897
|
throw new Error(refusal);
|
|
972
898
|
}
|
|
973
899
|
}
|
|
974
|
-
const
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
hint: "MODEL_PROVIDER is unset but an explicit ANTHROPIC base URL + credential are configured — inferred provider=anthropic (set MODEL_PROVIDER explicitly to override)",
|
|
987
|
-
},
|
|
988
|
-
});
|
|
989
|
-
return "anthropic";
|
|
990
|
-
}
|
|
991
|
-
return "gateway";
|
|
992
|
-
})();
|
|
900
|
+
const provider = route.provider;
|
|
901
|
+
if (route.providerSource === "inferred") {
|
|
902
|
+
CONFIG_NOTICES.push({
|
|
903
|
+
level: "warn",
|
|
904
|
+
event: "model_provider_inferred",
|
|
905
|
+
fields: {
|
|
906
|
+
provider: "anthropic",
|
|
907
|
+
baseUrl: buildDisplaySafeUrl(route.anthropicBaseUrl),
|
|
908
|
+
hint: "MODEL_PROVIDER is unset but an explicit ANTHROPIC base URL + credential are configured — inferred provider=anthropic (set MODEL_PROVIDER explicitly to override)",
|
|
909
|
+
},
|
|
910
|
+
});
|
|
911
|
+
}
|
|
993
912
|
const extraBody = buildExtraBody();
|
|
994
913
|
const thinkingDefault = parseDefaultThinking(process.env.MODEL_DEFAULT_THINKING);
|
|
995
914
|
const envCompatDeclared = buildModelCompat({
|
|
@@ -1021,35 +940,40 @@ function parseModelDomain() {
|
|
|
1021
940
|
...(envCompat ? { compat: envCompat } : {}),
|
|
1022
941
|
...(extraBody ? { extraBody } : {}),
|
|
1023
942
|
};
|
|
1024
|
-
const
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
943
|
+
const cheapSlot = route.cheapSlot;
|
|
944
|
+
switch (cheapSlot.kind) {
|
|
945
|
+
case "without_main":
|
|
946
|
+
CONFIG_NOTICES.push({
|
|
947
|
+
level: "warn",
|
|
948
|
+
event: "model_cheap_slot_without_main",
|
|
949
|
+
fields: { hint: "MODEL_CHEAP_ID is set but MODEL_ID is not — the env cheap slot derives from the env main model, so it is not minted; the catalog (config.d/models.json or the web-admin) serves the roles. Set MODEL_ID to use the env slots, or unset MODEL_CHEAP_ID to silence this line." },
|
|
950
|
+
});
|
|
951
|
+
break;
|
|
952
|
+
case "same_as_main":
|
|
953
|
+
CONFIG_NOTICES.push({
|
|
954
|
+
level: "warn",
|
|
955
|
+
event: "config_env_entry_cheap_same_as_main",
|
|
956
|
+
fields: {
|
|
957
|
+
env: "MODEL_CHEAP_ID",
|
|
958
|
+
model: modelId,
|
|
959
|
+
hint: `MODEL_CHEAP_ID names the same model as MODEL_ID ("${modelId}") — the env cheap slot is the main gateway under a different id, ` +
|
|
960
|
+
`so the same id IS the main model: no cheap slot is minted and subagent / summarize stay on the main model (roles -> default); ` +
|
|
961
|
+
`any other MODEL_CHEAP_* key set here describes that slot and is not applied. Set MODEL_CHEAP_ID to a different (cheaper) model ` +
|
|
962
|
+
`id to run those roles cheap, or declare two differently-named entries in config.d/models.json to give one upstream id a second ` +
|
|
963
|
+
`shape (price / reasoning / window); unset MODEL_CHEAP_ID to silence this line.`,
|
|
964
|
+
},
|
|
965
|
+
});
|
|
966
|
+
break;
|
|
967
|
+
case "absent":
|
|
968
|
+
case "minted":
|
|
969
|
+
break;
|
|
1047
970
|
}
|
|
1048
|
-
const
|
|
971
|
+
const cheapMintedId = mintedCheapId(cheapSlot);
|
|
972
|
+
const cheapModel = cheapMintedId !== undefined
|
|
1049
973
|
? {
|
|
1050
974
|
...model,
|
|
1051
|
-
id:
|
|
1052
|
-
name:
|
|
975
|
+
id: cheapMintedId,
|
|
976
|
+
name: cheapMintedId,
|
|
1053
977
|
input: ((v) => (v === undefined ? model.input : v ? ["text", "image"] : ["text"]))(parseBoolWord("MODEL_CHEAP_VISION", process.env.MODEL_CHEAP_VISION)),
|
|
1054
978
|
...buildModelCostKey(buildCostOrAbsent({
|
|
1055
979
|
input: costEnv("MODEL_CHEAP_COST_INPUT", "declares-zero"),
|
|
@@ -1093,9 +1017,7 @@ function parseModelDomain() {
|
|
|
1093
1017
|
}
|
|
1094
1018
|
noticeAutoCompactAboveWindow("cheap", "MODEL_CHEAP_AUTO_COMPACT_TOKENS", cheapModel);
|
|
1095
1019
|
}
|
|
1096
|
-
const models = modelId
|
|
1097
|
-
if (cheapModel)
|
|
1098
|
-
models[cheapModel.id] = cheapModel;
|
|
1020
|
+
const models = envLaneTable(modelId, model, cheapModel);
|
|
1099
1021
|
const gatewayApiKey = process.env.MODEL_API_KEY;
|
|
1100
1022
|
if (gatewayBaseUrl === undefined && gatewayApiKey !== undefined && gatewayApiKey !== "") {
|
|
1101
1023
|
CONFIG_NOTICES.push({
|
|
@@ -1129,13 +1051,13 @@ function parseModelDomain() {
|
|
|
1129
1051
|
const degradeOn = parseDegradeOn(csv("MODEL_DEGRADE_ON"));
|
|
1130
1052
|
return {
|
|
1131
1053
|
...(gatewayBaseUrl !== undefined ? { gatewayBaseUrl, gatewayApiKey } : {}),
|
|
1132
|
-
gatewayFallbackUrls:
|
|
1054
|
+
gatewayFallbackUrls: route.gatewayFallbackUrls,
|
|
1133
1055
|
...(process.env.GATEWAY_MAX_RETRIES ? { gatewayMaxRetries: numEnvBounded("GATEWAY_MAX_RETRIES", "2", 0, 20) } : {}),
|
|
1134
|
-
anthropic:
|
|
1056
|
+
anthropic: route.anthropicRouteMounted
|
|
1135
1057
|
? {
|
|
1136
|
-
apiKey:
|
|
1137
|
-
authToken:
|
|
1138
|
-
baseUrl:
|
|
1058
|
+
apiKey: route.anthropicApiKey,
|
|
1059
|
+
authToken: route.anthropicAuthToken,
|
|
1060
|
+
baseUrl: route.anthropicBaseUrl,
|
|
1139
1061
|
version: process.env.ANTHROPIC_VERSION,
|
|
1140
1062
|
cacheBreakpoints: boolEnv("ANTHROPIC_CACHE_BREAKPOINTS", true),
|
|
1141
1063
|
...(process.env.ANTHROPIC_MAX_RETRIES ? { maxRetries: numEnv("ANTHROPIC_MAX_RETRIES", "2") } : {}),
|
|
@@ -1155,11 +1077,12 @@ function parseModelDomain() {
|
|
|
1155
1077
|
modelApiKeyEnv: {},
|
|
1156
1078
|
modelApiKeys: {},
|
|
1157
1079
|
modelRefusals: {},
|
|
1080
|
+
droppedCatalogEntries: [],
|
|
1158
1081
|
modelQuotaWeights: {},
|
|
1159
1082
|
tiers: {},
|
|
1160
1083
|
projects: {},
|
|
1161
1084
|
roles,
|
|
1162
|
-
|
|
1085
|
+
atMention: DEFAULT_AT_MENTION,
|
|
1163
1086
|
cascadeLadder: csv("MODEL_CASCADE_LADDER"),
|
|
1164
1087
|
degrade: process.env.MODEL_DEGRADE_TO
|
|
1165
1088
|
? {
|
|
@@ -1272,9 +1195,6 @@ export function approvalGrantRefusal(names) {
|
|
|
1272
1195
|
const over = allowLayerEntryCountIssue(APPROVAL_GRANT_ENV, names);
|
|
1273
1196
|
if (over !== undefined)
|
|
1274
1197
|
return `${over.message} — refusing to start rather than running with a truncated list`;
|
|
1275
|
-
const empty = emptyToolSegmentEntryOf(names);
|
|
1276
|
-
if (empty !== undefined)
|
|
1277
|
-
return `${describeEmptyToolSegmentEntry(APPROVAL_GRANT_ENV, empty)} — refusing to start rather than running without it`;
|
|
1278
1198
|
const inert = inertRuleEntriesOf(names, "allow");
|
|
1279
1199
|
if (inert.length > 0)
|
|
1280
1200
|
return `${describeInertRuleEntries(APPROVAL_GRANT_ENV, inert)} — the engine would grant nothing for ${inert.length === 1 ? "it" : "them"}; refusing to start rather than running with an allow rule that never takes effect`;
|
|
@@ -1375,7 +1295,7 @@ function parseApprovalDomain(ctx) {
|
|
|
1375
1295
|
const trimmed = raw.trim();
|
|
1376
1296
|
if (trimmed === "" || trimmed.toLowerCase() === "off")
|
|
1377
1297
|
return [];
|
|
1378
|
-
return trimmed
|
|
1298
|
+
return csvOf(trimmed);
|
|
1379
1299
|
})(process.env.SENSITIVE_WRITE_PATTERNS),
|
|
1380
1300
|
...((decision) => (decision === undefined ? {} : { writeProtectedPaths: decision }))(parseWriteProtectedTableEnv(process.env.WRITE_PROTECTED_EXTRA, process.env.WRITE_PROTECTED_TABLE_REPLACE)),
|
|
1381
1301
|
...((raw) => {
|
|
@@ -1826,7 +1746,7 @@ function parseAuthDomain(ctx) {
|
|
|
1826
1746
|
authToken: process.env.SERVICE_AUTH_TOKEN,
|
|
1827
1747
|
authTokens,
|
|
1828
1748
|
allowUnauthedWrites: boolEnv("ALLOW_UNAUTHED_WRITES", false),
|
|
1829
|
-
corsOrigins: (
|
|
1749
|
+
corsOrigins: csv("CORS_ORIGIN"),
|
|
1830
1750
|
principalHeader: headerNameEnv("PRINCIPAL_HEADER", "x-agent-principal"),
|
|
1831
1751
|
requirePrincipal,
|
|
1832
1752
|
autonomy: parseAutonomy(process.env.AUTONOMY),
|
|
@@ -2011,7 +1931,7 @@ function parseOrchestrationDomain(ctx) {
|
|
|
2011
1931
|
? {
|
|
2012
1932
|
repoRoot: process.env.WORKTREE_REPO_ROOT,
|
|
2013
1933
|
...(process.env.WORKTREE_ALLOWED_ROOTS
|
|
2014
|
-
? { allowedRoots:
|
|
1934
|
+
? { allowedRoots: csv("WORKTREE_ALLOWED_ROOTS") }
|
|
2015
1935
|
: {}),
|
|
2016
1936
|
...(process.env.WORKTREE_BASE_COMMIT ? { commit: process.env.WORKTREE_BASE_COMMIT } : {}),
|
|
2017
1937
|
}
|
|
@@ -2095,7 +2015,7 @@ function parseLimitsHttpDomain() {
|
|
|
2095
2015
|
workspaceFileMaxBytes: optFinitePositiveEnv("WORKSPACE_FILE_MAX_BYTES") ?? 8 * 1024 * 1024,
|
|
2096
2016
|
attachmentMaxBytes: clampEnvWithWarn("ATTACHMENT_MAX_BYTES", String(32 * 1024 * 1024), LIMITS_HTTP_FLOORS.attachmentMaxBytes),
|
|
2097
2017
|
...(process.env.ATTACHMENT_MIME_ALLOWLIST
|
|
2098
|
-
? { attachmentMimeAllowlist:
|
|
2018
|
+
? { attachmentMimeAllowlist: csv("ATTACHMENT_MIME_ALLOWLIST").map((s) => s.toLowerCase()) }
|
|
2099
2019
|
: {}),
|
|
2100
2020
|
attachmentUnboundTtlMs: clampEnvWithWarn("ATTACHMENT_UNBOUND_TTL_MS", String(24 * 3600 * 1000), LIMITS_HTTP_FLOORS.attachmentUnboundTtlMs),
|
|
2101
2021
|
infraCostRates: {
|
|
@@ -2125,7 +2045,7 @@ function parseLimitsHttpDomain() {
|
|
|
2125
2045
|
toolResultTtlSec: (() => {
|
|
2126
2046
|
const ttl = numEnv("TOOL_RESULT_TTL_SEC", "86400");
|
|
2127
2047
|
if (ttl <= 0) {
|
|
2128
|
-
throw new Error(`env TOOL_RESULT_TTL_SEC=${ttl} must be > 0 — it is the age (seconds) after which an offloaded tool result is reaped, so 0 or less puts the cutoff at or after now and every reaper tick would delete ALL of them; there is no "off": set a larger value to keep results longer (the
|
|
2048
|
+
throw new Error(`env TOOL_RESULT_TTL_SEC=${ttl} must be > 0 — it is the age (seconds) after which an offloaded tool result is reaped, so 0 or less puts the cutoff at or after now and every reaper tick would delete ALL of them; there is no "off": set a larger value to keep results longer (the web-admin refuses the same value)`);
|
|
2129
2049
|
}
|
|
2130
2050
|
return ttl;
|
|
2131
2051
|
})(),
|
|
@@ -2182,15 +2102,15 @@ function parseGitApiKind(raw, baseUrl) {
|
|
|
2182
2102
|
}
|
|
2183
2103
|
function parseIntegrationsDomain(ctx) {
|
|
2184
2104
|
const { requirePrincipal, configProvider } = ctx;
|
|
2185
|
-
const
|
|
2186
|
-
const
|
|
2187
|
-
const
|
|
2188
|
-
const
|
|
2105
|
+
const baseUrl = parseCenterBaseUrl(WEB_ADMIN_ENV.url, process.env[WEB_ADMIN_ENV.url], `It is the center base every config pull, fleet and lease request is sent to; setting it selects the center as the config source.`);
|
|
2106
|
+
const liveBaseUrl = parseCenterBaseUrl(WEB_ADMIN_ENV.liveUrl, process.env[WEB_ADMIN_ENV.liveUrl], `It is the center base the fleet liveness endpoints (heartbeat, serving lease) are sent to; unset it to send them to ${WEB_ADMIN_ENV.url}.`);
|
|
2107
|
+
const webBaseUrl = parseCenterBaseUrl(WEB_ADMIN_ENV.webUrl, process.env[WEB_ADMIN_ENV.webUrl], `It is the center's web console base this engine reports on GET /health (center.webBaseUrl); unset it if the center has no web console to link to.`);
|
|
2108
|
+
const webAdmin = baseUrl !== undefined ? parseWebAdmin(baseUrl, requirePrincipal, liveBaseUrl, webBaseUrl) : undefined;
|
|
2189
2109
|
const fleetGeneration = parseFleetGeneration(process.env.FLEET_GENERATION);
|
|
2190
2110
|
const fleetAdvertiseAddress = parseFleetAdvertiseAddress(process.env.FLEET_ADVERTISE_ADDRESS);
|
|
2191
|
-
fleetFenceLaneOf({ ...fleetGeneration,
|
|
2111
|
+
fleetFenceLaneOf({ ...fleetGeneration, webAdmin, ...fleetAdvertiseAddress });
|
|
2192
2112
|
return {
|
|
2193
|
-
pluginsAllowHosts: (process.env.PLUGINS_ALLOW_HOSTS ?? "github.com")
|
|
2113
|
+
pluginsAllowHosts: csvOf(process.env.PLUGINS_ALLOW_HOSTS ?? "github.com"),
|
|
2194
2114
|
configBootFetchBudgetMs: clampEnvWithWarn("CONFIG_BOOT_FETCH_BUDGET_MS", "1500", 0),
|
|
2195
2115
|
gitApiBaseUrl: process.env.GIT_API_BASEURL,
|
|
2196
2116
|
gitApiToken: process.env.GIT_API_TOKEN,
|
|
@@ -2198,7 +2118,7 @@ function parseIntegrationsDomain(ctx) {
|
|
|
2198
2118
|
defaultScenario: env("DEFAULT_SCENARIO", "code"),
|
|
2199
2119
|
skillsDir: env("SKILLS_DIR", defaultSkillsDir()),
|
|
2200
2120
|
centerCredentialRenewLeadMs: parseCenterCredentialRenewLeadMs(process.env.CENTER_CREDENTIAL_RENEW_LEAD_MS),
|
|
2201
|
-
|
|
2121
|
+
webAdmin,
|
|
2202
2122
|
fleetLeaseFailClosed: parseFleetLeaseFailClosed(process.env.FLEET_LEASE_FAIL_CLOSED, requirePrincipal),
|
|
2203
2123
|
...fleetGeneration,
|
|
2204
2124
|
fleetScope: parseFleetScope(process.env.FLEET_SCOPE),
|
|
@@ -2256,9 +2176,9 @@ export function fleetFenceLaneOf(cfg) {
|
|
|
2256
2176
|
return undefined;
|
|
2257
2177
|
const laneConfigured = centerLaneConfigured(cfg);
|
|
2258
2178
|
if (laneConfigured && cfg.fleetAdvertiseAddress !== undefined)
|
|
2259
|
-
return { center: cfg.
|
|
2179
|
+
return { center: cfg.webAdmin, generation };
|
|
2260
2180
|
const missing = [
|
|
2261
|
-
...(laneConfigured ? [] : [`the center lane (
|
|
2181
|
+
...(laneConfigured ? [] : [`the center lane (${WEB_ADMIN_ENV.url} + ${WEB_ADMIN_ENV.token} or ${WEB_ADMIN_ENV.tokenFile} + ${WEB_ADMIN_ENV.worker})`]),
|
|
2262
2182
|
...(cfg.fleetAdvertiseAddress === undefined ? ["the announce address (FLEET_ADVERTISE_ADDRESS)"] : []),
|
|
2263
2183
|
];
|
|
2264
2184
|
throw fleetEnvRefusal("member_unfenced", `fleet member cannot be fenced — env FLEET_GENERATION=${JSON.stringify(generation)} makes this engine a fleet member, ` +
|
|
@@ -2293,15 +2213,15 @@ function parseCenterBaseUrl(name, raw, role) {
|
|
|
2293
2213
|
throw new Error(`${refusal}. ${role}`);
|
|
2294
2214
|
return raw;
|
|
2295
2215
|
}
|
|
2296
|
-
function
|
|
2297
|
-
const worker = process.env.
|
|
2216
|
+
function parseWebAdmin(baseUrl, requirePrincipal, liveBaseUrl, webBaseUrl) {
|
|
2217
|
+
const worker = process.env[WEB_ADMIN_ENV.worker] || undefined;
|
|
2298
2218
|
const declared = readCenterCredentialDeclaration();
|
|
2299
2219
|
return {
|
|
2300
2220
|
baseUrl,
|
|
2301
2221
|
...(liveBaseUrl !== undefined ? { liveBaseUrl } : {}),
|
|
2302
2222
|
...(webBaseUrl !== undefined ? { webBaseUrl } : {}),
|
|
2303
2223
|
credential: createCenterCredentialSource(declared.from === "file" ? { ...declared, multiTenant: requirePrincipal } : declared, worker),
|
|
2304
|
-
dryRun: boolEnv(
|
|
2224
|
+
dryRun: boolEnv(WEB_ADMIN_ENV.dryRun, false),
|
|
2305
2225
|
worker,
|
|
2306
2226
|
};
|
|
2307
2227
|
}
|
|
@@ -2388,7 +2308,7 @@ const STORE_GROUP_KEYS = [
|
|
|
2388
2308
|
];
|
|
2389
2309
|
const MODEL_PLANE_GROUP_KEYS = [
|
|
2390
2310
|
"gatewayBaseUrl", "gatewayApiKey", "gatewayFallbackUrls", "gatewayMaxRetries", "anthropic", "resilience", "model", "envModel", "models",
|
|
2391
|
-
"modelApiKeyEnv", "modelApiKeys", "modelRefusals", "modelQuotaWeights", "tiers", "projects", "roles", "
|
|
2311
|
+
"modelApiKeyEnv", "modelApiKeys", "modelRefusals", "droppedCatalogEntries", "modelQuotaWeights", "tiers", "projects", "roles", "atMention", "cascadeLadder", "degrade",
|
|
2392
2312
|
];
|
|
2393
2313
|
const APPROVAL_GROUP_KEYS = [
|
|
2394
2314
|
"approvalRequire", "approvalDeny", "approvalTimeoutSec", "approvalAutoBudget", "approvalNeverAuto", "approvalGrant",
|
|
@@ -2428,7 +2348,7 @@ const LIMITS_HTTP_GROUP_KEYS = [
|
|
|
2428
2348
|
const OBSERVABILITY_GROUP_KEYS = ["metricsToken", "traceToken", "toolTrace", "traceThinking", "logLevel", "otel"];
|
|
2429
2349
|
const INTEGRATIONS_GROUP_KEYS = [
|
|
2430
2350
|
"pluginsAllowHosts", "mcpServers", "a2aPeers", "a2aServe", "configBootFetchBudgetMs", "gitApiBaseUrl", "gitApiToken", "gitApiKind", "defaultScenario",
|
|
2431
|
-
"skillsDir", "centerCredentialRenewLeadMs", "
|
|
2351
|
+
"skillsDir", "centerCredentialRenewLeadMs", "webAdmin", "fleetLeaseFailClosed", "fleetGeneration", "fleetScope", "fleetAdvertiseAddress", "fleetLeaseOutageMaxMs", "configProvider", "configLocalDir",
|
|
2432
2352
|
];
|
|
2433
2353
|
export const CONFIG_GROUP_KEYS = {
|
|
2434
2354
|
store: STORE_GROUP_KEYS,
|
|
@@ -2490,6 +2410,10 @@ export function loadConfig() {
|
|
|
2490
2410
|
const limitsHttp = parseLimitsHttpDomain();
|
|
2491
2411
|
const observability = parseObservabilityDomain();
|
|
2492
2412
|
const integrations = parseIntegrationsDomain({ requirePrincipal, configProvider });
|
|
2413
|
+
const centerIdentity = centerIdentityRefusal({ authBridgeIssuer: auth.authBridgeIssuer, webAdmin: integrations.webAdmin });
|
|
2414
|
+
if (centerIdentity !== undefined) {
|
|
2415
|
+
throw new Error(centerIdentity);
|
|
2416
|
+
}
|
|
2493
2417
|
const { directApprovalDoor, durableApproval: dgDurable, approvalHmacKeys: dgHmacKeys } = approval;
|
|
2494
2418
|
const { principalJwtPubkeys, principalJwtIss, principalJwtAud, operatorPrincipals: dgOperators, authTokens } = auth;
|
|
2495
2419
|
const directDoorActive = directApprovalDoor && dgDurable && dgHmacKeys.length > 0 && principalJwtPubkeys.length > 0 && !!principalJwtIss && !!principalJwtAud;
|
|
@@ -2527,15 +2451,9 @@ export function loadConfig() {
|
|
|
2527
2451
|
throw new Error(laneRequiredRefusal);
|
|
2528
2452
|
}
|
|
2529
2453
|
{
|
|
2530
|
-
const
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
gatewayFallbackUrls: modelPlane.gatewayFallbackUrls,
|
|
2534
|
-
anthropic: modelPlane.anthropic,
|
|
2535
|
-
models: envLaneDispatchable ? modelPlane.models : {},
|
|
2536
|
-
});
|
|
2537
|
-
if (refusal !== undefined) {
|
|
2538
|
-
throw new Error(refusal);
|
|
2454
|
+
const routeGap = judgeModelRouteGap(process.env, { envLaneDispatchable: !isRosterGateArmed(integrations.webAdmin) });
|
|
2455
|
+
if (routeGap.gap !== "none") {
|
|
2456
|
+
throw new Error(routeGap.reason);
|
|
2539
2457
|
}
|
|
2540
2458
|
}
|
|
2541
2459
|
EXEC_LANE_NOTICE = buildExecLaneNotice(orchestration.remoteExec);
|
|
@@ -144,7 +144,7 @@ export declare function laneRequiredEnv(lane: RemoteExecProvider): readonly stri
|
|
|
144
144
|
*
|
|
145
145
|
* 🔴 病(S-1008,test d327-g6-engine-7112 OBS-4 / OBS-5;2026-10-03 亲核):修前**两份句子**。运行期真拒启的是 `config.ts` 手写 throw
|
|
146
146
|
* (点名 `REQUIRE_EXECUTION_LANE` / `REMOTE_EXEC` + 修法,用户在 stderr 读到的就是它);注册表条目另写了一句短的
|
|
147
|
-
* 「the deployment asked to refuse this state」,而它只在 `
|
|
147
|
+
* 「the deployment asked to refuse this state」,而它只在 `web-admin-client/stage-limits.ts` 的全表校验里被调 —— 候选视图只装
|
|
148
148
|
* `BATCH1_LIMIT_KEYS` 的限额键,带不上这两键 ⇒ 对本条恒 `next === live`,**那一句没有任何读者**(test 六个拒启格 stderr 里零命中)。
|
|
149
149
|
* 改一份另一份不跟。现形:boot 的 throw 与注册表条目的 `check` **都**调本函数 —— 一只判据、一句话,没有第二份文本可漂。
|
|
150
150
|
*
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* · `worker` / `expectedGeneration`:缺席对缺席(非 fleet 成员没有代际,不带 `expectedGeneration` 的请求是单机形,不是通配)。
|
|
22
22
|
* · `instanceId`:请求带了才比(它是引擎每进程自铸的身份,`/health` 上可读);「点名的是不是别的进程」与 run 行同一只判据
|
|
23
23
|
* `runProvenElsewhere`。
|
|
24
|
-
* 引擎自己的 worker / instanceId 读不出 ⇒ 带了这一项的请求不符(认不出自己就不认任何点名;没配 `
|
|
24
|
+
* 引擎自己的 worker / instanceId 读不出 ⇒ 带了这一项的请求不符(认不出自己就不认任何点名;没配 `SEMA_WEB_ADMIN_WORKER` 的引擎因此
|
|
25
25
|
* 只能用停止信号排空)。
|
|
26
26
|
* 5. **进入那一拍让出在飞**:本副本可抢占的在飞腿经 core `TaskSpec.preemptSignal` 让出(在下一个干净的回合边界耐久停驻,
|
|
27
27
|
* `resource_limit` / `preempt`;不合格的腿上 core 静默不动,等到期限硬停 —— 既有 `crashed` 臂);活的审批卡按断连同路改路耐久停驻
|