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
This commit is contained in:
retoor 2025-11-07 16:43:10 +01:00
parent c000afc699
commit c28c76e4b6
8 changed files with 49 additions and 16 deletions

View File

@ -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 ## 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. Ads can now be shown on multiple computers simultaneously. This release bumps the version to 1.7.0.

View File

@ -72,8 +72,9 @@ serve:
implode: build implode: build
cp rp.py rp if [ -d /home/retoor/bin ]; then \
chmod +x rp cp rp.py /home/retoor/bin/rp; \
if [ -d /home/retoor/bin ]; then cp rp /home/retoor/bin/rp; fi chmod +x /home/retoor/bin/rp; \
fi
.DEFAULT_GOAL := help .DEFAULT_GOAL := help

View File

@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project] [project]
name = "rp" name = "rp"
version = "1.7.0" version = "1.8.0"
description = "R python edition. The ultimate autonomous AI CLI." description = "R python edition. The ultimate autonomous AI CLI."
readme = "README.md" readme = "README.md"
requires-python = ">=3.12" requires-python = ">=3.12"

2
rp.py
View File

@ -7,7 +7,7 @@ import os
# Add current directory to path to ensure imports work # Add current directory to path to ensure imports work
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from pr.__main__ import main from rp.__main__ import main
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@ -88,6 +88,8 @@ class Assistant:
logger.addHandler(console_handler) logger.addHandler(console_handler)
logger.debug("Debug mode enabled") logger.debug("Debug mode enabled")
self.api_key = os.environ.get("OPENROUTER_API_KEY", "") 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.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.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( self.model_list_url = args.model_list_url or os.environ.get(
@ -430,9 +432,7 @@ class Assistant:
message = self.args.message message = self.args.message
else: else:
message = sys.stdin.read() message = sys.stdin.read()
from rp.autonomous.mode import run_autonomous_mode await process_message(self, message)
await run_autonomous_mode(self, message)
def cleanup(self): def cleanup(self):
if hasattr(self, "enhanced") and self.enhanced: if hasattr(self, "enhanced") and self.enhanced:
@ -457,14 +457,9 @@ class Assistant:
async def run(self): async def run(self):
try: 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()): if self.args.interactive or (not self.args.message and sys.stdin.isatty()):
print("DEBUG: calling run_repl")
await self.run_repl() await self.run_repl()
else: else:
print("DEBUG: calling run_single")
await self.run_single() await self.run_single()
finally: finally:
self.cleanup() self.cleanup()

View File

@ -7,7 +7,7 @@ import os
# Add current directory to path to ensure imports work # Add current directory to path to ensure imports work
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from pr.__main__ import main from rp.__main__ import main
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@ -26,6 +26,7 @@ from rp.tools.filesystem import (
search_replace, search_replace,
write_file, write_file,
) )
from rp.tools.lsp import get_diagnostics
from rp.tools.memory import ( from rp.tools.memory import (
add_knowledge_entry, add_knowledge_entry,
delete_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.patch import apply_patch, create_diff
from rp.tools.python_exec import python_exec 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 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__ = [ __all__ = [
"add_knowledge_entry", "add_knowledge_entry",
"apply_patch", "apply_patch",
"bash",
"chdir", "chdir",
"close_editor", "close_editor",
"collaborate_agents", "collaborate_agents",
@ -51,7 +65,9 @@ __all__ = [
"db_query", "db_query",
"db_set", "db_set",
"delete_knowledge_entry", "delete_knowledge_entry",
"diagnostics",
"post_image", "post_image",
"edit",
"editor_insert_text", "editor_insert_text",
"editor_replace_text", "editor_replace_text",
"editor_search", "editor_search",
@ -61,13 +77,18 @@ __all__ = [
"get_knowledge_statistics", "get_knowledge_statistics",
"get_tools_definition", "get_tools_definition",
"getpwd", "getpwd",
"glob",
"glob_files",
"grep",
"http_fetch", "http_fetch",
"index_source_directory", "index_source_directory",
"kill_process", "kill_process",
"list_agents", "list_agents",
"list_directory", "list_directory",
"ls",
"mkdir", "mkdir",
"open_editor", "open_editor",
"patch",
"python_exec", "python_exec",
"read_file", "read_file",
"remove_agent", "remove_agent",
@ -77,7 +98,9 @@ __all__ = [
"search_replace", "search_replace",
"tail_process", "tail_process",
"update_knowledge_importance", "update_knowledge_importance",
"view",
"web_search", "web_search",
"web_search_news", "web_search_news",
"write",
"write_file", "write_file",
] ]

View File

@ -70,11 +70,17 @@ def _generate_tool_schema(func):
def get_tools_definition(): def get_tools_definition():
"""Dynamically generate tool definitions from all tool functions.""" """Dynamically generate tool definitions from all tool functions."""
tools = [] tools = []
for name in dir(rp.tools): seen_functions = set()
all_names = getattr(rp.tools, "__all__", [])
for name in all_names:
if name.startswith("_"): if name.startswith("_"):
continue 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."): 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__: if obj.__doc__:
try: try:
schema = _generate_tool_schema(obj) schema = _generate_tool_schema(obj)