mgokg commited on
Commit
c4f8ee5
·
verified ·
1 Parent(s): 312f785

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +25 -26
app.py CHANGED
@@ -7,7 +7,8 @@ from google.genai import types
7
  from mcp import ClientSession, StdioServerParameters
8
  from mcp.client.stdio import stdio_client
9
 
10
- # Konfiguration des MCP-Servers für die DB-Fahrplanauskunft [1, 3]
 
11
  server_params = StdioServerParameters(
12
  command="npx",
13
  args=[
@@ -22,27 +23,27 @@ async def generate(input_text):
22
  try:
23
  client = genai.Client(api_key=os.environ.get("GEMINI_API_KEY"))
24
  except Exception as e:
25
- return f"Error initializing client: {e}", ""
26
 
27
- model = "gemini-2.0-flash" # Empfohlen für Tool-Calling [6]
28
-
29
- # Aufbau der Verbindung zum MCP-Server [9, 10]
30
  async with stdio_client(server_params) as (read, write):
31
  async with ClientSession(read, write) as session:
32
  await session.initialize()
33
 
34
- # MCP-Tools abrufen und für Gemini konvertieren [9, 11]
35
- mcp_tools_list = await session.list_tools()
36
  mcp_declarations = [
37
  {
38
  "name": tool.name,
39
- "description": tool.description or "Get train connections between stations",
40
  "parameters": tool.inputSchema,
41
  }
42
- for tool in mcp_tools_list.tools
43
  ]
44
 
45
- # Kombinierte Tools: Google Search + MCP Tools [2, 7]
46
  tools = [
47
  types.Tool(google_search=types.GoogleSearch()),
48
  types.Tool(function_declarations=mcp_declarations)
@@ -50,31 +51,29 @@ async def generate(input_text):
50
 
51
  contents = [types.Content(role="user", parts=[types.Part.from_text(text=input_text)])]
52
 
53
- # Initialer Aufruf
54
  response = await client.aio.models.generate_content(
55
  model=model,
56
  contents=contents,
57
- config=types.GenerateContentConfig(
58
- tools=tools,
59
- temperature=0.4
60
- )
61
  )
62
 
63
- contents.append(response.candidates.content)
64
-
65
- # Tool Calling Loop (für Fahrplandaten oder Google Search) [7, 8]
66
  turn_count = 0
67
  while response.function_calls and turn_count < 5:
68
  turn_count += 1
 
69
  tool_responses = []
70
 
71
  for fc in response.function_calls:
72
- # Ausführung der MCP-Tools (z.B. db_timetable_api_ui_wrapper) [8, 12]
73
  try:
 
74
  tool_result = await session.call_tool(fc.name, fc.args)
75
- result_text = tool_result.content.text if not tool_result.isError else tool_result.content.text
 
 
76
  tool_responses.append(types.Part.from_function_response(
77
- name=fc.name, response={"result": result_text}
78
  ))
79
  except Exception as e:
80
  tool_responses.append(types.Part.from_function_response(
@@ -82,22 +81,23 @@ async def generate(input_text):
82
  ))
83
 
84
  contents.append(types.Content(role="user", parts=tool_responses))
 
 
85
  response = await client.aio.models.generate_content(
86
  model=model, contents=contents, config=types.GenerateContentConfig(tools=tools)
87
  )
88
- contents.append(response.candidates.content)
89
 
90
  return response.text, ""
91
 
92
- # Gradio UI (Original Funktionalität und Design beibehalten) [13]
93
  def ui_wrapper(input_text):
94
  return asyncio.run(generate(input_text))
95
 
96
  if __name__ == '__main__':
97
  with gr.Blocks() as demo:
98
- gr.Markdown("# Gemini 2.0 Flash + Websearch + DB Timetable (MCP)")
99
  output_textbox = gr.Markdown()
100
- input_textbox = gr.Textbox(lines=3, label="", placeholder="Frage nach einer Zugverbindung (z.B. Berlin nach München)...")
101
  submit_button = gr.Button("Senden")
102
 
103
  submit_button.click(
@@ -109,7 +109,6 @@ if __name__ == '__main__':
109
 
110
 
111
 
112
-
113
  """
114
  import base64
115
  import gradio as gr
 
7
  from mcp import ClientSession, StdioServerParameters
8
  from mcp.client.stdio import stdio_client
9
 
10
+ # 1. Konfiguration des MCP-Servers via STDIO-Bridge
11
+ # Dies löst das SSE-Problem, indem npx mcp-remote die Kommunikation übernimmt [3].
12
  server_params = StdioServerParameters(
13
  command="npx",
14
  args=[
 
23
  try:
24
  client = genai.Client(api_key=os.environ.get("GEMINI_API_KEY"))
25
  except Exception as e:
26
+ return f"Fehler bei der Initialisierung: {e}", ""
27
 
28
+ model = "gemini-2.0-flash"
29
+
30
+ # 2. Aufbau der MCP-Session [4, 5]
31
  async with stdio_client(server_params) as (read, write):
32
  async with ClientSession(read, write) as session:
33
  await session.initialize()
34
 
35
+ # MCP-Tools abrufen und in Gemini-Format konvertieren [5, 6]
36
+ mcp_tools_data = await session.list_tools()
37
  mcp_declarations = [
38
  {
39
  "name": tool.name,
40
+ "description": tool.description or "Ruft Zugverbindungen ab.",
41
  "parameters": tool.inputSchema,
42
  }
43
+ for tool in mcp_tools_data.tools
44
  ]
45
 
46
+ # 3. Kombination der Tools: Google Search + DB-Timetable [5, 7]
47
  tools = [
48
  types.Tool(google_search=types.GoogleSearch()),
49
  types.Tool(function_declarations=mcp_declarations)
 
51
 
52
  contents = [types.Content(role="user", parts=[types.Part.from_text(text=input_text)])]
53
 
54
+ # Erster Aufruf an das Modell
55
  response = await client.aio.models.generate_content(
56
  model=model,
57
  contents=contents,
58
+ config=types.GenerateContentConfig(tools=tools, temperature=0.4)
 
 
 
59
  )
60
 
61
+ # 4. Agentic Loop: Bearbeitung von Tool-Calls (z.B. db_timetable_api_ui_wrapper) [8, 9]
 
 
62
  turn_count = 0
63
  while response.function_calls and turn_count < 5:
64
  turn_count += 1
65
+ contents.append(response.candidates.content)
66
  tool_responses = []
67
 
68
  for fc in response.function_calls:
 
69
  try:
70
+ # Ausführung des MCP-Tools [9]
71
  tool_result = await session.call_tool(fc.name, fc.args)
72
+
73
+ # Ergebnis formatieren (Erfolg oder Fehler) [9]
74
+ result_data = tool_result.content.text if not tool_result.isError else tool_result.content.text
75
  tool_responses.append(types.Part.from_function_response(
76
+ name=fc.name, response={"result": result_data}
77
  ))
78
  except Exception as e:
79
  tool_responses.append(types.Part.from_function_response(
 
81
  ))
82
 
83
  contents.append(types.Content(role="user", parts=tool_responses))
84
+
85
+ # Nächster Modell-Aufruf mit den Tool-Ergebnissen [10, 11]
86
  response = await client.aio.models.generate_content(
87
  model=model, contents=contents, config=types.GenerateContentConfig(tools=tools)
88
  )
 
89
 
90
  return response.text, ""
91
 
92
+ # 5. Gradio UI Integration [12]
93
  def ui_wrapper(input_text):
94
  return asyncio.run(generate(input_text))
95
 
96
  if __name__ == '__main__':
97
  with gr.Blocks() as demo:
98
+ gr.Markdown("# Gemini 2.0 Flash + Search + DB Timetable")
99
  output_textbox = gr.Markdown()
100
+ input_textbox = gr.Textbox(lines=3, label="Anfrage", placeholder="z.B. Wie komme ich von Berlin nach Hamburg?")
101
  submit_button = gr.Button("Senden")
102
 
103
  submit_button.click(
 
109
 
110
 
111
 
 
112
  """
113
  import base64
114
  import gradio as gr