Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@elizaos/plugin-knowledge",
"description": "Plugin for Knowledge",
"version": "1.5.12",
"version": "1.5.13",
"type": "module",
"main": "dist/index.js",
"module": "dist/index.js",
Expand Down
121 changes: 121 additions & 0 deletions src/documents-provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import type { IAgentRuntime, Memory, Provider } from '@elizaos/core';
import { addHeader, logger, MemoryType } from '@elizaos/core';
import { KnowledgeService } from './service.ts';
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Remove file extension from import statement.

The .ts extension in the import path may cause module resolution issues in certain build configurations. TypeScript imports should typically omit the file extension.

Apply this diff:

-import { KnowledgeService } from './service.ts';
+import { KnowledgeService } from './service';
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { KnowledgeService } from './service.ts';
import { KnowledgeService } from './service';
🤖 Prompt for AI Agents
In src/documents-provider.ts around line 3, the import uses a '.ts' extension
which can break some module resolvers; remove the file extension so the line
reads import { KnowledgeService } from './service'; and save; ensure the
relative path still points to the same module and update any other imports
following this project convention if needed.


/**
* Represents a static provider that lists available documents in the knowledge base.
* This provider helps the agent understand which documents are available for retrieval.
* @type {Provider}
* @property {string} name - The name of the documents provider.
* @property {string} description - The description of the documents provider.
* @property {boolean} dynamic - Indicates if the provider is static (false).
* @property {Function} get - Asynchronously retrieves the list of available documents.
* @param {IAgentRuntime} runtime - The agent runtime object.
* @returns {Object} An object containing the available documents list.
*/
export const documentsProvider: Provider = {
name: 'AVAILABLE_DOCUMENTS',
description:
'List of documents available in the knowledge base. Shows which documents the agent can reference and retrieve information from.',
dynamic: false, // Static provider - doesn't change based on the message
get: async (runtime: IAgentRuntime) => {
try {
const knowledgeService = runtime.getService('knowledge') as KnowledgeService;

if (!knowledgeService) {
logger.warn('Knowledge service not available for documents provider');
return {
data: { documents: [] },
values: { documents: '' },
text: '',
};
}
Comment on lines +25 to +32
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Inconsistent error handling in return values.

When the knowledge service is unavailable (lines 25-32), the return object doesn't include an error field in data, but when an exception occurs (lines 112-119), it does. This inconsistency may confuse consumers trying to distinguish between "no documents available" and "error occurred."

Consider adding an error field when the service is unavailable:

 if (!knowledgeService) {
   logger.warn('Knowledge service not available for documents provider');
   return {
-    data: { documents: [] },
+    data: { documents: [], error: 'Knowledge service not available' },
     values: { documents: '' },
     text: '',
   };
 }

Also applies to: 112-119

🤖 Prompt for AI Agents
In src/documents-provider.ts around lines 25-32 (and similarly ensure
consistency with lines 112-119), the return value when the knowledge service is
unavailable lacks the data.error field that the exception path sets; update the
early-return object to include a data.error string (e.g. 'Knowledge service not
available') and keep the same shape as the error-return in the catch block so
consumers can reliably detect an error versus an empty result; make the message
explicit and ensure values and text remain as currently returned.


// Retrieve all documents for the agent
const allMemories = await knowledgeService.getMemories({
tableName: 'documents',
roomId: runtime.agentId,
count: 100, // Limit to 100 documents to avoid context overflow
});

// Filter to only documents (not fragments)
const documents = allMemories.filter(
(memory) => memory.metadata?.type === MemoryType.DOCUMENT
);

if (!documents || documents.length === 0) {
return {
data: { documents: [] },
values: { documents: '' },
text: '',
};
}

// Format documents concisely
const documentsList = documents
.map((doc, index) => {
const metadata = doc.metadata as any;
const filename = metadata?.filename || metadata?.title || `Document ${index + 1}`;
const fileType = metadata?.fileExt || metadata?.fileType || 'unknown';
const source = metadata?.source || 'upload';
const fileSize = metadata?.fileSize;

// Build description from metadata
const parts = [filename];

// Add file type info
if (fileType && fileType !== 'unknown') {
parts.push(fileType);
}

// Add file size if available
if (fileSize) {
const sizeKB = Math.round(fileSize / 1024);
if (sizeKB > 1024) {
parts.push(`${Math.round(sizeKB / 1024)}MB`);
} else {
parts.push(`${sizeKB}KB`);
}
}

// Add source if meaningful
if (source && source !== 'upload') {
parts.push(`from ${source}`);
}

// Format: "filename (type, size, source)"
return parts.join(' - ');
})
.join('\n');

const documentsText = addHeader(
'# Available Documents',
`${documents.length} document(s) in knowledge base:\n${documentsList}`
);

return {
data: {
documents: documents.map((doc) => ({
id: doc.id,
filename: (doc.metadata as any)?.filename || (doc.metadata as any)?.title,
fileType: (doc.metadata as any)?.fileType || (doc.metadata as any)?.fileExt,
source: (doc.metadata as any)?.source,
})),
count: documents.length,
},
values: {
documentsCount: documents.length,
documents: documentsList,
},
text: documentsText,
};
} catch (error: any) {
logger.error('Error in documents provider:', error.message);
return {
data: { documents: [], error: error.message },
values: { documents: '' },
text: '',
};
}
},
};
4 changes: 3 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type { Plugin, IAgentRuntime } from '@elizaos/core';
import { logger } from '@elizaos/core';
import { KnowledgeService } from './service';
import { knowledgeProvider } from './provider';
import { documentsProvider } from './documents-provider';
import knowledgeTestSuite from './tests';
import { knowledgeActions } from './actions';
import { knowledgeRoutes } from './routes';
Expand Down Expand Up @@ -73,7 +74,7 @@ export function createKnowledgePlugin(config: KnowledgePluginConfig = {}): Plugi
description:
'Plugin for Retrieval Augmented Generation, including knowledge management and embedding.',
services: [KnowledgeService],
providers: [knowledgeProvider],
providers: [knowledgeProvider, documentsProvider],
};

// Add routes only if UI or routes are enabled
Expand Down Expand Up @@ -145,3 +146,4 @@ export * from './types';
*/
export { KnowledgeService } from './service';
export { knowledgeProvider } from './provider';
export { documentsProvider } from './documents-provider';