{"_id":"@backendkit-labs/agent-enterprise","_rev":"6-5e14575960d32349b0eb817de14a701e","name":"@backendkit-labs/agent-enterprise","dist-tags":{"latest":"0.4.0"},"versions":{"0.2.0":{"name":"@backendkit-labs/agent-enterprise","version":"0.2.0","_id":"@backendkit-labs/agent-enterprise@0.2.0","maintainers":[{"name":"backendkit.dev","email":"backendkit.dev@gmail.com"}],"dist":{"shasum":"484eb7e2dd579984ee70e38bc2e17c916db2ad97","tarball":"https://registry.npmjs.org/@backendkit-labs/agent-enterprise/-/agent-enterprise-0.2.0.tgz","fileCount":42,"integrity":"sha512-f9l3tyOx9BuY/plDAb8dhILXg516Ai0NLFKQ3TnlG7BCQ1HULLDCo3vjnxpBjNB1iiNG45WP7tV7rIIHUJnvgg==","signatures":[{"sig":"MEYCIQDzvKCRgGSxj3kv8I4sQEDyC00PTFu60xnZhq2hh0J+AgIhAM1UH1ShGXd+Xem4AwO2kpniFY78d29YJ11ZSWUW1ptH","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":115826},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=20.0.0"},"gitHead":"f40b38d2abf727ccaae570a9df9215548cf622c2","scripts":{"dev":"tsc --watch","test":"jest","build":"tsc","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"backendkit.dev","email":"backendkit.dev@gmail.com"},"_npmVersion":"11.8.0","description":"Business agents with local LLM and RAG knowledge base for agent-core","directories":{},"_nodeVersion":"24.16.0","dependencies":{"yaml":"^2.4.0","@backendkit-labs/agent-core":"*"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.0.0","ts-jest":"^29.0.0","typescript":"^5.4.0","@types/jest":"^29.0.0","@types/node":"^20.0.0"},"_npmOperationalInternal":{"tmp":"tmp/agent-enterprise_0.2.0_1781101939234_0.7311821270198697","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@backendkit-labs/agent-enterprise","version":"0.3.0","_id":"@backendkit-labs/agent-enterprise@0.3.0","maintainers":[{"name":"backendkit.dev","email":"backendkit.dev@gmail.com"}],"dist":{"shasum":"32502de4bb3baf1da5d6b4bd302fe37e1bd2de71","tarball":"https://registry.npmjs.org/@backendkit-labs/agent-enterprise/-/agent-enterprise-0.3.0.tgz","fileCount":46,"integrity":"sha512-KE9cdNkFn6hot8xDLe+HFCdyYDwsx2tqIDqBlKifwYi9W/FXAxjWJHbq72/LcFGeP0YajxCdNQl8IXD9GawpNA==","signatures":[{"sig":"MEYCIQDGHzMkTJVWshdU1EbO7vPdWsYXWGUwtDUqqzNiExFv6wIhAL3VzCPs/TpKAb2wOqhooeY8Ia3i31WPNaCiRXm/LQjN","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":121325},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=20.0.0"},"gitHead":"63f7d501c21cfee72722d2899f53d8b263a38931","scripts":{"dev":"tsc --watch","test":"jest","build":"tsc","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"backendkit.dev","email":"backendkit.dev@gmail.com"},"_npmVersion":"11.8.0","description":"Business agents with local LLM and RAG knowledge base for agent-core","directories":{},"_nodeVersion":"24.16.0","dependencies":{"yaml":"^2.4.0","@backendkit-labs/agent-core":"*"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.0.0","ts-jest":"^29.0.0","typescript":"^5.4.0","@types/jest":"^29.0.0","@types/node":"^20.0.0"},"_npmOperationalInternal":{"tmp":"tmp/agent-enterprise_0.3.0_1781129019050_0.125011091511934","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@backendkit-labs/agent-enterprise","version":"0.3.1","_id":"@backendkit-labs/agent-enterprise@0.3.1","maintainers":[{"name":"backendkit.dev","email":"backendkit.dev@gmail.com"}],"dist":{"shasum":"8afaa1c08a4a99fcd4ac5c49d18ad5b951a1fff6","tarball":"https://registry.npmjs.org/@backendkit-labs/agent-enterprise/-/agent-enterprise-0.3.1.tgz","fileCount":82,"integrity":"sha512-TzmSfVMiNK3d0PfyfPUQ9iLpSXG/v+B4W77nVBo4I/UivDL9EqB4pBLt8zBTgF7R1qXI/Cy9Ht4EOWOWY6lAUg==","signatures":[{"sig":"MEUCIGjWtgy93BxJsWR3EPAnntnK4VmJFVtPPpb4lMZyI9PfAiEAjkk9RXZa0yZT0m0dzDONOSRtVK4NX6FO2YbYlkBuDg0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":170222},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=20.0.0"},"gitHead":"7d0711bddc5202b123c766c6651bb923c3aa35e6","scripts":{"dev":"tsc --watch","test":"jest","build":"tsc","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"backendkit.dev","email":"backendkit.dev@gmail.com"},"_npmVersion":"11.8.0","description":"Business agents with local LLM and RAG knowledge base for agent-core","directories":{},"_nodeVersion":"24.16.0","dependencies":{"yaml":"^2.4.0","@backendkit-labs/agent-core":"*"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.0.0","ts-jest":"^29.0.0","typescript":"^5.4.0","@types/jest":"^29.0.0","@types/node":"^20.0.0"},"_npmOperationalInternal":{"tmp":"tmp/agent-enterprise_0.3.1_1781193323996_0.016150599723634862","host":"s3://npm-registry-packages-npm-production"}},"0.3.2":{"name":"@backendkit-labs/agent-enterprise","version":"0.3.2","_id":"@backendkit-labs/agent-enterprise@0.3.2","maintainers":[{"name":"backendkit.dev","email":"backendkit.dev@gmail.com"}],"dist":{"shasum":"e7b8878ed0204ac1fb4d68434490ed7800ebdc4a","tarball":"https://registry.npmjs.org/@backendkit-labs/agent-enterprise/-/agent-enterprise-0.3.2.tgz","fileCount":82,"integrity":"sha512-E9lWlPVM4LfGROCi/HPTD/fkrG7bovJRxsCoSWXUZYS5EsO1AyuHPRNiP3DmrLIBLwD/7wA/B72aV8FZhedK7w==","signatures":[{"sig":"MEQCID6pYGZRQUjoKUGtixpeKyEHjFzSe22uV3F/3xWBuKkuAiAbGVI1Ltdfk2QOI9hB7n4rAXeAUJfbpu3fPZDYEfuBEQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":170185},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=20.0.0"},"gitHead":"4dcb88f3216d46b1102c7487060054e834bdc550","scripts":{"dev":"tsc --watch","test":"jest","build":"tsc","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"backendkit.dev","email":"backendkit.dev@gmail.com"},"_npmVersion":"11.8.0","description":"Business agents with local LLM and RAG knowledge base for agent-core","directories":{},"_nodeVersion":"24.16.0","dependencies":{"yaml":"^2.4.0","@backendkit-labs/agent-core":"*"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.0.0","ts-jest":"^29.0.0","typescript":"^5.4.0","@types/jest":"^29.0.0","@types/node":"^20.0.0"},"_npmOperationalInternal":{"tmp":"tmp/agent-enterprise_0.3.2_1781201299536_0.23619176640950768","host":"s3://npm-registry-packages-npm-production"}},"0.3.6":{"name":"@backendkit-labs/agent-enterprise","version":"0.3.6","_id":"@backendkit-labs/agent-enterprise@0.3.6","maintainers":[{"name":"backendkit.dev","email":"backendkit.dev@gmail.com"}],"dist":{"shasum":"32df39be387cec5e25b8563523eee60ba918331c","tarball":"https://registry.npmjs.org/@backendkit-labs/agent-enterprise/-/agent-enterprise-0.3.6.tgz","fileCount":170,"integrity":"sha512-F3xxSEvmGWCZOCE6M4ZhU3aTM/jR5UiBI9cL182BLB+AmsBj1rYEb5yzDRq2ehGKXGVAC9VhuCUxLzWEYHZ3xA==","signatures":[{"sig":"MEUCIQCTnsI2oQ0Td5K/eOn8s6kHB6n7cCUKdVGsHjPvF9YuEgIgbX/mVlw/cH7+jZ7YGBIpj8ZRwhrm/3EDWLKBvCx7hdE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":448031},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=20.0.0"},"gitHead":"dc0675448f7f22bfd683588046283860fdfd532d","scripts":{"dev":"tsc --watch","test":"jest","build":"tsc","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"backendkit.dev","email":"backendkit.dev@gmail.com"},"_npmVersion":"11.8.0","description":"Business agents with local LLM and RAG knowledge base for agent-core","directories":{},"_nodeVersion":"24.16.0","dependencies":{"yaml":"^2.4.0","@backendkit-labs/agent-core":"*"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.0.0","bullmq":"^5.0.0","ts-jest":"^29.0.0","typescript":"^5.4.0","@types/jest":"^29.0.0","@types/node":"^20.0.0"},"optionalDependencies":{"bullmq":"^5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/agent-enterprise_0.3.6_1781214942916_0.8359880145711771","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@backendkit-labs/agent-enterprise","version":"0.4.0","description":"Business agents with local LLM and RAG knowledge base for agent-core","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"build":"tsc","dev":"tsc --watch","typecheck":"tsc --noEmit","test":"jest","prepublishOnly":"npm run build"},"dependencies":{"@backendkit-labs/agent-core":"*","yaml":"^2.4.0"},"optionalDependencies":{"bullmq":"^5.0.0"},"devDependencies":{"@types/node":"^20.0.0","@types/jest":"^29.0.0","jest":"^29.0.0","ts-jest":"^29.0.0","typescript":"^5.4.0","bullmq":"^5.0.0"},"engines":{"node":">=20.0.0"},"publishConfig":{"access":"public"},"gitHead":"a5a6d21f119fe8a9aa7a36e75101ffb9885a4e59","_id":"@backendkit-labs/agent-enterprise@0.4.0","_nodeVersion":"24.16.0","_npmVersion":"11.8.0","dist":{"integrity":"sha512-r5NgQ5IxWpIdw1pfgtHD/8Qfe8O6rJi2sMePtxreu7H7ru1PHY7Q0V2wfrMsWq0ipn509m9639jIt+1I2Ma5uA==","shasum":"025e3bf2b293382c57a3ca7cafc157e527a1bf2a","tarball":"https://registry.npmjs.org/@backendkit-labs/agent-enterprise/-/agent-enterprise-0.4.0.tgz","fileCount":186,"unpackedSize":510919,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDdk+ufpjmRmmNGxYh/WUXJfFr6wtaNr2UnJASkYswxDwIhALU1GDRdqg1xQ+KQnHBMpOu+v4574hHzcatv+94JnKj9"}]},"_npmUser":{"name":"backendkit.dev","email":"backendkit.dev@gmail.com"},"directories":{},"maintainers":[{"name":"backendkit.dev","email":"backendkit.dev@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/agent-enterprise_0.4.0_1781376784966_0.18598940902373373"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-10T14:32:18.941Z","modified":"2026-06-13T18:53:05.233Z","0.2.0":"2026-06-10T14:32:19.368Z","0.3.0":"2026-06-10T22:03:39.234Z","0.3.1":"2026-06-11T15:55:24.195Z","0.3.2":"2026-06-11T18:08:19.677Z","0.3.6":"2026-06-11T21:55:43.131Z","0.4.0":"2026-06-13T18:53:05.107Z"},"description":"Business agents with local LLM and RAG knowledge base for agent-core","maintainers":[{"name":"backendkit.dev","email":"backendkit.dev@gmail.com"}],"readme":"# @backendkit-labs/agent-enterprise\n\nEnterprise-grade AI agent setup with RAG (Retrieval-Augmented Generation) over an Obsidian vault, six pre-configured department agent profiles, a vault writing tool, and a factory that wires everything into an `AgentEngine`-compatible setup.\n\n[![npm](https://img.shields.io/npm/v/@backendkit-labs/agent-enterprise)](https://www.npmjs.com/package/@backendkit-labs/agent-enterprise)\n\n> **Status: `core`** — Required by the enterprise use case. Breaking changes go through full review before merging.\n\n## Table of contents\n\n- [Installation](#installation)\n- [Quick start](#quick-start)\n- [createEnterpriseSetup](#createenterprisesetup)\n- [Enterprise agent profiles](#enterprise-agent-profiles)\n- [RAG pipeline](#rag-pipeline)\n- [VaultIndexer](#vaultindexer)\n- [VaultWriter](#vaultwriter)\n- [Embedders](#embedders)\n- [ObsidianRAGProvider](#obsidianragprovider)\n- [VectorStore](#vectorstore)\n- [Full production example with AgentServer](#full-production-example-with-agentserver)\n\n---\n\n## Installation\n\n```bash\nnpm install @backendkit-labs/agent-enterprise @backendkit-labs/agent-core\n```\n\nFor the full web stack:\n\n```bash\nnpm install @backendkit-labs/agent-enterprise @backendkit-labs/agent-core @backendkit-labs/agent-web\n```\n\n---\n\n## Quick start\n\n```typescript\nimport { createEnterpriseSetup } from '@backendkit-labs/agent-enterprise';\nimport { ProviderRegistry } from '@backendkit-labs/agent-core';\nimport { AgentServer } from '@backendkit-labs/agent-web';\n\n// 1. Configure your LLM providers\nconst providers = new ProviderRegistry();\nproviders.register('openai', myOpenAIProvider);\n\n// 2. Create the enterprise setup\nconst enterprise = createEnterpriseSetup({\n  vaultPath:       '/shared/obsidian-vault',\n  providers,\n  defaultProvider: 'openai',\n});\n\n// 3. Index the vault (once at startup — subsequent runs only re-index changed files)\nawait enterprise.indexAll({ verbose: true });\n\n// 4. Start the web server\nconst server = new AgentServer({\n  port:          3000,\n  engineFactory: enterprise.engineFactory,\n  cors:          '*',\n});\n\nawait server.start();\n```\n\n---\n\n## createEnterpriseSetup\n\nThe main factory. Returns `{ indexAll, engineFactory }`.\n\n### Options\n\n```typescript\ninterface EnterpriseSetupOptions {\n  // Required\n  vaultPath:       string;           // absolute path to the Obsidian vault\n  providers:       ProviderRegistry;\n  defaultProvider: string;           // provider ID used when no per-agent override is set\n\n  // Optional\n  indexDir?:       string;           // where to store index files\n                                     // default: ~/.bk-agent/rag/enterprise/\n  embedder?:       Embedder;         // custom embedder, default: SimpleEmbedder\n  sessionsDir?:    string;           // per-session memory dir\n                                     // default: ~/.bk-agent/sessions/\n  extraProfiles?:  AgentProfile[];   // add custom agent profiles alongside the 6 defaults\n  maxIterations?:  number;           // per-engine run limit, default: 20\n}\n```\n\n### Return value\n\n```typescript\ninterface EnterpriseSetup {\n  // Call once at startup (or periodically to pick up new vault notes)\n  indexAll(opts?: { verbose?: boolean }): Promise<void>;\n\n  // Compatible with AgentServer's engineFactory option\n  engineFactory: (sessionId: string, transport: Transport) => AgentEngine;\n}\n```\n\n### What gets created per session\n\nEach call to `engineFactory` assembles a fresh, isolated `AgentEngine` with:\n\n- One `ObsidianRAGProvider` per department scoped to that department's vault folders\n- One global `ObsidianRAGProvider` for the General agent (all vault folders)\n- A shared `VaultWriter` for persisting knowledge back to the vault\n- All six enterprise `AgentProfile`s plus any `extraProfiles`\n- Per-session episodic, semantic, and procedural `MemorySystem` stored in `sessionsDir/<sessionId>/`\n\n---\n\n## Enterprise agent profiles\n\nSix department profiles are built in. Each has a system prompt, a scoped RAG tool, and an optional provider override for on-prem data isolation.\n\n| Profile ID | Agent Name | RAG tool | Default provider |\n|-----------|-----------|----------|-----------------|\n| `general` | General Assistant | `search_kb` (global vault) | `defaultProvider` |\n| `support` | Support Agent | `search_support_kb` | `defaultProvider` |\n| `hr` | HR Agent | `search_hr_kb` | `local` (sensitive) |\n| `sales` | Sales Agent | `search_sales_kb` | `defaultProvider` |\n| `finance` | Finance Agent | `search_finance_kb` | `local` (sensitive) |\n| `ops` | Operations Agent | `search_ops_kb` | `defaultProvider` |\n\nHR and Finance default to the `local` provider so sensitive payroll and financial data never leaves your network.\n\n### Using profiles individually\n\n```typescript\nimport {\n  GENERAL_PROFILE,\n  SUPPORT_PROFILE,\n  HR_PROFILE,\n  SALES_PROFILE,\n  FINANCE_PROFILE,\n  OPS_PROFILE,\n  ALL_ENTERPRISE_PROFILES,\n  ENTERPRISE_TOOLS,\n  VAULT_FOLDERS,\n} from '@backendkit-labs/agent-enterprise';\n\n// Register only the profiles you need\nconst agents = new AgentRegistry();\nagents.register(GENERAL_PROFILE);\nagents.register(SUPPORT_PROFILE);\nagents.register({ ...HR_PROFILE, provider: 'ollama' });      // force on-prem\nagents.register({ ...FINANCE_PROFILE, provider: 'ollama' }); // force on-prem\n\n// Tool name constants\nENTERPRISE_TOOLS.SEARCH_KB;       // 'search_kb'\nENTERPRISE_TOOLS.SEARCH_SUPPORT;  // 'search_support_kb'\nENTERPRISE_TOOLS.SEARCH_HR;       // 'search_hr_kb'\nENTERPRISE_TOOLS.SEARCH_SALES;    // 'search_sales_kb'\nENTERPRISE_TOOLS.SEARCH_FINANCE;  // 'search_finance_kb'\nENTERPRISE_TOOLS.SEARCH_OPS;      // 'search_ops_kb'\n\n// Vault folder name constants\nVAULT_FOLDERS.GENERAL;     // 'General'\nVAULT_FOLDERS.SUPPORT;     // 'Support'\nVAULT_FOLDERS.HR;          // 'HR'\nVAULT_FOLDERS.SALES;       // 'Sales'\nVAULT_FOLDERS.FINANCE;     // 'Finance'\nVAULT_FOLDERS.OPS;         // 'Operations'\n```\n\n### Adding custom profiles\n\n```typescript\nconst enterprise = createEnterpriseSetup({\n  ...opts,\n  extraProfiles: [\n    {\n      id:           'legal',\n      name:         'Legal Advisor',\n      systemPrompt: `You are a legal knowledge assistant.\n        Search the knowledge base for relevant precedents and policies.\n        Always recommend consulting a licensed attorney for case-specific advice.`,\n      tools:        ['search_kb'],\n      provider:     'local',  // sensitive — stays on-prem\n    },\n    {\n      id:           'engineering',\n      name:         'Engineering Assistant',\n      systemPrompt: 'You are a software engineering assistant with access to our internal technical documentation.',\n      tools:        ['search_kb', 'write_vault'],\n    },\n  ],\n});\n```\n\n---\n\n## RAG pipeline\n\nThe RAG pipeline works in two phases: **indexing** and **search**.\n\n### Indexing phase\n\nAt startup, `indexAll()` walks each vault folder, chunks the markdown files, embeds each chunk with the configured embedder, and saves the index to disk as JSON.\n\n```typescript\n// Full or incremental re-index (skips unchanged files)\nawait enterprise.indexAll({ verbose: true });\n// [VaultIndexer] Indexed 142 files, 1,847 chunks in 4.2s (38 skipped, unchanged)\n```\n\n### Search phase\n\nWhen an agent's RAG tool is called, it performs cosine-similarity search over the pre-built index and injects the top-K chunks as context into the LLM prompt:\n\n```\nUser: \"What is our parental leave policy?\"\n  → HR agent selected\n  → search_hr_kb(\"parental leave policy\")\n  → Top 5 chunks from HR/ and General/ folders returned\n  → LLM answers using the retrieved excerpts as grounding context\n```\n\n---\n\n## VaultIndexer\n\nUse `VaultIndexer` directly for fine-grained control over indexing.\n\n```typescript\nimport { VaultIndexer } from '@backendkit-labs/agent-enterprise';\n\nconst indexer = new VaultIndexer({\n  vaultPath:    '/shared/obsidian-vault',\n  indexPath:    '/cache/support-index.json',\n  embedder:     myEmbedder,\n  folders:      ['Support', 'General'],  // only index these folders (omit for all)\n  chunkSize:    500,                     // tokens per chunk\n  chunkOverlap: 50,                      // overlap between adjacent chunks\n});\n\nawait indexer.index({ verbose: true });\n\nconst stats = indexer.getStats();\n// { files: 42, chunks: 587, lastIndexedAt: '2026-06-11T09:00:00.000Z' }\n```\n\n### Incremental re-indexing\n\nThe indexer tracks file modification times. Re-running `index()` only processes changed or new files:\n\n```typescript\n// First run — full index (may take seconds to minutes depending on vault size)\nawait indexer.index({ verbose: true });\n\n// Subsequent runs — only re-indexes changed files (very fast)\nawait indexer.index({ verbose: true });\n// [VaultIndexer] 3 files changed, re-indexed 28 chunks\n```\n\n---\n\n## VaultWriter\n\n`VaultWriter` lets agents persist knowledge back to the Obsidian vault — closing the knowledge loop.\n\n```typescript\nimport { VaultWriter } from '@backendkit-labs/agent-enterprise';\n\nconst writer = new VaultWriter({\n  vaultPath:      '/shared/obsidian-vault',\n  allowedFolders: ['General', 'Support'],  // restrict where agents can write\n});\n\n// Create a ToolDefinition the engine can call\nconst writeTool = writer.createTool('general'); // 'write_vault' tool\n\n// Write directly (from non-agent code)\nawait writer.writeNote({\n  folder:   'General',\n  filename: 'api-auth-pattern.md',\n  content:  '# API Auth Pattern\\n\\nAll endpoints require a Bearer token...',\n  tags:     ['api', 'patterns', 'security'],\n});\n```\n\n### How agents use VaultWriter\n\nAgents with `write_vault` in their tool list can invoke it directly in conversation:\n\n```\nUser: \"Document the new API authentication pattern we agreed on\"\n  → General agent\n  → LLM calls write_vault({\n      folder: \"General\",\n      filename: \"api-auth-2026.md\",\n      content: \"# API Auth Pattern\\n\\n...\"\n    })\n  → File created/updated in the vault\n  → LLM: \"I've documented the auth pattern in General/api-auth-2026.md\"\n```\n\n---\n\n## Embedders\n\nEmbedders convert text strings into float vectors for similarity search.\n\n### SimpleEmbedder (default — no external dependencies)\n\nA deterministic, hash-based embedder. Requires no API key or running service. Lower accuracy than neural models but always available and zero-latency:\n\n```typescript\nimport { SimpleEmbedder } from '@backendkit-labs/agent-enterprise';\n\nconst embedder = new SimpleEmbedder();\n// Good for: prototyping, CI/CD, air-gapped systems, and fallback\n```\n\n### OllamaEmbedder (recommended for production)\n\nUses a local Ollama embedding model for high-quality semantic embeddings. Requires a running Ollama instance with an embedding model installed:\n\n```bash\nollama pull nomic-embed-text    # 274 MB — general purpose, fast\nollama pull mxbai-embed-large   # 669 MB — higher accuracy\n```\n\n```typescript\nimport { OllamaEmbedder, OLLAMA_EMBED_DEFAULT_HOST, OLLAMA_EMBED_DEFAULT_MODEL } from '@backendkit-labs/agent-enterprise';\n\nconst embedder = new OllamaEmbedder({\n  host:  'http://localhost:11434',  // default: OLLAMA_EMBED_DEFAULT_HOST\n  model: 'nomic-embed-text',        // default: OLLAMA_EMBED_DEFAULT_MODEL\n});\n\nconst enterprise = createEnterpriseSetup({\n  vaultPath:       '/vault',\n  providers,\n  defaultProvider: 'local',\n  embedder,\n});\n```\n\n### Custom embedder (OpenAI, Cohere, Hugging Face, etc.)\n\n```typescript\nimport type { Embedder } from '@backendkit-labs/agent-enterprise';\n\nclass OpenAIEmbedder implements Embedder {\n  async embed(texts: string[]): Promise<number[][]> {\n    const res = await openai.embeddings.create({\n      model: 'text-embedding-3-small',\n      input: texts,\n    });\n    return res.data.map(d => d.embedding);\n  }\n}\n\nconst enterprise = createEnterpriseSetup({\n  ...opts,\n  embedder: new OpenAIEmbedder(),\n});\n```\n\n---\n\n## ObsidianRAGProvider\n\nCombines `VaultIndexer` + `VectorStore` in one class with a search API and a tool factory. Use it directly for custom RAG configurations.\n\n```typescript\nimport { ObsidianRAGProvider } from '@backendkit-labs/agent-enterprise';\n\nconst rag = new ObsidianRAGProvider({\n  vaultPath: '/shared/obsidian-vault',\n  indexPath: '/cache/support-index.json',\n  embedder:  new OllamaEmbedder({ model: 'nomic-embed-text' }),\n  folders:   ['Support', 'General'],\n  topK:       5,      // return top 5 results\n  minScore:   0.15,   // discard results below this similarity threshold\n});\n\n// Index the vault\nawait rag.index({ verbose: true });\n\n// Search\nconst results = await rag.search('How do I reset my password?');\n// [\n//   { content: \"To reset your password...\", score: 0.82, source: \"Support/password-reset.md\" },\n//   { content: \"Users can request a reset...\", score: 0.71, source: \"General/user-guide.md\" },\n// ]\n\n// Create a typed ToolDefinition for the engine\nconst searchTool = rag.createTool('search_support_kb');\n// → ToolDefinition with name 'search_support_kb' that calls rag.search()\n```\n\n---\n\n## VectorStore\n\nLow-level cosine-similarity search engine. Use it when you have your own embedding pipeline.\n\n```typescript\nimport { VectorStore } from '@backendkit-labs/agent-enterprise';\nimport type { VectorChunk, SearchResult } from '@backendkit-labs/agent-enterprise';\n\nconst store = new VectorStore();\n\n// Add pre-embedded chunks\nstore.add([\n  { id: 'c1', content: 'Password reset procedure...', embedding: [...512 floats...], source: 'support.md' },\n  { id: 'c2', content: 'Password policy requires...', embedding: [...512 floats...], source: 'policy.md' },\n]);\n\n// Search by query embedding\nconst queryEmbeddings = await embedder.embed(['reset password steps']);\nconst results: SearchResult[] = store.search(queryEmbeddings[0], { topK: 3, minScore: 0.1 });\n\n// Persist index to disk\nstore.saveToFile('/cache/my-index.json');\n\n// Load from disk (on restart)\nconst loaded = VectorStore.loadFromFile('/cache/my-index.json');\n```\n\n---\n\n## Full production example with AgentServer\n\nA complete on-prem enterprise deployment with Ollama embeddings, DeepSeek for general agents, local Ollama for HR/Finance, Redis sessions, and JWT auth:\n\n```typescript\nimport { createEnterpriseSetup, OllamaEmbedder } from '@backendkit-labs/agent-enterprise';\nimport { ProviderRegistry } from '@backendkit-labs/agent-core';\nimport { AgentServer, JwtAuth, TriggerBus, RedisSessionMetaStore } from '@backendkit-labs/agent-web';\nimport Redis from 'ioredis';\n\n// ── LLM Providers ─────────────────────────────────────────────────────────────\n\nconst providers = new ProviderRegistry();\n\n// Cloud: general, support, sales, ops\nproviders.register('deepseek', new DeepSeekProvider({\n  apiKey: process.env.DEEPSEEK_API_KEY!,\n  model:  'deepseek-chat',\n}));\n\n// On-prem: HR and Finance (sensitive data)\nproviders.register('local', new OllamaProvider({\n  host:  'http://ollama.internal:11434',\n  model: 'llama3.2',\n}));\n\n// ── Enterprise Setup ───────────────────────────────────────────────────────────\n\nconst enterprise = createEnterpriseSetup({\n  vaultPath:       process.env.VAULT_PATH!,\n  providers,\n  defaultProvider: 'deepseek',\n  embedder:        new OllamaEmbedder({\n    host:  'http://ollama.internal:11434',\n    model: 'nomic-embed-text',\n  }),\n  indexDir:     '/var/bk-agent/rag-indexes',\n  sessionsDir:  '/var/bk-agent/sessions',\n  maxIterations: 20,\n});\n\nawait enterprise.indexAll({ verbose: true });\n\n// Re-index every night at 2 AM to pick up new vault notes\nimport { CronJob } from 'node-cron';\nCronJob.schedule('0 2 * * *', () => enterprise.indexAll());\n\n// ── Infrastructure ─────────────────────────────────────────────────────────────\n\nconst redis  = new Redis(process.env.REDIS_URL!);\nconst jwt    = new JwtAuth({ secret: process.env.JWT_SECRET!, sessionIdClaim: 'sub' });\nconst triggers = new TriggerBus(enterprise.engineFactory)\n  .addCron({\n    name:        'weekly-digest',\n    schedule:    '0 9 * * 1',\n    buildPrompt: () => 'Summarize all knowledge base updates from the past week.',\n    onResult:    (out) => intranet.post('/announcements', out),\n  });\n\n// ── Server ─────────────────────────────────────────────────────────────────────\n\nconst server = new AgentServer({\n  port:          3000,\n  engineFactory: enterprise.engineFactory,\n  auth:          jwt.hook(),\n  store:         new RedisSessionMetaStore(redis),\n  cors:          ['https://intranet.company.com'],\n  rateLimiting:  { max: 30, timeWindow: '1 minute' },\n  metrics:       { enabled: true, prefix: 'enterprise_' },\n  maxIdleMs:     30 * 60 * 1000,\n  triggers,\n});\n\nawait server.start();\nconsole.log('Enterprise agent server running on :3000');\n\nprocess.on('SIGTERM', () => server.stop());\n```\n\n### Required vault folder structure\n\n```\n/obsidian-vault\n├── General/          ← all agents can search here\n├── Support/          ← Support agent\n├── HR/               ← HR agent (on-prem LLM)\n├── Sales/            ← Sales agent\n├── Finance/          ← Finance agent (on-prem LLM)\n└── Operations/       ← Ops agent\n```\n\nCreate these folders in Obsidian and add `.md` files. The indexer discovers all markdown files recursively.\n","readmeFilename":"README.md"}