Files
ai-contract-platform/backend/tests/test_shared_ai_platform_client.py
T

102 lines
4.6 KiB
Python

import unittest
import httpx
from app.clients.shared_ai_platform import RemoteSharedAIPlatformClient
from shared_ai_platform_sdk.client import SharedAIPlatformClient as VendoredSharedAiPlatformClient
from shared_ai_platform_sdk.types import RequestContext, SSEEvent
class VendoredSharedAiPlatformSdkTestCase(unittest.TestCase):
def test_stream_conversation_supports_split_data_and_json_lines(self):
sse_payload = (
'data:\n'
'{"type":"delta","content":"hello"}\n\n'
'data:\n'
'{"type":"end","conversation_id":"conv-1"}\n\n'
).encode("utf-8")
def handler(request: httpx.Request) -> httpx.Response:
return httpx.Response(
200,
headers={"content-type": "text/event-stream"},
content=sse_payload,
)
transport = httpx.MockTransport(handler)
http_client = httpx.Client(base_url="http://testserver", transport=transport, timeout=30.0)
sdk = VendoredSharedAiPlatformClient(
base_url="http://testserver",
api_key="test-key",
app_id="test-app",
client=http_client,
)
try:
events = list(
sdk.stream_conversation(
RequestContext(tenant_id="tenant-1", user_id="user-1", user_role="admin"),
message="hello",
)
)
finally:
http_client.close()
self.assertEqual([event.event_type for event in events], ["delta", "end"])
self.assertEqual(events[0].payload["content"], "hello")
self.assertEqual(events[1].payload["conversation_id"], "conv-1")
class RemoteSharedAiPlatformClientStreamTestCase(unittest.TestCase):
def test_remote_stream_ignores_start_and_usage_and_maps_delta(self):
class StubSdk:
def stream_conversation(self, context, *, message, chat_context=None, provider=None, template_key=None, conversation_id=None):
yield SSEEvent(event_type="start", payload={"type": "start", "conversation_id": "conv-1"})
yield SSEEvent(event_type="delta", payload={"type": "delta", "content": "hello"})
yield SSEEvent(event_type="usage", payload={"type": "usage", "usage": {"provider_mode": "stream"}})
yield SSEEvent(event_type="sources", payload={"type": "sources", "sources": [{"title": "source", "content": "body"}]})
yield SSEEvent(event_type="end", payload={"type": "end", "conversation_id": "conv-1"})
def run_legal_review(self, context, *, title, text, contract_type=None, review_as="party_a", provider=None):
return {
"basic_info": {
"contract_type": contract_type or "采购合同",
"contract_title": title,
"party_a": "甲方",
"party_b": "乙方",
"amount": "100万元",
"term": "自2026-01-01至2026-12-31",
},
"risk_summary": {"high": 1, "medium": 0, "low": 0, "overall": "high"},
"clauses": [{"title": "付款条款", "content": "签署后5日内支付50%", "clause_type": "payment", "clause_label": "付款条款", "summary": "签署后5日内支付50%"}],
"risk_items": [{"title": "存在自动续约安排", "level": "high", "description": "需核查自动续约", "suggestion": "补充退出机制"}],
"review_opinion": "建议人工复核",
"recommendation": "manual_review",
"confidence_summary": {"provider_mode": "provider-enhanced"},
"contract_structure": {"title": title, "payment_milestones": [], "clause_relationships": [], "missing_sections": [], "clause_type_counts": {"payment": 1}},
}
client = RemoteSharedAIPlatformClient(
base_url="http://testserver",
app_id="test-app",
api_key="test-key",
timeout_seconds=30.0,
)
client.sdk = StubSdk()
current_user = {"id": "user-1", "tenant_id": "tenant-1", "role": "admin"}
chunks = list(client.stream_answer(current_user, None, "hello", {"metadata": {"reviewTitle": "demo"}}))
self.assertEqual(
chunks,
[
'data: {"type": "text", "content": "hello"}\n\n',
'data: {"type": "sources", "sources": [{"title": "source", "content": "body"}]}\n\n',
'data: {"type": "end", "conversation_id": "conv-1"}\n\n',
],
)
if __name__ == "__main__":
unittest.main()