| |
| import sys |
| import types |
|
|
| if 'audioop' not in sys.modules: |
| mock_audioop = types.ModuleType('audioop') |
| mock_audioop.error = Exception |
| mock_audioop.getsample = lambda data, width, index: 0 |
| sys.modules['audioop'] = mock_audioop |
| |
|
|
| import os |
| import sqlite3 |
| import pandas as pd |
| import json |
| import gradio as gr |
| from groq import Groq |
| import requests |
|
|
| |
| DB_NAME = "strides_production.db" |
|
|
| def init_db(): |
| conn = sqlite3.connect(DB_NAME) |
| cursor = conn.cursor() |
| cursor.execute(''' |
| CREATE TABLE IF NOT EXISTS project_tasks ( |
| id INTEGER PRIMARY KEY AUTOINCREMENT, |
| timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, |
| phase TEXT, |
| task_name TEXT, |
| owner TEXT, |
| timeline TEXT, |
| priority TEXT |
| ) |
| ''') |
| |
| cursor.execute("SELECT COUNT(*) FROM project_tasks") |
| if cursor.fetchone()[0] == 0: |
| dummy_data = [ |
| ('Discovery', 'Identify Deviation Root Cause', 'A. Sharma', 'Week 1', 'High'), |
| ('Data Prep', 'Clean LIMS Batch Records', 'R. Verma', 'Week 2-3', 'Medium'), |
| ('Modeling', 'Train Predictive Quality AI', 'S. Iyer', 'Week 4-5', 'High'), |
| ('Validation', 'Draft GxP Validation Protocol', 'M. Reddy', 'Week 6', 'High'), |
| ('Discovery', 'Audit Existing Logbook Manuals', 'P. Gupta', 'Week 1', 'Low'), |
| ('Data Prep', 'Standardize Sensor Timestamp Data', 'R. Verma', 'Week 2-3', 'Medium'), |
| ('Validation', 'Perform IQ/OQ/PQ for AI Model', 'M. Reddy', 'Week 6', 'High') |
| ] |
| cursor.executemany( |
| 'INSERT INTO project_tasks (phase, task_name, owner, timeline, priority) VALUES (?,?,?,?,?)', |
| dummy_data |
| ) |
| conn.commit() |
| conn.close() |
|
|
| init_db() |
|
|
| |
| GROQ_MODELS = [ |
| "llama-3.1-8b-instant", |
| "llama-3.1-70b-versatile", |
| "openai/gpt-oss-20b", |
| "whisper-large-v3-turbo" |
| ] |
|
|
| OPENROUTER_MODELS = [ |
| "nvidia/nemotron-3.5-content-safety:free", |
| "qwen/qwen3.7-plus", |
| "microsoft/mai-transcribe-1.5", |
| "google/gemini-embedding-2" |
| ] |
|
|
| def update_model_dropdown(provider): |
| if provider == "Groq": |
| return gr.Dropdown(choices=GROQ_MODELS, value=GROQ_MODELS[0], label="Target Engine Architecture") |
| elif provider == "OpenRouter": |
| return gr.Dropdown(choices=OPENROUTER_MODELS, value=OPENROUTER_MODELS[0], label="Target Engine Architecture") |
|
|
| |
| def call_llm(provider, api_key, model_choice, system_prompt, user_message, chat_history_format=None): |
| messages = [{"role": "system", "content": system_prompt}] |
| |
| if chat_history_format: |
| messages.extend(chat_history_format) |
| else: |
| messages.append({"role": "user", "content": user_message}) |
|
|
| if provider == "Groq": |
| client = Groq(api_key=api_key) |
| groq_model_map = { |
| "llama-3.1-8b-instant": "llama-3.1-8b-instant", |
| "llama-3.1-70b-versatile": "llama-3.1-70b-versatile", |
| "openai/gpt-oss-20b": "llama-3.1-8b-instant", |
| "whisper-large-v3-turbo": "whisper-large-v3-turbo" |
| } |
| target_model = groq_model_map.get(model_choice, "llama-3.1-8b-instant") |
| response = client.chat.completions.create( |
| model=target_model, messages=messages, temperature=0.0 |
| ) |
| return response.choices[0].message.content.strip() |
|
|
| elif provider == "OpenRouter": |
| headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"} |
| |
| |
| openrouter_model_map = { |
| "nvidia/nemotron-3.5-content-safety:free": "nvidia/nemotron-3.5-content-safety:free", |
| "qwen/qwen3.7-plus": "qwen/qwen3.7-plus", |
| "microsoft/mai-transcribe-1.5": "microsoft/mai-transcribe-1.5", |
| "google/gemini-embedding-2": "google/gemini-embedding-2" |
| } |
| target_model = openrouter_model_map.get(model_choice, "nvidia/nemotron-3.5-content-safety:free") |
| |
| payload = { |
| "model": target_model, |
| "messages": messages, |
| "temperature": 0.0 |
| } |
| response = requests.post("https://openrouter.ai/api/v1/chat/completions", headers=headers, json=payload) |
| if response.status_code == 200: |
| return response.json()['choices'][0]['message']['content'].strip() |
| else: |
| raise Exception(f"OpenRouter Gateway Alert ({response.status_code}): {response.text}") |
|
|
| |
| def execute_ai_query(provider, api_key, model_choice, user_question): |
| if not api_key.strip(): |
| return None, "β οΈ Please enter a valid API Key to proceed." |
| if not user_question.strip(): |
| return None, "β οΈ Please type a question or scenario." |
|
|
| system_prompt = ( |
| "You are an expert SQL assistant. The database table is called 'project_tasks' with columns: " |
| "[id, timestamp, phase, task_name, owner, timeline, priority]. " |
| "Return ONLY a valid, executable raw SQLite query based on the user's question. " |
| "Do not include any explanation, introductory markdown, markdown code block wrappers, or trailing text. " |
| "Output raw text only." |
| ) |
|
|
| try: |
| sql_query = call_llm(provider, api_key, model_choice, system_prompt, user_question) |
| sql_query = sql_query.replace("```sql", "").replace("```", "").replace("`", "").strip() |
|
|
| conn = sqlite3.connect(DB_NAME) |
| df = pd.read_sql_query(sql_query, conn) |
| conn.close() |
| return df, f"β‘ **Generated SQL Query:** `{sql_query}`" |
| except Exception as e: |
| return None, f"β Execution Failed: {str(e)}" |
|
|
| |
| def conversation_and_commit_agent(chat_history, provider, api_key, model_choice, user_msg): |
| if not api_key.strip(): |
| chat_history.append({"role": "assistant", "content": "β οΈ Authentication missing. Please input your API Key on the left menu pane."}) |
| return chat_history, "" |
| if not user_msg.strip(): |
| return chat_history, "" |
|
|
| system_prompt = ( |
| "You are a helpful conversational assistant and workflow coordinator for the Strides Pharma AI operational framework.\n" |
| "Your goal is twofold:\n" |
| "1. Respond to general conversational statements normally and professionally.\n" |
| "2. If the user expresses intent to log, add, or append a task milestone to the schedule, guide them or process it. " |
| "The required metrics are: Phase, Task_Name, Owner, Timeline, and Priority.\n\n" |
| "CRITICAL MECHANISM FOR DATA INSERTION:\n" |
| "If you have gathered or been explicitly provided structural task properties to log, you MUST append a raw JSON block at the very end of your final response text. " |
| "The format must exactly be: ||JSON_DATA: {\"phase\": \"...\", \"task_name\": \"...\", \"owner\": \"...\", \"timeline\": \"...\", \"priority\": \"...\"}||\n" |
| "If some schema details are completely absent, converse politely with the client to verify those remaining parameters before adding the string tag marker." |
| ) |
|
|
| formatted_history = [] |
| for turn in chat_history: |
| formatted_history.append({"role": turn["role"], "content": turn["content"]}) |
| formatted_history.append({"role": "user", "content": user_msg}) |
|
|
| try: |
| raw_response = call_llm(provider, api_key, model_choice, system_prompt, "", chat_history_format=formatted_history) |
| |
| cleaned_response = raw_response |
| database_committed_alert = "" |
| |
| if "||JSON_DATA:" in raw_response: |
| try: |
| parts = raw_response.split("||JSON_DATA:") |
| cleaned_response = parts[0].strip() |
| json_string = parts[1].replace("||", "").strip() |
| |
| data_payload = json.loads(json_string) |
| |
| conn = sqlite3.connect(DB_NAME) |
| cursor = conn.cursor() |
| cursor.execute( |
| "INSERT INTO project_tasks (phase, task_name, owner, timeline, priority) VALUES (?, ?, ?, ?, ?)", |
| (data_payload.get('phase'), data_payload.get('task_name'), data_payload.get('owner'), data_payload.get('timeline'), data_payload.get('priority')) |
| ) |
| conn.commit() |
| conn.close() |
| |
| database_committed_alert = "\n\nβοΈ **[SYSTEM UPDATE]:** Successfully appended task '" + str(data_payload.get('task_name')) + "' to the internal server database master record structure." |
| except Exception as inner_err: |
| database_committed_alert = "\n\nβ οΈ **[SYSTEM NOTICE]:** Captured structure request token, but insertion execution aborted due to tracking parsing discrepancies: " + str(inner_err) |
|
|
| final_display_text = cleaned_response + database_committed_alert |
| |
| chat_history.append({"role": "user", "content": user_msg}) |
| chat_history.append({"role": "assistant", "content": final_display_text}) |
| return chat_history, "" |
|
|
| except Exception as e: |
| chat_history.append({"role": "user", "content": user_msg}) |
| chat_history.append({"role": "assistant", "content": f"β API Connection Failure: {str(e)}"}) |
| return chat_history, "" |
|
|
| |
| with gr.Blocks(theme=gr.themes.Soft()) as demo: |
| gr.Markdown("# π Strides Pharma AI Production & Data Portal") |
| gr.Markdown("Orchestrate production tasks, converse with core system workflows, and modify infrastructure records securely.") |
| |
| with gr.Row(): |
| with gr.Column(scale=1): |
| gr.Markdown("### π Global Control Tower") |
| provider_select = gr.Dropdown(choices=["Groq", "OpenRouter"], value="Groq", label="API Gateway Provider") |
| token_input = gr.Textbox(label="User API Secret Key", type="password", placeholder="gsk_... or sk-or-...") |
| |
| |
| model_select = gr.Dropdown( |
| choices=GROQ_MODELS, |
| value=GROQ_MODELS[0], |
| label="Target Engine Architecture" |
| ) |
| |
| gr.Markdown("β¨ **Global Platform Database State Schema:**\n- `phase` (Discovery, Data Prep, Modeling, Validation)\n- `task_name` (Structural workflow description string)\n- `owner` (Assigned personnel scientist name)\n- `timeline` (Expected operational delivery time frames)\n- `priority` (High, Medium, Low)") |
| |
| with gr.Column(scale=2): |
| with gr.Tabs(): |
| |
| with gr.TabItem("π€ Interactive Data Contributor Chatbot"): |
| gr.Markdown("### Conversational Contributor Agent") |
| gr.Markdown("Chat with this engine normally, or tell it to log a brand-new task assignment milestone directly into the active SQLite infrastructure.") |
| |
| chatbot_viewport = gr.Chatbot(type="messages", label="Operational History Workspace") |
| chat_input = gr.Textbox(placeholder="Say hello, or submit task details to log...", label="Your Message") |
| send_btn = gr.Button("Submit Message", variant="primary") |
| |
| send_btn.click( |
| fn=conversation_and_commit_agent, |
| inputs=[chatbot_viewport, provider_select, token_input, model_select, chat_input], |
| outputs=[chatbot_viewport, chat_input] |
| ) |
| chat_input.submit( |
| fn=conversation_and_commit_agent, |
| inputs=[chatbot_viewport, provider_select, token_input, model_select, chat_input], |
| outputs=[chatbot_viewport, chat_input] |
| ) |
| |
| with gr.TabItem("π SQL Inquisitor Desk"): |
| gr.Markdown("### Natural Language SQL Query Engine") |
| query_input = gr.Textbox(label="Query the current database contents using conversational English:", placeholder="e.g., Show me all records sorted by priority status") |
| query_btn = gr.Button("Evaluate Infrastructure", variant="secondary") |
| |
| sql_status_display = gr.Markdown() |
| output_data_table = gr.DataFrame(label="Queried Records Dataframe Live Output") |
| |
| query_btn.click( |
| fn=execute_ai_query, |
| inputs=[provider_select, token_input, model_select, query_input], |
| outputs=[output_data_table, sql_status_display] |
| ) |
|
|
| |
| |
| provider_select.change( |
| fn=update_model_dropdown, |
| inputs=[provider_select], |
| outputs=[model_select] |
| ) |
|
|
| if __name__ == "__main__": |
| demo.launch() |
|
|