Output Transformation Post-Hook
Use post-hooks to reformat a Team's TeamRunOutput.content with member metadata, a collaboration summary, or an AI-structured layout before returning it.
Use a post-hook to transform the output of a Team before it is returned to the user.
This hook:
- Transforms team responses by updating TeamRunOutput.content
- Adds formatting, structure, and additional information
- Enhances the user experience through content modification
This curated example attributes each contribution using the recorded member identity. A member can run repeatedly or out of roster order.
Code
from datetime import datetime
from agno.agent import Agent
from agno.models.openai import OpenAIResponses
from agno.run.team import TeamRunOutput
from agno.team import Team
from pydantic import BaseModel
class FormattedTeamResponse(BaseModel):
executive_summary: str
member_contributions: dict[str, str]
key_insights: list[str]
action_items: list[str]
coordination_notes: str
disclaimer: str
def add_team_metadata(run_output: TeamRunOutput, team: Team) -> None:
"""Add team metadata to output for transparency."""
content = run_output.content.strip() if run_output.content else ""
team_members = [member.name for member in team.members]
formatted_content = f"""# {team.name} Response
{content}
---
**Team Members:** {", ".join(team_members)}
**Generated:** {datetime.now().strftime("%Y-%m-%d %H:%M:%S")}"""
run_output.content = formatted_content
def add_collaboration_summary(run_output: TeamRunOutput, team: Team) -> None:
"""Append a collaboration summary with per-member highlights."""
content = run_output.content.strip() if run_output.content else ""
member_summaries = []
if hasattr(run_output, "member_responses") and run_output.member_responses:
for member_response in run_output.member_responses:
member_name = (
getattr(member_response, "agent_name", None)
or getattr(member_response, "team_name", None)
or getattr(member_response, "agent_id", None)
or getattr(member_response, "team_id", None)
or "Unknown member"
)
if hasattr(member_response, "content") and member_response.content:
summary = (
member_response.content[:200] + "..."
if len(member_response.content) > 200
else member_response.content
)
member_summaries.append(f"**{member_name}:** {summary}")
enhanced_content = f"""{content}
## Team Collaboration Summary
{chr(10).join(member_summaries) if member_summaries else "No member responses were recorded."}
---
*Response coordinated by {team.name} • {len(team.members)} team members*
*Generated on {datetime.now().strftime("%B %d, %Y at %I:%M %p")}*"""
run_output.content = enhanced_content
def structure_team_response(run_output: TeamRunOutput, team: Team) -> None:
"""Reformat output into a structured, action-oriented summary."""
formatter_agent = Agent(
name="Team Response Formatter",
model=OpenAIResponses(id="gpt-5.2"),
instructions=[
"You are a team response formatting specialist.",
"Transform team responses into well-structured formats that highlight:",
"1. EXECUTIVE_SUMMARY: Clear overview of the team's collective response",
"2. MEMBER_CONTRIBUTIONS: Identify unique value each team member provided",
"3. KEY_INSIGHTS: Extract 3-5 most important insights from the team",
"4. ACTION_ITEMS: Concrete next steps or recommendations",
"5. COORDINATION_NOTES: How the team members' expertise complemented each other",
"6. DISCLAIMER: Appropriate disclaimer for the type of advice provided",
"",
"Maintain all original information while improving organization and clarity.",
],
output_schema=FormattedTeamResponse,
)
try:
team_context = f"Team '{team.name}' with members: " + ", ".join(
[
f"{member.name} ({getattr(member, 'description', 'No description')})"
for member in team.members
]
)
formatted_result = formatter_agent.run(
input=f"""
{team_context}
Format this team response: '{run_output.content}'
"""
)
formatted = formatted_result.content
enhanced_response = f"""# {team.name} - Collaborative Response
## Executive Summary
{formatted.executive_summary}
## Team Member Contributions
{chr(10).join([f"### {member}: {contribution}" for member, contribution in formatted.member_contributions.items()])}
## Key Insights
{chr(10).join([f"- {insight}" for insight in formatted.key_insights])}
## Recommended Actions
{chr(10).join([f"{i + 1}. {action}" for i, action in enumerate(formatted.action_items)])}
## Team Coordination
{formatted.coordination_notes}
## Important Notice
{formatted.disclaimer}
---
**Team:** {team.name} ({len(team.members)} members)
**Formatted:** {datetime.now().strftime("%Y-%m-%d at %H:%M:%S")}"""
run_output.content = enhanced_response
except Exception as e:
print(
f"Warning: Advanced team formatting failed ({e}), using collaboration summary"
)
add_collaboration_summary(run_output, team)
metadata_team = Team(
name="Business Intelligence Team",
model=OpenAIResponses(id="gpt-5.2"),
members=[
Agent(
name="Market Analyst",
model=OpenAIResponses(id="gpt-5.2"),
description="Expert in market trends and competitive analysis",
),
Agent(
name="Business Advisor",
model=OpenAIResponses(id="gpt-5.2"),
description="Specialist in business strategy and operations",
),
],
post_hooks=[add_team_metadata],
instructions=[
"Provide comprehensive business insights combining market analysis and strategic advice."
],
)
collab_team = Team(
name="Product Development Team",
members=[
Agent(
name="UX Designer",
model=OpenAIResponses(id="gpt-5.2"),
description="User experience and interface design expert",
),
Agent(
name="Product Manager",
model=OpenAIResponses(id="gpt-5.2"),
description="Product strategy and roadmap specialist",
),
Agent(
name="Engineer",
model=OpenAIResponses(id="gpt-5.2"),
description="Technical implementation and architecture expert",
),
],
post_hooks=[add_collaboration_summary],
instructions=[
"Collaborate to provide comprehensive product development guidance:",
"UX Designer: Focus on user experience and design considerations",
"Product Manager: Address strategy, features, and market fit",
"Engineer: Cover technical feasibility and implementation",
],
)
consulting_team = Team(
name="Management Consulting Team",
members=[
Agent(
name="Strategy Consultant",
model=OpenAIResponses(id="gpt-5.2"),
description="Business strategy and planning expert",
),
Agent(
name="Operations Specialist",
model=OpenAIResponses(id="gpt-5.2"),
description="Process optimization and efficiency expert",
),
Agent(
name="Change Management Expert",
model=OpenAIResponses(id="gpt-5.2"),
description="Organizational change and transformation specialist",
),
],
post_hooks=[structure_team_response],
instructions=[
"Provide comprehensive management consulting advice:",
"Strategy Consultant: Define strategic direction and competitive positioning",
"Operations Specialist: Identify operational improvements and efficiencies",
"Change Management Expert: Address organizational and cultural considerations",
"",
"Work together to deliver actionable transformation guidance.",
],
)
def main() -> None:
"""Demonstrate output transformation post-hooks."""
print("Team Output Transformation Post-Hook Examples")
print("=" * 60)
print("\n[TEST 1] Basic team metadata transformation")
print("-" * 50)
metadata_team.print_response(
input="What are the key trends in the e-commerce industry for 2024?"
)
print("[OK] Response with team metadata formatting")
print("\n[TEST 2] Collaboration summary transformation")
print("-" * 50)
collab_team.print_response(
input="How should we approach building a mobile app for fitness tracking? Give me a detailed plan."
)
print("[OK] Response with collaboration summary")
print("\n[TEST 3] Comprehensive structured team response")
print("-" * 50)
consulting_team.print_response(
input="Our mid-size manufacturing company wants to implement digital transformation. We have 500 employees and are struggling with outdated processes and resistance to change. What's our path forward?"
)
print("[OK] Comprehensive structured team response")
if __name__ == "__main__":
main()Usage
Set up your virtual environment
uv venv --python 3.12
source .venv/bin/activateInstall dependencies
uv pip install -U agno openaiExport your OpenAI API key
export OPENAI_API_KEY="your_openai_api_key_here"Run example
Save the code above as output_transformation_post_hook.py, then run:
python output_transformation_post_hook.py