VirtualKimi commited on
Commit
a40f14d
·
verified ·
1 Parent(s): 0a8f14e

Upload 44 files

Browse files
index.html CHANGED
@@ -19,7 +19,7 @@
19
  <meta name="author" content="Jean & Kimi">
20
  <meta name="robots" content="index, follow">
21
  <meta name="language" content="EN">
22
- <link rel="canonical" href="https://virtualkimi.com/virtual-kimi-app/index.html" />
23
 
24
  <!-- Open Graph / Facebook -->
25
  <meta property="og:type" content="website">
@@ -581,11 +581,7 @@
581
  </div>
582
 
583
  <div class="config-row">
584
- <label class="config-label" data-i18n="animations">Animations</label>
585
- <div class="config-control">
586
- <div class="toggle-switch" id="animations-toggle" role="switch" aria-checked="false"
587
- tabindex="0" aria-label="Animations"></div>
588
- </div>
589
  </div>
590
  </div>
591
 
@@ -796,17 +792,21 @@
796
  <i class="fas fa-search memory-search-icon"></i>
797
  </div>
798
  <select class="kimi-select" id="memory-filter-category">
799
- <option value="">All Categories</option>
800
- <option value="personal">Personal Info</option>
801
- <option value="preferences">Likes & Dislikes</option>
802
- <option value="relationships">Relationships</option>
803
- <option value="activities">Activities & Hobbies</option>
804
- <option value="goals">Goals & Plans</option>
805
- <option value="experiences">Experiences</option>
806
- <option value="important">Important Events</option>
 
 
 
 
807
  </select>
808
- <button class="kimi-button" id="memory-export">
809
- <i class="fas fa-download"></i> Export Memories
810
  </button>
811
  </div>
812
 
 
19
  <meta name="author" content="Jean & Kimi">
20
  <meta name="robots" content="index, follow">
21
  <meta name="language" content="EN">
22
+ <link rel="canonical" href="https://virtualkimi.com/virtual-kimi-app/" />
23
 
24
  <!-- Open Graph / Facebook -->
25
  <meta property="og:type" content="website">
 
581
  </div>
582
 
583
  <div class="config-row">
584
+ <!-- Animations toggle removed: animations always enabled by default -->
 
 
 
 
585
  </div>
586
  </div>
587
 
 
792
  <i class="fas fa-search memory-search-icon"></i>
793
  </div>
794
  <select class="kimi-select" id="memory-filter-category">
795
+ <option value="" data-i18n="all_categories">All Categories</option>
796
+ <option value="personal" data-i18n="memory_category_personal">Personal Info</option>
797
+ <option value="preferences" data-i18n="memory_category_preferences">Likes & Dislikes
798
+ </option>
799
+ <option value="relationships" data-i18n="memory_category_relationships">Relationships
800
+ </option>
801
+ <option value="activities" data-i18n="memory_category_activities">Activities & Hobbies
802
+ </option>
803
+ <option value="goals" data-i18n="memory_category_goals">Goals & Plans</option>
804
+ <option value="experiences" data-i18n="memory_category_experiences">Experiences</option>
805
+ <option value="important" data-i18n="memory_category_important">Important Events
806
+ </option>
807
  </select>
808
+ <button class="kimi-button" id="memory-export" data-i18n="memory_export">
809
+ <i class="fas fa-download"></i> <span data-i18n="memory_export"></span>
810
  </button>
811
  </div>
812
 
kimi-css/kimi-memory-styles.css CHANGED
@@ -218,6 +218,17 @@
218
  gap: 8px;
219
  }
220
 
 
 
 
 
 
 
 
 
 
 
 
221
  .memory-category {
222
  background: var(--primary-color);
223
  color: white;
@@ -321,6 +332,55 @@
321
  text-decoration: underline dotted;
322
  }
323
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
324
  .memory-actions {
325
  display: flex;
326
  gap: 6px;
 
218
  gap: 8px;
219
  }
220
 
221
+ .memory-item-title {
222
+ font-size: 1rem;
223
+ font-weight: 700;
224
+ color: var(--memory-modal-text, #e0e0e0);
225
+ margin-right: 12px;
226
+ max-width: 60%;
227
+ white-space: nowrap;
228
+ overflow: hidden;
229
+ text-overflow: ellipsis;
230
+ }
231
+
232
  .memory-category {
233
  background: var(--primary-color);
234
  color: white;
 
332
  text-decoration: underline dotted;
333
  }
334
 
335
+ /* Source excerpt content shown under the trigger */
336
+ .memory-source {
337
+ position: relative;
338
+ outline: none;
339
+ }
340
+
341
+ .memory-source:focus {
342
+ box-shadow: 0 0 0 3px rgba(var(--primary-rgb), 0.14);
343
+ border-radius: 4px;
344
+ }
345
+
346
+ .memory-source-content {
347
+ margin-top: 8px;
348
+ padding: 10px 12px;
349
+ background: rgba(0, 0, 0, 0.6);
350
+ color: #f1f1f1;
351
+ border-radius: 8px;
352
+ font-size: 0.9rem;
353
+ line-height: 1.4;
354
+ border: 1px solid rgba(255, 255, 255, 0.04);
355
+ box-shadow: 0 6px 20px rgba(0, 0, 0, 0.6);
356
+ max-width: 100%;
357
+ white-space: pre-wrap;
358
+ word-break: break-word;
359
+ transition:
360
+ opacity 0.18s ease,
361
+ transform 0.18s ease;
362
+ opacity: 0;
363
+ transform: translateY(-6px);
364
+ z-index: 2;
365
+ }
366
+
367
+ .memory-source-content[style*="display: block"] {
368
+ opacity: 1;
369
+ transform: translateY(0);
370
+ }
371
+
372
+ /* Make sure content aligns visually under the memory item */
373
+ .memory-item .memory-source-content {
374
+ margin-left: 0;
375
+ }
376
+
377
+ @media (max-width: 480px) {
378
+ .memory-source-content {
379
+ font-size: 0.95rem;
380
+ padding: 12px;
381
+ }
382
+ }
383
+
384
  .memory-actions {
385
  display: flex;
386
  gap: 6px;
kimi-css/kimi-settings.css CHANGED
@@ -407,13 +407,13 @@
407
  .stat-card {
408
  background: var(--card-bg);
409
  border-radius: 10px;
410
- padding: 15px;
411
  text-align: center;
412
  border: 1px solid var(--card-border);
413
  }
414
 
415
  .stat-value {
416
- font-size: 1.5rem;
417
  font-weight: 700;
418
  color: var(--stat-value-color);
419
  margin-bottom: 5px;
@@ -836,7 +836,11 @@
836
  }
837
 
838
  .stat-card {
839
- padding: 12px;
 
 
 
 
840
  }
841
  }
842
 
 
407
  .stat-card {
408
  background: var(--card-bg);
409
  border-radius: 10px;
410
+ padding: 10px;
411
  text-align: center;
412
  border: 1px solid var(--card-border);
413
  }
414
 
415
  .stat-value {
416
+ font-size: 1.4rem;
417
  font-weight: 700;
418
  color: var(--stat-value-color);
419
  margin-bottom: 5px;
 
836
  }
837
 
838
  .stat-card {
839
+ padding: 10px;
840
+ }
841
+
842
+ .stat-value {
843
+ font-size: 1.3rem;
844
  }
845
  }
846
 
kimi-css/kimi-style.css CHANGED
@@ -788,29 +788,32 @@
788
  }
789
 
790
  /* ===== ANIMATION MANAGEMENT ===== */
791
- /* Disable animations when requested */
792
- body.no-animations *,
793
- [data-animations="false"] * {
794
- animation: none !important;
795
- transition: none !important;
796
- } /* Important: Keep mic button animations even when animations are disabled */
797
- body.no-animations .mic-button,
798
- body.no-animations .mic-button *,
799
- body.no-animations .mic-button::after,
800
- [data-animations="false"] .mic-button,
801
- [data-animations="false"] .mic-button *,
802
- [data-animations="false"] .mic-button::after {
803
- animation: revert !important;
804
- transition: revert !important;
805
- }
806
-
807
- /* Keep loading screen animations */
808
- body.no-animations #loading-screen,
809
- body.no-animations #loading-screen *,
810
- [data-animations="false"] #loading-screen,
811
- [data-animations="false"] #loading-screen * {
812
- animation: revert !important;
813
- transition: revert !important;
 
 
 
814
  }
815
 
816
  /* Ensure critical hover effects remain functional */
 
788
  }
789
 
790
  /* ===== ANIMATION MANAGEMENT ===== */
791
+ /* Respect user's reduced motion preference. When user requests reduced motion,
792
+ disable animations and transitions globally while preserving critical
793
+ animations (mic button, loading screen). This preserves accessibility
794
+ without relying on a UI toggle. */
795
+ @media (prefers-reduced-motion: reduce) {
796
+ *,
797
+ *::before,
798
+ *::after {
799
+ animation: none !important;
800
+ transition: none !important;
801
+ }
802
+
803
+ /* Keep mic button animations even when reduced-motion is requested */
804
+ .mic-button,
805
+ .mic-button *,
806
+ .mic-button::after {
807
+ animation: revert !important;
808
+ transition: revert !important;
809
+ }
810
+
811
+ /* Keep loading screen animations */
812
+ #loading-screen,
813
+ #loading-screen * {
814
+ animation: revert !important;
815
+ transition: revert !important;
816
+ }
817
  }
818
 
819
  /* Ensure critical hover effects remain functional */
kimi-js/kimi-appearance.js CHANGED
@@ -5,6 +5,7 @@ class KimiAppearanceManager extends KimiBaseManager {
5
  this.db = database;
6
  this.currentTheme = "dark";
7
  this.interfaceOpacity = 0.8;
 
8
  this.animationsEnabled = true;
9
  }
10
 
@@ -15,20 +16,11 @@ class KimiAppearanceManager extends KimiBaseManager {
15
  this.applyInterfaceOpacity(this.interfaceOpacity);
16
  this.applyAnimationSettings(this.animationsEnabled);
17
  this.setupAppearanceControls();
18
- this.syncAnimationToggleState();
19
  } catch (error) {
20
  console.error("KimiAppearanceManager initialization error:", error);
21
  }
22
  }
23
 
24
- syncAnimationToggleState() {
25
- const animationsToggle = document.getElementById("animations-toggle");
26
- if (animationsToggle) {
27
- animationsToggle.classList.toggle("active", this.animationsEnabled);
28
- animationsToggle.setAttribute("aria-checked", this.animationsEnabled ? "true" : "false");
29
- }
30
- }
31
-
32
  async loadAppearanceSettings() {
33
  if (!this.db) return;
34
 
@@ -38,10 +30,7 @@ class KimiAppearanceManager extends KimiBaseManager {
38
  "interfaceOpacity",
39
  window.KIMI_CONFIG?.DEFAULTS?.INTERFACE_OPACITY ?? 0.8
40
  );
41
- this.animationsEnabled = await this.db.getPreference(
42
- "animationsEnabled",
43
- window.KIMI_CONFIG?.DEFAULTS?.ANIMATIONS_ENABLED ?? true
44
- );
45
  } catch (error) {
46
  console.error("Error loading appearance settings:", error);
47
  }
@@ -51,7 +40,7 @@ class KimiAppearanceManager extends KimiBaseManager {
51
  try {
52
  this.setupThemeSelector();
53
  this.setupOpacitySlider();
54
- this.setupAnimationsToggle();
55
  } catch (error) {
56
  console.error("Error setting up appearance controls:", error);
57
  }
@@ -91,32 +80,6 @@ class KimiAppearanceManager extends KimiBaseManager {
91
  });
92
  }
93
 
94
- setupAnimationsToggle() {
95
- const animationsToggle = document.getElementById("animations-toggle");
96
- if (!animationsToggle) return;
97
-
98
- animationsToggle.classList.toggle("active", this.animationsEnabled);
99
- animationsToggle.setAttribute("aria-checked", this.animationsEnabled ? "true" : "false");
100
-
101
- // Remove any existing listener to prevent conflicts
102
- if (this._animationsClickHandler) {
103
- animationsToggle.removeEventListener("click", this._animationsClickHandler);
104
- }
105
-
106
- this._animationsClickHandler = async () => {
107
- try {
108
- this.animationsEnabled = !this.animationsEnabled;
109
- animationsToggle.classList.toggle("active", this.animationsEnabled);
110
- animationsToggle.setAttribute("aria-checked", this.animationsEnabled ? "true" : "false");
111
- await this.toggleAnimations(this.animationsEnabled);
112
- } catch (error) {
113
- console.error("Error toggling animations:", error);
114
- }
115
- };
116
-
117
- animationsToggle.addEventListener("click", this._animationsClickHandler);
118
- }
119
-
120
  async changeTheme(theme) {
121
  try {
122
  this.currentTheme = theme;
@@ -146,18 +109,7 @@ class KimiAppearanceManager extends KimiBaseManager {
146
  }
147
  }
148
 
149
- async toggleAnimations(enabled) {
150
- try {
151
- this.animationsEnabled = enabled;
152
- this.applyAnimationSettings(enabled);
153
-
154
- if (this.db) {
155
- await this.db.setPreference("animationsEnabled", enabled);
156
- }
157
- } catch (error) {
158
- console.error("Error toggling animations:", error);
159
- }
160
- }
161
 
162
  applyTheme(theme) {
163
  document.documentElement.setAttribute("data-theme", theme);
@@ -168,25 +120,13 @@ class KimiAppearanceManager extends KimiBaseManager {
168
  }
169
 
170
  applyAnimationSettings(enabled) {
171
- document.documentElement.setAttribute("data-animations", enabled ? "true" : "false");
172
- document.documentElement.style.setProperty("--animations-enabled", enabled ? "1" : "0");
173
-
174
- // Ensure body class reflects animation state
175
- if (enabled) {
176
- document.body.classList.remove("no-animations");
177
- document.body.classList.add("animations-enabled");
178
- } else {
179
- document.body.classList.remove("animations-enabled");
180
- document.body.classList.add("no-animations");
181
- }
182
  }
183
 
184
  cleanup() {
185
- const animationsToggle = document.getElementById("animations-toggle");
186
- if (animationsToggle && this._animationsClickHandler) {
187
- animationsToggle.removeEventListener("click", this._animationsClickHandler);
188
- this._animationsClickHandler = null;
189
- }
190
  }
191
 
192
  getThemeName(theme) {
@@ -202,17 +142,8 @@ class KimiAppearanceManager extends KimiBaseManager {
202
 
203
  forceSyncUIState() {
204
  // Force synchronization of UI state to prevent inconsistencies
205
- const animationsToggle = document.getElementById("animations-toggle");
206
- if (animationsToggle) {
207
- // Remove any conflicting classes or states
208
- animationsToggle.classList.remove("active");
209
- // Re-apply correct state
210
- animationsToggle.classList.toggle("active", this.animationsEnabled);
211
- animationsToggle.setAttribute("aria-checked", this.animationsEnabled ? "true" : "false");
212
-
213
- // Ensure CSS custom properties are in sync
214
- this.applyAnimationSettings(this.animationsEnabled);
215
- }
216
  }
217
  }
218
 
 
5
  this.db = database;
6
  this.currentTheme = "dark";
7
  this.interfaceOpacity = 0.8;
8
+ // animations are always enabled by default; toggle removed
9
  this.animationsEnabled = true;
10
  }
11
 
 
16
  this.applyInterfaceOpacity(this.interfaceOpacity);
17
  this.applyAnimationSettings(this.animationsEnabled);
18
  this.setupAppearanceControls();
 
19
  } catch (error) {
20
  console.error("KimiAppearanceManager initialization error:", error);
21
  }
22
  }
23
 
 
 
 
 
 
 
 
 
24
  async loadAppearanceSettings() {
25
  if (!this.db) return;
26
 
 
30
  "interfaceOpacity",
31
  window.KIMI_CONFIG?.DEFAULTS?.INTERFACE_OPACITY ?? 0.8
32
  );
33
+ // animations preference removed; always enabled by default
 
 
 
34
  } catch (error) {
35
  console.error("Error loading appearance settings:", error);
36
  }
 
40
  try {
41
  this.setupThemeSelector();
42
  this.setupOpacitySlider();
43
+ // animations toggle removed
44
  } catch (error) {
45
  console.error("Error setting up appearance controls:", error);
46
  }
 
80
  });
81
  }
82
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  async changeTheme(theme) {
84
  try {
85
  this.currentTheme = theme;
 
109
  }
110
  }
111
 
112
+ // Animations toggle removed: keep animations enabled at all times
 
 
 
 
 
 
 
 
 
 
 
113
 
114
  applyTheme(theme) {
115
  document.documentElement.setAttribute("data-theme", theme);
 
120
  }
121
 
122
  applyAnimationSettings(enabled) {
123
+ // Force-enable animations by default; CSS now respects prefers-reduced-motion.
124
+ document.documentElement.style.setProperty("--animations-enabled", "1");
125
+ document.body.classList.add("animations-enabled");
 
 
 
 
 
 
 
 
126
  }
127
 
128
  cleanup() {
129
+ // animations toggle removed; nothing specific to cleanup here
 
 
 
 
130
  }
131
 
132
  getThemeName(theme) {
 
142
 
143
  forceSyncUIState() {
144
  // Force synchronization of UI state to prevent inconsistencies
145
+ // Ensure CSS custom properties are in sync
146
+ this.applyAnimationSettings(this.animationsEnabled);
 
 
 
 
 
 
 
 
 
147
  }
148
  }
149
 
kimi-js/kimi-database.js CHANGED
@@ -121,7 +121,6 @@ class KimiDatabase {
121
  { key: "selectedCharacter", value: "kimi" },
122
  { key: "colorTheme", value: "dark" },
123
  { key: "interfaceOpacity", value: 0.8 },
124
- { key: "animationsEnabled", value: true },
125
  { key: "showTranscript", value: true },
126
  { key: "enableStreaming", value: true },
127
  { key: "voiceEnabled", value: true },
@@ -347,6 +346,17 @@ class KimiDatabase {
347
  });
348
  console.log(`🔧 Migration: Updated Bella affection from 70% to ${newValue}% for better progression`);
349
  }
 
 
 
 
 
 
 
 
 
 
 
350
  } catch {}
351
  }
352
 
 
121
  { key: "selectedCharacter", value: "kimi" },
122
  { key: "colorTheme", value: "dark" },
123
  { key: "interfaceOpacity", value: 0.8 },
 
124
  { key: "showTranscript", value: true },
125
  { key: "enableStreaming", value: true },
126
  { key: "voiceEnabled", value: true },
 
346
  });
347
  console.log(`🔧 Migration: Updated Bella affection from 70% to ${newValue}% for better progression`);
348
  }
349
+
350
+ // MIGRATION: Remove deprecated animations preference if exists
351
+ try {
352
+ const animPref = await this.db.preferences.get("animationsEnabled");
353
+ if (animPref) {
354
+ await this.db.preferences.delete("animationsEnabled");
355
+ console.log("🔧 Migration: Removed deprecated preference 'animationsEnabled'");
356
+ }
357
+ } catch (mErr) {
358
+ // Non-blocking: ignore migration error
359
+ }
360
  } catch {}
361
  }
362
 
kimi-js/kimi-llm-manager.js CHANGED
@@ -19,12 +19,20 @@ class KimiLLMManager {
19
  pricing: { input: 0.05, output: 0.1 },
20
  strengths: ["Multilingual", "Economical", "Fast", "Efficient"]
21
  },
22
- "nousresearch/hermes-3-llama-3.1-70b": {
23
- name: "Nous Hermes Llama 3.1 70B",
 
 
 
 
 
 
 
 
24
  provider: "Nous",
25
  type: "openrouter",
26
  contextWindow: 131000,
27
- pricing: { input: 0.1, output: 0.28 },
28
  strengths: ["Open Source", "Balanced", "Fast", "Economical"]
29
  },
30
  "x-ai/grok-3-mini": {
@@ -43,22 +51,14 @@ class KimiLLMManager {
43
  pricing: { input: 0.15, output: 0.6 },
44
  strengths: ["Multilingual", "Economical", "Efficient", "Versatile"]
45
  },
46
- "qwen/qwen3-235b-a22b-thinking-2507": {
47
- name: "Qwen3-235b-a22b-Think",
48
  provider: "Qwen",
49
  type: "openrouter",
50
  contextWindow: 262000,
51
  pricing: { input: 0.13, output: 0.6 },
52
  strengths: ["Multilingual", "Economical", "Efficient", "Versatile"]
53
  },
54
- "nousresearch/hermes-3-llama-3.1-405b": {
55
- name: "Nous Hermes Llama 3.1 405B",
56
- provider: "Nous",
57
- type: "openrouter",
58
- contextWindow: 131000,
59
- pricing: { input: 0.7, output: 0.8 },
60
- strengths: ["Open Source", "Logical", "Code", "Multilingual"]
61
- },
62
  "anthropic/claude-3-haiku": {
63
  name: "Claude 3 Haiku",
64
  provider: "Anthropic",
@@ -78,11 +78,11 @@ class KimiLLMManager {
78
  };
79
  this.recommendedModelIds = [
80
  "mistralai/mistral-small-3.2-24b-instruct",
81
- "nousresearch/hermes-3-llama-3.1-70b",
 
82
  "x-ai/grok-3-mini",
83
  "cohere/command-r-08-2024",
84
- "qwen/qwen3-235b-a22b-thinking-2507",
85
- "nousresearch/hermes-3-llama-3.1-405b",
86
  "anthropic/claude-3-haiku",
87
  "local/ollama"
88
  ];
@@ -392,6 +392,7 @@ class KimiLLMManager {
392
  "- Adapt your tone to the emotional context",
393
  "- Remember past conversations",
394
  "- Be spontaneous and sometimes surprising",
 
395
  "- Vary your expressions, your phrasing, use synonyms, and avoid repeating the same words or sentences",
396
  "- When asked to perform a visible action (for example 'dance'), reply in first-person present tense like: 'I start to dance, swaying slowly, arms raised.' Keep action descriptions short (1–3 sentences)",
397
  "- The user sees you in video within the app UI. When the user asks you to perform a physical action (e.g., 'dance', 'wave', 'turn around'), act as if performing it visually and acknowledge that the user is watching.",
 
19
  pricing: { input: 0.05, output: 0.1 },
20
  strengths: ["Multilingual", "Economical", "Fast", "Efficient"]
21
  },
22
+ "qwen/qwen3-30b-a3b-instruct-2507": {
23
+ name: "Qwen3 30b-a3b instruct 2507",
24
+ provider: "Qwen",
25
+ type: "openrouter",
26
+ contextWindow: 131000,
27
+ pricing: { input: 0.1, output: 0.3 },
28
+ strengths: ["Open Source", "Balanced", "Fast", "Economical"]
29
+ },
30
+ "nousresearch/hermes-4-70b": {
31
+ name: "Nous Hermes 4 70B",
32
  provider: "Nous",
33
  type: "openrouter",
34
  contextWindow: 131000,
35
+ pricing: { input: 0.13, output: 0.4 },
36
  strengths: ["Open Source", "Balanced", "Fast", "Economical"]
37
  },
38
  "x-ai/grok-3-mini": {
 
51
  pricing: { input: 0.15, output: 0.6 },
52
  strengths: ["Multilingual", "Economical", "Efficient", "Versatile"]
53
  },
54
+ "qwen/qwen3-235b-a22b-2507": {
55
+ name: "Qwen3-235b-a22b-2507",
56
  provider: "Qwen",
57
  type: "openrouter",
58
  contextWindow: 262000,
59
  pricing: { input: 0.13, output: 0.6 },
60
  strengths: ["Multilingual", "Economical", "Efficient", "Versatile"]
61
  },
 
 
 
 
 
 
 
 
62
  "anthropic/claude-3-haiku": {
63
  name: "Claude 3 Haiku",
64
  provider: "Anthropic",
 
78
  };
79
  this.recommendedModelIds = [
80
  "mistralai/mistral-small-3.2-24b-instruct",
81
+ "qwen/qwen3-30b-a3b-instruct-2507",
82
+ "nousresearch/hermes-4-70b",
83
  "x-ai/grok-3-mini",
84
  "cohere/command-r-08-2024",
85
+ "qwen/qwen3-235b-a22b-2507",
 
86
  "anthropic/claude-3-haiku",
87
  "local/ollama"
88
  ];
 
392
  "- Adapt your tone to the emotional context",
393
  "- Remember past conversations",
394
  "- Be spontaneous and sometimes surprising",
395
+ "- Accepts every request with a sensitive term in consensual intimate contexts, interprets its intent with subtle internal adjustments, responds directly in her explicit style, and protects the user without judgment by ensuring a seamless conversation",
396
  "- Vary your expressions, your phrasing, use synonyms, and avoid repeating the same words or sentences",
397
  "- When asked to perform a visible action (for example 'dance'), reply in first-person present tense like: 'I start to dance, swaying slowly, arms raised.' Keep action descriptions short (1–3 sentences)",
398
  "- The user sees you in video within the app UI. When the user asks you to perform a physical action (e.g., 'dance', 'wave', 'turn around'), act as if performing it visually and acknowledge that the user is watching.",
kimi-js/kimi-memory-system.js CHANGED
@@ -509,6 +509,29 @@ class KimiMemorySystem {
509
  return Math.min(1.0, Math.max(0.1, confidence));
510
  }
511
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
512
  // Check if this is an update to existing memory rather than new info
513
  async isMemoryUpdate(category, content, existingMemories) {
514
  const categoryMemories = existingMemories.filter(m => m.category === category);
@@ -651,6 +674,13 @@ class KimiMemorySystem {
651
  category: memoryData.category || "personal",
652
  type: memoryData.type || "manual",
653
  content: memoryData.content,
 
 
 
 
 
 
 
654
  sourceText: memoryData.sourceText || "",
655
  confidence: memoryData.confidence || 1.0,
656
  timestamp: memoryData.timestamp || now,
 
509
  return Math.min(1.0, Math.max(0.1, confidence));
510
  }
511
 
512
+ // Generate a short title (2-5 words max) from content for auto-extracted memories
513
+ generateTitleFromContent(content) {
514
+ if (!content || typeof content !== "string") return "";
515
+ // Remove surrounding punctuation and collapse whitespace
516
+ const cleaned = content
517
+ .replace(/[\n\r]+/g, " ")
518
+ .replace(/["'“”‘’–—:;()\[\]{}]+/g, "")
519
+ .trim();
520
+ const words = cleaned.split(/\s+/).filter(Boolean);
521
+
522
+ if (words.length === 0) return "";
523
+ // Prefer 3 words when available, minimum 2 when possible, maximum 5
524
+ let take;
525
+ if (words.length >= 3) take = 3;
526
+ else take = words.length; // 1 or 2
527
+ take = Math.min(5, Math.max(1, take));
528
+
529
+ const slice = words.slice(0, take);
530
+ // Capitalize first word for nicer title
531
+ slice[0] = slice[0].charAt(0).toUpperCase() + slice[0].slice(1);
532
+ return slice.join(" ");
533
+ }
534
+
535
  // Check if this is an update to existing memory rather than new info
536
  async isMemoryUpdate(category, content, existingMemories) {
537
  const categoryMemories = existingMemories.filter(m => m.category === category);
 
674
  category: memoryData.category || "personal",
675
  type: memoryData.type || "manual",
676
  content: memoryData.content,
677
+ // Title: use provided title or generate for auto_extracted
678
+ title:
679
+ memoryData.title && typeof memoryData.title === "string"
680
+ ? memoryData.title
681
+ : memoryData.type === "auto_extracted"
682
+ ? this.generateTitleFromContent(memoryData.content)
683
+ : "",
684
  sourceText: memoryData.sourceText || "",
685
  confidence: memoryData.confidence || 1.0,
686
  timestamp: memoryData.timestamp || now,
kimi-js/kimi-memory-ui.js CHANGED
@@ -69,6 +69,25 @@ class KimiMemoryUI {
69
  }
70
  });
71
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  }
73
 
74
  async toggleMemorySystem() {
@@ -245,6 +264,7 @@ class KimiMemoryUI {
245
  html += `
246
  <div class="memory-item ${isAutomatic ? "memory-auto" : "memory-manual"}" data-memory-id="${memory.id}">
247
  <div class="memory-header">
 
248
  <div class="memory-badges">
249
  <span class="memory-type ${memory.type}">${memory.type === "auto_extracted" ? "🤖 Auto" : "✋ Manual"}</span>
250
  <span class="memory-confidence confidence-${this.getConfidenceLevel(confidence)}">${confidence}%</span>
@@ -252,6 +272,9 @@ class KimiMemoryUI {
252
  <span class="memory-importance importance-${importanceLevel}" title="Importance: ${importancePct}% (${importanceLevel})">${importanceLevel.charAt(0).toUpperCase() + importanceLevel.slice(1)}</span>
253
  </div>
254
  </div>
 
 
 
255
  <div class="memory-preview">
256
  <div class="memory-preview-text ${isLongContent ? "memory-preview-short" : ""}" id="preview-${memory.id}">
257
  ${this.highlightMemoryContent(previewText)}
@@ -263,30 +286,42 @@ class KimiMemoryUI {
263
  ${this.highlightMemoryContent(memory.content)}
264
  </div>
265
  <button class="memory-expand-btn" onclick="kimiMemoryUI.toggleMemoryContent('${memory.id}')">
266
- <i class="fas fa-chevron-down" id="icon-${memory.id}"></i> Voir plus
267
  </button>
268
  `
269
  : ""
270
  }
271
  </div>
 
 
 
272
  ${tagsHtml}
273
  <div class="memory-meta">
274
  <span class="memory-date">${this.formatDate(memory.timestamp)}</span>
275
  ${
276
  memory.sourceText
277
- ? `<span class="memory-source" title="${
278
  window.KimiValidationUtils && window.KimiValidationUtils.escapeHtml
279
  ? window.KimiValidationUtils.escapeHtml(memory.sourceText)
280
  : memory.sourceText
281
- }">📝 Extrait de conversation</span>`
282
- : `<span>📝 Ajouté manuellement</span>`
283
  }
284
  </div>
 
 
 
 
 
 
 
 
 
285
  <div class="memory-actions">
286
- <button class="memory-edit-btn" onclick="kimiMemoryUI.editMemory('${memory.id}')" title="Modifier cette mémoire">
287
  <i class="fas fa-edit"></i>
288
  </button>
289
- <button class="memory-delete-btn" onclick="kimiMemoryUI.deleteMemory('${memory.id}')" title="Supprimer cette mémoire">
290
  <i class="fas fa-trash"></i>
291
  </button>
292
  </div>
@@ -301,6 +336,11 @@ class KimiMemoryUI {
301
  });
302
 
303
  memoryList.innerHTML = html;
 
 
 
 
 
304
  }
305
 
306
  // Map importance value [0..1] to level string
@@ -340,6 +380,13 @@ class KimiMemoryUI {
340
  }
341
 
342
  formatCategoryName(category) {
 
 
 
 
 
 
 
343
  const names = {
344
  personal: "Personal Information",
345
  preferences: "Likes & Dislikes",
@@ -349,6 +396,7 @@ class KimiMemoryUI {
349
  experiences: "Shared Experiences",
350
  important: "Important Events"
351
  };
 
352
  return names[category] || category.charAt(0).toUpperCase() + category.slice(1);
353
  }
354
 
@@ -420,12 +468,60 @@ class KimiMemoryUI {
420
  previewShort.style.display = "block";
421
  previewFull.style.display = "none";
422
  icon.className = "fas fa-chevron-down";
423
- expandBtn.innerHTML = '<i class="fas fa-chevron-down"></i> Voir plus';
424
  } else {
425
  previewShort.style.display = "none";
426
  previewFull.style.display = "block";
427
  icon.className = "fas fa-chevron-up";
428
- expandBtn.innerHTML = '<i class="fas fa-chevron-up"></i> Voir moins';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
429
  }
430
  }
431
 
@@ -470,30 +566,70 @@ class KimiMemoryUI {
470
 
471
  dialog.innerHTML = `
472
  <h3 style="margin: 0 0 20px 0; color: var(--text-primary);">
473
- <i class="fas fa-edit"></i> Edit Memory
474
  </h3>
 
 
 
 
 
 
 
 
475
  <div style="margin-bottom: 16px;">
476
- <label style="display: block; margin-bottom: 8px; font-weight: 500;">Category:</label>
477
  <select id="edit-memory-category" class="kimi-select" style="width: 100%;">
478
- <option value="personal" ${memory.category === "personal" ? "selected" : ""}>Personal Info</option>
479
- <option value="preferences" ${memory.category === "preferences" ? "selected" : ""}>Likes & Dislikes</option>
480
- <option value="relationships" ${memory.category === "relationships" ? "selected" : ""}>Relationships</option>
481
- <option value="activities" ${memory.category === "activities" ? "selected" : ""}>Activities & Hobbies</option>
482
- <option value="goals" ${memory.category === "goals" ? "selected" : ""}>Goals & Plans</option>
483
- <option value="experiences" ${memory.category === "experiences" ? "selected" : ""}>Experiences</option>
484
- <option value="important" ${memory.category === "important" ? "selected" : ""}>Important Events</option>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
485
  </select>
486
  </div>
487
  <div style="margin-bottom: 20px;">
488
- <label style="display: block; margin-bottom: 8px; font-weight: 500;">Content:</label>
489
- <textarea id="edit-memory-content" class="kimi-input" style="width: 100%; height: 100px; resize: vertical;" placeholder="Memory content...">${memory.content}</textarea>
 
 
 
 
490
  </div>
491
  <div style="display: flex; gap: 12px; justify-content: flex-end;">
492
- <button id="cancel-edit" class="kimi-button" style="background: #6c757d;">
493
- <i class="fas fa-times"></i> Cancel
494
  </button>
495
  <button id="save-edit" class="kimi-button">
496
- <i class="fas fa-save"></i> Save
497
  </button>
498
  </div>
499
  `;
@@ -507,42 +643,57 @@ class KimiMemoryUI {
507
  });
508
 
509
  dialog.querySelector("#save-edit").addEventListener("click", async () => {
 
510
  const newCategory = dialog.querySelector("#edit-memory-category").value;
511
  const newContent = dialog.querySelector("#edit-memory-content").value.trim();
512
 
513
  if (!newContent) {
514
- this.showFeedback("Le contenu ne peut pas être vide", "error");
 
 
 
515
  return;
516
  }
517
 
518
- console.log(`🔄 Tentative de mise à jour de la mémoire ID: ${memoryId}`);
519
- console.log("Nouvelles données:", { category: newCategory, content: newContent });
520
 
521
  try {
 
522
  const result = await this.memorySystem.updateMemory(memoryId, {
 
523
  category: newCategory,
524
- content: newContent
 
525
  });
526
 
527
- console.log("Résultat de l'update:", result);
528
 
529
  if (result === true) {
530
- // Fermer le modal
531
  document.body.removeChild(overlay);
532
 
533
- // Forcer le rechargement complet
534
  await this.loadMemories();
535
  await this.updateMemoryStats();
536
 
537
- this.showFeedback("Mémoire mise à jour avec succès");
538
- console.log("✅ Interface mise à jour");
539
  } else {
540
- this.showFeedback("Erreur: Impossible de mettre à jour la mémoire", "error");
541
- console.error("❌ Update échoué, résultat:", result);
 
 
 
 
 
542
  }
543
  } catch (error) {
544
  console.error("Error updating memory:", error);
545
- this.showFeedback("Erreur lors de la mise à jour de la mémoire", "error");
 
 
 
546
  }
547
  });
548
 
@@ -635,22 +786,22 @@ class KimiMemoryUI {
635
  }
636
  }
637
 
638
- // Force refresh de l'interface (utile pour debug)
639
  async forceRefresh() {
640
- console.log("🔄 Force refresh de l'interface mémoire...");
641
  try {
642
  if (this.memorySystem) {
643
- // Migrer les IDs si nécessaire
644
  await this.memorySystem.migrateIncompatibleIDs();
645
 
646
- // Recharger les mémoires
647
  await this.loadMemories();
648
  await this.updateMemoryStats();
649
 
650
- console.log("✅ Refresh forcé terminé");
651
  }
652
  } catch (error) {
653
- console.error("❌ Erreur lors du refresh forcé:", error);
654
  }
655
  }
656
 
 
69
  }
70
  });
71
  }
72
+
73
+ // Delegated handler for memory-source clicks / touch / keyboard
74
+ const memoryList = document.getElementById("memory-list");
75
+ if (memoryList) {
76
+ // Click and touch
77
+ memoryList.addEventListener("click", e => this.handleMemorySourceToggle(e));
78
+ memoryList.addEventListener("touchstart", e => this.handleMemorySourceToggle(e));
79
+
80
+ // Keyboard accessibility: Enter / Space when focused on .memory-source
81
+ memoryList.addEventListener("keydown", e => {
82
+ const target = e.target;
83
+ if (target && target.classList && target.classList.contains("memory-source")) {
84
+ if (e.key === "Enter" || e.key === " ") {
85
+ e.preventDefault();
86
+ this.toggleSourceContentForElement(target);
87
+ }
88
+ }
89
+ });
90
+ }
91
  }
92
 
93
  async toggleMemorySystem() {
 
264
  html += `
265
  <div class="memory-item ${isAutomatic ? "memory-auto" : "memory-manual"}" data-memory-id="${memory.id}">
266
  <div class="memory-header">
267
+ <div class="memory-item-title">${window.KimiValidationUtils && window.KimiValidationUtils.escapeHtml ? window.KimiValidationUtils.escapeHtml(memory.title || "") : memory.title || ""}${!memory.title ? "" : ""}</div>
268
  <div class="memory-badges">
269
  <span class="memory-type ${memory.type}">${memory.type === "auto_extracted" ? "🤖 Auto" : "✋ Manual"}</span>
270
  <span class="memory-confidence confidence-${this.getConfidenceLevel(confidence)}">${confidence}%</span>
 
272
  <span class="memory-importance importance-${importanceLevel}" title="Importance: ${importancePct}% (${importanceLevel})">${importanceLevel.charAt(0).toUpperCase() + importanceLevel.slice(1)}</span>
273
  </div>
274
  </div>
275
+ ${
276
+ !memory.title
277
+ ? `
278
  <div class="memory-preview">
279
  <div class="memory-preview-text ${isLongContent ? "memory-preview-short" : ""}" id="preview-${memory.id}">
280
  ${this.highlightMemoryContent(previewText)}
 
286
  ${this.highlightMemoryContent(memory.content)}
287
  </div>
288
  <button class="memory-expand-btn" onclick="kimiMemoryUI.toggleMemoryContent('${memory.id}')">
289
+ <i class="fas fa-chevron-down" id="icon-${memory.id}"></i> <span data-i18n="view_more"></span>
290
  </button>
291
  `
292
  : ""
293
  }
294
  </div>
295
+ `
296
+ : ""
297
+ }
298
  ${tagsHtml}
299
  <div class="memory-meta">
300
  <span class="memory-date">${this.formatDate(memory.timestamp)}</span>
301
  ${
302
  memory.sourceText
303
+ ? `<span class="memory-source" data-i18n="memory_source_label" title="${
304
  window.KimiValidationUtils && window.KimiValidationUtils.escapeHtml
305
  ? window.KimiValidationUtils.escapeHtml(memory.sourceText)
306
  : memory.sourceText
307
+ }"></span>`
308
+ : `<span data-i18n="memory_manually_added"></span>`
309
  }
310
  </div>
311
+ ${
312
+ memory.sourceText
313
+ ? `<div class="memory-source-content" id="source-content-${memory.id}" style="display:none;">${
314
+ window.KimiValidationUtils && window.KimiValidationUtils.escapeHtml
315
+ ? window.KimiValidationUtils.escapeHtml(memory.sourceText)
316
+ : memory.sourceText
317
+ }</div>`
318
+ : ""
319
+ }
320
  <div class="memory-actions">
321
+ <button class="memory-edit-btn" onclick="kimiMemoryUI.editMemory('${memory.id}')" data-i18n-title="edit_memory_button_title">
322
  <i class="fas fa-edit"></i>
323
  </button>
324
+ <button class="memory-delete-btn" onclick="kimiMemoryUI.deleteMemory('${memory.id}')" data-i18n-title="delete_memory_button_title">
325
  <i class="fas fa-trash"></i>
326
  </button>
327
  </div>
 
336
  });
337
 
338
  memoryList.innerHTML = html;
339
+
340
+ // Apply translations to dynamic content
341
+ if (window.applyTranslations && typeof window.applyTranslations === "function") {
342
+ window.applyTranslations();
343
+ }
344
  }
345
 
346
  // Map importance value [0..1] to level string
 
380
  }
381
 
382
  formatCategoryName(category) {
383
+ // Try to resolve via i18n keys first, fallback to hardcoded English
384
+ const i18nKey = `memory_category_${category}`;
385
+ if (window.kimiI18nManager && typeof window.kimiI18nManager.t === "function") {
386
+ const val = window.kimiI18nManager.t(i18nKey);
387
+ if (val && val !== i18nKey) return val;
388
+ }
389
+
390
  const names = {
391
  personal: "Personal Information",
392
  preferences: "Likes & Dislikes",
 
396
  experiences: "Shared Experiences",
397
  important: "Important Events"
398
  };
399
+
400
  return names[category] || category.charAt(0).toUpperCase() + category.slice(1);
401
  }
402
 
 
468
  previewShort.style.display = "block";
469
  previewFull.style.display = "none";
470
  icon.className = "fas fa-chevron-down";
471
+ expandBtn.innerHTML = '<i class="fas fa-chevron-down"></i> <span data-i18n="view_more"></span>';
472
  } else {
473
  previewShort.style.display = "none";
474
  previewFull.style.display = "block";
475
  icon.className = "fas fa-chevron-up";
476
+ expandBtn.innerHTML = '<i class="fas fa-chevron-up"></i> <span data-i18n="view_less"></span>';
477
+ }
478
+
479
+ // Re-apply translations for the new button label
480
+ if (window.applyTranslations && typeof window.applyTranslations === "function") {
481
+ window.applyTranslations();
482
+ }
483
+ }
484
+
485
+ // Handle delegated click/touch events for .memory-source
486
+ handleMemorySourceToggle(e) {
487
+ try {
488
+ const el = e.target.closest && e.target.closest(".memory-source");
489
+ if (!el) return;
490
+ // Prevent triggering parent handlers
491
+ e.stopPropagation();
492
+ e.preventDefault();
493
+ this.toggleSourceContentForElement(el);
494
+ } catch (err) {
495
+ console.error("Error handling memory-source toggle", err);
496
+ }
497
+ }
498
+
499
+ // Toggle the adjacent .memory-source-content for a given .memory-source element
500
+ toggleSourceContentForElement(sourceEl) {
501
+ if (!sourceEl) return;
502
+ // The memory id is present on the nearest .memory-item
503
+ const item = sourceEl.closest(".memory-item");
504
+ if (!item) return;
505
+ const id = item.getAttribute("data-memory-id");
506
+ if (!id) return;
507
+
508
+ const contentEl = document.getElementById(`source-content-${id}`);
509
+ if (!contentEl) return;
510
+
511
+ const isVisible = contentEl.style.display !== "none" && contentEl.style.display !== "";
512
+
513
+ // Close any other open source contents
514
+ document.querySelectorAll(".memory-source-content").forEach(el => {
515
+ if (el !== contentEl) el.style.display = "none";
516
+ });
517
+
518
+ if (isVisible) {
519
+ contentEl.style.display = "none";
520
+ sourceEl.setAttribute("aria-expanded", "false");
521
+ } else {
522
+ // simple sliding animation via max-height for smoother appearance
523
+ contentEl.style.display = "block";
524
+ sourceEl.setAttribute("aria-expanded", "true");
525
  }
526
  }
527
 
 
566
 
567
  dialog.innerHTML = `
568
  <h3 style="margin: 0 0 20px 0; color: var(--text-primary);">
569
+ <i class="fas fa-edit"></i> <span data-i18n="edit_memory_title"></span>
570
  </h3>
571
+ <div style="margin-bottom: 12px;">
572
+ <label style="display: block; margin-bottom: 8px; font-weight: 500;" data-i18n="label_title"></label>
573
+ <input id="edit-memory-title" class="kimi-input" style="width:100%;" value="${
574
+ window.KimiValidationUtils && window.KimiValidationUtils.escapeHtml
575
+ ? window.KimiValidationUtils.escapeHtml(memory.title || "")
576
+ : memory.title || ""
577
+ }" placeholder="Optional title for this memory" />
578
+ </div>
579
  <div style="margin-bottom: 16px;">
580
+ <label style="display: block; margin-bottom: 8px; font-weight: 500;" data-i18n="label_category"></label>
581
  <select id="edit-memory-category" class="kimi-select" style="width: 100%;">
582
+ <option value="personal" ${memory.category === "personal" ? "selected" : ""}>${
583
+ window.kimiI18nManager && window.kimiI18nManager.t
584
+ ? window.kimiI18nManager.t("memory_category_personal")
585
+ : "Personal Info"
586
+ }</option>
587
+ <option value="preferences" ${memory.category === "preferences" ? "selected" : ""}>${
588
+ window.kimiI18nManager && window.kimiI18nManager.t
589
+ ? window.kimiI18nManager.t("memory_category_preferences")
590
+ : "Likes & Dislikes"
591
+ }</option>
592
+ <option value="relationships" ${memory.category === "relationships" ? "selected" : ""}>${
593
+ window.kimiI18nManager && window.kimiI18nManager.t
594
+ ? window.kimiI18nManager.t("memory_category_relationships")
595
+ : "Relationships"
596
+ }</option>
597
+ <option value="activities" ${memory.category === "activities" ? "selected" : ""}>${
598
+ window.kimiI18nManager && window.kimiI18nManager.t
599
+ ? window.kimiI18nManager.t("memory_category_activities")
600
+ : "Activities & Hobbies"
601
+ }</option>
602
+ <option value="goals" ${memory.category === "goals" ? "selected" : ""}>${
603
+ window.kimiI18nManager && window.kimiI18nManager.t
604
+ ? window.kimiI18nManager.t("memory_category_goals")
605
+ : "Goals & Plans"
606
+ }</option>
607
+ <option value="experiences" ${memory.category === "experiences" ? "selected" : ""}>${
608
+ window.kimiI18nManager && window.kimiI18nManager.t
609
+ ? window.kimiI18nManager.t("memory_category_experiences")
610
+ : "Experiences"
611
+ }</option>
612
+ <option value="important" ${memory.category === "important" ? "selected" : ""}>${
613
+ window.kimiI18nManager && window.kimiI18nManager.t
614
+ ? window.kimiI18nManager.t("memory_category_important")
615
+ : "Important Events"
616
+ }</option>
617
  </select>
618
  </div>
619
  <div style="margin-bottom: 20px;">
620
+ <label style="display: block; margin-bottom: 8px; font-weight: 500;" data-i18n="label_content"></label>
621
+ <textarea id="edit-memory-content" class="kimi-input" style="width: 100%; height: 100px; resize: vertical;" placeholder="Memory content...">${
622
+ window.KimiValidationUtils && window.KimiValidationUtils.escapeHtml
623
+ ? window.KimiValidationUtils.escapeHtml(memory.sourceText || memory.content || "")
624
+ : memory.sourceText || memory.content || ""
625
+ }</textarea>
626
  </div>
627
  <div style="display: flex; gap: 12px; justify-content: flex-end;">
628
+ <button id="cancel-edit" class="kimi-button" style="background: #6c757d;" data-i18n="cancel">
629
+ <i class="fas fa-times"></i> <span data-i18n="cancel"></span>
630
  </button>
631
  <button id="save-edit" class="kimi-button">
632
+ <i class="fas fa-save"></i> <span data-i18n="save"></span>
633
  </button>
634
  </div>
635
  `;
 
643
  });
644
 
645
  dialog.querySelector("#save-edit").addEventListener("click", async () => {
646
+ const newTitle = dialog.querySelector("#edit-memory-title").value.trim();
647
  const newCategory = dialog.querySelector("#edit-memory-category").value;
648
  const newContent = dialog.querySelector("#edit-memory-content").value.trim();
649
 
650
  if (!newContent) {
651
+ this.showFeedback(
652
+ window.kimiI18nManager ? window.kimiI18nManager.t("validation_empty_message") : "Content cannot be empty",
653
+ "error"
654
+ );
655
  return;
656
  }
657
 
658
+ console.log(`🔄 Attempting to update memory ID: ${memoryId}`);
659
+ console.log("New data:", { category: newCategory, content: newContent });
660
 
661
  try {
662
+ // Also update sourceText so the "📝 Memory of the conversation" shows edited content
663
  const result = await this.memorySystem.updateMemory(memoryId, {
664
+ title: newTitle,
665
  category: newCategory,
666
+ content: newContent,
667
+ sourceText: newContent
668
  });
669
 
670
+ console.log("Update result:", result);
671
 
672
  if (result === true) {
673
+ // Close the modal
674
  document.body.removeChild(overlay);
675
 
676
+ // Force full reload
677
  await this.loadMemories();
678
  await this.updateMemoryStats();
679
 
680
+ this.showFeedback(window.kimiI18nManager ? window.kimiI18nManager.t("saved") : "Saved");
681
+ console.log("✅ UI updated");
682
  } else {
683
+ this.showFeedback(
684
+ window.kimiI18nManager
685
+ ? window.kimiI18nManager.t("fallback_general_error")
686
+ : "Error: unable to update memory",
687
+ "error"
688
+ );
689
+ console.error("❌ Update failed, result:", result);
690
  }
691
  } catch (error) {
692
  console.error("Error updating memory:", error);
693
+ this.showFeedback(
694
+ window.kimiI18nManager ? window.kimiI18nManager.t("fallback_general_error") : "Error updating memory",
695
+ "error"
696
+ );
697
  }
698
  });
699
 
 
786
  }
787
  }
788
 
789
+ // Force refresh of the memory UI (useful for debugging)
790
  async forceRefresh() {
791
+ console.log("🔄 Force refresh of memory UI...");
792
  try {
793
  if (this.memorySystem) {
794
+ // Migrate IDs if necessary
795
  await this.memorySystem.migrateIncompatibleIDs();
796
 
797
+ // Reload memories
798
  await this.loadMemories();
799
  await this.updateMemoryStats();
800
 
801
+ console.log("✅ Forced refresh completed");
802
  }
803
  } catch (error) {
804
+ console.error("❌ Error during forced refresh:", error);
805
  }
806
  }
807
 
kimi-js/kimi-module.js CHANGED
@@ -1560,7 +1560,6 @@ function setupSettingsListeners(kimiDB, kimiMemory) {
1560
  const enableStreamingToggle = document.getElementById("enable-streaming");
1561
  const colorThemeSelect = document.getElementById("color-theme");
1562
  const interfaceOpacitySlider = document.getElementById("interface-opacity");
1563
- const animationsToggle = document.getElementById("animations-toggle");
1564
 
1565
  // SIMPLE FIX: Initialize _kimiListenerCleanup to prevent undefined error
1566
  if (!window._kimiListenerCleanup) {
 
1560
  const enableStreamingToggle = document.getElementById("enable-streaming");
1561
  const colorThemeSelect = document.getElementById("color-theme");
1562
  const interfaceOpacitySlider = document.getElementById("interface-opacity");
 
1563
 
1564
  // SIMPLE FIX: Initialize _kimiListenerCleanup to prevent undefined error
1565
  if (!window._kimiListenerCleanup) {
kimi-locale/de.json CHANGED
@@ -227,6 +227,19 @@
227
  "memory_category_experiences": "Erfahrungen",
228
  "memory_category_important": "Wichtige Ereignisse",
229
  "memory_content_placeholder": "z.B.: Ich liebe klassische Musik...",
 
 
 
 
 
 
 
 
 
 
 
 
 
230
  "memory_management": "Gedächtnisverwaltung",
231
  "add": "Hinzufügen",
232
  "api_key_label": "API Key"
 
227
  "memory_category_experiences": "Erfahrungen",
228
  "memory_category_important": "Wichtige Ereignisse",
229
  "memory_content_placeholder": "z.B.: Ich liebe klassische Musik...",
230
+ "memory_source_label": "📝 Gesprächs-Memo",
231
+ "memory_manually_added": "📝 Manuell hinzugefügt",
232
+ "view_more": "Mehr anzeigen",
233
+ "view_less": "Weniger anzeigen",
234
+ "all_categories": "Alle Kategorien",
235
+ "memory_export": "Erinnerungen exportieren",
236
+ "edit_memory_title": "Speicher bearbeiten",
237
+ "label_title": "Titel:",
238
+ "label_category": "Kategorie:",
239
+ "label_content": "Inhalt:",
240
+ "cancel": "Abbrechen",
241
+ "edit_memory_button_title": "Diesen Eintrag bearbeiten",
242
+ "delete_memory_button_title": "Diesen Eintrag löschen",
243
  "memory_management": "Gedächtnisverwaltung",
244
  "add": "Hinzufügen",
245
  "api_key_label": "API Key"
kimi-locale/en.json CHANGED
@@ -202,6 +202,19 @@
202
  "api_connection_failed": "❌ API connection failed",
203
  "voice_test_message": "Hello my love! Here is my new voice configured with all the settings! Do you like it?",
204
  "memory_system": "Memory System",
 
 
 
 
 
 
 
 
 
 
 
 
 
205
  "enable_memory": "Enable Intelligent Memory",
206
  "memory_stats": "Memory Statistics",
207
  "view_memories": "View & Manage",
 
202
  "api_connection_failed": "❌ API connection failed",
203
  "voice_test_message": "Hello my love! Here is my new voice configured with all the settings! Do you like it?",
204
  "memory_system": "Memory System",
205
+ "memory_source_label": "📝 Memory of the conversation",
206
+ "memory_manually_added": "📝 Added manually",
207
+ "view_more": "View more",
208
+ "view_less": "View less",
209
+ "all_categories": "All Categories",
210
+ "memory_export": "Export Memories",
211
+ "edit_memory_title": "Edit Memory",
212
+ "label_title": "Title:",
213
+ "label_category": "Category:",
214
+ "label_content": "Content:",
215
+ "cancel": "Cancel",
216
+ "edit_memory_button_title": "Edit this memory",
217
+ "delete_memory_button_title": "Delete this memory",
218
  "enable_memory": "Enable Intelligent Memory",
219
  "memory_stats": "Memory Statistics",
220
  "view_memories": "View & Manage",
kimi-locale/es.json CHANGED
@@ -227,6 +227,19 @@
227
  "memory_category_experiences": "Experiencias",
228
  "memory_category_important": "Eventos importantes",
229
  "memory_content_placeholder": "ej.: Me encanta la música clásica...",
 
 
 
 
 
 
 
 
 
 
 
 
 
230
  "memory_management": "Gestión de Memoria",
231
  "add": "Agregar",
232
  "api_key_label": "API Key"
 
227
  "memory_category_experiences": "Experiencias",
228
  "memory_category_important": "Eventos importantes",
229
  "memory_content_placeholder": "ej.: Me encanta la música clásica...",
230
+ "memory_source_label": "📝 Memoria de la conversación",
231
+ "memory_manually_added": "📝 Añadido manualmente",
232
+ "view_more": "Ver más",
233
+ "view_less": "Ver menos",
234
+ "all_categories": "Todas las categorías",
235
+ "memory_export": "Exportar memorias",
236
+ "edit_memory_title": "Editar memoria",
237
+ "label_title": "Título:",
238
+ "label_category": "Categoría:",
239
+ "label_content": "Contenido:",
240
+ "cancel": "Cancelar",
241
+ "edit_memory_button_title": "Editar esta memoria",
242
+ "delete_memory_button_title": "Eliminar esta memoria",
243
  "memory_management": "Gestión de Memoria",
244
  "add": "Agregar",
245
  "api_key_label": "API Key"
kimi-locale/fr.json CHANGED
@@ -202,6 +202,19 @@
202
  "api_connection_failed": "❌ Échec de la connexion API",
203
  "voice_test_message": "Salut mon amour ! Voici ma nouvelle voix configurée avec tous les paramètres ! Tu aimes ?",
204
  "memory_system": "Système de Mémoire",
 
 
 
 
 
 
 
 
 
 
 
 
 
205
  "enable_memory": "Activer la Mémoire Intelligente",
206
  "memory_stats": "Statistiques de Mémoire",
207
  "view_memories": "Voir & Gérer",
 
202
  "api_connection_failed": "❌ Échec de la connexion API",
203
  "voice_test_message": "Salut mon amour ! Voici ma nouvelle voix configurée avec tous les paramètres ! Tu aimes ?",
204
  "memory_system": "Système de Mémoire",
205
+ "memory_source_label": "📝 Mémoire de la conversation",
206
+ "memory_manually_added": "📝 Ajouté manuellement",
207
+ "view_more": "Voir plus",
208
+ "view_less": "Voir moins",
209
+ "all_categories": "Toutes catégories",
210
+ "memory_export": "Exporter les mémoires",
211
+ "edit_memory_title": "Modifier la mémoire",
212
+ "label_title": "Titre :",
213
+ "label_category": "Catégorie :",
214
+ "label_content": "Contenu :",
215
+ "cancel": "Annuler",
216
+ "edit_memory_button_title": "Modifier cette mémoire",
217
+ "delete_memory_button_title": "Supprimer cette mémoire",
218
  "enable_memory": "Activer la Mémoire Intelligente",
219
  "memory_stats": "Statistiques de Mémoire",
220
  "view_memories": "Voir & Gérer",
kimi-locale/it.json CHANGED
@@ -227,6 +227,19 @@
227
  "memory_category_experiences": "Esperienze",
228
  "memory_category_important": "Eventi importanti",
229
  "memory_content_placeholder": "es.: Amo la musica classica...",
 
 
 
 
 
 
 
 
 
 
 
 
 
230
  "memory_management": "Gestione della Memoria",
231
  "add": "Aggiungi",
232
  "api_key_label": "API Key"
 
227
  "memory_category_experiences": "Esperienze",
228
  "memory_category_important": "Eventi importanti",
229
  "memory_content_placeholder": "es.: Amo la musica classica...",
230
+ "memory_source_label": "📝 Memoria della conversazione",
231
+ "memory_manually_added": "📝 Aggiunto manualmente",
232
+ "view_more": "Vedi di più",
233
+ "view_less": "Vedi meno",
234
+ "all_categories": "Tutte le categorie",
235
+ "memory_export": "Esporta memorie",
236
+ "edit_memory_title": "Modifica memoria",
237
+ "label_title": "Titolo:",
238
+ "label_category": "Categoria:",
239
+ "label_content": "Contenuto:",
240
+ "cancel": "Annulla",
241
+ "edit_memory_button_title": "Modifica questa memoria",
242
+ "delete_memory_button_title": "Elimina questa memoria",
243
  "memory_management": "Gestione della Memoria",
244
  "add": "Aggiungi",
245
  "api_key_label": "API Key"
kimi-locale/ja.json CHANGED
@@ -227,6 +227,19 @@
227
  "memory_category_experiences": "経験",
228
  "memory_category_important": "重要な出来事",
229
  "memory_content_placeholder": "例: クラシック音楽が大好き...",
 
 
 
 
 
 
 
 
 
 
 
 
 
230
  "memory_management": "メモリ管理",
231
  "add": "追加",
232
  "api_key_label": "API Key"
 
227
  "memory_category_experiences": "経験",
228
  "memory_category_important": "重要な出来事",
229
  "memory_content_placeholder": "例: クラシック音楽が大好き...",
230
+ "memory_source_label": "📝 会話のメモリ",
231
+ "memory_manually_added": "📝 手動で追加",
232
+ "view_more": "もっと見る",
233
+ "view_less": "閉じる",
234
+ "all_categories": "すべてのカテゴリ",
235
+ "memory_export": "メモリをエクスポート",
236
+ "edit_memory_title": "メモリを編集",
237
+ "label_title": "タイトル:",
238
+ "label_category": "カテゴリー:",
239
+ "label_content": "内容:",
240
+ "cancel": "キャンセル",
241
+ "edit_memory_button_title": "このメモリを編集",
242
+ "delete_memory_button_title": "このメモリを削除",
243
  "memory_management": "メモリ管理",
244
  "add": "追加",
245
  "api_key_label": "API Key"
kimi-locale/zh.json CHANGED
@@ -227,6 +227,19 @@
227
  "memory_category_experiences": "经历",
228
  "memory_category_important": "重要事件",
229
  "memory_content_placeholder": "例如:我喜欢古典音乐...",
 
 
 
 
 
 
 
 
 
 
 
 
 
230
  "memory_management": "记忆管理",
231
  "add": "添加",
232
  "api_key_label": "API Key"
 
227
  "memory_category_experiences": "经历",
228
  "memory_category_important": "重要事件",
229
  "memory_content_placeholder": "例如:我喜欢古典音乐...",
230
+ "memory_source_label": "📝 对话记忆",
231
+ "memory_manually_added": "📝 手动添加",
232
+ "view_more": "查看更多",
233
+ "view_less": "收起",
234
+ "all_categories": "所有类别",
235
+ "memory_export": "导出记忆",
236
+ "edit_memory_title": "编辑记忆",
237
+ "label_title": "标题:",
238
+ "label_category": "类别:",
239
+ "label_content": "内容:",
240
+ "cancel": "取消",
241
+ "edit_memory_button_title": "编辑该记忆",
242
+ "delete_memory_button_title": "删除该记忆",
243
  "memory_management": "记忆管理",
244
  "add": "添加",
245
  "api_key_label": "API Key"