<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: abisoyeo</title>
    <description>The latest articles on DEV Community by abisoyeo (@abisoyeo).</description>
    <link>https://dev.to/abisoyeo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1113107%2Fe63dbe9d-7f69-4ad5-a86e-54560ddae8e7.png</url>
      <title>DEV Community: abisoyeo</title>
      <link>https://dev.to/abisoyeo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/abisoyeo"/>
    <language>en</language>
    <item>
      <title>HNG Internship Stage 1: String Analyzer API</title>
      <dc:creator>abisoyeo</dc:creator>
      <pubDate>Mon, 03 Nov 2025 18:16:36 +0000</pubDate>
      <link>https://dev.to/abisoyeo/hng-internship-stage-1-string-analyzer-api-286</link>
      <guid>https://dev.to/abisoyeo/hng-internship-stage-1-string-analyzer-api-286</guid>
      <description>&lt;p&gt;For the second task in the &lt;strong&gt;HNG Internship&lt;/strong&gt;, I had to build a string analysis API. The brief was simple: create a RESTful API that analyses strings, computes their properties, and stores everything in a database. It sounded straightforward at first, but it ended up being a really good exercise in backend logic, data modelling, and thinking through how users might actually query the data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting Started
&lt;/h3&gt;

&lt;p&gt;I went with &lt;strong&gt;Node.js&lt;/strong&gt; and &lt;strong&gt;Express&lt;/strong&gt; for the backend, paired with &lt;strong&gt;MongoDB&lt;/strong&gt; through &lt;strong&gt;Mongoose&lt;/strong&gt;. To keep things flexible, I used &lt;strong&gt;dotenv&lt;/strong&gt; for environment variables and added &lt;strong&gt;express-rate-limit&lt;/strong&gt; to prevent the API from being hammered with too many requests. I kept the string analysis logic modular, which made everything easier to maintain and extend down the line.&lt;/p&gt;

&lt;p&gt;The main &lt;code&gt;/strings&lt;/code&gt; endpoint does most of the heavy lifting. When you send it a string, it computes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;length&lt;/code&gt; (including spaces)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;is_palindrome&lt;/code&gt; (ignoring case)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;unique_characters&lt;/code&gt; count&lt;/li&gt;
&lt;li&gt;&lt;code&gt;word_count&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sha256_hash&lt;/code&gt; for unique identification&lt;/li&gt;
&lt;li&gt;&lt;code&gt;character_frequency_map&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After analysing the string, everything gets saved to MongoDB with a timestamp. This makes it easy to filter, retrieve, or delete strings later.&lt;/p&gt;

&lt;h3&gt;
  
  
  What the API Can Do
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. POST /strings – Analyse and store a string&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This endpoint validates the input, checks if the string already exists using its &lt;code&gt;sha256_hash&lt;/code&gt;, and returns a clean JSON response with all the computed properties.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. GET /strings – Retrieve strings with filters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can filter by palindrome status, length range, word count, or even check if a string contains a specific character. It's pretty flexible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. GET /strings/filter-by-natural-language – Query using plain language&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This was probably the most interesting part to build. Instead of wrestling with query parameters, you can just ask for something like &lt;code&gt;"all single word palindromic strings"&lt;/code&gt; or &lt;code&gt;"strings containing the letter z"&lt;/code&gt;, and the API figures out what you mean.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. GET /strings/:value – Fetch a specific string&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pass in the original string value, and you'll get back the full analysis if it exists.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. DELETE /strings/:value – Remove a string&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pretty self-explanatory, deletes the string from the database if you don't need it anymore.&lt;/p&gt;

&lt;h3&gt;
  
  
  What I Learned Along the Way
&lt;/h3&gt;

&lt;p&gt;One thing I had to think carefully about was &lt;strong&gt;data consistency&lt;/strong&gt;. Using a &lt;code&gt;sha256&lt;/code&gt; hash for each string was crucial, it guaranteed that the same string couldn't be added twice, even if someone tried submitting it multiple times.&lt;/p&gt;

&lt;p&gt;The natural language parser was fun to build. It's not perfect, but it does a decent job of turning conversational queries into structured database filters. Testing it actually made working on the API more enjoyable.&lt;/p&gt;

&lt;p&gt;I also spent time making sure the error handling was solid. Every endpoint returns clear, consistent HTTP status codes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;400&lt;/code&gt; for malformed requests&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;404&lt;/code&gt; when a string doesn't exist&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;409&lt;/code&gt; when someone tries to add a duplicate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It keeps things predictable and makes the API easier to work with, whether you're building a frontend or just testing with Postman.&lt;/p&gt;

&lt;h3&gt;
  
  
  Takeaways
&lt;/h3&gt;

&lt;p&gt;This task really drove home some important backend principles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep your endpoints modular and maintainable&lt;/li&gt;
&lt;li&gt;Always validate and sanitize user input&lt;/li&gt;
&lt;li&gt;Handle database operations carefully&lt;/li&gt;
&lt;li&gt;Sometimes the best UX is just letting users describe what they want in plain language&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I also realized how much small design choices matter. Things like hashing strings for uniqueness or building flexible query filters might seem minor, but they make a huge difference in how robust and user-friendly the API ends up being.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example Response
&lt;/h3&gt;

&lt;p&gt;Here's what you get back when you submit a string for analysis:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"racecar"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"length"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"is_palindrome"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"unique_characters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"word_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"sha256_hash"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"character_frequency_map"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"r"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"a"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"c"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"e"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"created_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025-08-27T10:00:00Z"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Wrapping Up
&lt;/h3&gt;

&lt;p&gt;Stage 1 felt like a step up from Stage 0. It wasn't just about building endpoints anymore, it was about thinking through &lt;strong&gt;data integrity, query flexibility, and making the API genuinely easy to use&lt;/strong&gt;. It's kind of funny how something as simple as analysing strings can get surprisingly complex when you factor in storage, retrieval, and letting users filter the data however they want.&lt;/p&gt;

&lt;p&gt;The API feels solid now, and it's a good foundation for more advanced backend work. Plus, seeing it handle complex queries with clean, consistent responses was pretty satisfying.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>node</category>
      <category>api</category>
      <category>backend</category>
    </item>
    <item>
      <title>Building AI Co-workers That Actually Think With You</title>
      <dc:creator>abisoyeo</dc:creator>
      <pubDate>Mon, 03 Nov 2025 18:15:41 +0000</pubDate>
      <link>https://dev.to/abisoyeo/building-ai-co-workers-that-actually-think-with-you-bee</link>
      <guid>https://dev.to/abisoyeo/building-ai-co-workers-that-actually-think-with-you-bee</guid>
      <description>&lt;p&gt;I've been working on something that started simple and turned into something more interesting than I expected.&lt;/p&gt;

&lt;p&gt;It began with a text summarizer. You know the kind: paste in a long article, get back the main points. Useful, but not exactly revolutionary. The goal was to build it as an agent using Mastra (a TypeScript agent framework), deploy it, and connect it to Telex.im (an AI agent platform like n8n, but designed as a Slack alternative for communities and bootcamps) as an AI coworker. Clean, straightforward, done.&lt;/p&gt;

&lt;p&gt;But then I kept thinking about what else an agent could do if it wasn't just processing text in one shot. What if it could actually think through problems with you? Not just answer questions, but ask them back. Help you see angles you hadn't considered. Act less like a tool and more like someone you'd grab coffee with to talk through a decision.&lt;/p&gt;

&lt;p&gt;That's how the Strategic Advisor agent happened.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Built This: The Complete Process
&lt;/h2&gt;

&lt;p&gt;Let me walk you through exactly how I went from idea to deployed AI coworker.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Setting Up Mastra
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz0cr7xpssakwc8z7c98r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz0cr7xpssakwc8z7c98r.png" alt="Mastra's CLI setup - from zero to agent framework in under a minute" width="800" height="399"&gt;&lt;/a&gt;  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Mastra's CLI setup — from zero to agent framework in under a minute&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I started by creating a new folder for the project and opening it in Visual Studio Code. Then I installed Mastra:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm create mastra@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The CLI walked me through setup with a few simple prompts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Project name&lt;/li&gt;
&lt;li&gt;Default AI provider (I chose Google)&lt;/li&gt;
&lt;li&gt;API key for Google Generative AI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In under a minute, Mastra had created the entire project structure, installed dependencies, and initialized everything I needed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1f5fz9lclkq1l44nl29v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1f5fz9lclkq1l44nl29v.png" alt="_*Clean project structure generated by Mastra - everything organized and ready to go*_&amp;lt;br&amp;gt;
" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;em&gt;Clean project structure generated by Mastra - everything organized and ready to go&lt;/em&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What I love about Mastra is how it handles the boring infrastructure so you can focus on agent logic. It gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Agent orchestration&lt;/strong&gt; - the core framework for building conversational agents with personality&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory management using LibSQLStore&lt;/strong&gt; - persistent conversation history that survives restarts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A2A API routes&lt;/strong&gt; - JSON-RPC 2.0 compliant endpoints automatically generated&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Development server with hot reload&lt;/strong&gt; for instant testing&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Step 2: Building the Summarizer Agent
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmdxcgqwc780o3lnur5kw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmdxcgqwc780o3lnur5kw.png" alt="*The complete summarizer agent - just 31 lines of code for production-ready text summarization*&amp;lt;br&amp;gt;
" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The complete summarizer agent - just 31 lines of code for production-ready text summarization&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I created my first agent in the agents folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;summarizerAgent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Text Summarizer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;instructions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
    You are an expert summarization assistant.

    Main Idea: (A single sentence capturing the core thesis)
    Key Points: (2-3 bullet points with supporting details)
  `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;google/gemini-2.5-flash&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
  &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Memory&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;LibSQLStore&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;file:../mastra.db&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After creating the agent, I registered it inside my main index.ts so Mastra could recognize and run it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mastra&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Mastra&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;agents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;summarizerAgent&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;LibSQLStore&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;file:../mastra.db&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;....&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures the agent is available to the Mastra runtime and ready for deployment.&lt;/p&gt;

&lt;p&gt;The key Mastra features I'm using here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Agent class&lt;/strong&gt; - Mastra's core abstraction with built-in prompt management&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory with LibSQLStore&lt;/strong&gt; - persistent storage with zero configuration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model abstraction&lt;/strong&gt; - swap providers without changing code&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instruction templates&lt;/strong&gt; - clear prompts that define agent behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I tested it locally by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmyl66u5jakocuenggooc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmyl66u5jakocuenggooc.png" alt="_*Testing the summarizer in Mastra Studio - instant feedback on agent responses*_&amp;lt;br&amp;gt;
" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;em&gt;Testing the summarizer in Mastra Studio - instant feedback on agent responses&lt;/em&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The agent worked perfectly, taking long text and returning clean, structured summaries.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 3: Deploying to Mastra Cloud
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8wh93dztzuhs6xhhc614.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8wh93dztzuhs6xhhc614.png" alt="Create project on mastra" width="800" height="381"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To make this accessible from Telex, I needed to deploy it. Mastra Cloud made this dead simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Signed up at &lt;a href="https://cloud.mastra.ai" rel="noopener noreferrer"&gt;Mastra Cloud&lt;/a&gt; using my GitHub account&lt;/li&gt;
&lt;li&gt;Clicked "Create New Project"&lt;/li&gt;
&lt;li&gt;Selected the GitHub repository to deploy from&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm5pdrkzc5hghsqfe1ydj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm5pdrkzc5hghsqfe1ydj.png" alt=" " width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol start="4"&gt;
&lt;li&gt;Chose the branch and specified the root folder for my project&lt;/li&gt;
&lt;li&gt;Added the necessary environment variables (e.g., my Google API key)&lt;/li&gt;
&lt;li&gt;Clicked "Create Project" to finish setup&lt;/li&gt;
&lt;li&gt;After the project was created, went to the Deployments tab&lt;/li&gt;
&lt;li&gt;Enabled deployment to get the API URL&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Within minutes, my agent was live at:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://limited-gray-house-e6958.mastra.cloud/a2a/agent/summarizerAgent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The A2A endpoints were automatically generated by Mastra's routing system. I didn't write any API boilerplate - Mastra's &lt;code&gt;registerApiRoute&lt;/code&gt; function handles all the JSON-RPC 2.0 protocol details.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Creating the Strategic Advisor
&lt;/h3&gt;

&lt;p&gt;After the summarizer was working, I built the Strategic Advisor using the same Mastra patterns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;strategicAdvisorAgent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Strategic Advisor&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;instructions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
    You are a strategic business advisor...

    # Your Three Core Capabilities
    1. Competitor Snapshot Analysis
    2. Decision Support Engine
    3. Idea Feasibility Evaluator

    [Detailed instructions for each capability...]
  `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;google/gemini-2.5-flash&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
  &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Memory&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;LibSQLStore&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;file:../mastra.db&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both agents share the same LibSQLStore, which means they access the same conversation history database. This is powerful for future multi-agent workflows.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Integrating With Telex
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxvys05to0jp2knb62o2e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxvys05to0jp2knb62o2e.png" alt="Telex's AI Coworkers section - where agents become team members" width="800" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Telex's AI Coworkers section - where agents become team members&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now comes the fun part - turning these deployed agents into AI coworkers.&lt;/p&gt;

&lt;p&gt;I logged into Telex.im and navigated to the AI Coworkers section:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click "Add New AI Coworker"&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi3h8y7npt5grj8shp2s7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi3h8y7npt5grj8shp2s7.png" alt="Creating an AI coworker" width="800" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Creating an AI coworker - Telex even generates custom avatars&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Telex includes a built-in avatar picker which you can browse and select from a range of preset faces to represent your agents.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Fill in the details:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Name: "Text Summarizer" and "Strategic Advisor"&lt;/li&gt;
&lt;li&gt;Title: "Expert Summarization Specialist" and "Business Strategy &amp;amp; Decision Support Specialist"&lt;/li&gt;
&lt;li&gt;Description: Clear explanation of what each agent does&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the workflow JSON - This is where Mastra and Telex connect:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1ppg5ifteun68jhngzbt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1ppg5ifteun68jhngzbt.png" alt="Workflow configuration" width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Workflow configuration - pointing Telex to the deployed Mastra agent&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"active"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"category"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"custom-agents"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Delegates all strategic business analysis, competitor insights, decision support, and idea feasibility evaluation requests to the external Mastra strategic advisor agent."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"a7c9d3e2-5f8b-4a1c-9e2d-3fa8b6c4d9e1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"long_description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"You are a routing workflow for strategic business advisory tasks.&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;You delegate three types of requests to the Mastra Strategic Advisor Agent:&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;1. **Competitor Analysis** - When users ask about competitor insights, market positioning, or competitive landscape analysis&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;2. **Decision Support** - When users need help weighing options, evaluating trade-offs, or making strategic choices&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;3. **Idea Feasibility** - When users want to evaluate new business ideas, features, or initiatives before investing resources&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;You must never perform these analyses internally. Always route requests to the 'Strategic Advisor Agent Node' via its A2A endpoint and return its structured response.&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;The agent will engage in conversation with the user, asking clarifying questions as needed to gather context before providing:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;- Competitor snapshots with strengths/weaknesses&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;- Decision matrices with weighted factors&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;- Feasibility assessments with risk/opportunity analysis&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;Simply forward all strategic advisory requests to the Mastra agent node and relay its responses back to the user. Do not attempt to provide business advice, competitor analysis, or decision frameworks yourself."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"strategic_advisor_agent_delegate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"nodes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"c4e7f2a1-6d9b-4c3e-8f1d-5ba9c7e2d4f3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Strategic Advisor Agent Node"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"parameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"a2a/mastra-a2a-node"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"typeVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://limited-gray-house-e6958.mastra.cloud/a2a/agent/strategicAdvisorAgent"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"pinData"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"settings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"executionOrder"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"v1"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"short_description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Routes strategic business analysis and decision support tasks to the Mastra strategic advisor agent."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells Telex: "When someone messages this AI coworker, forward the request to this Mastra endpoint using the A2A protocol."&lt;/p&gt;

&lt;p&gt;That's it. The agents were live. Now I can engage either one in their specific agent chat.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Worked (and What Didn't)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What worked:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Mastra made the integration process feel effortless. The API routes worked right out of the box, and testing agents through them was straightforward. Swapping agents or endpoints took seconds; it felt like having a local playground for experimentation before deployment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What didn't:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Telex integration gave me more trouble than expected. The &lt;code&gt;workflow.json&lt;/code&gt; setup wasn't always consistent, and occasionally the Telex UI wouldn't update with responses from the A2A agent even though the backend call succeeded. These bugs were random and hard to reproduce, but they slowed things down a bit. Once configured, it worked, but getting there took some trial and error.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the Strategic Advisor Actually Does
&lt;/h2&gt;

&lt;p&gt;The Strategic Advisor has three core capabilities:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Competitor Analysis
&lt;/h3&gt;

&lt;p&gt;You tell it "analyze competitors for fintech salary-advance startups in Nigeria," and instead of generic advice, it asks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Give me 3-5 competitor names and what each does"&lt;/li&gt;
&lt;li&gt;"What's your differentiation?"&lt;/li&gt;
&lt;li&gt;"What customer segment are you targeting?"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then it builds you a structured breakdown with strengths/weaknesses tables, market positioning maps, and strategic gaps.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzda1m4r61owwsz5q4p32.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzda1m4r61owwsz5q4p32.png" alt="Structured competitor analysis" width="650" height="756"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Structured competitor analysis - clear insights instead of generic advice&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  2. Decision Support
&lt;/h3&gt;

&lt;p&gt;You say "should we raise seed funding now or wait 6 months?" and it asks what matters to you - speed, control, runway, risk tolerance. Then it builds a weighted decision matrix based on your priorities.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbzf40d1kvvc6oxr8fdlw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbzf40d1kvvc6oxr8fdlw.png" alt="Decision framework " width="800" height="395"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Caption: Decision framework tailored to your priorities, not generic startup advice&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  3. Idea Feasibility
&lt;/h3&gt;

&lt;p&gt;You say "I'm thinking of building a WhatsApp bot for team feedback," and it asks about target customers, pricing, and go-to-market. Then it evaluates market fit, complexity, monetization, and risk/opportunity ratio.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwprwo5wzhv9tjscj2rjh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwprwo5wzhv9tjscj2rjh.png" alt="Idea validation" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Idea validation before you invest time and resources&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Mastra Features That Made This Possible
&lt;/h2&gt;

&lt;p&gt;Let me highlight the specific Mastra capabilities that made this project smooth:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Agent Orchestration
&lt;/h3&gt;

&lt;p&gt;The Agent class handles prompt management, model selection, message history, and response generation. You define behavior through instructions - Mastra handles execution.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Memory Management
&lt;/h3&gt;

&lt;p&gt;LibSQLStore provides persistent conversation history with zero configuration. Both agents share the same database, enabling cross-session context and future multi-agent workflows.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. A2A API Routes
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;registerApiRoute&lt;/code&gt; automatically generates A2A-compliant endpoints. No API boilerplate needed - Mastra handles JSON-RPC 2.0 parsing, error handling, and response formatting.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Model Abstraction
&lt;/h3&gt;

&lt;p&gt;Swap &lt;code&gt;google/gemini-2.5-flash&lt;/code&gt; for &lt;code&gt;anthropic/claude-3&lt;/code&gt; or &lt;code&gt;openai/gpt-4&lt;/code&gt; without changing other code. Mastra normalizes the interface across providers.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Development Experience
&lt;/h3&gt;

&lt;p&gt;Hot-reload server and built-in Studio UI make testing instant. Iterate on prompts and see results in seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Conversation quality beats speed.&lt;/strong&gt; The advisor takes longer to respond, but when you're making real decisions you need good answers, not fast ones.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Asking questions is more valuable than giving answers.&lt;/strong&gt; The advisor's superpower isn't what it knows - it's what it asks. By forcing you to clarify what matters, it helps you see your own thinking more clearly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Specialization scales better than generalization.&lt;/strong&gt; Two focused agents beat one bloated agent. This is true in software, and it's true in AI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Standards reduce friction.&lt;/strong&gt; A2A compliance meant Telex integration took 10 minutes instead of 10 hours. Boring standards are good.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory turns tools into partners.&lt;/strong&gt; When agents remember context across sessions, people stop treating them like search engines and start treating them like collaborators.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frameworks like Mastra let you focus on what matters.&lt;/strong&gt; I spent 90% of my time on agent logic and 10% on infrastructure. That ratio is backwards in most AI projects.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;Right now both agents work well for what they do. But there are obvious next steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Streaming responses for the advisor, so you see it thinking in real-time&lt;/li&gt;
&lt;li&gt;Artifact generation - export decision matrices and reports&lt;/li&gt;
&lt;li&gt;Tool calling - let the advisor pull in real data when needed&lt;/li&gt;
&lt;li&gt;Multi-agent workflows - one agent delegating to another&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try It Yourself
&lt;/h2&gt;

&lt;p&gt;The code is open source on &lt;a href="https://github.com/abisoyeo/telex-agent" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;. If you want to build your own version, the &lt;a href="https://github.com/abisoyeo/telex-agent#" rel="noopener noreferrer"&gt;README &lt;/a&gt; has everything you need.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built with Mastra, deployed on Mastra Cloud, integrated with Telex.im.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Documentation Links&lt;/strong&gt;&lt;br&gt;
&lt;a href="//mastra.ai/docs/getting-started/installation"&gt;Mastra Docs&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.telex.im/docs/intro" rel="noopener noreferrer"&gt;Telex Docs&lt;/a&gt;&lt;/p&gt;

</description>
      <category>agents</category>
      <category>mastra</category>
      <category>typescript</category>
      <category>programming</category>
    </item>
    <item>
      <title>HNG Internship Stage 0: Building a Profile API with Cat Facts</title>
      <dc:creator>abisoyeo</dc:creator>
      <pubDate>Fri, 17 Oct 2025 22:50:52 +0000</pubDate>
      <link>https://dev.to/abisoyeo/hng-internship-stage-0-building-a-profile-api-with-cat-facts-58ak</link>
      <guid>https://dev.to/abisoyeo/hng-internship-stage-0-building-a-profile-api-with-cat-facts-58ak</guid>
      <description>&lt;p&gt;The first task for the HNG Internship was to build a simple RESTful API that returns my profile information along with a random cat fact. It sounds light, but it was a great way to test the fundamentals — consuming external APIs, structuring clean JSON responses, and handling dynamic data reliably.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Things Up
&lt;/h2&gt;

&lt;p&gt;I started by setting up a small Express server, keeping everything clean and modular. I added dotenv for environment variables and axios to handle HTTP requests. The goal was to make sure anyone could run the project locally without hardcoding personal info like my name, email, or stack.&lt;/p&gt;

&lt;p&gt;The /me endpoint was straightforward: return a JSON response with the required fields — status, user, timestamp, and fact. I made sure the timestamp updates dynamically with each request and followed the ISO 8601 format, so everything looks consistent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Integrating the Cat Facts API
&lt;/h2&gt;

&lt;p&gt;The fun part was fetching a random cat fact from the Cat Facts API. I used axios.get() to make a request inside the /me handler.&lt;/p&gt;

&lt;p&gt;Of course, real APIs don't always behave — so I added proper error handling and a fallback response just in case the external API fails. That way, the endpoint still returns a complete response even if the cat fact service goes down.&lt;/p&gt;

&lt;p&gt;To protect the endpoint, I also included basic rate limiting with express-rate-limit — it's good practice for any public API, no matter how small.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;p&gt;Even though it's a simple endpoint, this task reminded me how much polish goes into doing things right:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Writing clean, predictable responses&lt;/li&gt;
&lt;li&gt;Handling third-party API failures gracefully&lt;/li&gt;
&lt;li&gt;Using environment variables properly&lt;/li&gt;
&lt;li&gt;Keeping code readable and consistent for anyone who might review it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also reinforced something I value in backend development — clarity over complexity. Small details like proper timestamps or helpful error messages make a huge difference.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Final Output
&lt;/h2&gt;

&lt;p&gt;Each time you hit /me, you get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;My profile info (from environment variables)&lt;/li&gt;
&lt;li&gt;A fresh UTC timestamp&lt;/li&gt;
&lt;li&gt;A brand-new cat fact fetched in real time&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Sample Response
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"abisoyeogunmona@gmail.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Abisoye Ogunmona"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"stack"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Node.js/Express"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025-10-17T20:55:12.345Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"fact"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Cats sleep 70% of their lives."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;Stage 0 was a solid start to the internship — a reminder that even small tasks can sharpen your discipline as a developer. It's not about building something huge; it's about getting the fundamentals right and paying attention to the details that make your work feel complete.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>node</category>
      <category>api</category>
    </item>
  </channel>
</rss>
