Ganesh Chintalapati commited on
Commit
0696c74
·
1 Parent(s): 74a52a0

change from dropdown to checkbox

Browse files
Files changed (1) hide show
  1. app.py +38 -192
app.py CHANGED
@@ -17,207 +17,53 @@ logger.info(f"OPENAI_API_KEY present: {'OPENAI_API_KEY' in os.environ}")
17
  logger.info(f"ANTHROPIC_API_KEY present: {'ANTHROPIC_API_KEY' in os.environ}")
18
  logger.info(f"GEMINI_API_KEY present: {'GEMINI_API_KEY' in os.environ}")
19
 
20
- async def ask_openai(query: str, history: List[Dict[str, str]]) -> AsyncGenerator[str, None]:
21
- openai_api_key = os.getenv("OPENAI_API_KEY")
22
- if not openai_api_key:
23
- logger.error("OpenAI API key not provided")
24
- yield "Error: OpenAI API key not provided."
25
- return
26
-
27
- # Build message history
28
- messages = []
29
- for msg in history:
30
- messages.append({"role": "user", "content": msg["user"]})
31
- if msg["bot"]:
32
- messages.append({"role": "assistant", "content": msg["bot"]})
33
- messages.append({"role": "user", "content": query})
34
-
35
- headers = {
36
- "Authorization": f"Bearer {openai_api_key}",
37
- "Content-Type": "application/json"
38
- }
39
-
40
- payload = {
41
- "model": "gpt-4o-mini",
42
- "messages": messages,
43
- "stream": True
44
- }
45
-
46
- try:
47
- async with httpx.AsyncClient() as client:
48
- async with client.stream("POST", "https://api.openai.com/v1/chat/completions", headers=headers, json=payload) as response:
49
- response.raise_for_status()
50
- async for chunk in response.aiter_text():
51
- if chunk:
52
- # Parse the streaming chunk (JSON lines)
53
- lines = chunk.splitlines()
54
- for line in lines:
55
- if line.startswith("data: "):
56
- data = line[6:] # Remove "data: " prefix
57
- if data == "[DONE]":
58
- break
59
- if not data.strip():
60
- continue
61
- try:
62
- json_data = json.loads(data) # Safely parse JSON
63
- if "choices" in json_data and json_data["choices"]:
64
- delta = json_data["choices"][0].get("delta", {})
65
- if "content" in delta and delta["content"] is not None:
66
- yield delta["content"]
67
- except json.JSONDecodeError as e:
68
- logger.error(f"Error parsing OpenAI stream chunk: {str(e)} - Data: {data}")
69
- yield f"Error parsing stream: {str(e)}"
70
- except Exception as e:
71
- logger.error(f"Unexpected error in OpenAI stream: {str(e)} - Data: {data}")
72
- yield f"Error in stream: {str(e)}"
73
-
74
- except httpx.HTTPStatusError as e:
75
- # Read the response body for streaming responses
76
- response_text = await e.response.aread()
77
- logger.error(f"OpenAI HTTP Status Error: {e.response.status_code}, {response_text}")
78
- yield f"Error: OpenAI HTTP Status Error: {e.response.status_code}, {response_text.decode('utf-8')}"
79
- except Exception as e:
80
- logger.error(f"OpenAI Error: {str(e)}")
81
- yield f"Error: OpenAI Error: {str(e)}"
82
-
83
- async def ask_anthropic(query: str, history: List[Dict[str, str]]) -> str:
84
- anthropic_api_key = os.getenv("ANTHROPIC_API_KEY")
85
- if not anthropic_api_key:
86
- logger.error("Anthropic API key not provided")
87
- return "Error: Anthropic API key not provided."
88
-
89
- # Build message history
90
- messages = []
91
- for msg in history:
92
- messages.append({"role": "user", "content": msg["user"]})
93
- if msg["bot"]:
94
- messages.append({"role": "assistant", "content": msg["bot"]})
95
- messages.append({"role": "user", "content": query})
96
-
97
- headers = {
98
- "x-api-key": anthropic_api_key,
99
- "anthropic-version": "2023-06-01",
100
- "Content-Type": "application/json"
101
- }
102
-
103
- payload = {
104
- "model": "claude-3-5-sonnet-20241022",
105
- "max_tokens": 1024,
106
- "messages": messages
107
- }
108
-
109
- try:
110
- async with httpx.AsyncClient() as client:
111
- logger.info(f"Sending Anthropic request: {payload}")
112
- response = await client.post("https://api.anthropic.com/v1/messages", headers=headers, json=payload)
113
-
114
- response.raise_for_status()
115
- logger.info(f"Anthropic response: {response.json()}")
116
- return response.json()['content'][0]['text']
117
-
118
- except httpx.HTTPStatusError as e:
119
- logger.error(f"Anthropic HTTP Status Error: {e.response.status_code}, {e.response.text}")
120
- return f"Error: Anthropic HTTP Status Error: {e.response.status_code}, {e.response.text}"
121
- except Exception as e:
122
- logger.error(f"Anthropic Error: {str(e)}")
123
- return f"Error: Anthropic Error: {str(e)}"
124
 
125
- async def ask_gemini(query: str, history: List[Dict[str, str]]) -> str:
126
- gemini_api_key = os.getenv("GEMINI_API_KEY")
127
- if not gemini_api_key:
128
- logger.error("Gemini API key not provided")
129
- return "Error: Gemini API key not provided."
130
-
131
- # Gemini doesn't natively support chat history in the same way, so we concatenate history as text
132
- history_text = ""
133
- for msg in history:
134
- history_text += f"User: {msg['user']}\nAssistant: {msg['bot']}\n" if msg["bot"] else f"User: {msg['user']}\n"
135
- full_query = history_text + f"User: {query}\n"
136
-
137
- headers = {
138
- "Content-Type": "application/json"
139
- }
140
-
141
- payload = {
142
- "contents": [{"parts": [{"text": full_query}]}]
143
- }
144
-
145
- try:
146
- async with httpx.AsyncClient() as client:
147
- response = await client.post(
148
- f"https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key={gemini_api_key}",
149
- headers=headers,
150
- json=payload
151
- )
152
-
153
- response.raise_for_status()
154
- return response.json()['candidates'][0]['content']['parts'][0]['text']
155
-
156
- except httpx.HTTPStatusError as e:
157
- logger.error(f"Gemini HTTP Status Error: {e.response.status_code}, {e.response.text}")
158
- return f"Error: Gemini HTTP Status Error: {e.response.status_code}, {e.response.text}"
159
- except Exception as e:
160
- logger.error(f"Gemini Error: {str(e)}")
161
- return f"Error: Gemini Error: {str(e)}"
162
-
163
- async def query_model(query: str, provider: str, history: List[Dict[str, str]]) -> AsyncGenerator[Tuple[str, List[Dict[str, str]]], None]:
164
- provider = provider.lower()
165
- response = "" # Initialize response to avoid UnboundLocalError
166
 
167
- logger.info(f"Processing query with provider: {provider}")
168
- if provider == "openai":
169
- async for chunk in ask_openai(query, history):
170
- response += chunk
171
- yield chunk, history # Yield partial response for streaming
172
- elif provider == "anthropic":
173
- response = await ask_anthropic(query, history)
174
- yield response, history
175
- elif provider == "gemini":
176
- response = await ask_gemini(query, history)
177
- yield response, history
178
- else:
179
- response = f"Error: Unknown provider: {provider}"
180
- logger.error(response)
181
- yield response, history
182
-
183
- # Update history with the new query and response
184
- updated_history = history + [{"user": query, "bot": response}]
 
 
 
185
  logger.info(f"Updated history: {updated_history}")
186
- yield response, updated_history # Final yield with updated history
187
 
188
- async def submit_query(query: str, provider: str, history: List[Dict[str, str]]) -> AsyncGenerator[Tuple[str, List[Dict[str, str]], List[Dict[str, str]]], None]:
189
  if not query.strip():
190
- yield "", [{"role": "assistant", "content": "Please enter a query."}], history
191
  return
192
 
193
- response = ""
194
  chatbot_messages = []
195
  for msg in history:
196
  chatbot_messages.append({"role": "user", "content": msg["user"]})
197
  if msg["bot"]:
198
  chatbot_messages.append({"role": "assistant", "content": msg["bot"]})
199
- async for response_chunk, updated_history in query_model(query, provider, history):
200
- response += response_chunk
201
- # Update chatbot messages for streaming
202
- chatbot_messages = []
203
- for msg in updated_history:
204
- chatbot_messages.append({"role": "user", "content": msg["user"]})
205
- if msg["bot"]:
206
- chatbot_messages.append({"role": "assistant", "content": msg["bot"]})
207
- if response and provider == "openai":
208
- # For streaming, show partial response
209
- if chatbot_messages and chatbot_messages[-1]["role"] == "user":
210
- chatbot_messages.append({"role": "assistant", "content": response})
211
- else:
212
- chatbot_messages[-1] = {"role": "assistant", "content": response}
213
- yield "", chatbot_messages, updated_history # Yield to chatbot, not query
214
- # Final yield with complete response
215
- chatbot_messages = []
216
- for msg in updated_history:
217
- chatbot_messages.append({"role": "user", "content": msg["user"]})
218
- if msg["bot"]:
219
- chatbot_messages.append({"role": "assistant", "content": msg["bot"]})
220
- yield "", chatbot_messages, updated_history
221
 
222
  # Gradio interface
223
  def clear_history():
@@ -226,9 +72,9 @@ def clear_history():
226
  # Define Gradio interface
227
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
228
  gr.Markdown("# Multi-Model Chat")
229
- gr.Markdown("Chat with OpenAI, Anthropic, or Gemini. Select a provider and start typing!")
230
 
231
- provider = gr.Dropdown(choices=["OpenAI", "Anthropic", "Gemini"], label="Select Provider", value="OpenAI")
232
  history_state = gr.State(value=[])
233
  chatbot = gr.Chatbot(label="Conversation", type="messages")
234
  query = gr.Textbox(label="Enter your query", placeholder="e.g., What is the capital of the United States?")
@@ -238,7 +84,7 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
238
  submit_button.click(
239
  fn=submit_query,
240
  inputs=[query, provider, history_state],
241
- outputs=[query, chatbot, history_state]
242
  )
243
  clear_button.click(
244
  fn=clear_history,
 
17
  logger.info(f"ANTHROPIC_API_KEY present: {'ANTHROPIC_API_KEY' in os.environ}")
18
  logger.info(f"GEMINI_API_KEY present: {'GEMINI_API_KEY' in os.environ}")
19
 
20
+ # Asking functions remain the same ...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
 
22
+ async def query_model(query: str, providers: List[str], history: List[Dict[str, str]]) -> AsyncGenerator[List[Tuple[str, str]], None]:
23
+ responses = []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
 
25
+ for provider in providers:
26
+ provider = provider.lower()
27
+ response = ""
28
+ logger.info(f"Processing query with provider: {provider}")
29
+ if provider == "openai":
30
+ async for chunk in ask_openai(query, history):
31
+ response += chunk
32
+ yield [(provider, response)], history
33
+ elif provider == "anthropic":
34
+ response = await ask_anthropic(query, history)
35
+ responses.append((provider, response))
36
+ elif provider == "gemini":
37
+ response = await ask_gemini(query, history)
38
+ responses.append((provider, response))
39
+ else:
40
+ response = f"Error: Unknown provider: {provider}"
41
+ logger.error(response)
42
+ responses.append((provider, response))
43
+
44
+ # Update history with the new query and responses
45
+ updated_history = history + [{"user": query, "bot": " | ".join(resp[1] for resp in responses)}]
46
  logger.info(f"Updated history: {updated_history}")
47
+ yield responses, updated_history # Final yield with updated history
48
 
49
+ async def submit_query(query: str, providers: List[str], history: List[Dict[str, str]]) -> AsyncGenerator[List[str], None]:
50
  if not query.strip():
51
+ yield ["Please enter a query."], history
52
  return
53
 
54
+ responses = []
55
  chatbot_messages = []
56
  for msg in history:
57
  chatbot_messages.append({"role": "user", "content": msg["user"]})
58
  if msg["bot"]:
59
  chatbot_messages.append({"role": "assistant", "content": msg["bot"]})
60
+
61
+ async for response_group, updated_history in query_model(query, providers, history):
62
+ for provider, response in response_group:
63
+ responses.append(f"{provider.capitalize()}: {response}")
64
+ chatbot_messages.append({"role": "assistant", "content": f"{provider.capitalize()}: {response}"})
65
+
66
+ yield responses, chatbot_messages, updated_history
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
 
68
  # Gradio interface
69
  def clear_history():
 
72
  # Define Gradio interface
73
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
74
  gr.Markdown("# Multi-Model Chat")
75
+ gr.Markdown("Chat with OpenAI, Anthropic, or Gemini. Select one or multiple providers and start typing!")
76
 
77
+ provider = gr.CheckboxGroup(choices=["OpenAI", "Anthropic", "Gemini"], label="Select Provider")
78
  history_state = gr.State(value=[])
79
  chatbot = gr.Chatbot(label="Conversation", type="messages")
80
  query = gr.Textbox(label="Enter your query", placeholder="e.g., What is the capital of the United States?")
 
84
  submit_button.click(
85
  fn=submit_query,
86
  inputs=[query, provider, history_state],
87
+ outputs=[chatbot, history_state]
88
  )
89
  clear_button.click(
90
  fn=clear_history,