@sema-agent/server 1.315.0 → 1.317.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/README.md +9 -0
- package/README.zh-CN.md +7 -0
- package/dist/config-types.d.ts +1 -1
- package/dist/config.d.ts +14 -0
- package/dist/config.js +148 -45
- package/dist/elicitation.js +2 -2
- 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 +116 -0
- package/dist/http/route-ctx.js +2 -0
- package/dist/http/routes/approvals-assistant.d.ts +11 -0
- package/dist/http/routes/approvals-assistant.js +530 -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/fleet.d.ts +4 -0
- package/dist/http/routes/fleet.js +147 -0
- package/dist/http/routes/images.d.ts +20 -0
- package/dist/http/routes/images.js +572 -0
- package/dist/http/routes/leader.d.ts +4 -0
- package/dist/http/routes/leader.js +48 -0
- package/dist/http/routes/memory-policy.d.ts +4 -0
- package/dist/http/routes/memory-policy.js +105 -0
- package/dist/http/routes/notify-wake.d.ts +4 -0
- package/dist/http/routes/notify-wake.js +133 -0
- package/dist/http/routes/observability.d.ts +4 -0
- package/dist/http/routes/observability.js +63 -0
- package/dist/http/routes/runs.d.ts +19 -0
- package/dist/http/routes/runs.js +967 -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/routes/side-query.d.ts +4 -0
- package/dist/http/routes/side-query.js +88 -0
- package/dist/http/routes/tasks.d.ts +4 -0
- package/dist/http/routes/tasks.js +632 -0
- package/dist/http/routes/trace-usage.d.ts +4 -0
- package/dist/http/routes/trace-usage.js +239 -0
- package/dist/http/routes/workflows.d.ts +5 -0
- package/dist/http/routes/workflows.js +337 -0
- package/dist/http/run-meta.d.ts +11 -0
- package/dist/http/run-meta.js +16 -0
- package/dist/http/send.d.ts +7 -0
- package/dist/http/send.js +34 -0
- package/dist/http/server.d.ts +12 -12
- package/dist/http/server.js +289 -5502
- package/dist/http/sse-log.d.ts +25 -0
- package/dist/http/sse-log.js +59 -0
- package/dist/http/wire-types.d.ts +6 -0
- package/dist/http/workspace-content.d.ts +3 -0
- package/dist/http/workspace-content.js +20 -0
- package/dist/leader/endpoint.js +4 -4
- package/dist/main.js +5 -5
- 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/file-snapshot-store-sql.d.ts +38 -0
- package/dist/plugins/file-snapshot-store-sql.js +210 -0
- package/dist/plugins/image-index-sql.d.ts +33 -0
- package/dist/plugins/image-index-sql.js +328 -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-file-snapshot-store.d.ts +1 -27
- package/dist/plugins/pg-file-snapshot-store.js +1 -190
- 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-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-host.js +4 -3
- 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/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-file-snapshot-store.d.ts +1 -27
- package/dist/plugins/tidb-file-snapshot-store.js +1 -192
- 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/question.js +2 -2
- package/dist/run-local.js +1 -1
- package/dist/tool-approval.js +2 -2
- package/dist/trace/ledger-sink.js +1 -1
- package/dist/trace/project.d.ts +1 -0
- package/dist/trace/project.js +3 -0
- package/package.json +1 -1
|
@@ -1,62 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
import { summarizeWorkflowRun, type WorkflowRunStore } from "@sema-agent/core";
|
|
3
|
-
import { type WorkflowCompletionInbox, type WorkflowCompletionInboxEntry } from "../orchestration/workflow-completion-inbox.js";
|
|
4
|
-
import type { WorkflowNotifyJournalStore, WorkflowNotifyJournalEntry } from "../orchestration/workflow-notify-journal.js";
|
|
5
|
-
type WorkflowRun = Parameters<WorkflowRunStore["put"]>[1];
|
|
6
|
-
export declare const MAX_RUN_BLOB_BYTES: number;
|
|
7
|
-
declare const onWarnType: (msg: string, meta: Record<string, unknown>) => void;
|
|
8
|
-
export type InboxWarn = typeof onWarnType;
|
|
9
|
-
export declare function slimOversizeRun(run: WorkflowRun & {
|
|
10
|
-
id: string;
|
|
11
|
-
scope: string;
|
|
12
|
-
}, maxBytes: number): string | null;
|
|
13
|
-
export declare class TiDBWorkflowRunStore implements WorkflowRunStore {
|
|
14
|
-
private readonly pool;
|
|
15
|
-
constructor(pool: Pool);
|
|
16
|
-
put(id: string, run: WorkflowRun): Promise<void>;
|
|
17
|
-
get(id: string): Promise<WorkflowRun | null>;
|
|
18
|
-
update(id: string, scope: string, run: WorkflowRun, expect?: {
|
|
19
|
-
rev: number;
|
|
20
|
-
}): Promise<boolean>;
|
|
21
|
-
listByScope(scope: string, opts?: {
|
|
22
|
-
status?: WorkflowRun["status"];
|
|
23
|
-
limit?: number;
|
|
24
|
-
session?: string;
|
|
25
|
-
}): Promise<ReturnType<typeof summarizeWorkflowRun>[]>;
|
|
26
|
-
reapAllScopes(now: number, opts: {
|
|
27
|
-
maxAgeMs?: number;
|
|
28
|
-
keep?: number;
|
|
29
|
-
}): Promise<number>;
|
|
30
|
-
reap(scope: string, now: number, opts?: {
|
|
31
|
-
maxAgeMs?: number;
|
|
32
|
-
keep?: number;
|
|
33
|
-
}): Promise<number>;
|
|
34
|
-
}
|
|
35
|
-
export declare class TiDBWorkflowCompletionInbox implements WorkflowCompletionInbox {
|
|
36
|
-
private readonly pool;
|
|
37
|
-
private readonly onWarn?;
|
|
38
|
-
constructor(pool: Pool, onWarn?: InboxWarn | undefined);
|
|
39
|
-
private sweepFences;
|
|
40
|
-
enqueue(entry: WorkflowCompletionInboxEntry): Promise<void>;
|
|
41
|
-
pending(sessionId: string): Promise<WorkflowCompletionInboxEntry[]>;
|
|
42
|
-
ack(sessionId: string, runId: string): Promise<void>;
|
|
43
|
-
purge(sessionId: string, purgedOwner?: string | null): Promise<void>;
|
|
44
|
-
markTerminalServed(sessionId: string, runId: string): Promise<void>;
|
|
45
|
-
}
|
|
46
|
-
export declare class TiDBWorkflowNotifyJournalStore implements WorkflowNotifyJournalStore {
|
|
47
|
-
private readonly pool;
|
|
48
|
-
constructor(pool: Pool);
|
|
49
|
-
record(input: {
|
|
50
|
-
runId: string;
|
|
51
|
-
scope: string;
|
|
52
|
-
sourceTaskId?: string;
|
|
53
|
-
principal?: string;
|
|
54
|
-
createdAt: number;
|
|
55
|
-
}): Promise<void>;
|
|
56
|
-
ack(runId: string, ackedAt: number): Promise<void>;
|
|
57
|
-
listPending(): Promise<WorkflowNotifyJournalEntry[]>;
|
|
58
|
-
reapAcked(before: number): Promise<number>;
|
|
59
|
-
get(runId: string): Promise<WorkflowNotifyJournalEntry | null>;
|
|
60
|
-
}
|
|
61
|
-
export {};
|
|
1
|
+
export { MAX_RUN_BLOB_BYTES, slimOversizeRun, type InboxWarn, TiDBWorkflowRunStore, TiDBWorkflowCompletionInbox, TiDBWorkflowNotifyJournalStore, } from "./workflow-run-store-sql.js";
|
|
62
2
|
//# sourceMappingURL=tidb-workflow-run-store.d.ts.map
|
|
@@ -1,232 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
import { foldKeyFamily, MAX_PENDING_PER_SESSION, PURGE_FENCE_MS, SERVED_FENCE_MS, } from "../orchestration/workflow-completion-inbox.js";
|
|
3
|
-
export const MAX_RUN_BLOB_BYTES = 4 * 1024 * 1024;
|
|
4
|
-
const onWarnType = (msg, meta) => void [msg, meta];
|
|
5
|
-
export function slimOversizeRun(run, maxBytes) {
|
|
6
|
-
const MARK = "…[truncated: run blob exceeded the store cap]";
|
|
7
|
-
const cut = (s) => s.slice(0, 4000) + MARK;
|
|
8
|
-
const step1 = {
|
|
9
|
-
...run,
|
|
10
|
-
...(typeof run.result === "string" && run.result.length > 4000 ? { result: cut(run.result) } : {}),
|
|
11
|
-
...(typeof run.error === "string" && run.error.length > 4000 ? { error: cut(run.error) } : {}),
|
|
12
|
-
};
|
|
13
|
-
let blob = JSON.stringify(step1);
|
|
14
|
-
if (Buffer.byteLength(blob) <= maxBytes)
|
|
15
|
-
return blob;
|
|
16
|
-
const step2 = { ...step1, phases: [], agents: [], groups: [], error: step1.error ? String(step1.error).slice(0, 1000) + MARK : MARK };
|
|
17
|
-
blob = JSON.stringify(step2);
|
|
18
|
-
return Buffer.byteLength(blob) <= maxBytes ? blob : null;
|
|
19
|
-
}
|
|
20
|
-
export class TiDBWorkflowRunStore {
|
|
21
|
-
pool;
|
|
22
|
-
constructor(pool) {
|
|
23
|
-
this.pool = pool;
|
|
24
|
-
}
|
|
25
|
-
async put(id, run) {
|
|
26
|
-
const stored = { ...run, id, rev: run.rev ?? 0 };
|
|
27
|
-
try {
|
|
28
|
-
await this.pool.query("INSERT INTO workflow_run (id, scope, status, run, rev, created_at, ended_at) VALUES (?,?,?,?,?,?,?)", [id, run.scope, run.status, JSON.stringify(stored), stored.rev, run.createdAt, run.endedAt ?? null]);
|
|
29
|
-
}
|
|
30
|
-
catch (e) {
|
|
31
|
-
if (e.code === "ER_DUP_ENTRY") {
|
|
32
|
-
throw new WorkflowRunStoreError("workflow_run.already_exists", "workflow run id already exists");
|
|
33
|
-
}
|
|
34
|
-
throw e;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
async get(id) {
|
|
38
|
-
const [rows] = await this.pool.query("SELECT run, rev FROM workflow_run WHERE id = ?", [id]);
|
|
39
|
-
const r = rows[0];
|
|
40
|
-
if (!r)
|
|
41
|
-
return null;
|
|
42
|
-
const run = JSON.parse(String(r.run));
|
|
43
|
-
run.rev = Number(r.rev);
|
|
44
|
-
return run;
|
|
45
|
-
}
|
|
46
|
-
async update(id, scope, run, expect) {
|
|
47
|
-
let blob = JSON.stringify({ ...run, id, scope });
|
|
48
|
-
if (Buffer.byteLength(blob) > MAX_RUN_BLOB_BYTES) {
|
|
49
|
-
const slim = slimOversizeRun({ ...run, id, scope }, MAX_RUN_BLOB_BYTES);
|
|
50
|
-
if (slim === null)
|
|
51
|
-
return false;
|
|
52
|
-
blob = slim;
|
|
53
|
-
}
|
|
54
|
-
const [res] = await this.pool.query(`UPDATE workflow_run SET run = ?, rev = rev + 1, status = ?, ended_at = ? WHERE id = ? AND scope = ?${expect !== undefined ? " AND rev = ?" : ""}`, expect !== undefined
|
|
55
|
-
? [blob, run.status, run.endedAt ?? null, id, scope, expect.rev]
|
|
56
|
-
: [blob, run.status, run.endedAt ?? null, id, scope]);
|
|
57
|
-
return res.affectedRows === 1;
|
|
58
|
-
}
|
|
59
|
-
async listByScope(scope, opts) {
|
|
60
|
-
const params = [scope];
|
|
61
|
-
let where = "scope = ?";
|
|
62
|
-
if (opts?.status !== undefined) {
|
|
63
|
-
where += " AND status = ?";
|
|
64
|
-
params.push(opts.status);
|
|
65
|
-
}
|
|
66
|
-
if (opts?.session !== undefined) {
|
|
67
|
-
where += " AND JSON_UNQUOTE(JSON_EXTRACT(run, '$.originatingSessionId')) = ?";
|
|
68
|
-
params.push(opts.session);
|
|
69
|
-
}
|
|
70
|
-
let limit = "";
|
|
71
|
-
if (opts?.limit !== undefined) {
|
|
72
|
-
limit = " LIMIT ?";
|
|
73
|
-
params.push(Math.max(0, opts.limit));
|
|
74
|
-
}
|
|
75
|
-
const [rows] = await this.pool.query(`SELECT run, rev FROM workflow_run WHERE ${where} ORDER BY created_at DESC, id DESC${limit}`, params);
|
|
76
|
-
return rows.map((r) => {
|
|
77
|
-
const run = JSON.parse(String(r.run));
|
|
78
|
-
run.rev = Number(r.rev);
|
|
79
|
-
return summarizeWorkflowRun(run);
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
async reapAllScopes(now, opts) {
|
|
83
|
-
const [rows] = await this.pool.query("SELECT DISTINCT scope FROM workflow_run");
|
|
84
|
-
let total = 0;
|
|
85
|
-
for (const r of rows)
|
|
86
|
-
total += await this.reap(String(r.scope), now, opts);
|
|
87
|
-
return total;
|
|
88
|
-
}
|
|
89
|
-
async reap(scope, now, opts) {
|
|
90
|
-
if (opts?.maxAgeMs === undefined && opts?.keep === undefined)
|
|
91
|
-
return 0;
|
|
92
|
-
const [rows] = await this.pool.query("SELECT id, status, created_at, ended_at FROM workflow_run WHERE scope = ? ORDER BY created_at DESC, id DESC", [scope]);
|
|
93
|
-
const terminal = rows.filter((r) => isTerminalWorkflowStatus(String(r.status)));
|
|
94
|
-
const doomed = [];
|
|
95
|
-
for (let i = 0; i < terminal.length; i++) {
|
|
96
|
-
const r = terminal[i];
|
|
97
|
-
const anchor = r.ended_at != null ? Number(r.ended_at) : Number(r.created_at);
|
|
98
|
-
const tooOld = opts.maxAgeMs !== undefined && anchor < now - opts.maxAgeMs;
|
|
99
|
-
const overKeep = opts.keep !== undefined && i >= opts.keep;
|
|
100
|
-
if (tooOld || overKeep)
|
|
101
|
-
doomed.push(String(r.id));
|
|
102
|
-
}
|
|
103
|
-
if (doomed.length === 0)
|
|
104
|
-
return 0;
|
|
105
|
-
const [res] = await this.pool.query(`DELETE FROM workflow_run WHERE scope = ? AND id IN (${doomed.map(() => "?").join(",")})`, [scope, ...doomed]);
|
|
106
|
-
return res.affectedRows;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
const KIND_SERVED = "served";
|
|
110
|
-
const KIND_PURGE = "purge";
|
|
111
|
-
export class TiDBWorkflowCompletionInbox {
|
|
112
|
-
pool;
|
|
113
|
-
onWarn;
|
|
114
|
-
constructor(pool, onWarn) {
|
|
115
|
-
this.pool = pool;
|
|
116
|
-
this.onWarn = onWarn;
|
|
117
|
-
}
|
|
118
|
-
async sweepFences(now) {
|
|
119
|
-
await this.pool.query("DELETE FROM workflow_inbox_fence WHERE until_ms < ?", [now]);
|
|
120
|
-
}
|
|
121
|
-
async enqueue(entry) {
|
|
122
|
-
const now = Date.now();
|
|
123
|
-
await this.sweepFences(now);
|
|
124
|
-
const [served] = await this.pool.query("SELECT 1 FROM workflow_inbox_fence WHERE session_id = ? AND kind = ? AND run_id IN (?, ?) AND until_ms >= ?", [entry.sessionId, KIND_SERVED, entry.runId, foldKeyFamily(entry.runId), now]);
|
|
125
|
-
if (served.length > 0) {
|
|
126
|
-
this.onWarn?.("workflow_completion_enqueue_after_poll_served", { sessionId: entry.sessionId, runId: entry.runId });
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
const [purge] = await this.pool.query("SELECT owner, owner_known FROM workflow_inbox_fence WHERE session_id = ? AND kind = ? AND run_id = '' AND until_ms >= ?", [entry.sessionId, KIND_PURGE, now]);
|
|
130
|
-
const pf = purge[0];
|
|
131
|
-
if (pf && (Number(pf.owner_known) === 0 || (pf.owner === null ? entry.owner === null : String(pf.owner) === entry.owner))) {
|
|
132
|
-
this.onWarn?.("workflow_completion_enqueue_after_purge", { sessionId: entry.sessionId, runId: entry.runId });
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
135
|
-
await this.pool.query("REPLACE INTO workflow_completion_inbox (session_id, run_id, owner, status, summary, enqueued_at, kind, payload) VALUES (?,?,?,?,?,?,?,?)", [entry.sessionId, entry.runId, entry.owner, entry.status, entry.summary, entry.enqueuedAt, entry.kind ?? null, entry.payload ?? null]);
|
|
136
|
-
const [confirm] = await this.pool.query("SELECT kind, owner, owner_known FROM workflow_inbox_fence WHERE session_id = ? AND until_ms >= ? AND (run_id IN (?, ?) OR (kind = ? AND run_id = ''))", [entry.sessionId, now, entry.runId, foldKeyFamily(entry.runId), KIND_PURGE]);
|
|
137
|
-
for (const f of confirm) {
|
|
138
|
-
const isServed = String(f.kind) === KIND_SERVED;
|
|
139
|
-
const purgeFencesUs = !isServed && (Number(f.owner_known) === 0 || (f.owner === null ? entry.owner === null : String(f.owner) === entry.owner));
|
|
140
|
-
if (isServed || purgeFencesUs) {
|
|
141
|
-
await this.ack(entry.sessionId, entry.runId);
|
|
142
|
-
this.onWarn?.(isServed ? "workflow_completion_enqueue_after_poll_served" : "workflow_completion_enqueue_after_purge", {
|
|
143
|
-
sessionId: entry.sessionId,
|
|
144
|
-
runId: entry.runId,
|
|
145
|
-
});
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
const [over] = await this.pool.query("SELECT seq, run_id FROM workflow_completion_inbox WHERE session_id = ? ORDER BY seq DESC LIMIT 100000 OFFSET ?", [entry.sessionId, MAX_PENDING_PER_SESSION]);
|
|
150
|
-
if (over.length > 0) {
|
|
151
|
-
await this.pool.query(`DELETE FROM workflow_completion_inbox WHERE session_id = ? AND seq IN (${over.map(() => "?").join(",")})`, [entry.sessionId, ...over.map((r) => r.seq)]);
|
|
152
|
-
for (const r of over)
|
|
153
|
-
this.onWarn?.("workflow_completion_inbox_overflow", { sessionId: entry.sessionId, droppedRunId: String(r.run_id) });
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
async pending(sessionId) {
|
|
157
|
-
const [rows] = await this.pool.query("SELECT i.run_id, i.owner, i.status, i.summary, i.enqueued_at, i.kind, i.payload FROM workflow_completion_inbox i " +
|
|
158
|
-
"WHERE i.session_id = ? AND NOT EXISTS (SELECT 1 FROM workflow_inbox_fence f WHERE f.session_id = i.session_id AND f.kind = ? AND f.run_id IN (i.run_id, REGEXP_REPLACE(i.run_id, '#[0-9]+$', '')) AND f.until_ms >= ?) " +
|
|
159
|
-
"ORDER BY i.seq ASC", [sessionId, KIND_SERVED, Date.now()]);
|
|
160
|
-
return rows.map((r) => ({
|
|
161
|
-
sessionId,
|
|
162
|
-
runId: String(r.run_id),
|
|
163
|
-
owner: r.owner === null ? null : String(r.owner),
|
|
164
|
-
status: String(r.status),
|
|
165
|
-
summary: String(r.summary),
|
|
166
|
-
enqueuedAt: Number(r.enqueued_at),
|
|
167
|
-
...(r.kind != null ? { kind: String(r.kind) } : {}),
|
|
168
|
-
...(r.payload != null ? { payload: String(r.payload) } : {}),
|
|
169
|
-
}));
|
|
170
|
-
}
|
|
171
|
-
async ack(sessionId, runId) {
|
|
172
|
-
await this.pool.query("DELETE FROM workflow_completion_inbox WHERE session_id = ? AND run_id = ?", [sessionId, runId]);
|
|
173
|
-
}
|
|
174
|
-
async purge(sessionId, purgedOwner) {
|
|
175
|
-
const now = Date.now();
|
|
176
|
-
await this.sweepFences(now);
|
|
177
|
-
await this.pool.query("INSERT INTO workflow_inbox_fence (session_id, kind, run_id, owner, owner_known, until_ms) VALUES (?,?,?,?,?,?) " +
|
|
178
|
-
"ON DUPLICATE KEY UPDATE owner = VALUES(owner), owner_known = VALUES(owner_known), until_ms = VALUES(until_ms)", [sessionId, KIND_PURGE, "", purgedOwner ?? null, purgedOwner !== undefined ? 1 : 0, now + PURGE_FENCE_MS]);
|
|
179
|
-
await this.pool.query("DELETE FROM workflow_completion_inbox WHERE session_id = ?", [sessionId]);
|
|
180
|
-
}
|
|
181
|
-
async markTerminalServed(sessionId, runId) {
|
|
182
|
-
const now = Date.now();
|
|
183
|
-
await this.sweepFences(now);
|
|
184
|
-
await this.pool.query("INSERT INTO workflow_inbox_fence (session_id, kind, run_id, owner, owner_known, until_ms) VALUES (?,?,?,NULL,0,?) " +
|
|
185
|
-
"ON DUPLICATE KEY UPDATE until_ms = VALUES(until_ms)", [sessionId, KIND_SERVED, runId, now + SERVED_FENCE_MS]);
|
|
186
|
-
await this.ack(sessionId, runId);
|
|
187
|
-
await this.pool.query("DELETE FROM workflow_completion_inbox WHERE session_id = ? AND run_id <> ? AND REGEXP_REPLACE(run_id, '#[0-9]+$', '') = ?", [sessionId, runId, runId]);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
export class TiDBWorkflowNotifyJournalStore {
|
|
191
|
-
pool;
|
|
192
|
-
constructor(pool) {
|
|
193
|
-
this.pool = pool;
|
|
194
|
-
}
|
|
195
|
-
async record(input) {
|
|
196
|
-
await this.pool.query("INSERT IGNORE INTO workflow_notify_journal (run_id, scope, acked, source_task_id, principal, created_at) VALUES (?,?,0,?,?,?)", [input.runId, input.scope, input.sourceTaskId ?? null, input.principal ?? null, input.createdAt]);
|
|
197
|
-
}
|
|
198
|
-
async ack(runId, ackedAt) {
|
|
199
|
-
await this.pool.query("UPDATE workflow_notify_journal SET acked = 1, acked_at = ? WHERE run_id = ? AND acked = 0", [ackedAt, runId]);
|
|
200
|
-
}
|
|
201
|
-
async listPending() {
|
|
202
|
-
const [rows] = await this.pool.query("SELECT run_id, scope, source_task_id, principal, created_at FROM workflow_notify_journal WHERE acked = 0");
|
|
203
|
-
return rows.map((r) => ({
|
|
204
|
-
runId: String(r.run_id),
|
|
205
|
-
scope: String(r.scope),
|
|
206
|
-
acked: false,
|
|
207
|
-
...(r.source_task_id != null ? { sourceTaskId: String(r.source_task_id) } : {}),
|
|
208
|
-
...(r.principal != null ? { principal: String(r.principal) } : {}),
|
|
209
|
-
createdAt: Number(r.created_at),
|
|
210
|
-
}));
|
|
211
|
-
}
|
|
212
|
-
async reapAcked(before) {
|
|
213
|
-
const [res] = await this.pool.query("DELETE FROM workflow_notify_journal WHERE acked = 1 AND acked_at < ?", [before]);
|
|
214
|
-
return res.affectedRows;
|
|
215
|
-
}
|
|
216
|
-
async get(runId) {
|
|
217
|
-
const [rows] = await this.pool.query("SELECT run_id, scope, acked, source_task_id, principal, created_at, acked_at FROM workflow_notify_journal WHERE run_id = ?", [runId]);
|
|
218
|
-
const r = rows[0];
|
|
219
|
-
if (!r)
|
|
220
|
-
return null;
|
|
221
|
-
return {
|
|
222
|
-
runId: String(r.run_id),
|
|
223
|
-
scope: String(r.scope),
|
|
224
|
-
acked: Number(r.acked) === 1,
|
|
225
|
-
...(r.source_task_id != null ? { sourceTaskId: String(r.source_task_id) } : {}),
|
|
226
|
-
...(r.principal != null ? { principal: String(r.principal) } : {}),
|
|
227
|
-
createdAt: Number(r.created_at),
|
|
228
|
-
...(r.acked_at != null ? { ackedAt: Number(r.acked_at) } : {}),
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
}
|
|
1
|
+
export { MAX_RUN_BLOB_BYTES, slimOversizeRun, TiDBWorkflowRunStore, TiDBWorkflowCompletionInbox, TiDBWorkflowNotifyJournalStore, } from "./workflow-run-store-sql.js";
|
|
232
2
|
//# sourceMappingURL=tidb-workflow-run-store.js.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ToolResultStore, ToolResultSlice } from "@sema-agent/core";
|
|
2
|
+
import type { Pool as MySqlPool } from "mysql2/promise";
|
|
3
|
+
import type { Pool as PgPool, PoolClient as PgPoolClient } from "pg";
|
|
4
|
+
import { type SqlDriver } from "./sql-driver.js";
|
|
5
|
+
export declare const PG_TOOL_RESULT_SCHEMA: string[];
|
|
6
|
+
export declare function ensureSchema(pool: PgPool | PgPoolClient): Promise<void>;
|
|
7
|
+
export declare class SqlToolResultStore implements ToolResultStore {
|
|
8
|
+
protected readonly db: SqlDriver;
|
|
9
|
+
constructor(db: SqlDriver);
|
|
10
|
+
private q;
|
|
11
|
+
put(ref: string, content: string): Promise<void>;
|
|
12
|
+
get(ref: string, opts?: {
|
|
13
|
+
offset?: number;
|
|
14
|
+
limit?: number;
|
|
15
|
+
}): Promise<ToolResultSlice | undefined>;
|
|
16
|
+
reapOlderThan(cutoffMs: number): Promise<number>;
|
|
17
|
+
deleteBySession(sessionId: string): Promise<number>;
|
|
18
|
+
}
|
|
19
|
+
export declare class TiDBToolResultStore extends SqlToolResultStore {
|
|
20
|
+
constructor(pool: MySqlPool);
|
|
21
|
+
}
|
|
22
|
+
export declare class PgToolResultStore extends SqlToolResultStore {
|
|
23
|
+
constructor(pool: PgPool);
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=tool-result-store-sql.d.ts.map
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { escapeLike } from "./sql-escape.js";
|
|
2
|
+
import { pgSanitizeText } from "./pg-safe-json.js";
|
|
3
|
+
import { mysqlDriver, pgDriver } from "./sql-driver.js";
|
|
4
|
+
export const PG_TOOL_RESULT_SCHEMA = [
|
|
5
|
+
`CREATE TABLE IF NOT EXISTS tool_result (
|
|
6
|
+
ref VARCHAR(190) NOT NULL,
|
|
7
|
+
content TEXT NOT NULL,
|
|
8
|
+
created_at TIMESTAMPTZ(3) NOT NULL,
|
|
9
|
+
PRIMARY KEY (ref)
|
|
10
|
+
)`,
|
|
11
|
+
`CREATE INDEX IF NOT EXISTS idx_tool_result_created ON tool_result (created_at)`,
|
|
12
|
+
];
|
|
13
|
+
export async function ensureSchema(pool) {
|
|
14
|
+
for (const stmt of PG_TOOL_RESULT_SCHEMA)
|
|
15
|
+
await pool.query(stmt);
|
|
16
|
+
}
|
|
17
|
+
export class SqlToolResultStore {
|
|
18
|
+
db;
|
|
19
|
+
constructor(db) {
|
|
20
|
+
this.db = db;
|
|
21
|
+
}
|
|
22
|
+
q(tidb, pg) {
|
|
23
|
+
return this.db.dialect === "tidb" ? tidb : pg;
|
|
24
|
+
}
|
|
25
|
+
async put(ref, content) {
|
|
26
|
+
let safe = Buffer.from(content, "utf8").toString("utf8");
|
|
27
|
+
if (this.db.dialect === "pg")
|
|
28
|
+
safe = pgSanitizeText(safe);
|
|
29
|
+
await this.db.query(this.q("INSERT IGNORE INTO tool_result (ref, content, created_at) VALUES (?,?,?)", "INSERT INTO tool_result (ref, content, created_at) VALUES ($1,$2,$3) ON CONFLICT (ref) DO NOTHING"), [ref, safe, new Date()]);
|
|
30
|
+
}
|
|
31
|
+
async get(ref, opts = {}) {
|
|
32
|
+
const offset = Math.max(0, Math.floor(opts.offset ?? 0));
|
|
33
|
+
const hasLimit = opts.limit !== undefined && Number.isFinite(opts.limit);
|
|
34
|
+
const limit = hasLimit ? Math.max(0, Math.floor(opts.limit)) : 0;
|
|
35
|
+
const sql = hasLimit
|
|
36
|
+
? this.q("SELECT SUBSTRING(content, ?, ?) AS slice, CHAR_LENGTH(content) AS total FROM tool_result WHERE ref = ?", "SELECT SUBSTRING(content FROM $1::int FOR $2::int) AS slice, CHAR_LENGTH(content) AS total FROM tool_result WHERE ref = $3")
|
|
37
|
+
: this.q("SELECT SUBSTRING(content, ?) AS slice, CHAR_LENGTH(content) AS total FROM tool_result WHERE ref = ?", "SELECT SUBSTRING(content FROM $1::int) AS slice, CHAR_LENGTH(content) AS total FROM tool_result WHERE ref = $2");
|
|
38
|
+
const params = hasLimit ? [offset + 1, limit, ref] : [offset + 1, ref];
|
|
39
|
+
const { rows } = await this.db.query(sql, params);
|
|
40
|
+
if (rows.length === 0)
|
|
41
|
+
return undefined;
|
|
42
|
+
return { content: String(rows[0].slice ?? ""), offset, totalChars: Number(rows[0].total) };
|
|
43
|
+
}
|
|
44
|
+
async reapOlderThan(cutoffMs) {
|
|
45
|
+
try {
|
|
46
|
+
const { affected } = await this.db.query(this.q("DELETE FROM tool_result WHERE created_at < ?", "DELETE FROM tool_result WHERE created_at < $1"), [new Date(cutoffMs)]);
|
|
47
|
+
return affected;
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return 0;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
async deleteBySession(sessionId) {
|
|
54
|
+
const prefix = `${escapeLike(`tr_${sessionId}_`)}%`;
|
|
55
|
+
const { affected } = await this.db.query(this.q("DELETE FROM tool_result WHERE ref LIKE ? ESCAPE '\\\\'", "DELETE FROM tool_result WHERE ref LIKE $1 ESCAPE '\\'"), [prefix]);
|
|
56
|
+
return affected;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
export class TiDBToolResultStore extends SqlToolResultStore {
|
|
60
|
+
constructor(pool) {
|
|
61
|
+
super(mysqlDriver(pool));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
export class PgToolResultStore extends SqlToolResultStore {
|
|
65
|
+
constructor(pool) {
|
|
66
|
+
super(pgDriver(pool));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=tool-result-store-sql.js.map
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Pool as MySqlPool } from "mysql2/promise";
|
|
2
|
+
import type { Pool as PgPool } from "pg";
|
|
3
|
+
import { type WorkflowJournalEntry, type WorkflowJournalStore } from "@sema-agent/core";
|
|
4
|
+
import { type SqlDriver } from "./sql-driver.js";
|
|
5
|
+
export declare class SqlWorkflowJournalStore implements WorkflowJournalStore {
|
|
6
|
+
private readonly db;
|
|
7
|
+
constructor(db: SqlDriver);
|
|
8
|
+
private q;
|
|
9
|
+
append(runId: string, scope: string, entry: WorkflowJournalEntry): Promise<void>;
|
|
10
|
+
load(runId: string, scope: string): Promise<WorkflowJournalEntry[]>;
|
|
11
|
+
locator(runId: string, _scope: string): string;
|
|
12
|
+
loadPage(runId: string, scope: string, opts: {
|
|
13
|
+
offset: number;
|
|
14
|
+
limit: number;
|
|
15
|
+
maxResultBytes: number;
|
|
16
|
+
}): Promise<Array<{
|
|
17
|
+
callKey: string;
|
|
18
|
+
resultJson: string | null;
|
|
19
|
+
resultBytes: number;
|
|
20
|
+
}>>;
|
|
21
|
+
deleteByRun(runId: string): Promise<number>;
|
|
22
|
+
reapExpired(now: number, maxAgeMs: number): Promise<number>;
|
|
23
|
+
}
|
|
24
|
+
export declare class TiDBWorkflowJournalStore extends SqlWorkflowJournalStore {
|
|
25
|
+
constructor(pool: MySqlPool);
|
|
26
|
+
}
|
|
27
|
+
export declare class PgWorkflowJournalStore extends SqlWorkflowJournalStore {
|
|
28
|
+
constructor(pool: PgPool);
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=workflow-journal-store-sql.d.ts.map
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { callKeyOrdinal } from "@sema-agent/core";
|
|
2
|
+
import { oversizeJournalResult } from "./workflow-journal-limits.js";
|
|
3
|
+
import { mysqlDriver, pgDriver } from "./sql-driver.js";
|
|
4
|
+
export class SqlWorkflowJournalStore {
|
|
5
|
+
db;
|
|
6
|
+
constructor(db) {
|
|
7
|
+
this.db = db;
|
|
8
|
+
}
|
|
9
|
+
q(tidb, pg) {
|
|
10
|
+
return this.db.dialect === "tidb" ? tidb : pg;
|
|
11
|
+
}
|
|
12
|
+
async append(runId, scope, entry) {
|
|
13
|
+
const serialized = JSON.stringify(entry.result);
|
|
14
|
+
if (oversizeJournalResult(serialized))
|
|
15
|
+
return;
|
|
16
|
+
await this.db.query(this.q("INSERT INTO workflow_journal (run_id, ordinal, scope, call_key, result, created_at) VALUES (?,?,?,?,?,?) " +
|
|
17
|
+
"ON DUPLICATE KEY UPDATE call_key = VALUES(call_key), result = VALUES(result)", "INSERT INTO workflow_journal (run_id, ordinal, scope, call_key, result, created_at) VALUES ($1,$2,$3,$4,$5,$6) " +
|
|
18
|
+
"ON CONFLICT (run_id, ordinal) DO UPDATE SET call_key = EXCLUDED.call_key, result = EXCLUDED.result"), [runId, callKeyOrdinal(entry.callKey), scope, entry.callKey, serialized, Date.now()]);
|
|
19
|
+
}
|
|
20
|
+
async load(runId, scope) {
|
|
21
|
+
const { rows } = await this.db.query(this.q("SELECT call_key, result FROM workflow_journal WHERE run_id = ? AND scope = ? ORDER BY ordinal ASC", "SELECT call_key, result FROM workflow_journal WHERE run_id = $1 AND scope = $2 ORDER BY ordinal ASC"), [runId, scope]);
|
|
22
|
+
return rows.map((r) => ({ callKey: String(r.call_key), result: JSON.parse(String(r.result)) }));
|
|
23
|
+
}
|
|
24
|
+
locator(runId, _scope) {
|
|
25
|
+
return `/v1/workflows/${runId}/journal`;
|
|
26
|
+
}
|
|
27
|
+
async loadPage(runId, scope, opts) {
|
|
28
|
+
const params = this.db.dialect === "tidb"
|
|
29
|
+
? [opts.maxResultBytes, runId, scope, opts.limit, opts.offset]
|
|
30
|
+
: [runId, scope, opts.maxResultBytes, opts.limit, opts.offset];
|
|
31
|
+
const { rows } = await this.db.query(this.q("SELECT call_key, CASE WHEN LENGTH(result) > ? THEN NULL ELSE result END AS result_json, LENGTH(result) AS result_bytes FROM workflow_journal WHERE run_id = ? AND scope = ? ORDER BY ordinal ASC LIMIT ? OFFSET ?", "SELECT call_key, CASE WHEN OCTET_LENGTH(result) > $3 THEN NULL ELSE result END AS result_json, OCTET_LENGTH(result) AS result_bytes FROM workflow_journal WHERE run_id = $1 AND scope = $2 ORDER BY ordinal ASC LIMIT $4 OFFSET $5"), params);
|
|
32
|
+
return rows.map((r) => ({ callKey: String(r.call_key), resultJson: r.result_json === null ? null : String(r.result_json), resultBytes: Number(r.result_bytes) }));
|
|
33
|
+
}
|
|
34
|
+
async deleteByRun(runId) {
|
|
35
|
+
const res = await this.db.query(this.q("DELETE FROM workflow_journal WHERE run_id = ?", "DELETE FROM workflow_journal WHERE run_id = $1"), [runId]);
|
|
36
|
+
return res.affected;
|
|
37
|
+
}
|
|
38
|
+
async reapExpired(now, maxAgeMs) {
|
|
39
|
+
const res = await this.db.query(this.q("DELETE FROM workflow_journal WHERE created_at < ?", "DELETE FROM workflow_journal WHERE created_at < $1"), [now - maxAgeMs]);
|
|
40
|
+
return res.affected;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export class TiDBWorkflowJournalStore extends SqlWorkflowJournalStore {
|
|
44
|
+
constructor(pool) {
|
|
45
|
+
super(mysqlDriver(pool));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export class PgWorkflowJournalStore extends SqlWorkflowJournalStore {
|
|
49
|
+
constructor(pool) {
|
|
50
|
+
super(pgDriver(pool));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=workflow-journal-store-sql.js.map
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { Pool as MySqlPool } from "mysql2/promise";
|
|
2
|
+
import type { Pool as PgPool } from "pg";
|
|
3
|
+
import { summarizeWorkflowRun, type WorkflowRunStore } from "@sema-agent/core";
|
|
4
|
+
import { type WorkflowCompletionInbox, type WorkflowCompletionInboxEntry } from "../orchestration/workflow-completion-inbox.js";
|
|
5
|
+
import type { WorkflowNotifyJournalStore, WorkflowNotifyJournalEntry } from "../orchestration/workflow-notify-journal.js";
|
|
6
|
+
import { type SqlDriver } from "./sql-driver.js";
|
|
7
|
+
type WorkflowRun = Parameters<WorkflowRunStore["put"]>[1];
|
|
8
|
+
export declare const MAX_RUN_BLOB_BYTES: number;
|
|
9
|
+
declare const onWarnType: (msg: string, meta: Record<string, unknown>) => void;
|
|
10
|
+
export type InboxWarn = typeof onWarnType;
|
|
11
|
+
export declare function slimOversizeRun(run: WorkflowRun & {
|
|
12
|
+
id: string;
|
|
13
|
+
scope: string;
|
|
14
|
+
}, maxBytes: number): string | null;
|
|
15
|
+
export declare class SqlWorkflowRunStore implements WorkflowRunStore {
|
|
16
|
+
protected readonly db: SqlDriver;
|
|
17
|
+
constructor(db: SqlDriver);
|
|
18
|
+
private q;
|
|
19
|
+
put(id: string, run: WorkflowRun): Promise<void>;
|
|
20
|
+
get(id: string): Promise<WorkflowRun | null>;
|
|
21
|
+
update(id: string, scope: string, run: WorkflowRun, expect?: {
|
|
22
|
+
rev: number;
|
|
23
|
+
}): Promise<boolean>;
|
|
24
|
+
listByScope(scope: string, opts?: {
|
|
25
|
+
status?: WorkflowRun["status"];
|
|
26
|
+
limit?: number;
|
|
27
|
+
session?: string;
|
|
28
|
+
}): Promise<ReturnType<typeof summarizeWorkflowRun>[]>;
|
|
29
|
+
reapAllScopes(now: number, opts: {
|
|
30
|
+
maxAgeMs?: number;
|
|
31
|
+
keep?: number;
|
|
32
|
+
}): Promise<number>;
|
|
33
|
+
reap(scope: string, now: number, opts?: {
|
|
34
|
+
maxAgeMs?: number;
|
|
35
|
+
keep?: number;
|
|
36
|
+
}): Promise<number>;
|
|
37
|
+
}
|
|
38
|
+
export declare class SqlWorkflowCompletionInbox implements WorkflowCompletionInbox {
|
|
39
|
+
protected readonly db: SqlDriver;
|
|
40
|
+
private readonly onWarn?;
|
|
41
|
+
constructor(db: SqlDriver, onWarn?: InboxWarn | undefined);
|
|
42
|
+
private q;
|
|
43
|
+
private sweepFences;
|
|
44
|
+
enqueue(entry: WorkflowCompletionInboxEntry): Promise<void>;
|
|
45
|
+
pending(sessionId: string): Promise<WorkflowCompletionInboxEntry[]>;
|
|
46
|
+
ack(sessionId: string, runId: string): Promise<void>;
|
|
47
|
+
purge(sessionId: string, purgedOwner?: string | null): Promise<void>;
|
|
48
|
+
markTerminalServed(sessionId: string, runId: string): Promise<void>;
|
|
49
|
+
}
|
|
50
|
+
export declare class SqlWorkflowNotifyJournalStore implements WorkflowNotifyJournalStore {
|
|
51
|
+
protected readonly db: SqlDriver;
|
|
52
|
+
constructor(db: SqlDriver);
|
|
53
|
+
private q;
|
|
54
|
+
record(input: {
|
|
55
|
+
runId: string;
|
|
56
|
+
scope: string;
|
|
57
|
+
sourceTaskId?: string;
|
|
58
|
+
principal?: string;
|
|
59
|
+
createdAt: number;
|
|
60
|
+
}): Promise<void>;
|
|
61
|
+
ack(runId: string, ackedAt: number): Promise<void>;
|
|
62
|
+
listPending(): Promise<WorkflowNotifyJournalEntry[]>;
|
|
63
|
+
reapAcked(before: number): Promise<number>;
|
|
64
|
+
get(runId: string): Promise<WorkflowNotifyJournalEntry | null>;
|
|
65
|
+
}
|
|
66
|
+
export declare class TiDBWorkflowRunStore extends SqlWorkflowRunStore {
|
|
67
|
+
constructor(pool: MySqlPool);
|
|
68
|
+
}
|
|
69
|
+
export declare class TiDBWorkflowCompletionInbox extends SqlWorkflowCompletionInbox {
|
|
70
|
+
constructor(pool: MySqlPool, onWarn?: InboxWarn);
|
|
71
|
+
}
|
|
72
|
+
export declare class TiDBWorkflowNotifyJournalStore extends SqlWorkflowNotifyJournalStore {
|
|
73
|
+
constructor(pool: MySqlPool);
|
|
74
|
+
}
|
|
75
|
+
export declare class PgWorkflowRunStore extends SqlWorkflowRunStore {
|
|
76
|
+
constructor(pool: PgPool);
|
|
77
|
+
}
|
|
78
|
+
export declare class PgWorkflowCompletionInbox extends SqlWorkflowCompletionInbox {
|
|
79
|
+
constructor(pool: PgPool, onWarn?: InboxWarn);
|
|
80
|
+
}
|
|
81
|
+
export declare class PgWorkflowNotifyJournalStore extends SqlWorkflowNotifyJournalStore {
|
|
82
|
+
constructor(pool: PgPool);
|
|
83
|
+
}
|
|
84
|
+
export {};
|
|
85
|
+
//# sourceMappingURL=workflow-run-store-sql.d.ts.map
|