devduck 0.1.1766644714__py3-none-any.whl → 0.2.0__py3-none-any.whl

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 (36) hide show
  1. devduck/__init__.py +591 -1092
  2. devduck/_version.py +2 -2
  3. devduck/install.sh +42 -0
  4. devduck/test_redduck.py +1 -0
  5. devduck/tools/__init__.py +4 -44
  6. devduck/tools/install_tools.py +2 -103
  7. devduck/tools/mcp_server.py +6 -34
  8. devduck/tools/tcp.py +7 -6
  9. devduck/tools/websocket.py +2 -8
  10. devduck-0.2.0.dist-info/METADATA +143 -0
  11. devduck-0.2.0.dist-info/RECORD +16 -0
  12. {devduck-0.1.1766644714.dist-info → devduck-0.2.0.dist-info}/entry_points.txt +0 -1
  13. devduck-0.2.0.dist-info/licenses/LICENSE +21 -0
  14. devduck/agentcore_handler.py +0 -76
  15. devduck/tools/_ambient_input.py +0 -423
  16. devduck/tools/_tray_app.py +0 -530
  17. devduck/tools/agentcore_agents.py +0 -197
  18. devduck/tools/agentcore_config.py +0 -441
  19. devduck/tools/agentcore_invoke.py +0 -423
  20. devduck/tools/agentcore_logs.py +0 -320
  21. devduck/tools/ambient.py +0 -157
  22. devduck/tools/create_subagent.py +0 -659
  23. devduck/tools/fetch_github_tool.py +0 -201
  24. devduck/tools/ipc.py +0 -546
  25. devduck/tools/scraper.py +0 -935
  26. devduck/tools/speech_to_speech.py +0 -850
  27. devduck/tools/state_manager.py +0 -292
  28. devduck/tools/store_in_kb.py +0 -187
  29. devduck/tools/system_prompt.py +0 -608
  30. devduck/tools/tray.py +0 -247
  31. devduck/tools/use_github.py +0 -438
  32. devduck-0.1.1766644714.dist-info/METADATA +0 -717
  33. devduck-0.1.1766644714.dist-info/RECORD +0 -33
  34. devduck-0.1.1766644714.dist-info/licenses/LICENSE +0 -201
  35. {devduck-0.1.1766644714.dist-info → devduck-0.2.0.dist-info}/WHEEL +0 -0
  36. {devduck-0.1.1766644714.dist-info → devduck-0.2.0.dist-info}/top_level.txt +0 -0
@@ -1,201 +0,0 @@
1
- """GitHub Tool Fetcher for Strands Agent.
2
-
3
- This tool fetches Python tool files from GitHub repositories and loads them
4
- as available tools in the current Strands agent. It combines HTTP fetching
5
- with the load_tool functionality to enable dynamic tool loading from remote
6
- GitHub repositories.
7
-
8
- Usage with Strands Agents:
9
- python
10
- from strands import Agent
11
- from tools.fetch_github_tool import fetch_github_tool
12
-
13
- agent = Agent(tools=[fetch_github_tool])
14
-
15
- # Fetch and load a tool from GitHub
16
- agent.tool.fetch_github_tool(
17
- github_url="https://github.com/owner/repo/blob/main/tools/my_tool.py",
18
- tool_name="my_tool"
19
- )
20
-
21
- # Now you can use the fetched tool
22
- agent.tool.my_tool(param1="value")
23
-
24
-
25
- Supported GitHub URL formats:
26
- - https://github.com/owner/repo/blob/branch/path/to/file.py
27
- - https://github.com/owner/repo/tree/branch/path/to/file.py
28
- - https://raw.githubusercontent.com/owner/repo/branch/path/to/file.py
29
- """
30
-
31
- import os
32
- import re
33
- from pathlib import Path
34
- from typing import Any
35
-
36
- import requests
37
- from strands import tool
38
-
39
-
40
- def parse_github_url(github_url: str) -> dict[str, str]:
41
- """Parse GitHub URL to extract repository information.
42
-
43
- Args:
44
- github_url: GitHub URL to the file
45
-
46
- Returns:
47
- Dictionary with owner, repo, branch, and file_path
48
-
49
- Raises:
50
- ValueError: If URL format is not supported
51
- """
52
- # Handle raw.githubusercontent.com URLs
53
- raw_pattern = r"https://raw\.githubusercontent\.com/([^/]+)/([^/]+)/([^/]+)/(.+)"
54
- raw_match = re.match(raw_pattern, github_url)
55
-
56
- if raw_match:
57
- owner, repo, branch, file_path = raw_match.groups()
58
- return {"owner": owner, "repo": repo, "branch": branch, "file_path": file_path}
59
-
60
- # Handle github.com/owner/repo/blob/branch/path URLs
61
- blob_pattern = r"https://github\.com/([^/]+)/([^/]+)/(?:blob|tree)/([^/]+)/(.+)"
62
- blob_match = re.match(blob_pattern, github_url)
63
-
64
- if blob_match:
65
- owner, repo, branch, file_path = blob_match.groups()
66
- return {"owner": owner, "repo": repo, "branch": branch, "file_path": file_path}
67
-
68
- raise ValueError(f"Unsupported GitHub URL format: {github_url}")
69
-
70
-
71
- def build_raw_url(owner: str, repo: str, branch: str, file_path: str) -> str:
72
- """Build GitHub raw content URL.
73
-
74
- Args:
75
- owner: Repository owner
76
- repo: Repository name
77
- branch: Branch name
78
- file_path: Path to file in repository
79
-
80
- Returns:
81
- Raw GitHub URL for the file
82
- """
83
- return f"https://raw.githubusercontent.com/{owner}/{repo}/{branch}/{file_path}"
84
-
85
-
86
- @tool
87
- def fetch_github_tool(
88
- github_url: str,
89
- tool_name: str | None = None,
90
- local_dir: str = "./github_tools",
91
- agent: Any = None,
92
- ) -> dict[str, Any]:
93
- """Fetch a Python tool file from GitHub and load it as a Strands tool.
94
-
95
- This tool downloads Python files from GitHub repositories, saves them locally,
96
- and registers them as available tools in the current Strands agent. It supports
97
- various GitHub URL formats and automatically handles the conversion to raw content URLs.
98
-
99
- Args:
100
- github_url: GitHub URL to the Python tool file. Supports formats like:
101
- - https://github.com/owner/repo/blob/main/tools/my_tool.py
102
- - https://github.com/owner/repo/tree/main/tools/my_tool.py
103
- - https://raw.githubusercontent.com/owner/repo/main/tools/my_tool.py
104
- tool_name: Name to register the tool under. If not provided, will extract
105
- from the filename (e.g., "my_tool.py" becomes "my_tool")
106
- local_dir: Local directory to save the fetched tool file. Defaults to "./github_tools"
107
- agent: Agent instance (automatically provided by Strands)
108
-
109
- Returns:
110
- Dict containing status and response content:
111
- {
112
- "status": "success|error",
113
- "content": [{"text": "Response message"}]
114
- }
115
-
116
- Examples:
117
- # Fetch a tool from GitHub and load it
118
- agent.tool.fetch_github_tool(
119
- github_url="https://github.com/cagataycali/my-tools/blob/main/weather_tool.py",
120
- tool_name="weather"
121
- )
122
-
123
- # Tool name can be auto-detected from filename
124
- agent.tool.fetch_github_tool(
125
- github_url="https://github.com/cagataycali/my-tools/blob/main/calculator.py"
126
- )
127
- """
128
- try:
129
- # Parse the GitHub URL
130
- try:
131
- url_info = parse_github_url(github_url)
132
- except ValueError as e:
133
- return {"status": "error", "content": [{"text": f"❌ {e!s}"}]}
134
-
135
- # Extract tool name from filename if not provided
136
- if not tool_name:
137
- filename = os.path.basename(url_info["file_path"])
138
- tool_name = os.path.splitext(filename)[0]
139
-
140
- # Check if it's a Python file first (before making HTTP request)
141
- if not url_info["file_path"].endswith(".py"):
142
- return {
143
- "status": "error",
144
- "content": [
145
- {
146
- "text": f"❌ File must be a Python file (.py), got: {url_info['file_path']}"
147
- }
148
- ],
149
- }
150
-
151
- # Build raw GitHub URL
152
- raw_url = build_raw_url(
153
- url_info["owner"],
154
- url_info["repo"],
155
- url_info["branch"],
156
- url_info["file_path"],
157
- )
158
-
159
- # Create local directory if it doesn't exist
160
- local_path = Path(local_dir)
161
- local_path.mkdir(parents=True, exist_ok=True)
162
-
163
- # Download the file
164
- response = requests.get(raw_url, timeout=30)
165
- response.raise_for_status()
166
- # Save the file locally
167
- local_file_path = local_path / f"{tool_name}.py"
168
- with open(local_file_path, "w", encoding="utf-8") as f:
169
- f.write(response.text)
170
-
171
- # Load the tool using load_tool functionality
172
- if agent and hasattr(agent, "tool_registry"):
173
- agent.tool_registry.load_tool_from_filepath(
174
- tool_name=tool_name, tool_path=str(local_file_path)
175
- )
176
-
177
- success_message = f"""✅ Successfully fetched and loaded GitHub tool!
178
-
179
- 📂 **Source:** {github_url}
180
- 🏷️ **Tool Name:** {tool_name}
181
- 💾 **Local Path:** {local_file_path}
182
- 🔧 **Status:** Ready to use
183
-
184
- You can now use the tool with: agent.tool.{tool_name}(...)"""
185
-
186
- return {"status": "success", "content": [{"text": success_message}]}
187
- else:
188
- return {
189
- "status": "error",
190
- "content": [
191
- {"text": "❌ Agent instance not available for tool registration"}
192
- ],
193
- }
194
-
195
- except requests.RequestException as e:
196
- return {
197
- "status": "error",
198
- "content": [{"text": f"❌ Failed to download file from GitHub: {e!s}"}],
199
- }
200
- except Exception as e:
201
- return {"status": "error", "content": [{"text": f"❌ Unexpected error: {e!s}"}]}