@mmnto/totem 1.4.1 → 1.4.3

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 (67) hide show
  1. package/dist/ast-query.d.ts +2 -1
  2. package/dist/ast-query.d.ts.map +1 -1
  3. package/dist/ast-query.js +6 -15
  4. package/dist/ast-query.js.map +1 -1
  5. package/dist/ast-query.test.js +31 -1
  6. package/dist/ast-query.test.js.map +1 -1
  7. package/dist/chunkers/chunker-utils.d.ts +4 -0
  8. package/dist/chunkers/chunker-utils.d.ts.map +1 -0
  9. package/dist/chunkers/chunker-utils.js +13 -0
  10. package/dist/chunkers/chunker-utils.js.map +1 -0
  11. package/dist/chunkers/markdown-chunker.d.ts.map +1 -1
  12. package/dist/chunkers/markdown-chunker.js +1 -11
  13. package/dist/chunkers/markdown-chunker.js.map +1 -1
  14. package/dist/chunkers/session-log-chunker.d.ts.map +1 -1
  15. package/dist/chunkers/session-log-chunker.js +1 -12
  16. package/dist/chunkers/session-log-chunker.js.map +1 -1
  17. package/dist/chunkers/session-log-chunker.test.d.ts +2 -0
  18. package/dist/chunkers/session-log-chunker.test.d.ts.map +1 -0
  19. package/dist/chunkers/session-log-chunker.test.js +235 -0
  20. package/dist/chunkers/session-log-chunker.test.js.map +1 -0
  21. package/dist/compile-lesson.d.ts +52 -0
  22. package/dist/compile-lesson.d.ts.map +1 -0
  23. package/dist/compile-lesson.js +144 -0
  24. package/dist/compile-lesson.js.map +1 -0
  25. package/dist/compile-lesson.test.d.ts +2 -0
  26. package/dist/compile-lesson.test.d.ts.map +1 -0
  27. package/dist/compile-lesson.test.js +244 -0
  28. package/dist/compile-lesson.test.js.map +1 -0
  29. package/dist/embedders/gemini-embedder.test.d.ts +2 -0
  30. package/dist/embedders/gemini-embedder.test.d.ts.map +1 -0
  31. package/dist/embedders/gemini-embedder.test.js +158 -0
  32. package/dist/embedders/gemini-embedder.test.js.map +1 -0
  33. package/dist/embedders/ollama-embedder.d.ts +2 -1
  34. package/dist/embedders/ollama-embedder.d.ts.map +1 -1
  35. package/dist/embedders/ollama-embedder.js +11 -3
  36. package/dist/embedders/ollama-embedder.js.map +1 -1
  37. package/dist/embedders/ollama-embedder.test.d.ts +2 -0
  38. package/dist/embedders/ollama-embedder.test.d.ts.map +1 -0
  39. package/dist/embedders/ollama-embedder.test.js +211 -0
  40. package/dist/embedders/ollama-embedder.test.js.map +1 -0
  41. package/dist/errors.d.ts +1 -1
  42. package/dist/errors.d.ts.map +1 -1
  43. package/dist/errors.js.map +1 -1
  44. package/dist/index.d.ts +2 -0
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +1 -0
  47. package/dist/index.js.map +1 -1
  48. package/dist/lock.d.ts.map +1 -1
  49. package/dist/lock.js +3 -1
  50. package/dist/lock.js.map +1 -1
  51. package/dist/rule-engine.js +4 -5
  52. package/dist/rule-engine.js.map +1 -1
  53. package/dist/rule-engine.test.js +46 -0
  54. package/dist/rule-engine.test.js.map +1 -1
  55. package/dist/rule-metrics.test.d.ts +2 -0
  56. package/dist/rule-metrics.test.d.ts.map +1 -0
  57. package/dist/rule-metrics.test.js +205 -0
  58. package/dist/rule-metrics.test.js.map +1 -0
  59. package/dist/store/lance-search.test.d.ts +2 -0
  60. package/dist/store/lance-search.test.d.ts.map +1 -0
  61. package/dist/store/lance-search.test.js +249 -0
  62. package/dist/store/lance-search.test.js.map +1 -0
  63. package/dist/suspicious-lesson.test.d.ts +2 -0
  64. package/dist/suspicious-lesson.test.d.ts.map +1 -0
  65. package/dist/suspicious-lesson.test.js +184 -0
  66. package/dist/suspicious-lesson.test.js.map +1 -0
  67. package/package.json +1 -1
@@ -0,0 +1,144 @@
1
+ import { engineFields, sanitizeFileGlobs, validateRegex } from './compiler.js';
2
+ import { extractManualPattern } from './lesson-pattern.js';
3
+ // ─── Rule builder (pure, no I/O) ────────────────────
4
+ /**
5
+ * Build a CompiledRule from parsed compiler output.
6
+ * Returns { rule, rejectReason } so callers can report why a rule was rejected.
7
+ */
8
+ export function buildCompiledRule(parsed, lesson, existingByHash) {
9
+ if (!parsed.compilable)
10
+ return { rule: null };
11
+ const severity = parsed.severity ?? 'warning';
12
+ const engine = parsed.engine ?? 'regex';
13
+ const now = new Date().toISOString();
14
+ const existing = existingByHash.get(lesson.hash);
15
+ const sanitizedGlobs = parsed.fileGlobs ? sanitizeFileGlobs(parsed.fileGlobs) : undefined;
16
+ const globsObj = sanitizedGlobs && sanitizedGlobs.length > 0 ? { fileGlobs: sanitizedGlobs } : {};
17
+ if (engine === 'ast-grep') {
18
+ if (!parsed.astGrepPattern || !parsed.message) {
19
+ return { rule: null, rejectReason: 'Missing astGrepPattern or message' };
20
+ }
21
+ return {
22
+ rule: {
23
+ lessonHash: lesson.hash,
24
+ lessonHeading: lesson.heading,
25
+ message: parsed.message,
26
+ engine: 'ast-grep',
27
+ severity,
28
+ ...engineFields('ast-grep', parsed.astGrepPattern),
29
+ compiledAt: now,
30
+ createdAt: existing?.createdAt ?? now,
31
+ ...globsObj,
32
+ },
33
+ };
34
+ }
35
+ if (engine === 'ast') {
36
+ if (!parsed.astQuery || !parsed.message) {
37
+ return { rule: null, rejectReason: 'Missing astQuery or message' };
38
+ }
39
+ return {
40
+ rule: {
41
+ lessonHash: lesson.hash,
42
+ lessonHeading: lesson.heading,
43
+ message: parsed.message,
44
+ engine: 'ast',
45
+ severity,
46
+ ...engineFields('ast', parsed.astQuery),
47
+ compiledAt: now,
48
+ createdAt: existing?.createdAt ?? now,
49
+ ...globsObj,
50
+ },
51
+ };
52
+ }
53
+ // Regex engine (default)
54
+ if (!parsed.pattern || !parsed.message) {
55
+ return { rule: null, rejectReason: 'Missing pattern or message' };
56
+ }
57
+ const validation = validateRegex(parsed.pattern);
58
+ if (!validation.valid) {
59
+ return { rule: null, rejectReason: `Rejected regex: ${validation.reason}` };
60
+ }
61
+ return {
62
+ rule: {
63
+ lessonHash: lesson.hash,
64
+ lessonHeading: lesson.heading,
65
+ message: parsed.message,
66
+ engine: 'regex',
67
+ severity,
68
+ ...engineFields('regex', parsed.pattern),
69
+ compiledAt: now,
70
+ createdAt: existing?.createdAt ?? now,
71
+ ...globsObj,
72
+ },
73
+ };
74
+ }
75
+ /**
76
+ * Build a CompiledRule from a lesson's manually specified pattern.
77
+ * Returns { rule, rejectReason } so callers can report why a pattern was rejected.
78
+ */
79
+ export function buildManualRule(lesson, existingByHash) {
80
+ const manual = extractManualPattern(lesson.body);
81
+ if (!manual)
82
+ return { rule: null };
83
+ if (manual.engine === 'regex') {
84
+ const validation = validateRegex(manual.pattern);
85
+ if (!validation.valid) {
86
+ return { rule: null, rejectReason: `Manual pattern rejected: ${validation.reason}` };
87
+ }
88
+ }
89
+ const now = new Date().toISOString();
90
+ const existing = existingByHash.get(lesson.hash);
91
+ const sanitizedGlobs = manual.fileGlobs ? sanitizeFileGlobs(manual.fileGlobs) : undefined;
92
+ return {
93
+ rule: {
94
+ lessonHash: lesson.hash,
95
+ lessonHeading: lesson.heading,
96
+ message: lesson.heading,
97
+ engine: manual.engine,
98
+ severity: manual.severity,
99
+ ...engineFields(manual.engine, manual.pattern),
100
+ compiledAt: now,
101
+ createdAt: existing?.createdAt ?? now,
102
+ ...(sanitizedGlobs && sanitizedGlobs.length > 0 ? { fileGlobs: sanitizedGlobs } : {}),
103
+ },
104
+ };
105
+ }
106
+ // ─── Single-lesson compilation ──────────────────────
107
+ /**
108
+ * Compile a single lesson into a rule.
109
+ * Handles both manual patterns (zero LLM) and LLM-compiled patterns.
110
+ * Pure business logic — no UI, no I/O, no process.exit.
111
+ */
112
+ export async function compileLesson(lesson, compilerPrompt, deps) {
113
+ const { parseCompilerResponse, runOrchestrator, existingByHash, callbacks } = deps;
114
+ // ── Pipeline 1: Manual pattern (zero LLM) ────────
115
+ const manualResult = buildManualRule(lesson, existingByHash);
116
+ if (manualResult.rule)
117
+ return { status: 'compiled', rule: manualResult.rule };
118
+ if (manualResult.rejectReason) {
119
+ callbacks?.onWarn?.(lesson.heading, manualResult.rejectReason);
120
+ return { status: 'failed' };
121
+ }
122
+ // manualResult.rule === null && no rejectReason → no manual pattern, proceed to LLM
123
+ // ── Pipeline 2: LLM compilation ──────────────────
124
+ const prompt = `${compilerPrompt}\n\n## Lesson to Compile\n\nHeading: ${lesson.heading}\n\n${lesson.body}`;
125
+ const response = await runOrchestrator(prompt);
126
+ if (response == null)
127
+ return { status: 'noop' };
128
+ const parsed = parseCompilerResponse(response);
129
+ if (!parsed) {
130
+ callbacks?.onWarn?.(lesson.heading, 'Failed to parse LLM response — skipping');
131
+ return { status: 'failed' };
132
+ }
133
+ if (!parsed.compilable) {
134
+ callbacks?.onDim?.(lesson.heading, 'Not compilable (conceptual/architectural) — skipping');
135
+ return { status: 'skipped', hash: lesson.hash };
136
+ }
137
+ const ruleResult = buildCompiledRule(parsed, lesson, existingByHash);
138
+ if (!ruleResult.rule) {
139
+ callbacks?.onWarn?.(lesson.heading, `${ruleResult.rejectReason ?? 'Unknown error'} — skipping`);
140
+ return { status: 'failed' };
141
+ }
142
+ return { status: 'compiled', rule: ruleResult.rule };
143
+ }
144
+ //# sourceMappingURL=compile-lesson.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile-lesson.js","sourceRoot":"","sources":["../src/compile-lesson.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=compile-lesson.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile-lesson.test.d.ts","sourceRoot":"","sources":["../src/compile-lesson.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,244 @@
1
+ import { describe, expect, it, vi } from 'vitest';
2
+ import { buildCompiledRule, buildManualRule, compileLesson, } from './compile-lesson.js';
3
+ // ─── Helpers ────────────────────────────────────────
4
+ const lesson = {
5
+ index: 0,
6
+ heading: 'Use err not error in catch blocks',
7
+ body: 'Always use `err` as the variable name in catch blocks.',
8
+ hash: 'abc123',
9
+ };
10
+ const manualLesson = {
11
+ index: 1,
12
+ heading: 'No console.log in production',
13
+ body: '**Pattern:** `console\\.log`\n**Engine:** regex\n**Severity:** warning\n**Scope:** **/*.ts',
14
+ hash: 'manual456',
15
+ };
16
+ const existingByHash = new Map();
17
+ // ─── buildCompiledRule ──────────────────────────────
18
+ describe('buildCompiledRule', () => {
19
+ it('builds a regex rule from valid compiler output', () => {
20
+ const parsed = {
21
+ compilable: true,
22
+ pattern: 'console\\.log',
23
+ message: 'No console.log',
24
+ engine: 'regex',
25
+ severity: 'warning',
26
+ };
27
+ const result = buildCompiledRule(parsed, lesson, existingByHash);
28
+ expect(result.rule).not.toBeNull();
29
+ expect(result.rule.engine).toBe('regex');
30
+ expect(result.rule.pattern).toBe('console\\.log');
31
+ expect(result.rule.message).toBe('No console.log');
32
+ expect(result.rule.lessonHash).toBe('abc123');
33
+ expect(result.rule.severity).toBe('warning');
34
+ });
35
+ it('builds an ast-grep rule', () => {
36
+ const parsed = {
37
+ compilable: true,
38
+ message: 'Use err in catch',
39
+ engine: 'ast-grep',
40
+ astGrepPattern: 'catch($ERR) { $$$ }',
41
+ };
42
+ const result = buildCompiledRule(parsed, lesson, existingByHash);
43
+ expect(result.rule).not.toBeNull();
44
+ expect(result.rule.engine).toBe('ast-grep');
45
+ });
46
+ it('builds an ast rule', () => {
47
+ const parsed = {
48
+ compilable: true,
49
+ message: 'AST check',
50
+ engine: 'ast',
51
+ astQuery: '(catch_clause parameter: (identifier) @name)',
52
+ };
53
+ const result = buildCompiledRule(parsed, lesson, existingByHash);
54
+ expect(result.rule).not.toBeNull();
55
+ expect(result.rule.engine).toBe('ast');
56
+ });
57
+ it('returns null rule for non-compilable output', () => {
58
+ const parsed = { compilable: false };
59
+ expect(buildCompiledRule(parsed, lesson, existingByHash).rule).toBeNull();
60
+ });
61
+ it('returns rejectReason for regex with missing pattern', () => {
62
+ const parsed = { compilable: true, message: 'test', engine: 'regex' };
63
+ const result = buildCompiledRule(parsed, lesson, existingByHash);
64
+ expect(result.rule).toBeNull();
65
+ expect(result.rejectReason).toContain('Missing');
66
+ });
67
+ it('returns rejectReason for invalid regex', () => {
68
+ const parsed = {
69
+ compilable: true,
70
+ pattern: '(unclosed',
71
+ message: 'test',
72
+ engine: 'regex',
73
+ };
74
+ const result = buildCompiledRule(parsed, lesson, existingByHash);
75
+ expect(result.rule).toBeNull();
76
+ expect(result.rejectReason).toContain('Rejected regex');
77
+ });
78
+ it('returns rejectReason for ast-grep with missing pattern', () => {
79
+ const parsed = { compilable: true, message: 'test', engine: 'ast-grep' };
80
+ const result = buildCompiledRule(parsed, lesson, existingByHash);
81
+ expect(result.rule).toBeNull();
82
+ expect(result.rejectReason).toContain('astGrepPattern');
83
+ });
84
+ it('returns rejectReason for ast-grep with missing message', () => {
85
+ const parsed = {
86
+ compilable: true,
87
+ engine: 'ast-grep',
88
+ astGrepPattern: 'catch($ERR) { $$$ }',
89
+ };
90
+ const result = buildCompiledRule(parsed, lesson, existingByHash);
91
+ expect(result.rule).toBeNull();
92
+ expect(result.rejectReason).toContain('message');
93
+ });
94
+ it('returns rejectReason for ast with missing query', () => {
95
+ const parsed = { compilable: true, message: 'test', engine: 'ast' };
96
+ const result = buildCompiledRule(parsed, lesson, existingByHash);
97
+ expect(result.rule).toBeNull();
98
+ expect(result.rejectReason).toContain('astQuery');
99
+ });
100
+ it('returns rejectReason for ast with missing message', () => {
101
+ const parsed = {
102
+ compilable: true,
103
+ engine: 'ast',
104
+ astQuery: '(catch_clause)',
105
+ };
106
+ const result = buildCompiledRule(parsed, lesson, existingByHash);
107
+ expect(result.rule).toBeNull();
108
+ expect(result.rejectReason).toContain('message');
109
+ });
110
+ it('preserves createdAt from existing rule', () => {
111
+ const existing = new Map();
112
+ existing.set('abc123', {
113
+ lessonHash: 'abc123',
114
+ lessonHeading: 'old',
115
+ pattern: 'old',
116
+ message: 'old',
117
+ engine: 'regex',
118
+ compiledAt: '2026-01-01T00:00:00.000Z',
119
+ createdAt: '2025-01-01T00:00:00.000Z',
120
+ });
121
+ const parsed = {
122
+ compilable: true,
123
+ pattern: 'console\\.log',
124
+ message: 'No console.log',
125
+ engine: 'regex',
126
+ };
127
+ const result = buildCompiledRule(parsed, lesson, existing);
128
+ expect(result.rule.createdAt).toBe('2025-01-01T00:00:00.000Z');
129
+ });
130
+ it('includes sanitized fileGlobs when provided', () => {
131
+ const parsed = {
132
+ compilable: true,
133
+ pattern: 'test',
134
+ message: 'test',
135
+ engine: 'regex',
136
+ fileGlobs: ['**/*.ts'],
137
+ };
138
+ const result = buildCompiledRule(parsed, lesson, existingByHash);
139
+ expect(result.rule.fileGlobs).toEqual(['**/*.ts']);
140
+ });
141
+ it('defaults severity to warning', () => {
142
+ const parsed = {
143
+ compilable: true,
144
+ pattern: 'test',
145
+ message: 'test',
146
+ };
147
+ const result = buildCompiledRule(parsed, lesson, existingByHash);
148
+ expect(result.rule.severity).toBe('warning');
149
+ });
150
+ });
151
+ // ─── buildManualRule ────────────────────────────────
152
+ describe('buildManualRule', () => {
153
+ it('returns null rule for lessons without manual patterns', () => {
154
+ const result = buildManualRule(lesson, existingByHash);
155
+ expect(result.rule).toBeNull();
156
+ expect(result.rejectReason).toBeUndefined();
157
+ });
158
+ it('builds a rule from a manual pattern lesson', () => {
159
+ const result = buildManualRule(manualLesson, existingByHash);
160
+ expect(result.rule).not.toBeNull();
161
+ expect(result.rule.message).toBe(manualLesson.heading);
162
+ expect(result.rule.engine).toBe('regex');
163
+ });
164
+ it('returns rejectReason for invalid manual regex', () => {
165
+ const invalidLesson = {
166
+ index: 2,
167
+ heading: 'Bad regex',
168
+ body: '**Pattern:** `(unclosed`\n**Engine:** regex\n**Severity:** warning',
169
+ hash: 'bad789',
170
+ };
171
+ const result = buildManualRule(invalidLesson, existingByHash);
172
+ expect(result.rule).toBeNull();
173
+ expect(result.rejectReason).toContain('rejected');
174
+ });
175
+ });
176
+ // ─── compileLesson ──────────────────────────────────
177
+ describe('compileLesson', () => {
178
+ const makeDeps = (response) => ({
179
+ parseCompilerResponse: vi.fn().mockReturnValue(response
180
+ ? {
181
+ compilable: true,
182
+ pattern: 'console\\.log',
183
+ message: 'No console.log',
184
+ engine: 'regex',
185
+ }
186
+ : null),
187
+ runOrchestrator: vi.fn().mockResolvedValue(response),
188
+ existingByHash: new Map(),
189
+ callbacks: {
190
+ onWarn: vi.fn(),
191
+ onDim: vi.fn(),
192
+ },
193
+ });
194
+ it('compiles via LLM when no manual pattern', async () => {
195
+ const deps = makeDeps('{"compilable": true}');
196
+ const result = await compileLesson(lesson, 'system prompt', deps);
197
+ expect(result.status).toBe('compiled');
198
+ expect(deps.runOrchestrator).toHaveBeenCalled();
199
+ });
200
+ it('uses manual pattern when available (skips LLM)', async () => {
201
+ const deps = makeDeps('should not be called');
202
+ const result = await compileLesson(manualLesson, 'system prompt', deps);
203
+ expect(result.status).toBe('compiled');
204
+ expect(deps.runOrchestrator).not.toHaveBeenCalled();
205
+ });
206
+ it('returns noop when orchestrator returns null', async () => {
207
+ const deps = makeDeps(undefined);
208
+ const result = await compileLesson(lesson, 'system prompt', deps);
209
+ expect(result.status).toBe('noop');
210
+ });
211
+ it('returns failed when parseCompilerResponse returns null', async () => {
212
+ const deps = {
213
+ parseCompilerResponse: vi.fn().mockReturnValue(null),
214
+ runOrchestrator: vi.fn().mockResolvedValue('bad response'),
215
+ existingByHash: new Map(),
216
+ callbacks: { onWarn: vi.fn(), onDim: vi.fn() },
217
+ };
218
+ const result = await compileLesson(lesson, 'system prompt', deps);
219
+ expect(result.status).toBe('failed');
220
+ expect(deps.callbacks.onWarn).toHaveBeenCalled();
221
+ });
222
+ it('returns skipped for non-compilable lessons', async () => {
223
+ const deps = {
224
+ parseCompilerResponse: vi.fn().mockReturnValue({ compilable: false }),
225
+ runOrchestrator: vi.fn().mockResolvedValue('response'),
226
+ existingByHash: new Map(),
227
+ callbacks: { onWarn: vi.fn(), onDim: vi.fn() },
228
+ };
229
+ const result = await compileLesson(lesson, 'system prompt', deps);
230
+ expect(result.status).toBe('skipped');
231
+ expect(deps.callbacks.onDim).toHaveBeenCalled();
232
+ });
233
+ it('calls onWarn callback on failures', async () => {
234
+ const deps = {
235
+ parseCompilerResponse: vi.fn().mockReturnValue(null),
236
+ runOrchestrator: vi.fn().mockResolvedValue('bad'),
237
+ existingByHash: new Map(),
238
+ callbacks: { onWarn: vi.fn(), onDim: vi.fn() },
239
+ };
240
+ await compileLesson(lesson, 'system prompt', deps);
241
+ expect(deps.callbacks.onWarn).toHaveBeenCalledWith(lesson.heading, expect.stringContaining('parse'));
242
+ });
243
+ });
244
+ //# sourceMappingURL=compile-lesson.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile-lesson.test.js","sourceRoot":"","sources":["../src/compile-lesson.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAElD,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,aAAa,GAGd,MAAM,qBAAqB,CAAC;AAG7B,uDAAuD;AAEvD,MAAM,MAAM,GAAgB;IAC1B,KAAK,EAAE,CAAC;IACR,OAAO,EAAE,mCAAmC;IAC5C,IAAI,EAAE,wDAAwD;IAC9D,IAAI,EAAE,QAAQ;CACf,CAAC;AAEF,MAAM,YAAY,GAAgB;IAChC,KAAK,EAAE,CAAC;IACR,OAAO,EAAE,8BAA8B;IACvC,IAAI,EAAE,4FAA4F;IAClG,IAAI,EAAE,WAAW;CAClB,CAAC;AAEF,MAAM,cAAc,GAAG,IAAI,GAAG,EAAwB,CAAC;AAEvD,uDAAuD;AAEvD,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,MAAM,MAAM,GAAmB;YAC7B,UAAU,EAAE,IAAI;YAChB,OAAO,EAAE,eAAe;YACxB,OAAO,EAAE,gBAAgB;YACzB,MAAM,EAAE,OAAO;YACf,QAAQ,EAAE,SAAS;SACpB,CAAC;QACF,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;QACjE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QACnC,MAAM,CAAC,MAAM,CAAC,IAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,IAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACnD,MAAM,CAAC,MAAM,CAAC,IAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QACpD,MAAM,CAAC,MAAM,CAAC,IAAK,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC/C,MAAM,CAAC,MAAM,CAAC,IAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACjC,MAAM,MAAM,GAAmB;YAC7B,UAAU,EAAE,IAAI;YAChB,OAAO,EAAE,kBAAkB;YAC3B,MAAM,EAAE,UAAU;YAClB,cAAc,EAAE,qBAAqB;SACtC,CAAC;QACF,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;QACjE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QACnC,MAAM,CAAC,MAAM,CAAC,IAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oBAAoB,EAAE,GAAG,EAAE;QAC5B,MAAM,MAAM,GAAmB;YAC7B,UAAU,EAAE,IAAI;YAChB,OAAO,EAAE,WAAW;YACpB,MAAM,EAAE,KAAK;YACb,QAAQ,EAAE,8CAA8C;SACzD,CAAC;QACF,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;QACjE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QACnC,MAAM,CAAC,MAAM,CAAC,IAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,MAAM,GAAmB,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;QACrD,MAAM,CAAC,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC5E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,MAAM,GAAmB,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;QACtF,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;QACjE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC/B,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,MAAM,GAAmB;YAC7B,UAAU,EAAE,IAAI;YAChB,OAAO,EAAE,WAAW;YACpB,OAAO,EAAE,MAAM;YACf,MAAM,EAAE,OAAO;SAChB,CAAC;QACF,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;QACjE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC/B,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,MAAM,MAAM,GAAmB,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;QACzF,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;QACjE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC/B,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,MAAM,MAAM,GAAmB;YAC7B,UAAU,EAAE,IAAI;YAChB,MAAM,EAAE,UAAU;YAClB,cAAc,EAAE,qBAAqB;SACtC,CAAC;QACF,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;QACjE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC/B,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,MAAM,GAAmB,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QACpF,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;QACjE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC/B,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,MAAM,MAAM,GAAmB;YAC7B,UAAU,EAAE,IAAI;YAChB,MAAM,EAAE,KAAK;YACb,QAAQ,EAAE,gBAAgB;SAC3B,CAAC;QACF,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;QACjE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC/B,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAwB,CAAC;QACjD,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE;YACrB,UAAU,EAAE,QAAQ;YACpB,aAAa,EAAE,KAAK;YACpB,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,OAAO;YACf,UAAU,EAAE,0BAA0B;YACtC,SAAS,EAAE,0BAA0B;SACtC,CAAC,CAAC;QACH,MAAM,MAAM,GAAmB;YAC7B,UAAU,EAAE,IAAI;YAChB,OAAO,EAAE,eAAe;YACxB,OAAO,EAAE,gBAAgB;YACzB,MAAM,EAAE,OAAO;SAChB,CAAC;QACF,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QAC3D,MAAM,CAAC,MAAM,CAAC,IAAK,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,MAAM,GAAmB;YAC7B,UAAU,EAAE,IAAI;YAChB,OAAO,EAAE,MAAM;YACf,OAAO,EAAE,MAAM;YACf,MAAM,EAAE,OAAO;YACf,SAAS,EAAE,CAAC,SAAS,CAAC;SACvB,CAAC;QACF,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;QACjE,MAAM,CAAC,MAAM,CAAC,IAAK,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;QACtC,MAAM,MAAM,GAAmB;YAC7B,UAAU,EAAE,IAAI;YAChB,OAAO,EAAE,MAAM;YACf,OAAO,EAAE,MAAM;SAChB,CAAC;QACF,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;QACjE,MAAM,CAAC,MAAM,CAAC,IAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,uDAAuD;AAEvD,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,MAAM,GAAG,eAAe,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QACvD,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC/B,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,aAAa,EAAE,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,MAAM,GAAG,eAAe,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;QAC7D,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QACnC,MAAM,CAAC,MAAM,CAAC,IAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QACxD,MAAM,CAAC,MAAM,CAAC,IAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,aAAa,GAAgB;YACjC,KAAK,EAAE,CAAC;YACR,OAAO,EAAE,WAAW;YACpB,IAAI,EAAE,oEAAoE;YAC1E,IAAI,EAAE,QAAQ;SACf,CAAC;QACF,MAAM,MAAM,GAAG,eAAe,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC;QAC9D,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC/B,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,uDAAuD;AAEvD,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,MAAM,QAAQ,GAAG,CAAC,QAA4B,EAAqB,EAAE,CAAC,CAAC;QACrE,qBAAqB,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,eAAe,CAC5C,QAAQ;YACN,CAAC,CAAC;gBACE,UAAU,EAAE,IAAI;gBAChB,OAAO,EAAE,eAAe;gBACxB,OAAO,EAAE,gBAAgB;gBACzB,MAAM,EAAE,OAAgB;aACzB;YACH,CAAC,CAAC,IAAI,CACT;QACD,eAAe,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,QAAQ,CAAC;QACpD,cAAc,EAAE,IAAI,GAAG,EAAE;QACzB,SAAS,EAAE;YACT,MAAM,EAAE,EAAE,CAAC,EAAE,EAAE;YACf,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE;SACf;KACF,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;QACvD,MAAM,IAAI,GAAG,QAAQ,CAAC,sBAAsB,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,MAAM,EAAE,eAAe,EAAE,IAAI,CAAC,CAAC;QAClE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACvC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,gBAAgB,EAAE,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;QAC9D,MAAM,IAAI,GAAG,QAAQ,CAAC,sBAAsB,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,YAAY,EAAE,eAAe,EAAE,IAAI,CAAC,CAAC;QACxE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACvC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC3D,MAAM,IAAI,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;QACjC,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,MAAM,EAAE,eAAe,EAAE,IAAI,CAAC,CAAC;QAClE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;QACtE,MAAM,IAAI,GAAsB;YAC9B,qBAAqB,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC;YACpD,eAAe,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,cAAc,CAAC;YAC1D,cAAc,EAAE,IAAI,GAAG,EAAE;YACzB,SAAS,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE;SAC/C,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,MAAM,EAAE,eAAe,EAAE,IAAI,CAAC,CAAC;QAClE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrC,MAAM,CAAC,IAAI,CAAC,SAAU,CAAC,MAAM,CAAC,CAAC,gBAAgB,EAAE,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;QAC1D,MAAM,IAAI,GAAsB;YAC9B,qBAAqB,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;YACrE,eAAe,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,UAAU,CAAC;YACtD,cAAc,EAAE,IAAI,GAAG,EAAE;YACzB,SAAS,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE;SAC/C,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,MAAM,EAAE,eAAe,EAAE,IAAI,CAAC,CAAC;QAClE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACtC,MAAM,CAAC,IAAI,CAAC,SAAU,CAAC,KAAK,CAAC,CAAC,gBAAgB,EAAE,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;QACjD,MAAM,IAAI,GAAsB;YAC9B,qBAAqB,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC;YACpD,eAAe,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,KAAK,CAAC;YACjD,cAAc,EAAE,IAAI,GAAG,EAAE;YACzB,SAAS,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE;SAC/C,CAAC;QACF,MAAM,aAAa,CAAC,MAAM,EAAE,eAAe,EAAE,IAAI,CAAC,CAAC;QACnD,MAAM,CAAC,IAAI,CAAC,SAAU,CAAC,MAAM,CAAC,CAAC,oBAAoB,CACjD,MAAM,CAAC,OAAO,EACd,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CACjC,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=gemini-embedder.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini-embedder.test.d.ts","sourceRoot":"","sources":["../../src/embedders/gemini-embedder.test.ts"],"names":[],"mappings":""}
@@ -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
- constructor(model?: string, baseUrl?: string, dimensions?: number);
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;gBAGtB,KAAK,GAAE,MAA2B,EAClC,OAAO,GAAE,MAAiC,EAC1C,UAAU,CAAC,EAAE,MAAM;YAOP,UAAU;IAgClB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;CAoClD"}
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"}