Deadmon commited on
Commit
a0f90fe
·
verified ·
1 Parent(s): 549835f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +69 -4
app.py CHANGED
@@ -7,10 +7,22 @@ import uuid
7
  import sqlite3
8
  import datetime
9
  import difflib
 
10
  from tiktoken import get_encoding
11
  from openai import AzureOpenAI
12
  import httpx
13
 
 
 
 
 
 
 
 
 
 
 
 
14
  # Clear proxy environment variables to avoid interference
15
  os.environ.pop("HTTP_PROXY", None)
16
  os.environ.pop("HTTPS_PROXY", None)
@@ -21,6 +33,7 @@ class ConversationMemory:
21
  self.conn = sqlite3.connect(db_path)
22
  self.create_table()
23
  self.tokenizer = get_encoding("cl100k_base")
 
24
 
25
  def create_table(self):
26
  self.conn.execute("""
@@ -35,6 +48,7 @@ class ConversationMemory:
35
  )
36
  """)
37
  self.conn.commit()
 
38
 
39
  def add_chunk(self, text, role, intent="general"):
40
  chunk_id = str(uuid.uuid4())
@@ -46,16 +60,20 @@ class ConversationMemory:
46
  VALUES (?, ?, ?, ?, ?, ?)
47
  """, (chunk_id, text, role, timestamp, intent, token_count))
48
  self.conn.commit()
 
49
  return chunk_id
50
 
51
  def get_chunk(self, chunk_id):
52
  cursor = self.conn.execute("SELECT * FROM conversation_chunks WHERE chunk_id = ?", (chunk_id,))
53
  row = cursor.fetchone()
54
  if row:
55
- return {
56
  "chunk_id": row[0], "text": row[1], "role": row[2],
57
  "timestamp": row[3], "intent": row[4], "token_count": row[5]
58
  }
 
 
 
59
  return None
60
 
61
  def update_chunk(self, chunk_id, text):
@@ -66,16 +84,20 @@ class ConversationMemory:
66
  WHERE chunk_id = ?
67
  """, (text, token_count, chunk_id))
68
  self.conn.commit()
 
69
 
70
  def get_recent_chunks(self, limit=10):
71
  cursor = self.conn.execute("SELECT * FROM conversation_chunks ORDER BY timestamp DESC LIMIT ?", (limit,))
72
- return [{"chunk_id": row[0], "text": row[1], "role": row[2], "timestamp": row[3], "intent": row[4], "token_count": row[5]} for row in cursor]
 
 
73
 
74
  # TextEditor class
75
  class TextEditor:
76
  def __init__(self, memory):
77
  self.memory = memory
78
  self.clipboard = ""
 
79
 
80
  def cut(self, chunk_id, start, end):
81
  chunk = self.memory.get_chunk(chunk_id)
@@ -83,12 +105,18 @@ class TextEditor:
83
  self.clipboard = chunk['text'][start:end]
84
  chunk['text'] = chunk['text'][:start] + chunk['text'][end:]
85
  self.memory.update_chunk(chunk_id, chunk['text'])
 
 
 
86
  return chunk['text']
87
 
88
  def copy(self, chunk_id, start, end):
89
  chunk = self.memory.get_chunk(chunk_id)
90
  if chunk:
91
  self.clipboard = chunk['text'][start:end]
 
 
 
92
  return self.clipboard
93
 
94
  def paste(self, chunk_id, position):
@@ -96,6 +124,9 @@ class TextEditor:
96
  if chunk:
97
  chunk['text'] = chunk['text'][:position] + self.clipboard + chunk['text'][position:]
98
  self.memory.update_chunk(chunk_id, chunk['text'])
 
 
 
99
  return chunk['text']
100
 
101
  def add_prefix(self, chunk_id, prefix):
@@ -103,6 +134,9 @@ class TextEditor:
103
  if chunk:
104
  chunk['text'] = prefix + chunk['text']
105
  self.memory.update_chunk(chunk_id, chunk['text'])
 
 
 
106
  return chunk['text']
107
 
108
  def add_suffix(self, chunk_id, suffix):
@@ -110,6 +144,9 @@ class TextEditor:
110
  if chunk:
111
  chunk['text'] = chunk['text'] + suffix
112
  self.memory.update_chunk(chunk_id, chunk['text'])
 
 
 
113
  return chunk['text']
114
 
115
  def diff(self, chunk_id, original_text):
@@ -117,24 +154,27 @@ class TextEditor:
117
  if chunk:
118
  differ = difflib.Differ()
119
  diff = list(differ.compare(original_text.splitlines(), chunk['text'].splitlines()))
 
120
  return '\n'.join(diff)
 
121
  return ""
122
 
123
  # OpenAIApi class
124
  class OpenAIApi:
125
- def __init__(self, preprompt="", endpoint="https://T-App-GPT4o.openai.azure.com/openai/v1/", model="gpt-4o", api_key=None):
126
  # Use a minimal httpx.Client to avoid proxies parameter
127
  http_client = httpx.Client()
128
  self.client = AzureOpenAI(
129
  azure_endpoint=endpoint,
130
  api_key=api_key or os.getenv("AZURE_OPENAI_API_KEY"),
131
- api_version="2025-01-01-preview",
132
  http_client=http_client
133
  )
134
  self.model = model
135
  self.preprompt = preprompt
136
  self.memory = ConversationMemory()
137
  self.editor = TextEditor(self.memory)
 
138
  self.functions = [
139
  {
140
  "type": "function",
@@ -216,6 +256,8 @@ class OpenAIApi:
216
  messages.extend({"role": c["role"], "content": c["text"]} for c in context)
217
  messages.append({"role": "user", "content": sanitized_prompt})
218
 
 
 
219
  try:
220
  response = await self.client.chat.completions.create(
221
  model=self.model,
@@ -238,11 +280,13 @@ class OpenAIApi:
238
  tool_calls.extend(chunk.choices[0].delta.tool_calls)
239
 
240
  response_chunk_id = self.memory.add_chunk(full_response, "assistant")
 
241
 
242
  for tool_call in tool_calls:
243
  if tool_call and hasattr(tool_call, 'function'):
244
  func_name = tool_call.function.name
245
  args = json.loads(tool_call.function.arguments)
 
246
  if func_name == "cut_text":
247
  result = self.editor.cut(args["chunk_id"], args["start"], args["end"])
248
  self.memory.add_chunk(f"Cut result: {result}", "system")
@@ -265,6 +309,7 @@ class OpenAIApi:
265
 
266
  except Exception as e:
267
  error_msg = f"API Error: {str(e)}"
 
268
  self.memory.add_chunk(error_msg, "system")
269
  return {"error": error_msg}
270
 
@@ -274,16 +319,29 @@ async def chat_submit(user_input, chat_history, preprompt):
274
  response = await api.fetch_response(user_input)
275
  if "error" in response:
276
  chat_history.append({"role": "assistant", "content": f"Error: {response['error']}"})
 
277
  else:
278
  chat_history.append({"role": "user", "content": user_input})
279
  chat_history.append({"role": "assistant", "content": response["content"]})
 
280
  return chat_history, preprompt
281
 
282
  def get_history():
283
  memory = ConversationMemory()
284
  return memory.get_recent_chunks(limit=10)
285
 
 
 
 
 
 
 
 
 
 
 
286
  def select_chunk(evt: gr.SelectData):
 
287
  return evt.value["chunk_id"], evt.value["text"]
288
 
289
  async def edit_cut(chunk_id, start, end):
@@ -361,10 +419,17 @@ def create_ui():
361
  prefix_btn.click(fn=edit_prefix, inputs=[chunk_id, prefix], outputs=[chunk_text, diff_output])
362
  suffix_btn.click(fn=edit_suffix, inputs=[chunk_id, suffix], outputs=[chunk_text, diff_output])
363
 
 
 
 
 
 
364
  gr.Markdown(f"Current Time: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S %Z')}")
365
 
 
366
  return demo
367
 
368
  if __name__ == "__main__":
 
369
  demo = create_ui()
370
  demo.launch(server_name="0.0.0.0", server_port=7860)
 
7
  import sqlite3
8
  import datetime
9
  import difflib
10
+ import logging
11
  from tiktoken import get_encoding
12
  from openai import AzureOpenAI
13
  import httpx
14
 
15
+ # Configure logging
16
+ logging.basicConfig(
17
+ level=logging.INFO,
18
+ format='%(asctime)s - %(levelname)s - %(message)s',
19
+ handlers=[
20
+ logging.FileHandler('app.log'),
21
+ logging.StreamHandler()
22
+ ]
23
+ )
24
+ logger = logging.getLogger(__name__)
25
+
26
  # Clear proxy environment variables to avoid interference
27
  os.environ.pop("HTTP_PROXY", None)
28
  os.environ.pop("HTTPS_PROXY", None)
 
33
  self.conn = sqlite3.connect(db_path)
34
  self.create_table()
35
  self.tokenizer = get_encoding("cl100k_base")
36
+ logger.info(f"Initialized ConversationMemory with db_path: {db_path}")
37
 
38
  def create_table(self):
39
  self.conn.execute("""
 
48
  )
49
  """)
50
  self.conn.commit()
51
+ logger.info("Created conversation_chunks table")
52
 
53
  def add_chunk(self, text, role, intent="general"):
54
  chunk_id = str(uuid.uuid4())
 
60
  VALUES (?, ?, ?, ?, ?, ?)
61
  """, (chunk_id, text, role, timestamp, intent, token_count))
62
  self.conn.commit()
63
+ logger.info(f"Added chunk: {chunk_id}, role: {role}, intent: {intent}, token_count: {token_count}")
64
  return chunk_id
65
 
66
  def get_chunk(self, chunk_id):
67
  cursor = self.conn.execute("SELECT * FROM conversation_chunks WHERE chunk_id = ?", (chunk_id,))
68
  row = cursor.fetchone()
69
  if row:
70
+ chunk = {
71
  "chunk_id": row[0], "text": row[1], "role": row[2],
72
  "timestamp": row[3], "intent": row[4], "token_count": row[5]
73
  }
74
+ logger.info(f"Retrieved chunk: {chunk_id}")
75
+ return chunk
76
+ logger.warning(f"Chunk not found: {chunk_id}")
77
  return None
78
 
79
  def update_chunk(self, chunk_id, text):
 
84
  WHERE chunk_id = ?
85
  """, (text, token_count, chunk_id))
86
  self.conn.commit()
87
+ logger.info(f"Updated chunk: {chunk_id}, new token_count: {token_count}")
88
 
89
  def get_recent_chunks(self, limit=10):
90
  cursor = self.conn.execute("SELECT * FROM conversation_chunks ORDER BY timestamp DESC LIMIT ?", (limit,))
91
+ chunks = [{"chunk_id": row[0], "text": row[1], "role": row[2], "timestamp": row[3], "intent": row[4], "token_count": row[5]} for row in cursor]
92
+ logger.info(f"Retrieved {len(chunks)} recent chunks")
93
+ return chunks
94
 
95
  # TextEditor class
96
  class TextEditor:
97
  def __init__(self, memory):
98
  self.memory = memory
99
  self.clipboard = ""
100
+ logger.info("Initialized TextEditor")
101
 
102
  def cut(self, chunk_id, start, end):
103
  chunk = self.memory.get_chunk(chunk_id)
 
105
  self.clipboard = chunk['text'][start:end]
106
  chunk['text'] = chunk['text'][:start] + chunk['text'][end:]
107
  self.memory.update_chunk(chunk_id, chunk['text'])
108
+ logger.info(f"Cut text from chunk: {chunk_id}, start: {start}, end: {end}, clipboard: {self.clipboard}")
109
+ else:
110
+ logger.warning(f"Failed to cut text, chunk not found: {chunk_id}")
111
  return chunk['text']
112
 
113
  def copy(self, chunk_id, start, end):
114
  chunk = self.memory.get_chunk(chunk_id)
115
  if chunk:
116
  self.clipboard = chunk['text'][start:end]
117
+ logger.info(f"Copied text from chunk: {chunk_id}, start: {start}, end: {end}, clipboard: {self.clipboard}")
118
+ else:
119
+ logger.warning(f"Failed to copy text, chunk not found: {chunk_id}")
120
  return self.clipboard
121
 
122
  def paste(self, chunk_id, position):
 
124
  if chunk:
125
  chunk['text'] = chunk['text'][:position] + self.clipboard + chunk['text'][position:]
126
  self.memory.update_chunk(chunk_id, chunk['text'])
127
+ logger.info(f"Pasted text to chunk: {chunk_id}, position: {position}, clipboard: {self.clipboard}")
128
+ else:
129
+ logger.warning(f"Failed to paste text, chunk not found: {chunk_id}")
130
  return chunk['text']
131
 
132
  def add_prefix(self, chunk_id, prefix):
 
134
  if chunk:
135
  chunk['text'] = prefix + chunk['text']
136
  self.memory.update_chunk(chunk_id, chunk['text'])
137
+ logger.info(f"Added prefix to chunk: {chunk_id}, prefix: {prefix}")
138
+ else:
139
+ logger.warning(f"Failed to add prefix, chunk not found: {chunk_id}")
140
  return chunk['text']
141
 
142
  def add_suffix(self, chunk_id, suffix):
 
144
  if chunk:
145
  chunk['text'] = chunk['text'] + suffix
146
  self.memory.update_chunk(chunk_id, chunk['text'])
147
+ logger.info(f"Added suffix to chunk: {chunk_id}, suffix: {suffix}")
148
+ else:
149
+ logger.warning(f"Failed to add suffix, chunk not found: {chunk_id}")
150
  return chunk['text']
151
 
152
  def diff(self, chunk_id, original_text):
 
154
  if chunk:
155
  differ = difflib.Differ()
156
  diff = list(differ.compare(original_text.splitlines(), chunk['text'].splitlines()))
157
+ logger.info(f"Generated diff for chunk: {chunk_id}")
158
  return '\n'.join(diff)
159
+ logger.warning(f"Failed to generate diff, chunk not found: {chunk_id}")
160
  return ""
161
 
162
  # OpenAIApi class
163
  class OpenAIApi:
164
+ def __init__(self, preprompt="", endpoint="https://<your-resource-name>.openai.azure.com/", model="gpt-4o", api_key=None):
165
  # Use a minimal httpx.Client to avoid proxies parameter
166
  http_client = httpx.Client()
167
  self.client = AzureOpenAI(
168
  azure_endpoint=endpoint,
169
  api_key=api_key or os.getenv("AZURE_OPENAI_API_KEY"),
170
+ api_version="2024-02-15-preview",
171
  http_client=http_client
172
  )
173
  self.model = model
174
  self.preprompt = preprompt
175
  self.memory = ConversationMemory()
176
  self.editor = TextEditor(self.memory)
177
+ logger.info(f"Initialized OpenAIApi with endpoint: {endpoint}, model: {model}, api_version: 2024-02-15-preview")
178
  self.functions = [
179
  {
180
  "type": "function",
 
256
  messages.extend({"role": c["role"], "content": c["text"]} for c in context)
257
  messages.append({"role": "user", "content": sanitized_prompt})
258
 
259
+ logger.info(f"Sending request to model: {self.model}, messages: {json.dumps(messages, ensure_ascii=False)}")
260
+
261
  try:
262
  response = await self.client.chat.completions.create(
263
  model=self.model,
 
280
  tool_calls.extend(chunk.choices[0].delta.tool_calls)
281
 
282
  response_chunk_id = self.memory.add_chunk(full_response, "assistant")
283
+ logger.info(f"Received response for chunk: {response_chunk_id}, length: {len(full_response)}")
284
 
285
  for tool_call in tool_calls:
286
  if tool_call and hasattr(tool_call, 'function'):
287
  func_name = tool_call.function.name
288
  args = json.loads(tool_call.function.arguments)
289
+ logger.info(f"Processing tool call: {func_name}, args: {args}")
290
  if func_name == "cut_text":
291
  result = self.editor.cut(args["chunk_id"], args["start"], args["end"])
292
  self.memory.add_chunk(f"Cut result: {result}", "system")
 
309
 
310
  except Exception as e:
311
  error_msg = f"API Error: {str(e)}"
312
+ logger.error(f"API request failed: {error_msg}, endpoint: {self.client.azure_endpoint}, model: {self.model}")
313
  self.memory.add_chunk(error_msg, "system")
314
  return {"error": error_msg}
315
 
 
319
  response = await api.fetch_response(user_input)
320
  if "error" in response:
321
  chat_history.append({"role": "assistant", "content": f"Error: {response['error']}"})
322
+ logger.warning(f"Chat error: {response['error']}")
323
  else:
324
  chat_history.append({"role": "user", "content": user_input})
325
  chat_history.append({"role": "assistant", "content": response["content"]})
326
+ logger.info("Chat response added to history")
327
  return chat_history, preprompt
328
 
329
  def get_history():
330
  memory = ConversationMemory()
331
  return memory.get_recent_chunks(limit=10)
332
 
333
+ def get_logs():
334
+ try:
335
+ with open("app.log", "r") as f:
336
+ logs = f.read()
337
+ logger.info("Retrieved logs from app.log")
338
+ return logs
339
+ except Exception as e:
340
+ logger.error(f"Failed to read logs: {str(e)}")
341
+ return f"Error reading logs: {str(e)}"
342
+
343
  def select_chunk(evt: gr.SelectData):
344
+ logger.info(f"Selected chunk: {evt.value['chunk_id']}")
345
  return evt.value["chunk_id"], evt.value["text"]
346
 
347
  async def edit_cut(chunk_id, start, end):
 
419
  prefix_btn.click(fn=edit_prefix, inputs=[chunk_id, prefix], outputs=[chunk_text, diff_output])
420
  suffix_btn.click(fn=edit_suffix, inputs=[chunk_id, suffix], outputs=[chunk_text, diff_output])
421
 
422
+ with gr.Tab("Logs"):
423
+ logs = gr.Textbox(label="Application Logs", interactive=False)
424
+ logs_btn = gr.Button("Refresh Logs")
425
+ logs_btn.click(fn=get_logs, outputs=logs)
426
+
427
  gr.Markdown(f"Current Time: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S %Z')}")
428
 
429
+ logger.info("Created Gradio UI")
430
  return demo
431
 
432
  if __name__ == "__main__":
433
+ logger.info("Starting application")
434
  demo = create_ui()
435
  demo.launch(server_name="0.0.0.0", server_port=7860)