ec-web 0.0.20 → 0.0.21
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/server.js +117 -23
- package/dist/sources/aid.js +69 -49
- package/dist/sources/baseagent-detector.js +60 -6
- package/dist/sources/basic-settings.js +818 -0
- package/dist/sources/gateway.js +5 -4
- package/dist/sources/msg.js +4 -96
- package/dist/sources/relation-roles.js +150 -191
- package/dist/sources/role-definitions.js +138 -331
- package/dist/sources/session-codex.js +189 -78
- package/dist/sources/system.js +10 -9
- package/dist/sources/triggers.js +24 -13
- package/dist/sources/types.js +20 -1
- package/dist/static/app.js +83 -9
- package/dist/static/basic-settings.js +1576 -0
- package/dist/static/index.html +43 -1
- package/dist/static/style.css +586 -2
- package/ecweb-wrapper.cjs +5 -1
- package/package.json +1 -1
package/dist/static/app.js
CHANGED
|
@@ -92,6 +92,28 @@ const translations = {
|
|
|
92
92
|
'common.online': '在线',
|
|
93
93
|
'common.offline': '离线',
|
|
94
94
|
'common.ago': '前',
|
|
95
|
+
'basicSettings.open': '基础设置',
|
|
96
|
+
'basicSettings.openTitle': '打开基础设置',
|
|
97
|
+
'basicSettings.title': '基础设置',
|
|
98
|
+
'basicSettings.subtitle': '按用途组织参数。保存前会校验并保留未编辑字段。',
|
|
99
|
+
'basicSettings.reload': '重新读取',
|
|
100
|
+
'basicSettings.tabs.models': '模型与推理',
|
|
101
|
+
'basicSettings.tabs.modelsHint': '基座、模型与连接',
|
|
102
|
+
'basicSettings.tabs.response': '响应与会话',
|
|
103
|
+
'basicSettings.tabs.responseHint': '响应方式与续接',
|
|
104
|
+
'basicSettings.tabs.projects': '项目与服务',
|
|
105
|
+
'basicSettings.tabs.projectsHint': '路径与本机服务',
|
|
106
|
+
'basicSettings.tabs.identity': '身份与安全',
|
|
107
|
+
'basicSettings.tabs.identityHint': 'AID 与访问保护',
|
|
108
|
+
'basicSettings.tabs.runtime': '运行与诊断',
|
|
109
|
+
'basicSettings.tabs.runtimeHint': '日志与稳定性',
|
|
110
|
+
'basicSettings.noChanges': '没有需要保存的改动',
|
|
111
|
+
'basicSettings.viewJson': '查看 JSON',
|
|
112
|
+
'basicSettings.save': '保存设置',
|
|
113
|
+
'basicSettings.jsonTitle': '查看 JSON',
|
|
114
|
+
'basicSettings.jsonSubtitle': '只读预览,敏感值已脱敏。',
|
|
115
|
+
'basicSettings.daemonFile': 'daemon.json',
|
|
116
|
+
'basicSettings.defaultsFile': 'agents/defaults.json',
|
|
95
117
|
'theme.light': '浅色模式',
|
|
96
118
|
'theme.dark': '深色模式',
|
|
97
119
|
'theme.system': '跟随系统',
|
|
@@ -587,6 +609,8 @@ const translations = {
|
|
|
587
609
|
'triggers.history.field.payload': '事件数据',
|
|
588
610
|
'triggers.history.field.sessionId': '会话 ID',
|
|
589
611
|
'triggers.history.field.messageId': '消息 ID',
|
|
612
|
+
'triggers.history.field.operationId': '操作 ID',
|
|
613
|
+
'triggers.history.field.outboxId': 'Outbox ID',
|
|
590
614
|
'triggers.history.field.handoffId': 'Handoff ID',
|
|
591
615
|
'triggers.history.field.attempt': '尝试次数',
|
|
592
616
|
'triggers.history.field.triggerId': 'Trigger ID',
|
|
@@ -609,8 +633,9 @@ const translations = {
|
|
|
609
633
|
'triggers.history.outcome.error': '错误',
|
|
610
634
|
'triggers.history.outcome.interrupted': '已中断',
|
|
611
635
|
'triggers.history.outcome.timeout': '超时',
|
|
636
|
+
'triggers.history.outcome.queued': '已入队',
|
|
612
637
|
'triggers.history.effect.message.send': '发送消息',
|
|
613
|
-
'triggers.history.effect.handoff.enqueue': '
|
|
638
|
+
'triggers.history.effect.handoff.enqueue': 'Handoff 投递',
|
|
614
639
|
'triggers.history.effect.message.inbound': '注入目标会话',
|
|
615
640
|
'triggers.history.effect.agent.conversation': 'Agent 对话',
|
|
616
641
|
'triggers.runStatus.completed': '成功',
|
|
@@ -998,6 +1023,28 @@ const translations = {
|
|
|
998
1023
|
'common.online': 'Online',
|
|
999
1024
|
'common.offline': 'Offline',
|
|
1000
1025
|
'common.ago': 'ago',
|
|
1026
|
+
'basicSettings.open': 'Settings',
|
|
1027
|
+
'basicSettings.openTitle': 'Open basic settings',
|
|
1028
|
+
'basicSettings.title': 'Basic Settings',
|
|
1029
|
+
'basicSettings.subtitle': 'Settings organized by purpose. Saving validates changes and preserves untouched fields.',
|
|
1030
|
+
'basicSettings.reload': 'Reload',
|
|
1031
|
+
'basicSettings.tabs.models': 'Models & Reasoning',
|
|
1032
|
+
'basicSettings.tabs.modelsHint': 'Base Agents, models, connections',
|
|
1033
|
+
'basicSettings.tabs.response': 'Responses & Sessions',
|
|
1034
|
+
'basicSettings.tabs.responseHint': 'Delivery and renewal',
|
|
1035
|
+
'basicSettings.tabs.projects': 'Projects & Services',
|
|
1036
|
+
'basicSettings.tabs.projectsHint': 'Paths and local services',
|
|
1037
|
+
'basicSettings.tabs.identity': 'Identity & Security',
|
|
1038
|
+
'basicSettings.tabs.identityHint': 'AID and access protection',
|
|
1039
|
+
'basicSettings.tabs.runtime': 'Runtime & Diagnostics',
|
|
1040
|
+
'basicSettings.tabs.runtimeHint': 'Logs and stability',
|
|
1041
|
+
'basicSettings.noChanges': 'No unsaved changes',
|
|
1042
|
+
'basicSettings.viewJson': 'View JSON',
|
|
1043
|
+
'basicSettings.save': 'Save Settings',
|
|
1044
|
+
'basicSettings.jsonTitle': 'View JSON',
|
|
1045
|
+
'basicSettings.jsonSubtitle': 'Read-only preview with sensitive values redacted.',
|
|
1046
|
+
'basicSettings.daemonFile': 'daemon.json',
|
|
1047
|
+
'basicSettings.defaultsFile': 'agents/defaults.json',
|
|
1001
1048
|
'theme.light': 'Light',
|
|
1002
1049
|
'theme.dark': 'Dark',
|
|
1003
1050
|
'theme.system': 'System',
|
|
@@ -1493,6 +1540,8 @@ const translations = {
|
|
|
1493
1540
|
'triggers.history.field.payload': 'Event Data',
|
|
1494
1541
|
'triggers.history.field.sessionId': 'Session ID',
|
|
1495
1542
|
'triggers.history.field.messageId': 'Message ID',
|
|
1543
|
+
'triggers.history.field.operationId': 'Operation ID',
|
|
1544
|
+
'triggers.history.field.outboxId': 'Outbox ID',
|
|
1496
1545
|
'triggers.history.field.handoffId': 'Handoff ID',
|
|
1497
1546
|
'triggers.history.field.attempt': 'Attempts',
|
|
1498
1547
|
'triggers.history.field.triggerId': 'Trigger ID',
|
|
@@ -1515,8 +1564,9 @@ const translations = {
|
|
|
1515
1564
|
'triggers.history.outcome.error': 'Error',
|
|
1516
1565
|
'triggers.history.outcome.interrupted': 'Interrupted',
|
|
1517
1566
|
'triggers.history.outcome.timeout': 'Timeout',
|
|
1567
|
+
'triggers.history.outcome.queued': 'Queued',
|
|
1518
1568
|
'triggers.history.effect.message.send': 'Send Message',
|
|
1519
|
-
'triggers.history.effect.handoff.enqueue': '
|
|
1569
|
+
'triggers.history.effect.handoff.enqueue': 'Deliver Handoff',
|
|
1520
1570
|
'triggers.history.effect.message.inbound': 'Inject Target Session',
|
|
1521
1571
|
'triggers.history.effect.agent.conversation': 'Agent Conversation',
|
|
1522
1572
|
'triggers.runStatus.completed': 'Completed',
|
|
@@ -1857,6 +1907,7 @@ function updateI18n() {
|
|
|
1857
1907
|
// 更新 html lang 属性
|
|
1858
1908
|
document.documentElement.lang = currentLang;
|
|
1859
1909
|
updateThemeButton();
|
|
1910
|
+
window.refreshBasicSettingsI18n?.();
|
|
1860
1911
|
}
|
|
1861
1912
|
|
|
1862
1913
|
function toggleLang() {
|
|
@@ -1873,7 +1924,16 @@ function toggleLang() {
|
|
|
1873
1924
|
// 本地直连时页面在 "/",经 AUN Service Proxy 时页面在 "/ecweb/"。
|
|
1874
1925
|
// 取当前页面所在目录(含尾斜杠)作为所有 API/WS 的前缀,使绝对路径在两种
|
|
1875
1926
|
// 部署下都正确(proxy-server 用首段路径选服务,前缀不能丢)。
|
|
1876
|
-
const BASE =
|
|
1927
|
+
const BASE = (() => {
|
|
1928
|
+
const baseElement = document.querySelector('base[href]');
|
|
1929
|
+
if (baseElement) {
|
|
1930
|
+
try {
|
|
1931
|
+
const basePath = new URL(baseElement.href, location.href).pathname;
|
|
1932
|
+
return basePath.endsWith('/') ? basePath : `${basePath}/`;
|
|
1933
|
+
} catch {}
|
|
1934
|
+
}
|
|
1935
|
+
return location.pathname.replace(/[^/]*$/, '');
|
|
1936
|
+
})();
|
|
1877
1937
|
const apiUrl = (p) => BASE + p.replace(/^\/+/, '');
|
|
1878
1938
|
const authApiUrl = (p) => {
|
|
1879
1939
|
const token = localStorage.getItem(TOKEN_KEY);
|
|
@@ -5460,6 +5520,13 @@ const TRIGGER_EXECUTION_TYPES = [
|
|
|
5460
5520
|
];
|
|
5461
5521
|
const TRIGGER_EFFORTS = ['low', 'medium', 'high', 'xhigh', 'max'];
|
|
5462
5522
|
const TRIGGER_PERMISSION_MODES = ['readonly', 'auto', 'request', 'bypass'];
|
|
5523
|
+
function triggerPermissionModes(currentMode = '') {
|
|
5524
|
+
const modes = [...TRIGGER_PERMISSION_MODES];
|
|
5525
|
+
if ((state.triggers?.fullaccessEnabled === true
|
|
5526
|
+
&& state.triggers?.canApprovePersistentFullAccess === true)
|
|
5527
|
+
|| currentMode === 'fullaccess') modes.push('fullaccess');
|
|
5528
|
+
return modes;
|
|
5529
|
+
}
|
|
5463
5530
|
const TRIGGER_TARGET_SESSIONS = [
|
|
5464
5531
|
['main', () => t('triggers.session.main')],
|
|
5465
5532
|
['thread', () => t('triggers.session.thread')],
|
|
@@ -5581,8 +5648,9 @@ async function withTriggerOp(id, agent, label, fn) {
|
|
|
5581
5648
|
finally { setTriggerOp(id, agent, null); }
|
|
5582
5649
|
}
|
|
5583
5650
|
|
|
5584
|
-
function triggerOptionHtml(items, current, emptyLabel) {
|
|
5651
|
+
function triggerOptionHtml(items, current, emptyLabel, disabledValues = null) {
|
|
5585
5652
|
const selected = String(current || '');
|
|
5653
|
+
const disabled = disabledValues instanceof Set ? disabledValues : new Set(disabledValues || []);
|
|
5586
5654
|
let html = emptyLabel == null ? '' : `<option value=""${selected ? '' : ' selected'}>${esc(emptyLabel)}</option>`;
|
|
5587
5655
|
let seen = new Set();
|
|
5588
5656
|
for (const item of items) {
|
|
@@ -5591,10 +5659,10 @@ function triggerOptionHtml(items, current, emptyLabel) {
|
|
|
5591
5659
|
const label = typeof rawLabel === 'function' ? rawLabel() : String(rawLabel);
|
|
5592
5660
|
if (seen.has(value)) continue;
|
|
5593
5661
|
seen.add(value);
|
|
5594
|
-
html += `<option value="${esc(value)}"${value === selected ? ' selected' : ''}>${esc(label)}</option>`;
|
|
5662
|
+
html += `<option value="${esc(value)}"${value === selected ? ' selected' : ''}${disabled.has(value) ? ' disabled' : ''}>${esc(label)}</option>`;
|
|
5595
5663
|
}
|
|
5596
5664
|
if (selected && !seen.has(selected)) {
|
|
5597
|
-
html += `<option value="${esc(selected)}" selected>${esc(selected)} (${t('common.currentSuffix')})</option>`;
|
|
5665
|
+
html += `<option value="${esc(selected)}" selected${disabled.has(selected) ? ' disabled' : ''}>${esc(selected)} (${t('common.currentSuffix')})</option>`;
|
|
5598
5666
|
}
|
|
5599
5667
|
return html;
|
|
5600
5668
|
}
|
|
@@ -6216,7 +6284,9 @@ function triggerHistoryFieldLabel(path, context = '') {
|
|
|
6216
6284
|
channelType: t('triggers.th.channelType'),
|
|
6217
6285
|
channelId: t('triggers.field.channelId'),
|
|
6218
6286
|
sessionId: t('triggers.history.field.sessionId'),
|
|
6287
|
+
operationId: t('triggers.history.field.operationId'),
|
|
6219
6288
|
messageId: t('triggers.history.field.messageId'),
|
|
6289
|
+
outboxId: t('triggers.history.field.outboxId'),
|
|
6220
6290
|
handoffId: t('triggers.history.field.handoffId'),
|
|
6221
6291
|
attempt: t('triggers.history.field.attempt'),
|
|
6222
6292
|
startedAt: t('triggers.history.startedAt'),
|
|
@@ -6254,6 +6324,7 @@ function triggerHistoryFieldValue(path, value, context = '') {
|
|
|
6254
6324
|
}
|
|
6255
6325
|
if (context === 'effects' && path === 'status') {
|
|
6256
6326
|
if (value === 'success') return t('triggers.history.outcome.success');
|
|
6327
|
+
if (value === 'queued') return t('triggers.history.outcome.queued');
|
|
6257
6328
|
if (value === 'failed') return t('triggers.runStatus.failed');
|
|
6258
6329
|
if (value === 'skipped') return t('triggers.runStatus.skipped');
|
|
6259
6330
|
}
|
|
@@ -6368,7 +6439,7 @@ function triggerHistoryEffectsBlock(effects) {
|
|
|
6368
6439
|
'channelId',
|
|
6369
6440
|
...(Number(effect?.attempt) === 1 ? ['attempt'] : []),
|
|
6370
6441
|
],
|
|
6371
|
-
keyOrder: ['type', 'status', 'handoffId', 'sessionId'],
|
|
6442
|
+
keyOrder: ['type', 'status', 'messageId', 'outboxId', 'handoffId', 'sessionId', 'operationId'],
|
|
6372
6443
|
}) +
|
|
6373
6444
|
`</div>`,
|
|
6374
6445
|
).join('')}</div>`;
|
|
@@ -7280,7 +7351,7 @@ function openTriggerEditDrawer(id, agent) {
|
|
|
7280
7351
|
`<label class="ag-edit-field"><span>${t('triggers.field.executionType')}</span><select id="trig-edit-type">${triggerOptionHtml(TRIGGER_EXECUTION_TYPES, original.executionType, null)}</select></label>` +
|
|
7281
7352
|
`<label class="ag-edit-field trig-agent-field"><span>${t('triggers.field.model')}</span><select id="trig-edit-model">${agentSelectOptions([], original.model, t('common.inherited'))}</select></label>` +
|
|
7282
7353
|
`<label class="ag-edit-field trig-agent-field"><span>${t('triggers.field.effort')}</span><select id="trig-edit-effort">${agentSelectOptions([], original.effort, t('common.inherited'))}</select></label>` +
|
|
7283
|
-
`<label class="ag-edit-field trig-agent-field"><span>${t('triggers.field.permission')}</span><select id="trig-edit-permission">${triggerOptionHtml(
|
|
7354
|
+
`<label class="ag-edit-field trig-agent-field"><span>${t('triggers.field.permission')}</span><select id="trig-edit-permission">${triggerOptionHtml(triggerPermissionModes(original.permissionMode), original.permissionMode, t('common.inherited'), state.triggers?.canApprovePersistentFullAccess === true ? [] : ['fullaccess'])}</select></label>` +
|
|
7284
7355
|
`<label class="ag-edit-field trig-script-field"><span>${t('triggers.field.scriptRuntime')}</span><select id="trig-edit-script-runtime">${triggerOptionHtml(['node', 'python', 'bash'], original.scriptRuntime, null)}</select></label>` +
|
|
7285
7356
|
`<label class="ag-edit-field trig-script-field trig-script-path-field"><span>${t('triggers.field.scriptPath')}</span><input id="trig-edit-script-path" type="text" autocomplete="off" spellcheck="false" value="${esc(original.scriptPath)}" placeholder="${t('triggers.placeholder.scriptPath')}"></label>` +
|
|
7286
7357
|
`</div>` +
|
|
@@ -9063,6 +9134,7 @@ function roleSourceLabel(source) {
|
|
|
9063
9134
|
const labels = {
|
|
9064
9135
|
'relation-assigned': 'Explicit',
|
|
9065
9136
|
'group-member': 'Member override',
|
|
9137
|
+
'relation-actor': 'Private role',
|
|
9066
9138
|
'private-inherited': 'Private role',
|
|
9067
9139
|
'group-default': 'Group role',
|
|
9068
9140
|
default: 'Default',
|
|
@@ -9092,7 +9164,9 @@ function assignedRoleFor(scope, item) {
|
|
|
9092
9164
|
if (!item) return '';
|
|
9093
9165
|
if (scope === 'private') return item.source === 'relation-assigned' ? (item.assignment?.role || item.role || '') : '';
|
|
9094
9166
|
if (scope === 'group') return item.source === 'relation-assigned' ? (item.assignment?.role || item.role || '') : '';
|
|
9095
|
-
return item.source === 'group-member'
|
|
9167
|
+
return item.source === 'group-member' || item.source === 'relation-actor'
|
|
9168
|
+
? (item.assignment?.role || item.role || '')
|
|
9169
|
+
: '';
|
|
9096
9170
|
}
|
|
9097
9171
|
|
|
9098
9172
|
function assignableRolesForAgent(agentAid) {
|