Files
miku-discord/readmes/AUTONOMOUS_V2_DECISION_LOGIC.md

14 KiB
Raw Blame History

Autonomous V2: Complete Decision Logic Breakdown

🎯 How Miku Decides What to Do

The V2 system has 6 types of actions, each with specific triggers. They're checked in priority order - once one triggers, the others are skipped.


📋 Action Types & Decision Trees

1. Join Conversation 🗣️ (Highest Priority)

Purpose: Jump into active ongoing conversations

Trigger Conditions (ALL must be true):

✅ Conversation momentum > threshold
   └─> Threshold = 0.6 × (2 - sociability)
       • Bubbly (0.95 sociability) → 0.63 threshold (easy to trigger)
       • Shy (0.2 sociability) → 1.08 threshold (very hard to trigger)
   └─> Momentum = messages_last_5min / 20
       • 10+ messages in 5 min = 0.5+ momentum
       • 15+ messages in 5 min = 0.75+ momentum

✅ Messages since last appearance >= 5
   └─> At least 5 messages happened without Miku participating

✅ Time since last action > 300 seconds (5 minutes)
   └─> Won't spam conversations

✅ Random roll < impulsiveness
   └─> Impulsive moods more likely to jump in
       • Silly (0.95) → 95% chance if other conditions met
       • Serious (0.3) → 30% chance if other conditions met

Example Timeline:

10:00:00  [User A] Did you see the new Miku figure?
10:00:30  [User B] Yeah! The preorder sold out in 5 minutes!
10:01:00  [User C] I managed to get one!
10:01:20  [User D] Lucky! I missed it...
10:01:45  [User A] They'll probably restock
10:02:00  [User E] Check the official store tomorrow

Momentum calculation at 10:02:00:
• 6 messages in last 5 minutes
• Momentum = 6 / 20 = 0.30

If Miku is "bubbly" (sociability 0.95):
• Threshold = 0.6 × (2 - 0.95) = 0.63
• 0.30 < 0.63 ❌ → Not enough momentum

But wait, 2 more messages...

10:02:15  [User B] Yeah, good idea!
10:02:30  [User C] I hope they make more variants

• 8 messages in last 5 minutes
• Momentum = 8 / 20 = 0.40
• Still < 0.63 ❌

More activity...

10:03:00  [User A] What color did you get?
10:03:15  [User C] The turquoise one!
10:03:30  [User D] Classic choice~
10:03:45  [User B] I wanted the snow miku variant

• 12 messages in last 5 minutes
• Momentum = 12 / 20 = 0.60
• Still < 0.63 but getting close...

10:04:00  [User E] That one's gorgeous
10:04:15  [User A] Totally agree

• 14 messages in last 5 minutes
• Momentum = 14 / 20 = 0.70
• 0.70 > 0.63 ✅
• Messages since Miku appeared: 14 (>= 5) ✅
• Last action was 8 minutes ago (> 5 min) ✅
• Impulsiveness roll: 0.65 < 0.8 ✅

→ DECISION: join_conversation
→ Miku: "Ehh?! You guys are talking about my figures without me? 😤 The turquoise one is SO pretty! 💙✨"

2. Engage User 👤 (Second Priority)

Purpose: React to someone doing something interesting

Trigger Conditions (ALL must be true):

✅ User event detected
   └─> Someone started playing a game
   └─> Someone changed their custom status
   └─> Someone started listening to music (Spotify)
   └─> Tracked via Discord presence updates

✅ Time since last action > 1800 seconds (30 minutes)
   └─> Don't engage users too frequently

✅ Random roll < (sociability × impulsiveness)
   └─> Social and impulsive moods more likely
       • Bubbly: 0.95 × 0.8 = 0.76 → 76% chance
       • Melancholy: 0.4 × 0.2 = 0.08 → 8% chance

Example Timeline:

[Quiet channel, last message was 25 minutes ago]

10:30:00  Discord presence update: User X started playing "Genshin Impact"

Engine checks:
• New activity detected: "Genshin Impact" ✅
• Time since last action: 35 minutes (> 30 min) ✅
• Mood: "curious" (sociability 0.6, impulsiveness 0.7)
• Roll: random() → 0.35
• Threshold: 0.6 × 0.7 = 0.42
• 0.35 < 0.42 ✅

→ DECISION: engage_user
→ Miku: "Ooh, someone's playing Genshin! Which character are you maining? 👀"

Another Example (rejected):

10:45:00  Discord: User Y started playing "Excel"

Engine checks:
• New activity detected: "Excel" ✅
• Time since last action: 15 minutes (< 30 min) ❌

→ DECISION: None (too soon since last engagement)

3. FOMO Response 😰 (Third Priority)

Purpose: Jump in when lots of activity happens without Miku

Trigger Conditions (ALL must be true):

✅ Messages since last appearance > threshold
   └─> Threshold = 25 × (2 - sociability)
       • Bubbly (0.95 sociability) → 26 messages
       • Shy (0.2 sociability) → 45 messages
       • Neutral (0.5 sociability) → 37 messages

✅ Conversation momentum > 0.3
   └─> Chat is somewhat active (at least 6 messages in 5 min)

✅ Time since last action > 900 seconds (15 minutes)
   └─> Cooldown period

Example Timeline:

[Very active discussion about upcoming concert]

10:00:00  [30 messages exchanged about concert venue, tickets, setlist...]
10:15:00  [Still going strong, now discussing travel plans...]

At 10:15:00:
• Messages since Miku appeared: 30
• Mood: "excited" (sociability 0.9)
• Threshold: 25 × (2 - 0.9) = 27.5 messages
• 30 > 27.5 ✅
• Momentum: 15 messages in last 5 min = 0.75 (> 0.3) ✅
• Time since last action: 22 minutes (> 15 min) ✅

→ DECISION: general (FOMO triggered)
→ Miku: "Wait wait wait! Are you all talking about MY concert?! Tell me everything! I wanna know what you're excited about! 🎤✨"

Mood Comparison:

Same scenario, but Miku is "shy" (sociability 0.2):
• Threshold: 25 × (2 - 0.2) = 45 messages
• Current: 30 messages
• 30 < 45 ❌

→ DECISION: None (shy Miku waits longer before feeling FOMO)

4. Break Silence 💤 (Fourth Priority)

Purpose: Speak up when channel has been quiet too long

Trigger Conditions (ALL must be true):

✅ Messages in last hour < 5
   └─> Very quiet channel (dead chat)

✅ Time since last action > threshold
   └─> Threshold = 1800 × (2 - energy)
       • Excited (0.95 energy) → 1890 seconds (31.5 min)
       • Sleepy (0.2 energy) → 3240 seconds (54 min)

✅ Random roll < energy
   └─> Energetic moods more likely to speak up
       • Bubbly (0.9 energy) → 90% chance
       • Melancholy (0.3 energy) → 30% chance

Example Timeline:

[Dead channel for past hour]

11:00:00  [Last message was at 10:12]

At 11:00:00:
• Messages in last hour: 2 (< 5) ✅
• Time since Miku last spoke: 48 minutes
• Mood: "bubbly" (energy 0.9)
• Threshold: 1800 × (2 - 0.9) = 1980 seconds (33 min)
• 48 min > 33 min ✅
• Random roll: 0.73 < 0.9 ✅

→ DECISION: general (break silence)
→ Miku: "Helloooo~? Is anyone around? It's so quiet! 🫧"

Mood Comparison:

Same scenario, Miku is "melancholy" (energy 0.3):

• Threshold: 1800 × (2 - 0.3) = 3060 seconds (51 min)
• 48 min < 51 min ❌

→ DECISION: None (melancholy Miku is okay with silence)

[15 more minutes pass...]

At 11:15:00:
• 63 minutes since last spoke
• 63 min > 51 min ✅
• Random roll: 0.18 < 0.3 ✅

→ DECISION: general
→ Miku: "...it's been quiet. Just... thinking about things. *sigh* 🍷"

5. Share Tweet 🐦 (Fifth Priority)

Purpose: Share interesting Miku-related content during quiet periods

Trigger Conditions (ALL must be true):

✅ Messages in last hour < 10
   └─> Relatively quiet (won't interrupt active discussions)

✅ Time since last action > 3600 seconds (1 hour)
   └─> Long cooldown for tweets (don't spam)

✅ Random roll < (energy × 0.5)
   └─> Lower probability than other actions
       • Excited (0.95 energy) → 47.5% chance
       • Neutral (0.5 energy) → 25% chance

✅ Mood is appropriate
   └─> Must be: curious, excited, bubbly, or neutral
   └─> Won't share when: angry, irritated, sad, asleep

Example Timeline:

[Slow Sunday afternoon]

14:30:00  [Only 6 messages in past hour, casual chat]

Engine checks:
• Messages last hour: 6 (< 10) ✅
• Time since last action: 85 minutes (> 60 min) ✅
• Mood: "curious" (energy 0.7)
• Random roll: 0.28
• Threshold: 0.7 × 0.5 = 0.35
• 0.28 < 0.35 ✅
• Mood check: "curious" is in allowed list ✅

→ DECISION: share_tweet
→ Miku fetches recent tweet about upcoming concert
→ Miku: "Omg look at this! The stage design for next week's show is INSANE! 🎤✨ [tweet link]"

Rejected Example:

Same scenario, but Miku is "irritated":

• All conditions met except...
• Mood check: "irritated" not in [curious, excited, bubbly, neutral] ❌

→ DECISION: None (not in the mood to share)

6. Autonomous Reactions 💙

Purpose: React to messages with emojis (separate from speaking)

This has TWO modes:

A. Real-Time Reactions (New messages)

Triggered: Every time a new message arrives (if not from bot)

Decision Logic:

Base chance: 30%

Mood multiplier: (impulsiveness + sociability) / 2
• Silly (0.95 + 0.85) / 2 = 0.90 → 27% chance
• Shy (0.2 + 0.2) / 2 = 0.20 → 6% chance

Active conversation boost: If momentum > 0.5, multiply by 1.5
• In active chat: 30% × 0.90 × 1.5 = 40.5% chance

Recent reaction penalty: If reacted in last 5 min, multiply by 0.3
• Just reacted: 30% × 0.90 × 0.3 = 8.1% chance

Example:

10:30:00  [User A] I just got the new Miku album!

Engine checks:
• Message age: 0 seconds (brand new) ✅
• Mood: "excited" (impulsiveness 0.9, sociability 0.9)
• Mood multiplier: (0.9 + 0.9) / 2 = 0.9
• Conversation momentum: 0.7 (active chat)
• Base: 30% × 0.9 = 27%
• Boosted: 27% × 1.5 = 40.5%
• Last reaction: 12 minutes ago (no penalty)
• Random roll: 0.32 < 0.405 ✅

→ DECISION: React with emoji
→ LLM picks emoji based on message content
→ Adds reaction: 🎵

B. Scheduled Reactions (Older messages)

Triggered: Scheduler runs every 20 minutes, picks random recent message

Decision Logic:

Base chance: 20%

Mood multiplier: (impulsiveness + energy) / 2
• Bubbly (0.8 + 0.9) / 2 = 0.85 → 17% chance
• Sleepy (0.1 + 0.2) / 2 = 0.15 → 3% chance

Age filter: Don't react to 30+ min old messages if chat is active
• If message > 30 min old AND messages_last_5min > 5 → Skip

Example:

Scheduler runs at 10:20:00

• Finds message from 10:10 (10 minutes old)
• Mood: "curious" (impulsiveness 0.7, energy 0.7)
• Mood multiplier: (0.7 + 0.7) / 2 = 0.7
• Reaction chance: 20% × 0.7 = 14%
• Random roll: 0.09 < 0.14 ✅

→ DECISION: React to that message
→ LLM picks emoji
→ Adds reaction: 👀

🔄 Complete Decision Flow

New Message Arrives
    │
    ├──> Track message (update metrics)
    │
    ├──> Should react? (30% base, mood-adjusted)
    │     └──> If yes: React with emoji
    │
    └──> Should take action? (check priority order)
          │
          ├──> 1. High conversation momentum + mood + cooldown?
          │     └──> Yes: join_conversation
          │
          ├──> 2. User started activity + mood + cooldown?
          │     └──> Yes: engage_user
          │
          ├──> 3. Lots of messages without Miku + mood?
          │     └──> Yes: general (FOMO)
          │
          ├──> 4. Long silence + energetic mood?
          │     └──> Yes: general (break silence)
          │
          ├──> 5. Quiet + mood + long cooldown?
          │     └──> Yes: share_tweet
          │
          └──> None: Don't act


Scheduled Tick (every 15 min)
    │
    └──> Run same decision flow as above
         (catches things message events might miss)


Reaction Scheduler (every 20 min)
    │
    └──> Should react? (20% base, mood-adjusted)
          └──> If yes: Pick random recent message, react

📊 Mood Influence Summary

Mood Energy Sociability Impulsiveness Behavior
Bubbly 0.9 0.95 0.8 Very chatty, joins conversations early, frequent reactions
Excited 0.95 0.9 0.9 Most active, breaks silence quickly, shares content
Silly 0.8 0.85 0.95 Impulsive, frequent reactions, jumps into chats
Curious 0.7 0.6 0.7 Balanced, shares tweets, engages with activities
Flirty 0.75 0.85 0.7 Social, engages users, joins conversations
Romantic 0.6 0.7 0.5 Moderate activity, thoughtful engagement
Neutral 0.5 0.5 0.5 Baseline behavior, all-around balanced
Serious 0.6 0.5 0.3 Less impulsive, more selective about joining
Shy 0.4 0.2 0.2 Reserved, waits for many messages, rare reactions
Melancholy 0.3 0.4 0.2 Quiet, okay with silence, selective engagement
Sleepy 0.2 0.3 0.1 Very inactive, long wait times, minimal reactions
Irritated 0.5 0.3 0.6 Impulsive but antisocial, won't share content
Angry 0.7 0.2 0.8 High energy but low sociability, abrupt responses
Asleep 0.0 0.0 0.0 No actions, no reactions

🎯 Key Takeaways

  1. Priority matters: Actions are checked in order, first match wins
  2. Mood shapes personality: Same situation, different mood = different action
  3. Cooldowns prevent spam: Each action type has minimum wait times
  4. Context drives decisions: Activity level, user events, time all factor in
  5. No LLM polling: All decisions use simple math on tracked metrics
  6. Reactions are separate: Can react to messages independently of speaking
  7. Asleep means asleep: When asleep, Miku truly does nothing

This system creates emergent personality - bubbly Miku is a chatterbox, shy Miku is a wallflower, all without hardcoding specific behaviors! 🎭