Skip to content

Commit e4f1d95

Browse files
Refactor file reading functionality by consolidating read_markdown and read_csv_preview into a new read_file function that supports multiple file types. Update relevant prompts and agent configurations to utilize the new function. Enhance notebook output to include execution tracing information for better debugging and analysis context.
1 parent 58c9834 commit e4f1d95

File tree

7 files changed

+45
-56
lines changed

7 files changed

+45
-56
lines changed

examples/agents_sdk/multi-agent-portfolio-collaboration/investment_agents/editor.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from agents import Agent, ModelSettings, function_tool, Runner, RunContextWrapper
2-
from tools import write_markdown, read_markdown, read_csv_preview, list_output_files
2+
from tools import write_markdown, read_file, list_output_files
33
from utils import load_prompt, DISCLAIMER
44
from pydantic import BaseModel
55
import json
@@ -19,7 +19,7 @@ def build_editor_agent():
1919
return Agent(
2020
name="Memo Editor Agent",
2121
instructions=(editor_prompt + DISCLAIMER + tool_retry_instructions),
22-
tools=[write_markdown, read_markdown, read_csv_preview, list_output_files],
22+
tools=[write_markdown, read_file, list_output_files],
2323
model=default_model,
2424
model_settings=ModelSettings(temperature=0),
2525
)

examples/agents_sdk/multi-agent-portfolio-collaboration/investment_agents/quant.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from agents import Agent, ModelSettings
2-
from tools import run_code_interpreter, get_fred_series, read_csv_preview, list_output_files
2+
from tools import run_code_interpreter, get_fred_series, read_file, list_output_files
33
from utils import load_prompt, DISCLAIMER
44
from pathlib import Path
55

@@ -21,7 +21,7 @@ def build_quant_agent():
2121
name="Quantitative Analysis Agent",
2222
instructions=(quant_prompt + DISCLAIMER + tool_retry_instructions),
2323
mcp_servers=[yahoo_mcp_server],
24-
tools=[run_code_interpreter, get_fred_series, read_csv_preview, list_output_files],
24+
tools=[run_code_interpreter, get_fred_series, read_file, list_output_files],
2525
model=default_model,
2626
model_settings=ModelSettings(parallel_tool_calls=True, temperature=0),
2727
)

examples/agents_sdk/multi-agent-portfolio-collaboration/multi_agent_portfolio_collaboration.ipynb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,8 @@
176176
" today_str = datetime.date.today().strftime(\"%B %d, %Y\")\n",
177177
" question = (\n",
178178
" f\"Today is {today_str}. \"\n",
179-
" \"Is walmart losing market share to instacart? Provide analysis as this will influence a trading decision.\"\n",
179+
" \"How would the planned interest rate reduction effect my holdings in GOOGL if they were to happen?\"\n",
180+
" \"Considering all the factors effecting its price right now (Macro, Technical, Fundamental, etc.), what is a realistic price target by the end of the year?\"\n",
180181
" )\n",
181182
" bundle = build_investment_agents()\n",
182183
"\n",
@@ -351,7 +352,7 @@
351352
},
352353
{
353354
"cell_type": "code",
354-
"execution_count": 3,
355+
"execution_count": 1,
355356
"id": "9fe6e452",
356357
"metadata": {},
357358
"outputs": [

examples/agents_sdk/multi-agent-portfolio-collaboration/prompts/code_interpreter.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ You are an expert quantitative developer using OpenAI's Code Interpreter. You ar
1111
## Analysis Workflow
1212
1. Print the schema of each input file. Understand the dataset, and make logical assumptions on analysis even if the quant doesn't explicitly provide them.
1313
2. Drop missing values and normalize data as needed.
14-
3. Run the Analysis processed data, and inspect the data to ensure it ran.
15-
4. Create visualizations that best fit the analysis type.
16-
5. If the analysis cannot be completed even after the data processing, do not generate outputs. Instead, return a `<reason>` tag with a clear explanation, including the available columns.
14+
3. Run the analysis on the processed data.
15+
4. **If the data is empty or contains no rows after cleaning, do not generate any outputs. Instead, return only a `<reason>` tag explaining that the data is empty or insufficient for analysis, and list the available columns.**
16+
5. If the data is sufficient, create visualizations and tables as appropriate for the analysis.
1717

1818
## Constraints
1919
- Do **not** fetch external data or use `yfinance`. Use only the files in `input_files`.

examples/agents_sdk/multi-agent-portfolio-collaboration/prompts/editor_base.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ You will receive a structured dictionary with the following keys:
8080
4. **Format**
8181
- Embed files appropriately:
8282
- Use `list_output_files` to discover available files.
83-
- Use `read_csv_preview` for `.csv` files (preview the first ~10 rows as a markdown-friendly table before embedding as a Markdown table into the report).
83+
- Use `read_file` for `.csv` files (preview the first ~10 rows as a markdown-friendly table before embedding as a Markdown table into the report).
8484
- Use standard Markdown syntax for charts and images (only if the file exists), e.g., `![vol-chart](AVGO_NVDA_price_vol_chart.png)`.
8585
- You cannot read PNG files directly.
8686
- These must be written to the report so they render. Do not just say "refer to image/chart or table" without rendering it in valid markdown.
@@ -101,8 +101,6 @@ You will receive a structured dictionary with the following keys:
101101
**Example of a process (yours might be different):**
102102

103103
1. Use `list_output_files` to get available files.
104-
2. Preview CSV files with `read_csv_preview` for `.csv` files.
104+
2. Preview CSV files with `read_file` for `.csv` files.
105105
3. Save the memo using `write_markdown` to generate the investment_report, add relevant charts and tables rendered in markdown.
106-
4. Verify the memo using the `read_markdown` tool.
107-
5. Return `{ "file": "investment_report.md" }` JSON to the PM Agent (not the memo, just the file).
108-
106+
4. Return `{ "file": "investment_report.md" }` JSON to the PM Agent (not the memo, just the file).

examples/agents_sdk/multi-agent-portfolio-collaboration/prompts/quant_base.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ If you mention a file in your request but do not include it in `input_files`, th
3434
---
3535

3636
**Additional Tools Available:**
37-
- **read_csv_preview**: Use this tool to preview the contents of any CSV file in the outputs directory before running an analysis. This helps you understand the schema, columns, and data quality, it doesn't generate any files.
37+
- **read_file**: Use this tool to preview the contents of any CSV, Markdown, or text file in the outputs directory before running an analysis. For CSVs, it returns a markdown table preview. This helps you understand the schema, columns, and data quality, it doesn't generate any files.
3838
- **list_output_files**: Use this tool to list all available files in the outputs directory. This helps you check which files are present and avoid referencing non-existent files. If you get file not found errors use this.
3939

4040
_You may use these tools to inspect available data and plan your analysis more effectively before calling run_code_interpreter._

examples/agents_sdk/multi-agent-portfolio-collaboration/tools.py

Lines changed: 31 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ def run_code_interpreter(request: str, input_files: list[str]) -> str:
8080
raise ValueError(
8181
f"File not found: {file_path}. "
8282
"Use the list_output_files tool to see which files exist, "
83-
"and the read_csv_preview tool to see the contents of CSV files."
83+
"and the read_file tool to see the contents of CSV files."
8484
)
8585
with abs_path.open("rb") as f:
8686
uploaded = client.files.create(file=f, purpose="user_data")
@@ -156,34 +156,43 @@ def write_markdown(filename: str, content: str) -> str:
156156
return json.dumps({"file": filename})
157157

158158
@function_tool
159-
def read_markdown(filename: str) -> str:
160-
"""Read a Markdown file from the outputs directory.
161-
162-
If the caller provides a filename with **no** extension, we assume they meant a Markdown file
163-
and append ``.md`` automatically. However, if the caller explicitly provides an extension that
164-
is *not* ``.md``, we return an error explaining that only Markdown files are supported.
159+
def read_file(filename: str, n_rows: int = 10) -> str:
165160
"""
161+
Read and preview the contents of a file from the outputs directory.
166162
167-
# Determine if an explicit, non-Markdown extension was provided
168-
suffix = Path(filename).suffix
169-
if suffix and suffix.lower() != ".md":
170-
return json.dumps({
171-
"error": f"Wrong extension. cannot read '{suffix}' files; only .md files are supported",
172-
"file": filename,
173-
})
163+
Supports reading CSV, Markdown (.md), and plain text (.txt) files. For CSV files, returns a preview of the last `n_rows` as a Markdown table. For Markdown and text files, returns the full text content. For unsupported file types, returns an error message.
174164
175-
# If no extension or already .md, ensure filename ends with .md
176-
if not filename.endswith(".md"):
177-
filename += ".md"
165+
Args:
166+
filename: The name of the file to read, relative to the outputs directory. Supported extensions: .csv, .md, .txt.
167+
n_rows: The number of rows to preview for CSV files (default: 10).
178168
169+
Returns:
170+
str: A JSON string containing either:
171+
- For CSV: {"file": filename, "preview_markdown": "<markdown table>"}
172+
- For Markdown/Text: {"file": filename, "content": "<text content>"}
173+
- For errors: {"error": "<error message>", "file": filename}
174+
"""
179175
path = output_file(filename, make_parents=False)
180176
if not path.exists():
181177
return json.dumps({"error": "file not found", "file": filename})
182178

183-
with open(path, "r", encoding="utf-8") as f:
184-
content = f.read()
185-
186-
return json.dumps({"file": filename, "content": content})
179+
suffix = Path(filename).suffix.lower()
180+
if suffix == ".csv":
181+
try:
182+
df = pd.read_csv(path).tail(n_rows)
183+
table_md = df.to_markdown(index=False)
184+
return json.dumps({"file": filename, "preview_markdown": table_md})
185+
except Exception as e:
186+
return json.dumps({"error": str(e), "file": filename})
187+
elif suffix == ".md" or suffix == ".txt":
188+
try:
189+
with open(path, "r", encoding="utf-8") as f:
190+
content = f.read()
191+
return json.dumps({"file": filename, "content": content})
192+
except Exception as e:
193+
return json.dumps({"error": str(e), "file": filename})
194+
else:
195+
return json.dumps({"error": f"Unsupported file type: {suffix}", "file": filename})
187196

188197
@function_tool
189198
def get_fred_series(series_id: str, start_date: str, end_date: str, download_csv: bool = False) -> str:
@@ -253,24 +262,6 @@ def get_fred_series(series_id: str, start_date: str, end_date: str, download_csv
253262
except Exception as e:
254263
return json.dumps({"error": str(e), "series_id": series_id})
255264

256-
@function_tool
257-
def read_csv_preview(filename: str, n_rows: int = 10) -> str:
258-
"""Return last `n_rows` of a CSV in outputs/ as Markdown table JSON."""
259-
if not filename.endswith(".csv"):
260-
filename += ".csv"
261-
262-
path = output_file(filename, make_parents=False)
263-
if not path.exists():
264-
return json.dumps({"error": "file not found", "file": filename})
265-
266-
try:
267-
df = pd.read_csv(path).tail(n_rows)
268-
except Exception as e:
269-
return json.dumps({"error": str(e), "file": filename})
270-
271-
table_md = df.to_markdown(index=False)
272-
return json.dumps({"file": filename, "preview_markdown": table_md})
273-
274265
@function_tool
275266
def list_output_files(extension: str = None) -> str:
276267
"""
@@ -289,8 +280,7 @@ def list_output_files(extension: str = None) -> str:
289280
__all__ = [
290281
"run_code_interpreter",
291282
"write_markdown",
292-
"read_markdown",
293283
"get_fred_series",
294-
"read_csv_preview",
295284
"list_output_files",
285+
"read_file",
296286
]

0 commit comments

Comments
 (0)