添加获取历史对话数据的接口
This commit is contained in:
+14
-50
@@ -1,9 +1,14 @@
|
||||
import asyncio
|
||||
from collections.abc import AsyncGenerator
|
||||
from datetime import UTC, datetime
|
||||
from openai import APIError, AsyncOpenAI
|
||||
|
||||
from models import Message, SendMessageResponse, Session, TokenUsage
|
||||
from models import (
|
||||
Message,
|
||||
SendMessageResponse,
|
||||
Session,
|
||||
SessionHistoryResponse,
|
||||
TokenUsage,
|
||||
)
|
||||
from storage import JsonSessionStorage
|
||||
|
||||
|
||||
@@ -36,7 +41,6 @@ class ChatService:
|
||||
completion = await self.client.chat.completions.create(
|
||||
model=self.model,
|
||||
messages=api_messages, # type: ignore[arg-type]
|
||||
stream=False,
|
||||
extra_body={"thinking": {"type": "disabled"}},
|
||||
)
|
||||
assistant_content = completion.choices[0].message.content
|
||||
@@ -57,57 +61,17 @@ class ChatService:
|
||||
usage=usage,
|
||||
)
|
||||
|
||||
async def ensure_session_exists(self, session_id: str) -> None:
|
||||
await self.storage.read(session_id)
|
||||
|
||||
async def generate_response_stream(
|
||||
self, session_id: str, content: str
|
||||
) -> AsyncGenerator[dict[str, object], None]:
|
||||
async def get_session_history(self, session_id: str) -> SessionHistoryResponse:
|
||||
lock = self._locks.setdefault(session_id, asyncio.Lock())
|
||||
async with lock:
|
||||
user_created_at = datetime.now(UTC)
|
||||
session = await self.storage.read(session_id)
|
||||
api_messages = self._build_api_messages(session, content)
|
||||
|
||||
try:
|
||||
stream = await self.client.chat.completions.create(
|
||||
model=self.model,
|
||||
messages=api_messages, # type: ignore[arg-type]
|
||||
stream=True,
|
||||
stream_options={"include_usage": True},
|
||||
extra_body={"thinking": {"type": "disabled"}},
|
||||
)
|
||||
parts: list[str] = []
|
||||
usage: TokenUsage | None = None
|
||||
|
||||
try:
|
||||
async for chunk in stream:
|
||||
chunk_usage = getattr(chunk, "usage", None)
|
||||
if chunk_usage is not None:
|
||||
usage = self._parse_usage(chunk_usage)
|
||||
|
||||
for choice in chunk.choices:
|
||||
delta = choice.delta.content
|
||||
if delta:
|
||||
parts.append(delta)
|
||||
yield {"type": "delta", "content": delta}
|
||||
finally:
|
||||
await stream.close()
|
||||
except (APIError, AttributeError, TypeError) as exc:
|
||||
raise ChatProviderError("Upstream chat stream failed") from exc
|
||||
|
||||
assistant_content = "".join(parts)
|
||||
if not assistant_content:
|
||||
raise ChatProviderError("Upstream chat provider returned an empty response")
|
||||
|
||||
assistant_message = await self._save_exchange(
|
||||
session, content, user_created_at, assistant_content
|
||||
return SessionHistoryResponse(
|
||||
session_id=session.session_id,
|
||||
system_prompt=session.system_prompt,
|
||||
created_at=session.created_at,
|
||||
updated_at=session.updated_at,
|
||||
messages=session.messages,
|
||||
)
|
||||
yield {
|
||||
"type": "done",
|
||||
"message": assistant_message.model_dump(mode="json"),
|
||||
"usage": usage.model_dump() if usage is not None else None,
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def _build_api_messages(
|
||||
|
||||
Reference in New Issue
Block a user