<?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>Forem: Nik</title>
    <description>The latest articles on Forem by Nik (@nmaroulis21).</description>
    <link>https://forem.com/nmaroulis21</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%2F3631079%2F2ac6649d-434c-49c5-b48e-450c18313e2a.png</url>
      <title>Forem: Nik</title>
      <link>https://forem.com/nmaroulis21</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/nmaroulis21"/>
    <language>en</language>
    <item>
      <title>Your First Autonomous Agent Mesh – Easier Than You Think</title>
      <dc:creator>Nik</dc:creator>
      <pubDate>Mon, 04 May 2026 14:26:05 +0000</pubDate>
      <link>https://forem.com/nmaroulis21/your-first-autonomous-agent-mesh-easier-than-you-think-4p97</link>
      <guid>https://forem.com/nmaroulis21/your-first-autonomous-agent-mesh-easier-than-you-think-4p97</guid>
      <description>&lt;p&gt;In this guide we’ll build a Decentralized, Autonomous Vacation Booking System in Python using the &lt;a href="https://github.com/nMaroulis/protolink" rel="noopener noreferrer"&gt;Protolink&lt;/a&gt; library.&lt;/p&gt;

&lt;p&gt;The original post can be found on &lt;a href="https://levelup.gitconnected.com/your-first-autonomous-agent-mesh-easier-than-you-think-ce697b3dd87a" rel="noopener noreferrer"&gt;medium (Level-up-coding)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The landscape of AI agents is shifting. We are moving away from monolithic scripts driven by a single giant model, towards Multi-Agent Systems (MAS) where specialized, autonomous agents collaborate to solve complex problems.&lt;/p&gt;

&lt;p&gt;But today’s frameworks often trap you in a walled garden:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Locked into a specific LLM (OpenAI, Anthropic, etc.)&lt;/li&gt;
&lt;li&gt;Locked into a specific Transport for communication.&lt;/li&gt;
&lt;li&gt;Locked into a specific runtime (only runs in Python, or only in a specific cloud)&lt;/li&gt;
&lt;li&gt;Locked into specific Tooling schemes.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Agents are just functions, not independent entities.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Protolink&lt;/strong&gt; breaks away from this model &amp;amp; addresses these limitations directly.&lt;/p&gt;

&lt;p&gt;In Protolink, an Agent is an &lt;strong&gt;autonomous, centralized object&lt;/strong&gt; that serves as the core unit of your system. It is designed to be fully modular, so you can plug in any &lt;strong&gt;LLM, Tools, Transport, Storage, OpenTelemetry and Authentication&lt;/strong&gt; stack you need.&lt;/p&gt;

&lt;p&gt;Care only about the logic. Leave the communication, agent lifecycle, inference and tooling, authentication, memory and logging to Protolink.&lt;/p&gt;

&lt;p&gt;Protolink is based on &lt;a href="https://a2a-protocol.org/latest/" rel="noopener noreferrer"&gt;Google’s Agent-to-Agent (&lt;strong&gt;A2A&lt;/strong&gt;) Protocol&lt;/a&gt;. Unlike the base A2A specifications, Protolink enables more open and flexible communication: agents can call another agent’s &lt;strong&gt;LLM&lt;/strong&gt; for reasoning, invoke its &lt;strong&gt;Tools&lt;/strong&gt; directly or let the users define their own communication scheme. This allows for a flexible mesh where specialized agents can leverage each other’s native capabilities without rigid orchestration bottlenecks.&lt;/p&gt;

&lt;p&gt;In this post, we’ll build a 🏖️ &lt;strong&gt;Vacation Booking System&lt;/strong&gt; where four distinct agents collaborate to plan and book a trip to Greece, running entirely on your local machine or distributed across the cloud.&lt;/p&gt;

&lt;p&gt;The code provided below will be 100% runnable. The link to the github file for each script will also be provided.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Architecture: A Mesh of Specialists
&lt;/h2&gt;

&lt;p&gt;We will build a team of &lt;strong&gt;four agents&lt;/strong&gt;. Note that they don’t just “call” each other as functions; they communicate over HTTP using protolink’s standard agent_call protocol.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Coordinator Agent&lt;/strong&gt; (LLM + Tools): The user-facing orchestrator. It breaks down the user’s request and decides wether to delegate tasks to other agents.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Holiday Advisor&lt;/strong&gt; (LLM): A pure reasoning agent. It uses an LLM to evaluate destinations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Weather Agent&lt;/strong&gt; (Tools): A deterministic agent that provides weather forecasts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hotel Agent&lt;/strong&gt; (Tools): A deterministic agent that executes bookings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Registry&lt;/strong&gt;: The Registry is where the agents are registered so they can be discovered and discover other agents. In our example we’ll use an HTTP Transport for the Agent-to-Registry as well.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let’s install the library first (using pip or uv) and python version ≥ 3.11.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;protolink
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Instructions:
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Note 1:
&lt;/h3&gt;

&lt;p&gt;If you run the following code all in one file keep the code as is and just copy-paste it. Just make sure to include the code in an asynchronous method (async def) since the await doesn’t work in .&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;dotenv&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;load_dotenv&lt;/span&gt;

&lt;span class="nf"&gt;load_dotenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.env&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="n"&gt;CODE&lt;/span&gt; &lt;span class="n"&gt;HERE&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="bp"&gt;...&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to run each agent in a separate python script, please use the .start(&lt;strong&gt;blocking=True&lt;/strong&gt;) argument. This blocks the runtime and keeps the agent running even if the script ends. In case you run it in a jupyter notebook this is not needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Note 2:
&lt;/h3&gt;

&lt;p&gt;Please either set an .env file in the folder where the script(s) is contained, setting the variables for the LLM API key you’re going to use.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;
&lt;span class="py"&gt;ANTHROPIC_API_KEY&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;
&lt;span class="py"&gt;GEMINI_API_KEY&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;
&lt;span class="py"&gt;HF_API_TOKEN&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;
&lt;span class="py"&gt;OLLAMA_URL&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;
&lt;span class="py"&gt;OLLAMA_MODEL&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also set it in the constructor of the LLM e.g.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;protolink.llms.api&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AnthropicLLM&lt;/span&gt;

&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AnthropicLLM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;YOUR_API_KEY&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in the example I’ll use &lt;strong&gt;llm = OpenAILLM(model=”gpt-4o”)&lt;/strong&gt;, &lt;strong&gt;&lt;em&gt;feel free to replace it with the LLM of your choice&lt;/em&gt;&lt;/strong&gt;, currently supported by Protolink.&lt;/p&gt;

&lt;p&gt;protolink.llms.api: OpenAILLM, AnthropicLLM, GeminiLLM, DeepSeekLLM, GrokLLM&lt;/p&gt;

&lt;p&gt;protolink.llms.server: OllamaLLM&lt;/p&gt;

&lt;p&gt;protolink.llms.local: TBD&lt;/p&gt;

&lt;p&gt;You can also make your own LLM wrapper class, really easily, by just implementing the call and call_stream functions. The LLM base class can be found here prot&lt;a href="https://github.com/nMaroulis/protolink/blob/main/protolink/llms/base.py" rel="noopener noreferrer"&gt;olink/llms/base.py&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Let’s start the coding
&lt;/h3&gt;

&lt;p&gt;The complete code you’re about to see, can be found in this &lt;a href="https://github.com/nMaroulis/protolink/blob/main/examples/ticket_booking/quickstart.py" rel="noopener noreferrer"&gt;file&lt;/a&gt;. It includes every piece of code from this guide, in one python script. In the &lt;a href="https://github.com/nMaroulis/protolink/tree/main/examples/ticket_booking" rel="noopener noreferrer"&gt;project example folder&lt;/a&gt;, you may find all scripts as standalone, along with helper scripts.&lt;/p&gt;

&lt;p&gt;Before starting implementing our agents, let’s start the Registry so the Agents can discover their network.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;protolink.discovery&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Registry&lt;/span&gt;

&lt;span class="n"&gt;registry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Registry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;transport&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:9000&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Start the Registry simply by using .start()
&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s it!&lt;/p&gt;

&lt;p&gt;💡 When starting an Agent or the Registry using the HTTP Transport, a card written in HTTP/CSS/JS is automatically exposed in the &lt;strong&gt;/status&lt;/strong&gt; URI. So by starting the registry you can access in the browser at &lt;a href="http://localhost:9000/status" rel="noopener noreferrer"&gt;http://localhost:9000/status&lt;/a&gt; the card to see the overall status. See the following image.&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%2Fecv30jxb9atslzzqsbmn.webp" 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%2Fecv30jxb9atslzzqsbmn.webp" alt="Image Registry Status Card. Source: Image by the author." width="720" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a built-in functionality provided by protolink for monitoring.&lt;/p&gt;

&lt;p&gt;Let’s see a high-level architecture before continuing. All the agents communicate with the Registry in order to register themselves and get information about other agents in the network. Each Agent exposes its &lt;a href="https://github.com/nMaroulis/protolink/blob/main/protolink/core/agent_card.py" rel="noopener noreferrer"&gt;Agent Card&lt;/a&gt;, which contains info about it.&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%2Fy5ug9e3kol6vvfaxzslf.webp" 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%2Fy5ug9e3kol6vvfaxzslf.webp" alt="Image Example Architecture - Agent Mesh. Source: Image by the author." width="720" height="266"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let’s see a flowchart with the agent’s behavior in order to understand how the system works.&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%2Fn4alnvu6ybpoz5u3bhy4.webp" 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%2Fn4alnvu6ybpoz5u3bhy4.webp" alt="Image Agent Call Flowchart. Source: Image by the author." width="720" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It’s important to note that what the flowchart shows is how the agents are expected to act in our example. Since in Protolink, the Agents are &lt;strong&gt;autonomous entities&lt;/strong&gt;, an agent might decide to act differently (e.g. the coordinator agent doesn't call the weather agent) and this is the beauty of A2A, multiple Agents that collaborate to solve a Task autonomously, while also you as the programmer has the power to be as invasive as you want in the agent flow.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The Holiday Advisor: Pure Reasoning (LLM-Agnostic)
&lt;/h3&gt;

&lt;p&gt;This &lt;a href="https://github.com/nMaroulis/protolink/blob/main/examples/ticket_booking/holiday_advisor_agent.py" rel="noopener noreferrer"&gt;agent’s&lt;/a&gt; job is to think. It doesn’t need external tools. Protolink provides all necessary &lt;strong&gt;adapters&lt;/strong&gt; behind the scenes to ensure that whichever provider and model you choose (OpenAI API, Anthropic API, Gemini, Ollama, etc.) strictly complies with the system’s inference cycle and tool calling protocols.&lt;/p&gt;

&lt;p&gt;The system prompt we provide to the Agent and ultimately to its LLM needs to only define the &lt;strong&gt;role&lt;/strong&gt; and &lt;strong&gt;logic-specific instructions&lt;/strong&gt;. Agent &amp;amp; tool calling is handled by Protolink automatically, through &lt;strong&gt;predefined prompts&lt;/strong&gt; that are loaded automatically. Also the &lt;strong&gt;reasoning&lt;/strong&gt; logic and &lt;strong&gt;inference loop&lt;/strong&gt; are also built-in.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;protolink.agents&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;protolink.llms.api&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAILLM&lt;/span&gt;

&lt;span class="c1"&gt;# pass the key directly as an argument or leave empty to use environment variables
&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAILLM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-4o&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# The following prompt will be added to the existing predefined system prompt given by Protolink.
&lt;/span&gt;&lt;span class="n"&gt;ADVISOR_SYSTEM_PROMPT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;You are a Greek islands vacation expert. Your job is to evaluate
vacation destinations and provide recommendations.

When asked about a destination, consider:
1. Is this a good choice for the given dates?
2. Is the budget realistic for this destination?
3. Is it suitable for the number of travelers?
4. What are the highlights and potential concerns?

RESPONSE FORMAT:
Always provide a structured response with:
- verdict: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;recommended&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; or &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;not_recommended&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; or &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;consider_alternatives&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;
- destination: the evaluated location
- reasoning: 2-3 sentences explaining your verdict
- highlights: list of 2-3 things that make this destination great
- tips: 1-2 practical travel tips
- alternative: if not recommended, suggest ONE better option with a brief reason

Keep responses concise and helpful. You are the expert - be confident in your advice.
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

&lt;span class="n"&gt;agent_card&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;holiday_advisor&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;description&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Expert travel consultant who recommends destinations&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;url&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:8020&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;card&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;agent_card&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;transport&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;registry&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;registry_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:9000&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ADVISOR_SYSTEM_PROMPT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;verbosity&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just with &lt;code&gt;agent.start()&lt;/code&gt; the holiday advisor agent is now running and ready to receive requests. Since the &lt;strong&gt;transport&lt;/strong&gt; is set to “http”, the agent will be available at &lt;code&gt;http://localhost:8020&lt;/code&gt;. The agent’s address is defined in its Agent Card in the url field.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The agent is &lt;strong&gt;Transport-Agnostic&lt;/strong&gt;. If you want to use a different transport, you can set it to “websocket” or “grpc” and that’s it.&lt;/li&gt;
&lt;li&gt;The agent is &lt;strong&gt;LLM-Agnostic&lt;/strong&gt;. If you want to use a different LLM, you can just write e.g. llm = AnthropicLLM(model=”claude-3.5-sonnet-20240620") and that’s it.&lt;/li&gt;
&lt;li&gt;The agent can integrate &lt;strong&gt;tools&lt;/strong&gt; from other sources and make them native using adapters e.g. &lt;a href="https://github.com/nMaroulis/protolink/blob/main/protolink/tools/adapters/mcp_adapter.py" rel="noopener noreferrer"&gt;protolink.tools.adapters.MCPToolAdapter&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;In case tools are provided, the LLM knows automatically how to call them, since they’re handled by Protolink’s tool integration and pre-defined prompts that guide the LLM on how to perform tools calls.&lt;/li&gt;
&lt;li&gt;We’re setting verbosity to 2 which means the debug messages will also be shown, in order to see the Tasks received and sent for each agent.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Important Note&lt;/strong&gt;: Instructions on how to find and call other agents, agent tools or its native tools are not needed, as &lt;strong&gt;predefined prompts&lt;/strong&gt; are provided by default by protolink. You just define in the prompt the LLM &lt;strong&gt;logic&lt;/strong&gt; or &lt;strong&gt;role&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Weather Agent: Deterministic Tools
&lt;/h3&gt;

&lt;p&gt;Some agents don’t need an LLM. They are reliable workers. The &lt;a href="https://github.com/nMaroulis/protolink/blob/main/examples/ticket_booking/weather_agent.py" rel="noopener noreferrer"&gt;Weather Agent&lt;/a&gt; exposes a &lt;code&gt;get_weather&lt;/code&gt; tool. Protolink makes it easy to turn any Python function into a discoverable tool.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;protolink.agents&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;

&lt;span class="n"&gt;agent_card&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;weather_agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;description&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Weather forecast provider&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;url&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:8030&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;card&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;agent_card&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;transport&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;registry&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;registry_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:9000&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;verbosity&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Adding a tool to the agent using the tool decorator
&lt;/span&gt;&lt;span class="nd"&gt;@agent.tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;get_weather&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Get current weather forecast for a Greek island&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="c1"&gt;# The input and output schemas are automatically inferred by protolink, so this agent and also the others know how to call this tool.
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_weather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;travel_date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# Connects to real APIs, databases, or static data.
&lt;/span&gt;  &lt;span class="c1"&gt;# Now just provides dummy data
&lt;/span&gt;  &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;location&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;travel_date&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Summer season&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;temperature_celsius&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;condition&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Sunny&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;humidity_percent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wind&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;moderate&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;suitable_for_vacation&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;recommendation&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Perfect weather for a beach vacation!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;timestamp&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;isoformat&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;here’s the status card for the Weather Agent that can be found in &lt;a href="http://localhost:8030/status" rel="noopener noreferrer"&gt;http://localhost:8030/status&lt;/a&gt;. The &lt;strong&gt;skills&lt;/strong&gt; tab shows all the Agent’s &lt;strong&gt;Tools&lt;/strong&gt;.&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%2F8dux4oslj63l983rs5ro.webp" 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%2F8dux4oslj63l983rs5ro.webp" alt="Image Agent Status Card. Source: Image by the author." width="720" height="807"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. The Hotel Agent: State &amp;amp; Action
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://github.com/nMaroulis/protolink/blob/main/examples/ticket_booking/hotel_booking_agent.py" rel="noopener noreferrer"&gt;Hotel Agent&lt;/a&gt; defines a &lt;code&gt;book_hotel&lt;/code&gt; tool. In a real system, this would interact with a booking engine (Amadeus, Sabre) or a database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;card&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hotel_agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;description&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Searches and books hotel accommodations.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;url&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:8040&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="n"&gt;transport&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;registry&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;registry_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:9000&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;verbosity&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@agent.tool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;book_hotel&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Book a hotel for a vacation. Returns booking confirmation with details.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;book_hotel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;check_in&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;check_out&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;guests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;budget&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mid-range&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;check_in_date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromisoformat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;check_in&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;check_out_date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromisoformat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;check_out&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;nights&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;check_out_date&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;check_in_date&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;days&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;nights&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;  &lt;span class="c1"&gt;# Default
&lt;/span&gt;
    &lt;span class="n"&gt;total_price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;280&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;nights&lt;/span&gt;

    &lt;span class="c1"&gt;# Execute transaction
&lt;/span&gt;    &lt;span class="n"&gt;booking_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;confirmed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;booking_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;HTL-DAS98DA8D79D2JD9&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hotel&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Aegean Sunset Suites&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stars&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;location&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;title&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;amenities&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pool&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;spa&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;breakfast&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sea view&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;reservation&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;check_in&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;check_in&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;check_out&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;check_out&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;nights&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;nights&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;guests&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;guests&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;room_type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Double Room&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;guests&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Family Suite&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pricing&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;price_per_night&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;280&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;total_price&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;total_price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;currency&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;EUR&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;policies&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;check_in_time&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;15:00&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;check_out_time&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;11:00&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cancellation&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Free cancellation until 24h before check-in&lt;/span&gt;&lt;span class="sh"&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;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;confirmed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;booking_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;booking_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. The Coordinator: Orchestration &amp;amp; A2A
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;&lt;a href="https://github.com/nMaroulis/protolink/blob/main/examples/ticket_booking/coordinator_agent.py" rel="noopener noreferrer"&gt;Coordinator&lt;/a&gt;&lt;/strong&gt; is where the magic happens. It uses an LLM to orchestrate the others. Crucially, it doesn’t “know” the other agents hard-coded. It discovers them via the &lt;strong&gt;Registry&lt;/strong&gt; and uses the standard &lt;code&gt;agent_call&lt;/code&gt; capability.&lt;/p&gt;

&lt;p&gt;The Coordinator’s system prompt instructs it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;protolink.llms.api&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAILLM&lt;/span&gt;

&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAILLM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-4o&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;agent_card&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;coordinator&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;description&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Vacation booking coordinator that orchestrates specialist agents&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;url&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:8010&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# prompt the User can define in order to give a Role to the Agent
&lt;/span&gt;&lt;span class="n"&gt;COORDINATOR_SYSTEM_PROMPT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;You are a vacation booking coordinator.

Your role is to help users plan and book trips by orchestrating available specialist agents.
You will discover available agents dynamically - each agent has a description and capabilities
that tell you what it can do.

When handling a vacation request, follow this general workflow:
1. **Gather information**: Get travel advice and destination recommendations from advisory agents.
2. **Check conditions**: Verify weather, availability, or other relevant factors before booking.
3. **Make bookings**: Reserve accommodations, transportation, or other services as needed.
4. **Summarize**: Provide the user with a complete summary of their trip details.

Use your judgment to determine which agents to consult based on their descriptions and the user&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s needs.
If an agent has an LLM, ask it for advice. If an agent has tools, call those tools with appropriate parameters.
&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;card&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;agent_card&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;transport&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;registry&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;registry_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:9000&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;COORDINATOR_SYSTEM_PROMPT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;verbosity&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Protolink handles the routing, network request, and response parsing automatically.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You as the User only need to provide a complementary prompt to the Agent (later passed to the LLM), explaining the role and the logic. The agent/tool calling and final response generation is handled by protolink.&lt;/p&gt;

&lt;h4&gt;
  
  
  Our Agents in action
&lt;/h4&gt;

&lt;p&gt;Let’s ask a simple question and see how our network of agents operates in order to get the final answer. Let’s ask a generic question and let the agents figure out and book our vacations:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Book me a relaxing vacation to Santorini for 5 nights in mid-July 2026&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now let’s see how we can interact dynamically with any agent we want on our system. For this example we want to send a &lt;strong&gt;Task&lt;/strong&gt; to the Orchestrator agent with the previous User Query as the content. We will also specify in the Task that we want to invoke the Agent’s LLM for this task. From there and on the Agent will act autonomously, call other agents, tools etc.&lt;/p&gt;

&lt;p&gt;Before continuing let’s answer the following question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How does the LLM know how to call other agents’ LLMs or tools, call native tools, handle their outputs and return a final result?&lt;br&gt;
How does an agent, when receiving a Task, knows what to do ? (call its LLM or tools etc.) ?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Answer: It’s all handled by Protolink’s internal logic. A &lt;strong&gt;Task&lt;/strong&gt; is the top-level container that includes either a &lt;strong&gt;Message&lt;/strong&gt; or an &lt;strong&gt;Artifact&lt;/strong&gt; (as defined in the A2A specs). Each of these contains &lt;strong&gt;Parts&lt;/strong&gt;, the &lt;strong&gt;atomic units of action&lt;/strong&gt; that tell the agent exactly what to do.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;infer&lt;/code&gt;: Request another agent’s LLM to reason about a prompt and decide the next action.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;infer_output&lt;/code&gt;: The final response produced by the LLM after reasoning.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tool_call&lt;/code&gt;: Execute another agent’s specific tool with given arguments.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tool_output&lt;/code&gt;: Contains the result returned by a tool execution.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Running the System
&lt;/h4&gt;

&lt;p&gt;Let’s define the Task. Feel free to play around with the input user query and try other questions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;protolink.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;

&lt;span class="n"&gt;user_query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Book me a relaxing vacation to Santorini for 5 nights in mid-July 2026&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_infer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;user_query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The function &lt;strong&gt;Task.create_infer()&lt;/strong&gt; is a convenience factory method that creates a Task with an &lt;strong&gt;infer message part&lt;/strong&gt;. It tells the receiving agent to use its LLM to reason about the prompt.&lt;/p&gt;

&lt;p&gt;The command above creates a &lt;strong&gt;Task&lt;/strong&gt; that &lt;strong&gt;serializes&lt;/strong&gt; to:&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="err"&gt;“id”:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;“task_&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;f&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="err"&gt;b&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="err"&gt;c&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="err"&gt;d&lt;/span&gt;&lt;span class="mi"&gt;6e7&lt;/span&gt;&lt;span class="err"&gt;f&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="err"&gt;g”&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="err"&gt;“messages”:&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="err"&gt;“role”:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;“user”&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
     &lt;/span&gt;&lt;span class="err"&gt;“parts”:&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="err"&gt;“type”:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;“infer”&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
       &lt;/span&gt;&lt;span class="err"&gt;“prompt”:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;“Book&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;me&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;relaxing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;vacation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Santorini&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;nights&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;mid-July&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2026&lt;/span&gt;&lt;span class="err"&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="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="err"&gt;“status”:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;“pending”&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;What is seen above is what will be sent over the wire to the other Agent.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;So Protolink agents have already the interface and logic to communicate with other Agents and send/receive tasks. How do we send a Task and communicate with an Agent?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The answer is by using the &lt;strong&gt;AgentClient&lt;/strong&gt;. This is a Client that also needs a &lt;strong&gt;Transport&lt;/strong&gt; to operate and start communicating with the Agents.&lt;/p&gt;

&lt;p&gt;The Agents themeselves use an AgentClient to send tasks and messages to other agents. In order to serve their endpoints they use an AgentServer, but it’s outside the scope of this tutorial.&lt;/p&gt;

&lt;p&gt;There are two ways to initiate the AgentClient (the same goes for the Agent). 1) You can provide the type as str and define the url e.g. &lt;code&gt;client = AgentClient(transport=”http”, url=”..”)&lt;/code&gt; or 2) pass a transport instance directly e.g. &lt;code&gt;client = AgentClient(transport=HTTPTransport(url=”…”))&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Let’s create an AgentClient.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;protolink.client&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AgentClient&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AgentClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;transport&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:8050&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using the &lt;strong&gt;send_task&lt;/strong&gt; function to send a task to the Agent.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:8010&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the CoordinatorAgent receives the Task, parses it, sees that it’s an infer request and run the inference cycle using its LLM. Then the LLM decides to call other agents, get the info etc. and finally we get the result.&lt;/p&gt;

&lt;p&gt;when printing the result, you should see something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_last_part_content&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;span class="n"&gt;Great&lt;/span&gt; &lt;span class="n"&gt;news&lt;/span&gt;&lt;span class="err"&gt;!&lt;/span&gt; &lt;span class="n"&gt;I&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ve successfully booked your relaxing vacation to Santorini!

🌤️ **Weather Report for Santorini (July 2026):**
- Temperature: 32°C (86°F)
- Conditions: Sunny
- Humidity: 50%
- Wind: Light breeze
- Verdict: Perfect weather for a beach vacation!

🏨 **Hotel Booking Confirmed:**
- Hotel: Oia Boutique Hotel ⭐⭐⭐⭐
- Location: Santorini
- Check-in: July 15, 2026 at 15:00
- Check-out: July 20, 2026 at 11:00
- Duration: 5 nights
- Room: Double Room for 2 guests
- Amenities: Pool, Breakfast, WiFi
- Total Price: €900 EUR
- Booking ID: HTL-A7B3C2D1
- Cancellation: Free until 24h before check-in

Have a wonderful trip! 🏖️
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🏆 That’s it, you did it ! 🏆&lt;/p&gt;

&lt;p&gt;So by just defining prompts that just define the main role and the logic and the tools you want as simple python functions, you have an agent mesh that is gives the ability to each agent to communicate with its peers automatically to solve any problem. Feel free to experiment with other setups for different problems or even for general purpose apps. Google uses A2A for Agents, with tools for Google Drive, Email clients etc.&lt;/p&gt;

&lt;p&gt;You can see this entire system in action in the &lt;a href="https://github.com/nMaroulis/protolink/tree/main/examples/ticket_booking" rel="noopener noreferrer"&gt;examples/ticket_booking&lt;/a&gt; directory, where the agents contain some extra info that was not included in this guide and the all the code we saw in one place in the &lt;a href="https://github.com/nMaroulis/protolink/blob/main/examples/ticket_booking/quickstart.py" rel="noopener noreferrer"&gt;quickstart.py&lt;/a&gt; script.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion &amp;amp; Why This Matters
&lt;/h3&gt;

&lt;p&gt;This isn’t just a demo, it’s a blueprint for scalable AI systems.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Transport Independence&lt;/strong&gt;: Protolink agents speak HTTP today, but can speak WebSockets, gRPC, or in-memory queues tomorrow without changing agent code, just by changing one line of code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Universal Tooling&lt;/strong&gt;: Protolink supports the &lt;strong&gt;Model Context Protocol (MCP)&lt;/strong&gt; via a built-in adapter. You can import tools from thousands of existing MCP servers (Google Drive, Slack, Postgres) instantly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Resilience&lt;/strong&gt;: By decoupling the Brain (LLM) from the Body (Agent), you are immune to provider outages or pricing changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Modular by Design&lt;/strong&gt;: The Agent-as-an-Entity model means you can plug in any Transport, LLM, Tools, Storage etc. and swap them freely without rewriting your core logic.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Developer Freedom&lt;/strong&gt;: The &lt;strong&gt;pluggable&lt;/strong&gt; architecture means you own your stack. No vendor lock-in, no framework constraints, just clean, composable components.&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%2Fed5wvy8n2tt1ewklzsui.webp" 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%2Fed5wvy8n2tt1ewklzsui.webp" alt="Image Agents enjoying their vacations. Source: Image by the author." width="720" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Start Building&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The age of the single-bot script is over. The age of the Agent Mesh is here.&lt;/p&gt;

&lt;p&gt;Check out &lt;strong&gt;&lt;a href="https://github.com/nMaroulis/protolink" rel="noopener noreferrer"&gt;Protolink on GitHub&lt;/a&gt;&lt;/strong&gt; and start building your own autonomous systems today &amp;amp; feel free to contribute !&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%2Fibcrdrae4wc040zn3s06.webp" 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%2Fibcrdrae4wc040zn3s06.webp" alt="Image Protolink logo. Source: Image by the author." width="720" height="297"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;— -&lt;/p&gt;

&lt;p&gt;Based on the &lt;a href="https://github.com/nMaroulis/protolink/tree/main/examples/ticket_booking" rel="noopener noreferrer"&gt;Vacation Booking&lt;/a&gt; example in the Protolink repository.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>programming</category>
      <category>agents</category>
    </item>
    <item>
      <title>Awesome A2A libraries: A curated list of Agent-to-Agent Libraries and SDKs</title>
      <dc:creator>Nik</dc:creator>
      <pubDate>Tue, 23 Dec 2025 16:44:40 +0000</pubDate>
      <link>https://forem.com/nmaroulis21/awesome-a2a-libraries-a-curated-list-of-agent-to-agent-libraries-and-sdks-4obe</link>
      <guid>https://forem.com/nmaroulis21/awesome-a2a-libraries-a-curated-list-of-agent-to-agent-libraries-and-sdks-4obe</guid>
      <description>&lt;p&gt;Hi DEV community,&lt;/p&gt;

&lt;p&gt;I just published &lt;a href="https://github.com/nMaroulis/awesome-a2a-libraries" rel="noopener noreferrer"&gt;Awesome A2A Libraries&lt;/a&gt;, a curated GitHub list focused &lt;strong&gt;exclusively on code libraries&lt;/strong&gt; that implement or support the &lt;strong&gt;Agent-to-Agent (A2A) protocol&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is A2A?&lt;/strong&gt;&lt;br&gt;
A2A (Agent-to-Agent) is Google’s open protocol for &lt;strong&gt;peer-to-peer, interoperable communication between autonomous agents&lt;/strong&gt;, independent of framework or vendor. It’s designed to make agents talk to each other in a standard, production-friendly way (HTTP, JSON-RPC, async, artifacts, etc.).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What makes this list different?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;🔹 &lt;strong&gt;Libraries only&lt;/strong&gt; (no SaaS, no UIs, no prompts)&lt;br&gt;
⁠🔹 Organized &lt;strong&gt;by programming language&lt;/strong&gt; (Python, JS/TS, Java, Go, Rust, C#)&lt;br&gt;
⁠🔹 Clear classification: role, architecture, readiness, and learning curve&lt;br&gt;
⁠🔹 Includes &lt;strong&gt;official SDKs + serious community implementations&lt;/strong&gt;&lt;br&gt;
⁠🔹 Aimed at developers actually building A2A agents&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Examples included:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;• ⁠Official A2A SDKs&lt;br&gt;
• ⁠Pydantic-AI with native A2A support&lt;br&gt;
• Language-native servers, clients, and utilities.&lt;/p&gt;

&lt;p&gt;Looking for contributors 👀&lt;br&gt;
If you know of:&lt;br&gt;
• ⁠A2A libraries I missed&lt;br&gt;
• ⁠Experimental or production A2A agents&lt;br&gt;
• ⁠Language-specific implementations&lt;/p&gt;

&lt;p&gt;I’d love to add them.&lt;/p&gt;

&lt;p&gt;👉 GitHub: &lt;a href="https://github.com/nMaroulis/awesome-a2a-libraries" rel="noopener noreferrer"&gt;https://github.com/nMaroulis/awesome-a2a-libraries&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>github</category>
      <category>a2a</category>
    </item>
    <item>
      <title>Protolink: the foundational layer for Agent-to-Agent (A2A) communication.</title>
      <dc:creator>Nik</dc:creator>
      <pubDate>Wed, 26 Nov 2025 18:23:53 +0000</pubDate>
      <link>https://forem.com/nmaroulis21/protolink-the-foundational-layer-for-agent-to-agent-a2a-communication-26fp</link>
      <guid>https://forem.com/nmaroulis21/protolink-the-foundational-layer-for-agent-to-agent-a2a-communication-26fp</guid>
      <description>&lt;p&gt;Hi DEV community,&lt;/p&gt;

&lt;p&gt;I’m building &lt;strong&gt;Protolink&lt;/strong&gt;, a Python framework for building agent systems inspired by &lt;strong&gt;Google’s A2A&lt;/strong&gt; protocol.&lt;br&gt;
Currently in &lt;strong&gt;prototype stage&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Key points:&lt;br&gt;
    •    &lt;strong&gt;Centralized agent model&lt;/strong&gt;: single agent handles both client/server roles.&lt;br&gt;
    •    &lt;strong&gt;Reduced boilerplate&lt;/strong&gt;: focus on logic, not infrastructure.&lt;br&gt;
    •    &lt;strong&gt;LLM&lt;/strong&gt; integration: API (OpenAI, Anthropic), &lt;strong&gt;local&lt;/strong&gt; models (llama.cpp), LangChain &lt;strong&gt;chains.&lt;br&gt;
    •    Tool&lt;/strong&gt; integration: native Python, &lt;strong&gt;MCP&lt;/strong&gt;, or LangChain tools via &lt;strong&gt;adapters&lt;/strong&gt;.&lt;br&gt;
    •    Flexible &lt;strong&gt;transport&lt;/strong&gt; layer: HTTP, WebSocket, or in-memory&lt;/p&gt;

&lt;p&gt;It’s inspired by Google’s A2A protocol, but the goal is practical: unify these capabilities while keeping things simple.&lt;/p&gt;

&lt;p&gt;Yes, it’s a lot of buzzwords, but the aim is to actually make them work together in a low-boilerplate framework.&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/nMaroulis/protolink" rel="noopener noreferrer"&gt;https://github.com/nMaroulis/protolink&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Code Snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from protolink.agents import Agent
from protolink.models import AgentCard
from protolink.transport import HTTPTransport
from protolink.tools import MCPToolAdapter
from protolink.llms.api import OpenAILLM

# Define the agent card
agent_card = AgentCard(
    name="example_agent",
    description="A dummy agent",
)

# Initialize the transport
transport = HTTPTransport()

# OpenAI API LLM
llm = OpenAILLM(model="gpt-5.1")

# Initialize the agent
agent = Agent(agent_card, transport, llm)

# Add Native tool
@agent.tool(name="add", description="Add two numbers")
async def add_numbers(a: int, b: int):
    return a + b

# Add MCP tool
mcp_tool = MCPToolAdapter(mcp_client, "multiply")
agent.add_tool(mcp_tool)


# Start the agent
agent.start()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Feedback, ideas, or early experiments are very welcome! 🙌&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>python</category>
      <category>mcp</category>
    </item>
  </channel>
</rss>
