Skip to content

Commit

Permalink
add plugin-perplexica/src
Browse files Browse the repository at this point in the history
  • Loading branch information
boliang_zhang committed Feb 2, 2025
1 parent 10fbbc1 commit 58ab449
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 2 deletions.
2 changes: 0 additions & 2 deletions packages/client-telegram/src/templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,6 @@ Note that {{agentName}} is capable of reading/seeing/hearing various forms of me
{{recentMessages}}
{{searchResult}}
# Task: Generate a post/reply in the voice, style and perspective of {{agentName}} (@{{twitterUserName}}) while using the thread of tweets as additional context:
Current Post:
{{currentPost}}
Expand Down
12 changes: 12 additions & 0 deletions packages/plugin-perplexica/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {
Plugin
} from "@elizaos/core";
import { PerplexicaSearchService } from "./search_service";

export const PerplexicaSearchPlugin: Plugin = {
name: "perplexicaSearch",
description: "Search the web with Perplexica search engine",
services: [new PerplexicaSearchService()],
};

export default PerplexicaSearchPlugin;
144 changes: 144 additions & 0 deletions packages/plugin-perplexica/src/search_service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import {
Memory,
Actor,
elizaLogger,
Character,
Service,
IAgentRuntime,
ServiceType
} from "@elizaos/core";

export interface IPerplexicaSearchService extends Service {
settings: {
[key: string]: string;
};
search(
query: string,
messages?: Memory[],
actors?: Actor[],
character?: Character,
optimizationMode?: string,
focusMode?: string,
): Promise<PerplexicaSearchResponse>;
}


export class PerplexicaSearchService extends Service implements IPerplexicaSearchService {
settings: {[key: string]: string;};

static get serviceType(): ServiceType {
return ServiceType.PERPLEXICA_SEARCH;
}

async initialize(runtime: IAgentRuntime): Promise<void> {
this.settings = {
modelProvider: runtime.getSetting('PERPLEXICA_MODEL_PROVIDER') || 'openai',
modelName: runtime.getSetting('PERPLEXICA_MODEL_NAME') || 'gpt-4',
embeddingModelProvider: runtime.getSetting('PERPLEXICA_EMBEDDING_MODEL_PROVIDER') || 'openai',
embeddingModelName: runtime.getSetting('PERPLEXICA_EMBEDDING_MODEL_NAME') || 'text-embedding-3-large',
apiUrl: runtime.getSetting('PERPLEXICA_API_URL') || 'http://localhost:3001/api/search',
}
}

async search(
query: string,
messages?: Memory[],
actors?: Actor[],
character?: Character,
optimizationMode: 'speed' | 'balanced' | 'quality' = 'speed',
focusMode: 'webSearch' | 'academicSearch' | 'writingAssistant' | 'wolframAlphaSearch' | 'youtubeSearch' | 'redditSearch' = 'webSearch',
): Promise<PerplexicaSearchResponse> {
const history = formatPerplexicaSearchHistory(messages, actors, character?.name);

elizaLogger.debug("Searching with Perplexica:\n",
query, history, this.settings.optimizationMode, this.settings.focusMode);

try {
const searchRequest: SearchRequest = {
chatModel: {
provider: this.settings.modelProvider,
model: this.settings.modelName,
},
embeddingModel: {
provider: this.settings.embeddingModelProvider,
model: this.settings.embeddingModelName,
},
optimizationMode: optimizationMode,
focusMode: focusMode,
query,
history: history || []
};
elizaLogger.debug('Search request:', searchRequest);

const response = await fetch(this.settings.apiUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify(searchRequest),
});

if (!response.ok) {
const errorText = await response.text();
elizaLogger.error('Response error:', errorText);
throw new Error(`HTTP error! status: ${response.status}, message: ${errorText}`);
}

const data = await response.json();
elizaLogger.debug('Search response:', data);
return data;
} catch (error) {
elizaLogger.error('Error searching Perplexica:', error);
return {
message: 'Unknown error occurred',
sources: []
};
}
}
}

interface ChatModel {
provider: string;
model: string;
}

interface SearchRequest {
chatModel: ChatModel;
embeddingModel: ChatModel;
optimizationMode: string;
focusMode: string;
query: string;
history?: [string, string][];
}

export interface PerplexicaSearchResponse {
message: string;
sources: {
pageContent: string;
metadata: {
title: string;
url: string;
};
}[];
}

function formatPerplexicaSearchHistory(
messages: Memory[],
actors: Actor[],
agentName: string,
): [string, string][] {
return messages
.slice(0, 6) // limit to 6 messages
.reverse()
.filter((message) => message.userId)
.map((message) => {
const messageContent = message.content.text;
const formattedName =
actors.find((actor) => actor.id === message.userId)?.name === agentName
? "assistant"
: "human";

return [formattedName, messageContent];
});
}

0 comments on commit 58ab449

Please sign in to comment.