"""Public course agent. Research tools generate answers without answer tables.""" import os import requests import xml.etree.ElementTree as ET from smolagents import ToolCallingAgent, InferenceClientModel, tool @tool def web_search(query: str) -> str: """Search the web. Rejects irrelevant search responses. Args: query: Specific search terms. """ import re errors=[] terms={w for w in re.findall(r'[a-z0-9]+',query.lower()) if len(w)>3} def relevant(text): return len(terms & set(re.findall(r'[a-z0-9]+',text.lower()))) >= min(2,len(terms)) try: from ddgs import DDGS results=list(DDGS(timeout=15).text(query,backend='google',max_results=6)) good=[r for r in results if relevant(str(r))] if good: return str(good)[:14000] except Exception as e: errors.append(type(e).__name__) try: import time r=requests.get('https://www.bing.com/search',params={'q':query,'format':'rss','_':str(time.time_ns())},headers={'Cache-Control':'no-cache'},timeout=20) r.raise_for_status() items=ET.fromstring(r.text).findall('.//item') rows=[item.findtext('title','')+' '+item.findtext('link','')+' '+item.findtext('description','') for item in items] good=[row for row in rows if relevant(row)] if good: return '\n'.join(good[:6])[:14000] except Exception as e: errors.append(type(e).__name__) return 'No relevant search results. Use a direct known authoritative source URL instead. '+str(errors) @tool def visit_webpage(url: str) -> str: """Read a public source webpage as text, with a public text-reader fallback. Args: url: Public HTTPS webpage URL. """ from bs4 import BeautifulSoup for target in [url, 'https://r.jina.ai/'+url]: try: r=requests.get(target,timeout=35) r.raise_for_status() if 'r.jina.ai/' in target: return r.text[:35000] soup=BeautifulSoup(r.text,'html.parser') for tag in soup(['script','style','nav','footer']): tag.decompose() text=soup.get_text(' ',strip=True) if len(text)>200: return text[:35000] except requests.RequestException: pass return 'Source unavailable. Do not treat an error page as evidence.' @tool def guest_search(query: str) -> str: """Retrieve relevant public gala guest records for the Unit 3 use case. Args: query: Guest name or topic to search for. """ from datasets import load_dataset records=load_dataset('agents-course/unit3-invitees',split='train') terms=set(query.lower().split()) ranked=sorted(records,key=lambda r:len(terms & set(str(r).lower().split())),reverse=True) return str(ranked[:3]) def build_agent(use_case=False): token=os.environ.get('HF_TOKEN') if not token: raise RuntimeError('Add HF_TOKEN to Space secrets.') model=InferenceClientModel(token=token,provider='cerebras',max_tokens=4096,model_id='openai/gpt-oss-120b') tools=[web_search,visit_webpage] if use_case: tools.append(guest_search) return ToolCallingAgent(tools=tools,model=model,max_steps=10) def answer(agent,question): instruction='\nReturn only the exact answer requested, without a FINAL ANSWER prefix or explanation. Use source evidence for research questions. Never claim to have read a source that failed. If the task requires unavailable media or evidence, return an empty string rather than fabricate. Solve the entire requested task, not an intermediate transformation. Verify your conclusion against every constraint in the question before final_answer. Stop repeating failed searches. Prefer direct Wikipedia or primary webpages when search is irrelevant. Finish by calling final_answer with the answer only. Keep tool output concise.' return str(agent.run(question+instruction,reset=True)).strip()