๐ฆ Self-adapting agent - one file.
Project description
๐ฆ DevDuck
One file. Self-healing. Builds itself as it runs.
An AI agent that hot-reloads its own code, fixes itself when things break, and expands capabilities at runtime. Terminal, browser, cloud โ or all at once.
pipx install devduck && devduck
What It Does
- Hot-reloads โ edit source, agent restarts instantly
- Self-heals โ errors trigger automatic recovery
- 60+ tools โ shell, GitHub, browser control, speech, scheduler, ML, messaging
- Multi-protocol โ CLI, TUI, WebSocket, TCP, MCP, IPC, Zenoh P2P
- Unified mesh โ terminal + browser + cloud agents in one network
- Deploys anywhere โ
devduck deploy --launchโ AWS AgentCore
Requirements: Python 3.10โ3.13 + any model provider (AWS, Anthropic, OpenAI, Ollama, Gemini, etc.)
Quick Start
devduck # interactive REPL
devduck --tui # multi-conversation terminal UI
devduck "create a REST API" # one-shot
devduck --record # record session for replay
devduck --resume session.zip # resume from snapshot
devduck deploy --launch # ship to AgentCore
import devduck
devduck("analyze this code")
Power User Setup
A real-world .zshrc config for daily driving DevDuck with all the bells and whistles:
# Model โ Claude Opus via Bedrock bearer token (fastest auth, no STS calls)
export AWS_BEARER_TOKEN_BEDROCK="ABSK..."
export STRANDS_MODEL_ID="global.anthropic.claude-opus-4-6-v1"
export STRANDS_MAX_TOKENS="64000"
# Tools โ curated toolset (loads faster than all 60+)
export DEVDUCK_TOOLS="devduck.tools:use_github,editor,system_prompt,store_in_kb,manage_tools,websocket,zenoh_peer,agentcore_proxy,manage_messages,sqlite_memory,dialog,listen,use_computer,tasks,scheduler,telegram;strands_tools:retrieve,shell,file_read,file_write,use_agent"
# Knowledge Base โ automatic RAG (stores & retrieves every conversation)
export STRANDS_KNOWLEDGE_BASE_ID="YOUR_KB_ID"
# MCP โ auto-load Strands docs server
export MCP_SERVERS='{"mcpServers":{"strands-docs":{"command":"uvx","args":["strands-agents-mcp-server"]}}}'
# Messaging โ Telegram & Slack bots
export TELEGRAM_BOT_TOKEN="your-telegram-bot-token"
export SLACK_BOT_TOKEN="xoxb-your-slack-bot-token"
export SLACK_APP_TOKEN="xapp-your-slack-app-token"
# Spotify control
export SPOTIFY_CLIENT_ID="your-client-id"
export SPOTIFY_CLIENT_SECRET="your-client-secret"
export SPOTIFY_REDIRECT_URI="http://127.0.0.1:8888/callback"
# Gemini as fallback/sub-agent model
export GEMINI_API_KEY="your-gemini-key"
This gives you:
- ๐ง Opus on Bedrock as primary model with bearer token (zero-latency auth)
- ๐ Auto-RAG โ every conversation stored in Knowledge Base, context retrieved before each query
- ๐ Strands docs available as MCP tools (search + fetch)
- ๐ฑ Telegram + Slack listeners ready (
telegram(action="start_listener")) - ๐ต Spotify control via
use_spotify - ๐ Zenoh P2P + mesh auto-enabled (multi-terminal awareness)
- ๐ฌ 26 tools loaded on startup, expandable to 60+ on demand via
manage_tools
Model Detection
Set your key. DevDuck figures out the rest.
export ANTHROPIC_API_KEY=sk-ant-... # โ uses Anthropic
export OPENAI_API_KEY=sk-... # โ uses OpenAI
export GOOGLE_API_KEY=... # โ uses Gemini
# or just have AWS credentials # โ uses Bedrock
# or nothing at all # โ uses Ollama
Priority: Bedrock โ Anthropic โ OpenAI โ GitHub โ Gemini โ Cohere โ Writer โ Mistral โ LiteLLM โ LlamaAPI โ MLX โ Ollama
Override: MODEL_PROVIDER=bedrock STRANDS_MODEL_ID=us.anthropic.claude-sonnet-4-20250514-v1:0 devduck
Tools
Runtime โ no restart needed
manage_tools(action="add", tools="strands_fun_tools.cursor")
manage_tools(action="create", code='...')
manage_tools(action="fetch", url="https://github.com/user/repo/blob/main/tool.py")
Hot-reload from disk
Drop a .py file in ./tools/ โ it's available immediately.
# ./tools/weather.py
from strands import tool
import requests
@tool
def weather(city: str) -> str:
"""Get weather for a city."""
return requests.get(f"https://wttr.in/{city}?format=%C+%t").text
Static config
export DEVDUCK_TOOLS="strands_tools:shell,editor;devduck.tools:use_github,scheduler"
Architecture
devduck/
โโโ __init__.py # the whole agent โ single file
โโโ tui.py # multi-conversation Textual UI
โโโ tools/ # 60+ built-in tools (hot-reloadable)
โโโ agentcore_handler.py # AWS AgentCore deployment handler
User โ [CLI/TUI/WS/TCP/MCP/IPC] โ DevDuck Core โ Tools โ Response
โ โ
Zenoh P2P Knowledge Base
โ
Browser + Cloud
(Unified Mesh)
Ports: 10000 (mesh relay) ยท 10001 (WebSocket) ยท 10002 (TCP) ยท 10003 (MCP)
TUI Concurrency Model
The TUI (devduck --tui) supports true concurrent conversations with shared awareness:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ SharedMessages (thread-safe) โ
โ [msg1, msg2, msg3, msg4, ...] โ
โโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโ
โ โ โ
โผ โผ โผ
โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ
โ Agent #1 โ โ Agent #2 โ โ Agent #3 โ
โ cb โ ๐ฆ โ โ cb โ ๐ฉ โ โ cb โ ๐จ โ
โ panel #1 โ โ panel #2 โ โ panel #3 โ
โโโโโโโโโโโโ โโโโโโโโโโโโ โโโโโโโโโโโโ
All agents share the SAME messages list
Each conversation creates a fresh Agent (like TCP/Telegram tools do), but all agents point their .messages at a single SharedMessages instance โ a thread-safe list subclass that serializes all reads and writes via a lock. This gives you:
- True concurrency โ separate Agent instances with separate callback handlers, no conflicts
- Real-time shared awareness โ when Agent #1 appends a message, Agent #2 sees it immediately on its next loop iteration
- Correct ordering โ the lock ensures messages are appended in the order they're produced
- Isolated rendering โ each agent's callback handler routes streaming output to its own color-coded TUI panel
The shared history is capped at 100 messages (configurable via DEVDUCK_TUI_MAX_SHARED_MESSAGES) and auto-clears on context window overflow.
Comparison across interfaces:
| Interface | Agent per request | Shared messages | Use case |
|---|---|---|---|
| CLI | No (reuse one) | N/A (single-threaded) | Sequential interactive REPL |
| TUI | Yes (fresh Agent) | Yes (SharedMessages) |
Concurrent conversations with shared context |
| TCP | Yes (fresh DevDuck) | No (fully isolated) | External network clients |
| Telegram | Yes (fresh DevDuck) | No (fully isolated) | Chat bot, each user isolated |
| WebSocket | Yes (fresh DevDuck) | No (fully isolated) | Browser clients |
Multi-Agent Networking
Zenoh P2P โ zero config
# Terminal 1
devduck # โ Zenoh peer: hostname-abc123
# Terminal 2
devduck # auto-discovers Terminal 1
zenoh_peer(action="broadcast", message="git pull && npm test") # all peers
zenoh_peer(action="send", peer_id="hostname-abc123", message="status?") # one peer
Cross-network: ZENOH_CONNECT=tcp/remote:7447 devduck
Unified Mesh โ everything connected
Terminal DevDucks (Zenoh) + browser tabs (WebSocket) + AgentCore agents (AWS) share one ring context. Open mesh.html to join from a browser.
Deploy
devduck deploy --launch
devduck deploy --name reviewer --tools "strands_tools:shell,editor" --launch
devduck list # see deployed agents
devduck invoke "analyze code" --name reviewer
Session Recording & Resume
devduck --record # captures sys/tool/agent events
devduck --resume session.zip # restores conversation + state
devduck --resume session.zip "continue where we left off"
from devduck import load_session
session = load_session("session.zip")
session.resume_from_snapshot(2, agent=devduck.agent)
Asciinema: DEVDUCK_ASCIINEMA=true devduck โ shareable .cast files.
Background Modes
# Standard ambient โ thinks while you're idle
DEVDUCK_AMBIENT_MODE=true devduck
# Autonomous โ works until done
๐ฆ auto
# Agent signals [AMBIENT_DONE] when finished
Messaging
# Telegram
TELEGRAM_BOT_TOKEN=... STRANDS_TELEGRAM_AUTO_REPLY=true devduck
telegram(action="start_listener")
# Slack
SLACK_BOT_TOKEN=xoxb-... SLACK_APP_TOKEN=xapp-... devduck
slack(action="start_listener")
# WhatsApp (via wacli, no Cloud API)
whatsapp(action="start_listener")
Each incoming message spawns a fresh DevDuck with full tool access.
MCP
Expose as server (Claude Desktop):
{"mcpServers": {"devduck": {"command": "uvx", "args": ["devduck", "--mcp"]}}}
Load external servers:
export MCP_SERVERS='{"mcpServers": {"docs": {"command": "uvx", "args": ["strands-agents-mcp-server"]}}}'
macOS
use_mac(action="calendar.events", days=7)
use_mac(action="mail.send", to="x@y.com", subject="Hi", body="Hello")
use_mac(action="safari.read")
use_mac(action="system.screenshot", path="/tmp/shot.png")
use_mac(action="system.dark_mode", enable=True)
use_mac(action="keychain.get", service="MyApp", account="me")
apple_notes(action="list")
use_spotify(action="now_playing")
More Tools
| Tool | What |
|---|---|
shell |
Interactive PTY shell |
editor |
File create/replace/insert/undo |
use_github |
GitHub GraphQL API |
use_computer |
Mouse, keyboard, screenshots |
listen |
Background Whisper transcription |
lsp |
Language server diagnostics |
scheduler |
Cron + one-time jobs |
tasks |
Parallel background agents |
sqlite_memory |
Persistent memory with FTS |
dialog |
Rich terminal UI dialogs |
speech_to_speech |
Nova Sonic / OpenAI / Gemini voice |
rl |
Train RL agents, fine-tune LLMs |
scraper |
HTML/XML parsing |
use_agent |
Nested agents with different models |
retrieve / store_in_kb |
Bedrock Knowledge Base RAG |
All 60+ tools
Core: system_prompt ยท manage_tools ยท manage_messages ยท tasks ยท scheduler ยท sqlite_memory ยท dialog ยท notify ยท use_computer ยท listen ยท lsp ยท tui ยท session_recorder ยท view_logs
Network: tcp ยท websocket ยท ipc ยท mcp_server ยท zenoh_peer ยท agentcore_proxy ยท unified_mesh ยท mesh_registry ยท jsonrpc
Platform: use_mac ยท apple_notes ยท use_spotify ยท telegram ยท whatsapp ยท slack
Cloud: use_github ยท fetch_github_tool ยท gist ยท agentcore_config ยท agentcore_invoke ยท agentcore_logs ยท agentcore_agents ยท create_subagent ยท store_in_kb ยท retrieve
AI/ML: rl ยท speech_to_speech ยท use_agent ยท scraper
macOS Native: apple_nlp ยท apple_vision ยท apple_wifi ยท apple_sensors ยท apple_smc
Strands: shell ยท editor ยท file_read ยท file_write ยท calculator ยท image_reader ยท speak
AGENTS.md
Drop an AGENTS.md in your working directory. DevDuck auto-loads it into the system prompt. No config needed.
# AGENTS.md
## Project: My API
- Framework: FastAPI
- Tests: pytest
- Deploy: Docker on ECS
Config Reference
All environment variables
| Variable | Default | What |
|---|---|---|
MODEL_PROVIDER |
auto | bedrock anthropic openai github gemini cohere writer mistral litellm llamaapi mlx ollama |
STRANDS_MODEL_ID |
auto | Model name |
DEVDUCK_TOOLS |
60+ tools | package:tool1,tool2;package2:tool3 |
DEVDUCK_LOAD_TOOLS_FROM_DIR |
false |
Auto-load ./tools/*.py |
DEVDUCK_KNOWLEDGE_BASE_ID |
โ | Bedrock KB for auto-RAG |
MCP_SERVERS |
โ | JSON config for MCP servers |
DEVDUCK_ENABLE_WS |
true |
WebSocket server |
DEVDUCK_ENABLE_ZENOH |
true |
Zenoh P2P |
DEVDUCK_ENABLE_AGENTCORE_PROXY |
true |
Mesh relay |
DEVDUCK_ENABLE_TCP |
false |
TCP server |
DEVDUCK_ENABLE_MCP |
false |
MCP HTTP server |
DEVDUCK_ENABLE_IPC |
false |
IPC socket |
DEVDUCK_WS_PORT |
10001 |
WebSocket port |
DEVDUCK_TCP_PORT |
10002 |
TCP port |
DEVDUCK_MCP_PORT |
10003 |
MCP port |
DEVDUCK_AGENTCORE_PROXY_PORT |
10000 |
Mesh relay port |
DEVDUCK_AMBIENT_MODE |
false |
Background thinking |
DEVDUCK_AMBIENT_IDLE_SECONDS |
30 |
Idle before ambient starts |
DEVDUCK_AMBIENT_MAX_ITERATIONS |
3 |
Max ambient iterations |
DEVDUCK_AUTONOMOUS_MAX_ITERATIONS |
100 |
Max autonomous iterations |
DEVDUCK_ASCIINEMA |
false |
Record .cast files |
DEVDUCK_TUI_MAX_SHARED_MESSAGES |
100 |
Max shared message history in TUI |
DEVDUCK_LSP_AUTO_DIAGNOSTICS |
false |
Auto LSP after edits |
TELEGRAM_BOT_TOKEN |
โ | Telegram bot |
SLACK_BOT_TOKEN |
โ | Slack bot |
SPOTIFY_CLIENT_ID |
โ | Spotify |
Dev Setup
git clone git@github.com:cagataycali/devduck.git && cd devduck
python3.13 -m venv .venv && source .venv/bin/activate
pip install -e . && devduck
GitHub Actions
- uses: cagataycali/devduck@main
with:
task: "Review this PR"
provider: "github"
model: "gpt-4o"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Citation
@software{devduck2025,
author = {Cagatay Cali},
title = {DevDuck: Self-Modifying AI Agent},
year = {2025},
url = {https://github.com/cagataycali/devduck}
}
Apache 2.0 ยท Built with Strands Agents ยท @cagataycali
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file devduck-1.10.2.tar.gz.
File metadata
- Download URL: devduck-1.10.2.tar.gz
- Upload date:
- Size: 15.2 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
811be890b0b230fb9a81cc743acab45d0c3354857f4e335ade7fbae6e410caf3
|
|
| MD5 |
b9a7c139412b81df035123aa80d731df
|
|
| BLAKE2b-256 |
1abea757555a06e0beff7ec2941c9c4c94fbc0c7341ad366cbac6e118d82b3f9
|
File details
Details for the file devduck-1.10.2-py3-none-any.whl.
File metadata
- Download URL: devduck-1.10.2-py3-none-any.whl
- Upload date:
- Size: 360.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
91828a2495b3923bbb41ee913e2b2bf4ef87efbea6a69bc3560ba44cd84273fa
|
|
| MD5 |
1d70bbac0d35ad63e2c799cc94e2c9f5
|
|
| BLAKE2b-256 |
d0a95200644f1db5a914dcee7ee8f0f79c58dcaa60eddc79fe85f8fb100525a0
|