mirror of
https://github.com/coleam00/Archon.git
synced 2026-01-01 12:18:41 -05:00
180 lines
7.6 KiB
Python
180 lines
7.6 KiB
Python
import streamlit as st
|
|
import sys
|
|
import os
|
|
|
|
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
from utils.utils import get_env_var
|
|
|
|
@st.cache_data
|
|
def load_sql_template():
|
|
"""Load the SQL template file and cache it"""
|
|
with open(os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "utils", "site_pages.sql"), "r") as f:
|
|
return f.read()
|
|
|
|
def get_supabase_sql_editor_url(supabase_url):
|
|
"""Get the URL for the Supabase SQL Editor"""
|
|
try:
|
|
# Extract the project reference from the URL
|
|
# Format is typically: https://<project-ref>.supabase.co
|
|
if '//' in supabase_url and 'supabase' in supabase_url:
|
|
parts = supabase_url.split('//')
|
|
if len(parts) > 1:
|
|
domain_parts = parts[1].split('.')
|
|
if len(domain_parts) > 0:
|
|
project_ref = domain_parts[0]
|
|
return f"https://supabase.com/dashboard/project/{project_ref}/sql/new"
|
|
|
|
# Fallback to a generic URL
|
|
return "https://supabase.com/dashboard"
|
|
except Exception:
|
|
return "https://supabase.com/dashboard"
|
|
|
|
def show_manual_sql_instructions(sql, vector_dim, recreate=False):
|
|
"""Show instructions for manually executing SQL in Supabase"""
|
|
st.info("### Manual SQL Execution Instructions")
|
|
|
|
# Provide a link to the Supabase SQL Editor
|
|
supabase_url = get_env_var("SUPABASE_URL")
|
|
if supabase_url:
|
|
dashboard_url = get_supabase_sql_editor_url(supabase_url)
|
|
st.markdown(f"**Step 1:** [Open Your Supabase SQL Editor with this URL]({dashboard_url})")
|
|
else:
|
|
st.markdown("**Step 1:** Open your Supabase Dashboard and navigate to the SQL Editor")
|
|
|
|
st.markdown("**Step 2:** Create a new SQL query")
|
|
|
|
if recreate:
|
|
st.markdown("**Step 3:** Copy and execute the following SQL:")
|
|
drop_sql = f"DROP FUNCTION IF EXISTS match_site_pages(vector({vector_dim}), int, jsonb);\nDROP TABLE IF EXISTS site_pages CASCADE;"
|
|
st.code(drop_sql, language="sql")
|
|
|
|
st.markdown("**Step 4:** Then copy and execute this SQL:")
|
|
st.code(sql, language="sql")
|
|
else:
|
|
st.markdown("**Step 3:** Copy and execute the following SQL:")
|
|
st.code(sql, language="sql")
|
|
|
|
st.success("After executing the SQL, return to this page and refresh to see the updated table status.")
|
|
|
|
def database_tab(supabase):
|
|
"""Display the database configuration interface"""
|
|
st.header("Database Configuration")
|
|
st.write("Set up and manage your Supabase database tables for Archon.")
|
|
|
|
# Check if Supabase is configured
|
|
if not supabase:
|
|
st.error("Supabase is not configured. Please set your Supabase URL and Service Key in the Environment tab.")
|
|
return
|
|
|
|
# Site Pages Table Setup
|
|
st.subheader("Site Pages Table")
|
|
st.write("This table stores web page content and embeddings for semantic search.")
|
|
|
|
# Add information about the table
|
|
with st.expander("About the Site Pages Table", expanded=False):
|
|
st.markdown("""
|
|
This table is used to store:
|
|
- Web page content split into chunks
|
|
- Vector embeddings for semantic search
|
|
- Metadata for filtering results
|
|
|
|
The table includes:
|
|
- URL and chunk number (unique together)
|
|
- Title and summary of the content
|
|
- Full text content
|
|
- Vector embeddings for similarity search
|
|
- Metadata in JSON format
|
|
|
|
It also creates:
|
|
- A vector similarity search function
|
|
- Appropriate indexes for performance
|
|
- Row-level security policies for Supabase
|
|
""")
|
|
|
|
# Check if the table already exists
|
|
table_exists = False
|
|
table_has_data = False
|
|
|
|
try:
|
|
# Try to query the table to see if it exists
|
|
response = supabase.table("site_pages").select("id").limit(1).execute()
|
|
table_exists = True
|
|
|
|
# Check if the table has data
|
|
count_response = supabase.table("site_pages").select("*", count="exact").execute()
|
|
row_count = count_response.count if hasattr(count_response, 'count') else 0
|
|
table_has_data = row_count > 0
|
|
|
|
st.success("✅ The site_pages table already exists in your database.")
|
|
if table_has_data:
|
|
st.info(f"The table contains data ({row_count} rows).")
|
|
else:
|
|
st.info("The table exists but contains no data.")
|
|
except Exception as e:
|
|
error_str = str(e)
|
|
if "relation" in error_str and "does not exist" in error_str:
|
|
st.info("The site_pages table does not exist yet. You can create it below.")
|
|
else:
|
|
st.error(f"Error checking table status: {error_str}")
|
|
st.info("Proceeding with the assumption that the table needs to be created.")
|
|
table_exists = False
|
|
|
|
# Vector dimensions selection
|
|
st.write("### Vector Dimensions")
|
|
st.write("Select the embedding dimensions based on your embedding model:")
|
|
|
|
vector_dim = st.selectbox(
|
|
"Embedding Dimensions",
|
|
options=[1536, 768, 384, 1024],
|
|
index=0,
|
|
help="Use 1536 for OpenAI embeddings, 768 for nomic-embed-text with Ollama, or select another dimension based on your model."
|
|
)
|
|
|
|
# Get the SQL with the selected vector dimensions
|
|
sql_template = load_sql_template()
|
|
|
|
# Replace the vector dimensions in the SQL
|
|
sql = sql_template.replace("vector(1536)", f"vector({vector_dim})")
|
|
|
|
# Also update the match_site_pages function dimensions
|
|
sql = sql.replace("query_embedding vector(1536)", f"query_embedding vector({vector_dim})")
|
|
|
|
# Show the SQL
|
|
with st.expander("View SQL", expanded=False):
|
|
st.code(sql, language="sql")
|
|
|
|
# Create table button
|
|
if not table_exists:
|
|
if st.button("Get Instructions for Creating Site Pages Table"):
|
|
show_manual_sql_instructions(sql, vector_dim)
|
|
else:
|
|
# Option to recreate the table or clear data
|
|
col1, col2 = st.columns(2)
|
|
|
|
with col1:
|
|
st.warning("⚠️ Recreating will delete all existing data.")
|
|
if st.button("Get Instructions for Recreating Site Pages Table"):
|
|
show_manual_sql_instructions(sql, vector_dim, recreate=True)
|
|
|
|
with col2:
|
|
if table_has_data:
|
|
st.warning("⚠️ Clear all data but keep structure.")
|
|
if st.button("Clear Table Data"):
|
|
try:
|
|
with st.spinner("Clearing table data..."):
|
|
# Use the Supabase client to delete all rows
|
|
response = supabase.table("site_pages").delete().neq("id", 0).execute()
|
|
st.success("✅ Table data cleared successfully!")
|
|
st.rerun()
|
|
except Exception as e:
|
|
st.error(f"Error clearing table data: {str(e)}")
|
|
# Fall back to manual SQL
|
|
truncate_sql = "TRUNCATE TABLE site_pages;"
|
|
st.code(truncate_sql, language="sql")
|
|
st.info("Execute this SQL in your Supabase SQL Editor to clear the table data.")
|
|
|
|
# Provide a link to the Supabase SQL Editor
|
|
supabase_url = get_env_var("SUPABASE_URL")
|
|
if supabase_url:
|
|
dashboard_url = get_supabase_sql_editor_url(supabase_url)
|
|
st.markdown(f"[Open Your Supabase SQL Editor with this URL]({dashboard_url})") |