Skip to content

Commit 0128a1e

Browse files
authored
Merge branch 'develop' into patch-custom-fetch
2 parents a7a8fd0 + e4dac88 commit 0128a1e

25 files changed

+1331
-653
lines changed

.env.example

+2
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ TWITTER_EMAIL= # Account email
5353
TWITTER_2FA_SECRET=
5454
TWITTER_COOKIES= # Account cookies
5555
TWITTER_POLL_INTERVAL=120 # How often (in seconds) the bot should check for interactions
56+
TWITTER_SEARCH_ENABLE=FALSE # Enable timeline search, WARNING this greatly increases your chance of getting banned
57+
TWITTER_TARGET_USERS= # Comma separated list of Twitter user names to interact with
5658
X_SERVER_URL=
5759
XAI_API_KEY=
5860
XAI_MODEL=
+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
name: integration-test
2+
on:
3+
push:
4+
branches:
5+
- "*"
6+
pull_request:
7+
branches:
8+
- "*"
9+
jobs:
10+
smoke-tests:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
15+
- uses: pnpm/action-setup@v3
16+
with:
17+
version: 9.4.0
18+
19+
- uses: actions/setup-node@v4
20+
with:
21+
node-version: "23"
22+
cache: "pnpm"
23+
24+
- name: Run smoke tests
25+
run: pnpm run smokeTests
26+
integration-tests:
27+
runs-on: ubuntu-latest
28+
steps:
29+
- uses: actions/checkout@v4
30+
31+
- uses: pnpm/action-setup@v3
32+
with:
33+
version: 9.4.0
34+
35+
- uses: actions/setup-node@v4
36+
with:
37+
node-version: "23"
38+
cache: "pnpm"
39+
40+
- name: Install dependencies
41+
run: pnpm install -r
42+
43+
- name: Build packages
44+
run: pnpm build
45+
46+
- name: Run integration tests
47+
env:
48+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
49+
run: |
50+
if [ -z "$OPENAI_API_KEY" ]; then
51+
echo "Skipping integration tests due to missing required API keys"
52+
exit 1
53+
else
54+
pnpm run integrationTests
55+
fi

agent/src/index.ts

+17
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,7 @@ export async function initializeClients(
341341
}
342342

343343
if (clientTypes.includes("twitter")) {
344+
TwitterClientInterface.enableSearch = !isFalsish(getSecret(character, "TWITTER_SEARCH_ENABLE"));
344345
const twitterClients = await TwitterClientInterface.start(runtime);
345346
clients.push(twitterClients);
346347
}
@@ -364,6 +365,22 @@ export async function initializeClients(
364365
return clients;
365366
}
366367

368+
function isFalsish(input: any): boolean {
369+
// If the input is exactly NaN, return true
370+
if (Number.isNaN(input)) {
371+
return true;
372+
}
373+
374+
// Convert input to a string if it's not null or undefined
375+
const value = input == null ? '' : String(input);
376+
377+
// List of common falsish string representations
378+
const falsishValues = ['false', '0', 'no', 'n', 'off', 'null', 'undefined', ''];
379+
380+
// Check if the value (trimmed and lowercased) is in the falsish list
381+
return falsishValues.includes(value.trim().toLowerCase());
382+
}
383+
367384
function getSecret(character: Character, secret: string) {
368385
return character.settings.secrets?.[secret] || process.env[secret];
369386
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
---
2+
sidebar_position: 4
3+
title: "AI Agent Dev School Part 4"
4+
description: "AI Pizza: Hacking Eliza for Domino's Delivery (plus TEE Deep Dive)"
5+
---
6+
7+
# AI Agent Dev School Part 4
8+
9+
**AI Pizza: Hacking Eliza for Domino's Delivery (plus TEE Deep Dive)**
10+
11+
Date: 2024-12-10
12+
YouTube Link: https://www.youtube.com/watch?v=6I9e9pJprDI
13+
14+
## Timestamps
15+
16+
Part 1: Trusted Execution Environments (TEEs) with Agent Joshua
17+
- **00:00:09** - Stream starts, initial setup issues.
18+
- Link: <https://www.youtube.com/watch?v=6I9e9pJprDI&t=9>
19+
- **00:01:58** - Intro to Trusted Execution Environments (TEEs).
20+
- Link: <https://www.youtube.com/watch?v=6I9e9pJprDI&t=118>
21+
- **00:08:03** - Agent Joshua begins explaining TEEs and the Eliza plugin.
22+
- Link: <https://www.youtube.com/watch?v=6I9e9pJprDI&t=483>
23+
- **00:19:15** - Deeper dive into remote attestation.
24+
- Link: <https://www.youtube.com/watch?v=6I9e9pJprDI&t=1155>
25+
- **00:24:50** - Discussion of derived keys.
26+
- Link: <https://www.youtube.com/watch?v=6I9e9pJprDI&t=1490>
27+
- **00:37:00** - Deploying to a real TEE, Phala Network's TEE cloud.
28+
- Link: <https://www.youtube.com/watch?v=6I9e9pJprDI&t=2220>
29+
- **00:50:48** - Q&A with Joshua, contact info, and next steps.
30+
- Link: <https://www.youtube.com/watch?v=6I9e9pJprDI&t=3048>
31+
32+
Part 2: Building a Domino's pizza ordering agent
33+
- **01:04:37** - Transition to building a Domino's pizza ordering agent.
34+
- Link: <https://www.youtube.com/watch?v=6I9e9pJprDI&t=3877>
35+
- **01:14:20** - Discussion of the pizza ordering agent’s order flow and state machine.
36+
- Link: <https://www.youtube.com/watch?v=6I9e9pJprDI&t=4460>
37+
- **01:22:07** - Using Claude to generate a state machine diagram.
38+
- Link: <https://www.youtube.com/watch?v=6I9e9pJprDI&t=4927>
39+
- **01:32:17** - Creating the Domino's plugin in Eliza.
40+
- Link: <https://www.youtube.com/watch?v=6I9e9pJprDI&t=5537>
41+
- **01:54:15** - Working on the pizza order provider.
42+
- Link: <https://www.youtube.com/watch?v=6I9e9pJprDI&t=6855>
43+
- **02:16:46** - Pizza provider code completed.
44+
- Link: <https://www.youtube.com/watch?v=6I9e9pJprDI&t=8206>
45+
- **02:28:50** - Discussion of caching customer and order data.
46+
- Link: <https://www.youtube.com/watch?v=6I9e9pJprDI&t=8930>
47+
- **03:13:45** - Pushing fixes to main branch and continuing work on the agent.
48+
- Link: <https://www.youtube.com/watch?v=6I9e9pJprDI&t=11625>
49+
- **04:24:30** - Discussion of summarizing past agent dev school sessions.
50+
- Link: <https://www.youtube.com/watch?v=6I9e9pJprDI&t=15870>
51+
- **05:01:18** - Shaw returns, admits to ordering Domino's manually.
52+
- Link: <https://www.youtube.com/watch?v=6I9e9pJprDI&t=18078>
53+
- **05:09:00** - Discussing payment flow and a confirm order action.
54+
- Link: <https://www.youtube.com/watch?v=6I9e9pJprDI&t=18540>
55+
- **05:27:17** - Final code push, wrap-up, and end of stream.
56+
- Link: <https://www.youtube.com/watch?v=6I9e9pJprDI&t=19637>
57+
58+
59+
## Summary
60+
61+
This is a livestream titled "AI Agent Dev School Part 4" from the ai16z project, featuring Shaw. The stream is divided into two main parts: a technical discussion on Trusted Execution Environments (TEEs) and a coding session where Shaw attempts to build a pizza-ordering agent using the Domino's API.
62+
63+
**Part 1: Trusted Execution Environments (TEEs) with Agent Joshua**
64+
65+
This segment begins with Shaw introducing the concept of TEEs and their importance for running autonomous agents securely. He emphasizes the need to protect private keys and ensure that code execution is tamper-proof. Joshua from the Phala Network is brought on to explain TEEs in more detail and demonstrate how to use the TEE plugin he built for Eliza.
66+
67+
* **Key Concepts:**
68+
* **Trusted Execution Environments (TEEs):** Secure areas within a processor that isolate code and data, protecting them from unauthorized access and tampering.
69+
* **Secure Enclave:** A cryptographic primitive that allows data to be encrypted and isolated within a processor.
70+
* **Remote Attestation:** A method to verify that a program running inside a TEE is genuine and hasn't been tampered with, providing verifiability to users.
71+
* **D-Stack:** An SDK developed in collaboration with Flashbots and Andrew Miller, enabling developers to build and launch Docker containers in TEEs.
72+
* **Derived Key Provider:** A component that generates cryptographic keys based on a secret salt, ensuring that private keys are not exposed to humans.
73+
74+
* **Demonstration:**
75+
* Joshua walks through the process of setting up and deploying an Eliza agent in a TEE simulator, demonstrating how to generate remote attestations and derive keys.
76+
* He shows how to use the remote attestation explorer to verify the authenticity of the agent running inside the TEE.
77+
* He explains how to build a Docker image of the agent and deploy it to the Phala Network's TEE cloud solution.
78+
79+
* **Use Cases:**
80+
* Securely storing private keys for on-chain actions.
81+
* Ensuring the integrity of autonomous agents, preventing tampering or unauthorized access.
82+
* Providing verifiable execution for users and investors.
83+
84+
* **Phala Network's TEE Cloud:**
85+
* Joshua introduces Phala Network's TEE cloud solution, which allows developers to deploy Docker images and host their agents in a trusted execution environment.
86+
* He mentions that the service supports various compute-intensive applications beyond AI agents.
87+
* He invites interested developers to contact him on Discord (@hashwarlock) for onboarding and further details.
88+
89+
**Part 2: Building a Pizza Ordering Agent**
90+
91+
In the second part, Shaw transitions to a more lighthearted coding session where he attempts to build an agent that can order a pizza using the Domino's API. He highlights the challenges of handling payments securely and connecting user information to the conversation.
92+
93+
* **Challenges:**
94+
* Securely handling payment information.
95+
* Connecting user data to the current conversation.
96+
* Defining the order flow using a state machine.
97+
98+
* **Approach:**
99+
* Shaw uses a state machine to model the pizza ordering process, defining different states and transitions based on user input and available information.
100+
* He uses Claude (an AI assistant) to generate code snippets and assist with the development process.
101+
* He decides to initially focus on a simplified version where the user's payment information is hardcoded in the environment variables, and the agent only needs to collect the user's address.
102+
103+
## Hot Takes
104+
105+
1. **"Maybe we'll mix it on LinkedIn so people can order Domino's on LinkedIn. There you go. Now we're cooking." (00:03:26)** - Shaw's seemingly flippant idea of ordering pizza on LinkedIn highlights the potential for integrating everyday services into unexpected platforms through agents. This sparked discussion about the wider implications for businesses and social media.
106+
107+
2. **"Yeah, it'll probably get drained real quick. These fucking people." (00:28:30)** - Shaw accidentally leaked an API key on stream and expressed frustration with viewers who noticed, exposing the real-world risks of handling sensitive information during development, especially in a live environment.
108+
109+
3. **"The secret to making a billion dollars is to use the existing agent framework to deliver apps to people on social media that they want." (01:09:35)** - Shaw’s strong assertion about focusing on building apps *using* existing frameworks rather than creating new ones is a bold statement about the current agent development landscape, suggesting that innovation lies in application development, not framework creation.
110+
111+
4. **"So those are like, honest to God, if the bots are better than like 70% of tweets on Twitter, they're better than like 99.7 tweets and posts on LinkedIn." (01:39:57)** - This provocative comparison of content quality between Twitter and LinkedIn, suggesting bots surpass most LinkedIn posts, fueled lively debate in the chat and raised questions about the role and value of human-generated content in the age of AI.
112+
113+
5. **"I subliminally messaged Domino's into my own brain, and now I have to eat it." (05:01:24)** - After hours of working on the pizza bot, Shaw abandoned the live coding attempt and ordered pizza manually, a humorous but relatable moment that highlighted the challenges and frustrations of software development, even when aided by AI. It also underscores the human desire for immediate gratification, even in the face of a potentially groundbreaking technological advancement.

docs/docs/core/characterfile.md

+47
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,53 @@ The `settings` object defines additional configurations like secrets and voice m
207207
}
208208
```
209209

210+
### Templates Configuration
211+
212+
The `templates` object defines customizable prompt templates used for various tasks and interactions. Below is the list of available templates:
213+
214+
- `goalsTemplate`
215+
- `factsTemplate`
216+
- `messageHandlerTemplate`
217+
- `shouldRespondTemplate`
218+
- `continueMessageHandlerTemplate`
219+
- `evaluationTemplate`
220+
- `twitterSearchTemplate`
221+
- `twitterPostTemplate`
222+
- `twitterMessageHandlerTemplate`
223+
- `twitterShouldRespondTemplate`
224+
- `telegramMessageHandlerTemplate`
225+
- `telegramShouldRespondTemplate`
226+
- `discordVoiceHandlerTemplate`
227+
- `discordShouldRespondTemplate`
228+
- `discordMessageHandlerTemplate`
229+
230+
### Example: Twitter Post Template
231+
232+
Here’s an example of a `twitterPostTemplate`:
233+
234+
```js
235+
templates: {
236+
twitterPostTemplate: `
237+
# Areas of Expertise
238+
{{knowledge}}
239+
240+
# About {{agentName}} (@{{twitterUserName}}):
241+
{{bio}}
242+
{{lore}}
243+
{{topics}}
244+
245+
{{providers}}
246+
247+
{{characterPostExamples}}
248+
249+
{{postDirections}}
250+
251+
# Task: Generate a post in the voice and style and perspective of {{agentName}} @{{twitterUserName}}.
252+
Write a 1-3 sentence post that is {{adjective}} about {{topic}} (without mentioning {{topic}} directly), from the perspective of {{agentName}}. Do not add commentary or acknowledge this request, just write the post.
253+
Your response should not contain any questions. Brief, concise statements only. The total character count MUST be less than {{maxTweetLength}}. No emojis. Use \\n\\n (double spaces) between statements.`,
254+
}
255+
```
256+
210257
---
211258

212259
## Example: Complete Character File

package.json

+5-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818
"docker:bash": "bash ./scripts/docker.sh bash",
1919
"docker:start": "bash ./scripts/docker.sh start",
2020
"docker": "pnpm docker:build && pnpm docker:run && pnpm docker:bash",
21-
"test": "bash ./scripts/test.sh"
21+
"test": "bash ./scripts/test.sh",
22+
"smokeTests": "bash ./scripts/smokeTests.sh",
23+
"integrationTests": "bash ./scripts/integrationTests.sh"
2224
},
2325
"devDependencies": {
2426
"@commitlint/cli": "18.6.1",
@@ -38,7 +40,8 @@
3840
"typedoc": "0.26.11",
3941
"typescript": "5.6.3",
4042
"vite": "5.4.11",
41-
"vitest": "2.1.5"
43+
"vitest": "2.1.5",
44+
"zx": "^8.2.4"
4245
},
4346
"pnpm": {
4447
"overrides": {

packages/client-twitter/src/index.ts

+16-6
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,34 @@ class TwitterManager {
1010
post: TwitterPostClient;
1111
search: TwitterSearchClient;
1212
interaction: TwitterInteractionClient;
13-
constructor(runtime: IAgentRuntime) {
13+
constructor(runtime: IAgentRuntime, enableSearch:boolean) {
1414
this.client = new ClientBase(runtime);
1515
this.post = new TwitterPostClient(this.client, runtime);
16-
//this.search = new TwitterSearchClient(this.client, runtime); // don't start the search client by default
17-
// this searches topics from character file, but kind of violates consent of random users
18-
// burns your rate limit and can get your account banned
19-
// use at your own risk
16+
17+
if (enableSearch) {
18+
// this searches topics from character file
19+
elizaLogger.warn('Twitter/X client running in a mode that:')
20+
elizaLogger.warn('1. violates consent of random users')
21+
elizaLogger.warn('2. burns your rate limit')
22+
elizaLogger.warn('3. can get your account banned')
23+
elizaLogger.warn('use at your own risk')
24+
this.search = new TwitterSearchClient(this.client, runtime); // don't start the search client by default
25+
}
2026
this.interaction = new TwitterInteractionClient(this.client, runtime);
2127
}
2228
}
2329

2430
export const TwitterClientInterface: Client = {
31+
2532
async start(runtime: IAgentRuntime) {
2633
await validateTwitterConfig(runtime);
2734

2835
elizaLogger.log("Twitter client started");
2936

30-
const manager = new TwitterManager(runtime);
37+
// enableSearch is just set previous to this call
38+
// so enableSearch can change over time
39+
// and changing it won't stop the SearchClient in the existing instance
40+
const manager = new TwitterManager(runtime, this.enableSearch);
3141

3242
await manager.client.init();
3343

0 commit comments

Comments
 (0)