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:
parent
c000afc699
commit
c28c76e4b6
@ -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.
|
||||||
|
|||||||
7
Makefile
7
Makefile
@ -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
|
||||||
|
|||||||
@ -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
2
rp.py
@ -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()
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
2
rp/rp.py
2
rp/rp.py
@ -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()
|
||||||
|
|||||||
@ -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",
|
||||||
]
|
]
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user