import streamlit as st from humanize import naturaltime from open_notebook.domain.notebook import Notebook from pages.stream_app.chat import chat_sidebar from pages.stream_app.note import add_note, note_card from pages.stream_app.source import add_source, source_card from pages.stream_app.utils import setup_page, setup_stream_state setup_page("📒 Open Notebook", only_check_mandatory_models=True) def notebook_header(current_notebook: Notebook): """ Defines the header of the notebook page, including the ability to edit the notebook's name and description. """ c1, c2, c3 = st.columns([8, 2, 2]) c1.header(current_notebook.name) if c2.button("Back to the list", icon="🔙"): st.session_state["current_notebook_id"] = None st.rerun() if c3.button("Refresh", icon="🔄"): st.rerun() current_description = current_notebook.description with st.expander( current_notebook.description if len(current_description) > 0 else "click to add a description" ): notebook_name = st.text_input("Name", value=current_notebook.name) notebook_description = st.text_area( "Description", value=current_description, placeholder="Add as much context as you can as this will be used by the AI to generate insights.", ) c1, c2, c3 = st.columns([1, 1, 1]) if c1.button("Save", icon="💾", key="edit_notebook"): current_notebook.name = notebook_name current_notebook.description = notebook_description current_notebook.save() st.rerun() if not current_notebook.archived: if c2.button("Archive", icon="🗃️"): current_notebook.archived = True current_notebook.save() st.toast("Notebook archived", icon="🗃️") else: if c2.button("Unarchive", icon="🗃️"): current_notebook.archived = False current_notebook.save() st.toast("Notebook unarchived", icon="🗃️") if c3.button("Delete forever", type="primary", icon="☠️"): current_notebook.delete() st.session_state["current_notebook_id"] = None st.rerun() def notebook_page(current_notebook: Notebook): # Guarantees that we have an entry for this notebook in the session state if current_notebook.id not in st.session_state: st.session_state[current_notebook.id] = {"notebook": current_notebook} # sets up the active session current_session = setup_stream_state( current_notebook=current_notebook, ) sources = current_notebook.sources notes = current_notebook.notes notebook_header(current_notebook) work_tab, chat_tab = st.columns([4, 2]) with work_tab: sources_tab, notes_tab = st.columns(2) with sources_tab: with st.container(border=True): if st.button("Add Source", icon="➕"): add_source(current_notebook.id) for source in sources: source_card(source=source, notebook_id=current_notebook.id) with notes_tab: with st.container(border=True): if st.button("Write a Note", icon="📝"): add_note(current_notebook.id) for note in notes: note_card(note=note, notebook_id=current_notebook.id) with chat_tab: chat_sidebar(current_notebook=current_notebook, current_session=current_session) def notebook_list_item(notebook): with st.container(border=True): st.subheader(notebook.name) st.caption( f"Created: {naturaltime(notebook.created)}, updated: {naturaltime(notebook.updated)}" ) st.write(notebook.description) if st.button("Open", key=f"open_notebook_{notebook.id}"): st.session_state["current_notebook_id"] = notebook.id st.rerun() if "current_notebook_id" not in st.session_state: st.session_state["current_notebook_id"] = None # todo: get the notebook, check if it exists and if it's archived if st.session_state["current_notebook_id"]: current_notebook: Notebook = Notebook.get(st.session_state["current_notebook_id"]) if not current_notebook: st.error("Notebook not found") st.stop() notebook_page(current_notebook) st.stop() st.title("📒 My Notebooks") st.caption( "Notebooks are a great way to organize your thoughts, ideas, and sources. You can create notebooks for different research topics and projects, to create new articles, etc. " ) with st.expander("➕ **New Notebook**"): new_notebook_title = st.text_input("New Notebook Name") new_notebook_description = st.text_area( "Description", placeholder="Explain the purpose of this notebook. The more details the better.", ) if st.button("Create a new Notebook", icon="➕"): notebook = Notebook( name=new_notebook_title, description=new_notebook_description ) notebook.save() st.toast("Notebook created successfully", icon="📒") notebooks = Notebook.get_all(order_by="updated desc") archived_notebooks = [nb for nb in notebooks if nb.archived] for notebook in notebooks: if notebook.archived: continue notebook_list_item(notebook) if len(archived_notebooks) > 0: with st.expander(f"**🗃️ {len(archived_notebooks)} archived Notebooks**"): st.write("ℹ Archived Notebooks can still be accessed and used in search.") for notebook in archived_notebooks: notebook_list_item(notebook)