调整登记预览解析顺序
This commit is contained in:
+46
-23
@@ -299,6 +299,13 @@ def _merge_answers(fields: dict[str, str], answers: dict[str, str]) -> dict[str,
|
|||||||
return merged
|
return merged
|
||||||
|
|
||||||
|
|
||||||
|
def _model_fields(payload: dict[str, Any]) -> dict[str, str]:
|
||||||
|
fields = payload.get("fields") or {}
|
||||||
|
if not isinstance(fields, dict):
|
||||||
|
return {}
|
||||||
|
return {str(key): str(value or "").strip() for key, value in fields.items() if str(value or "").strip()}
|
||||||
|
|
||||||
|
|
||||||
def _missing_fields(register_type: str, fields: dict[str, str]) -> list[str]:
|
def _missing_fields(register_type: str, fields: dict[str, str]) -> list[str]:
|
||||||
return [field for field in REQUIRED_FIELDS[register_type] if not str(fields.get(field) or "").strip()]
|
return [field for field in REQUIRED_FIELDS[register_type] if not str(fields.get(field) or "").strip()]
|
||||||
|
|
||||||
@@ -385,6 +392,8 @@ def call_model_for_standardization(
|
|||||||
register_type: str,
|
register_type: str,
|
||||||
source_lines: list[str],
|
source_lines: list[str],
|
||||||
answers: dict[str, str],
|
answers: dict[str, str],
|
||||||
|
local_fields: dict[str, str] | None = None,
|
||||||
|
missing_fields: list[str] | None = None,
|
||||||
) -> dict[str, Any]:
|
) -> dict[str, Any]:
|
||||||
config = load_codex_ai_config()
|
config = load_codex_ai_config()
|
||||||
system_prompt = (
|
system_prompt = (
|
||||||
@@ -401,18 +410,25 @@ def call_model_for_standardization(
|
|||||||
"course_summary": "学生:...\n日期:YYYY.MM.DD\n时间:HH:MM-HH:MM\n老师:...\n科目:...\n小结:\n正文",
|
"course_summary": "学生:...\n日期:YYYY.MM.DD\n时间:HH:MM-HH:MM\n老师:...\n科目:...\n小结:\n正文",
|
||||||
},
|
},
|
||||||
"input": source_lines,
|
"input": source_lines,
|
||||||
|
"script_fields": local_fields or {},
|
||||||
|
"script_missing_fields": missing_fields or [],
|
||||||
|
"field_labels": _field_labels(register_type),
|
||||||
"answers": answers,
|
"answers": answers,
|
||||||
"response_schema": {
|
"response_schema": {
|
||||||
"status": "ready 或 needs_info",
|
"status": "ready 或 needs_info",
|
||||||
"standard_lines": ["完整时提供"],
|
"standard_lines": ["完整时提供"],
|
||||||
|
"fields": {"缺信息时提供已能确认的字段"},
|
||||||
"questions": ["缺信息时提供中文问题"],
|
"questions": ["缺信息时提供中文问题"],
|
||||||
"summary": "简短中文预览",
|
"summary": "简短中文预览",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
instructions = (
|
instructions = (
|
||||||
"输出必须是紧凑 JSON。"
|
"输出必须是紧凑 JSON。"
|
||||||
|
"script_fields 是脚本已识别字段,script_missing_fields 是脚本缺失字段。"
|
||||||
|
"如果能确认完整内容,必须返回 ready 和 standard_lines。"
|
||||||
|
"如果不能确认,返回 needs_info、fields、questions。"
|
||||||
"ready 示例:{\"status\":\"ready\",\"standard_lines\":[\"...\"],\"questions\":[],\"summary\":\"...\"}。"
|
"ready 示例:{\"status\":\"ready\",\"standard_lines\":[\"...\"],\"questions\":[],\"summary\":\"...\"}。"
|
||||||
"needs_info 示例:{\"status\":\"needs_info\",\"standard_lines\":[],\"questions\":[\"请补充...\"],\"summary\":\"...\"}。"
|
"needs_info 示例:{\"status\":\"needs_info\",\"standard_lines\":[],\"fields\":{\"student\":\"...\"},\"questions\":[\"请补充...\"],\"summary\":\"...\"}。"
|
||||||
"不要解释,不要输出额外字段。"
|
"不要解释,不要输出额外字段。"
|
||||||
)
|
)
|
||||||
body = json.dumps(
|
body = json.dumps(
|
||||||
@@ -527,6 +543,21 @@ def fields_preview(register_type: str, fields: dict[str, str]) -> dict[str, Any]
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def standard_lines_preview(register_type: str, standard_lines: list[str], summary: str, *, ai_used: bool, source: str) -> dict[str, Any]:
|
||||||
|
return {
|
||||||
|
"status": "ready",
|
||||||
|
"standard_lines": standard_lines,
|
||||||
|
"questions": [],
|
||||||
|
"summary": summary,
|
||||||
|
"ai_used": ai_used,
|
||||||
|
"fields": {},
|
||||||
|
"missing_fields": [],
|
||||||
|
"field_labels": _field_labels(register_type),
|
||||||
|
"timed_out": False,
|
||||||
|
"recognition_source": source,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def validate_standard_lines(register_type: str, lines: list[str]) -> list[str]:
|
def validate_standard_lines(register_type: str, lines: list[str]) -> list[str]:
|
||||||
if not lines:
|
if not lines:
|
||||||
raise ValueError("模型未返回标准行")
|
raise ValueError("模型未返回标准行")
|
||||||
@@ -555,24 +586,12 @@ def validate_standard_lines(register_type: str, lines: list[str]) -> list[str]:
|
|||||||
return standard_lines
|
return standard_lines
|
||||||
|
|
||||||
|
|
||||||
def local_preview(register_type: str, lines: list[str], answers: dict[str, str] | None = None) -> dict[str, Any] | None:
|
def local_standard_preview(register_type: str, lines: list[str]) -> dict[str, Any] | None:
|
||||||
try:
|
try:
|
||||||
standard_lines = validate_standard_lines(register_type, lines)
|
standard_lines = validate_standard_lines(register_type, lines)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
fields = _merge_answers(extract_local_fields(register_type, lines), answers or {})
|
return None
|
||||||
return fields_preview(register_type, fields)
|
return standard_lines_preview(register_type, standard_lines, "已按标准格式通过本地校验", ai_used=False, source="local")
|
||||||
return {
|
|
||||||
"status": "ready",
|
|
||||||
"standard_lines": standard_lines,
|
|
||||||
"questions": [],
|
|
||||||
"summary": "已按标准格式通过本地校验",
|
|
||||||
"ai_used": False,
|
|
||||||
"fields": {},
|
|
||||||
"missing_fields": [],
|
|
||||||
"field_labels": _field_labels(register_type),
|
|
||||||
"timed_out": False,
|
|
||||||
"recognition_source": "local",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def preview_register(
|
def preview_register(
|
||||||
@@ -590,22 +609,26 @@ def preview_register(
|
|||||||
merged_answers = {**dict(session.get("answers") or {}), **(answers or {})}
|
merged_answers = {**dict(session.get("answers") or {}), **(answers or {})}
|
||||||
session["answers"] = merged_answers
|
session["answers"] = merged_answers
|
||||||
|
|
||||||
local = local_preview(normalized_type, source_lines, merged_answers)
|
local = local_standard_preview(normalized_type, source_lines)
|
||||||
if local is not None:
|
if local is not None:
|
||||||
return {"conversation_id": conversation_id, "type": normalized_type, **local}
|
return {"conversation_id": conversation_id, "type": normalized_type, **local}
|
||||||
|
|
||||||
|
local_fields = _merge_answers(extract_local_fields(normalized_type, source_lines), merged_answers)
|
||||||
|
local_ready = fields_preview(normalized_type, local_fields)
|
||||||
|
if local_ready is not None and local_ready.get("status") == "ready":
|
||||||
|
return {"conversation_id": conversation_id, "type": normalized_type, **local_ready}
|
||||||
|
missing = _missing_fields(normalized_type, local_fields)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
model_payload = call_model_for_standardization(normalized_type, source_lines, merged_answers)
|
model_payload = call_model_for_standardization(normalized_type, source_lines, merged_answers, local_fields, missing)
|
||||||
except ValueError as exc:
|
except ValueError as exc:
|
||||||
fields = _merge_answers(extract_local_fields(normalized_type, source_lines), merged_answers)
|
|
||||||
missing = _missing_fields(normalized_type, fields)
|
|
||||||
timed_out = "timed out" in str(exc).lower() or "timeout" in str(exc).lower()
|
timed_out = "timed out" in str(exc).lower() or "timeout" in str(exc).lower()
|
||||||
return {
|
return {
|
||||||
"conversation_id": conversation_id,
|
"conversation_id": conversation_id,
|
||||||
"type": normalized_type,
|
"type": normalized_type,
|
||||||
**_needs_info_response(
|
**_needs_info_response(
|
||||||
normalized_type,
|
normalized_type,
|
||||||
fields,
|
local_fields,
|
||||||
missing,
|
missing,
|
||||||
ai_used=True,
|
ai_used=True,
|
||||||
timed_out=timed_out,
|
timed_out=timed_out,
|
||||||
@@ -618,7 +641,7 @@ def preview_register(
|
|||||||
questions = [str(item).strip() for item in model_payload.get("questions") or [] if str(item).strip()]
|
questions = [str(item).strip() for item in model_payload.get("questions") or [] if str(item).strip()]
|
||||||
if status == "needs_info" or questions:
|
if status == "needs_info" or questions:
|
||||||
session["questions"] = questions
|
session["questions"] = questions
|
||||||
fields = _merge_answers(extract_local_fields(normalized_type, source_lines), merged_answers)
|
fields = _merge_answers(local_fields, _model_fields(model_payload))
|
||||||
return {
|
return {
|
||||||
"conversation_id": conversation_id,
|
"conversation_id": conversation_id,
|
||||||
"type": normalized_type,
|
"type": normalized_type,
|
||||||
@@ -637,7 +660,7 @@ def preview_register(
|
|||||||
try:
|
try:
|
||||||
standard_lines = validate_standard_lines(normalized_type, model_payload.get("standard_lines") or [])
|
standard_lines = validate_standard_lines(normalized_type, model_payload.get("standard_lines") or [])
|
||||||
except ValueError as exc:
|
except ValueError as exc:
|
||||||
fields = _merge_answers(extract_local_fields(normalized_type, source_lines), merged_answers)
|
fields = _merge_answers(local_fields, _model_fields(model_payload))
|
||||||
return {
|
return {
|
||||||
"conversation_id": conversation_id,
|
"conversation_id": conversation_id,
|
||||||
"type": normalized_type,
|
"type": normalized_type,
|
||||||
|
|||||||
Reference in New Issue
Block a user