0412Xu commited on
Commit
2c70af5
·
verified ·
1 Parent(s): 3327444

Upload utils.js

Browse files
Files changed (1) hide show
  1. src/utils/utils.js +115 -113
src/utils/utils.js CHANGED
@@ -4,44 +4,83 @@ const crypto = require('crypto');
4
  const { v4: uuidv4 } = require('uuid');
5
  const $root = require('../proto/message.js');
6
 
7
- const regex = /<\|BEGIN_SYSTEM\|>.*?<\|END_SYSTEM\|>.*?<\|BEGIN_USER\|>.*?<\|END_USER\|>/s;
8
-
9
  function generateCursorBody(messages, modelName) {
10
 
11
- const systemMessages = messages
12
- .filter((msg) => msg.role === 'system');
13
- const instruction = systemMessages.map((msg) => msg.content).join('\n')
14
-
15
- const nonSystemMessages = messages
16
- .filter((msg) => msg.role !== 'system');
17
- const formattedMessages = nonSystemMessages.map((msg) => ({
18
- ...msg,
19
- role: msg.role === 'user' ? 1 : 2,
20
- messageId: uuidv4()
21
- }));
22
-
23
- const chatBody = {
24
- userMessages: formattedMessages,
25
- instructions: {
26
- instruction: "Alway respond in 中文.\n" + instruction
27
- },
28
- model: {
29
- name: modelName,
30
- empty: '',
31
- },
32
- unknown13: 1,
33
- conversationId: uuidv4(),
34
- unknown16: 1,
35
- unknown29: 1,
36
- unknown31: 0,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  };
38
 
39
- const errMsg = $root.ChatMessage.verify(chatBody);
40
  if (errMsg) throw Error(errMsg);
41
- const chatMessageInstance = $root.ChatMessage.create(chatBody);
42
- let buffer = $root.ChatMessage.encode(chatMessageInstance).finish();
43
  let magicNumber = 0x00
44
- if (formattedMessages.length >= 5){
45
  buffer = zlib.gzipSync(buffer)
46
  magicNumber = 0x01
47
  }
@@ -58,99 +97,66 @@ function generateCursorBody(messages, modelName) {
58
  function chunkToUtf8String(chunk) {
59
  const results = []
60
  const errorResults = { hasError: false, errorMessage: '' }
61
-
62
- try {
63
- if (!chunk || chunk.length === 0) {
64
- console.error('收到空的chunk数据');
65
- return '';
66
- }
67
-
68
- const buffer = Buffer.from(chunk, 'hex');
69
 
 
70
  for(let i = 0; i < buffer.length; i++){
71
- try {
72
- if (i + 5 >= buffer.length) {
73
- console.error('数据不足以读取魔数和长度');
74
- break;
 
 
 
 
 
 
 
 
75
  }
76
-
77
- const magicNumber = parseInt(buffer.subarray(i, i + 1).toString('hex'), 16)
78
- const dataLength = parseInt(buffer.subarray(i + 1, i + 5).toString('hex'), 16)
79
-
80
- if (dataLength <= 0 || dataLength > 1000000) {
81
- console.error(`数据长度异常: ${dataLength}`);
82
- break;
83
- }
84
-
85
- if (i + 5 + dataLength > buffer.length) {
86
- console.error('数据不足以读取内容');
87
- break;
88
  }
89
 
90
- const data = buffer.subarray(i + 5, i + 5 + dataLength)
91
-
92
- // 处理不同类型的消息
93
- const processMessage = async (data, isGzip = false) => {
94
- try {
95
- let processedData = data;
96
- if (isGzip) {
97
- processedData = zlib.gunzipSync(data);
98
- }
99
-
100
- if (magicNumber === 0 || magicNumber === 1) {
101
- // 处理 Proto 消息
102
- const resMessage = $root.ResMessage.decode(processedData);
103
- if (resMessage.content !== undefined) {
104
- results.push(resMessage.content);
105
- }
106
- } else if (magicNumber === 2 || magicNumber === 3) {
107
- // 处理 JSON 消息
108
- const utf8 = processedData.toString('utf-8');
109
- const message = JSON.parse(utf8);
110
-
111
- if (message && message.error) {
112
- console.error(`检测到JSON错误对象(${isGzip ? 'Gzip ' : ''}):`, utf8);
113
- errorResults.hasError = true;
114
- errorResults.errorMessage = utf8;
115
- }
116
- } else {
117
- console.log('未知的魔数:', magicNumber);
118
  }
119
- } catch (error) {
120
- console.error(`处理${isGzip ? 'Gzip ' : ''}消息错误:`, error);
121
- }
122
- };
123
-
124
- // 根据魔数处理不同类型的消息
125
- if (magicNumber === 0 || magicNumber === 2) {
126
- processMessage(data, false);
127
- } else if (magicNumber === 1 || magicNumber === 3) {
128
- processMessage(data, true);
129
  }
130
-
131
- i += 5 + dataLength - 1;
132
- } catch (chunkParseError) {
133
- console.error('解析单个chunk部分错误:', chunkParseError);
134
- i += 1;
135
  }
 
 
 
 
 
136
  }
137
  } catch (err) {
138
- console.error('解析chunk整体错误:', err);
139
  }
140
 
 
141
  if (errorResults.hasError) {
142
  return { error: errorResults.errorMessage };
143
  }
144
 
145
- return results.join('');
146
- }
147
-
148
- function generateUUIDHash(input, salt = '') {
149
- const hash = crypto.createHash('sha256').update(input + salt).digest('hex');
150
- const hash128 = hash.substring(0, 32);
151
- const uuid = `${hash128.substring(0, 8)}-${hash128.substring(8, 12)}-${hash128.substring(12, 16)}-${hash128.substring(16, 20)}-${hash128.substring(20, 32)}`;
152
-
153
- return uuid;
154
  }
155
 
156
  function generateHashed64Hex(input, salt = '') {
@@ -169,11 +175,9 @@ function obfuscateBytes(byteArray) {
169
  }
170
 
171
  function generateCursorChecksum(token) {
172
- // 生成machineId和macMachineId
173
  const machineId = generateHashed64Hex(token, 'machineId');
174
  const macMachineId = generateHashed64Hex(token, 'macMachineId');
175
 
176
- // 获取时间戳并转换为字节数组
177
  const timestamp = Math.floor(Date.now() / 1e6);
178
  const byteArray = new Uint8Array([
179
  (timestamp >> 40) & 255,
@@ -184,11 +188,9 @@ function generateCursorChecksum(token) {
184
  255 & timestamp,
185
  ]);
186
 
187
- // 混淆字节数组并进行base64编码
188
  const obfuscatedBytes = obfuscateBytes(byteArray);
189
  const encodedChecksum = Buffer.from(obfuscatedBytes).toString('base64');
190
 
191
- // 组合最终的checksum
192
  return `${encodedChecksum}${machineId}/${macMachineId}`;
193
  }
194
 
 
4
  const { v4: uuidv4 } = require('uuid');
5
  const $root = require('../proto/message.js');
6
 
 
 
7
  function generateCursorBody(messages, modelName) {
8
 
9
+ const instruction = messages
10
+ .filter(msg => msg.role === 'system')
11
+ .map(msg => msg.content)
12
+ .join('\n')
13
+
14
+ const formattedMessages = messages
15
+ .filter(msg => msg.role !== 'system')
16
+ .map(msg => ({
17
+ content: msg.content,
18
+ role: msg.role === 'user' ? 1 : 2,
19
+ messageId: uuidv4(),
20
+ ...(msg.role === 'user' ? { chatModeEnum: 1 } : {})
21
+ //...(msg.role !== 'user' ? { summaryId: uuidv4() } : {})
22
+ }));
23
+
24
+ const messageIds = formattedMessages.map(msg => {
25
+ const { role, messageId, summaryId } = msg;
26
+ return summaryId ? { role, messageId, summaryId } : { role, messageId };
27
+ });
28
+
29
+ const body = {
30
+ request:{
31
+ messages: formattedMessages,
32
+ unknown2: 1,
33
+ instruction: {
34
+ instruction: instruction
35
+ },
36
+ unknown4: 1,
37
+ model: {
38
+ name: modelName,
39
+ empty: '',
40
+ },
41
+ webTool: "",
42
+ unknown13: 1,
43
+ cursorSetting: {
44
+ name: "cursor\\aisettings",
45
+ unknown3: "",
46
+ unknown6: {
47
+ unknwon1: "",
48
+ unknown2: ""
49
+ },
50
+ unknown8: 1,
51
+ unknown9: 1
52
+ },
53
+ unknown19: 1,
54
+ //unknown22: 1,
55
+ conversationId: uuidv4(),
56
+ metadata: {
57
+ os: "win32",
58
+ arch: "x64",
59
+ version: "10.0.22631",
60
+ path: "C:\\Program Files\\PowerShell\\7\\pwsh.exe",
61
+ timestamp: new Date().toISOString(),
62
+ },
63
+ unknown27: 0,
64
+ //unknown29: "",
65
+ messageIds: messageIds,
66
+ largeContext: 0,
67
+ unknown38: 0,
68
+ chatModeEnum: 1,
69
+ unknown47: "",
70
+ unknown48: 0,
71
+ unknown49: 0,
72
+ unknown51: 0,
73
+ unknown53: 1,
74
+ chatMode: "Ask"
75
+ }
76
  };
77
 
78
+ const errMsg = $root.StreamUnifiedChatWithToolsRequest.verify(body);
79
  if (errMsg) throw Error(errMsg);
80
+ const instance = $root.StreamUnifiedChatWithToolsRequest.create(body);
81
+ let buffer = $root.StreamUnifiedChatWithToolsRequest.encode(instance).finish();
82
  let magicNumber = 0x00
83
+ if (formattedMessages.length >= 3){
84
  buffer = zlib.gzipSync(buffer)
85
  magicNumber = 0x01
86
  }
 
97
  function chunkToUtf8String(chunk) {
98
  const results = []
99
  const errorResults = { hasError: false, errorMessage: '' }
100
+ const buffer = Buffer.from(chunk, 'hex');
101
+ //console.log("Chunk buffer:", buffer.toString('hex'))
 
 
 
 
 
 
102
 
103
+ try {
104
  for(let i = 0; i < buffer.length; i++){
105
+ const magicNumber = parseInt(buffer.subarray(i, i + 1).toString('hex'), 16)
106
+ const dataLength = parseInt(buffer.subarray(i + 1, i + 5).toString('hex'), 16)
107
+ const data = buffer.subarray(i + 5, i + 5 + dataLength)
108
+ //console.log("Parsed buffer:", magicNumber, dataLength, data.toString('hex'))
109
+
110
+ if (magicNumber == 0 || magicNumber == 1) {
111
+ const gunzipData = magicNumber == 0 ? data : zlib.gunzipSync(data)
112
+ const response = $root.StreamUnifiedChatWithToolsResponse.decode(gunzipData);
113
+ const thinking = response?.message?.thinking?.content
114
+ if (thinking !== undefined){
115
+ results.push(thinking);
116
+ //console.log(thinking);
117
  }
118
+
119
+ const content = response?.message?.content
120
+ if (content !== undefined){
121
+ results.push(content)
122
+ //console.log(content)
 
 
 
 
 
 
 
123
  }
124
 
125
+ }
126
+ else if (magicNumber == 2 || magicNumber == 3) {
127
+ // Json message
128
+ const gunzipData = magicNumber == 2 ? data : zlib.gunzipSync(data)
129
+ const utf8 = gunzipData.toString('utf-8')
130
+ const message = JSON.parse(utf8)
131
+
132
+ if (message != null && (typeof message !== 'object' ||
133
+ (Array.isArray(message) ? message.length > 0 : Object.keys(message).length > 0))){
134
+ //results.push(utf8)
135
+ console.error(utf8)
136
+
137
+ // 检查是否为错误消息
138
+ if (message && message.error) {
139
+ errorResults.hasError = true;
140
+ errorResults.errorMessage = utf8;
 
 
 
 
 
 
 
 
 
 
 
 
141
  }
 
 
 
 
 
 
 
 
 
 
142
  }
 
 
 
 
 
143
  }
144
+ else {
145
+ //console.log('Unknown magic number when parsing chunk response: ' + magicNumber)
146
+ }
147
+
148
+ i += 5 + dataLength - 1
149
  }
150
  } catch (err) {
151
+ console.log('Error parsing chunk response:', err)
152
  }
153
 
154
+ // 如果存在错误,返回错误对象
155
  if (errorResults.hasError) {
156
  return { error: errorResults.errorMessage };
157
  }
158
 
159
+ return results.join('')
 
 
 
 
 
 
 
 
160
  }
161
 
162
  function generateHashed64Hex(input, salt = '') {
 
175
  }
176
 
177
  function generateCursorChecksum(token) {
 
178
  const machineId = generateHashed64Hex(token, 'machineId');
179
  const macMachineId = generateHashed64Hex(token, 'macMachineId');
180
 
 
181
  const timestamp = Math.floor(Date.now() / 1e6);
182
  const byteArray = new Uint8Array([
183
  (timestamp >> 40) & 255,
 
188
  255 & timestamp,
189
  ]);
190
 
 
191
  const obfuscatedBytes = obfuscateBytes(byteArray);
192
  const encodedChecksum = Buffer.from(obfuscatedBytes).toString('base64');
193
 
 
194
  return `${encodedChecksum}${machineId}/${macMachineId}`;
195
  }
196