diff --git a/README.md b/README.md index 69d718c..ff7e9aa 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,67 @@ Give your AI agent the ability to learn from documents and answer questions based on that knowledge. Works out of the box with zero configuration! +## 📦 Installation Modes + +The Knowledge plugin supports multiple deployment modes to fit your use case: + +### **Full Mode** (Default - With UI & Routes) + +Perfect for standard deployments with the full web interface: + +```typescript +import { knowledgePlugin } from '@elizaos/plugin-knowledge'; +// or +import knowledgePlugin from '@elizaos/plugin-knowledge'; + +export const character = { + plugins: [knowledgePlugin], +}; +``` + +### **Headless Mode** (Service + Provider + Actions, No UI) + +For server deployments without frontend: + +```typescript +import { knowledgePluginHeadless } from '@elizaos/plugin-knowledge'; + +export const character = { + plugins: [knowledgePluginHeadless], +}; +``` + +### **Core Mode** (Service + Provider Only) + +For cloud runtimes or minimal deployments (no routes, no UI, no actions): + +```typescript +import { knowledgePluginCore } from '@elizaos/plugin-knowledge'; + +export const character = { + plugins: [knowledgePluginCore], +}; +``` + +### **Custom Configuration** + +Create your own configuration: + +```typescript +import { createKnowledgePlugin } from '@elizaos/plugin-knowledge'; + +const customPlugin = createKnowledgePlugin({ + enableUI: false, // Disable frontend UI + enableRoutes: false, // Disable HTTP routes + enableActions: true, // Keep actions enabled + enableTests: false, // Disable tests +}); + +export const character = { + plugins: [customPlugin], +}; +``` + ## 🚀 Getting Started (Beginner-Friendly) ### Step 1: Add the Plugin @@ -14,7 +75,7 @@ export const character = { name: 'MyAgent', plugins: [ '@elizaos/plugin-openai', // ← Make sure you have this - '@elizaos/plugin-knowledge', // ← Add this line + '@elizaos/plugin-knowledge', // ← Add this line (full mode) // ... your other plugins ], // ... rest of your character config @@ -192,28 +253,68 @@ MAX_OUTPUT_TOKENS=4096 # Response size limit ```typescript import { KnowledgeService } from '@elizaos/plugin-knowledge'; +// Get the service from runtime +const knowledgeService = runtime.getService(KnowledgeService.serviceType); + // Add knowledge programmatically const result = await knowledgeService.addKnowledge({ - clientDocumentId: 'unique-doc-id', + agentId: runtime.agentId, + clientDocumentId: '' as UUID, // Auto-generated based on content content: documentContent, // Base64 for PDFs, plain text for others contentType: 'application/pdf', originalFilename: 'document.pdf', - worldId: runtime.worldId, - roomId: runtime.roomId, - entityId: runtime.entityId, + worldId: runtime.agentId, + roomId: runtime.agentId, + entityId: runtime.agentId, metadata: { - // Optional + // Optional custom metadata source: 'upload', author: 'John Doe', }, }); -// Search knowledge -const searchResults = await knowledgeService.searchKnowledge({ - query: 'quantum computing', +// The provider automatically retrieves relevant knowledge during conversations +// But you can also search directly: +const knowledgeItems = await knowledgeService.getKnowledge( + message, // The message/query + { + roomId: runtime.agentId, + worldId: runtime.agentId, + entityId: runtime.agentId, + } +); +``` + +### Cloud/Custom Runtime Usage + +For cloud deployments or custom runtimes, use the core mode and access the service directly: + +```typescript +import { knowledgePluginCore, KnowledgeService } from '@elizaos/plugin-knowledge'; + +// In your cloud runtime setup +const runtime = await createRuntime({ + // ... your runtime config + plugins: [knowledgePluginCore], // Core mode: no routes, no UI +}); + +// Access the service +const knowledgeService = runtime.getService(KnowledgeService.serviceType); + +// Add documents +await knowledgeService.addKnowledge({ agentId: runtime.agentId, - limit: 10, + clientDocumentId: '' as UUID, + content: base64Content, + contentType: 'application/pdf', + originalFilename: 'company-docs.pdf', + worldId: runtime.agentId, + roomId: runtime.agentId, + entityId: runtime.agentId, }); + +// The knowledge provider will automatically inject relevant context +// into the agent's conversations based on the query ``` diff --git a/__tests__/plugin-exports.test.ts b/__tests__/plugin-exports.test.ts new file mode 100644 index 0000000..9d04fa4 --- /dev/null +++ b/__tests__/plugin-exports.test.ts @@ -0,0 +1,106 @@ +import { describe, it, expect } from 'bun:test'; +import { + knowledgePlugin, + knowledgePluginCore, + knowledgePluginHeadless, + createKnowledgePlugin, + KnowledgeService, + knowledgeProvider, + type KnowledgePluginConfig, +} from '../src/index'; + +describe('Knowledge Plugin Exports', () => { + it('should export the default full plugin', () => { + expect(knowledgePlugin).toBeDefined(); + expect(knowledgePlugin.name).toBe('knowledge'); + expect(knowledgePlugin.services).toBeDefined(); + expect(knowledgePlugin.providers).toBeDefined(); + expect(knowledgePlugin.routes).toBeDefined(); + expect(knowledgePlugin.actions).toBeDefined(); + expect(knowledgePlugin.tests).toBeDefined(); + }); + + it('should export the core plugin (service + provider only)', () => { + expect(knowledgePluginCore).toBeDefined(); + expect(knowledgePluginCore.name).toBe('knowledge'); + expect(knowledgePluginCore.services).toBeDefined(); + expect(knowledgePluginCore.providers).toBeDefined(); + expect(knowledgePluginCore.routes).toBeUndefined(); + expect(knowledgePluginCore.actions).toBeUndefined(); + expect(knowledgePluginCore.tests).toBeUndefined(); + }); + + it('should export the headless plugin (service + provider + actions)', () => { + expect(knowledgePluginHeadless).toBeDefined(); + expect(knowledgePluginHeadless.name).toBe('knowledge'); + expect(knowledgePluginHeadless.services).toBeDefined(); + expect(knowledgePluginHeadless.providers).toBeDefined(); + expect(knowledgePluginHeadless.actions).toBeDefined(); + expect(knowledgePluginHeadless.routes).toBeUndefined(); + expect(knowledgePluginHeadless.tests).toBeUndefined(); + }); + + it('should export the createKnowledgePlugin factory function', () => { + expect(createKnowledgePlugin).toBeDefined(); + expect(typeof createKnowledgePlugin).toBe('function'); + }); + + it('should create a custom plugin with specific configuration', () => { + const customPlugin = createKnowledgePlugin({ + enableUI: false, + enableRoutes: false, + enableActions: true, + enableTests: false, + }); + + expect(customPlugin).toBeDefined(); + expect(customPlugin.name).toBe('knowledge'); + expect(customPlugin.services).toBeDefined(); + expect(customPlugin.providers).toBeDefined(); + expect(customPlugin.actions).toBeDefined(); + expect(customPlugin.routes).toBeUndefined(); + expect(customPlugin.tests).toBeUndefined(); + }); + + it('should export KnowledgeService class', () => { + expect(KnowledgeService).toBeDefined(); + expect(KnowledgeService.serviceType).toBe('knowledge'); + }); + + it('should export knowledgeProvider', () => { + expect(knowledgeProvider).toBeDefined(); + expect(knowledgeProvider.name).toBe('KNOWLEDGE'); + }); + + it('should create plugin with all features enabled by default', () => { + const defaultPlugin = createKnowledgePlugin(); + + expect(defaultPlugin.services).toBeDefined(); + expect(defaultPlugin.providers).toBeDefined(); + expect(defaultPlugin.routes).toBeDefined(); + expect(defaultPlugin.actions).toBeDefined(); + expect(defaultPlugin.tests).toBeDefined(); + }); + + it('should create plugin with only UI disabled', () => { + const noUIPlugin = createKnowledgePlugin({ + enableUI: false, + enableRoutes: true, + enableActions: true, + enableTests: true, + }); + + expect(noUIPlugin.routes).toBeDefined(); // Routes still enabled + expect(noUIPlugin.actions).toBeDefined(); + expect(noUIPlugin.tests).toBeDefined(); + }); + + it('should create plugin with no routes when both UI and routes disabled', () => { + const noRoutesPlugin = createKnowledgePlugin({ + enableUI: false, + enableRoutes: false, + }); + + expect(noRoutesPlugin.routes).toBeUndefined(); + }); +}); diff --git a/package.json b/package.json index 8eabd4c..5798819 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@elizaos/plugin-knowledge", "description": "Plugin for Knowledge", - "version": "1.5.11", + "version": "1.5.12", "type": "module", "main": "dist/index.js", "module": "dist/index.js", diff --git a/src/index.ts b/src/index.ts index a70f175..9686a57 100644 --- a/src/index.ts +++ b/src/index.ts @@ -12,19 +12,136 @@ import { knowledgeActions } from './actions'; import { knowledgeRoutes } from './routes'; /** - * Knowledge Plugin - Provides Retrieval Augmented Generation capabilities - */ -export const knowledgePlugin: Plugin = { - name: 'knowledge', - description: - 'Plugin for Retrieval Augmented Generation, including knowledge management and embedding.', - services: [KnowledgeService], - providers: [knowledgeProvider], - routes: knowledgeRoutes, - actions: knowledgeActions, - tests: [knowledgeTestSuite], -}; + * Configuration options for the Knowledge Plugin + */ +export interface KnowledgePluginConfig { + /** + * Enable frontend UI and routes + * Set to false for cloud/server-only deployments + * @default true + */ + enableUI?: boolean; + + /** + * Enable HTTP routes for document management + * Set to false for browser-only or minimal deployments + * @default true + */ + enableRoutes?: boolean; + + /** + * Enable actions (PROCESS_KNOWLEDGE, SEARCH_KNOWLEDGE) + * @default true + */ + enableActions?: boolean; + + /** + * Enable tests + * @default true + */ + enableTests?: boolean; +} + +/** + * Create a Knowledge Plugin with custom configuration + * @param config Plugin configuration options + * @returns Configured Plugin instance + * + * @example + * // Cloud runtime mode (service + provider only) + * const plugin = createKnowledgePlugin({ + * enableUI: false, + * enableRoutes: false, + * }); + * + * @example + * // Browser-only mode (no routes) + * const plugin = createKnowledgePlugin({ + * enableRoutes: false, + * }); + * + * @example + * // Full mode (default) + * const plugin = createKnowledgePlugin(); + */ +export function createKnowledgePlugin(config: KnowledgePluginConfig = {}): Plugin { + const { enableUI = true, enableRoutes = true, enableActions = true, enableTests = true } = config; + + // Build plugin based on configuration + const plugin: Plugin = { + name: 'knowledge', + description: + 'Plugin for Retrieval Augmented Generation, including knowledge management and embedding.', + services: [KnowledgeService], + providers: [knowledgeProvider], + }; + + // Add routes only if UI or routes are enabled + if (enableUI || enableRoutes) { + plugin.routes = knowledgeRoutes; + logger.debug('[Knowledge Plugin] Routes enabled'); + } else { + logger.info('[Knowledge Plugin] Running in headless mode (no routes or UI)'); + } + // Add actions if enabled + if (enableActions) { + plugin.actions = knowledgeActions; + } + + // Add tests if enabled + if (enableTests) { + plugin.tests = [knowledgeTestSuite]; + } + + return plugin; +} + +/** + * Knowledge Plugin - Core mode (Service + Provider only) + * Use this for cloud runtimes or minimal deployments + */ +export const knowledgePluginCore: Plugin = createKnowledgePlugin({ + enableUI: false, + enableRoutes: false, + enableActions: false, + enableTests: false, +}); + +/** + * Knowledge Plugin - Headless mode (Service + Provider + Actions, no UI) + * Use this for server deployments without frontend + */ +export const knowledgePluginHeadless: Plugin = createKnowledgePlugin({ + enableUI: false, + enableRoutes: false, + enableActions: true, + enableTests: false, +}); + +/** + * Knowledge Plugin - Full mode (default) + * Includes everything: Service, Provider, Actions, Routes, UI, Tests + */ +export const knowledgePlugin: Plugin = createKnowledgePlugin({ + enableUI: true, + enableRoutes: true, + enableActions: true, + enableTests: true, +}); + +/** + * Default export - Full plugin for backward compatibility + */ export default knowledgePlugin; +/** + * Export all types and utilities + */ export * from './types'; + +/** + * Export service and provider for direct use + */ +export { KnowledgeService } from './service'; +export { knowledgeProvider } from './provider';