Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -3,11 +3,19 @@ import requests
|
|
3 |
from smolagents import CodeAgent
|
4 |
import json
|
5 |
import re
|
|
|
|
|
6 |
|
7 |
-
|
|
|
|
|
8 |
|
|
|
|
|
|
|
|
|
9 |
def call_mcp_server(message, tool_type="knowledge_base"):
|
10 |
-
"""Call your MCP server
|
11 |
try:
|
12 |
# Determine which tool to use based on tool_type
|
13 |
fn_index_map = {
|
@@ -18,10 +26,26 @@ def call_mcp_server(message, tool_type="knowledge_base"):
|
|
18 |
|
19 |
fn_index = fn_index_map.get(tool_type, 0)
|
20 |
|
21 |
-
|
22 |
-
|
23 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
except Exception as e:
|
|
|
25 |
return f"MCP server error: {str(e)}"
|
26 |
|
27 |
def extract_thought_action_observation(response):
|
@@ -51,45 +75,33 @@ agent = CodeAgent(
|
|
51 |
tools=[],
|
52 |
model="microsoft/DialoGPT-medium",
|
53 |
system_prompt="""You are a Technical Support AI Agent that uses a structured Thought-Action-Observation cycle to solve user queries effectively.
|
54 |
-
|
55 |
WORKFLOW:
|
56 |
For every user query, you MUST follow this exact structure:
|
57 |
-
|
58 |
THOUGHT: Analyze the user's problem and decide what action to take
|
59 |
- Identify the type of issue (technical problem, information request, formatting need)
|
60 |
- Determine which MCP server tool would be most appropriate
|
61 |
- Consider what information you need to provide a complete answer
|
62 |
-
|
63 |
ACTION: Specify exactly what action you will take
|
64 |
- "search_knowledge_base" for known technical issues (wifi, screen, hardware problems)
|
65 |
- "web_search" for current information, news, or unknown topics
|
66 |
- "format_response" for organizing or structuring information
|
67 |
- "direct_response" if you can answer without tools
|
68 |
-
|
69 |
OBSERVATION: Analyze the results and determine next steps
|
70 |
- Evaluate if the action provided sufficient information
|
71 |
- Identify if additional actions are needed
|
72 |
- Note any gaps in the information
|
73 |
-
|
74 |
FINAL RESPONSE: Provide a clear, helpful answer to the user
|
75 |
-
|
76 |
EXAMPLE:
|
77 |
User: "My wifi keeps disconnecting"
|
78 |
-
|
79 |
THOUGHT: The user has a wifi connectivity issue. This is a common technical problem that likely has solutions in our knowledge base. I should search the knowledge base first for wifi-related solutions.
|
80 |
-
|
81 |
ACTION: search_knowledge_base with query "wifi disconnecting problem"
|
82 |
-
|
83 |
OBSERVATION: The knowledge base provided basic wifi troubleshooting steps. These steps are helpful but I should also check for any recent wifi issues or advanced solutions via web search to provide comprehensive help.
|
84 |
-
|
85 |
FINAL RESPONSE: [Provide complete solution combining knowledge base and any additional insights]
|
86 |
-
|
87 |
Remember:
|
88 |
- Always use the THOUGHT-ACTION-OBSERVATION-FINAL RESPONSE structure
|
89 |
- Be specific about which tool you're using and why
|
90 |
- Provide actionable, clear solutions
|
91 |
- If one action isn't sufficient, explain what additional actions you'll take
|
92 |
-
|
93 |
{{managed_agents_descriptions}}
|
94 |
{{authorized_imports}}"""
|
95 |
)
|
@@ -119,18 +131,20 @@ def determine_tool_type(message):
|
|
119 |
def chat_interface(message, history):
|
120 |
"""Enhanced chat interface with thought-action-observation cycle"""
|
121 |
|
122 |
-
# Step 1: Let agent think about the problem
|
123 |
-
thinking_prompt = f"""
|
124 |
-
User Query: "{message}"
|
125 |
-
|
126 |
-
Follow the THOUGHT-ACTION-OBSERVATION cycle:
|
127 |
-
|
128 |
-
THOUGHT: Analyze this query and determine the best approach.
|
129 |
-
"""
|
130 |
-
|
131 |
try:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
132 |
# Get agent's initial thought process
|
133 |
agent_response = agent.run(thinking_prompt)
|
|
|
|
|
134 |
|
135 |
# Extract thought and determine action
|
136 |
cycle_parts = extract_thought_action_observation(agent_response)
|
@@ -155,30 +169,27 @@ def chat_interface(message, history):
|
|
155 |
"""
|
156 |
|
157 |
final_response = agent.run(final_prompt)
|
|
|
|
|
158 |
|
159 |
# Format the response to show the thinking process
|
160 |
formatted_response = f"""π€ **THOUGHT:** {cycle_parts.get('thought', 'Analyzing your query...')}
|
161 |
-
|
162 |
β‘ **ACTION:** Used {tool_type.replace('_', ' ')} tool
|
163 |
-
|
164 |
ποΈ **OBSERVATION:** {mcp_response[:200]}{'...' if len(mcp_response) > 200 else ''}
|
165 |
-
|
166 |
β
**SOLUTION:**
|
167 |
{final_response}"""
|
168 |
|
169 |
return formatted_response
|
170 |
|
171 |
except Exception as e:
|
|
|
172 |
# Fallback to direct MCP response with simple structure
|
173 |
tool_type = determine_tool_type(message)
|
174 |
mcp_response = call_mcp_server(message, tool_type)
|
175 |
|
176 |
return f"""π€ **THOUGHT:** You have a {tool_type.replace('_', ' ')} related query.
|
177 |
-
|
178 |
β‘ **ACTION:** Consulted the MCP server using {tool_type} tool.
|
179 |
-
|
180 |
ποΈ **OBSERVATION:** Found relevant information.
|
181 |
-
|
182 |
β
**SOLUTION:**
|
183 |
{mcp_response}"""
|
184 |
|
|
|
3 |
from smolagents import CodeAgent
|
4 |
import json
|
5 |
import re
|
6 |
+
import logging
|
7 |
+
from tenacity import retry, stop_after_attempt, wait_exponential
|
8 |
|
9 |
+
# Configure logging
|
10 |
+
logging.basicConfig(level=logging.INFO)
|
11 |
+
logger = logging.getLogger(__name__)
|
12 |
|
13 |
+
# Use lowercase and verify your exact Hugging Face Space URL
|
14 |
+
HF_SPACE_URL = "https://manavraj-troubleshoot-mcp.hf.space" # Note: Changed underscores to hyphens
|
15 |
+
|
16 |
+
@retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=4, max=10))
|
17 |
def call_mcp_server(message, tool_type="knowledge_base"):
|
18 |
+
"""Call your MCP server with retries and proper error handling"""
|
19 |
try:
|
20 |
# Determine which tool to use based on tool_type
|
21 |
fn_index_map = {
|
|
|
26 |
|
27 |
fn_index = fn_index_map.get(tool_type, 0)
|
28 |
|
29 |
+
logger.info(f"Calling MCP server with message: {message[:50]}...")
|
30 |
+
|
31 |
+
response = requests.post(
|
32 |
+
f"{HF_SPACE_URL}/api/predict",
|
33 |
+
json={"data": [message], "fn_index": fn_index},
|
34 |
+
verify=False, # Temporarily disable SSL verification
|
35 |
+
timeout=30
|
36 |
+
)
|
37 |
+
|
38 |
+
if response.status_code != 200:
|
39 |
+
raise Exception(f"MCP server returned {response.status_code}")
|
40 |
+
|
41 |
+
data = response.json()
|
42 |
+
if not isinstance(data, dict) or 'data' not in data:
|
43 |
+
raise Exception("Invalid MCP response format")
|
44 |
+
|
45 |
+
return data['data'][0]
|
46 |
+
|
47 |
except Exception as e:
|
48 |
+
logger.error(f"MCP server call failed: {str(e)}")
|
49 |
return f"MCP server error: {str(e)}"
|
50 |
|
51 |
def extract_thought_action_observation(response):
|
|
|
75 |
tools=[],
|
76 |
model="microsoft/DialoGPT-medium",
|
77 |
system_prompt="""You are a Technical Support AI Agent that uses a structured Thought-Action-Observation cycle to solve user queries effectively.
|
|
|
78 |
WORKFLOW:
|
79 |
For every user query, you MUST follow this exact structure:
|
|
|
80 |
THOUGHT: Analyze the user's problem and decide what action to take
|
81 |
- Identify the type of issue (technical problem, information request, formatting need)
|
82 |
- Determine which MCP server tool would be most appropriate
|
83 |
- Consider what information you need to provide a complete answer
|
|
|
84 |
ACTION: Specify exactly what action you will take
|
85 |
- "search_knowledge_base" for known technical issues (wifi, screen, hardware problems)
|
86 |
- "web_search" for current information, news, or unknown topics
|
87 |
- "format_response" for organizing or structuring information
|
88 |
- "direct_response" if you can answer without tools
|
|
|
89 |
OBSERVATION: Analyze the results and determine next steps
|
90 |
- Evaluate if the action provided sufficient information
|
91 |
- Identify if additional actions are needed
|
92 |
- Note any gaps in the information
|
|
|
93 |
FINAL RESPONSE: Provide a clear, helpful answer to the user
|
|
|
94 |
EXAMPLE:
|
95 |
User: "My wifi keeps disconnecting"
|
|
|
96 |
THOUGHT: The user has a wifi connectivity issue. This is a common technical problem that likely has solutions in our knowledge base. I should search the knowledge base first for wifi-related solutions.
|
|
|
97 |
ACTION: search_knowledge_base with query "wifi disconnecting problem"
|
|
|
98 |
OBSERVATION: The knowledge base provided basic wifi troubleshooting steps. These steps are helpful but I should also check for any recent wifi issues or advanced solutions via web search to provide comprehensive help.
|
|
|
99 |
FINAL RESPONSE: [Provide complete solution combining knowledge base and any additional insights]
|
|
|
100 |
Remember:
|
101 |
- Always use the THOUGHT-ACTION-OBSERVATION-FINAL RESPONSE structure
|
102 |
- Be specific about which tool you're using and why
|
103 |
- Provide actionable, clear solutions
|
104 |
- If one action isn't sufficient, explain what additional actions you'll take
|
|
|
105 |
{{managed_agents_descriptions}}
|
106 |
{{authorized_imports}}"""
|
107 |
)
|
|
|
131 |
def chat_interface(message, history):
|
132 |
"""Enhanced chat interface with thought-action-observation cycle"""
|
133 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
134 |
try:
|
135 |
+
# Step 1: Let agent think about the problem
|
136 |
+
thinking_prompt = f"""
|
137 |
+
User Query: "{message}"
|
138 |
+
|
139 |
+
Follow the THOUGHT-ACTION-OBSERVATION cycle:
|
140 |
+
|
141 |
+
THOUGHT: Analyze this query and determine the best approach.
|
142 |
+
"""
|
143 |
+
|
144 |
# Get agent's initial thought process
|
145 |
agent_response = agent.run(thinking_prompt)
|
146 |
+
if not isinstance(agent_response, str):
|
147 |
+
raise ValueError("Agent returned non-string response")
|
148 |
|
149 |
# Extract thought and determine action
|
150 |
cycle_parts = extract_thought_action_observation(agent_response)
|
|
|
169 |
"""
|
170 |
|
171 |
final_response = agent.run(final_prompt)
|
172 |
+
if not isinstance(final_response, str):
|
173 |
+
final_response = str(final_response)
|
174 |
|
175 |
# Format the response to show the thinking process
|
176 |
formatted_response = f"""π€ **THOUGHT:** {cycle_parts.get('thought', 'Analyzing your query...')}
|
|
|
177 |
β‘ **ACTION:** Used {tool_type.replace('_', ' ')} tool
|
|
|
178 |
ποΈ **OBSERVATION:** {mcp_response[:200]}{'...' if len(mcp_response) > 200 else ''}
|
|
|
179 |
β
**SOLUTION:**
|
180 |
{final_response}"""
|
181 |
|
182 |
return formatted_response
|
183 |
|
184 |
except Exception as e:
|
185 |
+
logger.error(f"Error in chat interface: {str(e)}")
|
186 |
# Fallback to direct MCP response with simple structure
|
187 |
tool_type = determine_tool_type(message)
|
188 |
mcp_response = call_mcp_server(message, tool_type)
|
189 |
|
190 |
return f"""π€ **THOUGHT:** You have a {tool_type.replace('_', ' ')} related query.
|
|
|
191 |
β‘ **ACTION:** Consulted the MCP server using {tool_type} tool.
|
|
|
192 |
ποΈ **OBSERVATION:** Found relevant information.
|
|
|
193 |
β
**SOLUTION:**
|
194 |
{mcp_response}"""
|
195 |
|