@sema-agent/server 7.139.0 → 7.140.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.
Files changed (194) hide show
  1. package/MIGRATION.md +181 -0
  2. package/USAGE.md +19 -13
  3. package/dist/adoption/runner.js +1 -1
  4. package/dist/adoption/sql.js +1 -1
  5. package/dist/approval-card.d.ts +6 -6
  6. package/dist/bench/s1/live-deps.js +3 -2
  7. package/dist/bench/s1/row.d.ts +5 -2
  8. package/dist/bench/s1/row.js +2 -22
  9. package/dist/boot/adoption.js +1 -1
  10. package/dist/boot/execution-env.js +12 -10
  11. package/dist/boot/execution-lane.d.ts +8 -0
  12. package/dist/boot/execution-lane.js +6 -1
  13. package/dist/boot/memory-boundary.d.ts +14 -51
  14. package/dist/boot/memory-boundary.js +10 -20
  15. package/dist/boot/memory-consolidation.d.ts +15 -11
  16. package/dist/boot/memory-consolidation.js +23 -12
  17. package/dist/boot/resolve-spec.d.ts +3 -5
  18. package/dist/boot/resolve-spec.js +2 -4
  19. package/dist/boot/runner-deps.d.ts +3 -3
  20. package/dist/boot/runner-deps.js +1 -0
  21. package/dist/boot/stage-03-store-backend.d.ts +2 -6
  22. package/dist/boot/stage-03-store-backend.js +2 -3
  23. package/dist/boot/stage-04-stores.d.ts +2 -6
  24. package/dist/boot/stage-04-stores.js +5 -5
  25. package/dist/boot/stage-05-execution-env.d.ts +2 -6
  26. package/dist/boot/stage-06-runners.d.ts +2 -6
  27. package/dist/boot/stage-06-runners.js +2 -2
  28. package/dist/boot/stage-07-capability-layer.d.ts +2 -6
  29. package/dist/boot/stage-08-reapers.d.ts +2 -6
  30. package/dist/boot/stage-09-leader.d.ts +2 -6
  31. package/dist/boot/stage-10-http-server.d.ts +2 -6
  32. package/dist/boot/stage-10-http-server.js +5 -4
  33. package/dist/boot/stores.d.ts +3 -6
  34. package/dist/boot/stores.js +27 -40
  35. package/dist/boot/task-list-lane.d.ts +1 -1
  36. package/dist/boot/task-list-lane.js +1 -1
  37. package/dist/boot/web-admin.js +35 -9
  38. package/dist/capabilities/execution-lane.d.ts +2 -2
  39. package/dist/config-catalog.js +2 -1
  40. package/dist/config-provider.d.ts +14 -13
  41. package/dist/config-provider.js +24 -18
  42. package/dist/config-types.d.ts +11 -2
  43. package/dist/config.js +2 -1
  44. package/dist/delegated-session-owner.d.ts +2 -1
  45. package/dist/delegated-session-owner.js +1 -1
  46. package/dist/deployment-shape.d.ts +9 -8
  47. package/dist/deployment-shape.js +4 -4
  48. package/dist/execution-lane-caps.d.ts +97 -106
  49. package/dist/execution-lane-caps.js +67 -83
  50. package/dist/http/memory-compliance-failure-reply.d.ts +3 -1
  51. package/dist/http/memory-compliance-failure-reply.js +5 -0
  52. package/dist/http/memory-layer-reply.d.ts +30 -0
  53. package/dist/http/memory-layer-reply.js +24 -0
  54. package/dist/http/resume-legs.js +13 -16
  55. package/dist/http/retired-service-deps.d.ts +1 -1
  56. package/dist/http/retired-service-deps.js +1 -1
  57. package/dist/http/routes/adoption.js +1 -1
  58. package/dist/http/routes/memory-bundle.js +3 -0
  59. package/dist/http/routes/memory-compliance.js +8 -1
  60. package/dist/http/routes/memory-consolidation.js +12 -1
  61. package/dist/http/routes/memory-origin.js +14 -2
  62. package/dist/http/routes/memory-policy.js +5 -0
  63. package/dist/http/routes/sessions.js +28 -11
  64. package/dist/http/routes/tasks.js +4 -2
  65. package/dist/http/server.d.ts +5 -25
  66. package/dist/http/server.js +2 -2
  67. package/dist/identity-source.d.ts +1 -1
  68. package/dist/identity-source.js +1 -1
  69. package/dist/lane-home-probe.d.ts +68 -42
  70. package/dist/lane-home-probe.js +53 -30
  71. package/dist/leader/wire.js +5 -4
  72. package/dist/memory-bundle-engine.d.ts +16 -9
  73. package/dist/memory-bundle-engine.js +29 -6
  74. package/dist/memory-operator-faces.d.ts +85 -30
  75. package/dist/memory-operator-faces.js +136 -30
  76. package/dist/memory-project-layer.d.ts +3 -21
  77. package/dist/memory-project-layer.js +11 -8
  78. package/dist/memory-scope-stores.d.ts +73 -0
  79. package/dist/memory-scope-stores.js +86 -0
  80. package/dist/memory-scope.d.ts +29 -5
  81. package/dist/memory-scope.js +16 -4
  82. package/dist/memory-sync-client.d.ts +20 -7
  83. package/dist/memory-sync-client.js +31 -13
  84. package/dist/plugins/adoption-log-sql.js +4 -4
  85. package/dist/plugins/approval-ask-store-sql.js +14 -14
  86. package/dist/plugins/approval-nonce-store.js +4 -4
  87. package/dist/plugins/blob-backend.d.ts +4 -4
  88. package/dist/plugins/blob-backend.js +7 -7
  89. package/dist/plugins/breaker-state-sql.js +2 -2
  90. package/dist/plugins/checkpoint-index-columns.js +2 -2
  91. package/dist/plugins/checkpoint-store-sql.js +16 -16
  92. package/dist/plugins/device-store-sql.js +19 -19
  93. package/dist/plugins/ensure-index.d.ts +1 -2
  94. package/dist/plugins/execution-placement-sql.d.ts +8 -8
  95. package/dist/plugins/execution-placement-sql.js +8 -8
  96. package/dist/plugins/file-history-store-sql.d.ts +2 -2
  97. package/dist/plugins/file-history-store-sql.js +4 -4
  98. package/dist/plugins/image-bake-store-sql.js +9 -9
  99. package/dist/plugins/image-index-sql.js +11 -11
  100. package/dist/plugins/leader-run-store-sql.js +4 -4
  101. package/dist/plugins/mailbox-store-sql.d.ts +2 -1
  102. package/dist/plugins/mailbox-store-sql.js +4 -4
  103. package/dist/plugins/memory-engine-tidb.js +5 -5
  104. package/dist/plugins/memory-optout-grant-store-sql.js +1 -1
  105. package/dist/plugins/memory-sync-store-tidb.js +3 -3
  106. package/dist/plugins/one-time-migrations.d.ts +10 -9
  107. package/dist/plugins/one-time-migrations.js +36 -36
  108. package/dist/plugins/org-delivery-quota-store.js +2 -2
  109. package/dist/plugins/outcome-ledger-sql.js +2 -2
  110. package/dist/plugins/permission-rule-store-sql.d.ts +4 -4
  111. package/dist/plugins/permission-rule-store-sql.js +16 -16
  112. package/dist/plugins/remote-env-adb.d.ts +7 -24
  113. package/dist/plugins/remote-env-adb.js +22 -5
  114. package/dist/plugins/remote-env-device.d.ts +2 -28
  115. package/dist/plugins/remote-env-device.js +2 -1
  116. package/dist/plugins/remote-env-e2b.d.ts +18 -26
  117. package/dist/plugins/remote-env-e2b.js +51 -4
  118. package/dist/plugins/remote-env-file-error.d.ts +1 -1
  119. package/dist/plugins/remote-env-file-error.js +8 -2
  120. package/dist/plugins/remote-env-host.d.ts +19 -35
  121. package/dist/plugins/remote-env-host.js +26 -3
  122. package/dist/plugins/remote-env-k8s.d.ts +3 -14
  123. package/dist/plugins/remote-env-k8s.js +3 -2
  124. package/dist/plugins/remote-env-local-docker.d.ts +4 -15
  125. package/dist/plugins/remote-env-local-docker.js +5 -4
  126. package/dist/plugins/remote-env-ssh.d.ts +4 -24
  127. package/dist/plugins/remote-env-ssh.js +4 -3
  128. package/dist/plugins/resume-anchor-store-sql.js +2 -2
  129. package/dist/plugins/retention-lane-store-sql.d.ts +1 -1
  130. package/dist/plugins/retention-lane-store-sql.js +2 -2
  131. package/dist/plugins/retention-store-sql.d.ts +1 -1
  132. package/dist/plugins/retention-store-sql.js +6 -6
  133. package/dist/plugins/run-store-sql.js +15 -15
  134. package/dist/plugins/schema-consistency.d.ts +6 -6
  135. package/dist/plugins/schema-consistency.js +1 -1
  136. package/dist/plugins/schema-ensure-legs.d.ts +2 -3
  137. package/dist/plugins/schema-ensure-legs.js +2 -2
  138. package/dist/plugins/schema-live-columns.d.ts +1 -1
  139. package/dist/plugins/session-capture-record-store-sql.js +1 -1
  140. package/dist/plugins/session-rules-column.d.ts +1 -1
  141. package/dist/plugins/session-rules-column.js +1 -1
  142. package/dist/plugins/session-workspace-cell.d.ts +1 -1
  143. package/dist/plugins/session-workspace-cell.js +1 -1
  144. package/dist/plugins/shared-memory-store-sql.js +2 -2
  145. package/dist/plugins/sql-driver.d.ts +10 -5
  146. package/dist/plugins/sql-driver.js +6 -6
  147. package/dist/plugins/sql-errors.js +1 -1
  148. package/dist/plugins/store-backend.d.ts +4 -6
  149. package/dist/plugins/store-backend.js +6 -6
  150. package/dist/plugins/task-list-store-sql.js +11 -11
  151. package/dist/plugins/tidb-pool.js +5 -5
  152. package/dist/plugins/tidb-session-storage.js +4 -4
  153. package/dist/plugins/tidb-session-store.js +13 -13
  154. package/dist/plugins/tool-result-store-sql.d.ts +2 -2
  155. package/dist/plugins/tool-result-store-sql.js +3 -3
  156. package/dist/plugins/user-input-ledger-sql.js +2 -2
  157. package/dist/plugins/workflow-journal-store-sql.js +5 -5
  158. package/dist/plugins/workflow-run-store-sql.js +19 -19
  159. package/dist/plugins/write-behind-counter.d.ts +2 -3
  160. package/dist/plugins/write-behind-counter.js +5 -5
  161. package/dist/resource-suspend.d.ts +14 -12
  162. package/dist/resource-suspend.js +1 -1
  163. package/dist/resource-window.d.ts +4 -3
  164. package/dist/run-local.js +14 -19
  165. package/dist/runs.d.ts +8 -4
  166. package/dist/runs.js +49 -65
  167. package/dist/session-incarnation.d.ts +1 -1
  168. package/dist/session-incarnation.js +1 -1
  169. package/dist/session-policy-wire.d.ts +1 -1
  170. package/dist/sql-engine-posture.d.ts +1 -1
  171. package/dist/sql-engine-posture.js +1 -1
  172. package/dist/{plugins → stores-sql}/background-agent-store-sql.d.ts +2 -2
  173. package/dist/{plugins → stores-sql}/background-agent-store-sql.js +8 -8
  174. package/dist/{plugins → stores-sql}/session-policy-store-sql.d.ts +7 -5
  175. package/dist/{plugins → stores-sql}/session-policy-store-sql.js +12 -12
  176. package/dist/{plugins → stores-sql}/usage-window-store-sql.d.ts +1 -1
  177. package/dist/{plugins → stores-sql}/usage-window-store-sql.js +3 -3
  178. package/dist/task-a2a.js +5 -6
  179. package/dist/task-mcp.d.ts +20 -7
  180. package/dist/task-mcp.js +17 -9
  181. package/dist/terminal.d.ts +27 -0
  182. package/dist/terminal.js +6 -0
  183. package/dist/trace/redact.d.ts +3 -1
  184. package/dist/trace/redact.js +80 -28
  185. package/dist/trace/self-minted-wire.d.ts +58 -0
  186. package/dist/trace/self-minted-wire.js +16 -0
  187. package/dist/web-admin-client/candidate-gate.d.ts +11 -7
  188. package/dist/web-admin-client/candidate-gate.js +1 -1
  189. package/dist/web-admin-client/http-client.d.ts +5 -4
  190. package/dist/web-admin-client/http-client.js +2 -2
  191. package/dist/web-admin-client/read-warnings.d.ts +7 -17
  192. package/dist/web-admin-client/read-warnings.js +5 -9
  193. package/package.json +2 -2
  194. package/wire-changes/server@7.140.0.json +184 -0
@@ -24,8 +24,8 @@ export class SqlBreakerState {
24
24
  this.db = db;
25
25
  this.onWriteFail = onWriteFail;
26
26
  }
27
- q(tidb, pg) {
28
- return this.db.dialect === "tidb" ? tidb : pg;
27
+ q(mysql, pg) {
28
+ return this.db.dialect === "mysql" ? mysql : pg;
29
29
  }
30
30
  get(key) {
31
31
  return this.cache.get(key);
@@ -33,7 +33,7 @@ export function buildCheckpointIndexCells(cp) {
33
33
  };
34
34
  }
35
35
  export const APPROVAL_CARD_COLUMN_MAX_BYTES = {
36
- tidb: 65_535,
36
+ mysql: 65_535,
37
37
  pg: Number.POSITIVE_INFINITY,
38
38
  };
39
39
  export function judgeCheckpointIndexCells(cp, dialect) {
@@ -83,7 +83,7 @@ function renderFacetCase(compared) {
83
83
  return `CASE ${CHECKPOINT_FACET_CASES.map((c) => `WHEN ${compared(c.column)} IN (${c.words.map(literal).join(", ")}) THEN ${literal(c.facet)}`).join(" ")} END`;
84
84
  }
85
85
  export const CHECKPOINT_FACET_SQL = Object.freeze({
86
- tidb: renderFacetCase((column) => `CAST(${column} AS BINARY)`),
86
+ mysql: renderFacetCase((column) => `CAST(${column} AS BINARY)`),
87
87
  pg: renderFacetCase((column) => column),
88
88
  });
89
89
  export const CHECKPOINT_SWEEP_ORDER_SQL = "CASE WHEN approval_card IS NULL THEN 1 ELSE 0 END ASC, deadline ASC, token ASC";
@@ -343,8 +343,8 @@ export class SqlCheckpointStore {
343
343
  this.logger = logger;
344
344
  this.retention = opts.retention ?? UNMANAGED_RETENTION;
345
345
  }
346
- q(tidb, pg) {
347
- return this.db.dialect === "tidb" ? tidb : pg;
346
+ q(mysql, pg) {
347
+ return this.db.dialect === "mysql" ? mysql : pg;
348
348
  }
349
349
  json(value, label) {
350
350
  return dialectProtocolJsonEncoder(this.db.dialect)(value, label);
@@ -353,7 +353,7 @@ export class SqlCheckpointStore {
353
353
  return isDupKeyError(this.db.dialect, e);
354
354
  }
355
355
  ph(n) {
356
- return this.db.dialect === "tidb" ? "?" : `$${n}`;
356
+ return this.db.dialect === "mysql" ? "?" : `$${n}`;
357
357
  }
358
358
  pendingRowQuery(select, sessionId, scope, binding) {
359
359
  const params = [sessionId];
@@ -424,8 +424,8 @@ export class SqlCheckpointStore {
424
424
  }
425
425
  }
426
426
  async get(token) {
427
- const { rows } = await this.db.query(this.q(`SELECT version, status, ${jsonColumnText("tidb", "checkpoint")}, ${jsonColumnText("tidb", "outcome")}, reopen_reason, rev, ` +
428
- `${jsonColumnText("tidb", "pending_steer_queue")}, ${jsonColumnText("tidb", "execution_outcome")}, execution_at_ms FROM checkpoint WHERE token = ?`, `SELECT version, status, ${jsonColumnText("pg", "checkpoint")}, ${jsonColumnText("pg", "outcome")}, reopen_reason, rev, ` +
427
+ const { rows } = await this.db.query(this.q(`SELECT version, status, ${jsonColumnText("mysql", "checkpoint")}, ${jsonColumnText("mysql", "outcome")}, reopen_reason, rev, ` +
428
+ `${jsonColumnText("mysql", "pending_steer_queue")}, ${jsonColumnText("mysql", "execution_outcome")}, execution_at_ms FROM checkpoint WHERE token = ?`, `SELECT version, status, ${jsonColumnText("pg", "checkpoint")}, ${jsonColumnText("pg", "outcome")}, reopen_reason, rev, ` +
429
429
  `${jsonColumnText("pg", "pending_steer_queue")}, ${jsonColumnText("pg", "execution_outcome")}, execution_at_ms FROM checkpoint WHERE token = $1`), [token]);
430
430
  const r = rows[0];
431
431
  if (!r)
@@ -480,7 +480,7 @@ export class SqlCheckpointStore {
480
480
  }
481
481
  async recordExecutionOutcome(token, scope, gate) {
482
482
  for (let attempt = 0; attempt < EXECUTION_RECORD_CAS_ATTEMPTS; attempt++) {
483
- const { rows } = await this.db.query(this.q(`SELECT scope, status, ${jsonColumnText("tidb", "execution_outcome")} FROM checkpoint WHERE token = ?`, `SELECT scope, status, ${jsonColumnText("pg", "execution_outcome")} FROM checkpoint WHERE token = $1`), [token]);
483
+ const { rows } = await this.db.query(this.q(`SELECT scope, status, ${jsonColumnText("mysql", "execution_outcome")} FROM checkpoint WHERE token = ?`, `SELECT scope, status, ${jsonColumnText("pg", "execution_outcome")} FROM checkpoint WHERE token = $1`), [token]);
484
484
  const row = rows[0];
485
485
  const facts = row === undefined
486
486
  ? undefined
@@ -504,7 +504,7 @@ export class SqlCheckpointStore {
504
504
  async setPendingSteer(token, scope, steer) {
505
505
  const clean = validatePendingSteer(steer);
506
506
  for (let attempt = 0; attempt < STEER_CAS_ATTEMPTS; attempt++) {
507
- const { rows } = await this.db.query(this.q(`SELECT status, ${jsonColumnText("tidb", "pending_steer_queue")}, pending_steer_rev FROM checkpoint WHERE token = ? AND scope = ?`, `SELECT status, ${jsonColumnText("pg", "pending_steer_queue")}, pending_steer_rev FROM checkpoint WHERE token = $1 AND scope = $2`), [token, scope]);
507
+ const { rows } = await this.db.query(this.q(`SELECT status, ${jsonColumnText("mysql", "pending_steer_queue")}, pending_steer_rev FROM checkpoint WHERE token = ? AND scope = ?`, `SELECT status, ${jsonColumnText("pg", "pending_steer_queue")}, pending_steer_rev FROM checkpoint WHERE token = $1 AND scope = $2`), [token, scope]);
508
508
  const row = rows[0];
509
509
  if (!row || row.status !== "pending")
510
510
  return false;
@@ -537,12 +537,12 @@ export class SqlCheckpointStore {
537
537
  }
538
538
  async reapExpired(cutoff) {
539
539
  const res = await this.db.query(this.q("UPDATE checkpoint SET status = 'expired', decided_at_ms = ? " +
540
- `WHERE status = 'pending' AND ((deadline IS NOT NULL AND deadline <= ? AND COALESCE(${CHECKPOINT_FACET_SQL.tidb}, '') <> 'A') OR (terminal_at_ms IS NOT NULL AND terminal_at_ms <= ?))`, "UPDATE checkpoint SET status = 'expired', decided_at_ms = $1 " +
540
+ `WHERE status = 'pending' AND ((deadline IS NOT NULL AND deadline <= ? AND COALESCE(${CHECKPOINT_FACET_SQL.mysql}, '') <> 'A') OR (terminal_at_ms IS NOT NULL AND terminal_at_ms <= ?))`, "UPDATE checkpoint SET status = 'expired', decided_at_ms = $1 " +
541
541
  `WHERE status = 'pending' AND ((deadline IS NOT NULL AND deadline <= $2 AND COALESCE(${CHECKPOINT_FACET_SQL.pg}, '') <> 'A') OR (terminal_at_ms IS NOT NULL AND terminal_at_ms <= $3))`), [Date.now(), cutoff, cutoff]);
542
542
  return res.affected;
543
543
  }
544
544
  async listExpiredApprovalGates(cutoff, limit = 100) {
545
- const { rows } = await this.db.query(this.q(`SELECT session_id, scope FROM checkpoint WHERE status = 'pending' AND deadline IS NOT NULL AND deadline <= ? AND ${CHECKPOINT_FACET_SQL.tidb} = 'A' ORDER BY ${CHECKPOINT_SWEEP_ORDER_SQL} LIMIT ?`, `SELECT session_id, scope FROM checkpoint WHERE status = 'pending' AND deadline IS NOT NULL AND deadline <= $1 AND ${CHECKPOINT_FACET_SQL.pg} = 'A' ORDER BY ${CHECKPOINT_SWEEP_ORDER_SQL} LIMIT $2`), [cutoff, limit]);
545
+ const { rows } = await this.db.query(this.q(`SELECT session_id, scope FROM checkpoint WHERE status = 'pending' AND deadline IS NOT NULL AND deadline <= ? AND ${CHECKPOINT_FACET_SQL.mysql} = 'A' ORDER BY ${CHECKPOINT_SWEEP_ORDER_SQL} LIMIT ?`, `SELECT session_id, scope FROM checkpoint WHERE status = 'pending' AND deadline IS NOT NULL AND deadline <= $1 AND ${CHECKPOINT_FACET_SQL.pg} = 'A' ORDER BY ${CHECKPOINT_SWEEP_ORDER_SQL} LIMIT $2`), [cutoff, limit]);
546
546
  return rows.map((r) => ({ sessionId: String(r.session_id), scope: String(r.scope) }));
547
547
  }
548
548
  async listPending(scope) {
@@ -591,7 +591,7 @@ export class SqlCheckpointStore {
591
591
  return out.sort((a, b) => (b.riskDescriptor?.severity ?? 0) - (a.riskDescriptor?.severity ?? 0) || a.createdAt - b.createdAt);
592
592
  }
593
593
  async readParkedSkillCardFacts(token) {
594
- const { rows } = await this.db.query(this.q(`SELECT ${jsonColumnText("tidb", "checkpoint")} FROM checkpoint WHERE token = ? AND status = 'pending'`, `SELECT ${jsonColumnText("pg", "checkpoint")} FROM checkpoint WHERE token = $1 AND status = 'pending'`), [token]);
594
+ const { rows } = await this.db.query(this.q(`SELECT ${jsonColumnText("mysql", "checkpoint")} FROM checkpoint WHERE token = ? AND status = 'pending'`, `SELECT ${jsonColumnText("pg", "checkpoint")} FROM checkpoint WHERE token = $1 AND status = 'pending'`), [token]);
595
595
  const r = rows[0];
596
596
  if (r === undefined)
597
597
  return {};
@@ -614,7 +614,7 @@ export class SqlCheckpointStore {
614
614
  }
615
615
  }
616
616
  async listByScope(scope) {
617
- const { rows } = await this.db.query(this.q(`SELECT ${jsonColumnText("tidb", "checkpoint")}, status FROM checkpoint WHERE status = 'pending' AND scope = ? ORDER BY created_at_ms ASC LIMIT 500`, `SELECT ${jsonColumnText("pg", "checkpoint")}, status FROM checkpoint WHERE status = 'pending' AND scope = $1 ORDER BY created_at_ms ASC LIMIT 500`), [scope]);
617
+ const { rows } = await this.db.query(this.q(`SELECT ${jsonColumnText("mysql", "checkpoint")}, status FROM checkpoint WHERE status = 'pending' AND scope = ? ORDER BY created_at_ms ASC LIMIT 500`, `SELECT ${jsonColumnText("pg", "checkpoint")}, status FROM checkpoint WHERE status = 'pending' AND scope = $1 ORDER BY created_at_ms ASC LIMIT 500`), [scope]);
618
618
  const out = [];
619
619
  for (const r of rows) {
620
620
  const cp = refusing("a checkpoint nobody can resume", () => decodeCheckpointColumn(r.checkpoint, `in the ${scope} scheduler view`));
@@ -633,7 +633,7 @@ export class SqlCheckpointStore {
633
633
  return rows[0] ? String(rows[0].token) : null;
634
634
  }
635
635
  async findCheckpointCandidatesForAsk(scope, sessionId, toolCallId, sinceMs) {
636
- const { rows } = await this.db.query(this.q(`SELECT token, status, created_at_ms, tool_call_id, bound_input_hash, version, ${jsonColumnText("tidb", "checkpoint")} FROM checkpoint ` +
636
+ const { rows } = await this.db.query(this.q(`SELECT token, status, created_at_ms, tool_call_id, bound_input_hash, version, ${jsonColumnText("mysql", "checkpoint")} FROM checkpoint ` +
637
637
  "WHERE scope=? AND session_id=? AND created_at_ms>=? AND (tool_call_id=? OR tool_call_id IS NULL) ORDER BY created_at_ms ASC", `SELECT token, status, created_at_ms, tool_call_id, bound_input_hash, version, ${jsonColumnText("pg", "checkpoint")} FROM checkpoint ` +
638
638
  "WHERE scope=$1 AND session_id=$2 AND created_at_ms>=$3 AND (tool_call_id=$4 OR tool_call_id IS NULL) ORDER BY created_at_ms ASC"), [scope, sessionId, sinceMs, toolCallId]);
639
639
  const out = [];
@@ -671,7 +671,7 @@ export class SqlCheckpointStore {
671
671
  return out;
672
672
  }
673
673
  async findDecidedApprovalsForBinding(sessionId, boundCallId) {
674
- const { rows } = await this.db.query(this.q(`SELECT scope, bound_input_hash, ${jsonColumnText("tidb", "outcome")}, ${jsonColumnText("tidb", "execution_outcome")} FROM checkpoint ` +
674
+ const { rows } = await this.db.query(this.q(`SELECT scope, bound_input_hash, ${jsonColumnText("mysql", "outcome")}, ${jsonColumnText("mysql", "execution_outcome")} FROM checkpoint ` +
675
675
  `WHERE session_id=? AND tool_call_id=? AND status='resolved' AND decided_at_ms IS NOT NULL ORDER BY decided_at_ms DESC LIMIT ${DECIDED_REPLAY_SCAN_CAP}`, `SELECT scope, bound_input_hash, ${jsonColumnText("pg", "outcome")}, ${jsonColumnText("pg", "execution_outcome")} FROM checkpoint ` +
676
676
  `WHERE session_id=$1 AND tool_call_id=$2 AND status='resolved' AND decided_at_ms IS NOT NULL ORDER BY decided_at_ms DESC LIMIT ${DECIDED_REPLAY_SCAN_CAP}`), [sessionId, boundCallId]);
677
677
  return rows.map((r) => {
@@ -733,14 +733,14 @@ export class SqlCheckpointStore {
733
733
  }
734
734
  }
735
735
  async getCtx(sessionId) {
736
- const { rows } = await this.db.query(this.q(`SELECT ${jsonColumnText("tidb", "ctx")} FROM checkpoint_ctx WHERE session_id=?`, `SELECT ${jsonColumnText("pg", "ctx")} FROM checkpoint_ctx WHERE session_id=$1`), [sessionId]);
736
+ const { rows } = await this.db.query(this.q(`SELECT ${jsonColumnText("mysql", "ctx")} FROM checkpoint_ctx WHERE session_id=?`, `SELECT ${jsonColumnText("pg", "ctx")} FROM checkpoint_ctx WHERE session_id=$1`), [sessionId]);
737
737
  return rows[0] ? refusing("a resume context nobody can read", () => decodeCtxColumn(rows[0].ctx, `for session ${JSON.stringify(sessionId)}`)) : null;
738
738
  }
739
739
  async rewriteCtxRows(rewrite) {
740
740
  const out = { scanned: 0, rewritten: 0, valuesRewritten: 0, unreadable: 0, tooLarge: 0 };
741
741
  let after = "";
742
742
  for (;;) {
743
- const { rows } = await this.db.query(this.q(`SELECT session_id, ${jsonColumnText("tidb", "ctx")} FROM checkpoint_ctx WHERE session_id > ? ORDER BY session_id LIMIT ${CTX_REWRITE_PAGE}`, `SELECT session_id, ${jsonColumnText("pg", "ctx")} FROM checkpoint_ctx WHERE session_id > $1 ORDER BY session_id LIMIT ${CTX_REWRITE_PAGE}`), [after]);
743
+ const { rows } = await this.db.query(this.q(`SELECT session_id, ${jsonColumnText("mysql", "ctx")} FROM checkpoint_ctx WHERE session_id > ? ORDER BY session_id LIMIT ${CTX_REWRITE_PAGE}`, `SELECT session_id, ${jsonColumnText("pg", "ctx")} FROM checkpoint_ctx WHERE session_id > $1 ORDER BY session_id LIMIT ${CTX_REWRITE_PAGE}`), [after]);
744
744
  for (const row of rows) {
745
745
  const sessionId = String(row.session_id);
746
746
  after = sessionId;
@@ -789,7 +789,7 @@ export class SqlCheckpointStore {
789
789
  }
790
790
  async deleteBySession(sessionId, owner) {
791
791
  const ownerGuard = this.q("EXISTS (SELECT 1 FROM session_meta sm WHERE sm.session_id = ? AND sm.owner <=> ?)", "EXISTS (SELECT 1 FROM session_meta sm WHERE sm.session_id = $1 AND sm.owner IS NOT DISTINCT FROM $2)");
792
- const params = this.db.dialect === "tidb" ? [sessionId, sessionId, owner] : [sessionId, owner];
792
+ const params = this.db.dialect === "mysql" ? [sessionId, sessionId, owner] : [sessionId, owner];
793
793
  const res = await this.db.query(this.q(`DELETE FROM checkpoint WHERE session_id = ? AND ${ownerGuard}`, `DELETE FROM checkpoint WHERE session_id = $1 AND ${ownerGuard}`), params);
794
794
  await this.db.query(this.q(`DELETE FROM checkpoint_ctx WHERE session_id = ? AND ${ownerGuard}`, `DELETE FROM checkpoint_ctx WHERE session_id = $1 AND ${ownerGuard}`), params);
795
795
  return res.affected;
@@ -140,7 +140,7 @@ export async function assertDeviceAuditRebindEventSchema(db) {
140
140
  try {
141
141
  await conn.begin();
142
142
  try {
143
- await conn.query(db.dialect === "tidb"
143
+ await conn.query(db.dialect === "mysql"
144
144
  ? `INSERT INTO ${DEVICE_AUDIT_TABLE} (at, event, device_id, owner_tenant, owner_subject, detail) VALUES (NOW(3), ?, NULL, NULL, NULL, NULL)`
145
145
  : `INSERT INTO ${DEVICE_AUDIT_TABLE} (at, event, device_id, owner_tenant, owner_subject, detail) VALUES (now(), $1, NULL, NULL, NULL, NULL)`, ["session_rebound"]);
146
146
  }
@@ -168,9 +168,9 @@ export async function assertDeviceAuditRebindEventSchema(db) {
168
168
  conn.release();
169
169
  }
170
170
  }
171
- const ms = (dialect, col, alias) => dialect === "tidb" ? `ROUND(UNIX_TIMESTAMP(${col}) * 1000) AS ${alias}` : `(EXTRACT(EPOCH FROM ${col}) * 1000)::bigint AS ${alias}`;
172
- const NOW = (dialect) => (dialect === "tidb" ? "NOW(3)" : "now()");
173
- const nowPlusSeconds = (dialect, placeholder) => dialect === "tidb" ? `NOW(3) + INTERVAL ${placeholder} SECOND` : `now() + (${placeholder}::double precision * INTERVAL '1 second')`;
171
+ const ms = (dialect, col, alias) => dialect === "mysql" ? `ROUND(UNIX_TIMESTAMP(${col}) * 1000) AS ${alias}` : `(EXTRACT(EPOCH FROM ${col}) * 1000)::bigint AS ${alias}`;
172
+ const NOW = (dialect) => (dialect === "mysql" ? "NOW(3)" : "now()");
173
+ const nowPlusSeconds = (dialect, placeholder) => dialect === "mysql" ? `NOW(3) + INTERVAL ${placeholder} SECOND` : `now() + (${placeholder}::double precision * INTERVAL '1 second')`;
174
174
  function deviceCols(dialect) {
175
175
  return [
176
176
  "device_id",
@@ -286,10 +286,10 @@ function readAuditDetail(raw, id) {
286
286
  }
287
287
  }
288
288
  function ph(dialect, n) {
289
- return dialect === "tidb" ? "?" : `$${n}`;
289
+ return dialect === "mysql" ? "?" : `$${n}`;
290
290
  }
291
291
  function dupKeyName(dialect, err) {
292
- if (dialect === "tidb") {
292
+ if (dialect === "mysql") {
293
293
  const msg = String(err?.sqlMessage ?? err?.message ?? "");
294
294
  if (new RegExp(UQ_DEVICES_PUBKEY, "i").test(msg))
295
295
  return "pubkey";
@@ -309,8 +309,8 @@ export class SqlDeviceStore {
309
309
  constructor(db) {
310
310
  this.db = db;
311
311
  }
312
- q(tidb, pg) {
313
- return this.db.dialect === "tidb" ? tidb : pg;
312
+ q(mysql, pg) {
313
+ return this.db.dialect === "mysql" ? mysql : pg;
314
314
  }
315
315
  json(value) {
316
316
  return dialectJsonEncoder(this.db.dialect)(value);
@@ -319,7 +319,7 @@ export class SqlDeviceStore {
319
319
  assertIssueTokenShape(input);
320
320
  try {
321
321
  await this.db.query(this.q(`INSERT INTO ${DEVICE_ENROLL_TOKENS_TABLE} (token_hash, target_tenant, target_subject, created_by, created_at, expires_at, consumed_at, consumed_device_id, consumed_pubkey, rev)
322
- VALUES (?, ?, ?, ?, NOW(3), ${nowPlusSeconds("tidb", "?")}, NULL, NULL, NULL, 0)`, `INSERT INTO ${DEVICE_ENROLL_TOKENS_TABLE} (token_hash, target_tenant, target_subject, created_by, created_at, expires_at, consumed_at, consumed_device_id, consumed_pubkey, rev)
322
+ VALUES (?, ?, ?, ?, NOW(3), ${nowPlusSeconds("mysql", "?")}, NULL, NULL, NULL, 0)`, `INSERT INTO ${DEVICE_ENROLL_TOKENS_TABLE} (token_hash, target_tenant, target_subject, created_by, created_at, expires_at, consumed_at, consumed_device_id, consumed_pubkey, rev)
323
323
  VALUES ($1, $2, $3, $4, now(), ${nowPlusSeconds("pg", "$5")}, NULL, NULL, NULL, 0)`), [input.tokenHash, input.target.tenant, input.target.subject, input.createdBy, input.ttlSeconds]);
324
324
  }
325
325
  catch (err) {
@@ -334,7 +334,7 @@ export class SqlDeviceStore {
334
334
  }
335
335
  async getEnrollToken(tokenHash) {
336
336
  assertEnrollTokenHashShape(tokenHash);
337
- const { rows } = await this.db.query(this.q(`SELECT ${tokenCols("tidb")} FROM ${DEVICE_ENROLL_TOKENS_TABLE} WHERE token_hash = ?`, `SELECT ${tokenCols("pg")} FROM ${DEVICE_ENROLL_TOKENS_TABLE} WHERE token_hash = $1`), [tokenHash]);
337
+ const { rows } = await this.db.query(this.q(`SELECT ${tokenCols("mysql")} FROM ${DEVICE_ENROLL_TOKENS_TABLE} WHERE token_hash = ?`, `SELECT ${tokenCols("pg")} FROM ${DEVICE_ENROLL_TOKENS_TABLE} WHERE token_hash = $1`), [tokenHash]);
338
338
  return rows[0] ? mapTokenRow(rows[0]) : null;
339
339
  }
340
340
  async consumeEnrollToken(input) {
@@ -382,7 +382,7 @@ export class SqlDeviceStore {
382
382
  return { outcome: "enrolled", device };
383
383
  }
384
384
  await conn.rollback();
385
- const { rows } = await conn.query(this.q(`SELECT ${tokenCols("tidb")} FROM ${DEVICE_ENROLL_TOKENS_TABLE} WHERE token_hash = ?`, `SELECT ${tokenCols("pg")} FROM ${DEVICE_ENROLL_TOKENS_TABLE} WHERE token_hash = $1`), [input.tokenHash]);
385
+ const { rows } = await conn.query(this.q(`SELECT ${tokenCols("mysql")} FROM ${DEVICE_ENROLL_TOKENS_TABLE} WHERE token_hash = ?`, `SELECT ${tokenCols("pg")} FROM ${DEVICE_ENROLL_TOKENS_TABLE} WHERE token_hash = $1`), [input.tokenHash]);
386
386
  const token = rows[0] ? mapTokenRow(rows[0]) : null;
387
387
  if (!token)
388
388
  return { outcome: "unknown_token" };
@@ -405,28 +405,28 @@ export class SqlDeviceStore {
405
405
  }
406
406
  }
407
407
  async readDeviceOn(conn, deviceId) {
408
- const { rows } = await conn.query(this.q(`SELECT ${deviceCols("tidb")} FROM ${DEVICES_TABLE} WHERE device_id = ?`, `SELECT ${deviceCols("pg")} FROM ${DEVICES_TABLE} WHERE device_id = $1`), [deviceId]);
408
+ const { rows } = await conn.query(this.q(`SELECT ${deviceCols("mysql")} FROM ${DEVICES_TABLE} WHERE device_id = ?`, `SELECT ${deviceCols("pg")} FROM ${DEVICES_TABLE} WHERE device_id = $1`), [deviceId]);
409
409
  return rows[0] ? mapDeviceRow(rows[0]) : null;
410
410
  }
411
411
  async readDeviceForAdmission(deviceId, owner) {
412
412
  assertDeviceIdShape(deviceId);
413
413
  assertDeviceOwnerShape(owner);
414
- const { rows } = await this.db.query(this.q(`SELECT ${deviceCols("tidb")}, ${onlineCol("tidb")} FROM ${DEVICES_TABLE} WHERE device_id = ? AND owner_tenant = ? AND owner_subject = ?`, `SELECT ${deviceCols("pg")}, ${onlineCol("pg")} FROM ${DEVICES_TABLE} WHERE device_id = $1 AND owner_tenant = $2 AND owner_subject = $3`), [deviceId, owner.tenant, owner.subject]);
414
+ const { rows } = await this.db.query(this.q(`SELECT ${deviceCols("mysql")}, ${onlineCol("mysql")} FROM ${DEVICES_TABLE} WHERE device_id = ? AND owner_tenant = ? AND owner_subject = ?`, `SELECT ${deviceCols("pg")}, ${onlineCol("pg")} FROM ${DEVICES_TABLE} WHERE device_id = $1 AND owner_tenant = $2 AND owner_subject = $3`), [deviceId, owner.tenant, owner.subject]);
415
415
  const r = rows[0];
416
416
  return r ? { row: mapDeviceRow(r), online: Number(r.online) === 1 } : null;
417
417
  }
418
418
  async getDeviceUnscoped(deviceId) {
419
419
  assertDeviceIdShape(deviceId);
420
- const { rows } = await this.db.query(this.q(`SELECT ${deviceCols("tidb")} FROM ${DEVICES_TABLE} WHERE device_id = ?`, `SELECT ${deviceCols("pg")} FROM ${DEVICES_TABLE} WHERE device_id = $1`), [deviceId]);
420
+ const { rows } = await this.db.query(this.q(`SELECT ${deviceCols("mysql")} FROM ${DEVICES_TABLE} WHERE device_id = ?`, `SELECT ${deviceCols("pg")} FROM ${DEVICES_TABLE} WHERE device_id = $1`), [deviceId]);
421
421
  return rows[0] ? mapDeviceRow(rows[0]) : null;
422
422
  }
423
423
  async listDevicesByOwner(owner) {
424
424
  assertDeviceOwnerShape(owner);
425
- const { rows } = await this.db.query(this.q(`SELECT ${deviceCols("tidb")} FROM ${DEVICES_TABLE} WHERE owner_tenant = ? AND owner_subject = ? ORDER BY device_id ASC`, `SELECT ${deviceCols("pg")} FROM ${DEVICES_TABLE} WHERE owner_tenant = $1 AND owner_subject = $2 ORDER BY device_id ASC`), [owner.tenant, owner.subject]);
425
+ const { rows } = await this.db.query(this.q(`SELECT ${deviceCols("mysql")} FROM ${DEVICES_TABLE} WHERE owner_tenant = ? AND owner_subject = ? ORDER BY device_id ASC`, `SELECT ${deviceCols("pg")} FROM ${DEVICES_TABLE} WHERE owner_tenant = $1 AND owner_subject = $2 ORDER BY device_id ASC`), [owner.tenant, owner.subject]);
426
426
  return rows.map(mapDeviceRow);
427
427
  }
428
428
  async listDevicesUnscoped() {
429
- const { rows } = await this.db.query(this.q(`SELECT ${deviceCols("tidb")} FROM ${DEVICES_TABLE} ORDER BY device_id ASC`, `SELECT ${deviceCols("pg")} FROM ${DEVICES_TABLE} ORDER BY device_id ASC`));
429
+ const { rows } = await this.db.query(this.q(`SELECT ${deviceCols("mysql")} FROM ${DEVICES_TABLE} ORDER BY device_id ASC`, `SELECT ${deviceCols("pg")} FROM ${DEVICES_TABLE} ORDER BY device_id ASC`));
430
430
  return rows.map(mapDeviceRow);
431
431
  }
432
432
  async revokeDevice(input) {
@@ -446,7 +446,7 @@ export class SqlDeviceStore {
446
446
  return { outcome: "revoked", row };
447
447
  }
448
448
  await conn.rollback();
449
- const { rows } = await conn.query(this.q(`SELECT ${deviceCols("tidb")} FROM ${DEVICES_TABLE} WHERE device_id = ? AND owner_tenant = ? AND owner_subject = ?`, `SELECT ${deviceCols("pg")} FROM ${DEVICES_TABLE} WHERE device_id = $1 AND owner_tenant = $2 AND owner_subject = $3`), [input.deviceId, input.owner.tenant, input.owner.subject]);
449
+ const { rows } = await conn.query(this.q(`SELECT ${deviceCols("mysql")} FROM ${DEVICES_TABLE} WHERE device_id = ? AND owner_tenant = ? AND owner_subject = ?`, `SELECT ${deviceCols("pg")} FROM ${DEVICES_TABLE} WHERE device_id = $1 AND owner_tenant = $2 AND owner_subject = $3`), [input.deviceId, input.owner.tenant, input.owner.subject]);
450
450
  if (!rows[0])
451
451
  return { outcome: "not_found" };
452
452
  return { outcome: "already_revoked", row: mapDeviceRow(rows[0]) };
@@ -464,7 +464,7 @@ export class SqlDeviceStore {
464
464
  const conn = await this.db.connect();
465
465
  try {
466
466
  await conn.begin();
467
- const cas = await conn.query(this.q(`UPDATE ${DEVICES_TABLE} SET conn_generation = conn_generation + 1, conn_epoch = ?, replica_id = ?, lease_expires_at = ${nowPlusSeconds("tidb", "?")}, connected_at = NOW(3), last_seen_at = NOW(3), rev = rev + 1
467
+ const cas = await conn.query(this.q(`UPDATE ${DEVICES_TABLE} SET conn_generation = conn_generation + 1, conn_epoch = ?, replica_id = ?, lease_expires_at = ${nowPlusSeconds("mysql", "?")}, connected_at = NOW(3), last_seen_at = NOW(3), rev = rev + 1
468
468
  WHERE device_id = ? AND owner_tenant = ? AND owner_subject = ? AND status = 'active' AND (lease_expires_at IS NULL OR lease_expires_at <= NOW(3))`, `UPDATE ${DEVICES_TABLE} SET conn_generation = conn_generation + 1, conn_epoch = $1, replica_id = $2, lease_expires_at = ${nowPlusSeconds("pg", "$3")}, connected_at = now(), last_seen_at = now(), rev = rev + 1
469
469
  WHERE device_id = $4 AND owner_tenant = $5 AND owner_subject = $6 AND status = 'active' AND (lease_expires_at IS NULL OR lease_expires_at <= now())`), [input.connEpoch, input.replicaId, input.leaseSeconds, input.deviceId, input.owner.tenant, input.owner.subject]);
470
470
  const { rows } = await conn.query(this.q(`SELECT conn_generation, status FROM ${DEVICES_TABLE} WHERE device_id = ? AND owner_tenant = ? AND owner_subject = ? FOR UPDATE`, `SELECT conn_generation, status FROM ${DEVICES_TABLE} WHERE device_id = $1 AND owner_tenant = $2 AND owner_subject = $3 FOR UPDATE`), [input.deviceId, input.owner.tenant, input.owner.subject]);
@@ -488,7 +488,7 @@ export class SqlDeviceStore {
488
488
  async heartbeatConnection(input) {
489
489
  assertDeviceIdShape(input.deviceId);
490
490
  assertWholeSeconds("leaseSeconds", input.leaseSeconds);
491
- const res = await this.db.query(this.q(`UPDATE ${DEVICES_TABLE} SET last_seen_at = NOW(3), lease_expires_at = ${nowPlusSeconds("tidb", "?")}, rev = rev + 1 WHERE device_id = ? AND conn_generation = ? AND status = 'active'`, `UPDATE ${DEVICES_TABLE} SET last_seen_at = now(), lease_expires_at = ${nowPlusSeconds("pg", "$1")}, rev = rev + 1 WHERE device_id = $2 AND conn_generation = $3 AND status = 'active'`), [input.leaseSeconds, input.deviceId, input.generation]);
491
+ const res = await this.db.query(this.q(`UPDATE ${DEVICES_TABLE} SET last_seen_at = NOW(3), lease_expires_at = ${nowPlusSeconds("mysql", "?")}, rev = rev + 1 WHERE device_id = ? AND conn_generation = ? AND status = 'active'`, `UPDATE ${DEVICES_TABLE} SET last_seen_at = now(), lease_expires_at = ${nowPlusSeconds("pg", "$1")}, rev = rev + 1 WHERE device_id = $2 AND conn_generation = $3 AND status = 'active'`), [input.leaseSeconds, input.deviceId, input.generation]);
492
492
  return res.affected === 1;
493
493
  }
494
494
  async releaseConnection(deviceId, generation) {
@@ -1,5 +1,4 @@
1
- /** 本原语认得的两种方言(闭集;新方言进来是编译期的事,不是运行期的 `default` 臂)。 */
2
- export type SqlDialect = "mysql" | "pg";
1
+ import type { SqlDialect } from "./sql-driver.js";
3
2
  /**
4
3
  * 一条索引的**声明**(纯数据)。两方言共用同一份声明 —— 这就是"一处属主"的兑现物:
5
4
  * per-store 文件各导出自己那份 `readonly IndexSpec[]`,PG 侧由该 store 的 `ensurePg*Schema` 应用,
@@ -35,35 +35,35 @@ export interface PlacementStatement {
35
35
  */
36
36
  export declare const SESSION_META_PLACEMENT_COLUMNS: readonly [{
37
37
  readonly name: "execution_role";
38
- readonly tidb: "execution_role VARCHAR(16) NULL";
38
+ readonly mysql: "execution_role VARCHAR(16) NULL";
39
39
  readonly pg: "execution_role VARCHAR(16) COLLATE \"C\"";
40
40
  }, {
41
41
  readonly name: "execution_lane";
42
- readonly tidb: "execution_lane VARCHAR(32) NULL";
42
+ readonly mysql: "execution_lane VARCHAR(32) NULL";
43
43
  readonly pg: "execution_lane VARCHAR(32) COLLATE \"C\"";
44
44
  }, {
45
45
  readonly name: "execution_device_id";
46
- readonly tidb: "execution_device_id VARCHAR(64) NULL";
46
+ readonly mysql: "execution_device_id VARCHAR(64) NULL";
47
47
  readonly pg: "execution_device_id VARCHAR(64) COLLATE \"C\"";
48
48
  }, {
49
49
  readonly name: "execution_device_owner_tenant";
50
- readonly tidb: "execution_device_owner_tenant VARCHAR(190) NULL";
50
+ readonly mysql: "execution_device_owner_tenant VARCHAR(190) NULL";
51
51
  readonly pg: "execution_device_owner_tenant VARCHAR(190) COLLATE \"C\"";
52
52
  }, {
53
53
  readonly name: "execution_device_owner_subject";
54
- readonly tidb: "execution_device_owner_subject VARCHAR(190) NULL";
54
+ readonly mysql: "execution_device_owner_subject VARCHAR(190) NULL";
55
55
  readonly pg: "execution_device_owner_subject VARCHAR(190) COLLATE \"C\"";
56
56
  }, {
57
57
  readonly name: "execution_placed_at";
58
- readonly tidb: "execution_placed_at DATETIME(3) NULL";
58
+ readonly mysql: "execution_placed_at DATETIME(3) NULL";
59
59
  readonly pg: "execution_placed_at TIMESTAMPTZ(3)";
60
60
  }, {
61
61
  readonly name: "execution_rev";
62
- readonly tidb: "execution_rev BIGINT NULL";
62
+ readonly mysql: "execution_rev BIGINT NULL";
63
63
  readonly pg: "execution_rev BIGINT";
64
64
  }, {
65
65
  readonly name: "fork_key";
66
- readonly tidb: "fork_key VARCHAR(255) NULL";
66
+ readonly mysql: "fork_key VARCHAR(255) NULL";
67
67
  readonly pg: "fork_key VARCHAR(255) COLLATE \"C\"";
68
68
  }];
69
69
  /** 中央 DDL 内插的那一段(列与列之间逗号分隔,不带首尾逗号)。 */
@@ -3,14 +3,14 @@ import { sessionFaceFromRow } from "../session-incarnation.js";
3
3
  import { toIso } from "./sql-row-helpers.js";
4
4
  import { WRITABLE, assertPlaceableLane, settledMirrorOutcome, settledPlaceOutcome, } from "../execution-placement.js";
5
5
  export const SESSION_META_PLACEMENT_COLUMNS = [
6
- { name: "execution_role", tidb: "execution_role VARCHAR(16) NULL", pg: `execution_role VARCHAR(16) COLLATE "C"` },
7
- { name: "execution_lane", tidb: "execution_lane VARCHAR(32) NULL", pg: `execution_lane VARCHAR(32) COLLATE "C"` },
8
- { name: "execution_device_id", tidb: "execution_device_id VARCHAR(64) NULL", pg: `execution_device_id VARCHAR(64) COLLATE "C"` },
9
- { name: "execution_device_owner_tenant", tidb: "execution_device_owner_tenant VARCHAR(190) NULL", pg: `execution_device_owner_tenant VARCHAR(190) COLLATE "C"` },
10
- { name: "execution_device_owner_subject", tidb: "execution_device_owner_subject VARCHAR(190) NULL", pg: `execution_device_owner_subject VARCHAR(190) COLLATE "C"` },
11
- { name: "execution_placed_at", tidb: "execution_placed_at DATETIME(3) NULL", pg: "execution_placed_at TIMESTAMPTZ(3)" },
12
- { name: "execution_rev", tidb: "execution_rev BIGINT NULL", pg: "execution_rev BIGINT" },
13
- { name: "fork_key", tidb: "fork_key VARCHAR(255) NULL", pg: `fork_key VARCHAR(255) COLLATE "C"` },
6
+ { name: "execution_role", mysql: "execution_role VARCHAR(16) NULL", pg: `execution_role VARCHAR(16) COLLATE "C"` },
7
+ { name: "execution_lane", mysql: "execution_lane VARCHAR(32) NULL", pg: `execution_lane VARCHAR(32) COLLATE "C"` },
8
+ { name: "execution_device_id", mysql: "execution_device_id VARCHAR(64) NULL", pg: `execution_device_id VARCHAR(64) COLLATE "C"` },
9
+ { name: "execution_device_owner_tenant", mysql: "execution_device_owner_tenant VARCHAR(190) NULL", pg: `execution_device_owner_tenant VARCHAR(190) COLLATE "C"` },
10
+ { name: "execution_device_owner_subject", mysql: "execution_device_owner_subject VARCHAR(190) NULL", pg: `execution_device_owner_subject VARCHAR(190) COLLATE "C"` },
11
+ { name: "execution_placed_at", mysql: "execution_placed_at DATETIME(3) NULL", pg: "execution_placed_at TIMESTAMPTZ(3)" },
12
+ { name: "execution_rev", mysql: "execution_rev BIGINT NULL", pg: "execution_rev BIGINT" },
13
+ { name: "fork_key", mysql: "fork_key VARCHAR(255) NULL", pg: `fork_key VARCHAR(255) COLLATE "C"` },
14
14
  ];
15
15
  export function sessionMetaPlacementColumnsDdl(dialect) {
16
16
  return SESSION_META_PLACEMENT_COLUMNS.map((c) => c[dialect]).join(",\n ");
@@ -3,7 +3,7 @@ import type { Pool as PgPool } from "pg";
3
3
  import { type FileHistoryRetentionPolicy, type ExecutionEnv, type FileHistoryStore, type FileHistoryResult, type FileHistoryTrackResult, type FileHistoryRestoreResult, type FileHistoryExport, type FileHistoryExportResult } from "@sema-agent/core";
4
4
  import { type BlobBackend } from "./blob-backend.js";
5
5
  import type { SyncBlobPutResult } from "./store-backend.js";
6
- import { type SqlDriver } from "./sql-driver.js";
6
+ import { type SqlDriver, type SqlDialect } from "./sql-driver.js";
7
7
  /** The file-history blob domain's SQL table (BlobBackend `table`/MinIO index binding + the A7 assert). */
8
8
  export declare const FILE_HISTORY_BLOB_TABLE = "file_history_blob";
9
9
  /** MinIO object-key prefix for this domain (snapshot epoch used "blobs/"; a separate prefix keeps the
@@ -196,5 +196,5 @@ export declare class PgFileHistoryStore extends SqlFileHistoryStore {
196
196
  */
197
197
  export declare function assertFileHistorySchema(query: (sql: string) => Promise<{
198
198
  rows: Record<string, unknown>[];
199
- }>, dialect: "tidb" | "pg"): Promise<void>;
199
+ }>, dialect: SqlDialect): Promise<void>;
200
200
  //# sourceMappingURL=file-history-store-sql.d.ts.map
@@ -33,13 +33,13 @@ export class SqlFileHistoryStore {
33
33
  this.db = db;
34
34
  this.pool = pool;
35
35
  this.blobs = blobBackend ?? new SqlBlobBackend(this.db.dialect, this.pool, undefined, FILE_HISTORY_BLOB_TABLE);
36
- this.boundaryKeep = resolveFileHistoryRetention(this.db.dialect === "tidb" ? "TiDBFileHistoryStore" : "PgFileHistoryStore", opts?.retention);
36
+ this.boundaryKeep = resolveFileHistoryRetention(this.db.dialect === "mysql" ? "TiDBFileHistoryStore" : "PgFileHistoryStore", opts?.retention);
37
37
  }
38
- q(tidb, pg) {
39
- return this.db.dialect === "tidb" ? tidb : pg;
38
+ q(mysql, pg) {
39
+ return this.db.dialect === "mysql" ? mysql : pg;
40
40
  }
41
41
  bool(v) {
42
- return this.db.dialect === "tidb" ? (v ? 1 : 0) : v;
42
+ return this.db.dialect === "mysql" ? (v ? 1 : 0) : v;
43
43
  }
44
44
  leaseKey(scope, entryId) {
45
45
  return `${scope}\x00${entryId}`;
@@ -145,7 +145,7 @@ export async function ensurePgImageBakeSchema(pool, poolName = "standard") {
145
145
  }
146
146
  const isDupKey = isDupKeyError;
147
147
  function dupKeyName(dialect, err) {
148
- if (dialect === "tidb") {
148
+ if (dialect === "mysql") {
149
149
  const msg = String(err?.sqlMessage ?? err?.message ?? "");
150
150
  if (/uq_image_bake_event_line/i.test(msg))
151
151
  return "uq_line";
@@ -169,8 +169,8 @@ export class SqlImageBake {
169
169
  this.db = db;
170
170
  this.poolName = poolName;
171
171
  }
172
- q(tidb, pg) {
173
- return this.db.dialect === "tidb" ? tidb : pg;
172
+ q(mysql, pg) {
173
+ return this.db.dialect === "mysql" ? mysql : pg;
174
174
  }
175
175
  insertParams(bakeId, input, now) {
176
176
  return [
@@ -214,7 +214,7 @@ export class SqlImageBake {
214
214
  const conn = await this.db.connect();
215
215
  let inserted = false;
216
216
  try {
217
- if (this.db.dialect === "tidb") {
217
+ if (this.db.dialect === "mysql") {
218
218
  await conn.begin();
219
219
  await conn.query("INSERT INTO image_bake_admit (pool) VALUES (?) ON DUPLICATE KEY UPDATE pool = pool", [this.poolName]);
220
220
  await conn.query("SELECT pool FROM image_bake_admit WHERE pool = ? FOR UPDATE", [this.poolName]);
@@ -255,15 +255,15 @@ export class SqlImageBake {
255
255
  return { created: true, bake };
256
256
  }
257
257
  async getBake(bakeId) {
258
- const { rows } = await this.db.query(this.q(`SELECT ${bakeSelectCols("tidb")} FROM image_bake WHERE bake_id = ? LIMIT 1`, `SELECT ${bakeSelectCols("pg")} FROM image_bake WHERE bake_id = $1 LIMIT 1`), [bakeId]);
258
+ const { rows } = await this.db.query(this.q(`SELECT ${bakeSelectCols("mysql")} FROM image_bake WHERE bake_id = ? LIMIT 1`, `SELECT ${bakeSelectCols("pg")} FROM image_bake WHERE bake_id = $1 LIMIT 1`), [bakeId]);
259
259
  return rows[0] ? refusingBakeRow(() => mapRow(rows[0])) : null;
260
260
  }
261
261
  async getBakeByIdem(idemKey) {
262
- const { rows } = await this.db.query(this.q(`SELECT ${bakeSelectCols("tidb")} FROM image_bake WHERE idem_key = ? LIMIT 1`, `SELECT ${bakeSelectCols("pg")} FROM image_bake WHERE idem_key = $1 LIMIT 1`), [idemKey]);
262
+ const { rows } = await this.db.query(this.q(`SELECT ${bakeSelectCols("mysql")} FROM image_bake WHERE idem_key = ? LIMIT 1`, `SELECT ${bakeSelectCols("pg")} FROM image_bake WHERE idem_key = $1 LIMIT 1`), [idemKey]);
263
263
  return rows[0] ? refusingBakeRow(() => mapRow(rows[0])) : null;
264
264
  }
265
265
  async findActiveByArgv(argv) {
266
- const { rows } = await this.db.query(this.q(`SELECT ${bakeSelectCols("tidb")} FROM image_bake WHERE status IN ('queued','running') AND argv = CAST(? AS JSON) ` +
266
+ const { rows } = await this.db.query(this.q(`SELECT ${bakeSelectCols("mysql")} FROM image_bake WHERE status IN ('queued','running') AND argv = CAST(? AS JSON) ` +
267
267
  "ORDER BY created_at DESC LIMIT 1", `SELECT ${bakeSelectCols("pg")} FROM image_bake WHERE status IN ('queued','running') AND argv = $1::jsonb ` +
268
268
  "ORDER BY created_at DESC LIMIT 1"), [JSON.stringify(argv)]);
269
269
  return rows[0] ? refusingBakeRow(() => mapRow(rows[0])) : null;
@@ -380,7 +380,7 @@ export class SqlImageBake {
380
380
  return m == null ? 0 : Number(m);
381
381
  }
382
382
  async getEvents(bakeId, afterSeq) {
383
- const { rows } = await this.db.query(this.q(`SELECT seq, line_ord, kind, level, ${jsonColumnText("tidb", "data")}, ts FROM image_bake_event WHERE bake_id = ? AND seq > ? ORDER BY seq ASC`, `SELECT seq, line_ord, kind, level, ${jsonColumnText("pg", "data")}, ts FROM image_bake_event WHERE bake_id = $1 AND seq > $2 ORDER BY seq ASC`), [bakeId, afterSeq]);
383
+ const { rows } = await this.db.query(this.q(`SELECT seq, line_ord, kind, level, ${jsonColumnText("mysql", "data")}, ts FROM image_bake_event WHERE bake_id = ? AND seq > ? ORDER BY seq ASC`, `SELECT seq, line_ord, kind, level, ${jsonColumnText("pg", "data")}, ts FROM image_bake_event WHERE bake_id = $1 AND seq > $2 ORDER BY seq ASC`), [bakeId, afterSeq]);
384
384
  return rows.map((r) => ({
385
385
  seq: Number(r.seq),
386
386
  lineOrd: r.line_ord === null ? null : Number(r.line_ord),
@@ -401,7 +401,7 @@ export class SqlImageBake {
401
401
  await this.tx(async (conn) => {
402
402
  const res = await conn.query(this.q("UPDATE image_bake SET status=?, state=?, digest=?, repo=?, ref=?, index_id=?, exit_code=?, error=?, " +
403
403
  "error_code=?, manifest_sha=?, tag=?, ingest_secret=NULL, updated_at=? WHERE bake_id=? AND status IN ('queued','running')", "UPDATE image_bake SET status=$1, state=$2, digest=$3, repo=$4, ref=$5, index_id=$6, exit_code=$7, error=$8, " +
404
- "error_code=$9, manifest_sha=$10, tag=$11, ingest_secret=NULL, updated_at=$12 WHERE bake_id=$13 AND status IN ('queued','running')"), this.db.dialect === "tidb" ? this.terminalParamsTidb(bakeId, t) : this.terminalParamsPg(bakeId, t));
404
+ "error_code=$9, manifest_sha=$10, tag=$11, ingest_secret=NULL, updated_at=$12 WHERE bake_id=$13 AND status IN ('queued','running')"), this.db.dialect === "mysql" ? this.terminalParamsTidb(bakeId, t) : this.terminalParamsPg(bakeId, t));
405
405
  affectedRows = res.affected;
406
406
  await conn.query(this.q("DELETE FROM image_bake_lease WHERE pool = ? AND bake_id = ?", "DELETE FROM image_bake_lease WHERE pool = $1 AND bake_id = $2"), [this.poolName, bakeId]);
407
407
  });
@@ -181,8 +181,8 @@ export class SqlImageIndex {
181
181
  constructor(db) {
182
182
  this.db = db;
183
183
  }
184
- q(tidb, pg) {
185
- return this.db.dialect === "tidb" ? tidb : pg;
184
+ q(mysql, pg) {
185
+ return this.db.dialect === "mysql" ? mysql : pg;
186
186
  }
187
187
  static idFor(repo, digest) {
188
188
  return createHash("sha256").update(`${repo}@${digest}`).digest("hex").slice(0, 64);
@@ -216,7 +216,7 @@ export class SqlImageIndex {
216
216
  status = EXCLUDED.status, visibility = EXCLUDED.visibility, tenant_id = EXCLUDED.tenant_id,
217
217
  manifest_sha = EXCLUDED.manifest_sha, recipe_git_sha = EXCLUDED.recipe_git_sha,
218
218
  generator_version = EXCLUDED.generator_version, build_date = EXCLUDED.build_date,
219
- supersedes = EXCLUDED.supersedes, signed = EXCLUDED.signed, updated_at = EXCLUDED.updated_at`), this.db.dialect === "tidb" ? tidbUpsertParams(e, id, now) : pgUpsertParams(e, id, now));
219
+ supersedes = EXCLUDED.supersedes, signed = EXCLUDED.signed, updated_at = EXCLUDED.updated_at`), this.db.dialect === "mysql" ? tidbUpsertParams(e, id, now) : pgUpsertParams(e, id, now));
220
220
  return id;
221
221
  }
222
222
  async registerBuilding(e) {
@@ -258,21 +258,21 @@ export class SqlImageIndex {
258
258
  supersedes = EXCLUDED.supersedes,
259
259
  signed = CASE WHEN sandbox_image_index.status = 'published'
260
260
  THEN sandbox_image_index.signed ELSE EXCLUDED.signed END,
261
- updated_at = EXCLUDED.updated_at`), this.db.dialect === "tidb" ? tidbUpsertParams(e, id, now) : pgUpsertParams(e, id, now));
261
+ updated_at = EXCLUDED.updated_at`), this.db.dialect === "mysql" ? tidbUpsertParams(e, id, now) : pgUpsertParams(e, id, now));
262
262
  return id;
263
263
  }
264
264
  async getById(id) {
265
- const { rows } = await this.db.query(this.q(`SELECT ${imageSelectCols("tidb")} FROM sandbox_image_index WHERE id=? LIMIT 1`, `SELECT ${imageSelectCols("pg")} FROM sandbox_image_index WHERE id = $1 LIMIT 1`), [id]);
265
+ const { rows } = await this.db.query(this.q(`SELECT ${imageSelectCols("mysql")} FROM sandbox_image_index WHERE id=? LIMIT 1`, `SELECT ${imageSelectCols("pg")} FROM sandbox_image_index WHERE id = $1 LIMIT 1`), [id]);
266
266
  return rows[0] ? refusingImageRow(() => mapRow(rows[0])) : null;
267
267
  }
268
268
  async getByDigest(digest) {
269
- const { rows } = await this.db.query(this.q(`SELECT ${imageSelectCols("tidb")} FROM sandbox_image_index WHERE digest=? ORDER BY updated_at DESC LIMIT 1`, `SELECT ${imageSelectCols("pg")} FROM sandbox_image_index WHERE digest = $1 ORDER BY updated_at DESC LIMIT 1`), [digest]);
269
+ const { rows } = await this.db.query(this.q(`SELECT ${imageSelectCols("mysql")} FROM sandbox_image_index WHERE digest=? ORDER BY updated_at DESC LIMIT 1`, `SELECT ${imageSelectCols("pg")} FROM sandbox_image_index WHERE digest = $1 ORDER BY updated_at DESC LIMIT 1`), [digest]);
270
270
  return rows[0] ? refusingImageRow(() => mapRow(rows[0])) : null;
271
271
  }
272
272
  async latestPublished(profile, viewer) {
273
- if (this.db.dialect === "tidb") {
273
+ if (this.db.dialect === "mysql") {
274
274
  const vis = visibilityClauseTidb(viewer);
275
- const { rows } = await this.db.query(`SELECT ${imageSelectCols("tidb")} FROM sandbox_image_index
275
+ const { rows } = await this.db.query(`SELECT ${imageSelectCols("mysql")} FROM sandbox_image_index
276
276
  WHERE profile=? AND status='published' AND ${vis.sql}
277
277
  ORDER BY (build_date IS NULL), build_date DESC, created_at DESC LIMIT 1`, [profile, ...vis.params]);
278
278
  return rows[0] ? refusingImageRow(() => mapRow(rows[0])) : null;
@@ -286,7 +286,7 @@ export class SqlImageIndex {
286
286
  async list(filter) {
287
287
  const limit = Math.min(Math.max(1, filter.limit ?? DEFAULT_LIMIT), MAX_LIMIT);
288
288
  let rawRows;
289
- if (this.db.dialect === "tidb") {
289
+ if (this.db.dialect === "mysql") {
290
290
  const vis = visibilityClauseTidb(filter);
291
291
  const where = [vis.sql];
292
292
  const params = [...vis.params];
@@ -309,7 +309,7 @@ export class SqlImageIndex {
309
309
  params.push(new Date(c.createdAt), new Date(c.createdAt), c.id);
310
310
  }
311
311
  }
312
- const sql = `SELECT ${imageSelectCols("tidb")} FROM sandbox_image_index WHERE ${where.join(" AND ")} ` +
312
+ const sql = `SELECT ${imageSelectCols("mysql")} FROM sandbox_image_index WHERE ${where.join(" AND ")} ` +
313
313
  `ORDER BY created_at DESC, id DESC LIMIT ?`;
314
314
  const { rows } = await this.db.query(sql, [...params, limit + 1]);
315
315
  rawRows = rows;
@@ -359,7 +359,7 @@ export class SqlImageIndex {
359
359
  return { entries, nextCursor };
360
360
  }
361
361
  async setStatus(id, status, opts) {
362
- if (this.db.dialect === "tidb") {
362
+ if (this.db.dialect === "mysql") {
363
363
  const sets = ["status=?", "updated_at=?"];
364
364
  const params = [status, new Date()];
365
365
  if (opts && "supersedes" in opts) {
@@ -95,8 +95,8 @@ export class SqlLeaderRunStore {
95
95
  constructor(db) {
96
96
  this.db = db;
97
97
  }
98
- q(tidb, pg) {
99
- return this.db.dialect === "tidb" ? tidb : pg;
98
+ q(mysql, pg) {
99
+ return this.db.dialect === "mysql" ? mysql : pg;
100
100
  }
101
101
  async createRun(input) {
102
102
  const id = uuidv7();
@@ -120,12 +120,12 @@ export class SqlLeaderRunStore {
120
120
  return { created: true, run };
121
121
  }
122
122
  async getRun(id) {
123
- const res = await this.db.query(this.q(`SELECT ${selectCols("tidb")} FROM ${LEADER_RUN_TABLE} WHERE leader_run_id = ?`, `SELECT ${selectCols("pg")} FROM ${LEADER_RUN_TABLE} WHERE leader_run_id = $1`), [id]);
123
+ const res = await this.db.query(this.q(`SELECT ${selectCols("mysql")} FROM ${LEADER_RUN_TABLE} WHERE leader_run_id = ?`, `SELECT ${selectCols("pg")} FROM ${LEADER_RUN_TABLE} WHERE leader_run_id = $1`), [id]);
124
124
  const row = res.rows[0];
125
125
  return row ? mapRow(row) : undefined;
126
126
  }
127
127
  async getByIdem(idemKey) {
128
- const res = await this.db.query(this.q(`SELECT ${selectCols("tidb")} FROM ${LEADER_RUN_TABLE} WHERE idem_key = ?`, `SELECT ${selectCols("pg")} FROM ${LEADER_RUN_TABLE} WHERE idem_key = $1`), [idemKey]);
128
+ const res = await this.db.query(this.q(`SELECT ${selectCols("mysql")} FROM ${LEADER_RUN_TABLE} WHERE idem_key = ?`, `SELECT ${selectCols("pg")} FROM ${LEADER_RUN_TABLE} WHERE idem_key = $1`), [idemKey]);
129
129
  const row = res.rows[0];
130
130
  return row ? mapRow(row) : undefined;
131
131
  }
@@ -3,6 +3,7 @@ import type { Pool as PgPool } from "pg";
3
3
  import type { MailboxAckResult, MailboxAppendMessage, MailboxDecision, MailboxDecisionOutcome, MailboxLease, MailboxStore } from "@sema-agent/core";
4
4
  import { type IndexSpec } from "./ensure-index.js";
5
5
  import type { MailboxRecipientLifecycle, MailboxRecipientTombstone } from "./mailbox-recipient-lifecycle.js";
6
+ import type { SqlDialect } from "./sql-driver.js";
6
7
  export declare const MAILBOX_TABLE = "mailbox";
7
8
  export declare const MAILBOX_MSG_TABLE = "mailbox_message";
8
9
  /** [ref] 收件人墓碑表(预删除态的**唯一**真源;形与理由见 `mailbox-recipient-lifecycle.ts` 模块头)。
@@ -40,7 +41,7 @@ export declare function storedMailboxKeyless(scopeKey: unknown, handle: unknown)
40
41
  export declare const MAILBOX_KEYED_TABLES: readonly ["mailbox", "mailbox_message", "mailbox_tombstone"];
41
42
  export type MailboxKeyedTable = (typeof MAILBOX_KEYED_TABLES)[number];
42
43
  /** 按键删收件箱表族的一张表(两方言;参数 = [scope_key, handle])。 */
43
- export declare function mailboxKeyDeleteSql(dialect: "tidb" | "pg", table: MailboxKeyedTable): string;
44
+ export declare function mailboxKeyDeleteSql(dialect: SqlDialect, table: MailboxKeyedTable): string;
44
45
  /** 店侧日志座(可选;boot 注入 `Logger`)。7.58.0 合并重扫 [medium]:坏行的 fail-closed 抛必须**响亮**——core 唯一的
45
46
  * claimLease 调用方(peer-session-drain)吞掉该错,店不记这一笔就成了「静默永久卡箱」。抛之前记
46
47
  * `mailbox_message_column_corrupt`(scope/handle/seq/column/code),运维按 seq 修行。