neoagent 2.4.1-beta.31 → 2.4.1-beta.33
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/package.json +1 -1
- package/server/public/.last_build_id +1 -1
- package/server/public/flutter_bootstrap.js +1 -1
- package/server/public/main.dart.js +4 -4
- package/server/services/ai/tools.js +51 -7
- package/server/services/messaging/formatting_guides.js +26 -1
- package/server/services/messaging/manager.js +5 -2
- package/server/services/tasks/runtime.js +178 -7
- package/server/services/tasks/task_repository.js +13 -0
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
49442e542f5b85df16e4fff2751cb6a3
|
|
@@ -37,6 +37,6 @@ _flutter.buildConfig = {"engineRevision":"c416acfeb8126e097f758c664aaa3da929e27d
|
|
|
37
37
|
|
|
38
38
|
_flutter.loader.load({
|
|
39
39
|
serviceWorkerSettings: {
|
|
40
|
-
serviceWorkerVersion: "
|
|
40
|
+
serviceWorkerVersion: "2270904145" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
|
|
41
41
|
}
|
|
42
42
|
});
|
|
@@ -133653,7 +133653,7 @@ r===$&&A.b()
|
|
|
133653
133653
|
o.push(A.jM(p,A.j9(!1,new A.a2(B.un,A.ds(new A.cB(B.ho,new A.a7n(r,p),p),p,p),p),!1,B.H,!0),p,p,0,0,0,p))}r=!1
|
|
133654
133654
|
if(!s.ay)if(!s.ch){r=s.e
|
|
133655
133655
|
r===$&&A.b()
|
|
133656
|
-
r=B.b.t("
|
|
133656
|
+
r=B.b.t("mpzv8963-3cb08c9").length!==0&&r.b}if(r){r=s.d
|
|
133657
133657
|
r===$&&A.b()
|
|
133658
133658
|
r=r.av&&!r.aP?84:0
|
|
133659
133659
|
q=s.e
|
|
@@ -139137,7 +139137,7 @@ $S:0}
|
|
|
139137
139137
|
A.ZM.prototype={}
|
|
139138
139138
|
A.Su.prototype={
|
|
139139
139139
|
nc(a){var s=this
|
|
139140
|
-
if(B.b.t("
|
|
139140
|
+
if(B.b.t("mpzv8963-3cb08c9").length===0||s.a!=null)return
|
|
139141
139141
|
s.AM()
|
|
139142
139142
|
s.a=A.qe(B.R2,new A.b9L(s))},
|
|
139143
139143
|
AM(){var s=0,r=A.l(t.H),q,p=2,o=[],n=this,m,l,k,j,i,h,g,f
|
|
@@ -139155,7 +139155,7 @@ if(!t.f.b(k)){s=1
|
|
|
139155
139155
|
break}i=J.T(k,"buildId")
|
|
139156
139156
|
h=i==null?null:B.b.t(J.p(i))
|
|
139157
139157
|
j=h==null?"":h
|
|
139158
|
-
if(J.bf(j)===0||J.d(j,"
|
|
139158
|
+
if(J.bf(j)===0||J.d(j,"mpzv8963-3cb08c9")){s=1
|
|
139159
139159
|
break}n.b=!0
|
|
139160
139160
|
n.D()
|
|
139161
139161
|
p=2
|
|
@@ -139172,7 +139172,7 @@ case 2:return A.i(o.at(-1),r)}})
|
|
|
139172
139172
|
return A.k($async$AM,r)},
|
|
139173
139173
|
vu(){var s=0,r=A.l(t.H),q,p=2,o=[],n=this,m,l,k,j,i,h,g,f,e,d,c,b,a,a0,a1
|
|
139174
139174
|
var $async$vu=A.h(function(a2,a3){if(a2===1){o.push(a3)
|
|
139175
|
-
s=p}for(;;)switch(s){case 0:if(B.b.t("
|
|
139175
|
+
s=p}for(;;)switch(s){case 0:if(B.b.t("mpzv8963-3cb08c9").length===0||n.c){s=1
|
|
139176
139176
|
break}n.c=!0
|
|
139177
139177
|
n.D()
|
|
139178
139178
|
p=4
|
|
@@ -274,6 +274,33 @@ function markProactiveMessageSent({ runState, deliveryState, content }) {
|
|
|
274
274
|
}
|
|
275
275
|
}
|
|
276
276
|
|
|
277
|
+
function normalizeStoredSettingString(value) {
|
|
278
|
+
if (value == null) return '';
|
|
279
|
+
if (typeof value !== 'string') return String(value || '').trim();
|
|
280
|
+
let current = value.trim();
|
|
281
|
+
for (let i = 0; i < 2; i += 1) {
|
|
282
|
+
if (!current) return '';
|
|
283
|
+
try {
|
|
284
|
+
const parsed = JSON.parse(current);
|
|
285
|
+
if (typeof parsed === 'string') {
|
|
286
|
+
current = parsed.trim();
|
|
287
|
+
continue;
|
|
288
|
+
}
|
|
289
|
+
return '';
|
|
290
|
+
} catch {
|
|
291
|
+
return current;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
return current;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
function normalizeMessagingTarget(target = {}) {
|
|
298
|
+
const platform = normalizeStoredSettingString(target.platform);
|
|
299
|
+
const to = normalizeStoredSettingString(target.to);
|
|
300
|
+
if (!platform || !to) return null;
|
|
301
|
+
return { platform, to };
|
|
302
|
+
}
|
|
303
|
+
|
|
277
304
|
function buildAndroidUiMatchProperties(extra = {}) {
|
|
278
305
|
return {
|
|
279
306
|
x: { type: 'number', description: 'Absolute X coordinate' },
|
|
@@ -2323,8 +2350,8 @@ async function executeTool(toolName, args, context, engine) {
|
|
|
2323
2350
|
|| null
|
|
2324
2351
|
);
|
|
2325
2352
|
const loadDefaultTarget = () => ({
|
|
2326
|
-
platform: loadAgentSetting('last_platform'),
|
|
2327
|
-
to: loadAgentSetting('last_chat_id')
|
|
2353
|
+
platform: normalizeStoredSettingString(loadAgentSetting('last_platform')),
|
|
2354
|
+
to: normalizeStoredSettingString(loadAgentSetting('last_chat_id'))
|
|
2328
2355
|
});
|
|
2329
2356
|
|
|
2330
2357
|
let taskConfig = null;
|
|
@@ -2336,26 +2363,43 @@ async function executeTool(toolName, args, context, engine) {
|
|
|
2336
2363
|
try {
|
|
2337
2364
|
taskConfig = JSON.parse(task.task_config || '{}');
|
|
2338
2365
|
taskTarget = {
|
|
2339
|
-
platform: taskConfig.notifyPlatform
|
|
2340
|
-
to: taskConfig.notifyTo
|
|
2366
|
+
platform: normalizeStoredSettingString(taskConfig.notifyPlatform),
|
|
2367
|
+
to: normalizeStoredSettingString(taskConfig.notifyTo)
|
|
2341
2368
|
};
|
|
2342
2369
|
} catch { }
|
|
2343
2370
|
}
|
|
2344
2371
|
}
|
|
2345
2372
|
|
|
2346
2373
|
const fallbackTarget = loadDefaultTarget();
|
|
2374
|
+
const recentTargets = db.prepare(
|
|
2375
|
+
`SELECT platform, platform_chat_id
|
|
2376
|
+
FROM messages
|
|
2377
|
+
WHERE user_id = ?
|
|
2378
|
+
AND agent_id = ?
|
|
2379
|
+
AND platform IS NOT NULL
|
|
2380
|
+
AND platform_chat_id IS NOT NULL
|
|
2381
|
+
ORDER BY id DESC
|
|
2382
|
+
LIMIT 20`
|
|
2383
|
+
).all(userId, agentId);
|
|
2347
2384
|
const candidateTargets = [];
|
|
2348
2385
|
const seenTargets = new Set();
|
|
2349
2386
|
const addCandidate = (target) => {
|
|
2350
|
-
|
|
2351
|
-
|
|
2387
|
+
const normalizedTarget = normalizeMessagingTarget(target);
|
|
2388
|
+
if (!normalizedTarget) return;
|
|
2389
|
+
const key = `${normalizedTarget.platform}:${normalizedTarget.to}`;
|
|
2352
2390
|
if (seenTargets.has(key)) return;
|
|
2353
2391
|
seenTargets.add(key);
|
|
2354
|
-
candidateTargets.push(
|
|
2392
|
+
candidateTargets.push(normalizedTarget);
|
|
2355
2393
|
};
|
|
2356
2394
|
|
|
2357
2395
|
addCandidate(taskTarget);
|
|
2358
2396
|
addCandidate(fallbackTarget);
|
|
2397
|
+
for (const row of recentTargets) {
|
|
2398
|
+
addCandidate({
|
|
2399
|
+
platform: row.platform,
|
|
2400
|
+
to: row.platform_chat_id
|
|
2401
|
+
});
|
|
2402
|
+
}
|
|
2359
2403
|
|
|
2360
2404
|
if (candidateTargets.length === 0) {
|
|
2361
2405
|
throw new Error('No messaging target is configured for this task run. Connect a platform and send at least one message on this server, or recreate the task after reconnecting.');
|
|
@@ -99,9 +99,34 @@ function adaptSpokenFormatting(text) {
|
|
|
99
99
|
.trim();
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
+
function coerceMessageContent(content) {
|
|
103
|
+
if (typeof content === 'string') return content;
|
|
104
|
+
if (content == null) return '';
|
|
105
|
+
if (typeof content === 'number' || typeof content === 'boolean' || typeof content === 'bigint') {
|
|
106
|
+
return String(content);
|
|
107
|
+
}
|
|
108
|
+
if (typeof content !== 'object') return String(content || '');
|
|
109
|
+
|
|
110
|
+
for (const key of ['text', 'content', 'message', 'summary']) {
|
|
111
|
+
if (typeof content[key] === 'string' && content[key].trim()) {
|
|
112
|
+
return content[key];
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (content.result != null && content.result !== content) {
|
|
117
|
+
return coerceMessageContent(content.result);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
try {
|
|
121
|
+
return JSON.stringify(content, null, 2);
|
|
122
|
+
} catch {
|
|
123
|
+
return String(content || '');
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
102
127
|
function normalizeOutgoingMessageForPlatform(platform, content, options = {}) {
|
|
103
128
|
const profile = getPlatformFormattingProfile(platform);
|
|
104
|
-
let text =
|
|
129
|
+
let text = coerceMessageContent(content);
|
|
105
130
|
|
|
106
131
|
if (options.stripNoResponseMarker !== false) {
|
|
107
132
|
text = text.replace(/\[NO RESPONSE\]/gi, '');
|
|
@@ -104,6 +104,9 @@ class MessagingManager extends EventEmitter {
|
|
|
104
104
|
return null;
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
+
const normalizedIncomingContent = normalizeOutgoingMessageForPlatform(platformName, msg?.content, {
|
|
108
|
+
stripNoResponseMarker: false
|
|
109
|
+
});
|
|
107
110
|
const agentId = this._agentId(userId, {
|
|
108
111
|
...options,
|
|
109
112
|
agentId: options?.agentId ?? msg?.agentId ?? null,
|
|
@@ -135,7 +138,7 @@ class MessagingManager extends EventEmitter {
|
|
|
135
138
|
userId,
|
|
136
139
|
agentId,
|
|
137
140
|
'user',
|
|
138
|
-
|
|
141
|
+
normalizedIncomingContent,
|
|
139
142
|
platformName,
|
|
140
143
|
msg.messageId,
|
|
141
144
|
msg.chatId,
|
|
@@ -143,7 +146,7 @@ class MessagingManager extends EventEmitter {
|
|
|
143
146
|
msg.timestamp,
|
|
144
147
|
);
|
|
145
148
|
|
|
146
|
-
const enrichedMsg = { ...msg, agentId, platform: platformName };
|
|
149
|
+
const enrichedMsg = { ...msg, content: normalizedIncomingContent, agentId, platform: platformName };
|
|
147
150
|
|
|
148
151
|
if (this.isShuttingDown) {
|
|
149
152
|
return enrichedMsg;
|
|
@@ -13,11 +13,58 @@ const { TaskRepository } = require('./task_repository');
|
|
|
13
13
|
const { TriggerRegistry } = require('./trigger_registry');
|
|
14
14
|
const scheduleAdapter = require('./adapters/schedule');
|
|
15
15
|
const { normalizeJsonObject } = require('./utils');
|
|
16
|
+
const { normalizeOutgoingMessageForPlatform } = require('../messaging/formatting_guides');
|
|
16
17
|
|
|
17
18
|
const MAX_AUTONOMOUS_RETRIES = 1;
|
|
18
19
|
const MAX_RECURRING_TASK_START_DELAY_MS = 90 * 1000;
|
|
19
20
|
const INTEGRATION_TRIGGER_POLL_CRON = '* * * * *';
|
|
20
21
|
|
|
22
|
+
function normalizeStoredString(value) {
|
|
23
|
+
if (value == null) return '';
|
|
24
|
+
if (typeof value !== 'string') return String(value || '').trim();
|
|
25
|
+
let current = value.trim();
|
|
26
|
+
for (let i = 0; i < 2; i += 1) {
|
|
27
|
+
if (!current) return '';
|
|
28
|
+
try {
|
|
29
|
+
const parsed = JSON.parse(current);
|
|
30
|
+
if (typeof parsed === 'string') {
|
|
31
|
+
current = parsed.trim();
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
return '';
|
|
35
|
+
} catch {
|
|
36
|
+
return current;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return current;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function normalizeNotifyTarget(target = {}) {
|
|
43
|
+
const platform = normalizeStoredString(target.platform);
|
|
44
|
+
const to = normalizeStoredString(target.to);
|
|
45
|
+
if (!platform || !to) return null;
|
|
46
|
+
return { platform, to };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function stringifyTaskResult(result) {
|
|
50
|
+
if (typeof result === 'string') return result;
|
|
51
|
+
if (result == null) return '';
|
|
52
|
+
if (typeof result !== 'object') return String(result);
|
|
53
|
+
|
|
54
|
+
for (const key of ['content', 'message', 'text', 'summary', 'finalResponse', 'final_response']) {
|
|
55
|
+
if (typeof result[key] === 'string' && result[key].trim()) {
|
|
56
|
+
return result[key];
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (result.result != null && result.result !== result) {
|
|
61
|
+
const nested = stringifyTaskResult(result.result);
|
|
62
|
+
if (nested) return nested;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return '';
|
|
66
|
+
}
|
|
67
|
+
|
|
21
68
|
class TaskRuntime {
|
|
22
69
|
constructor(io, agentEngine, app = null) {
|
|
23
70
|
this.io = io;
|
|
@@ -343,6 +390,17 @@ class TaskRuntime {
|
|
|
343
390
|
const result = typeof this.agentEngine.runWithModel === 'function'
|
|
344
391
|
? await this.agentEngine.runWithModel(userId, finalPrompt, runOptions, normalizedConfig.model || null)
|
|
345
392
|
: await this.agentEngine.run(userId, finalPrompt, runOptions);
|
|
393
|
+
const fallbackDelivery = await this._deliverTaskResultIfNeeded({
|
|
394
|
+
userId,
|
|
395
|
+
agentId,
|
|
396
|
+
taskId,
|
|
397
|
+
taskConfig: normalizedConfig,
|
|
398
|
+
result,
|
|
399
|
+
deliveryState,
|
|
400
|
+
});
|
|
401
|
+
if (fallbackDelivery && result && typeof result === 'object') {
|
|
402
|
+
result.taskDelivery = fallbackDelivery;
|
|
403
|
+
}
|
|
346
404
|
this.io.to(`user:${userId}`).emit('tasks:task_complete', { taskId, result });
|
|
347
405
|
return result;
|
|
348
406
|
} catch (err) {
|
|
@@ -362,7 +420,11 @@ class TaskRuntime {
|
|
|
362
420
|
}
|
|
363
421
|
} catch (err) {
|
|
364
422
|
console.error(`[Tasks] Task ${taskId} error:`, err.message);
|
|
365
|
-
this.io.to(`user:${userId}`).emit('tasks:
|
|
423
|
+
this.io.to(`user:${userId}`).emit('tasks:task_skipped', {
|
|
424
|
+
taskId,
|
|
425
|
+
reason: 'execution_failed',
|
|
426
|
+
timestamp: new Date().toISOString(),
|
|
427
|
+
});
|
|
366
428
|
return { skipped: false, error: err.message };
|
|
367
429
|
}
|
|
368
430
|
}
|
|
@@ -486,25 +548,134 @@ class TaskRuntime {
|
|
|
486
548
|
|
|
487
549
|
_getDefaultNotifyTarget(userId, agentId = null) {
|
|
488
550
|
const scopedAgentId = resolveAgentId(userId, agentId);
|
|
489
|
-
return {
|
|
551
|
+
return normalizeNotifyTarget({
|
|
490
552
|
platform: this._getAgentSetting(userId, scopedAgentId, 'last_platform'),
|
|
491
553
|
to: this._getAgentSetting(userId, scopedAgentId, 'last_chat_id'),
|
|
492
|
-
};
|
|
554
|
+
});
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
_buildNotifyTargets(userId, agentId, taskConfig = {}) {
|
|
558
|
+
const scopedAgentId = resolveAgentId(userId, agentId);
|
|
559
|
+
const candidates = [
|
|
560
|
+
normalizeNotifyTarget({
|
|
561
|
+
platform: taskConfig.notifyPlatform,
|
|
562
|
+
to: taskConfig.notifyTo,
|
|
563
|
+
}),
|
|
564
|
+
this._getDefaultNotifyTarget(userId, scopedAgentId),
|
|
565
|
+
...this.taskRepository.listRecentMessageTargets(userId, scopedAgentId).map((row) => normalizeNotifyTarget({
|
|
566
|
+
platform: row.platform,
|
|
567
|
+
to: row.platform_chat_id,
|
|
568
|
+
})),
|
|
569
|
+
];
|
|
570
|
+
|
|
571
|
+
const unique = [];
|
|
572
|
+
const seen = new Set();
|
|
573
|
+
for (const target of candidates) {
|
|
574
|
+
if (!target) continue;
|
|
575
|
+
const key = `${target.platform}:${target.to}`;
|
|
576
|
+
if (seen.has(key)) continue;
|
|
577
|
+
seen.add(key);
|
|
578
|
+
unique.push(target);
|
|
579
|
+
}
|
|
580
|
+
return unique;
|
|
493
581
|
}
|
|
494
582
|
|
|
495
583
|
_ensureDefaultNotifyTarget(userId, agentId, taskConfig, taskId) {
|
|
496
584
|
const normalized = { ...taskConfig };
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
585
|
+
const existingTarget = normalizeNotifyTarget({
|
|
586
|
+
platform: normalized.notifyPlatform,
|
|
587
|
+
to: normalized.notifyTo,
|
|
588
|
+
});
|
|
589
|
+
if (existingTarget) {
|
|
590
|
+
normalized.notifyPlatform = existingTarget.platform;
|
|
591
|
+
normalized.notifyTo = existingTarget.to;
|
|
592
|
+
}
|
|
593
|
+
if (!normalized.callTo && !existingTarget) {
|
|
594
|
+
const notifyTarget = this._buildNotifyTargets(userId, agentId, normalized)[0];
|
|
595
|
+
if (notifyTarget) {
|
|
500
596
|
normalized.notifyPlatform = notifyTarget.platform;
|
|
501
597
|
normalized.notifyTo = notifyTarget.to;
|
|
502
|
-
this.taskRepository.updateTaskConfig(taskId, userId, normalized);
|
|
503
598
|
}
|
|
504
599
|
}
|
|
600
|
+
if (
|
|
601
|
+
normalized.notifyPlatform !== taskConfig.notifyPlatform
|
|
602
|
+
|| normalized.notifyTo !== taskConfig.notifyTo
|
|
603
|
+
) {
|
|
604
|
+
this.taskRepository.updateTaskConfig(taskId, userId, normalized);
|
|
605
|
+
}
|
|
505
606
|
return normalized;
|
|
506
607
|
}
|
|
507
608
|
|
|
609
|
+
async _deliverTaskResultIfNeeded({
|
|
610
|
+
userId,
|
|
611
|
+
agentId,
|
|
612
|
+
taskId,
|
|
613
|
+
taskConfig,
|
|
614
|
+
result,
|
|
615
|
+
deliveryState,
|
|
616
|
+
}) {
|
|
617
|
+
if (deliveryState?.messagingSent || taskConfig.callTo) return null;
|
|
618
|
+
const manager = this.app?.locals?.messagingManager || this.agentEngine?.messagingManager || null;
|
|
619
|
+
if (!manager) return null;
|
|
620
|
+
|
|
621
|
+
const targets = this._buildNotifyTargets(userId, agentId, taskConfig);
|
|
622
|
+
if (!targets.length) return null;
|
|
623
|
+
|
|
624
|
+
let lastError = null;
|
|
625
|
+
for (const target of targets) {
|
|
626
|
+
const message = normalizeOutgoingMessageForPlatform(
|
|
627
|
+
target.platform,
|
|
628
|
+
stringifyTaskResult(result),
|
|
629
|
+
{ stripNoResponseMarker: false },
|
|
630
|
+
);
|
|
631
|
+
if (!message || message.toUpperCase() === '[NO RESPONSE]') return null;
|
|
632
|
+
|
|
633
|
+
const status = typeof manager.getPlatformStatus === 'function'
|
|
634
|
+
? manager.getPlatformStatus(userId, target.platform, { agentId })
|
|
635
|
+
: null;
|
|
636
|
+
if (!status || status.status !== 'connected') {
|
|
637
|
+
lastError = new Error(`Platform ${target.platform} is not connected on this server.`);
|
|
638
|
+
continue;
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
try {
|
|
642
|
+
const sendResult = await manager.sendMessage(userId, target.platform, target.to, message, {
|
|
643
|
+
agentId,
|
|
644
|
+
runId: result?.runId || null,
|
|
645
|
+
persistConversation: true,
|
|
646
|
+
});
|
|
647
|
+
deliveryState.messagingSent = true;
|
|
648
|
+
deliveryState.lastSentMessage = message;
|
|
649
|
+
if (!Array.isArray(deliveryState.sentMessages)) {
|
|
650
|
+
deliveryState.sentMessages = [];
|
|
651
|
+
}
|
|
652
|
+
deliveryState.sentMessages.push(message);
|
|
653
|
+
|
|
654
|
+
if (taskConfig.notifyPlatform !== target.platform || taskConfig.notifyTo !== target.to) {
|
|
655
|
+
this.taskRepository.updateTaskConfig(taskId, userId, {
|
|
656
|
+
...taskConfig,
|
|
657
|
+
notifyPlatform: target.platform,
|
|
658
|
+
notifyTo: target.to,
|
|
659
|
+
});
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
return {
|
|
663
|
+
sent: true,
|
|
664
|
+
platform: target.platform,
|
|
665
|
+
to: target.to,
|
|
666
|
+
result: sendResult,
|
|
667
|
+
};
|
|
668
|
+
} catch (error) {
|
|
669
|
+
lastError = error;
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
if (lastError) {
|
|
674
|
+
console.error(`[Tasks] Task ${taskId} notification delivery failed:`, lastError.message);
|
|
675
|
+
}
|
|
676
|
+
return null;
|
|
677
|
+
}
|
|
678
|
+
|
|
508
679
|
_getTaskConversation(userId, taskId, taskName, agentId = null) {
|
|
509
680
|
const scopedAgentId = resolveAgentId(userId, agentId);
|
|
510
681
|
const platform = 'tasks';
|
|
@@ -131,6 +131,19 @@ class TaskRepository {
|
|
|
131
131
|
.run(JSON.stringify(taskConfig), taskId, userId);
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
+
listRecentMessageTargets(userId, agentId, limit = 20) {
|
|
135
|
+
return db.prepare(
|
|
136
|
+
`SELECT platform, platform_chat_id
|
|
137
|
+
FROM messages
|
|
138
|
+
WHERE user_id = ?
|
|
139
|
+
AND agent_id = ?
|
|
140
|
+
AND platform IS NOT NULL
|
|
141
|
+
AND platform_chat_id IS NOT NULL
|
|
142
|
+
ORDER BY id DESC
|
|
143
|
+
LIMIT ?`
|
|
144
|
+
).all(userId, agentId, Math.max(1, Math.min(Number(limit) || 20, 100)));
|
|
145
|
+
}
|
|
146
|
+
|
|
134
147
|
getAgentSetting(userId, agentId, key) {
|
|
135
148
|
return db.prepare('SELECT value FROM agent_settings WHERE user_id = ? AND agent_id = ? AND key = ?')
|
|
136
149
|
.get(userId, agentId, key);
|