CHAN9IJI commited on
Commit
b2f33c1
Β·
verified Β·
1 Parent(s): cdeefd0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +346 -70
app.py CHANGED
@@ -1,70 +1,346 @@
1
- import gradio as gr
2
- from huggingface_hub import InferenceClient
3
-
4
-
5
- def respond(
6
- message,
7
- history: list[dict[str, str]],
8
- system_message,
9
- max_tokens,
10
- temperature,
11
- top_p,
12
- hf_token: gr.OAuthToken,
13
- ):
14
- """
15
- For more information on `huggingface_hub` Inference API support, please check the docs: https://huggingface.co/docs/huggingface_hub/v0.22.2/en/guides/inference
16
- """
17
- client = InferenceClient(token=hf_token.token, model="openai/gpt-oss-20b")
18
-
19
- messages = [{"role": "system", "content": system_message}]
20
-
21
- messages.extend(history)
22
-
23
- messages.append({"role": "user", "content": message})
24
-
25
- response = ""
26
-
27
- for message in client.chat_completion(
28
- messages,
29
- max_tokens=max_tokens,
30
- stream=True,
31
- temperature=temperature,
32
- top_p=top_p,
33
- ):
34
- choices = message.choices
35
- token = ""
36
- if len(choices) and choices[0].delta.content:
37
- token = choices[0].delta.content
38
-
39
- response += token
40
- yield response
41
-
42
-
43
- """
44
- For information on how to customize the ChatInterface, peruse the gradio docs: https://www.gradio.app/docs/chatinterface
45
- """
46
- chatbot = gr.ChatInterface(
47
- respond,
48
- type="messages",
49
- additional_inputs=[
50
- gr.Textbox(value="You are a friendly Chatbot.", label="System message"),
51
- gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
52
- gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
53
- gr.Slider(
54
- minimum=0.1,
55
- maximum=1.0,
56
- value=0.95,
57
- step=0.05,
58
- label="Top-p (nucleus sampling)",
59
- ),
60
- ],
61
- )
62
-
63
- with gr.Blocks() as demo:
64
- with gr.Sidebar():
65
- gr.LoginButton()
66
- chatbot.render()
67
-
68
-
69
- if __name__ == "__main__":
70
- demo.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from huggingface_hub import InferenceClient
3
+ import json
4
+ import asyncio
5
+ from typing import Optional, Dict, Any, List
6
+
7
+
8
+ class MCPContextManager:
9
+ """Model Context Protocol Manager for handling context and tools"""
10
+
11
+ def __init__(self):
12
+ self.context = []
13
+ self.tools = {}
14
+ self.resources = {}
15
+
16
+ def add_context(self, role: str, content: str, metadata: Optional[Dict] = None):
17
+ """Add context entry following MCP specification"""
18
+ entry = {
19
+ "role": role,
20
+ "content": content,
21
+ "timestamp": None,
22
+ "metadata": metadata or {}
23
+ }
24
+ self.context.append(entry)
25
+ return entry
26
+
27
+ def register_tool(self, name: str, description: str, parameters: Dict, handler):
28
+ """Register a tool following MCP tool specification"""
29
+ self.tools[name] = {
30
+ "name": name,
31
+ "description": description,
32
+ "parameters": parameters,
33
+ "handler": handler
34
+ }
35
+
36
+ def register_resource(self, uri: str, name: str, mime_type: str, content: Any):
37
+ """Register a resource following MCP resource specification"""
38
+ self.resources[uri] = {
39
+ "uri": uri,
40
+ "name": name,
41
+ "mimeType": mime_type,
42
+ "content": content
43
+ }
44
+
45
+ def get_context_window(self, max_tokens: int = 4096) -> List[Dict]:
46
+ """Get context window within token limits"""
47
+ return self.context[-10:] # Simple implementation
48
+
49
+ async def call_tool(self, tool_name: str, arguments: Dict) -> Any:
50
+ """Execute a registered tool"""
51
+ if tool_name not in self.tools:
52
+ raise ValueError(f"Tool {tool_name} not found")
53
+
54
+ tool = self.tools[tool_name]
55
+ return await tool["handler"](arguments)
56
+
57
+ def get_available_tools(self) -> List[Dict]:
58
+ """Get list of available tools in MCP format"""
59
+ return [
60
+ {
61
+ "name": tool["name"],
62
+ "description": tool["description"],
63
+ "parameters": tool["parameters"]
64
+ }
65
+ for tool in self.tools.values()
66
+ ]
67
+
68
+ def export_context(self) -> str:
69
+ """Export context in MCP-compatible JSON format"""
70
+ return json.dumps({
71
+ "context": self.context,
72
+ "tools": self.get_available_tools(),
73
+ "resources": list(self.resources.keys())
74
+ }, indent=2)
75
+
76
+
77
+ # Initialize MCP Manager
78
+ mcp_manager = MCPContextManager()
79
+
80
+
81
+ # Register example MCP tools
82
+ async def calculator_handler(args):
83
+ """Calculator tool handler"""
84
+ operation = args.get("operation")
85
+ a = float(args.get("a", 0))
86
+ b = float(args.get("b", 0))
87
+
88
+ operations = {
89
+ "add": a + b,
90
+ "subtract": a - b,
91
+ "multiply": a * b,
92
+ "divide": a / b if b != 0 else "Error: Division by zero"
93
+ }
94
+ return operations.get(operation, "Invalid operation")
95
+
96
+
97
+ async def memory_handler(args):
98
+ """Memory/context storage handler"""
99
+ action = args.get("action")
100
+ key = args.get("key")
101
+ value = args.get("value")
102
+
103
+ if action == "store":
104
+ mcp_manager.register_resource(
105
+ uri=f"memory://{key}",
106
+ name=key,
107
+ mime_type="text/plain",
108
+ content=value
109
+ )
110
+ return f"Stored {key}"
111
+ elif action == "retrieve":
112
+ resource = mcp_manager.resources.get(f"memory://{key}")
113
+ return resource["content"] if resource else "Not found"
114
+ return "Invalid action"
115
+
116
+
117
+ async def web_search_handler(args):
118
+ """Simulated web search handler"""
119
+ query = args.get("query")
120
+ return f"Search results for: {query} (MCP tool simulation)"
121
+
122
+
123
+ # Register tools with MCP manager
124
+ mcp_manager.register_tool(
125
+ name="calculator",
126
+ description="Perform basic arithmetic operations",
127
+ parameters={
128
+ "type": "object",
129
+ "properties": {
130
+ "operation": {"type": "string", "enum": ["add", "subtract", "multiply", "divide"]},
131
+ "a": {"type": "number"},
132
+ "b": {"type": "number"}
133
+ },
134
+ "required": ["operation", "a", "b"]
135
+ },
136
+ handler=calculator_handler
137
+ )
138
+
139
+ mcp_manager.register_tool(
140
+ name="memory",
141
+ description="Store and retrieve information in memory",
142
+ parameters={
143
+ "type": "object",
144
+ "properties": {
145
+ "action": {"type": "string", "enum": ["store", "retrieve"]},
146
+ "key": {"type": "string"},
147
+ "value": {"type": "string"}
148
+ },
149
+ "required": ["action", "key"]
150
+ },
151
+ handler=memory_handler
152
+ )
153
+
154
+ mcp_manager.register_tool(
155
+ name="web_search",
156
+ description="Search the web for information",
157
+ parameters={
158
+ "type": "object",
159
+ "properties": {
160
+ "query": {"type": "string"}
161
+ },
162
+ "required": ["query"]
163
+ },
164
+ handler=web_search_handler
165
+ )
166
+
167
+
168
+ def respond(
169
+ message,
170
+ history: list[dict[str, str]],
171
+ system_message,
172
+ max_tokens,
173
+ temperature,
174
+ top_p,
175
+ enable_mcp,
176
+ hf_token: gr.OAuthToken,
177
+ ):
178
+ """
179
+ Enhanced respond function with MCP support
180
+ """
181
+ # Add message to MCP context if enabled
182
+ if enable_mcp:
183
+ mcp_manager.add_context("user", message)
184
+
185
+ client = InferenceClient(token=hf_token.token, model="openai/gpt-oss-20b")
186
+
187
+ # Build messages with MCP context
188
+ messages = [{"role": "system", "content": system_message}]
189
+
190
+ if enable_mcp:
191
+ # Add MCP tools information to system message
192
+ tools_info = "\n\nAvailable MCP Tools:\n" + json.dumps(mcp_manager.get_available_tools(), indent=2)
193
+ messages[0]["content"] += tools_info
194
+
195
+ messages.extend(history)
196
+ messages.append({"role": "user", "content": message})
197
+
198
+ response = ""
199
+
200
+ for msg in client.chat_completion(
201
+ messages,
202
+ max_tokens=max_tokens,
203
+ stream=True,
204
+ temperature=temperature,
205
+ top_p=top_p,
206
+ ):
207
+ choices = msg.choices
208
+ token = ""
209
+ if len(choices) and choices[0].delta.content:
210
+ token = choices[0].delta.content
211
+
212
+ response += token
213
+ yield response
214
+
215
+ # Add response to MCP context if enabled
216
+ if enable_mcp:
217
+ mcp_manager.add_context("assistant", response)
218
+
219
+
220
+ def call_mcp_tool(tool_name: str, arguments_json: str):
221
+ """Interface for calling MCP tools from UI"""
222
+ try:
223
+ arguments = json.loads(arguments_json)
224
+ result = asyncio.run(mcp_manager.call_tool(tool_name, arguments))
225
+ return json.dumps({"success": True, "result": result}, indent=2)
226
+ except Exception as e:
227
+ return json.dumps({"success": False, "error": str(e)}, indent=2)
228
+
229
+
230
+ def export_mcp_context():
231
+ """Export current MCP context"""
232
+ return mcp_manager.export_context()
233
+
234
+
235
+ def get_mcp_tools_list():
236
+ """Get formatted list of available MCP tools"""
237
+ tools = mcp_manager.get_available_tools()
238
+ return json.dumps(tools, indent=2)
239
+
240
+
241
+ """
242
+ Enhanced Gradio interface with Model Context Protocol (MCP) support
243
+ """
244
+ chatbot = gr.ChatInterface(
245
+ respond,
246
+ type="messages",
247
+ additional_inputs=[
248
+ gr.Textbox(
249
+ value="You are a friendly AI assistant with access to Model Context Protocol (MCP) tools. You can use tools like calculator, memory storage, and web search to help users.",
250
+ label="System message",
251
+ lines=3
252
+ ),
253
+ gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
254
+ gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
255
+ gr.Slider(
256
+ minimum=0.1,
257
+ maximum=1.0,
258
+ value=0.95,
259
+ step=0.05,
260
+ label="Top-p (nucleus sampling)",
261
+ ),
262
+ gr.Checkbox(value=True, label="Enable MCP (Model Context Protocol)"),
263
+ ],
264
+ )
265
+
266
+ with gr.Blocks(title="AI Chat with MCP Support") as demo:
267
+ gr.Markdown("# πŸ€– AI Chatbot with Model Context Protocol (MCP)")
268
+ gr.Markdown("Enhanced with MCP for context management, tool usage, and resource handling")
269
+
270
+ with gr.Tabs():
271
+ with gr.Tab("πŸ’¬ Chat"):
272
+ with gr.Sidebar():
273
+ gr.LoginButton()
274
+ chatbot.render()
275
+
276
+ with gr.Tab("πŸ› οΈ MCP Tools"):
277
+ gr.Markdown("### Available MCP Tools")
278
+ tools_display = gr.JSON(label="Registered Tools")
279
+ refresh_tools_btn = gr.Button("Refresh Tools List")
280
+
281
+ gr.Markdown("### Call MCP Tool")
282
+ with gr.Row():
283
+ tool_name_input = gr.Textbox(label="Tool Name", placeholder="calculator")
284
+ tool_args_input = gr.Textbox(
285
+ label="Arguments (JSON)",
286
+ placeholder='{"operation": "add", "a": 5, "b": 3}',
287
+ lines=3
288
+ )
289
+ call_tool_btn = gr.Button("Call Tool")
290
+ tool_result = gr.JSON(label="Tool Result")
291
+
292
+ refresh_tools_btn.click(
293
+ fn=get_mcp_tools_list,
294
+ outputs=tools_display
295
+ )
296
+
297
+ call_tool_btn.click(
298
+ fn=call_mcp_tool,
299
+ inputs=[tool_name_input, tool_args_input],
300
+ outputs=tool_result
301
+ )
302
+
303
+ with gr.Tab("πŸ“‹ MCP Context"):
304
+ gr.Markdown("### Export MCP Context")
305
+ gr.Markdown("View and export the current context window managed by MCP")
306
+ export_btn = gr.Button("Export Context")
307
+ context_display = gr.Code(language="json", label="MCP Context")
308
+
309
+ export_btn.click(
310
+ fn=export_mcp_context,
311
+ outputs=context_display
312
+ )
313
+
314
+ with gr.Tab("ℹ️ About MCP"):
315
+ gr.Markdown("""
316
+ ### Model Context Protocol (MCP)
317
+
318
+ MCP is a protocol for managing context, tools, and resources in AI applications.
319
+
320
+ **Features:**
321
+ - πŸ”§ **Tool Integration**: Register and call tools dynamically
322
+ - πŸ’Ύ **Context Management**: Maintain conversation history and context
323
+ - πŸ“¦ **Resource Handling**: Store and retrieve resources (files, data, etc.)
324
+ - πŸ”Œ **Extensible**: Easy to add new tools and capabilities
325
+
326
+ **Available Tools:**
327
+ 1. **Calculator**: Perform arithmetic operations
328
+ 2. **Memory**: Store and retrieve information
329
+ 3. **Web Search**: Search for information (simulated)
330
+
331
+ **Example Tool Call:**
332
+ ```json
333
+ {
334
+ "tool": "calculator",
335
+ "arguments": {
336
+ "operation": "add",
337
+ "a": 10,
338
+ "b": 5
339
+ }
340
+ }
341
+ ```
342
+ """)
343
+
344
+
345
+ if __name__ == "__main__":
346
+ demo.launch()