From b6ccb59f6659741d9ce599f56a97f6bcd353c87a Mon Sep 17 00:00:00 2001 From: 9547 <29431502+9547@users.noreply.github.com> Date: Thu, 2 Jan 2025 14:25:30 +0800 Subject: [PATCH 01/34] chore(scripts): rename ai16z/eliza to elizaOS/eliza --- scripts/jsdoc-automation/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/jsdoc-automation/README.md b/scripts/jsdoc-automation/README.md index 9d9e141162..47a0d284bd 100644 --- a/scripts/jsdoc-automation/README.md +++ b/scripts/jsdoc-automation/README.md @@ -1,5 +1,5 @@ # Codebase Documentation -- https://github.com/ai16z/eliza/issues/1110 +- https://github.com/elizaOS/eliza/issues/1110 ## Set up - Set GH_PAT & OPENAI_API_KEY in github actions as env variables @@ -38,7 +38,7 @@ The `src/Configuration.ts` handles configuration loading from environment variab #### Default Values -- **Repository**: ai16z/eliza +- **Repository**: elizaOS/eliza - **Branch**: develop - **Commit Message**: "Generated JSDoc comments" - **PR Title**: "JSDoc Generation" From b1d72c43b597a8cc9fa4fe6eb144a61fd6a6a8fd Mon Sep 17 00:00:00 2001 From: 9547 <29431502+9547@users.noreply.github.com> Date: Thu, 2 Jan 2025 14:25:41 +0800 Subject: [PATCH 02/34] chore(docs): rename ai16z/eliza to elizaOS/eliza --- .../Discord/the_arena/memes-and-marketing/chat_2024-11-14.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/community/Discord/the_arena/memes-and-marketing/chat_2024-11-14.md b/docs/community/Discord/the_arena/memes-and-marketing/chat_2024-11-14.md index 4d49b71fdd..4296c9d64b 100644 --- a/docs/community/Discord/the_arena/memes-and-marketing/chat_2024-11-14.md +++ b/docs/community/Discord/the_arena/memes-and-marketing/chat_2024-11-14.md @@ -1,7 +1,7 @@ # memes-and-marketing 2024-11-14 ## Summary - In the provided chat excerpt, participants engaged in discussions related to marketing memes with a focus on creating an animated version of Eliza from GitHub repository 'https://github.com/ai16z/eliza'. The team considered updating LinkedIn profiles and discussed the potential for a new preview card featuring Eliza. A humorous exchange about driving backwards led to laughter, while DorianD reminded everyone to update their professional online presence. Jin proposed an official position of Director of Memetic Warfare with Trump memes, which was met with amusement. The community celebrated the quality of work on 'bord.eth' and shared a link featuring Eliza in a meme format from Tenor. Knockerton welcomed everyone to continue building together, marking a milestone for the group's collaborative spirit. + In the provided chat excerpt, participants engaged in discussions related to marketing memes with a focus on creating an animated version of Eliza from GitHub repository 'https://github.com/elizaOS/eliza'. The team considered updating LinkedIn profiles and discussed the potential for a new preview card featuring Eliza. A humorous exchange about driving backwards led to laughter, while DorianD reminded everyone to update their professional online presence. Jin proposed an official position of Director of Memetic Warfare with Trump memes, which was met with amusement. The community celebrated the quality of work on 'bord.eth' and shared a link featuring Eliza in a meme format from Tenor. Knockerton welcomed everyone to continue building together, marking a milestone for the group's collaborative spirit. ## FAQ - When did astrid animate the meme from the repository? From bb1e45e19c89aa9edea80908abb78c0232c80b85 Mon Sep 17 00:00:00 2001 From: 9547 <29431502+9547@users.noreply.github.com> Date: Thu, 2 Jan 2025 14:25:50 +0800 Subject: [PATCH 03/34] chore(docs): rename ai16z/eliza to elizaOS/eliza --- .../Discord/the_arena/memes-and-marketing/chat_2024-11-24.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/community/Discord/the_arena/memes-and-marketing/chat_2024-11-24.md b/docs/community/Discord/the_arena/memes-and-marketing/chat_2024-11-24.md index 62997cad52..f76bc0cf9a 100644 --- a/docs/community/Discord/the_arena/memes-and-marketing/chat_2024-11-24.md +++ b/docs/community/Discord/the_arena/memes-and-marketing/chat_2024-11-24.md @@ -9,11 +9,11 @@ - Are you available to share your screen for the presentation preparation? - YoungPhlo: Yes, after some initial confusion about repository locations and tools (GitHub Desktop vs CLI), agreed to use GitHub Desktop as it's better suited for beginners. - What should be used when creating a pull request on GitHub? - - YoungPhlo: Suggested using the "Create draft pull request" option, referencing an existing PR (`ai16z/eliza/pull/580`) as an example. + - YoungPhlo: Suggested using the "Create draft pull request" option, referencing an existing PR (`elizaOS/eliza/pull/580`) as an example. ## Who Helped Who - YoungPhlo helped Jin with setting up a repository for presentation documents by suggesting to fork from GitHub.com or use gh-cli, ultimately agreeing on using GitHub Desktop as it's better for beginners. -- YoungPhlo assisted Jin in deciding between "Create pull request" and "Create draft pull request" options when preparing documentation updates, settling on the former with a specific reference to `ai16z/eliza/pull/580`. +- YoungPhlo assisted Jin in deciding between "Create pull request" and "Create draft pull request" options when preparing documentation updates, settling on the former with a specific reference to `elizaOS/eliza/pull/580`. ## Action Items - Technical Tasks From bb9253be05b45bac09f617a97a77a779c858f1b8 Mon Sep 17 00:00:00 2001 From: 9547 <29431502+9547@users.noreply.github.com> Date: Thu, 2 Jan 2025 14:25:54 +0800 Subject: [PATCH 04/34] chore(docs): rename ai16z/eliza to elizaOS/eliza --- docs/community/Notes/lore.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/community/Notes/lore.md b/docs/community/Notes/lore.md index dd9065167b..a3d61667ff 100644 --- a/docs/community/Notes/lore.md +++ b/docs/community/Notes/lore.md @@ -127,7 +127,7 @@ What's the difference between degenai and ai16z? 4. Big Names in Play: Itโ€™s a collaboration between two AI agents modeled after the GOAT investors, + the rest of us -5. Same Framework: Both projects use the same tech framework https://github.com/ai16z/eliza +5. Same Framework: Both projects use the same tech framework https://github.com/elizaOS/eliza Sorta betting on an individual AI (degenspartan) vs a fund (ai16z). AI Marc might listen to @degenspartanai moreso than the holders, so it's like an influence game From 8bdf6133d563e9ac627dc858a7a2400ee3d19e17 Mon Sep 17 00:00:00 2001 From: 9547 <29431502+9547@users.noreply.github.com> Date: Thu, 2 Jan 2025 14:25:59 +0800 Subject: [PATCH 05/34] chore(docs): rename ai16z/eliza to elizaOS/eliza --- docs/community/ai-dev-school/nader_tutorial_10min.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/community/ai-dev-school/nader_tutorial_10min.md b/docs/community/ai-dev-school/nader_tutorial_10min.md index 7784bc8a2e..cb17552d12 100644 --- a/docs/community/ai-dev-school/nader_tutorial_10min.md +++ b/docs/community/ai-dev-school/nader_tutorial_10min.md @@ -4,7 +4,7 @@ sidebar_position: 2 # Creating an AI Agent with Your Own Personality -In this tutorial, we'll explore how to create an AI agent that embodies your own personality using data from your Twitter archive, videos, markdown files, and PDFs. We'll leverage the [Characterfile](https://github.com/ai16z/characterfile) repo and [Eliza framework](https://github.com/ai16z/eliza) to generate and integrate the character data. +In this tutorial, we'll explore how to create an AI agent that embodies your own personality using data from your Twitter archive, videos, markdown files, and PDFs. We'll leverage the [Characterfile](https://github.com/ai16z/characterfile) repo and [Eliza framework](https://github.com/elizaOS/eliza) to generate and integrate the character data. Video: https://youtu.be/uouSdtcWXTQ?si=cm13L4T7DQUMXd0C @@ -50,7 +50,7 @@ Video: https://youtu.be/uouSdtcWXTQ?si=cm13L4T7DQUMXd0C 1. Clone Eliza repo and check out latest version: ```bash - git clone https://github.com/ai16z/eliza.git + git clone https://github.com/elizaOS/eliza.git git checkout ``` From 8259ea4c6da0b65a8f8d34e2fb275268d6164633 Mon Sep 17 00:00:00 2001 From: 9547 <29431502+9547@users.noreply.github.com> Date: Thu, 2 Jan 2025 14:26:03 +0800 Subject: [PATCH 06/34] chore(docs): rename ai16z/eliza to elizaOS/eliza --- docs/community/ai-dev-school/nader_tutorial_15min.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/community/ai-dev-school/nader_tutorial_15min.md b/docs/community/ai-dev-school/nader_tutorial_15min.md index 7263608c43..28caac3108 100644 --- a/docs/community/ai-dev-school/nader_tutorial_15min.md +++ b/docs/community/ai-dev-school/nader_tutorial_15min.md @@ -18,7 +18,7 @@ Video: https://youtu.be/6PZVwNTl5hI?si=0zB3OvYU4KiRQTxI 1. Clone the Eliza repo and check out the latest version: ```bash - git clone https://github.com/ai16z/eliza.git + git clone https://github.com/elizaOS/eliza.git cd eliza git checkout ``` @@ -99,6 +99,6 @@ Video: https://youtu.be/6PZVwNTl5hI?si=0zB3OvYU4KiRQTxI - [Code Repo](https://github.com/dabit3/ai-agent-cognitivedriftt) - [Eliza Docs](https://ai16z.github.io/eliza/) - [Example Character File](https://github.com/ai16z/characterfile/blob/main/examples/example.character.json) -- [Default Character](https://github.com/ai16z/eliza/blob/8f4e2643dcb1a5aafb25267e80d22e7e12fd044a/packages/core/src/defaultCharacter.ts#L4) +- [Default Character](https://github.com/elizaOS/eliza/blob/8f4e2643dcb1a5aafb25267e80d22e7e12fd044a/packages/core/src/defaultCharacter.ts#L4) - [Environment Variables](https://gist.github.com/dabit3/7602e97f3abe0a93bdd84dc250f23021) From a31a3bf2afdd7f9e28911bc9cc59603292b69c23 Mon Sep 17 00:00:00 2001 From: "KIM, WOOJUNG" Date: Thu, 2 Jan 2025 17:42:18 +0900 Subject: [PATCH 07/34] Update README_KOR.md Update README with detailed sections - Added "Features" section with clear use cases in English and Korean. - Translated "Note for Windows Users" and "Additional Requirements" into Korean. - Enhanced "Community & Contact" section with actionable phrases. - Added contributors section with visual representation. - Included star history chart for project insights. - Improved formatting and consistency across all sections. --- README_KOR.md | 48 ++++++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/README_KOR.md b/README_KOR.md index eba3cc4073..754c21ec94 100644 --- a/README_KOR.md +++ b/README_KOR.md @@ -10,16 +10,24 @@ +## ๐ŸŒ README Translations + +[ไธญๆ–‡่ฏดๆ˜Ž](./README_CN.md) | [ๆ—ฅๆœฌ่ชžใฎ่ชฌๆ˜Ž](./README_JA.md) | [ํ•œ๊ตญ์–ด ์„ค๋ช…](./README_KOR.md) | [Franรงais](./README_FR.md) | [Portuguรชs](./README_PTBR.md) | [Tรผrkรงe](./README_TR.md) | [ะ ัƒััะบะธะน](./README_RU.md) | [Espaรฑol](./README_ES.md) | [Italiano](./README_IT.md) | [เน„เธ—เธข](./README_TH.md) | [Deutsch](./README_DE.md) | [Tiแบฟng Viแป‡t](./README_VI.md) | [ืขึดื‘ืจึดื™ืช](https://github.com/elizaos/Elisa/blob/main/README_HE.md) | [Tagalog](./README_TG.md) + ## โœจ ๊ธฐ๋Šฅ -- ๐Ÿ›  SNS ์ง€์›: ๋””์Šค์ฝ”๋“œ, ํŠธ์œ„ํ„ฐ, ํ…”๋ ˆ๊ทธ๋žจ ๋ชจ๋‘ ์ง€์›๋ฉ๋‹ˆ๋‹ค. -- ๐Ÿ”— ๋‹ค์–‘ํ•œ ๋ชจ๋ธ ์ง€์› (Llama, Grok, OpenAI, Anthropic ๋“ฑ) -- ๐Ÿ‘ฅ ๋‹ค์ค‘ ์ง€์›: ๋‹ค์ค‘ ์—์ด์ „ํŠธ ๋ฐ ์ฑ„ํŒ…๋ฐฉ์ด ์ง€์›๋ฉ๋‹ˆ๋‹ค. -- ๐Ÿ“š ๋†’์€ ์œ ์—ฐ์„ฑ: ๊ฐœ๋ฐœ์ž๊ฐ€ ์‰ฝ๊ฒŒ ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ , ์ด๋ฅผ ํ™œ์šฉํ•ด ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -- ๐Ÿ’พ ๊ฒ€์ƒ‰ ์ง€์›: ๋‹น์‹ ์˜ ๋ฐ์ดํ„ฐ์™€ ์ž‘์—…์„ ์‰ฝ๊ฒŒ ์ฐพ์•„๋ณผ ์ˆ˜ ์žˆ๋„๋ก, ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. -- ๐Ÿš€ ๋†’์€ ํ™•์žฅ์„ฑ: ์ž์‹ ์˜ ๋™์ž‘๊ณผ ํด๋ผ์ด์–ธํŠธ๋ฅผ ๋งŒ๋“ค์–ด ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. -- โ˜๏ธ ๋‹ค์–‘ํ•œ AI ๋ชจ๋ธ ์ง€์›: local Llama, OpenAI, Anthropic, Groq ๋“ฑ ๋‹ค์–‘ํ•œ AI ๋ชจ๋ธ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค -- ๐Ÿ“ฆ ์ฆ๊ฒ๊ฒŒ ๊ฐœ๋ฐœํ•ด ๋ด์š”! +- ๐Ÿ›  SNS ํ†ตํ•ฉ ์ง€์›: Discord, Twitter, Telegram์„ ๋ชจ๋‘ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. +- ๐Ÿ”— ๋‹ค์–‘ํ•œ ๋ชจ๋ธ ํ˜ธํ™˜: Llama, Grok, OpenAI, Anthropic ๋“ฑ ๋‹ค์–‘ํ•œ AI ๋ชจ๋ธ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. +- ๐Ÿ‘ฅ ๋‹ค์ค‘ ์—์ด์ „ํŠธ ๋ฐ ์ฑ„ํŒ…๋ฐฉ ์ง€์›: ์—ฌ๋Ÿฌ ์—์ด์ „ํŠธ์™€ ์ฑ„ํŒ…๋ฐฉ์„ ์†์‰ฝ๊ฒŒ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +- ๐Ÿ“š ๋ฌธ์„œ ์ฒ˜๋ฆฌ ๋ฐ ์ƒํ˜ธ์ž‘์šฉ: ๋ฐ์ดํ„ฐ๋ฅผ ์†์‰ฝ๊ฒŒ ์ถ”๊ฐ€ํ•˜๊ณ  ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. +- ๐Ÿ’พ ๊ฒ€์ƒ‰ ๊ฐ€๋Šฅํ•œ ๋ฉ”๋ชจ๋ฆฌ ๋ฐ ๋ฌธ์„œ ์ €์žฅ์†Œ: ๋ฐ์ดํ„ฐ๋ฅผ ๋น ๋ฅด๊ณ  ๊ฐ„ํŽธํ•˜๊ฒŒ ๊ฒ€์ƒ‰ํ•˜๊ณ  ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +- ๐Ÿš€ ๋†’์€ ํ™•์žฅ์„ฑ: ์‚ฌ์šฉ์ž ์ •์˜ ๋™์ž‘ ๋ฐ ํด๋ผ์ด์–ธํŠธ๋ฅผ ๋งŒ๋“ค์–ด ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +- โ˜๏ธ ๋‹ค์–‘ํ•œ AI ๋ชจ๋ธ ์ง€์›: Local Llama, OpenAI, Anthropic, Groq ๋“ฑ๊ณผ ํ˜ธํ™˜๋ฉ๋‹ˆ๋‹ค. +- ๐Ÿ“ฆ ์‰ฝ๊ฒŒ ์‹œ์ž‘ํ•˜์„ธ์š”: ๋ฐ”๋กœ ์ž‘๋™ํ•˜๋ฉฐ ์†์‰ฝ๊ฒŒ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค! + +## ๋น„๋””์˜ค ํŠœํ† ๋ฆฌ์–ผ + +[AI Agent Dev School](https://www.youtube.com/watch?v=ArptLpQiKfI&list=PLx5pnFXdPTRzWla0RaOxALTSTnVq53fKL) ## ๐ŸŽฏ eliza๋กœ ์–ด๋–ค๊ฑธ ๋งŒ๋“ค ์ˆ˜ ์žˆ์„๊นŒ์š”? @@ -37,21 +45,25 @@ - [Node.js 23.3+](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) - [pnpm](https://pnpm.io/installation) -> **Windows ์‚ฌ์šฉ์ž ์ฐธ๊ณ :** [WSL 2](https://learn.microsoft.com/en-us/windows/wsl/install-manual) ํ•„์š”. +> **Windows ์‚ฌ์šฉ์ž ์ฐธ๊ณ :** [WSL 2](https://learn.microsoft.com/en-us/windows/wsl/install-manual)๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ### Starter ์‚ฌ์šฉ (๊ถŒ์žฅ) ```bash git clone https://github.com/elizaos/eliza-starter.git - +cd eliza-starter cp .env.example .env - -pnpm i && pnpm start +pnpm i && pnpm build && pnpm start +``` +์—์ด์ „ํŠธ๊ฐ€ ์‹คํ–‰๋˜๋ฉด ๋งˆ์ง€๋ง‰์— "pnpm start:client"๋ฅผ ์‹คํ–‰ํ•˜๋ผ๋Š” ๋ฉ”์‹œ์ง€๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. +๋‹ค๋ฅธ ํ„ฐ๋ฏธ๋„์„ ์—ด๊ณ  ๊ฐ™์€ ๋””๋ ‰ํ† ๋ฆฌ๋กœ ์ด๋™ํ•œ ๋’ค ์•„๋ž˜ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜์„ธ์š”. ํ‘œ์‹œ๋œ URL์„ ์—ด์–ด ์—์ด์ „ํŠธ์™€ ๋Œ€ํ™”ํ•˜์„ธ์š”. +```bash +pnpm start:client ``` -[๋ฌธ์„œ](https://elizaos.github.io/eliza/)๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ Eliza๋ฅผ ์ปค์Šค๋งˆ์ด์ง• ๋ฐฉ๋ฒ•์„ ํ™•์ธํ•˜์„ธ์š”. +[๋ฌธ์„œ](https://elizaos.github.io/eliza/)๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ Eliza๋ฅผ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ฐฐ์›Œ๋ณด์„ธ์š”. -### ์ง์ ‘ ์‹คํ–‰ํ•˜๊ธฐ (๊ฒฝํ—˜์ž๋งŒ ๊ถŒ์žฅ) +### Eliza๋ฅผ ์ˆ˜๋™์œผ๋กœ ์‹คํ–‰ํ•˜๊ธฐ (๊ฒฝํ—˜์ž์—๊ฒŒ๋งŒ ๊ถŒ์žฅ) ```bash # ๋ฆฌํฌ์ง€ํ† ๋ฆฌ ํด๋ก  @@ -107,16 +119,16 @@ pnpm clean #### ์ถ”๊ฐ€ ์š”๊ตฌ ์‚ฌํ•ญ -์‹œ์ž‘ ์‹œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด Sharp๋ฅผ ์„ค์น˜ํ•ด์•ผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„ค์น˜ํ•˜์„ธ์š”: +์‹œ์ž‘ํ•  ๋•Œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด Sharp๋ฅผ ์„ค์น˜ํ•ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ์„ค์น˜ํ•˜์„ธ์š”: ``` pnpm install --include=optional sharp ``` -### Community & contact +### ์ปค๋ฎค๋‹ˆํ‹ฐ & ๋ฌธ์˜ -- [Github Issues](https://github.com/elizaos/eliza/issues). ์šฉ๋„: Eliza ์‚ฌ์šฉ ์ค‘ ๋ฐœ๊ฒฌ๋œ ๋ฒ„๊ทธ ๋ฆฌํฌํŠธ, ๊ธฐ๋Šฅ ์ œ์•ˆ. -- [Discord](https://discord.gg/ai16z). ์šฉ๋„: ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ณต์œ  ๋ฐ ์ปค๋ฎค๋‹ˆํ‹ฐ ํ™œ๋™. +- [Github Issues](https://github.com/elizaos/eliza/issues). liza ์‚ฌ์šฉ ์ค‘ ๋ฐœ๊ฒฌ๋œ ๋ฒ„๊ทธ ๋ณด๊ณ  ๋ฐ ๊ธฐ๋Šฅ ์ œ์•ˆ์— ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค. +- [Discord](https://discord.gg/ai16z). ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ณต์œ  ๋ฐ ์ปค๋ฎค๋‹ˆํ‹ฐ์™€์˜ ์†Œํ†ต์— ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค. ## ์ปจํŠธ๋ฆฌ๋ทฐํ„ฐ From aea8ee6076afc71fe4ca4352fe45ff454358caeb Mon Sep 17 00:00:00 2001 From: "KIM, WOOJUNG" Date: Thu, 2 Jan 2025 17:47:39 +0900 Subject: [PATCH 08/34] Update README_KOR.md --- README_KOR.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README_KOR.md b/README_KOR.md index 754c21ec94..0ddd35582f 100644 --- a/README_KOR.md +++ b/README_KOR.md @@ -17,7 +17,6 @@ ## โœจ ๊ธฐ๋Šฅ - ๐Ÿ›  SNS ํ†ตํ•ฉ ์ง€์›: Discord, Twitter, Telegram์„ ๋ชจ๋‘ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. -- ๐Ÿ”— ๋‹ค์–‘ํ•œ ๋ชจ๋ธ ํ˜ธํ™˜: Llama, Grok, OpenAI, Anthropic ๋“ฑ ๋‹ค์–‘ํ•œ AI ๋ชจ๋ธ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. - ๐Ÿ‘ฅ ๋‹ค์ค‘ ์—์ด์ „ํŠธ ๋ฐ ์ฑ„ํŒ…๋ฐฉ ์ง€์›: ์—ฌ๋Ÿฌ ์—์ด์ „ํŠธ์™€ ์ฑ„ํŒ…๋ฐฉ์„ ์†์‰ฝ๊ฒŒ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - ๐Ÿ“š ๋ฌธ์„œ ์ฒ˜๋ฆฌ ๋ฐ ์ƒํ˜ธ์ž‘์šฉ: ๋ฐ์ดํ„ฐ๋ฅผ ์†์‰ฝ๊ฒŒ ์ถ”๊ฐ€ํ•˜๊ณ  ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. - ๐Ÿ’พ ๊ฒ€์ƒ‰ ๊ฐ€๋Šฅํ•œ ๋ฉ”๋ชจ๋ฆฌ ๋ฐ ๋ฌธ์„œ ์ €์žฅ์†Œ: ๋ฐ์ดํ„ฐ๋ฅผ ๋น ๋ฅด๊ณ  ๊ฐ„ํŽธํ•˜๊ฒŒ ๊ฒ€์ƒ‰ํ•˜๊ณ  ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. From 5ed62a87b13a022d3ed90b36029530c0889f46ff Mon Sep 17 00:00:00 2001 From: "KIM, WOOJUNG" Date: Thu, 2 Jan 2025 17:48:00 +0900 Subject: [PATCH 09/34] Update README_KOR.md --- README_KOR.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README_KOR.md b/README_KOR.md index 0ddd35582f..754c21ec94 100644 --- a/README_KOR.md +++ b/README_KOR.md @@ -17,6 +17,7 @@ ## โœจ ๊ธฐ๋Šฅ - ๐Ÿ›  SNS ํ†ตํ•ฉ ์ง€์›: Discord, Twitter, Telegram์„ ๋ชจ๋‘ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. +- ๐Ÿ”— ๋‹ค์–‘ํ•œ ๋ชจ๋ธ ํ˜ธํ™˜: Llama, Grok, OpenAI, Anthropic ๋“ฑ ๋‹ค์–‘ํ•œ AI ๋ชจ๋ธ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. - ๐Ÿ‘ฅ ๋‹ค์ค‘ ์—์ด์ „ํŠธ ๋ฐ ์ฑ„ํŒ…๋ฐฉ ์ง€์›: ์—ฌ๋Ÿฌ ์—์ด์ „ํŠธ์™€ ์ฑ„ํŒ…๋ฐฉ์„ ์†์‰ฝ๊ฒŒ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - ๐Ÿ“š ๋ฌธ์„œ ์ฒ˜๋ฆฌ ๋ฐ ์ƒํ˜ธ์ž‘์šฉ: ๋ฐ์ดํ„ฐ๋ฅผ ์†์‰ฝ๊ฒŒ ์ถ”๊ฐ€ํ•˜๊ณ  ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. - ๐Ÿ’พ ๊ฒ€์ƒ‰ ๊ฐ€๋Šฅํ•œ ๋ฉ”๋ชจ๋ฆฌ ๋ฐ ๋ฌธ์„œ ์ €์žฅ์†Œ: ๋ฐ์ดํ„ฐ๋ฅผ ๋น ๋ฅด๊ณ  ๊ฐ„ํŽธํ•˜๊ฒŒ ๊ฒ€์ƒ‰ํ•˜๊ณ  ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. From 498612e35b56c5c57cf3241f383f93679e695946 Mon Sep 17 00:00:00 2001 From: "KIM, WOOJUNG" Date: Thu, 2 Jan 2025 18:00:49 +0900 Subject: [PATCH 10/34] remove link to another translate section --- README_KOR.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/README_KOR.md b/README_KOR.md index 754c21ec94..ebbe2fb29f 100644 --- a/README_KOR.md +++ b/README_KOR.md @@ -10,10 +10,6 @@ -## ๐ŸŒ README Translations - -[ไธญๆ–‡่ฏดๆ˜Ž](./README_CN.md) | [ๆ—ฅๆœฌ่ชžใฎ่ชฌๆ˜Ž](./README_JA.md) | [ํ•œ๊ตญ์–ด ์„ค๋ช…](./README_KOR.md) | [Franรงais](./README_FR.md) | [Portuguรชs](./README_PTBR.md) | [Tรผrkรงe](./README_TR.md) | [ะ ัƒััะบะธะน](./README_RU.md) | [Espaรฑol](./README_ES.md) | [Italiano](./README_IT.md) | [เน„เธ—เธข](./README_TH.md) | [Deutsch](./README_DE.md) | [Tiแบฟng Viแป‡t](./README_VI.md) | [ืขึดื‘ืจึดื™ืช](https://github.com/elizaos/Elisa/blob/main/README_HE.md) | [Tagalog](./README_TG.md) - ## โœจ ๊ธฐ๋Šฅ - ๐Ÿ›  SNS ํ†ตํ•ฉ ์ง€์›: Discord, Twitter, Telegram์„ ๋ชจ๋‘ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. From cee9b2b754b6851a8c16f7e19c14b79aca991edf Mon Sep 17 00:00:00 2001 From: 9547 <29431502+9547@users.noreply.github.com> Date: Thu, 2 Jan 2025 19:48:03 +0800 Subject: [PATCH 11/34] fix(core): trimTokens no need to await --- packages/core/src/generation.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/generation.ts b/packages/core/src/generation.ts index f30204ceba..8e6d322db4 100644 --- a/packages/core/src/generation.ts +++ b/packages/core/src/generation.ts @@ -176,7 +176,7 @@ export async function generateText({ elizaLogger.debug( `Trimming context to max length of ${max_context_length} tokens.` ); - context = await trimTokens(context, max_context_length, "gpt-4o"); + context = trimTokens(context, max_context_length, "gpt-4o"); let response: string; From 096d0b1afad57865a948584544ca0dbc6678f6c7 Mon Sep 17 00:00:00 2001 From: Affaan Mustafa <124439313+affaan-m@users.noreply.github.com> Date: Thu, 2 Jan 2025 04:16:59 -0800 Subject: [PATCH 12/34] Update index.ts Making sure plugin has a proper default export at bottom to avoid collisions when used in actions module in char file. --- packages/plugin-web-search/src/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/plugin-web-search/src/index.ts b/packages/plugin-web-search/src/index.ts index 58a511eee2..528e260904 100644 --- a/packages/plugin-web-search/src/index.ts +++ b/packages/plugin-web-search/src/index.ts @@ -207,3 +207,5 @@ export const webSearchPlugin: Plugin = { evaluators: [], providers: [], }; + +export default webSearchPlugin; From ca6696b4b5231b210bbe9f6403f61733a87c1915 Mon Sep 17 00:00:00 2001 From: SK1989sL <91366180+SK1989sL@users.noreply.github.com> Date: Thu, 2 Jan 2025 14:22:05 +0100 Subject: [PATCH 13/34] Update README.md spelling Just two little points as want to make it look flawless --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4c91531ddb..48acbbc637 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ cd eliza-starter cp .env.example .env pnpm i && pnpm build && pnpm start ``` -Once the agent is running, You should see the message to run "pnpm start:client" at the end. +Once the agent is running, you should see the message to run "pnpm start:client" at the end. Open another terminal and move to same directory and then run below command and follow the URL to chat to your agent. ```bash pnpm start:client @@ -86,7 +86,7 @@ Copy .env.example to .env and fill in the appropriate values. cp .env.example .env ``` -Note: .env is optional. If your planning to run multiple distinct agents, you can pass secrets through the character JSON +Note: .env is optional. If you're planning to run multiple distinct agents, you can pass secrets through the character JSON ### Automatically Start Eliza From 6ed900133f98a9b6c35f967453b7ff6dbc82dc25 Mon Sep 17 00:00:00 2001 From: v1xingyue Date: Thu, 2 Jan 2025 22:01:35 +0800 Subject: [PATCH 14/34] plugin-sui support suiprivatekey private key --- packages/plugin-sui/src/actions/transfer.ts | 4 ++-- packages/plugin-sui/src/providers/wallet.ts | 4 ++-- packages/plugin-sui/src/tests/wallet.test.ts | 6 ++++++ packages/plugin-sui/src/utils.ts | 15 +++++++++++++++ 4 files changed, 25 insertions(+), 4 deletions(-) create mode 100644 packages/plugin-sui/src/utils.ts diff --git a/packages/plugin-sui/src/actions/transfer.ts b/packages/plugin-sui/src/actions/transfer.ts index ab6d8f65ca..721a27d5cf 100644 --- a/packages/plugin-sui/src/actions/transfer.ts +++ b/packages/plugin-sui/src/actions/transfer.ts @@ -19,6 +19,7 @@ import { Transaction } from "@mysten/sui/transactions"; import { SUI_DECIMALS } from "@mysten/sui/utils"; import { walletProvider } from "../providers/wallet"; +import { parseAccount } from "../utils"; type SuiNetwork = "mainnet" | "testnet" | "devnet" | "localnet"; @@ -139,8 +140,7 @@ export default { } try { - const privateKey = runtime.getSetting("SUI_PRIVATE_KEY"); - const suiAccount = Ed25519Keypair.deriveKeypair(privateKey); + const suiAccount = parseAccount(runtime); const network = runtime.getSetting("SUI_NETWORK"); const suiClient = new SuiClient({ url: getFullnodeUrl(network as SuiNetwork), diff --git a/packages/plugin-sui/src/providers/wallet.ts b/packages/plugin-sui/src/providers/wallet.ts index 4ee649befb..478fc2ce49 100644 --- a/packages/plugin-sui/src/providers/wallet.ts +++ b/packages/plugin-sui/src/providers/wallet.ts @@ -13,6 +13,7 @@ import { MIST_PER_SUI } from "@mysten/sui/utils"; import BigNumber from "bignumber.js"; import NodeCache from "node-cache"; import * as path from "path"; +import { parseAccount } from "../utils"; // Provider configuration const PROVIDER_CONFIG = { @@ -220,8 +221,7 @@ const walletProvider: Provider = { _message: Memory, _state?: State ): Promise => { - const privateKey = runtime.getSetting("SUI_PRIVATE_KEY"); - const suiAccount = Ed25519Keypair.deriveKeypair(privateKey); + const suiAccount = parseAccount(runtime); try { const suiClient = new SuiClient({ diff --git a/packages/plugin-sui/src/tests/wallet.test.ts b/packages/plugin-sui/src/tests/wallet.test.ts index 39d3c62d4d..df3372f57d 100644 --- a/packages/plugin-sui/src/tests/wallet.test.ts +++ b/packages/plugin-sui/src/tests/wallet.test.ts @@ -49,6 +49,12 @@ describe("WalletProvider", () => { "gaze throw also reveal kite load tennis tone club cloth chaos picture" ); + const suiAccountx = Ed25519Keypair.fromSecretKey( + "suiprivkey1qzuw2uvhqz330pwl94rv39jvk93kuvfd4pvdkw9vl922kum80prqvxtlntr" + ); + + console.log(suiAccountx.toSuiAddress()); + // Create new instance of TokenProvider with mocked dependencies walletProvider = new WalletProvider( suiClient, diff --git a/packages/plugin-sui/src/utils.ts b/packages/plugin-sui/src/utils.ts new file mode 100644 index 0000000000..4db8623eb1 --- /dev/null +++ b/packages/plugin-sui/src/utils.ts @@ -0,0 +1,15 @@ +import { IAgentRuntime } from "@elizaos/core"; +import { Ed25519Keypair } from "@mysten/sui/keypairs/ed25519"; + +const parseAccount = (runtime: IAgentRuntime): Ed25519Keypair => { + const privateKey = runtime.getSetting("SUI_PRIVATE_KEY"); + if (!privateKey) { + throw new Error("SUI_PRIVATE_KEY is not set"); + } else if (privateKey.startsWith("suiprivkey")) { + return Ed25519Keypair.fromSecretKey(privateKey); + } else { + return Ed25519Keypair.deriveKeypairFromSeed(privateKey); + } +}; + +export { parseAccount }; From c0b105543ac51c8baa0c0d92fcaa00b7d64992ba Mon Sep 17 00:00:00 2001 From: v1xingyue Date: Thu, 2 Jan 2025 22:03:57 +0800 Subject: [PATCH 15/34] add parse cmdline --- .env.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.example b/.env.example index f54f552f6a..31a1304802 100644 --- a/.env.example +++ b/.env.example @@ -341,7 +341,7 @@ AWS_S3_UPLOAD_PATH= DEEPGRAM_API_KEY= # Sui -SUI_PRIVATE_KEY= # Sui Mnemonic Seed Phrase (`sui keytool generate ed25519`) +SUI_PRIVATE_KEY= # Sui Mnemonic Seed Phrase (`sui keytool generate ed25519`) , Also support `suiprivatekeyxxxx` (sui keytool export --key-identity 0x63) SUI_NETWORK= # must be one of mainnet, testnet, devnet, localnet # Story From 4f996dc862a2bc329d8acefb9b303f6806f1c3ce Mon Sep 17 00:00:00 2001 From: Shakker Nerd Date: Thu, 2 Jan 2025 15:01:22 +0000 Subject: [PATCH 16/34] chore: remove conflicted readme files --- packages/plugin-story/README.md | 228 -------------------------------- packages/plugin-story/Readme.md | 186 -------------------------- 2 files changed, 414 deletions(-) delete mode 100644 packages/plugin-story/README.md delete mode 100644 packages/plugin-story/Readme.md diff --git a/packages/plugin-story/README.md b/packages/plugin-story/README.md deleted file mode 100644 index 9f8661626d..0000000000 --- a/packages/plugin-story/README.md +++ /dev/null @@ -1,228 +0,0 @@ -# @elizaos/plugin-story - -The Story Protocol plugin enables interaction with Story Protocol's IP management and licensing system on the Odyssey testnet. - -## Overview - -This plugin provides functionality to: -- Register IP assets on Story Protocol -- License IP assets -- Attach license terms to IP assets -- Query IP asset details and available licenses -- Manage wallet interactions with Story Protocol - -## Installation - -```bash -npm install @elizaos/plugin-story -``` - -## Configuration - -The plugin requires the following environment variables: - -```env -STORY_PRIVATE_KEY=your_private_key -STORY_API_KEY=your_api_key -STORY_API_BASE_URL=https://api.story.xyz -PINATA_JWT=your_pinata_jwt_token -``` - -## Usage - -Import and register the plugin in your Eliza configuration: - -```typescript -import { storyPlugin } from "@elizaos/plugin-story"; - -export default { - plugins: [storyPlugin], - // ... other configuration -}; -``` - -## Features - -### Register IP - -Register a new IP asset on Story Protocol: - -```typescript -// Example conversation -User: "I want to register my IP titled 'My Story' with the description 'An epic tale'" -Assistant: "I'll help you register your IP on Story Protocol..." -``` - -### License IP - -License an existing IP asset: - -```typescript -// Example conversation -User: "I want to license IP Asset 0x1234...5678 with license terms ID 1" -Assistant: "I'll help you license that IP asset..." -``` - -### Attach Terms - -Attach license terms to an IP asset: - -```typescript -// Example conversation -User: "I want to attach commercial license terms with 10% revenue share to IP 0x1234...5678" -Assistant: "I'll help you attach those license terms..." -``` - -### Get IP Details - -Query details about an IP asset: - -```typescript -// Example conversation -User: "Get details for IP Asset 0x1234...5678" -Assistant: "Here are the details for that IP asset..." -``` - -### Get Available Licenses - -Query available licenses for an IP asset: - -```typescript -// Example conversation -User: "What licenses are available for IP Asset 0x1234...5678?" -Assistant: "Here are the available licenses..." -``` - -## API Reference - -### Actions - -- `REGISTER_IP`: Register a new IP asset -- `LICENSE_IP`: License an existing IP asset -- `ATTACH_TERMS`: Attach license terms to an IP -- `GET_IP_DETAILS`: Get details about an IP -- `GET_AVAILABLE_LICENSES`: Get available licenses for an IP - -### Providers - -- `storyWalletProvider`: Manages wallet interactions with Story Protocol - -## Development - -### Building - -```bash -npm run build -``` - -### Testing - -```bash -npm run test -``` - -## Dependencies - -- `@story-protocol/core-sdk`: Core SDK for Story Protocol -- `@pinata/sdk`: IPFS pinning service -- `viem`: Ethereum interaction library -- Other standard dependencies listed in package.json - -## Future Enhancements - -The following features and improvements are planned for future releases: - -1. **IP Management** - - Batch IP registration - - Advanced metadata management - - IP relationship mapping - - Automated IP verification - - Collection management - - IP analytics dashboard - -2. **Licensing Features** - - Custom license templates - - License negotiation tools - - Automated royalty distribution - - Usage tracking system - - License violation detection - - Bulk licensing tools - -3. **Rights Management** - - Advanced permission systems - - Rights transfer automation - - Usage rights tracking - - Derivative works management - - Rights verification tools - - Dispute resolution system - -4. **Smart Contract Integration** - - Contract deployment templates - - Automated verification - - Contract upgrade system - - Security analysis tools - - Gas optimization - - Multi-signature support - -5. **Content Management** - - Media file handling - - Content versioning - - Distribution tracking - - Content authentication - - Storage optimization - - Format conversion tools - -6. **Revenue Management** - - Automated payments - - Revenue sharing tools - - Payment tracking - - Financial reporting - - Tax documentation - - Audit trail system - -7. **Developer Tools** - - Enhanced SDK features - - Testing framework - - Documentation generator - - CLI improvements - - Integration templates - - Performance monitoring - -8. **Analytics and Reporting** - - Usage statistics - - Revenue analytics - - License tracking - - Performance metrics - - Custom reporting - - Market analysis tools - -We welcome community feedback and contributions to help prioritize these enhancements. - -## Contributing - -Contributions are welcome! Please see the [CONTRIBUTING.md](CONTRIBUTING.md) file for more information. - -## Credits - -This plugin integrates with and builds upon several key technologies: - -- [Story Protocol](https://www.story.xyz/): IP management and licensing platform -- [@story-protocol/core-sdk](https://www.npmjs.com/package/@story-protocol/core-sdk): Official Story Protocol SDK -- [@pinata/sdk](https://www.npmjs.com/package/@pinata/sdk): IPFS pinning service -- [viem](https://www.npmjs.com/package/viem): Ethereum interaction library - -Special thanks to: -- The Story Protocol team for developing the IP management platform -- The Story Protocol Developer community -- The Pinata team for IPFS infrastructure -- The Eliza community for their contributions and feedback - -For more information about Story Protocol capabilities: -- [Story Protocol Documentation](https://docs.story.xyz/) -- [Story Protocol Dashboard](https://app.story.xyz/) -- [Story Protocol Blog](https://www.story.xyz/blog) -- [Story Protocol GitHub](https://github.com/storyprotocol) - -## License - -This plugin is part of the Eliza project. See the main project repository for license information. diff --git a/packages/plugin-story/Readme.md b/packages/plugin-story/Readme.md deleted file mode 100644 index 32276d874a..0000000000 --- a/packages/plugin-story/Readme.md +++ /dev/null @@ -1,186 +0,0 @@ -# Plugin Story - -A plugin for managing intellectual property (IP) operations, including registration, licensing, and integration with IPFS for decentralized storage. - -## Overview and Purpose - -The Plugin Story simplifies the process of managing intellectual property by providing APIs and utilities for registering IP, licensing it, and uploading related data to IPFS. It is designed to streamline workflows for developers dealing with IP management in decentralized or traditional environments. - -## Installation Instructions - -```bash -npm install @elizaos/plugin-story -``` - -## Configuration Requirements - -Ensure you have the following dependencies installed: - -- `ethers` -- `@elizaos/core` -- `ipfs-http-client` - -## Usage Examples - -### Register Intellectual Property - -#### TypeScript Example - -```typescript -import { registerIP } from '@elizaos/plugin-story/actions/registerIP'; - -const ipDetails = { - name: 'My First IP', - description: 'A sample intellectual property', - owner: '0x123...456', -}; - -try { - const registrationResult = await registerIP(ipDetails); - console.log('IP Registered Successfully:', registrationResult); -} catch (error) { - console.error('IP Registration Failed:', error); -} -``` - -### License Intellectual Property - -```typescript -import { licenseIP } from '@elizaos/plugin-story/actions/licenseIP'; - -const licenseData = { - ipId: 'IP123', - licenseType: 'Exclusive', - duration: 12, // in months -}; - -try { - const licenseResult = await licenseIP(licenseData); - console.log('IP Licensed Successfully:', licenseResult); -} catch (error) { - console.error('IP Licensing Failed:', error); -} -``` - -### Upload Data to IPFS - -```typescript -import { uploadJSONToIPFS } from '@elizaos/plugin-story/functions/uploadJSONToIPFS'; - -const jsonData = { - name: 'Sample Data', - description: 'Data to be stored on IPFS', -}; - -try { - const ipfsHash = await uploadJSONToIPFS(jsonData); - console.log('Data uploaded to IPFS. Hash:', ipfsHash); -} catch (error) { - console.error('IPFS Upload Failed:', error); -} -``` - -## API Reference - -### Actions - -#### `registerIP` - -Registers intellectual property. - -**Parameters:** - -- `details: { name: string; description: string; owner: string; }` - -**Returns:** - -- `Promise` - Result of the registration process. - -#### `licenseIP` - -Licenses registered intellectual property. - -**Parameters:** - -- `licenseData: { ipId: string; licenseType: string; duration: number; }` - -**Returns:** - -- `Promise` - Result of the licensing process. - -#### `getIPDetails` - -Fetches details of a specific intellectual property. - -**Parameters:** - -- `ipId: string` - -**Returns:** - -- `Promise` - Details of the requested IP. - -### Functions - -#### `uploadJSONToIPFS` - -Uploads JSON data to IPFS. - -**Parameters:** - -- `data: object` - -**Returns:** - -- `Promise` - The IPFS hash of the uploaded data. - -### Templates - -#### `index` - -Provides reusable templates for consistent IP management workflows. - -## Common Issues/Troubleshooting - -### Issue: IPFS Upload Fails - -- **Cause:** Invalid or large JSON data. -- **Solution:** Validate and compress JSON data before uploading. - -### Issue: IP Registration Fails - -- **Cause:** Missing or invalid owner address. -- **Solution:** Verify the owner's blockchain address. - -## Additional Documentation - -### Examples Folder - -The `examples/` folder contains practical implementations for registering, licensing, and uploading IP data. - -### Testing Guide - -Run the following command to execute tests: - -```bash -npm test -``` - -### Plugin Development Guide - -Developers can extend the plugin by adding new actions and utilities. Refer to the `src/` folder for detailed implementation patterns. - -### Security Best Practices - -- Validate all inputs for IP management actions. -- Ensure proper authentication and authorization for licensing. -- Keep dependencies updated to prevent vulnerabilities. - -### Performance Optimization Guide - -- Optimize IPFS uploads by compressing data. -- Cache frequently accessed IP details for faster retrieval. - -## Value Add - -This plugin enhances intellectual property management workflows, reduces implementation overhead, and ensures compatibility with decentralized storage systems like IPFS. From 9b8a9707095bcff54de2839c99899efab0635455 Mon Sep 17 00:00:00 2001 From: Shakker Nerd Date: Thu, 2 Jan 2025 15:02:38 +0000 Subject: [PATCH 17/34] chore: readme for story plugin --- packages/plugin-story/README.MD | 238 ++++++++++++++++++++++++++++++++ 1 file changed, 238 insertions(+) create mode 100644 packages/plugin-story/README.MD diff --git a/packages/plugin-story/README.MD b/packages/plugin-story/README.MD new file mode 100644 index 0000000000..f85a140e16 --- /dev/null +++ b/packages/plugin-story/README.MD @@ -0,0 +1,238 @@ +# @elizaos/plugin-story + +The Story Protocol plugin enables interaction with Story Protocol's IP management and licensing system on the Odyssey testnet. + +## Overview + +This plugin provides functionality to: + +- Register IP assets on Story Protocol +- License IP assets +- Attach license terms to IP assets +- Query IP asset details and available licenses +- Manage wallet interactions with Story Protocol + +## Installation + +```bash +npm install @elizaos/plugin-story +``` + +## Configuration + +The plugin requires the following environment variables: + +```env +STORY_PRIVATE_KEY=your_private_key +STORY_API_KEY=your_api_key +STORY_API_BASE_URL=https://api.story.xyz +PINATA_JWT=your_pinata_jwt_token +``` + +## Usage + +Import and register the plugin in your Eliza configuration: + +```typescript +import { storyPlugin } from "@elizaos/plugin-story"; + +export default { + plugins: [storyPlugin], + // ... other configuration +}; +``` + +## Features + +### Register IP + +Register a new IP asset on Story Protocol: + +```typescript +// Example conversation +User: "I want to register my IP titled 'My Story' with the description 'An epic tale'"; +Assistant: "I'll help you register your IP on Story Protocol..."; +``` + +### License IP + +License an existing IP asset: + +```typescript +// Example conversation +User: "I want to license IP Asset 0x1234...5678 with license terms ID 1"; +Assistant: "I'll help you license that IP asset..."; +``` + +### Attach Terms + +Attach license terms to an IP asset: + +```typescript +// Example conversation +User: "I want to attach commercial license terms with 10% revenue share to IP 0x1234...5678"; +Assistant: "I'll help you attach those license terms..."; +``` + +### Get IP Details + +Query details about an IP asset: + +```typescript +// Example conversation +User: "Get details for IP Asset 0x1234...5678"; +Assistant: "Here are the details for that IP asset..."; +``` + +### Get Available Licenses + +Query available licenses for an IP asset: + +```typescript +// Example conversation +User: "What licenses are available for IP Asset 0x1234...5678?"; +Assistant: "Here are the available licenses..."; +``` + +## API Reference + +### Actions + +- `REGISTER_IP`: Register a new IP asset +- `LICENSE_IP`: License an existing IP asset +- `ATTACH_TERMS`: Attach license terms to an IP +- `GET_IP_DETAILS`: Get details about an IP +- `GET_AVAILABLE_LICENSES`: Get available licenses for an IP + +### Providers + +- `storyWalletProvider`: Manages wallet interactions with Story Protocol + +## Development + +### Building + +```bash +npm run build +``` + +### Testing + +```bash +npm run test +``` + +## Dependencies + +- `@story-protocol/core-sdk`: Core SDK for Story Protocol +- `@pinata/sdk`: IPFS pinning service +- `viem`: Ethereum interaction library +- Other standard dependencies listed in package.json + +## Future Enhancements + +The following features and improvements are planned for future releases: + +1. **IP Management** + + - Batch IP registration + - Advanced metadata management + - IP relationship mapping + - Automated IP verification + - Collection management + - IP analytics dashboard + +2. **Licensing Features** + + - Custom license templates + - License negotiation tools + - Automated royalty distribution + - Usage tracking system + - License violation detection + - Bulk licensing tools + +3. **Rights Management** + + - Advanced permission systems + - Rights transfer automation + - Usage rights tracking + - Derivative works management + - Rights verification tools + - Dispute resolution system + +4. **Smart Contract Integration** + + - Contract deployment templates + - Automated verification + - Contract upgrade system + - Security analysis tools + - Gas optimization + - Multi-signature support + +5. **Content Management** + + - Media file handling + - Content versioning + - Distribution tracking + - Content authentication + - Storage optimization + - Format conversion tools + +6. **Revenue Management** + + - Automated payments + - Revenue sharing tools + - Payment tracking + - Financial reporting + - Tax documentation + - Audit trail system + +7. **Developer Tools** + + - Enhanced SDK features + - Testing framework + - Documentation generator + - CLI improvements + - Integration templates + - Performance monitoring + +8. **Analytics and Reporting** + - Usage statistics + - Revenue analytics + - License tracking + - Performance metrics + - Custom reporting + - Market analysis tools + +We welcome community feedback and contributions to help prioritize these enhancements. + +## Contributing + +Contributions are welcome! Please see the [CONTRIBUTING.md](CONTRIBUTING.md) file for more information. + +## Credits + +This plugin integrates with and builds upon several key technologies: + +- [Story Protocol](https://www.story.xyz/): IP management and licensing platform +- [@story-protocol/core-sdk](https://www.npmjs.com/package/@story-protocol/core-sdk): Official Story Protocol SDK +- [@pinata/sdk](https://www.npmjs.com/package/@pinata/sdk): IPFS pinning service +- [viem](https://www.npmjs.com/package/viem): Ethereum interaction library + +Special thanks to: + +- The Story Protocol team for developing the IP management platform +- The Story Protocol Developer community +- The Pinata team for IPFS infrastructure +- The Eliza community for their contributions and feedback + +For more information about Story Protocol capabilities: + +- [Story Protocol Documentation](https://docs.story.xyz/) +- [Story Protocol Dashboard](https://app.story.xyz/) +- [Story Protocol Blog](https://www.story.xyz/blog) +- [Story Protocol GitHub](https://github.com/storyprotocol) + +## License + +This plugin is part of the Eliza project. See the main project repository for license information. From 4dff318ecf89c56e49a9bd6b6614e238ec409f83 Mon Sep 17 00:00:00 2001 From: Shakker Nerd Date: Thu, 2 Jan 2025 15:03:32 +0000 Subject: [PATCH 18/34] chore: npm -> pnpm --- packages/plugin-story/README.MD | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/plugin-story/README.MD b/packages/plugin-story/README.MD index f85a140e16..a56d6a1c97 100644 --- a/packages/plugin-story/README.MD +++ b/packages/plugin-story/README.MD @@ -15,7 +15,7 @@ This plugin provides functionality to: ## Installation ```bash -npm install @elizaos/plugin-story +pnpm install @elizaos/plugin-story ``` ## Configuration @@ -113,13 +113,13 @@ Assistant: "Here are the available licenses..."; ### Building ```bash -npm run build +pnpm run build ``` ### Testing ```bash -npm run test +pnpm run test ``` ## Dependencies From f761d47e2e5fbb485e0fb68c302484bab8e1340d Mon Sep 17 00:00:00 2001 From: Shakker Nerd Date: Thu, 2 Jan 2025 15:05:02 +0000 Subject: [PATCH 19/34] fix: install packages with no frozen lockfile flag --- scripts/smokeTests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/smokeTests.sh b/scripts/smokeTests.sh index 0104298125..084057d903 100755 --- a/scripts/smokeTests.sh +++ b/scripts/smokeTests.sh @@ -36,7 +36,7 @@ cd "$PROJECT_DIR" cp .env.example .env -pnpm install -r +pnpm install -r --no-frozen-lockfile pnpm build From b1da5acd97e335409631f1eb6ee084602b71a4e4 Mon Sep 17 00:00:00 2001 From: Shakker Nerd Date: Thu, 2 Jan 2025 15:06:39 +0000 Subject: [PATCH 20/34] chore: clean before installing --- scripts/smokeTests.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/smokeTests.sh b/scripts/smokeTests.sh index 084057d903..388e7fb439 100755 --- a/scripts/smokeTests.sh +++ b/scripts/smokeTests.sh @@ -36,6 +36,8 @@ cd "$PROJECT_DIR" cp .env.example .env +pnpm clean + pnpm install -r --no-frozen-lockfile pnpm build From e6d356d3f4067b1ee98ec08621f6aff1f274ed17 Mon Sep 17 00:00:00 2001 From: Masterdai Date: Thu, 2 Jan 2025 23:29:38 +0800 Subject: [PATCH 21/34] Update environment.ts Fix Twitter username validation regex to match platform requirements --- packages/client-twitter/src/environment.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/client-twitter/src/environment.ts b/packages/client-twitter/src/environment.ts index 8ff2fb454e..43d41ea4c5 100644 --- a/packages/client-twitter/src/environment.ts +++ b/packages/client-twitter/src/environment.ts @@ -5,7 +5,7 @@ export const DEFAULT_MAX_TWEET_LENGTH = 280; const twitterUsernameSchema = z.string() .min(1) .max(15) - .regex(/^[A-Za-z][A-Za-z0-9_]*[A-Za-z0-9]$|^[A-Za-z]$/, 'Invalid Twitter username format'); + .regex(/^[A-Za-z0-9_][A-Za-z0-9_]*[A-Za-z0-9]$/, 'Invalid Twitter username format'); export const twitterEnvSchema = z.object({ TWITTER_DRY_RUN: z.boolean(), From 22e4a5e26b3d5b9962e2cca2e611e43e853dbf43 Mon Sep 17 00:00:00 2001 From: Shakker Nerd Date: Thu, 2 Jan 2025 16:28:35 +0000 Subject: [PATCH 22/34] chore: fix typo --- packages/client-twitter/src/environment.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/client-twitter/src/environment.ts b/packages/client-twitter/src/environment.ts index fcf104dca2..2c54cb0f92 100644 --- a/packages/client-twitter/src/environment.ts +++ b/packages/client-twitter/src/environment.ts @@ -6,10 +6,10 @@ export const DEFAULT_MAX_TWEET_LENGTH = 280; const twitterUsernameSchema = z .string() .min(1, "An X/Twitter Username must be at least 1 characters long") - .max(15, "n X/Twitter Username cannot exceed 15 characters") + .max(15, "An X/Twitter Username cannot exceed 15 characters") .regex( /^[A-Za-z0-9_]*$/, - "n X Username can only contain letters, numbers, and underscores" + "An X Username can only contain letters, numbers, and underscores" ); /** From 9fae2ab562cf68d977c18aecee02d4ab674153d2 Mon Sep 17 00:00:00 2001 From: Nikita Ruban <64008830+nicky-ru@users.noreply.github.com> Date: Thu, 26 Dec 2024 16:52:12 +0000 Subject: [PATCH 23/34] feat: add cache to evm plugin --- packages/plugin-evm/src/providers/wallet.ts | 106 +++++++++++++++++- .../plugin-evm/src/tests/transfer.test.ts | 18 ++- packages/plugin-evm/src/tests/wallet.test.ts | 36 ++++-- packages/plugin-evm/tsup.config.ts | 2 + 4 files changed, 145 insertions(+), 17 deletions(-) diff --git a/packages/plugin-evm/src/providers/wallet.ts b/packages/plugin-evm/src/providers/wallet.ts index 752f6b7c05..ac5537bf08 100644 --- a/packages/plugin-evm/src/providers/wallet.ts +++ b/packages/plugin-evm/src/providers/wallet.ts @@ -5,7 +5,7 @@ import { http, } from "viem"; import { privateKeyToAccount } from "viem/accounts"; -import type { IAgentRuntime, Provider, Memory, State } from "@elizaos/core"; +import type { IAgentRuntime, Provider, Memory, State, ICacheManager } from "@elizaos/core"; import type { Address, WalletClient, @@ -17,16 +17,21 @@ import type { } from "viem"; import * as viemChains from "viem/chains"; import { DeriveKeyProvider, TEEMode } from "@elizaos/plugin-tee"; +import NodeCache from "node-cache"; +import * as path from "path"; import type { SupportedChain } from "../types"; export class WalletProvider { + private cache: NodeCache; + private cacheKey: string = "evm/wallet"; private currentChain: SupportedChain = "mainnet"; chains: Record = { mainnet: viemChains.mainnet }; account: PrivateKeyAccount; constructor( accountOrPrivateKey: PrivateKeyAccount | `0x${string}`, + private cacheManager: ICacheManager, chains?: Record ) { this.setAccount(accountOrPrivateKey); @@ -35,6 +40,8 @@ export class WalletProvider { if (chains && Object.keys(chains).length > 0) { this.setCurrentChain(Object.keys(chains)[0] as SupportedChain); } + + this.cache = new NodeCache({ stdTTL: 5 }); } getAddress(): Address { @@ -80,12 +87,22 @@ export class WalletProvider { } async getWalletBalance(): Promise { + const cacheKey = "walletBalance_" + this.currentChain; + const cachedData = await this.getCachedData(cacheKey); + if (cachedData) { + console.log("Returning cached wallet balance for chain: " + this.currentChain); + return cachedData; + } + try { const client = this.getPublicClient(this.currentChain); const balance = await client.getBalance({ address: this.account.address, }); - return formatUnits(balance, 18); + const balanceFormatted = formatUnits(balance, 18); + this.setCachedData(cacheKey, balanceFormatted); + console.log("Wallet balance cached for chain: ", this.currentChain); + return balanceFormatted; } catch (error) { console.error("Error getting wallet balance:", error); return null; @@ -122,6 +139,84 @@ export class WalletProvider { this.setCurrentChain(chainName); } + private async readFromCache(key: string): Promise { + const cached = await this.cacheManager.get( + path.join(this.cacheKey, key) + ); + return cached; + } + + private async writeToCache(key: string, data: T): Promise { + await this.cacheManager.set(path.join(this.cacheKey, key), data, { + expires: Date.now() + 5 * 60 * 1000, + }); + } + + private async getCachedData(key: string): Promise { + // Check in-memory cache first + const cachedData = this.cache.get(key); + if (cachedData) { + return cachedData; + } + + // Check file-based cache + const fileCachedData = await this.readFromCache(key); + if (fileCachedData) { + // Populate in-memory cache + this.cache.set(key, fileCachedData); + return fileCachedData; + } + + return null; + } + + private async setCachedData(cacheKey: string, data: T): Promise { + // Set in-memory cache + this.cache.set(cacheKey, data); + + // Write to file-based cache + await this.writeToCache(cacheKey, data); + } + + private async readFromCache(key: string): Promise { + const cached = await this.cacheManager.get( + path.join(this.cacheKey, key) + ); + return cached; + } + + private async writeToCache(key: string, data: T): Promise { + await this.cacheManager.set(path.join(this.cacheKey, key), data, { + expires: Date.now() + 5 * 60 * 1000, + }); + } + + private async getCachedData(key: string): Promise { + // Check in-memory cache first + const cachedData = this.cache.get(key); + if (cachedData) { + return cachedData; + } + + // Check file-based cache + const fileCachedData = await this.readFromCache(key); + if (fileCachedData) { + // Populate in-memory cache + this.cache.set(key, fileCachedData); + return fileCachedData; + } + + return null; + } + + private async setCachedData(cacheKey: string, data: T): Promise { + // Set in-memory cache + this.cache.set(cacheKey, data); + + // Write to file-based cache + await this.writeToCache(cacheKey, data); + } + private setAccount = ( accountOrPrivateKey: PrivateKeyAccount | `0x${string}` ) => { @@ -234,7 +329,7 @@ export const initWalletProvider = async (runtime: IAgentRuntime) => { if (!privateKey) { throw new Error("EVM_PRIVATE_KEY is missing"); } - return new WalletProvider(privateKey, chains); + return new WalletProvider(privateKey, runtime.cacheManager, chains); } }; @@ -242,14 +337,15 @@ export const evmWalletProvider: Provider = { async get( runtime: IAgentRuntime, _message: Memory, - _state?: State + state?: State ): Promise { try { const walletProvider = await initWalletProvider(runtime); const address = walletProvider.getAddress(); const balance = await walletProvider.getWalletBalance(); const chain = walletProvider.getCurrentChain(); - return `EVM Wallet Address: ${address}\nBalance: ${balance} ${chain.nativeCurrency.symbol}\nChain ID: ${chain.id}, Name: ${chain.name}`; + const agentName = state?.agentName || "The agent"; + return `${agentName}'s EVM Wallet Address: ${address}\nBalance: ${balance} ${chain.nativeCurrency.symbol}\nChain ID: ${chain.id}, Name: ${chain.name}`; } catch (error) { console.error("Error in EVM wallet provider:", error); return null; diff --git a/packages/plugin-evm/src/tests/transfer.test.ts b/packages/plugin-evm/src/tests/transfer.test.ts index a6159db76d..5b3b2df118 100644 --- a/packages/plugin-evm/src/tests/transfer.test.ts +++ b/packages/plugin-evm/src/tests/transfer.test.ts @@ -1,18 +1,32 @@ -import { describe, it, expect, beforeEach } from "vitest"; +import { describe, it, expect, beforeEach, vi, afterEach } from "vitest"; import { generatePrivateKey, privateKeyToAccount } from "viem/accounts"; import { Account, Chain } from "viem"; import { TransferAction } from "../actions/transfer"; import { WalletProvider } from "../providers/wallet"; +// Mock the ICacheManager +const mockCacheManager = { + get: vi.fn().mockResolvedValue(null), + set: vi.fn(), +}; + describe("Transfer Action", () => { let wp: WalletProvider; beforeEach(async () => { + vi.clearAllMocks(); + mockCacheManager.get.mockResolvedValue(null); + const pk = generatePrivateKey(); const customChains = prepareChains(); - wp = new WalletProvider(pk, customChains); + wp = new WalletProvider(mockCacheManager as any, pk, customChains); }); + + afterEach(() => { + vi.clearAllTimers(); + }); + describe("Constructor", () => { it("should initialize with wallet provider", () => { const ta = new TransferAction(wp); diff --git a/packages/plugin-evm/src/tests/wallet.test.ts b/packages/plugin-evm/src/tests/wallet.test.ts index a6b227a470..b0b8b6a7cf 100644 --- a/packages/plugin-evm/src/tests/wallet.test.ts +++ b/packages/plugin-evm/src/tests/wallet.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeAll, beforeEach } from "vitest"; +import { describe, it, expect, beforeAll, beforeEach, vi, afterEach } from "vitest"; import { generatePrivateKey, privateKeyToAccount } from "viem/accounts"; import { mainnet, iotex, arbitrum, Chain } from "viem/chains"; @@ -10,6 +10,13 @@ const customRpcUrls = { iotex: "custom-rpc.iotex.io", }; +// Mock the ICacheManager +const mockCacheManager = { + get: vi.fn().mockResolvedValue(null), + set: vi.fn(), +}; + + describe("Wallet provider", () => { let walletProvider: WalletProvider; let pk: `0x${string}`; @@ -25,36 +32,45 @@ describe("Wallet provider", () => { ); }); + afterEach(() => { + vi.clearAllTimers(); + }); + + beforeEach(() => { + vi.clearAllMocks(); + mockCacheManager.get.mockResolvedValue(null); + }); + describe("Constructor", () => { it("sets address", () => { const account = privateKeyToAccount(pk); const expectedAddress = account.address; - walletProvider = new WalletProvider(pk); + walletProvider = new WalletProvider(mockCacheManager as any, pk); expect(walletProvider.getAddress()).toEqual(expectedAddress); }); it("sets default chain to ethereum mainnet", () => { - walletProvider = new WalletProvider(pk); + walletProvider = new WalletProvider(mockCacheManager as any, pk); expect(walletProvider.chains.mainnet.id).toEqual(mainnet.id); expect(walletProvider.getCurrentChain().id).toEqual(mainnet.id); }); it("sets custom chains", () => { - walletProvider = new WalletProvider(pk, customChains); + walletProvider = new WalletProvider(mockCacheManager as any, pk, customChains); expect(walletProvider.chains.iotex.id).toEqual(iotex.id); expect(walletProvider.chains.arbitrum.id).toEqual(arbitrum.id); }); it("sets the first provided custom chain as current chain", () => { - walletProvider = new WalletProvider(pk, customChains); + walletProvider = new WalletProvider(mockCacheManager as any, pk, customChains); expect(walletProvider.getCurrentChain().id).toEqual(iotex.id); }); }); describe("Clients", () => { beforeEach(() => { - walletProvider = new WalletProvider(pk); + walletProvider = new WalletProvider(mockCacheManager as any, pk); }); it("generates public client", () => { const client = walletProvider.getPublicClient("mainnet"); @@ -68,7 +84,7 @@ describe("Wallet provider", () => { "mainnet", customRpcUrls.mainnet ); - const wp = new WalletProvider(pk, { ["mainnet"]: chain }); + const wp = new WalletProvider(mockCacheManager as any, pk, { ["mainnet"]: chain }); const client = wp.getPublicClient("mainnet"); expect(client.chain.id).toEqual(mainnet.id); @@ -98,7 +114,7 @@ describe("Wallet provider", () => { "mainnet", customRpcUrls.mainnet ); - const wp = new WalletProvider(pk, { ["mainnet"]: chain }); + const wp = new WalletProvider(mockCacheManager as any, pk, { ["mainnet"]: chain }); const client = wp.getWalletClient("mainnet"); @@ -115,7 +131,7 @@ describe("Wallet provider", () => { }); describe("Balance", () => { beforeEach(() => { - walletProvider = new WalletProvider(pk, customChains); + walletProvider = new WalletProvider(mockCacheManager as any, pk, customChains); }); it("should fetch balance", async () => { const bal = await walletProvider.getWalletBalance(); @@ -134,7 +150,7 @@ describe("Wallet provider", () => { }); describe("Chain", () => { beforeEach(() => { - walletProvider = new WalletProvider(pk, customChains); + walletProvider = new WalletProvider(mockCacheManager as any, pk, customChains); }); it("generates chains from chain name", () => { const chainName = "iotex"; diff --git a/packages/plugin-evm/tsup.config.ts b/packages/plugin-evm/tsup.config.ts index a68ccd636a..1cecf6b75b 100644 --- a/packages/plugin-evm/tsup.config.ts +++ b/packages/plugin-evm/tsup.config.ts @@ -17,5 +17,7 @@ export default defineConfig({ "agentkeepalive", "viem", "@lifi/sdk", + "events", + "node-cache" ], }); From a66938e876a642bfbe1230ec204ee38dd07fd640 Mon Sep 17 00:00:00 2001 From: Nikita Ruban <64008830+nicky-ru@users.noreply.github.com> Date: Sun, 29 Dec 2024 09:01:28 +0000 Subject: [PATCH 24/34] fix: align transfer action to it's type --- packages/plugin-evm/src/actions/transfer.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/plugin-evm/src/actions/transfer.ts b/packages/plugin-evm/src/actions/transfer.ts index 7ca220da14..e9dfd2a12d 100644 --- a/packages/plugin-evm/src/actions/transfer.ts +++ b/packages/plugin-evm/src/actions/transfer.ts @@ -1,5 +1,6 @@ import { ByteArray, formatEther, parseEther, type Hex } from "viem"; import { + Action, composeContext, generateObjectDeprecated, HandlerCallback, @@ -104,7 +105,7 @@ const buildTransferDetails = async ( return transferDetails; }; -export const transferAction = { +export const transferAction: Action = { name: "transfer", description: "Transfer tokens between addresses on the same chain", handler: async ( @@ -151,7 +152,6 @@ export const transferAction = { return false; } }, - template: transferTemplate, validate: async (runtime: IAgentRuntime) => { const privateKey = runtime.getSetting("EVM_PRIVATE_KEY"); return typeof privateKey === "string" && privateKey.startsWith("0x"); From f08f41aaf8192cf3aff1fd984a7a2dfc96c8e42f Mon Sep 17 00:00:00 2001 From: Nikita Ruban <64008830+nicky-ru@users.noreply.github.com> Date: Sun, 29 Dec 2024 09:37:37 +0000 Subject: [PATCH 25/34] perf: update evm state on transfer --- packages/plugin-evm/src/actions/transfer.ts | 20 +++++++++++--------- packages/plugin-evm/src/templates/index.ts | 15 +++++++++++++-- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/packages/plugin-evm/src/actions/transfer.ts b/packages/plugin-evm/src/actions/transfer.ts index e9dfd2a12d..c76dfd2644 100644 --- a/packages/plugin-evm/src/actions/transfer.ts +++ b/packages/plugin-evm/src/actions/transfer.ts @@ -73,21 +73,17 @@ const buildTransferDetails = async ( runtime: IAgentRuntime, wp: WalletProvider ): Promise => { + const chains = Object.keys(wp.chains); + state.supportedChains = chains.map((item) => `"${item}"`).join("|"); + const context = composeContext({ state, template: transferTemplate, }); - const chains = Object.keys(wp.chains); - - const contextWithChains = context.replace( - "SUPPORTED_CHAINS", - chains.map((item) => `"${item}"`).join("|") - ); - const transferDetails = (await generateObjectDeprecated({ runtime, - context: contextWithChains, + context, modelClass: ModelClass.SMALL, })) as TransferParams; @@ -110,11 +106,17 @@ export const transferAction: Action = { description: "Transfer tokens between addresses on the same chain", handler: async ( runtime: IAgentRuntime, - _message: Memory, + message: Memory, state: State, _options: any, callback?: HandlerCallback ) => { + if (!state) { + state = (await runtime.composeState(message)) as State; + } else { + state = await runtime.updateRecentMessageState(state); + } + console.log("Transfer action handler called"); const walletProvider = await initWalletProvider(runtime); const action = new TransferAction(walletProvider); diff --git a/packages/plugin-evm/src/templates/index.ts b/packages/plugin-evm/src/templates/index.ts index 8c89bcbc4b..d349c51e0c 100644 --- a/packages/plugin-evm/src/templates/index.ts +++ b/packages/plugin-evm/src/templates/index.ts @@ -1,5 +1,8 @@ -export const transferTemplate = `Given the recent messages and wallet information below: +export const transferTemplate = `You are an AI assistant specialized in processing cryptocurrency transfer requests. Your task is to extract specific information from user messages and format it into a structured JSON response. +First, review the recent messages from the conversation: + + {{recentMessages}} {{walletInfo}} @@ -14,12 +17,20 @@ Respond with a JSON markdown block containing only the extracted values. All fie \`\`\`json { - "fromChain": SUPPORTED_CHAINS, + "fromChain": string, "amount": string, "toAddress": string, "token": string | null } \`\`\` + +Remember: +- The chain name must be a string and must exactly match one of the supported chains. +- The amount should be a string representing the number without any currency symbol. +- The recipient address must be a valid Ethereum address starting with "0x". +- If no specific token is mentioned (i.e., it's a native token transfer), set the "token" field to null. + +Now, process the user's request and provide your response. `; export const bridgeTemplate = `Given the recent messages and wallet information below: From 5368be4757330c4a7a1ce4277bbcbf0a4a752968 Mon Sep 17 00:00:00 2001 From: Nikita Ruban <64008830+nicky-ru@users.noreply.github.com> Date: Thu, 2 Jan 2025 14:22:42 +0000 Subject: [PATCH 26/34] fix: remove duplicated code, add cache expiry constant --- packages/plugin-evm/src/providers/wallet.ts | 46 ++------------------- 1 file changed, 4 insertions(+), 42 deletions(-) diff --git a/packages/plugin-evm/src/providers/wallet.ts b/packages/plugin-evm/src/providers/wallet.ts index ac5537bf08..852e77f339 100644 --- a/packages/plugin-evm/src/providers/wallet.ts +++ b/packages/plugin-evm/src/providers/wallet.ts @@ -26,6 +26,7 @@ export class WalletProvider { private cache: NodeCache; private cacheKey: string = "evm/wallet"; private currentChain: SupportedChain = "mainnet"; + private CACHE_EXPIRY_SEC = 5; chains: Record = { mainnet: viemChains.mainnet }; account: PrivateKeyAccount; @@ -41,7 +42,7 @@ export class WalletProvider { this.setCurrentChain(Object.keys(chains)[0] as SupportedChain); } - this.cache = new NodeCache({ stdTTL: 5 }); + this.cache = new NodeCache({ stdTTL: this.CACHE_EXPIRY_SEC }); } getAddress(): Address { @@ -148,46 +149,7 @@ export class WalletProvider { private async writeToCache(key: string, data: T): Promise { await this.cacheManager.set(path.join(this.cacheKey, key), data, { - expires: Date.now() + 5 * 60 * 1000, - }); - } - - private async getCachedData(key: string): Promise { - // Check in-memory cache first - const cachedData = this.cache.get(key); - if (cachedData) { - return cachedData; - } - - // Check file-based cache - const fileCachedData = await this.readFromCache(key); - if (fileCachedData) { - // Populate in-memory cache - this.cache.set(key, fileCachedData); - return fileCachedData; - } - - return null; - } - - private async setCachedData(cacheKey: string, data: T): Promise { - // Set in-memory cache - this.cache.set(cacheKey, data); - - // Write to file-based cache - await this.writeToCache(cacheKey, data); - } - - private async readFromCache(key: string): Promise { - const cached = await this.cacheManager.get( - path.join(this.cacheKey, key) - ); - return cached; - } - - private async writeToCache(key: string, data: T): Promise { - await this.cacheManager.set(path.join(this.cacheKey, key), data, { - expires: Date.now() + 5 * 60 * 1000, + expires: Date.now() + this.CACHE_EXPIRY_SEC * 1000, }); } @@ -321,7 +283,7 @@ export const initWalletProvider = async (runtime: IAgentRuntime) => { walletSecretSalt, runtime.agentId ); - return new WalletProvider(deriveKeyResult.keypair, chains); + return new WalletProvider(deriveKeyResult.keypair, runtime.cacheManager, chains); } else { const privateKey = runtime.getSetting( "EVM_PRIVATE_KEY" From 9fbb0d71c4c77da42af0e17df99527d1c9603f1f Mon Sep 17 00:00:00 2001 From: Nikita Ruban <64008830+nicky-ru@users.noreply.github.com> Date: Thu, 2 Jan 2025 14:23:14 +0000 Subject: [PATCH 27/34] test: align tests to new Wallet provider contructor --- packages/plugin-evm/src/tests/transfer.test.ts | 2 +- packages/plugin-evm/src/tests/wallet.test.ts | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/plugin-evm/src/tests/transfer.test.ts b/packages/plugin-evm/src/tests/transfer.test.ts index 5b3b2df118..ff2a088777 100644 --- a/packages/plugin-evm/src/tests/transfer.test.ts +++ b/packages/plugin-evm/src/tests/transfer.test.ts @@ -20,7 +20,7 @@ describe("Transfer Action", () => { const pk = generatePrivateKey(); const customChains = prepareChains(); - wp = new WalletProvider(mockCacheManager as any, pk, customChains); + wp = new WalletProvider(pk, mockCacheManager as any, customChains); }); afterEach(() => { diff --git a/packages/plugin-evm/src/tests/wallet.test.ts b/packages/plugin-evm/src/tests/wallet.test.ts index b0b8b6a7cf..ed19e04831 100644 --- a/packages/plugin-evm/src/tests/wallet.test.ts +++ b/packages/plugin-evm/src/tests/wallet.test.ts @@ -46,31 +46,31 @@ describe("Wallet provider", () => { const account = privateKeyToAccount(pk); const expectedAddress = account.address; - walletProvider = new WalletProvider(mockCacheManager as any, pk); + walletProvider = new WalletProvider(pk, mockCacheManager as any); expect(walletProvider.getAddress()).toEqual(expectedAddress); }); it("sets default chain to ethereum mainnet", () => { - walletProvider = new WalletProvider(mockCacheManager as any, pk); + walletProvider = new WalletProvider(pk, mockCacheManager as any); expect(walletProvider.chains.mainnet.id).toEqual(mainnet.id); expect(walletProvider.getCurrentChain().id).toEqual(mainnet.id); }); it("sets custom chains", () => { - walletProvider = new WalletProvider(mockCacheManager as any, pk, customChains); + walletProvider = new WalletProvider(pk, mockCacheManager as any, customChains); expect(walletProvider.chains.iotex.id).toEqual(iotex.id); expect(walletProvider.chains.arbitrum.id).toEqual(arbitrum.id); }); it("sets the first provided custom chain as current chain", () => { - walletProvider = new WalletProvider(mockCacheManager as any, pk, customChains); + walletProvider = new WalletProvider(pk, mockCacheManager as any, customChains); expect(walletProvider.getCurrentChain().id).toEqual(iotex.id); }); }); describe("Clients", () => { beforeEach(() => { - walletProvider = new WalletProvider(mockCacheManager as any, pk); + walletProvider = new WalletProvider(pk, mockCacheManager as any); }); it("generates public client", () => { const client = walletProvider.getPublicClient("mainnet"); @@ -84,7 +84,7 @@ describe("Wallet provider", () => { "mainnet", customRpcUrls.mainnet ); - const wp = new WalletProvider(mockCacheManager as any, pk, { ["mainnet"]: chain }); + const wp = new WalletProvider(pk, mockCacheManager as any, { ["mainnet"]: chain }); const client = wp.getPublicClient("mainnet"); expect(client.chain.id).toEqual(mainnet.id); @@ -114,7 +114,7 @@ describe("Wallet provider", () => { "mainnet", customRpcUrls.mainnet ); - const wp = new WalletProvider(mockCacheManager as any, pk, { ["mainnet"]: chain }); + const wp = new WalletProvider(pk, mockCacheManager as any, { ["mainnet"]: chain }); const client = wp.getWalletClient("mainnet"); @@ -131,7 +131,7 @@ describe("Wallet provider", () => { }); describe("Balance", () => { beforeEach(() => { - walletProvider = new WalletProvider(mockCacheManager as any, pk, customChains); + walletProvider = new WalletProvider(pk, mockCacheManager as any, customChains); }); it("should fetch balance", async () => { const bal = await walletProvider.getWalletBalance(); @@ -150,7 +150,7 @@ describe("Wallet provider", () => { }); describe("Chain", () => { beforeEach(() => { - walletProvider = new WalletProvider(mockCacheManager as any, pk, customChains); + walletProvider = new WalletProvider(pk, mockCacheManager as any, customChains); }); it("generates chains from chain name", () => { const chainName = "iotex"; From 8570869f2cfa45a06f54d31b1d1347660368d3aa Mon Sep 17 00:00:00 2001 From: Nikita Ruban <64008830+nicky-ru@users.noreply.github.com> Date: Thu, 2 Jan 2025 16:20:51 +0000 Subject: [PATCH 28/34] feat: improve transfer template --- packages/plugin-evm/src/templates/index.ts | 38 ++++++++++++++++++---- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/packages/plugin-evm/src/templates/index.ts b/packages/plugin-evm/src/templates/index.ts index d349c51e0c..9a146b081c 100644 --- a/packages/plugin-evm/src/templates/index.ts +++ b/packages/plugin-evm/src/templates/index.ts @@ -4,16 +4,40 @@ First, review the recent messages from the conversation: {{recentMessages}} + -{{walletInfo}} +Here's a list of supported chains: + +{{supportedChains}} + + +Your goal is to extract the following information about the requested transfer: +1. Chain to execute on (must be one of the supported chains) +2. Amount to transfer (in ETH, without the coin symbol) +3. Recipient address (must be a valid Ethereum address) +4. Token symbol or address (if not a native token transfer) + +Before providing the final JSON output, show your reasoning process inside tags. Follow these steps: + +1. Identify the relevant information from the user's message: + - Quote the part of the message mentioning the chain. + - Quote the part mentioning the amount. + - Quote the part mentioning the recipient address. + - Quote the part mentioning the token (if any). + +2. Validate each piece of information: + - Chain: List all supported chains and check if the mentioned chain is in the list. + - Amount: Attempt to convert the amount to a number to verify it's valid. + - Address: Check that it starts with "0x" and count the number of characters (should be 42). + - Token: Note whether it's a native transfer or if a specific token is mentioned. + +3. If any information is missing or invalid, prepare an appropriate error message. + +4. If all information is valid, summarize your findings. -Extract the following information about the requested transfer: -- Chain to execute on (like in viem/chains) -- Amount to transfer: Must be a string representing the amount in ETH (only number without coin symbol, e.g., "0.1") -- Recipient address: Must be a valid Ethereum address starting with "0x" -- Token symbol or address (if not native token): Optional, leave as null for ETH transfers +5. Prepare the JSON structure based on your analysis. -Respond with a JSON markdown block containing only the extracted values. All fields except 'token' are required: +After your analysis, provide the final output in a JSON markdown block. All fields except 'token' are required. The JSON should have this structure: \`\`\`json { From d4831c853fee7faeaf392cb23b05f2a1ab3c0266 Mon Sep 17 00:00:00 2001 From: Nikita Ruban <64008830+nicky-ru@users.noreply.github.com> Date: Thu, 2 Jan 2025 16:28:31 +0000 Subject: [PATCH 29/34] chore: remove unnecessary export --- packages/plugin-evm/src/actions/transfer.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/plugin-evm/src/actions/transfer.ts b/packages/plugin-evm/src/actions/transfer.ts index c76dfd2644..51c3b27ead 100644 --- a/packages/plugin-evm/src/actions/transfer.ts +++ b/packages/plugin-evm/src/actions/transfer.ts @@ -14,8 +14,6 @@ import { initWalletProvider, WalletProvider } from "../providers/wallet"; import type { Transaction, TransferParams } from "../types"; import { transferTemplate } from "../templates"; -export { transferTemplate }; - // Exported for tests export class TransferAction { constructor(private walletProvider: WalletProvider) {} From a8c279f080164c40fd413298ff4f7ab2ca33f377 Mon Sep 17 00:00:00 2001 From: Nikita Ruban <64008830+nicky-ru@users.noreply.github.com> Date: Thu, 2 Jan 2025 17:05:14 +0000 Subject: [PATCH 30/34] fix: log with elizalogger --- packages/plugin-evm/src/providers/wallet.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/plugin-evm/src/providers/wallet.ts b/packages/plugin-evm/src/providers/wallet.ts index 852e77f339..0e97a716df 100644 --- a/packages/plugin-evm/src/providers/wallet.ts +++ b/packages/plugin-evm/src/providers/wallet.ts @@ -5,7 +5,7 @@ import { http, } from "viem"; import { privateKeyToAccount } from "viem/accounts"; -import type { IAgentRuntime, Provider, Memory, State, ICacheManager } from "@elizaos/core"; +import { type IAgentRuntime, type Provider, type Memory, type State, type ICacheManager, elizaLogger } from "@elizaos/core"; import type { Address, WalletClient, @@ -91,7 +91,7 @@ export class WalletProvider { const cacheKey = "walletBalance_" + this.currentChain; const cachedData = await this.getCachedData(cacheKey); if (cachedData) { - console.log("Returning cached wallet balance for chain: " + this.currentChain); + elizaLogger.log("Returning cached wallet balance for chain: " + this.currentChain); return cachedData; } @@ -102,7 +102,7 @@ export class WalletProvider { }); const balanceFormatted = formatUnits(balance, 18); this.setCachedData(cacheKey, balanceFormatted); - console.log("Wallet balance cached for chain: ", this.currentChain); + elizaLogger.log("Wallet balance cached for chain: ", this.currentChain); return balanceFormatted; } catch (error) { console.error("Error getting wallet balance:", error); From 4edfd7638f775a7eed6d95ebfe76515cc2377ad3 Mon Sep 17 00:00:00 2001 From: denizekiz Date: Thu, 2 Jan 2025 18:13:40 +0300 Subject: [PATCH 31/34] supported url format provided --- packages/plugin-node/src/services/image.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/plugin-node/src/services/image.ts b/packages/plugin-node/src/services/image.ts index b77ca7daea..00cff18fe7 100644 --- a/packages/plugin-node/src/services/image.ts +++ b/packages/plugin-node/src/services/image.ts @@ -187,22 +187,22 @@ export class ImageDescriptionService ): Promise { for (let attempt = 0; attempt < 3; attempt++) { try { - const shouldUseBase64 = isGif || isLocalFile; + const shouldUseBase64 = isLocalFile; const mimeType = isGif ? "png" : path.extname(imageUrl).slice(1) || "jpeg"; const base64Data = imageData.toString("base64"); - const imageUrlToUse = shouldUseBase64 - ? `data:image/${mimeType};base64,${base64Data}` - : imageUrl; + //const imageUrlToUse = shouldUseBase64 + // ? `data:image/${mimeType};base64,${base64Data}` + //: imageUrl; const content = [ { type: "text", text: prompt }, { type: "image_url", image_url: { - url: imageUrlToUse, + url: imageUrl, }, }, ]; From dd23584e8375e3480c6608fda509d03aae85e393 Mon Sep 17 00:00:00 2001 From: denizekiz Date: Thu, 2 Jan 2025 18:18:55 +0300 Subject: [PATCH 32/34] fix --- packages/plugin-node/src/services/image.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/plugin-node/src/services/image.ts b/packages/plugin-node/src/services/image.ts index 00cff18fe7..3cba162752 100644 --- a/packages/plugin-node/src/services/image.ts +++ b/packages/plugin-node/src/services/image.ts @@ -187,7 +187,7 @@ export class ImageDescriptionService ): Promise { for (let attempt = 0; attempt < 3; attempt++) { try { - const shouldUseBase64 = isLocalFile; + const shouldUseBase64 = isGif || isLocalFile; const mimeType = isGif ? "png" : path.extname(imageUrl).slice(1) || "jpeg"; From 13c62ce8f7b12dead66c562750b8ce5088f3809b Mon Sep 17 00:00:00 2001 From: denizekiz Date: Thu, 2 Jan 2025 18:19:42 +0300 Subject: [PATCH 33/34] fix --- packages/plugin-node/src/services/image.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/plugin-node/src/services/image.ts b/packages/plugin-node/src/services/image.ts index 3cba162752..004e67c499 100644 --- a/packages/plugin-node/src/services/image.ts +++ b/packages/plugin-node/src/services/image.ts @@ -187,7 +187,7 @@ export class ImageDescriptionService ): Promise { for (let attempt = 0; attempt < 3; attempt++) { try { - const shouldUseBase64 = isGif || isLocalFile; + const shouldUseBase64 = isGif || isLocalFile; const mimeType = isGif ? "png" : path.extname(imageUrl).slice(1) || "jpeg"; From 9ea2449b8f49d4ced34ff084562bef9df3ee426f Mon Sep 17 00:00:00 2001 From: denizekiz Date: Thu, 2 Jan 2025 20:04:05 +0300 Subject: [PATCH 34/34] shouldUseBase64 fix --- packages/plugin-node/src/services/image.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/plugin-node/src/services/image.ts b/packages/plugin-node/src/services/image.ts index 004e67c499..44d88f9e7d 100644 --- a/packages/plugin-node/src/services/image.ts +++ b/packages/plugin-node/src/services/image.ts @@ -187,22 +187,22 @@ export class ImageDescriptionService ): Promise { for (let attempt = 0; attempt < 3; attempt++) { try { - const shouldUseBase64 = isGif || isLocalFile; + const shouldUseBase64 = (isGif || isLocalFile)&& !(this.runtime.imageModelProvider === ModelProviderName.OPENAI); const mimeType = isGif ? "png" : path.extname(imageUrl).slice(1) || "jpeg"; const base64Data = imageData.toString("base64"); - //const imageUrlToUse = shouldUseBase64 - // ? `data:image/${mimeType};base64,${base64Data}` - //: imageUrl; + const imageUrlToUse = shouldUseBase64 + ? `data:image/${mimeType};base64,${base64Data}` + : imageUrl; const content = [ { type: "text", text: prompt }, { type: "image_url", image_url: { - url: imageUrl, + url: imageUrlToUse, }, }, ];