Skip to content

Commit

Permalink
Merge branch 'develop' into pr/2079
Browse files Browse the repository at this point in the history
  • Loading branch information
wtfsayo committed Jan 10, 2025
2 parents c84ea52 + c9d4411 commit 58471eb
Show file tree
Hide file tree
Showing 100 changed files with 9,751 additions and 797 deletions.
54 changes: 54 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,10 @@ STARKNET_ADDRESS=
STARKNET_PRIVATE_KEY=
STARKNET_RPC_URL=

# Lens Network Configuration
LENS_ADDRESS=
LENS_PRIVATE_KEY=

# Coinbase
COINBASE_COMMERCE_KEY= # From Coinbase developer portal
COINBASE_API_KEY= # From Coinbase developer portal
Expand Down Expand Up @@ -483,3 +487,53 @@ TAVILY_API_KEY=
# Verifiable Inference Configuration
VERIFIABLE_INFERENCE_ENABLED=false # Set to false to disable verifiable inference
VERIFIABLE_INFERENCE_PROVIDER=opacity # Options: opacity


# Autonome Configuration
AUTONOME_JWT_TOKEN=
AUTONOME_RPC=https://wizard-bff-rpc.alt.technology/v1/bff/aaa/apps

####################################
#### Akash Network Configuration ####
####################################
AKASH_ENV=mainnet
AKASH_NET=https://raw.githubusercontent.com/ovrclk/net/master/mainnet
RPC_ENDPOINT=https://rpc.akashnet.net:443
AKASH_GAS_PRICES=0.025uakt
AKASH_GAS_ADJUSTMENT=1.5
AKASH_KEYRING_BACKEND=os
AKASH_FROM=default
AKASH_FEES=20000uakt
AKASH_DEPOSIT=500000uakt
AKASH_MNEMONIC=
AKASH_WALLET_ADDRESS=
# Akash Pricing API
AKASH_PRICING_API_URL=https://console-api.akash.network/v1/pricing
# Default values # 1 CPU = 1000 1GB = 1000000000 1GB = 1000000000
AKASH_DEFAULT_CPU=1000
AKASH_DEFAULT_MEMORY=1000000000
AKASH_DEFAULT_STORAGE=1000000000
AKASH_SDL=example.sdl.yml
# Close deployment
# Close all deployments = closeAll
# Close a single deployment = dseq and add the value in AKASH_CLOSE_DSEQ
AKASH_CLOSE_DEP=closeAll
AKASH_CLOSE_DSEQ=19729929
# Provider Info we added one to check you will have to pass this into the action
AKASH_PROVIDER_INFO=akash1ccktptfkvdc67msasmesuy5m7gpc76z75kukpz
# Deployment Status
# AKASH_DEP_STATUS = dseq or param_passed when you are building you wil pass the dseq dinamically to test you
# you can pass the dseq using AKASH_DEP_DSEQ 19729929 is an example of a dseq we test while build.
AKASH_DEP_STATUS=dseq
AKASH_DEP_DSEQ=19729929
# Gas Estimation Options: close, create, or update
# qseq is required when operation is "close" 19729929 is an example of a dseq we test while build.
AKASH_GAS_OPERATION=close
AKASH_GAS_DSEQ=19729929
# Manifest
# Values: "auto" | "manual" | "validate_only" Default: "auto"
AKASH_MANIFEST_MODE=auto
# Default: Will use the SDL directory
AKASH_MANIFEST_PATH=
# Values: "strict" | "lenient" | "none" - Default: "strict"
AKASH_MANIFEST_VALIDATION_LEVEL=strict
15 changes: 6 additions & 9 deletions .github/workflows/integrationTests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ on:
push:
branches:
- "*"
pull_request_target:
pull_request:
branches:
- "*"

Expand Down Expand Up @@ -33,12 +33,9 @@ jobs:
- name: Build packages
run: pnpm build

- name: Check for API key
run: |
if [ -z "$OPENAI_API_KEY" ]; then
echo "Error: OPENAI_API_KEY is not set."
exit 1
fi
- name: Run integration tests
run: pnpm run integrationTests
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
COINBASE_COMMERCE_KEY: ${{ secrets.COINBASE_COMMERCE_KEY }}
run: |
pnpm run integrationTests
4 changes: 2 additions & 2 deletions .github/workflows/pnpm-lockfile-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Pnpm Lockfile Check

on:
pull_request:
branches: ["*"]
branches: [main]

jobs:
check-lockfile:
Expand Down Expand Up @@ -38,4 +38,4 @@ jobs:
owner: context.repo.owner,
repo: context.repo.repo,
body: '❌ The pnpm-lockfile is out of date. Please run `pnpm install --no-frozen-lockfile` and commit the updated pnpm-lock.yaml file.'
})
})
4 changes: 4 additions & 0 deletions agent/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,15 @@
"@elizaos/plugin-gitbook": "workspace:*",
"@elizaos/plugin-story": "workspace:*",
"@elizaos/plugin-goat": "workspace:*",
"@elizaos/plugin-lensNetwork": "workspace:*",
"@elizaos/plugin-icp": "workspace:*",
"@elizaos/plugin-image-generation": "workspace:*",
"@elizaos/plugin-movement": "workspace:*",
"@elizaos/plugin-nft-generation": "workspace:*",
"@elizaos/plugin-node": "workspace:*",
"@elizaos/plugin-solana": "workspace:*",
"@elizaos/plugin-solana-agentkit": "workspace:*",
"@elizaos/plugin-autonome": "workspace:*",
"@elizaos/plugin-starknet": "workspace:*",
"@elizaos/plugin-stargaze": "workspace:*",
"@elizaos/plugin-giphy": "workspace:*",
Expand All @@ -74,6 +76,7 @@
"@elizaos/plugin-3d-generation": "workspace:*",
"@elizaos/plugin-fuel": "workspace:*",
"@elizaos/plugin-avalanche": "workspace:*",
"@elizaos/plugin-video-generation": "workspace:*",
"@elizaos/plugin-web-search": "workspace:*",
"@elizaos/plugin-letzai": "workspace:*",
"@elizaos/plugin-thirdweb": "workspace:*",
Expand All @@ -85,6 +88,7 @@
"@elizaos/plugin-allora": "workspace:*",
"@elizaos/plugin-opacity": "workspace:*",
"@elizaos/plugin-nillion": "workspace:*",
"@elizaos/plugin-akash": "workspace:*",
"readline": "1.3.0",
"ws": "8.18.0",
"yargs": "17.7.2"
Expand Down
64 changes: 49 additions & 15 deletions agent/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ import { flowPlugin } from "@elizaos/plugin-flow";
import { fuelPlugin } from "@elizaos/plugin-fuel";
import { genLayerPlugin } from "@elizaos/plugin-genlayer";
import { imageGenerationPlugin } from "@elizaos/plugin-image-generation";
import { lensPlugin } from "@elizaos/plugin-lensNetwork";
import { multiversxPlugin } from "@elizaos/plugin-multiversx";
import { nearPlugin } from "@elizaos/plugin-near";
import { nillionPlugin } from "@elizaos/plugin-nillion";
Expand All @@ -72,6 +73,7 @@ import { obsidianPlugin } from "@elizaos/plugin-obsidian";
import { sgxPlugin } from "@elizaos/plugin-sgx";
import { solanaPlugin } from "@elizaos/plugin-solana";
import { solanaAgentkitPlguin } from "@elizaos/plugin-solana-agentkit";
import { autonomePlugin } from "@elizaos/plugin-autonome";
import { storyPlugin } from "@elizaos/plugin-story";
import { suiPlugin } from "@elizaos/plugin-sui";
import { TEEMode, teePlugin } from "@elizaos/plugin-tee";
Expand All @@ -90,6 +92,7 @@ import { zksyncEraPlugin } from "@elizaos/plugin-zksync-era";
import { OpacityAdapter } from "@elizaos/plugin-opacity";
import { openWeatherPlugin } from "@elizaos/plugin-open-weather";
import { stargazePlugin } from "@elizaos/plugin-stargaze";
import { akashPlugin } from "@elizaos/plugin-akash";
import Database from "better-sqlite3";
import fs from "fs";
import net from "net";
Expand Down Expand Up @@ -143,10 +146,6 @@ function tryLoadFile(filePath: string): string | null {
}
}

function isAllStrings(arr: unknown[]): boolean {
return Array.isArray(arr) && arr.every((item) => typeof item === "string");
}

export async function loadCharacters(
charactersArg: string
): Promise<Character[]> {
Expand Down Expand Up @@ -232,16 +231,9 @@ export async function loadCharacters(
}

// Handle plugins
if (isAllStrings(character.plugins)) {
elizaLogger.info("Plugins are: ", character.plugins);
const importedPlugins = await Promise.all(
character.plugins.map(async (plugin) => {
const importedPlugin = await import(plugin);
return importedPlugin.default;
})
);
character.plugins = importedPlugins;
}
character.plugins = await handlePluginImporting(
character.plugins
);

loadedCharacters.push(character);
elizaLogger.info(
Expand All @@ -264,6 +256,36 @@ export async function loadCharacters(
return loadedCharacters;
}

async function handlePluginImporting(plugins: string[]) {
if (plugins.length > 0) {
elizaLogger.info("Plugins are: ", plugins);
const importedPlugins = await Promise.all(
plugins.map(async (plugin) => {
try {
const importedPlugin = await import(plugin);
const functionName =
plugin
.replace("@elizaos/plugin-", "")
.replace(/-./g, (x) => x[1].toUpperCase()) +
"Plugin"; // Assumes plugin function is camelCased with Plugin suffix
return (
importedPlugin.default || importedPlugin[functionName]
);
} catch (importError) {
elizaLogger.error(
`Failed to import plugin: ${plugin}`,
importError
);
return []; // Return null for failed imports
}
})
);
return importedPlugins;
} else {
return [];
}
}

export function getTokenForProvider(
provider: ModelProviderName,
character: Character
Expand Down Expand Up @@ -619,6 +641,7 @@ export async function createAgent(
getSecret(character, "SOLANA_PRIVATE_KEY")
? solanaAgentkitPlguin
: null,
getSecret(character, "AUTONOME_JWT_TOKEN") ? autonomePlugin : null,
(getSecret(character, "NEAR_ADDRESS") ||
getSecret(character, "NEAR_WALLET_PUBLIC_KEY")) &&
getSecret(character, "NEAR_WALLET_SECRET_KEY")
Expand Down Expand Up @@ -696,6 +719,10 @@ export async function createAgent(
getSecret(character, "FLOW_PRIVATE_KEY")
? flowPlugin
: null,
getSecret(character, "LENS_ADDRESS") &&
getSecret(character, "LENS_PRIVATE_KEY")
? lensPlugin
: null,
getSecret(character, "APTOS_PRIVATE_KEY") ? aptosPlugin : null,
getSecret(character, "MVX_PRIVATE_KEY") ? multiversxPlugin : null,
getSecret(character, "ZKSYNC_PRIVATE_KEY") ? zksyncEraPlugin : null,
Expand Down Expand Up @@ -733,6 +760,10 @@ export async function createAgent(
? artheraPlugin
: null,
getSecret(character, "ALLORA_API_KEY") ? alloraPlugin : null,
getSecret(character, "AKASH_MNEMONIC") &&
getSecret(character, "AKASH_WALLET_ADDRESS")
? akashPlugin
: null,
getSecret(character, "NILLION_NILDB_URLS") &&
getSecret(character, "NILLION_NILDB_NODE_IDS") &&
getSecret(character, "NILLION_NILDB_NODE_JWTS") &&
Expand Down Expand Up @@ -929,7 +960,10 @@ const startAgents = async () => {
}

// upload some agent functionality into directClient
directClient.startAgent = async (character: Character) => {
directClient.startAgent = async (character) => {
// Handle plugins
character.plugins = await handlePluginImporting(character.plugins);

// wrap it so we don't have to inject directClient later
return startAgent(character, directClient);
};
Expand Down
83 changes: 83 additions & 0 deletions docs/docs/advanced/verified-inference.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
---
sidebar_position: 18
---

# 🪪 Verified Inference

## Overview

With verified inference, you can turn your Eliza agent fully verifiable on-chain on Solana with an OpenAI compatible TEE API. This proves that your agent’s thoughts and outputs are free from human control thus increasing the trust of the agent.

Compared to [fully deploying the agent in a TEE](https://elizaos.github.io/eliza/docs/advanced/eliza-in-tee/), this is a more light-weight solution which only verifies the inference calls and only needs a single line of code change.

The API supports all OpenAI models out of the box, including your fine-tuned models. The following guide will walk you through how to use verified inference API with Eliza.

## Background

The API is built on top of [Sentience Stack](https://github.com/galadriel-ai/Sentience), which cryptographically verifies agent's LLM inferences inside TEEs, posts those proofs on-chain on Solana, and makes the verified inference logs available to read and display to users.

Here’s how it works:
![](https://i.imgur.com/SNwSHam.png)

1. The agent sends a request containing a message with the desired LLM model to the TEE.
2. The TEE securely processes the request by calling the LLM API.
3. The TEE sends back the `{Message, Proof}` to the agent.
4. The TEE submits the attestation with `{Message, Proof}` to Solana.
5. The Proof of Sentience SDK is used to read the attestation from Solana and verify it with `{Message, Proof}`. The proof log can be added to the agent website/app.

To verify the code running inside the TEE, use instructions [from here](https://github.com/galadriel-ai/sentience/tree/main/verified-inference/verify).

## Tutorial

1. **Create a free API key on [Galadriel dashboard](https://dashboard.galadriel.com/login)**
2. **Configure the environment variables**
```bash
GALADRIEL_API_KEY=gal-* # Get from https://dashboard.galadriel.com/
# Use any model supported by OpenAI
SMALL_GALADRIEL_MODEL= # Default: gpt-4o-mini
MEDIUM_GALADRIEL_MODEL= # Default: gpt-4o
LARGE_GALADRIEL_MODEL= # Default: gpt-4o
# If you wish to use a fine-tuned model you will need to provide your own OpenAI API key
GALADRIEL_FINE_TUNE_API_KEY= # starting with sk-
```
3. **Configure your character to use `galadriel`**

In your character file set the `modelProvider` as `galadriel`.
```
"modelProvider": "galadriel"
```
4. **Run your agent.**

Reminder how to run an agent is [here](https://elizaos.github.io/eliza/docs/quickstart/#create-your-first-agent).
```bash
pnpm start --character="characters/<your_character>.json"
pnpm start:client
```
5. **Get the history of all of your verified inference calls**
```javascript
const url = 'https://api.galadriel.com/v1/verified/chat/completions?limit=100&filter=mine';
const headers = {
'accept': 'application/json',
'Authorization': 'Bearer <GALADRIEL_API_KEY>'// Replace with your Galadriel API key
};
const response = await fetch(url, { method: 'GET', headers });
const data = await response.json();
console.log(data);
```
Use this to build a verified logs terminal to your agent front end, for example:
![](https://i.imgur.com/yejIlao.png)
6. **Check your inferences in the explorer.**
You can also see your inferences with proofs in the [Galadriel explorer](https://explorer.galadriel.com/). For specific inference responses use `https://explorer.galadriel.com/details/<hash>`
The `hash` param is returned with every inference request.
![](https://i.imgur.com/QazDxbE.png)
7. **Check proofs posted on Solana.**
You can also see your inferences with proofs on Solana. For specific inference responses: `https://explorer.solana.com/tx/<>tx_hash?cluster=devnet`
The `tx_hash` param is returned with every inference request.
Loading

0 comments on commit 58471eb

Please sign in to comment.