generated from kgod/ai-review-template
feat: initialize resume agent with OfferPai sync
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
"""Turn and card builders for the Builder conversation."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from ..fsm import anchor_field_specs, assistant_turn, component
|
||||
from ..models import ComposerMode
|
||||
from .constants import SECTION_HEADINGS, SECTION_PRIORITY, u
|
||||
from .state import _completed_sections, _set_stream_phases, ensure_builder_state
|
||||
|
||||
|
||||
def recommended_section(profile: dict[str, Any], resume_content: dict[str, Any] | None = None) -> str:
|
||||
priorities = SECTION_PRIORITY.get(str(profile.get("job_type") or "campus"), SECTION_PRIORITY["campus"])
|
||||
completed = _completed_sections(resume_content or {})
|
||||
return next((section for section in priorities if section not in completed), priorities[0])
|
||||
|
||||
|
||||
def welcome_turn(
|
||||
profile: dict[str, Any],
|
||||
resume_id: str | None,
|
||||
*,
|
||||
imported: bool = False,
|
||||
resume_content: dict[str, Any] | None = None,
|
||||
) -> tuple[dict[str, Any], dict[str, Any]]:
|
||||
state = ensure_builder_state(profile)
|
||||
state["imported"] = imported
|
||||
if imported:
|
||||
turn = assistant_turn("简历已经导入。你想先修改哪一段经历,还是补充一段新的内容?", [], mode=ComposerMode.CHAT)
|
||||
_set_stream_phases(profile, "suggesting_next")
|
||||
return profile, turn
|
||||
turn = _next_step_turn(recommended_section(profile, resume_content))
|
||||
_set_stream_phases(profile, "suggesting_next")
|
||||
return profile, turn
|
||||
|
||||
|
||||
def _next_step_turn(section: str, *, prefix: str = "") -> dict[str, Any]:
|
||||
lead = f"{prefix} " if prefix else ""
|
||||
return assistant_turn(
|
||||
f"{lead}接下来建议补充{SECTION_HEADINGS[section]}。你想继续这类经历,还是改选其他经历类型?",
|
||||
[_section_choice_card(section)],
|
||||
mode=ComposerMode.CHAT,
|
||||
)
|
||||
|
||||
|
||||
def _section_choice_card(recommended: str) -> dict[str, Any]:
|
||||
return component(
|
||||
"ChoiceChips",
|
||||
module="builder_next_section",
|
||||
title=u("选择下一步"),
|
||||
description=f"{u('建议先补充')}{SECTION_HEADINGS[recommended]}{u(',也可以换一种经历、推荐岗位技能,或直接完成。')}",
|
||||
options=[
|
||||
*({"value": kind, "label": heading} for kind, heading in SECTION_HEADINGS.items()),
|
||||
{"value": "builder_recommend_skills", "label": u("推荐岗位技能")},
|
||||
{"value": "builder_finish", "label": u("完成并生成个人总结")},
|
||||
],
|
||||
value=recommended,
|
||||
)
|
||||
|
||||
|
||||
def _entry_choice_card(matches: list[tuple[dict[str, Any], dict[str, Any]]]) -> dict[str, Any]:
|
||||
options = [{"value": str(entry.get("id") or ""), "label": _entry_label(entry, str(section.get("kind") or ""))} for section, entry in matches]
|
||||
return component("ChoiceChips", module="builder_entry_select", title="选择要修改的经历", options=options)
|
||||
|
||||
|
||||
def _record_card(section: str, *, title: str, value: dict[str, Any] | None = None, entry_id: Any = None, skippable: bool = False) -> dict[str, Any]:
|
||||
props: dict[str, Any] = {
|
||||
"module": "builder_identity",
|
||||
"record_type": section,
|
||||
"title": title,
|
||||
"fields": anchor_field_specs(section),
|
||||
"show_description": False,
|
||||
"require_description": False,
|
||||
"skippable": skippable,
|
||||
"skip_label": "稍后补充",
|
||||
}
|
||||
if value:
|
||||
props["value"] = value
|
||||
if entry_id:
|
||||
props["entry_id"] = entry_id
|
||||
return component("RecordFields", **props)
|
||||
|
||||
|
||||
def _fact_prompt(section: str) -> str:
|
||||
prompts = {
|
||||
"education": "请补充这段教育经历的真实信息,例如课程项目、竞赛、实践或学习成果;没有也可以直接说没有。",
|
||||
"campus_experience": "请补充你实际承担的职责,或规模和结果中的一两项;没有也可以直接说没有。",
|
||||
"project_experience": "请补充个人动作、方法或工具,以及交付物、规模或量化结果中的一两项;没有也可以直接说没有。",
|
||||
"work_experience": "请补充个人动作、方法或工具,以及交付物、规模或量化结果中的一两项;没有也可以直接说没有。",
|
||||
"internship_experience": "请补充个人动作、方法或工具,以及交付物、规模或量化结果中的一两项;没有也可以直接说没有。",
|
||||
}
|
||||
return prompts[section]
|
||||
|
||||
|
||||
def _entry_label(entry: dict[str, Any], kind: str) -> str:
|
||||
identity = next((str(entry.get(key) or "").strip() for key in ("school", "company", "project_name", "organization") if str(entry.get(key) or "").strip()), SECTION_HEADINGS.get(kind, "经历"))
|
||||
role = next((str(entry.get(key) or "").strip() for key in ("major", "position", "project_role", "role") if str(entry.get(key) or "").strip()), "")
|
||||
return f"{identity} · {role}" if role else identity
|
||||
Reference in New Issue
Block a user