ec-web 0.0.11 → 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/process-utils.js +20 -6
- package/dist/sources/msg.js +26 -11
- package/dist/static/app.js +25 -3
- package/dist/static/index.html +1 -1
- package/package.json +1 -1
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,
|
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': '权限',
|
|
@@ -633,6 +633,7 @@ const translations = {
|
|
|
633
633
|
'triggers.error.promptRequired': 'Prompt 不能为空',
|
|
634
634
|
'triggers.error.channelRequired': '目标渠道不能为空',
|
|
635
635
|
'triggers.error.channelIdRequired': '渠道 ID 不能为空',
|
|
636
|
+
'triggers.error.chatTypeRequired': 'AUN 目标必须选择私聊或群聊',
|
|
636
637
|
'triggers.error.scriptPathRequired': '脚本路径不能为空',
|
|
637
638
|
'triggers.error.scriptRuntimeRequired': '脚本运行时不能为空',
|
|
638
639
|
'triggers.error.threadRequired': '指定话题会话时必须填写话题会话 ID',
|
|
@@ -681,6 +682,9 @@ const translations = {
|
|
|
681
682
|
'triggers.delivery.off': '禁用',
|
|
682
683
|
'triggers.field.targetChannel': '渠道实例',
|
|
683
684
|
'triggers.field.channelId': '渠道 ID',
|
|
685
|
+
'triggers.field.chatType': '会话类型',
|
|
686
|
+
'triggers.chatType.private': '私聊',
|
|
687
|
+
'triggers.chatType.group': '群聊',
|
|
684
688
|
'triggers.field.sessionStrategy': '会话选择',
|
|
685
689
|
'triggers.field.threadId': '话题会话 ID',
|
|
686
690
|
'triggers.field.maxRuns': '最大执行次数',
|
|
@@ -1171,7 +1175,7 @@ const translations = {
|
|
|
1171
1175
|
'messages.msgType.command': 'Command',
|
|
1172
1176
|
'messages.groupCount': '{count} groups',
|
|
1173
1177
|
'messages.privateCount': '{count} private',
|
|
1174
|
-
'messages.session.field.sessionId': 'Session ID',
|
|
1178
|
+
'messages.session.field.sessionId': 'EvolCore Session ID',
|
|
1175
1179
|
'messages.session.field.baseagent': 'Baseagent',
|
|
1176
1180
|
'messages.session.field.chatMode': 'Mode',
|
|
1177
1181
|
'messages.session.field.permissionMode': 'Perm',
|
|
@@ -1526,6 +1530,7 @@ const translations = {
|
|
|
1526
1530
|
'triggers.error.promptRequired': 'Prompt is required',
|
|
1527
1531
|
'triggers.error.channelRequired': 'Target channel is required',
|
|
1528
1532
|
'triggers.error.channelIdRequired': 'Channel ID is required',
|
|
1533
|
+
'triggers.error.chatTypeRequired': 'AUN targets require Private or Group chat type',
|
|
1529
1534
|
'triggers.error.scriptPathRequired': 'Script path is required',
|
|
1530
1535
|
'triggers.error.scriptRuntimeRequired': 'Script runtime is required',
|
|
1531
1536
|
'triggers.error.threadRequired': 'Topic session ID is required',
|
|
@@ -1574,6 +1579,9 @@ const translations = {
|
|
|
1574
1579
|
'triggers.delivery.off': 'Disabled',
|
|
1575
1580
|
'triggers.field.targetChannel': 'Channel instance',
|
|
1576
1581
|
'triggers.field.channelId': 'Channel ID',
|
|
1582
|
+
'triggers.field.chatType': 'Chat Type',
|
|
1583
|
+
'triggers.chatType.private': 'Private',
|
|
1584
|
+
'triggers.chatType.group': 'Group',
|
|
1577
1585
|
'triggers.field.sessionStrategy': 'Session Selection',
|
|
1578
1586
|
'triggers.field.threadId': 'Topic Session ID',
|
|
1579
1587
|
'triggers.field.maxRuns': 'Max Runs',
|
|
@@ -3244,7 +3252,7 @@ function renderMsg(data) {
|
|
|
3244
3252
|
for (const m of messages) {
|
|
3245
3253
|
const cls = m.dir === 'in' ? 'in' : 'out';
|
|
3246
3254
|
const arrow = m.dir === 'in' ? '↓' : '↑';
|
|
3247
|
-
const from = shortId(m.from), to = shortId(m.to);
|
|
3255
|
+
const from = shortId(m.displayFrom || m.from), to = shortId(m.displayTo || m.to);
|
|
3248
3256
|
const tags = [];
|
|
3249
3257
|
if (m.channelType) tags.push(m.channelType);
|
|
3250
3258
|
if (m.chatType === 'group') tags.push(t('messages.tag.group'));
|
|
@@ -5383,6 +5391,10 @@ const TRIGGER_TARGET_SESSIONS = [
|
|
|
5383
5391
|
['main', () => t('triggers.session.main')],
|
|
5384
5392
|
['thread', () => t('triggers.session.thread')],
|
|
5385
5393
|
];
|
|
5394
|
+
const TRIGGER_TARGET_CHAT_TYPES = [
|
|
5395
|
+
['private', () => t('triggers.chatType.private')],
|
|
5396
|
+
['group', () => t('triggers.chatType.group')],
|
|
5397
|
+
];
|
|
5386
5398
|
const TRIGGER_CONCURRENCY_OPTIONS = [
|
|
5387
5399
|
['forbid', () => t('triggers.concurrency.forbid')],
|
|
5388
5400
|
['replace', () => t('triggers.concurrency.replace')],
|
|
@@ -5895,6 +5907,7 @@ function triggerPrimaryTarget(definition) {
|
|
|
5895
5907
|
channelId: definition.origin.channelId || definition.origin.peerId || '',
|
|
5896
5908
|
session: definition.origin.session || 'main',
|
|
5897
5909
|
threadId: definition.origin.threadId || '',
|
|
5910
|
+
chatType: definition.origin.delivery?.chatType || '',
|
|
5898
5911
|
};
|
|
5899
5912
|
}
|
|
5900
5913
|
return null;
|
|
@@ -5971,6 +5984,7 @@ function triggerOriginalEditState(t) {
|
|
|
5971
5984
|
templateFailure: String(feedback.onFailure?.template ?? ''),
|
|
5972
5985
|
targetChannel: String(target.channelKey ?? t?.targetChannel ?? ''),
|
|
5973
5986
|
targetChannelId: String(target.channelId ?? t?.targetChannelId ?? ''),
|
|
5987
|
+
targetChatType: String(target.chatType ?? ''),
|
|
5974
5988
|
targetSessionStrategy: triggerUiSessionStrategy(target.session ?? t?.targetSessionStrategy),
|
|
5975
5989
|
targetThreadId: String(target.threadId ?? t?.targetThreadId ?? ''),
|
|
5976
5990
|
maxRuns: limits.maxRuns == null ? '' : String(limits.maxRuns),
|
|
@@ -6860,6 +6874,7 @@ function readTriggerEditValues(root) {
|
|
|
6860
6874
|
templateFailure: root.querySelector('#trig-edit-template-failure')?.value || '',
|
|
6861
6875
|
targetChannel: (root.querySelector('#trig-edit-channel')?.value || '').trim(),
|
|
6862
6876
|
targetChannelId: (root.querySelector('#trig-edit-channel-id')?.value || '').trim(),
|
|
6877
|
+
targetChatType: root.querySelector('#trig-edit-chat-type')?.value || '',
|
|
6863
6878
|
targetSessionStrategy: root.querySelector('#trig-edit-session-strategy')?.value || 'main',
|
|
6864
6879
|
targetThreadId: (root.querySelector('#trig-edit-thread')?.value || '').trim(),
|
|
6865
6880
|
maxRuns: (root.querySelector('#trig-edit-max-runs')?.value || '').trim(),
|
|
@@ -6929,6 +6944,7 @@ function triggerEditScheduleChanged(original, values) {
|
|
|
6929
6944
|
function triggerEditTargetChanged(original, values) {
|
|
6930
6945
|
return values.targetChannel !== original.targetChannel
|
|
6931
6946
|
|| values.targetChannelId !== original.targetChannelId
|
|
6947
|
+
|| values.targetChatType !== original.targetChatType
|
|
6932
6948
|
|| values.targetSessionStrategy !== original.targetSessionStrategy
|
|
6933
6949
|
|| values.targetThreadId !== original.targetThreadId;
|
|
6934
6950
|
}
|
|
@@ -6995,6 +7011,8 @@ function triggerDefinitionFromEdit(original, values, eventFilter, feedbackStrate
|
|
|
6995
7011
|
const target = triggerEditableObject(feedback.target);
|
|
6996
7012
|
target.channelKey = values.targetChannel;
|
|
6997
7013
|
target.channelId = values.targetChannelId;
|
|
7014
|
+
if (values.targetChatType) target.chatType = values.targetChatType;
|
|
7015
|
+
else delete target.chatType;
|
|
6998
7016
|
target.session = values.targetSessionStrategy;
|
|
6999
7017
|
if (values.targetSessionStrategy === 'thread') target.threadId = values.targetThreadId;
|
|
7000
7018
|
else delete target.threadId;
|
|
@@ -7068,6 +7086,9 @@ function collectTriggerEditPatch(ctx) {
|
|
|
7068
7086
|
if (feedbackStrategy === 'target') {
|
|
7069
7087
|
if (!values.targetChannel) return { error: t('triggers.error.channelRequired') };
|
|
7070
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
|
+
}
|
|
7071
7092
|
if (values.targetSessionStrategy === 'thread' && !values.targetThreadId) return { error: t('triggers.error.threadRequired') };
|
|
7072
7093
|
}
|
|
7073
7094
|
if (values.maxRuns) {
|
|
@@ -7213,6 +7234,7 @@ function openTriggerEditDrawer(id, agent) {
|
|
|
7213
7234
|
`<div id="trig-edit-target-fields" class="ag-edit-grid trig-edit-grid">` +
|
|
7214
7235
|
`<label class="ag-edit-field"><span>${t('triggers.field.targetChannel')}</span><select id="trig-edit-channel">${channelOptions}</select></label>` +
|
|
7215
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>` +
|
|
7216
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>` +
|
|
7217
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>` +
|
|
7218
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>
|