Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -297,81 +297,6 @@ class HybridAIAssistant:
|
|
| 297 |
logger.error(f"Request failed: {e}")
|
| 298 |
return self.get_fallback_response(message)
|
| 299 |
|
| 300 |
-
def get_streaming_response(self, message: str, billing_context: bool = False) -> Iterator[str]:
|
| 301 |
-
"""Get streaming response from OpenRouter API"""
|
| 302 |
-
|
| 303 |
-
# Prepare system prompt
|
| 304 |
-
system_prompt = """You are a helpful, friendly AI assistant with expertise in healthcare billing codes.
|
| 305 |
-
You can assist with any topic - from casual conversation to complex questions.
|
| 306 |
-
When discussing medical billing codes, you provide accurate, detailed information.
|
| 307 |
-
Be conversational, helpful, and engaging. Use emojis occasionally to be friendly.
|
| 308 |
-
Keep responses concise but informative."""
|
| 309 |
-
|
| 310 |
-
if billing_context:
|
| 311 |
-
system_prompt += "\nThe user is asking about medical billing. Provide helpful information even if you don't have specific code details."
|
| 312 |
-
|
| 313 |
-
# Build conversation history for context
|
| 314 |
-
messages = [{'role': 'system', 'content': system_prompt}]
|
| 315 |
-
|
| 316 |
-
# Add recent conversation history
|
| 317 |
-
for msg in self.context.messages[-10:]:
|
| 318 |
-
messages.append(msg)
|
| 319 |
-
|
| 320 |
-
# Add current message
|
| 321 |
-
messages.append({'role': 'user', 'content': message})
|
| 322 |
-
|
| 323 |
-
try:
|
| 324 |
-
response = requests.post(
|
| 325 |
-
'https://openrouter.ai/api/v1/chat/completions',
|
| 326 |
-
headers=self.headers,
|
| 327 |
-
json={
|
| 328 |
-
'model': 'openai/gpt-3.5-turbo',
|
| 329 |
-
'messages': messages,
|
| 330 |
-
'temperature': 0.7,
|
| 331 |
-
'max_tokens': 500,
|
| 332 |
-
'stream': True
|
| 333 |
-
},
|
| 334 |
-
timeout=30,
|
| 335 |
-
stream=True
|
| 336 |
-
)
|
| 337 |
-
|
| 338 |
-
if response.status_code == 200:
|
| 339 |
-
full_response = ""
|
| 340 |
-
for line in response.iter_lines():
|
| 341 |
-
if line:
|
| 342 |
-
line = line.decode('utf-8')
|
| 343 |
-
if line.startswith('data: '):
|
| 344 |
-
line = line[6:]
|
| 345 |
-
if line.strip() == '[DONE]':
|
| 346 |
-
break
|
| 347 |
-
try:
|
| 348 |
-
chunk = json.loads(line)
|
| 349 |
-
if 'choices' in chunk and len(chunk['choices']) > 0:
|
| 350 |
-
delta = chunk['choices'][0].get('delta', {})
|
| 351 |
-
if 'content' in delta:
|
| 352 |
-
content = delta['content']
|
| 353 |
-
full_response += content
|
| 354 |
-
yield full_response
|
| 355 |
-
except json.JSONDecodeError:
|
| 356 |
-
continue
|
| 357 |
-
|
| 358 |
-
# Update context with full response
|
| 359 |
-
self.context.messages.append({'role': 'user', 'content': message})
|
| 360 |
-
self.context.messages.append({'role': 'assistant', 'content': full_response})
|
| 361 |
-
|
| 362 |
-
# Keep only last 20 messages in context
|
| 363 |
-
if len(self.context.messages) > 20:
|
| 364 |
-
self.context.messages = self.context.messages[-20:]
|
| 365 |
-
|
| 366 |
-
else:
|
| 367 |
-
fallback = self.get_fallback_response(message)
|
| 368 |
-
yield fallback
|
| 369 |
-
|
| 370 |
-
except Exception as e:
|
| 371 |
-
logger.error(f"Streaming request failed: {e}")
|
| 372 |
-
fallback = self.get_fallback_response(message)
|
| 373 |
-
yield fallback
|
| 374 |
-
|
| 375 |
def get_fallback_response(self, message: str) -> str:
|
| 376 |
"""Fallback responses when API fails"""
|
| 377 |
fallbacks = [
|
|
@@ -382,20 +307,19 @@ class HybridAIAssistant:
|
|
| 382 |
]
|
| 383 |
return random.choice(fallbacks)
|
| 384 |
|
| 385 |
-
def
|
| 386 |
-
"""Main method to process any message
|
| 387 |
if not message.strip():
|
| 388 |
-
|
| 389 |
-
return
|
| 390 |
|
| 391 |
# Detect intent
|
| 392 |
intent = self.detect_intent(message)
|
| 393 |
|
| 394 |
# Route to appropriate handler
|
| 395 |
if intent['is_billing'] and intent['codes_found']:
|
| 396 |
-
|
| 397 |
else:
|
| 398 |
-
|
| 399 |
|
| 400 |
def reset_context(self):
|
| 401 |
"""Reset conversation context"""
|
|
@@ -406,22 +330,21 @@ assistant = HybridAIAssistant()
|
|
| 406 |
|
| 407 |
# ============= Chat Functions =============
|
| 408 |
|
| 409 |
-
def
|
| 410 |
-
"""
|
| 411 |
if not message.strip():
|
| 412 |
-
|
| 413 |
-
return
|
| 414 |
|
| 415 |
-
# Process message
|
| 416 |
-
|
| 417 |
-
|
| 418 |
|
| 419 |
def reset_chat():
|
| 420 |
"""Reset the conversation context"""
|
| 421 |
assistant.reset_context()
|
| 422 |
-
return
|
| 423 |
|
| 424 |
-
# ============= Examples
|
| 425 |
|
| 426 |
examples = [
|
| 427 |
"What is healthcare billing code A0429?",
|
|
@@ -474,21 +397,6 @@ def create_interface():
|
|
| 474 |
opacity: 0.9;
|
| 475 |
}
|
| 476 |
|
| 477 |
-
.examples-container {
|
| 478 |
-
margin: 1rem 0;
|
| 479 |
-
padding: 1rem;
|
| 480 |
-
background: #f8fafc;
|
| 481 |
-
border-radius: 12px;
|
| 482 |
-
border: 1px solid #e2e8f0;
|
| 483 |
-
}
|
| 484 |
-
|
| 485 |
-
.examples-title {
|
| 486 |
-
color: #4a5568;
|
| 487 |
-
font-weight: 600;
|
| 488 |
-
margin-bottom: 0.5rem;
|
| 489 |
-
text-align: center;
|
| 490 |
-
}
|
| 491 |
-
|
| 492 |
.reset-btn {
|
| 493 |
background: #f56565 !important;
|
| 494 |
color: white !important;
|
|
@@ -516,27 +424,9 @@ def create_interface():
|
|
| 516 |
|
| 517 |
# Main Chat Interface
|
| 518 |
chat_interface = gr.ChatInterface(
|
| 519 |
-
fn=
|
| 520 |
-
title="", # We have custom header
|
| 521 |
-
description="", # We have custom header
|
| 522 |
examples=examples,
|
| 523 |
-
cache_examples=False
|
| 524 |
-
retry_btn="π Retry",
|
| 525 |
-
undo_btn="β©οΈ Undo",
|
| 526 |
-
clear_btn="ποΈ Clear",
|
| 527 |
-
submit_btn="Send π€",
|
| 528 |
-
chatbot=gr.Chatbot(
|
| 529 |
-
height=600,
|
| 530 |
-
show_copy_button=True,
|
| 531 |
-
show_share_button=False,
|
| 532 |
-
avatar_images=["π€", "π€"]
|
| 533 |
-
),
|
| 534 |
-
textbox=gr.Textbox(
|
| 535 |
-
placeholder="Ask me anything... (e.g., 'Explain code 99213' or 'Help me write a story')",
|
| 536 |
-
scale=7,
|
| 537 |
-
lines=1,
|
| 538 |
-
max_lines=8
|
| 539 |
-
)
|
| 540 |
)
|
| 541 |
|
| 542 |
# Additional controls
|
|
@@ -574,10 +464,7 @@ def create_interface():
|
|
| 574 |
# Connect reset button
|
| 575 |
reset_context_btn.click(
|
| 576 |
fn=reset_chat,
|
| 577 |
-
|
| 578 |
-
outputs=None
|
| 579 |
-
).then(
|
| 580 |
-
lambda: gr.Info("Context reset! Starting fresh conversation.")
|
| 581 |
)
|
| 582 |
|
| 583 |
return demo
|
|
|
|
| 297 |
logger.error(f"Request failed: {e}")
|
| 298 |
return self.get_fallback_response(message)
|
| 299 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 300 |
def get_fallback_response(self, message: str) -> str:
|
| 301 |
"""Fallback responses when API fails"""
|
| 302 |
fallbacks = [
|
|
|
|
| 307 |
]
|
| 308 |
return random.choice(fallbacks)
|
| 309 |
|
| 310 |
+
def process_message(self, message: str) -> str:
|
| 311 |
+
"""Main method to process any message"""
|
| 312 |
if not message.strip():
|
| 313 |
+
return "Feel free to ask me anything! I can help with general questions or healthcare billing codes. π"
|
|
|
|
| 314 |
|
| 315 |
# Detect intent
|
| 316 |
intent = self.detect_intent(message)
|
| 317 |
|
| 318 |
# Route to appropriate handler
|
| 319 |
if intent['is_billing'] and intent['codes_found']:
|
| 320 |
+
return self.handle_billing_query(message, intent['codes_found'])
|
| 321 |
else:
|
| 322 |
+
return self.get_general_response(message, billing_context=intent['is_billing'])
|
| 323 |
|
| 324 |
def reset_context(self):
|
| 325 |
"""Reset conversation context"""
|
|
|
|
| 330 |
|
| 331 |
# ============= Chat Functions =============
|
| 332 |
|
| 333 |
+
def respond(message, history):
|
| 334 |
+
"""Response function for ChatInterface"""
|
| 335 |
if not message.strip():
|
| 336 |
+
return "Feel free to ask me anything! I can help with general questions or healthcare billing codes. π"
|
|
|
|
| 337 |
|
| 338 |
+
# Process message
|
| 339 |
+
response = assistant.process_message(message)
|
| 340 |
+
return response
|
| 341 |
|
| 342 |
def reset_chat():
|
| 343 |
"""Reset the conversation context"""
|
| 344 |
assistant.reset_context()
|
| 345 |
+
return []
|
| 346 |
|
| 347 |
+
# ============= Examples =============
|
| 348 |
|
| 349 |
examples = [
|
| 350 |
"What is healthcare billing code A0429?",
|
|
|
|
| 397 |
opacity: 0.9;
|
| 398 |
}
|
| 399 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 400 |
.reset-btn {
|
| 401 |
background: #f56565 !important;
|
| 402 |
color: white !important;
|
|
|
|
| 424 |
|
| 425 |
# Main Chat Interface
|
| 426 |
chat_interface = gr.ChatInterface(
|
| 427 |
+
fn=respond,
|
|
|
|
|
|
|
| 428 |
examples=examples,
|
| 429 |
+
cache_examples=False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 430 |
)
|
| 431 |
|
| 432 |
# Additional controls
|
|
|
|
| 464 |
# Connect reset button
|
| 465 |
reset_context_btn.click(
|
| 466 |
fn=reset_chat,
|
| 467 |
+
outputs=chat_interface.chatbot
|
|
|
|
|
|
|
|
|
|
| 468 |
)
|
| 469 |
|
| 470 |
return demo
|