Bharadwaj-m7 commited on
Commit
d0abc85
·
verified ·
1 Parent(s): f15c873

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +409 -180
app.py CHANGED
@@ -1,196 +1,425 @@
 
 
 
 
 
 
 
 
 
1
  import os
2
  import gradio as gr
3
- import requests
4
- import inspect
5
- import pandas as pd
6
-
7
- # (Keep Constants as is)
8
- # --- Constants ---
9
- DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
10
-
11
- # --- Basic Agent Definition ---
12
- # ----- THIS IS WERE YOU CAN BUILD WHAT YOU WANT ------
13
- class BasicAgent:
14
- def __init__(self):
15
- print("BasicAgent initialized.")
16
- def __call__(self, question: str) -> str:
17
- print(f"Agent received question (first 50 chars): {question[:50]}...")
18
- fixed_answer = "This is a default answer."
19
- print(f"Agent returning fixed answer: {fixed_answer}")
20
- return fixed_answer
21
-
22
- def run_and_submit_all( profile: gr.OAuthProfile | None):
23
- """
24
- Fetches all questions, runs the BasicAgent on them, submits all answers,
25
- and displays the results.
26
- """
27
- # --- Determine HF Space Runtime URL and Repo URL ---
28
- space_id = os.getenv("SPACE_ID") # Get the SPACE_ID for sending link to the code
29
-
30
- if profile:
31
- username= f"{profile.username}"
32
- print(f"User logged in: {username}")
33
- else:
34
- print("User not logged in.")
35
- return "Please Login to Hugging Face with the button.", None
36
-
37
- api_url = DEFAULT_API_URL
38
- questions_url = f"{api_url}/questions"
39
- submit_url = f"{api_url}/submit"
40
-
41
- # 1. Instantiate Agent ( modify this part to create your agent)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  try:
43
- agent = BasicAgent()
 
 
 
 
 
 
 
44
  except Exception as e:
45
- print(f"Error instantiating agent: {e}")
46
- return f"Error initializing agent: {e}", None
47
- # In the case of an app running as a hugging Face space, this link points toward your codebase ( usefull for others so please keep it public)
48
- agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
49
- print(agent_code)
50
-
51
- # 2. Fetch Questions
52
- print(f"Fetching questions from: {questions_url}")
53
  try:
54
- response = requests.get(questions_url, timeout=15)
55
- response.raise_for_status()
56
- questions_data = response.json()
57
- if not questions_data:
58
- print("Fetched questions list is empty.")
59
- return "Fetched questions list is empty or invalid format.", None
60
- print(f"Fetched {len(questions_data)} questions.")
61
- except requests.exceptions.RequestException as e:
62
- print(f"Error fetching questions: {e}")
63
- return f"Error fetching questions: {e}", None
64
- except requests.exceptions.JSONDecodeError as e:
65
- print(f"Error decoding JSON response from questions endpoint: {e}")
66
- print(f"Response text: {response.text[:500]}")
67
- return f"Error decoding server response for questions: {e}", None
68
  except Exception as e:
69
- print(f"An unexpected error occurred fetching questions: {e}")
70
- return f"An unexpected error occurred fetching questions: {e}", None
71
-
72
- # 3. Run your Agent
73
- results_log = []
74
- answers_payload = []
75
- print(f"Running agent on {len(questions_data)} questions...")
76
- for item in questions_data:
77
- task_id = item.get("task_id")
78
- question_text = item.get("question")
79
- if not task_id or question_text is None:
80
- print(f"Skipping item with missing task_id or question: {item}")
81
- continue
82
- try:
83
- submitted_answer = agent(question_text)
84
- answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
85
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
86
- except Exception as e:
87
- print(f"Error running agent on task {task_id}: {e}")
88
- results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
89
-
90
- if not answers_payload:
91
- print("Agent did not produce any answers to submit.")
92
- return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
93
-
94
- # 4. Prepare Submission
95
- submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
96
- status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
97
- print(status_update)
98
-
99
- # 5. Submit
100
- print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
101
  try:
102
- response = requests.post(submit_url, json=submission_data, timeout=60)
103
- response.raise_for_status()
104
- result_data = response.json()
105
- final_status = (
106
- f"Submission Successful!\n"
107
- f"User: {result_data.get('username')}\n"
108
- f"Overall Score: {result_data.get('score', 'N/A')}% "
109
- f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"
110
- f"Message: {result_data.get('message', 'No message received.')}"
111
  )
112
- print("Submission successful.")
113
- results_df = pd.DataFrame(results_log)
114
- return final_status, results_df
115
- except requests.exceptions.HTTPError as e:
116
- error_detail = f"Server responded with status {e.response.status_code}."
117
- try:
118
- error_json = e.response.json()
119
- error_detail += f" Detail: {error_json.get('detail', e.response.text)}"
120
- except requests.exceptions.JSONDecodeError:
121
- error_detail += f" Response: {e.response.text[:500]}"
122
- status_message = f"Submission Failed: {error_detail}"
123
- print(status_message)
124
- results_df = pd.DataFrame(results_log)
125
- return status_message, results_df
126
- except requests.exceptions.Timeout:
127
- status_message = "Submission Failed: The request timed out."
128
- print(status_message)
129
- results_df = pd.DataFrame(results_log)
130
- return status_message, results_df
131
- except requests.exceptions.RequestException as e:
132
- status_message = f"Submission Failed: Network error - {e}"
133
- print(status_message)
134
- results_df = pd.DataFrame(results_log)
135
- return status_message, results_df
136
  except Exception as e:
137
- status_message = f"An unexpected error occurred during submission: {e}"
138
- print(status_message)
139
- results_df = pd.DataFrame(results_log)
140
- return status_message, results_df
141
-
142
-
143
- # --- Build Gradio Interface using Blocks ---
144
- with gr.Blocks() as demo:
145
- gr.Markdown("# Basic Agent Evaluation Runner")
146
- gr.Markdown(
147
- """
148
- **Instructions:**
149
-
150
- 1. Please clone this space, then modify the code to define your agent's logic, the tools, the necessary packages, etc ...
151
- 2. Log in to your Hugging Face account using the button below. This uses your HF username for submission.
152
- 3. Click 'Run Evaluation & Submit All Answers' to fetch questions, run your agent, submit answers, and see the score.
153
-
154
- ---
155
- **Disclaimers:**
156
- Once clicking on the "submit button, it can take quite some time ( this is the time for the agent to go through all the questions).
157
- This space provides a basic setup and is intentionally sub-optimal to encourage you to develop your own, more robust solution. For instance for the delay process of the submit button, a solution could be to cache the answers and submit in a seperate action or even to answer the questions in async.
158
- """
159
- )
160
 
161
- gr.LoginButton()
 
 
 
 
162
 
163
- run_button = gr.Button("Run Evaluation & Submit All Answers")
 
164
 
165
- status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
166
- # Removed max_rows=10 from DataFrame constructor
167
- results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
168
 
169
- run_button.click(
170
- fn=run_and_submit_all,
171
- outputs=[status_output, results_table]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
172
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
173
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
174
  if __name__ == "__main__":
175
- print("\n" + "-"*30 + " App Starting " + "-"*30)
176
- # Check for SPACE_HOST and SPACE_ID at startup for information
177
- space_host_startup = os.getenv("SPACE_HOST")
178
- space_id_startup = os.getenv("SPACE_ID") # Get SPACE_ID at startup
179
-
180
- if space_host_startup:
181
- print(f"✅ SPACE_HOST found: {space_host_startup}")
182
- print(f" Runtime URL should be: https://{space_host_startup}.hf.space")
183
- else:
184
- print("ℹ️ SPACE_HOST environment variable not found (running locally?).")
185
-
186
- if space_id_startup: # Print repo URLs if SPACE_ID is found
187
- print(f" SPACE_ID found: {space_id_startup}")
188
- print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")
189
- print(f" Repo Tree URL: https://huggingface.co/spaces/{space_id_startup}/tree/main")
190
- else:
191
- print("ℹ️ SPACE_ID environment variable not found (running locally?). Repo URL cannot be determined.")
192
-
193
- print("-"*(60 + len(" App Starting ")) + "\n")
194
-
195
- print("Launching Gradio Interface for Basic Agent Evaluation...")
196
- demo.launch(debug=True, share=False)
 
 
 
1
+ """
2
+ LangChain Agent with Tools Workflow, Search, and Llama Models
3
+ This application demonstrates a sophisticated agent using LangChain with:
4
+ - Llama models via Ollama
5
+ - Multiple tools (calculator, search, Wikipedia, etc.)
6
+ - Tool workflow and reasoning
7
+ - Gradio interface for interaction
8
+ """
9
+
10
  import os
11
  import gradio as gr
12
+ from typing import List, Dict, Any, Optional
13
+ from datetime import datetime
14
+ import math
15
+
16
+ # LangChain imports
17
+ from langchain.agents import AgentExecutor, create_tool_calling_agent, Tool
18
+ from langchain.tools import StructuredTool
19
+ from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
20
+ from langchain.memory import ConversationBufferMemory
21
+ from langchain_community.llms import Ollama
22
+ from langchain_community.tools import DuckDuckGoSearchRun, WikipediaQueryRun
23
+ from langchain_community.utilities import WikipediaAPIWrapper
24
+
25
+ # --- Configuration ---
26
+ DEFAULT_MODEL = "llama2" # Can be changed to llama3, mistral, etc.
27
+ DEFAULT_TEMPERATURE = 0.7
28
+ DEFAULT_MAX_TOKENS = 2000
29
+
30
+ # --- Calculator Tools ---
31
+ def calculator_add(a: float, b: float) -> str:
32
+ """Add two numbers together."""
33
+ result = a + b
34
+ return f"The sum of {a} and {b} is {result}"
35
+
36
+ def calculator_subtract(a: float, b: float) -> str:
37
+ """Subtract second number from first."""
38
+ result = a - b
39
+ return f"The difference between {a} and {b} is {result}"
40
+
41
+ def calculator_multiply(a: float, b: float) -> str:
42
+ """Multiply two numbers."""
43
+ result = a * b
44
+ return f"The product of {a} and {b} is {result}"
45
+
46
+ def calculator_divide(a: float, b: float) -> str:
47
+ """Divide first number by second."""
48
+ if b == 0:
49
+ return "Error: Cannot divide by zero"
50
+ result = a / b
51
+ return f"{a} divided by {b} is {result}"
52
+
53
+ def calculator_power(a: float, b: float) -> str:
54
+ """Calculate a to the power of b."""
55
+ result = a ** b
56
+ return f"{a} to the power of {b} is {result}"
57
+
58
+ def calculator_sqrt(x: float) -> str:
59
+ """Calculate square root of a number."""
60
+ if x < 0:
61
+ return "Error: Cannot calculate square root of negative number"
62
+ result = math.sqrt(x)
63
+ return f"The square root of {x} is {result}"
64
+
65
+ def calculator_average(numbers: str) -> str:
66
+ """Calculate average of comma-separated numbers."""
67
+ try:
68
+ nums = [float(n.strip()) for n in numbers.split(',')]
69
+ if not nums:
70
+ return "Error: No numbers provided"
71
+ result = sum(nums) / len(nums)
72
+ return f"The average of {nums} is {result}"
73
+ except ValueError:
74
+ return "Error: Invalid number format. Use comma-separated numbers like '1, 2, 3, 4'"
75
+
76
+ # --- String Tools ---
77
+ def text_uppercase(text: str) -> str:
78
+ """Convert text to uppercase."""
79
+ return text.upper()
80
+
81
+ def text_lowercase(text: str) -> str:
82
+ """Convert text to lowercase."""
83
+ return text.lower()
84
+
85
+ def text_reverse(text: str) -> str:
86
+ """Reverse a string."""
87
+ return text[::-1]
88
+
89
+ def text_word_count(text: str) -> str:
90
+ """Count words in text."""
91
+ words = text.split()
92
+ return f"The text contains {len(words)} words"
93
+
94
+ def text_char_count(text: str) -> str:
95
+ """Count characters in text."""
96
+ return f"The text contains {len(text)} characters"
97
+
98
+ # --- Utility Tools ---
99
+ def get_current_time() -> str:
100
+ """Get current date and time."""
101
+ return datetime.now().strftime("%Y-%m-%d %H:%M:%S")
102
+
103
+ def get_current_date() -> str:
104
+ """Get current date."""
105
+ return datetime.now().strftime("%Y-%m-%d")
106
+
107
+ # --- Initialize Tools ---
108
+ def initialize_tools() -> List[Tool]:
109
+ """Initialize all available tools for the agent."""
110
+
111
+ # Calculator tools
112
+ tools = [
113
+ Tool(
114
+ name="add",
115
+ func=calculator_add,
116
+ description="Add two numbers together. Input: two numbers separated by space or comma."
117
+ ),
118
+ Tool(
119
+ name="subtract",
120
+ func=calculator_subtract,
121
+ description="Subtract second number from first. Input: two numbers separated by space or comma."
122
+ ),
123
+ Tool(
124
+ name="multiply",
125
+ func=calculator_multiply,
126
+ description="Multiply two numbers together. Input: two numbers separated by space or comma."
127
+ ),
128
+ Tool(
129
+ name="divide",
130
+ func=calculator_divide,
131
+ description="Divide first number by second. Input: two numbers separated by space or comma."
132
+ ),
133
+ Tool(
134
+ name="power",
135
+ func=calculator_power,
136
+ description="Calculate a to the power of b. Input: two numbers separated by space or comma."
137
+ ),
138
+ Tool(
139
+ name="sqrt",
140
+ func=calculator_sqrt,
141
+ description="Calculate square root of a number. Input: a single number."
142
+ ),
143
+ Tool(
144
+ name="average",
145
+ func=calculator_average,
146
+ description="Calculate average of multiple numbers. Input: comma-separated numbers like '1, 2, 3, 4'."
147
+ ),
148
+
149
+ # String tools
150
+ Tool(
151
+ name="uppercase",
152
+ func=text_uppercase,
153
+ description="Convert text to uppercase. Input: the text to convert."
154
+ ),
155
+ Tool(
156
+ name="lowercase",
157
+ func=text_lowercase,
158
+ description="Convert text to lowercase. Input: the text to convert."
159
+ ),
160
+ Tool(
161
+ name="reverse",
162
+ func=text_reverse,
163
+ description="Reverse a string. Input: the text to reverse."
164
+ ),
165
+ Tool(
166
+ name="word_count",
167
+ func=text_word_count,
168
+ description="Count words in text. Input: the text to analyze."
169
+ ),
170
+ Tool(
171
+ name="char_count",
172
+ func=text_char_count,
173
+ description="Count characters in text. Input: the text to analyze."
174
+ ),
175
+
176
+ # Utility tools
177
+ Tool(
178
+ name="current_time",
179
+ func=get_current_time,
180
+ description="Get current date and time. No input needed."
181
+ ),
182
+ Tool(
183
+ name="current_date",
184
+ func=get_current_date,
185
+ description="Get current date. No input needed."
186
+ ),
187
+ ]
188
+
189
+ # Search tools
190
  try:
191
+ search = DuckDuckGoSearchRun()
192
+ tools.append(
193
+ Tool(
194
+ name="search",
195
+ func=search.run,
196
+ description="Search the web for current information using DuckDuckGo. Input: search query."
197
+ )
198
+ )
199
  except Exception as e:
200
+ print(f"Warning: Could not initialize DuckDuckGo search: {e}")
201
+
202
+ # Wikipedia tool
 
 
 
 
 
203
  try:
204
+ wikipedia = WikipediaQueryRun(api_wrapper=WikipediaAPIWrapper())
205
+ tools.append(
206
+ Tool(
207
+ name="wikipedia",
208
+ func=wikipedia.run,
209
+ description="Search Wikipedia for encyclopedic information. Input: search query."
210
+ )
211
+ )
 
 
 
 
 
 
212
  except Exception as e:
213
+ print(f"Warning: Could not initialize Wikipedia search: {e}")
214
+
215
+ return tools
216
+
217
+ # --- Agent Initialization ---
218
+ def create_agent(model_name: str = DEFAULT_MODEL, temperature: float = DEFAULT_TEMPERATURE):
219
+ """Create a LangChain agent with tools."""
220
+
221
+ # Initialize LLM with Ollama (Llama models)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
222
  try:
223
+ llm = Ollama(
224
+ model=model_name,
225
+ temperature=temperature,
226
+ num_predict=DEFAULT_MAX_TOKENS
 
 
 
 
 
227
  )
228
+ print(f" Successfully initialized Ollama with model: {model_name}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
229
  except Exception as e:
230
+ print(f" Error initializing Ollama: {e}")
231
+ print("Make sure Ollama is installed and running. Visit: https://ollama.ai")
232
+ raise
233
+
234
+ # Initialize tools
235
+ tools = initialize_tools()
236
+ print(f"✅ Initialized {len(tools)} tools")
237
+
238
+ # Create prompt template
239
+ prompt = ChatPromptTemplate.from_messages([
240
+ ("system", """You are a helpful AI assistant with access to various tools.
241
+ You can perform calculations, search the web, look up information on Wikipedia, and manipulate text.
 
 
 
 
 
 
 
 
 
 
 
242
 
243
+ When answering questions:
244
+ 1. Think about which tool(s) you need to use
245
+ 2. Use the tools to gather information
246
+ 3. Provide a clear, helpful response based on the tool results
247
+ 4. If you don't have enough information, ask for clarification
248
 
249
+ Available tools:
250
+ {tools}
251
 
252
+ Tool names: {tool_names}
 
 
253
 
254
+ Remember to be helpful, accurate, and concise in your responses."""),
255
+ MessagesPlaceholder(variable_name="chat_history", optional=True),
256
+ ("human", "{input}"),
257
+ MessagesPlaceholder(variable_name="agent_scratchpad"),
258
+ ])
259
+
260
+ # Create agent
261
+ agent = create_tool_calling_agent(llm, tools, prompt)
262
+
263
+ # Create agent executor
264
+ agent_executor = AgentExecutor(
265
+ agent=agent,
266
+ tools=tools,
267
+ verbose=True,
268
+ handle_parsing_errors=True,
269
+ max_iterations=10,
270
+ early_stopping_method="generate"
271
  )
272
+
273
+ return agent_executor
274
+
275
+ # --- Global Agent Instance ---
276
+ agent_executor = None
277
+
278
+ def initialize_global_agent(model_name: str = DEFAULT_MODEL):
279
+ """Initialize the global agent instance."""
280
+ global agent_executor
281
+ try:
282
+ agent_executor = create_agent(model_name)
283
+ return True, f"✅ Agent initialized successfully with model: {model_name}"
284
+ except Exception as e:
285
+ return False, f"❌ Error initializing agent: {str(e)}"
286
+
287
+ # --- Query Function ---
288
+ def query_agent(question: str, model_name: str = DEFAULT_MODEL) -> str:
289
+ """Query the agent with a question."""
290
+ global agent_executor
291
+
292
+ # Reinitialize if model changed or agent not initialized
293
+ if agent_executor is None:
294
+ success, message = initialize_global_agent(model_name)
295
+ if not success:
296
+ return message
297
+
298
+ try:
299
+ print(f"\n{'='*60}")
300
+ print(f"Query: {question}")
301
+ print(f"{'='*60}\n")
302
+
303
+ result = agent_executor.invoke({"input": question})
304
+ response = result.get("output", "No response generated")
305
+
306
+ print(f"\n{'='*60}")
307
+ print(f"Response: {response}")
308
+ print(f"{'='*60}\n")
309
+
310
+ return response
311
+ except Exception as e:
312
+ error_msg = f"Error processing query: {str(e)}"
313
+ print(f"❌ {error_msg}")
314
+ return error_msg
315
 
316
+ # --- Gradio Interface ---
317
+ def create_interface():
318
+ """Create the Gradio interface."""
319
+
320
+ with gr.Blocks(title="LangChain Agent with Llama Models") as demo:
321
+ gr.Markdown("# 🤖 LangChain Agent with Llama Models")
322
+ gr.Markdown("""
323
+ This agent uses **LangChain** with **Llama models** (via Ollama) and a comprehensive set of tools.
324
+
325
+ ## Features:
326
+ - **Calculator Tools**: Add, subtract, multiply, divide, power, square root, average
327
+ - **String Tools**: Uppercase, lowercase, reverse, word count, character count
328
+ - **Search Tools**: DuckDuckGo web search, Wikipedia lookup
329
+ - **Utility Tools**: Current time, current date
330
+
331
+ ## Requirements:
332
+ - Install Ollama from [ollama.ai](https://ollama.ai)
333
+ - Pull a Llama model: `ollama pull llama2` or `ollama pull llama3`
334
+ - Make sure Ollama is running: `ollama serve`
335
+ """)
336
+
337
+ with gr.Row():
338
+ with gr.Column(scale=1):
339
+ model_input = gr.Dropdown(
340
+ choices=["llama2", "llama3", "llama3:8b", "mistral", "codellama"],
341
+ value="llama2",
342
+ label="Select Model",
343
+ info="Choose the Llama model to use"
344
+ )
345
+ init_btn = gr.Button("Initialize Agent", variant="primary")
346
+ status_output = gr.Textbox(label="Status", interactive=False)
347
+
348
+ with gr.Column(scale=2):
349
+ question_input = gr.Textbox(
350
+ label="Your Question",
351
+ placeholder="Ask me anything... e.g., 'What is 25 * 4?' or 'Search for information about Python'",
352
+ lines=3
353
+ )
354
+ submit_btn = gr.Button("Ask Agent", variant="primary")
355
+ response_output = gr.Textbox(
356
+ label="Agent Response",
357
+ lines=10,
358
+ interactive=False
359
+ )
360
+
361
+ # Examples
362
+ gr.Examples(
363
+ examples=[
364
+ ["What is 15 * 7?"],
365
+ ["Calculate the square root of 144"],
366
+ ["What is the average of 10, 20, 30, 40, 50?"],
367
+ ["Convert 'hello world' to uppercase"],
368
+ ["How many words are in this sentence?"],
369
+ ["What is the current time?"],
370
+ ["Search for information about artificial intelligence"],
371
+ ["Look up Python programming on Wikipedia"],
372
+ ["What is 2 to the power of 10?"],
373
+ ["Reverse the string 'LangChain'"],
374
+ ],
375
+ inputs=question_input,
376
+ label="Example Questions"
377
+ )
378
+
379
+ # Event handlers
380
+ init_btn.click(
381
+ fn=initialize_global_agent,
382
+ inputs=[model_input],
383
+ outputs=[status_output]
384
+ )
385
+
386
+ submit_btn.click(
387
+ fn=query_agent,
388
+ inputs=[question_input, model_input],
389
+ outputs=[response_output]
390
+ )
391
+
392
+ question_input.submit(
393
+ fn=query_agent,
394
+ inputs=[question_input, model_input],
395
+ outputs=[response_output]
396
+ )
397
+
398
+ return demo
399
+
400
+ # --- Main ---
401
  if __name__ == "__main__":
402
+ print("\n" + "="*60)
403
+ print("LangChain Agent with Llama Models")
404
+ print("="*60 + "\n")
405
+
406
+ # Check if Ollama is available
407
+ try:
408
+ import ollama
409
+ models = ollama.list()
410
+ print(f"✅ Ollama is running")
411
+ print(f"Available models: {[m['name'] for m in models.get('models', [])]}")
412
+ except Exception as e:
413
+ print(f"⚠️ Warning: Could not connect to Ollama: {e}")
414
+ print("Please make sure Ollama is installed and running:")
415
+ print(" 1. Install from https://ollama.ai")
416
+ print(" 2. Run: ollama pull llama2")
417
+ print(" 3. Run: ollama serve")
418
+
419
+ print("\nInitializing agent...")
420
+ success, message = initialize_global_agent()
421
+ print(message)
422
+
423
+ print("\nLaunching Gradio interface...")
424
+ demo = create_interface()
425
+ demo.launch(share=False, debug=True)