Commit b5c29abf authored by Admin's avatar Admin

fix: sync/async boundary fixes, closure bug, missing deps, runtime imports

- Fix run_conversation sync/async boundary in 5 files:
  - run_agent.py main(): use _run_conversation_sync
  - batch_runner.py: use _run_conversation_sync
  - background_review.py: use _run_conversation_sync
  - curator.py: use _run_conversation_sync
  - acp_adapter/server.py: use _run_conversation_sync
- Fix classic Python closure late-binding bug in get_tools.py
  (is_async captured by reference, not value)
- Add missing deps to requirements.txt: openai, langchain-core, pyyaml, fire
- Fix missing HTTPException import in environment_config.py
- Fix missing List import in org_chart_svg.py
parent 78c8749c
...@@ -1453,7 +1453,7 @@ class HermesACPAgent(acp.Agent): ...@@ -1453,7 +1453,7 @@ class HermesACPAgent(acp.Agent):
previous_session_id = os.environ.get("HERMES_SESSION_ID") previous_session_id = os.environ.get("HERMES_SESSION_ID")
os.environ["HERMES_SESSION_ID"] = session_id os.environ["HERMES_SESSION_ID"] = session_id
try: try:
result = agent.run_conversation( result = agent._run_conversation_sync(
user_message=user_content, user_message=user_content,
conversation_history=state.history, conversation_history=state.history,
task_id=session_id, task_id=session_id,
......
...@@ -471,7 +471,7 @@ def _run_review_in_thread( ...@@ -471,7 +471,7 @@ def _run_review_in_thread(
), ),
) )
try: try:
review_agent.run_conversation( review_agent._run_conversation_sync(
user_message=( user_message=(
prompt prompt
+ "\n\nYou can only call memory and skill " + "\n\nYou can only call memory and skill "
......
...@@ -1717,7 +1717,7 @@ def _run_llm_review(prompt: str) -> Dict[str, Any]: ...@@ -1717,7 +1717,7 @@ def _run_llm_review(prompt: str) -> Dict[str, Any]:
with open(os.devnull, "w", encoding="utf-8") as _devnull, \ with open(os.devnull, "w", encoding="utf-8") as _devnull, \
contextlib.redirect_stdout(_devnull), \ contextlib.redirect_stdout(_devnull), \
contextlib.redirect_stderr(_devnull): contextlib.redirect_stderr(_devnull):
conv_result = review_agent.run_conversation(user_message=prompt) conv_result = review_agent._run_conversation_sync(user_message=prompt)
final = "" final = ""
if isinstance(conv_result, dict): if isinstance(conv_result, dict):
......
...@@ -346,7 +346,7 @@ def _process_single_prompt( ...@@ -346,7 +346,7 @@ def _process_single_prompt(
) )
# Run the agent with task_id to ensure each task gets its own isolated VM # Run the agent with task_id to ensure each task gets its own isolated VM
result = agent.run_conversation(prompt, task_id=task_id) result = agent._run_conversation_sync(prompt, task_id=task_id)
# Extract tool usage statistics # Extract tool usage statistics
tool_stats = _extract_tool_stats(result["messages"]) tool_stats = _extract_tool_stats(result["messages"])
......
...@@ -4398,7 +4398,7 @@ def main( ...@@ -4398,7 +4398,7 @@ def main(
print("\n" + "=" * 50) print("\n" + "=" * 50)
# Run conversation # Run conversation
result = agent.run_conversation(user_query) result = agent._run_conversation_sync(user_query)
print("\n" + "=" * 50) print("\n" + "=" * 50)
print("📋 CONVERSATION SUMMARY") print("📋 CONVERSATION SUMMARY")
......
...@@ -55,11 +55,11 @@ def register_company_tools(company_id: str | None = None) -> None: ...@@ -55,11 +55,11 @@ def register_company_tools(company_id: str | None = None) -> None:
logger.error(f"Error converting tool {tool.name} schema: {e}", exc_info=True) logger.error(f"Error converting tool {tool.name} schema: {e}", exc_info=True)
continue continue
# Define handler # Detect async — passed into make_handler as default param to capture per-iteration value
is_async = inspect.iscoroutinefunction(tool._run) or inspect.iscoroutinefunction(tool.ainvoke) tool_is_async = inspect.iscoroutinefunction(getattr(tool, '_run', None)) or inspect.iscoroutinefunction(getattr(tool, 'ainvoke', None))
def make_handler(t): def make_handler(t, _is_async=tool_is_async):
if is_async: if _is_async:
async def async_handler(args, **kwargs): async def async_handler(args, **kwargs):
return await t.ainvoke(args) return await t.ainvoke(args)
return async_handler return async_handler
...@@ -76,11 +76,11 @@ def register_company_tools(company_id: str | None = None) -> None: ...@@ -76,11 +76,11 @@ def register_company_tools(company_id: str | None = None) -> None:
toolset="company_tools", toolset="company_tools",
schema=schema, schema=schema,
handler=handler, handler=handler,
is_async=is_async, is_async=tool_is_async,
description=tool.description, description=tool.description,
override=True override=True
) )
logger.info(f"Registered company tool '{tool.name}' (async={is_async}) in Hermes registry") logger.info(f"Registered company tool '{tool.name}' (async={tool_is_async}) in Hermes registry")
except Exception as e: except Exception as e:
logger.error(f"Error registering company tool {tool.name} in Hermes registry: {e}", exc_info=True) logger.error(f"Error registering company tool {tool.name} in Hermes registry: {e}", exc_info=True)
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
Environment config routes. Environment config routes.
""" """
from fastapi import APIRouter, Depends, Query, status, Body from fastapi import APIRouter, Depends, HTTPException, Query, status, Body
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select from sqlalchemy import select
import json import json
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
Org chart SVG routes. Org chart SVG routes.
""" """
from typing import Optional from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, Query, Response, status from fastapi import APIRouter, Depends, HTTPException, Query, Response, status
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select from sqlalchemy import select
......
...@@ -10,6 +10,12 @@ passlib[bcrypt]==1.7.4 ...@@ -10,6 +10,12 @@ passlib[bcrypt]==1.7.4
httpx==0.27.0 httpx==0.27.0
structlog==24.1.0 structlog==24.1.0
python-dotenv==1.0.1 python-dotenv==1.0.1
# Agent core dependencies
openai>=1.30.0
langchain-core>=0.2.0
pyyaml>=6.0
fire>=0.5.0
# Testing
pytest==8.1.1 pytest==8.1.1
pytest-asyncio==0.23.5 pytest-asyncio==0.23.5
pytest-cov==4.1.0 pytest-cov==4.1.0
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment