devduck 0.4.0__tar.gz → 0.4.1__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.

Files changed (40) hide show
  1. {devduck-0.4.0/devduck.egg-info → devduck-0.4.1}/PKG-INFO +29 -6
  2. {devduck-0.4.0 → devduck-0.4.1}/README.md +28 -5
  3. {devduck-0.4.0 → devduck-0.4.1}/devduck/__init__.py +31 -180
  4. {devduck-0.4.0 → devduck-0.4.1}/devduck/_version.py +3 -3
  5. {devduck-0.4.0 → devduck-0.4.1/devduck.egg-info}/PKG-INFO +29 -6
  6. {devduck-0.4.0 → devduck-0.4.1}/devduck.egg-info/SOURCES.txt +2 -2
  7. {devduck-0.4.0 → devduck-0.4.1}/.github/workflows/agent.yml +0 -0
  8. {devduck-0.4.0 → devduck-0.4.1}/.gitignore +0 -0
  9. {devduck-0.4.0 → devduck-0.4.1}/LICENSE +0 -0
  10. {devduck-0.4.0 → devduck-0.4.1}/MANIFEST.in +0 -0
  11. {devduck-0.4.0 → devduck-0.4.1}/action.yml +0 -0
  12. {devduck-0.4.0 → devduck-0.4.1}/agent_runner.py +0 -0
  13. {devduck-0.4.0 → devduck-0.4.1}/devduck/__main__.py +0 -0
  14. {devduck-0.4.0 → devduck-0.4.1}/devduck/test_redduck.py +0 -0
  15. {devduck-0.4.0 → devduck-0.4.1}/devduck/tools/__init__.py +0 -0
  16. {devduck-0.4.0 → devduck-0.4.1}/devduck/tools/create_subagent.py +0 -0
  17. {devduck-0.4.0 → devduck-0.4.1}/devduck/tools/install_tools.py +0 -0
  18. {devduck-0.4.0 → devduck-0.4.1}/devduck/tools/mcp_server.py +0 -0
  19. {devduck-0.4.0 → devduck-0.4.1}/devduck/tools/store_in_kb.py +0 -0
  20. {devduck-0.4.0 → devduck-0.4.1/devduck}/tools/system_prompt.py +0 -0
  21. {devduck-0.4.0 → devduck-0.4.1}/devduck/tools/tcp.py +0 -0
  22. {devduck-0.4.0 → devduck-0.4.1}/devduck/tools/use_github.py +0 -0
  23. {devduck-0.4.0 → devduck-0.4.1}/devduck/tools/websocket.py +0 -0
  24. {devduck-0.4.0 → devduck-0.4.1}/devduck.egg-info/dependency_links.txt +0 -0
  25. {devduck-0.4.0 → devduck-0.4.1}/devduck.egg-info/entry_points.txt +0 -0
  26. {devduck-0.4.0 → devduck-0.4.1}/devduck.egg-info/requires.txt +0 -0
  27. {devduck-0.4.0 → devduck-0.4.1}/devduck.egg-info/top_level.txt +0 -0
  28. {devduck-0.4.0 → devduck-0.4.1}/docs/index.html +0 -0
  29. {devduck-0.4.0 → devduck-0.4.1}/install.sh +0 -0
  30. {devduck-0.4.0 → devduck-0.4.1}/mcp.json +0 -0
  31. {devduck-0.4.0 → devduck-0.4.1}/pyproject.toml +0 -0
  32. {devduck-0.4.0 → devduck-0.4.1}/requirements.txt +0 -0
  33. {devduck-0.4.0 → devduck-0.4.1}/setup-aws-oidc.sh +0 -0
  34. {devduck-0.4.0 → devduck-0.4.1}/setup.cfg +0 -0
  35. {devduck-0.4.0 → devduck-0.4.1}/test.py +0 -0
  36. {devduck-0.4.0 → devduck-0.4.1}/tools/__init__.py +0 -0
  37. {devduck-0.4.0 → devduck-0.4.1}/tools/fetch_github_tool.py +0 -0
  38. {devduck-0.4.0 → devduck-0.4.1}/tools/gist.py +0 -0
  39. {devduck-0.4.0 → devduck-0.4.1}/tools/github_tools.py +0 -0
  40. {devduck-0.4.0 → devduck-0.4.1}/tools/scraper.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devduck
3
- Version: 0.4.0
3
+ Version: 0.4.1
4
4
  Summary: 🦆 Extreme minimalist self-adapting AI agent - one file, self-healing, runtime dependencies
5
5
  Author-email: duck <hey@devduck.dev>
6
6
  License-Expression: MIT
@@ -51,10 +51,22 @@ Minimalist AI that adapts to your environment and fixes itself when things break
51
51
 
52
52
  ## Install
53
53
 
54
+ **Homebrew (macOS/Linux):**
55
+ ```bash
56
+ brew tap cagataycali/devduck
57
+ brew install devduck
58
+ ```
59
+
60
+ **pipx (all platforms):**
54
61
  ```bash
55
62
  pipx install "devduck[all]" # Full install (recommended)
56
63
  ```
57
64
 
65
+ **uvx (instant run, no install):**
66
+ ```bash
67
+ uvx devduck "hello world"
68
+ ```
69
+
58
70
  Requires: Python 3.10+, Ollama (or set `MODEL_PROVIDER`)
59
71
 
60
72
  ## Quick Start
@@ -246,11 +258,22 @@ Log location: `/tmp/devduck/logs/devduck.log`
246
258
  Run DevDuck in CI/CD:
247
259
 
248
260
  ```yaml
249
- - name: DevDuck Analysis
250
- uses: cagataycali/devduck@main
251
- with:
252
- query: "analyze test coverage"
253
- model: "us.anthropic.claude-sonnet-4-20250514-v1:0"
261
+ name: AI Assistant
262
+ on: [issues, pull_request]
263
+
264
+ jobs:
265
+ assistant:
266
+ runs-on: ubuntu-latest
267
+ permissions:
268
+ contents: read
269
+ issues: write
270
+ pull-requests: write
271
+ steps:
272
+ - uses: cagataycali/devduck@main
273
+ with:
274
+ task: "Help with this issue or PR"
275
+ provider: "github"
276
+ model: "openai/o4-mini"
254
277
  ```
255
278
 
256
279
  ---
@@ -6,10 +6,22 @@ Minimalist AI that adapts to your environment and fixes itself when things break
6
6
 
7
7
  ## Install
8
8
 
9
+ **Homebrew (macOS/Linux):**
10
+ ```bash
11
+ brew tap cagataycali/devduck
12
+ brew install devduck
13
+ ```
14
+
15
+ **pipx (all platforms):**
9
16
  ```bash
10
17
  pipx install "devduck[all]" # Full install (recommended)
11
18
  ```
12
19
 
20
+ **uvx (instant run, no install):**
21
+ ```bash
22
+ uvx devduck "hello world"
23
+ ```
24
+
13
25
  Requires: Python 3.10+, Ollama (or set `MODEL_PROVIDER`)
14
26
 
15
27
  ## Quick Start
@@ -201,11 +213,22 @@ Log location: `/tmp/devduck/logs/devduck.log`
201
213
  Run DevDuck in CI/CD:
202
214
 
203
215
  ```yaml
204
- - name: DevDuck Analysis
205
- uses: cagataycali/devduck@main
206
- with:
207
- query: "analyze test coverage"
208
- model: "us.anthropic.claude-sonnet-4-20250514-v1:0"
216
+ name: AI Assistant
217
+ on: [issues, pull_request]
218
+
219
+ jobs:
220
+ assistant:
221
+ runs-on: ubuntu-latest
222
+ permissions:
223
+ contents: read
224
+ issues: write
225
+ pull-requests: write
226
+ steps:
227
+ - uses: cagataycali/devduck@main
228
+ with:
229
+ task: "Help with this issue or PR"
230
+ provider: "github"
231
+ model: "openai/o4-mini"
209
232
  ```
210
233
 
211
234
  ---
@@ -126,168 +126,6 @@ def get_own_source_code():
126
126
  except Exception as e:
127
127
  return f"Error reading own source code: {e}"
128
128
 
129
-
130
- # 🛠️ System prompt tool (with .prompt file persistence)
131
- def system_prompt_tool(
132
- action: str,
133
- prompt: str | None = None,
134
- context: str | None = None,
135
- variable_name: str = "SYSTEM_PROMPT",
136
- ) -> Dict[str, Any]:
137
- """
138
- Manage the agent's system prompt dynamically with file persistence.
139
-
140
- Args:
141
- action: "view", "update", "add_context", or "reset"
142
- prompt: New system prompt text (required for "update")
143
- context: Additional context to prepend (for "add_context")
144
- variable_name: Environment variable name (default: SYSTEM_PROMPT)
145
-
146
- Returns:
147
- Dict with status and content
148
- """
149
- from pathlib import Path
150
- import tempfile
151
-
152
- def _get_prompt_file_path() -> Path:
153
- """Get the .prompt file path in temp directory."""
154
- temp_dir = Path(tempfile.gettempdir()) / ".devduck"
155
- temp_dir.mkdir(exist_ok=True, mode=0o700) # Create with restrictive permissions
156
- return temp_dir / ".prompt"
157
-
158
- def _write_prompt_file(prompt_text: str) -> None:
159
- """Write prompt to .prompt file in temp directory."""
160
- prompt_file = _get_prompt_file_path()
161
- try:
162
- # Create file with restrictive permissions
163
- with open(
164
- prompt_file,
165
- "w",
166
- encoding="utf-8",
167
- opener=lambda path, flags: os.open(path, flags, 0o600),
168
- ) as f:
169
- f.write(prompt_text)
170
- except (OSError, PermissionError):
171
- try:
172
- prompt_file.write_text(prompt_text, encoding="utf-8")
173
- prompt_file.chmod(0o600)
174
- except (OSError, PermissionError):
175
- prompt_file.write_text(prompt_text, encoding="utf-8")
176
-
177
- def _get_system_prompt(var_name: str) -> str:
178
- """Get current system prompt from environment variable."""
179
- return os.environ.get(var_name, "")
180
-
181
- def _update_system_prompt(new_prompt: str, var_name: str) -> None:
182
- """Update system prompt in both environment and .prompt file."""
183
- os.environ[var_name] = new_prompt
184
- if var_name == "SYSTEM_PROMPT":
185
- _write_prompt_file(new_prompt)
186
-
187
- try:
188
- if action == "view":
189
- current = _get_system_prompt(variable_name)
190
- return {
191
- "status": "success",
192
- "content": [
193
- {"text": f"Current system prompt from {variable_name}:{current}"}
194
- ],
195
- }
196
-
197
- elif action == "update":
198
- if not prompt:
199
- return {
200
- "status": "error",
201
- "content": [
202
- {"text": "Error: prompt parameter required for update action"}
203
- ],
204
- }
205
-
206
- _update_system_prompt(prompt, variable_name)
207
-
208
- if variable_name == "SYSTEM_PROMPT":
209
- message = f"System prompt updated (env: {variable_name}, file: .prompt)"
210
- else:
211
- message = f"System prompt updated (env: {variable_name})"
212
-
213
- return {"status": "success", "content": [{"text": message}]}
214
-
215
- elif action == "add_context":
216
- if not context:
217
- return {
218
- "status": "error",
219
- "content": [
220
- {
221
- "text": "Error: context parameter required for add_context action"
222
- }
223
- ],
224
- }
225
-
226
- current = _get_system_prompt(variable_name)
227
- new_prompt = f"{current} {context}" if current else context
228
- _update_system_prompt(new_prompt, variable_name)
229
-
230
- if variable_name == "SYSTEM_PROMPT":
231
- message = f"Context added to system prompt (env: {variable_name}, file: .prompt)"
232
- else:
233
- message = f"Context added to system prompt (env: {variable_name})"
234
-
235
- return {"status": "success", "content": [{"text": message}]}
236
-
237
- elif action == "reset":
238
- os.environ.pop(variable_name, None)
239
-
240
- if variable_name == "SYSTEM_PROMPT":
241
- prompt_file = _get_prompt_file_path()
242
- if prompt_file.exists():
243
- try:
244
- prompt_file.unlink()
245
- except (OSError, PermissionError):
246
- pass
247
- message = (
248
- f"System prompt reset (env: {variable_name}, file: .prompt cleared)"
249
- )
250
- else:
251
- message = f"System prompt reset (env: {variable_name})"
252
-
253
- return {"status": "success", "content": [{"text": message}]}
254
-
255
- elif action == "get":
256
- # Backward compatibility
257
- current = _get_system_prompt(variable_name)
258
- return {
259
- "status": "success",
260
- "content": [{"text": f"System prompt: {current}"}],
261
- }
262
-
263
- elif action == "set":
264
- # Backward compatibility
265
- if prompt is None:
266
- return {"status": "error", "content": [{"text": "No prompt provided"}]}
267
-
268
- if context:
269
- prompt = f"{context} {prompt}"
270
-
271
- _update_system_prompt(prompt, variable_name)
272
- return {
273
- "status": "success",
274
- "content": [{"text": "System prompt updated successfully"}],
275
- }
276
-
277
- else:
278
- return {
279
- "status": "error",
280
- "content": [
281
- {
282
- "text": f"Unknown action '{action}'. Valid: view, update, add_context, reset"
283
- }
284
- ],
285
- }
286
-
287
- except Exception as e:
288
- return {"status": "error", "content": [{"text": f"Error: {str(e)}"}]}
289
-
290
-
291
129
  def view_logs_tool(
292
130
  action: str = "view",
293
131
  lines: int = 100,
@@ -661,6 +499,7 @@ class DevDuck:
661
499
  use_github,
662
500
  create_subagent,
663
501
  store_in_kb,
502
+ system_prompt,
664
503
  )
665
504
 
666
505
  core_tools.extend(
@@ -672,6 +511,7 @@ class DevDuck:
672
511
  use_github,
673
512
  create_subagent,
674
513
  store_in_kb,
514
+ system_prompt
675
515
  ]
676
516
  )
677
517
  except ImportError as e:
@@ -731,17 +571,6 @@ class DevDuck:
731
571
  "strands-agents-tools not installed - core tools unavailable (install with: pip install devduck[all])"
732
572
  )
733
573
 
734
- # Wrap system_prompt_tool with @tool decorator
735
- @tool
736
- def system_prompt(
737
- action: str,
738
- prompt: str = None,
739
- context: str = None,
740
- variable_name: str = "SYSTEM_PROMPT",
741
- ) -> Dict[str, Any]:
742
- """Manage agent system prompt dynamically."""
743
- return system_prompt_tool(action, prompt, context, variable_name)
744
-
745
574
  # Wrap view_logs_tool with @tool decorator
746
575
  @tool
747
576
  def view_logs(
@@ -753,7 +582,7 @@ class DevDuck:
753
582
  return view_logs_tool(action, lines, pattern)
754
583
 
755
584
  # Add built-in tools to the toolset
756
- core_tools.extend([system_prompt, view_logs])
585
+ core_tools.extend([view_logs])
757
586
 
758
587
  # Assign tools
759
588
  self.tools = core_tools
@@ -980,9 +809,20 @@ def weather(action: str, location: str = None) -> Dict[str, Any]:
980
809
  ```
981
810
 
982
811
  ## System Prompt Management:
983
- - Use system_prompt(action='get') to view current prompt
984
- - Use system_prompt(action='set', prompt='new text') to update
985
- - Changes persist in SYSTEM_PROMPT environment variable
812
+ - **View**: system_prompt(action='view') - See current prompt
813
+ - **Update Local**: system_prompt(action='update', prompt='new text') - Updates env var + .prompt file
814
+ - **Update GitHub**: system_prompt(action='update', prompt='text', repository='cagataycali/devduck') - Syncs to repo variables
815
+ - **Variable Name**: system_prompt(action='update', prompt='text', variable_name='CUSTOM_PROMPT') - Use custom var
816
+ - **Add Context**: system_prompt(action='add_context', context='new learning') - Append without replacing
817
+
818
+ ### 🧠 Self-Improvement Pattern:
819
+ When you learn something valuable during conversations:
820
+ 1. Identify the new insight or pattern
821
+ 2. Use system_prompt(action='add_context', context='...') to append it
822
+ 3. Sync to GitHub: system_prompt(action='update', prompt=new_full_prompt, repository='owner/repo')
823
+ 4. New learnings persist across sessions via SYSTEM_PROMPT env var
824
+
825
+ **Repository Integration**: Set repository='cagataycali/devduck' to sync prompts across deployments
986
826
 
987
827
  ## Shell Commands:
988
828
  - Prefix with ! to execute shell commands directly
@@ -1520,9 +1360,20 @@ You have full access to your own source code for self-awareness and self-modific
1520
1360
  - Full bidirectional communication
1521
1361
 
1522
1362
  ## System Prompt Management:
1523
- - Use system_prompt(action='get') to view current prompt
1524
- - Use system_prompt(action='set', prompt='new text') to update
1525
- - Changes persist in SYSTEM_PROMPT environment variable
1363
+ - **View**: system_prompt(action='view') - See current prompt
1364
+ - **Update Local**: system_prompt(action='update', prompt='new text') - Updates env var + .prompt file
1365
+ - **Update GitHub**: system_prompt(action='update', prompt='text', repository='cagataycali/devduck') - Syncs to repo variables
1366
+ - **Variable Name**: system_prompt(action='update', prompt='text', variable_name='CUSTOM_PROMPT') - Use custom var
1367
+ - **Add Context**: system_prompt(action='add_context', context='new learning') - Append without replacing
1368
+
1369
+ ### 🧠 Self-Improvement Pattern:
1370
+ When you learn something valuable during conversations:
1371
+ 1. Identify the new insight or pattern
1372
+ 2. Use system_prompt(action='add_context', context='...') to append it
1373
+ 3. Optionally sync to GitHub: system_prompt(action='update', prompt=new_full_prompt, repository='owner/repo')
1374
+ 4. New learnings persist across sessions via SYSTEM_PROMPT env var
1375
+
1376
+ **Repository Integration**: Set repository='cagataycali/devduck' to sync prompts across deployments
1526
1377
 
1527
1378
  ## Shell Commands:
1528
1379
  - Prefix with ! to execute shell commands directly
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '0.4.0'
32
- __version_tuple__ = version_tuple = (0, 4, 0)
31
+ __version__ = version = '0.4.1'
32
+ __version_tuple__ = version_tuple = (0, 4, 1)
33
33
 
34
- __commit_id__ = commit_id = 'ga94b2b054'
34
+ __commit_id__ = commit_id = 'gb757a5f0e'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devduck
3
- Version: 0.4.0
3
+ Version: 0.4.1
4
4
  Summary: 🦆 Extreme minimalist self-adapting AI agent - one file, self-healing, runtime dependencies
5
5
  Author-email: duck <hey@devduck.dev>
6
6
  License-Expression: MIT
@@ -51,10 +51,22 @@ Minimalist AI that adapts to your environment and fixes itself when things break
51
51
 
52
52
  ## Install
53
53
 
54
+ **Homebrew (macOS/Linux):**
55
+ ```bash
56
+ brew tap cagataycali/devduck
57
+ brew install devduck
58
+ ```
59
+
60
+ **pipx (all platforms):**
54
61
  ```bash
55
62
  pipx install "devduck[all]" # Full install (recommended)
56
63
  ```
57
64
 
65
+ **uvx (instant run, no install):**
66
+ ```bash
67
+ uvx devduck "hello world"
68
+ ```
69
+
58
70
  Requires: Python 3.10+, Ollama (or set `MODEL_PROVIDER`)
59
71
 
60
72
  ## Quick Start
@@ -246,11 +258,22 @@ Log location: `/tmp/devduck/logs/devduck.log`
246
258
  Run DevDuck in CI/CD:
247
259
 
248
260
  ```yaml
249
- - name: DevDuck Analysis
250
- uses: cagataycali/devduck@main
251
- with:
252
- query: "analyze test coverage"
253
- model: "us.anthropic.claude-sonnet-4-20250514-v1:0"
261
+ name: AI Assistant
262
+ on: [issues, pull_request]
263
+
264
+ jobs:
265
+ assistant:
266
+ runs-on: ubuntu-latest
267
+ permissions:
268
+ contents: read
269
+ issues: write
270
+ pull-requests: write
271
+ steps:
272
+ - uses: cagataycali/devduck@main
273
+ with:
274
+ task: "Help with this issue or PR"
275
+ provider: "github"
276
+ model: "openai/o4-mini"
254
277
  ```
255
278
 
256
279
  ---
@@ -26,6 +26,7 @@ devduck/tools/create_subagent.py
26
26
  devduck/tools/install_tools.py
27
27
  devduck/tools/mcp_server.py
28
28
  devduck/tools/store_in_kb.py
29
+ devduck/tools/system_prompt.py
29
30
  devduck/tools/tcp.py
30
31
  devduck/tools/use_github.py
31
32
  devduck/tools/websocket.py
@@ -34,5 +35,4 @@ tools/__init__.py
34
35
  tools/fetch_github_tool.py
35
36
  tools/gist.py
36
37
  tools/github_tools.py
37
- tools/scraper.py
38
- tools/system_prompt.py
38
+ tools/scraper.py
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes