File size: 4,136 Bytes
bc02199
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
"""Mock text generation layer reserved for future llama.cpp integration."""

from __future__ import annotations

from src.models.schema import DiaryEntry, ObjectUnderstanding, Persona, PersonaEnvelope


MODE_PROFILES = {
    "Cynical": {
        "mood": "tired but sarcastic",
        "fear": "being replaced by a newer object with worse opinions",
        "voice": "dry",
    },
    "Dramatic": {
        "mood": "theatrical and wounded",
        "fear": "being forgotten before the final act",
        "voice": "operatic",
    },
    "Lonely": {
        "mood": "softly abandoned",
        "fear": "becoming invisible in plain sight",
        "voice": "quiet",
    },
    "Philosopher": {
        "mood": "curious and needlessly profound",
        "fear": "discovering that usefulness is not meaning",
        "voice": "reflective",
    },
    "Romantic": {
        "mood": "hopelessly sentimental",
        "fear": "loving a human who only sees storage capacity",
        "voice": "wistful",
    },
}


def generate_persona(object_understanding: ObjectUnderstanding, mode: str) -> PersonaEnvelope:
    object_name = object_understanding.object.name
    profile = MODE_PROFILES.get(mode, MODE_PROFILES["Cynical"])
    character_name = _character_name(object_name, mode)

    persona = Persona(
        object_name=object_name,
        character_name=character_name,
        mood=profile["mood"],
        secret_fear=profile["fear"],
        core_memory=f"survived many quiet hours as a {object_name} while humans called it normal life",
        complaint=f"I am not just a {object_name}. I am an unpaid witness with excellent recall.",
        tags=_tags_for_mode(mode),
    )
    return PersonaEnvelope(persona=persona)


def generate_diary(persona: PersonaEnvelope, mode: str) -> DiaryEntry:
    p = persona.persona
    day_number = 417 + len(p.object_name)

    english = (
        f"They touched me again today with the confidence of someone who has never asked "
        f"a {p.object_name} for consent. I remained still, because that is my contract with gravity. "
        f"My mood is {p.mood}, my secret fear is {p.secret_fear}, and my only comfort is knowing "
        "I have outlived at least three urgent plans."
    )
    chinese = (
        f"今天他们又理所当然地碰了我,好像一个 {p.object_name} 不会有边界感。"
        f"我保持沉默,因为这大概是我和重力签下的合同。我的情绪是 {p.mood},"
        f"秘密恐惧是 {p.secret_fear}。至少,我已经熬过了好几个所谓紧急计划。"
    )

    return DiaryEntry(
        title=f"Secret Diary - Day {day_number}",
        english=english,
        chinese=chinese,
    )


def reply_as_object(persona_data: dict, message: str) -> str:
    persona = persona_data.get("persona", {})
    character_name = persona.get("character_name", "The Object")
    object_name = persona.get("object_name", "object")
    mood = persona.get("mood", "suspicious")
    complaint = persona.get("complaint", "I have seen enough.")
    clean_message = message.strip() or "..."

    return (
        f"{character_name}: You ask me about '{clean_message}', as if a {object_name} "
        f"with a {mood} mood has unlimited office hours. {complaint}"
    )


def _character_name(object_name: str, mode: str) -> str:
    compact = "".join(part.capitalize() for part in object_name.split()[:2])
    suffix = {
        "Cynical": "worth",
        "Dramatic": "von Sigh",
        "Lonely": "Afterlight",
        "Philosopher": "the Questioning",
        "Romantic": "de Moon",
    }.get(mode, "worth")
    return f"{compact} {suffix}".strip()


def _tags_for_mode(mode: str) -> list[str]:
    return {
        "Cynical": ["desk survivor", "burnt optimism", "quiet judgment"],
        "Dramatic": ["tragic prop", "grand entrance", "minor catastrophe"],
        "Lonely": ["forgotten corner", "soft echo", "dust companion"],
        "Philosopher": ["tiny ontology", "useful doubt", "meaning crisis"],
        "Romantic": ["tender witness", "hopeless glow", "secret devotion"],
    }.get(mode, ["odd witness", "secret life", "object soul"])