Aigenthix commited on
Commit
e690a4a
Β·
verified Β·
1 Parent(s): 4d76161

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +156 -92
app.py CHANGED
@@ -12,8 +12,8 @@ if 'audioop' not in sys.modules:
12
  import os
13
  import sqlite3
14
  import pandas as pd
 
15
  import gradio as gr
16
- from datetime import datetime
17
  from groq import Groq
18
  import requests
19
 
@@ -55,7 +55,47 @@ def init_db():
55
 
56
  init_db()
57
 
58
- # --- Core Query Logic ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  def execute_ai_query(provider, api_key, model_choice, user_question):
60
  if not api_key.strip():
61
  return None, "⚠️ Please enter a valid API Key to proceed."
@@ -70,117 +110,141 @@ def execute_ai_query(provider, api_key, model_choice, user_question):
70
  "Output raw text only."
71
  )
72
 
73
- # Context map adjustment for audio transcription models vs LLM text interfaces
74
- if "whisper" in model_choice.lower():
75
- system_prompt += " Even though your engine architecture is optimized for transcription pipelines, execute this as text-to-SQL logic and return only the raw SQLite string."
76
-
77
  try:
78
- sql_query = ""
79
-
80
- # Choice A: Groq API Gateway Routing
81
- if provider == "Groq":
82
- client = Groq(api_key=api_key)
83
-
84
- # Map clean names to Groq-supported technical production IDs
85
- groq_model_map = {
86
- "llama-3.1-8b-instant": "llama-3.1-8b-instant",
87
- "llama-3.1-70b-versatile": "llama-3.1-70b-versatile",
88
- "openai/gpt-oss-20b": "llama-3.1-8b-instant", # Fallback map if provider doesn't host open-source mock
89
- "whisper-large-v3-turbo": "whisper-large-v3-turbo"
90
- }
91
- target_model = groq_model_map.get(model_choice, "llama-3.1-8b-instant")
92
-
93
- response = client.chat.completions.create(
94
- model=target_model,
95
- messages=[
96
- {"role": "system", "content": system_prompt},
97
- {"role": "user", "content": user_question}
98
- ],
99
- temperature=0.0
100
- )
101
- sql_query = response.choices[0].message.content.strip()
102
-
103
- # Choice B: OpenRouter API Gateway Routing
104
- elif provider == "OpenRouter":
105
- headers = {
106
- "Authorization": f"Bearer {api_key}",
107
- "Content-Type": "application/json"
108
- }
109
-
110
- # Map clean names to OpenRouter specific global endpoints
111
- openrouter_model_map = {
112
- "llama-3.1-8b-instant": "meta-llama/llama-3.1-8b-instruct",
113
- "llama-3.1-70b-versatile": "meta-llama/llama-3.1-70b-instruct",
114
- "openai/gpt-oss-20b": "openai/gpt-3.5-turbo", # Routed fallback target
115
- "whisper-large-v3-turbo": "meta-llama/llama-3.1-8b-instruct" # Text fallback routing
116
- }
117
- target_model = openrouter_model_map.get(model_choice, "meta-llama/llama-3.1-8b-instruct")
118
-
119
- payload = {
120
- "model": target_model,
121
- "messages": [
122
- {"role": "system", "content": system_prompt},
123
- {"role": "user", "content": user_question}
124
- ],
125
- "temperature": 0.0
126
- }
127
- response = requests.post("https://openrouter.ai/api/v1/chat/completions", headers=headers, json=payload)
128
- if response.status_code == 200:
129
- sql_query = response.json()['choices'][0]['message']['content'].strip()
130
- else:
131
- return None, f"❌ OpenRouter Error: {response.text}"
132
-
133
- # Clean formatting wrappers from LLM output
134
  sql_query = sql_query.replace("```sql", "").replace("```", "").replace("`", "").strip()
135
 
136
- # Execute query securely against local SQLite engine
137
  conn = sqlite3.connect(DB_NAME)
138
  df = pd.read_sql_query(sql_query, conn)
139
  conn.close()
 
 
 
140
 
141
- return df, f"⚑ **Generated SQL Query via {model_choice}:** `{sql_query}`"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
142
 
143
  except Exception as e:
144
- return None, f"❌ Execution Failed: {str(e)}"
 
 
145
 
146
- # --- Interface Layout ---
147
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
148
- gr.Markdown("# πŸ’Š Strides Pharma AI Data Portal")
149
- gr.Markdown("Transform conversational natural language directly into validated SQL operations.")
150
 
151
  with gr.Row():
 
152
  with gr.Column(scale=1):
153
- gr.Markdown("### πŸ”‘ Authentication & LLM Setup")
154
  provider_select = gr.Dropdown(choices=["Groq", "OpenRouter"], value="Groq", label="API Gateway Provider")
155
  token_input = gr.Textbox(label="User API Secret Key", type="password", placeholder="gsk_... or sk-or-...")
156
-
157
- # Updated Model Selection Field
158
  model_select = gr.Dropdown(
159
- choices=[
160
- "llama-3.1-8b-instant",
161
- "llama-3.1-70b-versatile",
162
- "openai/gpt-oss-20b",
163
- "whisper-large-v3-turbo"
164
- ],
165
  value="llama-3.1-8b-instant",
166
- label="Target Language Model"
167
  )
 
168
 
169
- gr.Markdown("πŸ’‘ **Sample Queries to try:**\n- *Show me all tasks where priority is High*\n- *List tasks owned by M. Reddy*\n- *Count the number of tasks in each phase*")
170
-
171
  with gr.Column(scale=2):
172
- gr.Markdown("### πŸ€– Data Query Desk")
173
- query_input = gr.Textbox(label="Ask your database a question:", placeholder="e.g., Show all tasks in the Validation phase")
174
- submit_btn = gr.Button("Query Database Infrastructure", variant="primary")
175
-
176
- sql_status = gr.Markdown()
177
- output_table = gr.DataFrame(label="Queried Records Dataframe Output")
178
-
179
- submit_btn.click(
180
- fn=execute_ai_query,
181
- inputs=[provider_select, token_input, model_select, query_input],
182
- outputs=[output_table, sql_status]
183
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
184
 
185
  if __name__ == "__main__":
186
  demo.launch()
 
12
  import os
13
  import sqlite3
14
  import pandas as pd
15
+ import json
16
  import gradio as gr
 
17
  from groq import Groq
18
  import requests
19
 
 
55
 
56
  init_db()
57
 
58
+ # --- Common LLM API Request Orchestrator ---
59
+ def call_llm(provider, api_key, model_choice, system_prompt, user_message, chat_history_format=None):
60
+ # Formulate standardized payload messages setup
61
+ messages = [{"role": "system", "content": system_prompt}]
62
+
63
+ if chat_history_format:
64
+ messages.extend(chat_history_format)
65
+ else:
66
+ messages.append({"role": "user", "content": user_message})
67
+
68
+ if provider == "Groq":
69
+ client = Groq(api_key=api_key)
70
+ groq_model_map = {
71
+ "llama-3.1-8b-instant": "llama-3.1-8b-instant",
72
+ "llama-3.1-70b-versatile": "llama-3.1-70b-versatile",
73
+ "openai/gpt-oss-20b": "llama-3.1-8b-instant",
74
+ "whisper-large-v3-turbo": "whisper-large-v3-turbo"
75
+ }
76
+ target_model = groq_model_map.get(model_choice, "llama-3.1-8b-instant")
77
+ response = client.chat.completions.create(
78
+ model=target_model, messages=messages, temperature=0.0
79
+ )
80
+ return response.choices[0].message.content.strip()
81
+
82
+ elif provider == "OpenRouter":
83
+ headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}
84
+ openrouter_model_map = {
85
+ "llama-3.1-8b-instant": "meta-llama/llama-3.1-8b-instruct",
86
+ "llama-3.1-70b-versatile": "meta-llama/llama-3.1-70b-instruct",
87
+ "openai/gpt-oss-20b": "openai/gpt-3.5-turbo",
88
+ "whisper-large-v3-turbo": "meta-llama/llama-3.1-8b-instruct"
89
+ }
90
+ target_model = openrouter_model_map.get(model_choice, "meta-llama/llama-3.1-8b-instruct")
91
+ payload = {"model": target_model, "messages": messages, "temperature": 0.0}
92
+ response = requests.post("https://openrouter.ai/api/v1/chat/completions", headers=headers, json=payload)
93
+ if response.status_code == 200:
94
+ return response.json()['choices'][0]['message']['content'].strip()
95
+ else:
96
+ raise Exception(f"OpenRouter Error: {response.text}")
97
+
98
+ # --- Tab 1: Text-to-SQL Reader Desk Core Logic ---
99
  def execute_ai_query(provider, api_key, model_choice, user_question):
100
  if not api_key.strip():
101
  return None, "⚠️ Please enter a valid API Key to proceed."
 
110
  "Output raw text only."
111
  )
112
 
 
 
 
 
113
  try:
114
+ sql_query = call_llm(provider, api_key, model_choice, system_prompt, user_question)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
  sql_query = sql_query.replace("```sql", "").replace("```", "").replace("`", "").strip()
116
 
 
117
  conn = sqlite3.connect(DB_NAME)
118
  df = pd.read_sql_query(sql_query, conn)
119
  conn.close()
120
+ return df, f"⚑ **Generated SQL Query:** `{sql_query}`"
121
+ except Exception as e:
122
+ return None, f"❌ Execution Failed: {str(e)}"
123
 
124
+ # --- Tab 2: Conversation & Data Append Agent Core Logic ---
125
+ def conversation_and_commit_agent(chat_history, provider, api_key, model_choice, user_msg):
126
+ if not api_key.strip():
127
+ chat_history.append({"role": "assistant", "content": "⚠️ Authentication missing. Please input your API Key on the left menu pane."})
128
+ return chat_history, ""
129
+ if not user_msg.strip():
130
+ return chat_history, ""
131
+
132
+ system_prompt = (
133
+ "You are a helpful conversational assistant and workflow coordinator for the Strides Pharma AI operational framework.\n"
134
+ "Your goal is twofold:\n"
135
+ "1. Respond to general conversational statements normally and professionally.\n"
136
+ "2. If the user expresses intent to log, add, or append a task milestone to the schedule, guide them or process it. "
137
+ "The required metrics are: Phase, Task_Name, Owner, Timeline, and Priority.\n\n"
138
+ "CRITICAL MECHANISM FOR DATA INSERTION:\n"
139
+ "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. "
140
+ "The format must exactly be: ||JSON_DATA: {\"phase\": \"...\", \"task_name\": \"...\", \"owner\": \"...\", \"timeline\": \"...\", \"priority\": \"...\"}||\n"
141
+ "If some schema details are completely absent, converse politely with the client to verify those remaining parameters before adding the string tag marker."
142
+ )
143
+
144
+ # Process conversational memory structure
145
+ formatted_history = []
146
+ for turn in chat_history:
147
+ formatted_history.append({"role": turn["role"], "content": turn["content"]})
148
+ formatted_history.append({"role": "user", "content": user_msg})
149
+
150
+ try:
151
+ # Fetch target assistant reply
152
+ raw_response = call_llm(provider, api_key, model_choice, system_prompt, "", chat_history_format=formatted_history)
153
+
154
+ # Intercept database tags if present
155
+ cleaned_response = raw_response
156
+ database_committed_alert = ""
157
+
158
+ if "||JSON_DATA:" in raw_response:
159
+ try:
160
+ parts = raw_response.split("||JSON_DATA:")
161
+ cleaned_response = parts[0].strip()
162
+ json_string = parts[1].replace("||", "").strip()
163
+
164
+ # Extract dictionary properties cleanly
165
+ data_payload = json.loads(json_string)
166
+
167
+ # Append to SQLite physical table
168
+ conn = sqlite3.connect(DB_NAME)
169
+ cursor = conn.cursor()
170
+ cursor.execute(
171
+ "INSERT INTO project_tasks (phase, task_name, owner, timeline, priority) VALUES (?, ?, ?, ?, ?)",
172
+ (data_payload.get('phase'), data_payload.get('task_name'), data_payload.get('owner'), data_payload.get('timeline'), data_payload.get('priority'))
173
+ )
174
+ conn.commit()
175
+ conn.close()
176
+
177
+ database_committed_alert = f"\n\nβš™οΈ **[SYSTEM UPDATE]:** Successfully appended task '{data_payload.get('task_name')}' to the internal server database master record structure."
178
+ except Exception as inner_err:
179
+ database_committed_alert = f"\n\n⚠️ **[SYSTEM NOTICE]:** Captured structure request token, but insertion execution aborted due to tracking parsing discrepancies: {str(inner_err)}"
180
+
181
+ final_display_text = cleaned_response + database_committed_alert
182
+
183
+ chat_history.append({"role": "user", "content": user_msg})
184
+ chat_history.append({"role": "assistant", "content": final_display_text})
185
+ return chat_history, ""
186
 
187
  except Exception as e:
188
+ chat_history.append({"role": "user", "content": user_msg})
189
+ chat_history.append({"role": "assistant", "content": f"❌ Error communicating with LLM orchestration layout: {str(e)}"})
190
+ return chat_history, ""
191
 
192
+ # --- Interface Layout Configuration ---
193
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
194
+ gr.Markdown("# πŸ’Š Strides Pharma AI Production & Data Portal")
195
+ gr.Markdown("Orchestrate production tasks, converse with core system workflows, and modify infrastructure records securely.")
196
 
197
  with gr.Row():
198
+ # Universal Infrastructure Left Control Tower Pane
199
  with gr.Column(scale=1):
200
+ gr.Markdown("### πŸ”‘ Global Control Tower")
201
  provider_select = gr.Dropdown(choices=["Groq", "OpenRouter"], value="Groq", label="API Gateway Provider")
202
  token_input = gr.Textbox(label="User API Secret Key", type="password", placeholder="gsk_... or sk-or-...")
 
 
203
  model_select = gr.Dropdown(
204
+ choices=["llama-3.1-8b-instant", "llama-3.1-70b-versatile", "openai/gpt-oss-20b", "whisper-large-v3-turbo"],
 
 
 
 
 
205
  value="llama-3.1-8b-instant",
206
+ label="Target Engine Architecture"
207
  )
208
+ 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)")
209
 
210
+ # Interactive Operational Tab Elements
 
211
  with gr.Column(scale=2):
212
+ with gr.Tabs():
213
+
214
+ # Tab A View: Operational Task Creator Conversational Chatbot
215
+ with gr.TabItem("πŸ€– Interactive Data Contributor Chatbot"):
216
+ gr.Markdown("### Conversational Contributor Agent")
217
+ gr.Markdown("Chat with this engine normally, or tell it to log a brand-new task assignment milestone directly into the active SQLite infrastructure.")
218
+
219
+ chatbot_viewport = gr.Chatbot(type="messages", label="Operational History Workspace")
220
+ chat_input = gr.Textbox(placeholder="Say hello, or submit task details to log (e.g., Log a task in Validation phase named Run final audit owned by M. Reddy for Week 8 with High priority)", label="Your Message")
221
+ send_btn = gr.Button("Submit Message", variant="primary")
222
+
223
+ send_btn.click(
224
+ fn=conversation_and_commit_agent,
225
+ inputs=[chatbot_viewport, provider_select, token_input, model_select, chat_input],
226
+ outputs=[chatbot_viewport, chat_input]
227
+ )
228
+ chat_input.submit(
229
+ fn=conversation_and_commit_agent,
230
+ inputs=[chatbot_viewport, provider_select, token_input, model_select, chat_input],
231
+ outputs=[chatbot_viewport, chat_input]
232
+ )
233
+
234
+ # Tab B View: Legacy Natural-Language-to-SQL Inquisitor Node
235
+ with gr.TabItem("πŸ”Ž SQL Inquisitor Desk"):
236
+ gr.Markdown("### Natural Language SQL Query Engine")
237
+ query_input = gr.Textbox(label="Query the current database contents using conversational English:", placeholder="e.g., Show me all records sorted by priority status")
238
+ query_btn = gr.Button("Evaluate Infrastructure", variant="secondary")
239
+
240
+ sql_status_display = gr.Markdown()
241
+ output_data_table = gr.DataFrame(label="Queried Records Dataframe Live Output")
242
+
243
+ query_btn.click(
244
+ fn=execute_ai_query,
245
+ inputs=[provider_select, token_input, model_select, query_input],
246
+ outputs=[output_data_table, sql_status_display]
247
+ )
248
 
249
  if __name__ == "__main__":
250
  demo.launch()