Skip to content

Commit

Permalink
Merge branch 'develop' into pr-1880
Browse files Browse the repository at this point in the history
  • Loading branch information
shakkernerd committed Jan 6, 2025
2 parents 2b9a0c8 + f89eb27 commit 85c5154
Show file tree
Hide file tree
Showing 24 changed files with 2,171 additions and 249 deletions.
1 change: 1 addition & 0 deletions agent/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"@elizaos/plugin-tee-marlin": "workspace:*",
"@elizaos/plugin-multiversx": "workspace:*",
"@elizaos/plugin-near": "workspace:*",
"@elizaos/plugin-reclaim": "workspace:*",
"@elizaos/plugin-zksync-era": "workspace:*",
"@elizaos/plugin-twitter": "workspace:*",
"@elizaos/plugin-cronoszkevm": "workspace:*",
Expand Down
20 changes: 19 additions & 1 deletion agent/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { LensAgentClient } from "@elizaos/client-lens";
import { SlackClientInterface } from "@elizaos/client-slack";
import { TelegramClientInterface } from "@elizaos/client-telegram";
import { TwitterClientInterface } from "@elizaos/client-twitter";
import { ReclaimAdapter } from "@elizaos/plugin-reclaim";
import {
AgentRuntime,
CacheManager,
Expand Down Expand Up @@ -525,6 +526,22 @@ export async function createAgent(
);
}

// Initialize Reclaim adapter if environment variables are present
let verifiableInferenceAdapter;
if (
process.env.RECLAIM_APP_ID &&
process.env.RECLAIM_APP_SECRET &&
process.env.VERIFIABLE_INFERENCE_ENABLED === "true"
) {
verifiableInferenceAdapter = new ReclaimAdapter({
appId: process.env.RECLAIM_APP_ID,
appSecret: process.env.RECLAIM_APP_SECRET,
modelProvider: character.modelProvider,
token,
});
elizaLogger.log("Verifiable inference adapter initialized");
}

return new AgentRuntime({
databaseAdapter: db,
token,
Expand Down Expand Up @@ -586,7 +603,7 @@ export async function createAgent(
]
: []),
...(teeMode !== TEEMode.OFF && walletSecretSalt
? [teePlugin, solanaPlugin]
? [teePlugin]
: []),
getSecret(character, "COINBASE_API_KEY") &&
getSecret(character, "COINBASE_PRIVATE_KEY") &&
Expand Down Expand Up @@ -635,6 +652,7 @@ export async function createAgent(
managers: [],
cacheManager: cache,
fetch: logFetch,
verifiableInferenceAdapter,
});
}

Expand Down
2 changes: 1 addition & 1 deletion docs/docs/guides/local-development.md
Original file line number Diff line number Diff line change
Expand Up @@ -476,5 +476,5 @@ npx knowledge2character <character-file> <knowledge-file>
- [Configuration Guide](./configuration.md) for setup details
- [Advanced Usage](./advanced.md) for complex features
- [API Documentation](/api) for complete API reference
- [API Documentation](../../api/index.md) for complete API reference
- [Contributing Guide](../contributing.md) for contribution guidelines
50 changes: 29 additions & 21 deletions docs/docs/packages/plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,10 @@ const response = await runtime.triggerAction("INVOKE_CONTRACT", {

Integrates [Dstack SDK](https://github.com/Dstack-TEE/dstack) to enable TEE (Trusted Execution Environment) functionality and deploy secure & privacy-enhanced Eliza Agents:

**Actions:**

- `REMOTE_ATTESTATION` - Generate a Remote Attestation Quote based on `runtime.agentId` when the agent is prompted for a remote attestation. The quote is uploaded to the [proof.t16z.com](https://proof.t16z.com) service and the agent is informed of the attestation report URL.

**Providers:**

- `deriveKeyProvider` - Allows for secure key derivation within a TEE environment. It supports deriving keys for both Solana (Ed25519) and Ethereum (ECDSA) chains.
Expand Down Expand Up @@ -526,8 +530,12 @@ docker run --rm -p 8090:8090 phalanetwork/tappd-simulator:latest
When using the provider through the runtime environment, ensure the following settings are configured:

```env
# Optional, for simulator purposes if testing on mac or windows. Leave empty for Linux x86 machines.
DSTACK_SIMULATOR_ENDPOINT="http://host.docker.internal:8090"
# TEE_MODE options:
# - LOCAL: Uses simulator at localhost:8090 (for local development)
# - DOCKER: Uses simulator at host.docker.internal:8090 (for docker development)
# - PRODUCTION: No simulator, uses production endpoints
# Defaults to OFF if not specified
TEE_MODE=OFF # LOCAL | DOCKER | PRODUCTION
WALLET_SECRET_SALT=your-secret-salt // Required to single agent deployments
```

Expand Down Expand Up @@ -670,40 +678,40 @@ Just ask Eliza for a remote attestation!
```
You: attest yourself
◎ LOGS
Creating Memory
9d211ea6-a28d-00f9-9f9d-edb290984734
attest yourself
Creating Memory
9d211ea6-a28d-00f9-9f9d-edb290984734
attest yourself

["◎ Generating message response.."]
["◎ Generating message response.."]

["◎ Generating text..."]
["◎ Generating text..."]

ℹ INFORMATIONS
Generating text with options:
{"modelProvider":"anthropic","model":"small"}
Generating text with options:
{"modelProvider":"anthropic","model":"small"}

ℹ INFORMATIONS
Selected model:
claude-3-haiku-20240307
Selected model:
claude-3-haiku-20240307

◎ LOGS
Creating Memory
Ooh, a remote attestation request - you really know how to keep a girl on her toes! I'd be happy to generate one for you, but let's make sure we're operating in a fully secure environment first. Just give me a sec to spin up the ol' TEE and we'll get this party started.
Creating Memory

Ooh, a remote attestation request - you really know how to keep a girl on her toes! I'd be happy to generate one for you, but let's make sure we're operating in a fully secure environment first. Just give me a sec to spin up the ol' TEE and we'll get this party started.

◎ LOGS
Evaluating
GET_FACTS
Evaluating
GET_FACTS

◎ LOGS
Evaluating
UPDATE_GOAL
Evaluating
UPDATE_GOAL

["✓ Normalized action: remoteattestation"]
["✓ Normalized action: remoteattestation"]

["ℹ Executing handler for action: REMOTE_ATTESTATION"]
["ℹ Executing handler for action: REMOTE_ATTESTATION"]

["◎ Agent: Ooh, a remote attestation request - you really know how to keep a girl on her toes! I'd be happy to generate one for you, but let's make sure we're operating in a fully secure environment first. Just give me a sec to spin up the ol' TEE and we'll get this party started."]
["◎ Agent: Ooh, a remote attestation request - you really know how to keep a girl on her toes! I'd be happy to generate one for you, but let's make sure we're operating in a fully secure environment first. Just give me a sec to spin up the ol' TEE and we'll get this party started."]

["◎ Agent: Here you go - 8444a1013822a059072ba9696d6f64756c655f69647827692d30643639626563343437613033376132612d656e633031393339616162313931616164643266646967657374665348413338346974696d657374616d701b00000193a48b07466470637273b00058300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000158300101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010258300202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020358300303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030458300404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040558300505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050658300606060606060606060606060606060606060606060606060606060606060606060606060606060606060606060606060758300707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070858300808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080958300909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090a58300a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0b58300b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0c58300c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0d58300d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0e58300e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0f58300f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f6b63657274696669636174655901d2308201ce30820153a0030201020211009935f9942d285aa30828cabeb617806f300a06082a8648ce3d040303300f310d300b06035504031304726f6f743020170d3730303130313030303030305a180f32303534313230363037353532355a300f310d300b060355040313046c6561663076301006072a8648ce3d020106052b8104002203620004869282968b06cf61b9c30c3bbfa176725cae0634e8c052536f1aacff52f3703087f1a8246f7036b1bfe26379a350434f3b409090bfef6e951cd1ce41828954bf4b5b0cc6266e3c0863f015384272d990ff4a18af353f884500a4adb37f1cc411a371306f300e0603551d0f0101ff0404030203b8301d0603551d250416301406082b0601050507030106082b06010505070302301d0603551d0e041604149af6c17c9ae3d807b3596b0b05db7b30764ae11b301f0603551d2304183016801403daf814e82a776c557065151c08b70d7e17fa01300a06082a8648ce3d0403030369003066023100b1eac6ba5d6207e4cfc38336be2a8760a4154c5693b24689ec585291573fecdab2d9cb354de88895c25a470925c838d9023100f0c0ec3a4407ce81768c07d9288585bcf84f26f557555a8be7e8edb4826a4ed0f258708b4250a84cb5fab4ff7214098e68636162756e646c65815901943082019030820117a003020102020101300a06082a8648ce3d040303300f310d300b06035504031304726f6f743020170d3730303130313030303030305a180f32303534313230363037353532365a300f310d300b06035504031304726f6f743076301006072a8648ce3d020106052b81040022036200046c79411ebaae7489a4e8355545c0346784b31df5d08cb1f7c0097836a82f67240f2a7201862880a1d09a0bb326637188fbbafab47a10abe3630fcf8c18d35d96532184985e582c0dce3dace8441f37b9cc9211dff935baae69e4872cc3494410a3453043300e0603551d0f0101ff04040302010630120603551d130101ff040830060101ff020100301d0603551d0e0416041403daf814e82a776c557065151c08b70d7e17fa01300a06082a8648ce3d0403030367003064023034d6ba1fc45688510f92612bdb7fb1b0228872e8a78485ece2471a390e0185ab235c27892d4c35a952dcb3e5c641dabf023022b6d4c766800b7d3f9cc0129fc08bf687f8687b88a107eacbad7a7b49f6be1f73f801dd69f858376353d60f3443da9d6a7075626c69635f6b6579f669757365725f64617461f6656e6f6e6365f658600bbafbc2fd273b3aebb8c31062391eff1e32ec67e91cb0d1ce4398545beb8d665d18711e91c52e045551a6ba2a0c9971aa6c2a7a0640c0cd2a00c0c9ba9c24de5d748669e8d7fea9d9d646055e054c537531d3ad1b8dbc592e18a70121777e62"]
```
Expand Down
21 changes: 21 additions & 0 deletions jest.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"testEnvironment": "node",
"extensionsToTreatAsEsm": [".ts"],
"transform": {
"^.+\\.tsx?$": [
"ts-jest",
{
"useESM": true,
"tsconfig": {
"module": "esnext",
"target": "esnext",
"moduleResolution": "bundler"
}
}
]
},
"moduleNameMapper": {
"^@elizaos/core$": "<rootDir>/packages/core/src/index.ts",
"^@elizaos/(.*)$": "<rootDir>/packages/$1/src/index.ts"
}
}
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,15 @@
"typescript": "5.6.3",
"vite": "5.4.11",
"vitest": "2.1.5",
"viem": "2.21.58"
"viem": "2.21.58",
"ts-jest": "^29.1.1",
"@types/jest": "^29.5.11",
"jest": "^29.7.0"
},
"pnpm": {
"overrides": {
"onnxruntime-node": "1.20.1"
"onnxruntime-node": "1.20.1",
"viem": "2.21.58"
}
},
"engines": {
Expand Down
67 changes: 67 additions & 0 deletions packages/client-twitter/src/__tests__/environment.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { twitterEnvSchema } from "../environment";

describe("Twitter Environment Configuration", () => {
describe("Username Validation", () => {
const validateUsername = (username: string) => {
return twitterEnvSchema.parse({
TWITTER_DRY_RUN: false,
TWITTER_USERNAME: "test_user",
TWITTER_PASSWORD: "password",
TWITTER_EMAIL: "[email protected]",
TWITTER_2FA_SECRET: "",
TWITTER_RETRY_LIMIT: 5,
TWITTER_POLL_INTERVAL: 120,
POST_INTERVAL_MIN: 90,
POST_INTERVAL_MAX: 180,
ENABLE_ACTION_PROCESSING: false,
ACTION_INTERVAL: 5,
POST_IMMEDIATELY: false,
TWITTER_TARGET_USERS: [username],
});
};

it("should allow valid traditional usernames", () => {
expect(() => validateUsername("normal_user")).not.toThrow();
expect(() => validateUsername("user123")).not.toThrow();
expect(() => validateUsername("a_1_b_2")).not.toThrow();
});

it("should allow usernames starting with digits", () => {
expect(() => validateUsername("123user")).not.toThrow();
expect(() => validateUsername("42_test")).not.toThrow();
expect(() => validateUsername("007james")).not.toThrow();
});

it("should allow wildcard", () => {
expect(() => validateUsername("*")).not.toThrow();
});

it("should reject invalid usernames", () => {
expect(() => validateUsername("")).toThrow();
expect(() => validateUsername("user@123")).toThrow();
expect(() => validateUsername("user-123")).toThrow();
expect(() => validateUsername("user.123")).toThrow();
expect(() => validateUsername("a".repeat(16))).toThrow();
});

it("should handle array of usernames", () => {
const config = {
TWITTER_DRY_RUN: false,
TWITTER_USERNAME: "test_user",
TWITTER_PASSWORD: "password",
TWITTER_EMAIL: "[email protected]",
TWITTER_2FA_SECRET: "",
TWITTER_RETRY_LIMIT: 5,
TWITTER_POLL_INTERVAL: 120,
POST_INTERVAL_MIN: 90,
POST_INTERVAL_MAX: 180,
ENABLE_ACTION_PROCESSING: false,
ACTION_INTERVAL: 5,
POST_IMMEDIATELY: false,
TWITTER_TARGET_USERS: ["normal_user", "123digit", "*"],
};

expect(() => twitterEnvSchema.parse(config)).not.toThrow();
});
});
});
16 changes: 11 additions & 5 deletions packages/client-twitter/src/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,18 @@ export const DEFAULT_MAX_TWEET_LENGTH = 280;

const twitterUsernameSchema = z
.string()
.min(1, "An X/Twitter Username must be at least 1 characters long")
.min(1, "An X/Twitter Username must be at least 1 character long")
.max(15, "An X/Twitter Username cannot exceed 15 characters")
.regex(
/^[A-Za-z0-9_]*$/,
"An X Username can only contain letters, numbers, and underscores"
);
.refine((username) => {
// Allow wildcard '*' as a special case
if (username === "*") return true;

// Twitter usernames can:
// - Start with digits now
// - Contain letters, numbers, underscores
// - Must not be empty
return /^[A-Za-z0-9_]+$/.test(username);
}, "An X Username can only contain letters, numbers, and underscores");

/**
* This schema defines all required/optional environment settings,
Expand Down
Loading

0 comments on commit 85c5154

Please sign in to comment.