1"use strict";(self.webpackChunkinnovation_labs=self.webpackChunkinnovation_labs||[]).push([[2308],{26268:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"examples/adapters/a2a-outbound-adapter-example","title":"A2A Outbound Adapter Example","description":"Note: Use a unique agent name and seed when starting SingleA2AAdapter or MultiA2AAdapter. The uAgent address is derived from _seed when you omit seed. Reusing a common name collides with other local agents.","source":"@site/versioned_docs/version-1.0.5/examples/adapters/a2a-outbound-adapter.md","sourceDirName":"examples/adapters","slug":"/examples/adapters/a2a-outbound-adapter-example","permalink":"/resources/docs/examples/adapters/a2a-outbound-adapter-example","draft":false,"unlisted":false,"tags":[],"version":"1.0.5","frontMatter":{"id":"a2a-outbound-adapter-example","title":"A2A Outbound Adapter Example"},"sidebar":"tutorialSidebar","previous":{"title":"A2A Inbound Adapter Example","permalink":"/resources/docs/examples/adapters/a2a-inbound-adapter-example"},"next":{"title":"A2A Cart Store (AP2 + Skyfire)","permalink":"/resources/docs/examples/adapters/a2a-cart-store-example"}}');var t=r(74848),d=r(28453);const i={id:"a2a-outbound-adapter-example",title:"A2A Outbound Adapter Example"},a="A2A Outbound Adapter Example",c={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Features",id:"features",level:2},{value:"Agent management",id:"agent-management",level:3},{value:"Routing (<code>MultiA2AAdapter</code> only)",id:"routing-multia2aadapter-only",level:3},{value:"Reliability",id:"reliability",level:3},{value:"Installation",id:"installation",level:2},{value:"Class reference",id:"class-reference",level:2},{value:"<code>A2AAgentConfig</code>",id:"a2aagentconfig",level:3},{value:"<code>SingleA2AAdapter</code>
1",id:"singlea2aadapter",level:3},{value:"<code>MultiA2AAdapter</code>",id:"multia2aadapter",level:3},{value:"<code>a2a_servers(agent_configs, executors)</code>",id:"a2a_serversagent_configs-executors",level:3},{value:"Why three ports in the Brave demo",id:"why-three-ports-in-the-brave-demo",level:2},{value:"Agent Card vs Agentverse",id:"agent-card-vs-agentverse",level:2},{value:"File structure (Brave example)",id:"file-structure-brave-example",level:2},{value:"Full system example: <code>main.py</code>",id:"full-system-example-mainpy",level:2},{value:"Getting started",id:"getting-started",level:2},{value:"1. Clone the examples repo",id:"1-clone-the-examples-repo",level:3},{value:"2. Install dependencies",id:"2-install-dependencies",level:3},{value:"3. Environment variables",id:"3-environment-variables",level:3},{value:"4. Run",id:"4-run",level:3},{value:"5. Manifests and inspector",id:"5-manifests-and-inspector",level:3},{value:"6. Chat",id:"6-chat",level:3},{value:"Architecture",id:"architecture",level:2},{value:"Expected output",id:"expected-output",level:2},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"References",id:"references",level:2}];function o(e){const n={a:"a",blockquote:"blockquote",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,d.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"a2a-outbound-adapter-example",children:"A2A Outbound Adapter Example"})}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsxs)(n.p,{children:["Note: Use a unique agent ",(0,t.jsx)(n.code,{children:"name"})," and ",(0,t.jsx)(n.code,{children:"seed"})," when starting ",(0,t.jsx)(n.code,{children:"SingleA2AAdapter"})," or ",(0,t.jsx)(n.code,{children:"MultiA2AAdapter"}),". The uAgent address is derived from ",(0,t.jsx)(n.code,{children:"{name}_seed"})," when you omit ",(0,t.jsx)(n.code,{children:"seed"}),". Reusing a common name collides with other local agents."]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Inbound vs outbound:"})," this page is ",(0,t.jsx)(n.strong,{children:"outbound"})," \u2014 a uAgent that ",(0,t.jsx)(n.strong,{children:"calls out"})," to A2A HTTP specialists and exposes them on Agentverse via mailbox/chat. For the reverse (A2A clients calling ",(0,t.jsx)(n.strong,{children:"into"})," Agentverse uAgents), see the ",(0,t.jsx)(n.a,{href:"/docs/examples/adapters/a2a-inbound-adapter-example",children:"A2A Inbound Adapter Example"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"The A2A Outbound Adapter connects uAgents to A2A HTTP servers. You can:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Run specialist A2A servers (",(0,t.jsx)(n.code,{children:"a2a_servers"}),") and a coordinating uAgent in one process"]}),"\n",(0,t.jsxs)(n.li,{children:["Route chat from ASI",":One"," / Agentverse to those specialists"]}),"\n",(0,t.jsxs)(n.li,{children:["Discover specialists via A2A Agent Cards (",(0,t.jsx)(n.code,{children:"/.well-known/agent-card.json"}),")"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Whether you wrap one specialist (",(0,t.jsx)(n.code,{children:"SingleA2AAdapter"}),") or several (",(0,t.jsx)(n.code,{children:"MultiA2AAdapter"}),"), the adapter handles chat protocol, health checks, and HTTP forwarding."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.strong,{children:"Python 3.10+"})}),"\n",(0,t.jsxs)(n.li,{children:["A ",(0,t.jsx)(n.a,{href:"https://brave.com/search/api/",children:"Brave Search API"})," key for the Brave example"]}),"\n",(0,t.jsxs)(n.li,{children:["An ",(0,t.jsx)(n.a,{href:"/docs/agentverse/agentverse-api-key",children:"Agentverse API key"})," so ",(0,t.jsx)(n.code,{children:"mailbox=True"})," can register the uAgent"]}),"\n",(0,t.jsxs)(n.li,{children:["For ",(0,t.jsx)(n.code,{children:"MultiA2AAdapter"})," LLM scoring, an ",(0,t.jsx)(n.a,{href:"https://docs.asi1.ai/docs",children:"ASI1 API"})," key (",(0,t.jsx)(n.code,{children:"llm_api_key"}),")"]}
1),"\n",(0,t.jsxs)(n.li,{children:["Background: ",(0,t.jsx)(n.a,{href:"/docs/agent-creation/uagents-adapter-guide",children:"uAgents Adapter guide"})]}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"features",children:"Features"}),"\n",(0,t.jsx)(n.h3,{id:"agent-management",children:"Agent management"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Configure specialists with ",(0,t.jsx)(n.code,{children:"A2AAgentConfig"})," and start them with ",(0,t.jsx)(n.code,{children:"a2a_servers"})]}),"\n",(0,t.jsxs)(n.li,{children:["Health-check Agent Cards at runtime (",(0,t.jsx)(n.code,{children:"MultiA2AAdapter"}),")"]}),"\n",(0,t.jsx)(n.li,{children:"Chat protocol on the uAgent (mailbox) plus A2A HTTP on separate ports"}),"\n"]}),"\n",(0,t.jsxs)(n.h3,{id:"routing-multia2aadapter-only",children:["Routing (",(0,t.jsx)(n.code,{children:"MultiA2AAdapter"})," only)"]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"routing_strategy"})," argument accepts ",(0,t.jsx)(n.strong,{children:"two"})," values. Anything else falls through to keyword matching:"]}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:(0,t.jsx)(n.code,{children:"routing_strategy"})}),(0,t.jsx)(n.th,{children:"What the code does"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:[(0,t.jsx)(n.code,{children:"keyword_match"})," (default)"]}),(0,t.jsxs)(n.td,{children:["Score specialties / keywords / skills. ",(0,t.jsx)(n.code,{children:"priority"})," is a ",(0,t.jsx)(n.strong,{children:"score multiplier"}),", not a separate strategy. If ",(0,t.jsx)(n.code,{children:"llm_api_key"})," is set, ",(0,t.jsx)(n.code,{children:"_route_by_keywords"})," ",(0,t.jsx)(n.strong,{children:"tries an LLM pick first"}),", then falls back to keyword scores."]})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"round_robin"})}),(0,t.jsx)(n.td,{children:"Rotate through healthy agents."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["any other string (including ",(0,t.jsx)(n.code,{children:'"llm"'})," or ",(0,t.jsx)(n.code,{children:'"priority_based"'}),")"]}),(0,t.jsxs)(n.td,{children:[(0,t.jsx)(n.strong,{children:"Not"})," a dedicated path \u2014 same as ",(0,t.jsx)(n.code,{children:"keyword_match"}),"."]})]})]})]}),"\n",(0,t.jsxs)(n.p,{children:["There is no ",(0,t.jsx)(n.code,{children:"priority_based"})," strategy string. Setting ",(0,t.jsx)(n.code,{children:'routing_strategy="llm"'})," does not skip keyword scoring; LLM selection runs ",(0,t.jsx)(n.strong,{children:"inside"})," keyword routing when a key is present."]}),"\n",(0,t.jsx)(n.h3,{id:"reliability",children:"Reliability"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Health checking and Agent Card discovery"}),"\n",(0,t.jsxs)(n.li,{children:["Optional ",(0,t.jsx)(n.code,{children:"fallback_executor"})," when no specialist matches"]}),"\n",(0,t.jsx)(n.li,{children:"Timeouts on A2A HTTP calls"}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,t.jsxs)(n.p,{children:["Use a virtual environment. Pin ",(0,t.jsx)(n.strong,{children:"both"})," the adapter extra and ",(0,t.jsx)(n.code,{children:"a2a-sdk"})," ",(0,t.jsx)(n.strong,{children:"below 1.0"}),". Adapter ",(0,t.jsx)(n.code,{children:"0.6.2"})," imports ",(0,t.jsx)(n.code,{children:"A2AStarletteApplication"})," from ",(0,t.jsx)(n.code,{children:"a2a.server.apps"}),". That module was removed in ",(0,t.jsx)(n.code,{children:"a2a-sdk"})," 1.x (",(0,t.jsx)(n.a,{href:"https://github.com/a2aproject/a2a-python/blob/main/docs/migrations/v1_0/README.md",children:"v0.3 \u2192 v1.0 migration"}),"), so an unpinned install that resolves ",(0,t.jsx)(n.code,{children:"a2a-sdk==1.1.2"})," fails with ",(0,t.jsx)(n.code,{children:"ModuleNotFoundError: a2a.server has no attribute apps"}),"."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"macOS / Linux:"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'python3 -m venv .venv\nsource .venv/bin/activate\npip install "uagents==0.25.5" "uagents-adapter[a2a-outboun
1d]==0.6.2" "a2a-sdk[all,sql,sqlite]>=0.2.11,<1.0"\n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Windows (PowerShell):"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-powershell",children:'python -m venv .venv\n.\\.venv\\Scripts\\Activate.ps1\npip install "uagents==0.25.5" "uagents-adapter[a2a-outbound]==0.6.2" "a2a-sdk[all,sql,sqlite]>=0.2.11,<1.0"\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Verified combo: ",(0,t.jsx)(n.code,{children:"uagents==0.25.5"})," + ",(0,t.jsx)(n.code,{children:"uagents-adapter[a2a-outbound]==0.6.2"})," + ",(0,t.jsx)(n.code,{children:"a2a-sdk"})," ",(0,t.jsx)(n.strong,{children:"0.3.x"})," (",(0,t.jsx)(n.code,{children:">=0.2.11,<1.0"}),"). After install, ",(0,t.jsx)(n.code,{children:"from a2a.server.apps import A2AStarletteApplication"})," and ",(0,t.jsx)(n.code,{children:"from uagents_adapter import SingleA2AAdapter"})," should succeed."]}),"\n",(0,t.jsxs)(n.p,{children:["The extra name is ",(0,t.jsx)(n.strong,{children:(0,t.jsx)(n.code,{children:"a2a-outbound"})})," (not ",(0,t.jsx)(n.code,{children:"a2a-outbond"})," and not ",(0,t.jsx)(n.code,{children:"a2a"}),"). A typo extra does not install ",(0,t.jsx)(n.code,{children:"a2a-sdk"}),"."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"class-reference",children:"Class reference"}),"\n",(0,t.jsxs)(n.p,{children:["There is ",(0,t.jsx)(n.strong,{children:"no"})," ",(0,t.jsx)(n.code,{children:"A2AAdapter"})," class and ",(0,t.jsx)(n.strong,{children:"no"})," ",(0,t.jsx)(n.code,{children:"asi_api_key"})," constructor argument. Export these from ",(0,t.jsx)(n.code,{children:"uagents_adapter"})," (or ",(0,t.jsx)(n.code,{children:"uagents_adapter.a2a_outbound"}),"): ",(0,t.jsx)(n.code,{children:"SingleA2AAdapter"}),", ",(0,t.jsx)(n.code,{children:"MultiA2AAdapter"}),", ",(0,t.jsx)(n.code,{children:"A2AAgentConfig"}),", ",(0,t.jsx)(n.code,{children:"a2a_servers"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"a2aagentconfig",children:(0,t.jsx)(n.code,{children:"A2AAgentConfig"})}),"\n",(0,t.jsxs)(n.p,{children:["Dataclass fields only (invalid kwargs such as ",(0,t.jsx)(n.code,{children:"a2a_port"})," or ",(0,t.jsx)(n.code,{children:"executor_class"})," raise ",(0,t.jsx)(n.code,{children:"TypeError"}),"):"]}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Parameter"}),(0,t.jsx)(n.th,{children:"Type"}),(0,t.jsx)(n.th,{children:"Default"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"name"})}),(0,t.jsx)(n.td,{children:"str"}),(0,t.jsx)(n.td,{children:"required"}),(0,t.jsxs)(n.td,{children:["Specialist name; must match a key in the ",(0,t.jsx)(n.code,{children:"executors"})," dict passed to ",(0,t.jsx)(n.code,{children:"a2a_servers"})]})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"description"})}),(0,t.jsx)(n.td,{children:"str"}),(0,t.jsx)(n.td,{children:"required"}),(0,t.jsx)(n.td,{children:"Human-readable summary"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"url"})}),(0,t.jsx)(n.td,{children:"str"}),(0,t.jsx)(n.td,{children:"required"}),(0,t.jsxs)(n.td,{children:["Base URL used for health checks (for example ",(0,t.jsx)(n.code,{children:"http://localhost:10020"}),")"]})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"port"})}),(0,t.jsx)(n.td,{children:"int"}),(0,t.jsx)(n.td,{children:"required"}),(0,t.jsx)(n.td,{children:"Port for this specialist\u2019s A2A HTTP server"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"specialties"})}),(0,t.jsx)(n.td,{children:"list[str]"}),(0,t.jsx)(n.td,{children:"required"}),(0,t.jsx)(n.td,{children:"Domains used for tags and keyword generation"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"skills"})}),(0,t.jsx)(n.td,{children:"list[str] | None"}),(0,t.jsx)(n.td,{children:"auto from specialties"}),(0,t.jsx)(n.td,{children:"Skill ids"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"examples"})}),(0,t.jsx)(n.td,{children:"list[str] | None"}),(0,t.jsx)(n.td,{children:"auto"}),(0,t.jsx)(n.td,{children:"Sample prompts"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"keywords"})}),(0,t.jsx)(n.td,{children:"list[str] | None"}),(0,t.jsx)(n.td,{children:"auto"}),(0,t.jsx)(n.td,{children:"Routing keywords"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"priority"})}),(0,t.jsx)(n.td,{children:"int"}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"1"})}),(0,t.jsxs)(n.td,{children:["Keyword-score ",(0,t.jsx)(n.strong,{children:"multiplier"})," (higher prefers this agent)"]})]})]})]}),"\n",(0,t.jsxs)(n.p,{children:["Executors are ",(0,t.jsx)(n.strong,{children:"not"})," fields on the config. Pass a separate ",(0,t.jsx)(n.code,{children:"dict[str, AgentExecutor]"})," to ",(0,t.jsx)(n.code,{children:"a2a_servers"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",metastring:'title="config_example.py"',children:'from uagents_adapter import A2AAgentConfig\n\nA2AAgentConfig(\n name="research_specialist",\n description="AI research specialist for research and analysis",\n url="http://localhost:10020",\n port=10020,\n specialties=["research", "analysis", "fact-finding", "summarization"],\n priority=2,\n)\n'})}),"\n",(0,t.jsx)(n.h3,{id:"singlea2aadapter",children:(0,t.jsx)(n.code,{children:"SingleA2AAdapter"})}),"\n",(0,t.jsxs)(n.p,{children:["Wraps one ",(0,t.jsx)(n.code,{children:"AgentExecutor"}),". Starts ",(0,t.jsx)(n.strong,{children:"its own"})," A2A HTTP server on ",(0,t.jsx)(n.code,{children:"a2a_port"})," (default ",(0,t.jsx)(n.strong,{children:"9999"}),") and a uAgent on ",(0,t.jsx)(n.code,{children:"port"})," (default ",(0,t.jsx)(n.strong,{children:"8000"}),"). Chat is forwarded to ",(0,t.jsx)(n.code,{children:"http://localhost:{a2a_port}"}),"."]}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Parameter"}),(0,t.jsx)(n.th,{children:"Type"}),(0,t.jsx)(n.th,{children:"Default"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"agent_executor"})}),(0,t.jsx)(n.td,{children:"AgentExecutor"}),(0,t.jsx)(n.td,{children:"required"}),(0,t.jsx)(n.td,{children:"Executor that handles A2A tasks"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"name"})}),(0,t.jsx)(n.td,{children:"str"}),(0,t.jsx)(n.td,{children:"required"}),(0,t.jsxs)(n.td,{children:["uAgent name; default seed is ",(0,t.jsx)(n.code,{children:"{name}_seed"})]})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"description"})}),(0,t.jsx)(n.td,{children:"str"}),(0,t.jsx)(n.td,{children:"required"}),(0,t.jsx)(n.td,{children:"uAgent description"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"timeout"})}),(0,t.jsx)(n.td,{children:"int"}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"90"})}),(0,t.jsx)(n.td,{children:"HTTP timeout (seconds)"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"port"})}),(0,t.jsx)(n.td,{children:"int"}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"8000"})}),(0,t.jsx)(n.td,{children:"uAgent HTTP port"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"a2a_port"})}),(0,t.jsx)(n.td,{children:"int"}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"9999"})}),(0,t.jsx)(n.td,{children:"Adapter\u2019s A2A HTTP port (chat target)"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"mailbox"})}),(0,t.jsx)(n.td,{children:"bool"}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"True"})}),(0,t.jsx)(n.td,{children:"Agentverse mailbox"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"seed"})}),(0,t.jsx)(n.td,{children:"str | None"}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"{name}_seed"})}),(0,t.jsx)(n.td,{children:"uAgent seed"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"agent_ports"})}),(0,t.jsx)(n.td,{children:"list[int] | None"}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"[]"})}),(0,t.jsx)(n.td,{children:"Optional extra ports"})]})]})]}),"\n",(0,t.jsx)(n.h3,{id:"multia2aadapter",children:(0,t.jsx)(n.code,{children:"MultiA2AAdapter"})}),"\n",(0,t.jsxs)(n.p,{children:["Coordinates ",(0,t.jsx)(n.strong,{children:"multiple"})," ",(0,t.jsx)(n.code,{children:"A2AAgentConfig"})," entries. ",(0,t.jsx)(n.code,{children:"llm_api_key"})," is ",(0,t.jsx)(n.strong,{children:"keyword-only and required"})," (no default). Pass ",(0,t.jsx)(n.code,{children:'""'})," to skip LLM routing. Model default is ",(0,t.jsx)(n.strong,{children:(0,t.jsx)(n.code,{children:"asi1-mini"})})," (not ",(0,t.jsx)(n.code,{children:'"asi1"'}),"). Default ",(0,t.jsx)(n.code,{children:"base_url"})," is ",(0,t.jsx)(n.code,{children:"https://api.asi1.ai/v1/chat/completions"}),"."]}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Parameter"}),(0,t.jsx)(n.th,{children:"Type"}),(0,t.jsx)(n.th,{children:"Default"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"name"})}),(0,t.jsx)(n.td,{children:"str"}),(0,t.jsx)(n.td,{children:"required"}),(0,t.jsx)(n.td,{children:"Coordinator uAgent name"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"description"})}),(0,t.jsx)(n.td,{children:"str"}),(0,t.jsx)(n.td,{children:"required"}),(0,t.jsx)(n.td,{children:"Coordinator description"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"llm_api_key"})}),(0,t.jsx)(n.td,{children:"str"}),(0,t.jsxs)(n.td,{children:[(0,t.jsx)(n.strong,{children:"required"})," (keyword-only)"]}),(0,t.jsx)(n.td,{children:"ASI1 (or compatible) API key; empty string disables LLM pick"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"port"})}),(0,t.jsx)(n.td,{children:"int"}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"8000"})}),(0,t.jsx)(n.td,{children:"uAgent port"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"timeout"})}),(0,t.jsx)(n.td,{children:"int"}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"90"})}),(0,t.jsx)(n.td,{children:"HTTP timeout"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"mailbox"})}),(0,t.jsx)(n.td,{children:"bool"}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"True"})}),(0,t.jsx)(n.td,{children:"Agentverse mailbox"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"seed"})}),(0,t.jsx)(n.td,{children:"str | None"}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"{name}_seed"})}),(0,t.jsx)(n.td,{children:"uAgent seed"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"agent_c
1onfigs"})}),(0,t.jsx)(n.td,{children:"list[A2AAgentConfig] | None"}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"[]"})}),(0,t.jsx)(n.td,{children:"Specialists to discover"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"fallback_executor"})}),(0,t.jsx)(n.td,{children:"AgentExecutor | None"}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"None"})}),(0,t.jsx)(n.td,{children:"Used when routing finds no agent"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"routing_strategy"})}),(0,t.jsx)(n.td,{children:"str"}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:'"keyword_match"'})}),(0,t.jsxs)(n.td,{children:[(0,t.jsx)(n.code,{children:"keyword_match"})," or ",(0,t.jsx)(n.code,{children:"round_robin"})," only"]})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"model"})}),(0,t.jsx)(n.td,{children:"str"}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:'"asi1-mini"'})}),(0,t.jsx)(n.td,{children:"Chat completions model"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"base_url"})}),(0,t.jsx)(n.td,{children:"str"}),(0,t.jsx)(n.td,{children:"ASI1 chat URL"}),(0,t.jsx)(n.td,{children:"LLM HTTP endpoint"})]})]})]}),"\n",(0,t.jsxs)(n.p,{children:["Methods: ",(0,t.jsx)(n.code,{children:"add_agent_config(config)"}),", ",(0,t.jsx)(n.code,{children:"run()"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",metastring:'title="multi_coordinator.py"',children:'import os\nfrom uagents_adapter import MultiA2AAdapter\n\ncoordinator = MultiA2AAdapter(\n name="multi-specialist-coordinator",\n description="Routes queries to A2A specialists",\n llm_api_key=os.environ["ASI1_API_KEY"],\n base_url="https://api.asi1.ai/v1/chat/completions",\n model="asi1-mini",\n port=8200,\n mailbox=True,\n agent_configs=agent_configs, # list[A2AAgentConfig]\n routing_strategy="keyword_match",\n)\ncoordinator.run()\n'})}),"\n",(0,t.jsx)(n.h3,{id:"a2a_serversagent_configs-executors",children:(0,t.jsx)(n.code,{children:"a2a_servers(agent_configs, executors)"})}),"\n",(0,t.jsxs)(n.p,{children:["Starts one uvicorn thread per config. Each server uses ",(0,t.jsx)(n.code,{children:"config.port"})," and ",(0,t.jsx)(n.code,{children:"executors[config.name]"}),". This is ",(0,t.jsx)(n.strong,{children:"independent"})," of ",(0,t.jsx)(n.code,{children:"SingleA2AAdapter.a2a_port"}),"."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"why-three-ports-in-the-brave-demo",children:"Why three ports in the Brave demo"}),"\n",(0,t.jsxs)(n.p,{children:["A \u201csingle agent\u201d Brave sample still starts ",(0,t.jsx)(n.strong,{children:"two"})," A2A HTTP servers plus one uAgent:"]}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Process"}),(0,t.jsx)(n.th,{children:"Port (this tutorial)"}),(0,t.jsx)(n.th,{children:"Role"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Specialist from ",(0,t.jsx)(n.code,{children:"a2a_servers"})]}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.strong,{children:"10020"})}),(0,t.jsxs)(n.td,{children:["A2A Agent Card for the Brave executor (",(0,t.jsx)(n.code,{children:"A2AAgentConfig.port"}),")"]})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:[(0,t.jsx)(n.code,{children:"SingleA2AAdapter"})," A2A HTTP"]}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.strong,{children:"9999"})}),(0,t.jsxs)(n.td,{children:["Chat target. The uAgent POSTs here (",(0,t.jsx)(n.code,{children:"a2a_port"})," default)"]})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"uAgent"}),(0,t.jsx)(n.td,{children:(0,t.jsx)(n.strong,{children:"8200"})}),(0,t.jsxs)(n.td,{children:["Chat protocol + mailbox (",(0,t.jsx)(n.code,{children:"SingleA2AAdapter.port"}),")"]})]})]})]}),"\n",(0,t.jsxs)(n.p,{children:["Agentverse / ASI",":One"," talk to the ",(0,t.jsx)(n.strong,{children:"uAgent"})," (mailbox / inspector on 8200). That uAgent does ",(0,t.jsx)(n.strong,{children:"not"})," call port 10020 for chat; it calls ",(0,t.jsx)(n.strong,{children:"9999"}),". Port 10020 is the specialist card you can inspect or call as a raw A2A client."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"agent-card-vs-agentverse",children:"Agent Card vs Agentverse"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"A2A Agent Card"})," is an HTTP discovery document. Prefer ",(0,t.jsx)(n.code,{children:"http://localhost:PORT/.well-known/agent-card.json"})," (replace ",(0,t.jsx)(n.code,{children:"PORT"})," with ",(0,t.jsx)(n.code,{children:"10020"})," or ",(0,t.jsx)(n.code,{children:"9999"}),"). The adapter health-check uses that path first, then falls back to legacy ",(0,t.jsx)(n.code,{children:"/.well-known/agent.
1json"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Agentverse"})," sees the ",(0,t.jsx)(n.strong,{children:"uAgent"})," after mailbox/Almanac registration. It does not scrape the A2A card to list the agent. Inspector URLs use the uAgent address and port 8200, not the A2A card URL."]}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"file-structure-brave-example",children:"File structure (Brave example)"}),"\n",(0,t.jsxs)(n.p,{children:["Upstream folder: ",(0,t.jsx)(n.a,{href:"https://github.com/fetchai/innovation-lab-examples/tree/main/a2a-uAgents-Integration/a2a-Outbound-Communication/braveagent",children:"braveagent"})]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-text",children:"braveagent/\n function.py # orchestrator (same logic as main.py below)\n brave/\n agent.py # BraveSearchAgentExecutor\n requirements.txt # see install pins below; do not use extra [a2a]\n readme.md\n .env # you create this\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The GitHub tree currently has ",(0,t.jsx)(n.strong,{children:"no"})," ",(0,t.jsx)(n.code,{children:"main.py"}),". Save the sample below as ",(0,t.jsx)(n.code,{children:"main.py"}),", or run ",(0,t.jsx)(n.code,{children:"python function.py"})," if you use the repo file as-is. Keep the filename you run in sync with these docs."]}),"\n",(0,t.jsxs)(n.p,{children:["Recommended ",(0,t.jsx)(n.code,{children:"requirements.txt"})," (the published example file still lists invalid ",(0,t.jsx)(n.code,{children:"uagents-adapter[a2a]"})," and a broken ",(0,t.jsx)(n.code,{children:"a2a-sdk"})," line \u2014 do not copy those):"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-text",metastring:'title="requirements.txt"',children:"uagents==0.25.5\nuagents-adapter[a2a-outbound]==0.6.2\na2a-sdk[all,sql,sqlite]>=0.2.11,<1.0\npython-dotenv>=1.0.0\n"})}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsxs)(n.h2,{id:"full-system-example-mainpy",children:["Full system example: ",(0,t.jsx)(n.code,{children:"main.py"})]}),"\n",(0,t.jsxs)(n.p,{children:["This matches the Brave orchestrator: ",(0,t.jsx)(n.code,{children:"A2AAgentConfig"})," + ",(0,t.jsx)(n.code,{children:"a2a_servers"})," + ",(0,t.jsx)(n.code,{children:"SingleA2AAdapter"}),". Coordinator name is ",(0,t.jsx)(n.strong,{children:(0,t.jsx)(n.code,{children:"brave-search-coordinator"})})," (same as the example repo). Address is unique to your seed; do not copy inspector addresses from old screenshots."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",metastring:'title="main.py"',children:'from typing import Any, Dict, List\n\nfrom uagents_adapter import A2AAgentConfig, SingleA2AAdapter, a2a_servers\n\nfrom brave.agent import BraveSearchAgentExecutor\n\nCOORDINATOR_NAME = "brave-search-coordinator"\nSPECIALIST_NAME = "brave_search_specialist"\nSPECIALIST_PORT = 10020\nUAGENT_PORT = 8200\n\nclass BraveSearchAgent:\n def __init__(self) -> None:\n self.coordinator = None\n self.agent_configs: List[A2AAgentConfig] = []\n self.executors: Dict[str, Any] = {}\n self.running = False\n\n def setup_agents(self) -> None:\n print("Setting up Brave Search Agent")\n self.agent_configs = [\n A2AAgentConfig(\n name=SPECIALIST_NAME,\n description="AI Agent for web and news search using Brave Search API",\n url=f"http://localhost:{SPECIALIST_PORT}",\n port=SPECIALIST_PORT,\n specialties=[\n "web search",\n "news",\n "information retrieval",\n "local business",\n "site-specific lookup",\n ],\n priority=3,\n )\n ]\n self.executors = {SPECIALIST_NAME: BraveSearchAgentExecutor()}\n print("Brave Search Agent configuration created")\n\n def start_individual_a2a_servers(self) -> None:\n print("Starting Brave Search specialist server...")\n a2a_servers(self.agent_configs, self.executors)\n print("Brave Search specialist server started")\n\n def create_coordinator(self) -> SingleA2AAdapter:\n print("Creating Brave Coordinator...")\n brave_executor = self.executors.get(SPECIALIST_NAME)\n if brave_executor is None:\n raise ValueError("BraveSearchAgentExecutor not found in executors dictionary.")\n self.coordinator = SingleA2AAdapter(\n agent_executor=brave_executor,\n name=COORDINATOR_NAME,\n description="Coordinator for routing Brave Search queries",\n port=UAGENT_PORT,\n mailbox=True,\n )\n print("Brave Coordinator created")\n return self.coordinator\n\n def start_system(self) -> None:\n print("Starting Brave Search System")\n try:\n self.setup_agents()\n self.start_individual_a2a_servers()\n coordinator = self.create_coordinator()\n self.running = True\n print(f"Starting Brave c
1oordinator on port {coordinator.port}...")\n print(\n f"Specialist Agent Card: http://localhost:{SPECIALIST_PORT}/.well-known/agent-card.json"\n )\n coordinator.run()\n except KeyboardInterrupt:\n print("Shutting down Brave Search system...")\n self.running = False\n\ndef main() -> None:\n BraveSearchAgent().start_system()\n\nif __name__ == "__main__":\n main()\n'})}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"getting-started",children:"Getting started"}),"\n",(0,t.jsx)(n.h3,{id:"1-clone-the-examples-repo",children:"1. Clone the examples repo"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/fetchai/innovation-lab-examples.git\ncd innovation-lab-examples/a2a-uAgents-Integration/a2a-Outbound-Communication/braveagent\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Copy the ",(0,t.jsx)(n.code,{children:"main.py"})," listing above into this folder (or run ",(0,t.jsx)(n.code,{children:"python function.py"}),")."]}),"\n",(0,t.jsx)(n.h3,{id:"2-install-dependencies",children:"2. Install dependencies"}),"\n",(0,t.jsxs)(n.p,{children:["Do ",(0,t.jsx)(n.strong,{children:"not"})," run ",(0,t.jsx)(n.code,{children:'pip install "uagents-adapter[a2a]"'})," or ",(0,t.jsx)(n.code,{children:"[a2a-outbond]"}),". Use the Installation commands (or the recommended ",(0,t.jsx)(n.code,{children:"requirements.txt"}),")."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'python3 -m venv .venv\nsource .venv/bin/activate\npip install "uagents==0.25.5" "uagents-adapter[a2a-outbound]==0.6.2" "a2a-sdk[all,sql,sqlite]>=0.2.11,<1.0" python-dotenv\n'})}),"\n",(0,t.jsx)(n.h3,{id:"3-environment-variables",children:"3. Environment variables"}),"\n",(0,t.jsxs)(n.p,{children:["Never commit real keys. Create ",(0,t.jsx)(n.code,{children:".env"})," in ",(0,t.jsx)(n.code,{children:"braveagent/"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",metastring:'title=".env.example"',children:"BRAVE_API_KEY=your_brave_api_key_here\nAGENTVERSE_API_KEY=your_agentverse_api_key_here\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"BraveSearchAgentExecutor"})," needs ",(0,t.jsx)(n.code,{children:"BRAVE_API_KEY"}),". ",(0,t.jsx)(n.code,{children:"mailbox=True"})," needs Agentverse credentials (",(0,t.jsx)(n.code,{children:"AGENTVERSE_API_KEY"}),") so the uAgent can obtain a mailbox token and register on Almanac. For ",(0,t.jsx)(n.code,{children:"MultiA2AAdapter"}),", also set ",(0,t.jsx)(n.code,{children:"ASI1_API_KEY"})," and pass it as ",(0,t.jsx)(n.code,{children:"llm_api_key"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Load ",(0,t.jsx)(n.code,{children:".env"})," if your executor does not already:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",metastring:'title="load_env.py"',children:"from dotenv import load_dotenv\n\nload_dotenv()\n"})}),"\n",(0,t.jsx)(n.h3,{id:"4-run",children:"4. Run"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"python main.py\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Expected listeners: specialist ",(0,t.jsx)(n.strong,{children:"10020"}),", adapter A2A ",(0,t.jsx)(n.strong,{children:"9999"}),", uAgent ",(0,t.jsx)(n.strong,{children:"8200"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"5-manifests-and-inspector",children:"5. Manifests and inspector"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Specialist card: ",(0,t.jsx)(n.code,{children:"http://localhost:10020/.well-known/agent-card.json"})," (legacy fallback: ",(0,t.jsx)(n.code,{children:".../agent.json"}),")"]}),"\n",(0,t.jsxs)(n.li,{children:["Adapter A2A card: ",(0,t.jsx)(n.code,{children:"http://localhost:9999/.well-known/agent-card.json"})]}),"\n",(0,t.jsxs)(n.li,{children:["Inspector: the process prints an Agentverse inspect URL with ",(0,t.jsx)(n.code,{children:"uri=http://127.0.0.1:8200"})," and ",(0,t.jsx)(n.code,{children:"address="})," set to ",(0,t.jsx)(n.strong,{children:"your"})," uAgent address. That address changes if ",(0,t.jsx)(n.code,{children:"name"})," or ",(0,t.jsx)(n.code,{children:"seed"})," changes."]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"6-chat",children:"6. Chat"}),"\n",(0,t.jsx)("div",{style:{textAlign:"center"},children:(0,t.jsx)("img",{src:"/resources/img/adapters/a2a-brave.png",alt:"Brave Search agent in Agentverse inspector",style:{width:"100%",maxWidth:"1000px"}})}),"\n",(0,t.jsxs)(n.p,{children:["Use ",(0,t.jsx)(n.strong,{children:"Chat with agent"})," in the inspector (for example ",(0,t.jsx)(n.code,{children:"Find pizza restaurants near Central Park"}),") or ASI",":One"," against the mailbox uAgent."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"architecture",children:"Architecture"}),"\n",(0,t.jsx)("div",{style:{textAlign:"center"},children:(0,t.jsx)("img",{src:"/resources/img/adapters/arch.png",alt:"A2A outbound adapter architecture",style:{width:"100%",maxWidth:"1000px"}})}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"User sends chat to the uAgent."}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"SingleA2AAdapter"})," posts to its A2A server (",(0,t.jsx)(n.code,{children:"a2a_port"}),", default 9999). ",(0,t.jsx)(n.code,{children:"MultiA2AAdapter"})," health-checks cards and forwards to the chosen specialist ",(0,t.jsx)(n.code,{children:"url"}),"."]}),"\n",(0,t.jsx)(n.li,{children:"The executor returns text (or payment artifacts); the adapter sends a chat reply and an acknowledgement."}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"expected-output",children:"Expected output"}),"\n",(0,t.jsx)(n.p,{children:"When running the example, you should see output similar to:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-text",children:"\ud83d\ude80 Starting Brave Search System\
1n\ud83d\udd27 Setting up Brave Search Agent\n\u2705 Brave Search Agent configuration created\n\ud83d\udd04 Starting Brave Search server...\n\ud83d\ude80 Starting brave_search_specialist on port 10020\nINFO: Started server process [78780]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\nINFO: Uvicorn running on http://0.0.0.0:10020 (Press CTRL+C to quit)\n\u23f3 Initializing servers...\n\u2705 All A2A servers started!\n\u2705 Brave Search server started!\n\ud83e\udd16 Creating Brave Coordinator...\n\u2705 Brave Coordinator created!\n\ud83c\udfaf Starting Brave coordinator on port 8200...\nAgentCard manifest URL: http://localhost:10020/.well-known/agent.json\n\ud83d\ude80 Starting A2A Adapter for 'brave_coordin'\n\ud83d\udce1 A2A Server will run on port 9999\n\ud83e\udd16 uAgent will run on port 8200\nINFO: Started server process [78780]\nINFO: Waiting for application startup.\nINFO: Application startup complete.\nINFO: Uvicorn running on http://0.0.0.0:9999 (Press CTRL+C to quit)\nINFO: [brave_coordin]: Starting agent with address: agent1qfs8ujwza9enrq926cncxttt2qglmwa3svp09dgn63wfkulzhjv56lh8tr9\nINFO: [brave_coordin]: \ud83d\ude80 A2A uAgent started at address: agent1qfs8ujwza9enrq926cncxttt2qglmwa3svp09dgn63wfkulzhjv56lh8tr9\nINFO: [brave_coordin]: \ud83d\udd17 A2A Server running on port: 9999\nINFO: [brave_coordin]: Agent inspector available at https://agentverse.ai/inspect/?uri=http%3A//127.0.0.1%3A8200&address=agent1qfs8ujwza9enrq926cncxttt2qglmwa3svp09dgn63wfkulzhjv56lh8tr9\nINFO: [brave_coordin]: Starting server on http://0.0.0.0:8200 (Press CTRL+C to quit)\nINFO: [brave_coordin]: Starting mailbox client for https://agentverse.ai\nINFO: [brave_coordin]: Manifest published successfully: AgentChatProtocol\nINFO: [uagents.registration]: Registration on Almanac API successful\nINFO: [uagents.registration]: Almanac contract registration is up to date!\nINFO: [brave_coordin]: Mailbox access token acquired\nINFO: [brave_coordin]: \ud83d\udce9 Received message from agent1qvj7rlfmwqq95unelgs2hnfd5w8swwr6endw9664a26lpfk8fftjydlkhyv: Find pizza restaurants near Central Park\nINFO:httpx:HTTP Request: POST http://localhost:9999/ \"HTTP/1.1 200 OK\"\nINFO: [brave_coordin]: \ud83e\udd16 A2A Response: \ud83c\udf10 Brave Search Agent - General Search\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\ud83d\udd0d Query: Find pizza r...\nINFO: [brave_coordin]: \ud83d\udce4 Sent response back to agent1qvj7rlfmwqq95unelgs2hnfd5w8swwr6endw9664a26lpfk8fftjydlkhyv\nINFO: [brave_coordin]: \u2705 Sent acknowledgment for message accdd830-7726-498b-8df9-4159ac3a17cd\n"})}),"\n",(0,t.jsx)("div",{style:{textAlign:"center"},children:(0,t.jsx)("img",{src:"/resources/img/adapters/a2a-brave-with-chat.png",alt:"Brave Search agent chat in inspector",style:{width:"100%",maxWidth:"1000px"}})}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Symptom"}),(0,t.jsx)(n.th,{children:"Cause"}),(0,t.jsx)(n.th,{children:"Fix"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["pip extra ",(0,t.jsx)(n.code,{children:"a2a-outbond"})," / ",(0,t.jsx)(n.code,{children:"a2a"})]}),(0,t.jsx)(n.td,{children:"Extra does not exist"}),(0,t.jsxs)(n.td,{children:["Install ",(0,t.jsx)(n.code,{children:"[a2a-outbound]==0.6.2"})]})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"ModuleNotFoundError: a2a.server.apps"})}),(0,t.jsxs)(n.td,{children:[(0,t.jsx)(n.code,{children:"a2a-sdk"})," 1.x"]}),(0,t.jsxs)(n.td,{children:["Pin ",(0,t.jsx)(n.code,{children:"a2a-sdk[all,sql,sqlite]>=0.2.11,<1.0"})]})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:[(0,t.jsx)(n.code,{children:"TypeError"})," on ",(0,t.jsx)(n.code,{children:"A2AAgentConfig"})]}),(0,t.jsxs)(n.td,{children:[(0,t.jsx)(n.code,{children:"a2a_port"})," / ",(0,t.jsx)(n.code,{children:"executor_class"})]}),(0,t.jsxs)(n.td,{children:["Use only documented fields; pass executors to ",(0,t.jsx)(n.code,{children:"a2a_servers"})]})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:[(0,t.jsx)(n.code,{children:"NameError: A2AAdapter"})," / missing ",(0,t.jsx)(n.code,{children:"asi_api_key"})]}),(0,t.jsx)(n.td,{children:"Fictional class"}),(0,t.jsxs)(n.td,{children:["Use ",(0,t.jsx)(n.code,{children:"SingleA2AAdapter"})," or ",(0,t.jsx)(n.code,{children:"MultiA2AAdapter"})," + ",(0,t.jsx)(n.code,{children:"llm_api_key"})]})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:[(0,t.jsx)(n.code,{children:"python main.py"})," file not found"]}
1),(0,t.jsxs)(n.td,{children:["Repo ships ",(0,t.jsx)(n.code,{children:"function.py"})]}),(0,t.jsxs)(n.td,{children:["Save ",(0,t.jsx)(n.code,{children:"main.py"})," from this page or run ",(0,t.jsx)(n.code,{children:"python function.py"})]})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Mailbox / Almanac errors"}),(0,t.jsx)(n.td,{children:"Missing Agentverse key"}),(0,t.jsxs)(n.td,{children:["Set ",(0,t.jsx)(n.code,{children:"AGENTVERSE_API_KEY"})]})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Brave executor errors"}),(0,t.jsx)(n.td,{children:"Missing search key"}),(0,t.jsxs)(n.td,{children:["Set ",(0,t.jsx)(n.code,{children:"BRAVE_API_KEY"})]})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Address not matching a screenshot"}),(0,t.jsxs)(n.td,{children:["Different ",(0,t.jsx)(n.code,{children:"name"}),"/",(0,t.jsx)(n.code,{children:"seed"})]}),(0,t.jsxs)(n.td,{children:["Expected; use the inspector URL from ",(0,t.jsx)(n.strong,{children:"your"})," logs"]})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Port already in use"}),(0,t.jsx)(n.td,{children:"10020, 9999, or 8200 taken"}),(0,t.jsxs)(n.td,{children:["Stop the other process or change ",(0,t.jsx)(n.code,{children:"port"})," / ",(0,t.jsx)(n.code,{children:"a2a_port"})]})]})]})]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"references",children:"References"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://a2aproject.github.io/A2A/latest/",children:"A2A Protocol"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://github.com/fetchai/uAgents",children:"uAgents"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://github.com/fetchai/uAgents/tree/main/python/uagents-adapter/src/uagents_adapter",children:"uAgents Adapter source"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsxs)(n.a,{href:"https://github.com/a2aproject/a2a-python/blob/main/docs/migrations/v1_0/README.md",children:["a2a-sdk v1 migration (breaking ",(0,t.jsx)(n.code,{children:"a2a.server.apps"}),")"]})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.asi1.ai/docs",children:"ASI1 API"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://agentverse.ai",children:"Agentverse"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/docs/agent-creation/uagents-adapter-guide",children:"uAgents Adapter guide"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/docs/examples/adapters/a2a-inbound-adapter-example",children:"A2A Inbound Adapter Example"})}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"This pattern shows how outbound adapters expose A2A specialists through uAgent chat and mailbox."}),"\n",(0,t.jsx)(n.p,{children:"Happy building!"})]})}function h(e={}){const{wrapper:n}={...(0,d.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(o,{...e})}):o(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>i,x:()=>a});var s=r(96540);const t={},d=s.createContext(t);function i(e){const n=s.useContext(d);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),s.createElement(d.Provider,{value:n},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.