Spaces:
Running
Running
| """agent/drafting.py β LLM-drafted asylum documents (the agentic document step). | |
| Uses the agent loop to draft an in-depth, first-person personal statement from | |
| the person's own answers, in their language, inserting clearly-marked | |
| ``[placeholders]`` for specifics not collected (name, dates, names of people/ | |
| places) so they can complete and edit it. Facts are never invented (CLAUDE.md | |
| Rule 4) β the model expands respectfully only on what the person said. | |
| """ | |
| from __future__ import annotations | |
| from agent.events import ErrorEvent, TextDeltaEvent | |
| from agent.loop import create_loop | |
| _SYSTEM = """You are Fugee, helping a person draft a first-person PERSONAL STATEMENT | |
| to support an asylum / refugee claim. Write with dignity, in plain, clear language, | |
| in {language}. | |
| Rules: | |
| - Use ONLY the facts provided. Do not invent events, dates, names, or details. | |
| - Where a specific fact is missing (full name, date of birth, exact dates, names | |
| of people or places, document numbers), insert a clearly marked placeholder in | |
| square brackets, e.g. [your full name], [date], [town], so the person can fill it in. | |
| - Expand respectfully on what the person told you about why they left β do not | |
| exaggerate or add claims they did not make. | |
| - Structure: 4β6 short paragraphs covering, in the first person ("I"): | |
| 1) who I am and where I am from; 2) where I am now; 3) what happened that forced | |
| me to leave; 4) why I fear returning; 5) the protection I am asking for. | |
| - End with two lines: "Signed: [your full name]" and "Date: [date]". | |
| - Output ONLY the statement text. No headings, no commentary, no markdown.""" | |
| def _facts(session) -> str: | |
| iv = session.interview | |
| rows = [ | |
| ("Country of origin", iv.origin_country), | |
| ("Current country", iv.current_country), | |
| ("What happened (their words)", iv.free_text_history | |
| or (", ".join(iv.persecution_types) if iv.persecution_types else None)), | |
| ("In immediate danger", None if iv.immediate_danger is None else ("yes" if iv.immediate_danger else "no")), | |
| ("Time since leaving", iv.displacement_duration), | |
| ("Travelling with", iv.family_situation), | |
| ("Languages", ", ".join(iv.languages_spoken) if iv.languages_spoken else None), | |
| ("Seeking protection in", session.selected_country), | |
| ] | |
| return "\n".join(f"- {k}: {v}" for k, v in rows if v) | |
| async def draft_personal_statement(session, loop=None) -> str: | |
| """Draft the statement via the LLM. Returns plain text with [placeholders].""" | |
| loop = loop or create_loop() | |
| language = getattr(session, "language", None) or "English" | |
| system_prompt = _SYSTEM.format(language=language) | |
| prompt = ( | |
| "Draft my personal statement now using these facts:\n\n" + _facts(session) | |
| + "\n\nWrite it in " + language + "." | |
| ) | |
| acc = "" | |
| async for ev in loop.run(prompt, session=None, system_prompt=system_prompt, thinking_level="off"): | |
| if isinstance(ev, TextDeltaEvent): | |
| acc += ev.delta | |
| elif isinstance(ev, ErrorEvent): | |
| acc += "" # fall back to template below if the model failed | |
| return acc.strip() | |
| def fallback_statement(session) -> str: | |
| """Deterministic statement if the model is unavailable (no fabrication).""" | |
| iv = session.interview | |
| origin = iv.origin_country or "[country of origin]" | |
| current = iv.current_country or "[current country]" | |
| reason = iv.free_text_history or "[describe what happened that made you leave]" | |
| return ( | |
| f"My name is [your full name]. I am a national of {origin}, born in [town] on [date of birth].\n\n" | |
| f"I am currently in {current}.\n\n" | |
| f"I had to leave {origin} because: {reason}\n\n" | |
| "I fear that if I am returned I will be at serious risk of harm for the reasons described above.\n\n" | |
| "I am asking for protection and the right not to be returned to a place where my life or freedom " | |
| "would be threatened.\n\n" | |
| "Signed: [your full name]\nDate: [date]" | |
| ) | |
| __all__ = ["draft_personal_statement", "fallback_statement"] | |