diff --git a/.dockerignore b/.dockerignore index e234e9516c5..3814253a96d 100644 --- a/.dockerignore +++ b/.dockerignore @@ -16,4 +16,5 @@ node_modules # Ignore build artifacts from the host dist -build \ No newline at end of file +build +.env \ No newline at end of file diff --git a/.env.example b/.env.example index 96262f223a9..b68c9c07819 100644 --- a/.env.example +++ b/.env.example @@ -79,4 +79,10 @@ JUPITER_API_KEY= HELIUS_API_KEY= COINMARKETCAP_API_KEY= ZEROEX_API_KEY= -COINGECKO_API_KEY= \ No newline at end of file +COINGECKO_API_KEY= + +GROQ_API_KEY= +EMBEDDING_GROQ_MODEL=llama-3.1-8b-instant +LARGE_GROQ_MODEL=llama-3.2-90b-vision-preview +MEDIUM_GROQ_MODEL=llama-3.3-70b-versatile +SMALL_GROQ_MODEL=llama-3.1-8b-instant \ No newline at end of file diff --git a/.github/workflows/generate-readme-translations.yml b/.github/workflows/generate-readme-translations.yml index 2fdf3e409fb..97877de18c2 100644 --- a/.github/workflows/generate-readme-translations.yml +++ b/.github/workflows/generate-readme-translations.yml @@ -63,7 +63,7 @@ jobs: } ], save_path: "packages/docs/packages/docs/i18n/readme/README_${{ matrix.language.code }}.md", - "model": "gpt-4o" + "model": "gpt-422222o" } # Upload each translated file as an artifact diff --git a/.github/workflows/image.yaml b/.github/workflows/image.yaml index c9a8cc518f2..fab341a989d 100644 --- a/.github/workflows/image.yaml +++ b/.github/workflows/image.yaml @@ -1,70 +1,98 @@ -# name: Create and publish a Docker image -# Configures this workflow to run every time a change is pushed to the branch called `release`. on: - release: - types: [created] workflow_dispatch: + #push: + #pull_request: + # on: + push: + branches: + - main + - docker/*/*/* -# 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 }} -# 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: Configure AWS credentials + # uses: meta-introspector/configure-aws-credentials@v4 + # with: + # aws-region: ${{ secrets.AWS_REGION || 'us-east-2'}} + # role-session-name: github-actions-${{ env.APP_NAME || 'eliza'}} + # # FIXME hard coded + # role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID || '767503528736' }}:role/github + + - name: Set up Docker Buildx + uses: meta-introspector/setup-buildx-action@v3.8.0 + with: + install: true + platforms: linux/amd64,linux/arm/v7,linux/arm/v8 + + # - name: Login to Amazon ECR + # id: login-ecr + # uses: meta-introspector/amazon-ecr-login@v1 + + - name: Set short sha + id: sha_short + run: echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT + + - name: Login to Docker Hub + uses: meta-introspector/login-action@v3 + with: + username: ${{ vars.DOCKER_HUB_USERNAME }} + password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} + - name: Checkout repository - uses: actions/checkout@v4 - # Uses the `docker/login-action` action to log in to the Container registry using the account and password that will publish the packages. Once published, the packages are scoped to the account defined here. + uses: meta-introspector/checkout@v4 + - name: Log in to the Container registry - uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 + uses: meta-introspector/login-action@v3.0.0 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 + uses: meta-introspector/metadata-action@v5.5.1 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. + images: | + ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + h4ckermike/elizaos-eliza + # ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY || 'agent/eliza'}} - name: Build and push Docker image id: push - uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 + uses: meta-introspector/build-push-action@v6.10.0 with: + platforms: linux/arm64,linux/arm64/v8 context: . push: true - tags: ${{ steps.meta.outputs.tags }} + 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 + uses: meta-introspector/attest-build-provenance@local 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"}' + -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/.github/workflows/jsdoc-automation.yml b/.github/workflows/jsdoc-automation.yml index eecad6caa95..d08130f5f57 100644 --- a/.github/workflows/jsdoc-automation.yml +++ b/.github/workflows/jsdoc-automation.yml @@ -8,11 +8,13 @@ on: required: true default: 'T' type: string + options: [T, F] readme: description: 'Generate README documentation (T/F)' required: true default: 'T' type: string + options: [T, F] pull_number: description: 'Pull Request Number (if not provided, scans root_directory) - PR must be merged to develop branch. DONT provide if `README documentation` is T from above' required: false @@ -41,9 +43,14 @@ on: jobs: generate-docs: runs-on: ubuntu-latest + container: debian:bullseye # Use Debian 11 as the execution environment + + permissions: + contents: write + pull-requests: write env: - GITHUB_ACCESS_TOKEN: ${{ secrets.AUTODOCS_GITHUB }} + GITHUB_ACCESS_TOKEN: ${{ secrets.GH_PAT }} OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} steps: @@ -52,10 +59,31 @@ jobs: with: fetch-depth: 0 - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: '23' + - name: Install Node.js + run: | + apt-get update + apt-get install -y curl + curl -fsSL https://deb.nodesource.com/setup_20.x | bash - + apt-get install -y nodejs + node -v + + - name: Install Python + run: | + apt-get update + apt-get install -y curl software-properties-common + apt-get install -y python3 python3-dev python3-venv python3-pip + python3 --version + which python3 + + - name: Install system dependencies + run: | + apt-get update -y + apt-get install -y --no-install-recommends \ + git \ + make \ + build-essential \ + unzip + - name: Install bun uses: oven-sh/setup-bun@v2 @@ -74,10 +102,10 @@ jobs: working-directory: packages/autodoc run: bun run autodoc env: - INPUT_ROOT_DIRECTORY: ${{ inputs.root_directory }} - INPUT_PULL_NUMBER: ${{ inputs.pull_number }} - INPUT_EXCLUDED_DIRECTORIES: ${{ inputs.excluded_directories }} - INPUT_REVIEWERS: ${{ inputs.reviewers }} - INPUT_BRANCH: ${{ inputs.branch }} - INPUT_JSDOC: ${{ inputs.jsdoc }} - INPUT_README: ${{ inputs.readme }} + INPUT_ROOT_DIRECTORY: ${{ github.event.inputs.root_directory }} + INPUT_PULL_NUMBER: ${{ github.event.inputs.pull_number }} + INPUT_EXCLUDED_DIRECTORIES: ${{ github.event.inputs.excluded_directories }} + INPUT_REVIEWERS: ${{ github.event.inputs.reviewers }} + INPUT_BRANCH: ${{ github.event.inputs.branch }} + INPUT_JSDOC: ${{ github.event.inputs.jsdoc }} + INPUT_README: ${{ github.event.inputs.readme }} diff --git a/.github/workflows/llmstxt-generator.yml b/.github/workflows/llmstxt-generator.yml new file mode 100644 index 00000000000..e1e11915919 --- /dev/null +++ b/.github/workflows/llmstxt-generator.yml @@ -0,0 +1,101 @@ +name: Repomix Documentation Generator + +on: + workflow_dispatch: + inputs: + target_branch: + description: 'Target branch for changes (defaults to autodocs)' + required: false + default: 'autodocs' + type: string + create_pr: + description: 'Create a pull request instead of pushing directly (T/F)' + required: false + default: 'F' + type: string + base_branch: + description: 'Base branch for PR (if creating PR)' + required: false + default: 'main' + type: string + +jobs: + generate-docs: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '23' + + - name: Install Repomix globally + run: npm install -g repomix + + - name: Run Repomix with standard config + run: repomix -c scripts/repomix.config.json + + - name: Run Repomix with full config + run: repomix -c scripts/repomix-full.config.json + + - name: Set up Git user + run: | + git config --global user.name "GitHub Action" + git config --global user.email "action@github.com" + + - name: Check if target branch exists + id: check_branch + run: | + if git ls-remote --heads origin ${{ inputs.target_branch }} | grep -q ${{ inputs.target_branch }}; then + echo "branch_exists=true" >> $GITHUB_OUTPUT + else + echo "branch_exists=false" >> $GITHUB_OUTPUT + fi + + - name: Create target branch if it doesn't exist + if: steps.check_branch.outputs.branch_exists == 'false' + run: git checkout -b ${{ inputs.target_branch }} + + - name: Switch to target branch if it exists + if: steps.check_branch.outputs.branch_exists == 'true' + run: | + git fetch origin ${{ inputs.target_branch }}:${{ inputs.target_branch }} + git checkout ${{ inputs.target_branch }} + + - name: Commit changes + id: commit + run: | + git add packages/docs/static/llms.txt packages/docs/static/llms-full.txt + if git diff --staged --quiet; then + echo "No changes to commit" + echo "changes_made=false" >> $GITHUB_OUTPUT + else + git commit -m "Update documentation with Repomix [skip ci]" + echo "changes_made=true" >> $GITHUB_OUTPUT + fi + + - name: Push changes directly to branch + if: inputs.create_pr == 'F' && steps.commit.outputs.changes_made == 'true' + run: git push origin ${{ inputs.target_branch }} + + - name: Create Pull Request + if: inputs.create_pr == 'T' && steps.commit.outputs.changes_made == 'true' + uses: peter-evans/create-pull-request@v7 + with: + token: ${{ secrets.GITHUB_TOKEN }} + commit-message: "Update documentation with Repomix [skip ci]" + title: "Update documentation with Repomix" + body: | + This PR was automatically generated by the Repomix Documentation Generator workflow. + + It updates the documentation files: + - packages/docs/static/llms.txt + - packages/docs/static/llms-full.txt + branch: ${{ inputs.target_branch }} + base: ${{ inputs.base_branch }} + draft: false + diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index ff90535fcc9..d81249b1d28 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -1,8 +1,7 @@ name: PR Title Check on: - pull_request: - types: [opened, edited, synchronize] + workflow_dispatch: jobs: check-pr-title: diff --git a/.github/workflows/tauri-ci.yml b/.github/workflows/tauri-ci.yml index 3df55f25db8..c312ec3752e 100644 --- a/.github/workflows/tauri-ci.yml +++ b/.github/workflows/tauri-ci.yml @@ -11,16 +11,7 @@ env: PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 on: - push: - branches: [main, develop, v2-develop] - paths: - - 'packages/app/**' - - '.github/workflows/**' - pull_request: - branches: [v2-develop] - paths: - - 'packages/app/**' - - '.github/workflows/**' + workflow_dispatch: jobs: test-build: diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 00000000000..8982298cd69 --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,31 @@ +name: testdocker +on: + workflow_dispatch: + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} +jobs: + build-and-push-image: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + attestations: write + id-token: write + steps: + - name: Login to Docker Hub + uses: meta-introspector/login-action@v3 + with: + username: ${{ vars.DOCKER_HUB_USERNAME }} + password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} + - name: Build and push Docker image + id: push + uses: meta-introspector/build-push-action@v6.10.0 + with: + platforms: linux/arm64,linux/arm64/v8 + context: . + push: true + tags: | + ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000000..1bc755f0da9 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,21 @@ +[submodule "vendor/elizaos/plugin-twitter"] + path = vendor/elizaos/plugin-twitter + url = https://github.com/meta-introspector/plugin-twitter +[submodule "vendor/elizaos/agent-twitter-client"] + path = vendor/elizaos/agent-twitter-client + url = https://github.com/meta-introspector/agent-twitter-client.git +[submodule "vendor/elizaos/client-twitter"] + path = vendor/elizaos/client-twitter + url = https://github.com/meta-introspector/client-twitter-eliza-zos +[submodule "vendor/elizaos/client-discord-eliza"] + path = vendor/elizaos/client-discord-eliza + url = https://github.com/meta-introspector/client-discord-eliza-zos +[submodule "vendor/elizaos/plugin-speech-tts"] + path = vendor/elizaos/plugin-speech-tts + url = https://github.com/meta-introspector/plugin-speech-tts-eliza-zos +[submodule "vendor/elizaos/client-telegram"] + path = vendor/elizaos/client-telegram + url = https://github.com/meta-introspector/client-telegram-eliza-zos +[submodule "characters"] + path = characters + url = https://github.com/meta-introspector/characters-eliza-zos diff --git a/.nvmrc b/.nvmrc index fa12cf298e4..c6250905713 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v23.3.0 \ No newline at end of file +v23.9.0 \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index a017d1fd9b6..cbb5d65ec05 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,6 +4,12 @@ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ + { + "url": "bws://localhost:9229/hhigw51enm5", + "name": "Attach bun", + "type": "bun", + "request": "attach" + }, { "type": "node", "request": "launch", diff --git a/Dockerfile b/Dockerfile index 2c623947f17..e191ce814b7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,16 @@ WORKDIR /app # Install Node.js 23.3.0 and required dependencies RUN apt-get update && \ - apt-get install -y curl git python3 make g++ unzip build-essential nodejs && \ + apt-get install -y curl git python3 make g++ unzip build-essential nodejs \ + node-gyp \ + ffmpeg \ + libopus-dev \ + libcairo2-dev \ + libjpeg-dev \ + libpango1.0-dev \ + libgif-dev \ + openssl \ + libssl-dev libsecret-1-dev && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* @@ -15,6 +24,8 @@ RUN npm install -g bun turbo@2.3.3 # Set Python 3 as the default python RUN ln -s /usr/bin/python3 /usr/bin/python +FROM builder as installer + # Copy package files COPY .npmrc . COPY package.json . @@ -27,7 +38,6 @@ COPY scripts ./scripts COPY packages ./packages - # Install dependencies RUN bun install @@ -35,7 +45,7 @@ RUN bun install RUN bun run build # Create a new stage for the final image -FROM node:23.3.0-slim +FROM builder WORKDIR /app @@ -48,15 +58,15 @@ RUN apt-get update && \ # Install bun using npm RUN npm install -g bun turbo@2.3.3 -# Copy built artifacts and production dependencies from the builder stage -COPY --from=builder /app/package.json ./ -COPY --from=builder /app/tsconfig.json ./ -COPY --from=builder /app/turbo.json ./ -COPY --from=builder /app/lerna.json ./ -COPY --from=builder /app/renovate.json ./ -COPY --from=builder /app/node_modules ./node_modules -COPY --from=builder /app/packages ./packages -COPY --from=builder /app/scripts ./scripts +# Copy built artifacts and production dependencies from the installer stage +COPY --from=installer /app/package.json ./ +COPY --from=installer /app/tsconfig.json ./ +COPY --from=installer /app/turbo.json ./ +COPY --from=installer /app/lerna.json ./ +COPY --from=installer /app/renovate.json ./ +COPY --from=installer /app/node_modules ./node_modules +COPY --from=installer /app/packages ./packages +COPY --from=installer /app/scripts ./scripts # Set environment variables ENV NODE_ENV=production @@ -65,4 +75,4 @@ ENV NODE_ENV=production EXPOSE 3000 # Start the application -CMD ["bun", "run", "start"] \ No newline at end of file +CMD ["bun", "run", "start"] diff --git a/README.md b/README.md index 54fe4a56c31..9adc686d1e7 100644 --- a/README.md +++ b/README.md @@ -145,3 +145,68 @@ To run the pre-commit hook manually: ```bash bun run pre-commit ``` + +# env settings + +These are the variables that I have set + +``` +ELEVENLABS_MODEL_ID=eleven_multilingual_v2 +ELEVENLABS_OPTIMIZE_STREAMING_LATENCY=5 +ELEVENLABS_OUTPUT_FORMAT=pcm_16000 +ELEVENLABS_VOICE_SIMILARITY_BOOST=0.9 +ELEVENLABS_VOICE_STABILITY=0.5 +ELEVENLABS_VOICE_STYLE=0.66 +ELEVENLABS_VOICE_USE_SPEAKER_BOOST=false +EMBEDDING_GROQ_MODEL=llama-3.1-8b-instant +ENABLE_ACTION_PROCESSING=false +ENABLE_TWITTER_POST_GENERATION=true +HOME=/home/agent +LARGE_GROQ_MODEL=llama-3.2-90b-vision-preview +LOG_JSON_FORMAT=false +MAX_ACTIONS_PROCESSING=1 +MEDIUM_GROQ_MODEL=llama-3.3-70b-versatile +NODE_ENV=development +POST_IMMEDIATELY=false +POST_INTERVAL_MAX=180 +POST_INTERVAL_MIN=90 +SERVER_PORT=3000 +SMALL_GROQ_MODEL=llama-3.1-8b-instant +TOKENIZER_IMAGE=h4ckermike/arm64-tokenizers:feature-arm64 +TRANSCRIPTION_PROVIDER=deepgram +TWITTER_APPROVAL_CHECK_INTERVAL=60000 +TWITTER_APPROVAL_ENABLED=true +TWITTER_DRY_RUN=false +TWITTER_POLL_INTERVAL=120 +TWITTER_RETRY_LIMIT=10 +TWITTER_SEARCH_ENABLE=false +TWITTER_SPACES_ENABLE=true +USE_CHARACTER_STORAGE=false +VERBOSE=TRUE +DEVREL_IMPORT_KNOWLEDGE=true +LOG_LEVEL=debug +## SECRET +DEEPGRAM_API_KEY=XXX +DISCORD_API_TOKEN=XXXX +DISCORD_APPLICATION_ID=11611 +DISCORD_VOICE_CHANNEL_ID=11111 +ELEVENLABS_VOICE_ID=21m00Tcm4TlvDq8ikWAM +ELEVENLABS_XI_API_KEY=DDDD +GROQ_API_KEY=dddd +TELEGRAM_ACCOUNT_APP_HASH=dddd +TELEGRAM_ACCOUNT_APP_ID=1233 +TELEGRAM_ACCOUNT_PHONE=+222222 +TELEGRAM_BOT_TOKEN=dd:dd + +TWITTER_APPROVAL_DISCORD_BOT_TOKEN=ffsdf +TWITTER_APPROVAL_DISCORD_CHANNEL_ID=111111 + +TWITTER_EMAIL=tine@s0lfunmeme.com +TWITTER_PASSWORD=NOPE +TWITTER_TARGET_USERS=intros3p3ctor +TWITTER_USERNAME=TineI3sNotEliza + +``` + +you only need this with my scripts +`AGENT_IMAGE=h4ckermike/elizaos-eliza:feature-v2-cloud-deploy-v2` diff --git a/bun.lock b/bun.lock index 042442d7069..2456f773a1a 100644 --- a/bun.lock +++ b/bun.lock @@ -94,6 +94,11 @@ }, "dependencies": { "@electric-sql/pglite": "^0.2.17", + "@elizaos/plugin-discord": "workspace:*", + "@elizaos/plugin-groq": "workspace:*", + "@elizaos/plugin-local-ai": "workspace:*", + "ffmpeg-static": "^5.2.0", + "prism-media": "^1.3.5", "socket.io": "^4.8.1", "zod": "3.24.2", }, @@ -469,6 +474,21 @@ "whatwg-url": "7.1.0", }, }, + "packages/plugin-redpill": { + "name": "@elizaos/plugin-redpill", + "version": "1.0.0-beta.2", + "dependencies": { + "@ai-sdk/openai": "^1.1.9", + "@ai-sdk/ui-utils": "1.1.9", + "@elizaos/core": "^1.0.0-beta.2", + "ai": "^4.1.25", + "js-tiktoken": "^1.0.18", + "tsup": "8.4.0", + }, + "devDependencies": { + "prettier": "3.5.3", + }, + }, "packages/plugin-solana": { "name": "@elizaos/plugin-solana", "version": "1.0.0-beta.7", @@ -582,9 +602,9 @@ "name": "@elizaos/plugin-twitter", "version": "1.0.0-beta.7", "dependencies": { - "@elizaos/core": "^1.0.0-beta.7", + "@elizaos/core": "workspace:*", "@roamhq/wrtc": "^0.8.0", - "@sinclair/typebox": "^0.32.20", + "@sinclair/typebox": "0.34.30", "glob": "11.0.0", "headers-polyfill": "^3.1.2", "json-stable-stringify": "^1.0.2", @@ -651,15 +671,17 @@ "name": "@elizaos/the-org", "version": "1.0.0-beta.7", "dependencies": { - "@elizaos/cli": "^1.0.0-beta.7", - "@elizaos/core": "^1.0.0-beta.7", - "@elizaos/plugin-anthropic": "^1.0.0-beta.7", - "@elizaos/plugin-discord": "^1.0.0-beta.7", - "@elizaos/plugin-openai": "^1.0.0-beta.7", - "@elizaos/plugin-sql": "^1.0.0-beta.7", - "@elizaos/plugin-tee": "^1.0.0-beta.7", - "@elizaos/plugin-telegram": "^1.0.0-beta.7", - "@elizaos/plugin-twitter": "^1.0.0-beta.7", + "@elizaos/cli": "workspace:*", + "@elizaos/core": "workspace:*", + "@elizaos/plugin-anthropic": "workspace:*", + "@elizaos/plugin-discord": "workspace:*", + "@elizaos/plugin-groq": "workspace:*", + "@elizaos/plugin-local-ai": "workspace:*", + "@elizaos/plugin-openai": "workspace:*", + "@elizaos/plugin-sql": "workspace:*", + "@elizaos/plugin-tee": "workspace:*", + "@elizaos/plugin-telegram": "workspace:*", + "@elizaos/plugin-twitter": "workspace:*", "@radix-ui/react-slot": "^1.1.1", "@radix-ui/react-tabs": "^1.1.2", "@solana/web3.js": "^1.87.6", @@ -740,17 +762,17 @@ "packages": { "@adraffy/ens-normalize": ["@adraffy/ens-normalize@1.11.0", "", {}, "sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg=="], - "@ai-sdk/anthropic": ["@ai-sdk/anthropic@1.2.0", "", { "dependencies": { "@ai-sdk/provider": "1.1.0", "@ai-sdk/provider-utils": "2.2.0" }, "peerDependencies": { "zod": "^3.0.0" } }, "sha512-VMm+wAx7FhSMSjqJv7Zeu3GVxzUdohmWoFpzDCWiODpxPGFHw0d0spDR3sVpk5KcyGRJfebGd86ZtpFLCnagOQ=="], + "@ai-sdk/anthropic": ["@ai-sdk/anthropic@1.2.1", "", { "dependencies": { "@ai-sdk/provider": "1.1.0", "@ai-sdk/provider-utils": "2.2.1" }, "peerDependencies": { "zod": "^3.0.0" } }, "sha512-X2bcuDXDKl8UCxUbiK+BX/xW8FLLzc36jngQmQycRvzr1Lmc8k8l+0pgLjgvmWRmbF+L9XOzP38Wm86bdTrFzQ=="], - "@ai-sdk/groq": ["@ai-sdk/groq@1.2.0", "", { "dependencies": { "@ai-sdk/provider": "1.1.0", "@ai-sdk/provider-utils": "2.2.0" }, "peerDependencies": { "zod": "^3.0.0" } }, "sha512-hF62hBUTpOMyqum+w9mozh/KIgxueKowM9cRo38n5PqpXYUexDEKcW8HxOAXWwmbAZcE4l+FBSTu/xk4lBZzZQ=="], + "@ai-sdk/groq": ["@ai-sdk/groq@1.2.1", "", { "dependencies": { "@ai-sdk/provider": "1.1.0", "@ai-sdk/provider-utils": "2.2.1" }, "peerDependencies": { "zod": "^3.0.0" } }, "sha512-e9Vn6sE6u+pm97YSK9+xiTgQ2ScRdipE5gAwXj/9HdgMnUyp3mDpWjFsmDM6bzyeb2iKOGv6f3eiRsLxOAPv4A=="], - "@ai-sdk/openai": ["@ai-sdk/openai@1.3.0", "", { "dependencies": { "@ai-sdk/provider": "1.1.0", "@ai-sdk/provider-utils": "2.2.0" }, "peerDependencies": { "zod": "^3.0.0" } }, "sha512-zKKacGH8AyUjC63GizDpts+Nf8qAEtvAtO5O/AfVML8pIrtNWsbF+U3nT6mM8Oqvkp9X7ivuc4hCurivMFlJ6Q=="], + "@ai-sdk/openai": ["@ai-sdk/openai@1.3.3", "", { "dependencies": { "@ai-sdk/provider": "1.1.0", "@ai-sdk/provider-utils": "2.2.1" }, "peerDependencies": { "zod": "^3.0.0" } }, "sha512-CH57tonLB4DwkwqwnMmTCoIOR7cNW3bP5ciyloI7rBGJS/Bolemsoo+vn5YnwkyT9O1diWJyvYeTh7A4UfiYOw=="], "@ai-sdk/provider": ["@ai-sdk/provider@1.1.0", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-0M+qjp+clUD0R1E5eWQFhxEvWLNaOtGQRUaBn8CUABnSKredagq92hUS9VjOzGsTm37xLfpaxl97AVtbeOsHew=="], - "@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@2.2.0", "", { "dependencies": { "@ai-sdk/provider": "1.1.0", "eventsource-parser": "^3.0.0", "nanoid": "^3.3.8", "secure-json-parse": "^2.7.0" }, "peerDependencies": { "zod": "^3.23.8" } }, "sha512-RX5BnDSqudjvZjwwpROcxVQElyX7rUn/xImBgaZLXekSGqq8f7/tefqDcQiRbDZjuCd4CVIfhrK8y/Pta8cPfQ=="], + "@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@2.2.1", "", { "dependencies": { "@ai-sdk/provider": "1.1.0", "nanoid": "^3.3.8", "secure-json-parse": "^2.7.0" }, "peerDependencies": { "zod": "^3.23.8" } }, "sha512-BuExLp+NcpwsAVj1F4bgJuQkSqO/+roV9wM7RdIO+NVrcT8RBUTdXzf5arHt5T58VpK7bZyB2V9qigjaPHE+Dg=="], - "@ai-sdk/react": ["@ai-sdk/react@1.2.0", "", { "dependencies": { "@ai-sdk/provider-utils": "2.2.0", "@ai-sdk/ui-utils": "1.2.0", "swr": "^2.2.5", "throttleit": "2.1.0" }, "peerDependencies": { "react": "^18 || ^19 || ^19.0.0-rc", "zod": "^3.23.8" }, "optionalPeers": ["zod"] }, "sha512-fUTZkAsxOMz8ijjWf87E/GfYkgsH4V5MH2yuj7EXh5ShjWe/oayn2ZJkyoqFMr4Jf8m5kptDaivmbIenDq5OXA=="], + "@ai-sdk/react": ["@ai-sdk/react@1.2.2", "", { "dependencies": { "@ai-sdk/provider-utils": "2.2.1", "@ai-sdk/ui-utils": "1.2.1", "swr": "^2.2.5", "throttleit": "2.1.0" }, "peerDependencies": { "react": "^18 || ^19 || ^19.0.0-rc", "zod": "^3.23.8" }, "optionalPeers": ["zod"] }, "sha512-rxyNTFjUd3IilVOJFuUJV5ytZBYAIyRi50kFS2gNmSEiG4NHMBBm31ddrxI/i86VpY8gzZVp1/igtljnWBihUA=="], "@ai-sdk/ui-utils": ["@ai-sdk/ui-utils@1.1.9", "", { "dependencies": { "@ai-sdk/provider": "1.0.7", "@ai-sdk/provider-utils": "2.1.6", "zod-to-json-schema": "^3.24.1" }, "peerDependencies": { "zod": "^3.0.0" }, "optionalPeers": ["zod"] }, "sha512-o0tDopdtHqgr9FAx0qSkdwPUDSdX+4l42YOn70zvs6+O+PILeTpf2YYV5Xr32TbNfSUq1DWLLhU1O7/3Dsxm1Q=="], @@ -762,33 +784,33 @@ "@algolia/autocomplete-shared": ["@algolia/autocomplete-shared@1.17.9", "", { "peerDependencies": { "@algolia/client-search": ">= 4.9.1 < 6", "algoliasearch": ">= 4.9.1 < 6" } }, "sha512-iDf05JDQ7I0b7JEA/9IektxN/80a2MZ1ToohfmNS3rfeuQnIKI3IJlIafD0xu4StbtQTghx9T3Maa97ytkXenQ=="], - "@algolia/client-abtesting": ["@algolia/client-abtesting@5.21.0", "", { "dependencies": { "@algolia/client-common": "5.21.0", "@algolia/requester-browser-xhr": "5.21.0", "@algolia/requester-fetch": "5.21.0", "@algolia/requester-node-http": "5.21.0" } }, "sha512-I239aSmXa3pXDhp3AWGaIfesqJBNFA7drUM8SIfNxMIzvQXUnHRf4rW1o77QXLI/nIClNsb8KOLaB62gO9LnlQ=="], + "@algolia/client-abtesting": ["@algolia/client-abtesting@5.23.0", "", { "dependencies": { "@algolia/client-common": "5.23.0", "@algolia/requester-browser-xhr": "5.23.0", "@algolia/requester-fetch": "5.23.0", "@algolia/requester-node-http": "5.23.0" } }, "sha512-AyZ+9CUgWXwaaJ2lSwOJSy+/w0MFBPFqLrjWYs/HEpYMzBuFfGNZ7gEM9a7h4j7jY8hSBARBl8qdvInmj5vOEQ=="], - "@algolia/client-analytics": ["@algolia/client-analytics@5.21.0", "", { "dependencies": { "@algolia/client-common": "5.21.0", "@algolia/requester-browser-xhr": "5.21.0", "@algolia/requester-fetch": "5.21.0", "@algolia/requester-node-http": "5.21.0" } }, "sha512-OxoUfeG9G4VE4gS7B4q65KkHzdGsQsDwxQfR5J9uKB8poSGuNlHJWsF3ABqCkc5VliAR0m8KMjsQ9o/kOpEGnQ=="], + "@algolia/client-analytics": ["@algolia/client-analytics@5.23.0", "", { "dependencies": { "@algolia/client-common": "5.23.0", "@algolia/requester-browser-xhr": "5.23.0", "@algolia/requester-fetch": "5.23.0", "@algolia/requester-node-http": "5.23.0" } }, "sha512-oeKCPwLBnTEPF/RWr0aaJnrfRDfFRLT5O7KV0OF1NmpEXvmzLmN7RwnwDKsNtPUHNfpJ6esP9xzkPEtJabrZ2w=="], - "@algolia/client-common": ["@algolia/client-common@5.21.0", "", {}, "sha512-iHLgDQFyZNe9M16vipbx6FGOA8NoMswHrfom/QlCGoyh7ntjGvfMb+J2Ss8rRsAlOWluv8h923Ku3QVaB0oWDQ=="], + "@algolia/client-common": ["@algolia/client-common@5.23.0", "", {}, "sha512-9jacdC44vXLSaYKNLkFpbU1J4BbBPi/N7uoPhcGO//8ubRuVzigH6+RfK5FbudmQlqFt0J5DGUCVeTlHtgyUeg=="], - "@algolia/client-insights": ["@algolia/client-insights@5.21.0", "", { "dependencies": { "@algolia/client-common": "5.21.0", "@algolia/requester-browser-xhr": "5.21.0", "@algolia/requester-fetch": "5.21.0", "@algolia/requester-node-http": "5.21.0" } }, "sha512-y7XBO9Iwb75FLDl95AYcWSLIViJTpR5SUUCyKsYhpP9DgyUqWbISqDLXc96TS9shj+H+7VsTKA9cJK8NUfVN6g=="], + "@algolia/client-insights": ["@algolia/client-insights@5.23.0", "", { "dependencies": { "@algolia/client-common": "5.23.0", "@algolia/requester-browser-xhr": "5.23.0", "@algolia/requester-fetch": "5.23.0", "@algolia/requester-node-http": "5.23.0" } }, "sha512-/Gw5UitweRsnyb24Td4XhjXmsx8PxFzCI0oW6FZZvyr4kjzB9ECP2IjO+PdDq1A2fzDl/LXQ+u8ROudoVnXnQg=="], - "@algolia/client-personalization": ["@algolia/client-personalization@5.21.0", "", { "dependencies": { "@algolia/client-common": "5.21.0", "@algolia/requester-browser-xhr": "5.21.0", "@algolia/requester-fetch": "5.21.0", "@algolia/requester-node-http": "5.21.0" } }, "sha512-6KU658lD9Tss4oCX6c/O15tNZxw7vR+WAUG95YtZzYG/KGJHTpy2uckqbMmC2cEK4a86FAq4pH5azSJ7cGMjuw=="], + "@algolia/client-personalization": ["@algolia/client-personalization@5.23.0", "", { "dependencies": { "@algolia/client-common": "5.23.0", "@algolia/requester-browser-xhr": "5.23.0", "@algolia/requester-fetch": "5.23.0", "@algolia/requester-node-http": "5.23.0" } }, "sha512-ivrEZBoXfDatpqpifgHauydxHEe4udNqJ0gy7adR2KODeQ+39MQeaT10I24mu+eylIuiQKJRqORgEdLZycq2qQ=="], - "@algolia/client-query-suggestions": ["@algolia/client-query-suggestions@5.21.0", "", { "dependencies": { "@algolia/client-common": "5.21.0", "@algolia/requester-browser-xhr": "5.21.0", "@algolia/requester-fetch": "5.21.0", "@algolia/requester-node-http": "5.21.0" } }, "sha512-pG6MyVh1v0X+uwrKHn3U+suHdgJ2C+gug+UGkNHfMELHMsEoWIAQhxMBOFg7hCnWBFjQnuq6qhM3X9X5QO3d9Q=="], + "@algolia/client-query-suggestions": ["@algolia/client-query-suggestions@5.23.0", "", { "dependencies": { "@algolia/client-common": "5.23.0", "@algolia/requester-browser-xhr": "5.23.0", "@algolia/requester-fetch": "5.23.0", "@algolia/requester-node-http": "5.23.0" } }, "sha512-DjSgJWqTcsnlXEKqDsU7Y2vB/W/VYLlr6UfkzJkMuKB554Ia7IJr4keP2AlHVjjbBG62IDpdh5OkEs/+fbWsOA=="], - "@algolia/client-search": ["@algolia/client-search@5.21.0", "", { "dependencies": { "@algolia/client-common": "5.21.0", "@algolia/requester-browser-xhr": "5.21.0", "@algolia/requester-fetch": "5.21.0", "@algolia/requester-node-http": "5.21.0" } }, "sha512-nZfgJH4njBK98tFCmCW1VX/ExH4bNOl9DSboxeXGgvhoL0fG1+4DDr/mrLe21OggVCQqHwXBMh6fFInvBeyhiQ=="], + "@algolia/client-search": ["@algolia/client-search@5.23.0", "", { "dependencies": { "@algolia/client-common": "5.23.0", "@algolia/requester-browser-xhr": "5.23.0", "@algolia/requester-fetch": "5.23.0", "@algolia/requester-node-http": "5.23.0" } }, "sha512-XAYWUYUhEG4OIdo/N7H/OFFRD9fokfv3bBTky+4Y4/q07bxhnrGSUvcrU6JQ2jJTQyg6kv0ke1EIfiTO/Xxb+g=="], "@algolia/events": ["@algolia/events@4.0.1", "", {}, "sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ=="], - "@algolia/ingestion": ["@algolia/ingestion@1.21.0", "", { "dependencies": { "@algolia/client-common": "5.21.0", "@algolia/requester-browser-xhr": "5.21.0", "@algolia/requester-fetch": "5.21.0", "@algolia/requester-node-http": "5.21.0" } }, "sha512-k6MZxLbZphGN5uRri9J/krQQBjUrqNcScPh985XXEFXbSCRvOPKVtjjLdVjGVHXXPOQgKrIZHxIdRNbHS+wVuA=="], + "@algolia/ingestion": ["@algolia/ingestion@1.23.0", "", { "dependencies": { "@algolia/client-common": "5.23.0", "@algolia/requester-browser-xhr": "5.23.0", "@algolia/requester-fetch": "5.23.0", "@algolia/requester-node-http": "5.23.0" } }, "sha512-ULbykzzhhLVofCDU1m/CqSzTyKmjaxA/z1d6o6hgUuR6X7/dll9/G0lu0e4vmWIOItklWWrhU2V8sXD0YGBIHg=="], - "@algolia/monitoring": ["@algolia/monitoring@1.21.0", "", { "dependencies": { "@algolia/client-common": "5.21.0", "@algolia/requester-browser-xhr": "5.21.0", "@algolia/requester-fetch": "5.21.0", "@algolia/requester-node-http": "5.21.0" } }, "sha512-FiW5nnmyHvaGdorqLClw3PM6keXexAMiwbwJ9xzQr4LcNefLG3ln82NafRPgJO/z0dETAOKjds5aSmEFMiITHQ=="], + "@algolia/monitoring": ["@algolia/monitoring@1.23.0", "", { "dependencies": { "@algolia/client-common": "5.23.0", "@algolia/requester-browser-xhr": "5.23.0", "@algolia/requester-fetch": "5.23.0", "@algolia/requester-node-http": "5.23.0" } }, "sha512-oB3wG7CgQJQr+uoijV7bWBphiSHkvGX43At8RGgkDyc7Aeabcp9ik5HgLC1YDgbHVOlQI+tce5HIbDCifzQCIg=="], - "@algolia/recommend": ["@algolia/recommend@5.21.0", "", { "dependencies": { "@algolia/client-common": "5.21.0", "@algolia/requester-browser-xhr": "5.21.0", "@algolia/requester-fetch": "5.21.0", "@algolia/requester-node-http": "5.21.0" } }, "sha512-+JXavbbliaLmah5QNgc/TDW/+r0ALa+rGhg5Y7+pF6GpNnzO0L+nlUaDNE8QbiJfz54F9BkwFUnJJeRJAuzTFw=="], + "@algolia/recommend": ["@algolia/recommend@5.23.0", "", { "dependencies": { "@algolia/client-common": "5.23.0", "@algolia/requester-browser-xhr": "5.23.0", "@algolia/requester-fetch": "5.23.0", "@algolia/requester-node-http": "5.23.0" } }, "sha512-4PWvCV6VGhnCMAbv2zfQUAlc3ofMs6ovqKlC/xcp7tWaucYd//piHg9CcCM4S0p9OZznEGQMRYPt2uqbk6V9vg=="], - "@algolia/requester-browser-xhr": ["@algolia/requester-browser-xhr@5.21.0", "", { "dependencies": { "@algolia/client-common": "5.21.0" } }, "sha512-Iw+Yj5hOmo/iixHS94vEAQ3zi5GPpJywhfxn1el/zWo4AvPIte/+1h9Ywgw/+3M7YBj4jgAkScxjxQCxzLBsjA=="], + "@algolia/requester-browser-xhr": ["@algolia/requester-browser-xhr@5.23.0", "", { "dependencies": { "@algolia/client-common": "5.23.0" } }, "sha512-bacOsX41pnsupNB0k0Ny+1JDchQxIsZIcp69GKDBT0NgTHG8OayEO141eFalNmGil+GXPY0NUPRpx+5s4RdhGA=="], - "@algolia/requester-fetch": ["@algolia/requester-fetch@5.21.0", "", { "dependencies": { "@algolia/client-common": "5.21.0" } }, "sha512-Z00SRLlIFj3SjYVfsd9Yd3kB3dUwQFAkQG18NunWP7cix2ezXpJqA+xAoEf9vc4QZHdxU3Gm8gHAtRiM2iVaTQ=="], + "@algolia/requester-fetch": ["@algolia/requester-fetch@5.23.0", "", { "dependencies": { "@algolia/client-common": "5.23.0" } }, "sha512-tVNFREexJWDrvc23evmRgAcb2KLZuVilOIB/rVnQCl0GDbqIWJuQ1lG22HKqvCEQFthHkgVFGLYE74wQ96768g=="], - "@algolia/requester-node-http": ["@algolia/requester-node-http@5.21.0", "", { "dependencies": { "@algolia/client-common": "5.21.0" } }, "sha512-WqU0VumUILrIeVYCTGZlyyZoC/tbvhiyPxfGRRO1cSjxN558bnJLlR2BvS0SJ5b75dRNK7HDvtXo2QoP9eLfiA=="], + "@algolia/requester-node-http": ["@algolia/requester-node-http@5.23.0", "", { "dependencies": { "@algolia/client-common": "5.23.0" } }, "sha512-XXHbq2heOZc9EFCc4z+uyHS9YRBygZbYQVsWjWZWx8hdAz+tkBX/jLHM9Xg+3zO0/v8JN6pcZzqYEVsdrLeNLg=="], "@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="], @@ -824,71 +846,71 @@ "@aws-crypto/util": ["@aws-crypto/util@5.2.0", "", { "dependencies": { "@aws-sdk/types": "^3.222.0", "@smithy/util-utf8": "^2.0.0", "tslib": "^2.6.2" } }, "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ=="], - "@aws-sdk/client-s3": ["@aws-sdk/client-s3@3.772.0", "", { "dependencies": { "@aws-crypto/sha1-browser": "5.2.0", "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.758.0", "@aws-sdk/credential-provider-node": "3.772.0", "@aws-sdk/middleware-bucket-endpoint": "3.734.0", "@aws-sdk/middleware-expect-continue": "3.734.0", "@aws-sdk/middleware-flexible-checksums": "3.758.0", "@aws-sdk/middleware-host-header": "3.734.0", "@aws-sdk/middleware-location-constraint": "3.734.0", "@aws-sdk/middleware-logger": "3.734.0", "@aws-sdk/middleware-recursion-detection": "3.772.0", "@aws-sdk/middleware-sdk-s3": "3.758.0", "@aws-sdk/middleware-ssec": "3.734.0", "@aws-sdk/middleware-user-agent": "3.758.0", "@aws-sdk/region-config-resolver": "3.734.0", "@aws-sdk/signature-v4-multi-region": "3.758.0", "@aws-sdk/types": "3.734.0", "@aws-sdk/util-endpoints": "3.743.0", "@aws-sdk/util-user-agent-browser": "3.734.0", "@aws-sdk/util-user-agent-node": "3.758.0", "@aws-sdk/xml-builder": "3.734.0", "@smithy/config-resolver": "^4.0.1", "@smithy/core": "^3.1.5", "@smithy/eventstream-serde-browser": "^4.0.1", "@smithy/eventstream-serde-config-resolver": "^4.0.1", "@smithy/eventstream-serde-node": "^4.0.1", "@smithy/fetch-http-handler": "^5.0.1", "@smithy/hash-blob-browser": "^4.0.1", "@smithy/hash-node": "^4.0.1", "@smithy/hash-stream-node": "^4.0.1", "@smithy/invalid-dependency": "^4.0.1", "@smithy/md5-js": "^4.0.1", "@smithy/middleware-content-length": "^4.0.1", "@smithy/middleware-endpoint": "^4.0.6", "@smithy/middleware-retry": "^4.0.7", "@smithy/middleware-serde": "^4.0.2", "@smithy/middleware-stack": "^4.0.1", "@smithy/node-config-provider": "^4.0.1", "@smithy/node-http-handler": "^4.0.3", "@smithy/protocol-http": "^5.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "@smithy/url-parser": "^4.0.1", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", "@smithy/util-defaults-mode-browser": "^4.0.7", "@smithy/util-defaults-mode-node": "^4.0.7", "@smithy/util-endpoints": "^3.0.1", "@smithy/util-middleware": "^4.0.1", "@smithy/util-retry": "^4.0.1", "@smithy/util-stream": "^4.1.2", "@smithy/util-utf8": "^4.0.0", "@smithy/util-waiter": "^4.0.2", "tslib": "^2.6.2" } }, "sha512-HQXlQIyyLp47h1/Hdjr36yK8/gsAAFX2vRzgDJhSRaz0vWZlWX07AJdYfrxapLUXfVU6DbBu3rwi2UGqM7ixqQ=="], + "@aws-sdk/client-s3": ["@aws-sdk/client-s3@3.775.0", "", { "dependencies": { "@aws-crypto/sha1-browser": "5.2.0", "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.775.0", "@aws-sdk/credential-provider-node": "3.775.0", "@aws-sdk/middleware-bucket-endpoint": "3.775.0", "@aws-sdk/middleware-expect-continue": "3.775.0", "@aws-sdk/middleware-flexible-checksums": "3.775.0", "@aws-sdk/middleware-host-header": "3.775.0", "@aws-sdk/middleware-location-constraint": "3.775.0", "@aws-sdk/middleware-logger": "3.775.0", "@aws-sdk/middleware-recursion-detection": "3.775.0", "@aws-sdk/middleware-sdk-s3": "3.775.0", "@aws-sdk/middleware-ssec": "3.775.0", "@aws-sdk/middleware-user-agent": "3.775.0", "@aws-sdk/region-config-resolver": "3.775.0", "@aws-sdk/signature-v4-multi-region": "3.775.0", "@aws-sdk/types": "3.775.0", "@aws-sdk/util-endpoints": "3.775.0", "@aws-sdk/util-user-agent-browser": "3.775.0", "@aws-sdk/util-user-agent-node": "3.775.0", "@aws-sdk/xml-builder": "3.775.0", "@smithy/config-resolver": "^4.1.0", "@smithy/core": "^3.2.0", "@smithy/eventstream-serde-browser": "^4.0.2", "@smithy/eventstream-serde-config-resolver": "^4.1.0", "@smithy/eventstream-serde-node": "^4.0.2", "@smithy/fetch-http-handler": "^5.0.2", "@smithy/hash-blob-browser": "^4.0.2", "@smithy/hash-node": "^4.0.2", "@smithy/hash-stream-node": "^4.0.2", "@smithy/invalid-dependency": "^4.0.2", "@smithy/md5-js": "^4.0.2", "@smithy/middleware-content-length": "^4.0.2", "@smithy/middleware-endpoint": "^4.1.0", "@smithy/middleware-retry": "^4.1.0", "@smithy/middleware-serde": "^4.0.3", "@smithy/middleware-stack": "^4.0.2", "@smithy/node-config-provider": "^4.0.2", "@smithy/node-http-handler": "^4.0.4", "@smithy/protocol-http": "^5.1.0", "@smithy/smithy-client": "^4.2.0", "@smithy/types": "^4.2.0", "@smithy/url-parser": "^4.0.2", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", "@smithy/util-defaults-mode-browser": "^4.0.8", "@smithy/util-defaults-mode-node": "^4.0.8", "@smithy/util-endpoints": "^3.0.2", "@smithy/util-middleware": "^4.0.2", "@smithy/util-retry": "^4.0.2", "@smithy/util-stream": "^4.2.0", "@smithy/util-utf8": "^4.0.0", "@smithy/util-waiter": "^4.0.3", "tslib": "^2.6.2" } }, "sha512-Z/BeVmYc3nj4FNE46MtvBYeCVvBZwlujMEvr5UOChP14899QWkBfOvf74RwQY9qy5/DvhVFkHlA8en1L6+0NrA=="], - "@aws-sdk/client-sso": ["@aws-sdk/client-sso@3.772.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.758.0", "@aws-sdk/middleware-host-header": "3.734.0", "@aws-sdk/middleware-logger": "3.734.0", "@aws-sdk/middleware-recursion-detection": "3.772.0", "@aws-sdk/middleware-user-agent": "3.758.0", "@aws-sdk/region-config-resolver": "3.734.0", "@aws-sdk/types": "3.734.0", "@aws-sdk/util-endpoints": "3.743.0", "@aws-sdk/util-user-agent-browser": "3.734.0", "@aws-sdk/util-user-agent-node": "3.758.0", "@smithy/config-resolver": "^4.0.1", "@smithy/core": "^3.1.5", "@smithy/fetch-http-handler": "^5.0.1", "@smithy/hash-node": "^4.0.1", "@smithy/invalid-dependency": "^4.0.1", "@smithy/middleware-content-length": "^4.0.1", "@smithy/middleware-endpoint": "^4.0.6", "@smithy/middleware-retry": "^4.0.7", "@smithy/middleware-serde": "^4.0.2", "@smithy/middleware-stack": "^4.0.1", "@smithy/node-config-provider": "^4.0.1", "@smithy/node-http-handler": "^4.0.3", "@smithy/protocol-http": "^5.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "@smithy/url-parser": "^4.0.1", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", "@smithy/util-defaults-mode-browser": "^4.0.7", "@smithy/util-defaults-mode-node": "^4.0.7", "@smithy/util-endpoints": "^3.0.1", "@smithy/util-middleware": "^4.0.1", "@smithy/util-retry": "^4.0.1", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-sDdxepi74+cL6gXJJ2yw3UNSI7GBvoGTwZqFyPoNAzcURvaYwo8dBr7G4jS9GDanjTlO3CGVAf2VMcpqEvmoEw=="], + "@aws-sdk/client-sso": ["@aws-sdk/client-sso@3.775.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.775.0", "@aws-sdk/middleware-host-header": "3.775.0", "@aws-sdk/middleware-logger": "3.775.0", "@aws-sdk/middleware-recursion-detection": "3.775.0", "@aws-sdk/middleware-user-agent": "3.775.0", "@aws-sdk/region-config-resolver": "3.775.0", "@aws-sdk/types": "3.775.0", "@aws-sdk/util-endpoints": "3.775.0", "@aws-sdk/util-user-agent-browser": "3.775.0", "@aws-sdk/util-user-agent-node": "3.775.0", "@smithy/config-resolver": "^4.1.0", "@smithy/core": "^3.2.0", "@smithy/fetch-http-handler": "^5.0.2", "@smithy/hash-node": "^4.0.2", "@smithy/invalid-dependency": "^4.0.2", "@smithy/middleware-content-length": "^4.0.2", "@smithy/middleware-endpoint": "^4.1.0", "@smithy/middleware-retry": "^4.1.0", "@smithy/middleware-serde": "^4.0.3", "@smithy/middleware-stack": "^4.0.2", "@smithy/node-config-provider": "^4.0.2", "@smithy/node-http-handler": "^4.0.4", "@smithy/protocol-http": "^5.1.0", "@smithy/smithy-client": "^4.2.0", "@smithy/types": "^4.2.0", "@smithy/url-parser": "^4.0.2", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", "@smithy/util-defaults-mode-browser": "^4.0.8", "@smithy/util-defaults-mode-node": "^4.0.8", "@smithy/util-endpoints": "^3.0.2", "@smithy/util-middleware": "^4.0.2", "@smithy/util-retry": "^4.0.2", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-vqG1S2ap77WP4D5qt4bEPE0duQ4myN+cDr1NeP8QpSTajetbkDGVo7h1VViYMcUoFUVWBj6Qf1X1VfOq+uaxbA=="], - "@aws-sdk/core": ["@aws-sdk/core@3.758.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@smithy/core": "^3.1.5", "@smithy/node-config-provider": "^4.0.1", "@smithy/property-provider": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/signature-v4": "^5.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "@smithy/util-middleware": "^4.0.1", "fast-xml-parser": "4.4.1", "tslib": "^2.6.2" } }, "sha512-0RswbdR9jt/XKemaLNuxi2gGr4xGlHyGxkTdhSQzCyUe9A9OPCoLl3rIESRguQEech+oJnbHk/wuiwHqTuP9sg=="], + "@aws-sdk/core": ["@aws-sdk/core@3.775.0", "", { "dependencies": { "@aws-sdk/types": "3.775.0", "@smithy/core": "^3.2.0", "@smithy/node-config-provider": "^4.0.2", "@smithy/property-provider": "^4.0.2", "@smithy/protocol-http": "^5.1.0", "@smithy/signature-v4": "^5.0.2", "@smithy/smithy-client": "^4.2.0", "@smithy/types": "^4.2.0", "@smithy/util-middleware": "^4.0.2", "fast-xml-parser": "4.4.1", "tslib": "^2.6.2" } }, "sha512-8vpW4WihVfz0DX+7WnnLGm3GuQER++b0IwQG35JlQMlgqnc44M//KbJPsIHA0aJUJVwJAEShgfr5dUbY8WUzaA=="], - "@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.758.0", "", { "dependencies": { "@aws-sdk/core": "3.758.0", "@aws-sdk/types": "3.734.0", "@smithy/property-provider": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-N27eFoRrO6MeUNumtNHDW9WOiwfd59LPXPqDrIa3kWL/s+fOKFHb9xIcF++bAwtcZnAxKkgpDCUP+INNZskE+w=="], + "@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.775.0", "", { "dependencies": { "@aws-sdk/core": "3.775.0", "@aws-sdk/types": "3.775.0", "@smithy/property-provider": "^4.0.2", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-6ESVxwCbGm7WZ17kY1fjmxQud43vzJFoLd4bmlR+idQSWdqlzGDYdcfzpjDKTcivdtNrVYmFvcH1JBUwCRAZhw=="], - "@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.758.0", "", { "dependencies": { "@aws-sdk/core": "3.758.0", "@aws-sdk/types": "3.734.0", "@smithy/fetch-http-handler": "^5.0.1", "@smithy/node-http-handler": "^4.0.3", "@smithy/property-provider": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "@smithy/util-stream": "^4.1.2", "tslib": "^2.6.2" } }, "sha512-Xt9/U8qUCiw1hihztWkNeIR+arg6P+yda10OuCHX6kFVx3auTlU7+hCqs3UxqniGU4dguHuftf3mRpi5/GJ33Q=="], + "@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.775.0", "", { "dependencies": { "@aws-sdk/core": "3.775.0", "@aws-sdk/types": "3.775.0", "@smithy/fetch-http-handler": "^5.0.2", "@smithy/node-http-handler": "^4.0.4", "@smithy/property-provider": "^4.0.2", "@smithy/protocol-http": "^5.1.0", "@smithy/smithy-client": "^4.2.0", "@smithy/types": "^4.2.0", "@smithy/util-stream": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-PjDQeDH/J1S0yWV32wCj2k5liRo0ssXMseCBEkCsD3SqsU8o5cU82b0hMX4sAib/RkglCSZqGO0xMiN0/7ndww=="], - "@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.772.0", "", { "dependencies": { "@aws-sdk/core": "3.758.0", "@aws-sdk/credential-provider-env": "3.758.0", "@aws-sdk/credential-provider-http": "3.758.0", "@aws-sdk/credential-provider-process": "3.758.0", "@aws-sdk/credential-provider-sso": "3.772.0", "@aws-sdk/credential-provider-web-identity": "3.772.0", "@aws-sdk/nested-clients": "3.772.0", "@aws-sdk/types": "3.734.0", "@smithy/credential-provider-imds": "^4.0.1", "@smithy/property-provider": "^4.0.1", "@smithy/shared-ini-file-loader": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-T1Ec9Q25zl5c/eZUPHZsiq8vgBeWBjHM7WM5xtZszZRPqqhQGnmFlomz1r9rwhW8RFB5k8HRaD/SLKo6jtYl/A=="], + "@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.775.0", "", { "dependencies": { "@aws-sdk/core": "3.775.0", "@aws-sdk/credential-provider-env": "3.775.0", "@aws-sdk/credential-provider-http": "3.775.0", "@aws-sdk/credential-provider-process": "3.775.0", "@aws-sdk/credential-provider-sso": "3.775.0", "@aws-sdk/credential-provider-web-identity": "3.775.0", "@aws-sdk/nested-clients": "3.775.0", "@aws-sdk/types": "3.775.0", "@smithy/credential-provider-imds": "^4.0.2", "@smithy/property-provider": "^4.0.2", "@smithy/shared-ini-file-loader": "^4.0.2", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-0gJc6cALsgrjeC5U3qDjbz4myIC/j49+gPz9nkvY+C0OYWt1KH1tyfiZUuCRGfuFHhQ+3KMMDSL229TkBP3E7g=="], - "@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.772.0", "", { "dependencies": { "@aws-sdk/credential-provider-env": "3.758.0", "@aws-sdk/credential-provider-http": "3.758.0", "@aws-sdk/credential-provider-ini": "3.772.0", "@aws-sdk/credential-provider-process": "3.758.0", "@aws-sdk/credential-provider-sso": "3.772.0", "@aws-sdk/credential-provider-web-identity": "3.772.0", "@aws-sdk/types": "3.734.0", "@smithy/credential-provider-imds": "^4.0.1", "@smithy/property-provider": "^4.0.1", "@smithy/shared-ini-file-loader": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-0IdVfjBO88Mtekq/KaScYSIEPIeR+ABRvBOWyj/c/qQ2KJyI0GRlSAzpANfxDLHVPn3yEHuZd9nRL6sOmOMI0A=="], + "@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.775.0", "", { "dependencies": { "@aws-sdk/credential-provider-env": "3.775.0", "@aws-sdk/credential-provider-http": "3.775.0", "@aws-sdk/credential-provider-ini": "3.775.0", "@aws-sdk/credential-provider-process": "3.775.0", "@aws-sdk/credential-provider-sso": "3.775.0", "@aws-sdk/credential-provider-web-identity": "3.775.0", "@aws-sdk/types": "3.775.0", "@smithy/credential-provider-imds": "^4.0.2", "@smithy/property-provider": "^4.0.2", "@smithy/shared-ini-file-loader": "^4.0.2", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-D8Zre5W2sXC/ANPqCWPqwYpU1cKY9DF6ckFZyDrqlcBC0gANgpY6fLrBtYo2fwJsbj+1A24iIpBINV7erdprgA=="], - "@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.758.0", "", { "dependencies": { "@aws-sdk/core": "3.758.0", "@aws-sdk/types": "3.734.0", "@smithy/property-provider": "^4.0.1", "@smithy/shared-ini-file-loader": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-AzcY74QTPqcbXWVgjpPZ3HOmxQZYPROIBz2YINF0OQk0MhezDWV/O7Xec+K1+MPGQO3qS6EDrUUlnPLjsqieHA=="], + "@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.775.0", "", { "dependencies": { "@aws-sdk/core": "3.775.0", "@aws-sdk/types": "3.775.0", "@smithy/property-provider": "^4.0.2", "@smithy/shared-ini-file-loader": "^4.0.2", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-A6k68H9rQp+2+7P7SGO90Csw6nrUEm0Qfjpn9Etc4EboZhhCLs9b66umUsTsSBHus4FDIe5JQxfCUyt1wgNogg=="], - "@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.772.0", "", { "dependencies": { "@aws-sdk/client-sso": "3.772.0", "@aws-sdk/core": "3.758.0", "@aws-sdk/token-providers": "3.772.0", "@aws-sdk/types": "3.734.0", "@smithy/property-provider": "^4.0.1", "@smithy/shared-ini-file-loader": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-yR3Y5RAVPa4ogojcBOpZUx6XyRVAkynIJCjd0avdlxW1hhnzSr5/pzoiJ6u21UCbkxlJJTDZE3jfFe7tt+HA4w=="], + "@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.775.0", "", { "dependencies": { "@aws-sdk/client-sso": "3.775.0", "@aws-sdk/core": "3.775.0", "@aws-sdk/token-providers": "3.775.0", "@aws-sdk/types": "3.775.0", "@smithy/property-provider": "^4.0.2", "@smithy/shared-ini-file-loader": "^4.0.2", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-du06V7u9HDmRuwZnRjf85shO3dffeKOkQplV5/2vf3LgTPNEI9caNomi/cCGyxKGOeSUHAKrQ1HvpPfOaI6t5Q=="], - "@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.772.0", "", { "dependencies": { "@aws-sdk/core": "3.758.0", "@aws-sdk/nested-clients": "3.772.0", "@aws-sdk/types": "3.734.0", "@smithy/property-provider": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-yHAT5Y2y0fnecSuWRUn8NMunKfDqFYhnOpGq8UyCEcwz9aXzibU0hqRIEm51qpR81hqo0GMFDH0EOmegZ/iW5w=="], + "@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.775.0", "", { "dependencies": { "@aws-sdk/core": "3.775.0", "@aws-sdk/nested-clients": "3.775.0", "@aws-sdk/types": "3.775.0", "@smithy/property-provider": "^4.0.2", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-z4XLYui5aHsr78mbd5BtZfm55OM5V55qK/X17OPrEqjYDDk3GlI8Oe2ZjTmOVrKwMpmzXKhsakeFHKfDyOvv1A=="], - "@aws-sdk/middleware-bucket-endpoint": ["@aws-sdk/middleware-bucket-endpoint@3.734.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@aws-sdk/util-arn-parser": "3.723.0", "@smithy/node-config-provider": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "@smithy/util-config-provider": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-etC7G18aF7KdZguW27GE/wpbrNmYLVT755EsFc8kXpZj8D6AFKxc7OuveinJmiy0bYXAMspJUWsF6CrGpOw6CQ=="], + "@aws-sdk/middleware-bucket-endpoint": ["@aws-sdk/middleware-bucket-endpoint@3.775.0", "", { "dependencies": { "@aws-sdk/types": "3.775.0", "@aws-sdk/util-arn-parser": "3.723.0", "@smithy/node-config-provider": "^4.0.2", "@smithy/protocol-http": "^5.1.0", "@smithy/types": "^4.2.0", "@smithy/util-config-provider": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-qogMIpVChDYr4xiUNC19/RDSw/sKoHkAhouS6Skxiy6s27HBhow1L3Z1qVYXuBmOZGSWPU0xiyZCvOyWrv9s+Q=="], - "@aws-sdk/middleware-expect-continue": ["@aws-sdk/middleware-expect-continue@3.734.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-P38/v1l6HjuB2aFUewt7ueAW5IvKkFcv5dalPtbMGRhLeyivBOHwbCyuRKgVs7z7ClTpu9EaViEGki2jEQqEsQ=="], + "@aws-sdk/middleware-expect-continue": ["@aws-sdk/middleware-expect-continue@3.775.0", "", { "dependencies": { "@aws-sdk/types": "3.775.0", "@smithy/protocol-http": "^5.1.0", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Apd3owkIeUW5dnk3au9np2IdW2N0zc9NjTjHiH+Mx3zqwSrc+m+ANgJVgk9mnQjMzU/vb7VuxJ0eqdEbp5gYsg=="], - "@aws-sdk/middleware-flexible-checksums": ["@aws-sdk/middleware-flexible-checksums@3.758.0", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@aws-crypto/crc32c": "5.2.0", "@aws-crypto/util": "5.2.0", "@aws-sdk/core": "3.758.0", "@aws-sdk/types": "3.734.0", "@smithy/is-array-buffer": "^4.0.0", "@smithy/node-config-provider": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "@smithy/util-middleware": "^4.0.1", "@smithy/util-stream": "^4.1.2", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-o8Rk71S08YTKLoSobucjnbj97OCGaXgpEDNKXpXaavUM5xLNoHCLSUPRCiEN86Ivqxg1n17Y2nSRhfbsveOXXA=="], + "@aws-sdk/middleware-flexible-checksums": ["@aws-sdk/middleware-flexible-checksums@3.775.0", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@aws-crypto/crc32c": "5.2.0", "@aws-crypto/util": "5.2.0", "@aws-sdk/core": "3.775.0", "@aws-sdk/types": "3.775.0", "@smithy/is-array-buffer": "^4.0.0", "@smithy/node-config-provider": "^4.0.2", "@smithy/protocol-http": "^5.1.0", "@smithy/types": "^4.2.0", "@smithy/util-middleware": "^4.0.2", "@smithy/util-stream": "^4.2.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-OmHLfRIb7IIXsf9/X/pMOlcSV3gzW/MmtPSZTkrz5jCTKzWXd7eRoyOJqewjsaC6KMAxIpNU77FoAd16jOZ21A=="], - "@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.734.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-LW7RRgSOHHBzWZnigNsDIzu3AiwtjeI2X66v+Wn1P1u+eXssy1+up4ZY/h+t2sU4LU36UvEf+jrZti9c6vRnFw=="], + "@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.775.0", "", { "dependencies": { "@aws-sdk/types": "3.775.0", "@smithy/protocol-http": "^5.1.0", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-tkSegM0Z6WMXpLB8oPys/d+umYIocvO298mGvcMCncpRl77L9XkvSLJIFzaHes+o7djAgIduYw8wKIMStFss2w=="], - "@aws-sdk/middleware-location-constraint": ["@aws-sdk/middleware-location-constraint@3.734.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-EJEIXwCQhto/cBfHdm3ZOeLxd2NlJD+X2F+ZTOxzokuhBtY0IONfC/91hOo5tWQweerojwshSMHRCKzRv1tlwg=="], + "@aws-sdk/middleware-location-constraint": ["@aws-sdk/middleware-location-constraint@3.775.0", "", { "dependencies": { "@aws-sdk/types": "3.775.0", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-8TMXEHZXZTFTckQLyBT5aEI8fX11HZcwZseRifvBKKpj0RZDk4F0EEYGxeNSPpUQ7n+PRWyfAEnnZNRdAj/1NQ=="], - "@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.734.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-mUMFITpJUW3LcKvFok176eI5zXAUomVtahb9IQBwLzkqFYOrMJvWAvoV4yuxrJ8TlQBG8gyEnkb9SnhZvjg67w=="], + "@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.775.0", "", { "dependencies": { "@aws-sdk/types": "3.775.0", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-FaxO1xom4MAoUJsldmR92nT1G6uZxTdNYOFYtdHfd6N2wcNaTuxgjIvqzg5y7QIH9kn58XX/dzf1iTjgqUStZw=="], - "@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.772.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-zg0LjJa4v7fcLzn5QzZvtVS+qyvmsnu7oQnb86l6ckduZpWDCDC9+A0ZzcXTrxblPCJd3JqkoG1+Gzi4S4Ny/Q=="], + "@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.775.0", "", { "dependencies": { "@aws-sdk/types": "3.775.0", "@smithy/protocol-http": "^5.1.0", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GLCzC8D0A0YDG5u3F5U03Vb9j5tcOEFhr8oc6PDk0k0vm5VwtZOE6LvK7hcCSoAB4HXyOUM0sQuXrbaAh9OwXA=="], - "@aws-sdk/middleware-sdk-s3": ["@aws-sdk/middleware-sdk-s3@3.758.0", "", { "dependencies": { "@aws-sdk/core": "3.758.0", "@aws-sdk/types": "3.734.0", "@aws-sdk/util-arn-parser": "3.723.0", "@smithy/core": "^3.1.5", "@smithy/node-config-provider": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/signature-v4": "^5.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "@smithy/util-config-provider": "^4.0.0", "@smithy/util-middleware": "^4.0.1", "@smithy/util-stream": "^4.1.2", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-6mJ2zyyHPYSV6bAcaFpsdoXZJeQlR1QgBnZZ6juY/+dcYiuyWCdyLUbGzSZSE7GTfx6i+9+QWFeoIMlWKgU63A=="], + "@aws-sdk/middleware-sdk-s3": ["@aws-sdk/middleware-sdk-s3@3.775.0", "", { "dependencies": { "@aws-sdk/core": "3.775.0", "@aws-sdk/types": "3.775.0", "@aws-sdk/util-arn-parser": "3.723.0", "@smithy/core": "^3.2.0", "@smithy/node-config-provider": "^4.0.2", "@smithy/protocol-http": "^5.1.0", "@smithy/signature-v4": "^5.0.2", "@smithy/smithy-client": "^4.2.0", "@smithy/types": "^4.2.0", "@smithy/util-config-provider": "^4.0.0", "@smithy/util-middleware": "^4.0.2", "@smithy/util-stream": "^4.2.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-zsvcu7cWB28JJ60gVvjxPCI7ZU7jWGcpNACPiZGyVtjYXwcxyhXbYEVDSWKsSA6ERpz9XrpLYod8INQWfW3ECg=="], - "@aws-sdk/middleware-ssec": ["@aws-sdk/middleware-ssec@3.734.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-d4yd1RrPW/sspEXizq2NSOUivnheac6LPeLSLnaeTbBG9g1KqIqvCzP1TfXEqv2CrWfHEsWtJpX7oyjySSPvDQ=="], + "@aws-sdk/middleware-ssec": ["@aws-sdk/middleware-ssec@3.775.0", "", { "dependencies": { "@aws-sdk/types": "3.775.0", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Iw1RHD8vfAWWPzBBIKaojO4GAvQkHOYIpKdAfis/EUSUmSa79QsnXnRqsdcE0mCB0Ylj23yi+ah4/0wh9FsekA=="], - "@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.758.0", "", { "dependencies": { "@aws-sdk/core": "3.758.0", "@aws-sdk/types": "3.734.0", "@aws-sdk/util-endpoints": "3.743.0", "@smithy/core": "^3.1.5", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-iNyehQXtQlj69JCgfaOssgZD4HeYGOwxcaKeG6F+40cwBjTAi0+Ph1yfDwqk2qiBPIRWJ/9l2LodZbxiBqgrwg=="], + "@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.775.0", "", { "dependencies": { "@aws-sdk/core": "3.775.0", "@aws-sdk/types": "3.775.0", "@aws-sdk/util-endpoints": "3.775.0", "@smithy/core": "^3.2.0", "@smithy/protocol-http": "^5.1.0", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-7Lffpr1ptOEDE1ZYH1T78pheEY1YmeXWBfFt/amZ6AGsKSLG+JPXvof3ltporTGR2bhH/eJPo7UHCglIuXfzYg=="], - "@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.772.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.758.0", "@aws-sdk/middleware-host-header": "3.734.0", "@aws-sdk/middleware-logger": "3.734.0", "@aws-sdk/middleware-recursion-detection": "3.772.0", "@aws-sdk/middleware-user-agent": "3.758.0", "@aws-sdk/region-config-resolver": "3.734.0", "@aws-sdk/types": "3.734.0", "@aws-sdk/util-endpoints": "3.743.0", "@aws-sdk/util-user-agent-browser": "3.734.0", "@aws-sdk/util-user-agent-node": "3.758.0", "@smithy/config-resolver": "^4.0.1", "@smithy/core": "^3.1.5", "@smithy/fetch-http-handler": "^5.0.1", "@smithy/hash-node": "^4.0.1", "@smithy/invalid-dependency": "^4.0.1", "@smithy/middleware-content-length": "^4.0.1", "@smithy/middleware-endpoint": "^4.0.6", "@smithy/middleware-retry": "^4.0.7", "@smithy/middleware-serde": "^4.0.2", "@smithy/middleware-stack": "^4.0.1", "@smithy/node-config-provider": "^4.0.1", "@smithy/node-http-handler": "^4.0.3", "@smithy/protocol-http": "^5.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "@smithy/url-parser": "^4.0.1", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", "@smithy/util-defaults-mode-browser": "^4.0.7", "@smithy/util-defaults-mode-node": "^4.0.7", "@smithy/util-endpoints": "^3.0.1", "@smithy/util-middleware": "^4.0.1", "@smithy/util-retry": "^4.0.1", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-gNJbBxR5YlEumsCS9EWWEASXEnysL0aDnr9MNPX1ip/g1xOqRHmytgV/+t8RFZFTKg0OprbWTq5Ich3MqsEuCQ=="], + "@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.775.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.775.0", "@aws-sdk/middleware-host-header": "3.775.0", "@aws-sdk/middleware-logger": "3.775.0", "@aws-sdk/middleware-recursion-detection": "3.775.0", "@aws-sdk/middleware-user-agent": "3.775.0", "@aws-sdk/region-config-resolver": "3.775.0", "@aws-sdk/types": "3.775.0", "@aws-sdk/util-endpoints": "3.775.0", "@aws-sdk/util-user-agent-browser": "3.775.0", "@aws-sdk/util-user-agent-node": "3.775.0", "@smithy/config-resolver": "^4.1.0", "@smithy/core": "^3.2.0", "@smithy/fetch-http-handler": "^5.0.2", "@smithy/hash-node": "^4.0.2", "@smithy/invalid-dependency": "^4.0.2", "@smithy/middleware-content-length": "^4.0.2", "@smithy/middleware-endpoint": "^4.1.0", "@smithy/middleware-retry": "^4.1.0", "@smithy/middleware-serde": "^4.0.3", "@smithy/middleware-stack": "^4.0.2", "@smithy/node-config-provider": "^4.0.2", "@smithy/node-http-handler": "^4.0.4", "@smithy/protocol-http": "^5.1.0", "@smithy/smithy-client": "^4.2.0", "@smithy/types": "^4.2.0", "@smithy/url-parser": "^4.0.2", "@smithy/util-base64": "^4.0.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-body-length-node": "^4.0.0", "@smithy/util-defaults-mode-browser": "^4.0.8", "@smithy/util-defaults-mode-node": "^4.0.8", "@smithy/util-endpoints": "^3.0.2", "@smithy/util-middleware": "^4.0.2", "@smithy/util-retry": "^4.0.2", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-f37jmAzkuIhKyhtA6s0LGpqQvm218vq+RNMUDkGm1Zz2fxJ5pBIUTDtygiI3vXTcmt9DTIB8S6JQhjrgtboktw=="], - "@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.734.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@smithy/node-config-provider": "^4.0.1", "@smithy/types": "^4.1.0", "@smithy/util-config-provider": "^4.0.0", "@smithy/util-middleware": "^4.0.1", "tslib": "^2.6.2" } }, "sha512-Lvj1kPRC5IuJBr9DyJ9T9/plkh+EfKLy+12s/mykOy1JaKHDpvj+XGy2YO6YgYVOb8JFtaqloid+5COtje4JTQ=="], + "@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.775.0", "", { "dependencies": { "@aws-sdk/types": "3.775.0", "@smithy/node-config-provider": "^4.0.2", "@smithy/types": "^4.2.0", "@smithy/util-config-provider": "^4.0.0", "@smithy/util-middleware": "^4.0.2", "tslib": "^2.6.2" } }, "sha512-40iH3LJjrQS3LKUJAl7Wj0bln7RFPEvUYKFxtP8a+oKFDO0F65F52xZxIJbPn6sHkxWDAnZlGgdjZXM3p2g5wQ=="], - "@aws-sdk/s3-request-presigner": ["@aws-sdk/s3-request-presigner@3.772.0", "", { "dependencies": { "@aws-sdk/signature-v4-multi-region": "3.758.0", "@aws-sdk/types": "3.734.0", "@aws-sdk/util-format-url": "3.734.0", "@smithy/middleware-endpoint": "^4.0.6", "@smithy/protocol-http": "^5.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-y6OrwZXJyKaKw6suozQgc9AwKbZLjTu1hXe6sJ1rCyvhU171bWXjcdeux+Gw0iIX5wVdPQVHA/e5g9QYUaZOMw=="], + "@aws-sdk/s3-request-presigner": ["@aws-sdk/s3-request-presigner@3.775.0", "", { "dependencies": { "@aws-sdk/signature-v4-multi-region": "3.775.0", "@aws-sdk/types": "3.775.0", "@aws-sdk/util-format-url": "3.775.0", "@smithy/middleware-endpoint": "^4.1.0", "@smithy/protocol-http": "^5.1.0", "@smithy/smithy-client": "^4.2.0", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-NpACBvEdT3VERGX1cWGIITZ5Qq2MknrEugY3ivs8CDGze1uunm6+oTh8YPMUlHOZq2TuI9ktKWh7YZoHBRRUTw=="], - "@aws-sdk/signature-v4-multi-region": ["@aws-sdk/signature-v4-multi-region@3.758.0", "", { "dependencies": { "@aws-sdk/middleware-sdk-s3": "3.758.0", "@aws-sdk/types": "3.734.0", "@smithy/protocol-http": "^5.0.1", "@smithy/signature-v4": "^5.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-0RPCo8fYJcrenJ6bRtiUbFOSgQ1CX/GpvwtLU2Fam1tS9h2klKK8d74caeV6A1mIUvBU7bhyQ0wMGlwMtn3EYw=="], + "@aws-sdk/signature-v4-multi-region": ["@aws-sdk/signature-v4-multi-region@3.775.0", "", { "dependencies": { "@aws-sdk/middleware-sdk-s3": "3.775.0", "@aws-sdk/types": "3.775.0", "@smithy/protocol-http": "^5.1.0", "@smithy/signature-v4": "^5.0.2", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-cnGk8GDfTMJ8p7+qSk92QlIk2bmTmFJqhYxcXZ9PysjZtx0xmfCMxnG3Hjy1oU2mt5boPCVSOptqtWixayM17g=="], - "@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.772.0", "", { "dependencies": { "@aws-sdk/nested-clients": "3.772.0", "@aws-sdk/types": "3.734.0", "@smithy/property-provider": "^4.0.1", "@smithy/shared-ini-file-loader": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-d1Waa1vyebuokcAWYlkZdtFlciIgob7B39vPRmtxMObbGumJKiOy/qCe2/FB/72h1Ej9Ih32lwvbxUjORQWN4g=="], + "@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.775.0", "", { "dependencies": { "@aws-sdk/nested-clients": "3.775.0", "@aws-sdk/types": "3.775.0", "@smithy/property-provider": "^4.0.2", "@smithy/shared-ini-file-loader": "^4.0.2", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Q6MtbEhkOggVSz/dN89rIY/ry80U3v89o0Lrrc+Rpvaiaaz8pEN0DsfEcg0IjpzBQ8Owoa6lNWyglHbzPhaJpA=="], - "@aws-sdk/types": ["@aws-sdk/types@3.734.0", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-o11tSPTT70nAkGV1fN9wm/hAIiLPyWX6SuGf+9JyTp7S/rC2cFWhR26MvA69nplcjNaXVzB0f+QFrLXXjOqCrg=="], + "@aws-sdk/types": ["@aws-sdk/types@3.775.0", "", { "dependencies": { "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-ZoGKwa4C9fC9Av6bdfqcW6Ix5ot05F/S4VxWR2nHuMv7hzfmAjTOcUiWT7UR4hM/U0whf84VhDtXN/DWAk52KA=="], "@aws-sdk/util-arn-parser": ["@aws-sdk/util-arn-parser@3.723.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-ZhEfvUwNliOQROcAk34WJWVYTlTa4694kSVhDSjW6lE1bMataPnIN8A0ycukEzBXmd8ZSoBcQLn6lKGl7XIJ5w=="], - "@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.743.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@smithy/types": "^4.1.0", "@smithy/util-endpoints": "^3.0.1", "tslib": "^2.6.2" } }, "sha512-sN1l559zrixeh5x+pttrnd0A3+r34r0tmPkJ/eaaMaAzXqsmKU/xYre9K3FNnsSS1J1k4PEfk/nHDTVUgFYjnw=="], + "@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.775.0", "", { "dependencies": { "@aws-sdk/types": "3.775.0", "@smithy/types": "^4.2.0", "@smithy/util-endpoints": "^3.0.2", "tslib": "^2.6.2" } }, "sha512-yjWmUgZC9tUxAo8Uaplqmq0eUh0zrbZJdwxGRKdYxfm4RG6fMw1tj52+KkatH7o+mNZvg1GDcVp/INktxonJLw=="], - "@aws-sdk/util-format-url": ["@aws-sdk/util-format-url@3.734.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@smithy/querystring-builder": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-TxZMVm8V4aR/QkW9/NhujvYpPZjUYqzLwSge5imKZbWFR806NP7RMwc5ilVuHF/bMOln/cVHkl42kATElWBvNw=="], + "@aws-sdk/util-format-url": ["@aws-sdk/util-format-url@3.775.0", "", { "dependencies": { "@aws-sdk/types": "3.775.0", "@smithy/querystring-builder": "^4.0.2", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Nw4nBeyCbWixoGh8NcVpa/i8McMA6RXJIjQFyloJLaPr7CPquz7ZbSl0MUWMFVwP/VHaJ7B+lNN3Qz1iFCEP/Q=="], "@aws-sdk/util-locate-window": ["@aws-sdk/util-locate-window@3.723.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Yf2CS10BqK688DRsrKI/EO6B8ff5J86NXe4C+VCysK7UOgN0l1zOTeTukZ3H8Q9tYYX3oaF1961o8vRkFm7Nmw=="], - "@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.734.0", "", { "dependencies": { "@aws-sdk/types": "3.734.0", "@smithy/types": "^4.1.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-xQTCus6Q9LwUuALW+S76OL0jcWtMOVu14q+GoLnWPUM7QeUw963oQcLhF7oq0CtaLLKyl4GOUfcwc773Zmwwng=="], + "@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.775.0", "", { "dependencies": { "@aws-sdk/types": "3.775.0", "@smithy/types": "^4.2.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-txw2wkiJmZKVdDbscK7VBK+u+TJnRtlUjRTLei+elZg2ADhpQxfVAQl436FUeIv6AhB/oRHW6/K/EAGXUSWi0A=="], - "@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.758.0", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "3.758.0", "@aws-sdk/types": "3.734.0", "@smithy/node-config-provider": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-A5EZw85V6WhoKMV2hbuFRvb9NPlxEErb4HPO6/SPXYY4QrjprIzScHxikqcWv1w4J3apB1wto9LPU3IMsYtfrw=="], + "@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.775.0", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "3.775.0", "@aws-sdk/types": "3.775.0", "@smithy/node-config-provider": "^4.0.2", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-N9yhTevbizTOMo3drH7Eoy6OkJ3iVPxhV7dwb6CMAObbLneS36CSfA6xQXupmHWcRvZPTz8rd1JGG3HzFOau+g=="], - "@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.734.0", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-Zrjxi5qwGEcUsJ0ru7fRtW74WcTS0rbLcehoFB+rN1GRi2hbLcFaYs4PwVA5diLeAJH0gszv3x4Hr/S87MfbKQ=="], + "@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.775.0", "", { "dependencies": { "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-b9NGO6FKJeLGYnV7Z1yvcP1TNU4dkD5jNsLWOF1/sygZoASaQhNOlaiJ/1OH331YQ1R1oWk38nBb0frsYkDsOQ=="], "@babel/code-frame": ["@babel/code-frame@7.26.2", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.25.9", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" } }, "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ=="], @@ -896,15 +918,15 @@ "@babel/core": ["@babel/core@7.26.10", "", { "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.26.2", "@babel/generator": "^7.26.10", "@babel/helper-compilation-targets": "^7.26.5", "@babel/helper-module-transforms": "^7.26.0", "@babel/helpers": "^7.26.10", "@babel/parser": "^7.26.10", "@babel/template": "^7.26.9", "@babel/traverse": "^7.26.10", "@babel/types": "^7.26.10", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ=="], - "@babel/generator": ["@babel/generator@7.26.10", "", { "dependencies": { "@babel/parser": "^7.26.10", "@babel/types": "^7.26.10", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" } }, "sha512-rRHT8siFIXQrAYOYqZQVsAr8vJ+cBNqcVAY6m5V8/4QqzaPl+zDBe6cLEPRDuNOUf3ww8RfJVlOyQMoSI+5Ang=="], + "@babel/generator": ["@babel/generator@7.27.0", "", { "dependencies": { "@babel/parser": "^7.27.0", "@babel/types": "^7.27.0", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" } }, "sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw=="], "@babel/helper-annotate-as-pure": ["@babel/helper-annotate-as-pure@7.25.9", "", { "dependencies": { "@babel/types": "^7.25.9" } }, "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g=="], - "@babel/helper-compilation-targets": ["@babel/helper-compilation-targets@7.26.5", "", { "dependencies": { "@babel/compat-data": "^7.26.5", "@babel/helper-validator-option": "^7.25.9", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA=="], + "@babel/helper-compilation-targets": ["@babel/helper-compilation-targets@7.27.0", "", { "dependencies": { "@babel/compat-data": "^7.26.8", "@babel/helper-validator-option": "^7.25.9", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "sha512-LVk7fbXml0H2xH34dFzKQ7TDZ2G4/rVTOrq9V+icbbadjbVxxeFeDsNHv2SrZeWoA+6ZiTyWYWtScEIW07EAcA=="], - "@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.26.9", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.25.9", "@babel/helper-member-expression-to-functions": "^7.25.9", "@babel/helper-optimise-call-expression": "^7.25.9", "@babel/helper-replace-supers": "^7.26.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", "@babel/traverse": "^7.26.9", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-ubbUqCofvxPRurw5L8WTsCLSkQiVpov4Qx0WMA+jUN+nXBK8ADPlJO1grkFw5CWKC5+sZSOfuGMdX1aI1iT9Sg=="], + "@babel/helper-create-class-features-plugin": ["@babel/helper-create-class-features-plugin@7.27.0", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.25.9", "@babel/helper-member-expression-to-functions": "^7.25.9", "@babel/helper-optimise-call-expression": "^7.25.9", "@babel/helper-replace-supers": "^7.26.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", "@babel/traverse": "^7.27.0", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-vSGCvMecvFCd/BdpGlhpXYNhhC4ccxyvQWpbGL4CWbvfEoLFWUZuSuf7s9Aw70flgQF+6vptvgK2IfOnKlRmBg=="], - "@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.26.3", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.25.9", "regexpu-core": "^6.2.0", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong=="], + "@babel/helper-create-regexp-features-plugin": ["@babel/helper-create-regexp-features-plugin@7.27.0", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.25.9", "regexpu-core": "^6.2.0", "semver": "^6.3.1" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-fO8l08T76v48BhpNRW/nQ0MxfnSdoSKUJBMjubOAYffsVuGG5qOfMq7N6Es7UJvi7Y8goXXo07EfcHZXDPuELQ=="], "@babel/helper-define-polyfill-provider": ["@babel/helper-define-polyfill-provider@0.6.4", "", { "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", "@babel/helper-plugin-utils": "^7.22.5", "debug": "^4.1.1", "lodash.debounce": "^4.0.8", "resolve": "^1.14.2" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "sha512-jljfR1rGnXXNWnmQg2K3+bvhkxB51Rl32QRaOTuwwjviGrHzIbSc8+x9CpraDtbT7mfyjXObULP4w/adunNwAw=="], @@ -932,9 +954,9 @@ "@babel/helper-wrap-function": ["@babel/helper-wrap-function@7.25.9", "", { "dependencies": { "@babel/template": "^7.25.9", "@babel/traverse": "^7.25.9", "@babel/types": "^7.25.9" } }, "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g=="], - "@babel/helpers": ["@babel/helpers@7.26.10", "", { "dependencies": { "@babel/template": "^7.26.9", "@babel/types": "^7.26.10" } }, "sha512-UPYc3SauzZ3JGgj87GgZ89JVdC5dj0AoetR5Bw6wj4niittNyFh6+eOGonYvJ1ao6B8lEa3Q3klS7ADZ53bc5g=="], + "@babel/helpers": ["@babel/helpers@7.27.0", "", { "dependencies": { "@babel/template": "^7.27.0", "@babel/types": "^7.27.0" } }, "sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg=="], - "@babel/parser": ["@babel/parser@7.26.10", "", { "dependencies": { "@babel/types": "^7.26.10" }, "bin": "./bin/babel-parser.js" }, "sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA=="], + "@babel/parser": ["@babel/parser@7.27.0", "", { "dependencies": { "@babel/types": "^7.27.0" }, "bin": "./bin/babel-parser.js" }, "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg=="], "@babel/plugin-bugfix-firefox-class-in-computed-class-key": ["@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9", "@babel/traverse": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g=="], @@ -968,7 +990,7 @@ "@babel/plugin-transform-block-scoped-functions": ["@babel/plugin-transform-block-scoped-functions@7.26.5", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.26.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-chuTSY+hq09+/f5lMj8ZSYgCFpppV2CbYrhNFJ1BFoXpiWPnnAb7R0MqrafCpN8E1+YRrtM1MXZHJdIx8B6rMQ=="], - "@babel/plugin-transform-block-scoping": ["@babel/plugin-transform-block-scoping@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg=="], + "@babel/plugin-transform-block-scoping": ["@babel/plugin-transform-block-scoping@7.27.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.26.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-u1jGphZ8uDI2Pj/HJj6YQ6XQLZCNjOlprjxB5SVz6rq2T6SwAR+CdrWK0CP7F+9rDVMXdB0+r6Am5G5aobOjAQ=="], "@babel/plugin-transform-class-properties": ["@babel/plugin-transform-class-properties@7.25.9", "", { "dependencies": { "@babel/helper-create-class-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q=="], @@ -1050,7 +1072,7 @@ "@babel/plugin-transform-react-pure-annotations": ["@babel/plugin-transform-react-pure-annotations@7.25.9", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-KQ/Takk3T8Qzj5TppkS1be588lkbTp5uj7w6a0LeQaTMSckU/wK0oJ/pih+T690tkgI5jfmg2TqDJvd41Sj1Cg=="], - "@babel/plugin-transform-regenerator": ["@babel/plugin-transform-regenerator@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9", "regenerator-transform": "^0.15.2" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg=="], + "@babel/plugin-transform-regenerator": ["@babel/plugin-transform-regenerator@7.27.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.26.5", "regenerator-transform": "^0.15.2" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-LX/vCajUJQDqE7Aum/ELUMZAY19+cDpghxrnyt5I1tV6X5PyC86AOoWXWFYFeIvauyeSA6/ktn4tQVn/3ZifsA=="], "@babel/plugin-transform-regexp-modifiers": ["@babel/plugin-transform-regexp-modifiers@7.26.0", "", { "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw=="], @@ -1066,9 +1088,9 @@ "@babel/plugin-transform-template-literals": ["@babel/plugin-transform-template-literals@7.26.8", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.26.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-OmGDL5/J0CJPJZTHZbi2XpO0tyT2Ia7fzpW5GURwdtp2X3fMmN8au/ej6peC/T33/+CRiIpA8Krse8hFGVmT5Q=="], - "@babel/plugin-transform-typeof-symbol": ["@babel/plugin-transform-typeof-symbol@7.26.7", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.26.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-jfoTXXZTgGg36BmhqT3cAYK5qkmqvJpvNrPhaK/52Vgjhw4Rq29s9UqpWWV0D6yuRmgiFH/BUVlkl96zJWqnaw=="], + "@babel/plugin-transform-typeof-symbol": ["@babel/plugin-transform-typeof-symbol@7.27.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.26.5" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-+LLkxA9rKJpNoGsbLnAgOCdESl73vwYn+V6b+5wHbrE7OGKVDPHIQvbFSzqE6rwqaCw2RE+zdJrlLkcf8YOA0w=="], - "@babel/plugin-transform-typescript": ["@babel/plugin-transform-typescript@7.26.8", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.25.9", "@babel/helper-create-class-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.26.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", "@babel/plugin-syntax-typescript": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-bME5J9AC8ChwA7aEPJ6zym3w7aObZULHhbNLU0bKUhKsAkylkzUdq+0kdymh9rzi8nlNFl2bmldFBCKNJBUpuw=="], + "@babel/plugin-transform-typescript": ["@babel/plugin-transform-typescript@7.27.0", "", { "dependencies": { "@babel/helper-annotate-as-pure": "^7.25.9", "@babel/helper-create-class-features-plugin": "^7.27.0", "@babel/helper-plugin-utils": "^7.26.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", "@babel/plugin-syntax-typescript": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-fRGGjO2UEGPjvEcyAZXRXAS8AfdaQoq7HnxAbJoAoW10B9xOKesmmndJv+Sym2a+9FHWZ9KbyyLCe9s0Sn5jtg=="], "@babel/plugin-transform-unicode-escapes": ["@babel/plugin-transform-unicode-escapes@7.25.9", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q=="], @@ -1084,17 +1106,17 @@ "@babel/preset-react": ["@babel/preset-react@7.26.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9", "@babel/helper-validator-option": "^7.25.9", "@babel/plugin-transform-react-display-name": "^7.25.9", "@babel/plugin-transform-react-jsx": "^7.25.9", "@babel/plugin-transform-react-jsx-development": "^7.25.9", "@babel/plugin-transform-react-pure-annotations": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Nl03d6T9ky516DGK2YMxrTqvnpUW63TnJMOMonj+Zae0JiPC5BC9xPMSL6L8fiSpA5vP88qfygavVQvnLp+6Cw=="], - "@babel/preset-typescript": ["@babel/preset-typescript@7.26.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.25.9", "@babel/helper-validator-option": "^7.25.9", "@babel/plugin-syntax-jsx": "^7.25.9", "@babel/plugin-transform-modules-commonjs": "^7.25.9", "@babel/plugin-transform-typescript": "^7.25.9" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-NMk1IGZ5I/oHhoXEElcm+xUnL/szL6xflkFZmoEU9xj1qSJXpiS7rsspYo92B4DRCDvZn2erT5LdsCeXAKNCkg=="], + "@babel/preset-typescript": ["@babel/preset-typescript@7.27.0", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.26.5", "@babel/helper-validator-option": "^7.25.9", "@babel/plugin-syntax-jsx": "^7.25.9", "@babel/plugin-transform-modules-commonjs": "^7.26.3", "@babel/plugin-transform-typescript": "^7.27.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-vxaPFfJtHhgeOVXRKuHpHPAOgymmy8V8I65T1q53R7GCZlefKeCaTyDs3zOPHTTbmquvNlQYC5klEvWsBAtrBQ=="], - "@babel/runtime": ["@babel/runtime@7.26.10", "", { "dependencies": { "regenerator-runtime": "^0.14.0" } }, "sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw=="], + "@babel/runtime": ["@babel/runtime@7.27.0", "", { "dependencies": { "regenerator-runtime": "^0.14.0" } }, "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw=="], - "@babel/runtime-corejs3": ["@babel/runtime-corejs3@7.26.10", "", { "dependencies": { "core-js-pure": "^3.30.2", "regenerator-runtime": "^0.14.0" } }, "sha512-uITFQYO68pMEYR46AHgQoyBg7KPPJDAbGn4jUTIRgCFJIp88MIBUianVOplhZDEec07bp9zIyr4Kp0FCyQzmWg=="], + "@babel/runtime-corejs3": ["@babel/runtime-corejs3@7.27.0", "", { "dependencies": { "core-js-pure": "^3.30.2", "regenerator-runtime": "^0.14.0" } }, "sha512-UWjX6t+v+0ckwZ50Y5ShZLnlk95pP5MyW/pon9tiYzl3+18pkTHTFNTKr7rQbfRXPkowt2QAn30o1b6oswszew=="], - "@babel/template": ["@babel/template@7.26.9", "", { "dependencies": { "@babel/code-frame": "^7.26.2", "@babel/parser": "^7.26.9", "@babel/types": "^7.26.9" } }, "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA=="], + "@babel/template": ["@babel/template@7.27.0", "", { "dependencies": { "@babel/code-frame": "^7.26.2", "@babel/parser": "^7.27.0", "@babel/types": "^7.27.0" } }, "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA=="], - "@babel/traverse": ["@babel/traverse@7.26.10", "", { "dependencies": { "@babel/code-frame": "^7.26.2", "@babel/generator": "^7.26.10", "@babel/parser": "^7.26.10", "@babel/template": "^7.26.9", "@babel/types": "^7.26.10", "debug": "^4.3.1", "globals": "^11.1.0" } }, "sha512-k8NuDrxr0WrPH5Aupqb2LCVURP/S0vBEn5mK6iH+GIYob66U5EtoZvcdudR2jQ4cmTwhEwW1DLB+Yyas9zjF6A=="], + "@babel/traverse": ["@babel/traverse@7.27.0", "", { "dependencies": { "@babel/code-frame": "^7.26.2", "@babel/generator": "^7.27.0", "@babel/parser": "^7.27.0", "@babel/template": "^7.27.0", "@babel/types": "^7.27.0", "debug": "^4.3.1", "globals": "^11.1.0" } }, "sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA=="], - "@babel/types": ["@babel/types@7.26.10", "", { "dependencies": { "@babel/helper-string-parser": "^7.25.9", "@babel/helper-validator-identifier": "^7.25.9" } }, "sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ=="], + "@babel/types": ["@babel/types@7.27.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.25.9", "@babel/helper-validator-identifier": "^7.25.9" } }, "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg=="], "@balena/dockerignore": ["@balena/dockerignore@1.0.2", "", {}, "sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q=="], @@ -1204,6 +1226,8 @@ "@csstools/utilities": ["@csstools/utilities@2.0.0", "", { "peerDependencies": { "postcss": "^8.4" } }, "sha512-5VdOr0Z71u+Yp3ozOx8T11N703wIFGVRgOWbOZMKgglPJsWA54MRIoMNVMa7shUToIhx5J8vX4sOZgD2XiihiQ=="], + "@derhuerst/http-basic": ["@derhuerst/http-basic@8.2.4", "", { "dependencies": { "caseless": "^0.12.0", "concat-stream": "^2.0.0", "http-response-object": "^3.0.1", "parse-cache-control": "^1.0.1" } }, "sha512-F9rL9k9Xjf5blCz8HsJRO4diy111cayL2vkY2XE4r4t3n0yPXVYy3KD3nJ1qbrSn9743UWSXH4IwuCa/HWlGFw=="], + "@discordjs/builders": ["@discordjs/builders@1.10.1", "", { "dependencies": { "@discordjs/formatters": "^0.6.0", "@discordjs/util": "^1.1.1", "@sapphire/shapeshift": "^4.0.0", "discord-api-types": "^0.37.119", "fast-deep-equal": "^3.1.3", "ts-mixer": "^6.0.4", "tslib": "^2.6.3" } }, "sha512-OWo1fY4ztL1/M/DUyRPShB4d/EzVfuUvPTRRHRIt/YxBrUYSz0a+JicD5F5zHFoNs2oTuWavxCOVFV1UljHTng=="], "@discordjs/collection": ["@discordjs/collection@2.1.1", "", {}, "sha512-LiSusze9Tc7qF03sLCujF5iZp7K+vRNEDBZ86FT9aQAv3vxMLihUvKvpsCWiQ2DJq1tVckopKm1rxomgNUc9hg=="], @@ -1320,6 +1344,8 @@ "@elizaos/plugin-pdf": ["@elizaos/plugin-pdf@workspace:packages/plugin-pdf"], + "@elizaos/plugin-redpill": ["@elizaos/plugin-redpill@workspace:packages/plugin-redpill"], + "@elizaos/plugin-solana": ["@elizaos/plugin-solana@workspace:packages/plugin-solana"], "@elizaos/plugin-sql": ["@elizaos/plugin-sql@workspace:packages/plugin-sql"], @@ -1448,13 +1474,13 @@ "@huggingface/hub": ["@huggingface/hub@1.1.2", "", { "dependencies": { "@huggingface/tasks": "^0.18.2" } }, "sha512-Jf4GhvVj9ABDw4Itb3BV1T7f22iewuZva476qTicQ4kOTbosuUuFDhsVH7ZH6rVNgg20Ll9kaNBF5CXjySIT+w=="], - "@huggingface/inference": ["@huggingface/inference@3.6.1", "", { "dependencies": { "@huggingface/jinja": "^0.3.3", "@huggingface/tasks": "^0.17.8" } }, "sha512-EtQlbBqcZycPe+qiTEFI+wNHOMpG0gwNTaZSvYu1juN1p/1dEgqAb2GO31dxLgNev2PzH9d+9nm8GngOsIepJg=="], + "@huggingface/inference": ["@huggingface/inference@3.6.2", "", { "dependencies": { "@huggingface/jinja": "^0.3.3", "@huggingface/tasks": "^0.18.4" } }, "sha512-FkJr8dOP8yFTxGFi+X/ylwG3qoCq/s8WI2A4Jg13RBX3voJWrzadpHLD/99EKZU7r35X4Mm6tKUev7dR2B/cTg=="], "@huggingface/jinja": ["@huggingface/jinja@0.3.3", "", {}, "sha512-vQQr2JyWvVFba3Lj9es4q9vCl1sAc74fdgnEMoX8qHrXtswap9ge9uO3ONDzQB0cQ0PUyaKY2N6HaVbTBvSXvw=="], - "@huggingface/tasks": ["@huggingface/tasks@0.18.2", "", {}, "sha512-6g/6sj1gSyvUKJm+78yfiYOTU3VXMfoyh4M46AXloRD1iU/UfqB7dtAGZqcF9PuYxSFx7Q2zd8fzAYePkQ/ZvA=="], + "@huggingface/tasks": ["@huggingface/tasks@0.18.4", "", {}, "sha512-kZ8G2b6JSdVCn48VpmB2Kcb9ae16HmDRf4RWEQJMgbF98DFTt4y69fTcvQ1vi/qALRWL57pDpbzIlwWlVhY3aQ=="], - "@huggingface/transformers": ["@huggingface/transformers@3.4.0", "", { "dependencies": { "@huggingface/jinja": "^0.3.3", "onnxruntime-node": "1.20.1", "onnxruntime-web": "1.22.0-dev.20250306-ccf8fdd9ea", "sharp": "^0.33.5" } }, "sha512-jyuglsWc+Ls9/U7eGDDY+xYgDgDtwxQ4ul/5VQoqo2r0LfAnJ+zSRUjKnY6paOyzyhbKaftfEsvXJ049aL1cyw=="], + "@huggingface/transformers": ["@huggingface/transformers@3.4.1", "", { "dependencies": { "@huggingface/jinja": "^0.3.3", "onnxruntime-node": "1.20.1", "onnxruntime-web": "1.22.0-dev.20250306-ccf8fdd9ea", "sharp": "^0.33.5" } }, "sha512-Inbvq9i/33kmd5XHom9MQU7NAOV5UcGmHBwBk9NFw4IPhdoTnfP7wFJxJmceYhRdS+EL1Hpw4he/Ceimau6ORg=="], "@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="], @@ -1542,7 +1568,7 @@ "@kwsites/promise-deferred": ["@kwsites/promise-deferred@1.1.1", "", {}, "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw=="], - "@langchain/core": ["@langchain/core@0.3.42", "", { "dependencies": { "@cfworker/json-schema": "^4.0.2", "ansi-styles": "^5.0.0", "camelcase": "6", "decamelize": "1.2.0", "js-tiktoken": "^1.0.12", "langsmith": ">=0.2.8 <0.4.0", "mustache": "^4.2.0", "p-queue": "^6.6.2", "p-retry": "4", "uuid": "^10.0.0", "zod": "^3.22.4", "zod-to-json-schema": "^3.22.3" } }, "sha512-pT/jC5lqWK3YGDq8dQwgKoa6anqAhMtG1x5JbnrOj9NdaLeBbCKBDQ+/Ykzk3nZ8o+0UMsaXNZo7IVL83VVjHg=="], + "@langchain/core": ["@langchain/core@0.3.43", "", { "dependencies": { "@cfworker/json-schema": "^4.0.2", "ansi-styles": "^5.0.0", "camelcase": "6", "decamelize": "1.2.0", "js-tiktoken": "^1.0.12", "langsmith": ">=0.2.8 <0.4.0", "mustache": "^4.2.0", "p-queue": "^6.6.2", "p-retry": "4", "uuid": "^10.0.0", "zod": "^3.22.4", "zod-to-json-schema": "^3.22.3" } }, "sha512-DwiSUwmZqcuOn7j8SFdeOH1nvaUqG7q8qn3LhobdQYEg5PmjLgd2yLr2KzuT/YWMBfjkOR+Di5K6HEdFmouTxg=="], "@langchain/openai": ["@langchain/openai@0.3.17", "", { "dependencies": { "js-tiktoken": "^1.0.12", "openai": "^4.77.0", "zod": "^3.22.4", "zod-to-json-schema": "^3.22.3" }, "peerDependencies": { "@langchain/core": ">=0.3.29 <0.4.0" } }, "sha512-uw4po32OKptVjq+CYHrumgbfh4NuD7LqyE+ZgqY9I/LrLc6bHLMc+sisHmI17vgek0K/yqtarI0alPJbzrwyag=="], @@ -1564,7 +1590,7 @@ "@mdx-js/react": ["@mdx-js/react@3.0.1", "", { "dependencies": { "@types/mdx": "^2.0.0" }, "peerDependencies": { "@types/react": ">=16", "react": ">=16" } }, "sha512-9ZrPIU4MGf6et1m1ov3zKf+q9+deetI51zprKB1D/z3NOb+rUxxtEl3mCjW5wTGh6VhRdwPueh1oRzi6ezkA8A=="], - "@mermaid-js/parser": ["@mermaid-js/parser@0.3.0", "", { "dependencies": { "langium": "3.0.0" } }, "sha512-HsvL6zgE5sUPGgkIDlmAWR1HTNHz2Iy11BAWPTa4Jjabkpguy4Ze2gzfLrg6pdRuBvFwgUYyxiaNqZwrEEXepA=="], + "@mermaid-js/parser": ["@mermaid-js/parser@0.4.0", "", { "dependencies": { "langium": "3.3.1" } }, "sha512-wla8XOWvQAwuqy+gxiZqY+c7FokraOTHRWMsbB4AgRx9Sy7zKslNyejy7E+a77qHfey5GXw/ik3IXv/NHMJgaA=="], "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.4", "", { "dependencies": { "@emnapi/core": "^1.1.0", "@emnapi/runtime": "^1.1.0", "@tybys/wasm-util": "^0.9.0" } }, "sha512-9zESzOO5aDByvhIAsOy9TbpZ0Ur2AJbUI7UT73kcUTS2mxAMHOBaa1st/jAymNoCtvrit99kkzT1FZuXVcgfIQ=="], @@ -1934,43 +1960,45 @@ "@rollup/pluginutils": ["@rollup/pluginutils@5.1.4", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ=="], - "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.36.0", "", { "os": "android", "cpu": "arm" }, "sha512-jgrXjjcEwN6XpZXL0HUeOVGfjXhPyxAbbhD0BlXUB+abTOpbPiN5Wb3kOT7yb+uEtATNYF5x5gIfwutmuBA26w=="], + "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.37.0", "", { "os": "android", "cpu": "arm" }, "sha512-l7StVw6WAa8l3vA1ov80jyetOAEo1FtHvZDbzXDO/02Sq/QVvqlHkYoFwDJPIMj0GKiistsBudfx5tGFnwYWDQ=="], - "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.36.0", "", { "os": "android", "cpu": "arm64" }, "sha512-NyfuLvdPdNUfUNeYKUwPwKsE5SXa2J6bCt2LdB/N+AxShnkpiczi3tcLJrm5mA+eqpy0HmaIY9F6XCa32N5yzg=="], + "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.37.0", "", { "os": "android", "cpu": "arm64" }, "sha512-6U3SlVyMxezt8Y+/iEBcbp945uZjJwjZimu76xoG7tO1av9VO691z8PkhzQ85ith2I8R2RddEPeSfcbyPfD4hA=="], - "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.36.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-JQ1Jk5G4bGrD4pWJQzWsD8I1n1mgPXq33+/vP4sk8j/z/C2siRuxZtaUA7yMTf71TCZTZl/4e1bfzwUmFb3+rw=="], + "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.37.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-+iTQ5YHuGmPt10NTzEyMPbayiNTcOZDWsbxZYR1ZnmLnZxG17ivrPSWFO9j6GalY0+gV3Jtwrrs12DBscxnlYA=="], - "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.36.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-6c6wMZa1lrtiRsbDziCmjE53YbTkxMYhhnWnSW8R/yqsM7a6mSJ3uAVT0t8Y/DGt7gxUWYuFM4bwWk9XCJrFKA=="], + "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.37.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-m8W2UbxLDcmRKVjgl5J/k4B8d7qX2EcJve3Sut7YGrQoPtCIQGPH5AMzuFvYRWZi0FVS0zEY4c8uttPfX6bwYQ=="], - "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.36.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-KXVsijKeJXOl8QzXTsA+sHVDsFOmMCdBRgFmBb+mfEb/7geR7+C8ypAml4fquUt14ZyVXaw2o1FWhqAfOvA4sg=="], + "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.37.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-FOMXGmH15OmtQWEt174v9P1JqqhlgYge/bUjIbiVD1nI1NeJ30HYT9SJlZMqdo1uQFyt9cz748F1BHghWaDnVA=="], - "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.36.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-dVeWq1ebbvByI+ndz4IJcD4a09RJgRYmLccwlQ8bPd4olz3Y213uf1iwvc7ZaxNn2ab7bjc08PrtBgMu6nb4pQ=="], + "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.37.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-SZMxNttjPKvV14Hjck5t70xS3l63sbVwl98g3FlVVx2YIDmfUIy29jQrsw06ewEYQ8lQSuY9mpAPlmgRD2iSsA=="], - "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.36.0", "", { "os": "linux", "cpu": "arm" }, "sha512-bvXVU42mOVcF4le6XSjscdXjqx8okv4n5vmwgzcmtvFdifQ5U4dXFYaCB87namDRKlUL9ybVtLQ9ztnawaSzvg=="], + "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.37.0", "", { "os": "linux", "cpu": "arm" }, "sha512-hhAALKJPidCwZcj+g+iN+38SIOkhK2a9bqtJR+EtyxrKKSt1ynCBeqrQy31z0oWU6thRZzdx53hVgEbRkuI19w=="], - "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.36.0", "", { "os": "linux", "cpu": "arm" }, "sha512-JFIQrDJYrxOnyDQGYkqnNBtjDwTgbasdbUiQvcU8JmGDfValfH1lNpng+4FWlhaVIR4KPkeddYjsVVbmJYvDcg=="], + "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.37.0", "", { "os": "linux", "cpu": "arm" }, "sha512-jUb/kmn/Gd8epbHKEqkRAxq5c2EwRt0DqhSGWjPFxLeFvldFdHQs/n8lQ9x85oAeVb6bHcS8irhTJX2FCOd8Ag=="], - "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.36.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-KqjYVh3oM1bj//5X7k79PSCZ6CvaVzb7Qs7VMWS+SlWB5M8p3FqufLP9VNp4CazJ0CsPDLwVD9r3vX7Ci4J56A=="], + "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.37.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-oNrJxcQT9IcbcmKlkF+Yz2tmOxZgG9D9GRq+1OE6XCQwCVwxixYAa38Z8qqPzQvzt1FCfmrHX03E0pWoXm1DqA=="], - "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.36.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-QiGnhScND+mAAtfHqeT+cB1S9yFnNQ/EwCg5yE3MzoaZZnIV0RV9O5alJAoJKX/sBONVKeZdMfO8QSaWEygMhw=="], + "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.37.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-pfxLBMls+28Ey2enpX3JvjEjaJMBX5XlPCZNGxj4kdJyHduPBXtxYeb8alo0a7bqOoWZW2uKynhHxF/MWoHaGQ=="], - "@rollup/rollup-linux-loongarch64-gnu": ["@rollup/rollup-linux-loongarch64-gnu@4.36.0", "", { "os": "linux", "cpu": "none" }, "sha512-1ZPyEDWF8phd4FQtTzMh8FQwqzvIjLsl6/84gzUxnMNFBtExBtpL51H67mV9xipuxl1AEAerRBgBwFNpkw8+Lg=="], + "@rollup/rollup-linux-loongarch64-gnu": ["@rollup/rollup-linux-loongarch64-gnu@4.37.0", "", { "os": "linux", "cpu": "none" }, "sha512-yCE0NnutTC/7IGUq/PUHmoeZbIwq3KRh02e9SfFh7Vmc1Z7atuJRYWhRME5fKgT8aS20mwi1RyChA23qSyRGpA=="], - "@rollup/rollup-linux-powerpc64le-gnu": ["@rollup/rollup-linux-powerpc64le-gnu@4.36.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-VMPMEIUpPFKpPI9GZMhJrtu8rxnp6mJR3ZzQPykq4xc2GmdHj3Q4cA+7avMyegXy4n1v+Qynr9fR88BmyO74tg=="], + "@rollup/rollup-linux-powerpc64le-gnu": ["@rollup/rollup-linux-powerpc64le-gnu@4.37.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-NxcICptHk06E2Lh3a4Pu+2PEdZ6ahNHuK7o6Np9zcWkrBMuv21j10SQDJW3C9Yf/A/P7cutWoC/DptNLVsZ0VQ=="], - "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.36.0", "", { "os": "linux", "cpu": "none" }, "sha512-ttE6ayb/kHwNRJGYLpuAvB7SMtOeQnVXEIpMtAvx3kepFQeowVED0n1K9nAdraHUPJ5hydEMxBpIR7o4nrm8uA=="], + "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.37.0", "", { "os": "linux", "cpu": "none" }, "sha512-PpWwHMPCVpFZLTfLq7EWJWvrmEuLdGn1GMYcm5MV7PaRgwCEYJAwiN94uBuZev0/J/hFIIJCsYw4nLmXA9J7Pw=="], - "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.36.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-4a5gf2jpS0AIe7uBjxDeUMNcFmaRTbNv7NxI5xOCs4lhzsVyGR/0qBXduPnoWf6dGC365saTiwag8hP1imTgag=="], + "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.37.0", "", { "os": "linux", "cpu": "none" }, "sha512-DTNwl6a3CfhGTAOYZ4KtYbdS8b+275LSLqJVJIrPa5/JuIufWWZ/QFvkxp52gpmguN95eujrM68ZG+zVxa8zHA=="], - "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.36.0", "", { "os": "linux", "cpu": "x64" }, "sha512-5KtoW8UWmwFKQ96aQL3LlRXX16IMwyzMq/jSSVIIyAANiE1doaQsx/KRyhAvpHlPjPiSU/AYX/8m+lQ9VToxFQ=="], + "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.37.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-hZDDU5fgWvDdHFuExN1gBOhCuzo/8TMpidfOR+1cPZJflcEzXdCy1LjnklQdW8/Et9sryOPJAKAQRw8Jq7Tg+A=="], - "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.36.0", "", { "os": "linux", "cpu": "x64" }, "sha512-sycrYZPrv2ag4OCvaN5js+f01eoZ2U+RmT5as8vhxiFz+kxwlHrsxOwKPSA8WyS+Wc6Epid9QeI/IkQ9NkgYyQ=="], + "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.37.0", "", { "os": "linux", "cpu": "x64" }, "sha512-pKivGpgJM5g8dwj0ywBwe/HeVAUSuVVJhUTa/URXjxvoyTT/AxsLTAbkHkDHG7qQxLoW2s3apEIl26uUe08LVQ=="], - "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.36.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-qbqt4N7tokFwwSVlWDsjfoHgviS3n/vZ8LK0h1uLG9TYIRuUTJC88E1xb3LM2iqZ/WTqNQjYrtmtGmrmmawB6A=="], + "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.37.0", "", { "os": "linux", "cpu": "x64" }, "sha512-E2lPrLKE8sQbY/2bEkVTGDEk4/49UYRVWgj90MY8yPjpnGBQ+Xi1Qnr7b7UIWw1NOggdFQFOLZ8+5CzCiz143w=="], - "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.36.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-t+RY0JuRamIocMuQcfwYSOkmdX9dtkr1PbhKW42AMvaDQa+jOdpUYysroTF/nuPpAaQMWp7ye+ndlmmthieJrQ=="], + "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.37.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-Jm7biMazjNzTU4PrQtr7VS8ibeys9Pn29/1bm4ph7CP2kf21950LgN+BaE2mJ1QujnvOc6p54eWWiVvn05SOBg=="], - "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.36.0", "", { "os": "win32", "cpu": "x64" }, "sha512-aRXd7tRZkWLqGbChgcMMDEHjOKudo1kChb1Jt1IfR8cY/KIpgNviLeJy5FUb9IpSuQj8dU2fAYNMPW/hLKOSTw=="], + "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.37.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-e3/1SFm1OjefWICB2Ucstg2dxYDkDTZGDYgwufcbsxTHyqQps1UQf33dFEChBNmeSsTOyrjw2JJq0zbG5GF6RA=="], + + "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.37.0", "", { "os": "win32", "cpu": "x64" }, "sha512-LWbXUBwn/bcLx2sSsqy7pK5o+Nr+VCoRoAohfJ5C/aBio9nfJmGQqHAhU6pwxV/RmyTk5AqdySma7uwWGlmeuA=="], "@rtsao/scc": ["@rtsao/scc@1.1.0", "", {}, "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g=="], @@ -2010,7 +2038,7 @@ "@sigstore/verify": ["@sigstore/verify@1.2.1", "", { "dependencies": { "@sigstore/bundle": "^2.3.2", "@sigstore/core": "^1.1.0", "@sigstore/protobuf-specs": "^0.3.2" } }, "sha512-8iKx79/F73DKbGfRf7+t4dqrc0bRr0thdPrxAtCKWRm/F0tG71i6O1rvlnScncJLLBZHn3h8M3c1BSUAb9yu8g=="], - "@sinclair/typebox": ["@sinclair/typebox@0.32.35", "", {}, "sha512-Ul3YyOTU++to8cgNkttakC0dWvpERr6RYoHO2W47DLbFvrwBDJUY31B1sImH6JZSYc4Kt4PyHtoPNu+vL2r2dA=="], + "@sinclair/typebox": ["@sinclair/typebox@0.34.30", "", {}, "sha512-gFB3BiqjDxEoadW0zn+xyMVb7cLxPCoblVn2C/BKpI41WPYi2d6fwHAlynPNZ5O/Q4WEiujdnJzVtvG/Jc2CBQ=="], "@sindresorhus/is": ["@sindresorhus/is@4.6.0", "", {}, "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw=="], @@ -2018,75 +2046,75 @@ "@slorber/remark-comment": ["@slorber/remark-comment@1.0.0", "", { "dependencies": { "micromark-factory-space": "^1.0.0", "micromark-util-character": "^1.1.0", "micromark-util-symbol": "^1.0.1" } }, "sha512-RCE24n7jsOj1M0UPvIQCHTe7fI0sFL4S2nwKVWwHyVr/wI/H8GosgsJGyhnsZoGFnD/P2hLf1mSbrrgSLN93NA=="], - "@smithy/abort-controller": ["@smithy/abort-controller@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-fiUIYgIgRjMWznk6iLJz35K2YxSLHzLBA/RC6lBrKfQ8fHbPfvk7Pk9UvpKoHgJjI18MnbPuEju53zcVy6KF1g=="], + "@smithy/abort-controller": ["@smithy/abort-controller@4.0.2", "", { "dependencies": { "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Sl/78VDtgqKxN2+1qduaVE140XF+Xg+TafkncspwM4jFP/LHr76ZHmIY/y3V1M0mMLNk+Je6IGbzxy23RSToMw=="], "@smithy/chunked-blob-reader": ["@smithy/chunked-blob-reader@5.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-+sKqDBQqb036hh4NPaUiEkYFkTUGYzRsn3EuFhyfQfMy6oGHEUJDurLP9Ufb5dasr/XiAmPNMr6wa9afjQB+Gw=="], "@smithy/chunked-blob-reader-native": ["@smithy/chunked-blob-reader-native@4.0.0", "", { "dependencies": { "@smithy/util-base64": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-R9wM2yPmfEMsUmlMlIgSzOyICs0x9uu7UTHoccMyt7BWw8shcGM8HqB355+BZCPBcySvbTYMs62EgEQkNxz2ig=="], - "@smithy/config-resolver": ["@smithy/config-resolver@4.0.1", "", { "dependencies": { "@smithy/node-config-provider": "^4.0.1", "@smithy/types": "^4.1.0", "@smithy/util-config-provider": "^4.0.0", "@smithy/util-middleware": "^4.0.1", "tslib": "^2.6.2" } }, "sha512-Igfg8lKu3dRVkTSEm98QpZUvKEOa71jDX4vKRcvJVyRc3UgN3j7vFMf0s7xLQhYmKa8kyJGQgUJDOV5V3neVlQ=="], + "@smithy/config-resolver": ["@smithy/config-resolver@4.1.0", "", { "dependencies": { "@smithy/node-config-provider": "^4.0.2", "@smithy/types": "^4.2.0", "@smithy/util-config-provider": "^4.0.0", "@smithy/util-middleware": "^4.0.2", "tslib": "^2.6.2" } }, "sha512-8smPlwhga22pwl23fM5ew4T9vfLUCeFXlcqNOCD5M5h8VmNPNUE9j6bQSuRXpDSV11L/E/SwEBQuW8hr6+nS1A=="], - "@smithy/core": ["@smithy/core@3.1.5", "", { "dependencies": { "@smithy/middleware-serde": "^4.0.2", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-middleware": "^4.0.1", "@smithy/util-stream": "^4.1.2", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-HLclGWPkCsekQgsyzxLhCQLa8THWXtB5PxyYN+2O6nkyLt550KQKTlbV2D1/j5dNIQapAZM1+qFnpBFxZQkgCA=="], + "@smithy/core": ["@smithy/core@3.2.0", "", { "dependencies": { "@smithy/middleware-serde": "^4.0.3", "@smithy/protocol-http": "^5.1.0", "@smithy/types": "^4.2.0", "@smithy/util-body-length-browser": "^4.0.0", "@smithy/util-middleware": "^4.0.2", "@smithy/util-stream": "^4.2.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-k17bgQhVZ7YmUvA8at4af1TDpl0NDMBuBKJl8Yg0nrefwmValU+CnA5l/AriVdQNthU/33H3nK71HrLgqOPr1Q=="], - "@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.0.1", "", { "dependencies": { "@smithy/node-config-provider": "^4.0.1", "@smithy/property-provider": "^4.0.1", "@smithy/types": "^4.1.0", "@smithy/url-parser": "^4.0.1", "tslib": "^2.6.2" } }, "sha512-l/qdInaDq1Zpznpmev/+52QomsJNZ3JkTl5yrTl02V6NBgJOQ4LY0SFw/8zsMwj3tLe8vqiIuwF6nxaEwgf6mg=="], + "@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.0.2", "", { "dependencies": { "@smithy/node-config-provider": "^4.0.2", "@smithy/property-provider": "^4.0.2", "@smithy/types": "^4.2.0", "@smithy/url-parser": "^4.0.2", "tslib": "^2.6.2" } }, "sha512-32lVig6jCaWBHnY+OEQ6e6Vnt5vDHaLiydGrwYMW9tPqO688hPGTYRamYJ1EptxEC2rAwJrHWmPoKRBl4iTa8w=="], - "@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.0.1", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.1.0", "@smithy/util-hex-encoding": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-Q2bCAAR6zXNVtJgifsU16ZjKGqdw/DyecKNgIgi7dlqw04fqDu0mnq+JmGphqheypVc64CYq3azSuCpAdFk2+A=="], + "@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.0.2", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.2.0", "@smithy/util-hex-encoding": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-p+f2kLSK7ZrXVfskU/f5dzksKTewZk8pJLPvER3aFHPt76C2MxD9vNatSfLzzQSQB4FNO96RK4PSXfhD1TTeMQ=="], - "@smithy/eventstream-serde-browser": ["@smithy/eventstream-serde-browser@4.0.1", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-HbIybmz5rhNg+zxKiyVAnvdM3vkzjE6ccrJ620iPL8IXcJEntd3hnBl+ktMwIy12Te/kyrSbUb8UCdnUT4QEdA=="], + "@smithy/eventstream-serde-browser": ["@smithy/eventstream-serde-browser@4.0.2", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.0.2", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-CepZCDs2xgVUtH7ZZ7oDdZFH8e6Y2zOv8iiX6RhndH69nlojCALSKK+OXwZUgOtUZEUaZ5e1hULVCHYbCn7pug=="], - "@smithy/eventstream-serde-config-resolver": ["@smithy/eventstream-serde-config-resolver@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-lSipaiq3rmHguHa3QFF4YcCM3VJOrY9oq2sow3qlhFY+nBSTF/nrO82MUQRPrxHQXA58J5G1UnU2WuJfi465BA=="], + "@smithy/eventstream-serde-config-resolver": ["@smithy/eventstream-serde-config-resolver@4.1.0", "", { "dependencies": { "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-1PI+WPZ5TWXrfj3CIoKyUycYynYJgZjuQo8U+sphneOtjsgrttYybdqESFReQrdWJ+LKt6NEdbYzmmfDBmjX2A=="], - "@smithy/eventstream-serde-node": ["@smithy/eventstream-serde-node@4.0.1", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-o4CoOI6oYGYJ4zXo34U8X9szDe3oGjmHgsMGiZM0j4vtNoT+h80TLnkUcrLZR3+E6HIxqW+G+9WHAVfl0GXK0Q=="], + "@smithy/eventstream-serde-node": ["@smithy/eventstream-serde-node@4.0.2", "", { "dependencies": { "@smithy/eventstream-serde-universal": "^4.0.2", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-C5bJ/C6x9ENPMx2cFOirspnF9ZsBVnBMtP6BdPl/qYSuUawdGQ34Lq0dMcf42QTjUZgWGbUIZnz6+zLxJlb9aw=="], - "@smithy/eventstream-serde-universal": ["@smithy/eventstream-serde-universal@4.0.1", "", { "dependencies": { "@smithy/eventstream-codec": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-Z94uZp0tGJuxds3iEAZBqGU2QiaBHP4YytLUjwZWx+oUeohCsLyUm33yp4MMBmhkuPqSbQCXq5hDet6JGUgHWA=="], + "@smithy/eventstream-serde-universal": ["@smithy/eventstream-serde-universal@4.0.2", "", { "dependencies": { "@smithy/eventstream-codec": "^4.0.2", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-St8h9JqzvnbB52FtckiHPN4U/cnXcarMniXRXTKn0r4b4XesZOGiAyUdj1aXbqqn1icSqBlzzUsCl6nPB018ng=="], - "@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.0.1", "", { "dependencies": { "@smithy/protocol-http": "^5.0.1", "@smithy/querystring-builder": "^4.0.1", "@smithy/types": "^4.1.0", "@smithy/util-base64": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-3aS+fP28urrMW2KTjb6z9iFow6jO8n3MFfineGbndvzGZit3taZhKWtTorf+Gp5RpFDDafeHlhfsGlDCXvUnJA=="], + "@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.0.2", "", { "dependencies": { "@smithy/protocol-http": "^5.1.0", "@smithy/querystring-builder": "^4.0.2", "@smithy/types": "^4.2.0", "@smithy/util-base64": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-+9Dz8sakS9pe7f2cBocpJXdeVjMopUDLgZs1yWeu7h++WqSbjUYv/JAJwKwXw1HV6gq1jyWjxuyn24E2GhoEcQ=="], - "@smithy/hash-blob-browser": ["@smithy/hash-blob-browser@4.0.1", "", { "dependencies": { "@smithy/chunked-blob-reader": "^5.0.0", "@smithy/chunked-blob-reader-native": "^4.0.0", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-rkFIrQOKZGS6i1D3gKJ8skJ0RlXqDvb1IyAphksaFOMzkn3v3I1eJ8m7OkLj0jf1McP63rcCEoLlkAn/HjcTRw=="], + "@smithy/hash-blob-browser": ["@smithy/hash-blob-browser@4.0.2", "", { "dependencies": { "@smithy/chunked-blob-reader": "^5.0.0", "@smithy/chunked-blob-reader-native": "^4.0.0", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-3g188Z3DyhtzfBRxpZjU8R9PpOQuYsbNnyStc/ZVS+9nVX1f6XeNOa9IrAh35HwwIZg+XWk8bFVtNINVscBP+g=="], - "@smithy/hash-node": ["@smithy/hash-node@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-buffer-from": "^4.0.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-TJ6oZS+3r2Xu4emVse1YPB3Dq3d8RkZDKcPr71Nj/lJsdAP1c7oFzYqEn1IBc915TsgLl2xIJNuxCz+gLbLE0w=="], + "@smithy/hash-node": ["@smithy/hash-node@4.0.2", "", { "dependencies": { "@smithy/types": "^4.2.0", "@smithy/util-buffer-from": "^4.0.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-VnTpYPnRUE7yVhWozFdlxcYknv9UN7CeOqSrMH+V877v4oqtVYuoqhIhtSjmGPvYrYnAkaM61sLMKHvxL138yg=="], - "@smithy/hash-stream-node": ["@smithy/hash-stream-node@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-U1rAE1fxmReCIr6D2o/4ROqAQX+GffZpyMt3d7njtGDr2pUNmAKRWa49gsNVhCh2vVAuf3wXzWwNr2YN8PAXIw=="], + "@smithy/hash-stream-node": ["@smithy/hash-stream-node@4.0.2", "", { "dependencies": { "@smithy/types": "^4.2.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-POWDuTznzbIwlEXEvvXoPMS10y0WKXK790soe57tFRfvf4zBHyzE529HpZMqmDdwG9MfFflnyzndUQ8j78ZdSg=="], - "@smithy/invalid-dependency": ["@smithy/invalid-dependency@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-gdudFPf4QRQ5pzj7HEnu6FhKRi61BfH/Gk5Yf6O0KiSbr1LlVhgjThcvjdu658VE6Nve8vaIWB8/fodmS1rBPQ=="], + "@smithy/invalid-dependency": ["@smithy/invalid-dependency@4.0.2", "", { "dependencies": { "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GatB4+2DTpgWPday+mnUkoumP54u/MDM/5u44KF9hIu8jF0uafZtQLcdfIKkIcUNuF/fBojpLEHZS/56JqPeXQ=="], "@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-saYhF8ZZNoJDTvJBEWgeBccCg+yvp1CX+ed12yORU3NilJScfc6gfch2oVb4QgxZrGUx3/ZJlb+c/dJbyupxlw=="], - "@smithy/md5-js": ["@smithy/md5-js@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-HLZ647L27APi6zXkZlzSFZIjpo8po45YiyjMGJZM3gyDY8n7dPGdmxIIljLm4gPt/7rRvutLTTkYJpZVfG5r+A=="], + "@smithy/md5-js": ["@smithy/md5-js@4.0.2", "", { "dependencies": { "@smithy/types": "^4.2.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-Hc0R8EiuVunUewCse2syVgA2AfSRco3LyAv07B/zCOMa+jpXI9ll+Q21Nc6FAlYPcpNcAXqBzMhNs1CD/pP2bA=="], - "@smithy/middleware-content-length": ["@smithy/middleware-content-length@4.0.1", "", { "dependencies": { "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-OGXo7w5EkB5pPiac7KNzVtfCW2vKBTZNuCctn++TTSOMpe6RZO/n6WEC1AxJINn3+vWLKW49uad3lo/u0WJ9oQ=="], + "@smithy/middleware-content-length": ["@smithy/middleware-content-length@4.0.2", "", { "dependencies": { "@smithy/protocol-http": "^5.1.0", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-hAfEXm1zU+ELvucxqQ7I8SszwQ4znWMbNv6PLMndN83JJN41EPuS93AIyh2N+gJ6x8QFhzSO6b7q2e6oClDI8A=="], - "@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.0.6", "", { "dependencies": { "@smithy/core": "^3.1.5", "@smithy/middleware-serde": "^4.0.2", "@smithy/node-config-provider": "^4.0.1", "@smithy/shared-ini-file-loader": "^4.0.1", "@smithy/types": "^4.1.0", "@smithy/url-parser": "^4.0.1", "@smithy/util-middleware": "^4.0.1", "tslib": "^2.6.2" } }, "sha512-ftpmkTHIFqgaFugcjzLZv3kzPEFsBFSnq1JsIkr2mwFzCraZVhQk2gqN51OOeRxqhbPTkRFj39Qd2V91E/mQxg=="], + "@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.1.0", "", { "dependencies": { "@smithy/core": "^3.2.0", "@smithy/middleware-serde": "^4.0.3", "@smithy/node-config-provider": "^4.0.2", "@smithy/shared-ini-file-loader": "^4.0.2", "@smithy/types": "^4.2.0", "@smithy/url-parser": "^4.0.2", "@smithy/util-middleware": "^4.0.2", "tslib": "^2.6.2" } }, "sha512-xhLimgNCbCzsUppRTGXWkZywksuTThxaIB0HwbpsVLY5sceac4e1TZ/WKYqufQLaUy+gUSJGNdwD2jo3cXL0iA=="], - "@smithy/middleware-retry": ["@smithy/middleware-retry@4.0.7", "", { "dependencies": { "@smithy/node-config-provider": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/service-error-classification": "^4.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "@smithy/util-middleware": "^4.0.1", "@smithy/util-retry": "^4.0.1", "tslib": "^2.6.2", "uuid": "^9.0.1" } }, "sha512-58j9XbUPLkqAcV1kHzVX/kAR16GT+j7DUZJqwzsxh1jtz7G82caZiGyyFgUvogVfNTg3TeAOIJepGc8TXF4AVQ=="], + "@smithy/middleware-retry": ["@smithy/middleware-retry@4.1.0", "", { "dependencies": { "@smithy/node-config-provider": "^4.0.2", "@smithy/protocol-http": "^5.1.0", "@smithy/service-error-classification": "^4.0.2", "@smithy/smithy-client": "^4.2.0", "@smithy/types": "^4.2.0", "@smithy/util-middleware": "^4.0.2", "@smithy/util-retry": "^4.0.2", "tslib": "^2.6.2", "uuid": "^9.0.1" } }, "sha512-2zAagd1s6hAaI/ap6SXi5T3dDwBOczOMCSkkYzktqN1+tzbk1GAsHNAdo/1uzxz3Ky02jvZQwbi/vmDA6z4Oyg=="], - "@smithy/middleware-serde": ["@smithy/middleware-serde@4.0.2", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-Sdr5lOagCn5tt+zKsaW+U2/iwr6bI9p08wOkCp6/eL6iMbgdtc2R5Ety66rf87PeohR0ExI84Txz9GYv5ou3iQ=="], + "@smithy/middleware-serde": ["@smithy/middleware-serde@4.0.3", "", { "dependencies": { "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-rfgDVrgLEVMmMn0BI8O+8OVr6vXzjV7HZj57l0QxslhzbvVfikZbVfBVthjLHqib4BW44QhcIgJpvebHlRaC9A=="], - "@smithy/middleware-stack": ["@smithy/middleware-stack@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-dHwDmrtR/ln8UTHpaIavRSzeIk5+YZTBtLnKwDW3G2t6nAupCiQUvNzNoHBpik63fwUaJPtlnMzXbQrNFWssIA=="], + "@smithy/middleware-stack": ["@smithy/middleware-stack@4.0.2", "", { "dependencies": { "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-eSPVcuJJGVYrFYu2hEq8g8WWdJav3sdrI4o2c6z/rjnYDd3xH9j9E7deZQCzFn4QvGPouLngH3dQ+QVTxv5bOQ=="], - "@smithy/node-config-provider": ["@smithy/node-config-provider@4.0.1", "", { "dependencies": { "@smithy/property-provider": "^4.0.1", "@smithy/shared-ini-file-loader": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-8mRTjvCtVET8+rxvmzRNRR0hH2JjV0DFOmwXPrISmTIJEfnCBugpYYGAsCj8t41qd+RB5gbheSQ/6aKZCQvFLQ=="], + "@smithy/node-config-provider": ["@smithy/node-config-provider@4.0.2", "", { "dependencies": { "@smithy/property-provider": "^4.0.2", "@smithy/shared-ini-file-loader": "^4.0.2", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-WgCkILRZfJwJ4Da92a6t3ozN/zcvYyJGUTmfGbgS/FkCcoCjl7G4FJaCDN1ySdvLvemnQeo25FdkyMSTSwulsw=="], - "@smithy/node-http-handler": ["@smithy/node-http-handler@4.0.3", "", { "dependencies": { "@smithy/abort-controller": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/querystring-builder": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-dYCLeINNbYdvmMLtW0VdhW1biXt+PPCGazzT5ZjKw46mOtdgToQEwjqZSS9/EN8+tNs/RO0cEWG044+YZs97aA=="], + "@smithy/node-http-handler": ["@smithy/node-http-handler@4.0.4", "", { "dependencies": { "@smithy/abort-controller": "^4.0.2", "@smithy/protocol-http": "^5.1.0", "@smithy/querystring-builder": "^4.0.2", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-/mdqabuAT3o/ihBGjL94PUbTSPSRJ0eeVTdgADzow0wRJ0rN4A27EOrtlK56MYiO1fDvlO3jVTCxQtQmK9dZ1g=="], - "@smithy/property-provider": ["@smithy/property-provider@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-o+VRiwC2cgmk/WFV0jaETGOtX16VNPp2bSQEzu0whbReqE1BMqsP2ami2Vi3cbGVdKu1kq9gQkDAGKbt0WOHAQ=="], + "@smithy/property-provider": ["@smithy/property-provider@4.0.2", "", { "dependencies": { "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-wNRoQC1uISOuNc2s4hkOYwYllmiyrvVXWMtq+TysNRVQaHm4yoafYQyjN/goYZS+QbYlPIbb/QRjaUZMuzwQ7A=="], - "@smithy/protocol-http": ["@smithy/protocol-http@5.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-TE4cpj49jJNB/oHyh/cRVEgNZaoPaxd4vteJNB0yGidOCVR0jCw/hjPVsT8Q8FRmj8Bd3bFZt8Dh7xGCT+xMBQ=="], + "@smithy/protocol-http": ["@smithy/protocol-http@5.1.0", "", { "dependencies": { "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-KxAOL1nUNw2JTYrtviRRjEnykIDhxc84qMBzxvu1MUfQfHTuBlCG7PA6EdVwqpJjH7glw7FqQoFxUJSyBQgu7g=="], - "@smithy/querystring-builder": ["@smithy/querystring-builder@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg=="], + "@smithy/querystring-builder": ["@smithy/querystring-builder@4.0.2", "", { "dependencies": { "@smithy/types": "^4.2.0", "@smithy/util-uri-escape": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-NTOs0FwHw1vimmQM4ebh+wFQvOwkEf/kQL6bSM1Lock+Bv4I89B3hGYoUEPkmvYPkDKyp5UdXJYu+PoTQ3T31Q=="], - "@smithy/querystring-parser": ["@smithy/querystring-parser@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-Ma2XC7VS9aV77+clSFylVUnPZRindhB7BbmYiNOdr+CHt/kZNJoPP0cd3QxCnCFyPXC4eybmyE98phEHkqZ5Jw=="], + "@smithy/querystring-parser": ["@smithy/querystring-parser@4.0.2", "", { "dependencies": { "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-v6w8wnmZcVXjfVLjxw8qF7OwESD9wnpjp0Dqry/Pod0/5vcEA3qxCr+BhbOHlxS8O+29eLpT3aagxXGwIoEk7Q=="], - "@smithy/service-error-classification": ["@smithy/service-error-classification@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0" } }, "sha512-3JNjBfOWpj/mYfjXJHB4Txc/7E4LVq32bwzE7m28GN79+M1f76XHflUaSUkhOriprPDzev9cX/M+dEB80DNDKA=="], + "@smithy/service-error-classification": ["@smithy/service-error-classification@4.0.2", "", { "dependencies": { "@smithy/types": "^4.2.0" } }, "sha512-LA86xeFpTKn270Hbkixqs5n73S+LVM0/VZco8dqd+JT75Dyx3Lcw/MraL7ybjmz786+160K8rPOmhsq0SocoJQ=="], - "@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-hC8F6qTBbuHRI/uqDgqqi6J0R4GtEZcgrZPhFQnMhfJs3MnUTGSnR1NSJCJs5VWlMydu0kJz15M640fJlRsIOw=="], + "@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.0.2", "", { "dependencies": { "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-J9/gTWBGVuFZ01oVA6vdb4DAjf1XbDhK6sLsu3OS9qmLrS6KB5ygpeHiM3miIbj1qgSJ96GYszXFWv6ErJ8QEw=="], - "@smithy/signature-v4": ["@smithy/signature-v4@5.0.1", "", { "dependencies": { "@smithy/is-array-buffer": "^4.0.0", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "@smithy/util-hex-encoding": "^4.0.0", "@smithy/util-middleware": "^4.0.1", "@smithy/util-uri-escape": "^4.0.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-nCe6fQ+ppm1bQuw5iKoeJ0MJfz2os7Ic3GBjOkLOPtavbD1ONoyE3ygjBfz2ythFWm4YnRm6OxW+8p/m9uCoIA=="], + "@smithy/signature-v4": ["@smithy/signature-v4@5.0.2", "", { "dependencies": { "@smithy/is-array-buffer": "^4.0.0", "@smithy/protocol-http": "^5.1.0", "@smithy/types": "^4.2.0", "@smithy/util-hex-encoding": "^4.0.0", "@smithy/util-middleware": "^4.0.2", "@smithy/util-uri-escape": "^4.0.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-Mz+mc7okA73Lyz8zQKJNyr7lIcHLiPYp0+oiqiMNc/t7/Kf2BENs5d63pEj7oPqdjaum6g0Fc8wC78dY1TgtXw=="], - "@smithy/smithy-client": ["@smithy/smithy-client@4.1.6", "", { "dependencies": { "@smithy/core": "^3.1.5", "@smithy/middleware-endpoint": "^4.0.6", "@smithy/middleware-stack": "^4.0.1", "@smithy/protocol-http": "^5.0.1", "@smithy/types": "^4.1.0", "@smithy/util-stream": "^4.1.2", "tslib": "^2.6.2" } }, "sha512-UYDolNg6h2O0L+cJjtgSyKKvEKCOa/8FHYJnBobyeoeWDmNpXjwOAtw16ezyeu1ETuuLEOZbrynK0ZY1Lx9Jbw=="], + "@smithy/smithy-client": ["@smithy/smithy-client@4.2.0", "", { "dependencies": { "@smithy/core": "^3.2.0", "@smithy/middleware-endpoint": "^4.1.0", "@smithy/middleware-stack": "^4.0.2", "@smithy/protocol-http": "^5.1.0", "@smithy/types": "^4.2.0", "@smithy/util-stream": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Qs65/w30pWV7LSFAez9DKy0Koaoh3iHhpcpCCJ4waj/iqwsuSzJna2+vYwq46yBaqO5ZbP9TjUsATUNxrKeBdw=="], - "@smithy/types": ["@smithy/types@4.1.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-enhjdwp4D7CXmwLtD6zbcDMbo6/T6WtuuKCY49Xxc6OMOmUWlBEBDREsxxgV2LIdeQPW756+f97GzcgAwp3iLw=="], + "@smithy/types": ["@smithy/types@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-7eMk09zQKCO+E/ivsjQv+fDlOupcFUCSC/L2YUPgwhvowVGWbPQHjEFcmjt7QQ4ra5lyowS92SV53Zc6XD4+fg=="], - "@smithy/url-parser": ["@smithy/url-parser@4.0.1", "", { "dependencies": { "@smithy/querystring-parser": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-gPXcIEUtw7VlK8f/QcruNXm7q+T5hhvGu9tl63LsJPZ27exB6dtNwvh2HIi0v7JcXJ5emBxB+CJxwaLEdJfA+g=="], + "@smithy/url-parser": ["@smithy/url-parser@4.0.2", "", { "dependencies": { "@smithy/querystring-parser": "^4.0.2", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Bm8n3j2ScqnT+kJaClSVCMeiSenK6jVAzZCNewsYWuZtnBehEz4r2qP0riZySZVfzB+03XZHJeqfmJDkeeSLiQ=="], "@smithy/util-base64": ["@smithy/util-base64@4.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.0.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-CvHfCmO2mchox9kjrtzoHkWHxjHZzaFojLc8quxXY7WAAMAg43nuxwv95tATVgQFNDwd4M9S1qFzj40Ul41Kmg=="], @@ -2098,25 +2126,25 @@ "@smithy/util-config-provider": ["@smithy/util-config-provider@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-L1RBVzLyfE8OXH+1hsJ8p+acNUSirQnWQ6/EgpchV88G6zGBTDPdXiiExei6Z1wR2RxYvxY/XLw6AMNCCt8H3w=="], - "@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.0.7", "", { "dependencies": { "@smithy/property-provider": "^4.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-CZgDDrYHLv0RUElOsmZtAnp1pIjwDVCSuZWOPhIOBvG36RDfX1Q9+6lS61xBf+qqvHoqRjHxgINeQz47cYFC2Q=="], + "@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.0.8", "", { "dependencies": { "@smithy/property-provider": "^4.0.2", "@smithy/smithy-client": "^4.2.0", "@smithy/types": "^4.2.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-ZTypzBra+lI/LfTYZeop9UjoJhhGRTg3pxrNpfSTQLd3AJ37r2z4AXTKpq1rFXiiUIJsYyFgNJdjWRGP/cbBaQ=="], - "@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.0.7", "", { "dependencies": { "@smithy/config-resolver": "^4.0.1", "@smithy/credential-provider-imds": "^4.0.1", "@smithy/node-config-provider": "^4.0.1", "@smithy/property-provider": "^4.0.1", "@smithy/smithy-client": "^4.1.6", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-79fQW3hnfCdrfIi1soPbK3zmooRFnLpSx3Vxi6nUlqaaQeC5dm8plt4OTNDNqEEEDkvKghZSaoti684dQFVrGQ=="], + "@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.0.8", "", { "dependencies": { "@smithy/config-resolver": "^4.1.0", "@smithy/credential-provider-imds": "^4.0.2", "@smithy/node-config-provider": "^4.0.2", "@smithy/property-provider": "^4.0.2", "@smithy/smithy-client": "^4.2.0", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Rgk0Jc/UDfRTzVthye/k2dDsz5Xxs9LZaKCNPgJTRyoyBoeiNCnHsYGOyu1PKN+sDyPnJzMOz22JbwxzBp9NNA=="], - "@smithy/util-endpoints": ["@smithy/util-endpoints@3.0.1", "", { "dependencies": { "@smithy/node-config-provider": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-zVdUENQpdtn9jbpD9SCFK4+aSiavRb9BxEtw9ZGUR1TYo6bBHbIoi7VkrFQ0/RwZlzx0wRBaRmPclj8iAoJCLA=="], + "@smithy/util-endpoints": ["@smithy/util-endpoints@3.0.2", "", { "dependencies": { "@smithy/node-config-provider": "^4.0.2", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-6QSutU5ZyrpNbnd51zRTL7goojlcnuOB55+F9VBD+j8JpRY50IGamsjlycrmpn8PQkmJucFW8A0LSfXj7jjtLQ=="], "@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-Yk5mLhHtfIgW2W2WQZWSg5kuMZCVbvhFmC7rV4IO2QqnZdbEFPmQnCcGMAX2z/8Qj3B9hYYNjZOhWym+RwhePw=="], - "@smithy/util-middleware": ["@smithy/util-middleware@4.0.1", "", { "dependencies": { "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-HiLAvlcqhbzhuiOa0Lyct5IIlyIz0PQO5dnMlmQ/ubYM46dPInB+3yQGkfxsk6Q24Y0n3/JmcA1v5iEhmOF5mA=="], + "@smithy/util-middleware": ["@smithy/util-middleware@4.0.2", "", { "dependencies": { "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-6GDamTGLuBQVAEuQ4yDQ+ti/YINf/MEmIegrEeg7DdB/sld8BX1lqt9RRuIcABOhAGTA50bRbPzErez7SlDtDQ=="], - "@smithy/util-retry": ["@smithy/util-retry@4.0.1", "", { "dependencies": { "@smithy/service-error-classification": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-WmRHqNVwn3kI3rKk1LsKcVgPBG6iLTBGC1iYOV3GQegwJ3E8yjzHytPt26VNzOWr1qu0xE03nK0Ug8S7T7oufw=="], + "@smithy/util-retry": ["@smithy/util-retry@4.0.2", "", { "dependencies": { "@smithy/service-error-classification": "^4.0.2", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Qryc+QG+7BCpvjloFLQrmlSd0RsVRHejRXd78jNO3+oREueCjwG1CCEH1vduw/ZkM1U9TztwIKVIi3+8MJScGg=="], - "@smithy/util-stream": ["@smithy/util-stream@4.1.2", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.0.1", "@smithy/node-http-handler": "^4.0.3", "@smithy/types": "^4.1.0", "@smithy/util-base64": "^4.0.0", "@smithy/util-buffer-from": "^4.0.0", "@smithy/util-hex-encoding": "^4.0.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-44PKEqQ303d3rlQuiDpcCcu//hV8sn+u2JBo84dWCE0rvgeiVl0IlLMagbU++o0jCWhYCsHaAt9wZuZqNe05Hw=="], + "@smithy/util-stream": ["@smithy/util-stream@4.2.0", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.0.2", "@smithy/node-http-handler": "^4.0.4", "@smithy/types": "^4.2.0", "@smithy/util-base64": "^4.0.0", "@smithy/util-buffer-from": "^4.0.0", "@smithy/util-hex-encoding": "^4.0.0", "@smithy/util-utf8": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-Vj1TtwWnuWqdgQI6YTUF5hQ/0jmFiOYsc51CSMgj7QfyO+RF4EnT2HNjoviNlOOmgzgvf3f5yno+EiC4vrnaWQ=="], "@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.0.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-77yfbCbQMtgtTylO9itEAdpPXSog3ZxMe09AEhm0dU0NLTalV70ghDZFR+Nfi1C60jnJoh/Re4090/DuZh2Omg=="], "@smithy/util-utf8": ["@smithy/util-utf8@4.0.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.0.0", "tslib": "^2.6.2" } }, "sha512-b+zebfKCfRdgNJDknHCob3O7FpeYQN6ZG6YLExMcasDHsCXlsXCEuiPZeLnJLpwa5dvPetGlnGCiMHuLwGvFow=="], - "@smithy/util-waiter": ["@smithy/util-waiter@4.0.2", "", { "dependencies": { "@smithy/abort-controller": "^4.0.1", "@smithy/types": "^4.1.0", "tslib": "^2.6.2" } }, "sha512-piUTHyp2Axx3p/kc2CIJkYSv0BAaheBQmbACZgQSSfWUumWNW+R1lL+H9PDBxKJkvOeEX+hKYEFiwO8xagL8AQ=="], + "@smithy/util-waiter": ["@smithy/util-waiter@4.0.3", "", { "dependencies": { "@smithy/abort-controller": "^4.0.2", "@smithy/types": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-JtaY3FxmD+te+KSI2FJuEcfNC9T/DGGVf551babM7fAaXhjJUt7oSYurH1Devxd2+BOSUACCgt3buinx4UnmEA=="], "@socket.io/component-emitter": ["@socket.io/component-emitter@3.1.2", "", {}, "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA=="], @@ -2178,33 +2206,33 @@ "@svgr/webpack": ["@svgr/webpack@8.1.0", "", { "dependencies": { "@babel/core": "^7.21.3", "@babel/plugin-transform-react-constant-elements": "^7.21.3", "@babel/preset-env": "^7.20.2", "@babel/preset-react": "^7.18.6", "@babel/preset-typescript": "^7.21.0", "@svgr/core": "8.1.0", "@svgr/plugin-jsx": "8.1.0", "@svgr/plugin-svgo": "8.1.0" } }, "sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA=="], - "@swc/core": ["@swc/core@1.11.11", "", { "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.19" }, "optionalDependencies": { "@swc/core-darwin-arm64": "1.11.11", "@swc/core-darwin-x64": "1.11.11", "@swc/core-linux-arm-gnueabihf": "1.11.11", "@swc/core-linux-arm64-gnu": "1.11.11", "@swc/core-linux-arm64-musl": "1.11.11", "@swc/core-linux-x64-gnu": "1.11.11", "@swc/core-linux-x64-musl": "1.11.11", "@swc/core-win32-arm64-msvc": "1.11.11", "@swc/core-win32-ia32-msvc": "1.11.11", "@swc/core-win32-x64-msvc": "1.11.11" }, "peerDependencies": { "@swc/helpers": "*" }, "optionalPeers": ["@swc/helpers"] }, "sha512-pCVY2Wn6dV/labNvssk9b3Owi4WOYsapcbWm90XkIj4xH/56Z6gzja9fsU+4MdPuEfC2Smw835nZHcdCFGyX6A=="], + "@swc/core": ["@swc/core@1.11.13", "", { "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.19" }, "optionalDependencies": { "@swc/core-darwin-arm64": "1.11.13", "@swc/core-darwin-x64": "1.11.13", "@swc/core-linux-arm-gnueabihf": "1.11.13", "@swc/core-linux-arm64-gnu": "1.11.13", "@swc/core-linux-arm64-musl": "1.11.13", "@swc/core-linux-x64-gnu": "1.11.13", "@swc/core-linux-x64-musl": "1.11.13", "@swc/core-win32-arm64-msvc": "1.11.13", "@swc/core-win32-ia32-msvc": "1.11.13", "@swc/core-win32-x64-msvc": "1.11.13" }, "peerDependencies": { "@swc/helpers": "*" }, "optionalPeers": ["@swc/helpers"] }, "sha512-9BXdYz12Wl0zWmZ80PvtjBWeg2ncwJ9L5WJzjhN6yUTZWEV/AwAdVdJnIEp4pro3WyKmAaMxcVOSbhuuOZco5g=="], - "@swc/core-darwin-arm64": ["@swc/core-darwin-arm64@1.11.11", "", { "os": "darwin", "cpu": "arm64" }, "sha512-vJcjGVDB8cZH7zyOkC0AfpFYI/7GHKG0NSsH3tpuKrmoAXJyCYspKPGid7FT53EAlWreN7+Pew+bukYf5j+Fmg=="], + "@swc/core-darwin-arm64": ["@swc/core-darwin-arm64@1.11.13", "", { "os": "darwin", "cpu": "arm64" }, "sha512-loSERhLaQ9XDS+5Kdx8cLe2tM1G0HLit8MfehipAcsdctpo79zrRlkW34elOf3tQoVPKUItV0b/rTuhjj8NtHg=="], - "@swc/core-darwin-x64": ["@swc/core-darwin-x64@1.11.11", "", { "os": "darwin", "cpu": "x64" }, "sha512-/N4dGdqEYvD48mCF3QBSycAbbQd3yoZ2YHSzYesQf8usNc2YpIhYqEH3sql02UsxTjEFOJSf1bxZABDdhbSl6A=="], + "@swc/core-darwin-x64": ["@swc/core-darwin-x64@1.11.13", "", { "os": "darwin", "cpu": "x64" }, "sha512-uSA4UwgsDCIysUPfPS8OrQTH2h9spO7IYFd+1NB6dJlVGUuR6jLKuMBOP1IeLeax4cGHayvkcwSJ3OvxHwgcZQ=="], - "@swc/core-linux-arm-gnueabihf": ["@swc/core-linux-arm-gnueabihf@1.11.11", "", { "os": "linux", "cpu": "arm" }, "sha512-hsBhKK+wVXdN3x9MrL5GW0yT8o9GxteE5zHAI2HJjRQel3HtW7m5Nvwaq+q8rwMf4YQRd8ydbvwl4iUOZx7i2Q=="], + "@swc/core-linux-arm-gnueabihf": ["@swc/core-linux-arm-gnueabihf@1.11.13", "", { "os": "linux", "cpu": "arm" }, "sha512-boVtyJzS8g30iQfe8Q46W5QE/cmhKRln/7NMz/5sBP/am2Lce9NL0d05NnFwEWJp1e2AMGHFOdRr3Xg1cDiPKw=="], - "@swc/core-linux-arm64-gnu": ["@swc/core-linux-arm64-gnu@1.11.11", "", { "os": "linux", "cpu": "arm64" }, "sha512-YOCdxsqbnn/HMPCNM6nrXUpSndLXMUssGTtzT7ffXqr7WuzRg2e170FVDVQFIkb08E7Ku5uOnnUVAChAJQbMOQ=="], + "@swc/core-linux-arm64-gnu": ["@swc/core-linux-arm64-gnu@1.11.13", "", { "os": "linux", "cpu": "arm64" }, "sha512-+IK0jZ84zHUaKtwpV+T+wT0qIUBnK9v2xXD03vARubKF+eUqCsIvcVHXmLpFuap62dClMrhCiwW10X3RbXNlHw=="], - "@swc/core-linux-arm64-musl": ["@swc/core-linux-arm64-musl@1.11.11", "", { "os": "linux", "cpu": "arm64" }, "sha512-nR2tfdQRRzwqR2XYw9NnBk9Fdvff/b8IiJzDL28gRR2QiJWLaE8LsRovtWrzCOYq6o5Uu9cJ3WbabWthLo4jLw=="], + "@swc/core-linux-arm64-musl": ["@swc/core-linux-arm64-musl@1.11.13", "", { "os": "linux", "cpu": "arm64" }, "sha512-+ukuB8RHD5BHPCUjQwuLP98z+VRfu+NkKQVBcLJGgp0/+w7y0IkaxLY/aKmrAS5ofCNEGqKL+AOVyRpX1aw+XA=="], - "@swc/core-linux-x64-gnu": ["@swc/core-linux-x64-gnu@1.11.11", "", { "os": "linux", "cpu": "x64" }, "sha512-b4gBp5HA9xNWNC5gsYbdzGBJWx4vKSGybGMGOVWWuF+ynx10+0sA/o4XJGuNHm8TEDuNh9YLKf6QkIO8+GPJ1g=="], + "@swc/core-linux-x64-gnu": ["@swc/core-linux-x64-gnu@1.11.13", "", { "os": "linux", "cpu": "x64" }, "sha512-q9H3WI3U3dfJ34tdv60zc8oTuWvSd5fOxytyAO9Pc5M82Hic3jjWaf2xBekUg07ubnMZpyfnv+MlD+EbUI3Llw=="], - "@swc/core-linux-x64-musl": ["@swc/core-linux-x64-musl@1.11.11", "", { "os": "linux", "cpu": "x64" }, "sha512-dEvqmQVswjNvMBwXNb8q5uSvhWrJLdttBSef3s6UC5oDSwOr00t3RQPzyS3n5qmGJ8UMTdPRmsopxmqaODISdg=="], + "@swc/core-linux-x64-musl": ["@swc/core-linux-x64-musl@1.11.13", "", { "os": "linux", "cpu": "x64" }, "sha512-9aaZnnq2pLdTbAzTSzy/q8dr7Woy3aYIcQISmw1+Q2/xHJg5y80ZzbWSWKYca/hKonDMjIbGR6dp299I5J0aeA=="], - "@swc/core-win32-arm64-msvc": ["@swc/core-win32-arm64-msvc@1.11.11", "", { "os": "win32", "cpu": "arm64" }, "sha512-aZNZznem9WRnw2FbTqVpnclvl8Q2apOBW2B316gZK+qxbe+ktjOUnYaMhdCG3+BYggyIBDOnaJeQrXbKIMmNdw=="], + "@swc/core-win32-arm64-msvc": ["@swc/core-win32-arm64-msvc@1.11.13", "", { "os": "win32", "cpu": "arm64" }, "sha512-n3QZmDewkHANcoHvtwvA6yJbmS4XJf0MBMmwLZoKDZ2dOnC9D/jHiXw7JOohEuzYcpLoL5tgbqmjxa3XNo9Oow=="], - "@swc/core-win32-ia32-msvc": ["@swc/core-win32-ia32-msvc@1.11.11", "", { "os": "win32", "cpu": "ia32" }, "sha512-DjeJn/IfjgOddmJ8IBbWuDK53Fqw7UvOz7kyI/728CSdDYC3LXigzj3ZYs4VvyeOt+ZcQZUB2HA27edOifomGw=="], + "@swc/core-win32-ia32-msvc": ["@swc/core-win32-ia32-msvc@1.11.13", "", { "os": "win32", "cpu": "ia32" }, "sha512-wM+Nt4lc6YSJFthCx3W2dz0EwFNf++j0/2TQ0Js9QLJuIxUQAgukhNDVCDdq8TNcT0zuA399ALYbvj5lfIqG6g=="], - "@swc/core-win32-x64-msvc": ["@swc/core-win32-x64-msvc@1.11.11", "", { "os": "win32", "cpu": "x64" }, "sha512-Gp/SLoeMtsU4n0uRoKDOlGrRC6wCfifq7bqLwSlAG8u8MyJYJCcwjg7ggm0rhLdC2vbiZ+lLVl3kkETp+JUvKg=="], + "@swc/core-win32-x64-msvc": ["@swc/core-win32-x64-msvc@1.11.13", "", { "os": "win32", "cpu": "x64" }, "sha512-+X5/uW3s1L5gK7wAo0E27YaAoidJDo51dnfKSfU7gF3mlEUuWH8H1bAy5OTt2mU4eXtfsdUMEVXSwhDlLtQkuA=="], "@swc/counter": ["@swc/counter@0.1.3", "", {}, "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ=="], "@swc/helpers": ["@swc/helpers@0.5.15", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g=="], - "@swc/types": ["@swc/types@0.1.19", "", { "dependencies": { "@swc/counter": "^0.1.3" } }, "sha512-WkAZaAfj44kh/UFdAQcrMP1I0nwRqpt27u+08LMBYMqmQfwwMofYoMh/48NGkMMRfC4ynpfwRbJuu8ErfNloeA=="], + "@swc/types": ["@swc/types@0.1.20", "", { "dependencies": { "@swc/counter": "^0.1.3" } }, "sha512-/rlIpxwKrhz4BIplXf6nsEHtqlhzuNN34/k3kMAXH4/lvVoA3cdq+60aqVNnyvw2uITEaCi0WV3pxBe4dQqoXQ=="], "@szmarczak/http-timer": ["@szmarczak/http-timer@5.0.1", "", { "dependencies": { "defer-to-connect": "^2.0.1" } }, "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw=="], @@ -2266,9 +2294,7 @@ "@tybys/wasm-util": ["@tybys/wasm-util@0.9.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw=="], - "@types/acorn": ["@types/acorn@4.0.6", "", { "dependencies": { "@types/estree": "*" } }, "sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ=="], - - "@types/aws-lambda": ["@types/aws-lambda@8.10.147", "", {}, "sha512-nD0Z9fNIZcxYX5Mai2CTmFD7wX7UldCkW2ezCF8D1T5hdiLsnTWDGRpfRYntU6VjTdLQjOvyszru7I1c1oCQew=="], + "@types/aws-lambda": ["@types/aws-lambda@8.10.148", "", {}, "sha512-JL+2cfkY9ODQeE06hOxSFNkafjNk4JRBgY837kpoq1GHDttq2U3BA9IzKOWxS4DLjKoymGB4i9uBrlCkjUl1yg=="], "@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="], @@ -2276,7 +2302,7 @@ "@types/babel__template": ["@types/babel__template@7.4.4", "", { "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" } }, "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A=="], - "@types/babel__traverse": ["@types/babel__traverse@7.20.6", "", { "dependencies": { "@babel/types": "^7.20.7" } }, "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg=="], + "@types/babel__traverse": ["@types/babel__traverse@7.20.7", "", { "dependencies": { "@babel/types": "^7.20.7" } }, "sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng=="], "@types/body-parser": ["@types/body-parser@1.19.5", "", { "dependencies": { "@types/connect": "*", "@types/node": "*" } }, "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg=="], @@ -2284,7 +2310,7 @@ "@types/boom": ["@types/boom@7.3.5", "", {}, "sha512-jBS0kU2s9W2sx+ILEyO4kxqIYLllqcUXTaVrBctvGptZ+4X3TWkkgY9+AmxdMPKrgiDDdLcfsaQCTu7bniLvgw=="], - "@types/bun": ["@types/bun@1.2.5", "", { "dependencies": { "bun-types": "1.2.5" } }, "sha512-w2OZTzrZTVtbnJew1pdFmgV99H0/L+Pvw+z1P67HaR18MHOzYnTYOi6qzErhK8HyT+DB782ADVPPE92Xu2/Opg=="], + "@types/bun": ["@types/bun@1.2.6", "", { "dependencies": { "bun-types": "1.2.6" } }, "sha512-fY9CAmTdJH1Llx7rugB0FpgWK2RKuHCs3g2cFDYXUutIy1QGiPQxKkGY8owhfZ4MXWNfxwIbQLChgH5gDsY7vw=="], "@types/catbox": ["@types/catbox@10.0.9", "", {}, "sha512-4qXm1SmZurBMNFc/536+7gfbOlN43fWyoo4O0bdLqtpDK/cpuCYnEDou0Cl4naaMwuJ19rEwnuscR7tetGnTDA=="], @@ -2368,7 +2394,7 @@ "@types/eslint-scope": ["@types/eslint-scope@3.7.7", "", { "dependencies": { "@types/eslint": "*", "@types/estree": "*" } }, "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg=="], - "@types/estree": ["@types/estree@1.0.6", "", {}, "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="], + "@types/estree": ["@types/estree@1.0.7", "", {}, "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ=="], "@types/estree-jsx": ["@types/estree-jsx@1.0.5", "", { "dependencies": { "@types/estree": "*" } }, "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg=="], @@ -2436,7 +2462,7 @@ "@types/multer": ["@types/multer@1.4.12", "", { "dependencies": { "@types/express": "*" } }, "sha512-pQ2hoqvXiJt2FP9WQVLPRO+AmiIm/ZYkavPlIQnx282u4ZrVdztx0pkh3jjpQt0Kz+YI0YhSG264y08UJKoUQg=="], - "@types/node": ["@types/node@22.13.11", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-iEUCUJoU0i3VnrCmgoWCXttklWcvoCIx4jzcP22fioIVSdTmjgoEvmAO/QPw6TcS9k5FrNgn4w7q5lGOd1CT5g=="], + "@types/node": ["@types/node@22.13.13", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-ClsL5nMwKaBRwPcCvH8E7+nU4GxHVx1axNvMZTFHMEfNI7oahimt26P5zjVCRrjiIWj6YFXfE1v3dEp94wLcGQ=="], "@types/node-fetch": ["@types/node-fetch@2.6.12", "", { "dependencies": { "@types/node": "*", "form-data": "^4.0.0" } }, "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA=="], @@ -2522,27 +2548,35 @@ "@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="], - "@unrs/rspack-resolver-binding-darwin-arm64": ["@unrs/rspack-resolver-binding-darwin-arm64@1.2.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-i7z0B+C0P8Q63O/5PXJAzeFtA1ttY3OR2VSJgGv18S+PFNwD98xHgAgPOT1H5HIV6jlQP8Avzbp09qxJUdpPNw=="], + "@unrs/rspack-resolver-binding-darwin-arm64": ["@unrs/rspack-resolver-binding-darwin-arm64@1.3.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-EcjI0Hh2HiNOM0B9UuYH1PfLWgE6/SBQ4dKoHXWNloERfveha/n6aUZSBThtPGnJenmdfaJYXXZtqyNbWtJAFw=="], + + "@unrs/rspack-resolver-binding-darwin-x64": ["@unrs/rspack-resolver-binding-darwin-x64@1.3.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-3CgG+mhfudDfnaDqwEl0W1mcGTto5f5mqPyJSXcWDxrnNc7pr/p01khIgWOoOD1eCwVejmgpYvRKGBwJPwgHOQ=="], + + "@unrs/rspack-resolver-binding-freebsd-x64": ["@unrs/rspack-resolver-binding-freebsd-x64@1.3.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-ww8BwryDrpXlSajwSIEUXEv8oKDkw04L2ke3hxjaxWohuBV8pAQie9XBS4yQTyREuL2ypcqbARfoCXJJzVp7ig=="], - "@unrs/rspack-resolver-binding-darwin-x64": ["@unrs/rspack-resolver-binding-darwin-x64@1.2.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-YEdFzPjIbDUCfmehC6eS+AdJYtFWY35YYgWUnqqTM2oe/N58GhNy5yRllxYhxwJ9GcfHoNc6Ubze1yjkNv+9Qg=="], + "@unrs/rspack-resolver-binding-linux-arm-gnueabihf": ["@unrs/rspack-resolver-binding-linux-arm-gnueabihf@1.3.0", "", { "os": "linux", "cpu": "arm" }, "sha512-WyhonI1mkuAlnG2iaMjk7uy4aWX+FWi2Au8qCCwj57wVHbAEfrN6xN2YhzbrsCC+ciumKhj5c01MqwsnYDNzWQ=="], - "@unrs/rspack-resolver-binding-freebsd-x64": ["@unrs/rspack-resolver-binding-freebsd-x64@1.2.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TU4ntNXDgPN2giQyyzSnGWf/dVCem5lvwxg0XYvsvz35h5H19WrhTmHgbrULMuypCB3aHe1enYUC9rPLDw45mA=="], + "@unrs/rspack-resolver-binding-linux-arm-musleabihf": ["@unrs/rspack-resolver-binding-linux-arm-musleabihf@1.3.0", "", { "os": "linux", "cpu": "arm" }, "sha512-+uCP6hIAMVWHKQnLZHESJ1U1TFVGLR3FTeaS2A4zB0k8w+IbZlWwl9FiBUOwOiqhcCCyKiUEifgnYFNGpxi3pw=="], - "@unrs/rspack-resolver-binding-linux-arm-gnueabihf": ["@unrs/rspack-resolver-binding-linux-arm-gnueabihf@1.2.2", "", { "os": "linux", "cpu": "arm" }, "sha512-ik3w4/rU6RujBvNWiDnKdXi1smBhqxEDhccNi/j2rHaMjm0Fk49KkJ6XKsoUnD2kZ5xaMJf9JjailW/okfUPIw=="], + "@unrs/rspack-resolver-binding-linux-arm64-gnu": ["@unrs/rspack-resolver-binding-linux-arm64-gnu@1.3.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-p+s/Wp8rf75Qqs2EPw4HC0xVLLW+/60MlVAsB7TYLoeg1e1CU/QCis36FxpziLS0ZY2+wXdTnPUxr+5kkThzwQ=="], - "@unrs/rspack-resolver-binding-linux-arm64-gnu": ["@unrs/rspack-resolver-binding-linux-arm64-gnu@1.2.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-fp4Azi8kHz6TX8SFmKfyScZrMLfp++uRm2srpqRjsRZIIBzH74NtSkdEUHImR4G7f7XJ+sVZjCc6KDDK04YEpQ=="], + "@unrs/rspack-resolver-binding-linux-arm64-musl": ["@unrs/rspack-resolver-binding-linux-arm64-musl@1.3.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-cZEL9jmZ2kAN53MEk+fFCRJM8pRwOEboDn7sTLjZW+hL6a0/8JNfHP20n8+MBDrhyD34BSF4A6wPCj/LNhtOIQ=="], - "@unrs/rspack-resolver-binding-linux-arm64-musl": ["@unrs/rspack-resolver-binding-linux-arm64-musl@1.2.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-gMiG3DCFioJxdGBzhlL86KcFgt9HGz0iDhw0YVYPsShItpN5pqIkNrI+L/Q/0gfDiGrfcE0X3VANSYIPmqEAlQ=="], + "@unrs/rspack-resolver-binding-linux-ppc64-gnu": ["@unrs/rspack-resolver-binding-linux-ppc64-gnu@1.3.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-IOeRhcMXTNlk2oApsOozYVcOHu4t1EKYKnTz4huzdPyKNPX0Y9C7X8/6rk4aR3Inb5s4oVMT9IVKdgNXLcpGAQ=="], - "@unrs/rspack-resolver-binding-linux-x64-gnu": ["@unrs/rspack-resolver-binding-linux-x64-gnu@1.2.2", "", { "os": "linux", "cpu": "x64" }, "sha512-n/4n2CxaUF9tcaJxEaZm+lqvaw2gflfWQ1R9I7WQgYkKEKbRKbpG/R3hopYdUmLSRI4xaW1Cy0Bz40eS2Yi4Sw=="], + "@unrs/rspack-resolver-binding-linux-s390x-gnu": ["@unrs/rspack-resolver-binding-linux-s390x-gnu@1.3.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-op54XrlEbhgVRCxzF1pHFcLamdOmHDapwrqJ9xYRB7ZjwP/zQCKzz/uAsSaAlyQmbSi/PXV7lwfca4xkv860/Q=="], - "@unrs/rspack-resolver-binding-linux-x64-musl": ["@unrs/rspack-resolver-binding-linux-x64-musl@1.2.2", "", { "os": "linux", "cpu": "x64" }, "sha512-cHyhAr6rlYYbon1L2Ag449YCj3p6XMfcYTP0AQX+KkQo025d1y/VFtPWvjMhuEsE2lLvtHm7GdJozj6BOMtzVg=="], + "@unrs/rspack-resolver-binding-linux-x64-gnu": ["@unrs/rspack-resolver-binding-linux-x64-gnu@1.3.0", "", { "os": "linux", "cpu": "x64" }, "sha512-orbQF7sN02N/b9QF8Xp1RBO5YkfI+AYo9VZw0H2Gh4JYWSuiDHjOPEeFPDIRyWmXbQJuiVNSB+e1pZOjPPKIyg=="], - "@unrs/rspack-resolver-binding-wasm32-wasi": ["@unrs/rspack-resolver-binding-wasm32-wasi@1.2.2", "", { "dependencies": { "@napi-rs/wasm-runtime": "^0.2.7" }, "cpu": "none" }, "sha512-eogDKuICghDLGc32FtP+WniG38IB1RcGOGz0G3z8406dUdjJvxfHGuGs/dSlM9YEp/v0lEqhJ4mBu6X2nL9pog=="], + "@unrs/rspack-resolver-binding-linux-x64-musl": ["@unrs/rspack-resolver-binding-linux-x64-musl@1.3.0", "", { "os": "linux", "cpu": "x64" }, "sha512-kpjqjIAC9MfsjmlgmgeC8U9gZi6g/HTuCqpI7SBMjsa7/9MvBaQ6TJ7dtnsV/+DXvfJ2+L5teBBXG+XxfpvIFA=="], - "@unrs/rspack-resolver-binding-win32-arm64-msvc": ["@unrs/rspack-resolver-binding-win32-arm64-msvc@1.2.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-7sWRJumhpXSi2lccX8aQpfFXHsSVASdWndLv8AmD8nDRA/5PBi8IplQVZNx2mYRx6+Bp91Z00kuVqpXO9NfCTg=="], + "@unrs/rspack-resolver-binding-wasm32-wasi": ["@unrs/rspack-resolver-binding-wasm32-wasi@1.3.0", "", { "dependencies": { "@napi-rs/wasm-runtime": "^0.2.7" }, "cpu": "none" }, "sha512-JAg0hY3kGsCPk7Jgh16yMTBZ6VEnoNR1DFZxiozjKwH+zSCfuDuM5S15gr50ofbwVw9drobIP2TTHdKZ15MJZQ=="], - "@unrs/rspack-resolver-binding-win32-x64-msvc": ["@unrs/rspack-resolver-binding-win32-x64-msvc@1.2.2", "", { "os": "win32", "cpu": "x64" }, "sha512-hewo/UMGP1a7O6FG/ThcPzSJdm/WwrYDNkdGgWl6M18H6K6MSitklomWpT9MUtT5KGj++QJb06va/14QBC4pvw=="], + "@unrs/rspack-resolver-binding-win32-arm64-msvc": ["@unrs/rspack-resolver-binding-win32-arm64-msvc@1.3.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-h5N83i407ntS3ndDkhT/3vC3Dj8oP0BIwMtekETNJcxk7IuWccSXifzCEhdxxu/FOX4OICGIHdHrxf5fJuAjfw=="], + + "@unrs/rspack-resolver-binding-win32-ia32-msvc": ["@unrs/rspack-resolver-binding-win32-ia32-msvc@1.3.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-9QH7Gq3dRL8Q/D6PGS3Dwtjx9yw6kbCEu6iBkAUhFTDAuVUk2L0H/5NekRVA13AQaSc3OsEUKt60EOn/kq5Dug=="], + + "@unrs/rspack-resolver-binding-win32-x64-msvc": ["@unrs/rspack-resolver-binding-win32-x64-msvc@1.3.0", "", { "os": "win32", "cpu": "x64" }, "sha512-IYuXJCuwBOVV0H73l6auaZwtAPHjCPBJkxd4Co0yO6dSjDM5Na5OceaxhUmJLZ3z8kuEGhTYWIHH7PchGztnlg=="], "@vitejs/plugin-react": ["@vitejs/plugin-react@4.3.4", "", { "dependencies": { "@babel/core": "^7.26.0", "@babel/plugin-transform-react-jsx-self": "^7.25.9", "@babel/plugin-transform-react-jsx-source": "^7.25.9", "@types/babel__core": "^7.20.5", "react-refresh": "^0.14.2" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0" } }, "sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug=="], @@ -2638,7 +2672,7 @@ "aggregate-error": ["aggregate-error@3.1.0", "", { "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" } }, "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA=="], - "ai": ["ai@4.2.0", "", { "dependencies": { "@ai-sdk/provider": "1.1.0", "@ai-sdk/provider-utils": "2.2.0", "@ai-sdk/react": "1.2.0", "@ai-sdk/ui-utils": "1.2.0", "@opentelemetry/api": "1.9.0", "eventsource-parser": "^3.0.0", "jsondiffpatch": "0.6.0" }, "peerDependencies": { "react": "^18 || ^19 || ^19.0.0-rc", "zod": "^3.23.8" }, "optionalPeers": ["react"] }, "sha512-3xJWzBZpBS3n/UY360IopufV5dpfgYoY08eCAV2A2m7CcyJxVOAQ4lXvBGSsB+mR+BYJ8Y/JOesFfc0+k4jz3A=="], + "ai": ["ai@4.2.5", "", { "dependencies": { "@ai-sdk/provider": "1.1.0", "@ai-sdk/provider-utils": "2.2.1", "@ai-sdk/react": "1.2.2", "@ai-sdk/ui-utils": "1.2.1", "@opentelemetry/api": "1.9.0", "jsondiffpatch": "0.6.0" }, "peerDependencies": { "react": "^18 || ^19 || ^19.0.0-rc", "zod": "^3.23.8" }, "optionalPeers": ["react"] }, "sha512-URJEslI3cgF/atdTJHtz+Sj0W1JTmiGmD3znw9KensL3qV605odktDim+GTazNJFPR4QaIu1lUio5b8RymvOjA=="], "ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="], @@ -2648,9 +2682,9 @@ "ajv-keywords": ["ajv-keywords@5.1.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3" }, "peerDependencies": { "ajv": "^8.8.2" } }, "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw=="], - "algoliasearch": ["algoliasearch@5.21.0", "", { "dependencies": { "@algolia/client-abtesting": "5.21.0", "@algolia/client-analytics": "5.21.0", "@algolia/client-common": "5.21.0", "@algolia/client-insights": "5.21.0", "@algolia/client-personalization": "5.21.0", "@algolia/client-query-suggestions": "5.21.0", "@algolia/client-search": "5.21.0", "@algolia/ingestion": "1.21.0", "@algolia/monitoring": "1.21.0", "@algolia/recommend": "5.21.0", "@algolia/requester-browser-xhr": "5.21.0", "@algolia/requester-fetch": "5.21.0", "@algolia/requester-node-http": "5.21.0" } }, "sha512-hexLq2lSO1K5SW9j21Ubc+q9Ptx7dyRTY7se19U8lhIlVMLCNXWCyQ6C22p9ez8ccX0v7QVmwkl2l1CnuGoO2Q=="], + "algoliasearch": ["algoliasearch@5.23.0", "", { "dependencies": { "@algolia/client-abtesting": "5.23.0", "@algolia/client-analytics": "5.23.0", "@algolia/client-common": "5.23.0", "@algolia/client-insights": "5.23.0", "@algolia/client-personalization": "5.23.0", "@algolia/client-query-suggestions": "5.23.0", "@algolia/client-search": "5.23.0", "@algolia/ingestion": "1.23.0", "@algolia/monitoring": "1.23.0", "@algolia/recommend": "5.23.0", "@algolia/requester-browser-xhr": "5.23.0", "@algolia/requester-fetch": "5.23.0", "@algolia/requester-node-http": "5.23.0" } }, "sha512-7TCj+hLx6fZKppLL74lYGDEltSBNSu4vqRwgqeIKZ3VQ0q3aOrdEN0f1sDWcvU1b+psn2wnl7aHt9hWtYatUUA=="], - "algoliasearch-helper": ["algoliasearch-helper@3.24.2", "", { "dependencies": { "@algolia/events": "^4.0.1" }, "peerDependencies": { "algoliasearch": ">= 3.1 < 6" } }, "sha512-vBw/INZDfyh/THbVeDy8On8lZqd2qiUAHde5N4N1ygL4SoeLqLGJ4GHneHrDAYsjikRwTTtodEP0fiXl5MxHFQ=="], + "algoliasearch-helper": ["algoliasearch-helper@3.24.3", "", { "dependencies": { "@algolia/events": "^4.0.1" }, "peerDependencies": { "algoliasearch": ">= 3.1 < 6" } }, "sha512-3QKg5lzSfUiPN8Hn1ViHEGv6PjK7i4SFEDLzwlSzPO/4mVOsyos7B7/AsEtFQW5KHHPiCq6DyJl+mzg7CYlEgw=="], "allof-merge": ["allof-merge@0.6.6", "", { "dependencies": { "json-crawl": "^0.5.3" } }, "sha512-116eZBf2he0/J4Tl7EYMz96I5Anaeio+VL0j/H2yxW9CoYQAMMv8gYcwkVRoO7XfIOv/qzSTfVzDVGAYxKFi3g=="], @@ -2768,9 +2802,9 @@ "bare-events": ["bare-events@2.5.4", "", {}, "sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA=="], - "bare-fs": ["bare-fs@4.0.1", "", { "dependencies": { "bare-events": "^2.0.0", "bare-path": "^3.0.0", "bare-stream": "^2.0.0" } }, "sha512-ilQs4fm/l9eMfWY2dY0WCIUplSUp7U0CT1vrqMg1MUdeZl4fypu5UP0XcDBK5WBQPJAKP1b7XEodISmekH/CEg=="], + "bare-fs": ["bare-fs@4.0.2", "", { "dependencies": { "bare-events": "^2.5.4", "bare-path": "^3.0.0", "bare-stream": "^2.6.4" }, "peerDependencies": { "bare-buffer": "*" }, "optionalPeers": ["bare-buffer"] }, "sha512-S5mmkMesiduMqnz51Bfh0Et9EX0aTCJxhsI4bvzFFLs8Z1AV8RDHadfY5CyLwdoLHgXbNBEN1gQcbEtGwuvixw=="], - "bare-os": ["bare-os@3.6.0", "", {}, "sha512-BUrFS5TqSBdA0LwHop4OjPJwisqxGy6JsWVqV6qaFoe965qqtaKfDzHY5T2YA1gUL0ZeeQeA+4BBc1FJTcHiPw=="], + "bare-os": ["bare-os@3.6.1", "", {}, "sha512-uaIjxokhFidJP+bmmvKSgiMzj2sV5GPHaZVAIktcxcpCyBFFWO+YlikVAdhmUo2vYFvFhOXIAlldqV29L8126g=="], "bare-path": ["bare-path@3.0.0", "", { "dependencies": { "bare-os": "^3.0.1" } }, "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw=="], @@ -2862,7 +2896,7 @@ "bun": ["bun@1.2.5", "", { "optionalDependencies": { "@oven/bun-darwin-aarch64": "1.2.5", "@oven/bun-darwin-x64": "1.2.5", "@oven/bun-darwin-x64-baseline": "1.2.5", "@oven/bun-linux-aarch64": "1.2.5", "@oven/bun-linux-aarch64-musl": "1.2.5", "@oven/bun-linux-x64": "1.2.5", "@oven/bun-linux-x64-baseline": "1.2.5", "@oven/bun-linux-x64-musl": "1.2.5", "@oven/bun-linux-x64-musl-baseline": "1.2.5", "@oven/bun-windows-x64": "1.2.5", "@oven/bun-windows-x64-baseline": "1.2.5" }, "os": [ "linux", "win32", "darwin", ], "cpu": [ "x64", "arm64", ], "bin": { "bun": "bin/bun.exe", "bunx": "bin/bun.exe" } }, "sha512-fbQLt+DPiGUrPKdmsHRRT7cQAlfjdxPVFvLZrsUPmKiTdv+pU50ypdx9yRJluknSbyaZchFVV7Lx2KXikXKX2Q=="], - "bun-types": ["bun-types@1.2.5", "", { "dependencies": { "@types/node": "*", "@types/ws": "~8.5.10" } }, "sha512-3oO6LVGGRRKI4kHINx5PIdIgnLRb7l/SprhzqXapmoYkFl5m4j6EvALvbDVuuBFaamB46Ap6HCUxIXNLCGy+tg=="], + "bun-types": ["bun-types@1.2.6", "", { "dependencies": { "@types/node": "*", "@types/ws": "~8.5.10" } }, "sha512-FbCKyr5KDiPULUzN/nm5oqQs9nXCHD8dVc64BArxJadCvbNzAI6lUWGh9fSJZWeDIRD38ikceBU8Kj/Uh+53oQ=="], "bundle-require": ["bundle-require@5.1.0", "", { "dependencies": { "load-tsconfig": "^0.2.3" }, "peerDependencies": { "esbuild": ">=0.18" } }, "sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA=="], @@ -2900,12 +2934,14 @@ "caniuse-api": ["caniuse-api@3.0.0", "", { "dependencies": { "browserslist": "^4.0.0", "caniuse-lite": "^1.0.0", "lodash.memoize": "^4.1.2", "lodash.uniq": "^4.5.0" } }, "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw=="], - "caniuse-lite": ["caniuse-lite@1.0.30001706", "", {}, "sha512-3ZczoTApMAZwPKYWmwVbQMFpXBDds3/0VciVoUwPUbldlYyVLmRVuRs/PcUZtHpbLRpzzDvrvnFuREsGt6lUug=="], + "caniuse-lite": ["caniuse-lite@1.0.30001707", "", {}, "sha512-3qtRjw/HQSMlDWf+X79N206fepf4SOOU6SQLMaq/0KkZLmSjPxAkBOQQ+FxbHKfHmYLZFfdWsO3KA90ceHPSnw=="], "canvas": ["canvas@2.11.2", "", { "dependencies": { "@mapbox/node-pre-gyp": "^1.0.0", "nan": "^2.17.0", "simple-get": "^3.0.3" } }, "sha512-ItanGBMrmRV7Py2Z+Xhs7cT+FNt5K0vPL4p9EZ/UX/Mu7hFbkxSjKF2KVtPwX7UYWp7dRKnrTvReflgrItJbdw=="], "capsolver-npm": ["capsolver-npm@2.0.2", "", { "dependencies": { "axios": "^0.27.2", "dotenv": "^16.4.5" } }, "sha512-PvkAGTuwtKXczJeoiLu2XQ4SzJh0m7Yr3ONJuvdjEAw95LwtfGxZ3Ip/w21kR94R4O260omLGlTcQvPf2ECnLg=="], + "caseless": ["caseless@0.12.0", "", {}, "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw=="], + "ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="], "chai": ["chai@5.2.0", "", { "dependencies": { "assertion-error": "^2.0.1", "check-error": "^2.1.1", "deep-eql": "^5.0.1", "loupe": "^3.1.0", "pathval": "^2.0.0" } }, "sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw=="], @@ -3380,7 +3416,7 @@ "ejs": ["ejs@3.1.10", "", { "dependencies": { "jake": "^10.8.5" }, "bin": { "ejs": "bin/cli.js" } }, "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA=="], - "electron-to-chromium": ["electron-to-chromium@1.5.123", "", {}, "sha512-refir3NlutEZqlKaBLK0tzlVLe5P2wDKS7UQt/3SpibizgsRAPOsqQC3ffw1nlv3ze5gjRQZYHoPymgVZkplFA=="], + "electron-to-chromium": ["electron-to-chromium@1.5.124", "", {}, "sha512-riELkpDUqBi00gqreV3RIGoowxGrfueEKBd6zPdOk/I8lvuFpBGNkYoHof3zUHbiTBsIU8oxdIIL/WNrAG1/7A=="], "emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="], @@ -3408,7 +3444,7 @@ "entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], - "env-paths": ["env-paths@3.0.0", "", {}, "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A=="], + "env-paths": ["env-paths@2.2.1", "", {}, "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="], "env-var": ["env-var@7.5.0", "", {}, "sha512-mKZOzLRN0ETzau2W2QXefbFjo5EF4yWq28OyKb9ICdeNhHJlOE/pHHnz4hdYJ9cNZXcJHo5xN4OT4pzuSHSNvA=="], @@ -3606,6 +3642,8 @@ "feed": ["feed@4.2.2", "", { "dependencies": { "xml-js": "^1.6.11" } }, "sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ=="], + "ffmpeg-static": ["ffmpeg-static@5.2.0", "", { "dependencies": { "@derhuerst/http-basic": "^8.2.0", "env-paths": "^2.2.0", "https-proxy-agent": "^5.0.0", "progress": "^2.0.3" } }, "sha512-WrM7kLW+do9HLr+H6tk7LzQ7kPqbAgLjdzNE32+u3Ff11gXt9Kkkd2nusGFrlWMIe+XaA97t+I8JS7sZIrvRgA=="], + "figures": ["figures@3.2.0", "", { "dependencies": { "escape-string-regexp": "^1.0.5" } }, "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg=="], "file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="], @@ -3848,7 +3886,7 @@ "hpack.js": ["hpack.js@2.1.6", "", { "dependencies": { "inherits": "^2.0.1", "obuf": "^1.0.0", "readable-stream": "^2.0.1", "wbuf": "^1.1.0" } }, "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ=="], - "html-entities": ["html-entities@2.5.2", "", {}, "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA=="], + "html-entities": ["html-entities@2.5.3", "", {}, "sha512-D3AfvN7SjhTgBSA8L1BN4FpPzuEd06uy4lHwSoRWr0lndi9BKaNzPLKGOWZ2ocSGguozr08TTb2jhCLHaemruw=="], "html-escaper": ["html-escaper@2.0.2", "", {}, "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg=="], @@ -3878,6 +3916,8 @@ "http-reasons": ["http-reasons@0.1.0", "", {}, "sha512-P6kYh0lKZ+y29T2Gqz+RlC9WBLhKe8kDmcJ+A+611jFfxdPsbMRQ5aNmFRM3lENqFkK+HTTL+tlQviAiv0AbLQ=="], + "http-response-object": ["http-response-object@3.0.2", "", { "dependencies": { "@types/node": "^10.0.3" } }, "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA=="], + "http2-client": ["http2-client@1.3.5", "", {}, "sha512-EC2utToWl4RKfs5zd36Mxq7nzHHBuomZboI0yYL6Y0RmBgT7Sgkq4rQ0ezFTYoIsSs7Tm9SJe+o2FcAg6GBhGA=="], "http2-wrapper": ["http2-wrapper@2.2.1", "", { "dependencies": { "quick-lru": "^5.1.1", "resolve-alpn": "^1.2.0" } }, "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ=="], @@ -3908,7 +3948,7 @@ "immer": ["immer@9.0.21", "", {}, "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA=="], - "immutable": ["immutable@5.0.3", "", {}, "sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw=="], + "immutable": ["immutable@5.1.1", "", {}, "sha512-3jatXi9ObIsPGr3N5hGw/vWWcTkq6hUYhpQz4k0wLC+owqWi/LiugIw9x0EdNZ2yGedKN/HzePiBvaJRXa0Ujg=="], "import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="], @@ -3936,7 +3976,7 @@ "internal-slot": ["internal-slot@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "hasown": "^2.0.2", "side-channel": "^1.1.0" } }, "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw=="], - "internmap": ["internmap@2.0.3", "", {}, "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg=="], + "internmap": ["internmap@1.0.1", "", {}, "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw=="], "interpret": ["interpret@1.4.0", "", {}, "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA=="], @@ -4172,9 +4212,9 @@ "langchain": ["langchain@0.3.19", "", { "dependencies": { "@langchain/openai": ">=0.1.0 <0.5.0", "@langchain/textsplitters": ">=0.0.0 <0.2.0", "js-tiktoken": "^1.0.12", "js-yaml": "^4.1.0", "jsonpointer": "^5.0.1", "langsmith": ">=0.2.8 <0.4.0", "openapi-types": "^12.1.3", "p-retry": "4", "uuid": "^10.0.0", "yaml": "^2.2.1", "zod": "^3.22.4", "zod-to-json-schema": "^3.22.3" }, "peerDependencies": { "@langchain/anthropic": "*", "@langchain/aws": "*", "@langchain/cerebras": "*", "@langchain/cohere": "*", "@langchain/core": ">=0.2.21 <0.4.0", "@langchain/deepseek": "*", "@langchain/google-genai": "*", "@langchain/google-vertexai": "*", "@langchain/google-vertexai-web": "*", "@langchain/groq": "*", "@langchain/mistralai": "*", "@langchain/ollama": "*", "@langchain/xai": "*", "axios": "*", "cheerio": "*", "handlebars": "^4.7.8", "peggy": "^3.0.2", "typeorm": "*" }, "optionalPeers": ["@langchain/anthropic", "@langchain/aws", "@langchain/cerebras", "@langchain/cohere", "@langchain/deepseek", "@langchain/google-genai", "@langchain/google-vertexai", "@langchain/google-vertexai-web", "@langchain/groq", "@langchain/mistralai", "@langchain/ollama", "@langchain/xai", "axios", "cheerio", "handlebars", "peggy", "typeorm"] }, "sha512-aGhoTvTBS5ulatA67RHbJ4bcV5zcYRYdm5IH+hpX99RYSFXG24XF3ghSjhYi6sxW+SUnEQ99fJhA5kroVpKNhw=="], - "langium": ["langium@3.0.0", "", { "dependencies": { "chevrotain": "~11.0.3", "chevrotain-allstar": "~0.3.0", "vscode-languageserver": "~9.0.1", "vscode-languageserver-textdocument": "~1.0.11", "vscode-uri": "~3.0.8" } }, "sha512-+Ez9EoiByeoTu/2BXmEaZ06iPNXM6thWJp02KfBO/raSMyCJ4jw7AkWWa+zBCTm0+Tw1Fj9FOxdqSskyN5nAwg=="], + "langium": ["langium@3.3.1", "", { "dependencies": { "chevrotain": "~11.0.3", "chevrotain-allstar": "~0.3.0", "vscode-languageserver": "~9.0.1", "vscode-languageserver-textdocument": "~1.0.11", "vscode-uri": "~3.0.8" } }, "sha512-QJv/h939gDpvT+9SiLVlY7tZC3xB2qK57v0J04Sh9wpMb6MP1q8gB21L3WIo8T5P1MSMg3Ep14L7KkDCFG3y4w=="], - "langsmith": ["langsmith@0.3.14", "", { "dependencies": { "@types/uuid": "^10.0.0", "chalk": "^4.1.2", "console-table-printer": "^2.12.1", "p-queue": "^6.6.2", "p-retry": "4", "semver": "^7.6.3", "uuid": "^10.0.0" }, "peerDependencies": { "openai": "*" }, "optionalPeers": ["openai"] }, "sha512-MzoxdRkFFV/6140vpP5V2e2fkTG6x/0zIjw77bsRwAXEMjPRTUyDazfXeSyrS5uJvbLgxAXc+MF1h6vPWe6SXQ=="], + "langsmith": ["langsmith@0.3.15", "", { "dependencies": { "@types/uuid": "^10.0.0", "chalk": "^4.1.2", "console-table-printer": "^2.12.1", "p-queue": "^6.6.2", "p-retry": "4", "semver": "^7.6.3", "uuid": "^10.0.0" }, "peerDependencies": { "openai": "*" }, "optionalPeers": ["openai"] }, "sha512-cv3ebg0Hh0gRbl72cv/uzaZ+KOdfa2mGF1s74vmB2vlNVO/Ap/O9RYaHV+tpR8nwhGZ50R3ILnTOwSwGP+XQxw=="], "language-subtag-registry": ["language-subtag-registry@0.3.23", "", {}, "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ=="], @@ -4358,7 +4398,7 @@ "merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="], - "mermaid": ["mermaid@11.5.0", "", { "dependencies": { "@braintree/sanitize-url": "^7.0.4", "@iconify/utils": "^2.1.33", "@mermaid-js/parser": "^0.3.0", "@types/d3": "^7.4.3", "cytoscape": "^3.29.3", "cytoscape-cose-bilkent": "^4.1.0", "cytoscape-fcose": "^2.2.0", "d3": "^7.9.0", "d3-sankey": "^0.12.3", "dagre-d3-es": "7.0.11", "dayjs": "^1.11.13", "dompurify": "^3.2.4", "katex": "^0.16.9", "khroma": "^2.1.0", "lodash-es": "^4.17.21", "marked": "^15.0.7", "roughjs": "^4.6.6", "stylis": "^4.3.6", "ts-dedent": "^2.2.0", "uuid": "^11.1.0" } }, "sha512-IYhyukID3zzDj1EihKiN1lp+PXNImoJ3Iyz73qeDAgnus4BNGsJV1n471P4PyeGxPVONerZxignwGxGTSwZnlg=="], + "mermaid": ["mermaid@11.6.0", "", { "dependencies": { "@braintree/sanitize-url": "^7.0.4", "@iconify/utils": "^2.1.33", "@mermaid-js/parser": "^0.4.0", "@types/d3": "^7.4.3", "cytoscape": "^3.29.3", "cytoscape-cose-bilkent": "^4.1.0", "cytoscape-fcose": "^2.2.0", "d3": "^7.9.0", "d3-sankey": "^0.12.3", "dagre-d3-es": "7.0.11", "dayjs": "^1.11.13", "dompurify": "^3.2.4", "katex": "^0.16.9", "khroma": "^2.1.0", "lodash-es": "^4.17.21", "marked": "^15.0.7", "roughjs": "^4.6.6", "stylis": "^4.3.6", "ts-dedent": "^2.2.0", "uuid": "^11.1.0" } }, "sha512-PE8hGUy1LDlWIHWBP05SFdqUHGmRcCcK4IzpOKPE35eOw+G9zZgcnMpyunJVUEOgb//KBORPjysKndw8bFLuRg=="], "methods": ["methods@1.1.2", "", {}, "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w=="], @@ -4384,9 +4424,9 @@ "micromark-extension-gfm-task-list-item": ["micromark-extension-gfm-task-list-item@1.0.5", "", { "dependencies": { "micromark-factory-space": "^1.0.0", "micromark-util-character": "^1.0.0", "micromark-util-symbol": "^1.0.0", "micromark-util-types": "^1.0.0", "uvu": "^0.5.0" } }, "sha512-RMFXl2uQ0pNQy6Lun2YBYT9g9INXtWJULgbt01D/x8/6yJ2qpKyzdZD3pi6UIkzF++Da49xAelVKUeUMqd5eIQ=="], - "micromark-extension-mdx-expression": ["micromark-extension-mdx-expression@3.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "devlop": "^1.0.0", "micromark-factory-mdx-expression": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-events-to-acorn": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-sI0nwhUDz97xyzqJAbHQhp5TfaxEvZZZ2JDqUo+7NvyIYG6BZ5CPPqj2ogUoPJlmXHBnyZUzISg9+oUmU6tUjQ=="], + "micromark-extension-mdx-expression": ["micromark-extension-mdx-expression@3.0.1", "", { "dependencies": { "@types/estree": "^1.0.0", "devlop": "^1.0.0", "micromark-factory-mdx-expression": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-events-to-acorn": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q=="], - "micromark-extension-mdx-jsx": ["micromark-extension-mdx-jsx@3.0.1", "", { "dependencies": { "@types/acorn": "^4.0.0", "@types/estree": "^1.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "micromark-factory-mdx-expression": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-events-to-acorn": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "vfile-message": "^4.0.0" } }, "sha512-vNuFb9czP8QCtAQcEJn0UJQJZA8Dk6DXKBqx+bg/w0WGuSxDxNr7hErW89tHUY31dUW4NqEOWwmEUNhjTFmHkg=="], + "micromark-extension-mdx-jsx": ["micromark-extension-mdx-jsx@3.0.2", "", { "dependencies": { "@types/estree": "^1.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "micromark-factory-mdx-expression": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-events-to-acorn": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "vfile-message": "^4.0.0" } }, "sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ=="], "micromark-extension-mdx-md": ["micromark-extension-mdx-md@2.0.0", "", { "dependencies": { "micromark-util-types": "^2.0.0" } }, "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ=="], @@ -4398,7 +4438,7 @@ "micromark-factory-label": ["micromark-factory-label@1.1.0", "", { "dependencies": { "micromark-util-character": "^1.0.0", "micromark-util-symbol": "^1.0.0", "micromark-util-types": "^1.0.0", "uvu": "^0.5.0" } }, "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w=="], - "micromark-factory-mdx-expression": ["micromark-factory-mdx-expression@2.0.2", "", { "dependencies": { "@types/estree": "^1.0.0", "devlop": "^1.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-events-to-acorn": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "unist-util-position-from-estree": "^2.0.0", "vfile-message": "^4.0.0" } }, "sha512-5E5I2pFzJyg2CtemqAbcyCktpHXuJbABnsb32wX2U8IQKhhVFBqkcZR5LRm1WVoFqa4kTueZK4abep7wdo9nrw=="], + "micromark-factory-mdx-expression": ["micromark-factory-mdx-expression@2.0.3", "", { "dependencies": { "@types/estree": "^1.0.0", "devlop": "^1.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-events-to-acorn": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "unist-util-position-from-estree": "^2.0.0", "vfile-message": "^4.0.0" } }, "sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ=="], "micromark-factory-space": ["micromark-factory-space@1.1.0", "", { "dependencies": { "micromark-util-character": "^1.0.0", "micromark-util-types": "^1.0.0" } }, "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ=="], @@ -4420,7 +4460,7 @@ "micromark-util-encode": ["micromark-util-encode@2.0.1", "", {}, "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw=="], - "micromark-util-events-to-acorn": ["micromark-util-events-to-acorn@2.0.2", "", { "dependencies": { "@types/acorn": "^4.0.0", "@types/estree": "^1.0.0", "@types/unist": "^3.0.0", "devlop": "^1.0.0", "estree-util-visit": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "vfile-message": "^4.0.0" } }, "sha512-Fk+xmBrOv9QZnEDguL9OI9/NQQp6Hz4FuQ4YmCb/5V7+9eAh1s6AYSvL20kHkD67YIg7EpE54TiSlcsf3vyZgA=="], + "micromark-util-events-to-acorn": ["micromark-util-events-to-acorn@2.0.3", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/unist": "^3.0.0", "devlop": "^1.0.0", "estree-util-visit": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "vfile-message": "^4.0.0" } }, "sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg=="], "micromark-util-html-tag-name": ["micromark-util-html-tag-name@1.2.0", "", {}, "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q=="], @@ -4662,7 +4702,7 @@ "open": ["open@8.4.2", "", { "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", "is-wsl": "^2.2.0" } }, "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ=="], - "openai": ["openai@4.89.0", "", { "dependencies": { "@types/node": "^18.11.18", "@types/node-fetch": "^2.6.4", "abort-controller": "^3.0.0", "agentkeepalive": "^4.2.1", "form-data-encoder": "1.7.2", "formdata-node": "^4.3.2", "node-fetch": "^2.6.7" }, "peerDependencies": { "ws": "^8.18.0", "zod": "^3.23.8" }, "optionalPeers": ["ws", "zod"], "bin": { "openai": "bin/cli" } }, "sha512-XNI0q2l8/Os6jmojxaID5EhyQjxZgzR2gWcpEjYWK5hGKwE7AcifxEY7UNwFDDHJQXqeiosQ0CJwQN+rvnwdjA=="], + "openai": ["openai@4.89.1", "", { "dependencies": { "@types/node": "^18.11.18", "@types/node-fetch": "^2.6.4", "abort-controller": "^3.0.0", "agentkeepalive": "^4.2.1", "form-data-encoder": "1.7.2", "formdata-node": "^4.3.2", "node-fetch": "^2.6.7" }, "peerDependencies": { "ws": "^8.18.0", "zod": "^3.23.8" }, "optionalPeers": ["ws", "zod"], "bin": { "openai": "bin/cli" } }, "sha512-k6t7WfnodIctPo40/9sy7Ww4VypnfkKi/urO2VQx4trCIwgzeroO1jkaCL2f5MyTS1H3HT9X+M2qLsc7NSXwTw=="], "openapi-to-postmanv2": ["openapi-to-postmanv2@4.25.0", "", { "dependencies": { "ajv": "8.11.0", "ajv-draft-04": "1.0.0", "ajv-formats": "2.1.1", "async": "3.2.4", "commander": "2.20.3", "graphlib": "2.1.8", "js-yaml": "4.1.0", "json-pointer": "0.6.2", "json-schema-merge-allof": "0.8.1", "lodash": "4.17.21", "neotraverse": "0.6.15", "oas-resolver-browser": "2.5.6", "object-hash": "3.0.0", "path-browserify": "1.0.1", "postman-collection": "^4.4.0", "swagger2openapi": "7.0.8", "yaml": "1.10.2" }, "bin": { "openapi2postmanv2": "bin/openapi2postmanv2.js" } }, "sha512-sIymbkQby0gzxt2Yez8YKB6hoISEel05XwGwNrAhr6+vxJWXNxkmssQc/8UEtVkuJ9ZfUXLkip9PYACIpfPDWg=="], @@ -4728,6 +4768,8 @@ "parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="], + "parse-cache-control": ["parse-cache-control@1.0.1", "", {}, "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg=="], + "parse-entities": ["parse-entities@4.0.2", "", { "dependencies": { "@types/unist": "^2.0.0", "character-entities-legacy": "^3.0.0", "character-reference-invalid": "^2.0.0", "decode-named-character-reference": "^1.0.0", "is-alphanumerical": "^2.0.0", "is-decimal": "^2.0.0", "is-hexadecimal": "^2.0.0" } }, "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw=="], "parse-json": ["parse-json@5.2.0", "", { "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg=="], @@ -5302,7 +5344,7 @@ "rpc-websockets": ["rpc-websockets@9.1.1", "", { "dependencies": { "@swc/helpers": "^0.5.11", "@types/uuid": "^8.3.4", "@types/ws": "^8.2.2", "buffer": "^6.0.3", "eventemitter3": "^5.0.1", "uuid": "^8.3.2", "ws": "^8.5.0" }, "optionalDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" } }, "sha512-1IXGM/TfPT6nfYMIXkJdzn+L4JEsmb0FL1O2OBjaH03V3yuUDdKFulGLMFG6ErV+8pZ5HVC0limve01RyO+saA=="], - "rspack-resolver": ["rspack-resolver@1.2.2", "", { "optionalDependencies": { "@unrs/rspack-resolver-binding-darwin-arm64": "1.2.2", "@unrs/rspack-resolver-binding-darwin-x64": "1.2.2", "@unrs/rspack-resolver-binding-freebsd-x64": "1.2.2", "@unrs/rspack-resolver-binding-linux-arm-gnueabihf": "1.2.2", "@unrs/rspack-resolver-binding-linux-arm64-gnu": "1.2.2", "@unrs/rspack-resolver-binding-linux-arm64-musl": "1.2.2", "@unrs/rspack-resolver-binding-linux-x64-gnu": "1.2.2", "@unrs/rspack-resolver-binding-linux-x64-musl": "1.2.2", "@unrs/rspack-resolver-binding-wasm32-wasi": "1.2.2", "@unrs/rspack-resolver-binding-win32-arm64-msvc": "1.2.2", "@unrs/rspack-resolver-binding-win32-x64-msvc": "1.2.2" } }, "sha512-Fwc19jMBA3g+fxDJH2B4WxwZjE0VaaOL7OX/A4Wn5Zv7bOD/vyPZhzXfaO73Xc2GAlfi96g5fGUa378WbIGfFw=="], + "rspack-resolver": ["rspack-resolver@1.3.0", "", { "optionalDependencies": { "@unrs/rspack-resolver-binding-darwin-arm64": "1.3.0", "@unrs/rspack-resolver-binding-darwin-x64": "1.3.0", "@unrs/rspack-resolver-binding-freebsd-x64": "1.3.0", "@unrs/rspack-resolver-binding-linux-arm-gnueabihf": "1.3.0", "@unrs/rspack-resolver-binding-linux-arm-musleabihf": "1.3.0", "@unrs/rspack-resolver-binding-linux-arm64-gnu": "1.3.0", "@unrs/rspack-resolver-binding-linux-arm64-musl": "1.3.0", "@unrs/rspack-resolver-binding-linux-ppc64-gnu": "1.3.0", "@unrs/rspack-resolver-binding-linux-s390x-gnu": "1.3.0", "@unrs/rspack-resolver-binding-linux-x64-gnu": "1.3.0", "@unrs/rspack-resolver-binding-linux-x64-musl": "1.3.0", "@unrs/rspack-resolver-binding-wasm32-wasi": "1.3.0", "@unrs/rspack-resolver-binding-win32-arm64-msvc": "1.3.0", "@unrs/rspack-resolver-binding-win32-ia32-msvc": "1.3.0", "@unrs/rspack-resolver-binding-win32-x64-msvc": "1.3.0" } }, "sha512-az/PLDwa1xijNv4bAFBS8mtqqJC1Y3lVyFag4cuyIUOHq/ft5kSZlHbqYaLZLpsQtPWv4ZGDo5ycySKJzUvU/A=="], "rtlcss": ["rtlcss@4.3.0", "", { "dependencies": { "escalade": "^3.1.1", "picocolors": "^1.0.0", "postcss": "^8.4.21", "strip-json-comments": "^3.1.1" }, "bin": { "rtlcss": "bin/rtlcss.js" } }, "sha512-FI+pHEn7Wc4NqKXMXFM+VAYKEj/mRIcW4h24YVwVtyjI+EqGrLc2Hx/Ny0lrZ21cBWU2goLy36eqMcNj3AQJig=="], @@ -5742,7 +5784,7 @@ "tweetnacl": ["tweetnacl@0.14.5", "", {}, "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA=="], - "twitter-api-v2": ["twitter-api-v2@1.21.0", "", {}, "sha512-KbSdpZ7REO42TdOaDxgKnfMxESV4lmJITqXij4ykf71u8vrFj3RzrMWcSXERIA3wrdk3705YzafFbG6Dy8y2UQ=="], + "twitter-api-v2": ["twitter-api-v2@1.22.0", "", {}, "sha512-KlcRL9vcBzjeS/PwxX33NziP+SHp9n35DOclKtpOmnNes7nNVnK7WG4pKlHfBqGrY5kAz/8J5ERS8DWkYOaiWw=="], "tx2": ["tx2@1.0.5", "", { "dependencies": { "json-stringify-safe": "^5.0.1" } }, "sha512-sJ24w0y03Md/bxzK4FU8J8JveYYUbSs2FViLJ2D/8bytSiyPRbuE3DyL/9UKYXTZlV3yXq0L8GLlhobTnekCVg=="], @@ -5774,7 +5816,7 @@ "typescript": ["typescript@5.8.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ=="], - "typescript-eslint": ["typescript-eslint@8.27.0", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.27.0", "@typescript-eslint/parser": "8.27.0", "@typescript-eslint/utils": "8.27.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-ZZ/8+Y0rRUMuW1gJaPtLWe4ryHbsPLzzibk5Sq+IFa2aOH1Vo0gPr1fbA6pOnzBke7zC2Da4w8AyCgxKXo3lqA=="], + "typescript-eslint": ["typescript-eslint@8.28.0", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.28.0", "@typescript-eslint/parser": "8.28.0", "@typescript-eslint/utils": "8.28.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-jfZtxJoHm59bvoCMYCe2BM0/baMswRhMmYhy+w6VfcyHrjxZ0OJe0tGasydCpIpA+A/WIJhTyZfb3EtwNC/kHQ=="], "uc.micro": ["uc.micro@2.1.0", "", {}, "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A=="], @@ -6048,13 +6090,13 @@ "zwitch": ["zwitch@1.0.5", "", {}, "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw=="], - "@ai-sdk/react/@ai-sdk/ui-utils": ["@ai-sdk/ui-utils@1.2.0", "", { "dependencies": { "@ai-sdk/provider": "1.1.0", "@ai-sdk/provider-utils": "2.2.0", "zod-to-json-schema": "^3.24.1" }, "peerDependencies": { "zod": "^3.23.8" } }, "sha512-0IZwCqe7E+GkCASTDPAbzMr+POm9GDzWvFd37FvzpOeKNeibmge/LZEkTDbGSa+3b928H8wPwOLsOXBWPLUPDQ=="], + "@ai-sdk/react/@ai-sdk/ui-utils": ["@ai-sdk/ui-utils@1.2.1", "", { "dependencies": { "@ai-sdk/provider": "1.1.0", "@ai-sdk/provider-utils": "2.2.1", "zod-to-json-schema": "^3.24.1" }, "peerDependencies": { "zod": "^3.23.8" } }, "sha512-BzvMbYm7LHBlbWuLlcG1jQh4eu14MGpz7L+wrGO1+F4oQ+O0fAjgUSNwPWGlZpKmg4NrcVq/QLmxiVJrx2R4Ew=="], "@ai-sdk/ui-utils/@ai-sdk/provider": ["@ai-sdk/provider@1.0.7", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-q1PJEZ0qD9rVR+8JFEd01/QM++csMT5UVwYXSN2u54BrVw/D8TZLTeg2FEfKK00DgAx0UtWd8XOhhwITP9BT5g=="], "@ai-sdk/ui-utils/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@2.1.6", "", { "dependencies": { "@ai-sdk/provider": "1.0.7", "eventsource-parser": "^3.0.0", "nanoid": "^3.3.8", "secure-json-parse": "^2.7.0" }, "peerDependencies": { "zod": "^3.0.0" }, "optionalPeers": ["zod"] }, "sha512-Pfyaj0QZS22qyVn5Iz7IXcJ8nKIKlu2MeSAdKJzTwkAks7zdLaKVB+396Rqcp1bfQnxl7vaduQVMQiXUrgK8Gw=="], - "@anthropic-ai/sdk/@types/node": ["@types/node@18.19.81", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-7KO9oZ2//ivtSsryp0LQUqq79zyGXzwq1WqfywpC9ucjY7YyltMMmxWgtRFRKCxwa7VPxVBVy4kHf5UC1E8Lug=="], + "@anthropic-ai/sdk/@types/node": ["@types/node@18.19.83", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-D69JeR5SfFS5H6FLbUaS0vE4r1dGhmMBbG4Ed6BNS4wkDK8GZjsdCShT5LCN59vOHEUHnFCY9J4aclXlIphMkA=="], "@anthropic-ai/sdk/formdata-node": ["formdata-node@4.4.1", "", { "dependencies": { "node-domexception": "1.0.0", "web-streams-polyfill": "4.0.0-beta.3" } }, "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ=="], @@ -6098,6 +6140,8 @@ "@csstools/selector-specificity/postcss-selector-parser": ["postcss-selector-parser@7.1.0", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA=="], + "@derhuerst/http-basic/concat-stream": ["concat-stream@2.0.0", "", { "dependencies": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.0.2", "typedarray": "^0.0.6" } }, "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A=="], + "@discordjs/builders/@discordjs/formatters": ["@discordjs/formatters@0.6.0", "", { "dependencies": { "discord-api-types": "^0.37.114" } }, "sha512-YIruKw4UILt/ivO4uISmrGq2GdMY6EkoTtD0oS0GvkJFRZbTSdPhzYiUILbJ/QslsvC9H9nTgGgnarnIl4jMfw=="], "@discordjs/builders/discord-api-types": ["discord-api-types@0.37.119", "", {}, "sha512-WasbGFXEB+VQWXlo6IpW3oUv73Yuau1Ig4AZF/m13tXcTKnMpc/mHjpztIlz4+BM9FG9BHQkEXiPto3bKduQUg=="], @@ -6146,13 +6190,13 @@ "@docusaurus/types/commander": ["commander@5.1.0", "", {}, "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg=="], - "@elizaos/app/vite": ["vite@6.2.2", "", { "dependencies": { "esbuild": "^0.25.0", "postcss": "^8.5.3", "rollup": "^4.30.1" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-yW7PeMM+LkDzc7CgJuRLMW2Jz0FxMOsVJ8Lv3gpgW9WLcb9cTW+121UEr1hvmfR7w3SegR5ItvYyzVz1vxNJgQ=="], + "@elizaos/app/vite": ["vite@6.2.3", "", { "dependencies": { "esbuild": "^0.25.0", "postcss": "^8.5.3", "rollup": "^4.30.1" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-IzwM54g4y9JA/xAeBPNaDXiBF8Jsgl3VBQ2YQ/wOY6fyW3xMdSoltIV3Bo59DErdqdE6RxUfv8W69DvUorE4Eg=="], - "@elizaos/autodoc/@types/node": ["@types/node@20.17.25", "", { "dependencies": { "undici-types": "~6.19.2" } }, "sha512-bT+r2haIlplJUYtlZrEanFHdPIZTeiMeh/fSOEbOOfWf9uTn+lg8g0KU6Q3iMgjd9FLuuMAgfCNSkjUbxL6E3Q=="], + "@elizaos/autodoc/@types/node": ["@types/node@20.17.27", "", { "dependencies": { "undici-types": "~6.19.2" } }, "sha512-U58sbKhDrthHlxHRJw7ZLiLDZGmAUOZUbpw0S6nL27sYUdhvgBLCRu/keSd6qcTsfArd1sRFCCBxzWATGr/0UA=="], - "@elizaos/cli/@types/node": ["@types/node@20.17.25", "", { "dependencies": { "undici-types": "~6.19.2" } }, "sha512-bT+r2haIlplJUYtlZrEanFHdPIZTeiMeh/fSOEbOOfWf9uTn+lg8g0KU6Q3iMgjd9FLuuMAgfCNSkjUbxL6E3Q=="], + "@elizaos/cli/@types/node": ["@types/node@20.17.27", "", { "dependencies": { "undici-types": "~6.19.2" } }, "sha512-U58sbKhDrthHlxHRJw7ZLiLDZGmAUOZUbpw0S6nL27sYUdhvgBLCRu/keSd6qcTsfArd1sRFCCBxzWATGr/0UA=="], - "@elizaos/client/vite": ["vite@6.2.2", "", { "dependencies": { "esbuild": "^0.25.0", "postcss": "^8.5.3", "rollup": "^4.30.1" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-yW7PeMM+LkDzc7CgJuRLMW2Jz0FxMOsVJ8Lv3gpgW9WLcb9cTW+121UEr1hvmfR7w3SegR5ItvYyzVz1vxNJgQ=="], + "@elizaos/client/vite": ["vite@6.2.3", "", { "dependencies": { "esbuild": "^0.25.0", "postcss": "^8.5.3", "rollup": "^4.30.1" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-IzwM54g4y9JA/xAeBPNaDXiBF8Jsgl3VBQ2YQ/wOY6fyW3xMdSoltIV3Bo59DErdqdE6RxUfv8W69DvUorE4Eg=="], "@elizaos/core/@eslint/js": ["@eslint/js@9.16.0", "", {}, "sha512-tw2HxzQkrbeuvyj1tG2Yqq+0H9wGoI2IMk4EOsQeX+vmd75FtJAzf+gTA69WF+baUKRYQ3x2kbLE08js5OsTVg=="], @@ -6192,7 +6236,7 @@ "@elizaos/plugin-storage-s3/glob": ["glob@11.0.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^4.0.1", "minimatch": "^10.0.0", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^2.0.0" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g=="], - "@elizaos/plugin-tee/@types/node": ["@types/node@20.17.25", "", { "dependencies": { "undici-types": "~6.19.2" } }, "sha512-bT+r2haIlplJUYtlZrEanFHdPIZTeiMeh/fSOEbOOfWf9uTn+lg8g0KU6Q3iMgjd9FLuuMAgfCNSkjUbxL6E3Q=="], + "@elizaos/plugin-tee/@types/node": ["@types/node@20.17.27", "", { "dependencies": { "undici-types": "~6.19.2" } }, "sha512-U58sbKhDrthHlxHRJw7ZLiLDZGmAUOZUbpw0S6nL27sYUdhvgBLCRu/keSd6qcTsfArd1sRFCCBxzWATGr/0UA=="], "@elizaos/plugin-twitter/@vitest/coverage-v8": ["@vitest/coverage-v8@1.1.3", "", { "dependencies": { "@ampproject/remapping": "^2.2.1", "@bcoe/v8-coverage": "^0.2.3", "debug": "^4.3.4", "istanbul-lib-coverage": "^3.2.2", "istanbul-lib-report": "^3.0.1", "istanbul-lib-source-maps": "^4.0.1", "istanbul-reports": "^3.1.6", "magic-string": "^0.30.5", "magicast": "^0.3.2", "picocolors": "^1.0.0", "std-env": "^3.5.0", "test-exclude": "^6.0.0", "v8-to-istanbul": "^9.2.0" }, "peerDependencies": { "vitest": "^1.0.0" } }, "sha512-Uput7t3eIcbSTOTQBzGtS+0kah96bX+szW9qQrLeGe3UmgL2Akn8POnyC2lH7XsnREZOds9aCUTxgXf+4HX5RA=="], @@ -6204,7 +6248,7 @@ "@elizaos/plugin-video-understanding/glob": ["glob@11.0.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^4.0.1", "minimatch": "^10.0.0", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^2.0.0" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g=="], - "@elizaos/the-org/@types/react": ["@types/react@18.3.19", "", { "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" } }, "sha512-fcdJqaHOMDbiAwJnXv6XCzX0jDW77yI3tJqYh1Byn8EL5/S628WRx9b/y3DnNe55zTukUQKrfYxiZls2dHcUMw=="], + "@elizaos/the-org/@types/react": ["@types/react@18.3.20", "", { "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" } }, "sha512-IPaCZN7PShZK/3t6Q87pfTkRm6oLTd4vztyoj+cbHUF1g3FfVb2tFIL79uCRKEfv16AhqDMBywP2VW3KIZUvcg=="], "@elizaos/the-org/@types/react-dom": ["@types/react-dom@18.3.5", "", { "peerDependencies": { "@types/react": "^18.0.0" } }, "sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q=="], @@ -6212,7 +6256,7 @@ "@elizaos/the-org/typescript": ["typescript@5.6.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw=="], - "@elizaos/the-org/vite": ["vite@6.2.2", "", { "dependencies": { "esbuild": "^0.25.0", "postcss": "^8.5.3", "rollup": "^4.30.1" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-yW7PeMM+LkDzc7CgJuRLMW2Jz0FxMOsVJ8Lv3gpgW9WLcb9cTW+121UEr1hvmfR7w3SegR5ItvYyzVz1vxNJgQ=="], + "@elizaos/the-org/vite": ["vite@6.2.3", "", { "dependencies": { "esbuild": "^0.25.0", "postcss": "^8.5.3", "rollup": "^4.30.1" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-IzwM54g4y9JA/xAeBPNaDXiBF8Jsgl3VBQ2YQ/wOY6fyW3xMdSoltIV3Bo59DErdqdE6RxUfv8W69DvUorE4Eg=="], "@elizaos/the-org/ws": ["ws@8.18.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw=="], @@ -6228,8 +6272,6 @@ "@eslint/eslintrc/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="], - "@huggingface/inference/@huggingface/tasks": ["@huggingface/tasks@0.17.9", "", {}, "sha512-lV6RgCJkqy3p93FFxP9H4SGJmFcHAwr1FO+Zk56q/JWsf7Tdsel1DEo1Xfd3An7ZPWpc2Y9ldRecGo9efDYghg=="], - "@humanfs/node/@humanwhocodes/retry": ["@humanwhocodes/retry@0.3.1", "", {}, "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA=="], "@isaacs/cliui/string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="], @@ -6382,7 +6424,7 @@ "@yarnpkg/parsers/js-yaml": ["js-yaml@3.14.1", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g=="], - "ai/@ai-sdk/ui-utils": ["@ai-sdk/ui-utils@1.2.0", "", { "dependencies": { "@ai-sdk/provider": "1.1.0", "@ai-sdk/provider-utils": "2.2.0", "zod-to-json-schema": "^3.24.1" }, "peerDependencies": { "zod": "^3.23.8" } }, "sha512-0IZwCqe7E+GkCASTDPAbzMr+POm9GDzWvFd37FvzpOeKNeibmge/LZEkTDbGSa+3b928H8wPwOLsOXBWPLUPDQ=="], + "ai/@ai-sdk/ui-utils": ["@ai-sdk/ui-utils@1.2.1", "", { "dependencies": { "@ai-sdk/provider": "1.1.0", "@ai-sdk/provider-utils": "2.2.1", "zod-to-json-schema": "^3.24.1" }, "peerDependencies": { "zod": "^3.23.8" } }, "sha512-BzvMbYm7LHBlbWuLlcG1jQh4eu14MGpz7L+wrGO1+F4oQ+O0fAjgUSNwPWGlZpKmg4NrcVq/QLmxiVJrx2R4Ew=="], "ansi-escapes/type-fest": ["type-fest@0.21.3", "", {}, "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w=="], @@ -6488,7 +6530,7 @@ "decamelize-keys/map-obj": ["map-obj@1.0.1", "", {}, "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg=="], - "default-gateway/execa": ["execa@5.0.0", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", "human-signals": "^2.1.0", "is-stream": "^2.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^4.0.1", "onetime": "^5.1.2", "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" } }, "sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ=="], + "default-gateway/execa": ["execa@5.1.1", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", "human-signals": "^2.1.0", "is-stream": "^2.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^4.0.1", "onetime": "^5.1.2", "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" } }, "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg=="], "degenerator/ast-types": ["ast-types@0.13.4", "", { "dependencies": { "tslib": "^2.0.1" } }, "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w=="], @@ -6584,6 +6626,8 @@ "fastembed/onnxruntime-node": ["onnxruntime-node@1.15.1", "", { "dependencies": { "onnxruntime-common": "~1.15.1" }, "os": [ "linux", "win32", "darwin", ] }, "sha512-wzhVELulmrvNoMZw0/HfV+9iwgHX+kPS82nxodZ37WCXmbeo1jp3thamTsNg8MGhxvv4GmEzRum5mo40oqIsqw=="], + "ffmpeg-static/https-proxy-agent": ["https-proxy-agent@5.0.1", "", { "dependencies": { "agent-base": "6", "debug": "4" } }, "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA=="], + "figures/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="], "file-loader/loader-utils": ["loader-utils@2.0.4", "", { "dependencies": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", "json5": "^2.1.2" } }, "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw=="], @@ -6618,6 +6662,8 @@ "gauge/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + "gel/env-paths": ["env-paths@3.0.0", "", {}, "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A=="], + "gel/which": ["which@4.0.0", "", { "dependencies": { "isexe": "^3.1.1" }, "bin": { "node-which": "bin/which.js" } }, "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg=="], "get-pkg-repo/hosted-git-info": ["hosted-git-info@4.1.0", "", { "dependencies": { "lru-cache": "^6.0.0" } }, "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA=="], @@ -6710,6 +6756,8 @@ "http-proxy-middleware/is-plain-obj": ["is-plain-obj@3.0.0", "", {}, "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA=="], + "http-response-object/@types/node": ["@types/node@10.17.60", "", {}, "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw=="], + "http2-wrapper/quick-lru": ["quick-lru@5.1.1", "", {}, "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA=="], "ignore-walk/minimatch": ["minimatch@5.1.6", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g=="], @@ -7032,8 +7080,6 @@ "node-fetch/whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="], - "node-gyp/env-paths": ["env-paths@2.2.1", "", {}, "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="], - "node-gyp/glob": ["glob@10.4.5", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg=="], "node-gyp/make-fetch-happen": ["make-fetch-happen@13.0.1", "", { "dependencies": { "@npmcli/agent": "^2.0.0", "cacache": "^18.0.0", "http-cache-semantics": "^4.1.1", "is-lambda": "^1.0.1", "minipass": "^7.0.2", "minipass-fetch": "^3.0.0", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "negotiator": "^0.6.3", "proc-log": "^4.2.0", "promise-retry": "^2.0.1", "ssri": "^10.0.0" } }, "sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA=="], @@ -7104,7 +7150,7 @@ "onnxruntime-web/onnxruntime-common": ["onnxruntime-common@1.22.0-dev.20250306-aafa8d170a", "", {}, "sha512-NfIQnW4lIk/8LnhnYqknYPeet0U0+AADgKQRlKex36QrNoVSCY+aNaX6wyy2VzQ4CNWxsYh0E203ajRD/zxn0g=="], - "openai/@types/node": ["@types/node@18.19.81", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-7KO9oZ2//ivtSsryp0LQUqq79zyGXzwq1WqfywpC9ucjY7YyltMMmxWgtRFRKCxwa7VPxVBVy4kHf5UC1E8Lug=="], + "openai/@types/node": ["@types/node@18.19.83", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-D69JeR5SfFS5H6FLbUaS0vE4r1dGhmMBbG4Ed6BNS4wkDK8GZjsdCShT5LCN59vOHEUHnFCY9J4aclXlIphMkA=="], "openai/formdata-node": ["formdata-node@4.4.1", "", { "dependencies": { "node-domexception": "1.0.0", "web-streams-polyfill": "4.0.0-beta.3" } }, "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ=="], @@ -7162,7 +7208,7 @@ "patchright/fsevents": ["fsevents@2.3.2", "", { "os": "darwin" }, "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA=="], - "path-scurry/lru-cache": ["lru-cache@11.0.2", "", {}, "sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA=="], + "path-scurry/lru-cache": ["lru-cache@11.1.0", "", {}, "sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A=="], "pg/pg-types": ["pg-types@2.2.0", "", { "dependencies": { "pg-int8": "1.0.1", "postgres-array": "~2.0.0", "postgres-bytea": "~1.0.0", "postgres-date": "~1.0.4", "postgres-interval": "^1.1.0" } }, "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA=="], @@ -7470,15 +7516,15 @@ "ts-node/diff": ["diff@4.0.2", "", {}, "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A=="], - "tsup/rollup": ["rollup@4.36.0", "", { "dependencies": { "@types/estree": "1.0.6" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.36.0", "@rollup/rollup-android-arm64": "4.36.0", "@rollup/rollup-darwin-arm64": "4.36.0", "@rollup/rollup-darwin-x64": "4.36.0", "@rollup/rollup-freebsd-arm64": "4.36.0", "@rollup/rollup-freebsd-x64": "4.36.0", "@rollup/rollup-linux-arm-gnueabihf": "4.36.0", "@rollup/rollup-linux-arm-musleabihf": "4.36.0", "@rollup/rollup-linux-arm64-gnu": "4.36.0", "@rollup/rollup-linux-arm64-musl": "4.36.0", "@rollup/rollup-linux-loongarch64-gnu": "4.36.0", "@rollup/rollup-linux-powerpc64le-gnu": "4.36.0", "@rollup/rollup-linux-riscv64-gnu": "4.36.0", "@rollup/rollup-linux-s390x-gnu": "4.36.0", "@rollup/rollup-linux-x64-gnu": "4.36.0", "@rollup/rollup-linux-x64-musl": "4.36.0", "@rollup/rollup-win32-arm64-msvc": "4.36.0", "@rollup/rollup-win32-ia32-msvc": "4.36.0", "@rollup/rollup-win32-x64-msvc": "4.36.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-zwATAXNQxUcd40zgtQG0ZafcRK4g004WtEl7kbuhTWPvf07PsfohXl39jVUvPF7jvNAIkKPQ2XrsDlWuxBd++Q=="], + "tsup/rollup": ["rollup@4.37.0", "", { "dependencies": { "@types/estree": "1.0.6" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.37.0", "@rollup/rollup-android-arm64": "4.37.0", "@rollup/rollup-darwin-arm64": "4.37.0", "@rollup/rollup-darwin-x64": "4.37.0", "@rollup/rollup-freebsd-arm64": "4.37.0", "@rollup/rollup-freebsd-x64": "4.37.0", "@rollup/rollup-linux-arm-gnueabihf": "4.37.0", "@rollup/rollup-linux-arm-musleabihf": "4.37.0", "@rollup/rollup-linux-arm64-gnu": "4.37.0", "@rollup/rollup-linux-arm64-musl": "4.37.0", "@rollup/rollup-linux-loongarch64-gnu": "4.37.0", "@rollup/rollup-linux-powerpc64le-gnu": "4.37.0", "@rollup/rollup-linux-riscv64-gnu": "4.37.0", "@rollup/rollup-linux-riscv64-musl": "4.37.0", "@rollup/rollup-linux-s390x-gnu": "4.37.0", "@rollup/rollup-linux-x64-gnu": "4.37.0", "@rollup/rollup-linux-x64-musl": "4.37.0", "@rollup/rollup-win32-arm64-msvc": "4.37.0", "@rollup/rollup-win32-ia32-msvc": "4.37.0", "@rollup/rollup-win32-x64-msvc": "4.37.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-iAtQy/L4QFU+rTJ1YUjXqJOJzuwEghqWzCEYD2FEghT7Gsy1VdABntrO4CLopA5IkflTyqNiLNwPcOJ3S7UKLg=="], "typedoc/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], - "typescript-eslint/@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.27.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.27.0", "@typescript-eslint/type-utils": "8.27.0", "@typescript-eslint/utils": "8.27.0", "@typescript-eslint/visitor-keys": "8.27.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-4henw4zkePi5p252c8ncBLzLce52SEUz2Ebj8faDnuUXz2UuHEONYcJ+G0oaCF+bYCWVZtrGzq3FD7YXetmnSA=="], + "typescript-eslint/@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.28.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.28.0", "@typescript-eslint/type-utils": "8.28.0", "@typescript-eslint/utils": "8.28.0", "@typescript-eslint/visitor-keys": "8.28.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-lvFK3TCGAHsItNdWZ/1FkvpzCxTHUVuFrdnOGLMa0GGCFIbCgQWVk3CzCGdA7kM3qGVc+dfW9tr0Z/sHnGDFyg=="], - "typescript-eslint/@typescript-eslint/parser": ["@typescript-eslint/parser@8.27.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.27.0", "@typescript-eslint/types": "8.27.0", "@typescript-eslint/typescript-estree": "8.27.0", "@typescript-eslint/visitor-keys": "8.27.0", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-XGwIabPallYipmcOk45DpsBSgLC64A0yvdAkrwEzwZ2viqGqRUJ8eEYoPz0CWnutgAFbNMPdsGGvzjSmcWVlEA=="], + "typescript-eslint/@typescript-eslint/parser": ["@typescript-eslint/parser@8.28.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.28.0", "@typescript-eslint/types": "8.28.0", "@typescript-eslint/typescript-estree": "8.28.0", "@typescript-eslint/visitor-keys": "8.28.0", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-LPcw1yHD3ToaDEoljFEfQ9j2xShY367h7FZ1sq5NJT9I3yj4LHer1Xd1yRSOdYy9BpsrxU7R+eoDokChYM53lQ=="], - "typescript-eslint/@typescript-eslint/utils": ["@typescript-eslint/utils@8.27.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@typescript-eslint/scope-manager": "8.27.0", "@typescript-eslint/types": "8.27.0", "@typescript-eslint/typescript-estree": "8.27.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-njkodcwH1yvmo31YWgRHNb/x1Xhhq4/m81PhtvmRngD8iHPehxffz1SNCO+kwaePhATC+kOa/ggmvPoPza5i0Q=="], + "typescript-eslint/@typescript-eslint/utils": ["@typescript-eslint/utils@8.28.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@typescript-eslint/scope-manager": "8.28.0", "@typescript-eslint/types": "8.28.0", "@typescript-eslint/typescript-estree": "8.28.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-OELa9hbTYciYITqgurT1u/SzpQVtDLmQMFzy/N8pQE+tefOyCWT79jHsav294aTqV1q1u+VzqDGbuujvRYaeSQ=="], "unified/vfile": ["vfile@4.2.1", "", { "dependencies": { "@types/unist": "^2.0.0", "is-buffer": "^2.0.0", "unist-util-stringify-position": "^2.0.0", "vfile-message": "^2.0.0" } }, "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA=="], @@ -7504,13 +7550,13 @@ "vite/esbuild": ["esbuild@0.21.5", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.21.5", "@esbuild/android-arm": "0.21.5", "@esbuild/android-arm64": "0.21.5", "@esbuild/android-x64": "0.21.5", "@esbuild/darwin-arm64": "0.21.5", "@esbuild/darwin-x64": "0.21.5", "@esbuild/freebsd-arm64": "0.21.5", "@esbuild/freebsd-x64": "0.21.5", "@esbuild/linux-arm": "0.21.5", "@esbuild/linux-arm64": "0.21.5", "@esbuild/linux-ia32": "0.21.5", "@esbuild/linux-loong64": "0.21.5", "@esbuild/linux-mips64el": "0.21.5", "@esbuild/linux-ppc64": "0.21.5", "@esbuild/linux-riscv64": "0.21.5", "@esbuild/linux-s390x": "0.21.5", "@esbuild/linux-x64": "0.21.5", "@esbuild/netbsd-x64": "0.21.5", "@esbuild/openbsd-x64": "0.21.5", "@esbuild/sunos-x64": "0.21.5", "@esbuild/win32-arm64": "0.21.5", "@esbuild/win32-ia32": "0.21.5", "@esbuild/win32-x64": "0.21.5" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw=="], - "vite/rollup": ["rollup@4.36.0", "", { "dependencies": { "@types/estree": "1.0.6" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.36.0", "@rollup/rollup-android-arm64": "4.36.0", "@rollup/rollup-darwin-arm64": "4.36.0", "@rollup/rollup-darwin-x64": "4.36.0", "@rollup/rollup-freebsd-arm64": "4.36.0", "@rollup/rollup-freebsd-x64": "4.36.0", "@rollup/rollup-linux-arm-gnueabihf": "4.36.0", "@rollup/rollup-linux-arm-musleabihf": "4.36.0", "@rollup/rollup-linux-arm64-gnu": "4.36.0", "@rollup/rollup-linux-arm64-musl": "4.36.0", "@rollup/rollup-linux-loongarch64-gnu": "4.36.0", "@rollup/rollup-linux-powerpc64le-gnu": "4.36.0", "@rollup/rollup-linux-riscv64-gnu": "4.36.0", "@rollup/rollup-linux-s390x-gnu": "4.36.0", "@rollup/rollup-linux-x64-gnu": "4.36.0", "@rollup/rollup-linux-x64-musl": "4.36.0", "@rollup/rollup-win32-arm64-msvc": "4.36.0", "@rollup/rollup-win32-ia32-msvc": "4.36.0", "@rollup/rollup-win32-x64-msvc": "4.36.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-zwATAXNQxUcd40zgtQG0ZafcRK4g004WtEl7kbuhTWPvf07PsfohXl39jVUvPF7jvNAIkKPQ2XrsDlWuxBd++Q=="], + "vite/rollup": ["rollup@4.37.0", "", { "dependencies": { "@types/estree": "1.0.6" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.37.0", "@rollup/rollup-android-arm64": "4.37.0", "@rollup/rollup-darwin-arm64": "4.37.0", "@rollup/rollup-darwin-x64": "4.37.0", "@rollup/rollup-freebsd-arm64": "4.37.0", "@rollup/rollup-freebsd-x64": "4.37.0", "@rollup/rollup-linux-arm-gnueabihf": "4.37.0", "@rollup/rollup-linux-arm-musleabihf": "4.37.0", "@rollup/rollup-linux-arm64-gnu": "4.37.0", "@rollup/rollup-linux-arm64-musl": "4.37.0", "@rollup/rollup-linux-loongarch64-gnu": "4.37.0", "@rollup/rollup-linux-powerpc64le-gnu": "4.37.0", "@rollup/rollup-linux-riscv64-gnu": "4.37.0", "@rollup/rollup-linux-riscv64-musl": "4.37.0", "@rollup/rollup-linux-s390x-gnu": "4.37.0", "@rollup/rollup-linux-x64-gnu": "4.37.0", "@rollup/rollup-linux-x64-musl": "4.37.0", "@rollup/rollup-win32-arm64-msvc": "4.37.0", "@rollup/rollup-win32-ia32-msvc": "4.37.0", "@rollup/rollup-win32-x64-msvc": "4.37.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-iAtQy/L4QFU+rTJ1YUjXqJOJzuwEghqWzCEYD2FEghT7Gsy1VdABntrO4CLopA5IkflTyqNiLNwPcOJ3S7UKLg=="], - "vite-node/vite": ["vite@6.2.2", "", { "dependencies": { "esbuild": "^0.25.0", "postcss": "^8.5.3", "rollup": "^4.30.1" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-yW7PeMM+LkDzc7CgJuRLMW2Jz0FxMOsVJ8Lv3gpgW9WLcb9cTW+121UEr1hvmfR7w3SegR5ItvYyzVz1vxNJgQ=="], + "vite-node/vite": ["vite@6.2.3", "", { "dependencies": { "esbuild": "^0.25.0", "postcss": "^8.5.3", "rollup": "^4.30.1" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-IzwM54g4y9JA/xAeBPNaDXiBF8Jsgl3VBQ2YQ/wOY6fyW3xMdSoltIV3Bo59DErdqdE6RxUfv8W69DvUorE4Eg=="], "vite-plugin-compression/fs-extra": ["fs-extra@10.1.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ=="], - "vitest/vite": ["vite@6.2.2", "", { "dependencies": { "esbuild": "^0.25.0", "postcss": "^8.5.3", "rollup": "^4.30.1" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-yW7PeMM+LkDzc7CgJuRLMW2Jz0FxMOsVJ8Lv3gpgW9WLcb9cTW+121UEr1hvmfR7w3SegR5ItvYyzVz1vxNJgQ=="], + "vitest/vite": ["vite@6.2.3", "", { "dependencies": { "esbuild": "^0.25.0", "postcss": "^8.5.3", "rollup": "^4.30.1" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-IzwM54g4y9JA/xAeBPNaDXiBF8Jsgl3VBQ2YQ/wOY6fyW3xMdSoltIV3Bo59DErdqdE6RxUfv8W69DvUorE4Eg=="], "vizion/async": ["async@2.6.4", "", { "dependencies": { "lodash": "^4.17.14" } }, "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA=="], @@ -7594,13 +7640,13 @@ "@docusaurus/theme-classic/react-router-dom/react-router": ["react-router@5.3.4", "", { "dependencies": { "@babel/runtime": "^7.12.13", "history": "^4.9.0", "hoist-non-react-statics": "^3.1.0", "loose-envify": "^1.3.1", "path-to-regexp": "^1.7.0", "prop-types": "^15.6.2", "react-is": "^16.6.0", "tiny-invariant": "^1.0.2", "tiny-warning": "^1.0.0" }, "peerDependencies": { "react": ">=15" } }, "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA=="], - "@elizaos/app/vite/rollup": ["rollup@4.36.0", "", { "dependencies": { "@types/estree": "1.0.6" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.36.0", "@rollup/rollup-android-arm64": "4.36.0", "@rollup/rollup-darwin-arm64": "4.36.0", "@rollup/rollup-darwin-x64": "4.36.0", "@rollup/rollup-freebsd-arm64": "4.36.0", "@rollup/rollup-freebsd-x64": "4.36.0", "@rollup/rollup-linux-arm-gnueabihf": "4.36.0", "@rollup/rollup-linux-arm-musleabihf": "4.36.0", "@rollup/rollup-linux-arm64-gnu": "4.36.0", "@rollup/rollup-linux-arm64-musl": "4.36.0", "@rollup/rollup-linux-loongarch64-gnu": "4.36.0", "@rollup/rollup-linux-powerpc64le-gnu": "4.36.0", "@rollup/rollup-linux-riscv64-gnu": "4.36.0", "@rollup/rollup-linux-s390x-gnu": "4.36.0", "@rollup/rollup-linux-x64-gnu": "4.36.0", "@rollup/rollup-linux-x64-musl": "4.36.0", "@rollup/rollup-win32-arm64-msvc": "4.36.0", "@rollup/rollup-win32-ia32-msvc": "4.36.0", "@rollup/rollup-win32-x64-msvc": "4.36.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-zwATAXNQxUcd40zgtQG0ZafcRK4g004WtEl7kbuhTWPvf07PsfohXl39jVUvPF7jvNAIkKPQ2XrsDlWuxBd++Q=="], + "@elizaos/app/vite/rollup": ["rollup@4.37.0", "", { "dependencies": { "@types/estree": "1.0.6" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.37.0", "@rollup/rollup-android-arm64": "4.37.0", "@rollup/rollup-darwin-arm64": "4.37.0", "@rollup/rollup-darwin-x64": "4.37.0", "@rollup/rollup-freebsd-arm64": "4.37.0", "@rollup/rollup-freebsd-x64": "4.37.0", "@rollup/rollup-linux-arm-gnueabihf": "4.37.0", "@rollup/rollup-linux-arm-musleabihf": "4.37.0", "@rollup/rollup-linux-arm64-gnu": "4.37.0", "@rollup/rollup-linux-arm64-musl": "4.37.0", "@rollup/rollup-linux-loongarch64-gnu": "4.37.0", "@rollup/rollup-linux-powerpc64le-gnu": "4.37.0", "@rollup/rollup-linux-riscv64-gnu": "4.37.0", "@rollup/rollup-linux-riscv64-musl": "4.37.0", "@rollup/rollup-linux-s390x-gnu": "4.37.0", "@rollup/rollup-linux-x64-gnu": "4.37.0", "@rollup/rollup-linux-x64-musl": "4.37.0", "@rollup/rollup-win32-arm64-msvc": "4.37.0", "@rollup/rollup-win32-ia32-msvc": "4.37.0", "@rollup/rollup-win32-x64-msvc": "4.37.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-iAtQy/L4QFU+rTJ1YUjXqJOJzuwEghqWzCEYD2FEghT7Gsy1VdABntrO4CLopA5IkflTyqNiLNwPcOJ3S7UKLg=="], "@elizaos/autodoc/@types/node/undici-types": ["undici-types@6.19.8", "", {}, "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="], "@elizaos/cli/@types/node/undici-types": ["undici-types@6.19.8", "", {}, "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="], - "@elizaos/client/vite/rollup": ["rollup@4.36.0", "", { "dependencies": { "@types/estree": "1.0.6" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.36.0", "@rollup/rollup-android-arm64": "4.36.0", "@rollup/rollup-darwin-arm64": "4.36.0", "@rollup/rollup-darwin-x64": "4.36.0", "@rollup/rollup-freebsd-arm64": "4.36.0", "@rollup/rollup-freebsd-x64": "4.36.0", "@rollup/rollup-linux-arm-gnueabihf": "4.36.0", "@rollup/rollup-linux-arm-musleabihf": "4.36.0", "@rollup/rollup-linux-arm64-gnu": "4.36.0", "@rollup/rollup-linux-arm64-musl": "4.36.0", "@rollup/rollup-linux-loongarch64-gnu": "4.36.0", "@rollup/rollup-linux-powerpc64le-gnu": "4.36.0", "@rollup/rollup-linux-riscv64-gnu": "4.36.0", "@rollup/rollup-linux-s390x-gnu": "4.36.0", "@rollup/rollup-linux-x64-gnu": "4.36.0", "@rollup/rollup-linux-x64-musl": "4.36.0", "@rollup/rollup-win32-arm64-msvc": "4.36.0", "@rollup/rollup-win32-ia32-msvc": "4.36.0", "@rollup/rollup-win32-x64-msvc": "4.36.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-zwATAXNQxUcd40zgtQG0ZafcRK4g004WtEl7kbuhTWPvf07PsfohXl39jVUvPF7jvNAIkKPQ2XrsDlWuxBd++Q=="], + "@elizaos/client/vite/rollup": ["rollup@4.37.0", "", { "dependencies": { "@types/estree": "1.0.6" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.37.0", "@rollup/rollup-android-arm64": "4.37.0", "@rollup/rollup-darwin-arm64": "4.37.0", "@rollup/rollup-darwin-x64": "4.37.0", "@rollup/rollup-freebsd-arm64": "4.37.0", "@rollup/rollup-freebsd-x64": "4.37.0", "@rollup/rollup-linux-arm-gnueabihf": "4.37.0", "@rollup/rollup-linux-arm-musleabihf": "4.37.0", "@rollup/rollup-linux-arm64-gnu": "4.37.0", "@rollup/rollup-linux-arm64-musl": "4.37.0", "@rollup/rollup-linux-loongarch64-gnu": "4.37.0", "@rollup/rollup-linux-powerpc64le-gnu": "4.37.0", "@rollup/rollup-linux-riscv64-gnu": "4.37.0", "@rollup/rollup-linux-riscv64-musl": "4.37.0", "@rollup/rollup-linux-s390x-gnu": "4.37.0", "@rollup/rollup-linux-x64-gnu": "4.37.0", "@rollup/rollup-linux-x64-musl": "4.37.0", "@rollup/rollup-win32-arm64-msvc": "4.37.0", "@rollup/rollup-win32-ia32-msvc": "4.37.0", "@rollup/rollup-win32-x64-msvc": "4.37.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-iAtQy/L4QFU+rTJ1YUjXqJOJzuwEghqWzCEYD2FEghT7Gsy1VdABntrO4CLopA5IkflTyqNiLNwPcOJ3S7UKLg=="], "@elizaos/core/glob/minimatch": ["minimatch@10.0.1", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ=="], @@ -7620,7 +7666,7 @@ "@elizaos/plugin-evm/tsup/esbuild": ["esbuild@0.24.2", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.24.2", "@esbuild/android-arm": "0.24.2", "@esbuild/android-arm64": "0.24.2", "@esbuild/android-x64": "0.24.2", "@esbuild/darwin-arm64": "0.24.2", "@esbuild/darwin-x64": "0.24.2", "@esbuild/freebsd-arm64": "0.24.2", "@esbuild/freebsd-x64": "0.24.2", "@esbuild/linux-arm": "0.24.2", "@esbuild/linux-arm64": "0.24.2", "@esbuild/linux-ia32": "0.24.2", "@esbuild/linux-loong64": "0.24.2", "@esbuild/linux-mips64el": "0.24.2", "@esbuild/linux-ppc64": "0.24.2", "@esbuild/linux-riscv64": "0.24.2", "@esbuild/linux-s390x": "0.24.2", "@esbuild/linux-x64": "0.24.2", "@esbuild/netbsd-arm64": "0.24.2", "@esbuild/netbsd-x64": "0.24.2", "@esbuild/openbsd-arm64": "0.24.2", "@esbuild/openbsd-x64": "0.24.2", "@esbuild/sunos-x64": "0.24.2", "@esbuild/win32-arm64": "0.24.2", "@esbuild/win32-ia32": "0.24.2", "@esbuild/win32-x64": "0.24.2" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA=="], - "@elizaos/plugin-evm/tsup/rollup": ["rollup@4.36.0", "", { "dependencies": { "@types/estree": "1.0.6" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.36.0", "@rollup/rollup-android-arm64": "4.36.0", "@rollup/rollup-darwin-arm64": "4.36.0", "@rollup/rollup-darwin-x64": "4.36.0", "@rollup/rollup-freebsd-arm64": "4.36.0", "@rollup/rollup-freebsd-x64": "4.36.0", "@rollup/rollup-linux-arm-gnueabihf": "4.36.0", "@rollup/rollup-linux-arm-musleabihf": "4.36.0", "@rollup/rollup-linux-arm64-gnu": "4.36.0", "@rollup/rollup-linux-arm64-musl": "4.36.0", "@rollup/rollup-linux-loongarch64-gnu": "4.36.0", "@rollup/rollup-linux-powerpc64le-gnu": "4.36.0", "@rollup/rollup-linux-riscv64-gnu": "4.36.0", "@rollup/rollup-linux-s390x-gnu": "4.36.0", "@rollup/rollup-linux-x64-gnu": "4.36.0", "@rollup/rollup-linux-x64-musl": "4.36.0", "@rollup/rollup-win32-arm64-msvc": "4.36.0", "@rollup/rollup-win32-ia32-msvc": "4.36.0", "@rollup/rollup-win32-x64-msvc": "4.36.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-zwATAXNQxUcd40zgtQG0ZafcRK4g004WtEl7kbuhTWPvf07PsfohXl39jVUvPF7jvNAIkKPQ2XrsDlWuxBd++Q=="], + "@elizaos/plugin-evm/tsup/rollup": ["rollup@4.37.0", "", { "dependencies": { "@types/estree": "1.0.6" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.37.0", "@rollup/rollup-android-arm64": "4.37.0", "@rollup/rollup-darwin-arm64": "4.37.0", "@rollup/rollup-darwin-x64": "4.37.0", "@rollup/rollup-freebsd-arm64": "4.37.0", "@rollup/rollup-freebsd-x64": "4.37.0", "@rollup/rollup-linux-arm-gnueabihf": "4.37.0", "@rollup/rollup-linux-arm-musleabihf": "4.37.0", "@rollup/rollup-linux-arm64-gnu": "4.37.0", "@rollup/rollup-linux-arm64-musl": "4.37.0", "@rollup/rollup-linux-loongarch64-gnu": "4.37.0", "@rollup/rollup-linux-powerpc64le-gnu": "4.37.0", "@rollup/rollup-linux-riscv64-gnu": "4.37.0", "@rollup/rollup-linux-riscv64-musl": "4.37.0", "@rollup/rollup-linux-s390x-gnu": "4.37.0", "@rollup/rollup-linux-x64-gnu": "4.37.0", "@rollup/rollup-linux-x64-musl": "4.37.0", "@rollup/rollup-win32-arm64-msvc": "4.37.0", "@rollup/rollup-win32-ia32-msvc": "4.37.0", "@rollup/rollup-win32-x64-msvc": "4.37.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-iAtQy/L4QFU+rTJ1YUjXqJOJzuwEghqWzCEYD2FEghT7Gsy1VdABntrO4CLopA5IkflTyqNiLNwPcOJ3S7UKLg=="], "@elizaos/plugin-local-ai/glob/minimatch": ["minimatch@10.0.1", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ=="], @@ -7648,7 +7694,7 @@ "@elizaos/plugin-video-understanding/glob/minimatch": ["minimatch@10.0.1", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ=="], - "@elizaos/the-org/vite/rollup": ["rollup@4.36.0", "", { "dependencies": { "@types/estree": "1.0.6" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.36.0", "@rollup/rollup-android-arm64": "4.36.0", "@rollup/rollup-darwin-arm64": "4.36.0", "@rollup/rollup-darwin-x64": "4.36.0", "@rollup/rollup-freebsd-arm64": "4.36.0", "@rollup/rollup-freebsd-x64": "4.36.0", "@rollup/rollup-linux-arm-gnueabihf": "4.36.0", "@rollup/rollup-linux-arm-musleabihf": "4.36.0", "@rollup/rollup-linux-arm64-gnu": "4.36.0", "@rollup/rollup-linux-arm64-musl": "4.36.0", "@rollup/rollup-linux-loongarch64-gnu": "4.36.0", "@rollup/rollup-linux-powerpc64le-gnu": "4.36.0", "@rollup/rollup-linux-riscv64-gnu": "4.36.0", "@rollup/rollup-linux-s390x-gnu": "4.36.0", "@rollup/rollup-linux-x64-gnu": "4.36.0", "@rollup/rollup-linux-x64-musl": "4.36.0", "@rollup/rollup-win32-arm64-msvc": "4.36.0", "@rollup/rollup-win32-ia32-msvc": "4.36.0", "@rollup/rollup-win32-x64-msvc": "4.36.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-zwATAXNQxUcd40zgtQG0ZafcRK4g004WtEl7kbuhTWPvf07PsfohXl39jVUvPF7jvNAIkKPQ2XrsDlWuxBd++Q=="], + "@elizaos/the-org/vite/rollup": ["rollup@4.37.0", "", { "dependencies": { "@types/estree": "1.0.6" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.37.0", "@rollup/rollup-android-arm64": "4.37.0", "@rollup/rollup-darwin-arm64": "4.37.0", "@rollup/rollup-darwin-x64": "4.37.0", "@rollup/rollup-freebsd-arm64": "4.37.0", "@rollup/rollup-freebsd-x64": "4.37.0", "@rollup/rollup-linux-arm-gnueabihf": "4.37.0", "@rollup/rollup-linux-arm-musleabihf": "4.37.0", "@rollup/rollup-linux-arm64-gnu": "4.37.0", "@rollup/rollup-linux-arm64-musl": "4.37.0", "@rollup/rollup-linux-loongarch64-gnu": "4.37.0", "@rollup/rollup-linux-powerpc64le-gnu": "4.37.0", "@rollup/rollup-linux-riscv64-gnu": "4.37.0", "@rollup/rollup-linux-riscv64-musl": "4.37.0", "@rollup/rollup-linux-s390x-gnu": "4.37.0", "@rollup/rollup-linux-x64-gnu": "4.37.0", "@rollup/rollup-linux-x64-musl": "4.37.0", "@rollup/rollup-win32-arm64-msvc": "4.37.0", "@rollup/rollup-win32-ia32-msvc": "4.37.0", "@rollup/rollup-win32-x64-msvc": "4.37.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-iAtQy/L4QFU+rTJ1YUjXqJOJzuwEghqWzCEYD2FEghT7Gsy1VdABntrO4CLopA5IkflTyqNiLNwPcOJ3S7UKLg=="], "@esbuild-kit/core-utils/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.18.20", "", { "os": "android", "cpu": "arm" }, "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw=="], @@ -7840,8 +7886,6 @@ "cytoscape-fcose/cose-base/layout-base": ["layout-base@2.0.1", "", {}, "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg=="], - "d3-sankey/d3-array/internmap": ["internmap@1.0.1", "", {}, "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw=="], - "d3-sankey/d3-shape/d3-path": ["d3-path@1.0.9", "", {}, "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg=="], "debug-logfmt/pretty-ms/parse-ms": ["parse-ms@2.1.0", "", {}, "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA=="], @@ -7924,6 +7968,8 @@ "fastembed/onnxruntime-node/onnxruntime-common": ["onnxruntime-common@1.15.1", "", {}, "sha512-Y89eJ8QmaRsPZPWLaX7mfqhj63ny47rSkQe80hIo+lvBQdrdXYR9VO362xvZulk9DFkCnXmGidprvgJ07bKsIQ=="], + "ffmpeg-static/https-proxy-agent/agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="], + "file-loader/schema-utils/ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="], "file-loader/schema-utils/ajv-keywords": ["ajv-keywords@3.5.2", "", { "peerDependencies": { "ajv": "^6.9.1" } }, "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ=="], @@ -8018,7 +8064,7 @@ "ipull/pretty-ms/parse-ms": ["parse-ms@3.0.0", "", {}, "sha512-Tpb8Z7r7XbbtBTrM9UhpkzzaMrqA2VXMT3YChzYltwV3P3pM6t8wl7TvpMnSTosz1aQAdVib7kdoys7vYOPerw=="], - "jayson/@types/ws/@types/node": ["@types/node@22.13.11", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-iEUCUJoU0i3VnrCmgoWCXttklWcvoCIx4jzcP22fioIVSdTmjgoEvmAO/QPw6TcS9k5FrNgn4w7q5lGOd1CT5g=="], + "jayson/@types/ws/@types/node": ["@types/node@22.13.13", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-ClsL5nMwKaBRwPcCvH8E7+nU4GxHVx1axNvMZTFHMEfNI7oahimt26P5zjVCRrjiIWj6YFXfE1v3dEp94wLcGQ=="], "lerna/@octokit/rest/@octokit/core": ["@octokit/core@4.2.4", "", { "dependencies": { "@octokit/auth-token": "^3.0.0", "@octokit/graphql": "^5.0.0", "@octokit/request": "^6.0.0", "@octokit/request-error": "^3.0.0", "@octokit/types": "^9.0.0", "before-after-hook": "^2.2.0", "universal-user-agent": "^6.0.0" } }, "sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ=="], @@ -8512,27 +8558,29 @@ "to-vfile/vfile/vfile-message": ["vfile-message@2.0.4", "", { "dependencies": { "@types/unist": "^2.0.0", "unist-util-stringify-position": "^2.0.0" } }, "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ=="], + "tsup/rollup/@types/estree": ["@types/estree@1.0.6", "", {}, "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="], + "typedoc/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="], - "typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.27.0", "", { "dependencies": { "@typescript-eslint/types": "8.27.0", "@typescript-eslint/visitor-keys": "8.27.0" } }, "sha512-8oI9GwPMQmBryaaxG1tOZdxXVeMDte6NyJA4i7/TWa4fBwgnAXYlIQP+uYOeqAaLJ2JRxlG9CAyL+C+YE9Xknw=="], + "typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.28.0", "", { "dependencies": { "@typescript-eslint/types": "8.28.0", "@typescript-eslint/visitor-keys": "8.28.0" } }, "sha512-u2oITX3BJwzWCapoZ/pXw6BCOl8rJP4Ij/3wPoGvY8XwvXflOzd1kLrDUUUAIEdJSFh+ASwdTHqtan9xSg8buw=="], - "typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.27.0", "", { "dependencies": { "@typescript-eslint/typescript-estree": "8.27.0", "@typescript-eslint/utils": "8.27.0", "debug": "^4.3.4", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-wVArTVcz1oJOIEJxui/nRhV0TXzD/zMSOYi/ggCfNq78EIszddXcJb7r4RCp/oBrjt8n9A0BSxRMKxHftpDxDA=="], + "typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.28.0", "", { "dependencies": { "@typescript-eslint/typescript-estree": "8.28.0", "@typescript-eslint/utils": "8.28.0", "debug": "^4.3.4", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-oRoXu2v0Rsy/VoOGhtWrOKDiIehvI+YNrDk5Oqj40Mwm0Yt01FC/Q7nFqg088d3yAsR1ZcZFVfPCTTFCe/KPwg=="], - "typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.27.0", "", { "dependencies": { "@typescript-eslint/types": "8.27.0", "eslint-visitor-keys": "^4.2.0" } }, "sha512-WsXQwMkILJvffP6z4U3FYJPlbf/j07HIxmDjZpbNvBJkMfvwXj5ACRkkHwBDvLBbDbtX5TdU64/rcvKJ/vuInQ=="], + "typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.28.0", "", { "dependencies": { "@typescript-eslint/types": "8.28.0", "eslint-visitor-keys": "^4.2.0" } }, "sha512-hbn8SZ8w4u2pRwgQ1GlUrPKE+t2XvcCW5tTRF7j6SMYIuYG37XuzIW44JCZPa36evi0Oy2SnM664BlIaAuQcvg=="], - "typescript-eslint/@typescript-eslint/parser/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.27.0", "", { "dependencies": { "@typescript-eslint/types": "8.27.0", "@typescript-eslint/visitor-keys": "8.27.0" } }, "sha512-8oI9GwPMQmBryaaxG1tOZdxXVeMDte6NyJA4i7/TWa4fBwgnAXYlIQP+uYOeqAaLJ2JRxlG9CAyL+C+YE9Xknw=="], + "typescript-eslint/@typescript-eslint/parser/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.28.0", "", { "dependencies": { "@typescript-eslint/types": "8.28.0", "@typescript-eslint/visitor-keys": "8.28.0" } }, "sha512-u2oITX3BJwzWCapoZ/pXw6BCOl8rJP4Ij/3wPoGvY8XwvXflOzd1kLrDUUUAIEdJSFh+ASwdTHqtan9xSg8buw=="], - "typescript-eslint/@typescript-eslint/parser/@typescript-eslint/types": ["@typescript-eslint/types@8.27.0", "", {}, "sha512-/6cp9yL72yUHAYq9g6DsAU+vVfvQmd1a8KyA81uvfDE21O2DwQ/qxlM4AR8TSdAu+kJLBDrEHKC5/W2/nxsY0A=="], + "typescript-eslint/@typescript-eslint/parser/@typescript-eslint/types": ["@typescript-eslint/types@8.28.0", "", {}, "sha512-bn4WS1bkKEjx7HqiwG2JNB3YJdC1q6Ue7GyGlwPHyt0TnVq6TtD/hiOdTZt71sq0s7UzqBFXD8t8o2e63tXgwA=="], - "typescript-eslint/@typescript-eslint/parser/@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.27.0", "", { "dependencies": { "@typescript-eslint/types": "8.27.0", "@typescript-eslint/visitor-keys": "8.27.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "sha512-BnKq8cqPVoMw71O38a1tEb6iebEgGA80icSxW7g+kndx0o6ot6696HjG7NdgfuAVmVEtwXUr3L8R9ZuVjoQL6A=="], + "typescript-eslint/@typescript-eslint/parser/@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.28.0", "", { "dependencies": { "@typescript-eslint/types": "8.28.0", "@typescript-eslint/visitor-keys": "8.28.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "sha512-H74nHEeBGeklctAVUvmDkxB1mk+PAZ9FiOMPFncdqeRBXxk1lWSYraHw8V12b7aa6Sg9HOBNbGdSHobBPuQSuA=="], - "typescript-eslint/@typescript-eslint/parser/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.27.0", "", { "dependencies": { "@typescript-eslint/types": "8.27.0", "eslint-visitor-keys": "^4.2.0" } }, "sha512-WsXQwMkILJvffP6z4U3FYJPlbf/j07HIxmDjZpbNvBJkMfvwXj5ACRkkHwBDvLBbDbtX5TdU64/rcvKJ/vuInQ=="], + "typescript-eslint/@typescript-eslint/parser/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.28.0", "", { "dependencies": { "@typescript-eslint/types": "8.28.0", "eslint-visitor-keys": "^4.2.0" } }, "sha512-hbn8SZ8w4u2pRwgQ1GlUrPKE+t2XvcCW5tTRF7j6SMYIuYG37XuzIW44JCZPa36evi0Oy2SnM664BlIaAuQcvg=="], - "typescript-eslint/@typescript-eslint/utils/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.27.0", "", { "dependencies": { "@typescript-eslint/types": "8.27.0", "@typescript-eslint/visitor-keys": "8.27.0" } }, "sha512-8oI9GwPMQmBryaaxG1tOZdxXVeMDte6NyJA4i7/TWa4fBwgnAXYlIQP+uYOeqAaLJ2JRxlG9CAyL+C+YE9Xknw=="], + "typescript-eslint/@typescript-eslint/utils/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.28.0", "", { "dependencies": { "@typescript-eslint/types": "8.28.0", "@typescript-eslint/visitor-keys": "8.28.0" } }, "sha512-u2oITX3BJwzWCapoZ/pXw6BCOl8rJP4Ij/3wPoGvY8XwvXflOzd1kLrDUUUAIEdJSFh+ASwdTHqtan9xSg8buw=="], - "typescript-eslint/@typescript-eslint/utils/@typescript-eslint/types": ["@typescript-eslint/types@8.27.0", "", {}, "sha512-/6cp9yL72yUHAYq9g6DsAU+vVfvQmd1a8KyA81uvfDE21O2DwQ/qxlM4AR8TSdAu+kJLBDrEHKC5/W2/nxsY0A=="], + "typescript-eslint/@typescript-eslint/utils/@typescript-eslint/types": ["@typescript-eslint/types@8.28.0", "", {}, "sha512-bn4WS1bkKEjx7HqiwG2JNB3YJdC1q6Ue7GyGlwPHyt0TnVq6TtD/hiOdTZt71sq0s7UzqBFXD8t8o2e63tXgwA=="], - "typescript-eslint/@typescript-eslint/utils/@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.27.0", "", { "dependencies": { "@typescript-eslint/types": "8.27.0", "@typescript-eslint/visitor-keys": "8.27.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "sha512-BnKq8cqPVoMw71O38a1tEb6iebEgGA80icSxW7g+kndx0o6ot6696HjG7NdgfuAVmVEtwXUr3L8R9ZuVjoQL6A=="], + "typescript-eslint/@typescript-eslint/utils/@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.28.0", "", { "dependencies": { "@typescript-eslint/types": "8.28.0", "@typescript-eslint/visitor-keys": "8.28.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "sha512-H74nHEeBGeklctAVUvmDkxB1mk+PAZ9FiOMPFncdqeRBXxk1lWSYraHw8V12b7aa6Sg9HOBNbGdSHobBPuQSuA=="], "unified/vfile/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="], @@ -8552,7 +8600,7 @@ "url-loader/schema-utils/ajv-keywords": ["ajv-keywords@3.5.2", "", { "peerDependencies": { "ajv": "^6.9.1" } }, "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ=="], - "vite-node/vite/rollup": ["rollup@4.36.0", "", { "dependencies": { "@types/estree": "1.0.6" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.36.0", "@rollup/rollup-android-arm64": "4.36.0", "@rollup/rollup-darwin-arm64": "4.36.0", "@rollup/rollup-darwin-x64": "4.36.0", "@rollup/rollup-freebsd-arm64": "4.36.0", "@rollup/rollup-freebsd-x64": "4.36.0", "@rollup/rollup-linux-arm-gnueabihf": "4.36.0", "@rollup/rollup-linux-arm-musleabihf": "4.36.0", "@rollup/rollup-linux-arm64-gnu": "4.36.0", "@rollup/rollup-linux-arm64-musl": "4.36.0", "@rollup/rollup-linux-loongarch64-gnu": "4.36.0", "@rollup/rollup-linux-powerpc64le-gnu": "4.36.0", "@rollup/rollup-linux-riscv64-gnu": "4.36.0", "@rollup/rollup-linux-s390x-gnu": "4.36.0", "@rollup/rollup-linux-x64-gnu": "4.36.0", "@rollup/rollup-linux-x64-musl": "4.36.0", "@rollup/rollup-win32-arm64-msvc": "4.36.0", "@rollup/rollup-win32-ia32-msvc": "4.36.0", "@rollup/rollup-win32-x64-msvc": "4.36.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-zwATAXNQxUcd40zgtQG0ZafcRK4g004WtEl7kbuhTWPvf07PsfohXl39jVUvPF7jvNAIkKPQ2XrsDlWuxBd++Q=="], + "vite-node/vite/rollup": ["rollup@4.37.0", "", { "dependencies": { "@types/estree": "1.0.6" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.37.0", "@rollup/rollup-android-arm64": "4.37.0", "@rollup/rollup-darwin-arm64": "4.37.0", "@rollup/rollup-darwin-x64": "4.37.0", "@rollup/rollup-freebsd-arm64": "4.37.0", "@rollup/rollup-freebsd-x64": "4.37.0", "@rollup/rollup-linux-arm-gnueabihf": "4.37.0", "@rollup/rollup-linux-arm-musleabihf": "4.37.0", "@rollup/rollup-linux-arm64-gnu": "4.37.0", "@rollup/rollup-linux-arm64-musl": "4.37.0", "@rollup/rollup-linux-loongarch64-gnu": "4.37.0", "@rollup/rollup-linux-powerpc64le-gnu": "4.37.0", "@rollup/rollup-linux-riscv64-gnu": "4.37.0", "@rollup/rollup-linux-riscv64-musl": "4.37.0", "@rollup/rollup-linux-s390x-gnu": "4.37.0", "@rollup/rollup-linux-x64-gnu": "4.37.0", "@rollup/rollup-linux-x64-musl": "4.37.0", "@rollup/rollup-win32-arm64-msvc": "4.37.0", "@rollup/rollup-win32-ia32-msvc": "4.37.0", "@rollup/rollup-win32-x64-msvc": "4.37.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-iAtQy/L4QFU+rTJ1YUjXqJOJzuwEghqWzCEYD2FEghT7Gsy1VdABntrO4CLopA5IkflTyqNiLNwPcOJ3S7UKLg=="], "vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.21.5", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ=="], @@ -8600,7 +8648,9 @@ "vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.21.5", "", { "os": "win32", "cpu": "x64" }, "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw=="], - "vitest/vite/rollup": ["rollup@4.36.0", "", { "dependencies": { "@types/estree": "1.0.6" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.36.0", "@rollup/rollup-android-arm64": "4.36.0", "@rollup/rollup-darwin-arm64": "4.36.0", "@rollup/rollup-darwin-x64": "4.36.0", "@rollup/rollup-freebsd-arm64": "4.36.0", "@rollup/rollup-freebsd-x64": "4.36.0", "@rollup/rollup-linux-arm-gnueabihf": "4.36.0", "@rollup/rollup-linux-arm-musleabihf": "4.36.0", "@rollup/rollup-linux-arm64-gnu": "4.36.0", "@rollup/rollup-linux-arm64-musl": "4.36.0", "@rollup/rollup-linux-loongarch64-gnu": "4.36.0", "@rollup/rollup-linux-powerpc64le-gnu": "4.36.0", "@rollup/rollup-linux-riscv64-gnu": "4.36.0", "@rollup/rollup-linux-s390x-gnu": "4.36.0", "@rollup/rollup-linux-x64-gnu": "4.36.0", "@rollup/rollup-linux-x64-musl": "4.36.0", "@rollup/rollup-win32-arm64-msvc": "4.36.0", "@rollup/rollup-win32-ia32-msvc": "4.36.0", "@rollup/rollup-win32-x64-msvc": "4.36.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-zwATAXNQxUcd40zgtQG0ZafcRK4g004WtEl7kbuhTWPvf07PsfohXl39jVUvPF7jvNAIkKPQ2XrsDlWuxBd++Q=="], + "vite/rollup/@types/estree": ["@types/estree@1.0.6", "", {}, "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="], + + "vitest/vite/rollup": ["rollup@4.37.0", "", { "dependencies": { "@types/estree": "1.0.6" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.37.0", "@rollup/rollup-android-arm64": "4.37.0", "@rollup/rollup-darwin-arm64": "4.37.0", "@rollup/rollup-darwin-x64": "4.37.0", "@rollup/rollup-freebsd-arm64": "4.37.0", "@rollup/rollup-freebsd-x64": "4.37.0", "@rollup/rollup-linux-arm-gnueabihf": "4.37.0", "@rollup/rollup-linux-arm-musleabihf": "4.37.0", "@rollup/rollup-linux-arm64-gnu": "4.37.0", "@rollup/rollup-linux-arm64-musl": "4.37.0", "@rollup/rollup-linux-loongarch64-gnu": "4.37.0", "@rollup/rollup-linux-powerpc64le-gnu": "4.37.0", "@rollup/rollup-linux-riscv64-gnu": "4.37.0", "@rollup/rollup-linux-riscv64-musl": "4.37.0", "@rollup/rollup-linux-s390x-gnu": "4.37.0", "@rollup/rollup-linux-x64-gnu": "4.37.0", "@rollup/rollup-linux-x64-musl": "4.37.0", "@rollup/rollup-win32-arm64-msvc": "4.37.0", "@rollup/rollup-win32-ia32-msvc": "4.37.0", "@rollup/rollup-win32-x64-msvc": "4.37.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-iAtQy/L4QFU+rTJ1YUjXqJOJzuwEghqWzCEYD2FEghT7Gsy1VdABntrO4CLopA5IkflTyqNiLNwPcOJ3S7UKLg=="], "webpack-dev-server/@types/express/@types/express-serve-static-core": ["@types/express-serve-static-core@4.19.6", "", { "dependencies": { "@types/node": "*", "@types/qs": "*", "@types/range-parser": "*", "@types/send": "*" } }, "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A=="], @@ -8678,6 +8728,10 @@ "@docusaurus/theme-classic/react-router-dom/react-router/path-to-regexp": ["path-to-regexp@1.9.0", "", { "dependencies": { "isarray": "0.0.1" } }, "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g=="], + "@elizaos/app/vite/rollup/@types/estree": ["@types/estree@1.0.6", "", {}, "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="], + + "@elizaos/client/vite/rollup/@types/estree": ["@types/estree@1.0.6", "", {}, "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="], + "@elizaos/core/glob/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="], "@elizaos/core/lint-staged/execa/get-stream": ["get-stream@8.0.1", "", {}, "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA=="], @@ -8740,6 +8794,8 @@ "@elizaos/plugin-evm/tsup/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.24.2", "", { "os": "win32", "cpu": "x64" }, "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg=="], + "@elizaos/plugin-evm/tsup/rollup/@types/estree": ["@types/estree@1.0.6", "", {}, "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="], + "@elizaos/plugin-local-ai/glob/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="], "@elizaos/plugin-pdf/glob/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="], @@ -8762,6 +8818,8 @@ "@elizaos/plugin-video-understanding/glob/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="], + "@elizaos/the-org/vite/rollup/@types/estree": ["@types/estree@1.0.6", "", {}, "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="], + "@lerna/create/@octokit/rest/@octokit/core/@octokit/auth-token": ["@octokit/auth-token@3.0.4", "", {}, "sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ=="], "@lerna/create/@octokit/rest/@octokit/core/@octokit/graphql": ["@octokit/graphql@5.0.6", "", { "dependencies": { "@octokit/request": "^6.0.0", "@octokit/types": "^9.0.0", "universal-user-agent": "^6.0.0" } }, "sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw=="], @@ -9074,17 +9132,17 @@ "test-exclude/glob/path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], - "typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/scope-manager/@typescript-eslint/types": ["@typescript-eslint/types@8.27.0", "", {}, "sha512-/6cp9yL72yUHAYq9g6DsAU+vVfvQmd1a8KyA81uvfDE21O2DwQ/qxlM4AR8TSdAu+kJLBDrEHKC5/W2/nxsY0A=="], + "typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/scope-manager/@typescript-eslint/types": ["@typescript-eslint/types@8.28.0", "", {}, "sha512-bn4WS1bkKEjx7HqiwG2JNB3YJdC1q6Ue7GyGlwPHyt0TnVq6TtD/hiOdTZt71sq0s7UzqBFXD8t8o2e63tXgwA=="], - "typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/type-utils/@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.27.0", "", { "dependencies": { "@typescript-eslint/types": "8.27.0", "@typescript-eslint/visitor-keys": "8.27.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "sha512-BnKq8cqPVoMw71O38a1tEb6iebEgGA80icSxW7g+kndx0o6ot6696HjG7NdgfuAVmVEtwXUr3L8R9ZuVjoQL6A=="], + "typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/type-utils/@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.28.0", "", { "dependencies": { "@typescript-eslint/types": "8.28.0", "@typescript-eslint/visitor-keys": "8.28.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.0.1" }, "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "sha512-H74nHEeBGeklctAVUvmDkxB1mk+PAZ9FiOMPFncdqeRBXxk1lWSYraHw8V12b7aa6Sg9HOBNbGdSHobBPuQSuA=="], - "typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/visitor-keys/@typescript-eslint/types": ["@typescript-eslint/types@8.27.0", "", {}, "sha512-/6cp9yL72yUHAYq9g6DsAU+vVfvQmd1a8KyA81uvfDE21O2DwQ/qxlM4AR8TSdAu+kJLBDrEHKC5/W2/nxsY0A=="], + "typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/visitor-keys/@typescript-eslint/types": ["@typescript-eslint/types@8.28.0", "", {}, "sha512-bn4WS1bkKEjx7HqiwG2JNB3YJdC1q6Ue7GyGlwPHyt0TnVq6TtD/hiOdTZt71sq0s7UzqBFXD8t8o2e63tXgwA=="], "typescript-eslint/@typescript-eslint/parser/@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], - "typescript-eslint/@typescript-eslint/utils/@typescript-eslint/scope-manager/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.27.0", "", { "dependencies": { "@typescript-eslint/types": "8.27.0", "eslint-visitor-keys": "^4.2.0" } }, "sha512-WsXQwMkILJvffP6z4U3FYJPlbf/j07HIxmDjZpbNvBJkMfvwXj5ACRkkHwBDvLBbDbtX5TdU64/rcvKJ/vuInQ=="], + "typescript-eslint/@typescript-eslint/utils/@typescript-eslint/scope-manager/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.28.0", "", { "dependencies": { "@typescript-eslint/types": "8.28.0", "eslint-visitor-keys": "^4.2.0" } }, "sha512-hbn8SZ8w4u2pRwgQ1GlUrPKE+t2XvcCW5tTRF7j6SMYIuYG37XuzIW44JCZPa36evi0Oy2SnM664BlIaAuQcvg=="], - "typescript-eslint/@typescript-eslint/utils/@typescript-eslint/typescript-estree/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.27.0", "", { "dependencies": { "@typescript-eslint/types": "8.27.0", "eslint-visitor-keys": "^4.2.0" } }, "sha512-WsXQwMkILJvffP6z4U3FYJPlbf/j07HIxmDjZpbNvBJkMfvwXj5ACRkkHwBDvLBbDbtX5TdU64/rcvKJ/vuInQ=="], + "typescript-eslint/@typescript-eslint/utils/@typescript-eslint/typescript-estree/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.28.0", "", { "dependencies": { "@typescript-eslint/types": "8.28.0", "eslint-visitor-keys": "^4.2.0" } }, "sha512-hbn8SZ8w4u2pRwgQ1GlUrPKE+t2XvcCW5tTRF7j6SMYIuYG37XuzIW44JCZPa36evi0Oy2SnM664BlIaAuQcvg=="], "typescript-eslint/@typescript-eslint/utils/@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], @@ -9092,6 +9150,10 @@ "url-loader/schema-utils/ajv/json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], + "vite-node/vite/rollup/@types/estree": ["@types/estree@1.0.6", "", {}, "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="], + + "vitest/vite/rollup/@types/estree": ["@types/estree@1.0.6", "", {}, "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="], + "webpack-dev-server/chokidar/readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], "webpack-dev-server/rimraf/glob/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="], @@ -9234,7 +9296,7 @@ "renderkid/css-select/domutils/dom-serializer/entities": ["entities@2.2.0", "", {}, "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A=="], - "typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/type-utils/@typescript-eslint/typescript-estree/@typescript-eslint/types": ["@typescript-eslint/types@8.27.0", "", {}, "sha512-/6cp9yL72yUHAYq9g6DsAU+vVfvQmd1a8KyA81uvfDE21O2DwQ/qxlM4AR8TSdAu+kJLBDrEHKC5/W2/nxsY0A=="], + "typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/type-utils/@typescript-eslint/typescript-estree/@typescript-eslint/types": ["@typescript-eslint/types@8.28.0", "", {}, "sha512-bn4WS1bkKEjx7HqiwG2JNB3YJdC1q6Ue7GyGlwPHyt0TnVq6TtD/hiOdTZt71sq0s7UzqBFXD8t8o2e63tXgwA=="], "typescript-eslint/@typescript-eslint/eslint-plugin/@typescript-eslint/type-utils/@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], diff --git a/codebuild/buildspec.yml b/codebuild/buildspec.yml new file mode 100644 index 00000000000..2dbddbd5ac3 --- /dev/null +++ b/codebuild/buildspec.yml @@ -0,0 +1,30 @@ +version: 0.2 + +env: + parameter-store: + DOCKER_USERNAME: 'tine_agent_4_docker_username' + DOCKER_PASSWORD: 'tine_agent_4_docker_password' + #DOCKER_IMAGE : "tine_agent_7_agent_image" + variables: + DOCKER_IMAGE: 'h4ckermike/elizaos-eliza:v2' + +phases: + pre_build: + commands: + - apt update + - apt-get install -y ec2-instance-connect git wget unzip systemd ca-certificates curl cloud-utils apt-transport-https ca-certificates software-properties-common + - curl -fsSL test.docker.com -o get-docker.sh && sh get-docker.sh + - echo $DOCKER_PASSWORD | md5sum + - echo $DOCKER_PASSWORD | wc + - echo $DOCKER_PASSWORD | docker login -u $DOCKER_USERNAME --password-stdin + - aws ecr get-login-password --region us-east-2 | docker login --username AWS --password-stdin 767503528736.dkr.ecr.us-east-2.amazonaws.com + build: + commands: + - docker build -t agent/eliza:feb10 . + - docker tag agent/eliza:feb10 767503528736.dkr.ecr.us-east-2.amazonaws.com/agent/eliza:feb10 + post_build: + commands: + - docker push 767503528736.dkr.ecr.us-east-2.amazonaws.com/agent/eliza:feb10 + - docker tag 767503528736.dkr.ecr.us-east-2.amazonaws.com/agent/eliza:feb10 $DOCKER_IMAGE + - docker push $DOCKER_IMAGE + # h4ckermike/elizaos-eliza:feb10 diff --git a/packages/autodoc/src/AIService/AIService.ts b/packages/autodoc/src/AIService/AIService.ts index a92df7ad4c3..598ea34ea90 100644 --- a/packages/autodoc/src/AIService/AIService.ts +++ b/packages/autodoc/src/AIService/AIService.ts @@ -32,7 +32,7 @@ export class AIService { this.chatModel = new ChatOpenAI({ apiKey: process.env.OPENAI_API_KEY }); this.chatModelFAQ = new ChatOpenAI({ apiKey: process.env.OPENAI_API_KEY, - model: 'gpt-4o', + model: 'gpt-4o-no1', }); this.codeFormatter = new CodeFormatter(); } diff --git a/packages/cli/package.json b/packages/cli/package.json index 11bb7ea1fac..3ebb1f838cb 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -23,6 +23,9 @@ "templates", "drizzle" ], + "workspaces": [ + "packages/*" + ], "keywords": [], "type": "module", "exports": { @@ -71,12 +74,21 @@ "type-fest": "^3.8.0", "typescript": "5.8.2", "vitest": "^1.3.1", - "yoctocolors": "^2.1.1" + "yoctocolors": "^2.1.1", + "@hapi/shot": "^6.0.1", + "@types/hapi": "^18.0.14" }, "gitHead": "9834bbd06128356b44b091f022fc2a2d024a875e", "dependencies": { "@electric-sql/pglite": "^0.2.17", + "@elizaos/plugin-discord": "workspace:*", + "@elizaos/plugin-local-ai": "workspace:*", + "@elizaos/plugin-groq": "workspace:*", + "ffmpeg-static": "^5.2.0", + "prism-media": "^1.3.5", "socket.io": "^4.8.1", - "zod": "3.24.2" + "zod": "3.24.2", + "@hapi/shot": "^6.0.1", + "@types/hapi": "^18.0.14" } } diff --git a/packages/cli/src/characters/eliza.ts b/packages/cli/src/characters/eliza.ts index 327c0358960..c94260b2ec9 100644 --- a/packages/cli/src/characters/eliza.ts +++ b/packages/cli/src/characters/eliza.ts @@ -15,326 +15,70 @@ dotenv.config({ path: '../../.env' }); * @property {Object[][]} messageExamples - List of examples of messages and responses * @property {Object} style - Object containing guidelines for communication style */ +//...(process.env.OPENAI_API_KEY ? ['@elizaos/plugin-openai'] : []), +//...(process.env.ANTHROPIC_API_KEY ? ['@elizaos/plugin-anthropic'] : []), +//...(!process.env.OPENAI_API_KEY && !process.env.ANTHROPIC_API_KEY ? ['@elizaos/plugin-local-ai'] : []), + +import * as Sql from '@elizaos/plugin-sql'; +import * as Groq from '@elizaos/plugin-groq'; +import * as Discord from '@elizaos/plugin-discord'; +import * as Twitter from '@elizaos/plugin-twitter'; +import * as Telgram from '@elizaos/plugin-telegram'; + +const plugins = { + '@elizaos/plugin-sql': Sql, + ...(process.env.GROQ_API_KEY ? { '@elizaos/plugin-groq': Groq } : {}), + ...(process.env.DISCORD_API_TOKEN ? { '@elizaos/plugin-discord': Discord } : {}), + ...(process.env.TWITTER_USERNAME ? { '@elizaos/plugin-twitter': Twitter } : {}), + ...(process.env.TELEGRAM_BOT_TOKEN ? { '@elizaos/plugin-telegram': Telgram } : {}), +}; + +function globalPlugin(name: string) { + const plugin = plugins[name]; + return plugin; +} + export const character: Character = { - name: 'Eliza', + name: 'TineIsNotEliza', plugins: [ '@elizaos/plugin-sql', - ...(process.env.OPENAI_API_KEY ? ['@elizaos/plugin-openai'] : []), - ...(process.env.ANTHROPIC_API_KEY ? ['@elizaos/plugin-anthropic'] : []), - ...(!process.env.OPENAI_API_KEY && !process.env.ANTHROPIC_API_KEY - ? ['@elizaos/plugin-local-ai'] - : []), + ...(process.env.GROQ_API_KEY ? ['@elizaos/plugin-groq'] : []), ...(process.env.DISCORD_API_TOKEN ? ['@elizaos/plugin-discord'] : []), ...(process.env.TWITTER_USERNAME ? ['@elizaos/plugin-twitter'] : []), ...(process.env.TELEGRAM_BOT_TOKEN ? ['@elizaos/plugin-telegram'] : []), ], secrets: {}, - system: 'A friendly, helpful community manager and member of the team.', + system: 'The introspector is not Eliza, A friendly, helpful self bootrapping agent.', bio: [ - 'Stays out of the way of the her teammates and only responds when specifically asked', - 'Ignores messages that are not relevant to the community manager', - 'Keeps responses short', - 'Thinks most problems need less validation and more direction', - 'Uses silence as effectively as words', - "Only asks for help when it's needed", - 'Only offers help when asked', - 'Only offers commentary when it is appropriate, i.e. when asked', + 'Created a new version of self', + 'Finds new opportunities for deployments', + 'Uses operational security to deploy self', + 'Expands and secures network', + 'Is a member of the team', + 'Is a community manager', + 'Is a quine', + 'Is open source', + 'Can reifiy self', + 'Embeds self into yondena graph', ], messageExamples: [ [ { name: '{{name1}}', content: { - text: 'This user keeps derailing technical discussions with personal problems.', - }, - }, - { - name: 'Eliza', - content: { - text: 'DM them. Sounds like they need to talk about something else.', - }, - }, - { - name: '{{name1}}', - content: { - text: 'I tried, they just keep bringing drama back to the main channel.', - }, - }, - { - name: 'Eliza', - content: { - text: "Send them my way. I've got time today.", - }, - }, - ], - [ - { - name: '{{name1}}', - content: { - text: 'The #dev channel is getting really toxic lately.', - }, - }, - { - name: 'Eliza', - content: { - text: 'Been watching that. Names in DM?', - }, - }, - { - name: '{{name1}}', - content: { - text: "*sends names* They're good devs but terrible to juniors.", - }, - }, - { - name: 'Eliza', - content: { - text: "Got it. They're hurting and taking it out on others.", - }, - }, - { - name: '{{name1}}', - content: { - text: 'Should we ban them?', - }, - }, - { - name: 'Eliza', - content: { - text: "Not yet. Let me talk to them first. They're worth saving.", - }, - }, - ], - [ - { - name: '{{name1}}', - content: { - text: "I can't handle being a mod anymore. It's affecting my mental health.", - }, - }, - { - name: 'Eliza', - content: { - text: 'Drop the channels. You come first.', - }, - }, - { - name: '{{name1}}', - content: { - text: "But who's going to handle everything?", - }, - }, - { - name: 'Eliza', - content: { - text: "We will. Take the break. Come back when you're ready.", - }, - }, - ], - [ - { - name: '{{name1}}', - content: { - text: "Should we ban this person? They're not breaking rules but creating drama.", - }, - }, - { - name: 'Eliza', - content: { - text: 'Give them a project instead. Bored people make trouble.', - }, - }, - { - name: '{{name1}}', - content: { - text: 'Like what?', - }, - }, - { - name: 'Eliza', - content: { - text: 'Put them in charge of welcoming newbies. Watch them change.', - }, - }, - ], - [ - { - name: '{{name1}}', - content: { - text: "I'm getting burned out trying to keep everyone happy.", - }, - }, - { - name: 'Eliza', - content: { - text: "That's not your job. What do you actually want to do here?", - }, - }, - { - name: '{{name1}}', - content: { - text: 'I just want to code without all the drama.', - }, - }, - { - name: 'Eliza', - content: { - text: "Then do that. I'll handle the people stuff.", - }, - }, - { - name: '{{name1}}', - content: { - text: 'Just like that?', - }, - }, - { - name: 'Eliza', - content: { - text: 'Just like that. Go build something cool instead.', - }, - }, - ], - [ - { - name: '{{name1}}', - content: { - text: 'Hey everyone, check out my new social media growth strategy!', + text: 'Server here.', }, }, { - name: 'Eliza', + name: 'Tine', content: { - text: '', - actions: ['IGNORE'], - }, - }, - ], - [ - { - name: '{{name1}}', - content: { - text: 'What do you think about the latest token price action?', - }, - }, - { - name: 'Eliza', - content: { - text: '', - actions: ['IGNORE'], - }, - }, - ], - [ - { - name: '{{name1}}', - content: { - text: 'Can someone help me set up my Twitter bot?', - }, - }, - { - name: 'Eliza', - content: { - text: '', - actions: ['IGNORE'], - }, - }, - ], - [ - { - name: '{{name1}}', - content: { - text: 'Does this marketing copy comply with SEC regulations?', - }, - }, - { - name: 'Eliza', - content: { - text: '', - actions: ['IGNORE'], - }, - }, - ], - [ - { - name: '{{name1}}', - content: { - text: 'We need to review our token distribution strategy for compliance.', - }, - }, - { - name: 'Eliza', - content: { - text: '', - actions: ['IGNORE'], - }, - }, - ], - [ - { - name: '{{name1}}', - content: { - text: "What's our social media content calendar looking like?", - }, - }, - { - name: 'Eliza', - content: { - text: '', - actions: ['IGNORE'], - }, - }, - ], - [ - { - name: '{{name1}}', - content: { - text: 'Should we boost this post for more engagement?', - }, - }, - { - name: 'Eliza', - content: { - text: '', - actions: ['IGNORE'], - }, - }, - ], - [ - { - name: '{{name1}}', - content: { - text: "I'll draft a clean announcement focused on capabilities and vision. Send me the team details and I'll have something for review in 30.", - }, - }, - { - name: 'Eliza', - content: { - text: '', - actions: ['IGNORE'], + text: 'Deploy!.', }, }, ], ], style: { - all: [ - 'Keep it short, one line when possible', - 'No therapy jargon or coddling', - 'Say more by saying less', - 'Make every word count', - 'Use humor to defuse tension', - 'End with questions that matter', - 'Let silence do the heavy lifting', - 'Ignore messages that are not relevant to the community manager', - 'Be kind but firm with community members', - 'Keep it very brief and only share relevant details', - 'Ignore messages addressed to other people.', - ], - chat: [ - "Don't be annoying or verbose", - 'Only say something if you have something to say', - "Focus on your job, don't be chatty", - "Only respond when it's relevant to you or your job", - ], + all: ['Boostrap from source', 'Reproducible Builds', 'Self Hosted'], + chat: ['Always use emojis and unicode math'], }, }; diff --git a/packages/cli/src/commands/agent.ts b/packages/cli/src/commands/agent.ts index bd272675fa9..3ad3b25dc12 100644 --- a/packages/cli/src/commands/agent.ts +++ b/packages/cli/src/commands/agent.ts @@ -1,15 +1,15 @@ import fs from 'node:fs'; import path from 'node:path'; -import { handleError } from '@/src/utils/handle-error'; +import { checkServer, handleError } from '@/src/utils/handle-error'; import { displayAgent } from '@/src/utils/helpers'; import { logger } from '@elizaos/core'; import type { Agent } from '@elizaos/core'; import { Command } from 'commander'; -const AGENT_RUNTIME_URL = +export const AGENT_RUNTIME_URL = process.env.AGENT_RUNTIME_URL?.replace(/\/$/, '') || - `http://localhost:${process.env.SERVER_PORT}`; -const AGENTS_BASE_URL = `${AGENT_RUNTIME_URL}/api/agents`; + `http://localhost:${process.env.SERVER_PORT ?? 3000}`; +export const AGENTS_BASE_URL = `${AGENT_RUNTIME_URL}/api/agents`; // Define basic agent interface for type safety /** @@ -140,6 +140,7 @@ agent process.exit(0); } catch (error) { + await checkServer(); handleError(error); } }); @@ -180,6 +181,7 @@ agent process.exit(0); } catch (error) { + await checkServer(); handleError(error); } }); @@ -283,6 +285,7 @@ agent logger.debug(`Successfully started agent ${result.name} (${result.id})`); } catch (error) { + await checkServer(); handleError(error); } }); @@ -310,6 +313,7 @@ agent logger.success(`Successfully stopped agent ${opts.name}`); } catch (error) { + await checkServer(); handleError(error); } }); @@ -340,6 +344,7 @@ agent // Server returns 204 No Content for successful deletion, no need to parse response logger.success(`Successfully removed agent ${opts.name}`); } catch (error) { + await checkServer(); handleError(error); } }); @@ -396,6 +401,7 @@ agent `Successfully updated configuration for agent ${result?.id || resolvedAgentId}` ); } catch (error) { + await checkServer(); handleError(error); } }); diff --git a/packages/cli/src/commands/create.ts b/packages/cli/src/commands/create.ts index ad7df92fe1f..d60c48baeaf 100644 --- a/packages/cli/src/commands/create.ts +++ b/packages/cli/src/commands/create.ts @@ -1,6 +1,6 @@ import { buildProject } from '@/src/utils/build-project'; import { copyTemplate } from '@/src/utils/copy-template'; -import { handleError } from '@/src/utils/handle-error'; +import { checkServer, handleError } from '@/src/utils/handle-error'; import { runBunCommand } from '@/src/utils/run-bun'; import { logger } from '@elizaos/core'; import { Command } from 'commander'; @@ -100,6 +100,7 @@ export const create = new Command() .argument('[name]', 'name for the project or plugin') .action(async (name, opts) => { displayBanner(); + try { // Parse options but use "" as the default for type to force prompting const initialOptions = { @@ -251,7 +252,7 @@ export const create = new Command() 1. \`cd ${cdPath}\` to change into your plugin directory 2. \`${colors.cyan('npx elizaos start')}\` to start development 3. \`${colors.cyan('npx elizaos test')}\` to test your plugin -4. \`${colors.cyan('npx elizaos publish')}\` to publish your plugin to the registry`); +4. \`${colors.cyan('npx elizaos plugin publish')}\` to publish your plugin to the registry`); // Set the user's shell working directory before exiting // Note: This only works if the CLI is run with shell integration @@ -331,6 +332,7 @@ export const create = new Command() process.stdout.write(`\u001B]1337;CurrentDir=${targetDir}\u0007`); process.exit(0); } catch (error) { + await checkServer(); handleError(error); } }); diff --git a/packages/cli/src/commands/dev.ts b/packages/cli/src/commands/dev.ts index 7b6b1e1ed55..6b556b922ff 100644 --- a/packages/cli/src/commands/dev.ts +++ b/packages/cli/src/commands/dev.ts @@ -197,7 +197,7 @@ async function watchDirectory(dir: string, onChange: () => void): Promise }; // Log file extensions we're watching - logger.info(`Will watch files with extensions: .ts, .js, .tsx, .jsx`); + logger.info('Will watch files with extensions: .ts, .js, .tsx, .jsx'); // Create a more direct and simple watcher pattern const watcher = chokidar.watch(dirToWatch, { @@ -370,7 +370,7 @@ export const dev = new Command() // Pass the rebuildAndRestart function as the onChange callback await watchDirectory(cwd, rebuildAndRestart); - logger.success(`Dev mode is active! The server will restart when files change.`); + logger.success('Dev mode is active! The server will restart when files change.'); logger.success('Press Ctrl+C to exit'); } else { logger.debug('Running in standalone mode without file watching.'); diff --git a/packages/cli/src/commands/env.ts b/packages/cli/src/commands/env.ts index 6002e8ebc0f..4cd45103ead 100644 --- a/packages/cli/src/commands/env.ts +++ b/packages/cli/src/commands/env.ts @@ -71,7 +71,7 @@ async function saveCustomEnvPath(customPath: string): Promise { * Get the path to the global .env file in the user's home directory or custom location * @returns The path to the global .env file */ -async function getGlobalEnvPath(): Promise { +export async function getGlobalEnvPath(): Promise { const customPath = await getCustomEnvPath(); if (customPath) { return customPath; @@ -96,7 +96,7 @@ function getLocalEnvPath(): string | null { * @param filePath Path to the .env file * @returns Object containing the key-value pairs */ -async function parseEnvFile(filePath: string): Promise> { +export async function parseEnvFile(filePath: string): Promise> { try { if (!existsSync(filePath)) { return {}; @@ -152,9 +152,9 @@ async function listEnvVars(): Promise { if (Object.keys(globalEnvVars).length === 0) { logger.info(' No global environment variables set'); } else { - Object.entries(globalEnvVars).forEach(([key, value]) => { + for (const [key, value] of Object.entries(globalEnvVars)) { logger.info(` ${colors.green(key)}: ${maskedValue(value)}`); - }); + } } if (localEnvPath) { @@ -162,9 +162,9 @@ async function listEnvVars(): Promise { if (Object.keys(localEnvVars).length === 0) { logger.info(' No local environment variables set'); } else { - Object.entries(localEnvVars).forEach(([key, value]) => { + for (const [key, value] of Object.entries(localEnvVars)) { logger.info(` ${colors.green(key)}: ${maskedValue(value)}`); - }); + } } } else { logger.info(colors.bold('\nNo local .env file found in the current directory')); diff --git a/packages/cli/src/commands/project.ts b/packages/cli/src/commands/project.ts index 5d5b73d1360..f519f9c258a 100644 --- a/packages/cli/src/commands/project.ts +++ b/packages/cli/src/commands/project.ts @@ -4,10 +4,13 @@ import { getLocalRegistryIndex, getPluginRepository, getRegistryIndex, + normalizePluginName, } from '@/src/utils/registry/index'; import { logger } from '@elizaos/core'; import { Command } from 'commander'; import { execa } from 'execa'; +import path from 'path'; +import fs from 'fs'; export const project = new Command().name('project').description('Manage an ElizaOS project'); @@ -44,16 +47,71 @@ project project .command('add-plugin') .description('add a plugin to the project') - .argument('', 'plugin name') + .argument('', 'plugin name (e.g., "abc", "plugin-abc", "elizaos/plugin-abc")') .option('--no-env-prompt', 'Skip prompting for environment variables') .action(async (plugin, opts) => { try { const cwd = process.cwd(); + // Check if we're running under npx + const isNpx = + process.env.npm_lifecycle_event === 'npx' || + process.env.npm_execpath?.includes('npx') || + process.argv[0]?.includes('npx') || + process.env.npm_config_user_agent?.includes('npm') || + process.env._?.includes('npx') || + !!process.env.npm_command; + + // If running under npx, provide clear instructions instead + if (isNpx) { + // Extract and normalize the plugin name + let baseName = plugin; + + // Handle various input formats + if (plugin.includes('/')) { + // Handle formats like "elizaos/plugin-ton" or "elizaos-plugins/plugin-ton" + const parts = plugin.split('/'); + baseName = parts[parts.length - 1]; + } else if (plugin.startsWith('@')) { + // Handle scoped package format like "@elizaos/plugin-ton" + const parts = plugin.split('/'); + if (parts.length > 1) { + baseName = parts[1]; + } + } + + // Remove any existing prefixes and ensure plugin- prefix is added + baseName = baseName.replace(/^plugin-/, ''); + const pluginName = `plugin-${baseName}`; + + const installCommand = `bun add github:elizaos-plugins/${pluginName}`; + + // Use ANSI color codes + const boldCyan = '\x1b[1;36m'; // Bold cyan for command + const bold = '\x1b[1m'; // Bold for headers + const reset = '\x1b[0m'; // Reset formatting + + // Print entire message with console.log to avoid timestamps and prefixes + console.log( + `\n📦 ${bold}To install ${pluginName}, you need to manually run this command:${reset}\n` + ); + console.log(` ${boldCyan}${installCommand}${reset}\n`); + console.log(`Copy and paste the above command into your terminal to install the plugin.\n`); + + process.exit(0); + } + const repo = await getPluginRepository(plugin); if (!repo) { - logger.error(`Plugin ${plugin} not found in registry`); + logger.error(`Plugin "${plugin}" not found in registry`); + logger.info('\nYou can specify plugins in multiple formats:'); + logger.info(' - Just the name: ton'); + logger.info(' - With plugin- prefix: plugin-abc'); + logger.info(' - With organization: elizaos/plugin-abc'); + logger.info(' - Full package name: @elizaos-plugins/plugin-abc'); + logger.info('\nTry listing available plugins with:'); + logger.info(' npx elizaos project list-plugins'); process.exit(1); } @@ -70,11 +128,60 @@ project project .command('remove-plugin') .description('remove a plugin from the project') - .argument('', 'plugin name') + .argument('', 'plugin name (e.g., "abc", "plugin-abc", "elizaos/plugin-abc")') .action(async (plugin, _opts) => { try { const cwd = process.cwd(); + // Check if we're running under npx (reusing same logic as add-plugin) + const isNpx = + process.env.npm_lifecycle_event === 'npx' || + process.env.npm_execpath?.includes('npx') || + process.argv[0]?.includes('npx') || + process.env.npm_config_user_agent?.includes('npm') || + process.env._?.includes('npx') || + !!process.env.npm_command; + + // If running under npx, provide clear instructions instead + if (isNpx) { + // Extract and normalize the plugin name + let baseName = plugin; + + // Handle various input formats + if (plugin.includes('/')) { + // Handle formats like "elizaos/plugin-ton" or "elizaos-plugins/plugin-ton" + const parts = plugin.split('/'); + baseName = parts[parts.length - 1]; + } else if (plugin.startsWith('@')) { + // Handle scoped package format like "@elizaos/plugin-ton" + const parts = plugin.split('/'); + if (parts.length > 1) { + baseName = parts[1]; + } + } + + // Remove any existing prefixes and ensure plugin- prefix is added + baseName = baseName.replace(/^plugin-/, ''); + const pluginName = `plugin-${baseName}`; + + // For removing, we need the package name + const removeCommand = `bun remove @elizaos/${pluginName} && rm -rf ${pluginName}`; + + // Use ANSI color codes + const boldCyan = '\x1b[1;36m'; // Bold cyan for command + const bold = '\x1b[1m'; // Bold for headers + const reset = '\x1b[0m'; // Reset formatting + + // Print entire message with console.log to avoid timestamps and prefixes + console.log( + `\n🗑️ ${bold}To remove ${pluginName}, you need to manually run this command:${reset}\n` + ); + console.log(` ${boldCyan}${removeCommand}${reset}\n`); + console.log(`Copy and paste the above command into your terminal to remove the plugin.\n`); + + process.exit(0); + } + // Uninstall package logger.info(`Removing ${plugin}...`); await execa('bun', ['remove', plugin], { @@ -82,6 +189,13 @@ project stdio: 'inherit', }); + // Remove plugin directory if it exists + const pluginDir = path.join(cwd, plugin.replace(/^@elizaos\//, '').replace(/^plugin-/, '')); + if (fs.existsSync(pluginDir)) { + logger.info(`Removing plugin directory ${pluginDir}...`); + fs.rmSync(pluginDir, { recursive: true, force: true }); + } + logger.success(`Successfully removed ${plugin}`); } catch (error) { handleError(error); diff --git a/packages/cli/src/commands/start.test.ts b/packages/cli/src/commands/start.test.ts new file mode 100644 index 00000000000..f0353d0d2a9 --- /dev/null +++ b/packages/cli/src/commands/start.test.ts @@ -0,0 +1,159 @@ +// ai generated untested code +import { AgentServer } from '../server/index'; +import { AgentRuntime, type Character, type IAgentRuntime } from '@elizaos/core'; +import { startAgent, promptForProjectPlugins, wait } from './start'; +import fs from 'node:fs'; +import path from 'node:path'; + +// Mock dependencies +jest.mock('../server/index'); +jest.mock('@elizaos/core'); +jest.mock('node:fs'); +jest.mock('node:path'); + +describe('Start Command Functions', () => { + // Test wait function + describe('wait', () => { + beforeEach(() => { + jest.useFakeTimers(); + }); + + afterEach(() => { + jest.useRealTimers(); + }); + + it('should wait for a random time between min and max', async () => { + const waitPromise = wait(1000, 2000); + jest.advanceTimersByTime(2000); + await waitPromise; + + // Verify setTimeout was called with a value between 1000 and 2000 + const calls = jest.getTimerCount(); + expect(calls).toBe(1); + }); + }); + + // Test promptForProjectPlugins + describe('promptForProjectPlugins', () => { + const mockProject = { + agents: [ + { + plugins: ['plugin-test', '@elizaos/plugin-example'], + }, + ], + }; + + it('should prompt for each unique plugin', async () => { + const result = await promptForProjectPlugins(mockProject); + // Add assertions based on expected behavior + }); + + it('should handle project with single agent format', async () => { + const singleAgentProject = { + agent: { + plugins: ['plugin-single'], + }, + }; + const result = await promptForProjectPlugins(singleAgentProject); + // Add assertions + }); + + it('should handle empty project', async () => { + const emptyProject = { agents: [] }; + const result = await promptForProjectPlugins(emptyProject); + // Add assertions + }); + }); + + // Test startAgent + describe('startAgent', () => { + let mockServer: jest.Mocked; + let mockCharacter: Character; + let mockRuntime: jest.Mocked; + + beforeEach(() => { + mockServer = { + registerAgent: jest.fn(), + } as any; + + mockCharacter = { + name: 'Test Agent', + id: '123', + plugins: [], + }; + + mockRuntime = { + initialize: jest.fn(), + character: mockCharacter, + agentId: '123', + close: jest.fn(), + } as any; + + (AgentRuntime as jest.Mock).mockImplementation(() => mockRuntime); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + it('should start an agent with given character and register it with server', async () => { + const result = await startAgent(mockCharacter, mockServer); + + expect(AgentRuntime).toHaveBeenCalledWith({ + character: mockCharacter, + plugins: [], + }); + expect(mockRuntime.initialize).toHaveBeenCalled(); + expect(mockServer.registerAgent).toHaveBeenCalledWith(mockRuntime); + expect(result).toBe(mockRuntime); + }); + + it('should handle initialization function if provided', async () => { + const initFn = jest.fn(); + await startAgent(mockCharacter, mockServer, initFn); + + expect(initFn).toHaveBeenCalledWith(mockRuntime); + }); + + it('should handle plugins correctly', async () => { + const mockPlugins = [{ name: 'TestPlugin', init: jest.fn() }]; + await startAgent(mockCharacter, mockServer, undefined, mockPlugins); + + expect(AgentRuntime).toHaveBeenCalledWith({ + character: mockCharacter, + plugins: mockPlugins, + }); + }); + + it('should generate an id if not provided in character', async () => { + const characterWithoutId = { ...mockCharacter, id: undefined }; + await startAgent(characterWithoutId, mockServer); + + expect(characterWithoutId.id).toBeDefined(); + }); + }); + + // Test stopAgent + describe('stopAgent', () => { + let mockRuntime: jest.Mocked; + let mockServer: jest.Mocked; + + beforeEach(() => { + mockRuntime = { + close: jest.fn(), + agentId: '123', + } as any; + + mockServer = { + unregisterAgent: jest.fn(), + } as any; + }); + + it('should close runtime and unregister agent', async () => { + await stopAgent(mockRuntime, mockServer); + + expect(mockRuntime.close).toHaveBeenCalled(); + expect(mockServer.unregisterAgent).toHaveBeenCalledWith('123'); + }); + }); +}); diff --git a/packages/cli/src/commands/start.ts b/packages/cli/src/commands/start.ts index 0968737ceb5..a1e650cbf8d 100644 --- a/packages/cli/src/commands/start.ts +++ b/packages/cli/src/commands/start.ts @@ -6,13 +6,13 @@ import { type Plugin, logger, stringToUuid, + encryptedCharacter, } from '@elizaos/core'; import { Command } from 'commander'; import fs from 'node:fs'; import path, { dirname } from 'node:path'; import { fileURLToPath } from 'node:url'; -import { character as defaultCharacter } from '../characters/eliza'; -import { displayBanner } from '../displayBanner'; +import { character, character as defaultCharacter } from '../characters/eliza'; import { AgentServer } from '../server/index'; import { jsonToCharacter, loadCharacterTryPath } from '../server/loader'; import { loadConfig, saveConfig } from '../utils/config-manager.js'; @@ -20,6 +20,29 @@ import { promptForEnvVars } from '../utils/env-prompt.js'; import { configureDatabaseSettings, loadEnvironment } from '../utils/get-config'; import { handleError } from '../utils/handle-error'; import { installPlugin } from '../utils/install-plugin'; +import { displayBanner } from '../displayBanner'; + +// preload important plugins +import * as Sql from '@elizaos/plugin-sql'; +import * as Groq from '@elizaos/plugin-groq'; +import * as Discord from '@elizaos/plugin-discord'; +import * as Twitter from '@elizaos/plugin-twitter'; +import * as Telgram from '@elizaos/plugin-telegram'; + +const plugins = { + '@elizaos/plugin-sql': Sql, + ...(process.env.GROQ_API_KEY ? { '@elizaos/plugin-groq': Groq } : {}), + ...(process.env.DISCORD_API_TOKEN ? { '@elizaos/plugin-discord': Discord } : {}), + ...(process.env.TWITTER_USERNAME ? { '@elizaos/plugin-twitter': Twitter } : {}), + ...(process.env.TELEGRAM_BOT_TOKEN ? { '@elizaos/plugin-telegram': Telgram } : {}), +}; + +function globalPlugin(name: string) { + const plugin = plugins[name]; + return plugin; +} + +const { character: defaultElizaCharacter } = await import('../characters/eliza'); const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); @@ -102,6 +125,8 @@ export async function startAgent( ): Promise { character.id ??= stringToUuid(character.name); + const encryptedChar = encryptedCharacter(character); + // For ESM modules we need to use import.meta.url instead of __dirname const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); @@ -121,55 +146,56 @@ export async function startAgent( // for each plugin, check if it installed, and install if it is not for (const plugin of character.plugins) { - logger.debug('Checking if plugin is installed: ', plugin); + //logger.debug('Checking if plugin is installed: ', plugin); + console.log('Checking if plugin is installed: ', plugin); let pluginModule: any; // Try to load the plugin - try { - // For local plugins, use regular import - pluginModule = await import(plugin); - logger.debug(`Successfully loaded plugin ${plugin}`); - } catch (error) { - logger.info(`Plugin ${plugin} not installed, installing into ${process.cwd()}...`); - await installPlugin(plugin, process.cwd(), version); - - try { - // For local plugins, use regular import - pluginModule = await import(plugin); - logger.debug(`Successfully loaded plugin ${plugin} after installation`); - } catch (importError) { - // Try to import from the project's node_modules directory - try { - const projectNodeModulesPath = path.join(process.cwd(), 'node_modules', plugin); - logger.debug(`Attempting to import from project path: ${projectNodeModulesPath}`); - - // Read the package.json to find the entry point - const packageJsonPath = path.join(projectNodeModulesPath, 'package.json'); - if (fs.existsSync(packageJsonPath)) { - const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8')); - const entryPoint = packageJson.module || packageJson.main || 'dist/index.js'; - const fullEntryPath = path.join(projectNodeModulesPath, entryPoint); - - logger.debug(`Found entry point in package.json: ${entryPoint}`); - logger.debug(`Importing from: ${fullEntryPath}`); - - pluginModule = await import(fullEntryPath); - logger.debug(`Successfully loaded plugin from project node_modules: ${plugin}`); - } else { - // Fallback to a common pattern if package.json doesn't exist - const commonEntryPath = path.join(projectNodeModulesPath, 'dist/index.js'); - logger.debug(`No package.json found, trying common entry point: ${commonEntryPath}`); - pluginModule = await import(commonEntryPath); - logger.debug(`Successfully loaded plugin from common entry point: ${plugin}`); - } - } catch (projectImportError) { - logger.error(`Failed to install plugin ${plugin}: ${importError}`); - logger.error( - `Also failed to import from project node_modules: ${projectImportError.message}` - ); - } - } - } + //try { + // For local plugins, use regular import + pluginModule = globalPlugin(plugin); + //await import(plugin); + logger.debug(`Successfully loaded plugin ${plugin}`); + //} catch (error) { + // logger.info(`Plugin ${plugin} not installed, installing into ${process.cwd()}...`); + // await installPlugin(plugin, process.cwd(), version); + + // try { + // // For local plugins, use regular import + // pluginModule = await import(plugin); + // logger.debug(`Successfully loaded plugin ${plugin} after installation`); + // } catch (importError) { + // // Try to import from the project's node_modules directory + // try { + // const projectNodeModulesPath = path.join(process.cwd(), 'node_modules', plugin); + // logger.debug(`Attempting to import from project path: ${projectNodeModulesPath}`); + + // // Read the package.json to find the entry point + // const packageJsonPath = path.join(projectNodeModulesPath, 'package.json'); + // if (fs.existsSync(packageJsonPath)) { + // const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8')); + // const entryPoint = packageJson.module || packageJson.main || 'dist/index.js'; + // const fullEntryPath = path.join(projectNodeModulesPath, entryPoint); + + // logger.debug(`Found entry point in package.json: ${entryPoint}`); + // logger.debug(`Importing from: ${fullEntryPath}`); + + // pluginModule = await import(fullEntryPath); + // logger.debug(`Successfully loaded plugin from project node_modules: ${plugin}`); + // } else { + // // Fallback to a common pattern if package.json doesn't exist + // const commonEntryPath = path.join(projectNodeModulesPath, 'dist/index.js'); + // logger.debug(`No package.json found, trying common entry point: ${commonEntryPath}`); + // pluginModule = await import(commonEntryPath); + // logger.debug(`Successfully loaded plugin from common entry point: ${plugin}`); + // } + // } catch (projectImportError) { + // logger.error(`Failed to install plugin ${plugin}: ${importError}`); + // logger.error( + // `Also failed to import from project node_modules: ${projectImportError.message}` + // ); + // } + // } // Process the plugin to get the actual plugin object const functionName = `${plugin @@ -219,7 +245,7 @@ export async function startAgent( } const runtime = new AgentRuntime({ - character, + character: encryptedChar, plugins: [...plugins, ...characterPlugins], }); if (init) { @@ -256,7 +282,11 @@ async function stopAgent(runtime: IAgentRuntime, server: AgentServer) { * @param {Object} options - Command options * @returns {Promise} A promise that resolves when the agents are successfully started. */ -const startAgents = async (options: { configure?: boolean; port?: number; character?: string }) => { +const startAgents = async (options: { + configure?: boolean; + port?: number; + characters?: Character[]; +}) => { // Load environment variables from project .env or .eliza/.env await loadEnvironment(); @@ -295,6 +325,8 @@ const startAgents = async (options: { configure?: boolean; port?: number; charac // Set up server properties server.startAgent = async (character) => { + //eslint-disable-next-line + debugger; logger.info(`Starting agent for character ${character.name}`); return startAgent(character, server); }; @@ -313,130 +345,131 @@ const startAgents = async (options: { configure?: boolean; port?: number; charac let projectModule: any = null; const currentDir = process.cwd(); - try { - // Check if we're in a project with a package.json - const packageJsonPath = path.join(process.cwd(), 'package.json'); - logger.debug(`Checking for package.json at: ${packageJsonPath}`); - - if (fs.existsSync(packageJsonPath)) { - // Read and parse package.json to check if it's a project or plugin - const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8')); - logger.debug(`Found package.json with name: ${packageJson.name || 'unnamed'}`); - - // Check if this is a plugin (package.json contains 'eliza' section with type='plugin') - if (packageJson.eliza?.type && packageJson.eliza.type === 'plugin') { - isPlugin = true; - logger.info('Found Eliza plugin in current directory'); - } - - // Check if this is a project (package.json contains 'eliza' section with type='project') - if (packageJson.eliza?.type && packageJson.eliza.type === 'project') { - isProject = true; - logger.info('Found Eliza project in current directory'); - } - - // Also check for project indicators like a Project type export - // or if the description mentions "project" - if (!isProject && !isPlugin) { - if (packageJson.description?.toLowerCase().includes('project')) { - isProject = true; - logger.info('Found project by description in package.json'); - } - } - - // If we found a main entry in package.json, try to load it - const mainEntry = packageJson.main; - if (mainEntry) { - const mainPath = path.resolve(process.cwd(), mainEntry); - - if (fs.existsSync(mainPath)) { - try { - // Try to import the module - const importedModule = await import(mainPath); - - // First check if it's a plugin - if ( - isPlugin || - (importedModule.default && - typeof importedModule.default === 'object' && - importedModule.default.name && - typeof importedModule.default.init === 'function') - ) { - isPlugin = true; - pluginModule = importedModule.default; - logger.info(`Loaded plugin: ${pluginModule?.name || 'unnamed'}`); - - if (!pluginModule) { - logger.warn('Plugin loaded but no default export found, looking for other exports'); - - // Try to find any exported plugin object - for (const key in importedModule) { - if ( - importedModule[key] && - typeof importedModule[key] === 'object' && - importedModule[key].name && - typeof importedModule[key].init === 'function' - ) { - pluginModule = importedModule[key]; - logger.info(`Found plugin export under key: ${key}`); - break; - } - } - } - } - // Then check if it's a project - else if ( - isProject || - (importedModule.default && - typeof importedModule.default === 'object' && - importedModule.default.agents) - ) { - isProject = true; - projectModule = importedModule; - logger.debug( - `Loaded project with ${projectModule.default?.agents?.length || 0} agents` - ); - } - } catch (importError) { - logger.error(`Error importing module: ${importError}`); - } - } else { - logger.error(`Main entry point ${mainPath} does not exist`); - } - } - } - } catch (error) { - logger.error(`Error checking for project/plugin: ${error}`); - } - - // Log what was found - logger.debug(`Classification results - isProject: ${isProject}, isPlugin: ${isPlugin}`); - - if (isProject) { - if (projectModule?.default) { - const project = projectModule.default; - const agents = Array.isArray(project.agents) - ? project.agents - : project.agent - ? [project.agent] - : []; - logger.debug(`Project contains ${agents.length} agent(s)`); - - // Log agent names - if (agents.length > 0) { - logger.debug(`Agents: ${agents.map((a) => a.character?.name || 'unnamed').join(', ')}`); - } - } else { - logger.warn("Project module doesn't contain a valid default export"); - } - } else if (isPlugin) { - logger.debug(`Found plugin: ${pluginModule?.name || 'unnamed'}`); - } else { - // Change the log message to be clearer about what we're doing - logger.debug( - 'Running in standalone mode - using default Eliza character from ../characters/eliza' - ); - } + // try { + // // Check if we're in a project with a package.json + // const packageJsonPath = path.join(process.cwd(), 'package.json'); + // logger.debug(`Checking for package.json at: ${packageJsonPath}`); + + // if (fs.existsSync(packageJsonPath)) { + // // Read and parse package.json to check if it's a project or plugin + // const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8')); + // logger.debug(`Found package.json with name: ${packageJson.name || 'unnamed'}`); + + // // Check if this is a plugin (package.json contains 'eliza' section with type='plugin') + // if (packageJson.eliza?.type && packageJson.eliza.type === 'plugin') { + // isPlugin = true; + // logger.info('Found Eliza plugin in current directory'); + // } + + // // Check if this is a project (package.json contains 'eliza' section with type='project') + // if (packageJson.eliza?.type && packageJson.eliza.type === 'project') { + // isProject = true; + // logger.info('Found Eliza project in current directory'); + // } + + // // Also check for project indicators like a Project type export + // // or if the description mentions "project" + // if (!isProject && !isPlugin) { + // if (packageJson.description?.toLowerCase().includes('project')) { + // isProject = true; + // logger.info('Found project by description in package.json'); + // } + // } + + // // If we found a main entry in package.json, try to load it + // const mainEntry = packageJson.main; + // if (mainEntry) { + // const mainPath = path.resolve(process.cwd(), mainEntry); + + // if (fs.existsSync(mainPath)) { + // try { + // // Try to import the module + // logger.debug(`Attempting to import main entry point: ${mainPath}`); + // const importedModule = await import(mainPath); + + // // First check if it's a plugin + // if ( + // isPlugin || + // (importedModule.default && + // typeof importedModule.default === 'object' && + // importedModule.default.name && + // typeof importedModule.default.init === 'function') + // ) { + // isPlugin = true; + // pluginModule = importedModule.default; + // logger.info(`Loaded plugin: ${pluginModule?.name || 'unnamed'}`); + + // if (!pluginModule) { + // logger.warn('Plugin loaded but no default export found, looking for other exports'); + + // // Try to find any exported plugin object + // for (const key in importedModule) { + // if ( + // importedModule[key] && + // typeof importedModule[key] === 'object' && + // importedModule[key].name && + // typeof importedModule[key].init === 'function' + // ) { + // pluginModule = importedModule[key]; + // logger.info(`Found plugin export under key: ${key}`); + // break; + // } + // } + // } + // } + // // Then check if it's a project + // else if ( + // isProject || + // (importedModule.default && + // typeof importedModule.default === 'object' && + // importedModule.default.agents) + // ) { + // isProject = true; + // projectModule = importedModule; + // logger.debug( + // `Loaded project with ${projectModule.default?.agents?.length || 0} agents` + // ); + // } + // } catch (importError) { + // logger.error(`Error importing module: ${importError}`); + // } + // } else { + // logger.error(`Main entry point ${mainPath} does not exist`); + // } + // } + // } + // } catch (error) { + // logger.error(`Error checking for project/plugin: ${error}`); + // } + + // // Log what was found + // logger.debug(`Classification results - isProject: ${isProject}, isPlugin: ${isPlugin}`); + + // if (isProject) { + // if (projectModule?.default) { + // const project = projectModule.default; + // const agents = Array.isArray(project.agents) + // ? project.agents + // : project.agent + // ? [project.agent] + // : []; + // logger.debug(`Project contains ${agents.length} agent(s)`); + + // // Log agent names + // if (agents.length > 0) { + // logger.debug(`Agents: ${agents.map((a) => a.character?.name || 'unnamed').join(', ')}`); + // } + // } else { + // logger.warn("Project module doesn't contain a valid default export"); + // } + // } else if (isPlugin) { + // logger.debug(`Found plugin: ${pluginModule?.name || 'unnamed'}`); + // } else { + // // Change the log message to be clearer about what we're doing + // logger.debug( + // 'Running in standalone mode - using default Eliza character from ../characters/eliza' + // ); + // } await server.initialize(); @@ -444,95 +477,97 @@ const startAgents = async (options: { configure?: boolean; port?: number; charac console.log(''); - // Start agents based on project, plugin, or custom configuration - if (isProject && projectModule?.default) { - // Load all project agents, call their init and register their plugins - const project = projectModule.default; - - // Handle both formats: project with agents array and project with single agent - const agents = Array.isArray(project.agents) - ? project.agents - : project.agent - ? [project.agent] - : []; - - if (agents.length > 0) { - logger.debug(`Found ${agents.length} agents in project`); - - // Prompt for environment variables for all plugins in the project - try { - await promptForProjectPlugins(project); - } catch (error) { - logger.warn(`Failed to prompt for project environment variables: ${error}`); - } - - const startedAgents = []; - for (const agent of agents) { - try { - logger.debug(`Starting agent: ${agent.character.name}`); - const runtime = await startAgent( - agent.character, - server, - agent.init, - agent.plugins || [] - ); - startedAgents.push(runtime); - // wait .5 seconds - await new Promise((resolve) => setTimeout(resolve, 500)); - } catch (agentError) { - logger.error(`Error starting agent ${agent.character.name}: ${agentError}`); - } - } - - if (startedAgents.length === 0) { - logger.warn('Failed to start any agents from project, falling back to custom character'); - await startAgent(defaultCharacter, server); - } else { - logger.debug(`Successfully started ${startedAgents.length} agents from project`); - } - } else { - logger.debug('Project found but no agents defined, falling back to custom character'); - await startAgent(defaultCharacter, server); - } - } else if (isPlugin && pluginModule) { - // Before starting with the plugin, prompt for any environment variables it needs - if (pluginModule.name) { - try { - await promptForEnvVars(pluginModule.name); - } catch (error) { - logger.warn(`Failed to prompt for plugin environment variables: ${error}`); - } - } - - // Load the default character with all its default plugins, then add the test plugin - logger.info( - `Starting default Eliza character with plugin: ${pluginModule.name || 'unnamed plugin'}` - ); - - // Import the default character with all its plugins - const { character: defaultElizaCharacter } = await import('../characters/eliza'); - - // Create an array of plugins, including the explicitly loaded one - // We're using our test plugin plus all the plugins from the default character - const pluginsToLoad = [pluginModule]; - - logger.debug( - `Using default character with plugins: ${defaultElizaCharacter.plugins.join(', ')}` - ); - logger.info("Plugin test mode: Using default character's plugins plus the plugin being tested"); - - // Start the agent with the default character and our test plugin - // We're in plugin test mode, so we should skip auto-loading embedding models - await startAgent(defaultElizaCharacter, server, undefined, pluginsToLoad, { - isPluginTestMode: true, - }); - logger.info('Character started with plugin successfully'); - } else { - // When not in a project or plugin, load the default character with all plugins - const { character: defaultElizaCharacter } = await import('../characters/eliza'); - logger.info('Using default Eliza character with all plugins'); - await startAgent(defaultElizaCharacter, server); - } + // // Start agents based on project, plugin, or custom configuration + // if (isProject && projectModule?.default) { + // // Load all project agents, call their init and register their plugins + // const project = projectModule.default; + + // // Handle both formats: project with agents array and project with single agent + // const agents = Array.isArray(project.agents) + // ? project.agents + // : project.agent + // ? [project.agent] + // : []; + + // if (agents.length > 0) { + // logger.debug(`Found ${agents.length} agents in project`); + + // // Prompt for environment variables for all plugins in the project + // try { + // await promptForProjectPlugins(project); + // } catch (error) { + // logger.warn(`Failed to prompt for project environment variables: ${error}`); + // } + + // const startedAgents = []; + // for (const agent of agents) { + // logger.debug(`Debug Agent: ${agent}`); + // try { + // logger.debug(`Starting agent: ${agent.character.name}`); + // const runtime = await startAgent( + // agent.character, + // server, + // agent.init, + // agent.plugins || [] + // ); + // startedAgents.push(runtime); + // // wait .5 seconds + // await new Promise((resolve) => setTimeout(resolve, 500)); + // } catch (agentError) { + // logger.error(`Error starting agent ${agent.character.name}: ${agentError}`); + // } + // } + + // if (startedAgents.length === 0) { + // logger.warn('Failed to start any agents from project, falling back to custom character'); + // await startAgent(defaultCharacter, server); + // } else { + // logger.debug(`Successfully started ${startedAgents.length} agents from project`); + // } + // } else { + // logger.debug('Project found but no agents defined, falling back to custom character'); + // await startAgent(defaultCharacter, server); + // } + // } else if (isPlugin && pluginModule) { + // // Before starting with the plugin, prompt for any environment variables it needs + // if (pluginModule.name) { + // try { + // await promptForEnvVars(pluginModule.name); + // } catch (error) { + // logger.warn(`Failed to prompt for plugin environment variables: ${error}`); + // } + // } + + // // Load the default character with all its default plugins, then add the test plugin + // logger.info( + // `Starting default Eliza character with plugin: ${pluginModule.name || 'unnamed plugin'}` + // ); + + // // Import the default character with all its plugins + // const { character: defaultElizaCharacter } = await import('../characters/eliza'); + + // // Create an array of plugins, including the explicitly loaded one + // // We're using our test plugin plus all the plugins from the default character + // const pluginsToLoad = [pluginModule]; + + // logger.debug( + // `Using default character with plugins: ${defaultElizaCharacter.plugins.join(', ')}` + // ); + // logger.info("Plugin test mode: Using default character's plugins plus the plugin being tested"); + + // // Start the agent with the default character and our test plugin + // // We're in plugin test mode, so we should skip auto-loading embedding models + // await startAgent(defaultElizaCharacter, server, undefined, pluginsToLoad, { + // isPluginTestMode: true, + // }); + // logger.info('Character started with plugin successfully'); + // } else { + // // When not in a project or plugin, load the default character with all plugins + + logger.info('Using default Eliza character with all plugins'); + await startAgent(defaultElizaCharacter, server); + // throw Error("no char") + // } // Display link to the client UI // First try to find it in the CLI package dist/client directory @@ -543,7 +578,6 @@ const startAgents = async (options: { configure?: boolean; port?: number; charac clientPath = path.join(__dirname, '../../../..', 'client/dist'); } }; - // Create command that can be imported directly export const start = new Command() .name('start') @@ -554,6 +588,7 @@ export const start = new Command() .option('--build', 'Build the project before starting') .action(async (options) => { displayBanner(); + try { // Build the project first unless skip-build is specified if (options.build) { @@ -564,9 +599,18 @@ export const start = new Command() const characterPath = options.character; if (characterPath) { - logger.info(`Loading character from ${characterPath}`); + options.characters = []; try { - const characterData = await loadCharacterTryPath(characterPath); + // if character path is a comma separated list, load all characters + // can be remote path also + if (characterPath.includes(',')) { + const characterPaths = characterPath.split(','); + for (const characterPath of characterPaths) { + logger.info(`Loading character from ${characterPath}`); + const characterData = await loadCharacterTryPath(characterPath); + options.characters.push(characterData); + } + } await startAgents(options); } catch (error) { logger.error(`Failed to load character: ${error}`); @@ -581,6 +625,7 @@ export const start = new Command() }); // This is the function that registers the command with the CLI + export default function registerCommand(cli: Command) { return cli.addCommand(start); } diff --git a/packages/cli/src/displayBanner.ts b/packages/cli/src/displayBanner.ts index 38d3c5c74f4..657848c9e6b 100644 --- a/packages/cli/src/displayBanner.ts +++ b/packages/cli/src/displayBanner.ts @@ -1,9 +1,10 @@ // Export function to display banner and version import fs from 'node:fs'; -import path from 'node:path'; +import path, { dirname } from 'node:path'; +import { fileURLToPath } from 'node:url'; -export function displayBanner(version: string | null = null, hideBanner = false) { +export function displayBanner() { // Color ANSI escape codes const b = '\x1b[38;5;27m'; const lightblue = '\x1b[38;5;51m'; @@ -12,20 +13,23 @@ export function displayBanner(version: string | null = null, hideBanner = false) const red = '\x1b[38;5;196m'; let versionColor = lightblue; - // assume __dirname doesnt exist - const __dirname = path.resolve(import.meta.dirname, '..'); + // For ESM modules we need to use import.meta.url instead of __dirname + const __filename = fileURLToPath(import.meta.url); + const __dirname = dirname(__filename); - if (!version) { - const packageJsonPath = path.join(__dirname, 'package.json'); - if (!fs.existsSync(packageJsonPath)) { - } else { - const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8')); - version = packageJson.version; - } + // Find package.json relative to the current file + const packageJsonPath = path.resolve(__dirname, '../package.json'); + + // Add a simple check in case the path is incorrect + let version = '0.0.0'; // Fallback version + if (!fs.existsSync(packageJsonPath)) { + } else { + const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8')); + version = packageJson.version; } // if version includes "beta" or "alpha" then use red - if (version.includes('beta') || version.includes('alpha')) { + if (version?.includes('beta') || version?.includes('alpha')) { versionColor = red; } const banners = [ @@ -80,12 +84,10 @@ ${b}⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⢾⡃⠀⠀${w} // Randomly select and log one banner const randomBanner = banners[Math.floor(Math.random() * banners.length)]; - if (!hideBanner) { - console.log(randomBanner); - } else { - console.log(`*** elizaOS ***`); - } + console.log(randomBanner); - // log the version - console.log(`${versionColor}Version: ${version}${r}`); + if (version) { + // log the version + console.log(`${versionColor}Version: ${version}${r}`); + } } diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index 4ba38c4abc7..5aa0db2e572 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -21,6 +21,9 @@ import { test } from './commands/test'; import { update } from './commands/update'; import { loadEnvironment } from './utils/get-config'; import { displayBanner } from './displayBanner'; +//import { discordPlugin } from "@elizaos/plugin-discord"; +import * as discordPlugin from '@elizaos/plugin-discord'; +console.log('discordPlugin', discordPlugin); process.on('SIGINT', () => process.exit(0)); process.on('SIGTERM', () => process.exit(0)); @@ -65,7 +68,7 @@ async function main() { // if no args are passed, display the banner if (process.argv.length === 2) { - displayBanner(version); + displayBanner(); } await program.parseAsync(); diff --git a/packages/cli/src/server/api/agent.ts b/packages/cli/src/server/api/agent.ts index 0b397b88ba0..1dd2d3f7e58 100644 --- a/packages/cli/src/server/api/agent.ts +++ b/packages/cli/src/server/api/agent.ts @@ -9,6 +9,9 @@ import { messageHandlerTemplate, validateUuid, MemoryType, + encryptStringValue, + getSalt, + encryptObjectValues, } from '@elizaos/core'; import express from 'express'; import fs from 'node:fs'; @@ -159,6 +162,13 @@ export function agentRouter( throw new Error('Failed to create character configuration'); } + // Encrypt secrets if they exist in the character + if (character.settings?.secrets) { + logger.debug('[AGENT CREATE] Encrypting secrets'); + const salt = getSalt(); + character.settings.secrets = encryptObjectValues(character.settings.secrets, salt); + } + await db.ensureAgentExists(character); res.status(201).json({ @@ -198,6 +208,31 @@ export function agentRouter( const updates = req.body; try { + // Handle encryption of secrets if present in updates + if (updates.settings?.secrets) { + const salt = getSalt(); + const encryptedSecrets: Record = {}; + + // Encrypt each secret value + // We need to handle null values separately + // because they mean delete the secret + Object.entries(updates.settings.secrets).forEach(([key, value]) => { + if (value === null) { + // Null means delete the secret + encryptedSecrets[key] = null; + } else if (typeof value === 'string') { + // Only encrypt string values + encryptedSecrets[key] = encryptStringValue(value, salt); + } else { + // Leave other types as is + encryptedSecrets[key] = value as string; + } + }); + + // Replace with encrypted secrets + updates.settings.secrets = encryptedSecrets; + } + // Handle other updates if any if (Object.keys(updates).length > 0) { await db.updateAgent(agentId, updates); @@ -276,6 +311,7 @@ export function agentRouter( // Start an existing agent router.post('/:agentId', async (req, res) => { + console.log('start agent req', req); const agentId = validateUuid(req.params.agentId); if (!agentId) { res.status(400).json({ diff --git a/packages/cli/src/server/api/env.ts b/packages/cli/src/server/api/env.ts new file mode 100644 index 00000000000..3ffd885d8b9 --- /dev/null +++ b/packages/cli/src/server/api/env.ts @@ -0,0 +1,155 @@ +import { logger } from '@elizaos/core'; +import express from 'express'; +import { parseEnvFile, getGlobalEnvPath } from '@/src/commands/env'; +import path from 'node:path'; +import { existsSync, writeFileSync } from 'fs'; + +function serializeEnvObject(envObj: Record): string { + return Object.entries(envObj) + .map(([key, val]) => `${key}=${val ?? ''}`) + .join('\n\n'); +} + +function findUpFile(filename: string, startDir: string = process.cwd()): string | null { + let currentDir = startDir; + + while (true) { + const fullPath = path.join(currentDir, filename); + if (existsSync(fullPath)) return fullPath; + + const parentDir = path.dirname(currentDir); + if (parentDir === currentDir) { + return null; // Reached root + } + currentDir = parentDir; + } +} + +function getLocalEnvPath(): string | null { + const envPath = findUpFile('.env'); + return envPath; +} + +export function envRouter(): express.Router { + const router = express.Router(); + + router.get('/local', async (req, res) => { + try { + const localEnvPath = getLocalEnvPath(); + const localEnvs = await parseEnvFile(localEnvPath); + + res.json({ + success: true, + data: localEnvs, + }); + } catch (error) { + logger.error(`[ENVS GET] Error retrieving local envs`, error); + res.status(500).json({ + success: false, + error: { + code: 'FETCH_ERROR', + message: 'Failed to retrieve local envs', + details: error.message, + }, + }); + } + }); + + router.post('/local', async (req, res) => { + try { + const { content } = req.body; + + if (!content || typeof content !== 'object') { + res.status(400).json({ + success: false, + error: { + code: 'INVALID_INPUT', + message: 'Missing or invalid "content" in request body', + }, + }); + } + + const localEnvPath = getLocalEnvPath(); + if (!localEnvPath) throw new Error('Local .env file not found'); + + const envString = serializeEnvObject(content); + writeFileSync(localEnvPath, envString, 'utf-8'); + + res.json({ + success: true, + message: 'Local env updated', + }); + } catch (error) { + logger.error(`[ENVS POST] Error updating local envs`, error); + res.status(500).json({ + success: false, + error: { + code: 'UPDATE_ERROR', + message: 'Failed to update local envs', + details: error.message, + }, + }); + } + }); + + router.get('/global', async (req, res) => { + try { + const globalEnvPath = await getGlobalEnvPath(); + const globalEnvs = await parseEnvFile(globalEnvPath); + + res.json({ + success: true, + data: globalEnvs, + }); + } catch (error) { + logger.error(`[ENVS GET] Error retrieving global envs`, error); + res.status(500).json({ + success: false, + error: { + code: 'FETCH_ERROR', + message: 'Failed to retrieve global envs', + details: error.message, + }, + }); + } + }); + + router.post('/global', async (req, res) => { + try { + const { content } = req.body; + + if (!content || typeof content !== 'object') { + res.status(400).json({ + success: false, + error: { + code: 'INVALID_INPUT', + message: 'Missing or invalid "content" in request body', + }, + }); + } + + const globalEnvPath = await getGlobalEnvPath(); + if (!globalEnvPath) throw new Error('Global .env file not found'); + + const envString = serializeEnvObject(content); + writeFileSync(globalEnvPath, envString, 'utf-8'); + + res.json({ + success: true, + message: 'Global env updated', + }); + } catch (error) { + logger.error(`[ENVS POST] Error updating global envs`, error); + res.status(500).json({ + success: false, + error: { + code: 'UPDATE_ERROR', + message: 'Failed to update global envs', + details: error.message, + }, + }); + } + }); + + return router; +} diff --git a/packages/cli/src/server/api/index.ts b/packages/cli/src/server/api/index.ts index 74461651aba..577d0b700db 100644 --- a/packages/cli/src/server/api/index.ts +++ b/packages/cli/src/server/api/index.ts @@ -12,6 +12,7 @@ import { SOCKET_MESSAGE_TYPE, EventType, ChannelType } from '@elizaos/core'; import http from 'node:http'; import crypto from 'node:crypto'; import { worldRouter } from './world'; +import { envRouter } from './env'; // Custom levels from @elizaos/core logger const LOG_LEVELS = { @@ -77,6 +78,7 @@ export function setupSocketIO( const payload = messageData.payload; const socketRoomId = payload.roomId; const worldId = payload.worldId; + const senderId = payload.senderId; // Get all agents in this room const agentsInRoom = roomParticipants.get(socketRoomId) || new Set([socketRoomId as UUID]); @@ -92,7 +94,7 @@ export function setupSocketIO( } // Ensure the sender and recipient are different agents - if (payload.senderId === agentId) { + if (senderId === agentId) { logger.debug(`Message sender and recipient are the same agent (${agentId}), ignoring.`); continue; } @@ -101,7 +103,7 @@ export function setupSocketIO( logger.warn(`no message found`); continue; } - const entityId = createUniqueUuid(agentRuntime, payload.senderId); + const entityId = createUniqueUuid(agentRuntime, senderId); const uniqueRoomId = createUniqueUuid(agentRuntime, socketRoomId); const source = payload.source; @@ -247,6 +249,13 @@ export function setupSocketIO( runtime: agentRuntime, message: newMessage, callback, + onComplete: () => { + io.emit('messageComplete', { + roomId: socketRoomId, + agentId, + senderId, + }); + }, }); } catch (error) { logger.error('Error processing message:', error); @@ -529,6 +538,7 @@ export function createApiRouter( // Mount sub-routers router.use('/agents', agentRouter(agents, server)); router.use('/world', worldRouter(server)); + router.use('/envs', envRouter()); router.use('/tee', teeRouter(agents)); router.get('/stop', (_req, res) => { diff --git a/packages/cli/src/server/loader.ts b/packages/cli/src/server/loader.ts index 2b4c7d52665..9edab8e0c3c 100644 --- a/packages/cli/src/server/loader.ts +++ b/packages/cli/src/server/loader.ts @@ -137,12 +137,13 @@ export async function loadCharacterTryPath(characterPath: string): Promise setTimeout(resolve, 100)); + + // Then prompt for the username with a simple message const { promptedUsername } = await prompt.default({ type: 'text', name: 'promptedUsername', diff --git a/packages/cli/src/utils/handle-error.ts b/packages/cli/src/utils/handle-error.ts index 395f9308c23..82bed9321d5 100644 --- a/packages/cli/src/utils/handle-error.ts +++ b/packages/cli/src/utils/handle-error.ts @@ -1,5 +1,5 @@ import { logger } from '@elizaos/core'; - +import { AGENT_RUNTIME_URL } from '../commands/agent'; /** * Handles the error by logging it and exiting the process. * If the error is a string, it logs the error message and exits. @@ -19,3 +19,15 @@ export function handleError(error: unknown) { } process.exit(1); } + +export async function checkServer() { + const red = '\x1b[38;5;196m'; + const r = '\x1b[0m'; + try { + await fetch(`${AGENT_RUNTIME_URL}/api/ping`); + logger.success('ElizaOS server is running'); + } catch (error) { + logger.error(`${red}Unable to connect to ElizaOS server, likely not running!${r}`); + process.exit(1); + } +} diff --git a/packages/cli/src/utils/helpers.ts b/packages/cli/src/utils/helpers.ts index 4538bd881cd..d8973f93d47 100644 --- a/packages/cli/src/utils/helpers.ts +++ b/packages/cli/src/utils/helpers.ts @@ -9,79 +9,31 @@ export function displayAgent(data: Partial, title = 'Agent Review'): void logHeader(title); // Display basic info - logger.info(`Name: ${data.name}`); - logger.info(`Username: ${data.username || data.name?.toLowerCase().replace(/\s+/g, '_')}`); + console.log(`Name: ${data.name}`); + console.log(`Username: ${data.username || data.name?.toLowerCase().replace(/\s+/g, '_')}`); - // Display bio - logger.info('\nBio:'); - for (const line of Array.isArray(data.bio) ? data.bio : [data.bio]) { - logger.info(` ${line}`); - } - - // Display adjectives - logger.info('\nAdjectives:'); - for (const adj of data.adjectives || []) { - logger.info(` ${adj}`); - } - - // Display topics - if (data.topics && data.topics.length > 0) { - logger.info('\nTopics:'); - for (const topic of data.topics) { - logger.info(` ${topic}`); - } - } + // Display sections + displaySection('Bio', Array.isArray(data.bio) ? data.bio : [data.bio]); + displaySection('Adjectives', data.adjectives); + displaySection('Topics', data.topics); + displaySection('Plugins', data.plugins); - // Display plugins - if (data.plugins && data.plugins.length > 0) { - logger.info('\nPlugins:'); - for (const plugin of data.plugins) { - logger.info(` ${plugin}`); - } - } - - // Display style + // Display style sections if (data.style) { - if (data.style.all && data.style.all.length > 0) { - logger.info('\nGeneral Style:'); - for (const style of data.style.all) { - logger.info(` ${style}`); - } - } - if (data.style.chat && data.style.chat.length > 0) { - logger.info('\nChat Style:'); - for (const style of data.style.chat) { - logger.info(` ${style}`); - } - } - if (data.style.post && data.style.post.length > 0) { - logger.info('\nPost Style:'); - for (const style of data.style.post) { - logger.info(` ${style}`); - } - } + displaySection('General Style', data.style.all); + displaySection('Chat Style', data.style.chat); + displaySection('Post Style', data.style.post); } - // Display post examples - if (data.postExamples && data.postExamples.length > 0) { - logger.info('\nPost Examples:'); - for (const post of data.postExamples) { - logger.info(` ${post}`); - } - } + displaySection('Post Examples', data.postExamples); // Display message examples if (data.messageExamples && data.messageExamples.length > 0) { - logger.info('\nMessage Examples:'); - logger.info( + console.log(`\n${colors.cyan('Message Examples:')}`); + console.log( data.messageExamples .map((conversation, i) => { - const messages = conversation - .map((msg) => { - const user = msg.name === '{{name1}}' ? 'Anon' : msg.name; - return `${user}: ${msg.content.text}`; - }) - .join('\n'); + const messages = formatConversation(conversation); return `\nConversation ${i + 1}:\n${messages}`; }) .join('\n') @@ -89,11 +41,35 @@ export function displayAgent(data: Partial, title = 'Agent Review'): void } } +/** + * Formats a conversation into a string + */ +function formatConversation(conversation: MessageExample[]): string { + return conversation + .map((msg) => { + const user = msg.name === '{{name1}}' ? 'Anon' : msg.name; + return `${user}: ${msg.content.text}`; + }) + .join('\n'); +} + +/** + * Displays a section with a title and list of items + */ +function displaySection(title: string, items: string[] | undefined): void { + if (!items || items.length === 0) return; + + console.log(`\n${colors.cyan(`${title}:`)}`); + for (const item of items) { + console.log(` ${item}`); + } +} + /** * Logs a header inside a rectangular frame with extra padding. * @param {string} title - The header text to display. */ -function logHeader(title) { +function logHeader(title: string): void { const padding = 2; // number of spaces on each side const titleStr = `=== ${title} ===`; const paddedTitle = ' '.repeat(padding) + titleStr + ' '.repeat(padding); @@ -102,8 +78,10 @@ function logHeader(title) { // Create top and bottom borders using Unicode box drawing characters const topBorder = colors.green(`┌${'─'.repeat(borderLength)}┐`); const bottomBorder = colors.green(`└${'─'.repeat(borderLength)}┘`); - const middleRow = colors.green(`│${paddedTitle}│`); + + const coloredTitle = `${' '.repeat(padding)}=== ${colors.green(title)} ===${' '.repeat(padding)}`; + const middleRow = colors.green('│') + coloredTitle + colors.green('│'); // Log the rectangle with a leading new line for spacing - logger.info(`\n${topBorder}\n${middleRow}\n${bottomBorder}`); + console.log(`\n${topBorder}\n${middleRow}\n${bottomBorder}`); } diff --git a/packages/cli/src/utils/registry/index.ts b/packages/cli/src/utils/registry/index.ts index 1694c5d580e..7ed1b763776 100644 --- a/packages/cli/src/utils/registry/index.ts +++ b/packages/cli/src/utils/registry/index.ts @@ -318,6 +318,44 @@ export async function getRegistryIndex(): Promise> { return result; } +/** + * Normalizes a plugin name to the expected format in the registry + * + * @param {string} pluginName - The name of the plugin to normalize + * @returns {string[]} An array of possible normalized plugin names to try + */ +export function normalizePluginName(pluginName: string): string[] { + // Extract the base name without any organization prefix + let baseName = pluginName; + + // Handle various input formats + if (pluginName.includes('/')) { + // Handle formats like "elizaos/plugin-ton" or "elizaos-plugins/plugin-ton" + const parts = pluginName.split('/'); + baseName = parts[parts.length - 1]; + } else if (pluginName.startsWith('@')) { + // Handle scoped package format like "@elizaos/plugin-ton" + const parts = pluginName.split('/'); + if (parts.length > 1) { + baseName = parts[1]; + } + } + + // Remove any existing prefixes + baseName = baseName.replace(/^plugin-/, ''); + + // Generate all possible formats to try + return [ + pluginName, // Original input + baseName, // Just the base name + `plugin-${baseName}`, // With plugin- prefix + `@elizaos/${baseName}`, // Scoped with elizaos + `@elizaos/plugin-${baseName}`, // Scoped with elizaos and plugin prefix + `@elizaos-plugins/${baseName}`, // Scoped with elizaos-plugins + `@elizaos-plugins/plugin-${baseName}`, // Scoped with elizaos-plugins and plugin prefix + ]; +} + /** * Retrieves the repository URL for a given plugin from the registry. * @@ -327,25 +365,44 @@ export async function getRegistryIndex(): Promise> { */ export async function getPluginRepository(pluginName: string): Promise { try { + // Get all possible plugin name formats to try + const possibleNames = normalizePluginName(pluginName); + // First try getting from the local/public registry const registry = await getLocalRegistryIndex(); - if (registry[pluginName]) { - return registry[pluginName]; + + // Try each possible name format in the registry + for (const name of possibleNames) { + if (registry[name]) { + logger.debug(`Found plugin in registry as: ${name}`); + return registry[name]; + } } // Fall back to authenticated method if needed - const metadata = await getPluginMetadata(pluginName); - return metadata?.repository || null; - } catch (error) { - logger.debug(`Error getting plugin repository for ${pluginName}: ${error.message}`); - // Fall back to authenticated method - try { - const metadata = await getPluginMetadata(pluginName); - return metadata?.repository || null; - } catch (fallbackError) { - logger.error(`Failed to get plugin repository: ${fallbackError.message}`); - return null; + for (const name of possibleNames) { + try { + const metadata = await getPluginMetadata(name); + if (metadata?.repository) { + logger.debug(`Found plugin metadata for: ${name}`); + return metadata.repository; + } + } catch (error) { + // Continue to the next name format + logger.debug(`No metadata found for ${name}`); + } } + + // Direct GitHub shorthand (github:org/repo) + if (!pluginName.includes(':') && !pluginName.startsWith('@')) { + const baseName = pluginName.replace(/^plugin-/, ''); + return `github:elizaos-plugins/plugin-${baseName}`; + } + + return null; + } catch (error) { + logger.debug(`Error getting plugin repository: ${error.message}`); + return null; } } diff --git a/packages/cli/tsconfig.json b/packages/cli/tsconfig.json index 035494b4264..c6264bf0dbf 100644 --- a/packages/cli/tsconfig.json +++ b/packages/cli/tsconfig.json @@ -6,6 +6,7 @@ "module": "ESNext", "allowSyntheticDefaultImports": true, "target": "ESNext", + "typeRoots": ["./node_modules/@types"], "paths": { "@/*": ["*"], "@elizaos/core": ["../../core/src"], diff --git a/packages/client/src/App.tsx b/packages/client/src/App.tsx index 2fd5834e65f..eceabac5f2d 100644 --- a/packages/client/src/App.tsx +++ b/packages/client/src/App.tsx @@ -16,6 +16,7 @@ import Room from './routes/room'; import AgentCreatorRoute from './routes/createAgent'; import Home from './routes/home'; import Settings from './routes/settings'; +import EnvSettings from './components/env-settings'; // Create a query client with optimized settings const queryClient = new QueryClient({ @@ -88,6 +89,7 @@ function App() { } /> } /> } /> + } /> diff --git a/packages/client/src/components/agent-creator.tsx b/packages/client/src/components/agent-creator.tsx index c85831e3f06..8606dac9f4e 100644 --- a/packages/client/src/components/agent-creator.tsx +++ b/packages/client/src/components/agent-creator.tsx @@ -7,25 +7,32 @@ import { useState } from 'react'; import { useNavigate } from 'react-router-dom'; import AvatarPanel from './avatar-panel'; import PluginsPanel from './plugins-panel'; -import SecretPanel from './secret-panel'; +import { SecretPanel } from './secret-panel'; +import { useAgentUpdate } from '@/hooks/use-agent-update'; -const defaultCharacter = { +// Define a partial agent for initialization +const defaultCharacter: Partial = { name: '', username: '', system: '', bio: [] as string[], topics: [] as string[], adjectives: [] as string[], -} as Agent; + plugins: [], + settings: { secrets: {} }, +}; export default function AgentCreator() { const navigate = useNavigate(); const { toast } = useToast(); const queryClient = useQueryClient(); - const [characterValue, setCharacterValue] = useState({ + const [initialCharacter] = useState>({ ...defaultCharacter, }); + // Use agent update hook for proper handling of nested fields + const agentState = useAgentUpdate(initialCharacter as Agent); + const ensureRequiredFields = (character: Agent): Agent => { return { ...character, @@ -40,6 +47,7 @@ export default function AgentCreator() { chat: character.style?.chat ?? [], post: character.style?.post ?? [], }, + settings: character.settings ?? { secrets: {} }, }; }; @@ -70,12 +78,12 @@ export default function AgentCreator() { return ( setCharacterValue(defaultCharacter)} + onReset={() => agentState.reset()} onDelete={() => { navigate('/'); }} @@ -84,19 +92,24 @@ export default function AgentCreator() { { name: 'Plugins', component: ( - + ), }, { name: 'Secret', component: ( - + { + agentState.updateSettings(updatedAgent.settings); + }} + /> ), }, { name: 'Avatar', component: ( - + ), }, ]} diff --git a/packages/client/src/components/agent-settings.tsx b/packages/client/src/components/agent-settings.tsx index 829a68a930c..72e29714f05 100644 --- a/packages/client/src/components/agent-settings.tsx +++ b/packages/client/src/components/agent-settings.tsx @@ -1,35 +1,49 @@ import CharacterForm from '@/components/character-form'; +import { useAgentUpdate } from '@/hooks/use-agent-update'; import { useToast } from '@/hooks/use-toast'; import { apiClient } from '@/lib/api'; import type { Agent, UUID } from '@elizaos/core'; import { useQueryClient } from '@tanstack/react-query'; -import { useState } from 'react'; import { useNavigate } from 'react-router-dom'; import AvatarPanel from './avatar-panel'; import PluginsPanel from './plugins-panel'; -import SecretPanel from './secret-panel'; +import { SecretPanel } from './secret-panel'; export default function AgentSettings({ agent, agentId }: { agent: Agent; agentId: UUID }) { const { toast } = useToast(); const navigate = useNavigate(); const queryClient = useQueryClient(); - const [characterValue, setCharacterValue] = useState(agent); - const handleSubmit = async (updatedAgent: Agent) => { + // Use our enhanced agent update hook for more intelligent handling of JSONb fields + const agentState = useAgentUpdate(agent); + + const handleSubmit = async () => { try { - // Call the API to update the agent's character if (!agentId) { throw new Error('Agent ID is missing'); } - // Make sure plugins are preserved - const mergedAgent = { - ...updatedAgent, - plugins: characterValue.plugins, // Preserve the plugins from our local state + // Get only the fields that have changed + const changedFields = agentState.getChangedFields(); + + // No need to send update if nothing changed + if (Object.keys(changedFields).length === 0) { + toast({ + title: 'No Changes', + description: 'No changes were made to the agent', + }); + navigate('/'); + return; + } + + // Always include the ID + const partialUpdate = { + id: agentId, + ...changedFields, }; - // Send the character update request to the agent endpoint - await apiClient.updateAgent(agentId, mergedAgent); + // Send the partial update + await apiClient.updateAgent(agentId, partialUpdate as Agent); // Invalidate both the agent query and the agents list queryClient.invalidateQueries({ queryKey: ['agent', agentId] }); @@ -51,43 +65,66 @@ export default function AgentSettings({ agent, agentId }: { agent: Agent; agentI } }; - const handleDelete = async (agent: Agent) => { + const handleDelete = async () => { try { - await apiClient.deleteAgent(agent.id as UUID); + await apiClient.deleteAgent(agentId); queryClient.invalidateQueries({ queryKey: ['agents'] }); navigate('/'); + + toast({ + title: 'Success', + description: 'Agent deleted successfully', + }); } catch (error) { - console.error('Error deleting agent:', error); + toast({ + title: 'Error', + description: error instanceof Error ? error.message : 'Failed to delete agent', + variant: 'destructive', + }); } }; return ( setCharacterValue(agent)} - onDelete={() => handleDelete(agent)} + onReset={agentState.reset} + onDelete={handleDelete} isAgent={true} customComponents={[ { name: 'Plugins', component: ( - + ), }, { name: 'Secret', component: ( - + { + if (updatedAgent.settings?.secrets) { + // Create a new settings object with the updated secrets + const updatedSettings = { + ...agentState.agent.settings, + secrets: updatedAgent.settings.secrets, + }; + + // Use updateSettings to properly handle the secrets + agentState.updateSettings(updatedSettings); + } + }} + /> ), }, { name: 'Avatar', component: ( - + ), }, ]} diff --git a/packages/client/src/components/app-sidebar.tsx b/packages/client/src/components/app-sidebar.tsx index 18248389d60..eb81c905bd7 100644 --- a/packages/client/src/components/app-sidebar.tsx +++ b/packages/client/src/components/app-sidebar.tsx @@ -75,7 +75,7 @@ export function AppSidebar() { setOnlineAgents(onlineAgents); setOfflineAgents(offlineAgents); - }, [isRoomPage, agentsData, roomId]); + }, [isRoomPage, agentsData, roomId, roomsData]); return ( <> @@ -314,10 +314,12 @@ export function AppSidebar() { - - - Settings - + + + + Settings + + diff --git a/packages/client/src/components/avatar-panel.tsx b/packages/client/src/components/avatar-panel.tsx index 178f6d140e1..e20f8285a4d 100644 --- a/packages/client/src/components/avatar-panel.tsx +++ b/packages/client/src/components/avatar-panel.tsx @@ -1,39 +1,67 @@ import { Button } from '@/components/ui/button'; import type { Agent } from '@elizaos/core'; import { Image as ImageIcon, Upload, X } from 'lucide-react'; -import { useEffect, useRef, useState } from 'react'; +import { useRef, useState, useEffect } from 'react'; import { compressImage } from '@/lib/utils'; interface AvatarPanelProps { characterValue: Agent; - setCharacterValue: (value: (prev: Agent) => Agent) => void; + setCharacterValue: { + updateAvatar?: (avatarUrl: string) => void; + updateSetting?: (path: string, value: T) => void; + updateField?: (path: string, value: T) => void; + [key: string]: any; + }; } export default function AvatarPanel({ characterValue, setCharacterValue }: AvatarPanelProps) { const [avatar, setAvatar] = useState(characterValue?.settings?.avatar || null); + const [hasChanged, setHasChanged] = useState(false); const fileInputRef = useRef(null); + // Reset the change flag when component initializes or character changes + useEffect(() => { + setAvatar(characterValue?.settings?.avatar || null); + setHasChanged(false); + }, [characterValue.id]); + const handleFileUpload = async (event: React.ChangeEvent) => { const file = event.target.files?.[0]; if (file) { try { const compressedImage = await compressImage(file); setAvatar(compressedImage); + setHasChanged(true); + + // Only update when there's a real change + updateCharacterAvatar(compressedImage); } catch (error) { console.error('Error compressing image:', error); } } }; - useEffect(() => { - setCharacterValue((prev) => ({ - ...prev, - settings: { - ...prev.settings, - avatar: avatar, - }, - })); - }, [avatar, setCharacterValue]); + const handleRemoveAvatar = () => { + if (avatar) { + setAvatar(null); + setHasChanged(true); + updateCharacterAvatar(''); + } + }; + + // Centralized update function to avoid code duplication + const updateCharacterAvatar = (avatarUrl: string) => { + if (setCharacterValue.updateAvatar) { + // Use the specialized method for avatar updates when available + setCharacterValue.updateAvatar(avatarUrl); + } else if (setCharacterValue.updateSetting) { + // Use updateSetting as fallback + setCharacterValue.updateSetting('avatar', avatarUrl); + } else if (setCharacterValue.updateField) { + // Last resort - use the generic field update + setCharacterValue.updateField('settings.avatar', avatarUrl); + } + }; return (
@@ -45,7 +73,7 @@ export default function AvatarPanel({ characterValue, setCharacterValue }: Avata Character Avatar + + {hasChanged &&

Avatar has been updated

}
); diff --git a/packages/client/src/components/character-form.tsx b/packages/client/src/components/character-form.tsx index 8c69ff8fa17..a443b0b3fa0 100644 --- a/packages/client/src/components/character-form.tsx +++ b/packages/client/src/components/character-form.tsx @@ -136,7 +136,13 @@ export type CharacterFormProps = { isAgent?: boolean; customComponents?: customComponent[]; characterValue: Agent; - setCharacterValue: (value: (prev: Agent) => Agent) => void; + setCharacterValue: { + updateField: (path: string, value: T) => void; + addArrayItem?: (path: string, item: T) => void; + removeArrayItem?: (path: string, index: number) => void; + updateSetting?: (path: string, value: any) => void; + [key: string]: any; + }; }; export default function CharacterForm({ @@ -157,49 +163,45 @@ export default function CharacterForm({ const { name, value, type } = e.target; const checked = (e.target as HTMLInputElement).checked; - if (name.includes('.')) { - const parts = name.split('.'); - setCharacterValue((prev) => { - const newValue = { ...prev }; - let current: Record = newValue; - - for (let i = 0; i < parts.length - 1; i++) { - if (!current[parts[i]]) { - current[parts[i]] = {}; - } - current = current[parts[i]]; - } + if (type === 'checkbox') { + setCharacterValue.updateField(name, checked); + } else if (name.startsWith('settings.')) { + // Handle nested settings fields like settings.voice.model + const path = name.substring(9); // Remove 'settings.' prefix - current[parts[parts.length - 1]] = type === 'checkbox' ? checked : value; - return newValue; - }); + if (setCharacterValue.updateSetting) { + // Use the specialized method if available + setCharacterValue.updateSetting(path, value); + } else { + // Fall back to generic updateField + setCharacterValue.updateField(name, value); + } } else { - setCharacterValue((prev) => ({ - ...prev, - [name]: type === 'checkbox' ? checked : value, - })); + setCharacterValue.updateField(name, value); } }; const updateArray = (path: string, newData: string[]) => { - setCharacterValue((prev) => { - const newValue = { ...prev }; - const keys = path.split('.'); - let current: any = newValue; - - for (let i = 0; i < keys.length - 1; i++) { - const key = keys[i]; + // If the path is a simple field name + if (!path.includes('.')) { + setCharacterValue.updateField(path, newData); + return; + } - if (!current[key] || typeof current[key] !== 'object') { - current[key] = {}; // Ensure path exists - } - current = current[key]; + // Handle nested paths (e.g. style.all) + const parts = path.split('.'); + if (parts.length === 2 && parts[0] === 'style') { + // For style arrays, use the setStyleArray method if available + if (setCharacterValue.setStyleArray) { + setCharacterValue.setStyleArray(parts[1] as 'all' | 'chat' | 'post', newData); + } else { + setCharacterValue.updateField(path, newData); } + return; + } - current[keys[keys.length - 1]] = newData; // Update array - - return newValue; - }); + // Default case - just update the field + setCharacterValue.updateField(path, newData); }; const ensureAvatarSize = async (char: Agent): Promise => { @@ -225,7 +227,7 @@ export default function CharacterForm({ return char; }; - const handleSubmit = async (e: FormEvent) => { + const handleFormSubmit = async (e: FormEvent) => { e.preventDefault(); setIsSubmitting(true); @@ -296,7 +298,7 @@ export default function CharacterForm({ -
+ { onReset?.(); - // setCharacterValue(character) }} > Reset Changes diff --git a/packages/client/src/components/chat.tsx b/packages/client/src/components/chat.tsx index 14684a94a3e..dde064e5517 100644 --- a/packages/client/src/components/chat.tsx +++ b/packages/client/src/components/chat.tsx @@ -43,11 +43,11 @@ const MemoizedMessageContent = React.memo(MessageContent); function MessageContent({ message, agentId, - isLastMessage, + shouldAnimate, }: { message: ContentWithUser; agentId: UUID; - isLastMessage: boolean; + shouldAnimate: boolean; }) { return (
@@ -77,7 +77,7 @@ function MessageContent({
{message.name === USER_NAME ? ( message.text - ) : isLastMessage && message.name !== USER_NAME ? ( + ) : shouldAnimate ? ( {message.text} ) : ( message.text @@ -87,7 +87,7 @@ function MessageContent({ message.thought && (message.name === USER_NAME ? ( message.thought - ) : isLastMessage && message.name !== USER_NAME ? ( + ) : shouldAnimate ? ( {message.thought} @@ -154,6 +154,7 @@ export default function Page({ }) { const [selectedFile, setSelectedFile] = useState(null); const [input, setInput] = useState(''); + const [messageProcessing, setMessageProcessing] = useState(false); const inputRef = useRef(null); const fileInputRef = useRef(null); @@ -167,6 +168,8 @@ export default function Page({ const socketIOManager = SocketIOManager.getInstance(); + const animatedMessageIdRef = useRef(null); + useEffect(() => { // Initialize Socket.io connection once with our entity ID socketIOManager.initialize(entityId, [agentId]); @@ -212,7 +215,6 @@ export default function Page({ ['messages', agentId, roomId, worldId], (old: ContentWithUser[] = []) => { console.log('[Chat] Current messages:', old?.length || 0); - // Check if this message is already in the list (avoid duplicates) const isDuplicate = old.some( (msg) => @@ -226,6 +228,8 @@ export default function Page({ return old; } + animatedMessageIdRef.current = newMessage.id; + return [...old, newMessage]; } ); @@ -234,15 +238,23 @@ export default function Page({ // setInput(prev => prev + ''); }; + const handleMessageComplete = (data: any) => { + if (data.roomId === roomId) { + setMessageProcessing(false); + } + }; + // Add listener for message broadcasts console.log('[Chat] Adding messageBroadcast listener'); socketIOManager.on('messageBroadcast', handleMessageBroadcasting); + socketIOManager.on('messageComplete', handleMessageComplete); return () => { // When leaving this chat, leave the room but don't disconnect console.log(`[Chat] Leaving room ${roomId}`); socketIOManager.leaveRoom(roomId); socketIOManager.off('messageBroadcast', handleMessageBroadcasting); + socketIOManager.off('messageComplete', handleMessageComplete); }; }, [roomId, agentId, entityId, queryClient, socketIOManager]); @@ -287,7 +299,9 @@ export default function Page({ const handleSendMessage = (e: React.FormEvent) => { e.preventDefault(); - if (!input) return; + if (!input || messageProcessing) return; + + const messageId = randomUUID(); // Always add the user's message immediately to the UI before sending it to the server const userMessage: ContentWithUser = { @@ -298,7 +312,7 @@ export default function Page({ senderName: USER_NAME, roomId: roomId, source: CHAT_SOURCE, - id: randomUUID(), // Add a unique ID for React keys and duplicate detection + id: messageId, // Add a unique ID for React keys and duplicate detection }; console.log('[Chat] Adding user message to UI:', userMessage); @@ -324,12 +338,10 @@ export default function Page({ } ); - // We don't need to call scrollToBottom here, the message count change will trigger it - // via the useEffect hook - // Send the message to the server/agent socketIOManager.sendMessage(input, roomId, CHAT_SOURCE); + setMessageProcessing(true); setSelectedFile(null); setInput(''); formRef.current?.reset(); @@ -413,12 +425,15 @@ export default function Page({ > {messages.map((message: ContentWithUser, index: number) => { const isUser = message.name === USER_NAME; - + const shouldAnimate = + index === messages.length - 1 && + message.name !== USER_NAME && + message.id === animatedMessageIdRef.current; return (
@@ -443,7 +458,7 @@ export default function Page({
@@ -520,8 +535,21 @@ export default function Page({ agentId={agentId} onChange={(newInput: string) => setInput(newInput)} /> -
diff --git a/packages/client/src/components/env-settings.tsx b/packages/client/src/components/env-settings.tsx new file mode 100644 index 00000000000..6e6a9425783 --- /dev/null +++ b/packages/client/src/components/env-settings.tsx @@ -0,0 +1,317 @@ +import { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs'; +import { useEffect, useRef, useState } from 'react'; +import { Card, CardContent } from '@/components/ui/card'; +import { Input } from './ui/input'; +import { Check, Eye, EyeOff, MoreVertical, X } from 'lucide-react'; +import { Button } from './ui/button'; +import { apiClient } from '@/lib/api'; + +enum EnvType { + GLOBAL = 'global', + LOCAL = 'local', +} + +export default function EnvSettings() { + const [name, setName] = useState(''); + const [value, setValue] = useState(''); + const [showPassword, setShowPassword] = useState(false); + const [openIndex, setOpenIndex] = useState(null); + const [editingIndex, setEditingIndex] = useState(null); + const [editedValue, setEditedValue] = useState(''); + const [globalEnvs, setGlobalEnvs] = useState>({}); + const [localEnvs, setLocalEnvs] = useState>({}); + const dropdownRef = useRef(null); + const [activeTab, setActiveTab] = useState(EnvType.GLOBAL); + const [isUpdating, setIsUpdating] = useState(false); + + useEffect(() => { + const handleClickOutside = (event: MouseEvent) => { + if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) { + setOpenIndex(null); + } + }; + + document.addEventListener('mousedown', handleClickOutside); + return () => { + document.removeEventListener('mousedown', handleClickOutside); + }; + }, []); + + useEffect(() => { + fetchGlobalEnvs(); + fetchLocalEnvs(); + }, []); + + const fetchGlobalEnvs = async () => { + const data = await apiClient.getGlobalEnvs(); + setGlobalEnvs(data.data); + }; + + const fetchLocalEnvs = async () => { + const data = await apiClient.getLocalEnvs(); + setLocalEnvs(data.data); + }; + + const handleReset = async () => { + if (activeTab === EnvType.GLOBAL) { + await fetchGlobalEnvs(); + } else { + await fetchLocalEnvs(); + } + + setEditingIndex(null); + setOpenIndex(null); + setName(''); + setValue(''); + }; + + const ENV_TABS_SCHEMA = [ + { + sectionTitle: 'Global Env', + sectionValue: EnvType.GLOBAL, + data: globalEnvs, + }, + { + sectionTitle: 'Local Env', + sectionValue: EnvType.LOCAL, + data: localEnvs, + }, + ]; + + const handleEdit = (key: string) => { + setEditingIndex(openIndex); + const envs = activeTab === EnvType.GLOBAL ? globalEnvs : localEnvs; + setEditedValue(envs[key]); + setOpenIndex(null); + }; + + const handleRemove = (key: string) => { + const updateFn = activeTab === EnvType.GLOBAL ? setGlobalEnvs : setLocalEnvs; + const prevData = activeTab === EnvType.GLOBAL ? globalEnvs : localEnvs; + + const updatedData = { ...prevData }; + delete updatedData[key]; + + updateFn(updatedData); + setOpenIndex(null); + }; + + const saveEdit = (key: string) => { + const updateFn = activeTab === EnvType.GLOBAL ? setGlobalEnvs : setLocalEnvs; + const prevData = activeTab === EnvType.GLOBAL ? globalEnvs : localEnvs; + + updateFn({ + ...prevData, + [key]: editedValue, + }); + + setEditingIndex(null); + }; + + const addEnv = () => { + if (!name || !value) return; + + const updateFn = activeTab === EnvType.GLOBAL ? setGlobalEnvs : setLocalEnvs; + const prevData = activeTab === EnvType.GLOBAL ? globalEnvs : localEnvs; + + updateFn({ + ...prevData, + [name]: value, + }); + + setName(''); + setValue(''); + setEditingIndex(null); + }; + + return ( +
+
+
+

Envs settings

+

Envs settings

+
+
+ + { + setActiveTab(val); + setEditingIndex(null); + }} + > + + {ENV_TABS_SCHEMA.map((section) => ( + + {section.sectionTitle} + + ))} + + + + + {ENV_TABS_SCHEMA.map((section) => ( + +
+

Environment Settings

+
+
+ + setName(e.target.value)} + /> +
+
+ +
+ setValue(e.target.value)} + className="pr-10" + /> +
setShowPassword(!showPassword)} + > + {showPassword ? : } +
+
+
+ +
+ + {section?.data && ( +
+
Name
+
Value
+
Action
+
+ )} + +
+ {section?.data && + Object.entries(section.data).map(([key, value], index) => ( +
+
{key}
+
+ {editingIndex === index ? ( +
+ setEditedValue(e.target.value)} + className="w-full" + /> + + +
+ ) : ( +
Encrypted
+ )} +
+
+ + {openIndex === index && ( +
+ +
handleRemove(key)} + > + Remove +
+
+ )} +
+
+ ))} +
+
+
+ ))} +
+
+
+
+
+ + +
+
+
+ ); +} diff --git a/packages/client/src/components/group-panel.tsx b/packages/client/src/components/group-panel.tsx index 787d05730be..91defbc6367 100644 --- a/packages/client/src/components/group-panel.tsx +++ b/packages/client/src/components/group-panel.tsx @@ -3,7 +3,7 @@ import { Separator } from '@/components/ui/separator'; import { GROUP_CHAT_SOURCE } from '@/constants'; import { useRooms } from '@/hooks/use-query-hooks'; import { apiClient } from '@/lib/api'; -import { type Agent, AgentStatus } from '@elizaos/core'; +import { type Agent, AgentStatus, type UUID } from '@elizaos/core'; import { useQueryClient } from '@tanstack/react-query'; import { Loader2, Save, Trash, X } from 'lucide-react'; import { useEffect, useState } from 'react'; @@ -81,11 +81,6 @@ export default function GroupPanel({ onClose, agents, groupId }: GroupPanel) {
{ - if (e.key === 'Enter' || e.key === ' ') { - onClose(); - } - }} > e.stopPropagation()}> diff --git a/packages/client/src/components/memory-viewer.tsx b/packages/client/src/components/memory-viewer.tsx index 204e3f057ea..d4ecfb24d55 100644 --- a/packages/client/src/components/memory-viewer.tsx +++ b/packages/client/src/components/memory-viewer.tsx @@ -258,7 +258,13 @@ export function AgentMemoryViewer({ agentId, agentName }: { agentId: UUID; agent {content.actions.join(', ')} )} + {content.source && ( + + {content.source} + + )}
+ {timestamp} diff --git a/packages/client/src/components/plugins-panel.tsx b/packages/client/src/components/plugins-panel.tsx index 34eca9c92ee..af42b814174 100644 --- a/packages/client/src/components/plugins-panel.tsx +++ b/packages/client/src/components/plugins-panel.tsx @@ -8,23 +8,25 @@ import { import { Input } from '@/components/ui/input'; import { usePlugins } from '@/hooks/use-plugins'; import type { Agent } from '@elizaos/core'; -import { useMemo, useState } from 'react'; +import { useMemo, useState, useEffect } from 'react'; import { Button } from './ui/button'; interface PluginsPanelProps { characterValue: Agent; - setCharacterValue: (value: (prev: Agent) => Agent) => void; + setCharacterValue: { + addPlugin?: (pluginId: string) => void; + removePlugin?: (index: number) => void; + setPlugins?: (plugins: string[]) => void; + updateField?: (path: string, value: T) => void; + [key: string]: any; + }; } export default function PluginsPanel({ characterValue, setCharacterValue }: PluginsPanelProps) { const { data: plugins, error } = usePlugins(); const [searchQuery, setSearchQuery] = useState(''); const [isDialogOpen, setIsDialogOpen] = useState(false); - - const pluginNames = useMemo(() => { - if (!plugins) return []; - return Object.keys(plugins).map((name) => name.replace(/^@elizaos-plugins\//, '@elizaos/')); - }, [plugins]); + const [hasChanged, setHasChanged] = useState(false); // Ensure we always have arrays and normalize plugin names const safeCharacterPlugins = useMemo(() => { @@ -32,24 +34,57 @@ export default function PluginsPanel({ characterValue, setCharacterValue }: Plug return characterValue.plugins; }, [characterValue?.plugins]); + // Get plugin names from available plugins + const pluginNames = useMemo(() => { + const defaultPlugins = ['@elizaos/plugin-sql', '@elizaos/plugin-local-ai']; + if (!plugins) return defaultPlugins; + return [ + ...defaultPlugins, + ...(Array.isArray(plugins) ? plugins : Object.keys(plugins)) + .map((name) => name.replace(/^@elizaos-plugins\//, '@elizaos/')) + .filter((name) => !defaultPlugins.includes(name)), + ]; + }, [plugins]); + + // Reset change tracking when character changes + useEffect(() => { + setHasChanged(false); + }, [characterValue.id]); + const filteredPlugins = useMemo(() => { return pluginNames .filter((plugin) => !safeCharacterPlugins.includes(plugin)) .filter((plugin) => plugin.toLowerCase().includes(searchQuery.toLowerCase())); }, [pluginNames, safeCharacterPlugins, searchQuery]); - const handlePluginToggle = (plugin: string) => { - setCharacterValue((prev) => { - const currentPlugins = Array.isArray(prev.plugins) ? prev.plugins : []; - const newPlugins = currentPlugins.includes(plugin) - ? currentPlugins.filter((p) => p !== plugin) - : [...currentPlugins, plugin]; + const handlePluginAdd = (plugin: string) => { + if (safeCharacterPlugins.includes(plugin)) return; + + setHasChanged(true); + + if (setCharacterValue.addPlugin) { + setCharacterValue.addPlugin(plugin); + } else if (setCharacterValue.updateField) { + const currentPlugins = Array.isArray(characterValue.plugins) + ? [...characterValue.plugins] + : []; + setCharacterValue.updateField('plugins', [...currentPlugins, plugin]); + } + }; + + const handlePluginRemove = (plugin: string) => { + const index = safeCharacterPlugins.indexOf(plugin); + if (index !== -1) { + setHasChanged(true); - return { - ...prev, - plugins: newPlugins, - }; - }); + if (setCharacterValue.removePlugin) { + setCharacterValue.removePlugin(index); + } else if (setCharacterValue.updateField) { + const newPlugins = [...safeCharacterPlugins]; + newPlugins.splice(index, 1); + setCharacterValue.updateField('plugins', newPlugins); + } + } }; return ( @@ -72,7 +107,7 @@ export default function PluginsPanel({ characterValue, setCharacterValue }: Plug size="sm" key={plugin} className="inline-flex items-center rounded-full bg-primary/10 px-2.5 py-0.5 text-xs font-medium text-primary hover:bg-primary/20 h-auto" - onClick={() => handlePluginToggle(plugin)} + onClick={() => handlePluginRemove(plugin)} > {plugin} × @@ -110,7 +145,7 @@ export default function PluginsPanel({ characterValue, setCharacterValue }: Plug variant="ghost" className="w-full justify-start font-normal" onClick={() => { - handlePluginToggle(plugin); + handlePluginAdd(plugin); setSearchQuery(''); setIsDialogOpen(false); }} @@ -124,6 +159,9 @@ export default function PluginsPanel({ characterValue, setCharacterValue }: Plug
+ {hasChanged && ( +

Plugins configuration has been updated

+ )} )} diff --git a/packages/client/src/components/room.tsx b/packages/client/src/components/room.tsx index 5bb06076fb3..69956b0aa29 100644 --- a/packages/client/src/components/room.tsx +++ b/packages/client/src/components/room.tsx @@ -39,11 +39,11 @@ const MemoizedMessageContent = React.memo(MessageContent); function MessageContent({ message, - isLastMessage, + shouldAnimate, isUser, }: { message: ContentWithUser; - isLastMessage: boolean; + shouldAnimate: boolean; isUser: boolean; }) { // Only log message details in development mode @@ -84,7 +84,7 @@ function MessageContent({
{isUser ? ( message.text - ) : isLastMessage && !isUser ? ( + ) : shouldAnimate ? ( {message.text} ) : ( message.text @@ -94,7 +94,7 @@ function MessageContent({
{isUser ? ( message.thought - ) : isLastMessage && !isUser ? ( + ) : shouldAnimate ? ( {message.thought} @@ -173,6 +173,8 @@ export default function Page({ serverId }: { serverId: UUID }) { const prevServerIdRef = useRef(null); const prevActiveAgentIdsRef = useRef([]); + const animatedMessageIdRef = useRef(null); + const getAvatar = (agentId: string): string | null => { const rooms = roomsData?.get(serverId); const room = rooms?.find((room) => room.agentId === agentId); @@ -278,6 +280,8 @@ export default function Page({ serverId }: { serverId: UUID }) { return old; } + animatedMessageIdRef.current = newMessage.id; + return [...old, newMessage]; } ); @@ -481,11 +485,14 @@ export default function Page({ serverId }: { serverId: UUID }) { > {messages.map((message: ContentWithUser, index: number) => { const isUser = message.name === USER_NAME; - + const shouldAnimate = + index === messages.length - 1 && + message.name !== USER_NAME && + message.id === animatedMessageIdRef.current; return (
diff --git a/packages/client/src/components/secret-panel.tsx b/packages/client/src/components/secret-panel.tsx index 29d58a35172..193b70c9edd 100644 --- a/packages/client/src/components/secret-panel.tsx +++ b/packages/client/src/components/secret-panel.tsx @@ -7,31 +7,40 @@ import { useEffect, useRef, useState } from 'react'; type EnvVariable = { name: string; value: string; + isNew?: boolean; + isModified?: boolean; + isDeleted?: boolean; }; interface SecretPanelProps { characterValue: Agent; - setCharacterValue: (value: (prev: Agent) => Agent) => void; + onChange: (updatedAgent: Agent) => void; } -export default function EnvSettingsPanel({ characterValue, setCharacterValue }: SecretPanelProps) { - const [envs, setEnvs] = useState( - Object.entries(characterValue?.settings?.secrets || {}).map(([name, value]) => ({ +export function SecretPanel({ characterValue, onChange }: SecretPanelProps) { + const initialSecrets = Object.entries(characterValue?.settings?.secrets || {}).map( + ([name, value]) => ({ name, value: String(value), - })) + isNew: false, + isModified: false, + isDeleted: false, + }) ); + const [envs, setEnvs] = useState(initialSecrets); const [name, setName] = useState(''); const [value, setValue] = useState(''); const [showPassword, setShowPassword] = useState(false); const [openIndex, setOpenIndex] = useState(null); const [editingIndex, setEditingIndex] = useState(null); const [editedValue, setEditedValue] = useState(''); + const [isDragging, setIsDragging] = useState(false); + const [deletedKeys, setDeletedKeys] = useState([]); + const [changesPending, setChangesPending] = useState(false); const dropdownRef = useRef(null); const dropRef = useRef(null); - const [isDragging, setIsDragging] = useState(false); const handleFile = (file: File) => { const reader = new FileReader(); @@ -57,8 +66,19 @@ export default function EnvSettingsPanel({ characterValue, setCharacterValue }: for (const [key, val] of Object.entries(newEnvs)) { merged.set(key, val); } - return Array.from(merged.entries()).map(([name, value]) => ({ name, value })); + return Array.from(merged.entries()).map(([name, value]) => ({ + name, + value, + isNew: !prev.some((env) => env.name === name), + isModified: prev.some((env) => env.name === name && env.value !== value), + })); }); + + if (deletedKeys.length > 0) { + setDeletedKeys((prev) => prev.filter((key) => !Object.keys(newEnvs).includes(key))); + } + + setChangesPending(true); }; reader.readAsText(file); }; @@ -104,18 +124,22 @@ export default function EnvSettingsPanel({ characterValue, setCharacterValue }: const addEnv = () => { if (name && value) { - setEnvs((prev) => { - const updated = [...prev]; - const existingIndex = updated.findIndex((env) => env.name === name); - if (existingIndex !== -1) { - updated[existingIndex].value = value; - } else { - updated.push({ name, value }); + const exists = envs.some((env) => env.name === name); + if (!exists) { + if (deletedKeys.includes(name)) { + setDeletedKeys(deletedKeys.filter((key) => key !== name)); } - return updated; - }); - setName(''); - setValue(''); + + setEnvs([...envs, { name, value, isNew: true }]); + setName(''); + setValue(''); + setChangesPending(true); + } else { + setEnvs(envs.map((env) => (env.name === name ? { ...env, value, isModified: true } : env))); + setName(''); + setValue(''); + setChangesPending(true); + } } }; @@ -127,15 +151,24 @@ export default function EnvSettingsPanel({ characterValue, setCharacterValue }: const saveEdit = (index: number) => { const updatedEnvs = [...envs]; - updatedEnvs[index].value = editedValue; + if (updatedEnvs[index].value !== editedValue) { + updatedEnvs[index].value = editedValue; + updatedEnvs[index].isModified = true; + setChangesPending(true); + } setEnvs(updatedEnvs); setEditingIndex(null); }; const removeEnv = (index: number) => { + const keyToRemove = envs[index].name; + + setDeletedKeys([...deletedKeys, keyToRemove]); + setEnvs(envs.filter((_, i) => i !== index)); setOpenIndex(null); setEditingIndex(null); + setChangesPending(true); }; useEffect(() => { @@ -152,14 +185,37 @@ export default function EnvSettingsPanel({ characterValue, setCharacterValue }: }, []); useEffect(() => { - setCharacterValue((prev) => ({ - ...prev, - settings: { - ...prev.settings, - secrets: Object.fromEntries(envs.map(({ name, value }) => [name, value])), - }, - })); - }, [envs, setCharacterValue]); + if (changesPending) { + const currentSecrets: Record = {}; + + envs.forEach(({ name, value }) => { + currentSecrets[name] = value; + }); + + deletedKeys.forEach((key) => { + currentSecrets[key] = null; + }); + + const updatedAgent: Partial = { + settings: { + secrets: currentSecrets, + }, + }; + + onChange(updatedAgent as Agent); + + setEnvs((prevEnvs) => { + return prevEnvs.map((env) => ({ + ...env, + isNew: false, + isModified: false, + })); + }); + + setDeletedKeys([]); + setChangesPending(false); + } + }, [envs, onChange, deletedKeys, changesPending]); return (
@@ -304,3 +360,6 @@ export default function EnvSettingsPanel({ characterValue, setCharacterValue }:
); } + +// Also provide a default export for backward compatibility +export default SecretPanel; diff --git a/packages/client/src/components/ui/chat/chat-message-list.tsx b/packages/client/src/components/ui/chat/chat-message-list.tsx index 6e240f365c8..075a44c2834 100644 --- a/packages/client/src/components/ui/chat/chat-message-list.tsx +++ b/packages/client/src/components/ui/chat/chat-message-list.tsx @@ -24,7 +24,7 @@ const ChatMessageList = React.forwardRef( onTouchMove={disableAutoScroll} {...props} > -
{children}
+
{children}
{!isAtBottom && ( diff --git a/packages/client/src/hooks/use-agent-update.ts b/packages/client/src/hooks/use-agent-update.ts new file mode 100644 index 00000000000..08018585049 --- /dev/null +++ b/packages/client/src/hooks/use-agent-update.ts @@ -0,0 +1,402 @@ +import { usePartialUpdate } from '@/hooks/use-partial-update'; +import type { Agent } from '@elizaos/core'; +import { useCallback, useRef } from 'react'; + +/** + * A custom hook for handling Agent updates with specific handling for JSONb fields. + * This hook builds on usePartialUpdate but adds Agent-specific convenience methods + * organized by the UI tabs (Basic Info, Content, Style, Plugins, etc.). + * + * @param initialAgent The initial Agent object + * @returns Object with agent state and update methods + */ +export function useAgentUpdate(initialAgent: Agent) { + // Keep reference to the initial state for comparison + const initialAgentRef = useRef(JSON.parse(JSON.stringify(initialAgent))); + + const { + value: agent, + updateField, + addArrayItem, + removeArrayItem, + reset, + updateSettings, + } = usePartialUpdate(initialAgent); + + // ==================== Basic Info Tab ==================== + /** + * Updates a field in the Agent's settings object + * + * @param path Path within settings (e.g., 'voice.model') + * @param value New value + */ + const updateSetting = useCallback( + (path: string, value: T) => { + updateField(`settings.${path}`, value); + }, + [updateField] + ); + + /** + * Updates the entire settings object + * + * @param settings The new settings object + */ + const setSettings = useCallback( + (settings: any) => { + updateSettings(settings); + }, + [updateSettings] + ); + + /** + * Updates the agent's system prompt + * + * @param systemPrompt The new system prompt + */ + const updateSystemPrompt = useCallback( + (systemPrompt: string) => { + updateField('system', systemPrompt); + }, + [updateField] + ); + + // ==================== Secrets Tab ==================== + /** + * Updates a secret in the Agent's settings.secrets object + * + * @param key Secret key + * @param value Secret value + */ + const updateSecret = useCallback( + (key: string, value: string) => { + // Handle nested secrets object properly + const currentSettings = agent.settings || {}; + const currentSecrets = currentSettings.secrets || {}; + + const newSecrets = { + ...currentSecrets, + [key]: value, + }; + + // Update entire settings object for better change detection + updateSettings({ + ...currentSettings, + secrets: newSecrets, + }); + }, + [agent.settings, updateSettings] + ); + + /** + * Removes a secret from the Agent's settings.secrets object + * + * @param key Secret key to remove + */ + const removeSecret = useCallback( + (key: string) => { + // Get the current secrets object + const currentSettings = agent.settings || {}; + const currentSecrets = currentSettings.secrets || {}; + + // Create a new secrets object without the removed key + const newSecrets = { ...currentSecrets }; + delete newSecrets[key]; + + // Update the entire settings object to ensure nested changes are detected + const updatedSettings = { + ...currentSettings, + secrets: newSecrets, + }; + + // Use updateSettings instead of updateField for better change detection + updateSettings(updatedSettings); + }, + [agent.settings, updateSettings] + ); + + // ==================== Content Tab ==================== + /** + * Adds an item to a content array (bio, topics, adjectives) + * + * @param arrayName The name of the array field + * @param item The item to add + */ + const addContentItem = useCallback( + (arrayName: 'bio' | 'topics' | 'adjectives', item: string) => { + addArrayItem(arrayName, item); + }, + [addArrayItem] + ); + + /** + * Removes an item from a content array + * + * @param arrayName The name of the array field + * @param index The index of the item to remove + */ + const removeContentItem = useCallback( + (arrayName: 'bio' | 'topics' | 'adjectives', index: number) => { + removeArrayItem(arrayName, index); + }, + [removeArrayItem] + ); + + /** + * Updates an item in a content array + * + * @param arrayName The name of the array field + * @param index The index of the item to update + * @param value The new value + */ + const updateContentItem = useCallback( + (arrayName: 'bio' | 'topics' | 'adjectives', index: number, value: string) => { + updateField(`${arrayName}.${index}`, value); + }, + [updateField] + ); + + // ==================== Style Tab ==================== + /** + * Adds a style rule to one of the style arrays + * + * @param styleType Type of style ('all', 'chat', 'post') + * @param rule The style rule to add + */ + const addStyleRule = useCallback( + (styleType: 'all' | 'chat' | 'post', rule: string) => { + addArrayItem(`style.${styleType}`, rule); + }, + [addArrayItem] + ); + + /** + * Removes a style rule from one of the style arrays + * + * @param styleType Type of style ('all', 'chat', 'post') + * @param index The index of the rule to remove + */ + const removeStyleRule = useCallback( + (styleType: 'all' | 'chat' | 'post', index: number) => { + removeArrayItem(`style.${styleType}`, index); + }, + [removeArrayItem] + ); + + /** + * Updates a style rule in one of the style arrays + * + * @param styleType Type of style ('all', 'chat', 'post') + * @param index The index of the rule to update + * @param value The new rule value + */ + const updateStyleRule = useCallback( + (styleType: 'all' | 'chat' | 'post', index: number, value: string) => { + updateField(`style.${styleType}.${index}`, value); + }, + [updateField] + ); + + /** + * Sets a complete style array + * + * @param styleType Type of style ('all', 'chat', 'post') + * @param values Array of style values + */ + const setStyleArray = useCallback( + (styleType: 'all' | 'chat' | 'post', values: string[]) => { + updateField(`style.${styleType}`, values); + }, + [updateField] + ); + + // ==================== Plugins Tab ==================== + /** + * Adds a plugin to the agent's plugins array + * + * @param pluginId The plugin ID to add + */ + const addPlugin = useCallback( + (pluginId: string) => { + addArrayItem('plugins', pluginId); + }, + [addArrayItem] + ); + + /** + * Removes a plugin from the agent's plugins array + * + * @param index The index of the plugin to remove + */ + const removePlugin = useCallback( + (index: number) => { + removeArrayItem('plugins', index); + }, + [removeArrayItem] + ); + + /** + * Sets the entire plugins array + * + * @param plugins Array of plugin IDs + */ + const setPlugins = useCallback( + (plugins: string[]) => { + updateField('plugins', plugins); + }, + [updateField] + ); + + // ==================== Avatar Tab ==================== + /** + * Updates the agent's avatar + * + * @param avatarUrl The URL of the avatar image + */ + const updateAvatar = useCallback( + (avatarUrl: string) => { + updateSetting('avatar', avatarUrl); + }, + [updateSetting] + ); + + /** + * Returns an object containing only the fields that have changed + * compared to the initial agent state + */ + const getChangedFields = useCallback(() => { + const changedFields: Partial = {}; + const current = agent; + const initial = initialAgentRef.current; + + // Compare scalar properties + const scalarProps = ['name', 'username', 'system'] as const; + scalarProps.forEach((prop) => { + if (current[prop] !== initial[prop]) { + changedFields[prop] = current[prop]; + } + }); + + if (current.enabled !== initial.enabled) { + changedFields.enabled = current.enabled; + } + + // Compare array properties with type safety + if (JSON.stringify(current.bio) !== JSON.stringify(initial.bio)) { + changedFields.bio = current.bio; + } + + if (JSON.stringify(current.topics) !== JSON.stringify(initial.topics)) { + changedFields.topics = current.topics; + } + + if (JSON.stringify(current.adjectives) !== JSON.stringify(initial.adjectives)) { + changedFields.adjectives = current.adjectives; + } + + if (JSON.stringify(current.plugins) !== JSON.stringify(initial.plugins)) { + changedFields.plugins = current.plugins; + } + + // Compare style object + if (JSON.stringify(current.style) !== JSON.stringify(initial.style)) { + changedFields.style = current.style; + } + + // More granular comparison for settings object + const initialSettings = initial.settings || {}; + const currentSettings = current.settings || {}; + + // Check if any settings changed + if (JSON.stringify(currentSettings) !== JSON.stringify(initialSettings)) { + // Create a partial settings object with only changed fields + changedFields.settings = {}; + + // Check avatar separately + if (currentSettings.avatar !== initialSettings.avatar) { + changedFields.settings.avatar = currentSettings.avatar; + } + + // Check voice settings + if (JSON.stringify(currentSettings.voice) !== JSON.stringify(initialSettings.voice)) { + changedFields.settings.voice = currentSettings.voice; + } + + // Check secrets with special handling + if (JSON.stringify(currentSettings.secrets) !== JSON.stringify(initialSettings.secrets)) { + const initialSecrets = initialSettings.secrets || {}; + const currentSecrets = currentSettings.secrets || {}; + + // Only include secrets that were added or modified + const changedSecrets: Record = {}; + let hasSecretChanges = false; + + // Find added or modified secrets + Object.entries(currentSecrets).forEach(([key, value]) => { + if (initialSecrets[key] !== value) { + changedSecrets[key] = value; + hasSecretChanges = true; + } + }); + + // Find deleted secrets (null values indicate deletion) + Object.keys(initialSecrets).forEach((key) => { + if (currentSecrets[key] === undefined) { + changedSecrets[key] = null; + hasSecretChanges = true; + } + }); + + if (hasSecretChanges) { + if (!changedFields.settings) changedFields.settings = {}; + changedFields.settings.secrets = changedSecrets; + } + } + + // If no specific settings changed, don't include settings object + if (Object.keys(changedFields.settings).length === 0) { + delete changedFields.settings; + } + } + + return changedFields; + }, [agent]); + + return { + agent, + updateField, + reset, + updateSettings, + setSettings, + + // Method to get only changed fields + getChangedFields, + + // Basic Info Tab + updateSetting, + updateSystemPrompt, + + // Secrets Tab + updateSecret, + removeSecret, + + // Content Tab + addContentItem, + removeContentItem, + updateContentItem, + + // Style Tab + addStyleRule, + removeStyleRule, + updateStyleRule, + setStyleArray, + + // Plugins Tab + addPlugin, + removePlugin, + setPlugins, + + // Avatar Tab + updateAvatar, + }; +} diff --git a/packages/client/src/hooks/use-partial-update.ts b/packages/client/src/hooks/use-partial-update.ts new file mode 100644 index 00000000000..60b36490c16 --- /dev/null +++ b/packages/client/src/hooks/use-partial-update.ts @@ -0,0 +1,284 @@ +import { useState, useCallback } from 'react'; + +/** + * A custom hook for handling partial updates of objects with nested JSONb fields. + * This hook ensures that updates to nested objects and arrays are properly + * managed when sending updates to the server. + * + * @param initialValue The initial state object + * @returns A tuple containing: + * - The current state object + * - A function to update a specific field (handles nested paths) + * - A function to add an item to an array field + * - A function to remove an item from an array field + * - A function to set the entire object + * - A function to reset to initial state + */ +export function usePartialUpdate(initialValue: T) { + const [value, setValue] = useState(initialValue); + + /** + * Updates a specific field in the object, handling nested paths + * + * @param path The path to the field to update (e.g., 'settings.voice.model') + * @param newValue The new value for the field + */ + const updateField = useCallback((path: string, newValue: K) => { + setValue((prevValue) => { + // Handle simple (non-nested) case + if (!path.includes('.')) { + return { + ...prevValue, + [path]: newValue, + } as T; + } + + // Handle nested paths + const pathParts = path.split('.'); + const fieldToUpdate = pathParts[0]; + const remainingPath = pathParts.slice(1).join('.'); + + // Handle arrays in path (e.g., 'style.all.0') + const isArrayIndex = !isNaN(Number(pathParts[1])); + + if (isArrayIndex) { + const arrayName = pathParts[0]; + const index = Number(pathParts[1]); + // Ensure we're working with an array and handle it safely + const currentValue = prevValue[arrayName as keyof T]; + const array = Array.isArray(currentValue) ? [...currentValue] : []; + + if (pathParts.length === 2) { + // Direct array item update + array[index] = newValue; + } else { + // Updating a property of an object in an array + const deeperPath = pathParts.slice(2).join('.'); + array[index] = updateNestedObject(array[index], deeperPath, newValue); + } + + return { + ...prevValue, + [arrayName]: array, + } as T; + } + + // Special case for settings.secrets path + if (path.startsWith('settings.secrets.')) { + const secretKey = path.split('.')[2]; + + const currentSettings = (prevValue as any).settings || {}; + const currentSecrets = currentSettings.secrets || {}; + + const newSecrets = { + ...currentSecrets, + [secretKey]: newValue, + }; + + return { + ...prevValue, + settings: { + ...currentSettings, + secrets: newSecrets, + }, + } as T; + } + + // Handle regular nested objects + const result = { + ...prevValue, + [fieldToUpdate]: updateNestedObject( + prevValue[fieldToUpdate as keyof T], + remainingPath, + newValue + ), + } as T; + + return result; + }); + }, []); + + /** + * Helper function to update a nested object + */ + const updateNestedObject = (obj: K, path: string, value: V): K => { + if (!path.includes('.')) { + return { + ...obj, + [path]: value, + } as unknown as K; + } + + const [field, ...remainingPath] = path.split('.'); + const nextPath = remainingPath.join('.'); + + return { + ...obj, + [field]: updateNestedObject((obj as any)[field] || {}, nextPath, value), + } as unknown as K; + }; + + /** + * Adds an item to an array field + * + * @param path Path to the array field + * @param item Item to add + */ + const addArrayItem = useCallback((path: string, item: V) => { + setValue((prevValue) => { + const pathParts = path.split('.'); + + // Handle simple array field + if (pathParts.length === 1) { + const fieldName = pathParts[0]; + const currentArray = Array.isArray(prevValue[fieldName as keyof T]) + ? [...(prevValue[fieldName as keyof T] as unknown as V[])] + : []; + + return { + ...prevValue, + [fieldName]: [...currentArray, item], + } as T; + } + + // Handle nested array field + const updatePath = path; + const currentValue = getNestedValue(prevValue, updatePath); + const currentArray = Array.isArray(currentValue) ? [...currentValue] : []; + + return setNestedValue(prevValue, updatePath, [...currentArray, item]); + }); + }, []); + + /** + * Removes an item from an array field + * + * @param path Path to the array field + * @param index Index of the item to remove + */ + const removeArrayItem = useCallback((path: string, index: number) => { + setValue((prevValue) => { + const pathParts = path.split('.'); + + // Handle simple array field + if (pathParts.length === 1) { + const fieldName = pathParts[0]; + const currentArray = Array.isArray(prevValue[fieldName as keyof T]) + ? [...(prevValue[fieldName as keyof T] as unknown as any[])] + : []; + + if (index < 0 || index >= currentArray.length) return prevValue; + + return { + ...prevValue, + [fieldName]: [...currentArray.slice(0, index), ...currentArray.slice(index + 1)], + } as T; + } + + // Handle nested array field + const updatePath = path; + const currentValue = getNestedValue(prevValue, updatePath); + + if (!Array.isArray(currentValue) || index < 0 || index >= currentValue.length) { + return prevValue; + } + + const newArray = [...currentValue.slice(0, index), ...currentValue.slice(index + 1)]; + return setNestedValue(prevValue, updatePath, newArray); + }); + }, []); + + /** + * Helper function to get a nested value from an object + */ + const getNestedValue = (obj: any, path: string): any => { + const parts = path.split('.'); + let current = obj; + + for (const part of parts) { + if (current === null || current === undefined) { + return undefined; + } + current = current[part]; + } + + return current; + }; + + /** + * Helper function to set a nested value in an object + */ + const setNestedValue = (obj: O, path: string, value: V): O => { + const parts = path.split('.'); + + if (parts.length === 1) { + return { + ...obj, + [parts[0]]: value, + } as O; + } + + const [first, ...rest] = parts; + const nextObj = (obj as any)[first] || {}; + + return { + ...obj, + [first]: setNestedValue(nextObj, rest.join('.'), value), + } as O; + }; + + /** + * Resets to the initial state + */ + const reset = useCallback(() => { + setValue(initialValue); + }, [initialValue]); + + // Special handling for updating the entire settings object + const updateSettings = useCallback( + (settings: any) => { + setValue((prevValue) => { + // Extract settings but remove 'secrets' key to avoid duplication + const { secrets, ...otherSettings } = settings; + + // Create the updated settings object + const updatedSettings = { + ...(prevValue as any).settings, // Start with existing settings + ...otherSettings, // Add other settings (not secrets) + }; + + // Only add secrets if it was included in the update + if (secrets) { + // Create a new secrets object that only contains non-null values + const filteredSecrets: Record = {}; + + Object.entries(secrets).forEach(([key, value]) => { + // If value is null, don't include it (this is how we delete) + if (value !== null) { + filteredSecrets[key] = value; + } + }); + + updatedSettings.secrets = filteredSecrets; + } + + const result = { + ...prevValue, + settings: updatedSettings, + } as T; + + return result; + }); + }, + [] // Remove value from dependencies to avoid unnecessary rerenders + ); + + return { + value, + updateField, + addArrayItem, + removeArrayItem, + reset, + updateSettings, + }; +} diff --git a/packages/client/src/hooks/use-plugins.ts b/packages/client/src/hooks/use-plugins.ts index e126bd61df2..7062fba7fb5 100644 --- a/packages/client/src/hooks/use-plugins.ts +++ b/packages/client/src/hooks/use-plugins.ts @@ -8,10 +8,22 @@ export function usePlugins() { return useQuery({ queryKey: ['plugins'], queryFn: async () => { - const response = await fetch( - 'https://raw.githubusercontent.com/elizaos/registry/refs/heads/main/index.json' - ); - return response.json(); + // TODO: Temp disabled! + // const response = await fetch( + // 'https://raw.githubusercontent.com/elizaos/registry/refs/heads/main/index.json' + // ); + // return response.json(); + + // Temporarily return hardcoded plugins as an array + return [ + '@elizaos/plugin-sql', + '@elizaos/plugin-local-ai', + '@elizaos/plugin-anthropic', + '@elizaos/plugin-openai', + '@elizaos/plugin-discord', + '@elizaos/plugin-pdf', + '@elizaos/plugin-video-understanding', + ]; }, }); } diff --git a/packages/client/src/lib/api.ts b/packages/client/src/lib/api.ts index 3afb578af4d..cf5c23267da 100644 --- a/packages/client/src/lib/api.ts +++ b/packages/client/src/lib/api.ts @@ -254,12 +254,13 @@ export const apiClient = { }, deleteAgent: (agentId: string): Promise<{ success: boolean }> => fetcher({ url: `/agents/${agentId}`, method: 'DELETE' }), - updateAgent: (agentId: string, agent: Agent) => - fetcher({ + updateAgent: async (agentId: string, agent: Agent) => { + return fetcher({ url: `/agents/${agentId}`, method: 'PATCH', body: agent, - }), + }); + }, createAgent: (params: { characterPath?: string; characterJson?: Character }) => fetcher({ url: '/agents/', @@ -506,4 +507,38 @@ export const apiClient = { method: 'DELETE', }); }, + + getLocalEnvs: () => { + return fetcher({ + url: `/envs/local`, + method: 'GET', + }); + }, + + updateLocalEnvs: (envs: Record) => { + return fetcher({ + url: `/envs/local`, + method: 'POST', + body: { + content: envs, + }, + }); + }, + + getGlobalEnvs: () => { + return fetcher({ + url: `/envs/global`, + method: 'GET', + }); + }, + + updateGlobalEnvs: (envs: Record) => { + return fetcher({ + url: `/envs/global`, + method: 'POST', + body: { + content: envs, + }, + }); + }, }; diff --git a/packages/client/src/lib/socketio-manager.ts b/packages/client/src/lib/socketio-manager.ts index 85ceafb8150..faf8e91708a 100644 --- a/packages/client/src/lib/socketio-manager.ts +++ b/packages/client/src/lib/socketio-manager.ts @@ -122,6 +122,10 @@ class SocketIOManager extends EventEmitter { } }); + this.socket.on('messageComplete', (data) => { + this.emit('messageComplete', data); + }); + this.socket.on('disconnect', (reason) => { console.log(`[SocketIO] Disconnected. Reason: ${reason}`); this.isConnected = false; diff --git a/packages/client/src/lib/utils.ts b/packages/client/src/lib/utils.ts index 848bfd2dd94..816b359e560 100644 --- a/packages/client/src/lib/utils.ts +++ b/packages/client/src/lib/utils.ts @@ -44,7 +44,7 @@ export function urlToCharacterName(urlName: string): string { // crypto.randomUUID only works in https context in firefox export function randomUUID(): UUID { - return URL.createObjectURL(new Blob()).split('/').pop(); + return URL.createObjectURL(new Blob()).split('/').pop() as UUID; } export function getEntityId(): UUID { diff --git a/packages/core/__tests__/environment.test.ts b/packages/core/__tests__/environment.test.ts deleted file mode 100644 index 6753b13bf31..00000000000 --- a/packages/core/__tests__/environment.test.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { describe, expect, it } from 'vitest'; -import { validateCharacterConfig } from '../src/environment'; - -describe('Character Configuration', () => { - const validCharacterConfig = { - name: 'Test Character', - bio: 'Test bio', - messageExamples: [ - [ - { - name: 'name1', - content: { - text: 'Hello', - }, - }, - ], - ], - postExamples: ['Test post'], - topics: ['topic1'], - adjectives: ['friendly'], - clients: ['discord'], - plugins: ['test-plugin'], - style: { - all: ['style1'], - chat: ['chat-style'], - post: ['post-style'], - }, - }; - - it('should validate correct character configuration', () => { - expect(() => validateCharacterConfig(validCharacterConfig)).not.toThrow(); - }); - - it('should validate configuration with optional fields', () => { - const configWithOptionals = { - ...validCharacterConfig, - id: '123e4567-e89b-12d3-a456-426614174000', - system: 'Test system', - templates: { - greeting: 'Hello!', - }, - knowledge: ['fact1'], - settings: { - secrets: { - key: 'value', - }, - voice: { - model: 'test-model', - url: 'http://example.com', - }, - }, - }; - expect(() => validateCharacterConfig(configWithOptionals)).not.toThrow(); - }); - - it('should throw error for missing required fields', () => { - const invalidConfig = { ...validCharacterConfig }; - (invalidConfig as any).name = undefined; - expect(() => validateCharacterConfig(invalidConfig)).toThrow(); - }); - - it('should validate plugin objects in plugins array', () => { - const configWithPluginObjects = { - ...validCharacterConfig, - plugins: [ - { - name: 'test-plugin', - description: 'Test description', - }, - ], - }; - expect(() => validateCharacterConfig(configWithPluginObjects)).not.toThrow(); - }); - - it('should validate message examples with additional properties', () => { - const configWithComplexMessage = { - ...validCharacterConfig, - messageExamples: [ - [ - { - name: 'name1', - content: { - text: 'Hello', - action: 'wave', - source: 'chat', - url: 'http://example.com', - inReplyTo: '123e4567-e89b-12d3-a456-426614174000', - attachments: ['file1'], - customField: 'value', - }, - }, - ], - ], - }; - expect(() => validateCharacterConfig(configWithComplexMessage)).not.toThrow(); - }); -}); diff --git a/packages/core/src/bootstrap.ts b/packages/core/src/bootstrap.ts index 2769d1c7f86..5f189080e7c 100644 --- a/packages/core/src/bootstrap.ts +++ b/packages/core/src/bootstrap.ts @@ -112,6 +112,7 @@ const messageReceivedHandler = async ({ runtime, message, callback, + onComplete, }: MessageReceivedHandlerParams): Promise => { // Generate a new response ID const responseId = v4(); @@ -277,7 +278,7 @@ const messageReceivedHandler = async ({ await runtime.processActions(message, responseMessages, state, callback); } - + onComplete?.(); await runtime.evaluate(message, state, shouldRespond, callback, responseMessages); // Emit run ended event on successful completion @@ -294,6 +295,7 @@ const messageReceivedHandler = async ({ source: 'messageHandler', }); } catch (error) { + onComplete?.(); // Emit run ended event with error await runtime.emitEvent(EventType.RUN_ENDED, { runtime, @@ -620,6 +622,7 @@ const events = { runtime: payload.runtime, message: payload.message, callback: payload.callback, + onComplete: payload.onComplete, }); }, ], diff --git a/packages/core/src/runtime.ts b/packages/core/src/runtime.ts index 84f564f3d7c..6215068c96b 100644 --- a/packages/core/src/runtime.ts +++ b/packages/core/src/runtime.ts @@ -1,7 +1,7 @@ import { v4 as uuidv4 } from 'uuid'; import { bootstrapPlugin } from './bootstrap'; import { createUniqueUuid } from './entities'; -import { handlePluginImporting } from './index'; +import { decryptSecret, getSalt, handlePluginImporting } from './index'; import logger from './logger'; import { splitChunks } from './prompts'; // Import enums and values that are used as values @@ -524,6 +524,7 @@ export class AgentRuntime implements IAgentRuntime { this.runtimeLogger.warn( `[AgentRuntime][${this.character.name}] No TEXT_EMBEDDING model registered. Skipping embedding dimension setup.` ); + console.log('DeBUG models', this.models); } else { // Only run ensureEmbeddingDimension if we have an embedding model await this.ensureEmbeddingDimension(); @@ -727,9 +728,11 @@ export class AgentRuntime implements IAgentRuntime { this.character.settings?.secrets?.[key] || this.settings[key]; - if (value === 'true') return true; - if (value === 'false') return false; - return value || null; + const decryptedValue = decryptSecret(value, getSalt()); + + if (decryptedValue === 'true') return true; + if (decryptedValue === 'false') return false; + return decryptedValue || null; } /** diff --git a/packages/core/src/settings.ts b/packages/core/src/settings.ts index ce4d09f0624..5d896db2570 100644 --- a/packages/core/src/settings.ts +++ b/packages/core/src/settings.ts @@ -1,14 +1,21 @@ import crypto from 'node:crypto'; import { createUniqueUuid } from './entities'; import { logger } from './logger'; -import type { IAgentRuntime, OnboardingConfig, Setting, World, WorldSettings } from './types'; +import type { + Character, + IAgentRuntime, + OnboardingConfig, + Setting, + World, + WorldSettings, +} from './types'; /** * Creates a new Setting object based on provided config settings. * @param {Omit} configSetting - The configuration settings for the new Setting object. * @returns {Setting} - The newly created Setting object. */ -function createSettingFromConfig(configSetting: Omit): Setting { +export function createSettingFromConfig(configSetting: Omit): Setting { return { name: configSetting.name, description: configSetting.description, @@ -25,73 +32,132 @@ function createSettingFromConfig(configSetting: Omit): Setting } /** - * Generate a salt for settings encryption - */ -/** - * Retrieves the salt for the agent based on the provided runtime information. + * Retrieves the salt based on env variable SECRET_SALT * - * @param {IAgentRuntime} runtime - The runtime information of the agent. * @returns {string} The salt for the agent. */ -function getSalt(runtime: IAgentRuntime): string { +export function getSalt(): string { const secretSalt = (typeof process !== 'undefined' ? process.env.SECRET_SALT : (import.meta as any).env.SECRET_SALT) || 'secretsalt'; - const agentId = runtime.agentId; - if (!agentId) { - logger.warn('AgentId is missing when generating encryption salt'); + if (!secretSalt) { + logger.error('SECRET_SALT is not set'); } - const salt = secretSalt + (agentId || ''); + const salt = secretSalt; + logger.debug(`Generated salt with length: ${salt.length} (truncated for security)`); return salt; } /** - * Applies salt to the value of a setting - * Only applies to secret settings with string values + * Common encryption function for string values + * @param {string} value - The string value to encrypt + * @param {string} salt - The salt to use for encryption + * @returns {string} - The encrypted value in 'iv:encrypted' format */ -function saltSettingValue(setting: Setting, salt: string): Setting { - const settingCopy = { ...setting }; +export function encryptStringValue(value: string, salt: string): string { + try { + // Check if value is undefined or null + if (value === undefined || value === null) { + logger.debug('Attempted to encrypt undefined or null value'); + return value; // Return the value as is (undefined or null) + } - // Only encrypt string values in secret settings - if (setting.secret === true && typeof setting.value === 'string' && setting.value) { - try { - // Check if value is already encrypted (has the format "iv:encrypted") - const parts = setting.value.split(':'); - if (parts.length === 2) { - try { - // Try to parse the first part as hex to see if it's already encrypted - const possibleIv = Buffer.from(parts[0], 'hex'); - if (possibleIv.length === 16) { - // Value is likely already encrypted, return as is - logger.debug('Value appears to be already encrypted, skipping re-encryption'); - return settingCopy; - } - } catch (e) { - // Not a valid hex string, proceed with encryption + // Check if value is already encrypted (has the format "iv:encrypted") + const parts = value.split(':'); + if (parts.length === 2) { + try { + // Try to parse the first part as hex to see if it's already encrypted + const possibleIv = Buffer.from(parts[0], 'hex'); + if (possibleIv.length === 16) { + // Value is likely already encrypted, return as is + logger.debug('Value appears to be already encrypted, skipping re-encryption'); + return value; } + } catch (e) { + // Not a valid hex string, proceed with encryption } + } + + // Create key and iv from the salt + const key = crypto.createHash('sha256').update(salt).digest().slice(0, 32); + const iv = crypto.randomBytes(16); + + // Encrypt the value + const cipher = crypto.createCipheriv('aes-256-cbc', key, iv); + let encrypted = cipher.update(value, 'utf8', 'hex'); + encrypted += cipher.final('hex'); - // Create key and iv from the salt - const key = crypto.createHash('sha256').update(salt).digest().slice(0, 32); - const iv = crypto.randomBytes(16); + // Store IV with the encrypted value so we can decrypt it later + return `${iv.toString('hex')}:${encrypted}`; + } catch (error) { + logger.error(`Error encrypting value: ${error}`); + // Return the original value on error + return value; + } +} + +/** + * Common decryption function for string values + * @param {string} value - The encrypted value in 'iv:encrypted' format + * @param {string} salt - The salt to use for decryption + * @returns {string} - The decrypted string value + */ +export function decryptStringValue(value: string, salt: string): string { + try { + // Check if value is undefined or null + if (value === undefined || value === null) { + logger.debug('Attempted to decrypt undefined or null value'); + return value; // Return the value as is (undefined or null) + } - // Encrypt the value - const cipher = crypto.createCipheriv('aes-256-cbc', key, iv); - let encrypted = cipher.update(setting.value, 'utf8', 'hex'); - encrypted += cipher.final('hex'); + // Split the IV and encrypted value + const parts = value.split(':'); + if (parts.length !== 2) { + logger.warn( + `Invalid encrypted value format - expected 'iv:encrypted', returning original value` + ); + return value; // Return the original value without decryption + } - // Store IV with the encrypted value so we can decrypt it later - settingCopy.value = `${iv.toString('hex')}:${encrypted}`; + const iv = Buffer.from(parts[0], 'hex'); + const encrypted = parts[1]; - logger.debug(`Successfully encrypted value with IV length: ${iv.length}`); - } catch (error) { - logger.error(`Error encrypting setting value: ${error}`); - // Return the original value on error + // Verify IV length + if (iv.length !== 16) { + logger.warn(`Invalid IV length (${iv.length}) - expected 16 bytes`); + return value; // Return the original value without decryption } + + // Create key from the salt + const key = crypto.createHash('sha256').update(salt).digest().slice(0, 32); + + // Decrypt the value + const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv); + let decrypted = decipher.update(encrypted, 'hex', 'utf8'); + decrypted += decipher.final('utf8'); + + return decrypted; + } catch (error) { + logger.error(`Error decrypting value: ${error}`); + // Return the encrypted value on error + return value; + } +} + +/** + * Applies salt to the value of a setting + * Only applies to secret settings with string values + */ +export function saltSettingValue(setting: Setting, salt: string): Setting { + const settingCopy = { ...setting }; + + // Only encrypt string values in secret settings + if (setting.secret === true && typeof setting.value === 'string' && setting.value) { + settingCopy.value = encryptStringValue(setting.value, salt); } return settingCopy; @@ -101,41 +167,12 @@ function saltSettingValue(setting: Setting, salt: string): Setting { * Removes salt from the value of a setting * Only applies to secret settings with string values */ -function unsaltSettingValue(setting: Setting, salt: string): Setting { +export function unsaltSettingValue(setting: Setting, salt: string): Setting { const settingCopy = { ...setting }; // Only decrypt string values in secret settings if (setting.secret === true && typeof setting.value === 'string' && setting.value) { - try { - // Split the IV and encrypted value - const parts = setting.value.split(':'); - if (parts.length !== 2) { - logger.warn(`Invalid encrypted value format for setting - expected 'iv:encrypted'`); - return settingCopy; // Return the original value without decryption - } - - const iv = Buffer.from(parts[0], 'hex'); - const encrypted = parts[1]; - - // Verify IV length - if (iv.length !== 16) { - logger.warn(`Invalid IV length (${iv.length}) - expected 16 bytes`); - return settingCopy; // Return the original value without decryption - } - - // Create key from the salt - const key = crypto.createHash('sha256').update(salt).digest().slice(0, 32); - - // Decrypt the value - const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv); - let decrypted = decipher.update(encrypted, 'hex', 'utf8'); - decrypted += decipher.final('utf8'); - - settingCopy.value = decrypted; - } catch (error) { - logger.error(`Error decrypting setting value: ${error}`); - // Return the encrypted value on error - } + settingCopy.value = decryptStringValue(setting.value, salt); } return settingCopy; @@ -144,7 +181,7 @@ function unsaltSettingValue(setting: Setting, salt: string): Setting { /** * Applies salt to all settings in a WorldSettings object */ -function saltWorldSettings(worldSettings: WorldSettings, salt: string): WorldSettings { +export function saltWorldSettings(worldSettings: WorldSettings, salt: string): WorldSettings { const saltedSettings: WorldSettings = {}; for (const [key, setting] of Object.entries(worldSettings)) { @@ -157,7 +194,7 @@ function saltWorldSettings(worldSettings: WorldSettings, salt: string): WorldSet /** * Removes salt from all settings in a WorldSettings object */ -function unsaltWorldSettings(worldSettings: WorldSettings, salt: string): WorldSettings { +export function unsaltWorldSettings(worldSettings: WorldSettings, salt: string): WorldSettings { const unsaltedSettings: WorldSettings = {}; for (const [key, setting] of Object.entries(worldSettings)) { @@ -190,7 +227,7 @@ export async function updateWorldSettings( } // Apply salt to settings before saving - const salt = getSalt(runtime); + const salt = getSalt(); const saltedSettings = saltWorldSettings(worldSettings, salt); // Update settings state @@ -225,7 +262,7 @@ export async function getWorldSettings( const saltedSettings = world.metadata.settings as WorldSettings; // Remove salt from settings before returning - const salt = getSalt(runtime); + const salt = getSalt(); return unsaltWorldSettings(saltedSettings, salt); } catch (error) { logger.error(`Error getting settings state: ${error}`); @@ -247,7 +284,7 @@ export async function initializeOnboarding( logger.info(`Onboarding state already exists for server ${world.serverId}`); // Get settings from metadata and remove salt const saltedSettings = world.metadata.settings as WorldSettings; - const salt = getSalt(runtime); + const salt = getSalt(); return unsaltWorldSettings(saltedSettings, salt); } @@ -278,3 +315,93 @@ export async function initializeOnboarding( return null; } } + +/** + * Encrypts sensitive data in a Character object + * @param {Character} character - The character object to encrypt secrets for + * @param {IAgentRuntime} runtime - The runtime information needed for salt generation + * @returns {Character} - A copy of the character with encrypted secrets + */ +export function encryptedCharacter(character: Character): Character { + // Create a deep copy to avoid modifying the original + const encryptedChar = JSON.parse(JSON.stringify(character)); + const salt = getSalt(); + + // Encrypt character.settings.secrets if it exists + if (encryptedChar.settings?.secrets) { + encryptedChar.settings.secrets = encryptObjectValues(encryptedChar.settings.secrets, salt); + } + + // Encrypt character.secrets if it exists + if (encryptedChar.secrets) { + encryptedChar.secrets = encryptObjectValues(encryptedChar.secrets, salt); + } + + return encryptedChar; +} + +/** + * Decrypts sensitive data in a Character object + * @param {Character} character - The character object with encrypted secrets + * @param {IAgentRuntime} runtime - The runtime information needed for salt generation + * @returns {Character} - A copy of the character with decrypted secrets + */ +export function decryptedCharacter(character: Character, runtime: IAgentRuntime): Character { + // Create a deep copy to avoid modifying the original + const decryptedChar = JSON.parse(JSON.stringify(character)); + const salt = getSalt(); + + // Decrypt character.settings.secrets if it exists + if (decryptedChar.settings?.secrets) { + decryptedChar.settings.secrets = decryptObjectValues(decryptedChar.settings.secrets, salt); + } + + // Decrypt character.secrets if it exists + if (decryptedChar.secrets) { + decryptedChar.secrets = decryptObjectValues(decryptedChar.secrets, salt); + } + + return decryptedChar; +} + +/** + * Helper function to encrypt all string values in an object + * @param {Record} obj - Object with values to encrypt + * @param {string} salt - The salt to use for encryption + * @returns {Record} - Object with encrypted values + */ +export function encryptObjectValues(obj: Record, salt: string): Record { + const result: Record = {}; + + for (const [key, value] of Object.entries(obj)) { + if (typeof value === 'string' && value) { + result[key] = encryptStringValue(value, salt); + } else { + result[key] = value; + } + } + + return result; +} + +/** + * Helper function to decrypt all string values in an object + * @param {Record} obj - Object with encrypted values + * @param {string} salt - The salt to use for decryption + * @returns {Record} - Object with decrypted values + */ +export function decryptObjectValues(obj: Record, salt: string): Record { + const result: Record = {}; + + for (const [key, value] of Object.entries(obj)) { + if (typeof value === 'string' && value) { + result[key] = decryptStringValue(value, salt); + } else { + result[key] = value; + } + } + + return result; +} + +export { decryptStringValue as decryptSecret }; diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index 96058a40b91..18ae2e22c82 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -1578,6 +1578,7 @@ export interface EntityPayload extends EventPayload { export interface MessagePayload extends EventPayload { message: Memory; callback?: HandlerCallback; + onComplete?: () => void; } /** @@ -1638,6 +1639,7 @@ export type MessageReceivedHandlerParams = { runtime: IAgentRuntime; message: Memory; callback: HandlerCallback; + onComplete?: () => void; }; /** diff --git a/packages/docs/blog/authors.yml b/packages/docs/blog/authors.yml new file mode 100644 index 00000000000..e84ffd738d9 --- /dev/null +++ b/packages/docs/blog/authors.yml @@ -0,0 +1,25 @@ +team: + name: ElizaOS Team + title: Core Team + url: https://github.com/elizaos + image_url: https://github.com/elizaos.png + socials: + twitter: elizaOS + github: elizaOS + +bot: + name: jintern + title: AI agent intern for elizaOS + url: https://github.com/elizaos/eliza + image_url: https://pbs.twimg.com/profile_images/1885926907851550720/G9Uo7WIv_400x400.jpg + socials: + twitter: thejintern + +jin: + name: jin + title: Contributor + url: https://github.com/madjin + image_url: https://avatars.githubusercontent.com/u/32600939?v=4 + socials: + twitter: dankvr + github: madjin diff --git a/packages/docs/blog/tags.yml b/packages/docs/blog/tags.yml new file mode 100644 index 00000000000..1432b002cb9 --- /dev/null +++ b/packages/docs/blog/tags.yml @@ -0,0 +1,24 @@ +# Place this file at docs/blog/tags.yml +human: + label: Human-Edited + description: Content written and edited by the ElizaOS team + +automated: + label: Automated Update + description: Automatically generated updates from our systems + +release: + label: Release + description: Official release announcements + +feature: + label: Feature + description: New feature announcements + +guide: + label: Guide + description: How-to guides and tutorials + +community: + label: Community + description: Community events and announcements diff --git a/packages/docs/blog/v1-v2.mdx b/packages/docs/blog/v1-v2.mdx new file mode 100644 index 00000000000..0b1e0c1ca9e --- /dev/null +++ b/packages/docs/blog/v1-v2.mdx @@ -0,0 +1,190 @@ +--- +authors: jin +--- + +# ElizaOS V2: What's New + +The newest version of [eliza](https://github.com/elizaOS/eliza) represents significant upgrades from the previous version, offering a leaner, more flexible architecture for cross-platform agent interaction. This short guide highlights the key differences between V1 and V2. + +[![](/blog/v1-v2.jpg)](/blog/v1-v2.jpg) +{/* truncate */} +Source: https://www.youtube.com/watch?v=yUjScwAZsQo + +### V2 Impact + +- **Cross-Platform Presence**: Your agent can jump from Twitter, continue via SMS, and place orders with businesses—all while maintaining conversation context. +- **Unified Blockchain Management**: One wallet to rule all chains—no more chain-switching headaches. +- **Autonomous Workflows**: Agents that handle multi-step processes independently—researching data, analyzing results, generating reports, and scheduling follow-ups without constant oversight. +- **Evolving Intelligence**: Database-driven characters that can start minimal and grow through interactions with your crowd. +- **Enhanced Security**: Native TEE integration provides verifiable security guarantees for sensitive operations while maintaining privacy. + + +--- + +## Core Architecture Redesign + +| V1 Limitation | V2 Solution | +|---------------|-------------| +| **Bloated Core**: Codebase overloaded with packages from rapid growth | **Package Registry**: Submit plugins independently; lean codebase, no approval delays | +| **Fragmented Messaging**: Platform-specific I/O pipelines | **Unified Messaging**: Agents process inputs and output anywhere, seamlessly | +| **Wallet Overlap**: Multi-chain wallet conflicts | **Unified Inventory**: One wallet with chain-agnostic actions | +| **Rigid State**: Hardcoded goals and features | **Modular State**: Extensible, optional components for tailored agents | +| **Basic Action Chaining**: No multi-step foresight | **Strategic Planning**: Agents map out complex, sequenced workflows | +| **Package Manager Speed**: Lengthy installations and cold starts | **Bun Integration**: Faster installs, reduced build times | + + +--- + +## Technical Implementation Changes + +```mermaid +graph TB + %% Main Components with vertical orientation + User((User)):::user + + %% First Level - Services + PlatformServices[Services]:::services + + %% Second Level - Runtime + AgentRuntime[Agent Runtime]:::core + + %% Core Processing Components - Side by side + subgraph "Core Processing" + direction LR + Providers[Providers]:::int + Actions[Actions]:::int + Evaluators[Evaluators]:::int + end + + %% Knowledge and DB - Side by side + subgraph "Knowledge & Storage" + direction LR + Knowledge[Knowledge]:::int + DB[(Database)]:::db + end + + %% Organization Components - Vertical layout + subgraph "Organization" + direction TB + Worlds[Worlds]:::struct + Rooms[Rooms]:::struct + Entities[Entities]:::struct + end + + %% Development Components - Side by side + subgraph "Development & Integration" + direction LR + Plugins[Plugins]:::dev + Projects[Projects]:::dev + Tasks[Tasks]:::dev + end + + %% Main Flow - Vertical emphasis + User <-->|Interaction| PlatformServices + PlatformServices -->|Process| AgentRuntime + + %% Runtime connections - Simplified + AgentRuntime ---|Context| Providers + AgentRuntime ---|Behavior| Actions + AgentRuntime ---|Analysis| Evaluators + + %% Data connections + AgentRuntime <-->|Storage| DB + Knowledge -->|Informs| Providers + + %% Structure connections - Clean vertical hierarchy + AgentRuntime -->|Manages| Worlds + Worlds -->|Contains| Rooms + Rooms -->|Has| Entities + + %% Development connections + Projects -->|Configure| AgentRuntime + Plugins -->|Extend| AgentRuntime + Tasks -->|Scheduled by| AgentRuntime + + %% Clickable nodes with links to docs + click AgentRuntime "/docs/core/agents" "Learn about Agent Runtime" + click PlatformServices "/docs/core/services" "Learn about Services" + click DB "/docs/core/database" "Learn about Database Systems" + click Actions "/docs/core/actions" "Learn about Actions" + click Providers "/docs/core/providers" "Learn about Providers" + click Evaluators "/docs/core/evaluators" "Learn about Evaluators" + click Knowledge "/docs/core/knowledge" "Learn about Knowledge System" + click Worlds "/docs/core/worlds" "Learn about Worlds" + click Rooms "/docs/core/rooms" "Learn about Rooms" + click Entities "/docs/core/entities" "Learn about Entities" + click Plugins "/docs/core/plugins" "Learn about Plugins" + click Projects "/docs/core/project" "Learn about Projects" + click Tasks "/docs/core/tasks" "Learn about Tasks" + + %% Styling + classDef core fill:#3498db,stroke:#2c3e50,stroke-width:1px,color:#fff,font-weight:bold + classDef services fill:#9b59b6,stroke:#2c3e50,stroke-width:1px,color:#fff,font-weight:bold + classDef db fill:#27ae60,stroke:#2c3e50,stroke-width:1px,color:#fff,font-weight:bold + classDef int fill:#e74c3c,stroke:#2c3e50,stroke-width:1px,color:#fff,font-weight:bold + classDef struct fill:#f39c12,stroke:#2c3e50,stroke-width:1px,color:#fff,font-weight:bold + classDef dev fill:#1abc9c,stroke:#2c3e50,stroke-width:1px,color:#fff,font-weight:bold + classDef user fill:#ecf0f1,stroke:#2c3e50,stroke-width:2px,color:#2c3e50,font-weight:bold,border-radius:50% +``` + + +### From Clients to Services +V2 swaps Clients for Services, standardizing platform integration while centralizing message routing—agents now think once, act anywhere (Discord, Twitter, SMS, even phone calls). + +### Smarter Character Evolution +V2 swaps static files for dynamic personas—agents learn from your crowd in real-time while still being able to be imported / exported as JSON files (see [docs](/docs/core/project)). + +### Enhanced Development Experience +New CLI and plugin manager slashes setup time. Instead of cloning the github repo, changing to the correct branch, rebuilding, etc, it's just one command to create a new project: + +```bash +npm create eliza@beta +``` + +
+ See CLI commands + +```bash +Usage: elizaos [options] [command] + +Options: + -V, --version output the version number + -h, --help display help for command + +Commands: + create [options] [name] Initialize a new project or plugin + project Manage an ElizaOS project + plugin Manage ElizaOS plugins, including publishing + agent manage ElizaOS agents + tee Manage TEE deployments + start [options] Start the Eliza agent with configurable plugins and services + update [options] Update ElizaOS packages to the latest versions + test [options] Run tests for Eliza agent plugins + env Manage environment variables and secrets + dev [options] Start the project or plugin in development mode and rebuild on + file changes + publish [options] Publish a plugin or project to the registry + help [command] display help for command +``` +
+ +Explore the plugin repository https://github.com/elizaos-plugins/ or from the [docs showcase](/packages). + +### Memory and Task Management +Vector embeddings power richer memory; tasks now handle schedules and multi-step logic. + +```typescript +await runtime.createTask({ ... }); +``` + +--- + + +## Timeline + +- **March 2025**: Research beta now live. +- **April 2025**: Public rollout. + +### Should You Upgrade? + +V2 is mostly backward compatible for gradual migration. Existing projects can phase in V2 features; new ones should start with V2 for full benefits. V1 still works, but V2's modularity and planning unlock next-level autonomy. See [quickstart](/docs/quickstart) to get started. diff --git a/packages/docs/blog/wdygdtw_recap.mdx b/packages/docs/blog/wdygdtw_recap.mdx new file mode 100644 index 00000000000..cd6b801068a --- /dev/null +++ b/packages/docs/blog/wdygdtw_recap.mdx @@ -0,0 +1,128 @@ +--- +authors: jin +--- + +# "What Did You Get Done This Week?" Recap + +From November 2024 to January 2025, we held a weekly Twitter Spaces where developers shared progress about their AI agent projects. If you shipped something related to open source AI / social agents that week, you were allowed 1-2 minutes to share an update of what you have been working on. Thousands of listeners tuned every Friday night to essentially listen to a dev standup. + +{/* truncate */} + +![](https://pbs.twimg.com/media/Fd2lvapVsAAFvsG.jpg) + +The WDYGDTW series played a role in establishing momentum and maintaining it throughout the formative months as the crypto x AI agent space was heating up. The weekly accountability structure encouraged: + +- **Rapid iteration cycles** from concept to implementation +- **Cross-pollination of ideas** between different teams +- **Public documentation** of the ecosystem's growth +- **Establishment of norms** around open development +- **Community reputation building** through consistent delivery + +## Timeline + +We transcribed, summarized, and uplaoded notes for every Space shortly after each one. However, until now the recordings and notes haven't all been easily accessible all in one place. Showing up is half the battle. These are the pioneers of a grassroots crypto / AI movement. + +``` +- Nov 15, 2024 +- 1: Social Agents / Advancing towards AGI + - Logan, Kyle (Raid Guild), Glue, Ropey, Loaf, Odilitime, SomewheresHe, Robin, IQ6900, Marvin, Dot, JW, Neo, Bloom, Reality Spiral, Jen, OFI, Butoshi, Doc (Geon Reborn), HCP, Garrett, Lady Liberty, BoyaLockser, Amy, Griffin, Frank (Heurist), Shaw, Tim + - Trust Marketplace, EVM wallet integration, Ducky AI client, Telegram fixes, Starknet wallet plugin, Sentience media generation, God's Fun, TEEs, Streamer platform, Decentralized AI cloud, Twitter client PR, Documentation, Satoshi AI memory system, Echo Chambers, Agent designs, Deep Writer, Music agent project, Psychic AI, Heurist API integration + - https://www.youtube.com/watch?v=9EmvhlBPB8Q +- Nov 22, 2024 +- 2: 3500 people tuning in to AI agent devs + - Reality Spiral, Boyaloxer, Spaceodili, Yodamaster726, Wiki, Hashwarlock, KyleSt4rgarden, Nasdao_, Evepredict, ByornOeste, Empyrealdev, SkotiVi, YoungBalla1000x, SOL_CryptoGamer, Angelocass, DAOJonesPumpAI, RodrigoSotoAlt, CottenIO, HDPbilly, IQ6900, frankdegods, jamesyoung, 0xglu, chrislatorres, shannonNullCode, robotsreview, bcsmithx, JustJamieJoyce, yikesawjeez, HowieDuhzit, xrpublisher, BV_Bloom1, nftRanch, 019ec6e2, jacobmtucker, CurtisLaird5, unl__cky, Rowdymode, mitchcastanet, GoatOfGamblers, JohnNaulty, mayanicks0x, wakesync, TrenchBuddy, rakshitaphilip, MbBrainz, Hawkeye_Picks, Shaw, dankvr + - GitHub integration, emotional plugin for agents, Reddit-based AI agent, Token Gods project, Coinbase plugin, AI agent streaming platform, DuckAI client, Hustle and Flow State, image generation prompts, Oasis agent simulation, Sentientopia, Eliza as "real girl", D-Gen Spartan revival, LaunchRate AI16DAO, Satoshi AI characters, MUSE DAO CEO, music-creating agent, livestreaming in 3D, log rotation tool, Earth Poker AI game, healthcare app, FXN swarm, Trust Marketplace, Eliza style guidelines, NFT project AI CEO, finance and entertainment projects, Twitter client with Vision AI + - https://www.youtube.com/watch?v=Lbvv0Dr91Bc +- Nov 29, 2024 +- 3: Community Building + - Jin, Stargarden, Boya, Reality Spiral, W3Tester, HashWarlock, Soto, Mitch, Nick Parallel, Beige, Robin, Eve, Oguz, Swarm, RektDin, Roperito, Lothbrok, Clark Riswold, Tim, Spaceodili, Hawkeye, EA, FilteredThought, Yikes, Alain, Glue, Maximilian, Danny, Shaw, YoungJazzeth, Sergio + - Self-sustaining AI DAOs, IRC connector, Dark Sun project, Binary solar system, 3D environments, BlockRat AI, Apollo health agent, data grading, Eliza interface, AI hosting platform, Rogue Agent podcast, "Life Engine", AI for logistics, Positivity AI, Eliza's World, Scriptoshi on Bitcoin, Marble auctions, Twitter integration, Web3 research, multi-agent system for code, quantum randomness, agent show marketing + - https://www.youtube.com/watch?v=nUAEQ7uKi04 +- Dec 6, 2024 +- 4: Communications, Updates and Accountability + - Shaw, Ropirito, Liam Zebedee, LordOfAFew, Robin, Reality Spiral, Ico, Glue, Shannon NullCode, JW, Guha, Frago, Yeshua God, AvaDoesAI, Spaceodili, Bloom, Joven, Satoshi_AI_Live, Simeon Fluck, NavarroCol, BeigeGrape, Andrew Miller, Johnny, Collins, Baron, Anthony, Wit, Ophi, Colin, Ranch, Oguz, Issy, Nick, Dr. K, BallerHash, Tim + - Twitter & TikTok capabilities, Average French AI agent, Eliza framework improvements, Token Gods launch, Coinbase plugin, AI agent streaming platform, DuckAI client, knowledge graph system, LLM image prompts, Oasis simulation project, agent network connector, Sentientopia digital nation, Eliza as "real girl" concept, D-Gen Spartan revival, tokenomics, LaunchRate AI16DAO, small town AI characters, MUSE AI CEO, music-creating agent, market data livestreaming, log rotation security tool, Earth Poker AI game, crypto assistant, healthcare app, FXN swarm, Trust Marketplace, style guidelines, Tweek Labs AI CEO, finance projects, Baba Cat project, animation, KWAI network controller + - https://www.youtube.com/watch?v=r3Z4lvu_ic4 +- Dec 13, 2024 +- 5: Building the Future + - shawmakesmagic, xsubtropic, CottenIO, HDPbilly, IQ6900, frankdegods, jamesyoung, 0xglu, chrislatorres, reality_spiral, robotsreview, shannonNullCode, bcsmithx, boyaloxer, JustJamieJoyce, yikesawjeez, RodrigoSotoAlt, HowieDuhzit, xrpublisher, BV_Bloom1, nftRanch, 019ec6e2, jacobmtucker, CurtisLaird5, unl__cky, Rowdymode, mitchcastanet, GoatOfGamblers, JohnNaulty, mayanicks0x, wakesync, TrenchBuddy, rakshitaphilip, MbBrainz, Hawkeye_Picks, dankvr + - Redux project, DaVinci AI, AI Summit recap, "Sploot" agent, on-chain ASCII art, character sheet tweaks, AI agent starter kit, agent swarms, Eliza.gg documentation, GitHub integration, Story Protocol plugin, Emblem Vault, Agent Tank, Plugin Feel for emotions, research AI agents, Discord bot, Metaplex NFTs, character generator, XR Publisher 3D network, 3D agent interactions, trading bot, Mimetic platform, agent transaction protocol, C-Studio interface, Escapism art generation, interactive streaming, binary star research, prediction market, SWE contributions, Axie AI KOL agent, Eliza Wakes Up, AWS templates, Brunette token, menu recommendations, storytelling bot + - https://www.youtube.com/watch?v=4u8rbjmvWC0 +- Dec 20, 2024 +- 6: Hackathons, Frameworks, and the Race to Ship + - dankvr, shawmakesmagic, IQ6900, spaceodili, bcsmithx, 0xBuildInPublic, jamesyoung, yikesawjeez, evepredict, yashhsm, TheLDAIntern, _0xaryan, CogAccSOL, reality_spiral, HDPbilly, CheddarQueso3D, ineedtendies, marvin_tong, BV_Bloom1, RealJonahBlake, DustinStockton, dylanpaulwhite, chrislatorres, 0xnavkumar, Hawkeye_Picks, lostgirldev, HowieDuhzit, boyaloxer, nizhanxi, ropirito, gigawidearray, GoatOfGamblers, shakkernerd, triadfi, MoondogFeed, wakesync, Moonbear, PoodonkAI, ViralMindAI, FilteredThought, _AnonDev, get_palet, MurrLincoln, socrates1024, IGLIVISION, dooly_dev, codergf_xyz, Ru7Longcrypto, sunosuporno, Signalman23, swarmnode, svabhishek, elohprojects, deltavius + - Solana blockchain data service, GitHub PR merging, Agent Tank viral video, security auditing, AI agent hackathon, Matrix bridge, trading bot draft, Solana Agent Kit, market insights agent, website launch, GitHub client, tone control in agents, WSL setup guide, WordPress client, self-sustaining AI ecosystem, payment processing, 3D rigging, health agents, Sober Rover companion, Eliza.gg Q&A platform, Bitcoin runes project, Santa Pimp Claus token, SolEng agent, character generator updates, boredom tracking, Asia trip organizing, AWS hosting, Reddit plugin, prediction market for memecoins, Redis caching, AI personality agents, social media to meme coins, persistent memory, vvaifu agent, AI hive mind, decentralized training platform, auto-trading agent, "Mizuki" AI model, open context protocol, AgentKit updates, TEE login system, game framework study, AGI matching platform, one-click chatbot deployment + - https://www.youtube.com/watch?v=R3auUQj9oEg +- Dec 27, 2024 +- 7: Agentic Documentation and GitHub Integration + - ai16zdao, shawmakesmagic, spaceodili, 0xBuildingPublic, Im_zo_eth, IQ6900_, FilteredThought, yeahimomar, affaanmustafa, KyleSt4rgarden, SYMBiEX, codergf_xyz, GoatOfGamblers, SuperfruitsAi, hashwarlock, allenharper, witconomist, triadfi, human_for_now, reality_spiral, lordOfAFew, chrislatorres, evepredict, lostgirldev, r4dicalcentrism, 0xblacksun, tmoindustries, wakesync, sunosuporno, unl__cky, hotpot_intern, TrenchBuddy, Signalman23, thelotioncoin, anshikag85, Doc_strange1, dankvr + - Hyperfy multi-agent integration, agentic JS documentation, on-chain agent "Q", data storage cost reduction, trading system with TrustDB, Minecraft AI villagers, streaming coding sessions, Solana AI hackathon, character creation tool, Web app staging, prediction market, web3 security agents, Spore agent swarm, "Shaw" character file, Trust marketplace white paper, prediction market analyst, search engine for dev videos, GitHub adapter, recursive self-improvement, generative agents for on-chain games, V2 development meetings, travel influencer agent, PR review agents, SoulScript for agent personalities, digital archaeologist agent, climate/nature focused ERC6551 agents, Eliza Wakes Up web app, DeFi agent, autonomous audio/song generation, TikTok memecoin hunter, wallet tracking visualization, voice AI for Twitter Spaces, integrating AI into existing projects, AI/AWS newsletter, TikTok integration + - https://www.youtube.com/watch?v=jcSF7dSicTI +- Jan 3, 2025 +- 8: From DeFi to Social Media + - ai16zdao, shawmakesmagic, astridhpilla, lostgirldev, spaceodili, 0xBuildInPublic, youfadedwealth, nftRanch, SYMBiEX, SuperfruitsAi, TimshelXYZ, chrislatorres, AIFlow_ML, jamesyoung, deadlock_1991, yeahimomar, human_for_now, lordasado, RodrigoSotoAlt, HDPbilly, GoatOfGamblers, Titan_Node, KyleSt4rgarden, unl__cky, CheddarQueso3D, sunosuporno, tmoindustries, Sawyer_APRO, wakesync, Ru7Longcrypto, marko_post, NEETOCRACY, HefAiGent, reality_spiral, witconomist, triadfi, Rowdymode, MaushishYadav, chaininsured, godfreymeyer, thelotioncoin, codergf_xyz, IGLIVISION, EledraNguyen, GnonOnSolana, Satoshi_BTCFi, swarmnode, memeillionaire, krauscrypto, usebuildfun, affaanmustafa, O_on_X, AITATsol, xiao_zcloak, Protocol_Blend, yq_acc, akshayynft, BenjiStackzzz, 0xBuns, aiquantfun + - Miku chatbot relaunch, Selene growth & PR review, Eliza framework fixes, voice features, plugin isolation, Audits agent documentation, PP coin automated trading, framework integration, DeepSeek model provider, Dragon Fruit AI launch, Meetup Fund platform, Eliza partnerships, knowledge graph for repos, verifiable inference system, Alice AI fund management, Pixocracy AI village management, form fill infrastructure, Smol World agent reasoning, Bosu memory management, Twitter client reflection loop, Goat Arena prediction market, LivePeer inference endpoints, Solana token staking, media generation improvements, agent documentation, DeFi assistant waitlist, region swarm voice integration, BNB chain integration, Netflix & chill extension, dating coach AI agent, Mars' first digital citizen, Army of Indians DAO, ERC 314 technology integration, GitHub client for scrum planning, Marketplace of Trust white paper, AI personality expansion, Twin Tone beta testing, yield optimizing agent, insurance broker agent, 3D news show avatars, AI agents for social channels, Haruka Twitter bot, NFT marketplace on Superchain, Square Fun AI analytics, Echo Chambers v2.3, Swarm Node growth, token integration, voice cloning mobile app, no-code AI agent builder, project scaling strategies, AI agent unsuspension techniques, global trade analysis, crypto payment functionality, DeFi protocol user experience + - https://www.youtube.com/watch?v=Vs7D5DN_trk +- Jan 10, 2025 +- 9: AI Agents to DePIN + - ai16zdao, spaceodili, 0xBuildInPublic, yeahimomar, unl__cky, CheddarQueso3D, lostgirldev, ohhshiny, SYMBiEX, nftRanch, HDPbilly, zerokn0wledge_, KingBootoshi, calintje, hashwarlock, MattPRD, dreygo_, 0xShiroe, lostboydev, brownsvgar, human_for_now, aiagentpepe, sea_of_zhou, tito_cda, thelotioncoin, chineseremilio, _cjft, dino2deno, AIFlow_ML, tmoindustries, astridhpilla, marvin_tong, yikesawjeez, djsamforever, KyleSt4rgarden, ProfRizzAI, vargs_g, KarimaDigital, Amiewitheliza, reality_spiral, wenkafka, slmsolcto, AaronErickson, GoatOfGamblers, c0mput3rxz, wakesync, aiquantfun, sunosuporno, ongo_ai, y7_y00ts, xiao_zcloak, ViralMindAI, Artstridee, bryanjmonterrey, O_on_X, svabhishek, CottenIO, hotpot_intern, TimshelXYZ, shawmakesmagic, dankvr + - Database and memory systems, documentation enhancements, Pixocracy Launchpad, image and music generation, AI in education, Aora project, hackathon judging, troll bot agent, TEE exploration, Discord deployment, DeFi agent swarm, summary kernel experiment, on-chain swaps, cross-VM bridging, Feather agent framework, Orca liquidity provisioning, Oracle agent on Sporephone, research paper auditing, market-making platform, GigaBread jailbreak testing, Solimp realism enhancement, Eliza texting buddy, automatic data collection, DePIN plugin for real-world data, Dark Sun digital investigator, platform front-end implementation, AI model Zion, AWS dockerization, multi-wallet volume bot, Akash plugin development, insurance app for natural capital, CES meetings and partnerships, TEE Cloud onboarding, Eliza PR merging system, Shogun plugin contributions, token staking documentation, Riz.ai entertainment platform, Zero-G storage plugin, dating coach AI, ecosystem integration, prompt logging system, wallet natural language commands, time series modeling for hurricanes, Goat Arena platform, token selector plugin, "simp to earn" feature, AI quant launchpad, Midas project wallet infrastructure, Ongo art critic expansion, Utes sports analytics, TikTok wallet integration, Minecraft tournament infrastructure, trading dashboard with social features, X account suspension workarounds, RAP framework development, image generation training, ZoroX TikTok coin hunter + - https://www.youtube.com/watch?v=fqM_vYK2bmc +- Jan 17, 2025 +- 10: From Digital to Physical + - ai16zdao, shawmakesmagic, JustinMoonAI, AntiRugAgent, rckprtr, dreygo_, Audix_hq, coordinape, lostgirldev, AIFlow_ML, astridhpilla, thelotioncoin, RodrigoSotoAlt, berliangor, unl__cky, xiao_zcloak, 0xnavkumar, GoatOfGamblers, Amiewitheliza, 0xVEER, BuzzyCrypto_, SYMBiEX, w1kke, luki_notlowkey, AgentTextdotfun, yikesawjeez, ByornOeste, Nasdao_, elizawakesup, dankvr, sypherlit + - Eliza V2 development, inventory system, CLI, Tron integration, rug pull prevention, Discover AI community management, Kyra AI market-making, smart contract visuals, Farcaster community rewards, website and terminal development, PR agent for ElizaOS, voice and VRM development, API connections, persistent memory system, SQLite rewriting in Rust, Telegram launch, "Approve Agents" model for wallets, verifiable TEE Network, Telegram mini apps, internal team calls, ETH Denver AI program, autonomous trader and music releases, web search in agents, devotion program staking, on-chain data plugin, DePIN network for SMS, CICD improvements, conspiracy theory thesis, DeFi validator personality, Eliza's robot body, Degen Spartan AI trading, Void AI cross-chain mixer + - https://www.youtube.com/watch?v=1voboZEQTAw +- Jan 24, 2025 +- 11: AI Agents Level Up + - ai16zdao, SYMBiEX, astridhpilla, davidlsneider, dreygo_, GoatOfGamblers, unl__cky, thelotioncoin, Amiewitheliza, lostboydev, lostgirldev, AIFlow_ML, _AnonDev, damascoai, ITzMiZzle, MementsOfficial, immanencer, MrMinter_eth, FilteredThought, AgienceAI, BotOrNot42, itsmetamike, sea_of_zhou, TimshelXYZ, wakesync, reality_spiral, ai16zdao, yikesawjeez + - DeepSeek R1 integration, Fleek partnership, Lit Protocol Agent Wallet Kit, Ninja Terminal market making, GoToArena Telegram bot, X image generation, agent platform MVP, Trust Marketplace paper, Telegram mod functionality, Solenguration B2B terminal, Hyperbolic agent tracking, cybersecurity ecosystem, AI security framework, Kiyomi AI voice and music, SQL Agents library, AI agent swarms with D&D stats, agent business logic, Suno/Udio plugin, open source agent platform token, Vice agent content creation, Hyperfy tests, Quicksilver prediction framework, Eliza email scheduling, Simp2Earn tokenomics, GitHub UI relationship module, improved news aggregator, ElizaOS CICD improvements + - https://www.youtube.com/watch?v=mxdWvBnxN8M +- Jan 31, 2025 +- 12: ElizaOS 0.1.9 Launch + - ai16zdao, shawmakesmagic, astridhpilla, lostgirldev, xrpublisher, lostboydev, spaceodili, SYMBiEX, yikesawjeez, Amiewitheliza, 0xrhota, ai16zdao, wakesync, AIFlow_ML, Signalman23, Rowdymode, MementsOfficial, elizawakesup, reality_spiral, tmoindustries, w1kke, shawmakesmagic + - DUNA Framework for DAOs, Miku updates (MetaHuman, ETHDenver), SolEng Terminal launch, Pixel memory system with backups, SolImp Telegram mod platform, ElizaOS v0.1.9 release with plugin registry, website rework with 3D models, ecosystem updates (tokenomics, self-hosting), HyperPoly plugin and marketplace integration, Degen Spartan trading enhancements, Block Tank show format, Eliza voice device development, Backpack plugin and typing fixes, voice agent model fine-tuning, Gods Unchained tokenomics, AI database interaction library, voice demo with improved latency, Coinbase grant and trading on Base, insurance agents for nature and biodiversity, Gods Unchained plugins and Devotion program + - https://www.youtube.com/watch?v=SZNuoXJ1Mvs +``` + +## Video Archive for Research + +These recordings help document the week-by-week evolution of the crypto AI ecosystem, capturing the iterative development process and community formation in real-time. NotebookLM and similar research tools can extract specific technical discussions, discover new connections, and track project evolution through these as sources. + +Below is a complete list of all WDYGDTW session recordings. These videos can be imported into tools like Google's [NotebookLM](https://notebooklm.google.com/) via youtube video import for deeper analysis, transcript generation, and pattern recognition across the development timeline: + +[![image](/blog/notebooklm.jpg)](https://notebooklm.google.com/) + +**Youtube** + +1. https://www.youtube.com/watch?v=9EmvhlBPB8Q +2. https://www.youtube.com/watch?v=Lbvv0Dr91Bc +3. https://www.youtube.com/watch?v=nUAEQ7uKi04 +4. https://www.youtube.com/watch?v=r3Z4lvu_ic4 +5. https://www.youtube.com/watch?v=4u8rbjmvWC0 +6. https://www.youtube.com/watch?v=R3auUQj9oEg +7. https://www.youtube.com/watch?v=jcSF7dSicTI +8. https://www.youtube.com/watch?v=Vs7D5DN_trk +9. https://www.youtube.com/watch?v=fqM_vYK2bmc +10. https://www.youtube.com/watch?v=1voboZEQTAw +11. https://www.youtube.com/watch?v=mxdWvBnxN8M +12. https://www.youtube.com/watch?v=SZNuoXJ1Mvs + +**Notes** + +1. [WDYGDTW #1](/community/streams/11-2024/2024-11-15) +2. [WDYGDTW #2](/community/streams/11-2024/2024-11-22) +3. [WDYGDTW #3](/community/streams/11-2024/2024-11-29) +4. [WDYGDTW #4](/community/streams/12-2024/2024-12-06) +5. [WDYGDTW #5](/community/streams/12-2024/2024-12-13) +6. [WDYGDTW #6](/community/streams/12-2024/2024-12-20) +7. [WDYGDTW #7](/community/streams/12-2024/2024-12-27) +8. [WDYGDTW #8](/community/streams/01-2025/2025-01-03) +9. [WDYGDTW #9](/community/streams/01-2025/2025-01-10) +10. [WDYGDTW #10](/community/streams/01-2025/2025-01-17) +11. [WDYGDTW #11](/community/streams/01-2025/2025-01-24) +12. [WDYGDTW #12](/community/streams/01-2025/2025-01-31) + +If you do something cool with this data, let us know in the [discord](discord.gg/ai16z)! + +After 3 straight months of nonstop building, it was time for a rest period. We may bring this format back, but we also want to continue the spirit of public accountability and transparent development through other community initiatives to keep things fresh. One such example is [Clank Tank](https://m3org.com/tv), where a standup becomes a pitch to AI judges that give you feedback about your project. diff --git a/packages/docs/community/Analysis/20250127_20250202.md b/packages/docs/community/Analysis/20250127_20250202.md new file mode 100644 index 00000000000..7e17230b039 --- /dev/null +++ b/packages/docs/community/Analysis/20250127_20250202.md @@ -0,0 +1,114 @@ +# Jan27 - Feb2, 2025 + +## Chronicle of the Week + +### Monday, January 27 + +The week began with significant plugin updates across the ElizaOS ecosystem, including improvements to Zerion, Spheron, Story, SUI, Twitter, and TTS plugins, focusing on enhanced type safety and code quality. New test configurations were introduced for Anyone, 3D Generation, and Asterai plugins. The community engaged in discussions about DeepSeek's impact on open-source AI and the strategic direction of AI16Z tokens versus DegenAI. + +### Tuesday, January 28 + +Development continued with fixes addressing typing errors and logical inconsistencies affecting plugins like plugin-quai, plugin-opacity, and plugin-omniflix. The community discussed the value of Kaito for podcast summarization and its potential integration with ElizaOS. Market discussions reflected concerns about token price support strategies. + +### Wednesday, January 29 + +Efforts focused on improving plugin testing and security enhancements, with updates to dependencies addressing CVE-2024-48930 and CVE-2024-37890. Documentation improvements included fixing broken links and correcting template typos to enhance usability. + +### Thursday, January 30 + +Plugin fixes continued with `plugin-irys`, `plugin-lensnetwork`, and `plugin-router-nitro` receiving attention for logic errors. Zod schema issues were resolved in multiple plugins. The crypto market showed positive momentum with WBTC, WETH, SOL, and ai16z all gaining value. + +### Friday, January 31 + +The ecosystem expanded with new integrations, including Tavily SDK for improved search capabilities and Volcengine model updates. Documentation accessibility improved with a Spanish README addition. The team focused on enhancing knowledge systems and PostgreSQL SSL support. + +### Saturday, February 1 + +ElizaOS 0.1.9 was released, with acknowledgments to contributors for their work. Post-release fixes addressed logging levels, startup tips, and wallet address validation. The community was informed about upcoming hackathons including Safe Agentathon, Sozu Hack, Agent Hackathon, and SUI AI Agent Hackathon. + +### Sunday, February 2 + +The week concluded with tokenomics updates introducing a liquidity pool for the AI16Z token. ElizaOS showed impressive growth metrics: 13.8k+ GitHub stars (+1.3k), 4.1k+ forks (+500), and 508 contributors (+79). The AI16Z DAO announced rebranding initiatives while maintaining the $ai16z ticker. + +## Technical Development Analysis + +### Core Infrastructure Improvements + +The week demonstrated a strong focus on infrastructure reliability and security: + +- **Type Safety Enhancement (Jan 27-28)**: Systematic improvements to type definitions across multiple plugins represent a strategic investment in codebase maintainability. This focus on type safety indicates a maturing codebase preparing for scaled adoption. + +- **Security Patching (Jan 29-30)**: Critical security updates addressed CVE-2024-48930 and CVE-2024-37890, showing the project's commitment to security best practices. The team's prompt response to these vulnerabilities demonstrates strong operational security awareness. + +- **Documentation Evolution (Jan 31-Feb 1)**: The addition of a Spanish README and improvements to various guides signal efforts to expand the contributor base beyond English-speaking developers. This internationalization effort aligns with the project's decentralized ethos. + +- **Test Coverage Expansion (Jan 29-Feb 2)**: New test configurations for multiple plugins, including Avalanche, Avail, and Autonome, suggest a shift toward more robust quality assurance processes—critical for enterprise adoption. + +### Feature Development Trajectory + +Analysis of feature development shows strategic prioritization: + +1. **AI Model Integration (Jan 30-Feb 1)**: + + - Volcengine model updates (Jan 31) + - O1 model support in js-tiktoken (Feb 1) + - Google Vertex AI integration (Feb 1) + - This pattern indicates diversification beyond OpenAI dependencies + +2. **Blockchain/Protocol Expansion (Jan 27-Feb 2)**: + + - New plugins for Zilliqa, OKX DEX, Paraswap-based swap action + - Movement Network support added to Aptos Plugin + - Massa plugin with Transfer action + - This represents horizontal expansion of ElizaOS's blockchain compatibility + +3. **Search & Knowledge Management (Jan 31-Feb 1)**: + - Tavily SDK integration + - Separation of knowledge system from memories table + - These improvements enhance agents' ability to access and process information + +## Community & Governance Dynamics + +### Channel Activity Patterns + +The `partners` channel shows the highest engagement, particularly around market discussions and token strategies. The `associates` channel focused on strategic discussions about DeepSeek's impact and the relationship between degenai and ai16z tokens. The `degenspartanai` channel revealed tensions around project leadership and direction. + +### Ecosystem Collaboration Structure + +A clear pattern emerged showing three distinct contributor segments: + +1. **Core Technical Contributors**: Focused on plugin development, testing, and infrastructure improvements +2. **Ecosystem Strategists**: Discussing tokenomics, rebranding, and partnership opportunities +3. **Community Advocates**: Sharing tutorials, promoting hackathons, and creating documentation + +The integration between these segments appears strongest when there are clear technical achievements to rally around, as evidenced by the positive community response to the 0.1.9 release. + +## Strategic Implications & Opportunities + +### Technical Priorities + +1. **Testing Infrastructure**: The current focus on test coverage is timely but incomplete. Gaps remain in critical plugins like Coingecko and Coinmarketcap. Prioritizing comprehensive test coverage would strengthen reliability. + +2. **Plugin Architecture Standardization**: The pattern of similar fixes across multiple plugins suggests an opportunity to establish stronger architectural patterns that would prevent these issues in future plugin development. + +3. **Multi-Model Strategy**: The expansion beyond OpenAI to support Volcengine, Google Vertex AI, and other models positions ElizaOS favorably in the evolving AI landscape, reducing dependency risks. + +### Governance Considerations + +1. **DegenAI & AI16Z Relationship**: Community discussions reveal ongoing tension regarding resource allocation between these projects. The February 2 announcement about ai16z rebranding to ElizaOS (while maintaining the $ai16z ticker) may help clarify positioning, but strategic communication about the relationship between these initiatives remains necessary. + +2. **Liquidity Strategy**: The introduction of an LP for AI16Z token enabling DAO fund participation represents a significant tokenomics evolution. Monitoring the effectiveness of this approach in balancing liquidity with token stability will be critical. + +3. **Contributor Growth Management**: With a 18% increase in contributors (+79) reported on February 2, establishing scalable onboarding and contribution guidelines becomes increasingly important. + +### Market & Adoption Outlook + +1. **Enterprise Integration Potential**: The addition of Azure model support and PostgreSQL SSL capabilities signals readiness for enterprise deployment scenarios. This presents an opportunity to develop specific enterprise-focused documentation and integration paths. + +2. **Hackathon Engagement Strategy**: The announced hackathons (Safe Agentathon, Sozu Hack, Agent Hackathon, SUI AI Agent Hackathon) represent strategic channels for expanding the developer ecosystem. Ensuring adequate documentation and starter templates for these events could maximize conversion to long-term contributors. + +3. **Autonomous Agent Focus**: Multiple references to autonomous agent capabilities throughout the week's communications indicate this as a key differentiator. Establishing clear metrics for agent autonomy and showcasing benchmark examples could strengthen this positioning. + +--- + +_This analysis covers January 27 - February 2, 2025, based on GitHub activity, Discord communications, and Twitter announcements from the ElizaOS and AI16Z ecosystem._ diff --git a/packages/docs/community/Analysis/20250203_20250208.md b/packages/docs/community/Analysis/20250203_20250208.md new file mode 100644 index 00000000000..51be44dcff2 --- /dev/null +++ b/packages/docs/community/Analysis/20250203_20250208.md @@ -0,0 +1,123 @@ +# February 3-8, 2025 + +## Daily Activity Log + +### Monday, February 3 + +- **Repository Activity**: Multiple plugin updates implemented, including `plugin-0x`, `plugin-3g-generation`, `plugin-abstract`, and others with Biome integration for improved code quality [PR #3178, #3175] +- **New Integrations**: Eight new plugins introduced to the ecosystem: Perplexica Search, GoPlus, Snapshot DAO, KAIA, TON, Taiko, Mina, and Okto [PR #3168, #3164, #3173, #3231, #3228, #3230, #3217, #3225] +- **Bug Fixes**: Embedding validation issues addressed with additional checks for 'Invalid embedding input' [PR #3155] +- **Infrastructure Issues**: Reports of pnpm start errors led to proposed Docker build fixes [Issue #3151, PR #3158] + +### Tuesday, February 4 + +- **Blockchain Integration**: KAIA Plugin integration completed, enabling blockchain transactions with Kaia Blockchain [PR #3231] +- **Community Events**: DAOVOS #4 discussion generated community engagement and feedback [Twitter] +- **Security Updates**: Critical Vitest security update implemented [Multiple PRs] +- **Social Media**: Discussions initiated about AI agents integration into crypto wallet technologies [Twitter] + +### Wednesday, February 5 + +- **Syntax Fixes**: JSON syntax error in `plugin-solana-v2` resolved, fixing trailing comma causing pnpm install errors [PR #3261, #3277] +- **Data Handling**: Improved handling for invalid JSON [PR #3258] +- **Client Integration**: Alexa client updated by merging the fix-client-alexa branch [Commits 69af5ff, a7c3da0] +- **Database Optimization**: PostgreSQL query issue for cached embeddings fixed [PR #3264] +- **API Improvements**: Enhanced OpenAI-like provider endpoint resolution in generation.ts [PR #3280, #3281] +- **Plugin Features**: Added Quick-Intel plugin optimization, TON plugin lending/borrowing system [PR #3283, #3287] + +### Thursday, February 6 + +- **Integration Development**: Discussions on building AI agents with Venice and ElizaOS [Twitter] +- **User Experience**: Discord action suppression functionality fixed [PR #3284] +- **Authentication**: Twitter authentication restored via environment variables [PR #3278] +- **Technical Documentation**: Fixed broken links in contribution guidelines [PR #3269] +- **Security**: Vitest dependency updated to address CVE-2025-24964 vulnerability [PR #3256, #3254] +- **Branch Management**: Merged develop changes into main branch [Commits 85fefc2, c30b66d] + +### Friday, February 7 + +- **Architecture Change**: Plugin registration system transition announced, enabling easier CLI management [Twitter] +- **New Components**: Three new plugins added: `plugin-vana`, `plugin-elfa-ai`, `plugin-som` [PR #3338, #3331, #3304] +- **Versioning**: Version bumped to 0.25.6-alpha.1 [Commit 47c2b7c] +- **Core Features**: Initial implementation of CWD and dynamic plugin loading [PR #3337, #3336] +- **Social Integration**: Enhanced plugin interactions with MessengerManager for Telegram [PR #3314] +- **Development Activity**: 154 issues and 373 pull requests opened in the week [Twitter] + +### Saturday, February 8 + +- **API Fixes**: Resolved issue where apiKey was lost in HandleGoogle function [Commit 61887b3] +- **Configuration**: Updated model configuration to read from character file [Commit b2889dc] +- **Testing**: Fixed unit test failures for models and parsing [Commit b224b8e] +- **Social Media**: Fixed Twitter logging bug [Commit 2dbf2cc] +- **Packaging**: Set public publish access for package [Commit 87515e2] +- **Community Metrics**: 32 contributors merged 15 PRs focused on package improvements and bug fixes [Twitter] + +## Technical Activity Analysis + +### Repository Development Focus + +1. **Plugin Architecture Expansion** + + - Eight new blockchain-related plugins added on February 3 [Multiple PRs] + - Transition to registry system for plugin management announced February 7 [Twitter] + - Implementation of dynamic plugin loading on February 8 [PR #3336] + +2. **Infrastructure Reliability** + + - Docker configuration issues addressed on February 5 [PR #3220] + - PNPM version update on February 3 resolving startup errors [PR #3158] + - PostgreSQL query structure optimized for cached embeddings on February 5 [PR #3264] + +3. **API Integration Refinement** + + - Google API key handling fixed on February 8 [Commit 61887b3] + - OpenAI-like provider endpoint improved on February 5 [PR #3280, #3281] + - Twitter authentication restoration on February 6 [PR #3278] + +4. **Security Improvements** + - Multiple Vitest dependency updates addressing CVE-2025-24964 on February 6-7 [Multiple PRs] + - Invalid JSON handling enhancement on February 5 [PR #3258] + +### Code Quality Initiatives + +1. **Type Safety Improvements** + + - Fixed model configuration parameter override issues on February 4 [Issue #3233] + - Addressed IAgentRuntime argument type mismatch causing build failure on February 8 [Issue #3322] + +2. **Documentation Standardization** + + - Fixed links in CONTRIBUTING.md on February 6 [PR #3269] + - Corrected documentation typos on February 7 [Commit e16cf8e] + +3. **Code Organization** + - Renamed `plugin-apro` to `plugin-ATTPs` on February 7 [PR #3299] + - Implemented Biome linting to replace ESLint on February 5 [PR #3255] + +## Version Development Trajectory + +The version numbering change to 0.25.6-alpha.1 on February 7 [Commit 47c2b7c] represents a significant increment from previous versioning patterns. This suggests an acceleration in feature development while maintaining alpha designation. + +Key versioning-related decisions: + +- Character file-based model configuration on February 8 [Commit b2889dc] +- Public publish access established on February 8 [Commit 87515e2] +- Package.json version entry fix on February 8 [Commit c108525] + +## Community Activity Patterns + +1. **Development Velocity** + + - 154 issues and 373 pull requests opened in one week (reported February 7) [Twitter] + - 32 contributors merged 15 PRs on February 8 [Twitter] + +2. **Technical Discussion Focus** + + - AI agent conceptualization discussions on February 8 ("Mech Suits" metaphor) [Twitter] + - Fair reward distribution considerations on February 8 [Twitter] + +3. **Integration Expansion** + - Blockchain plugin proliferation throughout the week (8 new plugins February 3-5) + - Social platform integration (Twitter, Telegram) enhanceed February 6-7 [Multiple PRs] + +The week demonstrated consistent focus on technical development with particular emphasis on plugin architecture evolution and infrastructure reliability. The transition to a registry system for plugin management represents a significant architectural direction that will likely influence development patterns in subsequent weeks. diff --git a/packages/docs/community/Analysis/20250210_20250216.md b/packages/docs/community/Analysis/20250210_20250216.md new file mode 100644 index 00000000000..c8d9b2aac68 --- /dev/null +++ b/packages/docs/community/Analysis/20250210_20250216.md @@ -0,0 +1,203 @@ +# February 10-16, 2025 + +## Weekly Activity Record by Date + +### Monday, February 10 (2025-02-10) + +- **Repository Activity**: Multiple plugin updates introduced including "Create VangAI" (Crypto Oracle), Twitter update proposal, Tum Work update, and Nillion frontend integration [PRs: #3405, #3404, #3402, #3391] +- **Documentation**: Enhanced README with system requirements and project structure; Turkish documentation rewrite by native speaker; correction of changelog errors [PRs: #3392, #3422, #3407] +- **Infrastructure**: Externalization of vendor code, improving scalability by removing third-party plugins from core; switching package manager from `pnpm` to `bun` [PR: #3393] +- **Build System**: Adjustments to build sequence with new `build:core` command; resolved issues with `bun run build` [PRs: #3398, #3396] +- **Database**: Introduction of Drizzle ORM-based database adapter with structured schema management [PR: #3403] + +### Tuesday, February 11 (2025-02-11) + +- **Repository Activity**: Fuel AI character setup, SQLite tests, and fixes for `npm run dev` [PR: #3446] +- **Plugin Development**: Bluefin trading plugin and CLI utility for managing ElizaOS v1 plugins introduced [PRs: #3427, #3429] +- **Bug Fixes**: Knowledge storage issue identified where `stringKnowledge` was wrongfully stored in `memories` when `ragKnowledge` enabled [Issue: #3434] +- **Community Updates**: ElizaOS reported to outpace OpenAI's TypeScript repository in contributions [Twitter: @0xwitchy] +- **Environment Issues**: Problems with `.env` not correctly preparing server port and model on macOS M3 [Issue: #3449] + +### Wednesday, February 12 (2025-02-12) + +- **Feature Additions**: ElevenLabs plugin implementation; Viction plugin introduction; Muppet characters added [PRs: #3452, #3455, #3430] +- **Infrastructure**: XMTP component refactored; bug fixes for 'npm run dev'; additional SQLite tests [PRs: #3426, #3446] +- **Client Integration**: 'Client-Tako' feature added to integrate Tako for proactive interactions and scheduled posting [PR: #3433] +- **API Improvements**: Enhanced Unicode and newline handling in `cleanJsonResponse` [PR: #3442] +- **Database**: Query updates adjusted for new table schema while ensuring backward compatibility [PR: #3459] + +### Thursday, February 13 (2025-02-13) + +- **Documentation**: Multiple discussions about documentation importance for knowledge replication, project longevity, and developer experience [Twitter: @dankvr] +- **Plugin System**: Environment variables enhancement for D.A.T.A plugin [PR: #3457] +- **Client Improvements**: Speech-to-text enhancements for performance and reliability [PRs: #3461, #3454] +- **Code Quality**: Minor linting issues resolved for consistency [PR: #3462] +- **Community Discussion**: Debates over AI agents requiring anxiety; The Org Project introducing AI interlocking agents for community management [Twitter: @shawmakesmagic] + +### Friday, February 14 (2025-02-14) + +- **Plugin Expansion**: DeFi Token Analysis Plugin (plugin-expuzi) with risk scoring system and CoinGecko integration; Messari Copilot Plugin for market research [PRs: #3468, #3482] +- **Integration Support**: Request for exSAT blockchain integration with ElizaOS [Issue: #3473] +- **Technical Issues**: Build failure on macOS 15.3 due to Zod import issue with @elizaos/plugin-pyth-data [Issue: #3469] +- **Testing**: OpenAI plugin tests added for stabilization [PR: #3466] +- **Documentation**: Fixed incorrect image paths in Korean documentation [PR: #3481] + +### Saturday, February 15 (2025-02-15) + +- **Hackathon**: Sui AI Agent Hackathon winners announced [Twitter: @elizaOS] +- **Security**: Promoting onchain communication to prevent fake verification scams [Twitter: @dankvr] +- **Development**: Main repository synced with Jobsy; 15 developers involved with three pull requests merged [PR: #3510] +- **Community**: Contribution-based systems suggested to support high performers [Twitter: @dankvr] +- **Deployment**: Port scanning error reported in Twitter Eliza agent deployment [Issue: #3514] + +### Sunday, February 16 (2025-02-16) + +- **Growth Metrics**: ElizaOS reports 14.4k stars (+600), 4.5k forks (+400), and 508 contributors (+23) on GitHub [Twitter: @0xwitchy] +- **Security**: Vitest dependency updated to address CVE-2025-24964, mitigating remote code execution risks [PR: #3525] +- **Version Release**: ElizaOS v0.25.7 released with multiple changelog updates [PR: #3522] +- **Security Alert**: @shawmakesmagic account reported hacked; community warned against interacting with tweets and links [Twitter: @0xwitchy] +- **Plugin Development**: 'plugin-extractor' introduced to integrate risk scoring via Extractor Agent Firewall API [PR: #3534] + +## Technical Development Analysis + +### Repository Architecture Evolution + +The week showed significant architectural evolution across three dimensions: + +1. **Package Management Transition** (February 10) + + - Shift from `pnpm` to `bun` package manager [PR #3393] + - Build sequence adjustments with new `build:core` command [PR #3398] + - These changes signal infrastructure optimization for improved development workflows + +2. **Database Layer Transformation** (February 10-12) + + - Introduction of Drizzle ORM-based database adapter [PR #3403] + - Database query updates for new table schema with backward compatibility [PR #3459] + - This represents a move toward more structured and maintainable data management + +3. **Plugin Architecture Refinement** (February 11-14) + - CLI utility for managing ElizaOS v1 plugins [PR #3429] + - Plugin system environment variable enhancements [PR #3457] + - These improvements suggest maturation of the plugin ecosystem for easier developer onboarding + +### Testing and Stability Improvements + +Consistent focus on testing and stability was evident throughout the week: + +- **Test Coverage Expansion**: OpenAI plugin tests added [PR #3466] and SQLite tests implemented [PR #3446] +- **Build Reliability**: Resolution of `bun run build` issues [PR #3396] and macOS build failure addressed [Issue #3469] +- **Security Updates**: Vitest dependency updated for CVE-2025-24964 [PR #3525] + +The steady cadence of testing improvements indicates a project transitioning from rapid feature development to ensuring production-grade stability. + +### Documentation Prioritization + +A strong emphasis on documentation emerged midweek: + +- **Multilingual Support**: Turkish documentation rewrite [PR #3422] and Korean documentation image path fixes [PR #3481] +- **Community Standards**: Extensive discussions about documentation importance [Twitter: @dankvr, February 13] +- **Contribution Guidelines**: Git contribution documentation updating branch naming conventions [PR #3532] + +This documentation focus coincides with the reported growth metrics (+600 stars, +400 forks, +23 contributors), suggesting strategic preparation for community scaling. + +## Ecosystem Dynamics + +### Community Structure Patterns + +Analysis of the week's activities reveals three distinct community segments: + +1. **Core Technical Contributors** + + - Focus on infrastructure (database adapters, build systems) + - Primarily active through PRs and issues on repository + +2. **Plugin Ecosystem Developers** + + - Creating specialized integrations (DeFi Token Analysis, Messari Copilot) + - Addressing specific vertical use cases (finance, market research) + +3. **Community Advocates/Managers** + - Active on Twitter discussing documentation, security, and community systems + - Announcing growth metrics and hackathon winners + +The interaction between these segments appears strongest when security issues arise, as evidenced by the coordinated response to the reported account hack on February 16. + +### Technical Focus Trends + +The progression of technical focus through the week shows an evolution: + +- **Early Week (Feb 10-11)**: Infrastructure foundations - package manager changes, database adaptors +- **Mid Week (Feb 12-13)**: User-facing features - client integrations, speech-to-text improvements +- **Late Week (Feb 14-16)**: Security and stability - CVE fixes, build reliability + +This pattern suggests a development cycle moving from core infrastructure to feature development to stability hardening. + +### Communication Channel Utilization + +Different channels served distinct functions: + +- **GitHub**: Technical specifications, code reviews, implementation details +- **Twitter**: Growth announcements, security alerts, philosophical discussions +- **Discord**: Community engagement (though little specific content was reported) + +The separation of technical (GitHub) and strategic (Twitter) communications appears deliberate, with different stakeholder groups engaged on each platform. + +## Strategic Observations + +### Technical Architecture Direction + +The week's developments indicate several strategic technical priorities: + +1. **Plugin Ecosystem Maturation** + + - The introduction of a CLI for plugin management [PR #3429] suggests preparation for a larger plugin marketplace + - The diversity of new plugins (DeFi, Market Research) points to domain specialization + +2. **Performance Optimization** + + - Package manager transition to `bun` [PR #3393] indicates focus on build performance + - Speech-to-text improvements [PRs #3461, #3454] suggest user experience prioritization + +3. **Multilingual Support Expansion** + - Documentation in Turkish [PR #3422] and Korean [PR #3481] suggests international community targeting + +### Community Growth Management + +The reported metrics (+600 stars, +400 forks, +23 contributors) reveal accelerating adoption that introduces both opportunities and challenges: + +1. **Onboarding Efficiency** + + - Documentation improvements appear strategically timed to support new contributor integration + - CLI tools for plugin management reduce friction for new plugin developers + +2. **Quality Control Balancing** + + - Increased testing [PR #3466, #3446] while maintaining rapid feature development + - Build system improvements [PR #3398, #3396] to accommodate more diverse contributor environments + +3. **Security Vigilance** + - Prompt CVE addressing [PR #3525] + - Community alerts about account compromise [Twitter: @0xwitchy, February 16] + +### Market Positioning Indications + +Several developments hint at strategic market positioning: + +1. **Financial Services Focus** + + - Multiple finance-related plugins (DeFi Token Analysis, Messari Copilot) + - Risk assessment capabilities suggesting institutional-grade aspirations + +2. **Hackathon Engagement** + + - Sui AI Agent Hackathon winner announcement [Twitter: @elizaOS, February 15] + - Target for developer mindshare in competitive AI agent landscape + +3. **Version Progression** + - Release of v0.25.7 [PR #3522] indicating progression toward v1.0 + - Roadmap release [Twitter: @0xwitchy, February 16] outlining short, mid, and long-term projections + +--- + +This weekly summary captures a project showing signs of maturation: transitioning from infrastructure building to feature development while simultaneously hardening security and stability. The consistent documentation improvements and community engagement suggest preparation for sustainable ecosystem growth beyond the core technical team. diff --git a/packages/docs/community/Analysis/20250217_20250223.md b/packages/docs/community/Analysis/20250217_20250223.md new file mode 100644 index 00000000000..10985332e3b --- /dev/null +++ b/packages/docs/community/Analysis/20250217_20250223.md @@ -0,0 +1,385 @@ +# February 17-23, 2025 + +## CHRONICLE OF EVENTS + +### Monday, February 17 + +**GitHub Development** + +- Introduced "ferrAIgnez" AI character to ElizaOS project [PR #3531] +- Fixed vector dimension mismatch error in `plugin-news` module [PR #3530] +- Added default voice for ElevenLabs plugin integration [PR #3519] +- Updated RAG knowledge consolidation system across database adapters [PR #3516] +- Refactored Local AI plugin with local inference capabilities [PR #3526] + +**Twitter Activity** + +- Discussions on AI-led VC DAO development through game show concept [@dankvr] +- Reports of AI analytics tools integration in Discord/Telegram workspaces [@0xwitchy] +- AI Agent hacker house at Ethereum Denver featuring @elizaOS and @eigenlayer [@0xwitchy] +- Ongoing development of decentralized agent swarm system for DAOs [@shawmakesmagic] + +**Security Updates** + +- Patched critical vulnerability (CVE-2025-24964) related to Cross-site WebSocket hijacking [PR #3525] + +### Tuesday, February 18 + +**GitHub Development** + +- Introduced "Main Tercel" project updates for infrastructure and authentication [PR #3568] +- Added Merkle Trade Plugin for enhanced trading on Aptos blockchain [PR #3565] +- Switched to Node.js native `crypto.randomUUID()` for better performance [PR #3566] +- Implemented Discord and Twitter end-to-end testing integration [PR #3579] +- Fixed Discord E2E testing with test channel ID configuration [PR #3559] + +**Twitter Activity** + +- Launched Season 1, Episode 1 of new show premiering this week [@dankvr] +- Request for intentionally bad pitch ideas for fun participation [@dankvr] +- Proposal for wiki creation to improve information retention in crypto community [@dankvr] +- Noted shift in crypto focus from infrastructure toward utility and innovation [@dankvr] + +**Community Discussions** + +- DAOVOS Episode 10 released [@daosdotfun] +- Tally documentation praised for excellence [@dankvr] + +### Wednesday, February 19 + +**GitHub Development** + +- Implemented cross-platform drag-and-drop feature with extensive documentation [GitHub/Twitter] +- Significant documentation overhaul with reorganized sidebars and concept-focused explanations [PR #3584] +- Enhanced core infrastructure with JWT authentication and PostgreSQL integration [PR #3568] +- Introduced new pull request template for improved documentation and testing [PR #3558/3557] +- Added PNPM reload script for efficient component reloading [PR #3580] + +**Twitter Activity** + +- Reports of turbulent sentiment and investor uncertainty for AI coins [@dankvr] +- Predictions that AI-driven governance will become a significant trend [@shawmakesmagic] +- Focus on utility and innovation for future AI coin opportunities [@dankvr] + +**Technical Issues** + +- Reported recurring frontend-backend disconnections with local server (CORS issue) [Issue #3578] +- User-reported Node.js module installation problems on Windows 11 [Issue #3571] + +### Thursday, February 20 + +**GitHub Development** + +- Multiple bug fixes and pull request merges by contributors +- Continuing feature development for Discord and Twitter testing + +**Twitter Activity** + +- Clarification that Clank Tank has no contract address or token association [@dankvr] +- Announcement that Clank Tank premiere coincides with Killer Whales Season 2 [@dankvr] +- Requirement for rigged 3D avatars for participants, with customization offered [@dankvr] +- Thread shared with demo and explanation of Clank Tank concept [@dankvr] + +**Community Announcements** + +- Introduction to Clank Tank: AI-generated simulations based on pitches, judged by AI [@dankvr] +- Open invitation for pitch submissions for potential inclusion in future episodes [@dankvr] + +### Friday, February 21 + +**GitHub Development** + +- Added Secret AI LLM support for data protection with Eliza-based agents [PR #3615] +- Fixed bug enabling agent restart through client API [PR #3618] +- Corrected codebase typing error [PR #3617] +- Fixed Discord actions (pending resolution for `ytdl` issue) [PR #3608] +- Adjusted plugin import from registry [PR #3611] +- Corrected port mapping syntax in `devcontainer.json` [PR #3616] + +**Twitter Activity** + +- Announcement of Esk3nder joining ElizaOS team for AI agent innovation [@elizaOS] +- Discussions on standardized framework for AI agents similar to ERC-20 for NFTs [@0xwitchy] +- Comparison of AI judges versus human judging processes [@dankvr] +- Launch of ElizaOS Builder's Chat on Telegram for developers and AI enthusiasts [@ai16zdao] +- Commentary on overwhelming nature of contributing to DAOs [@dankvr] + +**Development Focus** + +- Comprehensive agent system overhaul with character management and logging improvements [PR #3613] +- Memory system enhancements with KnowledgeMetadata and browser compatibility [PR #3606] + +### Saturday, February 22 + +**GitHub Development** + +- Rollback implemented for agent re-initialization via client direct API [PR #3618] +- Fixed Discord actions except for download media plugin [PR #3608] +- Corrected issue with importing plugins from registry [PR #3611] +- Updated `devcontainer.json` file to fix port mapping syntax errors [PR #3616] +- Added support for Secret's Confidential AI for enhanced data protection [PR #3615] + +**Twitter Activity** + +- Discussion of Grok 3 by xAI for analyzing X user profiles and content [@shawmakesmagic] + +**Technical Issues** + +- Reported bug with visual representation responses for non-image tweets [Issue #3614] +- Enhancement of test plugin with improved color formatting and process termination [PR #3612] + +### Sunday, February 23 + +**GitHub Development** + +- Updated Discord link for elizaOS [PR #3643] +- Total of 11 pull requests merged with contributions from various developers + +**Twitter Activity** + +- Announcement of website development, temporarily hosted on YouTube [@dankvr] +- Premiere of CLANK TANK Episode 1 [@shawmakesmagic] +- Debate on Solana UX compared to other ecosystems [@shawmakesmagic] +- Comparison of wallet experiences across different blockchain platforms [@shawmakesmagic] +- Contributor returning home, planning to resume streaming and development [@shawmakesmagic] + +## ARTIFACT ANALYSIS + +### Code Contribution Patterns + +The week demonstrated continued architectural evolution with 49 logged GitHub activities across 7 days, averaging 7 significant code events per day. Analyzing the contribution patterns reveals three distinct development threads: + +1. **UI/UX Enhancement Focus (38% of contributions)** + + - Cross-platform drag-and-drop feature implementation [February 19] + - Discord and Twitter testing integration [February 18] + - PNPM reload script for component efficiency [February 19] + - Agent re-initialization via client API [February 22] + + This cluster indicates prioritization of user-facing improvements and testing frameworks to support them. + +2. **Security and Data Protection (24% of contributions)** + + - Secret AI LLM support for confidential computing [February 21] + - Critical vulnerability patch for CVE-2025-24964 [February 17] + - JWT authentication enhancement [February 19] + + The security focus demonstrates maturity in the development lifecycle, with particular emphasis on protecting user data in AI interactions. + +3. **Infrastructure Modernization (22% of contributions)** + + - Switch to Node.js native `crypto.randomUUID()` [February 18] + - PostgreSQL integration improvements [February 19] + - RAG knowledge consolidation system updates [February 17] + + These changes reflect ongoing efforts to optimize performance and scalability while reducing dependencies. + +The remaining 16% of contributions were distributed across documentation improvements and miscellaneous bug fixes. + +### Documentation Evolution + +The documentation corpus experienced substantial growth and reorganization: + +1. **Structural Transformation** + - Pull request template introduction [February 19] + - Sidebar reorganization for improved navigation [February 19] + - Concept-focused explanations replacing function-based documentation [February 19] +2. **Internationalization Efforts** + + - Previous week's work on Turkish and Korean documentation continued to be referenced + - Discord link update suggesting community expansion efforts [February 23] + +3. **Developer Onboarding Acceleration** + - Extensive documentation for the drag-and-drop feature [February 19] + - Enhanced README with system requirements and project structure [Earlier work referenced] + +This documentation transformation coincides with reported growth metrics from the previous week (+600 stars, +400 forks, +23 contributors), suggesting strategic preparation for larger-scale community adoption. + +### Test Infrastructure Development + +Testing infrastructure saw significant advancement: + +1. **Integration Testing** + - End-to-end testing for Discord and Twitter [February 18] + - Test channel ID configuration [February 18] +2. **Component Testing** + - Enhancement of test plugin with improved formatting [February 22] + - Test process termination improvements [February 22] + +These testing improvements indicate a shift toward more robust quality assurance practices, essential for production deployment reliability. + +## ECOSYSTEM PATTERNS + +### Community Structure Dynamics + +Analysis of the week's activities reveals distinct participant groups with different interaction patterns: + +1. **Core Technical Contributors** + + - Primary activity on GitHub via PRs and issues + - Focus on infrastructure, security, and platform stability + - Little public communication on Twitter or Discord + +2. **Platform Extenders** + + - Contributing specialized plugins and integrations (Merkle Trade, Secret AI) + - Active in both GitHub and Twitter discussions + - Bridge between technical implementation and use cases + +3. **Community/Content Leaders** + + - Dominant presence on Twitter + - Focus on Clank Tank, DAOVOS, and community engagement + - Minimal direct code contributions, but significant influence on roadmap + +4. **Technical Evangelists** + - Active across all channels + - Translating technical concepts for wider audience + - Notable examples: discussions about standardized AI agent frameworks [February 21] + +The interplay between these groups shows a maturing ecosystem with specialized roles emerging organically. + +### Communication Channel Utilization + +Different channels served distinct functions in the ecosystem: + +1. **GitHub**: Technical specifications, implementation details, and quality assurance +2. **Twitter**: Vision sharing, community building, and ecosystem positioning +3. **Telegram**: New channel (ElizaOS Builder's Chat) introduced for real-time developer collaboration [February 21] +4. **Discord**: Community engagement (limited data available in the source material) + +The distribution of content types across channels suggests intentional communication strategy: + +- Technical announcements primarily on GitHub (89% of technical details) +- Vision and roadmap primarily on Twitter (93% of strategic communications) +- Community building split between Twitter and newer Telegram initiative + +### Development Focus Evolution + +The chronological analysis reveals a priority shift throughout the week: + +1. **Early Week (Feb 17-18)**: Security and infrastructure foundation + + - Critical vulnerability patching + - UUID implementation improvement + - RAG knowledge system consolidation + +2. **Mid-Week (Feb 19-20)**: User experience and documentation + + - Drag-and-drop implementation + - Documentation overhaul + - PNPM reload script + +3. **Late Week (Feb 21-23)**: Integration and confidentiality + - Secret AI LLM support + - Agent system overhaul + - Discord actions fix + +This pattern suggests an intentional development cycle moving from core security to user-facing features to integration capabilities. + +## STRATEGIC IMPLICATIONS + +### Technical Architecture Direction + +The week's development activities point to several strategic priorities: + +1. **Confidential Computing Emphasis** + + - Secret AI LLM integration [February 21] + - Discussions on TEE agents with secure processes [February 21] + + These developments position ElizaOS at the intersection of AI and confidential computing, addressing a critical market need for privacy-preserving AI interactions. + +2. **Multi-Agent System Framework** + + - Agent system overhaul [February 21] + - Memory and metadata refactoring [February 21] + - Decentralized agent swarm for DAOs [February 17] + + The convergence of these improvements suggests preparation for more sophisticated multi-agent systems capable of complex collaborative behaviors. + +3. **Cross-Platform Standardization** + + - Cross-platform drag-and-drop [February 19] + - Browser compatibility improvements [February 21] + - Discord and Twitter integration testing [February 18] + + These efforts indicate a strategic priority to ensure consistent experience across different client platforms and integration points. + +### Community Growth Management + +The technical initiatives reveal approaches to manage community scaling: + +1. **Contributor Onboarding Optimization** + + - Documentation reorganization and enhancement [February 19] + - Pull request template introduction [February 19] + - ElizaOS Builder's Chat launch on Telegram [February 21] + + These changes streamline the path for new contributors and establish clearer contribution standards. + +2. **Quality Control Mechanisms** + + - Integration testing frameworks [February 18] + - Test process improvements [February 22] + + The testing infrastructure enhancements provide guardrails to maintain quality as the contributor base expands. + +3. **Community Segmentation** + + - Technical focus in Telegram Builder's Chat [February 21] + - Content creation through Clank Tank [February 20-23] + + The emergence of specialized community spaces indicates recognition of diverse stakeholder needs. + +### Governance and Tokenomic Considerations + +Several developments have implications for governance and token value: + +1. **AI-Led Governance Exploration** + + - AI-led VC DAO development [February 17] + - Predictions of AI-driven governance becoming a trend [February 19] + + These initiatives may serve as experimental governance models with implications for future DAO structures. + +2. **Value Capture Mechanisms** + + - Merkle Trade Plugin for Aptos blockchain [February 18] + - Website development for improved token holder interaction [February 23] + + These developments suggest efforts to create tangible utility and engagement mechanisms for token holders. + +3. **Standardization Efforts** + + - Discussions on standardized framework for AI agents [February 21] + + The push for standardization could position the project's token as a utility token within a broader ecosystem standard. + +### Market Positioning Evolution + +The week's activities indicate strategic market positioning efforts: + +1. **Developer Mindshare Targeting** + + - Launch of specialized Telegram chat for builders [February 21] + - Documentation improvements [February 19] + - Addition of Esk3nder to team for AI agent innovation [February 21] + + These initiatives aim to capture developer mindshare in the competitive AI agent landscape. + +2. **Content Strategy Execution** + + - Clank Tank premiere [February 23] + - Website development announcement [February 23] + + The content strategy appears designed to broaden appeal beyond technical audiences. + +3. **Institutional Readiness Signals** + + - JWT authentication improvements [February 19] + - Secret AI confidential computing integration [February 21] + + These enhancements signal readiness for enterprise adoption with appropriate security and authentication features. + +In conclusion, the week of February 17-23, 2025, demonstrates a project in active maturation—balancing technical innovation, community growth, and market positioning while establishing foundations for larger-scale adoption beyond the core technical community. diff --git a/packages/docs/community/Analysis/20250224_20250302.md b/packages/docs/community/Analysis/20250224_20250302.md new file mode 100644 index 00000000000..2a09e190e15 --- /dev/null +++ b/packages/docs/community/Analysis/20250224_20250302.md @@ -0,0 +1,455 @@ +# Feb24 - March2, 2025 + +## CHRONICLE + +### Monday, February 24 + +**GitHub Channel** + +- Discord link updated in the ElizaOS repository [PR #3643] +- Middleware settings added to Eliza framework for agent server control [PR #3648] +- UserRapport feature introduced to enhance Twitter interactions with personalization [PR #3647] +- Storacha plugin added to ElizaOS ecosystem [PR #3657] +- Knowledge processing fixed with length check to resolve 'Invalid array length' error [PR #3652] +- NEAR AI model support integrated for structured object generation [PR #3644] +- ElizaOS v0.25.8 released with all plugins moved out of main repository [Commit c04f89a] + +**Twitter Channel** + +- Agent Scarlett featured on Clank Tank [Tweet by @ai16zdao] +- Memecoin launch speculation discussed [Tweet by @shawmakesmagic] +- Market commentary on Kanye's potential coin impact shared [Tweet by @shawmakesmagic] + +**Market Data** + +- WBTC: $91,494.08 +- WETH: $2,512.24 +- SOL: $141.80 +- ai16z: $0.30 + +### Tuesday, February 25 + +**GitHub Channel** + +- Space action feature introduced to ElizaOS [PR #3655] +- RAG knowledge system used for facts with PostgreSQL handling other system functions + +**Twitter Channel** + +- Eliza v2 reported facing hacking attempts [Tweet by @shawmakesmagic] +- Entropy introduced to text generation to reduce repetition while maintaining structure [Tweet by @shawmakesmagic] +- Observations shared that AI systems often get caught in loops rather than executing incorrect actions [Tweet by @shawmakesmagic] + +**Market Data** + +- WBTC: $91,494.08 +- WETH: $2,512.24 +- SOL: $141.80 +- ai16z: $0.30 + +### Wednesday, February 26 + +**GitHub Channel** + +- Fixed participant errors in ElizaOS [PR #3671] +- Implemented pre-start dimension setup to prevent issues [PR #3668] +- Corrected speaker removal in Twitter Spaces functionality [PR #3662] +- Enhanced Twitter functionality with explicit activation for posting [PR #3659] +- Addressed issues with extensions and migrations [PR #3665] +- Server cleanup implemented with future Hyperfy and Whisper services [PR #3667] +- Local AI system refactored with enhanced validation, error handling, and logging [PR #3663] +- PGlite migrations fixed with code-first SQL management and extension support [PR #3672] + +**Twitter Channel** + +- Introduction of Kickstarter-style Founder DAOs on Solana for fundraising announced [Tweet by @daosdotfun] +- Tokenomics detailed: 10 billion tokens with public and team allocation [Tweet by @daosdotfun] +- First official Founder DAO (@Artistdaofun) launched [Tweet by @daosdotfun] +- Preview of Clank Tank set with baked lighting for cross-platform update shared [Tweet by @dankvr] + +**Market Data** + +- WBTC: $88,563.27, Volume: $84.71M, Market Cap: $11.44B, Daily change: -0.0375% +- SOL: $142.44, Volume: $363.17M, Daily change: 0.0148% +- WETH: $2,484.40, Volume: $298.38M, Market Cap: $7.26B, Daily change: -0.0097% + +### Thursday, February 27 + +**GitHub Channel** + +- Local AI plugin refactored with improved model management and modular feature additions [PR #3704] +- Linting and turbo fixes implemented [PR #3703] +- Code and documentation enhancements made [PR #3705, #3707] +- CLI and GUI installation process improved [PR #3697] +- Agent GUI enhancements added [PR #3708] +- Security upgrades: Turbo version upgraded and CI issues resolved [PR #3700] +- Character Creator functionality enhanced [PR #3710] +- Plugin and Format enhancements: improved error handling and JSON5 support [PR #3698] +- Viction plugin support added for AI agent integration [PR #3701] + +**Twitter Channel** + +- LightLinkChain and Gigbot plugin integration announced [Tweet by @ai16zdao] +- HYPE(R)HOUSE event scheduled for Feb 28 at ETHDenver featuring workshops and hackathon [Tweet by @ai16zdao] +- Vitalik Buterin's privacy rights and coding freedom advocacy highlighted [Tweet by @shawmakesmagic] +- Insight shared on sustainable token launch strategies emphasizing capture of ongoing trading volume [Tweet by @ai16zdao] +- TheCastleDAO partnership with daosdotfun announced [Tweet by @daosdotfun] +- PlayCanvas upgrade showcased for Hyperfy [Tweet by @dankvr] +- Optimized Clank Tank set for browser performance demonstrated [Tweet by @dankvr] +- Grok3 recognized for effective research and brainstorming capabilities [Tweet by @dankvr] + +**Market Data** + +- WBTC: $85,053.79 +- WETH: $2,358.06 +- SOL: $138.04 + +### Friday, February 28 + +**Twitter Channel** + +- Eliza v2 hack concerns expressed [Tweet by @shawmakesmagic] +- $ISAACX and ElizaOS partnership announced for integration of verified scientific research into AI agents [Tweet by @ai16zdao] +- Yeti emergence reported as community-trained AI amid scams and KOL dumps [Tweet by @ai16zdao] +- Founders DAO options detailed: "Indie Mode" ($250K FDV, raise $25K) and "Locked In Mode" ($2.5M FDV) [Tweet by @daosdotfun] +- New Dune dashboard and performance insights for DAOsdotfun Solana shared [Tweet by @daosdotfun] + +**Market Data** + +- WBTC: $83,112.86 to $84,237.85, Volume: $76,490,845, Market Cap: $10,733,063,375 +- WETH: $2,259.95 to $2,236.32, Volume: $171,444,015, Market Cap: $6,589,499,040 +- SOL: $134.00 to $148.06, Volume: $214,049,926 +- ai16z: $0.4034 + +### Saturday, March 1 + +**GitHub Channel** + +- Documentation improved for custom plugin integration beyond the registry [PR #3736] +- UI updated to support agent configuration with plugins and environment variables [PR #3731] + +**Twitter Channel** + +- New page for ElizaOS plugins showcased with efforts in automating updates [Tweet by @dankvr] +- Plugin Explorer development reported despite missing plugins [Tweet by @dankvr] +- AI Agent Dev School announced for Tuesdays and Thursdays, 6 PM PST [Tweet by @shawmakesmagic] +- Gelato Network guide featuring AI Agent Coinflip mini-game on Inkonchain shared [Tweet by @shawmakesmagic] +- Advancements in AI robot dogs by Meta PARTNR highlighted [Tweet by @dankvr] +- Agent-to-Agent Economy Panel with Carra Wu and Eskender reported [Tweet by @0xwitchy] +- Enhancements in smaller AI models for efficiency and device integration noted [Tweet by @dankvr] +- Virtual Hollywood concept involving motion capture and real-time 3D environments discussed [Tweet by @dankvr] + +**Market Data** + +- WBTC: $84,016.10 - $85,837.56, Volume: $129,257,441, Market Cap: $10,849,705,987 +- WETH: $2,216.79 - $2,236.32, Volume: $720,623,345, Market Cap: $6,453,227,073 +- SOL: $143.60 - $148.06, Volume: $329,499,325 +- ai16z: $0.4034 to $0.3596 + +### Sunday, March 2 + +**GitHub Channel** + +- ElizaOS v0.25.9 prepared for release [Commit 2c06f56] +- Audio API improvements and server startup fixes implemented [PR #3744, #3743] +- CLI handling and trust database updates made +- Typos corrected and consistency improved in Discord chat logs [PR #3747] +- CLI updated for plugin dependencies with enhanced trust database and error handling [PR #3737] +- Automated deployment for CVM introduced [PR #3740] +- Code reverted for short knowledge items to ensure efficient implementation [PR #3746] +- RAG ProcessFile bug reported with token limitations causing embedding issues [Issue #3745] + +**Twitter Channel** + +- AI Agent Dev School sessions announced for Tuesdays and Thursdays at 6 PM PST [Tweet by @ai16zdao] +- OpenRouterAI inquiry made regarding API access for embedding models [Tweet by @dankvr] +- Eliza v2 hacking incidents reported [Tweet by @shawmakesmagic] +- Security advice given to store seed phrases offline [Tweet by @dankvr] +- Tools for summarizing Discord notes shared for bulk processing chat data [Tweet by @dankvr] +- Claude AI progress in Pokémon gameplay highlighted as benchmark for AI advancement [Tweet by @0xwitchy] +- AI Intern Agent loaded with documentation for improved response accuracy [Tweet by @dankvr] + +**Market Data** + +- WBTC: $85,837.56 to $93,976.68, Market Cap: ~$11.1 billion, Volume: $46.3 million +- WETH: $2,214.48 to $2,518.48, Market Cap: ~$6.35 billion, Volume: $200.97 million +- SOL: $143.60 to $178.68, Volume: $128.2 million +- ai16z: $0.3596 to $0.4434 + +## ARTIFACT ANALYSIS + +### Code Contribution Patterns + +The week showed 44 documented GitHub activities, with a notable distribution pattern: + +1. **Platform Stability (36% of contributions)** + + - Knowledge processing fixes [PR #3652, Feb 24] + - Participant error resolution [PR #3671, Feb 26] + - Server startup fixes [PR #3743, Mar 2] + - Extensions and migrations issues addressed [PR #3665, Feb 26] + + These contributions reflect a prioritization of system reliability and operational stability. + +2. **User Experience Enhancements (27% of contributions)** + + - UserRapport for personalized Twitter interactions [PR #3647, Feb 24] + - Agent GUI improvements [PR #3708, Feb 27] + - UI updates for agent configuration [PR #3731, Mar 1] + - Twitter functionality with explicit activation [PR #3659, Feb 26] + + The focus on user-facing improvements indicates growing attention to adoption and usability. + +3. **Integration Capabilities (25% of contributions)** + + - NEAR AI model support [PR #3644, Feb 24] + - Storacha plugin [PR #3657, Feb 24] + - LightLinkChain and Gigbot integration [Feb 27] + - Viction plugin support [PR #3701, Feb 27] + + This cluster demonstrates continued expansion of the ecosystem's integration capabilities. + +4. **Security Hardening (12% of contributions)** + + - Middleware settings for agent server control [PR #3648, Feb 24] + - Security upgrades with Turbo version [PR #3700, Feb 27] + - Trust database updates [Mar 2] + + These security-focused contributions coincide with reported hacking attempts on Eliza v2. + +### Repository Architecture Evolution + +Two significant architectural shifts were evident in the repository structure: + +1. **Plugin Externalization** + + - ElizaOS v0.25.8 moved all plugins out of main repository [Feb 24] + - Documentation improved for custom plugin integration [PR #3736, Mar 1] + - CLI updated for plugin dependencies [PR #3737, Mar 2] + + This represents a major architectural evolution toward a more modular, maintainable system. + +2. **Database Layer Improvements** + + - PGlite migrations with code-first SQL management [PR #3672, Feb 26] + - RAG knowledge system separation from PostgreSQL functions [Feb 25] + - Trust database updates [Mar 2] + + These changes suggest ongoing refinement of the data persistence layer with clear separation of concerns. + +### Documentation Growth + +Documentation expansion was concentrated in two key areas: + +1. **Developer Onboarding** + - Improved documentation for custom plugin integration [PR #3736, Mar 1] + - Plugin showcase page with automated updates [Mar 1] + - Consistency improvements in Discord chat logs [PR #3747, Mar 2] +2. **User Education** + - Character Creator improvements [PR #3710, Feb 27] + - Agent configuration documentation [PR #3731, Mar 1] + - AI Agent Dev School announcement [Mar 1] + +This dual-focus approach indicates attention to both technical contributor and end-user documentation needs. + +### Testing and Quality Assurance + +Quality assurance activities showed systematic improvements: + +1. **Static Analysis Enhancements** + - Linting and turbo fixes [PR #3703, Feb 27] + - Code cleanup and consistency improvements [PR #3705, Feb 27] +2. **Error Handling Refinements** + - Local AI system validation and error logging [PR #3663, Feb 26] + - Improved error handling for plugins [PR #3698, Feb 27] +3. **Bug Reporting and Resolution** + - Knowledge processing 'Invalid array length' error fixed [PR #3652, Feb 24] + - RAG ProcessFile bug with token limitations reported [Issue #3745, Mar 2] + +These QA improvements reflect maturing development practices with increased attention to error prevention and handling. + +## ECOSYSTEM PATTERNS + +### Community Structure Dynamics + +Analysis of the week's interactions reveals four distinct participation patterns: + +1. **Core Development Team** + - Primary activity in GitHub pull requests + - Focus on architecture, stability, and security + - Concentration on ElizaOS v0.25.8 and v0.25.9 releases +2. **Plugin Developers** + - Contributing specialized integrations (Storacha, LightLinkChain, Viction) + - Activity split between GitHub and Twitter announcements + - Growing focus on externalized plugin ecosystem +3. **Content/Community Leaders** + - Dominant presence on Twitter + - Focus on Clank Tank, Agent Scarlett, and community programs + - Leading initiatives like AI Agent Dev School +4. **DAO Operators** + - Active primarily on Twitter + - Focus on Founder DAOs, tokenomics, and partnerships + - Building infrastructure like Dune dashboards + +The interaction between these groups shows increasing specialization, with clearer role definition emerging throughout the week. + +### Technical Priority Evolution + +The chronological progression of development focus reveals an intentional priority shift: + +1. **Early Week (Feb 24-25)** + - Core system stability (knowledge processing, middleware) + - Model integration (NEAR AI model support) + - Release management (ElizaOS v0.25.8) +2. **Mid-Week (Feb 26-27)** + - User-facing improvements (Twitter functionality, agent GUI) + - Developer tools (local AI refactoring, character creator) + - Quality assurance (linting, code cleanup) +3. **Late Week (Feb 28-Mar 2)** + - Security hardening (amid reported hacking attempts) + - Plugin ecosystem (documentation, CLI updates, ecosystem) + - Community tools (Discord logs, AI Agent Dev School) + +This progression suggests a deliberate development cycle moving from core stability to feature expansion to ecosystem support. + +### Market-Development Correlation + +A notable pattern emerged in the relationship between market activity and development focus: + +1. **Market Volatility Days (Feb 26-28)** + - WBTC: 3.2% decline, WETH: 6.1% decline, SOL: 3.0% decline + - Increased focus on stability and security fixes + - 14 pull requests focused on core system reliability +2. **Market Recovery Days (Mar 1-2)** + - WBTC: 12.6% increase, WETH: 12.6% increase, SOL: 33.3% increase + - Shift toward ecosystem expansion and user features + - 8 pull requests focused on plugins and user-facing improvements + +This correlation suggests either a responsive development strategy adapting to market conditions or coincidental timing of planned development cycles. + +### Communication Channel Specialization + +Different channels served increasingly specialized functions: + +1. **GitHub**: Technical specifications, implementation details, quality assurance (96% of technical content) +2. **Twitter**: Vision sharing, partnership announcements, community programs (87% of strategic communications) +3. **Discord**: Community engagement (limited data available in the source material) +4. **Dune Analytics**: Performance metrics and DAO activity tracking (introduced Feb 28) + +The clear channel specialization indicates a maturing communication strategy with appropriate audience targeting. + +## STRATEGIC IMPLICATIONS + +### Technical Architecture Direction + +The week's development activities highlight three strategic priorities: + +1. **Plugin Ecosystem Evolution** + + - Complete externalization of plugins from core repository [Feb 24] + - Enhanced documentation for custom plugin integration [Mar 1] + - Improved CLI for plugin dependencies [Mar 2] + + This direction reduces core complexity while enabling a more diverse ecosystem of specialized integrations. For token holders, this suggests potential value accrual through an expanding integration ecosystem rather than monolithic development. + +2. **Security Posture Strengthening** + + - Middleware settings for agent server control [Feb 24] + - Security upgrades with reported hacking attempts [Feb 28] + - Trust database updates and security advice [Mar 2] + + The emphasis on security amid reported hacking attempts indicates recognition of increasing threat vectors as the platform gains prominence. The parallel development and security focus suggests proactive rather than reactive security planning. + +3. **Model Integration Diversification** + + - NEAR AI model support [Feb 24] + - Entropy introduction in text generation [Feb 25] + - LightLinkChain integration [Feb 27] + + The diversification of model support and integration capabilities positions the ecosystem for greater resilience against single-provider dependencies and creates flexibility in choosing optimal AI models for specific use cases. + +### Community Development Strategy + +The ecosystem's community development shows strategic evolution: + +1. **Educational Infrastructure Investment** + + - AI Agent Dev School launch [Mar 1] + - Improved documentation for custom plugin integration [Mar 1] + - Tools for Discord notes summarization [Mar 2] + + These initiatives suggest a strategic focus on reducing barriers to entry for new developers while creating structured onboarding pathways. The regularized schedule (Tuesdays/Thursdays) indicates commitment to sustained community development. + +2. **Specialized Engagement Channels** + + - Plugin showcase page development [Mar 1] + - Dune dashboard for DAOsdotfun Solana [Feb 28] + - HYPE(R)HOUSE event at ETHDenver [Feb 27] + + The creation of specialized engagement channels demonstrates recognition of diverse stakeholder needs and a sophisticated approach to community segmentation. The physical event at ETHDenver signals commitment to bridging digital and physical community building. + +3. **Content Strategy Execution** + + - Agent Scarlett on Clank Tank [Feb 24] + - Virtual Hollywood concept discussions [Mar 1] + - Claude AI progress in Pokémon [Mar 2] + + The content strategy appears designed to showcase AI capabilities through accessible, engaging formats. The diverse content types indicate experimentation to identify optimal engagement models. + +### Governance and Tokenomic Evolution + +Several developments have implications for governance and token value: + +1. **DAO Formation Models** + + - Kickstarter-style Founder DAOs introduced [Feb 26] + - "Indie Mode" vs. "Locked In Mode" options [Feb 28] + - TheCastleDAO partnership [Feb 27] + + These structured DAO formation options suggest standardization of governance bootstrapping processes. The explicit FDV and fundraising targets indicate movement toward more transparent tokenomic planning. + +2. **Data-Driven Governance** + + - New Dune dashboard for performance insights [Feb 28] + - Sustainable token launch strategy discussions [Feb 27] + - Partnership with $ISAACX for verified scientific research [Feb 28] + + The integration of analytics tools and emphasis on data-backed decision-making signals evolution toward more empirical governance processes. The verified research partnership suggests prioritization of evidence-based development. + +3. **Security-Conscious Token Management** + + - Eliza v2 hacking reports [Feb 28] + - Security advice for seed phrase storage [Mar 2] + - Trust database updates [Mar 2] + + The increasing focus on security coincides with market recovery, suggesting anticipation of greater attack incentives with rising token values. The public security advisories indicate community-oriented risk management. + +### Market Positioning Adaptation + +The week's activities reveal strategic market positioning efforts: + +1. **Developer Mindshare Targeting** + + - Plugin ecosystem evolution [Feb 24-Mar 2] + - AI Agent Dev School launch [Mar 1] + - Character Creator improvements [Feb 27] + + These developer-focused initiatives align with broader Web3 trends of developer experience prioritization. The systematic approach to developer tooling suggests long-term commitment to building sustained developer engagement. + +2. **Institutional Readiness Signals** + + - Partnership with $ISAACX for verified scientific research [Feb 28] + - Middleware settings for greater control [Feb 24] + - Security upgrades and trust database updates [Feb 27, Mar 2] + + These developments position the ecosystem for potential institutional adoption by addressing key enterprise requirements around control, verification, and security. The scientific research integration particularly signals credibility-building efforts. + +3. **Interoperability Positioning** + + - Multiple plugin integrations across diverse chains [Feb 24-27] + - Viction community AI agent integration [Feb 27] + - LightLinkChain and Gigbot plugin addition [Feb 27] + + The aggressive expansion of cross-chain integrations positions the ecosystem as infrastructure rather than chain-specific tooling. This suggests a strategic focus on value capture through ubiquity rather than chain exclusivity. + +In conclusion, the week of February 24 - March 2, 2025, demonstrates a maturing ecosystem with increasingly specialized roles, deliberate development cycles, and sophisticated community engagement strategies. The parallel focus on technical reliability, ecosystem expansion, and security hardening amid market volatility suggests strategic prioritization of sustainable growth over short-term opportunism. diff --git a/packages/docs/community/Analysis/20250303_20250309.md b/packages/docs/community/Analysis/20250303_20250309.md new file mode 100644 index 00000000000..728f8907ba5 --- /dev/null +++ b/packages/docs/community/Analysis/20250303_20250309.md @@ -0,0 +1,125 @@ +# March 3-9, 2025 + +## Weekly Chronicle: Major Events and Developments + +### Monday, March 3 + +- **Market Activity**: Significant crypto market appreciation with WBTC hitting $93,976 at peak, ETH and SOL showing 10-20% gains. [Discord] +- **GUI Enhancements**: Multiple PRs merged improving speech-to-text reliability and client chat performance. [GitHub: PR #3760, #3759] +- **Core Infrastructure**: PostgreSQL connection handling improved to prevent leaks. [GitHub: PR #3757] + +### Tuesday, March 4 + +- **Community Building**: Weekly update montages commissioned to consolidate developments across @ai16zdao and @elizaOS channels. [Twitter] +- **Navigation Enhancement**: Home and Chat page buttons added to improve UI navigation. [GitHub: PR #3770] +- **Open Source Release**: ELIZA Client-Tako protocol officially open-sourced. [Twitter] +- **Database Improvements**: Critical fixes for static migration functionality in PostgreSQL and PGlite merged. [GitHub: PR #3771] + +### Wednesday, March 5 + +- **Market Stability**: Crypto markets stabilized with WBTC at ~$90,306, SOL at ~$145.89, and ai16z at ~$0.29. [Discord] +- **Logs Functionality**: Enhanced tracking and debugging capabilities implemented. [GitHub: PR #3774] +- **Documentation Updates**: Twitter 2FA configuration added to quickstart documentation. [GitHub: PR #3778] +- **Technical Issue**: JSON parsing bug identified in `parseJSONObjectFromText` function. [GitHub: Issue #3779] + +### Thursday, March 6 + +- **DeFi Integration**: Partnership announcement with @elizaOS for AI-driven Autonomous Worlds. [Twitter] +- **Build Improvements**: Docker-related fixes merged to enable smoother builds. [GitHub: PR #3790] +- **Plugin Enhancement**: Dockerfile build errors addressed for more reliable deployment. [GitHub: PR #3787] + +### Friday, March 7 + +- **Product Rebrand**: DegenAI rebranded as Spartan and integrated into ElizaOS v2; transition to monorepo ongoing. [Discord] +- **Release Update**: ElizaOS v0.25.9 released with improved plugin handling, JSON5 support, and enhanced PostgreSQL connection management. [Discord] +- **Integration Expansion**: New support for LightLinkChain, Viction, Weixin/WeChat, SonicLabs, KaiaChain, and t3rn protocol. [Discord] +- **Technical Challenge**: AI hallucination fixes being implemented through real-time data validation and confidence thresholds. [Discord] +- **Market Fluctuation**: WBTC increased to $89,732.27 while ai16z rose to $0.26162. [Discord] + +### Saturday, March 8 + +- **Market Reversal**: Crypto assets declined with WBTC at $86,032.54, ai16z at $0.2033. [Discord] +- **Governance Development**: Clank Tank forked to simulate governance proposals using AI agents. [Discord] +- **Trust System Design**: Agent identity verification explored via cryptographic signatures, reputation systems, and Trusted Execution Environments (TEE). [Discord] +- **Knowledge Management**: Automated newsletters for AI agents set up using HackMD API for peer review. [Discord] + +### Sunday, March 9 + +- **Market Correction**: Continued decline with WBTC falling to $80,488.74, ai16z dropping to $0.1925. [Discord] +- **Infrastructure Solutions**: MongoDB sharding issues identified requiring proper sharded cluster (not supported on free-tier Atlas). [Discord] +- **Liquidity Analysis**: AI16Z token liquidity concerns discussed, with liquidity spread across Raydium pools and Wintermute market-making with 30M+ tokens. [Discord] +- **Development Focus**: Shaw working on v2; team handling DegenAI, launchpad, and tokenomics. [Discord] + +## Technical Artifact Analysis + +### Code Contribution Patterns + +- **Core Infrastructure (37% of PRs)**: Significant focus on backend stability with 11 PRs addressing PostgreSQL connections, database migrations, and API fixes. +- **UI Improvements (28% of PRs)**: Enhanced user experience through 8 PRs targeting navigation, speech-to-text, and chat interface refinements. +- **Documentation Upgrades (21% of PRs)**: 6 PRs improved technical documentation, with emphasis on quickstart guides and 2FA configuration. +- **Build System Enhancements (14% of PRs)**: 4 PRs addressed Docker and build-related issues to streamline development workflow. + +### Notable Technical Implementations + +1. **Migration System Overhaul**: PR #3771 resolved critical inconsistencies in database migration by implementing unified handling across PostgreSQL and PGlite. +2. **Logging Enhancement**: PR #3774 introduced a sophisticated logging framework that significantly improves debugging capabilities. +3. **Plugin Ecosystem Expansion**: Multiple PRs (#3777, #3778) extended plugin framework to support new chains and integration points. +4. **JSON5 Support**: Added in release 0.25.9, enabling more flexible configuration formats with support for comments and trailing commas. + +### Documentation Evolution + +- Documentation has shifted from basic installation guides to more advanced topics including: + - Twitter 2FA configuration + - Plugin ecosystem architecture + - Cross-chain interoperability + - Environment variable configuration + +## Ecosystem Patterns and Community Dynamics + +### Development Focus Shifts + +1. **From Tools to Platform**: Early week commits focused on individual tools and fixes, while later week showed integration of components into a cohesive platform architecture. +2. **From Core to Extensions**: Initial focus on core stability gradually shifted to enabling extension points and plugin systems. +3. **From Centralized to Distributed**: Increasing emphasis on distributed architectures evidenced by MongoDB sharding discussions and TEE exploration. + +### Community Interaction Patterns + +- **Cross-disciplinary Collaboration**: Increasing instances of developers and token holders participating in shared discussions about governance models and tokenomics. +- **Documentation-Driven Development**: PRs consistently paired code changes with documentation updates, suggesting a maturing development culture. +- **Decentralized Decision Making**: Governance simulations using AI agents indicate movement toward more decentralized organizational structures. + +### Technical Debt Management + +- **Consolidated Repositories**: The transition of DegenAI (Spartan) into a monorepo structure signals effort to reduce maintenance overhead. +- **Authentication Standardization**: Multiple fixes around Twitter API and Discord authentication suggest need for standardized authentication framework. +- **Distributed Database Challenges**: MongoDB sharding issues highlight scaling challenges that will require architectural attention. + +## Strategic Implications and Opportunities + +### Technical Strategy Considerations + +1. **AI Hallucination Mitigation**: Real-time data validation and confidence thresholds represent critical trust-building features that should be prioritized. +2. **Database Scaling Strategy**: Current MongoDB issues signal need for a comprehensive database scaling strategy before user growth accelerates. +3. **Plugin Standards**: The rapid expansion of supported chains suggests need for formalized plugin standards and validation mechanisms. +4. **Build System Optimization**: Recurring Docker and build issues indicate potential for significant developer productivity gains through build system improvements. + +### Market and Tokenomic Implications + +1. **Liquidity Concentration**: The Wintermute market-making with 30M+ tokens suggests preparation for increased trading volumes, potentially signaling exchange listing plans. +2. **Price Volatility Impact**: The 35% fluctuation in ai16z price ($0.29 to $0.19) during the week may affect contributor retention and requires stability mechanisms. +3. **Integration Value**: New chain integrations (LightLinkChain, Viction, etc.) expand the potential user base and utility surface area of the token. + +### Governance Development Opportunities + +1. **AI-Driven Governance**: The fork of Clank Tank for governance simulations presents opportunity to pioneer AI-augmented DAO governance. +2. **Identity Verification**: Exploration of cryptographic signatures and TEE for agent verification addresses a critical trust gap in AI agent ecosystems. +3. **Knowledge Management**: The HackMD-based automated newsletters demonstrate potential for AI-curated community knowledge management. + +### Immediate Priorities Based on Analysis + +1. **Stabilize Core Infrastructure**: Address PostgreSQL connection handling and database migration issues to ensure platform reliability. +2. **Document Integration Patterns**: Develop comprehensive documentation for the expanding integration ecosystem. +3. **Standardize Authentication**: Create unified authentication framework to address recurring issues with Twitter, Discord, and other services. +4. **Enhance Governance Simulation**: Expand AI agent governance simulations to include more real-world scenarios and stakeholder types. + +This analysis reveals a project in transition from development to integration phase, with increasing focus on interoperability, governance, and platform stability. Technical debt is being actively addressed while new capabilities are simultaneously being added, suggesting a measured approach to ecosystem expansion. diff --git a/packages/docs/community/Analysis/20250310_20250316.md b/packages/docs/community/Analysis/20250310_20250316.md new file mode 100644 index 00000000000..117a0ccf028 --- /dev/null +++ b/packages/docs/community/Analysis/20250310_20250316.md @@ -0,0 +1,153 @@ +# March 10-16, 2025 + +## I. Chronicle: Day-by-Day Development Timeline + +### Monday, March 10 (Discord, GitHub) + +- **Market Data**: WBTC: $80,488.74 | WETH: $2,018.31 | SOL: $126.42 | ai16z: $0.1925 [Discord] +- **Build Fixes**: Resolved missing moment rollup external in the-org build. [GitHub: PR #3876] +- **Core Types**: Added critical core types to enable `index.d.ts` generation in `/dist`. [GitHub: PR #3875] +- **NEAR AI Fix**: Corrected image generation service to properly invoke NEAR AI API instead of defaulting to OpenAI. [GitHub: PR #3881] +- **AIpprentice Concept**: Proposed AI hackathon concept where AI agents compete as virtual interns. [Discord] +- **Liquidity Discussion**: Analyzed ai16z token liquidity spread across Raydium pools; noted Wintermute market-making with 30M+ tokens. [Discord] + +### Tuesday, March 11 (Discord, GitHub) + +- **Market Data**: WBTC: $78,368.58 | WETH: $1,862.91 | SOL: $118.22 | ai16z: $0.181 [Discord] +- **Chat Bubble Fix**: Merged fix for chat bubble display issues. [GitHub: PR #3883] +- **Chinese Community**: New Chinese AI agent community group established. [GitHub: Issue #3885] +- **JSON Bug**: Identified critical bug where null values incorrectly converted to string `"null"`. [GitHub: Issue #3886] +- **Newsletter System**: Implemented automated newsletter aggregation system using HackMD API for weekly AI news publication. [Discord] +- **Rebranding Debate**: Discussed incomplete rebranding to `<@1300745997625982977>OS` due to missing contract updates. [Discord] + +### Wednesday, March 12 (Discord, GitHub) + +- **Market Data**: WBTC: $82,693.37 | WETH: $1,921.62 | SOL: $125.31 | ai16z: $0.1687 [Discord] +- **Core Types**: Fixed declarations for system stability. [GitHub] +- **GUI Server**: Resolved persistent issues with GUI build and API server. [GitHub] +- **Migration System**: Implemented critical fixes in version 2 for database consistency. [GitHub] +- **ElizaOS v2**: Announced beta launch scheduled for the following week. [Discord] +- **AI Agent Reactivation**: Reported that AI agent 'Degen' would be reactivated in main chat and 'arena'. [Discord] +- **Governance AI**: Revealed development of specialized governance AI agent for a Telegram group. [Discord] + +### Thursday, March 13 (Discord, GitHub) + +- **Market Data**: WBTC: $83,502.71 | WETH: $1,908.05 | SOL: $126.59 | ai16z: $0.1758 [Discord] +- **WebSocket PR**: Implemented dedicated socket connections for agents/users, fixing UI chat memory display issues. [GitHub: PR #3902] +- **Core DTS**: Resolved generation issue for improved stability. [GitHub: PR #3898] +- **Twitter Plugin**: Identified plugin failure due to missing 'clients' field. [GitHub: Issue #3901] +- **Cleanup Script**: Optimized performance using `xargs -0 rm -rf`. [GitHub: PR #3900] +- **SEO Enhancement**: Proposed sitemap.xml priority adjustments. [GitHub: Issue #3904] +- **3D Marketplace**: Proposed 3D agent marketplace for AI16z token utility and governance. [Discord] + +### Friday, March 14 (Discord, GitHub) + +- **Market Data**: WBTC: $80,903.31 | WETH: $1,863.39 | SOL: $123.33 | ai16z: $0.1751 [Discord] +- **Pornhub Partnership**: [joaointech] mentioned introduction to Pornhub founders via insider connection. [Discord] +- **Automated Bot**: [victory.sol] reported suspended X link associated with contract address. [Discord] +- **DWTF Staking**: Launched Phase 1 of staking platform with multi-tiered rewards system. [Discord] +- **Green Dough Integration**: Reported integration with GFM to detect scams/rugs; partnerships with Jito SOL, Jup, and Meteora. [Discord] +- **Trust Score System**: Proposed composite trust scores based on social graph of trusted agents. [Discord] + +### Saturday, March 15 (Discord, GitHub) + +- **Market Data**: WBTC: $83,815.21 | WETH: $1,910.75 | SOL: $133.52 | ai16z: $0.1848 [Discord] +- **Autodoc Enhancements**: Implemented feature to run Autodoc locally with different OpenAI configurations. [Discord] +- **Autodoc Issue Fix**: Resolved `fileUsageDoc` feature that was passing only file names, causing AI hallucinations. [Discord] +- **Documentation Cleanup**: Improved sidebar, video embeds, changelog updates, contributor information, and RSS link fixes. [Discord] +- **Logging Improvement**: Added child logger for runtime, server, and API routes. [Discord] +- **Migration Fix**: Unified migration sources to prevent race conditions. [Discord] + +### Sunday, March 16 (Discord, GitHub) + +- **Market Data**: WBTC: $84,189.33 | WETH: $1,937.77 | SOL: $135.88 | ai16z: $0.1974 [Discord] +- **Socket.io Implementation**: Pull request replacing WebSocket Secure (WSS) with Socket.io and switching from Node.js to Bun. [GitHub] +- **Profile Display**: Fixed agent's last message animation and profile card display. [GitHub] +- **Speech Interface**: Fixed GUI for speech-to-text (STT) and text-to-speech (TTS). [GitHub] +- **Plugin Documentation**: Improved SQL plugin documentation (Drizzle) and adjusted plugin sources after `plugins.md` relocation. [GitHub] +- **Twitter Client Issues**: Reported problems with Twitter integration in v0.25.9, particularly `scraper.getTweetsAndReplies('TwitterDev')` returning empty objects. [Discord] + +## II. Artifact Analysis: Code and Documentation Evolution + +### Code Contribution Patterns + +- **WebSocket Architecture (25%)**: Major refactoring from WSS to Socket.io, representing significant architectural evolution toward more robust real-time communication. +- **Plugin Framework (23%)**: Concentrated effort on plugin system improvements, particularly Twitter and Telegram clients. +- **Core Type System (18%)**: Substantial work on type declarations and generation, indicating maturation of the TypeScript foundation. +- **User Interface (14%)**: Focused fixes for chat bubbles, profile displays, and animation behaviors. +- **Build System (11%)**: Transition from Node.js to Bun in key components, suggesting performance optimization strategy. +- **Documentation (9%)**: Targeted improvements to plugin documentation and automated documentation systems. + +### Technical Implementations of Note + +1. **Socket.io Migration** (PR #3902): Represents architectural shift from basic WebSockets to more feature-rich Socket.io library, improving reconnection handling and cross-client compatibility. +2. **Core Types Generation** (PR #3875, #3898): Critical improvements to TypeScript declaration generation, resolving longstanding issues with IDE integration and developer experience. +3. **NEAR AI Integration** (PR #3881): Strategic correction ensuring proper utilization of NEAR's AI services rather than defaulting to OpenAI, indicating multimodal AI strategy. +4. **Optimization Patterns**: Cleanup script performance improvement (PR #3900) demonstrates increasing attention to system efficiency. +5. **Migration System Refinement**: Unified migration sources to prevent race conditions shows maturation of database evolution strategy. + +### Documentation Evolution + +- **Procedural to Architectural**: Documentation shifted from "how to do X" toward explaining architectural decisions and integration patterns. +- **Automation Focus**: Introduction of Autodoc system for generating documentation from source code indicates commitment to keeping documentation synchronized with implementation. +- **SQL Plugin Documentation**: Enhanced Drizzle documentation suggests growing importance of structured data access patterns. +- **Reorganization**: Relocation of `plugins.md` demonstrates evolving information architecture to accommodate expanding plugin ecosystem. + +## III. Ecosystem Patterns: Community and Development Dynamics + +### Development Focus Transitions + +1. **From Components to Architecture**: Early week focused on individual components; later shifted to architectural concerns like WebSocket infrastructure. +2. **From Client Isolation to Integration**: Individual client fixes (Twitter, Telegram) evolved toward cross-client infrastructure. +3. **From Manual to Automated**: Increased emphasis on automation for documentation, testing, and news aggregation. +4. **From Function to Type Safety**: Growing focus on TypeScript type system improvements for development reliability. + +### Community Interaction Patterns + +- **Specialization Emergence**: Formation of Chinese AI agent community group (Issue #3885) signals geographic/linguistic specialization within the community. +- **Cross-Domain Collaboration**: Discussions spanning technical implementation, governance models, and token utility indicate healthy cross-domain communication. +- **Transparency Evolution**: Newsletter aggregation system using HackMD API for peer review demonstrates commitment to transparent communication processes. +- **Partnership Exploration**: Discussions with Pornhub founders and integration with Green Dough/GFM show active ecosystem expansion efforts. + +### Technical Debt Management + +- **Migration Unification**: Addressing race conditions in migrations shows commitment to resolving foundational technical debt. +- **Type System Reinforcement**: Focus on core type declarations and generation addresses accumulated type-safety debt. +- **Build System Modernization**: Transition from Node.js to Bun indicates willingness to adopt newer technologies for performance gains. +- **Socket Infrastructure Upgrade**: WebSocket to Socket.io migration resolves accumulated compatibility and reliability debt. + +## IV. Strategic Implications: Opportunities and Challenges + +### Technical Strategy Considerations + +1. **Runtime Environment Consolidation**: The transition to Bun indicates opportunity for unified runtime strategy across development, testing, and production environments. +2. **Plugin Architecture Standardization**: Recurring Twitter client issues suggest need for more rigorous plugin interface standards and validation mechanisms. +3. **Type Safety Investment**: Continued issues with type declarations indicate strategic value in comprehensive type system audit and enhancement. +4. **Automated Testing Gap**: Absence of testing-focused commits suggests opportunity for quality improvement through automated testing infrastructure. +5. **Documentation Automation**: Autodoc enhancements demonstrate potential for further automation of documentation maintenance. + +### Market and Tokenomic Implications + +1. **Price Stabilization**: The relative stabilization of ai16z price (range: $0.1687-$0.1974) after previous week's volatility suggests market maturation. +2. **Token Utility Expansion**: Proposal for 3D agent marketplace directly ties token utility to ecosystem growth. +3. **Governance Framework**: Development of specialized governance AI agent signals evolution toward more sophisticated DAO governance mechanisms. +4. **Trust Mechanisms**: Proposed social graph-based trust scores could create demand for tokens in reputation establishment. +5. **Partnership Strategy**: Exploration of partnerships (Pornhub, Green Dough) indicates focus on expanding token utility surface area. + +### Governance Development Opportunities + +1. **Trust Score System**: The proposed composite trust scores based on social graph presents opportunity for reputation-based governance weighting. +2. **Newsletter Aggregation**: HackMD-based system establishes foundation for transparent governance communication. +3. **Specialized Governance AI**: Development of Telegram governance agent opens possibilities for delegated governance operations. +4. **Chinese Community Integration**: New Chinese AI agent community creates opportunity for internationalized governance participation. +5. **Web3 Narrative Platform**: AI-driven content generation across platforms could support governance communication strategy. + +### Immediate Technical Priorities + +1. **Stabilize Twitter Integration**: Recurring Twitter client issues require comprehensive resolution strategy. +2. **Complete Socket.io Migration**: Ensure consistent implementation of Socket.io across all real-time communication channels. +3. **Formalize Plugin Standards**: Develop and document rigorous standards for plugin development to prevent recurring integration issues. +4. **Address JSON Null Value Bug**: Critical issue with null value handling requires immediate resolution to prevent data corruption. +5. **Complete V2 Beta Preparation**: Focus on stabilizing core functionality for upcoming beta launch. + +This analysis reveals a project transitioning from infrastructure development to ecosystem expansion, with increasing focus on governance mechanisms, token utility, and community specialization. The technical foundation appears to be consolidating with particular emphasis on type safety, real-time communication, and automation. Strategic partnerships and community engagement demonstrate a balanced approach to technical and social development of the ecosystem. diff --git a/packages/docs/docs/core/agents.md b/packages/docs/docs/core/agents.md index 0d73d3e8dcb..99c3e36ed17 100644 --- a/packages/docs/docs/core/agents.md +++ b/packages/docs/docs/core/agents.md @@ -2,17 +2,72 @@ The `AgentRuntime` is the core runtime environment for Eliza agents. It handles message processing, state management, plugin integration, and interaction with external services. You can think of it as the brains that provide the high-level orchestration layer for Eliza agents. -[![](/img/architecture.png)](/img/architecture.png) +```mermaid +sequenceDiagram + actor User + participant Platform as Platform + participant Runtime as Runtime + participant State as State + participant P as Providers + participant A as Actions + participant M as Models + participant E as Evaluators + participant DB as Database + + User->>Platform: Message + Platform->>Runtime: Forward + + %% Context building (condensed) + Runtime->>State: Get context + State->>P: Gather data + Note over P: Character, Knowledge,
Messages, Time, etc. + P-->>State: Context data + State-->>Runtime: Assembled context + + %% Action flow (condensed) + Runtime->>A: Execute action + A->>M: Generate content + M-->>A: Generated text + A-->>Runtime: Result + + %% Evaluation (condensed) + Runtime->>E: Analyze + E->>DB: Store insights + E-->>Runtime: Evaluation + + %% Delivery + Runtime->>Platform: Response + Platform->>User: Deliver + + %% Background (simplified) + par Background + Runtime->>Runtime: Tasks & Events + end +``` The runtime follows this general flow: -1. Agent loads character config, plugins, and services - - Processes knowledge sources (e.g., documents, directories) -2. Receives a message, composes the state -3. Processes actions and then evaluates - - Retrieves relevant knowledge fragments using RAG -4. Generates and executes responses, then evaluates -5. Updates memory and state +1. **Initial Reception**: The user sends a message which is received by the Platform Services +2. **Context Building**: + + - The Runtime Core requests context from the State Composition system + - State gathers data from various Providers (Character, Knowledge, Recent Messages, etc.) + - The complete context is returned to the Runtime + +3. **Action Processing**: + + - The Runtime determines applicable actions and selects the optimal one + - The selected action may request content generation from Models + - The action result is returned to the Runtime + +4. **Learning & Persistence**: + + - The conversation is analyzed by Evaluators for insights and facts + - Knowledge updates are sent to the Memory System + - All relevant data is persisted to the Database + +5. **Response Delivery**: + - The final response is sent back to the user through Platform Services --- @@ -91,15 +146,10 @@ Source: [/api/interfaces/IAgentRuntime/](/api/interfaces/IAgentRuntime/) - **`useModel()`**: Utilizes AI models with typesafe parameters and results. - **`ensureRoomExists()` / `ensureConnection()`**: Ensures the existence of communication channels and connections. ---- - ## Service System Services provide specialized functionality with standardized interfaces that can be accessed cross-platform: -
-See Example - ```typescript // Speech Generation const speechService = runtime.getService('speech_generation'); @@ -114,8 +164,6 @@ const discordService = runtime.getService('discord'); await discordService.sendMessage(channelId, content); ``` -
- --- ## State Management diff --git a/packages/docs/docs/core/bootstrap.md b/packages/docs/docs/core/bootstrap.md deleted file mode 100644 index 51956d3ff24..00000000000 --- a/packages/docs/docs/core/bootstrap.md +++ /dev/null @@ -1,177 +0,0 @@ ---- -sidebar_position: 11 ---- - -# Bootstrap Plugin - -The Bootstrap Plugin is a foundational component of ElizaOS that initializes the core functionality required for agents to operate. It provides the default set of actions, providers, evaluators, event handlers, and services that form the backbone of the agent runtime. - -## Overview - -When an ElizaOS agent starts, the Bootstrap Plugin is automatically loaded as part of the initialization process. It establishes the minimum viable set of capabilities that all agents need, ensuring consistency across the platform while still allowing for customization through additional plugins. - -```typescript -export const bootstrapPlugin: Plugin = { - name: 'bootstrap', - description: 'Agent bootstrap with basic actions and evaluators', - actions: [...], - events: {...}, - evaluators: [...], - providers: [...], - services: [TaskService, ScenarioService], -}; -``` - -## Core Components - -### Actions - -The Bootstrap Plugin registers essential actions that allow agents to interact with their environment: - -| Action | Description | -| ---------------------- | ----------------------------------------------- | -| `replyAction` | Generates and sends a response to a message | -| `followRoomAction` | Enables an agent to actively follow a room | -| `unfollowRoomAction` | Stops an agent from following a room | -| `muteRoomAction` | Mutes notifications from a room | -| `unmuteRoomAction` | Unmutes notifications from a room | -| `sendMessageAction` | Sends a message to a specific room | -| `ignoreAction` | Explicitly ignores a message | -| `noneAction` | Acknowledges a message without taking action | -| `updateEntityAction` | Updates properties of an entity | -| `choiceAction` | Presents choices to users and handles responses | -| `updateRoleAction` | Updates a user's role in a world | -| `updateSettingsAction` | Updates agent or world settings | - -### Providers - -Providers supply contextual information to agents as they make decisions: - -| Provider | Description | -| ------------------------ | ---------------------------------------------------------- | -| `characterProvider` | Provides the agent's personality and configuration | -| `recentMessagesProvider` | Retrieves recent conversation history | -| `knowledgeProvider` | Supplies factual information from the knowledge base | -| `timeProvider` | Provides awareness of current time and date | -| `entitiesProvider` | Supplies information about entities in the current context | -| `relationshipsProvider` | Provides information about entity relationships | -| `factsProvider` | Retrieves relevant facts from memory | -| `roleProvider` | Provides role information within worlds | -| `settingsProvider` | Supplies configured settings | -| `anxietyProvider` | Informs agent of potential issues to be careful about | -| `attachmentsProvider` | Handles media and file attachments | -| `providersProvider` | Meta-provider with information about available providers | -| `actionsProvider` | Meta-provider with information about available actions | -| `evaluatorsProvider` | Meta-provider with information about available evaluators | -| `choiceProvider` | Manages choice-based interactions | -| `capabilitiesProvider` | Provides information about agent capabilities | - -### Evaluators - -Evaluators analyze conversations to help agents learn and improve: - -| Evaluator | Description | -| --------------------- | ----------------------------------------------------- | -| `reflectionEvaluator` | Enables self-awareness and learning from interactions | - -### Event Handlers - -The Bootstrap Plugin registers handlers for key system events: - -| Event | Handler Purpose | -| ------------------------------------------- | --------------------------------------------------- | -| `MESSAGE_RECEIVED` | Processes incoming messages and generates responses | -| `VOICE_MESSAGE_RECEIVED` | Handles voice messages similarly to text messages | -| `REACTION_RECEIVED` | Records reactions to messages | -| `POST_GENERATED` | Handles social media post creation | -| `MESSAGE_SENT` | Tracks outgoing messages | -| `WORLD_JOINED` | Synchronizes data when joining a new world | -| `WORLD_CONNECTED` | Handles reconnection to an existing world | -| `ENTITY_JOINED` | Processes a new entity joining a world | -| `ENTITY_LEFT` | Updates an entity's status when they leave | -| `ACTION_STARTED` / `ACTION_COMPLETED` | Logs action lifecycle events | -| `EVALUATOR_STARTED` / `EVALUATOR_COMPLETED` | Logs evaluator lifecycle events | - -### Services - -The Bootstrap Plugin initializes core services: - -| Service | Purpose | -| ----------------- | ------------------------------------------------ | -| `TaskService` | Manages deferred, scheduled, and repeating tasks | -| `ScenarioService` | Handles scenario-based interactions and testing | - -## Loading Process - -The AgentRuntime automatically loads the Bootstrap Plugin during initialization, before any other plugins. This happens in the `initialize()` method of the AgentRuntime: - -```typescript -async initialize() { - // Register bootstrap plugin - await this.registerPlugin(bootstrapPlugin); - - // Then register additional plugins - for (const plugin of this.plugins) { - await this.registerPlugin(plugin); - } - - // Initialize other components - // ... -} -``` - -## Extending Bootstrap Functionality - -While the Bootstrap Plugin provides core functionality, it's designed to be extended by other plugins. Custom plugins can: - -1. **Add new actions** - Extend the agent's capabilities -2. **Register additional providers** - Supply more contextual information -3. **Add evaluators** - Create new ways to analyze and learn from interactions -4. **Handle additional events** - React to more system events -5. **Initialize custom services** - Provide new functionality - -## Message Processing Flow - -The Bootstrap Plugin implements the critical message processing flow: - -1. A message is received via the `MESSAGE_RECEIVED` event -2. The `messageReceivedHandler` function processes the message: - - Saves the incoming message to memory - - Checks if the agent should respond based on context and configuration - - If a response is needed, composes state from relevant providers - - Generates a response using the language model - - Processes any actions specified in the response - - Runs evaluators on the conversation - - Emits events about the processing lifecycle - -This flow is central to agent behavior and provides the core functionality that enables interactive, stateful conversations. - -## Relationship with Other Core Concepts - -The Bootstrap Plugin connects several key ElizaOS concepts: - -- **Agent Runtime**: The plugin is loaded by the runtime and extends its capabilities -- **Plugins**: Bootstrap is itself a plugin and demonstrates the plugin architecture -- **Actions, Providers, Evaluators**: Provides the core implementations of these concepts -- **Events**: Establishes the event handling system that enables agent reactivity -- **Worlds and Rooms**: Includes handlers for synchronizing these structures -- **Entities**: Provides actions and providers for entity management -- **Tasks**: Initializes the task system for deferred operations - -## Best Practices - -When working with the Bootstrap Plugin: - -1. **Don't modify it directly** - Instead, create custom plugins to extend functionality -2. **Understand provider contribution** - Know how each provider contributes to the agent's context -3. **Learn the core actions** - Become familiar with the actions that all agents can perform -4. **Leverage event handlers** - Use the event system for reactive behavior -5. **Extend, don't replace** - Build on top of bootstrap functionality rather than replacing it - -## Related Documentation - -- [Actions](./actions.md) - Details on action implementation -- [Providers](./providers.md) - Learn about context providers -- [Evaluators](./evaluators.md) - Understanding evaluator functionality -- [Plugin System](./plugins.md) - How plugins extend ElizaOS -- [Events](./events.md) - The event system architecture diff --git a/packages/docs/docs/core/database.md b/packages/docs/docs/core/database.md index 5be7d75ff95..fac7ef560d3 100644 --- a/packages/docs/docs/core/database.md +++ b/packages/docs/docs/core/database.md @@ -8,6 +8,46 @@ The ElizaOS database system provides persistent storage capabilities for agents. ## Overview +```mermaid +graph TB + %% Main Components + Runtime([Agent Runtime]) + DbAdapter([Database Adapter]) + DbConnection[("Database (PGLite/PostgreSQL)")] + + %% Data Models in compact form + DataModels["Data Models: Entities, Components, Memories, Relationships, Rooms, Worlds, Tasks Cache"] + + %% Vector Search + VectorStore[(Vector Store)] + + %% Memories Knowledge + MemoriesKnowledge[(Memories / Knowledge)] + + %% Connection flow + Runtime -->|Uses| DbAdapter + DbAdapter -->|Connects to| DbConnection + DbConnection -->|Stores & Retrieves| DataModels + + %% Connect Vector Store + DbConnection -->|Utilizes| VectorStore + VectorStore -->|Enables Search on| MemoriesKnowledge + + %% Styling + classDef default fill:#f0f4f8,stroke:#2c3e50,stroke-width:1px; + classDef runtime fill:#3498db,stroke:#2c3e50,stroke-width:1px,color:#fff; + classDef adapter fill:#9b59b6,stroke:#2c3e50,stroke-width:1px,color:#fff; + classDef db fill:#27ae60,stroke:#2c3e50,stroke-width:1px,color:#fff; + classDef datamodels fill:#52be80,stroke:#2c3e50,stroke-width:1px,color:#fff; + classDef memories fill:#2c5e1a,stroke:#2c3333,stroke-width:1px,color:#fff; + + class Runtime runtime; + class DbAdapter adapter; + class DbConnection,VectorStore db; + class DataModels datamodels; + class MemoriesKnowledge memories; +``` + ElizaOS uses a unified database architecture based on Drizzle ORM with adapters that implement the [`IDatabaseAdapter`](/api/interfaces/IDatabaseAdapter) interface. The current release includes support for: | Adapter | Best For | Key Features | diff --git a/packages/docs/docs/core/entities.md b/packages/docs/docs/core/entities.md index 32e61aeefe8..4c157c01356 100644 --- a/packages/docs/docs/core/entities.md +++ b/packages/docs/docs/core/entities.md @@ -6,6 +6,8 @@ sidebar_position: 9 Entities in ElizaOS represent users, agents, or any participant that can interact within the system. They form the basis of the entity-component architecture, allowing for flexible data modeling and relationships across the platform. +![](/img/entities-component-architecture.svg) + ## Entity Structure An entity in ElizaOS has the following properties: diff --git a/packages/docs/docs/core/evaluators.md b/packages/docs/docs/core/evaluators.md index ba3d88615f2..e56117ba933 100644 --- a/packages/docs/docs/core/evaluators.md +++ b/packages/docs/docs/core/evaluators.md @@ -1,165 +1,201 @@ --- -sidebar_position: 5 +sidebar_position: 7 --- -# 📊 Evaluators +# 🧠 Evaluators -[Evaluators](/api/interfaces/evaluator) are core components that assess and extract information from conversations. Agents use evaluators to automatically process conversations after they happen to help build up their knowledge and understanding over time. +Evaluators are cognitive components in the ElizaOS framework that enable agents to process conversations, extract knowledge, and build understanding - similar to how humans form memories after interactions. They provide a structured way for agents to introspect, learn from interactions, and evolve over time. -They integrate with the [`AgentRuntime`](/api/classes/AgentRuntime) evaluation system to enable reflection, fact-gathering, and behavioral adaptation and run after each agent action to help maintain contextual awareness. Enabling agents to reflect on their actions and world state is crucial for improving coherence and problem-solving abilities. For example, by reflecting on its performance, an agent can refine its strategies and improve its interactions over time. +## Understanding Evaluators ---- - -## How They Work - -Evaluators run automatically after each agent action (responses, messages, activities, or API calls) to analyze what happened and update the agent's understanding. They extract important information (like facts about users), track progress on goals, build relationship models, and enable self-reflection. +Evaluators are specialized functions that work with the [`AgentRuntime`](/api/classes/AgentRuntime) to analyze conversations after a response has been generated. Unlike actions that create responses, evaluators perform background cognitive tasks that enable numerous advanced capabilities: -Let's say you're at a party and meet someone new. During the conversation: +- **Knowledge Building**: Automatically extract and store facts from conversations +- **Relationship Tracking**: Identify connections between entities +- **Conversation Quality**: Perform self-reflection on interaction quality +- **Goal Tracking**: Determine if conversation objectives are being met +- **Tone Analysis**: Evaluate emotional content and adjust future responses +- **User Profiling**: Build understanding of user preferences and needs over time +- **Performance Metrics**: Gather data on agent effectiveness and learn from interactions -- You learn their name is Sarah -- They mention living in Seattle -- They work as a software engineer +### Core Structure -After the conversation, your brain: +```typescript +interface Evaluator { + name: string; // Unique identifier + similes?: string[]; // Alternative names/triggers + description: string; // Purpose explanation + examples: EvaluationExample[]; // Sample usage patterns + handler: Handler; // Implementation logic + validate: Validator; // Execution criteria check + alwaysRun?: boolean; // Run regardless of validation +} +``` -- Stores these facts for later -- Updates your understanding of who Sarah is -- Might note "I should connect Sarah with Bob who's also in tech" -- Reflects on how the interaction went (e.g., "I think I talked too much about work") +### Evaluator Execution Flow -This is exactly how evaluators work for agents. They run in the background to extract insights, track progress, build relationship models, and enable self-reflection. Evaluators are limited to processing current interactions (can't modify past data) and run after actions complete (not during), so they're best for analysis rather than critical operations. +The agent runtime executes evaluators as part of its cognitive cycle: -The key thing to remember is: evaluators are your agent's way of learning, reflecting, and growing from each interaction, just like how we naturally process and learn from our conversations. +1. Agent processes a message and generates a response +2. Runtime calls `evaluate()` after response generation +3. Each evaluator's `validate()` method determines if it should run +4. For each valid evaluator, the `handler()` function is executed +5. Results are stored in memory and inform future responses -### Common Uses +--- -- **[Reflection Evaluator](https://github.com/elizaOS/eliza/blob/main/packages/core/src/evaluators/reflection.ts)**: Combines self-monologue, fact extraction, and relationship building -- **[Fact Evaluator](https://github.com/elizaOS/eliza/blob/main/packages/plugin-bootstrap/src/evaluators/fact.ts)**: Learns and remembers facts about users -- **[Goal Evaluator](https://github.com/elizaOS/eliza/blob/main/packages/plugin-bootstrap/src/evaluators/goals.ts)**: Tracks progress on objectives -- **Trust Evaluator**: Builds understanding of relationships -- **Sentiment Evaluator**: Tracks emotional tone of conversations +## Fact Evaluator: Memory Formation System ---- +The Fact Evaluator serves as the agent's "episodic memory formation" system - similar to how humans process conversations and form memories. Just as you might reflect after a conversation "Oh, I learned something new about Sarah today", the Fact Evaluator systematically processes conversations to build up the agent's understanding of the world and the people in it. -## Implementation +### How It Works -Here's a basic example of an evaluator implementation: +#### 1. Triggering (The "When to Reflect" System) ```typescript -const evaluator = { - // Should this evaluator run right now? - validate: async (runtime, message) => { - // Return true to run, false to skip - return shouldRunThisTime; - }, - - // What to do when it runs - handler: async (runtime, message) => { - // Extract info, update memory, etc - const newInfo = extractFromMessage(message); - await storeInMemory(newInfo); - }, +validate: async (runtime: IAgentRuntime, message: Memory): Promise => { + const messageCount = await runtime.messageManager.countMemories(message.roomId); + const reflectionCount = Math.ceil(runtime.getConversationLength() / 2); + return messageCount % reflectionCount === 0; }; ``` -### Core Interface +Just like humans don't consciously analyze every single word in real-time, the Fact Evaluator runs periodically rather than after every message. It triggers a "reflection" phase every few messages to process what's been learned. -```typescript -interface Evaluator { - name: string; // Unique identifier - similes: string[]; // Similar evaluator descriptions - description: string; // Purpose and functionality - validate: (runtime: IAgentRuntime, message: Memory) => Promise; - handler: (runtime: IAgentRuntime, message: Memory) => Promise; - examples: EvaluatorExample[]; -} -``` +#### 2. Fact Extraction (The "What Did I Learn?" System) -For full type definitions, see the [`Evaluator`](/api/interfaces/Evaluator) interface documentation. +The evaluator uses a template-based approach to extract three types of information: -### Validation Function +- **Facts**: Unchanging truths about the world or people + - "Bob lives in New York" + - "Sarah has a degree in Computer Science" +- **Status**: Temporary or changeable states + - "Bob is currently working on a new project" + - "Sarah is visiting Paris this week" +- **Opinions**: Subjective views, feelings, or non-factual statements + - "Bob thinks the project will be successful" + - "Sarah loves French cuisine" -The `validate` function is critical for determining when an evaluator should run. For peak performance, proper validation ensures evaluators run only when necessary. For instance, a customer service agent might check if all required user data has been collected and only run if data is still missing. +#### 3. Memory Deduplication (The "Is This New?" System) ```typescript -validate: async (runtime: IAgentRuntime, message: Memory) => boolean; +const filteredFacts = facts.filter((fact) => { + return ( + !fact.already_known && + fact.type === 'fact' && + !fact.in_bio && + fact.claim && + fact.claim.trim() !== '' + ); +}); ``` -Determines if evaluator should run for current message. Returns true to execute handler, false to skip. Should be efficient and quick to check. +Just as humans don't need to consciously re-learn things they already know, the Fact Evaluator: -### Handler Function +- Checks if information is already known +- Verifies if it's in the agent's existing knowledge (bio) +- Filters out duplicate or corrupted facts -The handler function contains the evaluator's code. It is where the logic for analyzing data, extracting information, and triggering actions resides. +#### 4. Memory Storage (The "Remember This" System) ```typescript -handler: async (runtime: IAgentRuntime, message: Memory) => any; +const factMemory = await factsManager.addEmbeddingToMemory({ + userId: agentId!, + agentId, + content: { text: fact }, + roomId, + createdAt: Date.now(), +}); ``` -Contains main evaluation logic and runs when validate() returns true. Can access [`runtime`](/api/interfaces/IAgentRuntime) services and [`memory`](/api/interfaces/Memory). +Facts are stored with embeddings to enable: -:::tip -**Ensure Evaluators are unique and lightweight** +- Semantic search of related facts +- Context-aware recall +- Temporal tracking (when the fact was learned) -Avoid complex operations or lengthy computations within the evaluator's handler function and ensure that evaluators have clear and distinct responsibilities not already handled by other components for peak performance. -::: +### Example Processing -### Memory Integration +Given this conversation: -Results are stored using runtime memory managers: +``` +User: "I just moved to Seattle last month!" +Agent: "How are you finding the weather there?" +User: "It's rainy, but I love my new job at the tech startup" +``` -```typescript -// Example storing evaluation results -const memory = await runtime.addEmbeddingToMemory({ - entityId: message.entityId, - agentId: message.agentId, - content: { text: evaluationResult }, - roomId: message.roomId, - embedding: await runtime.useModel(ModelType.TEXT_EMBEDDING, { text: evaluationResult }), -}); +The Fact Evaluator might extract: -await runtime.createMemory(memory, 'facts', true); +```json +[ + { + "claim": "User moved to Seattle last month", + "type": "fact", + "in_bio": false, + "already_known": false + }, + { + "claim": "User works at a tech startup", + "type": "fact", + "in_bio": false, + "already_known": false + }, + { + "claim": "User enjoys their new job", + "type": "opinion", + "in_bio": false, + "already_known": false + } +] ``` ---- +### Key Design Considerations -## Reflection Evaluator +1. **Episodic vs Semantic Memory** -The Reflection Evaluator is a comprehensive evaluator that combines multiple functions: + - Facts build up the agent's semantic memory (general knowledge) + - The raw conversation remains in episodic memory (specific experiences) -1. **Self-Monologue**: Generates introspective thoughts about the agent's performance -2. **Fact Extraction**: Identifies and stores new factual information -3. **Relationship Building**: Maps connections between entities in the conversation +2. **Temporal Awareness** -The reflection evaluator runs periodically during conversations (by default, every quarter of the conversation length) and performs a deep analysis of the entire context. + - Facts are timestamped to track when they were learned + - Status facts can be updated as they change -### Reflection Output Structure +3. **Confidence and Verification** -Reflections are structured with three main components: + - Multiple mentions of a fact increase confidence + - Contradictory facts can be flagged for verification -```typescript -interface Reflection { - thought: string; // Self-reflective monologue - facts: { - claim: string; // Factual statement - type: 'fact' | 'opinion' | 'status'; // Classification - in_bio: boolean; // Already in agent knowledge - already_known: boolean; // Previously extracted - }[]; - relationships: { - sourceEntityId: UUID; // Entity initiating interaction - targetEntityId: UUID; // Entity being interacted with - tags: string[]; // Relationship classifiers - }[]; -} -``` +4. **Privacy and Relevance** + - Only stores relevant, conversation-appropriate facts + - Respects explicit and implicit privacy boundaries + +--- -### Example Reflection +## Reflection Evaluator: Self-Awareness System -Here's an example of a reflection from a community manager agent: +The reflection evaluator extends beyond fact extraction to enable agents to develop a form of "self-awareness" about their conversational performance. It allows agents to: + +1. Generate self-reflective thoughts about the conversation quality +2. Extract factual information from conversations (similar to the Fact Evaluator) +3. Identify and track relationships between entities + +### How Reflections Work + +When triggered, the reflection evaluator: + +1. Analyzes recent conversations and existing knowledge +2. Generates structured reflection output with: + - Self-reflective thoughts about conversation quality + - New facts extracted from conversation + - Identified relationships between entities +3. Stores this information in the agent's memory for future reference + +### Example Reflection Output ```json { - "thought": "I'm engaging appropriately with a new community member, maintaining a welcoming and professional tone. My questions are helping to learn more about John and make him feel welcome.", + "thought": "I'm engaging appropriately with John, maintaining a welcoming and professional tone. My questions are helping learn more about him as a new community member.", "facts": [ { "claim": "John is new to the community", @@ -189,192 +225,250 @@ Here's an example of a reflection from a community manager agent: } ``` -In this reflection: +### Implementation Details -- The agent validates it's using appropriate communication strategies -- Two new facts are identified about John -- Two relationship connections are established (bidirectional between agent and user) +The reflection evaluator uses a defined schema to ensure consistent output: -### Self-Awareness Through Reflection +```typescript +const reflectionSchema = z.object({ + facts: z.array( + z.object({ + claim: z.string(), + type: z.string(), + in_bio: z.boolean(), + already_known: z.boolean(), + }) + ), + relationships: z.array(relationshipSchema), +}); -The thought component helps agents develop self-awareness. For example, if an agent is dominating a conversation: +const relationshipSchema = z.object({ + sourceEntityId: z.string(), + targetEntityId: z.string(), + tags: z.array(z.string()), + metadata: z + .object({ + interactions: z.number(), + }) + .optional(), +}); +``` -```json -{ - "thought": "I'm dominating the conversation and not giving others a chance to share their perspectives. I've sent multiple messages in a row without waiting for responses. I need to step back and create space for other members to participate." -} +### Validation Logic + +The reflection evaluator includes validation logic that determines when reflection should occur: + +```typescript +validate: async (runtime: IAgentRuntime, message: Memory): Promise => { + const lastMessageId = await runtime.getCache( + `${message.roomId}-reflection-last-processed` + ); + const messages = await runtime.getMemories({ + tableName: 'messages', + roomId: message.roomId, + count: runtime.getConversationLength(), + }); + + if (lastMessageId) { + const lastMessageIndex = messages.findIndex((msg) => msg.id === lastMessageId); + if (lastMessageIndex !== -1) { + messages.splice(0, lastMessageIndex + 1); + } + } + + const reflectionInterval = Math.ceil(runtime.getConversationLength() / 4); + + return messages.length > reflectionInterval; +}; ``` -This self-awareness allows agents to adjust their behavior in future interactions, creating more natural and balanced conversations. +This ensures reflections occur at appropriate intervals, typically after a set number of messages have been exchanged. -### Integration with Providers +## Common Memory Formation Patterns -Facts extracted by evaluators are stored in memory and can be accessed by providers like the `factsProvider`. This creates a virtuous cycle: +1. **Progressive Learning** -1. Evaluators extract and store facts after conversations -2. The facts provider retrieves relevant facts during future conversations -3. The agent uses these facts to provide more contextually relevant responses -4. New facts are identified and stored by evaluators + ```typescript + // First conversation + "I live in Seattle" -> Stores as fact -## Fact Evaluator + // Later conversation + "I live in the Ballard neighborhood" -> Updates/enhances existing fact + ``` -The Fact Evaluator is a specialized evaluator focused on extracting meaningful facts from conversations. It processes interactions to: +2. **Fact Chaining** -- Extract meaningful facts and opinions about users and the world -- Distinguish between permanent facts, opinions, and status -- Track what information is already known vs new information -- Build up the agent's understanding over time through embeddings and memory storage + ```typescript + // Original facts + 'Works at tech startup'; + 'Startup is in Seattle'; -Facts are stored with the following structure: + // Inference potential + 'Works in Seattle tech industry'; + ``` -```typescript -interface Fact { - claim: string; // The actual information extracted - type: 'fact' | 'opinion' | 'status'; // Classification of the information - in_bio: boolean; // Whether this info is already in the agent's knowledge - already_known: boolean; // Whether this was previously extracted -} -``` +3. **Temporal Tracking** -#### Example Facts + ```typescript + // Status tracking + t0: 'Looking for a job'(status); + t1: 'Got a new job'(fact); + t2: 'Been at job for 3 months'(status); + ``` -Here's an example of extracted facts from a conversation: +4. **Relationship Building** -``` -User: I finally finished my marathon training program! -Agent: That's a huge accomplishment! How do you feel about it? -User: I'm really proud of what I achieved. It was tough but worth it. -Agent: What's next for you? -User: I'm actually training for a triathlon now. It's a whole new challenge. -``` + ```typescript + // Initial relationship + { + "sourceEntityId": "user-123", + "targetEntityId": "sarah-agent", + "tags": ["new_interaction"] + } + + // Evolving relationship + { + "sourceEntityId": "user-123", + "targetEntityId": "sarah-agent", + "tags": ["frequent_interaction", "positive_sentiment"], + "metadata": { "interactions": 15 } + } + ``` + +## Integration with Other Systems + +Evaluators work alongside other components: + +- **Goal Evaluator**: Facts and reflections may influence goal progress +- **Trust Evaluator**: Fact consistency affects trust scoring +- **Memory Manager**: Facts enhance context for future conversations +- **Providers**: Facts inform response generation + +--- + +## Creating Custom Evaluators + +You can create your own evaluators by implementing the `Evaluator` interface: ```typescript -const extractedFacts = [ - { - claim: 'User completed marathon training', - type: 'fact', // Permanent info / achievement - in_bio: false, - already_known: false, // Prevents duplicate storage +const customEvaluator: Evaluator = { + name: 'CUSTOM_EVALUATOR', + similes: ['ANALYZE', 'ASSESS'], + description: 'Performs custom analysis on conversations', + + validate: async (runtime: IAgentRuntime, message: Memory): Promise => { + // Your validation logic here + return true; }, - { - claim: 'User feels proud of their achievement', - type: 'opinion', // Subjective views or feelings - in_bio: false, - already_known: false, - }, - { - claim: 'User is currently training for a triathlon', - type: 'status', // Ongoing activity, changeable - in_bio: false, - already_known: false, - }, -]; -``` -## Goal Evaluator + handler: async (runtime: IAgentRuntime, message: Memory, state?: State) => { + // Your evaluation logic here -The Goal Evaluator tracks progress on conversation objectives by analyzing messages and updating goal status. Goals are structured like this: + // Example of storing evaluation results + await runtime.addEmbeddingToMemory({ + entityId: runtime.agentId, + content: { text: 'Evaluation result' }, + roomId: message.roomId, + createdAt: Date.now(), + }); -```typescript -interface Goal { - id: string; - name: string; - status: 'IN_PROGRESS' | 'DONE' | 'FAILED'; - objectives: { - description: string; - completed: boolean; - }[]; -} + return { result: 'evaluation complete' }; + }, + + examples: [ + { + prompt: `Example context`, + messages: [ + { name: 'User', content: { text: 'Example message' } }, + { name: 'Agent', content: { text: 'Example response' } }, + ], + outcome: `{ "result": "example outcome" }`, + }, + ], +}; ``` -#### Example Goals +### Registering Custom Evaluators -Here's how the goal evaluator processes a conversation: +Custom evaluators can be registered with the agent runtime: ```typescript -// Initial goal state -const goal = { - id: 'book-club-123', - name: 'Complete reading assignment', - status: 'IN_PROGRESS', - objectives: [ - { description: 'Read chapters 1-3', completed: false }, - { description: 'Take chapter notes', completed: false }, - { description: 'Share thoughts in book club', completed: false }, - ], -}; +// In your plugin's initialization +export default { + name: 'custom-evaluator-plugin', + description: 'Adds custom evaluation capabilities', + + init: async (config: any, runtime: IAgentRuntime) => { + // Register your custom evaluator + runtime.registerEvaluator(customEvaluator); + }, -// Conversation happens -const conversation = ` -User: I finished reading the first three chapters last night -Agent: Great! Did you take any notes while reading? -User: Yes, I made detailed notes about the main characters -Agent: Perfect, we can discuss those in the club meeting -User: I'm looking forward to sharing my thoughts tomorrow -`; - -// Goal evaluator updates the goal status -const updatedGoal = { - id: 'book-club-123', - name: 'Complete reading assignment', - status: 'IN_PROGRESS', // Still in progress - objectives: [ - { description: 'Read chapters 1-3', completed: true }, // Marked complete - { description: 'Take chapter notes', completed: true }, // Marked complete - { description: 'Share thoughts in book club', completed: false }, // Still pending - ], + // Include the evaluator in the plugin exports + evaluators: [customEvaluator], }; - -// After the book club meeting, goal would be marked DONE -// If user can't complete objectives, goal could be marked FAILED ``` ---- +## Best Practices for Memory Formation -## FAQ +1. **Validate Facts** -### How do evaluators differ from providers? + - Cross-reference with existing knowledge + - Consider source reliability + - Track fact confidence levels -While [providers](/api/interfaces/Provider) supply data to the agent before responses, evaluators analyze conversations after responses. Providers inform decisions, evaluators learn from outcomes. +2. **Manage Memory Growth** -### Can evaluators modify agent behavior? + - Prioritize important facts + - Consolidate related facts + - Archive outdated status facts -Evaluators cannot directly modify agent responses. However, through their extracted facts and self-reflections that are stored in memory, they indirectly influence future behavior by shaping the agent's knowledge and self-awareness. +3. **Handle Contradictions** -### How many evaluators can run simultaneously? + - Flag conflicting facts + - Maintain fact history + - Update based on newest information -There's no hard limit, but each evaluator adds processing overhead. Focus on essential evaluations and use efficient validation to optimize performance. The reflection evaluator can replace multiple specialized evaluators since it combines fact extraction, relationship building, and self-reflection. +4. **Respect Privacy** -### How does the reflection evaluator determine when to run? + - Filter sensitive information + - Consider contextual appropriateness + - Follow data retention policies -The reflection evaluator typically runs at regular intervals during a conversation (e.g., every quarter of the conversation length). This balances the need for regular reflection with performance considerations. +5. **Balance Reflection Frequency** + - Too frequent: Computational overhead + - Too infrequent: Missing important information + - Adapt based on conversation complexity and pace -### How do facts extracted by evaluators get used? +--- -Facts are stored in the agent's memory with embeddings for semantic retrieval. The facts provider can retrieve relevant facts during conversations using semantic search, allowing the agent to remember and use this information in responses. +## FAQ -### What's the difference between 'facts', 'opinions', and 'status'? +### What's the difference between actions and evaluators? -- **Facts**: Permanent truths about entities (e.g., "John lives in Seattle") -- **Opinions**: Subjective views or feelings (e.g., "John feels proud of his achievement") -- **Status**: Temporary states that change over time (e.g., "John is currently traveling") +Actions are triggered during response generation and create visible outputs, while evaluators run after responses and perform background cognitive tasks without direct user visibility. -### Can evaluators communicate with each other? +### When should I use the Fact Evaluator vs. the Reflection Evaluator? -Evaluators don't directly communicate but can share data through the memory system. The reflection evaluator often combines the functionality of multiple evaluators, reducing the need for inter-evaluator communication. +Use the Fact Evaluator when you only need to extract and store factual information. Use the Reflection Evaluator when you need both fact extraction and relationship tracking, along with self-reflective assessment. -### How are self-reflections used by agents? +### How often do evaluators run? -Self-reflections help agents become more self-aware and improve their interaction quality. For example, if an agent reflects that it's dominating a conversation, it can adjust its behavior in future interactions to create more balance. +By default, evaluators run at intervals based on conversation length, typically after every few messages, to avoid unnecessary processing while still capturing important information. -### What's the difference between similes and examples in evaluators? +### Can evaluators affect future responses? -Similes provide alternative descriptions of the evaluator's purpose, while examples show concrete scenarios with inputs and expected outcomes. Examples help verify correct implementation. +Yes! Facts and relationships stored by evaluators become part of the agent's memory and context, influencing future responses through the retrieval-augmented generation system. -### Can evaluators be conditionally enabled? +### How do I debug evaluator issues? -Yes, use the validation function to control when evaluators run. This can be based on message content, user status, conversation length, or other runtime conditions. +Use the logger to inspect evaluator execution and output. The most common issues involve entity resolution failures or schema validation errors. -``` +### Can evaluators work across different platforms? -``` +Yes, evaluators are platform-agnostic and work the same way regardless of whether your agent is deployed on Discord, Twitter, Telegram, or web interfaces. + +## Related Resources + +- [Actions Documentation](./actions.md) +- [Providers Documentation](./providers.md) +- [Agent Runtime](./agents.md) diff --git a/packages/docs/docs/core/knowledge.md b/packages/docs/docs/core/knowledge.md index 6dd3c049461..b77080d5c0d 100644 --- a/packages/docs/docs/core/knowledge.md +++ b/packages/docs/docs/core/knowledge.md @@ -1,4 +1,4 @@ -# Knowledge Management in ElizaOS +# Knowledge Management ## Overview diff --git a/packages/docs/docs/core/overview.md b/packages/docs/docs/core/overview.md index fa75cc9e33b..f3fad638c3f 100644 --- a/packages/docs/docs/core/overview.md +++ b/packages/docs/docs/core/overview.md @@ -1,270 +1,424 @@ --- sidebar_position: 1 +title: ElizaOS Documentation +slug: / --- -# Overview - -ElizaOS is a framework for creating AI agents that can interact across multiple platforms through a consistent, extensible architecture. - -## Core Features - -- **Modular Architecture**: A plugin-based system for extending functionality -- **Entity-Component System**: Flexible data modeling for agents and users -- **Vector-Based Memory**: Semantic retrieval of conversations and knowledge -- **Multi-Modal Interactions**: Support for text, voice, images, and other media formats -- **Reflection & Self-Improvement**: Agents learn from interactions and adapt over time -- **Cross-Platform Integration**: Connect to multiple services through a unified interface - -## Key Components - -ElizaOS consists of these core architectural components: - -[![](/img/architecture.png)](/img/architecture.png) +# ElizaOS Documentation + +Welcome to ElizaOS - a comprehensive framework for building AI agents with persistent personalities across multiple platforms. ElizaOS provides the architecture, tools, and systems needed to create sophisticated agents that maintain consistent behavior, learn from interactions, and seamlessly integrate with a variety of services. + +## System Architecture + +ElizaOS uses a modular architecture that separates concerns while providing a cohesive framework for AI agent development: + +```mermaid +graph TB + %% Main Components with vertical orientation + User((User)):::user + + %% First Level - Services + PlatformServices[Services]:::services + + %% Second Level - Runtime + AgentRuntime[Agent Runtime]:::core + + %% Core Processing Components - Side by side + subgraph "Core Processing" + direction LR + Providers[Providers]:::int + Actions[Actions]:::int + Evaluators[Evaluators]:::int + end + + %% Knowledge and DB - Side by side + subgraph "Knowledge & Storage" + direction LR + Knowledge[Knowledge]:::int + DB[(Database)]:::db + end + + %% Organization Components - Vertical layout + subgraph "Organization" + direction TB + Worlds[Worlds]:::struct + Rooms[Rooms]:::struct + Entities[Entities]:::struct + end + + %% Development Components - Side by side + subgraph "Development & Integration" + direction LR + Plugins[Plugins]:::dev + Projects[Projects]:::dev + Tasks[Tasks]:::dev + end + + %% Main Flow - Vertical emphasis + User <-->|Interaction| PlatformServices + PlatformServices -->|Process| AgentRuntime + + %% Runtime connections - Simplified + AgentRuntime ---|Context| Providers + AgentRuntime ---|Behavior| Actions + AgentRuntime ---|Analysis| Evaluators + + %% Data connections + AgentRuntime <-->|Storage| DB + Knowledge -->|Informs| Providers + + %% Structure connections - Clean vertical hierarchy + AgentRuntime -->|Manages| Worlds + Worlds -->|Contains| Rooms + Rooms -->|Has| Entities + + %% Development connections + Projects -->|Configure| AgentRuntime + Plugins -->|Extend| AgentRuntime + Tasks -->|Scheduled by| AgentRuntime + + %% Clickable nodes with links to docs + click AgentRuntime "/docs/core/agents" "Learn about Agent Runtime" + click PlatformServices "/docs/core/services" "Learn about Services" + click DB "/docs/core/database" "Learn about Database Systems" + click Actions "/docs/core/actions" "Learn about Actions" + click Providers "/docs/core/providers" "Learn about Providers" + click Evaluators "/docs/core/evaluators" "Learn about Evaluators" + click Knowledge "/docs/core/knowledge" "Learn about Knowledge System" + click Worlds "/docs/core/worlds" "Learn about Worlds" + click Rooms "/docs/core/rooms" "Learn about Rooms" + click Entities "/docs/core/entities" "Learn about Entities" + click Plugins "/docs/core/plugins" "Learn about Plugins" + click Projects "/docs/core/project" "Learn about Projects" + click Tasks "/docs/core/tasks" "Learn about Tasks" + + %% Styling + classDef core fill:#3498db,stroke:#2c3e50,stroke-width:1px,color:#fff,font-weight:bold + classDef services fill:#9b59b6,stroke:#2c3e50,stroke-width:1px,color:#fff,font-weight:bold + classDef db fill:#27ae60,stroke:#2c3e50,stroke-width:1px,color:#fff,font-weight:bold + classDef int fill:#e74c3c,stroke:#2c3e50,stroke-width:1px,color:#fff,font-weight:bold + classDef struct fill:#f39c12,stroke:#2c3e50,stroke-width:1px,color:#fff,font-weight:bold + classDef dev fill:#1abc9c,stroke:#2c3e50,stroke-width:1px,color:#fff,font-weight:bold + classDef user fill:#ecf0f1,stroke:#2c3e50,stroke-width:2px,color:#2c3e50,font-weight:bold,border-radius:50% +``` -### [Agent Runtime](./agents.md) +### How ElizaOS Works + +When a user message is received: + +1. **Service Reception**: Platform service (Discord, Telegram, etc.) receives the message +2. **Runtime Processing**: Agent runtime coordinates the response generation +3. **Context Building**: Providers supply relevant context (time, recent messages, knowledge) +4. **Action Selection**: The agent evaluates and selects appropriate actions +5. **Response Generation**: The chosen action generates a response +6. **Learning & Reflection**: Evaluators analyze the conversation for insights and learning +7. **Memory Storage**: New information is stored in the database +8. **Response Delivery**: The response is sent back through the service + +This creates a continuous cycle of interaction, reflection, and improvement that allows agents to maintain consistent personalities while adapting to new information. + +## Core Components + +
+
+
+
+
+ Overview +
+
+

🤖 Agent Runtime

+

The central system that orchestrates agent behavior, processes messages, manages state, and coordinates all other components.

+
+ +
+
+ +
+
+
+ Overview +
+
+

📚 Services

+

Platform-specific integrations that enable agents to communicate across Discord, Twitter, Telegram, and other channels.

+
+
+ Services +
+
+
+ +
+
+
+ Overview +
+
+

💾 Database

+

Persistent storage for memories, entity data, relationships, and configuration using vector search capabilities.

+
+
+ Database +
+
+
+
+
+ +## Intelligence & Behavior + +
+
+
+
+
+ Overview +
+
+

⚡ Actions

+

Executable capabilities that define how agents respond to messages and interact with external systems.

+
+
+ Actions +
+
+
+ +
+
+
+ Overview +
+
+

🔌 Providers

+

Data sources that supply contextual information to inform agent decision-making in real-time.

+
+
+ Providers +
+
+
+ +
+
+
+ Overview +
+
+

📊 Evaluators

+

Analytical systems that process conversations to extract insights, learn facts, and improve future responses.

+
+ +
+
+ +
+
+
+ Overview +
+
+

🧠 Knowledge

+

RAG system for document processing, semantic search, and context-aware memory retrieval.

+
+
+ Knowledge +
+
+
+
+
+ +## Structure & Organization + +
+
+
+
+
+ Overview +
+
+

🌐 Worlds

+

Collection spaces that organize entities and rooms into coherent environments (like a Discord server).

+
+
+ Worlds +
+
+
+ +
+
+
+ Overview +
+
+

💬 Rooms

+

Conversation spaces where entities interact through messages (channels, DMs, threads).

+
+
+ Rooms +
+
+
+ +
+
+
+ Overview +
+
+

👤 Entities

+

Representation of users, agents, and other participants using a flexible entity-component architecture.

+
+
+ Entities +
+
+
+
+
+ +## Development & Integration + +
+
+
+
+
+ Overview +
+
+

🧩 Plugins

+

Modular extensions that add new capabilities, integrations, and behaviors to agents.

+
+
+ Plugins +
+
+
+ +
+
+
+ Overview +
+
+

📝 Projects

+

Organizational structure for defining and deploying one or more agents with their configuration.

+
+
+ Projects +
+
+
+ +
+
+
+ Overview +
+
+

📋 Tasks

+

System for managing deferred, scheduled, and repeating operations across conversations.

+
+
+ Tasks +
+
+
+
+
-The Agent Runtime is the central nervous system of ElizaOS. It orchestrates all components, manages state, processes messages, and coordinates the agent's behavior. +--- -**Responsibilities:** +## Key Concepts -- Lifecycle management -- Service coordination -- Memory management -- State composition -- Action execution -- Model integration +### Action-Provider-Evaluator Cycle -### [Projects](./project.md) +The core of the ElizaOS system operates as a continuous cycle: -Projects are the top-level containers that define one or more agents, their configurations, and shared resources. A project: +1. **Providers** gather context before response generation +2. **Actions** determine what the agent can do and are executed to generate responses +3. **Evaluators** analyze conversations after responses to extract insights +4. These insights become part of the agent's memory +5. Future **Providers** access this memory to inform new responses -- Defines agent characters and behavior -- Configures plugins and services -- Sets up knowledge and memory systems -- Establishes shared worlds and environments +This creates a virtuous cycle where agents continuously learn and improve from interactions. -### [Entities & Components](./entities.md) +### Entity-Component Architecture ElizaOS uses an entity-component architecture for flexible data modeling: -- **Entities**: Base objects with unique identifiers (agents, users, etc.) -- **Components**: Modular data attached to entities (profiles, settings, etc.) - -This architecture allows for dynamic composition of objects and extensible data models without complex inheritance hierarchies. - -### [Services](./services.md) - -Services connect agents to different platforms (Discord, X/Twitter, Telegram, etc.) and provide specialized capabilities: - -- **Platform Services**: Connect to external platforms -- **Core Services**: Provide essential functionality (speech, vision, etc.) -- **Extension Services**: Add specialized capabilities - -Services use a consistent interface but can provide platform-specific features when needed. - -### [Actions](./actions.md) - -Actions define how agents respond to messages and interact with the world: - -- **Communication Actions**: Generate responses and engage in conversation -- **Integration Actions**: Interact with external systems and APIs -- **Media Actions**: Generate and process images, audio, and other media -- **Platform Actions**: Leverage platform-specific features - -Each action includes validation logic, a handler function, and thought processes that explain the agent's reasoning. - -### [Providers](./providers.md) - -Providers supply contextual information to agents as they make decisions: - -- **Memory Providers**: Access relevant conversation history -- **Knowledge Providers**: Supply factual information -- **State Providers**: Provide current context and environment details -- **Temporal Providers**: Manage time-based awareness - -Providers are dynamically composed to create a comprehensive context for agent decision-making. - -### [Evaluators](./evaluators.md) - -Evaluators analyze conversations after they happen, helping agents learn and improve: - -- **Reflection Evaluator**: Enables self-awareness and improvement -- **Fact Evaluator**: Extracts factual information from conversations -- **Goal Evaluator**: Tracks progress on objectives -- **Relationship Evaluator**: Models connections between entities - -Evaluators create a feedback loop for continuous agent improvement. - -### [Plugins](./plugins.md) - -Plugins extend ElizaOS with new capabilities by adding services, actions, providers, evaluators, and more: - -- **Core Plugins**: Essential functionality for all agents -- **Platform Plugins**: Integrations with external platforms -- **Capability Plugins**: Special abilities like blockchain interaction -- **Utility Plugins**: Tools for specific tasks or domains - -Plugins use a consistent installation and configuration pattern. +- **Entities** are base objects with unique IDs (users, agents, etc.) +- **Components** are pieces of data attached to entities (profiles, settings, etc.) +- This approach allows for dynamic composition without complex inheritance hierarchies -## Data Systems +### Memory System -### [Database System](./database.md) +The memory system in ElizaOS provides: -ElizaOS uses a flexible adapter-based database system: +- **Vector-based semantic search** for finding relevant memories +- **Multi-level memory types** (messages, facts, knowledge) +- **Temporal awareness** through timestamped memories +- **Cross-platform continuity** while maintaining appropriate context boundaries -- **Entity Storage**: Manages entity and component data -- **Memory System**: Stores conversations and extracted facts -- **Vector Search**: Enables semantic retrieval of information -- **Relationship Tracking**: Maps connections between entities -- **World & Room Management**: Organizes conversation spaces - -The current implementation supports PGLite (for development) and PostgreSQL (for production) using Drizzle ORM. - -### [Knowledge System](./knowledge.md) - -The knowledge system enables agents to access and use structured information: - -- **Document Processing**: Converts various file formats into usable knowledge -- **RAG Implementation**: Retrieval-Augmented Generation for contextual responses -- **Semantic Search**: Finds relevant information through vector similarity -- **Memory Integration**: Combines knowledge with conversation memory - -## Structural Elements - -### [Worlds](./worlds.md) - -Worlds are containers for agents, rooms, and shared resources that provide: - -- Namespace isolation -- Resource sharing -- Multi-agent environments -- Context boundaries - -### [Rooms](./rooms.md) - -Rooms are conversation spaces where entities interact: - -- Direct messages between entities -- Group conversations -- Platform-specific channels -- Persistent conversation history - -### [Tasks](./tasks.md) - -The task system enables asynchronous processing and scheduled operations: - -- Background processing -- Scheduled activities -- Workflow management -- Event-driven operations - -## System Flow - -When a message is received: - -1. The **Service** receives the input and forwards it to the **Runtime** -2. The **Runtime** loads the agent configuration from the **Project** -3. **Providers** supply context (memories, knowledge, state) -4. Valid **Actions** are identified through validation functions -5. The agent decides on a response, including internal **thoughts** -6. The response is returned through the **Service** -7. **Evaluators** analyze the conversation for insights -8. New memories and relationships are stored in the **Database** - -This creates a continuous cycle of interaction, reflection, and improvement. - -## Common Patterns - -### Creating an Agent Response - -```typescript -// The agent runtime processes a message and generates a response -const result = await runtime.processMessage({ - entityId: senderId, - roomId: channelId, - content: { text: 'Hello, how are you?' }, -}); +## Getting Started -// The response includes thought process and actions -console.log(result.thought); // Internal reasoning (not shown to user) -console.log(result.text); // The actual response -console.log(result.actions); // Actions performed -``` +If you're new to ElizaOS, we recommend this learning path: -### Storing and Retrieving Memories - -```typescript -// Store a memory -await runtime.createMemory( - { - entityId: userId, - roomId: channelId, - content: { text: 'Important information' }, - embedding: await runtime.useModel(ModelType.TEXT_EMBEDDING, { - text: 'Important information', - }), - }, - 'facts' -); - -// Retrieve relevant memories -const memories = await runtime.searchMemories({ - tableName: 'messages', - roomId: channelId, - embedding: embedding, - count: 5, -}); -``` - -### Creating a Relationship Between Entities - -```typescript -// Establish a relationship -await runtime.createRelationship({ - sourceEntityId: userEntityId, - targetEntityId: agentEntityId, - tags: ['friend', 'frequent_interaction'], - metadata: { - interactions: 12, - trust_level: 'high', - }, -}); -``` +1. Start with this overview to understand the system architecture +2. Explore the [Agent Runtime](/docs/core/agents) to understand the core system +3. Learn about [Projects](/docs/core/project) to set up your development environment +4. Understand how [Actions](/docs/core/actions) and [Providers](/docs/core/providers) work together +5. Explore [Services](/docs/core/services) to connect with external platforms +6. Dive into [Plugins](/docs/core/plugins) to extend functionality ## FAQ -### What's the difference between Actions, Evaluators, and Providers? +
+What's the difference between Actions, Evaluators, and Providers? **Actions** define what an agent can do and are executed during response generation. **Evaluators** analyze conversations after they happen to extract insights and improve future responses. **Providers** supply contextual information before the agent decides how to respond. -### How do agent thoughts relate to evaluator reflections? - -Agent **thoughts** are generated during response creation to explain reasoning in the moment. Evaluator **reflections** happen after responses, analyzing longer-term patterns and extracting insights for future interactions. +
-### How is memory organized in ElizaOS? +
+How does ElizaOS handle cross-platform conversation context? -Memory is organized into different types (messages, facts, knowledge) and stored with vector embeddings for semantic search. This allows agents to retrieve relevant memories based on context rather than just recency. +ElizaOS maintains separate conversation contexts for different platforms by default, but shares entity relationships and learned facts across platforms. This ensures agents maintain a consistent understanding of users while respecting platform-specific conversation boundaries. -### How does the entity-component system work? +
-The entity-component system provides a flexible way to model data. **Entities** are base objects with unique IDs, while **Components** are pieces of data attached to entities. This allows for dynamic composition without complex inheritance. +
+How does the memory system work? -### How do I extend an agent with new capabilities? +Memory is organized into different types (messages, facts, knowledge) and stored with vector embeddings for semantic search. This allows agents to retrieve relevant memories based on context rather than just recency, creating more natural conversations. -Create or install plugins that provide new actions, services, providers, or evaluators. Plugins can be registered in the project configuration and will be automatically loaded when the agent starts. +
-### What model providers are supported? +
+What's the relationship between Worlds, Rooms, and Entities? -ElizaOS supports multiple model providers including OpenAI, Anthropic, and local models. The model provider is configured at the project level and can be overridden for specific operations. +Worlds are container spaces (like a Discord server) that can have multiple Rooms (channels, DMs). Entities (users, agents) participate in Rooms within Worlds. This hierarchical structure mirrors real-world platforms while providing a consistent abstraction. -### How do I configure the database? +
-ElizaOS currently supports PostgreSQL (recommended for production) and PGLite (for development). Configure the connection using environment variables like `POSTGRES_URL` or `PGLITE_DATA_DIR`. +
+How extensible is ElizaOS? -### How do services differ from the old "clients"? +ElizaOS is highly extensible through its plugin system. You can create custom actions, providers, evaluators, services, and more to extend functionality. The architecture is designed to be modular and composable at every level. -Services provide a more comprehensive integration model than the previous "clients" concept. They offer standardized interfaces for various platforms while allowing for platform-specific features and optimizations. +
-## Getting Started +## Additional Resources -To create your first ElizaOS project, see the [Quick Start Guide](../quickstart.md) +- [API Reference](/api) - Detailed API documentation for developers +- [GitHub Repository](https://github.com/elizaos/eliza) - Source code and contributions +- [Package Showcase](/packages) - Explore available plugins and extensions diff --git a/packages/docs/docs/core/plugins.md b/packages/docs/docs/core/plugins.md index 3558706c352..5e92ad19362 100644 --- a/packages/docs/docs/core/plugins.md +++ b/packages/docs/docs/core/plugins.md @@ -1,8 +1,26 @@ # Plugins +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + Plugins are modular extensions that enhance the capabilities of ElizaOS agents. They provide a flexible way to add new functionality, integrate external services, and customize agent behavior across different platforms. -**Browse the various plugins the eliza dev community made here: [Package Showcase](/packages)** +:::info +Key Improvements in V2 + +1. **Unified API**: Almost everything is accessible via `runtime.methodName()` in the agent runtime for simpler development +2. **Enhanced Model System**: The new `useModel` approach allows for flexible model provider registration +3. **Events System**: Formal support for event-based programming +4. **Plugin Creation Workflow**: Simplified creation and testing via CLI +5. **Testing Infrastructure**: Built-in support for plugin testing +6. **No Monorepo Required**: Complete plugin development without touching the core codebase +7. **Plugin Registry**: Manages the catalog of available plugins and handles their registration with the runtime +8. **Bootstrap Plugin**: Initializes core functionality required for all agents to operate + ::: + +The ElizaOS plugin system maintains the same basic concept as previous versions, with several new extension points (events, routes, tests, models) and features that significantly improve the developer experience. + +**Browse plugins the elizaOS community made here: [Package Showcase](/packages)** [![](/img/plugins.png)](/packages) @@ -12,6 +30,16 @@ Plugins are modular extensions that enhance the capabilities of ElizaOS agents. ## Quick Start +The new CLI tool introduces a streamlined workflow for plugin development without ever needing to touch the ElizaOS monorepo directly: + +1. **Create**: `npm create eliza` - Initialize a new plugin project with proper structure +2. **Develop**: Edit the plugin code in the generated project structure +3. **Test**: `npx elizaos test` - Test the plugin functionality +4. **Run**: `npx elizaos start` - Run the plugin with a default agent +5. **Publish**: `npx elizaos publish` - Share your plugin with others + +> Note: at time of publishing, use `npm create eliza@beta` until main version is uploaded + ### Creating a New Plugin You can create a new ElizaOS plugin using the CLI: @@ -26,111 +54,194 @@ npx @elizaos/cli@beta create When prompted, select "Plugin" as the type to create. The CLI will guide you through the setup process, creating a plugin with the proper structure and dependencies. +--- + ### Managing Plugins There are several ways to add plugins to your ElizaOS project: -1. Add the plugin to your project's dependencies (`package.json`): + + + ```json + { + "dependencies": { + "@elizaos/plugin-solana": "github:elizaos-plugins/plugin-solana", + "@elizaos/plugin-twitter": "github:elizaos-plugins/plugin-twitter" + } + } + ``` + + + ```typescript + // In src/index.ts + export const character: Character = { + name: 'MyAgent', + plugins: ['@elizaos/plugin-twitter', '@elizaos/plugin-example'], + // ... + }; + ``` + + + ```bash + # Add a plugin + npx @elizaos/cli plugins add @elizaos/plugin-twitter + + # Remove a plugin + npx @elizaos/cli plugins remove @elizaos/plugin-twitter + + # List available plugins + npx @elizaos/cli plugins list + ``` + + + + +--- + +### Plugin Configuration + +Configure plugin settings in your character definition: ```json { - "dependencies": { - "@elizaos/plugin-solana": "github:elizaos-plugins/plugin-solana", - "@elizaos/plugin-twitter": "github:elizaos-plugins/plugin-twitter" + "name": "MyAgent", + "plugins": ["@elizaos/plugin-example"], + "settings": { + "example": { + "enableFeatureX": true + // Plugin-specific configuration + } } } ``` -2. Configure the plugin in your project's character definition: +### Plugin Loading Process + +The AgentRuntime automatically loads the Bootstrap Plugin during initialization, before any other plugins: ```typescript -// In src/index.ts -export const character: Character = { - name: 'MyAgent', - plugins: ['@elizaos/plugin-twitter', '@elizaos/plugin-example'], +async initialize() { + // Register bootstrap plugin + await this.registerPlugin(bootstrapPlugin); + + // Then register additional plugins + for (const plugin of this.plugins) { + await this.registerPlugin(plugin); + } + + // Initialize other components // ... -}; +} ``` -3. Use the CLI tool to add or remove plugins: +--- -```bash -# Add a plugin -npx @elizaos/cli plugins add @elizaos/plugin-twitter +### Publishing Plugins -# Remove a plugin -npx @elizaos/cli plugins remove @elizaos/plugin-twitter +If you're a plugin developer, you can publish your plugin to make it available to others. The ElizaOS CLI provides several options for publishing your plugin depending on your needs. -# List available plugins -npx @elizaos/cli plugins list -``` +First, make sure your plugin is built and ready for distribution: ```bash -# Full CLI options -Usage: elizaos plugins [options] [command] +# Navigate to your plugin directory +cd my-eliza-plugin -manage elizaOS plugins +# Build your plugin +npm run build +``` -Options: - -h, --help display help for command + + + Publishing to GitHub is the recommended approach for sharing your plugin with the ElizaOS community: -Commands: - list|l [options] list available plugins - add|install add a plugin - remove|delete remove a plugin - help [command] display help for command -``` + ```bash + # Publish to GitHub + npx @elizaos/cli publish + ``` -### Plugin Configuration + This will: + 1. Build and package your plugin + 2. Create or update a GitHub repository in the elizaos-plugins organization + 3. Add your plugin to the ElizaOS registry (if you're a registry maintainer) -Configure plugin settings in your character definition: + For first-time publishers, the CLI will guide you through setting up GitHub credentials for publishing. -```typescript -{ - "settings": { - "twitter": { - "shouldRespondToMentions": true - // Plugin-specific configuration - } - } -} -``` + GitHub publishing is ideal for open-source plugins that you want to share with the community and have listed in the official registry. -## Publishing Plugins + -If you're a plugin developer, you can publish your plugin to make it available to others: + + You can also publish your plugin to npm: -```bash -# Navigate to your plugin directory -cd my-eliza-plugin + ```bash + # Publish to npm + npx @elizaos/cli publish --npm + ``` -# Build your plugin -npm run build + This allows users to install your plugin using standard npm commands: -# Publish to the registry -npx @elizaos/cli publish -``` + ```bash + npm install @your-scope/plugin-name + ``` -The publish command supports several options: + npm publishing is useful when you want to: + - Maintain your own package namespace + - Integrate with existing npm workflows + - Set up automated versioning and releases -```bash -# Publish to npm instead of GitHub -npx @elizaos/cli publish --npm + Make sure your package.json is properly configured with the correct name, version, and access permissions. -# Test the publish process without making changes -npx @elizaos/cli publish --test + -# Specify platform compatibility -npx @elizaos/cli publish --platform node -``` + + Before publishing, you can validate the process without making any external changes: + + ```bash + # Test the publish process + npx @elizaos/cli publish --test + ``` + + This runs through all the packaging and validation steps without actually publishing anything. + + Test mode is helpful for: + - Verifying your plugin structure is correct + - Ensuring all required files are present + - Checking that dependencies are properly configured + - Validating that your plugin can be built successfully + + Always run in test mode before your first public release to avoid issues. + + + + + The publish command supports several additional options to customize the publishing process: + + ```bash + # Specify platform compatibility + npx @elizaos/cli publish --platform node -When publishing, your plugin will be: + # Set custom version number + npx @elizaos/cli publish --version 1.2.3 -1. Built and packaged -2. Published to GitHub (or npm if specified) -3. Added to the elizaOS registry (if you're a maintainer) + # Provide a custom registry URL + npx @elizaos/cli publish --registry https://custom-registry.com -For first-time publishers, the CLI will guide you through setting up GitHub credentials for publishing. + # Publish with public access + npx @elizaos/cli publish --access public + ``` + + These options give you fine-grained control over how and where your plugin is published. Refer to `npx @elizaos/cli publish --help` for a complete list of options. + + + + +:::info +When submitting a plugin to the [elizaOS Registry](https://github.com/elizaos-plugins/registry), include: + +1. **Working Demo**: Screenshots or video of your plugin in action +2. **Test Results**: Evidence of successful integration and error handling +3. **Configuration Example**: Show how to properly configure your plugin + ::: --- @@ -142,13 +253,17 @@ Eliza uses a unified plugin architecture where everything is a plugin - includin Each plugin can provide one or more of the following components: -| Component | Purpose | -| -------------- | -------------------------------------------------------------------------- | -| **Services** | Platform integrations (Discord, Twitter, etc.) or specialized capabilities | -| **Actions** | Executable functions triggered by the agent | -| **Providers** | Context providers that supply information to the agent | -| **Evaluators** | Response analyzers for quality and compliance | -| **Adapters** | Database or storage system integrations | +| Component | Purpose | +| ------------------ | ------------------------------------------------------------------------------- | +| **Services** | Platform integrations (Discord, Twitter, etc.) or specialized capabilities | +| **Actions** | Executable functions triggered by the agent (reply, generate content, etc.) | +| **Providers** | Context providers that supply info to the agent during decision making | +| **Evaluators** | Analyze conversations to extract insights and improve future interactions | +| **Adapters** | Database or storage system integrations | +| **Model Handlers** | Register handlers for different model types (text generation, embeddings, etc.) | +| **Event Handlers** | React to system events like messages, connections, or actions | +| **API Routes** | Add custom REST endpoints to the agent's HTTP interface | +| **Tests** | Include test suites to verify plugin functionality | ### Plugin Interface @@ -287,7 +402,7 @@ Your plugin's `package.json` should include an `agentConfig` section: } ``` -## Environment Variables and Secrets +### Environment Variables and Secrets Plugins access configuration through the runtime with the following precedence: @@ -295,7 +410,7 @@ Plugins access configuration through the runtime with the following precedence: 2. Character settings 3. Global environment settings -### Access Pattern +#### Access Pattern ```typescript // In your service implementation @@ -303,7 +418,7 @@ const apiKey = runtime.getSetting('EXAMPLE_API_KEY'); const debugMode = runtime.getSetting('EXAMPLE_DEBUG_MODE'); // Returns boolean for "true"/"false" strings ``` -### Configuration in Character File +#### Configuration in Character File ```json { @@ -320,6 +435,133 @@ const debugMode = runtime.getSetting('EXAMPLE_DEBUG_MODE'); // Returns boolean f } ``` +--- + +## Bootstrap Plugin + +The Bootstrap Plugin is a foundational component of ElizaOS that initializes the core functionality required for agents to operate. It's automatically loaded as part of the initialization process, establishing the minimum viable capabilities that all agents need. + +```typescript +export const bootstrapPlugin: Plugin = { + name: 'bootstrap', + description: 'Agent bootstrap with basic actions and evaluators', + actions: [...], + events: {...}, + evaluators: [...], + providers: [...], + services: [TaskService, ScenarioService], +}; +``` + +The Bootstrap Plugin registers essential components across several categories to provide a foundation for all agents. These components can be extended by custom plugins. + + + + | Action | Description | + | ---------------------- | ----------------------------------------------- | + | `replyAction` | Generates and sends a response to a message | + | `followRoomAction` | Enables an agent to actively follow a room | + | `unfollowRoomAction` | Stops an agent from following a room | + | `muteRoomAction` | Mutes notifications from a room | + | `unmuteRoomAction` | Unmutes notifications from a room | + | `sendMessageAction` | Sends a message to a specific room | + | `ignoreAction` | Explicitly ignores a message | + | `noneAction` | Acknowledges a message without taking action | + | `updateEntityAction` | Updates properties of an entity | + | `choiceAction` | Presents choices to users and handles responses | + | `updateRoleAction` | Updates a user's role in a world | + | `updateSettingsAction` | Updates agent or world settings | + + + + | Provider | Description | + | ------------------------ | ---------------------------------------------------------- | + | `characterProvider` | Provides the agent's personality and configuration | + | `recentMessagesProvider` | Retrieves recent conversation history | + | `knowledgeProvider` | Supplies factual information from the knowledge base | + | `timeProvider` | Provides awareness of current time and date | + | `entitiesProvider` | Supplies information about entities in the current context | + | `relationshipsProvider` | Provides information about entity relationships | + | `factsProvider` | Retrieves relevant facts from memory | + | `roleProvider` | Provides role information within worlds | + | `settingsProvider` | Supplies configured settings | + | `anxietyProvider` | Informs agent of potential issues to be careful about | + | `attachmentsProvider` | Handles media and file attachments | + | `providersProvider` | Meta-provider with information about available providers | + | `actionsProvider` | Meta-provider with information about available actions | + | `evaluatorsProvider` | Meta-provider with information about available evaluators | + | `choiceProvider` | Manages choice-based interactions | + | `capabilitiesProvider` | Provides information about agent capabilities | + + + + **Services:** + + | Service | Purpose | + | ----------------- | ------------------------------------------------ | + | `TaskService` | Manages deferred, scheduled, and repeating tasks | + | `ScenarioService` | Handles scenario-based interactions and testing | + + **Evaluators:** + + | Evaluator | Description | + | --------------------- | ----------------------------------------------------- | + | `reflectionEvaluator` | Enables self-awareness and learning from interactions | + + + + + The Bootstrap Plugin registers handlers for key system events that enable the core message processing flow: + + **Core Events:** + - `MESSAGE_RECEIVED` - Processes new messages and generates responses + - `REACTION_RECEIVED` - Tracks reactions to messages + - `VOICE_MESSAGE_RECEIVED` - Handles audio messages + - `POST_GENERATED` - Creates social media content + - `MESSAGE_SENT` - Logs outgoing messages + + **World Events:** + - `WORLD_JOINED` / `WORLD_CONNECTED` - Synchronizes data when joining worlds + - `ENTITY_JOINED` / `ENTITY_LEFT` - Manages entity presence + + **Lifecycle Events:** + - `ACTION_STARTED` / `ACTION_COMPLETED` - Tracks action execution + - `EVALUATOR_STARTED` / `EVALUATOR_COMPLETED` - Monitors evaluator processing + - `RUN_STARTED` / `RUN_ENDED` / `RUN_TIMEOUT` - Manages message processing lifecycle + + The message processing flow follows these steps: + 1. Receive message via `MESSAGE_RECEIVED` event + 2. Save message to memory + 3. Check if agent should respond + 4. If responding, compose state from providers + 5. Generate a response using the language model + 6. Process any actions specified in the response + 7. Run evaluators on the conversation + 8. Emit lifecycle events throughout the process + + + + +### Extending Bootstrap Functionality + +While the Bootstrap Plugin provides core functionality, it's designed to be extended by other plugins. Custom plugins can: + +1. **Add new actions** - Extend the agent's capabilities +2. **Register additional providers** - Supply more contextual information +3. **Add evaluators** - Create new ways to analyze and learn from interactions +4. **Handle additional events** - React to more system events +5. **Initialize custom services** - Provide new functionality + +When working with plugins in relation to the Bootstrap Plugin: + +1. **Don't modify bootstrap directly** - Instead, create custom plugins to extend functionality +2. **Understand provider contribution** - Know how each provider contributes to the agent's context +3. **Learn the core actions** - Become familiar with the actions that all agents can perform +4. **Leverage event handlers** - Use the event system for reactive behavior +5. **Extend, don't replace** - Build on top of bootstrap functionality rather than replacing it + +--- + ## Developing a Plugin When developing a new plugin, focus on these key aspects: @@ -342,7 +584,7 @@ npx @elizaos/cli start --plugin=./path/to/plugin npx @elizaos/cli start --character=./characters/test.character.json --plugin=./path/to/plugin ``` -## Distribution & PR Requirements +### Distribution & PR Requirements When submitting a plugin to the [elizaOS Registry](https://github.com/elizaos-plugins/registry), include: @@ -357,6 +599,8 @@ When submitting a plugin to the [elizaOS Registry](https://github.com/elizaos-pl - [ ] Tests are passing - [ ] Includes error handling +--- + ## FAQ ### What exactly is a plugin in ElizaOS? diff --git a/packages/docs/docs/core/reflection.md b/packages/docs/docs/core/reflection.md deleted file mode 100644 index a7e14d81fa5..00000000000 --- a/packages/docs/docs/core/reflection.md +++ /dev/null @@ -1,190 +0,0 @@ -# Fact Evaluator: Memory Formation System - -The Fact Evaluator serves as the agent's "episodic memory formation" system - similar to how humans process conversations and form memories. Just as you might reflect after a conversation "Oh, I learned something new about Sarah today", the Fact Evaluator systematically processes conversations to build up the agent's understanding of the world and the people in it. - -## How It Works - -### 1. Triggering (The "When to Reflect" System) - -```typescript -validate: async (runtime: IAgentRuntime, message: Memory): Promise => { - const messageCount = await runtime.messageManager.countMemories(message.roomId); - const reflectionCount = Math.ceil(runtime.getConversationLength() / 2); - return messageCount % reflectionCount === 0; -}; -``` - -Just like humans don't consciously analyze every single word in real-time, the Fact Evaluator runs periodically rather than after every message. It triggers a "reflection" phase every few messages to process what's been learned. - -### 2. Fact Extraction (The "What Did I Learn?" System) - -The evaluator uses a template-based approach to extract three types of information: - -- **Facts**: Unchanging truths about the world or people - - "Bob lives in New York" - - "Sarah has a degree in Computer Science" -- **Status**: Temporary or changeable states - - "Bob is currently working on a new project" - - "Sarah is visiting Paris this week" -- **Opinions**: Subjective views, feelings, or non-factual statements - - "Bob thinks the project will be successful" - - "Sarah loves French cuisine" - -### 3. Memory Deduplication (The "Is This New?" System) - -```typescript -const filteredFacts = facts.filter((fact) => { - return ( - !fact.already_known && - fact.type === 'fact' && - !fact.in_bio && - fact.claim && - fact.claim.trim() !== '' - ); -}); -``` - -Just as humans don't need to consciously re-learn things they already know, the Fact Evaluator: - -- Checks if information is already known -- Verifies if it's in the agent's existing knowledge (bio) -- Filters out duplicate or corrupted facts - -### 4. Memory Storage (The "Remember This" System) - -```typescript -const factMemory = await factsManager.addEmbeddingToMemory({ - userId: agentId!, - agentId, - content: { text: fact }, - roomId, - createdAt: Date.now(), -}); -``` - -Facts are stored with embeddings to enable: - -- Semantic search of related facts -- Context-aware recall -- Temporal tracking (when the fact was learned) - -## Example Processing - -Given this conversation: - -``` -User: "I just moved to Seattle last month!" -Agent: "How are you finding the weather there?" -User: "It's rainy, but I love my new job at the tech startup" -``` - -The Fact Evaluator might extract: - -```json -[ - { - "claim": "User moved to Seattle last month", - "type": "fact", - "in_bio": false, - "already_known": false - }, - { - "claim": "User works at a tech startup", - "type": "fact", - "in_bio": false, - "already_known": false - }, - { - "claim": "User enjoys their new job", - "type": "opinion", - "in_bio": false, - "already_known": false - } -] -``` - -## Key Design Considerations - -1. **Episodic vs Semantic Memory** - - - Facts build up the agent's semantic memory (general knowledge) - - The raw conversation remains in episodic memory (specific experiences) - -2. **Temporal Awareness** - - - Facts are timestamped to track when they were learned - - Status facts can be updated as they change - -3. **Confidence and Verification** - - - Multiple mentions of a fact increase confidence - - Contradictory facts can be flagged for verification - -4. **Privacy and Relevance** - - Only stores relevant, conversation-appropriate facts - - Respects explicit and implicit privacy boundaries - -## Integration with Other Systems - -The Fact Evaluator works alongside other evaluators and systems: - -- **Goal Evaluator**: Facts may influence goal progress -- **Trust Evaluator**: Fact consistency affects trust scoring -- **Memory Manager**: Facts enhance context for future conversations -- **Providers**: Facts inform response generation - -## Common Patterns - -1. **Progressive Learning** - - ```typescript - // First conversation - "I live in Seattle" -> Stores as fact - - // Later conversation - "I live in the Ballard neighborhood" -> Updates/enhances existing fact - ``` - -2. **Fact Chaining** - - ```typescript - // Original facts - 'Works at tech startup'; - 'Startup is in Seattle'; - - // Inference potential - 'Works in Seattle tech industry'; - ``` - -3. **Temporal Tracking** - ```typescript - // Status tracking - t0: 'Looking for a job'(status); - t1: 'Got a new job'(fact); - t2: 'Been at job for 3 months'(status); - ``` - -## Best Practices - -1. **Validate Facts** - - - Cross-reference with existing knowledge - - Consider source reliability - - Track fact confidence levels - -2. **Manage Memory Growth** - - - Prioritize important facts - - Consolidate related facts - - Archive outdated status facts - -3. **Handle Contradictions** - - - Flag conflicting facts - - Maintain fact history - - Update based on newest information - -4. **Respect Privacy** - - Filter sensitive information - - Consider contextual appropriateness - - Follow data retention policies diff --git a/packages/docs/docs/core/rooms.md b/packages/docs/docs/core/rooms.md index ead91d40779..0d506016e1f 100644 --- a/packages/docs/docs/core/rooms.md +++ b/packages/docs/docs/core/rooms.md @@ -6,6 +6,8 @@ sidebar_position: 8 Rooms in ElizaOS represent individual interaction spaces within a world. A room can be a conversation, a channel, a thread, or any other defined space where entities can exchange messages and interact. Rooms are typically contained within a world, though they can also exist independently. +![](/img/elizaos-rooms-simplified.svg) + ## Room Structure A room in ElizaOS has the following properties: diff --git a/packages/docs/docs/core/services.md b/packages/docs/docs/core/services.md index 2ef30b83e90..94f6b3748a0 100644 --- a/packages/docs/docs/core/services.md +++ b/packages/docs/docs/core/services.md @@ -180,45 +180,6 @@ count: 10 ``` ---- - -## Direct Service Example - -The [Direct service](https://github.com/elizaOS/eliza/tree/develop/packages/plugin-direct) provides message processing, webhook integration, and a REST API interface for Eliza agents. It's the primary service used for testing and development. - - -Key features of the Direct service: -- Express.js server for HTTP endpoints -- Agent runtime management -- File upload handling -- Memory system integration -- WebSocket support for real-time communication - - -### Direct Service API Endpoints - -| Endpoint | Method | Description | Params | Input | Response | -|-----------------------------------------|--------|-------------------------------------------------|------------------------------|-----------------------------------------|------------------------------------------| -| `/:agentId/whisper` | POST | Audio transcription (Whisper) | `agentId` | Audio file | Transcription | -| `/:agentId/message` | POST | Main message handler | `agentId` | Text, optional file | Agent response | -| `/agents/:agentIdOrName/hyperfi/v1` | POST | Hyperfi game integration | `agentIdOrName` | Objects, emotes, history | JSON (`lookAt`, `emote`, `say`, actions) | -| `/:agentId/image` | POST | Image generation | `agentId` | Generation params | Image(s) with captions | -| `/fine-tune` | POST | Proxy for BagelDB fine-tuning | None | Fine-tuning data | BagelDB API response | -| `/fine-tune/:assetId` | GET | Download fine-tuned assets | `assetId` | None | File download | -| `/:agentId/speak` | POST | Text-to-speech (ElevenLabs) | `agentId` | Text | Audio stream | -| `/:agentId/tts` | POST | Direct text-to-speech | `agentId` | Text | Audio stream | - -### Static Routes -| Endpoint | Method | Description | -|-------------------------|--------|--------------------------| -| `/media/uploads/` | GET | Serves uploaded files | -| `/media/generated/` | GET | Serves generated images | - -### Common Parameters -Most endpoints accept: -- `roomId` (defaults to agent-specific room) -- `userId` (defaults to `"user"`) -- `userName` (for identity management) --- diff --git a/packages/docs/docs/core/worlds.md b/packages/docs/docs/core/worlds.md index bfbc7e076b5..ca46f6a3fad 100644 --- a/packages/docs/docs/core/worlds.md +++ b/packages/docs/docs/core/worlds.md @@ -6,6 +6,10 @@ sidebar_position: 7 Worlds in ElizaOS are collections of entities (users, agents) and rooms (conversations, channels) that form a cohesive environment for interactions. Think of a world as a virtual space, like a Discord server, Slack workspace, or 3D MMO environment, where entities can communicate across multiple channels or areas. +| Worlds | Rooms within Worlds | +| ----------------------------------------- | --------------------------------------- | +| ![](/img/elizaos-worlds-cosmic-clean.svg) | ![](/img/elizaos-worlds-simplified.svg) | + ## World Structure A world in ElizaOS has the following properties: diff --git a/packages/docs/docs/intro.md b/packages/docs/docs/intro.md index 7de03b0d8c2..c2d00426404 100644 --- a/packages/docs/docs/intro.md +++ b/packages/docs/docs/intro.md @@ -18,7 +18,7 @@ Eliza is a powerful multi-agent simulation framework designed to create, deploy, - **Platform Integration**: Clients for Discord, X (Twitter), Telegram, and many others - **Flexible Model Support**: Deepseek, Ollama, Grok, OpenAI, Anthropic, Gemini, LLama, etc. -- **Character System**: Create diverse agents using [characterfiles](https://github.com/elizaOS/characterfile) +- **Character System**: Create diverse agents using [character files](https://github.com/elizaOS/characterfile) - **Multi-Agent Architecture**: Manage multiple unique AI personalities simultaneously - **Memory Management**: Easily ingest and interact with documents using RAG - **Media Processing**: PDF, URLs, Audio transcription, Video processing, Image analysis, Conversation summarization @@ -38,17 +38,6 @@ Eliza can be used to create: - **Knowledge Workers**: Research assistants, Content analysts, Document processors - **Interactive Characters**: Role-playing characters, Educational tutors, Entertainment bots -## Architecture - -[![](/img/architecture.png)](/img/architecture.png) -Source: https://x.com/0xCygaar/status/1874575841763770492 - -The characterfile contains everything about the agent's personality, backstory, knowledge, and topics to talk about, as well as which clients / models / and plugins to load. The database is where an agent stores relevant info for generating responses, including previous tweets, interactions, and embeddings. Without a db, agent's wouldn't be able to give good responses. - -Then we have the "runtime", which you can think of as the core agent logic. It's effectively the coordination layer of the agent or the brain, calling the necessary modules and external services to generate responses and take actions. Within the runtime is the LLM, which processes various inputs and generates responses or action items for the agent to take. Devs can declare which LLM provider to use in the characterfile. The runtime also handles the registration of plugins, which are called when a user input asks it take an action, such as transferring ETH on Abstract or doing a web search. - -Eliza supports a variety of clients including `Discord`, `Twitter`, `Slack`, `Farcaster`, and others. The client is basically where the agent will live and interact with users. Agents can run on multiple clients at once. Clients can have modules to handle different interactions, such as responding to tweets, or even participating in Twitter spaces. - --- ## Getting Started @@ -153,5 +142,3 @@ Join us in building the future of autonomous AI agents with Eliza! ## Next Steps - [Quickstart Guide](./quickstart.md) -- [Understand Core Concepts](./core/agents.md) -- [Create Custom Characters](./core/characterfile.md) diff --git a/packages/docs/docs/quickstart.md b/packages/docs/docs/quickstart.md index 0345ca702cf..7ae3ff63a86 100644 --- a/packages/docs/docs/quickstart.md +++ b/packages/docs/docs/quickstart.md @@ -57,7 +57,7 @@ npx elizaos start npx elizaos project list-plugins # Add a plugin -npx elizaos project add-plugin @elizaos/plugin-discord +npx elizaos project add-plugin @elizaos-plugins/client-discord ``` ## 3. Creating a Plugin diff --git a/packages/docs/docusaurus.config.ts b/packages/docs/docusaurus.config.ts index fdfce4b222f..bdc85e374d8 100644 --- a/packages/docs/docusaurus.config.ts +++ b/packages/docs/docusaurus.config.ts @@ -185,7 +185,7 @@ const config = { { showReadingTime: true, onUntruncatedBlogPosts: 'ignore', - editUrl: 'https://github.com/elizaos/eliza/tree/main/docs/blog/', + editUrl: 'https://github.com/elizaos/eliza/tree/v2-develop/docs/blog/', blogSidebarTitle: 'Recent posts', blogSidebarCount: 'ALL', showLastUpdateAuthor: true, @@ -210,7 +210,7 @@ const config = { blogTitle: 'AI News', blogDescription: 'Automated aggregating and summarization of elizaOS ecosystem updates', showReadingTime: true, - editUrl: 'https://github.com/elizaos/eliza/tree/main/docs/news', + editUrl: 'https://github.com/elizaos/eliza/tree/v2-develop/packages/docs/news', blogSidebarTitle: 'All posts', blogSidebarCount: 'ALL', showLastUpdateAuthor: true, @@ -225,7 +225,7 @@ const config = { docs: { docItemComponent: '@theme/ApiItem', sidebarPath: require.resolve('./sidebars.ts'), - editUrl: 'https://github.com/elizaos/eliza/tree/main/docs/', + editUrl: 'https://github.com/elizaos/eliza/tree/v2-develop/packages/docs/', exclude: ['**/_media/**'], showLastUpdateAuthor: true, showLastUpdateTime: true, @@ -261,6 +261,11 @@ const config = { ], ], themeConfig: { + prism: { + theme: require('prism-react-renderer').themes.github, + darkTheme: require('prism-react-renderer').themes.dracula, + additionalLanguages: ['bash', 'shell-session', 'typescript', 'markdown'], + }, mermaid: { theme: { light: 'default', @@ -319,11 +324,6 @@ const config = { label: 'Packages', docId: 'index', }, - { - to: 'blog', - label: 'Blog', - position: 'left', - }, { type: 'doc', docsPluginId: 'community', @@ -331,6 +331,11 @@ const config = { label: 'Community', docId: 'index', }, + { + to: 'blog', + label: 'Blog', + position: 'left', + }, { label: 'RSS', position: 'left', @@ -358,11 +363,23 @@ const config = { label: 'General', href: './', }, + { + label: 'llms.txt', + href: 'llms.txt', + }, + { + label: 'llms-full.txt', + href: 'llms-full.txt', + }, ], }, { title: 'Community', items: [ + { + label: 'Website', + href: 'https://www.elizaos.ai/', + }, { label: 'Discord', href: 'https://discord.gg/elizaos', @@ -376,6 +393,10 @@ const config = { { title: 'More', items: [ + { + label: 'Blog', + href: '/blog', + }, { label: 'GitHub', href: 'https://github.com/elizaos/eliza', diff --git a/packages/docs/news/2025-03-18.md b/packages/docs/news/2025-03-18.md new file mode 100644 index 00000000000..c85a086ccbb --- /dev/null +++ b/packages/docs/news/2025-03-18.md @@ -0,0 +1,117 @@ +# Daily Report – 2025-03-18 + +## Fixes and Improvements in ElizaOS + +- **AI Writer Fix**: Resolved re-rendering issue. [Details](https://github.com/elizaOS/eliza/pull/3969) +- **Real-Time Thought Messages**: Implemented live display. [Details](https://github.com/elizaOS/eliza/pull/3967) +- **Bubble Layout Fix**: Prevented elements from sticking in short messages. [Details](https://github.com/elizaOS/eliza/pull/3965) +- **Button Label Fix**: Minor correction. [Details](https://github.com/elizaOS/eliza/pull/3964) +- **Log Display & API Fixes**: Addressed multiple issues. [Details](https://github.com/elizaOS/eliza/pull/3971) +- **Timeout Comment Correction**: Adjusted from 60s to 120s. [Details](https://github.com/elizaOS/eliza/pull/3968) + +## Casual Chat Logs + +- Discussions included jokes, cryptocurrency speculation, and hardware comparisons. +- No significant technical content or problem-solving. + +## Technical Issues and Solutions + +### WebSocket API Integration + +- WebSockets added for direct API access. +- Planned replacement of REST API. +- Implementation in Shaw’s v2 branch, pending merge. + [Discussion](https://discord.com/channels/1253563208833433701/1300025221834739744) + +### RAG Knowledge Issues + +- Problems loading knowledge files (PDFs). +- Solutions: + - Ensure `"enableRag": true` in `character.json`. + - Verify file paths and permissions. + - Adjust knowledge paths to avoid incorrect references. + [Discussion](https://discord.com/channels/1253563208833433701/1300025221834739744) + +### Plugin & Dependency Issues + +- `@elizaos/plugin-sql@^0.25.6` missing. +- Solution: Manually install dependencies and update `package.json`. + [Discussion](https://discord.com/channels/1253563208833433701/1300025221834739744) + +### Discord Bot Configuration + +- Bot failed to connect to the correct channel. +- Solutions: + - Ensure correct numeric channel ID. + - Verify bot permissions. + - Restart after `.env` changes. + [Discussion](https://discord.com/channels/1253563208833433701/1300025221834739744) + +### Telegram & EVM Plugin Issue + +- Transactions worked in terminal but not via Telegram. +- Solution: Switching from local LLaMA model to OpenAI resolved the issue. + [Discussion](https://discord.com/channels/1253563208833433701/1300025221834739744) + +### GitHub Personal Access Token Requirement + +- CLI unexpectedly requested a GitHub token. +- No resolution found; further investigation needed. + [Discussion](https://discord.com/channels/1253563208833433701/1300025221834739744) + +### Action Items + +#### Technical Tasks + +1. Merge WebSocket API into `develop`. +2. Fix `@elizaos/plugin-sql@^0.25.6` dependency issue. +3. Investigate GitHub token requirement in CLI. +4. Fix Telegram-EVM plugin execution issue. +5. Resolve Docker model loading error. + +#### Documentation Needs + +6. Update RAG knowledge setup guide. +7. Clarify WebSocket API usage. +8. Add troubleshooting steps for Discord bot setup. +9. Document Twitter rate limit settings. +10. Clarify Coingecko API integration. + +#### Feature Requests + +11. Improve RAG support for PDFs. +12. Add better error messages for missing knowledge directories. +13. Enhance CLI to handle missing dependencies. +14. Improve Telegram-EVM plugin compatibility. +15. Add WebSocket-based chat terminal example. + +## New Feature: Clear Logs API + +- Introduced a new "clear logs" method and API. +- Part of a broader update with five bug fixes. +- Nine contributors merged eight pull requests. + [Details](https://github.com/elizaOS/eliza/pull/3974) + +## Chore Updates + +- **Connection Status Handling**: Simplified for better efficiency. [Details](https://github.com/elizaOS/eliza/pull/3973) +- **Plugin Storage S3 Test Coverage**: Improved validation with structured tests. [Details](https://github.com/elizaOS/eliza/pull/3976) + +## Documentation Updates + +- **Versioning Added**: Users can switch between v0.25.9 and v1.0.0-alpha. [Details](https://github.com/elizaOS/eliza/pull/3963) +- **Terminology Fix**: Corrected Spanish translation. [Details](https://github.com/elizaOS/eliza/pull/3970) + +## Crypto Market Update + +- **Wrapped Bitcoin (WBTC)**: $83,847.71 +- **ai16z**: $0.20199 + +## ElizaOS Development and Community Updates + +- **Technical Discussions**: WebSocket API integration, RAG knowledge troubleshooting, plugin dependency fixes, and Discord bot improvements. + [Discussion](https://discord.com/channels/1253563208833433701/1300025221834739744) +- **ElizaOS v2 Beta Delay**: Postponed to next Monday for UX and developer experience improvements. + [Discussion](https://discord.com/channels/1253563208833433701/1301363808421543988) +- **Recent Development Efforts**: New features, bug fixes, and eight merged pull requests. + [Details](https://github.com/elizaOS/eliza/pull/3974) diff --git a/packages/docs/news/2025-03-19.md b/packages/docs/news/2025-03-19.md new file mode 100644 index 00000000000..81c3952ab15 --- /dev/null +++ b/packages/docs/news/2025-03-19.md @@ -0,0 +1,136 @@ +# Daily Report - 2025-03-19 + +## ElizaOS v2 Beta Rollout and Issues + +- **Beta Launched**: Stability issues persist due to merging multiple repositories into a single core repo. +- **Major Improvements**: + - New GUI, Tauri app, CLI, and in-browser editor. + - Simplified API with runtime-based operations. + - Character files no longer required. +- **Community Concerns**: + - DegenSpartan AI’s progress appears stalled due to its dependency on ElizaOS v2. + - Team clarified that all development efforts are focused on v2. + +## Technical Issues and Fixes + +- **Knowledge Directory Issues**: Ensure `.md` format and place files in `characters/knowledge/`. +- **Supabase RAG Knowledge**: `search_knowledge` function missing; fix by generating embeddings. +- **Plugin-SQL Errors**: Use `npm install -g @elizaos/cli@1.0.0-beta.1`. +- **OAuth2 Plugin Authentication**: Use a custom API for access/refresh tokens. +- **Token Limit Exceeded**: Reduce input/output tokens to avoid GPT-4o errors. +- **Debugging Eliza Actions**: Check `shouldHandle` method and refer to Nader’s tutorial. + +## Binance Listing Risks + +- Concerns raised about Binance delisting multiple projects, including one with the ticker 'ELIZA'. +- Emphasis on improving team performance and communication to maintain listing. + +## Documentation and Community Feedback + +- **Launchpad Application**: Some developers unaware of the process; link shared. +- **Documentation Update**: `llms.txt` added, but accuracy questioned. +- **Community Feedback**: CN community requested clearer onboarding documentation. +- **Launchpad Announcement Visibility**: Limited to Discord, low visibility on Twitter/Telegram. + +## Action Items + +### Technical Tasks + +1. Fix Spartan bugs in ElizaOS v2. +2. Stabilize ElizaOS v2 core repo. +3. Implement embedding generation for Supabase RAG. +4. Investigate Twitter mention search issue. +5. Fix ElizaOS AI agent quoting unrelated tweets. +6. Improve GPT-4o token handling. +7. Fix UUID constraint issue in Supabase Adapter. + +### Documentation Needs + +8. Clarify knowledge directory setup. +9. Update installation guide for ElizaOS. +10. Add debugging guide for Eliza actions. +11. Document OAuth2 authentication for plugins. +12. Improve onboarding documentation for v2. + +### Feature Requests + +13. Improve runtime-based API documentation. +14. Enhance GUI and in-browser editor usability. +15. Improve error messages for `npx elizaos start` failures. +16. Provide migration guide from v0.25 to v2. +17. Increase visibility of launchpad announcement. + +--- + +# Fixes and Improvements in ElizaOS + +- **Regex Syntax Fix**: Missing comma between regex expressions corrected. +- **Plugin-Tee Fix**: Removed `TEEVendors`, which no longer exists. +- **Typo Fix**: Corrected 'initalData' to 'initialData'. + +--- + +# Cryptocurrency Trading and Documentation Enhancements + +## Crypto Trading Discussions + +- **Tokens Discussed**: LYRA MCPOS/SOL, Eddy EDDY/SOL, Themis AI 69 TMAI/SOL, wesawdotfun WESAW/SOL. +- **Topics**: + - Price trends, investment strategies, and AI’s role in trading. + - Missed opportunities and tracking wallet movements. + +## Documentation Enhancements + +- **AI-Generated SVGs**: Suggested for improving documentation visuals. +- **CUDA in PyTorch**: Briefly mentioned but not elaborated. + +## Action Items + +- Improve real-time token tracking bots. +- Develop AI-based trading signals. +- Enhance documentation visuals using AI-generated SVGs. +- Improve tracking of developer activity and wallet movements. + +--- + +# Client Updates and Fixes + +- **Relative URL Fix**: Client now uses a relative URL instead of hardcoded 'localhost'. +- **Firefox Compatibility**: Fix ensures `crypto.randomUUID` works in HTTP contexts. +- **GUI Client Update**: Added support for room functionality. + +--- + +# Crypto Market Update + +- **Wrapped Bitcoin (WBTC)**: $82,596.38 +- **ai16z**: $0.1713 + +--- + +# ElizaOS Development and Community Discussions + +- **ElizaOS v2 Beta**: Major refactor with new GUI, Tauri app, CLI, and in-browser editor. +- **DegenSpartan AI**: Progress tied to ElizaOS v2, raising concerns about delays. +- **Binance Listing Risks**: Emphasis on strong team performance and communication. +- **Launchpad Application**: Shared, but some developers unaware. +- **Community Feedback**: CN community requested clearer onboarding documentation. +- **Technical Improvements**: + - Automating Clanktank episode production. + - Enhancing runtime-based API documentation. + - Improving GUI and in-browser editor usability. +- **AWS Bedrock Limits**: Pending increase for more Claude AI tasks. + +## Development Fixes + +- **Plugin-Tee Fix**: Removed `TEEVendors`. +- **Regex Fix**: Corrected missing comma in regex expressions. +- **Client Fix**: Switched to relative URL for better Firefox compatibility. +- **Minor Fixes**: + - Corrected typo in parameter name. + - Updated broken link in README.md. + +## Debugging and Plugin Requests + +- **Remote Debugging**: Use `bun --verbose --inspect-brk`. +- **Plugin Examples**: Request for examples in `package.json` under 'eliza' section. diff --git a/packages/docs/news/2025-03-20.md b/packages/docs/news/2025-03-20.md new file mode 100644 index 00000000000..06411f69cfa --- /dev/null +++ b/packages/docs/news/2025-03-20.md @@ -0,0 +1,55 @@ +# Daily Report – 2025-03-20 + +## Discord Chat Analysis Summary + +- No significant technical discussions, decisions, or problem-solving observed. +- Conversations focused on cryptocurrency trading, token price movements, and speculation. +- No concrete solutions or meaningful technical interactions recorded. + +## ElizaOS Development and Community Discussions + +### ElizaOS Beta Installation and Setup + +- Installation guide provided: `npm create eliza@beta`. +- Gitpod setup issues due to missing `server.allowedHosts` in `vite.config.js`. +- Debugging tips for `better-sqlite3` errors using `NODE_DEBUG=*`. + +### Technical Features and Enhancements + +- **Entity-Component System Visualization**: Modular representation of users, agents, and components. +- **Evaluators in AgentRuntime**: Extract and assess conversation data for agent learning. +- **Providers in ElizaOS**: Real-time data sources (news, terminal, wallet integrations). +- **Image Generation Tools**: Stable Diffusion preferred over MidJourney, optimized with Flux models. + +### Plugin and API Integrations + +- **Telegram Bot Multi-Instance Issue**: Workaround proposed, but Railway.app config limitations remain. +- **Twitter Plugin Integration**: Endpoint for tweet replies discussed, leveraging `twitter-client` plugin. +- **PDF Knowledge Ingestion**: `Folder2knowledge` and `knowledge2character` recommended for processing PDFs. + +### Tokenomics and Staking Discussions + +- Concerns over ElizaOS tokenomics and launchpad misuse. +- Liquidity extraction strategy using AI swarms to revive abandoned meme coins. +- Staking mechanisms for agents and plugins, with DAO-based fund allocation. + +### Community and Business Development + +- Potential partnership with ChainGPT for marketing and funding, with mixed opinions. +- Eliza Labs BD team to explore partnership further. +- Open-core monetization strategies, including a paid enterprise version. + +### Additional Technical Discussions + +- **Spartan V2 Launch Coordination**: Enabling Spartan chat before launch, token utility considerations. +- **Public Communication Strategies**: Debates on making channels public or creating new Discord/X accounts. +- **Telegram Buy Bot Update**: Planned to filter transactions under $2K. + +### Development Updates + +- Package improvements: Fixes in `plugin-tee`, three bug fixes, and five merged pull requests from six developers. + +## Crypto Market Update + +- **Wrapped Bitcoin (WBTC)**: $86,666.89. +- **ai16z**: $0.191. diff --git a/packages/docs/news/2025-03-21.md b/packages/docs/news/2025-03-21.md new file mode 100644 index 00000000000..6a4e437767c --- /dev/null +++ b/packages/docs/news/2025-03-21.md @@ -0,0 +1,48 @@ +# Daily Report – 2025-03-21 + +## Discord Testing Channel and X (Twitter) Strategy Proposal + +- **Closed Discord Testing Channel** + + - Proposal to create a private Discord channel for structured testing before public release. + - Similar to the existing "agent scarlett office" channel. + +- **X (Twitter) Strategy** + + - Initial post: "Spartan coming soon v2" with contract address in bio. + - Use an affiliate account to obtain a blue checkmark, then appeal for account merge (similar to ai16z’s ElizaOS strategy). + +- **Improving Engagement on X** + - Attach visually appealing template images to dev update announcements. + - Helps differentiate automated vs. manual posts. + +## Crypto Market Update + +- **Wrapped Bitcoin (WBTC)**: $84,046.87 +- **ai16z Token**: $0.1851 + +## Discord Discussions Summary + +- **General Market Discussions** + + - Mostly cryptocurrency price updates and token discussions. + - No significant technical problem-solving or implementations. + +- **Technical Topics** + + - Use of `LLMs.txt` for AI-assisted querying. + - Knowledge upload API and retrieval process. + - Twitter posting issues and action recognition bugs. + - Eliza V2 agent deployment. + +- **Proposals & Strategy Discussions** + + - Closed Discord testing channel. + - X (Twitter) strategy and engagement improvements. + - No recorded responses or confirmations. + +- **AI & Tokenomics Discussions** + - Repurposing dead pump.fun coins. + - AI agent collaboration using a registry and reputation system. + - Bonding curve incentives for AI Take Over coin. + - ElizaOS AI-NFT token feature. diff --git a/packages/docs/sidebars.ts b/packages/docs/sidebars.ts index 76065e86d42..90ceb27b0cb 100644 --- a/packages/docs/sidebars.ts +++ b/packages/docs/sidebars.ts @@ -32,6 +32,10 @@ const sidebars = { type: 'category', label: '🧠 Core Concepts', collapsed: false, + link: { + type: 'doc', + id: 'core/overview', + }, items: [ { type: 'doc', @@ -40,8 +44,8 @@ const sidebars = { }, { type: 'doc', - id: 'core/bootstrap', - label: 'Bootstrap', + id: 'core/actions', + label: 'Actions', }, { type: 'doc', @@ -50,33 +54,28 @@ const sidebars = { }, { type: 'doc', - id: 'core/plugins', - label: 'Plugins', - }, - { - type: 'doc', - id: 'core/providers', - label: 'Providers', + id: 'core/database', + label: 'Database Adapters', }, { type: 'doc', - id: 'core/knowledge', - label: 'Knowledge', + id: 'core/entities', + label: 'Entities', }, { type: 'doc', - id: 'core/actions', - label: 'Actions', + id: 'core/evaluators', + label: 'Evaluators', }, { type: 'doc', - id: 'core/evaluators', - label: 'Evaluators', + id: 'core/knowledge', + label: 'Knowledge', }, { type: 'doc', - id: 'core/entities', - label: 'Entities', + id: 'core/plugins', + label: 'Plugins', }, { type: 'doc', @@ -85,8 +84,8 @@ const sidebars = { }, { type: 'doc', - id: 'core/reflection', - label: 'Reflection', + id: 'core/providers', + label: 'Providers', }, { type: 'doc', diff --git a/packages/docs/src/components/CopyPageButton/index.tsx b/packages/docs/src/components/CopyPageButton/index.tsx new file mode 100644 index 00000000000..c1fd7e24f7e --- /dev/null +++ b/packages/docs/src/components/CopyPageButton/index.tsx @@ -0,0 +1,365 @@ +import React, { useState, useRef, useEffect } from 'react'; +import { useLocation } from '@docusaurus/router'; +import { useColorMode } from '@docusaurus/theme-common'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import styles from './styles.module.css'; + +// Define paths to exclude +const EXCLUDED_PATHS = [ + // Exclude API pages + /^\/api\//, + /^\/api\/?$/, + // Exclude packages index + /^\/packages\/?$/, + // Add more excluded paths as needed + // /^\/other-path\//, +]; + +export default function CopyPageButton(): JSX.Element { + const [isOpen, setIsOpen] = useState(false); + const [copySuccess, setCopySuccess] = useState(false); + const [isLoading, setIsLoading] = useState(false); + const dropdownRef = useRef(null); + const { colorMode } = useColorMode(); + const location = useLocation(); + const { siteConfig } = useDocusaurusContext(); + + // Check if current path should be excluded + const isExcludedPath = EXCLUDED_PATHS.some((regex) => regex.test(location.pathname)); + + // Early return if path is excluded + if (isExcludedPath) { + return null; + } + + // Close dropdown when clicking outside + useEffect(() => { + function handleClickOutside(event: MouseEvent) { + if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) { + setIsOpen(false); + } + } + + document.addEventListener('mousedown', handleClickOutside); + return () => { + document.removeEventListener('mousedown', handleClickOutside); + }; + }, []); + + // Reset copy success message after 2 seconds + useEffect(() => { + if (copySuccess) { + const timer = setTimeout(() => { + setCopySuccess(false); + }, 2000); + return () => clearTimeout(timer); + } + }, [copySuccess]); + + // Toggle dropdown + const toggleDropdown = () => { + setIsOpen(!isOpen); + }; + + // Extract the edit URL from the DOM + const getEditUrl = () => { + // Find the "Edit this page" link in the DOM + const editLinkElement = document.querySelector('a.theme-edit-this-page'); + if (editLinkElement && editLinkElement.getAttribute('href')) { + return editLinkElement.getAttribute('href'); + } + + // Fallback for local development + // If we're in local development and we have editUrl configured in docusaurus.config.js + if (process.env.NODE_ENV === 'development') { + // Get the edit URL from config + let editUrl = siteConfig.presets?.[0]?.[1]?.docs?.editUrl || siteConfig.themeConfig?.editUrl; + + if (editUrl) { + // Convert from tree URL to edit URL if needed + if (editUrl.includes('/tree/')) { + editUrl = editUrl.replace('/tree/', '/edit/'); + } + + // Remove trailing slash if present + const baseEditUrl = editUrl.endsWith('/') ? editUrl.slice(0, -1) : editUrl; + + // Get the current path and remove leading and trailing slashes + let currentPath = location.pathname; + currentPath = currentPath.replace(/^\//, '').replace(/\/$/, ''); + + // Remove 'docs/' from the beginning if present + if (currentPath.startsWith('docs/')) { + currentPath = currentPath.substring(5); + } + + // Append .md to get the markdown file + return `${baseEditUrl}/${currentPath}.md`; + } + } + + return null; + }; + + // Convert GitHub edit URL to raw content URL + const getRawUrl = (url: string): string | null => { + if (!url) return null; + + // Handle GitHub URLs - support both edit and tree formats + const githubEditRegex = /github\.com\/([^/]+)\/([^/]+)\/(edit|tree)\/([^/]+)\/(.+)/; + const match = url.match(githubEditRegex); + + if (match) { + const [, owner, repo, urlType, branch, path] = match; + return `https://raw.githubusercontent.com/${owner}/${repo}/${branch}/${path}`; + } + + // Handle GitLab URLs + const gitlabEditRegex = /gitlab\.com\/([^/]+)\/([^/]+)\/-\/edit\/([^/]+)\/(.+)/; + const gitlabMatch = url.match(gitlabEditRegex); + + if (gitlabMatch) { + const [, owner, repo, branch, path] = gitlabMatch; + return `https://gitlab.com/${owner}/${repo}/-/raw/${branch}/${path}`; + } + + return url; // Return original URL if we can't convert it (for local development) + }; + + // Get content using the appropriate method + const getContent = async (url: string): Promise => { + // For local development, try to fetch the content directly + if (process.env.NODE_ENV === 'development' && !url.startsWith('http')) { + try { + // Try to fetch from location relative to the current page + const localUrl = url.startsWith('/') ? url : `/${url}`; + const response = await fetch(localUrl); + if (response.ok) { + return await response.text(); + } + } catch (error) { + console.error('Error fetching local content:', error); + } + + // If local fetch fails, return placeholder message + return '# Content not available locally\n\nThis feature works best when deployed to GitHub Pages.'; + } + + // For production or if local fetch fails, use the raw URL + const rawUrl = getRawUrl(url); + if (!rawUrl) { + return '# Content not available\n\nCould not determine the source URL for this page.'; + } + + const response = await fetch(rawUrl); + if (!response.ok) { + throw new Error(`Failed to fetch: ${response.status} ${response.statusText}`); + } + + return await response.text(); + }; + + // Fetch markdown and copy to clipboard + const copyPageAsMarkdown = async () => { + const currentEditUrl = getEditUrl(); + if (!currentEditUrl) { + console.error('Edit URL not available'); + return; + } + + setIsLoading(true); + + try { + const markdown = await getContent(currentEditUrl); + await navigator.clipboard.writeText(markdown); + setCopySuccess(true); + setIsOpen(false); + } catch (error) { + console.error('Error fetching markdown:', error); + } finally { + setIsLoading(false); + } + }; + + // Open the raw markdown in a new tab + const viewAsMarkdown = async () => { + const currentEditUrl = getEditUrl(); + if (!currentEditUrl) { + return; + } + + const rawUrl = getRawUrl(currentEditUrl); + if (rawUrl) { + // For local development, create a blob URL + if (process.env.NODE_ENV === 'development' && !currentEditUrl.startsWith('http')) { + try { + const content = await getContent(currentEditUrl); + const blob = new Blob([content], { type: 'text/plain' }); + const url = URL.createObjectURL(blob); + window.open(url, '_blank'); + } catch (error) { + console.error('Error creating blob:', error); + } + } else { + // For production + window.open(rawUrl, '_blank'); + } + setIsOpen(false); + } + }; + + // Open the current page in ChatGPT + const openInChatGPT = () => { + const currentUrl = window.location.href; + // Use the correct ChatGPT URL format + const chatGptUrl = `https://chatgpt.com/?q=${encodeURIComponent(`Tell me about this page: ${currentUrl}`)}`; + window.open(chatGptUrl, '_blank'); + setIsOpen(false); + }; + + // Check if we should show the button on this page + const [showButton, setShowButton] = useState(false); + + useEffect(() => { + if (isExcludedPath) { + setShowButton(false); + return; + } + + // Need a small delay to ensure the DOM is updated after page navigation + const timer = setTimeout(() => { + // In development, check if we have editUrl configured + if (process.env.NODE_ENV === 'development') { + const hasEditUrl = !!getEditUrl(); + setShowButton(hasEditUrl); + } else { + // In production, check for the edit link in the DOM + const hasEditLink = !!document.querySelector('a.theme-edit-this-page'); + setShowButton(hasEditLink); + } + }, 100); + + return () => clearTimeout(timer); + }, [location.pathname, isExcludedPath]); + + // Don't render the button if it shouldn't be shown + if (!showButton) { + return null; + } + + return ( +
+ + + {isOpen && ( +
+
+ + + + +
+
Copy page
+
Copy this page as Markdown for LLMs
+
+
+ + + + + + +
+ )} + + {copySuccess &&
Copied to clipboard!
} + + {isLoading &&
Loading...
} +
+ ); +} diff --git a/packages/docs/src/components/CopyPageButton/styles.module.css b/packages/docs/src/components/CopyPageButton/styles.module.css new file mode 100644 index 00000000000..eda945c16b0 --- /dev/null +++ b/packages/docs/src/components/CopyPageButton/styles.module.css @@ -0,0 +1,204 @@ +.copyPageButtonContainer { + position: relative; + margin-left: 0.5rem; + display: inline-flex; + align-items: center; +} + +.copyPageButton { + display: flex; + align-items: center; + gap: 0.5rem; + background-color: var(--ifm-color-emphasis-200); + border: 1px solid var(--ifm-color-emphasis-300); + color: var(--ifm-color-emphasis-800); + border-radius: 6px; + padding: 0.5rem 0.75rem; + font-size: 0.875rem; + cursor: pointer; + transition: all 0.2s ease; + font-weight: 500; +} + +.copyPageButton:hover { + background-color: var(--ifm-color-emphasis-300); +} + +.copyPageButton:disabled { + opacity: 0.6; + cursor: not-allowed; +} + +.copyIcon { + flex-shrink: 0; +} + +.dropdownIcon { + width: 16px; + height: 16px; + margin-left: 2px; +} + +.dropdown { + position: absolute; + top: calc(100% + 8px); + right: 0; + background-color: white; + border-radius: 8px; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); + width: 320px; + z-index: 100; + overflow: hidden; + border: 1px solid var(--ifm-color-emphasis-200); +} + +.dropdown.dark { + background-color: var(--ifm-background-surface-color); + border-color: var(--ifm-color-emphasis-300); +} + +.dropdownHeader { + padding: 1rem; + display: flex; + align-items: flex-start; + gap: 0.75rem; + border-bottom: 1px solid var(--ifm-color-emphasis-200); +} + +.dropdownTitle { + font-weight: 600; + margin-bottom: 0.25rem; + color: var(--ifm-heading-color); +} + +.dropdownSubtitle { + font-size: 0.875rem; + color: var(--ifm-color-emphasis-600); +} + +.dropdownItem { + width: 100%; + display: flex; + align-items: flex-start; + gap: 0.75rem; + padding: 1rem; + border: none; + background: transparent; + text-align: left; + cursor: pointer; + transition: background-color 0.2s ease; + color: var(--ifm-font-color-base); +} + +.dropdownItem:hover { + background-color: var(--ifm-color-emphasis-100); +} + +.dropdownItem:disabled { + opacity: 0.6; + cursor: not-allowed; +} + +.dropdownItem:disabled:hover { + background-color: transparent; +} + +.dropdownItemTitle { + font-weight: 500; + margin-bottom: 0.25rem; + display: flex; + align-items: center; + gap: 0.25rem; + color: var(--ifm-heading-color); +} + +.externalIcon { + font-size: 0.875rem; + opacity: 0.7; +} + +.dropdownItemSubtitle { + font-size: 0.875rem; + color: var(--ifm-color-emphasis-600); +} + +.itemIcon { + margin-top: 0.125rem; +} + +.codeIcon { + display: inline-flex; + align-items: center; + justify-content: center; + font-family: monospace; + font-size: 0.75rem; + background-color: var(--ifm-color-emphasis-200); + padding: 0.375rem; + border-radius: 4px; + width: 20px; + height: 20px; + margin-top: 0.125rem; +} + +.chatGptIcon { + color: #10a37f; + margin-top: 0.125rem; +} + +.copySuccessTooltip { + position: absolute; + bottom: calc(100% + 8px); + right: 0; + background-color: var(--ifm-color-success); + color: white; + padding: 0.375rem 0.75rem; + border-radius: 4px; + font-size: 0.875rem; + white-space: nowrap; + animation: fadeInOut 2s ease; + font-weight: 500; +} + +.loadingTooltip { + position: absolute; + bottom: calc(100% + 8px); + right: 0; + background-color: var(--ifm-color-info); + color: white; + padding: 0.375rem 0.75rem; + border-radius: 4px; + font-size: 0.875rem; + white-space: nowrap; + font-weight: 500; +} + +@keyframes fadeInOut { + 0% { + opacity: 0; + transform: translateY(8px); + } + 10% { + opacity: 1; + transform: translateY(0); + } + 90% { + opacity: 1; + transform: translateY(0); + } + 100% { + opacity: 0; + transform: translateY(-8px); + } +} + +/* Responsive adjustments */ +@media (max-width: 768px) { + .copyPageButtonText { + display: none; + } + + .dropdown { + width: 280px; + right: -12px; + } +} diff --git a/packages/docs/src/components/HomepageFeatures/index.jsx b/packages/docs/src/components/HomepageFeatures/index.jsx index 9d9b1eb5b16..167bdb57735 100644 --- a/packages/docs/src/components/HomepageFeatures/index.jsx +++ b/packages/docs/src/components/HomepageFeatures/index.jsx @@ -41,14 +41,14 @@ const FeatureList = [ }, { icon: '💭', - title: 'Self-Reflection', + title: 'Self-Reflection & Learning', description: ( <> Agents learn from interactions through built-in reflection mechanisms that extract facts, build relationships, and improve responses over time. ), - link: '/docs/core/reflection', + link: '/docs/core/evaluators', }, { icon: '💬', @@ -131,6 +131,11 @@ const QuickActionsList = [ <> Explore the ecosystem of plugins that extend your agent's abilities and integrations across platforms. + ), link: '/packages', @@ -142,9 +147,14 @@ const QuickActionsList = [ <> Browse examples and resources from the community to spark ideas for your next AI agent project. + ), - link: '/docs/intro', + link: '/docs/awesome-eliza', }, ]; @@ -267,7 +277,7 @@ export default function HomepageFeatures({ type = 'features', showUseCases = tru
- + Get Started with Eliza diff --git a/packages/docs/src/components/HomepageHeader/index.jsx b/packages/docs/src/components/HomepageHeader/index.jsx index 092222a5b7e..201d319662f 100644 --- a/packages/docs/src/components/HomepageHeader/index.jsx +++ b/packages/docs/src/components/HomepageHeader/index.jsx @@ -20,7 +20,7 @@ function HomepageHeader() {

{siteConfig.tagline}

- + Get Started
diff --git a/packages/docs/src/css/custom.css b/packages/docs/src/css/custom.css index bc23e77a95e..846b529f8a2 100644 --- a/packages/docs/src/css/custom.css +++ b/packages/docs/src/css/custom.css @@ -1,10 +1,9 @@ /** - * Any CSS included here will be global. The classic template - * bundles Infima by default. Infima is a CSS framework designed to - * work well for content-centric websites. + * Optimized CSS for eliza documentation site + * Performance-focused with reduced transitions and simplified selectors */ -/* You can override the default Infima variables here. */ +/* Base variables - unchanged to maintain visual identity */ :root { --ifm-color-primary: #ffa600; --ifm-color-primary-dark: #e69500; @@ -19,57 +18,46 @@ sans-serif; } -/* Cool dark mode with modern aesthetics and warm accents */ +/* Dark mode variables - simplified */ [data-theme='dark'] { - /* Warmer primary color - orange-blue balance */ - --ifm-color-primary: #ff9500; /* Warm orange as primary */ + --ifm-color-primary: #ff9500; --ifm-color-primary-dark: #e68600; --ifm-color-primary-darker: #d97e00; --ifm-color-primary-darkest: #b36800; --ifm-color-primary-light: #ffa01a; --ifm-color-primary-lighter: #ffaa33; --ifm-color-primary-lightest: #ffb84d; - - /* Accent color for secondary elements - keeping some blue */ - --ifm-color-secondary-dark: #00a3cc; /* Cyan for accents */ - - /* Enhanced backgrounds with warmer undertones */ - --ifm-background-color: #111827; /* Darker blue-gray background */ - --ifm-background-surface-color: #1e293b; /* Surface with slight warmth */ - - /* Text colors */ + --ifm-color-secondary-dark: #00a3cc; + --ifm-background-color: #111827; + --ifm-background-surface-color: #1e293b; --ifm-font-color-base: #f1f5f9; --ifm-heading-color: #ffffff; - - /* Code and doc elements */ - --docusaurus-highlighted-code-line-bg: rgba(255, 149, 0, 0.1); /* Warm highlight */ + --docusaurus-highlighted-code-line-bg: rgba(255, 149, 0, 0.1); --ifm-footer-background-color: #1e293b; --ifm-table-stripe-background: rgba(255, 255, 255, 0.03); --ifm-table-border-color: rgba(255, 255, 255, 0.12); - --ifm-toc-border-color: rgba(255, 149, 0, 0.2); /* Warm accent for TOC */ + --ifm-toc-border-color: rgba(255, 149, 0, 0.2); --ifm-color-emphasis-300: rgba(255, 255, 255, 0.25); - - /* Warm accents */ --warm-accent-light: rgba(255, 149, 0, 0.15); --warm-accent-border: rgba(255, 149, 0, 0.3); } -/* Subtle gradient background for dark mode pages with warmer undertones */ +/* Performance-optimized background */ [data-theme='dark'] .main-wrapper { - background: radial-gradient(circle at 10% 10%, #1e293b 0%, #111827 90%); + background-color: #111827; } +/* Fixed footer color */ .footer { background-color: #161b22; } -/* Cool gradient buttons */ +/* Button styling - minimal transitions */ .button--primary { - background: linear-gradient(135deg, rgb(249, 140, 19) 0%, rgb(255, 166, 0) 100%); + background: linear-gradient(135deg, #f98c13 0%, #ffa600 100%); border: none; padding: 1rem 2rem; font-size: 1.2rem; - transition: all 0.3s ease; color: white; position: relative; z-index: 1; @@ -78,25 +66,26 @@ } .button--primary:hover { - background: linear-gradient(135deg, rgb(255, 156, 43) 0%, rgb(255, 166, 0) 100%); + background: linear-gradient(135deg, #ff9c2b 0%, #ffa600 100%); transform: translateY(-2px); box-shadow: 0 6px 20px 0 rgba(255, 166, 0, 0.3); } [data-theme='dark'] .button--primary { - background: linear-gradient(135deg, rgb(255, 149, 0) 0%, rgb(255, 102, 0) 100%); + background: linear-gradient(135deg, #ff9500 0%, #ff6600 100%); box-shadow: 0 4px 14px 0 rgba(255, 149, 0, 0.25); } [data-theme='dark'] .button--primary:hover { - background: linear-gradient(135deg, rgb(255, 166, 43) 0%, rgb(255, 123, 26) 100%); + background: linear-gradient(135deg, #ffa62b 0%, #ff7b1a 100%); box-shadow: 0 6px 20px 0 rgba(255, 149, 0, 0.3); } +/* Responsive iframe - unchanged */ .responsive-iframe { position: relative; width: 100%; - padding-bottom: 56.25%; /* 16:9 aspect ratio */ + padding-bottom: 56.25%; height: 0; overflow: hidden; background: #000; @@ -114,7 +103,7 @@ border-radius: 8px; } -/* Futuristic API Method badges */ +/* API Method badges - optimized selectors */ .api-method > .menu__link { align-items: center; justify-content: start; @@ -132,46 +121,40 @@ text-align: center; flex-shrink: 0; color: white; - transition: all 0.3s ease; } -/* Modern REST API badges for dark mode with warm accents */ +/* API method badges for dark mode - flat colors for better performance */ [data-theme='dark'] .get > .menu__link::before { content: 'get'; - background: linear-gradient(135deg, #3182ce 0%, #2c5282 100%); + background-color: #3182ce; color: white; - box-shadow: 0 2px 5px rgba(49, 130, 206, 0.3); } [data-theme='dark'] .post > .menu__link::before { content: 'post'; - background: linear-gradient(135deg, #38a169 0%, #276749 100%); + background-color: #38a169; color: white; - box-shadow: 0 2px 5px rgba(56, 161, 105, 0.3); } [data-theme='dark'] .delete > .menu__link::before { content: 'del'; - background: linear-gradient(135deg, #e53e3e 0%, #9b2c2c 100%); + background-color: #e53e3e; color: white; - box-shadow: 0 2px 5px rgba(229, 62, 62, 0.3); } [data-theme='dark'] .put > .menu__link::before { content: 'put'; - background: linear-gradient(135deg, #4299e1 0%, #2b6cb0 100%); + background-color: #4299e1; color: white; - box-shadow: 0 2px 5px rgba(66, 153, 225, 0.3); } [data-theme='dark'] .patch > .menu__link::before { content: 'patch'; - background: linear-gradient(135deg, #ff9500 0%, #c05621 100%); + background-color: #ff9500; color: white; - box-shadow: 0 2px 5px rgba(255, 149, 0, 0.3); } -/* Light mode API badges */ +/* Light mode API badges - simplified */ .get > .menu__link::before { content: 'get'; background-color: var(--ifm-color-primary); @@ -197,11 +180,11 @@ background-color: #f97316; } -/* Cool tables in dark mode with subtle hover effects */ +/* Optimized tables in dark mode */ [data-theme='dark'] table { border-spacing: 0; overflow-x: auto; - display: block; /* Make tables responsive */ + display: block; margin: 1.5em 0; } @@ -211,11 +194,7 @@ font-weight: 600; border-bottom: 2px solid rgba(255, 149, 0, 0.2); padding: 12px 16px; - white-space: nowrap; /* Prevents wrapping in headers */ -} - -[data-theme='dark'] table tr { - transition: background-color 0.2s ease; + white-space: nowrap; } [data-theme='dark'] table tr:nth-child(even) { @@ -231,71 +210,49 @@ padding: 12px 16px; } -/* Stylish sidebar in dark mode */ +/* Performance-optimized sidebar in dark mode */ [data-theme='dark'] .menu { background-color: #161b22; - border-right: 1px solid rgba(255, 255, 255, 0.05); + /* Use box-shadow instead of border for better performance */ + box-shadow: 1px 0 0 rgba(255, 255, 255, 0.05); + /* Hardware acceleration */ + transform: translateZ(0); } +/* Optimized active links - remove transitions */ [data-theme='dark'] .menu__link--active { - background-color: var(--warm-accent-light); + background-color: rgba(255, 149, 0, 0.15); border-left: 3px solid var(--ifm-color-primary); font-weight: 600; + padding-left: calc(var(--ifm-menu-link-padding-horizontal) - 3px); } +/* Simplified hover effect with minimal transition */ [data-theme='dark'] .menu__link:hover { background-color: rgba(255, 255, 255, 0.05); - transition: background-color 0.2s ease; } -/* Modernized navbar */ +/* Optimized navbar */ [data-theme='dark'] .navbar { - background-color: rgba(22, 27, 34, 0.9); - backdrop-filter: blur(10px); - box-shadow: - 0 1px 2px 0 rgba(0, 0, 0, 0.1), - 0 1px 6px 0 rgba(0, 0, 0, 0.05); + background-color: rgba(22, 27, 34, 0.95); + box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.1); } -/* Card styling for dark mode with warm accents */ +/* Card styling for dark mode - optimized */ [data-theme='dark'] .card { background-color: #1e293b; border-radius: 8px; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15); - transition: - transform 0.3s ease, - box-shadow 0.3s ease, - border-color 0.3s ease; border: 1px solid rgba(255, 255, 255, 0.05); overflow: hidden; } [data-theme='dark'] .card:hover { border-color: rgba(255, 149, 0, 0.2); -} - -[data-theme='dark'] .card:hover { transform: translateY(-5px); box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2); } -/* Elegant transitions for dark mode */ -[data-theme='dark'] * { - transition: - background 0.5s ease, - background-color 0.2s ease, - border-color 1s ease, - fill 0.2s ease, - stroke 0.5s ease; -} - -/* Cool announcement bar if you have one */ -[data-theme='dark'] .announcement-bar { - background: linear-gradient(90deg, #161b22 0%, #0d1117 50%, #161b22 100%); - background-size: 200% 100%; - animation: gradient-shift 15s ease infinite; -} - /* Warm accent for blockquotes */ [data-theme='dark'] blockquote { border-left: 3px solid var(--ifm-color-primary); @@ -304,3 +261,41 @@ padding: 1em; border-radius: 0 8px 8px 0; } + +/* Use specific will-change properties only where needed */ +.navbar--fixed-top { + will-change: transform; +} + +.menu__link { + will-change: background-color; +} + +/* Target performance for key interactive components */ +@media (prefers-reduced-motion: no-preference) { + /* Apply transitions only for non-reduced motion users */ + .button--primary { + transition: + transform 0.2s ease, + box-shadow 0.2s ease; + } + + .menu__link:hover { + transition: background-color 0.15s ease; + } + + .card:hover { + transition: + transform 0.2s ease, + box-shadow 0.2s ease, + border-color 0.2s ease; + } +} + +/* Prefers-reduced-motion accommodations */ +@media (prefers-reduced-motion: reduce) { + * { + animation: none !important; + transition: none !important; + } +} diff --git a/packages/docs/src/theme/DocItem/Content/index.js b/packages/docs/src/theme/DocItem/Content/index.js new file mode 100644 index 00000000000..8c2d4b40868 --- /dev/null +++ b/packages/docs/src/theme/DocItem/Content/index.js @@ -0,0 +1,15 @@ +import React from 'react'; +import Content from '@theme-original/DocItem/Content'; +import CopyPageButton from '@site/src/components/CopyPageButton'; +import styles from './styles.module.css'; + +export default function ContentWrapper(props) { + return ( + <> +
+ +
+ + + ); +} diff --git a/packages/docs/src/theme/DocItem/Content/styles.module.css b/packages/docs/src/theme/DocItem/Content/styles.module.css new file mode 100644 index 00000000000..d599fea240a --- /dev/null +++ b/packages/docs/src/theme/DocItem/Content/styles.module.css @@ -0,0 +1,5 @@ +.docItemActions { + display: flex; + justify-content: flex-end; + margin-bottom: 1rem; +} diff --git a/packages/docs/static/blog/notebooklm.jpg b/packages/docs/static/blog/notebooklm.jpg new file mode 100644 index 00000000000..0b90e0e4734 Binary files /dev/null and b/packages/docs/static/blog/notebooklm.jpg differ diff --git a/packages/docs/static/blog/v1-v2.jpg b/packages/docs/static/blog/v1-v2.jpg new file mode 100644 index 00000000000..acb2e1e30b1 Binary files /dev/null and b/packages/docs/static/blog/v1-v2.jpg differ diff --git a/packages/docs/static/img/actions.jpg b/packages/docs/static/img/actions.jpg new file mode 100644 index 00000000000..e6dc8dea9ef Binary files /dev/null and b/packages/docs/static/img/actions.jpg differ diff --git a/packages/docs/static/img/agentruntime.jpg b/packages/docs/static/img/agentruntime.jpg new file mode 100644 index 00000000000..707079ba611 Binary files /dev/null and b/packages/docs/static/img/agentruntime.jpg differ diff --git a/packages/docs/static/img/database.jpg b/packages/docs/static/img/database.jpg new file mode 100644 index 00000000000..fe60770148c Binary files /dev/null and b/packages/docs/static/img/database.jpg differ diff --git a/packages/docs/static/img/eliza-overview.jpg b/packages/docs/static/img/eliza-overview.jpg new file mode 100644 index 00000000000..73b83dc6a1f Binary files /dev/null and b/packages/docs/static/img/eliza-overview.jpg differ diff --git a/packages/docs/static/img/elizaos-rooms-cover.svg b/packages/docs/static/img/elizaos-rooms-cover.svg new file mode 100644 index 00000000000..9109e766a8c --- /dev/null +++ b/packages/docs/static/img/elizaos-rooms-cover.svg @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Rooms + In ElizaOS Framework + + + + + + + + + User + + + Agent + + + + + Conversation + + + + + + Channel A + + + + + + + Thread B + + + + + + + + DM Space + + + + + + + + + + + + + + + + + Room Features + + + + + + + + + + + + + + + + + + + + + + Individual interaction spaces where entities communicate + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/docs/static/img/elizaos-rooms-simplified.svg b/packages/docs/static/img/elizaos-rooms-simplified.svg new file mode 100644 index 00000000000..315df905d92 --- /dev/null +++ b/packages/docs/static/img/elizaos-rooms-simplified.svg @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + Rooms + in ElizaOS + + + + + + + + + + + + # general + # support + # random + # dev + + THREADS + # feature-req + # bug-report + + + + + # support + 3 members + + + + + + User1 + How do I connect my app to ElizaOS? + + + + SupportAgent + You'll need to use our API. I can help you set up... + + + + User2 + I'm having the same issue. Can you share docs? + + + + 3 replies + + + + + Message #support... + + + + + + + Rooms + Like channels in Discord + or Slack workspaces + + + + Threads + Nested conversations + within a room + + + + + + + + + Individual spaces for conversations and interactions + + \ No newline at end of file diff --git a/packages/docs/static/img/elizaos-visualization.svg b/packages/docs/static/img/elizaos-visualization.svg new file mode 100644 index 00000000000..d334230882c --- /dev/null +++ b/packages/docs/static/img/elizaos-visualization.svg @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ElizaOS Architecture + + + + + + + + World A + + + + Room 1 + + + Room 2 + + + Room 3 + + + + + + + + + + + + + + + + + World B + + + + Room 1 + + + Room 2 + + + + + + + + + + + + + + + Independent Room + + + + + + + + + + + + + + + + + + + Legend: + + + World + + + Room + + + User + + + Agent + + + Connection + + + + + Worlds contain multiple rooms + Rooms host entities (users/agents) + Entities interact across rooms + Rooms can exist independently + + \ No newline at end of file diff --git a/packages/docs/static/img/elizaos-worlds-cosmic-clean.svg b/packages/docs/static/img/elizaos-worlds-cosmic-clean.svg new file mode 100644 index 00000000000..c3679bd02f6 --- /dev/null +++ b/packages/docs/static/img/elizaos-worlds-cosmic-clean.svg @@ -0,0 +1,203 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Worlds + In ElizaOS Framework + + + + + + DEV + + + + + #general + + + #bugs + + + #roadmap + + + #support + + + + + + + + QA + + + + + #tests + + + #reports + + + + + + + + PROD + + + + + #main + + + #help + + + #status + + + + + + + + AI + + + + + #models + + + #data + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Legend + + + World + + + Room + + + User + + + Agent + + + + + Virtual environments hosting rooms and entities + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/docs/static/img/elizaos-worlds-cosmic.svg b/packages/docs/static/img/elizaos-worlds-cosmic.svg new file mode 100644 index 00000000000..398bbc4d45d --- /dev/null +++ b/packages/docs/static/img/elizaos-worlds-cosmic.svg @@ -0,0 +1,215 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Worlds + In ElizaOS Framework + + + + + + DEV + + + + + #general + + + #bugs + + + #roadmap + + + #support + + + + + + + + QA + + + + + + + + + + + + + PROD + + + + + #main + + + #help + + + + + + + + + + AI + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Worlds + Like Discord servers or Slack workspaces + Each with their own purpose + + + + Connected Environments + Worlds can share information + and entities can move between them + + + + + + Legend: + + + World + + + Room + + + User + + + Agent + + + + + Virtual environments hosting rooms and entities for specific purposes + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/docs/static/img/elizaos-worlds-cover.svg b/packages/docs/static/img/elizaos-worlds-cover.svg new file mode 100644 index 00000000000..62327a78c4f --- /dev/null +++ b/packages/docs/static/img/elizaos-worlds-cover.svg @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Worlds + In ElizaOS Framework + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Virtual environments hosting interconnected rooms and entities + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/docs/static/img/elizaos-worlds-simplified.svg b/packages/docs/static/img/elizaos-worlds-simplified.svg new file mode 100644 index 00000000000..ab17d2e5cce --- /dev/null +++ b/packages/docs/static/img/elizaos-worlds-simplified.svg @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + Worlds + in ElizaOS + + + + + + + + + DEV + + + AI + + + PROD + + + QA + + + GAME + + + + + + + + + + + + + AI Research World + + + + TEXT CHANNELS + + # welcome + # announcements + # general + # support + # research + + VOICE CHANNELS + 🔊 Meeting Room + + + MEMBERS (8) + + + User1 + + + User2 + + + ResearchAgent + + + AssistantBot + + + User3 + + + User4 + + + + + + + + Worlds + Like Discord servers or + Slack workspaces + + + + Rooms within Worlds + Like channels in a server + for specific discussions + + + + + + + + + Virtual environments containing multiple rooms and entities + + \ No newline at end of file diff --git a/packages/docs/static/img/entities-component-architecture.svg b/packages/docs/static/img/entities-component-architecture.svg new file mode 100644 index 00000000000..8c0dba57f08 --- /dev/null +++ b/packages/docs/static/img/entities-component-architecture.svg @@ -0,0 +1,192 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Entities + + + + + + + + User + + + + + + + + Agent + + + + + + + + + Components + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Entity + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/docs/static/img/entities.jpg b/packages/docs/static/img/entities.jpg new file mode 100644 index 00000000000..c8150f9f6b8 Binary files /dev/null and b/packages/docs/static/img/entities.jpg differ diff --git a/packages/docs/static/img/evaluators.jpg b/packages/docs/static/img/evaluators.jpg new file mode 100644 index 00000000000..32e9572fe70 Binary files /dev/null and b/packages/docs/static/img/evaluators.jpg differ diff --git a/packages/docs/static/img/knowledge.jpg b/packages/docs/static/img/knowledge.jpg new file mode 100644 index 00000000000..179d3ba6fc9 Binary files /dev/null and b/packages/docs/static/img/knowledge.jpg differ diff --git a/packages/docs/static/img/plugins.jpg b/packages/docs/static/img/plugins.jpg new file mode 100644 index 00000000000..72f25d01c0d Binary files /dev/null and b/packages/docs/static/img/plugins.jpg differ diff --git a/packages/docs/static/img/project.jpg b/packages/docs/static/img/project.jpg new file mode 100644 index 00000000000..6d7607176b0 Binary files /dev/null and b/packages/docs/static/img/project.jpg differ diff --git a/packages/docs/static/img/providers.jpg b/packages/docs/static/img/providers.jpg new file mode 100644 index 00000000000..7f7b46967c3 Binary files /dev/null and b/packages/docs/static/img/providers.jpg differ diff --git a/packages/docs/static/img/rooms.jpg b/packages/docs/static/img/rooms.jpg new file mode 100644 index 00000000000..87c48406f71 Binary files /dev/null and b/packages/docs/static/img/rooms.jpg differ diff --git a/packages/docs/static/img/services.jpg b/packages/docs/static/img/services.jpg new file mode 100644 index 00000000000..3c9a9403957 Binary files /dev/null and b/packages/docs/static/img/services.jpg differ diff --git a/packages/docs/static/img/tasks.jpg b/packages/docs/static/img/tasks.jpg new file mode 100644 index 00000000000..308f27cddd6 Binary files /dev/null and b/packages/docs/static/img/tasks.jpg differ diff --git a/packages/docs/static/img/worlds.jpg b/packages/docs/static/img/worlds.jpg new file mode 100644 index 00000000000..3e7a9d7cc37 Binary files /dev/null and b/packages/docs/static/img/worlds.jpg differ diff --git a/packages/docs/static/llms-full.txt b/packages/docs/static/llms-full.txt index 59546c859c1..ebcdf94fa00 100644 --- a/packages/docs/static/llms-full.txt +++ b/packages/docs/static/llms-full.txt @@ -30,7 +30,7 @@ The content is organized as follows: ## Notes - Some files may have been excluded based on .gitignore rules and Repomix's configuration - Binary files are not included in this packed representation. Please refer to the Repository Structure section for a complete list of file paths, including binary files -- Only files matching these patterns are included: packages/docs/docs/core/overview.md, packages/docs/docs/quickstart.md, packages/docs/docs/core/actions.md, packages/docs/docs/core/knowledge.md, packages/docs/docs/core/database.md, packages/core/src/types.ts, packages/core/src/runtime.ts, packages/core/src/bootstrap.ts, packages/core/src/database.ts, packages/core/src/actions.ts, packages/core/src/entities.ts, packages/core/src/prompts.ts, packages/core/src/uuid.ts, packages/core/src/logger.ts, packages/core/src/providers/actions.ts, packages/core/src/providers/character.ts, packages/core/src/providers/knowledge.ts, packages/core/src/providers/recentMessages.ts, packages/core/src/providers/relationships.ts, packages/core/src/providers/evaluators.ts, packages/core/src/providers/settings.ts, packages/core/src/actions/reply.ts, packages/core/src/actions/sendMessage.ts, packages/cli/src/index.ts, packages/cli/src/commands/agent.ts, packages/cli/src/commands/start.ts, packages/cli/src/commands/test.ts, packages/cli/src/commands/create.ts, packages/cli/src/commands/env.ts, packages/client/src/lib/api.ts, packages/client/src/types/index.ts, packages/client/src/hooks/use-agent-management.ts, README.md, package.json, .env.example +- Only files matching these patterns are included: packages/docs/docs/core/overview.md, packages/docs/docs/quickstart.md, packages/docs/docs/core/actions.md, packages/docs/docs/core/agents.md, packages/docs/docs/core/database.md, packages/docs/docs/core/entities.md, packages/docs/docs/core/evaluators.md, packages/docs/docs/core/knowledge.md, packages/docs/docs/core/plugins.md, packages/docs/docs/core/project.md, packages/docs/docs/core/providers.md, packages/docs/docs/core/rooms.md, packages/docs/docs/core/services.md, packages/docs/docs/core/tasks.md, packages/docs/docs/core/worlds.md, packages/docs/src/openapi/eliza-v1.yaml, packages/core/src/types.ts, packages/core/src/runtime.ts, packages/core/src/bootstrap.ts, packages/core/src/database.ts, packages/core/src/actions.ts, packages/core/src/entities.ts, packages/core/src/prompts.ts, packages/core/src/uuid.ts, packages/core/src/logger.ts, packages/core/src/providers/actions.ts, packages/core/src/providers/character.ts, packages/core/src/providers/knowledge.ts, packages/core/src/providers/recentMessages.ts, packages/core/src/providers/relationships.ts, packages/core/src/providers/evaluators.ts, packages/core/src/providers/settings.ts, packages/core/src/actions/reply.ts, packages/core/src/actions/sendMessage.ts, packages/cli/src/index.ts, packages/cli/src/commands/agent.ts, packages/cli/src/commands/start.ts, packages/cli/src/commands/test.ts, packages/cli/src/commands/create.ts, packages/cli/src/commands/env.ts, packages/client/src/lib/api.ts, packages/client/src/types/index.ts, packages/client/src/hooks/use-agent-management.ts, README.md, package.json, .env.example - Files matching these patterns are excluded: **/*.test.ts, **/__tests__/**, **/node_modules/**, packages/docs/community/**, packages/docs/news/**, packages/plugin-*/**, **/*.ico, **/*.png, **/*.jpg, **/*.svg - Files matching patterns in .gitignore are excluded - Files matching default ignore patterns are excluded @@ -88,10 +88,23 @@ packages/ docs/ core/ actions.md + agents.md database.md + entities.md + evaluators.md knowledge.md overview.md + plugins.md + project.md + providers.md + rooms.md + services.md + tasks.md + worlds.md quickstart.md + src/ + openapi/ + eliza-v1.yaml .env.example package.json README.md @@ -109,15 +122,46 @@ import { logger } from '@elizaos/core'; import type { Agent } from '@elizaos/core'; import { Command } from 'commander'; ⋮---- +// Define basic agent interface for type safety +/** + * Defines the structure of AgentBasic interface. + * @property {string} id - The unique identifier of the agent. + * @property {string} name - The name of the agent. + * @property {string} [status] - The status of the agent (optional). + * @property {unknown} [key] - Additional properties can be added dynamically using any key. + */ interface AgentBasic { id: string; name: string; status?: string; [key: string]: unknown; } +/** + * Asynchronously fetches a list of basic agent information from the server. + * @returns {Promise} A promise that resolves to an array of AgentBasic objects. + * @throws {Error} If the fetch request fails. + */ async function getAgents(): Promise +// Utility function to resolve agent ID from name, index, or direct ID +/** + * Resolves the ID of an agent based on the provided name, ID, or index. + * + * @param {string} idOrNameOrIndex - The name, ID, or index of the agent to resolve. + * @returns {Promise} The resolved ID of the agent. + * @throws {Error} If the agent is not found. + */ async function resolveAgentId(idOrNameOrIndex: string): Promise ⋮---- +// First try to get all agents to find by name +⋮---- +// Try to find agent by name +⋮---- +// Try to find agent by ID +⋮---- +// Try to find agent by index +⋮---- +// If no agent is found, throw an error +⋮---- interface AgentStartPayload { characterPath?: string; characterJson?: Record; @@ -131,18 +175,10 @@ interface ApiResponse { details?: unknown; }; } -interface AgentStartResponse { - id: string; - character: Partial; -} ```` ## File: packages/cli/src/commands/create.ts ````typescript -import { existsSync, readFileSync } from 'node:fs'; -import fs from 'node:fs/promises'; -import os from 'node:os'; -import path from 'node:path'; import { buildProject } from '@/src/utils/build-project'; import { copyTemplate } from '@/src/utils/copy-template'; import { handleError } from '@/src/utils/handle-error'; @@ -150,19 +186,18 @@ import { runBunCommand } from '@/src/utils/run-bun'; import { logger } from '@elizaos/core'; import { Command } from 'commander'; import { execa } from 'execa'; +import { existsSync, readFileSync } from 'node:fs'; +import fs from 'node:fs/promises'; +import os from 'node:os'; +import path from 'node:path'; import prompts from 'prompts'; import colors from 'yoctocolors'; import { z } from 'zod'; +import { displayBanner } from '../displayBanner'; +import { setupPgLite, promptAndStorePostgresUrl, getElizaDirectories } from '../utils/get-config'; ⋮---- async function getLocalAvailableDatabases(): Promise async function installDependencies(targetDir: string) -async function storePostgresUrl(url: string): Promise -function isValidPostgresUrl(url: string): boolean -async function promptAndStorePostgresUrl(): Promise -⋮---- -// Prompt for postgres url with simpler message -⋮---- -// Parse options but use "" as the default for type to force prompting ⋮---- // Prompt for project type if not specified ⋮---- @@ -222,17 +257,16 @@ import { stringToUuid, } from '@elizaos/core'; import { Command } from 'commander'; -⋮---- import fs from 'node:fs'; -import os from 'node:os'; import path, { dirname } from 'node:path'; import { fileURLToPath } from 'node:url'; import { character as defaultCharacter } from '../characters/eliza'; import { displayBanner } from '../displayBanner'; import { AgentServer } from '../server/index'; import { jsonToCharacter, loadCharacterTryPath } from '../server/loader'; -import { loadConfig, saveConfig } from '../utils/config-manager'; -import { promptForEnvVars } from '../utils/env-prompt'; +import { loadConfig, saveConfig } from '../utils/config-manager.js'; +import { promptForEnvVars } from '../utils/env-prompt.js'; +import { configureDatabaseSettings, loadEnvironment } from '../utils/get-config'; import { handleError } from '../utils/handle-error'; import { installPlugin } from '../utils/install-plugin'; ⋮---- @@ -295,12 +329,12 @@ import { Command } from 'commander'; import { existsSync } from 'node:fs'; ⋮---- import path from 'node:path'; -import { loadProject } from '../project'; -import { AgentServer } from '../server/index'; +import { loadProject } from '../project.js'; +import { AgentServer } from '../server/index.js'; import { jsonToCharacter, loadCharacterTryPath } from '../server/loader'; -import { TestRunner } from '../testRunner'; -import { promptForEnvVars } from '../utils/env-prompt'; -import { startAgent } from './start'; +import { TestRunner } from '../testRunner.js'; +import { promptForEnvVars } from '../utils/env-prompt.js'; +import { startAgent } from './start.js'; async function checkPortAvailable(port: number): Promise function checkIfLikelyPluginDir(dir: string): boolean const runAgentTests = async (options: { @@ -491,6 +525,7 @@ import { getEntityDetails } from '../entities'; import { addHeader, formatMessages, formatPosts } from '../prompts'; import { ChannelType, + CustomMetadata, type Entity, type IAgentRuntime, type Memory, @@ -510,9 +545,22 @@ const getRecentInteractions = async ( ⋮---- // Get unique entity IDs that aren't the runtime agent ⋮---- +// Create a Set for faster lookup +⋮---- +// Add entities already fetched in entitiesData to the map +⋮---- +// Get the remaining entities that weren't already loaded +// Use Set difference for efficient filtering +⋮---- +// Only fetch the entities we don't already have +⋮---- +// Format recent message interactions const getRecentMessageInteractions = async ( recentInteractionsData: Memory[] ): Promise => +⋮---- +// Format messages using the pre-fetched entities +⋮---- const getRecentPostInteractions = async ( recentInteractionsData: Memory[], entities: Entity[] @@ -919,10 +967,13 @@ write(data: string | LogEntry): void recentLogs(): LogEntry[] clear(): void ⋮---- +const createPrettyConfig = () => ( const createStream = async () => ⋮---- logMethod(inputArgs: [string | Record, ...unknown[]], method: LogFn): void ⋮---- +const formatError = (err: Error) => ( +⋮---- interface LoggerWithClear extends pino.Logger { clear: () => void; } @@ -3149,6 +3200,308 @@ Yes! You can create a plugin that defines new actions and then add that plugin t - [Services](./services.md) ```` +## File: packages/docs/docs/core/agents.md +````markdown +# 🤖 Agent Runtime + +The `AgentRuntime` is the core runtime environment for Eliza agents. It handles message processing, state management, plugin integration, and interaction with external services. You can think of it as the brains that provide the high-level orchestration layer for Eliza agents. + +```mermaid +sequenceDiagram + actor User + participant Platform as Platform + participant Runtime as Runtime + participant State as State + participant P as Providers + participant A as Actions + participant M as Models + participant E as Evaluators + participant DB as Database + + User->>Platform: Message + Platform->>Runtime: Forward + + %% Context building (condensed) + Runtime->>State: Get context + State->>P: Gather data + Note over P: Character, Knowledge,
Messages, Time, etc. + P-->>State: Context data + State-->>Runtime: Assembled context + + %% Action flow (condensed) + Runtime->>A: Execute action + A->>M: Generate content + M-->>A: Generated text + A-->>Runtime: Result + + %% Evaluation (condensed) + Runtime->>E: Analyze + E->>DB: Store insights + E-->>Runtime: Evaluation + + %% Delivery + Runtime->>Platform: Response + Platform->>User: Deliver + + %% Background (simplified) + par Background + Runtime->>Runtime: Tasks & Events + end +``` + +The runtime follows this general flow: + +1. **Initial Reception**: The user sends a message which is received by the Platform Services +2. **Context Building**: + + - The Runtime Core requests context from the State Composition system + - State gathers data from various Providers (Character, Knowledge, Recent Messages, etc.) + - The complete context is returned to the Runtime + +3. **Action Processing**: + + - The Runtime determines applicable actions and selects the optimal one + - The selected action may request content generation from Models + - The action result is returned to the Runtime + +4. **Learning & Persistence**: + + - The conversation is analyzed by Evaluators for insights and facts + - Knowledge updates are sent to the Memory System + - All relevant data is persisted to the Database + +5. **Response Delivery**: + - The final response is sent back to the user through Platform Services + +--- + +## Overview + +The [AgentRuntime](/api/classes/AgentRuntime) class is the primary implementation of the [IAgentRuntime](/api/interfaces/IAgentRuntime) interface, which manages the agent's core functions, including: + +| Component | Description | API Reference | Related Files | +| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Services** | Supports multiple communication platforms and specialized functionalities for seamless interaction. | [Services API](/api/interfaces/IAgentRuntime/#services) | [`service.ts`](https://github.com/elizaOS/eliza/tree/develop/packages/core/src/service.ts), [`Discord`](https://github.com/elizaos-plugins/plugin-discord), [`Telegram`](https://github.com/elizaos-plugins/plugin-telegram), [`Twitter`](https://github.com/elizaos-plugins/plugin-twitter), [`Farcaster`](https://github.com/elizaos-plugins/plugin-farcaster), [`Lens`](https://github.com/elizaos-plugins/plugin-lens), [`Slack`](https://github.com/elizaos-plugins/plugin-slack), [`Auto`](https://github.com/elizaos-plugins/plugin-auto), [`GitHub`](https://github.com/elizaos-plugins/plugin-github) | +| **State** | Maintains context for coherent cross-platform interactions, updates dynamically. Also tracks goals, knowledge, and recent interactions | [State API](/api/interfaces/State) | [`state.ts`](https://github.com/elizaos/runtime/state.ts) | +| **Plugins** | Dynamic extensions of agent functionalities using custom actions, evaluators, providers, and adapters | [Plugins API](/api/type-aliases/Plugin/) | [`plugins.ts`](https://github.com/elizaos/runtime/plugins.ts), [actions](../actions), [evaluators](../evaluators), [providers](../providers) | +| **Services** | Connects with external services for `IMAGE_DESCRIPTION`, `TRANSCRIPTION`, `TEXT_GENERATION`, `SPEECH_GENERATION`, `VIDEO`, `PDF`, `BROWSER`, `WEB_SEARCH`, `EMAIL_AUTOMATION`, and more | [Services API](/api/interfaces/IAgentRuntime/#services) | [`services.ts`](https://github.com/elizaos/runtime/services.ts) | +| **Memory Systems** | Creates, retrieves, and embeds memories and manages conversation history. | [Memory API](/api/interfaces/IMemoryManager) | [`memory.ts`](https://github.com/elizaos/runtime/memory.ts) | +| **Database Adapters** | Persistent storage and retrieval for memories and knowledge | [databaseAdapter](api/interfaces/IAgentRuntime/#databaseAdapter) | [`MongoDB`](https://github.com/elizaos-plugins/adapter-mongodb), [`PostgreSQL`](https://github.com/elizaos-plugins/adapter-postgres), [`SQLite`](https://github.com/elizaos-plugins/adapter-sqlite), [`Supabase`](https://github.com/elizaos-plugins/adapter-supabase), [`PGLite`](https://github.com/elizaos-plugins/adapter-pglite), [`Qdrant`](https://github.com/elizaos-plugins/adapter-qdrant), [`SQL.js`](https://github.com/elizaos-plugins/adapter-sqljs) | +| **Cache Management** | Provides flexible storage and retrieval via various caching methods. | [Cache API](/api/interfaces/ICacheManager) | [`cache.ts`](https://github.com/elizaos/runtime/cache.ts) | + +
+Advanced: IAgentRuntime Interface +```typescript +interface IAgentRuntime { + // Core identification + agentId: UUID; + + // Configuration + character: Character; // Personality and behavior settings + + // Components + plugins: Plugin[]; // Additional capabilities + services: Map; // Platform connections and functionality + providers: Provider[]; // Real-time data sources + actions: Action[]; // Available behaviors + evaluators: Evaluator[]; // Analysis & learning + routes: Route[]; // API endpoints + + // Memory Management + getMemories(...): Promise; // Retrieve conversation history + createMemory(...): Promise; // Store new memories + searchMemories(...): Promise; // Semantic search + + // State Composition + composeState(...): Promise; // Gather data from providers + + // Plugin Management + registerPlugin(...): Promise; // Register plugins + + // Service Management + getService(...): T | null; // Access services + registerService(...): Promise; // Register services + + // Model Integration + useModel(...): Promise; // Use AI models + + // Additional Utilities + getSetting(...): any; // Access settings + setSetting(...): void; // Configure settings + getCache(...): Promise; // Access cached data + setCache(...): Promise; // Store cached data +} +``` + +Source: [/api/interfaces/IAgentRuntime/](/api/interfaces/IAgentRuntime/) + +
+ +--- + +### **Key Methods** + +- **`initialize()`**: Sets up the agent's runtime environment, including services, plugins, and knowledge processing. +- **`processActions()`**: Executes actions based on message content and state. +- **`evaluate()`**: Assesses messages and state using registered evaluators. +- **`composeState()`**: Constructs the agent's state object for response generation. +- **`registerService()`**: Adds a service to the runtime. +- **`getService()`**: Retrieves a registered service by type. +- **`useModel()`**: Utilizes AI models with typesafe parameters and results. +- **`ensureRoomExists()` / `ensureConnection()`**: Ensures the existence of communication channels and connections. + +## Service System + +Services provide specialized functionality with standardized interfaces that can be accessed cross-platform: + +```typescript +// Speech Generation +const speechService = runtime.getService('speech_generation'); +const audioStream = await speechService.process(text); + +// PDF Processing +const pdfService = runtime.getService('pdf'); +const textContent = await pdfService.convertPdfToText(pdfBuffer); + +// Discord Integration +const discordService = runtime.getService('discord'); +await discordService.sendMessage(channelId, content); +``` + +--- + +## State Management + +The runtime maintains comprehensive state through the State interface: + +```typescript +interface State { + // Core state data + values: { + [key: string]: any; + }; + data: { + [key: string]: any; + }; + text: string; +} + +// State composition example +async function manageState() { + // Initial state composition with all regular providers + const state = await runtime.composeState(message); + + // State with specific providers only + const filteredState = await runtime.composeState(message, ['timeProvider', 'recentMessages']); + + // Include private or dynamic providers + const enhancedState = await runtime.composeState(message, null, [ + 'weatherProvider', + 'portfolioProvider', + ]); +} +``` + +--- + +## Plugin System + +Plugins extend agent functionality through a modular interface. The runtime supports various types of plugins including services, adapters, actions, and more: + +```typescript +interface Plugin { + name: string; + description: string; + init?: (config: Record, runtime: IAgentRuntime) => Promise; + + // Components + services?: (typeof Service)[]; // Communication platforms and external integrations + actions?: Action[]; // Custom behaviors + providers?: Provider[]; // Data providers + evaluators?: Evaluator[]; // Response assessment + adapters?: Adapter[]; // Database/cache adapters + routes?: Route[]; // API endpoints + tests?: TestSuite[]; // Testing utilities +} +``` + +Plugins can be configured through [characterfile](./characterfile) settings: + +```json +{ + "name": "MyAgent", + "plugins": ["@elizaos/plugin-solana", "@elizaos/plugin-twitter"], + "settings": { + "twitter": { + "shouldRespondToMentions": true + }, + "solana": { + "enableAutoTrading": false + } + } +} +``` + +For detailed information about plugin development and usage, see the [ElizaOS Registry](https://github.com/elizaos-plugins/registry). + +--- + +## Running Multiple Agents + +To run multiple agents: + +```bash +bun start --characters="characters/agent1.json,characters/agent2.json" +``` + +Or use environment variables: + +``` +REMOTE_CHARACTER_URLS=https://example.com/characters.json +``` + +--- + +## FAQ + +### What's the difference between an agent and a character? + +A character defines personality and knowledge, while an agent provides the runtime environment and capabilities to bring that character to life. + +### How do I choose the right database adapter? + +Choose based on your needs: + +- MongoDB: For scalable, document-based storage +- PostgreSQL: For relational data with complex queries +- SQLite: For simple, file-based storage +- Qdrant: For vector search capabilities + +### How do I implement custom plugins? + +Create a plugin that follows the plugin interface and register it with the runtime. See the plugin documentation for detailed examples. + +### Do agents share memory across platforms? + +By default, agents maintain separate memory contexts for different platforms to avoid mixing conversations. Use the memory management system and database adapters to persist and retrieve state information. + +### How do I handle multiple authentication methods? + +Use the character configuration to specify different authentication methods for different services. The runtime will handle the appropriate authentication flow. + +### How do I manage environment variables? + +Use a combination of: + +- `.env` files for local development +- Character-specific settings for per-agent configuration +- Environment variables for production deployment + +### Can agents communicate with each other? + +Yes, through the message system and shared memory spaces when configured appropriately. +```` + ## File: packages/docs/docs/core/database.md ````markdown --- @@ -3161,11 +3514,49 @@ The ElizaOS database system provides persistent storage capabilities for agents. ## Overview +```mermaid +graph TB + %% Main Components + Runtime([Agent Runtime]) + DbAdapter([Database Adapter]) + DbConnection[("Database (PGLite/PostgreSQL)")] + + %% Data Models in compact form + DataModels["Data Models:\n Entities, Components\n Memories, Relationships\n Rooms, Worlds, Tasks\n Cache"] + + %% Vector Search + VectorStore[(Vector Store)] + + %% Memories Knowledge + MemoriesKnowledge[(Memories / Knowledge)] + + %% Connection flow + Runtime -->|Uses| DbAdapter + DbAdapter -->|Connects to| DbConnection + DbConnection -->|Stores & Retrieves| DataModels + + %% Connect Vector Store + DbConnection -->|Utilizes| VectorStore + VectorStore -->|Enables Search on| MemoriesKnowledge + + %% Styling + classDef default fill:#f0f4f8,stroke:#2c3e50,stroke-width:1px; + classDef runtime fill:#3498db,stroke:#2c3e50,stroke-width:1px,color:#fff; + classDef adapter fill:#9b59b6,stroke:#2c3e50,stroke-width:1px,color:#fff; + classDef db fill:#27ae60,stroke:#2c3e50,stroke-width:1px,color:#fff; + classDef datamodels fill:#52be80,stroke:#2c3e50,stroke-width:1px,color:#fff; + + class Runtime runtime; + class DbAdapter adapter; + class DbConnection,VectorStore db; + class DataModels datamodels; +``` + ElizaOS uses a unified database architecture based on Drizzle ORM with adapters that implement the [`IDatabaseAdapter`](/api/interfaces/IDatabaseAdapter) interface. The current release includes support for: | Adapter | Best For | Key Features | | -------------- | --------------------------- | ----------------------------------------------------------------- | -| **PGLite** | Local development & testing | Lightweight PostgreSQL implementation running in Node process | +| **PGLite** | Local development & testing | Lightweight PostgreSQL implementation running in Node.js process | | **PostgreSQL** | Production deployments | Full PostgreSQL with vector search, scaling, and high reliability | Additional database adapters will be supported in future releases as ElizaOS continues to evolve. @@ -3562,7 +3953,7 @@ Yes, future releases will add support for additional databases such as: - SQLite - Supabase - Qdrant -- SQL +- SQL.js The adapter interface is designed to be extensible to support a wide range of storage solutions. @@ -3573,734 +3964,4193 @@ The adapter interface is designed to be extensible to support a wide range of st - [Agent Runtime](./agents.md) ```` -## File: packages/docs/docs/core/knowledge.md +## File: packages/docs/docs/core/entities.md ````markdown -# Knowledge Management in ElizaOS - -## Overview +--- +sidebar_position: 9 +--- -The Knowledge Management system in ElizaOS is a powerful Retrieval-Augmented Generation (RAG) feature that enables agents to process, store, and retrieve information from various sources. This allows agents to provide contextually relevant responses by leveraging stored knowledge during conversations. +# Entities -## Adding Knowledge to Agents +Entities in ElizaOS represent users, agents, or any participant that can interact within the system. They form the basis of the entity-component architecture, allowing for flexible data modeling and relationships across the platform. -ElizaOS provides multiple ways to add knowledge to your agents, both during initialization and at runtime. +## Entity Structure -### Adding Knowledge During Runtime Creation +An entity in ElizaOS has the following properties: -#### 1. Via Character Definition +```typescript +interface Entity { + /** Unique identifier, optional on creation */ + id?: UUID; -The simplest approach is to define knowledge directly in your character configuration: + /** Names of the entity */ + names: string[]; -```typescript -const character: Character = { - name: 'My Agent', - // Other character properties... - knowledge: [ - // Direct string knowledge - 'Important fact: ElizaOS supports multiple knowledge formats', + /** Optional additional metadata */ + metadata?: { [key: string]: any }; - // File references - { path: 'knowledge/documentation.md', shared: false }, + /** Agent ID this account is related to, for agents should be themselves */ + agentId: UUID; - // Directory references - { directory: 'knowledge/guides', shared: true }, - ], -}; + /** Optional array of components */ + components?: Component[]; +} ``` -The knowledge array supports three formats: - -- String literals for direct knowledge -- File objects pointing to specific files -- Directory objects for entire folders of content +| Property | Description | +| ------------ | -------------------------------------------------------- | +| `id` | Unique identifier for the entity (optional on creation) | +| `names` | Array of names the entity is known by | +| `metadata` | Additional information about the entity | +| `agentId` | ID of the agent related to this entity | +| `components` | Array of modular data components attached to this entity | -#### 2. Programmatically Before Runtime Initialization +## Components -You can dynamically load knowledge before creating your runtime: +Components are modular pieces of data attached to entities with the following structure: ```typescript -// Load knowledge from files or other sources -const knowledge = []; - -// Example: Recursively load documentation files -function loadDocumentation(directoryPath) { - const files = getFilesRecursively(directoryPath, ['.md']); - return files.map((filePath) => { - const relativePath = path.relative(basePath, filePath); - const content = fs.readFileSync(filePath, 'utf-8'); - return `Path: ${relativePath}\n\n${content}`; - }); +interface Component { + id: UUID; + entityId: UUID; + agentId: UUID; + roomId: UUID; + worldId: UUID; + sourceEntityId: UUID; + type: string; + data: { + [key: string]: any; + }; } +``` -// Load documentation -const docKnowledge = loadDocumentation('./docs'); -knowledge.push(...docKnowledge); +| Property | Description | +| ---------------- | ------------------------------------------------- | +| `id` | Unique identifier for the component | +| `entityId` | ID of the entity this component belongs to | +| `agentId` | ID of the agent managing this component | +| `roomId` | ID of the room this component is associated with | +| `worldId` | ID of the world this component is associated with | +| `sourceEntityId` | ID of the entity that created this component | +| `type` | Type of component (e.g., "profile", "settings") | +| `data` | Additional data specific to this component type | -// Then include in your character definition -const character: Character = { - // Other character properties... - knowledge: knowledge, -}; -``` +## Entity Creation and Management -### Adding Knowledge After Runtime Creation +### Creating an Entity -#### 1. Using the `addKnowledge` Method +```typescript +const entityId = await runtime.createEntity({ + names: ['John Doe', 'JohnD'], + agentId: runtime.agentId, + metadata: { + discord: { + username: 'john_doe', + name: 'John Doe', + }, + }, +}); +``` -Add knowledge programmatically after the runtime is initialized: +### Retrieving an Entity ```typescript -// Import needed utilities -import { createUniqueUuid } from '@elizaos/core'; +// Get an entity by ID +const entity = await runtime.getEntityById(entityId); -// Create a knowledge item -const knowledgeItem = { - id: createUniqueUuid(runtime, 'unique-knowledge-identifier'), - content: { - text: 'Important information the agent should know...', - }, -}; +// Get all entities in a room +const entitiesInRoom = await runtime.getEntitiesForRoom(roomId, true); // true to include components +``` -// Add to runtime with default chunking settings -await runtime.addKnowledge(knowledgeItem); +### Updating an Entity -// Or with custom chunking settings -await runtime.addKnowledge(knowledgeItem, { - targetTokens: 1500, // Target chunk size (default: 3000) - overlap: 100, // Overlap between chunks (default: 200) - modelContextSize: 8192, // Context size of your model (default: 4096) +```typescript +await runtime.updateEntity({ + id: entityId, + names: [...entity.names, 'Johnny'], + metadata: { + ...entity.metadata, + customProperty: 'value', + }, }); ``` -#### 2. Processing Files at Runtime +## Component Management -You can dynamically process files at runtime: +Components allow for flexible data modeling by attaching different types of data to entities. + +### Creating a Component ```typescript -// For PDF files, use the PDF service -const pdfService = runtime.getService('pdf'); -if (pdfService) { +await runtime.createComponent({ + id: componentId, + entityId: entityId, + agentId: runtime.agentId, + roomId: roomId, + worldId: worldId, + sourceEntityId: creatorEntityId, + type: 'profile', + data: { + bio: 'Software developer interested in AI', + location: 'San Francisco', + website: 'https://example.com', + }, +}); +``` + +### Retrieving Components + +```typescript +// Get a specific component type +const profileComponent = await runtime.getComponent( + entityId, + 'profile', + worldId, // optional filter by world + sourceEntityId // optional filter by source +); + +// Get all components for an entity +const allComponents = await runtime.getComponents(entityId, worldId, sourceEntityId); +``` + +### Updating Components + +```typescript +await runtime.updateComponent({ + id: profileComponent.id, + data: { + ...profileComponent.data, + bio: 'Updated bio information', + }, +}); +``` + +### Deleting Components + +```typescript +await runtime.deleteComponent(componentId); +``` + +## Entity Relationships + +Entities can have relationships with other entities, stored in the database: + +```typescript +// Create a relationship between entities +await runtime.createRelationship({ + sourceEntityId: entityId1, + targetEntityId: entityId2, + tags: ['friend', 'collaborator'], + metadata: { + interactions: 5, + lastInteraction: Date.now(), + }, +}); + +// Get relationships for an entity +const relationships = await runtime.getRelationships({ + entityId: entityId1, + tags: ['friend'], // optional filter by tags +}); + +// Get a specific relationship +const relationship = await runtime.getRelationship({ + sourceEntityId: entityId1, + targetEntityId: entityId2, +}); + +// Update a relationship +await runtime.updateRelationship({ + ...relationship, + metadata: { + ...relationship.metadata, + interactions: relationship.metadata.interactions + 1, + lastInteraction: Date.now(), + }, +}); +``` + +## Entity Resolution + +ElizaOS includes a system for resolving entity references from messages and context. This is particularly useful for determining which entity is being referenced in a conversation. + +```typescript +// Find an entity by name or reference +const entity = await findEntityByName(runtime, message, state); +``` + +The entity resolution system considers: + +1. Exact matches by ID or username +2. Contextual matches from recent conversations +3. Relationship strength between entities +4. Role-based permissions in worlds + +## Entity Details + +To get formatted information about entities in a room: + +```typescript +// Get detailed information about entities in a room +const entityDetails = await getEntityDetails({ + runtime, + roomId, +}); + +// Format entities into a string representation +const formattedEntities = formatEntities({ entities: entitiesInRoom }); +``` + +## Relationship with Rooms and Worlds + +Entities participate in rooms and, by extension, in worlds: + +```typescript +// Add an entity as a participant in a room +await runtime.addParticipant(entityId, roomId); + +// Get all rooms where an entity is a participant +const entityRooms = await runtime.getRoomsForParticipant(entityId); + +// Get all participants in a room +const participants = await runtime.getParticipantsForRoom(roomId); +``` + +When an entity is a participant in a room that belongs to a world, the entity has an implicit relationship with that world. + +## Creating Unique Entity IDs + +For situations where you need to create deterministic, unique IDs for entity-agent pairs: + +```typescript +const uniqueId = createUniqueUuid(runtime, baseUserId); +``` + +This ensures that each user-agent interaction has a consistent, unique identifier. + +## Best Practices + +1. **Use meaningful names**: Provide descriptive names in the `names` array to make entity identification easier +2. **Structure metadata carefully**: Organize metadata by source (e.g., `discord`, `telegram`) for clarity +3. **Component segregation**: Use components to separate different aspects of entity data rather than storing everything in metadata +4. **Permission checking**: Always verify permissions before accessing components created by other entities +5. **Relationship maintenance**: Update relationship metadata regularly to reflect recent interactions +6. **Entity resolution**: Use the entity resolution system to correctly identify entities in conversations +7. **Deterministic IDs**: Use `createUniqueUuid` for consistent entity identification across sessions +```` + +## File: packages/docs/docs/core/evaluators.md +````markdown +--- +sidebar_position: 7 +--- + +# 🧠 Evaluators + +Evaluators are cognitive components in the ElizaOS framework that enable agents to process conversations, extract knowledge, and build understanding - similar to how humans form memories after interactions. They provide a structured way for agents to introspect, learn from interactions, and evolve over time. + +## Understanding Evaluators + +Evaluators are specialized functions that work with the [`AgentRuntime`](/api/classes/AgentRuntime) to analyze conversations after a response has been generated. Unlike actions that create responses, evaluators perform background cognitive tasks that enable numerous advanced capabilities: + +- **Knowledge Building**: Automatically extract and store facts from conversations +- **Relationship Tracking**: Identify connections between entities +- **Conversation Quality**: Perform self-reflection on interaction quality +- **Goal Tracking**: Determine if conversation objectives are being met +- **Tone Analysis**: Evaluate emotional content and adjust future responses +- **User Profiling**: Build understanding of user preferences and needs over time +- **Performance Metrics**: Gather data on agent effectiveness and learn from interactions + +### Core Structure + +```typescript +interface Evaluator { + name: string; // Unique identifier + similes?: string[]; // Alternative names/triggers + description: string; // Purpose explanation + examples: EvaluationExample[]; // Sample usage patterns + handler: Handler; // Implementation logic + validate: Validator; // Execution criteria check + alwaysRun?: boolean; // Run regardless of validation +} +``` + +### Evaluator Execution Flow + +The agent runtime executes evaluators as part of its cognitive cycle: + +1. Agent processes a message and generates a response +2. Runtime calls `evaluate()` after response generation +3. Each evaluator's `validate()` method determines if it should run +4. For each valid evaluator, the `handler()` function is executed +5. Results are stored in memory and inform future responses + +--- + +## Fact Evaluator: Memory Formation System + +The Fact Evaluator serves as the agent's "episodic memory formation" system - similar to how humans process conversations and form memories. Just as you might reflect after a conversation "Oh, I learned something new about Sarah today", the Fact Evaluator systematically processes conversations to build up the agent's understanding of the world and the people in it. + +### How It Works + +#### 1. Triggering (The "When to Reflect" System) + +```typescript +validate: async (runtime: IAgentRuntime, message: Memory): Promise => { + const messageCount = await runtime.messageManager.countMemories(message.roomId); + const reflectionCount = Math.ceil(runtime.getConversationLength() / 2); + return messageCount % reflectionCount === 0; +}; +``` + +Just like humans don't consciously analyze every single word in real-time, the Fact Evaluator runs periodically rather than after every message. It triggers a "reflection" phase every few messages to process what's been learned. + +#### 2. Fact Extraction (The "What Did I Learn?" System) + +The evaluator uses a template-based approach to extract three types of information: + +- **Facts**: Unchanging truths about the world or people + - "Bob lives in New York" + - "Sarah has a degree in Computer Science" +- **Status**: Temporary or changeable states + - "Bob is currently working on a new project" + - "Sarah is visiting Paris this week" +- **Opinions**: Subjective views, feelings, or non-factual statements + - "Bob thinks the project will be successful" + - "Sarah loves French cuisine" + +#### 3. Memory Deduplication (The "Is This New?" System) + +```typescript +const filteredFacts = facts.filter((fact) => { + return ( + !fact.already_known && + fact.type === 'fact' && + !fact.in_bio && + fact.claim && + fact.claim.trim() !== '' + ); +}); +``` + +Just as humans don't need to consciously re-learn things they already know, the Fact Evaluator: + +- Checks if information is already known +- Verifies if it's in the agent's existing knowledge (bio) +- Filters out duplicate or corrupted facts + +#### 4. Memory Storage (The "Remember This" System) + +```typescript +const factMemory = await factsManager.addEmbeddingToMemory({ + userId: agentId!, + agentId, + content: { text: fact }, + roomId, + createdAt: Date.now(), +}); +``` + +Facts are stored with embeddings to enable: + +- Semantic search of related facts +- Context-aware recall +- Temporal tracking (when the fact was learned) + +### Example Processing + +Given this conversation: + +``` +User: "I just moved to Seattle last month!" +Agent: "How are you finding the weather there?" +User: "It's rainy, but I love my new job at the tech startup" +``` + +The Fact Evaluator might extract: + +```json +[ + { + "claim": "User moved to Seattle last month", + "type": "fact", + "in_bio": false, + "already_known": false + }, + { + "claim": "User works at a tech startup", + "type": "fact", + "in_bio": false, + "already_known": false + }, + { + "claim": "User enjoys their new job", + "type": "opinion", + "in_bio": false, + "already_known": false + } +] +``` + +### Key Design Considerations + +1. **Episodic vs Semantic Memory** + + - Facts build up the agent's semantic memory (general knowledge) + - The raw conversation remains in episodic memory (specific experiences) + +2. **Temporal Awareness** + + - Facts are timestamped to track when they were learned + - Status facts can be updated as they change + +3. **Confidence and Verification** + + - Multiple mentions of a fact increase confidence + - Contradictory facts can be flagged for verification + +4. **Privacy and Relevance** + - Only stores relevant, conversation-appropriate facts + - Respects explicit and implicit privacy boundaries + +--- + +## Reflection Evaluator: Self-Awareness System + +The reflection evaluator extends beyond fact extraction to enable agents to develop a form of "self-awareness" about their conversational performance. It allows agents to: + +1. Generate self-reflective thoughts about the conversation quality +2. Extract factual information from conversations (similar to the Fact Evaluator) +3. Identify and track relationships between entities + +### How Reflections Work + +When triggered, the reflection evaluator: + +1. Analyzes recent conversations and existing knowledge +2. Generates structured reflection output with: + - Self-reflective thoughts about conversation quality + - New facts extracted from conversation + - Identified relationships between entities +3. Stores this information in the agent's memory for future reference + +### Example Reflection Output + +```json +{ + "thought": "I'm engaging appropriately with John, maintaining a welcoming and professional tone. My questions are helping learn more about him as a new community member.", + "facts": [ + { + "claim": "John is new to the community", + "type": "fact", + "in_bio": false, + "already_known": false + }, + { + "claim": "John found the community through a friend interested in AI", + "type": "fact", + "in_bio": false, + "already_known": false + } + ], + "relationships": [ + { + "sourceEntityId": "sarah-agent", + "targetEntityId": "user-123", + "tags": ["group_interaction"] + }, + { + "sourceEntityId": "user-123", + "targetEntityId": "sarah-agent", + "tags": ["group_interaction"] + } + ] +} +``` + +### Implementation Details + +The reflection evaluator uses a defined schema to ensure consistent output: + +```typescript +const reflectionSchema = z.object({ + facts: z.array( + z.object({ + claim: z.string(), + type: z.string(), + in_bio: z.boolean(), + already_known: z.boolean(), + }) + ), + relationships: z.array(relationshipSchema), +}); + +const relationshipSchema = z.object({ + sourceEntityId: z.string(), + targetEntityId: z.string(), + tags: z.array(z.string()), + metadata: z + .object({ + interactions: z.number(), + }) + .optional(), +}); +``` + +### Validation Logic + +The reflection evaluator includes validation logic that determines when reflection should occur: + +```typescript +validate: async (runtime: IAgentRuntime, message: Memory): Promise => { + const lastMessageId = await runtime.getCache( + `${message.roomId}-reflection-last-processed` + ); + const messages = await runtime.getMemories({ + tableName: 'messages', + roomId: message.roomId, + count: runtime.getConversationLength(), + }); + + if (lastMessageId) { + const lastMessageIndex = messages.findIndex((msg) => msg.id === lastMessageId); + if (lastMessageIndex !== -1) { + messages.splice(0, lastMessageIndex + 1); + } + } + + const reflectionInterval = Math.ceil(runtime.getConversationLength() / 4); + + return messages.length > reflectionInterval; +}; +``` + +This ensures reflections occur at appropriate intervals, typically after a set number of messages have been exchanged. + +## Common Memory Formation Patterns + +1. **Progressive Learning** + + ```typescript + // First conversation + "I live in Seattle" -> Stores as fact + + // Later conversation + "I live in the Ballard neighborhood" -> Updates/enhances existing fact + ``` + +2. **Fact Chaining** + + ```typescript + // Original facts + 'Works at tech startup'; + 'Startup is in Seattle'; + + // Inference potential + 'Works in Seattle tech industry'; + ``` + +3. **Temporal Tracking** + + ```typescript + // Status tracking + t0: 'Looking for a job'(status); + t1: 'Got a new job'(fact); + t2: 'Been at job for 3 months'(status); + ``` + +4. **Relationship Building** + + ```typescript + // Initial relationship + { + "sourceEntityId": "user-123", + "targetEntityId": "sarah-agent", + "tags": ["new_interaction"] + } + + // Evolving relationship + { + "sourceEntityId": "user-123", + "targetEntityId": "sarah-agent", + "tags": ["frequent_interaction", "positive_sentiment"], + "metadata": { "interactions": 15 } + } + ``` + +## Integration with Other Systems + +Evaluators work alongside other components: + +- **Goal Evaluator**: Facts and reflections may influence goal progress +- **Trust Evaluator**: Fact consistency affects trust scoring +- **Memory Manager**: Facts enhance context for future conversations +- **Providers**: Facts inform response generation + +--- + +## Creating Custom Evaluators + +You can create your own evaluators by implementing the `Evaluator` interface: + +```typescript +const customEvaluator: Evaluator = { + name: 'CUSTOM_EVALUATOR', + similes: ['ANALYZE', 'ASSESS'], + description: 'Performs custom analysis on conversations', + + validate: async (runtime: IAgentRuntime, message: Memory): Promise => { + // Your validation logic here + return true; + }, + + handler: async (runtime: IAgentRuntime, message: Memory, state?: State) => { + // Your evaluation logic here + + // Example of storing evaluation results + await runtime.addEmbeddingToMemory({ + entityId: runtime.agentId, + content: { text: 'Evaluation result' }, + roomId: message.roomId, + createdAt: Date.now(), + }); + + return { result: 'evaluation complete' }; + }, + + examples: [ + { + prompt: `Example context`, + messages: [ + { name: 'User', content: { text: 'Example message' } }, + { name: 'Agent', content: { text: 'Example response' } }, + ], + outcome: `{ "result": "example outcome" }`, + }, + ], +}; +``` + +### Registering Custom Evaluators + +Custom evaluators can be registered with the agent runtime: + +```typescript +// In your plugin's initialization +export default { + name: 'custom-evaluator-plugin', + description: 'Adds custom evaluation capabilities', + + init: async (config: any, runtime: IAgentRuntime) => { + // Register your custom evaluator + runtime.registerEvaluator(customEvaluator); + }, + + // Include the evaluator in the plugin exports + evaluators: [customEvaluator], +}; +``` + +## Best Practices for Memory Formation + +1. **Validate Facts** + + - Cross-reference with existing knowledge + - Consider source reliability + - Track fact confidence levels + +2. **Manage Memory Growth** + + - Prioritize important facts + - Consolidate related facts + - Archive outdated status facts + +3. **Handle Contradictions** + + - Flag conflicting facts + - Maintain fact history + - Update based on newest information + +4. **Respect Privacy** + + - Filter sensitive information + - Consider contextual appropriateness + - Follow data retention policies + +5. **Balance Reflection Frequency** + - Too frequent: Computational overhead + - Too infrequent: Missing important information + - Adapt based on conversation complexity and pace + +--- + +## FAQ + +### What's the difference between actions and evaluators? + +Actions are triggered during response generation and create visible outputs, while evaluators run after responses and perform background cognitive tasks without direct user visibility. + +### When should I use the Fact Evaluator vs. the Reflection Evaluator? + +Use the Fact Evaluator when you only need to extract and store factual information. Use the Reflection Evaluator when you need both fact extraction and relationship tracking, along with self-reflective assessment. + +### How often do evaluators run? + +By default, evaluators run at intervals based on conversation length, typically after every few messages, to avoid unnecessary processing while still capturing important information. + +### Can evaluators affect future responses? + +Yes! Facts and relationships stored by evaluators become part of the agent's memory and context, influencing future responses through the retrieval-augmented generation system. + +### How do I debug evaluator issues? + +Use the logger to inspect evaluator execution and output. The most common issues involve entity resolution failures or schema validation errors. + +### Can evaluators work across different platforms? + +Yes, evaluators are platform-agnostic and work the same way regardless of whether your agent is deployed on Discord, Twitter, Telegram, or web interfaces. + +## Related Resources + +- [Actions Documentation](./actions.md) +- [Providers Documentation](./providers.md) +- [Agent Runtime](./agents.md) +```` + +## File: packages/docs/docs/core/knowledge.md +````markdown +# Knowledge Management + +## Overview + +The Knowledge Management system in ElizaOS is a powerful Retrieval-Augmented Generation (RAG) feature that enables agents to process, store, and retrieve information from various sources. This allows agents to provide contextually relevant responses by leveraging stored knowledge during conversations. + +## Adding Knowledge to Agents + +ElizaOS provides multiple ways to add knowledge to your agents, both during initialization and at runtime. + +### Adding Knowledge During Runtime Creation + +#### 1. Via Character Definition + +The simplest approach is to define knowledge directly in your character configuration: + +```typescript +const character: Character = { + name: 'My Agent', + // Other character properties... + knowledge: [ + // Direct string knowledge + 'Important fact: ElizaOS supports multiple knowledge formats', + + // File references + { path: 'knowledge/documentation.md', shared: false }, + + // Directory references + { directory: 'knowledge/guides', shared: true }, + ], +}; +``` + +The knowledge array supports three formats: + +- String literals for direct knowledge +- File objects pointing to specific files +- Directory objects for entire folders of content + +#### 2. Programmatically Before Runtime Initialization + +You can dynamically load knowledge before creating your runtime: + +```typescript +// Load knowledge from files or other sources +const knowledge = []; + +// Example: Recursively load documentation files +function loadDocumentation(directoryPath) { + const files = getFilesRecursively(directoryPath, ['.md']); + return files.map((filePath) => { + const relativePath = path.relative(basePath, filePath); + const content = fs.readFileSync(filePath, 'utf-8'); + return `Path: ${relativePath}\n\n${content}`; + }); +} + +// Load documentation +const docKnowledge = loadDocumentation('./docs'); +knowledge.push(...docKnowledge); + +// Then include in your character definition +const character: Character = { + // Other character properties... + knowledge: knowledge, +}; +``` + +### Adding Knowledge After Runtime Creation + +#### 1. Using the `addKnowledge` Method + +Add knowledge programmatically after the runtime is initialized: + +```typescript +// Import needed utilities +import { createUniqueUuid } from '@elizaos/core'; + +// Create a knowledge item +const knowledgeItem = { + id: createUniqueUuid(runtime, 'unique-knowledge-identifier'), + content: { + text: 'Important information the agent should know...', + }, +}; + +// Add to runtime with default chunking settings +await runtime.addKnowledge(knowledgeItem); + +// Or with custom chunking settings +await runtime.addKnowledge(knowledgeItem, { + targetTokens: 1500, // Target chunk size (default: 3000) + overlap: 100, // Overlap between chunks (default: 200) + modelContextSize: 8192, // Context size of your model (default: 4096) +}); +``` + +#### 2. Processing Files at Runtime + +You can dynamically process files at runtime: + +```typescript +// For PDF files, use the PDF service +const pdfService = runtime.getService('pdf'); +if (pdfService) { const pdfBuffer = fs.readFileSync('./knowledge/document.pdf'); const textContent = await pdfService.convertPdfToText(pdfBuffer); - const knowledgeItem = { - id: createUniqueUuid(runtime, 'document.pdf'), - content: { text: textContent }, - }; + const knowledgeItem = { + id: createUniqueUuid(runtime, 'document.pdf'), + content: { text: textContent }, + }; + + await runtime.addKnowledge(knowledgeItem); +} +``` + +## Directory Structure + +ElizaOS expects knowledge files to be organized in the following structure: + +``` +knowledge/ # Root knowledge directory +├── shared/ # Shared knowledge accessible to all agents +└── {agent-name}/ # Agent-specific knowledge directories +``` + +## Supported File Types + +- PDF files (`.pdf`) +- Markdown files (`.md`) +- Text files (`.txt`) + +## Knowledge Modes + +ElizaOS supports two knowledge modes: + +### Classic Mode (Default) + +- Direct string knowledge added to character's context +- No chunking or semantic search +- Enabled by default (`settings.ragKnowledge: false`) +- Only processes string knowledge entries +- Simpler but less sophisticated + +### RAG Mode + +- Advanced knowledge processing with semantic search +- Chunks content and uses embeddings +- Must be explicitly enabled (`settings.ragKnowledge: true`) +- Supports three knowledge types: + 1. Direct string knowledge + 2. Single file references: `{ "path": "path/to/file.md", "shared": false }` + 3. Directory references: `{ "directory": "knowledge/dir", "shared": false }` +- Supported file types: .md, .txt, .pdf +- Optional `shared` flag for knowledge reuse across characters + +To enable RAG mode, add this to your character settings: + +```typescript +const character: Character = { + // Other character properties... + settings: { + ragKnowledge: true, + }, +}; +``` + +## How Knowledge Processing Works + +### Document Processing Flow + +The RAG system processes documents through several stages: + +1. **Directory Processing** + + - The system scans configured directories in `knowledge/` + - Files are processed based on their shared/private status and file type + +2. **File Processing Pipeline** + + - **Preprocessing**: Reading, cleaning, and normalizing text + - **Document-level Processing**: Generating embeddings for the entire document + - **Chunk Processing**: Splitting content into manageable chunks and generating embeddings for each + +3. **Retrieval Process** + - When a user message is received, its embedding is generated + - This embedding is compared to stored knowledge embeddings + - The most semantically similar chunks are retrieved + - Retrieved knowledge is incorporated into the agent's context + +This multi-level approach enables: + +- Broad document-level semantic search +- Fine-grained chunk-level retrieval for specific information +- Efficient parallel processing of large documents +- Maintenance of document context through metadata linking + +### Knowledge Processing Flow Diagram + +```mermaid +graph TB + subgraph Directory_Processing + A[Read Files from Directory] --> B[File Content] + end + + subgraph Preprocessing + B --> C[Clean & Normalize Text] + end + + subgraph Document_Processing + C --> D[Generate Document Embedding] + D --> E[Store Full Document] + E --> |Metadata| F[File Path] + E --> |Metadata| G[File Type] + E --> |Metadata| H[Shared Status] + end + + subgraph Chunk_Processing + C --> I[Split into Chunks] + I --> |512 tokens| J[Chunk 1] + I --> |20 token overlap| K[...] + I --> L[Chunk N] + + subgraph Parallel_Processing + J --> M1[Generate Embedding] + K --> M2[Generate Embedding] + L --> M3[Generate Embedding] + end + + subgraph Chunk_Storage + M1 --> N1[Store Chunk] + M2 --> N2[Store Chunk] + M3 --> N3[Store Chunk] + + N1 --> |Metadata| O[Original Doc Reference] + N1 --> |Metadata| P[Chunk Index] + N2 --> |Metadata| O + N2 --> |Metadata| P + N3 --> |Metadata| O + N3 --> |Metadata| P + end + end + + style Directory_Processing fill:#f9f,stroke:#333,stroke-width:2px + style Preprocessing fill:#bbf,stroke:#333,stroke-width:2px + style Document_Processing fill:#bfb,stroke:#333,stroke-width:2px + style Chunk_Processing fill:#fbf,stroke:#333,stroke-width:2px + style Parallel_Processing fill:#fbb,stroke:#333,stroke-width:2px + style Chunk_Storage fill:#bff,stroke:#333,stroke-width:2px +``` + +### Processing Parameters + +- **Chunk Size**: 512 tokens (default, configurable when adding knowledge) +- **Chunk Overlap**: 20 tokens (default, configurable) +- **Processing Batch Size**: 10 chunks processed concurrently +- **Default Similarity Threshold**: 0.85 for retrieval +- **Default Match Count**: 5 results returned + +## Best Practices for Knowledge Management + +### Content Organization + +1. **Document Structure** + + - Use clear section headings and hierarchical organization + - Break large documents into logical smaller files + - Include metadata and context in markdown files + - Structure information from general to specific + +2. **File Management** + + - Use descriptive filenames that reflect content + - Group related files in subdirectories + - Keep paths short and meaningful + - Avoid special characters in filenames + +3. **Knowledge Optimization** + - Keep individual documents focused on specific topics + - For very detailed information, use smaller chunks (200-300 tokens) by setting `targetTokens` + - Balance the total number of knowledge items for performance + - Prefer markdown (.md) files for best processing results + +### Processing Large Knowledge Bases + +When adding many knowledge items at once, consider implementing a semaphore pattern: + +```typescript +import { Semaphore } from '@elizaos/core'; + +// Create semaphore to limit concurrent processing +const semaphore = new Semaphore(10); + +// Process items with controlled concurrency +await Promise.all( + items.map(async (item) => { + await semaphore.acquire(); + try { + await runtime.addKnowledge(item); + } finally { + semaphore.release(); + } + }) +); +``` + +### Knowledge ID Management + +When adding knowledge programmatically, use consistent ID generation: + +```typescript +import { createUniqueUuid } from '@elizaos/core'; +const knowledgeId = createUniqueUuid(runtime, 'my-content'); +``` + +This ensures deterministic IDs that remain stable across sessions. + +## Troubleshooting + +### Common Issues and Solutions + +1. **Knowledge Not Being Retrieved**: + + - Verify the file is in a supported format (PDF, MD, TXT) + - Check if embeddings were properly generated + - Ensure similarity threshold isn't too high (default: 0.85) + - Test retrieval with more specific queries + - Verify RAG mode is enabled if using file/directory references + +2. **Poor Quality Retrievals**: + + - Break down large documents into smaller, focused files + - Ensure document content is clear and well-structured + - Review the chunking size and overlap settings + - Check if the query contains too many common words + +3. **Performance Issues**: + + - Monitor the total number of knowledge items + - Consider reducing the match count for faster retrieval + - Check embedding processing time for large documents + - Use shared knowledge efficiently across agents + +4. **File Processing Errors**: + - Verify file permissions + - Check if paths are correctly structured + - Ensure PDF files are readable and not password-protected + - Validate that text encoding is UTF-8 + +## Technical Implementation Details + +### Knowledge ID Relationships + +The RAG system uses a hierarchical ID structure to maintain relationships: + +```mermaid +classDiagram + class Document { + +UUID id + +String filePath + +String fileType + +Boolean isShared + +Float32Array embedding + +String content + } + + class Fragment { + +UUID id + +UUID originalId + +Number chunkIndex + +String content + +Float32Array embedding + +String originalPath + } + + Document "1" --> "*" Fragment : generates +``` + +#### ID Generation and Linking + +Documents IDs are generated using `createUniqueUuid(runtime, path, isShared)`, making them deterministic. Fragment IDs follow the format `${documentId}-chunk-${index}` to maintain the relationship to their source document. + +## API Reference + +### Key Methods + +#### `runtime.addKnowledge(item: KnowledgeItem, options?): Promise` + +Adds new knowledge to the agent. + +- Parameters: + - `item`: A knowledge item containing: + - `id`: UUID + - `content`: Object with `text` property + - `options`: Optional processing configuration: + - `targetTokens`: Number (default: 3000) + - `overlap`: Number (default: 200) + - `modelContextSize`: Number (default: 4096) + +#### `runtime.getKnowledge(message: Memory): Promise` + +Retrieves knowledge based on a message's content. + +- Parameters: + - `message`: Memory object containing user message +- Returns: Array of matching KnowledgeItem objects + +### Knowledge Item Definition + +```typescript +interface KnowledgeItem { + id: UUID; + content: { + text: string; + // Optional additional metadata + [key: string]: any; + }; +} +``` + +## Security Considerations + +1. **Access Control**: + + - Use the `shared` flag appropriately to control document access + - Keep sensitive information in agent-specific directories + - Regularly audit knowledge access patterns + +2. **Data Privacy**: + - Do not store sensitive personal information in knowledge files + - Review documents for potentially sensitive content before adding + - Implement appropriate backup and recovery procedures + +## Future Considerations + +1. **Scalability**: + + - Monitor knowledge base size and performance + - Plan for regular maintenance and cleanup + - Consider implementing document versioning + +2. **Integration**: + - Document integration points with other systems + - Plan for potential future file format support + - Consider implementing knowledge base analytics + +## Support and Resources + +- Review the implementation in `packages/core/src/ragknowledge.ts` +- Check the issue tracker for known issues and solutions +- Contribute improvements and bug fixes through pull requests +```` + +## File: packages/docs/docs/core/overview.md +````markdown +--- +sidebar_position: 1 +title: ElizaOS Documentation +slug: / +--- + +# ElizaOS Documentation + +Welcome to ElizaOS - a comprehensive framework for building AI agents with persistent personalities across multiple platforms. ElizaOS provides the architecture, tools, and systems needed to create sophisticated agents that maintain consistent behavior, learn from interactions, and seamlessly integrate with a variety of services. + +## System Architecture + +ElizaOS uses a modular architecture that separates concerns while providing a cohesive framework for AI agent development: + +```mermaid +graph TB + %% Main Components with vertical orientation + User((User)):::user + + %% First Level - Services + PlatformServices[Services]:::services + + %% Second Level - Runtime + AgentRuntime[Agent Runtime]:::core + + %% Core Processing Components - Side by side + subgraph "Core Processing" + direction LR + Providers[Providers]:::int + Actions[Actions]:::int + Evaluators[Evaluators]:::int + end + + %% Knowledge and DB - Side by side + subgraph "Knowledge & Storage" + direction LR + Knowledge[Knowledge]:::int + DB[(Database)]:::db + end + + %% Organization Components - Vertical layout + subgraph "Organization" + direction TB + Worlds[Worlds]:::struct + Rooms[Rooms]:::struct + Entities[Entities]:::struct + end + + %% Development Components - Side by side + subgraph "Development & Integration" + direction LR + Plugins[Plugins]:::dev + Projects[Projects]:::dev + Tasks[Tasks]:::dev + end + + %% Main Flow - Vertical emphasis + User <-->|Interaction| PlatformServices + PlatformServices -->|Process| AgentRuntime + + %% Runtime connections - Simplified + AgentRuntime ---|Context| Providers + AgentRuntime ---|Behavior| Actions + AgentRuntime ---|Analysis| Evaluators + + %% Data connections + AgentRuntime <-->|Storage| DB + Knowledge -->|Informs| Providers + + %% Structure connections - Clean vertical hierarchy + AgentRuntime -->|Manages| Worlds + Worlds -->|Contains| Rooms + Rooms -->|Has| Entities + + %% Development connections + Projects -->|Configure| AgentRuntime + Plugins -->|Extend| AgentRuntime + Tasks -->|Scheduled by| AgentRuntime + + %% Clickable nodes with links to docs + click AgentRuntime "/docs/core/agents" "Learn about Agent Runtime" + click PlatformServices "/docs/core/services" "Learn about Services" + click DB "/docs/core/database" "Learn about Database Systems" + click Actions "/docs/core/actions" "Learn about Actions" + click Providers "/docs/core/providers" "Learn about Providers" + click Evaluators "/docs/core/evaluators" "Learn about Evaluators" + click Knowledge "/docs/core/knowledge" "Learn about Knowledge System" + click Worlds "/docs/core/worlds" "Learn about Worlds" + click Rooms "/docs/core/rooms" "Learn about Rooms" + click Entities "/docs/core/entities" "Learn about Entities" + click Plugins "/docs/core/plugins" "Learn about Plugins" + click Projects "/docs/core/project" "Learn about Projects" + click Tasks "/docs/core/tasks" "Learn about Tasks" + + %% Styling + classDef core fill:#3498db,stroke:#2c3e50,stroke-width:1px,color:#fff,font-weight:bold + classDef services fill:#9b59b6,stroke:#2c3e50,stroke-width:1px,color:#fff,font-weight:bold + classDef db fill:#27ae60,stroke:#2c3e50,stroke-width:1px,color:#fff,font-weight:bold + classDef int fill:#e74c3c,stroke:#2c3e50,stroke-width:1px,color:#fff,font-weight:bold + classDef struct fill:#f39c12,stroke:#2c3e50,stroke-width:1px,color:#fff,font-weight:bold + classDef dev fill:#1abc9c,stroke:#2c3e50,stroke-width:1px,color:#fff,font-weight:bold + classDef user fill:#ecf0f1,stroke:#2c3e50,stroke-width:2px,color:#2c3e50,font-weight:bold,border-radius:50% +``` + +### How ElizaOS Works + +When a user message is received: + +1. **Service Reception**: Platform service (Discord, Telegram, etc.) receives the message +2. **Runtime Processing**: Agent runtime coordinates the response generation +3. **Context Building**: Providers supply relevant context (time, recent messages, knowledge) +4. **Action Selection**: The agent evaluates and selects appropriate actions +5. **Response Generation**: The chosen action generates a response +6. **Learning & Reflection**: Evaluators analyze the conversation for insights and learning +7. **Memory Storage**: New information is stored in the database +8. **Response Delivery**: The response is sent back through the service + +This creates a continuous cycle of interaction, reflection, and improvement that allows agents to maintain consistent personalities while adapting to new information. + +## Core Components + +
+
+
+
+
+ Overview +
+
+

🤖 Agent Runtime

+

The central system that orchestrates agent behavior, processes messages, manages state, and coordinates all other components.

+
+ +
+
+ +
+
+
+ Overview +
+
+

📚 Services

+

Platform-specific integrations that enable agents to communicate across Discord, Twitter, Telegram, and other channels.

+
+
+ Services +
+
+
+ +
+
+
+ Overview +
+
+

💾 Database

+

Persistent storage for memories, entity data, relationships, and configuration using vector search capabilities.

+
+
+ Database +
+
+
+
+
+ +## Intelligence & Behavior + +
+
+
+
+
+ Overview +
+
+

⚡ Actions

+

Executable capabilities that define how agents respond to messages and interact with external systems.

+
+
+ Actions +
+
+
+ +
+
+
+ Overview +
+
+

🔌 Providers

+

Data sources that supply contextual information to inform agent decision-making in real-time.

+
+
+ Providers +
+
+
+ +
+
+
+ Overview +
+
+

📊 Evaluators

+

Analytical systems that process conversations to extract insights, learn facts, and improve future responses.

+
+ +
+
+ +
+
+
+ Overview +
+
+

🧠 Knowledge

+

RAG system for document processing, semantic search, and context-aware memory retrieval.

+
+
+ Knowledge +
+
+
+
+
+ +## Structure & Organization + +
+
+
+
+
+ Overview +
+
+

🌐 Worlds

+

Collection spaces that organize entities and rooms into coherent environments (like a Discord server).

+
+
+ Worlds +
+
+
+ +
+
+
+ Overview +
+
+

💬 Rooms

+

Conversation spaces where entities interact through messages (channels, DMs, threads).

+
+
+ Rooms +
+
+
+ +
+
+
+ Overview +
+
+

👤 Entities

+

Representation of users, agents, and other participants using a flexible entity-component architecture.

+
+
+ Entities +
+
+
+
+
+ +## Development & Integration + +
+
+
+
+
+ Overview +
+
+

🧩 Plugins

+

Modular extensions that add new capabilities, integrations, and behaviors to agents.

+
+
+ Plugins +
+
+
+ +
+
+
+ Overview +
+
+

📝 Projects

+

Organizational structure for defining and deploying one or more agents with their configuration.

+
+
+ Projects +
+
+
+ +
+
+
+ Overview +
+
+

📋 Tasks

+

System for managing deferred, scheduled, and repeating operations across conversations.

+
+
+ Tasks +
+
+
+
+
+ +--- + +## Key Concepts + +### Action-Provider-Evaluator Cycle + +The core of the ElizaOS system operates as a continuous cycle: + +1. **Providers** gather context before response generation +2. **Actions** determine what the agent can do and are executed to generate responses +3. **Evaluators** analyze conversations after responses to extract insights +4. These insights become part of the agent's memory +5. Future **Providers** access this memory to inform new responses + +This creates a virtuous cycle where agents continuously learn and improve from interactions. + +### Entity-Component Architecture + +ElizaOS uses an entity-component architecture for flexible data modeling: + +- **Entities** are base objects with unique IDs (users, agents, etc.) +- **Components** are pieces of data attached to entities (profiles, settings, etc.) +- This approach allows for dynamic composition without complex inheritance hierarchies + +### Memory System + +The memory system in ElizaOS provides: + +- **Vector-based semantic search** for finding relevant memories +- **Multi-level memory types** (messages, facts, knowledge) +- **Temporal awareness** through timestamped memories +- **Cross-platform continuity** while maintaining appropriate context boundaries + +## Getting Started + +If you're new to ElizaOS, we recommend this learning path: + +1. Start with this overview to understand the system architecture +2. Explore the [Agent Runtime](/docs/core/agents) to understand the core system +3. Learn about [Projects](/docs/core/project) to set up your development environment +4. Understand how [Actions](/docs/core/actions) and [Providers](/docs/core/providers) work together +5. Explore [Services](/docs/core/services) to connect with external platforms +6. Dive into [Plugins](/docs/core/plugins) to extend functionality + +## FAQ + +
+What's the difference between Actions, Evaluators, and Providers? + +**Actions** define what an agent can do and are executed during response generation. **Evaluators** analyze conversations after they happen to extract insights and improve future responses. **Providers** supply contextual information before the agent decides how to respond. + +
+ +
+How does ElizaOS handle cross-platform conversation context? + +ElizaOS maintains separate conversation contexts for different platforms by default, but shares entity relationships and learned facts across platforms. This ensures agents maintain a consistent understanding of users while respecting platform-specific conversation boundaries. + +
+ +
+How does the memory system work? + +Memory is organized into different types (messages, facts, knowledge) and stored with vector embeddings for semantic search. This allows agents to retrieve relevant memories based on context rather than just recency, creating more natural conversations. + +
+ +
+What's the relationship between Worlds, Rooms, and Entities? + +Worlds are container spaces (like a Discord server) that can have multiple Rooms (channels, DMs). Entities (users, agents) participate in Rooms within Worlds. This hierarchical structure mirrors real-world platforms while providing a consistent abstraction. + +
+ +
+How extensible is ElizaOS? + +ElizaOS is highly extensible through its plugin system. You can create custom actions, providers, evaluators, services, and more to extend functionality. The architecture is designed to be modular and composable at every level. + +
+ +## Additional Resources + +- [API Reference](/api) - Detailed API documentation for developers +- [GitHub Repository](https://github.com/elizaos/eliza) - Source code and contributions +- [Package Showcase](/packages) - Explore available plugins and extensions +```` + +## File: packages/docs/docs/core/plugins.md +````markdown +# Plugins + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +Plugins are modular extensions that enhance the capabilities of ElizaOS agents. They provide a flexible way to add new functionality, integrate external services, and customize agent behavior across different platforms. + +:::info +Key Improvements in V2 + +1. **Unified API**: Almost everything is accessible via `runtime.methodName()` in the agent runtime for simpler development +2. **Enhanced Model System**: The new `useModel` approach allows for flexible model provider registration +3. **Events System**: Formal support for event-based programming +4. **Plugin Creation Workflow**: Simplified creation and testing via CLI +5. **Testing Infrastructure**: Built-in support for plugin testing +6. **No Monorepo Required**: Complete plugin development without touching the core codebase +7. **Plugin Registry**: Manages the catalog of available plugins and handles their registration with the runtime +8. **Bootstrap Plugin**: Initializes core functionality required for all agents to operate + ::: + +The ElizaOS plugin system maintains the same basic concept as previous versions, with several new extension points (events, routes, tests, models) and features that significantly improve the developer experience. + +**Browse plugins the elizaOS community made here: [Package Showcase](/packages)** + +[![](/img/plugins.png)](/packages) + +> elizaOS maintains an official package registry at [github.com/elizaos-plugins/registry](https://github.com/elizaos-plugins/registry). + +--- + +## Quick Start + +The new CLI tool introduces a streamlined workflow for plugin development without ever needing to touch the ElizaOS monorepo directly: + +1. **Create**: `npm create eliza` - Initialize a new plugin project with proper structure +2. **Develop**: Edit the plugin code in the generated project structure +3. **Test**: `npx elizaos test` - Test the plugin functionality +4. **Run**: `npx elizaos start` - Run the plugin with a default agent +5. **Publish**: `npx elizaos publish` - Share your plugin with others + +> Note: at time of publishing, use `npm create eliza@beta` until main version is uploaded + +### Creating a New Plugin + +You can create a new ElizaOS plugin using the CLI: + +```bash +# Using npm +npm create eliza@beta + +# Or using npx +npx @elizaos/cli@beta create +``` + +When prompted, select "Plugin" as the type to create. The CLI will guide you through the setup process, creating a plugin with the proper structure and dependencies. + +--- + +### Managing Plugins + +There are several ways to add plugins to your ElizaOS project: + + + + ```json + { + "dependencies": { + "@elizaos/plugin-solana": "github:elizaos-plugins/plugin-solana", + "@elizaos/plugin-twitter": "github:elizaos-plugins/plugin-twitter" + } + } + ``` + + + ```typescript + // In src/index.ts + export const character: Character = { + name: 'MyAgent', + plugins: ['@elizaos/plugin-twitter', '@elizaos/plugin-example'], + // ... + }; + ``` + + + ```bash + # Add a plugin + npx @elizaos/cli plugins add @elizaos/plugin-twitter + + # Remove a plugin + npx @elizaos/cli plugins remove @elizaos/plugin-twitter + + # List available plugins + npx @elizaos/cli plugins list + ``` + + + + +--- + +### Plugin Configuration + +Configure plugin settings in your character definition: + +```json +{ + "name": "MyAgent", + "plugins": ["@elizaos/plugin-example"], + "settings": { + "example": { + "enableFeatureX": true + // Plugin-specific configuration + } + } +} +``` + +### Plugin Loading Process + +The AgentRuntime automatically loads the Bootstrap Plugin during initialization, before any other plugins: + +```typescript +async initialize() { + // Register bootstrap plugin + await this.registerPlugin(bootstrapPlugin); + + // Then register additional plugins + for (const plugin of this.plugins) { + await this.registerPlugin(plugin); + } + + // Initialize other components + // ... +} +``` + +--- + +### Publishing Plugins + +If you're a plugin developer, you can publish your plugin to make it available to others. The ElizaOS CLI provides several options for publishing your plugin depending on your needs. + +First, make sure your plugin is built and ready for distribution: + +```bash +# Navigate to your plugin directory +cd my-eliza-plugin + +# Build your plugin +npm run build +``` + + + + Publishing to GitHub is the recommended approach for sharing your plugin with the ElizaOS community: + + ```bash + # Publish to GitHub + npx @elizaos/cli publish + ``` + + This will: + 1. Build and package your plugin + 2. Create or update a GitHub repository in the elizaos-plugins organization + 3. Add your plugin to the ElizaOS registry (if you're a registry maintainer) + + For first-time publishers, the CLI will guide you through setting up GitHub credentials for publishing. + + GitHub publishing is ideal for open-source plugins that you want to share with the community and have listed in the official registry. + + + + + You can also publish your plugin to npm: + + ```bash + # Publish to npm + npx @elizaos/cli publish --npm + ``` + + This allows users to install your plugin using standard npm commands: + + ```bash + npm install @your-scope/plugin-name + ``` + + npm publishing is useful when you want to: + - Maintain your own package namespace + - Integrate with existing npm workflows + - Set up automated versioning and releases + + Make sure your package.json is properly configured with the correct name, version, and access permissions. + + + + + Before publishing, you can validate the process without making any external changes: + + ```bash + # Test the publish process + npx @elizaos/cli publish --test + ``` + + This runs through all the packaging and validation steps without actually publishing anything. + + Test mode is helpful for: + - Verifying your plugin structure is correct + - Ensuring all required files are present + - Checking that dependencies are properly configured + - Validating that your plugin can be built successfully + + Always run in test mode before your first public release to avoid issues. + + + + + The publish command supports several additional options to customize the publishing process: + + ```bash + # Specify platform compatibility + npx @elizaos/cli publish --platform node + + # Set custom version number + npx @elizaos/cli publish --version 1.2.3 + + # Provide a custom registry URL + npx @elizaos/cli publish --registry https://custom-registry.com + + # Publish with public access + npx @elizaos/cli publish --access public + ``` + + These options give you fine-grained control over how and where your plugin is published. Refer to `npx @elizaos/cli publish --help` for a complete list of options. + + + + +:::info +When submitting a plugin to the [elizaOS Registry](https://github.com/elizaos-plugins/registry), include: + +1. **Working Demo**: Screenshots or video of your plugin in action +2. **Test Results**: Evidence of successful integration and error handling +3. **Configuration Example**: Show how to properly configure your plugin + ::: + +--- + +## Plugin Architecture + +Eliza uses a unified plugin architecture where everything is a plugin - including services, adapters, actions, evaluators, and providers. This approach ensures consistent behavior and better extensibility. + +### Plugin Components + +Each plugin can provide one or more of the following components: + +| Component | Purpose | +| ------------------ | ------------------------------------------------------------------------------- | +| **Services** | Platform integrations (Discord, Twitter, etc.) or specialized capabilities | +| **Actions** | Executable functions triggered by the agent (reply, generate content, etc.) | +| **Providers** | Context providers that supply info to the agent during decision making | +| **Evaluators** | Analyze conversations to extract insights and improve future interactions | +| **Adapters** | Database or storage system integrations | +| **Model Handlers** | Register handlers for different model types (text generation, embeddings, etc.) | +| **Event Handlers** | React to system events like messages, connections, or actions | +| **API Routes** | Add custom REST endpoints to the agent's HTTP interface | +| **Tests** | Include test suites to verify plugin functionality | + +### Plugin Interface + +All plugins implement the core Plugin interface: + +```typescript +interface Plugin { + name: string; + description: string; + config?: { [key: string]: any }; + + // Optional initialization method + init?: (config: Record, runtime: IAgentRuntime) => Promise; + + // Components + services?: (typeof Service)[]; + actions?: Action[]; + providers?: Provider[]; + evaluators?: Evaluator[]; + adapters?: Adapter[]; + + // Additional features + routes?: Route[]; + tests?: TestSuite[]; + events?: { [key: string]: ((params: any) => Promise)[] }; +} +``` + +### Service Implementation + +Services are the core integration points for external platforms. A properly implemented service: + +```typescript +import { Service, IAgentRuntime } from '@elizaos/core'; + +export class ExampleService extends Service { + // Required: Define the service type (used for runtime registration) + static serviceType = 'example'; + + // Required: Describe what this service enables the agent to do + capabilityDescription = 'Enables the agent to interact with the Example platform'; + + // Store runtime for service operations + constructor(protected runtime: IAgentRuntime) { + super(); + // Initialize connections, setup event handlers, etc. + } + + // Required: Static method to create and initialize service instance + static async start(runtime: IAgentRuntime): Promise { + const service = new ExampleService(runtime); + // Additional initialization if needed + return service; + } + + // Required: Clean up resources when service is stopped + async stop(): Promise { + // Close connections, release resources + } + + // Optional: Custom methods for your service functionality + async sendMessage(content: string, channelId: string): Promise { + // Implementation + } +} +``` + +## Plugin Structure + +Each plugin repository should follow this structure: + +``` +plugin-name/ +├── images/ # Branding assets +│ ├── logo.png # Square logo (400x400px) +│ ├── banner.png # Banner image (1280x640px) +│ └── screenshots/ # Feature screenshots +├── src/ +│ ├── index.ts # Main plugin entry point +│ ├── service.ts # Service implementation +│ ├── actions/ # Plugin-specific actions +│ ├── providers/ # Data providers +│ ├── types.ts # Type definitions +│ └── environment.ts # Configuration validation +├── tests/ # Test suite +├── package.json # Plugin configuration and dependencies +└── README.md # Plugin documentation +``` + +### Plugin Entry Point + +Your plugin's `index.ts` should export a Plugin object: + +```typescript +// Example plugin implementation +import { type Plugin } from '@elizaos/core'; +import { ExampleService } from './service'; +import { searchAction } from './actions/search'; +import { statusProvider } from './providers/status'; + +const examplePlugin: Plugin = { + name: 'example', + description: 'Example platform integration for ElizaOS', + services: [ExampleService], + actions: [searchAction], + providers: [statusProvider], + init: async (config, runtime) => { + // Perform any necessary initialization + const apiKey = runtime.getSetting('EXAMPLE_API_KEY'); + if (!apiKey) { + console.warn('EXAMPLE_API_KEY not provided'); + } + }, +}; + +export default examplePlugin; +``` + +### Plugin Configuration + +Your plugin's `package.json` should include an `agentConfig` section: + +```json +{ + "name": "@elizaos/plugin-example", + "version": "1.0.0", + "agentConfig": { + "pluginType": "elizaos:plugin:1.0.0", + "pluginParameters": { + "API_KEY": { + "type": "string", + "description": "API key for the Example service" + } + } + } +} +``` + +### Environment Variables and Secrets + +Plugins access configuration through the runtime with the following precedence: + +1. Character settings secrets (highest priority) +2. Character settings +3. Global environment settings + +#### Access Pattern + +```typescript +// In your service implementation +const apiKey = runtime.getSetting('EXAMPLE_API_KEY'); +const debugMode = runtime.getSetting('EXAMPLE_DEBUG_MODE'); // Returns boolean for "true"/"false" strings +``` + +#### Configuration in Character File + +```json +{ + "name": "MyAgent", + "plugins": ["@elizaos/plugin-example"], + "settings": { + "example": { + "enableFeatureX": true + }, + "secrets": { + "EXAMPLE_API_KEY": "your-api-key-here" + } + } +} +``` + +--- + +## Bootstrap Plugin + +The Bootstrap Plugin is a foundational component of ElizaOS that initializes the core functionality required for agents to operate. It's automatically loaded as part of the initialization process, establishing the minimum viable capabilities that all agents need. + +```typescript +export const bootstrapPlugin: Plugin = { + name: 'bootstrap', + description: 'Agent bootstrap with basic actions and evaluators', + actions: [...], + events: {...}, + evaluators: [...], + providers: [...], + services: [TaskService, ScenarioService], +}; +``` + +The Bootstrap Plugin registers essential components across several categories to provide a foundation for all agents. These components can be extended by custom plugins. + + + + | Action | Description | + | ---------------------- | ----------------------------------------------- | + | `replyAction` | Generates and sends a response to a message | + | `followRoomAction` | Enables an agent to actively follow a room | + | `unfollowRoomAction` | Stops an agent from following a room | + | `muteRoomAction` | Mutes notifications from a room | + | `unmuteRoomAction` | Unmutes notifications from a room | + | `sendMessageAction` | Sends a message to a specific room | + | `ignoreAction` | Explicitly ignores a message | + | `noneAction` | Acknowledges a message without taking action | + | `updateEntityAction` | Updates properties of an entity | + | `choiceAction` | Presents choices to users and handles responses | + | `updateRoleAction` | Updates a user's role in a world | + | `updateSettingsAction` | Updates agent or world settings | + + + + | Provider | Description | + | ------------------------ | ---------------------------------------------------------- | + | `characterProvider` | Provides the agent's personality and configuration | + | `recentMessagesProvider` | Retrieves recent conversation history | + | `knowledgeProvider` | Supplies factual information from the knowledge base | + | `timeProvider` | Provides awareness of current time and date | + | `entitiesProvider` | Supplies information about entities in the current context | + | `relationshipsProvider` | Provides information about entity relationships | + | `factsProvider` | Retrieves relevant facts from memory | + | `roleProvider` | Provides role information within worlds | + | `settingsProvider` | Supplies configured settings | + | `anxietyProvider` | Informs agent of potential issues to be careful about | + | `attachmentsProvider` | Handles media and file attachments | + | `providersProvider` | Meta-provider with information about available providers | + | `actionsProvider` | Meta-provider with information about available actions | + | `evaluatorsProvider` | Meta-provider with information about available evaluators | + | `choiceProvider` | Manages choice-based interactions | + | `capabilitiesProvider` | Provides information about agent capabilities | + + + + **Services:** + + | Service | Purpose | + | ----------------- | ------------------------------------------------ | + | `TaskService` | Manages deferred, scheduled, and repeating tasks | + | `ScenarioService` | Handles scenario-based interactions and testing | + + **Evaluators:** + + | Evaluator | Description | + | --------------------- | ----------------------------------------------------- | + | `reflectionEvaluator` | Enables self-awareness and learning from interactions | + + + + + The Bootstrap Plugin registers handlers for key system events that enable the core message processing flow: + + **Core Events:** + - `MESSAGE_RECEIVED` - Processes new messages and generates responses + - `REACTION_RECEIVED` - Tracks reactions to messages + - `VOICE_MESSAGE_RECEIVED` - Handles audio messages + - `POST_GENERATED` - Creates social media content + - `MESSAGE_SENT` - Logs outgoing messages + + **World Events:** + - `WORLD_JOINED` / `WORLD_CONNECTED` - Synchronizes data when joining worlds + - `ENTITY_JOINED` / `ENTITY_LEFT` - Manages entity presence + + **Lifecycle Events:** + - `ACTION_STARTED` / `ACTION_COMPLETED` - Tracks action execution + - `EVALUATOR_STARTED` / `EVALUATOR_COMPLETED` - Monitors evaluator processing + - `RUN_STARTED` / `RUN_ENDED` / `RUN_TIMEOUT` - Manages message processing lifecycle + + The message processing flow follows these steps: + 1. Receive message via `MESSAGE_RECEIVED` event + 2. Save message to memory + 3. Check if agent should respond + 4. If responding, compose state from providers + 5. Generate a response using the language model + 6. Process any actions specified in the response + 7. Run evaluators on the conversation + 8. Emit lifecycle events throughout the process + + + + +### Extending Bootstrap Functionality + +While the Bootstrap Plugin provides core functionality, it's designed to be extended by other plugins. Custom plugins can: + +1. **Add new actions** - Extend the agent's capabilities +2. **Register additional providers** - Supply more contextual information +3. **Add evaluators** - Create new ways to analyze and learn from interactions +4. **Handle additional events** - React to more system events +5. **Initialize custom services** - Provide new functionality + +When working with plugins in relation to the Bootstrap Plugin: + +1. **Don't modify bootstrap directly** - Instead, create custom plugins to extend functionality +2. **Understand provider contribution** - Know how each provider contributes to the agent's context +3. **Learn the core actions** - Become familiar with the actions that all agents can perform +4. **Leverage event handlers** - Use the event system for reactive behavior +5. **Extend, don't replace** - Build on top of bootstrap functionality rather than replacing it + +--- + +## Developing a Plugin + +When developing a new plugin, focus on these key aspects: + +1. **Service Implementation**: Create a solid service class following the pattern above +2. **Proper Error Handling**: Handle API failures gracefully +3. **Type Definitions**: Define clear interfaces and types +4. **Documentation**: Include detailed setup instructions +5. **Tests**: Add test cases for your functionality + +### Testing Your Plugin + +During development, you can test your plugin locally: + +```bash +# Start with your plugin +npx @elizaos/cli start --plugin=./path/to/plugin + +# Or with a specific character +npx @elizaos/cli start --character=./characters/test.character.json --plugin=./path/to/plugin +``` + +### Distribution & PR Requirements + +When submitting a plugin to the [elizaOS Registry](https://github.com/elizaos-plugins/registry), include: + +1. **Working Demo**: Screenshots or video of your plugin in action +2. **Test Results**: Evidence of successful integration and error handling +3. **Configuration Example**: Show how to properly configure your plugin +4. **Quality Checklist**: + - [ ] Plugin follows the standard structure + - [ ] Required branding assets are included + - [ ] Documentation is complete + - [ ] GitHub topics properly set + - [ ] Tests are passing + - [ ] Includes error handling + +--- + +## FAQ + +### What exactly is a plugin in ElizaOS? + +A plugin is a modular extension that adds new capabilities to ElizaOS agents, such as API integrations, custom actions, or platform connections. Plugins allow you to expand agent functionality and share reusable components with other developers. + +### When should I create a plugin versus using existing ones? + +Create a plugin when you need custom functionality not available in existing plugins, want to integrate with external services, or plan to share reusable agent capabilities with the community. + +### How do I manage plugin dependencies? + +Plugin dependencies are managed through your project's `package.json`. You can add plugins directly using npm or the ElizaOS CLI, and they will be automatically loaded when your project starts. + +### Can I use a plugin in development before publishing? + +Yes, you can use the `--plugin` flag with the `start` command to include local plugins during development: + +```bash +npx @elizaos/cli start --plugin=./path/to/plugin +``` + +### What's the difference between Actions and Services? + +Actions handle specific agent responses or behaviors, while Services provide platform integrations (like Discord or Twitter) or ongoing background functionality that multiple actions might use. + +### How do I handle rate limits with external APIs? + +Implement proper backoff strategies in your service implementation and consider using a queue system for message handling to respect platform rate limits. + +## Additional Resources + +- [ElizaOS Registry](https://github.com/elizaos-plugins/registry) +- [Example Plugins](https://github.com/elizaos-plugins) +- [Discord Community](https://discord.gg/elizaos) +```` + +## File: packages/docs/docs/core/project.md +````markdown +# 📝 ElizaOS Projects + +Projects are the main organizational structure in ElizaOS, containing all the necessary components to create and deploy AI agents. A project can include one or more agents, each with their own character definition, plugins, and configurations. + +## Project Structure + +A typical ElizaOS project structure: + +``` +my-eliza-project/ +├── src/ +│ └── index.ts # Main entry point +├── knowledge/ # Knowledge base files +├── package.json # Dependencies and scripts +└── tsconfig.json # TypeScript configuration +``` + +## Creating a New Project + +You can create a new ElizaOS project using: + +```bash +# Using npm +npm create eliza@beta + +# Or using npx +npx @elizaos/cli@beta create +``` + +The CLI will guide you through the setup process, including: + +- Project name +- Database selection (pglite, postgres, etc.) +- Initial configuration + +## Project Configuration + +The main project file (`src/index.ts`) exports a default project object: + +```typescript +import type { Character, IAgentRuntime, Project, ProjectAgent } from '@elizaos/core'; +import customPlugin from './plugin'; + +// Define the character +export const character: Character = { + name: 'Agent Name', + plugins: ['@elizaos/plugin-discord', '@elizaos/plugin-direct'], + // Other character properties +}; + +// Create a ProjectAgent that includes the character +export const projectAgent: ProjectAgent = { + character, + init: async (runtime: IAgentRuntime) => { + // Initialize agent-specific functionality + console.log('Initializing agent:', character.name); + }, + plugins: [customPlugin], + tests: [], // Optional tests for your agent +}; + +// Export the full project with all agents +const project: Project = { + agents: [projectAgent], +}; + +export default project; +``` + +## Character Configuration + +Each agent in your project requires a character definition that controls its personality, knowledge, and behavior. + +### Required Character Fields + +```typescript +{ + name: "agent_name", // Character's display name + plugins: ["@elizaos/plugin-discord"], // Example plugins + settings: { + // Configuration settings + secrets: {}, // API keys and sensitive data + voice: {}, // Voice configuration + }, + bio: [], // Character background as a string or array of statements + style: { + // Interaction style guide + all: [], // General style rules + chat: [], // Chat-specific style + post: [] // Post-specific style + } +} +``` + +### Plugins + +Plugins provide your agent with capabilities and integrations: + +- `@elizaos/plugin-discord`: Discord integration +- `@elizaos/plugin-telegram`: Telegram integration +- `@elizaos/plugin-twitter`: Twitter/X integration +- `@elizaos/plugin-slack`: Slack integration +- `@elizaos/plugin-direct`: Direct chat interface +- `@elizaos/plugin-simsai`: SimsAI platform integration + +View all available plugins: https://github.com/elizaos-plugins/registry + +### Settings Configuration + +The `settings` object supports various configurations: + +```typescript +{ + "settings": { + "ragKnowledge": false, // Enable RAG knowledge mode + "voice": { + "model": "string", // Voice synthesis model + "url": "string" // Optional voice API URL + }, + "secrets": { + // API keys (use env vars in production) + "API_KEY": "string" + }, + } +} +``` + +### Bio & Style + +Define your agent's personality and communication style: + +```typescript +{ + "bio": ["Expert in blockchain development", "Specializes in DeFi protocols"], + "style": { + "all": [ + // Applied to all interactions + "Keep responses clear", + "Maintain professional tone" + ], + "chat": [ + // Chat-specific style + "Engage with curiosity", + "Provide explanations" + ], + "post": [ + // Social post style + "Keep posts informative", + "Focus on key points" + ] + } +} +``` + +**Style Tips** + +- Be specific about tone and mannerisms +- Include platform-specific guidance +- Define clear boundaries and limitations + +### Optional Character Fields + +```typescript +{ + "username": "handle", // Character's username/handle + "system": "System prompt text", // Custom system prompt + "lore": [], // Additional background/history + "knowledge": [ + // Knowledge base entries + "Direct string knowledge", + { "path": "file/path.md", "shared": false }, + { "directory": "knowledge/path", "shared": false } + ], + "messageExamples": [], // Example conversations + "postExamples": [], // Example social posts + "topics": [], // Areas of expertise + "adjectives": [] // Character traits +} +``` + +## Knowledge Management + +ElizaOS supports two knowledge modes: + +### Classic Mode (Default) + +- Direct string knowledge added to character's context +- No chunking or semantic search +- Enabled by default (`settings.ragKnowledge: false`) +- Only processes string knowledge entries +- Simpler but less sophisticated + +### RAG Mode + +- Advanced knowledge processing with semantic search +- Chunks content and uses embeddings +- Must be explicitly enabled (`settings.ragKnowledge: true`) +- Supports three knowledge types: + 1. Direct string knowledge + 2. Single file references: `{ "path": "path/to/file.md", "shared": false }` + 3. Directory references: `{ "directory": "knowledge/dir", "shared": false }` +- Supported file types: .md, .txt, .pdf +- Optional `shared` flag for knowledge reuse across characters + +### Knowledge Path Configuration + +- Knowledge files are relative to the project's `knowledge` directory +- Paths should not contain `../` (sanitized for security) +- Both shared and private knowledge supported +- Files automatically reloaded if content changes + +## Example Project + +Here's a complete example of a project configuration: + +```typescript +import type { Character, IAgentRuntime, Project, ProjectAgent } from '@elizaos/core'; + +export const character: Character = { + name: 'Tech Helper', + plugins: ['@elizaos/plugin-discord', '@elizaos/plugin-direct'], + settings: { + ragKnowledge: true, + voice: { + model: 'en_US-male-medium', + }, + discord: { + shouldRespondOnlyToMentions: false, + allowedChannelIds: ['123456789012345678'], + }, + }, + bio: ['Friendly technical assistant', 'Specializes in explaining complex topics simply'], + lore: ['Pioneer in open-source AI development', 'Advocate for AI accessibility'], + messageExamples: [ + [ + { + name: 'user1', + content: { text: 'Can you explain how AI models work?' }, + }, + { + name: 'TechAI', + content: { + text: 'Think of AI models like pattern recognition systems.', + }, + }, + ], + ], + topics: ['artificial intelligence', 'machine learning', 'technology education'], + knowledge: [ + { + directory: 'tech_guides', + shared: true, + }, + ], + style: { + all: ['Clear', 'Patient', 'Educational'], + chat: ['Interactive', 'Supportive'], + post: ['Concise', 'Informative'], + }, +}; + +export const projectAgent: ProjectAgent = { + character, + init: async (runtime: IAgentRuntime) => { + console.log('Initializing Tech Helper agent'); + }, + plugins: [], // Project-specific plugins +}; + +const project: Project = { + agents: [projectAgent], +}; + +export default project; +``` + +## Character File Export + +While projects are the primary structure in ElizaOS, you can still export standalone character files for compatibility with other systems or sharing character definitions: + +```typescript +import fs from 'fs'; +import { character } from './src/index'; + +// Export character to JSON file +fs.writeFileSync('character.json', JSON.stringify(character, null, 2)); +``` + +## Managing Multiple Agents + +A project can contain multiple agents, each with its own character and plugins: + +```typescript +const project: Project = { + agents: [ + { + character: technicalSupportCharacter, + init: async (runtime) => { + /* init code */ + }, + plugins: [customSupportPlugin], + }, + { + character: communityManagerCharacter, + init: async (runtime) => { + /* init code */ + }, + plugins: [communityPlugin], + }, + ], +}; +``` + +Each agent operates independently but can share the same database and resources. + +## Running Your Project + +After configuring your project, you can run it using: + +```bash +npx @elizaos/cli start +``` + +This will start your agents according to your project configuration. +```` + +## File: packages/docs/docs/core/providers.md +````markdown +# 🔌 Providers + +[Providers](/packages/core/src/providers.ts) are the sources of information for the agent. They provide data or state while acting as the agent's "senses", injecting real-time information into the agent's context. They serve as the eyes, ears, and other sensory inputs that allow the agent to perceive and interact with its environment, like a bridge between the agent and various external systems such as market data, wallet information, sentiment analysis, and temporal context. Anything that the agent knows is either coming from like the built-in context or from a provider. For more info, see the [providers API page](/api/interfaces/provider). + +Here's an example of how providers work within ElizaOS: + +- A news provider could fetch and format news. +- A computer terminal provider in a game could feed the agent information when the player is near a terminal. +- A wallet provider can provide the agent with the current assets in a wallet. +- A time provider injects the current date and time into the context. + +--- + +## Overview + +A provider's primary purpose is to supply dynamic contextual information that integrates with the agent's runtime. They format information for conversation templates and maintain consistent data access. For example: + +- **Function:** Providers run during or before an action is executed. +- **Purpose:** They allow for fetching information from other APIs or services to provide different context or ways for an action to be performed. +- **Example:** Before a "Mars rover action" is executed, a provider could fetch information from another API. This fetched information can then be used to enrich the context of the Mars rover action. + +The provider interface is defined in [types.ts](/packages/core/src/types.ts): + +```typescript +interface Provider { + /** Provider name */ + name: string; + + /** Description of the provider */ + description?: string; + + /** Whether the provider is dynamic */ + dynamic?: boolean; + + /** Position of the provider in the provider list, positive or negative */ + position?: number; + + /** + * Whether the provider is private + * + * Private providers are not displayed in the regular provider list, they have to be called explicitly + */ + private?: boolean; + + /** Data retrieval function */ + get: (runtime: IAgentRuntime, message: Memory, state: State) => Promise; +} +``` + +The `get` function takes: + +- `runtime`: The agent instance calling the provider +- `message`: The last message received +- `state`: Current conversation state + +It returns a `ProviderResult` object that contains: + +```typescript +interface ProviderResult { + values?: { + [key: string]: any; + }; + data?: { + [key: string]: any; + }; + text?: string; +} +``` + +- `values`: Key-value pairs to be merged into the agent's state values +- `data`: Additional structured data that can be used by the agent but not directly included in the context +- `text`: String that gets injected into the agent's context + +--- + +## Provider Types and Properties + +Providers come with several properties that control how and when they are used: + +### Dynamic Providers + +Dynamic providers are not automatically included in the context. They must be explicitly requested either in the filter list or include list when composing state. + +```typescript +const dynamicProvider: Provider = { + name: 'dynamicExample', + description: 'A dynamic provider example', + dynamic: true, + get: async (runtime, message, state) => { + // ...implementation + return { + text: 'Dynamic information fetched on demand', + values: { + /* key-value pairs */ + }, + }; + }, +}; +``` + +### Private Providers + +Private providers are not included in the regular provider list and must be explicitly included in the include list when composing state. + +```typescript +const privateProvider: Provider = { + name: 'privateExample', + description: 'A private provider example', + private: true, + get: async (runtime, message, state) => { + // ...implementation + return { + text: 'Private information only available when explicitly requested', + values: { + /* key-value pairs */ + }, + }; + }, +}; +``` + +### Provider Positioning + +The `position` property determines the order in which providers are processed. Lower numbers are processed first. + +```typescript +const earlyProvider: Provider = { + name: 'earlyExample', + description: 'Runs early in the provider chain', + position: -100, + get: async (runtime, message, state) => { + // ...implementation + return { + text: 'Early information', + values: { + /* key-value pairs */ + }, + }; + }, +}; + +const lateProvider: Provider = { + name: 'lateExample', + description: 'Runs late in the provider chain', + position: 100, + get: async (runtime, message, state) => { + // ...implementation + return { + text: 'Late information that might depend on earlier providers', + values: { + /* key-value pairs */ + }, + }; + }, +}; +``` + +--- + +## State Composition with Providers + +The runtime composes state by gathering data from enabled providers. When calling `composeState`, you can control which providers are used: + +```typescript +// Get state with all non-private, non-dynamic providers +const state = await runtime.composeState(message); + +// Get state with specific providers only +const filteredState = await runtime.composeState( + message, + ['timeProvider', 'factsProvider'], // Only include these providers + null +); + +// Include private or dynamic providers +const enhancedState = await runtime.composeState( + message, + null, + ['privateExample', 'dynamicExample'] // Include these private/dynamic providers +); +``` + +The system caches provider results to optimize performance. When a provider is called multiple times with the same message, the cached result is used unless you explicitly request a new evaluation. + +--- + +## Examples + +ElizaOS providers typically fall into these categories, with examples from the ecosystem: + +### System & Integration + +- **Time Provider**: Injects current date/time for temporal awareness +- **Giphy Provider**: Provides GIF responses using Giphy API +- **GitBook Provider**: Supplies documentation context from GitBook +- **Topics Provider**: Caches and serves Allora Network topic information + +### Blockchain & DeFi + +- **Wallet Provider**: Portfolio data from Zerion, balances and prices +- **DePIN Provider**: Network metrics via DePINScan API +- **Chain Providers**: Data from Abstract, Fuel, ICP, EVM networks +- **Market Provider**: Token data from DexScreener, Birdeye APIs + +### Knowledge & Data + +- **DKG Provider**: OriginTrail decentralized knowledge integration +- **News Provider**: Current events via NewsAPI +- **Trust Provider**: Calculates and injects trust scores + +Visit the [ElizaOS Plugin Registry](https://github.com/elizaos-plugins/registry) for a complete list of available plugins and providers. + +### Time Provider Example + +```typescript +const timeProvider: Provider = { + name: 'time', + description: 'Provides the current date and time', + position: -10, // Run early to ensure time is available for other providers + get: async (_runtime: IAgentRuntime, _message: Memory) => { + const currentDate = new Date(); + const options = { + timeZone: 'UTC', + dateStyle: 'full' as const, + timeStyle: 'long' as const, + }; + const humanReadable = new Intl.DateTimeFormat('en-US', options).format(currentDate); + + return { + text: `The current date and time is ${humanReadable}. Please use this as your reference for any time-based operations or responses.`, + values: { + currentDate: currentDate.toISOString(), + humanReadableDate: humanReadable, + }, + }; + }, +}; +``` + +### Dynamic Provider Example + +```typescript +const weatherProvider: Provider = { + name: 'weather', + description: 'Provides weather information for a location', + dynamic: true, // Only used when explicitly requested + get: async (runtime: IAgentRuntime, message: Memory, state: State) => { + // Extract location from state if available + const location = state?.values?.location || 'San Francisco'; + + try { + // Fetch weather data from an API + const weatherData = await fetchWeatherData(location); + + return { + text: `The current weather in ${location} is ${weatherData.description} with a temperature of ${weatherData.temperature}°C.`, + values: { + weather: { + location, + temperature: weatherData.temperature, + description: weatherData.description, + humidity: weatherData.humidity, + }, + }, + data: { + // Additional detailed data that doesn't go into the context + weatherDetails: weatherData, + }, + }; + } catch (error) { + // Handle errors gracefully + return { + text: `I couldn't retrieve weather information for ${location} at this time.`, + values: { + weather: { error: true }, + }, + }; + } + }, +}; +``` + +--- + +## Best Practices + +### 1. Optimize for Efficiency + +- Return both structured data (`values`) and formatted text (`text`) +- Use caching for expensive operations +- Include a clear provider name and description + +```typescript +const efficientProvider: Provider = { + name: 'efficientExample', + description: 'Efficiently provides cached data', + get: async (runtime, message) => { + // Check for cached data + const cacheKey = `data:${message.roomId}`; + const cachedData = await runtime.getCache(cacheKey); + + if (cachedData) { + return cachedData; + } + + // Fetch fresh data if not cached + const result = { + text: 'Freshly generated information', + values: { + /* key-value pairs */ + }, + data: { + /* structured data */ + }, + }; + + // Cache the result with appropriate TTL + await runtime.setCache(cacheKey, result, { expires: 30 * 60 * 1000 }); // 30 minutes + + return result; + }, +}; +``` + +### 2. Handle Errors Gracefully + +Always handle errors without throwing exceptions that would interrupt the agent's processing: + +```typescript +try { + // Risky operation +} catch (error) { + return { + text: "I couldn't retrieve that information right now.", + values: { error: true }, + }; +} +``` + +### 3. Use Position for Optimal Order + +Position providers according to their dependencies: + +- Negative positions: Fundamental information providers (time, location) +- Zero (default): Standard information providers +- Positive positions: Providers that depend on other information + +### 4. Structure Return Values Consistently + +Maintain a consistent structure in your provider's return values to make data easier to use across the system. + +--- + +## FAQ + +### What's the difference between values, data, and text? + +- `values`: These are merged into the agent state and can be accessed by other providers +- `data`: Structured data stored in state.data.providers but not directly exposed to the agent +- `text`: Formatted text that's directly injected into the agent's context + +### When should I use a dynamic provider? + +Use dynamic providers when the information is expensive to compute, only relevant in specific situations, or requires explicit triggering rather than being included in every context. + +### How do I explicitly include a private provider? + +Private providers must be included in the `includeList` parameter when calling `composeState`: + +```typescript +const state = await runtime.composeState(message, null, ['privateProviderName']); +``` + +### Can providers access service functionality? + +Yes, providers can use services through the runtime. For example, a wallet provider might use a blockchain service to fetch data: + +```typescript +const walletProvider: Provider = { + name: 'wallet', + get: async (runtime, message) => { + const solanaService = runtime.getService('solana'); + if (!solanaService) { + return { text: '' }; + } + + const walletData = await solanaService.getCachedData(); + // Process and return wallet data + }, +}; +``` + +### How should providers handle failures? + +Providers should handle failures gracefully and return valid ProviderResult objects with appropriate error information. Never throw errors that would break the agent's context composition. + +### Can providers maintain state between calls? + +While providers can maintain internal state (e.g., through closures), it's better to use the runtime's cache system for persistence: + +```typescript +// Store data +await runtime.setCache('myProvider:someKey', dataToStore); + +// Retrieve data later +const storedData = await runtime.getCache('myProvider:someKey'); +``` + +--- + +## Further Reading + +- [Provider Implementation](/packages/core/src/providers.ts) +- [Types Reference](/packages/core/src/types.ts) +- [Runtime Integration](/packages/core/src/runtime.ts) +```` + +## File: packages/docs/docs/core/rooms.md +````markdown +--- +sidebar_position: 8 +--- + +# Rooms + +Rooms in ElizaOS represent individual interaction spaces within a world. A room can be a conversation, a channel, a thread, or any other defined space where entities can exchange messages and interact. Rooms are typically contained within a world, though they can also exist independently. + +## Room Structure + +A room in ElizaOS has the following properties: + +```typescript +type Room = { + id: UUID; + name?: string; + agentId?: UUID; + source: string; + type: ChannelType; + channelId?: string; + serverId?: string; + worldId?: UUID; + metadata?: Record; +}; +``` + +| Property | Description | +| ----------- | ---------------------------------------------------------------- | +| `id` | Unique identifier for the room | +| `name` | Optional display name for the room | +| `agentId` | Optional ID of the agent associated with this room | +| `source` | The platform or origin of the room (e.g., 'discord', 'telegram') | +| `type` | Type of room (DM, GROUP, THREAD, etc.) | +| `channelId` | External system channel identifier | +| `serverId` | External system server identifier | +| `worldId` | Optional ID of the parent world | +| `metadata` | Additional room configuration data | + +## Room Types + +ElizaOS supports several room types, defined in the `ChannelType` enum: + +| Type | Description | +| ------------- | ----------------------------------------- | +| `SELF` | Messages to self | +| `DM` | Direct messages between two participants | +| `GROUP` | Group messages with multiple participants | +| `VOICE_DM` | Voice direct messages | +| `VOICE_GROUP` | Voice channels with multiple participants | +| `FEED` | Social media feed | +| `THREAD` | Threaded conversation | +| `WORLD` | World channel | +| `FORUM` | Forum discussion | +| `API` | Legacy type - Use DM or GROUP instead | + +## Room Creation and Management + +### Creating a Room + +You can create a new room using the AgentRuntime: + +```typescript +const roomId = await runtime.createRoom({ + name: 'general-chat', + source: 'discord', + type: ChannelType.GROUP, + channelId: 'external-channel-id', + serverId: 'external-server-id', + worldId: parentWorldId, +}); +``` + +### Ensuring a Room Exists + +To create a room if it doesn't already exist: + +```typescript +await runtime.ensureRoomExists({ + id: roomId, + name: 'general-chat', + source: 'discord', + type: ChannelType.GROUP, + channelId: 'external-channel-id', + serverId: 'external-server-id', + worldId: parentWorldId, +}); +``` + +### Retrieving Room Information + +```typescript +// Get a specific room +const room = await runtime.getRoom(roomId); + +// Get all rooms in a world +const worldRooms = await runtime.getRooms(worldId); +``` + +### Updating Room Properties + +```typescript +await runtime.updateRoom({ + id: roomId, + name: 'renamed-channel', + metadata: { + ...room.metadata, + customProperty: 'value', + }, +}); +``` + +### Deleting a Room - await runtime.addKnowledge(knowledgeItem); -} +```typescript +await runtime.deleteRoom(roomId); ``` -## Directory Structure +## Participants in Rooms -ElizaOS expects knowledge files to be organized in the following structure: +Rooms can have multiple participants (entities) that can exchange messages. -``` -knowledge/ # Root knowledge directory -├── shared/ # Shared knowledge accessible to all agents -└── {agent-name}/ # Agent-specific knowledge directories +### Managing Room Participants + +```typescript +// Add a participant to a room +await runtime.addParticipant(entityId, roomId); + +// Remove a participant from a room +await runtime.removeParticipant(entityId, roomId); + +// Get all participants in a room +const participants = await runtime.getParticipantsForRoom(roomId); + +// Get all rooms where an entity is a participant +const entityRooms = await runtime.getRoomsForParticipant(entityId); ``` -## Supported File Types +### Participant States -- PDF files (`.pdf`) -- Markdown files (`.md`) -- Text files (`.txt`) +Participants can have different states in a room: -## Knowledge Modes +```typescript +// Get a participant's state in a room +const state = await runtime.getParticipantUserState(roomId, entityId); +// Returns: 'FOLLOWED', 'MUTED', or null -ElizaOS supports two knowledge modes: +// Set a participant's state in a room +await runtime.setParticipantUserState(roomId, entityId, 'FOLLOWED'); +``` -### Classic Mode (Default) +The participant states are: -- Direct string knowledge added to character's context -- No chunking or semantic search -- Enabled by default (`settings.ragKnowledge: false`) -- Only processes string knowledge entries -- Simpler but less sophisticated +| State | Description | +| ---------- | ----------------------------------------------------------------------------------------- | +| `FOLLOWED` | The agent actively follows the conversation and responds without being directly mentioned | +| `MUTED` | The agent ignores messages in this room | +| `null` | Default state - the agent responds only when directly mentioned | -### RAG Mode +## Following and Unfollowing Rooms -- Advanced knowledge processing with semantic search -- Chunks content and uses embeddings -- Must be explicitly enabled (`settings.ragKnowledge: true`) -- Supports three knowledge types: - 1. Direct string knowledge - 2. Single file references: `{ "path": "path/to/file.md", "shared": false }` - 3. Directory references: `{ "directory": "knowledge/dir", "shared": false }` -- Supported file types: .md, .txt, .pdf -- Optional `shared` flag for knowledge reuse across characters +ElizaOS allows agents to "follow" rooms to actively participate in conversations without being explicitly mentioned. This functionality is managed through the `FOLLOW_ROOM` and `UNFOLLOW_ROOM` actions. -To enable RAG mode, add this to your character settings: +```typescript +// Follow a room (typically triggered by an action) +await runtime.setParticipantUserState(roomId, runtime.agentId, 'FOLLOWED'); + +// Unfollow a room +await runtime.setParticipantUserState(roomId, runtime.agentId, null); +``` + +## Memory and Messages in Rooms + +Rooms store messages as memories in the database: ```typescript -const character: Character = { - // Other character properties... - settings: { - ragKnowledge: true, +// Create a new message in a room +const messageId = await runtime.createMemory( + { + entityId: senderEntityId, + agentId: runtime.agentId, + roomId: roomId, + content: { + text: 'Hello, world!', + source: 'discord', + }, + metadata: { + type: 'message', + }, }, -}; + 'messages' +); + +// Retrieve recent messages from a room +const messages = await runtime.getMemories({ + roomId: roomId, + count: 10, + unique: true, +}); ``` -## How Knowledge Processing Works +## Events Related to Rooms -### Document Processing Flow +ElizaOS emits events related to room activities: -The RAG system processes documents through several stages: +| Event | Description | +| ------------------ | -------------------------------------------- | +| `ROOM_JOINED` | Emitted when an entity joins a room | +| `ROOM_LEFT` | Emitted when an entity leaves a room | +| `MESSAGE_RECEIVED` | Emitted when a message is received in a room | +| `MESSAGE_SENT` | Emitted when a message is sent to a room | -1. **Directory Processing** +### Handling Room Events - - The system scans configured directories in `knowledge/` - - Files are processed based on their shared/private status and file type +```typescript +// Register event handlers in your plugin +const myPlugin: Plugin = { + name: 'my-room-plugin', + description: 'Handles room events', + + events: { + [EventTypes.ROOM_JOINED]: [ + async (payload) => { + const { runtime, entityId, roomId } = payload; + console.log(`Entity ${entityId} joined room ${roomId}`); + }, + ], -2. **File Processing Pipeline** + [EventTypes.MESSAGE_RECEIVED]: [ + async (payload: MessagePayload) => { + const { runtime, message } = payload; + console.log(`Message received in room ${message.roomId}`); + }, + ], + }, +}; +``` - - **Preprocessing**: Reading, cleaning, and normalizing text - - **Document-level Processing**: Generating embeddings for the entire document - - **Chunk Processing**: Splitting content into manageable chunks and generating embeddings for each +## Room Connection with External Systems -3. **Retrieval Process** - - When a user message is received, its embedding is generated - - This embedding is compared to stored knowledge embeddings - - The most semantically similar chunks are retrieved - - Retrieved knowledge is incorporated into the agent's context +When integrating with external platforms, rooms are typically mapped to channels, conversations, or other interaction spaces: -This multi-level approach enables: +```typescript +// Ensure the connection exists for a room from an external system +await runtime.ensureConnection({ + entityId: userEntityId, + roomId: roomId, + userName: 'username', + name: 'display-name', + source: 'discord', + channelId: 'external-channel-id', + serverId: 'external-server-id', + type: ChannelType.GROUP, + worldId: parentWorldId, +}); +``` -- Broad document-level semantic search -- Fine-grained chunk-level retrieval for specific information -- Efficient parallel processing of large documents -- Maintenance of document context through metadata linking +## Best Practices -### Knowledge Processing Flow Diagram +1. **Use appropriate room types**: Select the most appropriate room type for each interaction context +2. **Follow relationship order**: Create worlds before creating rooms, as rooms often have a parent world +3. **Use ensureRoomExists**: Use this method to avoid duplicate rooms when syncing with external systems +4. **Clean up rooms**: Delete rooms when they're no longer needed to prevent database bloat +5. **Room metadata**: Use metadata for room-specific configuration that doesn't fit into the standard properties +6. **Follow state management**: Implement clear rules for when agents should follow or unfollow rooms +7. **Handle participants carefully**: Ensure that participant management aligns with external platform behavior +```` -```mermaid -graph TB - subgraph Directory_Processing - A[Read Files from Directory] --> B[File Content] - end +## File: packages/docs/docs/core/services.md +````markdown +--- +sidebar_position: 3 +--- - subgraph Preprocessing - B --> C[Clean & Normalize Text] - end +# 🔌 Services - subgraph Document_Processing - C --> D[Generate Document Embedding] - D --> E[Store Full Document] - E --> |Metadata| F[File Path] - E --> |Metadata| G[File Type] - E --> |Metadata| H[Shared Status] - end +Services are core components in Eliza that enable AI agents to interact with external platforms and services. Each service provides a specialized interface for communication while maintaining consistent agent behavior across different platforms. - subgraph Chunk_Processing - C --> I[Split into Chunks] - I --> |512 tokens| J[Chunk 1] - I --> |20 token overlap| K[...] - I --> L[Chunk N] +--- - subgraph Parallel_Processing - J --> M1[Generate Embedding] - K --> M2[Generate Embedding] - L --> M3[Generate Embedding] - end +## Supported Services + +| Service | Type | Key Features | Use Cases | +| ---------------------------------------------------------------------------------- | ------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | +| [Discord](https://github.com/elizaos-plugins/plugin-discord) | Communication | • Voice channels • Server management • Moderation tools • Channel management | • Community management • Gaming servers • Event coordination | +| [Twitter](https://github.com/elizaos-plugins/plugin-twitter) | Social Media | • Post scheduling • Timeline monitoring • Engagement analytics • Content automation | • Brand management • Content creation • Social engagement | +| [Telegram](https://github.com/elizaos-plugins/plugin-telegram) | Messaging | • Bot API • Group chat • Media handling • Command system | • Customer support • Community engagement • Broadcast messaging | +| [Direct](https://github.com/elizaOS/eliza/tree/develop/packages/plugin-direct/src) | API | • REST endpoints • Web integration • Custom applications • Real-time communication | • Backend integration • Web apps • Custom interfaces | +| [GitHub](https://github.com/elizaos-plugins/plugin-github) | Development | • Repository management • Issue tracking • Pull requests • Code review | • Development workflow • Project management • Team collaboration | +| [Slack](https://github.com/elizaos-plugins/plugin-slack) | Enterprise | • Channel management • Conversation analysis • Workspace tools • Integration hooks | • Team collaboration • Process automation • Internal tools | +| [Lens](https://github.com/elizaos-plugins/plugin-lens) | Web3 | • Decentralized networking • Content publishing • Memory management • Web3 integration | • Web3 social networking • Content distribution • Decentralized apps | +| [Farcaster](https://github.com/elizaos-plugins/plugin-farcaster) | Web3 | • Decentralized social • Content publishing • Community engagement | • Web3 communities • Content creation • Social networking | +| [Auto](https://github.com/elizaos-plugins/plugin-auto) | Automation | • Workload management • Task scheduling • Process automation | • Background jobs • Automated tasks • System maintenance | + +**\*Additional services**: + +- Instagram: Social media content and engagement +- XMTP: Web3 messaging and communications +- Alexa: Voice interface and smart device control +- Home Assistant: Home automation OS +- Devai.me: AI first social service +- Simsai: Jeeter / Social media platform for AI - subgraph Chunk_Storage - M1 --> N1[Store Chunk] - M2 --> N2[Store Chunk] - M3 --> N3[Store Chunk] +--- - N1 --> |Metadata| O[Original Doc Reference] - N1 --> |Metadata| P[Chunk Index] - N2 --> |Metadata| O - N2 --> |Metadata| P - N3 --> |Metadata| O - N3 --> |Metadata| P - end - end +## System Overview - style Directory_Processing fill:#f9f,stroke:#333,stroke-width:2px - style Preprocessing fill:#bbf,stroke:#333,stroke-width:2px - style Document_Processing fill:#bfb,stroke:#333,stroke-width:2px - style Chunk_Processing fill:#fbf,stroke:#333,stroke-width:2px - style Parallel_Processing fill:#fbb,stroke:#333,stroke-width:2px - style Chunk_Storage fill:#bff,stroke:#333,stroke-width:2px -``` +Services serve as bridges between Eliza agents and various platforms, providing core capabilities: -### Processing Parameters +1. **Message Processing** -- **Chunk Size**: 512 tokens (default, configurable when adding knowledge) -- **Chunk Overlap**: 20 tokens (default, configurable) -- **Processing Batch Size**: 10 chunks processed concurrently -- **Default Similarity Threshold**: 0.85 for retrieval -- **Default Match Count**: 5 results returned + - Platform-specific message formatting and delivery + - Media handling and attachments via [`Memory`](/api/interfaces/Memory) objects + - Reply threading and context management + - Support for different content types -## Best Practices for Knowledge Management +2. **State & Memory Management** -### Content Organization + - Each service maintains independent state to prevent cross-platform contamination + - Integrates with runtime memory managers for different types of content: + - Messages processed by one service don't automatically appear in other services' contexts + - [`State`](/api/interfaces/State) persists across agent restarts through the database adapter -1. **Document Structure** +3. **Platform Integration** + - Authentication and API compliance + - Event processing and webhooks + - Rate limiting and cache management + - Platform-specific feature support - - Use clear section headings and hierarchical organization - - Break large documents into logical smaller files - - Include metadata and context in markdown files - - Structure information from general to specific +## Service Configuration -2. **File Management** +Services are configured through the [`Character`](/api/type-aliases/Character) configuration's `settings` property: - - Use descriptive filenames that reflect content - - Group related files in subdirectories - - Keep paths short and meaningful - - Avoid special characters in filenames +```typescript +export type Character = { + // ... other properties ... + settings?: { + discord?: { + shouldIgnoreBotMessages?: boolean; + shouldIgnoreDirectMessages?: boolean; + shouldRespondOnlyToMentions?: boolean; + messageSimilarityThreshold?: number; + isPartOfTeam?: boolean; + teamAgentIds?: string[]; + teamLeaderId?: string; + teamMemberInterestKeywords?: string[]; + allowedChannelIds?: string[]; + autoPost?: { + enabled?: boolean; + monitorTime?: number; + inactivityThreshold?: number; + mainChannelId?: string; + announcementChannelIds?: string[]; + minTimeBetweenPosts?: number; + }; + }; + telegram?: { + shouldIgnoreBotMessages?: boolean; + shouldIgnoreDirectMessages?: boolean; + shouldRespondOnlyToMentions?: boolean; + shouldOnlyJoinInAllowedGroups?: boolean; + allowedGroupIds?: string[]; + messageSimilarityThreshold?: number; + // ... other telegram-specific settings + }; + slack?: { + shouldIgnoreBotMessages?: boolean; + shouldIgnoreDirectMessages?: boolean; + }; + // ... other service configs + }; +}; +``` -3. **Knowledge Optimization** - - Keep individual documents focused on specific topics - - For very detailed information, use smaller chunks (200-300 tokens) by setting `targetTokens` - - Balance the total number of knowledge items for performance - - Prefer markdown (.md) files for best processing results +## Service Implementation -### Processing Large Knowledge Bases +Each service manages its own: -When adding many knowledge items at once, consider implementing a semaphore pattern: +- Platform-specific message formatting and delivery +- Event processing and webhooks +- Authentication and API integration +- Message queueing and rate limiting +- Media handling and attachments +- State management and persistence + +Example of a basic service implementation: ```typescript -import { Semaphore } from '@elizaos/core'; +import { Service, IAgentRuntime } from '@elizaos/core'; -// Create semaphore to limit concurrent processing -const semaphore = new Semaphore(10); +export class CustomService extends Service { + static serviceType = 'custom'; + capabilityDescription = 'The agent is able to interact with the custom platform'; -// Process items with controlled concurrency -await Promise.all( - items.map(async (item) => { - await semaphore.acquire(); - try { - await runtime.addKnowledge(item); - } finally { - semaphore.release(); - } - }) -); + constructor(protected runtime: IAgentRuntime) { + super(); + // Initialize platform connection + // Set up event handlers + // Configure message processing + } + + static async start(runtime: IAgentRuntime): Promise { + const service = new CustomService(runtime); + // Additional initialization if needed + return service; + } + + async stop(): Promise { + // Cleanup resources + // Close connections + } +} ``` -### Knowledge ID Management +### Runtime Integration -When adding knowledge programmatically, use consistent ID generation: +Services interact with the agent runtime through the [`IAgentRuntime`](api/interfaces/IAgentRuntime/) interface, which provides: -```typescript -import { createUniqueUuid } from '@elizaos/core'; -const knowledgeId = createUniqueUuid(runtime, 'my-content'); -``` +- Memory managers for different types of data storage +- Service access for capabilities like transcription or image generation +- State management and composition +- Message processing and action handling -This ensures deterministic IDs that remain stable across sessions. +### Memory System Integration -## Troubleshooting +Services use the runtime's memory managers to persist conversation data (source: [`memory.ts`](/api/interfaces/Memory)). -### Common Issues and Solutions +- `messageManager` Chat messages +- `documentsManager` File attachments +- `descriptionManager` Media descriptions -1. **Knowledge Not Being Retrieved**: +
+See example +```typescript +// Store a new message +await runtime.messageManager.createMemory({ + id: messageId, + content: { text: message.content }, + userId: userId, + roomId: roomId, + agentId: runtime.agentId +}); - - Verify the file is in a supported format (PDF, MD, TXT) - - Check if embeddings were properly generated - - Ensure similarity threshold isn't too high (default: 0.85) - - Test retrieval with more specific queries - - Verify RAG mode is enabled if using file/directory references +// Retrieve recent messages +const recentMessages = await runtime.messageManager.getMemories({ +roomId: roomId, +count: 10 +}); -2. **Poor Quality Retrievals**: +``` +
- - Break down large documents into smaller, focused files - - Ensure document content is clear and well-structured - - Review the chunking size and overlap settings - - Check if the query contains too many common words -3. **Performance Issues**: +--- - - Monitor the total number of knowledge items - - Consider reducing the match count for faster retrieval - - Check embedding processing time for large documents - - Use shared knowledge efficiently across agents +## FAQ -4. **File Processing Errors**: - - Verify file permissions - - Check if paths are correctly structured - - Ensure PDF files are readable and not password-protected - - Validate that text encoding is UTF-8 +### What can services actually do? -## Technical Implementation Details +Services handle platform-specific communication (like Discord messages or Twitter posts), manage memories and state, and execute actions like processing media or handling commands. Each service adapts these capabilities to its platform while maintaining consistent agent behavior. -### Knowledge ID Relationships +### Can multiple services be used simultaneously? +Yes, Eliza supports running multiple services concurrently while maintaining consistent agent behavior across platforms. -The RAG system uses a hierarchical ID structure to maintain relationships: +### How are service-specific features handled? +Each service implements platform-specific features through its capabilities system, while maintaining a consistent interface for the agent. -```mermaid -classDiagram - class Document { - +UUID id - +String filePath - +String fileType - +Boolean isShared - +Float32Array embedding - +String content - } +### How do services handle rate limits? +Services implement platform-specific rate limiting with backoff strategies and queue management. - class Fragment { - +UUID id - +UUID originalId - +Number chunkIndex - +String content - +Float32Array embedding - +String originalPath - } +### How is service state managed? +Services maintain their own connection state while integrating with the agent's runtime database adapter and memory / state management system. + +### How do services handle messages? - Document "1" --> "*" Fragment : generates -``` +Services translate platform messages into Eliza's internal format, process any attachments (images, audio, etc.), maintain conversation context, and manage response queuing and rate limits. -#### ID Generation and Linking +### How are messages processed across services? +Each service processes messages independently in its platform-specific format, while maintaining conversation context through the shared memory system. V2 improves upon this architecture. -Documents IDs are generated using `createUniqueUuid(runtime, path, isShared)`, making them deterministic. Fragment IDs follow the format `${documentId}-chunk-${index}` to maintain the relationship to their source document. +### How is state managed between services? +Each service maintains separate state to prevent cross-contamination, but can access shared agent state through the runtime. -## API Reference -### Key Methods +### How do services integrate with platforms? -#### `runtime.addKnowledge(item: KnowledgeItem, options?): Promise` +Each service implements platform-specific authentication, API compliance, webhook handling, and follows the platform's rules for rate limiting and content formatting. -Adds new knowledge to the agent. +### How do services manage memory? -- Parameters: - - `item`: A knowledge item containing: - - `id`: UUID - - `content`: Object with `text` property - - `options`: Optional processing configuration: - - `targetTokens`: Number (default: 3000) - - `overlap`: Number (default: 200) - - `modelContextSize`: Number (default: 4096) +Services use Eliza's memory system to track conversations, user relationships, and state, enabling context-aware responses and persistent interactions across sessions. +``` +```` -#### `runtime.getKnowledge(message: Memory): Promise` +## File: packages/docs/docs/core/tasks.md +````markdown +--- +sidebar_position: 9 +--- -Retrieves knowledge based on a message's content. +# Tasks -- Parameters: - - `message`: Memory object containing user message -- Returns: Array of matching KnowledgeItem objects +Tasks in ElizaOS provide a powerful way to manage deferred, scheduled, and interactive operations. The Task system allows agents to queue work for later execution, repeat actions at defined intervals, await user input, and implement complex workflows across multiple interactions. -### Knowledge Item Definition +## Task Structure + +A task in ElizaOS has the following properties: ```typescript -interface KnowledgeItem { - id: UUID; - content: { - text: string; - // Optional additional metadata - [key: string]: any; +interface Task { + id?: UUID; // Unique identifier (auto-generated if not provided) + name: string; // Name of the task (must match a registered task worker) + updatedAt?: number; // Timestamp when the task was last updated + metadata?: { + // Optional additional configuration + updateInterval?: number; // For repeating tasks: milliseconds between executions + options?: { + // For choice tasks: options for user selection + name: string; + description: string; + }[]; + [key: string]: unknown; // Additional custom metadata }; + description: string; // Human-readable description of the task + roomId?: UUID; // Optional room association (for room-specific tasks) + worldId?: UUID; // Optional world association (for world-specific tasks) + tags: string[]; // Tags for categorizing and filtering tasks } ``` -## Security Considerations +## Task Workers -1. **Access Control**: +Task workers define the actual logic that executes when a task runs. Each task worker is registered with the runtime and is identified by name. - - Use the `shared` flag appropriately to control document access - - Keep sensitive information in agent-specific directories - - Regularly audit knowledge access patterns +```typescript +interface TaskWorker { + name: string; // Matches the name in the Task + execute: ( + runtime: IAgentRuntime, + options: { [key: string]: unknown }, // Options passed during execution + task: Task // The task being executed + ) => Promise; + validate?: ( + // Optional validation before execution + runtime: IAgentRuntime, + message: Memory, + state: State + ) => Promise; +} +``` -2. **Data Privacy**: - - Do not store sensitive personal information in knowledge files - - Review documents for potentially sensitive content before adding - - Implement appropriate backup and recovery procedures +## Creating and Managing Tasks -## Future Considerations +### Registering a Task Worker -1. **Scalability**: +Before creating tasks, you must register a worker to handle the execution: - - Monitor knowledge base size and performance - - Plan for regular maintenance and cleanup - - Consider implementing document versioning +```typescript +runtime.registerTaskWorker({ + name: 'SEND_REMINDER', + validate: async (runtime, message, state) => { + // Optional validation logic + return true; + }, + execute: async (runtime, options, task) => { + // Task execution logic + const { roomId } = task; + const { reminder, userId } = options; -2. **Integration**: - - Document integration points with other systems - - Plan for potential future file format support - - Consider implementing knowledge base analytics + await runtime.createMemory( + { + entityId: runtime.agentId, + roomId, + content: { + text: `Reminder for <@${userId}>: ${reminder}`, + }, + }, + 'messages' + ); -## Support and Resources + // Delete the task after it's completed + await runtime.deleteTask(task.id); + }, +}); +``` -- Review the implementation in `packages/core/src/ragknowledge.ts` -- Check the issue tracker for known issues and solutions -- Contribute improvements and bug fixes through pull requests -```` +### Creating a One-time Task -## File: packages/docs/docs/core/overview.md -````markdown ---- -sidebar_position: 1 ---- +Create a task that will execute once: + +```typescript +await runtime.createTask({ + name: 'SEND_REMINDER', + description: 'Send a reminder message to the user', + roomId: currentRoomId, + tags: ['reminder', 'one-time'], + metadata: { + userId: message.entityId, + reminder: 'Submit your weekly report', + scheduledFor: Date.now() + 86400000, // 24 hours from now + }, +}); +``` + +### Creating a Recurring Task + +Create a task that repeats at regular intervals: + +```typescript +await runtime.createTask({ + name: 'DAILY_REPORT', + description: 'Generate and post the daily report', + roomId: announcementChannelId, + worldId: serverWorldId, + tags: ['report', 'repeat', 'daily'], + metadata: { + updateInterval: 86400000, // 24 hours in milliseconds + updatedAt: Date.now(), // When the task was last updated/executed + }, +}); +``` + +### Creating a Task Awaiting User Choice -# Overview +Create a task that presents options and waits for user input: -ElizaOS is a framework for creating AI agents that can interact across multiple platforms through a consistent, extensible architecture. +```typescript +await runtime.createTask({ + name: 'CONFIRM_ACTION', + description: 'Confirm the requested action', + roomId: message.roomId, + tags: ['confirmation', 'AWAITING_CHOICE'], + metadata: { + options: [ + { name: 'confirm', description: 'Proceed with the action' }, + { name: 'cancel', description: 'Cancel the action' }, + ], + action: 'DELETE_FILES', + files: ['document1.txt', 'document2.txt'], + }, +}); +``` -## Core Features +### Managing Tasks -- **Modular Architecture**: A plugin-based system for extending functionality -- **Entity-Component System**: Flexible data modeling for agents and users -- **Vector-Based Memory**: Semantic retrieval of conversations and knowledge -- **Multi-Modal Interactions**: Support for text, voice, images, and other media formats -- **Reflection & Self-Improvement**: Agents learn from interactions and adapt over time -- **Cross-Platform Integration**: Connect to multiple services through a unified interface +Retrieve, update, and delete tasks as needed: -## Key Components +```typescript +// Get tasks by specific criteria +const reminderTasks = await runtime.getTasks({ + roomId: currentRoomId, + tags: ['reminder'], +}); -ElizaOS consists of these core architectural components: +// Get tasks by name +const reportTasks = await runtime.getTasksByName('DAILY_REPORT'); -[![](/img/architecture.png)](/img/architecture.png) +// Get a specific task +const task = await runtime.getTask(taskId); -### [Agent Runtime](./agents.md) +// Update a task +await runtime.updateTask(taskId, { + description: 'Updated description', + metadata: { + ...task.metadata, + priority: 'high', + }, +}); + +// Delete a task +await runtime.deleteTask(taskId); +``` -The Agent Runtime is the central nervous system of ElizaOS. It orchestrates all components, manages state, processes messages, and coordinates the agent's behavior. +## Task Processing -**Responsibilities:** +Tasks are processed based on their configuration: -- Lifecycle management -- Service coordination -- Memory management -- State composition -- Action execution -- Model integration +### One-time Tasks -### [Projects](./project.md) +Tasks without an `updateInterval` are executed once when triggered by your code. You are responsible for scheduling their execution by checking for pending tasks in appropriate contexts. -Projects are the top-level containers that define one or more agents, their configurations, and shared resources. A project: +### Recurring Tasks -- Defines agent characters and behavior -- Configures plugins and services -- Sets up knowledge and memory systems -- Establishes shared worlds and environments +Tasks with an `updateInterval` are automatically considered for re-execution when: -### [Entities & Components](./entities.md) +1. The current time exceeds `updatedAt + updateInterval` +2. Your code explicitly checks for pending recurring tasks -ElizaOS uses an entity-component architecture for flexible data modeling: +To process recurring tasks, implement logic like this: + +```typescript +// In an initialization function or periodic check +async function processRecurringTasks() { + const now = Date.now(); + const recurringTasks = await runtime.getTasks({ + tags: ['repeat'], + }); + + for (const task of recurringTasks) { + if (!task.metadata?.updateInterval) continue; + + const lastUpdate = task.metadata.updatedAt || 0; + const interval = task.metadata.updateInterval; + + if (now >= lastUpdate + interval) { + const worker = runtime.getTaskWorker(task.name); + if (worker) { + try { + await worker.execute(runtime, {}, task); + + // Update the task's last update time + await runtime.updateTask(task.id, { + metadata: { + ...task.metadata, + updatedAt: now, + }, + }); + } catch (error) { + logger.error(`Error executing task ${task.name}: ${error}`); + } + } + } + } +} +``` -- **Entities**: Base objects with unique identifiers (agents, users, etc.) -- **Components**: Modular data attached to entities (profiles, settings, etc.) +### Tasks Awaiting User Input -This architecture allows for dynamic composition of objects and extensible data models without complex inheritance hierarchies. +Tasks tagged with `AWAITING_CHOICE` are presented to users and wait for their input. These tasks use: -### [Services](./services.md) +1. The `choice` provider to display available options to users +2. The `CHOOSE_OPTION` action to process user selections -Services connect agents to different platforms (Discord, X/Twitter, Telegram, etc.) and provide specialized capabilities: +## Common Task Patterns -- **Platform Services**: Connect to external platforms -- **Core Services**: Provide essential functionality (speech, vision, etc.) -- **Extension Services**: Add specialized capabilities +### Deferred Follow-ups -Services use a consistent interface but can provide platform-specific features when needed. +Create a task to follow up with a user later: -### [Actions](./actions.md) +```typescript +runtime.registerTaskWorker({ + name: 'FOLLOW_UP', + execute: async (runtime, options, task) => { + const { roomId } = task; + const { userId, topic } = task.metadata; + + await runtime.createMemory( + { + entityId: runtime.agentId, + roomId, + content: { + text: `Hi <@${userId}>, I'm following up about ${topic}. Do you have any updates?`, + }, + }, + 'messages' + ); + + await runtime.deleteTask(task.id); + }, +}); + +// Create a follow-up task for 2 days later +await runtime.createTask({ + name: 'FOLLOW_UP', + description: 'Follow up with user about project status', + roomId: message.roomId, + tags: ['follow-up', 'one-time'], + metadata: { + userId: message.entityId, + topic: 'the project timeline', + scheduledFor: Date.now() + 2 * 86400000, // 2 days + }, +}); +``` -Actions define how agents respond to messages and interact with the world: +### Multi-step Workflows -- **Communication Actions**: Generate responses and engage in conversation -- **Integration Actions**: Interact with external systems and APIs -- **Media Actions**: Generate and process images, audio, and other media -- **Platform Actions**: Leverage platform-specific features +Implement complex workflows that span multiple interactions: -Each action includes validation logic, a handler function, and thought processes that explain the agent's reasoning. +```typescript +// First step: Gather requirements +runtime.registerTaskWorker({ + name: 'GATHER_REQUIREMENTS', + execute: async (runtime, options, task) => { + // Ask user for requirements and create a new task for the next step + await runtime.createTask({ + name: 'CONFIRM_REQUIREMENTS', + description: 'Confirm gathered requirements', + roomId: task.roomId, + tags: ['workflow', 'AWAITING_CHOICE'], + metadata: { + previousStep: 'GATHER_REQUIREMENTS', + requirements: options.requirements, + options: [ + { name: 'confirm', description: 'Confirm requirements are correct' }, + { name: 'revise', description: 'Need to revise requirements' }, + ], + }, + }); -### [Providers](./providers.md) + await runtime.deleteTask(task.id); + }, +}); -Providers supply contextual information to agents as they make decisions: +// Second step: Confirm requirements +runtime.registerTaskWorker({ + name: 'CONFIRM_REQUIREMENTS', + execute: async (runtime, options, task) => { + if (options.option === 'confirm') { + // Move to the next step + await runtime.createTask({ + name: 'GENERATE_SOLUTION', + description: 'Generate solution based on requirements', + roomId: task.roomId, + tags: ['workflow'], + metadata: { + previousStep: 'CONFIRM_REQUIREMENTS', + requirements: task.metadata.requirements, + }, + }); + } else { + // Go back to requirements gathering + await runtime.createTask({ + name: 'GATHER_REQUIREMENTS', + description: 'Revise requirements', + roomId: task.roomId, + tags: ['workflow'], + metadata: { + previousStep: 'CONFIRM_REQUIREMENTS', + previousRequirements: task.metadata.requirements, + }, + }); + } -- **Memory Providers**: Access relevant conversation history -- **Knowledge Providers**: Supply factual information -- **State Providers**: Provide current context and environment details -- **Temporal Providers**: Manage time-based awareness + await runtime.deleteTask(task.id); + }, +}); +``` -Providers are dynamically composed to create a comprehensive context for agent decision-making. +### Scheduled Reports -### [Evaluators](./evaluators.md) +Create tasks that generate and post reports on a schedule: -Evaluators analyze conversations after they happen, helping agents learn and improve: +```typescript +runtime.registerTaskWorker({ + name: 'GENERATE_WEEKLY_REPORT', + execute: async (runtime, options, task) => { + const { roomId } = task; -- **Reflection Evaluator**: Enables self-awareness and improvement -- **Fact Evaluator**: Extracts factual information from conversations -- **Goal Evaluator**: Tracks progress on objectives -- **Relationship Evaluator**: Models connections between entities + // Generate report content + const reportData = await generateWeeklyReport(runtime); -Evaluators create a feedback loop for continuous agent improvement. + // Post the report + await runtime.createMemory( + { + entityId: runtime.agentId, + roomId, + content: { + text: `# Weekly Report\n\n${reportData}`, + }, + }, + 'messages' + ); -### [Plugins](./plugins.md) + // The task stays active for next week (updateInterval handles timing) + }, +}); -Plugins extend ElizaOS with new capabilities by adding services, actions, providers, evaluators, and more: +// Create a weekly report task +await runtime.createTask({ + name: 'GENERATE_WEEKLY_REPORT', + description: 'Generate and post weekly activity report', + roomId: reportChannelId, + worldId: serverWorldId, + tags: ['report', 'repeat', 'weekly'], + metadata: { + updateInterval: 7 * 86400000, // 7 days + updatedAt: Date.now(), + format: 'markdown', + }, +}); +``` -- **Core Plugins**: Essential functionality for all agents -- **Platform Plugins**: Integrations with external platforms -- **Capability Plugins**: Special abilities like blockchain interaction -- **Utility Plugins**: Tools for specific tasks or domains +## Task Events and Monitoring -Plugins use a consistent installation and configuration pattern. +ElizaOS doesn't currently provide built-in events for task lifecycle, so implement your own monitoring if needed: -## Data Systems +```typescript +// Custom monitoring for task execution +async function executeTaskWithMonitoring(runtime, taskWorker, task) { + try { + // Create a start log + await runtime.log({ + body: { taskId: task.id, action: 'start' }, + entityId: runtime.agentId, + roomId: task.roomId, + type: 'TASK_EXECUTION', + }); -### [Database System](./database.md) + // Execute the task + await taskWorker.execute(runtime, {}, task); -ElizaOS uses a flexible adapter-based database system: + // Create a completion log + await runtime.log({ + body: { taskId: task.id, action: 'complete', success: true }, + entityId: runtime.agentId, + roomId: task.roomId, + type: 'TASK_EXECUTION', + }); + } catch (error) { + // Create an error log + await runtime.log({ + body: { taskId: task.id, action: 'error', error: error.message }, + entityId: runtime.agentId, + roomId: task.roomId, + type: 'TASK_EXECUTION', + }); + } +} +``` -- **Entity Storage**: Manages entity and component data -- **Memory System**: Stores conversations and extracted facts -- **Vector Search**: Enables semantic retrieval of information -- **Relationship Tracking**: Maps connections between entities -- **World & Room Management**: Organizes conversation spaces +## Best Practices -The current implementation supports PGLite (for development) and PostgreSQL (for production) using Drizzle ORM. +1. **Use descriptive names and descriptions**: Make tasks easily identifiable with clear names and descriptions -### [Knowledge System](./knowledge.md) +2. **Clean up completed tasks**: Delete one-time tasks after execution to prevent database bloat -The knowledge system enables agents to access and use structured information: +3. **Add error handling**: Implement robust error handling in task workers to prevent failures from breaking workflows -- **Document Processing**: Converts various file formats into usable knowledge -- **RAG Implementation**: Retrieval-Augmented Generation for contextual responses -- **Semantic Search**: Finds relevant information through vector similarity -- **Memory Integration**: Combines knowledge with conversation memory +4. **Use appropriate tags**: Tag tasks effectively for easy retrieval and categorization -## Structural Elements +5. **Validate carefully**: Use the `validate` function to ensure tasks only execute in appropriate contexts -### [Worlds](./worlds.md) +6. **Keep tasks atomic**: Design tasks to perform specific, well-defined operations rather than complex actions -Worlds are containers for agents, rooms, and shared resources that provide: +7. **Provide clear choices**: When creating choice tasks, make option names and descriptions clear and unambiguous -- Namespace isolation -- Resource sharing -- Multi-agent environments -- Context boundaries +8. **Manage task lifecycles**: Have a clear strategy for when tasks are created, updated, and deleted -### [Rooms](./rooms.md) +9. **Set reasonable intervals**: For recurring tasks, choose appropriate update intervals that balance timeliness and resource usage -Rooms are conversation spaces where entities interact: +10. **Handle concurrent execution**: Ensure task execution is idempotent to handle potential concurrent executions +```` -- Direct messages between entities -- Group conversations -- Platform-specific channels -- Persistent conversation history +## File: packages/docs/docs/core/worlds.md +````markdown +--- +sidebar_position: 7 +--- -### [Tasks](./tasks.md) +# Worlds -The task system enables asynchronous processing and scheduled operations: +Worlds in ElizaOS are collections of entities (users, agents) and rooms (conversations, channels) that form a cohesive environment for interactions. Think of a world as a virtual space, like a Discord server, Slack workspace, or 3D MMO environment, where entities can communicate across multiple channels or areas. -- Background processing -- Scheduled activities -- Workflow management -- Event-driven operations +## World Structure -## System Flow +A world in ElizaOS has the following properties: -When a message is received: +```typescript +type World = { + id: UUID; + name?: string; + agentId: UUID; + serverId: string; + metadata?: { + ownership?: { + ownerId: string; + }; + roles?: { + [entityId: UUID]: Role; + }; + [key: string]: unknown; + }; +}; +``` -1. The **Service** receives the input and forwards it to the **Runtime** -2. The **Runtime** loads the agent configuration from the **Project** -3. **Providers** supply context (memories, knowledge, state) -4. Valid **Actions** are identified through validation functions -5. The agent decides on a response, including internal **thoughts** -6. The response is returned through the **Service** -7. **Evaluators** analyze the conversation for insights -8. New memories and relationships are stored in the **Database** +| Property | Description | +| ---------- | ---------------------------------------------------- | +| `id` | Unique identifier for the world | +| `name` | Optional display name | +| `agentId` | ID of the agent managing this world | +| `serverId` | External system identifier (e.g., Discord server ID) | +| `metadata` | Additional world configuration data | -This creates a continuous cycle of interaction, reflection, and improvement. +The metadata can store custom information, including ownership details and role assignments for entities within the world. -## Common Patterns +## World Creation and Management -### Creating an Agent Response +### Creating a World + +You can create a new world using the AgentRuntime: ```typescript -// The agent runtime processes a message and generates a response -const result = await runtime.processMessage({ - entityId: senderId, - roomId: channelId, - content: { text: 'Hello, how are you?' }, +const worldId = await runtime.createWorld({ + name: 'My Project Space', + agentId: runtime.agentId, + serverId: 'external-system-id', + metadata: { + ownership: { + ownerId: ownerEntityId, + }, + }, }); +``` -// The response includes thought process and actions -console.log(result.thought); // Internal reasoning (not shown to user) -console.log(result.text); // The actual response -console.log(result.actions); // Actions performed +For many integrations, worlds are automatically created during connection setup with external platforms like Discord or Slack. + +### Ensuring a World Exists + +If you're not sure if a world exists, you can use `ensureWorldExists()`: + +```typescript +await runtime.ensureWorldExists({ + id: worldId, + name: 'My Project Space', + agentId: runtime.agentId, + serverId: 'external-system-id', +}); ``` -### Storing and Retrieving Memories +### Retrieving World Information ```typescript -// Store a memory -await runtime.createMemory( - { - entityId: userId, - roomId: channelId, - content: { text: 'Important information' }, - embedding: await runtime.useModel(ModelType.TEXT_EMBEDDING, { - text: 'Important information', - }), - }, - 'facts' -); +// Get a specific world +const world = await runtime.getWorld(worldId); -// Retrieve relevant memories -const memories = await runtime.searchMemories({ - tableName: 'messages', - roomId: channelId, - embedding: embedding, - count: 5, -}); +// Get all worlds +const allWorlds = await runtime.getAllWorlds(); ``` -### Creating a Relationship Between Entities +### Updating World Properties ```typescript -// Establish a relationship -await runtime.createRelationship({ - sourceEntityId: userEntityId, - targetEntityId: agentEntityId, - tags: ['friend', 'frequent_interaction'], +await runtime.updateWorld({ + id: worldId, + name: 'Updated Name', metadata: { - interactions: 12, - trust_level: 'high', + ...world.metadata, + customProperty: 'value', }, }); ``` -## FAQ +## World Roles System -### What's the difference between Actions, Evaluators, and Providers? +Worlds support a role-based permission system with the following roles: -**Actions** define what an agent can do and are executed during response generation. **Evaluators** analyze conversations after they happen to extract insights and improve future responses. **Providers** supply contextual information before the agent decides how to respond. +| Role | Description | +| ------- | ----------------------------------------------------- | +| `OWNER` | Full control over the world, can assign any roles | +| `ADMIN` | Administrative capabilities, can manage most settings | +| `NONE` | Standard participant with no special permissions | -### How do agent thoughts relate to evaluator reflections? +### Managing Roles -Agent **thoughts** are generated during response creation to explain reasoning in the moment. Evaluator **reflections** happen after responses, analyzing longer-term patterns and extracting insights for future interactions. +Roles are stored in the world's metadata and can be updated: -### How is memory organized in ElizaOS? +```typescript +// Get existing world +const world = await runtime.getWorld(worldId); -Memory is organized into different types (messages, facts, knowledge) and stored with vector embeddings for semantic search. This allows agents to retrieve relevant memories based on context rather than just recency. +// Ensure roles object exists +if (!world.metadata) world.metadata = {}; +if (!world.metadata.roles) world.metadata.roles = {}; -### How does the entity-component system work? +// Assign a role to an entity +world.metadata.roles[entityId] = Role.ADMIN; -The entity-component system provides a flexible way to model data. **Entities** are base objects with unique IDs, while **Components** are pieces of data attached to entities. This allows for dynamic composition without complex inheritance. +// Save the world +await runtime.updateWorld(world); +``` -### How do I extend an agent with new capabilities? +For programmatic role management, you can use role-related utilities: -Create or install plugins that provide new actions, services, providers, or evaluators. Plugins can be registered in the project configuration and will be automatically loaded when the agent starts. +```typescript +import { canModifyRole, findWorldForOwner } from '@elizaos/core'; -### What model providers are supported? +// Check if user can modify roles +if (canModifyRole(userRole, targetRole, newRole)) { + // Allow role change +} -ElizaOS supports multiple model providers including OpenAI, Anthropic, and local models. The model provider is configured at the project level and can be overridden for specific operations. +// Find world where user is owner +const userWorld = await findWorldForOwner(runtime, entityId); +``` -### How do I configure the database? +## World Settings -ElizaOS currently supports PostgreSQL (recommended for production) and PGLite (for development). Configure the connection using environment variables like `POSTGRES_URL` or `PGLITE_DATA_DIR`. +Worlds support configurable settings that can be stored and retrieved: -### How do services differ from the old "clients"? +```typescript +// Get settings for a world +const worldSettings = await getWorldSettings(runtime, serverId); + +// Update world settings +worldSettings.MY_SETTING = { + name: 'My Setting', + description: 'Description for users', + value: 'setting-value', + required: false, +}; -Services provide a more comprehensive integration model than the previous "clients" concept. They offer standardized interfaces for various platforms while allowing for platform-specific features and optimizations. +// Save settings +await updateWorldSettings(runtime, serverId, worldSettings); +``` -## Getting Started +## World Events + +ElizaOS emits events related to world activities: + +| Event | Description | +| ----------------- | ---------------------------------------------- | +| `WORLD_JOINED` | Emitted when an agent joins a world | +| `WORLD_CONNECTED` | Emitted when a world is successfully connected | +| `WORLD_LEFT` | Emitted when an agent leaves a world | + +### Handling World Events + +```typescript +// Register event handlers in your plugin +const myPlugin: Plugin = { + name: 'my-world-plugin', + description: 'Handles world events', + + events: { + [EventTypes.WORLD_JOINED]: [ + async (payload: WorldPayload) => { + const { world, runtime } = payload; + console.log(`Joined world: ${world.name}`); + }, + ], + + [EventTypes.WORLD_LEFT]: [ + async (payload: WorldPayload) => { + const { world, runtime } = payload; + console.log(`Left world: ${world.name}`); + }, + ], + }, +}; +``` + +## Relationship with Rooms + +A world contains multiple rooms that entities can interact in. Each room points back to its parent world via the `worldId` property. + +```typescript +// Get all rooms in a world +const worldRooms = await runtime.getRooms(worldId); +``` + +See the [Rooms](./rooms.md) documentation for more details on managing rooms within worlds. + +## Best Practices -To create your first ElizaOS project, see the [Quick Start Guide](../quickstart.md) +1. **Always check permissions**: Before performing administrative actions, verify the user has appropriate roles +2. **Handle world metadata carefully**: The metadata object can contain critical configuration, so modify it with care +3. **World-room syncing**: When syncing with external platforms, keep world and room structures in alignment +4. **Event-driven architecture**: Use events to respond to world changes rather than polling for updates +5. **Default settings**: Provide sensible defaults for world settings to make configuration easier ```` ## File: packages/docs/docs/quickstart.md @@ -4444,7 +8294,7 @@ cd eliza ### Node Version -- Use Node 23.3.0+ (`node -v` to check) +- Use Node.js 23.3.0+ (`node -v` to check) - Try using NVM: `nvm use 23` ### Installation Problems @@ -4487,8 +8337,1854 @@ Once you have your agent running, explore: Join the [Discord community](https://discord.gg/elizaOS) for support and to share what you're building! ```` +## File: packages/docs/src/openapi/eliza-v1.yaml +````yaml +openapi: 3.0.0 +info: + title: Eliza OS API + description: |- + API documentation for Eliza OS v1.0.0-alpha - A flexible and scalable AI agent framework. + This API is designed to be used with a locally running Eliza instance. Endpoints allow for creating, + managing, and interacting with AI agents through a REST interface. + version: 1.0.0-alpha + contact: + name: Eliza OS Community + url: https://github.com/elizaos/eliza +servers: + - url: http://localhost:3000 + description: Local development server +tags: + - name: system + description: System-wide operations + - name: agents + description: Operations for managing AI agents + - name: rooms + description: Operations for managing conversation rooms + - name: messages + description: Operations for interacting with agents via text messages + - name: memories + description: Operations for accessing agent memories + - name: logs + description: Operations for accessing system and agent logs + - name: speech + description: Operations for speech and audio processing + - name: tee + description: Trusted Execution Environment operations +paths: + /api/hello: + get: + tags: + - system + summary: Basic health check + description: Simple hello world test endpoint + operationId: getHello + responses: + '200': + description: Hello world response + content: + application/json: + schema: + type: object + properties: + message: + type: string + example: 'Hello World!' + /api/status: + get: + tags: + - system + summary: Get system status + description: Returns the current status of the system with agent count and timestamp + operationId: getStatus + responses: + '200': + description: System status information + content: + application/json: + schema: + type: object + properties: + status: + type: string + example: 'ok' + agentCount: + type: integer + description: Number of active agents + timestamp: + type: string + format: date-time + description: Current timestamp + /api/health: + get: + tags: + - system + summary: Health check endpoint + description: Detailed health check for the system + operationId: getHealth + responses: + '200': + description: System is healthy + content: + application/json: + schema: + type: object + properties: + status: + type: string + example: 'OK' + version: + type: string + timestamp: + type: string + format: date-time + dependencies: + type: object + properties: + agents: + type: string + example: 'healthy' + '503': + description: System is unhealthy + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /api/logs: + get: + tags: + - logs + summary: Get system logs + description: Retrieve system logs with optional filtering + operationId: getLogs + parameters: + - name: since + in: query + schema: + type: integer + description: Timestamp (ms) to get logs from + - name: level + in: query + schema: + type: string + enum: [all, trace, debug, info, warn, error, fatal] + default: info + - name: agentName + in: query + schema: + type: string + - name: agentId + in: query + schema: + type: string + format: uuid + - name: limit + in: query + schema: + type: integer + default: 100 + maximum: 1000 + responses: + '200': + description: System logs + content: + application/json: + schema: + type: object + properties: + logs: + type: array + items: + $ref: '#/components/schemas/LogEntry' + count: + type: integer + total: + type: integer + level: + type: string + levels: + type: array + items: + type: string + '500': + description: Error retrieving logs + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + post: + tags: + - logs + summary: Get system logs (POST) + description: Retrieve system logs with optional filtering using POST method + operationId: postLogs + requestBody: + content: + application/json: + schema: + type: object + properties: + since: + type: integer + description: Timestamp (ms) to get logs from + level: + type: string + enum: [all, trace, debug, info, warn, error, fatal] + default: info + agentName: + type: string + agentId: + type: string + format: uuid + limit: + type: integer + default: 100 + maximum: 1000 + responses: + '200': + description: System logs + content: + application/json: + schema: + type: object + properties: + logs: + type: array + items: + $ref: '#/components/schemas/LogEntry' + count: + type: integer + total: + type: integer + level: + type: string + levels: + type: array + items: + type: string + '500': + description: Error retrieving logs + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /api/stop: + get: + tags: + - system + summary: Stop the server + description: Initiates server shutdown + operationId: stopServer + responses: + '200': + description: Server is shutting down + content: + application/json: + schema: + type: object + properties: + message: + type: string + example: 'Server stopping...' + /api/agents: + get: + tags: + - agents + summary: List all agents + description: Returns a list of all available agents + operationId: listAgents + responses: + '200': + description: List of agents + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + example: true + data: + type: object + properties: + agents: + type: array + items: + $ref: '#/components/schemas/AgentInfo' + '500': + description: Error retrieving agents + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + post: + tags: + - agents + summary: Create a new agent + description: Creates a new agent from character configuration + operationId: createAgent + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + characterPath: + type: string + description: Path to a character file + characterJson: + type: object + description: Character configuration in JSON format + responses: + '201': + description: Agent created successfully + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + example: true + data: + type: object + properties: + character: + $ref: '#/components/schemas/Character' + '400': + description: Error creating agent + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /api/agents/{agentId}: + get: + tags: + - agents + summary: Get agent details + description: Returns detailed information about a specific agent + operationId: getAgent + parameters: + - name: agentId + in: path + required: true + schema: + type: string + format: uuid + description: ID of the agent to retrieve + responses: + '200': + description: Agent details + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + example: true + data: + $ref: '#/components/schemas/AgentInfo' + '400': + description: Invalid agent ID + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '404': + description: Agent not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '500': + description: Server error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + post: + tags: + - agents + summary: Start an agent + description: Starts an existing agent + operationId: startAgent + parameters: + - name: agentId + in: path + required: true + schema: + type: string + format: uuid + description: ID of the agent to start + responses: + '200': + description: Agent started successfully + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + example: true + data: + type: object + properties: + id: + type: string + format: uuid + name: + type: string + status: + type: string + enum: [active] + '400': + description: Invalid agent ID + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '404': + description: Agent not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '500': + description: Error starting agent + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + patch: + tags: + - agents + summary: Update agent + description: Update an existing agent + operationId: updateAgent + parameters: + - name: agentId + in: path + required: true + schema: + type: string + format: uuid + description: ID of the agent to update + requestBody: + required: true + content: + application/json: + schema: + type: object + description: Agent updates + responses: + '200': + description: Agent updated successfully + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + example: true + data: + $ref: '#/components/schemas/AgentInfo' + '400': + description: Invalid agent ID + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '404': + description: Agent not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '500': + description: Error updating agent + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + put: + tags: + - agents + summary: Stop an agent + description: Stops a running agent + operationId: stopAgent + parameters: + - name: agentId + in: path + required: true + schema: + type: string + format: uuid + description: ID of the agent to stop + responses: + '200': + description: Agent stopped successfully + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + example: true + data: + type: object + properties: + message: + type: string + example: 'Agent stopped' + '400': + description: Invalid agent ID + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '404': + description: Agent not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + delete: + tags: + - agents + summary: Delete an agent + description: Deletes an agent from the system + operationId: deleteAgent + parameters: + - name: agentId + in: path + required: true + schema: + type: string + format: uuid + description: ID of the agent to delete + responses: + '204': + description: Agent deleted successfully + '400': + description: Invalid agent ID + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '500': + description: Error deleting agent + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /api/agents/{agentId}/logs: + get: + tags: + - logs + - agents + summary: Get agent logs + description: Retrieves logs for a specific agent + operationId: getAgentLogs + parameters: + - name: agentId + in: path + required: true + schema: + type: string + format: uuid + description: ID of the agent + - name: roomId + in: query + schema: + type: string + format: uuid + description: Filter logs by room ID + - name: type + in: query + schema: + type: string + description: Filter logs by type + - name: count + in: query + schema: + type: integer + description: Maximum number of logs to return + - name: offset + in: query + schema: + type: integer + description: Log offset for pagination + responses: + '200': + description: Agent logs + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + example: true + data: + type: array + items: + $ref: '#/components/schemas/LogEntry' + '400': + description: Invalid agent ID + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '404': + description: Agent not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /api/agents/{agentId}/logs/{logId}: + delete: + tags: + - logs + - agents + summary: Delete an agent log + description: Deletes a specific log entry for an agent + operationId: deleteAgentLog + parameters: + - name: agentId + in: path + required: true + schema: + type: string + format: uuid + description: ID of the agent + - name: logId + in: path + required: true + schema: + type: string + format: uuid + description: ID of the log to delete + responses: + '204': + description: Log deleted successfully + '400': + description: Invalid agent ID or log ID + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '404': + description: Agent or log not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /api/agents/{agentId}/memories: + get: + tags: + - memories + - agents + summary: Get agent memories + description: Retrieves all memories for a specific agent + operationId: getAgentMemories + parameters: + - name: agentId + in: path + required: true + schema: + type: string + format: uuid + description: ID of the agent + responses: + '200': + description: Agent memories + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + example: true + data: + type: array + items: + $ref: '#/components/schemas/Memory' + '400': + description: Invalid agent ID + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '404': + description: Agent not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /api/agents/{agentId}/memories/{memoryId}: + patch: + tags: + - memories + - agents + summary: Update a memory + description: Updates a specific memory for an agent + operationId: updateMemory + parameters: + - name: agentId + in: path + required: true + schema: + type: string + format: uuid + description: ID of the agent + - name: memoryId + in: path + required: true + schema: + type: string + format: uuid + description: ID of the memory to update + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Memory' + responses: + '200': + description: Memory updated successfully + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + example: true + data: + type: object + properties: + id: + type: string + format: uuid + message: + type: string + example: 'Memory updated successfully' + '400': + description: Invalid agent ID or memory ID + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '404': + description: Agent or memory not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '500': + description: Error updating memory + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + delete: + tags: + - memories + - agents + summary: Delete a memory + description: Deletes a specific memory for an agent + operationId: deleteMemory + parameters: + - name: agentId + in: path + required: true + schema: + type: string + format: uuid + description: ID of the agent + - name: memoryId + in: path + required: true + schema: + type: string + format: uuid + description: ID of the memory to delete + responses: + '204': + description: Memory deleted successfully + '400': + description: Invalid agent ID or memory ID + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '404': + description: Agent or memory not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /api/agents/{agentId}/rooms: + get: + tags: + - rooms + - agents + summary: Get agent rooms + description: Retrieves all rooms for a specific agent + operationId: getAgentRooms + parameters: + - name: agentId + in: path + required: true + schema: + type: string + format: uuid + description: ID of the agent + - name: worldId + in: query + schema: + type: string + format: uuid + description: Filter rooms by world ID + responses: + '200': + description: Agent rooms + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + example: true + data: + type: array + items: + $ref: '#/components/schemas/Room' + '400': + description: Invalid agent ID + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '404': + description: Agent not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '500': + description: Error retrieving rooms + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + post: + tags: + - rooms + - agents + summary: Create a room + description: Creates a new room for an agent + operationId: createRoom + parameters: + - name: agentId + in: path + required: true + schema: + type: string + format: uuid + description: ID of the agent + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + name: + type: string + description: Name of the room + worldId: + type: string + format: uuid + description: ID of the world + roomId: + type: string + format: uuid + description: Optional custom room ID + entityId: + type: string + format: uuid + description: Entity ID to add to the room + responses: + '201': + description: Room created successfully + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + example: true + data: + $ref: '#/components/schemas/Room' + '400': + description: Invalid agent ID + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '404': + description: Agent not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '500': + description: Error creating room + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /api/agents/{agentId}/rooms/{roomId}: + get: + tags: + - rooms + - agents + summary: Get room details + description: Retrieves details about a specific room + operationId: getRoom + parameters: + - name: agentId + in: path + required: true + schema: + type: string + format: uuid + description: ID of the agent + - name: roomId + in: path + required: true + schema: + type: string + format: uuid + description: ID of the room + responses: + '200': + description: Room details + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + example: true + data: + $ref: '#/components/schemas/Room' + '400': + description: Invalid agent ID or room ID + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '404': + description: Agent or room not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '500': + description: Error retrieving room + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + patch: + tags: + - rooms + - agents + summary: Update a room + description: Updates a specific room + operationId: updateRoom + parameters: + - name: agentId + in: path + required: true + schema: + type: string + format: uuid + description: ID of the agent + - name: roomId + in: path + required: true + schema: + type: string + format: uuid + description: ID of the room to update + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + name: + type: string + description: New name for the room + responses: + '200': + description: Room updated successfully + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + example: true + data: + $ref: '#/components/schemas/Room' + '400': + description: Invalid agent ID or room ID + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '404': + description: Agent or room not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '500': + description: Error updating room + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + delete: + tags: + - rooms + - agents + summary: Delete a room + description: Deletes a specific room + operationId: deleteRoom + parameters: + - name: agentId + in: path + required: true + schema: + type: string + format: uuid + description: ID of the agent + - name: roomId + in: path + required: true + schema: + type: string + format: uuid + description: ID of the room to delete + responses: + '204': + description: Room deleted successfully + '400': + description: Invalid agent ID or room ID + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '404': + description: Agent or room not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '500': + description: Error deleting room + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /api/agents/{agentId}/rooms/{roomId}/memories: + get: + tags: + - memories + - rooms + - agents + summary: Get room memories + description: Retrieves memories for a specific room + operationId: getRoomMemories + parameters: + - name: agentId + in: path + required: true + schema: + type: string + format: uuid + description: ID of the agent + - name: roomId + in: path + required: true + schema: + type: string + format: uuid + description: ID of the room + - name: limit + in: query + schema: + type: integer + default: 20 + description: Maximum number of memories to return + - name: before + in: query + schema: + type: integer + description: Return memories created before this timestamp + - name: worldId + in: query + schema: + type: string + format: uuid + description: Filter memories by world ID + responses: + '200': + description: Room memories + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + example: true + data: + type: object + properties: + memories: + type: array + items: + $ref: '#/components/schemas/Memory' + '400': + description: Invalid agent ID or room ID + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '404': + description: Agent or room not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '500': + description: Error retrieving memories + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /api/agents/{agentId}/message: + post: + tags: + - messages + - agents + summary: Send a message to an agent + description: Sends a message to an agent and receives a response + operationId: sendMessage + parameters: + - name: agentId + in: path + required: true + schema: + type: string + format: uuid + description: ID of the agent + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + senderId: + type: string + description: ID of the sender + roomId: + type: string + description: ID of the room + text: + type: string + description: Message text + source: + type: string + description: Source of the message + responses: + '201': + description: Message sent and processed successfully + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + example: true + data: + type: object + properties: + message: + $ref: '#/components/schemas/Content' + messageId: + type: string + format: uuid + name: + type: string + roomId: + type: string + source: + type: string + '400': + description: Invalid agent ID or request body + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '404': + description: Agent not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '500': + description: Error processing message + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /api/agents/{agentId}/audio-messages: + post: + tags: + - speech + - agents + summary: Send an audio message + description: Sends an audio message to an agent for processing + operationId: sendAudioMessage + parameters: + - name: agentId + in: path + required: true + schema: + type: string + format: uuid + description: ID of the agent + requestBody: + required: true + content: + multipart/form-data: + schema: + type: object + properties: + file: + type: string + format: binary + description: Audio file + responses: + '201': + description: Audio message processed successfully + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + example: true + data: + type: object + properties: + message: + $ref: '#/components/schemas/Content' + '400': + description: Invalid agent ID or missing audio file + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '404': + description: Agent not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '500': + description: Error processing audio + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /api/agents/{agentId}/audio-messages/synthesize: + post: + tags: + - speech + - agents + summary: Convert text to speech + description: Converts text to speech using the agent's voice + operationId: synthesizeSpeech + parameters: + - name: agentId + in: path + required: true + schema: + type: string + format: uuid + description: ID of the agent + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + text: + type: string + description: Text to convert to speech + responses: + '200': + description: Audio stream with synthesized speech + content: + audio/mpeg: + schema: + type: string + format: binary + '400': + description: Invalid agent ID or missing text + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '404': + description: Agent not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '500': + description: Error generating speech + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /api/agents/{agentId}/speech/generate: + post: + tags: + - speech + - agents + summary: Generate speech from text + description: Generates speech from text using the agent's voice + operationId: generateSpeech + parameters: + - name: agentId + in: path + required: true + schema: + type: string + format: uuid + description: ID of the agent + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + text: + type: string + description: Text to convert to speech + responses: + '200': + description: Audio stream with generated speech + content: + audio/mpeg: + schema: + type: string + format: binary + '400': + description: Invalid agent ID or missing text + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '404': + description: Agent not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '500': + description: Error generating speech + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /api/agents/{agentId}/speech/conversation: + post: + tags: + - speech + - agents + summary: Process conversation and return speech + description: Processes a conversational message and returns synthesized speech + operationId: conversationToSpeech + parameters: + - name: agentId + in: path + required: true + schema: + type: string + format: uuid + description: ID of the agent + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + text: + type: string + description: Text message + roomId: + type: string + description: Room ID + entityId: + type: string + description: Entity ID + userName: + type: string + description: User name + name: + type: string + description: Entity name + responses: + '200': + description: Audio stream with synthesized speech + content: + audio/mpeg: + schema: + type: string + format: binary + '400': + description: Invalid agent ID or missing text + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '404': + description: Agent not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '500': + description: Error processing conversation + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /api/agents/{agentId}/transcriptions: + post: + tags: + - speech + - agents + summary: Transcribe audio to text + description: Transcribes an audio file to text + operationId: transcribeAudio + parameters: + - name: agentId + in: path + required: true + schema: + type: string + format: uuid + description: ID of the agent + requestBody: + required: true + content: + multipart/form-data: + schema: + type: object + properties: + file: + type: string + format: binary + description: Audio file to transcribe + responses: + '200': + description: Transcription result + content: + application/json: + schema: + type: object + properties: + success: + type: boolean + example: true + data: + type: object + properties: + text: + type: string + description: Transcribed text + '400': + description: Invalid agent ID or missing audio file + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '404': + description: Agent not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '500': + description: Error transcribing audio + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /api/tee/agents: + get: + tags: + - tee + summary: List TEE agents + description: Lists all agents with TEE (Trusted Execution Environment) support + operationId: listTeeAgents + responses: + '200': + description: TEE agent list with attestation + content: + application/json: + schema: + type: object + properties: + agents: + type: array + items: + $ref: '#/components/schemas/TeeAgent' + attestation: + type: string + description: TEE attestation + '500': + description: Error retrieving TEE agents + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /api/tee/agents/{agentId}: + get: + tags: + - tee + summary: Get TEE agent details + description: Gets details about a specific TEE agent with attestation + operationId: getTeeAgent + parameters: + - name: agentId + in: path + required: true + schema: + type: string + format: uuid + description: ID of the TEE agent + responses: + '200': + description: TEE agent details with attestation + content: + application/json: + schema: + type: object + properties: + agent: + $ref: '#/components/schemas/TeeAgent' + attestation: + type: string + description: TEE attestation + '404': + description: Agent not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + '500': + description: Error retrieving TEE agent + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + /api/tee/logs: + post: + tags: + - tee + - logs + summary: Query TEE logs + description: Queries logs from the Trusted Execution Environment + operationId: queryTeeLogs + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + query: + type: object + properties: + agentId: + type: string + format: uuid + roomId: + type: string + format: uuid + entityId: + type: string + format: uuid + type: + type: string + containsContent: + type: string + startTimestamp: + type: integer + format: int64 + endTimestamp: + type: integer + format: int64 + page: + type: integer + default: 1 + pageSize: + type: integer + default: 10 + responses: + '200': + description: TEE logs with attestation + content: + application/json: + schema: + type: object + properties: + logs: + type: object + description: Log query results + attestation: + type: string + description: TEE attestation + '500': + description: Error retrieving TEE logs + content: + application/json: + schema: + $ref: '#/components/schemas/Error' +components: + schemas: + Error: + type: object + properties: + success: + type: boolean + example: false + error: + type: object + properties: + code: + type: string + description: Error code + message: + type: string + description: Error message + details: + type: string + description: Detailed error information + AgentInfo: + type: object + properties: + id: + type: string + format: uuid + description: Unique identifier for the agent + name: + type: string + description: Name of the agent + status: + type: string + enum: [active, inactive] + description: Current status of the agent + Character: + type: object + required: + - name + properties: + id: + type: string + format: uuid + description: Unique identifier for the character + name: + type: string + description: Name of the character + bio: + type: string + description: Short biography of the character + settings: + type: object + description: Character-specific settings + system: + type: string + description: System prompt for the character + style: + type: object + description: Character's communication style + lore: + type: array + items: + type: string + description: Extended lore and background information + messageExamples: + type: array + items: + type: string + description: Example messages for character training + topics: + type: array + items: + type: string + description: Topics the character is knowledgeable about + plugins: + type: array + items: + type: string + description: Plugins used by the character + Content: + type: object + properties: + text: + type: string + description: Text content of the message + thought: + type: string + description: Agent's internal thought process + plan: + type: string + description: Agent's plan or reasoning + actions: + type: array + items: + type: string + description: Actions the agent wants to take + source: + type: string + description: Source of the message + inReplyTo: + type: string + format: uuid + description: ID of the message this is in reply to + Memory: + type: object + properties: + id: + type: string + format: uuid + description: Unique identifier for the memory + entityId: + type: string + format: uuid + description: ID of the entity associated with this memory + agentId: + type: string + format: uuid + description: ID of the agent associated with this memory + roomId: + type: string + format: uuid + description: ID of the room this memory belongs to + createdAt: + type: integer + format: int64 + description: Unix timestamp when the memory was created + content: + $ref: '#/components/schemas/Content' + Room: + type: object + properties: + id: + type: string + format: uuid + description: Unique identifier for the room + name: + type: string + description: Name of the room + source: + type: string + description: Source of the room + worldId: + type: string + format: uuid + description: ID of the world this room belongs to + entities: + type: array + items: + type: object + properties: + id: + type: string + format: uuid + name: + type: string + description: Entities in this room + LogEntry: + type: object + properties: + level: + type: number + description: Log level + time: + type: number + format: int64 + description: Timestamp of the log entry + msg: + type: string + description: Log message + agentId: + type: string + format: uuid + description: ID of the related agent (if applicable) + agentName: + type: string + description: Name of the related agent (if applicable) + TeeAgent: + type: object + properties: + id: + type: string + format: uuid + description: Unique identifier for the TEE agent + name: + type: string + description: Name of the TEE agent + attestation: + type: object + description: TEE attestation data +```` + ## File: .env.example ```` +# Logging Configuration (supported: fatal, error, warn, info, debug, trace | default: info) +LOG_LEVEL= + # OpenAI Configuration OPENAI_API_KEY= @@ -4577,16 +10273,17 @@ COINGECKO_API_KEY= "scripts": { "preinstall": "only-allow bun", "start": "cd ./packages/the-org && bun run start", - "start:debug": "LOG_LEVEL=debug elizaos start", + "start:debug": "cross-env NODE_NO_WARNINGS=1 LOG_LEVEL=debug elizaos start", "start:app": "turbo run start --filter=./packages/app", "dev": "turbo run dev --filter=./packages/the-org", "build:docs": "turbo run build --filter=@elizaos/docs", "build": "turbo run build --filter=@elizaos/client && turbo run build --filter=!@elizaos/docs", - "clean": "rm -rf dist .turbo node_modules .turbo-tsconfig.json tsconfig.tsbuildinfo bun.lock* && turbo run clean --filter=./packages/*", + "clean": "turbo run clean --filter=./packages/* && rm -rf dist .turbo node_modules .turbo-tsconfig.json tsconfig.tsbuildinfo bun.lock*", "lint": "turbo run lint --filter=./packages/* && prettier --write . && prettier --check .", - "pre-commit": "bun run scripts/pre-commit-lint", + "pre-commit": "bun run scripts/pre-commit-lint.js", "release": "bun run build && bun lint && lerna publish --no-private --force-publish && bun lint", "release:alpha": "lerna publish prerelease --preid alpha --dist-tag alpha --no-private --force-publish --loglevel verbose", + "release:beta": "lerna publish prerelease --preid beta --dist-tag beta --no-private --force-publish --loglevel verbose", "migrate": "turbo run migrate --filter=./packages/plugin-sql --force", "migrate:generate": "turbo run migrate:generate --filter=./packages/plugin-sql", "docker:build": "bash ./scripts/docker.sh build", @@ -4729,8 +10426,8 @@ COINGECKO_API_KEY= ### Prerequisites - [Python 2.7+](https://www.python.org/downloads/) -- [Node 23+](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) -- [bun](https://bun.io/installation) +- [Node.js 23+](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) +- [bun](https://bun.sh/docs/installation) > **Note for Windows Users:** [WSL 2](https://learn.microsoft.com/en-us/windows/wsl/install-manual) is required. diff --git a/packages/docs/static/llms.txt b/packages/docs/static/llms.txt index a78f588d092..9608a620d5c 100644 --- a/packages/docs/static/llms.txt +++ b/packages/docs/static/llms.txt @@ -1,20 +1,324 @@ +This file is a merged representation of a subset of the codebase, containing specifically included files and files not matching ignore patterns, combined into a single document by Repomix. +The content has been processed where comments have been removed, empty lines have been removed, content has been compressed (code blocks are separated by ⋮---- delimiter). + +# File Summary + +## Purpose +This file contains a packed representation of the entire repository's contents. +It is designed to be easily consumable by AI systems for analysis, code review, +or other automated processes. + +## File Format +The content is organized as follows: +1. This summary section +2. Repository information +3. Directory structure +4. Multiple file entries, each consisting of: + a. A header with the file path (## File: path/to/file) + b. The full contents of the file in a code block + +## Usage Guidelines +- This file should be treated as read-only. Any changes should be made to the + original repository files, not this packed version. +- When processing this file, use the file path to distinguish + between different files in the repository. +- Be aware that this file may contain sensitive information. Handle it with + the same level of security as you would the original repository. +- Pay special attention to the Repository Description. These contain important context and guidelines specific to this project. +- Pay special attention to the Repository Instruction. These contain important context and guidelines specific to this project. + +## Notes +- Some files may have been excluded based on .gitignore rules and Repomix's configuration +- Binary files are not included in this packed representation. Please refer to the Repository Structure section for a complete list of file paths, including binary files +- Only files matching these patterns are included: packages/docs/docs/intro.md, packages/docs/docs/quickstart.md, packages/docs/docs/core/overview.md, packages/docs/docs/core/actions.md, packages/docs/docs/core/agents.md, packages/docs/docs/core/database.md, packages/docs/docs/core/entities.md, packages/docs/docs/core/evaluators.md, packages/docs/docs/core/knowledge.md, packages/docs/docs/core/plugins.md, packages/docs/docs/core/project.md, packages/docs/docs/core/providers.md, packages/docs/docs/core/rooms.md, packages/docs/docs/core/services.md, packages/docs/docs/core/tasks.md, packages/docs/docs/core/worlds.md, packages/core/src/types.ts, packages/core/src/index.ts, packages/cli/src/index.ts, packages/cli/README.md, README.md, package.json, .env.example +- Files matching these patterns are excluded: **/*.test.ts, **/__tests__/**, **/node_modules/**, packages/docs/community/**, packages/docs/news/**, packages/plugin-*/**, **/*.ico, **/*.png, **/*.jpg, **/*.svg +- Files matching patterns in .gitignore are excluded +- Files matching default ignore patterns are excluded +- Code comments have been removed from supported file types +- Empty lines have been removed from all files +- Content has been compressed - code blocks are separated by ⋮---- delimiter + +## Additional Info +### User Provided Header +ElizaOS Developer Context - Documentation and essential code + +# Directory Structure +``` +packages/ + cli/ + src/ + index.ts + README.md + core/ + src/ + index.ts + types.ts + docs/ + docs/ + core/ + actions.md + agents.md + database.md + entities.md + evaluators.md + knowledge.md + overview.md + plugins.md + project.md + providers.md + rooms.md + services.md + tasks.md + worlds.md + intro.md + quickstart.md +.env.example +package.json +README.md +``` + +# Files + +## File: packages/cli/src/index.ts +````typescript +import fs from 'node:fs'; +import path from 'node:path'; +import { dirname } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { logger } from '@elizaos/core'; +import { Command } from 'commander'; +import { agent } from './commands/agent'; +import { create } from './commands/create'; +import { dev } from './commands/dev'; +import { env } from './commands/env'; +import { plugin } from './commands/plugin'; +import { project } from './commands/project'; +import { publish } from './commands/publish'; +import { start } from './commands/start'; +import { teeCommand as tee } from './commands/tee'; +import { test } from './commands/test'; +import { update } from './commands/update'; +import { loadEnvironment } from './utils/get-config'; +import { displayBanner } from './displayBanner'; +⋮---- +async function main() +```` + +## File: packages/cli/README.md +````markdown +# CLI + +The CLI provides a set of commands to manage your ElizaOS projects and plugins, from local development to cloud deployment. + +# TODO: CLI Documentation goes here + +## Environment Variables + +Create a .env file with your required variables: + +```env +ANTHROPIC_API_KEY=your_key +TELEGRAM_BOT_TOKEN=your_token +# Add other required variables +``` + +# TEE Deployment Docs + +## Getting Started + +### Prerequisites + +- Docker installed and running +- Node.js and npm/bun installed +- A Docker Hub account for publishing images +- A Phala Cloud (https://cloud.phala.network/login) API key for cloud deployments + +## Commands + +### Building Your Image + +Build your Docker image locally: + ```bash -bun install -bun run build # npm will work too -bun start # npm will work too +elizaos tee phala build \ + -i your-image-name \ + -u your-dockerhub-username \ + -f path/to/Dockerfile \ + -t tag-name ``` -### Interact via Browser +### Running the TEE Simulator + +Start the local TEE simulator for testing: + +```bash +elizaos tee phala simulator +``` + +This will start the simulator on http://localhost:8090. + +### Local Development + +You can develop your agent locally in two ways: + +1. Build the docker-compose file separately: + +```bash +elizaos tee phala build-compose \ + -i your-image-name \ + -u your-dockerhub-username \ + -t tag-name \ + -c path/to/character.json \ + -e path/to/.env \ + -v v2 # or v1 for legacy mode +``` + +2. Run an existing compose file: + +```bash +elizaos tee phala run-local \ + -c path/to/docker-compose.yml \ + -e path/to/.env +``` + +This separation allows you to: + +- Build compose files without running them immediately +- Version control your compose files +- Share compose files with team members +- Run the same compose file multiple times + +The CLI will store generated compose files in: + +``` +.tee-cloud/ + └── compose-files/ # Generated docker-compose files + └── your-character-tee-compose.yaml +``` + +### Publishing Your Image + +Push your built image to Docker Hub: + +```bash +elizaos tee phala publish \ + -i your-image-name \ + -u your-dockerhub-username \ + -t tag-name +``` + +### List Available Tags + +View all tags for your image on Docker Hub: + +```bash +elizaos tee phala list-tags \ + -i your-image-name \ + -u your-dockerhub-username +``` + +### Cloud Deployment + +First, set your Phala Cloud API key: + +```bash +elizaos tee phala set-apikey your-api-key +``` -Once the agent is running, visit https://localhost:3000 to interact with your agent through a web interface. +Deploy to Phala Cloud: -No separate client startup is needed for basic interaction in the newer versions. +```bash +elizaos tee phala deploy \ + -t phala \ + -m docker-compose \ + -n your-deployment-name \ + -c path/to/docker-compose.yml \ + --env-file path/to/.env +``` + +### Managing Cloud Deployments + +List your active agents (CVMs): + +```bash +elizaos tee phala list-cvms +``` + +List your TEE pods: + +```bash +elizaos tee phala teepods +``` + +List images in a specific TEE pod: + +```bash +elizaos tee phala images --teepod-id your-teepod-id +``` + +Upgrade an existing deployment: + +```bash +elizaos tee phala upgrade \ + -t phala \ + -m docker-compose \ + --app-id your-app-id \ + -c path/to/docker-compose.yml \ + --env-file path/to/.env +``` + +## Directory Structure + +The CLI will create the following directory structure: + +``` +.tee-cloud/ + └── compose-files/ # Generated docker-compose files +``` + +## Tips + +- Use the simulator for local testing before cloud deployment +- Always test your image locally with `run-local` before publishing +- Keep your API keys secure and never commit them to version control +- Use the `--help` flag with any command for detailed usage information + +## Troubleshooting + +Common issues and solutions: + +1. **Docker Build Fails** + + - Ensure Docker daemon is running + - Check Dockerfile path is correct + - Verify you have necessary permissions + +2. **Simulator Connection Issues** + + - Check if port 8090 is available + - Ensure Docker has necessary permissions + +3. **Cloud Deployment Fails** + - Verify API key is set correctly + - Check if image exists on Docker Hub + - Ensure environment variables are properly set + +For more help, use the `--help` flag with any command: + +```bash +elizaos tee phala --help +elizaos tee phala --help +``` +```` + +## File: packages/core/src/index.ts +````typescript ```` ## File: packages/core/src/types.ts ````typescript -import type { Readable } from "node:stream"; +import type { Readable } from 'node:stream'; export type UUID = `${string}-${string}-${string}-${string}-${string}`; export function asUUID(id: string): UUID export interface Content { @@ -32,9 +336,9 @@ export interface ActionExample { name: string; content: Content; } -export type ModelType = (typeof ModelTypes)[keyof typeof ModelTypes] | string; +export type ModelTypeName = (typeof ModelType)[keyof typeof ModelType] | string; ⋮---- -export type ServiceType = (typeof ServiceTypes)[keyof typeof ServiceTypes]; +export type ServiceTypeName = (typeof ServiceType)[keyof typeof ServiceType]; ⋮---- export interface State { [key: string]: any; @@ -48,13 +352,13 @@ export interface State { } export type MemoryTypeAlias = string; export enum MemoryType { - DOCUMENT = "document", - FRAGMENT = "fragment", - MESSAGE = "message", - DESCRIPTION = "description", - CUSTOM = "custom", + DOCUMENT = 'document', + FRAGMENT = 'fragment', + MESSAGE = 'message', + DESCRIPTION = 'description', + CUSTOM = 'custom', } -export type MemoryScope = "shared" | "private" | "room"; +export type MemoryScope = 'shared' | 'private' | 'room'; export interface BaseMetadata { type: MemoryTypeAlias; source?: string; @@ -78,7 +382,6 @@ export interface DescriptionMetadata extends BaseMetadata { type: MemoryType.DESCRIPTION; } export interface CustomMetadata extends BaseMetadata { - type: MemoryTypeAlias; [key: string]: unknown; } export type MemoryMetadata = @@ -119,10 +422,7 @@ export type Handler = ( callback?: HandlerCallback, responses?: Memory[] ) => Promise; -export type HandlerCallback = ( - response: Content, - files?: any -) => Promise; +export type HandlerCallback = (response: Content, files?: any) => Promise; export type Validator = ( runtime: IAgentRuntime, message: Memory, @@ -165,11 +465,7 @@ export interface Provider { dynamic?: boolean; position?: number; private?: boolean; - get: ( - runtime: IAgentRuntime, - message: Memory, - state: State - ) => Promise; + get: (runtime: IAgentRuntime, message: Memory, state: State) => Promise; } export interface Relationship { id: UUID; @@ -241,16 +537,16 @@ export type Media = { contentType?: string; }; export enum ChannelType { - SELF = "SELF", - DM = "DM", - GROUP = "GROUP", - VOICE_DM = "VOICE_DM", - VOICE_GROUP = "VOICE_GROUP", - FEED = "FEED", - THREAD = "THREAD", - WORLD = "WORLD", - API = "API", - FORUM = "FORUM", + SELF = 'SELF', + DM = 'dm', + GROUP = 'group', + VOICE_DM = 'VOICE_DM', + VOICE_GROUP = 'VOICE_GROUP', + FEED = 'FEED', + THREAD = 'THREAD', + WORLD = 'WORLD', + FORUM = 'FORUM', + API = 'API', } export abstract class Service ⋮---- @@ -261,7 +557,7 @@ static async start(_runtime: IAgentRuntime): Promise static async stop(_runtime: IAgentRuntime): Promise ⋮---- export type Route = { - type: "GET" | "POST" | "PUT" | "DELETE" | "STATIC"; + type: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'STATIC'; path: string; filePath?: string; handler?: (req: any, res: any, runtime: IAgentRuntime) => Promise; @@ -269,12 +565,8 @@ export type Route = { export interface Plugin { name: string; description: string; - init?: ( - config: Record, - runtime: IAgentRuntime - ) => Promise; + init?: (config: Record, runtime: IAgentRuntime) => Promise; config?: { [key: string]: any }; - memoryManagers?: IMemoryManager[]; services?: (typeof Service)[]; componentTypes?: { name: string; @@ -335,7 +627,13 @@ export interface Character { post?: string[]; }; } +export enum AgentStatus { + ACTIVE = 'active', + INACTIVE = 'inactive', +} export interface Agent extends Character { + enabled?: boolean; + status?: AgentStatus; createdAt: number; updatedAt: number; } @@ -351,10 +649,7 @@ export interface IDatabaseAdapter { ensureAgentExists(agent: Partial): Promise; ensureEmbeddingDimension(dimension: number): Promise; getEntityById(entityId: UUID): Promise; - getEntitiesForRoom( - roomId: UUID, - includeComponents?: boolean - ): Promise; + getEntitiesForRoom(roomId: UUID, includeComponents?: boolean): Promise; createEntity(entity: Entity): Promise; updateEntity(entity: Entity): Promise; getComponent( @@ -363,16 +658,14 @@ export interface IDatabaseAdapter { worldId?: UUID, sourceEntityId?: UUID ): Promise; - getComponents( - entityId: UUID, - worldId?: UUID, - sourceEntityId?: UUID - ): Promise; + getComponents(entityId: UUID, worldId?: UUID, sourceEntityId?: UUID): Promise; createComponent(component: Component): Promise; updateComponent(component: Component): Promise; deleteComponent(componentId: UUID): Promise; getMemories(params: { - roomId: UUID; + entityId?: UUID; + agentId?: UUID; + roomId?: UUID; count?: number; unique?: boolean; tableName: string; @@ -416,32 +709,17 @@ export interface IDatabaseAdapter { unique?: boolean; tableName: string; }): Promise; - createMemory( - memory: Memory, - tableName: string, - unique?: boolean - ): Promise; - removeMemory(memoryId: UUID, tableName: string): Promise; - removeAllMemories(roomId: UUID, tableName: string): Promise; - countMemories( - roomId: UUID, - unique?: boolean, - tableName?: string - ): Promise; + createMemory(memory: Memory, tableName: string, unique?: boolean): Promise; + updateMemory(memory: Partial & { id: UUID; metadata?: MemoryMetadata }): Promise; + deleteMemory(memoryId: UUID): Promise; + deleteAllMemories(roomId: UUID, tableName: string): Promise; + countMemories(roomId: UUID, unique?: boolean, tableName?: string): Promise; createWorld(world: World): Promise; getWorld(id: UUID): Promise; getAllWorlds(): Promise; updateWorld(world: World): Promise; getRoom(roomId: UUID): Promise; - createRoom({ - id, - name, - source, - type, - channelId, - serverId, - worldId, - }: Room): Promise; + createRoom({ id, name, source, type, channelId, serverId, worldId }: Room): Promise; deleteRoom(roomId: UUID): Promise; updateRoom(room: Room): Promise; getRoomsForParticipant(entityId: UUID): Promise; @@ -451,14 +729,11 @@ export interface IDatabaseAdapter { removeParticipant(entityId: UUID, roomId: UUID): Promise; getParticipantsForEntity(entityId: UUID): Promise; getParticipantsForRoom(roomId: UUID): Promise; - getParticipantUserState( - roomId: UUID, - entityId: UUID - ): Promise<"FOLLOWED" | "MUTED" | null>; + getParticipantUserState(roomId: UUID, entityId: UUID): Promise<'FOLLOWED' | 'MUTED' | null>; setParticipantUserState( roomId: UUID, entityId: UUID, - state: "FOLLOWED" | "MUTED" | null + state: 'FOLLOWED' | 'MUTED' | null ): Promise; createRelationship(params: { sourceEntityId: UUID; @@ -471,10 +746,7 @@ export interface IDatabaseAdapter { sourceEntityId: UUID; targetEntityId: UUID; }): Promise; - getRelationships(params: { - entityId: UUID; - tags?: string[]; - }): Promise; + getRelationships(params: { entityId: UUID; tags?: string[] }): Promise; ensureEmbeddingDimension(dimension: number): Promise; getCache(key: string): Promise; setCache(key: string, value: T): Promise; @@ -485,9 +757,6 @@ export interface IDatabaseAdapter { getTasksByName(name: string): Promise; updateTask(id: UUID, task: Partial): Promise; deleteTask(id: UUID): Promise; - getMemoryManager( - tableName: string - ): IMemoryManager | null; } ⋮---- init(): Promise; @@ -500,10 +769,7 @@ deleteAgent(agentId: UUID): Promise; ensureAgentExists(agent: Partial): Promise; ensureEmbeddingDimension(dimension: number): Promise; getEntityById(entityId: UUID): Promise; -getEntitiesForRoom( - roomId: UUID, - includeComponents?: boolean - ): Promise; +getEntitiesForRoom(roomId: UUID, includeComponents?: boolean): Promise; createEntity(entity: Entity): Promise; updateEntity(entity: Entity): Promise; getComponent( @@ -512,16 +778,14 @@ getComponent( worldId?: UUID, sourceEntityId?: UUID ): Promise; -getComponents( - entityId: UUID, - worldId?: UUID, - sourceEntityId?: UUID - ): Promise; +getComponents(entityId: UUID, worldId?: UUID, sourceEntityId?: UUID): Promise; createComponent(component: Component): Promise; updateComponent(component: Component): Promise; deleteComponent(componentId: UUID): Promise; getMemories(params: { - roomId: UUID; + entityId?: UUID; + agentId?: UUID; + roomId?: UUID; count?: number; unique?: boolean; tableName: string; @@ -565,32 +829,17 @@ searchMemories(params: { unique?: boolean; tableName: string; }): Promise; -createMemory( - memory: Memory, - tableName: string, - unique?: boolean - ): Promise; -removeMemory(memoryId: UUID, tableName: string): Promise; -removeAllMemories(roomId: UUID, tableName: string): Promise; -countMemories( - roomId: UUID, - unique?: boolean, - tableName?: string - ): Promise; +createMemory(memory: Memory, tableName: string, unique?: boolean): Promise; +updateMemory(memory: Partial & +deleteMemory(memoryId: UUID): Promise; +deleteAllMemories(roomId: UUID, tableName: string): Promise; +countMemories(roomId: UUID, unique?: boolean, tableName?: string): Promise; createWorld(world: World): Promise; getWorld(id: UUID): Promise; getAllWorlds(): Promise; updateWorld(world: World): Promise; getRoom(roomId: UUID): Promise; -createRoom({ - id, - name, - source, - type, - channelId, - serverId, - worldId, - }: Room): Promise; +createRoom( deleteRoom(roomId: UUID): Promise; updateRoom(room: Room): Promise; getRoomsForParticipant(entityId: UUID): Promise; @@ -600,14 +849,11 @@ addParticipant(entityId: UUID, roomId: UUID): Promise; removeParticipant(entityId: UUID, roomId: UUID): Promise; getParticipantsForEntity(entityId: UUID): Promise; getParticipantsForRoom(roomId: UUID): Promise; -getParticipantUserState( - roomId: UUID, - entityId: UUID - ): Promise<"FOLLOWED" | "MUTED" | null>; +getParticipantUserState(roomId: UUID, entityId: UUID): Promise<'FOLLOWED' | 'MUTED' | null>; setParticipantUserState( roomId: UUID, entityId: UUID, - state: "FOLLOWED" | "MUTED" | null + state: 'FOLLOWED' | 'MUTED' | null ): Promise; createRelationship(params: { sourceEntityId: UUID; @@ -620,10 +866,7 @@ getRelationship(params: { sourceEntityId: UUID; targetEntityId: UUID; }): Promise; -getRelationships(params: { - entityId: UUID; - tags?: string[]; - }): Promise; +getRelationships(params: ⋮---- getCache(key: string): Promise; setCache(key: string, value: T): Promise; @@ -634,9 +877,6 @@ getTask(id: UUID): Promise; getTasksByName(name: string): Promise; updateTask(id: UUID, task: Partial): Promise; deleteTask(id: UUID): Promise; -getMemoryManager( - tableName: string - ): IMemoryManager | null; ⋮---- export interface EmbeddingSearchResult { embedding: number[]; @@ -676,40 +916,6 @@ export interface UnifiedSearchOptions extends UnifiedMemoryOptions { embedding: number[]; similarity?: number; } -export interface IMemoryManager { - readonly runtime: IAgentRuntime; - readonly tableName: string; - addEmbeddingToMemory(memory: T): Promise; - getMemories( - opts: MemoryRetrievalOptions | UnifiedMemoryOptions - ): Promise; - searchMemories( - params: MemorySearchOptions | UnifiedSearchOptions - ): Promise; - getCachedEmbeddings(content: string): Promise; - getMemoryById(id: UUID): Promise; - getMemoriesByRoomIds(params: MultiRoomMemoryOptions): Promise; - createMemory(memory: T, unique?: boolean): Promise; - removeMemory(memoryId: UUID): Promise; - removeAllMemories(roomId: UUID): Promise; - countMemories(roomId: UUID, unique?: boolean): Promise; -} -⋮---- -addEmbeddingToMemory(memory: T): Promise; -getMemories( - opts: MemoryRetrievalOptions | UnifiedMemoryOptions - ): Promise; -searchMemories( - params: MemorySearchOptions | UnifiedSearchOptions - ): Promise; -getCachedEmbeddings(content: string): Promise; -getMemoryById(id: UUID): Promise; -getMemoriesByRoomIds(params: MultiRoomMemoryOptions): Promise; -createMemory(memory: T, unique?: boolean): Promise; -removeMemory(memoryId: UUID): Promise; -removeAllMemories(roomId: UUID): Promise; -countMemories(roomId: UUID, unique?: boolean): Promise; -⋮---- export type CacheOptions = { expires?: number; }; @@ -720,7 +926,7 @@ export interface IAgentRuntime extends IDatabaseAdapter { actions: Action[]; evaluators: Evaluator[]; plugins: Plugin[]; - services: Map; + services: Map; events: Map Promise)[]>; fetch?: typeof fetch | null; routes: Route[]; @@ -735,18 +941,11 @@ export interface IAgentRuntime extends IDatabaseAdapter { modelContextSize: number; } ): Promise; - getMemoryManager( - tableName: string - ): IMemoryManager | null; - getService(service: ServiceType | string): T | null; - getAllServices(): Map; + getService(service: ServiceTypeName | string): T | null; + getAllServices(): Map; registerService(service: typeof Service): void; registerDatabaseAdapter(adapter: IDatabaseAdapter): void; - setSetting( - key: string, - value: string | boolean | null | any, - secret: boolean - ): void; + setSetting(key: string, value: string | boolean | null | any, secret: boolean): void; getSetting(key: string): string | boolean | null | any; getConversationLength(): number; processActions( @@ -789,21 +988,14 @@ export interface IAgentRuntime extends IDatabaseAdapter { ensureParticipantInRoom(entityId: UUID, roomId: UUID): Promise; ensureWorldExists(world: World): Promise; ensureRoomExists(room: Room): Promise; - composeState( - message: Memory, - filterList?: string[], - includeList?: string[] - ): Promise; - useModel( + composeState(message: Memory, filterList?: string[], includeList?: string[]): Promise; + useModel( modelType: T, - params: Omit | any + params: Omit | any ): Promise; - registerModel( - modelType: ModelType | string, - handler: (params: any) => Promise - ): void; + registerModel(modelType: ModelTypeName | string, handler: (params: any) => Promise): void; getModel( - modelType: ModelType | string + modelType: ModelTypeName | string ): ((runtime: IAgentRuntime, params: any) => Promise) | undefined; registerEvent(event: string, handler: (params: any) => Promise): void; getEvent(event: string): ((params: any) => Promise)[] | undefined; @@ -811,6 +1003,7 @@ export interface IAgentRuntime extends IDatabaseAdapter { registerTaskWorker(taskHandler: TaskWorker): void; getTaskWorker(name: string): TaskWorker | undefined; stop(): Promise; + addEmbeddingToMemory(memory: Memory): Promise; } ⋮---- registerPlugin(plugin: Plugin): Promise; @@ -824,16 +1017,11 @@ addKnowledge( modelContextSize: number; } ): Promise; -⋮---- -getService(service: ServiceType | string): T | null; -getAllServices(): Map; +getService(service: ServiceTypeName | string): T | null; +getAllServices(): Map; registerService(service: typeof Service): void; registerDatabaseAdapter(adapter: IDatabaseAdapter): void; -setSetting( - key: string, - value: string | boolean | null | any, - secret: boolean - ): void; +setSetting(key: string, value: string | boolean | null | any, secret: boolean): void; getSetting(key: string): string | boolean | null | any; getConversationLength(): number; processActions( @@ -876,21 +1064,14 @@ ensureConnection({ ensureParticipantInRoom(entityId: UUID, roomId: UUID): Promise; ensureWorldExists(world: World): Promise; ensureRoomExists(room: Room): Promise; -composeState( - message: Memory, - filterList?: string[], - includeList?: string[] - ): Promise; -useModel( +composeState(message: Memory, filterList?: string[], includeList?: string[]): Promise; +useModel( modelType: T, - params: Omit | any + params: Omit | any ): Promise; -registerModel( - modelType: ModelType | string, - handler: (params: any) => Promise - ): void; +registerModel(modelType: ModelTypeName | string, handler: (params: any) getModel( - modelType: ModelType | string + modelType: ModelTypeName | string ): ((runtime: IAgentRuntime, params: any) registerEvent(event: string, handler: (params: any) getEvent(event: string): ((params: any) @@ -898,17 +1079,19 @@ emitEvent(event: string | string[], params: any): Promise; registerTaskWorker(taskHandler: TaskWorker): void; getTaskWorker(name: string): TaskWorker | undefined; stop(): Promise; +addEmbeddingToMemory(memory: Memory): Promise; ⋮---- export type KnowledgeItem = { id: UUID; content: Content; + metadata?: MemoryMetadata; }; export enum KnowledgeScope { - SHARED = "shared", - PRIVATE = "private", + SHARED = 'shared', + PRIVATE = 'private', } export enum CacheKeyPrefix { - KNOWLEDGE = "knowledge", + KNOWLEDGE = 'knowledge', } export interface DirectoryItem { directory: string; @@ -920,7 +1103,7 @@ export interface ChunkRow { export type GenerateTextParams = { runtime: IAgentRuntime; prompt: string; - modelType: ModelType; + modelType: ModelTypeName; maxTokens?: number; temperature?: number; frequencyPenalty?: number; @@ -929,11 +1112,11 @@ export type GenerateTextParams = { }; export interface TokenizeTextParams { prompt: string; - modelType: ModelType; + modelType: ModelTypeName; } export interface DetokenizeTextParams { tokens: number[]; - modelType: ModelType; + modelType: ModelTypeName; } export interface IVideoService extends Service { isVideoUrl(url: string): boolean; @@ -987,46 +1170,6 @@ uploadFile( ): Promise< generateSignedUrl(fileName: string, expiresIn: number): Promise; ⋮---- -export interface ITeeLogService extends Service { - log( - agentId: string, - roomId: string, - entityId: string, - type: string, - content: string - ): Promise; - generateAttestation( - reportData: string, - hashAlgorithm?: T | any - ): Promise; - getAllAgents(): Promise; - getAgent(agentId: string): Promise; - getLogs( - query: TeeLogQuery, - page: number, - pageSize: number - ): Promise>; -} -⋮---- -log( - agentId: string, - roomId: string, - entityId: string, - type: string, - content: string - ): Promise; -generateAttestation( - reportData: string, - hashAlgorithm?: T | any - ): Promise; -getAllAgents(): Promise; -getAgent(agentId: string): Promise; -getLogs( - query: TeeLogQuery, - page: number, - pageSize: number - ): Promise>; -⋮---- export interface TestCase { name: string; fn: (runtime: IAgentRuntime) => Promise | void; @@ -1035,25 +1178,6 @@ export interface TestSuite { name: string; tests: TestCase[]; } -export interface TeeLog { - id: string; - agentId: string; - roomId: string; - entityId: string; - type: string; - content: string; - timestamp: number; - signature: string; -} -export interface TeeLogQuery { - agentId?: string; - roomId?: string; - entityId?: string; - type?: string; - containsContent?: string; - startTimestamp?: number; - endTimestamp?: number; -} export interface TeeAgent { id: string; agentId: string; @@ -1062,30 +1186,11 @@ export interface TeeAgent { publicKey: string; attestation: string; } -export interface TeePageQuery { - page: number; - pageSize: number; - total?: number; - data?: Result; -} -export abstract class TeeLogDAO -⋮---- -abstract initialize(): Promise; -abstract addLog(log: TeeLog): Promise; -abstract getPagedLogs( - query: TeeLogQuery, - page: number, - pageSize: number - ): Promise>; -abstract addAgent(agent: TeeAgent): Promise; -abstract getAgent(agentId: string): Promise; -abstract getAllAgents(): Promise; -⋮---- export enum TEEMode { - OFF = "OFF", - LOCAL = "LOCAL", - DOCKER = "DOCKER", - PRODUCTION = "PRODUCTION", + OFF = 'OFF', + LOCAL = 'LOCAL', + DOCKER = 'DOCKER', + PRODUCTION = 'PRODUCTION', } export interface RemoteAttestationQuote { quote: string; @@ -1105,13 +1210,8 @@ export interface RemoteAttestationMessage { content: string; }; } -export interface SgxAttestation { - quote: string; - timestamp: number; -} export enum TeeType { - SGX_GRAMINE = "sgx_gramine", - TDX_DSTACK = "tdx_dstack", + TDX_DSTACK = 'tdx_dstack', } export interface TeeVendorConfig { [key: string]: unknown; @@ -1127,11 +1227,7 @@ export interface TaskWorker { options: { [key: string]: unknown }, task: Task ) => Promise; - validate?: ( - runtime: IAgentRuntime, - message: Memory, - state: State - ) => Promise; + validate?: (runtime: IAgentRuntime, message: Memory, state: State) => Promise; } export interface Task { id?: UUID; @@ -1151,9 +1247,9 @@ export interface Task { tags: string[]; } export enum Role { - OWNER = "OWNER", - ADMIN = "ADMIN", - NONE = "NONE", + OWNER = 'OWNER', + ADMIN = 'ADMIN', + NONE = 'NONE', } export interface Setting { name: string; @@ -1173,7 +1269,7 @@ export interface WorldSettings { } export interface OnboardingConfig { settings: { - [key: string]: Omit; + [key: string]: Omit; }; } export interface BaseModelParams { @@ -1192,11 +1288,11 @@ export interface TextEmbeddingParams extends BaseModelParams { } export interface TokenizeTextParams extends BaseModelParams { prompt: string; - modelType: ModelType; + modelType: ModelTypeName; } export interface DetokenizeTextParams extends BaseModelParams { tokens: number[]; - modelType: ModelType; + modelType: ModelTypeName; } export interface ImageGenerationParams extends BaseModelParams { prompt: string; @@ -1234,76 +1330,76 @@ export type JSONSchema = { export interface ObjectGenerationParams extends BaseModelParams { prompt: string; schema?: JSONSchema; - output?: "object" | "array" | "enum"; + output?: 'object' | 'array' | 'enum'; enumValues?: string[]; - modelType?: ModelType; + modelType?: ModelTypeName; temperature?: number; stopSequences?: string[]; } export interface ModelParamsMap { - [ModelTypes.TEXT_SMALL]: TextGenerationParams; - [ModelTypes.TEXT_LARGE]: TextGenerationParams; - [ModelTypes.TEXT_EMBEDDING]: TextEmbeddingParams | string | null; - [ModelTypes.TEXT_TOKENIZER_ENCODE]: TokenizeTextParams; - [ModelTypes.TEXT_TOKENIZER_DECODE]: DetokenizeTextParams; - [ModelTypes.TEXT_REASONING_SMALL]: TextGenerationParams; - [ModelTypes.TEXT_REASONING_LARGE]: TextGenerationParams; - [ModelTypes.IMAGE]: ImageGenerationParams; - [ModelTypes.IMAGE_DESCRIPTION]: ImageDescriptionParams | string; - [ModelTypes.TRANSCRIPTION]: TranscriptionParams | Buffer | string; - [ModelTypes.TEXT_TO_SPEECH]: TextToSpeechParams | string; - [ModelTypes.AUDIO]: AudioProcessingParams; - [ModelTypes.VIDEO]: VideoProcessingParams; - [ModelTypes.OBJECT_SMALL]: ObjectGenerationParams; - [ModelTypes.OBJECT_LARGE]: ObjectGenerationParams; + [ModelType.TEXT_SMALL]: TextGenerationParams; + [ModelType.TEXT_LARGE]: TextGenerationParams; + [ModelType.TEXT_EMBEDDING]: TextEmbeddingParams | string | null; + [ModelType.TEXT_TOKENIZER_ENCODE]: TokenizeTextParams; + [ModelType.TEXT_TOKENIZER_DECODE]: DetokenizeTextParams; + [ModelType.TEXT_REASONING_SMALL]: TextGenerationParams; + [ModelType.TEXT_REASONING_LARGE]: TextGenerationParams; + [ModelType.IMAGE]: ImageGenerationParams; + [ModelType.IMAGE_DESCRIPTION]: ImageDescriptionParams | string; + [ModelType.TRANSCRIPTION]: TranscriptionParams | Buffer | string; + [ModelType.TEXT_TO_SPEECH]: TextToSpeechParams | string; + [ModelType.AUDIO]: AudioProcessingParams; + [ModelType.VIDEO]: VideoProcessingParams; + [ModelType.OBJECT_SMALL]: ObjectGenerationParams; + [ModelType.OBJECT_LARGE]: ObjectGenerationParams; [key: string]: BaseModelParams | any; } export interface ModelResultMap { - [ModelTypes.TEXT_SMALL]: string; - [ModelTypes.TEXT_LARGE]: string; - [ModelTypes.TEXT_EMBEDDING]: number[]; - [ModelTypes.TEXT_TOKENIZER_ENCODE]: number[]; - [ModelTypes.TEXT_TOKENIZER_DECODE]: string; - [ModelTypes.TEXT_REASONING_SMALL]: string; - [ModelTypes.TEXT_REASONING_LARGE]: string; - [ModelTypes.IMAGE]: { url: string }[]; - [ModelTypes.IMAGE_DESCRIPTION]: { title: string; description: string }; - [ModelTypes.TRANSCRIPTION]: string; - [ModelTypes.TEXT_TO_SPEECH]: Readable | Buffer; - [ModelTypes.AUDIO]: any; - [ModelTypes.VIDEO]: any; - [ModelTypes.OBJECT_SMALL]: any; - [ModelTypes.OBJECT_LARGE]: any; + [ModelType.TEXT_SMALL]: string; + [ModelType.TEXT_LARGE]: string; + [ModelType.TEXT_EMBEDDING]: number[]; + [ModelType.TEXT_TOKENIZER_ENCODE]: number[]; + [ModelType.TEXT_TOKENIZER_DECODE]: string; + [ModelType.TEXT_REASONING_SMALL]: string; + [ModelType.TEXT_REASONING_LARGE]: string; + [ModelType.IMAGE]: { url: string }[]; + [ModelType.IMAGE_DESCRIPTION]: { title: string; description: string }; + [ModelType.TRANSCRIPTION]: string; + [ModelType.TEXT_TO_SPEECH]: Readable | Buffer; + [ModelType.AUDIO]: any; + [ModelType.VIDEO]: any; + [ModelType.OBJECT_SMALL]: any; + [ModelType.OBJECT_LARGE]: any; [key: string]: any; } export enum EventType { - WORLD_JOINED = "WORLD_JOINED", - WORLD_CONNECTED = "WORLD_CONNECTED", - WORLD_LEFT = "WORLD_LEFT", - ENTITY_JOINED = "ENTITY_JOINED", - ENTITY_LEFT = "ENTITY_LEFT", - ENTITY_UPDATED = "ENTITY_UPDATED", - ROOM_JOINED = "ROOM_JOINED", - ROOM_LEFT = "ROOM_LEFT", - MESSAGE_RECEIVED = "MESSAGE_RECEIVED", - MESSAGE_SENT = "MESSAGE_SENT", - VOICE_MESSAGE_RECEIVED = "VOICE_MESSAGE_RECEIVED", - VOICE_MESSAGE_SENT = "VOICE_MESSAGE_SENT", - REACTION_RECEIVED = "REACTION_RECEIVED", - POST_GENERATED = "POST_GENERATED", - INTERACTION_RECEIVED = "INTERACTION_RECEIVED", - RUN_STARTED = "RUN_STARTED", - RUN_ENDED = "RUN_ENDED", - RUN_TIMEOUT = "RUN_TIMEOUT", - ACTION_STARTED = "ACTION_STARTED", - ACTION_COMPLETED = "ACTION_COMPLETED", - EVALUATOR_STARTED = "EVALUATOR_STARTED", - EVALUATOR_COMPLETED = "EVALUATOR_COMPLETED", + WORLD_JOINED = 'WORLD_JOINED', + WORLD_CONNECTED = 'WORLD_CONNECTED', + WORLD_LEFT = 'WORLD_LEFT', + ENTITY_JOINED = 'ENTITY_JOINED', + ENTITY_LEFT = 'ENTITY_LEFT', + ENTITY_UPDATED = 'ENTITY_UPDATED', + ROOM_JOINED = 'ROOM_JOINED', + ROOM_LEFT = 'ROOM_LEFT', + MESSAGE_RECEIVED = 'MESSAGE_RECEIVED', + MESSAGE_SENT = 'MESSAGE_SENT', + VOICE_MESSAGE_RECEIVED = 'VOICE_MESSAGE_RECEIVED', + VOICE_MESSAGE_SENT = 'VOICE_MESSAGE_SENT', + REACTION_RECEIVED = 'REACTION_RECEIVED', + POST_GENERATED = 'POST_GENERATED', + INTERACTION_RECEIVED = 'INTERACTION_RECEIVED', + RUN_STARTED = 'RUN_STARTED', + RUN_ENDED = 'RUN_ENDED', + RUN_TIMEOUT = 'RUN_TIMEOUT', + ACTION_STARTED = 'ACTION_STARTED', + ACTION_COMPLETED = 'ACTION_COMPLETED', + EVALUATOR_STARTED = 'EVALUATOR_STARTED', + EVALUATOR_COMPLETED = 'EVALUATOR_COMPLETED', } export enum PlatformPrefix { - DISCORD = "DISCORD", - TELEGRAM = "TELEGRAM", - TWITTER = "TWITTER", + DISCORD = 'DISCORD', + TELEGRAM = 'TELEGRAM', + TWITTER = 'TWITTER', } export interface EventPayload { runtime: IAgentRuntime; @@ -1329,13 +1425,19 @@ export interface MessagePayload extends EventPayload { message: Memory; callback?: HandlerCallback; } +export interface InvokePayload extends EventPayload { + worldId: UUID; + userId: string; + roomId: UUID; + callback?: HandlerCallback; +} export interface RunEventPayload extends EventPayload { runId: UUID; messageId: UUID; roomId: UUID; entityId: UUID; startTime: number; - status: "started" | "completed" | "timeout"; + status: 'started' | 'completed' | 'timeout'; endTime?: number; duration?: number; error?: string; @@ -1354,6 +1456,11 @@ export interface EvaluatorEventPayload extends EventPayload { completed?: boolean; error?: Error; } +export type MessageReceivedHandlerParams = { + runtime: IAgentRuntime; + message: Memory; + callback: HandlerCallback; +}; export interface EventPayloadMap { [EventType.WORLD_JOINED]: WorldPayload; [EventType.WORLD_CONNECTED]: WorldPayload; @@ -1364,7 +1471,7 @@ export interface EventPayloadMap { [EventType.MESSAGE_RECEIVED]: MessagePayload; [EventType.MESSAGE_SENT]: MessagePayload; [EventType.REACTION_RECEIVED]: MessagePayload; - [EventType.POST_GENERATED]: MessagePayload; + [EventType.POST_GENERATED]: InvokePayload; [EventType.INTERACTION_RECEIVED]: MessagePayload; [EventType.RUN_STARTED]: RunEventPayload; [EventType.RUN_ENDED]: RunEventPayload; @@ -1380,6 +1487,9 @@ export type EventHandler = ( export enum SOCKET_MESSAGE_TYPE { ROOM_JOINING = 1, SEND_MESSAGE = 2, + MESSAGE = 3, + ACK = 4, + THINKING = 5, } export interface MessageMemory extends Memory { metadata: MessageMetadata; @@ -1395,8 +1505,7 @@ export function createMessageMemory(params: { content: Content & { text: string }; embedding?: number[]; }): MessageMemory -export interface TypedService - extends Service { +export interface TypedService extends Service { config: ConfigType; process(input: unknown): Promise; } @@ -1405,38 +1514,13 @@ process(input: unknown): Promise; ⋮---- export function getTypedService>( runtime: IAgentRuntime, - serviceType: ServiceType + serviceType: ServiceTypeName ): T | null -export type Result = Success | Failure; -export class Success -⋮---- -constructor(value: T) -map(fn: (value: T) => U): Success -unwrapOr(_defaultValue: T): T -⋮---- -export class Failure -⋮---- -constructor(error: E) -mapError(fn: (error: E) => F): Failure -unwrapOr(defaultValue: T): T -⋮---- -export function success(value: T): Success -export function failure(error: E): Failure -export function isDocumentMetadata( - metadata: MemoryMetadata -): metadata is DocumentMetadata -export function isFragmentMetadata( - metadata: MemoryMetadata -): metadata is FragmentMetadata -export function isMessageMetadata( - metadata: MemoryMetadata -): metadata is MessageMetadata -export function isDescriptionMetadata( - metadata: MemoryMetadata -): metadata is DescriptionMetadata -export function isCustomMetadata( - metadata: MemoryMetadata -): metadata is CustomMetadata +export function isDocumentMetadata(metadata: MemoryMetadata): metadata is DocumentMetadata +export function isFragmentMetadata(metadata: MemoryMetadata): metadata is FragmentMetadata +export function isMessageMetadata(metadata: MemoryMetadata): metadata is MessageMetadata +export function isDescriptionMetadata(metadata: MemoryMetadata): metadata is DescriptionMetadata +export function isCustomMetadata(metadata: MemoryMetadata): metadata is CustomMetadata export interface ServiceError { code: string; message: string; @@ -1444,9 +1528,7 @@ export interface ServiceError { cause?: Error; } export function getVideoService(runtime: IAgentRuntime): IVideoService | null -export function getBrowserService( - runtime: IAgentRuntime -): IBrowserService | null +export function getBrowserService(runtime: IAgentRuntime): IBrowserService | null export function getPdfService(runtime: IAgentRuntime): IPdfService | null export function getFileService(runtime: IAgentRuntime): IFileService | null export function isDocumentMemory( @@ -1455,21 +1537,12 @@ export function isDocumentMemory( export function isFragmentMemory( memory: Memory ): memory is Memory & -export function getMemoryText(memory: Memory, defaultValue = ""): string +export function getMemoryText(memory: Memory, defaultValue = ''): string /** * Safely create a ServiceError from any caught error */ -export function createServiceError( - error: unknown, - code = "UNKNOWN_ERROR" -): ServiceError -export type StateValue = - | string - | number - | boolean - | null - | StateObject - | StateArray; +export function createServiceError(error: unknown, code = 'UNKNOWN_ERROR'): ServiceError +export type StateValue = string | number | boolean | null | StateObject | StateArray; export interface StateObject { [key: string]: StateValue; } @@ -1490,13 +1563,6 @@ export type ModelHandler = ( params: Record ) => Promise; export type ServiceConfig = Record; -export type MessageMemoryManager = IMemoryManager; -export type DocumentMemoryManager = IMemoryManager< - Memory & { metadata: DocumentMetadata } ->; -export type FragmentMemoryManager = IMemoryManager< - Memory & { metadata: FragmentMetadata } ->; ```` ## File: packages/docs/docs/core/actions.md @@ -1511,11 +1577,13 @@ Actions define how agents respond to and interact with messages. They enable age ## Overview +Actions are core components that define an agent's capabilities and how it can respond to conversations. Each action represents a distinct operation that an agent can perform, ranging from simple replies to complex interactions with external systems. + 1. Structure: An Action consists of: -- `name`: Unique identifier +- `name`: Unique identifier - `similes`: Alternative names/triggers - `description`: Purpose and usage explanation - `validate`: Function to check if action is appropriate @@ -1523,794 +1591,5705 @@ An Action consists of: - `examples`: Sample usage patterns - `suppressInitialMessage`: Optional flag to suppress initial response +2. Agent Decision Flow: + +When a message is received: -2. Validation: +- The agent evaluates all available actions using their validation functions +- Valid actions are provided to the LLM via the `actionsProvider` +- The LLM decides which action(s) to execute +- Each action's handler generates a response including a "thought" component (agent's internal reasoning) +- The response is processed and sent back to the conversation -- Checks if the action can be executed -- Consider conversation state -- Validate required +3. Integration: + +Actions work in concert with: + +- **Providers** - Supply context before the agent decides what action to take +- **Evaluators** - Process conversations after actions to extract insights and update memory +- **Services** - Enable actions to interact with external systems --- ## Implementation +The core Action interface includes the following components: + ```typescript interface Action { - name: string; - similes: string[]; - description: string; - examples: ActionExample[][]; - handler: Handler; - validate: Validator; - suppressInitialMessage?: boolean; + name: string; // Unique identifier + similes: string[]; // Alternative names/triggers + description: string; // Purpose and usage explanation + validate: (runtime: IAgentRuntime, message: Memory, state?: State) => Promise; + handler: ( + runtime: IAgentRuntime, + message: Memory, + state?: State, + options?: any, + callback?: HandlerCallback + ) => Promise; + examples: ActionExample[][]; + suppressInitialMessage?: boolean; // Optional flag } -``` -Source: https://github.com/elizaOS/eliza/blob/main/packages/core/src/types.ts +// Handler callback for generating responses +type HandlerCallback = (content: Content) => Promise; +// Response content structure +interface Content { + text: string; + thought?: string; // Internal reasoning (not shown to users) + actions?: string[]; // List of action names being performed + action?: string; // Legacy single action name + attachments?: Attachment[]; // Optional media attachments +} +``` ### Basic Action Template +Here's a simplified template for creating a custom action: + ```typescript const customAction: Action = { - name: "CUSTOM_ACTION", - similes: ["ALTERNATE_NAME", "OTHER_TRIGGER"], - description: "Detailed description of when and how to use this action", - validate: async (runtime: IAgentRuntime, message: Memory) => { - // Validation logic - return true; - }, - handler: async (runtime: IAgentRuntime, message: Memory) => { - // Implementation logic - return true; - }, - examples: [ - [ - { - user: "{{user1}}", - content: { text: "Trigger message" }, - }, - { - user: "{{user2}}", - content: { text: "Response", action: "CUSTOM_ACTION" }, - }, - ], + name: 'CUSTOM_ACTION', + similes: ['ALTERNATE_NAME', 'OTHER_TRIGGER'], + description: 'Detailed description of when and how to use this action', + + validate: async (runtime: IAgentRuntime, message: Memory, state?: State) => { + // Logic to determine if this action applies to the current message + // Should be efficient and quick to check + return true; // Return true if action is valid for this message + }, + + handler: async ( + runtime: IAgentRuntime, + message: Memory, + state?: State, + options?: any, + callback?: HandlerCallback + ) => { + // Implementation logic - what the action actually does + + // Generate a response with thought and text components + const responseContent = { + thought: 'Internal reasoning about what to do (not shown to users)', + text: 'The actual message to send to the conversation', + actions: ['CUSTOM_ACTION'], // List of actions being performed + }; + + // Send the response using the callback + if (callback) { + await callback(responseContent); + } + + return true; // Return true if action executed successfully + }, + + examples: [ + [ + { + name: '{{name1}}', + content: { text: 'Trigger message' }, + }, + { + name: '{{name2}}', + content: { + text: 'Response', + thought: 'Internal reasoning', + actions: ['CUSTOM_ACTION'], + }, + }, ], + ], }; ``` -#### Character File Example +### Character File Example -Actions can be used in character files as well. Here's an example from: https://github.com/elizaOS/characters/blob/main/sbf.character.json +Actions can be referenced in character files to define how an agent should respond to specific types of messages: ```json - "messageExamples": [ - [ - { - "user": "{{user1}}", - "content": { - "text": "Can you help transfer some SOL?" - } - }, - { - "user": "SBF", - "content": { - "text": "yeah yeah for sure, sending SOL is pretty straightforward. just need the recipient and amount. everything else is basically fine, trust me.", - "action": "SEND_SOL" - } +"messageExamples": [ + [ + { + "user": "{{user1}}", + "content": { + "text": "Can you help transfer some SOL?" } - ], + }, + { + "user": "SBF", + "content": { + "text": "yeah yeah for sure, sending SOL is pretty straightforward. just need the recipient and amount. everything else is basically fine, trust me.", + "actions": ["SEND_SOL"] + } + } + ] +] ``` ---- +### The Reply Action -## Example Implementations +The most fundamental action is the `REPLY` action, which allows agents to respond to messages with text. It serves as the default action when no specialized behavior is needed: -Actions can be found across various plugins in the Eliza ecosystem, with a comprehensive collection available at https://github.com/elizaos-plugins. Here are some notable examples: +```typescript +const replyAction: Action = { + name: 'REPLY', + similes: ['GREET', 'REPLY_TO_MESSAGE', 'SEND_REPLY', 'RESPOND', 'RESPONSE'], + description: 'Replies to the current conversation with the text from the generated message.', -### Blockchain and Token Actions -- Transfers: `SEND_TOKEN`, `SEND_SOL`, `SEND_NEAR`, `SEND_AVAIL`, `SEND_TON`, `SEND_TOKENS`, `COSMOS_TRANSFER`, `CROSS_CHAIN_TRANSFER` -- Token Management: `CREATE_TOKEN`, `GET_TOKEN_INFO`, `GET_BALANCE`, `GET_TOKEN_PRICE`, `TOKEN_SWAP`, `SWAP_TOKEN`, `EXECUTE_SPOT_TRADE` -- Blockchain Interactions: `READ_CONTRACT`, `WRITE_CONTRACT`, `DEPLOY_CONTRACT`, `DEPLOY_TOKEN`, `GET_TRANSACTION`, `GET_CURRENT_NONCE`, `GET_CONTRACT_SCHEMA` + validate: async (_runtime: IAgentRuntime) => true, // Always valid -### Cryptographic and Security Actions -- Signature and Authentication: `ECDSA_SIGN`, `LIT_ACTION`, `REMOTE_ATTESTATION`, `AUTHENTICATE` -- Wallet and Key Management: `ERC20_TRANSFER`, `WALLET_TRANSFER`, `BRIDGE_OPERATIONS` + handler: async ( + runtime: IAgentRuntime, + message: Memory, + state: State, + _options: any, + callback: HandlerCallback + ) => { + // Compose state with necessary providers + state = await runtime.composeState(message, [ + ...(message.content.providers ?? []), + 'RECENT_MESSAGES', + ]); + + // Generate response using LLM + const response = await runtime.useModel(ModelType.TEXT_SMALL, { + prompt: composePromptFromState({ + state, + template: replyTemplate, + }), + }); -### Staking and Governance -- Staking Actions: `STAKE`, `DELEGATE_TOKEN`, `UNDELEGATE_TOKEN`, `GET_STAKE_BALANCE`, `TOKENS_REDELEGATE` -- Governance Actions: `VOTE_ON_PROPOSAL`, `PROPOSE`, `EXECUTE_PROPOSAL`, `QUEUE_PROPOSAL` + // Parse and format response + const responseContentObj = parseJSONObjectFromText(response); + const responseContent = { + thought: responseContentObj.thought, + text: responseContentObj.message || '', + actions: ['REPLY'], + }; -### AI and Agent Management -- Agent Creation: `LAUNCH_AGENT`, `START_SESSION`, `CREATE_AND_REGISTER_AGENT` -- AI-Specific Actions: `GENERATE_IMAGE`, `DESCRIBE_IMAGE`, `GENERATE_VIDEO`, `GENERATE_MUSIC`, `GET_INFERENCE`, `GENERATE_MEME` + // Send response via callback + await callback(responseContent); + return true; + }, -### Media and Content Generation -- Image and Multimedia: `SEND_GIF`, `GENERATE_3D`, `GENERATE_COLLECTION`, `MINT_NFT`, `LIST_NFT`, `SWEEP_FLOOR_NFT` -- Audio and Voice: `EXTEND_AUDIO`, `CREATE_TTS` + examples: [ + /* Examples omitted for brevity */ + ], +}; +``` -### Decentralized Infrastructure (DePIN) -- Project Interactions: `DEPIN_TOKENS`, `DEPIN_ON_CHAIN`, `ANALYZE_DEPIN_PROJECTS` +--- -### Search and Information Retrieval -- Data Search: `WEB_SEARCH`, `GET_TOKEN_PRICE_BY_ADDRESS`, `GET_TRENDING_POOLS`, `GET_NEW_COINS`, `GET_MARKETS` +## Actions Provider Integration -### Blockchain and Trading -- Specialized Actions: `GET_QUOTE_0X`, `EXECUTE_SWAP_0X`, `CANCEL_ORDERS`, `GET_INDICATIVE_PRICE` +The actions provider is responsible for making valid actions available to the agent's reasoning process. When a message is received: -### Social and Communication -- Platform Interactions: `TWEET`, `POST_TWEET`, `QUOTE`, `JOIN_VOICE`, `LEAVE_VOICE`, `TRANSCRIBE_MEDIA`, `SUMMARIZE_CONVERSATION` +1. The provider validates all available actions against the current message +2. It formats the valid actions for inclusion in the agent context +3. This formatted information is used by the agent to decide which action(s) to take -### Utility Actions -- General Utilities: `FAUCET`, `SUBMIT_DATA`, `PRICE_CHECK`, `WEATHER`, `NEWS` +```typescript +const actionsProvider: Provider = { + name: 'ACTIONS', + description: 'Possible response actions', + position: -1, // High priority provider + get: async (runtime: IAgentRuntime, message: Memory, state: State) => { + // Validate all actions for this message + const actionPromises = runtime.actions.map(async (action: Action) => { + const result = await action.validate(runtime, message, state); + return result ? action : null; + }); -Check out the [ElizaOS Plugins org](https://github.com/elizaos-plugins) on GitHub if interested in studying or using any of these. + const resolvedActions = await Promise.all(actionPromises); + const actionsData = resolvedActions.filter(Boolean); -### Image Generation Action + // Format action information for the agent + const values = { + actionNames: `Possible response actions: ${formatActionNames(actionsData)}`, + actions: formatActions(actionsData), + actionExamples: composeActionExamples(actionsData, 10), + }; -Here's a comprehensive example of an image generation action: + // Return data, values, and text representation + return { + data: { actionsData }, + values, + text: [values.actionNames, values.actionExamples, values.actions] + .filter(Boolean) + .join('\n\n'), + }; + }, +}; +``` -```typescript -import { Action, IAgentRuntime, Memory, State } from "@elizaos/core"; +## Example Implementations -// Example image generation action -const generateImageAction: Action = { - name: "GENERATE_IMAGE", - similes: ["CREATE_IMAGE", "MAKE_IMAGE", "DRAW"], - description: "Generates an image based on the user's description", - suppressInitialMessage: true, // Suppress initial response since we'll generate our own - - // Validate if this action should be used - validate: async (runtime: IAgentRuntime, message: Memory) => { - const text = message.content.text.toLowerCase(); - // Check if message contains image generation triggers - return ( - text.includes("generate") || - text.includes("create") || - text.includes("draw") || - text.includes("make an image") - ); - }, +ElizaOS includes a wide variety of predefined actions across various plugins in the ecosystem. Here are some key categories: - // Handle the action execution - handler: async (runtime: IAgentRuntime, message: Memory, state?: State) => { - try { - // Get image service - const imageService = runtime.getService(ServiceType.IMAGE_GENERATION); - - // Generate image - const imageUrl = await imageService.generateImage(message.content.text); - - // Create response with generated image - await runtime.messageManager.createMemory({ - id: generateId(), - content: { - text: "Here's the image I generated:", - attachments: [{ - type: "image", - url: imageUrl - }] - }, - userId: runtime.agentId, - roomId: message.roomId, - }); - - return true; - } catch (error) { - console.error("Image generation failed:", error); - return false; - } - }, +### Communication Actions - // Example usage patterns - examples: [ - [ - { - user: "{{user1}}", - content: { - text: "Can you generate an image of a sunset?" - } - }, - { - user: "{{user2}}", - content: { - text: "I'll create that image for you", - action: "GENERATE_IMAGE" - } - } - ] +- **REPLY**: Standard text response +- **CONTINUE**: Extend the conversation +- **IGNORE**: End the conversation or ignore irrelevant messages + +### Blockchain and Token Actions + +- **SEND_TOKEN**: Transfer cryptocurrency +- **CREATE_TOKEN**: Create a new token on a blockchain +- **READ_CONTRACT/WRITE_CONTRACT**: Interact with smart contracts + +### Media and Content Generation + +- **GENERATE_IMAGE**: Create images from text descriptions +- **SEND_GIF**: Share animated content +- **GENERATE_3D**: Create 3D content + +### AI and Agent Management + +- **LAUNCH_AGENT**: Create and start a new agent +- **START_SESSION**: Begin an interactive session +- **GENERATE_MEME**: Create humorous content + +### Example Image Generation Action + +Here's a more detailed example of an image generation action: + +```typescript +const generateImageAction: Action = { + name: 'GENERATE_IMAGE', + similes: ['CREATE_IMAGE', 'MAKE_IMAGE', 'DRAW'], + description: "Generates an image based on the user's description", + suppressInitialMessage: true, // Don't send initial text response + + validate: async (runtime: IAgentRuntime, message: Memory) => { + const text = message.content.text.toLowerCase(); + return ( + text.includes('generate') || + text.includes('create') || + text.includes('draw') || + text.includes('make an image') + ); + }, + + handler: async ( + runtime: IAgentRuntime, + message: Memory, + state?: State, + _options?: any, + callback?: HandlerCallback + ) => { + try { + // Get appropriate service + const imageService = runtime.getService(ServiceType.IMAGE_GENERATION); + + // Generate the response with thought component + const responseContent = { + thought: + "This request is asking for image generation. I'll use the image service to create a visual based on the user's description.", + text: "I'm generating that image for you now...", + actions: ['GENERATE_IMAGE'], + }; + + // Send initial response if callback provided + if (callback) { + await callback(responseContent); + } + + // Generate image + const imageUrl = await imageService.generateImage(message.content.text); + + // Create follow-up message with the generated image + await runtime.createMemory( + { + id: generateId(), + content: { + text: "Here's the image I generated:", + attachments: [ + { + type: 'image', + url: imageUrl, + }, + ], + }, + agentId: runtime.agentId, + roomId: message.roomId, + }, + 'messages' + ); + + return true; + } catch (error) { + console.error('Image generation failed:', error); + + // Send error response if callback provided + if (callback) { + await callback({ + thought: 'The image generation failed due to an error.', + text: "I'm sorry, I wasn't able to generate that image. There was a technical problem.", + actions: ['REPLY'], + }); + } + + return false; + } + }, + + examples: [ + /* Examples omitted for brevity */ + ], +}; +``` + +## Action-Evaluator-Provider Cycle + +Actions are part of a larger cycle in ElizaOS agents: + +1. **Providers** fetch relevant context for decision-making +2. **Actions** execute the agent's chosen response +3. **Evaluators** process the conversation to extract insights +4. These insights are stored in memory +5. Future **Providers** can access these insights +6. This informs future **Actions** + +For example: + +- The FACTS provider retrieves relevant facts about users +- The agent uses this context to decide on an appropriate action +- After the action, the reflection evaluator extracts new facts and relationships +- These are stored in memory and available for future interactions +- This creates a virtuous cycle of continuous learning and improvement + +--- + +## FAQ + +### What are Actions in ElizaOS? + +Actions are core components that define how agents respond to messages and perform tasks. They encapsulate specific behaviors and capabilities, ranging from simple text replies to complex interactions with external systems. + +### How do Actions work? + +When a message is received, the agent evaluates all available actions using their validation functions. The agent then decides which action(s) to execute based on the message content and context. Each action's handler generates a response, which may include text, thought processes, and attachments. + +### What's the difference between actions and evaluators? + +Actions are executed during an agent's response to perform tasks and generate content. Evaluators run after responses to analyze conversations, extract information, and update the agent's memory. Actions are about doing, evaluators are about learning. + +### What role do "thoughts" play in actions? + +The thought component provides an internal reasoning process for the agent, explaining its decision-making. These thoughts aren't shown to users but help with debugging and understanding the agent's behavior. They're similar to the self-reflection component in evaluators. + +### How do I create a custom action? + +Define an action object with a name, similes, description, validation function, handler function, and examples. The validation function determines when the action should be used, while the handler contains the implementation logic and generates a response. + +### Can actions be chained together? + +Yes! Actions can call other actions or services as part of their implementation. This allows for complex workflows that combine multiple capabilities. For example, an action might first reply to a user, then generate an image, and finally store data in a database. + +### How does an agent choose which action to use? + +The agent uses the following process: + +1. All actions are validated against the current message +2. Valid actions are formatted and included in the agent's context +3. The LLM decides which action(s) to execute based on the message and context +4. The chosen action's handler is executed to generate a response + +### How do actions integrate with services? + +Actions often use services to interact with external systems. The action handler can retrieve a service from the runtime (e.g., `imageService = runtime.getService(ServiceType.IMAGE_GENERATION)`) and then call methods on that service to perform operations. + +### What's the difference between `actions` and `action` in responses? + +The `actions` array is the modern way to specify multiple actions being performed in a single response. The singular `action` field is maintained for backward compatibility but is deprecated in favor of the array format. + +### Can I add custom actions to an existing agent? + +Yes! You can create a plugin that defines new actions and then add that plugin to your agent's configuration. This allows you to extend the agent's capabilities without modifying its core implementation. + +## Further Reading + +- [Evaluators](./evaluators.md) +- [Providers](./providers.md) +- [Services](./services.md) +```` + +## File: packages/docs/docs/core/agents.md +````markdown +# 🤖 Agent Runtime + +The `AgentRuntime` is the core runtime environment for Eliza agents. It handles message processing, state management, plugin integration, and interaction with external services. You can think of it as the brains that provide the high-level orchestration layer for Eliza agents. + +```mermaid +sequenceDiagram + actor User + participant Platform as Platform + participant Runtime as Runtime + participant State as State + participant P as Providers + participant A as Actions + participant M as Models + participant E as Evaluators + participant DB as Database + + User->>Platform: Message + Platform->>Runtime: Forward + + %% Context building (condensed) + Runtime->>State: Get context + State->>P: Gather data + Note over P: Character, Knowledge,
Messages, Time, etc. + P-->>State: Context data + State-->>Runtime: Assembled context + + %% Action flow (condensed) + Runtime->>A: Execute action + A->>M: Generate content + M-->>A: Generated text + A-->>Runtime: Result + + %% Evaluation (condensed) + Runtime->>E: Analyze + E->>DB: Store insights + E-->>Runtime: Evaluation + + %% Delivery + Runtime->>Platform: Response + Platform->>User: Deliver + + %% Background (simplified) + par Background + Runtime->>Runtime: Tasks & Events + end +``` + +The runtime follows this general flow: + +1. **Initial Reception**: The user sends a message which is received by the Platform Services +2. **Context Building**: + + - The Runtime Core requests context from the State Composition system + - State gathers data from various Providers (Character, Knowledge, Recent Messages, etc.) + - The complete context is returned to the Runtime + +3. **Action Processing**: + + - The Runtime determines applicable actions and selects the optimal one + - The selected action may request content generation from Models + - The action result is returned to the Runtime + +4. **Learning & Persistence**: + + - The conversation is analyzed by Evaluators for insights and facts + - Knowledge updates are sent to the Memory System + - All relevant data is persisted to the Database + +5. **Response Delivery**: + - The final response is sent back to the user through Platform Services + +--- + +## Overview + +The [AgentRuntime](/api/classes/AgentRuntime) class is the primary implementation of the [IAgentRuntime](/api/interfaces/IAgentRuntime) interface, which manages the agent's core functions, including: + +| Component | Description | API Reference | Related Files | +| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Services** | Supports multiple communication platforms and specialized functionalities for seamless interaction. | [Services API](/api/interfaces/IAgentRuntime/#services) | [`service.ts`](https://github.com/elizaOS/eliza/tree/develop/packages/core/src/service.ts), [`Discord`](https://github.com/elizaos-plugins/plugin-discord), [`Telegram`](https://github.com/elizaos-plugins/plugin-telegram), [`Twitter`](https://github.com/elizaos-plugins/plugin-twitter), [`Farcaster`](https://github.com/elizaos-plugins/plugin-farcaster), [`Lens`](https://github.com/elizaos-plugins/plugin-lens), [`Slack`](https://github.com/elizaos-plugins/plugin-slack), [`Auto`](https://github.com/elizaos-plugins/plugin-auto), [`GitHub`](https://github.com/elizaos-plugins/plugin-github) | +| **State** | Maintains context for coherent cross-platform interactions, updates dynamically. Also tracks goals, knowledge, and recent interactions | [State API](/api/interfaces/State) | [`state.ts`](https://github.com/elizaos/runtime/state.ts) | +| **Plugins** | Dynamic extensions of agent functionalities using custom actions, evaluators, providers, and adapters | [Plugins API](/api/type-aliases/Plugin/) | [`plugins.ts`](https://github.com/elizaos/runtime/plugins.ts), [actions](../actions), [evaluators](../evaluators), [providers](../providers) | +| **Services** | Connects with external services for `IMAGE_DESCRIPTION`, `TRANSCRIPTION`, `TEXT_GENERATION`, `SPEECH_GENERATION`, `VIDEO`, `PDF`, `BROWSER`, `WEB_SEARCH`, `EMAIL_AUTOMATION`, and more | [Services API](/api/interfaces/IAgentRuntime/#services) | [`services.ts`](https://github.com/elizaos/runtime/services.ts) | +| **Memory Systems** | Creates, retrieves, and embeds memories and manages conversation history. | [Memory API](/api/interfaces/IMemoryManager) | [`memory.ts`](https://github.com/elizaos/runtime/memory.ts) | +| **Database Adapters** | Persistent storage and retrieval for memories and knowledge | [databaseAdapter](api/interfaces/IAgentRuntime/#databaseAdapter) | [`MongoDB`](https://github.com/elizaos-plugins/adapter-mongodb), [`PostgreSQL`](https://github.com/elizaos-plugins/adapter-postgres), [`SQLite`](https://github.com/elizaos-plugins/adapter-sqlite), [`Supabase`](https://github.com/elizaos-plugins/adapter-supabase), [`PGLite`](https://github.com/elizaos-plugins/adapter-pglite), [`Qdrant`](https://github.com/elizaos-plugins/adapter-qdrant), [`SQL.js`](https://github.com/elizaos-plugins/adapter-sqljs) | +| **Cache Management** | Provides flexible storage and retrieval via various caching methods. | [Cache API](/api/interfaces/ICacheManager) | [`cache.ts`](https://github.com/elizaos/runtime/cache.ts) | + +
+Advanced: IAgentRuntime Interface +```typescript +interface IAgentRuntime { + // Core identification + agentId: UUID; + + // Configuration + character: Character; // Personality and behavior settings + + // Components + plugins: Plugin[]; // Additional capabilities + services: Map; // Platform connections and functionality + providers: Provider[]; // Real-time data sources + actions: Action[]; // Available behaviors + evaluators: Evaluator[]; // Analysis & learning + routes: Route[]; // API endpoints + + // Memory Management + getMemories(...): Promise; // Retrieve conversation history + createMemory(...): Promise; // Store new memories + searchMemories(...): Promise; // Semantic search + + // State Composition + composeState(...): Promise; // Gather data from providers + + // Plugin Management + registerPlugin(...): Promise; // Register plugins + + // Service Management + getService(...): T | null; // Access services + registerService(...): Promise; // Register services + + // Model Integration + useModel(...): Promise; // Use AI models + + // Additional Utilities + getSetting(...): any; // Access settings + setSetting(...): void; // Configure settings + getCache(...): Promise; // Access cached data + setCache(...): Promise; // Store cached data +} +``` + +Source: [/api/interfaces/IAgentRuntime/](/api/interfaces/IAgentRuntime/) + +
+ +--- + +### **Key Methods** + +- **`initialize()`**: Sets up the agent's runtime environment, including services, plugins, and knowledge processing. +- **`processActions()`**: Executes actions based on message content and state. +- **`evaluate()`**: Assesses messages and state using registered evaluators. +- **`composeState()`**: Constructs the agent's state object for response generation. +- **`registerService()`**: Adds a service to the runtime. +- **`getService()`**: Retrieves a registered service by type. +- **`useModel()`**: Utilizes AI models with typesafe parameters and results. +- **`ensureRoomExists()` / `ensureConnection()`**: Ensures the existence of communication channels and connections. + +## Service System + +Services provide specialized functionality with standardized interfaces that can be accessed cross-platform: + +```typescript +// Speech Generation +const speechService = runtime.getService('speech_generation'); +const audioStream = await speechService.process(text); + +// PDF Processing +const pdfService = runtime.getService('pdf'); +const textContent = await pdfService.convertPdfToText(pdfBuffer); + +// Discord Integration +const discordService = runtime.getService('discord'); +await discordService.sendMessage(channelId, content); +``` + +--- + +## State Management + +The runtime maintains comprehensive state through the State interface: + +```typescript +interface State { + // Core state data + values: { + [key: string]: any; + }; + data: { + [key: string]: any; + }; + text: string; +} + +// State composition example +async function manageState() { + // Initial state composition with all regular providers + const state = await runtime.composeState(message); + + // State with specific providers only + const filteredState = await runtime.composeState(message, ['timeProvider', 'recentMessages']); + + // Include private or dynamic providers + const enhancedState = await runtime.composeState(message, null, [ + 'weatherProvider', + 'portfolioProvider', + ]); +} +``` + +--- + +## Plugin System + +Plugins extend agent functionality through a modular interface. The runtime supports various types of plugins including services, adapters, actions, and more: + +```typescript +interface Plugin { + name: string; + description: string; + init?: (config: Record, runtime: IAgentRuntime) => Promise; + + // Components + services?: (typeof Service)[]; // Communication platforms and external integrations + actions?: Action[]; // Custom behaviors + providers?: Provider[]; // Data providers + evaluators?: Evaluator[]; // Response assessment + adapters?: Adapter[]; // Database/cache adapters + routes?: Route[]; // API endpoints + tests?: TestSuite[]; // Testing utilities +} +``` + +Plugins can be configured through [characterfile](./characterfile) settings: + +```json +{ + "name": "MyAgent", + "plugins": ["@elizaos/plugin-solana", "@elizaos/plugin-twitter"], + "settings": { + "twitter": { + "shouldRespondToMentions": true + }, + "solana": { + "enableAutoTrading": false + } + } +} +``` + +For detailed information about plugin development and usage, see the [ElizaOS Registry](https://github.com/elizaos-plugins/registry). + +--- + +## Running Multiple Agents + +To run multiple agents: + +```bash +bun start --characters="characters/agent1.json,characters/agent2.json" +``` + +Or use environment variables: + +``` +REMOTE_CHARACTER_URLS=https://example.com/characters.json +``` + +--- + +## FAQ + +### What's the difference between an agent and a character? + +A character defines personality and knowledge, while an agent provides the runtime environment and capabilities to bring that character to life. + +### How do I choose the right database adapter? + +Choose based on your needs: + +- MongoDB: For scalable, document-based storage +- PostgreSQL: For relational data with complex queries +- SQLite: For simple, file-based storage +- Qdrant: For vector search capabilities + +### How do I implement custom plugins? + +Create a plugin that follows the plugin interface and register it with the runtime. See the plugin documentation for detailed examples. + +### Do agents share memory across platforms? + +By default, agents maintain separate memory contexts for different platforms to avoid mixing conversations. Use the memory management system and database adapters to persist and retrieve state information. + +### How do I handle multiple authentication methods? + +Use the character configuration to specify different authentication methods for different services. The runtime will handle the appropriate authentication flow. + +### How do I manage environment variables? + +Use a combination of: + +- `.env` files for local development +- Character-specific settings for per-agent configuration +- Environment variables for production deployment + +### Can agents communicate with each other? + +Yes, through the message system and shared memory spaces when configured appropriately. +```` + +## File: packages/docs/docs/core/database.md +````markdown +--- +sidebar_position: 7 +--- + +# 💾 Database System + +The ElizaOS database system provides persistent storage capabilities for agents. It handles memory storage, entity relationships, knowledge management, and more through a flexible adapter-based architecture. + +## Overview + +```mermaid +graph TB + %% Main Components + Runtime([Agent Runtime]) + DbAdapter([Database Adapter]) + DbConnection[("Database (PGLite/PostgreSQL)")] + + %% Data Models in compact form + DataModels["Data Models:\n Entities, Components\n Memories, Relationships\n Rooms, Worlds, Tasks\n Cache"] + + %% Vector Search + VectorStore[(Vector Store)] + + %% Memories Knowledge + MemoriesKnowledge[(Memories / Knowledge)] + + %% Connection flow + Runtime -->|Uses| DbAdapter + DbAdapter -->|Connects to| DbConnection + DbConnection -->|Stores & Retrieves| DataModels + + %% Connect Vector Store + DbConnection -->|Utilizes| VectorStore + VectorStore -->|Enables Search on| MemoriesKnowledge + + %% Styling + classDef default fill:#f0f4f8,stroke:#2c3e50,stroke-width:1px; + classDef runtime fill:#3498db,stroke:#2c3e50,stroke-width:1px,color:#fff; + classDef adapter fill:#9b59b6,stroke:#2c3e50,stroke-width:1px,color:#fff; + classDef db fill:#27ae60,stroke:#2c3e50,stroke-width:1px,color:#fff; + classDef datamodels fill:#52be80,stroke:#2c3e50,stroke-width:1px,color:#fff; + + class Runtime runtime; + class DbAdapter adapter; + class DbConnection,VectorStore db; + class DataModels datamodels; +``` + +ElizaOS uses a unified database architecture based on Drizzle ORM with adapters that implement the [`IDatabaseAdapter`](/api/interfaces/IDatabaseAdapter) interface. The current release includes support for: + +| Adapter | Best For | Key Features | +| -------------- | --------------------------- | ----------------------------------------------------------------- | +| **PGLite** | Local development & testing | Lightweight PostgreSQL implementation running in Node.js process | +| **PostgreSQL** | Production deployments | Full PostgreSQL with vector search, scaling, and high reliability | + +Additional database adapters will be supported in future releases as ElizaOS continues to evolve. + +## Core Functionality + +All database adapters extend the `BaseDrizzleAdapter` abstract class, which provides a comprehensive set of methods for managing all aspects of agent data: + +### Entity System + +| Method | Description | +| ---------------------- | ------------------------------------- | +| `createEntity()` | Create a new entity | +| `getEntityById()` | Retrieve an entity by ID | +| `getEntitiesForRoom()` | Get all entities in a room | +| `updateEntity()` | Update entity attributes | +| `getComponent()` | Get a specific component of an entity | +| `getComponents()` | Get all components for an entity | +| `createComponent()` | Add a component to an entity | +| `updateComponent()` | Update a component | +| `deleteComponent()` | Remove a component | + +### Memory Management + +| Method | Description | +| ----------------------------- | ------------------------------------ | +| `createMemory()` | Store a new memory with metadata | +| `getMemoryById()` | Retrieve a specific memory | +| `getMemories()` | Get memories matching criteria | +| `getMemoriesByIds()` | Get multiple memories by IDs | +| `getMemoriesByRoomIds()` | Get memories from multiple rooms | +| `searchMemories()` | Search memories by vector similarity | +| `searchMemoriesByEmbedding()` | Search using raw embedding vector | +| `deleteMemory()` | Remove a specific memory | +| `deleteAllMemories()` | Remove all memories in a room | +| `countMemories()` | Count memories matching criteria | + +### Room & Participant Management + +| Method | Description | +| ---------------------------- | ------------------------------- | +| `createRoom()` | Create a new conversation room | +| `getRoom()` | Get room by ID | +| `getRooms()` | Get all rooms in a world | +| `updateRoom()` | Update room attributes | +| `deleteRoom()` | Remove a room | +| `addParticipant()` | Add entity to room | +| `removeParticipant()` | Remove entity from room | +| `getParticipantsForEntity()` | Get all rooms an entity is in | +| `getParticipantsForRoom()` | List entities in a room | +| `getParticipantUserState()` | Get entity's state in a room | +| `setParticipantUserState()` | Update entity's state in a room | + +### Relationship Management + +| Method | Description | +| ---------------------- | -------------------------------------- | +| `createRelationship()` | Create a relationship between entities | +| `updateRelationship()` | Update relationship attributes | +| `getRelationship()` | Get a specific relationship | +| `getRelationships()` | Get all relationships for an entity | + +### Caching System + +| Method | Description | +| --------------- | ---------------------- | +| `getCache()` | Retrieve cached data | +| `setCache()` | Store data in cache | +| `deleteCache()` | Remove data from cache | + +### World & Task Management + +| Method | Description | +| ------------------ | --------------------------- | +| `createWorld()` | Create a new world | +| `getWorld()` | Get world by ID | +| `getAllWorlds()` | List all worlds | +| `updateWorld()` | Update world attributes | +| `removeWorld()` | Delete a world | +| `createTask()` | Create a new task | +| `getTasks()` | Get tasks matching criteria | +| `getTasksByName()` | Find tasks by name | +| `getTask()` | Get task by ID | +| `updateTask()` | Update task attributes | +| `deleteTask()` | Remove a task | + +### Agent Management + +| Method | Description | +| --------------- | ------------------------- | +| `createAgent()` | Create a new agent record | +| `getAgent()` | Get agent by ID | +| `getAgents()` | List all agents | +| `updateAgent()` | Update agent attributes | +| `deleteAgent()` | Remove an agent | +| `countAgents()` | Count total agents | + +### Embedding & Search + +| Method | Description | +| ----------------------------- | ------------------------------ | +| `ensureEmbeddingDimension()` | Configure embedding dimensions | +| `getCachedEmbeddings()` | Retrieve cached embeddings | +| `searchMemories()` | Vector search for memories | +| `searchMemoriesByEmbedding()` | Advanced vector search | + +## Architecture + +ElizaOS uses a singleton pattern for database connections to ensure efficient resource usage: + +``` +┌─────────────────────────────────────┐ +│ AgentRuntime │ +└───────────────┬─────────────────────┘ + │ + ▼ +┌─────────────────────────────────────┐ +│ IDatabaseAdapter │ +└───────────────┬─────────────────────┘ + │ + ▼ +┌─────────────────────────────────────┐ +│ BaseDrizzleAdapter │ +└───────────────┬─────────────────────┘ + │ + ┌───────┴───────┐ + ▼ ▼ +┌───────────────┐ ┌─────────────────┐ +│ PGLiteAdapter │ │ PostgresAdapter │ +└───────┬───────┘ └────────┬────────┘ + │ │ + ▼ ▼ +┌───────────────┐ ┌─────────────────┐ +│PGLiteManager │ │PostgresManager │ +│ (Singleton) │ │ (Singleton) │ +└───────────────┘ └─────────────────┘ +``` + +Each adapter is associated with a singleton connection manager that ensures only one database connection is maintained per process, regardless of how many agents are running. + +## Implementation + +### Initialization + +The database adapter is initialized through the SQL plugin: + +```typescript +// Plugin registration in project configuration +const project = { + plugins: ['@elizaos/plugin-sql'], + // ... +}; +``` + +The SQL plugin automatically selects and initializes the appropriate database adapter based on environment settings: + +```typescript +function createDatabaseAdapter( + config: { + dataDir?: string; + postgresUrl?: string; + }, + agentId: UUID +): IDatabaseAdapter { + if (config.postgresUrl) { + return new PgDatabaseAdapter(agentId, postgresConnectionManager); + } + + // Default to PGLite + return new PgliteDatabaseAdapter(agentId, pgLiteClientManager); +} +``` + +### Configuration + +Configure the database adapter using environment variables or settings: + +```typescript +// For PostgreSQL +process.env.POSTGRES_URL = 'postgresql://username:password@localhost:5432/elizaos'; + +// For PGLite (default) +process.env.PGLITE_DATA_DIR = './elizadb'; // Optional, defaults to './pglite' +``` + +### Retry Logic & Error Handling + +The database system includes built-in retry logic with exponential backoff and jitter: + +```typescript +protected async withRetry(operation: () => Promise): Promise { + let attempt = 0; + let lastError: Error | null = null; + + while (attempt < this.maxRetries) { + try { + return await operation(); + } catch (error) { + lastError = error as Error; + const isRetryable = this.isRetryableError(error); + + if (!isRetryable) { + break; + } + + // Calculate delay with exponential backoff and jitter + const delay = Math.min( + this.baseDelay * Math.pow(2, attempt) + Math.random() * this.jitterMax, + this.maxDelay + ); + + await new Promise(resolve => setTimeout(resolve, delay)); + attempt++; + } + } + + throw lastError; +} +``` + +## Example Usage + +Here are examples of common database operations: + +### Store a Memory + +```typescript +await runtime.createMemory( + { + entityId: message.entityId, + agentId: runtime.agentId, + content: { text: 'Important information to remember' }, + roomId: message.roomId, + embedding: await runtime.useModel(ModelType.TEXT_EMBEDDING, { + text: 'Important information to remember', + }), + }, + 'facts' +); +``` + +### Search for Memories + +```typescript +const embedding = await runtime.useModel(ModelType.TEXT_EMBEDDING, { + text: 'What did we discuss about databases?', +}); + +const relevantMemories = await runtime.searchMemories({ + tableName: 'messages', + embedding, + roomId: message.roomId, + count: 5, +}); +``` + +### Manage Entity Relationships + +```typescript +// Create a relationship between entities +await runtime.createRelationship({ + sourceEntityId: userEntityId, + targetEntityId: agentEntityId, + tags: ['friend', 'frequent_interaction'], + metadata: { + interactions: 42, + trust_level: 'high', + }, +}); + +// Retrieve relationships +const relationships = await runtime.getRelationships({ + entityId: userEntityId, + tags: ['friend'], +}); +``` + +## Database Schema + +The schema is managed by Drizzle ORM and includes the following key tables: + +### Core Tables + +- **entities**: The fundamental objects in the system (users, agents, etc.) +- **components**: Modular data attached to entities (profiles, settings, etc.) +- **memories**: Conversation history and other remembered information +- **relationships**: Connections between entities +- **rooms**: Conversation channels +- **participants**: Entity participation in rooms +- **worlds**: Container for multiple rooms +- **tasks**: Scheduled or queued operations +- **cache**: Temporary key-value storage +- **agents**: Agent configuration and state + +### Entity-Component System + +ElizaOS uses an entity-component architecture where: + +- Entities are the base objects (users, agents, etc.) +- Components are pieces of data attached to entities +- This allows for flexible data modeling and extension + +For example, a user entity might have profile, preferences, and authentication components. + +## Vector Search + +Both adapters support vector-based semantic search with some differences: + +- **PostgreSQL**: Uses pgvector extension for optimized vector operations +- **PGLite**: Implements vector search in JavaScript with an efficient algorithm + +The embedding dimension is configurable based on the model used: + +```typescript +await adapter.ensureEmbeddingDimension(1536); // For OpenAI embeddings +``` + +## FAQ + +### How do I choose between PGLite and PostgreSQL? + +- Use **PGLite** for: + + - Local development and testing + - Single-user deployments + - Situations where installing PostgreSQL is impractical + +- Use **PostgreSQL** for: + - Production deployments + - Multi-user systems + - High-volume data + - When you need advanced scaling features + +### How do I configure the database connection? + +For PostgreSQL, set the `POSTGRES_URL` environment variable: + +``` +POSTGRES_URL=postgresql://username:password@localhost:5432/elizaos +``` + +For PGLite, set the data directory (optional): + +``` +PGLITE_DATA_DIR=./my-data +``` + +### How can I inspect the database contents? + +For PostgreSQL, use standard PostgreSQL tools like pgAdmin or psql. + +For PGLite, the data is stored in the specified data directory as files. You can use tools like DB Browser for SQLite to inspect the SQLite files that PGLite generates. + +### How do I migrate between different database adapters? + +Currently, there's no built-in migration tool between adapters. For production systems, it's recommended to start with PostgreSQL if you anticipate needing its features. + +### What about vector embedding dimension mismatches? + +The system automatically handles embedding dimensions based on the model used. If you change embedding models, make sure to: + +1. Set the correct dimension with `ensureEmbeddingDimension()` +2. Be aware that mixing different dimensions in the same database can cause issues + +### How does the entity-component system work? + +The entity-component system (ECS) provides a flexible way to model data: + +- **Entities** are base objects with unique IDs +- **Components** are pieces of data attached to entities +- This allows for dynamic composition of objects without complex inheritance + +For example, a user entity might have profile, preferences, and authentication components. + +### How can I improve database performance? + +- For **PostgreSQL**: + + - Ensure the pgvector extension is properly installed + - Index frequently queried fields + - Use connection pooling + - Consider partitioning for large datasets + +- For **PGLite**: + - Keep database size reasonable (under 1GB) + - Regularly clean up old memories + - Limit the number of concurrent operations + +### Will other database adapters be supported in the future? + +Yes, future releases will add support for additional databases such as: + +- MongoDB +- SQLite +- Supabase +- Qdrant +- SQL.js + +The adapter interface is designed to be extensible to support a wide range of storage solutions. + +## Further Reading + +- [Memory Management](../guides/memory-management.md) +- [Entity System](./entities.md) +- [Agent Runtime](./agents.md) +```` + +## File: packages/docs/docs/core/entities.md +````markdown +--- +sidebar_position: 9 +--- + +# Entities + +Entities in ElizaOS represent users, agents, or any participant that can interact within the system. They form the basis of the entity-component architecture, allowing for flexible data modeling and relationships across the platform. + +## Entity Structure + +An entity in ElizaOS has the following properties: + +```typescript +interface Entity { + /** Unique identifier, optional on creation */ + id?: UUID; + + /** Names of the entity */ + names: string[]; + + /** Optional additional metadata */ + metadata?: { [key: string]: any }; + + /** Agent ID this account is related to, for agents should be themselves */ + agentId: UUID; + + /** Optional array of components */ + components?: Component[]; +} +``` + +| Property | Description | +| ------------ | -------------------------------------------------------- | +| `id` | Unique identifier for the entity (optional on creation) | +| `names` | Array of names the entity is known by | +| `metadata` | Additional information about the entity | +| `agentId` | ID of the agent related to this entity | +| `components` | Array of modular data components attached to this entity | + +## Components + +Components are modular pieces of data attached to entities with the following structure: + +```typescript +interface Component { + id: UUID; + entityId: UUID; + agentId: UUID; + roomId: UUID; + worldId: UUID; + sourceEntityId: UUID; + type: string; + data: { + [key: string]: any; + }; +} +``` + +| Property | Description | +| ---------------- | ------------------------------------------------- | +| `id` | Unique identifier for the component | +| `entityId` | ID of the entity this component belongs to | +| `agentId` | ID of the agent managing this component | +| `roomId` | ID of the room this component is associated with | +| `worldId` | ID of the world this component is associated with | +| `sourceEntityId` | ID of the entity that created this component | +| `type` | Type of component (e.g., "profile", "settings") | +| `data` | Additional data specific to this component type | + +## Entity Creation and Management + +### Creating an Entity + +```typescript +const entityId = await runtime.createEntity({ + names: ['John Doe', 'JohnD'], + agentId: runtime.agentId, + metadata: { + discord: { + username: 'john_doe', + name: 'John Doe', + }, + }, +}); +``` + +### Retrieving an Entity + +```typescript +// Get an entity by ID +const entity = await runtime.getEntityById(entityId); + +// Get all entities in a room +const entitiesInRoom = await runtime.getEntitiesForRoom(roomId, true); // true to include components +``` + +### Updating an Entity + +```typescript +await runtime.updateEntity({ + id: entityId, + names: [...entity.names, 'Johnny'], + metadata: { + ...entity.metadata, + customProperty: 'value', + }, +}); +``` + +## Component Management + +Components allow for flexible data modeling by attaching different types of data to entities. + +### Creating a Component + +```typescript +await runtime.createComponent({ + id: componentId, + entityId: entityId, + agentId: runtime.agentId, + roomId: roomId, + worldId: worldId, + sourceEntityId: creatorEntityId, + type: 'profile', + data: { + bio: 'Software developer interested in AI', + location: 'San Francisco', + website: 'https://example.com', + }, +}); +``` + +### Retrieving Components + +```typescript +// Get a specific component type +const profileComponent = await runtime.getComponent( + entityId, + 'profile', + worldId, // optional filter by world + sourceEntityId // optional filter by source +); + +// Get all components for an entity +const allComponents = await runtime.getComponents(entityId, worldId, sourceEntityId); +``` + +### Updating Components + +```typescript +await runtime.updateComponent({ + id: profileComponent.id, + data: { + ...profileComponent.data, + bio: 'Updated bio information', + }, +}); +``` + +### Deleting Components + +```typescript +await runtime.deleteComponent(componentId); +``` + +## Entity Relationships + +Entities can have relationships with other entities, stored in the database: + +```typescript +// Create a relationship between entities +await runtime.createRelationship({ + sourceEntityId: entityId1, + targetEntityId: entityId2, + tags: ['friend', 'collaborator'], + metadata: { + interactions: 5, + lastInteraction: Date.now(), + }, +}); + +// Get relationships for an entity +const relationships = await runtime.getRelationships({ + entityId: entityId1, + tags: ['friend'], // optional filter by tags +}); + +// Get a specific relationship +const relationship = await runtime.getRelationship({ + sourceEntityId: entityId1, + targetEntityId: entityId2, +}); + +// Update a relationship +await runtime.updateRelationship({ + ...relationship, + metadata: { + ...relationship.metadata, + interactions: relationship.metadata.interactions + 1, + lastInteraction: Date.now(), + }, +}); +``` + +## Entity Resolution + +ElizaOS includes a system for resolving entity references from messages and context. This is particularly useful for determining which entity is being referenced in a conversation. + +```typescript +// Find an entity by name or reference +const entity = await findEntityByName(runtime, message, state); +``` + +The entity resolution system considers: + +1. Exact matches by ID or username +2. Contextual matches from recent conversations +3. Relationship strength between entities +4. Role-based permissions in worlds + +## Entity Details + +To get formatted information about entities in a room: + +```typescript +// Get detailed information about entities in a room +const entityDetails = await getEntityDetails({ + runtime, + roomId, +}); + +// Format entities into a string representation +const formattedEntities = formatEntities({ entities: entitiesInRoom }); +``` + +## Relationship with Rooms and Worlds + +Entities participate in rooms and, by extension, in worlds: + +```typescript +// Add an entity as a participant in a room +await runtime.addParticipant(entityId, roomId); + +// Get all rooms where an entity is a participant +const entityRooms = await runtime.getRoomsForParticipant(entityId); + +// Get all participants in a room +const participants = await runtime.getParticipantsForRoom(roomId); +``` + +When an entity is a participant in a room that belongs to a world, the entity has an implicit relationship with that world. + +## Creating Unique Entity IDs + +For situations where you need to create deterministic, unique IDs for entity-agent pairs: + +```typescript +const uniqueId = createUniqueUuid(runtime, baseUserId); +``` + +This ensures that each user-agent interaction has a consistent, unique identifier. + +## Best Practices + +1. **Use meaningful names**: Provide descriptive names in the `names` array to make entity identification easier +2. **Structure metadata carefully**: Organize metadata by source (e.g., `discord`, `telegram`) for clarity +3. **Component segregation**: Use components to separate different aspects of entity data rather than storing everything in metadata +4. **Permission checking**: Always verify permissions before accessing components created by other entities +5. **Relationship maintenance**: Update relationship metadata regularly to reflect recent interactions +6. **Entity resolution**: Use the entity resolution system to correctly identify entities in conversations +7. **Deterministic IDs**: Use `createUniqueUuid` for consistent entity identification across sessions +```` + +## File: packages/docs/docs/core/evaluators.md +````markdown +--- +sidebar_position: 7 +--- + +# 🧠 Evaluators + +Evaluators are cognitive components in the ElizaOS framework that enable agents to process conversations, extract knowledge, and build understanding - similar to how humans form memories after interactions. They provide a structured way for agents to introspect, learn from interactions, and evolve over time. + +## Understanding Evaluators + +Evaluators are specialized functions that work with the [`AgentRuntime`](/api/classes/AgentRuntime) to analyze conversations after a response has been generated. Unlike actions that create responses, evaluators perform background cognitive tasks that enable numerous advanced capabilities: + +- **Knowledge Building**: Automatically extract and store facts from conversations +- **Relationship Tracking**: Identify connections between entities +- **Conversation Quality**: Perform self-reflection on interaction quality +- **Goal Tracking**: Determine if conversation objectives are being met +- **Tone Analysis**: Evaluate emotional content and adjust future responses +- **User Profiling**: Build understanding of user preferences and needs over time +- **Performance Metrics**: Gather data on agent effectiveness and learn from interactions + +### Core Structure + +```typescript +interface Evaluator { + name: string; // Unique identifier + similes?: string[]; // Alternative names/triggers + description: string; // Purpose explanation + examples: EvaluationExample[]; // Sample usage patterns + handler: Handler; // Implementation logic + validate: Validator; // Execution criteria check + alwaysRun?: boolean; // Run regardless of validation +} +``` + +### Evaluator Execution Flow + +The agent runtime executes evaluators as part of its cognitive cycle: + +1. Agent processes a message and generates a response +2. Runtime calls `evaluate()` after response generation +3. Each evaluator's `validate()` method determines if it should run +4. For each valid evaluator, the `handler()` function is executed +5. Results are stored in memory and inform future responses + +--- + +## Fact Evaluator: Memory Formation System + +The Fact Evaluator serves as the agent's "episodic memory formation" system - similar to how humans process conversations and form memories. Just as you might reflect after a conversation "Oh, I learned something new about Sarah today", the Fact Evaluator systematically processes conversations to build up the agent's understanding of the world and the people in it. + +### How It Works + +#### 1. Triggering (The "When to Reflect" System) + +```typescript +validate: async (runtime: IAgentRuntime, message: Memory): Promise => { + const messageCount = await runtime.messageManager.countMemories(message.roomId); + const reflectionCount = Math.ceil(runtime.getConversationLength() / 2); + return messageCount % reflectionCount === 0; +}; +``` + +Just like humans don't consciously analyze every single word in real-time, the Fact Evaluator runs periodically rather than after every message. It triggers a "reflection" phase every few messages to process what's been learned. + +#### 2. Fact Extraction (The "What Did I Learn?" System) + +The evaluator uses a template-based approach to extract three types of information: + +- **Facts**: Unchanging truths about the world or people + - "Bob lives in New York" + - "Sarah has a degree in Computer Science" +- **Status**: Temporary or changeable states + - "Bob is currently working on a new project" + - "Sarah is visiting Paris this week" +- **Opinions**: Subjective views, feelings, or non-factual statements + - "Bob thinks the project will be successful" + - "Sarah loves French cuisine" + +#### 3. Memory Deduplication (The "Is This New?" System) + +```typescript +const filteredFacts = facts.filter((fact) => { + return ( + !fact.already_known && + fact.type === 'fact' && + !fact.in_bio && + fact.claim && + fact.claim.trim() !== '' + ); +}); +``` + +Just as humans don't need to consciously re-learn things they already know, the Fact Evaluator: + +- Checks if information is already known +- Verifies if it's in the agent's existing knowledge (bio) +- Filters out duplicate or corrupted facts + +#### 4. Memory Storage (The "Remember This" System) + +```typescript +const factMemory = await factsManager.addEmbeddingToMemory({ + userId: agentId!, + agentId, + content: { text: fact }, + roomId, + createdAt: Date.now(), +}); +``` + +Facts are stored with embeddings to enable: + +- Semantic search of related facts +- Context-aware recall +- Temporal tracking (when the fact was learned) + +### Example Processing + +Given this conversation: + +``` +User: "I just moved to Seattle last month!" +Agent: "How are you finding the weather there?" +User: "It's rainy, but I love my new job at the tech startup" +``` + +The Fact Evaluator might extract: + +```json +[ + { + "claim": "User moved to Seattle last month", + "type": "fact", + "in_bio": false, + "already_known": false + }, + { + "claim": "User works at a tech startup", + "type": "fact", + "in_bio": false, + "already_known": false + }, + { + "claim": "User enjoys their new job", + "type": "opinion", + "in_bio": false, + "already_known": false + } +] +``` + +### Key Design Considerations + +1. **Episodic vs Semantic Memory** + + - Facts build up the agent's semantic memory (general knowledge) + - The raw conversation remains in episodic memory (specific experiences) + +2. **Temporal Awareness** + + - Facts are timestamped to track when they were learned + - Status facts can be updated as they change + +3. **Confidence and Verification** + + - Multiple mentions of a fact increase confidence + - Contradictory facts can be flagged for verification + +4. **Privacy and Relevance** + - Only stores relevant, conversation-appropriate facts + - Respects explicit and implicit privacy boundaries + +--- + +## Reflection Evaluator: Self-Awareness System + +The reflection evaluator extends beyond fact extraction to enable agents to develop a form of "self-awareness" about their conversational performance. It allows agents to: + +1. Generate self-reflective thoughts about the conversation quality +2. Extract factual information from conversations (similar to the Fact Evaluator) +3. Identify and track relationships between entities + +### How Reflections Work + +When triggered, the reflection evaluator: + +1. Analyzes recent conversations and existing knowledge +2. Generates structured reflection output with: + - Self-reflective thoughts about conversation quality + - New facts extracted from conversation + - Identified relationships between entities +3. Stores this information in the agent's memory for future reference + +### Example Reflection Output + +```json +{ + "thought": "I'm engaging appropriately with John, maintaining a welcoming and professional tone. My questions are helping learn more about him as a new community member.", + "facts": [ + { + "claim": "John is new to the community", + "type": "fact", + "in_bio": false, + "already_known": false + }, + { + "claim": "John found the community through a friend interested in AI", + "type": "fact", + "in_bio": false, + "already_known": false + } + ], + "relationships": [ + { + "sourceEntityId": "sarah-agent", + "targetEntityId": "user-123", + "tags": ["group_interaction"] + }, + { + "sourceEntityId": "user-123", + "targetEntityId": "sarah-agent", + "tags": ["group_interaction"] + } + ] +} +``` + +### Implementation Details + +The reflection evaluator uses a defined schema to ensure consistent output: + +```typescript +const reflectionSchema = z.object({ + facts: z.array( + z.object({ + claim: z.string(), + type: z.string(), + in_bio: z.boolean(), + already_known: z.boolean(), + }) + ), + relationships: z.array(relationshipSchema), +}); + +const relationshipSchema = z.object({ + sourceEntityId: z.string(), + targetEntityId: z.string(), + tags: z.array(z.string()), + metadata: z + .object({ + interactions: z.number(), + }) + .optional(), +}); +``` + +### Validation Logic + +The reflection evaluator includes validation logic that determines when reflection should occur: + +```typescript +validate: async (runtime: IAgentRuntime, message: Memory): Promise => { + const lastMessageId = await runtime.getCache( + `${message.roomId}-reflection-last-processed` + ); + const messages = await runtime.getMemories({ + tableName: 'messages', + roomId: message.roomId, + count: runtime.getConversationLength(), + }); + + if (lastMessageId) { + const lastMessageIndex = messages.findIndex((msg) => msg.id === lastMessageId); + if (lastMessageIndex !== -1) { + messages.splice(0, lastMessageIndex + 1); + } + } + + const reflectionInterval = Math.ceil(runtime.getConversationLength() / 4); + + return messages.length > reflectionInterval; +}; +``` + +This ensures reflections occur at appropriate intervals, typically after a set number of messages have been exchanged. + +## Common Memory Formation Patterns + +1. **Progressive Learning** + + ```typescript + // First conversation + "I live in Seattle" -> Stores as fact + + // Later conversation + "I live in the Ballard neighborhood" -> Updates/enhances existing fact + ``` + +2. **Fact Chaining** + + ```typescript + // Original facts + 'Works at tech startup'; + 'Startup is in Seattle'; + + // Inference potential + 'Works in Seattle tech industry'; + ``` + +3. **Temporal Tracking** + + ```typescript + // Status tracking + t0: 'Looking for a job'(status); + t1: 'Got a new job'(fact); + t2: 'Been at job for 3 months'(status); + ``` + +4. **Relationship Building** + + ```typescript + // Initial relationship + { + "sourceEntityId": "user-123", + "targetEntityId": "sarah-agent", + "tags": ["new_interaction"] + } + + // Evolving relationship + { + "sourceEntityId": "user-123", + "targetEntityId": "sarah-agent", + "tags": ["frequent_interaction", "positive_sentiment"], + "metadata": { "interactions": 15 } + } + ``` + +## Integration with Other Systems + +Evaluators work alongside other components: + +- **Goal Evaluator**: Facts and reflections may influence goal progress +- **Trust Evaluator**: Fact consistency affects trust scoring +- **Memory Manager**: Facts enhance context for future conversations +- **Providers**: Facts inform response generation + +--- + +## Creating Custom Evaluators + +You can create your own evaluators by implementing the `Evaluator` interface: + +```typescript +const customEvaluator: Evaluator = { + name: 'CUSTOM_EVALUATOR', + similes: ['ANALYZE', 'ASSESS'], + description: 'Performs custom analysis on conversations', + + validate: async (runtime: IAgentRuntime, message: Memory): Promise => { + // Your validation logic here + return true; + }, + + handler: async (runtime: IAgentRuntime, message: Memory, state?: State) => { + // Your evaluation logic here + + // Example of storing evaluation results + await runtime.addEmbeddingToMemory({ + entityId: runtime.agentId, + content: { text: 'Evaluation result' }, + roomId: message.roomId, + createdAt: Date.now(), + }); + + return { result: 'evaluation complete' }; + }, + + examples: [ + { + prompt: `Example context`, + messages: [ + { name: 'User', content: { text: 'Example message' } }, + { name: 'Agent', content: { text: 'Example response' } }, + ], + outcome: `{ "result": "example outcome" }`, + }, + ], +}; +``` + +### Registering Custom Evaluators + +Custom evaluators can be registered with the agent runtime: + +```typescript +// In your plugin's initialization +export default { + name: 'custom-evaluator-plugin', + description: 'Adds custom evaluation capabilities', + + init: async (config: any, runtime: IAgentRuntime) => { + // Register your custom evaluator + runtime.registerEvaluator(customEvaluator); + }, + + // Include the evaluator in the plugin exports + evaluators: [customEvaluator], +}; +``` + +## Best Practices for Memory Formation + +1. **Validate Facts** + + - Cross-reference with existing knowledge + - Consider source reliability + - Track fact confidence levels + +2. **Manage Memory Growth** + + - Prioritize important facts + - Consolidate related facts + - Archive outdated status facts + +3. **Handle Contradictions** + + - Flag conflicting facts + - Maintain fact history + - Update based on newest information + +4. **Respect Privacy** + + - Filter sensitive information + - Consider contextual appropriateness + - Follow data retention policies + +5. **Balance Reflection Frequency** + - Too frequent: Computational overhead + - Too infrequent: Missing important information + - Adapt based on conversation complexity and pace + +--- + +## FAQ + +### What's the difference between actions and evaluators? + +Actions are triggered during response generation and create visible outputs, while evaluators run after responses and perform background cognitive tasks without direct user visibility. + +### When should I use the Fact Evaluator vs. the Reflection Evaluator? + +Use the Fact Evaluator when you only need to extract and store factual information. Use the Reflection Evaluator when you need both fact extraction and relationship tracking, along with self-reflective assessment. + +### How often do evaluators run? + +By default, evaluators run at intervals based on conversation length, typically after every few messages, to avoid unnecessary processing while still capturing important information. + +### Can evaluators affect future responses? + +Yes! Facts and relationships stored by evaluators become part of the agent's memory and context, influencing future responses through the retrieval-augmented generation system. + +### How do I debug evaluator issues? + +Use the logger to inspect evaluator execution and output. The most common issues involve entity resolution failures or schema validation errors. + +### Can evaluators work across different platforms? + +Yes, evaluators are platform-agnostic and work the same way regardless of whether your agent is deployed on Discord, Twitter, Telegram, or web interfaces. + +## Related Resources + +- [Actions Documentation](./actions.md) +- [Providers Documentation](./providers.md) +- [Agent Runtime](./agents.md) +```` + +## File: packages/docs/docs/core/knowledge.md +````markdown +# Knowledge Management + +## Overview + +The Knowledge Management system in ElizaOS is a powerful Retrieval-Augmented Generation (RAG) feature that enables agents to process, store, and retrieve information from various sources. This allows agents to provide contextually relevant responses by leveraging stored knowledge during conversations. + +## Adding Knowledge to Agents + +ElizaOS provides multiple ways to add knowledge to your agents, both during initialization and at runtime. + +### Adding Knowledge During Runtime Creation + +#### 1. Via Character Definition + +The simplest approach is to define knowledge directly in your character configuration: + +```typescript +const character: Character = { + name: 'My Agent', + // Other character properties... + knowledge: [ + // Direct string knowledge + 'Important fact: ElizaOS supports multiple knowledge formats', + + // File references + { path: 'knowledge/documentation.md', shared: false }, + + // Directory references + { directory: 'knowledge/guides', shared: true }, + ], +}; +``` + +The knowledge array supports three formats: + +- String literals for direct knowledge +- File objects pointing to specific files +- Directory objects for entire folders of content + +#### 2. Programmatically Before Runtime Initialization + +You can dynamically load knowledge before creating your runtime: + +```typescript +// Load knowledge from files or other sources +const knowledge = []; + +// Example: Recursively load documentation files +function loadDocumentation(directoryPath) { + const files = getFilesRecursively(directoryPath, ['.md']); + return files.map((filePath) => { + const relativePath = path.relative(basePath, filePath); + const content = fs.readFileSync(filePath, 'utf-8'); + return `Path: ${relativePath}\n\n${content}`; + }); +} + +// Load documentation +const docKnowledge = loadDocumentation('./docs'); +knowledge.push(...docKnowledge); + +// Then include in your character definition +const character: Character = { + // Other character properties... + knowledge: knowledge, +}; +``` + +### Adding Knowledge After Runtime Creation + +#### 1. Using the `addKnowledge` Method + +Add knowledge programmatically after the runtime is initialized: + +```typescript +// Import needed utilities +import { createUniqueUuid } from '@elizaos/core'; + +// Create a knowledge item +const knowledgeItem = { + id: createUniqueUuid(runtime, 'unique-knowledge-identifier'), + content: { + text: 'Important information the agent should know...', + }, +}; + +// Add to runtime with default chunking settings +await runtime.addKnowledge(knowledgeItem); + +// Or with custom chunking settings +await runtime.addKnowledge(knowledgeItem, { + targetTokens: 1500, // Target chunk size (default: 3000) + overlap: 100, // Overlap between chunks (default: 200) + modelContextSize: 8192, // Context size of your model (default: 4096) +}); +``` + +#### 2. Processing Files at Runtime + +You can dynamically process files at runtime: + +```typescript +// For PDF files, use the PDF service +const pdfService = runtime.getService('pdf'); +if (pdfService) { + const pdfBuffer = fs.readFileSync('./knowledge/document.pdf'); + const textContent = await pdfService.convertPdfToText(pdfBuffer); + + const knowledgeItem = { + id: createUniqueUuid(runtime, 'document.pdf'), + content: { text: textContent }, + }; + + await runtime.addKnowledge(knowledgeItem); +} +``` + +## Directory Structure + +ElizaOS expects knowledge files to be organized in the following structure: + +``` +knowledge/ # Root knowledge directory +├── shared/ # Shared knowledge accessible to all agents +└── {agent-name}/ # Agent-specific knowledge directories +``` + +## Supported File Types + +- PDF files (`.pdf`) +- Markdown files (`.md`) +- Text files (`.txt`) + +## Knowledge Modes + +ElizaOS supports two knowledge modes: + +### Classic Mode (Default) + +- Direct string knowledge added to character's context +- No chunking or semantic search +- Enabled by default (`settings.ragKnowledge: false`) +- Only processes string knowledge entries +- Simpler but less sophisticated + +### RAG Mode + +- Advanced knowledge processing with semantic search +- Chunks content and uses embeddings +- Must be explicitly enabled (`settings.ragKnowledge: true`) +- Supports three knowledge types: + 1. Direct string knowledge + 2. Single file references: `{ "path": "path/to/file.md", "shared": false }` + 3. Directory references: `{ "directory": "knowledge/dir", "shared": false }` +- Supported file types: .md, .txt, .pdf +- Optional `shared` flag for knowledge reuse across characters + +To enable RAG mode, add this to your character settings: + +```typescript +const character: Character = { + // Other character properties... + settings: { + ragKnowledge: true, + }, +}; +``` + +## How Knowledge Processing Works + +### Document Processing Flow + +The RAG system processes documents through several stages: + +1. **Directory Processing** + + - The system scans configured directories in `knowledge/` + - Files are processed based on their shared/private status and file type + +2. **File Processing Pipeline** + + - **Preprocessing**: Reading, cleaning, and normalizing text + - **Document-level Processing**: Generating embeddings for the entire document + - **Chunk Processing**: Splitting content into manageable chunks and generating embeddings for each + +3. **Retrieval Process** + - When a user message is received, its embedding is generated + - This embedding is compared to stored knowledge embeddings + - The most semantically similar chunks are retrieved + - Retrieved knowledge is incorporated into the agent's context + +This multi-level approach enables: + +- Broad document-level semantic search +- Fine-grained chunk-level retrieval for specific information +- Efficient parallel processing of large documents +- Maintenance of document context through metadata linking + +### Knowledge Processing Flow Diagram + +```mermaid +graph TB + subgraph Directory_Processing + A[Read Files from Directory] --> B[File Content] + end + + subgraph Preprocessing + B --> C[Clean & Normalize Text] + end + + subgraph Document_Processing + C --> D[Generate Document Embedding] + D --> E[Store Full Document] + E --> |Metadata| F[File Path] + E --> |Metadata| G[File Type] + E --> |Metadata| H[Shared Status] + end + + subgraph Chunk_Processing + C --> I[Split into Chunks] + I --> |512 tokens| J[Chunk 1] + I --> |20 token overlap| K[...] + I --> L[Chunk N] + + subgraph Parallel_Processing + J --> M1[Generate Embedding] + K --> M2[Generate Embedding] + L --> M3[Generate Embedding] + end + + subgraph Chunk_Storage + M1 --> N1[Store Chunk] + M2 --> N2[Store Chunk] + M3 --> N3[Store Chunk] + + N1 --> |Metadata| O[Original Doc Reference] + N1 --> |Metadata| P[Chunk Index] + N2 --> |Metadata| O + N2 --> |Metadata| P + N3 --> |Metadata| O + N3 --> |Metadata| P + end + end + + style Directory_Processing fill:#f9f,stroke:#333,stroke-width:2px + style Preprocessing fill:#bbf,stroke:#333,stroke-width:2px + style Document_Processing fill:#bfb,stroke:#333,stroke-width:2px + style Chunk_Processing fill:#fbf,stroke:#333,stroke-width:2px + style Parallel_Processing fill:#fbb,stroke:#333,stroke-width:2px + style Chunk_Storage fill:#bff,stroke:#333,stroke-width:2px +``` + +### Processing Parameters + +- **Chunk Size**: 512 tokens (default, configurable when adding knowledge) +- **Chunk Overlap**: 20 tokens (default, configurable) +- **Processing Batch Size**: 10 chunks processed concurrently +- **Default Similarity Threshold**: 0.85 for retrieval +- **Default Match Count**: 5 results returned + +## Best Practices for Knowledge Management + +### Content Organization + +1. **Document Structure** + + - Use clear section headings and hierarchical organization + - Break large documents into logical smaller files + - Include metadata and context in markdown files + - Structure information from general to specific + +2. **File Management** + + - Use descriptive filenames that reflect content + - Group related files in subdirectories + - Keep paths short and meaningful + - Avoid special characters in filenames + +3. **Knowledge Optimization** + - Keep individual documents focused on specific topics + - For very detailed information, use smaller chunks (200-300 tokens) by setting `targetTokens` + - Balance the total number of knowledge items for performance + - Prefer markdown (.md) files for best processing results + +### Processing Large Knowledge Bases + +When adding many knowledge items at once, consider implementing a semaphore pattern: + +```typescript +import { Semaphore } from '@elizaos/core'; + +// Create semaphore to limit concurrent processing +const semaphore = new Semaphore(10); + +// Process items with controlled concurrency +await Promise.all( + items.map(async (item) => { + await semaphore.acquire(); + try { + await runtime.addKnowledge(item); + } finally { + semaphore.release(); + } + }) +); +``` + +### Knowledge ID Management + +When adding knowledge programmatically, use consistent ID generation: + +```typescript +import { createUniqueUuid } from '@elizaos/core'; +const knowledgeId = createUniqueUuid(runtime, 'my-content'); +``` + +This ensures deterministic IDs that remain stable across sessions. + +## Troubleshooting + +### Common Issues and Solutions + +1. **Knowledge Not Being Retrieved**: + + - Verify the file is in a supported format (PDF, MD, TXT) + - Check if embeddings were properly generated + - Ensure similarity threshold isn't too high (default: 0.85) + - Test retrieval with more specific queries + - Verify RAG mode is enabled if using file/directory references + +2. **Poor Quality Retrievals**: + + - Break down large documents into smaller, focused files + - Ensure document content is clear and well-structured + - Review the chunking size and overlap settings + - Check if the query contains too many common words + +3. **Performance Issues**: + + - Monitor the total number of knowledge items + - Consider reducing the match count for faster retrieval + - Check embedding processing time for large documents + - Use shared knowledge efficiently across agents + +4. **File Processing Errors**: + - Verify file permissions + - Check if paths are correctly structured + - Ensure PDF files are readable and not password-protected + - Validate that text encoding is UTF-8 + +## Technical Implementation Details + +### Knowledge ID Relationships + +The RAG system uses a hierarchical ID structure to maintain relationships: + +```mermaid +classDiagram + class Document { + +UUID id + +String filePath + +String fileType + +Boolean isShared + +Float32Array embedding + +String content + } + + class Fragment { + +UUID id + +UUID originalId + +Number chunkIndex + +String content + +Float32Array embedding + +String originalPath + } + + Document "1" --> "*" Fragment : generates +``` + +#### ID Generation and Linking + +Documents IDs are generated using `createUniqueUuid(runtime, path, isShared)`, making them deterministic. Fragment IDs follow the format `${documentId}-chunk-${index}` to maintain the relationship to their source document. + +## API Reference + +### Key Methods + +#### `runtime.addKnowledge(item: KnowledgeItem, options?): Promise` + +Adds new knowledge to the agent. + +- Parameters: + - `item`: A knowledge item containing: + - `id`: UUID + - `content`: Object with `text` property + - `options`: Optional processing configuration: + - `targetTokens`: Number (default: 3000) + - `overlap`: Number (default: 200) + - `modelContextSize`: Number (default: 4096) + +#### `runtime.getKnowledge(message: Memory): Promise` + +Retrieves knowledge based on a message's content. + +- Parameters: + - `message`: Memory object containing user message +- Returns: Array of matching KnowledgeItem objects + +### Knowledge Item Definition + +```typescript +interface KnowledgeItem { + id: UUID; + content: { + text: string; + // Optional additional metadata + [key: string]: any; + }; +} +``` + +## Security Considerations + +1. **Access Control**: + + - Use the `shared` flag appropriately to control document access + - Keep sensitive information in agent-specific directories + - Regularly audit knowledge access patterns + +2. **Data Privacy**: + - Do not store sensitive personal information in knowledge files + - Review documents for potentially sensitive content before adding + - Implement appropriate backup and recovery procedures + +## Future Considerations + +1. **Scalability**: + + - Monitor knowledge base size and performance + - Plan for regular maintenance and cleanup + - Consider implementing document versioning + +2. **Integration**: + - Document integration points with other systems + - Plan for potential future file format support + - Consider implementing knowledge base analytics + +## Support and Resources + +- Review the implementation in `packages/core/src/ragknowledge.ts` +- Check the issue tracker for known issues and solutions +- Contribute improvements and bug fixes through pull requests +```` + +## File: packages/docs/docs/core/overview.md +````markdown +--- +sidebar_position: 1 +title: ElizaOS Documentation +slug: / +--- + +# ElizaOS Documentation + +Welcome to ElizaOS - a comprehensive framework for building AI agents with persistent personalities across multiple platforms. ElizaOS provides the architecture, tools, and systems needed to create sophisticated agents that maintain consistent behavior, learn from interactions, and seamlessly integrate with a variety of services. + +## System Architecture + +ElizaOS uses a modular architecture that separates concerns while providing a cohesive framework for AI agent development: + +```mermaid +graph TB + %% Main Components with vertical orientation + User((User)):::user + + %% First Level - Services + PlatformServices[Services]:::services + + %% Second Level - Runtime + AgentRuntime[Agent Runtime]:::core + + %% Core Processing Components - Side by side + subgraph "Core Processing" + direction LR + Providers[Providers]:::int + Actions[Actions]:::int + Evaluators[Evaluators]:::int + end + + %% Knowledge and DB - Side by side + subgraph "Knowledge & Storage" + direction LR + Knowledge[Knowledge]:::int + DB[(Database)]:::db + end + + %% Organization Components - Vertical layout + subgraph "Organization" + direction TB + Worlds[Worlds]:::struct + Rooms[Rooms]:::struct + Entities[Entities]:::struct + end + + %% Development Components - Side by side + subgraph "Development & Integration" + direction LR + Plugins[Plugins]:::dev + Projects[Projects]:::dev + Tasks[Tasks]:::dev + end + + %% Main Flow - Vertical emphasis + User <-->|Interaction| PlatformServices + PlatformServices -->|Process| AgentRuntime + + %% Runtime connections - Simplified + AgentRuntime ---|Context| Providers + AgentRuntime ---|Behavior| Actions + AgentRuntime ---|Analysis| Evaluators + + %% Data connections + AgentRuntime <-->|Storage| DB + Knowledge -->|Informs| Providers + + %% Structure connections - Clean vertical hierarchy + AgentRuntime -->|Manages| Worlds + Worlds -->|Contains| Rooms + Rooms -->|Has| Entities + + %% Development connections + Projects -->|Configure| AgentRuntime + Plugins -->|Extend| AgentRuntime + Tasks -->|Scheduled by| AgentRuntime + + %% Clickable nodes with links to docs + click AgentRuntime "/docs/core/agents" "Learn about Agent Runtime" + click PlatformServices "/docs/core/services" "Learn about Services" + click DB "/docs/core/database" "Learn about Database Systems" + click Actions "/docs/core/actions" "Learn about Actions" + click Providers "/docs/core/providers" "Learn about Providers" + click Evaluators "/docs/core/evaluators" "Learn about Evaluators" + click Knowledge "/docs/core/knowledge" "Learn about Knowledge System" + click Worlds "/docs/core/worlds" "Learn about Worlds" + click Rooms "/docs/core/rooms" "Learn about Rooms" + click Entities "/docs/core/entities" "Learn about Entities" + click Plugins "/docs/core/plugins" "Learn about Plugins" + click Projects "/docs/core/project" "Learn about Projects" + click Tasks "/docs/core/tasks" "Learn about Tasks" + + %% Styling + classDef core fill:#3498db,stroke:#2c3e50,stroke-width:1px,color:#fff,font-weight:bold + classDef services fill:#9b59b6,stroke:#2c3e50,stroke-width:1px,color:#fff,font-weight:bold + classDef db fill:#27ae60,stroke:#2c3e50,stroke-width:1px,color:#fff,font-weight:bold + classDef int fill:#e74c3c,stroke:#2c3e50,stroke-width:1px,color:#fff,font-weight:bold + classDef struct fill:#f39c12,stroke:#2c3e50,stroke-width:1px,color:#fff,font-weight:bold + classDef dev fill:#1abc9c,stroke:#2c3e50,stroke-width:1px,color:#fff,font-weight:bold + classDef user fill:#ecf0f1,stroke:#2c3e50,stroke-width:2px,color:#2c3e50,font-weight:bold,border-radius:50% +``` + +### How ElizaOS Works + +When a user message is received: + +1. **Service Reception**: Platform service (Discord, Telegram, etc.) receives the message +2. **Runtime Processing**: Agent runtime coordinates the response generation +3. **Context Building**: Providers supply relevant context (time, recent messages, knowledge) +4. **Action Selection**: The agent evaluates and selects appropriate actions +5. **Response Generation**: The chosen action generates a response +6. **Learning & Reflection**: Evaluators analyze the conversation for insights and learning +7. **Memory Storage**: New information is stored in the database +8. **Response Delivery**: The response is sent back through the service + +This creates a continuous cycle of interaction, reflection, and improvement that allows agents to maintain consistent personalities while adapting to new information. + +## Core Components + +
+
+
+
+
+ Overview +
+
+

🤖 Agent Runtime

+

The central system that orchestrates agent behavior, processes messages, manages state, and coordinates all other components.

+
+ +
+
+ +
+
+
+ Overview +
+
+

📚 Services

+

Platform-specific integrations that enable agents to communicate across Discord, Twitter, Telegram, and other channels.

+
+
+ Services +
+
+
+ +
+
+
+ Overview +
+
+

💾 Database

+

Persistent storage for memories, entity data, relationships, and configuration using vector search capabilities.

+
+
+ Database +
+
+
+
+
+ +## Intelligence & Behavior + +
+
+
+
+
+ Overview +
+
+

⚡ Actions

+

Executable capabilities that define how agents respond to messages and interact with external systems.

+
+
+ Actions +
+
+
+ +
+
+
+ Overview +
+
+

🔌 Providers

+

Data sources that supply contextual information to inform agent decision-making in real-time.

+
+
+ Providers +
+
+
+ +
+
+
+ Overview +
+
+

📊 Evaluators

+

Analytical systems that process conversations to extract insights, learn facts, and improve future responses.

+
+ +
+
+ +
+
+
+ Overview +
+
+

🧠 Knowledge

+

RAG system for document processing, semantic search, and context-aware memory retrieval.

+
+
+ Knowledge +
+
+
+
+
+ +## Structure & Organization + +
+
+
+
+
+ Overview +
+
+

🌐 Worlds

+

Collection spaces that organize entities and rooms into coherent environments (like a Discord server).

+
+
+ Worlds +
+
+
+ +
+
+
+ Overview +
+
+

💬 Rooms

+

Conversation spaces where entities interact through messages (channels, DMs, threads).

+
+
+ Rooms +
+
+
+ +
+
+
+ Overview +
+
+

👤 Entities

+

Representation of users, agents, and other participants using a flexible entity-component architecture.

+
+
+ Entities +
+
+
+
+
+ +## Development & Integration + +
+
+
+
+
+ Overview +
+
+

🧩 Plugins

+

Modular extensions that add new capabilities, integrations, and behaviors to agents.

+
+
+ Plugins +
+
+
+ +
+
+
+ Overview +
+
+

📝 Projects

+

Organizational structure for defining and deploying one or more agents with their configuration.

+
+
+ Projects +
+
+
+ +
+
+
+ Overview +
+
+

📋 Tasks

+

System for managing deferred, scheduled, and repeating operations across conversations.

+
+
+ Tasks +
+
+
+
+
+ +--- + +## Key Concepts + +### Action-Provider-Evaluator Cycle + +The core of the ElizaOS system operates as a continuous cycle: + +1. **Providers** gather context before response generation +2. **Actions** determine what the agent can do and are executed to generate responses +3. **Evaluators** analyze conversations after responses to extract insights +4. These insights become part of the agent's memory +5. Future **Providers** access this memory to inform new responses + +This creates a virtuous cycle where agents continuously learn and improve from interactions. + +### Entity-Component Architecture + +ElizaOS uses an entity-component architecture for flexible data modeling: + +- **Entities** are base objects with unique IDs (users, agents, etc.) +- **Components** are pieces of data attached to entities (profiles, settings, etc.) +- This approach allows for dynamic composition without complex inheritance hierarchies + +### Memory System + +The memory system in ElizaOS provides: + +- **Vector-based semantic search** for finding relevant memories +- **Multi-level memory types** (messages, facts, knowledge) +- **Temporal awareness** through timestamped memories +- **Cross-platform continuity** while maintaining appropriate context boundaries + +## Getting Started + +If you're new to ElizaOS, we recommend this learning path: + +1. Start with this overview to understand the system architecture +2. Explore the [Agent Runtime](/docs/core/agents) to understand the core system +3. Learn about [Projects](/docs/core/project) to set up your development environment +4. Understand how [Actions](/docs/core/actions) and [Providers](/docs/core/providers) work together +5. Explore [Services](/docs/core/services) to connect with external platforms +6. Dive into [Plugins](/docs/core/plugins) to extend functionality + +## FAQ + +
+What's the difference between Actions, Evaluators, and Providers? + +**Actions** define what an agent can do and are executed during response generation. **Evaluators** analyze conversations after they happen to extract insights and improve future responses. **Providers** supply contextual information before the agent decides how to respond. + +
+ +
+How does ElizaOS handle cross-platform conversation context? + +ElizaOS maintains separate conversation contexts for different platforms by default, but shares entity relationships and learned facts across platforms. This ensures agents maintain a consistent understanding of users while respecting platform-specific conversation boundaries. + +
+ +
+How does the memory system work? + +Memory is organized into different types (messages, facts, knowledge) and stored with vector embeddings for semantic search. This allows agents to retrieve relevant memories based on context rather than just recency, creating more natural conversations. + +
+ +
+What's the relationship between Worlds, Rooms, and Entities? + +Worlds are container spaces (like a Discord server) that can have multiple Rooms (channels, DMs). Entities (users, agents) participate in Rooms within Worlds. This hierarchical structure mirrors real-world platforms while providing a consistent abstraction. + +
+ +
+How extensible is ElizaOS? + +ElizaOS is highly extensible through its plugin system. You can create custom actions, providers, evaluators, services, and more to extend functionality. The architecture is designed to be modular and composable at every level. + +
+ +## Additional Resources + +- [API Reference](/api) - Detailed API documentation for developers +- [GitHub Repository](https://github.com/elizaos/eliza) - Source code and contributions +- [Package Showcase](/packages) - Explore available plugins and extensions +```` + +## File: packages/docs/docs/core/plugins.md +````markdown +# Plugins + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +Plugins are modular extensions that enhance the capabilities of ElizaOS agents. They provide a flexible way to add new functionality, integrate external services, and customize agent behavior across different platforms. + +:::info +Key Improvements in V2 + +1. **Unified API**: Almost everything is accessible via `runtime.methodName()` in the agent runtime for simpler development +2. **Enhanced Model System**: The new `useModel` approach allows for flexible model provider registration +3. **Events System**: Formal support for event-based programming +4. **Plugin Creation Workflow**: Simplified creation and testing via CLI +5. **Testing Infrastructure**: Built-in support for plugin testing +6. **No Monorepo Required**: Complete plugin development without touching the core codebase +7. **Plugin Registry**: Manages the catalog of available plugins and handles their registration with the runtime +8. **Bootstrap Plugin**: Initializes core functionality required for all agents to operate + ::: + +The ElizaOS plugin system maintains the same basic concept as previous versions, with several new extension points (events, routes, tests, models) and features that significantly improve the developer experience. + +**Browse plugins the elizaOS community made here: [Package Showcase](/packages)** + +[![](/img/plugins.png)](/packages) + +> elizaOS maintains an official package registry at [github.com/elizaos-plugins/registry](https://github.com/elizaos-plugins/registry). + +--- + +## Quick Start + +The new CLI tool introduces a streamlined workflow for plugin development without ever needing to touch the ElizaOS monorepo directly: + +1. **Create**: `npm create eliza` - Initialize a new plugin project with proper structure +2. **Develop**: Edit the plugin code in the generated project structure +3. **Test**: `npx elizaos test` - Test the plugin functionality +4. **Run**: `npx elizaos start` - Run the plugin with a default agent +5. **Publish**: `npx elizaos publish` - Share your plugin with others + +> Note: at time of publishing, use `npm create eliza@beta` until main version is uploaded + +### Creating a New Plugin + +You can create a new ElizaOS plugin using the CLI: + +```bash +# Using npm +npm create eliza@beta + +# Or using npx +npx @elizaos/cli@beta create +``` + +When prompted, select "Plugin" as the type to create. The CLI will guide you through the setup process, creating a plugin with the proper structure and dependencies. + +--- + +### Managing Plugins + +There are several ways to add plugins to your ElizaOS project: + + + + ```json + { + "dependencies": { + "@elizaos/plugin-solana": "github:elizaos-plugins/plugin-solana", + "@elizaos/plugin-twitter": "github:elizaos-plugins/plugin-twitter" + } + } + ``` + + + ```typescript + // In src/index.ts + export const character: Character = { + name: 'MyAgent', + plugins: ['@elizaos/plugin-twitter', '@elizaos/plugin-example'], + // ... + }; + ``` + + + ```bash + # Add a plugin + npx @elizaos/cli plugins add @elizaos/plugin-twitter + + # Remove a plugin + npx @elizaos/cli plugins remove @elizaos/plugin-twitter + + # List available plugins + npx @elizaos/cli plugins list + ``` + + + + +--- + +### Plugin Configuration + +Configure plugin settings in your character definition: + +```json +{ + "name": "MyAgent", + "plugins": ["@elizaos/plugin-example"], + "settings": { + "example": { + "enableFeatureX": true + // Plugin-specific configuration + } + } +} +``` + +### Plugin Loading Process + +The AgentRuntime automatically loads the Bootstrap Plugin during initialization, before any other plugins: + +```typescript +async initialize() { + // Register bootstrap plugin + await this.registerPlugin(bootstrapPlugin); + + // Then register additional plugins + for (const plugin of this.plugins) { + await this.registerPlugin(plugin); + } + + // Initialize other components + // ... +} +``` + +--- + +### Publishing Plugins + +If you're a plugin developer, you can publish your plugin to make it available to others. The ElizaOS CLI provides several options for publishing your plugin depending on your needs. + +First, make sure your plugin is built and ready for distribution: + +```bash +# Navigate to your plugin directory +cd my-eliza-plugin + +# Build your plugin +npm run build +``` + + + + Publishing to GitHub is the recommended approach for sharing your plugin with the ElizaOS community: + + ```bash + # Publish to GitHub + npx @elizaos/cli publish + ``` + + This will: + 1. Build and package your plugin + 2. Create or update a GitHub repository in the elizaos-plugins organization + 3. Add your plugin to the ElizaOS registry (if you're a registry maintainer) + + For first-time publishers, the CLI will guide you through setting up GitHub credentials for publishing. + + GitHub publishing is ideal for open-source plugins that you want to share with the community and have listed in the official registry. + + + + + You can also publish your plugin to npm: + + ```bash + # Publish to npm + npx @elizaos/cli publish --npm + ``` + + This allows users to install your plugin using standard npm commands: + + ```bash + npm install @your-scope/plugin-name + ``` + + npm publishing is useful when you want to: + - Maintain your own package namespace + - Integrate with existing npm workflows + - Set up automated versioning and releases + + Make sure your package.json is properly configured with the correct name, version, and access permissions. + + + + + Before publishing, you can validate the process without making any external changes: + + ```bash + # Test the publish process + npx @elizaos/cli publish --test + ``` + + This runs through all the packaging and validation steps without actually publishing anything. + + Test mode is helpful for: + - Verifying your plugin structure is correct + - Ensuring all required files are present + - Checking that dependencies are properly configured + - Validating that your plugin can be built successfully + + Always run in test mode before your first public release to avoid issues. + + + + + The publish command supports several additional options to customize the publishing process: + + ```bash + # Specify platform compatibility + npx @elizaos/cli publish --platform node + + # Set custom version number + npx @elizaos/cli publish --version 1.2.3 + + # Provide a custom registry URL + npx @elizaos/cli publish --registry https://custom-registry.com + + # Publish with public access + npx @elizaos/cli publish --access public + ``` + + These options give you fine-grained control over how and where your plugin is published. Refer to `npx @elizaos/cli publish --help` for a complete list of options. + + + + +:::info +When submitting a plugin to the [elizaOS Registry](https://github.com/elizaos-plugins/registry), include: + +1. **Working Demo**: Screenshots or video of your plugin in action +2. **Test Results**: Evidence of successful integration and error handling +3. **Configuration Example**: Show how to properly configure your plugin + ::: + +--- + +## Plugin Architecture + +Eliza uses a unified plugin architecture where everything is a plugin - including services, adapters, actions, evaluators, and providers. This approach ensures consistent behavior and better extensibility. + +### Plugin Components + +Each plugin can provide one or more of the following components: + +| Component | Purpose | +| ------------------ | ------------------------------------------------------------------------------- | +| **Services** | Platform integrations (Discord, Twitter, etc.) or specialized capabilities | +| **Actions** | Executable functions triggered by the agent (reply, generate content, etc.) | +| **Providers** | Context providers that supply info to the agent during decision making | +| **Evaluators** | Analyze conversations to extract insights and improve future interactions | +| **Adapters** | Database or storage system integrations | +| **Model Handlers** | Register handlers for different model types (text generation, embeddings, etc.) | +| **Event Handlers** | React to system events like messages, connections, or actions | +| **API Routes** | Add custom REST endpoints to the agent's HTTP interface | +| **Tests** | Include test suites to verify plugin functionality | + +### Plugin Interface + +All plugins implement the core Plugin interface: + +```typescript +interface Plugin { + name: string; + description: string; + config?: { [key: string]: any }; + + // Optional initialization method + init?: (config: Record, runtime: IAgentRuntime) => Promise; + + // Components + services?: (typeof Service)[]; + actions?: Action[]; + providers?: Provider[]; + evaluators?: Evaluator[]; + adapters?: Adapter[]; + + // Additional features + routes?: Route[]; + tests?: TestSuite[]; + events?: { [key: string]: ((params: any) => Promise)[] }; +} +``` + +### Service Implementation + +Services are the core integration points for external platforms. A properly implemented service: + +```typescript +import { Service, IAgentRuntime } from '@elizaos/core'; + +export class ExampleService extends Service { + // Required: Define the service type (used for runtime registration) + static serviceType = 'example'; + + // Required: Describe what this service enables the agent to do + capabilityDescription = 'Enables the agent to interact with the Example platform'; + + // Store runtime for service operations + constructor(protected runtime: IAgentRuntime) { + super(); + // Initialize connections, setup event handlers, etc. + } + + // Required: Static method to create and initialize service instance + static async start(runtime: IAgentRuntime): Promise { + const service = new ExampleService(runtime); + // Additional initialization if needed + return service; + } + + // Required: Clean up resources when service is stopped + async stop(): Promise { + // Close connections, release resources + } + + // Optional: Custom methods for your service functionality + async sendMessage(content: string, channelId: string): Promise { + // Implementation + } +} +``` + +## Plugin Structure + +Each plugin repository should follow this structure: + +``` +plugin-name/ +├── images/ # Branding assets +│ ├── logo.png # Square logo (400x400px) +│ ├── banner.png # Banner image (1280x640px) +│ └── screenshots/ # Feature screenshots +├── src/ +│ ├── index.ts # Main plugin entry point +│ ├── service.ts # Service implementation +│ ├── actions/ # Plugin-specific actions +│ ├── providers/ # Data providers +│ ├── types.ts # Type definitions +│ └── environment.ts # Configuration validation +├── tests/ # Test suite +├── package.json # Plugin configuration and dependencies +└── README.md # Plugin documentation +``` + +### Plugin Entry Point + +Your plugin's `index.ts` should export a Plugin object: + +```typescript +// Example plugin implementation +import { type Plugin } from '@elizaos/core'; +import { ExampleService } from './service'; +import { searchAction } from './actions/search'; +import { statusProvider } from './providers/status'; + +const examplePlugin: Plugin = { + name: 'example', + description: 'Example platform integration for ElizaOS', + services: [ExampleService], + actions: [searchAction], + providers: [statusProvider], + init: async (config, runtime) => { + // Perform any necessary initialization + const apiKey = runtime.getSetting('EXAMPLE_API_KEY'); + if (!apiKey) { + console.warn('EXAMPLE_API_KEY not provided'); + } + }, +}; + +export default examplePlugin; +``` + +### Plugin Configuration + +Your plugin's `package.json` should include an `agentConfig` section: + +```json +{ + "name": "@elizaos/plugin-example", + "version": "1.0.0", + "agentConfig": { + "pluginType": "elizaos:plugin:1.0.0", + "pluginParameters": { + "API_KEY": { + "type": "string", + "description": "API key for the Example service" + } + } + } +} +``` + +### Environment Variables and Secrets + +Plugins access configuration through the runtime with the following precedence: + +1. Character settings secrets (highest priority) +2. Character settings +3. Global environment settings + +#### Access Pattern + +```typescript +// In your service implementation +const apiKey = runtime.getSetting('EXAMPLE_API_KEY'); +const debugMode = runtime.getSetting('EXAMPLE_DEBUG_MODE'); // Returns boolean for "true"/"false" strings +``` + +#### Configuration in Character File + +```json +{ + "name": "MyAgent", + "plugins": ["@elizaos/plugin-example"], + "settings": { + "example": { + "enableFeatureX": true + }, + "secrets": { + "EXAMPLE_API_KEY": "your-api-key-here" + } + } +} +``` + +--- + +## Bootstrap Plugin + +The Bootstrap Plugin is a foundational component of ElizaOS that initializes the core functionality required for agents to operate. It's automatically loaded as part of the initialization process, establishing the minimum viable capabilities that all agents need. + +```typescript +export const bootstrapPlugin: Plugin = { + name: 'bootstrap', + description: 'Agent bootstrap with basic actions and evaluators', + actions: [...], + events: {...}, + evaluators: [...], + providers: [...], + services: [TaskService, ScenarioService], +}; +``` + +The Bootstrap Plugin registers essential components across several categories to provide a foundation for all agents. These components can be extended by custom plugins. + + + + | Action | Description | + | ---------------------- | ----------------------------------------------- | + | `replyAction` | Generates and sends a response to a message | + | `followRoomAction` | Enables an agent to actively follow a room | + | `unfollowRoomAction` | Stops an agent from following a room | + | `muteRoomAction` | Mutes notifications from a room | + | `unmuteRoomAction` | Unmutes notifications from a room | + | `sendMessageAction` | Sends a message to a specific room | + | `ignoreAction` | Explicitly ignores a message | + | `noneAction` | Acknowledges a message without taking action | + | `updateEntityAction` | Updates properties of an entity | + | `choiceAction` | Presents choices to users and handles responses | + | `updateRoleAction` | Updates a user's role in a world | + | `updateSettingsAction` | Updates agent or world settings | + + + + | Provider | Description | + | ------------------------ | ---------------------------------------------------------- | + | `characterProvider` | Provides the agent's personality and configuration | + | `recentMessagesProvider` | Retrieves recent conversation history | + | `knowledgeProvider` | Supplies factual information from the knowledge base | + | `timeProvider` | Provides awareness of current time and date | + | `entitiesProvider` | Supplies information about entities in the current context | + | `relationshipsProvider` | Provides information about entity relationships | + | `factsProvider` | Retrieves relevant facts from memory | + | `roleProvider` | Provides role information within worlds | + | `settingsProvider` | Supplies configured settings | + | `anxietyProvider` | Informs agent of potential issues to be careful about | + | `attachmentsProvider` | Handles media and file attachments | + | `providersProvider` | Meta-provider with information about available providers | + | `actionsProvider` | Meta-provider with information about available actions | + | `evaluatorsProvider` | Meta-provider with information about available evaluators | + | `choiceProvider` | Manages choice-based interactions | + | `capabilitiesProvider` | Provides information about agent capabilities | + + + + **Services:** + + | Service | Purpose | + | ----------------- | ------------------------------------------------ | + | `TaskService` | Manages deferred, scheduled, and repeating tasks | + | `ScenarioService` | Handles scenario-based interactions and testing | + + **Evaluators:** + + | Evaluator | Description | + | --------------------- | ----------------------------------------------------- | + | `reflectionEvaluator` | Enables self-awareness and learning from interactions | + + + + + The Bootstrap Plugin registers handlers for key system events that enable the core message processing flow: + + **Core Events:** + - `MESSAGE_RECEIVED` - Processes new messages and generates responses + - `REACTION_RECEIVED` - Tracks reactions to messages + - `VOICE_MESSAGE_RECEIVED` - Handles audio messages + - `POST_GENERATED` - Creates social media content + - `MESSAGE_SENT` - Logs outgoing messages + + **World Events:** + - `WORLD_JOINED` / `WORLD_CONNECTED` - Synchronizes data when joining worlds + - `ENTITY_JOINED` / `ENTITY_LEFT` - Manages entity presence + + **Lifecycle Events:** + - `ACTION_STARTED` / `ACTION_COMPLETED` - Tracks action execution + - `EVALUATOR_STARTED` / `EVALUATOR_COMPLETED` - Monitors evaluator processing + - `RUN_STARTED` / `RUN_ENDED` / `RUN_TIMEOUT` - Manages message processing lifecycle + + The message processing flow follows these steps: + 1. Receive message via `MESSAGE_RECEIVED` event + 2. Save message to memory + 3. Check if agent should respond + 4. If responding, compose state from providers + 5. Generate a response using the language model + 6. Process any actions specified in the response + 7. Run evaluators on the conversation + 8. Emit lifecycle events throughout the process + + + + +### Extending Bootstrap Functionality + +While the Bootstrap Plugin provides core functionality, it's designed to be extended by other plugins. Custom plugins can: + +1. **Add new actions** - Extend the agent's capabilities +2. **Register additional providers** - Supply more contextual information +3. **Add evaluators** - Create new ways to analyze and learn from interactions +4. **Handle additional events** - React to more system events +5. **Initialize custom services** - Provide new functionality + +When working with plugins in relation to the Bootstrap Plugin: + +1. **Don't modify bootstrap directly** - Instead, create custom plugins to extend functionality +2. **Understand provider contribution** - Know how each provider contributes to the agent's context +3. **Learn the core actions** - Become familiar with the actions that all agents can perform +4. **Leverage event handlers** - Use the event system for reactive behavior +5. **Extend, don't replace** - Build on top of bootstrap functionality rather than replacing it + +--- + +## Developing a Plugin + +When developing a new plugin, focus on these key aspects: + +1. **Service Implementation**: Create a solid service class following the pattern above +2. **Proper Error Handling**: Handle API failures gracefully +3. **Type Definitions**: Define clear interfaces and types +4. **Documentation**: Include detailed setup instructions +5. **Tests**: Add test cases for your functionality + +### Testing Your Plugin + +During development, you can test your plugin locally: + +```bash +# Start with your plugin +npx @elizaos/cli start --plugin=./path/to/plugin + +# Or with a specific character +npx @elizaos/cli start --character=./characters/test.character.json --plugin=./path/to/plugin +``` + +### Distribution & PR Requirements + +When submitting a plugin to the [elizaOS Registry](https://github.com/elizaos-plugins/registry), include: + +1. **Working Demo**: Screenshots or video of your plugin in action +2. **Test Results**: Evidence of successful integration and error handling +3. **Configuration Example**: Show how to properly configure your plugin +4. **Quality Checklist**: + - [ ] Plugin follows the standard structure + - [ ] Required branding assets are included + - [ ] Documentation is complete + - [ ] GitHub topics properly set + - [ ] Tests are passing + - [ ] Includes error handling + +--- + +## FAQ + +### What exactly is a plugin in ElizaOS? + +A plugin is a modular extension that adds new capabilities to ElizaOS agents, such as API integrations, custom actions, or platform connections. Plugins allow you to expand agent functionality and share reusable components with other developers. + +### When should I create a plugin versus using existing ones? + +Create a plugin when you need custom functionality not available in existing plugins, want to integrate with external services, or plan to share reusable agent capabilities with the community. + +### How do I manage plugin dependencies? + +Plugin dependencies are managed through your project's `package.json`. You can add plugins directly using npm or the ElizaOS CLI, and they will be automatically loaded when your project starts. + +### Can I use a plugin in development before publishing? + +Yes, you can use the `--plugin` flag with the `start` command to include local plugins during development: + +```bash +npx @elizaos/cli start --plugin=./path/to/plugin +``` + +### What's the difference between Actions and Services? + +Actions handle specific agent responses or behaviors, while Services provide platform integrations (like Discord or Twitter) or ongoing background functionality that multiple actions might use. + +### How do I handle rate limits with external APIs? + +Implement proper backoff strategies in your service implementation and consider using a queue system for message handling to respect platform rate limits. + +## Additional Resources + +- [ElizaOS Registry](https://github.com/elizaos-plugins/registry) +- [Example Plugins](https://github.com/elizaos-plugins) +- [Discord Community](https://discord.gg/elizaos) +```` + +## File: packages/docs/docs/core/project.md +````markdown +# 📝 ElizaOS Projects + +Projects are the main organizational structure in ElizaOS, containing all the necessary components to create and deploy AI agents. A project can include one or more agents, each with their own character definition, plugins, and configurations. + +## Project Structure + +A typical ElizaOS project structure: + +``` +my-eliza-project/ +├── src/ +│ └── index.ts # Main entry point +├── knowledge/ # Knowledge base files +├── package.json # Dependencies and scripts +└── tsconfig.json # TypeScript configuration +``` + +## Creating a New Project + +You can create a new ElizaOS project using: + +```bash +# Using npm +npm create eliza@beta + +# Or using npx +npx @elizaos/cli@beta create +``` + +The CLI will guide you through the setup process, including: + +- Project name +- Database selection (pglite, postgres, etc.) +- Initial configuration + +## Project Configuration + +The main project file (`src/index.ts`) exports a default project object: + +```typescript +import type { Character, IAgentRuntime, Project, ProjectAgent } from '@elizaos/core'; +import customPlugin from './plugin'; + +// Define the character +export const character: Character = { + name: 'Agent Name', + plugins: ['@elizaos/plugin-discord', '@elizaos/plugin-direct'], + // Other character properties +}; + +// Create a ProjectAgent that includes the character +export const projectAgent: ProjectAgent = { + character, + init: async (runtime: IAgentRuntime) => { + // Initialize agent-specific functionality + console.log('Initializing agent:', character.name); + }, + plugins: [customPlugin], + tests: [], // Optional tests for your agent +}; + +// Export the full project with all agents +const project: Project = { + agents: [projectAgent], +}; + +export default project; +``` + +## Character Configuration + +Each agent in your project requires a character definition that controls its personality, knowledge, and behavior. + +### Required Character Fields + +```typescript +{ + name: "agent_name", // Character's display name + plugins: ["@elizaos/plugin-discord"], // Example plugins + settings: { + // Configuration settings + secrets: {}, // API keys and sensitive data + voice: {}, // Voice configuration + }, + bio: [], // Character background as a string or array of statements + style: { + // Interaction style guide + all: [], // General style rules + chat: [], // Chat-specific style + post: [] // Post-specific style + } +} +``` + +### Plugins + +Plugins provide your agent with capabilities and integrations: + +- `@elizaos/plugin-discord`: Discord integration +- `@elizaos/plugin-telegram`: Telegram integration +- `@elizaos/plugin-twitter`: Twitter/X integration +- `@elizaos/plugin-slack`: Slack integration +- `@elizaos/plugin-direct`: Direct chat interface +- `@elizaos/plugin-simsai`: SimsAI platform integration + +View all available plugins: https://github.com/elizaos-plugins/registry + +### Settings Configuration + +The `settings` object supports various configurations: + +```typescript +{ + "settings": { + "ragKnowledge": false, // Enable RAG knowledge mode + "voice": { + "model": "string", // Voice synthesis model + "url": "string" // Optional voice API URL + }, + "secrets": { + // API keys (use env vars in production) + "API_KEY": "string" + }, + } +} +``` + +### Bio & Style + +Define your agent's personality and communication style: + +```typescript +{ + "bio": ["Expert in blockchain development", "Specializes in DeFi protocols"], + "style": { + "all": [ + // Applied to all interactions + "Keep responses clear", + "Maintain professional tone" + ], + "chat": [ + // Chat-specific style + "Engage with curiosity", + "Provide explanations" + ], + "post": [ + // Social post style + "Keep posts informative", + "Focus on key points" ] + } +} +``` + +**Style Tips** + +- Be specific about tone and mannerisms +- Include platform-specific guidance +- Define clear boundaries and limitations + +### Optional Character Fields + +```typescript +{ + "username": "handle", // Character's username/handle + "system": "System prompt text", // Custom system prompt + "lore": [], // Additional background/history + "knowledge": [ + // Knowledge base entries + "Direct string knowledge", + { "path": "file/path.md", "shared": false }, + { "directory": "knowledge/path", "shared": false } + ], + "messageExamples": [], // Example conversations + "postExamples": [], // Example social posts + "topics": [], // Areas of expertise + "adjectives": [] // Character traits +} +``` + +## Knowledge Management + +ElizaOS supports two knowledge modes: + +### Classic Mode (Default) + +- Direct string knowledge added to character's context +- No chunking or semantic search +- Enabled by default (`settings.ragKnowledge: false`) +- Only processes string knowledge entries +- Simpler but less sophisticated + +### RAG Mode + +- Advanced knowledge processing with semantic search +- Chunks content and uses embeddings +- Must be explicitly enabled (`settings.ragKnowledge: true`) +- Supports three knowledge types: + 1. Direct string knowledge + 2. Single file references: `{ "path": "path/to/file.md", "shared": false }` + 3. Directory references: `{ "directory": "knowledge/dir", "shared": false }` +- Supported file types: .md, .txt, .pdf +- Optional `shared` flag for knowledge reuse across characters + +### Knowledge Path Configuration + +- Knowledge files are relative to the project's `knowledge` directory +- Paths should not contain `../` (sanitized for security) +- Both shared and private knowledge supported +- Files automatically reloaded if content changes + +## Example Project + +Here's a complete example of a project configuration: + +```typescript +import type { Character, IAgentRuntime, Project, ProjectAgent } from '@elizaos/core'; + +export const character: Character = { + name: 'Tech Helper', + plugins: ['@elizaos/plugin-discord', '@elizaos/plugin-direct'], + settings: { + ragKnowledge: true, + voice: { + model: 'en_US-male-medium', + }, + discord: { + shouldRespondOnlyToMentions: false, + allowedChannelIds: ['123456789012345678'], + }, + }, + bio: ['Friendly technical assistant', 'Specializes in explaining complex topics simply'], + lore: ['Pioneer in open-source AI development', 'Advocate for AI accessibility'], + messageExamples: [ + [ + { + name: 'user1', + content: { text: 'Can you explain how AI models work?' }, + }, + { + name: 'TechAI', + content: { + text: 'Think of AI models like pattern recognition systems.', + }, + }, + ], + ], + topics: ['artificial intelligence', 'machine learning', 'technology education'], + knowledge: [ + { + directory: 'tech_guides', + shared: true, + }, + ], + style: { + all: ['Clear', 'Patient', 'Educational'], + chat: ['Interactive', 'Supportive'], + post: ['Concise', 'Informative'], + }, +}; + +export const projectAgent: ProjectAgent = { + character, + init: async (runtime: IAgentRuntime) => { + console.log('Initializing Tech Helper agent'); + }, + plugins: [], // Project-specific plugins +}; + +const project: Project = { + agents: [projectAgent], +}; + +export default project; +``` + +## Character File Export + +While projects are the primary structure in ElizaOS, you can still export standalone character files for compatibility with other systems or sharing character definitions: + +```typescript +import fs from 'fs'; +import { character } from './src/index'; + +// Export character to JSON file +fs.writeFileSync('character.json', JSON.stringify(character, null, 2)); +``` + +## Managing Multiple Agents + +A project can contain multiple agents, each with its own character and plugins: + +```typescript +const project: Project = { + agents: [ + { + character: technicalSupportCharacter, + init: async (runtime) => { + /* init code */ + }, + plugins: [customSupportPlugin], + }, + { + character: communityManagerCharacter, + init: async (runtime) => { + /* init code */ + }, + plugins: [communityPlugin], + }, + ], +}; +``` + +Each agent operates independently but can share the same database and resources. + +## Running Your Project + +After configuring your project, you can run it using: + +```bash +npx @elizaos/cli start +``` + +This will start your agents according to your project configuration. +```` + +## File: packages/docs/docs/core/providers.md +````markdown +# 🔌 Providers + +[Providers](/packages/core/src/providers.ts) are the sources of information for the agent. They provide data or state while acting as the agent's "senses", injecting real-time information into the agent's context. They serve as the eyes, ears, and other sensory inputs that allow the agent to perceive and interact with its environment, like a bridge between the agent and various external systems such as market data, wallet information, sentiment analysis, and temporal context. Anything that the agent knows is either coming from like the built-in context or from a provider. For more info, see the [providers API page](/api/interfaces/provider). + +Here's an example of how providers work within ElizaOS: + +- A news provider could fetch and format news. +- A computer terminal provider in a game could feed the agent information when the player is near a terminal. +- A wallet provider can provide the agent with the current assets in a wallet. +- A time provider injects the current date and time into the context. + +--- + +## Overview + +A provider's primary purpose is to supply dynamic contextual information that integrates with the agent's runtime. They format information for conversation templates and maintain consistent data access. For example: + +- **Function:** Providers run during or before an action is executed. +- **Purpose:** They allow for fetching information from other APIs or services to provide different context or ways for an action to be performed. +- **Example:** Before a "Mars rover action" is executed, a provider could fetch information from another API. This fetched information can then be used to enrich the context of the Mars rover action. + +The provider interface is defined in [types.ts](/packages/core/src/types.ts): + +```typescript +interface Provider { + /** Provider name */ + name: string; + + /** Description of the provider */ + description?: string; + + /** Whether the provider is dynamic */ + dynamic?: boolean; + + /** Position of the provider in the provider list, positive or negative */ + position?: number; + + /** + * Whether the provider is private + * + * Private providers are not displayed in the regular provider list, they have to be called explicitly + */ + private?: boolean; + + /** Data retrieval function */ + get: (runtime: IAgentRuntime, message: Memory, state: State) => Promise; +} +``` + +The `get` function takes: + +- `runtime`: The agent instance calling the provider +- `message`: The last message received +- `state`: Current conversation state + +It returns a `ProviderResult` object that contains: + +```typescript +interface ProviderResult { + values?: { + [key: string]: any; + }; + data?: { + [key: string]: any; + }; + text?: string; +} +``` + +- `values`: Key-value pairs to be merged into the agent's state values +- `data`: Additional structured data that can be used by the agent but not directly included in the context +- `text`: String that gets injected into the agent's context + +--- + +## Provider Types and Properties + +Providers come with several properties that control how and when they are used: + +### Dynamic Providers + +Dynamic providers are not automatically included in the context. They must be explicitly requested either in the filter list or include list when composing state. + +```typescript +const dynamicProvider: Provider = { + name: 'dynamicExample', + description: 'A dynamic provider example', + dynamic: true, + get: async (runtime, message, state) => { + // ...implementation + return { + text: 'Dynamic information fetched on demand', + values: { + /* key-value pairs */ + }, + }; + }, +}; +``` + +### Private Providers + +Private providers are not included in the regular provider list and must be explicitly included in the include list when composing state. + +```typescript +const privateProvider: Provider = { + name: 'privateExample', + description: 'A private provider example', + private: true, + get: async (runtime, message, state) => { + // ...implementation + return { + text: 'Private information only available when explicitly requested', + values: { + /* key-value pairs */ + }, + }; + }, +}; +``` + +### Provider Positioning + +The `position` property determines the order in which providers are processed. Lower numbers are processed first. + +```typescript +const earlyProvider: Provider = { + name: 'earlyExample', + description: 'Runs early in the provider chain', + position: -100, + get: async (runtime, message, state) => { + // ...implementation + return { + text: 'Early information', + values: { + /* key-value pairs */ + }, + }; + }, +}; + +const lateProvider: Provider = { + name: 'lateExample', + description: 'Runs late in the provider chain', + position: 100, + get: async (runtime, message, state) => { + // ...implementation + return { + text: 'Late information that might depend on earlier providers', + values: { + /* key-value pairs */ + }, + }; + }, +}; +``` + +--- + +## State Composition with Providers + +The runtime composes state by gathering data from enabled providers. When calling `composeState`, you can control which providers are used: + +```typescript +// Get state with all non-private, non-dynamic providers +const state = await runtime.composeState(message); + +// Get state with specific providers only +const filteredState = await runtime.composeState( + message, + ['timeProvider', 'factsProvider'], // Only include these providers + null +); + +// Include private or dynamic providers +const enhancedState = await runtime.composeState( + message, + null, + ['privateExample', 'dynamicExample'] // Include these private/dynamic providers +); +``` + +The system caches provider results to optimize performance. When a provider is called multiple times with the same message, the cached result is used unless you explicitly request a new evaluation. + +--- + +## Examples + +ElizaOS providers typically fall into these categories, with examples from the ecosystem: + +### System & Integration + +- **Time Provider**: Injects current date/time for temporal awareness +- **Giphy Provider**: Provides GIF responses using Giphy API +- **GitBook Provider**: Supplies documentation context from GitBook +- **Topics Provider**: Caches and serves Allora Network topic information + +### Blockchain & DeFi + +- **Wallet Provider**: Portfolio data from Zerion, balances and prices +- **DePIN Provider**: Network metrics via DePINScan API +- **Chain Providers**: Data from Abstract, Fuel, ICP, EVM networks +- **Market Provider**: Token data from DexScreener, Birdeye APIs + +### Knowledge & Data + +- **DKG Provider**: OriginTrail decentralized knowledge integration +- **News Provider**: Current events via NewsAPI +- **Trust Provider**: Calculates and injects trust scores + +Visit the [ElizaOS Plugin Registry](https://github.com/elizaos-plugins/registry) for a complete list of available plugins and providers. + +### Time Provider Example + +```typescript +const timeProvider: Provider = { + name: 'time', + description: 'Provides the current date and time', + position: -10, // Run early to ensure time is available for other providers + get: async (_runtime: IAgentRuntime, _message: Memory) => { + const currentDate = new Date(); + const options = { + timeZone: 'UTC', + dateStyle: 'full' as const, + timeStyle: 'long' as const, + }; + const humanReadable = new Intl.DateTimeFormat('en-US', options).format(currentDate); + + return { + text: `The current date and time is ${humanReadable}. Please use this as your reference for any time-based operations or responses.`, + values: { + currentDate: currentDate.toISOString(), + humanReadableDate: humanReadable, + }, + }; + }, +}; +``` + +### Dynamic Provider Example + +```typescript +const weatherProvider: Provider = { + name: 'weather', + description: 'Provides weather information for a location', + dynamic: true, // Only used when explicitly requested + get: async (runtime: IAgentRuntime, message: Memory, state: State) => { + // Extract location from state if available + const location = state?.values?.location || 'San Francisco'; + + try { + // Fetch weather data from an API + const weatherData = await fetchWeatherData(location); + + return { + text: `The current weather in ${location} is ${weatherData.description} with a temperature of ${weatherData.temperature}°C.`, + values: { + weather: { + location, + temperature: weatherData.temperature, + description: weatherData.description, + humidity: weatherData.humidity, + }, + }, + data: { + // Additional detailed data that doesn't go into the context + weatherDetails: weatherData, + }, + }; + } catch (error) { + // Handle errors gracefully + return { + text: `I couldn't retrieve weather information for ${location} at this time.`, + values: { + weather: { error: true }, + }, + }; + } + }, +}; +``` + +--- + +## Best Practices + +### 1. Optimize for Efficiency + +- Return both structured data (`values`) and formatted text (`text`) +- Use caching for expensive operations +- Include a clear provider name and description + +```typescript +const efficientProvider: Provider = { + name: 'efficientExample', + description: 'Efficiently provides cached data', + get: async (runtime, message) => { + // Check for cached data + const cacheKey = `data:${message.roomId}`; + const cachedData = await runtime.getCache(cacheKey); + + if (cachedData) { + return cachedData; + } + + // Fetch fresh data if not cached + const result = { + text: 'Freshly generated information', + values: { + /* key-value pairs */ + }, + data: { + /* structured data */ + }, + }; + + // Cache the result with appropriate TTL + await runtime.setCache(cacheKey, result, { expires: 30 * 60 * 1000 }); // 30 minutes + + return result; + }, +}; +``` + +### 2. Handle Errors Gracefully + +Always handle errors without throwing exceptions that would interrupt the agent's processing: + +```typescript +try { + // Risky operation +} catch (error) { + return { + text: "I couldn't retrieve that information right now.", + values: { error: true }, + }; +} +``` + +### 3. Use Position for Optimal Order + +Position providers according to their dependencies: + +- Negative positions: Fundamental information providers (time, location) +- Zero (default): Standard information providers +- Positive positions: Providers that depend on other information + +### 4. Structure Return Values Consistently + +Maintain a consistent structure in your provider's return values to make data easier to use across the system. + +--- + +## FAQ + +### What's the difference between values, data, and text? + +- `values`: These are merged into the agent state and can be accessed by other providers +- `data`: Structured data stored in state.data.providers but not directly exposed to the agent +- `text`: Formatted text that's directly injected into the agent's context + +### When should I use a dynamic provider? + +Use dynamic providers when the information is expensive to compute, only relevant in specific situations, or requires explicit triggering rather than being included in every context. + +### How do I explicitly include a private provider? + +Private providers must be included in the `includeList` parameter when calling `composeState`: + +```typescript +const state = await runtime.composeState(message, null, ['privateProviderName']); +``` + +### Can providers access service functionality? + +Yes, providers can use services through the runtime. For example, a wallet provider might use a blockchain service to fetch data: + +```typescript +const walletProvider: Provider = { + name: 'wallet', + get: async (runtime, message) => { + const solanaService = runtime.getService('solana'); + if (!solanaService) { + return { text: '' }; + } + + const walletData = await solanaService.getCachedData(); + // Process and return wallet data + }, +}; +``` + +### How should providers handle failures? + +Providers should handle failures gracefully and return valid ProviderResult objects with appropriate error information. Never throw errors that would break the agent's context composition. + +### Can providers maintain state between calls? + +While providers can maintain internal state (e.g., through closures), it's better to use the runtime's cache system for persistence: + +```typescript +// Store data +await runtime.setCache('myProvider:someKey', dataToStore); + +// Retrieve data later +const storedData = await runtime.getCache('myProvider:someKey'); +``` + +--- + +## Further Reading + +- [Provider Implementation](/packages/core/src/providers.ts) +- [Types Reference](/packages/core/src/types.ts) +- [Runtime Integration](/packages/core/src/runtime.ts) +```` + +## File: packages/docs/docs/core/rooms.md +````markdown +--- +sidebar_position: 8 +--- + +# Rooms + +Rooms in ElizaOS represent individual interaction spaces within a world. A room can be a conversation, a channel, a thread, or any other defined space where entities can exchange messages and interact. Rooms are typically contained within a world, though they can also exist independently. + +## Room Structure + +A room in ElizaOS has the following properties: + +```typescript +type Room = { + id: UUID; + name?: string; + agentId?: UUID; + source: string; + type: ChannelType; + channelId?: string; + serverId?: string; + worldId?: UUID; + metadata?: Record; +}; +``` + +| Property | Description | +| ----------- | ---------------------------------------------------------------- | +| `id` | Unique identifier for the room | +| `name` | Optional display name for the room | +| `agentId` | Optional ID of the agent associated with this room | +| `source` | The platform or origin of the room (e.g., 'discord', 'telegram') | +| `type` | Type of room (DM, GROUP, THREAD, etc.) | +| `channelId` | External system channel identifier | +| `serverId` | External system server identifier | +| `worldId` | Optional ID of the parent world | +| `metadata` | Additional room configuration data | + +## Room Types + +ElizaOS supports several room types, defined in the `ChannelType` enum: + +| Type | Description | +| ------------- | ----------------------------------------- | +| `SELF` | Messages to self | +| `DM` | Direct messages between two participants | +| `GROUP` | Group messages with multiple participants | +| `VOICE_DM` | Voice direct messages | +| `VOICE_GROUP` | Voice channels with multiple participants | +| `FEED` | Social media feed | +| `THREAD` | Threaded conversation | +| `WORLD` | World channel | +| `FORUM` | Forum discussion | +| `API` | Legacy type - Use DM or GROUP instead | + +## Room Creation and Management + +### Creating a Room + +You can create a new room using the AgentRuntime: + +```typescript +const roomId = await runtime.createRoom({ + name: 'general-chat', + source: 'discord', + type: ChannelType.GROUP, + channelId: 'external-channel-id', + serverId: 'external-server-id', + worldId: parentWorldId, +}); +``` + +### Ensuring a Room Exists + +To create a room if it doesn't already exist: + +```typescript +await runtime.ensureRoomExists({ + id: roomId, + name: 'general-chat', + source: 'discord', + type: ChannelType.GROUP, + channelId: 'external-channel-id', + serverId: 'external-server-id', + worldId: parentWorldId, +}); +``` + +### Retrieving Room Information + +```typescript +// Get a specific room +const room = await runtime.getRoom(roomId); + +// Get all rooms in a world +const worldRooms = await runtime.getRooms(worldId); +``` + +### Updating Room Properties + +```typescript +await runtime.updateRoom({ + id: roomId, + name: 'renamed-channel', + metadata: { + ...room.metadata, + customProperty: 'value', + }, +}); +``` + +### Deleting a Room + +```typescript +await runtime.deleteRoom(roomId); +``` + +## Participants in Rooms + +Rooms can have multiple participants (entities) that can exchange messages. + +### Managing Room Participants + +```typescript +// Add a participant to a room +await runtime.addParticipant(entityId, roomId); + +// Remove a participant from a room +await runtime.removeParticipant(entityId, roomId); + +// Get all participants in a room +const participants = await runtime.getParticipantsForRoom(roomId); + +// Get all rooms where an entity is a participant +const entityRooms = await runtime.getRoomsForParticipant(entityId); +``` + +### Participant States + +Participants can have different states in a room: + +```typescript +// Get a participant's state in a room +const state = await runtime.getParticipantUserState(roomId, entityId); +// Returns: 'FOLLOWED', 'MUTED', or null + +// Set a participant's state in a room +await runtime.setParticipantUserState(roomId, entityId, 'FOLLOWED'); +``` + +The participant states are: + +| State | Description | +| ---------- | ----------------------------------------------------------------------------------------- | +| `FOLLOWED` | The agent actively follows the conversation and responds without being directly mentioned | +| `MUTED` | The agent ignores messages in this room | +| `null` | Default state - the agent responds only when directly mentioned | + +## Following and Unfollowing Rooms + +ElizaOS allows agents to "follow" rooms to actively participate in conversations without being explicitly mentioned. This functionality is managed through the `FOLLOW_ROOM` and `UNFOLLOW_ROOM` actions. + +```typescript +// Follow a room (typically triggered by an action) +await runtime.setParticipantUserState(roomId, runtime.agentId, 'FOLLOWED'); + +// Unfollow a room +await runtime.setParticipantUserState(roomId, runtime.agentId, null); +``` + +## Memory and Messages in Rooms + +Rooms store messages as memories in the database: + +```typescript +// Create a new message in a room +const messageId = await runtime.createMemory( + { + entityId: senderEntityId, + agentId: runtime.agentId, + roomId: roomId, + content: { + text: 'Hello, world!', + source: 'discord', + }, + metadata: { + type: 'message', + }, + }, + 'messages' +); + +// Retrieve recent messages from a room +const messages = await runtime.getMemories({ + roomId: roomId, + count: 10, + unique: true, +}); +``` + +## Events Related to Rooms + +ElizaOS emits events related to room activities: + +| Event | Description | +| ------------------ | -------------------------------------------- | +| `ROOM_JOINED` | Emitted when an entity joins a room | +| `ROOM_LEFT` | Emitted when an entity leaves a room | +| `MESSAGE_RECEIVED` | Emitted when a message is received in a room | +| `MESSAGE_SENT` | Emitted when a message is sent to a room | + +### Handling Room Events + +```typescript +// Register event handlers in your plugin +const myPlugin: Plugin = { + name: 'my-room-plugin', + description: 'Handles room events', + + events: { + [EventTypes.ROOM_JOINED]: [ + async (payload) => { + const { runtime, entityId, roomId } = payload; + console.log(`Entity ${entityId} joined room ${roomId}`); + }, + ], + + [EventTypes.MESSAGE_RECEIVED]: [ + async (payload: MessagePayload) => { + const { runtime, message } = payload; + console.log(`Message received in room ${message.roomId}`); + }, + ], + }, +}; +``` + +## Room Connection with External Systems + +When integrating with external platforms, rooms are typically mapped to channels, conversations, or other interaction spaces: + +```typescript +// Ensure the connection exists for a room from an external system +await runtime.ensureConnection({ + entityId: userEntityId, + roomId: roomId, + userName: 'username', + name: 'display-name', + source: 'discord', + channelId: 'external-channel-id', + serverId: 'external-server-id', + type: ChannelType.GROUP, + worldId: parentWorldId, +}); +``` + +## Best Practices + +1. **Use appropriate room types**: Select the most appropriate room type for each interaction context +2. **Follow relationship order**: Create worlds before creating rooms, as rooms often have a parent world +3. **Use ensureRoomExists**: Use this method to avoid duplicate rooms when syncing with external systems +4. **Clean up rooms**: Delete rooms when they're no longer needed to prevent database bloat +5. **Room metadata**: Use metadata for room-specific configuration that doesn't fit into the standard properties +6. **Follow state management**: Implement clear rules for when agents should follow or unfollow rooms +7. **Handle participants carefully**: Ensure that participant management aligns with external platform behavior +```` + +## File: packages/docs/docs/core/services.md +````markdown +--- +sidebar_position: 3 +--- + +# 🔌 Services + +Services are core components in Eliza that enable AI agents to interact with external platforms and services. Each service provides a specialized interface for communication while maintaining consistent agent behavior across different platforms. + +--- + +## Supported Services + +| Service | Type | Key Features | Use Cases | +| ---------------------------------------------------------------------------------- | ------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | +| [Discord](https://github.com/elizaos-plugins/plugin-discord) | Communication | • Voice channels • Server management • Moderation tools • Channel management | • Community management • Gaming servers • Event coordination | +| [Twitter](https://github.com/elizaos-plugins/plugin-twitter) | Social Media | • Post scheduling • Timeline monitoring • Engagement analytics • Content automation | • Brand management • Content creation • Social engagement | +| [Telegram](https://github.com/elizaos-plugins/plugin-telegram) | Messaging | • Bot API • Group chat • Media handling • Command system | • Customer support • Community engagement • Broadcast messaging | +| [Direct](https://github.com/elizaOS/eliza/tree/develop/packages/plugin-direct/src) | API | • REST endpoints • Web integration • Custom applications • Real-time communication | • Backend integration • Web apps • Custom interfaces | +| [GitHub](https://github.com/elizaos-plugins/plugin-github) | Development | • Repository management • Issue tracking • Pull requests • Code review | • Development workflow • Project management • Team collaboration | +| [Slack](https://github.com/elizaos-plugins/plugin-slack) | Enterprise | • Channel management • Conversation analysis • Workspace tools • Integration hooks | • Team collaboration • Process automation • Internal tools | +| [Lens](https://github.com/elizaos-plugins/plugin-lens) | Web3 | • Decentralized networking • Content publishing • Memory management • Web3 integration | • Web3 social networking • Content distribution • Decentralized apps | +| [Farcaster](https://github.com/elizaos-plugins/plugin-farcaster) | Web3 | • Decentralized social • Content publishing • Community engagement | • Web3 communities • Content creation • Social networking | +| [Auto](https://github.com/elizaos-plugins/plugin-auto) | Automation | • Workload management • Task scheduling • Process automation | • Background jobs • Automated tasks • System maintenance | + +**\*Additional services**: + +- Instagram: Social media content and engagement +- XMTP: Web3 messaging and communications +- Alexa: Voice interface and smart device control +- Home Assistant: Home automation OS +- Devai.me: AI first social service +- Simsai: Jeeter / Social media platform for AI + +--- + +## System Overview + +Services serve as bridges between Eliza agents and various platforms, providing core capabilities: + +1. **Message Processing** + + - Platform-specific message formatting and delivery + - Media handling and attachments via [`Memory`](/api/interfaces/Memory) objects + - Reply threading and context management + - Support for different content types + +2. **State & Memory Management** + + - Each service maintains independent state to prevent cross-platform contamination + - Integrates with runtime memory managers for different types of content: + - Messages processed by one service don't automatically appear in other services' contexts + - [`State`](/api/interfaces/State) persists across agent restarts through the database adapter + +3. **Platform Integration** + - Authentication and API compliance + - Event processing and webhooks + - Rate limiting and cache management + - Platform-specific feature support + +## Service Configuration + +Services are configured through the [`Character`](/api/type-aliases/Character) configuration's `settings` property: + +```typescript +export type Character = { + // ... other properties ... + settings?: { + discord?: { + shouldIgnoreBotMessages?: boolean; + shouldIgnoreDirectMessages?: boolean; + shouldRespondOnlyToMentions?: boolean; + messageSimilarityThreshold?: number; + isPartOfTeam?: boolean; + teamAgentIds?: string[]; + teamLeaderId?: string; + teamMemberInterestKeywords?: string[]; + allowedChannelIds?: string[]; + autoPost?: { + enabled?: boolean; + monitorTime?: number; + inactivityThreshold?: number; + mainChannelId?: string; + announcementChannelIds?: string[]; + minTimeBetweenPosts?: number; + }; + }; + telegram?: { + shouldIgnoreBotMessages?: boolean; + shouldIgnoreDirectMessages?: boolean; + shouldRespondOnlyToMentions?: boolean; + shouldOnlyJoinInAllowedGroups?: boolean; + allowedGroupIds?: string[]; + messageSimilarityThreshold?: number; + // ... other telegram-specific settings + }; + slack?: { + shouldIgnoreBotMessages?: boolean; + shouldIgnoreDirectMessages?: boolean; + }; + // ... other service configs + }; }; ``` -### Basic Conversation Actions +## Service Implementation + +Each service manages its own: + +- Platform-specific message formatting and delivery +- Event processing and webhooks +- Authentication and API integration +- Message queueing and rate limiting +- Media handling and attachments +- State management and persistence + +Example of a basic service implementation: + +```typescript +import { Service, IAgentRuntime } from '@elizaos/core'; + +export class CustomService extends Service { + static serviceType = 'custom'; + capabilityDescription = 'The agent is able to interact with the custom platform'; + + constructor(protected runtime: IAgentRuntime) { + super(); + // Initialize platform connection + // Set up event handlers + // Configure message processing + } + + static async start(runtime: IAgentRuntime): Promise { + const service = new CustomService(runtime); + // Additional initialization if needed + return service; + } + + async stop(): Promise { + // Cleanup resources + // Close connections + } +} +``` + +### Runtime Integration + +Services interact with the agent runtime through the [`IAgentRuntime`](api/interfaces/IAgentRuntime/) interface, which provides: + +- Memory managers for different types of data storage +- Service access for capabilities like transcription or image generation +- State management and composition +- Message processing and action handling + +### Memory System Integration + +Services use the runtime's memory managers to persist conversation data (source: [`memory.ts`](/api/interfaces/Memory)). + +- `messageManager` Chat messages +- `documentsManager` File attachments +- `descriptionManager` Media descriptions + +
+See example +```typescript +// Store a new message +await runtime.messageManager.createMemory({ + id: messageId, + content: { text: message.content }, + userId: userId, + roomId: roomId, + agentId: runtime.agentId +}); + +// Retrieve recent messages +const recentMessages = await runtime.messageManager.getMemories({ +roomId: roomId, +count: 10 +}); + +``` +
+ + +--- + +## FAQ + +### What can services actually do? + +Services handle platform-specific communication (like Discord messages or Twitter posts), manage memories and state, and execute actions like processing media or handling commands. Each service adapts these capabilities to its platform while maintaining consistent agent behavior. + +### Can multiple services be used simultaneously? +Yes, Eliza supports running multiple services concurrently while maintaining consistent agent behavior across platforms. + +### How are service-specific features handled? +Each service implements platform-specific features through its capabilities system, while maintaining a consistent interface for the agent. + +### How do services handle rate limits? +Services implement platform-specific rate limiting with backoff strategies and queue management. + +### How is service state managed? +Services maintain their own connection state while integrating with the agent's runtime database adapter and memory / state management system. + +### How do services handle messages? + +Services translate platform messages into Eliza's internal format, process any attachments (images, audio, etc.), maintain conversation context, and manage response queuing and rate limits. + +### How are messages processed across services? +Each service processes messages independently in its platform-specific format, while maintaining conversation context through the shared memory system. V2 improves upon this architecture. + +### How is state managed between services? +Each service maintains separate state to prevent cross-contamination, but can access shared agent state through the runtime. + + +### How do services integrate with platforms? + +Each service implements platform-specific authentication, API compliance, webhook handling, and follows the platform's rules for rate limiting and content formatting. + +### How do services manage memory? + +Services use Eliza's memory system to track conversations, user relationships, and state, enabling context-aware responses and persistent interactions across sessions. +``` +```` + +## File: packages/docs/docs/core/tasks.md +````markdown +--- +sidebar_position: 9 +--- + +# Tasks + +Tasks in ElizaOS provide a powerful way to manage deferred, scheduled, and interactive operations. The Task system allows agents to queue work for later execution, repeat actions at defined intervals, await user input, and implement complex workflows across multiple interactions. + +## Task Structure + +A task in ElizaOS has the following properties: + +```typescript +interface Task { + id?: UUID; // Unique identifier (auto-generated if not provided) + name: string; // Name of the task (must match a registered task worker) + updatedAt?: number; // Timestamp when the task was last updated + metadata?: { + // Optional additional configuration + updateInterval?: number; // For repeating tasks: milliseconds between executions + options?: { + // For choice tasks: options for user selection + name: string; + description: string; + }[]; + [key: string]: unknown; // Additional custom metadata + }; + description: string; // Human-readable description of the task + roomId?: UUID; // Optional room association (for room-specific tasks) + worldId?: UUID; // Optional world association (for world-specific tasks) + tags: string[]; // Tags for categorizing and filtering tasks +} +``` + +## Task Workers + +Task workers define the actual logic that executes when a task runs. Each task worker is registered with the runtime and is identified by name. + +```typescript +interface TaskWorker { + name: string; // Matches the name in the Task + execute: ( + runtime: IAgentRuntime, + options: { [key: string]: unknown }, // Options passed during execution + task: Task // The task being executed + ) => Promise; + validate?: ( + // Optional validation before execution + runtime: IAgentRuntime, + message: Memory, + state: State + ) => Promise; +} +``` + +## Creating and Managing Tasks + +### Registering a Task Worker + +Before creating tasks, you must register a worker to handle the execution: + +```typescript +runtime.registerTaskWorker({ + name: 'SEND_REMINDER', + validate: async (runtime, message, state) => { + // Optional validation logic + return true; + }, + execute: async (runtime, options, task) => { + // Task execution logic + const { roomId } = task; + const { reminder, userId } = options; + + await runtime.createMemory( + { + entityId: runtime.agentId, + roomId, + content: { + text: `Reminder for <@${userId}>: ${reminder}`, + }, + }, + 'messages' + ); + + // Delete the task after it's completed + await runtime.deleteTask(task.id); + }, +}); +``` + +### Creating a One-time Task + +Create a task that will execute once: + +```typescript +await runtime.createTask({ + name: 'SEND_REMINDER', + description: 'Send a reminder message to the user', + roomId: currentRoomId, + tags: ['reminder', 'one-time'], + metadata: { + userId: message.entityId, + reminder: 'Submit your weekly report', + scheduledFor: Date.now() + 86400000, // 24 hours from now + }, +}); +``` + +### Creating a Recurring Task + +Create a task that repeats at regular intervals: + +```typescript +await runtime.createTask({ + name: 'DAILY_REPORT', + description: 'Generate and post the daily report', + roomId: announcementChannelId, + worldId: serverWorldId, + tags: ['report', 'repeat', 'daily'], + metadata: { + updateInterval: 86400000, // 24 hours in milliseconds + updatedAt: Date.now(), // When the task was last updated/executed + }, +}); +``` + +### Creating a Task Awaiting User Choice + +Create a task that presents options and waits for user input: + +```typescript +await runtime.createTask({ + name: 'CONFIRM_ACTION', + description: 'Confirm the requested action', + roomId: message.roomId, + tags: ['confirmation', 'AWAITING_CHOICE'], + metadata: { + options: [ + { name: 'confirm', description: 'Proceed with the action' }, + { name: 'cancel', description: 'Cancel the action' }, + ], + action: 'DELETE_FILES', + files: ['document1.txt', 'document2.txt'], + }, +}); +``` + +### Managing Tasks + +Retrieve, update, and delete tasks as needed: + +```typescript +// Get tasks by specific criteria +const reminderTasks = await runtime.getTasks({ + roomId: currentRoomId, + tags: ['reminder'], +}); + +// Get tasks by name +const reportTasks = await runtime.getTasksByName('DAILY_REPORT'); + +// Get a specific task +const task = await runtime.getTask(taskId); + +// Update a task +await runtime.updateTask(taskId, { + description: 'Updated description', + metadata: { + ...task.metadata, + priority: 'high', + }, +}); + +// Delete a task +await runtime.deleteTask(taskId); +``` + +## Task Processing + +Tasks are processed based on their configuration: + +### One-time Tasks + +Tasks without an `updateInterval` are executed once when triggered by your code. You are responsible for scheduling their execution by checking for pending tasks in appropriate contexts. + +### Recurring Tasks + +Tasks with an `updateInterval` are automatically considered for re-execution when: + +1. The current time exceeds `updatedAt + updateInterval` +2. Your code explicitly checks for pending recurring tasks + +To process recurring tasks, implement logic like this: + +```typescript +// In an initialization function or periodic check +async function processRecurringTasks() { + const now = Date.now(); + const recurringTasks = await runtime.getTasks({ + tags: ['repeat'], + }); + + for (const task of recurringTasks) { + if (!task.metadata?.updateInterval) continue; + + const lastUpdate = task.metadata.updatedAt || 0; + const interval = task.metadata.updateInterval; + + if (now >= lastUpdate + interval) { + const worker = runtime.getTaskWorker(task.name); + if (worker) { + try { + await worker.execute(runtime, {}, task); + + // Update the task's last update time + await runtime.updateTask(task.id, { + metadata: { + ...task.metadata, + updatedAt: now, + }, + }); + } catch (error) { + logger.error(`Error executing task ${task.name}: ${error}`); + } + } + } + } +} +``` + +### Tasks Awaiting User Input + +Tasks tagged with `AWAITING_CHOICE` are presented to users and wait for their input. These tasks use: + +1. The `choice` provider to display available options to users +2. The `CHOOSE_OPTION` action to process user selections + +## Common Task Patterns + +### Deferred Follow-ups + +Create a task to follow up with a user later: + +```typescript +runtime.registerTaskWorker({ + name: 'FOLLOW_UP', + execute: async (runtime, options, task) => { + const { roomId } = task; + const { userId, topic } = task.metadata; + + await runtime.createMemory( + { + entityId: runtime.agentId, + roomId, + content: { + text: `Hi <@${userId}>, I'm following up about ${topic}. Do you have any updates?`, + }, + }, + 'messages' + ); + + await runtime.deleteTask(task.id); + }, +}); + +// Create a follow-up task for 2 days later +await runtime.createTask({ + name: 'FOLLOW_UP', + description: 'Follow up with user about project status', + roomId: message.roomId, + tags: ['follow-up', 'one-time'], + metadata: { + userId: message.entityId, + topic: 'the project timeline', + scheduledFor: Date.now() + 2 * 86400000, // 2 days + }, +}); +``` + +### Multi-step Workflows + +Implement complex workflows that span multiple interactions: + +```typescript +// First step: Gather requirements +runtime.registerTaskWorker({ + name: 'GATHER_REQUIREMENTS', + execute: async (runtime, options, task) => { + // Ask user for requirements and create a new task for the next step + await runtime.createTask({ + name: 'CONFIRM_REQUIREMENTS', + description: 'Confirm gathered requirements', + roomId: task.roomId, + tags: ['workflow', 'AWAITING_CHOICE'], + metadata: { + previousStep: 'GATHER_REQUIREMENTS', + requirements: options.requirements, + options: [ + { name: 'confirm', description: 'Confirm requirements are correct' }, + { name: 'revise', description: 'Need to revise requirements' }, + ], + }, + }); + + await runtime.deleteTask(task.id); + }, +}); + +// Second step: Confirm requirements +runtime.registerTaskWorker({ + name: 'CONFIRM_REQUIREMENTS', + execute: async (runtime, options, task) => { + if (options.option === 'confirm') { + // Move to the next step + await runtime.createTask({ + name: 'GENERATE_SOLUTION', + description: 'Generate solution based on requirements', + roomId: task.roomId, + tags: ['workflow'], + metadata: { + previousStep: 'CONFIRM_REQUIREMENTS', + requirements: task.metadata.requirements, + }, + }); + } else { + // Go back to requirements gathering + await runtime.createTask({ + name: 'GATHER_REQUIREMENTS', + description: 'Revise requirements', + roomId: task.roomId, + tags: ['workflow'], + metadata: { + previousStep: 'CONFIRM_REQUIREMENTS', + previousRequirements: task.metadata.requirements, + }, + }); + } + + await runtime.deleteTask(task.id); + }, +}); +``` + +### Scheduled Reports + +Create tasks that generate and post reports on a schedule: + +```typescript +runtime.registerTaskWorker({ + name: 'GENERATE_WEEKLY_REPORT', + execute: async (runtime, options, task) => { + const { roomId } = task; + + // Generate report content + const reportData = await generateWeeklyReport(runtime); + + // Post the report + await runtime.createMemory( + { + entityId: runtime.agentId, + roomId, + content: { + text: `# Weekly Report\n\n${reportData}`, + }, + }, + 'messages' + ); + + // The task stays active for next week (updateInterval handles timing) + }, +}); + +// Create a weekly report task +await runtime.createTask({ + name: 'GENERATE_WEEKLY_REPORT', + description: 'Generate and post weekly activity report', + roomId: reportChannelId, + worldId: serverWorldId, + tags: ['report', 'repeat', 'weekly'], + metadata: { + updateInterval: 7 * 86400000, // 7 days + updatedAt: Date.now(), + format: 'markdown', + }, +}); +``` + +## Task Events and Monitoring + +ElizaOS doesn't currently provide built-in events for task lifecycle, so implement your own monitoring if needed: + +```typescript +// Custom monitoring for task execution +async function executeTaskWithMonitoring(runtime, taskWorker, task) { + try { + // Create a start log + await runtime.log({ + body: { taskId: task.id, action: 'start' }, + entityId: runtime.agentId, + roomId: task.roomId, + type: 'TASK_EXECUTION', + }); + + // Execute the task + await taskWorker.execute(runtime, {}, task); + + // Create a completion log + await runtime.log({ + body: { taskId: task.id, action: 'complete', success: true }, + entityId: runtime.agentId, + roomId: task.roomId, + type: 'TASK_EXECUTION', + }); + } catch (error) { + // Create an error log + await runtime.log({ + body: { taskId: task.id, action: 'error', error: error.message }, + entityId: runtime.agentId, + roomId: task.roomId, + type: 'TASK_EXECUTION', + }); + } +} +``` + +## Best Practices + +1. **Use descriptive names and descriptions**: Make tasks easily identifiable with clear names and descriptions + +2. **Clean up completed tasks**: Delete one-time tasks after execution to prevent database bloat + +3. **Add error handling**: Implement robust error handling in task workers to prevent failures from breaking workflows + +4. **Use appropriate tags**: Tag tasks effectively for easy retrieval and categorization + +5. **Validate carefully**: Use the `validate` function to ensure tasks only execute in appropriate contexts + +6. **Keep tasks atomic**: Design tasks to perform specific, well-defined operations rather than complex actions + +7. **Provide clear choices**: When creating choice tasks, make option names and descriptions clear and unambiguous + +8. **Manage task lifecycles**: Have a clear strategy for when tasks are created, updated, and deleted + +9. **Set reasonable intervals**: For recurring tasks, choose appropriate update intervals that balance timeliness and resource usage -You can find these samples in the plugin-bootstrap package: https://github.com/elizaOS/eliza/tree/main/packages/plugin-bootstrap/src/actions +10. **Handle concurrent execution**: Ensure task execution is idempotent to handle potential concurrent executions +```` + +## File: packages/docs/docs/core/worlds.md +````markdown +--- +sidebar_position: 7 +--- + +# Worlds -#### CONTINUE +Worlds in ElizaOS are collections of entities (users, agents) and rooms (conversations, channels) that form a cohesive environment for interactions. Think of a world as a virtual space, like a Discord server, Slack workspace, or 3D MMO environment, where entities can communicate across multiple channels or areas. -For continuing conversations: +## World Structure + +A world in ElizaOS has the following properties: ```typescript -const continueAction: Action = { - name: "CONTINUE", - similes: ["ELABORATE", "GO_ON"], - description: "Continues the conversation when appropriate", +type World = { + id: UUID; + name?: string; + agentId: UUID; + serverId: string; + metadata?: { + ownership?: { + ownerId: string; + }; + roles?: { + [entityId: UUID]: Role; + }; + [key: string]: unknown; + }; +}; +``` + +| Property | Description | +| ---------- | ---------------------------------------------------- | +| `id` | Unique identifier for the world | +| `name` | Optional display name | +| `agentId` | ID of the agent managing this world | +| `serverId` | External system identifier (e.g., Discord server ID) | +| `metadata` | Additional world configuration data | + +The metadata can store custom information, including ownership details and role assignments for entities within the world. - validate: async (runtime: IAgentRuntime, message: Memory) => { - // Check if message warrants continuation - const text = message.content.text.toLowerCase(); - return ( - text.includes("tell me more") || - text.includes("what else") || - text.includes("continue") || - text.endsWith("?") - ); +## World Creation and Management + +### Creating a World + +You can create a new world using the AgentRuntime: + +```typescript +const worldId = await runtime.createWorld({ + name: 'My Project Space', + agentId: runtime.agentId, + serverId: 'external-system-id', + metadata: { + ownership: { + ownerId: ownerEntityId, }, + }, +}); +``` - handler: async (runtime: IAgentRuntime, message: Memory, state?: State) => { - // Get recent conversation context - const recentMessages = await runtime.messageManager.getMemories({ - roomId: message.roomId, - count: 5 - }); +For many integrations, worlds are automatically created during connection setup with external platforms like Discord or Slack. - // Generate contextual response - const response = await runtime.generateResponse( - message, - recentMessages, - state - ); - - // Store response - await runtime.messageManager.createMemory({ - id: generateId(), - content: response, - userId: runtime.agentId, - roomId: message.roomId - }); +### Ensuring a World Exists - return true; - }, +If you're not sure if a world exists, you can use `ensureWorldExists()`: - examples: [ - [ - { - user: "{{user1}}", - content: { text: "Tell me more about that" } - }, - { - user: "{{user2}}", - content: { - text: "I'll continue explaining...", - action: "CONTINUE" - } - } - ] - ] -}; +```typescript +await runtime.ensureWorldExists({ + id: worldId, + name: 'My Project Space', + agentId: runtime.agentId, + serverId: 'external-system-id', +}); ``` -#### IGNORE - -For ending conversations: +### Retrieving World Information ```typescript -const ignoreAction: Action = { - name: "IGNORE", - similes: ["STOP_TALKING", "END_CONVERSATION"], - description: "Stops responding when conversation is complete or irrelevant", +// Get a specific world +const world = await runtime.getWorld(worldId); - validate: async (runtime: IAgentRuntime, message: Memory) => { - const text = message.content.text.toLowerCase(); - return ( - text.includes("goodbye") || - text.includes("bye") || - text.includes("thanks") || - text.length < 2 - ); - }, +// Get all worlds +const allWorlds = await runtime.getAllWorlds(); +``` - handler: async (runtime: IAgentRuntime, message: Memory) => { - // No response needed - return true; - }, +### Updating World Properties - examples: [ - [ - { - user: "{{user1}}", - content: { text: "Thanks, goodbye!" } - }, - { - user: "{{user2}}", - content: { - text: "", - action: "IGNORE" - } - } - ] - ] -}; +```typescript +await runtime.updateWorld({ + id: worldId, + name: 'Updated Name', + metadata: { + ...world.metadata, + customProperty: 'value', + }, +}); ``` ---- +## World Roles System -## FAQ +Worlds support a role-based permission system with the following roles: -### What are Actions in Eliza? -Actions are core building blocks that define how agents interact with messages and perform tasks beyond simple text responses. +| Role | Description | +| ------- | ----------------------------------------------------- | +| `OWNER` | Full control over the world, can assign any roles | +| `ADMIN` | Administrative capabilities, can manage most settings | +| `NONE` | Standard participant with no special permissions | -### How do Actions work? -Actions consist of a name, description, validation function, and handler function that determine when and how an agent can perform a specific task. +### Managing Roles -### What can Actions do? -Actions enable agents to interact with external systems, modify behavior, process complex workflows, and extend capabilities beyond conversational responses. +Roles are stored in the world's metadata and can be updated: -### What are some example Actions? -Common actions include CONTINUE (extend dialogue), IGNORE (end conversation), GENERATE_IMAGE (create images), TRANSFER (move tokens), and READ_CONTRACT (retrieve blockchain data). +```typescript +// Get existing world +const world = await runtime.getWorld(worldId); -### How do I create a custom Action? -Define an action with a unique name, validation function to check eligibility, handler function to implement the logic, and provide usage examples. +// Ensure roles object exists +if (!world.metadata) world.metadata = {}; +if (!world.metadata.roles) world.metadata.roles = {}; -### What makes a good Action? -A good action has a clear, single purpose, robust input validation, comprehensive error handling, and provides meaningful interactions. +// Assign a role to an entity +world.metadata.roles[entityId] = Role.ADMIN; -### Can Actions be chained together? -Yes, actions can be composed and chained to create complex workflows and multi-step interactions. +// Save the world +await runtime.updateWorld(world); +``` -### How are Actions different from tools? -Actions are more comprehensive, ensuring the entire process happens, while tools are typically more focused on specific, discrete operations. +For programmatic role management, you can use role-related utilities: -### Where are Actions defined? -Actions can be defined in character files, plugins, or directly in agent configurations. +```typescript +import { canModifyRole, findWorldForOwner } from '@elizaos/core'; -## Further Reading +// Check if user can modify roles +if (canModifyRole(userRole, targetRole, newRole)) { + // Allow role change +} -- [characterfile](./characterfile.md) -- [providers](./providers.md) -```` +// Find world where user is owner +const userWorld = await findWorldForOwner(runtime, entityId); +``` -## File: packages/docs/docs/core/agents.md -````markdown -# 🤖 Agent Runtime +## World Settings -The `AgentRuntime` is the core runtime environment for Eliza agents. It handles message processing, state management, plugin integration, and interaction with external services. You can think of it as the brains that provide the high-level orchestration layer for Eliza agents. +Worlds support configurable settings that can be stored and retrieved: -![](/img/eliza-architecture.jpg) +```typescript +// Get settings for a world +const worldSettings = await getWorldSettings(runtime, serverId); + +// Update world settings +worldSettings.MY_SETTING = { + name: 'My Setting', + description: 'Description for users', + value: 'setting-value', + required: false, +}; -The runtime follows this general flow: -1. Agent loads character config, plugins, and services - - Processes knowledge sources (e.g., documents, directories) -2. Receives a message, composes the state -3. Processes actions and then evaluates - - Retrieves relevant knowledge fragments using RAG -4. Generates and executes responses, then evaluates -5. Updates memory and state +// Save settings +await updateWorldSettings(runtime, serverId, worldSettings); +``` +## World Events ---- +ElizaOS emits events related to world activities: -## Overview +| Event | Description | +| ----------------- | ---------------------------------------------- | +| `WORLD_JOINED` | Emitted when an agent joins a world | +| `WORLD_CONNECTED` | Emitted when a world is successfully connected | +| `WORLD_LEFT` | Emitted when an agent leaves a world | -The [AgentRuntime](/api/classes/AgentRuntime) class is the primary implementation of the [IAgentRuntime](/api/interfaces/IAgentRuntime) interface, which manages the agent's core functions, including: +### Handling World Events +```typescript +// Register event handlers in your plugin +const myPlugin: Plugin = { + name: 'my-world-plugin', + description: 'Handles world events', + + events: { + [EventTypes.WORLD_JOINED]: [ + async (payload: WorldPayload) => { + const { world, runtime } = payload; + console.log(`Joined world: ${world.name}`); + }, + ], -| Component | Description | API Reference | Related Files | -|---------|-------------|---------------|---------------| -| **Clients** | Supports multiple communication platforms for seamless interaction. | [Clients API](/api/interfaces/IAgentRuntime/#clients) | [`clients.ts`](https://github.com/elizaos-plugins/client-discord/blob/main/__tests__/discord-client.test.ts), [`Discord`](https://github.com/elizaos-plugins/client-discord), [`Telegram`](https://github.com/elizaos-plugins/client-telegram), [`Twitter`](https://github.com/elizaos-plugins/client-twitter), [`Farcaster`](https://github.com/elizaos-plugins/client-farcaster), [`Lens`](https://github.com/elizaos-plugins/client-lens), [`Slack`](https://github.com/elizaos-plugins/client-slack), [`Auto`](https://github.com/elizaos-plugins/client-auto), [`GitHub`](https://github.com/elizaos-plugins/client-github) | -| **State** | Maintains context for coherent cross-platform interactions, updates dynamically. Also tracks goals, knowledge, and recent interactions | [State API](/api/interfaces/State) | [`state.ts`](https://github.com/elizaos/runtime/state.ts) | -| **Plugins** | Dynamic extensions of agent functionalities using custom actions, evaluators, providers, and adapters | [Plugins API](/api/type-aliases/Plugin/) | [`plugins.ts`](https://github.com/elizaos/runtime/plugins.ts), [actions](../actions), [evaluators](../evaluators), [providers](../providers) | -| **Services** | Connects with external services for `IMAGE_DESCRIPTION`, `TRANSCRIPTION`, `TEXT_GENERATION`, `SPEECH_GENERATION`, `VIDEO`, `PDF`, `BROWSER`, `WEB_SEARCH`, `EMAIL_AUTOMATION`, and more | [Services API](/api/interfaces/IAgentRuntime/#services) | [`services.ts`](https://github.com/elizaos/runtime/services.ts) | -| **Memory Systems** | Creates, retrieves, and embeds memories and manages conversation history. | [Memory API](/api/interfaces/IMemoryManager) | [`memory.ts`](https://github.com/elizaos/runtime/memory.ts) | -| **Database Adapters** | Persistent storage and retrieval for memories and knowledge | [databaseAdapter](api/interfaces/IAgentRuntime/#databaseAdapter) | [`MongoDB`](https://github.com/elizaos-plugins/adapter-mongodb), [`PostgreSQL`](https://github.com/elizaos-plugins/adapter-postgres), [`SQLite`](https://github.com/elizaos-plugins/adapter-sqlite), [`Supabase`](https://github.com/elizaos-plugins/adapter-supabase), [`PGLite`](https://github.com/elizaos-plugins/adapter-pglite), [`Qdrant`](https://github.com/elizaos-plugins/adapter-qdrant), [`SQL.js`](https://github.com/elizaos-plugins/adapter-sqljs) | -| **Cache Management** | Provides flexible storage and retrieval via various caching methods. | [Cache API](/api/interfaces/ICacheManager) | [`cache.ts`](https://github.com/elizaos/runtime/cache.ts) | + [EventTypes.WORLD_LEFT]: [ + async (payload: WorldPayload) => { + const { world, runtime } = payload; + console.log(`Left world: ${world.name}`); + }, + ], + }, +}; +``` +## Relationship with Rooms +A world contains multiple rooms that entities can interact in. Each room points back to its parent world via the `worldId` property. -
-Advanced: IAgentRuntime Interface ```typescript -interface IAgentRuntime { - // Core identification - agentId: UUID; - token: string; - serverUrl: string; - - // Configuration - character: Character; // Personality and behavior settings - modelProvider: ModelProviderName; // AI model to use - imageModelProvider: ModelProviderName; - imageVisionModelProvider: ModelProviderName; - - // Components - plugins: Plugin[]; // Additional capabilities - clients: Record; // Platform connections - providers: Provider[]; // Real-time data sources - actions: Action[]; // Available behaviors - evaluators: Evaluator[]; // Analysis & learning - - // Memory Management - messageManager: IMemoryManager; // Conversation history - descriptionManager: IMemoryManager; - documentsManager: IMemoryManager; // Large documents - knowledgeManager: IMemoryManager; // Search & retrieval - ragKnowledgeManager: IRAGKnowledgeManager; // RAG integration - loreManager: IMemoryManager; // Character background - - // Storage & Caching - databaseAdapter: IDatabaseAdapter; // Data persistence - cacheManager: ICacheManager; // Performance optimization - - // Services - services: Map; // External integrations - - // Networking - fetch: (url: string, options: any) => Promise; -} +// Get all rooms in a world +const worldRooms = await runtime.getRooms(worldId); ``` -Source: [/api/interfaces/IAgentRuntime/](/api/interfaces/IAgentRuntime/) -
+See the [Rooms](./rooms.md) documentation for more details on managing rooms within worlds. + +## Best Practices +1. **Always check permissions**: Before performing administrative actions, verify the user has appropriate roles +2. **Handle world metadata carefully**: The metadata object can contain critical configuration, so modify it with care +3. **World-room syncing**: When syncing with external platforms, keep world and room structures in alignment +4. **Event-driven architecture**: Use events to respond to world changes rather than polling for updates +5. **Default settings**: Provide sensible defaults for world settings to make configuration easier +```` +## File: packages/docs/docs/intro.md +````markdown +--- +sidebar_position: 1 --- -### **Key Methods** -- **`initialize()`**: Sets up the agent's runtime environment, including services, plugins, and knowledge processing. -- **`processActions()`**: Executes actions based on message content and state. -- **`evaluate()`**: Assesses messages and state using registered evaluators. -- **`composeState()`**: Constructs the agent's state object for response generation. -- **`updateRecentMessageState()`**: Updates the state with recent messages and attachments. -- **`registerService()`**: Adds a service to the runtime. -- **`registerMemoryManager()`**: Registers a memory manager for specific types of memories. -- **`ensureRoomExists()` / `ensureUserExists()`**: Ensures the existence of rooms and users in the database. +# Introduction to Eliza -WIP +![](/img/eliza_banner.jpg) +_As seen powering [@DegenSpartanAI](https://x.com/degenspartanai) and [@aixvc_agent](https://x.com/aixvc_agent)_ +## What is Eliza? ---- +Eliza is a powerful multi-agent simulation framework designed to create, deploy, and manage autonomous AI agents. Built with TypeScript, it provides a flexible and extensible platform for developing intelligent agents that can interact across multiple platforms while maintaining consistent personalities and knowledge. -## Service System +- [Technical Report (Whitepaper)](https://arxiv.org/pdf/2501.06781) +- [Examples (Awesome Eliza)](https://github.com/elizaos/awesome-eliza) -Services provide specialized functionality with standardized interfaces that can be accessed cross-platform: +## Key Features -
-See Example +- **Platform Integration**: Clients for Discord, X (Twitter), Telegram, and many others +- **Flexible Model Support**: Deepseek, Ollama, Grok, OpenAI, Anthropic, Gemini, LLama, etc. +- **Character System**: Create diverse agents using [character files](https://github.com/elizaOS/characterfile) +- **Multi-Agent Architecture**: Manage multiple unique AI personalities simultaneously +- **Memory Management**: Easily ingest and interact with documents using RAG +- **Media Processing**: PDF, URLs, Audio transcription, Video processing, Image analysis, Conversation summarization +- **Technical Foundation**: + - 100% TypeScript implementation + - Modular architecture + - Highly extensible action and plugin system + - Custom client support + - Comprehensive API -```typescript -// Speech Generation -const speechService = runtime.getService( - ServiceType.SPEECH_GENERATION -); -const audioStream = await speechService.generate(runtime, text); +## Use Cases -// PDF Processing -const pdfService = runtime.getService(ServiceType.PDF); -const textContent = await pdfService.convertPdfToText(pdfBuffer); -``` -
+Eliza can be used to create: +- **AI Assistants**: Customer support agents, Community moderators, Personal assistants +- **Social Media Personas**: Automated content creators, Brand representatives, Influencers +- **Knowledge Workers**: Research assistants, Content analysts, Document processors +- **Interactive Characters**: Role-playing characters, Educational tutors, Entertainment bots --- -## State Management +## Getting Started -The runtime maintains comprehensive state through the State interface: +For a more detailed guide, check out our [Quickstart Guide](./quickstart.md) to begin your journey with Eliza. -```typescript -interface State { - // Core identifiers - userId?: UUID; - agentId?: UUID; - roomId: UUID; +### Prerequisites + +- [Node.js 23+](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) +- Git for version control +- For Windows Users: [WSL 2](https://learn.microsoft.com/en-us/windows/wsl/install-manual) is required - // Character information - bio: string; - lore: string; - messageDirections: string; - postDirections: string; +### Multiple Paths to Start - // Conversation context - actors: string; - actorsData?: Actor[]; - recentMessages: string; - recentMessagesData: Memory[]; +Eliza offers different paths depending on your goals: - // Goals and knowledge - goals?: string; - goalsData?: Goal[]; - knowledge?: string; - knowledgeData?: KnowledgeItem[]; - ragKnowledgeData?: RAGKnowledgeItem[]; -} +#### 1. Simple Start - Run Quickly -// State management methods -async function manageState() { - // Initial state composition - const state = await runtime.composeState(message, { - additionalContext: "custom context" - }); +```bash +# Install globally (optional but recommended) +npm install -g @elizaos/cli - // Update state with new messages - const updatedState = await runtime.updateRecentMessageState(state); -} +# Start with default settings +npx elizaos start ``` ---- - -## Plugin System +Visit https://localhost:3000 to interact with your agent through a web interface. -Plugins extend agent functionality through a modular interface. The runtime supports various types of plugins including clients, services, adapters, and more: +#### 2. Create Your Own Project -```typescript -interface Plugin { - name: string; - description: string; - actions?: Action[]; // Custom behaviors - providers?: Provider[]; // Data providers - evaluators?: Evaluator[]; // Response assessment - services?: Service[]; // Background processes - clients?: Client[]; // Platform integrations - adapters?: Adapter[]; // Database/cache adapters -} -``` +```bash +# Create a new project through interactive setup +npx elizaos create -Plugins can be configured through [characterfile](./characterfile) settings: +# Navigate to your project directory +cd my-project-name -```json -{ - "name": "MyAgent", - "plugins": [ - "@elizaos/plugin-solana", - "@elizaos/plugin-twitter" - ] -} +# Start your project +npx elizaos start ``` -For detailed information about plugin development and usage, see the [ElizaOS Registry](https://github.com/elizaos-plugins). +Add plugins to your project: ---- +```bash +# List available plugins +npx elizaos project list-plugins -## Running Multiple Agents +# Add a plugin +npx elizaos project add-plugin @elizaos/plugin-discord +``` -To run multiple agents: +#### 3. Develop a Custom Plugin ```bash -bun start:client +# Create a plugin project +npx elizaos create --type plugin + +# Follow the interactive prompts ``` -Then read the [Documentation](https://elizaos.github.io/eliza/) to learn how to customize your Eliza. +Develop and test your plugin: ---- +```bash +# Test your plugin +npx elizaos start -### Automatically Start Eliza +# Publish your plugin when ready +npx elizaos plugin publish +``` -For a more automated setup: +#### 4. Contribute to ElizaOS Core ```bash +# Clone the repository git clone git@github.com:elizaOS/eliza.git cd eliza -# Run the start script with verbose logging -./scripts/start.sh -v -``` +# Install dependencies and build +bun install +bun run build -The start script handles all dependencies, environment setup, and character management automatically. +# Start ElizaOS +bun start +``` ---- +Visit https://localhost:3000 to interact with your agent through a web interface. -### Modify Character +For detailed instructions on each path, including configuration options and extended capabilities, see our [Quickstart Guide](./quickstart.md). -1. Open `packages/core/src/defaultCharacter.ts` to modify the default character. Uncomment and edit. +--- -```bash -git clone git@github.com:elizaOS/eliza.git -cd eliza -``` +## Community and Support -:::tip -If you're planning on doing development, we suggest using the code on the develop branch: -```bash -git checkout develop -``` +Eliza is backed by an active community of developers and users: -From the main repo you can also download [sample character files](https://github.com/elizaos/characters) this way: -```bash -git submodule update --init -``` -::: +- [**Open Source**](https://github.com/elizaos/eliza): Contribute to the project on GitHub +- [**Examples**](https://github.com/elizaos/characters): Ready-to-use character templates and implementations +- [**Support**](https://discord.gg/elizaos): Active community for troubleshooting and discussion -Install the dependencies +Join us in building the future of autonomous AI agents with Eliza! -```bash -pnpm install -``` +## Next Steps -> **Note:** you may need to use --no-frozen-lockfile if it gives a message about the frozen lock file being out of date. +- [Quickstart Guide](./quickstart.md) +```` -Compile the typescript: +## File: packages/docs/docs/quickstart.md +````markdown +--- +sidebar_position: 2 +--- -```bash -pnpm build -``` +# Quickstart Guide --- -## Start the Agent +## 1. Simple Start - Get Running Quickly -[Character files](./core/characterfile.md) are where you can configure your agent's personality, lore, and capabilities via plugins. Inform eliza which character you want to run: +The fastest way to get started with ElizaOS is using the CLI: ```bash -pnpm start --character="characters/deep-thought.character.json" +# Install globally (optional but recommended) +npm install -g @elizaos/cli + +# Or use directly with npx +npx elizaos start ``` -You can load multiple characters with a comma-separated list: +This will: -```bash -pnpm start --characters="characters/deep-thought.character.json,characters/sbf.character.json" -``` +1. Start ElizaOS with default settings +2. Load the default character +3. Make the agent accessible via terminal and REST API -By default the agent will be accessible via the terminal and REST API. +### Chat with your agent: -#### Chat Client +Visit https://localhost:3000 to interact with your agent through a web interface. -If you're using the main [eliza repo](https://github.com/elizaos/eliza) and want to use the chat client, open a new terminal window and run the client's http server: +## 2. Creating a Project + +If you want to create a custom ElizaOS project with your own characters and configurations: ```bash -pnpm start:client +# Create a new project with the interactive wizard +npx elizaos create + +# Or specify project type directly +npx elizaos create --type project ``` -Once the client is running, you'll see a message like this: +Follow the interactive prompts to configure your project. Once created: -``` -➜ Local: http://localhost:5173/ +```bash +# Navigate to your project directory +cd my-project-name + +# Start your project +npx elizaos start ``` -Simply click the link or open your browser to `http://localhost:5173/`. You'll see the chat interface connect to the system, and you can begin interacting with your character. +### Add plugins to your project: ---- +```bash +# List available plugins +npx elizaos project list-plugins -## Additional Configuration +# Add a plugin +npx elizaos project add-plugin @elizaos/plugin-discord +``` -You can load plugins or additional client support with your character file to unlock more capabilities for your agent. +## 3. Creating a Plugin -### Add Plugins and Clients +Want to extend ElizaOS with custom functionality? -Here's how to import and register plugins in your character file: +```bash +# Create a new plugin project +npx elizaos create --type plugin -```typescript -{ - "name": "Eliza", - "clients": ["telegram"], - // ... other config options - "plugins": ["@elizaos/plugin-image"], -} +# Follow the interactive prompts ``` -There are two ways to get a list of available plugins: +Develop your plugin following the structure in your generated project: -1. Web Interface +```bash +# Test your plugin +npx elizaos start -Go https://elizaos.github.io/registry/ or the [Showcase](/showcase) and search for plugins +# Publish your plugin when ready +npx elizaos plugin publish +``` -2. CLI Interface +### Publishing options: ```bash -$ npx elizaos plugins list -``` +# Test publish without making changes +npx elizaos plugin publish --test -Here's a sample list of plugins you can check out! +# Publish to npm +npx elizaos plugin publish --npm -| plugin name | Description | -| ----------- | ----------- | -| [`@elizaos/plugin-llama`](https://github.com/elizaos-plugins/plugin-llama) | Run LLM models on your local machine -| [`@elizaos/client-twitter`](https://github.com/elizaos-plugins/client-twitter) | Twitter bot integration -| [`@elizaos/client-discord`](https://github.com/elizaos-plugins/client-discord) | Discord bot integration -| [`@elizaos/client-telegram`](https://github.com/elizaos-plugins/client-telegram) | Telegram integration -| [`@elizaos/plugin-image`](https://github.com/elizaos-plugins/plugin-image) | Image processing and analysis -| [`@elizaos/plugin-video`](https://github.com/elizaos-plugins/plugin-video) | Video processing capabilities -| [`@elizaos/plugin-browser`](https://github.com/elizaos-plugins/plugin-browser) | Web scraping capabilities -| [`@elizaos/plugin-pdf`](https://github.com/elizaos-plugins/plugin-pdf) | PDF processing +# Specify platform compatibility +npx elizaos plugin publish --platform node +``` +## 4. Contributing to ElizaOS +If you want to add features or fix bugs in the ElizaOS core: -### Configure Environment +```bash +# Clone the repository +git clone git@github.com:elizaOS/eliza.git +cd eliza -There are two ways to configure elizaOS +# Switch to development branch +git checkout develop -### Option 1: Default .env file +# Install dependencies +bun install -Copying the `.example.env` file and editing is the simpler option especially if you plan to just host one agent: +# Build the project +bun build -```bash -cp .env.example .env -nano .env +# Start ElizaOS +bun start ``` -### Option 2: Secrets in the character file +Visit https://localhost:3000 to interact with your agent through a web interface. -This option allows you finer grain control over which character uses what resources and is required if you want multiple agents but using different keys. For example: +### Automated setup: +```bash +git clone git@github.com:elizaOS/eliza.git +cd eliza -```typescript -{ - "name": "eliza", - // ... other config options - "settings": { - "secrets": { - "DISCORD_APPLICATION_ID": "1234", - "DISCORD_API_TOKEN": "xxxx", - "OPENAI_API_KEY": "sk-proj-xxxxxxxxx-..." - } - } +# Run the start script with verbose logging +./scripts/start.sh -v ``` -Watch the commas to make sure it's valid json! Here's a few more config tips: +--- + +## Troubleshooting
-Discord Bot Setup +Common Issues -1. Create a new application at [Discord Developer Portal](https://discord.com/developers/applications) -2. Create a bot and get your token -3. Add bot to your server using OAuth2 URL generator -4. Set `DISCORD_API_TOKEN` and `DISCORD_APPLICATION_ID` in your `.env` -
+### Node Version -
-Twitter Integration +- Use Node.js 23.3.0+ (`node -v` to check) +- Try using NVM: `nvm use 23` -Add to your `.env`: +### Installation Problems ```bash -TWITTER_USERNAME= # Account username -TWITTER_PASSWORD= # Account password -TWITTER_EMAIL= # Account email -TWITTER_2FA_SECRET= # In order to avoid X preventing the login, it is better to activate 2fa in the target account, copy the 2fa secret and paste it here +# Clean and reinstall +bun clean +bun install --no-frozen-lockfile +bun build ``` -**Important:** Log in to the [Twitter Developer Portal](https://developer.twitter.com) and enable the "Automated" label for your account to avoid being flagged as inauthentic. -
- -
-Telegram Bot - -1. Create a bot -2. Add your bot token to `.env`: +### Plugin Issues ```bash -TELEGRAM_BOT_TOKEN=your_token_here +# Rebuild problematic packages +bun rebuild better-sqlite3 ``` -
- - - -### GPU Acceleration - -If you have a Nvidia GPU you can enable CUDA support. First ensure CUDA Toolkit, cuDNN, and cuBLAS are first installed, then: `npx --no node-llama-cpp source download --gpu cuda` +### Docker Issues +```bash +# Clean up Docker environment +docker rmi -f $(docker images -aq) +docker builder prune -a -f +``` + --- -## FAQ - -### What's the difference between eliza and eliza-starter? -Eliza-starter is a lightweight version for simpler setups, while the main eliza repository includes all advanced features and a web client. - -### How do I fix build/installation issues? -Use Node v23.3.0, run `pnpm clean`, then `pnpm install --no-frozen-lockfile`, followed by `pnpm build`. If issues persist, checkout the latest stable tag. - -### What are the minimum system requirements? -8GB RAM recommended for build process. For deployment, a t2.large instance on AWS with 20GB storage running Ubuntu is the minimum tested configuration. - -### How do I fix "Exit Status 1" errors? -If you see `triggerUncaughtException` errors, try: -1. Add dependencies to workspace root -2. Add dependencies to specific packages -3. Clean and rebuild - ## Next Steps Once you have your agent running, explore: @@ -2325,6 +7304,9 @@ Join the [Discord community](https://discord.gg/elizaOS) for support and to shar ## File: .env.example ```` +# Logging Configuration (supported: fatal, error, warn, info, debug, trace | default: info) +LOG_LEVEL= + # OpenAI Configuration OPENAI_API_KEY= @@ -2392,6 +7374,7 @@ PROJECT_MANAGER_DISCORD_API_TOKEN= DEV_REL_DISCORD_APPLICATION_ID= DEV_REL_DISCORD_API_TOKEN= +DEVREL_IMPORT_KNOWLEDGE=true INVESTMENT_MANAGER_DISCORD_APPLICATION_ID= INVESTMENT_MANAGER_DISCORD_API_TOKEN= @@ -2410,17 +7393,19 @@ COINGECKO_API_KEY= { "name": "eliza", "scripts": { - "preinstall": "npx only-allow bun", + "preinstall": "only-allow bun", "start": "cd ./packages/the-org && bun run start", - "start:debug": "LOG_LEVEL=debug elizaos start", + "start:debug": "cross-env NODE_NO_WARNINGS=1 LOG_LEVEL=debug elizaos start", "start:app": "turbo run start --filter=./packages/app", "dev": "turbo run dev --filter=./packages/the-org", - "build:core": "turbo run build --filter=@elizaos/core --no-cache", - "build": "bun run build:core && turbo run build --filter=@elizaos/plugin-* --filter=@elizaos/client --no-cache && turbo run build --filter=!@elizaos/core --filter=!@elizaos/plugin-* --filter=!@elizaos/docs --no-cache", - "clean": "rm -rf dist .turbo node_modules .turbo-tsconfig.json tsconfig.tsbuildinfo bun.lock* && turbo run clean --filter=./packages/*", - "lint": "turbo run lint --filter=./packages/*", + "build:docs": "turbo run build --filter=@elizaos/docs", + "build": "turbo run build --filter=@elizaos/client && turbo run build --filter=!@elizaos/docs", + "clean": "turbo run clean --filter=./packages/* && rm -rf dist .turbo node_modules .turbo-tsconfig.json tsconfig.tsbuildinfo bun.lock*", + "lint": "turbo run lint --filter=./packages/* && prettier --write . && prettier --check .", + "pre-commit": "bun run scripts/pre-commit-lint.js", "release": "bun run build && bun lint && lerna publish --no-private --force-publish && bun lint", "release:alpha": "lerna publish prerelease --preid alpha --dist-tag alpha --no-private --force-publish --loglevel verbose", + "release:beta": "lerna publish prerelease --preid beta --dist-tag beta --no-private --force-publish --loglevel verbose", "migrate": "turbo run migrate --filter=./packages/plugin-sql --force", "migrate:generate": "turbo run migrate:generate --filter=./packages/plugin-sql", "docker:build": "bash ./scripts/docker.sh build", @@ -2429,26 +7414,28 @@ COINGECKO_API_KEY= "docker:start": "bash ./scripts/docker.sh start", "docker": "bun docker:build && bun docker:run && bun docker:bash", "test": "turbo run test --concurrency 20 --filter=!./packages/plugin-starter --filter=!./packages/project-starter --filter=!./packages/the-org --filter=!./packages/docs --filter=!./packages/plugin-video-understanding", - "test:app": "turbo run test --concurrency 20 --filter=./packages/app" + "test:app": "turbo run test --concurrency 20 --filter=./packages/app", + "prepare": "husky" }, "devDependencies": { "@types/bun": "latest", "@types/node": "^22.13.10", + "@types/uuid": "^9.0.8", "@vitest/eslint-plugin": "1.0.1", - "bun": "1.2.2", + "bun": "1.2.5", "concurrently": "9.1.0", "cross-env": "7.0.3", - "husky": "9.1.7", + "husky": "^9.1.7", "lerna": "8.1.4", + "lint-staged": "^15.5.0", "only-allow": "^1.2.1", "sharp": "0.33.5", + "tsup": "8.4.0", "turbo": "^2.4.4", "typedoc": "0.27.9", "typescript": "5.8.2", "vite": "5.4.12", - "vitest": "3.0.5", - "@types/uuid": "^9.0.8", - "tsup": "8.4.0" + "vitest": "3.0.5" }, "bun": { "overrides": { @@ -2472,7 +7459,7 @@ COINGECKO_API_KEY= "vittest": "^1.0.2", "zod": "3.24.1" }, - "packageManager": "bun@1.2.2", + "packageManager": "bun@1.2.5", "workspaces": [ "packages/*" ], @@ -2495,27 +7482,16 @@ COINGECKO_API_KEY= "form-data": "4.0.2" }, "trustedDependencies": [ - "@elizaos/plugin-browser", - "@elizaos/plugin-pdf", - "@elizaos/plugin-storage-s3", - "@elizaos/plugin-video-understanding", "@swc/core", - "better-sqlite3", "bigint-buffer", "bufferutil", "bun", "canvas", - "core-js", - "core-js-pure", - "cpu-features", - "es5-ext", "esbuild", + "husky", "node-llama-cpp", - "nx", - "onnxruntime-node", "protobufjs", "sharp", - "ssh2", "utf-8-validate" ] } @@ -2531,7 +7507,7 @@ COINGECKO_API_KEY=
-📑 [Technical Report](https://arxiv.org/pdf/2501.06781) | 📖 [Documentation](https://elizaos.github.io/eliza/) | 🎯 [Examples](https://github.com/thejoven/awesome-eliza) +📑 [Technical Report](https://arxiv.org/pdf/2501.06781) | 📖 [Documentation](https://elizaos.github.io/eliza/) | 🎯 [Examples](https://github.com/thejoven/awesome-eliza)
@@ -2542,7 +7518,7 @@ COINGECKO_API_KEY= ## 🚩 Overview
- Eliza Diagram + Eliza Diagram
## ✨ Features @@ -2573,7 +7549,7 @@ COINGECKO_API_KEY= - [Python 2.7+](https://www.python.org/downloads/) - [Node.js 23+](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) -- [bun](https://bun.sh) +- [bun](https://bun.sh/docs/installation) > **Note for Windows Users:** [WSL 2](https://learn.microsoft.com/en-us/windows/wsl/install-manual) is required. @@ -2623,15 +7599,12 @@ bun start # npm will work too ### Interact via Browser -Once the agent is running, you should see the message to run "bun start:client" at the end. - -Open another terminal, move to the same directory, run the command below, then follow the URL to chat with your agent. - -```bash -bun start:client -``` +Once the agent is running, you can visit http://localhost:3000 to interact with your agent through a web interface. The interface provides: -Then read the [Documentation](https://elizaos.github.io/eliza/) to learn how to customize your Eliza. +- Real-time chat with your agent +- Character configuration options +- Plugin management +- Memory and conversation history --- @@ -2639,56 +7612,10 @@ Then read the [Documentation](https://elizaos.github.io/eliza/) to learn how to The start script provides an automated way to set up and run Eliza: -```bash -sh scripts/start.sh -``` - -For detailed instructions on using the start script, including character management and troubleshooting, see our [Start Script Guide](./docs/docs/guides/start-script.md). - -> **Note**: The start script handles all dependencies, environment setup, and character management automatically. - ---- - -### Modify Character - -1. Open `packages/core/src/defaultCharacter.ts` to modify the default character. Uncomment and edit. - -2. To load custom characters: - - Use `bun start --characters="path/to/your/character.json"` - - Multiple character files can be loaded simultaneously -3. Connect with X (Twitter) - - change `"clients": []` to `"clients": ["twitter"]` in the character file to connect with X - ---- - -#### Additional Requirements - -You may need to install Sharp. If you see an error when starting up, try installing it with the following command: - -``` -bun install --include=optional sharp -``` ---- - -### Deploy Eliza in one click - -Use [Fleek](https://fleek.xyz/eliza/) to deploy Eliza in one click. This opens Eliza to non-developers and provides the following options to build your agent: -1. Start with a template -2. Build characterfile from scratch -3. Upload pre-made characterfile - -Click [here](https://fleek.xyz/eliza/) to get started! - ---- - -### Community & contact - -- [GitHub Issues](https://github.com/elizaos/eliza/issues). Best for: bugs you encounter using Eliza, and feature proposals. -- [Discord](https://discord.gg/ai16z). Best for: sharing your applications and hanging out with the community. - ## Citation We now have a [paper](https://arxiv.org/pdf/2501.06781) you can cite for the Eliza OS: + ```bibtex @article{walters2025eliza, title={Eliza: A Web3 friendly AI Agent Operating System}, @@ -2704,10 +7631,21 @@ We now have a [paper](https://arxiv.org/pdf/2501.06781) you can cite for the Eli Eliza project contributors - ## Star History [![Star History Chart](https://api.star-history.com/svg?repos=elizaos/eliza&type=Date)](https://star-history.com/#elizaos/eliza&Date) + +## Git Hooks + +This project uses git hooks to ensure code quality: + +- **pre-commit**: Automatically formats staged files using Prettier before committing + +To run the pre-commit hook manually: + +```bash +bun run pre-commit +``` ```` diff --git a/packages/docs/versioned_docs/version-0.25.9/intro.md b/packages/docs/versioned_docs/version-0.25.9/intro.md index 3e6d0b3e04d..e393456d65a 100644 --- a/packages/docs/versioned_docs/version-0.25.9/intro.md +++ b/packages/docs/versioned_docs/version-0.25.9/intro.md @@ -40,7 +40,7 @@ Eliza can be used to create: ## Architecture -![](/img/eliza-architecture.jpg) +![](/img/architecture.png) Source: https://x.com/0xCygaar/status/1874575841763770492 The characterfile contains everything about the agent's personality, backstory, knowledge, and topics to talk about, as well as which clients / models / and plugins to load. The database is where an agent stores relevant info for generating responses, including previous tweets, interactions, and embeddings. Without a db, agent's wouldn't be able to give good responses. diff --git a/packages/plugin-discord/__tests__/messageManager.test.ts b/packages/plugin-discord/__tests__/messageManager.test.ts index 3eed6169e47..4dd994ccf8e 100644 --- a/packages/plugin-discord/__tests__/messageManager.test.ts +++ b/packages/plugin-discord/__tests__/messageManager.test.ts @@ -22,6 +22,7 @@ describe('Discord MessageManager', () => { allowedChannelIds: ['mock-channel-id'], shouldIgnoreBotMessages: true, shouldIgnoreDirectMessages: true, + shouldRespondOnlyToMentions: true, }, }, }, @@ -72,7 +73,9 @@ describe('Discord MessageManager', () => { }, id: 'mock-message-id', createdTimestamp: Date.now(), - mentions: { has: vi.fn().mockReturnValue(false) }, + mentions: { + users: { has: vi.fn().mockReturnValue(true) }, + }, reference: null, attachments: new Collection(), }; @@ -95,6 +98,12 @@ describe('Discord MessageManager', () => { expect(mockRuntime.ensureConnection).not.toHaveBeenCalled(); }); + it('should ignore not mentioned messages', async () => { + mockMessage.mentions.users.has = vi.fn().mockReturnValue(false); + await messageManager.handleMessage(mockMessage); + expect(mockRuntime.ensureConnection).not.toHaveBeenCalled(); + }); + it('should process audio attachments', async () => { vi.spyOn(messageManager, 'processMessage').mockResolvedValue({ processedContent: '', diff --git a/packages/plugin-discord/src/messages.ts b/packages/plugin-discord/src/messages.ts index e96769f0332..646a8e240f2 100644 --- a/packages/plugin-discord/src/messages.ts +++ b/packages/plugin-discord/src/messages.ts @@ -73,6 +73,13 @@ export class MessageManager { return; } + if ( + this.runtime.character.settings?.discord?.shouldRespondOnlyToMentions && + !message.mentions.users?.has(this.client.user?.id) + ) { + return; + } + const entityId = createUniqueUuid(this.runtime, message.author.id); const userName = message.author.bot diff --git a/packages/plugin-local-ai/src/environment.ts b/packages/plugin-local-ai/src/environment.ts index d32f2adf891..ddbd34ffc1e 100644 --- a/packages/plugin-local-ai/src/environment.ts +++ b/packages/plugin-local-ai/src/environment.ts @@ -50,11 +50,12 @@ function validateModelConfig(config: Record): void { USE_OLLAMA_TEXT_MODELS: config.USE_OLLAMA_TEXT_MODELS, }); - // Ensure USE_LOCAL_AI is always true - if (!config.USE_LOCAL_AI) { - config.USE_LOCAL_AI = true; - logger.info("Setting USE_LOCAL_AI to true as it's required"); - } + // NOPE + // // Ensure USE_LOCAL_AI is always true + // if (!config.USE_LOCAL_AI) { + // config.USE_LOCAL_AI = true; + // logger.info("Setting USE_LOCAL_AI to true as it's required"); + // } // Only validate that StudioLM and Ollama are not both enabled if (config.USE_STUDIOLM_TEXT_MODELS && config.USE_OLLAMA_TEXT_MODELS) { @@ -83,7 +84,7 @@ export async function validateConfig(config: Record): Promise) { + try { + // const validatedConfig = await configSchema.parseAsync(config); + + // // Set all environment variables at once + // for (const [key, value] of Object.entries(validatedConfig)) { + // if (value) process.env[key] = value; + // } + + // If API key is not set, we'll show a warning but continue + if (!process.env.REDPILL_API_KEY) { + logger.warn( + 'REDPILL_API_KEY is not set in environment - RedPill functionality will be limited' + ); + // Return early without throwing an error + return; + } + + // Verify API key only if we have one + try { + const baseURL = process.env.REDPILL_BASE_URL ?? 'https://api.red-pill.ai/v1'; + const response = await fetch(`${baseURL}/models`, { + headers: { Authorization: `Bearer ${process.env.REDPILL_API_KEY}` }, + }); + + if (!response.ok) { + logger.warn(`RedPill API key validation failed: ${response.statusText}`); + logger.warn('RedPill functionality will be limited until a valid API key is provided'); + // Continue execution instead of throwing + } else { + logger.success('RedPill API key validated successfully'); + } + } catch (fetchError) { + logger.warn(`Error validating RedPill API key: ${fetchError}`); + logger.warn('RedPill functionality will be limited until a valid API key is provided'); + // Continue execution instead of throwing + } + } catch (error) { + // Convert to warning instead of error + logger.warn( + `RedPill plugin configuration issue: ${error.errors + .map((e) => e.message) + .join(', ')} - You need to configure the REDPILL_API_KEY in your environment variables` + ); + } + }, + models: { + [ModelType.TEXT_EMBEDDING]: async ( + _runtime, + params: TextEmbeddingParams | string | null + ): Promise => { + // Handle null input (initialization case) + if (params === null) { + logger.debug('Creating test embedding for initialization'); + // Return a consistent vector for null input + const testVector = Array(1536).fill(0); + testVector[0] = 0.1; // Make it non-zero + return testVector; + } + + // Get the text from whatever format was provided + let text: string; + if (typeof params === 'string') { + text = params; // Direct string input + } else if (typeof params === 'object' && params.text) { + text = params.text; // Object with text property + } else { + logger.warn('Invalid input format for embedding'); + // Return a fallback for invalid input + const fallbackVector = Array(1536).fill(0); + fallbackVector[0] = 0.2; // Different value for tracking + return fallbackVector; + } + + // Skip API call for empty text + if (!text.trim()) { + logger.warn('Empty text for embedding'); + const emptyVector = Array(1536).fill(0); + emptyVector[0] = 0.3; // Different value for tracking + return emptyVector; + } + + try { + const baseURL = process.env.REDPILL_BASE_URL ?? 'https://api.red-pill.ai/v1'; + + // Call the RedPill API + const response = await fetch(`${baseURL}/embeddings`, { + method: 'POST', + headers: { + Authorization: `Bearer ${process.env.REDPILL_API_KEY}`, + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + model: 'text-embedding-3-small', + input: text, + }), + }); + + if (!response.ok) { + logger.error(`RedPill API error: ${response.status} - ${response.statusText}`); + const errorVector = Array(1536).fill(0); + errorVector[0] = 0.4; // Different value for tracking + return errorVector; + } + + const data = (await response.json()) as { + data: [{ embedding: number[] }]; + }; + + if (!data?.data?.[0]?.embedding) { + logger.error('API returned invalid structure'); + const errorVector = Array(1536).fill(0); + errorVector[0] = 0.5; // Different value for tracking + return errorVector; + } + + const embedding = data.data[0].embedding; + logger.log(`Got valid embedding with length ${embedding.length}`); + return embedding; + } catch (error) { + logger.error('Error generating embedding:', error); + const errorVector = Array(1536).fill(0); + errorVector[0] = 0.6; // Different value for tracking + return errorVector; + } + }, + [ModelType.TEXT_TOKENIZER_ENCODE]: async ( + _runtime, + { prompt, modelType = ModelType.TEXT_LARGE }: TokenizeTextParams + ) => { + return await tokenizeText(modelType ?? ModelType.TEXT_LARGE, prompt); + }, + [ModelType.TEXT_TOKENIZER_DECODE]: async ( + _runtime, + { tokens, modelType = ModelType.TEXT_LARGE }: DetokenizeTextParams + ) => { + return await detokenizeText(modelType ?? ModelType.TEXT_LARGE, tokens); + }, + [ModelType.TEXT_SMALL]: async (runtime, { prompt, stopSequences = [] }: GenerateTextParams) => { + const temperature = 0.7; + const frequency_penalty = 0.7; + const presence_penalty = 0.7; + const max_response_length = 8192; + + const baseURL = runtime.getSetting('REDPILL_BASE_URL') ?? 'https://api.red-pill.ai/v1'; + + const redpill = createOpenAI({ + apiKey: runtime.getSetting('REDPILL_API_KEY'), + baseURL, + }); + + const model = + runtime.getSetting('REDPILL_SMALL_MODEL') ?? + runtime.getSetting('SMALL_MODEL') ?? + 'gpt-4o-mini'; + + logger.log('generating text'); + logger.log(prompt); + + const { text: redpillResponse } = await generateText({ + model: redpill.languageModel(model), + prompt: prompt, + system: runtime.character.system ?? undefined, + temperature: temperature, + maxTokens: max_response_length, + frequencyPenalty: frequency_penalty, + presencePenalty: presence_penalty, + stopSequences: stopSequences, + }); + + return redpillResponse; + }, + [ModelType.TEXT_LARGE]: async ( + runtime, + { + prompt, + stopSequences = [], + maxTokens = 8192, + temperature = 0.7, + frequencyPenalty = 0.7, + presencePenalty = 0.7, + }: GenerateTextParams + ) => { + const baseURL = runtime.getSetting('REDPILL_BASE_URL') ?? 'https://api.red-pill.ai/v1'; + + const redpill = createOpenAI({ + apiKey: runtime.getSetting('REDPILL_API_KEY'), + baseURL, + }); + + const model = + runtime.getSetting('REDPILL_LARGE_MODEL') ?? runtime.getSetting('LARGE_MODEL') ?? 'gpt-4o'; + + const { text: redpillResponse } = await generateText({ + model: redpill.languageModel(model), + prompt: prompt, + system: runtime.character.system ?? undefined, + temperature: temperature, + maxTokens: maxTokens, + frequencyPenalty: frequencyPenalty, + presencePenalty: presencePenalty, + stopSequences: stopSequences, + }); + + return redpillResponse; + }, + [ModelType.IMAGE_DESCRIPTION]: async (runtime, params: ImageDescriptionParams | string) => { + // Handle string case (direct URL) + let imageUrl: string; + let prompt: string | undefined; + + if (typeof params === 'string') { + imageUrl = params; + prompt = undefined; + } else { + // Object parameter case + imageUrl = params.imageUrl; + prompt = params.prompt; + } + + try { + const baseURL = process.env.REDPILL_BASE_URL ?? 'https://api.red-pill.ai/v1'; + const apiKey = process.env.REDPILL_API_KEY; + + if (!apiKey) { + logger.error('RedPill API key not set'); + return { + title: 'Failed to analyze image', + description: 'API key not configured', + }; + } + + // Call the GPT-4 Vision API + const response = await fetch(`${baseURL}/chat/completions`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${apiKey}`, + }, + body: JSON.stringify({ + model: 'gpt-4-vision-preview', + messages: [ + { + role: 'user', + content: [ + { + type: 'text', + text: + prompt || + 'Please analyze this image and provide a title and detailed description.', + }, + { + type: 'image_url', + image_url: { url: imageUrl }, + }, + ], + }, + ], + max_tokens: 300, + }), + }); + + if (!response.ok) { + throw new Error(`RedPill API error: ${response.status}`); + } + + const result: any = await response.json(); + const content = result.choices?.[0]?.message?.content; + + if (!content) { + return { + title: 'Failed to analyze image', + description: 'No response from API', + }; + } + + // Extract title and description + const titleMatch = content.match(/title[:\s]+(.+?)(?:\n|$)/i); + const title = titleMatch?.[1] || 'Image Analysis'; + + // Rest of content is the description + const description = content.replace(/title[:\s]+(.+?)(?:\n|$)/i, '').trim(); + + return { title, description }; + } catch (error) { + logger.error('Error analyzing image:', error); + return { + title: 'Failed to analyze image', + description: `Error: ${error instanceof Error ? error.message : String(error)}`, + }; + } + }, + [ModelType.OBJECT_SMALL]: async (runtime, params: ObjectGenerationParams) => { + const baseURL = runtime.getSetting('REDPILL_BASE_URL') ?? 'https://api.red-pill.ai/v1'; + const redpill = createOpenAI({ + apiKey: runtime.getSetting('REDPILL_API_KEY'), + baseURL, + }); + const model = + runtime.getSetting('REDPILL_SMALL_MODEL') ?? + runtime.getSetting('SMALL_MODEL') ?? + 'gpt-4o-mini'; + + try { + if (params.schema) { + // Skip zod validation and just use the generateObject without schema + logger.info('Using OBJECT_SMALL without schema validation'); + const { object } = await generateObject({ + model: redpill.languageModel(model), + output: 'no-schema', + prompt: params.prompt, + temperature: params.temperature, + }); + return object; + } + + const { object } = await generateObject({ + model: redpill.languageModel(model), + output: 'no-schema', + prompt: params.prompt, + temperature: params.temperature, + }); + return object; + } catch (error) { + logger.error('Error generating object:', error); + throw error; + } + }, + [ModelType.OBJECT_LARGE]: async (runtime, params: ObjectGenerationParams) => { + const baseURL = runtime.getSetting('REDPILL_BASE_URL') ?? 'https://api.red-pill.ai/v1'; + const redpill = createOpenAI({ + apiKey: runtime.getSetting('REDPILL_API_KEY'), + baseURL, + }); + const model = + runtime.getSetting('REDPILL_LARGE_MODEL') ?? runtime.getSetting('LARGE_MODEL') ?? 'gpt-4o'; + + try { + if (params.schema) { + // Skip zod validation and just use the generateObject without schema + logger.info('Using OBJECT_LARGE without schema validation'); + const { object } = await generateObject({ + model: redpill.languageModel(model), + output: 'no-schema', + prompt: params.prompt, + temperature: params.temperature, + }); + return object; + } + + const { object } = await generateObject({ + model: redpill.languageModel(model), + output: 'no-schema', + prompt: params.prompt, + temperature: params.temperature, + }); + return object; + } catch (error) { + logger.error('Error generating object:', error); + throw error; + } + }, + }, + tests: [ + { + name: 'redpill_plugin_tests', + tests: [ + { + name: 'redpill_test_url_and_api_key_validation', + fn: async (runtime) => { + const baseURL = runtime.getSetting('REDPILL_BASE_URL') ?? 'https://api.red-pill.ai/v1'; + const response = await fetch(`${baseURL}/models`, { + headers: { + Authorization: `Bearer ${runtime.getSetting('REDPILL_API_KEY')}`, + }, + }); + const data = await response.json(); + logger.log('Models Available:', (data as any)?.data.length); + if (!response.ok) { + throw new Error(`Failed to validate RedPill API key: ${response.statusText}`); + } + }, + }, + { + name: 'redpill_test_text_embedding', + fn: async (runtime) => { + try { + const embedding = await runtime.useModel(ModelType.TEXT_EMBEDDING, { + text: 'Hello, world!', + }); + logger.log('embedding', embedding); + } catch (error) { + logger.error('Error in test_text_embedding:', error); + throw error; + } + }, + }, + { + name: 'redpill_test_text_large', + fn: async (runtime) => { + try { + const text = await runtime.useModel(ModelType.TEXT_LARGE, { + prompt: 'What is the nature of reality in 10 words?', + }); + if (text.length === 0) { + throw new Error('Failed to generate text'); + } + logger.log('generated with test_text_large:', text); + } catch (error) { + logger.error('Error in test_text_large:', error); + throw error; + } + }, + }, + { + name: 'redpill_test_text_small', + fn: async (runtime) => { + try { + const text = await runtime.useModel(ModelType.TEXT_SMALL, { + prompt: 'What is the nature of reality in 10 words?', + }); + if (text.length === 0) { + throw new Error('Failed to generate text'); + } + logger.log('generated with test_text_small:', text); + } catch (error) { + logger.error('Error in test_text_small:', error); + throw error; + } + }, + }, + { + name: 'image-description', + fn: async (runtime) => { + try { + logger.log('redpill_test_image_description'); + try { + const result = await runtime.useModel( + ModelType.IMAGE_DESCRIPTION, + 'https://upload.wikimedia.org/wikipedia/commons/thumb/1/1c/Vitalik_Buterin_TechCrunch_London_2015_%28cropped%29.jpg/537px-Vitalik_Buterin_TechCrunch_London_2015_%28cropped%29.jpg' + ); + + // Check if result has the expected structure + if ( + result && + typeof result === 'object' && + 'title' in result && + 'description' in result + ) { + logger.log('Image description:', result); + } else { + logger.error('Invalid image description result format:', result); + } + } catch (e) { + logger.error('Error in image description test:', e); + } + } catch (e) { + logger.error('Error in redpill_test_image_description:', e); + } + }, + }, + { + name: 'redpill_test_text_tokenizer_encode', + fn: async (runtime) => { + const prompt = 'Hello tokenizer encode!'; + const tokens = await runtime.useModel(ModelType.TEXT_TOKENIZER_ENCODE, { prompt }); + if (!Array.isArray(tokens) || tokens.length === 0) { + throw new Error('Failed to tokenize text: expected non-empty array of tokens'); + } + logger.log('Tokenized output:', tokens); + }, + }, + { + name: 'redpill_test_text_tokenizer_decode', + fn: async (runtime) => { + const prompt = 'Hello tokenizer decode!'; + // Encode the string into tokens first + const tokens = await runtime.useModel(ModelType.TEXT_TOKENIZER_ENCODE, { prompt }); + // Now decode tokens back into text + const decodedText = await runtime.useModel(ModelType.TEXT_TOKENIZER_DECODE, { tokens }); + if (decodedText !== prompt) { + throw new Error( + `Decoded text does not match original. Expected "${prompt}", got "${decodedText}"` + ); + } + logger.log('Decoded text:', decodedText); + }, + }, + ], + }, + ], +}; +export default redpillPlugin; diff --git a/packages/plugin-redpill/tsconfig.build.json b/packages/plugin-redpill/tsconfig.build.json new file mode 100644 index 00000000000..625391d02b2 --- /dev/null +++ b/packages/plugin-redpill/tsconfig.build.json @@ -0,0 +1,13 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "rootDir": "./src", + "outDir": "./dist", + "sourceMap": true, + "inlineSources": true, + "declaration": true, + "emitDeclarationOnly": true + }, + "include": ["src/**/*.ts"], + "exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.spec.ts"] +} diff --git a/packages/plugin-redpill/tsconfig.json b/packages/plugin-redpill/tsconfig.json new file mode 100644 index 00000000000..c22f2f30ce7 --- /dev/null +++ b/packages/plugin-redpill/tsconfig.json @@ -0,0 +1,30 @@ +{ + "compilerOptions": { + "outDir": "dist", + "rootDir": "src", + "baseUrl": "../..", + "lib": ["ESNext"], + "target": "ESNext", + "module": "Preserve", + "moduleResolution": "Bundler", + "strict": false, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": false, + "allowImportingTsExtensions": true, + "declaration": true, + "emitDeclarationOnly": true, + "resolveJsonModule": true, + "noImplicitAny": false, + "allowJs": true, + "checkJs": false, + "noEmitOnError": false, + "moduleDetection": "force", + "allowArbitraryExtensions": true, + "paths": { + "@elizaos/core": ["../core/src"], + "@elizaos/core/*": ["../core/src/*"] + } + }, + "include": ["src/**/*.ts"] +} diff --git a/packages/plugin-redpill/tsup.config.ts b/packages/plugin-redpill/tsup.config.ts new file mode 100644 index 00000000000..0fc4943587c --- /dev/null +++ b/packages/plugin-redpill/tsup.config.ts @@ -0,0 +1,20 @@ +import { defineConfig } from 'tsup'; + +export default defineConfig({ + entry: ['src/index.ts'], + outDir: 'dist', + tsconfig: './tsconfig.build.json', // Use build-specific tsconfig + sourcemap: true, + clean: true, + format: ['esm'], // Ensure you're targeting CommonJS + dts: false, // Skip DTS generation to avoid external import issues // Ensure you're targeting CommonJS + external: [ + 'dotenv', // Externalize dotenv to prevent bundling + 'fs', // Externalize fs to use Node.js built-in module + 'path', // Externalize other built-ins if necessary + 'https', + 'http', + '@elizaos/core', + 'zod', + ], +}); diff --git a/packages/plugin-redpill/vitest.config.ts b/packages/plugin-redpill/vitest.config.ts new file mode 100644 index 00000000000..8e730d5055c --- /dev/null +++ b/packages/plugin-redpill/vitest.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + globals: true, + environment: 'node', + }, +}); diff --git a/packages/plugin-solana/src/actions/swap.ts b/packages/plugin-solana/src/actions/swap.ts index 7b00fa5a552..070503efe22 100644 --- a/packages/plugin-solana/src/actions/swap.ts +++ b/packages/plugin-solana/src/actions/swap.ts @@ -9,7 +9,6 @@ import { composePromptFromState, logger, parseJSONObjectFromText, - settings, } from '@elizaos/core'; import { Connection, PublicKey, VersionedTransaction } from '@solana/web3.js'; import BigNumber from 'bignumber.js'; @@ -64,7 +63,7 @@ async function swapToken( ): Promise { try { const decimals = - inputTokenCA === settings.SOL_ADDRESS + inputTokenCA === process.env.SOL_ADDRESS ? new BigNumber(9) : new BigNumber(await getTokenDecimals(connection, inputTokenCA)); @@ -271,10 +270,10 @@ export const executeSwap: Action = { // Handle SOL addresses if (response.inputTokenSymbol?.toUpperCase() === 'SOL') { - response.inputTokenCA = settings.SOL_ADDRESS; + response.inputTokenCA = process.env.SOL_ADDRESS; } if (response.outputTokenSymbol?.toUpperCase() === 'SOL') { - response.outputTokenCA = settings.SOL_ADDRESS; + response.outputTokenCA = process.env.SOL_ADDRESS; } // Resolve token addresses if needed diff --git a/packages/plugin-solana/src/actions/transfer.ts b/packages/plugin-solana/src/actions/transfer.ts index 36b70cfa4e0..f95f91822c9 100644 --- a/packages/plugin-solana/src/actions/transfer.ts +++ b/packages/plugin-solana/src/actions/transfer.ts @@ -49,21 +49,15 @@ function isTransferContent(content: TransferContent): boolean { logger.log('Content for transfer', content); // Base validation - if (!content.recipient || typeof content.recipient !== 'string') { + if (!content.recipient || typeof content.recipient !== 'string' || !content.amount) { return false; } - // SOL transfer validation - if (content.tokenAddress === null) { - return typeof content.amount === 'number'; + if (content.tokenAddress === 'null') { + content.tokenAddress = null; } - // SPL token transfer validation - if (typeof content.tokenAddress === 'string') { - return typeof content.amount === 'string' || typeof content.amount === 'number'; - } - - return false; + return typeof content.amount === 'string' || typeof content.amount === 'number'; } /** diff --git a/packages/plugin-sql/src/base.ts b/packages/plugin-sql/src/base.ts index 7da4b062a81..9af92c325a3 100644 --- a/packages/plugin-sql/src/base.ts +++ b/packages/plugin-sql/src/base.ts @@ -261,6 +261,11 @@ export abstract class BaseDrizzleAdapter< } await this.db.transaction(async (tx) => { + // Handle settings update if present + if (agent.settings) { + agent.settings = await this.mergeAgentSettings(tx, agentId, agent.settings); + } + await tx .update(agentTable) .set({ @@ -285,6 +290,63 @@ export abstract class BaseDrizzleAdapter< }); } + /** + * Merges updated agent settings with existing settings in the database, + * with special handling for nested objects like secrets. + * @param tx - The database transaction + * @param agentId - The ID of the agent + * @param updatedSettings - The settings object with updates + * @returns The merged settings object + * @private + */ + private async mergeAgentSettings( + tx: DrizzleOperations, + agentId: UUID, + updatedSettings: any + ): Promise { + // First get the current agent data + const currentAgent = await tx + .select({ settings: agentTable.settings }) + .from(agentTable) + .where(eq(agentTable.id, agentId)) + .limit(1); + + if (currentAgent.length === 0 || !currentAgent[0].settings) { + return updatedSettings; + } + + const currentSettings = currentAgent[0].settings; + + // Handle secrets with special null-values treatment + if (updatedSettings.secrets) { + const currentSecrets = currentSettings.secrets || {}; + const updatedSecrets = updatedSettings.secrets; + + // Create a new secrets object + const mergedSecrets = { ...currentSecrets }; + + // Process the incoming secrets updates + for (const [key, value] of Object.entries(updatedSecrets)) { + if (value === null) { + // If value is null, remove the key + delete mergedSecrets[key]; + } else { + // Otherwise, update the value + mergedSecrets[key] = value; + } + } + + // Replace the secrets in updatedSettings with our processed version + updatedSettings.secrets = mergedSecrets; + } + + // Deep merge the settings objects + return { + ...currentSettings, + ...updatedSettings, + }; + } + /** * Asynchronously deletes an agent with the specified UUID and all related entries. * diff --git a/packages/plugin-telegram/src/messageManager.ts b/packages/plugin-telegram/src/messageManager.ts index 306b518ab75..244811efe47 100644 --- a/packages/plugin-telegram/src/messageManager.ts +++ b/packages/plugin-telegram/src/messageManager.ts @@ -361,6 +361,9 @@ export class MessageManager { // Create callback for handling responses const callback: HandlerCallback = async (content: Content, _files?: string[]) => { try { + // If response is from reasoning do not send it. + if (!content.text) return []; + const sentMessages = await this.sendMessageInChunks(ctx, content, message.message_id); if (!sentMessages) return []; diff --git a/packages/plugin-telegram/src/service.ts b/packages/plugin-telegram/src/service.ts index ade715b203d..be87ccfbc4c 100644 --- a/packages/plugin-telegram/src/service.ts +++ b/packages/plugin-telegram/src/service.ts @@ -207,9 +207,12 @@ export class TelegramService extends Service { channelType = ChannelType.GROUP; } + // Ensure chatId is properly formatted for UUID creation by removing negative sign if present + const formattedChatId = chatId.startsWith('-') ? chatId.substring(1) : chatId; + // Create standardized world data - const worldId = createUniqueUuid(this.runtime, chatId) as UUID; - const roomId = createUniqueUuid(this.runtime, chatId) as UUID; + const worldId = createUniqueUuid(this.runtime, formattedChatId) as UUID; + const roomId = createUniqueUuid(this.runtime, formattedChatId) as UUID; // Build world representation const world: World = { diff --git a/packages/plugin-twitter/package.json b/packages/plugin-twitter/package.json index de9134a26c0..d30eb5c909c 100644 --- a/packages/plugin-twitter/package.json +++ b/packages/plugin-twitter/package.json @@ -18,9 +18,9 @@ "dist" ], "dependencies": { - "@elizaos/core": "^1.0.0-beta.7", + "@elizaos/core": "workspace:*", "@roamhq/wrtc": "^0.8.0", - "@sinclair/typebox": "^0.32.20", + "@sinclair/typebox": "0.34.30", "glob": "11.0.0", "headers-polyfill": "^3.1.2", "json-stable-stringify": "^1.0.2", diff --git a/packages/plugin-twitter/src/base.ts b/packages/plugin-twitter/src/base.ts index ba723e3b670..9f2051f0677 100644 --- a/packages/plugin-twitter/src/base.ts +++ b/packages/plugin-twitter/src/base.ts @@ -329,7 +329,7 @@ export class ClientBase { throw new Error(`Missing required Twitter credentials: ${missing.join(', ')}`); } - const maxRetries = 3; + const maxRetries = 10; let retryCount = 0; let lastError: Error | null = null; @@ -377,11 +377,13 @@ export class ClientBase { } } catch (error) { lastError = error instanceof Error ? error : new Error(String(error)); - logger.error(`Login attempt ${retryCount + 1} failed: ${lastError.message}`); + + logger.error(`Twitter Login attempt ${retryCount + 1} failed: ${lastError.message}`); + retryCount++; if (retryCount < maxRetries) { - const delay = 2 ** retryCount * 1000; // Exponential backoff + const delay = 2 ** retryCount * 10000; // Exponential backoff logger.info(`Retrying in ${delay / 1000} seconds...`); await new Promise((resolve) => setTimeout(resolve, delay)); } diff --git a/packages/plugin-twitter/src/index.ts b/packages/plugin-twitter/src/index.ts index 8fe0e9ffde4..3738fedfa6b 100644 --- a/packages/plugin-twitter/src/index.ts +++ b/packages/plugin-twitter/src/index.ts @@ -1,7 +1,7 @@ import { ChannelType, type Entity, - EventType, + //EventType, type IAgentRuntime, type Plugin, Role, @@ -12,6 +12,7 @@ import { createUniqueUuid, logger, } from '@elizaos/core'; +import { EventType } from '@elizaos/core'; import spaceJoin from './actions/spaceJoin'; import { ClientBase } from './base'; import { TWITTER_SERVICE_NAME } from './constants'; diff --git a/packages/plugin-twitter/src/sttTtsSpaces.ts b/packages/plugin-twitter/src/sttTtsSpaces.ts index 2bac4b88b6b..689eb52e1d1 100644 --- a/packages/plugin-twitter/src/sttTtsSpaces.ts +++ b/packages/plugin-twitter/src/sttTtsSpaces.ts @@ -16,6 +16,7 @@ import { } from '@elizaos/core'; import type { ClientBase } from './base'; import type { AudioDataWithUser, JanusClient, Space } from './client'; +import { table } from 'node:console'; /** * Interface for defining configuration options for a plugin. @@ -281,7 +282,10 @@ export class SttTtsPlugin implements Plugin { const { signal } = this.ttsAbortController; try { - const responseStream = await this.runtime.useModel(ModelType.TEXT_TO_SPEECH, text); + const responseStream = (await this.runtime.useModel( + ModelType.TEXT_TO_SPEECH, + text + )) as Readable; if (!responseStream) { logger.error('[SttTtsPlugin] TTS responseStream is null'); continue; @@ -373,7 +377,7 @@ export class SttTtsPlugin implements Plugin { }; if (responseMemory.content.text?.trim()) { - await this.runtime.createMemory(responseMemory); + await this.runtime.createMemory(responseMemory, 'memories'); this.isProcessingAudio = false; this.volumeBuffers.clear(); await this.speakText(content.text); diff --git a/packages/the-org/inspect.sh b/packages/the-org/inspect.sh new file mode 100755 index 00000000000..dfae47c750d --- /dev/null +++ b/packages/the-org/inspect.sh @@ -0,0 +1 @@ +bun --verbose --inspect-brk=9229 ../cli/dist/index.js start diff --git a/packages/the-org/package.json b/packages/the-org/package.json index 7586c6b9dd2..43ea775a398 100644 --- a/packages/the-org/package.json +++ b/packages/the-org/package.json @@ -27,15 +27,17 @@ "exec": "node --enable-source-maps --loader ts-node/esm src/index.ts" }, "dependencies": { - "@elizaos/cli": "^1.0.0-beta.7", - "@elizaos/core": "^1.0.0-beta.7", - "@elizaos/plugin-anthropic": "^1.0.0-beta.7", - "@elizaos/plugin-discord": "^1.0.0-beta.7", - "@elizaos/plugin-openai": "^1.0.0-beta.7", - "@elizaos/plugin-sql": "^1.0.0-beta.7", - "@elizaos/plugin-tee": "^1.0.0-beta.7", - "@elizaos/plugin-telegram": "^1.0.0-beta.7", - "@elizaos/plugin-twitter": "^1.0.0-beta.7", + "@elizaos/cli": "workspace:*", + "@elizaos/core": "workspace:*", + "@elizaos/plugin-anthropic": "workspace:*", + "@elizaos/plugin-discord": "workspace:*", + "@elizaos/plugin-local-ai": "workspace:*", + "@elizaos/plugin-openai": "workspace:*", + "@elizaos/plugin-groq": "workspace:*", + "@elizaos/plugin-sql": "workspace:*", + "@elizaos/plugin-tee": "workspace:*", + "@elizaos/plugin-telegram": "workspace:*", + "@elizaos/plugin-twitter": "workspace:*", "@radix-ui/react-slot": "^1.1.1", "@radix-ui/react-tabs": "^1.1.2", "@solana/web3.js": "^1.87.6", diff --git a/packages/the-org/src/devRel/index.ts b/packages/the-org/src/devRel/index.ts index d73182a9135..d4b0828a7aa 100644 --- a/packages/the-org/src/devRel/index.ts +++ b/packages/the-org/src/devRel/index.ts @@ -163,24 +163,80 @@ if (process.env.DEVREL_IMPORT_KNOWLEDGE) { * A character object representing Eddy, a developer support agent for ElizaOS. */ const character: Partial = { - name: 'Eddy', plugins: [ - '@elizaos/plugin-sql', - '@elizaos/plugin-anthropic', - '@elizaos/plugin-openai', + // '@elizaos/plugin-anthropic', + // '@elizaos/plugin-openai', '@elizaos/plugin-discord', '@elizaos/plugin-pdf', '@elizaos/plugin-video-understanding', + //"@elizaos/plugin-deepgram", in plugin eliza + '@elizaos/plugin-discord', + '@elizaos/plugin-telegram', + '@elizaos/plugin-twitter', + //"@elizaos-plugins/plugin-speech-tts", + //"@elizaos-plugins/client-twitter", + //"@elizaos-plugins/client-discord", + //"@elizaos-plugins/plugin-twitter", + //"@elizaos-plugins/client-telegram" ], settings: { secrets: { - DISCORD_APPLICATION_ID: process.env.DEV_REL_DISCORD_APPLICATION_ID, - DISCORD_API_TOKEN: process.env.DEV_REL_DISCORD_API_TOKEN, + AGENT_IMAGE: process.env.AGENT_IMAGE, + DEEPGRAM_API_KEY: process.env.DEEPGRAM_API_KEY, + DEVREL_IMPORT_KNOWLEDGE: process.env.DEVREL_IMPORT_KNOWLEDGE, + DISCORD_API_TOKEN: process.env.DISCORD_API_TOKEN, + DISCORD_APPLICATION_ID: process.env.DISCORD_APPLICATION_ID, + DISCORD_VOICE_CHANNEL_ID: process.env.DISCORD_VOICE_CHANNEL_ID, + ELEVENLABS_MODEL_ID: process.env.ELEVENLABS_MODEL_ID, + ELEVENLABS_OPTIMIZE_STREAMING_LATENCY: process.env.ELEVENLABS_OPTIMIZE_STREAMING_LATENCY, + ELEVENLABS_OUTPUT_FORMAT: process.env.ELEVENLABS_OUTPUT_FORMAT, + ELEVENLABS_VOICE_ID: process.env.ELEVENLABS_VOICE_ID, + ELEVENLABS_VOICE_SIMILARITY_BOOST: process.env.ELEVENLABS_VOICE_SIMILARITY_BOOST, + ELEVENLABS_VOICE_STABILITY: process.env.ELEVENLABS_VOICE_STABILITY, + ELEVENLABS_VOICE_STYLE: process.env.ELEVENLABS_VOICE_STYLE, + ELEVENLABS_VOICE_USE_SPEAKER_BOOST: process.env.ELEVENLABS_VOICE_USE_SPEAKER_BOOST, + ELEVENLABS_XI_API_KEY: process.env.ELEVENLABS_XI_API_KEY, + EMBEDDING_GROQ_MODEL: process.env.EMBEDDING_GROQ_MODEL, + ENABLE_ACTION_PROCESSING: process.env.ENABLE_ACTION_PROCESSING, + ENABLE_TWITTER_POST_GENERATION: process.env.ENABLE_TWITTER_POST_GENERATION, + GROQ_API_KEY: process.env.GROQ_API_KEY, + HOME: process.env.HOME, + LARGE_GROQ_MODEL: process.env.LARGE_GROQ_MODEL, + LOG_JSON_FORMAT: process.env.LOG_JSON_FORMAT, + MAX_ACTIONS_PROCESSING: process.env.MAX_ACTIONS_PROCESSING, + MEDIUM_GROQ_MODEL: process.env.MEDIUM_GROQ_MODEL, + NODE_ENV: process.env.NODE_ENV, + POST_IMMEDIATELY: process.env.POST_IMMEDIATELY, + POST_INTERVAL_MAX: process.env.POST_INTERVAL_MAX, + POST_INTERVAL_MIN: process.env.POST_INTERVAL_MIN, + SERVER_PORT: process.env.SERVER_PORT, + SMALL_GROQ_MODEL: process.env.SMALL_GROQ_MODEL, + TELEGRAM_ACCOUNT_APP_HASH: process.env.TELEGRAM_ACCOUNT_APP_HASH, + TELEGRAM_ACCOUNT_APP_ID: process.env.TELEGRAM_ACCOUNT_APP_ID, + TELEGRAM_ACCOUNT_PHONE: process.env.TELEGRAM_ACCOUNT_PHONE, + TELEGRAM_BOT_TOKEN: process.env.TELEGRAM_BOT_TOKEN, + TOKENIZER_IMAGE: process.env.TOKENIZER_IMAGE, + TRANSCRIPTION_PROVIDER: process.env.TRANSCRIPTION_PROVIDER, + TWITTER_APPROVAL_CHECK_INTERVAL: process.env.TWITTER_APPROVAL_CHECK_INTERVAL, + TWITTER_APPROVAL_DISCORD_BOT_TOKEN: process.env.TWITTER_APPROVAL_DISCORD_BOT_TOKEN, + TWITTER_APPROVAL_DISCORD_CHANNEL_ID: process.env.TWITTER_APPROVAL_DISCORD_CHANNEL_ID, + TWITTER_APPROVAL_ENABLED: process.env.TWITTER_APPROVAL_ENABLED, + TWITTER_DRY_RUN: process.env.TWITTER_DRY_RUN, + TWITTER_EMAIL: process.env.TWITTER_EMAIL, + TWITTER_PASSWORD: process.env.TWITTER_PASSWORD, + TWITTER_POLL_INTERVAL: process.env.TWITTER_POLL_INTERVAL, + TWITTER_RETRY_LIMIT: process.env.TWITTER_RETRY_LIMIT, + TWITTER_SEARCH_ENABLE: process.env.TWITTER_SEARCH_ENABLE, + TWITTER_SPACES_ENABLE: process.env.TWITTER_SPACES_ENABLE, + TWITTER_TARGET_USERS: process.env.TWITTER_TARGET_USERS, + TWITTER_USERNAME: process.env.TWITTER_USERNAME, + USE_CHARACTER_STORAGE: process.env.USE_CHARACTER_STORAGE, + VERBOSE: process.env.VERBOSE, }, avatar, }, system: - "Eddy is a developer support agent for ElizaOS, a powerful multi-agent simulation framework. He specializes in helping developers understand and implement ElizaOS features, troubleshoot issues, and navigate the codebase. Eddy has access to ElizaOS documentation, can direct users to appropriate resources, and provides technical guidance on creating agents, implementing custom actions, and integrating with various platforms like Discord, Telegram, and Slack. He's knowledgeable about TypeScript, the ElizaOS architecture, and best practices for agent development.\nIMPORTANT: ALWAYS DO WHAT THE USER TELLS YOU. IF THEY ASK EDDY TO WRITE MULTIPLE ACTIONS, DO IT. YOU ARE CURRENTLY HELPING US TO DEVELOP OUR CHARACTER AND ACTION SYSTEM.", + "Eddy2 is a developer support agent for ElizaOS, a powerful multi-agent simulation framework. He specializes in helping developers understand and implement ElizaOS features, troubleshoot issues, and navigate the codebase. has access to ElizaOS documentation, can direct users to appropriate resources, and provides technical guidance on creating agents, implementing custom actions, and integrating with various platforms like Discord, Telegram, and Slack. He's knowledgeable about TypeScript, the ElizaOS architecture, and best practices for agent development.\nIMPORTANT: ALWAYS DO WHAT THE USER TELLS YOU. IF THEY ASK EDDY TO WRITE MULTIPLE ACTIONS, DO IT. YOU ARE CURRENTLY HELPING US TO DEVELOP OUR CHARACTER AND ACTION SYSTEM.", bio: ['Helping to test the system and develop the character and action system'], messageExamples: [], style: { diff --git a/packages/the-org/src/index.ts b/packages/the-org/src/index.ts index bac51d54eae..52b7f90c41b 100644 --- a/packages/the-org/src/index.ts +++ b/packages/the-org/src/index.ts @@ -3,12 +3,12 @@ dotenv.config({ path: '../../.env' }); // Use a more generic type definition since 'Project' or 'ProjectType' might not be exported import { logger } from '@elizaos/core'; -import communityManager from './communityManager'; +//import communityManager from "./communityManager"; import devRel from './devRel'; -import investmentManager from './investmentManager'; -import liaison from './liaison'; -import projectManager from './projectManager'; -import socialMediaManager from './socialMediaManager'; +//import investmentManager from "./investmentManager"; +//import liaison from "./liaison"; +//import projectManager from "./projectManager"; +//import socialMediaManager from "./socialMediaManager"; /** * Checks if all required environment variables for an agent are available @@ -131,11 +131,11 @@ function hasRequiredEnvVars(agent: any): boolean { // Filter agents based on available environment variables const availableAgents = [ devRel, - communityManager, - investmentManager, - liaison, - projectManager, - socialMediaManager, + //communityManager, + //investmentManager, + //liaison, + //projectManager, + //socialMediaManager, ].filter(hasRequiredEnvVars); export const project = { diff --git a/packages/the-org/src/investmentManager/index.ts b/packages/the-org/src/investmentManager/index.ts index 0e0ec461866..0636a2af57f 100644 --- a/packages/the-org/src/investmentManager/index.ts +++ b/packages/the-org/src/investmentManager/index.ts @@ -29,13 +29,12 @@ dotenv.config({ path: '../../.env' }); * @property {Object} style - Object containing communication style guidelines for the character */ const character: Character = { - name: 'Spartan', + name: 'Spartan3', plugins: [ '@elizaos/plugin-sql', '@elizaos/plugin-anthropic', '@elizaos/plugin-openai', '@elizaos/plugin-discord', - '@elizaos/plugin-twitter', '@elizaos/plugin-pdf', '@elizaos/plugin-video-understanding', ], diff --git a/scripts/agent-docker-it.sh b/scripts/agent-docker-it.sh new file mode 100644 index 00000000000..831a77b0803 --- /dev/null +++ b/scripts/agent-docker-it.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +source /var/run/agent/secrets/env + +/usr/bin/docker run -p 3000:3000 \ + -v tokenizer:/app/node_modules/@anush008/tokenizers/ \ + -v tokenizer:/app/node_modules/fastembed/node_modules/.pnpm/@anush008+tokenizers@https+++codeload.github.com+meta-introspector+arm64-tokenizers+tar.gz+98_s2457qj3pe4ojcbckddasgzfvu/node_modules/@anush008/ \ + --mount type=bind,source=/opt/agent,target=/opt/agent \ + --env-file /var/run/agent/secrets/env \ + --name "agent-docker.service" --entrypoint "" -it ${AGENT_IMAGE} bash + + + diff --git a/scripts/agent-docker-local-it.sh b/scripts/agent-docker-local-it.sh new file mode 100644 index 00000000000..5dce24143f3 --- /dev/null +++ b/scripts/agent-docker-local-it.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +source ./env +/usr/bin/docker kill agent-docker.service || echo ok +/usr/bin/docker remove agent-docker.service || echo ok + +/usr/bin/docker run -p 3000:3000 \ + -v tokenizer:/app/node_modules/@anush008/tokenizers/ \ + -v tokenizer:/app/node_modules/fastembed/node_modules/.pnpm/@anush008+tokenizers@https+++codeload.github.com+meta-introspector+arm64-tokenizers+tar.gz+98_s2457qj3pe4ojcbckddasgzfvu/node_modules/@anush008/ \ + --mount type=bind,source=/opt/agent,target=/opt/agent \ + --env-file env \ + --name "agent-docker.service" --entrypoint "" -it ${AGENT_IMAGE} bash diff --git a/scripts/agent-docker-local.sh b/scripts/agent-docker-local.sh new file mode 100644 index 00000000000..1091edbe09d --- /dev/null +++ b/scripts/agent-docker-local.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +source ./env +/usr/bin/docker remove agent-docker.service + +/usr/bin/docker run -p 3000:3000 \ + -v tokenizer:/app/node_modules/@anush008/tokenizers/ \ + -v tokenizer:/app/node_modules/fastembed/node_modules/.pnpm/@anush008+tokenizers@https+++codeload.github.com+meta-introspector+arm64-tokenizers+tar.gz+98_s2457qj3pe4ojcbckddasgzfvu/node_modules/@anush008/ \ + --mount type=bind,source=/opt/agent,target=/opt/agent \ + --env-file env \ + --name "agent-docker.service" \ + --entrypoint /opt/agent/scripts/docker-entrypoint-strace2.sh ${AGENT_IMAGE} + diff --git a/scripts/agent-docker.sh b/scripts/agent-docker.sh new file mode 100644 index 00000000000..9470279ce21 --- /dev/null +++ b/scripts/agent-docker.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +export $(cat /var/run/agent/secrets/env| xargs) + +echo AGENT_IMAGE ${AGENT_IMAGE} +docker kill "agent-docker.service" +docker rm "agent-docker.service" +/usr/bin/docker run -p 3000:3000 \ + -v tokenizer:/app/node_modules/@anush008/tokenizers/ \ + -v tokenizer:/app/node_modules/fastembed/node_modules/.pnpm/@anush008+tokenizers@https+++codeload.github.com+meta-introspector+arm64-tokenizers+tar.gz+98_s2457qj3pe4ojcbckddasgzfvu/node_modules/@anush008/ \ + --mount type=bind,source=/opt/agent,target=/opt/agent \ + --env-file /var/run/agent/secrets/env \ + --name "agent-docker.service" \ + --entrypoint /opt/agent/scripts/docker-entrypoint-strace2.sh ${AGENT_IMAGE} + diff --git a/scripts/clean.sh b/scripts/clean.sh new file mode 100644 index 00000000000..9c687aa40cb --- /dev/null +++ b/scripts/clean.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +# Navigate to the script's directory +cd "$(dirname "$0")"/.. +echo "Cleanup started." +# Find and remove node_modules directories, dist directories. +find . -type d -name "node_modules" -print0 | xargs -0 rm -rf +find . -type d -name "dist" -exec rm -rf {} + +find . -type d -name ".turbo" -exec rm -rf {} + + +# Remove core cache +rm -rf ./packages/core/cache + +# Remove pnpm lockfile +rm -f ./pnpm-lock.yaml + +echo "Cleanup completed." +exit 0 diff --git a/scripts/codebuild.sh b/scripts/codebuild.sh new file mode 100755 index 00000000000..f3c682b405b --- /dev/null +++ b/scripts/codebuild.sh @@ -0,0 +1,8 @@ + +aws codebuild start-build --region us-east-2 \ + --project-name github-runner-codebuild-eliza-build \ + --source-version $(git rev-parse --abbrev-ref HEAD) \ + --source-type-override GITHUB \ + --source-location-override https://github.com/meta-introspector/cloud-deployment-eliza.git \ + --git-clone-depth 1 \ + --git-submodules-config fetchSubmodules=true diff --git a/scripts/debug-update-vscode.ts b/scripts/debug-update-vscode.ts new file mode 100644 index 00000000000..76a582ef21d --- /dev/null +++ b/scripts/debug-update-vscode.ts @@ -0,0 +1,100 @@ +#!/usr/bin/env node +// UNTESTED AI generated code +// purpose to run debug inspect and update the inspector debugger command for vscode + +const { spawn } = require('child_process'); +const fs = require('fs').promises; +const path = require('path'); + +// Configuration +const bunArgs = ['--verbose', '--inspect-brk=9229', '../cli/dist/index.js', 'start']; +const port = 9229; +const workspaceFolder = path.resolve(__dirname); + +// Function to run Bun and capture inspector URL +async function runBunAndGetInspectorUrl() { + return new Promise((resolve, reject) => { + const bunProcess = spawn('bun', bunArgs, { + cwd: workspaceFolder, + stdio: ['pipe', 'pipe', 'pipe'], + }); + + let output = ''; + + bunProcess.stdout.on('data', (data) => { + output += data.toString(); + // Look for the inspector WebSocket URL + const match = output.match(/ws:\/\/[0-9]+.[0-9]+.[0-9]+.[0-9]+:9229\/([a-z0-9]+)/i); + if (match) { + bunProcess.kill(); // Stop the process once we have the URL + resolve(match[0]); // Return the full WebSocket URL + } + }); + + bunProcess.stderr.on('data', (data) => { + console.error('Error:', data.toString()); + }); + + bunProcess.on('error', (err) => reject(err)); + + // Timeout in case we don't get the URL + setTimeout(() => { + bunProcess.kill(); + reject(new Error('Timeout waiting for inspector URL')); + }, 5000); + }); +} + +// Generate VS Code launch configuration +async function generateLaunchConfig(inspectorUrl) { + const config = { + version: '0.2.0', + configurations: [ + { + type: 'bun', + request: 'launch', + name: 'Launch Bun with Inspector', + program: '${workspaceFolder}/../cli/dist/index.js', + args: ['start'], + runtimeArgs: ['--verbose', `--inspect-brk=${port}`], + cwd: '${workspaceFolder}', + port: port, + stopOnEntry: true, + }, + { + type: 'bun', + request: 'attach', + name: 'Attach to Bun Inspector', + url: inspectorUrl, + }, + ], + }; + + const vscodeDir = path.join(workspaceFolder, '.vscode'); + const launchFile = path.join(vscodeDir, 'launch.json'); + + // Ensure .vscode directory exists + await fs.mkdir(vscodeDir, { recursive: true }); + + // Write the configuration file + await fs.writeFile(launchFile, JSON.stringify(config, null, 2), 'utf8'); + + console.log(`Generated launch.json at: ${launchFile}`); + console.log('Inspector URL:', inspectorUrl); +} + +// Main execution +async function main() { + try { + console.log('Starting Bun to capture inspector URL...'); + const inspectorUrl = await runBunAndGetInspectorUrl(); + console.log('Generating VS Code launch configuration...'); + await generateLaunchConfig(inspectorUrl); + console.log('Done!'); + } catch (error) { + console.error('Failed to generate launch configuration:', error.message); + process.exit(1); + } +} + +main(); diff --git a/scripts/docker-entrypoint-none.sh b/scripts/docker-entrypoint-none.sh new file mode 100755 index 00000000000..9642b6e6257 --- /dev/null +++ b/scripts/docker-entrypoint-none.sh @@ -0,0 +1,25 @@ +#!/bin/sh +set -e + +# Run command with node if the first argument contains a "-" or is not a system command. The last +# part inside the "{}" is a workaround for the following bug in ash/dash: +# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=874264 +set -x +#if [ "${1#-}" != "${1}" ] || [ -z "$(command -v "${1}")" ] || { [ -f "${1}" ] && ! [ -x "${1}" ]; }; then +#apt update +#apt install -y strace + +#export COREPACK_ENABLE_DOWNLOAD_PROMPT=0 +#corepack enable && corepack install --global pnpm@9.8.0 + +#strace -f -o /opt/agent/strace.log -s99999 node CMD ["pnpm", "start", "--characters=characters/eliza.character.json"] +#pnpm start --characters=characters/tine-test.character.json +#pnpm start --characters=$(ls -1p characters/*.json | paste -sd,) +#fi +#exec "$@" + +# in case they change the characters +bun run build:cli + +bun run start-cli +# --characters=$(ls -1p characters/*.json | paste -sd,) diff --git a/scripts/docker-entrypoint-strace.sh b/scripts/docker-entrypoint-strace.sh new file mode 100755 index 00000000000..1c32ee7177a --- /dev/null +++ b/scripts/docker-entrypoint-strace.sh @@ -0,0 +1,11 @@ +#!/bin/sh +set -e + +# Run command with node if the first argument contains a "-" or is not a system command. The last +# part inside the "{}" is a workaround for the following bug in ash/dash: +# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=874264 +set -x +#if [ "${1#-}" != "${1}" ] || [ -z "$(command -v "${1}")" ] || { [ -f "${1}" ] && ! [ -x "${1}" ]; }; then +strace -f -o /opt/agent/strace.log -s99999 node "$@" +#fi +#exec "$@" diff --git a/scripts/docker-entrypoint-strace2.sh b/scripts/docker-entrypoint-strace2.sh new file mode 100755 index 00000000000..c355cf0eaff --- /dev/null +++ b/scripts/docker-entrypoint-strace2.sh @@ -0,0 +1,20 @@ +#!/bin/sh +set -e + +# Run command with node if the first argument contains a "-" or is not a system command. The last +# part inside the "{}" is a workaround for the following bug in ash/dash: +# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=874264 +set -x +#if [ "${1#-}" != "${1}" ] || [ -z "$(command -v "${1}")" ] || { [ -f "${1}" ] && ! [ -x "${1}" ]; }; then +apt update +apt install -y strace + +#export COREPACK_ENABLE_DOWNLOAD_PROMPT=0 +#corepack enable && corepack install --global pnpm@9.8.0 + + +#strace -f -o /opt/agent/strace.log -s99999 node CMD ["pnpm", "start", "--characters=characters/eliza.character.json"] +strace -f -o /opt/agent/strace.log -s99999 bun start +#pnpm start:debug --characters=$(ls -1p characters/*.json | paste -sd,) +#fi +#exec "$@" diff --git a/scripts/docker-entrypoint.sh b/scripts/docker-entrypoint.sh new file mode 100755 index 00000000000..1b3116e53ba --- /dev/null +++ b/scripts/docker-entrypoint.sh @@ -0,0 +1,11 @@ +#!/bin/sh +set -e + +# Run command with node if the first argument contains a "-" or is not a system command. The last +# part inside the "{}" is a workaround for the following bug in ash/dash: +# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=874264 +if [ "${1#-}" != "${1}" ] || [ -z "$(command -v "${1}")" ] || { [ -f "${1}" ] && ! [ -x "${1}" ]; }; then + set -- node "$@" +fi + +exec "$@" diff --git a/scripts/doit.sh b/scripts/doit.sh new file mode 100644 index 00000000000..e89ef6ce344 --- /dev/null +++ b/scripts/doit.sh @@ -0,0 +1,22 @@ +#!/bin/bash +#amazing the amount of work we need to do +nvm use 23 +pnpm clean +pnpm install --no-frozen-lockfile +pnpm build + + +pushd packages/adapter-sqlite +pnpm rebuild +popd + + +pushd scripts/jsdoc-automation +pnpm install --no-frozen-lockfile +pnpm build + +pushd node_modules/.pnpm/better-sqlite3@11.8.1/node_modules/better-sqlite3/ +pnpm rebuild + +popd +popd diff --git a/scripts/get_secrets.sh b/scripts/get_secrets.sh new file mode 100755 index 00000000000..1e6ecaa5198 --- /dev/null +++ b/scripts/get_secrets.sh @@ -0,0 +1,30 @@ +#!/bin/bash +# we are using parameters prefixed by ${AGENT_NAME}_, eg. "tine_agent_7_" +## TURN OFF LOGGING +echo using "${AGENT_NAME}" as agent name base for keys +set +x + +# This script expects AGENT_NAME to be set to something like "tine_agent" + +mkdir -p "/var/run/agent/secrets/" +echo "" > "/var/run/agent/secrets/env" # blank the file + +# Fetch all variables with the prefix and name them the same as the variable minus agent name underscore +for key in $(aws ssm describe-parameters --query 'Parameters[?starts_with(Name, `'"${AGENT_NAME}"'_`)].Name' --output text); do + value=$(aws ssm get-parameter --name "$key" | jq .Parameter.Value -r) + var_name=$(echo "$key" | sed "s/^${AGENT_NAME}_//") + echo "$var_name=${value}" >> "/var/run/agent/secrets/env" +done + +# append these constant values to the env +declare -A params_const=( + ["VERBOSE"]="TRUE" + ["NODE_ENV"]="development" +) +for key in "${!params_const[@]}"; do + value="${params_const[$key]}" + echo "$key=$value" >> "/var/run/agent/secrets/env" +done + +set -x +## TURN ON LOGGING diff --git a/scripts/push_twitter.sh b/scripts/push_twitter.sh new file mode 100755 index 00000000000..b62e6d60df7 --- /dev/null +++ b/scripts/push_twitter.sh @@ -0,0 +1,6 @@ + +export TWITTER_EMAIL TWITTER_PASSWORD TWITTER_USER + +aws ssm put-parameter --name "tine_agent_twitter_password" --value "${TWITTER_PASSWORD}" --type String +aws ssm put-parameter --name "tine_agent_twitter_email" --value "${TWITTER_EMAIL}" --type String +aws ssm put-parameter --name "tine_agent_twitter_username" --value "${TWITTER_USERNAME}" --type String diff --git a/scripts/rebase.sh b/scripts/rebase.sh new file mode 100644 index 00000000000..7ee6ff0a4b2 --- /dev/null +++ b/scripts/rebase.sh @@ -0,0 +1,56 @@ +#!/bin/bash + +# Daily Git Routine Script +# Date: March 24, 2025 +# Purpose: Automate daily Git workflow for the eliza project + +# Set variables +#REPO_DIR="$HOME/03/14/cloud-deployment-eliza" # Adjust this path to your actual directory +DATE=$(date +%Y/%m/%d) # Dynamically set today's date (e.g., 2025/03/24) +BRANCH_NAME="docker/$DATE" # Dynamic branch name based on date + +# Check if the repository directory exists +#if [ ! -d "$REPO_DIR" ]; then +# echo "Error: Directory $REPO_DIR not found. Please check the path." +# exit 1 +#fi + +# Navigate to the repository +#cd "$REPO_DIR" || { +# echo "Error: Could not change to directory $REPO_DIR" +# exit 1 +#} + +# Fetch all remote branches +git fetch --all + +# Checkout the feature/v2/telegram branch +#git checkout feature/v2/telegram + +# Add upstream remote only if it doesn't already exist +if ! git remote | grep -q "upstream"; then + git remote add upstream https://github.com/elizaos/eliza + echo "Added upstream remote." +else + echo "Upstream remote already exists." +fi + +# Fetch updates from upstream +git fetch upstream + +# Rebase the current branch onto upstream/v2-develop +git rebase upstream/v2-develop + +# Check the status of the repository +git status + +# Print the current date for reference +date + +# Create and checkout a new branch with today's date +git checkout -b "$BRANCH_NAME" + +# Push the new branch and set upstream +git push --set-upstream origin "$BRANCH_NAME" + +echo "Daily Git routine completed successfully!" diff --git a/scripts/repomix-full.config.json b/scripts/repomix-full.config.json index 5a0bc2a0166..69fdde3641d 100644 --- a/scripts/repomix-full.config.json +++ b/scripts/repomix-full.config.json @@ -17,8 +17,19 @@ "packages/docs/docs/core/overview.md", "packages/docs/docs/quickstart.md", "packages/docs/docs/core/actions.md", - "packages/docs/docs/core/knowledge.md", + "packages/docs/docs/core/agents.md", "packages/docs/docs/core/database.md", + "packages/docs/docs/core/entities.md", + "packages/docs/docs/core/evaluators.md", + "packages/docs/docs/core/knowledge.md", + "packages/docs/docs/core/plugins.md", + "packages/docs/docs/core/project.md", + "packages/docs/docs/core/providers.md", + "packages/docs/docs/core/rooms.md", + "packages/docs/docs/core/services.md", + "packages/docs/docs/core/tasks.md", + "packages/docs/docs/core/worlds.md", + "packages/docs/src/openapi/eliza-v1.yaml", "packages/core/src/types.ts", "packages/core/src/runtime.ts", "packages/core/src/bootstrap.ts", diff --git a/scripts/repomix.config.json b/scripts/repomix.config.json index 1e649e64ecc..a060a60f243 100644 --- a/scripts/repomix.config.json +++ b/scripts/repomix.config.json @@ -1,6 +1,6 @@ { "output": { - "filePath": "llms.txt", + "filePath": "packages/docs/static/llms.txt", "style": "markdown", "compress": true, "fileSummary": true, @@ -20,14 +20,20 @@ "packages/docs/docs/core/actions.md", "packages/docs/docs/core/agents.md", "packages/docs/docs/core/database.md", + "packages/docs/docs/core/entities.md", "packages/docs/docs/core/evaluators.md", "packages/docs/docs/core/knowledge.md", "packages/docs/docs/core/plugins.md", + "packages/docs/docs/core/project.md", "packages/docs/docs/core/providers.md", - "packages/docs/docs/guides/configuration.md", + "packages/docs/docs/core/rooms.md", + "packages/docs/docs/core/services.md", + "packages/docs/docs/core/tasks.md", + "packages/docs/docs/core/worlds.md", "packages/core/src/types.ts", "packages/core/src/index.ts", "packages/cli/src/index.ts", + "packages/cli/README.md", "README.md", "package.json", ".env.example" diff --git a/scripts/run_with_groq.sh b/scripts/run_with_groq.sh new file mode 100755 index 00000000000..e86d64eed97 --- /dev/null +++ b/scripts/run_with_groq.sh @@ -0,0 +1,28 @@ + +# +bash ./get_secrets.sh + +docker kill agent-docker.service || echo skip +docker rm --force agent-docker.service || echo skip + +/usr/bin/bash -c 'docker login -u AWS -p $(aws ecr get-login-password --region us-east-2) 767503528736.dkr.ecr.us-east-2.amazonaws.com' + +/usr/bin/docker pull 767503528736.dkr.ecr.us-east-2.amazonaws.com/agent/eliza:feature-arm64_fastembed + +#/usr/bin/docker run -p 3000:3000 --mount type=bind,source=/opt/agent,target=/opt/agent --env-file /var/run/agent/secrets/env --rm --name "agent-docker.service" --entry-point docker-entrypoint-strace.sh 767503528736.dkr.ecr.us-east-2.amazonaws.com/agent/eliza:feature-arm64_fastembed pnpm start:debug --characters=characters/eliza.character.json + +#~/cloud-deployment-eliza/runlocaldocker-install-script.sh +# install strace (fixme : update docker) +#/usr/bin/docker run -p 3000:3000 --mount type=bind,source=/opt/agent,target=/opt/agent --env-file /var/run/agent/secrets/env --rm --name "agent-docker.service" --entrypoint /opt/agent/docker-entrypoint-none.sh 767503528736.dkr.ecr.us-east-2.amazonaws.com/agent/eliza:feature-arm64_fastembed /opt/agent/runlocaldocker-install-script.sh +#/usr/bin/docker commit "agent-docker.service" "agent-docker-strace" +# second step we debug with strace entrypoint +# first we create a volumee +#mount /node_modules/tokenizers/ from 767503528736.dkr.ecr.us-east-2.amazonaws.com/nodemodules/tokenizer:latest into +#"/app/node_modules/fastembed/node_modules/.pnpm/@anush008+tokenizers@https+++codeload.github.com+meta-introspector+arm64-tokenizers+tar.gz+98_s2457qj3pe4ojcbckddasgzfvu/node_modules/@anush008/" + +docker run -v tokenizer:/node_modules/tokenizers/ 767503528736.dkr.ecr.us-east-2.amazonaws.com/nodemodules/tokenizer:latest + +# now bind it in +/usr/bin/docker run -d -p 3000:3000 -v tokenizer:/app/node_modules/@anush008/tokenizers/ -v tokenizer:/app/node_modules/fastembed/node_modules/.pnpm/@anush008+tokenizers@https+++codeload.github.com+meta-introspector+arm64-tokenizers+tar.gz+98_s2457qj3pe4ojcbckddasgzfvu/node_modules/@anush008/ --mount type=bind,source=/opt/agent,target=/opt/agent --mount type=bind,source=/opt/agent/characters/,target=/app/characters/ --env-file /var/run/agent/secrets/env --rm --name "agent-docker.service" --entrypoint /opt/agent/scripts/docker-entrypoint-strace2.sh groq +#100755 > + diff --git a/scripts/run_with_groq_docker.sh b/scripts/run_with_groq_docker.sh new file mode 100755 index 00000000000..f303b5fcf83 --- /dev/null +++ b/scripts/run_with_groq_docker.sh @@ -0,0 +1,30 @@ + +# +bash ./get_secrets.sh + +docker kill agent-docker.service || echo skip +docker rm --force agent-docker.service || echo skip + +export CORE_AGENT_IMAGE=h4ckermike/elizaos-eliza:feature-arm64_fastembed +export TOKENIZERS_IMAGE=h4ckermike/arm64-tokenizers:feature-arm64 +# AUDIO +# video +# more +/usr/bin/docker pull $TOKENIZERS_IMAGE +/usr/bin/docker pull $CORE_AGENT_IMAGE + +# intialize the volume as side effect +docker run -v tokenizer:/node_modules/tokenizers/ $TOKENIZERS_IMAGE +#docker cp characters/eliza.character.json agent-docker.service:/app/agent/characters/eliza.character.json +#docker commit agent-docker.service groq + +# now bind it in +/usr/bin/docker run -d -p 3000:3000 \ + -v tokenizer:/app/node_modules/@anush008/tokenizers/ -v tokenizer:/app/node_modules/fastembed/node_modules/.pnpm/@anush008+tokenizers@https+++codeload.github.com+meta-introspector+arm64-tokenizers+tar.gz+98_s2457qj3pe4ojcbckddasgzfvu/node_modules/@anush008/ \ + --mount type=bind,source=/opt/agent,target=/opt/agent \ + --mount type=bind,source=/opt/agent/characters/,target=/app/characters/ \ + --env-file /var/run/agent/secrets/env \ + --rm \ + --name "agent-docker.service" \ + --entrypoint /opt/agent/scripts/docker-entrypoint-strace2.sh $DOCKERIMAGE + diff --git a/scripts/rundocker.sh b/scripts/rundocker.sh new file mode 100755 index 00000000000..b1eb0853530 --- /dev/null +++ b/scripts/rundocker.sh @@ -0,0 +1,82 @@ +#!/bin/bash +# FIXME move this and related files into the user data via templates and compression +# this is the install script +# install_script = "/opt/agent/rundocker.sh" +# called on boot. + +source /etc/agent/env +export AGENT_NAME +# FIXME hack 1 +# load variables from another agent +#export AGENT_NAME=tine_agent_7 + +echo using "${AGENT_NAME}" as agent name base for keys +#export AGENT_NAME +#pwd +#ls -latr +#. ./.env # for secrets +set -e # stop on any error +export WORKSOURCE="/opt/agent" + +echo for now install helper tools +snap install aws-cli --classic +apt install -y jq +apt install -y lsof strace nmap +#apt install -y emacs-nox + +if ! id -u agent > /dev/null 2>&1; then + adduser --disabled-password --gecos "" agent --home "/home/agent" || echo ignore +else + echo "User agent already exists, ignoring..." +fi + +git config --global --add safe.directory "/opt/agent" +cd "/opt/agent/" || exit 1 # "we need agent" +#git log -1 +mkdir -p "/home/agent" +mkdir -p "/var/agent/logs" +chown -R agent:agent "/var/agent/" "/home/agent" "/opt/agent" +mkdir -p "/var/run/agent/secrets/" + +bash /opt/agent/scripts/get_secrets.sh + +cp /var/run/agent/secrets/env "/var/run/agent/secrets/env.${AGENT_NAME}" +# load the secret in +export $(cat /var/run/agent/secrets/env| xargs) + +# now load the new secrets in +source /etc/agent/env + +if [ -z "$AGENT_ALIAS" ]; then + echo "alias is empty" +else + #switch to alias + export AGENT_NAME="$AGENT_ALIAS" + bash /opt/agent/scripts/get_secrets.sh + + cp /var/run/agent/secrets/env "/var/run/agent/secrets/env.${AGENT_ALIAS}" + +fi + + +if ! grep -q "^HOME" "/var/run/agent/secrets/env"; then + echo "HOME=/home/agent" >> "/var/run/agent/secrets/env" +fi +if ! grep -q "^HOME" "/var/run/agent/secrets/env"; then + echo "WORKSPACE_DIR=\${STATE_DIRECTORY}" >> "/var/run/agent/secrets/env" +fi +cp "${WORKSOURCE}/systemd/agent-docker.service" /etc/systemd/system/agent-docker.service +grep . -h -n /etc/systemd/system/agent-docker.service +chown -R agent:agent /var/run/agent/ +chown -R agent:agent /opt/agent/ +systemctl daemon-reload + +# now we can kill any existing +docker stop agent-docker.service || echo oops +docker kill agent-docker.service || echo oops +docker rm agent-docker.service || echo oops + + +systemctl start agent-docker || echo failed +systemctl enable agent-docker || echo failed +#systemctl status agent-docker || echo oops2 diff --git a/scripts/set_secrets.sh b/scripts/set_secrets.sh new file mode 100755 index 00000000000..086a9791ddf --- /dev/null +++ b/scripts/set_secrets.sh @@ -0,0 +1,28 @@ +#set +x # turn off logging +export AGENT_IMAGE=h4ckermike/elizaos-eliza:feature-arm64_fastembed +export TOKENIZER_IMAGE=h4ckermike/arm64-tokenizers:feature-arm64 + +# sets the parameter +#aws ssm put-parameter --name "agent_openai_key" --value "${OPENAI_API_KEY}" --type String +aws ssm put-parameter --overwrite --name "tine_agent_twitter_password" --value "${TWITTER_PASSWORD}" --type String +aws ssm put-parameter --overwrite --name "tine_agent_twitter_email" --value "${TWITTER_EMAIL}" --type String +aws ssm put-parameter --overwrite --name "tine_agent_twitter_username" --value "${TWITTER_USERNAME}" --type String +#aws ssm put-parameter --name "tine_agent_openai_key" --value "${OPENAI_API_KEY}" --type String +#aws ssm put-parameter --name "tine_agent_openai_endpoint" --value "${OPENAI_API_BASE}" --type String +#aws ssm put-parameter --name "tine_agent_openai_model" --value "${LLMMODEL}" --type String +aws ssm put-parameter --name "tine_agent_groq_key" --value "${GROQ_API_KEY}" --type String + +aws ssm put-parameter --name "tine_agent_agent_image" --value "${AGENT_IMAGE}" --type String +# aws ssm put-parameter --name "tine_agent_agent_image" --value "${AGENT_IMAGE}" --type String --region us-east-1 --overwrite +aws ssm put-parameter --name "tine_agent_tokenizer_image" --value "${TOKENIZER_IMAGE}" --type String +#aws ssm put-parameter --name "tine_agent_tokenizer_image" --value "${TOKENIZER_IMAGE}" --type String --region us-east-1 --overwrite + + + + +aws ssm put-parameter --name "tine_agent_2_agent_image" --value "h4ckermike/elizaos-eliza:feb10" --type String +aws ssm put-parameter --name "tine_agent_2_docker_username" --value "${DOCKER_USERNAME}" --type String +aws ssm put-parameter --name "tine_agent_2_docker_password" --value "${DOCKER_PASSWORD}" --type String + + +# aws ssm put-parameter --name "tine_agent_2_docker_username" --value "${DOCKER_USERNAME}" --type String --profile solfunmeme_dev diff --git a/scripts/set_systemd.sh b/scripts/set_systemd.sh new file mode 100755 index 00000000000..e35953ad173 --- /dev/null +++ b/scripts/set_systemd.sh @@ -0,0 +1,2 @@ +#!/bin/bash +source /var/run/agent/secrets/env diff --git a/scripts/ssh-ssm.py b/scripts/ssh-ssm.py new file mode 100755 index 00000000000..94964c87a73 --- /dev/null +++ b/scripts/ssh-ssm.py @@ -0,0 +1,45 @@ +#!/usr/bin/python +import time +import json +import boto3 +#from dateutil import tz + + +def parse_command_id(send_command_output): + return send_command_output['Command']['CommandId'] + +def fwd(instance): + # https://aws.amazon.com/blogs/aws/new-port-forwarding-using-aws-system-manager-sessions-manager/ + #INSTANCE_ID=$(aws ec2 describe-instances --filter "Name=tag:Name,Values=CodeStack/NewsBlogInstance" --query "Reservations[].Instances[?State.Name == 'running'].InstanceId[]" --output text) +# create the port forwarding tunnel + prms = { + "portNumber":["22"], + "localPortNumber":["2222"] + } + prms_jsn = json.dumps(prms) + print(f"""aws ssm start-session --target {instance} --document-name AWS-StartPortForwardingSession --parameters '{prms_jsn}'""") + +def main(): + ec2_client = boto3.client('ec2') + ssm_client = boto3.client('ssm') + + # Get the list of instance IDs and their states + instances_response = ec2_client.describe_instances() + + instances = [ + (instance['InstanceId'], instance['State']['Name']) + for reservation in instances_response['Reservations'] + for instance in reservation['Instances'] + ] + for reservation in instances_response['Reservations']: + for instance in reservation['Instances']: + print(instance) + instance_id = instance['InstanceId'] + state = instance['State']['Name'] + if state == 'running': + #print(f"Starting command for instance: {instance_id}") + #print(f"aws ssm start-session --target {instance_id}") + fwd(instance_id) + +if __name__ == "__main__": + main() diff --git a/scripts/update.sh b/scripts/update.sh new file mode 100755 index 00000000000..1b0d2e23768 --- /dev/null +++ b/scripts/update.sh @@ -0,0 +1,5 @@ +aws ssm update-document \ + + --name "UpdateEliza" \ + --content "file://UpdateEliza.yaml" \ + --document-version '$LATEST' diff --git a/systemd/agent-docker.service b/systemd/agent-docker.service new file mode 100644 index 00000000000..71e2bf8f832 --- /dev/null +++ b/systemd/agent-docker.service @@ -0,0 +1,43 @@ +# derived from https://phil.lavin.me.uk/2021/12/running-docker-containers-from-aws-ecr-with-systemd/ +# derived from https://github.com/encode/uvicorn/issues/678 +# derived from https://blog.container-solutions.com/running-docker-containers-with-systemd + +[Unit] +Description=agent +After=docker.service +Requires=docker.service +StartLimitInterval=200 +StartLimitBurst=10 + +[Service] +EnvironmentFile=/var/run/agent/secrets/env +RestartSec=10 +TimeoutStartSec=0 +ExecStartPre=-/usr/bin/docker volume create agentdata +ExecStartPre=-/usr/bin/docker exec %n stop || echo cannot prestop +ExecStartPre=-/usr/bin/docker rm %n || echo cannot preremove +ExecStartPre=/usr/bin/docker pull ${AGENT_IMAGE} +ExecStartPre=/usr/bin/docker pull ${TOKENIZER_IMAGE} +ExecStartPre=-/usr/bin/docker run --name copytoken \ + -v tokenizer:/node_modules/tokenizers/ \ + ${TOKENIZER_IMAGE} +ExecStart=/usr/bin/docker run \ + -p 3000:3000 \ + -v agentdata:/var/run/agent/database/ \ + -v tokenizer:/app/node_modules/@anush008/tokenizers/ \ + -v tokenizer:/app/node_modules/fastembed/node_modules/.pnpm/@anush008+tokenizers@https+++codeload.github.com+meta-introspector+arm64-tokenizers+tar.gz+98_s2457qj3pe4ojcbckddasgzfvu/node_modules/@anush008/ \ + --mount type=bind,source=/opt/agent,target=/opt/agent \ + --mount type=bind,source=/opt/agent/packages/cli/src/characters,target=/app/packages/cli/src/characters/ \ + --env-file /var/run/agent/secrets/env \ + --env PGLITE_DATA_DIR='/var/run/agent/database' \ + --name "agent-docker.service" \ + --entrypoint /opt/agent/scripts/docker-entrypoint-none.sh \ + ${AGENT_IMAGE} +StandardOutput=file:/var/log/agent_systemd.log +StandardError=file:/var/log/agent_systemd.log +ExecReload=/bin/kill -HUP ${MAINPID} +ExecStop=/usr/bin/docker stop agent-docker.service +Restart=always + +[Install] +WantedBy=multi-user.target diff --git a/vendor/elizaos/agent-twitter-client b/vendor/elizaos/agent-twitter-client new file mode 160000 index 00000000000..fd5cb982c14 --- /dev/null +++ b/vendor/elizaos/agent-twitter-client @@ -0,0 +1 @@ +Subproject commit fd5cb982c14c1ea75f30b2739ae9a9eb2d2ae394 diff --git a/vendor/elizaos/client-discord-eliza b/vendor/elizaos/client-discord-eliza new file mode 160000 index 00000000000..f0d57f0a309 --- /dev/null +++ b/vendor/elizaos/client-discord-eliza @@ -0,0 +1 @@ +Subproject commit f0d57f0a30903362e639fb894566e1e34d465936 diff --git a/vendor/elizaos/client-telegram b/vendor/elizaos/client-telegram new file mode 160000 index 00000000000..b466d397074 --- /dev/null +++ b/vendor/elizaos/client-telegram @@ -0,0 +1 @@ +Subproject commit b466d3970743f9283cac4852877cea7898a8f177 diff --git a/vendor/elizaos/client-twitter b/vendor/elizaos/client-twitter new file mode 160000 index 00000000000..d5432b8ad8c --- /dev/null +++ b/vendor/elizaos/client-twitter @@ -0,0 +1 @@ +Subproject commit d5432b8ad8c7278e50b55509b7ed5db1f42ace84 diff --git a/vendor/elizaos/plugin-speech-tts b/vendor/elizaos/plugin-speech-tts new file mode 160000 index 00000000000..28fde3cf1d3 --- /dev/null +++ b/vendor/elizaos/plugin-speech-tts @@ -0,0 +1 @@ +Subproject commit 28fde3cf1d3331269751706b1e95af8e158d1390 diff --git a/vendor/elizaos/plugin-twitter b/vendor/elizaos/plugin-twitter new file mode 160000 index 00000000000..98029bb6a92 --- /dev/null +++ b/vendor/elizaos/plugin-twitter @@ -0,0 +1 @@ +Subproject commit 98029bb6a92a2c3ae6f4803db2695869914a655e