feat(ai): gRPC clients 扩展 + server interceptors + proto_gen + 测试 + nextstep 文档
This commit is contained in:
@@ -23,13 +23,15 @@ from src.ai.workflow.state_store import WorkflowState, WorkflowStateStore
|
||||
from .conftest import MockProvider
|
||||
|
||||
# 有效的 LLM JSON 输出(通过三道防线评估)
|
||||
VALID_QUESTION_JSON = json.dumps({
|
||||
"question": "什么是函数?",
|
||||
"answer": "函数是一种对应关系",
|
||||
"explanation": "函数定义",
|
||||
"difficulty": "medium",
|
||||
"question_type": "short_answer",
|
||||
})
|
||||
VALID_QUESTION_JSON = json.dumps(
|
||||
{
|
||||
"question": "什么是函数?",
|
||||
"answer": "函数是一种对应关系",
|
||||
"explanation": "函数定义",
|
||||
"difficulty": "medium",
|
||||
"question_type": "short_answer",
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def _make_chain(provider: MockProvider | None = None) -> ProviderFailoverChain:
|
||||
@@ -135,11 +137,16 @@ class TestLessonPlanWorkflowConfirm:
|
||||
store = WorkflowStateStore(redis=None)
|
||||
state = _make_state(
|
||||
status="pending_review",
|
||||
questions=[GeneratedQuestionData(
|
||||
question="q1", answer="a1", explanation="e1",
|
||||
question_type="short_answer", difficulty="easy",
|
||||
knowledge_point_ids=["kp_1"],
|
||||
)],
|
||||
questions=[
|
||||
GeneratedQuestionData(
|
||||
question="q1",
|
||||
answer="a1",
|
||||
explanation="e1",
|
||||
question_type="short_answer",
|
||||
difficulty="easy",
|
||||
knowledge_point_ids=["kp_1"],
|
||||
)
|
||||
],
|
||||
)
|
||||
await store.create(state)
|
||||
svc = _make_service(store=store, content_client=ContentClientMock())
|
||||
@@ -166,11 +173,16 @@ class TestLessonPlanWorkflowConfirm:
|
||||
store = WorkflowStateStore(redis=None)
|
||||
state = _make_state(
|
||||
status="pending_review",
|
||||
questions=[GeneratedQuestionData(
|
||||
question="original", answer="a1", explanation="e1",
|
||||
question_type="short_answer", difficulty="easy",
|
||||
knowledge_point_ids=["kp_1"],
|
||||
)],
|
||||
questions=[
|
||||
GeneratedQuestionData(
|
||||
question="original",
|
||||
answer="a1",
|
||||
explanation="e1",
|
||||
question_type="short_answer",
|
||||
difficulty="easy",
|
||||
knowledge_point_ids=["kp_1"],
|
||||
)
|
||||
],
|
||||
)
|
||||
await store.create(state)
|
||||
|
||||
@@ -200,7 +212,7 @@ class TestLessonPlanWorkflowSteps:
|
||||
analysis = await svc._step1_analyze(state)
|
||||
assert "class_performance" in analysis
|
||||
assert analysis["class_performance"]["average_score"] == 78.5
|
||||
assert analysis["class_performance"]["student_count"] == 3
|
||||
assert analysis["class_performance"]["student_count"] == 2
|
||||
assert "weak_students" in analysis
|
||||
|
||||
async def test_step1_analyze_no_client_degraded(self) -> None:
|
||||
@@ -214,13 +226,14 @@ class TestLessonPlanWorkflowSteps:
|
||||
svc = _make_service(content_client=ContentClientMock())
|
||||
state = _make_state()
|
||||
kps = await svc._step2_recommend(state)
|
||||
assert len(kps) == 3
|
||||
assert len(kps) == 2
|
||||
assert kps[0]["id"] == "kp_001"
|
||||
|
||||
async def test_step2_recommend_no_client_fallback(self) -> None:
|
||||
svc = _make_service(content_client=None)
|
||||
state = _make_state(topic="函数")
|
||||
kps = await svc._step2_recommend(state)
|
||||
# 无 content_client 时降级到内置 3 个默认知识点
|
||||
assert len(kps) == 3
|
||||
assert "基础概念" in kps[0]["title"]
|
||||
assert "函数" in kps[0]["title"]
|
||||
@@ -233,7 +246,8 @@ class TestLessonPlanWorkflowSteps:
|
||||
)
|
||||
state = _make_state(question_count=1, target_difficulty="medium")
|
||||
questions = await svc._step3_generate(
|
||||
state, [{"id": "kp_1", "title": "KP1"}],
|
||||
state,
|
||||
[{"id": "kp_1", "title": "KP1"}],
|
||||
)
|
||||
assert len(questions) == 1
|
||||
assert questions[0].question == "什么是函数?"
|
||||
@@ -245,7 +259,8 @@ class TestLessonPlanWorkflowSteps:
|
||||
svc = _make_service(provider=provider)
|
||||
state = _make_state(question_count=1)
|
||||
questions = await svc._step3_generate(
|
||||
state, [{"id": "kp_1", "title": "KP1"}],
|
||||
state,
|
||||
[{"id": "kp_1", "title": "KP1"}],
|
||||
)
|
||||
assert len(questions) == 1
|
||||
assert questions[0].degraded is True
|
||||
|
||||
Reference in New Issue
Block a user