refactor: 重构 AgentScope 运行时模块并优化前端附件展示
This commit is contained in:
@@ -12,6 +12,7 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from core.config.settings import config
|
||||
from models.agent_chat_message import AgentChatMessage, AgentChatMessageRole
|
||||
from models.agent_chat_session import AgentChatSession
|
||||
from services.base.supabase import supabase_service
|
||||
|
||||
|
||||
class ToolResultPayloadStorage(Protocol):
|
||||
@@ -201,61 +202,6 @@ class AgentRepository:
|
||||
return None
|
||||
return str(latest_id)
|
||||
|
||||
async def get_message_attachment_reference(
|
||||
self,
|
||||
*,
|
||||
session_id: str,
|
||||
message_id: str,
|
||||
attachment_index: int,
|
||||
) -> dict[str, str] | None:
|
||||
try:
|
||||
session_uuid = UUID(session_id)
|
||||
message_uuid = UUID(message_id)
|
||||
except ValueError as exc:
|
||||
raise HTTPException(
|
||||
status_code=422, detail="Invalid message/session id"
|
||||
) from exc
|
||||
|
||||
stmt = (
|
||||
select(AgentChatMessage)
|
||||
.where(AgentChatMessage.id == message_uuid)
|
||||
.where(AgentChatMessage.session_id == session_uuid)
|
||||
.where(AgentChatMessage.deleted_at.is_(None))
|
||||
)
|
||||
message = (await self._session.execute(stmt)).scalar_one_or_none()
|
||||
if message is None:
|
||||
return None
|
||||
|
||||
metadata = (
|
||||
message.metadata_json if isinstance(message.metadata_json, dict) else {}
|
||||
)
|
||||
attachments_raw = metadata.get("attachments")
|
||||
if not isinstance(attachments_raw, list):
|
||||
return None
|
||||
if attachment_index < 0 or attachment_index >= len(attachments_raw):
|
||||
return None
|
||||
|
||||
attachment = attachments_raw[attachment_index]
|
||||
if not isinstance(attachment, dict):
|
||||
return None
|
||||
bucket = attachment.get("bucket")
|
||||
path = attachment.get("path")
|
||||
mime_type = attachment.get("mimeType")
|
||||
if (
|
||||
not isinstance(bucket, str)
|
||||
or not bucket
|
||||
or not isinstance(path, str)
|
||||
or not path
|
||||
or not isinstance(mime_type, str)
|
||||
or not mime_type
|
||||
):
|
||||
return None
|
||||
return {
|
||||
"bucket": bucket,
|
||||
"path": path,
|
||||
"mimeType": mime_type,
|
||||
}
|
||||
|
||||
async def _to_snapshot_message(
|
||||
self, message: AgentChatMessage
|
||||
) -> dict[str, object]:
|
||||
@@ -350,29 +296,45 @@ class AgentRepository:
|
||||
payload["content"] = display_content
|
||||
else:
|
||||
payload["content"] = message.content
|
||||
metadata = message.metadata_json or {}
|
||||
attachments = (
|
||||
metadata.get("attachments") if isinstance(metadata, dict) else None
|
||||
)
|
||||
if isinstance(attachments, list):
|
||||
rendered: list[dict[str, object]] = []
|
||||
for index, item in enumerate(attachments):
|
||||
if not isinstance(item, dict):
|
||||
continue
|
||||
mime_type = item.get("mimeType")
|
||||
if not isinstance(mime_type, str) or not mime_type:
|
||||
continue
|
||||
rendered.append(
|
||||
{
|
||||
"mimeType": mime_type,
|
||||
"previewPath": (
|
||||
f"/api/v1/agent/runs/{message.session_id}/attachments/"
|
||||
f"{message.id}/{index}"
|
||||
),
|
||||
}
|
||||
)
|
||||
if rendered:
|
||||
payload["attachments"] = rendered
|
||||
|
||||
if role == AgentChatMessageRole.USER.value:
|
||||
metadata = message.metadata_json or {}
|
||||
user_attachments = metadata.get("user_message_attachments")
|
||||
if isinstance(user_attachments, dict):
|
||||
bucket = user_attachments.get("bucket")
|
||||
path = user_attachments.get("path")
|
||||
mime_type = user_attachments.get("mime_type")
|
||||
if (
|
||||
isinstance(bucket, str)
|
||||
and isinstance(path, str)
|
||||
and isinstance(mime_type, str)
|
||||
):
|
||||
try:
|
||||
signed_url = await supabase_service.create_signed_url(
|
||||
bucket=bucket,
|
||||
path=path,
|
||||
expires_in_seconds=3600,
|
||||
)
|
||||
attachment_block = {
|
||||
"type": "binary",
|
||||
"mimeType": mime_type,
|
||||
"url": signed_url,
|
||||
}
|
||||
existing_content = message.content
|
||||
if (
|
||||
isinstance(existing_content, str)
|
||||
and existing_content.strip()
|
||||
):
|
||||
content_blocks = [
|
||||
{"type": "text", "text": existing_content}
|
||||
]
|
||||
content_blocks.append(attachment_block)
|
||||
payload["content"] = content_blocks
|
||||
else:
|
||||
payload["content"] = [attachment_block]
|
||||
except Exception: # noqa: BLE001
|
||||
pass
|
||||
|
||||
return payload
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user