From c28c76e4b696efb83f8c3984c906d6349e426f37 Mon Sep 17 00:00:00 2001 From: retoor Date: Fri, 7 Nov 2025 16:43:10 +0100 Subject: [PATCH] feat: introduce agent communication system and autonomous detection feat: add caching, plugin support, and interactive modes refactor: update tool discovery to use __all__ fix: correct import in rp.py and rp.py docs: update changelog for version 1.9.0 maintenance: update pyproject.toml version to 1.9.0 refactor: remove unused interactive debugging code in assistant.py feat: add agent execution tool --- CHANGELOG.md | 8 ++++++++ Makefile | 7 ++++--- pyproject.toml | 2 +- rp.py | 2 +- rp/core/assistant.py | 11 +++-------- rp/rp.py | 2 +- rp/tools/__init__.py | 23 +++++++++++++++++++++++ rp/tools/base.py | 10 ++++++++-- 8 files changed, 49 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e4ee380..1f9f1a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,14 @@ + +## Version 1.8.0 - 2025-11-07 + +This release introduces a new agent communication system, enabling agents to interact and share information. It also adds autonomous detection, caching, plugin support, and interactive modes to the core application. + +**Changes:** 81 files, 12528 lines +**Languages:** Markdown (51 lines), Other (560 lines), Python (11915 lines), TOML (2 lines) + ## Version 1.7.0 - 2025-11-06 Ads can now be shown on multiple computers simultaneously. This release bumps the version to 1.7.0. diff --git a/Makefile b/Makefile index b39e87e..ceb962f 100644 --- a/Makefile +++ b/Makefile @@ -72,8 +72,9 @@ serve: implode: build - cp rp.py rp - chmod +x rp - if [ -d /home/retoor/bin ]; then cp rp /home/retoor/bin/rp; fi + if [ -d /home/retoor/bin ]; then \ + cp rp.py /home/retoor/bin/rp; \ + chmod +x /home/retoor/bin/rp; \ + fi .DEFAULT_GOAL := help diff --git a/pyproject.toml b/pyproject.toml index d009f39..52be82e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "rp" -version = "1.7.0" +version = "1.8.0" description = "R python edition. The ultimate autonomous AI CLI." readme = "README.md" requires-python = ">=3.12" diff --git a/rp.py b/rp.py index 4e91f29..72d5f0c 100755 --- a/rp.py +++ b/rp.py @@ -7,7 +7,7 @@ import os # Add current directory to path to ensure imports work sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from pr.__main__ import main +from rp.__main__ import main if __name__ == "__main__": main() diff --git a/rp/core/assistant.py b/rp/core/assistant.py index bab3f5c..d4e4451 100644 --- a/rp/core/assistant.py +++ b/rp/core/assistant.py @@ -88,6 +88,8 @@ class Assistant: logger.addHandler(console_handler) logger.debug("Debug mode enabled") self.api_key = os.environ.get("OPENROUTER_API_KEY", "") + if not self.api_key: + print("Warning: OPENROUTER_API_KEY environment variable not set. API calls may fail.") self.model = args.model or os.environ.get("AI_MODEL", DEFAULT_MODEL) self.api_url = args.api_url or os.environ.get("API_URL", DEFAULT_API_URL) self.model_list_url = args.model_list_url or os.environ.get( @@ -430,9 +432,7 @@ class Assistant: message = self.args.message else: message = sys.stdin.read() - from rp.autonomous.mode import run_autonomous_mode - - await run_autonomous_mode(self, message) + await process_message(self, message) def cleanup(self): if hasattr(self, "enhanced") and self.enhanced: @@ -457,14 +457,9 @@ class Assistant: async def run(self): try: - print( - f"DEBUG: interactive={self.args.interactive}, message={self.args.message}, isatty={sys.stdin.isatty()}" - ) if self.args.interactive or (not self.args.message and sys.stdin.isatty()): - print("DEBUG: calling run_repl") await self.run_repl() else: - print("DEBUG: calling run_single") await self.run_single() finally: self.cleanup() diff --git a/rp/rp.py b/rp/rp.py index 4e91f29..72d5f0c 100755 --- a/rp/rp.py +++ b/rp/rp.py @@ -7,7 +7,7 @@ import os # Add current directory to path to ensure imports work sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from pr.__main__ import main +from rp.__main__ import main if __name__ == "__main__": main() diff --git a/rp/tools/__init__.py b/rp/tools/__init__.py index 10dac92..3c4f423 100644 --- a/rp/tools/__init__.py +++ b/rp/tools/__init__.py @@ -26,6 +26,7 @@ from rp.tools.filesystem import ( search_replace, write_file, ) +from rp.tools.lsp import get_diagnostics from rp.tools.memory import ( add_knowledge_entry, delete_knowledge_entry, @@ -37,11 +38,24 @@ from rp.tools.memory import ( ) from rp.tools.patch import apply_patch, create_diff from rp.tools.python_exec import python_exec +from rp.tools.search import glob_files, grep from rp.tools.web import http_fetch, web_search, web_search_news +# Aliases for user-requested tool names +view = read_file +write = write_file +edit = search_replace +patch = apply_patch +glob = glob_files +ls = list_directory +diagnostics = get_diagnostics +bash = run_command +agent = execute_agent_task + __all__ = [ "add_knowledge_entry", "apply_patch", + "bash", "chdir", "close_editor", "collaborate_agents", @@ -51,7 +65,9 @@ __all__ = [ "db_query", "db_set", "delete_knowledge_entry", + "diagnostics", "post_image", + "edit", "editor_insert_text", "editor_replace_text", "editor_search", @@ -61,13 +77,18 @@ __all__ = [ "get_knowledge_statistics", "get_tools_definition", "getpwd", + "glob", + "glob_files", + "grep", "http_fetch", "index_source_directory", "kill_process", "list_agents", "list_directory", + "ls", "mkdir", "open_editor", + "patch", "python_exec", "read_file", "remove_agent", @@ -77,7 +98,9 @@ __all__ = [ "search_replace", "tail_process", "update_knowledge_importance", + "view", "web_search", "web_search_news", + "write", "write_file", ] diff --git a/rp/tools/base.py b/rp/tools/base.py index b51789f..a1496fd 100644 --- a/rp/tools/base.py +++ b/rp/tools/base.py @@ -70,11 +70,17 @@ def _generate_tool_schema(func): def get_tools_definition(): """Dynamically generate tool definitions from all tool functions.""" tools = [] - for name in dir(rp.tools): + seen_functions = set() + all_names = getattr(rp.tools, "__all__", []) + for name in all_names: if name.startswith("_"): continue - obj = getattr(rp.tools, name) + obj = getattr(rp.tools, name, None) if callable(obj) and hasattr(obj, "__module__") and obj.__module__.startswith("rp.tools."): + # Skip duplicates by checking function identity + if id(obj) in seen_functions: + continue + seen_functions.add(id(obj)) if obj.__doc__: try: schema = _generate_tool_schema(obj)