open-notebook/pages/components/source_panel.py
Luis Novo b7e656a319
Version 1 (#160)
New front-end
Launch Chat API
Manage Sources
Enable re-embedding of all contents
Sources can be added without a notebook now
Improved settings
Enable model selector on all chats
Background processing for better experience
Dark mode
Improved Notes

Improved Docs: 
- Remove all Streamlit references from documentation
- Update deployment guides with React frontend setup
- Fix Docker environment variables format (SURREAL_URL, SURREAL_PASSWORD)
- Update docker image tag from :latest to :v1-latest
- Change navigation references (Settings → Models to just Models)
- Update development setup to include frontend npm commands
- Add MIGRATION.md guide for users upgrading from Streamlit
- Update quick-start guide with correct environment variables
- Add port 5055 documentation for API access
- Update project structure to reflect frontend/ directory
- Remove outdated source-chat documentation files
2025-10-18 12:46:22 -03:00

115 lines
5.3 KiB
Python

import streamlit as st
from humanize import naturaltime
from api.insights_service import insights_service
from api.models_service import ModelsService
from api.sources_service import SourcesService
from api.transformations_service import TransformationsService
from pages.stream_app.utils import check_models
# Initialize service instances
sources_service = SourcesService()
transformations_service = TransformationsService()
models_service = ModelsService()
def source_panel(source_id: str, notebook_id=None, modal=False):
check_models(only_mandatory=False)
source_with_metadata = sources_service.get_source(source_id)
if not source_with_metadata:
raise ValueError(f"Source not found: {source_id}")
# Now we can access both the source and embedded_chunks directly
current_title = source_with_metadata.title if source_with_metadata.title else "No Title"
source_with_metadata.title = st.text_input("Title", value=current_title)
if source_with_metadata.title != current_title:
sources_service.update_source(source_with_metadata.source)
st.toast("Saved new Title")
process_tab, source_tab = st.tabs(["Process", "Source"])
with process_tab:
c1, c2 = st.columns([4, 2])
with c1:
title = st.empty()
if source_with_metadata.title:
title.subheader(source_with_metadata.title)
if source_with_metadata.asset and source_with_metadata.asset.url:
from_src = f"from URL: {source_with_metadata.asset.url}"
elif source_with_metadata.asset and source_with_metadata.asset.file_path:
from_src = f"from file: {source_with_metadata.asset.file_path}"
else:
from_src = "from text"
st.caption(f"Created {naturaltime(source_with_metadata.created)}, {from_src}")
for insight in insights_service.get_source_insights(source_with_metadata.id):
with st.expander(f"**{insight.insight_type}**"):
st.markdown(insight.content)
x1, x2 = st.columns(2)
if x1.button(
"Delete", type="primary", key=f"delete_insight_{insight.id}"
):
insights_service.delete_insight(insight.id or "")
st.rerun(scope="fragment" if modal else "app")
st.toast("Insight deleted")
if notebook_id:
if x2.button(
"Save as Note", icon="📝", key=f"save_note_{insight.id}"
):
insights_service.save_insight_as_note(insight.id or "", notebook_id)
st.toast("Saved as Note. Refresh the Notebook to see it.")
with c2:
transformations = transformations_service.get_all_transformations()
if transformations:
with st.container(border=True):
transformation = st.selectbox(
"Run a transformation",
transformations,
key=f"transformation_{source_with_metadata.id}",
format_func=lambda x: x.name,
)
st.caption(transformation.description if transformation else "")
if st.button("Run"):
insights_service.create_source_insight(
source_id=source_with_metadata.id,
transformation_id=transformation.id or ""
)
st.rerun(scope="fragment" if modal else "app")
else:
st.markdown(
"No transformations created yet. Create new Transformation to use this feature."
)
default_models = models_service.get_default_models()
embedding_model = default_models.default_embedding_model
if not embedding_model:
help = (
"No embedding model found. Please, select one on the Models page."
)
else:
help = "This will generate your embedding vectors on the database for powerful search capabilities"
if not source_with_metadata.embedded_chunks and st.button(
"Embed vectors",
icon="🦾",
help=help,
disabled=not embedding_model,
):
from api.embedding_service import embedding_service
result = embedding_service.embed_content(source_with_metadata.id, "source")
result_dict = result if isinstance(result, dict) else result[0] if isinstance(result, list) else {}
st.success(result_dict.get("message", "Embedding complete"))
with st.container(border=True):
st.caption(
"Deleting the source will also delete all its insights and embeddings"
)
if st.button(
"Delete", type="primary", key=f"bt_delete_source_{source_with_metadata.id}"
):
sources_service.delete_source(source_with_metadata.id)
st.rerun()
with source_tab:
st.subheader("Content")
st.markdown(source_with_metadata.full_text)