borderless / ui /intake /prompts.py
spagestic's picture
Profile-based chat titles are implemented
dbdb569
Raw
History Blame Contribute Delete
4.68 kB
# ui/intake/prompts.py
from __future__ import annotations
DropdownValue = str | int | float | list[str | int | float] | None
def _chatbox_value(text: str) -> dict[str, object]:
return {"text": text.strip(), "files": []}
def _format_value(value: DropdownValue) -> str:
if value is None:
return ""
if isinstance(value, list):
parts = [str(item).strip() for item in value if str(item).strip()]
return ", ".join(parts)
return str(value).strip()
def _location_text(country: DropdownValue, status: DropdownValue) -> str:
country_text = _format_value(country)
status_text = _format_value(status)
if country_text and status_text:
return f"{country_text}{status_text}"
return country_text or status_text
def _work_history_text(occupation: DropdownValue, experience: DropdownValue) -> str:
occupation_text = _format_value(occupation)
experience_text = _format_value(experience)
if occupation_text and experience_text:
return f"{occupation_text}{experience_text}"
return occupation_text or experience_text
def _profile_prompt_text(
citizenship: DropdownValue,
current_country: DropdownValue,
residence_status: DropdownValue,
education: DropdownValue,
occupation: DropdownValue,
experience: DropdownValue,
languages: DropdownValue,
budget: DropdownValue,
family: DropdownValue,
timeline: DropdownValue,
goals: str,
) -> str:
sections = [
("Citizenship/passport", _format_value(citizenship)),
("Current location", _location_text(current_country, residence_status)),
("Education", _format_value(education)),
("Work history", _work_history_text(occupation, experience)),
("Languages", _format_value(languages)),
("Budget and savings", _format_value(budget)),
("Family/dependents", _format_value(family)),
("Target timeline", _format_value(timeline)),
("Goals and preferences", goals),
]
details = "\n".join(
f"- {label}: {value.strip()}"
for label, value in sections
if value and value.strip()
)
if not details:
details = (
"- I have not filled in the profile yet. Ask me only for the "
"missing details that matter most."
)
return (
"Research realistic migration options for my profile.\n\n"
f"{details}\n\n"
"Please recommend 3-5 suitable countries, mark them on the globe, "
"compare visa pathways, required documents, approximate costs, "
"realistic timelines, risks, and official sources to verify."
)
def build_profile_prompt(
citizenship: DropdownValue,
current_country: DropdownValue,
residence_status: DropdownValue,
education: DropdownValue,
occupation: DropdownValue,
experience: DropdownValue,
languages: DropdownValue,
budget: DropdownValue,
family: DropdownValue,
timeline: DropdownValue,
goals: str,
) -> dict[str, object]:
return _chatbox_value(
_profile_prompt_text(
citizenship,
current_country,
residence_status,
education,
occupation,
experience,
languages,
budget,
family,
timeline,
goals,
)
)
def _truncate_title(title: str, max_length: int = 72) -> str:
if len(title) <= max_length:
return title
return f"{title[: max_length - 3]}..."
def build_session_title(
current_country: DropdownValue,
residence_status: DropdownValue,
education: DropdownValue,
occupation: DropdownValue,
experience: DropdownValue,
budget: DropdownValue,
family: DropdownValue,
timeline: DropdownValue,
goals: str,
) -> str:
del residence_status, experience, budget, family # unused for title
parts = [
part
for part in (
_format_value(occupation),
_format_value(current_country),
_format_value(timeline),
)
if part
]
if not parts:
education_text = _format_value(education)
if education_text:
parts.append(education_text)
if parts:
return _truncate_title(" · ".join(parts))
goals_text = " ".join((goals or "").split())
if goals_text:
return _truncate_title(goals_text)
return "Untitled chat"
def example_prompt(prompt: str) -> dict[str, object]:
return _chatbox_value(prompt)