22
33from __future__ import annotations
44
5+ import uuid
6+
57from sub_agent_mcp .agent .builder import build_agent , get_recursion_limit
68from sub_agent_mcp .agent .errors import AgentExecutionError , AgentNotFoundError
79from sub_agent_mcp .config .schema import AgentConfig , AgentsFile
8- from sub_agent_mcp .logging import get_logger
10+ from sub_agent_mcp .logging import agent_log_context , get_logger
911
1012logger = get_logger (__name__ )
1113
@@ -24,49 +26,58 @@ async def execute_agent(agent: AgentConfig, prompt: str) -> str:
2426 from langchain_core .messages import HumanMessage
2527 from openai import AuthenticationError , OpenAIError
2628
27- logger .info ("spawn_agent_start" , agent_id = agent .id )
28-
29- try :
30- runnable = await build_agent (agent )
31- result = await runnable .ainvoke (
32- {"messages" : [HumanMessage (content = prompt )]},
33- config = {"recursion_limit" : get_recursion_limit ()},
34- )
35- except AuthenticationError as exc :
36- logger .error ("agent_auth_failed" , agent_id = agent .id )
37- raise AgentExecutionError (
38- f"Invalid credentials for agent '{ agent .id } ' LLM provider"
39- ) from exc
40- except OpenAIError as exc :
41- logger .error ("agent_llm_error" , agent_id = agent .id , error = str (exc ))
42- raise AgentExecutionError (f"LLM error for agent '{ agent .id } ': { exc } " ) from exc
43- except Exception as exc :
44- if "401" in str (exc ) or "authentication" in str (exc ).lower ():
45- logger .error ("agent_auth_failed" , agent_id = agent .id )
29+ trace_id = str (uuid .uuid4 ())
30+
31+ with agent_log_context (
32+ trace_id = trace_id ,
33+ model_id = agent .llm .model_id ,
34+ agent_id = agent .id ,
35+ ):
36+ logger .info ("spawn_agent_start" )
37+ logger .info ("agent_input" , input = prompt )
38+
39+ try :
40+ runnable = await build_agent (agent )
41+ result = await runnable .ainvoke (
42+ {"messages" : [HumanMessage (content = prompt )]},
43+ config = {"recursion_limit" : get_recursion_limit ()},
44+ )
45+ except AuthenticationError as exc :
46+ logger .error ("agent_auth_failed" )
4647 raise AgentExecutionError (
4748 f"Invalid credentials for agent '{ agent .id } ' LLM provider"
4849 ) from exc
49- logger .error ("agent_execution_failed" , agent_id = agent .id , error = str (exc ))
50- raise AgentExecutionError (f"Agent execution failed for '{ agent .id } ': { exc } " ) from exc
51-
52- messages = result .get ("messages" , [])
53- if not messages :
54- raise AgentExecutionError (f"Agent '{ agent .id } ' returned no messages" )
55-
56- final_message = messages [- 1 ]
57- content = getattr (final_message , "content" , None )
58- if content is None :
59- raise AgentExecutionError (f"Agent '{ agent .id } ' returned empty content" )
60-
61- if isinstance (content , list ):
62- text_parts = [
63- part .get ("text" , "" )
64- for part in content
65- if isinstance (part , dict ) and part .get ("type" ) == "text"
66- ]
67- response = "\n " .join (part for part in text_parts if part )
68- else :
69- response = str (content )
70-
71- logger .info ("spawn_agent_complete" , agent_id = agent .id )
72- return response
50+ except OpenAIError as exc :
51+ logger .error ("agent_llm_error" , error = str (exc ))
52+ raise AgentExecutionError (f"LLM error for agent '{ agent .id } ': { exc } " ) from exc
53+ except Exception as exc :
54+ if "401" in str (exc ) or "authentication" in str (exc ).lower ():
55+ logger .error ("agent_auth_failed" )
56+ raise AgentExecutionError (
57+ f"Invalid credentials for agent '{ agent .id } ' LLM provider"
58+ ) from exc
59+ logger .error ("agent_execution_failed" , error = str (exc ))
60+ raise AgentExecutionError (f"Agent execution failed for '{ agent .id } ': { exc } " ) from exc
61+
62+ messages = result .get ("messages" , [])
63+ if not messages :
64+ raise AgentExecutionError (f"Agent '{ agent .id } ' returned no messages" )
65+
66+ final_message = messages [- 1 ]
67+ content = getattr (final_message , "content" , None )
68+ if content is None :
69+ raise AgentExecutionError (f"Agent '{ agent .id } ' returned empty content" )
70+
71+ if isinstance (content , list ):
72+ text_parts = [
73+ part .get ("text" , "" )
74+ for part in content
75+ if isinstance (part , dict ) and part .get ("type" ) == "text"
76+ ]
77+ response = "\n " .join (part for part in text_parts if part )
78+ else :
79+ response = str (content )
80+
81+ logger .info ("agent_output" , output = response )
82+ logger .info ("spawn_agent_complete" )
83+ return response
0 commit comments