fix(agent): save conversations to DB, fix Test button hang, wire hasNext/search
## Root cause: _save_conversation() dead code + missing message persistence
### Backend: Conversation persistence (3 critical bugs)
- **app.py**: Replaced early with so _save_conversation() executes
after successful stream — was dead code on normal path
- **app.py**: Added _save_conversation call in HITL resume path (confirm/deny)
- **app.py**: Added broad that saves conversation (at least user
message) before re-raising on LLM errors (APIConnectionError etc.)
- **app.py**: _save_conversation now passes user_id from JWT (not hardcoded UUID)
and includes messages[] in payload
- **agent_conversations.py**: save_conversation endpoint now processes body.messages
and creates AgentMessage records (idempotent by msg id)
### Frontend: Agent chat sidebar wiring
- AgentChatModel.svelte.ts: added public derived getter
- AgentChatModel.svelte.ts: added method
- agent/+page.svelte: wired hasNext={model.conversationsHasNext} (was hardcoded false)
- agent/+page.svelte: wired onsearch to model.searchConversations (was no-op)
### Frontend: LLM Provider Test button hang fix
- ProviderConfig.svelte: resetForm/handleEdit now reset isTesting=false, isProbing=false
- ProviderConfig.svelte: Cancel button calls abortPendingRequests()
- ProviderConfig.svelte: Added AbortController lifecycle — cancels in-flight test/fetch
requests on modal close or provider switch, preventing stale disabled buttons
- provider_config.integration.test.ts: added 6 abort/reset invariant tests
This commit is contained in:
@@ -2,12 +2,14 @@
|
||||
# #region AgentChat.Api.Conversations [C:3] [TYPE Module] [SEMANTICS agent-chat,api,rest]
|
||||
# @defgroup AgentChat REST routes for conversation lifecycle.
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from ...core.database import get_db
|
||||
from ...dependencies import get_current_user
|
||||
from src.models.agent import AgentConversation
|
||||
from src.models.agent import AgentConversation, AgentMessage
|
||||
from src.schemas.agent import (
|
||||
ConversationItem,
|
||||
ConversationListResponse,
|
||||
@@ -57,12 +59,10 @@ async def list_conversations(
|
||||
|
||||
# #region AgentChat.Api.SaveConversation [C:3] [TYPE Function] [SEMANTICS agent-chat,api,save]
|
||||
# @ingroup AgentChat
|
||||
# @BRIEF POST /api/assistant/conversations/save — create or update conversation + messages.
|
||||
# @BRIEF POST /api/agent/conversations/save — create or update conversation + messages.
|
||||
# @PRE Service JWT with role=agent authenticates the Gradio container.
|
||||
# @POST Conversation saved (upsert by conversation_id). Existing messages appended.
|
||||
# @POST Conversation saved (upsert by conversation_id). Messages appended.
|
||||
# @SIDE_EFFECT Writes to AgentConversation and AgentMessage tables.
|
||||
from src.schemas.agent import SaveConversationRequest
|
||||
from datetime import datetime
|
||||
|
||||
@agent_router.post("/conversations/save")
|
||||
async def save_conversation(
|
||||
@@ -86,6 +86,30 @@ async def save_conversation(
|
||||
conv.updated_at = datetime.utcnow()
|
||||
if body.title:
|
||||
conv.title = body.title
|
||||
|
||||
# Save messages from payload
|
||||
if body.messages:
|
||||
for msg_data in body.messages:
|
||||
msg_id = msg_data.get("id", "")
|
||||
if not msg_id:
|
||||
continue
|
||||
# Check if message already exists (idempotent)
|
||||
existing = db.query(AgentMessage).filter(
|
||||
AgentMessage.id == msg_id,
|
||||
).first()
|
||||
if not existing:
|
||||
msg = AgentMessage(
|
||||
id=msg_id,
|
||||
conversation_id=body.conversation_id,
|
||||
role=msg_data.get("role", "user"),
|
||||
text=msg_data.get("text", ""),
|
||||
tool_calls=msg_data.get("tool_calls"),
|
||||
attachments=msg_data.get("attachments"),
|
||||
created_at=datetime.utcnow(),
|
||||
)
|
||||
db.add(msg)
|
||||
db.flush()
|
||||
|
||||
db.commit()
|
||||
return {"saved": True, "conversation_id": body.conversation_id}
|
||||
# #endregion AgentChat.Api.SaveConversation
|
||||
|
||||
Reference in New Issue
Block a user