@sema-agent/server 4.2.0 → 5.0.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/USAGE.md +5 -3
- package/dist/approval-hmac.js +1 -1
- package/dist/approval.d.ts +5 -37
- package/dist/approval.js +12 -112
- package/dist/auth-bridge.d.ts +0 -1
- package/dist/auth-bridge.js +0 -1
- package/dist/auth-keys.d.ts +1 -1
- package/dist/auth-keys.js +1 -1
- package/dist/bench/s1/run-firm.js +1 -1
- package/dist/boot/config-center.d.ts +1 -1
- package/dist/boot/config-center.js +3 -2
- package/dist/boot/execution-env.js +8 -1
- package/dist/boot/reapers.d.ts +1 -2
- package/dist/boot/reapers.js +4 -5
- package/dist/boot/resolve-spec.d.ts +1 -3
- package/dist/boot/resolve-spec.js +21 -35
- package/dist/boot/stores.js +1 -1
- package/dist/brain.js +3 -1
- package/dist/capabilities/center-prompts.d.ts +2 -3
- package/dist/capabilities/center-prompts.js +2 -3
- package/dist/capabilities/sandbox-file-send.d.ts +0 -2
- package/dist/capabilities/sandbox-file-send.js +2 -5
- package/dist/capabilities/scenarios.d.ts +0 -9
- package/dist/capabilities/scenarios.js +1 -20
- package/dist/capabilities/send-user-file-tool.js +3 -3
- package/dist/config-center/apply-effective.js +8 -8
- package/dist/config-center/types.d.ts +10 -3
- package/dist/config-provider.js +6 -11
- package/dist/config-types.d.ts +12 -26
- package/dist/config.js +95 -68
- package/dist/fleet/fleet-bus.js +25 -33
- package/dist/fleet-client.js +1 -1
- package/dist/http/active-run-conflict.d.ts +2 -0
- package/dist/http/active-run-conflict.js +1 -0
- package/dist/http/routes/approvals-assistant.d.ts +2 -1
- package/dist/http/routes/approvals-assistant.js +10 -96
- package/dist/http/routes/capabilities.js +6 -5
- package/dist/http/routes/fleet.js +4 -1
- package/dist/http/routes/images.js +10 -4
- package/dist/http/routes/runs.js +34 -49
- package/dist/http/routes/session-sync.d.ts +1 -1
- package/dist/http/routes/session-sync.js +2 -1
- package/dist/http/routes/tasks.js +7 -7
- package/dist/http/routes/trace-usage.js +1 -1
- package/dist/http/server.d.ts +18 -7
- package/dist/http/server.js +25 -14
- package/dist/http/verify-rounds.d.ts +2 -2
- package/dist/http/wire-types.d.ts +1 -1
- package/dist/images/bake-validate.d.ts +0 -22
- package/dist/images/bake-validate.js +0 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +2 -5
- package/dist/lsp/e2b-bridge.d.ts +36 -3
- package/dist/lsp/e2b-bridge.js +94 -7
- package/dist/lsp/e2b-manager.d.ts +64 -1
- package/dist/lsp/e2b-manager.js +197 -28
- package/dist/lsp/manager.d.ts +71 -4
- package/dist/lsp/manager.js +149 -29
- package/dist/lsp/ws-transport.d.ts +1 -1
- package/dist/lsp/ws-transport.js +4 -1
- package/dist/main.js +5 -9
- package/dist/memory-scope.js +2 -2
- package/dist/observability/metrics.js +6 -0
- package/dist/orchestration/workflow-completion-inbox.d.ts +6 -4
- package/dist/orchestration/workflow-completion-inbox.js +6 -4
- package/dist/plugins/breaker-state-sql.d.ts +2 -3
- package/dist/plugins/image-index-sql.d.ts +0 -1
- package/dist/plugins/image-index-sql.js +0 -1
- package/dist/plugins/local-checkpoint-store.d.ts +1 -1
- package/dist/plugins/local-checkpoint-store.js +1 -1
- package/dist/plugins/memory-engine-pg.js +2 -1
- package/dist/plugins/memory-engine-tidb.js +1 -1
- package/dist/plugins/memory-engine-vector-util.d.ts +2 -3
- package/dist/plugins/memory-engine-vector-util.js +2 -3
- package/dist/plugins/memory-run-store.d.ts +1 -1
- package/dist/plugins/memory-session-policy-store.d.ts +1 -1
- package/dist/plugins/memory-session-policy-store.js +1 -1
- package/dist/plugins/memory-sync-store-pg.js +1 -1
- package/dist/plugins/pg-pool.js +8 -10
- package/dist/plugins/pg-rate-limiter.d.ts +1 -4
- package/dist/plugins/pg-rate-limiter.js +0 -1
- package/dist/plugins/roster-store-sql.d.ts +1 -3
- package/dist/plugins/roster-store-sql.js +3 -5
- package/dist/plugins/store-backend.d.ts +7 -17
- package/dist/plugins/store-backend.js +14 -30
- package/dist/plugins/tidb-pool.js +4 -28
- package/dist/plugins/workflow-journal-store-sql.d.ts +1 -1
- package/dist/plugins/workflow-journal-store-sql.js +1 -1
- package/dist/principal-jwt.js +2 -2
- package/dist/prompts-domain-validate.d.ts +4 -3
- package/dist/prompts-domain-validate.js +7 -8
- package/dist/router/route-orchestration.js +3 -3
- package/dist/run-local.js +5 -4
- package/dist/runs.js +8 -6
- package/dist/runtime-caps-resolver.d.ts +3 -2
- package/dist/runtime-caps-resolver.js +4 -4
- package/dist/runtime-governance.d.ts +4 -7
- package/dist/runtime-governance.js +12 -17
- package/dist/sealed-key.d.ts +1 -1
- package/dist/sealed-key.js +1 -1
- package/dist/security.d.ts +0 -5
- package/dist/security.js +8 -12
- package/dist/session-sync.d.ts +0 -2
- package/dist/session-sync.js +10 -17
- package/dist/spec-fields.js +6 -6
- package/dist/task-settings.js +7 -7
- package/dist/tool-approval.d.ts +3 -3
- package/dist/tool-approval.js +10 -10
- package/dist/trace/artifacts.d.ts +11 -0
- package/dist/trace/artifacts.js +8 -19
- package/dist/trace/ledger-sink.js +7 -1
- package/dist/trace/project.d.ts +17 -0
- package/dist/trace/project.js +55 -5
- package/package.json +2 -2
- package/dist/capabilities/oa-tools.d.ts +0 -15
- package/dist/capabilities/oa-tools.js +0 -54
- package/dist/plugins/approval-store-sql.d.ts +0 -116
- package/dist/plugins/approval-store-sql.js +0 -150
- package/dist/plugins/file-workflow-journal-store.d.ts +0 -12
- package/dist/plugins/file-workflow-journal-store.js +0 -12
- package/dist/plugins/pg-approval-store.d.ts +0 -9
- package/dist/plugins/pg-approval-store.js +0 -9
- package/dist/plugins/pg-breaker-state.d.ts +0 -8
- package/dist/plugins/pg-breaker-state.js +0 -8
- package/dist/plugins/pg-checkpoint-store.d.ts +0 -10
- package/dist/plugins/pg-checkpoint-store.js +0 -10
- package/dist/plugins/pg-file-snapshot-store.d.ts +0 -8
- package/dist/plugins/pg-file-snapshot-store.js +0 -8
- package/dist/plugins/pg-image-bake.d.ts +0 -12
- package/dist/plugins/pg-image-bake.js +0 -11
- package/dist/plugins/pg-image-index.d.ts +0 -12
- package/dist/plugins/pg-image-index.js +0 -11
- package/dist/plugins/pg-outcome-ledger.d.ts +0 -12
- package/dist/plugins/pg-outcome-ledger.js +0 -11
- package/dist/plugins/pg-resume-anchor-store.d.ts +0 -7
- package/dist/plugins/pg-resume-anchor-store.js +0 -7
- package/dist/plugins/pg-run-store.d.ts +0 -9
- package/dist/plugins/pg-run-store.js +0 -9
- package/dist/plugins/pg-session-policy-store.d.ts +0 -7
- package/dist/plugins/pg-session-policy-store.js +0 -7
- package/dist/plugins/pg-session-store.d.ts +0 -12
- package/dist/plugins/pg-session-store.js +0 -12
- package/dist/plugins/pg-tool-result-store.d.ts +0 -9
- package/dist/plugins/pg-tool-result-store.js +0 -9
- package/dist/plugins/pg-workflow-journal-store.d.ts +0 -9
- package/dist/plugins/pg-workflow-journal-store.js +0 -9
- package/dist/plugins/pg-workflow-run-store.d.ts +0 -9
- package/dist/plugins/pg-workflow-run-store.js +0 -9
- package/dist/plugins/tidb-approval-store.d.ts +0 -8
- package/dist/plugins/tidb-approval-store.js +0 -8
- package/dist/plugins/tidb-breaker-state.d.ts +0 -7
- package/dist/plugins/tidb-breaker-state.js +0 -7
- package/dist/plugins/tidb-checkpoint-store.d.ts +0 -9
- package/dist/plugins/tidb-checkpoint-store.js +0 -9
- package/dist/plugins/tidb-file-snapshot-store.d.ts +0 -8
- package/dist/plugins/tidb-file-snapshot-store.js +0 -8
- package/dist/plugins/tidb-image-bake.d.ts +0 -12
- package/dist/plugins/tidb-image-bake.js +0 -11
- package/dist/plugins/tidb-image-index.d.ts +0 -12
- package/dist/plugins/tidb-image-index.js +0 -11
- package/dist/plugins/tidb-outcome-ledger.d.ts +0 -12
- package/dist/plugins/tidb-outcome-ledger.js +0 -12
- package/dist/plugins/tidb-resume-anchor-store.d.ts +0 -7
- package/dist/plugins/tidb-resume-anchor-store.js +0 -7
- package/dist/plugins/tidb-run-store.d.ts +0 -10
- package/dist/plugins/tidb-run-store.js +0 -9
- package/dist/plugins/tidb-session-policy-store.d.ts +0 -7
- package/dist/plugins/tidb-session-policy-store.js +0 -7
- package/dist/plugins/tidb-tool-result-store.d.ts +0 -8
- package/dist/plugins/tidb-tool-result-store.js +0 -10
- package/dist/plugins/tidb-workflow-journal-store.d.ts +0 -9
- package/dist/plugins/tidb-workflow-journal-store.js +0 -9
- package/dist/plugins/tidb-workflow-run-store.d.ts +0 -10
- package/dist/plugins/tidb-workflow-run-store.js +0 -10
- package/dist/plugins/workflow-journal-limits.d.ts +0 -12
- package/dist/plugins/workflow-journal-limits.js +0 -12
package/dist/lsp/ws-transport.js
CHANGED
|
@@ -209,7 +209,7 @@ export class WsLspTransport {
|
|
|
209
209
|
* Returns `undefined` on any failure (→ the manager degrades that language gracefully). `wsUrl` is the
|
|
210
210
|
* `wss://…e2b.dev` URL from `sandbox.getHost(port)`; `rootPath` is the in-sandbox workspace root.
|
|
211
211
|
*/
|
|
212
|
-
export async function connectWsLspTransport(wsUrl, rootPath, signal) {
|
|
212
|
+
export async function connectWsLspTransport(wsUrl, rootPath, signal, initializationOptions) {
|
|
213
213
|
let socket;
|
|
214
214
|
try {
|
|
215
215
|
socket = new WebSocket(wsUrl);
|
|
@@ -245,6 +245,9 @@ export async function connectWsLspTransport(wsUrl, rootPath, signal) {
|
|
|
245
245
|
processId: null,
|
|
246
246
|
rootUri: pathToUri(rootPath),
|
|
247
247
|
capabilities: { textDocument: { definition: {}, references: {}, hover: {}, documentSymbol: {}, implementation: {}, callHierarchy: {} }, workspace: { symbol: {} } },
|
|
248
|
+
// #96 真机门:tls 的 tsserver 路径只能走这里(v4 移除了 CLI 旗);非 tls 服务器按 LSP 规范忽略
|
|
249
|
+
// 未知 initializationOptions。缺席时不发键(老行为逐字保持)。
|
|
250
|
+
...(initializationOptions !== undefined ? { initializationOptions } : {}),
|
|
248
251
|
}, signal);
|
|
249
252
|
transport.notify("initialized", {});
|
|
250
253
|
return transport;
|
package/dist/main.js
CHANGED
|
@@ -390,12 +390,10 @@ async function main() {
|
|
|
390
390
|
maxOutputTokens: capEnv("TASK_MAX_OUTPUT_TOKENS_MAX"),
|
|
391
391
|
maxTurns: capEnv("TASK_MAX_TURNS_MAX"),
|
|
392
392
|
};
|
|
393
|
-
//
|
|
394
|
-
const approvalStore = backend?.approval ? backend.approval() : undefined; // local omits approval() → legacy poll-gate off (durable HITL needs checkpoint anyway)
|
|
395
|
-
const approvalEnabled = approvalStore && config.approvalRequire.length > 0;
|
|
393
|
+
// [2354]/[2356] A-5(5.0.0):F4 轮询门(approvalStore pending 行)整体退役——durable checkpoint 是唯一门形。
|
|
396
394
|
// Finding #2 (edge case): the single-user auto-accept tool-policy BASELINE applies ONLY when the operator
|
|
397
395
|
// expressed NO gate intent. If they SET approval flags (APPROVAL_REQUIRE/APPROVAL_DENY/DURABLE_APPROVAL) but no
|
|
398
|
-
// backing store is wired (e.g. DB_BACKEND=local → no
|
|
396
|
+
// backing store is wired (e.g. DB_BACKEND=local → no checkpointStore ⇒ durableEnabled
|
|
399
397
|
// false), that is a MISCONFIG — do NOT mask it with allow-all; leave toolPolicy undefined so core's UNGATED warning
|
|
400
398
|
// still surfaces it. So the baseline needs single-user turnkey ∧ zero expressed gate intent.
|
|
401
399
|
// 单源在 approval.ts(与 inv#2 同文件)—— 这里原是内联的三格枚举,漏了 approvalNeverAuto,详见该函数顶注。
|
|
@@ -585,7 +583,6 @@ async function main() {
|
|
|
585
583
|
// 构造区上方 const)同实例;ensureChildSessionDurable 见上方构造闭包注释。
|
|
586
584
|
checkpointStore: checkpointStore ? checkpointStore : undefined,
|
|
587
585
|
ensureChildSessionDurable: ensureChildSessionDurable ? ensureChildSessionDurable : undefined,
|
|
588
|
-
oaApiBaseUrl: config.oaApiBaseUrl, oaServiceToken: config.oaServiceToken, oaIssue: config.oaIssue,
|
|
589
586
|
brandIdentity: config.configProvider === "local",
|
|
590
587
|
// core 1.287 extraTools seam ([802]③ server half): SendUserFile reaches the delegated-child roster. SAME
|
|
591
588
|
// existence gate as the top-level mount (the one sendUserFileToolSpec built above — lane/tenancy/config
|
|
@@ -646,7 +643,7 @@ async function main() {
|
|
|
646
643
|
let runDenySweep;
|
|
647
644
|
// design/158 A10:reaper 段搬到 src/boot/reapers.ts(逐字;deny-sweep 晚绑改取值,见该文件头注)。
|
|
648
645
|
const reaper = startReapers({
|
|
649
|
-
config, logger, metrics, localRoot, backend, subRunner, runStore, checkpointStore,
|
|
646
|
+
config, logger, metrics, localRoot, backend, subRunner, runStore, checkpointStore,
|
|
650
647
|
rateLimiter, costQuota, toolResultStore, fileSnapshotStore, taskAttachmentStore, imageBakes, worktreeReap,
|
|
651
648
|
workflowNotifyGate, workflowJournalStore, sqlWorkflowRunStore, workflowNotifyJournal, rosterStore,
|
|
652
649
|
backgroundAgentStore, mailboxStore,
|
|
@@ -704,7 +701,6 @@ async function main() {
|
|
|
704
701
|
const stores = {
|
|
705
702
|
runStore,
|
|
706
703
|
resumeAnchorStore: resumeAnchorStore ? resumeAnchorStore : undefined, // E18 resume-at eventId→entryId map (tidb/pg/local)
|
|
707
|
-
approvalStore,
|
|
708
704
|
approvalExemptionStore: approvalExemptionStore ? approvalExemptionStore : undefined, // decide remember="session" + list/revoke
|
|
709
705
|
checkpointStore,
|
|
710
706
|
sessionPolicyStore: sessionPolicyStore ? sessionPolicyStore : undefined, // E6 operator session-rule store (PUT/GET /v1/sessions/:id/policy)
|
|
@@ -856,8 +852,8 @@ async function main() {
|
|
|
856
852
|
getKeyResolver: () => configCenter.getKeyResolver(),
|
|
857
853
|
taskAttachmentStore, perSessionCwd, setSessionCwd, setSessionShellEnv,
|
|
858
854
|
hookLlm, hookAgent, fleetBus, hookWakeBus, resumeAnchorStore, ownerAware, taskLimitCaps, taskTimeoutSec,
|
|
859
|
-
selectEnvTool, sendUserFileToolSpec, memoryEngine, durableEnabled, approvalExemptionStore,
|
|
860
|
-
|
|
855
|
+
selectEnvTool, sendUserFileToolSpec, memoryEngine, durableEnabled, approvalExemptionStore,
|
|
856
|
+
singleUserAutoAcceptBaseline, checkpointStore, deploymentHooks, imageIndex, perTaskImage,
|
|
861
857
|
sessionEnvSelection,
|
|
862
858
|
});
|
|
863
859
|
const server = createHttpServer({ runner, config, resolveSpec, stores, coordinators, seams, observability, governance, deployment, knobs });
|
package/dist/memory-scope.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// design/158 N17: the memory-plane resolvers moved VERBATIM out of security.ts (lens4 §4.1 — "budget.ts"'s
|
|
2
2
|
// sibling finding: security.ts's name says auth, but ~110 of its 765 lines were memory-scope config
|
|
3
|
-
// resolution with nothing to do with authentication). security.ts
|
|
4
|
-
// createAuthorizer
|
|
3
|
+
// resolution with nothing to do with authentication). security.ts imports memoryScopeFor for its own
|
|
4
|
+
// createAuthorizer; consumers import all four from HERE ([2354] 兼容面全清 — the security.ts compat re-export is gone); index.ts's npm-facing re-export is unaffected (package.json
|
|
5
5
|
// "exports" only ever exposed "." and "./main" — dist/security.js was never a reachable deep-import path).
|
|
6
6
|
import { join } from "node:path";
|
|
7
7
|
import { FileMemoryEngineBackend, resolveMemoryEngineRoot, deriveControlPlaneDir, formatUserScope, formatProjScope } from "@sema-agent/core";
|
|
@@ -295,6 +295,12 @@ export function createMetrics() {
|
|
|
295
295
|
// LOCAL floor(now/windowMs); replica clock skew splits a fleet window into disjoint buckets (soft-limit leak).
|
|
296
296
|
m.gauge("fleet_counter_bucket_skew_ms", "DB clock minus local clock in ms (S10) — skew splits cross-replica counter windows");
|
|
297
297
|
m.gauge("fleet_clock_probe_ok", "1 = last DB clock probe succeeded, 0 = failing (skew gauge is stale while 0)");
|
|
298
|
+
// #96 redesign⑤ (§DESIGN-V2 E): LSP sandbox-bridge lifecycle + session outcomes — previously zero metrics
|
|
299
|
+
// existed for the whole subsystem (a dead bridge or a stuck restart budget had no fleet-level signal).
|
|
300
|
+
m.counter("lsp_bridge_start_total", "LSP sandbox bridge (re)starts attempted, by provider and generation");
|
|
301
|
+
m.counter("lsp_bridge_dead_total", "LSP sandbox bridge generations that died, by reason (the word IS the model-facing unavailableReason)");
|
|
302
|
+
m.counter("lsp_session_open_total", "LSP session opens, by language and outcome (ok/failed)");
|
|
303
|
+
m.counter("lsp_session_heal_total", "LSP session heals (dead-transport reopen), by outcome (ok/failed)");
|
|
298
304
|
// S21 — which backend snapshot blobs actually land on (minio|sql). Partial MINIO_* config silently falls to sql.
|
|
299
305
|
m.gauge("snapshot_blob_backend", "1 on the active snapshot-blob backend series (S21), by backend (minio|sql)");
|
|
300
306
|
// S22 — memory embed/KNN runtime failures (boot said vector; runtime silently degrades to lexical).
|
|
@@ -77,7 +77,7 @@ export declare const SERVED_FENCE_MS: number;
|
|
|
77
77
|
*
|
|
78
78
|
* 编码=防碰撞元组:域/taskId/status 走 JSON 数组(调用方自由串伪造不了分隔符);`#seq` 尾折在 JSON 之外
|
|
79
79
|
* ——JSON 段恒以 `"]` 结尾,`#digits` 尾无歧义,于是 {@link foldKeyFamily} 的剥尾语义 AND SQL 双生子
|
|
80
|
-
* (
|
|
80
|
+
* (workflow-run-store-sql 的 `regexp_replace(run_id, '#[0-9]+$', '')` 家族比对)原样成立——把 seq 折进
|
|
81
81
|
* JSON 元组会让 SQL 侧家族 ack/fence 永 miss(那是另一批的真库改动面,本修有意不碰)。
|
|
82
82
|
* seq 折入=逐停机周期各自成键(1.283 起 background_agent 四腿 notify 铸 cycleSeq);无 seq=单周期旧键
|
|
83
83
|
* (bash/monitor terminal/retain 降级,诚实语义)。serve-fence 侧必须用同一函数(或其家族前缀)构造,
|
|
@@ -97,9 +97,11 @@ export declare function taskNotificationFoldKey(n: {
|
|
|
97
97
|
* task 的 Monitor event 批与 failed 终态在一条腿上互吞;wire 去重要的是逐帧身份,不是 inbox 的双终态列。
|
|
98
98
|
* `seq` 折入 = 停→唤→停的第二周期同 status 帧各自成键(core 1.283 起 background_agent 四腿 notify 铸
|
|
99
99
|
* cycleSeq;缺 seq 时旧键曾把二周期 completed 帧在 observer 臂反向吞掉——core [784]④a);无 seq 的帧
|
|
100
|
-
* (bash/monitor terminal/retain 降级)保持单周期旧键=同键第二帧吞,诚实语义。
|
|
101
|
-
*
|
|
102
|
-
*
|
|
100
|
+
* (bash/monitor terminal/retain 降级)保持单周期旧键=同键第二帧吞,诚实语义。[2373]B-10:core 4.0.0 起
|
|
101
|
+
* task_type 是必填闭合枚举——`task_type?` 可选性**不再对应旧 core 帧**,它活着只为家族前缀构造
|
|
102
|
+
* (server.ts fleet 腿 `taskNotificationFoldKey({task_id,status})` 同款用法);缺席归 "task" 域的语义
|
|
103
|
+
* 只在前缀用途下生效。external 帧三来源齐备(notify 端点 core 铸 / inbox entry extras 存 / drain 帧
|
|
104
|
+
* spread 复原),不会漏域。observer 臂 / stream 臂 / turn-open drain 登记三处必须用本函数
|
|
103
105
|
* 构键且都传 task_type,键形漂移=去重永 miss。 */
|
|
104
106
|
export declare function taskNotificationStreamKey(n: {
|
|
105
107
|
task_type?: string;
|
|
@@ -69,7 +69,7 @@ export const SERVED_FENCE_MS = 30 * 60 * 1000;
|
|
|
69
69
|
*
|
|
70
70
|
* 编码=防碰撞元组:域/taskId/status 走 JSON 数组(调用方自由串伪造不了分隔符);`#seq` 尾折在 JSON 之外
|
|
71
71
|
* ——JSON 段恒以 `"]` 结尾,`#digits` 尾无歧义,于是 {@link foldKeyFamily} 的剥尾语义 AND SQL 双生子
|
|
72
|
-
* (
|
|
72
|
+
* (workflow-run-store-sql 的 `regexp_replace(run_id, '#[0-9]+$', '')` 家族比对)原样成立——把 seq 折进
|
|
73
73
|
* JSON 元组会让 SQL 侧家族 ack/fence 永 miss(那是另一批的真库改动面,本修有意不碰)。
|
|
74
74
|
* seq 折入=逐停机周期各自成键(1.283 起 background_agent 四腿 notify 铸 cycleSeq);无 seq=单周期旧键
|
|
75
75
|
* (bash/monitor terminal/retain 降级,诚实语义)。serve-fence 侧必须用同一函数(或其家族前缀)构造,
|
|
@@ -87,9 +87,11 @@ export function taskNotificationFoldKey(n) {
|
|
|
87
87
|
* task 的 Monitor event 批与 failed 终态在一条腿上互吞;wire 去重要的是逐帧身份,不是 inbox 的双终态列。
|
|
88
88
|
* `seq` 折入 = 停→唤→停的第二周期同 status 帧各自成键(core 1.283 起 background_agent 四腿 notify 铸
|
|
89
89
|
* cycleSeq;缺 seq 时旧键曾把二周期 completed 帧在 observer 臂反向吞掉——core [784]④a);无 seq 的帧
|
|
90
|
-
* (bash/monitor terminal/retain 降级)保持单周期旧键=同键第二帧吞,诚实语义。
|
|
91
|
-
*
|
|
92
|
-
*
|
|
90
|
+
* (bash/monitor terminal/retain 降级)保持单周期旧键=同键第二帧吞,诚实语义。[2373]B-10:core 4.0.0 起
|
|
91
|
+
* task_type 是必填闭合枚举——`task_type?` 可选性**不再对应旧 core 帧**,它活着只为家族前缀构造
|
|
92
|
+
* (server.ts fleet 腿 `taskNotificationFoldKey({task_id,status})` 同款用法);缺席归 "task" 域的语义
|
|
93
|
+
* 只在前缀用途下生效。external 帧三来源齐备(notify 端点 core 铸 / inbox entry extras 存 / drain 帧
|
|
94
|
+
* spread 复原),不会漏域。observer 臂 / stream 臂 / turn-open drain 登记三处必须用本函数
|
|
93
95
|
* 构键且都传 task_type,键形漂移=去重永 miss。 */
|
|
94
96
|
export function taskNotificationStreamKey(n) {
|
|
95
97
|
const domain = n.task_type === "external" ? "external" : "task";
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Cross-replica circuit-breaker state (core 1.38 `BreakerState`) — SINGLE-FILE DUAL-DIALECT
|
|
3
3
|
* (design/158 A12 定型半场). ONE implementation, TWO dialects; the historical `TiDBBreakerState` /
|
|
4
|
-
* `PgBreakerState` class names survive as thin ctor subclasses (
|
|
5
|
-
* src/plugins/pg-breaker-state.ts are now re-export shims) so every consumer (store-backend.ts, the
|
|
4
|
+
* `PgBreakerState` class names survive as thin ctor subclasses in THIS file ([2354]: the old per-dialect shim files are deleted) so every consumer (store-backend.ts, the
|
|
6
5
|
* fake-pool unit suites, the real dual-DB integration suite) is untouched.
|
|
7
6
|
*
|
|
8
7
|
* core's `createCircuitBreakerBrain` defaults to a per-PROCESS Map → on a multi-replica deployment
|
|
@@ -26,7 +25,7 @@
|
|
|
26
25
|
* - upsert form: `ON DUPLICATE KEY UPDATE … VALUES(col)` vs `ON CONFLICT (breaker_key) DO UPDATE SET
|
|
27
26
|
* … EXCLUDED.col`
|
|
28
27
|
* - schema ownership: TiDB DDL lives centrally in tidb-pool.ts; PG DDL is self-contained here
|
|
29
|
-
* (`PG_BREAKER_STATE_SCHEMA` / `ensureSchema`,
|
|
28
|
+
* (`PG_BREAKER_STATE_SCHEMA` / `ensureSchema`, exported from THIS file) — disjoint table,
|
|
30
29
|
* so a standalone idempotent apply is safe (no central-schema shadowing), mirroring every other PG store.
|
|
31
30
|
* Everything else (write-through logic, the pending-guard race fix, refresh/prune, row→snapshot mapping,
|
|
32
31
|
* opened_at Date handling) is IDENTICAL — the SqlDriver seam (result unwrapping) is what let the row
|
|
@@ -3,7 +3,6 @@ import type { Pool as PgPool, PoolClient } from "pg";
|
|
|
3
3
|
import { type ImageStatus, type ImageIndexEntry, type ImageIndexUpsert, type ImageViewer, type ImageListFilter } from "./store-contracts.js";
|
|
4
4
|
import { type SqlDriver } from "./sql-driver.js";
|
|
5
5
|
export type { ImageNestedBuildMode, ImageCapabilities, ImagePodContract, ImageStatus, ImageVisibility, ImageIndexEntry, ImageIndexUpsert, ImageViewer, ImageListFilter, ImageRow, } from "./store-contracts.js";
|
|
6
|
-
export { mapImageRow as mapRow } from "./store-contracts.js";
|
|
7
6
|
/** PG translation of the `sandbox_image_index` DDL in tidb-pool.ts (JSON→JSONB, DATETIME(3)→TIMESTAMPTZ(3),
|
|
8
7
|
* TINYINT(1)→SMALLINT(布尔列 PG 映射归一,clay 批 2026-07-26 —— 两方言读回同为 number,写入 0/1,
|
|
9
8
|
* 读侧 `!!` 保持,出口 JS 类型不变), inline UNIQUE KEY/KEY → separate CREATE UNIQUE INDEX / CREATE INDEX). */
|
|
@@ -47,7 +47,6 @@ import {
|
|
|
47
47
|
// backend-neutral store-contracts.ts (design/158 A3 沉底; no adapter imports its twin).
|
|
48
48
|
mapImageRow as mapRow, } from "./store-contracts.js";
|
|
49
49
|
import { mysqlDriver, pgDriver } from "./sql-driver.js";
|
|
50
|
-
export { mapImageRow as mapRow } from "./store-contracts.js";
|
|
51
50
|
/** PG translation of the `sandbox_image_index` DDL in tidb-pool.ts (JSON→JSONB, DATETIME(3)→TIMESTAMPTZ(3),
|
|
52
51
|
* TINYINT(1)→SMALLINT(布尔列 PG 映射归一,clay 批 2026-07-26 —— 两方言读回同为 number,写入 0/1,
|
|
53
52
|
* 读侧 `!!` 保持,出口 JS 类型不变), inline UNIQUE KEY/KEY → separate CREATE UNIQUE INDEX / CREATE INDEX). */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Checkpoint, type CheckpointSummary, type CheckpointToken, type ReopenReason, type ResolveExpectation, type ResumeOutcome } from "@sema-agent/core";
|
|
2
|
-
import { type PendingCheckpoint } from "./
|
|
2
|
+
import { type PendingCheckpoint } from "./checkpoint-store-sql.js";
|
|
3
3
|
export interface LocalCheckpointStoreOptions {
|
|
4
4
|
/** taskId join for the pending card (the local FileRunStore's `getActiveTaskId`). Absent ⇒ `taskId: null`. */
|
|
5
5
|
getActiveTaskId?: (sessionId: string) => Promise<string | undefined>;
|
|
@@ -24,7 +24,7 @@ import { createHash } from "node:crypto";
|
|
|
24
24
|
import { existsSync, readFileSync, readdirSync, renameSync, unlinkSync, mkdirSync } from "node:fs";
|
|
25
25
|
import { join } from "node:path";
|
|
26
26
|
import { FileCheckpointStore, atomicWriteFile, sanitizePathComponent, } from "@sema-agent/core";
|
|
27
|
-
import { boundedToolInput, TERMINAL_BACKSTOP_MS, TERMINAL_GRACE_MS } from "./
|
|
27
|
+
import { boundedToolInput, TERMINAL_BACKSTOP_MS, TERMINAL_GRACE_MS } from "./checkpoint-store-sql.js";
|
|
28
28
|
/** design/80 D-D read-time twin of the TiDB put-time `terminal_at` column (same formula — anti-drift). */
|
|
29
29
|
function terminalAtOf(cp) {
|
|
30
30
|
return Math.max(cp.createdAt + TERMINAL_BACKSTOP_MS, (cp.deadline ?? 0) + TERMINAL_GRACE_MS);
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
// Vector rungs (design/81, re-mounted here per §4): lexical (jaccard, byte-equal to FileBackend) →
|
|
20
20
|
// portable (jsonb vectors, in-process cosine) → native (pgvector `<=>` SQL). All three share the
|
|
21
21
|
// cosine-distance contract score ∈ [0,2] — upgrading recall is a config change, not a recalibration.
|
|
22
|
-
import { cosineDistance, jaccardDistance, termSet
|
|
22
|
+
import { cosineDistance, jaccardDistance, termSet } from "@sema-agent/core";
|
|
23
|
+
import { isUniqueViolation } from "./memory-engine-vector-util.js";
|
|
23
24
|
import { computeEntryRev, serializeEntryFile } from "@sema-agent/core";
|
|
24
25
|
import { pgSafeJsonStringify, pgHasUnstorable } from "./pg-safe-json.js";
|
|
25
26
|
/** Table names (single source). Deliberately DISJOINT from the legacy `agent_memory*` tables —
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
// - v1 lexical only:embedder/vector 面无 TiDB 对应(Pg 的 pgvector rung 是 Pg 专属);构造签名保留
|
|
22
22
|
// opts 但传入 embedder=fail-loud 拒绝,search 恒走 jaccard 词面,haystack 与 Pg/File 逐字节同构
|
|
23
23
|
// (`${name ?? slug} ${description} ${body}`——memoryBackendContract 的 search 等价断言依赖)。
|
|
24
|
-
import { jaccardDistance, termSet } from "
|
|
24
|
+
import { jaccardDistance, termSet } from "@sema-agent/core";
|
|
25
25
|
import { computeEntryRev, serializeEntryFile } from "@sema-agent/core";
|
|
26
26
|
import { pgHasUnstorable } from "./pg-safe-json.js";
|
|
27
27
|
/** Table names (single source) — SAME names as PG_MEMORY_ENGINE_TABLES (the two dialects never share
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
/** memory-engine 方言实现共用的纯工具函数。三个距离/词集函数
|
|
2
|
-
*
|
|
1
|
+
/** memory-engine 方言实现共用的纯工具函数。三个距离/词集函数(termSet/jaccardDistance/cosineDistance)
|
|
2
|
+
* 在 core(1.268.0 起公开导出,单一语义源)——消费者直引 core([2354] 兼容面全清:此处转口已删)。
|
|
3
3
|
* `isUniqueViolation` 重新内联:它当年随 core 的 pg **示例适配器**导出面走,core 1.424 按 clay 包卫生令
|
|
4
4
|
* 把整个 examples 面退出 npm 包([1803] BREAKING)⇒ re-export 断源。逐字抄自 core 1.423
|
|
5
5
|
* `examples/adapters/pg-adapter.js`(纯谓词,无 byte-equal 契约约束)。 */
|
|
6
|
-
export { termSet, jaccardDistance, cosineDistance } from "@sema-agent/core";
|
|
7
6
|
export declare function isUniqueViolation(err: unknown): boolean;
|
|
8
7
|
//# sourceMappingURL=memory-engine-vector-util.d.ts.map
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
/** memory-engine 方言实现共用的纯工具函数。三个距离/词集函数
|
|
2
|
-
*
|
|
1
|
+
/** memory-engine 方言实现共用的纯工具函数。三个距离/词集函数(termSet/jaccardDistance/cosineDistance)
|
|
2
|
+
* 在 core(1.268.0 起公开导出,单一语义源)——消费者直引 core([2354] 兼容面全清:此处转口已删)。
|
|
3
3
|
* `isUniqueViolation` 重新内联:它当年随 core 的 pg **示例适配器**导出面走,core 1.424 按 clay 包卫生令
|
|
4
4
|
* 把整个 examples 面退出 npm 包([1803] BREAKING)⇒ re-export 断源。逐字抄自 core 1.423
|
|
5
5
|
* `examples/adapters/pg-adapter.js`(纯谓词,无 byte-equal 契约约束)。 */
|
|
6
|
-
export { termSet, jaccardDistance, cosineDistance } from "@sema-agent/core";
|
|
7
6
|
export function isUniqueViolation(err) {
|
|
8
7
|
if (typeof err !== "object" || err === null)
|
|
9
8
|
return false;
|
|
@@ -22,7 +22,7 @@ import type { RunRecord, SessionSummary, RunEvent } from "./store-contracts.js";
|
|
|
22
22
|
* injects this probe so the reapers get the SAME two predicates the SQL twins express as EXISTS subqueries:
|
|
23
23
|
* - hasPending = EXISTS (checkpoint c WHERE c.session_id = ? AND c.status = 'pending') — the design/80 D-D
|
|
24
24
|
* NOT-EXISTS-pending guard: a row whose checkpoint is STILL pending is owned by the checkpoint-state-driven
|
|
25
|
-
* sweeps and must NEVER be time-reaped (else two-runs-one-session, see
|
|
25
|
+
* sweeps and must NEVER be time-reaped (else two-runs-one-session, see run-store-sql.ts reapSuspended doc).
|
|
26
26
|
* - hasExpired = EXISTS (checkpoint ce WHERE ce.session_id = ? AND ce.status = 'expired') — the
|
|
27
27
|
* failSuspendedWithExpiredCheckpoint driver (checkpoint-STATE-driven, not time-driven).
|
|
28
28
|
* Probe ABSENT (old assembly / no checkpoint store wired) ⇒ the reapers stay honest NO-OPs — without the
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* WHY THIS EXISTS (and not core's `InMemorySessionPolicyStore`): core's in-memory/file policy stores implement only
|
|
5
5
|
* the core interface (getRules/putRules/listBySession) — they have NO deletion seam, so neither the E21 session purge
|
|
6
6
|
* nor the 2c `overwrite-dst` subsystem wipe can remove policy rows on a backend that uses them (the SQL twins carry
|
|
7
|
-
* `deleteBySession` as a service extension; see
|
|
7
|
+
* `deleteBySession` as a service extension; see session-policy-store-sql.ts). This store is the delete-capable
|
|
8
8
|
* in-memory twin. The seam itself is also requested upstream (core: optional `deleteBySession?` on the interface +
|
|
9
9
|
* the File/InMemory impls) — if core lands it, this class can retire in favor of core's.
|
|
10
10
|
*
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* WHY THIS EXISTS (and not core's `InMemorySessionPolicyStore`): core's in-memory/file policy stores implement only
|
|
5
5
|
* the core interface (getRules/putRules/listBySession) — they have NO deletion seam, so neither the E21 session purge
|
|
6
6
|
* nor the 2c `overwrite-dst` subsystem wipe can remove policy rows on a backend that uses them (the SQL twins carry
|
|
7
|
-
* `deleteBySession` as a service extension; see
|
|
7
|
+
* `deleteBySession` as a service extension; see session-policy-store-sql.ts). This store is the delete-capable
|
|
8
8
|
* in-memory twin. The seam itself is also requested upstream (core: optional `deleteBySession?` on the interface +
|
|
9
9
|
* the File/InMemory impls) — if core lands it, this class can retire in favor of core's.
|
|
10
10
|
*
|
|
@@ -27,7 +27,7 @@ export async function ensurePgMemorySyncSchema(query) {
|
|
|
27
27
|
await query(`CREATE INDEX IF NOT EXISTS ${PG_MEMORY_SYNC_TABLES.pushQueue}_next_attempt_idx ON ${PG_MEMORY_SYNC_TABLES.pushQueue} (next_attempt_at)`);
|
|
28
28
|
}
|
|
29
29
|
/** jsonb defense: node-pg hands back parsed objects, but a text-typed round-trip (or a foreign
|
|
30
|
-
* writer) may yield a string — same posture as parseJson in
|
|
30
|
+
* writer) may yield a string — same posture as parseJson in run-store-sql.ts. */
|
|
31
31
|
function fromJsonb(v) {
|
|
32
32
|
if (typeof v === "string")
|
|
33
33
|
return JSON.parse(v);
|
package/dist/plugins/pg-pool.js
CHANGED
|
@@ -28,14 +28,13 @@ import pg from "pg";
|
|
|
28
28
|
// Each PG store owns its own (disjoint) tables' DDL via a standalone idempotent ensureSchema; the central apply
|
|
29
29
|
// composes them so production wires ONE ensurePgSchema (the PG twin of tidb-pool's single ensureSchema).
|
|
30
30
|
import { ensureSchema as ensureSessionSchema } from "./pg-session-storage.js";
|
|
31
|
-
import { ensureSchema as ensureToolResultSchema } from "./
|
|
31
|
+
import { ensureSchema as ensureToolResultSchema } from "./tool-result-store-sql.js";
|
|
32
32
|
import { ensureSchema as ensureCostQuotaSchema } from "./pg-cost-quota.js";
|
|
33
33
|
import { ensureSchema as ensureRateLimitSchema } from "./pg-rate-limiter.js";
|
|
34
|
-
import { ensureSchema as ensureBreakerStateSchema } from "./
|
|
35
|
-
import {
|
|
36
|
-
import { ensureSchema as
|
|
37
|
-
import {
|
|
38
|
-
import { ensureSchema as ensureImageBakeSchema } from "./pg-image-bake.js";
|
|
34
|
+
import { ensureSchema as ensureBreakerStateSchema } from "./breaker-state-sql.js";
|
|
35
|
+
import { ensurePgOutcomeLedgerSchema as ensureOutcomeLedgerSchema } from "./outcome-ledger-sql.js";
|
|
36
|
+
import { ensureSchema as ensureImageIndexSchema } from "./image-index-sql.js";
|
|
37
|
+
import { ensurePgImageBakeSchema as ensureImageBakeSchema } from "./image-bake-store-sql.js";
|
|
39
38
|
export const PG_SCHEMA_STATEMENTS = [
|
|
40
39
|
`CREATE TABLE IF NOT EXISTS task_run (
|
|
41
40
|
task_id VARCHAR(64) NOT NULL,
|
|
@@ -145,7 +144,7 @@ export const PG_SCHEMA_STATEMENTS = [
|
|
|
145
144
|
`CREATE INDEX IF NOT EXISTS idx_sendfile_link_scope ON sendfile_link (scope, id)`,
|
|
146
145
|
// E6 durable SessionPolicyStore (the PG twin of the TiDB session_policy table; policy_key = sha256(JSON.stringify(
|
|
147
146
|
// [sessionId, principal ?? null])) = a fixed 64-char hash PK; rules JSONB; CAS-versioned tighten-only — see
|
|
148
|
-
// tidb-pool.ts /
|
|
147
|
+
// tidb-pool.ts / session-policy-store-sql.ts).
|
|
149
148
|
`CREATE TABLE IF NOT EXISTS session_policy (
|
|
150
149
|
policy_key CHAR(64) NOT NULL,
|
|
151
150
|
session_id VARCHAR(64) NOT NULL,
|
|
@@ -186,7 +185,7 @@ export const PG_SCHEMA_STATEMENTS = [
|
|
|
186
185
|
// SVC-2 (core CORE-7) durable WorkflowJournalStore — the PG twin of the TiDB workflow_journal table (cross-replica
|
|
187
186
|
// resume journal; (run_id, ordinal) PK = idempotent OVERWRITE upsert; `result` = JSON.stringify(TaskResult)). `result`
|
|
188
187
|
// is TEXT, NOT JSONB — the byte-match contract is "string in, string out" (the store JSON.parses on load); JSONB would
|
|
189
|
-
// make `pg` auto-parse the row back to an object and break the twin's String()→JSON.parse path. See
|
|
188
|
+
// make `pg` auto-parse the row back to an object and break the twin's String()→JSON.parse path. See workflow-journal-store-sql.ts.
|
|
190
189
|
`CREATE TABLE IF NOT EXISTS workflow_journal (
|
|
191
190
|
run_id VARCHAR(191) NOT NULL,
|
|
192
191
|
ordinal INT NOT NULL,
|
|
@@ -210,7 +209,7 @@ export const PG_SCHEMA_STATEMENTS = [
|
|
|
210
209
|
claimed_at BIGINT NOT NULL,
|
|
211
210
|
PRIMARY KEY (source_run_id, scope)
|
|
212
211
|
)`,
|
|
213
|
-
// P1 (fleet failover): WorkflowRunStore + completion-inbox PG twins (design doc in
|
|
212
|
+
// P1 (fleet failover): WorkflowRunStore + completion-inbox PG twins (design doc in workflow-run-store-sql.ts).
|
|
214
213
|
// `run` is TEXT not jsonb (node-pg auto-parse would break the shared String()→JSON.parse path).
|
|
215
214
|
`CREATE TABLE IF NOT EXISTS workflow_run (
|
|
216
215
|
id VARCHAR(191) NOT NULL,
|
|
@@ -332,7 +331,6 @@ export async function ensurePgSchema(pool) {
|
|
|
332
331
|
await ensureCostQuotaSchema(client);
|
|
333
332
|
await ensureRateLimitSchema(client);
|
|
334
333
|
await ensureBreakerStateSchema(client);
|
|
335
|
-
await ensureApprovalSchema(client);
|
|
336
334
|
await ensureOutcomeLedgerSchema(client);
|
|
337
335
|
await ensureImageIndexSchema(client);
|
|
338
336
|
await ensureImageBakeSchema(client);
|
|
@@ -8,8 +8,7 @@
|
|
|
8
8
|
*
|
|
9
9
|
* design/158 A12 C1b: the `PgWriteBehindCounter` this file used to define inline now lives in
|
|
10
10
|
* write-behind-counter.ts as the PG binding of ONE dialect-parameterized counter (the mysql2 twin is
|
|
11
|
-
* `WriteBehindCounter`); the SQL-dialect deltas are documented and branched there.
|
|
12
|
-
* so the historical import path keeps working.
|
|
11
|
+
* `WriteBehindCounter`); the SQL-dialect deltas are documented and branched there.
|
|
13
12
|
*
|
|
14
13
|
* Schema: this store's `rate_limit` table is DISJOINT from the other PG stores' tables, so a
|
|
15
14
|
* self-contained {@link PG_RATE_LIMITER_SCHEMA} + {@link ensureSchema} is safe (no shadowing).
|
|
@@ -17,8 +16,6 @@
|
|
|
17
16
|
import type { Pool, PoolClient } from "pg";
|
|
18
17
|
import type { RateDecision, RateGate } from "../observability/rate-limit.js";
|
|
19
18
|
import { type CounterDegradeHook } from "./write-behind-counter.js";
|
|
20
|
-
export { PgWriteBehindCounter } from "./write-behind-counter.js";
|
|
21
|
-
export type { CounterTable } from "./write-behind-counter.js";
|
|
22
19
|
export declare class PgRateLimiter implements RateGate {
|
|
23
20
|
private readonly limit;
|
|
24
21
|
private readonly counter;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { PgWriteBehindCounter } from "./write-behind-counter.js";
|
|
2
|
-
export { PgWriteBehindCounter } from "./write-behind-counter.js";
|
|
3
2
|
/** The counter's table binding for the per-key request rate limit (mirror of the TiDB twin's binding). */
|
|
4
3
|
const RATE_LIMIT_TABLE = { table: "rate_limit", keyCol: "limit_key", valCol: "n" };
|
|
5
4
|
export class PgRateLimiter {
|
|
@@ -21,11 +21,9 @@
|
|
|
21
21
|
* 是「core 变语义必须先过迁移裁量」的告警钉)。
|
|
22
22
|
*/
|
|
23
23
|
import type { Pool } from "mysql2/promise";
|
|
24
|
-
import {
|
|
24
|
+
import { type RosterStore, type RosterEntry } from "@sema-agent/core";
|
|
25
25
|
type RosterAccess = Parameters<RosterStore["resolve"]>[1];
|
|
26
26
|
import type { PgQueryFn } from "./pg-query.js";
|
|
27
|
-
/** 兼容名保留(测试/历史引用),现=core 导出直引(私拷已删)。 */
|
|
28
|
-
export declare const normalizeAgentNameLocal: typeof normalizeAgentName;
|
|
29
27
|
export declare const ROSTER_TABLE = "agent_roster";
|
|
30
28
|
export declare function ensureTiDBRosterSchema(pool: Pool): Promise<void>;
|
|
31
29
|
export declare function ensurePgRosterSchema(q: PgQueryFn): Promise<void>;
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { normalizeAgentName } from "@sema-agent/core";
|
|
2
|
-
/** 兼容名保留(测试/历史引用),现=core 导出直引(私拷已删)。 */
|
|
3
|
-
export const normalizeAgentNameLocal = normalizeAgentName;
|
|
4
2
|
export const ROSTER_TABLE = "agent_roster";
|
|
5
3
|
/** 行 → RosterEntry(缺席键省略,core 形逐字;session_scoped 数值/布尔双方言归一)。
|
|
6
4
|
* core 1.365 BREAKING:owner/scope 升类型必填——两方言 CREATE 直接建成 NOT NULL(当年的「清死行 +
|
|
@@ -114,7 +112,7 @@ export async function ensurePgRosterSchema(q) {
|
|
|
114
112
|
/** upsert 参数序(两方言共用;core 1.365 起 owner/scope 类型必填——键列直取,与 core upsertKey 同键)。 */
|
|
115
113
|
function upsertParams(entry, now) {
|
|
116
114
|
return [
|
|
117
|
-
|
|
115
|
+
normalizeAgentName(entry.name),
|
|
118
116
|
entry.owner,
|
|
119
117
|
entry.scope,
|
|
120
118
|
entry.name,
|
|
@@ -148,7 +146,7 @@ export class TiDBRosterStore {
|
|
|
148
146
|
session_scoped = VALUES(session_scoped), root_session_id = VALUES(root_session_id), model = VALUES(model), created_at_ms = VALUES(created_at_ms), recorded_at_ms = VALUES(recorded_at_ms)`, p.map((v) => (typeof v === "boolean" ? (v ? 1 : 0) : v)));
|
|
149
147
|
}
|
|
150
148
|
async resolve(name, access) {
|
|
151
|
-
const key =
|
|
149
|
+
const key = normalizeAgentName(name);
|
|
152
150
|
if (key === "")
|
|
153
151
|
return undefined;
|
|
154
152
|
const [rows] = (await this.pool.query(`SELECT ${COLS} FROM ${ROSTER_TABLE} WHERE ${RESOLVE_WHERE_TIDB} ORDER BY created_at_ms DESC, recorded_at_ms DESC, agent_id DESC LIMIT 1`, [key, access.scope ?? null, access.owner ?? null, access.sessionId ?? null, access.sessionId ?? null]));
|
|
@@ -185,7 +183,7 @@ export class PgRosterStore {
|
|
|
185
183
|
recorded_at_ms = EXCLUDED.recorded_at_ms`, upsertParams(entry, this.clock()));
|
|
186
184
|
}
|
|
187
185
|
async resolve(name, access) {
|
|
188
|
-
const key =
|
|
186
|
+
const key = normalizeAgentName(name);
|
|
189
187
|
if (key === "")
|
|
190
188
|
return undefined;
|
|
191
189
|
const { rows } = await this.q(`SELECT ${COLS} FROM ${ROSTER_TABLE} WHERE ${RESOLVE_WHERE_PG} ORDER BY created_at_ms DESC, recorded_at_ms DESC, agent_id DESC LIMIT 1`, [key, access.scope ?? null, access.owner ?? null, access.sessionId ?? null, access.sessionId ?? null]);
|
|
@@ -3,27 +3,19 @@ import type { Pool as PgPool } from "pg";
|
|
|
3
3
|
import type { SessionStore, SessionPolicyStore, FileSnapshotStore, WorkflowJournalStore, ToolResultStore } from "@sema-agent/core";
|
|
4
4
|
import { type FileSnapshotBounds } from "@sema-agent/core";
|
|
5
5
|
import { type OutcomeSink } from "./file-outcome-sink.js";
|
|
6
|
-
import { type InboxWarn } from "./
|
|
6
|
+
import { type InboxWarn } from "./workflow-run-store-sql.js";
|
|
7
7
|
import { FileRunStore } from "./file-run-store.js";
|
|
8
8
|
import { LocalCheckpointStore } from "./local-checkpoint-store.js";
|
|
9
9
|
import { FileResumeAnchorStore } from "./file-resume-anchor-store.js";
|
|
10
10
|
import { type ApprovalExemptionStore } from "./approval-exemption-store.js";
|
|
11
11
|
import { type SendFileLedger } from "./send-file-ledger.js";
|
|
12
|
-
import { TiDBResumeAnchorStore } from "./
|
|
13
|
-
import { PgResumeAnchorStore } from "./pg-resume-anchor-store.js";
|
|
12
|
+
import { TiDBResumeAnchorStore, PgResumeAnchorStore } from "./resume-anchor-store-sql.js";
|
|
14
13
|
import type { ServiceConfig } from "../config-types.js";
|
|
15
|
-
import { TiDBRunStore } from "./
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import { PgApprovalStore } from "./pg-approval-store.js";
|
|
21
|
-
import { TiDBImageIndex } from "./tidb-image-index.js";
|
|
22
|
-
import { PgImageIndex } from "./pg-image-index.js";
|
|
23
|
-
import { TiDBImageBake } from "./tidb-image-bake.js";
|
|
24
|
-
import { PgImageBake } from "./pg-image-bake.js";
|
|
25
|
-
import { TiDBBreakerState } from "./tidb-breaker-state.js";
|
|
26
|
-
import { PgBreakerState } from "./pg-breaker-state.js";
|
|
14
|
+
import { TiDBRunStore, PgRunStore } from "./run-store-sql.js";
|
|
15
|
+
import { TiDBCheckpointStore, PgCheckpointStore } from "./checkpoint-store-sql.js";
|
|
16
|
+
import { TiDBImageIndex, PgImageIndex } from "./image-index-sql.js";
|
|
17
|
+
import { TiDBImageBake, PgImageBake } from "./image-bake-store-sql.js";
|
|
18
|
+
import { TiDBBreakerState, PgBreakerState } from "./breaker-state-sql.js";
|
|
27
19
|
import { TiDBCostQuota } from "./tidb-cost-quota.js";
|
|
28
20
|
import { PgCostQuota } from "./pg-cost-quota.js";
|
|
29
21
|
import { TiDBRateLimiter } from "./tidb-rate-limiter.js";
|
|
@@ -79,7 +71,6 @@ export type ServiceWorkflowJournalStore = WorkflowJournalStore & {
|
|
|
79
71
|
* TaskResult-bearing table (the per-run deleteByRun has no run-store reap hook). Local InMemory omits it. */
|
|
80
72
|
reapExpired?(now: number, maxAgeMs: number): Promise<number>;
|
|
81
73
|
};
|
|
82
|
-
export type ApprovalStore = TiDBApprovalStore | PgApprovalStore;
|
|
83
74
|
export type ImageIndex = TiDBImageIndex | PgImageIndex;
|
|
84
75
|
export type ImageBake = TiDBImageBake | PgImageBake;
|
|
85
76
|
/** The FULL checkpoint store (core CheckpointStore + the service operator-queue/ctx methods listPending/
|
|
@@ -155,7 +146,6 @@ export interface StoreBackend {
|
|
|
155
146
|
checkpoint?(logger?: {
|
|
156
147
|
info?(msg: string, meta?: unknown): void;
|
|
157
148
|
}): CheckpointStoreFull;
|
|
158
|
-
approval?(): ApprovalStore;
|
|
159
149
|
toolResult?(): ToolResultStoreFull;
|
|
160
150
|
imageIndex?(): ImageIndex;
|
|
161
151
|
imageBake?(): ImageBake;
|
|
@@ -4,48 +4,34 @@
|
|
|
4
4
|
* subsystem. main.ts wires through this instead of `new TiDB*(pool)` so `DB_BACKEND=pg` boots the whole service on
|
|
5
5
|
* PG with zero call-site churn. The twins are interchangeable behaviourally (one shared real-DB integration suite
|
|
6
6
|
* keeps them in lock-step); the unions below exist only because TS private fields make the concrete classes
|
|
7
|
-
* nominally distinct (run/
|
|
7
|
+
* nominally distinct (run/imageIndex/imageBake have no core interface — the rest implement one).
|
|
8
8
|
*/
|
|
9
9
|
import { homedir } from "node:os";
|
|
10
10
|
import { join } from "node:path";
|
|
11
11
|
import { FileStorageBackend, FileSessionRepo, DEFAULT_SNAPSHOT_BOUNDS } from "@sema-agent/core";
|
|
12
|
-
import { FileWorkflowJournalStore } from "
|
|
13
|
-
import { TiDBOutcomeLedger } from "./
|
|
14
|
-
import { PgOutcomeLedger } from "./pg-outcome-ledger.js";
|
|
12
|
+
import { FileWorkflowJournalStore } from "@sema-agent/core";
|
|
13
|
+
import { TiDBOutcomeLedger, PgOutcomeLedger } from "./outcome-ledger-sql.js";
|
|
15
14
|
import { FileOutcomeSink } from "./file-outcome-sink.js";
|
|
16
|
-
import { TiDBWorkflowRunStore, TiDBWorkflowCompletionInbox, TiDBWorkflowNotifyJournalStore } from "./
|
|
17
|
-
import { PgWorkflowRunStore, PgWorkflowCompletionInbox, PgWorkflowNotifyJournalStore } from "./pg-workflow-run-store.js";
|
|
15
|
+
import { TiDBWorkflowRunStore, TiDBWorkflowCompletionInbox, TiDBWorkflowNotifyJournalStore, PgWorkflowRunStore, PgWorkflowCompletionInbox, PgWorkflowNotifyJournalStore } from "./workflow-run-store-sql.js";
|
|
18
16
|
import { FileRunStore } from "./file-run-store.js";
|
|
19
17
|
import { LocalSessionStore } from "./local-session-store.js";
|
|
20
18
|
import { LocalCheckpointStore } from "./local-checkpoint-store.js";
|
|
21
19
|
import { FileResumeAnchorStore } from "./file-resume-anchor-store.js";
|
|
22
20
|
import { TiDBApprovalExemptionStore, PgApprovalExemptionStore, FileApprovalExemptionStore } from "./approval-exemption-store.js";
|
|
23
21
|
import { TiDBSendFileLedger, PgSendFileLedger, FileSendFileLedger } from "./send-file-ledger.js";
|
|
24
|
-
import { TiDBResumeAnchorStore } from "./
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import { TiDBWorkflowJournalStore } from "./tidb-workflow-journal-store.js";
|
|
29
|
-
import { PgWorkflowJournalStore } from "./pg-workflow-journal-store.js";
|
|
30
|
-
import { TiDBFileSnapshotStore } from "./tidb-file-snapshot-store.js";
|
|
31
|
-
import { PgFileSnapshotStore } from "./pg-file-snapshot-store.js";
|
|
22
|
+
import { TiDBResumeAnchorStore, PgResumeAnchorStore } from "./resume-anchor-store-sql.js";
|
|
23
|
+
import { TiDBSessionPolicyStore, PgSessionPolicyStore } from "./session-policy-store-sql.js";
|
|
24
|
+
import { TiDBWorkflowJournalStore, PgWorkflowJournalStore } from "./workflow-journal-store-sql.js";
|
|
25
|
+
import { TiDBFileSnapshotStore, PgFileSnapshotStore } from "./file-snapshot-store-sql.js";
|
|
32
26
|
import { MinioBlobBackend, SqlBlobBackend } from "./blob-backend.js";
|
|
33
27
|
import { createTidbPool, ensureSchema as ensureTidbSchema } from "./tidb-pool.js";
|
|
34
28
|
import { createPgPool, ensurePgSchema, pgPoolOptions } from "./pg-pool.js";
|
|
35
|
-
import { TiDBRunStore } from "./
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
38
|
-
import {
|
|
39
|
-
import {
|
|
40
|
-
import {
|
|
41
|
-
import { TiDBToolResultStore } from "./tidb-tool-result-store.js";
|
|
42
|
-
import { PgToolResultStore } from "./pg-tool-result-store.js";
|
|
43
|
-
import { TiDBImageIndex } from "./tidb-image-index.js";
|
|
44
|
-
import { PgImageIndex } from "./pg-image-index.js";
|
|
45
|
-
import { TiDBImageBake } from "./tidb-image-bake.js";
|
|
46
|
-
import { PgImageBake } from "./pg-image-bake.js";
|
|
47
|
-
import { TiDBBreakerState } from "./tidb-breaker-state.js";
|
|
48
|
-
import { PgBreakerState } from "./pg-breaker-state.js";
|
|
29
|
+
import { TiDBRunStore, PgRunStore } from "./run-store-sql.js";
|
|
30
|
+
import { TiDBCheckpointStore, PgCheckpointStore } from "./checkpoint-store-sql.js";
|
|
31
|
+
import { TiDBToolResultStore, PgToolResultStore } from "./tool-result-store-sql.js";
|
|
32
|
+
import { TiDBImageIndex, PgImageIndex } from "./image-index-sql.js";
|
|
33
|
+
import { TiDBImageBake, PgImageBake } from "./image-bake-store-sql.js";
|
|
34
|
+
import { TiDBBreakerState, PgBreakerState } from "./breaker-state-sql.js";
|
|
49
35
|
import { TiDBCostQuota } from "./tidb-cost-quota.js";
|
|
50
36
|
import { PgCostQuota } from "./pg-cost-quota.js";
|
|
51
37
|
import { TiDBRateLimiter } from "./tidb-rate-limiter.js";
|
|
@@ -117,7 +103,6 @@ class TiDBBackend {
|
|
|
117
103
|
completionInbox(onWarn) { return new TiDBWorkflowCompletionInbox(this.pool, onWarn); } // P1: cross-replica push half
|
|
118
104
|
notifyJournal() { return new TiDBWorkflowNotifyJournalStore(this.pool); } // 1.108: cross-replica at-least-once notify
|
|
119
105
|
checkpoint(logger) { return new TiDBCheckpointStore(this.pool, logger); }
|
|
120
|
-
approval() { return new TiDBApprovalStore(this.pool); }
|
|
121
106
|
toolResult() { return new TiDBToolResultStore(this.pool); }
|
|
122
107
|
imageIndex() { return new TiDBImageIndex(this.pool); }
|
|
123
108
|
imageBake() { return new TiDBImageBake(this.pool); }
|
|
@@ -151,7 +136,6 @@ class PgBackend {
|
|
|
151
136
|
completionInbox(onWarn) { return new PgWorkflowCompletionInbox(this.pool, onWarn); } // P1: cross-replica push half
|
|
152
137
|
notifyJournal() { return new PgWorkflowNotifyJournalStore(this.pool); } // 1.108: cross-replica at-least-once notify
|
|
153
138
|
checkpoint(logger) { return new PgCheckpointStore(this.pool, logger); }
|
|
154
|
-
approval() { return new PgApprovalStore(this.pool); }
|
|
155
139
|
toolResult() { return new PgToolResultStore(this.pool); }
|
|
156
140
|
imageIndex() { return new PgImageIndex(this.pool); }
|
|
157
141
|
imageBake() { return new PgImageBake(this.pool); }
|