@sema-agent/server 4.3.0 → 5.0.1
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/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/USAGE.md +16 -16
- package/dist/approval-hmac.js +1 -1
- package/dist/approval.d.ts +17 -37
- package/dist/approval.js +26 -112
- package/dist/auth-bridge.d.ts +0 -1
- package/dist/auth-bridge.js +0 -1
- package/dist/auth-keys.d.ts +1 -1
- package/dist/auth-keys.js +1 -1
- package/dist/bench/s1/run-firm.js +1 -1
- package/dist/boot/config-center.d.ts +1 -1
- package/dist/boot/config-center.js +4 -3
- package/dist/boot/reapers.d.ts +1 -2
- package/dist/boot/reapers.js +4 -5
- package/dist/boot/resolve-spec.d.ts +1 -3
- package/dist/boot/resolve-spec.js +21 -35
- package/dist/boot/stores.js +1 -1
- package/dist/brain.js +3 -1
- package/dist/capabilities/center-prompts.d.ts +2 -3
- package/dist/capabilities/center-prompts.js +2 -3
- package/dist/capabilities/sandbox-file-send.d.ts +0 -2
- package/dist/capabilities/sandbox-file-send.js +2 -5
- package/dist/capabilities/scenarios.d.ts +2 -13
- package/dist/capabilities/scenarios.js +3 -22
- package/dist/capabilities/send-user-file-tool.js +3 -3
- package/dist/config-center/apply-effective.js +51 -13
- package/dist/config-center/types.d.ts +10 -3
- package/dist/config-provider.d.ts +1 -1
- package/dist/config-provider.js +6 -11
- package/dist/config-types.d.ts +15 -29
- package/dist/config.d.ts +28 -0
- package/dist/config.js +122 -68
- package/dist/fleet/fleet-bus.d.ts +1 -1
- package/dist/fleet/fleet-bus.js +25 -33
- package/dist/fleet-client.js +1 -1
- package/dist/http/active-run-conflict.d.ts +2 -0
- package/dist/http/active-run-conflict.js +1 -0
- package/dist/http/routes/approvals-assistant.d.ts +2 -1
- package/dist/http/routes/approvals-assistant.js +10 -96
- package/dist/http/routes/capabilities.js +6 -5
- package/dist/http/routes/fleet.js +7 -2
- package/dist/http/routes/images.js +10 -4
- package/dist/http/routes/runs.js +42 -65
- package/dist/http/routes/session-sync.d.ts +1 -1
- package/dist/http/routes/session-sync.js +2 -1
- package/dist/http/routes/tasks.js +7 -7
- package/dist/http/routes/trace-usage.js +1 -1
- package/dist/http/routes/workflows.js +3 -1
- package/dist/http/server.d.ts +1 -6
- package/dist/http/server.js +15 -10
- package/dist/http/verify-rounds.d.ts +2 -2
- package/dist/http/wire-types.d.ts +1 -1
- package/dist/images/bake-validate.d.ts +0 -22
- package/dist/images/bake-validate.js +0 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +2 -5
- package/dist/main.js +9 -10
- package/dist/memory-scope.d.ts +1 -2
- package/dist/memory-scope.js +8 -4
- package/dist/orchestration/workflow-completion-inbox.d.ts +6 -4
- package/dist/orchestration/workflow-completion-inbox.js +6 -4
- package/dist/plugins/breaker-state-sql.d.ts +2 -3
- package/dist/plugins/file-run-store.d.ts +1 -1
- package/dist/plugins/file-run-store.js +1 -1
- package/dist/plugins/image-index-sql.d.ts +0 -1
- package/dist/plugins/image-index-sql.js +0 -1
- package/dist/plugins/local-checkpoint-store.d.ts +1 -1
- package/dist/plugins/local-checkpoint-store.js +1 -1
- package/dist/plugins/memory-engine-pg.js +2 -1
- package/dist/plugins/memory-engine-tidb.js +1 -1
- package/dist/plugins/memory-engine-vector-util.d.ts +2 -3
- package/dist/plugins/memory-engine-vector-util.js +2 -3
- package/dist/plugins/memory-run-store.d.ts +2 -2
- package/dist/plugins/memory-run-store.js +1 -1
- package/dist/plugins/memory-session-policy-store.d.ts +1 -1
- package/dist/plugins/memory-session-policy-store.js +1 -1
- package/dist/plugins/memory-sync-store-pg.js +1 -1
- package/dist/plugins/pg-pool.js +8 -10
- package/dist/plugins/pg-rate-limiter.d.ts +1 -4
- package/dist/plugins/pg-rate-limiter.js +0 -1
- package/dist/plugins/roster-store-sql.d.ts +1 -3
- package/dist/plugins/roster-store-sql.js +3 -5
- package/dist/plugins/store-backend.d.ts +7 -17
- package/dist/plugins/store-backend.js +14 -30
- package/dist/plugins/tidb-pool.js +6 -30
- package/dist/plugins/workflow-journal-store-sql.d.ts +1 -1
- package/dist/plugins/workflow-journal-store-sql.js +1 -1
- package/dist/principal-jwt.js +2 -2
- package/dist/prompts-domain-validate.d.ts +4 -3
- package/dist/prompts-domain-validate.js +7 -8
- package/dist/router/route-orchestration.js +3 -3
- package/dist/run-local.js +13 -10
- package/dist/runs.js +8 -6
- package/dist/runtime-caps-resolver.d.ts +3 -2
- package/dist/runtime-caps-resolver.js +4 -4
- package/dist/runtime-governance.d.ts +4 -7
- package/dist/runtime-governance.js +12 -17
- package/dist/sealed-key.d.ts +1 -1
- package/dist/sealed-key.js +1 -1
- package/dist/security.d.ts +0 -5
- package/dist/security.js +8 -12
- package/dist/session-sync.d.ts +0 -2
- package/dist/session-sync.js +10 -17
- package/dist/spec-fields.js +6 -6
- package/dist/task-settings.d.ts +0 -27
- package/dist/task-settings.js +42 -11
- package/dist/tool-approval.d.ts +3 -3
- package/dist/tool-approval.js +10 -10
- package/dist/trace/artifacts.d.ts +11 -0
- package/dist/trace/artifacts.js +8 -19
- package/dist/trace/ledger-sink.js +7 -1
- package/dist/trace/project.d.ts +17 -0
- package/dist/trace/project.js +58 -5
- package/package.json +3 -3
- package/dist/capabilities/oa-tools.d.ts +0 -15
- package/dist/capabilities/oa-tools.js +0 -54
- package/dist/plugins/approval-store-sql.d.ts +0 -116
- package/dist/plugins/approval-store-sql.js +0 -150
- package/dist/plugins/file-workflow-journal-store.d.ts +0 -12
- package/dist/plugins/file-workflow-journal-store.js +0 -12
- package/dist/plugins/pg-approval-store.d.ts +0 -9
- package/dist/plugins/pg-approval-store.js +0 -9
- package/dist/plugins/pg-breaker-state.d.ts +0 -8
- package/dist/plugins/pg-breaker-state.js +0 -8
- package/dist/plugins/pg-checkpoint-store.d.ts +0 -10
- package/dist/plugins/pg-checkpoint-store.js +0 -10
- package/dist/plugins/pg-file-snapshot-store.d.ts +0 -8
- package/dist/plugins/pg-file-snapshot-store.js +0 -8
- package/dist/plugins/pg-image-bake.d.ts +0 -12
- package/dist/plugins/pg-image-bake.js +0 -11
- package/dist/plugins/pg-image-index.d.ts +0 -12
- package/dist/plugins/pg-image-index.js +0 -11
- package/dist/plugins/pg-outcome-ledger.d.ts +0 -12
- package/dist/plugins/pg-outcome-ledger.js +0 -11
- package/dist/plugins/pg-resume-anchor-store.d.ts +0 -7
- package/dist/plugins/pg-resume-anchor-store.js +0 -7
- package/dist/plugins/pg-run-store.d.ts +0 -9
- package/dist/plugins/pg-run-store.js +0 -9
- package/dist/plugins/pg-session-policy-store.d.ts +0 -7
- package/dist/plugins/pg-session-policy-store.js +0 -7
- package/dist/plugins/pg-session-store.d.ts +0 -12
- package/dist/plugins/pg-session-store.js +0 -12
- package/dist/plugins/pg-tool-result-store.d.ts +0 -9
- package/dist/plugins/pg-tool-result-store.js +0 -9
- package/dist/plugins/pg-workflow-journal-store.d.ts +0 -9
- package/dist/plugins/pg-workflow-journal-store.js +0 -9
- package/dist/plugins/pg-workflow-run-store.d.ts +0 -9
- package/dist/plugins/pg-workflow-run-store.js +0 -9
- package/dist/plugins/tidb-approval-store.d.ts +0 -8
- package/dist/plugins/tidb-approval-store.js +0 -8
- package/dist/plugins/tidb-breaker-state.d.ts +0 -7
- package/dist/plugins/tidb-breaker-state.js +0 -7
- package/dist/plugins/tidb-checkpoint-store.d.ts +0 -9
- package/dist/plugins/tidb-checkpoint-store.js +0 -9
- package/dist/plugins/tidb-file-snapshot-store.d.ts +0 -8
- package/dist/plugins/tidb-file-snapshot-store.js +0 -8
- package/dist/plugins/tidb-image-bake.d.ts +0 -12
- package/dist/plugins/tidb-image-bake.js +0 -11
- package/dist/plugins/tidb-image-index.d.ts +0 -12
- package/dist/plugins/tidb-image-index.js +0 -11
- package/dist/plugins/tidb-outcome-ledger.d.ts +0 -12
- package/dist/plugins/tidb-outcome-ledger.js +0 -12
- package/dist/plugins/tidb-resume-anchor-store.d.ts +0 -7
- package/dist/plugins/tidb-resume-anchor-store.js +0 -7
- package/dist/plugins/tidb-run-store.d.ts +0 -10
- package/dist/plugins/tidb-run-store.js +0 -9
- package/dist/plugins/tidb-session-policy-store.d.ts +0 -7
- package/dist/plugins/tidb-session-policy-store.js +0 -7
- package/dist/plugins/tidb-tool-result-store.d.ts +0 -8
- package/dist/plugins/tidb-tool-result-store.js +0 -10
- package/dist/plugins/tidb-workflow-journal-store.d.ts +0 -9
- package/dist/plugins/tidb-workflow-journal-store.js +0 -9
- package/dist/plugins/tidb-workflow-run-store.d.ts +0 -10
- package/dist/plugins/tidb-workflow-run-store.js +0 -10
- package/dist/plugins/workflow-journal-limits.d.ts +0 -12
- package/dist/plugins/workflow-journal-limits.js +0 -12
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
import { realpathSync } from "node:fs";
|
|
21
21
|
import { join } from "node:path";
|
|
22
22
|
import { NodeExecutionEnv, QUESTION_AWAITS_RESUME, combinePolicies, createAllowDenyPolicy, createDurableQuestionPolicy, expandTiers, tightenTaskSpec } from "@sema-agent/core";
|
|
23
|
-
import {
|
|
23
|
+
import { createDurableAskPolicy } from "../approval.js";
|
|
24
24
|
import { cappedCeiling } from "../budget.js";
|
|
25
25
|
import { centerPromptProvider, centerIdentityAssembled } from "../capabilities/center-prompts.js";
|
|
26
26
|
import { SessionEnvironmentSelection, selectEnvironmentTool } from "../capabilities/select-environment-tool.js";
|
|
@@ -39,7 +39,8 @@ import { resourceSuspendOptIn } from "../resource-suspend.js";
|
|
|
39
39
|
import { isIsolatedExecEnv, routeServiceTask, supPostureOverrides } from "../router/route-orchestration.js";
|
|
40
40
|
import { gateExecutionLane } from "../runtime-caps-resolver.js";
|
|
41
41
|
import { applyRuntimeGovernance, stripDelegationTools } from "../runtime-governance.js";
|
|
42
|
-
import { HttpError,
|
|
42
|
+
import { HttpError, encodeCheckpointScope } from "../security.js";
|
|
43
|
+
import { memorySpecForRequest } from "../memory-scope.js";
|
|
43
44
|
import { mcpForScenario } from "../config-center/facade.js";
|
|
44
45
|
import { normalizeAttachments, normalizeResilience, normalizeResumeAtMode, normalizeSuggestNextPrompts, promptProfileFromBody, resolveTaskLimits, retainBackgroundProcessesFromBody, taskAgentsSpecFragment, toolNameListFromBody } from "../spec-fields.js";
|
|
45
46
|
import { cwdHonored, effectiveHostWorkspace, inProcessSingleUserLane, isValidCwd, parseAdditionalDirectories, satisfiedByProcessCwd, shellEnvMismatchCount } from "../task-cwd.js";
|
|
@@ -48,7 +49,7 @@ import { MAX_SETTINGS_OUTPUT_STYLE_CHARS, acceptAppendSystemPrompt, applyTaskSet
|
|
|
48
49
|
import { enableForkFromBody, normalizeRetainSubagentSessions, selfOrchestrationFromBody } from "../task-workflow.js";
|
|
49
50
|
import { redactSecrets } from "../trace/redact.js";
|
|
50
51
|
export function createResolveSpec(ctx) {
|
|
51
|
-
const { config, logger, metrics, localRoot, scenarios, principalCaps, centerRuntimeCapsResolver, getCenterPrompts, getKeyResolver, taskAttachmentStore, perSessionCwd, setSessionCwd, setSessionShellEnv, hookLlm, hookAgent, fleetBus, hookWakeBus, resumeAnchorStore, ownerAware, taskLimitCaps, taskTimeoutSec, selectEnvTool, sendUserFileToolSpec, memoryEngine, durableEnabled, approvalExemptionStore,
|
|
52
|
+
const { config, logger, metrics, localRoot, scenarios, principalCaps, centerRuntimeCapsResolver, getCenterPrompts, getKeyResolver, taskAttachmentStore, perSessionCwd, setSessionCwd, setSessionShellEnv, hookLlm, hookAgent, fleetBus, hookWakeBus, resumeAnchorStore, ownerAware, taskLimitCaps, taskTimeoutSec, selectEnvTool, sendUserFileToolSpec, memoryEngine, durableEnabled, approvalExemptionStore, singleUserAutoAcceptBaseline, checkpointStore, deploymentHooks, imageIndex, perTaskImage, sessionEnvSelection, } = ctx;
|
|
52
53
|
// Deployment-owned mapping. Tools/prompt/skills come from the selected scenario (assembled once,
|
|
53
54
|
// bound per request); identity/session/policy stay server-side. Never taken from the request body.
|
|
54
55
|
// design/158 A8:从 createHttpServer 实参里提出来(原地占该字面量 1,093 行中的 967 行)——
|
|
@@ -692,8 +693,9 @@ export function createResolveSpec(ctx) {
|
|
|
692
693
|
// provider 才不会各看一版(TOCTOU:门判安全、pick 到已组装包=core 侧静默丢 rider 复活)。
|
|
693
694
|
promptProvider: centerDecls ? centerPromptProvider(centerDecls, scenarioName) : cap.promptProvider,
|
|
694
695
|
// F4: high-risk write approval gate. DURABLE (design/45, opt-in): the gated `ask` SUSPENDS the task
|
|
695
|
-
// (durable checkpoint, resumable on any replica).
|
|
696
|
-
//
|
|
696
|
+
// (durable checkpoint, resumable on any replica). [2354]/[2356] A-5(5.0.0): the legacy POLL gate
|
|
697
|
+
// (createOaApprovalPolicy over ApprovalStore pending rows) is retired — durable is the ONLY gate; an
|
|
698
|
+
// operator with approval intent but no checkpointStore falls to `undefined` (core's UNGATED warning).
|
|
697
699
|
// Durable ask (TC-5.4, core 1.95): in durable mode an AskUserQuestion call suspends like an F4 gate —
|
|
698
700
|
// the question policy adjudicates it `ask`, the operator answers out-of-band, and the resume carries
|
|
699
701
|
// the QuestionAnswer (server.ts `body.answer` → onQuestion closure). Suspend side mounts the tool with
|
|
@@ -711,36 +713,20 @@ export function createResolveSpec(ctx) {
|
|
|
711
713
|
}
|
|
712
714
|
: {}),
|
|
713
715
|
}))
|
|
714
|
-
:
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
: {}),
|
|
729
|
-
})
|
|
730
|
-
: singleUserAutoAcceptBaseline
|
|
731
|
-
// 🔴 (live finding: single-user host-lane Bash ran UNGATED, no adjudication): a
|
|
732
|
-
// single-user turnkey worker with NO expressed gate intent previously left `toolPolicy` UNDEFINED →
|
|
733
|
-
// core's write-capable hand tools mount UNADJUDICATED (core error-logs it every task; host lane has NO
|
|
734
|
-
// sandbox to fall back on). CC's trust model is auto-accept, but the GATE MECHANISM must be PRESENT
|
|
735
|
-
// (core 原则: "机制留、默认可更宽 auto-accept"). So wire an adjudicated auto-accept BASELINE
|
|
736
|
-
// (`createAllowDenyPolicy({})` = a present, effect-aware policy that allows all): satisfies core's
|
|
737
|
-
// `hasEffectAwareGate`, restores observability + a hook/tighten point, and the operator STILL tightens
|
|
738
|
-
// irreversible ops via `AUTONOMY` / `commandPolicy` (layered TIGHTEN-ONLY by applyRuntimeGovernance).
|
|
739
|
-
// Interactive approval routed to the shell HITL = follow-on. 🔴 `singleUserAutoAcceptBaseline` requires
|
|
740
|
-
// ZERO gate intent — a single-user op who SET approval flags but wired no store falls to `undefined`
|
|
741
|
-
// (core warns = real misconfig, not masked); multi-tenant likewise stays `undefined` (approval required).
|
|
742
|
-
? createAllowDenyPolicy({})
|
|
743
|
-
: undefined,
|
|
716
|
+
: singleUserAutoAcceptBaseline
|
|
717
|
+
// 🔴 (live finding: single-user host-lane Bash ran UNGATED, no adjudication): a
|
|
718
|
+
// single-user turnkey worker with NO expressed gate intent previously left `toolPolicy` UNDEFINED →
|
|
719
|
+
// core's write-capable hand tools mount UNADJUDICATED (core error-logs it every task; host lane has NO
|
|
720
|
+
// sandbox to fall back on). CC's trust model is auto-accept, but the GATE MECHANISM must be PRESENT
|
|
721
|
+
// (core 原则: "机制留、默认可更宽 auto-accept"). So wire an adjudicated auto-accept BASELINE
|
|
722
|
+
// (`createAllowDenyPolicy({})` = a present, effect-aware policy that allows all): satisfies core's
|
|
723
|
+
// `hasEffectAwareGate`, restores observability + a hook/tighten point, and the operator STILL tightens
|
|
724
|
+
// irreversible ops via `AUTONOMY` / `commandPolicy` (layered TIGHTEN-ONLY by applyRuntimeGovernance).
|
|
725
|
+
// Interactive approval routed to the shell HITL = follow-on. 🔴 `singleUserAutoAcceptBaseline` requires
|
|
726
|
+
// ZERO gate intent — a single-user op who SET approval flags but wired no store falls to `undefined`
|
|
727
|
+
// (core warns = real misconfig, not masked); multi-tenant likewise stays `undefined` (approval required).
|
|
728
|
+
? createAllowDenyPolicy({})
|
|
729
|
+
: undefined,
|
|
744
730
|
// Durable suspend needs both the store (here, per-task) and the opt-in scope key (multi-tenant =
|
|
745
731
|
// principal; "_" when auth is off). core suspends on a policy `ask` only when these are present.
|
|
746
732
|
...(durableEnabled
|
package/dist/boot/stores.js
CHANGED
|
@@ -27,7 +27,7 @@ import { LocalTaskAttachmentStore } from "../plugins/local-task-attachment-store
|
|
|
27
27
|
import { PgTaskAttachmentStore, TiDBTaskAttachmentStore, ensurePgTaskAttachmentSchema, ensureTiDBTaskAttachmentSchema } from "../plugins/task-attachment-store.js";
|
|
28
28
|
import { createSessionStore } from "../plugins/session-store.js";
|
|
29
29
|
import { assertCloudSnapshotBlobPosture, openStoreBackendWithFallback } from "../plugins/store-backend.js";
|
|
30
|
-
import { memoryEngineBackendFor, memoryEngineRemoteLanePosture } from "../
|
|
30
|
+
import { memoryEngineBackendFor, memoryEngineRemoteLanePosture } from "../memory-scope.js";
|
|
31
31
|
export async function openStores(ctx) {
|
|
32
32
|
const { config, logger, metrics, localRoot } = ctx;
|
|
33
33
|
// One shared SQL store backend for L1 + L2 (TiDB/MySQL or PostgreSQL per DB_BACKEND). Owned here.
|
package/dist/brain.js
CHANGED
|
@@ -183,7 +183,9 @@ export function createBrain(config, deps = {}) {
|
|
|
183
183
|
fetchImpl,
|
|
184
184
|
...timeouts,
|
|
185
185
|
});
|
|
186
|
-
|
|
186
|
+
// core 5.1.0([2390]②):chain-of-one 链形;downgradeOn 缺席时 core 默认含 server_error(默认门
|
|
187
|
+
// 变宽)——MODEL_DEGRADE_ON 是运维收窄旋钮,词表验门在 config.ts parseDegradeOn。
|
|
188
|
+
brain = createDegradingBrain({ primary: brain, fallbacks: [{ brain: fallback, model: fallbackModel }], downgradeOn: config.degrade.downgradeOn });
|
|
187
189
|
}
|
|
188
190
|
}
|
|
189
191
|
return brain;
|
|
@@ -22,9 +22,8 @@
|
|
|
22
22
|
import { type PromptProvider, type PublishedPromptArtifactEnvelope } from "@sema-agent/core";
|
|
23
23
|
import { type EffectiveCenterPrompts, type PromptsDomainFaces } from "../prompts-domain-validate.js";
|
|
24
24
|
/** 判形半场(validateCenterPrompts/validatePromptsDomain/CORE_ENGINE_VERSION 及两 interface)已下沉到
|
|
25
|
-
* 中立叶子 `src/prompts-domain-validate.ts`(design/158 S6
|
|
26
|
-
*
|
|
27
|
-
export { validateCenterPrompts, validatePromptsDomain, CORE_ENGINE_VERSION, type EffectiveCenterPrompts, type PromptsDomainFaces } from "../prompts-domain-validate.js";
|
|
25
|
+
* 中立叶子 `src/prompts-domain-validate.ts`(design/158 S6);消费者直引真源([2354] 兼容面全清,
|
|
26
|
+
* 此处兼容 re-export 已删)。 */
|
|
28
27
|
/** [985]b / [1285] — §9.4 by-digest 补拉组合店:local miss ⇒ fetchRaw(digest) 从 center 拉 envelope ⇒
|
|
29
28
|
* core verifyPromptArtifact 全管线 + **回验「拿到的=要的」digest 逐位**(center 答非所问=丢弃)⇒
|
|
30
29
|
* best-effort 回写 inner(下次直命中)。任何失败=undefined(诚实缺席,fail-loud 归 core 的
|
|
@@ -23,9 +23,8 @@ import { verifyPromptArtifact } from "@sema-agent/core";
|
|
|
23
23
|
import { CORE_ENGINE_VERSION } from "../prompts-domain-validate.js";
|
|
24
24
|
import { SHA256_HEX_RE } from "../digest-form.js";
|
|
25
25
|
/** 判形半场(validateCenterPrompts/validatePromptsDomain/CORE_ENGINE_VERSION 及两 interface)已下沉到
|
|
26
|
-
* 中立叶子 `src/prompts-domain-validate.ts`(design/158 S6
|
|
27
|
-
*
|
|
28
|
-
export { validateCenterPrompts, validatePromptsDomain, CORE_ENGINE_VERSION } from "../prompts-domain-validate.js";
|
|
26
|
+
* 中立叶子 `src/prompts-domain-validate.ts`(design/158 S6);消费者直引真源([2354] 兼容面全清,
|
|
27
|
+
* 此处兼容 re-export 已删)。 */
|
|
29
28
|
/** [985]b / [1285] — §9.4 by-digest 补拉组合店:local miss ⇒ fetchRaw(digest) 从 center 拉 envelope ⇒
|
|
30
29
|
* core verifyPromptArtifact 全管线 + **回验「拿到的=要的」digest 逐位**(center 答非所问=丢弃)⇒
|
|
31
30
|
* best-effort 回写 inner(下次直命中)。任何失败=undefined(诚实缺席,fail-loud 归 core 的
|
|
@@ -35,7 +35,6 @@
|
|
|
35
35
|
*/
|
|
36
36
|
import type { ExecutionEnv, ExecutionEnvFactory } from "@sema-agent/core";
|
|
37
37
|
import type { IssuedFileLink, PreparedDirectUpload } from "../plugins/send-user-file.js";
|
|
38
|
-
import { shellQuote as shq } from "../plugins/remote-shell.js";
|
|
39
38
|
/** Leak backstop (codex review HIGH): core skips destroy on suspend/review paths and a crash may skip it
|
|
40
39
|
* entirely — the suspendVM wrap covers the common case, this bound covers the rest. Far above any real
|
|
41
40
|
* per-replica concurrency. 修6: at the cap the registry REFUSES the new registration instead of FIFO-evicting
|
|
@@ -92,7 +91,6 @@ export declare class TaskEnvRegistry {
|
|
|
92
91
|
* adb/local-docker remain a follow-on).
|
|
93
92
|
*/
|
|
94
93
|
export declare function sandboxSendLaneEnabled(provider: string | undefined, requirePrincipal: boolean): boolean;
|
|
95
|
-
export { shq };
|
|
96
94
|
/** Strip the capability URL (and any SigV4 signature) from text before it reaches an error/log — including
|
|
97
95
|
* the percent-encoded forms an adapter may echo (the k8s exec transport carries the command in a request
|
|
98
96
|
* URI, so an error can quote the URL re-encoded; codex review MED). */
|
|
@@ -139,11 +139,8 @@ export function sandboxSendLaneEnabled(provider, requirePrincipal) {
|
|
|
139
139
|
return requirePrincipal !== true;
|
|
140
140
|
return false;
|
|
141
141
|
}
|
|
142
|
-
//
|
|
143
|
-
//
|
|
144
|
-
// re-exported alias — not a plain call-through rename — because two test files import `shq` by name from
|
|
145
|
-
// this module.
|
|
146
|
-
export { shq };
|
|
142
|
+
// [2354] clay 令兼容面全清:R10 曾留的 `export { shq }` 兼容转口已删——quoting 唯一真源=
|
|
143
|
+
// remote-shell.ts 的 shellQuote(原先仅有的两个消费者是测试文件,已改从真源导入)。
|
|
147
144
|
/** Strip the capability URL (and any SigV4 signature) from text before it reaches an error/log — including
|
|
148
145
|
* the percent-encoded forms an adapter may echo (the k8s exec transport carries the command in a request
|
|
149
146
|
* URI, so an error can quote the URL re-encoded; codex review MED). */
|
|
@@ -45,17 +45,6 @@ export interface ScenarioDeps {
|
|
|
45
45
|
webFetchSummarize?: NonNullable<NonNullable<WebFetchConfig["summarize"]>>;
|
|
46
46
|
metrics?: Metrics;
|
|
47
47
|
logger?: Logger;
|
|
48
|
-
/** OA backend coordinates for the `oa` scenario (read /api/v1, write /api/assets). */
|
|
49
|
-
oaApiBaseUrl?: string;
|
|
50
|
-
oaServiceToken?: string;
|
|
51
|
-
/** 可选:`oa` 场景注入"开 Gitea issue"工具(OA AI 请求#5);repo/token/labels 固定,模型只填 title/body。 */
|
|
52
|
-
oaIssue?: {
|
|
53
|
-
baseUrl: string;
|
|
54
|
-
owner: string;
|
|
55
|
-
repo: string;
|
|
56
|
-
token: string;
|
|
57
|
-
defaultLabels?: number[];
|
|
58
|
-
};
|
|
59
48
|
/**
|
|
60
49
|
* When true, the `default` scenario carries the Sema product identity (see {@link semaIdentityProvider}).
|
|
61
50
|
* Set by the local/TOC deployment (CONFIG_PROVIDER=local / run-local) so the local engine answers "who
|
|
@@ -159,8 +148,8 @@ export interface ScenarioDetail {
|
|
|
159
148
|
promptSummary: string;
|
|
160
149
|
enabled: boolean;
|
|
161
150
|
}
|
|
162
|
-
/**
|
|
163
|
-
* fail-loud 语义(缺 GIT_API
|
|
151
|
+
/** 内建五场景详情。default/autonomous/team 工厂对良性请求无副作用可真调(拿真实工具名单);code-review/scan 是
|
|
152
|
+
* fail-loud 语义(缺 GIT_API 配置/principal 即 throw)→ 探针失败落静态表兜底(表↔工厂一致性由测试锁:
|
|
164
153
|
* 测试喂 fake deps 真调工厂对账工具名)。enabled 对内建恒 true(约定②)。 */
|
|
165
154
|
export declare function builtinScenarioDetails(scenarios: Record<string, Scenario>, deps: Pick<ScenarioDeps, "brandIdentity">): Record<string, ScenarioDetail>;
|
|
166
155
|
/** center 条目详情(有效性判定与 centerScenarios 完全同款:无效条目既不进 overlay 也不进详情——
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { CODE_AGENT_PROMPT, CODE_SYSTEM_PROMPT, DEFAULT_SYSTEM_PROMPT, assembleCodeTools,
|
|
1
|
+
import { CODE_AGENT_PROMPT, CODE_SYSTEM_PROMPT, DEFAULT_SYSTEM_PROMPT, assembleCodeTools, defaultTaskRegistry } from "@sema-agent/core";
|
|
2
2
|
import { HttpError } from "../security.js";
|
|
3
3
|
import { nowTool } from "./builtin-tools.js";
|
|
4
4
|
import { GiteaClient, parseRepo, repoToolsFor } from "./repo-tools.js";
|
|
5
5
|
import { createCouncilTool, clampRounds } from "./code-review-council.js";
|
|
6
6
|
import { stablePrompt } from "./prompt.js";
|
|
7
7
|
import { createTeamTool, teamCoordinatorPrompt, getTeam, teamNames } from "./team.js";
|
|
8
|
-
import { oaTools, oaPrompt } from "./oa-tools.js";
|
|
9
8
|
import { createWebSearchBackend, webSearchConfigFromSettings } from "../plugins/web-search.js";
|
|
10
9
|
import { skillsForScenario } from "./skills.js";
|
|
11
10
|
/**
|
|
@@ -205,23 +204,6 @@ export function buildScenarios(deps) {
|
|
|
205
204
|
skills: skillsForScenario(deps.skills, "scan"),
|
|
206
205
|
};
|
|
207
206
|
},
|
|
208
|
-
oa: (req, principal) => {
|
|
209
|
-
if (!deps.oaApiBaseUrl || !deps.oaServiceToken)
|
|
210
|
-
throw new HttpError(501, "oa scenario needs OA_API_BASEURL + OA_SERVICE_TOKEN configured");
|
|
211
|
-
// OA enforces the END USER's RBAC from the forwarded principal — without one, every OA call would
|
|
212
|
-
// run unattributed. Refuse rather than silently send a null principal.
|
|
213
|
-
if (!principal)
|
|
214
|
-
throw new HttpError(401, "oa scenario requires an authenticated principal (set REQUIRE_PRINCIPAL + x-agent-principal)");
|
|
215
|
-
// 写权限的"开 issue"工具仅当配置了 OA_ISSUE_* 时注入;token/repo 固定,模型只填 title/body。
|
|
216
|
-
const issueTool = deps.oaIssue
|
|
217
|
-
? [createGiteaIssueTool({ ...deps.oaIssue, name: "open_gitea_issue", description: "把用户的 bug/需求开成 Gitea issue 报给老板。只填 title(简洁)/body(现象、影响、复现/建议)。仓库与标签由部署固定。" })]
|
|
218
|
-
: [];
|
|
219
|
-
return {
|
|
220
|
-
tools: [...oaTools({ baseUrl: deps.oaApiBaseUrl, token: deps.oaServiceToken, principal }), ...issueTool],
|
|
221
|
-
skills: skillsForScenario(deps.skills, "oa"),
|
|
222
|
-
promptProvider: oaPrompt,
|
|
223
|
-
};
|
|
224
|
-
},
|
|
225
207
|
// Multi-agent team: pick a template, the consumer (OA) injects business context, we run it.
|
|
226
208
|
// Templates resolve from the live registry (`getTeam`) = BUILTIN_TEAMS overridden/extended by the
|
|
227
209
|
// sema registry at runtime (applyEffective → registerTeams), so a team is config-driven; built-ins
|
|
@@ -246,8 +228,8 @@ export function buildScenarios(deps) {
|
|
|
246
228
|
export function selectScenario(scenarios, name) {
|
|
247
229
|
return (name && scenarios[name]) || scenarios.default;
|
|
248
230
|
}
|
|
249
|
-
/**
|
|
250
|
-
* fail-loud 语义(缺 GIT_API
|
|
231
|
+
/** 内建五场景详情。default/autonomous/team 工厂对良性请求无副作用可真调(拿真实工具名单);code-review/scan 是
|
|
232
|
+
* fail-loud 语义(缺 GIT_API 配置/principal 即 throw)→ 探针失败落静态表兜底(表↔工厂一致性由测试锁:
|
|
251
233
|
* 测试喂 fake deps 真调工厂对账工具名)。enabled 对内建恒 true(约定②)。 */
|
|
252
234
|
export function builtinScenarioDetails(scenarios, deps) {
|
|
253
235
|
const probe = (name, req, principal, fallback) => {
|
|
@@ -270,7 +252,6 @@ export function builtinScenarioDetails(scenarios, deps) {
|
|
|
270
252
|
: "core 编码完全体提示词(= code 场景;finalVerification 固定开)"),
|
|
271
253
|
"code-review": mk("code-review", "代码评审(clone-free 只读仓库工具;council=true 升多镜头评审团)", "repo-readonly", probe("code-review", { repo: "probe/probe" }, undefined, REPO_TOOLS), "评审员/评审团协调提示词(镜头分工+产出契约)"),
|
|
272
254
|
scan: mk("scan", "中性只读仓库扫描(输出契约由 objective+skills 决定)", "repo-readonly", probe("scan", { repo: "probe/probe" }, undefined, REPO_TOOLS), "无场景附加提示词(objective+center skills 拥有输出契约)"),
|
|
273
|
-
oa: mk("oa", "OA 资产运营助手(以最终用户 principal 走 OA API,RBAC+审计在 OA 侧)", "oa-api", probe("oa", {}, "probe:meta", ["oa_schema", "oa_alerts", "oa_list", "oa_get", "oa_lookup", "oa_create", "oa_update", "oa_transition"]), "OA 运营助手提示词(先 schema 后操作、写走受控流转)"),
|
|
274
255
|
team: mk("team", "多智能体团队圆桌(模板成员+synthesizer,模板可由 registry 配置)", "team", probe("team", {}, undefined, ["run_team"]), "团队协调者提示词(圆桌纪律+合成流程)"),
|
|
275
256
|
};
|
|
276
257
|
}
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
*/
|
|
25
25
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
26
26
|
import { Type } from "typebox";
|
|
27
|
-
import { builtinAgentDefinitions
|
|
27
|
+
import { builtinAgentDefinitions } from "@sema-agent/core";
|
|
28
28
|
/** Per-run ALS carrier (QuestionCoordinator pattern): run legs wrap their body via runWithContext; the tool
|
|
29
29
|
* recovers the ambient emit at execute time. No pending state, no respond face — emission is one-way. */
|
|
30
30
|
export class SendUserFileEmitter {
|
|
@@ -155,7 +155,7 @@ const READONLY_BUILTIN_AGENT_TYPES = new Set(builtinAgentDefinitions().map((d) =
|
|
|
155
155
|
* definition's name (core subagent.js); membership in core's builtin catalog ⇒ inject nothing for that spawn.
|
|
156
156
|
*/
|
|
157
157
|
export function subagentSendUserFileExtraTools(deps) {
|
|
158
|
-
const canonical =
|
|
158
|
+
const canonical = SEND_USER_FILE_TOOL_NAME; // RAW(5.0.0):本名恒 canonical,折叠面退役
|
|
159
159
|
return (ctx) => {
|
|
160
160
|
// F2: read-only builtin child (Explore/Plan) — never inject.
|
|
161
161
|
if (ctx.agentType !== undefined && READONLY_BUILTIN_AGENT_TYPES.has(ctx.agentType))
|
|
@@ -163,7 +163,7 @@ export function subagentSendUserFileExtraTools(deps) {
|
|
|
163
163
|
// F1: deployment policy gates SendUserFile (deny/ask) — withhold from ALL children (fail-closed stopgap
|
|
164
164
|
// until core propagates the parent toolPolicy into child specs). Canonical-space match (S8 discipline).
|
|
165
165
|
const gate = deps.approvalGate();
|
|
166
|
-
const gated = [...(gate.deny ?? []), ...(gate.require ?? []), ...(gate.neverAuto ?? [])].some((t) =>
|
|
166
|
+
const gated = [...(gate.deny ?? []), ...(gate.require ?? []), ...(gate.neverAuto ?? [])].some((t) => t === canonical);
|
|
167
167
|
return gated ? [] : [deps.spec];
|
|
168
168
|
};
|
|
169
169
|
}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import { isThinkingLevel } from "@sema-agent/core";
|
|
9
9
|
import { resolveActiveTiers, SEALED_BOX_ALG } from "@sema-agent/registry-core";
|
|
10
10
|
import { sealedKeyPoison } from "../sealed-key.js";
|
|
11
|
-
import { applyAutoCompactWindow, parseAutonomy } from "../config.js";
|
|
11
|
+
import { applyAutoCompactWindow, findUnmatchableToolNames, formatUnmatchableToolNames, parseAutonomy } from "../config.js";
|
|
12
12
|
import { validateCommandRules } from "../runtime-governance.js";
|
|
13
13
|
import { projectCollabToWorkflows, registerCollabWorkflows } from "../capabilities/collab-workflows.js";
|
|
14
14
|
import { registerTeams } from "../capabilities/team.js";
|
|
@@ -292,8 +292,8 @@ function stageEffective(config, eff, logger, opts) {
|
|
|
292
292
|
// → undefined = INERT). Values are catalog NAME strings (open, not enum'd); dangling bindings were already
|
|
293
293
|
// culled center-side. mutateInPlace keeps the reference RunnerDeps.tiers holds — the expansion itself happens
|
|
294
294
|
// at Runner CONSTRUCTION (core 1.265 expandTiers), so a refresh-time change is restart-to-apply like models.
|
|
295
|
-
//
|
|
296
|
-
//
|
|
295
|
+
// [2373]B-6:EffectiveConfig.models 已声明 tierGroups/activeTierGroup(types.ts)——旧「CenterModel
|
|
296
|
+
// doesn't type them」注随宽铸一起退役;resolveActiveTiers 收 registry-core 形,窄化一步即可。
|
|
297
297
|
const activeTiers = resolveActiveTiers(eff.models) ?? {};
|
|
298
298
|
// [865]①(生产实锤:面板上选了 A 模型,实际跑的是目录里的另一个)显式默认解析——enabled[0] 会被任何改变 pool 顺序的写
|
|
299
299
|
// 静默翻转,default 必须消费 wire 里已有的显式意图。解析单源 = resolveDefaultModelName(dry-run 的
|
|
@@ -316,7 +316,7 @@ function stageEffective(config, eff, logger, opts) {
|
|
|
316
316
|
// governance 切新位:治理三件优先读 governance 域(真值),runtime 旧位(双写镜像)fallback——
|
|
317
317
|
// 双写期两处逐键相等语义不变;center 撤双写后 governance 即唯一来源。限额残余(rateLimit/cost 五件)仍在 runtime。
|
|
318
318
|
const gatesView = eff.governance ? { ...eff.runtime, ...eff.governance } : eff.runtime;
|
|
319
|
-
const gates = opts.teamsOnly ? undefined : stageRuntimeGates(gatesView);
|
|
319
|
+
const gates = opts.teamsOnly ? undefined : stageRuntimeGates(gatesView, logger);
|
|
320
320
|
// Runtime governance "second baton" (center §10): autonomy + commandPolicy are per-request HOT (read live in
|
|
321
321
|
// resolveSpec), NOT baked into boot middleware → apply on BOTH boot and refresh (outside the teamsOnly guard) so
|
|
322
322
|
// they hot-reload. No restart-to-apply signal (they take effect on the next task without a restart).
|
|
@@ -360,13 +360,13 @@ function stageEffective(config, eff, logger, opts) {
|
|
|
360
360
|
// 142-S4 projects 域(registry-core 0.10.0):center 项目登记簿 → config.projects(键=
|
|
361
361
|
// projectId)。消费是 per-request 查表(memoryScope 派生 + defaultScopes 种子,security.ts/main.ts),
|
|
362
362
|
// 所以 boot+refresh 双腿都 mutateInPlace 热应用(整表替换,非粘——center 停发即清空);env lane 恒空。
|
|
363
|
-
//
|
|
364
|
-
//
|
|
363
|
+
// [2373]B-8:裸 Record 臂删——registry-core 0.13.0 ProjectsConfig 只有包裹形 `{projects:{...}}`
|
|
364
|
+
// (types.d.ts:3599,且 :12231 钉进 EffectiveConfig),裸形无 producer(与 Q15 declared 双形容忍同族)。
|
|
365
|
+
// 防御保留:非 object 条目跳过,字段逐个验型(wire verbatim,不信任形状)。
|
|
365
366
|
const projDomain = eff.projects;
|
|
366
|
-
const rawProjects = (projDomain && typeof projDomain === "object" && !Array.isArray(projDomain)
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
: projDomain
|
|
367
|
+
const rawProjects = (projDomain && typeof projDomain === "object" && !Array.isArray(projDomain) &&
|
|
368
|
+
"projects" in projDomain && typeof projDomain.projects === "object"
|
|
369
|
+
? (projDomain.projects ?? {})
|
|
370
370
|
: {}) ?? {};
|
|
371
371
|
const projects = {};
|
|
372
372
|
for (const [pid, reg] of Object.entries(rawProjects)) {
|
|
@@ -422,8 +422,38 @@ export function runtimeGatePresent(rt, key) {
|
|
|
422
422
|
return typeof v === "number" && v > 0;
|
|
423
423
|
return typeof v === "number";
|
|
424
424
|
}
|
|
425
|
-
/**
|
|
426
|
-
|
|
425
|
+
/**
|
|
426
|
+
* A1:中心下发的 `approvalRequire` 名单**按 env 腿同款判据**验过再落配。此前只验 `Array.isArray` 就逐字
|
|
427
|
+
* 落配——含退役工具名(`bash`/`Task`/`KillShell`)或 pre-prefix/不完整 MCP 名(`figma__x`/`mcp__figma`)时
|
|
428
|
+
* 该名单项永不匹配任何现役工具,审批门静默失守,而同一拼法从 env 腿(`APPROVAL_REQUIRE`)进来是 boot 拒启
|
|
429
|
+
* ——两腿判据不对称,写配置的人无从知道自己踩的是哪一条。判据单点=config.ts `findUnmatchableToolNames`。
|
|
430
|
+
*
|
|
431
|
+
* 处置形照本文件既有的域级拒绝先例(`commandPolicy` 非法 ⇒ fail-loud + 保留前值):常驻进程不能因为一次
|
|
432
|
+
* 坏发布 crash,所以**只拒这一个域**(其余五闸照常应用)、保留前值、留一条响亮 warn。「半应用一个被静默
|
|
433
|
+
* 削弱的门」才是要堵的那种失败。
|
|
434
|
+
*
|
|
435
|
+
* 顺带 C1-2:数组项 trim + 去空串,与 env csv 归一(`csv()` 的 `.map(trim).filter(Boolean)`)一致——
|
|
436
|
+
* 否则 `" Bash "` 从中心腿进来会是个永不匹配的名字,正是本条要消灭的那类静默失效。
|
|
437
|
+
*/
|
|
438
|
+
function stageApprovalRequire(raw, logger) {
|
|
439
|
+
// wire verbatim ⇒ 不信任元素形状(整表是 center 发的):非串项与空串一并落地板,与 env csv 归一同形。
|
|
440
|
+
const names = (Array.isArray(raw) ? raw : [])
|
|
441
|
+
.map((n) => (typeof n === "string" ? n.trim() : n))
|
|
442
|
+
.filter((n) => typeof n === "string" && n.length > 0);
|
|
443
|
+
const bad = findUnmatchableToolNames(names);
|
|
444
|
+
if (bad.length > 0) {
|
|
445
|
+
logger?.warn("sema_registry_approval_require_invalid", {
|
|
446
|
+
detail: formatUnmatchableToolNames("published runtime.approvalRequire", bad),
|
|
447
|
+
names: bad.map((b) => b.name),
|
|
448
|
+
kept: "the prior approvalRequire is unchanged — the published list would have silently matched nothing",
|
|
449
|
+
});
|
|
450
|
+
return {};
|
|
451
|
+
}
|
|
452
|
+
return { value: names };
|
|
453
|
+
}
|
|
454
|
+
/** [2283] stage 半场:六闸的赋值清单(纯计算,零变异)。commit 段照单赋值,通知载荷 post-commit 发。
|
|
455
|
+
* A1 的名单校验是**内容判定**(描述 eff 的真伪,与是否 commit 无关)⇒ 与 commandPolicy 同,stage 期发 warn。 */
|
|
456
|
+
function stageRuntimeGates(rt, logger) {
|
|
427
457
|
if (!rt)
|
|
428
458
|
return { assignments: [] };
|
|
429
459
|
const assignments = [];
|
|
@@ -431,6 +461,14 @@ function stageRuntimeGates(rt) {
|
|
|
431
461
|
for (const key of RUNTIME_GATE_KEYS) {
|
|
432
462
|
if (!runtimeGatePresent(rt, key))
|
|
433
463
|
continue; // undefined / sentinel → keep env
|
|
464
|
+
if (key === "approvalRequire") {
|
|
465
|
+
const staged = stageApprovalRequire(rt[key], logger);
|
|
466
|
+
if (staged.value === undefined)
|
|
467
|
+
continue; // 判据未过 ⇒ 只拒该域,保留前值(其余闸不受牵连)
|
|
468
|
+
assignments.push([key, staged.value]);
|
|
469
|
+
applied[key] = staged.value;
|
|
470
|
+
continue;
|
|
471
|
+
}
|
|
434
472
|
assignments.push([key, rt[key]]); // present (incl. explicit 0/[]) → override
|
|
435
473
|
applied[key] = rt[key];
|
|
436
474
|
}
|
|
@@ -439,7 +477,7 @@ function stageRuntimeGates(rt) {
|
|
|
439
477
|
export function applyRuntimeGates(config, rt, logger) {
|
|
440
478
|
// 独立调用面的兼容壳(测试/外部):stage → 就地赋值 → 通知。applyEffective 不走这里——它把
|
|
441
479
|
// assignments 并进自己的 commit 段以保住整世代原子性([2283]②)。
|
|
442
|
-
const s = stageRuntimeGates(rt);
|
|
480
|
+
const s = stageRuntimeGates(rt, logger);
|
|
443
481
|
for (const [k, v] of s.assignments)
|
|
444
482
|
config[k] = v;
|
|
445
483
|
if (s.info)
|
|
@@ -126,10 +126,17 @@ export interface CenterMcpServer {
|
|
|
126
126
|
export interface EffectiveConfig {
|
|
127
127
|
version: number;
|
|
128
128
|
updatedAt: string;
|
|
129
|
+
/** [2373]B-6:default/tierGroups/activeTierGroup 收进类型面(registry-core 0.13.0 已声明,
|
|
130
|
+
* types.d.ts:641/679/724)——此前 wire 面靠「JSON verbatim + 消费方结构读」逃逸,投影/消费两侧
|
|
131
|
+
* 各自 as 宽铸。tierGroups 上游是 ZodDefault(合规 center 恒发),但本类型描述的是**到货 JSON**
|
|
132
|
+
* (含非合规/旧存量 center),故仍标 optional——消费方 resolveActiveTiers 自身容缺。 */
|
|
129
133
|
models: {
|
|
130
134
|
models: CenterModel[];
|
|
131
135
|
roles: Record<string, CenterRoleTarget>;
|
|
132
136
|
atModelAllowlist?: string[];
|
|
137
|
+
default?: string;
|
|
138
|
+
tierGroups?: unknown;
|
|
139
|
+
activeTierGroup?: string;
|
|
133
140
|
};
|
|
134
141
|
/** OPTIONAL since registry-core 0.7 deleted the teams domain: a 0.7+ center /effective payload
|
|
135
142
|
* has NO teams key (collab is its successor). Absent/empty ⇒ registerTeams resets to BUILTIN_TEAMS (the
|
|
@@ -180,12 +187,12 @@ export interface EffectiveConfig {
|
|
|
180
187
|
};
|
|
181
188
|
/** 142-S4(registry-core 0.10.0 第 15 域):center 项目登记簿。wire 面 verbatim JSON —
|
|
182
189
|
* registry-core `ProjectsConfig` 的形状是 `{projects: Record<projectId, ProjectRegistration>}`(skills/mcp
|
|
183
|
-
* 同款域包裹)
|
|
184
|
-
*
|
|
190
|
+
* 同款域包裹)。[2373]B-8:裸 Record 联合臂随 apply-effective 的宽读一起删(0.13.0 只有包裹形,
|
|
191
|
+
* 裸形无 producer)。消费=applyEffective → config.projects(displayName/gitRemotes/defaultScopes
|
|
185
192
|
* 三个 runtime 字段;审计字段不进 ServiceConfig)。 */
|
|
186
193
|
projects?: {
|
|
187
194
|
projects?: Record<string, unknown>;
|
|
188
|
-
}
|
|
195
|
+
};
|
|
189
196
|
/** registry-core 0.6:治理三件(autonomy/commandPolicy/approvalRequire)拆新 governance 域=真值;
|
|
190
197
|
* 过渡期 effective 在 runtime 位双写镜像。读取优先 governance 新位、runtime 旧位 fallback(顺序契约:
|
|
191
198
|
* 消费端先切换、确认后 center 才撤双写,治理闸零 fail-open 窗口)。 */
|
|
@@ -53,7 +53,7 @@ export interface ConfigProvider {
|
|
|
53
53
|
/** The config-provider knobs read off ServiceConfig (a structural subset — avoids importing the whole
|
|
54
54
|
* ServiceConfig type and keeps this module testable with a plain object). */
|
|
55
55
|
export interface ConfigProviderInput {
|
|
56
|
-
/** Set when SEMA_REGISTRY_URL (legacy CONFIG_CENTER_URL) is configured (config.ts `configCenter`). `dryRun` is carried through so a
|
|
56
|
+
/** Set when SEMA_REGISTRY_URL (legacy CONFIG_CENTER_URL now boot-rejects, no dual-read) is configured (config.ts `configCenter`). `dryRun` is carried through so a
|
|
57
57
|
* remote↔local swap via this seam does NOT drop the dry-run posture main.ts branches on (config.ts
|
|
58
58
|
* `configCenter.dryRun`); the provider itself does not consume it (the caller still branches on it). */
|
|
59
59
|
configCenter?: {
|
package/dist/config-provider.js
CHANGED
|
@@ -210,16 +210,9 @@ export function mapToServiceEffective(eff, version) {
|
|
|
210
210
|
...(m.contextWindow !== undefined ? { contextWindow: m.contextWindow } : {}),
|
|
211
211
|
...(m.maxTokens !== undefined ? { maxTokens: m.maxTokens } : {}),
|
|
212
212
|
// codex F5 ([818]① 1M dual-window): an EXPLICIT `autoCompactTokens` must survive this CLOSED
|
|
213
|
-
// projection
|
|
214
|
-
//
|
|
215
|
-
|
|
216
|
-
// ModelEntry doesn't declare it — same passthrough posture as tierGroups below). NOTE (honest
|
|
217
|
-
// gap): registry-core's zod ModelEntry is "strip"-mode, so a value in a config.d/models.json read
|
|
218
|
-
// through FileConfigStore is ALSO dropped upstream of this mapper — that half needs a registry-core
|
|
219
|
-
// schema addition; this fix removes OUR projection's drop for any caller of this seam.
|
|
220
|
-
...(typeof m.autoCompactTokens === "number"
|
|
221
|
-
? { autoCompactTokens: m.autoCompactTokens }
|
|
222
|
-
: {}),
|
|
213
|
+
// projection. [2373]B-6d:registry-core 0.13.0 已把它收进 ModelEntry schema(types.d.ts:157/212)
|
|
214
|
+
// ——旧注的「strip-mode 会在上游丢值」的 honest gap 已随那次 schema addition 关闭,结构读改类型直读。
|
|
215
|
+
...(typeof m.autoCompactTokens === "number" ? { autoCompactTokens: m.autoCompactTokens } : {}),
|
|
223
216
|
...(m.cost !== undefined ? { cost: m.cost } : {}),
|
|
224
217
|
...(m.extraBody !== undefined ? { extraBody: m.extraBody } : {}),
|
|
225
218
|
// registry-core 0.10.13 promptGuidance ([998]⑤c): the CLOSED projection must pass it through or
|
|
@@ -232,10 +225,12 @@ export function mapToServiceEffective(eff, version) {
|
|
|
232
225
|
// 本 mapper 是 CLOSED 投影——不直通则本地 lane 静默丢键(autoCompactTokens 同类病),applyEffective 的
|
|
233
226
|
// resolveDefaultModelName 第一优先级在本地 lane 永远点不亮。写面悬空 ref 由 registry-core superRefine
|
|
234
227
|
// fail-loud;存量/未经 schema 的路径仍由消费方 warn 降级(config-center/facade.ts resolveDefaultModelName)。
|
|
235
|
-
...(eff.models.default !== undefined ? { default: eff.models.default } : {}),
|
|
228
|
+
...(eff.models.default !== undefined ? { default: eff.models.default } : {}), // [2373]B-6c:0.13.0 类型直读(types.d.ts:641)
|
|
236
229
|
...(eff.models.atModelAllowlist !== undefined ? { atModelAllowlist: eff.models.atModelAllowlist } : {}),
|
|
237
230
|
// registry-core 0.9.0 档位组: verbatim passthrough — applyEffective's resolveActiveTiers reads
|
|
238
231
|
// these structurally off eff.models (the remote lane ships them JSON-verbatim; the local lane must too).
|
|
232
|
+
// [2373]B-6b:0.13.0 类型直读(EffectiveConfig.models 面已声明四键,宽铸删)。本地 lane 的
|
|
233
|
+
// eff 来自 FileConfigStore 原始 JSON(非 zod 输出),tierGroups 的 ZodDefault 恒在场性不适用——门保留。
|
|
239
234
|
...(eff.models.tierGroups !== undefined ? { tierGroups: eff.models.tierGroups } : {}),
|
|
240
235
|
...(eff.models.activeTierGroup !== undefined ? { activeTierGroup: eff.models.activeTierGroup } : {}),
|
|
241
236
|
},
|
package/dist/config-types.d.ts
CHANGED
|
@@ -299,13 +299,13 @@ export interface ServiceConfigFlat {
|
|
|
299
299
|
database: string;
|
|
300
300
|
connectionLimit?: number;
|
|
301
301
|
};
|
|
302
|
-
/** Which SQL engine the durable stores run on (clay 2026-06-21 PG migration
|
|
303
|
-
*
|
|
304
|
-
*
|
|
305
|
-
*
|
|
306
|
-
*
|
|
307
|
-
*
|
|
308
|
-
*
|
|
302
|
+
/** Which SQL engine the durable stores run on (clay 2026-06-21 PG migration). Canonical value is `mysql`
|
|
303
|
+
* = any MySQL-protocol server — MySQL, TiDB, MariaDB — over the same mysql2 pool; `pg` (PostgreSQL
|
|
304
|
+
* dialect) reads `pg` below. [2354]/[2373]B-3(5.0.0):the env value `tidb` and the TIDB_* coord names
|
|
305
|
+
* are RETIRED — `tidb` is rejected by the enum and any TIDB_* env in place refuses to start with the
|
|
306
|
+
* MYSQL_* replacement named (see RETIRED_ENVS in config.ts). `mysql` reads MYSQL_* coords only.
|
|
307
|
+
* TiDB itself stays fully supported (any MySQL-protocol engine works — memory no longer needs a VECTOR
|
|
308
|
+
* column since design/138 moved it onto the file engine). Env: DB_BACKEND. */
|
|
309
309
|
dbBackend: "mysql" | "pg" | "local" | "memory";
|
|
310
310
|
/** clay 拍(2026-07-27):operator 是否显式设了 DB_BACKEND。main.ts 的降级判据——**默认推导**的
|
|
311
311
|
* local(裸 boot)在 mkdir/ensure 失败时降级 memory + warn + gauge(auto-DB 不可达先例);
|
|
@@ -468,11 +468,10 @@ export interface ServiceConfigFlat {
|
|
|
468
468
|
operatorPrincipals: string[];
|
|
469
469
|
/** Tool names that are always denied. */
|
|
470
470
|
approvalDeny: string[];
|
|
471
|
-
/** Poll interval (ms) for an approval decision. */
|
|
472
|
-
approvalPollMs: number;
|
|
473
471
|
/** design/45 durable-checkpoint (core 1.67): when true (+ a TiDB pool), F4 uses durable **suspend/resume**
|
|
474
472
|
* instead of poll-blocking — a gated tool `ask` suspends the task (status:"suspended" + checkpoint), an
|
|
475
|
-
* operator resumes it on any replica. Default OFF
|
|
473
|
+
* operator resumes it on any replica. Default OFF([2354] A-5:轮询车道已退役,OFF+门意图 ⇒ core UNGATED
|
|
474
|
+
* 告警,不再有回退门形). `DURABLE_APPROVAL=true`. */
|
|
476
475
|
durableApproval: boolean;
|
|
477
476
|
/** design/80 seam #2 (preemption) / design/74 ("失败≠没做完" third state): when true (+ durable mode), the
|
|
478
477
|
* /v1/runs durable path opts every task into core `resourceSuspend` — a budget/turns/walltime limit OR a
|
|
@@ -797,7 +796,7 @@ export interface ServiceConfigFlat {
|
|
|
797
796
|
to: string;
|
|
798
797
|
atCostFraction: number;
|
|
799
798
|
reactive: boolean;
|
|
800
|
-
downgradeOn?: ("
|
|
799
|
+
downgradeOn?: import("@sema-agent/core").DegradeReason[];
|
|
801
800
|
toSupportsImages: boolean;
|
|
802
801
|
};
|
|
803
802
|
/** Quality-gate cascade ladder (core 1.45 `runCascade`, opt-in via `cascade:true`): catalog model
|
|
@@ -847,25 +846,12 @@ export interface ServiceConfigFlat {
|
|
|
847
846
|
defaultScenario: string;
|
|
848
847
|
/** Directory of baked-in skill Markdown files, loaded once at startup. */
|
|
849
848
|
skillsDir: string;
|
|
850
|
-
/** OA backend base URL for the `oa` scenario tools (read /api/v1, write /api/assets). */
|
|
851
|
-
oaApiBaseUrl?: string;
|
|
852
|
-
/** Shared trust token forwarded to OA (= OA AGENT_SERVICE_TOKEN); OA enforces per-principal RBAC. */
|
|
853
|
-
oaServiceToken?: string;
|
|
854
|
-
/** `oa` 场景的"开 Gitea issue"工具配置(OA AI 请求#5);仅当 OA_ISSUE_TOKEN 配置时启用。token 来自 env,不入模型/日志。
|
|
855
|
-
* 上线建议:OA_ISSUE_TOKEN 用**最小权限**(仅 issue:write 的 scope),别用全权 token。 */
|
|
856
|
-
oaIssue?: {
|
|
857
|
-
baseUrl: string;
|
|
858
|
-
owner: string;
|
|
859
|
-
repo: string;
|
|
860
|
-
token: string;
|
|
861
|
-
defaultLabels?: number[];
|
|
862
|
-
};
|
|
863
849
|
/** Central sema registry (sema-registry). When set, the service pulls the effective config
|
|
864
850
|
* on boot (and refreshes) and applies it OVER the env defaults — env is the fallback. Logical config
|
|
865
851
|
* only (model roster/roles/teams); secrets/gateways stay in this service's env.
|
|
866
|
-
* `dryRun` (SEMA_REGISTRY_DRY_RUN=true
|
|
852
|
+
* `dryRun` (SEMA_REGISTRY_DRY_RUN=true; legacy CONFIG_CENTER_DRY_RUN now boot-rejects, no dual-read): pull + LOG what the registry would change vs the env-derived
|
|
867
853
|
* config, but do NOT apply it — a safe-rollout verification step before flipping to live.
|
|
868
|
-
* `worker` (SEMA_REGISTRY_WORKER=<name
|
|
854
|
+
* `worker` (SEMA_REGISTRY_WORKER=<name>; legacy CONFIG_CENTER_WORKER now boot-rejects, no dual-read; injected per-worker by the reconciler): scopes the pull to
|
|
869
855
|
* that worker's roster via `/effective?worker=<name>`. Unset → the global roster (backward compatible). */
|
|
870
856
|
configCenter?: {
|
|
871
857
|
baseUrl: string;
|
|
@@ -874,7 +860,7 @@ export interface ServiceConfigFlat {
|
|
|
874
860
|
worker?: string;
|
|
875
861
|
};
|
|
876
862
|
/** Dual-mode config SOURCE (DUAL-MODE-DESIGN §4): "remote" (sema-registry HTTP) | "local" (.env + config.d
|
|
877
|
-
* via @sema-agent/registry-core FileConfigStore) | unset → remote if SEMA_REGISTRY_URL (legacy CONFIG_CENTER_URL) is set, else pure-env.
|
|
863
|
+
* via @sema-agent/registry-core FileConfigStore) | unset → remote if SEMA_REGISTRY_URL (legacy CONFIG_CENTER_URL now boot-rejects, no dual-read) is set, else pure-env.
|
|
878
864
|
* Env: CONFIG_PROVIDER. The same resolver/EffectiveConfig either way (can't drift). */
|
|
879
865
|
configProvider?: string;
|
|
880
866
|
/** Root dir holding `config.d/<domain>.json` for the local config source. Env: CONFIG_LOCAL_DIR. */
|
|
@@ -886,7 +872,7 @@ export type ServiceStoreConfig = Pick<ServiceConfigFlat, "sessionBackend" | "ses
|
|
|
886
872
|
export type ServiceModelPlaneConfig = Pick<ServiceConfigFlat, "gatewayBaseUrl" | "gatewayApiKey" | "gatewayFallbackUrls" | "gatewayMaxRetries" | "anthropic" | "resilience" | "model" | "models" | "modelApiKeyEnv" | "modelApiKeys" | "modelQuotaWeights" | "tiers" | "projects" | "roles" | "cascadeLadder" | "degrade">;
|
|
887
873
|
/** 组:approval(审批 / HITL 门)。`directDoorActive` 无 env 解析腿(装配层三域合取的产物),但语义上
|
|
888
874
|
* 就是本组的门状态,故进组;`parseApprovalDomain` 的返回类型相应是 `Omit<…, "directDoorActive">`。 */
|
|
889
|
-
export type ServiceApprovalConfig = Pick<ServiceConfigFlat, "approvalRequire" | "approvalDeny" | "
|
|
875
|
+
export type ServiceApprovalConfig = Pick<ServiceConfigFlat, "approvalRequire" | "approvalDeny" | "approvalTimeoutSec" | "approvalAutoBudget" | "approvalNeverAuto" | "approvalHmacKeys" | "durableApproval" | "directApprovalDoor" | "directDoorActive" | "resourceSuspend" | "resourceSuspendTtlSec" | "askQuestionEnabled" | "toolApprovalEnabled" | "mcpElicitation" | "sensitiveWritePatterns" | "manualModeShellGate">;
|
|
890
876
|
/** 组:memory(记忆面 + TOC 同步腿)。 */
|
|
891
877
|
export type ServiceMemoryConfig = Pick<ServiceConfigFlat, "memoryEngineEnabled" | "memoryEngineDir" | "memoryEngineRemoteLaneAllowed" | "memoryEngineBackend" | "memoryScope" | "memorySync" | "projectMemoryEnabled" | "syncImportLeaseStaleSec">;
|
|
892
878
|
/** 组:auth(鉴权 / 身份 / 治理棒)。`commandPolicy` 只有 sema-registry 腿(无 env 标量形),故 env 解析
|
|
@@ -899,7 +885,7 @@ export type ServiceLimitsHttpConfig = Pick<ServiceConfigFlat, "port" | "attachme
|
|
|
899
885
|
/** 组:observability(可观测)。 */
|
|
900
886
|
export type ServiceObservabilityConfig = Pick<ServiceConfigFlat, "metricsToken" | "traceToken" | "toolTrace" | "traceThinking" | "logLevel" | "otel">;
|
|
901
887
|
/** 组:integrations(外部集成)。`mcpServers` 由 sema-registry 适配器填(无 env 腿),归本组。 */
|
|
902
|
-
export type ServiceIntegrationsConfig = Pick<ServiceConfigFlat, "pluginsAllowHosts" | "mcpServers" | "configBootFetchBudgetMs" | "gitApiBaseUrl" | "gitApiToken" | "defaultScenario" | "skillsDir" | "
|
|
888
|
+
export type ServiceIntegrationsConfig = Pick<ServiceConfigFlat, "pluginsAllowHosts" | "mcpServers" | "configBootFetchBudgetMs" | "gitApiBaseUrl" | "gitApiToken" | "defaultScenario" | "skillsDir" | "configCenter" | "configProvider" | "configLocalDir">;
|
|
903
889
|
/** 九个组槽。每组恒在场(`loadConfig` / `attachConfigGroups` 装好才交出配置),故不可选——新代码写
|
|
904
890
|
* `config.modelPlane.model` 不需要 `?.`(可选组会把 `Model` 污染成 `Model | undefined`)。 */
|
|
905
891
|
export interface ServiceConfigGroups {
|