@sema-agent/server 7.79.2 → 7.80.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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.js +28 -8
- package/dist/http/route-ctx.d.ts +101 -4
- package/dist/http/route-ctx.js +4 -0
- package/dist/http/route-table.d.ts +71 -43
- package/dist/http/route-table.js +111 -187
- package/dist/http/routes/a2a-serve.d.ts +18 -3
- package/dist/http/routes/a2a-serve.js +25 -23
- package/dist/http/routes/admin-config-refresh.d.ts +9 -2
- package/dist/http/routes/admin-config-refresh.js +32 -31
- package/dist/http/routes/admin-drain.d.ts +9 -2
- package/dist/http/routes/admin-drain.js +32 -31
- package/dist/http/routes/admin-memory-optout.d.ts +28 -2
- package/dist/http/routes/admin-memory-optout.js +26 -39
- package/dist/http/routes/adoption.d.ts +15 -2
- package/dist/http/routes/adoption.js +52 -52
- package/dist/http/routes/agents-roster.d.ts +9 -2
- package/dist/http/routes/agents-roster.js +82 -80
- package/dist/http/routes/approvals-assistant.d.ts +58 -5
- package/dist/http/routes/approvals-assistant.js +37 -38
- package/dist/http/routes/attachments.d.ts +22 -2
- package/dist/http/routes/attachments.js +81 -72
- package/dist/http/routes/capabilities.d.ts +21 -2
- package/dist/http/routes/capabilities.js +174 -170
- package/dist/http/routes/config-catalog.d.ts +9 -2
- package/dist/http/routes/config-catalog.js +28 -31
- package/dist/http/routes/devices.d.ts +24 -2
- package/dist/http/routes/devices.js +19 -21
- package/dist/http/routes/diagnostics.d.ts +9 -2
- package/dist/http/routes/diagnostics.js +41 -43
- package/dist/http/routes/fleet.d.ts +11 -2
- package/dist/http/routes/fleet.js +23 -22
- package/dist/http/routes/images.d.ts +63 -9
- package/dist/http/routes/images.js +53 -46
- package/dist/http/routes/leader.d.ts +20 -2
- package/dist/http/routes/leader.js +43 -40
- package/dist/http/routes/memory-bundle.d.ts +15 -2
- package/dist/http/routes/memory-bundle.js +38 -38
- package/dist/http/routes/memory-compliance.d.ts +16 -4
- package/dist/http/routes/memory-compliance.js +44 -45
- package/dist/http/routes/memory-consolidation.d.ts +14 -2
- package/dist/http/routes/memory-consolidation.js +66 -66
- package/dist/http/routes/memory-origin.d.ts +23 -4
- package/dist/http/routes/memory-origin.js +65 -65
- package/dist/http/routes/memory-policy.d.ts +21 -2
- package/dist/http/routes/memory-policy.js +119 -115
- package/dist/http/routes/notify-wake.d.ts +21 -11
- package/dist/http/routes/notify-wake.js +118 -116
- package/dist/http/routes/observability.d.ts +16 -2
- package/dist/http/routes/observability.js +54 -51
- package/dist/http/routes/retention-ops.d.ts +19 -2
- package/dist/http/routes/retention-ops.js +20 -22
- package/dist/http/routes/rules.d.ts +36 -2
- package/dist/http/routes/rules.js +22 -24
- package/dist/http/routes/run-memory-capture.d.ts +10 -3
- package/dist/http/routes/run-memory-capture.js +84 -84
- package/dist/http/routes/runs.d.ts +102 -22
- package/dist/http/routes/runs.js +71 -88
- package/dist/http/routes/session-sync.d.ts +41 -2
- package/dist/http/routes/session-sync.js +25 -23
- package/dist/http/routes/sessions-list.d.ts +16 -2
- package/dist/http/routes/sessions-list.js +78 -75
- package/dist/http/routes/sessions.d.ts +77 -2
- package/dist/http/routes/sessions.js +50 -47
- package/dist/http/routes/shared-memory.d.ts +19 -2
- package/dist/http/routes/shared-memory.js +65 -63
- package/dist/http/routes/side-query.d.ts +11 -2
- package/dist/http/routes/side-query.js +81 -79
- package/dist/http/routes/tasks.d.ts +17 -2
- package/dist/http/routes/tasks.js +18 -11
- package/dist/http/routes/trace-usage.d.ts +40 -2
- package/dist/http/routes/trace-usage.js +46 -35
- package/dist/http/routes/workflows.d.ts +35 -3
- package/dist/http/routes/workflows.js +29 -29
- 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 +7 -6
- package/dist/trace/redact.js +419 -229
- package/package.json +1 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { sendJson, sendError, httpErrorCode } from "../send.js";
|
|
3
3
|
import { gatedPrincipal, explicitOperatorOk } from "../principal-gate.js";
|
|
4
|
+
import { assertNever } from "../route-ctx.js";
|
|
4
5
|
import { createLogger } from "../../observability/logger.js";
|
|
5
6
|
import { RULE_IMPORT_RETRY_AFTER_SEC, MAX_RULE_SCOPE_CHARS, parseRuleScope, serializeRuleScope } from "../../rules-consent.js";
|
|
6
7
|
import { CONTROL_AND_BIDI_CHARS } from "../../text-bidi.js";
|
|
@@ -82,24 +83,9 @@ function decodeRulesCursor(raw) {
|
|
|
82
83
|
}
|
|
83
84
|
}
|
|
84
85
|
const rowKey = (r) => `${r.scope}\u0000${r.rule}\u0000${r.behavior}`;
|
|
85
|
-
export async function handleRules(req, res,
|
|
86
|
-
const miss = { fell: false };
|
|
87
|
-
await handleRulesBody(req, res, url, ctx, miss);
|
|
88
|
-
return !miss.fell;
|
|
89
|
-
}
|
|
90
|
-
async function handleRulesBody(req, res, url, ctx, miss) {
|
|
86
|
+
export async function handleRules(req, res, match, ctx) {
|
|
91
87
|
const { deps } = ctx;
|
|
92
88
|
const { readJson, rateLimited } = ctx.helpers;
|
|
93
|
-
const isPrepare = req.method === "POST" && url === RULES_CC_IMPORT_PREPARE_PATH;
|
|
94
|
-
const isRedeem = req.method === "POST" && url === RULES_CC_IMPORT_REDEEM_PATH;
|
|
95
|
-
const isLocalPrepare = req.method === "POST" && url === RULES_LOCAL_IMPORT_PREPARE_PATH;
|
|
96
|
-
const isLocalRedeem = req.method === "POST" && url === RULES_LOCAL_IMPORT_REDEEM_PATH;
|
|
97
|
-
const isList = req.method === "GET" && url === RULES_PATH;
|
|
98
|
-
const isRevoke = req.method === "DELETE" && url === RULES_PATH;
|
|
99
|
-
if (!isPrepare && !isRedeem && !isList && !isRevoke && !isLocalPrepare && !isLocalRedeem) {
|
|
100
|
-
miss.fell = true;
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
89
|
if (rateLimited(req, res))
|
|
104
90
|
return;
|
|
105
91
|
const principal = gatedPrincipal(req, deps.config);
|
|
@@ -112,8 +98,8 @@ async function handleRulesBody(req, res, url, ctx, miss) {
|
|
|
112
98
|
sendError(res, 501, "capability.rule_store_required", "this deployment has no permission-rule store wired");
|
|
113
99
|
return;
|
|
114
100
|
}
|
|
115
|
-
if (
|
|
116
|
-
await handleRuleList(
|
|
101
|
+
if (match.decl.id === "rules-list") {
|
|
102
|
+
await handleRuleList(res, match.search, principal, lane, deps.config.operatorPrincipals);
|
|
117
103
|
return;
|
|
118
104
|
}
|
|
119
105
|
let rawBody;
|
|
@@ -128,11 +114,11 @@ async function handleRulesBody(req, res, url, ctx, miss) {
|
|
|
128
114
|
sendError(res, 400, "request.body_shape", "body must be valid JSON");
|
|
129
115
|
return;
|
|
130
116
|
}
|
|
131
|
-
if (
|
|
117
|
+
if (match.decl.id === "rules-revoke") {
|
|
132
118
|
await handleRuleRevoke(res, rawBody, principal, lane, deps.config.operatorPrincipals);
|
|
133
119
|
return;
|
|
134
120
|
}
|
|
135
|
-
if (
|
|
121
|
+
if (match.decl.id === "rules-local-import-prepare") {
|
|
136
122
|
const parsed = LocalImportPrepareBodySchema.safeParse(rawBody);
|
|
137
123
|
if (!parsed.success) {
|
|
138
124
|
sendError(res, 400, "request.body_shape", "body must be {rows:[{behavior,rule,scope,tool,match,command,adds}]}");
|
|
@@ -147,7 +133,7 @@ async function handleRulesBody(req, res, url, ctx, miss) {
|
|
|
147
133
|
sendJson(res, 200, { preview: prepared.preview, ...(prepared.ticket !== undefined ? { ticket: prepared.ticket, expiresAtMs: prepared.expiresAtMs } : {}) });
|
|
148
134
|
return;
|
|
149
135
|
}
|
|
150
|
-
if (
|
|
136
|
+
if (match.decl.id === "rules-local-import-redeem") {
|
|
151
137
|
const parsed = LocalImportRedeemBodySchema.safeParse(rawBody);
|
|
152
138
|
if (!parsed.success) {
|
|
153
139
|
sendError(res, 400, "request.body_shape", "body must be {ticket}");
|
|
@@ -172,7 +158,7 @@ async function handleRulesBody(req, res, url, ctx, miss) {
|
|
|
172
158
|
sendError(res, 404, "not_found.rule_ticket", "no such import ticket");
|
|
173
159
|
return;
|
|
174
160
|
}
|
|
175
|
-
if (
|
|
161
|
+
if (match.decl.id === "rules-cc-import-prepare") {
|
|
176
162
|
const parsed = CcImportPrepareBodySchema.safeParse(rawBody);
|
|
177
163
|
if (!parsed.success) {
|
|
178
164
|
sendError(res, 400, "request.body_shape", "body must be {layers:[{layer,path,root,content}]}");
|
|
@@ -186,6 +172,8 @@ async function handleRulesBody(req, res, url, ctx, miss) {
|
|
|
186
172
|
sendJson(res, 200, { preview: prepared.preview, ...(prepared.ticket !== undefined ? { ticket: prepared.ticket, expiresAtMs: prepared.expiresAtMs } : {}) });
|
|
187
173
|
return;
|
|
188
174
|
}
|
|
175
|
+
if (match.decl.id !== "rules-cc-import-redeem")
|
|
176
|
+
return assertNever(match.decl.id);
|
|
189
177
|
const parsed = CcImportRedeemBodySchema.safeParse(rawBody);
|
|
190
178
|
if (!parsed.success) {
|
|
191
179
|
sendError(res, 400, "request.body_shape", "body must be {ticket}");
|
|
@@ -216,8 +204,8 @@ function resolveTargetPrincipal(requested, caller, operatorPrincipals) {
|
|
|
216
204
|
return { ok: false };
|
|
217
205
|
return { ok: true, principal: requested };
|
|
218
206
|
}
|
|
219
|
-
async function handleRuleList(
|
|
220
|
-
const q = new
|
|
207
|
+
async function handleRuleList(res, search, caller, lane, operatorPrincipals) {
|
|
208
|
+
const q = new URLSearchParams(search);
|
|
221
209
|
const target = resolveTargetPrincipal(q.get("principal") ?? undefined, caller, operatorPrincipals);
|
|
222
210
|
if (!target.ok) {
|
|
223
211
|
sendError(res, 403, "auth.operator_only", "reading another principal's rules is an operator-only action");
|
|
@@ -286,4 +274,14 @@ async function handleRuleRevoke(res, rawBody, caller, lane, operatorPrincipals)
|
|
|
286
274
|
return;
|
|
287
275
|
}
|
|
288
276
|
}
|
|
277
|
+
export const RULES_ROUTES = [
|
|
278
|
+
{ id: "rules-cc-import-prepare", path: RULES_CC_IMPORT_PREPARE_PATH, methods: ["POST"] },
|
|
279
|
+
{ id: "rules-cc-import-redeem", path: RULES_CC_IMPORT_REDEEM_PATH, methods: ["POST"] },
|
|
280
|
+
{ id: "rules-local-import-prepare", path: RULES_LOCAL_IMPORT_PREPARE_PATH, methods: ["POST"] },
|
|
281
|
+
{ id: "rules-local-import-redeem", path: RULES_LOCAL_IMPORT_REDEEM_PATH, methods: ["POST"] },
|
|
282
|
+
{ id: "rules-list", path: RULES_PATH, methods: ["GET"] },
|
|
283
|
+
{ id: "rules-revoke", path: RULES_PATH, credentialGated: ["DELETE"], methods: ["DELETE"] },
|
|
284
|
+
{ prefix: "/v1/rules/cc-import/", credentialGated: ["POST"] },
|
|
285
|
+
{ prefix: "/v1/rules/local-import/", credentialGated: ["POST"] },
|
|
286
|
+
];
|
|
289
287
|
//# sourceMappingURL=rules.js.map
|
|
@@ -28,7 +28,14 @@
|
|
|
28
28
|
* `sessionBackgroundable` 同谓词):老 worker 键缺席 ⇒ 壳不渲入口(假 affordance 纪律)。
|
|
29
29
|
*/
|
|
30
30
|
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
31
|
-
import { type RouteCtx } from "../route-ctx.js";
|
|
32
|
-
export declare
|
|
33
|
-
export declare
|
|
31
|
+
import { type RouteCtx, type RouteMatch, type RouteIdsOf } from "../route-ctx.js";
|
|
32
|
+
export declare function handleRunMemoryCapture(req: IncomingMessage, res: ServerResponse, match: RouteMatch<RunMemoryCaptureRouteId>, ctx: RouteCtx): Promise<void>;
|
|
33
|
+
export declare const RUN_MEMORY_CAPTURE_ROUTES: readonly [{
|
|
34
|
+
readonly id: "run-memory-capture-optout";
|
|
35
|
+
readonly pattern: RegExp;
|
|
36
|
+
readonly label: "/v1/runs/:id/memory/capture-optout";
|
|
37
|
+
readonly methods: readonly ["POST"];
|
|
38
|
+
}];
|
|
39
|
+
/** 本域可分派行的 `id` 闭集 —— handler 的 `switch` 按它判穷尽(漏一口 = 编译红)。 */
|
|
40
|
+
export type RunMemoryCaptureRouteId = RouteIdsOf<typeof RUN_MEMORY_CAPTURE_ROUTES>;
|
|
34
41
|
//# sourceMappingURL=run-memory-capture.d.ts.map
|
|
@@ -3,95 +3,95 @@ import { isParkedRunStatus, isTerminalRunStatus } from "../../plugins/store-cont
|
|
|
3
3
|
import { sendJson, sendError } from "../send.js";
|
|
4
4
|
import { gatedPrincipal, sendPrincipalRefusal } from "../principal-gate.js";
|
|
5
5
|
import { RUN_NOT_FOUND_MESSAGE, runNotFoundMessage } from "../route-ctx.js";
|
|
6
|
-
|
|
6
|
+
import { assertNever } from "../route-ctx.js";
|
|
7
7
|
const BodySchema = z.object({ reason: z.string().min(1).max(500).optional() }).strict();
|
|
8
|
-
export async function handleRunMemoryCapture(req, res,
|
|
9
|
-
const miss = { fell: false };
|
|
10
|
-
await handleBody(req, res, url, ctx, miss);
|
|
11
|
-
return !miss.fell;
|
|
12
|
-
}
|
|
13
|
-
async function handleBody(req, res, url, ctx, miss) {
|
|
8
|
+
export async function handleRunMemoryCapture(req, res, match, ctx) {
|
|
14
9
|
const { deps } = ctx;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
try {
|
|
49
|
-
const { outcome } = await live.optOutMemoryCapture(parsed.data.reason !== undefined ? { reason: parsed.data.reason } : {});
|
|
50
|
-
sendJson(res, 200, { taskId, sessionId: run.sessionId, outcome });
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
catch (e) {
|
|
54
|
-
const code = e.code;
|
|
55
|
-
const msg = e instanceof Error ? e.message : String(e);
|
|
56
|
-
switch (code) {
|
|
57
|
-
case "memory.capture_optout_denied":
|
|
58
|
-
sendError(res, 403, "memory.capture_optout_denied", msg);
|
|
59
|
-
return;
|
|
60
|
-
case "memory.capture_optout_unpersisted":
|
|
61
|
-
sendError(res, 503, "memory.capture_optout_unpersisted", msg);
|
|
62
|
-
return;
|
|
63
|
-
case "memory.capture_optout_unavailable":
|
|
64
|
-
sendError(res, 409, "memory.capture_optout_unavailable", msg);
|
|
65
|
-
return;
|
|
66
|
-
case "memory.capture_optout_sweep_failed":
|
|
67
|
-
sendError(res, 409, "memory.capture_optout_sweep_failed", msg);
|
|
68
|
-
return;
|
|
69
|
-
case "config.memory_capture_unsupported":
|
|
70
|
-
sendError(res, 409, "config.memory_capture_unsupported", msg);
|
|
71
|
-
return;
|
|
72
|
-
case "steering.invalid_content":
|
|
73
|
-
sendError(res, 422, "steering.invalid_content", msg);
|
|
74
|
-
return;
|
|
75
|
-
case "steering.not_running":
|
|
76
|
-
sendError(res, 409, "steering.not_running", "run just finished — the memory-capture opt-out verb needs a live run; declare it on the next submit instead (memoryCapture: 'off')");
|
|
10
|
+
switch (match.decl.id) {
|
|
11
|
+
case "run-memory-capture-optout": {
|
|
12
|
+
if (ctx.helpers.rateLimited(req, res))
|
|
13
|
+
return;
|
|
14
|
+
if (!deps.runStore) {
|
|
15
|
+
sendError(res, 501, "capability.run_store_required", "async runs require a durable run store (DB_BACKEND=mysql|pg|local)");
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const principal = gatedPrincipal(req, deps.config);
|
|
19
|
+
if (deps.config.requirePrincipal && principal === undefined) {
|
|
20
|
+
sendPrincipalRefusal(res, req, deps.config);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const taskId = match.params.taskId;
|
|
24
|
+
const parsed = BodySchema.safeParse((await ctx.helpers.readJson(req)) ?? {});
|
|
25
|
+
if (!parsed.success) {
|
|
26
|
+
sendError(res, 400, "request.body_shape", "body must be {} or { reason: string (non-empty, at most 500 chars) } — the session memory-capture opt-out verb takes no other keys");
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const run = await deps.runStore.getRun(taskId);
|
|
30
|
+
if (!run) {
|
|
31
|
+
sendError(res, 404, "not_found.run", runNotFoundMessage(taskId));
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (run.owner !== null && run.owner !== principal) {
|
|
35
|
+
sendError(res, 404, "not_found.run", RUN_NOT_FOUND_MESSAGE);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const live = ctx.registry.steerableRuns.get(taskId);
|
|
39
|
+
if (live) {
|
|
40
|
+
try {
|
|
41
|
+
const { outcome } = await live.optOutMemoryCapture(parsed.data.reason !== undefined ? { reason: parsed.data.reason } : {});
|
|
42
|
+
sendJson(res, 200, { taskId, sessionId: run.sessionId, outcome });
|
|
77
43
|
return;
|
|
78
|
-
|
|
44
|
+
}
|
|
45
|
+
catch (e) {
|
|
46
|
+
const code = e.code;
|
|
47
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
48
|
+
switch (code) {
|
|
49
|
+
case "memory.capture_optout_denied":
|
|
50
|
+
sendError(res, 403, "memory.capture_optout_denied", msg);
|
|
51
|
+
return;
|
|
52
|
+
case "memory.capture_optout_unpersisted":
|
|
53
|
+
sendError(res, 503, "memory.capture_optout_unpersisted", msg);
|
|
54
|
+
return;
|
|
55
|
+
case "memory.capture_optout_unavailable":
|
|
56
|
+
sendError(res, 409, "memory.capture_optout_unavailable", msg);
|
|
57
|
+
return;
|
|
58
|
+
case "memory.capture_optout_sweep_failed":
|
|
59
|
+
sendError(res, 409, "memory.capture_optout_sweep_failed", msg);
|
|
60
|
+
return;
|
|
61
|
+
case "config.memory_capture_unsupported":
|
|
62
|
+
sendError(res, 409, "config.memory_capture_unsupported", msg);
|
|
63
|
+
return;
|
|
64
|
+
case "steering.invalid_content":
|
|
65
|
+
sendError(res, 422, "steering.invalid_content", msg);
|
|
66
|
+
return;
|
|
67
|
+
case "steering.not_running":
|
|
68
|
+
sendError(res, 409, "steering.not_running", "run just finished — the memory-capture opt-out verb needs a live run; declare it on the next submit instead (memoryCapture: 'off')");
|
|
69
|
+
return;
|
|
70
|
+
default: throw e;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (isParkedRunStatus(run.status)) {
|
|
75
|
+
sendError(res, 409, "steering.not_running", "run is parked on a pending decision — the memory-capture opt-out verb needs a live turn, and a resumed continuation rebuilds its spec from the persisted body (it cannot take a new declaration); the opt-out becomes effective on this session's next NEW submit (POST /v1/tasks with this sessionId and memoryCapture: 'off') — content captured until then stays captured");
|
|
76
|
+
return;
|
|
79
77
|
}
|
|
78
|
+
if (isTerminalRunStatus(run.status)) {
|
|
79
|
+
sendError(res, 409, "steering.not_running", "run already ended — the memory-capture opt-out verb needs a live run; submit the next turn of this session with memoryCapture: 'off' (the declaration writes the same one-way session record)");
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const provenElsewhere = typeof run.instanceId === "string" && run.instanceId.length > 0 && deps.instanceId !== undefined && run.instanceId !== deps.instanceId;
|
|
83
|
+
if (provenElsewhere) {
|
|
84
|
+
sendError(res, 409, "steering.not_running", "run is live on another replica — the memory-capture opt-out verb must reach the replica holding the stream; resend it there, or declare memoryCapture: 'off' on the next submit");
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
sendError(res, 409, "steering.not_running", "no live steerable face for this run on this replica — verify/cascade execution lanes expose none; declare memoryCapture: 'off' on the next submit of this session instead");
|
|
88
|
+
return;
|
|
80
89
|
}
|
|
90
|
+
default:
|
|
91
|
+
return assertNever(match.decl.id);
|
|
81
92
|
}
|
|
82
|
-
if (isParkedRunStatus(run.status)) {
|
|
83
|
-
sendError(res, 409, "steering.not_running", "run is parked on a pending decision — the memory-capture opt-out verb needs a live turn, and a resumed continuation rebuilds its spec from the persisted body (it cannot take a new declaration); the opt-out becomes effective on this session's next NEW submit (POST /v1/tasks with this sessionId and memoryCapture: 'off') — content captured until then stays captured");
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
if (isTerminalRunStatus(run.status)) {
|
|
87
|
-
sendError(res, 409, "steering.not_running", "run already ended — the memory-capture opt-out verb needs a live run; submit the next turn of this session with memoryCapture: 'off' (the declaration writes the same one-way session record)");
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
const provenElsewhere = typeof run.instanceId === "string" && run.instanceId.length > 0 && deps.instanceId !== undefined && run.instanceId !== deps.instanceId;
|
|
91
|
-
if (provenElsewhere) {
|
|
92
|
-
sendError(res, 409, "steering.not_running", "run is live on another replica — the memory-capture opt-out verb must reach the replica holding the stream; resend it there, or declare memoryCapture: 'off' on the next submit");
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
sendError(res, 409, "steering.not_running", "no live steerable face for this run on this replica — verify/cascade execution lanes expose none; declare memoryCapture: 'off' on the next submit of this session instead");
|
|
96
93
|
}
|
|
94
|
+
export const RUN_MEMORY_CAPTURE_ROUTES = [
|
|
95
|
+
{ id: "run-memory-capture-optout", pattern: /^\/v1\/runs\/(?<taskId>[^/]+)\/memory\/capture-optout$/, label: "/v1/runs/:id/memory/capture-optout", methods: ["POST"] },
|
|
96
|
+
];
|
|
97
97
|
//# sourceMappingURL=run-memory-capture.js.map
|
|
@@ -1,33 +1,17 @@
|
|
|
1
1
|
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
2
2
|
import { ActorAssertionWire } from "@sema-agent/settings-schema";
|
|
3
|
-
import type { RouteCtx, PreparedTaskSubmission } from "../route-ctx.js";
|
|
4
|
-
export declare const RUN_ID_RE: RegExp;
|
|
5
|
-
export declare const RUN_CANCEL_RE: RegExp;
|
|
6
|
-
export declare const RUN_STEER_RE: RegExp;
|
|
7
|
-
export declare const RUN_DETACH_RE: RegExp;
|
|
8
|
-
export declare const RUN_COMPACT_RE: RegExp;
|
|
9
|
-
export declare const RUN_INTERRUPT_RE: RegExp;
|
|
10
|
-
/** PAIR-REVIEW F-10:runs 面 404 文案统一富形——a\* 形 id(background-agent registry 句柄,`a`+hex 短形)
|
|
11
|
-
* 是「结构性不在 run 店」的常客([ref]⑤ 记档裁量:不改路由,只给引导)。识别句法形即补引导;
|
|
12
|
-
* 非 a\* 形保通用富文案(cancel 腿 [ref]① 同款)。 */
|
|
13
|
-
export declare const ELICIT_RESPOND_RE: RegExp;
|
|
14
|
-
export declare const QUESTION_RESPOND_RE: RegExp;
|
|
15
|
-
export declare const TOOL_APPROVAL_RESPOND_RE: RegExp;
|
|
16
|
-
export declare const TASK_ASK_DECISION_RE: RegExp;
|
|
3
|
+
import type { RouteCtx, PreparedTaskSubmission, RouteMatch, RouteIdsOf } from "../route-ctx.js";
|
|
17
4
|
/** 行上的 `decision_actor`(裸 JSON)投成回显形;形不认 ⇒ undefined(调用点省略该键,不 500)。
|
|
18
5
|
* 导出仅为契约门(`test/ask-decision-actor-contract.test.ts` 钉「键集同源包版 + 严格度刻意宽读」两条)
|
|
19
6
|
* —— 导出的是**行为**而不是 schema 对象:schema 的推断类型会牵出 registry-core 内嵌的 zod 路径
|
|
20
7
|
* (TS2742,不可移植),而这道门要钉的本来就是行为。非 wire 面。 */
|
|
21
8
|
export declare function projectDecisionActor(raw: unknown): ActorAssertionWire | undefined;
|
|
22
|
-
export declare const RUN_SUBAGENT_STEER_RE: RegExp;
|
|
23
|
-
export declare const RUN_SUBAGENT_RESUME_RE: RegExp;
|
|
24
|
-
export declare const RUN_SUBAGENT_OUTPUT_RE: RegExp;
|
|
25
|
-
export declare const RUN_SUBAGENT_STREAM_RE: RegExp;
|
|
26
|
-
export declare const RUN_TASK_OUTPUT_RE: RegExp;
|
|
27
|
-
export declare const RUN_TASK_STOP_RE: RegExp;
|
|
28
|
-
export declare function handleRuns(req: IncomingMessage, res: ServerResponse, url: string, ctx: RouteCtx): Promise<boolean>;
|
|
29
9
|
/** 子代理 / 任务句柄 / HITL 应答段——`handle()` 里它在 SVC-5 workflow steer **之后**,故是独立的域入口。 */
|
|
30
|
-
|
|
10
|
+
/** 路由体 = 从 `server.ts` 的 `handle()` 里**整段剪切**过来的原文(唯一改动:统一去缩进两格)。裸 `return;`
|
|
11
|
+
* = 「本域已应答」;走到函数尾才是「没匹配上」。跨域的东西一律在首行解构出来。 */
|
|
12
|
+
export declare function handleRuns(req: IncomingMessage, res: ServerResponse, match: RouteMatch<RunsRouteId>, ctx: RouteCtx): Promise<void>;
|
|
13
|
+
/** 同上纪律(子代理 / 任务句柄 / HITL 应答段)。 */
|
|
14
|
+
export declare function handleRunVerbs(req: IncomingMessage, res: ServerResponse, match: RouteMatch<RunVerbsRouteId>, ctx: RouteCtx): Promise<void>;
|
|
31
15
|
/**
|
|
32
16
|
* DESIGN-269 车2 件2 —— `POST /v1/runs` 的**建行 + 驱动**段,从路由体里原样搬出来的具名腿。
|
|
33
17
|
*
|
|
@@ -54,4 +38,100 @@ idemKey: string | undefined): Promise<{
|
|
|
54
38
|
status: number;
|
|
55
39
|
body: unknown;
|
|
56
40
|
} | null>;
|
|
41
|
+
export declare const RUNS_ROUTES: readonly [{
|
|
42
|
+
readonly id: "runs-submit";
|
|
43
|
+
readonly path: "/v1/runs";
|
|
44
|
+
readonly billable: true;
|
|
45
|
+
readonly methods: readonly ["POST"];
|
|
46
|
+
}, {
|
|
47
|
+
readonly id: "run-steer";
|
|
48
|
+
readonly pattern: RegExp;
|
|
49
|
+
readonly label: "/v1/runs/:id/steer";
|
|
50
|
+
readonly methods: readonly ["POST"];
|
|
51
|
+
}, {
|
|
52
|
+
readonly id: "run-interrupt";
|
|
53
|
+
readonly pattern: RegExp;
|
|
54
|
+
readonly label: "/v1/runs/:id/interrupt";
|
|
55
|
+
readonly methods: readonly ["POST"];
|
|
56
|
+
}, {
|
|
57
|
+
readonly id: "run-detach";
|
|
58
|
+
readonly pattern: RegExp;
|
|
59
|
+
readonly label: "/v1/runs/:id/detach";
|
|
60
|
+
readonly methods: readonly ["POST"];
|
|
61
|
+
}, {
|
|
62
|
+
readonly id: "run-cancel";
|
|
63
|
+
readonly pattern: RegExp;
|
|
64
|
+
readonly label: "/v1/runs/:id/cancel";
|
|
65
|
+
readonly methods: readonly ["POST"];
|
|
66
|
+
}, {
|
|
67
|
+
readonly id: "run-compact";
|
|
68
|
+
readonly pattern: RegExp;
|
|
69
|
+
readonly label: "/v1/runs/:id/compact";
|
|
70
|
+
readonly methods: readonly ["POST"];
|
|
71
|
+
}, {
|
|
72
|
+
readonly id: "run-events";
|
|
73
|
+
readonly pattern: RegExp;
|
|
74
|
+
readonly label: "/v1/runs/:id/events";
|
|
75
|
+
readonly methods: readonly ["GET"];
|
|
76
|
+
}, {
|
|
77
|
+
readonly id: "run-detail";
|
|
78
|
+
readonly pattern: RegExp;
|
|
79
|
+
readonly label: "/v1/runs/:id";
|
|
80
|
+
readonly methods: readonly ["GET"];
|
|
81
|
+
}];
|
|
82
|
+
/** 本域可分派行的 `id` 闭集 —— handler 的收尾按它判穷尽(漏一口 = 编译红)。 */
|
|
83
|
+
export type RunsRouteId = RouteIdsOf<typeof RUNS_ROUTES>;
|
|
84
|
+
export declare const RUN_VERBS_ROUTES: readonly [{
|
|
85
|
+
readonly id: "run-subagent-output";
|
|
86
|
+
readonly pattern: RegExp;
|
|
87
|
+
readonly label: "/v1/runs/:id/subagents/:sub/*";
|
|
88
|
+
readonly methods: readonly ["GET"];
|
|
89
|
+
}, {
|
|
90
|
+
readonly id: "run-subagent-stream";
|
|
91
|
+
readonly pattern: RegExp;
|
|
92
|
+
readonly label: "/v1/runs/:id/subagents/:sub/*";
|
|
93
|
+
readonly methods: readonly ["GET"];
|
|
94
|
+
}, {
|
|
95
|
+
readonly id: "run-subagent-steer";
|
|
96
|
+
readonly pattern: RegExp;
|
|
97
|
+
readonly label: "/v1/runs/:id/subagents/:sub/*";
|
|
98
|
+
readonly methods: readonly ["POST"];
|
|
99
|
+
}, {
|
|
100
|
+
readonly id: "run-subagent-resume";
|
|
101
|
+
readonly pattern: RegExp;
|
|
102
|
+
readonly label: "/v1/runs/:id/subagents/:sub/*";
|
|
103
|
+
readonly billable: true;
|
|
104
|
+
readonly methods: readonly ["POST"];
|
|
105
|
+
}, {
|
|
106
|
+
readonly id: "run-task-output";
|
|
107
|
+
readonly pattern: RegExp;
|
|
108
|
+
readonly label: "/v1/runs/:id/tasks/:tid/*";
|
|
109
|
+
readonly methods: readonly ["GET"];
|
|
110
|
+
}, {
|
|
111
|
+
readonly id: "run-task-stop";
|
|
112
|
+
readonly pattern: RegExp;
|
|
113
|
+
readonly label: "/v1/runs/:id/tasks/:tid/*";
|
|
114
|
+
readonly methods: readonly ["POST"];
|
|
115
|
+
}, {
|
|
116
|
+
readonly id: "elicitation-respond";
|
|
117
|
+
readonly pattern: RegExp;
|
|
118
|
+
readonly label: "/v1/elicitations/:id/respond";
|
|
119
|
+
readonly methods: readonly ["POST"];
|
|
120
|
+
}, {
|
|
121
|
+
readonly id: "question-respond";
|
|
122
|
+
readonly pattern: RegExp;
|
|
123
|
+
readonly label: "/v1/questions/:id/respond";
|
|
124
|
+
readonly methods: readonly ["POST"];
|
|
125
|
+
}, {
|
|
126
|
+
readonly id: "tool-approval-respond";
|
|
127
|
+
readonly pattern: RegExp;
|
|
128
|
+
readonly label: "/v1/tool-approvals/:id/respond";
|
|
129
|
+
readonly methods: readonly ["POST"];
|
|
130
|
+
}, {
|
|
131
|
+
readonly id: "task-ask-decision";
|
|
132
|
+
readonly pattern: RegExp;
|
|
133
|
+
readonly label: "/v1/tasks/:id/asks/:askId/decision";
|
|
134
|
+
readonly methods: readonly ["POST"];
|
|
135
|
+
}];
|
|
136
|
+
export type RunVerbsRouteId = RouteIdsOf<typeof RUN_VERBS_ROUTES>;
|
|
57
137
|
//# sourceMappingURL=runs.d.ts.map
|