@knowledgine/core 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/dist/config/config-loader.d.ts +22 -0
  2. package/dist/config/config-loader.d.ts.map +1 -0
  3. package/dist/config/config-loader.js +73 -0
  4. package/dist/config/config-loader.js.map +1 -0
  5. package/dist/config.js +1 -1
  6. package/dist/config.js.map +1 -1
  7. package/dist/embedding/model-downloader.d.ts +34 -0
  8. package/dist/embedding/model-downloader.d.ts.map +1 -0
  9. package/dist/embedding/model-downloader.js +168 -0
  10. package/dist/embedding/model-downloader.js.map +1 -0
  11. package/dist/embedding/onnx-embedding-provider.js +2 -2
  12. package/dist/embedding/onnx-embedding-provider.js.map +1 -1
  13. package/dist/feedback/feedback-learner.d.ts +29 -0
  14. package/dist/feedback/feedback-learner.d.ts.map +1 -0
  15. package/dist/feedback/feedback-learner.js +88 -0
  16. package/dist/feedback/feedback-learner.js.map +1 -0
  17. package/dist/feedback/feedback-repository.d.ts +41 -0
  18. package/dist/feedback/feedback-repository.d.ts.map +1 -0
  19. package/dist/feedback/feedback-repository.js +90 -0
  20. package/dist/feedback/feedback-repository.js.map +1 -0
  21. package/dist/feedback/index.d.ts +5 -0
  22. package/dist/feedback/index.d.ts.map +1 -0
  23. package/dist/feedback/index.js +3 -0
  24. package/dist/feedback/index.js.map +1 -0
  25. package/dist/graph/entity-extractor.d.ts +8 -2
  26. package/dist/graph/entity-extractor.d.ts.map +1 -1
  27. package/dist/graph/entity-extractor.js +94 -12
  28. package/dist/graph/entity-extractor.js.map +1 -1
  29. package/dist/graph/graph-repository.d.ts +9 -0
  30. package/dist/graph/graph-repository.d.ts.map +1 -1
  31. package/dist/graph/graph-repository.js +49 -14
  32. package/dist/graph/graph-repository.js.map +1 -1
  33. package/dist/index.d.ts +20 -4
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +33 -4
  36. package/dist/index.js.map +1 -1
  37. package/dist/provenance/provenance-repository.d.ts +47 -0
  38. package/dist/provenance/provenance-repository.d.ts.map +1 -0
  39. package/dist/provenance/provenance-repository.js +121 -0
  40. package/dist/provenance/provenance-repository.js.map +1 -0
  41. package/dist/search/hybrid-searcher.js +2 -2
  42. package/dist/search/hybrid-searcher.js.map +1 -1
  43. package/dist/search/knowledge-searcher.d.ts.map +1 -1
  44. package/dist/search/knowledge-searcher.js +9 -1
  45. package/dist/search/knowledge-searcher.js.map +1 -1
  46. package/dist/search/semantic-searcher.d.ts.map +1 -1
  47. package/dist/search/semantic-searcher.js +3 -2
  48. package/dist/search/semantic-searcher.js.map +1 -1
  49. package/dist/services/knowledge-service.d.ts +128 -0
  50. package/dist/services/knowledge-service.d.ts.map +1 -0
  51. package/dist/services/knowledge-service.js +170 -0
  52. package/dist/services/knowledge-service.js.map +1 -0
  53. package/dist/storage/database.d.ts +5 -0
  54. package/dist/storage/database.d.ts.map +1 -1
  55. package/dist/storage/database.js +34 -4
  56. package/dist/storage/database.js.map +1 -1
  57. package/dist/storage/knowledge-repository.d.ts +17 -0
  58. package/dist/storage/knowledge-repository.d.ts.map +1 -1
  59. package/dist/storage/knowledge-repository.js +47 -7
  60. package/dist/storage/knowledge-repository.js.map +1 -1
  61. package/dist/storage/migrations/005a_events_layer.d.ts +3 -0
  62. package/dist/storage/migrations/005a_events_layer.d.ts.map +1 -0
  63. package/dist/storage/migrations/005a_events_layer.js +55 -0
  64. package/dist/storage/migrations/005a_events_layer.js.map +1 -0
  65. package/dist/storage/migrations/005b_bitemporal.d.ts +3 -0
  66. package/dist/storage/migrations/005b_bitemporal.d.ts.map +1 -0
  67. package/dist/storage/migrations/005b_bitemporal.js +53 -0
  68. package/dist/storage/migrations/005b_bitemporal.js.map +1 -0
  69. package/dist/storage/migrations/005c_provenance.d.ts +3 -0
  70. package/dist/storage/migrations/005c_provenance.d.ts.map +1 -0
  71. package/dist/storage/migrations/005c_provenance.js +56 -0
  72. package/dist/storage/migrations/005c_provenance.js.map +1 -0
  73. package/dist/storage/migrations/006_extraction_feedback.d.ts +3 -0
  74. package/dist/storage/migrations/006_extraction_feedback.d.ts.map +1 -0
  75. package/dist/storage/migrations/006_extraction_feedback.js +30 -0
  76. package/dist/storage/migrations/006_extraction_feedback.js.map +1 -0
  77. package/dist/types.d.ts +26 -0
  78. package/dist/types.d.ts.map +1 -1
  79. package/package.json +8 -4
@@ -0,0 +1,22 @@
1
+ import type { KnowledgineConfig } from "../config.js";
2
+ export interface RcConfig {
3
+ semantic?: boolean;
4
+ defaultPath?: string;
5
+ [key: string]: unknown;
6
+ }
7
+ /**
8
+ * Load knowledgine configuration from RC file and environment variables.
9
+ * Priority: env var > RC file > defaults (embedding.enabled = false)
10
+ */
11
+ export declare function loadConfig(rootPath: string): KnowledgineConfig;
12
+ /**
13
+ * Resolve the default root path.
14
+ * Priority: cliPath > KNOWLEDGINE_PATH env > cwd/.knowledginerc.json defaultPath > cwd
15
+ */
16
+ export declare function resolveDefaultPath(cliPath?: string): string;
17
+ /**
18
+ * Write a .knowledginerc.json config file to the specified directory.
19
+ * Merges with existing config if present.
20
+ */
21
+ export declare function writeRcConfig(dirPath: string, config: RcConfig): void;
22
+ //# sourceMappingURL=config-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../../src/config/config-loader.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEtD,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,CAgB9D;AAqBD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAW3D;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAG,IAAI,CAYrE"}
@@ -0,0 +1,73 @@
1
+ import { readFileSync, existsSync, writeFileSync } from "fs";
2
+ import { resolve } from "path";
3
+ import { parse as parseYaml } from "yaml";
4
+ import { defineConfig } from "../config.js";
5
+ /**
6
+ * Load knowledgine configuration from RC file and environment variables.
7
+ * Priority: env var > RC file > defaults (embedding.enabled = false)
8
+ */
9
+ export function loadConfig(rootPath) {
10
+ const rcConfig = loadRcFile(rootPath);
11
+ // Environment variable override
12
+ const envSemantic = process.env["KNOWLEDGINE_SEMANTIC"];
13
+ const semanticEnabled = envSemantic === "true" || envSemantic === "1" || rcConfig?.semantic === true;
14
+ return defineConfig({
15
+ rootPath,
16
+ embedding: {
17
+ modelName: "all-MiniLM-L6-v2",
18
+ dimensions: 384,
19
+ enabled: semanticEnabled,
20
+ },
21
+ });
22
+ }
23
+ function loadRcFile(rootPath) {
24
+ const jsonPath = resolve(rootPath, ".knowledginerc.json");
25
+ const ymlPath = resolve(rootPath, ".knowledginerc.yml");
26
+ try {
27
+ if (existsSync(jsonPath)) {
28
+ return JSON.parse(readFileSync(jsonPath, "utf-8"));
29
+ }
30
+ if (existsSync(ymlPath)) {
31
+ return parseYaml(readFileSync(ymlPath, "utf-8"));
32
+ }
33
+ }
34
+ catch (error) {
35
+ console.error(`Warning: Failed to parse config file: ${error instanceof Error ? error.message : String(error)}`);
36
+ }
37
+ return null;
38
+ }
39
+ /**
40
+ * Resolve the default root path.
41
+ * Priority: cliPath > KNOWLEDGINE_PATH env > cwd/.knowledginerc.json defaultPath > cwd
42
+ */
43
+ export function resolveDefaultPath(cliPath) {
44
+ if (cliPath)
45
+ return resolve(cliPath);
46
+ const envPath = process.env["KNOWLEDGINE_PATH"];
47
+ if (envPath)
48
+ return resolve(envPath);
49
+ // Read from cwd's .knowledginerc.json (NOT rootPath's — avoids circular dependency)
50
+ const rcConfig = loadRcFile(process.cwd());
51
+ if (rcConfig?.defaultPath)
52
+ return resolve(rcConfig.defaultPath);
53
+ return resolve(process.cwd());
54
+ }
55
+ /**
56
+ * Write a .knowledginerc.json config file to the specified directory.
57
+ * Merges with existing config if present.
58
+ */
59
+ export function writeRcConfig(dirPath, config) {
60
+ const rcPath = resolve(dirPath, ".knowledginerc.json");
61
+ let existing = {};
62
+ try {
63
+ if (existsSync(rcPath)) {
64
+ existing = JSON.parse(readFileSync(rcPath, "utf-8"));
65
+ }
66
+ }
67
+ catch {
68
+ // If existing file is invalid, overwrite it
69
+ }
70
+ const merged = { ...existing, ...config };
71
+ writeFileSync(rcPath, JSON.stringify(merged, null, 2) + "\n");
72
+ }
73
+ //# sourceMappingURL=config-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-loader.js","sourceRoot":"","sources":["../../src/config/config-loader.ts"],"names":[],"mappings":"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"}
package/dist/config.js CHANGED
@@ -11,7 +11,7 @@ const DEFAULT_CONFIG = {
11
11
  embedding: {
12
12
  modelName: "all-MiniLM-L6-v2",
13
13
  dimensions: 384,
14
- enabled: true,
14
+ enabled: false,
15
15
  },
16
16
  search: {
17
17
  defaultMode: "keyword",
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAiC/B,MAAM,cAAc,GAAsB;IACxC,QAAQ,EAAE,GAAG;IACb,MAAM,EAAE,EAAE;IACV,QAAQ,EAAE;QACR,OAAO,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,CAAC;KACrD;IACD,WAAW,EAAE;QACX,cAAc,EAAE,EAAE;KACnB;IACD,SAAS,EAAE;QACT,SAAS,EAAE,kBAAkB;QAC7B,UAAU,EAAE,GAAG;QACf,OAAO,EAAE,IAAI;KACd;IACD,MAAM,EAAE;QACN,WAAW,EAAE,SAAS;QACtB,WAAW,EAAE,GAAG;KACjB;CACF,CAAC;AAEF,MAAM,UAAU,YAAY,CAAC,UAAsC,EAAE;IACnE,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,cAAc,CAAC,QAAQ,CAAC;IAC7D,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,QAAQ,EAAE,cAAc,EAAE,cAAc,CAAC,CAAC;IAEnF,OAAO;QACL,GAAG,cAAc;QACjB,GAAG,OAAO;QACV,QAAQ;QACR,MAAM;QACN,QAAQ,EAAE;YACR,GAAG,cAAc,CAAC,QAAQ;YAC1B,GAAG,OAAO,CAAC,QAAQ;SACpB;QACD,WAAW,EAAE;YACX,GAAG,cAAc,CAAC,WAAW;YAC7B,GAAG,OAAO,CAAC,WAAW;SACvB;QACD,SAAS,EAAE;YACT,GAAG,cAAc,CAAC,SAAS;YAC3B,GAAG,OAAO,CAAC,SAAS;SACrB;QACD,MAAM,EAAE;YACN,GAAG,cAAc,CAAC,MAAM;YACxB,GAAG,OAAO,CAAC,MAAM;SAClB;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAiC/B,MAAM,cAAc,GAAsB;IACxC,QAAQ,EAAE,GAAG;IACb,MAAM,EAAE,EAAE;IACV,QAAQ,EAAE;QACR,OAAO,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,CAAC;KACrD;IACD,WAAW,EAAE;QACX,cAAc,EAAE,EAAE;KACnB;IACD,SAAS,EAAE;QACT,SAAS,EAAE,kBAAkB;QAC7B,UAAU,EAAE,GAAG;QACf,OAAO,EAAE,KAAK;KACf;IACD,MAAM,EAAE;QACN,WAAW,EAAE,SAAS;QACtB,WAAW,EAAE,GAAG;KACjB;CACF,CAAC;AAEF,MAAM,UAAU,YAAY,CAAC,UAAsC,EAAE;IACnE,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,cAAc,CAAC,QAAQ,CAAC;IAC7D,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,QAAQ,EAAE,cAAc,EAAE,cAAc,CAAC,CAAC;IAEnF,OAAO;QACL,GAAG,cAAc;QACjB,GAAG,OAAO;QACV,QAAQ;QACR,MAAM;QACN,QAAQ,EAAE;YACR,GAAG,cAAc,CAAC,QAAQ;YAC1B,GAAG,OAAO,CAAC,QAAQ;SACpB;QACD,WAAW,EAAE;YACX,GAAG,cAAc,CAAC,WAAW;YAC7B,GAAG,OAAO,CAAC,WAAW;SACvB;QACD,SAAS,EAAE;YACT,GAAG,cAAc,CAAC,SAAS;YAC3B,GAAG,OAAO,CAAC,SAAS;SACrB;QACD,MAAM,EAAE;YACN,GAAG,cAAc,CAAC,MAAM;YACxB,GAAG,OAAO,CAAC,MAAM;SAClB;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Embedding model downloader.
3
+ * Downloads all-MiniLM-L6-v2 ONNX model files from HuggingFace.
4
+ *
5
+ * Features:
6
+ * - Atomic download (.tmp + rename)
7
+ * - Redirect limit (max 5)
8
+ * - Timeout (5 minutes)
9
+ * - Progress callback
10
+ * - Skip existing files (0-byte treated as corrupt)
11
+ * - SIGINT cleanup
12
+ */
13
+ import type { ModelManager } from "./model-manager.js";
14
+ export interface DownloadProgress {
15
+ file: string;
16
+ downloaded: number;
17
+ total: number | null;
18
+ }
19
+ export interface DownloadOptions {
20
+ onProgress?: (progress: DownloadProgress) => void;
21
+ onFileComplete?: (file: string) => void;
22
+ timeoutMs?: number;
23
+ maxRedirects?: number;
24
+ }
25
+ export interface ModelFile {
26
+ url: string;
27
+ dest: string;
28
+ }
29
+ export declare const MODEL_FILES: ModelFile[];
30
+ export declare function downloadModel(modelManager: ModelManager, options?: DownloadOptions): Promise<{
31
+ downloaded: string[];
32
+ skipped: string[];
33
+ }>;
34
+ //# sourceMappingURL=model-downloader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-downloader.d.ts","sourceRoot":"","sources":["../../src/embedding/model-downloader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAClD,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAkBD,eAAO,MAAM,WAAW,EAAE,SAAS,EAalC,CAAC;AAgIF,wBAAsB,aAAa,CACjC,YAAY,EAAE,YAAY,EAC1B,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAqBtD"}
@@ -0,0 +1,168 @@
1
+ /**
2
+ * Embedding model downloader.
3
+ * Downloads all-MiniLM-L6-v2 ONNX model files from HuggingFace.
4
+ *
5
+ * Features:
6
+ * - Atomic download (.tmp + rename)
7
+ * - Redirect limit (max 5)
8
+ * - Timeout (5 minutes)
9
+ * - Progress callback
10
+ * - Skip existing files (0-byte treated as corrupt)
11
+ * - SIGINT cleanup
12
+ */
13
+ import { mkdirSync, renameSync, unlinkSync, existsSync, statSync, createWriteStream } from "fs";
14
+ import { get as httpsGet } from "https";
15
+ import { get as httpGet } from "http";
16
+ import { pipeline } from "stream/promises";
17
+ const HF_BASE = "https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2/resolve/main";
18
+ /**
19
+ * Select the best quantized ONNX model for the current platform.
20
+ * HuggingFace removed the generic `model_quantized.onnx` and now ships
21
+ * architecture-specific variants.
22
+ */
23
+ function selectOnnxModel() {
24
+ const arch = process.arch; // "arm64" | "x64" | ...
25
+ if (arch === "arm64") {
26
+ return `${HF_BASE}/onnx/model_qint8_arm64.onnx`;
27
+ }
28
+ // x64: prefer AVX2 quantized (widely supported on modern x86_64)
29
+ return `${HF_BASE}/onnx/model_quint8_avx2.onnx`;
30
+ }
31
+ export const MODEL_FILES = [
32
+ {
33
+ url: `${HF_BASE}/tokenizer.json`,
34
+ dest: "tokenizer.json",
35
+ },
36
+ {
37
+ url: `${HF_BASE}/config.json`,
38
+ dest: "config.json",
39
+ },
40
+ {
41
+ url: selectOnnxModel(),
42
+ dest: "model.onnx",
43
+ },
44
+ ];
45
+ function isExistingAndValid(filePath) {
46
+ if (!existsSync(filePath))
47
+ return false;
48
+ const stat = statSync(filePath);
49
+ return stat.size > 0;
50
+ }
51
+ function downloadFile(url, destPath, options, fileName, redirectCount = 0) {
52
+ const maxRedirects = options.maxRedirects ?? 5;
53
+ const timeoutMs = options.timeoutMs ?? 300_000; // 5 minutes
54
+ if (redirectCount > maxRedirects) {
55
+ return Promise.reject(new Error(`Too many redirects (${maxRedirects}) for ${url}`));
56
+ }
57
+ return new Promise((resolve, reject) => {
58
+ const tmpPath = destPath + ".tmp";
59
+ let aborted = false;
60
+ const cleanup = () => {
61
+ try {
62
+ if (existsSync(tmpPath))
63
+ unlinkSync(tmpPath);
64
+ }
65
+ catch {
66
+ // ignore cleanup errors
67
+ }
68
+ };
69
+ const onSigint = () => {
70
+ aborted = true;
71
+ cleanup();
72
+ };
73
+ process.on("SIGINT", onSigint);
74
+ const getFunc = url.startsWith("http://") ? httpGet : httpsGet;
75
+ const req = getFunc(url, (response) => {
76
+ if (aborted)
77
+ return;
78
+ // Handle redirects (301, 302, 307, 308)
79
+ if (response.statusCode === 301 ||
80
+ response.statusCode === 302 ||
81
+ response.statusCode === 307 ||
82
+ response.statusCode === 308) {
83
+ clearTimeout(timer);
84
+ process.removeListener("SIGINT", onSigint);
85
+ const rawLocation = response.headers.location;
86
+ if (!rawLocation) {
87
+ reject(new Error(`Redirect without location header for ${url}`));
88
+ return;
89
+ }
90
+ // Handle relative redirect URLs by resolving against the original URL
91
+ const location = rawLocation.startsWith("/") ? new URL(rawLocation, url).href : rawLocation;
92
+ downloadFile(location, destPath, options, fileName, redirectCount + 1)
93
+ .then(resolve)
94
+ .catch(reject);
95
+ return;
96
+ }
97
+ if (response.statusCode !== 200) {
98
+ clearTimeout(timer);
99
+ process.removeListener("SIGINT", onSigint);
100
+ reject(new Error(`HTTP ${response.statusCode} for ${fileName}`));
101
+ return;
102
+ }
103
+ const totalSize = response.headers["content-length"]
104
+ ? parseInt(response.headers["content-length"], 10)
105
+ : null;
106
+ let downloaded = 0;
107
+ response.on("data", (chunk) => {
108
+ downloaded += chunk.length;
109
+ options.onProgress?.({
110
+ file: fileName,
111
+ downloaded,
112
+ total: totalSize,
113
+ });
114
+ });
115
+ const fileStream = createWriteStream(tmpPath);
116
+ pipeline(response, fileStream)
117
+ .then(() => {
118
+ clearTimeout(timer);
119
+ process.removeListener("SIGINT", onSigint);
120
+ if (aborted) {
121
+ cleanup();
122
+ reject(new Error("Download aborted"));
123
+ return;
124
+ }
125
+ // Atomic rename
126
+ renameSync(tmpPath, destPath);
127
+ options.onFileComplete?.(fileName);
128
+ resolve();
129
+ })
130
+ .catch((err) => {
131
+ clearTimeout(timer);
132
+ process.removeListener("SIGINT", onSigint);
133
+ cleanup();
134
+ reject(err);
135
+ });
136
+ });
137
+ const timer = setTimeout(() => {
138
+ aborted = true;
139
+ req.destroy();
140
+ cleanup();
141
+ reject(new Error(`Download timeout (${timeoutMs}ms) for ${fileName}`));
142
+ }, timeoutMs);
143
+ req.on("error", (err) => {
144
+ clearTimeout(timer);
145
+ process.removeListener("SIGINT", onSigint);
146
+ cleanup();
147
+ reject(err);
148
+ });
149
+ });
150
+ }
151
+ export async function downloadModel(modelManager, options = {}) {
152
+ const modelDir = modelManager.getModelDir();
153
+ mkdirSync(modelDir, { recursive: true });
154
+ const downloaded = [];
155
+ const skipped = [];
156
+ for (const file of MODEL_FILES) {
157
+ const destPath = `${modelDir}/${file.dest}`;
158
+ if (isExistingAndValid(destPath)) {
159
+ skipped.push(file.dest);
160
+ options.onFileComplete?.(file.dest);
161
+ continue;
162
+ }
163
+ await downloadFile(file.url, destPath, options, file.dest);
164
+ downloaded.push(file.dest);
165
+ }
166
+ return { downloaded, skipped };
167
+ }
168
+ //# sourceMappingURL=model-downloader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-downloader.js","sourceRoot":"","sources":["../../src/embedding/model-downloader.ts"],"names":[],"mappings":"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"}
@@ -15,7 +15,7 @@ export class OnnxEmbeddingProvider {
15
15
  if (this.session)
16
16
  return this.session;
17
17
  if (!this.modelManager.isModelAvailable(this.modelName)) {
18
- throw new EmbeddingNotAvailableError(`Model "${this.modelName}" not found. Run the download script first: node scripts/download-model.js`);
18
+ throw new EmbeddingNotAvailableError(`Model "${this.modelName}" not found. Run 'knowledgine init' to download the model automatically.`);
19
19
  }
20
20
  try {
21
21
  const ort = await import("onnxruntime-node");
@@ -30,7 +30,7 @@ export class OnnxEmbeddingProvider {
30
30
  if (this.tokenizer)
31
31
  return this.tokenizer;
32
32
  if (!this.modelManager.isModelAvailable(this.modelName)) {
33
- throw new EmbeddingNotAvailableError(`Model "${this.modelName}" not found. Run the download script first: node scripts/download-model.js`);
33
+ throw new EmbeddingNotAvailableError(`Model "${this.modelName}" not found. Run 'knowledgine init' to download the model automatically.`);
34
34
  }
35
35
  this.tokenizer = new WordPieceTokenizer(this.modelManager.getTokenizerPath(this.modelName));
36
36
  return this.tokenizer;
@@ -1 +1 @@
1
- {"version":3,"file":"onnx-embedding-provider.js","sourceRoot":"","sources":["../../src/embedding/onnx-embedding-provider.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,EAAE,0BAA0B,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE1E,MAAM,UAAU,GAAG,GAAG,CAAC;AAEvB,MAAM,OAAO,qBAAqB;IACxB,OAAO,GAA4B,IAAI,CAAC;IACxC,SAAS,GAA8B,IAAI,CAAC;IAC5C,SAAS,CAAS;IAClB,YAAY,CAAe;IAEnC,YAAY,YAAoB,kBAAkB,EAAE,YAA2B;QAC7E,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,YAAY,GAAG,YAAY,IAAI,IAAI,YAAY,EAAE,CAAC;IACzD,CAAC;IAEO,KAAK,CAAC,UAAU;QACtB,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC,OAAO,CAAC;QAEtC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YACxD,MAAM,IAAI,0BAA0B,CAClC,UAAU,IAAI,CAAC,SAAS,4EAA4E,CACrG,CAAC;QACJ,CAAC;QAED,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;YAC7C,IAAI,CAAC,OAAO,GAAG,MAAM,GAAG,CAAC,gBAAgB,CAAC,MAAM,CAC9C,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,EAC9C,EAAE,kBAAkB,EAAE,CAAC,KAAK,CAAC,EAAE,CAChC,CAAC;YACF,OAAO,IAAI,CAAC,OAAO,CAAC;QACtB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,cAAc,CACtB,8BAA8B,IAAI,CAAC,SAAS,GAAG,EAC/C,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAC1D,CAAC;QACJ,CAAC;IACH,CAAC;IAEO,YAAY;QAClB,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC,SAAS,CAAC;QAC1C,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YACxD,MAAM,IAAI,0BAA0B,CAClC,UAAU,IAAI,CAAC,SAAS,4EAA4E,CACrG,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,SAAS,GAAG,IAAI,kBAAkB,CAAC,IAAI,CAAC,YAAY,CAAC,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;QAC5F,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,IAAY;QACtB,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC/C,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,KAAe;QAC9B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QACxC,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QAEtC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;YAC7C,MAAM,OAAO,GAAmB,EAAE,CAAC;YAEnC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBACvC,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAEvC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE;oBACzF,CAAC;oBACD,MAAM;iBACP,CAAC,CAAC;gBACH,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,MAAM,CAClC,OAAO,EACP,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EACrD,CAAC,CAAC,EAAE,MAAM,CAAC,CACZ,CAAC;gBACF,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,MAAM,CACjC,OAAO,EACP,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EACpD,CAAC,CAAC,EAAE,MAAM,CAAC,CACZ,CAAC;gBAEF,MAAM,KAAK,GAA2B;oBACpC,SAAS,EAAE,QAAQ;oBACnB,cAAc,EAAE,aAAa;oBAC7B,cAAc,EAAE,YAAY;iBAC7B,CAAC;gBACF,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBAExC,yDAAyD;gBACzD,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;gBACzC,MAAM,eAAe,GAAG,MAAM,CAAC,mBAAmB,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC;gBACzE,MAAM,IAAI,GAAG,eAAe,CAAC,IAAoB,CAAC;gBAClD,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;gBACjF,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC;YAC1C,CAAC;YAED,OAAO,OAAO,CAAC;QACjB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,0BAA0B,IAAI,KAAK,YAAY,cAAc,EAAE,CAAC;gBACnF,MAAM,KAAK,CAAC;YACd,CAAC;YACD,MAAM,IAAI,cAAc,CACtB,uBAAuB,EACvB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAC1D,CAAC;QACJ,CAAC;IACH,CAAC;IAED,aAAa;QACX,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YAC7B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACtB,CAAC;IACH,CAAC;IAEO,QAAQ,CACd,IAAkB,EAClB,aAAuB,EACvB,MAAc,EACd,UAAkB;QAElB,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,UAAU,CAAC,CAAC;QAC5C,IAAI,KAAK,GAAG,CAAC,CAAC;QAEd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAChC,IAAI,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC;gBAAE,SAAS;YACrC,KAAK,EAAE,CAAC;YACR,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;gBACpC,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,UAAU,GAAG,CAAC,CAAC,CAAC;YACxC,CAAC;QACH,CAAC;QAED,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;gBACpC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC;YACrB,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,SAAS,CAAC,GAAiB;QACjC,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,KAAK,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;YACpB,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;QAChB,CAAC;QACD,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvB,IAAI,IAAI,KAAK,CAAC;YAAE,OAAO,GAAG,CAAC;QAC3B,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACpC,MAAM,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;QAC5B,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
1
+ {"version":3,"file":"onnx-embedding-provider.js","sourceRoot":"","sources":["../../src/embedding/onnx-embedding-provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import { FeedbackRepository } from "./feedback-repository.js";
2
+ export interface TypeOverride {
3
+ name: string;
4
+ fromType: string;
5
+ toType: string;
6
+ }
7
+ export interface WhitelistEntry {
8
+ name: string;
9
+ type: string;
10
+ }
11
+ export interface ExtractionRules {
12
+ version: number;
13
+ updatedAt: string;
14
+ stopWords: {
15
+ added: string[];
16
+ };
17
+ typeOverrides: TypeOverride[];
18
+ entityBlacklist: string[];
19
+ entityWhitelist: WhitelistEntry[];
20
+ }
21
+ export declare class FeedbackLearner {
22
+ private feedbackRepository;
23
+ private rulesPath;
24
+ constructor(feedbackRepository: FeedbackRepository, rulesPath: string);
25
+ applyFeedback(feedbackId: number): void;
26
+ loadRules(): ExtractionRules;
27
+ private saveRules;
28
+ }
29
+ //# sourceMappingURL=feedback-learner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feedback-learner.d.ts","sourceRoot":"","sources":["../../src/feedback/feedback-learner.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE9D,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE;QAAE,KAAK,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAC/B,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,eAAe,EAAE,cAAc,EAAE,CAAC;CACnC;AAaD,qBAAa,eAAe;IAExB,OAAO,CAAC,kBAAkB;IAC1B,OAAO,CAAC,SAAS;gBADT,kBAAkB,EAAE,kBAAkB,EACtC,SAAS,EAAE,MAAM;IAG3B,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAyDvC,SAAS,IAAI,eAAe;IAS5B,OAAO,CAAC,SAAS;CAMlB"}
@@ -0,0 +1,88 @@
1
+ import { readFileSync, writeFileSync, renameSync } from "fs";
2
+ import { join, dirname } from "path";
3
+ import { FeedbackRepository } from "./feedback-repository.js";
4
+ function createEmptyRules() {
5
+ return {
6
+ version: 1,
7
+ updatedAt: new Date().toISOString(),
8
+ stopWords: { added: [] },
9
+ typeOverrides: [],
10
+ entityBlacklist: [],
11
+ entityWhitelist: [],
12
+ };
13
+ }
14
+ export class FeedbackLearner {
15
+ feedbackRepository;
16
+ rulesPath;
17
+ constructor(feedbackRepository, rulesPath) {
18
+ this.feedbackRepository = feedbackRepository;
19
+ this.rulesPath = rulesPath;
20
+ }
21
+ applyFeedback(feedbackId) {
22
+ const feedback = this.feedbackRepository.getById(feedbackId);
23
+ if (!feedback) {
24
+ throw new Error(`Feedback record not found: id=${feedbackId}`);
25
+ }
26
+ const rules = this.loadRules();
27
+ switch (feedback.errorType) {
28
+ case "false_positive":
29
+ if (!rules.entityBlacklist.includes(feedback.entityName)) {
30
+ rules.entityBlacklist.push(feedback.entityName);
31
+ }
32
+ break;
33
+ case "wrong_type":
34
+ if (!feedback.entityType || !feedback.correctType) {
35
+ throw new Error("wrong_type feedback requires both entityType and correctType");
36
+ }
37
+ // Check for existing override for same entity name
38
+ const existingIdx = rules.typeOverrides.findIndex((o) => o.name === feedback.entityName);
39
+ const override = {
40
+ name: feedback.entityName,
41
+ fromType: feedback.entityType,
42
+ toType: feedback.correctType,
43
+ };
44
+ if (existingIdx >= 0) {
45
+ rules.typeOverrides[existingIdx] = override;
46
+ }
47
+ else {
48
+ rules.typeOverrides.push(override);
49
+ }
50
+ break;
51
+ case "missed_entity": {
52
+ const entityType = feedback.correctType ?? feedback.entityType ?? "technology";
53
+ // Check for existing whitelist entry for same entity name
54
+ const existingWlIdx = rules.entityWhitelist.findIndex((w) => w.name === feedback.entityName);
55
+ const entry = {
56
+ name: feedback.entityName,
57
+ type: entityType,
58
+ };
59
+ if (existingWlIdx >= 0) {
60
+ rules.entityWhitelist[existingWlIdx] = entry;
61
+ }
62
+ else {
63
+ rules.entityWhitelist.push(entry);
64
+ }
65
+ break;
66
+ }
67
+ }
68
+ rules.updatedAt = new Date().toISOString();
69
+ this.saveRules(rules);
70
+ this.feedbackRepository.updateStatus(feedbackId, "applied");
71
+ }
72
+ loadRules() {
73
+ try {
74
+ const content = readFileSync(this.rulesPath, "utf-8");
75
+ return JSON.parse(content);
76
+ }
77
+ catch {
78
+ return createEmptyRules();
79
+ }
80
+ }
81
+ saveRules(rules) {
82
+ const dir = dirname(this.rulesPath);
83
+ const tmpPath = join(dir, `.extraction-rules.tmp.${process.pid}.json`);
84
+ writeFileSync(tmpPath, JSON.stringify(rules, null, 2), "utf-8");
85
+ renameSync(tmpPath, this.rulesPath);
86
+ }
87
+ }
88
+ //# sourceMappingURL=feedback-learner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feedback-learner.js","sourceRoot":"","sources":["../../src/feedback/feedback-learner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import type Database from "better-sqlite3";
2
+ import type { FeedbackErrorType, FeedbackStatus } from "../types.js";
3
+ export interface CreateFeedbackInput {
4
+ entityName: string;
5
+ errorType: FeedbackErrorType;
6
+ entityType?: string;
7
+ correctType?: string;
8
+ noteId?: number;
9
+ details?: string;
10
+ }
11
+ export interface FeedbackRecord {
12
+ id: number;
13
+ entityName: string;
14
+ entityType: string | null;
15
+ errorType: FeedbackErrorType;
16
+ correctType: string | null;
17
+ noteId: number | null;
18
+ details: string | null;
19
+ status: FeedbackStatus;
20
+ createdAt: string;
21
+ appliedAt: string | null;
22
+ }
23
+ export declare class FeedbackRepository {
24
+ private db;
25
+ constructor(db: Database.Database);
26
+ create(input: CreateFeedbackInput): FeedbackRecord;
27
+ getById(id: number): FeedbackRecord | undefined;
28
+ list(options?: {
29
+ status?: string;
30
+ limit?: number;
31
+ }): FeedbackRecord[];
32
+ updateStatus(id: number, status: string): void;
33
+ delete(id: number): void;
34
+ getStats(): {
35
+ total: number;
36
+ pending: number;
37
+ applied: number;
38
+ dismissed: number;
39
+ };
40
+ }
41
+ //# sourceMappingURL=feedback-repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feedback-repository.d.ts","sourceRoot":"","sources":["../../src/feedback/feedback-repository.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAKrE,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,iBAAiB,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,iBAAiB,CAAC;IAC7B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,cAAc,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AA8BD,qBAAa,kBAAkB;IACjB,OAAO,CAAC,EAAE;gBAAF,EAAE,EAAE,QAAQ,CAAC,QAAQ;IAEzC,MAAM,CAAC,KAAK,EAAE,mBAAmB,GAAG,cAAc;IAsBlD,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAO/C,IAAI,CAAC,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,cAAc,EAAE;IAyBrE,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAe9C,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAQxB,QAAQ,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE;CAcnF"}
@@ -0,0 +1,90 @@
1
+ const VALID_ERROR_TYPES = ["false_positive", "wrong_type", "missed_entity"];
2
+ const VALID_STATUSES = ["pending", "applied", "dismissed"];
3
+ function rowToRecord(row) {
4
+ return {
5
+ id: row.id,
6
+ entityName: row.entity_name,
7
+ entityType: row.entity_type,
8
+ errorType: row.error_type,
9
+ correctType: row.correct_type,
10
+ noteId: row.note_id,
11
+ details: row.details,
12
+ status: row.status,
13
+ createdAt: row.created_at,
14
+ appliedAt: row.applied_at,
15
+ };
16
+ }
17
+ export class FeedbackRepository {
18
+ db;
19
+ constructor(db) {
20
+ this.db = db;
21
+ }
22
+ create(input) {
23
+ if (!VALID_ERROR_TYPES.includes(input.errorType)) {
24
+ throw new Error(`Invalid error_type: "${input.errorType}". Must be one of: ${VALID_ERROR_TYPES.join(", ")}`);
25
+ }
26
+ const stmt = this.db.prepare(`
27
+ INSERT INTO extraction_feedback (entity_name, entity_type, error_type, correct_type, note_id, details)
28
+ VALUES (?, ?, ?, ?, ?, ?)
29
+ `);
30
+ const info = stmt.run(input.entityName, input.entityType ?? null, input.errorType, input.correctType ?? null, input.noteId ?? null, input.details ?? null);
31
+ return this.getById(Number(info.lastInsertRowid));
32
+ }
33
+ getById(id) {
34
+ const row = this.db.prepare("SELECT * FROM extraction_feedback WHERE id = ?").get(id);
35
+ return row ? rowToRecord(row) : undefined;
36
+ }
37
+ list(options) {
38
+ const conditions = [];
39
+ const params = [];
40
+ if (options?.status) {
41
+ if (!VALID_STATUSES.includes(options.status)) {
42
+ throw new Error(`Invalid status: "${options.status}". Must be one of: ${VALID_STATUSES.join(", ")}`);
43
+ }
44
+ conditions.push("status = ?");
45
+ params.push(options.status);
46
+ }
47
+ const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
48
+ const limit = options?.limit ?? 100;
49
+ params.push(limit);
50
+ const rows = this.db
51
+ .prepare(`SELECT * FROM extraction_feedback ${where} ORDER BY created_at DESC LIMIT ?`)
52
+ .all(...params);
53
+ return rows.map(rowToRecord);
54
+ }
55
+ updateStatus(id, status) {
56
+ if (!VALID_STATUSES.includes(status)) {
57
+ throw new Error(`Invalid status: "${status}". Must be one of: ${VALID_STATUSES.join(", ")}`);
58
+ }
59
+ const appliedAt = status === "applied" ? new Date().toISOString() : null;
60
+ const info = this.db
61
+ .prepare("UPDATE extraction_feedback SET status = ?, applied_at = ? WHERE id = ?")
62
+ .run(status, appliedAt, id);
63
+ if (info.changes === 0) {
64
+ throw new Error(`Feedback record not found: id=${id}`);
65
+ }
66
+ }
67
+ delete(id) {
68
+ const info = this.db.prepare("DELETE FROM extraction_feedback WHERE id = ?").run(id);
69
+ if (info.changes === 0) {
70
+ throw new Error(`Feedback record not found: id=${id}`);
71
+ }
72
+ }
73
+ getStats() {
74
+ const rows = this.db
75
+ .prepare(`SELECT status, COUNT(*) as count FROM extraction_feedback GROUP BY status`)
76
+ .all();
77
+ const stats = { total: 0, pending: 0, applied: 0, dismissed: 0 };
78
+ for (const row of rows) {
79
+ stats.total += row.count;
80
+ if (row.status === "pending")
81
+ stats.pending = row.count;
82
+ else if (row.status === "applied")
83
+ stats.applied = row.count;
84
+ else if (row.status === "dismissed")
85
+ stats.dismissed = row.count;
86
+ }
87
+ return stats;
88
+ }
89
+ }
90
+ //# sourceMappingURL=feedback-repository.js.map