feat(agent): stream admin debug preview
This commit is contained in:
@@ -1,17 +1,22 @@
|
||||
import asyncio
|
||||
from decimal import Decimal
|
||||
import json
|
||||
from unittest.mock import patch
|
||||
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import Session
|
||||
from sqlalchemy.pool import StaticPool
|
||||
|
||||
from app.api.admin_settings import get_agent_runtime_config, save_agent_runtime_config
|
||||
from app.api.admin_settings import _debug_agent_stream, get_agent_runtime_config, save_agent_runtime_config
|
||||
from app.models import Base
|
||||
from app.models.admin import Admin
|
||||
from app.models.ai_config import ModelConfig
|
||||
from app.schemas.admin import AgentRuntimeConfigSaveRequest
|
||||
from app.services.model_stream_service import _openai_stream_payload, _stream_configured_model_async
|
||||
from app.schemas.admin import AgentDebugRequest, AgentRuntimeConfigSaveRequest
|
||||
from app.services.model_stream_service import (
|
||||
AsyncStreamingModelResponse,
|
||||
_openai_stream_payload,
|
||||
_stream_configured_model_async,
|
||||
)
|
||||
from app.services.model_service import ModelClientService, _max_output_tokens
|
||||
from app.services.rag_service import RagResult
|
||||
|
||||
@@ -128,6 +133,66 @@ def test_disabled_stream_returns_one_complete_chunk():
|
||||
assert chunks == [answer]
|
||||
|
||||
|
||||
def test_agent_debug_stream_emits_status_content_and_trace():
|
||||
async def chunks():
|
||||
yield "<think>内部思考</think>"
|
||||
yield "- **第一步**:停一下"
|
||||
|
||||
rag_result = RagResult(
|
||||
question="怎么冷静",
|
||||
knowledge_scopes=[],
|
||||
chunks=[],
|
||||
prompt="怎么冷静",
|
||||
allow_general_knowledge=True,
|
||||
retrieval_log_id=9,
|
||||
tool_trace=[{"tool": "KnowledgeSearch", "status": "success"}],
|
||||
messages=[{"role": "user", "content": "怎么冷静"}],
|
||||
)
|
||||
model_response = AsyncStreamingModelResponse(
|
||||
model_id=1,
|
||||
model_name="production-model",
|
||||
input_token=10,
|
||||
chunks=chunks(),
|
||||
)
|
||||
|
||||
async def collect(payload, db, admin):
|
||||
return [event async for event in _debug_agent_stream(payload, db, admin)]
|
||||
|
||||
with _database() as db:
|
||||
admin = _admin()
|
||||
model = _model()
|
||||
db.add_all([admin, model])
|
||||
db.commit()
|
||||
payload = AgentDebugRequest(
|
||||
promptContent="你是测试助手",
|
||||
modelId=model.id,
|
||||
knowledgeIds=[],
|
||||
question="怎么冷静",
|
||||
maxToken=8192,
|
||||
)
|
||||
with (
|
||||
patch(
|
||||
"app.services.agent_debug_service.KnowledgeAgentService.build_result",
|
||||
return_value=rag_result,
|
||||
),
|
||||
patch(
|
||||
"app.services.agent_debug_service.ModelStreamService.debug_stream_async",
|
||||
return_value=model_response,
|
||||
),
|
||||
):
|
||||
events = asyncio.run(collect(payload, db, admin))
|
||||
|
||||
decoded = [
|
||||
json.loads(event.removeprefix("data: "))
|
||||
for event in events
|
||||
if event != "data: [DONE]\n\n"
|
||||
]
|
||||
assert [event["type"] for event in decoded] == ["status", "content", "content", "complete"]
|
||||
assert decoded[1]["content"].startswith("<think>")
|
||||
assert decoded[2]["content"] == "- **第一步**:停一下"
|
||||
assert decoded[3]["retrievalTrace"][0]["tool"] == "KnowledgeSearch"
|
||||
|
||||
|
||||
def test_agent_debug_does_not_truncate_long_answer(monkeypatch):
|
||||
monkeypatch.setattr(
|
||||
"app.services.model_service._call_configured_model",
|
||||
|
||||
Reference in New Issue
Block a user