devduck 0.6.0__tar.gz → 0.7.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of devduck might be problematic. Click here for more details.
- devduck-0.7.2/PKG-INFO +715 -0
- devduck-0.7.2/README.md +668 -0
- {devduck-0.6.0 → devduck-0.7.2}/action.yml +1 -1
- {devduck-0.6.0 → devduck-0.7.2}/devduck/__init__.py +462 -182
- {devduck-0.6.0 → devduck-0.7.2}/devduck/_version.py +3 -3
- {devduck-0.6.0 → devduck-0.7.2}/devduck/tools/agentcore_invoke.py +1 -0
- {devduck-0.6.0 → devduck-0.7.2}/devduck/tools/install_tools.py +103 -2
- devduck-0.7.2/devduck.egg-info/PKG-INFO +715 -0
- devduck-0.6.0/PKG-INFO +0 -457
- devduck-0.6.0/README.md +0 -410
- devduck-0.6.0/devduck.egg-info/PKG-INFO +0 -457
- {devduck-0.6.0 → devduck-0.7.2}/.github/workflows/agent.yml +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/.gitignore +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/LICENSE +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/MANIFEST.in +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/agent_runner.py +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/devduck/__main__.py +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/devduck/agentcore_handler.py +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/devduck/test_redduck.py +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/devduck/tools/__init__.py +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/devduck/tools/_ambient_input.py +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/devduck/tools/_tray_app.py +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/devduck/tools/agentcore_agents.py +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/devduck/tools/agentcore_config.py +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/devduck/tools/agentcore_logs.py +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/devduck/tools/ambient.py +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/devduck/tools/create_subagent.py +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/devduck/tools/ipc.py +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/devduck/tools/mcp_server.py +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/devduck/tools/state_manager.py +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/devduck/tools/store_in_kb.py +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/devduck/tools/system_prompt.py +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/devduck/tools/tcp.py +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/devduck/tools/tray.py +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/devduck/tools/use_github.py +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/devduck/tools/websocket.py +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/devduck.egg-info/SOURCES.txt +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/devduck.egg-info/dependency_links.txt +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/devduck.egg-info/entry_points.txt +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/devduck.egg-info/requires.txt +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/devduck.egg-info/top_level.txt +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/docs/index.html +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/docs/mac-os-tray.jpg +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/pyproject.toml +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/requirements.txt +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/setup-aws-oidc.sh +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/setup.cfg +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/test.py +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/tools/__init__.py +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/tools/fetch_github_tool.py +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/tools/gist.py +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/tools/github_tools.py +0 -0
- {devduck-0.6.0 → devduck-0.7.2}/tools/scraper.py +0 -0
devduck-0.7.2/PKG-INFO
ADDED
|
@@ -0,0 +1,715 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: devduck
|
|
3
|
+
Version: 0.7.2
|
|
4
|
+
Summary: 🦆 Extreme minimalist self-adapting AI agent - one file, self-healing, runtime dependencies
|
|
5
|
+
Author-email: Cagatay Cali <cagataycali@icloud.com>
|
|
6
|
+
License: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/cagataycali/devduck
|
|
8
|
+
Project-URL: Repository, https://github.com/cagataycali/devduck.git
|
|
9
|
+
Project-URL: Documentation, https://github.com/cagataycali/devduck#readme
|
|
10
|
+
Project-URL: Bug Tracker, https://github.com/cagataycali/devduck/issues
|
|
11
|
+
Keywords: ai,agent,minimalist,self-healing,ollama,strands-agents
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Intended Audience :: System Administrators
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
23
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
24
|
+
Classifier: Topic :: System :: Systems Administration
|
|
25
|
+
Classifier: Topic :: Utilities
|
|
26
|
+
Requires-Python: <3.14,>=3.10
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
License-File: LICENSE
|
|
29
|
+
Requires-Dist: strands-agents
|
|
30
|
+
Requires-Dist: prompt_toolkit
|
|
31
|
+
Requires-Dist: strands-agents[ollama]
|
|
32
|
+
Requires-Dist: strands-agents[anthropic]
|
|
33
|
+
Requires-Dist: strands-agents[openai]
|
|
34
|
+
Requires-Dist: strands-agents[otel]
|
|
35
|
+
Requires-Dist: strands-agents-tools
|
|
36
|
+
Requires-Dist: strands-fun-tools[all]; sys_platform == "darwin"
|
|
37
|
+
Requires-Dist: strands-fun-tools[audio]; sys_platform == "darwin"
|
|
38
|
+
Requires-Dist: beautifulsoup4
|
|
39
|
+
Requires-Dist: colorama
|
|
40
|
+
Requires-Dist: websockets
|
|
41
|
+
Requires-Dist: strands-mcp-server
|
|
42
|
+
Requires-Dist: bedrock-agentcore-starter-toolkit
|
|
43
|
+
Requires-Dist: bedrock-agentcore
|
|
44
|
+
Requires-Dist: rumps; sys_platform == "darwin"
|
|
45
|
+
Requires-Dist: strands-mlx; sys_platform == "darwin"
|
|
46
|
+
Dynamic: license-file
|
|
47
|
+
|
|
48
|
+
# 🦆 DevDuck
|
|
49
|
+
|
|
50
|
+
[](https://pypi.org/project/devduck/)
|
|
51
|
+
|
|
52
|
+
**Self-modifying AI agent that hot-reloads its own code—builds itself as it runs.**
|
|
53
|
+
|
|
54
|
+
One Python file that adapts to your environment, fixes itself, and expands capabilities at runtime.
|
|
55
|
+
|
|
56
|
+
Learn more: https://duck.nyc
|
|
57
|
+
|
|
58
|
+
## 🎬 See It In Action
|
|
59
|
+
|
|
60
|
+
| Feature | What You'll See | Demo |
|
|
61
|
+
|---------|----------------|-------|
|
|
62
|
+
| 🔥 **Hot-Reload** | Agent detects code changes and restarts instantly | [Watch](https://redduck.dev/videos/hot-reload.mp4) |
|
|
63
|
+
| 🌐 **Web UI** | Clean web interface with real-time streaming | [Watch](https://redduck.dev/videos/web-ui.mp4) |
|
|
64
|
+
| 🛠️ **Dynamic Tools** | Save `.py` file in `./tools/` → use instantly | [Watch](https://redduck.dev/videos/dynamic-tool-creation.mp4) |
|
|
65
|
+
| 🌊 **TCP Streaming** | Connect via netcat, apps, or other agents | [Watch](https://redduck.dev/videos/tcp.mp4) |
|
|
66
|
+
| 🔌 **IPC & Tray** | macOS menu bar + Unix socket IPC |  |
|
|
67
|
+
| 💬 **Ambient Overlay** | Floating AI input with glassmorphism UI | [Watch](https://redduck.dev/videos/floating-input.mp4) |
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Quick Start
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
# Install & run
|
|
75
|
+
pipx install devduck && devduck
|
|
76
|
+
|
|
77
|
+
# One-shot query
|
|
78
|
+
devduck "create a REST API with FastAPI"
|
|
79
|
+
|
|
80
|
+
# Python API
|
|
81
|
+
python -c "import devduck; devduck('analyze this code')"
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**Requirements:** Python 3.10-3.13, AWS credentials (or Ollama/Anthropic/GitHub/MLX)
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Core Capabilities
|
|
89
|
+
|
|
90
|
+
| Feature | What It Does | How to Use |
|
|
91
|
+
|---------|--------------|------------|
|
|
92
|
+
| 🔥 **Hot-Reload** | Auto-restarts on code changes | Edit `__init__.py` → saves → auto-restart |
|
|
93
|
+
| 🛠️ **Runtime Tools** | Add/remove tools without restart | `manage_tools(action="add", ...)` |
|
|
94
|
+
| 📦 **Dynamic Loading** | Install packages and load tools on-the-fly | `install_tools(action="install_and_load", package="...")` |
|
|
95
|
+
| 🧠 **Auto-RAG** | Remembers conversations via Knowledge Base | Set `DEVDUCK_KNOWLEDGE_BASE_ID` |
|
|
96
|
+
| 🌊 **Multi-Protocol** | TCP, WebSocket, MCP, IPC servers | Auto-starts on ports 9999, 8080, 8000 |
|
|
97
|
+
| 🔌 **MCP Client** | Connect to external MCP servers | Set `MCP_SERVERS` env var |
|
|
98
|
+
| 💾 **State Time-Travel** | Save/restore agent state | `state_manager(action="export")` |
|
|
99
|
+
| 📝 **Self-Improvement** | Updates own system prompt | `system_prompt(action="add_context", ...)` |
|
|
100
|
+
| ☁️ **AWS Deploy** | One-command serverless | `agentcore_config(auto_launch=True)` |
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Developer Setup
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
git clone git@github.com:cagataycali/devduck.git
|
|
108
|
+
cd devduck
|
|
109
|
+
python3.13 -m venv .venv
|
|
110
|
+
source .venv/bin/activate
|
|
111
|
+
.venv/bin/pip3.13 install -e .
|
|
112
|
+
devduck
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Architecture
|
|
118
|
+
|
|
119
|
+
```mermaid
|
|
120
|
+
graph TB
|
|
121
|
+
A[User Input] -->|CLI/TCP/WS/MCP/IPC| B[DevDuck Core]
|
|
122
|
+
B -->|Auto RAG| C[Knowledge Base]
|
|
123
|
+
C -.->|Context Retrieval| B
|
|
124
|
+
B -->|Tool Calls| D[38+ Built-in Tools]
|
|
125
|
+
D --> E[shell/editor/calculator]
|
|
126
|
+
D --> F[GitHub/AgentCore]
|
|
127
|
+
D --> G[TCP/WebSocket/MCP/IPC]
|
|
128
|
+
D --> H[tray/ambient/cursor/clipboard]
|
|
129
|
+
B -->|Hot-reload| I[./tools/*.py + __init__.py]
|
|
130
|
+
I -.->|Load Instantly| D
|
|
131
|
+
B -->|Runtime| K[manage_tools/install_tools]
|
|
132
|
+
K -.->|Expand| D
|
|
133
|
+
B -->|Response| J[User Output]
|
|
134
|
+
J -.->|Store Memory| C
|
|
135
|
+
|
|
136
|
+
style B fill:#e1f5ff
|
|
137
|
+
style C fill:#d4edda
|
|
138
|
+
style I fill:#fff3cd
|
|
139
|
+
style K fill:#ffe6cc
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
**Self-adapting loop:** Query → RAG → Tools → Response → Memory → Hot-reload/Runtime-load → Repeat
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Model Setup
|
|
147
|
+
|
|
148
|
+
DevDuck **auto-detects** providers based on credentials:
|
|
149
|
+
|
|
150
|
+
**Priority:** Bedrock → Anthropic → OpenAI → GitHub → Gemini → Cohere → Writer → Mistral → LiteLLM → LlamaAPI → MLX → Ollama
|
|
151
|
+
|
|
152
|
+
| Provider | API Key | Auto-Detected |
|
|
153
|
+
|----------|---------|---------------|
|
|
154
|
+
| **Bedrock** | AWS credentials | ✅ If `boto3` auth succeeds |
|
|
155
|
+
| **Anthropic** | `ANTHROPIC_API_KEY` | ✅ If key present |
|
|
156
|
+
| **OpenAI** | `OPENAI_API_KEY` | ✅ If key present |
|
|
157
|
+
| **GitHub** | `GITHUB_TOKEN` or `PAT_TOKEN` | ✅ If key present |
|
|
158
|
+
| **Gemini** | `GOOGLE_API_KEY` or `GEMINI_API_KEY` | ✅ If key present |
|
|
159
|
+
| **Cohere** | `COHERE_API_KEY` | ✅ If key present |
|
|
160
|
+
| **Writer** | `WRITER_API_KEY` | ✅ If key present |
|
|
161
|
+
| **Mistral** | `MISTRAL_API_KEY` | ✅ If key present |
|
|
162
|
+
| **LiteLLM** | `LITELLM_API_KEY` | ✅ If key present |
|
|
163
|
+
| **LlamaAPI** | `LLAMAAPI_API_KEY` | ✅ If key present |
|
|
164
|
+
| **MLX** | No key needed | ✅ On Apple Silicon (M1/M2/M3) |
|
|
165
|
+
| **Ollama** | No key needed | ✅ Fallback if nothing else found |
|
|
166
|
+
|
|
167
|
+
**Just set your API key - DevDuck handles the rest:**
|
|
168
|
+
```bash
|
|
169
|
+
export ANTHROPIC_API_KEY=sk-ant-...
|
|
170
|
+
devduck # Auto-uses Anthropic
|
|
171
|
+
|
|
172
|
+
export OPENAI_API_KEY=sk-...
|
|
173
|
+
devduck # Auto-uses OpenAI
|
|
174
|
+
|
|
175
|
+
export GOOGLE_API_KEY=...
|
|
176
|
+
devduck # Auto-uses Gemini
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
**Manual override:**
|
|
180
|
+
```bash
|
|
181
|
+
export MODEL_PROVIDER=bedrock
|
|
182
|
+
export STRANDS_MODEL_ID=us.anthropic.claude-sonnet-4-20250514-v1:0
|
|
183
|
+
devduck
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Tool Management
|
|
189
|
+
|
|
190
|
+
### Runtime Tool Management
|
|
191
|
+
|
|
192
|
+
Add, remove, or reload tools while agent is running:
|
|
193
|
+
|
|
194
|
+
```python
|
|
195
|
+
# List all loaded tools
|
|
196
|
+
manage_tools(action="list")
|
|
197
|
+
|
|
198
|
+
# Add tools from a package at runtime
|
|
199
|
+
manage_tools(action="add", package="strands_fun_tools", tool_names="cursor,clipboard,bluetooth")
|
|
200
|
+
|
|
201
|
+
# Remove tools you don't need
|
|
202
|
+
manage_tools(action="remove", tool_names="cursor,clipboard")
|
|
203
|
+
|
|
204
|
+
# Reload specific tools after editing
|
|
205
|
+
manage_tools(action="reload", tool_names="shell,editor")
|
|
206
|
+
|
|
207
|
+
# Reload all tools (restarts agent)
|
|
208
|
+
manage_tools(action="reload")
|
|
209
|
+
|
|
210
|
+
# Load custom tool from file
|
|
211
|
+
manage_tools(action="add", tool_path="./my_custom_tool.py")
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Dynamic Package Installation
|
|
215
|
+
|
|
216
|
+
Install Python packages and load their tools at runtime:
|
|
217
|
+
|
|
218
|
+
```python
|
|
219
|
+
# Discover available tools before loading
|
|
220
|
+
install_tools(action="list_available", package="strands-fun-tools", module="strands_fun_tools")
|
|
221
|
+
|
|
222
|
+
# Install package and load all tools
|
|
223
|
+
install_tools(action="install_and_load", package="strands-agents-tools", module="strands_tools")
|
|
224
|
+
|
|
225
|
+
# Install and load specific tools only
|
|
226
|
+
install_tools(
|
|
227
|
+
action="install_and_load",
|
|
228
|
+
package="strands-fun-tools",
|
|
229
|
+
module="strands_fun_tools",
|
|
230
|
+
tool_names=["clipboard", "cursor", "bluetooth"]
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
# Load tools from already installed package
|
|
234
|
+
install_tools(action="load", module="strands_tools", tool_names=["shell", "calculator"])
|
|
235
|
+
|
|
236
|
+
# List currently loaded tools
|
|
237
|
+
install_tools(action="list_loaded")
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### Static Tool Configuration
|
|
241
|
+
|
|
242
|
+
**Format:** `package:tool1,tool2:package2:tool3`
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
# Minimal (shell + editor only)
|
|
246
|
+
export DEVDUCK_TOOLS="strands_tools:shell,editor"
|
|
247
|
+
|
|
248
|
+
# Dev essentials
|
|
249
|
+
export DEVDUCK_TOOLS="strands_tools:shell,editor,file_read,file_write,calculator"
|
|
250
|
+
|
|
251
|
+
# Full stack + GitHub
|
|
252
|
+
export DEVDUCK_TOOLS="devduck.tools:tcp,websocket,mcp_server,use_github:strands_tools:shell,editor,file_read"
|
|
253
|
+
|
|
254
|
+
devduck
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Hot-Reload Tools from Directory
|
|
258
|
+
|
|
259
|
+
Create `./tools/weather.py`:
|
|
260
|
+
```python
|
|
261
|
+
from strands import tool
|
|
262
|
+
import requests
|
|
263
|
+
|
|
264
|
+
@tool
|
|
265
|
+
def weather(city: str) -> str:
|
|
266
|
+
"""Get weather for a city."""
|
|
267
|
+
r = requests.get(f"https://wttr.in/{city}?format=%C+%t")
|
|
268
|
+
return r.text
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
**Enable directory auto-loading:**
|
|
272
|
+
```bash
|
|
273
|
+
export DEVDUCK_LOAD_TOOLS_FROM_DIR=true
|
|
274
|
+
devduck
|
|
275
|
+
# Save weather.py → use instantly (no restart needed)
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
**Default:** Directory loading is OFF. Use `manage_tools()` or `install_tools()` for explicit control.
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
## MCP Integration
|
|
283
|
+
|
|
284
|
+
### As MCP Server (Expose DevDuck)
|
|
285
|
+
|
|
286
|
+
**Claude Desktop** (`~/Library/Application Support/Claude/claude_desktop_config.json`):
|
|
287
|
+
```json
|
|
288
|
+
{
|
|
289
|
+
"mcpServers": {
|
|
290
|
+
"devduck": {
|
|
291
|
+
"command": "uvx",
|
|
292
|
+
"args": ["devduck", "--mcp"]
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
**Or start HTTP MCP server:**
|
|
299
|
+
```python
|
|
300
|
+
mcp_server(action="start", port=8000, stateless=True)
|
|
301
|
+
# Connect at: http://localhost:8000/mcp
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
**Modes:** `--mcp` (stdio for Claude Desktop) | `http` (background server) | `stateless=True` (multi-node)
|
|
305
|
+
|
|
306
|
+
### As MCP Client (Load External Servers)
|
|
307
|
+
|
|
308
|
+
**Expand capabilities** by loading tools from external MCP servers:
|
|
309
|
+
|
|
310
|
+
```bash
|
|
311
|
+
export MCP_SERVERS='{
|
|
312
|
+
"mcpServers": {
|
|
313
|
+
"strands-docs": {"command": "uvx", "args": ["strands-agents-mcp-server"]},
|
|
314
|
+
"remote": {"url": "https://api.example.com/mcp", "headers": {"Auth": "Bearer token"}},
|
|
315
|
+
"custom": {"command": "python", "args": ["my_server.py"]}
|
|
316
|
+
}
|
|
317
|
+
}'
|
|
318
|
+
devduck
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
**Supported transports:** stdio (`command`/`args`/`env`) | HTTP (`url`/`headers`) | SSE (`url` with `/sse` path)
|
|
322
|
+
|
|
323
|
+
**Tool prefixing:** Each server's tools get prefixed (e.g., `strands-docs_search_docs`)
|
|
324
|
+
|
|
325
|
+
---
|
|
326
|
+
|
|
327
|
+
## Advanced Features
|
|
328
|
+
|
|
329
|
+
### State Management (Time-Travel)
|
|
330
|
+
|
|
331
|
+
Save and restore agent state for reproducibility:
|
|
332
|
+
|
|
333
|
+
```python
|
|
334
|
+
# Export current state
|
|
335
|
+
state_manager(action="export", metadata={"note": "before refactor"})
|
|
336
|
+
|
|
337
|
+
# List saved states
|
|
338
|
+
state_manager(action="list")
|
|
339
|
+
|
|
340
|
+
# Load and display state
|
|
341
|
+
state_manager(action="load", state_file="~/.devduck/states/devduck_20250118_150000.pkl")
|
|
342
|
+
|
|
343
|
+
# Resume from state (ephemeral - doesn't mutate parent)
|
|
344
|
+
state_manager(
|
|
345
|
+
action="resume",
|
|
346
|
+
state_file="~/.devduck/states/devduck_20250118_150000.pkl",
|
|
347
|
+
query="continue the analysis from where we left off"
|
|
348
|
+
)
|
|
349
|
+
|
|
350
|
+
# Modify state metadata
|
|
351
|
+
state_manager(
|
|
352
|
+
action="modify",
|
|
353
|
+
state_file="path/to/state.pkl",
|
|
354
|
+
metadata={"tags": ["important", "refactor"]}
|
|
355
|
+
)
|
|
356
|
+
|
|
357
|
+
# Delete state
|
|
358
|
+
state_manager(action="delete", state_file="path/to/state.pkl")
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
States saved to: `~/.devduck/states/`
|
|
362
|
+
|
|
363
|
+
### System Prompt Management
|
|
364
|
+
|
|
365
|
+
**Self-improvement** - agent updates its own system prompt:
|
|
366
|
+
|
|
367
|
+
```python
|
|
368
|
+
# View current system prompt
|
|
369
|
+
system_prompt(action="view")
|
|
370
|
+
|
|
371
|
+
# Add new context (appends to prompt)
|
|
372
|
+
system_prompt(action="add_context", context="New learning: Always use FastAPI for APIs")
|
|
373
|
+
|
|
374
|
+
# Update entire prompt
|
|
375
|
+
system_prompt(action="update", prompt="You are a specialized DevOps agent...")
|
|
376
|
+
|
|
377
|
+
# Sync to GitHub (persist across deployments)
|
|
378
|
+
system_prompt(
|
|
379
|
+
action="update",
|
|
380
|
+
prompt="Updated system prompt with new learnings...",
|
|
381
|
+
repository="cagataycali/devduck"
|
|
382
|
+
)
|
|
383
|
+
|
|
384
|
+
# Reset to default
|
|
385
|
+
system_prompt(action="reset")
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
**Pattern:** Learn → Add context → Sync to GitHub → Persist forever
|
|
389
|
+
|
|
390
|
+
### Knowledge Base (Auto-RAG)
|
|
391
|
+
|
|
392
|
+
**Automatic memory** across sessions:
|
|
393
|
+
|
|
394
|
+
```bash
|
|
395
|
+
export DEVDUCK_KNOWLEDGE_BASE_ID=your_kb_id
|
|
396
|
+
devduck
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
**How it works:**
|
|
400
|
+
1. Before each query: Retrieves relevant context from KB
|
|
401
|
+
2. After each response: Stores conversation for future reference
|
|
402
|
+
3. No manual tool calls needed - fully automatic
|
|
403
|
+
|
|
404
|
+
**Manual storage:**
|
|
405
|
+
```python
|
|
406
|
+
store_in_kb(
|
|
407
|
+
content="Important information to remember...",
|
|
408
|
+
title="Project Context",
|
|
409
|
+
knowledge_base_id="optional-kb-id"
|
|
410
|
+
)
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
### Sub-Agent Creation
|
|
414
|
+
|
|
415
|
+
**Delegate tasks** to specialized agents via GitHub Actions:
|
|
416
|
+
|
|
417
|
+
```python
|
|
418
|
+
# Create sub-agent with specific model and tools
|
|
419
|
+
create_subagent(
|
|
420
|
+
repository="owner/repo",
|
|
421
|
+
workflow_id="agent.yml",
|
|
422
|
+
task="Analyze this dataset and provide insights",
|
|
423
|
+
model="us.anthropic.claude-sonnet-4-20250514-v1:0",
|
|
424
|
+
provider="bedrock",
|
|
425
|
+
max_tokens=60000,
|
|
426
|
+
tools="file_read,python_repl,calculator,http_request"
|
|
427
|
+
)
|
|
428
|
+
|
|
429
|
+
# Custom system prompt for specialized behavior
|
|
430
|
+
create_subagent(
|
|
431
|
+
repository="owner/repo",
|
|
432
|
+
workflow_id="agent.yml",
|
|
433
|
+
task="Review code and suggest improvements",
|
|
434
|
+
tools="file_read,editor,shell",
|
|
435
|
+
system_prompt="You are a senior code reviewer focused on best practices"
|
|
436
|
+
)
|
|
437
|
+
|
|
438
|
+
# Check sub-agent status
|
|
439
|
+
create_subagent(action="status", repository="owner/repo", workflow_id="agent.yml", run_id="12345")
|
|
440
|
+
|
|
441
|
+
# List recent runs
|
|
442
|
+
create_subagent(action="list", repository="owner/repo", workflow_id="agent.yml")
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
---
|
|
446
|
+
|
|
447
|
+
<details>
|
|
448
|
+
<summary><strong>📋 All Built-in Tools (38 total)</strong></summary>
|
|
449
|
+
|
|
450
|
+
### DevDuck Core (17 tools)
|
|
451
|
+
- `system_prompt` - Update agent's system prompt (GitHub sync support)
|
|
452
|
+
- `store_in_kb` - Store content in Bedrock Knowledge Base
|
|
453
|
+
- `state_manager` - Save/restore agent state (time-travel)
|
|
454
|
+
- `tcp` - TCP server with real-time streaming
|
|
455
|
+
- `websocket` - WebSocket server with concurrent messaging
|
|
456
|
+
- `ipc` - Unix socket IPC server for local processes
|
|
457
|
+
- `mcp_server` - Expose as MCP server (HTTP/stdio)
|
|
458
|
+
- `install_tools` - Install packages and load tools at runtime
|
|
459
|
+
- `create_subagent` - Spawn sub-agents via GitHub Actions
|
|
460
|
+
- `use_github` - GitHub GraphQL API operations
|
|
461
|
+
- `tray` - System tray app control (macOS)
|
|
462
|
+
- `ambient` - Ambient AI input overlay (macOS)
|
|
463
|
+
- `agentcore_config` - Configure & launch on Bedrock AgentCore
|
|
464
|
+
- `agentcore_invoke` - Invoke deployed AgentCore agents
|
|
465
|
+
- `agentcore_logs` - View CloudWatch logs from agents
|
|
466
|
+
- `agentcore_agents` - List/manage agent runtimes
|
|
467
|
+
- `manage_tools` - Runtime tool add/remove/reload
|
|
468
|
+
- `view_logs` - View/search/clear DevDuck logs
|
|
469
|
+
|
|
470
|
+
### Strands Tools (13 tools)
|
|
471
|
+
- `shell` - Interactive shell with PTY support
|
|
472
|
+
- `editor` - File editing (view/create/replace/insert/undo)
|
|
473
|
+
- `file_read` - Multi-file reading with search modes
|
|
474
|
+
- `file_write` - Write content to files
|
|
475
|
+
- `file_read` - Read files with document mode for PDFs/CSVs
|
|
476
|
+
- `calculator` - SymPy-powered math (solve/derive/integrate)
|
|
477
|
+
- `image_reader` - Read images for Converse API
|
|
478
|
+
- `use_agent` - Nested agent with different model
|
|
479
|
+
- `load_tool` - Load custom tools from Python files
|
|
480
|
+
- `environment` - Environment variable management
|
|
481
|
+
- `mcp_client` - Connect to external MCP servers autonomously
|
|
482
|
+
- `retrieve` - Bedrock Knowledge Base retrieval
|
|
483
|
+
- `speak` - Text-to-speech (macOS `say` or AWS Polly)
|
|
484
|
+
- `slack` - Slack messaging and event handling
|
|
485
|
+
|
|
486
|
+
### Strands Fun Tools (6 tools - macOS)
|
|
487
|
+
- `listen` - Background speech transcription (Whisper)
|
|
488
|
+
- `cursor` - Mouse & keyboard control
|
|
489
|
+
- `clipboard` - Clipboard monitoring & control
|
|
490
|
+
- `screen_reader` - OCR & UI element detection
|
|
491
|
+
- `bluetooth` - BLE scanning and GATT operations
|
|
492
|
+
- `yolo_vision` - Object detection with YOLO
|
|
493
|
+
|
|
494
|
+
### Community Tools (./tools/)
|
|
495
|
+
- `fetch_github_tool` - Fetch and load tools from GitHub repos
|
|
496
|
+
- `gist` - Comprehensive GitHub Gist management (create/update/fork/star/comment)
|
|
497
|
+
- `scraper` - HTML/XML parsing with BeautifulSoup4
|
|
498
|
+
- `add_comment` - Add comments to GitHub issues/PRs
|
|
499
|
+
- `list_issues` - List GitHub repository issues
|
|
500
|
+
- `list_pull_requests` - List GitHub repository PRs
|
|
501
|
+
|
|
502
|
+
**Plus:** Hot-reload tools from `./tools/` directory when `DEVDUCK_LOAD_TOOLS_FROM_DIR=true`
|
|
503
|
+
|
|
504
|
+
</details>
|
|
505
|
+
|
|
506
|
+
---
|
|
507
|
+
|
|
508
|
+
## Hot-Reload Example
|
|
509
|
+
|
|
510
|
+
```python
|
|
511
|
+
# ./tools/weather.py
|
|
512
|
+
from strands import tool
|
|
513
|
+
import requests
|
|
514
|
+
|
|
515
|
+
@tool
|
|
516
|
+
def weather(city: str) -> str:
|
|
517
|
+
"""Get weather for a city."""
|
|
518
|
+
r = requests.get(f"https://wttr.in/{city}?format=%C+%t")
|
|
519
|
+
return r.text
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
**Save → use instantly:**
|
|
523
|
+
```bash
|
|
524
|
+
🦆 weather(city="Tokyo")
|
|
525
|
+
# Clear sky +15°C
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
No restart. No configuration. Just works.
|
|
529
|
+
|
|
530
|
+
---
|
|
531
|
+
|
|
532
|
+
## Access Methods
|
|
533
|
+
|
|
534
|
+
| Protocol | Endpoint | Test Command | Use Case |
|
|
535
|
+
|----------|----------|--------------|----------|
|
|
536
|
+
| **CLI** | Terminal | `devduck "query"` | Interactive/one-shot |
|
|
537
|
+
| **Python** | Import | `import devduck; devduck("query")` | Script integration |
|
|
538
|
+
| **TCP** | `localhost:9999` | `nc localhost 9999` | Network clients |
|
|
539
|
+
| **WebSocket** | `localhost:8080` | `wscat -c ws://localhost:8080` | Browser/async apps |
|
|
540
|
+
| **MCP** | `localhost:8000/mcp` | Add to Claude Desktop | MCP clients |
|
|
541
|
+
| **IPC** | `/tmp/devduck_main.sock` | `nc -U /tmp/devduck_main.sock` | Local processes |
|
|
542
|
+
|
|
543
|
+
**Custom ports:**
|
|
544
|
+
```bash
|
|
545
|
+
export DEVDUCK_TCP_PORT=9000 DEVDUCK_WS_PORT=8001 DEVDUCK_MCP_PORT=8002
|
|
546
|
+
devduck
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
**Disable servers:**
|
|
550
|
+
```bash
|
|
551
|
+
export DEVDUCK_ENABLE_TCP=false DEVDUCK_ENABLE_MCP=false
|
|
552
|
+
devduck
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
---
|
|
556
|
+
|
|
557
|
+
## Configuration
|
|
558
|
+
|
|
559
|
+
| Variable | Default | Description |
|
|
560
|
+
|----------|---------|-------------|
|
|
561
|
+
| **Model** | | |
|
|
562
|
+
| `MODEL_PROVIDER` | Auto | Manual override: `bedrock`, `anthropic`, `openai`, `github`, `gemini`, `cohere`, `writer`, `mistral`, `litellm`, `llamaapi`, `mlx`, `ollama` |
|
|
563
|
+
| `STRANDS_MODEL_ID` | Auto | Model name (e.g., `claude-sonnet-4`, `gpt-4o`, `qwen3:1.7b`) |
|
|
564
|
+
| **Provider API Keys** | | |
|
|
565
|
+
| `ANTHROPIC_API_KEY` | - | Anthropic API key (auto-detected) |
|
|
566
|
+
| `OPENAI_API_KEY` | - | OpenAI API key (auto-detected) |
|
|
567
|
+
| `GOOGLE_API_KEY` / `GEMINI_API_KEY` | - | Google Gemini API key (auto-detected) |
|
|
568
|
+
| `GITHUB_TOKEN` / `PAT_TOKEN` | - | GitHub token for GitHub Models (auto-detected) |
|
|
569
|
+
| `COHERE_API_KEY` | - | Cohere API key (auto-detected) |
|
|
570
|
+
| `WRITER_API_KEY` | - | Writer API key (auto-detected) |
|
|
571
|
+
| `MISTRAL_API_KEY` | - | Mistral API key (auto-detected) |
|
|
572
|
+
| `LITELLM_API_KEY` | - | LiteLLM API key (auto-detected) |
|
|
573
|
+
| `LLAMAAPI_API_KEY` | - | LlamaAPI key (auto-detected) |
|
|
574
|
+
| **Tools** | | |
|
|
575
|
+
| `DEVDUCK_TOOLS` | 38 tools | Format: `package:tool1,tool2:package2:tool3` |
|
|
576
|
+
| `DEVDUCK_LOAD_TOOLS_FROM_DIR` | `false` | Auto-load from `./tools/` directory |
|
|
577
|
+
| **Memory** | | |
|
|
578
|
+
| `DEVDUCK_KNOWLEDGE_BASE_ID` | - | Bedrock KB ID for auto-RAG |
|
|
579
|
+
| `SYSTEM_PROMPT` | - | Additional system prompt content |
|
|
580
|
+
| **MCP** | | |
|
|
581
|
+
| `MCP_SERVERS` | - | JSON config for external MCP servers |
|
|
582
|
+
| **Servers** | | |
|
|
583
|
+
| `DEVDUCK_TCP_PORT` | `9999` | TCP server port |
|
|
584
|
+
| `DEVDUCK_WS_PORT` | `8080` | WebSocket server port |
|
|
585
|
+
| `DEVDUCK_MCP_PORT` | `8000` | MCP server port |
|
|
586
|
+
| `DEVDUCK_IPC_SOCKET` | `/tmp/devduck_main.sock` | IPC socket path |
|
|
587
|
+
| `DEVDUCK_ENABLE_TCP` | `true` | Enable TCP server |
|
|
588
|
+
| `DEVDUCK_ENABLE_WS` | `true` | Enable WebSocket server |
|
|
589
|
+
| `DEVDUCK_ENABLE_MCP` | `true` | Enable MCP server |
|
|
590
|
+
| `DEVDUCK_ENABLE_IPC` | `true` | Enable IPC server |
|
|
591
|
+
| **Context** | | |
|
|
592
|
+
| `DEVDUCK_LOG_LINE_COUNT` | `50` | Recent log lines in context |
|
|
593
|
+
| `DEVDUCK_LAST_MESSAGE_COUNT` | `200` | Recent messages in context |
|
|
594
|
+
|
|
595
|
+
---
|
|
596
|
+
|
|
597
|
+
## Troubleshooting
|
|
598
|
+
|
|
599
|
+
**Ollama model not found:**
|
|
600
|
+
```bash
|
|
601
|
+
# DevDuck auto-pulls models, but if it fails:
|
|
602
|
+
ollama pull qwen3:1.7b
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
**Port already in use:**
|
|
606
|
+
```bash
|
|
607
|
+
# Change ports
|
|
608
|
+
export DEVDUCK_TCP_PORT=9000
|
|
609
|
+
export DEVDUCK_WS_PORT=8001
|
|
610
|
+
devduck
|
|
611
|
+
```
|
|
612
|
+
|
|
613
|
+
**Hot-reload not working:**
|
|
614
|
+
```bash
|
|
615
|
+
# Ensure tools directory exists
|
|
616
|
+
mkdir -p ./tools
|
|
617
|
+
|
|
618
|
+
# Check file watcher logs
|
|
619
|
+
devduck
|
|
620
|
+
🦆 view_logs(action="search", pattern="watcher")
|
|
621
|
+
```
|
|
622
|
+
|
|
623
|
+
**Memory/performance issues:**
|
|
624
|
+
```bash
|
|
625
|
+
# Use lighter model
|
|
626
|
+
export STRANDS_MODEL_ID="qwen3:0.5b"
|
|
627
|
+
|
|
628
|
+
# Reduce context
|
|
629
|
+
export DEVDUCK_LOG_LINE_COUNT=20
|
|
630
|
+
export DEVDUCK_LAST_MESSAGE_COUNT=50
|
|
631
|
+
```
|
|
632
|
+
|
|
633
|
+
**Ambient overlay not starting:**
|
|
634
|
+
```bash
|
|
635
|
+
# Make sure tkinter is installed
|
|
636
|
+
python3 -c "import tkinter"
|
|
637
|
+
|
|
638
|
+
# Install tkinter if missing
|
|
639
|
+
brew install python-tk@3.13 # macOS
|
|
640
|
+
sudo apt-get install python3-tk # Ubuntu/Debian
|
|
641
|
+
sudo dnf install python3-tkinter # Fedora
|
|
642
|
+
```
|
|
643
|
+
|
|
644
|
+
**Tray app not starting (macOS):**
|
|
645
|
+
```bash
|
|
646
|
+
# Install rumps
|
|
647
|
+
pip install rumps
|
|
648
|
+
|
|
649
|
+
# Or reinstall devduck
|
|
650
|
+
pip install -e .
|
|
651
|
+
```
|
|
652
|
+
|
|
653
|
+
**View logs:** `devduck` → `🦆 view_logs()`
|
|
654
|
+
|
|
655
|
+
---
|
|
656
|
+
|
|
657
|
+
## GitHub Actions
|
|
658
|
+
|
|
659
|
+
**Run DevDuck in CI/CD pipelines:**
|
|
660
|
+
|
|
661
|
+
```yaml
|
|
662
|
+
name: AI Code Assistant
|
|
663
|
+
on:
|
|
664
|
+
issues:
|
|
665
|
+
types: [opened, edited]
|
|
666
|
+
pull_request:
|
|
667
|
+
types: [opened, edited, synchronize]
|
|
668
|
+
|
|
669
|
+
jobs:
|
|
670
|
+
devduck:
|
|
671
|
+
runs-on: ubuntu-latest
|
|
672
|
+
permissions:
|
|
673
|
+
contents: read
|
|
674
|
+
issues: write
|
|
675
|
+
pull-requests: write
|
|
676
|
+
steps:
|
|
677
|
+
- uses: cagataycali/devduck@main
|
|
678
|
+
with:
|
|
679
|
+
task: "Analyze and help with this issue or PR"
|
|
680
|
+
provider: "github"
|
|
681
|
+
model: "gpt-4o"
|
|
682
|
+
tools: "shell,file_read,file_write,use_github,calculator"
|
|
683
|
+
env:
|
|
684
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
685
|
+
```
|
|
686
|
+
|
|
687
|
+
**Sub-agent workflows:**
|
|
688
|
+
```python
|
|
689
|
+
devduck("Create a sub-agent to analyze test coverage")
|
|
690
|
+
```
|
|
691
|
+
|
|
692
|
+
---
|
|
693
|
+
|
|
694
|
+
## Resources
|
|
695
|
+
|
|
696
|
+
- **Strands SDK:** [github.com/strands-agents/sdk-python](https://github.com/strands-agents/sdk-python)
|
|
697
|
+
- **Documentation:** [strandsagents.com](https://strandsagents.com)
|
|
698
|
+
- **Web UI:** [cagataycali.github.io/devduck](http://cagataycali.github.io/devduck)
|
|
699
|
+
|
|
700
|
+
---
|
|
701
|
+
|
|
702
|
+
## Citation
|
|
703
|
+
|
|
704
|
+
```bibtex
|
|
705
|
+
@software{devduck2025,
|
|
706
|
+
author = {Cagatay Cali},
|
|
707
|
+
title = {DevDuck: Self-Modifying AI Agent with Hot-Reload and Multi-Protocol Servers},
|
|
708
|
+
year = {2025},
|
|
709
|
+
url = {https://github.com/cagataycali/devduck}
|
|
710
|
+
}
|
|
711
|
+
```
|
|
712
|
+
|
|
713
|
+
---
|
|
714
|
+
|
|
715
|
+
**Apache 2.0** | Built with [Strands Agents](https://strandsagents.com) | [@cagataycali](https://github.com/cagataycali)
|