@mclean-capital/neura 2.2.4 → 2.3.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 +1 -1
- package/core/server.bundled.mjs +5703 -734
- package/core/server.bundled.mjs.map +4 -4
- package/core/version.txt +1 -1
- package/dist/commands/install.js +1 -1
- package/dist/commands/install.js.map +1 -1
- package/package.json +3 -1
- package/stores/index.js +38 -0
- package/stores/index.js.map +2 -2
- package/stores/migrations.d.ts.map +1 -1
- package/stores/migrations.js +48 -0
- package/stores/migrations.js.map +1 -1
- package/stores/pglite-store.d.ts +8 -0
- package/stores/pglite-store.d.ts.map +1 -1
- package/stores/pglite-store.js +9 -0
- package/stores/pglite-store.js.map +1 -1
- package/stores/worker-queries.d.ts +120 -0
- package/stores/worker-queries.d.ts.map +1 -0
- package/stores/worker-queries.js +175 -0
- package/stores/worker-queries.js.map +1 -0
- package/stores/worker-queries.test.d.ts +6 -0
- package/stores/worker-queries.test.d.ts.map +1 -0
- package/stores/worker-queries.test.js +224 -0
- package/stores/worker-queries.test.js.map +1 -0
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for worker-queries.ts — CRUD + recovery sweep against a real
|
|
3
|
+
* in-memory PGlite instance.
|
|
4
|
+
*/
|
|
5
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
6
|
+
import { PGlite } from '@electric-sql/pglite';
|
|
7
|
+
import { vector } from '@electric-sql/pglite/vector';
|
|
8
|
+
import { runMigrations } from './migrations.js';
|
|
9
|
+
import { createWorker, updateWorker, getWorker, listWorkers, sweepCrashedWorkers, deleteWorker, recordSkillUsage, listSkillUsage, } from './worker-queries.js';
|
|
10
|
+
let db;
|
|
11
|
+
beforeEach(async () => {
|
|
12
|
+
db = await PGlite.create('memory://', { extensions: { vector } });
|
|
13
|
+
await runMigrations(db);
|
|
14
|
+
});
|
|
15
|
+
afterEach(async () => {
|
|
16
|
+
await db.close();
|
|
17
|
+
});
|
|
18
|
+
function makeTask(overrides = {}) {
|
|
19
|
+
return {
|
|
20
|
+
taskType: 'execute_skill',
|
|
21
|
+
skillName: 'red-test-triage',
|
|
22
|
+
description: 'triage failing tests',
|
|
23
|
+
...overrides,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
describe('createWorker / getWorker', () => {
|
|
27
|
+
it('inserts a row in spawning state and returns its id', async () => {
|
|
28
|
+
const workerId = await createWorker(db, makeTask());
|
|
29
|
+
expect(workerId).toBeTruthy();
|
|
30
|
+
expect(typeof workerId).toBe('string');
|
|
31
|
+
const row = await getWorker(db, workerId);
|
|
32
|
+
expect(row).toBeDefined();
|
|
33
|
+
expect(row?.status).toBe('spawning');
|
|
34
|
+
expect(row?.taskType).toBe('execute_skill');
|
|
35
|
+
expect(row?.taskSpec.skillName).toBe('red-test-triage');
|
|
36
|
+
expect(row?.sessionFile).toBeNull();
|
|
37
|
+
expect(row?.result).toBeNull();
|
|
38
|
+
});
|
|
39
|
+
it('returns null for unknown ids', async () => {
|
|
40
|
+
const row = await getWorker(db, '00000000-0000-0000-0000-000000000000');
|
|
41
|
+
expect(row).toBeNull();
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
describe('updateWorker', () => {
|
|
45
|
+
it('transitions status and bumps last_progress_at', async () => {
|
|
46
|
+
const workerId = await createWorker(db, makeTask());
|
|
47
|
+
const before = await getWorker(db, workerId);
|
|
48
|
+
// Wait a millisecond so the timestamp comparison is meaningful.
|
|
49
|
+
await new Promise((r) => setTimeout(r, 5));
|
|
50
|
+
await updateWorker(db, workerId, { status: 'running' });
|
|
51
|
+
const after = await getWorker(db, workerId);
|
|
52
|
+
expect(after?.status).toBe('running');
|
|
53
|
+
expect(new Date(after.lastProgressAt).getTime()).toBeGreaterThanOrEqual(new Date(before.lastProgressAt).getTime());
|
|
54
|
+
});
|
|
55
|
+
it('persists session_file and session_id after dispatch', async () => {
|
|
56
|
+
const workerId = await createWorker(db, makeTask());
|
|
57
|
+
await updateWorker(db, workerId, {
|
|
58
|
+
status: 'running',
|
|
59
|
+
sessionId: 'sess-123',
|
|
60
|
+
sessionFile: '/tmp/sessions/abc.jsonl',
|
|
61
|
+
});
|
|
62
|
+
const row = await getWorker(db, workerId);
|
|
63
|
+
expect(row?.sessionId).toBe('sess-123');
|
|
64
|
+
expect(row?.sessionFile).toBe('/tmp/sessions/abc.jsonl');
|
|
65
|
+
});
|
|
66
|
+
it('writes result payload on completion', async () => {
|
|
67
|
+
const workerId = await createWorker(db, makeTask());
|
|
68
|
+
await updateWorker(db, workerId, {
|
|
69
|
+
status: 'completed',
|
|
70
|
+
result: { status: 'completed', output: 'created task wk-1' },
|
|
71
|
+
});
|
|
72
|
+
const row = await getWorker(db, workerId);
|
|
73
|
+
expect(row?.status).toBe('completed');
|
|
74
|
+
expect(row?.result).toEqual({ status: 'completed', output: 'created task wk-1' });
|
|
75
|
+
});
|
|
76
|
+
it('writes error payload on failure', async () => {
|
|
77
|
+
const workerId = await createWorker(db, makeTask());
|
|
78
|
+
await updateWorker(db, workerId, {
|
|
79
|
+
status: 'failed',
|
|
80
|
+
error: { reason: 'llm_exhausted', detail: 'max retries' },
|
|
81
|
+
});
|
|
82
|
+
const row = await getWorker(db, workerId);
|
|
83
|
+
expect(row?.status).toBe('failed');
|
|
84
|
+
expect(row?.error).toEqual({ reason: 'llm_exhausted', detail: 'max retries' });
|
|
85
|
+
});
|
|
86
|
+
it('is a no-op when no fields are supplied', async () => {
|
|
87
|
+
const workerId = await createWorker(db, makeTask());
|
|
88
|
+
await updateWorker(db, workerId, {});
|
|
89
|
+
const row = await getWorker(db, workerId);
|
|
90
|
+
expect(row?.status).toBe('spawning');
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
describe('listWorkers', () => {
|
|
94
|
+
it('returns all rows sorted by last_progress_at desc', async () => {
|
|
95
|
+
const id1 = await createWorker(db, makeTask({ description: 'first' }));
|
|
96
|
+
await new Promise((r) => setTimeout(r, 5));
|
|
97
|
+
const id2 = await createWorker(db, makeTask({ description: 'second' }));
|
|
98
|
+
const list = await listWorkers(db);
|
|
99
|
+
expect(list).toHaveLength(2);
|
|
100
|
+
// Most recent first.
|
|
101
|
+
expect(list[0]?.workerId).toBe(id2);
|
|
102
|
+
expect(list[1]?.workerId).toBe(id1);
|
|
103
|
+
});
|
|
104
|
+
it('filters by single status', async () => {
|
|
105
|
+
const running = await createWorker(db, makeTask());
|
|
106
|
+
await updateWorker(db, running, { status: 'running' });
|
|
107
|
+
const idle = await createWorker(db, makeTask());
|
|
108
|
+
await updateWorker(db, idle, { status: 'idle_partial' });
|
|
109
|
+
const runningOnly = await listWorkers(db, { status: 'running' });
|
|
110
|
+
expect(runningOnly).toHaveLength(1);
|
|
111
|
+
expect(runningOnly[0]?.workerId).toBe(running);
|
|
112
|
+
});
|
|
113
|
+
it('filters by multiple statuses', async () => {
|
|
114
|
+
const running = await createWorker(db, makeTask());
|
|
115
|
+
await updateWorker(db, running, { status: 'running' });
|
|
116
|
+
const blocked = await createWorker(db, makeTask());
|
|
117
|
+
await updateWorker(db, blocked, { status: 'blocked_clarifying' });
|
|
118
|
+
const done = await createWorker(db, makeTask());
|
|
119
|
+
await updateWorker(db, done, { status: 'completed' });
|
|
120
|
+
const active = await listWorkers(db, {
|
|
121
|
+
status: ['running', 'blocked_clarifying'],
|
|
122
|
+
});
|
|
123
|
+
expect(active.map((r) => r.workerId).sort()).toEqual([running, blocked].sort());
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
describe('sweepCrashedWorkers', () => {
|
|
127
|
+
it('marks spawning/running/blocked_clarifying as crashed (terminal)', async () => {
|
|
128
|
+
const spawning = await createWorker(db, makeTask()); // stays in spawning
|
|
129
|
+
const running = await createWorker(db, makeTask());
|
|
130
|
+
await updateWorker(db, running, { status: 'running' });
|
|
131
|
+
const blocked = await createWorker(db, makeTask());
|
|
132
|
+
await updateWorker(db, blocked, { status: 'blocked_clarifying' });
|
|
133
|
+
const result = await sweepCrashedWorkers(db, () => true);
|
|
134
|
+
expect(result.markedCrashedMidRun).toBe(3);
|
|
135
|
+
for (const id of [spawning, running, blocked]) {
|
|
136
|
+
const row = await getWorker(db, id);
|
|
137
|
+
expect(row?.status).toBe('crashed');
|
|
138
|
+
expect(row?.error?.reason).toBe('core_restarted');
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
it('preserves idle_partial rows whose session_file still exists', async () => {
|
|
142
|
+
const idleId = await createWorker(db, makeTask());
|
|
143
|
+
await updateWorker(db, idleId, {
|
|
144
|
+
status: 'idle_partial',
|
|
145
|
+
sessionFile: '/tmp/sessions/clean.jsonl',
|
|
146
|
+
});
|
|
147
|
+
const result = await sweepCrashedWorkers(db, (path) => path === '/tmp/sessions/clean.jsonl');
|
|
148
|
+
expect(result.resumable).toBe(1);
|
|
149
|
+
expect(result.markedCrashedMissingFile).toBe(0);
|
|
150
|
+
const row = await getWorker(db, idleId);
|
|
151
|
+
expect(row?.status).toBe('idle_partial');
|
|
152
|
+
expect(row?.sessionFile).toBe('/tmp/sessions/clean.jsonl');
|
|
153
|
+
});
|
|
154
|
+
it('marks idle_partial rows with missing session_file as crashed', async () => {
|
|
155
|
+
const idleId = await createWorker(db, makeTask());
|
|
156
|
+
await updateWorker(db, idleId, {
|
|
157
|
+
status: 'idle_partial',
|
|
158
|
+
sessionFile: '/tmp/sessions/missing.jsonl',
|
|
159
|
+
});
|
|
160
|
+
const result = await sweepCrashedWorkers(db, () => false);
|
|
161
|
+
expect(result.markedCrashedMissingFile).toBe(1);
|
|
162
|
+
expect(result.resumable).toBe(0);
|
|
163
|
+
const row = await getWorker(db, idleId);
|
|
164
|
+
expect(row?.status).toBe('crashed');
|
|
165
|
+
expect(row?.error?.reason).toBe('session_file_missing');
|
|
166
|
+
});
|
|
167
|
+
it('marks idle_partial rows with null session_file as crashed', async () => {
|
|
168
|
+
const idleId = await createWorker(db, makeTask());
|
|
169
|
+
await updateWorker(db, idleId, { status: 'idle_partial' });
|
|
170
|
+
// No session_file set.
|
|
171
|
+
const result = await sweepCrashedWorkers(db, () => true);
|
|
172
|
+
expect(result.markedCrashedMissingFile).toBe(1);
|
|
173
|
+
const row = await getWorker(db, idleId);
|
|
174
|
+
expect(row?.status).toBe('crashed');
|
|
175
|
+
expect(row?.error?.reason).toBe('session_file_missing');
|
|
176
|
+
});
|
|
177
|
+
it('leaves terminal states untouched (completed, failed, cancelled, crashed)', async () => {
|
|
178
|
+
const completed = await createWorker(db, makeTask());
|
|
179
|
+
await updateWorker(db, completed, { status: 'completed' });
|
|
180
|
+
const failed = await createWorker(db, makeTask());
|
|
181
|
+
await updateWorker(db, failed, { status: 'failed' });
|
|
182
|
+
const cancelled = await createWorker(db, makeTask());
|
|
183
|
+
await updateWorker(db, cancelled, { status: 'cancelled' });
|
|
184
|
+
await sweepCrashedWorkers(db, () => true);
|
|
185
|
+
expect((await getWorker(db, completed))?.status).toBe('completed');
|
|
186
|
+
expect((await getWorker(db, failed))?.status).toBe('failed');
|
|
187
|
+
expect((await getWorker(db, cancelled))?.status).toBe('cancelled');
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
describe('deleteWorker', () => {
|
|
191
|
+
it('removes a worker row', async () => {
|
|
192
|
+
const workerId = await createWorker(db, makeTask());
|
|
193
|
+
await deleteWorker(db, workerId);
|
|
194
|
+
expect(await getWorker(db, workerId)).toBeNull();
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
describe('skill usage', () => {
|
|
198
|
+
it('records first-use with count 1', async () => {
|
|
199
|
+
await recordSkillUsage(db, 'red-test-triage');
|
|
200
|
+
const list = await listSkillUsage(db);
|
|
201
|
+
expect(list).toHaveLength(1);
|
|
202
|
+
expect(list[0]?.skillName).toBe('red-test-triage');
|
|
203
|
+
expect(list[0]?.useCount).toBe(1);
|
|
204
|
+
});
|
|
205
|
+
it('increments count on subsequent uses via upsert', async () => {
|
|
206
|
+
await recordSkillUsage(db, 'red-test-triage');
|
|
207
|
+
await recordSkillUsage(db, 'red-test-triage');
|
|
208
|
+
await recordSkillUsage(db, 'red-test-triage');
|
|
209
|
+
const list = await listSkillUsage(db);
|
|
210
|
+
expect(list[0]?.useCount).toBe(3);
|
|
211
|
+
});
|
|
212
|
+
it('tracks multiple skills independently, sorted MRU', async () => {
|
|
213
|
+
await recordSkillUsage(db, 'skill-a');
|
|
214
|
+
await new Promise((r) => setTimeout(r, 5));
|
|
215
|
+
await recordSkillUsage(db, 'skill-b');
|
|
216
|
+
await new Promise((r) => setTimeout(r, 5));
|
|
217
|
+
await recordSkillUsage(db, 'skill-a'); // skill-a is now MRU
|
|
218
|
+
const list = await listSkillUsage(db);
|
|
219
|
+
expect(list).toHaveLength(2);
|
|
220
|
+
expect(list[0]?.skillName).toBe('skill-a');
|
|
221
|
+
expect(list[1]?.skillName).toBe('skill-b');
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
//# sourceMappingURL=worker-queries.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker-queries.test.js","sourceRoot":"","sources":["../../src/stores/worker-queries.test.ts"],"names":[],"mappings":"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"}
|