devduck 1.2.0__tar.gz → 1.3.0__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 (54) hide show
  1. {devduck-1.2.0 → devduck-1.3.0}/PKG-INFO +2 -1
  2. {devduck-1.2.0 → devduck-1.3.0}/devduck/__init__.py +83 -6
  3. {devduck-1.2.0 → devduck-1.3.0}/devduck/_version.py +3 -3
  4. {devduck-1.2.0 → devduck-1.3.0}/devduck/agentcore_handler.py +1 -0
  5. {devduck-1.2.0 → devduck-1.3.0}/devduck/tools/__init__.py +2 -2
  6. devduck-1.3.0/devduck/tools/zenoh_peer.py +1163 -0
  7. {devduck-1.2.0 → devduck-1.3.0}/devduck.egg-info/PKG-INFO +2 -1
  8. {devduck-1.2.0 → devduck-1.3.0}/devduck.egg-info/SOURCES.txt +1 -0
  9. {devduck-1.2.0 → devduck-1.3.0}/devduck.egg-info/requires.txt +1 -0
  10. {devduck-1.2.0 → devduck-1.3.0}/pyproject.toml +1 -0
  11. {devduck-1.2.0 → devduck-1.3.0}/.github/workflows/agent.yml +0 -0
  12. {devduck-1.2.0 → devduck-1.3.0}/.github/workflows/auto-release.yml +0 -0
  13. {devduck-1.2.0 → devduck-1.3.0}/.gitignore +0 -0
  14. {devduck-1.2.0 → devduck-1.3.0}/LICENSE +0 -0
  15. {devduck-1.2.0 → devduck-1.3.0}/MANIFEST.in +0 -0
  16. {devduck-1.2.0 → devduck-1.3.0}/README.md +0 -0
  17. {devduck-1.2.0 → devduck-1.3.0}/action.yml +0 -0
  18. {devduck-1.2.0 → devduck-1.3.0}/agent_runner.py +0 -0
  19. {devduck-1.2.0 → devduck-1.3.0}/devduck/__main__.py +0 -0
  20. {devduck-1.2.0 → devduck-1.3.0}/devduck/test_redduck.py +0 -0
  21. {devduck-1.2.0 → devduck-1.3.0}/devduck/tools/_ambient_input.py +0 -0
  22. {devduck-1.2.0 → devduck-1.3.0}/devduck/tools/_tray_app.py +0 -0
  23. {devduck-1.2.0 → devduck-1.3.0}/devduck/tools/agentcore_agents.py +0 -0
  24. {devduck-1.2.0 → devduck-1.3.0}/devduck/tools/agentcore_config.py +0 -0
  25. {devduck-1.2.0 → devduck-1.3.0}/devduck/tools/agentcore_invoke.py +0 -0
  26. {devduck-1.2.0 → devduck-1.3.0}/devduck/tools/agentcore_logs.py +0 -0
  27. {devduck-1.2.0 → devduck-1.3.0}/devduck/tools/ambient.py +0 -0
  28. {devduck-1.2.0 → devduck-1.3.0}/devduck/tools/create_subagent.py +0 -0
  29. {devduck-1.2.0 → devduck-1.3.0}/devduck/tools/fetch_github_tool.py +0 -0
  30. {devduck-1.2.0 → devduck-1.3.0}/devduck/tools/install_tools.py +0 -0
  31. {devduck-1.2.0 → devduck-1.3.0}/devduck/tools/ipc.py +0 -0
  32. {devduck-1.2.0 → devduck-1.3.0}/devduck/tools/mcp_server.py +0 -0
  33. {devduck-1.2.0 → devduck-1.3.0}/devduck/tools/scraper.py +0 -0
  34. {devduck-1.2.0 → devduck-1.3.0}/devduck/tools/speech_to_speech.py +0 -0
  35. {devduck-1.2.0 → devduck-1.3.0}/devduck/tools/state_manager.py +0 -0
  36. {devduck-1.2.0 → devduck-1.3.0}/devduck/tools/store_in_kb.py +0 -0
  37. {devduck-1.2.0 → devduck-1.3.0}/devduck/tools/system_prompt.py +0 -0
  38. {devduck-1.2.0 → devduck-1.3.0}/devduck/tools/tcp.py +0 -0
  39. {devduck-1.2.0 → devduck-1.3.0}/devduck/tools/tray.py +0 -0
  40. {devduck-1.2.0 → devduck-1.3.0}/devduck/tools/use_github.py +0 -0
  41. {devduck-1.2.0 → devduck-1.3.0}/devduck/tools/websocket.py +0 -0
  42. {devduck-1.2.0 → devduck-1.3.0}/devduck.egg-info/dependency_links.txt +0 -0
  43. {devduck-1.2.0 → devduck-1.3.0}/devduck.egg-info/entry_points.txt +0 -0
  44. {devduck-1.2.0 → devduck-1.3.0}/devduck.egg-info/top_level.txt +0 -0
  45. {devduck-1.2.0 → devduck-1.3.0}/docs/index.html +0 -0
  46. {devduck-1.2.0 → devduck-1.3.0}/docs/mac-os-tray.jpg +0 -0
  47. {devduck-1.2.0 → devduck-1.3.0}/requirements.txt +0 -0
  48. {devduck-1.2.0 → devduck-1.3.0}/setup-aws-oidc.sh +0 -0
  49. {devduck-1.2.0 → devduck-1.3.0}/setup.cfg +0 -0
  50. {devduck-1.2.0 → devduck-1.3.0}/test.py +0 -0
  51. {devduck-1.2.0 → devduck-1.3.0}/tools/__init__.py +0 -0
  52. {devduck-1.2.0 → devduck-1.3.0}/tools/fetch_github_tool.py +0 -0
  53. {devduck-1.2.0 → devduck-1.3.0}/tools/gist.py +0 -0
  54. {devduck-1.2.0 → devduck-1.3.0}/tools/github_tools.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devduck
3
- Version: 1.2.0
3
+ Version: 1.3.0
4
4
  Summary: 🦆 Self-adapting agent - one file.
5
5
  Author-email: Cagatay Cali <cagataycali@icloud.com>
6
6
  License: Apache-2.0
@@ -42,6 +42,7 @@ Requires-Dist: bedrock-agentcore-starter-toolkit
42
42
  Requires-Dist: bedrock-agentcore
43
43
  Requires-Dist: rumps; sys_platform == "darwin"
44
44
  Requires-Dist: strands-mlx; sys_platform == "darwin"
45
+ Requires-Dist: eclipse-zenoh
45
46
  Provides-Extra: speech
46
47
  Requires-Dist: strands-agents[bidi-all]; extra == "speech"
47
48
  Dynamic: license-file
@@ -3,6 +3,7 @@
3
3
  🦆 devduck - extreme minimalist self-adapting agent
4
4
  one file. self-healing. runtime dependencies. adaptive.
5
5
  """
6
+
6
7
  import os
7
8
  import sys
8
9
  import subprocess
@@ -457,6 +458,47 @@ def parse_history_line(line, history_type):
457
458
  return None
458
459
 
459
460
 
461
+ def get_zenoh_peers_context():
462
+ """Get current zenoh peers for dynamic context injection."""
463
+ try:
464
+ from devduck.tools.zenoh_peer import ZENOH_STATE
465
+ import time
466
+
467
+ logger.debug(
468
+ f"Zenoh context check - running: {ZENOH_STATE.get('running')}, peers: {ZENOH_STATE.get('peers')}"
469
+ )
470
+
471
+ if not ZENOH_STATE.get("running"):
472
+ logger.debug("Zenoh not running, returning empty context")
473
+ return ""
474
+
475
+ instance_id = ZENOH_STATE.get("instance_id", "unknown")
476
+ peers = ZENOH_STATE.get("peers", {})
477
+
478
+ context = f"\n\n## Zenoh Network Status:\n"
479
+ context += f"- **My Instance ID**: {instance_id}\n"
480
+ context += f"- **Connected Peers**: {len(peers)}\n"
481
+
482
+ if peers:
483
+ context += "\n### Active Peers:\n"
484
+ for peer_id, info in peers.items():
485
+ age = time.time() - info.get("last_seen", 0)
486
+ hostname = info.get("hostname", "unknown")
487
+ model = info.get("model", "unknown")
488
+ context += f"- `{peer_id}` ({hostname}) - model: {model}, seen {age:.0f}s ago\n"
489
+ context += "\n**Use**: `zenoh_peer(action='broadcast', message='...')` to send to all, or `zenoh_peer(action='send', peer_id='...', message='...')` for specific peer\n"
490
+ else:
491
+ context += "\n*No peers discovered yet. Start another DevDuck instance with zenoh enabled.*\n"
492
+
493
+ return context
494
+ except ImportError as e:
495
+ logger.debug(f"Zenoh context ImportError: {e}")
496
+ return ""
497
+ except Exception as e:
498
+ logger.debug(f"Could not get zenoh peers context: {e}")
499
+ return ""
500
+
501
+
460
502
  def get_recent_logs():
461
503
  """Get the last N lines from the log file for context."""
462
504
  try:
@@ -626,6 +668,10 @@ class DevDuck:
626
668
  "enabled": os.getenv("DEVDUCK_ENABLE_IPC", "false").lower()
627
669
  == "true",
628
670
  },
671
+ "zenoh_peer": {
672
+ "enabled": os.getenv("DEVDUCK_ENABLE_ZENOH", "true").lower()
673
+ == "true",
674
+ },
629
675
  }
630
676
 
631
677
  # Show server configuration status
@@ -672,6 +718,7 @@ class DevDuck:
672
718
  # - use_github: https://github.com/cagataycali/devduck/blob/main/devduck/tools/use_github.py
673
719
  # - speech_to_speech: https://github.com/cagataycali/devduck/blob/main/devduck/tools/speech_to_speech.py
674
720
  # - state_manager: https://github.com/cagataycali/devduck/blob/main/devduck/tools/state_manager.py
721
+ # - zenoh_peer: https://github.com/cagataycali/devduck/blob/main/devduck/tools/zenoh_peer.py
675
722
 
676
723
  # 📦 Strands Tools
677
724
  # - editor, file_read, file_write, image_reader, load_tool, retrieve
@@ -691,6 +738,8 @@ class DevDuck:
691
738
  server_tools_needed.append("mcp_server")
692
739
  if servers.get("ipc", {}).get("enabled", False):
693
740
  server_tools_needed.append("ipc")
741
+ if servers.get("zenoh_peer", {}).get("enabled", False):
742
+ server_tools_needed.append("zenoh_peer")
694
743
 
695
744
  # Append to default tools if any server tools are needed
696
745
  if server_tools_needed:
@@ -698,9 +747,7 @@ class DevDuck:
698
747
  default_tools = f"devduck.tools:system_prompt,fetch_github_tool,websocket,{server_tools_str};strands_tools:shell"
699
748
  logger.info(f"Auto-added server tools: {server_tools_str}")
700
749
  else:
701
- default_tools = (
702
- "devduck.tools:system_prompt,fetch_github_tool,websocket;strands_tools:shell"
703
- )
750
+ default_tools = "devduck.tools:system_prompt,fetch_github_tool,websocket;strands_tools:shell"
704
751
 
705
752
  tools_config = os.getenv("DEVDUCK_TOOLS", default_tools)
706
753
  logger.info(f"Loading tools from config: {tools_config}")
@@ -1312,8 +1359,8 @@ When you learn something valuable during conversations:
1312
1359
  logger.info("Auto-starting servers...")
1313
1360
  print("🦆 Auto-starting servers...")
1314
1361
 
1315
- # Start servers in order: IPC, TCP, WS, MCP
1316
- server_order = ["ipc", "tcp", "ws", "mcp"]
1362
+ # Start servers in order: IPC, TCP, WS, MCP, Zenoh
1363
+ server_order = ["ipc", "tcp", "ws", "mcp", "zenoh_peer"]
1317
1364
 
1318
1365
  for server_type in server_order:
1319
1366
  if server_type not in self.servers:
@@ -1436,6 +1483,26 @@ When you learn something valuable during conversations:
1436
1483
  if result.get("status") == "success":
1437
1484
  logger.info(f"✓ IPC server started on {socket_path}")
1438
1485
  print(f"🦆 ✓ IPC server: {socket_path}")
1486
+
1487
+ elif server_type == "zenoh_peer":
1488
+ # Zenoh peer-to-peer networking with auto-discovery
1489
+ result = self.agent.tool.zenoh_peer(
1490
+ action="start",
1491
+ agent=self.agent,
1492
+ record_direct_tool_call=False,
1493
+ )
1494
+
1495
+ if result.get("status") == "success":
1496
+ # Extract instance ID from result
1497
+ instance_id = "unknown"
1498
+ for content in result.get("content", []):
1499
+ text = content.get("text", "")
1500
+ if "Instance ID:" in text:
1501
+ instance_id = text.split("Instance ID:")[-1].strip()
1502
+ break
1503
+ logger.info(f"✓ Zenoh started as {instance_id}")
1504
+ print(f"🦆 ✓ Zenoh peer: {instance_id}")
1505
+
1439
1506
  # TODO: support custom file path here so we can trigger foreign python function like another file
1440
1507
  except Exception as e:
1441
1508
  logger.error(f"Failed to start {server_type} server: {e}")
@@ -1465,8 +1532,18 @@ When you learn something valuable during conversations:
1465
1532
  except Exception as e:
1466
1533
  logger.warning(f"KB retrieval failed: {e}")
1467
1534
 
1535
+ # 🔗 Inject dynamic zenoh peers context
1536
+ zenoh_context = get_zenoh_peers_context()
1537
+ if zenoh_context:
1538
+ # Prepend dynamic context to query for visibility
1539
+ query_with_context = (
1540
+ f"[Dynamic Context]{zenoh_context}\n\n[User Query]\n{query}"
1541
+ )
1542
+ else:
1543
+ query_with_context = query
1544
+
1468
1545
  # Run the agent
1469
- result = self.agent(query)
1546
+ result = self.agent(query_with_context)
1470
1547
 
1471
1548
  # 💾 Knowledge Base Storage (AFTER agent runs)
1472
1549
  if knowledge_base_id and hasattr(self.agent, "tool"):
@@ -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 = '1.2.0'
32
- __version_tuple__ = version_tuple = (1, 2, 0)
31
+ __version__ = version = '1.3.0'
32
+ __version_tuple__ = version_tuple = (1, 3, 0)
33
33
 
34
- __commit_id__ = commit_id = 'gb45b2cfc7'
34
+ __commit_id__ = commit_id = 'gd5f54385b'
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env python3
2
2
  """DevDuck AgentCore Handler"""
3
+
3
4
  import json
4
5
  import os
5
6
  import threading
@@ -22,6 +22,7 @@ from .tcp import tcp
22
22
  from .tray import tray
23
23
  from .use_github import use_github
24
24
  from .websocket import websocket
25
+ from .zenoh_peer import zenoh_peer
25
26
 
26
27
  # Optional Tools
27
28
  try:
@@ -47,6 +48,7 @@ try:
47
48
  "tray",
48
49
  "use_github",
49
50
  "websocket",
51
+ "zenoh_peer",
50
52
  ]
51
53
  except ImportError:
52
54
  __all__ = [
@@ -69,5 +71,3 @@ except ImportError:
69
71
  "use_github",
70
72
  "websocket",
71
73
  ]
72
-
73
-