@mmnto/totem 1.4.0 → 1.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ast-query.d.ts +2 -1
- package/dist/ast-query.d.ts.map +1 -1
- package/dist/ast-query.js +6 -15
- package/dist/ast-query.js.map +1 -1
- package/dist/ast-query.test.js +31 -1
- package/dist/ast-query.test.js.map +1 -1
- package/dist/chunkers/chunker-utils.d.ts +4 -0
- package/dist/chunkers/chunker-utils.d.ts.map +1 -0
- package/dist/chunkers/chunker-utils.js +13 -0
- package/dist/chunkers/chunker-utils.js.map +1 -0
- package/dist/chunkers/markdown-chunker.d.ts.map +1 -1
- package/dist/chunkers/markdown-chunker.js +1 -11
- package/dist/chunkers/markdown-chunker.js.map +1 -1
- package/dist/chunkers/session-log-chunker.d.ts.map +1 -1
- package/dist/chunkers/session-log-chunker.js +1 -12
- package/dist/chunkers/session-log-chunker.js.map +1 -1
- package/dist/chunkers/session-log-chunker.test.d.ts +2 -0
- package/dist/chunkers/session-log-chunker.test.d.ts.map +1 -0
- package/dist/chunkers/session-log-chunker.test.js +235 -0
- package/dist/chunkers/session-log-chunker.test.js.map +1 -0
- package/dist/embedders/gemini-embedder.test.d.ts +2 -0
- package/dist/embedders/gemini-embedder.test.d.ts.map +1 -0
- package/dist/embedders/gemini-embedder.test.js +158 -0
- package/dist/embedders/gemini-embedder.test.js.map +1 -0
- package/dist/embedders/ollama-embedder.d.ts +2 -1
- package/dist/embedders/ollama-embedder.d.ts.map +1 -1
- package/dist/embedders/ollama-embedder.js +11 -3
- package/dist/embedders/ollama-embedder.js.map +1 -1
- package/dist/embedders/ollama-embedder.test.d.ts +2 -0
- package/dist/embedders/ollama-embedder.test.d.ts.map +1 -0
- package/dist/embedders/ollama-embedder.test.js +211 -0
- package/dist/embedders/ollama-embedder.test.js.map +1 -0
- package/dist/errors.d.ts +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/lock.d.ts.map +1 -1
- package/dist/lock.js +3 -1
- package/dist/lock.js.map +1 -1
- package/dist/rule-engine.js +4 -5
- package/dist/rule-engine.js.map +1 -1
- package/dist/rule-engine.test.js +46 -0
- package/dist/rule-engine.test.js.map +1 -1
- package/dist/rule-metrics.test.d.ts +2 -0
- package/dist/rule-metrics.test.d.ts.map +1 -0
- package/dist/rule-metrics.test.js +205 -0
- package/dist/rule-metrics.test.js.map +1 -0
- package/dist/sanitize.d.ts.map +1 -1
- package/dist/sanitize.js +14 -7
- package/dist/sanitize.js.map +1 -1
- package/dist/sanitize.test.js +26 -0
- package/dist/sanitize.test.js.map +1 -1
- package/dist/store/lance-search.test.d.ts +2 -0
- package/dist/store/lance-search.test.d.ts.map +1 -0
- package/dist/store/lance-search.test.js +249 -0
- package/dist/store/lance-search.test.js.map +1 -0
- package/dist/store/lance-store.d.ts +9 -0
- package/dist/store/lance-store.d.ts.map +1 -1
- package/dist/store/lance-store.js +12 -1
- package/dist/store/lance-store.js.map +1 -1
- package/dist/store/lance-store.test.js +39 -1
- package/dist/store/lance-store.test.js.map +1 -1
- package/dist/suspicious-lesson.test.d.ts +2 -0
- package/dist/suspicious-lesson.test.d.ts.map +1 -0
- package/dist/suspicious-lesson.test.js +184 -0
- package/dist/suspicious-lesson.test.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { TotemConfigError, TotemError } from '../errors.js';
|
|
3
|
+
import { GeminiEmbedder } from './gemini-embedder.js';
|
|
4
|
+
// ─── Mock the @google/genai SDK ───────────────────────
|
|
5
|
+
const mockEmbedContent = vi.fn();
|
|
6
|
+
vi.mock('@google/genai', () => ({
|
|
7
|
+
GoogleGenAI: class {
|
|
8
|
+
models = { embedContent: mockEmbedContent };
|
|
9
|
+
},
|
|
10
|
+
}));
|
|
11
|
+
// ─── Helpers ──────────────────────────────────────────
|
|
12
|
+
/** Build a successful embedContent response for N texts. */
|
|
13
|
+
function embedResponse(count, dims = 768) {
|
|
14
|
+
return {
|
|
15
|
+
embeddings: Array.from({ length: count }, (_, i) => ({
|
|
16
|
+
values: new Array(dims).fill(i + 1),
|
|
17
|
+
})),
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
// ─── Tests ────────────────────────────────────────────
|
|
21
|
+
describe('GeminiEmbedder', () => {
|
|
22
|
+
beforeEach(() => {
|
|
23
|
+
process.env['GEMINI_API_KEY'] = 'test-gemini-key';
|
|
24
|
+
mockEmbedContent.mockReset();
|
|
25
|
+
// Mock setTimeout to resolve immediately (avoids fake timer issues in turbo builds)
|
|
26
|
+
vi.spyOn(globalThis, 'setTimeout').mockImplementation((fn) => {
|
|
27
|
+
fn();
|
|
28
|
+
return 0;
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
afterEach(() => {
|
|
32
|
+
delete process.env['GEMINI_API_KEY'];
|
|
33
|
+
delete process.env['GOOGLE_API_KEY'];
|
|
34
|
+
vi.restoreAllMocks();
|
|
35
|
+
});
|
|
36
|
+
// ─── Constructor ──────────────────────────────────────
|
|
37
|
+
it('throws TotemConfigError with no API key', () => {
|
|
38
|
+
delete process.env['GEMINI_API_KEY'];
|
|
39
|
+
expect(() => new GeminiEmbedder()).toThrow(TotemConfigError);
|
|
40
|
+
});
|
|
41
|
+
it('accepts GEMINI_API_KEY', () => {
|
|
42
|
+
expect(() => new GeminiEmbedder()).not.toThrow();
|
|
43
|
+
});
|
|
44
|
+
it('accepts GOOGLE_API_KEY as fallback', () => {
|
|
45
|
+
delete process.env['GEMINI_API_KEY'];
|
|
46
|
+
process.env['GOOGLE_API_KEY'] = 'google-key';
|
|
47
|
+
expect(() => new GeminiEmbedder()).not.toThrow();
|
|
48
|
+
});
|
|
49
|
+
// ─── Successful embedding ──────────────────────────
|
|
50
|
+
it('embeds a list of texts successfully', async () => {
|
|
51
|
+
mockEmbedContent.mockResolvedValueOnce(embedResponse(3));
|
|
52
|
+
const embedder = new GeminiEmbedder();
|
|
53
|
+
const result = await embedder.embed(['hello', 'world', 'test']);
|
|
54
|
+
expect(result).toHaveLength(3);
|
|
55
|
+
expect(result[0]).toHaveLength(768);
|
|
56
|
+
expect(mockEmbedContent).toHaveBeenCalledTimes(1);
|
|
57
|
+
const call = mockEmbedContent.mock.calls[0][0];
|
|
58
|
+
expect(call.model).toBe('gemini-embedding-2-preview');
|
|
59
|
+
expect(call.contents).toEqual([
|
|
60
|
+
{ parts: [{ text: 'hello' }] },
|
|
61
|
+
{ parts: [{ text: 'world' }] },
|
|
62
|
+
{ parts: [{ text: 'test' }] },
|
|
63
|
+
]);
|
|
64
|
+
expect(call.config.taskType).toBe('RETRIEVAL_DOCUMENT');
|
|
65
|
+
expect(call.config.outputDimensionality).toBe(768);
|
|
66
|
+
});
|
|
67
|
+
it('returns empty array for empty input', async () => {
|
|
68
|
+
const embedder = new GeminiEmbedder();
|
|
69
|
+
const result = await embedder.embed([]);
|
|
70
|
+
expect(result).toEqual([]);
|
|
71
|
+
expect(mockEmbedContent).not.toHaveBeenCalled();
|
|
72
|
+
});
|
|
73
|
+
// ─── Batch splitting ───────────────────────────────
|
|
74
|
+
it('splits inputs larger than 100 into batches', async () => {
|
|
75
|
+
mockEmbedContent
|
|
76
|
+
.mockResolvedValueOnce(embedResponse(100))
|
|
77
|
+
.mockResolvedValueOnce(embedResponse(50));
|
|
78
|
+
const embedder = new GeminiEmbedder();
|
|
79
|
+
const texts = Array.from({ length: 150 }, (_, i) => `text ${i}`);
|
|
80
|
+
const result = await embedder.embed(texts);
|
|
81
|
+
expect(result).toHaveLength(150);
|
|
82
|
+
expect(mockEmbedContent).toHaveBeenCalledTimes(2);
|
|
83
|
+
expect(mockEmbedContent.mock.calls[0][0].contents).toHaveLength(100);
|
|
84
|
+
expect(mockEmbedContent.mock.calls[1][0].contents).toHaveLength(50);
|
|
85
|
+
});
|
|
86
|
+
// ─── Retry logic: retryable errors ─────────────────
|
|
87
|
+
it('retries on 429 (rate limit) and succeeds', async () => {
|
|
88
|
+
const rateLimitErr = Object.assign(new Error('rate limited'), { status: 429 });
|
|
89
|
+
mockEmbedContent.mockRejectedValueOnce(rateLimitErr).mockResolvedValueOnce(embedResponse(1));
|
|
90
|
+
const embedder = new GeminiEmbedder();
|
|
91
|
+
const result = await embedder.embed(['hello']);
|
|
92
|
+
expect(result).toHaveLength(1);
|
|
93
|
+
expect(mockEmbedContent).toHaveBeenCalledTimes(2);
|
|
94
|
+
});
|
|
95
|
+
it('retries on 503 (unavailable) and succeeds', async () => {
|
|
96
|
+
const unavailableErr = Object.assign(new Error('service unavailable'), { status: 503 });
|
|
97
|
+
mockEmbedContent.mockRejectedValueOnce(unavailableErr).mockResolvedValueOnce(embedResponse(2));
|
|
98
|
+
const embedder = new GeminiEmbedder();
|
|
99
|
+
const result = await embedder.embed(['a', 'b']);
|
|
100
|
+
expect(result).toHaveLength(2);
|
|
101
|
+
expect(mockEmbedContent).toHaveBeenCalledTimes(2);
|
|
102
|
+
});
|
|
103
|
+
it('retries on RESOURCE_EXHAUSTED error name', async () => {
|
|
104
|
+
const exhaustedErr = Object.assign(new Error('quota exceeded'), {
|
|
105
|
+
name: 'RESOURCE_EXHAUSTED',
|
|
106
|
+
});
|
|
107
|
+
mockEmbedContent.mockRejectedValueOnce(exhaustedErr).mockResolvedValueOnce(embedResponse(1));
|
|
108
|
+
const embedder = new GeminiEmbedder();
|
|
109
|
+
const result = await embedder.embed(['test']);
|
|
110
|
+
expect(result).toHaveLength(1);
|
|
111
|
+
expect(mockEmbedContent).toHaveBeenCalledTimes(2);
|
|
112
|
+
});
|
|
113
|
+
it('retries up to MAX_RETRIES (3) times before giving up', async () => {
|
|
114
|
+
const rateLimitErr = Object.assign(new Error('rate limited'), { status: 429 });
|
|
115
|
+
mockEmbedContent
|
|
116
|
+
.mockRejectedValueOnce(rateLimitErr)
|
|
117
|
+
.mockRejectedValueOnce(rateLimitErr)
|
|
118
|
+
.mockRejectedValueOnce(rateLimitErr)
|
|
119
|
+
.mockRejectedValueOnce(rateLimitErr);
|
|
120
|
+
const embedder = new GeminiEmbedder();
|
|
121
|
+
await expect(embedder.embed(['test'])).rejects.toThrow(TotemError);
|
|
122
|
+
expect(mockEmbedContent).toHaveBeenCalledTimes(4);
|
|
123
|
+
});
|
|
124
|
+
// ─── Non-retryable errors ──────────────────────────
|
|
125
|
+
it('does not retry on non-retryable errors', async () => {
|
|
126
|
+
const authErr = Object.assign(new Error('unauthorized'), { status: 401 });
|
|
127
|
+
mockEmbedContent.mockRejectedValueOnce(authErr);
|
|
128
|
+
const embedder = new GeminiEmbedder();
|
|
129
|
+
await expect(embedder.embed(['test'])).rejects.toThrow('unauthorized');
|
|
130
|
+
expect(mockEmbedContent).toHaveBeenCalledTimes(1);
|
|
131
|
+
});
|
|
132
|
+
// ─── Response validation ───────────────────────────
|
|
133
|
+
it('throws when response has wrong embedding count', async () => {
|
|
134
|
+
mockEmbedContent.mockResolvedValueOnce(embedResponse(1)); // asked for 2
|
|
135
|
+
const embedder = new GeminiEmbedder();
|
|
136
|
+
await expect(embedder.embed(['a', 'b'])).rejects.toThrow('Expected 2 embeddings');
|
|
137
|
+
});
|
|
138
|
+
it('throws when response has missing embeddings', async () => {
|
|
139
|
+
mockEmbedContent.mockResolvedValueOnce({ embeddings: undefined });
|
|
140
|
+
const embedder = new GeminiEmbedder();
|
|
141
|
+
await expect(embedder.embed(['a'])).rejects.toThrow('Expected 1 embeddings');
|
|
142
|
+
});
|
|
143
|
+
it('throws when embedding values are missing', async () => {
|
|
144
|
+
mockEmbedContent.mockResolvedValueOnce({
|
|
145
|
+
embeddings: [{ values: undefined }],
|
|
146
|
+
});
|
|
147
|
+
const embedder = new GeminiEmbedder();
|
|
148
|
+
await expect(embedder.embed(['a'])).rejects.toThrow('missing values');
|
|
149
|
+
});
|
|
150
|
+
// ─── Custom model ──────────────────────────────────
|
|
151
|
+
it('uses custom model name', async () => {
|
|
152
|
+
mockEmbedContent.mockResolvedValueOnce(embedResponse(1));
|
|
153
|
+
const embedder = new GeminiEmbedder('custom-model');
|
|
154
|
+
await embedder.embed(['test']);
|
|
155
|
+
expect(mockEmbedContent.mock.calls[0][0].model).toBe('custom-model');
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
//# sourceMappingURL=gemini-embedder.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini-embedder.test.js","sourceRoot":"","sources":["../../src/embedders/gemini-embedder.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,7 +7,8 @@ export declare class OllamaEmbedder implements Embedder {
|
|
|
7
7
|
readonly dimensions: number;
|
|
8
8
|
private model;
|
|
9
9
|
private baseUrl;
|
|
10
|
-
|
|
10
|
+
private onWarn?;
|
|
11
|
+
constructor(model?: string, baseUrl?: string, dimensions?: number, onWarn?: (msg: string) => void);
|
|
11
12
|
private embedBatch;
|
|
12
13
|
embed(texts: string[]): Promise<number[][]>;
|
|
13
14
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ollama-embedder.d.ts","sourceRoot":"","sources":["../../src/embedders/ollama-embedder.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAM9C;;;GAGG;AACH,qBAAa,cAAe,YAAW,QAAQ;IAC7C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,OAAO,CAAS;
|
|
1
|
+
{"version":3,"file":"ollama-embedder.d.ts","sourceRoot":"","sources":["../../src/embedders/ollama-embedder.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAM9C;;;GAGG;AACH,qBAAa,cAAe,YAAW,QAAQ;IAC7C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,OAAO,CAAS;IAExB,OAAO,CAAC,MAAM,CAAC,CAAwB;gBAGrC,KAAK,GAAE,MAA2B,EAClC,OAAO,GAAE,MAAiC,EAC1C,UAAU,CAAC,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI;YAQlB,UAAU;IAgClB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;CA6ClD"}
|
|
@@ -11,10 +11,12 @@ export class OllamaEmbedder {
|
|
|
11
11
|
dimensions;
|
|
12
12
|
model;
|
|
13
13
|
baseUrl;
|
|
14
|
-
|
|
14
|
+
onWarn;
|
|
15
|
+
constructor(model = 'nomic-embed-text', baseUrl = 'http://localhost:11434', dimensions, onWarn) {
|
|
15
16
|
this.model = model;
|
|
16
17
|
this.baseUrl = baseUrl;
|
|
17
18
|
this.dimensions = dimensions ?? DEFAULT_DIMENSIONS;
|
|
19
|
+
this.onWarn = onWarn;
|
|
18
20
|
}
|
|
19
21
|
async embedBatch(texts) {
|
|
20
22
|
const response = await fetch(`${this.baseUrl}/api/embed`, {
|
|
@@ -43,6 +45,7 @@ export class OllamaEmbedder {
|
|
|
43
45
|
// Truncate oversized texts to stay within model context window
|
|
44
46
|
const truncated = texts.map((t) => t.length > MAX_CHARS_PER_TEXT ? t.slice(0, MAX_CHARS_PER_TEXT) : t);
|
|
45
47
|
const results = [];
|
|
48
|
+
let skipped = 0;
|
|
46
49
|
// Batch to avoid overwhelming Ollama with large payloads
|
|
47
50
|
for (let i = 0; i < truncated.length; i += MAX_BATCH_SIZE) {
|
|
48
51
|
const batch = truncated.slice(i, i + MAX_BATCH_SIZE);
|
|
@@ -58,13 +61,18 @@ export class OllamaEmbedder {
|
|
|
58
61
|
results.push(embedding);
|
|
59
62
|
}
|
|
60
63
|
catch {
|
|
61
|
-
// Individual text
|
|
62
|
-
|
|
64
|
+
// Individual text failed — insert zero vector to preserve 1:1 alignment with input
|
|
65
|
+
// Zero vectors have ~0 cosine similarity so they won't pollute search results
|
|
63
66
|
results.push(new Array(this.dimensions).fill(0));
|
|
67
|
+
this.onWarn?.(`[Totem] Zero-vector fallback for failed embedding (${text.length} chars): ${text.slice(0, 60)}...`);
|
|
68
|
+
skipped++;
|
|
64
69
|
}
|
|
65
70
|
}
|
|
66
71
|
}
|
|
67
72
|
}
|
|
73
|
+
if (skipped > 0) {
|
|
74
|
+
this.onWarn?.(`[Totem] Embedding batch complete: ${skipped} chunk(s) skipped due to failures`);
|
|
75
|
+
}
|
|
68
76
|
return results;
|
|
69
77
|
}
|
|
70
78
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ollama-embedder.js","sourceRoot":"","sources":["../../src/embedders/ollama-embedder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGhD,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAC/B,MAAM,cAAc,GAAG,EAAE,CAAC;AAC1B,MAAM,kBAAkB,GAAG,KAAK,CAAC,CAAC,iEAAiE;AAEnG;;;GAGG;AACH,MAAM,OAAO,cAAc;IAChB,UAAU,CAAS;IACpB,KAAK,CAAS;IACd,OAAO,CAAS;
|
|
1
|
+
{"version":3,"file":"ollama-embedder.js","sourceRoot":"","sources":["../../src/embedders/ollama-embedder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ollama-embedder.test.d.ts","sourceRoot":"","sources":["../../src/embedders/ollama-embedder.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { OllamaEmbedder } from './ollama-embedder.js';
|
|
3
|
+
// ─── Helpers ──────────────────────────────────────────
|
|
4
|
+
/** Build a fake Response that resolves with the given JSON. */
|
|
5
|
+
function okResponse(body) {
|
|
6
|
+
return {
|
|
7
|
+
ok: true,
|
|
8
|
+
status: 200,
|
|
9
|
+
json: () => Promise.resolve(body),
|
|
10
|
+
text: () => Promise.resolve(JSON.stringify(body)),
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
function errorResponse(status, body) {
|
|
14
|
+
return {
|
|
15
|
+
ok: false,
|
|
16
|
+
status,
|
|
17
|
+
json: () => Promise.resolve({}),
|
|
18
|
+
text: () => Promise.resolve(body),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/** Create a valid embedding response for N texts with the given dimensions. */
|
|
22
|
+
function embedResponse(count, dims = 768) {
|
|
23
|
+
return {
|
|
24
|
+
embeddings: Array.from({ length: count }, (_, i) => new Array(dims).fill(i + 1)),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
// ─── Tests ────────────────────────────────────────────
|
|
28
|
+
describe('OllamaEmbedder', () => {
|
|
29
|
+
const fetchSpy = vi.fn();
|
|
30
|
+
beforeEach(() => {
|
|
31
|
+
vi.stubGlobal('fetch', fetchSpy);
|
|
32
|
+
});
|
|
33
|
+
afterEach(() => {
|
|
34
|
+
vi.restoreAllMocks();
|
|
35
|
+
});
|
|
36
|
+
// ─── Constructor ────────────────────────────────────
|
|
37
|
+
it('uses default model, baseUrl and dimensions', () => {
|
|
38
|
+
const embedder = new OllamaEmbedder();
|
|
39
|
+
expect(embedder.dimensions).toBe(768);
|
|
40
|
+
});
|
|
41
|
+
it('accepts custom dimensions', () => {
|
|
42
|
+
const embedder = new OllamaEmbedder('nomic-embed-text', 'http://localhost:11434', 512);
|
|
43
|
+
expect(embedder.dimensions).toBe(512);
|
|
44
|
+
});
|
|
45
|
+
// ─── Successful embedding ──────────────────────────
|
|
46
|
+
it('embeds a list of texts successfully', async () => {
|
|
47
|
+
fetchSpy.mockResolvedValueOnce(okResponse(embedResponse(3)));
|
|
48
|
+
const embedder = new OllamaEmbedder();
|
|
49
|
+
const result = await embedder.embed(['hello', 'world', 'test']);
|
|
50
|
+
expect(result).toHaveLength(3);
|
|
51
|
+
expect(result[0]).toHaveLength(768);
|
|
52
|
+
expect(result[1]).toHaveLength(768);
|
|
53
|
+
expect(result[2]).toHaveLength(768);
|
|
54
|
+
// Verify the fetch was called correctly
|
|
55
|
+
expect(fetchSpy).toHaveBeenCalledTimes(1);
|
|
56
|
+
const [url, init] = fetchSpy.mock.calls[0];
|
|
57
|
+
expect(url).toBe('http://localhost:11434/api/embed');
|
|
58
|
+
expect(init?.method).toBe('POST');
|
|
59
|
+
const body = JSON.parse(init?.body);
|
|
60
|
+
expect(body.model).toBe('nomic-embed-text');
|
|
61
|
+
expect(body.input).toEqual(['hello', 'world', 'test']);
|
|
62
|
+
});
|
|
63
|
+
it('returns empty array for empty input', async () => {
|
|
64
|
+
const embedder = new OllamaEmbedder();
|
|
65
|
+
const result = await embedder.embed([]);
|
|
66
|
+
expect(result).toEqual([]);
|
|
67
|
+
expect(fetchSpy).not.toHaveBeenCalled();
|
|
68
|
+
});
|
|
69
|
+
// ─── Batch splitting ───────────────────────────────
|
|
70
|
+
it('splits large inputs into batches of 10', async () => {
|
|
71
|
+
// 25 texts → 3 batches (10 + 10 + 5)
|
|
72
|
+
fetchSpy
|
|
73
|
+
.mockResolvedValueOnce(okResponse(embedResponse(10)))
|
|
74
|
+
.mockResolvedValueOnce(okResponse(embedResponse(10)))
|
|
75
|
+
.mockResolvedValueOnce(okResponse(embedResponse(5)));
|
|
76
|
+
const embedder = new OllamaEmbedder();
|
|
77
|
+
const texts = Array.from({ length: 25 }, (_, i) => `text ${i}`);
|
|
78
|
+
const result = await embedder.embed(texts);
|
|
79
|
+
expect(result).toHaveLength(25);
|
|
80
|
+
expect(fetchSpy).toHaveBeenCalledTimes(3);
|
|
81
|
+
});
|
|
82
|
+
it('sends exactly MAX_BATCH_SIZE texts per batch', async () => {
|
|
83
|
+
fetchSpy
|
|
84
|
+
.mockResolvedValueOnce(okResponse(embedResponse(10)))
|
|
85
|
+
.mockResolvedValueOnce(okResponse(embedResponse(2)));
|
|
86
|
+
const embedder = new OllamaEmbedder();
|
|
87
|
+
const texts = Array.from({ length: 12 }, (_, i) => `text ${i}`);
|
|
88
|
+
await embedder.embed(texts);
|
|
89
|
+
// First call should have 10 texts
|
|
90
|
+
const firstBody = JSON.parse(fetchSpy.mock.calls[0][1]?.body);
|
|
91
|
+
expect(firstBody.input).toHaveLength(10);
|
|
92
|
+
// Second call should have 2 texts
|
|
93
|
+
const secondBody = JSON.parse(fetchSpy.mock.calls[1][1]?.body);
|
|
94
|
+
expect(secondBody.input).toHaveLength(2);
|
|
95
|
+
});
|
|
96
|
+
// ─── Text truncation ───────────────────────────────
|
|
97
|
+
it('truncates texts longer than 6000 characters', async () => {
|
|
98
|
+
fetchSpy.mockResolvedValueOnce(okResponse(embedResponse(1)));
|
|
99
|
+
const embedder = new OllamaEmbedder();
|
|
100
|
+
const longText = 'a'.repeat(10_000);
|
|
101
|
+
await embedder.embed([longText]);
|
|
102
|
+
const body = JSON.parse(fetchSpy.mock.calls[0][1]?.body);
|
|
103
|
+
expect(body.input[0].length).toBe(6_000);
|
|
104
|
+
});
|
|
105
|
+
it('does not truncate texts under the limit', async () => {
|
|
106
|
+
fetchSpy.mockResolvedValueOnce(okResponse(embedResponse(1)));
|
|
107
|
+
const embedder = new OllamaEmbedder();
|
|
108
|
+
const shortText = 'a'.repeat(5_000);
|
|
109
|
+
await embedder.embed([shortText]);
|
|
110
|
+
const body = JSON.parse(fetchSpy.mock.calls[0][1]?.body);
|
|
111
|
+
expect(body.input[0].length).toBe(5_000);
|
|
112
|
+
});
|
|
113
|
+
// ─── Error handling: model not found ────────────────
|
|
114
|
+
it('falls back to zero vector when model is not found (404)', async () => {
|
|
115
|
+
fetchSpy.mockResolvedValue(errorResponse(404, 'model not found'));
|
|
116
|
+
const warnSpy = vi.fn();
|
|
117
|
+
const embedder = new OllamaEmbedder('nonexistent-model', undefined, undefined, warnSpy);
|
|
118
|
+
const result = await embedder.embed(['test']);
|
|
119
|
+
expect(result).toHaveLength(1);
|
|
120
|
+
expect(result[0].every((v) => v === 0)).toBe(true);
|
|
121
|
+
});
|
|
122
|
+
it('falls back to zero vector on 400 model error', async () => {
|
|
123
|
+
fetchSpy.mockResolvedValue(errorResponse(400, 'no such model'));
|
|
124
|
+
const warnSpy = vi.fn();
|
|
125
|
+
const embedder = new OllamaEmbedder('bad-model', undefined, undefined, warnSpy);
|
|
126
|
+
const result = await embedder.embed(['test']);
|
|
127
|
+
expect(result).toHaveLength(1);
|
|
128
|
+
expect(result[0].every((v) => v === 0)).toBe(true);
|
|
129
|
+
});
|
|
130
|
+
it('falls back to zero vector when server returns 500 persistently', async () => {
|
|
131
|
+
fetchSpy.mockResolvedValue(errorResponse(500, 'internal server error'));
|
|
132
|
+
const warnSpy = vi.fn();
|
|
133
|
+
const embedder = new OllamaEmbedder(undefined, undefined, undefined, warnSpy);
|
|
134
|
+
const result = await embedder.embed(['test']);
|
|
135
|
+
expect(result).toHaveLength(1);
|
|
136
|
+
expect(result[0].every((v) => v === 0)).toBe(true);
|
|
137
|
+
});
|
|
138
|
+
// ─── Retry logic: batch failure → individual retry ─
|
|
139
|
+
it('retries each text individually when a batch fails', async () => {
|
|
140
|
+
// First batch call fails
|
|
141
|
+
fetchSpy.mockRejectedValueOnce(new Error('batch failed'));
|
|
142
|
+
// Then each individual text succeeds
|
|
143
|
+
fetchSpy.mockResolvedValueOnce(okResponse(embedResponse(1)));
|
|
144
|
+
fetchSpy.mockResolvedValueOnce(okResponse(embedResponse(1)));
|
|
145
|
+
fetchSpy.mockResolvedValueOnce(okResponse(embedResponse(1)));
|
|
146
|
+
const embedder = new OllamaEmbedder();
|
|
147
|
+
const result = await embedder.embed(['a', 'b', 'c']);
|
|
148
|
+
expect(result).toHaveLength(3);
|
|
149
|
+
// 1 batch call (failed) + 3 individual calls
|
|
150
|
+
expect(fetchSpy).toHaveBeenCalledTimes(4);
|
|
151
|
+
});
|
|
152
|
+
// ─── Skip on individual failure ─────────────────────
|
|
153
|
+
it('uses zero vector for failed individual text while preserving alignment', async () => {
|
|
154
|
+
const warnSpy = vi.fn();
|
|
155
|
+
// Batch fails
|
|
156
|
+
fetchSpy.mockRejectedValueOnce(new Error('batch failed'));
|
|
157
|
+
// First individual succeeds
|
|
158
|
+
fetchSpy.mockResolvedValueOnce(okResponse(embedResponse(1)));
|
|
159
|
+
// Second individual fails → zero vector
|
|
160
|
+
fetchSpy.mockRejectedValueOnce(new Error('oversized'));
|
|
161
|
+
const embedder = new OllamaEmbedder(undefined, undefined, undefined, warnSpy);
|
|
162
|
+
const result = await embedder.embed(['good text', 'bad text']);
|
|
163
|
+
// Both texts produce results — alignment preserved
|
|
164
|
+
expect(result).toHaveLength(2);
|
|
165
|
+
expect(result[0].every((v) => v === 1)).toBe(true);
|
|
166
|
+
expect(result[1].every((v) => v === 0)).toBe(true);
|
|
167
|
+
expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('Zero-vector fallback'));
|
|
168
|
+
});
|
|
169
|
+
it('logs summary warning with count of failed texts', async () => {
|
|
170
|
+
const warnSpy = vi.fn();
|
|
171
|
+
// Batch fails, then individual also fails
|
|
172
|
+
fetchSpy.mockRejectedValueOnce(new Error('batch failed'));
|
|
173
|
+
fetchSpy.mockRejectedValueOnce(new Error('individual failed'));
|
|
174
|
+
const embedder = new OllamaEmbedder('nomic-embed-text', 'http://localhost:11434', 512, warnSpy);
|
|
175
|
+
const result = await embedder.embed(['problematic text']);
|
|
176
|
+
// Zero vector preserves alignment
|
|
177
|
+
expect(result).toHaveLength(1);
|
|
178
|
+
expect(result[0].every((v) => v === 0)).toBe(true);
|
|
179
|
+
expect(result[0]).toHaveLength(512);
|
|
180
|
+
expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('1 chunk(s) skipped'));
|
|
181
|
+
});
|
|
182
|
+
// ─── Custom baseUrl ─────────────────────────────────
|
|
183
|
+
it('sends requests to a custom baseUrl', async () => {
|
|
184
|
+
fetchSpy.mockResolvedValueOnce(okResponse(embedResponse(1)));
|
|
185
|
+
const embedder = new OllamaEmbedder('nomic-embed-text', 'http://remote:9999');
|
|
186
|
+
await embedder.embed(['hello']);
|
|
187
|
+
const [url] = fetchSpy.mock.calls[0];
|
|
188
|
+
expect(url).toBe('http://remote:9999/api/embed');
|
|
189
|
+
});
|
|
190
|
+
// ─── Mixed batch success/failure ────────────────────
|
|
191
|
+
it('handles first batch success and second batch failure gracefully', async () => {
|
|
192
|
+
const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => { });
|
|
193
|
+
// 15 texts → 2 batches (10 + 5)
|
|
194
|
+
// First batch succeeds
|
|
195
|
+
fetchSpy.mockResolvedValueOnce(okResponse(embedResponse(10)));
|
|
196
|
+
// Second batch fails
|
|
197
|
+
fetchSpy.mockRejectedValueOnce(new Error('second batch failed'));
|
|
198
|
+
// Individual retries for the 5 texts in the second batch
|
|
199
|
+
fetchSpy.mockResolvedValueOnce(okResponse(embedResponse(1)));
|
|
200
|
+
fetchSpy.mockResolvedValueOnce(okResponse(embedResponse(1)));
|
|
201
|
+
fetchSpy.mockResolvedValueOnce(okResponse(embedResponse(1)));
|
|
202
|
+
fetchSpy.mockResolvedValueOnce(okResponse(embedResponse(1)));
|
|
203
|
+
fetchSpy.mockResolvedValueOnce(okResponse(embedResponse(1)));
|
|
204
|
+
const embedder = new OllamaEmbedder();
|
|
205
|
+
const texts = Array.from({ length: 15 }, (_, i) => `text ${i}`);
|
|
206
|
+
const result = await embedder.embed(texts);
|
|
207
|
+
expect(result).toHaveLength(15);
|
|
208
|
+
consoleSpy.mockRestore();
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
//# sourceMappingURL=ollama-embedder.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ollama-embedder.test.js","sourceRoot":"","sources":["../../src/embedders/ollama-embedder.test.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* - A recoveryHint telling the user exactly how to fix it
|
|
7
7
|
* - A code for programmatic handling
|
|
8
8
|
*/
|
|
9
|
-
export type TotemErrorCode = 'CONFIG_MISSING' | 'CONFIG_INVALID' | 'DATABASE_CORRUPT' | 'DATABASE_MISMATCH' | 'EMBEDDING_UNAVAILABLE' | 'ORCHESTRATOR_UNAVAILABLE' | 'COMPILE_FAILED' | 'PARSE_FAILED' | 'SYNC_FAILED' | 'GIT_FAILED' | 'NO_LESSONS' | 'NO_RULES' | 'SHIELD_FAILED' | 'LINT_LESSONS_FAILED' | 'MCP_ERROR';
|
|
9
|
+
export type TotemErrorCode = 'CONFIG_MISSING' | 'CONFIG_INVALID' | 'DATABASE_CORRUPT' | 'DATABASE_MISMATCH' | 'EMBEDDING_UNAVAILABLE' | 'ORCHESTRATOR_UNAVAILABLE' | 'COMPILE_FAILED' | 'PARSE_FAILED' | 'SYNC_FAILED' | 'GIT_FAILED' | 'NO_LESSONS' | 'NO_RULES' | 'SHIELD_FAILED' | 'LINT_LESSONS_FAILED' | 'DRIFT_FAILED' | 'TEST_FAILED' | 'MCP_ERROR';
|
|
10
10
|
export declare class TotemError extends Error {
|
|
11
11
|
readonly code: TotemErrorCode;
|
|
12
12
|
readonly recoveryHint: string;
|
package/dist/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,cAAc,GACtB,gBAAgB,GAChB,gBAAgB,GAChB,kBAAkB,GAClB,mBAAmB,GACnB,uBAAuB,GACvB,0BAA0B,GAC1B,gBAAgB,GAChB,cAAc,GACd,aAAa,GACb,YAAY,GACZ,YAAY,GACZ,UAAU,GACV,eAAe,GACf,qBAAqB,GACrB,WAAW,CAAC;AAEhB,qBAAa,UAAW,SAAQ,KAAK;IACnC,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;gBAElB,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;CAMxE;AAED,qBAAa,gBAAiB,SAAQ,UAAU;gBAE5C,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,IAAI,GAAE,gBAAgB,GAAG,gBAAmC;CAK/D;AAED,qBAAa,kBAAmB,SAAQ,UAAU;gBAE9C,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,IAAI,GAAE,kBAAkB,GAAG,mBAAwC;CAKtE;AAED,qBAAa,iBAAkB,SAAQ,UAAU;gBACnC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;CAIlD;AAED,qBAAa,eAAgB,SAAQ,UAAU;gBACjC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;CAIlD;AAED,qBAAa,sBAAuB,SAAQ,UAAU;gBACxC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;CAIlD;AAED,qBAAa,aAAc,SAAQ,UAAU;gBAC/B,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;CAIlD;AAID,qEAAqE;AACrE,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAEpD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,KAAK,CAGpF"}
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,cAAc,GACtB,gBAAgB,GAChB,gBAAgB,GAChB,kBAAkB,GAClB,mBAAmB,GACnB,uBAAuB,GACvB,0BAA0B,GAC1B,gBAAgB,GAChB,cAAc,GACd,aAAa,GACb,YAAY,GACZ,YAAY,GACZ,UAAU,GACV,eAAe,GACf,qBAAqB,GACrB,cAAc,GACd,aAAa,GACb,WAAW,CAAC;AAEhB,qBAAa,UAAW,SAAQ,KAAK;IACnC,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;gBAElB,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;CAMxE;AAED,qBAAa,gBAAiB,SAAQ,UAAU;gBAE5C,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,IAAI,GAAE,gBAAgB,GAAG,gBAAmC;CAK/D;AAED,qBAAa,kBAAmB,SAAQ,UAAU;gBAE9C,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,IAAI,GAAE,kBAAkB,GAAG,mBAAwC;CAKtE;AAED,qBAAa,iBAAkB,SAAQ,UAAU;gBACnC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;CAIlD;AAED,qBAAa,eAAgB,SAAQ,UAAU;gBACjC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;CAIlD;AAED,qBAAa,sBAAuB,SAAQ,UAAU;gBACxC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;CAIlD;AAED,qBAAa,aAAc,SAAQ,UAAU;gBAC/B,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;CAIlD;AAID,qEAAqE;AACrE,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAEpD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,KAAK,CAGpF"}
|
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAqBH,MAAM,OAAO,UAAW,SAAQ,KAAK;IAC1B,IAAI,CAAiB;IACrB,YAAY,CAAS;IAE9B,YAAY,IAAoB,EAAE,OAAe,EAAE,YAAoB;QACrE,KAAK,CAAC,iBAAiB,OAAO,EAAE,CAAC,CAAC;QAClC,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;QACzB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACnC,CAAC;CACF;AAED,MAAM,OAAO,gBAAiB,SAAQ,UAAU;IAC9C,YACE,OAAe,EACf,YAAoB,EACpB,OAA4C,gBAAgB;QAE5D,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CACF;AAED,MAAM,OAAO,kBAAmB,SAAQ,UAAU;IAChD,YACE,OAAe,EACf,YAAoB,EACpB,OAAiD,kBAAkB;QAEnE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AAED,MAAM,OAAO,iBAAkB,SAAQ,UAAU;IAC/C,YAAY,OAAe,EAAE,YAAoB;QAC/C,KAAK,CAAC,gBAAgB,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;QAC/C,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IAClC,CAAC;CACF;AAED,MAAM,OAAO,eAAgB,SAAQ,UAAU;IAC7C,YAAY,OAAe,EAAE,YAAoB;QAC/C,KAAK,CAAC,cAAc,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;QAC7C,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAED,MAAM,OAAO,sBAAuB,SAAQ,UAAU;IACpD,YAAY,OAAe,EAAE,YAAoB;QAC/C,KAAK,CAAC,0BAA0B,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;QACzD,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACvC,CAAC;CACF;AAED,MAAM,OAAO,aAAc,SAAQ,UAAU;IAC3C,YAAY,OAAe,EAAE,YAAoB;QAC/C,KAAK,CAAC,YAAY,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;QAC3C,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AAED,uDAAuD;AAEvD,qEAAqE;AACrE,MAAM,UAAU,eAAe,CAAC,GAAY;IAC1C,OAAO,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAC1D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAa,EAAE,GAAY,EAAE,IAAY;IAC3E,IAAI,GAAG,YAAY,eAAe;QAAE,MAAM,GAAG,CAAC;IAC9C,MAAM,IAAI,eAAe,CAAC,GAAG,KAAK,KAAK,eAAe,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,0EAA0E;AAClJ,CAAC"}
|
package/dist/lock.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../src/lock.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../src/lock.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAiEH;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAC7B,OAAO,CAAC,MAAM,IAAI,CAAC,CAwFrB;AAED;;;GAGG;AACH,wBAAsB,QAAQ,CAAC,CAAC,EAC9B,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAC7B,OAAO,CAAC,CAAC,CAAC,CA6CZ"}
|
package/dist/lock.js
CHANGED
|
@@ -43,7 +43,9 @@ function readLock(filePath) {
|
|
|
43
43
|
if (data !== null &&
|
|
44
44
|
typeof data === 'object' &&
|
|
45
45
|
typeof data.pid === 'number' &&
|
|
46
|
-
|
|
46
|
+
Number.isInteger(data.pid) &&
|
|
47
|
+
typeof data.timestamp === 'number' &&
|
|
48
|
+
data.timestamp > 0) {
|
|
47
49
|
return data;
|
|
48
50
|
}
|
|
49
51
|
return null;
|
package/dist/lock.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lock.js","sourceRoot":"","sources":["../src/lock.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,SAAS,GAAG,WAAW,CAAC;AAC9B,MAAM,kBAAkB,GAAG,OAAO,CAAC,CAAC,kDAAkD;AACtF,MAAM,WAAW,GAAG,EAAE,CAAC;AACvB,MAAM,aAAa,GAAG,GAAG,CAAC;AAO1B;;;GAGG;AACH,SAAS,cAAc,CAAC,GAAW;IACjC,IAAI,CAAC;QACH,qEAAqE;QACrE,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,2CAA2C;QACjE,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAQ,GAA6B,CAAC,IAAI,KAAK,OAAO,CAAC;IACzD,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,QAAgB;IAChC,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;AACxC,CAAC;AAED,SAAS,OAAO,CAAC,IAAc;IAC7B,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,GAAG,kBAAkB,CAAC;AAC1D,CAAC;AAED,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAE/B,SAAS,YAAY,CAAC,OAAe;IACnC,OAAO,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,QAAQ,CAAC,QAAgB;IAChC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC/C,MAAM,IAAI,GAAY,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACtC,IACE,IAAI,KAAK,IAAI;YACb,OAAO,IAAI,KAAK,QAAQ;YACxB,OAAQ,IAAiB,CAAC,GAAG,KAAK,QAAQ;YAC1C,OAAQ,IAAiB,CAAC,SAAS,KAAK,QAAQ,
|
|
1
|
+
{"version":3,"file":"lock.js","sourceRoot":"","sources":["../src/lock.ts"],"names":[],"mappings":"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"}
|
package/dist/rule-engine.js
CHANGED
|
@@ -159,13 +159,11 @@ export async function applyAstRulesToAdditions(rules, additions, cwd, onRuleEven
|
|
|
159
159
|
const ext = path.extname(file);
|
|
160
160
|
if (!extensionToLanguage(ext))
|
|
161
161
|
continue;
|
|
162
|
-
// Collect added line numbers
|
|
162
|
+
// Collect added line numbers (suppression is checked post-match so metrics fire)
|
|
163
163
|
const addedLineNumbers = [];
|
|
164
164
|
for (const addition of fileAdditions) {
|
|
165
165
|
if (addition.astContext && addition.astContext !== 'code')
|
|
166
166
|
continue;
|
|
167
|
-
if (isSuppressed(addition.line, addition.precedingLine))
|
|
168
|
-
continue;
|
|
169
167
|
addedLineNumbers.push(addition.lineNumber);
|
|
170
168
|
}
|
|
171
169
|
if (addedLineNumbers.length === 0)
|
|
@@ -186,8 +184,9 @@ export async function applyAstRulesToAdditions(rules, additions, cwd, onRuleEven
|
|
|
186
184
|
}));
|
|
187
185
|
const batchResults = await matchAstQueriesBatch(file, queries, cwd);
|
|
188
186
|
// Map results back to violations
|
|
189
|
-
for (
|
|
190
|
-
const
|
|
187
|
+
for (let i = 0; i < applicableTreeSitter.length; i++) {
|
|
188
|
+
const rule = applicableTreeSitter[i];
|
|
189
|
+
const matches = batchResults[i] ?? [];
|
|
191
190
|
for (const match of matches) {
|
|
192
191
|
const addition = fileAdditions.find((a) => a.lineNumber === match.lineNumber);
|
|
193
192
|
if (addition && isSuppressed(addition.line, addition.precedingLine)) {
|