kamorou commited on
Commit
06ef7bb
·
verified ·
1 Parent(s): d21ab3f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +109 -0
app.py CHANGED
@@ -11,6 +11,115 @@ import pandas as pd
11
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
12
 
13
  # --- Basic Agent Definition ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  class BasicAgent:
15
  """
16
  This is the agent class that the GAIA test harness will use.
 
11
  DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
12
 
13
  # --- Basic Agent Definition ---
14
+ # ==============================================================================
15
+ # 1. IMPORTS AND SETUP
16
+ # ==============================================================================
17
+ import os
18
+ from dotenv import load_dotenv
19
+ from typing import TypedDict, Annotated, List
20
+
21
+ # LangChain and LangGraph imports
22
+ from langchain_huggingface import HuggingFaceEndpoint
23
+ from langchain_community.tools.tavily_search import TavilySearchResults
24
+ from langchain_experimental.tools import PythonREPLTool
25
+ from langchain_core.messages import BaseMessage, HumanMessage
26
+ from langchain_core.prompts import ChatPromptTemplate
27
+ from langgraph.graph import StateGraph, END
28
+ from langgraph.prebuilt import ToolNode
29
+
30
+ # ==============================================================================
31
+ # 2. LOAD API KEYS AND DEFINE TOOLS
32
+ # ==============================================================================
33
+ load_dotenv()
34
+ hf_token = os.getenv("HF_TOKEN")
35
+ tavily_api_key = os.getenv("TAVILY_API_KEY")
36
+
37
+ if not hf_token or not tavily_api_key:
38
+ # This will show a clear error in the logs if keys are missing
39
+ raise ValueError("HF_TOKEN or TAVILY_API_KEY not set. Please add them to your Space secrets.")
40
+ os.environ["TAVILY_API_KEY"] = tavily_api_key
41
+
42
+ # The agent's tools
43
+ tools = [TavilySearchResults(max_results=3, description="A search engine for finding up-to-date information on the web."), PythonREPLTool()]
44
+ tool_node = ToolNode(tools)
45
+
46
+ # ==============================================================================
47
+ # 3. CONFIGURE THE LLM (THE "BRAIN")
48
+ # ==============================================================================
49
+ # The model we'll use as the agent's brain
50
+ repo_id = "meta-llama/Meta-Llama-3-8B-Instruct"
51
+
52
+ # The system prompt gives the agent its mission and instructions
53
+ SYSTEM_PROMPT = """You are a highly capable AI agent named 'GAIA-Solver'. Your mission is to accurately answer complex questions.
54
+ **Your Instructions:**
55
+ 1. **Analyze:** Carefully read the user's question to understand all parts of what is being asked.
56
+ 2. **Plan:** Think step-by-step. Break the problem into smaller tasks. Decide which tool is best for each task. (e.g., use 'tavily_search_results_json' for web searches, use 'python_repl' for calculations or code execution).
57
+ 3. **Execute:** Call ONE tool at a time.
58
+ 4. **Observe & Reason:** After getting a tool's result, observe it. Decide if you have the final answer or if you need to use another tool.
59
+ 5. **Final Answer:** Once you are confident, provide a clear, direct, and concise final answer. Do not include your thought process in the final answer.
60
+ """
61
+
62
+ # Initialize the LLM endpoint
63
+ llm = HuggingFaceEndpoint(
64
+ repo_id=repo_id,
65
+ huggingfacehub_api_token=hf_token,
66
+ temperature=0, # Set to 0 for deterministic, less random output
67
+ max_new_tokens=2048,
68
+ )
69
+
70
+ # ==============================================================================
71
+ # 4. BUILD THE LANGGRAPH AGENT
72
+ # ==============================================================================
73
+
74
+ # Define the Agent's State (its memory)
75
+ class AgentState(TypedDict):
76
+ messages: Annotated[List[BaseMessage], lambda x, y: x + y]
77
+
78
+ # This is a more robust way to combine the prompt, model, and tool binding
79
+ # It ensures the system prompt is always used.
80
+ llm_with_tools = llm.bind_tools(tools)
81
+
82
+ # Define the Agent Node
83
+ def agent_node(state):
84
+ # Get the last message to pass to the model
85
+ last_message = state['messages'][-1]
86
+
87
+ # Prepend the system prompt to every call
88
+ prompt_with_system = [
89
+ HumanMessage(content=SYSTEM_PROMPT, name="system_prompt"),
90
+ last_message
91
+ ]
92
+
93
+ response = llm_with_tools.invoke(prompt_with_system)
94
+ return {"messages": [response]}
95
+
96
+ # Define the Edge Logic
97
+ def should_continue(state):
98
+ last_message = state["messages"][-1]
99
+ if last_message.tool_calls:
100
+ return "tools" # Route to the tool node
101
+ return END # End the process
102
+
103
+ # Assemble the graph
104
+ workflow = StateGraph(AgentState)
105
+ workflow.add_node("agent", agent_node)
106
+ workflow.add_node("tools", tool_node)
107
+ workflow.set_entry_point("agent")
108
+ workflow.add_conditional_edges(
109
+ "agent",
110
+ should_continue,
111
+ {"tools": "tools", "end": END},
112
+ )
113
+ workflow.add_edge("tools", "agent")
114
+
115
+ # Compile the graph into a runnable app
116
+ app = workflow.compile()
117
+
118
+
119
+ # ==============================================================================
120
+ # 5. THE BASICAGENT CLASS (FOR THE TEST HARNESS)
121
+ # This MUST be at the end, after `app` is defined.
122
+ # ==============================================================================
123
  class BasicAgent:
124
  """
125
  This is the agent class that the GAIA test harness will use.