@sema-agent/server 7.79.1 → 7.79.3
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/dist/boot/late-binds.d.ts +35 -0
- package/dist/boot/late-binds.js +20 -0
- package/dist/boot/stage-01-config.d.ts +7 -0
- package/dist/boot/stage-01-config.js +60 -0
- package/dist/boot/stage-02-registry-pull.d.ts +10 -0
- package/dist/boot/stage-02-registry-pull.js +11 -0
- package/dist/boot/stage-03-store-backend.d.ts +32 -0
- package/dist/boot/stage-03-store-backend.js +11 -0
- package/dist/boot/stage-04-stores.d.ts +69 -0
- package/dist/boot/stage-04-stores.js +49 -0
- package/dist/boot/stage-05-execution-env.d.ts +82 -0
- package/dist/boot/stage-05-execution-env.js +20 -0
- package/dist/boot/stage-06-runners.d.ts +143 -0
- package/dist/boot/stage-06-runners.js +207 -0
- package/dist/boot/stage-07-capability-layer.d.ts +157 -0
- package/dist/boot/stage-07-capability-layer.js +162 -0
- package/dist/boot/stage-08-reapers.d.ts +172 -0
- package/dist/boot/stage-08-reapers.js +78 -0
- package/dist/boot/stage-09-leader.d.ts +204 -0
- package/dist/boot/stage-09-leader.js +47 -0
- package/dist/boot/stage-10-http-server.d.ts +204 -0
- package/dist/boot/stage-10-http-server.js +289 -0
- package/dist/config-invariants.d.ts +9 -0
- package/dist/config-invariants.js +7 -1
- package/dist/config-types.d.ts +1 -1
- package/dist/http/dispatch.d.ts +9 -73
- package/dist/http/dispatch.js +12 -281
- package/dist/http/route-table.d.ts +113 -0
- package/dist/http/route-table.js +235 -0
- package/dist/http/routes/admin-memory-optout.d.ts +1 -1
- package/dist/http/routes/memory-compliance.d.ts +1 -1
- package/dist/http/routes/memory-origin.d.ts +1 -1
- package/dist/http/routes/rules.js +4 -4
- package/dist/http/server.d.ts +2 -1
- package/dist/http/server.js +2 -1
- package/dist/main.js +20 -870
- package/dist/service-version.d.ts +5 -0
- package/dist/service-version.js +12 -0
- package/dist/trace/redact.d.ts +16 -6
- package/dist/trace/redact.js +568 -246
- package/package.json +1 -1
package/dist/http/dispatch.js
CHANGED
|
@@ -2,221 +2,13 @@ import { createHash } from "node:crypto";
|
|
|
2
2
|
import { setSsoPrincipal, ssoVerifiedPrincipal, setSsoScope, isDestructiveSessionWrite, PRINCIPAL_TOKEN_HEADER, APPROVAL_MAC_HEADER, APPROVAL_MAC_KID_HEADER } from "../security.js";
|
|
3
3
|
import { publicStoreProbeError } from "../store-live-probe.js";
|
|
4
4
|
import { looksLikeJwt } from "@sema-agent/settings-schema/api/auth-bridge";
|
|
5
|
-
import {
|
|
6
|
-
import { handleObservability } from "./routes/observability.js";
|
|
7
|
-
import { handleDiagnostics } from "./routes/diagnostics.js";
|
|
8
|
-
import { handleAdoption } from "./routes/adoption.js";
|
|
9
|
-
import { handleRetention } from "./routes/retention-ops.js";
|
|
10
|
-
import { handleAdminDrain } from "./routes/admin-drain.js";
|
|
11
|
-
import { handleDevices } from "./routes/devices.js";
|
|
12
|
-
import { handleAdminConfigRefresh } from "./routes/admin-config-refresh.js";
|
|
13
|
-
import { handleConfigCatalog } from "./routes/config-catalog.js";
|
|
14
|
-
import { handleMemoryOptOut } from "./routes/admin-memory-optout.js";
|
|
15
|
-
import { handleMemoryPolicy } from "./routes/memory-policy.js";
|
|
16
|
-
import { handleMemoryBundle } from "./routes/memory-bundle.js";
|
|
17
|
-
import { handleMemoryCompliance } from "./routes/memory-compliance.js";
|
|
18
|
-
import { handleMemoryOrigin } from "./routes/memory-origin.js";
|
|
19
|
-
import { handleMemoryConsolidation } from "./routes/memory-consolidation.js";
|
|
20
|
-
import { handleSharedMemory } from "./routes/shared-memory.js";
|
|
21
|
-
import { handleRules } from "./routes/rules.js";
|
|
22
|
-
import { handleSessionsList } from "./routes/sessions-list.js";
|
|
23
|
-
import { handleAgentRoster } from "./routes/agents-roster.js";
|
|
24
|
-
import { handleSessions } from "./routes/sessions.js";
|
|
25
|
-
import { handleSessionSync } from "./routes/session-sync.js";
|
|
26
|
-
import { handleAttachments } from "./routes/attachments.js";
|
|
27
|
-
import { handleFleet } from "./routes/fleet.js";
|
|
28
|
-
import { handleA2aServe, handleA2a } from "./routes/a2a-serve.js";
|
|
29
|
-
import { handleTraceUsage } from "./routes/trace-usage.js";
|
|
30
|
-
import { handleWorkflows, handleWorkflowAgentSteer } from "./routes/workflows.js";
|
|
31
|
-
import { handleNotifyWake, SESSION_WAKE_RE } from "./routes/notify-wake.js";
|
|
32
|
-
import { handleApprovalsAssistant, ASSISTANT_RESUME_RE, ASSISTANT_PLAN_REVIEW_RE } from "./routes/approvals-assistant.js";
|
|
33
|
-
import { handleRuns, handleRunVerbs, RUN_SUBAGENT_RESUME_RE } from "./routes/runs.js";
|
|
34
|
-
import { handleRunMemoryCapture } from "./routes/run-memory-capture.js";
|
|
35
|
-
import { handleSideQuery } from "./routes/side-query.js";
|
|
36
|
-
import { handleTasks } from "./routes/tasks.js";
|
|
37
|
-
import { handleLeader } from "./routes/leader.js";
|
|
38
|
-
import { handleImages } from "./routes/images.js";
|
|
5
|
+
import { PRE_CREDENTIAL_ROUTES, POST_CREDENTIAL_ROUTES, routeLabel, isBillableSubmitPath, isCredentialGatedRewrite, isMethodDispatchedSubmitPath } from "./route-table.js";
|
|
39
6
|
import { sendJson, sendError, isSseResponse } from "./send.js";
|
|
40
7
|
import { authorized, systemFor } from "./principal-gate.js";
|
|
41
8
|
const PROCESS_STARTED_AT_MS = Date.now() - Math.round(process.uptime() * 1000);
|
|
42
|
-
const ROUTE_DOMAINS = [
|
|
43
|
-
handleTraceUsage,
|
|
44
|
-
handleWorkflows,
|
|
45
|
-
handleFleet,
|
|
46
|
-
handleA2aServe,
|
|
47
|
-
handleCapabilities,
|
|
48
|
-
handleSideQuery,
|
|
49
|
-
handleTasks,
|
|
50
|
-
handleRuns,
|
|
51
|
-
handleA2a,
|
|
52
|
-
handleWorkflowAgentSteer,
|
|
53
|
-
handleRunVerbs,
|
|
54
|
-
handleRunMemoryCapture,
|
|
55
|
-
handleLeader,
|
|
56
|
-
handleImages,
|
|
57
|
-
handleApprovalsAssistant,
|
|
58
|
-
handleObservability,
|
|
59
|
-
handleDiagnostics,
|
|
60
|
-
handleAdoption,
|
|
61
|
-
handleRetention,
|
|
62
|
-
handleAdminDrain,
|
|
63
|
-
handleDevices,
|
|
64
|
-
handleAdminConfigRefresh,
|
|
65
|
-
handleConfigCatalog,
|
|
66
|
-
handleMemoryOptOut,
|
|
67
|
-
handleMemoryPolicy,
|
|
68
|
-
handleMemoryBundle,
|
|
69
|
-
handleMemoryCompliance,
|
|
70
|
-
handleMemoryOrigin,
|
|
71
|
-
handleMemoryConsolidation,
|
|
72
|
-
handleRules,
|
|
73
|
-
handleSharedMemory,
|
|
74
|
-
handleSessionsList,
|
|
75
|
-
handleAgentRoster,
|
|
76
|
-
handleSessions,
|
|
77
|
-
handleSessionSync,
|
|
78
|
-
handleAttachments,
|
|
79
|
-
handleNotifyWake,
|
|
80
|
-
];
|
|
81
|
-
void ROUTE_DOMAINS;
|
|
82
|
-
export function isMethodDispatchedSubmitPath(url) {
|
|
83
|
-
return url === "/v1/a2a";
|
|
84
|
-
}
|
|
85
9
|
export function hasServiceAuth(config) {
|
|
86
10
|
return Boolean(config.authToken) || Object.keys(config.authTokens ?? {}).length > 0;
|
|
87
11
|
}
|
|
88
|
-
export function isBillableSubmitPath(url) {
|
|
89
|
-
return (url === "/v1/side-query" ||
|
|
90
|
-
url === "/v1/tasks" ||
|
|
91
|
-
url === "/v1/tasks/stream" ||
|
|
92
|
-
url === "/v1/runs" ||
|
|
93
|
-
url === "/v1/leader" ||
|
|
94
|
-
url === "/v1/a2a" ||
|
|
95
|
-
url === "/v1/admin/memory/consolidation/run" ||
|
|
96
|
-
ASSISTANT_RESUME_RE.test(url) ||
|
|
97
|
-
ASSISTANT_PLAN_REVIEW_RE.test(url) ||
|
|
98
|
-
RUN_SUBAGENT_RESUME_RE.test(url) ||
|
|
99
|
-
SESSION_WAKE_RE.test(url) ||
|
|
100
|
-
url.startsWith("/v1/approvals"));
|
|
101
|
-
}
|
|
102
|
-
export function isCredentialGatedRewrite(method, url) {
|
|
103
|
-
const m = method.toUpperCase();
|
|
104
|
-
if (m === "POST") {
|
|
105
|
-
return (url === "/v1/adoption" ||
|
|
106
|
-
url.startsWith("/v1/rules/cc-import/") ||
|
|
107
|
-
url.startsWith("/v1/rules/local-import/") ||
|
|
108
|
-
url === "/v1/memory/import" ||
|
|
109
|
-
url === "/v1/memory/export" ||
|
|
110
|
-
url === "/v1/memory/erase" ||
|
|
111
|
-
url.startsWith("/v1/memory/origin/entries/") ||
|
|
112
|
-
url.startsWith("/v1/devices/"));
|
|
113
|
-
}
|
|
114
|
-
if (m === "PUT")
|
|
115
|
-
return url === "/v1/admin/memory-optout" || url.startsWith("/v1/admin/memory-optout/");
|
|
116
|
-
if (m === "DELETE")
|
|
117
|
-
return url === "/v1/rules" || url.startsWith("/v1/admin/memory-optout/");
|
|
118
|
-
if (m === "GET") {
|
|
119
|
-
return (/^\/v1\/memory\/entries\/[^/]+\/provenance$/.test(url) ||
|
|
120
|
-
url === "/v1/memory/origin/external" ||
|
|
121
|
-
url === "/v1/memory/origin/clearances" ||
|
|
122
|
-
url === "/v1/admin/memory-optout" ||
|
|
123
|
-
url === "/v1/devices" ||
|
|
124
|
-
/^\/v1\/devices\/sessions\/[^/]+$/.test(url));
|
|
125
|
-
}
|
|
126
|
-
return false;
|
|
127
|
-
}
|
|
128
|
-
const ROUTE_LABEL_PATTERNS = [
|
|
129
|
-
[/^\/v1\/runs\/[^/]+\/steer$/, "/v1/runs/:id/steer"],
|
|
130
|
-
[/^\/v1\/runs\/[^/]+\/memory\/capture-optout$/, "/v1/runs/:id/memory/capture-optout"],
|
|
131
|
-
[/^\/v1\/runs\/[^/]+\/interrupt$/, "/v1/runs/:id/interrupt"],
|
|
132
|
-
[/^\/v1\/runs\/[^/]+\/detach$/, "/v1/runs/:id/detach"],
|
|
133
|
-
[/^\/v1\/runs\/[^/]+\/cancel$/, "/v1/runs/:id/cancel"],
|
|
134
|
-
[/^\/v1\/runs\/[^/]+\/compact$/, "/v1/runs/:id/compact"],
|
|
135
|
-
[/^\/v1\/runs\/[^/]+\/events$/, "/v1/runs/:id/events"],
|
|
136
|
-
[/^\/v1\/runs\/[^/]+\/subagents\/[^/]+\/(steer|resume|output|stream)$/, "/v1/runs/:id/subagents/:sub/*"],
|
|
137
|
-
[/^\/v1\/runs\/[^/]+\/tasks\/[^/]+\/(output|stop)$/, "/v1/runs/:id/tasks/:tid/*"],
|
|
138
|
-
[/^\/v1\/runs\/[^/]+$/, "/v1/runs/:id"],
|
|
139
|
-
[/^\/v1\/images\/bakes\/[^/]+\/events$/, "/v1/images/bakes/:id/events"],
|
|
140
|
-
[/^\/v1\/images\/bakes\/[^/]+\/cancel$/, "/v1/images/bakes/:id/cancel"],
|
|
141
|
-
[/^\/v1\/images\/bakes\/[^/]+\/claim$/, "/v1/images/bakes/:id/claim"],
|
|
142
|
-
[/^\/v1\/images\/bakes\/[^/]+\/ingest$/, "/v1/images/bakes/:id/ingest"],
|
|
143
|
-
[/^\/v1\/images\/bakes\/[^/]+$/, "/v1/images/bakes/:id"],
|
|
144
|
-
[/^\/v1\/images\/digests\/[^/]+$/, "/v1/images/digests/:digest"],
|
|
145
|
-
[/^\/v1\/images\/[^/]+$/, "/v1/images/:profile"],
|
|
146
|
-
[/^\/v1\/approvals\/[^/]+\/decide$/, "/v1/approvals/:id/decide"],
|
|
147
|
-
[/^\/v1\/approvals\/[^/]+\/exemptions(\/[^/]+)?$/, "/v1/approvals/:id/exemptions"],
|
|
148
|
-
[/^\/v1\/sessions\/[^/]+\/(wake|fork|init|notify|events|head|mcp|a2a|policy|settings)$/, "/v1/sessions/:id/$verb"],
|
|
149
|
-
[/^\/v1\/admin\/memory-optout\/[^/]+$/, "/v1/admin/memory-optout/:principal"],
|
|
150
|
-
[/^\/v1\/sessions\/[^/]+\/memory\/erase$/, "/v1/sessions/:id/memory/erase"],
|
|
151
|
-
[/^\/v1\/sessions\/[^/]+\/memory-status$/, "/v1/sessions/:id/memory-status"],
|
|
152
|
-
[/^\/v1\/sessions\/[^/]+\/sync\/(manifest|entries|plan)$/, "/v1/sessions/:id/sync/$verb"],
|
|
153
|
-
[/^\/v1\/sessions\/[^/]+\/sync\/import(\/[^/]+\/entries)?$/, "/v1/sessions/:id/sync/import"],
|
|
154
|
-
[/^\/v1\/sessions\/[^/]+\/sync\/blobs(\/[^/]+)?$/, "/v1/sessions/:id/sync/blobs"],
|
|
155
|
-
[/^\/v1\/sessions\/[^/]+\/sync\/history\/blobs\/[^/]+$/, "/v1/sessions/:id/sync/history/blobs/:hash"],
|
|
156
|
-
[/^\/v1\/sessions\/[^/]+\/workspace(\/[^/]+(\/(tree|file|archive))?)?$/, "/v1/sessions/:id/workspace"],
|
|
157
|
-
[/^\/v1\/sessions\/[^/]+$/, "/v1/sessions/:id"],
|
|
158
|
-
[/^\/v1\/assistant\/tasks\/[^/]+\/preempt$/, "/v1/assistant/tasks/:id/preempt"],
|
|
159
|
-
[/^\/v1\/assistant\/tasks\/[^/]+\/resume$/, "/v1/assistant/tasks/:id/resume"],
|
|
160
|
-
[/^\/v1\/assistant\/tasks\/[^/]+\/plan_review$/, "/v1/assistant/tasks/:id/plan_review"],
|
|
161
|
-
[/^\/v1\/elicitations\/[^/]+\/respond$/, "/v1/elicitations/:id/respond"],
|
|
162
|
-
[/^\/v1\/questions\/[^/]+\/respond$/, "/v1/questions/:id/respond"],
|
|
163
|
-
[/^\/v1\/tool-approvals\/[^/]+\/respond$/, "/v1/tool-approvals/:id/respond"],
|
|
164
|
-
[/^\/v1\/workflows\/[^/]+\/agents\/[^/]+\/steer$/, "/v1/workflows/:id/agents/:aid/steer"],
|
|
165
|
-
[/^\/v1\/workflows\/[^/]+\/(stream|journal)$/, "/v1/workflows/:id/$sub"],
|
|
166
|
-
[/^\/v1\/workflows\/[^/]+$/, "/v1/workflows/:id"],
|
|
167
|
-
[/^\/v1\/tasks\/[^/]+\/asks\/[^/]+\/decision$/, "/v1/tasks/:id/asks/:askId/decision"],
|
|
168
|
-
[/^\/v1\/tasks\/[^/]+\/tool-results\/[^/]+$/, "/v1/tasks/:id/tool-results/:ref"],
|
|
169
|
-
[/^\/v1\/tasks\/[^/]+\/(turns|stream|artifacts)$/, "/v1/tasks/:id/$sub"],
|
|
170
|
-
[/^\/v1\/leader\/[^/]+$/, "/v1/leader/:id"],
|
|
171
|
-
[/^\/v1\/devices\/sessions\/[^/]+\/rebind$/, "/v1/devices/sessions/:id/rebind"],
|
|
172
|
-
[/^\/v1\/devices\/sessions\/[^/]+$/, "/v1/devices/sessions/:id"],
|
|
173
|
-
[/^\/v1\/attachments\/[^/]+$/, "/v1/attachments/:id"],
|
|
174
|
-
[/^\/v1\/capabilities\/scenarios\/[^/]+$/, "/v1/capabilities/scenarios/:name"],
|
|
175
|
-
[/^\/v1\/adoption\/[^/]+$/, "/v1/adoption/:id"],
|
|
176
|
-
[/^\/v1\/ops\/retention\/holds\/[^/]*$/, "/v1/ops/retention/holds/:domain"],
|
|
177
|
-
[/^\/v1\/memory\/sync\/[^/]+$/, "/v1/memory/sync/:scope"],
|
|
178
|
-
[/^\/v1\/memory\/entries\/[^/]+\/provenance$/, "/v1/memory/entries/:entryId/provenance"],
|
|
179
|
-
[/^\/v1\/memory\/origin\/entries\/[^/]+\/clear$/, "/v1/memory/origin/entries/:entryId/clear"],
|
|
180
|
-
[/^\/v1\/usage\/(summary|series|breakdown)$/, "/v1/usage/$sub"],
|
|
181
|
-
[/^\/v1\/shared-memory\/stores\/[^/]+\/documents$/, "/v1/shared-memory/stores/:store/documents"],
|
|
182
|
-
[/^\/v1\/shared-memory\/stores\/[^/]+\/document$/, "/v1/shared-memory/stores/:store/document"],
|
|
183
|
-
];
|
|
184
|
-
const ROUTE_LABEL_LITERALS = new Set([
|
|
185
|
-
"/health", "/metrics", "/metrics/summary", "/metrics/plan-cache",
|
|
186
|
-
"/v1/models", "/v1/tasks", "/v1/tasks/stream", "/v1/tasks/source-summary",
|
|
187
|
-
"/v1/runs", "/v1/sessions", "/v1/approvals", "/v1/approvals/stream",
|
|
188
|
-
"/v1/assistant/inbox", "/v1/assistant/tasks", "/v1/usage", "/v1/policy", "/v1/capabilities",
|
|
189
|
-
"/v1/images", "/v1/images/bakes", "/v1/images/bakes/claim", "/v1/images/select", "/v1/images/register",
|
|
190
|
-
"/v1/workflows", "/v1/attachments", "/v1/leader", "/v1/outcomes", "/v1/side-query",
|
|
191
|
-
"/v1/devices",
|
|
192
|
-
"/v1/fleet/stream",
|
|
193
|
-
"/v1/memory/export", "/v1/sendfile-links",
|
|
194
|
-
"/v1/memory/import",
|
|
195
|
-
"/v1/memory/erase",
|
|
196
|
-
"/v1/memory/origin/external", "/v1/memory/origin/clearances",
|
|
197
|
-
"/v1/shared-memory/stores",
|
|
198
|
-
"/v1/diagnostics/wiring",
|
|
199
|
-
"/v1/adoption",
|
|
200
|
-
"/v1/admin/drain",
|
|
201
|
-
"/v1/admin/config/refresh",
|
|
202
|
-
"/v1/config/catalog",
|
|
203
|
-
"/v1/admin/memory-optout",
|
|
204
|
-
"/v1/admin/memory/consolidation/run", "/v1/admin/memory/consolidation",
|
|
205
|
-
"/v1/rules/cc-import/prepare", "/v1/rules/cc-import/redeem",
|
|
206
|
-
"/v1/rules/local-import/prepare", "/v1/rules/local-import/redeem",
|
|
207
|
-
"/v1/rules",
|
|
208
|
-
"/.well-known/agent-card.json", "/v1/a2a",
|
|
209
|
-
"/v1/agents/roster",
|
|
210
|
-
"/v1/ops/retention/audit",
|
|
211
|
-
]);
|
|
212
|
-
export function routeLabel(_method, url) {
|
|
213
|
-
if (ROUTE_LABEL_LITERALS.has(url))
|
|
214
|
-
return url;
|
|
215
|
-
for (const [re, label] of ROUTE_LABEL_PATTERNS)
|
|
216
|
-
if (re.test(url))
|
|
217
|
-
return label;
|
|
218
|
-
return "other";
|
|
219
|
-
}
|
|
220
12
|
function cors(res, req, origins, principalHeader) {
|
|
221
13
|
if (!origins || origins.length === 0)
|
|
222
14
|
return;
|
|
@@ -250,6 +42,15 @@ export function createDispatch(ctx) {
|
|
|
250
42
|
};
|
|
251
43
|
deps.drainState.lastAttachEndedAt = () => lastAttachEndedAt;
|
|
252
44
|
}
|
|
45
|
+
async function dispatchSegment(rows, req, res, url, ctx) {
|
|
46
|
+
for (const row of rows) {
|
|
47
|
+
if (row.enabled !== undefined && !row.enabled(deps))
|
|
48
|
+
continue;
|
|
49
|
+
if (await row.handler(req, res, url, ctx))
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
253
54
|
async function handle(req, res) {
|
|
254
55
|
const startedAt = Date.now();
|
|
255
56
|
const method = req.method ?? "GET";
|
|
@@ -379,13 +180,7 @@ export function createDispatch(ctx) {
|
|
|
379
180
|
}
|
|
380
181
|
}
|
|
381
182
|
}
|
|
382
|
-
if (await
|
|
383
|
-
return;
|
|
384
|
-
if (await handleWorkflows(req, res, url, ctx))
|
|
385
|
-
return;
|
|
386
|
-
if (await handleFleet(req, res, url, ctx))
|
|
387
|
-
return;
|
|
388
|
-
if (await handleA2aServe(req, res, url, ctx))
|
|
183
|
+
if (await dispatchSegment(PRE_CREDENTIAL_ROUTES, req, res, url, ctx))
|
|
389
184
|
return;
|
|
390
185
|
let source = null;
|
|
391
186
|
const anyServiceAuth = hasServiceAuth(deps.config);
|
|
@@ -426,71 +221,7 @@ export function createDispatch(ctx) {
|
|
|
426
221
|
sendError(res, 503, "auth.service_token_required", "this worker requires a service auth token (set SERVICE_AUTH_TOKEN) before accepting destructive session writes (policy / sync-import / fork / delete)");
|
|
427
222
|
return;
|
|
428
223
|
}
|
|
429
|
-
if (await
|
|
430
|
-
return;
|
|
431
|
-
if (await handleSideQuery(req, res, url, ctx))
|
|
432
|
-
return;
|
|
433
|
-
if (await handleTasks(req, res, url, ctx))
|
|
434
|
-
return;
|
|
435
|
-
if (await handleRuns(req, res, url, ctx))
|
|
436
|
-
return;
|
|
437
|
-
if (await handleA2a(req, res, url, ctx))
|
|
438
|
-
return;
|
|
439
|
-
if (await handleWorkflowAgentSteer(req, res, url, ctx))
|
|
440
|
-
return;
|
|
441
|
-
if (await handleRunVerbs(req, res, url, ctx))
|
|
442
|
-
return;
|
|
443
|
-
if (await handleRunMemoryCapture(req, res, url, ctx))
|
|
444
|
-
return;
|
|
445
|
-
if (await handleLeader(req, res, url, ctx))
|
|
446
|
-
return;
|
|
447
|
-
if (await handleImages(req, res, url, ctx))
|
|
448
|
-
return;
|
|
449
|
-
if (await handleApprovalsAssistant(req, res, url, ctx))
|
|
450
|
-
return;
|
|
451
|
-
if (await handleObservability(req, res, url, ctx))
|
|
452
|
-
return;
|
|
453
|
-
if (await handleDiagnostics(req, res, url, ctx))
|
|
454
|
-
return;
|
|
455
|
-
if (await handleAdoption(req, res, url, ctx))
|
|
456
|
-
return;
|
|
457
|
-
if (await handleRetention(req, res, url, ctx))
|
|
458
|
-
return;
|
|
459
|
-
if (await handleAdminDrain(req, res, url, ctx))
|
|
460
|
-
return;
|
|
461
|
-
if (await handleDevices(req, res, url, ctx))
|
|
462
|
-
return;
|
|
463
|
-
if (await handleAdminConfigRefresh(req, res, url, ctx))
|
|
464
|
-
return;
|
|
465
|
-
if (await handleConfigCatalog(req, res, url, ctx))
|
|
466
|
-
return;
|
|
467
|
-
if (await handleMemoryOptOut(req, res, url, ctx))
|
|
468
|
-
return;
|
|
469
|
-
if (await handleMemoryPolicy(req, res, url, ctx))
|
|
470
|
-
return;
|
|
471
|
-
if (await handleMemoryBundle(req, res, url, ctx))
|
|
472
|
-
return;
|
|
473
|
-
if (await handleMemoryCompliance(req, res, url, ctx))
|
|
474
|
-
return;
|
|
475
|
-
if (await handleMemoryOrigin(req, res, url, ctx))
|
|
476
|
-
return;
|
|
477
|
-
if (deps.memoryConsolidation && (await handleMemoryConsolidation(req, res, url, ctx)))
|
|
478
|
-
return;
|
|
479
|
-
if (await handleRules(req, res, url, ctx))
|
|
480
|
-
return;
|
|
481
|
-
if (deps.sharedMemoryStore && deps.orgMemoryDirectory && (await handleSharedMemory(req, res, url, ctx)))
|
|
482
|
-
return;
|
|
483
|
-
if (await handleSessionsList(req, res, url, ctx))
|
|
484
|
-
return;
|
|
485
|
-
if (await handleAgentRoster(req, res, url, ctx))
|
|
486
|
-
return;
|
|
487
|
-
if (await handleSessions(req, res, url, ctx))
|
|
488
|
-
return;
|
|
489
|
-
if (await handleSessionSync(req, res, url, ctx))
|
|
490
|
-
return;
|
|
491
|
-
if (await handleAttachments(req, res, url, ctx))
|
|
492
|
-
return;
|
|
493
|
-
if (await handleNotifyWake(req, res, url, ctx))
|
|
224
|
+
if (await dispatchSegment(POST_CREDENTIAL_ROUTES, req, res, url, ctx))
|
|
494
225
|
return;
|
|
495
226
|
sendError(res, 404, "not_found.route", "not found");
|
|
496
227
|
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* **路由声明表**(S-146,[ref] 波 2 第二刀)—— 「这是什么路由」这件事在本仓的**唯一属主**。
|
|
3
|
+
*
|
|
4
|
+
* ## 病(S-146 债行原文的读数)
|
|
5
|
+
* 同一件事此前有五份写法、两道扫源码文本的对账门,而那两道门已经**反向塑形了源码**:表里必须写
|
|
6
|
+
* 字面量不许引常量(否则门的正则抓不到)、注释里不许出现某两个字符(否则门的非贪婪捕获提前收尾)。
|
|
7
|
+
* ① 分派序 = `handle()` 里 37 只 `if (await handleX(...)) return;`,鉴权/排空/破坏性写三道门按**行号**
|
|
8
|
+
* 插在链中间(4 只 handler 落在凭据门前);
|
|
9
|
+
* ② `ROUTE_DOMAINS` = 同一条链的域名册,靠一道从 `handle()` 源码文本抽序的门与 ① 对拍(表曾漏员又乱序);
|
|
10
|
+
* ③ `ROUTE_LABEL_PATTERNS` / `ROUTE_LABEL_LITERALS` = metrics/日志的标签名册;
|
|
11
|
+
* ④ `isBillableSubmitPath` / `isMethodDispatchedSubmitPath` = 三道 503 计费门的 url 名单;
|
|
12
|
+
* ⑤ `isCredentialGatedRewrite` = 无凭据部署上的改写门 url×方法 名单。
|
|
13
|
+
* 五份各自漂过:wake 不在 ④ 里(三道门对一条烧模型的腿全不生效)、`handleDiagnostics` 从不在 ② 里、
|
|
14
|
+
* `/v1/fleet/stream` 整条对 ③ 隐形。
|
|
15
|
+
*
|
|
16
|
+
* ## 形(规则少了几条)
|
|
17
|
+
* **一行 = 一条路由事实**,两张表:
|
|
18
|
+
* · `ROUTES` —— **行序 = 分派序**,`position` 说它在全局服务凭据门的哪一侧。门不再「按行号插在链中间」,
|
|
19
|
+
* 而是在 `pre` 段与 `post` 段之间**恒定一处**执行 ⇒ ① 与 ② 合一(名册就是分派序本身,两者再不可能漂),
|
|
20
|
+
* 那道「从 handle() 源码抽序对拍」的门随之删掉 —— 不是放松,是它守的事变成了结构上不可违反。
|
|
21
|
+
* ⚠️ 刻意**不引入 matcher**:handler 自己判 url 这一点一个字不动(改它等于重写 34 个域模块的判路)。
|
|
22
|
+
* · `ROUTE_DECLARATIONS` —— ③④⑤ 合成一张;一行声明它的匹配式与它**真有**的性质
|
|
23
|
+
* (`billable` / `credentialGated` / `methodDispatched`),没有该性质就不写那一列(零默认值)。
|
|
24
|
+
*
|
|
25
|
+
* 判据两条,逐字:
|
|
26
|
+
* · **标签取首命中**(优先序):精确行先于形状行([[ref]] 的结论,这里是结构性的而不是靠行序),
|
|
27
|
+
* 形状行按声明序;没有任何行给标签 ⇒ `"other"`。
|
|
28
|
+
* · **门取并集**(宁紧):一条 url 只要**有一行**声明了某性质,它就有该性质 —— 这正是旧谓词那几个
|
|
29
|
+
* `||` 的逐字同义,也是「前缀行比标签行宽」这件事的正解(`/v1/devices/` 下将来长出的任何写动词
|
|
30
|
+
* 天然在改写门内,不必等谁想起来补一行标签)。
|
|
31
|
+
*
|
|
32
|
+
* 新增一条路由 = 新建 `routes/x.ts` + 本表加一行(+ `test/route-order-freeze.test.ts` 的冻结表加一行,
|
|
33
|
+
* 那是 position 的外部对拍源)。`position` 与匹配式都是必填 —— 忘了就是**编译红**,不是静默 404。
|
|
34
|
+
*
|
|
35
|
+
* 🔴 **旧禁令已解除**:标签表此前必须「写字面量不引常量」、注释里不许出现某两个字符 —— 那是两道
|
|
36
|
+
* 扫源码文本的门反向塑形源码的产物(它们的捕获正则抓不到常量、非贪婪捕获会被那对字符提前截断)。
|
|
37
|
+
* 两道门都改成读本表之后,这条禁令没有了对象,随它的 11 处行注一并删;要引常量就引(`routes/*.ts`
|
|
38
|
+
* 的 `*_PATH` 常量本来就是那些路径的单一属主)。
|
|
39
|
+
*
|
|
40
|
+
* 🔴 本文件是**叶模块**:只 import `routes/*.ts` 的 handler 与几只单源正则、以及类型。组合根与流水线
|
|
41
|
+
* (`server.ts` / `dispatch.ts`)一律反过来 import 它,值边单向,`test/module-cycle-gate.test.ts` 看守。
|
|
42
|
+
*/
|
|
43
|
+
import type { FlatServiceDeps } from "./server.js";
|
|
44
|
+
import type { RouteHandler } from "./route-ctx.js";
|
|
45
|
+
/** 一只域 handler 相对**全局服务凭据门**的位置。门前 = 未鉴权可达(每一只都要单独论证),门后 = 先过凭据。 */
|
|
46
|
+
export type RoutePosition = "pre-credential" | "post-credential";
|
|
47
|
+
export interface RouteRow {
|
|
48
|
+
/** 域入口(`routes/*.ts` 的 `handleX`)。签名一致性是编译期钉:入口漂了形 = 编译红,不是运行时静默 404。 */
|
|
49
|
+
readonly handler: RouteHandler;
|
|
50
|
+
/** 必填 —— 新增路由必须**显式**决定它在凭据门的哪一侧。 */
|
|
51
|
+
readonly position: RoutePosition;
|
|
52
|
+
/** 域名(kebab;= `routes/` 下的模块名)。评审把本表当「域全集」读时它是那份清单的名字列,
|
|
53
|
+
* `test/route-shape-roster.test.ts` 层E 的能力位词干也取自这里 —— 域的身份是声明出来的,
|
|
54
|
+
* 不是从函数名反推的。函数真名与它的一致性由 `route-order-freeze` 自检格钉住。 */
|
|
55
|
+
readonly label: string;
|
|
56
|
+
/** **挂载条件**(只有真有条件的行才写):缺席 = 恒挂载。域头的合取式就是挂载条件 —— 阀门没开 ⇒
|
|
57
|
+
* 请求落到分派器尾的全局 404(**诚实缺席,不是 501**;判据全文在各域模块头注)。 */
|
|
58
|
+
readonly enabled?: (deps: FlatServiceDeps) => boolean;
|
|
59
|
+
}
|
|
60
|
+
export declare const ROUTES: readonly RouteRow[];
|
|
61
|
+
/** 两段(`dispatch.ts` 的分派循环各跑一段)。段内序 = 本表行序;
|
|
62
|
+
* 「门前行不许出现在门后行之后」由 `test/route-order-freeze.test.ts` 钉住。 */
|
|
63
|
+
export declare const PRE_CREDENTIAL_ROUTES: readonly RouteRow[];
|
|
64
|
+
export declare const POST_CREDENTIAL_ROUTES: readonly RouteRow[];
|
|
65
|
+
/** 改写门是**方法感知**的(它的撤销动词是 DELETE)。闭集 —— 加第五个动词是编译红。 */
|
|
66
|
+
export type RouteMethod = "GET" | "POST" | "PUT" | "DELETE";
|
|
67
|
+
interface RouteDeclFacts {
|
|
68
|
+
/** 「这条 url **烧模型**」—— drain / model-roster-pending / 无 service-token 三道 503 的共同判别。
|
|
69
|
+
* 没有这一列 = 不烧模型(零默认值:要它为真必须显式写出来,漏写的方向是**少收一笔账单**而不是
|
|
70
|
+
* 少一道门 —— 反了才是灾难,所以三道门读的是 true 这一侧)。 */
|
|
71
|
+
readonly billable?: true;
|
|
72
|
+
/** 「本条 url 在**没有任何 service credential** 的部署形下,这几个方法必须 fail-closed」。
|
|
73
|
+
* 判据(两个合取项)= 「授权的唯一输入是 principal 头」∧「持久改写,或爆炸半径跨租户的治理读」;
|
|
74
|
+
* 逐口论证在各 `routes/*.ts` 的头注里,本表只记结论。 */
|
|
75
|
+
readonly credentialGated?: readonly RouteMethod[];
|
|
76
|
+
/** 「这条 url **是**计费提交面,但它到底提不提交由**请求体里的方法**决定」—— 单 URL 多方法的
|
|
77
|
+
* JSON-RPC 端点。两道**可用性** 503(drain / roster-pending)按 url 一刀切会把同端点上的纯读一起
|
|
78
|
+
* 关掉,所以分派器对本行**跳过**那两道,改由域模块在写分支里施加同样的两道(文案逐字同源)。
|
|
79
|
+
* 🔴 只豁免那两道,**不豁免安全轴**:`billable` 本身仍为 true,无 service token 那道 fail-closed
|
|
80
|
+
* 503 照旧罩着(它判的是「这台机能不能收写」,与方法无关,且必须在解析请求体之前)。 */
|
|
81
|
+
readonly methodDispatched?: true;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* 一行的匹配式三选一(闭集;`path` 行的标签**就是** path 自身,所以它没有 label 列 —— 少一处手抄)。
|
|
85
|
+
* `prefix` 与 `pattern` 行的 label 可缺席:那是**纯门行**(比标签行宽,只供门的并集判据),
|
|
86
|
+
* 缺席 ⇒ 本行不铸任何标签。
|
|
87
|
+
*/
|
|
88
|
+
export type RouteDecl = (RouteDeclFacts & {
|
|
89
|
+
readonly path: string;
|
|
90
|
+
}) | (RouteDeclFacts & {
|
|
91
|
+
readonly prefix: string;
|
|
92
|
+
readonly label?: string;
|
|
93
|
+
}) | (RouteDeclFacts & {
|
|
94
|
+
readonly pattern: RegExp;
|
|
95
|
+
readonly label?: string;
|
|
96
|
+
});
|
|
97
|
+
/** 🔴 由 `test/route-shape-roster.test.ts` 棘轮看守:门机器枚举 `src/http/**` 的全部路由模式并断言每条
|
|
98
|
+
* 都映射到非 "other"——新路由不补本表该门当场红(census 抓获本表曾漂掉 56 条模式:session-sync/workspace/
|
|
99
|
+
* workflows/subagents/attachments/images/leader 等整族全折 "other",metrics 不可分桶)。 */
|
|
100
|
+
export declare const ROUTE_DECLARATIONS: readonly RouteDecl[];
|
|
101
|
+
/** Stable, low-cardinality route label for metrics/logs (ids collapsed to `:id`). */
|
|
102
|
+
export declare function routeLabel(_method: string, url: string): string;
|
|
103
|
+
/** POST endpoints that trigger BILLABLE work — the fail-closed auth guard must cover ALL of them. */
|
|
104
|
+
export declare function isBillableSubmitPath(url: string): boolean;
|
|
105
|
+
/** [ref]([ref] 件5)—— **改写门**:不烧模型、但在没有任何 service credential 的部署形下必须
|
|
106
|
+
* 与 billable / bake 两族一样 fail-closed 的写门。与 `isBillableSubmitPath` **刻意分开**:这几扇门
|
|
107
|
+
* `billable=false`(零模型工作),塞进那张名单会让它们连带吃 drain 与 roster-pending 两道 503 ——
|
|
108
|
+
* 而收编与规则读写在排空期/roster 未落时做完全无害。 */
|
|
109
|
+
export declare function isCredentialGatedRewrite(method: string, url: string): boolean;
|
|
110
|
+
/** 见 `RouteDeclFacts.methodDispatched` 的头注(单 URL 多方法端点)。 */
|
|
111
|
+
export declare function isMethodDispatchedSubmitPath(url: string): boolean;
|
|
112
|
+
export {};
|
|
113
|
+
//# sourceMappingURL=route-table.d.ts.map
|