kiku-agent 1.0.11 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (221) hide show
  1. package/README.md +300 -495
  2. package/package.json +12 -11
  3. package/public/fonts/GoogleSans-Bold.ttf +0 -0
  4. package/public/fonts/GoogleSans-Bold.woff2 +0 -0
  5. package/public/fonts/GoogleSans-BoldItalic.ttf +0 -0
  6. package/public/fonts/GoogleSans-Italic.ttf +0 -0
  7. package/public/fonts/GoogleSans-Latin-400.woff2 +0 -0
  8. package/public/fonts/GoogleSans-Latin-500.woff2 +0 -0
  9. package/public/fonts/GoogleSans-Latin-600.woff2 +0 -0
  10. package/public/fonts/GoogleSans-Latin-700.woff2 +0 -0
  11. package/public/fonts/GoogleSans-Medium.ttf +0 -0
  12. package/public/fonts/GoogleSans-Medium.woff2 +0 -0
  13. package/public/fonts/GoogleSans-Regular.ttf +0 -0
  14. package/public/fonts/GoogleSans-Regular.woff2 +0 -0
  15. package/public/fonts/GoogleSans-Thai-400.woff2 +0 -0
  16. package/public/fonts/GoogleSans-Thai-500.woff2 +0 -0
  17. package/public/fonts/GoogleSans-Thai-600.woff2 +0 -0
  18. package/public/fonts/GoogleSans-Thai-700.woff2 +0 -0
  19. package/public/fonts/NotoSansThai-Bold.woff2 +0 -0
  20. package/public/fonts/NotoSansThai-Regular.woff2 +0 -0
  21. package/public/fonts/google-sans-official.css +900 -0
  22. package/public/images/0040jbadgy1id6am4yxqfj61s82dn1kx02.jpg +0 -0
  23. package/public/images/0040jbadgy1id6am708pbj62c0340qv602.jpg +0 -0
  24. package/public/images/0040jbadgy1id6amb81uqj62c0340x6q02.jpg +0 -0
  25. package/public/images/0040jbadgy1id6amcqte3j62c0340qv602.jpg +0 -0
  26. package/public/images/0040jbadgy1id6amdg3xcj62b232wqv502.jpg +0 -0
  27. package/public/images/0040jbadgy1id6amexv23j620v2pau0x02.jpg +0 -0
  28. package/public/images/0040jbadly8icq3if7twwj60qy0qy0uc02.jpg +0 -0
  29. package/public/images/008ET7Legy1ig9s89nri5j30i20n1gn4.jpg +0 -0
  30. package/public/images/008ET7Legy1ig9s8a2lmlj30i20ny409.jpg +0 -0
  31. package/public/images/008ET7Legy1ig9s8ay1hsj30i20nk3zv.jpg +0 -0
  32. package/public/images/008ET7Legy1ig9s8bab6sj30i20o7go1.jpg +0 -0
  33. package/public/images/008ET7Legy1ig9s8blqsxj30i20oiq4r.jpg +0 -0
  34. package/public/images/008ET7Legy1ig9s8cbxkzj30i20mxmzh.jpg +0 -0
  35. package/public/images/douyin-update/thumbs//346/212/226/351/237/2632026820-399915.jpg +0 -0
  36. package/public/images/douyin-update/thumbs//346/212/226/351/237/2632026820-424041.jpg +0 -0
  37. package/public/images/douyin-update/thumbs//346/212/226/351/237/2632026820-588166.jpg +0 -0
  38. package/public/images/douyin-update/thumbs//346/212/226/351/237/2632026820-672198.jpg +0 -0
  39. package/public/images/douyin-update/thumbs//346/212/226/351/237/2632026820-700522.jpg +0 -0
  40. package/public/images/douyin-update/thumbs//346/212/226/351/237/2632026820-839722.jpg +0 -0
  41. package/public/images/douyin-update/thumbs//346/212/226/351/237/2632026825-460586.jpg +0 -0
  42. package/public/images/douyin-update/thumbs//346/212/226/351/237/263202694-689407.jpg +0 -0
  43. package/public/images/douyin-update//346/212/226/351/237/2632026820-399915.mp4 +0 -0
  44. package/public/images/douyin-update//346/212/226/351/237/2632026820-424041.mp4 +0 -0
  45. package/public/images/douyin-update//346/212/226/351/237/2632026820-588166.mp4 +0 -0
  46. package/public/images/douyin-update//346/212/226/351/237/2632026820-672198.mp4 +0 -0
  47. package/public/images/douyin-update//346/212/226/351/237/2632026820-700522.mp4 +0 -0
  48. package/public/images/douyin-update//346/212/226/351/237/2632026820-839722.mp4 +0 -0
  49. package/public/images/douyin-update//346/212/226/351/237/2632026825-460586.mp4 +0 -0
  50. package/public/images/douyin-update//346/212/226/351/237/263202694-689407.mp4 +0 -0
  51. package/public/images/general/0040jbadgy1id6am4yxqfj61s82dn1kx02.jpg +0 -0
  52. package/public/images/general/0040jbadgy1id6am708pbj62c0340qv602.jpg +0 -0
  53. package/public/images/general/0040jbadgy1id6amb81uqj62c0340x6q02.jpg +0 -0
  54. package/public/images/general/0040jbadgy1id6amcqte3j62c0340qv602.jpg +0 -0
  55. package/public/images/general/0040jbadgy1id6amdg3xcj62b232wqv502.jpg +0 -0
  56. package/public/images/general/0040jbadgy1id6amexv23j620v2pau0x02.jpg +0 -0
  57. package/public/images/general/0040jbadly8icq3if7twwj60qy0qy0uc02.jpg +0 -0
  58. package/public/images/general/008ET7Legy1ig9s89nri5j30i20n1gn4.jpg +0 -0
  59. package/public/images/general/008ET7Legy1ig9s8a2lmlj30i20ny409.jpg +0 -0
  60. package/public/images/general/008ET7Legy1ig9s8ay1hsj30i20nk3zv.jpg +0 -0
  61. package/public/images/general/008ET7Legy1ig9s8bab6sj30i20o7go1.jpg +0 -0
  62. package/public/images/general/008ET7Legy1ig9s8blqsxj30i20oiq4r.jpg +0 -0
  63. package/public/images/general/008ET7Legy1ig9s8cbxkzj30i20mxmzh.jpg +0 -0
  64. package/public/images/general/jujingyi_portrait.jpg +0 -0
  65. package/public/images/jujingyi_portrait.jpg +0 -0
  66. package/public/images/series/a-millenniums-wait/poster.jpg +0 -0
  67. package/public/images/series/beauty-of-resilience/poster.jpg +0 -0
  68. package/public/images/series/detective-samoyeds/poster.jpg +0 -0
  69. package/public/images/series/everyday/poster.jpg +0 -0
  70. package/public/images/series/fu-rong-ancient-painting/poster.jpg +0 -0
  71. package/public/images/series/in-a-class-of-her-own/poster.jpg +0 -0
  72. package/public/images/series/in-blossom/poster.jpg +0 -0
  73. package/public/images/series/legend-of-yunxi/poster.jpg +0 -0
  74. package/public/images/series/lets-fight/poster-2.jpg +0 -0
  75. package/public/images/series/lets-fight/poster.jpg +0 -0
  76. package/public/images/series/love-emergency/poster.jpg +0 -0
  77. package/public/images/series/love-under-the-full-moon/poster.jpg +0 -0
  78. package/public/images/series/money-bastion/poster.jpg +0 -0
  79. package/public/images/series/mr-swimmer/poster.jpg +0 -0
  80. package/public/images/series/novoland-castle-in-the-sky/poster.jpg +0 -0
  81. package/public/images/series/please-give-me-a-pair-of-wings/poster.jpg +0 -0
  82. package/public/images/series/rebirth-for-you/poster.jpg +0 -0
  83. package/public/images/series/sword-and-fairy-4/poster.jpg +0 -0
  84. package/public/images/series/the-blooms-at-ruyi-pavilion/poster.jpg +0 -0
  85. package/public/images/series/the-eternal-fragrance/poster-2.jpg +0 -0
  86. package/public/images/series/the-eternal-fragrance/poster.jpg +0 -0
  87. package/public/images/series/the-fallen-flowers/poster.jpg +0 -0
  88. package/public/images/series/the-legend-of-white-snake/poster.jpg +0 -0
  89. package/public/images/series/veil-of-shadows/poster.jpg +0 -0
  90. package/public/images/series/wanhua-sin/poster-2.jpg +0 -0
  91. package/public/images/series/wanhua-sin/poster.jpg +0 -0
  92. package/public/images/weibo-update/41/345/210/206/351/222/237/345/211/215/0040jbadgy1igrkj10yogj62u03s0npe02.jpg +0 -0
  93. package/public/images/weibo-update/41/345/210/206/351/222/237/345/211/215/0040jbadgy1igrkj2pdvyj61li25jkjl02.jpg +0 -0
  94. package/public/images/weibo-update/41/345/210/206/351/222/237/345/211/215/0040jbadgy1igrkj71177j62672w9e8302.jpg +0 -0
  95. package/public/images/weibo-update/41/345/210/206/351/222/237/345/211/215/0040jbadgy1igrkj7twpfj62192197rw02.jpg +0 -0
  96. package/public/images/weibo-update/41/345/210/206/351/222/237/345/211/215/0040jbadgy1igrkj8jfu8j62c03401kx02.jpg +0 -0
  97. package/public/images/weibo-update/41/345/210/206/351/222/237/345/211/215/0040jbadgy1igrkj9dhdsj622k2l77wh02.jpg +0 -0
  98. package/public/images/weibo-update/41/345/210/206/351/222/237/345/211/215/0040jbadgy1igrkja31s4j62bw3407r802.jpg +0 -0
  99. package/public/images/weibo-update/41/345/210/206/351/222/237/345/211/215/0040jbadgy1igrkjcf331j61402ey1kx02.jpg +0 -0
  100. package/public/images/weibo-update/41/345/210/206/351/222/237/345/211/215/0040jbadgy1igrkjdx8gqj62602pihdt02.jpg +0 -0
  101. package/public/images/weibo-update/41/345/210/206/351/222/237/345/211/215/0040jbadgy1igrkjfvxnzj62432n57wh02.jpg +0 -0
  102. package/public/images/weibo-update/8-14-17-16/0040jbadgy1ig3ixniv2yj627y4fxb2b02.jpg +0 -0
  103. package/public/images/weibo-update/8-14-17-16/0040jbadgy1ig3ixsvbdaj625k2vfu1102.jpg +0 -0
  104. package/public/images/weibo-update/8-14-17-16/0040jbadgy1ig3ixxxdaoj62c03501l202.jpg +0 -0
  105. package/public/images/weibo-update/8-14-17-16/0040jbadgy1ig3ixzeef9j62c0340npd02.jpg +0 -0
  106. package/public/images/weibo-update/8-14-17-16/0040jbadgy1ig3iy0vs6tj626t4rbhdu02.jpg +0 -0
  107. package/public/images/weibo-update/8-14-17-16/0040jbadgy1ig3iy21wwuj62bt34hx6q02.jpg +0 -0
  108. package/public/images/weibo-update/8-8-17-39/0040jbadgy1ifwly4wr85j62z629y7wh02.jpg +0 -0
  109. package/public/images/weibo-update/8-8-17-39/0040jbadgy1ifwly67oilj623u2t5npd02.jpg +0 -0
  110. package/public/images/weibo-update/8-8-17-39/0040jbadgy1ifwly9qtw8j62c0340u0x02.jpg +0 -0
  111. package/public/images/weibo-update/8-8-17-39/0040jbadgy1ifwlyem4m4j63402c01kz02.jpg +0 -0
  112. package/public/images/weibo-update/8-8-17-39/0040jbadgy1ifwlygkoq4j627s2yeavd02.jpg +0 -0
  113. package/public/images/weibo-update/8-8-17-39/0040jbadgy1ifwlyjh0daj62bw340nm102.jpg +0 -0
  114. package/public/images/weibo-update/8-8-17-39/0040jbadgy1ifwlylejlhj62bw3401kx02.jpg +0 -0
  115. package/public/images/weibo-update/today/0040jbadgy1igaiaa8b7fj627j2y67wh02.jpg +0 -0
  116. package/public/images/weibo-update/today/0040jbadgy1igaiagw3ezj61s02ebu0x02.jpg +0 -0
  117. package/public/images/weibo-update/today/0040jbadgy1igaiaivng3j61rv2ebx6p02.jpg +0 -0
  118. package/public/images/weibo-update/today/0040jbadgy1igaiajuixvj62bw340qv502.jpg +0 -0
  119. package/public/images/weibo-update/today/0040jbadgy1igaiapyartj62bw340hdt02.jpg +0 -0
  120. package/public/images/weibo-update/today/0040jbadgy1igaibkwu4ij61vy2iq1kx02.jpg +0 -0
  121. package/public/images/weibo-update/today/0040jbadgy1igaic1fvkpj61u92eo1ky02.jpg +0 -0
  122. package/public/images/weibo-update/today/0040jbadgy1igaic3cruhj62822ywb2902.jpg +0 -0
  123. package/public/manifest.json +25 -0
  124. package/public/mcp-logo-128.png +0 -0
  125. package/public/mcp-logo-64.png +0 -0
  126. package/public/mcp-logo.svg +16 -0
  127. package/server/agent/agentCore.js +542 -74
  128. package/server/agent/appPaths.js +1 -0
  129. package/server/agent/audioPlayer.js +4 -2
  130. package/server/agent/citations.js +294 -0
  131. package/server/agent/clarificationAnalytics.js +477 -0
  132. package/server/agent/clarifyingQuestions.js +1089 -0
  133. package/server/agent/cli.js +549 -125
  134. package/server/agent/commandFeatures.js +1 -0
  135. package/server/agent/commandRegistry.js +946 -879
  136. package/server/agent/commands.js +546 -272
  137. package/server/agent/config.js +581 -412
  138. package/server/agent/contextCompactor.js +2 -2
  139. package/server/agent/debate.js +235 -0
  140. package/server/agent/eventBus.js +3 -0
  141. package/server/agent/feedbackLearning.js +217 -0
  142. package/server/agent/llmClient.js +512 -394
  143. package/server/agent/mcpClient.js +182 -32
  144. package/server/agent/memory.js +283 -224
  145. package/server/agent/modelManager.js +79 -39
  146. package/server/agent/profiles.js +178 -0
  147. package/server/agent/publicTools.js +22 -0
  148. package/server/agent/queryDetails.js +68 -8
  149. package/server/agent/quizData.js +398 -384
  150. package/server/agent/research.js +121 -79
  151. package/server/agent/sanitizer.js +104 -13
  152. package/server/agent/session.js +319 -11
  153. package/server/agent/subagent.js +8 -3
  154. package/server/agent/suggestionTui.js +294 -0
  155. package/server/agent/suggestions.js +69 -3
  156. package/server/agent/telemetry.js +119 -0
  157. package/server/agent/terminalImage.js +146 -27
  158. package/server/agent/theme.js +17 -0
  159. package/server/agent/toolRouter.js +16 -1
  160. package/server/agent/tools.js +424 -225
  161. package/server/agent/ui.js +486 -64
  162. package/server/agent/version.js +2 -4
  163. package/server/agent/webSearch.js +111 -11
  164. package/server/agent/youtubeAuth.js +24 -6
  165. package/server/apiRouter.js +4222 -0
  166. package/server/mcp/data/discography.js +25 -16
  167. package/server/mcp/data/gallery.js +308 -20
  168. package/server/mcp/data/profile.js +74 -44
  169. package/server/mcp/data/timeline.js +1 -1
  170. package/server/mcp/data/works.js +51 -17
  171. package/server/mcp/dataAdapter.js +5 -3
  172. package/server/mcp/handler.js +5 -11
  173. package/server/mcp/prompts.js +86 -0
  174. package/server/mcp/security.js +18 -15
  175. package/server/mcp/server.js +7 -2
  176. package/server/mcp/tools.js +66 -2
  177. package/server/web-chat/core/browserLauncher.js +18 -0
  178. package/server/web-chat/core/connection.js +194 -0
  179. package/server/web-chat/core/conversationContext.js +82 -0
  180. package/server/web-chat/core/directCatalogEngine.js +196 -0
  181. package/server/web-chat/core/dramaKnowledge.js +142 -0
  182. package/server/web-chat/core/errorHandler.js +51 -0
  183. package/server/web-chat/core/followUpEngine.js +182 -0
  184. package/server/web-chat/core/futureEventGuard.js +80 -0
  185. package/server/web-chat/core/memorySnapshot.js +12 -0
  186. package/server/web-chat/core/security.js +146 -0
  187. package/server/web-chat/core/toolInspector.js +52 -0
  188. package/server/web-chat/router.js +120 -0
  189. package/server/web-chat/routes/chatRoute.js +397 -0
  190. package/server/web-chat/routes/clarifyConfigRoute.js +98 -0
  191. package/server/web-chat/routes/clarifyRoute.js +83 -0
  192. package/server/web-chat/routes/compareRoute.js +79 -0
  193. package/server/web-chat/routes/exportRoute.js +59 -0
  194. package/server/web-chat/routes/feedbackRoute.js +57 -0
  195. package/server/web-chat/routes/newsRoute.js +33 -0
  196. package/server/web-chat/routes/quizRoute.js +11 -0
  197. package/server/web-chat/routes/staticRoute.js +103 -0
  198. package/server/web-chat/routes/statusRoute.js +52 -0
  199. package/server/web-chat/routes/suggestRoute.js +77 -0
  200. package/server/web-chat/routes/timelineRoute.js +34 -0
  201. package/server/web-chat/routes/verifyRoute.js +57 -0
  202. package/server/web-chat/server.js +116 -0
  203. package/server/web-chat/ui/htmlBuilder.js +91 -0
  204. package/server/web-chat/ui/previews/agentBubble.preview.html +134 -0
  205. package/server/web-chat/ui/scripts/agentBubbleSystem.js +320 -0
  206. package/server/web-chat/ui/scripts/client.js +8397 -0
  207. package/server/web-chat/ui/scripts/kikuDb.js +177 -0
  208. package/server/web-chat/ui/scripts/suggestionsData.js +118 -0
  209. package/server/web-chat/ui/scripts/webchatI18n.js +291 -0
  210. package/server/web-chat/ui/styles/main.css +8568 -0
  211. package/server/web-chat/ui/templates/body.html +796 -0
  212. package/server/webChatHtml.js +1 -0
  213. package/server/webChatServer.js +6 -0
  214. package/src/data/discographyData.js +892 -866
  215. package/src/data/galleryData.js +1805 -561
  216. package/src/data/profileData.js +79 -2
  217. package/src/data/socialUpdatesData.js +106 -47
  218. package/src/data/timelineData.js +1 -1
  219. package/src/data/worksData.js +25 -4
  220. package/tokens.css +97 -0
  221. package/server/agent/updateManager.js +0 -456
@@ -0,0 +1,177 @@
1
+ const DB_NAME = 'kiku_chat_db';
2
+ const DB_VERSION = 1;
3
+ const SESSIONS_STORE = 'sessions';
4
+ const META_STORE = 'metadata';
5
+
6
+ let dbInstance = null;
7
+
8
+ export async function openKikuDb() {
9
+ if (dbInstance) return dbInstance;
10
+ if (typeof window === 'undefined' || !window.indexedDB) return null;
11
+
12
+ return new Promise((resolve) => {
13
+ try {
14
+ const request = indexedDB.open(DB_NAME, DB_VERSION);
15
+
16
+ request.onupgradeneeded = (e) => {
17
+ const db = e.target.result;
18
+ if (!db.objectStoreNames.contains(SESSIONS_STORE)) {
19
+ db.createObjectStore(SESSIONS_STORE, { keyPath: 'id' });
20
+ }
21
+ if (!db.objectStoreNames.contains(META_STORE)) {
22
+ db.createObjectStore(META_STORE, { keyPath: 'key' });
23
+ }
24
+ };
25
+
26
+ request.onsuccess = (e) => {
27
+ dbInstance = e.target.result;
28
+ resolve(dbInstance);
29
+ };
30
+
31
+ request.onerror = (err) => {
32
+ console.warn('[kikuDb] IndexedDB open error, falling back to localStorage:', err);
33
+ resolve(null);
34
+ };
35
+ } catch (err) {
36
+ console.warn('[kikuDb] IndexedDB exception:', err);
37
+ resolve(null);
38
+ }
39
+ });
40
+ }
41
+
42
+
43
+ export async function initKikuStorage() {
44
+ const db = await openKikuDb();
45
+ if (!db) {
46
+
47
+ try {
48
+ return JSON.parse(localStorage.getItem('kiku_sessions') || '[]');
49
+ } catch {
50
+ return [];
51
+ }
52
+ }
53
+
54
+
55
+ return new Promise((resolve) => {
56
+ try {
57
+ const tx = db.transaction(SESSIONS_STORE, 'readonly');
58
+ const store = tx.objectStore(SESSIONS_STORE);
59
+ const req = store.getAll();
60
+
61
+ req.onsuccess = async () => {
62
+ const stored = req.result || [];
63
+ if (stored.length > 0) {
64
+
65
+ stored.sort((a, b) => (b.createdAt || 0) - (a.createdAt || 0));
66
+ resolve(stored);
67
+ } else {
68
+
69
+ try {
70
+ const rawLocal = localStorage.getItem('kiku_sessions');
71
+ if (rawLocal) {
72
+ const localSessions = JSON.parse(rawLocal);
73
+ if (Array.isArray(localSessions) && localSessions.length > 0) {
74
+ await saveAllSessionsToDb(localSessions);
75
+ resolve(localSessions);
76
+ return;
77
+ }
78
+ }
79
+ } catch (e) {
80
+ console.warn('[kikuDb] Migration error:', e);
81
+ }
82
+ resolve([]);
83
+ }
84
+ };
85
+
86
+ req.onerror = () => resolve([]);
87
+ } catch {
88
+ resolve([]);
89
+ }
90
+ });
91
+ }
92
+
93
+ export async function saveAllSessionsToDb(sessions) {
94
+
95
+ try {
96
+ localStorage.setItem('kiku_sessions', JSON.stringify(sessions));
97
+ } catch (e) {
98
+
99
+ }
100
+
101
+ const db = await openKikuDb();
102
+ if (!db) return;
103
+
104
+ return new Promise((resolve) => {
105
+ try {
106
+ const tx = db.transaction(SESSIONS_STORE, 'readwrite');
107
+ const store = tx.objectStore(SESSIONS_STORE);
108
+
109
+
110
+ store.clear().onsuccess = () => {
111
+ for (const s of sessions) {
112
+ store.put(s);
113
+ }
114
+ tx.oncomplete = () => resolve(true);
115
+ tx.onerror = () => resolve(false);
116
+ };
117
+ } catch {
118
+ resolve(false);
119
+ }
120
+ });
121
+ }
122
+
123
+ export async function saveSingleSessionToDb(session) {
124
+ if (!session || !session.id) return;
125
+ const db = await openKikuDb();
126
+ if (!db) return;
127
+
128
+ return new Promise((resolve) => {
129
+ try {
130
+ const tx = db.transaction(SESSIONS_STORE, 'readwrite');
131
+ const store = tx.objectStore(SESSIONS_STORE);
132
+ store.put(session);
133
+ tx.oncomplete = () => resolve(true);
134
+ tx.onerror = () => resolve(false);
135
+ } catch {
136
+ resolve(false);
137
+ }
138
+ });
139
+ }
140
+
141
+ export async function deleteSessionFromDb(id) {
142
+ const db = await openKikuDb();
143
+ if (!db) return;
144
+
145
+ return new Promise((resolve) => {
146
+ try {
147
+ const tx = db.transaction(SESSIONS_STORE, 'readwrite');
148
+ const store = tx.objectStore(SESSIONS_STORE);
149
+ store.delete(id);
150
+ tx.oncomplete = () => resolve(true);
151
+ tx.onerror = () => resolve(false);
152
+ } catch {
153
+ resolve(false);
154
+ }
155
+ });
156
+ }
157
+
158
+ export async function clearAllSessionsFromDb() {
159
+ try {
160
+ localStorage.removeItem('kiku_sessions');
161
+ } catch {}
162
+
163
+ const db = await openKikuDb();
164
+ if (!db) return;
165
+
166
+ return new Promise((resolve) => {
167
+ try {
168
+ const tx = db.transaction(SESSIONS_STORE, 'readwrite');
169
+ const store = tx.objectStore(SESSIONS_STORE);
170
+ store.clear();
171
+ tx.oncomplete = () => resolve(true);
172
+ tx.onerror = () => resolve(false);
173
+ } catch {
174
+ resolve(false);
175
+ }
176
+ });
177
+ }
@@ -0,0 +1,118 @@
1
+ export const CATEGORIZED_SUGGESTIONS = {
2
+ th: {
3
+ 'ซีรีส์ & ละคร': [
4
+ 'จวีจิ้งอี มีผลงานซีรีส์เรื่องเด่นอะไรบ้างในปี 2024–2025?',
5
+ 'เล่าบทบาท "หยางไฉ่เวย" ในซีรีส์ ฮวาเจียนหลิง (In Blossom) ให้ฟังหน่อย',
6
+ 'ตำนานหยุนซี (Legend of Yunxi) จวีจิ้งอี รับบทเป็นใคร และมีจุดเด่นอย่างไร?',
7
+ 'ผลงานเรื่อง เซียนกระบี่พิชิตมาร 4 (Sword and Fairy 4) รับบทเป็นใคร?'
8
+ ],
9
+ 'เพลง & อัลบั้ม': [
10
+ 'แนะนำเพลงฮิตยอดนิยมของจวีจิ้งอี พร้อมประวัติและแนวเพลง',
11
+ 'เล่าเกี่ยวกับเพลง Everyday และเพลงเดี่ยวในยุค SNH48 ให้ฟังหน่อย',
12
+ 'เพลงประกอบซีรีส์ (OST) ที่จวีจิ้งอีร้อง มีเพลงอะไรที่โด่งดังบ้าง?',
13
+ 'มีผลงานเพลงภาษาไทยหรือเพลงสากลที่จวีจิ้งอีเคยร้องไหม?'
14
+ ],
15
+ 'แบรนด์ & รางวัล': [
16
+ 'จวีจิ้งอี ได้รับการแต่งตั้งเป็น Global Brand Ambassador ให้แบรนด์ระดับโลกใดบ้าง?',
17
+ 'จวีจิ้งอีได้รับรางวัลอะไรบ้างตลอดเส้นทางอาชีพในวงการบันเทิง?',
18
+ 'ความสำเร็จในงาน Weibo Night และงานประกาศรางวัลใหญ่ๆ มีอะไรบ้าง?'
19
+ ],
20
+ 'ประวัติ & ไทม์ไลน์': [
21
+ 'สรุปประวัติ จุดเริ่มต้นในวงการ และฉายา "สาวงาม 4,000 ปี" ให้ฟังหน่อย',
22
+ 'เส้นทางการเติบโตจากไอดอลสู่ศิลปินและนักแสดงเดี่ยวเต็มตัว',
23
+ 'ความสามารถพิเศษอื่นๆ เช่น การเล่นไวโอลิน กู่เจิง และเปียโน'
24
+ ]
25
+ },
26
+ zh: {
27
+ '影视作品': [
28
+ '鞠婧祎在2024–2025年有哪些代表影视剧作品?',
29
+ '请介绍《花间令》中“杨采薇”这一角色的特点与故事',
30
+ '《芸汐传》中韩芸汐的角色设定和经典台词是什么?',
31
+ '《仙剑四》中韩菱纱的角色故事与看点介绍'
32
+ ],
33
+ '音乐单曲': [
34
+ '推荐鞠婧祎的热门单曲及音乐风格介绍',
35
+ '介绍单曲《Everyday》以及SNH48时期的经典舞台',
36
+ '鞠婧祎演唱过哪些经典影视剧OST?'
37
+ ],
38
+ '品牌与荣誉': [
39
+ '鞠婧祎担任过哪些国际奢侈品牌全球代言人(如Versace)?',
40
+ '盘点鞠婧祎在微博之夜与各大盛典获得的荣誉奖项'
41
+ ],
42
+ '个人传记': [
43
+ '鞠婧祎的个人经历、成长历程与出道背景介绍',
44
+ '鞠婧祎的小提琴、古筝与钢琴等才艺介绍'
45
+ ]
46
+ },
47
+ en: {
48
+ 'Dramas & Films': [
49
+ 'What are Ju Jingyi’s most notable drama series in 2024–2025?',
50
+ 'Tell me about the character "Yang Caiwei" in In Blossom (花间令)',
51
+ 'What is Ju Jingyi’s role and highlights in Legend of Yunxi (芸汐传)?',
52
+ 'Introduce the character Han Lingsha in Sword and Fairy 4'
53
+ ],
54
+ 'Discography': [
55
+ 'Recommend top hit songs and solo singles by Ju Jingyi',
56
+ 'Tell me about the single Everyday and her SNH48 solo era',
57
+ 'Which hit drama OSTs were sung by Ju Jingyi?'
58
+ ],
59
+ 'Brands & Awards': [
60
+ 'Which global brands (e.g. Versace) has Ju Jingyi represented as Global Ambassador?',
61
+ 'List major career awards and Weibo Night honors won by Ju Jingyi'
62
+ ],
63
+ 'Biography': [
64
+ 'Summarize Ju Jingyi’s career journey and the "4000-Year Idol" nickname',
65
+ 'What special musical talents does Ju Jingyi have (violin, guzheng, piano)?'
66
+ ]
67
+ },
68
+ ja: {
69
+ 'ドラマ・映画': [
70
+ '2024–2025年のジュー・ジンイー代表ドラマは何ですか?',
71
+ '『花間令』の楊采薇という役柄と物語を紹介してください',
72
+ '『芸汐伝』の韓芸汐の役柄設定と名台詞は?',
73
+ '『仙剣四』の韓菱紗の見どころを紹介してください'
74
+ ],
75
+ '音楽・シングル': [
76
+ 'ジュー・ジンイーの人気曲と音楽スタイルを教えてください',
77
+ 'シングル『Everyday』とSNH48時代のステージについて',
78
+ 'ジュー・ジンイーが歌った代表的なドラマOSTは?'
79
+ ],
80
+ 'ブランド・受賞': [
81
+ 'ジュー・ジンイーがグローバルアンバサダーを務めるブランドは?(Versaceなど)',
82
+ 'Weibo Nightなどでの受賞歴を教えてください'
83
+ ],
84
+ 'プロフィール・年表': [
85
+ 'ジュー・ジンイーの経歴と「4000年に一度の美少女」の由来',
86
+ 'バイオリン・古筝・ピアノなどの特技を紹介してください'
87
+ ]
88
+ },
89
+ ko: {
90
+ '드라마・영화': [
91
+ '2024–2025년 쥐징이의 대표 드라마는 무엇인가요?',
92
+ '화간령의 양채미 역할과 스토리를 소개해주세요',
93
+ '운석전 한운희의 캐릭터 설정과 명대사는?',
94
+ '선검4 한릉사 역할의 관전 포인트는?'
95
+ ],
96
+ '음악・싱글': [
97
+ '쥐징이의 인기곡과 음악 스타일을 추천해주세요',
98
+ '싱글 Everyday와 SNH48 시절 무대에 대해 알려주세요',
99
+ '쥐징이가 부른 대표 드라마 OST는?'
100
+ ],
101
+ '브랜드・수상': [
102
+ '쥐징이가 글로벌 앰버서더로 활동하는 브랜드는?(Versace 등)',
103
+ '웨이보나이트 등에서의 수상 이력을 알려주세요'
104
+ ],
105
+ '프로필・연표': [
106
+ '쥐징이의 경력과 4000년 미소녀 별명의 유래',
107
+ '바이올린・고쟁・피아노 등 특기를 소개해주세요'
108
+ ]
109
+ }
110
+ };
111
+
112
+ export const DEFAULT_SUGGESTIONS = [
113
+ 'จวีจิ้งอี มีผลงานซีรีส์เรื่องเด่นอะไรบ้างในปี 2024?',
114
+ 'เล่าบทบาท "หยางไฉ่เวย" ในซีรีส์ ฮวาเจียนหลิง (In Blossom) ให้ฟังหน่อย',
115
+ 'แนะนำเพลงฮิตยอดนิยมของจวีจิ้งอี พร้อมประวัติสั้นๆ',
116
+ 'จวีจิ้งอีได้รับรางวัลอะไรบ้างตลอดเส้นทางอาชีพ?',
117
+ 'ผลงานพรีเซนเตอร์และแบรนด์แอมบาสเดอร์ระดับโลกมีแบรนด์อะไรบ้าง?'
118
+ ];
@@ -0,0 +1,291 @@
1
+ // Kiku web-chat UI i18n pack — injected BEFORE client.js (see htmlBuilder.js).
2
+ // Provides ja/ko UI strings (client.js ships th/zh/en inline) and the
3
+ // clarifying-question-box strings for all 5 languages.
4
+ const WEBCHAT_I18N_EXTRA = {
5
+ ja: {
6
+ brandSubtitle: "KIKU AGENT",
7
+ quizBtn: "クイズ",
8
+ musicBtn: "音楽",
9
+ historyBtn: "履歴",
10
+ suggestionsBtn: "おすすめ",
11
+ petalsOn: "花びら",
12
+ petalsOff: "花びら (オフ)",
13
+ themeDark: "ダーク",
14
+ themeLight: "ライト",
15
+ soundOn: "効果音",
16
+ soundOff: "効果音 (オフ)",
17
+ settingsBtn: "設定",
18
+ newChatBtn: "新規チャット",
19
+ menuBtn: "メニュー",
20
+ drawerTitle: "AIコントロールパネル",
21
+ drawerQuiz: "ファンクイズ (Quiz)",
22
+ drawerMusic: "ミュージックジュークボックス",
23
+ drawerHistory: "チャット履歴 (Sessions)",
24
+ drawerSuggestions: "おすすめの質問",
25
+ drawerPetalsOn: "桜の花びらを表示",
26
+ drawerPetalsOff: "桜の花びらを非表示",
27
+ drawerThemeDark: "ダークモード (Dark)",
28
+ drawerThemeLight: "ライトモード (Light)",
29
+ drawerSoundOn: "効果音: オン",
30
+ drawerSoundOff: "効果音: オフ",
31
+ drawerLang: "言語 / Language (JA)",
32
+ drawerSettings: "モデル & APIキー設定",
33
+ drawerExport: "チャットをエクスポート",
34
+ drawerNewChat: "クリア / 新規セッション",
35
+ welcomeTitle: "ミジューの皆さん、こんにちは",
36
+ welcomeSubtitle: "今日はジュー・ジンイーのどんな物語を探索しますか?",
37
+ welcomeBody: "ドラマ、名曲、ステージ、ブランドアンバサダーについて気軽にどうぞ",
38
+ tagInBlossom: "花間令",
39
+ tagYunxi: "芸汐伝",
40
+ tagMusic: "2026 ヒット曲",
41
+ tagBrand: "Versace Global Ambassador",
42
+ tagQuiz: "Fan Quiz Challenge",
43
+ sidebarExplore: "探索 & 機能",
44
+ sidebarSearch: "チャット検索",
45
+ sidebarMusic: "ジュークボックス",
46
+ sidebarQuiz: "ファンクイズ",
47
+ sidebarTimeline: "キャリア年表",
48
+ sidebarPrompts: "おすすめの質問",
49
+ sidebarSaved: "保存済みプロンプト",
50
+ sidebarHistory: "チャット履歴",
51
+ sidebarControls: "システム & AI設定",
52
+ sidebarSettings: "モデル & API設定",
53
+ sidebarExport: "チャットをエクスポート",
54
+ sidebarPetals: "桜の花びら",
55
+ sidebarTheme: "ダーク / ライト",
56
+ sidebarSound: "効果音",
57
+ sidebarLang: "言語 / Language (JA)",
58
+ sidebarEmptyTitle: "履歴がありません",
59
+ sidebarEmptySub: "メッセージを送信してチャットを開始...",
60
+ inputDisclaimer: "AIは間違えることがあります。個人情報や秘密は入力しないでください。",
61
+ suggestionsHeader: "おすすめトピック",
62
+ collapseSuggestions: "折りたたむ",
63
+ inputSuggestionsBtn: "おすすめ",
64
+ aiGenBtn: "✨ AIで生成",
65
+ aiGenerating: "⏳ KIKUが考え中…",
66
+ aiSourceAi: "✨ KIKU AIが生成",
67
+ inputPlaceholder: "何でも聞いてください…",
68
+ inputHint: "<kbd>Enter</kbd>で送信、<kbd>Shift + Enter</kbd>で改行",
69
+ lblProvider: "AIプロバイダー",
70
+ lblApiKey: "Cloud APIキー (クラウド用)",
71
+ lblModel: "モデル名 / ID",
72
+ lblThinking: "Thinking Mode",
73
+ lblTemp: "創造性 (Temperature)",
74
+ apiKeyHelpLm: "🔒 ローカルLM Studio利用時は不要",
75
+ apiKeyHelpCloud: "🔒 このブラウザにのみ保存 (Local Client Storage)",
76
+ copyMsg: "コピー",
77
+ quoteMsg: "名言カード",
78
+ regenerateMsg: "再生成",
79
+ sponsorsHeading: "SPONSOR SPOTLIGHT",
80
+ sidebarSponsors: "スポンサー"
81
+ },
82
+ ko: {
83
+ brandSubtitle: "KIKU AGENT",
84
+ quizBtn: "퀴즈",
85
+ musicBtn: "음악",
86
+ historyBtn: "기록",
87
+ suggestionsBtn: "추천",
88
+ petalsOn: "벚꽃잎",
89
+ petalsOff: "벚꽃잎 (끔)",
90
+ themeDark: "다크",
91
+ themeLight: "라이트",
92
+ soundOn: "효과음",
93
+ soundOff: "효과음 (끔)",
94
+ settingsBtn: "설정",
95
+ newChatBtn: "새 채팅",
96
+ menuBtn: "메뉴",
97
+ drawerTitle: "AI 제어판",
98
+ drawerQuiz: "팬 퀴즈 (Quiz)",
99
+ drawerMusic: "뮤직 주크박스",
100
+ drawerHistory: "채팅 기록 (Sessions)",
101
+ drawerSuggestions: "추천 질문",
102
+ drawerPetalsOn: "벚꽃잎 켜기",
103
+ drawerPetalsOff: "벚꽃잎 끄기",
104
+ drawerThemeDark: "다크 모드 (Dark)",
105
+ drawerThemeLight: "라이트 모드 (Light)",
106
+ drawerSoundOn: "효과음: 켬",
107
+ drawerSoundOff: "효과음: 끔",
108
+ drawerLang: "언어 / Language (KO)",
109
+ drawerSettings: "모델 & API 키 설정",
110
+ drawerExport: "채팅 내보내기",
111
+ drawerNewChat: "지우기 / 새 세션",
112
+ welcomeTitle: "미쥐 여러분 안녕하세요",
113
+ welcomeSubtitle: "오늘은 쥐징이의 어떤 이야기를 탐험할까요?",
114
+ welcomeBody: "드라마, 명곡, 무대, 브랜드 앰버서더에 대해 물어보세요",
115
+ tagInBlossom: "화간령",
116
+ tagYunxi: "운석전",
117
+ tagMusic: "2026 히트곡",
118
+ tagBrand: "Versace Global Ambassador",
119
+ tagQuiz: "Fan Quiz Challenge",
120
+ sidebarExplore: "탐색 & 기능",
121
+ sidebarSearch: "채팅 검색",
122
+ sidebarMusic: "주크박스",
123
+ sidebarQuiz: "팬 퀴즈",
124
+ sidebarTimeline: "커리어 타임라인",
125
+ sidebarPrompts: "추천 질문",
126
+ sidebarSaved: "저장된 프롬프트",
127
+ sidebarHistory: "채팅 기록",
128
+ sidebarControls: "시스템 & AI 제어",
129
+ sidebarSettings: "모델 & API 설정",
130
+ sidebarExport: "채팅 내보내기",
131
+ sidebarPetals: "벚꽃잎",
132
+ sidebarTheme: "다크 / 라이트",
133
+ sidebarSound: "효과음",
134
+ sidebarLang: "언어 / Language (KO)",
135
+ sidebarEmptyTitle: "기록이 없습니다",
136
+ sidebarEmptySub: "메시지를 보내 채팅을 시작하세요...",
137
+ inputDisclaimer: "AI가 틀릴 수 있습니다. 개인정보나 비밀은 입력하지 마세요.",
138
+ suggestionsHeader: "추천 주제",
139
+ collapseSuggestions: "접기",
140
+ inputSuggestionsBtn: "추천",
141
+ aiGenBtn: "✨ AI 생성",
142
+ aiGenerating: "⏳ KIKU가 생각 중…",
143
+ aiSourceAi: "✨ KIKU AI 생성",
144
+ inputPlaceholder: "무엇이든 물어보세요…",
145
+ inputHint: "<kbd>Enter</kbd> 전송, <kbd>Shift + Enter</kbd> 줄바꿈",
146
+ lblProvider: "AI 제공자",
147
+ lblApiKey: "Cloud API 키 (클라우드용)",
148
+ lblModel: "모델명 / ID",
149
+ lblThinking: "Thinking Mode",
150
+ lblTemp: "창의성 (Temperature)",
151
+ apiKeyHelpLm: "🔒 로컬 LM Studio 사용 시 불필요",
152
+ apiKeyHelpCloud: "🔒 이 브라우저에만 저장 (Local Client Storage)",
153
+ copyMsg: "복사",
154
+ quoteMsg: "명언 카드",
155
+ regenerateMsg: "다시 생성",
156
+ sponsorsHeading: "SPONSOR SPOTLIGHT",
157
+ sidebarSponsors: "스폰서"
158
+ }
159
+ };
160
+ const WEBCHAT_CLARIFY_I18N = {
161
+ th: {
162
+ title: "คำถามเพิ่มเติมเพื่อคำตอบที่แม่นยำ",
163
+ countSuffix: "ข้อ",
164
+ skip: "หรือตอบแบบภาพรวมทั่วไป ❯",
165
+ submitIdle: "ส่งคำตอบ (เลือกหรือพิมพ์เพื่อตอบ) ❯",
166
+ submitReady: "ส่งคำตอบ (เลือกแล้ว {done}/{total} ข้อ) ❯",
167
+ freeTextPlaceholder: "หรือพิมพ์คำตอบเพิ่มเติมเอง แล้วกด Enter…",
168
+ freeTextAria: "พิมพ์คำตอบเพิ่มเติมเอง",
169
+ collapsedSkipped: "ตอบแบบภาพรวมทั่วไป",
170
+ collapsedPicked: "เลือก:",
171
+ categories: {
172
+ specific_work: "🎬 ผลงานซีรีส์ / ละคร",
173
+ subject_focus: "🎯 ประเด็นที่สนใจ",
174
+ subject_scope: "🔍 ขอบเขตเรื่องที่ถาม",
175
+ career_phase: "✨ ช่วงเวลาและบทบาท",
176
+ timeframe: "📅 ช่วงเวลาที่สนใจ",
177
+ media_type: "🎵 หมวดหมู่เพลง & ผลงาน",
178
+ aspect_focus: "🎭 มุมมองที่ต้องการเน้น",
179
+ scope: "🔍 ขอบเขตเนื้อหา",
180
+ depth: "📖 ความละเอียดของข้อมูล",
181
+ comparison: "⚖️ หัวข้อเปรียบเทียบ",
182
+ language: "🌐 ภาษาที่ต้องการ",
183
+ date_range: "📆 ช่วงปี/พ.ศ.",
184
+ content_format: "📑 รูปแบบคำตอบ"
185
+ }
186
+ },
187
+ zh: {
188
+ title: "为了更准确的回答,请补充回答",
189
+ countSuffix: "题",
190
+ skip: "或按常规总体回答 ❯",
191
+ submitIdle: "提交回答(选择或输入后提交) ❯",
192
+ submitReady: "提交回答(已选 {done}/{total} 题) ❯",
193
+ freeTextPlaceholder: "或手动输入补充回答,按 Enter…",
194
+ freeTextAria: "手动输入补充回答",
195
+ collapsedSkipped: "按常规总体回答",
196
+ collapsedPicked: "已选:",
197
+ categories: {
198
+ specific_work: "🎬 影视剧作品",
199
+ subject_focus: "🎯 感兴趣的要点",
200
+ subject_scope: "🔍 提问范围",
201
+ career_phase: "✨ 时期与角色",
202
+ timeframe: "📅 感兴趣的时间",
203
+ media_type: "🎵 音乐作品分类",
204
+ aspect_focus: "🎭 想要强调的视角",
205
+ scope: "🔍 内容范围",
206
+ depth: "📖 信息详细程度",
207
+ comparison: "⚖️ 比较主题",
208
+ language: "🌐 想要的语言",
209
+ date_range: "📆 年份区间",
210
+ content_format: "📑 回答格式"
211
+ }
212
+ },
213
+ en: {
214
+ title: "Follow-up questions for accurate answers",
215
+ countSuffix: "items",
216
+ skip: "Or answer generally ❯",
217
+ submitIdle: "Submit (select or type to answer) ❯",
218
+ submitReady: "Submit ({done}/{total} selected) ❯",
219
+ freeTextPlaceholder: "Or type your own answer, then Enter…",
220
+ freeTextAria: "Type your own answer",
221
+ collapsedSkipped: "Answered generally",
222
+ collapsedPicked: "Picked:",
223
+ categories: {
224
+ specific_work: "🎬 Drama / Film",
225
+ subject_focus: "🎯 Focus point",
226
+ subject_scope: "🔍 Question scope",
227
+ career_phase: "✨ Era & role",
228
+ timeframe: "📅 Time of interest",
229
+ media_type: "🎵 Music category",
230
+ aspect_focus: "🎭 Angle to emphasize",
231
+ scope: "🔍 Content scope",
232
+ depth: "📖 Detail level",
233
+ comparison: "⚖️ Comparison topic",
234
+ language: "🌐 Preferred language",
235
+ date_range: "📆 Year range",
236
+ content_format: "📑 Answer format"
237
+ }
238
+ },
239
+ ja: {
240
+ title: "正確な回答のための追加質問",
241
+ countSuffix: "問",
242
+ skip: "または一般的に回答 ❯",
243
+ submitIdle: "回答を送信(選択または入力) ❯",
244
+ submitReady: "回答を送信({done}/{total} 選択中) ❯",
245
+ freeTextPlaceholder: "または自由に回答を入力して Enter…",
246
+ freeTextAria: "自由に回答を入力",
247
+ collapsedSkipped: "一般的に回答",
248
+ collapsedPicked: "選択:",
249
+ categories: {
250
+ specific_work: "🎬 ドラマ・映画",
251
+ subject_focus: "🎯 関心のあるポイント",
252
+ subject_scope: "🔍 質問の範囲",
253
+ career_phase: "✨ 時期と役柄",
254
+ timeframe: "📅 興味のある時期",
255
+ media_type: "🎵 楽曲・作品カテゴリー",
256
+ aspect_focus: "🎭 注目したい視点",
257
+ scope: "🔍 内容の範囲",
258
+ depth: "📖 情報の詳しさ",
259
+ comparison: "⚖️ 比較テーマ",
260
+ language: "🌐 希望言語",
261
+ date_range: "📆 年代・期間",
262
+ content_format: "📑 回答形式"
263
+ }
264
+ },
265
+ ko: {
266
+ title: "정확한 답변을 위한 추가 질문",
267
+ countSuffix: "문항",
268
+ skip: "또는 일반적으로 답변 ❯",
269
+ submitIdle: "답변 제출(선택 또는 입력) ❯",
270
+ submitReady: "답변 제출({done}/{total} 선택) ❯",
271
+ freeTextPlaceholder: "또는 직접 답변을 입력하고 Enter…",
272
+ freeTextAria: "직접 답변 입력",
273
+ collapsedSkipped: "일반적으로 답변",
274
+ collapsedPicked: "선택:",
275
+ categories: {
276
+ specific_work: "🎬 드라마・영화",
277
+ subject_focus: "🎯 관심 포인트",
278
+ subject_scope: "🔍 질문 범위",
279
+ career_phase: "✨ 시기 및 역할",
280
+ timeframe: "📅 관심 시기",
281
+ media_type: "🎵 음악・작품 카테고리",
282
+ aspect_focus: "🎭 주목할 관점",
283
+ scope: "🔍 내용 범위",
284
+ depth: "📖 정보 상세도",
285
+ comparison: "⚖️ 비교 주제",
286
+ language: "🌐 원하는 언어",
287
+ date_range: "📆 연도・기간",
288
+ content_format: "📑 답변 형식"
289
+ }
290
+ }
291
+ };