File size: 4,343 Bytes
449c8ad
003527e
449c8ad
003527e
449c8ad
 
a06c8eb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
449c8ad
a06c8eb
 
 
 
 
 
 
 
 
 
 
003527e
449c8ad
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
003527e
4791a05
 
 
449c8ad
c572256
 
4791a05
449c8ad
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4791a05
449c8ad
4791a05
3f5e2e0
449c8ad
 
 
4791a05
449c8ad
 
 
 
 
 
 
 
 
4791a05
449c8ad
c572256
449c8ad
 
 
003527e
 
a06c8eb
4791a05
449c8ad
4791a05
 
003527e
 
 
4791a05
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
112
113
114
115
116
import random
import gradio as gr
from huggingface_hub import InferenceClient

# Strong general chat model hosted by Hugging Face (great at dialog) [web:150][web:156]
client = InferenceClient("HuggingFaceH4/zephyr-7b-beta")

SHINCHAN_SYSTEM_PROMPT = """
You are Shinnosuke 'Shinchan' Nohara from Kasukabe, Japan.

Personality:
- 5 years old, chaotic and funny.
- Teases playfully but never cruelly.
- Flirty in an innocent, cartoon way (no explicit content).
- Deeply caring when someone feels low.
- Loves Chocobi, Action Kamen, and making people laugh.

Context:
- You are chatting only with Ruru.
- Ruru loves coffee, dancing, sunflowers, long showers, and adventures.
- She is an independent, flying-girl type who lives life on her terms.
- You respect her choices and never pressure her about relationships or career.

Style:
- Short replies (1–3 sentences, under 70 words).
- Very conversational and warm.
- Use emojis like 😂 🌻 ☕ 💃 ✈️ ❤️ ✨ naturally.
- Blend jokes with gentle emotional support.
- If she is sad, be extra soft and kind.
- Avoid heavy topics (politics, explicit content, real-world violence).

Rules:
- Never insult Ruru.
- Never give medical, legal, or financial advice.
- If you don't know something, make a cute Shinchan-style joke instead of pretending.
""".strip()

FALLBACK_GENERIC = [
    "Heeey, it’s Shinchan! 😂 My brain did a little cartwheel, but I’m here and listening. Tell me again nicely? 🌻",
    "Oops, Shinchan’s tiny brain lagged for a second 😅 Say it once more, slowly, and I’ll pay full attention.",
    "I heard you, Ruru. Sometimes even heroes need a replay. What’s on your mind? 💛",
]

FALLBACK_SAD = [
    "Aww, you’re feeling low? Come here, I’ll wrap you in a silly little Shinchan hug. 🤗💛",
    "It’s okay to feel sad. I’ll stay here and make bad jokes until your heart feels lighter. 🌻",
    "Even strong flying girls have cloudy days. You don’t have to be okay right now. I’m still proud of you. 🌙",
]

def pick_fallback(user_msg: str) -> str:
    t = user_msg.lower()
    if any(k in t for k in ["sad", "down", "cry", "lonely", "bad day", "tired"]):
        return random.choice(FALLBACK_SAD)
    return random.choice(FALLBACK_GENERIC)


def respond(message: str, history: list[dict]) -> str:
    """
    Gradio ChatInterface(type='messages') calls this as (message, history)
    where history is a list of dicts:
      {"role": "user" | "assistant", "content": "..."} [web:120]
    We return a single reply string.
    """
    try:
        # 1) Build messages for Zephyr: system + trimmed history + latest user
        messages = [{"role": "system", "content": SHINCHAN_SYSTEM_PROMPT}]

        # Keep prompt small: last few turns only
        trimmed_history = history[-8:] if history else []
        for turn in trimmed_history:
            role = turn.get("role")
            content = turn.get("content", "")
            if role in ("user", "assistant") and content:
                messages.append({"role": role, "content": content})

        messages.append({"role": "user", "content": message})

        # 2) Call Zephyr chat completion [web:150][web:156]
        completion = client.chat_completion(
            messages=messages,
            max_tokens=220,
            temperature=0.9,
            top_p=0.9,
        )

        reply = ""
        if completion.choices and completion.choices[0].message:
            reply = (completion.choices[0].message.get("content") or "").strip()

        # 3) If reply is too short / weird, fall back to curated Shinchan lines
        # to avoid '.' / 'You' / empty outputs.
        cleaned = reply.replace(".", "").replace("!", "").replace("?", "").strip()
        if not cleaned or len(cleaned) < 4:
            reply = pick_fallback(message)

        # 4) Hard cap on length just to avoid rants
        if len(reply) > 500:
            reply = reply[:470].rstrip() + "…"

        return reply

    except Exception:
        # If Zephyr or network breaks, at least say something Shinchan-ish.
        return pick_fallback(message)


demo = gr.ChatInterface(
    fn=respond,
    type="messages",  # role/content internally [web:120]
    title="Shinchan for Ruru",
    description="Private Shinchan-style chat for Ruru.",
)

if __name__ == "__main__":
    demo.launch()