Add model selection, dashboard chat input, and model warming
- Add GET /api/chat/ps and POST /api/chat/warm endpoints for hot model visibility and pre-loading - Extend PATCH /api/chat/conversations/:id to accept model in addition to title - Add ModelSelector component with hot/cold indicators from Ollama /api/ps - Add DashboardChatInput component (model selector + note picker + textarea) replacing the simple "New Chat" button on the dashboard - Add model selector dropdown to ChatView header, persisted per-conversation - Warm default model on dashboard mount via fire-and-forget background task - Configure Ollama with OLLAMA_MAX_LOADED_MODELS=2 and OLLAMA_KEEP_ALIVE=30m - Always-visible edit buttons on NoteCard/TaskCard (remove hover-only behavior) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -103,8 +103,11 @@ async def delete_conversation(user_id: int, conversation_id: int) -> bool:
|
||||
return True
|
||||
|
||||
|
||||
async def update_conversation_title(
|
||||
user_id: int, conversation_id: int, title: str
|
||||
async def update_conversation(
|
||||
user_id: int,
|
||||
conversation_id: int,
|
||||
title: str | None = None,
|
||||
model: str | None = None,
|
||||
) -> Conversation | None:
|
||||
async with async_session() as session:
|
||||
result = await session.execute(
|
||||
@@ -116,13 +119,22 @@ async def update_conversation_title(
|
||||
conv = result.scalars().first()
|
||||
if conv is None:
|
||||
return None
|
||||
conv.title = title
|
||||
if title is not None:
|
||||
conv.title = title
|
||||
if model is not None:
|
||||
conv.model = model
|
||||
conv.updated_at = datetime.now(timezone.utc)
|
||||
await session.commit()
|
||||
await session.refresh(conv)
|
||||
return conv
|
||||
|
||||
|
||||
async def update_conversation_title(
|
||||
user_id: int, conversation_id: int, title: str
|
||||
) -> Conversation | None:
|
||||
return await update_conversation(user_id, conversation_id, title=title)
|
||||
|
||||
|
||||
async def add_message(
|
||||
conversation_id: int,
|
||||
role: str,
|
||||
|
||||
@@ -80,7 +80,7 @@ async def stream_chat(
|
||||
payload: dict = {"model": model, "messages": messages, "stream": True}
|
||||
if options:
|
||||
payload["options"] = options
|
||||
async with httpx.AsyncClient(timeout=httpx.Timeout(300.0, connect=10.0)) as client:
|
||||
async with httpx.AsyncClient(timeout=httpx.Timeout(1800.0, connect=10.0, read=300.0)) as client:
|
||||
async with client.stream(
|
||||
"POST",
|
||||
f"{Config.OLLAMA_URL}/api/chat",
|
||||
@@ -100,7 +100,7 @@ async def stream_chat(
|
||||
|
||||
async def generate_completion(messages: list[dict], model: str) -> str:
|
||||
"""Non-streaming chat completion, returns full response text."""
|
||||
async with httpx.AsyncClient(timeout=httpx.Timeout(300.0, connect=10.0)) as client:
|
||||
async with httpx.AsyncClient(timeout=httpx.Timeout(1800.0, connect=10.0, read=300.0)) as client:
|
||||
resp = await client.post(
|
||||
f"{Config.OLLAMA_URL}/api/chat",
|
||||
json={"model": model, "messages": messages, "stream": False},
|
||||
|
||||
Reference in New Issue
Block a user