ec-web 0.0.10 → 0.0.12
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/ipc-client.js +16 -1
- package/dist/process-utils.js +20 -6
- package/dist/sources/msg.js +26 -11
- package/dist/sources/session-codex.js +17 -2
- package/dist/static/app.js +49 -5
- package/dist/static/index.html +1 -1
- package/dist/static/style.css +11 -0
- package/package.json +1 -1
package/dist/ipc-client.js
CHANGED
|
@@ -7,7 +7,22 @@
|
|
|
7
7
|
* watch 用到的只读查询:aun-aids / aun-aid-stats / status / evolagent.list / ping
|
|
8
8
|
*/
|
|
9
9
|
import net from 'net';
|
|
10
|
+
import fs from 'fs';
|
|
11
|
+
import path from 'path';
|
|
12
|
+
const LOCAL_CONTROL_COMMANDS = new Set(['menu.exec', 'monitor-snapshot']);
|
|
10
13
|
export function ipcQuery(socketPath, cmd, timeoutMs = 3000) {
|
|
14
|
+
let request = cmd;
|
|
15
|
+
if (LOCAL_CONTROL_COMMANDS.has(cmd.type) && typeof cmd.controlToken !== 'string') {
|
|
16
|
+
try {
|
|
17
|
+
const tokenPath = process.platform === 'win32'
|
|
18
|
+
? path.join(process.env.EVOLCORE_HOME || '', 'data', 'instance', 'control.token')
|
|
19
|
+
: path.join(path.dirname(socketPath), 'control.token');
|
|
20
|
+
const controlToken = fs.readFileSync(tokenPath, 'utf8').trim();
|
|
21
|
+
if (controlToken)
|
|
22
|
+
request = { ...cmd, controlToken };
|
|
23
|
+
}
|
|
24
|
+
catch { }
|
|
25
|
+
}
|
|
11
26
|
return new Promise((resolve) => {
|
|
12
27
|
const conn = net.connect(socketPath);
|
|
13
28
|
let buf = '';
|
|
@@ -16,7 +31,7 @@ export function ipcQuery(socketPath, cmd, timeoutMs = 3000) {
|
|
|
16
31
|
resolve(null);
|
|
17
32
|
}, timeoutMs);
|
|
18
33
|
conn.on('connect', () => {
|
|
19
|
-
conn.write(JSON.stringify(
|
|
34
|
+
conn.write(JSON.stringify(request) + '\n');
|
|
20
35
|
});
|
|
21
36
|
conn.on('data', (data) => {
|
|
22
37
|
buf += data.toString();
|
package/dist/process-utils.js
CHANGED
|
@@ -66,16 +66,30 @@ function getStartTimeLinux(pid) {
|
|
|
66
66
|
const starttimeJiffies = parseInt(tail.split(' ')[19], 10);
|
|
67
67
|
if (isNaN(starttimeJiffies))
|
|
68
68
|
return null;
|
|
69
|
-
|
|
69
|
+
// Use the kernel boot timestamp, the same source as EvolCore's process
|
|
70
|
+
// introspection. Deriving boot time as `Date.now() - /proc/uptime` can
|
|
71
|
+
// drift when the host clock is stepped while ECWeb is starting, producing
|
|
72
|
+
// instance records tens of seconds away from the real PID start time.
|
|
73
|
+
let bootSec = null;
|
|
70
74
|
try {
|
|
71
|
-
|
|
75
|
+
const statContent = fs.readFileSync('/proc/stat', 'utf-8');
|
|
76
|
+
const match = statContent.match(/^btime\s+(\d+)$/m);
|
|
77
|
+
if (match)
|
|
78
|
+
bootSec = parseInt(match[1], 10);
|
|
72
79
|
}
|
|
73
|
-
catch {
|
|
74
|
-
|
|
80
|
+
catch { }
|
|
81
|
+
if (!bootSec || !Number.isFinite(bootSec)) {
|
|
82
|
+
let uptimeSec;
|
|
83
|
+
try {
|
|
84
|
+
uptimeSec = parseFloat(fs.readFileSync('/proc/uptime', 'utf-8').split(' ')[0]);
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
bootSec = (Date.now() - uptimeSec * 1000) / 1000;
|
|
75
90
|
}
|
|
76
91
|
const clkTck = 100; // 几乎所有 Linux 为 100
|
|
77
|
-
|
|
78
|
-
return Math.round(bootMs + (starttimeJiffies / clkTck) * 1000);
|
|
92
|
+
return Math.round((bootSec + (starttimeJiffies / clkTck)) * 1000);
|
|
79
93
|
}
|
|
80
94
|
function getStartTimeMacOS(pid) {
|
|
81
95
|
const r = spawnSync('ps', ['-o', 'lstart=', '-p', String(pid)], { encoding: 'utf-8', timeout: 3000 });
|
package/dist/sources/msg.js
CHANGED
|
@@ -804,20 +804,35 @@ function selectedChats(chats, scope) {
|
|
|
804
804
|
return [];
|
|
805
805
|
return chats.filter(chat => scopeId(chat) === scope);
|
|
806
806
|
}
|
|
807
|
+
export function messageDisplayRoute(message) {
|
|
808
|
+
if (message.chatType !== 'group') {
|
|
809
|
+
return { displayFrom: message.from, displayTo: message.to };
|
|
810
|
+
}
|
|
811
|
+
return {
|
|
812
|
+
displayFrom: message.dir === 'out' ? (message.selfAID || message.from) : message.from,
|
|
813
|
+
displayTo: message.groupName || message.groupId || message.to,
|
|
814
|
+
};
|
|
815
|
+
}
|
|
807
816
|
function messagesFor(chats, peer, before, limit) {
|
|
808
817
|
const selected = peer
|
|
809
818
|
? chats.filter(chat => chatKey(chat) === peer)
|
|
810
819
|
: chats;
|
|
811
|
-
const messages = selected.flatMap(chat => chat.messages.map(msg =>
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
820
|
+
const messages = selected.flatMap(chat => chat.messages.map(msg => {
|
|
821
|
+
const message = {
|
|
822
|
+
...msg,
|
|
823
|
+
channelType: chat.channelType,
|
|
824
|
+
selfAID: chat.selfAID,
|
|
825
|
+
peerName: chat.peerName,
|
|
826
|
+
groupName: chat.groupName,
|
|
827
|
+
};
|
|
828
|
+
return {
|
|
829
|
+
...message,
|
|
830
|
+
channel: chat.channel,
|
|
831
|
+
partition: chat.partition,
|
|
832
|
+
threadName: chat.threadName,
|
|
833
|
+
...messageDisplayRoute(message),
|
|
834
|
+
};
|
|
835
|
+
}));
|
|
821
836
|
messages.sort((a, b) => (a.ts || 0) - (b.ts || 0));
|
|
822
837
|
const end = before == null ? messages.length : Math.min(Math.max(before, 0), messages.length);
|
|
823
838
|
const start = Math.max(0, end - limit);
|
|
@@ -892,7 +907,7 @@ async function buildSessionContext(chat) {
|
|
|
892
907
|
}
|
|
893
908
|
catch { }
|
|
894
909
|
return {
|
|
895
|
-
sessionId: active.
|
|
910
|
+
sessionId: active.id || null,
|
|
896
911
|
evolcoreSessionId: active.id || null,
|
|
897
912
|
name: active.name || null,
|
|
898
913
|
baseagent: active.baseagent || active.agentType || null,
|
|
@@ -430,6 +430,18 @@ function toolOutputText(output) {
|
|
|
430
430
|
return String(output);
|
|
431
431
|
}
|
|
432
432
|
}
|
|
433
|
+
function classifyCodexToolRejection(text) {
|
|
434
|
+
const normalized = text.replace(/\\(["'])/g, '$1');
|
|
435
|
+
if (!/Rejected\(\s*["']rejected by user["']\s*\)/i.test(normalized))
|
|
436
|
+
return undefined;
|
|
437
|
+
const isManagedEcSend = /(?:^|[/'\s])ec\s+(?:msg|group)\s+send\b/i.test(text);
|
|
438
|
+
return {
|
|
439
|
+
kind: 'approval_rejected',
|
|
440
|
+
source: isManagedEcSend ? 'evolcore-policy' : 'codex-approval',
|
|
441
|
+
reason: 'rejected_by_user',
|
|
442
|
+
executed: false,
|
|
443
|
+
};
|
|
444
|
+
}
|
|
433
445
|
export function parseCodexToolEvent(event) {
|
|
434
446
|
if (!event || (event.type !== 'event_msg' && event.type !== 'response_item') || !event.payload)
|
|
435
447
|
return null;
|
|
@@ -457,6 +469,8 @@ export function parseCodexToolEvent(event) {
|
|
|
457
469
|
};
|
|
458
470
|
}
|
|
459
471
|
if (payload.type === 'function_call_output' || payload.type === 'custom_tool_call_output') {
|
|
472
|
+
const text = toolOutputText(payload.output);
|
|
473
|
+
const rejection = classifyCodexToolRejection(text);
|
|
460
474
|
return {
|
|
461
475
|
kind: 'result',
|
|
462
476
|
callId,
|
|
@@ -467,8 +481,9 @@ export function parseCodexToolEvent(event) {
|
|
|
467
481
|
category: 'tool_result',
|
|
468
482
|
blocks: [{
|
|
469
483
|
kind: 'tool_result',
|
|
470
|
-
text
|
|
471
|
-
isError: payload.is_error === true || payload.status === 'failed',
|
|
484
|
+
text,
|
|
485
|
+
isError: payload.is_error === true || payload.status === 'failed' || !!rejection,
|
|
486
|
+
...(rejection ? { rejection } : {}),
|
|
472
487
|
}],
|
|
473
488
|
},
|
|
474
489
|
};
|
package/dist/static/app.js
CHANGED
|
@@ -278,7 +278,7 @@ const translations = {
|
|
|
278
278
|
'messages.msgType.command': '命令',
|
|
279
279
|
'messages.groupCount': '群 {count}',
|
|
280
280
|
'messages.privateCount': '单 {count}',
|
|
281
|
-
'messages.session.field.sessionId': '会话 ID',
|
|
281
|
+
'messages.session.field.sessionId': 'EvolCore 会话 ID',
|
|
282
282
|
'messages.session.field.baseagent': 'Baseagent',
|
|
283
283
|
'messages.session.field.chatMode': '模式',
|
|
284
284
|
'messages.session.field.permissionMode': '权限',
|
|
@@ -342,6 +342,11 @@ const translations = {
|
|
|
342
342
|
'sessions.block.thinking': '思考',
|
|
343
343
|
'sessions.block.result': '结果',
|
|
344
344
|
'sessions.block.resultError': '结果',
|
|
345
|
+
'sessions.block.rejection.title': '已拦截',
|
|
346
|
+
'sessions.block.rejection.source.policy': 'EvolCore 策略自动拦截',
|
|
347
|
+
'sessions.block.rejection.source.approval': '审批通道拒绝',
|
|
348
|
+
'sessions.block.rejection.notExecuted': '命令未执行',
|
|
349
|
+
'sessions.block.rejection.reason': '底层返回:Rejected("rejected by user")',
|
|
345
350
|
'sessions.content.expand': '展开内容',
|
|
346
351
|
'sessions.content.collapse': '收起内容',
|
|
347
352
|
'sessions.contextTitle': '最后一轮喂给模型的完整上下文大小',
|
|
@@ -628,6 +633,7 @@ const translations = {
|
|
|
628
633
|
'triggers.error.promptRequired': 'Prompt 不能为空',
|
|
629
634
|
'triggers.error.channelRequired': '目标渠道不能为空',
|
|
630
635
|
'triggers.error.channelIdRequired': '渠道 ID 不能为空',
|
|
636
|
+
'triggers.error.chatTypeRequired': 'AUN 目标必须选择私聊或群聊',
|
|
631
637
|
'triggers.error.scriptPathRequired': '脚本路径不能为空',
|
|
632
638
|
'triggers.error.scriptRuntimeRequired': '脚本运行时不能为空',
|
|
633
639
|
'triggers.error.threadRequired': '指定话题会话时必须填写话题会话 ID',
|
|
@@ -676,6 +682,9 @@ const translations = {
|
|
|
676
682
|
'triggers.delivery.off': '禁用',
|
|
677
683
|
'triggers.field.targetChannel': '渠道实例',
|
|
678
684
|
'triggers.field.channelId': '渠道 ID',
|
|
685
|
+
'triggers.field.chatType': '会话类型',
|
|
686
|
+
'triggers.chatType.private': '私聊',
|
|
687
|
+
'triggers.chatType.group': '群聊',
|
|
679
688
|
'triggers.field.sessionStrategy': '会话选择',
|
|
680
689
|
'triggers.field.threadId': '话题会话 ID',
|
|
681
690
|
'triggers.field.maxRuns': '最大执行次数',
|
|
@@ -1166,7 +1175,7 @@ const translations = {
|
|
|
1166
1175
|
'messages.msgType.command': 'Command',
|
|
1167
1176
|
'messages.groupCount': '{count} groups',
|
|
1168
1177
|
'messages.privateCount': '{count} private',
|
|
1169
|
-
'messages.session.field.sessionId': 'Session ID',
|
|
1178
|
+
'messages.session.field.sessionId': 'EvolCore Session ID',
|
|
1170
1179
|
'messages.session.field.baseagent': 'Baseagent',
|
|
1171
1180
|
'messages.session.field.chatMode': 'Mode',
|
|
1172
1181
|
'messages.session.field.permissionMode': 'Perm',
|
|
@@ -1230,6 +1239,11 @@ const translations = {
|
|
|
1230
1239
|
'sessions.block.thinking': 'Thinking',
|
|
1231
1240
|
'sessions.block.result': 'Result',
|
|
1232
1241
|
'sessions.block.resultError': 'Result',
|
|
1242
|
+
'sessions.block.rejection.title': 'Intercepted',
|
|
1243
|
+
'sessions.block.rejection.source.policy': 'EvolCore policy auto-blocked',
|
|
1244
|
+
'sessions.block.rejection.source.approval': 'Approval channel rejected',
|
|
1245
|
+
'sessions.block.rejection.notExecuted': 'Command was not executed',
|
|
1246
|
+
'sessions.block.rejection.reason': 'Backend response: Rejected("rejected by user")',
|
|
1233
1247
|
'sessions.content.expand': 'Expand content',
|
|
1234
1248
|
'sessions.content.collapse': 'Collapse content',
|
|
1235
1249
|
'sessions.contextTitle': 'Full context size sent to the model in the last turn',
|
|
@@ -1516,6 +1530,7 @@ const translations = {
|
|
|
1516
1530
|
'triggers.error.promptRequired': 'Prompt is required',
|
|
1517
1531
|
'triggers.error.channelRequired': 'Target channel is required',
|
|
1518
1532
|
'triggers.error.channelIdRequired': 'Channel ID is required',
|
|
1533
|
+
'triggers.error.chatTypeRequired': 'AUN targets require Private or Group chat type',
|
|
1519
1534
|
'triggers.error.scriptPathRequired': 'Script path is required',
|
|
1520
1535
|
'triggers.error.scriptRuntimeRequired': 'Script runtime is required',
|
|
1521
1536
|
'triggers.error.threadRequired': 'Topic session ID is required',
|
|
@@ -1564,6 +1579,9 @@ const translations = {
|
|
|
1564
1579
|
'triggers.delivery.off': 'Disabled',
|
|
1565
1580
|
'triggers.field.targetChannel': 'Channel instance',
|
|
1566
1581
|
'triggers.field.channelId': 'Channel ID',
|
|
1582
|
+
'triggers.field.chatType': 'Chat Type',
|
|
1583
|
+
'triggers.chatType.private': 'Private',
|
|
1584
|
+
'triggers.chatType.group': 'Group',
|
|
1567
1585
|
'triggers.field.sessionStrategy': 'Session Selection',
|
|
1568
1586
|
'triggers.field.threadId': 'Topic Session ID',
|
|
1569
1587
|
'triggers.field.maxRuns': 'Max Runs',
|
|
@@ -3234,7 +3252,7 @@ function renderMsg(data) {
|
|
|
3234
3252
|
for (const m of messages) {
|
|
3235
3253
|
const cls = m.dir === 'in' ? 'in' : 'out';
|
|
3236
3254
|
const arrow = m.dir === 'in' ? '↓' : '↑';
|
|
3237
|
-
const from = shortId(m.from), to = shortId(m.to);
|
|
3255
|
+
const from = shortId(m.displayFrom || m.from), to = shortId(m.displayTo || m.to);
|
|
3238
3256
|
const tags = [];
|
|
3239
3257
|
if (m.channelType) tags.push(m.channelType);
|
|
3240
3258
|
if (m.chatType === 'group') tags.push(t('messages.tag.group'));
|
|
@@ -3682,11 +3700,23 @@ function renderBlocks(blocks, options = {}) {
|
|
|
3682
3700
|
: '';
|
|
3683
3701
|
out += `<details class="blk blk-tool" open><summary class="tool-head">${icon} <span class="tool-name">${esc(tool)}</span></summary>${toolParams}</details>`;
|
|
3684
3702
|
} else if (b.kind === 'tool_result') {
|
|
3685
|
-
const
|
|
3703
|
+
const rejection = b.rejection?.kind === 'approval_rejected' ? b.rejection : undefined;
|
|
3704
|
+
const cls = b.isError ? `blk-result err${rejection ? ' rejection' : ''}` : 'blk-result';
|
|
3686
3705
|
const loadFull = b.truncated && b.resultKey
|
|
3687
3706
|
? `<button class="ctrl-btn result-load-full" type="button" data-result-key="${esc(b.resultKey)}">${t('sessions.loadFullResult') || '加载完整结果'}</button>`
|
|
3688
3707
|
: '';
|
|
3689
|
-
|
|
3708
|
+
const rejectionMeta = rejection
|
|
3709
|
+
? '<div class="result-rejection-meta">' +
|
|
3710
|
+
`<span class="result-rejection-badge">⚠ ${t('sessions.block.rejection.title')}</span>` +
|
|
3711
|
+
`<span>${rejection.source === 'evolcore-policy' ? t('sessions.block.rejection.source.policy') : t('sessions.block.rejection.source.approval')}</span>` +
|
|
3712
|
+
`<span>${t('sessions.block.rejection.notExecuted')}</span>` +
|
|
3713
|
+
`<span class="result-rejection-reason">${t('sessions.block.rejection.reason')}</span>` +
|
|
3714
|
+
'</div>'
|
|
3715
|
+
: '';
|
|
3716
|
+
const resultLabel = rejection
|
|
3717
|
+
? t('sessions.block.rejection.title')
|
|
3718
|
+
: b.isError ? t('sessions.block.resultError') : t('sessions.block.result');
|
|
3719
|
+
out += `<details class="blk ${cls}" open><summary>${b.isError ? '✗ ' : '↳ '}${resultLabel}</summary>${rejectionMeta}` +
|
|
3690
3720
|
`<div class="result-content collapse-content"><pre class="result-body collapse-body">${esc(b.text)}</pre>${loadFull}<button class="collapse-arrow-toggle" type="button" hidden aria-expanded="false"><span class="collapse-arrow-icon" aria-hidden="true"></span></button></div></details>`;
|
|
3691
3721
|
} else if (b.kind === 'subtask') {
|
|
3692
3722
|
const knownStatuses = ['running', 'completed', 'failed', 'stopped', 'killed'];
|
|
@@ -5361,6 +5391,10 @@ const TRIGGER_TARGET_SESSIONS = [
|
|
|
5361
5391
|
['main', () => t('triggers.session.main')],
|
|
5362
5392
|
['thread', () => t('triggers.session.thread')],
|
|
5363
5393
|
];
|
|
5394
|
+
const TRIGGER_TARGET_CHAT_TYPES = [
|
|
5395
|
+
['private', () => t('triggers.chatType.private')],
|
|
5396
|
+
['group', () => t('triggers.chatType.group')],
|
|
5397
|
+
];
|
|
5364
5398
|
const TRIGGER_CONCURRENCY_OPTIONS = [
|
|
5365
5399
|
['forbid', () => t('triggers.concurrency.forbid')],
|
|
5366
5400
|
['replace', () => t('triggers.concurrency.replace')],
|
|
@@ -5873,6 +5907,7 @@ function triggerPrimaryTarget(definition) {
|
|
|
5873
5907
|
channelId: definition.origin.channelId || definition.origin.peerId || '',
|
|
5874
5908
|
session: definition.origin.session || 'main',
|
|
5875
5909
|
threadId: definition.origin.threadId || '',
|
|
5910
|
+
chatType: definition.origin.delivery?.chatType || '',
|
|
5876
5911
|
};
|
|
5877
5912
|
}
|
|
5878
5913
|
return null;
|
|
@@ -5949,6 +5984,7 @@ function triggerOriginalEditState(t) {
|
|
|
5949
5984
|
templateFailure: String(feedback.onFailure?.template ?? ''),
|
|
5950
5985
|
targetChannel: String(target.channelKey ?? t?.targetChannel ?? ''),
|
|
5951
5986
|
targetChannelId: String(target.channelId ?? t?.targetChannelId ?? ''),
|
|
5987
|
+
targetChatType: String(target.chatType ?? ''),
|
|
5952
5988
|
targetSessionStrategy: triggerUiSessionStrategy(target.session ?? t?.targetSessionStrategy),
|
|
5953
5989
|
targetThreadId: String(target.threadId ?? t?.targetThreadId ?? ''),
|
|
5954
5990
|
maxRuns: limits.maxRuns == null ? '' : String(limits.maxRuns),
|
|
@@ -6838,6 +6874,7 @@ function readTriggerEditValues(root) {
|
|
|
6838
6874
|
templateFailure: root.querySelector('#trig-edit-template-failure')?.value || '',
|
|
6839
6875
|
targetChannel: (root.querySelector('#trig-edit-channel')?.value || '').trim(),
|
|
6840
6876
|
targetChannelId: (root.querySelector('#trig-edit-channel-id')?.value || '').trim(),
|
|
6877
|
+
targetChatType: root.querySelector('#trig-edit-chat-type')?.value || '',
|
|
6841
6878
|
targetSessionStrategy: root.querySelector('#trig-edit-session-strategy')?.value || 'main',
|
|
6842
6879
|
targetThreadId: (root.querySelector('#trig-edit-thread')?.value || '').trim(),
|
|
6843
6880
|
maxRuns: (root.querySelector('#trig-edit-max-runs')?.value || '').trim(),
|
|
@@ -6907,6 +6944,7 @@ function triggerEditScheduleChanged(original, values) {
|
|
|
6907
6944
|
function triggerEditTargetChanged(original, values) {
|
|
6908
6945
|
return values.targetChannel !== original.targetChannel
|
|
6909
6946
|
|| values.targetChannelId !== original.targetChannelId
|
|
6947
|
+
|| values.targetChatType !== original.targetChatType
|
|
6910
6948
|
|| values.targetSessionStrategy !== original.targetSessionStrategy
|
|
6911
6949
|
|| values.targetThreadId !== original.targetThreadId;
|
|
6912
6950
|
}
|
|
@@ -6973,6 +7011,8 @@ function triggerDefinitionFromEdit(original, values, eventFilter, feedbackStrate
|
|
|
6973
7011
|
const target = triggerEditableObject(feedback.target);
|
|
6974
7012
|
target.channelKey = values.targetChannel;
|
|
6975
7013
|
target.channelId = values.targetChannelId;
|
|
7014
|
+
if (values.targetChatType) target.chatType = values.targetChatType;
|
|
7015
|
+
else delete target.chatType;
|
|
6976
7016
|
target.session = values.targetSessionStrategy;
|
|
6977
7017
|
if (values.targetSessionStrategy === 'thread') target.threadId = values.targetThreadId;
|
|
6978
7018
|
else delete target.threadId;
|
|
@@ -7046,6 +7086,9 @@ function collectTriggerEditPatch(ctx) {
|
|
|
7046
7086
|
if (feedbackStrategy === 'target') {
|
|
7047
7087
|
if (!values.targetChannel) return { error: t('triggers.error.channelRequired') };
|
|
7048
7088
|
if (!values.targetChannelId) return { error: t('triggers.error.channelIdRequired') };
|
|
7089
|
+
if ((values.targetChannel === 'aun' || values.targetChannel.startsWith('aun#')) && !values.targetChatType) {
|
|
7090
|
+
return { error: t('triggers.error.chatTypeRequired') };
|
|
7091
|
+
}
|
|
7049
7092
|
if (values.targetSessionStrategy === 'thread' && !values.targetThreadId) return { error: t('triggers.error.threadRequired') };
|
|
7050
7093
|
}
|
|
7051
7094
|
if (values.maxRuns) {
|
|
@@ -7191,6 +7234,7 @@ function openTriggerEditDrawer(id, agent) {
|
|
|
7191
7234
|
`<div id="trig-edit-target-fields" class="ag-edit-grid trig-edit-grid">` +
|
|
7192
7235
|
`<label class="ag-edit-field"><span>${t('triggers.field.targetChannel')}</span><select id="trig-edit-channel">${channelOptions}</select></label>` +
|
|
7193
7236
|
`<label class="ag-edit-field"><span>${t('triggers.field.channelId')}</span><input id="trig-edit-channel-id" type="text" autocomplete="off" spellcheck="false" value="${esc(original.targetChannelId)}"></label>` +
|
|
7237
|
+
`<label class="ag-edit-field"><span>${t('triggers.field.chatType')}</span><select id="trig-edit-chat-type">${triggerOptionHtml(TRIGGER_TARGET_CHAT_TYPES, original.targetChatType, t('common.none'))}</select></label>` +
|
|
7194
7238
|
`<label class="ag-edit-field"><span>${t('triggers.field.sessionStrategy')}</span><select id="trig-edit-session-strategy">${triggerOptionHtml(TRIGGER_TARGET_SESSIONS, original.targetSessionStrategy, null)}</select></label>` +
|
|
7195
7239
|
`<label id="trig-edit-thread-field" class="ag-edit-field ag-edit-field-wide"><span>${t('triggers.field.threadId')}</span><input id="trig-edit-thread" type="text" autocomplete="off" spellcheck="false" value="${esc(original.targetThreadId)}"></label>` +
|
|
7196
7240
|
`</div>` +
|
package/dist/static/index.html
CHANGED
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
|
|
49
49
|
</nav>
|
|
50
50
|
<span style="flex:1"></span>
|
|
51
|
-
2026-08-
|
|
51
|
+
2026-08-21 14:14
|
|
52
52
|
<span id="conn-status" class="conn-status" data-i18n="status.connecting">连接中…</span>
|
|
53
53
|
<button id="lang-btn" class="theme-btn" data-i18n-title="language.buttonTitle" title="切换语言">🌐</button>
|
|
54
54
|
<button id="theme-btn" class="theme-btn" data-i18n-title="theme.buttonTitle" title="主题">🌗</button>
|
package/dist/static/style.css
CHANGED
|
@@ -540,6 +540,17 @@ tr:hover td { background: var(--bg2); }
|
|
|
540
540
|
.blk-result { font-size: 12px; }
|
|
541
541
|
.blk-result summary { cursor: pointer; color: var(--dim); }
|
|
542
542
|
.blk-result.err summary { color: var(--red); }
|
|
543
|
+
.result-rejection-meta {
|
|
544
|
+
display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px;
|
|
545
|
+
margin-top: 7px; color: var(--dim); font-size: 11px;
|
|
546
|
+
}
|
|
547
|
+
.result-rejection-badge {
|
|
548
|
+
display: inline-flex; align-items: center; gap: 4px;
|
|
549
|
+
padding: 2px 7px; border: 1px solid color-mix(in srgb, var(--red) 45%, var(--border));
|
|
550
|
+
border-radius: 4px; color: var(--red); background: color-mix(in srgb, var(--red) 8%, transparent);
|
|
551
|
+
font-weight: 600;
|
|
552
|
+
}
|
|
553
|
+
.result-rejection-reason { flex-basis: 100%; overflow-wrap: anywhere; }
|
|
543
554
|
.collapse-content { position: relative; }
|
|
544
555
|
.result-content { --collapse-fade-bg: var(--bg); margin-top: 6px; }
|
|
545
556
|
.collapse-content::after {
|