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
+64 -10
View File
@@ -126,7 +126,10 @@ def _user() -> CurrentUser:
)
def _build_run_input(*, url: str) -> RunAgentInput:
def _build_run_input(*, urls: list[str]) -> RunAgentInput:
content: list[dict[str, str]] = [{"type": "text", "text": "hello"}]
for url in urls:
content.append({"type": "binary", "mimeType": "image/png", "url": url})
return RunAgentInput.model_validate(
{
"threadId": "00000000-0000-0000-0000-000000000001",
@@ -136,10 +139,7 @@ def _build_run_input(*, url: str) -> RunAgentInput:
{
"id": "u1",
"role": "user",
"content": [
{"type": "text", "text": "hello"},
{"type": "binary", "mimeType": "image/png", "url": url},
],
"content": content,
}
],
"tools": [],
@@ -161,7 +161,9 @@ async def test_enqueue_run_rejects_non_project_host_signed_url(monkeypatch) -> N
attachment_storage=_FakeAttachmentStorage(),
)
run_input = _build_run_input(
url="https://evil.example.com/storage/v1/object/sign/agent-test-bucket/a.png?token=1"
urls=[
"https://evil.example.com/storage/v1/object/sign/agent-test-bucket/a.png?token=1"
]
)
with pytest.raises(HTTPException) as exc_info:
@@ -191,8 +193,15 @@ async def test_enqueue_run_persists_attachment_and_queue_without_user_token(
"agent-inputs/00000000-0000-0000-0000-000000000001/"
"00000000-0000-0000-0000-000000000001/uploads/a.png"
)
safe_path_two = quote(
"agent-inputs/00000000-0000-0000-0000-000000000001/"
"00000000-0000-0000-0000-000000000001/uploads/b.png"
)
run_input = _build_run_input(
url=f"{base_url}/storage/v1/object/sign/agent-test-bucket/{safe_path}?token=1"
urls=[
f"{base_url}/storage/v1/object/sign/agent-test-bucket/{safe_path}?token=1",
f"{base_url}/storage/v1/object/sign/agent-test-bucket/{safe_path_two}?token=1",
]
)
accepted = await service.enqueue_run(run_input=run_input, current_user=_user())
@@ -201,9 +210,10 @@ async def test_enqueue_run_persists_attachment_and_queue_without_user_token(
persisted = repository.persisted_user_messages[0]
metadata = cast(AgentChatMessageMetadata | None, persisted["metadata"])
assert metadata is not None
attachment = metadata.user_message_attachments
assert attachment is not None
assert attachment.bucket == "agent-test-bucket"
attachments = metadata.user_message_attachments
assert attachments is not None
assert len(attachments) == 2
assert attachments[0].bucket == "agent-test-bucket"
command = queue.commands[0]
assert "user_token" not in command
run_input = command["run_input"]
@@ -257,3 +267,47 @@ async def test_create_attachment_signed_url_rejects_out_of_scope_path(
)
assert exc_info.value.status_code == 422
@pytest.mark.asyncio
async def test_enqueue_run_rejects_too_many_attachments(monkeypatch) -> None:
monkeypatch.setattr(
agent_service_module.config.storage, "bucket", "agent-test-bucket"
)
service = AgentService(
repository=_FakeRepository(),
queue=_FakeQueue(),
stream=_FakeStream(),
attachment_storage=_FakeAttachmentStorage(),
)
base_url = str(config.supabase.url).rstrip("/")
safe_paths = [
quote(
"agent-inputs/00000000-0000-0000-0000-000000000001/"
"00000000-0000-0000-0000-000000000001/uploads/a.png"
),
quote(
"agent-inputs/00000000-0000-0000-0000-000000000001/"
"00000000-0000-0000-0000-000000000001/uploads/b.png"
),
quote(
"agent-inputs/00000000-0000-0000-0000-000000000001/"
"00000000-0000-0000-0000-000000000001/uploads/c.png"
),
quote(
"agent-inputs/00000000-0000-0000-0000-000000000001/"
"00000000-0000-0000-0000-000000000001/uploads/d.png"
),
]
run_input = _build_run_input(
urls=[
f"{base_url}/storage/v1/object/sign/agent-test-bucket/{safe_path}?token=1"
for safe_path in safe_paths
]
)
with pytest.raises(HTTPException) as exc_info:
await service.enqueue_run(run_input=run_input, current_user=_user())
assert exc_info.value.status_code == 422
assert exc_info.value.detail == "Too many attachments"