@sema-agent/server 1.314.0 → 1.316.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 (146) hide show
  1. package/dist/approval-hmac.d.ts +17 -0
  2. package/dist/approval-hmac.js +27 -0
  3. package/dist/config-center/apply-effective.d.ts +22 -0
  4. package/dist/config-center/apply-effective.js +283 -0
  5. package/dist/config-center/http-client.d.ts +23 -0
  6. package/dist/config-center/http-client.js +109 -0
  7. package/dist/config-center/restart-signal.d.ts +12 -0
  8. package/dist/config-center/restart-signal.js +70 -0
  9. package/dist/config-center/skills-mcp.d.ts +13 -0
  10. package/dist/config-center/skills-mcp.js +113 -0
  11. package/dist/config-center/types.d.ts +143 -0
  12. package/dist/config-center/types.js +2 -0
  13. package/dist/fleet/fleet-bus.js +92 -83
  14. package/dist/hooks/hook-runner.js +18 -9
  15. package/dist/http/idempotency.d.ts +1 -0
  16. package/dist/http/idempotency.js +3 -0
  17. package/dist/http/principal-gate.d.ts +12 -0
  18. package/dist/http/principal-gate.js +52 -0
  19. package/dist/http/route-ctx.d.ts +67 -0
  20. package/dist/http/route-ctx.js +2 -0
  21. package/dist/http/routes/attachments.d.ts +4 -0
  22. package/dist/http/routes/attachments.js +106 -0
  23. package/dist/http/routes/capabilities.d.ts +4 -0
  24. package/dist/http/routes/capabilities.js +111 -0
  25. package/dist/http/routes/images.d.ts +20 -0
  26. package/dist/http/routes/images.js +572 -0
  27. package/dist/http/routes/memory-policy.d.ts +4 -0
  28. package/dist/http/routes/memory-policy.js +105 -0
  29. package/dist/http/routes/observability.d.ts +4 -0
  30. package/dist/http/routes/observability.js +63 -0
  31. package/dist/http/routes/session-sync.d.ts +36 -0
  32. package/dist/http/routes/session-sync.js +513 -0
  33. package/dist/http/routes/sessions-list.d.ts +4 -0
  34. package/dist/http/routes/sessions-list.js +117 -0
  35. package/dist/http/routes/sessions.d.ts +17 -0
  36. package/dist/http/routes/sessions.js +746 -0
  37. package/dist/http/send.d.ts +6 -0
  38. package/dist/http/send.js +19 -0
  39. package/dist/http/server.d.ts +101 -76
  40. package/dist/http/server.js +129 -2410
  41. package/dist/http/sse-log.d.ts +25 -0
  42. package/dist/http/sse-log.js +59 -0
  43. package/dist/http/workspace-content.d.ts +3 -0
  44. package/dist/http/workspace-content.js +20 -0
  45. package/dist/index.d.ts +1 -1
  46. package/dist/leader/leader.js +5 -2
  47. package/dist/leader/wire.js +169 -165
  48. package/dist/main.js +462 -451
  49. package/dist/plugins/approval-store-sql.d.ts +52 -0
  50. package/dist/plugins/approval-store-sql.js +119 -0
  51. package/dist/plugins/breaker-state-sql.d.ts +29 -0
  52. package/dist/plugins/breaker-state-sql.js +104 -0
  53. package/dist/plugins/checkpoint-store-sql.d.ts +67 -0
  54. package/dist/plugins/checkpoint-store-sql.js +224 -0
  55. package/dist/plugins/file-snapshot-store-sql.d.ts +38 -0
  56. package/dist/plugins/file-snapshot-store-sql.js +210 -0
  57. package/dist/plugins/image-bake-store-sql.d.ts +53 -0
  58. package/dist/plugins/image-bake-store-sql.js +463 -0
  59. package/dist/plugins/image-index-sql.d.ts +33 -0
  60. package/dist/plugins/image-index-sql.js +328 -0
  61. package/dist/plugins/k8s-bg-scripts.d.ts +19 -0
  62. package/dist/plugins/k8s-bg-scripts.js +129 -0
  63. package/dist/plugins/k8s-exec-protocol.d.ts +20 -0
  64. package/dist/plugins/k8s-exec-protocol.js +87 -0
  65. package/dist/plugins/outcome-ledger-sql.d.ts +70 -0
  66. package/dist/plugins/outcome-ledger-sql.js +158 -0
  67. package/dist/plugins/pg-approval-store.d.ts +1 -27
  68. package/dist/plugins/pg-approval-store.js +1 -83
  69. package/dist/plugins/pg-breaker-state.d.ts +1 -19
  70. package/dist/plugins/pg-breaker-state.js +1 -88
  71. package/dist/plugins/pg-checkpoint-store.d.ts +1 -33
  72. package/dist/plugins/pg-checkpoint-store.js +1 -189
  73. package/dist/plugins/pg-cost-quota.js +3 -143
  74. package/dist/plugins/pg-file-snapshot-store.d.ts +1 -27
  75. package/dist/plugins/pg-file-snapshot-store.js +1 -190
  76. package/dist/plugins/pg-image-bake.d.ts +1 -40
  77. package/dist/plugins/pg-image-bake.js +1 -420
  78. package/dist/plugins/pg-image-index.d.ts +1 -21
  79. package/dist/plugins/pg-image-index.js +1 -217
  80. package/dist/plugins/pg-outcome-ledger.d.ts +2 -22
  81. package/dist/plugins/pg-outcome-ledger.js +1 -104
  82. package/dist/plugins/pg-rate-limiter.d.ts +2 -32
  83. package/dist/plugins/pg-rate-limiter.js +4 -147
  84. package/dist/plugins/pg-resume-anchor-store.d.ts +1 -13
  85. package/dist/plugins/pg-resume-anchor-store.js +1 -22
  86. package/dist/plugins/pg-run-store.d.ts +1 -75
  87. package/dist/plugins/pg-run-store.js +1 -287
  88. package/dist/plugins/pg-session-policy-store.d.ts +1 -11
  89. package/dist/plugins/pg-session-policy-store.js +1 -90
  90. package/dist/plugins/pg-tool-result-store.d.ts +1 -15
  91. package/dist/plugins/pg-tool-result-store.js +1 -52
  92. package/dist/plugins/pg-workflow-journal-store.d.ts +1 -20
  93. package/dist/plugins/pg-workflow-journal-store.js +1 -34
  94. package/dist/plugins/pg-workflow-run-store.d.ts +1 -55
  95. package/dist/plugins/pg-workflow-run-store.js +1 -220
  96. package/dist/plugins/remote-env-k8s.d.ts +5 -38
  97. package/dist/plugins/remote-env-k8s.js +7 -213
  98. package/dist/plugins/resume-anchor-store-sql.d.ts +23 -0
  99. package/dist/plugins/resume-anchor-store-sql.js +38 -0
  100. package/dist/plugins/run-store-sql.d.ts +89 -0
  101. package/dist/plugins/run-store-sql.js +397 -0
  102. package/dist/plugins/session-policy-store-sql.d.ts +22 -0
  103. package/dist/plugins/session-policy-store-sql.js +109 -0
  104. package/dist/plugins/sql-driver.d.ts +25 -0
  105. package/dist/plugins/sql-driver.js +59 -0
  106. package/dist/plugins/tidb-approval-store.d.ts +1 -39
  107. package/dist/plugins/tidb-approval-store.js +1 -71
  108. package/dist/plugins/tidb-breaker-state.d.ts +1 -17
  109. package/dist/plugins/tidb-breaker-state.js +1 -74
  110. package/dist/plugins/tidb-checkpoint-store.d.ts +1 -49
  111. package/dist/plugins/tidb-checkpoint-store.js +1 -191
  112. package/dist/plugins/tidb-file-snapshot-store.d.ts +1 -27
  113. package/dist/plugins/tidb-file-snapshot-store.js +1 -192
  114. package/dist/plugins/tidb-image-bake.d.ts +1 -38
  115. package/dist/plugins/tidb-image-bake.js +1 -348
  116. package/dist/plugins/tidb-image-index.d.ts +1 -19
  117. package/dist/plugins/tidb-image-index.js +1 -149
  118. package/dist/plugins/tidb-outcome-ledger.d.ts +1 -57
  119. package/dist/plugins/tidb-outcome-ledger.js +1 -97
  120. package/dist/plugins/tidb-resume-anchor-store.d.ts +1 -13
  121. package/dist/plugins/tidb-resume-anchor-store.js +1 -22
  122. package/dist/plugins/tidb-run-store.d.ts +1 -75
  123. package/dist/plugins/tidb-run-store.js +1 -306
  124. package/dist/plugins/tidb-session-policy-store.d.ts +1 -11
  125. package/dist/plugins/tidb-session-policy-store.js +1 -86
  126. package/dist/plugins/tidb-tool-result-store.d.ts +1 -13
  127. package/dist/plugins/tidb-tool-result-store.js +1 -38
  128. package/dist/plugins/tidb-workflow-journal-store.d.ts +1 -20
  129. package/dist/plugins/tidb-workflow-journal-store.js +1 -34
  130. package/dist/plugins/tidb-workflow-run-store.d.ts +1 -61
  131. package/dist/plugins/tidb-workflow-run-store.js +1 -231
  132. package/dist/plugins/tool-result-store-sql.d.ts +25 -0
  133. package/dist/plugins/tool-result-store-sql.js +69 -0
  134. package/dist/plugins/workflow-journal-store-sql.d.ts +30 -0
  135. package/dist/plugins/workflow-journal-store-sql.js +53 -0
  136. package/dist/plugins/workflow-run-store-sql.d.ts +85 -0
  137. package/dist/plugins/workflow-run-store-sql.js +299 -0
  138. package/dist/plugins/write-behind-counter.d.ts +14 -3
  139. package/dist/plugins/write-behind-counter.js +39 -12
  140. package/dist/principal-jwt.d.ts +44 -0
  141. package/dist/principal-jwt.js +95 -0
  142. package/dist/security.d.ts +2 -58
  143. package/dist/security.js +3 -118
  144. package/dist/sema-registry.d.ts +5 -200
  145. package/dist/sema-registry.js +4 -567
  146. package/package.json +1 -1
@@ -0,0 +1,210 @@
1
+ import { captureManifest, applyManifest, DEFAULT_SNAPSHOT_BOUNDS } from "@sema-agent/core";
2
+ import { createHash } from "node:crypto";
3
+ import { SqlBlobBackend, sqlBlobSizes } from "./blob-backend.js";
4
+ import { mysqlDriver, pgDriver } from "./sql-driver.js";
5
+ export class SqlFileSnapshotStore {
6
+ db;
7
+ pool;
8
+ bounds;
9
+ inFlight = new Set();
10
+ blobs;
11
+ onSkippedVanished = undefined;
12
+ constructor(db, pool, blobBackend, bounds = DEFAULT_SNAPSHOT_BOUNDS) {
13
+ this.db = db;
14
+ this.pool = pool;
15
+ this.bounds = bounds;
16
+ this.blobs = blobBackend ?? new SqlBlobBackend(this.db.dialect, this.pool);
17
+ }
18
+ q(tidb, pg) {
19
+ return this.db.dialect === "tidb" ? tidb : pg;
20
+ }
21
+ async putBlobRow(hash, bytes) {
22
+ await this.blobs.putBlob(hash, bytes);
23
+ }
24
+ async putBlob(hash, bytes) {
25
+ if (createHash("sha256").update(bytes).digest("hex") !== hash) {
26
+ return { ok: false, error: { code: "read_failed", message: `putBlob ${hash} fails content-address integrity — nothing stored` } };
27
+ }
28
+ try {
29
+ await this.putBlobRow(hash, bytes);
30
+ return { ok: true };
31
+ }
32
+ catch (err) {
33
+ return { ok: false, error: { code: "restore_failed", message: `putBlob ${hash} write/upload failed: ${err.message}` } };
34
+ }
35
+ }
36
+ async snapshot(scope, key, env, root, signal) {
37
+ const flightKey = `${scope}\x00${key}`;
38
+ if (this.inFlight.has(flightKey))
39
+ return { ok: true };
40
+ this.inFlight.add(flightKey);
41
+ try {
42
+ if (await this.has(scope, key))
43
+ return { ok: true };
44
+ let cap;
45
+ try {
46
+ cap = await captureManifest(env, root, this.bounds, signal, async (hash, bytes) => {
47
+ await this.putBlobRow(hash, bytes);
48
+ });
49
+ }
50
+ catch (err) {
51
+ return { ok: false, error: { code: "restore_failed", message: `snapshot blob write failed: ${err.message}` } };
52
+ }
53
+ if (!cap.ok)
54
+ return { ok: false, error: cap.error };
55
+ if (cap.skippedVanished > 0 && this.onSkippedVanished) {
56
+ try {
57
+ void Promise.resolve(this.onSkippedVanished(cap.skippedVanished)).catch(() => { });
58
+ }
59
+ catch { }
60
+ }
61
+ await this.tx(async (conn) => {
62
+ const exists = await conn.query(this.q("SELECT 1 FROM snapshot_manifest WHERE scope = ? AND snap_key = ? LIMIT 1", "SELECT 1 FROM snapshot_manifest WHERE scope = $1 AND snap_key = $2 LIMIT 1"), [scope, key]);
63
+ if (exists.rows[0])
64
+ return;
65
+ for (const [relPath, hash] of cap.value) {
66
+ await conn.query(this.q("INSERT INTO snapshot_manifest (scope, snap_key, rel_path, blob_hash) VALUES (?,?,?,?)", "INSERT INTO snapshot_manifest (scope, snap_key, rel_path, blob_hash) VALUES ($1,$2,$3,$4)"), [scope, key, relPath, hash]);
67
+ }
68
+ });
69
+ return { ok: true };
70
+ }
71
+ catch (err) {
72
+ return { ok: false, error: { code: "restore_failed", message: `snapshot persist failed: ${err.message}` } };
73
+ }
74
+ finally {
75
+ this.inFlight.delete(flightKey);
76
+ }
77
+ }
78
+ async importManifest(scope, key, manifest, srcGetBlob) {
79
+ const flightKey = `${scope}\x00${key}`;
80
+ if (this.inFlight.has(flightKey))
81
+ return { ok: true };
82
+ this.inFlight.add(flightKey);
83
+ try {
84
+ if (await this.has(scope, key))
85
+ return { ok: true };
86
+ for (const hash of new Set(manifest.values())) {
87
+ let bytes;
88
+ try {
89
+ bytes = await srcGetBlob(hash);
90
+ }
91
+ catch (err) {
92
+ return { ok: false, error: { code: "read_failed", message: `source blob ${hash} fetch failed: ${err.message}` } };
93
+ }
94
+ if (!bytes)
95
+ return { ok: false, error: { code: "read_failed", message: `missing source blob ${hash}` } };
96
+ if (createHash("sha256").update(bytes).digest("hex") !== hash) {
97
+ return { ok: false, error: { code: "read_failed", message: `source blob ${hash} fails content-address integrity` } };
98
+ }
99
+ await this.putBlobRow(hash, bytes);
100
+ }
101
+ await this.tx(async (conn) => {
102
+ const exists = await conn.query(this.q("SELECT 1 FROM snapshot_manifest WHERE scope = ? AND snap_key = ? LIMIT 1", "SELECT 1 FROM snapshot_manifest WHERE scope = $1 AND snap_key = $2 LIMIT 1"), [scope, key]);
103
+ if (exists.rows[0])
104
+ return;
105
+ for (const [relPath, hash] of manifest) {
106
+ await conn.query(this.q("INSERT INTO snapshot_manifest (scope, snap_key, rel_path, blob_hash) VALUES (?,?,?,?)", "INSERT INTO snapshot_manifest (scope, snap_key, rel_path, blob_hash) VALUES ($1,$2,$3,$4)"), [scope, key, relPath, hash]);
107
+ }
108
+ });
109
+ return { ok: true };
110
+ }
111
+ catch (err) {
112
+ return { ok: false, error: { code: "restore_failed", message: `import persist failed: ${err.message}` } };
113
+ }
114
+ finally {
115
+ this.inFlight.delete(flightKey);
116
+ }
117
+ }
118
+ async restore(scope, key, env, root, signal) {
119
+ try {
120
+ const { rows } = await this.db.query(this.q("SELECT rel_path, blob_hash FROM snapshot_manifest WHERE scope = ? AND snap_key = ?", "SELECT rel_path, blob_hash FROM snapshot_manifest WHERE scope = $1 AND snap_key = $2"), [scope, key]);
121
+ if (rows.length === 0)
122
+ return { ok: false, error: { code: "not_found", message: `no file snapshot for ${scope}/${key}` } };
123
+ const manifest = new Map(rows.map((r) => [String(r.rel_path), String(r.blob_hash)]));
124
+ return await applyManifest(env, root, this.bounds, signal, manifest, (hash) => this.blobs.getBlob(hash));
125
+ }
126
+ catch (err) {
127
+ return { ok: false, error: { code: "restore_failed", message: `restore blob read failed: ${err.message}` } };
128
+ }
129
+ }
130
+ async has(scope, key) {
131
+ const { rows } = await this.db.query(this.q("SELECT 1 FROM snapshot_manifest WHERE scope = ? AND snap_key = ? LIMIT 1", "SELECT 1 FROM snapshot_manifest WHERE scope = $1 AND snap_key = $2 LIMIT 1"), [scope, key]);
132
+ return Boolean(rows[0]);
133
+ }
134
+ async listKeys(scope) {
135
+ const { rows } = await this.db.query(this.q("SELECT DISTINCT snap_key FROM snapshot_manifest WHERE scope = ?", "SELECT DISTINCT snap_key FROM snapshot_manifest WHERE scope = $1"), [scope]);
136
+ return rows.map((r) => String(r.snap_key));
137
+ }
138
+ async exportManifest(scope, key) {
139
+ const { rows } = await this.db.query(this.q("SELECT rel_path, blob_hash FROM snapshot_manifest WHERE scope = ? AND snap_key = ?", "SELECT rel_path, blob_hash FROM snapshot_manifest WHERE scope = $1 AND snap_key = $2"), [scope, key]);
140
+ if (rows.length === 0)
141
+ return null;
142
+ return new Map(rows.map((r) => [String(r.rel_path), String(r.blob_hash)]));
143
+ }
144
+ async getBlob(hash) {
145
+ return this.blobs.getBlob(hash);
146
+ }
147
+ async hasBlobs(hashes) {
148
+ return this.blobs.hasBlobs(hashes);
149
+ }
150
+ async blobSizes(hashes) {
151
+ return sqlBlobSizes(this.db.dialect, this.pool, hashes);
152
+ }
153
+ async reap(scope, keepKeys) {
154
+ return this.tx(async (conn) => {
155
+ const { rows: keys } = await conn.query(this.q("SELECT DISTINCT snap_key FROM snapshot_manifest WHERE scope = ?", "SELECT DISTINCT snap_key FROM snapshot_manifest WHERE scope = $1"), [scope]);
156
+ const drop = keys.map((k) => String(k.snap_key)).filter((k) => !keepKeys.includes(k));
157
+ for (const k of drop) {
158
+ await conn.query(this.q("DELETE FROM snapshot_manifest WHERE scope = ? AND snap_key = ?", "DELETE FROM snapshot_manifest WHERE scope = $1 AND snap_key = $2"), [scope, k]);
159
+ }
160
+ return drop.length;
161
+ });
162
+ }
163
+ async deleteBySession(scope) {
164
+ const { affected } = await this.db.query(this.q("DELETE FROM snapshot_manifest WHERE scope = ?", "DELETE FROM snapshot_manifest WHERE scope = $1"), [scope]);
165
+ return affected;
166
+ }
167
+ async gcOrphanBlobs() {
168
+ const { rows } = await this.db
169
+ .query("SELECT blob_hash FROM snapshot_blob WHERE blob_hash NOT IN (SELECT blob_hash FROM snapshot_manifest)")
170
+ .catch(() => ({ rows: [], affected: 0 }));
171
+ const orphans = rows.map((r) => String(r.blob_hash));
172
+ if (orphans.length === 0)
173
+ return 0;
174
+ return this.blobs.deleteBlobs(orphans);
175
+ }
176
+ async sweepOrphanBlobs() {
177
+ return this.gcOrphanBlobs();
178
+ }
179
+ async tx(fn) {
180
+ const conn = await this.db.connect();
181
+ try {
182
+ await conn.begin();
183
+ const out = await fn(conn);
184
+ await conn.commit();
185
+ return out;
186
+ }
187
+ catch (err) {
188
+ try {
189
+ await conn.rollback();
190
+ }
191
+ catch {
192
+ }
193
+ throw err;
194
+ }
195
+ finally {
196
+ conn.release();
197
+ }
198
+ }
199
+ }
200
+ export class TiDBFileSnapshotStore extends SqlFileSnapshotStore {
201
+ constructor(pool, blobBackend, bounds = DEFAULT_SNAPSHOT_BOUNDS) {
202
+ super(mysqlDriver(pool), pool, blobBackend, bounds);
203
+ }
204
+ }
205
+ export class PgFileSnapshotStore extends SqlFileSnapshotStore {
206
+ constructor(pool, blobBackend, bounds = DEFAULT_SNAPSHOT_BOUNDS) {
207
+ super(pgDriver(pool), pool, blobBackend, bounds);
208
+ }
209
+ }
210
+ //# sourceMappingURL=file-snapshot-store-sql.js.map
@@ -0,0 +1,53 @@
1
+ import type { Pool as MySqlPool } from "mysql2/promise";
2
+ import type { Pool as PgPool, PoolClient } from "pg";
3
+ import { type SqlDriver } from "./sql-driver.js";
4
+ import { type BakeStatus, type BakeState, type BakeRecord, type BakeEvent, type CreateBakeInput, type BakeTerminal } from "./store-contracts.js";
5
+ export declare const PG_IMAGE_BAKE_SCHEMA: string[];
6
+ export declare function ensurePgImageBakeSchema(pool: PgPool | PoolClient, poolName?: string): Promise<void>;
7
+ export declare class SqlImageBake {
8
+ protected readonly db: SqlDriver;
9
+ protected readonly poolName: string;
10
+ constructor(db: SqlDriver, poolName?: string);
11
+ private q;
12
+ private insertParams;
13
+ createBake(input: CreateBakeInput): Promise<{
14
+ created: boolean;
15
+ bake: BakeRecord;
16
+ }>;
17
+ createBakeIfIdle(input: CreateBakeInput): Promise<{
18
+ created: boolean;
19
+ bake: BakeRecord | null;
20
+ }>;
21
+ getBake(bakeId: string): Promise<BakeRecord | null>;
22
+ getBakeByIdem(idemKey: string): Promise<BakeRecord | null>;
23
+ findActiveByArgv(argv: string[]): Promise<BakeRecord | null>;
24
+ findActiveAny(): Promise<BakeRecord | null>;
25
+ findNextQueuedId(): Promise<string | null>;
26
+ claimBake(bakeId: string, runnerId: string, leaseMs: number): Promise<BakeRecord | null>;
27
+ appendEvent(bakeId: string, kind: string, data: unknown, opts?: {
28
+ lineOrd?: number | null;
29
+ level?: string | null;
30
+ }): Promise<number | null>;
31
+ private lineOrdExists;
32
+ maxSeq(bakeId: string): Promise<number>;
33
+ retainedFrom(bakeId: string): Promise<number>;
34
+ getEvents(bakeId: string, afterSeq: number): Promise<BakeEvent[]>;
35
+ setStatus(bakeId: string, status: BakeStatus): Promise<void>;
36
+ setState(bakeId: string, state: BakeState): Promise<void>;
37
+ setTerminal(bakeId: string, t: BakeTerminal): Promise<number>;
38
+ private terminalParamsTidb;
39
+ private terminalParamsPg;
40
+ setIndexId(bakeId: string, indexId: string): Promise<boolean>;
41
+ heartbeatLease(bakeId: string, runnerId: string, leaseMs: number): Promise<boolean>;
42
+ requestCancel(bakeId: string): Promise<boolean>;
43
+ isCancelRequested(bakeId: string): Promise<boolean>;
44
+ reapStaleBakes(olderThanMs: number): Promise<number>;
45
+ private tx;
46
+ }
47
+ export declare class TiDBImageBake extends SqlImageBake {
48
+ constructor(pool: MySqlPool, poolName?: string);
49
+ }
50
+ export declare class PgImageBake extends SqlImageBake {
51
+ constructor(pool: PgPool, poolName?: string);
52
+ }
53
+ //# sourceMappingURL=image-bake-store-sql.d.ts.map