This project implements an intelligent agent using the Google Agent Development Kit (ADK). The agent features an advanced memory system called "MemoryBlossom" and is exposed for interaction via the Agent2Agent (A2A) protocol through a FastAPI wrapper. This allows it to be registered with an AIRA Hub and accessed by MCP clients.
memory_system/: Contains the implementation of the MemoryBlossom system.memory_models.py: Defines theMemorydata class.embedding_utils.py: Utilities for generating and comparing text embeddings.memory_blossom.py: The coreMemoryBlossomclass managing different memory types.memory_connector.py: Class for analyzing and creating connections between memories.
orchestrator_adk_agent.py: Defines the main ADKLlmAgent, its tools for interacting with MemoryBlossom, and the ADKRunner.a2a_wrapper/: Contains the FastAPI server that exposes the ADK agent via A2A.main.py: The FastAPI application logic.models.py: Pydantic models for the A2A protocol.
aira_hub_config.py: An illustrative configuration showing how this A2A-wrapped agent might be registered and understood by an AIRA Hub. This file is not run directly by this project.requirements.txt: Python dependencies.README.md: This file.
- ADK Agent: An
LlmAgentthat can converse and utilize tools. - MemoryBlossom:
- Supports multiple memory types (Explicit, Emotional, Procedural, etc.).
- Uses different
sentence-transformersmodels for embedding various memory types. - Calculates memory salience, applies decay.
- Connects related memories using
MemoryConnector. - Persists memories to a JSON file (
memory_blossom_data.json).
- A2A Wrapper:
- Exposes the ADK agent via a
/.well-known/agent.jsonAgent Card. - Handles A2A
tasks/sendrequests through a JSON-RPC endpoint. - Manages ADK sessions based on A2A Task IDs.
- Exposes the ADK agent via a
-
Create a Python Virtual Environment:
python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate
-
Install Dependencies:
pip install -r requirements.txt
-
API Keys:
- Ensure your
GOOGLE_API_KEYenvironment variable is set if you are using Gemini models directly with ADK. - If using other models via LiteLLM (e.g., OpenAI's GPT), set the corresponding API key (e.g.,
OPENAI_API_KEY). Theorchestrator_adk_agent.pycan be modified to useLiteLlm. - You can set these in your shell or create a
.envfile in the project root and load it (e.g., usingpython-dotenvin your scripts, though not explicitly added in these examples for brevity).
- Ensure your
You need to run the A2A Wrapper Server. The ADK agent and MemoryBlossom are part of this server process.
-
Start the A2A Wrapper Server: Navigate to the project root directory.
python -m uvicorn a2a_wrapper.main:app --host 0.0.0.0 --port 8090 --reload
- The server will start, typically on
http://localhost:8090. - The Agent Card will be available at
http://localhost:8090/.well-known/agent.json. - The A2A JSON-RPC endpoint will be
http://localhost:8090/.
- The server will start, typically on
-
Register with AIRA Hub (Manual Step):
- Start your AIRA Hub application.
- Send a POST request to your AIRA Hub's
/registerendpoint. The body should be a JSON payload describing this A2A agent. Seeaira_hub_config.pyfor an example structure.- Key fields for registration:
url: The URL of this A2A Wrapper Server (e.g.,http://localhost:8090).type: "a2a_bridged" (or similar, depending on your Hub's convention).a2a_agent_card_url:http://localhost:8090/.well-known/agent.json.- The Hub will then fetch the card to understand the A2A agent's skills and generate corresponding MCP tool definitions.
- Key fields for registration:
-
Interact via MCP Client:
- Use your MCP client (e.g.,
simpleStreamableHttp.ts) to connect to your AIRA Hub. - List tools: You should see a tool derived from the A2A agent's "general_conversation" skill (e.g., named "TalkToMemoryBlossomADK").
- Call the tool with appropriate arguments. For the "general_conversation" skill, the MCP tool call would look something like:
call-tool TalkToMemoryBlossomADK '{"user_input": "Hello, can you remember that I like hiking?"}'
- Use your MCP client (e.g.,
- MCP Client -> AIRA Hub:
list_tools - AIRA Hub:
- Identifies registered A2A-bridged agents.
- Fetches
agent.jsonfrom the A2A Wrapper (http://localhost:8090/.well-known/agent.json). - Translates the "general_conversation" A2A skill into an MCP tool definition.
- AIRA Hub -> MCP Client: Returns list of available tools, including one for interacting with this ADK agent.
- MCP Client -> AIRA Hub:
call_tool(e.g.,TalkToMemoryBlossomADKwith{"user_input": "..."}) - AIRA Hub:
- Receives MCP
call_tool. - Identifies it's for the A2A-bridged ADK agent.
- Constructs an A2A
tasks/sendJSON-RPC request.method: "tasks/send"params.id: New A2A Task ID (can be MCP call ID).params.message.parts[0].type: "data"params.message.parts[0].data:{"skill_id": "general_conversation", "user_input": "..."}(or however your Hub bridges MCP args to A2A skill params).
- Receives MCP
- AIRA Hub -> A2A Wrapper Server (
http://localhost:8090/): Sends A2Atasks/sendrequest. - A2A Wrapper Server:
- Receives A2A request.
- Extracts
user_input. - Gets/creates an ADK session ID mapped to the A2A Task ID.
- Updates conversation history in ADK session state.
- Calls
adk_runner.run_async()with theuser_input.
- ADK Orchestrator Agent:
- Processes the input.
- May use
add_memory_tool_funcorrecall_memories_tool_func(interacting withMemoryBlossom). - Generates a final text response.
- A2A Wrapper Server:
- Receives final ADK response.
- Updates ADK session history with agent response.
- Formats it as an A2A
TaskResult(with an artifact containing the text). - Sends A2A JSON-RPC response back to AIRA Hub.
- AIRA Hub:
- Receives A2A
TaskResult. - Extracts the text artifact.
- Translates it into an MCP tool response (e.g.,
{"text_response": "..."}).
- Receives A2A
- AIRA Hub -> MCP Client: Sends MCP tool response.
You can test the ADK agent and MemoryBlossom system directly by running:
python orchestrator_adk_agent.py