@yu_robotics/remote-cli-router 1.0.1 → 1.0.4
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.
- package/dist/binding/BindingManager.d.ts +28 -16
- package/dist/binding/BindingManager.d.ts.map +1 -1
- package/dist/binding/BindingManager.js +117 -26
- package/dist/binding/BindingManager.js.map +1 -1
- package/dist/feishu/FeishuLongConnHandler.d.ts +74 -1
- package/dist/feishu/FeishuLongConnHandler.d.ts.map +1 -1
- package/dist/feishu/FeishuLongConnHandler.js +600 -30
- package/dist/feishu/FeishuLongConnHandler.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +4 -3
- package/dist/server.js.map +1 -1
- package/dist/storage/JsonStore.d.ts +18 -18
- package/dist/storage/JsonStore.d.ts.map +1 -1
- package/dist/storage/JsonStore.js +82 -29
- package/dist/storage/JsonStore.js.map +1 -1
- package/dist/storage/MemoryStore.d.ts +6 -6
- package/dist/storage/MemoryStore.d.ts.map +1 -1
- package/dist/storage/MemoryStore.js +24 -14
- package/dist/storage/MemoryStore.js.map +1 -1
- package/dist/types/index.d.ts +17 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/utils/ToolFormatter.d.ts +2 -2
- package/dist/utils/ToolFormatter.d.ts.map +1 -1
- package/dist/utils/ToolFormatter.js +67 -17
- package/dist/utils/ToolFormatter.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DeviceBinding, UserBinding } from '../types';
|
|
2
2
|
import { JsonStore } from '../storage/JsonStore';
|
|
3
3
|
/**
|
|
4
4
|
* Binding Manager
|
|
5
5
|
* Responsible for managing user and device binding relationships
|
|
6
|
+
* Supports multiple devices per user with one active device
|
|
6
7
|
*/
|
|
7
8
|
export declare class BindingManager {
|
|
8
9
|
private store;
|
|
@@ -13,45 +14,56 @@ export declare class BindingManager {
|
|
|
13
14
|
* @param deviceName Device name
|
|
14
15
|
* @returns Binding code object
|
|
15
16
|
*/
|
|
16
|
-
generateBindingCode(deviceId: string, deviceName: string): Promise<BindingCode>;
|
|
17
|
+
generateBindingCode(deviceId: string, deviceName: string): Promise<import('../types').BindingCode>;
|
|
17
18
|
/**
|
|
18
19
|
* Verify binding code
|
|
19
20
|
* @param code Binding code
|
|
20
21
|
* @returns Binding code object, returns null if invalid or expired
|
|
21
22
|
*/
|
|
22
|
-
verifyBindingCode(code: string): Promise<BindingCode | null>;
|
|
23
|
+
verifyBindingCode(code: string): Promise<import('../types').BindingCode | null>;
|
|
23
24
|
/**
|
|
24
|
-
* Bind user and device
|
|
25
|
-
*
|
|
26
|
-
* @param deviceId Device unique identifier
|
|
27
|
-
* @param deviceName Device name
|
|
25
|
+
* Bind user and device (supports multi-device)
|
|
26
|
+
* First device becomes active; subsequent devices are added as inactive.
|
|
28
27
|
*/
|
|
29
28
|
bindUser(openId: string, deviceId: string, deviceName: string): Promise<void>;
|
|
30
29
|
/**
|
|
31
30
|
* Get user binding information
|
|
32
|
-
* @param openId Feishu user open_id
|
|
33
|
-
* @returns Binding information, returns null if not bound
|
|
34
31
|
*/
|
|
35
32
|
getUserBinding(openId: string): Promise<UserBinding | null>;
|
|
36
33
|
/**
|
|
37
|
-
* Get
|
|
38
|
-
|
|
39
|
-
|
|
34
|
+
* Get all devices for a user
|
|
35
|
+
*/
|
|
36
|
+
getUserDevices(openId: string): Promise<DeviceBinding[]>;
|
|
37
|
+
/**
|
|
38
|
+
* Get the active device for a user
|
|
39
|
+
*/
|
|
40
|
+
getActiveDevice(openId: string): Promise<DeviceBinding | null>;
|
|
41
|
+
/**
|
|
42
|
+
* Switch the active device for a user
|
|
43
|
+
* @returns true if switch was successful
|
|
44
|
+
*/
|
|
45
|
+
switchActiveDevice(openId: string, deviceId: string): Promise<boolean>;
|
|
46
|
+
/**
|
|
47
|
+
* Unbind a specific device from a user
|
|
48
|
+
* If the active device is removed, promotes the first remaining device.
|
|
49
|
+
* If no devices remain, removes the entire user binding.
|
|
50
|
+
* @returns true if device was found and removed
|
|
51
|
+
*/
|
|
52
|
+
unbindDevice(openId: string, deviceId: string): Promise<boolean>;
|
|
53
|
+
/**
|
|
54
|
+
* Get device binding information via reverse lookup
|
|
40
55
|
*/
|
|
41
56
|
getDeviceBinding(deviceId: string): Promise<UserBinding | null>;
|
|
42
57
|
/**
|
|
43
|
-
* Unbind user
|
|
44
|
-
* @param openId Feishu user open_id
|
|
58
|
+
* Unbind all devices for a user
|
|
45
59
|
*/
|
|
46
60
|
unbindUser(openId: string): Promise<void>;
|
|
47
61
|
/**
|
|
48
62
|
* Update user last active time
|
|
49
|
-
* @param openId Feishu user open_id
|
|
50
63
|
*/
|
|
51
64
|
updateLastActive(openId: string): Promise<void>;
|
|
52
65
|
/**
|
|
53
66
|
* Generate random binding code (format: XXX-XXX-XXX)
|
|
54
|
-
* @returns Binding code string
|
|
55
67
|
*/
|
|
56
68
|
private generateRandomCode;
|
|
57
69
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BindingManager.d.ts","sourceRoot":"","sources":["../../src/binding/BindingManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"BindingManager.d.ts","sourceRoot":"","sources":["../../src/binding/BindingManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD;;;;GAIG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAAY;gBAEb,KAAK,EAAE,SAAS;IAI5B;;;;;OAKG;IACG,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,UAAU,EAAE,WAAW,CAAC;IAiBxG;;;;OAIG;IACG,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,UAAU,EAAE,WAAW,GAAG,IAAI,CAAC;IAIrF;;;OAGG;IACG,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA6CnF;;OAEG;IACG,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAIjE;;OAEG;IACG,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAK9D;;OAEG;IACG,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAQpE;;;OAGG;IACG,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAsB5E;;;;;OAKG;IACG,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAgCtE;;OAEG;IACG,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAQrE;;OAEG;IACG,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/C;;OAEG;IACG,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrD;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAe1B;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}
|
|
@@ -4,6 +4,7 @@ exports.BindingManager = void 0;
|
|
|
4
4
|
/**
|
|
5
5
|
* Binding Manager
|
|
6
6
|
* Responsible for managing user and device binding relationships
|
|
7
|
+
* Supports multiple devices per user with one active device
|
|
7
8
|
*/
|
|
8
9
|
class BindingManager {
|
|
9
10
|
store;
|
|
@@ -39,62 +40,152 @@ class BindingManager {
|
|
|
39
40
|
return this.store.getBindingCode(code);
|
|
40
41
|
}
|
|
41
42
|
/**
|
|
42
|
-
* Bind user and device
|
|
43
|
-
*
|
|
44
|
-
* @param deviceId Device unique identifier
|
|
45
|
-
* @param deviceName Device name
|
|
43
|
+
* Bind user and device (supports multi-device)
|
|
44
|
+
* First device becomes active; subsequent devices are added as inactive.
|
|
46
45
|
*/
|
|
47
46
|
async bindUser(openId, deviceId, deviceName) {
|
|
48
47
|
const now = Date.now();
|
|
49
|
-
// Check if user already has a binding
|
|
50
48
|
const existingBinding = await this.getUserBinding(openId);
|
|
51
49
|
if (existingBinding) {
|
|
52
|
-
//
|
|
50
|
+
// Check if device already exists (rebinding scenario)
|
|
51
|
+
const deviceIndex = existingBinding.devices.findIndex(d => d.deviceId === deviceId);
|
|
52
|
+
if (deviceIndex >= 0) {
|
|
53
|
+
// Update existing device entry
|
|
54
|
+
existingBinding.devices[deviceIndex].deviceName = deviceName;
|
|
55
|
+
existingBinding.devices[deviceIndex].lastActiveAt = now;
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
// Add new device as inactive
|
|
59
|
+
existingBinding.devices.push({
|
|
60
|
+
deviceId,
|
|
61
|
+
deviceName,
|
|
62
|
+
boundAt: now,
|
|
63
|
+
lastActiveAt: now,
|
|
64
|
+
isActive: false,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
existingBinding.updatedAt = now;
|
|
68
|
+
await this.store.setUserBinding(openId, existingBinding);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
// First device for this user - set as active
|
|
72
|
+
const binding = {
|
|
73
|
+
openId,
|
|
74
|
+
devices: [{
|
|
75
|
+
deviceId,
|
|
76
|
+
deviceName,
|
|
77
|
+
boundAt: now,
|
|
78
|
+
lastActiveAt: now,
|
|
79
|
+
isActive: true,
|
|
80
|
+
}],
|
|
81
|
+
activeDeviceId: deviceId,
|
|
82
|
+
createdAt: now,
|
|
83
|
+
updatedAt: now,
|
|
84
|
+
};
|
|
85
|
+
await this.store.setUserBinding(openId, binding);
|
|
53
86
|
}
|
|
54
|
-
// Create new binding relationship
|
|
55
|
-
const binding = {
|
|
56
|
-
openId,
|
|
57
|
-
deviceId,
|
|
58
|
-
deviceName,
|
|
59
|
-
boundAt: now,
|
|
60
|
-
lastActiveAt: now
|
|
61
|
-
};
|
|
62
|
-
// Store user -> device mapping
|
|
63
|
-
await this.store.setUserBinding(openId, binding);
|
|
64
87
|
}
|
|
65
88
|
/**
|
|
66
89
|
* Get user binding information
|
|
67
|
-
* @param openId Feishu user open_id
|
|
68
|
-
* @returns Binding information, returns null if not bound
|
|
69
90
|
*/
|
|
70
91
|
async getUserBinding(openId) {
|
|
71
92
|
return this.store.getUserBinding(openId);
|
|
72
93
|
}
|
|
73
94
|
/**
|
|
74
|
-
* Get
|
|
75
|
-
|
|
76
|
-
|
|
95
|
+
* Get all devices for a user
|
|
96
|
+
*/
|
|
97
|
+
async getUserDevices(openId) {
|
|
98
|
+
const binding = this.store.getUserBinding(openId);
|
|
99
|
+
return binding?.devices || [];
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Get the active device for a user
|
|
103
|
+
*/
|
|
104
|
+
async getActiveDevice(openId) {
|
|
105
|
+
const binding = this.store.getUserBinding(openId);
|
|
106
|
+
if (!binding || !binding.activeDeviceId) {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
return binding.devices.find(d => d.deviceId === binding.activeDeviceId) || null;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Switch the active device for a user
|
|
113
|
+
* @returns true if switch was successful
|
|
114
|
+
*/
|
|
115
|
+
async switchActiveDevice(openId, deviceId) {
|
|
116
|
+
const binding = this.store.getUserBinding(openId);
|
|
117
|
+
if (!binding) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
const targetDevice = binding.devices.find(d => d.deviceId === deviceId);
|
|
121
|
+
if (!targetDevice) {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
// Update isActive flags
|
|
125
|
+
for (const device of binding.devices) {
|
|
126
|
+
device.isActive = device.deviceId === deviceId;
|
|
127
|
+
}
|
|
128
|
+
binding.activeDeviceId = deviceId;
|
|
129
|
+
binding.updatedAt = Date.now();
|
|
130
|
+
await this.store.setUserBinding(openId, binding);
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Unbind a specific device from a user
|
|
135
|
+
* If the active device is removed, promotes the first remaining device.
|
|
136
|
+
* If no devices remain, removes the entire user binding.
|
|
137
|
+
* @returns true if device was found and removed
|
|
138
|
+
*/
|
|
139
|
+
async unbindDevice(openId, deviceId) {
|
|
140
|
+
const binding = this.store.getUserBinding(openId);
|
|
141
|
+
if (!binding) {
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
const deviceIndex = binding.devices.findIndex(d => d.deviceId === deviceId);
|
|
145
|
+
if (deviceIndex < 0) {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
// Remove device
|
|
149
|
+
binding.devices.splice(deviceIndex, 1);
|
|
150
|
+
await this.store.removeDeviceToUserMap(deviceId);
|
|
151
|
+
if (binding.devices.length === 0) {
|
|
152
|
+
// No devices left, delete the entire binding
|
|
153
|
+
await this.store.deleteUserBinding(openId);
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
// If the removed device was the active one, promote first remaining device
|
|
157
|
+
if (binding.activeDeviceId === deviceId) {
|
|
158
|
+
binding.devices[0].isActive = true;
|
|
159
|
+
binding.activeDeviceId = binding.devices[0].deviceId;
|
|
160
|
+
}
|
|
161
|
+
binding.updatedAt = Date.now();
|
|
162
|
+
await this.store.setUserBinding(openId, binding);
|
|
163
|
+
return true;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Get device binding information via reverse lookup
|
|
77
167
|
*/
|
|
78
168
|
async getDeviceBinding(deviceId) {
|
|
79
|
-
|
|
169
|
+
const openId = this.store.getUserByDeviceId(deviceId);
|
|
170
|
+
if (!openId) {
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
return this.store.getUserBinding(openId);
|
|
80
174
|
}
|
|
81
175
|
/**
|
|
82
|
-
* Unbind user
|
|
83
|
-
* @param openId Feishu user open_id
|
|
176
|
+
* Unbind all devices for a user
|
|
84
177
|
*/
|
|
85
178
|
async unbindUser(openId) {
|
|
86
179
|
await this.store.deleteUserBinding(openId);
|
|
87
180
|
}
|
|
88
181
|
/**
|
|
89
182
|
* Update user last active time
|
|
90
|
-
* @param openId Feishu user open_id
|
|
91
183
|
*/
|
|
92
184
|
async updateLastActive(openId) {
|
|
93
185
|
await this.store.updateLastActive(openId);
|
|
94
186
|
}
|
|
95
187
|
/**
|
|
96
188
|
* Generate random binding code (format: XXX-XXX-XXX)
|
|
97
|
-
* @returns Binding code string
|
|
98
189
|
*/
|
|
99
190
|
generateRandomCode() {
|
|
100
191
|
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BindingManager.js","sourceRoot":"","sources":["../../src/binding/BindingManager.ts"],"names":[],"mappings":";;;AAGA
|
|
1
|
+
{"version":3,"file":"BindingManager.js","sourceRoot":"","sources":["../../src/binding/BindingManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -21,6 +21,9 @@ export declare class FeishuLongConnHandler {
|
|
|
21
21
|
private appId;
|
|
22
22
|
private appSecret;
|
|
23
23
|
private readonly FEISHU_MESSAGE_LIMIT;
|
|
24
|
+
private readonly CARD_ELEMENT_LIMIT;
|
|
25
|
+
private readonly CARD_DATA_SIZE_LIMIT;
|
|
26
|
+
private readonly CARD_SIZE_BUFFER;
|
|
24
27
|
private messageChains;
|
|
25
28
|
private lastProcessedLengths;
|
|
26
29
|
private messageLocks;
|
|
@@ -70,8 +73,38 @@ export declare class FeishuLongConnHandler {
|
|
|
70
73
|
private handleStatusCommand;
|
|
71
74
|
/**
|
|
72
75
|
* Handle unbind command
|
|
76
|
+
* Usage: /unbind or /unbind all (unbind all devices)
|
|
77
|
+
* For unbinding specific device, use /device unbind <device-id>
|
|
73
78
|
*/
|
|
74
79
|
private handleUnbindCommand;
|
|
80
|
+
/**
|
|
81
|
+
* Handle device command
|
|
82
|
+
* Usage:
|
|
83
|
+
* /device - List all bound devices (same as /device list)
|
|
84
|
+
* /device list - List all bound devices
|
|
85
|
+
* /device switch <device-id|index> - Switch active device (by ID or index number)
|
|
86
|
+
* /device <device-id|index> - Quick switch to device (by ID or index number)
|
|
87
|
+
* /device unbind <device-id|index> - Unbind a specific device (by ID or index number)
|
|
88
|
+
*/
|
|
89
|
+
private handleDeviceCommand;
|
|
90
|
+
/**
|
|
91
|
+
* Handle /device list
|
|
92
|
+
*/
|
|
93
|
+
private handleDeviceList;
|
|
94
|
+
/**
|
|
95
|
+
* Resolve device identifier (ID or index) to device ID
|
|
96
|
+
* @returns Resolved device ID or null if not found
|
|
97
|
+
*/
|
|
98
|
+
private resolveDeviceIdentifier;
|
|
99
|
+
/**
|
|
100
|
+
* Handle /device switch <device-id-or-index>
|
|
101
|
+
* Also handles quick switch: /device <device-id-or-index>
|
|
102
|
+
*/
|
|
103
|
+
private handleDeviceSwitch;
|
|
104
|
+
/**
|
|
105
|
+
* Handle /device unbind <device-id-or-index>
|
|
106
|
+
*/
|
|
107
|
+
private handleDeviceUnbind;
|
|
75
108
|
/**
|
|
76
109
|
* Handle help command
|
|
77
110
|
*/
|
|
@@ -107,6 +140,46 @@ export declare class FeishuLongConnHandler {
|
|
|
107
140
|
* - "~⬅️ Continued from previous message...~" (44 chars) at start of continuation chunks
|
|
108
141
|
*/
|
|
109
142
|
private splitTextIntoChunks;
|
|
143
|
+
/**
|
|
144
|
+
* Split Card 2.0 elements into chunks based on Feishu limits
|
|
145
|
+
*
|
|
146
|
+
* Feishu Card 2.0 has two main limits:
|
|
147
|
+
* 1. Element count: Max 200 tagged nodes per card (we use 150 for safety)
|
|
148
|
+
* 2. Data size: Max 3,000,000 characters in the data field (JSON.stringify result)
|
|
149
|
+
*
|
|
150
|
+
* This function splits elements array into chunks that satisfy both limits,
|
|
151
|
+
* and adds continuation indicators between chunks for better UX.
|
|
152
|
+
*
|
|
153
|
+
* Note: Element counting uses recursive tag counting - all nodes with 'tag' property
|
|
154
|
+
* are counted, including nested components, text elements, and container children.
|
|
155
|
+
*
|
|
156
|
+
* @param elements Array of Feishu Card 2.0 elements
|
|
157
|
+
* @returns Array of element chunks, each satisfying Feishu's limits
|
|
158
|
+
*/
|
|
159
|
+
private splitElementsIntoChunks;
|
|
160
|
+
/**
|
|
161
|
+
* Recursively count all nodes with 'tag' property in the element tree
|
|
162
|
+
* According to Feishu docs, all nodes with 'tag' property count towards the 200 limit
|
|
163
|
+
*
|
|
164
|
+
* @param obj The object or array to count tags in
|
|
165
|
+
* @returns Total count of nodes with 'tag' property
|
|
166
|
+
*/
|
|
167
|
+
private countTaggedNodes;
|
|
168
|
+
/**
|
|
169
|
+
* Check if elements array needs to be split based on Feishu limits
|
|
170
|
+
* @param elements Array of elements to check
|
|
171
|
+
* @returns true if splitting is needed
|
|
172
|
+
*/
|
|
173
|
+
private checkIfElementsNeedSplitting;
|
|
174
|
+
/**
|
|
175
|
+
* Create a continuation card message
|
|
176
|
+
* Used when elements need to be split across multiple cards
|
|
177
|
+
*
|
|
178
|
+
* @param openId User's open_id to send the message to
|
|
179
|
+
* @param elements Array of Feishu Card 2.0 elements
|
|
180
|
+
* @returns The new message ID, or null on error
|
|
181
|
+
*/
|
|
182
|
+
private createContinuationCard;
|
|
110
183
|
/**
|
|
111
184
|
* Update streaming message content
|
|
112
185
|
* Automatically creates new messages if content exceeds Feishu's size limit
|
|
@@ -131,7 +204,7 @@ export declare class FeishuLongConnHandler {
|
|
|
131
204
|
* @param sessionAbbr Optional session abbreviation
|
|
132
205
|
* @param openId User's open_id for creating continuation messages
|
|
133
206
|
*/
|
|
134
|
-
finalizeStreamingMessage(messageId: string, elements: any[], sessionAbbr?: string, openId?: string): Promise<boolean>;
|
|
207
|
+
finalizeStreamingMessage(messageId: string, elements: any[], sessionAbbr?: string, openId?: string, cwd?: string): Promise<boolean>;
|
|
135
208
|
private _finalizeStreamingMessage;
|
|
136
209
|
/**
|
|
137
210
|
* Start the Feishu WebSocket long connection
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FeishuLongConnHandler.d.ts","sourceRoot":"","sources":["../../src/feishu/FeishuLongConnHandler.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAE3D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,SAAS,CAAC;CAClB;AAED;;;GAGG;AACH,qBAAa,qBAAqB;IAChC,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,QAAQ,CAA8B;IAC9C,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,SAAS,CAAS;IAE1B,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAQ;
|
|
1
|
+
{"version":3,"file":"FeishuLongConnHandler.d.ts","sourceRoot":"","sources":["../../src/feishu/FeishuLongConnHandler.ts"],"names":[],"mappings":"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"}
|