Spaces:
Sleeping
Sleeping
File size: 5,330 Bytes
3af908f 8eabc3b ee8c58d 4a95c80 8eabc3b ee8c58d 3af908f 3da4c60 8eabc3b 3af908f 8eabc3b 75f03cb 3af908f 75f03cb 3af908f 75f03cb 3da4c60 e340c1f 3da4c60 e340c1f 3da4c60 75f03cb 1bfda6d 8eabc3b 3af908f 4879dd8 75f03cb 4879dd8 3af908f 4879dd8 3af908f 4879dd8 75f03cb 4879dd8 8eabc3b 3af908f 4879dd8 8eabc3b 3af908f 4a95c80 4879dd8 8eabc3b 3af908f 8eabc3b 4879dd8 8eabc3b 4879dd8 8eabc3b 4879dd8 3af908f 4879dd8 8eabc3b 3af908f 4879dd8 3af908f 4879dd8 3af908f 4879dd8 3af908f 3da4c60 8eabc3b 3af908f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | """Run the smolagents CodeAgent with all GAIA tools."""
from __future__ import annotations
import os
from pathlib import Path
from dotenv import load_dotenv
from smolagents import CodeAgent
load_dotenv()
from agent.tools import build_agent_tools
from agent.think_mode import should_use_think_mode
from model_provider import (
apply_think_mode,
build_model,
get_llm_provider,
supports_think_toggle,
use_markdown_code_blocks,
)
from provider_chain import ProviderFallbackModel
MAX_STEPS = int(os.getenv("AGENT_MAX_STEPS", "12"))
GAIA_SYSTEM_PROMPT = """
You are a general AI assistant solving GAIA Level 1 questions.
Use tools and Python code whenever needed:
- web search or Wikipedia for factual questions
- arxiv_search for academic papers
- file tools for attachments (PDF, Excel, CSV, images, audio)
- get_youtube_transcript for YouTube links
- execute_code for local Python or bash computation
Research tips:
- Prefer wikipedia_search() over visiting wikipedia.org URLs
- For discography counts, use wikipedia_studio_albums(title, start_year, end_year)
- Use web_search() snippets first; only visit_webpage() when snippets lack the fact
- Do not fetch Wikipedia API URLs manually or json.loads() tool output — use Wikipedia tools
- Never fetch github.com blob or raw JSON pages — they are not useful
- Keep tool use efficient: aim to answer in 3–5 steps when possible
Every action must be valid Python inside a code block.
When done, call final_answer("...") with ONLY the answer value.
Answer formatting rules (critical):
- Return a number, as few words as possible, or a comma-separated list
- Numbers: no commas in the number; no $ or % unless the question asks for them
- Strings: no articles; no abbreviations unless specified
- Lists: apply the same rules to each item
- Do NOT pass "FINAL ANSWER:" into final_answer()
- Do NOT add explanations, markdown, or extra punctuation
Examples:
- Question asks for a count -> final_answer("3")
- Question asks for a name -> final_answer("Smith")
- Question asks for a list -> final_answer("a, b, c") with a comma and space between items
""".strip()
def build_prompt(
question: str,
file_path: str | None,
file_error: str | None = None,
extra_sections: str | None = None,
) -> str:
parts = [question]
if file_path:
path = Path(file_path)
suffix = path.suffix.lower()
attachment_hint = {
".py": "A Python file is attached. Use read_text_file, then run or reason over it.",
".xlsx": "An Excel file is attached. Use read_excel_summary.",
".xls": "An Excel file is attached. Use read_excel_summary.",
".csv": "A CSV file is attached. Use analyze_csv_file.",
".pdf": "A PDF file is attached. Use read_pdf.",
".mp3": "An audio file is attached. Use transcribe_audio.",
".wav": "An audio file is attached. Use transcribe_audio.",
".png": "An image file is attached. Use describe_image or extract_text_from_image.",
".jpg": "An image file is attached. Use describe_image or extract_text_from_image.",
".jpeg": "An image file is attached. Use describe_image or extract_text_from_image.",
".webp": "An image file is attached. Use describe_image or extract_text_from_image.",
}.get(suffix, "A file is attached. Use the appropriate reading tool.")
parts.extend([attachment_hint, f"Attached file path: {path.resolve()}"])
elif file_error:
parts.append(
"Note: the benchmark file attachment could not be loaded "
f"({file_error}). Answer using web search and other tools instead."
)
if extra_sections:
parts.append(extra_sections)
return "\n\n".join(parts)
class AgentRunner:
def __init__(self):
model = build_model()
code_block_tags = "markdown" if use_markdown_code_blocks() else None
self.agent = CodeAgent(
tools=build_agent_tools(),
model=model,
instructions=GAIA_SYSTEM_PROMPT,
max_steps=MAX_STEPS,
verbosity_level=1,
code_block_tags=code_block_tags,
additional_authorized_imports=[
"requests",
"re",
"json",
"math",
"statistics",
"datetime",
"collections",
"itertools",
"pandas",
"numpy",
],
)
print(
f"AgentRunner ready ({get_llm_provider()}, "
f"code_blocks={'markdown' if code_block_tags else 'xml'})"
)
def run(
self,
prompt: str,
question: str | None = None,
file_path: str | None = None,
think: bool | None = None,
) -> str:
if think is None and question is not None:
think = should_use_think_mode(question, file_path)
if think is not None and supports_think_toggle():
apply_think_mode(self.agent.model, think)
model = self.agent.model
if isinstance(model, ProviderFallbackModel):
model.reset_for_question()
print(f"Running agent on question (first 80 chars): {prompt[:80]}...")
return str(self.agent.run(prompt))
|