ctxpkg 0.0.3 → 0.0.4

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.
Files changed (242) hide show
  1. package/bin/cli.js +1 -1
  2. package/bin/daemon.js +1 -1
  3. package/dist/agent/agent.d.ts +65 -0
  4. package/dist/agent/agent.d.ts.map +1 -0
  5. package/dist/agent/agent.js +291 -0
  6. package/dist/agent/agent.js.map +1 -0
  7. package/dist/agent/agent.prompts.d.ts +13 -0
  8. package/dist/agent/agent.prompts.d.ts.map +1 -0
  9. package/{src/agent/agent.prompts.ts → dist/agent/agent.prompts.js} +11 -12
  10. package/dist/agent/agent.prompts.js.map +1 -0
  11. package/dist/agent/agent.test-runner.d.ts +73 -0
  12. package/dist/agent/agent.test-runner.d.ts.map +1 -0
  13. package/dist/agent/agent.test-runner.js +316 -0
  14. package/dist/agent/agent.test-runner.js.map +1 -0
  15. package/dist/agent/agent.test-runner.schemas.d.ts +382 -0
  16. package/dist/agent/agent.test-runner.schemas.d.ts.map +1 -0
  17. package/dist/agent/agent.test-runner.schemas.js +110 -0
  18. package/dist/agent/agent.test-runner.schemas.js.map +1 -0
  19. package/dist/agent/agent.types.d.ts +122 -0
  20. package/dist/agent/agent.types.d.ts.map +1 -0
  21. package/dist/agent/agent.types.js +19 -0
  22. package/dist/agent/agent.types.js.map +1 -0
  23. package/dist/backend/backend.d.ts +16 -0
  24. package/dist/backend/backend.d.ts.map +1 -0
  25. package/dist/backend/backend.js +79 -0
  26. package/dist/backend/backend.js.map +1 -0
  27. package/dist/backend/backend.protocol.d.ts +74 -0
  28. package/dist/backend/backend.protocol.d.ts.map +1 -0
  29. package/dist/backend/backend.protocol.js +46 -0
  30. package/dist/backend/backend.protocol.js.map +1 -0
  31. package/dist/backend/backend.schemas.d.ts +141 -0
  32. package/dist/backend/backend.schemas.d.ts.map +1 -0
  33. package/dist/backend/backend.schemas.js +59 -0
  34. package/dist/backend/backend.schemas.js.map +1 -0
  35. package/dist/backend/backend.services.d.ts +290 -0
  36. package/dist/backend/backend.services.d.ts.map +1 -0
  37. package/dist/backend/backend.services.js +103 -0
  38. package/dist/backend/backend.services.js.map +1 -0
  39. package/dist/backend/backend.types.d.ts +25 -0
  40. package/dist/backend/backend.types.d.ts.map +1 -0
  41. package/dist/backend/backend.types.js +6 -0
  42. package/dist/backend/backend.types.js.map +1 -0
  43. package/dist/cli/cli.agent.d.ts +4 -0
  44. package/dist/cli/cli.agent.d.ts.map +1 -0
  45. package/dist/cli/cli.agent.js +158 -0
  46. package/dist/cli/cli.agent.js.map +1 -0
  47. package/dist/cli/cli.chat.d.ts +4 -0
  48. package/dist/cli/cli.chat.d.ts.map +1 -0
  49. package/dist/cli/cli.chat.js +311 -0
  50. package/dist/cli/cli.chat.js.map +1 -0
  51. package/dist/cli/cli.client.d.ts +11 -0
  52. package/dist/cli/cli.client.d.ts.map +1 -0
  53. package/dist/cli/cli.client.js +40 -0
  54. package/dist/cli/cli.client.js.map +1 -0
  55. package/dist/cli/cli.collections.d.ts +4 -0
  56. package/dist/cli/cli.collections.d.ts.map +1 -0
  57. package/dist/cli/cli.collections.js +411 -0
  58. package/dist/cli/cli.collections.js.map +1 -0
  59. package/dist/cli/cli.config.d.ts +4 -0
  60. package/dist/cli/cli.config.d.ts.map +1 -0
  61. package/dist/cli/cli.config.js +192 -0
  62. package/dist/cli/cli.config.js.map +1 -0
  63. package/dist/cli/cli.d.ts +4 -0
  64. package/dist/cli/cli.d.ts.map +1 -0
  65. package/dist/cli/cli.daemon.d.ts +4 -0
  66. package/dist/cli/cli.daemon.d.ts.map +1 -0
  67. package/dist/cli/cli.daemon.js +116 -0
  68. package/dist/cli/cli.daemon.js.map +1 -0
  69. package/dist/cli/cli.documents.d.ts +4 -0
  70. package/dist/cli/cli.documents.d.ts.map +1 -0
  71. package/dist/cli/cli.documents.js +332 -0
  72. package/dist/cli/cli.documents.js.map +1 -0
  73. package/dist/cli/cli.js +23 -0
  74. package/dist/cli/cli.js.map +1 -0
  75. package/dist/cli/cli.mcp.d.ts +4 -0
  76. package/dist/cli/cli.mcp.d.ts.map +1 -0
  77. package/dist/cli/cli.mcp.js +146 -0
  78. package/dist/cli/cli.mcp.js.map +1 -0
  79. package/dist/cli/cli.utils.d.ts +51 -0
  80. package/dist/cli/cli.utils.d.ts.map +1 -0
  81. package/dist/cli/cli.utils.js +95 -0
  82. package/dist/cli/cli.utils.js.map +1 -0
  83. package/dist/client/client.adapters.d.ts +38 -0
  84. package/dist/client/client.adapters.d.ts.map +1 -0
  85. package/dist/client/client.adapters.js +233 -0
  86. package/dist/client/client.adapters.js.map +1 -0
  87. package/dist/client/client.d.ts +16 -0
  88. package/dist/client/client.d.ts.map +1 -0
  89. package/dist/client/client.js +74 -0
  90. package/dist/client/client.js.map +1 -0
  91. package/dist/client/client.types.d.ts +10 -0
  92. package/dist/client/client.types.d.ts.map +1 -0
  93. package/dist/client/client.types.js +2 -0
  94. package/dist/client/client.types.js.map +1 -0
  95. package/dist/collections/collections.d.ts +219 -0
  96. package/dist/collections/collections.d.ts.map +1 -0
  97. package/dist/collections/collections.js +933 -0
  98. package/dist/collections/collections.js.map +1 -0
  99. package/dist/collections/collections.schemas.d.ts +298 -0
  100. package/dist/collections/collections.schemas.d.ts.map +1 -0
  101. package/dist/collections/collections.schemas.js +117 -0
  102. package/dist/collections/collections.schemas.js.map +1 -0
  103. package/dist/config/config.d.ts +29 -0
  104. package/dist/config/config.d.ts.map +1 -0
  105. package/dist/config/config.js +112 -0
  106. package/dist/config/config.js.map +1 -0
  107. package/dist/daemon/daemon.config.d.ts +6 -0
  108. package/dist/daemon/daemon.config.d.ts.map +1 -0
  109. package/dist/daemon/daemon.config.js +19 -0
  110. package/dist/daemon/daemon.config.js.map +1 -0
  111. package/dist/daemon/daemon.d.ts +10 -0
  112. package/dist/daemon/daemon.d.ts.map +1 -0
  113. package/dist/daemon/daemon.js +173 -0
  114. package/dist/daemon/daemon.js.map +1 -0
  115. package/dist/daemon/daemon.manager.d.ts +20 -0
  116. package/dist/daemon/daemon.manager.d.ts.map +1 -0
  117. package/dist/daemon/daemon.manager.js +176 -0
  118. package/dist/daemon/daemon.manager.js.map +1 -0
  119. package/dist/daemon/daemon.schemas.d.ts +38 -0
  120. package/dist/daemon/daemon.schemas.d.ts.map +1 -0
  121. package/dist/daemon/daemon.schemas.js +15 -0
  122. package/dist/daemon/daemon.schemas.js.map +1 -0
  123. package/dist/database/database.d.ts +10 -0
  124. package/dist/database/database.d.ts.map +1 -0
  125. package/dist/database/database.js +52 -0
  126. package/dist/database/database.js.map +1 -0
  127. package/dist/database/migrations/migrations.001-init.d.ts +9 -0
  128. package/dist/database/migrations/migrations.001-init.d.ts.map +1 -0
  129. package/dist/database/migrations/migrations.001-init.js +46 -0
  130. package/dist/database/migrations/migrations.001-init.js.map +1 -0
  131. package/dist/database/migrations/migrations.002-fts5.d.ts +11 -0
  132. package/dist/database/migrations/migrations.002-fts5.d.ts.map +1 -0
  133. package/dist/database/migrations/migrations.002-fts5.js +29 -0
  134. package/dist/database/migrations/migrations.002-fts5.js.map +1 -0
  135. package/dist/database/migrations/migrations.d.ts +11 -0
  136. package/dist/database/migrations/migrations.d.ts.map +1 -0
  137. package/dist/database/migrations/migrations.js +14 -0
  138. package/dist/database/migrations/migrations.js.map +1 -0
  139. package/dist/database/migrations/migrations.types.d.ts +8 -0
  140. package/dist/database/migrations/migrations.types.d.ts.map +1 -0
  141. package/dist/database/migrations/migrations.types.js +2 -0
  142. package/dist/database/migrations/migrations.types.js.map +1 -0
  143. package/dist/documents/documents.d.ts +58 -0
  144. package/dist/documents/documents.d.ts.map +1 -0
  145. package/dist/documents/documents.js +597 -0
  146. package/dist/documents/documents.js.map +1 -0
  147. package/dist/documents/documents.schemas.d.ts +418 -0
  148. package/dist/documents/documents.schemas.d.ts.map +1 -0
  149. package/dist/documents/documents.schemas.js +111 -0
  150. package/dist/documents/documents.schemas.js.map +1 -0
  151. package/dist/embedder/embedder.d.ts +22 -0
  152. package/dist/embedder/embedder.d.ts.map +1 -0
  153. package/dist/embedder/embedder.js +46 -0
  154. package/dist/embedder/embedder.js.map +1 -0
  155. package/dist/exports.d.ts +2 -0
  156. package/dist/exports.d.ts.map +1 -0
  157. package/dist/exports.js +2 -0
  158. package/dist/exports.js.map +1 -0
  159. package/dist/mcp/mcp.d.ts +44 -0
  160. package/dist/mcp/mcp.d.ts.map +1 -0
  161. package/dist/mcp/mcp.js +62 -0
  162. package/dist/mcp/mcp.js.map +1 -0
  163. package/dist/tools/agent/agent.d.ts +14 -0
  164. package/dist/tools/agent/agent.d.ts.map +1 -0
  165. package/dist/tools/agent/agent.js +31 -0
  166. package/dist/tools/agent/agent.js.map +1 -0
  167. package/dist/tools/documents/documents.d.ts +28 -0
  168. package/dist/tools/documents/documents.d.ts.map +1 -0
  169. package/dist/tools/documents/documents.js +336 -0
  170. package/dist/tools/documents/documents.js.map +1 -0
  171. package/dist/tools/tools.langchain.d.ts +11 -0
  172. package/dist/tools/tools.langchain.d.ts.map +1 -0
  173. package/dist/tools/tools.langchain.js +30 -0
  174. package/dist/tools/tools.langchain.js.map +1 -0
  175. package/dist/tools/tools.mcp.d.ts +12 -0
  176. package/dist/tools/tools.mcp.d.ts.map +1 -0
  177. package/dist/tools/tools.mcp.js +38 -0
  178. package/dist/tools/tools.mcp.js.map +1 -0
  179. package/{src/tools/tools.types.ts → dist/tools/tools.types.d.ts} +10 -16
  180. package/dist/tools/tools.types.d.ts.map +1 -0
  181. package/dist/tools/tools.types.js +7 -0
  182. package/dist/tools/tools.types.js.map +1 -0
  183. package/dist/tsconfig.tsbuildinfo +1 -0
  184. package/dist/utils/utils.services.d.ts +14 -0
  185. package/dist/utils/utils.services.d.ts.map +1 -0
  186. package/dist/utils/utils.services.js +33 -0
  187. package/dist/utils/utils.services.js.map +1 -0
  188. package/package.json +2 -2
  189. package/src/agent/AGENTS.md +0 -249
  190. package/src/agent/agent.test-runner.schemas.ts +0 -158
  191. package/src/agent/agent.test-runner.ts +0 -436
  192. package/src/agent/agent.ts +0 -371
  193. package/src/agent/agent.types.ts +0 -94
  194. package/src/backend/AGENTS.md +0 -112
  195. package/src/backend/backend.protocol.ts +0 -95
  196. package/src/backend/backend.schemas.ts +0 -123
  197. package/src/backend/backend.services.ts +0 -151
  198. package/src/backend/backend.ts +0 -111
  199. package/src/backend/backend.types.ts +0 -34
  200. package/src/cli/AGENTS.md +0 -213
  201. package/src/cli/cli.agent.ts +0 -197
  202. package/src/cli/cli.chat.ts +0 -369
  203. package/src/cli/cli.client.ts +0 -55
  204. package/src/cli/cli.collections.ts +0 -491
  205. package/src/cli/cli.config.ts +0 -252
  206. package/src/cli/cli.daemon.ts +0 -160
  207. package/src/cli/cli.documents.ts +0 -413
  208. package/src/cli/cli.mcp.ts +0 -177
  209. package/src/cli/cli.ts +0 -28
  210. package/src/cli/cli.utils.ts +0 -122
  211. package/src/client/AGENTS.md +0 -135
  212. package/src/client/client.adapters.ts +0 -279
  213. package/src/client/client.ts +0 -86
  214. package/src/client/client.types.ts +0 -17
  215. package/src/collections/AGENTS.md +0 -185
  216. package/src/collections/collections.schemas.ts +0 -195
  217. package/src/collections/collections.ts +0 -1160
  218. package/src/config/config.ts +0 -118
  219. package/src/daemon/AGENTS.md +0 -168
  220. package/src/daemon/daemon.config.ts +0 -23
  221. package/src/daemon/daemon.manager.ts +0 -215
  222. package/src/daemon/daemon.schemas.ts +0 -22
  223. package/src/daemon/daemon.ts +0 -205
  224. package/src/database/AGENTS.md +0 -211
  225. package/src/database/database.ts +0 -64
  226. package/src/database/migrations/migrations.001-init.ts +0 -56
  227. package/src/database/migrations/migrations.002-fts5.ts +0 -32
  228. package/src/database/migrations/migrations.ts +0 -20
  229. package/src/database/migrations/migrations.types.ts +0 -9
  230. package/src/documents/AGENTS.md +0 -301
  231. package/src/documents/documents.schemas.ts +0 -190
  232. package/src/documents/documents.ts +0 -734
  233. package/src/embedder/embedder.ts +0 -53
  234. package/src/exports.ts +0 -0
  235. package/src/mcp/AGENTS.md +0 -264
  236. package/src/mcp/mcp.ts +0 -105
  237. package/src/tools/AGENTS.md +0 -228
  238. package/src/tools/agent/agent.ts +0 -45
  239. package/src/tools/documents/documents.ts +0 -401
  240. package/src/tools/tools.langchain.ts +0 -37
  241. package/src/tools/tools.mcp.ts +0 -46
  242. package/src/utils/utils.services.ts +0 -46
@@ -0,0 +1,316 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { dirname, resolve } from 'node:path';
3
+ import { parse as parseYaml } from 'yaml';
4
+ import { createDocumentAgent, getLLMConfigFromAppConfig } from './agent.js';
5
+ import { testSuiteSchema, } from './agent.test-runner.schemas.js';
6
+ import { createClient } from '#root/client/client.js';
7
+ import { EmbedderService } from '#root/embedder/embedder.js';
8
+ import { Services, destroy } from '#root/utils/utils.services.js';
9
+ /**
10
+ * LLM validation prompt
11
+ */
12
+ const LLM_VALIDATION_PROMPT = `You are evaluating an AI agent's answer against expected criteria.
13
+
14
+ ## Expected Answer / Criteria
15
+ {expected}
16
+
17
+ ## Actual Answer
18
+ {actual}
19
+
20
+ ## Validation Instructions
21
+ {instructions}
22
+
23
+ ## Task
24
+ Evaluate how well the actual answer meets the expected criteria. Consider:
25
+ - Does it address the key points?
26
+ - Is the information accurate (based on what was expected)?
27
+ - Is it appropriately detailed?
28
+
29
+ Respond with a JSON object:
30
+ \`\`\`json
31
+ {
32
+ "score": <0.0 to 1.0>,
33
+ "passed": <true if score >= threshold>,
34
+ "reasoning": "<brief explanation of your evaluation>"
35
+ }
36
+ \`\`\``;
37
+ const DEFAULT_VALIDATION_INSTRUCTIONS = `Evaluate whether the actual answer adequately addresses the expected criteria.
38
+ Focus on factual correctness and completeness rather than exact wording.`;
39
+ /**
40
+ * Test runner service for validating agent performance
41
+ */
42
+ class AgentTestRunner {
43
+ #services;
44
+ #embedder;
45
+ constructor() {
46
+ this.#services = new Services();
47
+ this.#embedder = this.#services.get(EmbedderService);
48
+ }
49
+ /**
50
+ * Compute collection ID from spec URL (mirrors CollectionsService.computeCollectionId)
51
+ */
52
+ #computeCollectionId(url) {
53
+ const normalizedUrl = url.replace(/\/+$/, '');
54
+ return `pkg:${normalizedUrl}`;
55
+ }
56
+ /**
57
+ * Load and parse a test suite from a YAML file
58
+ */
59
+ async loadTestSuite(filePath) {
60
+ const content = await readFile(filePath, 'utf-8');
61
+ const parsed = parseYaml(content);
62
+ const suite = testSuiteSchema.parse(parsed);
63
+ const baseDir = dirname(resolve(filePath));
64
+ return { suite, baseDir };
65
+ }
66
+ /**
67
+ * Run a complete test suite
68
+ */
69
+ async runTestSuite(suite, options = {}) {
70
+ const { onProgress, llmConfig: providedLlmConfig, baseDir = process.cwd() } = options;
71
+ const startedAt = new Date().toISOString();
72
+ const startTime = Date.now();
73
+ // Get LLM config
74
+ const llmConfig = providedLlmConfig ?? (await getLLMConfigFromAppConfig());
75
+ onProgress?.({ type: 'suite_start', suiteName: suite.name, totalTests: suite.tests.length });
76
+ const results = [];
77
+ // Create client using direct mode (uses existing database)
78
+ const client = await createClient({ mode: 'direct' });
79
+ try {
80
+ // Sync collections from test suite
81
+ onProgress?.({ type: 'sync_start' });
82
+ // Build alias map for test suite collections only
83
+ const aliasMap = new Map();
84
+ for (const [alias, spec] of Object.entries(suite.collections)) {
85
+ // Compute collection ID (same as CollectionsService.computeCollectionId)
86
+ const collectionId = this.#computeCollectionId(spec.url);
87
+ aliasMap.set(alias, collectionId);
88
+ // Sync the collection
89
+ await client.collections.sync({
90
+ name: alias,
91
+ spec,
92
+ cwd: baseDir,
93
+ });
94
+ }
95
+ onProgress?.({ type: 'sync_complete' });
96
+ // Create agent with only the test suite's collections
97
+ const agent = createDocumentAgent({
98
+ client,
99
+ llmConfig,
100
+ aliasMap,
101
+ // Restrict searches to only the test suite's collections
102
+ collections: Array.from(aliasMap.values()),
103
+ });
104
+ // Run each test
105
+ for (let i = 0; i < suite.tests.length; i++) {
106
+ const testCase = suite.tests[i];
107
+ onProgress?.({ type: 'test_start', testId: testCase.id, index: i });
108
+ const result = await this.#runSingleTest(testCase, agent, client, llmConfig, suite.options, options);
109
+ results.push(result);
110
+ onProgress?.({ type: 'test_complete', testId: testCase.id, result });
111
+ }
112
+ }
113
+ finally {
114
+ await client.disconnect();
115
+ }
116
+ const completedAt = new Date().toISOString();
117
+ const durationMs = Date.now() - startTime;
118
+ const summary = {
119
+ total: results.length,
120
+ passed: results.filter((r) => r.passed && !r.skipped).length,
121
+ failed: results.filter((r) => !r.passed && !r.skipped).length,
122
+ skipped: results.filter((r) => r.skipped).length,
123
+ };
124
+ const runResult = {
125
+ suiteName: suite.name,
126
+ startedAt,
127
+ completedAt,
128
+ durationMs,
129
+ summary,
130
+ results,
131
+ };
132
+ onProgress?.({ type: 'suite_complete', result: runResult });
133
+ return runResult;
134
+ }
135
+ /**
136
+ * Run a single test case
137
+ */
138
+ async #runSingleTest(testCase, agent, client, llmConfig, suiteOptions, runnerOptions) {
139
+ const startTime = Date.now();
140
+ // Check if skipped
141
+ if (testCase.skip) {
142
+ return {
143
+ id: testCase.id,
144
+ passed: false,
145
+ skipped: true,
146
+ actualAnswer: '',
147
+ durationMs: 0,
148
+ };
149
+ }
150
+ try {
151
+ // Get the agent's answer
152
+ const response = await agent.ask(testCase.query, testCase.useCase);
153
+ const actualAnswer = response.answer;
154
+ // Determine validation mode
155
+ const validationMode = runnerOptions.validationMode ?? testCase.validationMode ?? suiteOptions?.validationMode ?? 'semantic';
156
+ // Determine pass threshold
157
+ const passThreshold = runnerOptions.passThreshold ?? testCase.passThreshold ?? suiteOptions?.passThreshold ?? 0.75;
158
+ // Validate based on mode
159
+ let result;
160
+ switch (validationMode) {
161
+ case 'keywords':
162
+ result = await this.#validateKeywords(testCase, actualAnswer, passThreshold);
163
+ break;
164
+ case 'llm':
165
+ result = await this.#validateWithLLM(testCase, actualAnswer, passThreshold, llmConfig, suiteOptions, runnerOptions.validationModel);
166
+ break;
167
+ case 'semantic':
168
+ default:
169
+ result = await this.#validateSemantic(testCase, actualAnswer, passThreshold);
170
+ break;
171
+ }
172
+ result.durationMs = Date.now() - startTime;
173
+ return result;
174
+ }
175
+ catch (error) {
176
+ const message = error instanceof Error ? error.message : String(error);
177
+ return {
178
+ id: testCase.id,
179
+ passed: false,
180
+ actualAnswer: '',
181
+ error: message,
182
+ durationMs: Date.now() - startTime,
183
+ };
184
+ }
185
+ }
186
+ /**
187
+ * Validate using semantic similarity
188
+ */
189
+ async #validateSemantic(testCase, actualAnswer, passThreshold) {
190
+ // Embed both expected and actual as documents (not queries)
191
+ const embeddings = await this.#embedder.createDocumentEmbeddings([testCase.expected, actualAnswer]);
192
+ const [expectedEmbedding, actualEmbedding] = embeddings;
193
+ // Compute cosine similarity
194
+ const similarity = this.#cosineSimilarity(expectedEmbedding, actualEmbedding);
195
+ return {
196
+ id: testCase.id,
197
+ passed: similarity >= passThreshold,
198
+ score: similarity,
199
+ actualAnswer,
200
+ reasoning: `Semantic similarity: ${(similarity * 100).toFixed(1)}% (threshold: ${(passThreshold * 100).toFixed(1)}%)`,
201
+ durationMs: 0,
202
+ };
203
+ }
204
+ /**
205
+ * Validate using keyword matching
206
+ */
207
+ async #validateKeywords(testCase, actualAnswer, passThreshold) {
208
+ const keywords = testCase.keywords ?? [];
209
+ if (keywords.length === 0) {
210
+ return {
211
+ id: testCase.id,
212
+ passed: false,
213
+ actualAnswer,
214
+ error: 'No keywords specified for keywords validation mode',
215
+ durationMs: 0,
216
+ };
217
+ }
218
+ const lowerAnswer = actualAnswer.toLowerCase();
219
+ const found = [];
220
+ const missing = [];
221
+ for (const keyword of keywords) {
222
+ if (lowerAnswer.includes(keyword.toLowerCase())) {
223
+ found.push(keyword);
224
+ }
225
+ else {
226
+ missing.push(keyword);
227
+ }
228
+ }
229
+ const score = found.length / keywords.length;
230
+ return {
231
+ id: testCase.id,
232
+ passed: score >= passThreshold,
233
+ score,
234
+ actualAnswer,
235
+ keywordsFound: found,
236
+ keywordsMissing: missing,
237
+ reasoning: `Found ${found.length}/${keywords.length} keywords (${(score * 100).toFixed(1)}%)`,
238
+ durationMs: 0,
239
+ };
240
+ }
241
+ /**
242
+ * Validate using LLM as judge
243
+ */
244
+ async #validateWithLLM(testCase, actualAnswer, passThreshold, llmConfig, suiteOptions, validationModel) {
245
+ const { ChatOpenAI } = await import('@langchain/openai');
246
+ const { HumanMessage } = await import('@langchain/core/messages');
247
+ const llm = new ChatOpenAI({
248
+ configuration: { baseURL: llmConfig.provider },
249
+ modelName: validationModel ?? llmConfig.model,
250
+ apiKey: llmConfig.apiKey,
251
+ temperature: 0,
252
+ });
253
+ const instructions = testCase.validationInstructions ?? suiteOptions?.validationInstructions ?? DEFAULT_VALIDATION_INSTRUCTIONS;
254
+ const prompt = LLM_VALIDATION_PROMPT.replace('{expected}', testCase.expected)
255
+ .replace('{actual}', actualAnswer)
256
+ .replace('{instructions}', instructions)
257
+ .replace('{threshold}', passThreshold.toString());
258
+ const response = await llm.invoke([new HumanMessage(prompt)]);
259
+ const content = typeof response.content === 'string' ? response.content : JSON.stringify(response.content);
260
+ // Parse JSON response
261
+ const jsonMatch = content.match(/```json\s*([\s\S]*?)\s*```/) ?? content.match(/\{[\s\S]*\}/);
262
+ if (jsonMatch) {
263
+ try {
264
+ const parsed = JSON.parse(jsonMatch[1] ?? jsonMatch[0]);
265
+ const score = Number(parsed.score) || 0;
266
+ return {
267
+ id: testCase.id,
268
+ passed: score >= passThreshold,
269
+ score,
270
+ actualAnswer,
271
+ reasoning: parsed.reasoning ?? 'No reasoning provided',
272
+ durationMs: 0,
273
+ };
274
+ }
275
+ catch {
276
+ // Fall through
277
+ }
278
+ }
279
+ return {
280
+ id: testCase.id,
281
+ passed: false,
282
+ actualAnswer,
283
+ error: 'Failed to parse LLM validation response',
284
+ reasoning: content,
285
+ durationMs: 0,
286
+ };
287
+ }
288
+ /**
289
+ * Compute cosine similarity between two vectors
290
+ */
291
+ #cosineSimilarity(a, b) {
292
+ let dotProduct = 0;
293
+ let normA = 0;
294
+ let normB = 0;
295
+ for (let i = 0; i < a.length; i++) {
296
+ dotProduct += a[i] * b[i];
297
+ normA += a[i] * a[i];
298
+ normB += b[i] * b[i];
299
+ }
300
+ return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));
301
+ }
302
+ /**
303
+ * Clean up resources
304
+ */
305
+ async [destroy]() {
306
+ await this.#services.destroy();
307
+ }
308
+ }
309
+ /**
310
+ * Create a test runner instance
311
+ */
312
+ const createTestRunner = () => {
313
+ return new AgentTestRunner();
314
+ };
315
+ export { AgentTestRunner, createTestRunner };
316
+ //# sourceMappingURL=agent.test-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.test-runner.js","sourceRoot":"","sources":["../../src/agent/agent.test-runner.ts"],"names":[],"mappings":"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"}