refactor: 重构聊天数据层至core并简化首页UI

This commit is contained in:
zl-q
2026-03-29 21:46:26 +08:00
parent 4db9a13bfe
commit f126d7a547
18 changed files with 568 additions and 328 deletions
+38 -16
View File
@@ -24,7 +24,6 @@ from fastapi import (
File,
Form,
Header,
HTTPException,
Query,
Request,
UploadFile,
@@ -195,16 +194,22 @@ async def stream_events(
if last_event_id is not None and (
len(last_event_id) > 32 or _LAST_EVENT_ID_RE.fullmatch(last_event_id) is None
):
raise HTTPException(
raise ApiProblemError(
status_code=422,
detail="Invalid Last-Event-ID",
detail=problem_payload(
code="AGENT_INVALID_LAST_EVENT_ID",
detail="Invalid Last-Event-ID",
),
)
sse_slot_acquired = await _acquire_sse_slot(user_id=str(current_user.id))
if not sse_slot_acquired:
raise HTTPException(
raise ApiProblemError(
status_code=429,
detail="Too many SSE connections",
detail=problem_payload(
code="AGENT_SSE_CONNECTION_LIMIT",
detail="Too many SSE connections",
),
)
async def _event_iter() -> AsyncIterator[str]:
@@ -296,14 +301,21 @@ async def upload_attachment(
) -> AttachmentUploadResponse:
payload = await file.read()
if not payload:
raise HTTPException(
raise ApiProblemError(
status_code=422,
detail="Empty attachment",
detail=problem_payload(
code="AGENT_ATTACHMENT_EMPTY",
detail="Empty attachment",
),
)
if len(payload) > _MAX_ATTACHMENT_UPLOAD_BYTES:
raise HTTPException(
raise ApiProblemError(
status_code=413,
detail="Attachment too large",
detail=problem_payload(
code="AGENT_ATTACHMENT_TOO_LARGE",
detail="Attachment too large",
params={"maxBytes": _MAX_ATTACHMENT_UPLOAD_BYTES},
),
)
attachment = await service.upload_attachment(
thread_id=thread_id,
@@ -388,9 +400,13 @@ async def transcribe(
break
total_bytes += len(chunk)
if total_bytes > _MAX_TRANSCRIBE_AUDIO_BYTES:
raise HTTPException(
raise ApiProblemError(
status_code=400,
detail="Audio file too large",
detail=problem_payload(
code="AGENT_AUDIO_TOO_LARGE",
detail="Audio file too large",
params={"maxBytes": _MAX_TRANSCRIBE_AUDIO_BYTES},
),
)
if len(header) < _WAV_HEADER_MIN_BYTES:
required = _WAV_HEADER_MIN_BYTES - len(header)
@@ -398,14 +414,20 @@ async def transcribe(
tmp_file.write(chunk)
if total_bytes == 0:
raise HTTPException(
raise ApiProblemError(
status_code=400,
detail="Empty audio file",
detail=problem_payload(
code="AGENT_AUDIO_EMPTY",
detail="Empty audio file",
),
)
if not _looks_like_wav_header(bytes(header)):
raise HTTPException(
raise ApiProblemError(
status_code=400,
detail="Unsupported audio format",
detail=problem_payload(
code="AGENT_AUDIO_UNSUPPORTED_FORMAT",
detail="Unsupported audio format",
),
)
transcript = await asr_service.transcribe_file(
@@ -414,7 +436,7 @@ async def transcribe(
return AsrTranscribeResponse(transcript=transcript)
except HTTPException:
except ApiProblemError:
raise
except RuntimeError:
raise ApiProblemError(