mirror of
https://github.com/lfnovo/open-notebook.git
synced 2026-05-05 15:24:35 +00:00
222 lines
8.1 KiB
Python
222 lines
8.1 KiB
Python
import os
|
|
|
|
import streamlit as st
|
|
|
|
from open_notebook.domain.models import DefaultModels, Model
|
|
from open_notebook.models import MODEL_CLASS_MAP
|
|
from stream_app.utils import version_sidebar
|
|
|
|
st.set_page_config(
|
|
layout="wide", page_title="⚙️ Settings", initial_sidebar_state="expanded"
|
|
)
|
|
version_sidebar()
|
|
|
|
|
|
st.title("⚙️ Settings")
|
|
|
|
model_tab, model_defaults_tab = st.tabs(["Models", "Model Defaults"])
|
|
|
|
provider_status = {}
|
|
|
|
model_types = [
|
|
# "vision",
|
|
"language",
|
|
"embedding",
|
|
"text_to_speech",
|
|
"speech_to_text",
|
|
]
|
|
|
|
provider_status["ollama"] = os.environ.get("OLLAMA_API_BASE") is not None
|
|
provider_status["openai"] = os.environ.get("OPENAI_API_KEY") is not None
|
|
provider_status["vertexai"] = (
|
|
os.environ.get("VERTEX_PROJECT") is not None
|
|
and os.environ.get("VERTEX_LOCATION") is not None
|
|
and os.environ.get("GOOGLE_APPLICATION_CREDENTIALS") is not None
|
|
)
|
|
provider_status["vertexai-anthropic"] = (
|
|
os.environ.get("VERTEX_PROJECT") is not None
|
|
and os.environ.get("VERTEX_LOCATION") is not None
|
|
and os.environ.get("GOOGLE_APPLICATION_CREDENTIALS") is not None
|
|
)
|
|
provider_status["gemini"] = os.environ.get("GEMINI_API_KEY") is not None
|
|
provider_status["openrouter"] = (
|
|
os.environ.get("OPENROUTER_API_KEY") is not None
|
|
and os.environ.get("OPENAI_API_KEY") is not None
|
|
and os.environ.get("OPENROUTER_BASE_URL") is not None
|
|
)
|
|
provider_status["anthropic"] = os.environ.get("ANTHROPIC_API_KEY") is not None
|
|
provider_status["elevenlabs"] = os.environ.get("ELEVENLABS_API_KEY") is not None
|
|
provider_status["litellm"] = (
|
|
provider_status["ollama"]
|
|
or provider_status["vertexai"]
|
|
or provider_status["vertexai-anthropic"]
|
|
or provider_status["anthropic"]
|
|
or provider_status["openai"]
|
|
or provider_status["gemini"]
|
|
)
|
|
|
|
available_providers = [k for k, v in provider_status.items() if v]
|
|
unavailable_providers = [k for k, v in provider_status.items() if not v]
|
|
|
|
with model_tab:
|
|
st.subheader("Add Model")
|
|
provider = st.selectbox("Provider", available_providers)
|
|
if len(unavailable_providers) > 0:
|
|
st.caption(
|
|
f"Unavailable Providers: {', '.join(unavailable_providers)}. Please check docs page if you wish to enable them."
|
|
)
|
|
|
|
# Filter model types based on provider availability in MODEL_CLASS_MAP
|
|
available_model_types = []
|
|
for model_type in model_types:
|
|
if model_type in MODEL_CLASS_MAP and provider in MODEL_CLASS_MAP[model_type]:
|
|
available_model_types.append(model_type)
|
|
|
|
if not available_model_types:
|
|
st.error(f"No compatible model types available for provider: {provider}")
|
|
else:
|
|
model_type = st.selectbox(
|
|
"Model Type",
|
|
available_model_types,
|
|
help="Use language for text generation models, text_to_speech for TTS models for generating podcasts, etc.",
|
|
)
|
|
model_name = st.text_input(
|
|
"Model Name", "", help="gpt-4o-mini, claude, gemini, llama3, etc"
|
|
)
|
|
if st.button("Save"):
|
|
model = Model(name=model_name, provider=provider, type=model_type)
|
|
model.save()
|
|
st.success("Saved")
|
|
st.divider()
|
|
all_models = Model.get_all()
|
|
st.subheader("Configured Models")
|
|
model_types_available = {
|
|
# "vision": False,
|
|
"language": False,
|
|
"embedding": False,
|
|
"text_to_speech": False,
|
|
"speech_to_text": False,
|
|
}
|
|
for model in all_models:
|
|
model_types_available[model.type] = True
|
|
with st.container(border=True):
|
|
st.markdown(f"{model.name} ({model.provider}, {model.type})")
|
|
if st.button("Delete", key=f"delete_{model.id}"):
|
|
model.delete()
|
|
st.rerun()
|
|
|
|
for model_type, available in model_types_available.items():
|
|
if not available:
|
|
st.warning(f"No models available for {model_type}")
|
|
|
|
|
|
def get_selected_index(models, model_id, default=0):
|
|
"""Returns the index of the selected model in the list of models"""
|
|
if not model_id or not models:
|
|
return default
|
|
for i, model in enumerate(models):
|
|
if model.id == model_id:
|
|
return i
|
|
return default
|
|
|
|
|
|
with model_defaults_tab:
|
|
default_models = DefaultModels.load().model_dump()
|
|
all_models = Model.get_all()
|
|
text_generation_models = [model for model in all_models if model.type == "language"]
|
|
|
|
text_to_speech_models = [
|
|
model for model in all_models if model.type == "text_to_speech"
|
|
]
|
|
|
|
speech_to_text_models = [
|
|
model for model in all_models if model.type == "speech_to_text"
|
|
]
|
|
vision_models = [model for model in all_models if model.type == "vision"]
|
|
embedding_models = [model for model in all_models if model.type == "embedding"]
|
|
st.write(
|
|
"In this section, you can select the default models to be used on the various content operations done by Open Notebook. Some of these can be overriden in the different modules."
|
|
)
|
|
defs = {}
|
|
defs["default_chat_model"] = st.selectbox(
|
|
"Default Chat Model",
|
|
text_generation_models,
|
|
format_func=lambda x: x.name,
|
|
help="This model will be used for chat.",
|
|
index=get_selected_index(
|
|
text_generation_models, default_models.get("default_chat_model")
|
|
),
|
|
)
|
|
st.divider()
|
|
defs["default_transformation_model"] = st.selectbox(
|
|
"Default Transformation Model",
|
|
text_generation_models,
|
|
format_func=lambda x: x.name,
|
|
help="This model will be used for text transformations such as summaries, insights, etc.",
|
|
index=get_selected_index(
|
|
text_generation_models, default_models.get("default_transformation_model")
|
|
),
|
|
)
|
|
st.caption("You can override this model on individual transformations")
|
|
st.divider()
|
|
defs["large_context_model"] = st.selectbox(
|
|
"Large Context Model",
|
|
text_generation_models,
|
|
format_func=lambda x: x.name,
|
|
help="This model will be used for larger context generation -- recommended: Gemini",
|
|
index=get_selected_index(
|
|
text_generation_models, default_models.get("large_context_model")
|
|
),
|
|
)
|
|
st.caption("Recommended to use Gemini models for larger context processing")
|
|
st.divider()
|
|
defs["default_text_to_speech_model"] = st.selectbox(
|
|
"Default Text to Speech Model",
|
|
text_to_speech_models,
|
|
format_func=lambda x: x.name,
|
|
help="This is the default model for converting text to speech (podcasts, etc)",
|
|
index=get_selected_index(
|
|
text_to_speech_models, default_models.get("default_text_to_speech_model")
|
|
),
|
|
)
|
|
st.caption("You can override this model on different podcasts")
|
|
st.divider()
|
|
defs["default_speech_to_text_model"] = st.selectbox(
|
|
"Default Speech to Text Model",
|
|
speech_to_text_models,
|
|
format_func=lambda x: x.name,
|
|
help="This is the default model for converting speech to text (audio transcriptions, etc)",
|
|
index=get_selected_index(
|
|
speech_to_text_models, default_models.get("default_speech_to_text_model")
|
|
),
|
|
)
|
|
st.divider()
|
|
# defs["default_vision_model"] = st.selectbox(
|
|
# "Default Vision Model",
|
|
# vision_models,
|
|
# format_func=lambda x: x.name,
|
|
# help="This is the default model for vision tasks (image recognition, PDF recognition, etc)",
|
|
# index=get_selected_index(
|
|
# vision_models, default_models.get("default_vision_model")
|
|
# ),
|
|
# )
|
|
# st.divider()
|
|
|
|
defs["default_embedding_model"] = st.selectbox(
|
|
"Default Embedding Model",
|
|
embedding_models,
|
|
format_func=lambda x: x.name,
|
|
help="This is the default model for embeddings (semantic search, etc)",
|
|
index=get_selected_index(
|
|
embedding_models, default_models.get("default_embedding_model")
|
|
),
|
|
)
|
|
st.caption(
|
|
"Caution: you cannot change the embedding model once there is embeddings or they will need to be regenerated"
|
|
)
|
|
|
|
# if st.button("Save Defaults", key="save_defaults"):
|
|
for k, v in defs.items():
|
|
if v:
|
|
defs[k] = v.id
|
|
DefaultModels.update(defs)
|