@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.
- package/dist/approval-hmac.d.ts +17 -0
- package/dist/approval-hmac.js +27 -0
- package/dist/config-center/apply-effective.d.ts +22 -0
- package/dist/config-center/apply-effective.js +283 -0
- package/dist/config-center/http-client.d.ts +23 -0
- package/dist/config-center/http-client.js +109 -0
- package/dist/config-center/restart-signal.d.ts +12 -0
- package/dist/config-center/restart-signal.js +70 -0
- package/dist/config-center/skills-mcp.d.ts +13 -0
- package/dist/config-center/skills-mcp.js +113 -0
- package/dist/config-center/types.d.ts +143 -0
- package/dist/config-center/types.js +2 -0
- package/dist/fleet/fleet-bus.js +92 -83
- package/dist/hooks/hook-runner.js +18 -9
- package/dist/http/idempotency.d.ts +1 -0
- package/dist/http/idempotency.js +3 -0
- package/dist/http/principal-gate.d.ts +12 -0
- package/dist/http/principal-gate.js +52 -0
- package/dist/http/route-ctx.d.ts +67 -0
- package/dist/http/route-ctx.js +2 -0
- package/dist/http/routes/attachments.d.ts +4 -0
- package/dist/http/routes/attachments.js +106 -0
- package/dist/http/routes/capabilities.d.ts +4 -0
- package/dist/http/routes/capabilities.js +111 -0
- package/dist/http/routes/images.d.ts +20 -0
- package/dist/http/routes/images.js +572 -0
- package/dist/http/routes/memory-policy.d.ts +4 -0
- package/dist/http/routes/memory-policy.js +105 -0
- package/dist/http/routes/observability.d.ts +4 -0
- package/dist/http/routes/observability.js +63 -0
- package/dist/http/routes/session-sync.d.ts +36 -0
- package/dist/http/routes/session-sync.js +513 -0
- package/dist/http/routes/sessions-list.d.ts +4 -0
- package/dist/http/routes/sessions-list.js +117 -0
- package/dist/http/routes/sessions.d.ts +17 -0
- package/dist/http/routes/sessions.js +746 -0
- package/dist/http/send.d.ts +6 -0
- package/dist/http/send.js +19 -0
- package/dist/http/server.d.ts +101 -76
- package/dist/http/server.js +129 -2410
- package/dist/http/sse-log.d.ts +25 -0
- package/dist/http/sse-log.js +59 -0
- package/dist/http/workspace-content.d.ts +3 -0
- package/dist/http/workspace-content.js +20 -0
- package/dist/index.d.ts +1 -1
- package/dist/leader/leader.js +5 -2
- package/dist/leader/wire.js +169 -165
- package/dist/main.js +462 -451
- package/dist/plugins/approval-store-sql.d.ts +52 -0
- package/dist/plugins/approval-store-sql.js +119 -0
- package/dist/plugins/breaker-state-sql.d.ts +29 -0
- package/dist/plugins/breaker-state-sql.js +104 -0
- package/dist/plugins/checkpoint-store-sql.d.ts +67 -0
- package/dist/plugins/checkpoint-store-sql.js +224 -0
- package/dist/plugins/file-snapshot-store-sql.d.ts +38 -0
- package/dist/plugins/file-snapshot-store-sql.js +210 -0
- package/dist/plugins/image-bake-store-sql.d.ts +53 -0
- package/dist/plugins/image-bake-store-sql.js +463 -0
- package/dist/plugins/image-index-sql.d.ts +33 -0
- package/dist/plugins/image-index-sql.js +328 -0
- package/dist/plugins/k8s-bg-scripts.d.ts +19 -0
- package/dist/plugins/k8s-bg-scripts.js +129 -0
- package/dist/plugins/k8s-exec-protocol.d.ts +20 -0
- package/dist/plugins/k8s-exec-protocol.js +87 -0
- package/dist/plugins/outcome-ledger-sql.d.ts +70 -0
- package/dist/plugins/outcome-ledger-sql.js +158 -0
- package/dist/plugins/pg-approval-store.d.ts +1 -27
- package/dist/plugins/pg-approval-store.js +1 -83
- package/dist/plugins/pg-breaker-state.d.ts +1 -19
- package/dist/plugins/pg-breaker-state.js +1 -88
- package/dist/plugins/pg-checkpoint-store.d.ts +1 -33
- package/dist/plugins/pg-checkpoint-store.js +1 -189
- package/dist/plugins/pg-cost-quota.js +3 -143
- package/dist/plugins/pg-file-snapshot-store.d.ts +1 -27
- package/dist/plugins/pg-file-snapshot-store.js +1 -190
- package/dist/plugins/pg-image-bake.d.ts +1 -40
- package/dist/plugins/pg-image-bake.js +1 -420
- package/dist/plugins/pg-image-index.d.ts +1 -21
- package/dist/plugins/pg-image-index.js +1 -217
- package/dist/plugins/pg-outcome-ledger.d.ts +2 -22
- package/dist/plugins/pg-outcome-ledger.js +1 -104
- package/dist/plugins/pg-rate-limiter.d.ts +2 -32
- package/dist/plugins/pg-rate-limiter.js +4 -147
- package/dist/plugins/pg-resume-anchor-store.d.ts +1 -13
- package/dist/plugins/pg-resume-anchor-store.js +1 -22
- package/dist/plugins/pg-run-store.d.ts +1 -75
- package/dist/plugins/pg-run-store.js +1 -287
- package/dist/plugins/pg-session-policy-store.d.ts +1 -11
- package/dist/plugins/pg-session-policy-store.js +1 -90
- package/dist/plugins/pg-tool-result-store.d.ts +1 -15
- package/dist/plugins/pg-tool-result-store.js +1 -52
- package/dist/plugins/pg-workflow-journal-store.d.ts +1 -20
- package/dist/plugins/pg-workflow-journal-store.js +1 -34
- package/dist/plugins/pg-workflow-run-store.d.ts +1 -55
- package/dist/plugins/pg-workflow-run-store.js +1 -220
- package/dist/plugins/remote-env-k8s.d.ts +5 -38
- package/dist/plugins/remote-env-k8s.js +7 -213
- package/dist/plugins/resume-anchor-store-sql.d.ts +23 -0
- package/dist/plugins/resume-anchor-store-sql.js +38 -0
- package/dist/plugins/run-store-sql.d.ts +89 -0
- package/dist/plugins/run-store-sql.js +397 -0
- package/dist/plugins/session-policy-store-sql.d.ts +22 -0
- package/dist/plugins/session-policy-store-sql.js +109 -0
- package/dist/plugins/sql-driver.d.ts +25 -0
- package/dist/plugins/sql-driver.js +59 -0
- package/dist/plugins/tidb-approval-store.d.ts +1 -39
- package/dist/plugins/tidb-approval-store.js +1 -71
- package/dist/plugins/tidb-breaker-state.d.ts +1 -17
- package/dist/plugins/tidb-breaker-state.js +1 -74
- package/dist/plugins/tidb-checkpoint-store.d.ts +1 -49
- package/dist/plugins/tidb-checkpoint-store.js +1 -191
- package/dist/plugins/tidb-file-snapshot-store.d.ts +1 -27
- package/dist/plugins/tidb-file-snapshot-store.js +1 -192
- package/dist/plugins/tidb-image-bake.d.ts +1 -38
- package/dist/plugins/tidb-image-bake.js +1 -348
- package/dist/plugins/tidb-image-index.d.ts +1 -19
- package/dist/plugins/tidb-image-index.js +1 -149
- package/dist/plugins/tidb-outcome-ledger.d.ts +1 -57
- package/dist/plugins/tidb-outcome-ledger.js +1 -97
- package/dist/plugins/tidb-resume-anchor-store.d.ts +1 -13
- package/dist/plugins/tidb-resume-anchor-store.js +1 -22
- package/dist/plugins/tidb-run-store.d.ts +1 -75
- package/dist/plugins/tidb-run-store.js +1 -306
- package/dist/plugins/tidb-session-policy-store.d.ts +1 -11
- package/dist/plugins/tidb-session-policy-store.js +1 -86
- package/dist/plugins/tidb-tool-result-store.d.ts +1 -13
- package/dist/plugins/tidb-tool-result-store.js +1 -38
- package/dist/plugins/tidb-workflow-journal-store.d.ts +1 -20
- package/dist/plugins/tidb-workflow-journal-store.js +1 -34
- package/dist/plugins/tidb-workflow-run-store.d.ts +1 -61
- package/dist/plugins/tidb-workflow-run-store.js +1 -231
- package/dist/plugins/tool-result-store-sql.d.ts +25 -0
- package/dist/plugins/tool-result-store-sql.js +69 -0
- package/dist/plugins/workflow-journal-store-sql.d.ts +30 -0
- package/dist/plugins/workflow-journal-store-sql.js +53 -0
- package/dist/plugins/workflow-run-store-sql.d.ts +85 -0
- package/dist/plugins/workflow-run-store-sql.js +299 -0
- package/dist/plugins/write-behind-counter.d.ts +14 -3
- package/dist/plugins/write-behind-counter.js +39 -12
- package/dist/principal-jwt.d.ts +44 -0
- package/dist/principal-jwt.js +95 -0
- package/dist/security.d.ts +2 -58
- package/dist/security.js +3 -118
- package/dist/sema-registry.d.ts +5 -200
- package/dist/sema-registry.js +4 -567
- package/package.json +1 -1
|
@@ -1,23 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import type { TaskOutcome as CoreTaskOutcome } from "@sema-agent/core";
|
|
4
|
-
export declare const PG_OUTCOME_LEDGER_SCHEMA: string[];
|
|
5
|
-
export declare function ensureSchema(pool: Pool | PoolClient): Promise<void>;
|
|
6
|
-
export declare class PgOutcomeLedger {
|
|
7
|
-
private readonly pool;
|
|
8
|
-
constructor(pool: Pool);
|
|
9
|
-
record(o: TaskOutcome): Promise<string>;
|
|
10
|
-
recordCore(o: CoreTaskOutcome): Promise<void>;
|
|
11
|
-
summary(opts?: {
|
|
12
|
-
taskSignature?: string;
|
|
13
|
-
includeAborted?: boolean;
|
|
14
|
-
}): Promise<Array<{
|
|
15
|
-
taskSignature: string;
|
|
16
|
-
model: string;
|
|
17
|
-
n: number;
|
|
18
|
-
passRate: number;
|
|
19
|
-
meanCostMicroUsd: number;
|
|
20
|
-
}>>;
|
|
21
|
-
}
|
|
22
|
-
export type { TaskOutcome, RunStatus };
|
|
1
|
+
export { PgOutcomeLedger, PG_OUTCOME_LEDGER_SCHEMA, ensurePgOutcomeLedgerSchema as ensureSchema, } from "./outcome-ledger-sql.js";
|
|
2
|
+
export type { TaskOutcome, RunStatus } from "./outcome-ledger-sql.js";
|
|
23
3
|
//# sourceMappingURL=pg-outcome-ledger.d.ts.map
|
|
@@ -1,105 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
import { taskSignature, deriveOutcome, } from "./tidb-outcome-ledger.js";
|
|
3
|
-
import { coreOutcomeToLedgerRow } from "./tidb-outcome-ledger.js";
|
|
4
|
-
import { pgSafeJsonStringify } from "./pg-safe-json.js";
|
|
5
|
-
export const PG_OUTCOME_LEDGER_SCHEMA = [
|
|
6
|
-
`CREATE TABLE IF NOT EXISTS outcome_ledger (
|
|
7
|
-
id VARCHAR(64) NOT NULL,
|
|
8
|
-
task_signature VARCHAR(190) NOT NULL,
|
|
9
|
-
model VARCHAR(190) NOT NULL,
|
|
10
|
-
task_id VARCHAR(64),
|
|
11
|
-
run_status VARCHAR(20) NOT NULL DEFAULT 'completed-graded',
|
|
12
|
-
route VARCHAR(16),
|
|
13
|
-
worker_count INTEGER,
|
|
14
|
-
oracle_passed INTEGER,
|
|
15
|
-
oracle_total INTEGER,
|
|
16
|
-
assemble_exit INTEGER,
|
|
17
|
-
lint_exit INTEGER,
|
|
18
|
-
merge_ok SMALLINT,
|
|
19
|
-
replan_triggers JSONB,
|
|
20
|
-
cost_micro_usd BIGINT,
|
|
21
|
-
turns INTEGER,
|
|
22
|
-
outcome VARCHAR(8),
|
|
23
|
-
llm_assisted JSONB,
|
|
24
|
-
signature_inputs JSONB,
|
|
25
|
-
-- design/73 §1 bridge: the VERBATIM core TaskOutcome fact (oracleHadRedRun / status / oracle blob) as it
|
|
26
|
-
-- came off core, kept alongside the derived mechanical columns. NULL when the caller recorded through the
|
|
27
|
-
-- non-core \`record()\` path (no core fact to bridge).
|
|
28
|
-
core_outcome JSONB,
|
|
29
|
-
created_at TIMESTAMPTZ(3) NOT NULL,
|
|
30
|
-
PRIMARY KEY (id)
|
|
31
|
-
)`,
|
|
32
|
-
`CREATE INDEX IF NOT EXISTS idx_outcome_ledger_sig_model ON outcome_ledger (task_signature, model, run_status)`,
|
|
33
|
-
`CREATE INDEX IF NOT EXISTS idx_outcome_ledger_outcome ON outcome_ledger (outcome)`,
|
|
34
|
-
`CREATE INDEX IF NOT EXISTS idx_outcome_ledger_created ON outcome_ledger (created_at)`,
|
|
35
|
-
];
|
|
36
|
-
export async function ensureSchema(pool) {
|
|
37
|
-
for (const stmt of PG_OUTCOME_LEDGER_SCHEMA)
|
|
38
|
-
await pool.query(stmt);
|
|
39
|
-
}
|
|
40
|
-
export class PgOutcomeLedger {
|
|
41
|
-
pool;
|
|
42
|
-
constructor(pool) {
|
|
43
|
-
this.pool = pool;
|
|
44
|
-
}
|
|
45
|
-
async record(o) {
|
|
46
|
-
const id = randomUUID().replace(/-/g, "").slice(0, 32);
|
|
47
|
-
const sig = taskSignature(o.signatureInputs);
|
|
48
|
-
const m = o.mechanical;
|
|
49
|
-
const runStatus = o.runStatus ?? "completed-graded";
|
|
50
|
-
await this.pool.query(`INSERT INTO outcome_ledger
|
|
51
|
-
(id, task_signature, model, task_id, run_status, route, worker_count, oracle_passed, oracle_total,
|
|
52
|
-
assemble_exit, lint_exit, merge_ok, replan_triggers, cost_micro_usd, turns, outcome,
|
|
53
|
-
llm_assisted, signature_inputs, core_outcome, created_at)
|
|
54
|
-
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13::jsonb,$14,$15,$16,$17::jsonb,$18::jsonb,$19::jsonb,$20)`, [
|
|
55
|
-
id,
|
|
56
|
-
sig,
|
|
57
|
-
o.model,
|
|
58
|
-
o.taskId ?? null,
|
|
59
|
-
runStatus,
|
|
60
|
-
m.route ?? null,
|
|
61
|
-
m.workerCount ?? null,
|
|
62
|
-
m.oraclePassed ?? null,
|
|
63
|
-
m.oracleTotal ?? null,
|
|
64
|
-
m.assembleExit ?? null,
|
|
65
|
-
m.lintExit ?? null,
|
|
66
|
-
m.mergeOk == null ? null : m.mergeOk ? 1 : 0,
|
|
67
|
-
m.replanTriggers ? pgSafeJsonStringify(m.replanTriggers) : null,
|
|
68
|
-
m.costMicroUsd ?? null,
|
|
69
|
-
m.turns ?? null,
|
|
70
|
-
deriveOutcome(m, runStatus),
|
|
71
|
-
o.llmAssisted ? pgSafeJsonStringify(o.llmAssisted) : null,
|
|
72
|
-
pgSafeJsonStringify(o.signatureInputs),
|
|
73
|
-
o.core != null ? pgSafeJsonStringify(o.core) : null,
|
|
74
|
-
new Date(),
|
|
75
|
-
]);
|
|
76
|
-
return id;
|
|
77
|
-
}
|
|
78
|
-
async recordCore(o) {
|
|
79
|
-
await this.record(coreOutcomeToLedgerRow(o));
|
|
80
|
-
}
|
|
81
|
-
async summary(opts = {}) {
|
|
82
|
-
const clauses = [];
|
|
83
|
-
const params = [];
|
|
84
|
-
if (!opts.includeAborted)
|
|
85
|
-
clauses.push("run_status = 'completed-graded'");
|
|
86
|
-
if (opts.taskSignature) {
|
|
87
|
-
params.push(opts.taskSignature);
|
|
88
|
-
clauses.push(`task_signature = $${params.length}`);
|
|
89
|
-
}
|
|
90
|
-
const where = clauses.length ? `WHERE ${clauses.join(" AND ")}` : "";
|
|
91
|
-
const res = await this.pool.query(`SELECT task_signature, model, COUNT(*) n,
|
|
92
|
-
AVG((outcome = 'pass')::int) pass_rate, AVG(cost_micro_usd) mean_cost
|
|
93
|
-
FROM outcome_ledger ${where}
|
|
94
|
-
GROUP BY task_signature, model
|
|
95
|
-
ORDER BY task_signature, model`, params);
|
|
96
|
-
return res.rows.map((r) => ({
|
|
97
|
-
taskSignature: String(r.task_signature),
|
|
98
|
-
model: String(r.model),
|
|
99
|
-
n: Number(r.n),
|
|
100
|
-
passRate: Number(r.pass_rate),
|
|
101
|
-
meanCostMicroUsd: Number(r.mean_cost ?? 0),
|
|
102
|
-
}));
|
|
103
|
-
}
|
|
104
|
-
}
|
|
1
|
+
export { PgOutcomeLedger, PG_OUTCOME_LEDGER_SCHEMA, ensurePgOutcomeLedgerSchema as ensureSchema, } from "./outcome-ledger-sql.js";
|
|
105
2
|
//# sourceMappingURL=pg-outcome-ledger.js.map
|
|
@@ -1,38 +1,8 @@
|
|
|
1
1
|
import type { Pool, PoolClient } from "pg";
|
|
2
2
|
import type { RateDecision, RateGate } from "../observability/rate-limit.js";
|
|
3
3
|
import { type CounterDegradeHook } from "./write-behind-counter.js";
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
keyCol: string;
|
|
7
|
-
valCol: string;
|
|
8
|
-
}
|
|
9
|
-
export declare class PgWriteBehindCounter {
|
|
10
|
-
private readonly pool;
|
|
11
|
-
private readonly t;
|
|
12
|
-
private readonly windowMs;
|
|
13
|
-
private readonly now;
|
|
14
|
-
private readonly onDegraded?;
|
|
15
|
-
private readonly queryTimeoutMs;
|
|
16
|
-
private pendingDelta;
|
|
17
|
-
private fleetTotal;
|
|
18
|
-
private timer?;
|
|
19
|
-
private flushing;
|
|
20
|
-
private flushStartedAt;
|
|
21
|
-
private failStreak;
|
|
22
|
-
constructor(pool: Pool, t: CounterTable, windowMs: number, now?: () => number, onDegraded?: CounterDegradeHook | undefined, queryTimeoutMs?: number);
|
|
23
|
-
private bump;
|
|
24
|
-
bucket(): number;
|
|
25
|
-
private rk;
|
|
26
|
-
used(key: string): number;
|
|
27
|
-
addLocal(key: string, n: number): void;
|
|
28
|
-
retryAfterSec(): number;
|
|
29
|
-
flush(): Promise<void>;
|
|
30
|
-
private flushOnce;
|
|
31
|
-
refresh(): Promise<void>;
|
|
32
|
-
reap(): Promise<number>;
|
|
33
|
-
startRefresh(intervalMs?: number): this;
|
|
34
|
-
stop(): void;
|
|
35
|
-
}
|
|
4
|
+
export { PgWriteBehindCounter } from "./write-behind-counter.js";
|
|
5
|
+
export type { CounterTable } from "./write-behind-counter.js";
|
|
36
6
|
export declare class PgRateLimiter implements RateGate {
|
|
37
7
|
private readonly limit;
|
|
38
8
|
private readonly counter;
|
|
@@ -1,155 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
pool;
|
|
5
|
-
t;
|
|
6
|
-
windowMs;
|
|
7
|
-
now;
|
|
8
|
-
onDegraded;
|
|
9
|
-
queryTimeoutMs;
|
|
10
|
-
pendingDelta = new Map();
|
|
11
|
-
fleetTotal = new Map();
|
|
12
|
-
timer;
|
|
13
|
-
flushing = false;
|
|
14
|
-
flushStartedAt = 0;
|
|
15
|
-
failStreak = new Map();
|
|
16
|
-
constructor(pool, t, windowMs, now = () => Date.now(), onDegraded, queryTimeoutMs = DEFAULT_COUNTER_QUERY_TIMEOUT_MS) {
|
|
17
|
-
this.pool = pool;
|
|
18
|
-
this.t = t;
|
|
19
|
-
this.windowMs = windowMs;
|
|
20
|
-
this.now = now;
|
|
21
|
-
this.onDegraded = onDegraded;
|
|
22
|
-
this.queryTimeoutMs = queryTimeoutMs;
|
|
23
|
-
}
|
|
24
|
-
bump(kind, failed, error) {
|
|
25
|
-
if (!this.onDegraded)
|
|
26
|
-
return;
|
|
27
|
-
const prev = this.failStreak.get(kind) ?? 0;
|
|
28
|
-
if (!failed && prev === 0)
|
|
29
|
-
return;
|
|
30
|
-
const next = failed ? prev + 1 : 0;
|
|
31
|
-
this.failStreak.set(kind, next);
|
|
32
|
-
try {
|
|
33
|
-
this.onDegraded({ table: this.t.table, kind, streak: next, prevStreak: prev, ...(failed && error !== undefined ? { error: error instanceof Error ? error.message : String(error) } : {}) });
|
|
34
|
-
}
|
|
35
|
-
catch {
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
bucket() {
|
|
39
|
-
return Math.floor(this.now() / this.windowMs);
|
|
40
|
-
}
|
|
41
|
-
rk(key) {
|
|
42
|
-
return `${key}${SEP}${this.bucket()}`;
|
|
43
|
-
}
|
|
44
|
-
used(key) {
|
|
45
|
-
const rk = this.rk(key);
|
|
46
|
-
return (this.fleetTotal.get(rk) ?? 0) + (this.pendingDelta.get(rk) ?? 0);
|
|
47
|
-
}
|
|
48
|
-
addLocal(key, n) {
|
|
49
|
-
if (n <= 0)
|
|
50
|
-
return;
|
|
51
|
-
const rk = this.rk(key);
|
|
52
|
-
this.pendingDelta.set(rk, (this.pendingDelta.get(rk) ?? 0) + n);
|
|
53
|
-
}
|
|
54
|
-
retryAfterSec() {
|
|
55
|
-
return Math.ceil(((this.bucket() + 1) * this.windowMs - this.now()) / 1000);
|
|
56
|
-
}
|
|
57
|
-
async flush() {
|
|
58
|
-
if (this.flushing) {
|
|
59
|
-
if (this.now() - this.flushStartedAt > 60_000)
|
|
60
|
-
this.bump("stalled", true, "flush round stalled >60s (hung query?)");
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
this.flushing = true;
|
|
64
|
-
this.flushStartedAt = this.now();
|
|
65
|
-
try {
|
|
66
|
-
await this.flushOnce();
|
|
67
|
-
}
|
|
68
|
-
finally {
|
|
69
|
-
this.flushing = false;
|
|
70
|
-
this.bump("stalled", false);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
async flushOnce() {
|
|
74
|
-
const { table, keyCol, valCol } = this.t;
|
|
75
|
-
let attempted = false;
|
|
76
|
-
let failure;
|
|
77
|
-
let hadFailure = false;
|
|
78
|
-
for (const [rk, delta] of [...this.pendingDelta]) {
|
|
79
|
-
if (delta <= 0)
|
|
80
|
-
continue;
|
|
81
|
-
const sep = rk.lastIndexOf(SEP);
|
|
82
|
-
const key = rk.slice(0, sep);
|
|
83
|
-
const windowBucket = Number(rk.slice(sep + 1));
|
|
84
|
-
attempted = true;
|
|
85
|
-
try {
|
|
86
|
-
const q = {
|
|
87
|
-
text: `INSERT INTO ${table} (${keyCol}, window_bucket, ${valCol}, updated_at) VALUES ($1,$2,$3,$4) ` +
|
|
88
|
-
`ON CONFLICT (${keyCol}, window_bucket) DO UPDATE SET ${valCol} = ${table}.${valCol} + EXCLUDED.${valCol}, updated_at = EXCLUDED.updated_at`,
|
|
89
|
-
values: [key, windowBucket, delta, new Date()],
|
|
90
|
-
query_timeout: this.queryTimeoutMs,
|
|
91
|
-
};
|
|
92
|
-
await this.pool.query(q);
|
|
93
|
-
const remaining = (this.pendingDelta.get(rk) ?? 0) - delta;
|
|
94
|
-
if (remaining > 0)
|
|
95
|
-
this.pendingDelta.set(rk, remaining);
|
|
96
|
-
else
|
|
97
|
-
this.pendingDelta.delete(rk);
|
|
98
|
-
}
|
|
99
|
-
catch (err) {
|
|
100
|
-
hadFailure = true;
|
|
101
|
-
failure = err;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
if (attempted)
|
|
105
|
-
this.bump("flush", hadFailure, failure);
|
|
106
|
-
await this.refresh();
|
|
107
|
-
await this.reap();
|
|
108
|
-
}
|
|
109
|
-
async refresh() {
|
|
110
|
-
const { table, keyCol, valCol } = this.t;
|
|
111
|
-
const b = this.bucket();
|
|
112
|
-
try {
|
|
113
|
-
const q = { text: `SELECT ${keyCol}, ${valCol} FROM ${table} WHERE window_bucket = $1`, values: [b], query_timeout: this.queryTimeoutMs };
|
|
114
|
-
const res = await this.pool.query(q);
|
|
115
|
-
const next = new Map();
|
|
116
|
-
for (const row of res.rows) {
|
|
117
|
-
next.set(`${String(row[keyCol])}${SEP}${b}`, Number(row[valCol]));
|
|
118
|
-
}
|
|
119
|
-
this.fleetTotal = next;
|
|
120
|
-
this.bump("refresh", false);
|
|
121
|
-
}
|
|
122
|
-
catch (err) {
|
|
123
|
-
this.bump("refresh", true, err);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
async reap() {
|
|
127
|
-
try {
|
|
128
|
-
const q = { text: `DELETE FROM ${this.t.table} WHERE window_bucket < $1`, values: [this.bucket()], query_timeout: this.queryTimeoutMs };
|
|
129
|
-
const res = await this.pool.query(q);
|
|
130
|
-
return res.rowCount ?? 0;
|
|
131
|
-
}
|
|
132
|
-
catch {
|
|
133
|
-
return 0;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
startRefresh(intervalMs = 5_000) {
|
|
137
|
-
this.timer ??= setInterval(() => void this.flush(), intervalMs);
|
|
138
|
-
this.timer.unref?.();
|
|
139
|
-
return this;
|
|
140
|
-
}
|
|
141
|
-
stop() {
|
|
142
|
-
if (this.timer)
|
|
143
|
-
clearInterval(this.timer);
|
|
144
|
-
this.timer = undefined;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
1
|
+
import { PgWriteBehindCounter } from "./write-behind-counter.js";
|
|
2
|
+
export { PgWriteBehindCounter } from "./write-behind-counter.js";
|
|
3
|
+
const RATE_LIMIT_TABLE = { table: "rate_limit", keyCol: "limit_key", valCol: "n" };
|
|
147
4
|
export class PgRateLimiter {
|
|
148
5
|
limit;
|
|
149
6
|
counter;
|
|
150
7
|
constructor(pool, limit, windowMs = 60_000, now, onDegraded, queryTimeoutMs) {
|
|
151
8
|
this.limit = limit;
|
|
152
|
-
this.counter = new PgWriteBehindCounter(pool,
|
|
9
|
+
this.counter = new PgWriteBehindCounter(pool, RATE_LIMIT_TABLE, windowMs, now, onDegraded, queryTimeoutMs);
|
|
153
10
|
}
|
|
154
11
|
check(key) {
|
|
155
12
|
if (this.limit <= 0)
|
|
@@ -1,14 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
export declare class PgResumeAnchorStore {
|
|
3
|
-
private readonly pool;
|
|
4
|
-
constructor(pool: Pool);
|
|
5
|
-
put(sessionId: string, eventId: string, entryId: string, owner: string | null): Promise<void>;
|
|
6
|
-
resolve(sessionId: string, eventId: string, owner: string | null): Promise<string | undefined>;
|
|
7
|
-
listBySession(sessionId: string): Promise<Array<{
|
|
8
|
-
eventId: string;
|
|
9
|
-
entryId: string;
|
|
10
|
-
owner: string | null;
|
|
11
|
-
}>>;
|
|
12
|
-
deleteBySession(sessionId: string): Promise<number>;
|
|
13
|
-
}
|
|
1
|
+
export { PgResumeAnchorStore } from "./resume-anchor-store-sql.js";
|
|
14
2
|
//# sourceMappingURL=pg-resume-anchor-store.d.ts.map
|
|
@@ -1,23 +1,2 @@
|
|
|
1
|
-
export
|
|
2
|
-
pool;
|
|
3
|
-
constructor(pool) {
|
|
4
|
-
this.pool = pool;
|
|
5
|
-
}
|
|
6
|
-
async put(sessionId, eventId, entryId, owner) {
|
|
7
|
-
await this.pool.query("INSERT INTO resume_anchor (session_id, event_id, entry_id, owner, created_at) VALUES ($1,$2,$3,$4,$5) " +
|
|
8
|
-
"ON CONFLICT (session_id, event_id) DO UPDATE SET entry_id = EXCLUDED.entry_id, owner = EXCLUDED.owner", [sessionId, eventId, entryId, owner, new Date()]);
|
|
9
|
-
}
|
|
10
|
-
async resolve(sessionId, eventId, owner) {
|
|
11
|
-
const r = await this.pool.query("SELECT entry_id FROM resume_anchor WHERE session_id = $1 AND event_id = $2 AND owner IS NOT DISTINCT FROM $3", [sessionId, eventId, owner]);
|
|
12
|
-
return r.rows[0] ? String(r.rows[0].entry_id) : undefined;
|
|
13
|
-
}
|
|
14
|
-
async listBySession(sessionId) {
|
|
15
|
-
const r = await this.pool.query("SELECT event_id, entry_id, owner FROM resume_anchor WHERE session_id = $1", [sessionId]);
|
|
16
|
-
return r.rows.map((row) => ({ eventId: String(row.event_id), entryId: String(row.entry_id), owner: row.owner == null ? null : String(row.owner) }));
|
|
17
|
-
}
|
|
18
|
-
async deleteBySession(sessionId) {
|
|
19
|
-
const r = await this.pool.query("DELETE FROM resume_anchor WHERE session_id = $1", [sessionId]);
|
|
20
|
-
return r.rowCount ?? 0;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
1
|
+
export { PgResumeAnchorStore } from "./resume-anchor-store-sql.js";
|
|
23
2
|
//# sourceMappingURL=pg-resume-anchor-store.js.map
|
|
@@ -1,76 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
import { type UsageRow } from "../usage-analytics.js";
|
|
3
|
-
import type { Pool } from "pg";
|
|
4
|
-
import type { RunRecord, RunEvent, SessionSummary } from "./store-contracts.js";
|
|
5
|
-
export declare class PgRunStore {
|
|
6
|
-
private readonly pool;
|
|
7
|
-
constructor(pool: Pool);
|
|
8
|
-
private tx;
|
|
9
|
-
createRun(taskId: string, sessionId: string, owner: string | null, instanceId: string, meta?: {
|
|
10
|
-
jobId?: string | null;
|
|
11
|
-
source?: string | null;
|
|
12
|
-
objectivePreview?: string | null;
|
|
13
|
-
}): Promise<{
|
|
14
|
-
ok: true;
|
|
15
|
-
} | {
|
|
16
|
-
ok: false;
|
|
17
|
-
activeTaskId: string;
|
|
18
|
-
}>;
|
|
19
|
-
requestCancel(taskId: string, owner: string | null): Promise<boolean>;
|
|
20
|
-
isCancelRequested(taskId: string, owner: string | null): Promise<boolean>;
|
|
21
|
-
requestPreempt(taskId: string, owner: string | null): Promise<boolean>;
|
|
22
|
-
isPreemptRequested(taskId: string, owner: string | null): Promise<boolean>;
|
|
23
|
-
heartbeat(taskId: string, owner: string | null): Promise<void>;
|
|
24
|
-
appendEvent(taskId: string, seq: number, type: string, data: unknown): Promise<void>;
|
|
25
|
-
maxSeq(taskId: string): Promise<number>;
|
|
26
|
-
setTerminal(taskId: string, status: TaskStatus, result: TaskResult | null, error: string | null): Promise<void>;
|
|
27
|
-
setSuspended(taskId: string): Promise<void>;
|
|
28
|
-
setNeedsReview(taskId: string): Promise<void>;
|
|
29
|
-
markResuming(taskId: string): Promise<boolean>;
|
|
30
|
-
getActiveTaskId(sessionId: string): Promise<string | undefined>;
|
|
31
|
-
private rowToRun;
|
|
32
|
-
getRun(taskId: string): Promise<RunRecord | undefined>;
|
|
33
|
-
listRuns(opts: {
|
|
34
|
-
status?: string;
|
|
35
|
-
jobId?: string;
|
|
36
|
-
source?: string;
|
|
37
|
-
owner?: string;
|
|
38
|
-
cursor?: {
|
|
39
|
-
createdAt: string;
|
|
40
|
-
taskId: string;
|
|
41
|
-
};
|
|
42
|
-
limit: number;
|
|
43
|
-
}): Promise<RunRecord[]>;
|
|
44
|
-
listSessions(opts: {
|
|
45
|
-
owner?: string;
|
|
46
|
-
cursor?: {
|
|
47
|
-
lastActivityAt: string;
|
|
48
|
-
sessionId: string;
|
|
49
|
-
};
|
|
50
|
-
limit: number;
|
|
51
|
-
q?: string;
|
|
52
|
-
}): Promise<SessionSummary[]>;
|
|
53
|
-
deleteBySession(sessionId: string, owner: string | null): Promise<{
|
|
54
|
-
removed: number;
|
|
55
|
-
} | {
|
|
56
|
-
active: string;
|
|
57
|
-
}>;
|
|
58
|
-
sourceSummary(sinceMs: number): Promise<Array<{
|
|
59
|
-
source: string | null;
|
|
60
|
-
status: string;
|
|
61
|
-
count: number;
|
|
62
|
-
}>>;
|
|
63
|
-
usageScan(fromMs: number, toMs: number, opts?: {
|
|
64
|
-
owner?: string;
|
|
65
|
-
limit?: number;
|
|
66
|
-
}): Promise<{
|
|
67
|
-
rows: UsageRow[];
|
|
68
|
-
truncated: boolean;
|
|
69
|
-
}>;
|
|
70
|
-
retainedFrom(taskId: string): Promise<number>;
|
|
71
|
-
getEvents(taskId: string, afterSeq: number): Promise<RunEvent[]>;
|
|
72
|
-
reapStale(olderThanMs: number): Promise<number>;
|
|
73
|
-
reapSuspended(olderThanMs: number): Promise<number>;
|
|
74
|
-
failSuspendedWithExpiredCheckpoint(): Promise<number>;
|
|
75
|
-
}
|
|
1
|
+
export { PgRunStore } from "./run-store-sql.js";
|
|
76
2
|
//# sourceMappingURL=pg-run-store.d.ts.map
|