@kafca/agentdock 0.1.46 → 0.1.47
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/README.md +6 -0
- package/dist/renderer/assets/{Badge-BIesaDYG.js → Badge-BYREM3t3.js} +1 -1
- package/dist/renderer/assets/{Chat-CpataoDh.js → Chat-Dtb5X7sB.js} +1 -1
- package/dist/renderer/assets/{ChatMarkdown-_Mdmltgv.js → ChatMarkdown-_slLloCh.js} +1 -1
- package/dist/renderer/assets/{Config-Pe5-zKZk.js → Config-pHichs7H.js} +1 -1
- package/dist/renderer/assets/{CronList-BnaOSPT8.js → CronList-CJQMeCjz.js} +1 -1
- package/dist/renderer/assets/{Dashboard-D05l8GKE.js → Dashboard-CY77Imde.js} +2 -2
- package/dist/renderer/assets/{EmptyState-BDBavDll.js → EmptyState-DCqmct2y.js} +1 -1
- package/dist/renderer/assets/{KnowledgeDetail-DvR798l_.js → KnowledgeDetail-DFrxa-pv.js} +1 -1
- package/dist/renderer/assets/{KnowledgeHome-r2ZuvU8-.js → KnowledgeHome-DL-vAfrH.js} +1 -1
- package/dist/renderer/assets/{Logs-BaljtmAV.js → Logs-jw9Uv590.js} +1 -1
- package/dist/renderer/assets/{Modal-CXhD_OWR.js → Modal-ChSm7tk6.js} +1 -1
- package/dist/renderer/assets/{MonitorList-D7tyipbx.js → MonitorList-DrEwyS71.js} +1 -1
- package/dist/renderer/assets/{Page-KUuFYgjg.js → Page-DhD-zgMU.js} +1 -1
- package/dist/renderer/assets/ProjectDetail-BVSjpfpL.js +11 -0
- package/dist/renderer/assets/{ProjectList-CbdHd5Ev.js → ProjectList-CHGbTJjk.js} +1 -1
- package/dist/renderer/assets/{Select-Djc8BXMC.js → Select-rHs9CSam.js} +1 -1
- package/dist/renderer/assets/{SessionChat-DOy0iKQR.js → SessionChat-CDc2FNMA.js} +1 -1
- package/dist/renderer/assets/{SessionList-DHgl1s1D.js → SessionList-Mr1uAnRW.js} +1 -1
- package/dist/renderer/assets/ThreadChat-Detu5UfN.js +23 -0
- package/dist/renderer/assets/{Workspace-DTocqY-F.js → Workspace-MRRg8ndJ.js} +1 -1
- package/dist/renderer/assets/{arrow-left-CXyya3hP.js → arrow-left-BU2NB2LA.js} +1 -1
- package/dist/renderer/assets/{book-open-9n4Kxc7E.js → book-open-D-TGvWwa.js} +1 -1
- package/dist/renderer/assets/{bot-C9HBk5XH.js → bot-IYNh8tH5.js} +1 -1
- package/dist/renderer/assets/{check-CutSg9a5.js → check-CCZ0JO_S.js} +1 -1
- package/dist/renderer/assets/{chevron-down-DrydR4i3.js → chevron-down-00bRZi15.js} +1 -1
- package/dist/renderer/assets/{circle-BEjtahw6.js → circle-CpQ8x4k_.js} +1 -1
- package/dist/renderer/assets/{desktop-DATgk_ka.js → desktop-D0k2aGSj.js} +1 -1
- package/dist/renderer/assets/{funnel-BhqZpS4f.js → funnel-UbcrCBCp.js} +1 -1
- package/dist/renderer/assets/{heart-Dp8Vs-7_.js → heart-DvLsV7tL.js} +1 -1
- package/dist/renderer/assets/{index-BKpv0P0s.js → index-B2L4G-b_.js} +1 -1
- package/dist/renderer/assets/{index-cI3pWBnN.js → index-dy-g2Bh4.js} +2 -2
- package/dist/renderer/assets/{pencil-ywcJzeOo.js → pencil-qBYOgW5M.js} +1 -1
- package/dist/renderer/assets/{play-AtN492Cx.js → play-Dn6b4AGj.js} +1 -1
- package/dist/renderer/assets/{plus-BEj14BBV.js → plus-CaApUwEm.js} +1 -1
- package/dist/renderer/assets/projects-BwF5RlNV.js +1 -0
- package/dist/renderer/assets/{save-D6ov4CNv.js → save-CN6yvTfD.js} +1 -1
- package/dist/renderer/assets/{search-C3bvw7AR.js → search-Dn2MxYiO.js} +1 -1
- package/dist/renderer/assets/{server-C1Uyedyx.js → server-DpcVLHeh.js} +1 -1
- package/dist/renderer/assets/{session-utils-DpRwJ6Nh.js → session-utils-DnD2Q_y1.js} +1 -1
- package/dist/renderer/assets/{sessions-BWmAppwK.js → sessions-eK5D4FLt.js} +1 -1
- package/dist/renderer/assets/{shield-check-CVx1mEs2.js → shield-check-DSSJkacw.js} +1 -1
- package/dist/renderer/assets/{trash-2-o-heXOgs.js → trash-2-DmYJlEvO.js} +1 -1
- package/dist/renderer/assets/{user-dPOzUqIc.js → user-Cvf_uiyQ.js} +1 -1
- package/dist/renderer/assets/{wifi-off-Fz5c3_x_.js → wifi-off-CCTloj-V.js} +1 -1
- package/dist/renderer/index.html +1 -1
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-session-coordinator.js +2 -1
- package/dist-electron/services/local-ai-core/src/agents/pi/launch.js +1 -1
- package/dist-electron/services/local-ai-core/src/agents/shared/launch-utils.js +22 -0
- package/dist-electron/services/local-ai-core/src/channel/lark/local-core-lark-gateway.js +132 -348
- package/dist-electron/services/local-ai-core/src/channel/shared/base-channel-gateway.js +303 -0
- package/dist-electron/services/local-ai-core/src/channel/weixin/local-core-weixin-gateway.js +131 -382
- package/dist-electron/services/local-ai-core/src/runtime/agent-runtime-detector.js +2 -1
- package/dist-electron/services/local-ai-core/src/runtime/channel-service.js +150 -0
- package/dist-electron/services/local-ai-core/src/runtime/env-utils.js +12 -0
- package/dist-electron/services/local-ai-core/src/runtime/external-service.js +234 -0
- package/dist-electron/services/local-ai-core/src/runtime/handlers/automation-handler.js +34 -0
- package/dist-electron/services/local-ai-core/src/runtime/handlers/capabilities-handler.js +12 -0
- package/dist-electron/services/local-ai-core/src/runtime/handlers/channel-handler.js +65 -0
- package/dist-electron/services/local-ai-core/src/runtime/handlers/external-handler.js +17 -0
- package/dist-electron/services/local-ai-core/src/runtime/handlers/knowledge-handler.js +65 -0
- package/dist-electron/services/local-ai-core/src/runtime/handlers/openai-handler.js +496 -0
- package/dist-electron/services/local-ai-core/src/runtime/handlers/provider-handler.js +24 -0
- package/dist-electron/services/local-ai-core/src/runtime/handlers/runtime-handler.js +68 -0
- package/dist-electron/services/local-ai-core/src/runtime/handlers/runtimes-handler.js +37 -0
- package/dist-electron/services/local-ai-core/src/runtime/handlers/scheduler-handler.js +34 -0
- package/dist-electron/services/local-ai-core/src/runtime/handlers/security-handler.js +49 -0
- package/dist-electron/services/local-ai-core/src/runtime/handlers/task-handler.js +27 -0
- package/dist-electron/services/local-ai-core/src/runtime/handlers/thread-handler.js +42 -0
- package/dist-electron/services/local-ai-core/src/runtime/handlers/workspace-handler.js +29 -0
- package/dist-electron/services/local-ai-core/src/runtime/local-core-controller.js +40 -592
- package/dist-electron/services/local-ai-core/src/runtime/server-helpers.js +96 -0
- package/dist-electron/services/local-ai-core/src/runtime/server.js +107 -1084
- package/dist-electron/services/local-ai-core/src/runtime/standalone.js +13 -1
- package/dist-electron/src/pages/Projects/project-provider-config.js +75 -0
- package/dist-electron/tests/contracts/architecture-docs.test.js +1 -0
- package/dist-electron/tests/electron/agent-runtime-detector.test.js +18 -0
- package/dist-electron/tests/electron/knowledge-skill-script.test.js +15 -5
- package/dist-electron/tests/electron/lac-cli.test.js +591 -688
- package/dist-electron/tests/electron/plugin-kernel.test.js +47 -31
- package/dist-electron/tests/electron/project-provider-config.test.js +71 -0
- package/dist-electron/tests/electron/workspace-task-store.test.js +19 -9
- package/dist-electron/tests/integration/local-core-cors.test.js +22 -0
- package/package.json +1 -1
- package/dist/renderer/assets/ProjectDetail-Ddq94-yu.js +0 -11
- package/dist/renderer/assets/ThreadChat-I7dYibDc.js +0 -23
- package/dist/renderer/assets/projects-Clar8lgb.js +0 -1
package/dist-electron/services/local-ai-core/src/channel/weixin/local-core-weixin-gateway.js
CHANGED
|
@@ -8,15 +8,13 @@ exports.createWeixinAttachmentContentPart = createWeixinAttachmentContentPart;
|
|
|
8
8
|
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
9
9
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
10
10
|
const node_path_1 = __importDefault(require("node:path"));
|
|
11
|
-
const node_events_1 = require("node:events");
|
|
12
11
|
const node_crypto_2 = require("node:crypto");
|
|
13
12
|
const desktop_js_1 = require("../../../../../shared/desktop.js");
|
|
14
13
|
const local_core_errors_js_1 = require("../../kernel/local-core-errors.js");
|
|
15
14
|
const content_js_1 = require("../shared/content.js");
|
|
16
15
|
const file_utils_js_1 = require("../shared/file-utils.js");
|
|
17
|
-
const session_command_runtime_js_1 = require("../shared/session-command-runtime.js");
|
|
18
16
|
const thread_routing_js_1 = require("../shared/thread-routing.js");
|
|
19
|
-
const
|
|
17
|
+
const base_channel_gateway_js_1 = require("../shared/base-channel-gateway.js");
|
|
20
18
|
const config_js_1 = require("./config.js");
|
|
21
19
|
const transport_js_1 = require("./transport.js");
|
|
22
20
|
// ==================== Constants ====================
|
|
@@ -147,169 +145,99 @@ function renderBridgeContentForWeixin(event) {
|
|
|
147
145
|
return [name, status].filter(Boolean).join(' - ');
|
|
148
146
|
}
|
|
149
147
|
// ==================== Gateway Class ====================
|
|
150
|
-
class LocalCoreWeixinGateway extends
|
|
151
|
-
options;
|
|
152
|
-
runtime = new Map();
|
|
153
|
-
threadRouting = new Map();
|
|
154
|
-
outboundEventChains = new Map();
|
|
155
|
-
outboundTurns = new Map();
|
|
148
|
+
class LocalCoreWeixinGateway extends base_channel_gateway_js_1.BaseChannelGateway {
|
|
156
149
|
processedInboundMessages = new Map();
|
|
157
|
-
mutedThreadBridgeCounts = new Map();
|
|
158
150
|
pollErrorLogWindows = new Map();
|
|
159
|
-
sessionCommandRuntime;
|
|
160
151
|
platform = 'weixin';
|
|
161
|
-
routeType = 'channel.chat';
|
|
162
152
|
constructor(options) {
|
|
163
|
-
super();
|
|
164
|
-
this.options = options;
|
|
165
|
-
const slashCommands = new thread_slash_command_dispatcher_js_1.ThreadSlashCommandDispatcher({
|
|
166
|
-
session: {
|
|
167
|
-
listThreads: (workspaceId) => this.options.getWorkspaceRouter().listThreads(workspaceId),
|
|
168
|
-
getThread: (threadId) => this.options.getWorkspaceRouter().getThread(threadId),
|
|
169
|
-
createThread: (workspaceId, title) => this.options.getWorkspaceRouter().createThread(workspaceId, title),
|
|
170
|
-
renameThread: (threadId, title) => this.options.getWorkspaceRouter().renameThread(threadId, title),
|
|
171
|
-
deleteThread: (threadId) => this.options.getWorkspaceRouter().deleteThread(threadId),
|
|
172
|
-
},
|
|
173
|
-
thread: {
|
|
174
|
-
getThreadRow: (threadId) => this.options.store.getThreadRow(threadId),
|
|
175
|
-
updateThreadAgentMode: (threadId, mode) => this.options.store.updateThreadAgentMode(threadId, mode),
|
|
176
|
-
updateThreadAgentType: (threadId, agentType) => this.options.store.updateThreadAgentType(threadId, agentType),
|
|
177
|
-
getLatestRunForThread: (threadId) => this.options.store.getLatestRunForThread(threadId),
|
|
178
|
-
createAuditEvent: (input) => this.options.store.createAuditEvent(input),
|
|
179
|
-
getAgentTypes: () => this.options.getWorkspaceRouter().getAgentTypes(),
|
|
180
|
-
setThreadMode: (threadId, mode) => this.options.getWorkspaceRouter().setThreadMode(threadId, mode),
|
|
181
|
-
closeThreadSession: (threadId) => this.options.getWorkspaceRouter().closeThreadSession(threadId),
|
|
182
|
-
interruptRun: (runId) => this.options.getWorkspaceRouter().interruptRun(runId),
|
|
183
|
-
log: this.options.log,
|
|
184
|
-
},
|
|
185
|
-
});
|
|
186
|
-
this.sessionCommandRuntime = new session_command_runtime_js_1.ChannelSessionCommandRuntime({
|
|
187
|
-
dispatcher: slashCommands,
|
|
188
|
-
store: this.options.store,
|
|
189
|
-
getThreadSessionKey: (threadId) => this.options.getWorkspaceRouter().getThreadSessionKey(threadId),
|
|
190
|
-
setThreadRoute: (sessionKey, route) => {
|
|
191
|
-
this.threadRouting.set(sessionKey, route);
|
|
192
|
-
},
|
|
193
|
-
createRoute: (input, threadId) => ({
|
|
194
|
-
workspaceId: input.workspaceId,
|
|
195
|
-
instanceId: input.instanceId,
|
|
196
|
-
platformKey: input.platformKey,
|
|
197
|
-
platformUserId: input.platformUserId,
|
|
198
|
-
chatId: input.chatId,
|
|
199
|
-
threadId,
|
|
200
|
-
}),
|
|
201
|
-
sendResult: (input, result) => this.sendSessionCommandResult(input, result),
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
// ==================== Lifecycle ====================
|
|
205
|
-
async refreshBindings() {
|
|
206
|
-
const config = await this.options.readConfig();
|
|
207
|
-
const bindings = this.collectBindings(config);
|
|
208
|
-
const nextKeys = new Set(bindings.map((b) => (0, config_js_1.runtimeKey)(b.workspaceId, b.instanceId)));
|
|
209
|
-
for (const key of [...this.runtime.keys()]) {
|
|
210
|
-
if (!nextKeys.has(key)) {
|
|
211
|
-
await this.stopWorkspaceKey(key);
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
for (const binding of bindings) {
|
|
215
|
-
const key = (0, config_js_1.runtimeKey)(binding.workspaceId, binding.instanceId);
|
|
216
|
-
const current = this.runtime.get(key);
|
|
217
|
-
if (!binding.enabled) {
|
|
218
|
-
if (current) {
|
|
219
|
-
await this.stopWorkspaceKey(key);
|
|
220
|
-
}
|
|
221
|
-
else {
|
|
222
|
-
this.runtime.set(key, {
|
|
223
|
-
workspaceId: binding.workspaceId,
|
|
224
|
-
instanceId: binding.instanceId,
|
|
225
|
-
displayName: binding.displayName,
|
|
226
|
-
platformKey: binding.platformKey,
|
|
227
|
-
enabled: false,
|
|
228
|
-
status: 'disabled',
|
|
229
|
-
connected: false,
|
|
230
|
-
accountId: binding.accountId,
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
continue;
|
|
234
|
-
}
|
|
235
|
-
if (current?.status === 'running' && current.accountId === binding.accountId) {
|
|
236
|
-
continue;
|
|
237
|
-
}
|
|
238
|
-
await this.startWorkspace(binding);
|
|
239
|
-
}
|
|
240
|
-
this.notifyRuntimeStateChanged();
|
|
241
|
-
}
|
|
242
|
-
async testConnection(workspaceId, instanceId) {
|
|
243
|
-
const binding = await this.getBinding(workspaceId, instanceId);
|
|
244
|
-
try {
|
|
245
|
-
const bufPath = (0, config_js_1.getWeixinBufPath)(binding);
|
|
246
|
-
node_fs_1.default.accessSync(bufPath);
|
|
247
|
-
return { success: true, platform: 'weixin', workspaceId, instanceId: binding.instanceId, appId: binding.accountId };
|
|
248
|
-
}
|
|
249
|
-
catch {
|
|
250
|
-
return { success: false, platform: 'weixin', workspaceId, instanceId: binding.instanceId, error: 'No sync buf found for account. Ensure the plugin has been connected at least once.' };
|
|
251
|
-
}
|
|
153
|
+
super(options);
|
|
252
154
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
155
|
+
// ==================== Abstract implementations ====================
|
|
156
|
+
makeThreadRoute(input, threadId) {
|
|
157
|
+
return {
|
|
158
|
+
workspaceId: input.workspaceId,
|
|
159
|
+
instanceId: input.instanceId,
|
|
160
|
+
platformKey: input.platformKey,
|
|
161
|
+
platformUserId: input.platformUserId,
|
|
162
|
+
chatId: input.chatId,
|
|
163
|
+
threadId,
|
|
164
|
+
};
|
|
257
165
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
return this.getStatus(workspaceId, instanceId);
|
|
166
|
+
collectBindings(config) {
|
|
167
|
+
return (0, config_js_1.collectWeixinWorkspaceBindings)(config);
|
|
261
168
|
}
|
|
262
|
-
|
|
169
|
+
buildStatusObject(state, resolved) {
|
|
263
170
|
this.options.store.expirePendingPairings();
|
|
264
|
-
const
|
|
265
|
-
const
|
|
266
|
-
const platformKey = binding?.platformKey || (0, config_js_1.channelPlatformKey)('weixin', resolved.instanceId);
|
|
267
|
-
const pairings = this.options.store.listPendingPairings(workspaceId)
|
|
171
|
+
const platformKey = state.platformKey || (0, config_js_1.channelPlatformKey)('weixin', resolved.instanceId);
|
|
172
|
+
const pairings = this.options.store.listPendingPairings(state.workspaceId)
|
|
268
173
|
.filter((row) => row.platform === platformKey && row.expires_at >= new Date().toISOString());
|
|
269
|
-
const users = this.options.store.listAuthorizedUsers(workspaceId, platformKey);
|
|
174
|
+
const users = this.options.store.listAuthorizedUsers(state.workspaceId, platformKey);
|
|
270
175
|
return {
|
|
271
|
-
workspaceId,
|
|
176
|
+
workspaceId: state.workspaceId,
|
|
272
177
|
platform: 'weixin',
|
|
273
178
|
instanceId: resolved.instanceId,
|
|
274
|
-
displayName:
|
|
275
|
-
enabled: Boolean(
|
|
276
|
-
connected: Boolean(
|
|
277
|
-
status:
|
|
278
|
-
appId:
|
|
279
|
-
lastError:
|
|
280
|
-
lastErrorInfo:
|
|
281
|
-
lastErrorAt:
|
|
282
|
-
consecutiveFailures:
|
|
283
|
-
nextRetryAt:
|
|
284
|
-
connectedAt:
|
|
179
|
+
displayName: state.displayName,
|
|
180
|
+
enabled: Boolean(state.enabled),
|
|
181
|
+
connected: Boolean(state.connected),
|
|
182
|
+
status: state.status || 'disabled',
|
|
183
|
+
appId: state.accountId || '',
|
|
184
|
+
lastError: state.lastError,
|
|
185
|
+
lastErrorInfo: state.lastErrorInfo,
|
|
186
|
+
lastErrorAt: state.lastErrorAt,
|
|
187
|
+
consecutiveFailures: state.consecutiveFailures,
|
|
188
|
+
nextRetryAt: state.nextRetryAt,
|
|
189
|
+
connectedAt: state.connectedAt,
|
|
285
190
|
pendingPairings: pairings.length,
|
|
286
191
|
authorizedUsers: users.length,
|
|
287
192
|
};
|
|
288
193
|
}
|
|
289
|
-
|
|
290
|
-
return
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
194
|
+
createDisabledState(binding) {
|
|
195
|
+
return {
|
|
196
|
+
workspaceId: binding.workspaceId,
|
|
197
|
+
instanceId: binding.instanceId,
|
|
198
|
+
displayName: binding.displayName,
|
|
199
|
+
platformKey: binding.platformKey,
|
|
200
|
+
enabled: false,
|
|
201
|
+
status: 'disabled',
|
|
202
|
+
connected: false,
|
|
203
|
+
accountId: binding.accountId,
|
|
204
|
+
};
|
|
300
205
|
}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
.
|
|
206
|
+
async stopWorkspaceTransport(state) {
|
|
207
|
+
try {
|
|
208
|
+
state.abortController?.abort();
|
|
209
|
+
}
|
|
210
|
+
catch { }
|
|
304
211
|
}
|
|
305
|
-
|
|
306
|
-
|
|
212
|
+
resetStateToStopped(state, _key) {
|
|
213
|
+
Object.assign(state, {
|
|
214
|
+
enabled: false,
|
|
215
|
+
status: 'stopped',
|
|
216
|
+
connected: false,
|
|
217
|
+
});
|
|
307
218
|
}
|
|
308
|
-
async
|
|
309
|
-
this.
|
|
219
|
+
async sendSessionCommandResult(input, result) {
|
|
220
|
+
const state = this.resolveRuntimeState(input.workspaceId, input.instanceId).state;
|
|
221
|
+
if (!state?.connected)
|
|
222
|
+
return;
|
|
223
|
+
try {
|
|
224
|
+
await this.sendTextMessage(state, input.chatId, result.displayText);
|
|
225
|
+
}
|
|
226
|
+
catch (error) {
|
|
227
|
+
this.options.log?.(`localcore-weixin session command result failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
228
|
+
}
|
|
310
229
|
}
|
|
311
|
-
|
|
312
|
-
|
|
230
|
+
// ==================== Lifecycle (platform-specific) ====================
|
|
231
|
+
async testConnection(workspaceId, instanceId) {
|
|
232
|
+
const binding = await this.getBinding(workspaceId, instanceId);
|
|
233
|
+
try {
|
|
234
|
+
const bufPath = (0, config_js_1.getWeixinBufPath)(binding);
|
|
235
|
+
node_fs_1.default.accessSync(bufPath);
|
|
236
|
+
return { success: true, platform: 'weixin', workspaceId, instanceId: binding.instanceId, appId: binding.accountId };
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
return { success: false, platform: 'weixin', workspaceId, instanceId: binding.instanceId, error: 'No sync buf found for account. Ensure the plugin has been connected at least once.' };
|
|
240
|
+
}
|
|
313
241
|
}
|
|
314
242
|
// ==================== QR Code Login ====================
|
|
315
243
|
async getQrCode(workspaceId, instanceId) {
|
|
@@ -354,62 +282,7 @@ class LocalCoreWeixinGateway extends node_events_1.EventEmitter {
|
|
|
354
282
|
};
|
|
355
283
|
}
|
|
356
284
|
// ==================== Pairing ====================
|
|
357
|
-
approvePairing(code) {
|
|
358
|
-
this.options.store.expirePendingPairings();
|
|
359
|
-
const pairing = this.options.store.getPairingRequest(code);
|
|
360
|
-
if (!pairing)
|
|
361
|
-
throw new Error(`Pairing code not found: ${code}`);
|
|
362
|
-
if (pairing.platform !== 'weixin' && !pairing.platform.startsWith('weixin:'))
|
|
363
|
-
throw new Error(`Pairing code ${code} is not a WeChat pairing`);
|
|
364
|
-
if (pairing.status !== 'pending')
|
|
365
|
-
throw new Error(`Pairing code ${code} is already ${pairing.status}`);
|
|
366
|
-
if (pairing.expires_at < new Date().toISOString()) {
|
|
367
|
-
this.options.store.updatePairingStatus(code, 'expired');
|
|
368
|
-
throw new Error(`Pairing code ${code} has expired`);
|
|
369
|
-
}
|
|
370
|
-
const existing = this.options.store.getAuthorizedUser(pairing.workspace_id, pairing.platform_user_id, pairing.platform);
|
|
371
|
-
const userId = existing?.id || `wx-user-${(0, node_crypto_2.randomUUID)()}`;
|
|
372
|
-
const authorizedAt = new Date().toISOString();
|
|
373
|
-
this.options.store.createAuthorizedUser({
|
|
374
|
-
id: userId,
|
|
375
|
-
workspace_id: pairing.workspace_id,
|
|
376
|
-
platform: pairing.platform,
|
|
377
|
-
platform_user_id: pairing.platform_user_id,
|
|
378
|
-
chat_id: pairing.chat_id,
|
|
379
|
-
display_name: pairing.display_name,
|
|
380
|
-
thread_id: existing?.thread_id || null,
|
|
381
|
-
authorized_at: authorizedAt,
|
|
382
|
-
});
|
|
383
|
-
this.options.store.updatePairingStatus(code, 'approved');
|
|
384
|
-
this.notifyRuntimeStateChanged();
|
|
385
|
-
const user = this.options.store.listAuthorizedUsers(pairing.workspace_id, pairing.platform).find((e) => e.id === userId);
|
|
386
|
-
if (!user)
|
|
387
|
-
throw new Error('Authorized user lookup failed after approval');
|
|
388
|
-
return user;
|
|
389
|
-
}
|
|
390
|
-
rejectPairing(code) {
|
|
391
|
-
const pairing = this.options.store.getPairingRequest(code);
|
|
392
|
-
if (!pairing)
|
|
393
|
-
throw new Error(`Pairing code not found: ${code}`);
|
|
394
|
-
if (pairing.platform !== 'weixin' && !pairing.platform.startsWith('weixin:'))
|
|
395
|
-
throw new Error(`Pairing code ${code} is not a WeChat pairing`);
|
|
396
|
-
this.options.store.updatePairingStatus(code, 'rejected');
|
|
397
|
-
this.notifyRuntimeStateChanged();
|
|
398
|
-
return { rejected: true };
|
|
399
|
-
}
|
|
400
285
|
// ==================== Bridge Event Handling ====================
|
|
401
|
-
muteThreadBridge(threadId) {
|
|
402
|
-
const current = this.mutedThreadBridgeCounts.get(threadId) || 0;
|
|
403
|
-
this.mutedThreadBridgeCounts.set(threadId, current + 1);
|
|
404
|
-
}
|
|
405
|
-
unmuteThreadBridge(threadId) {
|
|
406
|
-
const current = this.mutedThreadBridgeCounts.get(threadId) || 0;
|
|
407
|
-
if (current <= 1) {
|
|
408
|
-
this.mutedThreadBridgeCounts.delete(threadId);
|
|
409
|
-
return;
|
|
410
|
-
}
|
|
411
|
-
this.mutedThreadBridgeCounts.set(threadId, current - 1);
|
|
412
|
-
}
|
|
413
286
|
async onBridgeEvent(event) {
|
|
414
287
|
if (!event.sessionKey) {
|
|
415
288
|
this.options.log?.(`localcore-weixin bridge event ignored without sessionKey: ${event.type}`);
|
|
@@ -497,25 +370,6 @@ class LocalCoreWeixinGateway extends node_events_1.EventEmitter {
|
|
|
497
370
|
this.outboundEventChains.set(sessionKey, current);
|
|
498
371
|
await current;
|
|
499
372
|
}
|
|
500
|
-
async sendScheduledCard(workspaceId, chatId, text) {
|
|
501
|
-
return this.sendScheduledMessage(workspaceId, { type: 'channel.chat', channelId: chatId }, text);
|
|
502
|
-
}
|
|
503
|
-
async sendScheduledMessage(workspaceId, route, text) {
|
|
504
|
-
const state = this.resolveRuntimeState(workspaceId, route.instanceId).state;
|
|
505
|
-
if (!state?.connected) {
|
|
506
|
-
this.options.log?.(`localcore-weixin scheduled message skipped: workspace not connected: ${workspaceId}`);
|
|
507
|
-
return '';
|
|
508
|
-
}
|
|
509
|
-
try {
|
|
510
|
-
const stripped = stripHtml(text);
|
|
511
|
-
await this.sendTextMessage(state, route.channelId, stripped);
|
|
512
|
-
return `wx_sched_${(0, node_crypto_2.randomUUID)()}`;
|
|
513
|
-
}
|
|
514
|
-
catch (error) {
|
|
515
|
-
this.options.log?.(`localcore-weixin scheduled message failed for ${workspaceId}: ${formatError(error)}`);
|
|
516
|
-
return '';
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
373
|
registerScheduledThreadBridge(input) {
|
|
520
374
|
const instanceId = input.route.instanceId || getWeixinInstanceId(input.platform) || 'default';
|
|
521
375
|
const platformKey = (0, config_js_1.channelPlatformKey)('weixin', instanceId);
|
|
@@ -614,136 +468,126 @@ class LocalCoreWeixinGateway extends node_events_1.EventEmitter {
|
|
|
614
468
|
}
|
|
615
469
|
// ==================== Inbound Message Handling ====================
|
|
616
470
|
async handleInboundMessage(input) {
|
|
617
|
-
const
|
|
618
|
-
const
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
471
|
+
const msg = input;
|
|
472
|
+
const instanceId = msg.instanceId || 'default';
|
|
473
|
+
const platformKey = msg.platformKey || (0, config_js_1.channelPlatformKey)('weixin', instanceId);
|
|
474
|
+
if (this.isDuplicateInboundMessage(msg)) {
|
|
475
|
+
this.options.log?.(`localcore-weixin skipped duplicate inbound message workspace=${msg.workspaceId} chat=${msg.chatId} id=${msg.contextToken || msg.messageId}`);
|
|
476
|
+
return;
|
|
622
477
|
}
|
|
623
478
|
this.options.eventBus.emit({
|
|
624
479
|
type: 'platform.message.received',
|
|
625
480
|
payload: {
|
|
626
481
|
platform: this.platform,
|
|
627
|
-
workspaceId:
|
|
628
|
-
participantId:
|
|
629
|
-
channelId:
|
|
630
|
-
displayName:
|
|
631
|
-
text:
|
|
632
|
-
messageId:
|
|
482
|
+
workspaceId: msg.workspaceId,
|
|
483
|
+
participantId: msg.platformUserId,
|
|
484
|
+
channelId: msg.chatId,
|
|
485
|
+
displayName: msg.displayName,
|
|
486
|
+
text: msg.text,
|
|
487
|
+
messageId: msg.messageId,
|
|
633
488
|
},
|
|
634
489
|
});
|
|
635
490
|
this.options.store.expirePendingPairings();
|
|
636
|
-
const binding = await this.getBinding(
|
|
637
|
-
let authorized = this.options.store.getAuthorizedUser(
|
|
491
|
+
const binding = await this.getBinding(msg.workspaceId, instanceId);
|
|
492
|
+
let authorized = this.options.store.getAuthorizedUser(msg.workspaceId, msg.platformUserId, platformKey);
|
|
638
493
|
if (!authorized) {
|
|
639
494
|
if (binding.allowFrom === '*') {
|
|
640
495
|
const authorizedAt = new Date().toISOString();
|
|
641
496
|
this.options.store.createAuthorizedUser({
|
|
642
497
|
id: `wx-user-${(0, node_crypto_2.randomUUID)()}`,
|
|
643
|
-
workspace_id:
|
|
498
|
+
workspace_id: msg.workspaceId,
|
|
644
499
|
platform: platformKey,
|
|
645
|
-
platform_user_id:
|
|
646
|
-
chat_id:
|
|
647
|
-
display_name:
|
|
500
|
+
platform_user_id: msg.platformUserId,
|
|
501
|
+
chat_id: msg.chatId,
|
|
502
|
+
display_name: msg.displayName,
|
|
648
503
|
thread_id: null,
|
|
649
504
|
authorized_at: authorizedAt,
|
|
650
505
|
});
|
|
651
|
-
authorized = this.options.store.getAuthorizedUser(
|
|
652
|
-
this.options.log?.(`localcore-weixin auto-approved user for ${
|
|
506
|
+
authorized = this.options.store.getAuthorizedUser(msg.workspaceId, msg.platformUserId, platformKey);
|
|
507
|
+
this.options.log?.(`localcore-weixin auto-approved user for ${msg.workspaceId}: ${msg.platformUserId}`);
|
|
653
508
|
this.notifyRuntimeStateChanged();
|
|
654
509
|
}
|
|
655
510
|
}
|
|
656
511
|
if (!authorized) {
|
|
657
|
-
const existingPending = this.options.store.listPendingPairings(
|
|
512
|
+
const existingPending = this.options.store.listPendingPairings(msg.workspaceId).find((item) => item.platform === platformKey && item.platform_user_id === msg.platformUserId && item.chat_id === msg.chatId && item.status === 'pending');
|
|
658
513
|
let pairingCode = existingPending?.code || '';
|
|
659
514
|
if (!existingPending) {
|
|
660
515
|
const now = new Date();
|
|
661
516
|
pairingCode = String((0, node_crypto_2.randomInt)(100000, 1000000));
|
|
662
517
|
this.options.store.createPairingRequest({
|
|
663
518
|
code: pairingCode,
|
|
664
|
-
workspace_id:
|
|
519
|
+
workspace_id: msg.workspaceId,
|
|
665
520
|
platform: platformKey,
|
|
666
|
-
platform_user_id:
|
|
667
|
-
chat_id:
|
|
668
|
-
display_name:
|
|
521
|
+
platform_user_id: msg.platformUserId,
|
|
522
|
+
chat_id: msg.chatId,
|
|
523
|
+
display_name: msg.displayName,
|
|
669
524
|
requested_at: now.toISOString(),
|
|
670
525
|
expires_at: new Date(now.getTime() + PAIRING_EXPIRY_MS).toISOString(),
|
|
671
526
|
status: 'pending',
|
|
672
527
|
});
|
|
673
528
|
this.notifyRuntimeStateChanged();
|
|
674
529
|
}
|
|
675
|
-
const state = this.runtime.get((0, config_js_1.runtimeKey)(
|
|
530
|
+
const state = this.runtime.get((0, config_js_1.runtimeKey)(msg.workspaceId, instanceId));
|
|
676
531
|
if (state?.connected) {
|
|
677
|
-
await this.sendTextMessage(state,
|
|
532
|
+
await this.sendTextMessage(state, msg.chatId, `**已收到消息**\n\n当前账号还未授权接入这个工作区。\n请在桌面端完成审批后再次发送消息。\n\n配对码:\`${pairingCode}\``, msg.contextToken);
|
|
678
533
|
}
|
|
679
|
-
return
|
|
534
|
+
return;
|
|
680
535
|
}
|
|
681
536
|
const router = this.options.getWorkspaceRouter();
|
|
682
537
|
let { threadId } = await (0, thread_routing_js_1.resolveChannelThreadRoute)({
|
|
683
538
|
store: this.options.store,
|
|
684
539
|
router,
|
|
685
|
-
workspaceId:
|
|
540
|
+
workspaceId: msg.workspaceId,
|
|
686
541
|
platformKey,
|
|
687
|
-
chatId:
|
|
688
|
-
platformUserId:
|
|
689
|
-
displayName:
|
|
542
|
+
chatId: msg.chatId,
|
|
543
|
+
platformUserId: msg.platformUserId,
|
|
544
|
+
displayName: msg.displayName,
|
|
690
545
|
fallbackTitlePrefix: 'WeChat',
|
|
691
546
|
authorized,
|
|
692
547
|
});
|
|
693
|
-
const normalizedText = String(
|
|
694
|
-
const permissionThreadId = (normalizedText === 'allow' || normalizedText === 'allow all' || normalizedText === 'deny') ? this.findAwaitingPermissionThreadId(
|
|
548
|
+
const normalizedText = String(msg.text || '').trim().toLowerCase();
|
|
549
|
+
const permissionThreadId = (normalizedText === 'allow' || normalizedText === 'allow all' || normalizedText === 'deny') ? this.findAwaitingPermissionThreadId(msg.workspaceId, msg.chatId, msg.platformUserId, msg.platformKey) : '';
|
|
695
550
|
if (permissionThreadId && permissionThreadId !== threadId) {
|
|
696
551
|
threadId = permissionThreadId;
|
|
697
552
|
}
|
|
698
553
|
const effectiveSessionKey = router.getThreadSessionKey(threadId);
|
|
699
554
|
this.threadRouting.set(effectiveSessionKey, {
|
|
700
|
-
workspaceId:
|
|
555
|
+
workspaceId: msg.workspaceId,
|
|
701
556
|
instanceId,
|
|
702
557
|
platformKey,
|
|
703
|
-
platformUserId:
|
|
704
|
-
chatId:
|
|
558
|
+
platformUserId: msg.platformUserId,
|
|
559
|
+
chatId: msg.chatId,
|
|
705
560
|
threadId,
|
|
706
561
|
});
|
|
707
562
|
// Handle slash commands
|
|
708
|
-
const slashCommand = this.parseSlashCommand(
|
|
563
|
+
const slashCommand = this.parseSlashCommand(msg.text);
|
|
709
564
|
const sessionCommand = await this.executeSessionCommand({
|
|
710
|
-
workspaceId:
|
|
565
|
+
workspaceId: msg.workspaceId,
|
|
711
566
|
currentThreadId: threadId,
|
|
712
|
-
text:
|
|
713
|
-
defaultTitle: `${
|
|
714
|
-
defaultAgentType: slashCommand ? await this.resolveDefaultAgentType(
|
|
715
|
-
chatId:
|
|
716
|
-
platformUserId:
|
|
567
|
+
text: msg.text,
|
|
568
|
+
defaultTitle: `${msg.displayName || 'WeChat'} ${new Date().toLocaleTimeString()}`,
|
|
569
|
+
defaultAgentType: slashCommand ? await this.resolveDefaultAgentType(msg.workspaceId, threadId) : '',
|
|
570
|
+
chatId: msg.chatId,
|
|
571
|
+
platformUserId: msg.platformUserId,
|
|
717
572
|
platformKey,
|
|
718
573
|
instanceId,
|
|
719
|
-
contextToken:
|
|
574
|
+
contextToken: msg.contextToken,
|
|
720
575
|
});
|
|
721
576
|
if (sessionCommand.handled) {
|
|
722
|
-
return
|
|
577
|
+
return;
|
|
723
578
|
}
|
|
724
579
|
const latestRun = this.options.store.getLatestRunForThread(threadId);
|
|
725
580
|
if ((normalizedText === 'allow' || normalizedText === 'allow all' || normalizedText === 'deny')
|
|
726
581
|
&& latestRun?.status === 'awaiting_input') {
|
|
727
|
-
await router.sendThreadAction(threadId,
|
|
728
|
-
return { paired: true, threadId };
|
|
729
|
-
}
|
|
730
|
-
this.options.store.updatePlatformThreadMessageId(input.workspaceId, input.chatId, input.platformUserId, input.contextToken || input.messageId, platformKey);
|
|
731
|
-
const wrappedText = slashCommand
|
|
732
|
-
? input.text
|
|
733
|
-
: (0, desktop_js_1.wrapUserMessageWithSchedulerProtocol)(input.text);
|
|
734
|
-
await router.sendThreadMessage(threadId, (0, content_js_1.createChannelThreadMessageInput)(wrappedText, input.contentParts));
|
|
735
|
-
return { paired: true, threadId };
|
|
736
|
-
}
|
|
737
|
-
async executeSessionCommand(input) {
|
|
738
|
-
return this.sessionCommandRuntime.execute(input);
|
|
739
|
-
}
|
|
740
|
-
async sendSessionCommandResult(input, result) {
|
|
741
|
-
const state = this.resolveRuntimeState(input.workspaceId, input.instanceId).state;
|
|
742
|
-
if (!state?.connected) {
|
|
743
|
-
this.options.log?.(`localcore-weixin session command response skipped: workspace not connected: ${input.workspaceId}`);
|
|
582
|
+
await router.sendThreadAction(threadId, msg.text);
|
|
744
583
|
return;
|
|
745
584
|
}
|
|
746
|
-
|
|
585
|
+
this.options.store.updatePlatformThreadMessageId(msg.workspaceId, msg.chatId, msg.platformUserId, msg.contextToken || msg.messageId, platformKey);
|
|
586
|
+
const wrappedText = slashCommand
|
|
587
|
+
? msg.text
|
|
588
|
+
: (0, desktop_js_1.wrapUserMessageWithSchedulerProtocol)(msg.text);
|
|
589
|
+
await router.sendThreadMessage(threadId, (0, content_js_1.createChannelThreadMessageInput)(wrappedText, msg.contentParts));
|
|
590
|
+
return;
|
|
747
591
|
}
|
|
748
592
|
async resolveDefaultAgentType(workspaceId, threadId) {
|
|
749
593
|
const router = this.options.getWorkspaceRouter();
|
|
@@ -753,28 +597,6 @@ class LocalCoreWeixinGateway extends node_events_1.EventEmitter {
|
|
|
753
597
|
return this.options.store.getThreadRow(threadId)?.agent_type || 'codex';
|
|
754
598
|
}
|
|
755
599
|
// ==================== Private: Bindings ====================
|
|
756
|
-
resolveRuntimeState(workspaceId, instanceId) {
|
|
757
|
-
if (instanceId) {
|
|
758
|
-
const state = this.runtime.get((0, config_js_1.runtimeKey)(workspaceId, instanceId)) || (instanceId === 'default' ? this.runtime.get(workspaceId) : undefined);
|
|
759
|
-
return { instanceId, state };
|
|
760
|
-
}
|
|
761
|
-
const states = [...this.runtime.values()].filter((entry) => entry.workspaceId === workspaceId);
|
|
762
|
-
const state = states.find((entry) => entry.instanceId === 'default') || states[0];
|
|
763
|
-
return { instanceId: state?.instanceId || 'default', state: state || this.runtime.get(workspaceId) };
|
|
764
|
-
}
|
|
765
|
-
async getBinding(workspaceId, instanceId) {
|
|
766
|
-
const config = await this.options.readConfig();
|
|
767
|
-
const bindings = this.collectBindings(config).filter((e) => e.workspaceId === workspaceId);
|
|
768
|
-
const binding = instanceId
|
|
769
|
-
? bindings.find((entry) => entry.instanceId === instanceId)
|
|
770
|
-
: bindings.find((entry) => entry.instanceId === 'default') || bindings[0];
|
|
771
|
-
if (!binding)
|
|
772
|
-
throw new Error(`No WeChat binding configured for workspace "${workspaceId}"${instanceId ? ` instance "${instanceId}"` : ''}`);
|
|
773
|
-
return binding;
|
|
774
|
-
}
|
|
775
|
-
collectBindings(config) {
|
|
776
|
-
return (0, config_js_1.collectWeixinWorkspaceBindings)(config);
|
|
777
|
-
}
|
|
778
600
|
// ==================== Private: Workspace Lifecycle ====================
|
|
779
601
|
async startWorkspace(binding) {
|
|
780
602
|
const key = (0, config_js_1.runtimeKey)(binding.workspaceId, binding.instanceId);
|
|
@@ -815,11 +637,7 @@ class LocalCoreWeixinGateway extends node_events_1.EventEmitter {
|
|
|
815
637
|
if (!abortController.signal.aborted) {
|
|
816
638
|
status.status = 'error';
|
|
817
639
|
status.connected = false;
|
|
818
|
-
this.setRuntimeError(status,
|
|
819
|
-
workspaceId: binding.workspaceId,
|
|
820
|
-
instanceId: binding.instanceId,
|
|
821
|
-
runtimeId: 'weixin',
|
|
822
|
-
});
|
|
640
|
+
this.setRuntimeError(status, (0, local_core_errors_js_1.toLocalCoreErrorInfo)(err));
|
|
823
641
|
this.notifyRuntimeStateChanged();
|
|
824
642
|
}
|
|
825
643
|
});
|
|
@@ -827,38 +645,10 @@ class LocalCoreWeixinGateway extends node_events_1.EventEmitter {
|
|
|
827
645
|
catch (error) {
|
|
828
646
|
status.status = 'error';
|
|
829
647
|
status.connected = false;
|
|
830
|
-
this.setRuntimeError(status,
|
|
831
|
-
workspaceId: binding.workspaceId,
|
|
832
|
-
instanceId: binding.instanceId,
|
|
833
|
-
runtimeId: 'weixin',
|
|
834
|
-
});
|
|
648
|
+
this.setRuntimeError(status, (0, local_core_errors_js_1.toLocalCoreErrorInfo)(error));
|
|
835
649
|
}
|
|
836
650
|
this.notifyRuntimeStateChanged();
|
|
837
651
|
}
|
|
838
|
-
async stopWorkspace(workspaceId, instanceId) {
|
|
839
|
-
const resolved = this.resolveRuntimeState(workspaceId, instanceId);
|
|
840
|
-
await this.stopWorkspaceKey((0, config_js_1.runtimeKey)(workspaceId, resolved.instanceId));
|
|
841
|
-
}
|
|
842
|
-
async stopWorkspaceKey(key) {
|
|
843
|
-
const state = this.runtime.get(key);
|
|
844
|
-
if (!state)
|
|
845
|
-
return;
|
|
846
|
-
try {
|
|
847
|
-
state.abortController?.abort();
|
|
848
|
-
}
|
|
849
|
-
catch { }
|
|
850
|
-
this.runtime.set(key, {
|
|
851
|
-
workspaceId: state.workspaceId,
|
|
852
|
-
instanceId: state.instanceId,
|
|
853
|
-
displayName: state.displayName,
|
|
854
|
-
platformKey: state.platformKey,
|
|
855
|
-
enabled: false,
|
|
856
|
-
status: 'stopped',
|
|
857
|
-
connected: false,
|
|
858
|
-
accountId: state.accountId,
|
|
859
|
-
});
|
|
860
|
-
this.notifyRuntimeStateChanged();
|
|
861
|
-
}
|
|
862
652
|
// ==================== Private: Long-poll Monitor ====================
|
|
863
653
|
normalizeQrStatus(status) {
|
|
864
654
|
const normalized = String(status || 'wait').trim().toLowerCase();
|
|
@@ -887,17 +677,7 @@ class LocalCoreWeixinGateway extends node_events_1.EventEmitter {
|
|
|
887
677
|
state.connected = false;
|
|
888
678
|
state.consecutiveFailures = consecutiveFailures;
|
|
889
679
|
state.nextRetryAt = new Date(Date.now() + retryDelayMs).toISOString();
|
|
890
|
-
this.setRuntimeError(state, new local_core_errors_js_1.LocalCoreError('channel_session_expired', 'WeChat login expired.
|
|
891
|
-
suggestedAction: 'Generate and scan a new WeChat QR code.',
|
|
892
|
-
details: {
|
|
893
|
-
errcode: resp.errcode ?? resp.ret ?? -14,
|
|
894
|
-
},
|
|
895
|
-
}), 'channel_session_expired', {
|
|
896
|
-
workspaceId: binding.workspaceId,
|
|
897
|
-
instanceId: binding.instanceId,
|
|
898
|
-
runtimeId: 'weixin',
|
|
899
|
-
errcode: resp.errcode ?? resp.ret ?? -14,
|
|
900
|
-
});
|
|
680
|
+
this.setRuntimeError(state, (0, local_core_errors_js_1.toLocalCoreErrorInfo)(new local_core_errors_js_1.LocalCoreError('channel_session_expired', 'WeChat login expired.')));
|
|
901
681
|
this.notifyRuntimeStateChanged();
|
|
902
682
|
}
|
|
903
683
|
}
|
|
@@ -986,11 +766,7 @@ class LocalCoreWeixinGateway extends node_events_1.EventEmitter {
|
|
|
986
766
|
if (state) {
|
|
987
767
|
state.consecutiveFailures = consecutiveFailures;
|
|
988
768
|
state.nextRetryAt = new Date(Date.now() + retryDelayMs).toISOString();
|
|
989
|
-
this.setRuntimeError(state,
|
|
990
|
-
workspaceId: binding.workspaceId,
|
|
991
|
-
instanceId: binding.instanceId,
|
|
992
|
-
runtimeId: 'weixin',
|
|
993
|
-
});
|
|
769
|
+
this.setRuntimeError(state, (0, local_core_errors_js_1.toLocalCoreErrorInfo)(err));
|
|
994
770
|
this.notifyRuntimeStateChanged();
|
|
995
771
|
}
|
|
996
772
|
this.logPollError(binding, formatError(err), `localcore-weixin getUpdates error for ${binding.workspaceId} (${consecutiveFailures}): ${formatError(err)}`);
|
|
@@ -1327,33 +1103,6 @@ class LocalCoreWeixinGateway extends node_events_1.EventEmitter {
|
|
|
1327
1103
|
return null;
|
|
1328
1104
|
return { name: name.trim().toLowerCase(), args };
|
|
1329
1105
|
}
|
|
1330
|
-
notifyRuntimeStateChanged() {
|
|
1331
|
-
this.options.eventBus.emit({
|
|
1332
|
-
type: 'runtime.state.changed',
|
|
1333
|
-
payload: { reason: 'channel-bindings' },
|
|
1334
|
-
});
|
|
1335
|
-
}
|
|
1336
|
-
clearRuntimeError(state) {
|
|
1337
|
-
state.lastError = undefined;
|
|
1338
|
-
state.lastErrorInfo = undefined;
|
|
1339
|
-
state.lastErrorAt = undefined;
|
|
1340
|
-
state.consecutiveFailures = 0;
|
|
1341
|
-
state.nextRetryAt = undefined;
|
|
1342
|
-
}
|
|
1343
|
-
setRuntimeError(state, error, fallbackCode, context) {
|
|
1344
|
-
const errorInfo = (0, local_core_errors_js_1.toLocalCoreErrorInfo)(error, fallbackCode, context);
|
|
1345
|
-
state.lastError = errorInfo.message;
|
|
1346
|
-
state.lastErrorInfo = errorInfo;
|
|
1347
|
-
state.lastErrorAt = new Date().toISOString();
|
|
1348
|
-
this.options.eventBus.emit({
|
|
1349
|
-
type: 'localcore.error',
|
|
1350
|
-
payload: {
|
|
1351
|
-
scope: 'channel.weixin',
|
|
1352
|
-
errorInfo,
|
|
1353
|
-
context,
|
|
1354
|
-
},
|
|
1355
|
-
});
|
|
1356
|
-
}
|
|
1357
1106
|
computeRetryDelay(failures) {
|
|
1358
1107
|
if (failures <= 1)
|
|
1359
1108
|
return RETRY_DELAY_MS;
|