From 5e9d31501d760ee7af2cb9ab40de4269c30791ca Mon Sep 17 00:00:00 2001 From: pann0x Date: Thu, 9 Jan 2025 20:27:15 -0800 Subject: [PATCH] feat: dad jokes --- packages/plugin-dad-joke/README.md | 13 ++++ packages/plugin-dad-joke/package.json | 20 ++++++ packages/plugin-dad-joke/src/action.ts | 78 +++++++++++++++++++++++ packages/plugin-dad-joke/src/evaluator.ts | 71 +++++++++++++++++++++ packages/plugin-dad-joke/src/index.ts | 20 ++++++ packages/plugin-dad-joke/src/provider.ts | 54 ++++++++++++++++ packages/plugin-dad-joke/src/types.ts | 33 ++++++++++ packages/plugin-dad-joke/tsconfig.json | 10 +++ packages/plugin-dad-joke/tsup.config.ts | 20 ++++++ 9 files changed, 319 insertions(+) create mode 100644 packages/plugin-dad-joke/README.md create mode 100644 packages/plugin-dad-joke/package.json create mode 100644 packages/plugin-dad-joke/src/action.ts create mode 100644 packages/plugin-dad-joke/src/evaluator.ts create mode 100644 packages/plugin-dad-joke/src/index.ts create mode 100644 packages/plugin-dad-joke/src/provider.ts create mode 100644 packages/plugin-dad-joke/src/types.ts create mode 100644 packages/plugin-dad-joke/tsconfig.json create mode 100644 packages/plugin-dad-joke/tsup.config.ts diff --git a/packages/plugin-dad-joke/README.md b/packages/plugin-dad-joke/README.md new file mode 100644 index 00000000000..39fe10eca2e --- /dev/null +++ b/packages/plugin-dad-joke/README.md @@ -0,0 +1,13 @@ +# Dad Joke Plugin for Eliza + +Ask for a dad joke! + +This plugin was solely made for resarech and learning purposes. Feel free to use this as reference! Happy coding ☕️ + +## Contributing + +Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) for details. + +## License + +Built by [@pann0x](https://twitter.com/pann0x) on X. diff --git a/packages/plugin-dad-joke/package.json b/packages/plugin-dad-joke/package.json new file mode 100644 index 00000000000..21e01f5e19f --- /dev/null +++ b/packages/plugin-dad-joke/package.json @@ -0,0 +1,20 @@ +{ + "name": "@elizaos/plugin-dad-joke", + "version": "0.1.0", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "type": "module", + "scripts": { + "build": "tsup --format esm --dts", + "dev": "tsc -w", + "lint": "eslint src --ext .ts" + }, + "author": "pann0x", + "license": "MIT", + "dependencies": { + "@ai16z/client-direct": "0.1.6-alpha.4", + "@ai16z/eliza": "0.1.6-alpha.4", + "@ai16z/plugin-0g": "0.1.6-alpha.4", + "dotenv": "^16.4.7" + } +} diff --git a/packages/plugin-dad-joke/src/action.ts b/packages/plugin-dad-joke/src/action.ts new file mode 100644 index 00000000000..ea62eebd656 --- /dev/null +++ b/packages/plugin-dad-joke/src/action.ts @@ -0,0 +1,78 @@ +import {Action, IAgentRuntime, Memory, State} from "@ai16z/eliza"; +import { dadJokeActionContent, dadJokeData } from "./types.ts"; +import { dadJokeProvider } from "./provider.ts"; + +export const getDadJokeAction: Action = { + name: "GET_DAD_JOKE", + description: "Retrieves a random dad joke", + similes: [ + "DAD_JOKE", + "JOKE", + ], + examples: [ + [ + { + user: "{{user1}}", + content: { + text: "Tell me a dad joke", + } as dadJokeActionContent, + }, + { + user: "{{agentName}}", + content: { + text: "Why couldn't the bicycle stand up by itself? It was two tired.", + action: "GET_DAD_JOKE", + }, + }, + + ], + [ + { + user: "{{user1}}", + content: { + text: "You got any dad jokes?", + } as dadJokeActionContent, + }, + { + user: "{{agentName}}", + content: { + text: "What do you call a fake noodle? An impasta.", + action: "GET_DAD_JOKE", + }, + }, + ], + ], + + validate: async ( + runtime: IAgentRuntime, + message: Memory, + state?: State, + ): Promise => { + try { + const content = message.content as dadJokeActionContent; + return ( + typeof content.text === "string" && + content.text.toLowerCase().includes("joke") + ); + } catch { + return false; + } + }, + + handler: async ( + runtime: IAgentRuntime, + message: Memory, + state?: State, + ): Promise => { + try { + const response = await dadJokeProvider.get(runtime, message, state); + if (!response.success) { + throw new Error(response.error); + } + + return response.data; + } catch (error) { + throw new Error(error instanceof Error ? error.message : "Failed to retrieve dad joke"); + } + } +} \ No newline at end of file diff --git a/packages/plugin-dad-joke/src/evaluator.ts b/packages/plugin-dad-joke/src/evaluator.ts new file mode 100644 index 00000000000..d936951e027 --- /dev/null +++ b/packages/plugin-dad-joke/src/evaluator.ts @@ -0,0 +1,71 @@ +import { Evaluator, IAgentRuntime, Memory, State } from "@ai16z/eliza"; +import { dadJokeEvalContent, dadJokeEvalResponse } from "./types.ts"; + +//the evaluator for dad jokes +//validates the response to ensure it is a dad joke +export const dadJokeEvaluator: Evaluator = { + name: "DAD_JOKE_EVALUATOR", + description: "Validates dad joke responses", + similes: [ + "DAD_JOKE_CHECKER", + "JOKE_VALIDATOR", + "DAD_JOKE_RESPONSE_VALIDATOR", + ], + examples: [ + { + context: "Validating complete dad joke response", + messages: [ + { + user: "{{user1}}", + content: { + text: "When does a joke become a dad joke? When the punchline becomes apparent.", + }, + }, + ], + outcome: "When it becomes a groan-up.", + }, + ], + validate: async ( + runtime: IAgentRuntime, + message: Memory, + state?: State, + ): Promise => { + try { + const content = message.content as dadJokeEvalContent; + return typeof content.text === "string"; + } catch { + return false; + } + }, + + handler: async ( + runtime: IAgentRuntime, + message: Memory, + state?: State, + ): Promise => { + try { + const content = message.content as dadJokeEvalContent; + const text = content.text.toLowerCase(); + + //checks for the word "joke" in the response + if (!text.includes("joke")) { + return { + success: false, + response: "Response does not contain the word 'joke'", + }; + } + + return { + success: true, + response: "Dad joke response is valid", + }; + + } catch { + return { + success: false, + response: "Failed to validate dad joke response", + }; + } + }, + alwaysRun: true, +} \ No newline at end of file diff --git a/packages/plugin-dad-joke/src/index.ts b/packages/plugin-dad-joke/src/index.ts new file mode 100644 index 00000000000..4560c47a76a --- /dev/null +++ b/packages/plugin-dad-joke/src/index.ts @@ -0,0 +1,20 @@ +import { Plugin } from "@ai16z/eliza"; +import { dadJokeProvider, initializeDadJokeProvider } from "./provider.ts"; +import { dadJokeEvaluator } from "./evaluator.ts"; +import { dadJokeConfig } from "./types.ts"; +import { getDadJokeAction } from "./action.ts"; + +export const dadJokePlugin: Plugin = { + name: "Dad Joke", + description: "Dad Joke Plugin for Eliza", + actions: [ + getDadJokeAction + ], + providers: [dadJokeProvider], + evaluators: [dadJokeEvaluator], + //rest of the plugin +} + +export const initializeDadJoke = (config: dadJokeConfig): void => { + initializeDadJokeProvider(config); +} \ No newline at end of file diff --git a/packages/plugin-dad-joke/src/provider.ts b/packages/plugin-dad-joke/src/provider.ts new file mode 100644 index 00000000000..1b351c17c58 --- /dev/null +++ b/packages/plugin-dad-joke/src/provider.ts @@ -0,0 +1,54 @@ +import { IAgentRuntime, Memory, State, Provider } from "@ai16z/eliza"; +import { dadJokeProviderResponse, dadJokeData, dadJokeConfig} from "./types.ts"; + +let providerConfig: dadJokeConfig; + +export const dadJokeProvider: Provider = { + get: async ( + runtime: IAgentRuntime, + message: Memory, + state?: State, + ): Promise => { + try { + if (!providerConfig?.provider?.baseUrl) { + throw new Error("Dad Joke API url is required"); + } + + const baseUrl = + providerConfig.provider.baseUrl || + "https://icanhazdadjoke.com"; + + // Fetch dad joke + const response = await fetch(baseUrl, { + headers: { + Accept: "application/json", + }, + }); + + if (!response.ok) { + throw new Error(`API request failed: ${response.statusText}`); + } + + const data = await response.json(); + + // Transform API response to dadJokeData + const dadJokeData: dadJokeData = { + joke: data.joke, + }; + + return { + success: true, + data: dadJokeData, + }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error.message : "Failed to retrieve dad joke", + }; + } + } +} + +export const initializeDadJokeProvider = (config: dadJokeConfig): void => { + providerConfig = config; +} \ No newline at end of file diff --git a/packages/plugin-dad-joke/src/types.ts b/packages/plugin-dad-joke/src/types.ts new file mode 100644 index 00000000000..a17b755819b --- /dev/null +++ b/packages/plugin-dad-joke/src/types.ts @@ -0,0 +1,33 @@ +import { Content } from '@ai16z/eliza'; + +export interface dadJokeConfig { + provider: { + apiKey: string; + baseUrl?: string; + options?: string; + }; +} + +export interface dadJokeData { + joke: string; + //image?: ; +} + +export interface dadJokeActionContent extends Content { + text: string; +} + +export interface dadJokeEvalContent extends Content { + text: string; +} + +export interface dadJokeEvalResponse { + success: boolean; + response: string; +} + +export interface dadJokeProviderResponse { + success: boolean; + data?: dadJokeData; + error?: string; +} \ No newline at end of file diff --git a/packages/plugin-dad-joke/tsconfig.json b/packages/plugin-dad-joke/tsconfig.json new file mode 100644 index 00000000000..b98954f213e --- /dev/null +++ b/packages/plugin-dad-joke/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../core/tsconfig.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src" + }, + "include": [ + "src" + ] +} \ No newline at end of file diff --git a/packages/plugin-dad-joke/tsup.config.ts b/packages/plugin-dad-joke/tsup.config.ts new file mode 100644 index 00000000000..e42bf4efeae --- /dev/null +++ b/packages/plugin-dad-joke/tsup.config.ts @@ -0,0 +1,20 @@ +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", + // Add other modules you want to externalize + ], +});