Repository navigation
feat(ai): show safe review progress - #187
Conversation
📝 WalkthroughWalkthrough问询画像生成和初始审核接口改为 SSE 响应。后端发送安全阶段事件。前端转发事件并显示排队、生成、校验和回退进度。测试覆盖事件顺序、最终结果和敏感内容隔离。 ChangesAI SSE 合约与后端事件
客户端事件转发
前端进度展示
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related issues
Possibly related PRs
Suggested reviewers: Sequence Diagram(s)sequenceDiagram
participant FamilyIntakeForm
participant intakeApi
participant IntakeRoute
participant AiReviewProgress
FamilyIntakeForm->>intakeApi: start AI review with event listener
intakeApi->>IntakeRoute: send SSE request
IntakeRoute-->>intakeApi: send progress event
intakeApi-->>FamilyIntakeForm: forward parsed event
FamilyIntakeForm->>AiReviewProgress: render current stage
IntakeRoute-->>intakeApi: send completed event
intakeApi-->>FamilyIntakeForm: return final review result
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 oasdiff (1.27.0)docs/openapi.yamlError: failed to load revision spec from "docs/openapi.yaml": failed to unmarshal data: json error: invalid character 'o' looking for beginning of value, yaml error: error converting YAML to JSON: yaml: line 352: mapping values are not allowed in this context Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/openapi.yaml`:
- Line 352: 修复 OpenAPI YAML 中该 description 的语法:在包含 “SSE: optional” 的 description
值上使用引号或折叠块标量,确保整段描述可被 YAML 正确解析,并保留现有描述内容。
In `@tests/api/intake_session_confirm_post.rs`:
- Around line 298-316: Extend tests/api/intake_session_confirm_post.rs:298-316
to parse each SSE frame’s data payload, assert progress payloads contain only
the allowed stage field, reject unknown stages, and verify the final stage is
validating or fallback while preserving ordering and completion checks. Extend
frontend/src/api/client.test.ts:121-161 with an onEvent error-frame case,
asserting the listener receives the error event before the request rejects with
stream_failed.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: d5de7f72-5b0c-4be2-9694-887089482305
📒 Files selected for processing (11)
docs/API.mddocs/openapi.yamlfrontend/src/api/client.test.tsfrontend/src/api/client.tsfrontend/src/api/intake.tsfrontend/src/components/AiReviewProgress.test.tsxfrontend/src/components/AiReviewProgress.tsxfrontend/src/pages/CaseWorkspacePage.tsxfrontend/src/pages/FamilyIntakeForm.tsxsrc/api/routes/intake_sessions.rstests/api/intake_session_confirm_post.rs
| operationId: startIntakeAiInitialReview | ||
| summary: Start the family-visible AI initial review | ||
| description: The session creator submits the profile snapshot after first confirmation. The service validates model JSON and policy boundaries; the Gateway performs at most two total HTTP calls (one JSON repair or one compliant provider failover, never both), while unavailable providers, invalid output, and execution failures return a rule-based review fallback. This operation never creates a case. | ||
| description: The session creator submits the profile snapshot after first confirmation. The service validates model JSON and policy boundaries; the Gateway performs at most two total HTTP calls (one JSON repair or one compliant provider failover, never both), while unavailable providers, invalid output, and execution failures return a rule-based review fallback. This operation never creates a case. The response is SSE: optional safe `progress` events contain only a stage (`queued`, `preparing`, `generating`, `validating`, or `fallback`), and the final `completed` event contains the review result. Partial streams are not a valid review result. |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
yamllint docs/openapi.yamlRepository: AG-Angui/Angui
Length of output: 29805
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
path = Path("docs/openapi.yaml")
lines = path.read_text().splitlines()
line = lines[351]
print(f"line_352={line}")
print(f"sse_index={line.index('SSE: optional') if 'SSE: optional' in line else -1}")
try:
import yaml
except ImportError:
print("PyYAML unavailable")
else:
for label, text in (
("current", path.read_text()),
("folded", "\n".join(
lines[:351]
+ [
" description: >-",
" " + line.split("description: ", 1)[1],
]
+ lines[352:]
) + "\n"),
):
try:
yaml.safe_load(text)
print(f"{label}=parse_ok")
except Exception as exc:
print(f"{label}=parse_error:{type(exc).__name__}:{exc}")
PYRepository: AG-Angui/Angui
Length of output: 851
修复 OpenAPI YAML 语法。
docs/openapi.yaml:352 的未加引号 description 值包含 SSE: optional,导致 YAML 解析失败。请使用带引号的字符串或折叠块标量。
🧰 Tools
🪛 YAMLlint (1.37.1)
[error] 352-352: syntax error: mapping values are not allowed here
(syntax)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/openapi.yaml` at line 352, 修复 OpenAPI YAML 中该 description 的语法:在包含 “SSE:
optional” 的 description 值上使用引号或折叠块标量,确保整段描述可被 YAML 正确解析,并保留现有描述内容。
Source: Linters/SAST tools
| let events = stream | ||
| .split("\n\n") | ||
| .filter_map(|frame| { | ||
| frame | ||
| .lines() | ||
| .find_map(|line| line.strip_prefix("event:").map(str::trim)) | ||
| }) | ||
| .collect::<Vec<_>>(); | ||
|
|
||
| assert_eq!(events.first(), Some(&"started")); | ||
| assert!( | ||
| events | ||
| .windows(2) | ||
| .any(|pair| pair == ["started", "progress"]) | ||
| ); | ||
| assert!(events.iter().filter(|event| **event == "progress").count() >= 3); | ||
| assert_eq!(events.last(), Some(&"completed")); | ||
| assert!(!stream.contains("system_instruction")); | ||
| assert!(!stream.contains("raw_prompt")); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
补充 SSE 失败和安全载荷的契约测试。
当前测试只验证成功事件名。它们无法发现未知阶段、progress 事件中的额外敏感字段,或 error 事件未回调的问题。
tests/api/intake_session_confirm_post.rs#L298-L316: 解析每个 SSE 帧的data:。断言progress载荷只含允许的stage,并断言阶段顺序及最终validating或fallback阶段。frontend/src/api/client.test.ts#L121-L161: 增加带onEvent的error帧测试。断言监听器先收到该事件,然后请求以stream_failed拒绝。
As per path instructions, tests/**: Check that changed behavior has meaningful positive, negative, and boundary-case coverage. Do not request tests for style-only changes.
📍 Affects 2 files
tests/api/intake_session_confirm_post.rs#L298-L316(this comment)frontend/src/api/client.test.ts#L121-L161
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@tests/api/intake_session_confirm_post.rs` around lines 298 - 316, Extend
tests/api/intake_session_confirm_post.rs:298-316 to parse each SSE frame’s data
payload, assert progress payloads contain only the allowed stage field, reject
unknown stages, and verify the final stage is validating or fallback while
preserving ordering and completion checks. Extend
frontend/src/api/client.test.ts:121-161 with an onEvent error-frame case,
asserting the listener receives the error event before the request rejects with
stream_failed.
Source: Path instructions
Summary by CodeRabbit
新功能
文档
测试