@sema-agent/server 7.73.0 → 7.73.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.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { canAskTransition } from "../approval-ask-machine.js";
|
|
2
|
-
import { assertIdempotencyKeyShape, ApprovalAskReadAbortedError, projectAskTerminalClaimTruth } from "./approval-ask-store-sql.js";
|
|
2
|
+
import { assertIdempotencyKeyShape, assertIntegralEpochMs, ApprovalAskReadAbortedError, projectAskTerminalClaimTruth } from "./approval-ask-store-sql.js";
|
|
3
3
|
function applyPatch(row, patch) {
|
|
4
4
|
if (patch.decision !== undefined)
|
|
5
5
|
row.decision = patch.decision;
|
|
@@ -24,6 +24,8 @@ export class InMemoryApprovalAskStore {
|
|
|
24
24
|
asks = new Map();
|
|
25
25
|
batches = new Map();
|
|
26
26
|
async ensureAsk(row) {
|
|
27
|
+
assertIntegralEpochMs("expiresAtMs", row.expiresAtMs);
|
|
28
|
+
assertIntegralEpochMs("createdAtMs", row.createdAtMs);
|
|
27
29
|
if (!this.batches.has(row.batchId)) {
|
|
28
30
|
this.batches.set(row.batchId, {
|
|
29
31
|
batchId: row.batchId,
|
|
@@ -226,6 +226,11 @@ export type DecideResult = {
|
|
|
226
226
|
* `idempotency_conflict`/回放结果。键是调用方铸的 opaque 值,首尾空白没有任何合法语义,
|
|
227
227
|
* 在边界上 fail-loud 拒掉,方言分歧面整个消失(比把列改 VARBINARY 更窄、且对三形同时成立)。
|
|
228
228
|
*/
|
|
229
|
+
/** BIGINT 毫秒列的整数守卫(两 twin 同一只):`expires_at_ms` / `created_at_ms` / `updated_at_ms` 落库前必须是
|
|
230
|
+
* 安全整数。带小数的墙钟(`Date.now() + performance.now()` 派生窗)在 PG 上被 `bigint` 拒收、在 MySQL 协议上被
|
|
231
|
+
* 隐式截断 —— 两方言不同答;这里改成两方言同一句 TypeError(响亮,点名字段与值),铸点侧(`tool-approval.ts`
|
|
232
|
+
* 的 deadline 铸点)负责给整数,本守卫只拦漏网。 */
|
|
233
|
+
export declare function assertIntegralEpochMs(field: string, value: number): void;
|
|
229
234
|
export declare function assertIdempotencyKeyShape(key: string): void;
|
|
230
235
|
/**
|
|
231
236
|
* [ref] 车3 刀 3b(§14.2 遗留记账):两条**重放读口**被调用方的 deadline 掐断时抛的具名错误。
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { mysqlDriver, pgDriver, dialectJsonEncoder } from "./sql-driver.js";
|
|
2
2
|
import { canAskTransition } from "../approval-ask-machine.js";
|
|
3
3
|
import { isDupKeyError, isMissingColumnError } from "./sql-errors.js";
|
|
4
|
+
export function assertIntegralEpochMs(field, value) {
|
|
5
|
+
if (!Number.isSafeInteger(value)) {
|
|
6
|
+
throw new TypeError(`approval-ask store: ${field} must be an integer epoch-ms (BIGINT column), got ${String(value)}`);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
4
9
|
export function assertIdempotencyKeyShape(key) {
|
|
5
10
|
if (key.length === 0 || key.length > 255 || key.trim() !== key) {
|
|
6
11
|
throw new Error(`invalid idempotency key: must be 1-255 chars with no leading/trailing whitespace (got ${JSON.stringify(key.slice(0, 32))}${key.length > 32 ? "…" : ""}, length ${key.length})`);
|
|
@@ -314,6 +319,8 @@ export class SqlApprovalAskStore {
|
|
|
314
319
|
return rows[0] ? mapBatchRow(rows[0]) : null;
|
|
315
320
|
}
|
|
316
321
|
async ensureAsk(row) {
|
|
322
|
+
assertIntegralEpochMs("expiresAtMs", row.expiresAtMs);
|
|
323
|
+
assertIntegralEpochMs("createdAtMs", row.createdAtMs);
|
|
317
324
|
const now = row.createdAtMs;
|
|
318
325
|
let insertedRows = 0;
|
|
319
326
|
const conn = await this.db.connect();
|
package/dist/tool-approval.js
CHANGED
|
@@ -852,7 +852,7 @@ export class ToolApprovalCoordinator {
|
|
|
852
852
|
};
|
|
853
853
|
const windowBudgetMs = reachability === "unreached" ? this.unreachedTtlMs : this.ttlMs;
|
|
854
854
|
const effectiveWindowMs = effectiveAskWindowMs(windowBudgetMs, this.windowMarginMs, origin.legDeadlineMonotonic, performance.now());
|
|
855
|
-
const expiresAtMs = Date.now() + effectiveWindowMs;
|
|
855
|
+
const expiresAtMs = Math.ceil(Date.now() + effectiveWindowMs);
|
|
856
856
|
let askId;
|
|
857
857
|
let batchId;
|
|
858
858
|
const card = this.askStore ? buildApprovalCard(frame, req, req.requiresRealApproval === true) : undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sema-agent/server",
|
|
3
|
-
"version": "7.73.
|
|
3
|
+
"version": "7.73.1",
|
|
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",
|