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.
@@ -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': '创建 Handoff',
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': 'Create Handoff',
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 = location.pathname.replace(/[^/]*$/, '');
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(TRIGGER_PERMISSION_MODES, original.permissionMode, t('common.inherited'))}</select></label>` +
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' ? (item.assignment?.role || item.role || '') : '';
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) {