@adhd/agent-mcp 0.0.9 → 1.0.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/drizzle/0004_brief_shocker.sql +4 -0
- package/drizzle/0005_clear_lenny_balinger.sql +25 -0
- package/drizzle/meta/0004_snapshot.json +551 -0
- package/drizzle/meta/0005_snapshot.json +545 -0
- package/drizzle/meta/_journal.json +14 -0
- package/package.json +1 -1
- package/src/__tests__/integration/harness.d.ts +195 -0
- package/src/__tests__/integration/harness.d.ts.map +1 -0
- package/src/__tests__/integration/harness.js +396 -0
- package/src/__tests__/integration/harness.js.map +1 -0
- package/src/__tests__/integration/scripted-provider.d.ts +44 -0
- package/src/__tests__/integration/scripted-provider.d.ts.map +1 -0
- package/src/__tests__/integration/scripted-provider.js +82 -0
- package/src/__tests__/integration/scripted-provider.js.map +1 -0
- package/src/clients/registry.d.ts +17 -0
- package/src/clients/registry.d.ts.map +1 -1
- package/src/clients/registry.js +45 -6
- package/src/clients/registry.js.map +1 -1
- package/src/clients/tool-naming.d.ts +20 -0
- package/src/clients/tool-naming.d.ts.map +1 -0
- package/src/clients/tool-naming.js +22 -0
- package/src/clients/tool-naming.js.map +1 -0
- package/src/db/client.d.ts +1 -0
- package/src/db/client.d.ts.map +1 -1
- package/src/db/client.js +1 -1
- package/src/db/client.js.map +1 -1
- package/src/db/migrate-runner.d.ts +38 -0
- package/src/db/migrate-runner.d.ts.map +1 -0
- package/src/db/migrate-runner.js +41 -0
- package/src/db/migrate-runner.js.map +1 -0
- package/src/db/migrate.d.ts +3 -0
- package/src/db/migrate.d.ts.map +1 -1
- package/src/db/migrate.js +6 -5
- package/src/db/migrate.js.map +1 -1
- package/src/db/schema.d.ts +96 -3
- package/src/db/schema.d.ts.map +1 -1
- package/src/db/schema.js +16 -6
- package/src/db/schema.js.map +1 -1
- package/src/engine/dag-engine.d.ts +62 -0
- package/src/engine/dag-engine.d.ts.map +1 -0
- package/src/engine/dag-engine.js +158 -0
- package/src/engine/dag-engine.js.map +1 -0
- package/src/engine/orchestrator.d.ts +14 -0
- package/src/engine/orchestrator.d.ts.map +1 -1
- package/src/engine/orchestrator.js +202 -57
- package/src/engine/orchestrator.js.map +1 -1
- package/src/engine/queue.d.ts +6 -0
- package/src/engine/queue.d.ts.map +1 -1
- package/src/engine/queue.js +8 -0
- package/src/engine/queue.js.map +1 -1
- package/src/index.js +75 -0
- package/src/index.js.map +1 -1
- package/src/providers/anthropic.d.ts.map +1 -1
- package/src/providers/anthropic.js +22 -3
- package/src/providers/anthropic.js.map +1 -1
- package/src/server.d.ts +18 -0
- package/src/server.d.ts.map +1 -1
- package/src/server.js +25 -2
- package/src/server.js.map +1 -1
- package/src/store/task-store.d.ts +7 -1
- package/src/store/task-store.d.ts.map +1 -1
- package/src/store/task-store.js +37 -5
- package/src/store/task-store.js.map +1 -1
- package/src/streaming/event-bus.d.ts +28 -0
- package/src/streaming/event-bus.d.ts.map +1 -0
- package/src/streaming/event-bus.js +12 -0
- package/src/streaming/event-bus.js.map +1 -0
- package/src/streaming/sse-server.d.ts +4 -0
- package/src/streaming/sse-server.d.ts.map +1 -0
- package/src/streaming/sse-server.js +95 -0
- package/src/streaming/sse-server.js.map +1 -0
- package/src/tools/task.d.ts +35 -0
- package/src/tools/task.d.ts.map +1 -1
- package/src/tools/task.js +200 -36
- package/src/tools/task.js.map +1 -1
- package/src/validation/agent.d.ts +3 -0
- package/src/validation/agent.d.ts.map +1 -1
- package/src/validation/agent.js +7 -0
- package/src/validation/agent.js.map +1 -1
- package/src/validation/errors.d.ts +1 -0
- package/src/validation/errors.d.ts.map +1 -1
- package/src/validation/errors.js +1 -0
- package/src/validation/errors.js.map +1 -1
- package/src/validation/execution.d.ts +2 -0
- package/src/validation/execution.d.ts.map +1 -1
- package/src/validation/execution.js +5 -0
- package/src/validation/execution.js.map +1 -1
- package/src/validation/task.d.ts +31 -1
- package/src/validation/task.d.ts.map +1 -1
- package/src/validation/task.js +24 -1
- package/src/validation/task.js.map +1 -1
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integration test harness.
|
|
3
|
+
*
|
|
4
|
+
* Builds a fully-wired real system against a fresh temp sqlite database.
|
|
5
|
+
* Runs the same drizzle migrations used by the production server.
|
|
6
|
+
* Constructs real stores/queue/PolicyEngine/orchestrator/DagEngine with
|
|
7
|
+
* the same dispatchFn wiring as index.ts.
|
|
8
|
+
*
|
|
9
|
+
* The only scripted/stubbed components are:
|
|
10
|
+
* - LLMProvider (ScriptedProvider from scripted-provider.ts)
|
|
11
|
+
* - External MCP tool clients (in-process stubs at the registry boundary)
|
|
12
|
+
*/
|
|
13
|
+
import http from "node:http";
|
|
14
|
+
import Database from "better-sqlite3";
|
|
15
|
+
import { drizzle } from "drizzle-orm/better-sqlite3";
|
|
16
|
+
import * as schema from "../../db/schema.js";
|
|
17
|
+
import { AgentStore } from "../../store/agent-store.js";
|
|
18
|
+
import { SessionStore } from "../../store/session-store.js";
|
|
19
|
+
import { TaskStore } from "../../store/task-store.js";
|
|
20
|
+
import { BackgroundQueue } from "../../engine/queue.js";
|
|
21
|
+
import { DagEngine } from "../../engine/dag-engine.js";
|
|
22
|
+
import { Orchestrator } from "../../engine/orchestrator.js";
|
|
23
|
+
import { HookRegistry } from "../../engine/hooks.js";
|
|
24
|
+
import { PolicyEngine } from "../../engine/policy.js";
|
|
25
|
+
import { taskTool, taskCancel, taskResume } from "../../tools/task.js";
|
|
26
|
+
import type { TaskDeps } from "../../tools/task.js";
|
|
27
|
+
import type { AgentCreateInput } from "../../validation/index.js";
|
|
28
|
+
import type { LLMProvider } from "../../providers/types.js";
|
|
29
|
+
export type TestDb = ReturnType<typeof drizzle<typeof schema>>;
|
|
30
|
+
export interface Harness {
|
|
31
|
+
db: TestDb;
|
|
32
|
+
rawSqlite: InstanceType<typeof Database>;
|
|
33
|
+
agentStore: AgentStore;
|
|
34
|
+
sessionStore: SessionStore;
|
|
35
|
+
taskStore: TaskStore;
|
|
36
|
+
queue: BackgroundQueue;
|
|
37
|
+
orchestrator: Orchestrator;
|
|
38
|
+
policy: PolicyEngine;
|
|
39
|
+
dagEngine: DagEngine;
|
|
40
|
+
taskDeps: TaskDeps;
|
|
41
|
+
hooks: HookRegistry;
|
|
42
|
+
/** Tear down: close DB, stop SSE server if started */
|
|
43
|
+
teardown: () => Promise<void>;
|
|
44
|
+
/** The file path of the temp DB (for restart tests) */
|
|
45
|
+
dbPath: string;
|
|
46
|
+
/** SSE server (if started) */
|
|
47
|
+
sseServer?: http.Server;
|
|
48
|
+
/** Ephemeral port the SSE server is bound to (if started) */
|
|
49
|
+
ssePort?: number;
|
|
50
|
+
}
|
|
51
|
+
export interface HarnessOptions {
|
|
52
|
+
/** Start an SSE server on an ephemeral port */
|
|
53
|
+
withSse?: boolean;
|
|
54
|
+
/** Override server-max-tool-loops */
|
|
55
|
+
serverMaxToolLoops?: number;
|
|
56
|
+
/** Use an explicit DB path (for restart tests) */
|
|
57
|
+
dbPath?: string;
|
|
58
|
+
/**
|
|
59
|
+
* Skip the automatic orphan-scan re-enqueue on build.
|
|
60
|
+
* Prefer `defaultProvider` over this flag: that keeps the real scan
|
|
61
|
+
* exercised while avoiding the external-provider race.
|
|
62
|
+
*/
|
|
63
|
+
skipOrphanScan?: boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Inject a scripted LLMProvider into the harness orchestrator so every
|
|
66
|
+
* task dispatched through taskDeps (including the startup orphan scan)
|
|
67
|
+
* uses it instead of the real provider built from agentDefinition.provider.
|
|
68
|
+
*
|
|
69
|
+
* This mirrors the pattern used for per-task provider injection but applies
|
|
70
|
+
* it at harness construction time — so the orphan scan that fires during
|
|
71
|
+
* buildHarness already has the right provider, with no race against a
|
|
72
|
+
* parallel bad-provider run.
|
|
73
|
+
*/
|
|
74
|
+
defaultProvider?: LLMProvider;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Build a fully-wired harness. Call teardown() when done.
|
|
78
|
+
*/
|
|
79
|
+
export declare function buildHarness(opts?: HarnessOptions): Promise<Harness>;
|
|
80
|
+
/**
|
|
81
|
+
* Rebuild a harness against the SAME DB file (for restart/persistence tests).
|
|
82
|
+
* Does NOT re-run migrations (they're already applied).
|
|
83
|
+
* DOES run the orphan scan.
|
|
84
|
+
*/
|
|
85
|
+
export declare function rebuildHarness(dbPath: string, opts?: Omit<HarnessOptions, "dbPath">): Promise<Harness>;
|
|
86
|
+
/**
|
|
87
|
+
* Wait for the queue to drain (all enqueued tasks finished).
|
|
88
|
+
* Uses p-queue's onIdle() with a bounded deadline, which is more reliable
|
|
89
|
+
* than polling pending+size (which can momentarily read zero between batches).
|
|
90
|
+
*/
|
|
91
|
+
export declare function drainQueue(queue: BackgroundQueue, timeoutMs?: number): Promise<void>;
|
|
92
|
+
/**
|
|
93
|
+
* Create a minimal test agent + open a session. Returns { agentName, sessionId }.
|
|
94
|
+
*/
|
|
95
|
+
export declare function createSessionAndAgent(harness: Harness, provider: LLMProvider, agentOverrides?: Partial<AgentCreateInput>): Promise<{
|
|
96
|
+
agentName: string;
|
|
97
|
+
sessionId: string;
|
|
98
|
+
}>;
|
|
99
|
+
/**
|
|
100
|
+
* Run a task synchronously via the real taskTool, injecting the given provider
|
|
101
|
+
* into the orchestrator for this task only.
|
|
102
|
+
*
|
|
103
|
+
* We achieve provider injection by temporarily monkey-patching the registry
|
|
104
|
+
* to use the scripted provider — the cleanest approach without modifying
|
|
105
|
+
* production source. The provider is captured in a closure inside the harness
|
|
106
|
+
* task runner below.
|
|
107
|
+
*/
|
|
108
|
+
export declare function runTaskViaToolWithProvider(harness: Harness, sessionId: string, prompt: string, provider: LLMProvider, extraInput?: Record<string, unknown>): Promise<{
|
|
109
|
+
task_id: string;
|
|
110
|
+
status: "pending" | "running" | "completed" | "failed" | "cancelled" | "waiting" | "awaiting_input";
|
|
111
|
+
result?: string | undefined;
|
|
112
|
+
stream_url?: string | undefined;
|
|
113
|
+
usage?: {
|
|
114
|
+
direct: {
|
|
115
|
+
inputTokens: number;
|
|
116
|
+
outputTokens: number;
|
|
117
|
+
modelCalls: number;
|
|
118
|
+
toolCallCount: number;
|
|
119
|
+
latencyMs: number;
|
|
120
|
+
stopReason?: string | undefined;
|
|
121
|
+
};
|
|
122
|
+
subtree: {
|
|
123
|
+
inputTokens: number;
|
|
124
|
+
outputTokens: number;
|
|
125
|
+
modelCalls: number;
|
|
126
|
+
toolCallCount: number;
|
|
127
|
+
latencyMs: number;
|
|
128
|
+
stopReason?: string | undefined;
|
|
129
|
+
};
|
|
130
|
+
taskCount: number;
|
|
131
|
+
} | undefined;
|
|
132
|
+
}>;
|
|
133
|
+
/**
|
|
134
|
+
* Background version — enqueues and returns immediately; use drainQueue to wait.
|
|
135
|
+
*/
|
|
136
|
+
export declare function enqueueTaskWithProvider(harness: Harness, sessionId: string, prompt: string, provider: LLMProvider, extraInput?: Record<string, unknown>): Promise<{
|
|
137
|
+
task_id: string;
|
|
138
|
+
status: "pending" | "running" | "completed" | "failed" | "cancelled" | "waiting" | "awaiting_input";
|
|
139
|
+
result?: string | undefined;
|
|
140
|
+
stream_url?: string | undefined;
|
|
141
|
+
usage?: {
|
|
142
|
+
direct: {
|
|
143
|
+
inputTokens: number;
|
|
144
|
+
outputTokens: number;
|
|
145
|
+
modelCalls: number;
|
|
146
|
+
toolCallCount: number;
|
|
147
|
+
latencyMs: number;
|
|
148
|
+
stopReason?: string | undefined;
|
|
149
|
+
};
|
|
150
|
+
subtree: {
|
|
151
|
+
inputTokens: number;
|
|
152
|
+
outputTokens: number;
|
|
153
|
+
modelCalls: number;
|
|
154
|
+
toolCallCount: number;
|
|
155
|
+
latencyMs: number;
|
|
156
|
+
stopReason?: string | undefined;
|
|
157
|
+
};
|
|
158
|
+
taskCount: number;
|
|
159
|
+
} | undefined;
|
|
160
|
+
}>;
|
|
161
|
+
/**
|
|
162
|
+
* A binary latch. One side waits; the other releases.
|
|
163
|
+
* Used for proving concurrency without sleeps.
|
|
164
|
+
*/
|
|
165
|
+
export declare class Latch {
|
|
166
|
+
private _resolve;
|
|
167
|
+
private _reject;
|
|
168
|
+
readonly promise: Promise<void>;
|
|
169
|
+
constructor();
|
|
170
|
+
release(): void;
|
|
171
|
+
fail(err: Error): void;
|
|
172
|
+
/** Await with a bounded deadline. Rejects if deadline exceeded. */
|
|
173
|
+
wait(timeoutMs?: number): Promise<void>;
|
|
174
|
+
}
|
|
175
|
+
export interface SseFrame {
|
|
176
|
+
type: string;
|
|
177
|
+
data: Record<string, unknown>;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Connect to the real SSE server and collect frames until "done" or timeout.
|
|
181
|
+
* Returns collected frames in order.
|
|
182
|
+
*
|
|
183
|
+
* @param port - Ephemeral port from harness.ssePort
|
|
184
|
+
* @param taskId - Task UUID
|
|
185
|
+
* @param timeoutMs - Bounded deadline (default 8s)
|
|
186
|
+
* @param onConnected - Optional callback fired when the HTTP 200 response
|
|
187
|
+
* headers are received (i.e. the SSE connection is established and the
|
|
188
|
+
* server has accepted the request). Use this to release a latch that
|
|
189
|
+
* unblocks a background task, guaranteeing the SSE subscription is active
|
|
190
|
+
* before any events are emitted.
|
|
191
|
+
*/
|
|
192
|
+
export declare function collectSseFrames(port: number, taskId: string, timeoutMs?: number, onConnected?: () => void): Promise<SseFrame[]>;
|
|
193
|
+
export { taskTool, taskCancel, taskResume };
|
|
194
|
+
export type { TaskDeps };
|
|
195
|
+
//# sourceMappingURL=harness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness.d.ts","sourceRoot":"","sources":["../../../../../../../packages/ai/agent-mcp/src/__tests__/integration/harness.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integration test harness.
|
|
3
|
+
*
|
|
4
|
+
* Builds a fully-wired real system against a fresh temp sqlite database.
|
|
5
|
+
* Runs the same drizzle migrations used by the production server.
|
|
6
|
+
* Constructs real stores/queue/PolicyEngine/orchestrator/DagEngine with
|
|
7
|
+
* the same dispatchFn wiring as index.ts.
|
|
8
|
+
*
|
|
9
|
+
* The only scripted/stubbed components are:
|
|
10
|
+
* - LLMProvider (ScriptedProvider from scripted-provider.ts)
|
|
11
|
+
* - External MCP tool clients (in-process stubs at the registry boundary)
|
|
12
|
+
*/
|
|
13
|
+
import os from "node:os";
|
|
14
|
+
import path from "node:path";
|
|
15
|
+
import fs from "node:fs";
|
|
16
|
+
import http from "node:http";
|
|
17
|
+
import crypto from "node:crypto";
|
|
18
|
+
import Database from "better-sqlite3";
|
|
19
|
+
import { drizzle } from "drizzle-orm/better-sqlite3";
|
|
20
|
+
import { fileURLToPath } from "node:url";
|
|
21
|
+
import * as schema from "../../db/schema.js";
|
|
22
|
+
import { AgentStore } from "../../store/agent-store.js";
|
|
23
|
+
import { SessionStore } from "../../store/session-store.js";
|
|
24
|
+
import { TaskStore } from "../../store/task-store.js";
|
|
25
|
+
import { BackgroundQueue } from "../../engine/queue.js";
|
|
26
|
+
import { DagEngine } from "../../engine/dag-engine.js";
|
|
27
|
+
import { Orchestrator } from "../../engine/orchestrator.js";
|
|
28
|
+
import { HookRegistry } from "../../engine/hooks.js";
|
|
29
|
+
import { PolicyEngine } from "../../engine/policy.js";
|
|
30
|
+
import { startSseServer } from "../../streaming/sse-server.js";
|
|
31
|
+
import { enqueueExistingTask } from "../../tools/task.js";
|
|
32
|
+
import { runMigrationsOn } from "../../db/migrate-runner.js";
|
|
33
|
+
import { taskTool, taskCancel, taskResume } from "../../tools/task.js";
|
|
34
|
+
import { tasksTable } from "../../db/schema.js";
|
|
35
|
+
import { eq } from "drizzle-orm";
|
|
36
|
+
import { generateId } from "../../utils/ids.js";
|
|
37
|
+
const __dirname = fileURLToPath(new URL(".", import.meta.url));
|
|
38
|
+
const MIGRATIONS_FOLDER = path.resolve(__dirname, "../../../drizzle");
|
|
39
|
+
/**
|
|
40
|
+
* Build a fully-wired harness. Call teardown() when done.
|
|
41
|
+
*/
|
|
42
|
+
export async function buildHarness(opts = {}) {
|
|
43
|
+
const dbPath = opts.dbPath ??
|
|
44
|
+
path.join(os.tmpdir(), `agent-mcp-test-${crypto.randomUUID()}.db`);
|
|
45
|
+
const rawSqlite = new Database(dbPath);
|
|
46
|
+
rawSqlite.pragma("journal_mode = WAL");
|
|
47
|
+
rawSqlite.pragma("foreign_keys = ON");
|
|
48
|
+
const db = drizzle(rawSqlite, { schema });
|
|
49
|
+
// Run migrations — same folder + FK-safe runner as production
|
|
50
|
+
runMigrationsOn(rawSqlite, db, MIGRATIONS_FOLDER);
|
|
51
|
+
const hooks = new HookRegistry();
|
|
52
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
53
|
+
const dbAny = db;
|
|
54
|
+
const agentStore = new AgentStore(dbAny, hooks);
|
|
55
|
+
const sessionStore = new SessionStore(dbAny, hooks);
|
|
56
|
+
const taskStore = new TaskStore(dbAny);
|
|
57
|
+
const queue = new BackgroundQueue(5);
|
|
58
|
+
const orchestrator = new Orchestrator();
|
|
59
|
+
const policy = new PolicyEngine({
|
|
60
|
+
serverMaxDepth: 5,
|
|
61
|
+
serverMaxToolLoops: opts.serverMaxToolLoops ?? 50,
|
|
62
|
+
});
|
|
63
|
+
// Mirror dispatchFn wiring from index.ts
|
|
64
|
+
let taskDeps;
|
|
65
|
+
const dispatchFn = async (taskId) => {
|
|
66
|
+
if (!taskDeps)
|
|
67
|
+
throw new Error("dispatchFn called before harness initialized");
|
|
68
|
+
await enqueueExistingTask(taskId, taskDeps);
|
|
69
|
+
};
|
|
70
|
+
const dagEngine = new DagEngine(dbAny, queue, taskStore, dispatchFn);
|
|
71
|
+
// SSE server (optional)
|
|
72
|
+
let sseServer;
|
|
73
|
+
let ssePort;
|
|
74
|
+
if (opts.withSse) {
|
|
75
|
+
sseServer = startSseServer(taskStore);
|
|
76
|
+
// Override SSE_PORT to the ephemeral port after listen
|
|
77
|
+
await new Promise((resolve) => {
|
|
78
|
+
sseServer.listen(0, "127.0.0.1", () => {
|
|
79
|
+
const addr = sseServer.address();
|
|
80
|
+
ssePort = addr.port;
|
|
81
|
+
resolve();
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
// Build taskDeps — same shape as index.ts.
|
|
86
|
+
// When defaultProvider is supplied, wrap the orchestrator so every run
|
|
87
|
+
// that goes through taskDeps (including the startup orphan scan) uses it
|
|
88
|
+
// instead of the real provider built from agentDefinition.provider.
|
|
89
|
+
const effectiveOrchestrator = opts.defaultProvider
|
|
90
|
+
? {
|
|
91
|
+
run: (input) => orchestrator.run({ ...input, provider: opts.defaultProvider }),
|
|
92
|
+
}
|
|
93
|
+
: orchestrator;
|
|
94
|
+
taskDeps = {
|
|
95
|
+
agentStore,
|
|
96
|
+
sessionStore,
|
|
97
|
+
taskStore,
|
|
98
|
+
orchestrator: effectiveOrchestrator,
|
|
99
|
+
queue,
|
|
100
|
+
policy,
|
|
101
|
+
hooks,
|
|
102
|
+
selfUrl: undefined,
|
|
103
|
+
inProcessDescriptors: [],
|
|
104
|
+
inProcessHandler: async () => {
|
|
105
|
+
throw new Error("in-process tools not configured in test harness");
|
|
106
|
+
},
|
|
107
|
+
db: dbAny,
|
|
108
|
+
dagEngine,
|
|
109
|
+
};
|
|
110
|
+
// Re-enqueue orphaned pending tasks (mirrors startup scan in index.ts).
|
|
111
|
+
// Skipped when opts.skipOrphanScan is true — callers that need custom
|
|
112
|
+
// (patched) deps can trigger enqueueExistingTask manually.
|
|
113
|
+
if (!opts.skipOrphanScan) {
|
|
114
|
+
const orphanedPending = dbAny
|
|
115
|
+
.select()
|
|
116
|
+
.from(tasksTable)
|
|
117
|
+
.where(eq(tasksTable.status, "pending"))
|
|
118
|
+
.all();
|
|
119
|
+
for (const row of orphanedPending) {
|
|
120
|
+
try {
|
|
121
|
+
await enqueueExistingTask(row.id, taskDeps);
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
// ignore failures in teardown
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
const teardown = async () => {
|
|
129
|
+
// 1. Close the SSE server first so no new HTTP responses write to the DB.
|
|
130
|
+
if (sseServer) {
|
|
131
|
+
await new Promise((resolve) => sseServer.close(() => resolve()));
|
|
132
|
+
}
|
|
133
|
+
// 2. Drain the queue fully via p-queue's onIdle() — more reliable than
|
|
134
|
+
// polling pending+size, which can momentarily read zero between tasks.
|
|
135
|
+
// Race against a 15s deadline to avoid hanging test suite.
|
|
136
|
+
await Promise.race([
|
|
137
|
+
queue.onIdle(),
|
|
138
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error("teardown: queue.onIdle() timed out after 15s")), 15_000)),
|
|
139
|
+
]).catch(() => {
|
|
140
|
+
// Log but don't rethrow — we still need to close the DB.
|
|
141
|
+
});
|
|
142
|
+
// 3. One event-loop tick so the last task's finally-block DB writes settle.
|
|
143
|
+
await new Promise((r) => setImmediate(r));
|
|
144
|
+
// 4. Close the connection cleanly BEFORE unlinking the file.
|
|
145
|
+
//
|
|
146
|
+
// The previous strategy (leak the handle, unlink the open file) caused
|
|
147
|
+
// the intermittent teardown SIGSEGV (exit 139): in WAL mode, at process
|
|
148
|
+
// exit better-sqlite3's destructor checkpoints the WAL — but the backing
|
|
149
|
+
// file had already been unlinked, so the checkpoint operates on a deleted
|
|
150
|
+
// file and crashes the native addon. Leaking also let connections
|
|
151
|
+
// accumulate across the suite, multiplying the destructor work at exit.
|
|
152
|
+
//
|
|
153
|
+
// Closing here, after onIdle()+setImmediate have settled all statements,
|
|
154
|
+
// is race-free: TRUNCATE-checkpoint the WAL into the still-present file,
|
|
155
|
+
// then close(). better-sqlite3 finalizes drizzle's cached statements on
|
|
156
|
+
// close. Only then do we unlink the (now fully released) files.
|
|
157
|
+
if (rawSqlite.open) {
|
|
158
|
+
try {
|
|
159
|
+
rawSqlite.pragma("wal_checkpoint(TRUNCATE)");
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
// checkpoint is best-effort
|
|
163
|
+
}
|
|
164
|
+
try {
|
|
165
|
+
rawSqlite.close();
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
// already closed (e.g. a test closed it explicitly)
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
for (const suffix of ["", "-wal", "-shm"]) {
|
|
172
|
+
try {
|
|
173
|
+
fs.unlinkSync(`${dbPath}${suffix}`);
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
// ignore — file may not exist (e.g. -wal after TRUNCATE close)
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
return {
|
|
181
|
+
db,
|
|
182
|
+
rawSqlite,
|
|
183
|
+
agentStore,
|
|
184
|
+
sessionStore,
|
|
185
|
+
taskStore,
|
|
186
|
+
queue,
|
|
187
|
+
// Expose the effective orchestrator (wrapped when defaultProvider is set)
|
|
188
|
+
// so per-test overrides in runTaskViaToolWithProvider compose correctly.
|
|
189
|
+
orchestrator: effectiveOrchestrator,
|
|
190
|
+
policy,
|
|
191
|
+
dagEngine,
|
|
192
|
+
taskDeps: taskDeps,
|
|
193
|
+
hooks,
|
|
194
|
+
teardown,
|
|
195
|
+
dbPath,
|
|
196
|
+
sseServer,
|
|
197
|
+
ssePort,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Rebuild a harness against the SAME DB file (for restart/persistence tests).
|
|
202
|
+
* Does NOT re-run migrations (they're already applied).
|
|
203
|
+
* DOES run the orphan scan.
|
|
204
|
+
*/
|
|
205
|
+
export async function rebuildHarness(dbPath, opts = {}) {
|
|
206
|
+
return buildHarness({ ...opts, dbPath });
|
|
207
|
+
}
|
|
208
|
+
// ──────────────────────────────────────────────────────────────────────────────
|
|
209
|
+
// Helpers
|
|
210
|
+
// ──────────────────────────────────────────────────────────────────────────────
|
|
211
|
+
/**
|
|
212
|
+
* Wait for the queue to drain (all enqueued tasks finished).
|
|
213
|
+
* Uses p-queue's onIdle() with a bounded deadline, which is more reliable
|
|
214
|
+
* than polling pending+size (which can momentarily read zero between batches).
|
|
215
|
+
*/
|
|
216
|
+
export async function drainQueue(queue, timeoutMs = 10_000) {
|
|
217
|
+
await Promise.race([
|
|
218
|
+
queue.onIdle(),
|
|
219
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error(`drainQueue timed out after ${timeoutMs}ms`)), timeoutMs)),
|
|
220
|
+
]);
|
|
221
|
+
// One extra tick to let the last task's finally-block DB writes settle.
|
|
222
|
+
await new Promise((r) => setImmediate(r));
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Create a minimal test agent + open a session. Returns { agentName, sessionId }.
|
|
226
|
+
*/
|
|
227
|
+
export async function createSessionAndAgent(harness, provider, agentOverrides = {}) {
|
|
228
|
+
const agentName = `test-agent-${generateId()}`;
|
|
229
|
+
// Inject the provider into the factory by using a special "stub" type
|
|
230
|
+
// The provider is passed via the harness task runner helper
|
|
231
|
+
harness.agentStore.create({
|
|
232
|
+
name: agentName,
|
|
233
|
+
provider: { type: "openai", model: "test-model" },
|
|
234
|
+
systemPrompt: "You are a test assistant.",
|
|
235
|
+
mcpServers: {},
|
|
236
|
+
permissions: {},
|
|
237
|
+
...agentOverrides,
|
|
238
|
+
});
|
|
239
|
+
const agentDef = harness.agentStore.read(agentName);
|
|
240
|
+
const session = harness.sessionStore.create({
|
|
241
|
+
agentName,
|
|
242
|
+
agentDefinition: agentDef,
|
|
243
|
+
});
|
|
244
|
+
return { agentName, sessionId: session.id };
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Run a task synchronously via the real taskTool, injecting the given provider
|
|
248
|
+
* into the orchestrator for this task only.
|
|
249
|
+
*
|
|
250
|
+
* We achieve provider injection by temporarily monkey-patching the registry
|
|
251
|
+
* to use the scripted provider — the cleanest approach without modifying
|
|
252
|
+
* production source. The provider is captured in a closure inside the harness
|
|
253
|
+
* task runner below.
|
|
254
|
+
*/
|
|
255
|
+
export async function runTaskViaToolWithProvider(harness, sessionId, prompt, provider, extraInput = {}) {
|
|
256
|
+
// Wrap the orchestrator to inject the scripted provider for this one run
|
|
257
|
+
const realOrchestrator = harness.orchestrator;
|
|
258
|
+
const originalRun = realOrchestrator.run.bind(realOrchestrator);
|
|
259
|
+
const patchedDeps = {
|
|
260
|
+
...harness.taskDeps,
|
|
261
|
+
orchestrator: {
|
|
262
|
+
run: (input) => originalRun({ ...input, provider }),
|
|
263
|
+
},
|
|
264
|
+
};
|
|
265
|
+
return taskTool({ session_id: sessionId, prompt, background: false, ...extraInput }, patchedDeps);
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Background version — enqueues and returns immediately; use drainQueue to wait.
|
|
269
|
+
*/
|
|
270
|
+
export async function enqueueTaskWithProvider(harness, sessionId, prompt, provider, extraInput = {}) {
|
|
271
|
+
const realOrchestrator = harness.orchestrator;
|
|
272
|
+
const originalRun = realOrchestrator.run.bind(realOrchestrator);
|
|
273
|
+
const patchedDeps = {
|
|
274
|
+
...harness.taskDeps,
|
|
275
|
+
orchestrator: {
|
|
276
|
+
run: (input) => originalRun({ ...input, provider }),
|
|
277
|
+
},
|
|
278
|
+
};
|
|
279
|
+
return taskTool({ session_id: sessionId, prompt, background: true, ...extraInput }, patchedDeps);
|
|
280
|
+
}
|
|
281
|
+
// ──────────────────────────────────────────────────────────────────────────────
|
|
282
|
+
// Latch utility
|
|
283
|
+
// ──────────────────────────────────────────────────────────────────────────────
|
|
284
|
+
/**
|
|
285
|
+
* A binary latch. One side waits; the other releases.
|
|
286
|
+
* Used for proving concurrency without sleeps.
|
|
287
|
+
*/
|
|
288
|
+
export class Latch {
|
|
289
|
+
_resolve;
|
|
290
|
+
_reject;
|
|
291
|
+
promise;
|
|
292
|
+
constructor() {
|
|
293
|
+
this.promise = new Promise((res, rej) => {
|
|
294
|
+
this._resolve = res;
|
|
295
|
+
this._reject = rej;
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
release() {
|
|
299
|
+
this._resolve();
|
|
300
|
+
}
|
|
301
|
+
fail(err) {
|
|
302
|
+
this._reject(err);
|
|
303
|
+
}
|
|
304
|
+
/** Await with a bounded deadline. Rejects if deadline exceeded. */
|
|
305
|
+
async wait(timeoutMs = 5_000) {
|
|
306
|
+
return Promise.race([
|
|
307
|
+
this.promise,
|
|
308
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error(`Latch.wait timed out after ${timeoutMs}ms`)), timeoutMs)),
|
|
309
|
+
]);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Connect to the real SSE server and collect frames until "done" or timeout.
|
|
314
|
+
* Returns collected frames in order.
|
|
315
|
+
*
|
|
316
|
+
* @param port - Ephemeral port from harness.ssePort
|
|
317
|
+
* @param taskId - Task UUID
|
|
318
|
+
* @param timeoutMs - Bounded deadline (default 8s)
|
|
319
|
+
* @param onConnected - Optional callback fired when the HTTP 200 response
|
|
320
|
+
* headers are received (i.e. the SSE connection is established and the
|
|
321
|
+
* server has accepted the request). Use this to release a latch that
|
|
322
|
+
* unblocks a background task, guaranteeing the SSE subscription is active
|
|
323
|
+
* before any events are emitted.
|
|
324
|
+
*/
|
|
325
|
+
export async function collectSseFrames(port, taskId, timeoutMs = 8_000, onConnected) {
|
|
326
|
+
return new Promise((resolve, reject) => {
|
|
327
|
+
const frames = [];
|
|
328
|
+
const timer = setTimeout(() => {
|
|
329
|
+
reject(new Error(`collectSseFrames timed out after ${timeoutMs}ms`));
|
|
330
|
+
}, timeoutMs);
|
|
331
|
+
const req = http.get(`http://127.0.0.1:${port}/tasks/${taskId}/stream`, { headers: { Accept: "text/event-stream" } }, (res) => {
|
|
332
|
+
// Fire the onConnected callback as soon as the HTTP response
|
|
333
|
+
// headers arrive — this confirms the SSE endpoint has accepted
|
|
334
|
+
// the request and the subscription is active on the server.
|
|
335
|
+
onConnected?.();
|
|
336
|
+
let buf = "";
|
|
337
|
+
let currentEventType = "";
|
|
338
|
+
res.on("data", (chunk) => {
|
|
339
|
+
buf += chunk.toString();
|
|
340
|
+
const lines = buf.split("\n");
|
|
341
|
+
buf = lines.pop() ?? "";
|
|
342
|
+
for (const line of lines) {
|
|
343
|
+
if (line.startsWith("event: ")) {
|
|
344
|
+
currentEventType = line.slice("event: ".length).trim();
|
|
345
|
+
}
|
|
346
|
+
else if (line.startsWith("data: ")) {
|
|
347
|
+
const raw = line.slice("data: ".length).trim();
|
|
348
|
+
try {
|
|
349
|
+
const data = JSON.parse(raw);
|
|
350
|
+
frames.push({ type: currentEventType, data });
|
|
351
|
+
if (currentEventType === "done") {
|
|
352
|
+
clearTimeout(timer);
|
|
353
|
+
req.destroy();
|
|
354
|
+
resolve(frames);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
catch {
|
|
358
|
+
// ignore parse errors (e.g. ping lines)
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
// reset event type on blank line (SSE spec)
|
|
362
|
+
if (line === "") {
|
|
363
|
+
currentEventType = "";
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
res.on("error", (err) => {
|
|
368
|
+
clearTimeout(timer);
|
|
369
|
+
// If connection was destroyed after done frame, that's fine
|
|
370
|
+
if (frames.some((f) => f.type === "done")) {
|
|
371
|
+
resolve(frames);
|
|
372
|
+
}
|
|
373
|
+
else {
|
|
374
|
+
reject(err);
|
|
375
|
+
}
|
|
376
|
+
});
|
|
377
|
+
res.on("end", () => {
|
|
378
|
+
clearTimeout(timer);
|
|
379
|
+
resolve(frames);
|
|
380
|
+
});
|
|
381
|
+
});
|
|
382
|
+
req.on("error", (err) => {
|
|
383
|
+
clearTimeout(timer);
|
|
384
|
+
// Destroyed connections after done frame are fine
|
|
385
|
+
if (frames.some((f) => f.type === "done")) {
|
|
386
|
+
resolve(frames);
|
|
387
|
+
}
|
|
388
|
+
else {
|
|
389
|
+
reject(err);
|
|
390
|
+
}
|
|
391
|
+
});
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
// Re-export tools for convenience
|
|
395
|
+
export { taskTool, taskCancel, taskResume };
|
|
396
|
+
//# sourceMappingURL=harness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness.js","sourceRoot":"","sources":["../../../../../../../packages/ai/agent-mcp/src/__tests__/integration/harness.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ScriptedProvider — deterministic LLM provider for integration tests.
|
|
3
|
+
*
|
|
4
|
+
* Implements the real LLMProvider interface.
|
|
5
|
+
* Returns programmable responses per chat() call in sequence.
|
|
6
|
+
* After all scripted turns are exhausted, defaults to a "completed" response.
|
|
7
|
+
*
|
|
8
|
+
* Supported turn types:
|
|
9
|
+
* - "completed" → returns stopReason "completed" with given content
|
|
10
|
+
* - "tool_calls" → returns stopReason "tool_calls" with given tool calls
|
|
11
|
+
* - "hitl" → returns a single request_human_input tool call
|
|
12
|
+
*
|
|
13
|
+
* Supports a beforeCall hook so tool stubs can coordinate with Latches.
|
|
14
|
+
*/
|
|
15
|
+
import type { LLMProvider, ProviderChatResponse } from "../../providers/types.js";
|
|
16
|
+
export interface ToolCallSpec {
|
|
17
|
+
server: string;
|
|
18
|
+
tool: string;
|
|
19
|
+
arguments: unknown;
|
|
20
|
+
/** Override the generated call ID */
|
|
21
|
+
id?: string;
|
|
22
|
+
}
|
|
23
|
+
export type ScriptedTurn = {
|
|
24
|
+
type: "completed";
|
|
25
|
+
content: string;
|
|
26
|
+
} | {
|
|
27
|
+
type: "tool_calls";
|
|
28
|
+
toolCalls: ToolCallSpec[];
|
|
29
|
+
} | {
|
|
30
|
+
type: "hitl";
|
|
31
|
+
prompt: string;
|
|
32
|
+
};
|
|
33
|
+
export declare class ScriptedProvider implements LLMProvider {
|
|
34
|
+
private readonly turns;
|
|
35
|
+
private callIndex;
|
|
36
|
+
/**
|
|
37
|
+
* Optional hook invoked at the START of each chat() call (before returning).
|
|
38
|
+
* Receives the call index (0-based) so tests can key on specific turns.
|
|
39
|
+
*/
|
|
40
|
+
beforeCall?: (callIndex: number) => Promise<void>;
|
|
41
|
+
constructor(turns: ScriptedTurn[]);
|
|
42
|
+
chat(): Promise<ProviderChatResponse>;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=scripted-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scripted-provider.d.ts","sourceRoot":"","sources":["../../../../../../../packages/ai/agent-mcp/src/__tests__/integration/scripted-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAKlF,MAAM,WAAW,YAAY;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,qCAAqC;IACrC,EAAE,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,YAAY,GAClB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,SAAS,EAAE,YAAY,EAAE,CAAA;CAAE,GACjD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvC,qBAAa,gBAAiB,YAAW,WAAW;IAChD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiB;IACvC,OAAO,CAAC,SAAS,CAAK;IAEtB;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;gBAEtC,KAAK,EAAE,YAAY,EAAE;IAI3B,IAAI,IAAI,OAAO,CAAC,oBAAoB,CAAC;CA6D9C"}
|