oceansweep commited on
Commit
02b34b4
1 Parent(s): a324812

Upload 3 files

Browse files
App_Function_Libraries/Gradio_UI/Embeddings_tab.py CHANGED
@@ -7,14 +7,17 @@ import logging
7
  #
8
  # External Imports
9
  import gradio as gr
 
10
 
11
- from App_Function_Libraries.Chunk_Lib import improved_chunking_process, determine_chunk_position
12
  #
13
  # Local Imports
14
  from App_Function_Libraries.DB.DB_Manager import get_all_content_from_database
15
  from App_Function_Libraries.RAG.ChromaDB_Library import chroma_client, \
16
- store_in_chroma
17
- from App_Function_Libraries.RAG.Embeddings_Create import create_embedding
 
 
18
  #
19
  ########################################################################################################################
20
  #
@@ -174,17 +177,23 @@ def create_view_embeddings_tab():
174
  value="words"
175
  )
176
  max_chunk_size = gr.Slider(
177
- minimum=1, maximum=8000, step=1, value=500,
178
  label="Max Chunk Size"
179
  )
180
  chunk_overlap = gr.Slider(
181
- minimum=0, maximum=5000, step=1, value=200,
182
  label="Chunk Overlap"
183
  )
184
  adaptive_chunking = gr.Checkbox(
185
  label="Use Adaptive Chunking",
186
  value=False
187
  )
 
 
 
 
 
 
188
 
189
  def get_items_with_embedding_status():
190
  try:
@@ -242,7 +251,7 @@ def create_view_embeddings_tab():
242
  logging.error(f"Error in check_embedding_status: {str(e)}")
243
  return f"Error processing item: {selected_item}. Details: {str(e)}", "", ""
244
 
245
- def create_new_embedding_for_item(selected_item, provider, model, api_url, method, max_size, overlap, adaptive, item_mapping):
246
  if not selected_item:
247
  return "Please select an item", "", ""
248
 
@@ -263,31 +272,30 @@ def create_view_embeddings_tab():
263
  'adaptive': adaptive
264
  }
265
 
266
- chunks = improved_chunking_process(item['content'], chunk_options)
 
267
  collection_name = "all_content_embeddings"
268
  collection = chroma_client.get_or_create_collection(name=collection_name)
269
 
270
  # Delete existing embeddings for this item
271
  existing_ids = [f"doc_{item_id}_chunk_{i}" for i in range(len(chunks))]
272
  collection.delete(ids=existing_ids)
 
273
 
274
- for i, chunk in enumerate(chunks):
 
 
 
275
  chunk_text = chunk['text']
276
  chunk_metadata = chunk['metadata']
277
- chunk_position = determine_chunk_position(chunk_metadata['relative_position'])
278
-
279
- chunk_header = f"""
280
- Original Document: {item['title']}
281
- Chunk: {i + 1} of {len(chunks)}
282
- Position: {chunk_position}
283
- Header: {chunk_metadata.get('header_text', 'N/A')}
284
-
285
- --- Chunk Content ---
286
- """
287
-
288
- full_chunk_text = chunk_header + chunk_text
289
  chunk_id = f"doc_{item_id}_chunk_{i}"
290
- embedding = create_embedding(full_chunk_text, provider, model, api_url)
291
  metadata = {
292
  "media_id": str(item_id),
293
  "chunk_index": i,
@@ -298,13 +306,26 @@ def create_view_embeddings_tab():
298
  "adaptive_chunking": adaptive,
299
  "embedding_model": model,
300
  "embedding_provider": provider,
 
 
301
  **chunk_metadata
302
  }
303
- store_in_chroma(collection_name, [full_chunk_text], [embedding], [chunk_id], [metadata])
304
 
305
- embedding_preview = str(embedding[:50])
306
- status = f"New embeddings created and stored for item: {item['title']} (ID: {item_id})"
307
- return status, f"First 50 elements of new embedding:\n{embedding_preview}", json.dumps(metadata, indent=2)
 
 
 
 
 
 
 
 
 
 
 
 
308
  except Exception as e:
309
  logging.error(f"Error in create_new_embedding_for_item: {str(e)}")
310
  return f"Error creating embedding: {str(e)}", "", ""
@@ -321,7 +342,7 @@ def create_view_embeddings_tab():
321
  create_new_embedding_button.click(
322
  create_new_embedding_for_item,
323
  inputs=[item_dropdown, embedding_provider, embedding_model, embedding_api_url,
324
- chunking_method, max_chunk_size, chunk_overlap, adaptive_chunking, item_mapping],
325
  outputs=[embedding_status, embedding_preview, embedding_metadata]
326
  )
327
  embedding_provider.change(
 
7
  #
8
  # External Imports
9
  import gradio as gr
10
+ from tqdm import tqdm
11
 
12
+ from App_Function_Libraries.Chunk_Lib import improved_chunking_process, chunk_for_embedding
13
  #
14
  # Local Imports
15
  from App_Function_Libraries.DB.DB_Manager import get_all_content_from_database
16
  from App_Function_Libraries.RAG.ChromaDB_Library import chroma_client, \
17
+ store_in_chroma, situate_context
18
+ from App_Function_Libraries.RAG.Embeddings_Create import create_embedding, create_embeddings_batch
19
+
20
+
21
  #
22
  ########################################################################################################################
23
  #
 
177
  value="words"
178
  )
179
  max_chunk_size = gr.Slider(
180
+ minimum=1, maximum=8000, step=5, value=500,
181
  label="Max Chunk Size"
182
  )
183
  chunk_overlap = gr.Slider(
184
+ minimum=0, maximum=5000, step=5, value=200,
185
  label="Chunk Overlap"
186
  )
187
  adaptive_chunking = gr.Checkbox(
188
  label="Use Adaptive Chunking",
189
  value=False
190
  )
191
+ contextual_api_choice = gr.Dropdown(
192
+ choices=["Local-LLM", "OpenAI", "Anthropic", "Cohere", "Groq", "DeepSeek", "Mistral", "OpenRouter", "Llama.cpp", "Kobold", "Ooba", "Tabbyapi", "VLLM", "ollama", "HuggingFace"],
193
+ label="Select API for Contextualized Embeddings",
194
+ value="OpenAI"
195
+ )
196
+ contextual_api_key = gr.Textbox(label="API Key", lines=1)
197
 
198
  def get_items_with_embedding_status():
199
  try:
 
251
  logging.error(f"Error in check_embedding_status: {str(e)}")
252
  return f"Error processing item: {selected_item}. Details: {str(e)}", "", ""
253
 
254
+ def create_new_embedding_for_item(selected_item, provider, model, api_url, method, max_size, overlap, adaptive, item_mapping, contextual_api_choice=None):
255
  if not selected_item:
256
  return "Please select an item", "", ""
257
 
 
272
  'adaptive': adaptive
273
  }
274
 
275
+ logging.info(f"Chunking content for item: {item['title']} (ID: {item_id})")
276
+ chunks = chunk_for_embedding(item['content'], item['title'], chunk_options)
277
  collection_name = "all_content_embeddings"
278
  collection = chroma_client.get_or_create_collection(name=collection_name)
279
 
280
  # Delete existing embeddings for this item
281
  existing_ids = [f"doc_{item_id}_chunk_{i}" for i in range(len(chunks))]
282
  collection.delete(ids=existing_ids)
283
+ logging.info(f"Deleted {len(existing_ids)} existing embeddings for item {item_id}")
284
 
285
+ texts, ids, metadatas = [], [], []
286
+ chunk_count = 0
287
+ logging.info("Generating contextual summaries and preparing chunks for embedding")
288
+ for i, chunk in tqdm(enumerate(chunks), total=len(chunks), desc="Processing chunks"):
289
  chunk_text = chunk['text']
290
  chunk_metadata = chunk['metadata']
291
+ if chunk_count == 0:
292
+ chunk_count = 1
293
+ # Generate contextual summary
294
+ logging.debug(f"Generating contextual summary for chunk {chunk_count}")
295
+ context = situate_context(contextual_api_choice, item['content'], chunk_text)
296
+ contextualized_text = f"{chunk_text}\n\nContextual Summary: {context}"
297
+
 
 
 
 
 
298
  chunk_id = f"doc_{item_id}_chunk_{i}"
 
299
  metadata = {
300
  "media_id": str(item_id),
301
  "chunk_index": i,
 
306
  "adaptive_chunking": adaptive,
307
  "embedding_model": model,
308
  "embedding_provider": provider,
309
+ "original_text": chunk_text,
310
+ "contextual_summary": context,
311
  **chunk_metadata
312
  }
 
313
 
314
+ texts.append(contextualized_text)
315
+ ids.append(chunk_id)
316
+ metadatas.append(metadata)
317
+ chunk_count = chunk_count+1
318
+
319
+ # Create embeddings in batch
320
+ logging.info(f"Creating embeddings for {len(texts)} chunks")
321
+ embeddings = create_embeddings_batch(texts, provider, model, api_url)
322
+
323
+ # Store in Chroma
324
+ store_in_chroma(collection_name, texts, embeddings, ids, metadatas)
325
+
326
+ embedding_preview = str(embeddings[0][:50]) if embeddings else "No embeddings created"
327
+ status = f"New contextual embeddings created and stored for item: {item['title']} (ID: {item_id})"
328
+ return status, f"First 50 elements of new embedding:\n{embedding_preview}", json.dumps(metadatas[0], indent=2)
329
  except Exception as e:
330
  logging.error(f"Error in create_new_embedding_for_item: {str(e)}")
331
  return f"Error creating embedding: {str(e)}", "", ""
 
342
  create_new_embedding_button.click(
343
  create_new_embedding_for_item,
344
  inputs=[item_dropdown, embedding_provider, embedding_model, embedding_api_url,
345
+ chunking_method, max_chunk_size, chunk_overlap, adaptive_chunking, item_mapping, contextual_api_choice],
346
  outputs=[embedding_status, embedding_preview, embedding_metadata]
347
  )
348
  embedding_provider.change(
App_Function_Libraries/Gradio_UI/Search_Tab.py CHANGED
@@ -66,6 +66,8 @@ def update_content_for_version(selected_item, item_mapping, selected_version):
66
  return "", "", ""
67
 
68
  def format_as_html(content, title):
 
 
69
  escaped_content = html.escape(content)
70
  formatted_content = escaped_content.replace('\n', '<br>')
71
  return f"""
@@ -79,9 +81,9 @@ def format_as_html(content, title):
79
 
80
  def create_search_tab():
81
  with gr.TabItem("Search / Detailed View"):
 
82
  with gr.Row():
83
  with gr.Column(scale=1):
84
- gr.Markdown("# Search across all ingested items in the Database")
85
  gr.Markdown("by Title / URL / Keyword / or Content via SQLite Full-Text-Search")
86
  search_query_input = gr.Textbox(label="Search Query", placeholder="Enter your search query here...")
87
  search_type_input = gr.Radio(choices=["Title", "URL", "Keyword", "Content"], value="Title",
 
66
  return "", "", ""
67
 
68
  def format_as_html(content, title):
69
+ if content is None:
70
+ content = "No content available"
71
  escaped_content = html.escape(content)
72
  formatted_content = escaped_content.replace('\n', '<br>')
73
  return f"""
 
81
 
82
  def create_search_tab():
83
  with gr.TabItem("Search / Detailed View"):
84
+ gr.Markdown("# Search across all ingested items in the Database")
85
  with gr.Row():
86
  with gr.Column(scale=1):
 
87
  gr.Markdown("by Title / URL / Keyword / or Content via SQLite Full-Text-Search")
88
  search_query_input = gr.Textbox(label="Search Query", placeholder="Enter your search query here...")
89
  search_type_input = gr.Radio(choices=["Title", "URL", "Keyword", "Content"], value="Title",
App_Function_Libraries/Gradio_UI/View_DB_Items_tab.py CHANGED
@@ -10,7 +10,8 @@ import gradio as gr
10
  #
11
  # Local Imports
12
  from App_Function_Libraries.DB.DB_Manager import view_database, get_all_document_versions, \
13
- fetch_paginated_data, fetch_item_details, get_latest_transcription
 
14
  from App_Function_Libraries.DB.SQLite_DB import get_document_version
15
  from App_Function_Libraries.Utils.Utils import get_database_path, format_text_with_line_breaks
16
  #
@@ -30,72 +31,40 @@ def create_prompt_view_tab():
30
  next_page_button = gr.Button("Next Page")
31
  previous_page_button = gr.Button("Previous Page")
32
  pagination_info = gr.Textbox(label="Pagination Info", interactive=False)
 
33
  with gr.Column():
34
- results_display = gr.HTML()
35
-
36
- # FIXME - SQL functions to be moved to DB_Manager
37
 
38
  def view_database(page, entries_per_page):
39
- offset = (page - 1) * entries_per_page
40
  try:
41
- with sqlite3.connect(get_database_path('prompts.db')) as conn:
42
- cursor = conn.cursor()
43
- cursor.execute('''
44
- SELECT p.name, p.details, p.system, p.user, GROUP_CONCAT(k.keyword, ', ') as keywords
45
- FROM Prompts p
46
- LEFT JOIN PromptKeywords pk ON p.id = pk.prompt_id
47
- LEFT JOIN Keywords k ON pk.keyword_id = k.id
48
- GROUP BY p.id
49
- ORDER BY p.name
50
- LIMIT ? OFFSET ?
51
- ''', (entries_per_page, offset))
52
- prompts = cursor.fetchall()
53
-
54
- cursor.execute('SELECT COUNT(*) FROM Prompts')
55
- total_prompts = cursor.fetchone()[0]
56
-
57
- results = ""
58
- for prompt in prompts:
59
- # Escape HTML special characters and replace newlines with <br> tags
60
- title = html.escape(prompt[0]).replace('\n', '<br>')
61
- details = html.escape(prompt[1] or '').replace('\n', '<br>')
62
- system_prompt = html.escape(prompt[2] or '')
63
- user_prompt = html.escape(prompt[3] or '')
64
- keywords = html.escape(prompt[4] or '').replace('\n', '<br>')
65
-
66
- results += f"""
67
- <div style="border: 1px solid #ddd; padding: 10px; margin-bottom: 20px;">
68
- <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 10px;">
69
- <div><strong>Title:</strong> {title}</div>
70
- <div><strong>Details:</strong> {details}</div>
71
- </div>
72
- <div style="margin-top: 10px;">
73
- <strong>User Prompt:</strong>
74
- <pre style="white-space: pre-wrap; word-wrap: break-word;">{user_prompt}</pre>
75
- </div>
76
- <div style="margin-top: 10px;">
77
- <strong>System Prompt:</strong>
78
- <pre style="white-space: pre-wrap; word-wrap: break-word;">{system_prompt}</pre>
79
- </div>
80
- <div style="margin-top: 10px;">
81
- <strong>Keywords:</strong> {keywords}
82
- </div>
83
- </div>
84
- """
85
-
86
- total_pages = (total_prompts + entries_per_page - 1) // entries_per_page
87
- pagination = f"Page {page} of {total_pages} (Total prompts: {total_prompts})"
88
-
89
- return results, pagination, total_pages
90
- except sqlite3.Error as e:
91
- return f"<p>Error fetching prompts: {e}</p>", "Error", 0
92
 
93
  def update_page(page, entries_per_page):
94
- results, pagination, total_pages = view_database(page, entries_per_page)
95
  next_disabled = page >= total_pages
96
  prev_disabled = page <= 1
97
  return results, pagination, page, gr.update(interactive=not next_disabled), gr.update(
98
- interactive=not prev_disabled)
99
 
100
  def go_to_next_page(current_page, entries_per_page):
101
  next_page = current_page + 1
@@ -105,23 +74,158 @@ def create_prompt_view_tab():
105
  previous_page = max(1, current_page - 1)
106
  return update_page(previous_page, entries_per_page)
107
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
  view_button.click(
109
  fn=update_page,
110
  inputs=[page_number, entries_per_page],
111
- outputs=[results_display, pagination_info, page_number, next_page_button, previous_page_button]
 
112
  )
113
 
114
  next_page_button.click(
115
  fn=go_to_next_page,
116
  inputs=[page_number, entries_per_page],
117
- outputs=[results_display, pagination_info, page_number, next_page_button, previous_page_button]
 
118
  )
119
 
120
  previous_page_button.click(
121
  fn=go_to_previous_page,
122
  inputs=[page_number, entries_per_page],
123
- outputs=[results_display, pagination_info, page_number, next_page_button, previous_page_button]
 
 
 
 
 
 
 
124
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125
 
126
 
127
  def format_as_html(content, title):
 
10
  #
11
  # Local Imports
12
  from App_Function_Libraries.DB.DB_Manager import view_database, get_all_document_versions, \
13
+ fetch_paginated_data, fetch_item_details, get_latest_transcription, list_prompts, fetch_prompt_details, \
14
+ load_preset_prompts
15
  from App_Function_Libraries.DB.SQLite_DB import get_document_version
16
  from App_Function_Libraries.Utils.Utils import get_database_path, format_text_with_line_breaks
17
  #
 
31
  next_page_button = gr.Button("Next Page")
32
  previous_page_button = gr.Button("Previous Page")
33
  pagination_info = gr.Textbox(label="Pagination Info", interactive=False)
34
+ prompt_selector = gr.Dropdown(label="Select Prompt to View", choices=[])
35
  with gr.Column():
36
+ results_table = gr.HTML()
37
+ selected_prompt_display = gr.HTML()
 
38
 
39
  def view_database(page, entries_per_page):
 
40
  try:
41
+ prompts, total_pages, current_page = list_prompts(page, entries_per_page)
42
+
43
+ table_html = "<table style='width:100%; border-collapse: collapse;'>"
44
+ table_html += "<tr><th style='border: 1px solid black; padding: 8px;'>Title</th><th style='border: 1px solid black; padding: 8px;'>Author</th></tr>"
45
+ prompt_choices = []
46
+ for prompt_name in prompts:
47
+ details = fetch_prompt_details(prompt_name)
48
+ if details:
49
+ title, _, _, _, _ = details
50
+ author = "Unknown" # Assuming author is not stored in the current schema
51
+ table_html += f"<tr><td style='border: 1px solid black; padding: 8px;'>{html.escape(title)}</td><td style='border: 1px solid black; padding: 8px;'>{html.escape(author)}</td></tr>"
52
+ prompt_choices.append((title, title)) # Using title as both label and value
53
+ table_html += "</table>"
54
+
55
+ total_prompts = len(load_preset_prompts()) # This might be inefficient for large datasets
56
+ pagination = f"Page {current_page} of {total_pages} (Total prompts: {total_prompts})"
57
+
58
+ return table_html, pagination, total_pages, prompt_choices
59
+ except Exception as e:
60
+ return f"<p>Error fetching prompts: {e}</p>", "Error", 0, []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
 
62
  def update_page(page, entries_per_page):
63
+ results, pagination, total_pages, prompt_choices = view_database(page, entries_per_page)
64
  next_disabled = page >= total_pages
65
  prev_disabled = page <= 1
66
  return results, pagination, page, gr.update(interactive=not next_disabled), gr.update(
67
+ interactive=not prev_disabled), gr.update(choices=prompt_choices)
68
 
69
  def go_to_next_page(current_page, entries_per_page):
70
  next_page = current_page + 1
 
74
  previous_page = max(1, current_page - 1)
75
  return update_page(previous_page, entries_per_page)
76
 
77
+ def display_selected_prompt(prompt_name):
78
+ details = fetch_prompt_details(prompt_name)
79
+ if details:
80
+ title, description, system_prompt, user_prompt, keywords = details
81
+ html_content = f"""
82
+ <div style="border: 1px solid #ddd; padding: 10px; margin-bottom: 20px;">
83
+ <h3>{html.escape(title)}</h3>
84
+ <p><strong>Description:</strong> {html.escape(description or '')}</p>
85
+ <div style="margin-top: 10px;">
86
+ <strong>System Prompt:</strong>
87
+ <pre style="white-space: pre-wrap; word-wrap: break-word;">{html.escape(system_prompt or '')}</pre>
88
+ </div>
89
+ <div style="margin-top: 10px;">
90
+ <strong>User Prompt:</strong>
91
+ <pre style="white-space: pre-wrap; word-wrap: break-word;">{html.escape(user_prompt or '')}</pre>
92
+ </div>
93
+ <p><strong>Keywords:</strong> {html.escape(keywords or '')}</p>
94
+ </div>
95
+ """
96
+ return html_content
97
+ else:
98
+ return "<p>Prompt not found.</p>"
99
+
100
  view_button.click(
101
  fn=update_page,
102
  inputs=[page_number, entries_per_page],
103
+ outputs=[results_table, pagination_info, page_number, next_page_button, previous_page_button,
104
+ prompt_selector]
105
  )
106
 
107
  next_page_button.click(
108
  fn=go_to_next_page,
109
  inputs=[page_number, entries_per_page],
110
+ outputs=[results_table, pagination_info, page_number, next_page_button, previous_page_button,
111
+ prompt_selector]
112
  )
113
 
114
  previous_page_button.click(
115
  fn=go_to_previous_page,
116
  inputs=[page_number, entries_per_page],
117
+ outputs=[results_table, pagination_info, page_number, next_page_button, previous_page_button,
118
+ prompt_selector]
119
+ )
120
+
121
+ prompt_selector.change(
122
+ fn=display_selected_prompt,
123
+ inputs=[prompt_selector],
124
+ outputs=[selected_prompt_display]
125
  )
126
+ # def create_prompt_view_tab():
127
+ # with gr.TabItem("View Prompt Database"):
128
+ # gr.Markdown("# View Prompt Database Entries")
129
+ # with gr.Row():
130
+ # with gr.Column():
131
+ # entries_per_page = gr.Dropdown(choices=[10, 20, 50, 100], label="Entries per Page", value=10)
132
+ # page_number = gr.Number(value=1, label="Page Number", precision=0)
133
+ # view_button = gr.Button("View Page")
134
+ # next_page_button = gr.Button("Next Page")
135
+ # previous_page_button = gr.Button("Previous Page")
136
+ # pagination_info = gr.Textbox(label="Pagination Info", interactive=False)
137
+ # with gr.Column():
138
+ # results_display = gr.HTML()
139
+ #
140
+ # # FIXME - SQL functions to be moved to DB_Manager
141
+ #
142
+ # def view_database(page, entries_per_page):
143
+ # offset = (page - 1) * entries_per_page
144
+ # try:
145
+ # with sqlite3.connect(get_database_path('prompts.db')) as conn:
146
+ # cursor = conn.cursor()
147
+ # cursor.execute('''
148
+ # SELECT p.name, p.details, p.system, p.user, GROUP_CONCAT(k.keyword, ', ') as keywords
149
+ # FROM Prompts p
150
+ # LEFT JOIN PromptKeywords pk ON p.id = pk.prompt_id
151
+ # LEFT JOIN Keywords k ON pk.keyword_id = k.id
152
+ # GROUP BY p.id
153
+ # ORDER BY p.name
154
+ # LIMIT ? OFFSET ?
155
+ # ''', (entries_per_page, offset))
156
+ # prompts = cursor.fetchall()
157
+ #
158
+ # cursor.execute('SELECT COUNT(*) FROM Prompts')
159
+ # total_prompts = cursor.fetchone()[0]
160
+ #
161
+ # results = ""
162
+ # for prompt in prompts:
163
+ # # Escape HTML special characters and replace newlines with <br> tags
164
+ # title = html.escape(prompt[0]).replace('\n', '<br>')
165
+ # details = html.escape(prompt[1] or '').replace('\n', '<br>')
166
+ # system_prompt = html.escape(prompt[2] or '')
167
+ # user_prompt = html.escape(prompt[3] or '')
168
+ # keywords = html.escape(prompt[4] or '').replace('\n', '<br>')
169
+ #
170
+ # results += f"""
171
+ # <div style="border: 1px solid #ddd; padding: 10px; margin-bottom: 20px;">
172
+ # <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 10px;">
173
+ # <div><strong>Title:</strong> {title}</div>
174
+ # <div><strong>Details:</strong> {details}</div>
175
+ # </div>
176
+ # <div style="margin-top: 10px;">
177
+ # <strong>User Prompt:</strong>
178
+ # <pre style="white-space: pre-wrap; word-wrap: break-word;">{user_prompt}</pre>
179
+ # </div>
180
+ # <div style="margin-top: 10px;">
181
+ # <strong>System Prompt:</strong>
182
+ # <pre style="white-space: pre-wrap; word-wrap: break-word;">{system_prompt}</pre>
183
+ # </div>
184
+ # <div style="margin-top: 10px;">
185
+ # <strong>Keywords:</strong> {keywords}
186
+ # </div>
187
+ # </div>
188
+ # """
189
+ #
190
+ # total_pages = (total_prompts + entries_per_page - 1) // entries_per_page
191
+ # pagination = f"Page {page} of {total_pages} (Total prompts: {total_prompts})"
192
+ #
193
+ # return results, pagination, total_pages
194
+ # except sqlite3.Error as e:
195
+ # return f"<p>Error fetching prompts: {e}</p>", "Error", 0
196
+ #
197
+ # def update_page(page, entries_per_page):
198
+ # results, pagination, total_pages = view_database(page, entries_per_page)
199
+ # next_disabled = page >= total_pages
200
+ # prev_disabled = page <= 1
201
+ # return results, pagination, page, gr.update(interactive=not next_disabled), gr.update(
202
+ # interactive=not prev_disabled)
203
+ #
204
+ # def go_to_next_page(current_page, entries_per_page):
205
+ # next_page = current_page + 1
206
+ # return update_page(next_page, entries_per_page)
207
+ #
208
+ # def go_to_previous_page(current_page, entries_per_page):
209
+ # previous_page = max(1, current_page - 1)
210
+ # return update_page(previous_page, entries_per_page)
211
+ #
212
+ # view_button.click(
213
+ # fn=update_page,
214
+ # inputs=[page_number, entries_per_page],
215
+ # outputs=[results_display, pagination_info, page_number, next_page_button, previous_page_button]
216
+ # )
217
+ #
218
+ # next_page_button.click(
219
+ # fn=go_to_next_page,
220
+ # inputs=[page_number, entries_per_page],
221
+ # outputs=[results_display, pagination_info, page_number, next_page_button, previous_page_button]
222
+ # )
223
+ #
224
+ # previous_page_button.click(
225
+ # fn=go_to_previous_page,
226
+ # inputs=[page_number, entries_per_page],
227
+ # outputs=[results_display, pagination_info, page_number, next_page_button, previous_page_button]
228
+ # )
229
 
230
 
231
  def format_as_html(content, title):