@backendkit-labs/agent-enterprise 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +185 -0
  2. package/dist/__tests__/integration/ObsidianRAGProvider.test.d.ts +2 -0
  3. package/dist/__tests__/integration/ObsidianRAGProvider.test.d.ts.map +1 -0
  4. package/dist/__tests__/integration/ObsidianRAGProvider.test.js +237 -0
  5. package/dist/__tests__/integration/ObsidianRAGProvider.test.js.map +1 -0
  6. package/dist/__tests__/integration/OllamaEmbedder.test.d.ts +2 -0
  7. package/dist/__tests__/integration/OllamaEmbedder.test.d.ts.map +1 -0
  8. package/dist/__tests__/integration/OllamaEmbedder.test.js +101 -0
  9. package/dist/__tests__/integration/OllamaEmbedder.test.js.map +1 -0
  10. package/dist/__tests__/unit/VaultIndexer.test.d.ts +2 -0
  11. package/dist/__tests__/unit/VaultIndexer.test.d.ts.map +1 -0
  12. package/dist/__tests__/unit/VaultIndexer.test.js +174 -0
  13. package/dist/__tests__/unit/VaultIndexer.test.js.map +1 -0
  14. package/dist/__tests__/unit/VectorStore.test.d.ts +2 -0
  15. package/dist/__tests__/unit/VectorStore.test.d.ts.map +1 -0
  16. package/dist/__tests__/unit/VectorStore.test.js +146 -0
  17. package/dist/__tests__/unit/VectorStore.test.js.map +1 -0
  18. package/dist/index.d.ts +11 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +16 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/rag/ObsidianRAGProvider.d.ts +52 -0
  23. package/dist/rag/ObsidianRAGProvider.d.ts.map +1 -0
  24. package/dist/rag/ObsidianRAGProvider.js +148 -0
  25. package/dist/rag/ObsidianRAGProvider.js.map +1 -0
  26. package/dist/rag/OllamaEmbedder.d.ts +15 -0
  27. package/dist/rag/OllamaEmbedder.d.ts.map +1 -0
  28. package/dist/rag/OllamaEmbedder.js +50 -0
  29. package/dist/rag/OllamaEmbedder.js.map +1 -0
  30. package/dist/rag/VaultIndexer.d.ts +34 -0
  31. package/dist/rag/VaultIndexer.d.ts.map +1 -0
  32. package/dist/rag/VaultIndexer.js +230 -0
  33. package/dist/rag/VaultIndexer.js.map +1 -0
  34. package/dist/rag/VaultWriter.d.ts +33 -0
  35. package/dist/rag/VaultWriter.d.ts.map +1 -0
  36. package/dist/rag/VaultWriter.js +112 -0
  37. package/dist/rag/VaultWriter.js.map +1 -0
  38. package/dist/rag/VectorStore.d.ts +36 -0
  39. package/dist/rag/VectorStore.d.ts.map +1 -0
  40. package/dist/rag/VectorStore.js +119 -0
  41. package/dist/rag/VectorStore.js.map +1 -0
  42. package/package.json +35 -0
package/README.md ADDED
@@ -0,0 +1,185 @@
1
+ # @backendkit-labs/agent-enterprise
2
+
3
+ Enterprise knowledge layer for the BackendKit Agent Framework — local RAG over Obsidian vaults, shared knowledge vault with agent write-back, and pluggable embedders.
4
+
5
+ ```bash
6
+ npm install @backendkit-labs/agent-enterprise
7
+ ```
8
+
9
+ > Requires `@backendkit-labs/agent-core`. Works with any LLM provider — no cloud dependency required.
10
+
11
+ ---
12
+
13
+ ## What it does
14
+
15
+ Gives your agents a **shared, persistent knowledge base** backed by Markdown files:
16
+
17
+ - **Read** — agents search the vault semantically (`search_knowledge` tool)
18
+ - **Write** — agents contribute new knowledge back to the vault (`write_knowledge` tool)
19
+ - **Index** — incremental indexing by file mtime; only re-embeds new or modified files
20
+ - **Human-readable** — the vault is plain Markdown, openable in Obsidian or any editor
21
+
22
+ ---
23
+
24
+ ## Quick start — RAG over an Obsidian vault
25
+
26
+ ```ts
27
+ import { AgentEngine, ToolRegistry } from '@backendkit-labs/agent-core';
28
+ import { ObsidianRAGProvider } from '@backendkit-labs/agent-enterprise';
29
+
30
+ const rag = new ObsidianRAGProvider({
31
+ vaultPath: '/path/to/your/vault',
32
+ ollamaHost: 'http://localhost:11434', // default
33
+ embeddingModel: 'nomic-embed-text', // default
34
+ });
35
+
36
+ // Index the vault (incremental — only changed files on subsequent runs)
37
+ await rag.index({ verbose: true });
38
+
39
+ // Register the search_knowledge tool with your engine
40
+ const tools = new ToolRegistry();
41
+ tools.register(rag.createTool());
42
+ ```
43
+
44
+ The agent calls `search_knowledge` automatically when it needs information from the vault.
45
+
46
+ ---
47
+
48
+ ## Shared vault with agent write-back
49
+
50
+ ```ts
51
+ import { ObsidianRAGProvider, VaultWriter } from '@backendkit-labs/agent-enterprise';
52
+
53
+ const rag = new ObsidianRAGProvider({ vaultPath: '/vault', ...opts });
54
+ const writer = new VaultWriter({ vaultPath: '/vault' });
55
+
56
+ const tools = new ToolRegistry();
57
+ tools.register(rag.createTool()); // search_knowledge
58
+ tools.register(writer.createTool('analyst')); // write_knowledge — baked in with agent id
59
+
60
+ // After the agent writes a note, re-index to make it searchable:
61
+ await rag.index();
62
+ ```
63
+
64
+ Agent-written notes land in `<vaultPath>/agentes/` with standard frontmatter:
65
+
66
+ ```markdown
67
+ ---
68
+ title: "Cache Decision for RAG Embeddings"
69
+ author: "agent/analyst"
70
+ date: 2026-06-10
71
+ tags: ["área/rag", "tipo/decisión"]
72
+ description: "LRU in-memory cache chosen over persistent or semantic cache"
73
+ ---
74
+
75
+ ## Context
76
+ ...
77
+ ```
78
+
79
+ ---
80
+
81
+ ## Custom embedder — no Ollama required
82
+
83
+ Pass any object that implements `Embedder` to skip Ollama:
84
+
85
+ ```ts
86
+ import { ObsidianRAGProvider, type Embedder } from '@backendkit-labs/agent-enterprise';
87
+
88
+ class MyEmbedder implements Embedder {
89
+ readonly model = 'my-model-v1';
90
+ async embed(texts: string[]): Promise<number[][]> { /* ... */ }
91
+ async embedOne(text: string): Promise<number[]> { /* ... */ }
92
+ }
93
+
94
+ const rag = new ObsidianRAGProvider({
95
+ vaultPath: '/vault',
96
+ embedder: new MyEmbedder(), // ollamaHost and embeddingModel are ignored
97
+ });
98
+ ```
99
+
100
+ ---
101
+
102
+ ## SimpleEmbedder — local testing without Ollama
103
+
104
+ For tests and CI where Ollama is not available:
105
+
106
+ ```ts
107
+ // Not exported from the package — copy from pilot/src/embedders/SimpleEmbedder.ts
108
+ // TF-IDF feature hashing, 256 dims, pure Node.js, zero dependencies
109
+ const rag = new ObsidianRAGProvider({
110
+ vaultPath: '/vault',
111
+ embedder: new SimpleEmbedder(),
112
+ minScore: 0.1, // lower threshold for keyword-based vectors
113
+ });
114
+ ```
115
+
116
+ ---
117
+
118
+ ## ObsidianRAGProvider options
119
+
120
+ ```ts
121
+ new ObsidianRAGProvider({
122
+ vaultPath: string; // absolute path to vault directory
123
+ folders?: string[]; // sub-folders to index (default: all)
124
+ indexPath?: string; // where to save the vector index JSON
125
+ embedder?: Embedder; // custom embedder (overrides ollamaHost/embeddingModel)
126
+ ollamaHost?: string; // default: http://localhost:11434
127
+ embeddingModel?: string; // default: nomic-embed-text
128
+ topK?: number; // max results per search (default: 5)
129
+ minScore?: number; // min cosine similarity 0–1 (default: 0.3)
130
+ excludeTags?: string[]; // frontmatter tags to skip (default: ['skill'])
131
+ })
132
+ ```
133
+
134
+ ---
135
+
136
+ ## VaultWriter options
137
+
138
+ ```ts
139
+ new VaultWriter({
140
+ vaultPath: string; // must match the ObsidianRAGProvider vaultPath
141
+ agentFolder?: string; // sub-folder for agent notes (default: 'agentes')
142
+ })
143
+
144
+ writer.createTool(agentId: string): ToolDefinition
145
+ // Returns write_knowledge tool with agentId baked into each note's author field
146
+ ```
147
+
148
+ ---
149
+
150
+ ## Vault structure
151
+
152
+ Recommended layout for enterprise deployments:
153
+
154
+ ```
155
+ vault/
156
+ rrhh/ ← HR domain — only HR Agent indexed here
157
+ ventas/ ← Sales domain
158
+ ops/ ← Operations
159
+ compartido/ ← Cross-domain, all agents read
160
+ agentes/ ← Auto-created — agent-written notes land here
161
+ ```
162
+
163
+ Mount only the relevant folders per agent:
164
+
165
+ ```ts
166
+ new ObsidianRAGProvider({ vaultPath, folders: ['ventas', 'compartido', 'agentes'] })
167
+ ```
168
+
169
+ ---
170
+
171
+ ## How indexing works
172
+
173
+ 1. `VaultIndexer` scans `.md` files and reads their `mtime`
174
+ 2. Compares against stored mtimes in `VectorStore`
175
+ 3. Only embeds files that are new or modified since last index
176
+ 4. Chunks each file by `##` headings (max 500 words per chunk)
177
+ 5. Stores vectors + metadata in a single JSON file on disk
178
+
179
+ The JSON store scales to ~5–10k chunks. For larger vaults, use a proper vector DB (pgvector, Qdrant) with a custom `Embedder` adapter.
180
+
181
+ ---
182
+
183
+ ## License
184
+
185
+ MIT © [BackendKit Labs](https://github.com/BackendKit-labs)
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ObsidianRAGProvider.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ObsidianRAGProvider.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/integration/ObsidianRAGProvider.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,237 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const fs = __importStar(require("fs/promises"));
37
+ const os = __importStar(require("os"));
38
+ const path = __importStar(require("path"));
39
+ const ObsidianRAGProvider_1 = require("../../rag/ObsidianRAGProvider");
40
+ const OLLAMA_HOST = process.env.OLLAMA_HOST ?? 'http://localhost:11434';
41
+ const EMBED_MODEL = process.env.EMBEDDING_MODEL ?? 'nomic-embed-text';
42
+ // ── Vault de fixtures ─────────────────────────────────────────────────────────
43
+ const FIXTURES = {
44
+ 'agentes-orquestacion.md': `---
45
+ title: Orquestación de Agentes IA
46
+ tags: [área/arquitectura, stack/typescript]
47
+ description: Patrones para coordinar múltiples agentes especializados
48
+ ---
49
+
50
+ ## Patrón orquestador-especialista
51
+
52
+ El orquestador recibe la tarea del usuario y la descompone en subtareas.
53
+ Cada subtarea se delega a un agente especialista a través del tool ask_agent.
54
+ Los especialistas devuelven su resultado al orquestador, que sintetiza la respuesta final.
55
+
56
+ ## Delegación paralela
57
+
58
+ Cuando las subtareas son independientes entre sí, el orquestador puede lanzar
59
+ múltiples ask_agent en el mismo turno. El engine ejecuta todas las delegaciones
60
+ en paralelo, limitado por el bulkhead de 6 slots concurrentes.
61
+ `,
62
+ 'rag-vectorial.md': `---
63
+ title: RAG con Vector Store Local
64
+ tags: [área/ia, stack/typescript]
65
+ description: Implementación de Retrieval Augmented Generation sin dependencias externas
66
+ ---
67
+
68
+ ## Embeddings con Ollama
69
+
70
+ Los embeddings se generan usando el modelo nomic-embed-text de Ollama.
71
+ La API es POST /api/embed con el texto y el nombre del modelo.
72
+ El resultado es un vector de 768 dimensiones para nomic-embed-text.
73
+
74
+ ## Similitud coseno
75
+
76
+ La búsqueda semántica compara el embedding de la consulta con los embeddings
77
+ almacenados usando similitud coseno. El resultado más cercano a 1.0 es el más relevante.
78
+
79
+ ## Indexación incremental
80
+
81
+ El VectorStore guarda el mtime de cada archivo. En el siguiente índice,
82
+ solo se re-embeden los archivos nuevos o modificados.
83
+ `,
84
+ 'typescript-patterns.md': `---
85
+ title: Patrones TypeScript en el Framework
86
+ tags: [stack/typescript, área/arquitectura]
87
+ description: Convenciones de código usadas en el proyecto
88
+ ---
89
+
90
+ ## Tipos estrictos
91
+
92
+ El proyecto usa strict mode de TypeScript. Todos los parámetros opcionales
93
+ deben declararse explícitamente. No se permite any sin justificación.
94
+
95
+ ## Inyección de dependencias
96
+
97
+ Los providers se registran en ProviderRegistry y se resuelven por nombre.
98
+ Esto permite intercambiar OllamaProvider por otros providers en tests.
99
+ `,
100
+ };
101
+ // ── Helpers ───────────────────────────────────────────────────────────────────
102
+ async function ollamaAvailable() {
103
+ try {
104
+ const res = await fetch(`${OLLAMA_HOST}/api/tags`, {
105
+ signal: AbortSignal.timeout(3000),
106
+ });
107
+ if (!res.ok)
108
+ return false;
109
+ const data = await res.json();
110
+ return (data.models ?? []).some(m => m.name.startsWith(EMBED_MODEL));
111
+ }
112
+ catch {
113
+ return false;
114
+ }
115
+ }
116
+ async function createFixtureVault(dir) {
117
+ for (const [name, content] of Object.entries(FIXTURES)) {
118
+ await fs.writeFile(path.join(dir, name), content, 'utf-8');
119
+ }
120
+ }
121
+ // ── Suite ─────────────────────────────────────────────────────────────────────
122
+ describe('ObsidianRAGProvider — integración', () => {
123
+ let available = false;
124
+ let vaultDir;
125
+ let indexDir;
126
+ beforeAll(async () => {
127
+ available = await ollamaAvailable();
128
+ if (!available) {
129
+ console.warn(`\n⚠ ObsidianRAGProvider tests saltados — Ollama no disponible en ${OLLAMA_HOST} ` +
130
+ `o modelo '${EMBED_MODEL}' no descargado.\n` +
131
+ ` Para ejecutarlos: ollama serve && ollama pull ${EMBED_MODEL}\n`);
132
+ return;
133
+ }
134
+ const base = await fs.mkdtemp(path.join(os.tmpdir(), 'bk-rag-e2e-'));
135
+ vaultDir = path.join(base, 'vault');
136
+ indexDir = path.join(base, 'index');
137
+ await fs.mkdir(vaultDir);
138
+ await fs.mkdir(indexDir);
139
+ await createFixtureVault(vaultDir);
140
+ });
141
+ afterAll(async () => {
142
+ if (vaultDir) {
143
+ await fs.rm(path.dirname(vaultDir), { recursive: true, force: true });
144
+ }
145
+ });
146
+ test('index() indexa todos los archivos del vault fixture', async () => {
147
+ if (!available)
148
+ return;
149
+ const rag = new ObsidianRAGProvider_1.ObsidianRAGProvider({
150
+ vaultPath: vaultDir,
151
+ indexPath: path.join(indexDir, 'index.json'),
152
+ ollamaHost: OLLAMA_HOST,
153
+ embeddingModel: EMBED_MODEL,
154
+ });
155
+ const { indexed, removed } = await rag.index({ verbose: false });
156
+ expect(indexed).toBeGreaterThan(0); // al menos un chunk por archivo
157
+ expect(removed).toBe(0);
158
+ expect(rag.chunkCount).toBeGreaterThan(0);
159
+ });
160
+ test('index() incremental no re-indexa archivos sin cambios', async () => {
161
+ if (!available)
162
+ return;
163
+ const indexPath = path.join(indexDir, 'incremental.json');
164
+ const rag = new ObsidianRAGProvider_1.ObsidianRAGProvider({
165
+ vaultPath: vaultDir, indexPath, ollamaHost: OLLAMA_HOST, embeddingModel: EMBED_MODEL,
166
+ });
167
+ await rag.index(); // primera pasada — indexa todo
168
+ const rag2 = new ObsidianRAGProvider_1.ObsidianRAGProvider({
169
+ vaultPath: vaultDir, indexPath, ollamaHost: OLLAMA_HOST, embeddingModel: EMBED_MODEL,
170
+ });
171
+ const { indexed } = await rag2.index(); // segunda pasada — nada cambió
172
+ expect(indexed).toBe(0);
173
+ });
174
+ test('search devuelve el chunk más relevante para "orquestador"', async () => {
175
+ if (!available)
176
+ return;
177
+ const rag = new ObsidianRAGProvider_1.ObsidianRAGProvider({
178
+ vaultPath: vaultDir,
179
+ indexPath: path.join(indexDir, 'search-test.json'),
180
+ ollamaHost: OLLAMA_HOST,
181
+ embeddingModel: EMBED_MODEL,
182
+ topK: 3,
183
+ minScore: 0.1,
184
+ });
185
+ const result = await rag.search('patrón orquestador especialista delegación');
186
+ expect(result).toContain('orquestaci'); // título o contenido del archivo relevante
187
+ expect(result).not.toBe('No se encontró información relevante en la base de conocimiento para esa consulta.');
188
+ });
189
+ test('search devuelve mensaje de no-resultados para consulta sin match', async () => {
190
+ if (!available)
191
+ return;
192
+ const rag = new ObsidianRAGProvider_1.ObsidianRAGProvider({
193
+ vaultPath: vaultDir,
194
+ indexPath: path.join(indexDir, 'no-match.json'),
195
+ ollamaHost: OLLAMA_HOST,
196
+ embeddingModel: EMBED_MODEL,
197
+ minScore: 0.99, // umbral imposible de alcanzar
198
+ });
199
+ const result = await rag.search('xyzabcnonexistent987');
200
+ expect(result).toContain('No se encontró información relevante');
201
+ });
202
+ test('búsquedas sobre temas distintos devuelven fuentes distintas', async () => {
203
+ if (!available)
204
+ return;
205
+ const rag = new ObsidianRAGProvider_1.ObsidianRAGProvider({
206
+ vaultPath: vaultDir,
207
+ indexPath: path.join(indexDir, 'multi-topic.json'),
208
+ ollamaHost: OLLAMA_HOST,
209
+ embeddingModel: EMBED_MODEL,
210
+ topK: 1,
211
+ minScore: 0.1,
212
+ });
213
+ const resultOrq = await rag.search('orquestador y delegación de agentes');
214
+ const resultTS = await rag.search('strict mode TypeScript inyección dependencias');
215
+ // Los resultados top deben venir de archivos distintos
216
+ const titleOrq = resultOrq.match(/Fuente: ([^\n]+)/)?.[1] ?? '';
217
+ const titleTS = resultTS.match(/Fuente: ([^\n]+)/)?.[1] ?? '';
218
+ expect(titleOrq).not.toBe(titleTS);
219
+ });
220
+ test('createTool devuelve un ToolDefinition ejecutable', async () => {
221
+ if (!available)
222
+ return;
223
+ const rag = new ObsidianRAGProvider_1.ObsidianRAGProvider({
224
+ vaultPath: vaultDir,
225
+ indexPath: path.join(indexDir, 'tool-test.json'),
226
+ ollamaHost: OLLAMA_HOST,
227
+ embeddingModel: EMBED_MODEL,
228
+ });
229
+ const tool = rag.createTool();
230
+ expect(tool.name).toBe('search_knowledge');
231
+ expect(typeof tool.execute).toBe('function');
232
+ const result = await tool.execute({ query: 'embeddings vectoriales' }, {});
233
+ expect(typeof result).toBe('string');
234
+ expect(result.length).toBeGreaterThan(0);
235
+ });
236
+ });
237
+ //# sourceMappingURL=ObsidianRAGProvider.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ObsidianRAGProvider.test.js","sourceRoot":"","sources":["../../../src/__tests__/integration/ObsidianRAGProvider.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,gDAAkC;AAClC,uCAAyB;AACzB,2CAA6B;AAC7B,uEAAoE;AAEpE,MAAM,WAAW,GAAK,OAAO,CAAC,GAAG,CAAC,WAAW,IAAO,wBAAwB,CAAC;AAC7E,MAAM,WAAW,GAAK,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,kBAAkB,CAAC;AAExE,iFAAiF;AAEjF,MAAM,QAAQ,GAA2B;IACrC,yBAAyB,EAAE;;;;;;;;;;;;;;;;;CAiB9B;IAEG,kBAAkB,EAAE;;;;;;;;;;;;;;;;;;;;;CAqBvB;IAEG,wBAAwB,EAAE;;;;;;;;;;;;;;;CAe7B;CACA,CAAC;AAEF,iFAAiF;AAEjF,KAAK,UAAU,eAAe;IAC1B,IAAI,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,WAAW,WAAW,EAAE;YAC/C,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC;SACpC,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,KAAK,CAAC;QAC1B,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAA0C,CAAC;QACtE,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC;IACzE,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,KAAK,CAAC;IACjB,CAAC;AACL,CAAC;AAED,KAAK,UAAU,kBAAkB,CAAC,GAAW;IACzC,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACrD,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAC/D,CAAC;AACL,CAAC;AAED,iFAAiF;AAEjF,QAAQ,CAAC,mCAAmC,EAAE,GAAG,EAAE;IAC/C,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,IAAI,QAAgB,CAAC;IACrB,IAAI,QAAgB,CAAC;IAErB,SAAS,CAAC,KAAK,IAAI,EAAE;QACjB,SAAS,GAAG,MAAM,eAAe,EAAE,CAAC;QACpC,IAAI,CAAC,SAAS,EAAE,CAAC;YACb,OAAO,CAAC,IAAI,CACR,qEAAqE,WAAW,GAAG;gBACnF,aAAa,WAAW,oBAAoB;gBAC5C,oDAAoD,WAAW,IAAI,CACtE,CAAC;YACF,OAAO;QACX,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,aAAa,CAAC,CAAC,CAAC;QACrE,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACpC,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACpC,MAAM,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACzB,MAAM,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACzB,MAAM,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,KAAK,IAAI,EAAE;QAChB,IAAI,QAAQ,EAAE,CAAC;YACX,MAAM,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1E,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;QACnE,IAAI,CAAC,SAAS;YAAE,OAAO;QACvB,MAAM,GAAG,GAAG,IAAI,yCAAmB,CAAC;YAChC,SAAS,EAAO,QAAQ;YACxB,SAAS,EAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC;YACjD,UAAU,EAAM,WAAW;YAC3B,cAAc,EAAE,WAAW;SAC9B,CAAC,CAAC;QAEH,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QAEjE,MAAM,CAAC,OAAO,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAI,gCAAgC;QACvE,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACxB,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;QACrE,IAAI,CAAC,SAAS;YAAE,OAAO;QACvB,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC;QAC1D,MAAM,GAAG,GAAG,IAAI,yCAAmB,CAAC;YAChC,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE,WAAW;SACvF,CAAC,CAAC;QAEH,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,+BAA+B;QAElD,MAAM,IAAI,GAAG,IAAI,yCAAmB,CAAC;YACjC,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE,WAAW;SACvF,CAAC,CAAC;QACH,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,+BAA+B;QAEvE,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;QACzE,IAAI,CAAC,SAAS;YAAE,OAAO;QACvB,MAAM,GAAG,GAAG,IAAI,yCAAmB,CAAC;YAChC,SAAS,EAAE,QAAQ;YACnB,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,kBAAkB,CAAC;YAClD,UAAU,EAAE,WAAW;YACvB,cAAc,EAAE,WAAW;YAC3B,IAAI,EAAE,CAAC;YACP,QAAQ,EAAE,GAAG;SAChB,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,4CAA4C,CAAC,CAAC;QAE9E,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,2CAA2C;QACnF,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,oFAAoF,CAAC,CAAC;IAClH,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,kEAAkE,EAAE,KAAK,IAAI,EAAE;QAChF,IAAI,CAAC,SAAS;YAAE,OAAO;QACvB,MAAM,GAAG,GAAG,IAAI,yCAAmB,CAAC;YAChC,SAAS,EAAE,QAAQ;YACnB,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC;YAC/C,UAAU,EAAE,WAAW;YACvB,cAAc,EAAE,WAAW;YAC3B,QAAQ,EAAE,IAAI,EAAE,+BAA+B;SAClD,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC;QACxD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,sCAAsC,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,6DAA6D,EAAE,KAAK,IAAI,EAAE;QAC3E,IAAI,CAAC,SAAS;YAAE,OAAO;QACvB,MAAM,GAAG,GAAG,IAAI,yCAAmB,CAAC;YAChC,SAAS,EAAE,QAAQ;YACnB,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,kBAAkB,CAAC;YAClD,UAAU,EAAE,WAAW;YACvB,cAAc,EAAE,WAAW;YAC3B,IAAI,EAAE,CAAC;YACP,QAAQ,EAAE,GAAG;SAChB,CAAC,CAAC;QAEH,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,qCAAqC,CAAC,CAAC;QAC1E,MAAM,QAAQ,GAAI,MAAM,GAAG,CAAC,MAAM,CAAC,+CAA+C,CAAC,CAAC;QAEpF,uDAAuD;QACvD,MAAM,QAAQ,GAAG,SAAS,CAAC,KAAK,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAChE,MAAM,OAAO,GAAI,QAAQ,CAAC,KAAK,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC/D,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;QAChE,IAAI,CAAC,SAAS;YAAE,OAAO;QACvB,MAAM,GAAG,GAAG,IAAI,yCAAmB,CAAC;YAChC,SAAS,EAAE,QAAQ;YACnB,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,gBAAgB,CAAC;YAChD,UAAU,EAAE,WAAW;YACvB,cAAc,EAAE,WAAW;SAC9B,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,GAAG,CAAC,UAAU,EAAE,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAC3C,MAAM,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAE7C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAC7B,EAAE,KAAK,EAAE,wBAAwB,EAAE,EACnC,EAAW,CACd,CAAC;QACF,MAAM,CAAC,OAAO,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=OllamaEmbedder.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OllamaEmbedder.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/integration/OllamaEmbedder.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const OllamaEmbedder_1 = require("../../rag/OllamaEmbedder");
4
+ const OLLAMA_HOST = process.env.OLLAMA_HOST ?? 'http://localhost:11434';
5
+ const EMBED_MODEL = process.env.EMBEDDING_MODEL ?? 'nomic-embed-text';
6
+ async function ollamaAvailable() {
7
+ try {
8
+ const res = await fetch(`${OLLAMA_HOST}/api/tags`, {
9
+ signal: AbortSignal.timeout(3000),
10
+ });
11
+ return res.ok;
12
+ }
13
+ catch {
14
+ return false;
15
+ }
16
+ }
17
+ async function modelAvailable(model) {
18
+ try {
19
+ const res = await fetch(`${OLLAMA_HOST}/api/tags`);
20
+ const data = await res.json();
21
+ return (data.models ?? []).some(m => m.name.startsWith(model));
22
+ }
23
+ catch {
24
+ return false;
25
+ }
26
+ }
27
+ describe('OllamaEmbedder — integración', () => {
28
+ let available = false;
29
+ beforeAll(async () => {
30
+ available = await ollamaAvailable() && await modelAvailable(EMBED_MODEL);
31
+ if (!available) {
32
+ console.warn(`\n⚠ OllamaEmbedder tests saltados — Ollama no disponible en ${OLLAMA_HOST} ` +
33
+ `o modelo '${EMBED_MODEL}' no descargado.\n` +
34
+ ` Para ejecutarlos: ollama serve && ollama pull ${EMBED_MODEL}\n`);
35
+ }
36
+ });
37
+ test('checkConnection no lanza si Ollama está corriendo', async () => {
38
+ if (!available)
39
+ return;
40
+ const embedder = new OllamaEmbedder_1.OllamaEmbedder({ host: OLLAMA_HOST, model: EMBED_MODEL });
41
+ await expect(embedder.checkConnection()).resolves.not.toThrow();
42
+ });
43
+ test('embedOne devuelve un vector de la dimensión correcta (768 para nomic-embed-text)', async () => {
44
+ if (!available)
45
+ return;
46
+ const embedder = new OllamaEmbedder_1.OllamaEmbedder({ host: OLLAMA_HOST, model: EMBED_MODEL });
47
+ const vec = await embedder.embedOne('Hola mundo');
48
+ expect(Array.isArray(vec)).toBe(true);
49
+ expect(vec.length).toBeGreaterThan(0);
50
+ // nomic-embed-text produce vectores de 768 dimensiones
51
+ if (EMBED_MODEL === 'nomic-embed-text') {
52
+ expect(vec.length).toBe(768);
53
+ }
54
+ });
55
+ test('embed([]) devuelve array vacío sin llamar a Ollama', async () => {
56
+ // Este test no requiere Ollama — verifica el early-return
57
+ const embedder = new OllamaEmbedder_1.OllamaEmbedder({ host: OLLAMA_HOST, model: EMBED_MODEL });
58
+ const result = await embedder.embed([]);
59
+ expect(result).toEqual([]);
60
+ });
61
+ test('embed de un batch devuelve tantos vectores como textos', async () => {
62
+ if (!available)
63
+ return;
64
+ const embedder = new OllamaEmbedder_1.OllamaEmbedder({ host: OLLAMA_HOST, model: EMBED_MODEL });
65
+ const texts = ['primer texto', 'segundo texto', 'tercer texto'];
66
+ const vecs = await embedder.embed(texts);
67
+ expect(vecs).toHaveLength(3);
68
+ for (const v of vecs) {
69
+ expect(v.length).toBeGreaterThan(0);
70
+ }
71
+ });
72
+ test('textos similares tienen mayor similitud coseno que textos no relacionados', async () => {
73
+ if (!available)
74
+ return;
75
+ const embedder = new OllamaEmbedder_1.OllamaEmbedder({ host: OLLAMA_HOST, model: EMBED_MODEL });
76
+ const [vBase, vSimilar, vUnrelated] = await embedder.embed([
77
+ 'orquestación de agentes IA',
78
+ 'coordinación de múltiples agentes inteligentes',
79
+ 'receta de paella valenciana',
80
+ ]);
81
+ const cosine = (a, b) => {
82
+ let dot = 0, na = 0, nb = 0;
83
+ for (let i = 0; i < a.length; i++) {
84
+ dot += a[i] * b[i];
85
+ na += a[i] ** 2;
86
+ nb += b[i] ** 2;
87
+ }
88
+ return dot / (Math.sqrt(na) * Math.sqrt(nb));
89
+ };
90
+ const simSimilar = cosine(vBase, vSimilar);
91
+ const simUnrelated = cosine(vBase, vUnrelated);
92
+ expect(simSimilar).toBeGreaterThan(simUnrelated);
93
+ });
94
+ test('lanza error descriptivo si el modelo no existe', async () => {
95
+ if (!available)
96
+ return;
97
+ const embedder = new OllamaEmbedder_1.OllamaEmbedder({ host: OLLAMA_HOST, model: 'modelo-inexistente-xyz' });
98
+ await expect(embedder.embedOne('test')).rejects.toThrow(/modelo-inexistente-xyz/i);
99
+ });
100
+ });
101
+ //# sourceMappingURL=OllamaEmbedder.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OllamaEmbedder.test.js","sourceRoot":"","sources":["../../../src/__tests__/integration/OllamaEmbedder.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=VaultIndexer.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VaultIndexer.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/unit/VaultIndexer.test.ts"],"names":[],"mappings":""}