079project 1.0.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 (67) hide show
  1. package/GroupStarter.cjs +647 -0
  2. package/LICENSE +165 -0
  3. package/PropagateSignalUseJsWorker.js +92 -0
  4. package/README.md +102 -0
  5. package/Redis-8.0.3-Windows-x64-cygwin-with-Service/README.md +52 -0
  6. package/Redis-8.0.3-Windows-x64-cygwin-with-Service/README.zh_CN.md +59 -0
  7. package/Redis-8.0.3-Windows-x64-cygwin-with-Service/RedisService.exe +0 -0
  8. package/Redis-8.0.3-Windows-x64-cygwin-with-Service/cygcrypto-3.dll +0 -0
  9. package/Redis-8.0.3-Windows-x64-cygwin-with-Service/cyggcc_s-seh-1.dll +0 -0
  10. package/Redis-8.0.3-Windows-x64-cygwin-with-Service/cygssl-3.dll +0 -0
  11. package/Redis-8.0.3-Windows-x64-cygwin-with-Service/cygstdc++-6.dll +0 -0
  12. package/Redis-8.0.3-Windows-x64-cygwin-with-Service/cygwin1.dll +0 -0
  13. package/Redis-8.0.3-Windows-x64-cygwin-with-Service/cygz.dll +0 -0
  14. package/Redis-8.0.3-Windows-x64-cygwin-with-Service/dump.rdb +0 -0
  15. package/Redis-8.0.3-Windows-x64-cygwin-with-Service/install_redis_service.bat +100 -0
  16. package/Redis-8.0.3-Windows-x64-cygwin-with-Service/redis-benchmark.exe +0 -0
  17. package/Redis-8.0.3-Windows-x64-cygwin-with-Service/redis-check-aof.exe +0 -0
  18. package/Redis-8.0.3-Windows-x64-cygwin-with-Service/redis-check-rdb.exe +0 -0
  19. package/Redis-8.0.3-Windows-x64-cygwin-with-Service/redis-cli.exe +0 -0
  20. package/Redis-8.0.3-Windows-x64-cygwin-with-Service/redis-full.conf +376 -0
  21. package/Redis-8.0.3-Windows-x64-cygwin-with-Service/redis-sentinel.exe +0 -0
  22. package/Redis-8.0.3-Windows-x64-cygwin-with-Service/redis-server.exe +0 -0
  23. package/Redis-8.0.3-Windows-x64-cygwin-with-Service/redis.conf +2348 -0
  24. package/Redis-8.0.3-Windows-x64-cygwin-with-Service/sentinel.conf +361 -0
  25. package/Redis-8.0.3-Windows-x64-cygwin-with-Service/start.bat +4 -0
  26. package/Redis-8.0.3-Windows-x64-cygwin-with-Service/uninstall_redis_service.bat +30 -0
  27. package/boot.py +51 -0
  28. package/chat_Client.js +29 -0
  29. package/controller.cjs +118 -0
  30. package/enhancedForwarder.js +378 -0
  31. package/forwarder.js +1456 -0
  32. package/groupmanager.cjs +143 -0
  33. package/howToStart.txt +8 -0
  34. package/lemma.csv +210 -0
  35. package/load.py +35 -0
  36. package/mainManager.cjs +81 -0
  37. package/mainStarter.cjs +535 -0
  38. package/main_Serve.cjs +2745 -0
  39. package/main_Study.cjs +3230 -0
  40. package/memeMergeWorker.cjs +55 -0
  41. package/model_RNN.py +117 -0
  42. package/note.txt +5 -0
  43. package/notebook.txt +8 -0
  44. package/npminstall-debug.log +206 -0
  45. package/package.json +48 -0
  46. package/public/chat_straight.html +90 -0
  47. package/public/index.html +247 -0
  48. package/public/indexmain.html +136 -0
  49. package/public/monitor.html +194 -0
  50. package/robots/wikitext-something.txt +25 -0
  51. package/runtime.proto +24 -0
  52. package/runtime_data.json +766294 -0
  53. package/serializer_seq2seq.h5 +0 -0
  54. package/start.js +46 -0
  55. package/tests/test_FIrststep1.txt +1224 -0
  56. package/tests/test_FIrststep2.txt +2956 -0
  57. package/tests/test_FIrststep3.txt +1224 -0
  58. package/tests/test_FIrststep4.txt +1396 -0
  59. package/tests/test_FIrststep5.txt +2852 -0
  60. package/tests/test_FIrststep6.txt +1516 -0
  61. package/tests/test_FirstStep7.txt +1748 -0
  62. package/tests/test_Firstsetp8.txt +2672 -0
  63. package/tokenizer.json +1 -0
  64. package/vocabularySplitter.js +253 -0
  65. package/wikitext/.gitattributes +27 -0
  66. package/wikitext/README.md +344 -0
  67. package/wikitext/describtion.txt +1 -0
@@ -0,0 +1,378 @@
1
+ const express = require('express');
2
+ const bodyParser = require('body-parser');
3
+ const axios = require('axios');
4
+ const redis = require('redis');
5
+ const cors = require('cors');
6
+ const path = require('path');
7
+ const fs = require('fs');
8
+ const os = require('os');
9
+
10
+ // 配置
11
+ const PORT = 7500;
12
+ const REDIS_URL = 'redis://localhost:6379';
13
+ const REQUEST_TIMEOUT = 30000; // 30秒
14
+ const STATIC_DIR = path.join(__dirname, 'public');
15
+
16
+ // 创建Redis客户端
17
+ let redisClient;
18
+ async function initRedis() {
19
+ redisClient = redis.createClient({
20
+ url: REDIS_URL
21
+ });
22
+ redisClient.on('error', (err) => console.error('Redis错误:', err));
23
+ await redisClient.connect();
24
+ console.log('Redis已连接');
25
+ return redisClient;
26
+ }
27
+
28
+ // 创建Express应用
29
+ const app = express();
30
+ app.use(bodyParser.json({ limit: '10mb' }));
31
+ app.use(bodyParser.urlencoded({ extended: true, limit: '10mb' }));
32
+ app.use(cors());
33
+
34
+ // 如果存在静态目录,提供静态文件服务
35
+ if (fs.existsSync(STATIC_DIR)) {
36
+ app.use(express.static(STATIC_DIR));
37
+ }
38
+
39
+ // 工作组路由表 - 从Redis加载
40
+ async function getWorkgroups() {
41
+ try {
42
+ const totalCount = parseInt(await redisClient.get('workgroup:totalCount') || '0');
43
+ const readyCount = parseInt(await redisClient.get('workgroup:readyCount') || '0');
44
+
45
+ const groups = [];
46
+ for (let i = 0; i < readyCount; i++) {
47
+ const configStr = await redisClient.get(`workgroup:${i}:config`);
48
+ if (configStr) {
49
+ groups.push(JSON.parse(configStr));
50
+ }
51
+ }
52
+
53
+ return {
54
+ total: totalCount,
55
+ ready: readyCount,
56
+ groups
57
+ };
58
+ } catch (error) {
59
+ console.error('获取工作组信息失败:', error);
60
+ return { total: 0, ready: 0, groups: [] };
61
+ }
62
+ }
63
+
64
+ // 根据文本内容确定目标工作组
65
+ async function determineTargetGroups(text) {
66
+ if (!text) return [];
67
+
68
+ const allGroups = (await getWorkgroups()).groups;
69
+ if (allGroups.length === 0) {
70
+ console.warn('没有可用的工作组');
71
+ return [];
72
+ }
73
+
74
+ // 词频分析
75
+ const words = text.toLowerCase()
76
+ .replace(/[^a-z0-9\s]/g, ' ')
77
+ .split(/\s+/)
78
+ .filter(w => w.length > 1);
79
+
80
+ if (words.length === 0) return [allGroups[0]]; // 默认使用第一个组
81
+
82
+ // 简单实现:将每个词分发到包含该词的工作组
83
+ const wordMatches = new Map(); // 记录每个工作组匹配的词数
84
+
85
+ for (const group of allGroups) {
86
+ wordMatches.set(group.id, 0);
87
+
88
+ // 实现更高效的方法是使用Redis的集合操作
89
+ // 这里使用简化的方法
90
+ try {
91
+ // 使用Redis集合检查工作组是否含有这些词
92
+ const groupKey = `workgroup:${group.id}:vocabulary`;
93
+ const vocabExists = await redisClient.exists(groupKey);
94
+
95
+ if (vocabExists) {
96
+ // 检查该组包含多少个词
97
+ for (const word of words) {
98
+ const contains = await redisClient.sIsMember(groupKey, word);
99
+ if (contains) {
100
+ wordMatches.set(group.id, wordMatches.get(group.id) + 1);
101
+ }
102
+ }
103
+ }
104
+ } catch (error) {
105
+ console.error(`检查工作组 ${group.id} 词汇时出错:`, error);
106
+ }
107
+ }
108
+
109
+ // 根据匹配词数排序工作组
110
+ const sortedGroups = [...wordMatches.entries()]
111
+ .sort((a, b) => b[1] - a[1]) // 按匹配数降序
112
+ .map(([id, matches]) => {
113
+ return {
114
+ group: allGroups.find(g => g.id === id),
115
+ matches
116
+ };
117
+ })
118
+ .filter(item => item.matches > 0);
119
+
120
+ // 如果没有匹配,返回默认组
121
+ if (sortedGroups.length === 0) {
122
+ return [allGroups[0]];
123
+ }
124
+
125
+ // 返回前3个最匹配的工作组
126
+ return sortedGroups.slice(0, 3).map(item => item.group);
127
+ }
128
+
129
+ // 向工作组发送请求
130
+ async function requestWorkgroup(group, endpoint, data) {
131
+ const ports = group.servePorts;
132
+ let lastError = null;
133
+
134
+ // 尝试每个端口
135
+ for (const port of ports) {
136
+ try {
137
+ const url = `http://localhost:${port}/api/${endpoint}`;
138
+ const response = await axios.post(url, data, {
139
+ timeout: REQUEST_TIMEOUT,
140
+ headers: {
141
+ 'Content-Type': 'application/json',
142
+ 'X-Workgroup-ID': group.id
143
+ }
144
+ });
145
+
146
+ return {
147
+ groupId: group.id,
148
+ semanticDomain: group.semanticDomain,
149
+ data: response.data,
150
+ responseTime: response.headers['x-response-time'] || 0
151
+ };
152
+ } catch (error) {
153
+ lastError = error;
154
+ console.warn(`请求工作组 ${group.id} 端口 ${port} 失败:`, error.message);
155
+ }
156
+ }
157
+
158
+ // 所有端口都失败
159
+ throw new Error(`工作组 ${group.id} 的所有端口请求失败: ${lastError?.message}`);
160
+ }
161
+
162
+ // 聚合多个工作组的结果
163
+ function aggregateResponses(responses, endpoint) {
164
+ if (responses.length === 0) {
165
+ return { error: "所有工作组都没有响应" };
166
+ }
167
+
168
+ if (responses.length === 1) {
169
+ return responses[0].data;
170
+ }
171
+
172
+ // 根据不同端点使用不同的聚合策略
173
+ switch (endpoint) {
174
+ case 'chat':
175
+ return aggregateChatResponses(responses);
176
+ case 'complete':
177
+ return aggregateCompletionResponses(responses);
178
+ case 'analyze':
179
+ return aggregateAnalysisResponses(responses);
180
+ default:
181
+ // 默认策略:按响应时间和置信度加权
182
+ return responses.sort((a, b) => {
183
+ const scoreA = (a.data.confidence || 0.5) / (parseInt(a.responseTime) || 1000);
184
+ const scoreB = (b.data.confidence || 0.5) / (parseInt(b.responseTime) || 1000);
185
+ return scoreB - scoreA;
186
+ })[0].data;
187
+ }
188
+ }
189
+
190
+ function aggregateChatResponses(responses) {
191
+ // 按置信度排序
192
+ responses.sort((a, b) =>
193
+ (b.data.confidence || 0.5) - (a.data.confidence || 0.5)
194
+ );
195
+
196
+ // 取最高置信度的回复,但附上其他组的补充信息
197
+ const primaryResponse = responses[0].data;
198
+ const otherResponses = responses.slice(1);
199
+
200
+ if (otherResponses.length > 0) {
201
+ primaryResponse.alternativeResponses = otherResponses.map(r => ({
202
+ response: r.data.response,
203
+ confidence: r.data.confidence,
204
+ semanticDomain: r.semanticDomain
205
+ }));
206
+ }
207
+
208
+ return primaryResponse;
209
+ }
210
+
211
+ function aggregateCompletionResponses(responses) {
212
+ // 简单策略:选择最长且最高置信度的补全
213
+ const bestResponse = responses.sort((a, b) => {
214
+ const scoreA = (a.data.completion?.length || 0) * (a.data.confidence || 0.5);
215
+ const scoreB = (b.data.completion?.length || 0) * (b.data.confidence || 0.5);
216
+ return scoreB - scoreA;
217
+ })[0];
218
+
219
+ return bestResponse.data;
220
+ }
221
+
222
+ function aggregateAnalysisResponses(responses) {
223
+ // 合并所有分析结果
224
+ const combinedAnalysis = {
225
+ topics: [],
226
+ entities: [],
227
+ sentiments: [],
228
+ summaries: []
229
+ };
230
+
231
+ responses.forEach(resp => {
232
+ const data = resp.data;
233
+ if (data.topics) combinedAnalysis.topics.push(...data.topics);
234
+ if (data.entities) combinedAnalysis.entities.push(...data.entities);
235
+ if (data.sentiments) combinedAnalysis.sentiments.push(data.sentiments);
236
+ if (data.summary) combinedAnalysis.summaries.push(data.summary);
237
+ });
238
+
239
+ // 去重并排序
240
+ combinedAnalysis.topics = [...new Set(combinedAnalysis.topics)];
241
+
242
+ // 合并实体并去重
243
+ const uniqueEntities = new Map();
244
+ combinedAnalysis.entities.forEach(entity => {
245
+ const key = `${entity.name}:${entity.type}`;
246
+ if (!uniqueEntities.has(key) ||
247
+ uniqueEntities.get(key).confidence < entity.confidence) {
248
+ uniqueEntities.set(key, entity);
249
+ }
250
+ });
251
+ combinedAnalysis.entities = Array.from(uniqueEntities.values());
252
+
253
+ // 计算平均情感
254
+ if (combinedAnalysis.sentiments.length > 0) {
255
+ const avgSentiment = combinedAnalysis.sentiments.reduce((acc, s) => acc + s, 0) /
256
+ combinedAnalysis.sentiments.length;
257
+ combinedAnalysis.sentiment = avgSentiment;
258
+ delete combinedAnalysis.sentiments;
259
+ }
260
+
261
+ // 选择最长的摘要
262
+ if (combinedAnalysis.summaries.length > 0) {
263
+ combinedAnalysis.summary = combinedAnalysis.summaries.sort(
264
+ (a, b) => b.length - a.length
265
+ )[0];
266
+ delete combinedAnalysis.summaries;
267
+ }
268
+
269
+ return combinedAnalysis;
270
+ }
271
+
272
+ // API路由
273
+ app.post('/api/:endpoint', async (req, res) => {
274
+ const endpoint = req.params.endpoint;
275
+ const startTime = Date.now();
276
+
277
+ try {
278
+ // 获取请求内容
279
+ const requestData = req.body;
280
+
281
+ // 确定目标工作组
282
+ let targetGroups;
283
+ if (requestData.message || requestData.text || requestData.content) {
284
+ const text = requestData.message || requestData.text || requestData.content;
285
+ targetGroups = await determineTargetGroups(text);
286
+ } else {
287
+ // 没有文本内容,选择默认组
288
+ const allGroups = (await getWorkgroups()).groups;
289
+ targetGroups = allGroups.length > 0 ? [allGroups[0]] : [];
290
+ }
291
+
292
+ if (targetGroups.length === 0) {
293
+ return res.status(503).json({
294
+ error: "没有可用的工作组",
295
+ status: "error"
296
+ });
297
+ }
298
+
299
+ // 向所有目标工作组发送请求
300
+ const requests = targetGroups.map(group =>
301
+ requestWorkgroup(group, endpoint, requestData)
302
+ .catch(error => ({
303
+ groupId: group.id,
304
+ error: error.message,
305
+ data: { error: error.message }
306
+ }))
307
+ );
308
+
309
+ // 等待所有响应
310
+ const responses = await Promise.all(requests);
311
+ const successResponses = responses.filter(r => !r.error);
312
+
313
+ if (successResponses.length === 0) {
314
+ return res.status(502).json({
315
+ error: "所有工作组请求失败",
316
+ details: responses.map(r => r.error)
317
+ });
318
+ }
319
+
320
+ // 聚合响应
321
+ const finalResponse = aggregateResponses(successResponses, endpoint);
322
+
323
+ // 添加元数据
324
+ finalResponse.meta = {
325
+ processingTime: Date.now() - startTime,
326
+ groupsConsulted: targetGroups.map(g => g.id),
327
+ timestamp: new Date().toISOString()
328
+ };
329
+
330
+ res.json(finalResponse);
331
+
332
+ // 记录请求
333
+ console.log(`[API:${endpoint}] 处理完成,耗时 ${Date.now() - startTime}ms, 咨询了 ${targetGroups.length} 个工作组`);
334
+ } catch (error) {
335
+ console.error(`处理 ${endpoint} 请求时出错:`, error);
336
+ res.status(500).json({
337
+ error: error.message,
338
+ status: "error"
339
+ });
340
+ }
341
+ });
342
+
343
+ // 工作组状态API
344
+ app.get('/api/workgroups/status', async (req, res) => {
345
+ try {
346
+ const status = await getWorkgroups();
347
+ res.json(status);
348
+ } catch (error) {
349
+ res.status(500).json({ error: error.message });
350
+ }
351
+ });
352
+
353
+ // 健康检查
354
+ app.get('/health', (req, res) => {
355
+ res.json({ status: 'ok', uptime: process.uptime() });
356
+ });
357
+
358
+ // 启动服务器
359
+ async function start() {
360
+ try {
361
+ await initRedis();
362
+
363
+ app.listen(PORT, () => {
364
+ console.log(`增强型转发器运行在 http://localhost:${PORT}`);
365
+ console.log(`系统信息: ${os.platform()} ${os.release()}, ${os.cpus().length} CPU, ${Math.round(os.totalmem()/1024/1024/1024)}GB RAM`);
366
+ });
367
+ } catch (error) {
368
+ console.error('启动增强型转发器失败:', error);
369
+ process.exit(1);
370
+ }
371
+ }
372
+
373
+ // 启动入口
374
+ if (require.main === module) {
375
+ start();
376
+ }
377
+
378
+ module.exports = { app, start };