<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Gabey</title>
        <link>https://paragraph.com/@gabey</link>
        <description>Web3 Developer &amp; Entrepreneur | Building decentralized futures
Co-founder of Echo Bot and Dev at Sunflyers NFT</description>
        <lastBuildDate>Fri, 17 Apr 2026 20:51:13 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <image>
            <title>Gabey</title>
            <url>https://storage.googleapis.com/papyrus_images/6b3c392e0fb6642c6b98bd791f41db0b6b198b698d865ecdd89479725507d618.png</url>
            <link>https://paragraph.com/@gabey</link>
        </image>
        <copyright>All rights reserved</copyright>
        <item>
            <title><![CDATA[Eliza Simplified: A Modern Bun-based Architecture Guide]]></title>
            <link>https://paragraph.com/@gabey/eliza-simplified-a-modern-bun-based-architecture-guide</link>
            <guid>FIhrhTX9582sqLKtmQ8O</guid>
            <pubDate>Tue, 18 Mar 2025 07:50:42 GMT</pubDate>
            <description><![CDATA[It took me longer than I expected to write another blog post as I got extremely busy participating in all the hackathons possible. The good thing is that I got to deepen my skills using Eliza and I&apos;ve now figured out how to bootstrap a simple project with it. The recommended way from Eliza is to use their starter repo but I still found that repo extremely confusing and bloated for nothing. I believe that’s a recuring issue with Eliza, the team seem to want to have the project be as turnk...]]></description>
            <content:encoded><![CDATA[<p>It took me longer than I expected to write another blog post as I got extremely busy participating in <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://safe-agents.devfolio.co/">all</a> the <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://dorahacks.io/hackathon/sonic-defai-hackathon/prizes">hackathons</a> <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://dorahacks.io/hackathon/injective-ai/detail">possible</a>. The good thing is that I got to deepen my skills using Eliza and I&apos;ve now figured out how to bootstrap a simple project with it.</p><p>The recommended way from Eliza is to use their <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/elizaOS/eliza-starter">starter repo</a> but I still found that repo extremely confusing and bloated for nothing. I believe that’s a recuring issue with Eliza, the team seem to want to have the project be as turnkey as possible to the detriment of cleaner, simpler code, but I disgress.</p><p>For this blog post, refer to my <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/GabrielCartier/eliza-bootstrap">Github project</a> to get the basics of the architecture. This project is Eliza stripped down to what’s really needed (in my opinion) and structured in a way that makes sense (again, in my opinion).</p><blockquote><p>Note that the repo only has a dev method, I’ll make a post to deploy it.</p></blockquote><h2 id="h-bun-monorepo" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Bun monorepo</h2><p>First of all, as you can see, I’ve used bun monorepo to split the backend/frontend logic. That is much different than the Eliza Starter repo or even the Eliza Core repo where they actually define the frontend as a client within the Eliza project. In my opinion, having the client in your Eliza project is not a good separation of concern. Eliza is simply a backend and should be treated like so. If we wanted to make the architecture bigger, we could have a project for types so that we can share it within the projects.</p><figure float="none" data-type="figure" class="img-center" style="max-width: null;"><img src="https://storage.googleapis.com/papyrus_images/a4225eff836b7d45303a1da6c9720bb09549615803cdabf12b7af5002ced6726.png" alt="Simplified architecture" blurdataurl="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=" nextheight="600" nextwidth="800" class="image-node embed"><figcaption HTMLAttributes="[object Object]" class="">Simplified architecture</figcaption></figure><h1 id="h-now-on-to-eliza" class="text-4xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Now on to Eliza</h1><p>Everything starts with the <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/GabrielCartier/eliza-bootstrap/blob/main/backend/src/eliza/index.ts">index.ts file</a> in <code>backend/eliza</code> . The file is relatively simple but does a few different things. The entry point is the <code>startAgents</code> function, which will begin by adding clients. <em>Clients</em> in Eliza are basically entry points to your app. Typically, it would be an API, you can also add a Chat feature if you want, but I got rid of it as it felt useless since it was just a wrapper to make API calls. Now the API, Eliza comes with a <em>DirectClient</em> which is essentially an API to connect to your agent. I didn’t want to use the built-in one because it has tons of routes I don’t need and I also wanted to have the liberty to add my own routes and manage them the way I wanted. Using the <em>DirectClient</em> and then extending it wasn’t a solution I liked, so I completely rewrote it and while at it, I chose <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://elysiajs.com/">Elysia</a> over the built-in DirectClient for several reasons:</p><ul><li><p>Better performance (it&apos;s built on top of Bun)</p></li><li><p>More flexible routing system</p></li><li><p>Easier to extend with custom endpoints</p></li><li><p>Better TypeScript support</p></li></ul><h2 id="h-understanding-the-agent-lifecycle" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Understanding the Agent Lifecycle</h2><p>One crucial aspect of Eliza that deserves a deeper explanation is the agent lifecycle. While it might seem complex at first, it follows a straightforward pattern:</p><ol><li><p><strong>Database Initialization</strong></p><ul><li><p>The first step is setting up the database connection. I opted for Postgres (via Supabase) instead of SQLite:</p></li></ul><pre data-type="codeBlock" text="const db = new PostgresDatabaseAdapter({
  connectionString: process.env.POSTGRES_URL,
  parseInputs: true
});
await db.init();
"><code>const db <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> PostgresDatabaseAdapter({
  connectionString: process.env.POSTGRES_URL,
  parseInputs: <span class="hljs-literal">true</span>
});
await db.init();
</code></pre></li><li><p><strong>Agent Runtime Creation</strong></p><ul><li><p>Each agent gets its own runtime, which is the core of Eliza&apos;s architecture</p></li><li><p>The runtime manages the agent&apos;s state, handles message processing, and coordinates between different components</p></li></ul><pre data-type="codeBlock" text="const runtime = new AgentRuntime({
  databaseAdapter: db,
  token,          // API token for the model provider
  modelProvider,   // Which LLM to use
  character,      // Agent&apos;s personality and behavior
  plugins: [],    // Optional plugins for extended functionality
  cacheManager    // Handles caching of conversations and state
});
"><code><span class="hljs-type">const</span> runtime = <span class="hljs-keyword">new</span> <span class="hljs-built_in">AgentRuntime</span>({
  databaseAdapter: db,
  token,          <span class="hljs-comment">// API token for the model provider</span>
  modelProvider,   <span class="hljs-comment">// Which LLM to use</span>
  character,      <span class="hljs-comment">// Agent's personality and behavior</span>
  plugins: [],    <span class="hljs-comment">// Optional plugins for extended functionality</span>
  cacheManager    <span class="hljs-comment">// Handles caching of conversations and state</span>
});
</code></pre></li><li><p><strong>Client Registration</strong></p><ul><li><p>After initialization, the agent needs ways to communicate</p></li><li><p>In my implementation, I use a custom Elysia-based API client instead of Eliza&apos;s built-in DirectClient</p></li><li><p>The API client gets registered with the runtime and can then handle incoming requests</p></li></ul><pre data-type="codeBlock" text="runtime.clients = await initializeClients(character, runtime);
directClient.registerAgent(runtime);
"><code>runtime.clients <span class="hljs-operator">=</span> await initializeClients(character, runtime);
directClient.registerAgent(runtime);
</code></pre></li><li><p><strong>Graceful Shutdown</strong></p><ul><li><p>Often overlooked but crucial for production deployments</p></li><li><p>My implementation handles SIGINT and SIGTERM signals</p></li><li><p>Ensures proper cleanup of database connections and server shutdown</p></li></ul><pre data-type="codeBlock" text="const shutdown = async () =&gt; {
  await directClient.server.close();
  await db.close();
};
"><code>const shutdown <span class="hljs-operator">=</span> async () <span class="hljs-operator">=</span><span class="hljs-operator">></span> {
  await directClient.server.close();
  await db.close();
};
</code></pre></li></ol><h2 id="h-the-backend" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">The backend</h2><p>As you can see, the backend resides in the <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/GabrielCartier/eliza-bootstrap/blob/main/backend/src/api/api.ts">api.ts</a> file and really just sets up the routes for our app. In this case, the only app we have is the message handler. I then split the logic of handling the request in a controller (message-controller.ts), the controller then uses a service to execute the logic (message-service.ts). This is a pretty standard API logic architecture and gives us the flexibility we need. Going through this simple refactoring also allowed me to understand exactly what is happening when a message is sent. I will cover this in a later blog post (spoiler, it’s easier than you think), but you can see all the code if you want here. The only thing that is important to follow here is the <code>start</code> and <code>stop</code> function for the client, rest is not used within the framework.</p><h2 id="h-databasecache" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Database/cache</h2><p>Once the API client is started, it will be distributed and added to every specific agent. One important part of this is the Database and cache manager. For the cache manager, you can simply use the CacheManager from Eliza. I haven’t looked into it much, but it did what I wanted it to do. Perhaps there are optimizations to be done there, but didn’t run into limitations. For Database, Eliza recommends SQLite for testing and Postgres for prod. I ran into issues using SQLite with Bun so I just resorted to using Postgres. I use Supabase, even though Eliza has a plugin for it, I use the Postgres adapter from core as the plugin was not working properly, and I didn’t want to figure out why.</p><h2 id="h-tieing-it-all-together" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Tieing it all together</h2><p>As you can see, the project in its current form is extremely simple and that’s what I wanted it to be. I wanted to understand exactly what everything does and why, and I felt like the examples or the starter repo were completely bloated. Building this simpler version also allowed me to understand exactly how the framework works.</p><p>Simply put, every agent will start its own AgentRuntime based on the <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://github.com/GabrielCartier/eliza-bootstrap/blob/main/backend/src/eliza/character.ts">character definition file</a>.</p><h3 id="h-character-configuration" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Character Configuration</h3><p>Characters in Eliza define the personality and behavior of your agent. Here&apos;s a simplified example:</p><pre data-type="codeBlock" text="// eliza/character.ts
export const character: Character = {
  name: &apos;MyAgent&apos;,
  modelProvider: &apos;openai&apos;,
  personality: {
    traits: [&apos;helpful&apos;, &apos;friendly&apos;],
    background: &apos;An AI assistant focused on...&apos;
  },
  // Other configuration options
};
"><code><span class="hljs-comment">// eliza/character.ts</span>
<span class="hljs-keyword">export</span> <span class="hljs-type">const</span> character: Character = {
  name: <span class="hljs-string">'MyAgent'</span>,
  modelProvider: <span class="hljs-string">'openai'</span>,
  personality: {
    traits: [<span class="hljs-string">'helpful'</span>, <span class="hljs-string">'friendly'</span>],
    background: <span class="hljs-string">'An AI assistant focused on...'</span>
  },
  <span class="hljs-comment">// Other configuration options</span>
};
</code></pre><p>In our case, we kept it very simple with a single character with no plugin or client (will cover that in another post), but the important thing to note here is that you can run multiple agents at the same time, they will have their own AgentRuntime which allows every agent to do its own thing. They will typically all share a client to contact them (our API), but can also have their own clients (think Twitter, Telegram, etc.). They will all have their own plugins and actions too.</p><h2 id="h-resource-sharing-and-configuration" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Resource Sharing and Configuration</h2><p>One important aspect to note is how resources are shared between agents. While each agent has its own runtime:</p><ul><li><p>Database connections are pooled and shared</p></li><li><p>The API server handles requests for all agents (it basically reaches the proper agent based on the request)</p></li><li><p>Cache can be configured to be either shared or isolated</p></li><li><p>Plugins and other clients are on a per-agent basis (defined in the Character file)</p></li></ul><h2 id="h-wrapping-it-up" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Wrapping it up</h2><p>I think going through a refactoring and cleaning of the code from the Eliza Core allowed me to fully wrap my head around the architecture and how it works. Even though the Eliza documentation is quite extensive, it feels like a lot of the key elements are barely explained and the starter project felt so bloated it was a bit hard to understand the different moving parts. I also feel like the team is not fully exploiting the power of Typescript for some parts of the project and could really benefit from this.</p><p>As usual, feel free to reach out if you have any questions!</p>]]></content:encoded>
            <author>gabey@newsletter.paragraph.com (Gabey)</author>
            <enclosure url="https://storage.googleapis.com/papyrus_images/c1c4831cd39ee3fa99b766a7628e32074f352194be1911cf12f46760fa1268b6.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Breaking Down AI Agents on Blockchain: A Developer's Journey]]></title>
            <link>https://paragraph.com/@gabey/breaking-down-ai-agents-on-blockchain-a-developer-s-journey</link>
            <guid>SKQo32CWpusr1VHVqOzM</guid>
            <pubDate>Tue, 18 Feb 2025 16:12:55 GMT</pubDate>
            <description><![CDATA[As a blockchain developer with 5 years of experience, I&apos;ve witnessed the incredible evolution of Web3 technology. Today, I&apos;m starting a new adventure that combines my blockchain expertise with one of the most exciting emerging technologies: AI agents.Why This Blog Series?Even though AI saw its breakthrough moment a while ago with OpenAI, it&apos;s only been quite recently that it has experienced exponential growth on the blockchain. With the rise of Eliza, it seems clear that we&apo...]]></description>
            <content:encoded><![CDATA[<p>As a blockchain developer with 5 years of experience, I&apos;ve witnessed the incredible evolution of Web3 technology. Today, I&apos;m starting a new adventure that combines my blockchain expertise with one of the most exciting emerging technologies: AI agents.</p><h2 id="h-why-this-blog-series" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Why This Blog Series?</h2><p>Even though AI saw its breakthrough moment a while ago with OpenAI, it&apos;s only been quite recently that it has experienced exponential growth on the blockchain. With the rise of <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://elizaos.github.io/eliza/">Eliza</a>, it seems clear that we&apos;re only scratching the surface of the capabilities that AI and blockchain can offer together.</p><p>With all this hype, there have <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://ethglobal.com/events/agents">been</a> <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://dorahacks.io/hackathon/sonic-defai-hackathon/prizes">tons</a> <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://sui.io/sui-agent-typhoon">of</a> <a target="_blank" rel="noopener noreferrer nofollow ugc" class="dont-break-out" href="https://safe-agents.devfolio.co/">hackathons</a> focusing on AI Agents, and I decided to join some to deepen my knowledge in AI.</p><p>While developing my hackathon projects, I noticed a significant gap in the documentation. Despite the growing number of powerful frameworks, finding practical, hands-on guidance remains challenging. Documentation exists, but the path from concept to implementation isn&apos;t always clear. There are also several tools out there and choosing which one is the right one for you is not easy.</p><p>That&apos;s where this blog series comes in. I&apos;m documenting my journey of exploration, sharing both successes and challenges, to help other developers navigate this exciting but complex landscape.</p><h2 id="h-what-to-expect" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">What to Expect</h2><p>This series will focus on practical implementations and real-world applications. As I explore various frameworks (with a particular focus on ElizaOS), I&apos;ll share:</p><ul><li><p>Step-by-step tutorials for building AI agents on blockchain</p></li><li><p>Comparisons of different frameworks and their use cases</p></li><li><p>Common pitfalls and how to avoid them</p></li><li><p>Best practices for integrating AI capabilities with blockchain systems</p></li></ul><h2 id="h-my-background-and-approach" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">My Background and Approach</h2><p>While I bring years of blockchain development experience to the table, I&apos;m approaching AI with fresh eyes. This perspective allows me to bridge the gap between experienced blockchain developers and the emerging world of AI agents. I believe this combination makes for a unique learning opportunity – we&apos;ll tackle these technologies together, grounding advanced concepts in practical applications.</p><h2 id="h-coming-up-next" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Coming Up Next</h2><p>In the following posts, we&apos;ll dive into specific frameworks, starting with a comprehensive look at ElizaOS. We&apos;ll build real projects together, explore different tools, and discover how to create meaningful applications that leverage both blockchain and AI capabilities.</p><p>Whether you&apos;re a seasoned blockchain developer curious about AI, or an AI enthusiast looking to understand blockchain integration, this series aims to provide valuable insights and practical guidance.</p><p>Let&apos;s embark on this journey together.</p>]]></content:encoded>
            <author>gabey@newsletter.paragraph.com (Gabey)</author>
            <enclosure url="https://storage.googleapis.com/papyrus_images/4c49533c74d30cf7490fb9ca9f923bc9923a8c154b796c4693c3a62d2d355068.jpg" length="0" type="image/jpg"/>
        </item>
    </channel>
</rss>