Skip to main content

๐Ÿฆ† Self-adapting agent - one file.

Project description

๐Ÿฆ† DevDuck

PyPI

Self-modifying AI agent that hot-reloads its own codeโ€”builds itself as it runs.

One Python file that adapts to your environment, fixes itself, and expands capabilities at runtime. Deploy anywhere โ€” terminal, browser, cloud, or all at once in a unified mesh.

Learn more: https://duck.nyc

๐ŸŽฌ See It In Action

Feature What You'll See Demo
๐Ÿ”ฅ Hot-Reload Agent detects code changes and restarts instantly Watch
๐ŸŒ Web UI Clean web interface with real-time streaming Watch
๐Ÿ› ๏ธ Dynamic Tools Save .py file in ./tools/ โ†’ use instantly Watch
๐ŸŒŠ TCP Streaming Connect via netcat, apps, or other agents Watch
๐Ÿ”— Zenoh P2P Auto-discover & coordinate multiple DevDucks Multi-terminal magic โœจ
๐ŸŽฌ Session Recording Record, replay & resume agent sessions Time-travel debugging ๐Ÿ•ฐ๏ธ
๐ŸŒ™ Ambient Mode Background thinking while you're idle Auto-explores topics ๐Ÿง 
๐Ÿ”Œ IPC & Tray macOS menu bar + Unix socket IPC Demo
๐Ÿ’ฌ Ambient Overlay Floating AI input with glassmorphism UI Watch

| ๐ŸŒ Unified Mesh | Connect CLI + browser + cloud agents in one mesh | All agents, one network ๐Ÿ•ธ๏ธ | | โ˜๏ธ Deploy CLI | devduck deploy --launch to AgentCore | One-command cloud deploy ๐Ÿš€ | | ๐Ÿงฉ Browser Peers | Browser tabs join the mesh as first-class peers | Open mesh.html to join ๐ŸŒ |


Quick Start

# Install & run
pipx install devduck && devduck

# With speech-to-speech capabilities (optional)
pipx install "devduck[speech]" && devduck

# One-shot query
devduck "create a REST API with FastAPI"

# Python API
python -c "import devduck; devduck('analyze this code')"

# Session recording (time-travel debugging)
devduck --record "analyze this codebase"
# โ†’ Exports to /tmp/devduck/recordings/session-*.zip

# Resume from recorded session
devduck --resume session-20250202-123456.zip "continue where we left off"

# Deploy to AWS AgentCore
devduck deploy --launch
devduck deploy --name my-agent --tools "strands_tools:shell,editor" --launch

Requirements: Python 3.10-3.13, AWS credentials (or Ollama/Anthropic/GitHub/MLX)

Optional extras:

  • devduck[speech] - Real-time speech-to-speech conversations (Nova Sonic, OpenAI Realtime, Gemini Live)

Core Capabilities

Feature What It Does How to Use
๐Ÿ”ฅ Hot-Reload Auto-restarts on code changes Edit __init__.py โ†’ saves โ†’ auto-restart
๐Ÿ› ๏ธ Runtime Tools Add/remove tools without restart manage_tools(action="add", ...)
๐Ÿ“ฆ Dynamic Loading Install packages and load tools on-the-fly install_tools(action="install_and_load", package="...")
๐Ÿง  Auto-RAG Remembers conversations via Knowledge Base Set DEVDUCK_KNOWLEDGE_BASE_ID
๐ŸŒŠ Multi-Protocol TCP, WebSocket, MCP, IPC servers Auto-starts on ports 10001, 10002, 10003
๐Ÿ”— Zenoh P2P Auto-discover & coordinate with other DevDucks zenoh_peer(action="broadcast", message="...")
๐ŸŒ Unified Mesh Connect CLI + browser + cloud agents Auto-starts relay on port 10000
โ˜๏ธ Deploy CLI One-command AgentCore deployment devduck deploy --launch
๐Ÿ”Œ MCP Client Connect to external MCP servers Set MCP_SERVERS env var
๐ŸŽฌ Session Recording Record & replay entire sessions devduck --record or session_recorder()
๐Ÿ’พ State Time-Travel Save/restore agent state state_manager(action="export")
๐ŸŒ™ Ambient Mode Background thinking when idle DEVDUCK_AMBIENT_MODE=true or type ambient
๐Ÿ“ Self-Improvement Updates own system prompt system_prompt(action="add_context", ...)
โ˜๏ธ AWS Deploy One-command serverless devduck deploy --launch
๐ŸŽค Speech-to-Speech Real-time voice conversations pip install devduck[speech]

Developer Setup

git clone git@github.com:cagataycali/devduck.git
cd devduck
python3.13 -m venv .venv
source .venv/bin/activate

# Basic install
.venv/bin/pip3.13 install -e .

# With speech capabilities
.venv/bin/pip3.13 install -e ".[speech]"

devduck

Architecture

graph TB
    A[User Input] -->|CLI/TCP/WS/MCP/IPC| B[DevDuck Core]
    B -->|Auto RAG| C[Knowledge Base]
    C -.->|Context Retrieval| B
    B -->|Tool Calls| D[40+ Built-in Tools]
    D --> E[shell/editor/calculator]
    D --> F[GitHub/AgentCore]
    D --> G[TCP/WebSocket/MCP/IPC]
    D --> H[tray/ambient/cursor/clipboard]
    B -->|Hot-reload| I[./tools/*.py + __init__.py]
    I -.->|Load Instantly| D
    B -->|Runtime| K[manage_tools/install_tools]
    K -.->|Expand| D
    B <-->|Zenoh P2P| L[Other DevDucks]
    L -.->|Auto-discover| B
    B <-->|Unified Mesh| M[Browser Peers + AgentCore]
    M -.->|Ring Context| B
    B -->|Deploy| N[devduck deploy โ†’ AgentCore]
    B -->|Response| J[User Output]
    J -.->|Store Memory| C
    
    style B fill:#e1f5ff
    style C fill:#d4edda
    style I fill:#fff3cd
    style K fill:#ffe6cc
    style L fill:#f0e6ff
    style M fill:#ffe6f0

Self-adapting loop: Query โ†’ RAG โ†’ Tools โ†’ Response โ†’ Memory โ†’ Hot-reload/Runtime-load โ†’ Repeat


Model Setup

DevDuck auto-detects providers based on credentials:

Priority: Bedrock โ†’ Anthropic โ†’ OpenAI โ†’ GitHub โ†’ Gemini โ†’ Cohere โ†’ Writer โ†’ Mistral โ†’ LiteLLM โ†’ LlamaAPI โ†’ MLX โ†’ Ollama

Provider API Key Auto-Detected
Bedrock AWS credentials โœ… If boto3 auth succeeds
Anthropic ANTHROPIC_API_KEY โœ… If key present
OpenAI OPENAI_API_KEY โœ… If key present
GitHub GITHUB_TOKEN or PAT_TOKEN โœ… If key present
Gemini GOOGLE_API_KEY or GEMINI_API_KEY โœ… If key present
Cohere COHERE_API_KEY โœ… If key present
Writer WRITER_API_KEY โœ… If key present
Mistral MISTRAL_API_KEY โœ… If key present
LiteLLM LITELLM_API_KEY โœ… If key present
LlamaAPI LLAMAAPI_API_KEY โœ… If key present
MLX No key needed โœ… On Apple Silicon (M1/M2/M3)
Ollama No key needed โœ… Fallback if nothing else found

Just set your API key - DevDuck handles the rest:

export ANTHROPIC_API_KEY=sk-ant-...
devduck  # Auto-uses Anthropic

export OPENAI_API_KEY=sk-...
devduck  # Auto-uses OpenAI

export GOOGLE_API_KEY=...
devduck  # Auto-uses Gemini

Manual override:

export MODEL_PROVIDER=bedrock
export STRANDS_MODEL_ID=us.anthropic.claude-sonnet-4-20250514-v1:0
devduck

Tool Management

Runtime Tool Management

Add, remove, or reload tools while agent is running:

# List all loaded tools
manage_tools(action="list")

# Add tools from a package at runtime
manage_tools(action="add", package="strands_fun_tools", tool_names="cursor,clipboard,bluetooth")

# Remove tools you don't need
manage_tools(action="remove", tool_names="cursor,clipboard")

# Reload specific tools after editing
manage_tools(action="reload", tool_names="shell,editor")

# Reload all tools (restarts agent)
manage_tools(action="reload")

# Load custom tool from file
manage_tools(action="add", tool_path="./my_custom_tool.py")

Dynamic Package Installation

Install Python packages and load their tools at runtime:

# Discover available tools before loading
install_tools(action="list_available", package="strands-fun-tools", module="strands_fun_tools")

# Install package and load all tools
install_tools(action="install_and_load", package="strands-agents-tools", module="strands_tools")

# Install and load specific tools only
install_tools(
    action="install_and_load",
    package="strands-fun-tools", 
    module="strands_fun_tools",
    tool_names=["clipboard", "cursor", "bluetooth"]
)

# Load tools from already installed package
install_tools(action="load", module="strands_tools", tool_names=["shell", "calculator"])

# List currently loaded tools
install_tools(action="list_loaded")

Static Tool Configuration

Format: package1:tool1,tool2;package2:tool3,tool4

# Minimal (shell + editor only)
export DEVDUCK_TOOLS="strands_tools:shell,editor"

# Dev essentials
export DEVDUCK_TOOLS="strands_tools:shell,editor,file_read,file_write,calculator"

# Full stack + GitHub
export DEVDUCK_TOOLS="devduck.tools:tcp,websocket,mcp_server,use_github;strands_tools:shell,editor,file_read"

devduck

Hot-Reload Tools from Directory

Create ./tools/weather.py:

from strands import tool
import requests

@tool
def weather(city: str) -> str:
    """Get weather for a city."""
    r = requests.get(f"https://wttr.in/{city}?format=%C+%t")
    return r.text

Enable directory auto-loading:

export DEVDUCK_LOAD_TOOLS_FROM_DIR=true
devduck
# Save weather.py โ†’ use instantly (no restart needed)

Default: Directory loading is OFF. Use manage_tools() or install_tools() for explicit control.


Speech-to-Speech (Optional)

Install speech capabilities:

pip install "devduck[speech]"

Real-time voice conversations with multiple providers:

# Start speech session with Nova Sonic (AWS Bedrock)
speech_to_speech(action="start", provider="novasonic")

# Start with OpenAI Realtime API
speech_to_speech(action="start", provider="openai")

# Start with Gemini Live
speech_to_speech(action="start", provider="gemini_live")

# Custom voice and settings
speech_to_speech(
    action="start",
    provider="novasonic",
    model_settings={
        "provider_config": {"audio": {"voice": "matthew"}},
        "client_config": {"region": "us-east-1"}
    }
)

# Stop session
speech_to_speech(action="stop", session_id="speech_20250126_140000")

# Check status
speech_to_speech(action="status")

# List conversation histories
speech_to_speech(action="list_history")

# List available audio devices
speech_to_speech(action="list_audio_devices")

Supported Providers:

  • Nova Sonic (AWS Bedrock): 11 voices (English, French, Italian, German, Spanish)
  • OpenAI Realtime API: GPT-4o Realtime models
  • Gemini Live: Native audio streaming

Environment Variables:

  • OPENAI_API_KEY - For OpenAI Realtime
  • GOOGLE_API_KEY or GEMINI_API_KEY - For Gemini Live
  • AWS credentials - For Nova Sonic (boto3 default credential chain)

Features:

  • Background execution (parent agent stays responsive)
  • Tool inheritance from parent agent
  • Conversation history saved automatically
  • Natural interruption with VAD
  • Custom audio device selection

MCP Integration

As MCP Server (Expose DevDuck)

Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json):

{
  "mcpServers": {
    "devduck": {
      "command": "uvx",
      "args": ["devduck", "--mcp"]
    }
  }
}

Or start HTTP MCP server:

mcp_server(action="start", port=8000, stateless=True)
# Connect at: http://localhost:8000/mcp

Modes: --mcp (stdio for Claude Desktop) | http (background server) | stateless=True (multi-node)

As MCP Client (Load External Servers)

Expand capabilities by loading tools from external MCP servers:

export MCP_SERVERS='{
  "mcpServers": {
    "strands-docs": {"command": "uvx", "args": ["strands-agents-mcp-server"]},
    "remote": {"url": "https://api.example.com/mcp", "headers": {"Auth": "Bearer token"}},
    "custom": {"command": "python", "args": ["my_server.py"]}
  }
}'
devduck

Supported transports: stdio (command/args/env) | HTTP (url/headers) | SSE (url with /sse path)

Tool prefixing: Each server's tools get prefixed (e.g., strands-docs_search_docs)


Zenoh Peer-to-Peer Networking

Auto-discover and coordinate multiple DevDuck instances across terminals or networks.

How It Works

  1. Each DevDuck joins a Zenoh peer network
  2. Multicast scouting (224.0.0.224:7446) auto-discovers peers on local network
  3. Peers exchange heartbeats to maintain presence awareness
  4. Commands can be broadcast to ALL peers or sent to specific peers
  5. Responses stream back in real-time

Quick Start

# Terminal 1: Start DevDuck (Zenoh enabled by default)
devduck
# ๐Ÿฆ† โœ“ Zenoh peer: hostname-abc123

# Terminal 2: Start another DevDuck
devduck
# ๐Ÿฆ† โœ“ Zenoh peer: hostname-def456
# Auto-discovers Terminal 1!

# Terminal 1: See discovered peers
๐Ÿฆ† zenoh_peer(action="list_peers")

# Terminal 1: Broadcast to ALL DevDucks
๐Ÿฆ† zenoh_peer(action="broadcast", message="git status")
# Both terminals execute and stream responses!

# Send to specific peer
๐Ÿฆ† zenoh_peer(action="send", peer_id="hostname-def456", message="what files are here?")

Cross-Network Connections

Connect DevDuck instances across different networks:

# Machine A (office): Listen for remote connections
export ZENOH_LISTEN="tcp/0.0.0.0:7447"
devduck

# Machine B (home): Connect to office
export ZENOH_CONNECT="tcp/office.example.com:7447"
devduck

# Now they can communicate!
๐Ÿฆ† zenoh_peer(action="broadcast", message="sync all repos")

Use Cases

Scenario Command Description
Multi-terminal ops broadcast "git pull && npm install" Run on all instances
Distributed tasks broadcast "analyze ./src" Parallel analysis
Peer monitoring list_peers See all active DevDucks
Direct messaging send peer_id="..." message="..." Task specific instance
Cross-network Set ZENOH_CONNECT Connect home โ†” office

Actions

# Start Zenoh networking (auto-starts by default)
zenoh_peer(action="start")

# Stop Zenoh
zenoh_peer(action="stop")

# Check status and peer count
zenoh_peer(action="status")

# List all discovered peers
zenoh_peer(action="list_peers")

# Broadcast to ALL peers (waits for responses)
zenoh_peer(action="broadcast", message="your command", wait_time=60)

# Send to specific peer
zenoh_peer(action="send", peer_id="hostname-abc123", message="your command", wait_time=120)

# Start with remote connection
zenoh_peer(action="start", connect="tcp/remote.example.com:7447")

# Start listening for remote connections
zenoh_peer(action="start", listen="tcp/0.0.0.0:7447")

Environment Variables

Variable Default Description
DEVDUCK_ENABLE_ZENOH true Auto-start Zenoh on launch
ZENOH_CONNECT - Remote endpoint(s) to connect to
ZENOH_LISTEN - Endpoint(s) to listen on for remote connections

Features

  • Zero Config: Just start multiple DevDucks - they find each other
  • Real-time Streaming: Responses stream as they're generated
  • Peer Awareness: Dynamic context injection shows connected peers
  • Cross-Network: Connect instances across different networks
  • Fault Tolerant: Peers auto-detect disconnections (15s timeout)

Unified Mesh (CLI + Browser + Cloud)

Connect ALL agent types โ€” terminal DevDucks, browser tabs, and cloud-deployed agents โ€” into a single unified network with shared context.

How It Works

  1. Mesh Relay auto-starts on port 10000 (WebSocket)
  2. File-based Registry (/tmp/devduck/mesh_registry.json) tracks all agents
  3. Browser peers connect via mesh.html and register as first-class mesh participants
  4. Ring context is shared bidirectionally: CLI writes โ†’ browser sees it, browser writes โ†’ CLI sees it
  5. AgentCore agents (deployed to AWS) appear alongside local agents

Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                 Unified Mesh                     โ”‚
โ”‚                                                  โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚ Terminal  โ”‚  โ”‚ Browser  โ”‚  โ”‚  AgentCore   โ”‚  โ”‚
โ”‚  โ”‚ DevDuck  โ”‚  โ”‚  Tab(s)  โ”‚  โ”‚  (Cloud)     โ”‚  โ”‚
โ”‚  โ”‚ (Zenoh)  โ”‚  โ”‚ (WS)     โ”‚  โ”‚  (AWS)       โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚       โ”‚              โ”‚               โ”‚           โ”‚
โ”‚       โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜           โ”‚
โ”‚                      โ”‚                           โ”‚
โ”‚           โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                โ”‚
โ”‚           โ”‚  mesh_registry.json โ”‚                โ”‚
โ”‚           โ”‚  (file-based, TTL)  โ”‚                โ”‚
โ”‚           โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                โ”‚
โ”‚                                                  โ”‚
โ”‚           Ring Context (shared memory)           โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Port Allocation

Port Service Description
10000 Mesh Relay AgentCore proxy + browser gateway
10001 WebSocket Per-message DevDuck server
10002 TCP Raw socket server
10003 MCP HTTP Model Context Protocol
10004 IPC Reserved for Unix socket gateway

Quick Start

# Terminal: Start DevDuck (mesh auto-starts)
devduck
# ๐Ÿฆ† โœ“ AgentCore proxy: ws://localhost:10000
# ๐Ÿฆ† โœ“ Zenoh peer: hostname-abc123

# Browser: Open mesh.html โ†’ auto-connects to ws://localhost:10000
# Browser agents appear in zenoh peer list!

# See all agents in the mesh
๐Ÿฆ† unified_mesh(action="list_all")

# Route to any agent type
๐Ÿฆ† unified_mesh(action="route", target="browser:abc123", message="hello")
๐Ÿฆ† unified_mesh(action="route", target="hostname-def456", message="git status")

Mesh Registry

The file-based registry provides crash-safe agent discovery with zero race conditions:

from devduck.tools.mesh_registry import registry

# All reads are lock-free (read whatever's on disk)
agents = registry.get_all()              # All live agents
zenoh = registry.get_by_type("zenoh")    # Filter by type
agent = registry.get_agent("my-id")      # Single lookup

# Writes use fcntl.flock() + atomic rename
registry.register("my-agent", "local", {"name": "test"})
registry.heartbeat("my-agent")           # Update last_seen
registry.unregister("my-agent")          # Graceful shutdown

# Stale entries auto-expire (30s TTL) โ€” crash-safe
print(registry.summary())

Ring Context

Shared memory across all agents:

# Add to ring (auto-broadcasts to browsers)
unified_mesh(action="add_ring", agent_id="devduck", text="Working on file analysis")

# Get recent ring entries
unified_mesh(action="get_ring", max_entries=20)

# Ring is injected into every agent query as dynamic context

AgentCore Deployment (Deploy CLI)

One-command deployment of DevDuck to Amazon Bedrock AgentCore:

Quick Deploy

# Configure and deploy with defaults
devduck deploy --launch

# Custom agent
devduck deploy --name code-reviewer \
  --tools "strands_tools:shell,editor,file_read" \
  --model "us.anthropic.claude-sonnet-4-20250514-v1:0" \
  --system-prompt "You are a senior code reviewer" \
  --launch

# Configure only (don't launch yet)
devduck deploy --name my-agent

# Launch separately
agentcore launch -a my_agent --auto-update-on-conflict

Deploy Options

devduck deploy [OPTIONS]

Options:
  --name, -n          Agent name (default: devduck)
  --tools, -t         Tool config (e.g., "strands_tools:shell,editor")
  --model, -m         Model ID override
  --region, -r        AWS region (default: us-west-2)
  --launch            Auto-launch after configure
  --system-prompt, -s Custom system prompt
  --idle-timeout      Idle timeout seconds (default: 900)
  --max-lifetime      Max lifetime seconds (default: 28800)
  --no-memory         Disable AgentCore memory (STM)
  --no-otel           Disable OpenTelemetry
  --env KEY=VALUE     Additional env vars (repeatable)
  --force-rebuild     Force rebuild dependencies

Manage Deployed Agents

# List all deployed agents
devduck list

# Check agent status
devduck status --name my-agent

# Invoke a deployed agent
devduck invoke "analyze this code" --name my-agent

# Invoke by agent ID directly
devduck invoke "hello" --agent-id abc123-def456

Proxy Integration

Deployed agents automatically appear in the unified mesh:

# DevDuck auto-starts proxy on ws://localhost:10000
# Open mesh.html to see ALL agents (local + cloud)

# WebSocket protocol:
# {"type": "list_agents"}                              โ†’ See all agents
# {"type": "invoke", "agent_id": "...", "prompt": "..."} โ†’ Invoke any agent
# {"type": "get_ring"}                                  โ†’ Get ring context

Advanced Features

๐ŸŽฌ Session Recording (Time-Travel Debugging)

Record entire sessions for replay, debugging, and state restoration:

# CLI: Start with recording enabled
devduck --record
devduck --record "analyze this codebase"

# Resume from recorded session
devduck --resume ~/Desktop/session-20250202-123456.zip
devduck --resume session.zip "continue where we left off"

# Resume from specific snapshot
devduck --resume session.zip --snapshot 2 "what was I working on?"

Interactive recording:

๐Ÿฆ† record              # Toggle recording on/off
๐Ÿฆ† session_recorder(action="start")
๐Ÿฆ† session_recorder(action="snapshot", description="before refactor")
๐Ÿฆ† session_recorder(action="stop")  # Exports to /tmp/devduck/recordings/

Captures three layers:

  • sys: OS-level events (file I/O, HTTP requests)
  • tool: All tool calls and results
  • agent: Messages, decisions, state changes

Python API for session analysis:

from devduck import load_session, resume_session, list_sessions

# List all recordings
sessions = list_sessions()
# [{'name': 'session-20250202-123456.zip', 'size_kb': 45.2, ...}]

# Load and analyze a session
session = load_session("~/Desktop/session-20250202-123456.zip")
print(session)  # LoadedSession(events=156, snapshots=3, duration=342.5s)

# Get events by layer
tool_calls = session.get_events_by_layer("tool")
file_ops = session.get_events_by_type("file.open")

# Resume from snapshot (restores conversation history!)
result = session.resume_from_snapshot(2, agent=devduck.agent)
print(f"Restored {result['messages_restored']} messages")

# Resume and continue with new query
result = session.resume_and_continue(2, "what files did we modify?", devduck.agent)
print(result['agent_result'])

# Replay with callback
def on_event(event, idx):
    print(f"[{idx}] {event.layer}/{event.event_type}: {event.data}")
session.replay_events(callback=on_event)

Session file structure (ZIP):

session-20250202-123456.zip
โ”œโ”€โ”€ events.jsonl      # All events in JSON Lines format
โ”œโ”€โ”€ snapshots.json    # State snapshots with conversation history
โ”œโ”€โ”€ metadata.json     # Session info (duration, hostname, etc.)
โ””โ”€โ”€ session.pkl       # Serialized state for full restore (dill/pickle)

Recordings saved to: /tmp/devduck/recordings/


๐ŸŒ™ Ambient Mode (Background Thinking)

Continue working in the background while you're idle:

# Enable via environment
export DEVDUCK_AMBIENT_MODE=true
devduck

# Or toggle in REPL
๐Ÿฆ† ambient     # Toggle standard ambient mode
๐Ÿฆ† auto        # Toggle autonomous mode

Standard Mode: Runs up to 3 iterations when you go idle (30s)

# Configuration
export DEVDUCK_AMBIENT_IDLE_SECONDS=30      # Wait before starting
export DEVDUCK_AMBIENT_MAX_ITERATIONS=3     # Max background iterations
export DEVDUCK_AMBIENT_COOLDOWN=60          # Seconds between runs

Autonomous Mode: Runs continuously until done or stopped

export DEVDUCK_AUTONOMOUS_MAX_ITERATIONS=50  # Higher limit
export DEVDUCK_AUTONOMOUS_COOLDOWN=10        # Faster cycles

How it works:

  1. You go idle (30s default)
  2. DevDuck continues exploring the last topic
  3. Background work streams with ๐ŸŒ™ prefix
  4. When you return, findings are injected into your next query
  5. Agent can signal completion with [AMBIENT_DONE]

Programmatic control:

# Enable standard ambient mode
devduck.ambient.start()

# Enable autonomous mode
devduck.ambient.start(autonomous=True)

# Stop ambient mode
devduck.ambient.stop()

# Check status
devduck.status()['ambient_mode']

State Management (Time-Travel)

Save and restore agent state for reproducibility:

# Export current state
state_manager(action="export", metadata={"note": "before refactor"})

# List saved states
state_manager(action="list")

# Load and display state
state_manager(action="load", state_file="~/.devduck/states/devduck_20250118_150000.pkl")

# Resume from state (ephemeral - doesn't mutate parent)
state_manager(
    action="resume", 
    state_file="~/.devduck/states/devduck_20250118_150000.pkl",
    query="continue the analysis from where we left off"
)

# Modify state metadata
state_manager(
    action="modify",
    state_file="path/to/state.pkl",
    metadata={"tags": ["important", "refactor"]}
)

# Delete state
state_manager(action="delete", state_file="path/to/state.pkl")

States saved to: ~/.devduck/states/

System Prompt Management

Self-improvement - agent updates its own system prompt:

# View current system prompt
system_prompt(action="view")

# Add new context (appends to prompt)
system_prompt(action="add_context", context="New learning: Always use FastAPI for APIs")

# Update entire prompt
system_prompt(action="update", prompt="You are a specialized DevOps agent...")

# Sync to GitHub (persist across deployments)
system_prompt(
    action="update",
    prompt="Updated system prompt with new learnings...",
    repository="cagataycali/devduck"
)

# Reset to default
system_prompt(action="reset")

Pattern: Learn โ†’ Add context โ†’ Sync to GitHub โ†’ Persist forever

Knowledge Base (Auto-RAG)

Automatic memory across sessions:

export DEVDUCK_KNOWLEDGE_BASE_ID=your_kb_id
devduck

How it works:

  1. Before each query: Retrieves relevant context from KB
  2. After each response: Stores conversation for future reference
  3. No manual tool calls needed - fully automatic

Manual storage:

store_in_kb(
    content="Important information to remember...",
    title="Project Context",
    knowledge_base_id="optional-kb-id"
)

Sub-Agent Creation

Delegate tasks to specialized agents via GitHub Actions:

# Create sub-agent with specific model and tools
create_subagent(
    repository="owner/repo",
    workflow_id="agent.yml",
    task="Analyze this dataset and provide insights",
    model="us.anthropic.claude-sonnet-4-20250514-v1:0",
    provider="bedrock",
    max_tokens=60000,
    tools="file_read,python_repl,calculator,http_request"
)

# Custom system prompt for specialized behavior
create_subagent(
    repository="owner/repo",
    workflow_id="agent.yml",
    task="Review code and suggest improvements",
    tools="file_read,editor,shell",
    system_prompt="You are a senior code reviewer focused on best practices"
)

# Check sub-agent status
create_subagent(action="status", repository="owner/repo", workflow_id="agent.yml", run_id="12345")

# List recent runs
create_subagent(action="list", repository="owner/repo", workflow_id="agent.yml")

๐Ÿ“‹ All Built-in Tools (46 total)

DevDuck Core (25 tools)

  • system_prompt - Update agent's system prompt (GitHub sync support)
  • store_in_kb - Store content in Bedrock Knowledge Base
  • state_manager - Save/restore agent state (time-travel)
  • session_recorder - ๐ŸŽฌ Record sessions for replay and debugging
  • tcp - TCP server with real-time streaming
  • websocket - WebSocket server with concurrent messaging
  • ipc - Unix socket IPC server for local processes
  • mcp_server - Expose as MCP server (HTTP/stdio)
  • zenoh_peer - Peer-to-peer networking with auto-discovery
  • agentcore_proxy - ๐ŸŒ Unified mesh relay (Zenoh + AgentCore + browser peers)
  • unified_mesh - Single source of truth for all agent types + ring context
  • mesh_registry - File-based agent discovery with fcntl locking and TTL
  • ambient_mode - Control ambient/autonomous background thinking
  • install_tools - Install packages and load tools at runtime
  • create_subagent - Spawn sub-agents via GitHub Actions
  • use_github - GitHub GraphQL API operations
  • tray - System tray app control (macOS)
  • ambient - Ambient AI input overlay (macOS)
  • agentcore_config - Configure & launch on Bedrock AgentCore
  • agentcore_invoke - Invoke deployed AgentCore agents
  • agentcore_logs - View CloudWatch logs from agents
  • agentcore_agents - List/manage agent runtimes
  • manage_tools - Runtime tool add/remove/reload
  • view_logs - View/search/clear DevDuck logs
  • speech_to_speech - Real-time speech-to-speech conversations (optional - install with pip install devduck[speech])

Strands Tools (13 tools)

  • shell - Interactive shell with PTY support
  • editor - File editing (view/create/replace/insert/undo)
  • file_read - Multi-file reading with search modes
  • file_write - Write content to files
  • file_read - Read files with document mode for PDFs/CSVs
  • calculator - SymPy-powered math (solve/derive/integrate)
  • image_reader - Read images for Converse API
  • use_agent - Nested agent with different model
  • load_tool - Load custom tools from Python files
  • environment - Environment variable management
  • mcp_client - Connect to external MCP servers autonomously
  • retrieve - Bedrock Knowledge Base retrieval
  • speak - Text-to-speech (macOS say or AWS Polly)
  • slack - Slack messaging and event handling

Strands Fun Tools (6 tools - macOS)

  • listen - Background speech transcription (Whisper)
  • cursor - Mouse & keyboard control
  • clipboard - Clipboard monitoring & control
  • screen_reader - OCR & UI element detection
  • bluetooth - BLE scanning and GATT operations
  • yolo_vision - Object detection with YOLO

Community Tools (./tools/)

  • fetch_github_tool - Fetch and load tools from GitHub repos
  • gist - Comprehensive GitHub Gist management (create/update/fork/star/comment)
  • scraper - HTML/XML parsing with BeautifulSoup4
  • add_comment - Add comments to GitHub issues/PRs
  • list_issues - List GitHub repository issues
  • list_pull_requests - List GitHub repository PRs

Plus: Hot-reload tools from ./tools/ directory when DEVDUCK_LOAD_TOOLS_FROM_DIR=true


Hot-Reload Example

# ./tools/weather.py
from strands import tool
import requests

@tool
def weather(city: str) -> str:
    """Get weather for a city."""
    r = requests.get(f"https://wttr.in/{city}?format=%C+%t")
    return r.text

Save โ†’ use instantly:

๐Ÿฆ† weather(city="Tokyo")
# Clear sky +15ยฐC

No restart. No configuration. Just works.


Access Methods

Protocol Endpoint Test Command Use Case
CLI Terminal devduck "query" Interactive/one-shot
Python Import import devduck; devduck("query") Script integration
Mesh Relay localhost:10000 Open mesh.html Unified mesh (browser + all agents)
WebSocket localhost:10001 wscat -c ws://localhost:10001 Browser/async apps
TCP localhost:10002 nc localhost 10002 Network clients
MCP localhost:10003/mcp Add to Claude Desktop MCP clients
IPC /tmp/devduck_main.sock nc -U /tmp/devduck_main.sock Local processes

CLI Commands

# Interactive REPL
devduck

# One-shot query
devduck "your query here"

# MCP stdio mode (for Claude Desktop integration)
devduck --mcp

# Deploy to AgentCore
devduck deploy --launch
devduck deploy --name my-agent --tools "strands_tools:shell,editor" --launch

# Manage deployed agents
devduck list                              # List all agents
devduck status --name my-agent            # Check status
devduck invoke "hello" --name my-agent    # Invoke agent

# Session recording
devduck --record                    # Start with recording enabled
devduck --record "do something"     # Record a one-shot query

# Resume from recorded session
devduck --resume session.zip        # Resume from latest snapshot
devduck --resume session.zip "continue"  # Resume and run new query
devduck --resume session.zip --snapshot 2 "continue"  # Resume from specific snapshot

REPL Commands

Command Description
exit / quit / q Exit DevDuck
ambient Toggle standard ambient mode
auto / autonomous Toggle autonomous mode
record Toggle session recording
!<command> Execute shell command (e.g., !ls -la)
status Check agent status

Custom ports:

export DEVDUCK_TCP_PORT=10002 DEVDUCK_WS_PORT=10001 DEVDUCK_MCP_PORT=10003 DEVDUCK_AGENTCORE_PROXY_PORT=10000
devduck

Disable servers:

export DEVDUCK_ENABLE_TCP=false DEVDUCK_ENABLE_MCP=false
devduck

Configuration

Variable Default Description
Model
MODEL_PROVIDER Auto Manual override: bedrock, anthropic, openai, github, gemini, cohere, writer, mistral, litellm, llamaapi, mlx, ollama
STRANDS_MODEL_ID Auto Model name (e.g., claude-sonnet-4, gpt-4o, qwen3:1.7b)
Provider API Keys
ANTHROPIC_API_KEY - Anthropic API key (auto-detected)
OPENAI_API_KEY - OpenAI API key (auto-detected)
GOOGLE_API_KEY / GEMINI_API_KEY - Google Gemini API key (auto-detected)
GITHUB_TOKEN / PAT_TOKEN - GitHub token for GitHub Models (auto-detected)
COHERE_API_KEY - Cohere API key (auto-detected)
WRITER_API_KEY - Writer API key (auto-detected)
MISTRAL_API_KEY - Mistral API key (auto-detected)
LITELLM_API_KEY - LiteLLM API key (auto-detected)
LLAMAAPI_API_KEY - LlamaAPI key (auto-detected)
Tools
DEVDUCK_TOOLS 40 tools Format: package1:tool1,tool2;package2:tool3
DEVDUCK_LOAD_TOOLS_FROM_DIR false Auto-load from ./tools/ directory
Memory
DEVDUCK_KNOWLEDGE_BASE_ID - Bedrock KB ID for auto-RAG
SYSTEM_PROMPT - Additional system prompt content
MCP
MCP_SERVERS - JSON config for external MCP servers
Servers
DEVDUCK_TCP_PORT 10002 TCP server port
DEVDUCK_WS_PORT 10001 WebSocket server port
DEVDUCK_MCP_PORT 10003 MCP server port
DEVDUCK_AGENTCORE_PROXY_PORT 10000 Mesh relay / AgentCore proxy port
DEVDUCK_IPC_SOCKET /tmp/devduck_main.sock IPC socket path
DEVDUCK_ENABLE_TCP false Enable TCP server
DEVDUCK_ENABLE_WS true Enable WebSocket server
DEVDUCK_ENABLE_MCP false Enable MCP server
DEVDUCK_ENABLE_IPC false Enable IPC server
DEVDUCK_ENABLE_ZENOH true Enable Zenoh peer-to-peer
DEVDUCK_ENABLE_AGENTCORE_PROXY true Enable unified mesh relay
ZENOH_CONNECT - Remote Zenoh endpoint(s) to connect to
ZENOH_LISTEN - Zenoh endpoint(s) to listen on
Ambient Mode
DEVDUCK_AMBIENT_MODE false Enable ambient mode on startup
DEVDUCK_AMBIENT_IDLE_SECONDS 30 Seconds idle before ambient starts
DEVDUCK_AMBIENT_MAX_ITERATIONS 3 Max iterations in standard mode
DEVDUCK_AMBIENT_COOLDOWN 60 Seconds between ambient runs
DEVDUCK_AUTONOMOUS_MAX_ITERATIONS 50 Max iterations in autonomous mode
DEVDUCK_AUTONOMOUS_COOLDOWN 10 Seconds between autonomous runs
Speech
BIDI_MODEL_ID Provider default Override bidi model (e.g., amazon.nova-2-sonic-v1:0)
Context
DEVDUCK_LOG_LINE_COUNT 50 Recent log lines in context
DEVDUCK_LAST_MESSAGE_COUNT 200 Recent messages in context

Troubleshooting

Ollama model not found:

# DevDuck auto-pulls models, but if it fails:
ollama pull qwen3:1.7b

Port already in use:

# Change ports (10000+ block)
export DEVDUCK_AGENTCORE_PROXY_PORT=10010
export DEVDUCK_WS_PORT=10011
export DEVDUCK_TCP_PORT=10012
devduck

Hot-reload not working:

# Ensure tools directory exists
mkdir -p ./tools

# Check file watcher logs
devduck
๐Ÿฆ† view_logs(action="search", pattern="watcher")

Memory/performance issues:

# Use lighter model
export STRANDS_MODEL_ID="qwen3:0.5b"

# Reduce context
export DEVDUCK_LOG_LINE_COUNT=20
export DEVDUCK_LAST_MESSAGE_COUNT=50

Speech dependencies not found:

# Install speech extras
pip install "devduck[speech]"

# Or with pipx
pipx install "devduck[speech]"

Ambient overlay not starting:

# Make sure tkinter is installed
python3 -c "import tkinter"

# Install tkinter if missing
brew install python-tk@3.13  # macOS
sudo apt-get install python3-tk  # Ubuntu/Debian
sudo dnf install python3-tkinter  # Fedora

Tray app not starting (macOS):

# Install rumps
pip install rumps

# Or reinstall devduck
pip install -e .

View logs: devduck โ†’ ๐Ÿฆ† view_logs()


GitHub Actions

Run DevDuck in CI/CD pipelines:

name: AI Code Assistant
on: 
  issues:
    types: [opened, edited]
  pull_request:
    types: [opened, edited, synchronize]

jobs:
  devduck:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      issues: write
      pull-requests: write
    steps:
      - uses: cagataycali/devduck@main
        with:
          task: "Analyze and help with this issue or PR"
          provider: "github"
          model: "gpt-4o"
          tools: "shell,file_read,file_write,use_github,calculator"
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Sub-agent workflows:

devduck("Create a sub-agent to analyze test coverage")

Resources


Citation

@software{devduck2025,
  author = {Cagatay Cali},
  title = {DevDuck: Self-Modifying AI Agent with Unified Mesh, Hot-Reload, and Multi-Protocol Servers},
  year = {2025},
  url = {https://github.com/cagataycali/devduck}
}

Apache 2.0 | Built with Strands Agents | @cagataycali

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

devduck-1.6.1.tar.gz (356.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

devduck-1.6.1-py3-none-any.whl (195.9 kB view details)

Uploaded Python 3

File details

Details for the file devduck-1.6.1.tar.gz.

File metadata

  • Download URL: devduck-1.6.1.tar.gz
  • Upload date:
  • Size: 356.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for devduck-1.6.1.tar.gz
Algorithm Hash digest
SHA256 932ecfa27de369e774b184690941dc65f2d966fbb1df9a93adcf7b99b29d82eb
MD5 d3eb280a4afb1be7efbe4399e1052e42
BLAKE2b-256 171a8a85262e160607a77d0a12624fdb4375ba9ffb56f1fb8153b3185d721469

See more details on using hashes here.

File details

Details for the file devduck-1.6.1-py3-none-any.whl.

File metadata

  • Download URL: devduck-1.6.1-py3-none-any.whl
  • Upload date:
  • Size: 195.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for devduck-1.6.1-py3-none-any.whl
Algorithm Hash digest
SHA256 5506c3f976360a4ca17c7e05f3ec84aed4026aa02b653b67ffee90ba97bb41da
MD5 9118ba90fd4cb39488046c4530c8c045
BLAKE2b-256 962e59a7cc68484ab01fc1ed1503280a1a5d41d2b3c4c7ec84077225cea6a0ea

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page