fix(agent): unify logging API + add molecular-cot coverage to agent module
Phase 1 — API unification: - Replace direct log() from cot_logger with canonical logger.reason/reflect/explore across _confirmation.py, _persistence.py, _tool_resolver.py, app.py Phase 2 — Gap filling: - tools.py: add REASON/REFLECT/EXPLORE to 17 C3 tool functions (was 0 logs) - app.py agent_handler (C4): add lifecycle REASON on entry, REFLECT on exit, EXPLORE on OutputParserException + general exception - langgraph_setup.py create_agent (C4): add REASON with model/config_source, EXPLORE on env-var/InMemorySaver fallback, REFLECT on graph compilation - _tool_resolver.py infer_tool_from_text (C3, 13 branches): REASON on inference - _persistence.py: REFLECT on save_conversation success, EXPLORE on prefetch Phase 3 — Plain log migration: - middleware.py: plain logger.info() -> logger.reason() - run.py: 7 plain logger.info/warning/error -> molecular REASON/EXPLORE Phase 4 — Cleanup: - cot_logger.py: deprecate MarkerLogger (@DEPRECATED + @REPLACED_BY) - molecular-cot-logging SKILL.md: remove cot_span Section IV (never implemented), renumber sections V-VII -> IV-VI, add cot_span rejection rationale Verification: pytest 27/27, axiom rebuild 5844/2993/0 warnings
This commit is contained in:
@@ -15,7 +15,7 @@ from typing import Any
|
||||
|
||||
import httpx
|
||||
|
||||
from src.core.cot_logger import log
|
||||
from src.core.logger import logger
|
||||
|
||||
SAVE_API_URL = os.getenv("FASTAPI_URL", "http://localhost:8000") + "/api/agent/conversations/save"
|
||||
TITLE_MAX_LENGTH = 80
|
||||
@@ -170,13 +170,13 @@ def _get_llm_config() -> dict[str, Any] | None:
|
||||
|
||||
async def _call_llm_for_title(user_text: str) -> str | None:
|
||||
"""Call LLM to generate a 3-5 word Russian title. Returns title or None on failure."""
|
||||
from src.core.cot_logger import log as _log
|
||||
from src.core.logger import logger as _logger
|
||||
|
||||
try:
|
||||
import asyncio as _asyncio
|
||||
config = await _asyncio.to_thread(_get_llm_config)
|
||||
if not config or not config.get("configured"):
|
||||
_log("AgentChat.Persistence", "EXPLORE", "LLM title: no provider configured", {})
|
||||
_logger.explore("LLM title: no provider configured", extra={"src": "AgentChat.Persistence"})
|
||||
return None
|
||||
|
||||
clean_text = clean_title(user_text)[:200]
|
||||
@@ -211,8 +211,11 @@ async def _call_llm_for_title(user_text: str) -> str | None:
|
||||
async with httpx.AsyncClient(timeout=10) as client:
|
||||
resp = await client.post(api_url, json=payload, headers=headers)
|
||||
if resp.status_code != 200:
|
||||
_log("AgentChat.Persistence", "EXPLORE", "LLM title: API error",
|
||||
{"status": resp.status_code}, error=resp.text[:200])
|
||||
_logger.explore(
|
||||
"LLM title: API error",
|
||||
payload={"status": resp.status_code}, error=resp.text[:200],
|
||||
extra={"src": "AgentChat.Persistence"},
|
||||
)
|
||||
return None
|
||||
data = resp.json()
|
||||
title = data.get("choices", [{}])[0].get("message", {}).get("content", "")
|
||||
@@ -223,7 +226,7 @@ async def _call_llm_for_title(user_text: str) -> str | None:
|
||||
if title:
|
||||
return title
|
||||
except Exception as e:
|
||||
_log("AgentChat.Persistence", "EXPLORE", "LLM title generation failed", {}, error=str(e))
|
||||
_logger.explore("LLM title generation failed", error=str(e), extra={"src": "AgentChat.Persistence"})
|
||||
return None
|
||||
|
||||
|
||||
@@ -263,11 +266,17 @@ async def generate_llm_title(conv_id: str, user_text: str) -> None:
|
||||
}
|
||||
async with httpx.AsyncClient(timeout=5) as client:
|
||||
await client.post(SAVE_API_URL, json=payload, headers=headers)
|
||||
log("AgentChat.Persistence", "REFLECT", "LLM title updated",
|
||||
{"conv_id": conv_id, "title": title[:40]})
|
||||
logger.reflect(
|
||||
"LLM title updated",
|
||||
payload={"conv_id": conv_id, "title": title[:40]},
|
||||
extra={"src": "AgentChat.Persistence"},
|
||||
)
|
||||
except Exception as e:
|
||||
log("AgentChat.Persistence", "EXPLORE", "LLM title save failed",
|
||||
{"conv_id": conv_id}, error=str(e))
|
||||
logger.explore(
|
||||
"LLM title save failed",
|
||||
payload={"conv_id": conv_id}, error=str(e),
|
||||
extra={"src": "AgentChat.Persistence"},
|
||||
)
|
||||
finally:
|
||||
_title_locks.pop(conv_id, None)
|
||||
# #endregion AgentChat.Persistence.GenerateLlmTitle
|
||||
@@ -314,7 +323,12 @@ async def prefetch_dashboards(env_id: str) -> str:
|
||||
if total > limit:
|
||||
suffix = f"\n... {total - limit} more dashboards omitted. Ask for a narrower search if needed."
|
||||
return f"Available dashboards in environment '{env_id or 'default'}' ({total} total):\n" + "\n".join(lines) + suffix
|
||||
except Exception:
|
||||
except Exception as e:
|
||||
logger.explore(
|
||||
"Prefetch dashboards failed",
|
||||
payload={"env_id": env_id}, error=str(e),
|
||||
extra={"src": "AgentChat.Persistence.PrefetchDashboards"},
|
||||
)
|
||||
return ""
|
||||
# #endregion AgentChat.Persistence.PrefetchDashboards
|
||||
|
||||
@@ -369,8 +383,16 @@ async def save_conversation(conv_id: str, user_text: str, user_id: str = "admin"
|
||||
|
||||
async with httpx.AsyncClient(timeout=10) as client:
|
||||
await client.post(SAVE_API_URL, json=payload, headers=headers)
|
||||
logger.reflect(
|
||||
"Conversation saved",
|
||||
payload={"conv_id": conv_id, "msg_count": len(messages), "title": title[:40]},
|
||||
extra={"src": "AgentChat.Persistence.SaveConversation"},
|
||||
)
|
||||
except Exception as e:
|
||||
log("AgentChat.Persistence", "EXPLORE", "Failed to save conversation",
|
||||
{"conv_id": conv_id}, error=str(e))
|
||||
logger.explore(
|
||||
"Failed to save conversation",
|
||||
payload={"conv_id": conv_id}, error=str(e),
|
||||
extra={"src": "AgentChat.Persistence"},
|
||||
)
|
||||
# #endregion AgentChat.Persistence.SaveConversation
|
||||
# #endregion AgentChat.Persistence
|
||||
|
||||
Reference in New Issue
Block a user