ollama-intern-mcp 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.
Files changed (256) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +252 -0
  3. package/SECURITY.md +22 -0
  4. package/dist/corpus/chunker.d.ts +63 -0
  5. package/dist/corpus/chunker.d.ts.map +1 -0
  6. package/dist/corpus/chunker.js +230 -0
  7. package/dist/corpus/chunker.js.map +1 -0
  8. package/dist/corpus/fusion.d.ts +67 -0
  9. package/dist/corpus/fusion.d.ts.map +1 -0
  10. package/dist/corpus/fusion.js +76 -0
  11. package/dist/corpus/fusion.js.map +1 -0
  12. package/dist/corpus/indexer.d.ts +33 -0
  13. package/dist/corpus/indexer.d.ts.map +1 -0
  14. package/dist/corpus/indexer.js +201 -0
  15. package/dist/corpus/indexer.js.map +1 -0
  16. package/dist/corpus/lexical.d.ts +95 -0
  17. package/dist/corpus/lexical.d.ts.map +1 -0
  18. package/dist/corpus/lexical.js +227 -0
  19. package/dist/corpus/lexical.js.map +1 -0
  20. package/dist/corpus/manifest.d.ts +29 -0
  21. package/dist/corpus/manifest.d.ts.map +1 -0
  22. package/dist/corpus/manifest.js +45 -0
  23. package/dist/corpus/manifest.js.map +1 -0
  24. package/dist/corpus/refresh.d.ts +54 -0
  25. package/dist/corpus/refresh.d.ts.map +1 -0
  26. package/dist/corpus/refresh.js +155 -0
  27. package/dist/corpus/refresh.js.map +1 -0
  28. package/dist/corpus/searcher.d.ts +48 -0
  29. package/dist/corpus/searcher.d.ts.map +1 -0
  30. package/dist/corpus/searcher.js +131 -0
  31. package/dist/corpus/searcher.js.map +1 -0
  32. package/dist/corpus/storage.d.ts +56 -0
  33. package/dist/corpus/storage.d.ts.map +1 -0
  34. package/dist/corpus/storage.js +81 -0
  35. package/dist/corpus/storage.js.map +1 -0
  36. package/dist/coverage.d.ts +38 -0
  37. package/dist/coverage.d.ts.map +1 -0
  38. package/dist/coverage.js +117 -0
  39. package/dist/coverage.js.map +1 -0
  40. package/dist/embedMath.d.ts +22 -0
  41. package/dist/embedMath.d.ts.map +1 -0
  42. package/dist/embedMath.js +34 -0
  43. package/dist/embedMath.js.map +1 -0
  44. package/dist/envelope.d.ts +53 -0
  45. package/dist/envelope.d.ts.map +1 -0
  46. package/dist/envelope.js +32 -0
  47. package/dist/envelope.js.map +1 -0
  48. package/dist/errors.d.ts +20 -0
  49. package/dist/errors.d.ts.map +1 -0
  50. package/dist/errors.js +30 -0
  51. package/dist/errors.js.map +1 -0
  52. package/dist/evals/retrieval.d.ts +68 -0
  53. package/dist/evals/retrieval.d.ts.map +1 -0
  54. package/dist/evals/retrieval.js +173 -0
  55. package/dist/evals/retrieval.js.map +1 -0
  56. package/dist/guardrails/citations.d.ts +28 -0
  57. package/dist/guardrails/citations.d.ts.map +1 -0
  58. package/dist/guardrails/citations.js +45 -0
  59. package/dist/guardrails/citations.js.map +1 -0
  60. package/dist/guardrails/compileCheck.d.ts +20 -0
  61. package/dist/guardrails/compileCheck.d.ts.map +1 -0
  62. package/dist/guardrails/compileCheck.js +96 -0
  63. package/dist/guardrails/compileCheck.js.map +1 -0
  64. package/dist/guardrails/confidence.d.ts +21 -0
  65. package/dist/guardrails/confidence.d.ts.map +1 -0
  66. package/dist/guardrails/confidence.js +18 -0
  67. package/dist/guardrails/confidence.js.map +1 -0
  68. package/dist/guardrails/timeouts.d.ts +35 -0
  69. package/dist/guardrails/timeouts.d.ts.map +1 -0
  70. package/dist/guardrails/timeouts.js +58 -0
  71. package/dist/guardrails/timeouts.js.map +1 -0
  72. package/dist/guardrails/writeConfirm.d.ts +25 -0
  73. package/dist/guardrails/writeConfirm.d.ts.map +1 -0
  74. package/dist/guardrails/writeConfirm.js +35 -0
  75. package/dist/guardrails/writeConfirm.js.map +1 -0
  76. package/dist/index.d.ts +12 -0
  77. package/dist/index.d.ts.map +1 -0
  78. package/dist/index.js +153 -0
  79. package/dist/index.js.map +1 -0
  80. package/dist/observability.d.ts +66 -0
  81. package/dist/observability.d.ts.map +1 -0
  82. package/dist/observability.js +51 -0
  83. package/dist/observability.js.map +1 -0
  84. package/dist/ollama.d.ts +105 -0
  85. package/dist/ollama.d.ts.map +1 -0
  86. package/dist/ollama.js +109 -0
  87. package/dist/ollama.js.map +1 -0
  88. package/dist/prewarm.d.ts +28 -0
  89. package/dist/prewarm.d.ts.map +1 -0
  90. package/dist/prewarm.js +69 -0
  91. package/dist/prewarm.js.map +1 -0
  92. package/dist/profiles.d.ts +54 -0
  93. package/dist/profiles.d.ts.map +1 -0
  94. package/dist/profiles.js +95 -0
  95. package/dist/profiles.js.map +1 -0
  96. package/dist/protectedPaths.d.ts +33 -0
  97. package/dist/protectedPaths.d.ts.map +1 -0
  98. package/dist/protectedPaths.js +54 -0
  99. package/dist/protectedPaths.js.map +1 -0
  100. package/dist/runContext.d.ts +21 -0
  101. package/dist/runContext.d.ts.map +1 -0
  102. package/dist/runContext.js +9 -0
  103. package/dist/runContext.js.map +1 -0
  104. package/dist/semaphore.d.ts +16 -0
  105. package/dist/semaphore.d.ts.map +1 -0
  106. package/dist/semaphore.js +37 -0
  107. package/dist/semaphore.js.map +1 -0
  108. package/dist/sources.d.ts +19 -0
  109. package/dist/sources.d.ts.map +1 -0
  110. package/dist/sources.js +41 -0
  111. package/dist/sources.js.map +1 -0
  112. package/dist/tiers.d.ts +39 -0
  113. package/dist/tiers.d.ts.map +1 -0
  114. package/dist/tiers.js +44 -0
  115. package/dist/tiers.js.map +1 -0
  116. package/dist/tools/artifactDiff.d.ts +66 -0
  117. package/dist/tools/artifactDiff.d.ts.map +1 -0
  118. package/dist/tools/artifactDiff.js +66 -0
  119. package/dist/tools/artifactDiff.js.map +1 -0
  120. package/dist/tools/artifactExportToPath.d.ts +38 -0
  121. package/dist/tools/artifactExportToPath.d.ts.map +1 -0
  122. package/dist/tools/artifactExportToPath.js +51 -0
  123. package/dist/tools/artifactExportToPath.js.map +1 -0
  124. package/dist/tools/artifactList.d.ts +60 -0
  125. package/dist/tools/artifactList.d.ts.map +1 -0
  126. package/dist/tools/artifactList.js +107 -0
  127. package/dist/tools/artifactList.js.map +1 -0
  128. package/dist/tools/artifactRead.d.ts +43 -0
  129. package/dist/tools/artifactRead.d.ts.map +1 -0
  130. package/dist/tools/artifactRead.js +83 -0
  131. package/dist/tools/artifactRead.js.map +1 -0
  132. package/dist/tools/artifactSnippets.d.ts +56 -0
  133. package/dist/tools/artifactSnippets.d.ts.map +1 -0
  134. package/dist/tools/artifactSnippets.js +97 -0
  135. package/dist/tools/artifactSnippets.js.map +1 -0
  136. package/dist/tools/artifacts/diff.d.ts +161 -0
  137. package/dist/tools/artifacts/diff.d.ts.map +1 -0
  138. package/dist/tools/artifacts/diff.js +267 -0
  139. package/dist/tools/artifacts/diff.js.map +1 -0
  140. package/dist/tools/artifacts/export.d.ts +43 -0
  141. package/dist/tools/artifacts/export.d.ts.map +1 -0
  142. package/dist/tools/artifacts/export.js +113 -0
  143. package/dist/tools/artifacts/export.js.map +1 -0
  144. package/dist/tools/artifacts/scan.d.ts +86 -0
  145. package/dist/tools/artifacts/scan.d.ts.map +1 -0
  146. package/dist/tools/artifacts/scan.js +251 -0
  147. package/dist/tools/artifacts/scan.js.map +1 -0
  148. package/dist/tools/artifacts/snippets.d.ts +42 -0
  149. package/dist/tools/artifacts/snippets.d.ts.map +1 -0
  150. package/dist/tools/artifacts/snippets.js +165 -0
  151. package/dist/tools/artifacts/snippets.js.map +1 -0
  152. package/dist/tools/batch.d.ts +65 -0
  153. package/dist/tools/batch.d.ts.map +1 -0
  154. package/dist/tools/batch.js +117 -0
  155. package/dist/tools/batch.js.map +1 -0
  156. package/dist/tools/briefs/common.d.ts +65 -0
  157. package/dist/tools/briefs/common.d.ts.map +1 -0
  158. package/dist/tools/briefs/common.js +128 -0
  159. package/dist/tools/briefs/common.js.map +1 -0
  160. package/dist/tools/briefs/evidence.d.ts +40 -0
  161. package/dist/tools/briefs/evidence.d.ts.map +1 -0
  162. package/dist/tools/briefs/evidence.js +103 -0
  163. package/dist/tools/briefs/evidence.js.map +1 -0
  164. package/dist/tools/changeBrief.d.ts +85 -0
  165. package/dist/tools/changeBrief.d.ts.map +1 -0
  166. package/dist/tools/changeBrief.js +228 -0
  167. package/dist/tools/changeBrief.js.map +1 -0
  168. package/dist/tools/chat.d.ts +42 -0
  169. package/dist/tools/chat.d.ts.map +1 -0
  170. package/dist/tools/chat.js +49 -0
  171. package/dist/tools/chat.js.map +1 -0
  172. package/dist/tools/classify.d.ts +56 -0
  173. package/dist/tools/classify.d.ts.map +1 -0
  174. package/dist/tools/classify.js +103 -0
  175. package/dist/tools/classify.js.map +1 -0
  176. package/dist/tools/corpusAnswer.d.ts +79 -0
  177. package/dist/tools/corpusAnswer.d.ts.map +1 -0
  178. package/dist/tools/corpusAnswer.js +259 -0
  179. package/dist/tools/corpusAnswer.js.map +1 -0
  180. package/dist/tools/corpusIndex.d.ts +30 -0
  181. package/dist/tools/corpusIndex.d.ts.map +1 -0
  182. package/dist/tools/corpusIndex.js +67 -0
  183. package/dist/tools/corpusIndex.js.map +1 -0
  184. package/dist/tools/corpusList.d.ts +19 -0
  185. package/dist/tools/corpusList.d.ts.map +1 -0
  186. package/dist/tools/corpusList.js +34 -0
  187. package/dist/tools/corpusList.js.map +1 -0
  188. package/dist/tools/corpusRefresh.d.ts +29 -0
  189. package/dist/tools/corpusRefresh.d.ts.map +1 -0
  190. package/dist/tools/corpusRefresh.js +58 -0
  191. package/dist/tools/corpusRefresh.js.map +1 -0
  192. package/dist/tools/corpusSearch.d.ts +44 -0
  193. package/dist/tools/corpusSearch.d.ts.map +1 -0
  194. package/dist/tools/corpusSearch.js +80 -0
  195. package/dist/tools/corpusSearch.js.map +1 -0
  196. package/dist/tools/draft.d.ts +38 -0
  197. package/dist/tools/draft.d.ts.map +1 -0
  198. package/dist/tools/draft.js +72 -0
  199. package/dist/tools/draft.js.map +1 -0
  200. package/dist/tools/embed.d.ts +27 -0
  201. package/dist/tools/embed.d.ts.map +1 -0
  202. package/dist/tools/embed.js +41 -0
  203. package/dist/tools/embed.js.map +1 -0
  204. package/dist/tools/embedSearch.d.ts +58 -0
  205. package/dist/tools/embedSearch.d.ts.map +1 -0
  206. package/dist/tools/embedSearch.js +76 -0
  207. package/dist/tools/embedSearch.js.map +1 -0
  208. package/dist/tools/extract.d.ts +58 -0
  209. package/dist/tools/extract.d.ts.map +1 -0
  210. package/dist/tools/extract.js +93 -0
  211. package/dist/tools/extract.js.map +1 -0
  212. package/dist/tools/incidentBrief.d.ts +81 -0
  213. package/dist/tools/incidentBrief.d.ts.map +1 -0
  214. package/dist/tools/incidentBrief.js +252 -0
  215. package/dist/tools/incidentBrief.js.map +1 -0
  216. package/dist/tools/packs/changePack.d.ts +166 -0
  217. package/dist/tools/packs/changePack.d.ts.map +1 -0
  218. package/dist/tools/packs/changePack.js +470 -0
  219. package/dist/tools/packs/changePack.js.map +1 -0
  220. package/dist/tools/packs/incidentPack.d.ts +125 -0
  221. package/dist/tools/packs/incidentPack.d.ts.map +1 -0
  222. package/dist/tools/packs/incidentPack.js +354 -0
  223. package/dist/tools/packs/incidentPack.js.map +1 -0
  224. package/dist/tools/packs/repoPack.d.ts +207 -0
  225. package/dist/tools/packs/repoPack.d.ts.map +1 -0
  226. package/dist/tools/packs/repoPack.js +456 -0
  227. package/dist/tools/packs/repoPack.js.map +1 -0
  228. package/dist/tools/repoBrief.d.ts +81 -0
  229. package/dist/tools/repoBrief.d.ts.map +1 -0
  230. package/dist/tools/repoBrief.js +213 -0
  231. package/dist/tools/repoBrief.js.map +1 -0
  232. package/dist/tools/research.d.ts +45 -0
  233. package/dist/tools/research.d.ts.map +1 -0
  234. package/dist/tools/research.js +100 -0
  235. package/dist/tools/research.js.map +1 -0
  236. package/dist/tools/runner.d.ts +24 -0
  237. package/dist/tools/runner.d.ts.map +1 -0
  238. package/dist/tools/runner.js +47 -0
  239. package/dist/tools/runner.js.map +1 -0
  240. package/dist/tools/summarizeDeep.d.ts +49 -0
  241. package/dist/tools/summarizeDeep.d.ts.map +1 -0
  242. package/dist/tools/summarizeDeep.js +109 -0
  243. package/dist/tools/summarizeDeep.js.map +1 -0
  244. package/dist/tools/summarizeFast.d.ts +28 -0
  245. package/dist/tools/summarizeFast.d.ts.map +1 -0
  246. package/dist/tools/summarizeFast.js +43 -0
  247. package/dist/tools/summarizeFast.js.map +1 -0
  248. package/dist/tools/triageLogs.d.ts +51 -0
  249. package/dist/tools/triageLogs.d.ts.map +1 -0
  250. package/dist/tools/triageLogs.js +96 -0
  251. package/dist/tools/triageLogs.js.map +1 -0
  252. package/dist/version.d.ts +2 -0
  253. package/dist/version.d.ts.map +1 -0
  254. package/dist/version.js +2 -0
  255. package/dist/version.js.map +1 -0
  256. package/package.json +60 -0
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Corpus persistence — one JSON file per named corpus.
3
+ *
4
+ * Location: ~/.ollama-intern/corpora/<name>.json (override via INTERN_CORPUS_DIR)
5
+ *
6
+ * Schema is explicitly versioned so we can evolve without silent breakage.
7
+ * Raw vectors are stored (this file is the database), but they never reach
8
+ * Claude — search handlers strip them before returning.
9
+ */
10
+ import { readFile, writeFile, mkdir, readdir, stat } from "node:fs/promises";
11
+ import { existsSync } from "node:fs";
12
+ import { homedir } from "node:os";
13
+ import { join, dirname } from "node:path";
14
+ import { InternError } from "../errors.js";
15
+ export const CORPUS_SCHEMA_VERSION = 2;
16
+ export function corpusDir() {
17
+ return process.env.INTERN_CORPUS_DIR ?? join(homedir(), ".ollama-intern", "corpora");
18
+ }
19
+ export function corpusPath(name) {
20
+ return join(corpusDir(), `${name}.json`);
21
+ }
22
+ const NAME_RX = /^[a-zA-Z0-9_-]+$/;
23
+ export function assertValidCorpusName(name) {
24
+ if (!NAME_RX.test(name)) {
25
+ throw new InternError("SCHEMA_INVALID", `Invalid corpus name "${name}"`, "Corpus names must match [a-zA-Z0-9_-]+ so they map safely to filenames.", false);
26
+ }
27
+ }
28
+ export async function loadCorpus(name) {
29
+ assertValidCorpusName(name);
30
+ const path = corpusPath(name);
31
+ if (!existsSync(path))
32
+ return null;
33
+ const raw = await readFile(path, "utf8");
34
+ const parsed = JSON.parse(raw);
35
+ const found = parsed.schema_version;
36
+ if (found !== CORPUS_SCHEMA_VERSION) {
37
+ throw new InternError("SCHEMA_INVALID", `Corpus "${name}" is at schema v${found ?? "unknown"}; this build expects v${CORPUS_SCHEMA_VERSION}. File: ${path}`, `Re-index to upgrade in place: ollama_corpus_index({ name: "${name}", paths: [<your source paths>] }). No migration is performed — the re-index rewrites ${path} with the current schema.`, false);
38
+ }
39
+ return parsed;
40
+ }
41
+ export async function saveCorpus(corpus) {
42
+ assertValidCorpusName(corpus.name);
43
+ const path = corpusPath(corpus.name);
44
+ await mkdir(dirname(path), { recursive: true });
45
+ await writeFile(path, JSON.stringify(corpus), "utf8");
46
+ }
47
+ export async function listCorpora() {
48
+ const dir = corpusDir();
49
+ if (!existsSync(dir))
50
+ return [];
51
+ const entries = await readdir(dir);
52
+ const summaries = [];
53
+ for (const entry of entries) {
54
+ if (!entry.endsWith(".json"))
55
+ continue;
56
+ const name = entry.slice(0, -".json".length);
57
+ if (!NAME_RX.test(name))
58
+ continue;
59
+ try {
60
+ const full = join(dir, entry);
61
+ const [corpus, st] = await Promise.all([loadCorpus(name), stat(full)]);
62
+ if (!corpus)
63
+ continue;
64
+ summaries.push({
65
+ name: corpus.name,
66
+ model_version: corpus.model_version,
67
+ indexed_at: corpus.indexed_at,
68
+ documents: corpus.stats.documents,
69
+ chunks: corpus.stats.chunks,
70
+ total_chars: corpus.stats.total_chars,
71
+ bytes_on_disk: st.size,
72
+ });
73
+ }
74
+ catch {
75
+ // Skip malformed corpora silently in list; load will surface the error.
76
+ }
77
+ }
78
+ summaries.sort((a, b) => a.name.localeCompare(b.name));
79
+ return summaries;
80
+ }
81
+ //# sourceMappingURL=storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/corpus/storage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Coverage contract — after a multi-source research or summarize call,
3
+ * detect which source paths the model's output actually covered.
4
+ *
5
+ * A two-file summary that only mentions one file is a real quality bug
6
+ * (observed in the first adoption pass: commandui.md + hardware-m5-max.md
7
+ * → summary only covered CommandUI). Silently accepting that makes the
8
+ * flagship less trustworthy. This module surfaces omissions so the caller
9
+ * knows when to rerun, re-prompt, or read the omitted file themselves.
10
+ *
11
+ * Detection is deterministic and cheap — no extra LLM calls. We pull a
12
+ * small set of "distinctive tokens" per source and check how many show
13
+ * up in the output. Accurate enough to catch whole-file omissions,
14
+ * conservative enough to avoid false-alarm on tight summaries.
15
+ */
16
+ import type { LoadedSource } from "./sources.js";
17
+ export interface CoverageReport {
18
+ covered_sources: string[];
19
+ omitted_sources: string[];
20
+ coverage_notes: string[];
21
+ }
22
+ export interface DetectCoverageOptions {
23
+ /** Paths the caller already knows are covered (e.g. from research citations). */
24
+ explicitlyCovered?: string[];
25
+ /** Maximum signal tokens to extract per source. Default 12. */
26
+ maxTokensPerSource?: number;
27
+ }
28
+ /**
29
+ * Detect which source paths the output covers.
30
+ *
31
+ * A source is "covered" when:
32
+ * - it appears in `explicitlyCovered` (citations etc.), OR
33
+ * - any of its signal tokens appear in the output.
34
+ *
35
+ * Everything else is "omitted" and a coverage note is added.
36
+ */
37
+ export declare function detectCoverage(output: string, sources: LoadedSource[], options?: DetectCoverageOptions): CoverageReport;
38
+ //# sourceMappingURL=coverage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coverage.d.ts","sourceRoot":"","sources":["../src/coverage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,MAAM,WAAW,cAAc;IAC7B,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AA4DD,MAAM,WAAW,qBAAqB;IACpC,iFAAiF;IACjF,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,+DAA+D;IAC/D,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,YAAY,EAAE,EACvB,OAAO,GAAE,qBAA0B,GAClC,cAAc,CAiChB"}
@@ -0,0 +1,117 @@
1
+ /**
2
+ * Coverage contract — after a multi-source research or summarize call,
3
+ * detect which source paths the model's output actually covered.
4
+ *
5
+ * A two-file summary that only mentions one file is a real quality bug
6
+ * (observed in the first adoption pass: commandui.md + hardware-m5-max.md
7
+ * → summary only covered CommandUI). Silently accepting that makes the
8
+ * flagship less trustworthy. This module surfaces omissions so the caller
9
+ * knows when to rerun, re-prompt, or read the omitted file themselves.
10
+ *
11
+ * Detection is deterministic and cheap — no extra LLM calls. We pull a
12
+ * small set of "distinctive tokens" per source and check how many show
13
+ * up in the output. Accurate enough to catch whole-file omissions,
14
+ * conservative enough to avoid false-alarm on tight summaries.
15
+ */
16
+ import { basename, extname } from "node:path";
17
+ /** Stop words + common connectors we won't treat as distinctive signal. */
18
+ const STOP = new Set([
19
+ "the", "and", "for", "with", "from", "into", "over", "under", "this", "that", "these", "those",
20
+ "have", "will", "shall", "been", "were", "being", "your", "their", "them", "they", "each",
21
+ "when", "what", "where", "which", "would", "could", "should", "about", "after", "before",
22
+ "some", "most", "many", "much", "more", "less", "also", "than", "then", "there", "here",
23
+ "only", "just", "very", "such", "like", "than", "onto", "upon", "into", "unto", "then",
24
+ "name", "type", "description", "true", "false", "null", "none", "note", "notes", "section",
25
+ "example", "examples", "step", "steps", "item", "items", "thing", "things", "file", "files",
26
+ "input", "inputs", "output", "outputs", "result", "results", "value", "values", "field", "fields",
27
+ "option", "options", "param", "params", "return", "returns", "function", "class", "method",
28
+ "interface", "import", "export", "const", "async", "await", "null", "true", "false",
29
+ ]);
30
+ function isSignalToken(word) {
31
+ if (word.length < 5)
32
+ return false;
33
+ if (/^\d+$/.test(word))
34
+ return false;
35
+ if (STOP.has(word.toLowerCase()))
36
+ return false;
37
+ return true;
38
+ }
39
+ /** Extract distinctive signal tokens from a source: frequent, long, non-stop. */
40
+ function signalTokensFor(source, maxTokens = 12) {
41
+ const body = source.body.slice(0, 4000); // headers/summary region is enough
42
+ const words = body
43
+ .toLowerCase()
44
+ .split(/[^a-z0-9-]+/g)
45
+ .filter(isSignalToken);
46
+ const freq = new Map();
47
+ for (const w of words)
48
+ freq.set(w, (freq.get(w) ?? 0) + 1);
49
+ // Score: frequency * length — long repeated tokens are most distinctive.
50
+ const ranked = [...freq.entries()]
51
+ .map(([w, c]) => ({ word: w, score: c * Math.min(w.length, 12) }))
52
+ .sort((a, b) => b.score - a.score)
53
+ .slice(0, maxTokens)
54
+ .map((r) => r.word);
55
+ // Always include the filename stem — it's often the strongest coverage signal
56
+ // ("commandui" from "commandui.md" will appear in any summary that covers it).
57
+ const stem = basename(source.path, extname(source.path)).toLowerCase();
58
+ if (stem && !ranked.includes(stem))
59
+ ranked.unshift(stem);
60
+ return ranked;
61
+ }
62
+ function outputHasAnyToken(output, tokens) {
63
+ const lower = output.toLowerCase();
64
+ for (const t of tokens) {
65
+ // Word-ish match: surrounded by non-alphanum or at string edges.
66
+ const re = new RegExp(`(^|[^a-z0-9])${escapeRegExp(t)}([^a-z0-9]|$)`, "i");
67
+ if (re.test(lower))
68
+ return true;
69
+ }
70
+ return false;
71
+ }
72
+ function escapeRegExp(s) {
73
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
74
+ }
75
+ /**
76
+ * Detect which source paths the output covers.
77
+ *
78
+ * A source is "covered" when:
79
+ * - it appears in `explicitlyCovered` (citations etc.), OR
80
+ * - any of its signal tokens appear in the output.
81
+ *
82
+ * Everything else is "omitted" and a coverage note is added.
83
+ */
84
+ export function detectCoverage(output, sources, options = {}) {
85
+ const explicit = new Set((options.explicitlyCovered ?? []).map(normalizeForCompare));
86
+ const covered = [];
87
+ const omitted = [];
88
+ const notes = [];
89
+ for (const src of sources) {
90
+ const isExplicit = explicit.has(normalizeForCompare(src.path));
91
+ if (isExplicit) {
92
+ covered.push(src.path);
93
+ continue;
94
+ }
95
+ const tokens = signalTokensFor(src, options.maxTokensPerSource);
96
+ if (tokens.length === 0) {
97
+ // No detectable signal — don't falsely claim coverage. Call it omitted.
98
+ omitted.push(src.path);
99
+ notes.push(`No distinctive tokens extractable from "${src.path}"; coverage could not be verified.`);
100
+ continue;
101
+ }
102
+ if (outputHasAnyToken(output, tokens)) {
103
+ covered.push(src.path);
104
+ }
105
+ else {
106
+ omitted.push(src.path);
107
+ }
108
+ }
109
+ if (omitted.length > 0 && sources.length > 1) {
110
+ notes.unshift(`Summary omitted ${omitted.length} of ${sources.length} source(s). Consider rerunning with a narrower focus, a longer max_words, or reading the omitted files directly.`);
111
+ }
112
+ return { covered_sources: covered, omitted_sources: omitted, coverage_notes: notes };
113
+ }
114
+ function normalizeForCompare(p) {
115
+ return p.replace(/\\/g, "/").toLowerCase();
116
+ }
117
+ //# sourceMappingURL=coverage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coverage.js","sourceRoot":"","sources":["../src/coverage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Minimal vector math for concept-search mode. Stdlib only.
3
+ *
4
+ * `cosine(a, b)` returns a similarity in [-1, 1] (higher = more similar).
5
+ * `rank` returns descending by score and stable by input order on ties.
6
+ */
7
+ export declare function cosine(a: number[], b: number[]): number;
8
+ export interface RankedCandidate<T> {
9
+ item: T;
10
+ score: number;
11
+ /** Input-order index for stable sorting. */
12
+ originalIndex: number;
13
+ }
14
+ /**
15
+ * Rank candidates by cosine similarity to queryVec, descending.
16
+ * Ties break on original input index so the output is deterministic.
17
+ */
18
+ export declare function rankByCosine<T>(queryVec: number[], candidates: Array<{
19
+ item: T;
20
+ vec: number[];
21
+ }>): RankedCandidate<T>[];
22
+ //# sourceMappingURL=embedMath.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embedMath.d.ts","sourceRoot":"","sources":["../src/embedMath.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAYvD;AAED,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,IAAI,EAAE,CAAC,CAAC;IACR,KAAK,EAAE,MAAM,CAAC;IACd,4CAA4C;IAC5C,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAC5B,QAAQ,EAAE,MAAM,EAAE,EAClB,UAAU,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,CAAC,CAAC;IAAC,GAAG,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,GAC5C,eAAe,CAAC,CAAC,CAAC,EAAE,CAQtB"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Minimal vector math for concept-search mode. Stdlib only.
3
+ *
4
+ * `cosine(a, b)` returns a similarity in [-1, 1] (higher = more similar).
5
+ * `rank` returns descending by score and stable by input order on ties.
6
+ */
7
+ export function cosine(a, b) {
8
+ if (a.length !== b.length || a.length === 0)
9
+ return 0;
10
+ let dot = 0;
11
+ let na = 0;
12
+ let nb = 0;
13
+ for (let i = 0; i < a.length; i++) {
14
+ dot += a[i] * b[i];
15
+ na += a[i] * a[i];
16
+ nb += b[i] * b[i];
17
+ }
18
+ const denom = Math.sqrt(na) * Math.sqrt(nb);
19
+ return denom === 0 ? 0 : dot / denom;
20
+ }
21
+ /**
22
+ * Rank candidates by cosine similarity to queryVec, descending.
23
+ * Ties break on original input index so the output is deterministic.
24
+ */
25
+ export function rankByCosine(queryVec, candidates) {
26
+ const ranked = candidates.map((c, i) => ({
27
+ item: c.item,
28
+ score: cosine(queryVec, c.vec),
29
+ originalIndex: i,
30
+ }));
31
+ ranked.sort((a, b) => (b.score - a.score) || (a.originalIndex - b.originalIndex));
32
+ return ranked;
33
+ }
34
+ //# sourceMappingURL=embedMath.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"embedMath.js","sourceRoot":"","sources":["../src/embedMath.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,UAAU,MAAM,CAAC,CAAW,EAAE,CAAW;IAC7C,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACtD,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,IAAI,EAAE,GAAG,CAAC,CAAC;IACX,IAAI,EAAE,GAAG,CAAC,CAAC;IACX,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACnB,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAClB,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC5C,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC;AACvC,CAAC;AASD;;;GAGG;AACH,MAAM,UAAU,YAAY,CAC1B,QAAkB,EAClB,UAA6C;IAE7C,MAAM,MAAM,GAAyB,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QAC7D,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,GAAG,CAAC;QAC9B,aAAa,EAAE,CAAC;KACjB,CAAC,CAAC,CAAC;IACJ,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC;IAClF,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Uniform response envelope — every tool returns this shape.
3
+ *
4
+ * residency is populated from Ollama's /api/ps. When in_vram is false
5
+ * or size_vram < size, the model paged to disk; inference drops 5–10×.
6
+ * Surfacing it mechanically in every call is what prevents hand-wavy
7
+ * performance claims when Ollama's eviction bug (#13227) strikes.
8
+ */
9
+ import type { Tier } from "./tiers.js";
10
+ export interface Residency {
11
+ in_vram: boolean;
12
+ size_bytes: number;
13
+ size_vram_bytes: number;
14
+ evicted: boolean;
15
+ expires_at: string | null;
16
+ }
17
+ export interface Envelope<T> {
18
+ result: T;
19
+ tier_used: Tier;
20
+ model: string;
21
+ /** Active hardware profile (e.g. "dev-rtx5080", "m5-max"). Lets bench/eval runs keep dev numbers out of publishable tables. */
22
+ hardware_profile: string;
23
+ tokens_in: number;
24
+ tokens_out: number;
25
+ elapsed_ms: number;
26
+ residency: Residency | null;
27
+ /** Set when a timeout fired and the server fell back to a cheaper tier. */
28
+ fallback_from?: Tier;
29
+ /** Non-fatal warnings — e.g. "2 citations stripped (paths not in source_paths)". */
30
+ warnings?: string[];
31
+ /** Total items in the batch. Only set on batch-mode calls. */
32
+ batch_count?: number;
33
+ /** Items that returned {ok: true, result}. Only set on batch-mode calls. */
34
+ ok_count?: number;
35
+ /** Items that returned {ok: false, error}. Only set on batch-mode calls. */
36
+ error_count?: number;
37
+ }
38
+ export interface EnvelopeBuilderInput<T> {
39
+ result: T;
40
+ tier: Tier;
41
+ model: string;
42
+ hardwareProfile: string;
43
+ tokensIn: number;
44
+ tokensOut: number;
45
+ startedAt: number;
46
+ residency: Residency | null;
47
+ fallbackFrom?: Tier;
48
+ warnings?: string[];
49
+ }
50
+ export declare function buildEnvelope<T>(input: EnvelopeBuilderInput<T>): Envelope<T>;
51
+ /** True when residency indicates the model was evicted to disk. */
52
+ export declare function isEvicted(residency: Residency | null): boolean;
53
+ //# sourceMappingURL=envelope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"envelope.d.ts","sourceRoot":"","sources":["../src/envelope.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,QAAQ,CAAC,CAAC;IACzB,MAAM,EAAE,CAAC,CAAC;IACV,SAAS,EAAE,IAAI,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,+HAA+H;IAC/H,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5B,2EAA2E;IAC3E,aAAa,CAAC,EAAE,IAAI,CAAC;IACrB,oFAAoF;IACpF,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,8DAA8D;IAC9D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB,CAAC,CAAC;IACrC,MAAM,EAAE,CAAC,CAAC;IACV,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5B,YAAY,CAAC,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,KAAK,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAc5E;AAED,mEAAmE;AACnE,wBAAgB,SAAS,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,GAAG,OAAO,CAG9D"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Uniform response envelope — every tool returns this shape.
3
+ *
4
+ * residency is populated from Ollama's /api/ps. When in_vram is false
5
+ * or size_vram < size, the model paged to disk; inference drops 5–10×.
6
+ * Surfacing it mechanically in every call is what prevents hand-wavy
7
+ * performance claims when Ollama's eviction bug (#13227) strikes.
8
+ */
9
+ export function buildEnvelope(input) {
10
+ const env = {
11
+ result: input.result,
12
+ tier_used: input.tier,
13
+ model: input.model,
14
+ hardware_profile: input.hardwareProfile,
15
+ tokens_in: input.tokensIn,
16
+ tokens_out: input.tokensOut,
17
+ elapsed_ms: Date.now() - input.startedAt,
18
+ residency: input.residency,
19
+ };
20
+ if (input.fallbackFrom)
21
+ env.fallback_from = input.fallbackFrom;
22
+ if (input.warnings && input.warnings.length > 0)
23
+ env.warnings = input.warnings;
24
+ return env;
25
+ }
26
+ /** True when residency indicates the model was evicted to disk. */
27
+ export function isEvicted(residency) {
28
+ if (!residency)
29
+ return false;
30
+ return residency.evicted || !residency.in_vram || residency.size_vram_bytes < residency.size_bytes;
31
+ }
32
+ //# sourceMappingURL=envelope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"envelope.js","sourceRoot":"","sources":["../src/envelope.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA+CH,MAAM,UAAU,aAAa,CAAI,KAA8B;IAC7D,MAAM,GAAG,GAAgB;QACvB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,SAAS,EAAE,KAAK,CAAC,IAAI;QACrB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,gBAAgB,EAAE,KAAK,CAAC,eAAe;QACvC,SAAS,EAAE,KAAK,CAAC,QAAQ;QACzB,UAAU,EAAE,KAAK,CAAC,SAAS;QAC3B,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS;QACxC,SAAS,EAAE,KAAK,CAAC,SAAS;KAC3B,CAAC;IACF,IAAI,KAAK,CAAC,YAAY;QAAE,GAAG,CAAC,aAAa,GAAG,KAAK,CAAC,YAAY,CAAC;IAC/D,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC;QAAE,GAAG,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;IAC/E,OAAO,GAAG,CAAC;AACb,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,SAAS,CAAC,SAA2B;IACnD,IAAI,CAAC,SAAS;QAAE,OAAO,KAAK,CAAC;IAC7B,OAAO,SAAS,CAAC,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,IAAI,SAAS,CAAC,eAAe,GAAG,SAAS,CAAC,UAAU,CAAC;AACrG,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Structured error shape — code / message / hint / retryable.
3
+ * Matches shipcheck hard gate B: no raw stacks, always a hint, always a retry signal.
4
+ */
5
+ export type ErrorCode = "OLLAMA_UNREACHABLE" | "OLLAMA_MODEL_MISSING" | "OLLAMA_TIMEOUT" | "TIER_TIMEOUT" | "PROTECTED_PATH_WRITE" | "CITATION_INVALID" | "COMPILE_FAILED" | "EXTRACT_UNPARSEABLE" | "SOURCE_PATH_NOT_FOUND" | "SCHEMA_INVALID" | "INTERNAL";
6
+ export declare class InternError extends Error {
7
+ readonly code: ErrorCode;
8
+ readonly hint: string;
9
+ readonly retryable: boolean;
10
+ constructor(code: ErrorCode, message: string, hint: string, retryable?: boolean);
11
+ }
12
+ export interface ErrorShape {
13
+ error: true;
14
+ code: ErrorCode;
15
+ message: string;
16
+ hint: string;
17
+ retryable: boolean;
18
+ }
19
+ export declare function toErrorShape(err: unknown): ErrorShape;
20
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,SAAS,GACjB,oBAAoB,GACpB,sBAAsB,GACtB,gBAAgB,GAChB,cAAc,GACd,sBAAsB,GACtB,kBAAkB,GAClB,gBAAgB,GAChB,qBAAqB,GACrB,uBAAuB,GACvB,gBAAgB,GAChB,UAAU,CAAC;AAEf,qBAAa,WAAY,SAAQ,KAAK;aAElB,IAAI,EAAE,SAAS;aAEf,IAAI,EAAE,MAAM;aACZ,SAAS,EAAE,OAAO;gBAHlB,IAAI,EAAE,SAAS,EAC/B,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,MAAM,EACZ,SAAS,GAAE,OAAe;CAK7C;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,IAAI,CAAC;IACZ,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,UAAU,CAYrD"}
package/dist/errors.js ADDED
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Structured error shape — code / message / hint / retryable.
3
+ * Matches shipcheck hard gate B: no raw stacks, always a hint, always a retry signal.
4
+ */
5
+ export class InternError extends Error {
6
+ code;
7
+ hint;
8
+ retryable;
9
+ constructor(code, message, hint, retryable = false) {
10
+ super(message);
11
+ this.code = code;
12
+ this.hint = hint;
13
+ this.retryable = retryable;
14
+ this.name = "InternError";
15
+ }
16
+ }
17
+ export function toErrorShape(err) {
18
+ if (err instanceof InternError) {
19
+ return { error: true, code: err.code, message: err.message, hint: err.hint, retryable: err.retryable };
20
+ }
21
+ const message = err instanceof Error ? err.message : String(err);
22
+ return {
23
+ error: true,
24
+ code: "INTERNAL",
25
+ message,
26
+ hint: "Unexpected error. Check ~/.ollama-intern/log.ndjson for details.",
27
+ retryable: false,
28
+ };
29
+ }
30
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAeH,MAAM,OAAO,WAAY,SAAQ,KAAK;IAElB;IAEA;IACA;IAJlB,YACkB,IAAe,EAC/B,OAAe,EACC,IAAY,EACZ,YAAqB,KAAK;QAE1C,KAAK,CAAC,OAAO,CAAC,CAAC;QALC,SAAI,GAAJ,IAAI,CAAW;QAEf,SAAI,GAAJ,IAAI,CAAQ;QACZ,cAAS,GAAT,SAAS,CAAiB;QAG1C,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AAUD,MAAM,UAAU,YAAY,CAAC,GAAY;IACvC,IAAI,GAAG,YAAY,WAAW,EAAE,CAAC;QAC/B,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,CAAC;IACzG,CAAC;IACD,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACjE,OAAO;QACL,KAAK,EAAE,IAAI;QACX,IAAI,EAAE,UAAU;QAChB,OAAO;QACP,IAAI,EAAE,kEAAkE;QACxE,SAAS,EAAE,KAAK;KACjB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Retrieval eval runner — measurement law for the Retrieval Truth Spine.
3
+ *
4
+ * Loads gold queries from evals/gold/retrieval.jsonl, runs every query
5
+ * through every search mode against a fixture corpus, and reports
6
+ * precision@1 and precision@3 per (mode × class) plus per-mode and
7
+ * overall aggregates.
8
+ *
9
+ * The runner is deliberately retrieval-native: assertions check whether
10
+ * the expected path appears in the top-K hits, not whether the answer
11
+ * is correct. Answer synthesis is slice 5; measurement is the floor
12
+ * under it.
13
+ *
14
+ * No product-surface changes ride on this file. It is a pure consumer
15
+ * of searchCorpus() and the corpus schema.
16
+ */
17
+ import type { CorpusFile } from "../corpus/storage.js";
18
+ import { type SearchMode } from "../corpus/searcher.js";
19
+ import type { OllamaClient } from "../ollama.js";
20
+ export type QueryClass = "semantic" | "fact" | "procedural" | "confusable";
21
+ export declare const QUERY_CLASSES: readonly QueryClass[];
22
+ export interface GoldQuery {
23
+ id: string;
24
+ class: QueryClass;
25
+ query: string;
26
+ /** Paths that count as correct answers. Match is OR: at least one must appear in top-K. Paths are matched by basename so fixture-dir location doesn't matter. */
27
+ expected_paths: string[];
28
+ /** Optional factual anchor. If present, at least one matching chunk's text must contain every phrase. */
29
+ expected_phrases?: string[];
30
+ }
31
+ export declare function loadGold(filePath: string): Promise<GoldQuery[]>;
32
+ export interface EvalRecord {
33
+ id: string;
34
+ class: QueryClass;
35
+ query: string;
36
+ mode: SearchMode;
37
+ top_paths: string[];
38
+ hit1: boolean;
39
+ hit3: boolean;
40
+ /** null if no expected_phrases on the query. */
41
+ phrasesHit: boolean | null;
42
+ }
43
+ export interface RunEvalOptions {
44
+ gold: GoldQuery[];
45
+ corpus: CorpusFile;
46
+ client: OllamaClient;
47
+ model: string;
48
+ topK?: number;
49
+ previewChars?: number;
50
+ }
51
+ export declare function runRetrievalEval(opts: RunEvalOptions): Promise<EvalRecord[]>;
52
+ export interface CellMetrics {
53
+ n: number;
54
+ precision1: number;
55
+ precision3: number;
56
+ }
57
+ export interface EvalSummary {
58
+ overall: CellMetrics;
59
+ byMode: Record<SearchMode, CellMetrics>;
60
+ byModeByClass: Record<SearchMode, Record<QueryClass, CellMetrics>>;
61
+ }
62
+ export declare function summarizeEval(records: EvalRecord[]): EvalSummary;
63
+ /**
64
+ * Markdown-friendly report suitable for console.log during tests. The
65
+ * shape is stable so it can be diffed between runs.
66
+ */
67
+ export declare function formatEvalReport(summary: EvalSummary): string;
68
+ //# sourceMappingURL=retrieval.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retrieval.d.ts","sourceRoot":"","sources":["../../src/evals/retrieval.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAA8B,KAAK,UAAU,EAAkB,MAAM,uBAAuB,CAAC;AACpG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,MAAM,GAAG,YAAY,GAAG,YAAY,CAAC;AAE3E,eAAO,MAAM,aAAa,EAAE,SAAS,UAAU,EAKrC,CAAC;AAEX,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,UAAU,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,iKAAiK;IACjK,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,yGAAyG;IACzG,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,wBAAsB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAYrE;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,UAAU,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,UAAU,CAAC;IACjB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;IACd,gDAAgD;IAChD,UAAU,EAAE,OAAO,GAAG,IAAI,CAAC;CAC5B;AAqCD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,SAAS,EAAE,CAAC;IAClB,MAAM,EAAE,UAAU,CAAC;IACnB,MAAM,EAAE,YAAY,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAiClF;AAED,MAAM,WAAW,WAAW;IAC1B,CAAC,EAAE,MAAM,CAAC;IACV,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,WAAW,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;IACxC,aAAa,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC;CACpE;AAqBD,wBAAgB,aAAa,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,WAAW,CA0BhE;AAMD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CA0B7D"}