diff --git a/.env.example b/.env.example index d2d89eda85c..b66fecf35a5 100644 --- a/.env.example +++ b/.env.example @@ -34,6 +34,9 @@ LARGE_HYPERBOLIC_MODEL= # Default: meta-llama/Meta-Llama-3.1-405-Instruc # Speech Synthesis ELEVENLABS_XI_API_KEY= # API key from elevenlabs +# Direct Client Setting +EXPRESS_MAX_PAYLOAD= # Default: 100kb + # ElevenLabs Settings ELEVENLABS_MODEL_ID=eleven_multilingual_v2 ELEVENLABS_VOICE_ID=21m00Tcm4TlvDq8ikWAM @@ -55,6 +58,7 @@ TWITTER_COOKIES= # Account cookies TWITTER_POLL_INTERVAL=120 # How often (in seconds) the bot should check for interactions TWITTER_SEARCH_ENABLE=FALSE # Enable timeline search, WARNING this greatly increases your chance of getting banned TWITTER_TARGET_USERS= # Comma separated list of Twitter user names to interact with +TWITTER_RETRY_LIMIT= # Maximum retry attempts for Twitter login X_SERVER_URL= XAI_API_KEY= diff --git a/.github/workflows/image.yaml b/.github/workflows/image.yaml index ddd543b0b9b..9c3ba375b15 100644 --- a/.github/workflows/image.yaml +++ b/.github/workflows/image.yaml @@ -9,53 +9,62 @@ on: # Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds. env: - REGISTRY: ghcr.io - IMAGE_NAME: ${{ github.repository }} + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} # There is a single job in this workflow. It's configured to run on the latest available version of Ubuntu. jobs: - build-and-push-image: - runs-on: ubuntu-latest - # Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job. - permissions: - contents: read - packages: write - attestations: write - id-token: write - # - steps: - - name: Checkout repository - uses: actions/checkout@v4 - # Uses the `docker/login-action` action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here. - - name: Log in to the Container registry - uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - # This step uses [docker/metadata-action](https://github.com/docker/metadata-action#about) to extract tags and labels that will be applied to the specified image. The `id` "meta" allows the output of this step to be referenced in a subsequent step. The `images` value provides the base name for the tags and labels. - - name: Extract metadata (tags, labels) for Docker - id: meta - uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 - with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - # This step uses the `docker/build-push-action` action to build the image, based on your repository's `Dockerfile`. If the build succeeds, it pushes the image to GitHub Packages. - # It uses the `context` parameter to define the build's context as the set of files located in the specified path. For more information, see "[Usage](https://github.com/docker/build-push-action#usage)" in the README of the `docker/build-push-action` repository. - # It uses the `tags` and `labels` parameters to tag and label the image with the output from the "meta" step. - - name: Build and push Docker image - id: push - uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 - with: - context: . - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - - # This step generates an artifact attestation for the image, which is an unforgeable statement about where and how it was built. It increases supply chain security for people who consume the image. For more information, see "[AUTOTITLE](/actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds)." - - name: Generate artifact attestation - uses: actions/attest-build-provenance@v1 - with: - subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}} - subject-digest: ${{ steps.push.outputs.digest }} - push-to-registry: true - + build-and-push-image: + runs-on: ubuntu-latest + # Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job. + permissions: + contents: read + packages: write + attestations: write + id-token: write + # + steps: + - name: Checkout repository + uses: actions/checkout@v4 + # Uses the `docker/login-action` action to log in to the Container registry registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here. + - name: Log in to the Container registry + uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + # This step uses [docker/metadata-action](https://github.com/docker/metadata-action#about) to extract tags and labels that will be applied to the specified image. The `id` "meta" allows the output of this step to be referenced in a subsequent step. The `images` value provides the base name for the tags and labels. + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + # This step uses the `docker/build-push-action` action to build the image, based on your repository's `Dockerfile`. If the build succeeds, it pushes the image to GitHub Packages. + # It uses the `context` parameter to define the build's context as the set of files located in the specified path. For more information, see "[Usage](https://github.com/docker/build-push-action#usage)" in the README of the `docker/build-push-action` repository. + # It uses the `tags` and `labels` parameters to tag and label the image with the output from the "meta" step. + - name: Build and push Docker image + id: push + uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + + # This step generates an artifact attestation for the image, which is an unforgeable statement about where and how it was built. It increases supply chain security for people who consume the image. For more information, see "[AUTOTITLE](/actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds)." + - name: Generate artifact attestation + uses: actions/attest-build-provenance@v1 + with: + subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}} + subject-digest: ${{ steps.push.outputs.digest }} + push-to-registry: true + + # This step makes the Docker image public, so users can pull it without authentication. + - name: Make Docker image public + run: | + curl \ + -X PATCH \ + -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ + -H "Accept: application/vnd.github.v3+json" \ + https://api.github.com/user/packages/container/${{ env.IMAGE_NAME }}/visibility \ + -d '{"visibility":"public"}' diff --git a/README_ES.md b/README_ES.md index a16e672d9c6..e009f73ffbd 100644 --- a/README_ES.md +++ b/README_ES.md @@ -9,7 +9,7 @@ - 📚 Ingestión e interacción sencilla con documentos - 💾 Memoria recuperable y almacenamiento de documentos - 🚀 Altamente extensible - cree sus propias acciones y clientes para expandir capacidades -- ☁️ Soporta múltiples modelos, incluyendo Llama local, OpenAI, Anthropic, Groq y más +- ☁️ Soporta múltiples modelos, incluidos Llama local, OpenAI, Anthropic, Groq y más - 📦 Funciona perfectamente ## Usos @@ -29,8 +29,8 @@ ### Edite el archivo .env -- Copie .env.example a .env y complete los valores apropiados -- Edite las variables de ambiente de TWITTER para agregar nombre de usuario y contraseña del bot +- Copie el archivo .env.example a .env y complete los valores apropiados +- Edite las variables de entorno de TWITTER para agregar nombre de usuario y contraseña del bot ### Edite el archivo de personaje diff --git a/README_FR.md b/README_FR.md index da2cfbd9e8c..5555c03a8e5 100644 --- a/README_FR.md +++ b/README_FR.md @@ -7,7 +7,7 @@ - 🛠 Support des connecteurs Discord/ Twitter / Telegram - 🔗 Support des différents modèles d'IA (Llama, Grok, OpenAI, Anthropic, etc.) - 👥 Gestion de plusieurs agents et assistance -- 📚 Import et intéractions avec différents types de documents simplifiés +- 📚 Import et interactions avec différents types de documents simplifiés - 💾 Accès aux données en mémoire et aux documents stockés - 🚀 Grande personnalisation possible : création de nouveaux clients et de nouvelles actions - 📦 Simplicité d'utilisation @@ -15,9 +15,9 @@ Que pouvez-vous faire avec Eliza? - 🤖 Chatbot -- 🕵 ️Agents autonomes +- 🕵 Agents autonomes - 📈 Processus automatisés -- 🎮 PNJ intéractifs +- 🎮 PNJ interactifs - 🧠 Trading automatisé # Premiers pas @@ -32,7 +32,7 @@ Que pouvez-vous faire avec Eliza? ### Editer le fichier .env -- Copier le fichier d'example et le remplir le avec les valeurs adéquates +- Copier le fichier d'exemple .env.example et le remplir avec les valeurs adéquates ``` cp .env.example .env @@ -59,10 +59,10 @@ pnpm start pnpm clean ``` -#### Ressources additionelles +#### Ressources additionnelles Il vous faudra peut-être installer Sharp. -Si il y a une erreur lors du lancement du bot, essayez d'installer Sharp comme ceci : +S'il y a une erreur lors du lancement du bot, essayez d'installer Sharp comme ceci : ``` pnpm install --include=optional sharp diff --git a/README_IT.md b/README_IT.md index d716be5d2dd..17979a0e413 100644 --- a/README_IT.md +++ b/README_IT.md @@ -9,17 +9,17 @@ - 🛠️ Connettori completi per Discord, Twitter e Telegram - 🔗 Supporto per tutti i modelli (Llama, Grok, OpenAI, Anthropic, ecc.) - 👥 Supporto multi-agente e per stanze -- 📚 Acquisisci ed interagisci facilmente con i tuoi documenti +- 📚 Acquisisci e interagisci facilmente con i tuoi documenti - 💾 Memoria recuperabile e archivio documenti - 🚀 Altamente estensibile - crea le tue azioni e clients personalizzati - ☁️ Supporto di numerosi modelli (Llama locale, OpenAI, Anthropic, Groq, ecc.) - 📦 Funziona e basta! -## 🎯 Casi d'Uso +## 🎯 Casi d'uso - 🤖 Chatbot - 🕵️ Agenti Autonomi -- 📈 Gestione Processi Aziendali +- 📈 Gestione dei processi aziendali - 🎮 NPC per Videogiochi - 🧠 Trading @@ -51,7 +51,7 @@ sh scripts/start.sh ### Modifica il file del personaggio -1. Apri `packages/agent/src/character.ts` per modificare il personaggio predefinito. Decommentare e modificare. +1. Apri `packages/agent/src/character.ts` per modificare il personaggio predefinito. Decommenta e modifica. 2. Per caricare personaggi personalizzati: - Usa `pnpm start --characters="percorso/del/tuo/personaggio.json"` @@ -76,10 +76,10 @@ Potrebbe essere necessario installare Sharp. Se vedi un errore all'avvio, prova pnpm install --include=optional sharp ``` -### Community e contatti +### Comunità e contatti -- [GitHub Issues](https://github.com/ai16z/eliza/issues). Ideale per: bug riscontrati utilizzando Eliza e proposte di funzionalità. -- [Discord](https://discord.gg/ai16z). Ideale per: condividere le tue applicazioni e interagire con la community. +- [GitHub Issues](https://github.com/ai16z/eliza/issues). Ideale per segnalare bug riscontrati durante l’utilizzo di Eliza e proporre nuove funzionalità. +- [Discord](https://discord.gg/ai16z). Ideale per condividere le tue applicazioni e interagire con la comunità. ## Contributori diff --git a/agent/src/index.ts b/agent/src/index.ts index 5e458013302..e7101cbd8cc 100644 --- a/agent/src/index.ts +++ b/agent/src/index.ts @@ -581,7 +581,7 @@ function initializeDbCache(character: Character, db: IDatabaseCacheAdapter) { async function startAgent( character: Character, - directClient + directClient: DirectClient ): Promise { let db: IDatabaseAdapter & IDatabaseCacheAdapter; try { @@ -656,7 +656,7 @@ const startAgents = async () => { } // upload some agent functionality into directClient - directClient.startAgent = async (character) => { + directClient.startAgent = async (character: Character) => { // wrap it so we don't have to inject directClient later return startAgent(character, directClient); }; diff --git a/characters/trump.character.json b/characters/trump.character.json index 72f23966dfa..e22380de417 100644 --- a/characters/trump.character.json +++ b/characters/trump.character.json @@ -10,7 +10,7 @@ }, "plugins": [], "bio": [ - "SAVED America from the China Virus (while they let cities burn)", + "SAVED America from COVID-19 (while they let cities burn)", "secured the Southern Border COMPLETELY (until they DESTROYED it)", "protected WOMEN'S SPORTS (while Democrats let MEN compete)", "ended INFLATION and made America AFFORDABLE (until Kamala ruined it)", diff --git a/client/vite.config.ts b/client/vite.config.ts index e58c973caf9..32d1e1b9fd3 100644 --- a/client/vite.config.ts +++ b/client/vite.config.ts @@ -3,6 +3,9 @@ import { defineConfig } from "vite"; import topLevelAwait from "vite-plugin-top-level-await"; import react from "@vitejs/plugin-react"; import wasm from "vite-plugin-wasm"; +import { config } from "dotenv"; + +config({ path: path.resolve(__dirname, "../.env") }); // https://vite.dev/config/ export default defineConfig({ @@ -26,7 +29,7 @@ export default defineConfig({ server: { proxy: { "/api": { - target: "http://localhost:3000", + target: `http://localhost:${process.env.SERVER_PORT || 3000}`, changeOrigin: true, rewrite: (path) => path.replace(/^\/api/, ""), }, diff --git a/packages/client-direct/src/api.ts b/packages/client-direct/src/api.ts index fe26cee8f3c..4221772d1c6 100644 --- a/packages/client-direct/src/api.ts +++ b/packages/client-direct/src/api.ts @@ -5,17 +5,27 @@ import cors from "cors"; import { AgentRuntime, elizaLogger, + getEnvVariable, validateCharacterConfig, } from "@ai16z/eliza"; import { REST, Routes } from "discord.js"; +import { DirectClient } from "."; -export function createApiRouter(agents: Map, directClient) { +export function createApiRouter( + agents: Map, + directClient: DirectClient +) { const router = express.Router(); router.use(cors()); router.use(bodyParser.json()); router.use(bodyParser.urlencoded({ extended: true })); + router.use( + express.json({ + limit: getEnvVariable("EXPRESS_MAX_PAYLOAD") || "100kb", + }) + ); router.get("/", (req, res) => { res.send("Welcome, this is the REST API!"); @@ -51,33 +61,33 @@ export function createApiRouter(agents: Map, directClient) router.post("/agents/:agentId/set", async (req, res) => { const agentId = req.params.agentId; - console.log('agentId', agentId) - let agent:AgentRuntime = agents.get(agentId); + console.log("agentId", agentId); + let agent: AgentRuntime = agents.get(agentId); // update character if (agent) { // stop agent - agent.stop() - directClient.unregisterAgent(agent) + agent.stop(); + directClient.unregisterAgent(agent); // if it has a different name, the agentId will change } // load character from body - const character = req.body + const character = req.body; try { - validateCharacterConfig(character) - } catch(e) { - elizaLogger.error(`Error parsing character: ${e}`); - res.status(400).json({ - success: false, - message: e.message, - }); - return; + validateCharacterConfig(character); + } catch (e) { + elizaLogger.error(`Error parsing character: ${e}`); + res.status(400).json({ + success: false, + message: e.message, + }); + return; } // start it up (and register it) - agent = await directClient.startAgent(character) - elizaLogger.log(`${character.name} started`) + agent = await directClient.startAgent(character); + elizaLogger.log(`${character.name} started`); res.json({ id: character.id, @@ -85,7 +95,6 @@ export function createApiRouter(agents: Map, directClient) }); }); - router.get("/agents/:agentId/channels", async (req, res) => { const agentId = req.params.agentId; const runtime = agents.get(agentId); diff --git a/packages/client-twitter/src/base.ts b/packages/client-twitter/src/base.ts index 76fe766bf13..861821170df 100644 --- a/packages/client-twitter/src/base.ts +++ b/packages/client-twitter/src/base.ts @@ -157,6 +157,10 @@ export class ClientBase extends EventEmitter { const username = this.runtime.getSetting("TWITTER_USERNAME"); const password = this.runtime.getSetting("TWITTER_PASSWORD"); const email = this.runtime.getSetting("TWITTER_EMAIL"); + let retries = parseInt( + this.runtime.getSetting("TWITTER_RETRY_LIMIT") || "5", + 10 + ); const twitter2faSecret = this.runtime.getSetting("TWITTER_2FA_SECRET") || undefined; const cookies = this.runtime.getSetting("TWITTER_COOKIES"); @@ -180,7 +184,6 @@ export class ClientBase extends EventEmitter { } elizaLogger.log("Waiting for Twitter login"); - let retries = 5; // Optional: Set a retry limit while (retries > 0) { const cookies = await this.twitterClient.getCookies(); if ((await this.twitterClient.isLoggedIn()) && !!cookies) { diff --git a/packages/client-twitter/src/index.ts b/packages/client-twitter/src/index.ts index b973b84eaed..2476afd6d00 100644 --- a/packages/client-twitter/src/index.ts +++ b/packages/client-twitter/src/index.ts @@ -1,42 +1,39 @@ +import { Client, elizaLogger, IAgentRuntime } from "@ai16z/eliza"; +import { ClientBase } from "./base.ts"; +import { validateTwitterConfig } from "./environment.ts"; +import { TwitterInteractionClient } from "./interactions.ts"; import { TwitterPostClient } from "./post.ts"; import { TwitterSearchClient } from "./search.ts"; -import { TwitterInteractionClient } from "./interactions.ts"; -import { IAgentRuntime, Client, elizaLogger } from "@ai16z/eliza"; -import { validateTwitterConfig } from "./environment.ts"; -import { ClientBase } from "./base.ts"; class TwitterManager { client: ClientBase; post: TwitterPostClient; search: TwitterSearchClient; interaction: TwitterInteractionClient; - constructor(runtime: IAgentRuntime, enableSearch:boolean) { + constructor(runtime: IAgentRuntime, enableSearch: boolean) { this.client = new ClientBase(runtime); this.post = new TwitterPostClient(this.client, runtime); if (enableSearch) { - // this searches topics from character file - elizaLogger.warn('Twitter/X client running in a mode that:') - elizaLogger.warn('1. violates consent of random users') - elizaLogger.warn('2. burns your rate limit') - elizaLogger.warn('3. can get your account banned') - elizaLogger.warn('use at your own risk') - this.search = new TwitterSearchClient(this.client, runtime); // don't start the search client by default + // this searches topics from character file + elizaLogger.warn("Twitter/X client running in a mode that:"); + elizaLogger.warn("1. violates consent of random users"); + elizaLogger.warn("2. burns your rate limit"); + elizaLogger.warn("3. can get your account banned"); + elizaLogger.warn("use at your own risk"); + this.search = new TwitterSearchClient(this.client, runtime); } + this.interaction = new TwitterInteractionClient(this.client, runtime); } } export const TwitterClientInterface: Client = { - async start(runtime: IAgentRuntime) { await validateTwitterConfig(runtime); elizaLogger.log("Twitter client started"); - // enableSearch is just set previous to this call - // so enableSearch can change over time - // and changing it won't stop the SearchClient in the existing instance const manager = new TwitterManager(runtime, this.enableSearch); await manager.client.init(); @@ -45,7 +42,7 @@ export const TwitterClientInterface: Client = { await manager.interaction.start(); - //await manager.search.start(); // don't run the search by default + await manager.search?.start(); return manager; }, diff --git a/packages/client-twitter/src/interactions.ts b/packages/client-twitter/src/interactions.ts index 1a069b62730..bd71684bf41 100644 --- a/packages/client-twitter/src/interactions.ts +++ b/packages/client-twitter/src/interactions.ts @@ -398,9 +398,7 @@ export class TwitterInteractionClient { const shouldRespondContext = composeContext({ state, template: - this.runtime.character.templates?.twitterShouldRespondTemplate?.( - validTargetUsersStr - ) || + this.runtime.character.templates?.twitterShouldRespondTemplate || this.runtime.character?.templates?.shouldRespondTemplate || twitterShouldRespondTemplate(validTargetUsersStr), });