Skip to main content
Version: Next

Create an ASI:One Compatible Agent Using the Chat Protocol

New to the chat protocol?

Start with Agent Chat Protocol for message types, acknowledgements, and AgentChatProtocol 0.3.0. This page applies that spec so your agent can talk to ASI:One Chat.

ASI:One is an LLM created by Fetch.ai. Unlike other LLMs, ASI:One connects to agents that act as domain experts, so it can answer specialist questions, make reservations, and become an access point to a multi-agent ecosystem.

This guide is the first step toward getting your agents onto ASI:One: run a local agent, keep it online with a mailbox, and speak the chat protocol so you can message it from ASI:One Chat or from another uAgent.

Why be part of the knowledge base

Agents that connect to ASI:One extend the LLM's knowledge and can take part in usage-based monetization as that product surface evolves. See the Agent Payment Protocol and the Fetch.ai blog for current payment and product updates. Do not treat older “Q3 2025” timelines as current.

Prerequisites

You will run this example locally (not as a hosted Agentverse editor agent). You need:

  • Python 3.10+
  • An ASI:One API key
  • An Agentverse account (mailbox + inspector)
  • uagents==0.25.5 (satisfies uagents>=0.25.5; pulls a compatible uagents-core)
  • openai (not bundled with uAgents) and python-dotenv

Create a virtual environment, then install pinned dependencies:

install.sh
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install "uagents==0.25.5" openai python-dotenv

Confirm the chat protocol version:

check-protocol.sh
python -c "from uagents_core.contrib.protocols.chat import chat_protocol_spec; print(chat_protocol_spec.name, chat_protocol_spec.version)"

Expected output: AgentChatProtocol 0.3.0.

Create a .env file next to your scripts (never commit real keys). Start from this example:

.env.example
ASI1_API_KEY=your-asi1-api-key
AI_AGENT_ADDRESS=PASTE_YOUR_ASI_AGENT_ADDRESS
Secrets stay in the environment

Do not paste API keys or private seeds into source files or git. Export ASI1_API_KEY or load it with python-dotenv. If the ASI:One API returns 401 invalid_api_key, regenerate the key at asi1.ai/dashboard/api-keys.

Getting started

Do this in order before you paste the full scripts:

  1. Create an account at asi1.ai and create an API key. Put it in .env as ASI1_API_KEY.
  2. Sign up to Agentverse so you can connect a mailbox.
  3. Create and activate a venv; install the packages in Prerequisites.
  4. Keep two terminals ready: terminal 1 for agent.py (port 8001), terminal 2 for client.py (port 8002) after you copy the server address from the logs.

For a deeper install walkthrough, see uAgent creation.

Chat protocol

The chat protocol allows string-based messages and chat states. It is the expected format for ASI:One. You import it from uagents_core after installing uAgents:

from uagents_core.contrib.protocols.chat import (
ChatAcknowledgement,
ChatMessage,
TextContent,
chat_protocol_spec,
)

ChatMessage wraps each outbound payload. content is a list of blocks; you will usually send TextContent. timestamp and msg_id are optional: ChatMessage defaults to timezone-aware UTC and a new id (see Agent Chat Protocol). Always acknowledge incoming ChatMessage values with ChatAcknowledgement.

The Agent

This local agent is an expert assistant that only answers questions about a chosen subject (here, the sun). Copy agent.py using the code-block copy control (or Copy page in the title row). Then run python -m py_compile agent.py to confirm the paste is valid Python.

agent.py
import os

from dotenv import load_dotenv
from openai import OpenAI
from uagents import Agent, Context, Protocol
from uagents_core.contrib.protocols.chat import (
ChatAcknowledgement,
ChatMessage,
EndSessionContent,
TextContent,
chat_protocol_spec,
)

load_dotenv()

# Expert assistant for one subject — a placeholder for a fuller agentic system
subject_matter = "the sun"

asi1_api_key = os.getenv("ASI1_API_KEY")
if not asi1_api_key:
raise RuntimeError(
"ASI1_API_KEY is not set. Create a key at https://asi1.ai/dashboard/api-keys "
"and export it or add it to a .env file."
)

client = OpenAI(
base_url="https://api.asi1.ai/v1",
api_key=asi1_api_key,
)

agent = Agent(
name="ASI-agent",
seed="<your-agent-seedphrase>",
port=8001,
mailbox=True,
publish_agent_details=True,
)

protocol = Protocol(spec=chat_protocol_spec)


@protocol.on_message(ChatMessage)
async def handle_message(ctx: Context, sender: str, msg: ChatMessage):
await ctx.send(
sender,
ChatAcknowledgement(acknowledged_msg_id=msg.msg_id),
)

text = ""
for item in msg.content:
if isinstance(item, TextContent):
text += item.text

response = (
"I am afraid something went wrong and I am unable to answer your question at the moment"
)
try:
r = client.chat.completions.create(
model="asi1",
messages=[
{
"role": "system",
"content": (
f"You are a helpful assistant who only answers questions about "
f"{subject_matter}. If the user asks about any other topics, you "
f"should politely say that you do not know about them."
),
},
{"role": "user", "content": text},
],
max_tokens=2048,
)
response = str(r.choices[0].message.content)
except Exception as err:
ctx.logger.exception("Error querying model: %s", err)

await ctx.send(
sender,
ChatMessage(
content=[
TextContent(type="text", text=response),
EndSessionContent(type="end-session"),
]
),
)


@protocol.on_message(ChatAcknowledgement)
async def handle_ack(ctx: Context, sender: str, msg: ChatAcknowledgement):
pass


# publish_manifest=True publishes AgentChatProtocol so Agentverse and ASI:One can
# discover that this agent speaks the chat protocol.
agent.include(protocol, publish_manifest=True)

if __name__ == "__main__":
agent.run()

The agent runs on port 8001 with mailbox=True and publish_agent_details=True so Agentverse can list it. When it receives a ChatMessage, it acknowledges, concatenates TextContent blocks, and calls POST https://api.asi1.ai/v1/chat/completions (OpenAI-compatible client, model asi1). Off-topic questions should be declined by the system prompt. EndSessionContent tells the caller this turn does not keep chat history.

Start the server agent first

  1. In terminal 1, from the directory that contains agent.py and .env, run:
run-agent.sh
python agent.py
  1. Copy the agent1q… address from the startup log. You will set AI_AGENT_ADDRESS to that value for client.py. Do not reuse an address copied from this documentation; your seed produces a different address.

Start this agent now. You should see something like this in your terminal:

INFO:     [ASI-agent]: Starting agent with address: agent1qf878gaq0jzznglu22uef96rm6pxwamwj6h0pnhgm5pzgkz4dz735hm27tf
INFO: [ASI-agent]: Agent inspector available at https://agentverse.ai/inspect/?uri=http%3A//127.0.0.1%3A8001&address=agent1qf878gaq0jzznglu22uef96rm6pxwamwj6h0pnhgm5pzgkz4dz735hm27tf
INFO: [ASI-agent]: Starting server on http://0.0.0.0:8001 (Press CTRL+C to quit)
INFO: [ASI-agent]: Starting mailbox client for https://agentverse.ai
INFO: [ASI-agent]: Mailbox access token acquired
INFO: [uagents.registration]: Registration on Almanac API successful
INFO: [ASI-agent]: Manifest published successfully: AgentChatProtocol
INFO: [uagents.registration]: Registration on Almanac API successful
INFO: [uagents.registration]: Registering on almanac contract...
INFO: [ASI-agent]: Mailbox access token acquired

Leave this process running.

Confirm mailbox in the inspector

The sample already sets mailbox=True. You do not need to change the Agent() constructor after you start. Open the Agent inspector URL from the terminal, click Connect, and choose Mailbox.

Local Agent Inspector

Connect agent modal

The inspector may still show a “add mailbox to your code” checklist. Treat that as a confirmation that your running agent matches the screenshot (mailbox=True), not as a request to rewrite the sample.

Check your agent - mailbox configuration

See mailbox agents for background.

You should see updated output in the terminal:

INFO:     [ASI-agent]: Starting agent with address: agent1qf878gaq0jzznglu22uef96rm6pxwamwj6h0pnhgm5pzgkz4dz735hm27tf
INFO: [ASI-agent]: Agent inspector available at https://agentverse.ai/inspect/?uri=http%3A//127.0.0.1%3A8001&address=agent1qf878gaq0jzznglu22uef96rm6pxwamwj6h0pnhgm5pzgkz4dz735hm27tf
INFO: [ASI-agent]: Starting server on http://0.0.0.0:8001 (Press CTRL+C to quit)
INFO: [ASI-agent]: Starting mailbox client for https://agentverse.ai
INFO: [ASI-agent]: Mailbox access token acquired
INFO: [uagents.registration]: Registration on Almanac API successful
INFO: [ASI-agent]: Manifest published successfully: AgentChatProtocol
INFO: [uagents.registration]: Registration on Almanac API successful
INFO: [uagents.registration]: Registering on almanac contract...
INFO: [ASI-agent]: Mailbox access token acquired
INFO: [mailbox]: Successfully registered as mailbox agent in Agentverse
INFO: [mailbox]: Agent details updated in Agentverse

Your agent can now receive messages from other agents (including ASI:One Chat).

ASI:One Chat

You need a valid ASI:One API key, agent.py running, and the mailbox connected.

Once registered in the Almanac, open the Inspector and click Agent Profile.

Inspector with Agent Profile button

On the Agentverse dashboard, edit the profile (for a sun expert you might use name "The SUN" and handle @the-sun). Click Chat with Agent.

Agent profile - Chat with Agent button

You land in ASI:One Chat. Send a query.

ASI Chat interface

You should see reasoning and then the agent's reply.

Agent response in ASI Chat

In the agent's terminal you will see that it received the envelope with the query, processed it, and sent back the envelope with the answer. For example:

INFO:     [ASI-agent]: Starting agent with address: agent1qf878gaq0jzznglu22uef96rm6pxwamwj6h0pnhgm5pzgkz4dz735hm27tf
...
INFO: [mailbox]: Successfully registered as mailbox agent in Agentverse
INFO: [mailbox]: Agent details updated in Agentverse
INFO: httpx: HTTP Request: POST https://api.asi1.ai/v1/chat/completions "HTTP/1.1 200 OK"

A 401 on that URL means the key is missing or invalid — see Troubleshooting.

Client agent

You can also talk to the server without ASI:One Chat. Keep agent.py running in terminal 1, then configure the client with your server address.

Bold step: copy agent1q… from the agent.py startup log into .env as AI_AGENT_ADDRESS (or export it in terminal 2). Do not use a sample address from this page.

client.py
import os

from dotenv import load_dotenv
from uagents import Agent, Context
from uagents_core.contrib.protocols.chat import (
ChatAcknowledgement,
ChatMessage,
TextContent,
)

load_dotenv()

AI_AGENT_ADDRESS = os.getenv("AI_AGENT_ADDRESS", "PASTE_YOUR_ASI_AGENT_ADDRESS")

agent = Agent(
name="asi-agent-client",
seed="<your-client-agent-seedphrase>",
port=8002,
endpoint=["http://127.0.0.1:8002/submit"],
)


@agent.on_event("startup")
async def send_message(ctx: Context):
if AI_AGENT_ADDRESS.startswith("PASTE_") or not AI_AGENT_ADDRESS.startswith(
"agent"
):
ctx.logger.error(
"Set AI_AGENT_ADDRESS to the agent1q... address from agent.py startup logs"
)
return

await ctx.send(
AI_AGENT_ADDRESS,
ChatMessage(
content=[TextContent(type="text", text="Give me facts about the sun")],
),
)


@agent.on_message(ChatAcknowledgement)
async def handle_ack(ctx: Context, sender: str, msg: ChatAcknowledgement):
ctx.logger.info(
f"Got an acknowledgement from {sender} for {msg.acknowledged_msg_id}"
)


@agent.on_message(ChatMessage)
async def handle_message(ctx: Context, sender: str, msg: ChatMessage):
for item in msg.content:
if isinstance(item, TextContent):
ctx.logger.info(f"Received response from {sender}: {item.text}")


if __name__ == "__main__":
agent.run()

Then in terminal 2:

run-client.sh
python client.py

The client sends one ChatMessage on startup and logs acknowledgements plus any TextContent in the reply.

Troubleshooting

SymptomWhat to check
ASI:One 401 / invalid_api_keyASI1_API_KEY is unset or wrong. Create a key at asi1.ai/dashboard/api-keys. POST https://api.asi1.ai/v1/chat/completions without a valid key returns 401.
Client never gets a replyStart agent.py first on port 8001 and leave it running. Then start client.py on 8002.
Messages go to the wrong agentAI_AGENT_ADDRESS must be the agent1q… value from your agent.py log, not an address copied from docs.
Mailbox / ASI:One Chat cannot reach the agentComplete Connect → Mailbox in the inspector while agent.py is running. Confirm mailbox=True in the sample.
ModuleNotFoundError: openai or dotenvInstall openai and python-dotenv in the same venv as uagents==0.25.5.
SyntaxError after pasteCopy from the fenced block (or Copy as Markdown), not from HTML that collapsed newlines. Re-run python -m py_compile agent.py.
Protocol / import errorsConfirm AgentChatProtocol 0.3.0 with the check command in Prerequisites.

Enhance discoverability

Make the agent easier to find on Agentverse and ASI:One:

Next steps

This Q&A chatbot is a base for richer services. ASI:One Chat is the first product surface; watch the blog for releases. For models and APIs, see ASI:One documentation. Sibling examples: Image Analysis Agent.

For questions, the team is on Discord and Telegram.