Releases: agentesupersecreto/SMA_AIchat
Release list
AIchat_v1.3
IMPORTANT: If you were already using version 1.2, delete system_prompt.txt from the Some_Modeling_Agency\BepInEx\plugins\AIchat folder, as that file has been updated in the code. If you had previously edited system_prompt.txt, you can leave it as is; however, if the prompt causes issues, allow a new one to be created automatically.
The readme has also been updated with new usage instructions.
Ollama server URL changed from http://localhost:11434/api/generate to http://localhost:11434/api/chat so if you're going to use this version, make sure to change it.
New Files Created
[PsychologyEngine.cs] — The Brain
The central "Stream of Consciousness" engine. On character bind:
- Reads 16 base-game personality modifiers from
Personalidad - Performs dice rolls using personality traits as seeds (±15% variance)
- Initializes 10 keyword categories and extended mood parameters
10 Keyword Categories (0-100 intensity, updated per message):
- Flattery, Intimidation, Seduction, Professionalism, Humor
- Empathy, Dominance, Vulnerability, Negotiation, Provocation
Personality Accelerators — permanent traits that multiply keyword effects:
- High
pervertido→ seduction keywords have 2x effect on atmosphere - High
sumiso→ dominance keywords boost consent faster - High
timido→ intimidation increases disgust faster
Extended Mood Parameters (mod-only, not in base game):
- Boredom: increases on bland messages, decreases on interesting ones
- Disgust: provocation + intimidation increase it
- Thawing: seduction + flattery warm her up
- Relief: empathy + humor bring relief
Atmosphere (0-100): Cold → Neutral → Warm → Hot → Intimate
Modeling Stages (replaces old binary PreferencesDiscussed):
Discuss→Photos→Posing→Lingerie→Erotic- Auto-progression based on atmosphere + thawing thresholds
[ConversationMemory.cs] — Long-Term Memory
- Rolling summary: injected as
[MEMORY]block in system prompt - Topic tagging: auto-detects important events (agreements, refusals, player name)
- Persistence: saves/loads per character to
AIchat/memory/mem_{charId}.txt - Max 20 tags to prevent token bloat
[SpamFilter.cs] — Event Deduplication
- Cooldown: minimum 1.5s between system messages
- Dedup: identical messages blocked within 10s window
- Batching: rapid-fire events grouped into
⚡ (3 events) msg1 | msg2 | msg3 - Toggle: on/off in settings panel
Modified Files
[ChatWindow.cs] — Major UX Overhaul
+ Enter to send messages (was already Enter, now explicit)
+ Shift+Enter for line breaks in input
+ Auto-focus on text input when panel opens
+ Focus removed from input after sending
+ Animated "⏳ Thinking..." status with provider name
+ Chat history persistence per character (AIchat/history/chat_{charId}.txt)
+ Debug panel (toggle via "Debug" button):
- Psych state values (atmosphere, boredom, disgust, thawing, relief)
- All 10 keyword strengths
- Personality accelerators
- Memory tags and turn count
+ Stage + Vibe display in chat header
+ Spam filter toggle in settings
+ "AllowOpenMouthCommand" toggle in settings
- Removed PreferencesDiscussed gate (stages replace it)[PromptBuilder.cs] — Token-Optimized Rewrite
Old prompt: ~1500-2000 tokens of verbose prose.
New prompt: ~600-800 tokens of compact key:value notation.
- "You are wearing the following pieces of clothing: camisa, falda."
+ [CLOTHES] camisa, falda
- "[CORE PERSONALITY TRAITS] Perverted, Exhibitionist, Submissive, Extrovert(80), Submissive(60)..."
+ [PERSONA] Perverted,Exhibitionist,Submissive Perv:80 Sub:60 Dom:20 Shy:15 Extro:85
- "[HIDDEN TRAITS & KINKS (0-1)] gustoPorPervertidos(0.800), facilidadParaDesHielar(0.600)..."
+ [TRAITS] LikesPervs:0.80 EaseOfThawing:0.60 Patience:0.45 ...
- "[EMOTIONAL STATE (0-100%)] Arousal: 45%, Pleasure: 30%, Joy: 60%..."
+ [FEELING] She is currently aroused, content, warming up to intimacy.
+ [VIBE] Warm(55) [XMOOD] Thawing:40 [KWDS] Seduc:35 Flat:28 [STAGE] Photos
+ [MEMORY] Player complimented her several times...
+ [FACTS] She agreed to photos. Player's name: John.Key changes:
- Human-readable trait names:
gustoPorPervertidos→LikesPervs - Top 15 traits only: ranked by distance from 0.5 midpoint (saves tokens)
- Natural-language mood: replaces numeric emotion events
- Work info injected:
Hired:Y Salary:$100 Commission:30% Job:modeling - Memory block: summary + fact tags from ConversationMemory
- Backward-compatible: still reads
system_prompt.txttemplates with new placeholders
[AIResponseProcessor.cs]
+ PsychologyEngine processes AI responses (atmosphere shifts)
+ SpamFilter gates system messages (dedup + cooldown)
+ ConversationMemory auto-tags AI responses
+ History auto-saved after each AI response[DialogBehaviour.cs]
+ PsychologyEngine instance (initialized on character bind)
+ ConversationMemory instance (bound + loaded per character)
+ SpamFilter instance (flushes batched events in Update)
+ GetCharacterRoot() helper method
+ AllowOpenMouthCommand config field
+ SpamFilterEnabled config field
+ ModelingStage replaces PreferencesDiscussed[ChatMessage.cs]
+ DateTime Timestamp field
+ ToLine() serialization (pipe-separated format)
+ FromLine() deserialization[CommandExecutor.cs]
+ open_mouth command — opens jaw via IControladorDeJaw + ModificadorDeFloat (25° angle)
+ close_mouth command — closes jaw (0° angle)
+ AllowOpenMouthCommand toggle check
+ using Assets._ReusableScripts.CuchiCuchi._CharactersBasicsThe mouth commands work by:
- Finding
IControladorDeJawon the character root - Getting the jaw's x-axis
OrdenesDeIDwithobtenerMaximoAbsolutoorder type - Obtaining a
ModificadorDeFloatand setting its value to 25° (open) or 0° (close)
Architecture Diagram
graph TD
A["Player Message"] --> B["ChatWindow"]
B --> C["PsychologyEngine.ProcessPlayerMessage"]
C --> D["Keyword Detection"]
C --> E["Atmosphere Shift"]
C --> F["Mood Shifts"]
C --> G["Stage Progression"]
B --> H["API Client"]
H --> I["PromptBuilder.GenerateSystemPrompt"]
I --> J["Compact Identity + Traits"]
I --> K["PsychEngine.GenerateContextBlock"]
I --> L["PsychEngine.GenerateMoodDescription"]
I --> M["ConversationMemory.GenerateMemoryBlock"]
H --> N["AI Response"]
N --> O["AIResponseProcessor"]
O --> P["PsychEngine.ProcessAIResponse"]
O --> Q["SpamFilter.ShouldShow"]
O --> R["ConversationMemory.AutoTag"]
O --> S["CommandExecutor"]
S --> T["Game Commands"]
T --> U["open_mouth / close_mouth"]
T --> V["Existing commands"]AIchat v1.2 little fixes
[x] Create API/AIResponseProcessor.cs
[x] Refactor GemmaClient.cs, OllamaClient.cs, GeminiClient.cs to use the shared processor
[x] Fix "standA" bug in CommandExecutor.cs
[x] Rebalance Sentiment rage math in SentimentAnalyzer.cs
[x] Implement Harmony hook for SetTactilTo in HarmonyPatches.cs
AIchat v1.2
- Redefined the external system_prompt.txt file. If you already have something written in that file, move it out of the AIchat folder so a new one containing more data is generated.
- Fixed the bug that prevented the AI from detecting whether there was a new model and caused it to continue using the previous model's history
- Fixed “move to wall” and “move to desk” (I haven’t yet implemented the ability to do specific wall or desk pose).
- Added Gemma (LM Studios); not yet tested.
- Now, if you make a positive, romantic, or insulting comment to the model, her consent, arousal, or rage will change.
For developers:
- PromptBuilder.cs format instruction — Added explicit rules: "comando" must be null during normal chat, never invent commands not in the allowed list, never use "comando" in dialogo text, plus concrete examples (null vs actual command)
- GeminiClient.cs maxOutputTokens — Changed 150 → 512 in both the main response call (line 50) and the summarization call (line 178)
- GeminiClient.cs safer comando extraction — Now uses JsonHelper.ExtraerValorDeClaveJsonDesdeElFinal("comando") instead of ExtraerValorDeClaveJson, finding the last "comando" key (the real JSON schema key) instead of the first one (which could match inside dialogo text). Added the new method to JsonHelper.cs
- PromptBuilder.cs LANGUAGE RULE — Changed from "LANGUAGE RULE: You MUST strictly..." to "CRITICAL LANGUAGE RULE: You MUST strictly..." with explicit "NEVER switch languages mid-conversation" reinforcement
- Created Game/SentimentAnalyzer.cs — static class with keyword-based sentiment detection (English + Spanish) for three categories:
- Compliment → Joy +5, Consent +5
- Romantic → Arousal +8
- Insult → Rage +20, Joy −5, Consent −5
- Precedence: insult > romantic > compliment
- Null-guards all EmocionesFemeninas fields, clamps to [0, 100]
- Wired into ChatWindow.EnviarMensaje() — after adding user message to history, calls SentimentAnalyzer.ApplySentiment(), injects a system message with feedback, and shows the orange emotion feedback label
- Added AllowSentimentReactions toggle in Settings UI with tooltip
- Config save/load updated for AllowSentimentReactions key
- Bug fix — PromptBuilder isLocal:
- Changed Provider != ProviderType.Gemini (which made Gemini=local, Gemma=non-local) to Provider == ProviderType.Ollama || Provider == ProviderType.Gemma — now Ollama and Gemma correctly get the jailbreak + [CMD:] format, while Gemini gets JSON format