devduck 0.7.2__tar.gz → 1.1.3__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 (53) hide show
  1. {devduck-0.7.2 → devduck-1.1.3}/.github/workflows/agent.yml +2 -2
  2. {devduck-0.7.2 → devduck-1.1.3}/.gitignore +4 -1
  3. {devduck-0.7.2 → devduck-1.1.3}/PKG-INFO +6 -4
  4. {devduck-0.7.2 → devduck-1.1.3}/README.md +3 -3
  5. {devduck-0.7.2 → devduck-1.1.3}/action.yml +1 -1
  6. {devduck-0.7.2 → devduck-1.1.3}/devduck/__init__.py +143 -57
  7. {devduck-0.7.2 → devduck-1.1.3}/devduck/_version.py +3 -3
  8. devduck-1.1.3/devduck/tools/__init__.py +47 -0
  9. devduck-1.1.3/devduck/tools/speech_to_speech.py +850 -0
  10. {devduck-0.7.2 → devduck-1.1.3}/devduck/tools/system_prompt.py +276 -153
  11. {devduck-0.7.2 → devduck-1.1.3}/devduck.egg-info/PKG-INFO +6 -4
  12. {devduck-0.7.2 → devduck-1.1.3}/devduck.egg-info/SOURCES.txt +4 -2
  13. {devduck-0.7.2 → devduck-1.1.3}/devduck.egg-info/entry_points.txt +1 -0
  14. {devduck-0.7.2 → devduck-1.1.3}/devduck.egg-info/requires.txt +2 -0
  15. {devduck-0.7.2 → devduck-1.1.3}/pyproject.toml +3 -0
  16. devduck-1.1.3/tools/fetch_github_tool.py +201 -0
  17. devduck-0.7.2/devduck/tools/__init__.py +0 -55
  18. {devduck-0.7.2 → devduck-1.1.3}/LICENSE +0 -0
  19. {devduck-0.7.2 → devduck-1.1.3}/MANIFEST.in +0 -0
  20. {devduck-0.7.2 → devduck-1.1.3}/agent_runner.py +0 -0
  21. {devduck-0.7.2 → devduck-1.1.3}/devduck/__main__.py +0 -0
  22. {devduck-0.7.2 → devduck-1.1.3}/devduck/agentcore_handler.py +0 -0
  23. {devduck-0.7.2 → devduck-1.1.3}/devduck/test_redduck.py +0 -0
  24. {devduck-0.7.2 → devduck-1.1.3}/devduck/tools/_ambient_input.py +0 -0
  25. {devduck-0.7.2 → devduck-1.1.3}/devduck/tools/_tray_app.py +0 -0
  26. {devduck-0.7.2 → devduck-1.1.3}/devduck/tools/agentcore_agents.py +0 -0
  27. {devduck-0.7.2 → devduck-1.1.3}/devduck/tools/agentcore_config.py +0 -0
  28. {devduck-0.7.2 → devduck-1.1.3}/devduck/tools/agentcore_invoke.py +0 -0
  29. {devduck-0.7.2 → devduck-1.1.3}/devduck/tools/agentcore_logs.py +0 -0
  30. {devduck-0.7.2 → devduck-1.1.3}/devduck/tools/ambient.py +0 -0
  31. {devduck-0.7.2 → devduck-1.1.3}/devduck/tools/create_subagent.py +0 -0
  32. {devduck-0.7.2 → devduck-1.1.3/devduck}/tools/fetch_github_tool.py +0 -0
  33. {devduck-0.7.2 → devduck-1.1.3}/devduck/tools/install_tools.py +0 -0
  34. {devduck-0.7.2 → devduck-1.1.3}/devduck/tools/ipc.py +0 -0
  35. {devduck-0.7.2 → devduck-1.1.3}/devduck/tools/mcp_server.py +0 -0
  36. {devduck-0.7.2 → devduck-1.1.3/devduck}/tools/scraper.py +0 -0
  37. {devduck-0.7.2 → devduck-1.1.3}/devduck/tools/state_manager.py +0 -0
  38. {devduck-0.7.2 → devduck-1.1.3}/devduck/tools/store_in_kb.py +0 -0
  39. {devduck-0.7.2 → devduck-1.1.3}/devduck/tools/tcp.py +0 -0
  40. {devduck-0.7.2 → devduck-1.1.3}/devduck/tools/tray.py +0 -0
  41. {devduck-0.7.2 → devduck-1.1.3}/devduck/tools/use_github.py +0 -0
  42. {devduck-0.7.2 → devduck-1.1.3}/devduck/tools/websocket.py +0 -0
  43. {devduck-0.7.2 → devduck-1.1.3}/devduck.egg-info/dependency_links.txt +0 -0
  44. {devduck-0.7.2 → devduck-1.1.3}/devduck.egg-info/top_level.txt +0 -0
  45. {devduck-0.7.2 → devduck-1.1.3}/docs/index.html +0 -0
  46. {devduck-0.7.2 → devduck-1.1.3}/docs/mac-os-tray.jpg +0 -0
  47. {devduck-0.7.2 → devduck-1.1.3}/requirements.txt +0 -0
  48. {devduck-0.7.2 → devduck-1.1.3}/setup-aws-oidc.sh +0 -0
  49. {devduck-0.7.2 → devduck-1.1.3}/setup.cfg +0 -0
  50. {devduck-0.7.2 → devduck-1.1.3}/test.py +0 -0
  51. {devduck-0.7.2 → devduck-1.1.3}/tools/__init__.py +0 -0
  52. {devduck-0.7.2 → devduck-1.1.3}/tools/gist.py +0 -0
  53. {devduck-0.7.2 → devduck-1.1.3}/tools/github_tools.py +0 -0
@@ -1,8 +1,8 @@
1
1
  name: DevDuck
2
2
 
3
3
  on:
4
- schedule:
5
- - cron: '0 8 * * *'
4
+ # schedule:
5
+ # - cron: '0 8 * * *'
6
6
  issues:
7
7
  types: [opened, edited, closed, reopened, assigned, unassigned, labeled, unlabeled]
8
8
  issue_comment:
@@ -7,4 +7,7 @@ dist/
7
7
  build
8
8
  _version.py
9
9
  .bedrock_agentcore.yaml
10
- .bedrock_agentcore
10
+ .bedrock_agentcore
11
+ google_*.json
12
+ gmail_*.json
13
+ .DS_Store
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devduck
3
- Version: 0.7.2
3
+ Version: 1.1.3
4
4
  Summary: 🦆 Extreme minimalist self-adapting AI agent - one file, self-healing, runtime dependencies
5
5
  Author-email: Cagatay Cali <cagataycali@icloud.com>
6
6
  License: Apache-2.0
@@ -31,6 +31,7 @@ Requires-Dist: prompt_toolkit
31
31
  Requires-Dist: strands-agents[ollama]
32
32
  Requires-Dist: strands-agents[anthropic]
33
33
  Requires-Dist: strands-agents[openai]
34
+ Requires-Dist: strands-agents[bidi-all]; sys_platform == "darwin"
34
35
  Requires-Dist: strands-agents[otel]
35
36
  Requires-Dist: strands-agents-tools
36
37
  Requires-Dist: strands-fun-tools[all]; sys_platform == "darwin"
@@ -39,6 +40,7 @@ Requires-Dist: beautifulsoup4
39
40
  Requires-Dist: colorama
40
41
  Requires-Dist: websockets
41
42
  Requires-Dist: strands-mcp-server
43
+ Requires-Dist: strands-google
42
44
  Requires-Dist: bedrock-agentcore-starter-toolkit
43
45
  Requires-Dist: bedrock-agentcore
44
46
  Requires-Dist: rumps; sys_platform == "darwin"
@@ -239,7 +241,7 @@ install_tools(action="list_loaded")
239
241
 
240
242
  ### Static Tool Configuration
241
243
 
242
- **Format:** `package:tool1,tool2:package2:tool3`
244
+ **Format:** `package1:tool1,tool2;package2:tool3,tool4`
243
245
 
244
246
  ```bash
245
247
  # Minimal (shell + editor only)
@@ -249,7 +251,7 @@ export DEVDUCK_TOOLS="strands_tools:shell,editor"
249
251
  export DEVDUCK_TOOLS="strands_tools:shell,editor,file_read,file_write,calculator"
250
252
 
251
253
  # Full stack + GitHub
252
- export DEVDUCK_TOOLS="devduck.tools:tcp,websocket,mcp_server,use_github:strands_tools:shell,editor,file_read"
254
+ export DEVDUCK_TOOLS="devduck.tools:tcp,websocket,mcp_server,use_github;strands_tools:shell,editor,file_read"
253
255
 
254
256
  devduck
255
257
  ```
@@ -572,7 +574,7 @@ devduck
572
574
  | `LITELLM_API_KEY` | - | LiteLLM API key (auto-detected) |
573
575
  | `LLAMAAPI_API_KEY` | - | LlamaAPI key (auto-detected) |
574
576
  | **Tools** | | |
575
- | `DEVDUCK_TOOLS` | 38 tools | Format: `package:tool1,tool2:package2:tool3` |
577
+ | `DEVDUCK_TOOLS` | 38 tools | Format: `package1:tool1,tool2;package2:tool3` |
576
578
  | `DEVDUCK_LOAD_TOOLS_FROM_DIR` | `false` | Auto-load from `./tools/` directory |
577
579
  | **Memory** | | |
578
580
  | `DEVDUCK_KNOWLEDGE_BASE_ID` | - | Bedrock KB ID for auto-RAG |
@@ -192,7 +192,7 @@ install_tools(action="list_loaded")
192
192
 
193
193
  ### Static Tool Configuration
194
194
 
195
- **Format:** `package:tool1,tool2:package2:tool3`
195
+ **Format:** `package1:tool1,tool2;package2:tool3,tool4`
196
196
 
197
197
  ```bash
198
198
  # Minimal (shell + editor only)
@@ -202,7 +202,7 @@ export DEVDUCK_TOOLS="strands_tools:shell,editor"
202
202
  export DEVDUCK_TOOLS="strands_tools:shell,editor,file_read,file_write,calculator"
203
203
 
204
204
  # Full stack + GitHub
205
- export DEVDUCK_TOOLS="devduck.tools:tcp,websocket,mcp_server,use_github:strands_tools:shell,editor,file_read"
205
+ export DEVDUCK_TOOLS="devduck.tools:tcp,websocket,mcp_server,use_github;strands_tools:shell,editor,file_read"
206
206
 
207
207
  devduck
208
208
  ```
@@ -525,7 +525,7 @@ devduck
525
525
  | `LITELLM_API_KEY` | - | LiteLLM API key (auto-detected) |
526
526
  | `LLAMAAPI_API_KEY` | - | LlamaAPI key (auto-detected) |
527
527
  | **Tools** | | |
528
- | `DEVDUCK_TOOLS` | 38 tools | Format: `package:tool1,tool2:package2:tool3` |
528
+ | `DEVDUCK_TOOLS` | 38 tools | Format: `package1:tool1,tool2;package2:tool3` |
529
529
  | `DEVDUCK_LOAD_TOOLS_FROM_DIR` | `false` | Auto-load from `./tools/` directory |
530
530
  | **Memory** | | |
531
531
  | `DEVDUCK_KNOWLEDGE_BASE_ID` | - | Bedrock KB ID for auto-RAG |
@@ -42,7 +42,7 @@ inputs:
42
42
  tools:
43
43
  description: 'Comma-separated list of tools to enable'
44
44
  required: false
45
- default: 'current_time'
45
+ default: 'strands_tools:current_time'
46
46
 
47
47
  # Authentication & Access
48
48
  github_token:
@@ -3,19 +3,31 @@
3
3
  🦆 devduck - extreme minimalist self-adapting agent
4
4
  one file. self-healing. runtime dependencies. adaptive.
5
5
  """
6
+ import os
6
7
  import sys
7
8
  import subprocess
8
- import os
9
+ import threading
9
10
  import platform
10
11
  import socket
11
12
  import logging
12
13
  import tempfile
13
14
  import time
14
15
  import warnings
16
+ import json
15
17
  from pathlib import Path
16
18
  from datetime import datetime
17
19
  from typing import Dict, Any
18
20
  from logging.handlers import RotatingFileHandler
21
+ from strands import Agent, tool
22
+
23
+ # Import system prompt helper for loading prompts from files
24
+ try:
25
+ from devduck.tools.system_prompt import _get_system_prompt
26
+ except ImportError:
27
+ # Fallback if tools module not available yet
28
+ def _get_system_prompt(repository=None, variable_name="SYSTEM_PROMPT"):
29
+ return os.getenv(variable_name, "")
30
+
19
31
 
20
32
  warnings.filterwarnings("ignore", message=".*pkg_resources is deprecated.*")
21
33
  warnings.filterwarnings("ignore", message=".*cache_prompt is deprecated.*")
@@ -189,18 +201,7 @@ def manage_tools_func(
189
201
  tool_names: str = None,
190
202
  tool_path: str = None,
191
203
  ) -> Dict[str, Any]:
192
- """
193
- Manage the agent's tool set at runtime using ToolRegistry.
194
-
195
- Args:
196
- action: Action to perform - "list", "add", "remove", "reload"
197
- package: Package name to load tools from (e.g., "strands_tools", "strands_fun_tools")
198
- tool_names: Comma-separated tool names (e.g., "shell,editor,calculator")
199
- tool_path: Path to a .py file to load as a tool
200
-
201
- Returns:
202
- Dict with status and content
203
- """
204
+ """Manage the agent's tool set at runtime - add, remove, list, reload tools on the fly."""
204
205
  try:
205
206
  if not hasattr(devduck, "agent") or not devduck.agent:
206
207
  return {"status": "error", "content": [{"text": "Agent not initialized"}]}
@@ -605,7 +606,7 @@ class DevDuck:
605
606
  servers = {
606
607
  "tcp": {
607
608
  "port": int(os.getenv("DEVDUCK_TCP_PORT", "9999")),
608
- "enabled": os.getenv("DEVDUCK_ENABLE_TCP", "true").lower()
609
+ "enabled": os.getenv("DEVDUCK_ENABLE_TCP", "false").lower()
609
610
  == "true",
610
611
  },
611
612
  "ws": {
@@ -615,25 +616,93 @@ class DevDuck:
615
616
  },
616
617
  "mcp": {
617
618
  "port": int(os.getenv("DEVDUCK_MCP_PORT", "8000")),
618
- "enabled": os.getenv("DEVDUCK_ENABLE_MCP", "true").lower()
619
+ "enabled": os.getenv("DEVDUCK_ENABLE_MCP", "false").lower()
619
620
  == "true",
620
621
  },
621
622
  "ipc": {
622
623
  "socket_path": os.getenv(
623
624
  "DEVDUCK_IPC_SOCKET", "/tmp/devduck_main.sock"
624
625
  ),
625
- "enabled": os.getenv("DEVDUCK_ENABLE_IPC", "true").lower()
626
+ "enabled": os.getenv("DEVDUCK_ENABLE_IPC", "false").lower()
626
627
  == "true",
627
628
  },
628
629
  }
629
630
 
630
- self.servers = servers
631
+ # Show server configuration status
632
+ enabled_servers = []
633
+ disabled_servers = []
634
+ for server_name, config in servers.items():
635
+ if config.get("enabled", False):
636
+ if "port" in config:
637
+ enabled_servers.append(
638
+ f"{server_name.upper()}:{config['port']}"
639
+ )
640
+ else:
641
+ enabled_servers.append(server_name.upper())
642
+ else:
643
+ disabled_servers.append(server_name.upper())
631
644
 
632
- from strands import Agent, tool
645
+ logger.debug(
646
+ f"🦆 Server config: {', '.join(enabled_servers) if enabled_servers else 'none enabled'}"
647
+ )
648
+ if disabled_servers:
649
+ logger.debug(f"🦆 Disabled: {', '.join(disabled_servers)}")
650
+
651
+ self.servers = servers
633
652
 
634
653
  # Load tools with flexible configuration
635
- # Default tool config - user can override with DEVDUCK_TOOLS env var
636
- default_tools = "devduck.tools:system_prompt,store_in_kb,ipc,tcp,websocket,mcp_server,state_manager,tray,ambient,agentcore_config,agentcore_invoke,agentcore_logs,agentcore_agents,install_tools,create_subagent,use_github:strands_tools:shell,editor,file_read,file_write,image_reader,load_tool,retrieve,calculator,use_agent,environment,mcp_client,speak,slack:strands_fun_tools:listen,cursor,clipboard,screen_reader,bluetooth,yolo_vision"
654
+ # Default tool config
655
+ # Agent can load additional tools on-demand via fetch_github_tool
656
+
657
+ # 🔧 Available DevDuck Tools (load on-demand):
658
+ # - system_prompt: https://github.com/cagataycali/devduck/blob/main/devduck/tools/system_prompt.py
659
+ # - store_in_kb: https://github.com/cagataycali/devduck/blob/main/devduck/tools/store_in_kb.py
660
+ # - ipc: https://github.com/cagataycali/devduck/blob/main/devduck/tools/ipc.py
661
+ # - tcp: https://github.com/cagataycali/devduck/blob/main/devduck/tools/tcp.py
662
+ # - websocket: https://github.com/cagataycali/devduck/blob/main/devduck/tools/websocket.py
663
+ # - mcp_server: https://github.com/cagataycali/devduck/blob/main/devduck/tools/mcp_server.py
664
+ # - scraper: https://github.com/cagataycali/devduck/blob/main/devduck/tools/scraper.py
665
+ # - tray: https://github.com/cagataycali/devduck/blob/main/devduck/tools/tray.py
666
+ # - ambient: https://github.com/cagataycali/devduck/blob/main/devduck/tools/ambient.py
667
+ # - agentcore_config: https://github.com/cagataycali/devduck/blob/main/devduck/tools/agentcore_config.py
668
+ # - agentcore_invoke: https://github.com/cagataycali/devduck/blob/main/devduck/tools/agentcore_invoke.py
669
+ # - agentcore_logs: https://github.com/cagataycali/devduck/blob/main/devduck/tools/agentcore_logs.py
670
+ # - agentcore_agents: https://github.com/cagataycali/devduck/blob/main/devduck/tools/agentcore_agents.py
671
+ # - create_subagent: https://github.com/cagataycali/devduck/blob/main/devduck/tools/create_subagent.py
672
+ # - use_github: https://github.com/cagataycali/devduck/blob/main/devduck/tools/use_github.py
673
+ # - speech_to_speech: https://github.com/cagataycali/devduck/blob/main/devduck/tools/speech_to_speech.py
674
+ # - state_manager: https://github.com/cagataycali/devduck/blob/main/devduck/tools/state_manager.py
675
+
676
+ # 📦 Strands Tools
677
+ # - editor, file_read, file_write, image_reader, load_tool, retrieve
678
+ # - calculator, use_agent, environment, mcp_client, speak, slack
679
+
680
+ # 🎮 Strands Fun Tools
681
+ # - listen, cursor, clipboard, screen_reader, bluetooth, yolo_vision
682
+
683
+ # 🔍 Strands Google
684
+ # - use_google, google_auth
685
+
686
+ # 🔧 Auto-append server tools based on enabled servers
687
+ server_tools_needed = []
688
+ if servers.get("tcp", {}).get("enabled", False):
689
+ server_tools_needed.append("tcp")
690
+ if servers.get("ws", {}).get("enabled", False):
691
+ server_tools_needed.append("websocket")
692
+ if servers.get("mcp", {}).get("enabled", False):
693
+ server_tools_needed.append("mcp_server")
694
+ if servers.get("ipc", {}).get("enabled", False):
695
+ server_tools_needed.append("ipc")
696
+
697
+ # Append to default tools if any server tools are needed
698
+ if server_tools_needed:
699
+ server_tools_str = ",".join(server_tools_needed)
700
+ default_tools = f"devduck.tools:system_prompt,fetch_github_tool,{server_tools_str};strands_tools:shell"
701
+ logger.info(f"Auto-added server tools: {server_tools_str}")
702
+ else:
703
+ default_tools = (
704
+ "devduck.tools:system_prompt,fetch_github_tool;strands_tools:shell"
705
+ )
637
706
 
638
707
  tools_config = os.getenv("DEVDUCK_TOOLS", default_tools)
639
708
  logger.info(f"Loading tools from config: {tools_config}")
@@ -657,7 +726,18 @@ class DevDuck:
657
726
  tool_names: str = None,
658
727
  tool_path: str = None,
659
728
  ) -> Dict[str, Any]:
660
- """Manage the agent's tool set at runtime - add, remove, list, reload tools on the fly."""
729
+ """
730
+ Manage the agent's tool set at runtime using ToolRegistry.
731
+
732
+ Args:
733
+ action: Action to perform - "list", "add", "remove", "reload"
734
+ package: Package name to load tools from (e.g., "strands_tools", "strands_fun_tools") or "devduck.tools:speech_to_speech,system_prompt,..."
735
+ tool_names: Comma-separated tool names (e.g., "shell,editor,calculator")
736
+ tool_path: Path to a .py file to load as a tool
737
+
738
+ Returns:
739
+ Dict with status and content
740
+ """
661
741
  return manage_tools_func(action, package, tool_names, tool_path)
662
742
 
663
743
  # Add built-in tools to the toolset
@@ -715,39 +795,39 @@ class DevDuck:
715
795
  """
716
796
  Load tools based on DEVDUCK_TOOLS configuration.
717
797
 
718
- Format: package:tool1,tool2:package2:tool3
719
- Example: strands_tools:shell,editor:strands_fun_tools:clipboard
798
+ Format: package1:tool1,tool2;package2:tool3,tool4
799
+ Examples:
800
+ - strands_tools:shell,editor;strands_action:use_github
801
+ - strands_action:use_github;strands_tools:shell,use_aws
720
802
 
721
803
  Note: Only loads what's specified in config - no automatic additions
722
804
  """
723
805
  tools = []
724
- current_package = None
725
-
726
- for segment in config.split(":"):
727
- segment = segment.strip()
728
-
729
- # Check if segment is a package name (contains '.' or '_' and no ',')
730
- is_package = "," not in segment and ("." in segment or "_" in segment)
731
-
732
- if is_package:
733
- # This is a package name - set as current package
734
- current_package = segment
735
- logger.debug(f"Switched to package: {current_package}")
736
- elif "," in segment:
737
- # Tool list from current package
738
- if current_package:
739
- for tool_name in segment.split(","):
740
- tool_name = tool_name.strip()
741
- tool = self._load_single_tool(current_package, tool_name)
742
- if tool:
743
- tools.append(tool)
744
- elif current_package:
745
- # Single tool from current package
746
- tool = self._load_single_tool(current_package, segment)
806
+
807
+ # Split by semicolon to get package groups
808
+ groups = config.split(";")
809
+
810
+ for group in groups:
811
+ group = group.strip()
812
+ if not group:
813
+ continue
814
+
815
+ # Split by colon to get package:tools
816
+ parts = group.split(":", 1)
817
+ if len(parts) != 2:
818
+ logger.warning(f"Invalid format: {group}")
819
+ continue
820
+
821
+ package = parts[0].strip()
822
+ tools_str = parts[1].strip()
823
+
824
+ # Parse tools (comma-separated)
825
+ tool_names = [t.strip() for t in tools_str.split(",") if t.strip()]
826
+
827
+ for tool_name in tool_names:
828
+ tool = self._load_single_tool(package, tool_name)
747
829
  if tool:
748
830
  tools.append(tool)
749
- else:
750
- logger.warning(f"Skipping segment '{segment}' - no package set")
751
831
 
752
832
  logger.info(f"Loaded {len(tools)} tools from configuration")
753
833
  return tools
@@ -776,8 +856,6 @@ class DevDuck:
776
856
  Returns:
777
857
  List of MCPClient instances ready for direct use in Agent
778
858
  """
779
- import json
780
-
781
859
  mcp_servers_json = os.getenv("MCP_SERVERS")
782
860
  if not mcp_servers_json:
783
861
  logger.debug("No MCP_SERVERS environment variable found")
@@ -1094,9 +1172,11 @@ You have full access to your own source code for self-awareness and self-modific
1094
1172
 
1095
1173
  ## Tool Configuration:
1096
1174
  Set DEVDUCK_TOOLS for custom tools:
1097
- - Format: package:tool1,tool2:package2:tool3
1098
- - Example: strands_tools:shell,editor:strands_fun_tools:clipboard
1175
+ - Format: package1:tool1,tool2;package2:tool3,tool4
1176
+ - Example: strands_tools:shell,editor;strands_fun_tools:clipboard
1099
1177
  - Tools are filtered - only specified tools are loaded
1178
+ - Load the speech_to_speech tool when it's needed
1179
+ - Offload the tools when you don't need
1100
1180
 
1101
1181
  ## MCP Integration:
1102
1182
  - **Expose as MCP Server** - Use mcp_server() to expose devduck via MCP protocol
@@ -1143,7 +1223,7 @@ When you learn something valuable during conversations:
1143
1223
  - Communication: **MINIMAL WORDS**
1144
1224
  - Efficiency: **Speed is paramount**
1145
1225
 
1146
- {os.getenv('SYSTEM_PROMPT', '')}"""
1226
+ {_get_system_prompt()}"""
1147
1227
 
1148
1228
  def _self_heal(self, error):
1149
1229
  """Attempt self-healing when errors occur"""
@@ -1190,7 +1270,6 @@ When you learn something valuable during conversations:
1190
1270
 
1191
1271
  def _is_socket_available(self, socket_path):
1192
1272
  """Check if a Unix socket is available"""
1193
- import os
1194
1273
 
1195
1274
  # If socket file doesn't exist, it's available
1196
1275
  if not os.path.exists(socket_path):
@@ -1428,11 +1507,11 @@ When you learn something valuable during conversations:
1428
1507
  def restart(self):
1429
1508
  """Restart the agent"""
1430
1509
  print("\n🦆 Restarting...")
1510
+ logger.debug("\n🦆 Restarting...")
1431
1511
  self.__init__()
1432
1512
 
1433
1513
  def _start_file_watcher(self):
1434
1514
  """Start background file watcher for auto hot-reload"""
1435
- import threading
1436
1515
 
1437
1516
  logger.info("Starting file watcher for hot-reload")
1438
1517
  # Get the path to this file
@@ -1532,6 +1611,7 @@ When you learn something valuable during conversations:
1532
1611
  self._watcher_running = False
1533
1612
 
1534
1613
  print("\n🦆 Restarting process with fresh code...")
1614
+ logger.debug("\n🦆 Restarting process with fresh code...")
1535
1615
 
1536
1616
  # Restart the entire Python process
1537
1617
  # This ensures all code is freshly loaded
@@ -1675,7 +1755,7 @@ def interactive():
1675
1755
  print(f"📝 Logs: {LOG_DIR}")
1676
1756
  print("Type 'exit', 'quit', or 'q' to quit.")
1677
1757
  print("Prefix with ! to run shell commands (e.g., ! ls -la)")
1678
- print("-" * 50)
1758
+ print("\n\n")
1679
1759
  logger.info("Interactive mode started")
1680
1760
 
1681
1761
  # Set up prompt_toolkit with history
@@ -1703,7 +1783,6 @@ def interactive():
1703
1783
  auto_suggest=AutoSuggestFromHistory(),
1704
1784
  completer=completer,
1705
1785
  complete_while_typing=True,
1706
- mouse_support=False, # breaks scrolling when enabled
1707
1786
  )
1708
1787
 
1709
1788
  # Reset interrupt count on successful prompt
@@ -1731,6 +1810,10 @@ def interactive():
1731
1810
  )
1732
1811
  devduck._agent_executing = False
1733
1812
 
1813
+ # Reset terminal to fix rendering issues after command output
1814
+ print("\r", end="", flush=True)
1815
+ sys.stdout.flush()
1816
+
1734
1817
  # Append shell command to history
1735
1818
  append_to_shell_history(q, result["content"][0]["text"])
1736
1819
 
@@ -1745,6 +1828,9 @@ def interactive():
1745
1828
  except Exception as e:
1746
1829
  devduck._agent_executing = False # Reset on error
1747
1830
  print(f"🦆 Shell command error: {e}")
1831
+ # Reset terminal on error too
1832
+ print("\r", end="", flush=True)
1833
+ sys.stdout.flush()
1748
1834
  continue
1749
1835
 
1750
1836
  # Execute the agent with user input
@@ -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.7.2'
32
- __version_tuple__ = version_tuple = (0, 7, 2)
31
+ __version__ = version = '1.1.3'
32
+ __version_tuple__ = version_tuple = (1, 1, 3)
33
33
 
34
- __commit_id__ = commit_id = 'gadb5e74d2'
34
+ __commit_id__ = commit_id = 'gacfc41193'
@@ -0,0 +1,47 @@
1
+ """
2
+ DevDuck Tools Package
3
+
4
+ This module exports all available tools for devduck.
5
+ """
6
+
7
+ from .agentcore_agents import agentcore_agents
8
+ from .agentcore_config import agentcore_config
9
+ from .agentcore_invoke import agentcore_invoke
10
+ from .agentcore_logs import agentcore_logs
11
+ from .ambient import ambient
12
+ from .create_subagent import create_subagent
13
+ from .fetch_github_tool import fetch_github_tool
14
+ from .install_tools import install_tools
15
+ from .ipc import ipc
16
+ from .mcp_server import mcp_server
17
+ from .scraper import scraper
18
+ from .speech_to_speech import speech_to_speech
19
+ from .state_manager import state_manager
20
+ from .store_in_kb import store_in_kb
21
+ from .system_prompt import system_prompt
22
+ from .tcp import tcp
23
+ from .tray import tray
24
+ from .use_github import use_github
25
+ from .websocket import websocket
26
+
27
+ __all__ = [
28
+ "agentcore_agents",
29
+ "agentcore_config",
30
+ "agentcore_invoke",
31
+ "agentcore_logs",
32
+ "ambient",
33
+ "create_subagent",
34
+ "fetch_github_tool",
35
+ "install_tools",
36
+ "ipc",
37
+ "mcp_server",
38
+ "scraper",
39
+ "speech_to_speech",
40
+ "state_manager",
41
+ "store_in_kb",
42
+ "system_prompt",
43
+ "tcp",
44
+ "tray",
45
+ "use_github",
46
+ "websocket",
47
+ ]