Skip to content

Commit

Permalink
Merge branch 'tcm-tavily' of http://github.com/ai16z/eliza into HEAD
Browse files Browse the repository at this point in the history
  • Loading branch information
lalalune committed Nov 29, 2024
2 parents 1aeaab2 + 529328f commit 5d94e98
Show file tree
Hide file tree
Showing 9 changed files with 295 additions and 4 deletions.
2 changes: 1 addition & 1 deletion packages/client-direct/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ export class DirectClient {
);

if (message) {
res.json([message, response]);
res.json([response, message]);
} else {
res.json([response]);
}
Expand Down
34 changes: 34 additions & 0 deletions packages/core/src/generation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
ModelClass,
ModelProviderName,
ServiceType,
SearchResponse,
} from "./types.ts";
import { fal, } from "@fal-ai/client";

Expand Down Expand Up @@ -972,6 +973,39 @@ export const generateCaption = async (
description: resp.description.trim(),
};
};

export const generateWebSearch = async (
query: string,
runtime: IAgentRuntime
): Promise<SearchResponse> => {
const apiUrl = "https://api.tavily.com/search";
const apiKey = runtime.getSetting("TAVILY_API_KEY");

try {
const response = await fetch(apiUrl, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
api_key: apiKey,
query,
include_answer: true,
}),
});

if (!response.ok) {
throw new elizaLogger.error(
`HTTP error! status: ${response.status}`
);
}

const data: SearchResponse = await response.json();
return data;
} catch (error) {
elizaLogger.error("Error:", error);
}
};
/**
* Configuration options for generating objects with a model.
*/
Expand Down
17 changes: 17 additions & 0 deletions packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1100,6 +1100,23 @@ export interface IPdfService extends Service {
convertPdfToText(pdfBuffer: Buffer): Promise<string>;
}

export type SearchResult = {
title: string;
url: string;
content: string;
score: number;
raw_content: string | null;
};

export type SearchResponse = {
query: string;
follow_up_questions: string[] | null;
answer: string | null;
images: string[];
results: SearchResult[];
response_time: number;
};

export enum ServiceType {
IMAGE_DESCRIPTION = "image_description",
TRANSCRIPTION = "transcription",
Expand Down
6 changes: 6 additions & 0 deletions packages/plugin-web-search/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
*

!dist/**
!package.json
!readme.md
!tsup.config.ts
17 changes: 17 additions & 0 deletions packages/plugin-web-search/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "@ai16z/plugin-web-search",
"version": "0.1.3",
"main": "dist/index.js",
"type": "module",
"types": "dist/index.d.ts",
"dependencies": {
"@ai16z/eliza": "workspace:*",
"tsup": "^8.3.5"
},
"scripts": {
"build": "tsup --format esm --dts"
},
"peerDependencies": {
"whatwg-url": "7.1.0"
}
}
188 changes: 188 additions & 0 deletions packages/plugin-web-search/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
import { elizaLogger } from "@ai16z/eliza";
import {
Action,
HandlerCallback,
IAgentRuntime,
Memory,
Plugin,
State,
} from "@ai16z/eliza";
import { generateWebSearch } from "@ai16z/eliza";

import { SearchResult } from "@ai16z/eliza";

const webSearch: Action = {
name: "WEB_SEARCH",
similes: [
"SEARCH_WEB",
"INTERNET_SEARCH",
"LOOKUP",
"QUERY_WEB",
"FIND_ONLINE",
"SEARCH_ENGINE",
"WEB_LOOKUP",
"ONLINE_SEARCH",
"FIND_INFORMATION",
],
description:
"Perform a web search to find information related to the message.",
validate: async (runtime: IAgentRuntime, message: Memory) => {
const tavilyApiKeyOk = !!runtime.getSetting("TAVILY_API_KEY");

return tavilyApiKeyOk;
},
handler: async (
runtime: IAgentRuntime,
message: Memory,
state: State,
options: any,
callback: HandlerCallback
) => {
elizaLogger.log("Composing state for message:", message);
state = (await runtime.composeState(message)) as State;
const userId = runtime.agentId;
elizaLogger.log("User ID:", userId);

const webSearchPrompt = message.content.text;
elizaLogger.log("web search prompt received:", webSearchPrompt);

elizaLogger.log("Generating image with prompt:", webSearchPrompt);
const searchResponse = await generateWebSearch(
webSearchPrompt,
runtime
);

if (searchResponse && searchResponse.results.length) {
const responseList = searchResponse.answer
? `${searchResponse.answer}${
Array.isArray(searchResponse.results) &&
searchResponse.results.length > 0
? `\n\nFor more details, you can check out these resources:\n${searchResponse.results
.map(
(result: SearchResult, index: number) =>
`${index + 1}. [${result.title}](${result.url})`
)
.join("\n")}`
: ""
}`
: "";

callback({
text: responseList,
});
} else {
elizaLogger.error("search failed or returned no data.");
}
},
examples: [
[
{
user: "{{user1}}",
content: {
text: "Find the latest news about SpaceX launches.",
},
},
{
user: "{{agentName}}",
content: {
text: "Here is the latest news about SpaceX launches:",
action: "WEB_SEARCH",
},
},
],
[
{
user: "{{user1}}",
content: {
text: "Can you find details about the iPhone 16 release?",
},
},
{
user: "{{agentName}}",
content: {
text: "Here are the details I found about the iPhone 16 release:",
action: "WEB_SEARCH",
},
},
],
[
{
user: "{{user1}}",
content: {
text: "What is the schedule for the next FIFA World Cup?",
},
},
{
user: "{{agentName}}",
content: {
text: "Here is the schedule for the next FIFA World Cup:",
action: "WEB_SEARCH",
},
},
],
[
{
user: "{{user1}}",
content: { text: "Check the latest stock price of Tesla." },
},
{
user: "{{agentName}}",
content: {
text: "Here is the latest stock price of Tesla I found:",
action: "WEB_SEARCH",
},
},
],
[
{
user: "{{user1}}",
content: {
text: "What are the current trending movies in the US?",
},
},
{
user: "{{agentName}}",
content: {
text: "Here are the current trending movies in the US:",
action: "WEB_SEARCH",
},
},
],
[
{
user: "{{user1}}",
content: {
text: "What is the latest score in the NBA finals?",
},
},
{
user: "{{agentName}}",
content: {
text: "Here is the latest score from the NBA finals:",
action: "WEB_SEARCH",
},
},
],
[
{
user: "{{user1}}",
content: { text: "When is the next Apple keynote event?" },
},
{
user: "{{agentName}}",
content: {
text: "Here is the information about the next Apple keynote event:",
action: "WEB_SEARCH",
},
},
],
],
} as Action;

export const webSearchPlugin: Plugin = {
name: "webSearch",
description: "Search web",
actions: [webSearch],
evaluators: [],
providers: [],
};
9 changes: 9 additions & 0 deletions packages/plugin-web-search/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": "src",
"types": ["node"]
},
"include": ["src/**/*.ts"]
}
21 changes: 21 additions & 0 deletions packages/plugin-web-search/tsup.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { defineConfig } from "tsup";

export default defineConfig({
entry: ["src/index.ts"],
outDir: "dist",
sourcemap: true,
clean: true,
format: ["esm"], // Ensure you're targeting CommonJS
external: [
"dotenv", // Externalize dotenv to prevent bundling
"fs", // Externalize fs to use Node.js built-in module
"path", // Externalize other built-ins if necessary
"@reflink/reflink",
"@node-llama-cpp",
"https",
"http",
"agentkeepalive",
"zod",
// Add other modules you want to externalize
],
});
5 changes: 2 additions & 3 deletions scripts/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,15 @@ PACKAGES=(
"plugin-bootstrap"
"plugin-image-generation"
"plugin-coinbase"
"plugin-node"
"plugin-bootstrap"
"plugin-evm"
"plugin-image-generation"
"plugin-tee"
"client-auto"
"client-direct"
"client-discord"
"client-telegram"
"client-twitter"
"client-whatsapp"
"plugin-web-search"
)

# Build packages in specified order
Expand Down

0 comments on commit 5d94e98

Please sign in to comment.