@auto-ai/agent 2.1.221 → 2.1.222

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.
Files changed (41) hide show
  1. package/dist/safe-a/404/index.html +1 -1
  2. package/dist/safe-a/404.html +1 -1
  3. package/dist/safe-a/index.html +2 -2
  4. package/dist/safe-a/index.txt +1 -1
  5. package/dist/safe-a/manage/about/index.html +2 -2
  6. package/dist/safe-a/manage/about/index.txt +1 -1
  7. package/dist/safe-a/manage/env/index.html +2 -2
  8. package/dist/safe-a/manage/env/index.txt +1 -1
  9. package/dist/safe-a/manage/geelib/index.html +2 -2
  10. package/dist/safe-a/manage/geelib/index.txt +1 -1
  11. package/dist/safe-a/manage/general/index.html +2 -2
  12. package/dist/safe-a/manage/general/index.txt +1 -1
  13. package/dist/safe-a/manage/git/index.html +2 -2
  14. package/dist/safe-a/manage/git/index.txt +1 -1
  15. package/dist/safe-a/manage/im/index.html +2 -2
  16. package/dist/safe-a/manage/im/index.txt +1 -1
  17. package/dist/safe-a/manage/index.html +2 -2
  18. package/dist/safe-a/manage/index.txt +1 -1
  19. package/dist/safe-a/manage/library/index.html +2 -2
  20. package/dist/safe-a/manage/library/index.txt +1 -1
  21. package/dist/safe-a/manage/mcp/index.html +2 -2
  22. package/dist/safe-a/manage/mcp/index.txt +1 -1
  23. package/dist/safe-a/manage/permissions/index.html +2 -2
  24. package/dist/safe-a/manage/permissions/index.txt +1 -1
  25. package/dist/safe-a/manage/skills/index.html +2 -2
  26. package/dist/safe-a/manage/skills/index.txt +1 -1
  27. package/dist/safe-a/manage/task/index.html +2 -2
  28. package/dist/safe-a/manage/task/index.txt +1 -1
  29. package/dist/safe-a/manage/teams/index.html +2 -2
  30. package/dist/safe-a/manage/teams/index.txt +1 -1
  31. package/dist/safe-a/manage/tools/index.html +2 -2
  32. package/dist/safe-a/manage/tools/index.txt +1 -1
  33. package/dist/ws-test/agent-teams.html +1400 -0
  34. package/dist/ws-test/team-chat.js +760 -0
  35. package/dist/ws-test/ws-test.css +613 -6
  36. package/dist/ws-test/ws-test.html +23 -7
  37. package/dist/ws-test/ws-test.js +232 -85
  38. package/package.json +6 -6
  39. /package/dist/safe-a/_next/static/{1lVS2YCkhJeMjvIi_ropq → O9azldpveh8Nr32O4nBb7}/_buildManifest.js +0 -0
  40. /package/dist/safe-a/_next/static/{1lVS2YCkhJeMjvIi_ropq → O9azldpveh8Nr32O4nBb7}/_clientMiddlewareManifest.json +0 -0
  41. /package/dist/safe-a/_next/static/{1lVS2YCkhJeMjvIi_ropq → O9azldpveh8Nr32O4nBb7}/_ssgManifest.js +0 -0
@@ -81,14 +81,14 @@
81
81
  </svg>
82
82
  <span>定时任务</span>
83
83
  </button>
84
- <button type="button" class="sidebar-nav-row" data-add="agentTeams" title="Teams" aria-label="Teams">
84
+ <button type="button" class="sidebar-nav-row" data-add="agentTeams" title="团队" aria-label="团队">
85
85
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
86
86
  <circle cx="8" cy="8" r="2.8"/>
87
87
  <circle cx="16.2" cy="9.2" r="2.4"/>
88
88
  <path d="M3.2 18c.8-2.7 2.8-4.2 4.8-4.2s4 1.5 4.8 4.2"/>
89
89
  <path d="M13.2 18c.6-2 2.2-3.2 4-3.2 1.6 0 3.1 1 3.8 2.7"/>
90
90
  </svg>
91
- <span>Teams</span>
91
+ <span>团队</span>
92
92
  </button>
93
93
  <button type="button" class="sidebar-nav-row" id="btnManageRepo" data-add="repo" title="文件管理" aria-label="文件管理">
94
94
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
@@ -165,16 +165,13 @@
165
165
  </div>
166
166
  <div id="pickerManageView" class="picker-manage-view" hidden>
167
167
  <div class="picker-manage-layout">
168
- <aside id="pickerNavPanel" class="picker-nav-panel" aria-label="分类导航">
169
- <div class="picker-nav-title">分类</div>
170
- <nav id="pickerNavList" class="picker-nav-list" role="tablist"></nav>
171
- </aside>
172
168
  <section class="picker-content-panel">
173
169
  <div class="manage-view-head picker-manage-head">
174
170
  <input type="search" id="pickerSearch" class="picker-search" placeholder="筛选…" />
175
171
  <div class="manage-head-actions">
176
172
  <button type="button" class="btn-manage-head-action" id="btnPickerMcpJson" hidden>编辑 JSON</button>
177
173
  <button type="button" class="btn-manage-head-action" id="btnPickerImport" hidden>导入</button>
174
+ <button type="button" class="btn-manage-head-action" id="btnPickerSkillStore" hidden>skill商店</button>
178
175
  <button type="button" class="btn-manage-head-action" id="btnPickerCancel">取消</button>
179
176
  <button type="button" class="btn-primary" id="btnPickerSave">保存</button>
180
177
  </div>
@@ -186,7 +183,6 @@
186
183
  </thead>
187
184
  <tbody id="pickerEntriesBody"></tbody>
188
185
  </table>
189
- <div id="pickerCloudPanel" class="picker-cloud-panel" hidden></div>
190
186
  <div id="pickerContentState" class="picker-panel-state" hidden></div>
191
187
  </div>
192
188
  <input type="file" id="pickerImportInput" accept=".zip,application/zip" hidden />
@@ -637,6 +633,26 @@
637
633
  </div>
638
634
  </div>
639
635
 
636
+ <div id="skillStoreModal" class="agent-md-modal" aria-hidden="true">
637
+ <div class="agent-md-modal-backdrop" id="skillStoreModalBackdrop"></div>
638
+ <div class="agent-md-modal-card modal-unified" role="dialog" aria-modal="true" aria-labelledby="skillStoreModalTitle">
639
+ <div class="agent-md-modal-head">
640
+ <h2 id="skillStoreModalTitle">skill商店</h2>
641
+ <div class="modal-head-actions modal-head-actions--close-only">
642
+ <button type="button" class="agent-md-modal-close" id="btnSkillStoreModalClose" aria-label="关闭">
643
+ &times;
644
+ </button>
645
+ </div>
646
+ </div>
647
+ <div class="tool-files-body skill-store-modal-body">
648
+ <div id="skillStoreModalBody" class="picker-cloud-panel"></div>
649
+ </div>
650
+ <div class="agent-md-modal-foot">
651
+ <button type="button" class="btn-agent-md-cancel" id="btnSkillStoreClose">关闭</button>
652
+ </div>
653
+ </div>
654
+ </div>
655
+
640
656
  <div id="skillPackageModal" class="agent-md-modal" aria-hidden="true">
641
657
  <div class="agent-md-modal-backdrop" id="skillPackageModalBackdrop"></div>
642
658
  <div class="agent-md-modal-card modal-unified" role="dialog" aria-modal="true" aria-labelledby="skillPackageModalTitle">
@@ -167,6 +167,63 @@
167
167
  const mcpPackageImportInput = $('mcpPackageImportInput')
168
168
  const sessionListEl = $('sessionList')
169
169
  const sessionListMetaEl = $('sessionListMeta')
170
+ /** 侧栏会话来源:ws / tuitui / geelib / team / legacy */
171
+ var SESSION_KIND_LABELS = {
172
+ ws: '网页',
173
+ tuitui: '推推',
174
+ geelib: 'GeeLib',
175
+ team: '群聊',
176
+ legacy: '会话',
177
+ }
178
+ function resolveSessionKindForItem(s) {
179
+ if (!s || typeof s !== 'object') return 'ws'
180
+ var kind = s.sessionKind
181
+ if (kind && SESSION_KIND_LABELS[kind]) return kind
182
+ if (kind === 'user') return 'ws'
183
+ var sid = typeof s.sessionId === 'string' ? s.sessionId : ''
184
+ if (sid.indexOf('team-') === 0) return 'team'
185
+ if (sid.indexOf('tuitui-') === 0) return 'tuitui'
186
+ if (sid.indexOf('geelib-') === 0) return 'geelib'
187
+ if (sid.indexOf('ws-') === 0) return 'ws'
188
+ return 'legacy'
189
+ }
190
+ var SESSION_KIND_ICON_SVG = {
191
+ ws:
192
+ '<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">' +
193
+ '<rect x="3" y="4" width="18" height="14" rx="2"/>' +
194
+ '<path d="M8 20h8"/>' +
195
+ '</svg>',
196
+ tuitui:
197
+ '<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">' +
198
+ '<path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/>' +
199
+ '<path d="M13.73 21a2 2 0 0 1-3.46 0"/>' +
200
+ '</svg>',
201
+ geelib:
202
+ '<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">' +
203
+ '<path d="M4 4h16v16H4z"/>' +
204
+ '<path d="M4 9h16M9 4v16"/>' +
205
+ '</svg>',
206
+ team:
207
+ '<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">' +
208
+ '<circle cx="8" cy="8" r="2.8"/>' +
209
+ '<circle cx="16.2" cy="9.2" r="2.4"/>' +
210
+ '<path d="M3.2 18c.8-2.7 2.8-4.2 4.8-4.2s4 1.5 4.8 4.2"/>' +
211
+ '<path d="M13.2 18c.6-2 2.2-3.2 4-3.2 1.6 0 3.1 1 3.8 2.7"/>' +
212
+ '</svg>',
213
+ legacy:
214
+ '<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">' +
215
+ '<path d="M21 11.5a8.4 8.4 0 0 1-9 8.4 8.4 8.4 0 0 1-3.8-.9L3 20l1.9-5.2A8.4 8.4 0 1 1 21 11.5z"/>' +
216
+ '</svg>',
217
+ }
218
+ function createSessionKindIcon(kind) {
219
+ var resolved = SESSION_KIND_LABELS[kind] ? kind : 'ws'
220
+ var icon = document.createElement('span')
221
+ icon.className = 'sidebar-session-kind-icon sidebar-session-kind-icon--' + resolved
222
+ icon.setAttribute('aria-hidden', 'true')
223
+ icon.title = SESSION_KIND_LABELS[resolved]
224
+ icon.innerHTML = SESSION_KIND_ICON_SVG[resolved]
225
+ return icon
226
+ }
170
227
  /** 侧栏会话列表运行时状态轮询定时器 */
171
228
  let sessionRuntimePollTimer = null
172
229
  /** 当前附着 session 的 turn 是否进行中(由 query.progress 驱动) */
@@ -280,18 +337,21 @@
280
337
  const composerToolAskSelect = $('composerToolAskSelect')
281
338
  const btnSaveAgentConfig = $('btnSaveAgentConfig')
282
339
  const pickerManageView = $('pickerManageView')
283
- const pickerNavPanel = $('pickerNavPanel')
284
- const pickerNavList = $('pickerNavList')
285
340
  const pickerSearch = $('pickerSearch')
286
341
  const btnPickerMcpJson = $('btnPickerMcpJson')
287
342
  const btnPickerImport = $('btnPickerImport')
343
+ const btnPickerSkillStore = $('btnPickerSkillStore')
288
344
  const btnPickerCancel = $('btnPickerCancel')
289
345
  const btnPickerSave = $('btnPickerSave')
290
346
  const pickerEntriesTable = $('pickerEntriesTable')
291
347
  const pickerTableHeadRow = $('pickerTableHeadRow')
292
348
  const pickerEntriesBody = $('pickerEntriesBody')
293
- const pickerCloudPanel = $('pickerCloudPanel')
294
349
  const pickerContentState = $('pickerContentState')
350
+ const skillStoreModal = $('skillStoreModal')
351
+ const skillStoreModalBackdrop = $('skillStoreModalBackdrop')
352
+ const skillStoreModalBody = $('skillStoreModalBody')
353
+ const btnSkillStoreModalClose = $('btnSkillStoreModalClose')
354
+ const btnSkillStoreClose = $('btnSkillStoreClose')
295
355
  const pickerImportInput = $('pickerImportInput')
296
356
  const mcpJsonInputModal = $('mcpJsonInputModal')
297
357
  const mcpJsonInputModalBackdrop = $('mcpJsonInputModalBackdrop')
@@ -362,6 +422,7 @@
362
422
  let refreshToolPickerRows = null
363
423
  let refreshMcpPickerRows = null
364
424
  let refreshSkillPickerRows = null
425
+ let openSkillStoreModalFn = null
365
426
  let pickerRenderContent = null
366
427
  let remoteMcpServers = []
367
428
  const WS_PERMISSION_MODE_KEY = 'WS_PERMISSION_MODE'
@@ -769,6 +830,7 @@
769
830
  source: source,
770
831
  runId: runId,
771
832
  correlationId: correlationId,
833
+ turnId: typeof item.turnId === 'string' ? item.turnId : '',
772
834
  text: body,
773
835
  status: status,
774
836
  scheduledTrigger: item.scheduledTrigger === true,
@@ -1502,6 +1564,84 @@
1502
1564
  bodyEl.insertAdjacentElement('afterend', btn)
1503
1565
  }
1504
1566
 
1567
+ /**
1568
+ * 业务语义:HTTP 回放/初始化 turnId 为 replay|init,需按 user 消息再切分;
1569
+ * 实时 turn 每轮 prompt 有独立 UUID turnId,直接按 turnId 分组。
1570
+ */
1571
+ function shouldSplitTurnOnUserMessage(turnId) {
1572
+ const tid = typeof turnId === 'string' ? turnId.trim() : ''
1573
+ return !tid || tid === 'replay' || tid === 'init'
1574
+ }
1575
+
1576
+ function isRealUserPromptMessage(m) {
1577
+ if (!m || m.type !== 'user') return false
1578
+ if (!shouldShowWsUserMessage(m)) return false
1579
+ const blocks = getMessageContentBlocks(m)
1580
+ const nonToolBlocks = blocks.filter(function (b) {
1581
+ return b && b.type !== 'tool_result'
1582
+ })
1583
+ if (nonToolBlocks.length === 0) return false
1584
+ const rawBody = contentToPlainText(nonToolBlocks).trim()
1585
+ return !!unwrapChannelWrappedText(rawBody).body.trim()
1586
+ }
1587
+
1588
+ function isTimelineUserTurnStart(ev) {
1589
+ if (!ev || ev.kind !== 'conversation') return false
1590
+ const item = ev.payload
1591
+ const m = item && item.message
1592
+ return isRealUserPromptMessage(m)
1593
+ }
1594
+
1595
+ function isToolResultOnlyEvent(ev) {
1596
+ if (!ev || ev.kind !== 'conversation') return false
1597
+ const m = ev.payload && ev.payload.message
1598
+ if (!m || m.type !== 'user') return false
1599
+ const blocks = getMessageContentBlocks(m)
1600
+ if (!blocks.length) return false
1601
+ return blocks.every(function (b) {
1602
+ return b && b.type === 'tool_result'
1603
+ })
1604
+ }
1605
+
1606
+ function coalesceToolResultTurns(turns) {
1607
+ for (let i = 1; i < turns.length; i++) {
1608
+ const turn = turns[i]
1609
+ if (turn.items.length > 0 && turn.items.every(isToolResultOnlyEvent)) {
1610
+ turns[i - 1].items.push.apply(turns[i - 1].items, turn.items)
1611
+ turns.splice(i, 1)
1612
+ i -= 1
1613
+ }
1614
+ }
1615
+ return turns
1616
+ }
1617
+
1618
+ function groupItemsByTurn(blockItems) {
1619
+ const turns = []
1620
+ for (let i = 0; i < blockItems.length; i++) {
1621
+ const ev = blockItems[i]
1622
+ const turnId = typeof ev.turnId === 'string' ? ev.turnId.trim() : ''
1623
+ const splitOnUser = shouldSplitTurnOnUserMessage(turnId)
1624
+ const isUserStart = splitOnUser && isTimelineUserTurnStart(ev)
1625
+ let targetTurn = turns.length > 0 ? turns[turns.length - 1] : null
1626
+
1627
+ if (splitOnUser) {
1628
+ if (isUserStart || !targetTurn) {
1629
+ targetTurn = { turnId: turnId || 'unknown', items: [] }
1630
+ turns.push(targetTurn)
1631
+ }
1632
+ targetTurn.items.push(ev)
1633
+ continue
1634
+ }
1635
+
1636
+ if (!targetTurn || targetTurn.turnId !== turnId) {
1637
+ targetTurn = { turnId: turnId, items: [] }
1638
+ turns.push(targetTurn)
1639
+ }
1640
+ targetTurn.items.push(ev)
1641
+ }
1642
+ return coalesceToolResultTurns(turns)
1643
+ }
1644
+
1505
1645
  function renderChat() {
1506
1646
  /**
1507
1647
  * 业务语义:run 折叠头需要展示“最后一条消息前三行”预览。
@@ -1716,6 +1856,7 @@
1716
1856
  Number.isInteger(item.arrivalSeq) ? item.arrivalSeq : Number.MAX_SAFE_INTEGER,
1717
1857
  fallbackOrder: timelineFallbackOrder++,
1718
1858
  runId: runId,
1859
+ turnId: typeof item.turnId === 'string' ? item.turnId : '',
1719
1860
  sourceAgent: resolveRunDisplayAgent(runId, item.sourceAgent),
1720
1861
  scheduledTrigger: item.scheduledTrigger === true,
1721
1862
  kind: 'conversation',
@@ -1736,6 +1877,7 @@
1736
1877
  Number.isInteger(item.arrivalSeq) ? item.arrivalSeq : Number.MAX_SAFE_INTEGER,
1737
1878
  fallbackOrder: timelineFallbackOrder++,
1738
1879
  runId: rid,
1880
+ turnId: typeof item.turnId === 'string' ? item.turnId : '',
1739
1881
  sourceAgent: resolveRunDisplayAgent(rid, item.source),
1740
1882
  scheduledTrigger: item.scheduledTrigger === true,
1741
1883
  kind: 'source',
@@ -1824,16 +1966,24 @@
1824
1966
  const groupContainer = document.createElement('div')
1825
1967
  groupContainer.className = 'chat-run-group' + (blockAllScheduled ? ' chat-run-group--scheduled' : '')
1826
1968
  if (runId === 'main') {
1827
- const fixedHeader = document.createElement('div')
1828
- fixedHeader.className = 'chat-msg-label'
1829
- fixedHeader.textContent = blockAllScheduled
1830
- ? '⏱ 定时任务 · ' + summaryText
1831
- : summaryText
1832
- groupContainer.appendChild(fixedHeader)
1833
- const groupBody = document.createElement('div')
1834
- groupBody.className = 'chat-run-group-body'
1835
- appendRunItemsToContainer(groupBody, blockItems, runId, defaultSourceAgent)
1836
- groupContainer.appendChild(groupBody)
1969
+ groupContainer.classList.add('chat-run-group--main')
1970
+ const turnGroups = groupItemsByTurn(blockItems)
1971
+ for (let t = 0; t < turnGroups.length; t++) {
1972
+ const turn = turnGroups[t]
1973
+ if (!turn.items.length) continue
1974
+ const isLastTurn = t === turnGroups.length - 1
1975
+ const isActiveTurn = isLastTurn && sessionTurnActive
1976
+ const turnSection = document.createElement('section')
1977
+ turnSection.className =
1978
+ 'chat-turn' +
1979
+ (isActiveTurn ? ' chat-turn--active' : '') +
1980
+ (blockAllScheduled ? ' chat-turn--scheduled' : '')
1981
+ const turnBody = document.createElement('div')
1982
+ turnBody.className = 'chat-turn-body'
1983
+ appendRunItemsToContainer(turnBody, turn.items, runId, defaultSourceAgent)
1984
+ turnSection.appendChild(turnBody)
1985
+ groupContainer.appendChild(turnSection)
1986
+ }
1837
1987
  } else {
1838
1988
  const summaryCard = document.createElement('div')
1839
1989
  summaryCard.className =
@@ -1867,9 +2017,12 @@
1867
2017
  chatThreadEl.appendChild(groupContainer)
1868
2018
  }
1869
2019
  if (pendingUserEcho) {
1870
- const echoWrap = document.createElement('div')
1871
- echoWrap.className = 'chat-run-group chat-run-group--pending-echo'
1872
- appendPendingUserEchoToContainer(echoWrap)
2020
+ const echoWrap = document.createElement('section')
2021
+ echoWrap.className = 'chat-turn chat-turn--active chat-turn--pending-echo'
2022
+ const echoBody = document.createElement('div')
2023
+ echoBody.className = 'chat-turn-body'
2024
+ appendPendingUserEchoToContainer(echoBody)
2025
+ echoWrap.appendChild(echoBody)
1873
2026
  chatThreadEl.appendChild(echoWrap)
1874
2027
  }
1875
2028
  if (streamEntries.length > 0) {
@@ -2165,6 +2318,7 @@
2165
2318
  const runMessage = {
2166
2319
  message: msg,
2167
2320
  sourceAgent: sourceAgent,
2321
+ turnId: typeof data.turnId === 'string' ? data.turnId : '',
2168
2322
  scheduledTrigger: payload.scheduledTrigger === true,
2169
2323
  ts:
2170
2324
  typeof data.ts === 'string' && data.ts
@@ -2207,6 +2361,7 @@
2207
2361
  source: source,
2208
2362
  runId: runId,
2209
2363
  correlationId: corr,
2364
+ turnId: typeof data.turnId === 'string' ? data.turnId : '',
2210
2365
  status: payload.status === 'resolved' ? 'resolved' : 'failed',
2211
2366
  text: text,
2212
2367
  scheduledTrigger: payload.scheduledTrigger === true,
@@ -2288,6 +2443,7 @@
2288
2443
  source: source,
2289
2444
  runId: runId,
2290
2445
  correlationId: '',
2446
+ turnId: typeof data.turnId === 'string' ? data.turnId : '',
2291
2447
  status: type === 'session.error' ? 'failed' : 'resolved',
2292
2448
  text: payloadText,
2293
2449
  key: typeof data.eventId === 'string' ? data.eventId : '',
@@ -2369,6 +2525,7 @@
2369
2525
  }
2370
2526
  void loadSessions({ silent: true })
2371
2527
  }
2528
+ requestRenderChat()
2372
2529
  return true
2373
2530
  }
2374
2531
  if (type === 'session.error') {
@@ -3344,12 +3501,10 @@
3344
3501
  return (pickerSearch && pickerSearch.value.trim().toLowerCase()) || ''
3345
3502
  }
3346
3503
 
3347
- /** 切换表格与云端面板显示 */
3348
- function setPickerContentMode(mode) {
3349
- const isCloud = mode === 'cloud'
3350
- if (pickerEntriesTable) pickerEntriesTable.hidden = isCloud
3351
- if (pickerCloudPanel) pickerCloudPanel.hidden = !isCloud
3352
- if (!isCloud && pickerContentState) {
3504
+ /** 切换 Picker 内容为表格模式 */
3505
+ function setPickerContentMode() {
3506
+ if (pickerEntriesTable) pickerEntriesTable.hidden = false
3507
+ if (pickerContentState) {
3353
3508
  pickerContentState.hidden = true
3354
3509
  pickerContentState.textContent = ''
3355
3510
  }
@@ -3396,34 +3551,6 @@
3396
3551
  return td
3397
3552
  }
3398
3553
 
3399
- /** 控制 Picker 左侧分类栏显隐(仅 Skill 页保留分类,其余合并为单表) */
3400
- function setPickerNavPanelVisible(visible) {
3401
- if (!pickerNavPanel) return
3402
- pickerNavPanel.hidden = !visible
3403
- if (!visible && pickerNavList) pickerNavList.innerHTML = ''
3404
- }
3405
-
3406
- /** 渲染 Picker 左侧分类导航 */
3407
- function renderPickerNavTabs(tabDefs, activeId, onChange) {
3408
- if (!pickerNavList) return
3409
- pickerNavList.innerHTML = ''
3410
- pickerManageState.activeTab = activeId
3411
- for (let i = 0; i < tabDefs.length; i++) {
3412
- const tab = tabDefs[i]
3413
- const btn = document.createElement('button')
3414
- btn.type = 'button'
3415
- btn.className = 'picker-nav-item' + (tab.id === activeId ? ' is-selected' : '')
3416
- btn.setAttribute('role', 'tab')
3417
- btn.setAttribute('aria-selected', tab.id === activeId ? 'true' : 'false')
3418
- btn.textContent = tab.label
3419
- btn.addEventListener('click', function () {
3420
- if (tab.id === activeId) return
3421
- onChange(tab.id)
3422
- })
3423
- pickerNavList.appendChild(btn)
3424
- }
3425
- }
3426
-
3427
3554
  /** 设置 entries/history 面板加载或错误态 */
3428
3555
  function setRepoPanelState(el, message, isError) {
3429
3556
  if (!el) return
@@ -4981,6 +5108,13 @@
4981
5108
  skillPackageModal.setAttribute('aria-hidden', 'true')
4982
5109
  document.body.style.overflow = ''
4983
5110
  }
5111
+
5112
+ function closeSkillStoreModal() {
5113
+ if (!skillStoreModal) return
5114
+ skillStoreModal.classList.remove('is-open')
5115
+ skillStoreModal.setAttribute('aria-hidden', 'true')
5116
+ document.body.style.overflow = ''
5117
+ }
4984
5118
  function closeRunGroupModal() {
4985
5119
  if (!runGroupModal) return
4986
5120
  runGroupModal.classList.remove('is-open')
@@ -5525,7 +5659,7 @@
5525
5659
  if (!list.length) {
5526
5660
  const empty = document.createElement('span')
5527
5661
  empty.className = 'session-tabs-empty'
5528
- empty.textContent = '暂无历史会话'
5662
+ empty.textContent = '暂无会话'
5529
5663
  sessionListEl.appendChild(empty)
5530
5664
  return
5531
5665
  }
@@ -5551,6 +5685,7 @@
5551
5685
  const mainBtn = document.createElement('button')
5552
5686
  mainBtn.type = 'button'
5553
5687
  mainBtn.className = 'sidebar-session-main'
5688
+ mainBtn.appendChild(createSessionKindIcon(resolveSessionKindForItem(s)))
5554
5689
  if (isRunning) {
5555
5690
  const runBadge = document.createElement('span')
5556
5691
  runBadge.className = 'sidebar-session-running-badge'
@@ -7490,15 +7625,18 @@
7490
7625
  kind === 'mcp' ? '导入 MCP' : kind === 'skills' ? '导入 Skill' : '导入 zip'
7491
7626
  btnPickerImport.disabled = false
7492
7627
  }
7628
+ if (btnPickerSkillStore) {
7629
+ btnPickerSkillStore.hidden = kind !== 'skills'
7630
+ btnPickerSkillStore.disabled = false
7631
+ }
7493
7632
  if (btnPickerMcpJson) {
7494
7633
  btnPickerMcpJson.hidden = kind !== 'mcp'
7495
7634
  btnPickerMcpJson.disabled = false
7496
7635
  }
7497
7636
  if (btnPickerCancel) btnPickerCancel.hidden = kind === 'skills' || kind === 'mcp'
7498
7637
  if (btnPickerSave) btnPickerSave.hidden = kind === 'skills' || kind === 'mcp'
7499
- setPickerNavPanelVisible(kind === 'skills')
7500
7638
  setPickerContentState('加载中…', false)
7501
- setPickerContentMode('table')
7639
+ setPickerContentMode()
7502
7640
  clearPickerTableBody()
7503
7641
 
7504
7642
  if (kind === 'tools') {
@@ -7623,7 +7761,7 @@
7623
7761
  return tr
7624
7762
  }
7625
7763
  const renderToolsRows = function () {
7626
- setPickerContentMode('table')
7764
+ setPickerContentMode()
7627
7765
  setPickerTableHead(['名称', '类型', '详细信息', '操作'])
7628
7766
  clearPickerTableBody()
7629
7767
  setPickerContentState('', false)
@@ -7797,7 +7935,7 @@
7797
7935
  return tr
7798
7936
  }
7799
7937
  const renderMcpRows = function () {
7800
- setPickerContentMode('table')
7938
+ setPickerContentMode()
7801
7939
  setPickerTableHead(['名称', '来源', '操作'])
7802
7940
  clearPickerTableBody()
7803
7941
  setPickerContentState('', false)
@@ -7898,7 +8036,7 @@
7898
8036
  return (tags.length ? tags.join(' ') : '—') + (summary ? ' — ' + summary : '')
7899
8037
  }
7900
8038
  const renderAgentTeamsRows = function () {
7901
- setPickerContentMode('table')
8039
+ setPickerContentMode()
7902
8040
  setPickerTableHead(['成员', '配置', '操作'])
7903
8041
  clearPickerTableBody()
7904
8042
  setPickerContentState('', false)
@@ -7951,7 +8089,6 @@
7951
8089
  })
7952
8090
  } else {
7953
8091
  const skillPickerState = {
7954
- activeTab: 'list',
7955
8092
  baseRows: [],
7956
8093
  installedRows: [],
7957
8094
  cloudRows: [],
@@ -8065,8 +8202,8 @@
8065
8202
  return tr
8066
8203
  }
8067
8204
  const renderCloudSkillPanel = function () {
8068
- if (!pickerCloudPanel) return
8069
- pickerCloudPanel.innerHTML = ''
8205
+ if (!skillStoreModalBody) return
8206
+ skillStoreModalBody.innerHTML = ''
8070
8207
  const cloudSearch = document.createElement('input')
8071
8208
  cloudSearch.type = 'search'
8072
8209
  cloudSearch.className = 'agent-picker-cloud-search'
@@ -8077,13 +8214,13 @@
8077
8214
  skillPickerState.cloudPage = 1
8078
8215
  void loadCloudSkillRows()
8079
8216
  }
8080
- pickerCloudPanel.appendChild(cloudSearch)
8217
+ skillStoreModalBody.appendChild(cloudSearch)
8081
8218
  const meta = document.createElement('div')
8082
8219
  meta.className = 'agent-picker-cloud-meta'
8083
8220
  if (skillPickerState.cloudLoading) meta.textContent = '加载中…'
8084
8221
  else if (skillPickerState.cloudError) meta.textContent = '加载失败:' + skillPickerState.cloudError
8085
8222
  else meta.textContent = '展示前 ' + skillPickerState.cloudRows.length + ' 项'
8086
- pickerCloudPanel.appendChild(meta)
8223
+ skillStoreModalBody.appendChild(meta)
8087
8224
  if (!skillPickerState.cloudError && skillPickerState.cloudRows.length) {
8088
8225
  for (let i = 0; i < skillPickerState.cloudRows.length; i++) {
8089
8226
  const item = skillPickerState.cloudRows[i]
@@ -8101,7 +8238,7 @@
8101
8238
  installing ? '处理中…' : installed ? '卸载' : '安装', '', function () {
8102
8239
  if (installBtn.disabled) return
8103
8240
  skillPickerState.installingMap[item.id] = true
8104
- renderSkillRows()
8241
+ renderCloudSkillPanel()
8105
8242
  const request = installed
8106
8243
  ? fetch(buildRuntimeSkillDeleteUrl(item.packageId), { method: 'DELETE' })
8107
8244
  : fetch(buildCloudSkillInstallUrl(), {
@@ -8119,21 +8256,23 @@
8119
8256
  else pickerSelected.add(item.skillName || item.id)
8120
8257
  setStatus('云端技能已' + (installed ? '卸载' : '安装') + ':' + item.title, serverReady ? 'ready' : '')
8121
8258
  return persistSkillSelectionNow().then(function () {
8122
- return refreshSkillPickerRows()
8259
+ return refreshSkillPickerRows().then(function () {
8260
+ return loadCloudSkillRows()
8261
+ })
8123
8262
  })
8124
8263
  })
8125
8264
  .catch(function (e) { window.alert((installed ? '卸载' : '安装') + '失败: ' + e) })
8126
8265
  .finally(function () {
8127
8266
  delete skillPickerState.installingMap[item.id]
8128
- renderSkillRows()
8267
+ renderCloudSkillPanel()
8129
8268
  })
8130
8269
  }, { disabled: installing },
8131
8270
  )
8132
8271
  actions.appendChild(installBtn)
8133
8272
  row.appendChild(actions)
8134
- pickerCloudPanel.appendChild(row)
8273
+ skillStoreModalBody.appendChild(row)
8135
8274
  }
8136
- pickerCloudPanel.appendChild(createCloudPager({
8275
+ skillStoreModalBody.appendChild(createCloudPager({
8137
8276
  page: skillPickerState.cloudPage,
8138
8277
  totalPages: skillPickerState.cloudTotalPages,
8139
8278
  loading: skillPickerState.cloudLoading,
@@ -8145,24 +8284,11 @@
8145
8284
  const empty = document.createElement('div')
8146
8285
  empty.className = 'agent-picker-empty'
8147
8286
  empty.textContent = skillPickerState.cloudLoading ? '(技能商店加载中)' : '(无匹配项)'
8148
- pickerCloudPanel.appendChild(empty)
8287
+ skillStoreModalBody.appendChild(empty)
8149
8288
  }
8150
8289
  }
8151
8290
  const renderSkillRows = function () {
8152
- renderPickerNavTabs(
8153
- [
8154
- { id: 'list', label: 'Skill' },
8155
- { id: 'cloud', label: 'skill商店' },
8156
- ],
8157
- skillPickerState.activeTab,
8158
- function (id) { skillPickerState.activeTab = id; renderSkillRows() },
8159
- )
8160
- if (skillPickerState.activeTab === 'cloud') {
8161
- setPickerContentMode('cloud')
8162
- renderCloudSkillPanel()
8163
- return
8164
- }
8165
- setPickerContentMode('table')
8291
+ setPickerContentMode()
8166
8292
  setPickerTableHead(['名称', '描述', '操作'])
8167
8293
  clearPickerTableBody()
8168
8294
  setPickerContentState('', false)
@@ -8188,7 +8314,7 @@
8188
8314
  skillPickerState.cloudSeq = seq
8189
8315
  skillPickerState.cloudLoading = true
8190
8316
  skillPickerState.cloudError = ''
8191
- renderSkillRows()
8317
+ renderCloudSkillPanel()
8192
8318
  return fetch(buildCloudSkillCatalogUrl(skillPickerState.cloudQuery, skillPickerState.cloudPage, skillPickerState.cloudPageSize))
8193
8319
  .then(function (r) {
8194
8320
  return r.json().then(function (b) {
@@ -8201,21 +8327,28 @@
8201
8327
  skillPickerState.cloudRows = Array.isArray(x.b.items) ? x.b.items : []
8202
8328
  skillPickerState.cloudTotalPages = Number(x.b.totalPages || 0)
8203
8329
  skillPickerState.cloudLoading = false
8204
- renderSkillRows()
8330
+ renderCloudSkillPanel()
8205
8331
  })
8206
8332
  .catch(function (e) {
8207
8333
  if (seq !== skillPickerState.cloudSeq) return
8208
8334
  skillPickerState.cloudRows = []
8209
8335
  skillPickerState.cloudLoading = false
8210
8336
  skillPickerState.cloudError = String(e)
8211
- renderSkillRows()
8337
+ renderCloudSkillPanel()
8212
8338
  })
8213
8339
  }
8340
+ openSkillStoreModalFn = function () {
8341
+ if (!skillStoreModal) return
8342
+ skillStoreModal.classList.add('is-open')
8343
+ skillStoreModal.setAttribute('aria-hidden', 'false')
8344
+ document.body.style.overflow = 'hidden'
8345
+ skillPickerState.cloudPage = 1
8346
+ void loadCloudSkillRows()
8347
+ }
8214
8348
  refreshSkillPickerRows = function () {
8215
8349
  return Promise.all([
8216
8350
  fetchSkillRows(buildSkillBaseListUrl),
8217
8351
  fetchSkillRows(buildSkillInstalledListUrl),
8218
- loadCloudSkillRows(),
8219
8352
  ])
8220
8353
  .then(function (allRows) {
8221
8354
  skillPickerState.baseRows = allRows[0]
@@ -9170,6 +9303,20 @@
9170
9303
  openSkillPackageModal()
9171
9304
  })
9172
9305
  }
9306
+ if (btnPickerSkillStore) {
9307
+ btnPickerSkillStore.addEventListener('click', function () {
9308
+ if (typeof openSkillStoreModalFn === 'function') openSkillStoreModalFn()
9309
+ })
9310
+ }
9311
+ if (btnSkillStoreModalClose) {
9312
+ btnSkillStoreModalClose.addEventListener('click', closeSkillStoreModal)
9313
+ }
9314
+ if (btnSkillStoreClose) {
9315
+ btnSkillStoreClose.addEventListener('click', closeSkillStoreModal)
9316
+ }
9317
+ if (skillStoreModalBackdrop) {
9318
+ skillStoreModalBackdrop.addEventListener('click', closeSkillStoreModal)
9319
+ }
9173
9320
  if (btnSkillPackageModalClose) {
9174
9321
  btnSkillPackageModalClose.addEventListener('click', closeSkillPackageModal)
9175
9322
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@auto-ai/agent",
3
- "version": "2.1.221",
3
+ "version": "2.1.222",
4
4
  "description": "Auto AI Agent 网关 CLI(WebSocket,独立二进制,无需 Bun)",
5
5
  "type": "module",
6
6
  "maintainers": [
@@ -32,11 +32,11 @@
32
32
  "zod": "^4.3.6"
33
33
  },
34
34
  "optionalDependencies": {
35
- "@auto-ai/agent-linux-x64": "2.1.221",
36
- "@auto-ai/agent-linux-arm64": "2.1.221",
37
- "@auto-ai/agent-darwin-x64": "2.1.221",
38
- "@auto-ai/agent-darwin-arm64": "2.1.221",
39
- "@auto-ai/agent-win-x64": "2.1.221"
35
+ "@auto-ai/agent-linux-x64": "2.1.222",
36
+ "@auto-ai/agent-linux-arm64": "2.1.222",
37
+ "@auto-ai/agent-darwin-x64": "2.1.222",
38
+ "@auto-ai/agent-darwin-arm64": "2.1.222",
39
+ "@auto-ai/agent-win-x64": "2.1.222"
40
40
  },
41
41
  "scripts": {
42
42
  "prepare": "node ../../scripts/sync-launcher-env.js",