fix: resolve chat model selection and session display issues

- Add nullable_fields support to ObjectModel base class
- Configure ChatSession to allow model_override to be cleared to null
- Fix JSX conditional that rendered "0" when message_count was 0
- Display model name instead of raw ID in session manager

Fixes issues:
1. Switching to default model now persists correctly
2. Session list shows human-readable model names
3. Sessions with 0 messages no longer show "0" badge
This commit is contained in:
LUIS NOVO 2025-12-19 16:47:34 -03:00
parent 33b8f7a2b8
commit e11f0a4db8
3 changed files with 26 additions and 9 deletions

View file

@ -1,16 +1,16 @@
'use client'
import { useState } from 'react'
import { useState, useMemo } from 'react'
import { Button } from '@/components/ui/button'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Input } from '@/components/ui/input'
import { ScrollArea } from '@/components/ui/scroll-area'
import { Badge } from '@/components/ui/badge'
import {
MessageSquare,
Plus,
Trash2,
Edit2,
import {
MessageSquare,
Plus,
Trash2,
Edit2,
Check,
X,
Clock
@ -27,6 +27,7 @@ import {
AlertDialogTitle,
} from '@/components/ui/alert-dialog'
import { BaseChatSession } from '@/lib/types/api'
import { useModels } from '@/lib/hooks/use-models'
interface SessionManagerProps {
sessions: BaseChatSession[]
@ -53,6 +54,16 @@ export function SessionManager({
const [editTitle, setEditTitle] = useState('')
const [deleteConfirmId, setDeleteConfirmId] = useState<string | null>(null)
const { data: models } = useModels()
// Helper to get model name from ID
const getModelName = useMemo(() => {
return (modelId: string) => {
const model = models?.find(m => m.id === modelId)
return model?.name || 'Custom Model'
}
}, [models])
const handleCreateSession = () => {
if (newSessionTitle.trim()) {
onCreateSession(newSessionTitle.trim())
@ -211,14 +222,14 @@ export function SessionManager({
<Clock className="h-3 w-3" />
{formatDistanceToNow(new Date(session.created), { addSuffix: true })}
</div>
{session.message_count && session.message_count > 0 && (
{session.message_count != null && session.message_count > 0 && (
<Badge variant="secondary" className="mt-2 text-xs">
{session.message_count} messages
</Badge>
)}
{session.model_override && (
<Badge variant="outline" className="mt-2 ml-2 text-xs">
{session.model_override}
{getModelName(session.model_override)}
</Badge>
)}
</>

View file

@ -25,6 +25,7 @@ T = TypeVar("T", bound="ObjectModel")
class ObjectModel(BaseModel):
id: Optional[str] = None
table_name: ClassVar[str] = ""
nullable_fields: ClassVar[set[str]] = set() # Fields that can be saved as None
created: Optional[datetime] = None
updated: Optional[datetime] = None
@ -167,7 +168,11 @@ class ObjectModel(BaseModel):
def _prepare_save_data(self) -> Dict[str, Any]:
data = self.model_dump()
return {key: value for key, value in data.items() if value is not None}
return {
key: value
for key, value in data.items()
if value is not None or key in self.__class__.nullable_fields
}
async def delete(self) -> bool:
if self.id is None:

View file

@ -389,6 +389,7 @@ class Note(ObjectModel):
class ChatSession(ObjectModel):
table_name: ClassVar[str] = "chat_session"
nullable_fields: ClassVar[set[str]] = {"model_override"}
title: Optional[str] = None
model_override: Optional[str] = None