Spaces:
Running
Running
File size: 6,996 Bytes
3d50167 bcbb712 798bcc6 bcbb712 798bcc6 3d50167 d48e96e 3d50167 798bcc6 3d50167 798bcc6 3d50167 bcbb712 3d50167 798bcc6 3d50167 798bcc6 3d50167 bcbb712 3d50167 6236c66 3d50167 680de21 3d50167 bcbb712 3d50167 bcbb712 3d50167 bcbb712 3d50167 798bcc6 |
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 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
// ===== KIMI MEMORY MANAGER =====
class KimiMemory {
constructor(database) {
this.db = database;
this.preferences = {
voiceRate: 1.1,
voicePitch: 1.1,
voiceVolume: 0.8,
lastInteraction: null,
totalInteractions: 0,
emotionalState: "neutral"
};
this.isReady = false;
// affectionTrait will be loaded from database during init()
this.affectionTrait = 50; // Temporary default until loaded from DB
}
async init() {
if (!this.db) {
console.warn("Database not available, using local mode");
return;
}
try {
this.selectedCharacter = await this.db.getSelectedCharacter();
// Load affection trait from personality database with unified defaults
const charDefAff =
(window.KIMI_CHARACTERS && window.KIMI_CHARACTERS[this.selectedCharacter]?.traits?.affection) || null;
const unifiedDefaults = window.kimiEmotionSystem?.TRAIT_DEFAULTS || { affection: 55 };
const defaultAff = typeof charDefAff === "number" ? charDefAff : unifiedDefaults.affection;
this.affectionTrait = await this.db.getPersonalityTrait("affection", defaultAff, this.selectedCharacter);
this.preferences = {
voiceRate: await this.db.getPreference("voiceRate", 1.1),
voicePitch: await this.db.getPreference("voicePitch", 1.1),
voiceVolume: await this.db.getPreference("voiceVolume", 0.8),
lastInteraction: await this.db.getPreference(`lastInteraction_${this.selectedCharacter}`, null),
totalInteractions: await this.db.getPreference(`totalInteractions_${this.selectedCharacter}`, 0),
emotionalState: await this.db.getPreference(`emotionalState_${this.selectedCharacter}`, "neutral")
};
// affectionTrait already loaded above with coherent default
this.isReady = true;
this.updateFavorabilityBar();
} catch (error) {
console.error("KimiMemory initialization error:", error);
}
}
async saveConversation(userText, kimiResponse, tokenInfo = null) {
if (!this.db) return;
try {
const character = await this.db.getSelectedCharacter();
// Use global personality average for conversation favorability score
let relationshipLevel = 50; // fallback
try {
const traits = await this.db.getAllPersonalityTraits(character);
relationshipLevel = window.getPersonalityAverage ? window.getPersonalityAverage(traits) : 50;
} catch (error) {
console.warn("Error calculating relationship level for conversation:", error);
}
await this.db.saveConversation(userText, kimiResponse, relationshipLevel, new Date(), character);
// Legacy interactions counter kept for backward compatibility (not shown in UI now)
let total = await this.db.getPreference(`totalInteractions_${character}`, 0);
total = Number(total) + 1;
await this.db.setPreference(`totalInteractions_${character}`, total);
this.preferences.totalInteractions = total;
// Update tokens usage if provided (in/out)
if (tokenInfo && typeof tokenInfo.tokensIn === "number" && typeof tokenInfo.tokensOut === "number") {
const prevIn = Number(await this.db.getPreference(`totalTokensIn_${character}`, 0)) || 0;
const prevOut = Number(await this.db.getPreference(`totalTokensOut_${character}`, 0)) || 0;
await this.db.setPreference(`totalTokensIn_${character}`, prevIn + tokenInfo.tokensIn);
await this.db.setPreference(`totalTokensOut_${character}`, prevOut + tokenInfo.tokensOut);
}
let first = await this.db.getPreference(`firstInteraction_${character}`, null);
if (!first) {
first = new Date().toISOString();
await this.db.setPreference(`firstInteraction_${character}`, first);
}
this.preferences.lastInteraction = new Date().toISOString();
await this.db.setPreference(`lastInteraction_${character}`, this.preferences.lastInteraction);
} catch (error) {
console.error("Error saving conversation:", error);
}
}
async updateFavorability(change) {
try {
this.affectionTrait = Math.max(0, Math.min(100, this.affectionTrait + change));
if (this.db) {
await this.db.setPersonalityTrait("affection", this.affectionTrait, this.selectedCharacter);
}
this.updateFavorabilityBar();
} catch (error) {
console.error("Error updating favorability:", error);
}
}
async updateAffectionTrait() {
if (!this.db) return;
try {
this.selectedCharacter = await this.db.getSelectedCharacter();
// Use unified default that matches KimiEmotionSystem
const unifiedDefaults = window.kimiEmotionSystem?.TRAIT_DEFAULTS || { affection: 55 };
this.affectionTrait = await this.db.getPersonalityTrait(
"affection",
unifiedDefaults.affection,
this.selectedCharacter
);
this.updateFavorabilityBar();
} catch (error) {
console.error("Error updating affection trait:", error);
}
}
/**
* @deprecated Use updateGlobalPersonalityUI().
* Thin wrapper retained for backward compatibility only.
*/
updateFavorabilityBar() {
if (window.updateGlobalPersonalityUI) {
window.updateGlobalPersonalityUI();
}
}
async getGreeting() {
const i18n = window.kimiI18nManager;
// Use global personality average instead of just affection trait
let relationshipLevel = 50; // fallback
try {
if (this.db) {
const traits = await this.db.getAllPersonalityTraits(this.selectedCharacter);
relationshipLevel = window.getPersonalityAverage ? window.getPersonalityAverage(traits) : 50;
}
} catch (error) {
console.warn("Error calculating greeting level:", error);
}
if (relationshipLevel <= 10) {
return i18n?.t("greeting_low") || "Hello.";
}
if (relationshipLevel < 40) {
return i18n?.t("greeting_mid") || "Hi. How can I help you?";
}
return i18n?.t("greeting_high") || "Hello my love! π";
}
}
// Export to global scope
window.KimiMemory = KimiMemory;
export default KimiMemory;
|