@sema-agent/server 7.123.0 → 7.124.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/MIGRATION.md +138 -0
- package/README.md +2 -2
- package/README.zh-CN.md +2 -2
- package/USAGE.md +53 -51
- 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.js +1 -1
- 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 +1 -1
- 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} +38 -22
- 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 +15 -15
- 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 +26 -6
- package/dist/config-lkg.js +43 -14
- package/dist/config-provider.d.ts +23 -19
- package/dist/config-provider.js +24 -26
- package/dist/config-types.d.ts +52 -51
- package/dist/config.d.ts +9 -46
- package/dist/config.js +33 -92
- 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 +8 -8
- 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 +7 -7
- package/dist/fleet-client.js +5 -4
- 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 +2 -2
- package/dist/http/durable-run-leg.js +2 -1
- package/dist/http/health-self-report.d.ts +4 -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 +5 -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 +1 -1
- 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.js +3 -2
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/key-resolver.d.ts +1 -1
- package/dist/leader/wire.d.ts +2 -2
- 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 +3 -3
- package/dist/model-entry-refusal.js +4 -4
- package/dist/model-provider.d.ts +2 -2
- package/dist/model-route-endpoint.d.ts +1 -1
- 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/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 +26 -2
- package/dist/plugins/scheduler-support.d.ts +26 -7
- package/dist/plugins/scheduler-support.js +96 -53
- 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/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/run-local.js +6 -3
- package/dist/runtime-caps-resolver.d.ts +4 -4
- package/dist/runtime-caps-resolver.js +2 -2
- package/dist/runtime-governance.d.ts +5 -5
- 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-titler.d.ts +0 -11
- package/dist/session-titler.js +3 -5
- package/dist/shared-memory-scope-authorizer.d.ts +4 -4
- package/dist/task-a2a.d.ts +1 -1
- 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 +17 -15
- package/dist/trace/self-minted-wire.d.ts +134 -3
- package/dist/trace/self-minted-wire.js +46 -9
- 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 +100 -119
- 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 +12 -12
- 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/{config-center → web-admin-client}/read-warnings.d.ts +23 -16
- package/dist/{config-center → web-admin-client}/read-warnings.js +33 -23
- 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 +12 -39
- package/package.json +2 -2
- package/skills/find-skills.md +2 -2
- 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/http/routes/runs.js
CHANGED
|
@@ -18,6 +18,7 @@ import { buildApprovalPreamble, buildApprovalPreambleSseFrames, readClosedWordSe
|
|
|
18
18
|
import { heldAskOf, liveSettledBy, readDecidedBy, retiredDecisionKeyFacts, DECIDED_BY_NOT_IN_PROOF, DECIDED_BY_OUTSIDE_CLOSED_SET, POLICY_CANNOT_ALLOW_PERSON_ASK } from "../../host-decision.js";
|
|
19
19
|
import { ASK_DECISION_CONSUMER_ABSENT, outcomeOfDecidedRow, resolveStreamApprovalGate } from "../../tool-approval.js";
|
|
20
20
|
import { MAX_DECISION_NOTE_CHARS } from "../../approval-ask-machine.js";
|
|
21
|
+
import { causeOfAskRow } from "../../approval-deny-reasons.js";
|
|
21
22
|
import { normalizeRunEventType, screenedStoredEventData } from "../../trace/project.js";
|
|
22
23
|
import { sendJson, sendError, httpErrorCode, sseHeaders } from "../send.js";
|
|
23
24
|
import { readTurnActivityMs } from "../../turn-activity.js";
|
|
@@ -34,6 +35,7 @@ import { RUN_NOT_FOUND_MESSAGE, runNotFoundMessage } from "../route-ctx.js";
|
|
|
34
35
|
import { withPrincipal } from "../../observability/principal-context.js";
|
|
35
36
|
import { readResumeCtx } from "../resume-ctx-read.js";
|
|
36
37
|
import { storedBodyReplayAnswer, storedBodyReplayLogFields } from "../checkpoint-ctx.js";
|
|
38
|
+
import { serviceVersion } from "../../service-version.js";
|
|
37
39
|
import { storedBodyReplayRefusal } from "../stored-body-replay.js";
|
|
38
40
|
const STEER_PRIORITY_WORDS = INJECTION_TIERS.map((tier) => `'${tier}'`);
|
|
39
41
|
const STEER_PRIORITY_UNION = STEER_PRIORITY_WORDS.join(" | ");
|
|
@@ -709,7 +711,7 @@ export async function handleRuns(req, res, match, ctx) {
|
|
|
709
711
|
}
|
|
710
712
|
if (mintResult.unservable !== undefined) {
|
|
711
713
|
deps.logger?.warn?.("steer_wake_park_refused_stored_body", { taskId, sessionId: run.sessionId, ...storedBodyReplayLogFields(mintResult.unservable) });
|
|
712
|
-
const { status, body: { error, errorCode, ...rest } } = storedBodyReplayAnswer(mintResult.unservable);
|
|
714
|
+
const { status, body: { error, errorCode, ...rest } } = storedBodyReplayAnswer(mintResult.unservable, serviceVersion());
|
|
713
715
|
sendError(res, status, errorCode, error, rest);
|
|
714
716
|
return;
|
|
715
717
|
}
|
|
@@ -1485,12 +1487,14 @@ export async function handleRunVerbs(req, res, match, ctx) {
|
|
|
1485
1487
|
});
|
|
1486
1488
|
return;
|
|
1487
1489
|
case "DENIED":
|
|
1488
|
-
case "VOID":
|
|
1489
|
-
|
|
1490
|
+
case "VOID": {
|
|
1491
|
+
const rowCause = causeOfAskRow(row);
|
|
1492
|
+
sendError(res, 410, "gone.ask", "this ask reached a terminal state without a human decision (cause says why: a routing failure, a cancellation or batch withdrawal or abort, or the process that held it ended) and can no longer be decided", {
|
|
1490
1493
|
state: row.state,
|
|
1491
|
-
...(
|
|
1494
|
+
...(rowCause?.kind === "ending" ? { cause: rowCause.cause } : {}),
|
|
1492
1495
|
});
|
|
1493
1496
|
return;
|
|
1497
|
+
}
|
|
1494
1498
|
case "PARKING":
|
|
1495
1499
|
res.setHeader("retry-after", String(ASK_PARKING_RETRY_AFTER_SEC));
|
|
1496
1500
|
sendError(res, 425, "parking.ask_retry", "this ask is mid-park — retrying tells you where it finally landed; a retry does NOT queue this decision for acceptance", {
|
|
@@ -127,7 +127,8 @@ async function handleSessionList(res, lister, query, forceOwner, includeUnowned
|
|
|
127
127
|
const nextCursor = hasMore && last ? encodeSessionCursor({ lastActivityAt: last.lastActivityAt, sessionId: last.sessionId }, f) : undefined;
|
|
128
128
|
const sessions = page.map((r) => {
|
|
129
129
|
const tempo = sessionTempoOfRunStatus(r.lastStatus);
|
|
130
|
-
|
|
130
|
+
const row = r.objectivePreview === "" ? { ...r, objectivePreview: null } : r;
|
|
131
|
+
return tempo === undefined ? row : { ...row, tempo };
|
|
131
132
|
});
|
|
132
133
|
sendJson(res, 200, { sessions, ...(nextCursor ? { nextCursor } : {}) });
|
|
133
134
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SessionError, materializeA2aTools, materializeMcpTools, sanitizePathComponent } from "@sema-agent/core";
|
|
2
|
-
import { a2aForScenario, mcpForScenario } from "../../
|
|
2
|
+
import { a2aForScenario, mcpForScenario } from "../../web-admin-client/facade.js";
|
|
3
3
|
import { isUuidV7, isUuidShape, legacyUnownedSessionOk } from "../../security.js";
|
|
4
4
|
import { windowMessages, truncateMessageBlobs, redactSessionViewForRead } from "../../audit.js";
|
|
5
5
|
import { redactSecrets } from "../../trace/redact.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { expandTiers, isThinkingLevel } from "@sema-agent/core";
|
|
2
2
|
import { HttpError } from "../../security.js";
|
|
3
|
-
import {
|
|
3
|
+
import { isAtMentionable, matchCatalogModel, refusedCatalogEntry, selectableCatalog } from "../../model-select.js";
|
|
4
4
|
import { modelUnavailableMessage } from "../../model-entry-refusal.js";
|
|
5
5
|
import { redactSecrets } from "../../trace/redact.js";
|
|
6
6
|
import { admitProviderEcho, redactErrorMessage } from "../../observability/run-terminal.js";
|
|
@@ -88,8 +88,8 @@ export async function handleSideQuery(req, res, match, ctx) {
|
|
|
88
88
|
sendError(res, 400, "request.model_unavailable", message);
|
|
89
89
|
return;
|
|
90
90
|
}
|
|
91
|
-
if (!
|
|
92
|
-
sendError(res, 400, "request.model_not_allowed", `model is not
|
|
91
|
+
if (!isAtMentionable(body.model, catalog, deps.config.atMention, deps.config.modelRefusals)) {
|
|
92
|
+
sendError(res, 400, "request.model_not_allowed", `model is not @-mentionable on this deployment: "${body.model.slice(0, 120)}" — which models can be @-mentioned is configured by the operator (models.atMention)`);
|
|
93
93
|
return;
|
|
94
94
|
}
|
|
95
95
|
}
|
|
@@ -29,6 +29,7 @@ import { buildSyncSubmitBody } from "../sync-submit-body.js";
|
|
|
29
29
|
import { assertNever } from "../route-ctx.js";
|
|
30
30
|
import * as facts from "../../capability-facts.js";
|
|
31
31
|
import { buildCheckpointCtx } from "../checkpoint-ctx.js";
|
|
32
|
+
import { serviceVersion } from "../../service-version.js";
|
|
32
33
|
import { withModelReachScope } from "../../model-reach-scope.js";
|
|
33
34
|
import { createInstructionSelectionLeg } from "../../instruction-selection.js";
|
|
34
35
|
const DISCONNECT_PARK_GRACE_MS = 10_000;
|
|
@@ -254,7 +255,7 @@ export async function handleTasks(req, res, match, ctx) {
|
|
|
254
255
|
let ledgerSink;
|
|
255
256
|
let ledgerTerminal = false;
|
|
256
257
|
if (deps.checkpointStore && prepared.spec.sessionId) {
|
|
257
|
-
await deps.checkpointStore.putCtx(prepared.spec.sessionId, buildCheckpointCtx({ body: prepared.body, memoryScope: prepared.auth?.memoryScope }));
|
|
258
|
+
await deps.checkpointStore.putCtx(prepared.spec.sessionId, buildCheckpointCtx({ body: prepared.body, memoryScope: prepared.auth?.memoryScope, writerVersion: serviceVersion() }));
|
|
258
259
|
}
|
|
259
260
|
if (durableTaskId && deps.runStore) {
|
|
260
261
|
const rs = deps.runStore;
|
|
@@ -806,7 +807,7 @@ export async function handleTasks(req, res, match, ctx) {
|
|
|
806
807
|
}
|
|
807
808
|
commitSessionInheritEnv(deps, prepared.spec.sessionId, prepared.body);
|
|
808
809
|
if (deps.checkpointStore && prepared.spec.sessionId) {
|
|
809
|
-
await deps.checkpointStore.putCtx(prepared.spec.sessionId, buildCheckpointCtx({ body: prepared.body, memoryScope: prepared.auth?.memoryScope }));
|
|
810
|
+
await deps.checkpointStore.putCtx(prepared.spec.sessionId, buildCheckpointCtx({ body: prepared.body, memoryScope: prepared.auth?.memoryScope, writerVersion: serviceVersion() }));
|
|
810
811
|
}
|
|
811
812
|
const syncCancelCtrl = createRunAbort();
|
|
812
813
|
if (prepared.spec.sessionId)
|
package/dist/http/run-meta.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ export declare function runMeta(prepared: {
|
|
|
14
14
|
}, source: string | null): {
|
|
15
15
|
jobId: string | null;
|
|
16
16
|
source: string | null;
|
|
17
|
-
objectivePreview: string
|
|
17
|
+
objectivePreview: string;
|
|
18
18
|
};
|
|
19
19
|
/** Build the cascade config from the operator ladder. Default gate = `status==="completed"` (escalate
|
|
20
20
|
* on a cheap-rung failure); cost-ceiling from the task's budget bounds the cold-rerun tax. */
|
package/dist/http/run-meta.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { buildRunObjectivePreview } from "../user-authored-text.js";
|
|
2
2
|
export function runMeta(prepared, source) {
|
|
3
3
|
const obj = prepared.spec.objective ?? "";
|
|
4
4
|
return {
|
|
5
5
|
jobId: prepared.jobId ?? null,
|
|
6
6
|
source,
|
|
7
|
-
objectivePreview:
|
|
7
|
+
objectivePreview: buildRunObjectivePreview(obj),
|
|
8
8
|
};
|
|
9
9
|
}
|
|
10
10
|
export function cascadeConfig(ladder, maxCostUsd) {
|
package/dist/http/server.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { IncomingMessage } from "node:http";
|
|
|
3
3
|
import { type Runner, type TaskSpec, type TaskResult, type WorkflowRunStore, type MemoryEntry, type MemoryExportBundle, type MemoryImportReport, type EntryProvenanceAccount, type MemoryErasureAttestation, type MemoryEntryOrigin, type OriginClearanceRow, type SessionMemoryStatus, type ConsolidationRunReceipt, type ConsolidationDriverRunRow, type SideQuerySpec, type SideQueryResult, type Brain, type EngineNotice } from "@sema-agent/core";
|
|
4
4
|
import type { TaskRequestBody } from "./wire-types.js";
|
|
5
5
|
import type { ServiceConfig } from "../config-types.js";
|
|
6
|
-
import { type SessionMirrorRuling } from "../
|
|
6
|
+
import { type SessionMirrorRuling } from "../web-admin-client/facade.js";
|
|
7
7
|
import type { RestartSignal } from "@sema-agent/settings-schema/fleet";
|
|
8
8
|
import { type OwnerAwareSessionStore } from "../security.js";
|
|
9
9
|
import type { RunStore, ImageIndex, ImageBake, CheckpointStoreFull, ResumeAnchorStore, ApprovalExemptionStore, ApprovalNonceStore, ServiceSessionPolicyStore, ServiceFileHistoryStore, ToolResultStoreFull, StoreBackend } from "../plugins/store-backend.js";
|
|
@@ -628,7 +628,7 @@ export interface ServiceGovernanceDeps {
|
|
|
628
628
|
}) => Promise<RequestAuth>;
|
|
629
629
|
/** 鉴权桥(registry-core api/auth-bridge):registry 用户 JWT → principal。缺席=分支不存在
|
|
630
630
|
* (bearer 只认 SERVICE_AUTH_TOKEN(S),现状不变)。 */
|
|
631
|
-
|
|
631
|
+
webAdminJwtVerifier?: {
|
|
632
632
|
verify: (bearer: string) => Promise<import("../auth-bridge.js").VerifyOutcome>;
|
|
633
633
|
};
|
|
634
634
|
/** Per-principal rate limiter for task/run endpoints. In-memory (single replica) or TiDB-backed
|
|
@@ -694,7 +694,7 @@ export interface ServiceDeploymentDeps {
|
|
|
694
694
|
servingLease?: () => import("../fleet/engine-signal.js").ServingLeaseView;
|
|
695
695
|
/** boot ready 门(b):false = 布防(`CONFIG_REQUIRE_ROSTER=true`)且首次 effective pull 尚未落 roster
|
|
696
696
|
* (worker 只有占位模型)。就绪原因 `model_roster_pending`(`http/readiness.ts`):计费提交 503 + `/readyz` 503 +
|
|
697
|
-
* /health 加性 `ready:false`。absent = 恒 ready(未布防 / 非 registry 部署),现有部署零影响。
|
|
697
|
+
* /health 加性 `ready:false`。absent = 恒 ready(未布防 / 非 registry 部署),现有部署零影响。web-admin 的
|
|
698
698
|
* markRosterLanded 在落模型后翻 true(one-way latch)。 */
|
|
699
699
|
modelReady?: () => boolean;
|
|
700
700
|
/** Sema-registry restart signal: the refresh loop sets this when a pull carries restart-to-apply
|
|
@@ -709,7 +709,7 @@ export interface ServiceDeploymentDeps {
|
|
|
709
709
|
* (configTargetVersion / configAppliedVersion / configApplyStaleMs),`GET /v1/diagnostics/wiring` 取整份
|
|
710
710
|
* (按组的 appliedVersion / deferredKeys+铸因 / lastRejected 消毒形)。缺席 = 这个进程没有配置管道
|
|
711
711
|
* (纯 env 部署 / 测试夹具)⇒ 两个面的形状逐字不变(additive)。 */
|
|
712
|
-
configApplyState?: () => import("../
|
|
712
|
+
configApplyState?: () => import("../web-admin-client/apply-ledger.js").ConfigApplyLedgerView | undefined;
|
|
713
713
|
/** S-698:中心凭证健康位(`/health.centerCredential`)—— 凭证来源的健康态 + 续签器状态(`center-credential-renewer.ts`
|
|
714
714
|
* `buildCenterCredentialHealthView` 铸形,只有闭集词 / 时刻 / 计数,不带路径与令牌)。缺席 / 返回 undefined = 健康或没有中心
|
|
715
715
|
* ⇒ `/health` 形状逐字不变(additive)。 */
|
|
@@ -718,7 +718,7 @@ export interface ServiceDeploymentDeps {
|
|
|
718
718
|
* (`boot/stage-10-http-server.ts` → `modelRefusals: () => deployment.modelRefusalsState?.()`)—— 一处铸、两出口。缺席 / 返回 undefined =
|
|
719
719
|
* 没有可报的拒或没有配置管道 ⇒ `/health` 形状逐字不变(additive)。 */
|
|
720
720
|
modelRefusalsState?: () => import("@sema-agent/settings-schema").ModelRefusalsSignal | undefined;
|
|
721
|
-
/** `/health.configHandoff`(只上 `/health`):在场 ⇔ 部署声明了耐久接力 ∧ 应用着的那一代没被确认(
|
|
721
|
+
/** `/health.configHandoff`(只上 `/health`):在场 ⇔ 部署声明了耐久接力 ∧ 应用着的那一代没被确认(web-admin 接力账的 `configHandoffState()`;合成律
|
|
722
722
|
* `fleet/engine-signal.ts` 的 `buildConfigHandoff`)。缺席 / 返回 undefined = 有接力、没有中心或本地腿 ⇒ 键缺席。 */
|
|
723
723
|
configHandoffState?: () => import("../fleet/engine-signal.js").ConfigHandoff | undefined;
|
|
724
724
|
/** [ref] 追加件:`POST /v1/admin/config/refresh` 的实现面 —— 触发**一次既有**的 refresh 拍(在飞则 join)。
|
|
@@ -727,7 +727,7 @@ export interface ServiceDeploymentDeps {
|
|
|
727
727
|
/** DESIGN-278 §5 S2([ref]):center **当前在管**的 ServiceConfig 键集 —— `GET /v1/config/catalog`
|
|
728
728
|
* 判 `effectiveLane`(env 占位/center 在管/默认)的 center 半场。缺席或返回 undefined = 本部署
|
|
729
729
|
* 没有配置管道(纯 env worker / 测试夹具)⇒ 目录把每条 center 腿如实标「不在管」(additive)。 */
|
|
730
|
-
|
|
730
|
+
webAdminManagedKeys?: () => ReadonlySet<string> | undefined;
|
|
731
731
|
/** [ref](core 5.50 [ref]):mid-turn MCP 撤销台账读口 —— GET /v1/sessions/:id/mcp 的展示面与
|
|
732
732
|
* 引擎执行面同一权威(被撤服务器的工具不再进面板)。缺席 = 无中心撤销面(pre-338 展示语义)。 */
|
|
733
733
|
mcpRevocations?: {
|
|
@@ -783,7 +783,7 @@ export interface ServiceDeploymentDeps {
|
|
|
783
783
|
* (它在场景装配里每请求现算),所以本位不会随调用方漂。 */
|
|
784
784
|
webSearchProvider?: import("../plugins/web-search.js").WebSearchProvider;
|
|
785
785
|
/** S-737:本进程模型钥匙保管店的**公钥面** —— `GET /v1/capabilities` 的 `sealedKey` 段唯一席位。值**逐字**取自
|
|
786
|
-
*
|
|
786
|
+
* web-admin 运行时(`boot/web-admin.ts` 的 `sealedKeyPublic`,boot 期建的那一只店),路由里不再建店、不读全局。
|
|
787
787
|
* 类型只有最新那把公钥(`sealed-key.ts` `SealedKeyPublicFace`):私钥、保管路径、持有的旧 id 列表从这一层结构上够不着。
|
|
788
788
|
* 缺席 = 本进程没有保管店(boot 建店失败,或不是由 composition root 装起来的测试夹具形)⇒ caps 的 `sealedKey` 键缺席。 */
|
|
789
789
|
sealedKeyPublic?: import("../sealed-key.js").SealedKeyPublicFace;
|
package/dist/http/server.js
CHANGED
|
@@ -2,7 +2,7 @@ import http from "node:http";
|
|
|
2
2
|
import { outwardPlane } from "../terminal.js";
|
|
3
3
|
import { redactHead } from "../observability/run-terminal.js";
|
|
4
4
|
import { validatePendingSteer } from "@sema-agent/core";
|
|
5
|
-
import {} from "../
|
|
5
|
+
import {} from "../web-admin-client/facade.js";
|
|
6
6
|
import { HttpError } from "../security.js";
|
|
7
7
|
import {} from "../memory-sync.js";
|
|
8
8
|
import { evictIfConflict } from "../runs.js";
|
|
@@ -9,14 +9,15 @@ export function permissionModeReadingUnstated(ctx, floor) {
|
|
|
9
9
|
return entryPermissionMode(stored, floor).effective === stored ? undefined : { stored, floor };
|
|
10
10
|
}
|
|
11
11
|
export function storedBodyReplayRefusal(ctx, autonomy) {
|
|
12
|
+
const writer = ctx.writerVersion !== undefined ? { writerVersion: ctx.writerVersion } : {};
|
|
12
13
|
if (allowListReadingUnstated(ctx))
|
|
13
|
-
return { kind: "allow_list_reading", era: allowListReadingEraOf(ctx) };
|
|
14
|
+
return { kind: "allow_list_reading", era: allowListReadingEraOf(ctx), ...writer };
|
|
14
15
|
const entry = skillDenyInertEntryOf(ctx.body);
|
|
15
16
|
if (entry !== undefined)
|
|
16
17
|
return { kind: "skill_deny_inert", entry };
|
|
17
18
|
const mode = permissionModeReadingUnstated(ctx, autonomyModeFloor(autonomy));
|
|
18
19
|
if (mode !== undefined)
|
|
19
|
-
return { kind: "permission_mode_reading", ...mode };
|
|
20
|
+
return { kind: "permission_mode_reading", ...mode, ...writer };
|
|
20
21
|
return undefined;
|
|
21
22
|
}
|
|
22
23
|
//# sourceMappingURL=stored-body-replay.js.map
|
package/dist/index.d.ts
CHANGED
|
@@ -27,7 +27,6 @@ export { createHttpServer, type ServiceDeps, type RequestAuth, type FlatServiceD
|
|
|
27
27
|
export { createSideQueryLane, createPerModelKeyBrain, type KeyResolver, type SideQueryLane, type SideQueryLaneCtx } from "./boot/side-query-lane.js";
|
|
28
28
|
export { createKeyResolver, resolveModelApiKey, type ModelKeyRef } from "./key-resolver.js";
|
|
29
29
|
export { isModelKeyPoison, ModelKeyPoisonedError, type ModelKeyPoison, type ModelKeyPoisonReason } from "./key-resolver.js";
|
|
30
|
-
export { RETIRED_ENVS, type RetiredEnv, type RetiredEnvKind, type RetiredEnvWire } from "./config.js";
|
|
31
30
|
export { CATALOG_ENTRY_HEADER_LANES, CATALOG_ENTRY_HEADER_NAMES, type CatalogEntryHeaderName } from "./model-entry-headers.js";
|
|
32
31
|
export { judgeModelRouteGap, type ModelRouteGapReading, type ModelRouteGapOptions } from "./model-route-gap.js";
|
|
33
32
|
export type { ModelRouteGap } from "./model-route-endpoint.js";
|
package/dist/index.js
CHANGED
|
@@ -24,7 +24,6 @@ export { createHttpServer, } from "./http/server.js";
|
|
|
24
24
|
export { createSideQueryLane, createPerModelKeyBrain } from "./boot/side-query-lane.js";
|
|
25
25
|
export { createKeyResolver, resolveModelApiKey } from "./key-resolver.js";
|
|
26
26
|
export { isModelKeyPoison, ModelKeyPoisonedError } from "./key-resolver.js";
|
|
27
|
-
export { RETIRED_ENVS } from "./config.js";
|
|
28
27
|
export { CATALOG_ENTRY_HEADER_LANES, CATALOG_ENTRY_HEADER_NAMES } from "./model-entry-headers.js";
|
|
29
28
|
export { judgeModelRouteGap } from "./model-route-gap.js";
|
|
30
29
|
//# sourceMappingURL=index.js.map
|
package/dist/key-resolver.d.ts
CHANGED
|
@@ -56,7 +56,7 @@ export declare class ModelKeyPoisonedError extends Error {
|
|
|
56
56
|
}
|
|
57
57
|
/**
|
|
58
58
|
* Build a per-model API-key resolver for `TaskSpec.getApiKeyAndHeaders` from the catalog's
|
|
59
|
-
* name → env-var-NAME map (
|
|
59
|
+
* name → env-var-NAME map (web-admin `apiKeyEnv`). core threads this per brain call — and per cascade
|
|
60
60
|
* rung — so each model/rung authenticates with its OWN upstream account/key.
|
|
61
61
|
*
|
|
62
62
|
* A model absent from BOTH maps returns `undefined`, so core falls back to the brain's construction-time
|
package/dist/leader/wire.d.ts
CHANGED
|
@@ -69,7 +69,7 @@ export interface LeaderWireConfig {
|
|
|
69
69
|
* 得出这条 run 的入口体(`LeaderDeps.entry`);本 run 铸的每一条 spec 与 worker 的续跑体都从它取词。入口词是 `plan` 的 run 进不了这条车道
|
|
70
70
|
* (`leaderEntryRefusal`:worker 会话没有计划审阅通道)⇒ 出生处即以拒句收场;HTTP 受理口用同一只判据先答 422。
|
|
71
71
|
*
|
|
72
|
-
* 🔴 **函数席**(与 `deploymentPosture` / `durable` 同一条先例):`config.autonomy` 被
|
|
72
|
+
* 🔴 **函数席**(与 `deploymentPosture` / `durable` 同一条先例):`config.autonomy` 被 web-admin 原地热改,boot 期取一次值会把这条腿钉在起服那一刻。
|
|
73
73
|
* **必填**:没有 AUTONOMY 的装配递 `() => undefined` —— 缺席不是「没有地板」的合法拼法(权限轴上不许静默放宽)。
|
|
74
74
|
*/
|
|
75
75
|
autonomy: () => Autonomy | undefined;
|
|
@@ -101,7 +101,7 @@ export interface LeaderWireConfig {
|
|
|
101
101
|
usageWindowStore?: RunnerDeps["usageWindowStore"];
|
|
102
102
|
/**
|
|
103
103
|
* [ref]([ref])—— **center 发布的 prompt catalog** 席,原样递给本车道的每一只 Runner。唯一属主 =
|
|
104
|
-
* `boot/
|
|
104
|
+
* `boot/web-admin.ts` 的 `webAdmin.promptSource`(主 runner / subRunner 同一只;run-local 有自己
|
|
105
105
|
* 的等价腿)。缺席 ⇒ leader 的 planner/worker/repair/conflict 四类**顶层**任务跑引擎内置提示词,而同一
|
|
106
106
|
* 部署的 `/v1/tasks`、`/v1/runs` 跑运维发布的那一份 —— 且 core 顶层新任务走的是**静默**臂(pinned /
|
|
107
107
|
* parentCenterArtifactDigest 两支才 `prompt.snapshot_unavailable` fail-loud),运维面零信号。
|
package/dist/leader/wire.js
CHANGED
|
@@ -7,6 +7,7 @@ import { tmpdir } from "node:os";
|
|
|
7
7
|
import { Runner, combinePolicies, createDurableQuestionPolicy, QUESTION_AWAITS_RESUME, delimitUntrusted, hasDestroy, } from "@sema-agent/core";
|
|
8
8
|
import { leaderEntryRefusal, leaderRunEntry } from "./run-entry.js";
|
|
9
9
|
import { buildCheckpointCtx } from "../http/checkpoint-ctx.js";
|
|
10
|
+
import { serviceVersion } from "../service-version.js";
|
|
10
11
|
import { RemoteContainerExecutionEnv } from "../plugins/remote-env-e2b.js";
|
|
11
12
|
import { E2B_SANDBOX_HOME } from "../execution-lane-caps.js";
|
|
12
13
|
import { createDurableAskPolicy } from "../approval.js";
|
|
@@ -272,7 +273,7 @@ export function createLeaderRunner(cfg) {
|
|
|
272
273
|
const provisionWorker = async (sub) => {
|
|
273
274
|
const sessionId = `leader-${sub.workerId}-${Date.now()}`;
|
|
274
275
|
const durable = cfg.durable?.();
|
|
275
|
-
const resumeCtx = buildCheckpointCtx({ body: { ...entry, objective: sub.spec.objective }, unattendedLeg: true });
|
|
276
|
+
const resumeCtx = buildCheckpointCtx({ body: { ...entry, objective: sub.spec.objective }, unattendedLeg: true, writerVersion: serviceVersion() });
|
|
276
277
|
let durableSpec = {};
|
|
277
278
|
if (durable) {
|
|
278
279
|
const d = durable;
|
package/dist/main.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { fatalExit } from "./boot/fatal-exit.js";
|
|
2
2
|
import { runStage01 } from "./boot/stage-01-config.js";
|
|
3
|
-
import { runStage02 } from "./boot/stage-02-
|
|
3
|
+
import { runStage02 } from "./boot/stage-02-web-admin-pull.js";
|
|
4
4
|
import { runStage03 } from "./boot/stage-03-store-backend.js";
|
|
5
5
|
import { runStage04 } from "./boot/stage-04-stores.js";
|
|
6
6
|
import { runStage05 } from "./boot/stage-05-execution-env.js";
|
package/dist/mcp-tool-faces.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `McpServerSpec.toolFaces` —— MCP 工具的**面覆盖层**(core 7.8.0 [ref] §1.1/§2.7;声明面
|
|
3
3
|
* settings-schema 1.9.0)。一条规则、三条腿共用(请求腿 `task-mcp.ts normalizeServer` / center 腿
|
|
4
|
-
* `
|
|
4
|
+
* `web-admin-client/skills-mcp.ts resolveMcpServers` / 本地 config.d 腿 `config-provider.ts` 只做承载),
|
|
5
5
|
* 与 {@link import("./mcp-source-label.js").readMcpSourceLabel} 同一个「判据单点、三腿一致」的形。
|
|
6
6
|
*
|
|
7
7
|
* ## 分工(为什么本层**不**复述 core 的那张表)
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
* 该条、兄弟 server 照挂)。代价是真的(少一套工具),但它**响亮且立刻**;反方向的代价是一条
|
|
36
36
|
* **静默失效的安全声明**,而后者按 [ref] 不许存在于安全轴上;
|
|
37
37
|
* ③ 拿什么补偿 —— 报出来的名字本身:请求腿 `mcp_injection_dropped{dropped:[name]}`、center 腿
|
|
38
|
-
* `
|
|
38
|
+
* `web_admin_mcp_tool_faces_invalid{server,problem,note}` 一条点名 warn(`problem` 里带工具名与哪一段不合;运维照着改那一行即可)。
|
|
39
39
|
* 每只工具的面是**整只**判(core 明写 "applied whole or not at all");而**任一只**判不出形 ⇒ 整条 server
|
|
40
40
|
* 不进 —— 「留下好的那几只」同样是让坏的那一只无面挂载,与整张丢没有区别。
|
|
41
41
|
*/
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ModelEntryRefusalCode, type ModelPlaneRefusalCode, type ModelRefusalsSignal } from "@sema-agent/settings-schema";
|
|
2
|
-
import { type DroppedCatalogEntry } from "./
|
|
2
|
+
import { type DroppedCatalogEntry } from "./web-admin-client/read-warnings.js";
|
|
3
3
|
/**
|
|
4
4
|
* 条目拒因码 → 本仓铸它的成因 —— **以码为键**(S-768):码闭集的属主是 settings-schema(`MODEL_ENTRY_REFUSAL_CODES`,6.2.0 起;此前本仓
|
|
5
5
|
* 自持一份同名码表,撞名已消灭、零别名)。那边加一个条目码 ⇒ 本表缺键 ⇒ 本仓 tsc 红(只拿 `satisfies` 约束码值证明的是「子集」,
|
|
@@ -109,10 +109,10 @@ export declare function buildModelRefusalsSignal(v: ModelRefusalVerdict | undefi
|
|
|
109
109
|
* 不各写一份 `isReportableRefusalName` 判断。
|
|
110
110
|
*/
|
|
111
111
|
export declare function refusedNameLogField(key: string, name: string): Record<string, unknown>;
|
|
112
|
-
/** 一串被拒条目名的日志字段(`
|
|
112
|
+
/** 一串被拒条目名的日志字段(`web_admin_models` 行的 `unavailable`):只列可披露的名,被扣下的名**只数个数**(`<key>NamesWithheld`,0 个时键缺席)。 */
|
|
113
113
|
export declare function refusedNamesLogFields(key: string, names: readonly string[]): Record<string, unknown>;
|
|
114
114
|
/** 成因 → 它那一条 warn 的事件名(**穷举**)。两个名字是票面点名的既有/新事件,运维的告警规则按名挂。 */
|
|
115
|
-
export declare function refusalEventOf(reason: ModelEntryRefusalReason): "
|
|
115
|
+
export declare function refusalEventOf(reason: ModelEntryRefusalReason): "web_admin_model_no_brain" | "web_admin_model_entry_invalid";
|
|
116
116
|
/** warn 字段(不含值):`field` = 第一处坏字段(告警规则最常按它分组),`fields` = 全部。S-805:`model` 只在名可披露时写。 */
|
|
117
117
|
export declare function refusalWarnFields(name: string, r: ModelEntryRefusal): Record<string, unknown>;
|
|
118
118
|
/**
|
|
@@ -2,7 +2,7 @@ import { CC_MODEL_TIER_ALIASES, DEFAULT_TIER_ORDER, expandTiers } from "@sema-ag
|
|
|
2
2
|
import { ModelEntry, formatConfigPath, isReportableRefusalName } from "@sema-agent/settings-schema";
|
|
3
3
|
import { catalogBrainLane } from "./model-provider.js";
|
|
4
4
|
import { readCatalogEntryHeaders } from "./model-entry-headers.js";
|
|
5
|
-
import { DroppedCatalogEntryRow, describeSchemaIssueFields, describeSchemaIssues } from "./
|
|
5
|
+
import { DroppedCatalogEntryRow, describeSchemaIssueFields, describeSchemaIssues } from "./web-admin-client/read-warnings.js";
|
|
6
6
|
import { DEFAULT_MODEL_REF } from "./model-select.js";
|
|
7
7
|
export const ENTRY_REFUSAL_REASON_OF = {
|
|
8
8
|
"config.model_no_brain": "no_brain",
|
|
@@ -118,9 +118,9 @@ function nameSlot(name) {
|
|
|
118
118
|
export function refusalEventOf(reason) {
|
|
119
119
|
switch (reason) {
|
|
120
120
|
case "no_brain":
|
|
121
|
-
return "
|
|
121
|
+
return "web_admin_model_no_brain";
|
|
122
122
|
case "entry_invalid":
|
|
123
|
-
return "
|
|
123
|
+
return "web_admin_model_entry_invalid";
|
|
124
124
|
}
|
|
125
125
|
}
|
|
126
126
|
export function refusalWarnFields(name, r) {
|
|
@@ -146,7 +146,7 @@ export function defaultModelRefusal(view, leg) {
|
|
|
146
146
|
return (`MODEL_ID is required when no catalog default resolves [${DEFAULT_MODEL_MISSING_CODE}] — this model table has no default model` +
|
|
147
147
|
unavailable +
|
|
148
148
|
". Set MODEL_ID=<model name your gateway serves>, or enable at least one model this host can serve in the catalog " +
|
|
149
|
-
"(config.d/models.json, or the
|
|
149
|
+
"(config.d/models.json, or the web-admin) — either one is enough (a web-admin that answers after the boot budget " +
|
|
150
150
|
"counts as absent at boot: raise CONFIG_BOOT_FETCH_BUDGET_MS to wait for it).");
|
|
151
151
|
case "catalog":
|
|
152
152
|
return (`this catalog candidate has no default model [${DEFAULT_MODEL_MISSING_CODE}]` +
|
package/dist/model-provider.d.ts
CHANGED
|
@@ -60,7 +60,7 @@ export declare function modelBrainLane(provider: ModelProvider): ModelBrainLane;
|
|
|
60
60
|
*
|
|
61
61
|
* 🔴 为什么它与 {@link modelBrainLane} 不是同一只函数:两者的**输入保证不同**。
|
|
62
62
|
* · `MODEL_PROVIDER` 走 boot 闸(域外拒启)⇒ 到达 {@link modelBrainLane} 的恒是闭集词;
|
|
63
|
-
* · **目录条目**来自 settings-schema 的 `z.string()`,可以从
|
|
63
|
+
* · **目录条目**来自 settings-schema 的 `z.string()`,可以从 web-admin **热应用**进来 —— 那条路上
|
|
64
64
|
* 没有、也不该有「拒启」这回事(一次热发布不能让在跑的副本死),所以这里必然存在一条「认不出」的臂。
|
|
65
65
|
*
|
|
66
66
|
* 🔴 那条臂**就是今天的语义,本批一个字节都没改**([ref]「不可避免的运行期 miss 臂必须说出来」):
|
|
@@ -82,7 +82,7 @@ export declare function catalogBrainLane(provider: string | undefined): ModelBra
|
|
|
82
82
|
* `createBrain` 只在 anthropic 路由**装上**(`ANTHROPIC_API_KEY` / `ANTHROPIC_AUTH_TOKEN` 在场 ⇒
|
|
83
83
|
* `config.anthropic` 在场)时才铸 `createRoutingBrain({anthropic}, {fallback: gatewayStack})`;没装时整台机器
|
|
84
84
|
* 只有网关栈这一只 brain,**一切**条目(包括 `provider:"anthropic"` 的)都落 openai 兼容腿 ——
|
|
85
|
-
* `apply-effective.ts` 那条 `
|
|
85
|
+
* `apply-effective.ts` 那条 `web_admin_model_no_brain` warn 说的「mis-routes to the gateway brain」即此。
|
|
86
86
|
*
|
|
87
87
|
* 所以「这条路由要不要一个 openai 端点」的判据必须同时看词与装配:词判 {@link catalogBrainLane},
|
|
88
88
|
* 装配判路由在不在。本函数是这一合取的**唯一**写法 —— 端点判官(`model-route-endpoint.ts`)、降级腿与
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* · boot:`config.ts` 九域解析之后的跨域不变量区(锚 `CROSS-INVARIANT:model-route-endpoint`)⇒ 拒启;经 `model-route-gap.ts`
|
|
19
19
|
* 的 {@link judgeModelRouteGap}(env 读成本文件判据要的切面,与包根导出的纯判官是**同一只**);严格名册
|
|
20
20
|
* 布防(`isRosterGateArmed`)时 env 腿是占位、从不被派发 ⇒ 不判它(备用网关那一条照判);
|
|
21
|
-
* · 热路径:`
|
|
21
|
+
* · 热路径:`web-admin-client/apply-effective.ts` 的模型面 stage ⇒ 模型面组拒(opus 腿 O3:同候选其余组照落)、上一代模型面继续服务;
|
|
22
22
|
* · run-local:配置源解析完之后按真要派发的表再判一次(`run-local.ts`,7.98.0 合并复审 F2)—— 本入口没有名册门,
|
|
23
23
|
* loadConfig 对严格名册布防的占位豁免在这里兑现不了;没布防时恒惰性;
|
|
24
24
|
* · 登记:`config-invariants.ts` 的 `model-route-endpoint` 条(表的「不许有表外不变量」职责);
|
|
@@ -12,7 +12,7 @@ export declare const MODEL_ROUTE_URL_INVALID_CODE = "config.model_route_url_inva
|
|
|
12
12
|
*/
|
|
13
13
|
export declare const MODEL_ROUTE_URL_FRAGMENT_CODE = "config.model_route_url_fragment";
|
|
14
14
|
/**
|
|
15
|
-
* 模型路由 base URL 的拒因(`undefined` = 这一位合法)—— 判由
|
|
15
|
+
* 模型路由 base URL 的拒因(`undefined` = 这一位合法)—— 判由 settings-schema 的 `httpUrlFlaws`,本函数按**首个**拒因选码与出路句:
|
|
16
16
|
* ① 不是层级式 http(s) URL ⇒ `config.model_route_url_invalid`;
|
|
17
17
|
* ② 带 userinfo ⇒ `config.gateway_url_userinfo`;
|
|
18
18
|
* ③ 带 `#fragment` ⇒ `config.model_route_url_fragment`。
|
package/dist/model-route-url.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { httpUrlFlaws } from "@sema-agent/settings-schema";
|
|
2
|
+
import { buildHttpUrlRefusal } from "./url-refusal.js";
|
|
2
3
|
export const GATEWAY_URL_USERINFO_CODE = "config.gateway_url_userinfo";
|
|
3
4
|
export const MODEL_ROUTE_URL_INVALID_CODE = "config.model_route_url_invalid";
|
|
4
5
|
export const MODEL_ROUTE_URL_FRAGMENT_CODE = "config.model_route_url_fragment";
|
package/dist/model-select.d.ts
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { type Model, type RunnerDeps } from "@sema-agent/core";
|
|
2
|
+
import { type AtMention } from "@sema-agent/settings-schema";
|
|
2
3
|
import type { ModelEntryRefusal } from "./model-entry-refusal.js";
|
|
4
|
+
/** 座位缺席时的读法 —— 契约 prefault 解出来的值(今天是 `{mode:"all"}`),env 车道(没有中心)的 `config.atMention` 也是它。 */
|
|
5
|
+
export declare const DEFAULT_AT_MENTION: AtMention;
|
|
6
|
+
/** 一个 `models.atMention` 值的读法:缺席 ⇒ {@link DEFAULT_AT_MENTION};在场 ⇒ 契约 schema 判形,判不过 ⇒ `undefined`(调用方 fail-closed 并响亮)。 */
|
|
7
|
+
export declare function readAtMention(raw: unknown): AtMention | undefined;
|
|
3
8
|
/**
|
|
4
9
|
* Resolve the model ref for a task spec from the request (CLI `/model` picker + `run --model`).
|
|
5
10
|
*
|
|
@@ -37,7 +42,7 @@ export declare const DEFAULT_MODEL_REF = "default";
|
|
|
37
42
|
* 起不再各抄一份「展开 + 解」。
|
|
38
43
|
*/
|
|
39
44
|
export declare function resolveMainModel(plane: Pick<RunnerDeps, "models" | "tiers">): Model;
|
|
40
|
-
export declare function resolveTaskModel(bodyModel: unknown, objective: string, catalog: Record<string, unknown>,
|
|
45
|
+
export declare function resolveTaskModel(bodyModel: unknown, objective: string, catalog: Record<string, unknown>, atMention: AtMention, refusals?: Readonly<Record<string, ModelEntryRefusal>>): {
|
|
41
46
|
model: string;
|
|
42
47
|
cleanedObjective: string;
|
|
43
48
|
unknownExplicit?: string;
|
|
@@ -84,7 +89,7 @@ export declare function refusedCatalogEntry(ref: string, refusals: Readonly<Reco
|
|
|
84
89
|
name: string;
|
|
85
90
|
refusal: ModelEntryRefusal;
|
|
86
91
|
} | undefined;
|
|
87
|
-
/** [ref]
|
|
92
|
+
/** [ref] 判别式拒因:这次**用户选择**不在 `atMention` 许可之内(`none`,或 `only` 而不在名里)。`resolved` 已是目录 name 形(归一后)。 */
|
|
88
93
|
export interface ModelNotAllowed {
|
|
89
94
|
/** 调用方发来的原始 ref(name / 档位词 / 别名 / id / `@name`),已做过日志安全的 repr 归一。 */
|
|
90
95
|
requested: string;
|
|
@@ -94,28 +99,26 @@ export interface ModelNotAllowed {
|
|
|
94
99
|
source: "explicit" | "mention";
|
|
95
100
|
}
|
|
96
101
|
/**
|
|
97
|
-
* [ref] / [ref] ——
|
|
102
|
+
* [ref] / [ref] —— 「这个 ref 此刻可不可以被用户 `@` / 显式点选」的**唯一**判据(`models.atMention`,三态闭集,穷举 switch)。
|
|
98
103
|
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
+
* 判序(一条规则):先把 ref 归一到**目录条目**({@link matchCatalogModel},name / 档位词 / 别名 / id 同一只);目录里根本没有的 ref ⇒ 恒 `true`
|
|
105
|
+
* —— 那是「未知模型」那道门的辖区(fresh 400 / resume 降级留声),本门只答「在目录里,但准不准点」,两道门同码同拒会让消费端分不清
|
|
106
|
+
* "没这模型"和"不让你点"。然后按 `mode`:
|
|
107
|
+
* · `all` ⇒ `true`;
|
|
108
|
+
* · `none` ⇒ `false`(一个都不许);
|
|
109
|
+
* · `only` ⇒ ref 归一到的那只条目**自己的目录名**在名单里 ⇒ `true`(名单按目录名直比)。
|
|
104
110
|
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
111
|
+
* 为什么 ref 侧要先归一、不拿 ref 串直比:`expandTiers` 的增广目录里,档位词(`pro`)与 CC 别名(`sonnet`)的值与 `config.models[<name>]`
|
|
112
|
+
* 是**同一个对象引用**——裸串比较会让 `@pro` 跳过一张按 name 写的名单(同一只模型,两个键)。名单侧不归一:`only` 的名在 stage 期已按本世代
|
|
113
|
+
* 可用目录收窄成目录名(settings-schema `narrowAtMention`),名单项是档位词 / 别名 / id 的形只可能来自绕过 stage 的写者 —— 它们准不了任何东西。
|
|
114
|
+
* 🔴 **刻意没有「id 相等」退路**(codex 复审 R1 [high]):目录**允许两条不同 name 的条目共享同一个上游 `Model.id`,却各自带不同的
|
|
115
|
+
* `baseUrl` / `apiKeyEnv` / `cost` / provider** —— 按 id 判同会把 `safe` 与 `premium` 合并,一张只含 `safe` 的名单会放行 `premium`。
|
|
116
|
+
* 🔴 S-704:名里写着一条**不可用**条目的名字 ⇒ 它准不了任何东西(不经 id 回退 / 别名改绑去准另一只模型 —— `matchCatalogModel` 的名字保留律)。
|
|
117
|
+
* `only` 的名在 stage 期已按本世代可用目录收窄过(settings-schema `narrowAtMention`,收窄到一个不剩 ⇒ `none`),所以这里的悬空名只来自绕过 stage 的写者(按名直比,悬空名不等于任何条目的名)。
|
|
110
118
|
*
|
|
111
|
-
*
|
|
112
|
-
* 目录里根本没有的 ref ⇒ 恒 `true`:那是「未知模型」那道门的辖区(fresh 400 / resume 降级留声),
|
|
113
|
-
* 本门只答「在目录里,但准不准点」——两道门同码同拒会让消费端分不清"没这模型"和"不让你点"。
|
|
114
|
-
*
|
|
115
|
-
* ⚠️ 射程:本门是**提交时**门。core 运行时路由(degrade 降级链 / cascade 梯 / roles 解析)按 operator
|
|
116
|
-
* 配置自己走,**不经本门**——那不是一次用户选择,如实声明,不假装是运行时执法。
|
|
119
|
+
* ⚠️ 射程:本门是**提交时**门。core 运行时路由(degrade 降级链 / cascade 梯 / roles 解析)按 operator 配置自己走,**不经本门**。
|
|
117
120
|
*/
|
|
118
|
-
export declare function
|
|
121
|
+
export declare function isAtMentionable(ref: string, catalog: Record<string, unknown>, atMention: AtMention, refusals?: Readonly<Record<string, ModelEntryRefusal>>): boolean;
|
|
119
122
|
/**
|
|
120
123
|
* [ref] —— ref → **终端 catalog name**(拒因/日志的可读形)。
|
|
121
124
|
*
|
|
@@ -144,7 +147,7 @@ export type ModelImageInput = (typeof MODEL_IMAGE_INPUTS)[number];
|
|
|
144
147
|
* · 目录行 `GET /v1/models` 的 `vision`:`yes` ⇒ `true`,`no` ⇒ `false`,`undeclared` ⇒ **键缺席**(不替没声明的模型答「收」也不答「不收」);
|
|
145
148
|
* · 运行期的带图预检 {@link modelSupportsImages}:只有明说 `no` 才出信号。
|
|
146
149
|
* 此前两处各判各的,且对「没声明」答法相反(目录行报 false、预检放行)——客户端只读得到目录那一位,于是在手写、没声明 `input` 的
|
|
147
|
-
* 条目上把用户的图拦在了本地,而引擎其实会把图交给模型。env
|
|
150
|
+
* 条目上把用户的图拦在了本地,而引擎其实会把图交给模型。env 车道与 web-admin 车道恒写 `input`,分叉只落在手写目录条目上。
|
|
148
151
|
* `input` 不是数组(手写错形)与条目不在,同归 `undeclared`:没有可信的声明。
|
|
149
152
|
*/
|
|
150
153
|
export declare function modelImageInput(model: {
|
package/dist/model-select.js
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import { expandTiers, parseModelMention, resolveTaskModel as coreResolveTaskModel } from "@sema-agent/core";
|
|
2
|
+
import { DOMAIN_SCHEMAS } from "@sema-agent/settings-schema";
|
|
3
|
+
const AT_MENTION_SEAT = DOMAIN_SCHEMAS.models.shape.atMention;
|
|
4
|
+
export const DEFAULT_AT_MENTION = Object.freeze(AT_MENTION_SEAT.parse(undefined));
|
|
5
|
+
export function readAtMention(raw) {
|
|
6
|
+
const r = AT_MENTION_SEAT.safeParse(raw);
|
|
7
|
+
return r.success ? r.data : undefined;
|
|
8
|
+
}
|
|
2
9
|
export const DEFAULT_MODEL_REF = "default";
|
|
3
10
|
export function resolveMainModel(plane) {
|
|
4
11
|
const expanded = expandTiers(plane.models, plane.tiers ?? {}) ?? plane.models;
|
|
5
12
|
return coreResolveTaskModel({ model: DEFAULT_MODEL_REF }, { ...(expanded !== undefined ? { models: expanded } : {}) }).model;
|
|
6
13
|
}
|
|
7
|
-
export function resolveTaskModel(bodyModel, objective, catalog,
|
|
14
|
+
export function resolveTaskModel(bodyModel, objective, catalog, atMention, refusals) {
|
|
8
15
|
const mention = parseModelMention(objective, [...Object.keys(refusals ?? {}), ...Object.keys(catalog)]);
|
|
9
16
|
const mentionUsable = mention.model !== undefined && Object.hasOwn(catalog, mention.model) ? mention.model : undefined;
|
|
10
17
|
const explicit = typeof bodyModel === "string" ? matchCatalogModel(bodyModel, catalog, refusals) : undefined;
|
|
@@ -20,7 +27,7 @@ export function resolveTaskModel(bodyModel, objective, catalog, allowlist, refus
|
|
|
20
27
|
const unknown = present && explicit === undefined && refusedExplicit === undefined;
|
|
21
28
|
const model = explicit ?? mentionUsable ?? DEFAULT_MODEL_REF;
|
|
22
29
|
const picked = explicit !== undefined ? { ref: explicit, source: "explicit", requested: repr } : mentionUsable !== undefined ? { ref: mentionUsable, source: "mention", requested: mentionUsable } : undefined;
|
|
23
|
-
const notAllowed = picked !== undefined && !
|
|
30
|
+
const notAllowed = picked !== undefined && !isAtMentionable(picked.ref, catalog, atMention, refusals)
|
|
24
31
|
? { requested: picked.requested, resolved: terminalCatalogName(picked.ref, catalog, refusals) ?? picked.ref, source: picked.source }
|
|
25
32
|
: undefined;
|
|
26
33
|
return {
|
|
@@ -51,24 +58,22 @@ export function refusedCatalogEntry(ref, refusals) {
|
|
|
51
58
|
return { name, refusal: r };
|
|
52
59
|
return undefined;
|
|
53
60
|
}
|
|
54
|
-
export function
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const entry = catalogEntryOf(ref, catalog, refusals);
|
|
58
|
-
if (entry === undefined)
|
|
61
|
+
export function isAtMentionable(ref, catalog, atMention, refusals) {
|
|
62
|
+
const name = terminalCatalogName(ref, catalog, refusals);
|
|
63
|
+
if (name === undefined)
|
|
59
64
|
return true;
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if (allowed === undefined)
|
|
63
|
-
continue;
|
|
64
|
-
if (allowed === entry)
|
|
65
|
+
switch (atMention.mode) {
|
|
66
|
+
case "all":
|
|
65
67
|
return true;
|
|
68
|
+
case "none":
|
|
69
|
+
return false;
|
|
70
|
+
case "only":
|
|
71
|
+
return atMention.models.includes(name);
|
|
72
|
+
default: {
|
|
73
|
+
const unhandled = atMention;
|
|
74
|
+
throw new Error(`atMention: unknown mode ${JSON.stringify(unhandled)}`);
|
|
75
|
+
}
|
|
66
76
|
}
|
|
67
|
-
return false;
|
|
68
|
-
}
|
|
69
|
-
function catalogEntryOf(ref, catalog, refusals) {
|
|
70
|
-
const name = matchCatalogModel(ref, catalog, refusals);
|
|
71
|
-
return name === undefined ? undefined : catalog[name];
|
|
72
77
|
}
|
|
73
78
|
export function terminalCatalogName(ref, catalog, refusals) {
|
|
74
79
|
const key = matchCatalogModel(ref, catalog, refusals);
|
|
@@ -23,7 +23,7 @@ export declare class Metrics {
|
|
|
23
23
|
/** Structured snapshot of the whole registry — the OTLP exporter maps this to OTel data points
|
|
24
24
|
* (counters→Sum monotonic, gauges/dynamic→Gauge, histograms→Histogram). Read-only copy. */
|
|
25
25
|
snapshot(): MetricSnapshot;
|
|
26
|
-
/** Curated health summary (friendly JSON) for a lightweight fleet dashboard — the
|
|
26
|
+
/** Curated health summary (friendly JSON) for a lightweight fleet dashboard — the web-admin's
|
|
27
27
|
* fleet page fetches this per worker and renders cards + computes rates over polls (no Prometheus
|
|
28
28
|
* needed). Counters are cumulative totals; histograms are reported as averages (sum/count). */
|
|
29
29
|
summarize(): MetricsSummary;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Org 记忆准入 resolver — server 侧对接 @sema-agent/core@5.13.0 `RunnerDeps.memoryScopeAdmission` seam。
|
|
3
|
-
* 授权事实来自「目录」抽象:远程腿 =
|
|
3
|
+
* 授权事实来自「目录」抽象:远程腿 = web-admin per-principal caps 响应里的 `orgMemory` 段(形状
|
|
4
4
|
* 同源锚 = registry-core `PrincipalOrgMemoryWire`,zod schema 直接 safeParse);单机腿 = env JSON 静态表
|
|
5
5
|
* (`MEMORY_ORG_DIRECTORY_JSON`,{@link parseOrgDirectoryStatic} 装载,启动期 fail-loud)。
|
|
6
6
|
*
|