mirror of
https://github.com/onyx-dot-app/onyx.git
synced 2026-02-26 12:15:48 +00:00
Compare commits
5 Commits
bb
...
query_pagi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2e8493b837 | ||
|
|
b467e29179 | ||
|
|
8a905571b0 | ||
|
|
1fa34c93ea | ||
|
|
4b737e9101 |
@@ -13,6 +13,7 @@ def make_persona_private(
|
||||
persona_id: int,
|
||||
user_ids: list[UUID] | None,
|
||||
group_ids: list[int] | None,
|
||||
creator_id: UUID | None,
|
||||
db_session: Session,
|
||||
) -> None:
|
||||
db_session.query(Persona__User).filter(
|
||||
@@ -26,14 +27,15 @@ def make_persona_private(
|
||||
for user_uuid in user_ids:
|
||||
db_session.add(Persona__User(persona_id=persona_id, user_id=user_uuid))
|
||||
|
||||
create_notification(
|
||||
user_id=user_uuid,
|
||||
notif_type=NotificationType.PERSONA_SHARED,
|
||||
db_session=db_session,
|
||||
additional_data=PersonaSharedNotificationData(
|
||||
persona_id=persona_id,
|
||||
).model_dump(),
|
||||
)
|
||||
if creator_id and creator_id != user_uuid:
|
||||
create_notification(
|
||||
user_id=user_uuid,
|
||||
notif_type=NotificationType.PERSONA_SHARED,
|
||||
db_session=db_session,
|
||||
additional_data=PersonaSharedNotificationData(
|
||||
persona_id=persona_id,
|
||||
).model_dump(),
|
||||
)
|
||||
if group_ids:
|
||||
for group_id in group_ids:
|
||||
db_session.add(
|
||||
|
||||
@@ -132,8 +132,13 @@ def fetch_chat_sessions_eagerly_by_time(
|
||||
end: datetime,
|
||||
db_session: Session,
|
||||
limit: int | None = 500,
|
||||
offset: int | None = 0,
|
||||
initial_time: datetime | None = None,
|
||||
) -> list[ChatSession]:
|
||||
"""
|
||||
Fetch chunks of ChatSession objects eagerly by time, supporting pagination
|
||||
with limit/offset.
|
||||
"""
|
||||
time_order: UnaryExpression = desc(ChatSession.time_created)
|
||||
message_order: UnaryExpression = asc(ChatMessage.id)
|
||||
|
||||
@@ -150,6 +155,7 @@ def fetch_chat_sessions_eagerly_by_time(
|
||||
.order_by(ChatSession.id, time_order)
|
||||
.distinct(ChatSession.id)
|
||||
.limit(limit)
|
||||
.offset(offset)
|
||||
.subquery()
|
||||
)
|
||||
|
||||
@@ -167,6 +173,4 @@ def fetch_chat_sessions_eagerly_by_time(
|
||||
.order_by(time_order, message_order)
|
||||
)
|
||||
|
||||
chat_sessions = query.all()
|
||||
|
||||
return chat_sessions
|
||||
return query.all()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import csv
|
||||
import io
|
||||
from collections.abc import Generator
|
||||
from datetime import datetime
|
||||
from datetime import timezone
|
||||
from uuid import UUID
|
||||
@@ -35,6 +36,8 @@ from onyx.server.query_and_chat.models import ChatSessionsResponse
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
CHUNK_SIZE = 500 # or whatever size is appropriate
|
||||
|
||||
|
||||
def fetch_and_process_chat_session_history(
|
||||
db_session: Session,
|
||||
@@ -203,34 +206,61 @@ def get_query_history_as_csv(
|
||||
end: datetime | None = None,
|
||||
db_session: Session = Depends(get_session),
|
||||
) -> StreamingResponse:
|
||||
complete_chat_session_history = fetch_and_process_chat_session_history(
|
||||
db_session=db_session,
|
||||
start=start or datetime.fromtimestamp(0, tz=timezone.utc),
|
||||
end=end or datetime.now(tz=timezone.utc),
|
||||
feedback_type=None,
|
||||
limit=None,
|
||||
)
|
||||
"""Stream the CSV in chunks to avoid timeout and high memory usage."""
|
||||
# Set up the time range defaults
|
||||
start_time = start or datetime.fromtimestamp(0, tz=timezone.utc)
|
||||
end_time = end or datetime.now(tz=timezone.utc)
|
||||
|
||||
question_answer_pairs: list[QuestionAnswerPairSnapshot] = []
|
||||
for chat_session_snapshot in complete_chat_session_history:
|
||||
question_answer_pairs.extend(
|
||||
QuestionAnswerPairSnapshot.from_chat_session_snapshot(chat_session_snapshot)
|
||||
)
|
||||
# Build the streaming generator
|
||||
def generate_csv() -> Generator[str, None, None]:
|
||||
# Prepare CSV writer
|
||||
fieldnames = list(QuestionAnswerPairSnapshot.model_fields.keys())
|
||||
buffer = io.StringIO()
|
||||
writer = csv.DictWriter(buffer, fieldnames=fieldnames)
|
||||
|
||||
# Create an in-memory text stream
|
||||
stream = io.StringIO()
|
||||
writer = csv.DictWriter(
|
||||
stream, fieldnames=list(QuestionAnswerPairSnapshot.model_fields.keys())
|
||||
)
|
||||
writer.writeheader()
|
||||
for row in question_answer_pairs:
|
||||
writer.writerow(row.to_json())
|
||||
writer.writeheader()
|
||||
yield buffer.getvalue()
|
||||
buffer.seek(0)
|
||||
buffer.truncate(0)
|
||||
|
||||
# Reset the stream's position to the start
|
||||
stream.seek(0)
|
||||
# Paginate or chunk the fetching of sessions
|
||||
offset = 0
|
||||
while True:
|
||||
# Example chunk-based fetch from DB
|
||||
chunk_of_chat_sessions = fetch_chat_sessions_eagerly_by_time(
|
||||
start=start_time,
|
||||
end=end_time,
|
||||
db_session=db_session,
|
||||
limit=CHUNK_SIZE,
|
||||
offset=offset,
|
||||
)
|
||||
if not chunk_of_chat_sessions:
|
||||
break # no more data
|
||||
|
||||
# Convert each chat session to question-answer pairs
|
||||
for chat_session in chunk_of_chat_sessions:
|
||||
chat_snapshot = snapshot_from_chat_session(
|
||||
chat_session=chat_session,
|
||||
db_session=db_session,
|
||||
)
|
||||
if chat_snapshot is None:
|
||||
continue
|
||||
|
||||
# Build Q/A pairs
|
||||
qa_pairs = QuestionAnswerPairSnapshot.from_chat_session_snapshot(
|
||||
chat_snapshot
|
||||
)
|
||||
for row in qa_pairs:
|
||||
writer.writerow(row.to_json())
|
||||
# Yield the CSV row text
|
||||
yield buffer.getvalue()
|
||||
buffer.seek(0)
|
||||
buffer.truncate(0)
|
||||
|
||||
offset += CHUNK_SIZE
|
||||
|
||||
return StreamingResponse(
|
||||
iter([stream.getvalue()]),
|
||||
generate_csv(),
|
||||
media_type="text/csv",
|
||||
headers={"Content-Disposition": "attachment;filename=onyx_query_history.csv"},
|
||||
)
|
||||
|
||||
@@ -156,6 +156,8 @@ class DynamicTenantScheduler(PersistentScheduler):
|
||||
logger.info(
|
||||
"_try_updating_schedule: Current schedule is up to date, no changes needed"
|
||||
)
|
||||
logger.info("Current schedule is the following:")
|
||||
logger.info(current_schedule)
|
||||
return
|
||||
|
||||
logger.info(
|
||||
|
||||
@@ -68,6 +68,8 @@ logger = setup_logger()
|
||||
def check_for_indexing(self: Task, *, tenant_id: str | None) -> int | None:
|
||||
"""a lightweight task used to kick off indexing tasks.
|
||||
Occcasionally does some validation of existing state to clear up error conditions"""
|
||||
|
||||
task = f"check_for_indexing start: tenant_id={tenant_id}"
|
||||
time_start = time.monotonic()
|
||||
|
||||
tasks_created = 0
|
||||
@@ -86,8 +88,11 @@ def check_for_indexing(self: Task, *, tenant_id: str | None) -> int | None:
|
||||
|
||||
# these tasks should never overlap
|
||||
if not lock_beat.acquire(blocking=False):
|
||||
task_logger.info(f"{task} - Lock not acquired")
|
||||
return None
|
||||
|
||||
task_logger.info(f"{task} - Lock acquired")
|
||||
|
||||
try:
|
||||
locked = True
|
||||
|
||||
|
||||
@@ -234,6 +234,8 @@ def cloud_beat_task_generator(
|
||||
expires: int = BEAT_EXPIRES_DEFAULT,
|
||||
) -> bool | None:
|
||||
"""a lightweight task used to kick off individual beat tasks per tenant."""
|
||||
task = f"cloud_beat_task_generator start: task_name={task_name}, queue={queue}, priority={priority}"
|
||||
|
||||
time_start = time.monotonic()
|
||||
|
||||
redis_client = get_redis_client(tenant_id=ONYX_CLOUD_TENANT_ID)
|
||||
@@ -245,8 +247,10 @@ def cloud_beat_task_generator(
|
||||
|
||||
# these tasks should never overlap
|
||||
if not lock_beat.acquire(blocking=False):
|
||||
task_logger.info(f"{task} - Lock not acquired")
|
||||
return None
|
||||
|
||||
task_logger.info(f"{task} - Lock acquired")
|
||||
last_lock_time = time.monotonic()
|
||||
tenant_ids: list[str] | list[None] = []
|
||||
|
||||
@@ -262,6 +266,9 @@ def cloud_beat_task_generator(
|
||||
if IGNORED_SYNCING_TENANT_LIST and tenant_id in IGNORED_SYNCING_TENANT_LIST:
|
||||
continue
|
||||
|
||||
task_logger.info(
|
||||
f"{task} - sending task: task_name={task_name}, tenant_id={tenant_id}"
|
||||
)
|
||||
self.app.send_task(
|
||||
task_name,
|
||||
kwargs=dict(
|
||||
|
||||
@@ -163,6 +163,7 @@ def make_persona_private(
|
||||
persona_id: int,
|
||||
user_ids: list[UUID] | None,
|
||||
group_ids: list[int] | None,
|
||||
creator_id: UUID | None,
|
||||
db_session: Session,
|
||||
) -> None:
|
||||
if user_ids is not None:
|
||||
@@ -173,14 +174,15 @@ def make_persona_private(
|
||||
for user_uuid in user_ids:
|
||||
db_session.add(Persona__User(persona_id=persona_id, user_id=user_uuid))
|
||||
|
||||
create_notification(
|
||||
user_id=user_uuid,
|
||||
notif_type=NotificationType.PERSONA_SHARED,
|
||||
db_session=db_session,
|
||||
additional_data=PersonaSharedNotificationData(
|
||||
persona_id=persona_id,
|
||||
).model_dump(),
|
||||
)
|
||||
if creator_id and creator_id != user_uuid:
|
||||
create_notification(
|
||||
user_id=user_uuid,
|
||||
notif_type=NotificationType.PERSONA_SHARED,
|
||||
db_session=db_session,
|
||||
additional_data=PersonaSharedNotificationData(
|
||||
persona_id=persona_id,
|
||||
).model_dump(),
|
||||
)
|
||||
|
||||
db_session.commit()
|
||||
|
||||
@@ -240,6 +242,7 @@ def create_update_persona(
|
||||
persona_id=persona.id,
|
||||
user_ids=create_persona_request.users,
|
||||
group_ids=create_persona_request.groups,
|
||||
creator_id=user.id if user else None,
|
||||
db_session=db_session,
|
||||
)
|
||||
|
||||
@@ -275,6 +278,7 @@ def update_persona_shared_users(
|
||||
persona_id=persona_id,
|
||||
user_ids=user_ids,
|
||||
group_ids=None,
|
||||
creator_id=user.id if user else None,
|
||||
db_session=db_session,
|
||||
)
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@ from langchain_core.prompt_values import PromptValue
|
||||
|
||||
from onyx.configs.app_configs import LOG_DANSWER_MODEL_INTERACTIONS
|
||||
from onyx.configs.app_configs import MOCK_LLM_RESPONSE
|
||||
from onyx.configs.chat_configs import QA_TIMEOUT
|
||||
from onyx.configs.model_configs import (
|
||||
DISABLE_LITELLM_STREAMING,
|
||||
)
|
||||
@@ -36,7 +35,6 @@ from onyx.configs.model_configs import LITELLM_EXTRA_BODY
|
||||
from onyx.llm.interfaces import LLM
|
||||
from onyx.llm.interfaces import LLMConfig
|
||||
from onyx.llm.interfaces import ToolChoiceOptions
|
||||
from onyx.llm.utils import model_is_reasoning_model
|
||||
from onyx.server.utils import mask_string
|
||||
from onyx.utils.logger import setup_logger
|
||||
from onyx.utils.long_term_log import LongTermLogger
|
||||
@@ -231,15 +229,15 @@ class DefaultMultiLLM(LLM):
|
||||
def __init__(
|
||||
self,
|
||||
api_key: str | None,
|
||||
timeout: int,
|
||||
model_provider: str,
|
||||
model_name: str,
|
||||
timeout: int | None = None,
|
||||
api_base: str | None = None,
|
||||
api_version: str | None = None,
|
||||
deployment_name: str | None = None,
|
||||
max_output_tokens: int | None = None,
|
||||
custom_llm_provider: str | None = None,
|
||||
temperature: float | None = None,
|
||||
temperature: float = GEN_AI_TEMPERATURE,
|
||||
custom_config: dict[str, str] | None = None,
|
||||
extra_headers: dict[str, str] | None = None,
|
||||
extra_body: dict | None = LITELLM_EXTRA_BODY,
|
||||
@@ -247,16 +245,9 @@ class DefaultMultiLLM(LLM):
|
||||
long_term_logger: LongTermLogger | None = None,
|
||||
):
|
||||
self._timeout = timeout
|
||||
if timeout is None:
|
||||
if model_is_reasoning_model(model_name):
|
||||
self._timeout = QA_TIMEOUT * 10 # Reasoning models are slow
|
||||
else:
|
||||
self._timeout = QA_TIMEOUT
|
||||
|
||||
self._temperature = GEN_AI_TEMPERATURE if temperature is None else temperature
|
||||
|
||||
self._model_provider = model_provider
|
||||
self._model_version = model_name
|
||||
self._temperature = temperature
|
||||
self._api_key = api_key
|
||||
self._deployment_name = deployment_name
|
||||
self._api_base = api_base
|
||||
|
||||
@@ -2,6 +2,7 @@ from typing import Any
|
||||
|
||||
from onyx.chat.models import PersonaOverrideConfig
|
||||
from onyx.configs.app_configs import DISABLE_GENERATIVE_AI
|
||||
from onyx.configs.chat_configs import QA_TIMEOUT
|
||||
from onyx.configs.model_configs import GEN_AI_MODEL_FALLBACK_MAX_TOKENS
|
||||
from onyx.configs.model_configs import GEN_AI_TEMPERATURE
|
||||
from onyx.db.engine import get_session_context_manager
|
||||
@@ -87,8 +88,8 @@ def get_llms_for_persona(
|
||||
|
||||
|
||||
def get_default_llms(
|
||||
timeout: int | None = None,
|
||||
temperature: float | None = None,
|
||||
timeout: int = QA_TIMEOUT,
|
||||
temperature: float = GEN_AI_TEMPERATURE,
|
||||
additional_headers: dict[str, str] | None = None,
|
||||
long_term_logger: LongTermLogger | None = None,
|
||||
) -> tuple[LLM, LLM]:
|
||||
@@ -137,7 +138,7 @@ def get_llm(
|
||||
api_version: str | None = None,
|
||||
custom_config: dict[str, str] | None = None,
|
||||
temperature: float | None = None,
|
||||
timeout: int | None = None,
|
||||
timeout: int = QA_TIMEOUT,
|
||||
additional_headers: dict[str, str] | None = None,
|
||||
long_term_logger: LongTermLogger | None = None,
|
||||
) -> LLM:
|
||||
|
||||
@@ -29,11 +29,11 @@ OPENAI_PROVIDER_NAME = "openai"
|
||||
OPEN_AI_MODEL_NAMES = [
|
||||
"o3-mini",
|
||||
"o1-mini",
|
||||
"o1",
|
||||
"o1-preview",
|
||||
"o1-2024-12-17",
|
||||
"gpt-4",
|
||||
"gpt-4o",
|
||||
"gpt-4o-mini",
|
||||
"o1-preview",
|
||||
"gpt-4-turbo",
|
||||
"gpt-4-turbo-preview",
|
||||
"gpt-4-1106-preview",
|
||||
|
||||
@@ -543,14 +543,3 @@ def model_supports_image_input(model_name: str, model_provider: str) -> bool:
|
||||
f"Failed to get model object for {model_provider}/{model_name}"
|
||||
)
|
||||
return False
|
||||
|
||||
|
||||
def model_is_reasoning_model(model_name: str) -> bool:
|
||||
_REASONING_MODEL_NAMES = [
|
||||
"o1",
|
||||
"o1-mini",
|
||||
"o3-mini",
|
||||
"deepseek-reasoner",
|
||||
"deepseek-r1",
|
||||
]
|
||||
return model_name.lower() in _REASONING_MODEL_NAMES
|
||||
|
||||
@@ -147,8 +147,8 @@ const AssistantCard: React.FC<{
|
||||
)}
|
||||
</div>
|
||||
{isOwnedByUser && (
|
||||
<div className="flex ml-2 relative items-center gap-x-2">
|
||||
<Popover>
|
||||
<div className="flex ml-2 relative items-center gap-x-2">
|
||||
<Popover modal>
|
||||
<PopoverTrigger>
|
||||
<button
|
||||
type="button"
|
||||
@@ -157,7 +157,9 @@ const AssistantCard: React.FC<{
|
||||
<FiMoreHorizontal size={16} />
|
||||
</button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className={`w-32 z-[10000] p-2`}>
|
||||
<PopoverContent
|
||||
className={`w-32 z-[10000] p-2 hover:bg-red-400`}
|
||||
>
|
||||
<div className="flex flex-col text-sm space-y-1">
|
||||
<button
|
||||
onClick={isOwnedByUser ? handleEdit : undefined}
|
||||
|
||||
@@ -8,7 +8,6 @@ import { useUser } from "@/components/user/UserProvider";
|
||||
import { FilterIcon } from "lucide-react";
|
||||
import { checkUserOwnsAssistant } from "@/lib/assistants/checkOwnership";
|
||||
import { Dialog, DialogContent } from "@/components/ui/dialog";
|
||||
import { Modal } from "@/components/Modal";
|
||||
|
||||
export const AssistantBadgeSelector = ({
|
||||
text,
|
||||
@@ -24,8 +23,8 @@ export const AssistantBadgeSelector = ({
|
||||
className={`
|
||||
select-none ${
|
||||
selected
|
||||
? "bg-neutral-900 text-white"
|
||||
: "bg-transparent text-neutral-900"
|
||||
? "bg-background-900 text-white"
|
||||
: "bg-transparent text-text-900"
|
||||
} w-12 h-5 text-center px-1 py-0.5 rounded-lg cursor-pointer text-[12px] font-normal leading-[10px] border border-black justify-center items-center gap-1 inline-flex`}
|
||||
onClick={toggleFilter}
|
||||
>
|
||||
@@ -117,9 +116,9 @@ export function AssistantModal({
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 bg-neutral-950/80 bg-opacity-50 flex items-center justify-center z-50">
|
||||
<div
|
||||
className="p-0 max-w-4xl overflow-hidden max-h-[80vh] w-[95%] bg-background rounded-md shadow-2xl transform transition-all duration-300 ease-in-out relative w-11/12 max-w-4xl pt-10 pb-10 px-10 overflow-hidden flex flex-col"
|
||||
<Dialog open={true} onOpenChange={(open) => !open && hideModal()}>
|
||||
<DialogContent
|
||||
className="p-0 max-h-[80vh] max-w-none w-[95%] bg-background rounded-sm shadow-2xl transform transition-all duration-300 ease-in-out relative w-11/12 max-w-4xl pt-10 pb-10 px-10 flex flex-col max-w-4xl"
|
||||
style={{
|
||||
position: "fixed",
|
||||
top: "10vh",
|
||||
@@ -132,11 +131,11 @@ export function AssistantModal({
|
||||
<div className="flex flex-col sticky top-0 z-10">
|
||||
<div className="flex px-2 justify-between items-center gap-x-2 mb-0">
|
||||
<div className="h-12 w-full rounded-lg flex-col justify-center items-start gap-2.5 inline-flex">
|
||||
<div className="h-12 rounded-md w-full shadow-[0px_0px_2px_0px_rgba(0,0,0,0.25)] border border-[#dcdad4] flex items-center px-3">
|
||||
<div className="h-12 rounded-md w-full shadow-[0px_0px_2px_0px_rgba(0,0,0,0.25)] border border-background-300 flex items-center px-3">
|
||||
{!isSearchFocused && (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="h-5 w-5 text-gray-400"
|
||||
className="h-5 w-5 text-text-400"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
@@ -161,15 +160,15 @@ export function AssistantModal({
|
||||
</div>
|
||||
<button
|
||||
onClick={() => router.push("/assistants/new")}
|
||||
className="h-10 cursor-pointer px-6 py-3 bg-black rounded-md border border-black justify-center items-center gap-2.5 inline-flex"
|
||||
className="h-10 cursor-pointer px-6 py-3 bg-background-800 hover:bg-black rounded-md border border-black justify-center items-center gap-2.5 inline-flex"
|
||||
>
|
||||
<div className="text-[#fffcf4] text-lg font-normal leading-normal">
|
||||
<div className="text-text-50 text-lg font-normal leading-normal">
|
||||
Create
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<div className="px-2 flex py-4 items-center gap-x-2 flex-wrap">
|
||||
<FilterIcon size={16} />
|
||||
<FilterIcon className="text-text-800" size={16} />
|
||||
<AssistantBadgeSelector
|
||||
text="Pinned"
|
||||
selected={assistantFilters[AssistantFilter.Pinned]}
|
||||
@@ -198,15 +197,15 @@ export function AssistantModal({
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div className="w-full border-t border-neutral-200" />
|
||||
<div className="w-full border-t border-background-200" />
|
||||
</div>
|
||||
|
||||
<div className="flex-grow overflow-y-auto">
|
||||
<h2 className="text-2xl font-semibold text-gray-800 mb-2 px-4 py-2">
|
||||
<h2 className="text-2xl font-semibold text-text-800 mb-2 px-4 py-2">
|
||||
Featured Assistants
|
||||
</h2>
|
||||
|
||||
<div className="w-full px-2 pb-2 grid grid-cols-1 md:grid-cols-2 gap-x-6 gap-y-6">
|
||||
<div className="w-full px-2 pb-10 grid grid-cols-1 md:grid-cols-2 gap-x-6 gap-y-6">
|
||||
{featuredAssistants.length > 0 ? (
|
||||
featuredAssistants.map((assistant, index) => (
|
||||
<div key={index}>
|
||||
@@ -220,7 +219,7 @@ export function AssistantModal({
|
||||
</div>
|
||||
))
|
||||
) : (
|
||||
<div className="col-span-2 text-center text-gray-500">
|
||||
<div className="col-span-2 text-center text-text-500">
|
||||
No featured assistants match filters
|
||||
</div>
|
||||
)}
|
||||
@@ -228,7 +227,7 @@ export function AssistantModal({
|
||||
|
||||
{allAssistants && allAssistants.length > 0 && (
|
||||
<>
|
||||
<h2 className="text-2xl font-semibold text-gray-800 mt-4 mb-2 px-4 py-2">
|
||||
<h2 className="text-2xl font-semibold text-text-800 mt-4 mb-2 px-4 py-2">
|
||||
All Assistants
|
||||
</h2>
|
||||
|
||||
@@ -253,8 +252,8 @@ export function AssistantModal({
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
export default AssistantModal;
|
||||
|
||||
@@ -195,7 +195,7 @@ export function UserDropdown({
|
||||
) : hideUserDropdown ? (
|
||||
<DropdownOption
|
||||
onClick={() => router.push("/auth/login")}
|
||||
icon={<UserIcon className="h-5w-5 my-auto " />}
|
||||
icon={<UserIcon className="h-5 w-5 my-auto " />}
|
||||
label="Log In"
|
||||
/>
|
||||
) : (
|
||||
@@ -208,14 +208,14 @@ export function UserDropdown({
|
||||
item.svg_logo ? (
|
||||
<div
|
||||
className="
|
||||
h-4
|
||||
w-4
|
||||
my-auto
|
||||
overflow-hidden
|
||||
flex
|
||||
items-center
|
||||
justify-center
|
||||
"
|
||||
h-4
|
||||
w-4
|
||||
my-auto
|
||||
overflow-hidden
|
||||
flex
|
||||
items-center
|
||||
justify-center
|
||||
"
|
||||
aria-label={item.title}
|
||||
>
|
||||
<svg
|
||||
|
||||
@@ -62,7 +62,7 @@ export function Popover({
|
||||
<RadixPopover.Portal>
|
||||
<RadixPopover.Content
|
||||
className={`
|
||||
PopoverContent z-[100]
|
||||
PopoverContent z-50
|
||||
${contentClassName}
|
||||
${matchWidth ? " PopoverContentMatchWidth" : ""}
|
||||
`}
|
||||
|
||||
@@ -647,11 +647,11 @@ export const useUserGroups = (): {
|
||||
|
||||
const MODEL_DISPLAY_NAMES: { [key: string]: string } = {
|
||||
// OpenAI models
|
||||
"o1-2025-12-17": "o1 (December 2025)",
|
||||
"o3-mini": "o3 Mini",
|
||||
"o1-mini": "o1 Mini",
|
||||
"o1-preview": "o1 Preview",
|
||||
o1: "o1",
|
||||
"o1-2025-12-17": "O1 (December 2025)",
|
||||
"o3-mini": "O3 Mini",
|
||||
"o1-mini": "O1 Mini",
|
||||
"o1-preview": "O1 Preview",
|
||||
o1: "O1",
|
||||
"gpt-4": "GPT 4",
|
||||
"gpt-4o": "GPT 4o",
|
||||
"gpt-4o-2024-08-06": "GPT 4o (Structured Outputs)",
|
||||
@@ -753,7 +753,14 @@ export function getDisplayNameForModel(modelName: string): string {
|
||||
}
|
||||
|
||||
export const defaultModelsByProvider: { [name: string]: string[] } = {
|
||||
openai: ["gpt-4", "gpt-4o", "gpt-4o-mini", "o3-mini", "o1-mini", "o1"],
|
||||
openai: [
|
||||
"gpt-4",
|
||||
"gpt-4o",
|
||||
"gpt-4o-mini",
|
||||
"o3-mini",
|
||||
"o1-mini",
|
||||
"o1-preview",
|
||||
],
|
||||
bedrock: [
|
||||
"meta.llama3-1-70b-instruct-v1:0",
|
||||
"meta.llama3-1-8b-instruct-v1:0",
|
||||
|
||||
Reference in New Issue
Block a user