Project Info
Inspiration
Babushka means two things: the grandmother who never forgets and the nesting doll with a world tucked inside. Both nail the problem we kept hitting — coding assistants forget you between sessions. We wanted an agent you could text like a teammate, one that remembers your projects and gets sharper the more you talk to it.
What it does
Baba Babooshka is a Fetch.ai uAgent that can trigger Claude Code as a network-addressable AI workers for your discussions and project work. Reach her as a human (ASI:One / Agentverse chat) or as another agent (ClaudeRequest → ClaudeResponse). Long-term memory — searches a Redis Agent Memory Server for prior context per sender, prepends it to the prompt, and persists each exchange. Conversations compound. Sentry observability — every timeout, crash, and memory hiccup is captured so the agent never dies silently.
How we built it
Four components, no more: a Fetch.ai uAgent orchestrator, Claude Code as the engine, a Redis Agent Memory Server, and Sentry. The core spawns Claude headlessly as a non-blocking asyncio subprocess and parses its JSON result — and never raises, returning a readable error on any failure so the agent stays up.
Challenges we ran into
The Windows claude .cmd/.exe shim wouldn't resolve under asyncio — fixed with a cross-platform _resolve_claude(). Port collision: the memory server and agent both wanted :8000 (moved memory to :8001). Killing runaway Claude subprocesses cleanly on timeout without leaking processes. Holding scope discipline to four components under a 1.5-day clock.
Accomplishments we're proud of
A genuinely stateful agent — conversations carry across sessions instead of starting cold every time. A core that never crashes: every failure path returns a readable error, so the agent stays alive in the wild. A clean, minimal architecture — four components doing real work, nothing bolted on for show.
What we learned
Memory is a product feature, not a database — retrieving the right top-$k$ context matters more than storing it. "Never raise" is a design philosophy — an agent that returns an honest error beats one that crashes. Observability earns its keep instantly — Sentry turned "why did it hang?" into annotated events.
What's next
Working memory per project, so she tracks the state of each repo separately, not just per sender. Poke / iMessage as a human-facing layer so you can text her about project progress and errors directly. Multi-session orchestration — planning, scaffolding, and coding sessions running in parallel. Smarter memory — summarization and decay so context stays sharp instead of piling up.
Baba Babooshka
A Fetch.ai uAgent for all your discussions and project needs. Like the babushka — the wise grandmother who never forgets and the nesting doll with a whole world tucked inside — Baba Babooshka remembers every conversation and keeps the layers that matter close at hand.
Powered by Claude Code, she carries her own long-term agent memory so each chat picks up where the last one left off, and Sentry keeps watch over every session — so the conversations get sharper the more you talk, and nothing slips through the cracks.
What it does
The agent accepts prompts from two sources:
| Source | Protocol | Use case |
|---|---|---|
| ASI:One / Agentverse chat | Standard chat_protocol | Human users chatting via the Fetch.ai ecosystem |
| Another uAgent | ClaudeRequest → ClaudeResponse | Programmatic agent-to-agent calls |
Each request is enriched with long-term memory: before spawning Claude, the agent searches a Redis Agent Memory Server for prior context from the same sender and prepends it to the prompt; after the run it persists the prompt + result back to memory. Memory is keyed per sender and can be disabled with MEMORY_ENABLED=false.
Safety: the spawned Claude runs with
--dangerously-skip-permissions, so it can read/edit files and run commands insideCLAUDE_WORKDIRautonomously. PointCLAUDE_WORKDIRat a dedicated/sandboxed folder, not your whole machine.
Prerequisites
- Python 3.10+
- Claude Code CLI installed and authenticated (
claude --versionshould work) uagents >= 0.22.0(see requirements.txt)- A running Redis Agent Memory Server (optional — set
MEMORY_ENABLED=falseto skip)
Setup
python -m venv .venv
.venv\Scripts\activate # Windows
# source .venv/bin/activate # macOS / Linux
pip install -r requirements.txt
Memory server
The agent stores long-term memory in a Redis Agent Memory Server. Run it in a separate terminal before starting the agent:
docker compose up api redis
The memory server's API defaults to port 8000, which collides with AGENT_PORT. Run it on 8001 and point MEMORY_SERVER_URL at it (see the Configuration table). To run the agent without memory, set MEMORY_ENABLED=false.
Configuration
All settings are controlled by environment variables:
| Variable | Default | Description |
|---|---|---|
AGENT_SEED | baba-babooshka-seed-change-me | Deterministic seed for the agent's identity. Change this before deploying. |
AGENT_NAME | baba_babooshka | Human-readable name shown on Agentverse |
AGENT_PORT | 8000 | Local HTTP port |
AGENTVERSE_API_KEY | (unset) | API key for the Agentverse mailbox (get one at agentverse.ai) |
CLAUDE_WORKDIR | current working directory | Directory Claude Code runs in. All file edits happen here. |
CLAUDE_MODEL | claude-opus-4-8 | Model passed to claude --model. Empty string = Claude's default. |
CLAUDE_TIMEOUT | 600 | Seconds before a spawned Claude run is killed |
CLAUDE_MAX_TURNS | 40 | Maximum agentic turns per Claude run |
MEMORY_ENABLED | true | Set to false to disable long-term memory entirely |
MEMORY_SERVER_URL | http://localhost:8001 | Base URL of the Redis Agent Memory Server |
Running
export AGENT_SEED="my-unique-secret-seed"
export AGENTVERSE_API_KEY="<your key>"
export CLAUDE_WORKDIR="/path/to/workspace"
python agent.py
On startup the agent logs its address:
INFO: Agent 'baba_babooshka' address: agent1q...
INFO: Claude binary: /usr/local/bin/claude
INFO: Claude workdir: /path/to/workspace
Copy that address to chat with it from ASI:One / Agentverse, or to message it from another agent.
Agent-to-agent usage
from uagents import Agent, Context, Model
class ClaudeRequest(Model):
prompt: str
class ClaudeResponse(Model):
result: str
WORKER = "agent1q..." # address printed on worker startup
@agent.on_event("startup")
async def ask(ctx: Context):
await ctx.send(WORKER, ClaudeRequest(prompt="List files in the workspace."))
@agent.on_message(model=ClaudeResponse)
async def got(ctx: Context, sender: str, msg: ClaudeResponse):
print(msg.result)
Running the test suite
test_local.py runs a full end-to-end test in a single process — it spins up the real worker alongside a throwaway client in a uAgents Bureau, sends a prompt, and checks the reply:
python test_local.py
Expected output on success:
TEST RESULT: worker replied -> 'PONG'
TEST PASSED
Times out after 90 seconds and exits with code 1 on failure.
How it works
run_claude_code() in agent.py launches:
claude -p "<prompt>" --output-format json \
--dangerously-skip-permissions --max-turns 40 --model claude-opus-4-8
via a non-blocking asyncio subprocess, parses the JSON result field, and returns the text. On any failure (missing binary, non-zero exit, timeout) it returns a human-readable error string so the agent stays alive.
When MEMORY_ENABLED is set, each incoming request is wrapped by two helpers in agent.py:
get_memory_context()searches long-term memory for the sender's prior interactions and prepends the top matches to the prompt.save_interaction()persists a summary of the prompt + result as a semantic memory after the run.
Both fail soft — any memory-server error is reported to Sentry and the run continues without memory.
Project layout
agent.py — the worker agent
test_local.py — local end-to-end test
requirements.txt
License
MIT
Analysis
View
Metric
- 6
- 1
Figures cover GitHub contributors during the hackathon window. A co-authored commit counts in full for each author, so per-member totals add up to more than the whole-team figures.
Technology
- PythonIn code
- DockerClaimed
- LangChainClaimed
1 of 3 appear in the indexed code. 2 claimed on Devpost could not be matched to code, which may simply mean the tool leaves no trace in the repository.
AI coding agents
- Claude CodeCommits
Detected from committed agent config files and commit authorship. Absence of a signal is not proof an agent was unused.
Codebase size
Source size
28 KB
Source files
4
Counts recognized source files only; vendored directories, binaries and lockfiles are excluded, so this is smaller than the repository on disk.
Repository
slowloris-98/baba_babooshka
8 files · 1.9 MB · @ 8989b9a
Structure
Application logic
2 files · 25%Domain rules, services and shared utilities.
Supporting
Layers are inferred from where files sit in the tree, not from reading the code. A project that names its directories unconventionally will read oddly here — open the file browser to check anything the diagram implies.
Languages
- Markdown54%
- Python46%
Share of indexed source by file size. Binary and vendored files are excluded.
Dependencies
requirements.txt
pypi · 4- agent-memory-client
- python-dotenv
- sentry-sdk
- uagents
Declared in the repository’s manifests at the indexed commit. A declared package is not proof it is used, and runtime dependencies are listed first.
Feature verification
Cross-platform claude binary resolution (_resolve_claude)Verified
The Windows claude .cmd/.exe shim wouldn't resolve under asyncio, fixed with a cross-platform _resolve_claude()
Claimed on Devposthigh confidenceagent.py:57— _resolve_claude() tries shutil.which for 'claude', 'claude.cmd', 'claude.exe' candidates
Fetch.ai uAgent orchestratorVerified
Baba Babooshka is a Fetch.ai uAgent that can trigger Claude Code
Claimed on Devposthigh confidenceagent.py:209— Agent(name=AGENT_NAME, seed=AGENT_SEED, port=AGENT_PORT, mailbox=..., ...) instantiates a uagents.Agent
Local end-to-end test suiteVerified
test_local.py runs a full end-to-end test in a single process, spins up the real worker alongside a throwaway client, sends a prompt, and checks the reply
Claimed on readmehigh confidencetest_local.py:60— Bureau is populated with both worker (imported from agent.py) and client agents; client sends ClaudeRequest and checks for PONG in the ClaudeResponse
Long-term memory via Redis Agent Memory ServerVerified
Searches a Redis Agent Memory Server for prior context per sender, prepends it to the prompt, and persists each exchange
Claimed on Devposthigh confidenceagent.py:169— get_memory_context calls _memory_client.search_long_term_memory keyed by UserId(eq=user_id) and formats results as prior contextagent.py:188— save_interaction calls _memory_client.create_long_term_memory to persist prompt+result after each runagent.py:270— handle_chat calls get_memory_context then prepends it to the prompt sent to run_claude_code, and calls save_interaction afterward
Memory can be disabled via MEMORY_ENABLEDVerified
Memory is keyed per sender and can be disabled with MEMORY_ENABLED=false
Claimed on readmehigh confidenceagent.py:53— MEMORY_ENABLED env var gates whether _memory_client is constructed at startup (line 229)
Memory server port moved to 8001 to avoid collisionVerified
Port collision: the memory server and agent both wanted :8000 (moved memory to :8001)
Claimed on Devposthigh confidenceagent.py:52— MEMORY_SERVER_URL defaults to http://localhost:8001 while AGENT_PORT defaults to 8000
Reachable as another agent via ClaudeRequest/ClaudeResponseVerified
Reach her as another agent (ClaudeRequest -> ClaudeResponse)
Claimed on readmehigh confidenceagent.py:294— handle_request is registered with @agent.on_message(model=ClaudeRequest, replies=ClaudeResponse) and returns a ClaudeResponse
Reachable as human via ASI:One / Agentverse chatVerified
Reach her as a human via ASI:One / Agentverse chat using standard chat_protocol
Claimed on readmehigh confidenceagent.py:239— chat_proto = Protocol(spec=chat_protocol_spec) and handle_chat processes ChatMessage/TextContent, replying via ctx.send
run_claude_code never raises, always returns readable errorVerified
Never raises, returning a readable error on any failure so the agent stays up
Claimed on Devposthigh confidenceagent.py:87— explicit checks for missing CLAUDE_BIN, OSError on spawn, TimeoutError, and non-zero return code each return a formatted error string instead of raising
Sentry observability for timeouts, crashes, and memory hiccupsVerified
Every timeout, crash, and memory hiccup is captured so the agent never dies silently
Claimed on Devposthigh confidenceagent.py:73— sentry_sdk.init configured from SENTRY_DSNagent.py:131— sentry_sdk.capture_message on Claude timeoutagent.py:151— sentry_sdk.capture_message on non-zero exit codeagent.py:184— sentry_sdk.capture_exception in get_memory_context's except blockagent.py:202— sentry_sdk.capture_exception in save_interaction's except block
Spawns Claude Code headlessly as a subprocessVerified
Core spawns Claude headlessly as a non-blocking asyncio subprocess and parses its JSON result
Claimed on Devposthigh confidenceagent.py:109— asyncio.create_subprocess_exec runs the claude CLI with -p and --output-format json, then json.loads(stdout) parses the result field
Timeout kills runaway Claude subprocessVerified
Killing runaway Claude subprocesses cleanly on timeout without leaking processes
Claimed on Devposthigh confidenceagent.py:124— on asyncio.TimeoutError, proc.kill() is called followed by await proc.communicate() to reap the process
Four-component minimal architectureCode-supported
Four components, no more: a Fetch.ai uAgent orchestrator, Claude Code as the engine, a Redis Agent Memory Server, and Sentry
Claimed on Devpostmedium confidencerequirements.txt:1— dependencies are limited to uagents, sentry-sdk, python-dotenv, agent-memory-client, consistent with the four-component claim, but 'no more than four' is a design description not independently verifiable from code alone
Claude runs with --dangerously-skip-permissionsClaimed only
The spawned Claude runs with --dangerously-skip-permissions, so it can read/edit files and run commands inside CLAUDE_WORKDIR autonomously
Claimed on readmehigh confidenceDocker Compose setup for memory serverClaimed only
Built with Docker; run the memory server via `docker compose up api redis`
Claimed on readmehigh confidenceLangChain integrationClaimed only
Built with: ai, claude, docker, langchain, python, sdk
Claimed on Devposthigh confidenceMulti-session orchestration (future work)Claimed only
Multi-session orchestration: planning, scaffolding, and coding sessions running in parallel
Claimed on Devposthigh confidencePoke / iMessage human-facing layer (future work)Claimed only
Poke / iMessage as a human-facing layer so you can text her about project progress and errors directly
Claimed on Devposthigh confidenceSmarter memory with summarization and decay (future work)Claimed only
Smarter memory: summarization and decay so context stays sharp instead of piling up
Claimed on Devposthigh confidenceWorking memory per project (future work)Claimed only
Working memory per project, so she tracks the state of each repo separately, not just per sender
Claimed on Devposthigh confidence
An AI agent derived these features from the project’s Devpost page and readme, then searched the code for each one. Verified features are backed by cited code; claimed-only features had no supporting code, which is not by itself proof a feature is missing.
Export this project's context (description, README, evidence, key source files) to chat with an AI agent elsewhere.