|
|
|
@@ -6,10 +6,10 @@ from urllib.parse import quote
|
|
|
|
|
from uuid import UUID
|
|
|
|
|
|
|
|
|
|
from ag_ui.core import RunAgentInput
|
|
|
|
|
from fastapi import HTTPException
|
|
|
|
|
import pytest
|
|
|
|
|
|
|
|
|
|
import v1.agent.service as agent_service_module
|
|
|
|
|
from core.http.errors import ApiProblemError
|
|
|
|
|
from core.auth.models import CurrentUser
|
|
|
|
|
from core.config.settings import config
|
|
|
|
|
from schemas.domain.chat_message import AgentChatMessageMetadata
|
|
|
|
@@ -25,7 +25,7 @@ class _FakeRepository:
|
|
|
|
|
async def get_session_owner(self, *, session_id: str) -> str:
|
|
|
|
|
if session_id == "00000000-0000-0000-0000-000000000001":
|
|
|
|
|
return "00000000-0000-0000-0000-000000000001"
|
|
|
|
|
raise HTTPException(status_code=404, detail="Session not found")
|
|
|
|
|
raise ApiProblemError(status_code=404, detail="Session not found")
|
|
|
|
|
|
|
|
|
|
async def create_session_for_user(
|
|
|
|
|
self, *, user_id: str, session_id: str | None = None
|
|
|
|
@@ -92,7 +92,7 @@ class _FakeRepository:
|
|
|
|
|
"timeout_seconds": 30,
|
|
|
|
|
"visibility_consumer_bit": bit,
|
|
|
|
|
"context_messages": {"mode": "number", "count": 20},
|
|
|
|
|
"enabled_tools": [],
|
|
|
|
|
"enabled_skills": [],
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -201,7 +201,7 @@ def _build_run_input(*, urls: list[str], runtime_mode: str = "chat") -> RunAgent
|
|
|
|
|
@pytest.mark.asyncio
|
|
|
|
|
async def test_enqueue_run_rejects_non_project_host_signed_url(monkeypatch) -> None:
|
|
|
|
|
monkeypatch.setattr(
|
|
|
|
|
agent_service_module.config.storage, "bucket", "agent-test-bucket"
|
|
|
|
|
agent_service_module.config.storage.attachment, "bucket", "agent-test-bucket"
|
|
|
|
|
)
|
|
|
|
|
service = AgentService(
|
|
|
|
|
repository=_FakeRepository(),
|
|
|
|
@@ -215,11 +215,11 @@ async def test_enqueue_run_rejects_non_project_host_signed_url(monkeypatch) -> N
|
|
|
|
|
]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
with pytest.raises(HTTPException) as exc_info:
|
|
|
|
|
with pytest.raises(ApiProblemError) 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 == "INVALID_BINARY_URL_HOST"
|
|
|
|
|
assert exc_info.value.detail == "Invalid binary url host"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
|
|
@@ -227,7 +227,7 @@ async def test_enqueue_run_persists_attachment_and_queue_without_user_token(
|
|
|
|
|
monkeypatch,
|
|
|
|
|
) -> None:
|
|
|
|
|
monkeypatch.setattr(
|
|
|
|
|
agent_service_module.config.storage, "bucket", "agent-test-bucket"
|
|
|
|
|
agent_service_module.config.storage.attachment, "bucket", "agent-test-bucket"
|
|
|
|
|
)
|
|
|
|
|
repository = _FakeRepository()
|
|
|
|
|
queue = _FakeQueue()
|
|
|
|
@@ -274,7 +274,7 @@ async def test_enqueue_run_persists_attachment_and_queue_without_user_token(
|
|
|
|
|
@pytest.mark.asyncio
|
|
|
|
|
async def test_enqueue_run_rejects_unknown_agent_type(monkeypatch) -> None:
|
|
|
|
|
monkeypatch.setattr(
|
|
|
|
|
agent_service_module.config.storage, "bucket", "agent-test-bucket"
|
|
|
|
|
agent_service_module.config.storage.attachment, "bucket", "agent-test-bucket"
|
|
|
|
|
)
|
|
|
|
|
service = AgentService(
|
|
|
|
|
repository=_FakeRepository(),
|
|
|
|
@@ -294,7 +294,7 @@ async def test_enqueue_run_rejects_unknown_agent_type(monkeypatch) -> None:
|
|
|
|
|
runtime_mode="planner",
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
with pytest.raises(HTTPException) as exc_info:
|
|
|
|
|
with pytest.raises(ApiProblemError) as exc_info:
|
|
|
|
|
await service.enqueue_run(run_input=run_input, current_user=_user())
|
|
|
|
|
|
|
|
|
|
assert exc_info.value.status_code == 422
|
|
|
|
@@ -303,7 +303,7 @@ async def test_enqueue_run_rejects_unknown_agent_type(monkeypatch) -> None:
|
|
|
|
|
@pytest.mark.asyncio
|
|
|
|
|
async def test_enqueue_run_rejects_invalid_runtime_mode(monkeypatch) -> None:
|
|
|
|
|
monkeypatch.setattr(
|
|
|
|
|
agent_service_module.config.storage, "bucket", "agent-test-bucket"
|
|
|
|
|
agent_service_module.config.storage.attachment, "bucket", "agent-test-bucket"
|
|
|
|
|
)
|
|
|
|
|
repository = _FakeRepository()
|
|
|
|
|
service = AgentService(
|
|
|
|
@@ -314,7 +314,7 @@ async def test_enqueue_run_rejects_invalid_runtime_mode(monkeypatch) -> None:
|
|
|
|
|
)
|
|
|
|
|
run_input = _build_run_input(urls=[], runtime_mode="planner")
|
|
|
|
|
|
|
|
|
|
with pytest.raises(HTTPException) as exc_info:
|
|
|
|
|
with pytest.raises(ApiProblemError) as exc_info:
|
|
|
|
|
await service.enqueue_run(run_input=run_input, current_user=_user())
|
|
|
|
|
|
|
|
|
|
assert exc_info.value.status_code == 422
|
|
|
|
@@ -324,7 +324,7 @@ async def test_enqueue_run_rejects_invalid_runtime_mode(monkeypatch) -> None:
|
|
|
|
|
@pytest.mark.asyncio
|
|
|
|
|
async def test_create_attachment_signed_url_returns_url(monkeypatch) -> None:
|
|
|
|
|
monkeypatch.setattr(
|
|
|
|
|
agent_service_module.config.storage, "bucket", "agent-test-bucket"
|
|
|
|
|
agent_service_module.config.storage.attachment, "bucket", "agent-test-bucket"
|
|
|
|
|
)
|
|
|
|
|
service = AgentService(
|
|
|
|
|
repository=_FakeRepository(),
|
|
|
|
@@ -349,7 +349,7 @@ async def test_create_attachment_signed_url_rejects_out_of_scope_path(
|
|
|
|
|
monkeypatch,
|
|
|
|
|
) -> None:
|
|
|
|
|
monkeypatch.setattr(
|
|
|
|
|
agent_service_module.config.storage, "bucket", "agent-test-bucket"
|
|
|
|
|
agent_service_module.config.storage.attachment, "bucket", "agent-test-bucket"
|
|
|
|
|
)
|
|
|
|
|
service = AgentService(
|
|
|
|
|
repository=_FakeRepository(),
|
|
|
|
@@ -358,7 +358,7 @@ async def test_create_attachment_signed_url_rejects_out_of_scope_path(
|
|
|
|
|
attachment_storage=_FakeAttachmentStorage(),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
with pytest.raises(HTTPException) as exc_info:
|
|
|
|
|
with pytest.raises(ApiProblemError) as exc_info:
|
|
|
|
|
await service.create_attachment_signed_url(
|
|
|
|
|
bucket="agent-test-bucket",
|
|
|
|
|
path="agent-inputs/other-user/thread-x/uploads/a.png",
|
|
|
|
@@ -371,7 +371,7 @@ async def test_create_attachment_signed_url_rejects_out_of_scope_path(
|
|
|
|
|
@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"
|
|
|
|
|
agent_service_module.config.storage.attachment, "bucket", "agent-test-bucket"
|
|
|
|
|
)
|
|
|
|
|
service = AgentService(
|
|
|
|
|
repository=_FakeRepository(),
|
|
|
|
@@ -405,7 +405,7 @@ async def test_enqueue_run_rejects_too_many_attachments(monkeypatch) -> None:
|
|
|
|
|
]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
with pytest.raises(HTTPException) as exc_info:
|
|
|
|
|
with pytest.raises(ApiProblemError) as exc_info:
|
|
|
|
|
await service.enqueue_run(run_input=run_input, current_user=_user())
|
|
|
|
|
|
|
|
|
|
assert exc_info.value.status_code == 422
|
|
|
|
@@ -461,8 +461,6 @@ async def test_get_history_snapshot_filters_out_tool_messages() -> None:
|
|
|
|
|
"agent_output": {
|
|
|
|
|
"status": "success",
|
|
|
|
|
"answer": "今天共有 3 条日程。",
|
|
|
|
|
"key_points": [],
|
|
|
|
|
"result_type": "summary",
|
|
|
|
|
"suggested_actions": [],
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
@@ -529,7 +527,7 @@ async def test_cancel_run_rejects_non_owner() -> None:
|
|
|
|
|
phone="+8613812340000",
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
with pytest.raises(HTTPException) as exc_info:
|
|
|
|
|
with pytest.raises(ApiProblemError) as exc_info:
|
|
|
|
|
await service.cancel_run(
|
|
|
|
|
thread_id="00000000-0000-0000-0000-000000000001",
|
|
|
|
|
run_id="run-cancel-2",
|
|
|
|
|