Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add GitBook Plugin provider #1126

Merged
merged 24 commits into from
Dec 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
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: 2 additions & 0 deletions agent/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"@elizaos/plugin-conflux": "workspace:*",
"@elizaos/plugin-evm": "workspace:*",
"@elizaos/plugin-flow": "workspace:*",
"@elizaos/plugin-gitbook": "workspace:*",
"@elizaos/plugin-story": "workspace:*",
"@elizaos/plugin-goat": "workspace:*",
"@elizaos/plugin-icp": "workspace:*",
Expand All @@ -64,3 +65,4 @@
"tsup": "8.3.5"
}
}

7 changes: 7 additions & 0 deletions packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -783,6 +783,13 @@ export type Character = {
shouldIgnoreBotMessages?: boolean;
shouldIgnoreDirectMessages?: boolean;
};
gitbook?: {
keywords?: {
projectTerms?: string[];
generalQueries?: string[];
};
documentTriggers?: string[];
};
};

/** Writing style guides */
Expand Down
25 changes: 25 additions & 0 deletions packages/plugin-gitbook/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "@elizaos/plugin-gitbook",
"version": "0.1.0",
"main": "dist/index.js",
"type": "module",
"types": "dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.js",
"types": "./dist/index.d.ts"
}
},
"files": [
"dist"
],
"dependencies": {
"@elizaos/core": "workspace:*",
"tsup": "8.3.5"
},
"scripts": {
"build": "tsup --format esm --dts",
"dev": "tsup --format esm --dts --watch",
"test": "vitest"
}
}
14 changes: 14 additions & 0 deletions packages/plugin-gitbook/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Plugin } from "@elizaos/core";
import { gitbookProvider } from "./providers/gitbook";

export const gitbookPlugin: Plugin = {
name: "GitBook Documentation",
description: "Plugin for querying GitBook documentation",
actions: [],
providers: [gitbookProvider],
evaluators: []
};

export default gitbookPlugin;

export * from './types';
112 changes: 112 additions & 0 deletions packages/plugin-gitbook/src/providers/gitbook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { Provider, IAgentRuntime, Memory, State, elizaLogger } from "@elizaos/core";
import { GitBookResponse, GitBookClientConfig } from '../types';

function cleanText(text: string): string {
const cleaned = text
.replace(/<@!?\d+>/g, '') // Discord mentions
.replace(/<#\d+>/g, '') // Discord channels
.replace(/<@&\d+>/g, '') // Discord roles
.replace(/(?:^|\s)@[\w_]+/g, '') // Platform mentions
.trim();

return cleaned;
}

async function validateQuery(runtime: IAgentRuntime, text: string): Promise<boolean> {
// Default general queries - everything else comes from config
let keywords = {
generalQueries: [
'how', 'what', 'where', 'explain', 'show', 'tell',
'can', 'does', 'is', 'are', 'will', 'why',
'benefits', 'features', 'cost', 'price',
'use', 'using', 'work', 'access', 'get'
]
};

try {
const gitbookConfig = runtime.character.clientConfig?.gitbook as GitBookClientConfig;

// Get project terms and document triggers from config
const projectTerms = gitbookConfig?.keywords?.projectTerms || [];
const documentTriggers = gitbookConfig?.documentTriggers || [];

// Merge any additional general queries from config
if (gitbookConfig?.keywords?.generalQueries) {
keywords.generalQueries = [
...keywords.generalQueries,
...gitbookConfig.keywords.generalQueries
];
}

const containsAnyWord = (text: string, words: string[] = []) => {
return words.length === 0 || words.some(word => {
if (word.includes(' ')) {
return text.includes(word.toLowerCase());
}
const regex = new RegExp(`\\b${word}\\b`, 'i');
return regex.test(text);
});
};

const hasProjectTerm = containsAnyWord(text, projectTerms);
const hasDocTrigger = containsAnyWord(text, documentTriggers);
const hasGeneralQuery = containsAnyWord(text, keywords.generalQueries);

const isValid = hasProjectTerm || hasDocTrigger || hasGeneralQuery;

elizaLogger.info(`✅ Is GitBook Validation Result: ${isValid}`)
return isValid;

} catch (error) {
elizaLogger.warn(`❌ Error in GitBook validation:\n${error}`)
return false;
}
}

export const gitbookProvider: Provider = {
get: async (runtime: IAgentRuntime, message: Memory, _state?: State): Promise<string> => {
try {
const spaceId = runtime.getSetting("GITBOOK_SPACE_ID");
if (!spaceId) {
elizaLogger.error('⚠️ GitBook Space ID not configured')
return "";
}

const text = message.content.text.toLowerCase().trim();
const isValidQuery = await validateQuery(runtime, text);

if (!isValidQuery) {
elizaLogger.info('⚠️ GitBook Query validation failed')
return "";
}

const cleanedQuery = cleanText(message.content.text);

const response = await fetch(
`https://api.gitbook.com/v1/spaces/${spaceId}/search/ask`,
{
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
query: cleanedQuery,
variables: {}
})
}
);

if (!response.ok) {
console.error('❌ GitBook API error:', response.status);
return "";
}

const result: GitBookResponse = await response.json();

return result.answer?.text || "";
} catch (error) {
console.error("❌ Error in GitBook provider:", error);
return "";
}
}
};
18 changes: 18 additions & 0 deletions packages/plugin-gitbook/src/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// GitBook API response type
export interface GitBookResponse {
answer?: {
text: string;
};
error?: string;
}

// Client configuration in character.json (all optional)
export interface GitBookKeywords {
projectTerms?: string[];
generalQueries?: string[];
}

export interface GitBookClientConfig {
keywords?: GitBookKeywords;
documentTriggers?: string[];
}
13 changes: 13 additions & 0 deletions packages/plugin-gitbook/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"extends": "../core/tsconfig.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": ".",
"types": [
"node"
]
},
"include": [
"src"
]
}
12 changes: 12 additions & 0 deletions packages/plugin-gitbook/tsup.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { defineConfig } from "tsup";

export default defineConfig({
entry: ["src/index.ts"],
outDir: "dist",
sourcemap: true,
clean: true,
format: ["esm"],
external: [
"@elizaos/core"
],
});
Loading