opencastle 0.26.1 → 0.27.1
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 +7 -1
- package/bin/cli.mjs +10 -0
- package/dist/cli/agents.d.ts +3 -0
- package/dist/cli/agents.d.ts.map +1 -0
- package/dist/cli/agents.js +161 -0
- package/dist/cli/agents.js.map +1 -0
- package/dist/cli/baselines.d.ts +3 -0
- package/dist/cli/baselines.d.ts.map +1 -0
- package/dist/cli/baselines.js +128 -0
- package/dist/cli/baselines.js.map +1 -0
- package/dist/cli/convoy/engine.d.ts +68 -2
- package/dist/cli/convoy/engine.d.ts.map +1 -1
- package/dist/cli/convoy/engine.js +2102 -26
- package/dist/cli/convoy/engine.js.map +1 -1
- package/dist/cli/convoy/engine.test.js +1572 -70
- package/dist/cli/convoy/engine.test.js.map +1 -1
- package/dist/cli/convoy/events.d.ts +4 -1
- package/dist/cli/convoy/events.d.ts.map +1 -1
- package/dist/cli/convoy/events.js +74 -13
- package/dist/cli/convoy/events.js.map +1 -1
- package/dist/cli/convoy/events.test.js +154 -27
- package/dist/cli/convoy/events.test.js.map +1 -1
- package/dist/cli/convoy/expertise.d.ts +16 -0
- package/dist/cli/convoy/expertise.d.ts.map +1 -0
- package/dist/cli/convoy/expertise.js +121 -0
- package/dist/cli/convoy/expertise.js.map +1 -0
- package/dist/cli/convoy/expertise.test.d.ts +2 -0
- package/dist/cli/convoy/expertise.test.d.ts.map +1 -0
- package/dist/cli/convoy/expertise.test.js +96 -0
- package/dist/cli/convoy/expertise.test.js.map +1 -0
- package/dist/cli/convoy/export.test.js +1 -0
- package/dist/cli/convoy/export.test.js.map +1 -1
- package/dist/cli/convoy/formula.d.ts +19 -0
- package/dist/cli/convoy/formula.d.ts.map +1 -0
- package/dist/cli/convoy/formula.js +142 -0
- package/dist/cli/convoy/formula.js.map +1 -0
- package/dist/cli/convoy/formula.test.d.ts +2 -0
- package/dist/cli/convoy/formula.test.d.ts.map +1 -0
- package/dist/cli/convoy/formula.test.js +342 -0
- package/dist/cli/convoy/formula.test.js.map +1 -0
- package/dist/cli/convoy/gates.d.ts +128 -0
- package/dist/cli/convoy/gates.d.ts.map +1 -0
- package/dist/cli/convoy/gates.js +606 -0
- package/dist/cli/convoy/gates.js.map +1 -0
- package/dist/cli/convoy/gates.test.d.ts +2 -0
- package/dist/cli/convoy/gates.test.d.ts.map +1 -0
- package/dist/cli/convoy/gates.test.js +976 -0
- package/dist/cli/convoy/gates.test.js.map +1 -0
- package/dist/cli/convoy/health.d.ts +11 -0
- package/dist/cli/convoy/health.d.ts.map +1 -1
- package/dist/cli/convoy/health.js +54 -0
- package/dist/cli/convoy/health.js.map +1 -1
- package/dist/cli/convoy/health.test.js +56 -1
- package/dist/cli/convoy/health.test.js.map +1 -1
- package/dist/cli/convoy/issues.d.ts +8 -0
- package/dist/cli/convoy/issues.d.ts.map +1 -0
- package/dist/cli/convoy/issues.js +98 -0
- package/dist/cli/convoy/issues.js.map +1 -0
- package/dist/cli/convoy/issues.test.d.ts +2 -0
- package/dist/cli/convoy/issues.test.d.ts.map +1 -0
- package/dist/cli/convoy/issues.test.js +107 -0
- package/dist/cli/convoy/issues.test.js.map +1 -0
- package/dist/cli/convoy/knowledge.d.ts +5 -0
- package/dist/cli/convoy/knowledge.d.ts.map +1 -0
- package/dist/cli/convoy/knowledge.js +116 -0
- package/dist/cli/convoy/knowledge.js.map +1 -0
- package/dist/cli/convoy/knowledge.test.d.ts +2 -0
- package/dist/cli/convoy/knowledge.test.d.ts.map +1 -0
- package/dist/cli/convoy/knowledge.test.js +87 -0
- package/dist/cli/convoy/knowledge.test.js.map +1 -0
- package/dist/cli/convoy/lessons.d.ts +17 -0
- package/dist/cli/convoy/lessons.d.ts.map +1 -0
- package/dist/cli/convoy/lessons.js +149 -0
- package/dist/cli/convoy/lessons.js.map +1 -0
- package/dist/cli/convoy/lessons.test.d.ts +2 -0
- package/dist/cli/convoy/lessons.test.d.ts.map +1 -0
- package/dist/cli/convoy/lessons.test.js +135 -0
- package/dist/cli/convoy/lessons.test.js.map +1 -0
- package/dist/cli/convoy/lock.d.ts +13 -0
- package/dist/cli/convoy/lock.d.ts.map +1 -0
- package/dist/cli/convoy/lock.js +88 -0
- package/dist/cli/convoy/lock.js.map +1 -0
- package/dist/cli/convoy/lock.test.d.ts +2 -0
- package/dist/cli/convoy/lock.test.d.ts.map +1 -0
- package/dist/cli/convoy/lock.test.js +136 -0
- package/dist/cli/convoy/lock.test.js.map +1 -0
- package/dist/cli/convoy/merge.d.ts +4 -0
- package/dist/cli/convoy/merge.d.ts.map +1 -1
- package/dist/cli/convoy/merge.js +18 -1
- package/dist/cli/convoy/merge.js.map +1 -1
- package/dist/cli/convoy/merge.test.js +6 -7
- package/dist/cli/convoy/merge.test.js.map +1 -1
- package/dist/cli/convoy/partition.d.ts +51 -0
- package/dist/cli/convoy/partition.d.ts.map +1 -0
- package/dist/cli/convoy/partition.js +186 -0
- package/dist/cli/convoy/partition.js.map +1 -0
- package/dist/cli/convoy/partition.test.d.ts +2 -0
- package/dist/cli/convoy/partition.test.d.ts.map +1 -0
- package/dist/cli/convoy/partition.test.js +315 -0
- package/dist/cli/convoy/partition.test.js.map +1 -0
- package/dist/cli/convoy/pipeline.test.js +6 -0
- package/dist/cli/convoy/pipeline.test.js.map +1 -1
- package/dist/cli/convoy/store.d.ts +47 -5
- package/dist/cli/convoy/store.d.ts.map +1 -1
- package/dist/cli/convoy/store.js +525 -19
- package/dist/cli/convoy/store.js.map +1 -1
- package/dist/cli/convoy/store.test.js +1345 -12
- package/dist/cli/convoy/store.test.js.map +1 -1
- package/dist/cli/convoy/types.d.ts +156 -2
- package/dist/cli/convoy/types.d.ts.map +1 -1
- package/dist/cli/destroy.d.ts +3 -0
- package/dist/cli/destroy.d.ts.map +1 -0
- package/dist/cli/destroy.js +69 -0
- package/dist/cli/destroy.js.map +1 -0
- package/dist/cli/destroy.test.d.ts +2 -0
- package/dist/cli/destroy.test.d.ts.map +1 -0
- package/dist/cli/destroy.test.js +116 -0
- package/dist/cli/destroy.test.js.map +1 -0
- package/dist/cli/gitignore.d.ts +9 -0
- package/dist/cli/gitignore.d.ts.map +1 -1
- package/dist/cli/gitignore.js +29 -0
- package/dist/cli/gitignore.js.map +1 -1
- package/dist/cli/plan.d.ts +3 -0
- package/dist/cli/plan.d.ts.map +1 -0
- package/dist/cli/plan.js +288 -0
- package/dist/cli/plan.js.map +1 -0
- package/dist/cli/run/adapters/claude.d.ts +2 -0
- package/dist/cli/run/adapters/claude.d.ts.map +1 -1
- package/dist/cli/run/adapters/claude.js +89 -49
- package/dist/cli/run/adapters/claude.js.map +1 -1
- package/dist/cli/run/adapters/claude.test.d.ts +2 -0
- package/dist/cli/run/adapters/claude.test.d.ts.map +1 -0
- package/dist/cli/run/adapters/claude.test.js +205 -0
- package/dist/cli/run/adapters/claude.test.js.map +1 -0
- package/dist/cli/run/adapters/copilot.d.ts +1 -0
- package/dist/cli/run/adapters/copilot.d.ts.map +1 -1
- package/dist/cli/run/adapters/copilot.js +84 -46
- package/dist/cli/run/adapters/copilot.js.map +1 -1
- package/dist/cli/run/adapters/copilot.test.d.ts +2 -0
- package/dist/cli/run/adapters/copilot.test.d.ts.map +1 -0
- package/dist/cli/run/adapters/copilot.test.js +195 -0
- package/dist/cli/run/adapters/copilot.test.js.map +1 -0
- package/dist/cli/run/adapters/cursor.d.ts +1 -0
- package/dist/cli/run/adapters/cursor.d.ts.map +1 -1
- package/dist/cli/run/adapters/cursor.js +83 -47
- package/dist/cli/run/adapters/cursor.js.map +1 -1
- package/dist/cli/run/adapters/cursor.test.d.ts +2 -0
- package/dist/cli/run/adapters/cursor.test.d.ts.map +1 -0
- package/dist/cli/run/adapters/cursor.test.js +129 -0
- package/dist/cli/run/adapters/cursor.test.js.map +1 -0
- package/dist/cli/run/adapters/opencode.d.ts +1 -0
- package/dist/cli/run/adapters/opencode.d.ts.map +1 -1
- package/dist/cli/run/adapters/opencode.js +81 -47
- package/dist/cli/run/adapters/opencode.js.map +1 -1
- package/dist/cli/run/adapters/opencode.test.d.ts +2 -0
- package/dist/cli/run/adapters/opencode.test.d.ts.map +1 -0
- package/dist/cli/run/adapters/opencode.test.js +119 -0
- package/dist/cli/run/adapters/opencode.test.js.map +1 -0
- package/dist/cli/run/executor.js +1 -1
- package/dist/cli/run/executor.js.map +1 -1
- package/dist/cli/run/schema.d.ts.map +1 -1
- package/dist/cli/run/schema.js +245 -4
- package/dist/cli/run/schema.js.map +1 -1
- package/dist/cli/run/schema.test.js +669 -0
- package/dist/cli/run/schema.test.js.map +1 -1
- package/dist/cli/run.d.ts.map +1 -1
- package/dist/cli/run.js +362 -22
- package/dist/cli/run.js.map +1 -1
- package/dist/cli/types.d.ts +85 -2
- package/dist/cli/types.d.ts.map +1 -1
- package/dist/cli/types.js.map +1 -1
- package/dist/cli/watch.d.ts +15 -0
- package/dist/cli/watch.d.ts.map +1 -0
- package/dist/cli/watch.js +279 -0
- package/dist/cli/watch.js.map +1 -0
- package/package.json +1 -1
- package/src/cli/agents.ts +177 -0
- package/src/cli/baselines.ts +143 -0
- package/src/cli/convoy/engine.test.ts +1839 -70
- package/src/cli/convoy/engine.ts +2417 -38
- package/src/cli/convoy/events.test.ts +179 -38
- package/src/cli/convoy/events.ts +88 -16
- package/src/cli/convoy/expertise.test.ts +128 -0
- package/src/cli/convoy/expertise.ts +163 -0
- package/src/cli/convoy/export.test.ts +1 -0
- package/src/cli/convoy/formula.test.ts +405 -0
- package/src/cli/convoy/formula.ts +174 -0
- package/src/cli/convoy/gates.test.ts +1169 -0
- package/src/cli/convoy/gates.ts +774 -0
- package/src/cli/convoy/health.test.ts +64 -2
- package/src/cli/convoy/health.ts +80 -2
- package/src/cli/convoy/issues.test.ts +143 -0
- package/src/cli/convoy/issues.ts +136 -0
- package/src/cli/convoy/knowledge.test.ts +101 -0
- package/src/cli/convoy/knowledge.ts +132 -0
- package/src/cli/convoy/lessons.test.ts +188 -0
- package/src/cli/convoy/lessons.ts +164 -0
- package/src/cli/convoy/lock.test.ts +181 -0
- package/src/cli/convoy/lock.ts +103 -0
- package/src/cli/convoy/merge.test.ts +6 -7
- package/src/cli/convoy/merge.ts +19 -1
- package/src/cli/convoy/partition.test.ts +423 -0
- package/src/cli/convoy/partition.ts +232 -0
- package/src/cli/convoy/pipeline.test.ts +6 -0
- package/src/cli/convoy/store.test.ts +1512 -14
- package/src/cli/convoy/store.ts +676 -30
- package/src/cli/convoy/types.ts +170 -1
- package/src/cli/destroy.test.ts +141 -0
- package/src/cli/destroy.ts +88 -0
- package/src/cli/gitignore.ts +36 -0
- package/src/cli/plan.ts +316 -0
- package/src/cli/run/adapters/claude.test.ts +234 -0
- package/src/cli/run/adapters/claude.ts +45 -5
- package/src/cli/run/adapters/copilot.test.ts +224 -0
- package/src/cli/run/adapters/copilot.ts +34 -4
- package/src/cli/run/adapters/cursor.test.ts +144 -0
- package/src/cli/run/adapters/cursor.ts +33 -2
- package/src/cli/run/adapters/opencode.test.ts +135 -0
- package/src/cli/run/adapters/opencode.ts +30 -2
- package/src/cli/run/executor.ts +1 -1
- package/src/cli/run/schema.test.ts +758 -0
- package/src/cli/run/schema.ts +300 -25
- package/src/cli/run.ts +341 -21
- package/src/cli/types.ts +86 -1
- package/src/cli/watch.ts +298 -0
- package/src/dashboard/node_modules/.vite/deps/_metadata.json +6 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/cli/convoy/store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,cAAc,EACd,cAAc,EACf,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/cli/convoy/store.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/convoy/store.js
CHANGED
|
@@ -1,8 +1,48 @@
|
|
|
1
|
+
import { copyFileSync } from 'node:fs';
|
|
1
2
|
import { DatabaseSync } from 'node:sqlite';
|
|
2
|
-
const SCHEMA_VERSION =
|
|
3
|
+
const SCHEMA_VERSION = 9;
|
|
4
|
+
// ── Size limits (bytes) ────────────────────────────────────────────────────────
|
|
5
|
+
const LIMIT_SPEC_YAML = 256 * 1024; // 256 KB
|
|
6
|
+
const LIMIT_OUTPUT = 1024 * 1024; // 1 MB (head 512KB + tail 512KB)
|
|
7
|
+
const LIMIT_OUTPUT_HALF = 512 * 1024; // 512 KB per half
|
|
8
|
+
const LIMIT_EVENT_DATA = 64 * 1024; // 64 KB
|
|
9
|
+
const LIMIT_SUMMARY = 4096; // 4 KB
|
|
10
|
+
export class FieldSizeLimitError extends Error {
|
|
11
|
+
constructor(field, actual, limit) {
|
|
12
|
+
super(`Field "${field}" exceeds size limit: ${actual} bytes > ${limit} bytes`);
|
|
13
|
+
this.name = 'FieldSizeLimitError';
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function enforceLimit(value, field, limit) {
|
|
17
|
+
if (value == null)
|
|
18
|
+
return;
|
|
19
|
+
const size = Buffer.byteLength(value, 'utf8');
|
|
20
|
+
if (size > limit) {
|
|
21
|
+
throw new FieldSizeLimitError(field, size, limit);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function truncateOutput(value) {
|
|
25
|
+
if (value == null)
|
|
26
|
+
return null;
|
|
27
|
+
const size = Buffer.byteLength(value, 'utf8');
|
|
28
|
+
if (size <= LIMIT_OUTPUT)
|
|
29
|
+
return value;
|
|
30
|
+
// Head + tail truncation with marker
|
|
31
|
+
const head = value.slice(0, LIMIT_OUTPUT_HALF);
|
|
32
|
+
const tail = value.slice(-LIMIT_OUTPUT_HALF);
|
|
33
|
+
return head + '\n\n... [truncated: ' + size + ' bytes total, showing first/last 512KB] ...\n\n' + tail;
|
|
34
|
+
}
|
|
35
|
+
export class ConvoyArtifactLimitError extends Error {
|
|
36
|
+
constructor(convoyId) {
|
|
37
|
+
super(`Convoy ${convoyId} has reached the maximum of 50 artifacts`);
|
|
38
|
+
this.name = 'ConvoyArtifactLimitError';
|
|
39
|
+
}
|
|
40
|
+
}
|
|
3
41
|
class ConvoyStoreImpl {
|
|
4
42
|
db;
|
|
43
|
+
dbPath;
|
|
5
44
|
constructor(dbPath) {
|
|
45
|
+
this.dbPath = dbPath;
|
|
6
46
|
this.db = new DatabaseSync(dbPath);
|
|
7
47
|
this.db.exec('PRAGMA journal_mode = WAL');
|
|
8
48
|
this.db.exec('PRAGMA synchronous = NORMAL');
|
|
@@ -13,18 +53,21 @@ class ConvoyStoreImpl {
|
|
|
13
53
|
if (version === 0) {
|
|
14
54
|
this.db.exec(`
|
|
15
55
|
CREATE TABLE IF NOT EXISTS convoy (
|
|
16
|
-
id
|
|
17
|
-
name
|
|
18
|
-
spec_hash
|
|
19
|
-
status
|
|
20
|
-
branch
|
|
21
|
-
created_at
|
|
22
|
-
started_at
|
|
23
|
-
finished_at
|
|
24
|
-
spec_yaml
|
|
25
|
-
total_tokens
|
|
26
|
-
total_cost_usd
|
|
27
|
-
pipeline_id
|
|
56
|
+
id TEXT PRIMARY KEY,
|
|
57
|
+
name TEXT NOT NULL,
|
|
58
|
+
spec_hash TEXT NOT NULL,
|
|
59
|
+
status TEXT NOT NULL DEFAULT 'pending',
|
|
60
|
+
branch TEXT,
|
|
61
|
+
created_at TEXT NOT NULL,
|
|
62
|
+
started_at TEXT,
|
|
63
|
+
finished_at TEXT,
|
|
64
|
+
spec_yaml TEXT NOT NULL,
|
|
65
|
+
total_tokens INTEGER,
|
|
66
|
+
total_cost_usd TEXT,
|
|
67
|
+
pipeline_id TEXT,
|
|
68
|
+
circuit_state TEXT,
|
|
69
|
+
review_tokens_total INTEGER,
|
|
70
|
+
review_budget INTEGER
|
|
28
71
|
);
|
|
29
72
|
|
|
30
73
|
CREATE TABLE IF NOT EXISTS pipeline (
|
|
@@ -64,7 +107,41 @@ class ConvoyStoreImpl {
|
|
|
64
107
|
prompt_tokens INTEGER,
|
|
65
108
|
completion_tokens INTEGER,
|
|
66
109
|
total_tokens INTEGER,
|
|
67
|
-
cost_usd TEXT
|
|
110
|
+
cost_usd TEXT,
|
|
111
|
+
gates TEXT,
|
|
112
|
+
on_exhausted TEXT NOT NULL DEFAULT 'dlq',
|
|
113
|
+
injected INTEGER NOT NULL DEFAULT 0,
|
|
114
|
+
provenance TEXT,
|
|
115
|
+
idempotency_key TEXT,
|
|
116
|
+
current_step INTEGER,
|
|
117
|
+
total_steps INTEGER,
|
|
118
|
+
review_level TEXT,
|
|
119
|
+
review_verdict TEXT,
|
|
120
|
+
review_tokens INTEGER,
|
|
121
|
+
review_model TEXT,
|
|
122
|
+
panel_attempts INTEGER NOT NULL DEFAULT 0,
|
|
123
|
+
dispute_id TEXT,
|
|
124
|
+
drift_score REAL,
|
|
125
|
+
drift_retried INTEGER NOT NULL DEFAULT 0,
|
|
126
|
+
outputs TEXT,
|
|
127
|
+
inputs TEXT,
|
|
128
|
+
discovered_issues TEXT
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_task_idempotency ON task(convoy_id, idempotency_key)
|
|
132
|
+
WHERE idempotency_key IS NOT NULL;
|
|
133
|
+
|
|
134
|
+
CREATE TABLE IF NOT EXISTS task_step (
|
|
135
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
136
|
+
task_id TEXT NOT NULL REFERENCES task(id),
|
|
137
|
+
step_index INTEGER NOT NULL,
|
|
138
|
+
prompt TEXT NOT NULL,
|
|
139
|
+
gates TEXT,
|
|
140
|
+
status TEXT NOT NULL DEFAULT 'pending',
|
|
141
|
+
exit_code INTEGER,
|
|
142
|
+
output TEXT,
|
|
143
|
+
started_at TEXT,
|
|
144
|
+
finished_at TEXT
|
|
68
145
|
);
|
|
69
146
|
|
|
70
147
|
CREATE TABLE IF NOT EXISTS worker (
|
|
@@ -89,6 +166,57 @@ class ConvoyStoreImpl {
|
|
|
89
166
|
data TEXT,
|
|
90
167
|
created_at TEXT NOT NULL
|
|
91
168
|
);
|
|
169
|
+
|
|
170
|
+
CREATE TABLE IF NOT EXISTS dlq (
|
|
171
|
+
id TEXT PRIMARY KEY,
|
|
172
|
+
convoy_id TEXT NOT NULL REFERENCES convoy(id),
|
|
173
|
+
task_id TEXT NOT NULL REFERENCES task(id),
|
|
174
|
+
agent TEXT NOT NULL,
|
|
175
|
+
failure_type TEXT NOT NULL,
|
|
176
|
+
error_output TEXT,
|
|
177
|
+
attempts INTEGER NOT NULL,
|
|
178
|
+
tokens_spent INTEGER,
|
|
179
|
+
escalation_task_id TEXT,
|
|
180
|
+
resolved INTEGER NOT NULL DEFAULT 0,
|
|
181
|
+
resolution TEXT,
|
|
182
|
+
created_at TEXT NOT NULL,
|
|
183
|
+
resolved_at TEXT
|
|
184
|
+
);
|
|
185
|
+
|
|
186
|
+
CREATE TABLE IF NOT EXISTS artifact (
|
|
187
|
+
id TEXT PRIMARY KEY,
|
|
188
|
+
convoy_id TEXT NOT NULL REFERENCES convoy(id),
|
|
189
|
+
task_id TEXT NOT NULL REFERENCES task(id),
|
|
190
|
+
name TEXT NOT NULL,
|
|
191
|
+
type TEXT NOT NULL,
|
|
192
|
+
content TEXT NOT NULL CHECK (length(content) <= 1048576),
|
|
193
|
+
created_at TEXT NOT NULL,
|
|
194
|
+
UNIQUE(convoy_id, name)
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
CREATE TABLE IF NOT EXISTS agent_identity (
|
|
198
|
+
id TEXT PRIMARY KEY,
|
|
199
|
+
agent TEXT NOT NULL,
|
|
200
|
+
convoy_id TEXT NOT NULL,
|
|
201
|
+
task_id TEXT NOT NULL,
|
|
202
|
+
summary TEXT NOT NULL,
|
|
203
|
+
created_at TEXT NOT NULL,
|
|
204
|
+
retention_days INTEGER NOT NULL DEFAULT 90
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
CREATE TABLE IF NOT EXISTS scratchpad (
|
|
208
|
+
key TEXT PRIMARY KEY,
|
|
209
|
+
value TEXT NOT NULL,
|
|
210
|
+
updated_at TEXT NOT NULL
|
|
211
|
+
);
|
|
212
|
+
|
|
213
|
+
CREATE TABLE IF NOT EXISTS engine_lock (
|
|
214
|
+
id INTEGER PRIMARY KEY,
|
|
215
|
+
pid INTEGER NOT NULL,
|
|
216
|
+
hostname TEXT NOT NULL,
|
|
217
|
+
started_at TEXT NOT NULL,
|
|
218
|
+
last_heartbeat TEXT NOT NULL
|
|
219
|
+
);
|
|
92
220
|
`);
|
|
93
221
|
this.db.exec(`PRAGMA user_version = ${SCHEMA_VERSION}`);
|
|
94
222
|
version = SCHEMA_VERSION;
|
|
@@ -128,11 +256,36 @@ class ConvoyStoreImpl {
|
|
|
128
256
|
this.db.exec('PRAGMA user_version = 4');
|
|
129
257
|
version = 4;
|
|
130
258
|
}
|
|
259
|
+
if (version === 4) {
|
|
260
|
+
migrateSchema(this.db, this.dbPath, 4, 5);
|
|
261
|
+
version = 5;
|
|
262
|
+
}
|
|
263
|
+
if (version === 5) {
|
|
264
|
+
migrateSchema(this.db, this.dbPath, 5, 6);
|
|
265
|
+
version = 6;
|
|
266
|
+
}
|
|
267
|
+
if (version === 6) {
|
|
268
|
+
migrateSchema(this.db, this.dbPath, 6, 7);
|
|
269
|
+
version = 7;
|
|
270
|
+
}
|
|
271
|
+
if (version === 7) {
|
|
272
|
+
migrateSchema(this.db, this.dbPath, 7, 8);
|
|
273
|
+
version = 8;
|
|
274
|
+
}
|
|
275
|
+
if (version === 8) {
|
|
276
|
+
migrateSchema(this.db, this.dbPath, 8, 9);
|
|
277
|
+
version = 9;
|
|
278
|
+
}
|
|
131
279
|
}
|
|
132
280
|
insertConvoy(record) {
|
|
281
|
+
enforceLimit(record.spec_yaml, 'spec_yaml', LIMIT_SPEC_YAML);
|
|
133
282
|
this.db
|
|
134
|
-
.prepare(`INSERT INTO convoy
|
|
135
|
-
|
|
283
|
+
.prepare(`INSERT INTO convoy
|
|
284
|
+
(id, name, spec_hash, status, branch, created_at, started_at, finished_at,
|
|
285
|
+
spec_yaml, pipeline_id)
|
|
286
|
+
VALUES
|
|
287
|
+
(:id, :name, :spec_hash, :status, :branch, :created_at, NULL, NULL,
|
|
288
|
+
:spec_yaml, :pipeline_id)`)
|
|
136
289
|
.run({ ...record, pipeline_id: record.pipeline_id ?? null });
|
|
137
290
|
}
|
|
138
291
|
getConvoy(id) {
|
|
@@ -166,16 +319,52 @@ class ConvoyStoreImpl {
|
|
|
166
319
|
}
|
|
167
320
|
this.db.prepare(`UPDATE convoy SET ${sets.join(', ')} WHERE id = :id`).run(params);
|
|
168
321
|
}
|
|
322
|
+
updateConvoyReviewTokens(convoyId, tokens) {
|
|
323
|
+
this.db
|
|
324
|
+
.prepare(`UPDATE convoy
|
|
325
|
+
SET review_tokens_total = :tokens
|
|
326
|
+
WHERE id = :id`)
|
|
327
|
+
.run({ id: convoyId, tokens });
|
|
328
|
+
}
|
|
329
|
+
updateConvoyCircuitState(convoyId, state) {
|
|
330
|
+
this.db
|
|
331
|
+
.prepare('UPDATE convoy SET circuit_state = :state WHERE id = :id')
|
|
332
|
+
.run({ id: convoyId, state: state ?? null });
|
|
333
|
+
}
|
|
169
334
|
insertTask(record) {
|
|
170
335
|
this.db
|
|
171
336
|
.prepare(`INSERT INTO task
|
|
172
337
|
(id, convoy_id, phase, prompt, agent, adapter, model, timeout_ms, status,
|
|
173
338
|
worker_id, worktree, output, exit_code, started_at, finished_at,
|
|
174
|
-
retries, max_retries, files, depends_on
|
|
339
|
+
retries, max_retries, files, depends_on, gates,
|
|
340
|
+
on_exhausted, injected, provenance, idempotency_key,
|
|
341
|
+
outputs, inputs)
|
|
175
342
|
VALUES
|
|
176
343
|
(:id, :convoy_id, :phase, :prompt, :agent, :adapter, :model, :timeout_ms, :status,
|
|
177
344
|
NULL, NULL, NULL, NULL, NULL, NULL,
|
|
178
|
-
:retries, :max_retries, :files, :depends_on
|
|
345
|
+
:retries, :max_retries, :files, :depends_on, :gates,
|
|
346
|
+
'dlq', 0, NULL, NULL,
|
|
347
|
+
:outputs, :inputs)`)
|
|
348
|
+
.run({ ...record, outputs: record.outputs ?? null, inputs: record.inputs ?? null });
|
|
349
|
+
}
|
|
350
|
+
insertInjectedTask(record) {
|
|
351
|
+
this.db
|
|
352
|
+
.prepare(`INSERT INTO task
|
|
353
|
+
(id, convoy_id, phase, prompt, agent, adapter, model, timeout_ms, status,
|
|
354
|
+
worker_id, worktree, output, exit_code, started_at, finished_at,
|
|
355
|
+
retries, max_retries, files, depends_on, gates,
|
|
356
|
+
on_exhausted, injected, provenance, idempotency_key,
|
|
357
|
+
current_step, total_steps, review_level, review_verdict,
|
|
358
|
+
review_tokens, review_model, panel_attempts, dispute_id,
|
|
359
|
+
drift_score, drift_retried, outputs, inputs, discovered_issues)
|
|
360
|
+
VALUES
|
|
361
|
+
(:id, :convoy_id, :phase, :prompt, :agent, :adapter, :model, :timeout_ms, :status,
|
|
362
|
+
:worker_id, :worktree, :output, :exit_code, :started_at, :finished_at,
|
|
363
|
+
:retries, :max_retries, :files, :depends_on, :gates,
|
|
364
|
+
:on_exhausted, :injected, :provenance, :idempotency_key,
|
|
365
|
+
:current_step, :total_steps, :review_level, :review_verdict,
|
|
366
|
+
:review_tokens, :review_model, :panel_attempts, :dispute_id,
|
|
367
|
+
:drift_score, :drift_retried, :outputs, :inputs, :discovered_issues)`)
|
|
179
368
|
.run(record);
|
|
180
369
|
}
|
|
181
370
|
getTask(id, convoyId) {
|
|
@@ -188,10 +377,36 @@ class ConvoyStoreImpl {
|
|
|
188
377
|
.prepare('SELECT * FROM task WHERE convoy_id = :convoy_id ORDER BY phase, id')
|
|
189
378
|
.all({ convoy_id: convoyId });
|
|
190
379
|
}
|
|
380
|
+
getTaskByIdempotencyKey(convoyId, key) {
|
|
381
|
+
return this.db
|
|
382
|
+
.prepare('SELECT * FROM task WHERE convoy_id = :convoy_id AND idempotency_key = :key')
|
|
383
|
+
.get({ convoy_id: convoyId, key });
|
|
384
|
+
}
|
|
385
|
+
getTaskByDisputeId(disputeId) {
|
|
386
|
+
return this.db
|
|
387
|
+
.prepare('SELECT * FROM task WHERE dispute_id = :dispute_id LIMIT 1')
|
|
388
|
+
.get({ dispute_id: disputeId });
|
|
389
|
+
}
|
|
390
|
+
getDisputedTasks(convoyId) {
|
|
391
|
+
if (convoyId) {
|
|
392
|
+
return this.db
|
|
393
|
+
.prepare("SELECT * FROM task WHERE status = 'disputed' AND convoy_id = :convoy_id ORDER BY phase, id")
|
|
394
|
+
.all({ convoy_id: convoyId });
|
|
395
|
+
}
|
|
396
|
+
return this.db
|
|
397
|
+
.prepare("SELECT * FROM task WHERE status = 'disputed' ORDER BY convoy_id, phase, id")
|
|
398
|
+
.all({});
|
|
399
|
+
}
|
|
191
400
|
updateTaskStatus(id, convoyId, status, extra) {
|
|
401
|
+
if (extra?.output !== undefined) {
|
|
402
|
+
extra = { ...extra, output: truncateOutput(extra.output) };
|
|
403
|
+
}
|
|
192
404
|
const sets = ['status = :status'];
|
|
193
405
|
const params = { id, convoy_id: convoyId, status };
|
|
194
|
-
const extraFields = [
|
|
406
|
+
const extraFields = [
|
|
407
|
+
'worker_id', 'worktree', 'output', 'exit_code', 'started_at', 'finished_at',
|
|
408
|
+
'retries', 'prompt_tokens', 'completion_tokens', 'total_tokens', 'cost_usd', 'prompt',
|
|
409
|
+
];
|
|
195
410
|
if (extra) {
|
|
196
411
|
for (const field of extraFields) {
|
|
197
412
|
if (field in extra && extra[field] !== undefined) {
|
|
@@ -216,6 +431,65 @@ class ConvoyStoreImpl {
|
|
|
216
431
|
return deps.length === 0 || deps.every(depId => doneTaskIds.has(depId));
|
|
217
432
|
});
|
|
218
433
|
}
|
|
434
|
+
insertTaskStep(record) {
|
|
435
|
+
this.db
|
|
436
|
+
.prepare(`INSERT INTO task_step
|
|
437
|
+
(task_id, step_index, prompt, gates, status, exit_code, output, started_at, finished_at)
|
|
438
|
+
VALUES
|
|
439
|
+
(:task_id, :step_index, :prompt, :gates, :status, :exit_code, :output, :started_at, :finished_at)`)
|
|
440
|
+
.run(record);
|
|
441
|
+
const row = this.db.prepare('SELECT last_insert_rowid() AS id').get();
|
|
442
|
+
return row.id;
|
|
443
|
+
}
|
|
444
|
+
updateTaskStep(id, fields) {
|
|
445
|
+
const sets = [];
|
|
446
|
+
const params = { id };
|
|
447
|
+
const stepFields = ['status', 'exit_code', 'output', 'started_at', 'finished_at'];
|
|
448
|
+
for (const field of stepFields) {
|
|
449
|
+
if (field in fields && fields[field] !== undefined) {
|
|
450
|
+
sets.push(`${field} = :${field}`);
|
|
451
|
+
params[field] = fields[field];
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
if (sets.length === 0)
|
|
455
|
+
return;
|
|
456
|
+
this.db.prepare(`UPDATE task_step SET ${sets.join(', ')} WHERE id = :id`).run(params);
|
|
457
|
+
}
|
|
458
|
+
updateTaskReview(taskId, convoyId, fields) {
|
|
459
|
+
const sets = [];
|
|
460
|
+
const params = { id: taskId, convoy_id: convoyId };
|
|
461
|
+
const reviewFields = ['review_level', 'review_verdict', 'review_tokens', 'review_model', 'panel_attempts', 'dispute_id'];
|
|
462
|
+
for (const field of reviewFields) {
|
|
463
|
+
if (field in fields && fields[field] !== undefined) {
|
|
464
|
+
sets.push(`${field} = :${field}`);
|
|
465
|
+
params[field] = fields[field];
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
if (sets.length === 0)
|
|
469
|
+
return;
|
|
470
|
+
this.db.prepare(`UPDATE task SET ${sets.join(', ')} WHERE id = :id AND convoy_id = :convoy_id`).run(params);
|
|
471
|
+
}
|
|
472
|
+
updateTaskDrift(taskId, convoyId, fields) {
|
|
473
|
+
const sets = [];
|
|
474
|
+
const params = { id: taskId, convoy_id: convoyId };
|
|
475
|
+
if (fields.drift_score !== undefined) {
|
|
476
|
+
sets.push('drift_score = :drift_score');
|
|
477
|
+
params.drift_score = fields.drift_score;
|
|
478
|
+
}
|
|
479
|
+
if (fields.drift_retried !== undefined) {
|
|
480
|
+
sets.push('drift_retried = :drift_retried');
|
|
481
|
+
params.drift_retried = fields.drift_retried;
|
|
482
|
+
}
|
|
483
|
+
if (sets.length === 0)
|
|
484
|
+
return;
|
|
485
|
+
this.db.prepare(`UPDATE task SET ${sets.join(', ')} WHERE id = :id AND convoy_id = :convoy_id`).run(params);
|
|
486
|
+
}
|
|
487
|
+
updateTaskDisputeStatus(taskId, convoyId, status, disputeId) {
|
|
488
|
+
this.db
|
|
489
|
+
.prepare(`UPDATE task SET status = :status, dispute_id = :dispute_id
|
|
490
|
+
WHERE id = :id AND convoy_id = :convoy_id`)
|
|
491
|
+
.run({ id: taskId, convoy_id: convoyId, status, dispute_id: disputeId });
|
|
492
|
+
}
|
|
219
493
|
insertWorker(record) {
|
|
220
494
|
this.db
|
|
221
495
|
.prepare(`INSERT INTO worker
|
|
@@ -249,17 +523,137 @@ class ConvoyStoreImpl {
|
|
|
249
523
|
this.db.prepare(`UPDATE worker SET ${sets.join(', ')} WHERE id = :id`).run(params);
|
|
250
524
|
}
|
|
251
525
|
insertEvent(record) {
|
|
526
|
+
enforceLimit(record.data, 'event.data', LIMIT_EVENT_DATA);
|
|
252
527
|
this.db
|
|
253
528
|
.prepare(`INSERT INTO event (convoy_id, task_id, worker_id, type, data, created_at)
|
|
254
529
|
VALUES (:convoy_id, :task_id, :worker_id, :type, :data, :created_at)`)
|
|
255
530
|
.run(record);
|
|
531
|
+
const row = this.db.prepare('SELECT last_insert_rowid() AS id').get();
|
|
532
|
+
return row.id;
|
|
256
533
|
}
|
|
257
534
|
getEvents(convoyId) {
|
|
258
535
|
return this.db
|
|
259
536
|
.prepare('SELECT * FROM event WHERE convoy_id = :convoy_id ORDER BY id')
|
|
260
537
|
.all({ convoy_id: convoyId });
|
|
261
538
|
}
|
|
539
|
+
insertDlqEntry(record) {
|
|
540
|
+
this.db
|
|
541
|
+
.prepare(`INSERT INTO dlq
|
|
542
|
+
(id, convoy_id, task_id, agent, failure_type, error_output, attempts,
|
|
543
|
+
tokens_spent, escalation_task_id, resolved, resolution, created_at, resolved_at)
|
|
544
|
+
VALUES
|
|
545
|
+
(:id, :convoy_id, :task_id, :agent, :failure_type, :error_output, :attempts,
|
|
546
|
+
:tokens_spent, :escalation_task_id, :resolved, :resolution, :created_at, :resolved_at)`)
|
|
547
|
+
.run(record);
|
|
548
|
+
}
|
|
549
|
+
listDlqEntries(convoyIdFilter) {
|
|
550
|
+
if (convoyIdFilter) {
|
|
551
|
+
return this.db
|
|
552
|
+
.prepare('SELECT * FROM dlq WHERE convoy_id = :convoy_id ORDER BY created_at DESC')
|
|
553
|
+
.all({ convoy_id: convoyIdFilter });
|
|
554
|
+
}
|
|
555
|
+
return this.db
|
|
556
|
+
.prepare('SELECT * FROM dlq ORDER BY created_at DESC')
|
|
557
|
+
.all();
|
|
558
|
+
}
|
|
559
|
+
resolveDlqEntry(id, resolution) {
|
|
560
|
+
this.db
|
|
561
|
+
.prepare(`UPDATE dlq SET resolved = 1, resolution = :resolution, resolved_at = :resolved_at
|
|
562
|
+
WHERE id = :id`)
|
|
563
|
+
.run({ id, resolution, resolved_at: new Date().toISOString() });
|
|
564
|
+
}
|
|
565
|
+
insertArtifact(record) {
|
|
566
|
+
const count = this.db
|
|
567
|
+
.prepare('SELECT COUNT(*) AS cnt FROM artifact WHERE convoy_id = :convoy_id')
|
|
568
|
+
.get({ convoy_id: record.convoy_id }).cnt;
|
|
569
|
+
if (count >= 50) {
|
|
570
|
+
throw new ConvoyArtifactLimitError(record.convoy_id);
|
|
571
|
+
}
|
|
572
|
+
this.db
|
|
573
|
+
.prepare(`INSERT INTO artifact (id, convoy_id, task_id, name, type, content, created_at)
|
|
574
|
+
VALUES (:id, :convoy_id, :task_id, :name, :type, :content, :created_at)`)
|
|
575
|
+
.run(record);
|
|
576
|
+
}
|
|
577
|
+
getArtifact(convoyId, name) {
|
|
578
|
+
return this.db
|
|
579
|
+
.prepare('SELECT * FROM artifact WHERE convoy_id = :convoy_id AND name = :name')
|
|
580
|
+
.get({ convoy_id: convoyId, name });
|
|
581
|
+
}
|
|
582
|
+
getArtifactsByTask(taskId) {
|
|
583
|
+
return this.db
|
|
584
|
+
.prepare('SELECT * FROM artifact WHERE task_id = :task_id ORDER BY created_at')
|
|
585
|
+
.all({ task_id: taskId });
|
|
586
|
+
}
|
|
587
|
+
deleteArtifactsOlderThan(days) {
|
|
588
|
+
const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString();
|
|
589
|
+
const result = this.db
|
|
590
|
+
.prepare(`DELETE FROM artifact WHERE convoy_id IN (
|
|
591
|
+
SELECT id FROM convoy WHERE finished_at IS NOT NULL AND finished_at < :cutoff
|
|
592
|
+
)`)
|
|
593
|
+
.run({ cutoff });
|
|
594
|
+
return result.changes;
|
|
595
|
+
}
|
|
596
|
+
insertAgentIdentity(record) {
|
|
597
|
+
const summarySize = Buffer.byteLength(record.summary, 'utf8');
|
|
598
|
+
const truncatedSummary = summarySize > LIMIT_SUMMARY
|
|
599
|
+
? record.summary.slice(0, LIMIT_SUMMARY)
|
|
600
|
+
: record.summary;
|
|
601
|
+
this.db
|
|
602
|
+
.prepare(`INSERT INTO agent_identity
|
|
603
|
+
(id, agent, convoy_id, task_id, summary, created_at, retention_days)
|
|
604
|
+
VALUES
|
|
605
|
+
(:id, :agent, :convoy_id, :task_id, :summary, :created_at, :retention_days)`)
|
|
606
|
+
.run({ ...record, summary: truncatedSummary });
|
|
607
|
+
}
|
|
608
|
+
getAgentIdentities(agent, limit) {
|
|
609
|
+
return this.db
|
|
610
|
+
.prepare('SELECT * FROM agent_identity WHERE agent = :agent ORDER BY created_at DESC LIMIT :limit')
|
|
611
|
+
.all({ agent, limit });
|
|
612
|
+
}
|
|
613
|
+
listAgentIdentitySummary() {
|
|
614
|
+
return this.db
|
|
615
|
+
.prepare(`SELECT agent, COUNT(*) AS task_count, MAX(created_at) AS latest_date
|
|
616
|
+
FROM agent_identity GROUP BY agent ORDER BY agent`)
|
|
617
|
+
.all();
|
|
618
|
+
}
|
|
619
|
+
purgeAgentIdentities(agent) {
|
|
620
|
+
const result = this.db
|
|
621
|
+
.prepare('DELETE FROM agent_identity WHERE agent = :agent')
|
|
622
|
+
.run({ agent });
|
|
623
|
+
return result.changes;
|
|
624
|
+
}
|
|
625
|
+
deleteAgentIdentitiesOlderThan(days) {
|
|
626
|
+
const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString();
|
|
627
|
+
const result = this.db
|
|
628
|
+
.prepare(`DELETE FROM agent_identity
|
|
629
|
+
WHERE created_at < :cutoff
|
|
630
|
+
OR (retention_days IS NOT NULL
|
|
631
|
+
AND created_at < datetime('now', '-' || retention_days || ' days'))`)
|
|
632
|
+
.run({ cutoff });
|
|
633
|
+
return result.changes;
|
|
634
|
+
}
|
|
635
|
+
getScratchpadValue(key) {
|
|
636
|
+
const row = this.db
|
|
637
|
+
.prepare('SELECT value FROM scratchpad WHERE key = :key')
|
|
638
|
+
.get({ key });
|
|
639
|
+
return row?.value ?? null;
|
|
640
|
+
}
|
|
641
|
+
setScratchpadValue(key, value) {
|
|
642
|
+
this.db
|
|
643
|
+
.prepare(`INSERT INTO scratchpad (key, value, updated_at)
|
|
644
|
+
VALUES (:key, :value, :updated_at)
|
|
645
|
+
ON CONFLICT(key) DO UPDATE SET value = excluded.value, updated_at = excluded.updated_at`)
|
|
646
|
+
.run({ key, value, updated_at: new Date().toISOString() });
|
|
647
|
+
}
|
|
648
|
+
clearScratchpad() {
|
|
649
|
+
this.db.exec('DELETE FROM scratchpad');
|
|
650
|
+
}
|
|
651
|
+
clearScratchpadOlderThan(days) {
|
|
652
|
+
const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString();
|
|
653
|
+
this.db.prepare('DELETE FROM scratchpad WHERE updated_at < :cutoff').run({ cutoff });
|
|
654
|
+
}
|
|
262
655
|
insertPipeline(record) {
|
|
656
|
+
enforceLimit(record.spec_yaml, 'pipeline.spec_yaml', LIMIT_SPEC_YAML);
|
|
263
657
|
this.db
|
|
264
658
|
.prepare(`INSERT INTO pipeline (id, name, status, branch, spec_yaml, convoy_specs, created_at,
|
|
265
659
|
started_at, finished_at, total_tokens, total_cost_usd)
|
|
@@ -319,6 +713,118 @@ class ConvoyStoreImpl {
|
|
|
319
713
|
this.db.close();
|
|
320
714
|
}
|
|
321
715
|
}
|
|
716
|
+
export function migrateSchema(db, dbPath, fromVersion, toVersion) {
|
|
717
|
+
for (let v = fromVersion; v < toVersion; v++) {
|
|
718
|
+
const backupPath = `${dbPath}.v${v}.bak`;
|
|
719
|
+
copyFileSync(dbPath, backupPath);
|
|
720
|
+
db.exec('BEGIN');
|
|
721
|
+
try {
|
|
722
|
+
if (v === 4) {
|
|
723
|
+
db.exec(`
|
|
724
|
+
ALTER TABLE task ADD COLUMN gates TEXT;
|
|
725
|
+
ALTER TABLE task ADD COLUMN on_exhausted TEXT NOT NULL DEFAULT 'dlq';
|
|
726
|
+
ALTER TABLE task ADD COLUMN injected INTEGER NOT NULL DEFAULT 0;
|
|
727
|
+
ALTER TABLE task ADD COLUMN provenance TEXT;
|
|
728
|
+
ALTER TABLE task ADD COLUMN idempotency_key TEXT;
|
|
729
|
+
CREATE UNIQUE INDEX idx_task_idempotency ON task(convoy_id, idempotency_key)
|
|
730
|
+
WHERE idempotency_key IS NOT NULL;
|
|
731
|
+
ALTER TABLE convoy ADD COLUMN circuit_state TEXT;
|
|
732
|
+
CREATE TABLE dlq (
|
|
733
|
+
id TEXT PRIMARY KEY,
|
|
734
|
+
convoy_id TEXT NOT NULL REFERENCES convoy(id),
|
|
735
|
+
task_id TEXT NOT NULL REFERENCES task(id),
|
|
736
|
+
agent TEXT NOT NULL,
|
|
737
|
+
failure_type TEXT NOT NULL,
|
|
738
|
+
error_output TEXT,
|
|
739
|
+
attempts INTEGER NOT NULL,
|
|
740
|
+
tokens_spent INTEGER,
|
|
741
|
+
escalation_task_id TEXT,
|
|
742
|
+
resolved INTEGER NOT NULL DEFAULT 0,
|
|
743
|
+
resolution TEXT,
|
|
744
|
+
created_at TEXT NOT NULL,
|
|
745
|
+
resolved_at TEXT
|
|
746
|
+
);
|
|
747
|
+
`);
|
|
748
|
+
}
|
|
749
|
+
if (v === 5) {
|
|
750
|
+
db.exec(`
|
|
751
|
+
ALTER TABLE task ADD COLUMN current_step INTEGER;
|
|
752
|
+
ALTER TABLE task ADD COLUMN total_steps INTEGER;
|
|
753
|
+
ALTER TABLE task ADD COLUMN review_level TEXT;
|
|
754
|
+
ALTER TABLE task ADD COLUMN review_verdict TEXT;
|
|
755
|
+
ALTER TABLE task ADD COLUMN review_tokens INTEGER;
|
|
756
|
+
ALTER TABLE task ADD COLUMN review_model TEXT;
|
|
757
|
+
ALTER TABLE task ADD COLUMN panel_attempts INTEGER NOT NULL DEFAULT 0;
|
|
758
|
+
ALTER TABLE task ADD COLUMN dispute_id TEXT;
|
|
759
|
+
ALTER TABLE convoy ADD COLUMN review_tokens_total INTEGER;
|
|
760
|
+
ALTER TABLE convoy ADD COLUMN review_budget INTEGER;
|
|
761
|
+
CREATE TABLE task_step (
|
|
762
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
763
|
+
task_id TEXT NOT NULL REFERENCES task(id),
|
|
764
|
+
step_index INTEGER NOT NULL,
|
|
765
|
+
prompt TEXT NOT NULL,
|
|
766
|
+
gates TEXT,
|
|
767
|
+
status TEXT NOT NULL DEFAULT 'pending',
|
|
768
|
+
exit_code INTEGER,
|
|
769
|
+
output TEXT,
|
|
770
|
+
started_at TEXT,
|
|
771
|
+
finished_at TEXT
|
|
772
|
+
);
|
|
773
|
+
`);
|
|
774
|
+
}
|
|
775
|
+
if (v === 6) {
|
|
776
|
+
db.exec(`
|
|
777
|
+
ALTER TABLE task ADD COLUMN drift_score REAL;
|
|
778
|
+
ALTER TABLE task ADD COLUMN drift_retried INTEGER NOT NULL DEFAULT 0;
|
|
779
|
+
`);
|
|
780
|
+
}
|
|
781
|
+
if (v === 7) {
|
|
782
|
+
db.exec(`
|
|
783
|
+
ALTER TABLE task ADD COLUMN outputs TEXT;
|
|
784
|
+
ALTER TABLE task ADD COLUMN inputs TEXT;
|
|
785
|
+
ALTER TABLE task ADD COLUMN discovered_issues TEXT;
|
|
786
|
+
CREATE TABLE artifact (
|
|
787
|
+
id TEXT PRIMARY KEY,
|
|
788
|
+
convoy_id TEXT NOT NULL REFERENCES convoy(id),
|
|
789
|
+
task_id TEXT NOT NULL REFERENCES task(id),
|
|
790
|
+
name TEXT NOT NULL,
|
|
791
|
+
type TEXT NOT NULL,
|
|
792
|
+
content TEXT NOT NULL CHECK (length(content) <= 1048576),
|
|
793
|
+
created_at TEXT NOT NULL,
|
|
794
|
+
UNIQUE(convoy_id, name)
|
|
795
|
+
);
|
|
796
|
+
CREATE TABLE agent_identity (
|
|
797
|
+
id TEXT PRIMARY KEY,
|
|
798
|
+
agent TEXT NOT NULL,
|
|
799
|
+
convoy_id TEXT NOT NULL,
|
|
800
|
+
task_id TEXT NOT NULL,
|
|
801
|
+
summary TEXT NOT NULL,
|
|
802
|
+
created_at TEXT NOT NULL,
|
|
803
|
+
retention_days INTEGER NOT NULL DEFAULT 90
|
|
804
|
+
);
|
|
805
|
+
`);
|
|
806
|
+
}
|
|
807
|
+
if (v === 8) {
|
|
808
|
+
db.exec(`
|
|
809
|
+
CREATE TABLE scratchpad (
|
|
810
|
+
key TEXT PRIMARY KEY,
|
|
811
|
+
value TEXT NOT NULL,
|
|
812
|
+
updated_at TEXT NOT NULL
|
|
813
|
+
);
|
|
814
|
+
`);
|
|
815
|
+
}
|
|
816
|
+
db.exec('COMMIT');
|
|
817
|
+
}
|
|
818
|
+
catch (err) {
|
|
819
|
+
try {
|
|
820
|
+
db.exec('ROLLBACK');
|
|
821
|
+
}
|
|
822
|
+
catch { /* ignore */ }
|
|
823
|
+
throw new Error(`Migration v${v}→v${v + 1} failed. Backup at ${backupPath}. Original error: ${err.message}`);
|
|
824
|
+
}
|
|
825
|
+
db.exec(`PRAGMA user_version = ${v + 1}`);
|
|
826
|
+
}
|
|
827
|
+
}
|
|
322
828
|
export function createConvoyStore(dbPath) {
|
|
323
829
|
return new ConvoyStoreImpl(dbPath);
|
|
324
830
|
}
|