feat: Add Gitea MCP integration and project cleanup
## New Features - **Gitea MCP Tools** (zero API cost): - gitea_read_file: Read files from homelab repo - gitea_list_files: Browse directories - gitea_search_code: Search by filename - gitea_get_tree: Get directory tree - **Gitea Client** (gitea_tools/client.py): REST API wrapper with OAuth - **Proxmox SSH Scripts** (scripts/): Homelab data collection utilities - **Obsidian MCP Support** (obsidian_mcp.py): Advanced vault operations - **Voice Integration Plan** (JARVIS_VOICE_INTEGRATION_PLAN.md) ## Improvements - **Increased timeout**: 5min → 10min for complex tasks (llm_interface.py) - **Removed Direct API fallback**: Gitea tools are MCP-only (zero cost) - **Updated .env.example**: Added Obsidian MCP configuration - **Enhanced .gitignore**: Protect personal memory files (SOUL.md, MEMORY.md) ## Cleanup - Deleted 24 obsolete files (temp/test/experimental scripts, outdated docs) - Untracked personal memory files (SOUL.md, MEMORY.md now in .gitignore) - Removed: AGENT_SDK_IMPLEMENTATION.md, HYBRID_SEARCH_SUMMARY.md, IMPLEMENTATION_SUMMARY.md, MIGRATION.md, test_agent_sdk.py, etc. ## Configuration - Added config/gitea_config.example.yaml (Gitea setup template) - Added config/obsidian_mcp.example.yaml (Obsidian MCP template) - Updated scheduled_tasks.yaml with new task examples Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -139,11 +139,37 @@ class AdapterRuntime:
|
||||
if adapter:
|
||||
await adapter.send_typing_indicator(message.channel_id)
|
||||
|
||||
# Capture the event loop for thread-safe progress updates
|
||||
event_loop = asyncio.get_running_loop()
|
||||
|
||||
# Create progress callback to send updates to the user
|
||||
def progress_callback(update_message: str):
|
||||
"""Send progress updates to the user during long operations."""
|
||||
if adapter:
|
||||
try:
|
||||
# Create outbound message for progress update
|
||||
progress_msg = OutboundMessage(
|
||||
platform=message.platform,
|
||||
channel_id=message.channel_id,
|
||||
text=update_message,
|
||||
thread_id=message.thread_id,
|
||||
)
|
||||
# Run async send in a thread-safe way
|
||||
# Use the captured event loop instead of get_running_loop()
|
||||
# since this callback runs from a thread (agent.chat via to_thread)
|
||||
asyncio.run_coroutine_threadsafe(
|
||||
adapter.send_message(progress_msg),
|
||||
event_loop
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"[Runtime] Failed to send progress update: {e}")
|
||||
|
||||
# Get response from agent (synchronous call in thread)
|
||||
response = await asyncio.to_thread(
|
||||
self.agent.chat,
|
||||
user_message=processed_message.text,
|
||||
username=username,
|
||||
progress_callback=progress_callback,
|
||||
)
|
||||
|
||||
# Apply postprocessors
|
||||
@@ -217,6 +243,14 @@ class AdapterRuntime:
|
||||
print("[Runtime] Starting adapter runtime...")
|
||||
await self.registry.start_all()
|
||||
|
||||
# Pass the main event loop to the LLM interface so that Agent SDK
|
||||
# async calls (from worker threads created by asyncio.to_thread)
|
||||
# can be scheduled back onto this loop via run_coroutine_threadsafe.
|
||||
loop = asyncio.get_running_loop()
|
||||
if hasattr(self.agent, 'llm') and hasattr(self.agent.llm, 'set_event_loop'):
|
||||
self.agent.llm.set_event_loop(loop)
|
||||
print("[Runtime] Event loop reference passed to LLM interface")
|
||||
|
||||
self._is_running = True
|
||||
self.message_loop_task = asyncio.create_task(
|
||||
self._process_message_queue()
|
||||
|
||||
Reference in New Issue
Block a user