Module tinytroupe.extraction.results_reporter
Expand source code
import json
import os
from typing import Any, Dict, List, Union
from rich.console import Console
from rich.markdown import Markdown
from tinytroupe import config_manager
from tinytroupe.agent import TinyPerson
from tinytroupe.environment import TinyWorld
from tinytroupe.extraction import logger
from tinytroupe.utils import LLMChat
class ResultsReporter:
def __init__(
self,
default_reporting_task: str = "Summarize the key findings, insights, and outcomes from the simulation data.",
verbose: bool = False,
):
"""
Initializes the ResultsReporter.
Args:
default_reporting_task (str): The default task to ask agents when generating reports.
verbose (bool): Whether to print debug messages.
"""
self.default_reporting_task = default_reporting_task
self.verbose = verbose
self.console = Console()
# Cache for generated reports
self.last_report = None
def report_from_agents(
self,
agents: Union[TinyPerson, TinyWorld, List[TinyPerson]],
reporting_task: str = None,
report_title: str = "Simulation Report",
include_agent_summaries: bool = True,
consolidate_responses: bool = True,
requirements: str = "Present the findings in a clear, structured manner.",
) -> str:
"""
Option 1: Generate a report by asking agents about specific reporting tasks.
Args:
agents: Single agent, TinyWorld, or list of agents to interview.
reporting_task: The specific task to ask agents about.
report_title: Title for the generated report.
include_agent_summaries: Whether to include agent mini-bios in the report.
consolidate_responses: Whether to consolidate all responses into a single report.
requirements: Formatting or content requirements for the report.
Returns:
str: The generated Markdown report.
"""
if reporting_task is None:
reporting_task = self.default_reporting_task
# Extract agents from input
agent_list = self._extract_agents(agents)
if self.verbose:
logger.info(f"Interviewing {len(agent_list)} agents for report generation.")
# Collect responses from agents
agent_responses = []
for agent in agent_list:
response = self._interview_agent(agent, reporting_task)
agent_responses.append({"agent": agent, "response": response})
# Generate the report
report = self._format_agent_interview_report(
agent_responses,
report_title,
reporting_task,
include_agent_summaries,
consolidate_responses,
requirements,
)
self.last_report = report
return report
def report_from_interactions(
self,
agents: Union[TinyPerson, TinyWorld, List[TinyPerson]],
report_title: str = "Interaction Analysis Report",
include_agent_summaries: bool = True,
first_n: int = None,
last_n: int = None,
max_content_length: int = None,
requirements: str = "Present the findings in a clear, structured manner.",
) -> str:
"""
Option 2: Generate a report by analyzing agents' historical interactions.
Args:
agents: Single agent, TinyWorld, or list of agents to analyze.
report_title: Title for the generated report.
include_agent_summaries: Whether to include agent mini-bios.
first_n: Number of first interactions to include.
last_n: Number of last interactions to include.
max_content_length: Maximum content length for interactions.
requirements: Formatting or content requirements for the report.
Returns:
str: The generated Markdown report.
"""
# Extract agents from input
agent_list = self._extract_agents(agents)
if self.verbose:
logger.info(f"Analyzing interactions from {len(agent_list)} agents.")
# Collect interaction data
interactions_data = []
for agent in agent_list:
interactions = agent.pretty_current_interactions(
simplified=True,
first_n=first_n,
last_n=last_n,
max_content_length=max_content_length,
)
interactions_data.append({"agent": agent, "interactions": interactions})
# Generate the report
report = self._format_interactions_report(
interactions_data, report_title, include_agent_summaries, requirements
)
self.last_report = report
return report
def report_from_data(
self,
data: Union[str, Dict[str, Any], List[Dict[str, Any]]],
report_title: str = "Data Report",
requirements: str = "Present the findings in a clear, structured manner.",
) -> str:
"""
Option 3: Generate a report from raw text or structured data.
Args:
data: Raw text, dictionary, or list of dictionaries to format.
report_title: Title for the generated report.
requirements: Formatting or content requirements for the report. If None, uses simple formatting.
Returns:
str: The generated Markdown report.
"""
if self.verbose:
logger.info("Generating report from raw data.")
# Generate the report
report = self._format_data_report(data, report_title, requirements)
self.last_report = report
return report
def display_report(self, report: str = None):
"""
Display a report on the console with rich formatting.
Args:
report: The report to display. If None, uses the last generated report.
"""
if report is None:
report = self.last_report
if report is None:
self.console.print("[red]No report available to display.[/red]")
return
markdown = Markdown(report)
self.console.print(markdown)
def save_report(self, filename: str, report: str = None, verbose: bool = None):
"""
Save a report to a file.
Args:
filename: The filename to save the report to.
report: The report to save. If None, uses the last generated report.
verbose: Whether to print confirmation message.
"""
if report is None:
report = self.last_report
if report is None:
raise ValueError("No report available to save.")
if verbose is None:
verbose = self.verbose
with open(filename, "w", encoding="utf-8", errors="replace") as f:
f.write(report)
if verbose:
logger.info(f"Report saved to {filename}")
def _extract_agents(self, agents) -> List[TinyPerson]:
"""Extract a list of TinyPerson objects from various input types."""
if isinstance(agents, TinyPerson):
return [agents]
elif isinstance(agents, TinyWorld):
return agents.agents
elif isinstance(agents, list):
return agents
else:
raise ValueError(
"Agents must be a TinyPerson, TinyWorld, or list of TinyPerson objects."
)
def _interview_agent(self, agent: TinyPerson, reporting_task: str) -> str:
"""Interview a single agent about the reporting task."""
if self.verbose:
logger.debug(f"Interviewing agent {agent.name} about: {reporting_task}")
# Following TinyTroupe patterns - directly interact with the agent
prompt = f"""
I need you to provide a comprehensive report based on your experiences and observations.
Reporting task: {reporting_task}
Please provide detailed insights, specific examples, and key findings from your perspective.
Focus on what you've learned, observed, and experienced during the simulation.
"""
# Use listen_and_act pattern to get agent's response
agent.listen(prompt)
actions = agent.act(return_actions=True)
# Extract the response from the agent's actions
response = ""
for action in actions:
if action["action"]["type"] == "TALK":
response += action["action"]["content"] + "\n"
if self.verbose:
logger.debug(f"Agent {agent.name} response received.")
return response.strip()
def _format_agent_interview_report(
self,
agent_responses: List[Dict],
title: str,
task: str,
include_summaries: bool,
consolidate: bool,
requirements: str,
) -> str:
"""Format agent interview responses into a Markdown report."""
# Prepare data for LLM formatting
agents_data = []
for resp in agent_responses:
agent_info = {"name": resp["agent"].name, "response": resp["response"]}
if include_summaries:
agent_info["bio"] = resp["agent"].minibio(extended=False)
agents_data.append(agent_info)
# Generate report using LLM
return self._generate_report_with_llm(
title=title,
report_type="agent_interview",
data={
"reporting_task": task,
"agents_data": agents_data,
"consolidate": consolidate,
},
include_summaries=include_summaries,
requirements=requirements,
)
def _format_interactions_report(
self,
interactions_data: List[Dict],
title: str,
include_summaries: bool,
requirements: str,
) -> str:
"""Format interaction data into a Markdown report."""
# Prepare data for LLM formatting
agents_data = []
for data in interactions_data:
agent_info = {
"name": data["agent"].name,
"interactions": data["interactions"],
}
if include_summaries:
agent_info["bio"] = data["agent"].minibio(extended=False)
agents_data.append(agent_info)
# Generate report using LLM
return self._generate_report_with_llm(
title=title,
report_type="interactions",
data={"agents_data": agents_data},
include_summaries=include_summaries,
requirements=requirements,
)
def _format_data_report(self, data: Any, title: str, requirements: str) -> str:
"""Format raw data into a Markdown report."""
return self._generate_report_with_llm(
title=title, report_type="custom_data", data=data, requirements=requirements
)
def _generate_report_with_llm(
self,
title: str,
report_type: str,
data: Any,
include_summaries: bool = False,
requirements: str = None,
) -> str:
"""Generate a report using LLM based on the report type and data."""
# Base system prompt
system_prompt = "You are a professional report writer who creates clear, well-structured Markdown reports."
# Type-specific prompts and instructions
if report_type == "agent_interview":
system_prompt += " You specialize in synthesizing interview responses from multiple agents."
user_prompt = f"""
## Task
Create a comprehensive report based on agent interviews such that it fulfills the
specified requirements below.
## Report Title
{title}
## Report Details
- **Reporting Task:** {data['reporting_task']}
- **Number of Agents Interviewed:** {len(data['agents_data'])}
- **Generated on:** {self._get_timestamp()}
## Agent Responses
{json.dumps(data['agents_data'], indent=2)}
## Instructions
- Start with the title as a level-1 header
- Write a direct, clear report, but do not simplify or summarize the information
- Make sure all important details are included. This is not a summary, but a detailed report, so you never remove information, you just make it more readable
- Do not include the original data or agent responses, but only the resulting report information
- For each agent, include their bio if provided
- Use proper Markdown formatting throughout
- Follow the requirements given next, which can also override any of these rules
## Requirements
{requirements}
"""
elif report_type == "interactions":
system_prompt += " You specialize in analyzing and presenting agent interaction histories."
user_prompt = f"""
## Task
Create a report analyzing agent interactions from a simulation such that it fulfills the
specified requirements below.
## Report Title
{title}
## Report Details
- **Number of Agents Analyzed:** {len(data['agents_data'])}
- **Generated on:** {self._get_timestamp()}
## Agent Interaction Data
{json.dumps(data['agents_data'], indent=2)}
## Instructions
- Start with the title as a level-1 header
- Write a direct, clear report, but do not simplify or summarize the information
- Make sure all important details are included. This is not a summary, but a detailed report, so you never remove information, you just make it more readable
- Do not include agents' interaction history, but only the resulting report information
- For each agent, include their bio if provided
- Use proper Markdown formatting throughout
- Follow the requirements given next, which can also override any of these rules
## Requirements
{requirements}
"""
elif report_type == "custom_data":
# Handle arbitrary data without assuming any structure
if isinstance(data, str):
data_representation = data
else:
# For any other type, convert to JSON for a clean representation
data_representation = json.dumps(data, indent=2)
user_prompt = f"""
## Task
Create a well-structured Markdown report based on the provided data such that it fulfills the
specified requirements below.
## Report Title
{title}
## Generated on
{self._get_timestamp()}
## Data to Format
{data_representation}
## Instructions
- Start with the title as a level-1 header
- Write a direct, clear report, but do not simplify or summarize the information
- Make sure all important details are included. This is not a summary, but a detailed report, so you never remove information, you just make it more readable
- Use proper Markdown formatting throughout
- Follow the requirements given next, which can also override any of these rules
## Requirements
{requirements if requirements else "Use your best judgment to create a clear, informative report that presents the data in an organized and readable manner."}
"""
else:
raise ValueError(f"Unknown report type: {report_type}")
# Generate the report
report_chat = LLMChat(
system_prompt=system_prompt,
user_prompt=user_prompt,
output_type=str,
enable_json_output_format=False,
model=config_manager.get("model"),
)
return report_chat()
def _get_timestamp(self) -> str:
"""Get current timestamp for report headers."""
from datetime import datetime
return datetime.now().strftime("%Y-%m-%d %H:%M:%S")
Classes
class ResultsReporter (default_reporting_task: str = 'Summarize the key findings, insights, and outcomes from the simulation data.', verbose: bool = False)-
Initializes the ResultsReporter.
Args
default_reporting_task:str- The default task to ask agents when generating reports.
verbose:bool- Whether to print debug messages.
Expand source code
class ResultsReporter: def __init__( self, default_reporting_task: str = "Summarize the key findings, insights, and outcomes from the simulation data.", verbose: bool = False, ): """ Initializes the ResultsReporter. Args: default_reporting_task (str): The default task to ask agents when generating reports. verbose (bool): Whether to print debug messages. """ self.default_reporting_task = default_reporting_task self.verbose = verbose self.console = Console() # Cache for generated reports self.last_report = None def report_from_agents( self, agents: Union[TinyPerson, TinyWorld, List[TinyPerson]], reporting_task: str = None, report_title: str = "Simulation Report", include_agent_summaries: bool = True, consolidate_responses: bool = True, requirements: str = "Present the findings in a clear, structured manner.", ) -> str: """ Option 1: Generate a report by asking agents about specific reporting tasks. Args: agents: Single agent, TinyWorld, or list of agents to interview. reporting_task: The specific task to ask agents about. report_title: Title for the generated report. include_agent_summaries: Whether to include agent mini-bios in the report. consolidate_responses: Whether to consolidate all responses into a single report. requirements: Formatting or content requirements for the report. Returns: str: The generated Markdown report. """ if reporting_task is None: reporting_task = self.default_reporting_task # Extract agents from input agent_list = self._extract_agents(agents) if self.verbose: logger.info(f"Interviewing {len(agent_list)} agents for report generation.") # Collect responses from agents agent_responses = [] for agent in agent_list: response = self._interview_agent(agent, reporting_task) agent_responses.append({"agent": agent, "response": response}) # Generate the report report = self._format_agent_interview_report( agent_responses, report_title, reporting_task, include_agent_summaries, consolidate_responses, requirements, ) self.last_report = report return report def report_from_interactions( self, agents: Union[TinyPerson, TinyWorld, List[TinyPerson]], report_title: str = "Interaction Analysis Report", include_agent_summaries: bool = True, first_n: int = None, last_n: int = None, max_content_length: int = None, requirements: str = "Present the findings in a clear, structured manner.", ) -> str: """ Option 2: Generate a report by analyzing agents' historical interactions. Args: agents: Single agent, TinyWorld, or list of agents to analyze. report_title: Title for the generated report. include_agent_summaries: Whether to include agent mini-bios. first_n: Number of first interactions to include. last_n: Number of last interactions to include. max_content_length: Maximum content length for interactions. requirements: Formatting or content requirements for the report. Returns: str: The generated Markdown report. """ # Extract agents from input agent_list = self._extract_agents(agents) if self.verbose: logger.info(f"Analyzing interactions from {len(agent_list)} agents.") # Collect interaction data interactions_data = [] for agent in agent_list: interactions = agent.pretty_current_interactions( simplified=True, first_n=first_n, last_n=last_n, max_content_length=max_content_length, ) interactions_data.append({"agent": agent, "interactions": interactions}) # Generate the report report = self._format_interactions_report( interactions_data, report_title, include_agent_summaries, requirements ) self.last_report = report return report def report_from_data( self, data: Union[str, Dict[str, Any], List[Dict[str, Any]]], report_title: str = "Data Report", requirements: str = "Present the findings in a clear, structured manner.", ) -> str: """ Option 3: Generate a report from raw text or structured data. Args: data: Raw text, dictionary, or list of dictionaries to format. report_title: Title for the generated report. requirements: Formatting or content requirements for the report. If None, uses simple formatting. Returns: str: The generated Markdown report. """ if self.verbose: logger.info("Generating report from raw data.") # Generate the report report = self._format_data_report(data, report_title, requirements) self.last_report = report return report def display_report(self, report: str = None): """ Display a report on the console with rich formatting. Args: report: The report to display. If None, uses the last generated report. """ if report is None: report = self.last_report if report is None: self.console.print("[red]No report available to display.[/red]") return markdown = Markdown(report) self.console.print(markdown) def save_report(self, filename: str, report: str = None, verbose: bool = None): """ Save a report to a file. Args: filename: The filename to save the report to. report: The report to save. If None, uses the last generated report. verbose: Whether to print confirmation message. """ if report is None: report = self.last_report if report is None: raise ValueError("No report available to save.") if verbose is None: verbose = self.verbose with open(filename, "w", encoding="utf-8", errors="replace") as f: f.write(report) if verbose: logger.info(f"Report saved to {filename}") def _extract_agents(self, agents) -> List[TinyPerson]: """Extract a list of TinyPerson objects from various input types.""" if isinstance(agents, TinyPerson): return [agents] elif isinstance(agents, TinyWorld): return agents.agents elif isinstance(agents, list): return agents else: raise ValueError( "Agents must be a TinyPerson, TinyWorld, or list of TinyPerson objects." ) def _interview_agent(self, agent: TinyPerson, reporting_task: str) -> str: """Interview a single agent about the reporting task.""" if self.verbose: logger.debug(f"Interviewing agent {agent.name} about: {reporting_task}") # Following TinyTroupe patterns - directly interact with the agent prompt = f""" I need you to provide a comprehensive report based on your experiences and observations. Reporting task: {reporting_task} Please provide detailed insights, specific examples, and key findings from your perspective. Focus on what you've learned, observed, and experienced during the simulation. """ # Use listen_and_act pattern to get agent's response agent.listen(prompt) actions = agent.act(return_actions=True) # Extract the response from the agent's actions response = "" for action in actions: if action["action"]["type"] == "TALK": response += action["action"]["content"] + "\n" if self.verbose: logger.debug(f"Agent {agent.name} response received.") return response.strip() def _format_agent_interview_report( self, agent_responses: List[Dict], title: str, task: str, include_summaries: bool, consolidate: bool, requirements: str, ) -> str: """Format agent interview responses into a Markdown report.""" # Prepare data for LLM formatting agents_data = [] for resp in agent_responses: agent_info = {"name": resp["agent"].name, "response": resp["response"]} if include_summaries: agent_info["bio"] = resp["agent"].minibio(extended=False) agents_data.append(agent_info) # Generate report using LLM return self._generate_report_with_llm( title=title, report_type="agent_interview", data={ "reporting_task": task, "agents_data": agents_data, "consolidate": consolidate, }, include_summaries=include_summaries, requirements=requirements, ) def _format_interactions_report( self, interactions_data: List[Dict], title: str, include_summaries: bool, requirements: str, ) -> str: """Format interaction data into a Markdown report.""" # Prepare data for LLM formatting agents_data = [] for data in interactions_data: agent_info = { "name": data["agent"].name, "interactions": data["interactions"], } if include_summaries: agent_info["bio"] = data["agent"].minibio(extended=False) agents_data.append(agent_info) # Generate report using LLM return self._generate_report_with_llm( title=title, report_type="interactions", data={"agents_data": agents_data}, include_summaries=include_summaries, requirements=requirements, ) def _format_data_report(self, data: Any, title: str, requirements: str) -> str: """Format raw data into a Markdown report.""" return self._generate_report_with_llm( title=title, report_type="custom_data", data=data, requirements=requirements ) def _generate_report_with_llm( self, title: str, report_type: str, data: Any, include_summaries: bool = False, requirements: str = None, ) -> str: """Generate a report using LLM based on the report type and data.""" # Base system prompt system_prompt = "You are a professional report writer who creates clear, well-structured Markdown reports." # Type-specific prompts and instructions if report_type == "agent_interview": system_prompt += " You specialize in synthesizing interview responses from multiple agents." user_prompt = f""" ## Task Create a comprehensive report based on agent interviews such that it fulfills the specified requirements below. ## Report Title {title} ## Report Details - **Reporting Task:** {data['reporting_task']} - **Number of Agents Interviewed:** {len(data['agents_data'])} - **Generated on:** {self._get_timestamp()} ## Agent Responses {json.dumps(data['agents_data'], indent=2)} ## Instructions - Start with the title as a level-1 header - Write a direct, clear report, but do not simplify or summarize the information - Make sure all important details are included. This is not a summary, but a detailed report, so you never remove information, you just make it more readable - Do not include the original data or agent responses, but only the resulting report information - For each agent, include their bio if provided - Use proper Markdown formatting throughout - Follow the requirements given next, which can also override any of these rules ## Requirements {requirements} """ elif report_type == "interactions": system_prompt += " You specialize in analyzing and presenting agent interaction histories." user_prompt = f""" ## Task Create a report analyzing agent interactions from a simulation such that it fulfills the specified requirements below. ## Report Title {title} ## Report Details - **Number of Agents Analyzed:** {len(data['agents_data'])} - **Generated on:** {self._get_timestamp()} ## Agent Interaction Data {json.dumps(data['agents_data'], indent=2)} ## Instructions - Start with the title as a level-1 header - Write a direct, clear report, but do not simplify or summarize the information - Make sure all important details are included. This is not a summary, but a detailed report, so you never remove information, you just make it more readable - Do not include agents' interaction history, but only the resulting report information - For each agent, include their bio if provided - Use proper Markdown formatting throughout - Follow the requirements given next, which can also override any of these rules ## Requirements {requirements} """ elif report_type == "custom_data": # Handle arbitrary data without assuming any structure if isinstance(data, str): data_representation = data else: # For any other type, convert to JSON for a clean representation data_representation = json.dumps(data, indent=2) user_prompt = f""" ## Task Create a well-structured Markdown report based on the provided data such that it fulfills the specified requirements below. ## Report Title {title} ## Generated on {self._get_timestamp()} ## Data to Format {data_representation} ## Instructions - Start with the title as a level-1 header - Write a direct, clear report, but do not simplify or summarize the information - Make sure all important details are included. This is not a summary, but a detailed report, so you never remove information, you just make it more readable - Use proper Markdown formatting throughout - Follow the requirements given next, which can also override any of these rules ## Requirements {requirements if requirements else "Use your best judgment to create a clear, informative report that presents the data in an organized and readable manner."} """ else: raise ValueError(f"Unknown report type: {report_type}") # Generate the report report_chat = LLMChat( system_prompt=system_prompt, user_prompt=user_prompt, output_type=str, enable_json_output_format=False, model=config_manager.get("model"), ) return report_chat() def _get_timestamp(self) -> str: """Get current timestamp for report headers.""" from datetime import datetime return datetime.now().strftime("%Y-%m-%d %H:%M:%S")Methods
def display_report(self, report: str = None)-
Display a report on the console with rich formatting.
Args
report- The report to display. If None, uses the last generated report.
Expand source code
def display_report(self, report: str = None): """ Display a report on the console with rich formatting. Args: report: The report to display. If None, uses the last generated report. """ if report is None: report = self.last_report if report is None: self.console.print("[red]No report available to display.[/red]") return markdown = Markdown(report) self.console.print(markdown) def report_from_agents(self, agents: Union[TinyPerson, TinyWorld, List[TinyPerson]], reporting_task: str = None, report_title: str = 'Simulation Report', include_agent_summaries: bool = True, consolidate_responses: bool = True, requirements: str = 'Present the findings in a clear, structured manner.') ‑> str-
Option 1: Generate a report by asking agents about specific reporting tasks.
Args
agents- Single agent, TinyWorld, or list of agents to interview.
reporting_task- The specific task to ask agents about.
report_title- Title for the generated report.
include_agent_summaries- Whether to include agent mini-bios in the report.
consolidate_responses- Whether to consolidate all responses into a single report.
requirements- Formatting or content requirements for the report.
Returns
str- The generated Markdown report.
Expand source code
def report_from_agents( self, agents: Union[TinyPerson, TinyWorld, List[TinyPerson]], reporting_task: str = None, report_title: str = "Simulation Report", include_agent_summaries: bool = True, consolidate_responses: bool = True, requirements: str = "Present the findings in a clear, structured manner.", ) -> str: """ Option 1: Generate a report by asking agents about specific reporting tasks. Args: agents: Single agent, TinyWorld, or list of agents to interview. reporting_task: The specific task to ask agents about. report_title: Title for the generated report. include_agent_summaries: Whether to include agent mini-bios in the report. consolidate_responses: Whether to consolidate all responses into a single report. requirements: Formatting or content requirements for the report. Returns: str: The generated Markdown report. """ if reporting_task is None: reporting_task = self.default_reporting_task # Extract agents from input agent_list = self._extract_agents(agents) if self.verbose: logger.info(f"Interviewing {len(agent_list)} agents for report generation.") # Collect responses from agents agent_responses = [] for agent in agent_list: response = self._interview_agent(agent, reporting_task) agent_responses.append({"agent": agent, "response": response}) # Generate the report report = self._format_agent_interview_report( agent_responses, report_title, reporting_task, include_agent_summaries, consolidate_responses, requirements, ) self.last_report = report return report def report_from_data(self, data: Union[str, Dict[str, Any], List[Dict[str, Any]]], report_title: str = 'Data Report', requirements: str = 'Present the findings in a clear, structured manner.') ‑> str-
Option 3: Generate a report from raw text or structured data.
Args
data- Raw text, dictionary, or list of dictionaries to format.
report_title- Title for the generated report.
requirements- Formatting or content requirements for the report. If None, uses simple formatting.
Returns
str- The generated Markdown report.
Expand source code
def report_from_data( self, data: Union[str, Dict[str, Any], List[Dict[str, Any]]], report_title: str = "Data Report", requirements: str = "Present the findings in a clear, structured manner.", ) -> str: """ Option 3: Generate a report from raw text or structured data. Args: data: Raw text, dictionary, or list of dictionaries to format. report_title: Title for the generated report. requirements: Formatting or content requirements for the report. If None, uses simple formatting. Returns: str: The generated Markdown report. """ if self.verbose: logger.info("Generating report from raw data.") # Generate the report report = self._format_data_report(data, report_title, requirements) self.last_report = report return report def report_from_interactions(self, agents: Union[TinyPerson, TinyWorld, List[TinyPerson]], report_title: str = 'Interaction Analysis Report', include_agent_summaries: bool = True, first_n: int = None, last_n: int = None, max_content_length: int = None, requirements: str = 'Present the findings in a clear, structured manner.') ‑> str-
Option 2: Generate a report by analyzing agents' historical interactions.
Args
agents- Single agent, TinyWorld, or list of agents to analyze.
report_title- Title for the generated report.
include_agent_summaries- Whether to include agent mini-bios.
first_n- Number of first interactions to include.
last_n- Number of last interactions to include.
max_content_length- Maximum content length for interactions.
requirements- Formatting or content requirements for the report.
Returns
str- The generated Markdown report.
Expand source code
def report_from_interactions( self, agents: Union[TinyPerson, TinyWorld, List[TinyPerson]], report_title: str = "Interaction Analysis Report", include_agent_summaries: bool = True, first_n: int = None, last_n: int = None, max_content_length: int = None, requirements: str = "Present the findings in a clear, structured manner.", ) -> str: """ Option 2: Generate a report by analyzing agents' historical interactions. Args: agents: Single agent, TinyWorld, or list of agents to analyze. report_title: Title for the generated report. include_agent_summaries: Whether to include agent mini-bios. first_n: Number of first interactions to include. last_n: Number of last interactions to include. max_content_length: Maximum content length for interactions. requirements: Formatting or content requirements for the report. Returns: str: The generated Markdown report. """ # Extract agents from input agent_list = self._extract_agents(agents) if self.verbose: logger.info(f"Analyzing interactions from {len(agent_list)} agents.") # Collect interaction data interactions_data = [] for agent in agent_list: interactions = agent.pretty_current_interactions( simplified=True, first_n=first_n, last_n=last_n, max_content_length=max_content_length, ) interactions_data.append({"agent": agent, "interactions": interactions}) # Generate the report report = self._format_interactions_report( interactions_data, report_title, include_agent_summaries, requirements ) self.last_report = report return report def save_report(self, filename: str, report: str = None, verbose: bool = None)-
Save a report to a file.
Args
filename- The filename to save the report to.
report- The report to save. If None, uses the last generated report.
verbose- Whether to print confirmation message.
Expand source code
def save_report(self, filename: str, report: str = None, verbose: bool = None): """ Save a report to a file. Args: filename: The filename to save the report to. report: The report to save. If None, uses the last generated report. verbose: Whether to print confirmation message. """ if report is None: report = self.last_report if report is None: raise ValueError("No report available to save.") if verbose is None: verbose = self.verbose with open(filename, "w", encoding="utf-8", errors="replace") as f: f.write(report) if verbose: logger.info(f"Report saved to {filename}")