kiku-agent 1.3.1 → 1.3.3

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 (232) hide show
  1. package/README.md +69 -12
  2. package/package.json +5 -12
  3. package/server/agent/agentCore.js +319 -46
  4. package/server/agent/appPaths.js +31 -0
  5. package/server/agent/audioPlayer.js +339 -12
  6. package/server/agent/autoContext.js +193 -0
  7. package/server/agent/catalogEntityResolver.js +170 -28
  8. package/server/agent/clarifyingQuestions.js +137 -35
  9. package/server/agent/cli.js +177 -48
  10. package/server/agent/cloudAdapters.js +116 -0
  11. package/server/agent/commandRegistry.js +409 -80
  12. package/server/agent/commands.js +1056 -125
  13. package/server/agent/config.js +1088 -690
  14. package/server/agent/contextCompactor.js +213 -21
  15. package/server/agent/cpuMetrics.js +199 -0
  16. package/server/agent/engineService.js +591 -0
  17. package/server/agent/eval/AGENTS.md +228 -0
  18. package/server/agent/eval/analyze.py +684 -0
  19. package/server/agent/eval/gates.json +15 -0
  20. package/server/agent/eval/modules/analysis/compare.js +198 -0
  21. package/server/agent/eval/modules/analysis/gates.js +72 -0
  22. package/server/agent/eval/modules/analysis/judge.js +70 -0
  23. package/server/agent/eval/modules/core/cli.js +453 -0
  24. package/server/agent/eval/modules/core/config.js +60 -0
  25. package/server/agent/eval/modules/core/store.js +236 -0
  26. package/server/agent/eval/modules/evaluation/cases.js +689 -0
  27. package/server/agent/eval/modules/evaluation/runner.js +288 -0
  28. package/server/agent/eval/modules/evaluation/scoring.js +363 -0
  29. package/server/agent/eval/modules/evaluation/worker.js +122 -0
  30. package/server/agent/eval/modules/reporting/benchmark.js +265 -0
  31. package/server/agent/eval/modules/reporting/benchmarkPng.js +487 -0
  32. package/server/agent/eval/modules/reporting/dashboard.js +1406 -0
  33. package/server/agent/eval/modules/server/evalApi.js +1099 -0
  34. package/server/agent/eval/modules/ui/evalUi.js +4799 -0
  35. package/server/agent/eval/modules/utils/smokes.js +119 -0
  36. package/server/agent/eventBus.js +1 -0
  37. package/server/agent/ink/main.jsx +196 -191
  38. package/server/agent/jobManager.js +11 -1
  39. package/server/agent/lanDiscovery.js +721 -23
  40. package/server/agent/llmClient.js +317 -71
  41. package/server/agent/lmStudioWakeup.js +517 -65
  42. package/server/agent/locationService.js +797 -0
  43. package/server/agent/mcpQuizData.js +509 -0
  44. package/server/agent/memory/contextAllocator.js +19 -7
  45. package/server/agent/memory.js +3 -1
  46. package/server/agent/modelCompatibility.js +352 -0
  47. package/server/agent/modelDefaults.js +1 -0
  48. package/server/agent/modelManager.js +46 -2
  49. package/server/agent/newsWatch.js +9 -3
  50. package/server/agent/processManager.js +229 -0
  51. package/server/agent/prompts.js +174 -8
  52. package/server/agent/routingInterceptor.js +9 -1
  53. package/server/agent/sanitizer.js +41 -6
  54. package/server/agent/searchQueryPlanner.js +202 -0
  55. package/server/agent/session.js +59 -4
  56. package/server/agent/tests/agentBubbleSystem.test.js +65 -0
  57. package/server/agent/tests/agentFollowUps.test.js +253 -0
  58. package/server/agent/tests/agentMusicControl.test.js +245 -0
  59. package/server/agent/tests/apiRouter.test.js +108 -0
  60. package/server/agent/tests/architectureFixes.test.js +81 -0
  61. package/server/agent/tests/architectureRefactoring.test.js +194 -0
  62. package/server/agent/tests/autoContext.test.js +176 -0
  63. package/server/agent/tests/autoResearch.test.js +64 -0
  64. package/server/agent/tests/bilibiliEmbed.test.js +296 -0
  65. package/server/agent/tests/catalogSync.test.js +130 -0
  66. package/server/agent/tests/chatHardening.test.js +121 -0
  67. package/server/agent/tests/chineseWebSearchEscalation.test.js +62 -0
  68. package/server/agent/tests/citations.test.js +180 -0
  69. package/server/agent/tests/clarificationAnalytics.test.js +219 -0
  70. package/server/agent/tests/clarifyingQuestions.test.js +627 -0
  71. package/server/agent/tests/cliAutomation.test.js +158 -0
  72. package/server/agent/tests/cloudProviders.test.js +322 -0
  73. package/server/agent/tests/commandInput.test.js +24 -0
  74. package/server/agent/tests/commands.test.js +506 -0
  75. package/server/agent/tests/contextIntelligence.test.js +209 -0
  76. package/server/agent/tests/conversationSafety.test.js +53 -0
  77. package/server/agent/tests/cpuMetrics.test.js +101 -0
  78. package/server/agent/tests/decisionAndSearchEnhancements.test.js +167 -0
  79. package/server/agent/tests/dramaAnswerQuality.test.js +73 -0
  80. package/server/agent/tests/dynamicCatalogIngestion.test.js +285 -0
  81. package/server/agent/tests/dynamicRoutingAndSearch.test.js +92 -0
  82. package/server/agent/tests/edgeCasesScenarios.test.js +131 -0
  83. package/server/agent/tests/engineService.test.js +436 -0
  84. package/server/agent/tests/engineUnload.test.js +94 -0
  85. package/server/agent/tests/entertainmentMetrics.test.js +126 -0
  86. package/server/agent/tests/envBootstrap.test.js +87 -0
  87. package/server/agent/tests/envCommand.test.js +284 -0
  88. package/server/agent/tests/errorHandling.test.js +80 -0
  89. package/server/agent/tests/errors.test.js +13 -0
  90. package/server/agent/tests/evalAnalyze.test.js +54 -0
  91. package/server/agent/tests/evalCommand.test.js +54 -0
  92. package/server/agent/tests/evalCorpus.test.js +126 -0
  93. package/server/agent/tests/evalHarness.test.js +62 -0
  94. package/server/agent/tests/evalJudgeContext.test.js +38 -0
  95. package/server/agent/tests/evalMetrics.test.js +320 -0
  96. package/server/agent/tests/evalStore.test.js +190 -0
  97. package/server/agent/tests/evalStudio.test.js +179 -0
  98. package/server/agent/tests/feedbackLearning.test.js +186 -0
  99. package/server/agent/tests/fetchApi.test.js +99 -0
  100. package/server/agent/tests/firstRun.test.js +44 -0
  101. package/server/agent/tests/gemma4eOptimization.test.js +95 -0
  102. package/server/agent/tests/hardwareTiers.test.js +206 -0
  103. package/server/agent/tests/hybridWebSearch.test.js +194 -0
  104. package/server/agent/tests/judgeService.test.js +251 -0
  105. package/server/agent/tests/lanDiscovery.test.js +324 -0
  106. package/server/agent/tests/lanInterfaces.test.js +510 -0
  107. package/server/agent/tests/lmStudioWakeup.test.js +278 -0
  108. package/server/agent/tests/locationTool.test.js +278 -0
  109. package/server/agent/tests/mcpClient.test.js +201 -0
  110. package/server/agent/tests/memoryRoute.test.js +173 -0
  111. package/server/agent/tests/memoryUiNormalization.test.js +75 -0
  112. package/server/agent/tests/modelCompatibility.test.js +148 -0
  113. package/server/agent/tests/modelManager.test.js +141 -0
  114. package/server/agent/tests/multilingualScenarios.test.js +69 -0
  115. package/server/agent/tests/musicControlUiBridge.test.js +113 -0
  116. package/server/agent/tests/newCommands.test.js +347 -0
  117. package/server/agent/tests/newCommandsTui.test.js +141 -0
  118. package/server/agent/tests/newTools.test.js +113 -0
  119. package/server/agent/tests/newsIntelligence.test.js +178 -0
  120. package/server/agent/tests/nextGenArchitecture.test.js +101 -0
  121. package/server/agent/tests/offlineInput.test.js +217 -0
  122. package/server/agent/tests/openDomainPrompt.test.js +197 -0
  123. package/server/agent/tests/openDomainSearch.test.js +121 -0
  124. package/server/agent/tests/packagingGuard.test.js +57 -0
  125. package/server/agent/tests/presentation.test.js +61 -0
  126. package/server/agent/tests/processManager.test.js +144 -0
  127. package/server/agent/tests/providerPersistence.test.js +44 -0
  128. package/server/agent/tests/queryBenchmarks.test.js +83 -0
  129. package/server/agent/tests/queryDetails.test.js +126 -0
  130. package/server/agent/tests/quickActionsAndModals.test.js +180 -0
  131. package/server/agent/tests/realWorldValidation.test.js +391 -0
  132. package/server/agent/tests/resilienceAndConcurrency.test.js +117 -0
  133. package/server/agent/tests/runtimeWatchdog.test.js +32 -0
  134. package/server/agent/tests/sanitizer.test.js +37 -0
  135. package/server/agent/tests/scenariosData.js +378 -0
  136. package/server/agent/tests/schemaRouting.test.js +54 -0
  137. package/server/agent/tests/searchQueryPlanner.test.js +108 -0
  138. package/server/agent/tests/securityAuditRemediation.test.js +221 -0
  139. package/server/agent/tests/securityAuditRemediations2.test.js +154 -0
  140. package/server/agent/tests/securityHardening.test.js +146 -0
  141. package/server/agent/tests/securitySanitizer.test.js +38 -0
  142. package/server/agent/tests/sessionAndCopy.test.js +267 -0
  143. package/server/agent/tests/sidebarControls.test.js +135 -0
  144. package/server/agent/tests/statefulMemory.test.js +277 -0
  145. package/server/agent/tests/subagent.test.js +216 -0
  146. package/server/agent/tests/subagentProgress.test.js +109 -0
  147. package/server/agent/tests/subagentTextFallback.test.js +115 -0
  148. package/server/agent/tests/suggestions.test.js +199 -0
  149. package/server/agent/tests/suggestionsTui.test.js +251 -0
  150. package/server/agent/tests/telemetryAndProfiles.test.js +179 -0
  151. package/server/agent/tests/terminalImage.test.js +80 -0
  152. package/server/agent/tests/terminalMarkdown.test.js +166 -0
  153. package/server/agent/tests/terminalText.test.js +133 -0
  154. package/server/agent/tests/textProtocolLoop.test.js +197 -0
  155. package/server/agent/tests/textToolParsing.test.js +187 -0
  156. package/server/agent/tests/theme.test.js +26 -0
  157. package/server/agent/tests/toolRegistryParity.test.js +53 -0
  158. package/server/agent/tests/toolRoutingRegressions.test.js +160 -0
  159. package/server/agent/tests/tools.test.js +259 -0
  160. package/server/agent/tests/unifiedEndpoints.test.js +159 -0
  161. package/server/agent/tests/v110Features.test.js +262 -0
  162. package/server/agent/tests/versionBump.test.js +69 -0
  163. package/server/agent/tests/vramEstimator.test.js +595 -0
  164. package/server/agent/tests/webChatDocs.test.js +199 -0
  165. package/server/agent/tests/webChatInferenceControl.test.js +298 -0
  166. package/server/agent/tests/webChatInspection.test.js +551 -0
  167. package/server/agent/tests/webChatMcp.test.js +94 -0
  168. package/server/agent/tests/webChatMemory.test.js +112 -0
  169. package/server/agent/tests/webChatSecurity.test.js +169 -0
  170. package/server/agent/tests/webExtract.test.js +284 -0
  171. package/server/agent/tests/webSources.test.js +281 -0
  172. package/server/agent/textToolProtocol.js +173 -46
  173. package/server/agent/toolRouter.js +318 -44
  174. package/server/agent/tools.js +877 -96
  175. package/server/agent/ui.js +39 -34
  176. package/server/agent/vramService.js +35 -54
  177. package/server/agent/webSearch.js +441 -162
  178. package/server/agent/websearch/orchestrator.js +15 -5
  179. package/server/agent/websearch/resilience/cache.js +9 -2
  180. package/server/agent/websearch/security/ssrf.js +41 -10
  181. package/server/agent/youtubeAuth.js +5 -20
  182. package/server/apiRouter.js +5558 -4422
  183. package/server/eval/judgeRubrics.js +110 -0
  184. package/server/eval/judgeService.js +290 -0
  185. package/server/eval/runBenchmark.js +182 -0
  186. package/server/mcp/data/discography.js +2 -2
  187. package/server/mcp/examples/antigravity.example.json +17 -0
  188. package/server/mcp/examples/librechat.example.yaml +16 -0
  189. package/server/mcp/handler.js +8 -4
  190. package/server/mcp/security.js +220 -21
  191. package/server/mcp/server.js +2 -1
  192. package/server/mcp/tests/connection.test.js +162 -0
  193. package/server/mcp/tests/mcpKeyAuth.test.js +156 -0
  194. package/server/mcp/tools.js +7 -1
  195. package/server/supabase_migration_prefix.sql +102 -0
  196. package/server/supabase_schema.sql +63 -0
  197. package/server/web-chat/core/connection.js +179 -218
  198. package/server/web-chat/core/conversationContext.js +9 -2
  199. package/server/web-chat/core/directCatalogEngine.js +52 -28
  200. package/server/web-chat/core/dramaKnowledge.js +33 -22
  201. package/server/web-chat/core/followUpEngine.js +735 -81
  202. package/server/web-chat/core/futureEventGuard.js +5 -1
  203. package/server/web-chat/core/musicControlAction.js +70 -0
  204. package/server/web-chat/core/security.js +32 -21
  205. package/server/web-chat/core/toolInspector.js +6 -6
  206. package/server/web-chat/core/urlGuard.js +45 -0
  207. package/server/web-chat/router.js +204 -157
  208. package/server/web-chat/routes/chatRoute.js +885 -488
  209. package/server/web-chat/routes/engineRoute.js +270 -0
  210. package/server/web-chat/routes/exportRoute.js +1 -1
  211. package/server/web-chat/routes/lanDiscoveryRoute.js +17 -2
  212. package/server/web-chat/routes/lmStudioLoadRoute.js +172 -0
  213. package/server/web-chat/routes/mcpRoute.js +386 -0
  214. package/server/web-chat/routes/memoryRoute.js +253 -0
  215. package/server/web-chat/routes/providerRoute.js +49 -16
  216. package/server/web-chat/routes/staticRoute.js +306 -17
  217. package/server/web-chat/routes/statusRoute.js +194 -73
  218. package/server/web-chat/routes/suggestRoute.js +11 -3
  219. package/server/web-chat/routes/verifyRoute.js +26 -4
  220. package/server/web-chat/server.js +7 -6
  221. package/server/web-chat/ui/docsBuilder.js +3558 -0
  222. package/server/web-chat/ui/htmlBuilder.js +12 -0
  223. package/server/web-chat/ui/scripts/client.js +3401 -1302
  224. package/server/web-chat/ui/scripts/webchatI18n.js +155 -153
  225. package/server/web-chat/ui/settingsBuilder.js +7870 -0
  226. package/server/web-chat/ui/styles/lan-card.css +165 -0
  227. package/server/web-chat/ui/styles/main.css +4289 -447
  228. package/server/web-chat/ui/sw.js +64 -0
  229. package/server/web-chat/ui/templates/body.html +407 -281
  230. package/src/data/awardsData.js +146 -146
  231. package/src/data/musicVideoData.js +6 -4
  232. package/src/lib/vram/estimator.js +195 -19
@@ -1,157 +1,204 @@
1
- import { handleStaticRoute } from './routes/staticRoute.js';
2
- import { handleStatusRoute } from './routes/statusRoute.js';
3
- import { handleChatRoute } from './routes/chatRoute.js';
4
- import { handleProviderGetRoute, handleProviderUpdateRoute } from './routes/providerRoute.js';
5
- import { handleLanDiscoveryRoute, handleLanApplyRoute } from './routes/lanDiscoveryRoute.js';
6
- import { handleSuggestionsRoute, handleAiSuggestRoute } from './routes/suggestRoute.js';
7
- import { handleVerifyRoute } from './routes/verifyRoute.js';
8
- import { handleNewsRoute } from './routes/newsRoute.js';
9
- import { handleCompareRoute } from './routes/compareRoute.js';
10
- import { handleQuizRoute } from './routes/quizRoute.js';
11
- import { handleTimelineRoute } from './routes/timelineRoute.js';
12
- import { handleBilibiliCoverRoute } from './routes/bilibiliRoute.js';
13
- import { handleExportRoute } from './routes/exportRoute.js';
14
- import { handleClarifyRoute } from './routes/clarifyRoute.js';
15
- import { handleFeedbackRoute, handleFeedbackStatsRoute } from './routes/feedbackRoute.js';
16
- import { handleClarifyAnalyticsRoute, handleClarifyConfigRoute } from './routes/clarifyConfigRoute.js';
17
- import { handleSystemHardwareRoute, handleEstimateVramRoute } from './routes/vramRoute.js';
18
- import { applySecurityHeaders, checkChatRateLimitDistributed, resolveClientIp } from './core/security.js';
19
- import { sendError } from './core/errorHandler.js';
20
- import { handleApiRequest } from '../apiRouter.js';
21
-
22
- export async function handleWebChatRequest(req, res, options = {}) {
23
- const port = Number(options.port || 3002);
24
- const urlObj = new URL(req.url, `http://localhost:${port}`);
25
- const pathname = urlObj.pathname;
26
-
27
- const originAllowed = applySecurityHeaders(req, res);
28
- if (!originAllowed) {
29
- return sendError(res, 403, 'Origin is not allowed');
30
- }
31
-
32
- if (req.method === 'OPTIONS') {
33
- res.writeHead(204);
34
- res.end();
35
- return;
36
- }
37
-
38
- if (pathname.startsWith('/api/')) {
39
- const rate = await checkChatRateLimitDistributed(resolveClientIp(req));
40
- if (!rate.allowed) {
41
- res.setHeader('Retry-After', String(rate.retryAfter || 60));
42
- return sendError(res, 429, `Rate limit exceeded. Please retry in ${rate.retryAfter || 60} seconds.`);
43
- }
44
- }
45
-
46
- try {
47
-
48
- if (handleStaticRoute(req, res, pathname, port)) {
49
- return;
50
- }
51
-
52
- if (pathname === '/api/status') {
53
- return await handleStatusRoute(req, res, urlObj, port);
54
- }
55
-
56
- if (pathname === '/api/provider' && req.method === 'GET') {
57
- return await handleProviderGetRoute(req, res);
58
- }
59
-
60
- if (pathname === '/api/provider' && req.method === 'POST') {
61
- return await handleProviderUpdateRoute(req, res);
62
- }
63
-
64
- if (pathname === '/api/lan/discovery' && req.method === 'GET') {
65
- return await handleLanDiscoveryRoute(req, res);
66
- }
67
-
68
- if (pathname === '/api/lan/discovery/apply' && req.method === 'POST') {
69
- return await handleLanApplyRoute(req, res);
70
- }
71
-
72
- if (pathname === '/api/suggestions') {
73
- return await handleSuggestionsRoute(req, res);
74
- }
75
-
76
- if (pathname === '/api/ai-suggest' && req.method === 'POST') {
77
- return await handleAiSuggestRoute(req, res);
78
- }
79
-
80
- if (pathname === '/api/quiz') {
81
- return await handleQuizRoute(req, res);
82
- }
83
-
84
- if (pathname === '/api/v1/timeline') {
85
- return await handleTimelineRoute(req, res, urlObj);
86
- }
87
-
88
- if (pathname === '/api/bilibili/cover') {
89
- return await handleBilibiliCoverRoute(req, res, urlObj);
90
- }
91
-
92
- if (pathname === '/api/chat' && req.method === 'POST') {
93
- return await handleChatRoute(req, res, urlObj);
94
- }
95
-
96
- if (pathname === '/api/v1/system/hardware' && req.method === 'GET') {
97
- return await handleSystemHardwareRoute(req, res);
98
- }
99
-
100
- if (pathname === '/api/v1/models/estimate-vram' && (req.method === 'POST' || req.method === 'GET')) {
101
- return await handleEstimateVramRoute(req, res, urlObj);
102
- }
103
-
104
- if (pathname === '/api/export' && req.method === 'POST') {
105
- return await handleExportRoute(req, res);
106
- }
107
-
108
- if (pathname === '/api/verify' && req.method === 'POST') {
109
- return await handleVerifyRoute(req, res);
110
- }
111
-
112
- if (pathname === '/api/news' && req.method === 'POST') {
113
- return await handleNewsRoute(req, res);
114
- }
115
-
116
- if (pathname === '/api/compare' && req.method === 'POST') {
117
- return await handleCompareRoute(req, res);
118
- }
119
-
120
- if (pathname === '/api/clarify' && req.method === 'POST') {
121
- return await handleClarifyRoute(req, res);
122
- }
123
-
124
- if (pathname === '/api/feedback' && req.method === 'POST') {
125
- return await handleFeedbackRoute(req, res);
126
- }
127
-
128
- if (pathname === '/api/feedback/stats' && req.method === 'GET') {
129
- return await handleFeedbackStatsRoute(req, res);
130
- }
131
-
132
- if (pathname === '/api/clarify/analytics' && req.method === 'GET') {
133
- return await handleClarifyAnalyticsRoute(req, res, options);
134
- }
135
-
136
- if (pathname === '/api/clarify/config' && req.method === 'GET') {
137
- return await handleClarifyConfigRoute(req, res, options, 'get');
138
- }
139
-
140
- if (pathname === '/api/clarify/config' && req.method === 'POST') {
141
- return await handleClarifyConfigRoute(req, res, options, 'update');
142
- }
143
-
144
- if (pathname === '/api/clarify/config/reset' && req.method === 'POST') {
145
- return await handleClarifyConfigRoute(req, res, options, 'reset');
146
- }
147
-
148
- if (pathname.startsWith('/api/v1') || pathname === '/api-docs' || pathname === '/api/api-docs' || pathname === '/openapi.json') {
149
- return await handleApiRequest(req, res);
150
- }
151
-
152
- res.writeHead(404, { 'Content-Type': 'application/json' });
153
- res.end(JSON.stringify({ error: 'Not found' }));
154
- } catch (err) {
155
- sendError(res, 500, err.message);
156
- }
157
- }
1
+ import { handleStaticRoute } from './routes/staticRoute.js';
2
+ import { handleStatusRoute } from './routes/statusRoute.js';
3
+ import { handleChatRoute } from './routes/chatRoute.js';
4
+ import { handleProviderGetRoute, handleProviderUpdateRoute } from './routes/providerRoute.js';
5
+ import { handleLanDiscoveryRoute, handleLanInterfacesRoute, handleLanApplyRoute } from './routes/lanDiscoveryRoute.js';
6
+ import { handleLmStudioLoadRoute, handleLmStudioLoadSettingsRoute } from './routes/lmStudioLoadRoute.js';
7
+ import { handleEngineLoadRoute, handleEngineStatusRoute, handleEngineSettingsRoute, handleEngineStopRoute, handleEngineUnloadRoute } from './routes/engineRoute.js';
8
+ import { handleSuggestionsRoute, handleAiSuggestRoute } from './routes/suggestRoute.js';
9
+ import { handleVerifyRoute } from './routes/verifyRoute.js';
10
+ import { handleNewsRoute } from './routes/newsRoute.js';
11
+ import { handleCompareRoute } from './routes/compareRoute.js';
12
+ import { handleQuizRoute } from './routes/quizRoute.js';
13
+ import { handleTimelineRoute } from './routes/timelineRoute.js';
14
+ import { handleBilibiliCoverRoute } from './routes/bilibiliRoute.js';
15
+ import { handleExportRoute } from './routes/exportRoute.js';
16
+ import { handleClarifyRoute } from './routes/clarifyRoute.js';
17
+ import { handleFeedbackRoute, handleFeedbackStatsRoute } from './routes/feedbackRoute.js';
18
+ import { handleMemoryGetRoute, handleMemoryActionRoute } from './routes/memoryRoute.js';
19
+ import { handleClarifyAnalyticsRoute, handleClarifyConfigRoute } from './routes/clarifyConfigRoute.js';
20
+ import { handleSystemHardwareRoute, handleEstimateVramRoute } from './routes/vramRoute.js';
21
+ import { handleMcpStatusRoute } from './routes/mcpRoute.js';
22
+ import { applySecurityHeaders, checkChatRateLimitDistributed, resolveClientIp } from './core/security.js';
23
+ import { sendError } from './core/errorHandler.js';
24
+ import { handleApiRequest } from '../apiRouter.js';
25
+
26
+ export async function handleWebChatRequest(req, res, options = {}) {
27
+ const port = Number(options.port || 3002);
28
+ const urlObj = new URL(req.url, `http://localhost:${port}`);
29
+ const pathname = urlObj.pathname;
30
+
31
+ const originAllowed = applySecurityHeaders(req, res);
32
+ if (!originAllowed) {
33
+ return sendError(res, 403, 'Origin is not allowed');
34
+ }
35
+
36
+ if (req.method === 'OPTIONS') {
37
+ res.writeHead(204);
38
+ res.end();
39
+ return;
40
+ }
41
+
42
+ if (pathname.startsWith('/api/')) {
43
+ const [bucket, limit] = pathname === '/api/status'
44
+ ? (urlObj.searchParams.get('light') === '1' ? ['status-light', 120] : ['status-full', 20])
45
+ : pathname.startsWith('/api/lan/discovery') || pathname === '/api/lan/interfaces' ? ['lan-discovery', 6]
46
+ : pathname === '/api/provider' ? ['provider', 30]
47
+ : ['/api/lmstudio/load', '/api/engine/load', '/api/engine/unload', '/api/lmstudio/unload'].includes(pathname) ? ['engine-load', 6]
48
+ : ['/api/lmstudio/settings', '/api/engine/settings', '/api/engine/status'].includes(pathname) ? ['engine-settings', 30]
49
+ : ['/api/chat', '/api/ai-suggest'].includes(pathname) ? ['chat', 60] : ['default', 60];
50
+ const rate = await checkChatRateLimitDistributed(resolveClientIp(req), bucket, limit);
51
+ if (!rate.allowed) {
52
+ res.setHeader('Retry-After', String(rate.retryAfter || 60));
53
+ return sendError(res, 429, `Rate limit exceeded. Please retry in ${rate.retryAfter || 60} seconds.`);
54
+ }
55
+ }
56
+
57
+ try {
58
+
59
+ if (handleStaticRoute(req, res, pathname, port)) {
60
+ return;
61
+ }
62
+
63
+ if (pathname === '/api/status') {
64
+ return await handleStatusRoute(req, res, urlObj, port);
65
+ }
66
+
67
+ if (pathname === '/api/provider' && req.method === 'GET') {
68
+ return await handleProviderGetRoute(req, res);
69
+ }
70
+
71
+ if (pathname === '/api/provider' && req.method === 'POST') {
72
+ return await handleProviderUpdateRoute(req, res);
73
+ }
74
+
75
+ if (pathname === '/api/lan/discovery' && req.method === 'GET') {
76
+ return await handleLanDiscoveryRoute(req, res);
77
+ }
78
+
79
+ if (pathname === '/api/lan/interfaces' && req.method === 'GET') {
80
+ return await handleLanInterfacesRoute(req, res);
81
+ }
82
+
83
+ if (pathname === '/api/lan/discovery/apply' && req.method === 'POST') {
84
+ return await handleLanApplyRoute(req, res);
85
+ }
86
+
87
+ if ((pathname === '/api/engine/load' || pathname === '/api/lmstudio/load') && req.method === 'POST') {
88
+ return await handleEngineLoadRoute(req, res);
89
+ }
90
+
91
+ if (pathname === '/api/engine/stop' && req.method === 'POST') {
92
+ return await handleEngineStopRoute(req, res);
93
+ }
94
+
95
+ if ((pathname === '/api/engine/unload' || pathname === '/api/lmstudio/unload') && req.method === 'POST') {
96
+ return await handleEngineUnloadRoute(req, res);
97
+ }
98
+
99
+ if ((pathname === '/api/engine/settings' || pathname === '/api/lmstudio/settings') && (req.method === 'GET' || req.method === 'POST')) {
100
+ return await handleEngineSettingsRoute(req, res);
101
+ }
102
+
103
+ if (pathname === '/api/engine/status' && req.method === 'GET') {
104
+ return await handleEngineStatusRoute(req, res);
105
+ }
106
+
107
+ if (pathname === '/api/suggestions') {
108
+ return await handleSuggestionsRoute(req, res);
109
+ }
110
+
111
+ if (pathname === '/api/ai-suggest' && req.method === 'POST') {
112
+ return await handleAiSuggestRoute(req, res);
113
+ }
114
+
115
+ if (pathname === '/api/quiz') {
116
+ return await handleQuizRoute(req, res);
117
+ }
118
+
119
+ if (pathname === '/api/v1/timeline') {
120
+ return await handleTimelineRoute(req, res, urlObj);
121
+ }
122
+
123
+ if (pathname === '/api/bilibili/cover') {
124
+ return await handleBilibiliCoverRoute(req, res, urlObj);
125
+ }
126
+
127
+ if (pathname === '/api/chat' && req.method === 'POST') {
128
+ return await handleChatRoute(req, res, urlObj);
129
+ }
130
+
131
+ if (pathname === '/api/v1/system/hardware' && req.method === 'GET') {
132
+ return await handleSystemHardwareRoute(req, res);
133
+ }
134
+
135
+ if (pathname === '/api/v1/models/estimate-vram' && (req.method === 'POST' || req.method === 'GET')) {
136
+ return await handleEstimateVramRoute(req, res, urlObj);
137
+ }
138
+
139
+ if (pathname === '/api/export' && req.method === 'POST') {
140
+ return await handleExportRoute(req, res);
141
+ }
142
+
143
+ if (pathname === '/api/verify' && req.method === 'POST') {
144
+ return await handleVerifyRoute(req, res);
145
+ }
146
+
147
+ if (pathname === '/api/news' && req.method === 'POST') {
148
+ return await handleNewsRoute(req, res);
149
+ }
150
+
151
+ if (pathname === '/api/compare' && req.method === 'POST') {
152
+ return await handleCompareRoute(req, res);
153
+ }
154
+
155
+ if (pathname === '/api/clarify' && req.method === 'POST') {
156
+ return await handleClarifyRoute(req, res);
157
+ }
158
+
159
+ if (pathname === '/api/feedback' && req.method === 'POST') {
160
+ return await handleFeedbackRoute(req, res);
161
+ }
162
+
163
+ if (pathname === '/api/memory' && req.method === 'GET') {
164
+ return await handleMemoryGetRoute(req, res);
165
+ }
166
+
167
+ if (pathname === '/api/memory' && req.method === 'POST') {
168
+ return await handleMemoryActionRoute(req, res);
169
+ }
170
+
171
+ if (pathname === '/api/feedback/stats' && req.method === 'GET') {
172
+ return await handleFeedbackStatsRoute(req, res);
173
+ }
174
+
175
+ if (pathname === '/api/clarify/analytics' && req.method === 'GET') {
176
+ return await handleClarifyAnalyticsRoute(req, res, options);
177
+ }
178
+
179
+ if (pathname === '/api/clarify/config' && req.method === 'GET') {
180
+ return await handleClarifyConfigRoute(req, res, options, 'get');
181
+ }
182
+
183
+ if (pathname === '/api/clarify/config' && req.method === 'POST') {
184
+ return await handleClarifyConfigRoute(req, res, options, 'update');
185
+ }
186
+
187
+ if (pathname === '/api/clarify/config/reset' && req.method === 'POST') {
188
+ return await handleClarifyConfigRoute(req, res, options, 'reset');
189
+ }
190
+
191
+ if (pathname === '/api/mcp/status' || pathname === '/api/v1/mcp/status' || pathname === '/api/mcp/tools') {
192
+ return await handleMcpStatusRoute(req, res, options);
193
+ }
194
+
195
+ if (pathname === '/mcp' || pathname.startsWith('/mcp/') || pathname.startsWith('/api/v1') || pathname === '/api-docs' || pathname === '/api/api-docs' || pathname === '/openapi.json') {
196
+ return await handleApiRequest(req, res);
197
+ }
198
+
199
+ res.writeHead(404, { 'Content-Type': 'application/json' });
200
+ res.end(JSON.stringify({ error: 'Not found' }));
201
+ } catch (err) {
202
+ sendError(res, 500, err.message);
203
+ }
204
+ }