Problem
Managed agents emit no trace events. The langextract + langfuse bridges landed in #1420 listen to ContextTraceEmitter (agent_start / tool_call_* / llm_response / agent_end), but both AnthropicManagedAgent._execute_sync (src/praisonai/praisonai/integrations/managed_agents.py:377-406) and LocalManagedAgent._execute_sync (src/praisonai/praisonai/integrations/managed_local.py:548-577) bypass this pipeline entirely. Consequence: a run with praisonai --observe langextract managed run "β¦" produces an empty HTML.
Acceptance criteria
Implementation plan
- In both
_execute_sync methods: emitter = get_context_emitter() at the top (cheap), then emitter.agent_start(self._cfg.get("name","Agent"), {"input": prompt, "goal": ...}) before sending the user message; matching emitter.agent_end(...) in finally:.
- In
_process_events of AnthropicManagedAgent: on agent.tool_use call emitter.tool_call_start(agent_name, tool_name, input); no direct "end" event from Anthropic, so emit tool_call_end synthetically right after (or on the next event) with duration_ms from a local timer.
- On
agent.message aggregated text: call emitter.llm_response(agent_name, response_content=joined_text) once per turn.
- For
LocalManagedAgent, the inner Agent.chat() already emits context events via chat_mixin; still add managed-level agent_start/end to mark the boundary.
- No core changes needed β all emission happens from the wrapper.
Files
Modify:
src/praisonai/praisonai/integrations/managed_agents.py β _execute_sync, _process_events.
src/praisonai/praisonai/integrations/managed_local.py β _execute_sync.
Tests:
src/praisonai-agents/tests/managed/test_managed_trace_events.py (new) β uses ContextListSink + trace_context.
Invariants
- Protocol-driven core untouched.
- No new deps; emission is opt-in via
get_context_emitter().
- Backward-compatible.
References
cc @claude β per .windsurf/workflows/e2e-analysis-issue-pr-merge.md.
Problem
Managed agents emit no trace events. The langextract + langfuse bridges landed in #1420 listen to
ContextTraceEmitter(agent_start / tool_call_* / llm_response / agent_end), but bothAnthropicManagedAgent._execute_sync(src/praisonai/praisonai/integrations/managed_agents.py:377-406) andLocalManagedAgent._execute_sync(src/praisonai/praisonai/integrations/managed_local.py:548-577) bypass this pipeline entirely. Consequence: a run withpraisonai --observe langextract managed run "β¦"produces an empty HTML.Acceptance criteria
AnthropicManagedAgent._execute_syncemitsagent_startbefore SSE stream,tool_call_start/endaround eachagent.tool_useevent,llm_responsewhen aggregated text is available,agent_endonsession.status_idle.LocalManagedAgent._execute_syncemits the same five event types aroundagent.chat(...)(already partially covered via innerAgentbut managed-level agent_start/end must be explicit).praisonai --observe langextract managed run "Write a haiku"(or--observe langfuse) produces a non-empty HTML / Langfuse trace with the managed agent visible.get_context_emitter()returns the disabled singleton β seepraisonaiagents/trace/context_events.py).ContextTraceSinkProtocolconfirm event sequence and counts.Agent(backend=ManagedAgent()).start("Say hi")with an installedContextListSinkshows β₯ 2 events.Implementation plan
_execute_syncmethods:emitter = get_context_emitter()at the top (cheap), thenemitter.agent_start(self._cfg.get("name","Agent"), {"input": prompt, "goal": ...})before sending the user message; matchingemitter.agent_end(...)infinally:._process_eventsof AnthropicManagedAgent: onagent.tool_usecallemitter.tool_call_start(agent_name, tool_name, input); no direct "end" event from Anthropic, so emittool_call_endsynthetically right after (or on the next event) withduration_msfrom a local timer.agent.messageaggregated text: callemitter.llm_response(agent_name, response_content=joined_text)once per turn.LocalManagedAgent, the innerAgent.chat()already emits context events viachat_mixin; still add managed-levelagent_start/endto mark the boundary.Files
Modify:
src/praisonai/praisonai/integrations/managed_agents.pyβ_execute_sync,_process_events.src/praisonai/praisonai/integrations/managed_local.pyβ_execute_sync.Tests:
src/praisonai-agents/tests/managed/test_managed_trace_events.py(new) β usesContextListSink+trace_context.Invariants
get_context_emitter().References
ContextTraceEmitterAPI:src/praisonai-agents/praisonaiagents/trace/context_events.py:352-900.cc @claude β per
.windsurf/workflows/e2e-analysis-issue-pr-merge.md.