feat: 优化 Agent 运行时与聊天设置体验

This commit is contained in:
qzl
2026-03-16 18:32:09 +08:00
parent 3f79cf0df7
commit 5a34616287
41 changed files with 2603 additions and 1263 deletions
+38 -18
View File
@@ -19,7 +19,8 @@ from core.config.settings import config
from core.logging import get_logger
from schemas.messages.chat_message import (
AgentChatMessageMetadata,
UserMessageAttachments,
UserMessageAttachment,
extract_user_message_attachments,
)
from v1.agent.schemas import HistorySnapshotResponse
@@ -27,6 +28,7 @@ logger = get_logger(__name__)
_ALLOWED_ATTACHMENT_MIME_TYPES = {"image/png", "image/jpeg", "image/webp"}
_MAX_ATTACHMENT_BYTES = 5 * 1024 * 1024
_MAX_TOTAL_ATTACHMENT_BYTES = 12 * 1024 * 1024
_MAX_ATTACHMENTS_PER_MESSAGE = 3
@dataclass(frozen=True)
@@ -230,7 +232,7 @@ class AgentService:
) -> tuple[str, AgentChatMessageMetadata | None]:
text, content_blocks = extract_latest_user_payload(run_input)
user_attachments: UserMessageAttachments | None = None
user_attachments: list[UserMessageAttachment] = []
for block in content_blocks:
if not isinstance(block, dict):
continue
@@ -257,12 +259,15 @@ class AgentService:
thread_id=run_input.thread_id,
current_user=current_user,
)
user_attachments = UserMessageAttachments(
bucket=bucket,
path=path,
mime_type=mime_type,
user_attachments.append(
UserMessageAttachment(
bucket=bucket,
path=path,
mime_type=mime_type,
)
)
break
if len(user_attachments) > _MAX_ATTACHMENTS_PER_MESSAGE:
raise HTTPException(status_code=422, detail="Too many attachments")
except HTTPException:
raise
except Exception as exc: # noqa: BLE001
@@ -270,7 +275,7 @@ class AgentService:
raise HTTPException(status_code=422, detail="Invalid signed image url")
metadata: AgentChatMessageMetadata | None = None
if user_attachments is not None:
if user_attachments:
metadata = AgentChatMessageMetadata(
run_id=run_input.run_id,
user_message_attachments=user_attachments,
@@ -438,23 +443,38 @@ class AgentService:
messages: list[HistoryMessage] = []
if day_payload:
raw_messages = day_payload.get("messages") or []
raw_messages_obj = day_payload.get("messages")
raw_messages = (
raw_messages_obj if isinstance(raw_messages_obj, list) else []
)
for msg_dict in raw_messages:
msg = AgentChatMessage.model_validate(msg_dict)
signed_url: str | None = None
if self._attachment_storage and msg.metadata:
att = msg.metadata.user_message_attachments
if att:
signed_urls: dict[str, str] = {}
attachments = extract_user_message_attachments(msg.metadata)
if self._attachment_storage and attachments:
expected_prefix = (
f"agent-inputs/{current_user.id}/{thread_id}/uploads/"
)
for attachment in attachments:
if not _is_safe_attachment_path(
attachment.path,
expected_prefix=expected_prefix,
):
continue
signed_url = await self._attachment_storage.create_signed_url(
bucket=att.bucket,
path=att.path,
bucket=attachment.bucket,
path=attachment.path,
expires_in_seconds=self._SIGNED_URL_EXPIRES_IN_SECONDS,
)
key = f"{attachment.bucket}/{attachment.path}"
signed_urls[key] = signed_url
converted = convert_message_to_history(msg, None)
if signed_url:
converted["url"] = signed_url
def _get_signed_url(payload: dict[str, str]) -> str:
key = f"{payload['bucket']}/{payload['path']}"
return signed_urls[key]
converted = convert_message_to_history(msg, _get_signed_url)
messages.append(HistoryMessage.model_validate(converted))
return HistorySnapshotResponse(