@sema-agent/server 5.1.1 → 5.1.2
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.
|
@@ -18,12 +18,18 @@ export const ACTIVE_RUN_CONFLICT_BASE_TEXT = "session already has an active run
|
|
|
18
18
|
/** gate.kind → 它的那一个 resume 入口(sessionId/taskId 寻址,无秘密)。 */
|
|
19
19
|
export function resumeEntryForGate(kind, ids) {
|
|
20
20
|
switch (kind) {
|
|
21
|
+
// tool_approval / policy_ask 不是 core 现役 kind(wire 集=WIRE_GATE_KINDS 六个,type 门双向等值)——
|
|
22
|
+
// 这两臂是**耐久历史行容忍**([2373] D 类):旧 core 铸的 checkpoint 行可能带旧 kind 名,店里读出来
|
|
23
|
+
// 仍要给出真出路;不是对上游新帧的兼容臂,别当 [2354] 清理对象误删。
|
|
21
24
|
case "tool_approval":
|
|
22
25
|
case "human":
|
|
23
26
|
case "irreversible_ask":
|
|
24
27
|
case "policy_ask":
|
|
25
28
|
return `/v1/approvals/${ids.sessionId}/decide`;
|
|
26
29
|
case "plan_review":
|
|
30
|
+
// needs_review 与 plan_review 同入口(TASKS-RUNS-8 附注,[2400] 审计补臂):routes/tasks.ts 的
|
|
31
|
+
// needs_review park 注明文「resumable via /plan_review」——此前缺臂 ⇒ 409 体 pendingGate 丢指引。
|
|
32
|
+
case "needs_review":
|
|
27
33
|
return `/v1/assistant/tasks/${ids.taskId}/plan_review`;
|
|
28
34
|
case "resource_limit":
|
|
29
35
|
return `/v1/assistant/tasks/${ids.taskId}/resume`;
|
|
@@ -508,8 +508,10 @@ async function handleApprovalsAssistantBody(req, res, url, ctx, miss) {
|
|
|
508
508
|
// verify-reject): an unbound decide can consume a gate that was SWAPPED after the operator's GET (see
|
|
509
509
|
// gate A, approve lands on gate B) — tolerable as a one-shot legacy quirk, NOT as the mint of a
|
|
510
510
|
// SESSION-PERSISTENT auto-approval for a tool the operator never saw. remember is a NEW contract, so
|
|
511
|
-
// it can demand the strict calling shape
|
|
512
|
-
//
|
|
511
|
+
// it can demand the strict calling shape — the BFF receives boundCallId on the pending row
|
|
512
|
+
// (HITL-7 注纠,[2400] 审计:checkpointToken 从不上 pending 行,listPending 的 SELECT 无 token 列;
|
|
513
|
+
// 下面的门是「或」关系,boundCallId 单独即满足,所以旧措辞没造成真故障)。
|
|
514
|
+
// Plain decide without remember keeps the legacy unbound fallback untouched.
|
|
513
515
|
if (!body.checkpointToken && !body.boundCallId) {
|
|
514
516
|
sendError(res, 400, "remember_requires_binding", "remember requires the decision binding (echo checkpointToken and/or boundCallId from the pending approval)");
|
|
515
517
|
return;
|
package/dist/http/routes/runs.js
CHANGED
|
@@ -542,7 +542,13 @@ async function handleRunsBody(req, res, url, ctx, miss) {
|
|
|
542
542
|
try {
|
|
543
543
|
body = (await readJson(req));
|
|
544
544
|
}
|
|
545
|
-
catch {
|
|
545
|
+
catch (e) {
|
|
546
|
+
// TASKS-RUNS-5([2400] 审计):readJson 的 HttpError(413 超限)原样透传——裸 catch 折成
|
|
547
|
+
// 400 invalid_json 会让 9 MiB 合法 JSON 被报「JSON 非法」(compact 腿是既有对照组正确形)。
|
|
548
|
+
if (e instanceof HttpError) {
|
|
549
|
+
sendError(res, e.status, httpErrorCode(e.status, e.code), e.message);
|
|
550
|
+
return;
|
|
551
|
+
}
|
|
546
552
|
sendError(res, 400, "request.invalid_json", "invalid JSON body");
|
|
547
553
|
return;
|
|
548
554
|
}
|
|
@@ -856,7 +862,11 @@ async function handleRunsBody(req, res, url, ctx, miss) {
|
|
|
856
862
|
try {
|
|
857
863
|
body = (await readJson(req));
|
|
858
864
|
}
|
|
859
|
-
catch {
|
|
865
|
+
catch (e) {
|
|
866
|
+
if (e instanceof HttpError) {
|
|
867
|
+
sendError(res, e.status, httpErrorCode(e.status, e.code), e.message);
|
|
868
|
+
return;
|
|
869
|
+
} // TASKS-RUNS-5 同族
|
|
860
870
|
sendError(res, 400, "request.invalid_json", "invalid JSON body");
|
|
861
871
|
return;
|
|
862
872
|
}
|
|
@@ -1187,7 +1197,11 @@ async function handleRunVerbsBody(req, res, url, ctx, miss) {
|
|
|
1187
1197
|
try {
|
|
1188
1198
|
body = (await readJson(req));
|
|
1189
1199
|
}
|
|
1190
|
-
catch {
|
|
1200
|
+
catch (e) {
|
|
1201
|
+
if (e instanceof HttpError) {
|
|
1202
|
+
sendError(res, e.status, httpErrorCode(e.status, e.code), e.message);
|
|
1203
|
+
return;
|
|
1204
|
+
} // TASKS-RUNS-5 同族
|
|
1191
1205
|
sendError(res, 400, "request.invalid_json", "invalid JSON body");
|
|
1192
1206
|
return;
|
|
1193
1207
|
}
|
package/dist/runs.js
CHANGED
|
@@ -697,8 +697,10 @@ promptManifests) {
|
|
|
697
697
|
}
|
|
698
698
|
// E12 (shell-host contract): after a COMPLETED run, pull core's opt-in post-completion prompt suggestions (a fire-and-forget
|
|
699
699
|
// pass in core; suggestions() never rejects + resolves to [] when off / not completed / empty). UNTRUSTED model
|
|
700
|
-
// text for the shell UI ONLY → redact + persist as a `suggestions` event
|
|
701
|
-
//
|
|
700
|
+
// text for the shell UI ONLY → redact + persist as a `suggestions` event on the durable ledger; NEVER re-fed to a
|
|
701
|
+
// model. ⚠️ 读法(TASKS-RUNS-1 注漂移修,[2400] 审计):它落账在 setTerminal **之后**,而 live tail
|
|
702
|
+
// (sse-log)在终态时有意**不投递**这一帧(见 sse-log.ts 注)——消费契约是 `await result()` 后从
|
|
703
|
+
// `GET /v1/runs/:id` 的 RunRecord.suggestions 读,**不是**从 events tail 等它。 Gated on a COMPLETED terminal — a suspended/parked/failed leg has
|
|
702
704
|
// none (core also returns [] for a non-completed task; the explicit status gate avoids the needless call + pins the
|
|
703
705
|
// completed-only contract rather than depending on core's guard).
|
|
704
706
|
if (spec.suggestNextPrompts && reached?.kind === "done" && reached.result.status === "completed") {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sema-agent/server",
|
|
3
|
-
"version": "5.1.
|
|
3
|
+
"version": "5.1.2",
|
|
4
4
|
"description": "Sema Server — the server/API implementation layer for Sema, wiring core, registry, model providers, and cloud agent execution. Built on @sema-agent/core.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "BUSL-1.1",
|