dennis111 commited on
Commit
c5185b5
·
1 Parent(s): 9249994
Files changed (6) hide show
  1. agent.py +19 -21
  2. app.py +8 -23
  3. app_legacy.py +218 -0
  4. app_playground.ipynb +113 -6
  5. requirements.txt +3 -2
  6. test.py +0 -1
agent.py CHANGED
@@ -1,14 +1,17 @@
 
1
  import os
2
  from langchain.chat_models import init_chat_model
3
  from langchain_core.messages import HumanMessage, SystemMessage, AIMessage, AnyMessage
4
- from langgraph.graph import add_messages
 
5
 
6
  from typing_extensions import TypedDict, Annotated
7
 
8
 
9
  class State(TypedDict):
10
  messages: Annotated[list, add_messages]
11
- graph_state: str
 
12
 
13
 
14
  def get_llm():
@@ -20,33 +23,28 @@ def get_graph(llm):
20
  with open('prompts/system_prompt.md', 'r', encoding='utf-8') as markdown_file:
21
  system_prompt = markdown_file.read()
22
 
 
 
 
 
 
 
23
 
24
- def node_1(state):
25
- print("---Node 1---")
 
 
26
 
27
- messages = state['messages']
28
-
29
- prompt: AnyMessage = [SystemMessage(content=system_prompt), messages]
30
-
31
- response = llm.invoke([("system", prompt), messages])
32
-
33
- return {"message": response}
34
-
35
-
36
-
37
-
38
- from IPython.display import Image, display
39
-
40
- from langgraph.graph import MessagesState, START, END, StateGraph
41
 
42
  # Build graph
43
  builder = StateGraph(State)
44
- builder.add_node("node_1", node_1)
45
 
46
 
47
  # Logic
48
- builder.add_edge(START, "node_1")
49
- builder.add_edge("node_1", END)
50
 
51
  return builder.compile()
52
 
 
1
+ import operator
2
  import os
3
  from langchain.chat_models import init_chat_model
4
  from langchain_core.messages import HumanMessage, SystemMessage, AIMessage, AnyMessage
5
+ from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
6
+ from langgraph.graph import add_messages, START, END, StateGraph
7
 
8
  from typing_extensions import TypedDict, Annotated
9
 
10
 
11
  class State(TypedDict):
12
  messages: Annotated[list, add_messages]
13
+ aggregate: Annotated[list, operator.add]
14
+ # graph_state: str
15
 
16
 
17
  def get_llm():
 
23
  with open('prompts/system_prompt.md', 'r', encoding='utf-8') as markdown_file:
24
  system_prompt = markdown_file.read()
25
 
26
+ prompt_template = ChatPromptTemplate.from_messages(
27
+ [
28
+ ("system", system_prompt),
29
+ MessagesPlaceholder(variable_name="messages"),
30
+ ]
31
+ )
32
 
33
+ def call_model(state: State):
34
+ print("\n-------------------- Agent has been called -----------------------------------\n")
35
+ prompt = prompt_template.invoke(state["messages"])
36
+ response = llm.invoke(prompt)
37
 
38
+ return {"messages": [response], "aggregate": ["Agent"]}
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
  # Build graph
41
  builder = StateGraph(State)
42
+ builder.add_node("Agent", call_model)
43
 
44
 
45
  # Logic
46
+ builder.add_edge(START, "Agent")
47
+ builder.add_edge("Agent", END)
48
 
49
  return builder.compile()
50
 
app.py CHANGED
@@ -3,6 +3,9 @@ import gradio as gr
3
  import requests
4
  import inspect
5
  import pandas as pd
 
 
 
6
 
7
  # (Keep Constants as is)
8
  # --- Constants ---
@@ -12,34 +15,16 @@ DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
12
  # ----- THIS IS WERE YOU CAN BUILD WHAT YOU WANT ------
13
  class BasicAgent:
14
  def __init__(self):
15
- os.getenv("GROQ_API_KEY")
16
- from langchain.chat_models import init_chat_model
17
-
18
- self.model = init_chat_model("llama-3.3-70b-versatile", model_provider="groq")
19
 
20
  print("BasicAgent initialized.")
21
  def __call__(self, question: str) -> str:
22
  print(f"Agent received question (first 50 chars): {question[:50]}...")
23
- # fixed_answer = "This is a default answer."
24
- # fixed_answer = r'{"task_id": "task_id_1", "model_answer": "Between 2000 and 2009 (inclusive), Mercedes Sosa published three studio albums: Corazón Libre (2005), Cantora 1 (2009), and Cantora 2 (2009).", "reasoning_trace": "The different steps by which your model reached answer 1"}{"task_id": "task_id_2", "model_answer": "Answer 2 from your model", "reasoning_trace": "The different steps by which your model reached answer 2"}'
25
- #fixed_answer = "I need to find how many studio albums Mercedes Sosa published between 2000 and 2009, inclusive. From the provided list: 2005: Corazón Libre, 2009: Cantora 1 and 2009: Cantora 2. There are three albums within the specified range. FINAL ANSWER: 3"
26
- #print(f"Agent returning fixed answer: {fixed_answer}")
27
- fixed_answer = self.model.invoke([("system", """You are tasked with answering questions from the GAIA benchmark for AI agents.
28
-
29
- Provide ONLY the precise answer to the question. Do not include explanations, reasoning, or any additional text. Be direct, specific, and concise to meet the strict exact-matching requirements of the GAIA benchmark.
30
-
31
- # Output Format
32
-
33
- - **Single-word or short-phrase answers:** If the question necessitates a brief answer, provide just that word or phrase.
34
- - **Numerical values:** Provide only the number when applicable, with no additional formatting or units unless specifically requested.
35
- - **Full sentences:** If the question expects a sentence, provide the exact sentence required with no extra characters, punctuation, or formatting.
36
-
37
- # Notes
38
-
39
- - Be aware of strict exact-matching requirements; even minor deviations can result in an incorrect response.
40
- - If any ambiguity exists in the phrasing of the input, respond with an answer that aligns with the GAIA benchmark's intended interpretation."""), ("user", question)])
41
 
42
- return fixed_answer.content
43
 
44
  def run_and_submit_all( profile: gr.OAuthProfile | None):
45
  """
 
3
  import requests
4
  import inspect
5
  import pandas as pd
6
+ from dotenv import load_dotenv
7
+
8
+ from agent import *
9
 
10
  # (Keep Constants as is)
11
  # --- Constants ---
 
15
  # ----- THIS IS WERE YOU CAN BUILD WHAT YOU WANT ------
16
  class BasicAgent:
17
  def __init__(self):
18
+ load_dotenv()
19
+ self.llm = get_llm()
20
+ self.graph = get_graph(self.llm)
 
21
 
22
  print("BasicAgent initialized.")
23
  def __call__(self, question: str) -> str:
24
  print(f"Agent received question (first 50 chars): {question[:50]}...")
25
+ response = self.graph.invoke({"messages": [HumanMessage(content="question"),]})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
 
27
+ return response["messages"][-1].content
28
 
29
  def run_and_submit_all( profile: gr.OAuthProfile | None):
30
  """
app_legacy.py ADDED
@@ -0,0 +1,218 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ os.getenv("GROQ_API_KEY")
16
+ from langchain.chat_models import init_chat_model
17
+
18
+ self.model = init_chat_model("llama-3.3-70b-versatile", model_provider="groq")
19
+
20
+ print("BasicAgent initialized.")
21
+ def __call__(self, question: str) -> str:
22
+ print(f"Agent received question (first 50 chars): {question[:50]}...")
23
+ # fixed_answer = "This is a default answer."
24
+ # fixed_answer = r'{"task_id": "task_id_1", "model_answer": "Between 2000 and 2009 (inclusive), Mercedes Sosa published three studio albums: Corazón Libre (2005), Cantora 1 (2009), and Cantora 2 (2009).", "reasoning_trace": "The different steps by which your model reached answer 1"}{"task_id": "task_id_2", "model_answer": "Answer 2 from your model", "reasoning_trace": "The different steps by which your model reached answer 2"}'
25
+ #fixed_answer = "I need to find how many studio albums Mercedes Sosa published between 2000 and 2009, inclusive. From the provided list: 2005: Corazón Libre, 2009: Cantora 1 and 2009: Cantora 2. There are three albums within the specified range. FINAL ANSWER: 3"
26
+ #print(f"Agent returning fixed answer: {fixed_answer}")
27
+ fixed_answer = self.model.invoke([("system", """You are tasked with answering questions from the GAIA benchmark for AI agents.
28
+
29
+ Provide ONLY the precise answer to the question. Do not include explanations, reasoning, or any additional text. Be direct, specific, and concise to meet the strict exact-matching requirements of the GAIA benchmark.
30
+
31
+ # Output Format
32
+
33
+ - **Single-word or short-phrase answers:** If the question necessitates a brief answer, provide just that word or phrase.
34
+ - **Numerical values:** Provide only the number when applicable, with no additional formatting or units unless specifically requested.
35
+ - **Full sentences:** If the question expects a sentence, provide the exact sentence required with no extra characters, punctuation, or formatting.
36
+
37
+ # Notes
38
+
39
+ - Be aware of strict exact-matching requirements; even minor deviations can result in an incorrect response.
40
+ - If any ambiguity exists in the phrasing of the input, respond with an answer that aligns with the GAIA benchmark's intended interpretation."""), ("user", question)])
41
+
42
+ return fixed_answer.content
43
+
44
+ def run_and_submit_all( profile: gr.OAuthProfile | None):
45
+ """
46
+ Fetches all questions, runs the BasicAgent on them, submits all answers,
47
+ and displays the results.
48
+ """
49
+ # --- Determine HF Space Runtime URL and Repo URL ---
50
+ space_id = os.getenv("SPACE_ID") # Get the SPACE_ID for sending link to the code
51
+
52
+ if profile:
53
+ username= f"{profile.username}"
54
+ print(f"User logged in: {username}")
55
+ else:
56
+ print("User not logged in.")
57
+ return "Please Login to Hugging Face with the button.", None
58
+
59
+ api_url = DEFAULT_API_URL
60
+ questions_url = f"{api_url}/questions"
61
+ submit_url = f"{api_url}/submit"
62
+
63
+ # 1. Instantiate Agent ( modify this part to create your agent)
64
+ try:
65
+ agent = BasicAgent()
66
+ except Exception as e:
67
+ print(f"Error instantiating agent: {e}")
68
+ return f"Error initializing agent: {e}", None
69
+ # 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)
70
+ agent_code = f"https://huggingface.co/spaces/{space_id}/tree/main"
71
+ print(agent_code)
72
+
73
+ # 2. Fetch Questions
74
+ print(f"Fetching questions from: {questions_url}")
75
+ try:
76
+ response = requests.get(questions_url, timeout=15)
77
+ response.raise_for_status()
78
+ questions_data = response.json()
79
+ if not questions_data:
80
+ print("Fetched questions list is empty.")
81
+ return "Fetched questions list is empty or invalid format.", None
82
+ print(f"Fetched {len(questions_data)} questions.")
83
+ except requests.exceptions.RequestException as e:
84
+ print(f"Error fetching questions: {e}")
85
+ return f"Error fetching questions: {e}", None
86
+ except requests.exceptions.JSONDecodeError as e:
87
+ print(f"Error decoding JSON response from questions endpoint: {e}")
88
+ print(f"Response text: {response.text[:500]}")
89
+ return f"Error decoding server response for questions: {e}", None
90
+ except Exception as e:
91
+ print(f"An unexpected error occurred fetching questions: {e}")
92
+ return f"An unexpected error occurred fetching questions: {e}", None
93
+
94
+ # 3. Run your Agent
95
+ results_log = []
96
+ answers_payload = []
97
+ print(f"Running agent on {len(questions_data)} questions...")
98
+ for item in questions_data:
99
+ task_id = item.get("task_id")
100
+ question_text = item.get("question")
101
+ if not task_id or question_text is None:
102
+ print(f"Skipping item with missing task_id or question: {item}")
103
+ continue
104
+ try:
105
+ submitted_answer = agent(question_text)
106
+ answers_payload.append({"task_id": task_id, "submitted_answer": submitted_answer})
107
+ results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": submitted_answer})
108
+ except Exception as e:
109
+ print(f"Error running agent on task {task_id}: {e}")
110
+ results_log.append({"Task ID": task_id, "Question": question_text, "Submitted Answer": f"AGENT ERROR: {e}"})
111
+
112
+ if not answers_payload:
113
+ print("Agent did not produce any answers to submit.")
114
+ return "Agent did not produce any answers to submit.", pd.DataFrame(results_log)
115
+
116
+ # 4. Prepare Submission
117
+ submission_data = {"username": username.strip(), "agent_code": agent_code, "answers": answers_payload}
118
+ status_update = f"Agent finished. Submitting {len(answers_payload)} answers for user '{username}'..."
119
+ print(status_update)
120
+
121
+ # 5. Submit
122
+ print(f"Submitting {len(answers_payload)} answers to: {submit_url}")
123
+ try:
124
+ response = requests.post(submit_url, json=submission_data, timeout=60)
125
+ response.raise_for_status()
126
+ result_data = response.json()
127
+ final_status = (
128
+ f"Submission Successful!\n"
129
+ f"User: {result_data.get('username')}\n"
130
+ f"Overall Score: {result_data.get('score', 'N/A')}% "
131
+ f"({result_data.get('correct_count', '?')}/{result_data.get('total_attempted', '?')} correct)\n"
132
+ f"Message: {result_data.get('message', 'No message received.')}"
133
+ )
134
+ print("Submission successful.")
135
+ results_df = pd.DataFrame(results_log)
136
+ return final_status, results_df
137
+ except requests.exceptions.HTTPError as e:
138
+ error_detail = f"Server responded with status {e.response.status_code}."
139
+ try:
140
+ error_json = e.response.json()
141
+ error_detail += f" Detail: {error_json.get('detail', e.response.text)}"
142
+ except requests.exceptions.JSONDecodeError:
143
+ error_detail += f" Response: {e.response.text[:500]}"
144
+ status_message = f"Submission Failed: {error_detail}"
145
+ print(status_message)
146
+ results_df = pd.DataFrame(results_log)
147
+ return status_message, results_df
148
+ except requests.exceptions.Timeout:
149
+ status_message = "Submission Failed: The request timed out."
150
+ print(status_message)
151
+ results_df = pd.DataFrame(results_log)
152
+ return status_message, results_df
153
+ except requests.exceptions.RequestException as e:
154
+ status_message = f"Submission Failed: Network error - {e}"
155
+ print(status_message)
156
+ results_df = pd.DataFrame(results_log)
157
+ return status_message, results_df
158
+ except Exception as e:
159
+ status_message = f"An unexpected error occurred during submission: {e}"
160
+ print(status_message)
161
+ results_df = pd.DataFrame(results_log)
162
+ return status_message, results_df
163
+
164
+
165
+ # --- Build Gradio Interface using Blocks ---
166
+ with gr.Blocks() as demo:
167
+ gr.Markdown("# Basic Agent Evaluation Runner")
168
+ gr.Markdown(
169
+ """
170
+ **Instructions:**
171
+
172
+ 1. Please clone this space, then modify the code to define your agent's logic, the tools, the necessary packages, etc ...
173
+ 2. Log in to your Hugging Face account using the button below. This uses your HF username for submission.
174
+ 3. Click 'Run Evaluation & Submit All Answers' to fetch questions, run your agent, submit answers, and see the score.
175
+
176
+ ---
177
+ **Disclaimers:**
178
+ 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).
179
+ 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.
180
+ """
181
+ )
182
+
183
+ gr.LoginButton()
184
+
185
+ run_button = gr.Button("Run Evaluation & Submit All Answers")
186
+
187
+ status_output = gr.Textbox(label="Run Status / Submission Result", lines=5, interactive=False)
188
+ # Removed max_rows=10 from DataFrame constructor
189
+ results_table = gr.DataFrame(label="Questions and Agent Answers", wrap=True)
190
+
191
+ run_button.click(
192
+ fn=run_and_submit_all,
193
+ outputs=[status_output, results_table]
194
+ )
195
+
196
+ if __name__ == "__main__":
197
+ print("\n" + "-"*30 + " App Starting " + "-"*30)
198
+ # Check for SPACE_HOST and SPACE_ID at startup for information
199
+ space_host_startup = os.getenv("SPACE_HOST")
200
+ space_id_startup = os.getenv("SPACE_ID") # Get SPACE_ID at startup
201
+
202
+ if space_host_startup:
203
+ print(f"✅ SPACE_HOST found: {space_host_startup}")
204
+ print(f" Runtime URL should be: https://{space_host_startup}.hf.space")
205
+ else:
206
+ print("ℹ️ SPACE_HOST environment variable not found (running locally?).")
207
+
208
+ if space_id_startup: # Print repo URLs if SPACE_ID is found
209
+ print(f"✅ SPACE_ID found: {space_id_startup}")
210
+ print(f" Repo URL: https://huggingface.co/spaces/{space_id_startup}")
211
+ print(f" Repo Tree URL: https://huggingface.co/spaces/{space_id_startup}/tree/main")
212
+ else:
213
+ print("ℹ️ SPACE_ID environment variable not found (running locally?). Repo URL cannot be determined.")
214
+
215
+ print("-"*(60 + len(" App Starting ")) + "\n")
216
+
217
+ print("Launching Gradio Interface for Basic Agent Evaluation...")
218
+ demo.launch(debug=True, share=False)
app_playground.ipynb CHANGED
@@ -6,8 +6,8 @@
6
  "metadata": {
7
  "collapsed": true,
8
  "ExecuteTime": {
9
- "end_time": "2025-04-26T20:02:07.770606Z",
10
- "start_time": "2025-04-26T20:02:07.726139Z"
11
  }
12
  },
13
  "source": [
@@ -22,14 +22,121 @@
22
  "\n",
23
  "graph = get_graph(llm)\n"
24
  ],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  "outputs": [],
26
- "execution_count": 3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  },
28
  {
29
  "metadata": {
30
  "ExecuteTime": {
31
- "end_time": "2025-04-26T19:33:33.529627Z",
32
- "start_time": "2025-04-26T19:33:33.064005Z"
33
  }
34
  },
35
  "cell_type": "code",
@@ -43,7 +150,7 @@
43
  {
44
  "data": {
45
  "text/plain": [
46
- "\"Hello! I'm just a language model, so I don't have feelings or emotions like humans do, but I'm functioning properly and ready to help with any questions or tasks you might have. How can I assist you today?\""
47
  ]
48
  },
49
  "execution_count": 3,
 
6
  "metadata": {
7
  "collapsed": true,
8
  "ExecuteTime": {
9
+ "end_time": "2025-04-27T11:27:04.428213Z",
10
+ "start_time": "2025-04-27T11:26:58.244180Z"
11
  }
12
  },
13
  "source": [
 
22
  "\n",
23
  "graph = get_graph(llm)\n"
24
  ],
25
+ "outputs": [
26
+ {
27
+ "name": "stderr",
28
+ "output_type": "stream",
29
+ "text": [
30
+ "C:\\Users\\dennis.binzen\\PycharmProjects\\Final_Assignment\\.venv\\Lib\\site-packages\\tqdm\\auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
31
+ " from .autonotebook import tqdm as notebook_tqdm\n"
32
+ ]
33
+ }
34
+ ],
35
+ "execution_count": 1
36
+ },
37
+ {
38
+ "metadata": {
39
+ "ExecuteTime": {
40
+ "end_time": "2025-04-27T11:27:04.828108Z",
41
+ "start_time": "2025-04-27T11:27:04.434834Z"
42
+ }
43
+ },
44
+ "cell_type": "code",
45
+ "source": [
46
+ "from IPython.display import Image, display\n",
47
+ "display(Image(graph.get_graph().draw_mermaid_png()))"
48
+ ],
49
+ "id": "da8311fc7f1acf6",
50
+ "outputs": [
51
+ {
52
+ "data": {
53
+ "image/png": "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",
54
+ "text/plain": [
55
+ "<IPython.core.display.Image object>"
56
+ ]
57
+ },
58
+ "metadata": {},
59
+ "output_type": "display_data"
60
+ }
61
+ ],
62
+ "execution_count": 2
63
+ },
64
+ {
65
+ "metadata": {
66
+ "ExecuteTime": {
67
+ "end_time": "2025-04-27T11:30:44.925757Z",
68
+ "start_time": "2025-04-27T11:30:44.688378Z"
69
+ }
70
+ },
71
+ "cell_type": "code",
72
+ "source": "res = graph.invoke({\"messages\": [HumanMessage(content=\"Hello, how are you?\"),]})",
73
+ "id": "a9fdfecc1af0975e",
74
+ "outputs": [
75
+ {
76
+ "name": "stdout",
77
+ "output_type": "stream",
78
+ "text": [
79
+ "\n",
80
+ "-------------------- Agent has been called -----------------------------------\n",
81
+ "\n"
82
+ ]
83
+ }
84
+ ],
85
+ "execution_count": 4
86
+ },
87
+ {
88
+ "metadata": {
89
+ "ExecuteTime": {
90
+ "end_time": "2025-04-27T11:32:02.443950Z",
91
+ "start_time": "2025-04-27T11:32:02.438038Z"
92
+ }
93
+ },
94
+ "cell_type": "code",
95
+ "source": "res[\"messages\"][-1].content",
96
+ "id": "66f2dcaeb343c836",
97
+ "outputs": [
98
+ {
99
+ "data": {
100
+ "text/plain": [
101
+ "\"I'm doing well.\""
102
+ ]
103
+ },
104
+ "execution_count": 7,
105
+ "metadata": {},
106
+ "output_type": "execute_result"
107
+ }
108
+ ],
109
+ "execution_count": 7
110
+ },
111
+ {
112
+ "metadata": {},
113
+ "cell_type": "code",
114
  "outputs": [],
115
+ "execution_count": null,
116
+ "source": "",
117
+ "id": "8d3a94be44f4859a"
118
+ },
119
+ {
120
+ "metadata": {},
121
+ "cell_type": "code",
122
+ "outputs": [],
123
+ "execution_count": null,
124
+ "source": "",
125
+ "id": "3bf392ddf3ce5c96"
126
+ },
127
+ {
128
+ "metadata": {},
129
+ "cell_type": "code",
130
+ "outputs": [],
131
+ "execution_count": null,
132
+ "source": "",
133
+ "id": "abe6c705b7557bdc"
134
  },
135
  {
136
  "metadata": {
137
  "ExecuteTime": {
138
+ "end_time": "2025-04-27T11:18:19.448376Z",
139
+ "start_time": "2025-04-27T11:18:19.025565Z"
140
  }
141
  },
142
  "cell_type": "code",
 
150
  {
151
  "data": {
152
  "text/plain": [
153
+ "\"Hello. I'm just a language model, so I don't have feelings or emotions like humans do, but I'm functioning properly and ready to assist you with any questions or topics you'd like to discuss. How can I help you today?\""
154
  ]
155
  },
156
  "execution_count": 3,
requirements.txt CHANGED
@@ -5,5 +5,6 @@ langchain~=0.3.24
5
  dotenv~=0.9.9
6
  python-dotenv~=1.1.0
7
  typing_extensions~=4.13.2
8
- langchain-groq~=0.3.2
9
- langgraph~=0.3.34
 
 
5
  dotenv~=0.9.9
6
  python-dotenv~=1.1.0
7
  typing_extensions~=4.13.2
8
+ langgraph~=0.3.34
9
+ langchain-core~=0.3.56
10
+ ipython~=9.2.0
test.py DELETED
@@ -1 +0,0 @@
1
- print("Hello")