@auto-ai/agent 2.1.175 → 2.1.177
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/safe-a/404/index.html +1 -1
- package/dist/safe-a/404.html +1 -1
- package/dist/safe-a/index.html +2 -2
- package/dist/safe-a/index.txt +1 -1
- package/dist/safe-a/manage/about/index.html +2 -2
- package/dist/safe-a/manage/about/index.txt +1 -1
- package/dist/safe-a/manage/env/index.html +2 -2
- package/dist/safe-a/manage/env/index.txt +1 -1
- package/dist/safe-a/manage/general/index.html +2 -2
- package/dist/safe-a/manage/general/index.txt +1 -1
- package/dist/safe-a/manage/index.html +2 -2
- package/dist/safe-a/manage/index.txt +1 -1
- package/dist/safe-a/manage/mcp/index.html +2 -2
- package/dist/safe-a/manage/mcp/index.txt +1 -1
- package/dist/safe-a/manage/permissions/index.html +2 -2
- package/dist/safe-a/manage/permissions/index.txt +1 -1
- package/dist/safe-a/manage/skills/index.html +2 -2
- package/dist/safe-a/manage/skills/index.txt +1 -1
- package/dist/safe-a/manage/task/index.html +2 -2
- package/dist/safe-a/manage/task/index.txt +1 -1
- package/dist/safe-a/manage/teams/index.html +2 -2
- package/dist/safe-a/manage/teams/index.txt +1 -1
- package/dist/safe-a/manage/tools/index.html +2 -2
- package/dist/safe-a/manage/tools/index.txt +1 -1
- package/dist/ws-test/ws-test.css +337 -84
- package/dist/ws-test/ws-test.html +124 -180
- package/dist/ws-test/ws-test.js +770 -1119
- package/package.json +6 -6
- /package/dist/safe-a/_next/static/{u2RBPyRRGWwqO4bEEh88j → FLwrlrqnZ2-ZTbuZi3z9O}/_buildManifest.js +0 -0
- /package/dist/safe-a/_next/static/{u2RBPyRRGWwqO4bEEh88j → FLwrlrqnZ2-ZTbuZi3z9O}/_clientMiddlewareManifest.json +0 -0
- /package/dist/safe-a/_next/static/{u2RBPyRRGWwqO4bEEh88j → FLwrlrqnZ2-ZTbuZi3z9O}/_ssgManifest.js +0 -0
package/dist/ws-test/ws-test.js
CHANGED
|
@@ -105,11 +105,14 @@
|
|
|
105
105
|
const runGroupModalTitle = $('runGroupModalTitle')
|
|
106
106
|
const runGroupModalBody = $('runGroupModalBody')
|
|
107
107
|
const btnRunGroupModalClose = $('btnRunGroupModalClose')
|
|
108
|
-
const
|
|
109
|
-
const scheduleManageModalBackdrop = $('scheduleManageModalBackdrop')
|
|
108
|
+
const scheduleManageView = $('scheduleManageView')
|
|
110
109
|
const scheduleManageMeta = $('scheduleManageMeta')
|
|
110
|
+
const scheduleTasksWrap = $('scheduleTasksWrap')
|
|
111
|
+
const scheduleRunsWrap = $('scheduleRunsWrap')
|
|
111
112
|
const scheduleTaskTableBody = $('scheduleTaskTableBody')
|
|
112
113
|
const scheduleManageEmpty = $('scheduleManageEmpty')
|
|
114
|
+
const btnScheduleRunsBack = $('btnScheduleRunsBack')
|
|
115
|
+
const scheduleRunsTitle = $('scheduleRunsTitle')
|
|
113
116
|
const btnScheduleManageModalClose = $('btnScheduleManageModalClose')
|
|
114
117
|
const btnScheduleRefresh = $('btnScheduleRefresh')
|
|
115
118
|
const btnScheduleCreateToggle = $('btnScheduleCreateToggle')
|
|
@@ -121,9 +124,6 @@
|
|
|
121
124
|
const scheduleRecurringInput = $('scheduleRecurringInput')
|
|
122
125
|
const scheduleDelayRow = $('scheduleDelayRow')
|
|
123
126
|
const scheduleCronRow = $('scheduleCronRow')
|
|
124
|
-
const scheduleRunsModal = $('scheduleRunsModal')
|
|
125
|
-
const scheduleRunsModalBackdrop = $('scheduleRunsModalBackdrop')
|
|
126
|
-
const scheduleRunsModalTitle = $('scheduleRunsModalTitle')
|
|
127
127
|
const scheduleRunsMeta = $('scheduleRunsMeta')
|
|
128
128
|
const scheduleRunsTableBody = $('scheduleRunsTableBody')
|
|
129
129
|
const scheduleRunsEmpty = $('scheduleRunsEmpty')
|
|
@@ -132,7 +132,6 @@
|
|
|
132
132
|
let scheduleRunsViewTaskName = ''
|
|
133
133
|
const btnScheduleCreateCancel = $('btnScheduleCreateCancel')
|
|
134
134
|
const btnScheduleCreateSubmit = $('btnScheduleCreateSubmit')
|
|
135
|
-
const btnManageAgents = $('btnManageAgents')
|
|
136
135
|
const btnManageRepo = $('btnManageRepo')
|
|
137
136
|
const repoManageView = $('repoManageView')
|
|
138
137
|
const chatWorkspace = $('chatWorkspace')
|
|
@@ -166,9 +165,6 @@
|
|
|
166
165
|
const brandAgentSwitchBtnEl = $('brandAgentSwitchBtn')
|
|
167
166
|
/** agent id → 展示名(来自 /api/agents) */
|
|
168
167
|
const agentDisplayNameById = Object.create(null)
|
|
169
|
-
const agentSwitchWrapEl = $('agentSwitchWrap')
|
|
170
|
-
const agentSwitchDropdownEl = $('agentSwitchDropdown')
|
|
171
|
-
let agentSwitchOpen = false
|
|
172
168
|
const sidebarHoverTipEl = $('sidebarHoverTip')
|
|
173
169
|
const sidebarAsideEl = document.querySelector('aside.sidebar')
|
|
174
170
|
let sidebarHoverTipHideTimer = null
|
|
@@ -262,20 +258,20 @@
|
|
|
262
258
|
const composerModeSelect = $('composerModeSelect')
|
|
263
259
|
const composerToolAskSelect = $('composerToolAskSelect')
|
|
264
260
|
const btnSaveAgentConfig = $('btnSaveAgentConfig')
|
|
265
|
-
const
|
|
266
|
-
const
|
|
267
|
-
const
|
|
268
|
-
const
|
|
269
|
-
const
|
|
270
|
-
const
|
|
271
|
-
const
|
|
272
|
-
const
|
|
273
|
-
const
|
|
274
|
-
const
|
|
275
|
-
const
|
|
276
|
-
const
|
|
277
|
-
const
|
|
278
|
-
const
|
|
261
|
+
const pickerManageView = $('pickerManageView')
|
|
262
|
+
const pickerNavPanel = $('pickerNavPanel')
|
|
263
|
+
const pickerNavList = $('pickerNavList')
|
|
264
|
+
const pickerSearch = $('pickerSearch')
|
|
265
|
+
const btnPickerMcpJson = $('btnPickerMcpJson')
|
|
266
|
+
const btnPickerImport = $('btnPickerImport')
|
|
267
|
+
const btnPickerCancel = $('btnPickerCancel')
|
|
268
|
+
const btnPickerSave = $('btnPickerSave')
|
|
269
|
+
const pickerEntriesTable = $('pickerEntriesTable')
|
|
270
|
+
const pickerTableHeadRow = $('pickerTableHeadRow')
|
|
271
|
+
const pickerEntriesBody = $('pickerEntriesBody')
|
|
272
|
+
const pickerCloudPanel = $('pickerCloudPanel')
|
|
273
|
+
const pickerContentState = $('pickerContentState')
|
|
274
|
+
const pickerImportInput = $('pickerImportInput')
|
|
279
275
|
const mcpJsonInputModal = $('mcpJsonInputModal')
|
|
280
276
|
const mcpJsonInputModalBackdrop = $('mcpJsonInputModalBackdrop')
|
|
281
277
|
const mcpJsonInputEditor = $('mcpJsonInputEditor')
|
|
@@ -334,11 +330,18 @@
|
|
|
334
330
|
let agentEnvFieldValues = {}
|
|
335
331
|
let agentEnvActiveTab = 'settings'
|
|
336
332
|
let agentEnvAgentMdLoadOk = false
|
|
333
|
+
const pickerManageState = {
|
|
334
|
+
viewActive: false,
|
|
335
|
+
kind: 'tools',
|
|
336
|
+
activeTab: '',
|
|
337
|
+
draftSelected: new Set(),
|
|
338
|
+
}
|
|
337
339
|
let pickerKind = 'tools'
|
|
338
|
-
let pickerSelected =
|
|
340
|
+
let pickerSelected = pickerManageState.draftSelected
|
|
339
341
|
let refreshToolPickerRows = null
|
|
340
342
|
let refreshMcpPickerRows = null
|
|
341
343
|
let refreshSkillPickerRows = null
|
|
344
|
+
let pickerRenderContent = null
|
|
342
345
|
let remoteMcpServers = []
|
|
343
346
|
const WS_PERMISSION_MODE_KEY = 'WS_PERMISSION_MODE'
|
|
344
347
|
const LLM_MODEL_KEY = 'LLM_MODEL'
|
|
@@ -2187,11 +2190,24 @@
|
|
|
2187
2190
|
const label = agentBrandLabel(id)
|
|
2188
2191
|
if (brandAgentNameEl) brandAgentNameEl.textContent = label
|
|
2189
2192
|
if (brandAgentSwitchBtnEl) {
|
|
2190
|
-
brandAgentSwitchBtnEl.setAttribute('title', '
|
|
2191
|
-
brandAgentSwitchBtnEl.setAttribute(
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2193
|
+
brandAgentSwitchBtnEl.setAttribute('title', '返回首页:' + label)
|
|
2194
|
+
brandAgentSwitchBtnEl.setAttribute('aria-label', '返回首页:' + label)
|
|
2195
|
+
}
|
|
2196
|
+
}
|
|
2197
|
+
|
|
2198
|
+
/** 跳转 agent 办公室首页 */
|
|
2199
|
+
function goToAgentHomePage() {
|
|
2200
|
+
const cur = currentAgentParam()
|
|
2201
|
+
window.location.href = cur ? '/?agent=' + encodeURIComponent(cur) : '/'
|
|
2202
|
+
}
|
|
2203
|
+
|
|
2204
|
+
/** 清除侧栏管理导航选中态 */
|
|
2205
|
+
function clearSidebarNavActive() {
|
|
2206
|
+
const navEl = document.querySelector('.sidebar-nav')
|
|
2207
|
+
if (!navEl) return
|
|
2208
|
+
const items = navEl.querySelectorAll('.sidebar-nav-row')
|
|
2209
|
+
for (let i = 0; i < items.length; i++) {
|
|
2210
|
+
items[i].classList.remove('is-active')
|
|
2195
2211
|
}
|
|
2196
2212
|
}
|
|
2197
2213
|
|
|
@@ -2223,175 +2239,6 @@
|
|
|
2223
2239
|
).toString()
|
|
2224
2240
|
}
|
|
2225
2241
|
|
|
2226
|
-
/** 关闭 agent 切换下拉,恢复头像按钮状态 */
|
|
2227
|
-
function closeAgentSwitchMenu() {
|
|
2228
|
-
agentSwitchOpen = false
|
|
2229
|
-
if (agentSwitchWrapEl) agentSwitchWrapEl.classList.remove('open')
|
|
2230
|
-
if (agentSwitchDropdownEl) {
|
|
2231
|
-
agentSwitchDropdownEl.classList.remove('is-open')
|
|
2232
|
-
agentSwitchDropdownEl.hidden = true
|
|
2233
|
-
agentSwitchDropdownEl.style.left = ''
|
|
2234
|
-
agentSwitchDropdownEl.style.top = ''
|
|
2235
|
-
}
|
|
2236
|
-
if (brandAgentSwitchBtnEl) brandAgentSwitchBtnEl.setAttribute('aria-expanded', 'false')
|
|
2237
|
-
}
|
|
2238
|
-
|
|
2239
|
-
/** 根据品牌按钮位置计算浮层坐标,显示在侧栏右侧避免被 overflow 裁剪 */
|
|
2240
|
-
function positionAgentSwitchDropdown() {
|
|
2241
|
-
if (!brandAgentSwitchBtnEl || !agentSwitchDropdownEl || !agentSwitchOpen) return
|
|
2242
|
-
requestAnimationFrame(function () {
|
|
2243
|
-
if (!agentSwitchOpen || !brandAgentSwitchBtnEl || !agentSwitchDropdownEl) return
|
|
2244
|
-
const rect = brandAgentSwitchBtnEl.getBoundingClientRect()
|
|
2245
|
-
const gap = 10
|
|
2246
|
-
const menuW = agentSwitchDropdownEl.offsetWidth
|
|
2247
|
-
const menuH = agentSwitchDropdownEl.offsetHeight
|
|
2248
|
-
let left = rect.right + gap
|
|
2249
|
-
let top = rect.top
|
|
2250
|
-
if (left + menuW > window.innerWidth - 12) {
|
|
2251
|
-
left = rect.left
|
|
2252
|
-
top = rect.bottom + gap
|
|
2253
|
-
}
|
|
2254
|
-
left = Math.max(12, Math.min(left, window.innerWidth - menuW - 12))
|
|
2255
|
-
top = Math.max(12, Math.min(top, window.innerHeight - menuH - 12))
|
|
2256
|
-
agentSwitchDropdownEl.style.left = left + 'px'
|
|
2257
|
-
agentSwitchDropdownEl.style.top = top + 'px'
|
|
2258
|
-
})
|
|
2259
|
-
}
|
|
2260
|
-
|
|
2261
|
-
/** 在 agent 切换下拉底部追加「管理 Agent」入口 */
|
|
2262
|
-
function appendAgentSwitchManageFooter() {
|
|
2263
|
-
if (!agentSwitchDropdownEl) return
|
|
2264
|
-
const foot = document.createElement('div')
|
|
2265
|
-
foot.className = 'agent-switch-dropdown-foot'
|
|
2266
|
-
const manageBtn = document.createElement('button')
|
|
2267
|
-
manageBtn.type = 'button'
|
|
2268
|
-
manageBtn.className = 'agent-switch-manage-btn'
|
|
2269
|
-
manageBtn.textContent = '管理 Agent…'
|
|
2270
|
-
manageBtn.addEventListener('click', function (ev) {
|
|
2271
|
-
ev.preventDefault()
|
|
2272
|
-
ev.stopPropagation()
|
|
2273
|
-
closeAgentSwitchMenu()
|
|
2274
|
-
const cur = currentAgentParam()
|
|
2275
|
-
window.location.href = cur ? '/?agent=' + encodeURIComponent(cur) : '/'
|
|
2276
|
-
})
|
|
2277
|
-
foot.appendChild(manageBtn)
|
|
2278
|
-
agentSwitchDropdownEl.appendChild(foot)
|
|
2279
|
-
}
|
|
2280
|
-
|
|
2281
|
-
/** 渲染 agent 列表项;当前 agent 高亮,点击后立即切换 workspace */
|
|
2282
|
-
function renderAgentSwitchList(agents) {
|
|
2283
|
-
if (!agentSwitchDropdownEl) return
|
|
2284
|
-
agentSwitchDropdownEl.innerHTML = ''
|
|
2285
|
-
const current = currentAgentParam()
|
|
2286
|
-
const head = document.createElement('div')
|
|
2287
|
-
head.className = 'agent-switch-dropdown-head'
|
|
2288
|
-
head.textContent = '切换 Agent'
|
|
2289
|
-
agentSwitchDropdownEl.appendChild(head)
|
|
2290
|
-
if (!Array.isArray(agents) || !agents.length) {
|
|
2291
|
-
const empty = document.createElement('div')
|
|
2292
|
-
empty.className = 'agent-switch-empty'
|
|
2293
|
-
empty.textContent = '暂无 agent'
|
|
2294
|
-
agentSwitchDropdownEl.appendChild(empty)
|
|
2295
|
-
appendAgentSwitchManageFooter()
|
|
2296
|
-
positionAgentSwitchDropdown()
|
|
2297
|
-
return
|
|
2298
|
-
}
|
|
2299
|
-
const list = document.createElement('div')
|
|
2300
|
-
list.className = 'agent-switch-dropdown-list'
|
|
2301
|
-
const frag = document.createDocumentFragment()
|
|
2302
|
-
for (let i = 0; i < agents.length; i++) {
|
|
2303
|
-
const row = agents[i]
|
|
2304
|
-
const id = String(row && row.id != null ? row.id : '').trim()
|
|
2305
|
-
if (!id) continue
|
|
2306
|
-
const displayName =
|
|
2307
|
-
row && typeof row.displayName === 'string' && row.displayName.trim()
|
|
2308
|
-
? row.displayName.trim()
|
|
2309
|
-
: id
|
|
2310
|
-
const btn = document.createElement('button')
|
|
2311
|
-
btn.type = 'button'
|
|
2312
|
-
btn.className = 'agent-switch-item' + (id === current ? ' is-current' : '')
|
|
2313
|
-
btn.setAttribute('role', 'option')
|
|
2314
|
-
btn.setAttribute('aria-selected', id === current ? 'true' : 'false')
|
|
2315
|
-
const mainEl = document.createElement('span')
|
|
2316
|
-
mainEl.className = 'agent-switch-item-main'
|
|
2317
|
-
const nameEl = document.createElement('span')
|
|
2318
|
-
nameEl.className = 'agent-switch-item-name'
|
|
2319
|
-
nameEl.textContent = displayName
|
|
2320
|
-
mainEl.appendChild(nameEl)
|
|
2321
|
-
if (displayName !== id) {
|
|
2322
|
-
const idEl = document.createElement('span')
|
|
2323
|
-
idEl.className = 'agent-switch-item-id'
|
|
2324
|
-
idEl.textContent = id
|
|
2325
|
-
mainEl.appendChild(idEl)
|
|
2326
|
-
}
|
|
2327
|
-
btn.appendChild(mainEl)
|
|
2328
|
-
const checkEl = document.createElement('span')
|
|
2329
|
-
checkEl.className = 'agent-switch-item-check'
|
|
2330
|
-
checkEl.setAttribute('aria-hidden', 'true')
|
|
2331
|
-
checkEl.innerHTML =
|
|
2332
|
-
'<svg viewBox="0 0 16 16" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M3.5 8.2 6.6 11.3 12.5 4.8"/></svg>'
|
|
2333
|
-
btn.appendChild(checkEl)
|
|
2334
|
-
btn.addEventListener('click', function (ev) {
|
|
2335
|
-
ev.preventDefault()
|
|
2336
|
-
ev.stopPropagation()
|
|
2337
|
-
selectWorkspaceAgent(id)
|
|
2338
|
-
})
|
|
2339
|
-
frag.appendChild(btn)
|
|
2340
|
-
}
|
|
2341
|
-
list.appendChild(frag)
|
|
2342
|
-
agentSwitchDropdownEl.appendChild(list)
|
|
2343
|
-
appendAgentSwitchManageFooter()
|
|
2344
|
-
cacheAgentDisplayNames(agents)
|
|
2345
|
-
updateBrandAgent()
|
|
2346
|
-
positionAgentSwitchDropdown()
|
|
2347
|
-
}
|
|
2348
|
-
|
|
2349
|
-
/** 选中目标 agent:复用 onAgentChanged 完成 WS 切换、会话刷新与配置重载 */
|
|
2350
|
-
function selectWorkspaceAgent(nextId) {
|
|
2351
|
-
const id = String(nextId || '').trim()
|
|
2352
|
-
if (!id || !agentIdInput) return
|
|
2353
|
-
closeAgentSwitchMenu()
|
|
2354
|
-
if (id === currentAgentParam()) return
|
|
2355
|
-
agentIdInput.value = id
|
|
2356
|
-
onAgentChanged()
|
|
2357
|
-
}
|
|
2358
|
-
|
|
2359
|
-
/** 打开 agent 切换下拉,按需拉取 /api/agents 列表 */
|
|
2360
|
-
async function openAgentSwitchMenu() {
|
|
2361
|
-
if (!agentSwitchWrapEl || !agentSwitchDropdownEl || !brandAgentSwitchBtnEl) return
|
|
2362
|
-
hideSidebarHoverTip()
|
|
2363
|
-
agentSwitchOpen = true
|
|
2364
|
-
agentSwitchWrapEl.classList.add('open')
|
|
2365
|
-
agentSwitchDropdownEl.hidden = false
|
|
2366
|
-
agentSwitchDropdownEl.classList.add('is-open')
|
|
2367
|
-
brandAgentSwitchBtnEl.setAttribute('aria-expanded', 'true')
|
|
2368
|
-
agentSwitchDropdownEl.innerHTML = '<div class="agent-switch-loading">加载中…</div>'
|
|
2369
|
-
positionAgentSwitchDropdown()
|
|
2370
|
-
try {
|
|
2371
|
-
const r = await fetch(buildAgentsListUrl())
|
|
2372
|
-
const body = await r.json().catch(function () {
|
|
2373
|
-
return {}
|
|
2374
|
-
})
|
|
2375
|
-
if (!r.ok) {
|
|
2376
|
-
throw new Error(body.message || body.error || r.statusText)
|
|
2377
|
-
}
|
|
2378
|
-
renderAgentSwitchList(body.agents)
|
|
2379
|
-
} catch (e) {
|
|
2380
|
-
agentSwitchDropdownEl.innerHTML =
|
|
2381
|
-
'<div class="agent-switch-empty">加载失败: ' + escapeHtml(String(e)) + '</div>'
|
|
2382
|
-
positionAgentSwitchDropdown()
|
|
2383
|
-
}
|
|
2384
|
-
}
|
|
2385
|
-
|
|
2386
|
-
/** 点击头像时切换下拉开关 */
|
|
2387
|
-
async function toggleAgentSwitchMenu() {
|
|
2388
|
-
if (agentSwitchOpen) {
|
|
2389
|
-
closeAgentSwitchMenu()
|
|
2390
|
-
return
|
|
2391
|
-
}
|
|
2392
|
-
await openAgentSwitchMenu()
|
|
2393
|
-
}
|
|
2394
|
-
|
|
2395
2242
|
function rewriteSameOriginNavLinks() {
|
|
2396
2243
|
const agent = currentAgentParam()
|
|
2397
2244
|
const origin = window.location.origin
|
|
@@ -2683,9 +2530,66 @@
|
|
|
2683
2530
|
}
|
|
2684
2531
|
|
|
2685
2532
|
/** 显示/隐藏文件浏览主区域、聊天区;顶栏在文件视图下展示「文件」而非会话标题 */
|
|
2533
|
+
const scheduleManageState = {
|
|
2534
|
+
viewActive: false,
|
|
2535
|
+
contentView: 'list',
|
|
2536
|
+
}
|
|
2537
|
+
|
|
2538
|
+
/** 切换定时任务列表与执行记录面板 */
|
|
2539
|
+
function setScheduleContentView(view) {
|
|
2540
|
+
scheduleManageState.contentView = view === 'runs' ? 'runs' : 'list'
|
|
2541
|
+
if (scheduleTasksWrap) scheduleTasksWrap.hidden = scheduleManageState.contentView !== 'list'
|
|
2542
|
+
if (scheduleRunsWrap) scheduleRunsWrap.hidden = scheduleManageState.contentView !== 'runs'
|
|
2543
|
+
}
|
|
2544
|
+
|
|
2545
|
+
/** 显示/隐藏定时任务主视图,与聊天区等互斥 */
|
|
2546
|
+
function setScheduleManageVisible(visible) {
|
|
2547
|
+
if (visible) {
|
|
2548
|
+
closeAgentSettingsView()
|
|
2549
|
+
closePickerManageView(false)
|
|
2550
|
+
repoManageState.viewActive = false
|
|
2551
|
+
if (repoManageView) repoManageView.hidden = true
|
|
2552
|
+
if (btnManageRepo) btnManageRepo.classList.remove('is-active')
|
|
2553
|
+
}
|
|
2554
|
+
scheduleManageState.viewActive = visible
|
|
2555
|
+
if (scheduleManageView) scheduleManageView.hidden = !visible
|
|
2556
|
+
if (chatWorkspace) chatWorkspace.hidden = visible
|
|
2557
|
+
if (chatComposer) chatComposer.hidden = visible
|
|
2558
|
+
if (mainHeaderEl) mainHeaderEl.hidden = false
|
|
2559
|
+
if (visible) {
|
|
2560
|
+
if (mainTitleEl) mainTitleEl.textContent = '定时任务'
|
|
2561
|
+
if (mainSubEl) {
|
|
2562
|
+
mainSubEl.textContent = ''
|
|
2563
|
+
mainSubEl.hidden = true
|
|
2564
|
+
}
|
|
2565
|
+
} else {
|
|
2566
|
+
updateMainHeader()
|
|
2567
|
+
}
|
|
2568
|
+
}
|
|
2569
|
+
|
|
2570
|
+
/** 关闭定时任务主视图 */
|
|
2571
|
+
function closeScheduleManageView(restoreOffice) {
|
|
2572
|
+
if (!scheduleManageState.viewActive) return
|
|
2573
|
+
setScheduleContentView('list')
|
|
2574
|
+
scheduleRunsViewTaskId = null
|
|
2575
|
+
scheduleRunsViewTaskName = ''
|
|
2576
|
+
if (scheduleCreateForm) scheduleCreateForm.hidden = true
|
|
2577
|
+
setScheduleManageVisible(false)
|
|
2578
|
+
const navEl = document.querySelector('.sidebar-nav')
|
|
2579
|
+
if (navEl) {
|
|
2580
|
+
const items = navEl.querySelectorAll('.sidebar-nav-row[data-add]')
|
|
2581
|
+
for (let i = 0; i < items.length; i++) {
|
|
2582
|
+
items[i].classList.remove('is-active')
|
|
2583
|
+
}
|
|
2584
|
+
}
|
|
2585
|
+
if (restoreOffice !== false) clearSidebarNavActive()
|
|
2586
|
+
}
|
|
2587
|
+
|
|
2686
2588
|
function setRepoManageVisible(visible) {
|
|
2687
2589
|
if (visible) {
|
|
2688
2590
|
closeAgentSettingsView()
|
|
2591
|
+
closePickerManageView(false)
|
|
2592
|
+
closeScheduleManageView(false)
|
|
2689
2593
|
}
|
|
2690
2594
|
repoManageState.viewActive = visible
|
|
2691
2595
|
if (repoManageView) repoManageView.hidden = !visible
|
|
@@ -2715,6 +2619,8 @@
|
|
|
2715
2619
|
*/
|
|
2716
2620
|
function setAgentSettingsVisible(visible) {
|
|
2717
2621
|
if (visible) {
|
|
2622
|
+
closePickerManageView(false)
|
|
2623
|
+
closeScheduleManageView(false)
|
|
2718
2624
|
repoManageState.viewActive = false
|
|
2719
2625
|
if (repoManageView) repoManageView.hidden = true
|
|
2720
2626
|
if (btnManageRepo) btnManageRepo.classList.remove('is-active')
|
|
@@ -2744,6 +2650,154 @@
|
|
|
2744
2650
|
if (agentEnvSessionTabList) agentEnvSessionTabList.innerHTML = ''
|
|
2745
2651
|
}
|
|
2746
2652
|
|
|
2653
|
+
const PICKER_KIND_TITLES = {
|
|
2654
|
+
tools: '工具',
|
|
2655
|
+
mcp: 'MCP',
|
|
2656
|
+
skills: 'Skill',
|
|
2657
|
+
agentTeams: 'Teams',
|
|
2658
|
+
}
|
|
2659
|
+
|
|
2660
|
+
/** 设置 Picker 主视图与聊天区等互斥可见性 */
|
|
2661
|
+
function setPickerManageVisible(visible) {
|
|
2662
|
+
if (visible) {
|
|
2663
|
+
closeAgentSettingsView()
|
|
2664
|
+
closeScheduleManageView(false)
|
|
2665
|
+
repoManageState.viewActive = false
|
|
2666
|
+
if (repoManageView) repoManageView.hidden = true
|
|
2667
|
+
if (btnManageRepo) btnManageRepo.classList.remove('is-active')
|
|
2668
|
+
}
|
|
2669
|
+
pickerManageState.viewActive = visible
|
|
2670
|
+
if (pickerManageView) pickerManageView.hidden = !visible
|
|
2671
|
+
if (chatWorkspace) chatWorkspace.hidden = visible
|
|
2672
|
+
if (chatComposer) chatComposer.hidden = visible
|
|
2673
|
+
if (mainHeaderEl) mainHeaderEl.hidden = false
|
|
2674
|
+
if (visible) {
|
|
2675
|
+
if (mainTitleEl) {
|
|
2676
|
+
mainTitleEl.textContent = PICKER_KIND_TITLES[pickerManageState.kind] || '管理'
|
|
2677
|
+
}
|
|
2678
|
+
if (mainSubEl) {
|
|
2679
|
+
mainSubEl.textContent = ''
|
|
2680
|
+
mainSubEl.hidden = true
|
|
2681
|
+
}
|
|
2682
|
+
} else {
|
|
2683
|
+
updateMainHeader()
|
|
2684
|
+
}
|
|
2685
|
+
}
|
|
2686
|
+
|
|
2687
|
+
/** 关闭 Picker 主视图;回到聊天时清除侧栏导航选中态 */
|
|
2688
|
+
function closePickerManageView(restoreOffice) {
|
|
2689
|
+
if (!pickerManageState.viewActive) return
|
|
2690
|
+
pickerManageState.draftSelected.clear()
|
|
2691
|
+
pickerKind = pickerManageState.kind
|
|
2692
|
+
pickerSelected = pickerManageState.draftSelected
|
|
2693
|
+
refreshToolPickerRows = null
|
|
2694
|
+
refreshMcpPickerRows = null
|
|
2695
|
+
refreshSkillPickerRows = null
|
|
2696
|
+
pickerRenderContent = null
|
|
2697
|
+
setPickerManageVisible(false)
|
|
2698
|
+
const navEl = document.querySelector('.sidebar-nav')
|
|
2699
|
+
if (navEl) {
|
|
2700
|
+
const items = navEl.querySelectorAll('.sidebar-nav-row[data-add]')
|
|
2701
|
+
for (let i = 0; i < items.length; i++) {
|
|
2702
|
+
items[i].classList.remove('is-active')
|
|
2703
|
+
}
|
|
2704
|
+
}
|
|
2705
|
+
if (restoreOffice !== false) clearSidebarNavActive()
|
|
2706
|
+
}
|
|
2707
|
+
|
|
2708
|
+
/** Picker 内容区加载/错误态;有文案时隐藏表格 */
|
|
2709
|
+
function setPickerContentState(message, isError) {
|
|
2710
|
+
setRepoPanelState(pickerContentState, message, isError)
|
|
2711
|
+
if (pickerEntriesTable) {
|
|
2712
|
+
pickerEntriesTable.hidden = !!message
|
|
2713
|
+
}
|
|
2714
|
+
}
|
|
2715
|
+
|
|
2716
|
+
/** 获取 Picker 顶栏筛选关键词 */
|
|
2717
|
+
function getPickerSearchQuery() {
|
|
2718
|
+
return (pickerSearch && pickerSearch.value.trim().toLowerCase()) || ''
|
|
2719
|
+
}
|
|
2720
|
+
|
|
2721
|
+
/** 切换表格与云端面板显示 */
|
|
2722
|
+
function setPickerContentMode(mode) {
|
|
2723
|
+
const isCloud = mode === 'cloud'
|
|
2724
|
+
if (pickerEntriesTable) pickerEntriesTable.hidden = isCloud
|
|
2725
|
+
if (pickerCloudPanel) pickerCloudPanel.hidden = !isCloud
|
|
2726
|
+
if (!isCloud && pickerContentState) {
|
|
2727
|
+
pickerContentState.hidden = true
|
|
2728
|
+
pickerContentState.textContent = ''
|
|
2729
|
+
}
|
|
2730
|
+
}
|
|
2731
|
+
|
|
2732
|
+
/** 设置 Picker 表格表头;最后一列标记为操作列并右对齐 */
|
|
2733
|
+
function setPickerTableHead(cols) {
|
|
2734
|
+
if (!pickerTableHeadRow) return
|
|
2735
|
+
pickerTableHeadRow.innerHTML = ''
|
|
2736
|
+
for (let i = 0; i < cols.length; i++) {
|
|
2737
|
+
const th = document.createElement('th')
|
|
2738
|
+
th.textContent = cols[i]
|
|
2739
|
+
if (i === cols.length - 1) th.className = 'col-actions'
|
|
2740
|
+
pickerTableHeadRow.appendChild(th)
|
|
2741
|
+
}
|
|
2742
|
+
}
|
|
2743
|
+
|
|
2744
|
+
/** 清空 Picker 表格内容 */
|
|
2745
|
+
function clearPickerTableBody() {
|
|
2746
|
+
if (pickerEntriesBody) pickerEntriesBody.innerHTML = ''
|
|
2747
|
+
}
|
|
2748
|
+
|
|
2749
|
+
/** 创建主视图表格行操作按钮 */
|
|
2750
|
+
function createManageRowBtn(text, className, onClick, opts) {
|
|
2751
|
+
const options = opts || {}
|
|
2752
|
+
const btn = document.createElement('button')
|
|
2753
|
+
btn.type = 'button'
|
|
2754
|
+
btn.className = 'btn-manage-row-action' + (className ? ' ' + className : '')
|
|
2755
|
+
btn.textContent = text
|
|
2756
|
+
if (options.disabled) btn.disabled = true
|
|
2757
|
+
if (options.title) btn.title = options.title
|
|
2758
|
+
btn.addEventListener('click', onClick)
|
|
2759
|
+
return btn
|
|
2760
|
+
}
|
|
2761
|
+
|
|
2762
|
+
/** 创建主视图表格操作列(按钮靠右) */
|
|
2763
|
+
function createManageActionsTd(buttons) {
|
|
2764
|
+
const td = document.createElement('td')
|
|
2765
|
+
td.className = 'col-actions'
|
|
2766
|
+
const wrap = document.createElement('div')
|
|
2767
|
+
wrap.className = 'manage-row-actions'
|
|
2768
|
+
for (let i = 0; i < buttons.length; i++) wrap.appendChild(buttons[i])
|
|
2769
|
+
td.appendChild(wrap)
|
|
2770
|
+
return td
|
|
2771
|
+
}
|
|
2772
|
+
|
|
2773
|
+
/** 控制 Picker 左侧分类栏显隐(仅 Skill 页保留分类,其余合并为单表) */
|
|
2774
|
+
function setPickerNavPanelVisible(visible) {
|
|
2775
|
+
if (!pickerNavPanel) return
|
|
2776
|
+
pickerNavPanel.hidden = !visible
|
|
2777
|
+
if (!visible && pickerNavList) pickerNavList.innerHTML = ''
|
|
2778
|
+
}
|
|
2779
|
+
|
|
2780
|
+
/** 渲染 Picker 左侧分类导航 */
|
|
2781
|
+
function renderPickerNavTabs(tabDefs, activeId, onChange) {
|
|
2782
|
+
if (!pickerNavList) return
|
|
2783
|
+
pickerNavList.innerHTML = ''
|
|
2784
|
+
pickerManageState.activeTab = activeId
|
|
2785
|
+
for (let i = 0; i < tabDefs.length; i++) {
|
|
2786
|
+
const tab = tabDefs[i]
|
|
2787
|
+
const btn = document.createElement('button')
|
|
2788
|
+
btn.type = 'button'
|
|
2789
|
+
btn.className = 'picker-nav-item' + (tab.id === activeId ? ' is-selected' : '')
|
|
2790
|
+
btn.setAttribute('role', 'tab')
|
|
2791
|
+
btn.setAttribute('aria-selected', tab.id === activeId ? 'true' : 'false')
|
|
2792
|
+
btn.textContent = tab.label
|
|
2793
|
+
btn.addEventListener('click', function () {
|
|
2794
|
+
if (tab.id === activeId) return
|
|
2795
|
+
onChange(tab.id)
|
|
2796
|
+
})
|
|
2797
|
+
pickerNavList.appendChild(btn)
|
|
2798
|
+
}
|
|
2799
|
+
}
|
|
2800
|
+
|
|
2747
2801
|
/** 设置 entries/history 面板加载或错误态 */
|
|
2748
2802
|
function setRepoPanelState(el, message, isError) {
|
|
2749
2803
|
if (!el) return
|
|
@@ -3276,6 +3330,7 @@
|
|
|
3276
3330
|
scheduleTaskTableBody.innerHTML = ''
|
|
3277
3331
|
const list = Array.isArray(tasks) ? tasks : []
|
|
3278
3332
|
scheduleManageEmpty.hidden = list.length > 0
|
|
3333
|
+
if (list.length > 0) scheduleManageEmpty.classList.remove('is-error')
|
|
3279
3334
|
for (let i = 0; i < list.length; i++) {
|
|
3280
3335
|
const task = list[i]
|
|
3281
3336
|
if (!task || !task.id) continue
|
|
@@ -3289,7 +3344,7 @@
|
|
|
3289
3344
|
sessionBtn.textContent = task.taskName || task.id || task.sessionId.slice(0, 8) + '…'
|
|
3290
3345
|
sessionBtn.title = task.sessionId
|
|
3291
3346
|
sessionBtn.addEventListener('click', function () {
|
|
3292
|
-
|
|
3347
|
+
closeScheduleManageView(false)
|
|
3293
3348
|
switchToSession(task.sessionId)
|
|
3294
3349
|
})
|
|
3295
3350
|
tdSession.appendChild(sessionBtn)
|
|
@@ -3305,39 +3360,20 @@
|
|
|
3305
3360
|
const tdEnabled = document.createElement('td')
|
|
3306
3361
|
const isEnabled = task.enabled !== false
|
|
3307
3362
|
tdEnabled.textContent = isEnabled ? '启用中' : '已禁用'
|
|
3308
|
-
const tdAction =
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
})
|
|
3323
|
-
const toggleBtn = document.createElement('button')
|
|
3324
|
-
toggleBtn.type = 'button'
|
|
3325
|
-
toggleBtn.className = 'btn-system-settings'
|
|
3326
|
-
toggleBtn.textContent = isEnabled ? '禁用' : '启用'
|
|
3327
|
-
toggleBtn.addEventListener('click', function () {
|
|
3328
|
-
void patchScheduleTaskEnabled(task.id, !isEnabled)
|
|
3329
|
-
})
|
|
3330
|
-
const delBtn = document.createElement('button')
|
|
3331
|
-
delBtn.type = 'button'
|
|
3332
|
-
delBtn.className = 'btn-system-settings'
|
|
3333
|
-
delBtn.textContent = '删除'
|
|
3334
|
-
delBtn.addEventListener('click', function () {
|
|
3335
|
-
void deleteScheduleTask(task.id)
|
|
3336
|
-
})
|
|
3337
|
-
tdAction.appendChild(runsBtn)
|
|
3338
|
-
tdAction.appendChild(runBtn)
|
|
3339
|
-
tdAction.appendChild(toggleBtn)
|
|
3340
|
-
tdAction.appendChild(delBtn)
|
|
3363
|
+
const tdAction = createManageActionsTd([
|
|
3364
|
+
createManageRowBtn('执行记录', '', function () {
|
|
3365
|
+
void openScheduleRunsView(task.id, task.taskName || task.id)
|
|
3366
|
+
}),
|
|
3367
|
+
createManageRowBtn('立即执行', '', function () {
|
|
3368
|
+
void runScheduleTaskNow(task.id)
|
|
3369
|
+
}),
|
|
3370
|
+
createManageRowBtn(isEnabled ? '禁用' : '启用', isEnabled ? 'is-on' : '', function () {
|
|
3371
|
+
void patchScheduleTaskEnabled(task.id, !isEnabled)
|
|
3372
|
+
}),
|
|
3373
|
+
createManageRowBtn('删除', 'is-delete', function () {
|
|
3374
|
+
void deleteScheduleTask(task.id)
|
|
3375
|
+
}),
|
|
3376
|
+
])
|
|
3341
3377
|
tr.appendChild(tdId)
|
|
3342
3378
|
tr.appendChild(tdSession)
|
|
3343
3379
|
tr.appendChild(tdCron)
|
|
@@ -3493,6 +3529,7 @@
|
|
|
3493
3529
|
scheduleRunsTableBody.innerHTML = ''
|
|
3494
3530
|
const list = Array.isArray(runs) ? runs : []
|
|
3495
3531
|
scheduleRunsEmpty.hidden = list.length > 0
|
|
3532
|
+
if (list.length > 0) scheduleRunsEmpty.classList.remove('is-error')
|
|
3496
3533
|
if (scheduleRunResultPre) {
|
|
3497
3534
|
scheduleRunResultPre.hidden = true
|
|
3498
3535
|
scheduleRunResultPre.textContent = ''
|
|
@@ -3521,15 +3558,14 @@
|
|
|
3521
3558
|
tdSummary.textContent = scheduleRunResultSummary(run)
|
|
3522
3559
|
tdSummary.title = run.resultText || run.errorMessage || ''
|
|
3523
3560
|
const tdAction = document.createElement('td')
|
|
3561
|
+
tdAction.className = 'col-actions'
|
|
3524
3562
|
if (run.resultText && String(run.resultText).trim()) {
|
|
3525
|
-
const
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
viewBtn.textContent = '查看'
|
|
3529
|
-
viewBtn.addEventListener('click', function () {
|
|
3563
|
+
const wrap = document.createElement('div')
|
|
3564
|
+
wrap.className = 'manage-row-actions'
|
|
3565
|
+
wrap.appendChild(createManageRowBtn('查看', '', function () {
|
|
3530
3566
|
showScheduleRunResultText(run.resultText)
|
|
3531
|
-
})
|
|
3532
|
-
tdAction.appendChild(
|
|
3567
|
+
}))
|
|
3568
|
+
tdAction.appendChild(wrap)
|
|
3533
3569
|
}
|
|
3534
3570
|
tr.appendChild(tdId)
|
|
3535
3571
|
tr.appendChild(tdCreated)
|
|
@@ -3561,11 +3597,9 @@
|
|
|
3561
3597
|
return body
|
|
3562
3598
|
}
|
|
3563
3599
|
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
scheduleRunsModal.setAttribute('aria-hidden', 'true')
|
|
3568
|
-
document.body.style.overflow = ''
|
|
3600
|
+
/** 返回定时任务列表 */
|
|
3601
|
+
function closeScheduleRunsView() {
|
|
3602
|
+
setScheduleContentView('list')
|
|
3569
3603
|
scheduleRunsViewTaskId = null
|
|
3570
3604
|
scheduleRunsViewTaskName = ''
|
|
3571
3605
|
if (scheduleRunResultPre) {
|
|
@@ -3574,29 +3608,27 @@
|
|
|
3574
3608
|
}
|
|
3575
3609
|
}
|
|
3576
3610
|
|
|
3577
|
-
/**
|
|
3578
|
-
async function
|
|
3579
|
-
if (!
|
|
3611
|
+
/** 在主视图内打开执行记录面板 */
|
|
3612
|
+
async function openScheduleRunsView(taskId, taskName) {
|
|
3613
|
+
if (!scheduleManageView || !taskId) return
|
|
3580
3614
|
scheduleRunsViewTaskId = taskId
|
|
3581
3615
|
scheduleRunsViewTaskName = taskName || taskId
|
|
3582
|
-
if (
|
|
3583
|
-
|
|
3616
|
+
if (scheduleRunsTitle) {
|
|
3617
|
+
scheduleRunsTitle.textContent = '执行记录 · ' + scheduleRunsViewTaskName
|
|
3584
3618
|
}
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
'<tr><td colspan="7" style="padding:1rem;text-align:center;color:#8892a8">加载中…</td></tr>'
|
|
3619
|
+
setScheduleContentView('runs')
|
|
3620
|
+
if (scheduleRunsTableBody) scheduleRunsTableBody.innerHTML = ''
|
|
3621
|
+
if (scheduleRunsEmpty) {
|
|
3622
|
+
scheduleRunsEmpty.hidden = false
|
|
3623
|
+
scheduleRunsEmpty.textContent = '加载中…'
|
|
3591
3624
|
}
|
|
3592
3625
|
try {
|
|
3593
3626
|
await loadScheduleRuns(taskId)
|
|
3594
3627
|
} catch (e) {
|
|
3595
|
-
if (
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
'</td></tr>'
|
|
3628
|
+
if (scheduleRunsEmpty) {
|
|
3629
|
+
scheduleRunsEmpty.hidden = false
|
|
3630
|
+
scheduleRunsEmpty.textContent = '加载失败: ' + String(e)
|
|
3631
|
+
scheduleRunsEmpty.classList.add('is-error')
|
|
3600
3632
|
}
|
|
3601
3633
|
}
|
|
3602
3634
|
}
|
|
@@ -3619,7 +3651,7 @@
|
|
|
3619
3651
|
? '\n执行记录 ID: ' + run.id + '(状态: ' + scheduleRunStatusLabel(run.status) + ')'
|
|
3620
3652
|
: ''
|
|
3621
3653
|
window.alert('已加入执行队列' + runHint)
|
|
3622
|
-
if (scheduleRunsViewTaskId === id &&
|
|
3654
|
+
if (scheduleRunsViewTaskId === id && scheduleManageState.viewActive && scheduleManageState.contentView === 'runs') {
|
|
3623
3655
|
try {
|
|
3624
3656
|
await loadScheduleRuns(id)
|
|
3625
3657
|
} catch (e) {
|
|
@@ -3655,32 +3687,24 @@
|
|
|
3655
3687
|
await loadScheduleTasks()
|
|
3656
3688
|
}
|
|
3657
3689
|
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
if (
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
|
|
3668
|
-
if (!scheduleManageModal) return
|
|
3669
|
-
scheduleManageModal.classList.add('is-open')
|
|
3670
|
-
scheduleManageModal.setAttribute('aria-hidden', 'false')
|
|
3671
|
-
document.body.style.overflow = 'hidden'
|
|
3672
|
-
if (scheduleTaskTableBody) {
|
|
3673
|
-
scheduleTaskTableBody.innerHTML =
|
|
3674
|
-
'<tr><td colspan="8" style="padding:1rem;text-align:center;color:#8892a8">加载中…</td></tr>'
|
|
3690
|
+
/** 打开定时任务主视图 */
|
|
3691
|
+
async function openScheduleManageView() {
|
|
3692
|
+
if (!scheduleManageView) return
|
|
3693
|
+
setScheduleContentView('list')
|
|
3694
|
+
setScheduleManageVisible(true)
|
|
3695
|
+
if (scheduleTaskTableBody) scheduleTaskTableBody.innerHTML = ''
|
|
3696
|
+
if (scheduleManageEmpty) {
|
|
3697
|
+
scheduleManageEmpty.hidden = false
|
|
3698
|
+
scheduleManageEmpty.textContent = '加载中…'
|
|
3699
|
+
scheduleManageEmpty.classList.remove('is-error')
|
|
3675
3700
|
}
|
|
3676
3701
|
try {
|
|
3677
3702
|
await loadScheduleTasks()
|
|
3678
3703
|
} catch (e) {
|
|
3679
|
-
if (
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
'</td></tr>'
|
|
3704
|
+
if (scheduleManageEmpty) {
|
|
3705
|
+
scheduleManageEmpty.hidden = false
|
|
3706
|
+
scheduleManageEmpty.textContent = '加载失败: ' + String(e)
|
|
3707
|
+
scheduleManageEmpty.classList.add('is-error')
|
|
3684
3708
|
}
|
|
3685
3709
|
}
|
|
3686
3710
|
}
|
|
@@ -4733,6 +4757,8 @@
|
|
|
4733
4757
|
function switchToSession(id) {
|
|
4734
4758
|
closeRepoManageView()
|
|
4735
4759
|
closeAgentSettingsView()
|
|
4760
|
+
closePickerManageView()
|
|
4761
|
+
closeScheduleManageView(false)
|
|
4736
4762
|
const nextSid = typeof id === 'string' ? id : ''
|
|
4737
4763
|
sessionIdInput.value = nextSid
|
|
4738
4764
|
currentSessionContextPercent = null
|
|
@@ -6368,22 +6394,6 @@
|
|
|
6368
6394
|
}
|
|
6369
6395
|
}
|
|
6370
6396
|
|
|
6371
|
-
function closeAgentPickerModal() {
|
|
6372
|
-
if (!agentPickerModal) return
|
|
6373
|
-
agentPickerModal.classList.remove('is-open')
|
|
6374
|
-
agentPickerModal.setAttribute('aria-hidden', 'true')
|
|
6375
|
-
document.body.style.overflow = ''
|
|
6376
|
-
if (agentPickerModalCard) {
|
|
6377
|
-
agentPickerModalCard.classList.remove('agent-picker--tabbed')
|
|
6378
|
-
agentPickerModalCard.removeAttribute('aria-label')
|
|
6379
|
-
agentPickerModalCard.setAttribute('aria-labelledby', 'agentPickerModalTitle')
|
|
6380
|
-
}
|
|
6381
|
-
if (agentPickerSessionTabStrip) agentPickerSessionTabStrip.setAttribute('hidden', '')
|
|
6382
|
-
if (agentPickerSessionTabList) agentPickerSessionTabList.innerHTML = ''
|
|
6383
|
-
refreshToolPickerRows = null
|
|
6384
|
-
refreshMcpPickerRows = null
|
|
6385
|
-
refreshSkillPickerRows = null
|
|
6386
|
-
}
|
|
6387
6397
|
|
|
6388
6398
|
function closeMcpJsonInputModal() {
|
|
6389
6399
|
if (!mcpJsonInputModal) return
|
|
@@ -6413,62 +6423,12 @@
|
|
|
6413
6423
|
})
|
|
6414
6424
|
}
|
|
6415
6425
|
|
|
6416
|
-
function createPickerTabs(activeTab, onChange, options) {
|
|
6417
|
-
const wrap = document.createElement('div')
|
|
6418
|
-
wrap.className = 'agent-picker-tabs'
|
|
6419
|
-
const showCloud = !(options && options.hideCloud)
|
|
6420
|
-
const L = (options && options.tabLabels) || {}
|
|
6421
|
-
const tabs = [
|
|
6422
|
-
{ id: 'base', label: L.base || '基础工具列表' },
|
|
6423
|
-
{ id: 'installed', label: L.installed || '已安装工具列表' },
|
|
6424
|
-
]
|
|
6425
|
-
if (showCloud) tabs.push({ id: 'cloud', label: L.cloud || '云端工具列表' })
|
|
6426
|
-
for (let i = 0; i < tabs.length; i++) {
|
|
6427
|
-
const tab = tabs[i]
|
|
6428
|
-
const btn = document.createElement('button')
|
|
6429
|
-
btn.type = 'button'
|
|
6430
|
-
btn.className = 'btn-picker-tab' + (tab.id === activeTab ? ' is-on' : '')
|
|
6431
|
-
btn.textContent = tab.label
|
|
6432
|
-
btn.addEventListener('click', function () {
|
|
6433
|
-
if (tab.id === activeTab) return
|
|
6434
|
-
onChange(tab.id)
|
|
6435
|
-
})
|
|
6436
|
-
wrap.appendChild(btn)
|
|
6437
|
-
}
|
|
6438
|
-
return wrap
|
|
6439
|
-
}
|
|
6440
|
-
|
|
6441
|
-
function renderHeaderTabsIn(listEl, tabDefs, activeId, onChange) {
|
|
6442
|
-
if (!listEl) return
|
|
6443
|
-
listEl.innerHTML = ''
|
|
6444
|
-
for (let i = 0; i < tabDefs.length; i++) {
|
|
6445
|
-
const tab = tabDefs[i]
|
|
6446
|
-
const btn = document.createElement('button')
|
|
6447
|
-
btn.type = 'button'
|
|
6448
|
-
btn.className = 'session-tab' + (tab.id === activeId ? ' active' : '')
|
|
6449
|
-
btn.setAttribute('role', 'tab')
|
|
6450
|
-
btn.setAttribute('aria-selected', tab.id === activeId ? 'true' : 'false')
|
|
6451
|
-
const span = document.createElement('span')
|
|
6452
|
-
span.className = 'session-tab-label'
|
|
6453
|
-
span.textContent = tab.label
|
|
6454
|
-
btn.appendChild(span)
|
|
6455
|
-
btn.addEventListener('click', function () {
|
|
6456
|
-
if (tab.id === activeId) return
|
|
6457
|
-
onChange(tab.id)
|
|
6458
|
-
})
|
|
6459
|
-
listEl.appendChild(btn)
|
|
6460
|
-
}
|
|
6461
|
-
}
|
|
6462
|
-
function renderPickerHeaderTabs(tabDefs, activeId, onChange) {
|
|
6463
|
-
renderHeaderTabsIn(agentPickerSessionTabList, tabDefs, activeId, onChange)
|
|
6464
|
-
}
|
|
6465
|
-
|
|
6466
6426
|
function createCloudPager(state, onPageChange) {
|
|
6467
6427
|
const pager = document.createElement('div')
|
|
6468
6428
|
pager.className = 'agent-picker-cloud-pager'
|
|
6469
6429
|
const prev = document.createElement('button')
|
|
6470
6430
|
prev.type = 'button'
|
|
6471
|
-
prev.className = 'btn-
|
|
6431
|
+
prev.className = 'btn-manage-row-action'
|
|
6472
6432
|
prev.textContent = '上一页'
|
|
6473
6433
|
prev.disabled = state.page <= 1 || state.loading
|
|
6474
6434
|
prev.addEventListener('click', function () {
|
|
@@ -6477,7 +6437,7 @@
|
|
|
6477
6437
|
})
|
|
6478
6438
|
const next = document.createElement('button')
|
|
6479
6439
|
next.type = 'button'
|
|
6480
|
-
next.className = 'btn-
|
|
6440
|
+
next.className = 'btn-manage-row-action'
|
|
6481
6441
|
next.textContent = '下一页'
|
|
6482
6442
|
const totalPages = state.totalPages || 0
|
|
6483
6443
|
next.disabled = state.loading || totalPages <= 0 || state.page >= totalPages
|
|
@@ -6494,176 +6454,49 @@
|
|
|
6494
6454
|
return pager
|
|
6495
6455
|
}
|
|
6496
6456
|
|
|
6497
|
-
|
|
6457
|
+
/** 打开 Picker 主视图:工具 / MCP / Skill / Teams */
|
|
6458
|
+
function openPickerManageView(kind) {
|
|
6459
|
+
if (!pickerManageView) return
|
|
6460
|
+
pickerManageState.kind = kind
|
|
6498
6461
|
pickerKind = kind
|
|
6499
|
-
|
|
6462
|
+
pickerManageState.draftSelected.clear()
|
|
6500
6463
|
if (kind === 'tools') {
|
|
6501
6464
|
for (let i = 0; i < agentConfigState.tools.length; i++) {
|
|
6502
|
-
|
|
6465
|
+
pickerManageState.draftSelected.add(agentConfigState.tools[i])
|
|
6503
6466
|
}
|
|
6504
6467
|
} else if (kind === 'mcp') {
|
|
6505
6468
|
for (let i = 0; i < agentConfigState.mcpServers.length; i++) {
|
|
6506
|
-
|
|
6469
|
+
pickerManageState.draftSelected.add(agentConfigState.mcpServers[i])
|
|
6507
6470
|
}
|
|
6508
6471
|
} else if (kind === 'agentTeams') {
|
|
6509
6472
|
for (let i = 0; i < agentConfigState.agentTeams.length; i++) {
|
|
6510
|
-
|
|
6473
|
+
pickerManageState.draftSelected.add(agentConfigState.agentTeams[i])
|
|
6511
6474
|
}
|
|
6512
6475
|
} else {
|
|
6513
6476
|
for (let i = 0; i < agentConfigState.skills.length; i++) {
|
|
6514
|
-
|
|
6515
|
-
}
|
|
6516
|
-
}
|
|
6517
|
-
|
|
6518
|
-
|
|
6519
|
-
|
|
6520
|
-
|
|
6521
|
-
|
|
6522
|
-
|
|
6523
|
-
|
|
6524
|
-
|
|
6525
|
-
|
|
6526
|
-
|
|
6527
|
-
|
|
6528
|
-
|
|
6529
|
-
|
|
6530
|
-
|
|
6531
|
-
|
|
6532
|
-
|
|
6533
|
-
|
|
6534
|
-
|
|
6535
|
-
|
|
6536
|
-
|
|
6537
|
-
agentPickerSessionTabStrip.setAttribute('aria-label', 'MCP 分类')
|
|
6538
|
-
} else {
|
|
6539
|
-
agentPickerSessionTabStrip.setAttribute('aria-label', 'Teams 分类')
|
|
6540
|
-
}
|
|
6541
|
-
agentPickerSessionTabStrip.removeAttribute('hidden')
|
|
6542
|
-
}
|
|
6543
|
-
} else {
|
|
6544
|
-
agentPickerModalCard.classList.remove('agent-picker--tabbed')
|
|
6545
|
-
agentPickerModalCard.removeAttribute('aria-label')
|
|
6546
|
-
agentPickerModalCard.setAttribute('aria-labelledby', 'agentPickerModalTitle')
|
|
6547
|
-
if (agentPickerSessionTabStrip) agentPickerSessionTabStrip.setAttribute('hidden', '')
|
|
6548
|
-
if (agentPickerSessionTabList) agentPickerSessionTabList.innerHTML = ''
|
|
6549
|
-
}
|
|
6550
|
-
}
|
|
6551
|
-
agentPickerModal.classList.add('is-open')
|
|
6552
|
-
agentPickerModal.setAttribute('aria-hidden', 'false')
|
|
6553
|
-
document.body.style.overflow = 'hidden'
|
|
6554
|
-
if (agentPickerSearch) agentPickerSearch.value = ''
|
|
6555
|
-
const titles = {
|
|
6556
|
-
tools: '工具',
|
|
6557
|
-
mcp: 'MCP',
|
|
6558
|
-
skills: 'Skill',
|
|
6559
|
-
agentTeams: 'Teams',
|
|
6560
|
-
}
|
|
6561
|
-
agentPickerModalTitle.textContent = titles[kind] || '选择'
|
|
6562
|
-
if (btnAgentPickerToolImport) {
|
|
6563
|
-
btnAgentPickerToolImport.style.display =
|
|
6564
|
-
kind === 'tools' || kind === 'mcp' || kind === 'skills' ? '' : 'none'
|
|
6565
|
-
const importLabel =
|
|
6566
|
-
kind === 'mcp' ? '导入MCP' : kind === 'skills' ? '导入Skill' : '导入zip'
|
|
6567
|
-
btnAgentPickerToolImport.setAttribute('aria-label', importLabel)
|
|
6568
|
-
btnAgentPickerToolImport.setAttribute('title', importLabel)
|
|
6569
|
-
btnAgentPickerToolImport.disabled = false
|
|
6570
|
-
}
|
|
6571
|
-
if (btnAgentPickerMcpJson) {
|
|
6572
|
-
btnAgentPickerMcpJson.style.display = kind === 'mcp' ? '' : 'none'
|
|
6573
|
-
btnAgentPickerMcpJson.disabled = false
|
|
6574
|
-
}
|
|
6575
|
-
agentPickerList.innerHTML = '加载中…'
|
|
6576
|
-
|
|
6577
|
-
function renderList(rows, labelFn) {
|
|
6578
|
-
if (!agentPickerList) return
|
|
6579
|
-
agentPickerList.innerHTML = ''
|
|
6580
|
-
const q = (agentPickerSearch && agentPickerSearch.value.trim().toLowerCase()) || ''
|
|
6581
|
-
const frag = document.createDocumentFragment()
|
|
6582
|
-
for (let i = 0; i < rows.length; i++) {
|
|
6583
|
-
const row = rows[i]
|
|
6584
|
-
const id = row.id
|
|
6585
|
-
const lab = labelFn(row)
|
|
6586
|
-
if (q && String(lab).toLowerCase().indexOf(q) < 0 && String(id).toLowerCase().indexOf(q) < 0) {
|
|
6587
|
-
continue
|
|
6588
|
-
}
|
|
6589
|
-
const div = document.createElement('div')
|
|
6590
|
-
div.className = 'agent-picker-item'
|
|
6591
|
-
const labelEl = document.createElement('div')
|
|
6592
|
-
labelEl.className = 'agent-picker-item-label'
|
|
6593
|
-
labelEl.textContent = String(lab)
|
|
6594
|
-
div.appendChild(labelEl)
|
|
6595
|
-
|
|
6596
|
-
const actions = document.createElement('div')
|
|
6597
|
-
actions.className = 'agent-picker-actions'
|
|
6598
|
-
|
|
6599
|
-
const toggleBtn = document.createElement('button')
|
|
6600
|
-
toggleBtn.type = 'button'
|
|
6601
|
-
const selected = pickerSelected.has(id)
|
|
6602
|
-
toggleBtn.className = 'btn-picker-action' + (selected ? ' is-on' : '')
|
|
6603
|
-
toggleBtn.textContent = selected ? '禁用' : '启用'
|
|
6604
|
-
toggleBtn.addEventListener('click', function () {
|
|
6605
|
-
if (pickerSelected.has(id)) pickerSelected.delete(id)
|
|
6606
|
-
else pickerSelected.add(id)
|
|
6607
|
-
renderList(rows, labelFn)
|
|
6608
|
-
})
|
|
6609
|
-
actions.appendChild(toggleBtn)
|
|
6610
|
-
|
|
6611
|
-
if (pickerKind === 'tools') {
|
|
6612
|
-
const delBtn = document.createElement('button')
|
|
6613
|
-
delBtn.type = 'button'
|
|
6614
|
-
delBtn.className = 'btn-picker-action is-delete'
|
|
6615
|
-
delBtn.textContent = '删除'
|
|
6616
|
-
const isSystemTool = !(row.t && row.t.isRuntime === true)
|
|
6617
|
-
delBtn.disabled = isSystemTool
|
|
6618
|
-
if (isSystemTool) {
|
|
6619
|
-
delBtn.title = '系统工具不可删除'
|
|
6620
|
-
}
|
|
6621
|
-
delBtn.addEventListener('click', function () {
|
|
6622
|
-
if (delBtn.disabled) return
|
|
6623
|
-
const targetTool = id
|
|
6624
|
-
const ok = window.confirm('确认删除工具包?\n工具名:' + targetTool)
|
|
6625
|
-
if (!ok) return
|
|
6626
|
-
delBtn.disabled = true
|
|
6627
|
-
fetch(buildRuntimeToolDeleteUrl(targetTool), { method: 'DELETE' })
|
|
6628
|
-
.then(function (r) {
|
|
6629
|
-
return r.json().catch(function () {
|
|
6630
|
-
return {}
|
|
6631
|
-
}).then(function (b) {
|
|
6632
|
-
return { r: r, b: b }
|
|
6633
|
-
})
|
|
6634
|
-
})
|
|
6635
|
-
.then(function (x) {
|
|
6636
|
-
if (!x.r.ok) throw new Error(x.b.message || x.r.statusText)
|
|
6637
|
-
pickerSelected.delete(targetTool)
|
|
6638
|
-
const nextRows = rows.filter(function (item) {
|
|
6639
|
-
return item.id !== targetTool
|
|
6640
|
-
})
|
|
6641
|
-
rows.splice(0, rows.length)
|
|
6642
|
-
for (let j = 0; j < nextRows.length; j++) rows.push(nextRows[j])
|
|
6643
|
-
renderList(rows, labelFn)
|
|
6644
|
-
agentConfigState.tools = agentConfigState.tools.filter(function (name) {
|
|
6645
|
-
return name !== targetTool
|
|
6646
|
-
})
|
|
6647
|
-
renderBindChips()
|
|
6648
|
-
void persistAgentConfigAndRestartSession({ silent: true })
|
|
6649
|
-
})
|
|
6650
|
-
.catch(function (e) {
|
|
6651
|
-
window.alert('删除失败: ' + e)
|
|
6652
|
-
delBtn.disabled = false
|
|
6653
|
-
})
|
|
6654
|
-
})
|
|
6655
|
-
actions.appendChild(delBtn)
|
|
6656
|
-
}
|
|
6657
|
-
|
|
6658
|
-
div.appendChild(actions)
|
|
6659
|
-
frag.appendChild(div)
|
|
6660
|
-
}
|
|
6661
|
-
if (!frag.childNodes.length) {
|
|
6662
|
-
agentPickerList.textContent = '(无匹配项)'
|
|
6663
|
-
return
|
|
6664
|
-
}
|
|
6665
|
-
agentPickerList.appendChild(frag)
|
|
6666
|
-
}
|
|
6477
|
+
pickerManageState.draftSelected.add(agentConfigState.skills[i])
|
|
6478
|
+
}
|
|
6479
|
+
}
|
|
6480
|
+
pickerSelected = pickerManageState.draftSelected
|
|
6481
|
+
setPickerManageVisible(true)
|
|
6482
|
+
if (mainTitleEl) mainTitleEl.textContent = PICKER_KIND_TITLES[kind] || '管理'
|
|
6483
|
+
if (pickerSearch) pickerSearch.value = ''
|
|
6484
|
+
if (btnPickerImport) {
|
|
6485
|
+
btnPickerImport.hidden = !(kind === 'tools' || kind === 'mcp' || kind === 'skills')
|
|
6486
|
+
btnPickerImport.textContent =
|
|
6487
|
+
kind === 'mcp' ? '导入 MCP' : kind === 'skills' ? '导入 Skill' : '导入 zip'
|
|
6488
|
+
btnPickerImport.disabled = false
|
|
6489
|
+
}
|
|
6490
|
+
if (btnPickerMcpJson) {
|
|
6491
|
+
btnPickerMcpJson.hidden = kind !== 'mcp'
|
|
6492
|
+
btnPickerMcpJson.disabled = false
|
|
6493
|
+
}
|
|
6494
|
+
if (btnPickerCancel) btnPickerCancel.hidden = kind === 'skills' || kind === 'mcp'
|
|
6495
|
+
if (btnPickerSave) btnPickerSave.hidden = kind === 'skills' || kind === 'mcp'
|
|
6496
|
+
setPickerNavPanelVisible(kind === 'skills')
|
|
6497
|
+
setPickerContentState('加载中…', false)
|
|
6498
|
+
setPickerContentMode('table')
|
|
6499
|
+
clearPickerTableBody()
|
|
6667
6500
|
|
|
6668
6501
|
if (kind === 'tools') {
|
|
6669
6502
|
const toolPickerState = {
|
|
@@ -6717,49 +6550,33 @@
|
|
|
6717
6550
|
})
|
|
6718
6551
|
})
|
|
6719
6552
|
}
|
|
6720
|
-
const
|
|
6553
|
+
const makeToolTableRow = function (row) {
|
|
6721
6554
|
const id = row.id
|
|
6722
6555
|
const canDelete = row.deletable === true
|
|
6723
6556
|
const packageId = row.packageId || ''
|
|
6724
|
-
const
|
|
6725
|
-
|
|
6726
|
-
|
|
6727
|
-
|
|
6728
|
-
|
|
6729
|
-
|
|
6730
|
-
|
|
6731
|
-
|
|
6732
|
-
const toggleBtn = document.createElement('button')
|
|
6733
|
-
toggleBtn.type = 'button'
|
|
6557
|
+
const tr = document.createElement('tr')
|
|
6558
|
+
const nameTd = document.createElement('td')
|
|
6559
|
+
nameTd.textContent = toolLabel(row)
|
|
6560
|
+
tr.appendChild(nameTd)
|
|
6561
|
+
const typeTd = document.createElement('td')
|
|
6562
|
+
const layer = row.t && row.t.layer === 'system' ? '系统' : row.t && row.t.layer === 'agent' ? 'Agent' : '—'
|
|
6563
|
+
typeTd.textContent = layer
|
|
6564
|
+
tr.appendChild(typeTd)
|
|
6734
6565
|
const selected = pickerSelected.has(id)
|
|
6735
|
-
|
|
6736
|
-
|
|
6737
|
-
|
|
6738
|
-
|
|
6739
|
-
|
|
6740
|
-
|
|
6741
|
-
|
|
6742
|
-
actions.appendChild(toggleBtn)
|
|
6566
|
+
const buttons = [
|
|
6567
|
+
createManageRowBtn(selected ? '禁用' : '启用', selected ? 'is-on' : '', function () {
|
|
6568
|
+
if (pickerSelected.has(id)) pickerSelected.delete(id)
|
|
6569
|
+
else pickerSelected.add(id)
|
|
6570
|
+
renderToolsRows()
|
|
6571
|
+
}),
|
|
6572
|
+
]
|
|
6743
6573
|
if (canDelete && packageId) {
|
|
6744
|
-
|
|
6745
|
-
exportBtn.type = 'button'
|
|
6746
|
-
exportBtn.className = 'btn-picker-action'
|
|
6747
|
-
exportBtn.textContent = '导出'
|
|
6748
|
-
exportBtn.addEventListener('click', function () {
|
|
6574
|
+
buttons.push(createManageRowBtn('导出', '', function () {
|
|
6749
6575
|
window.open(buildRuntimeToolExportUrl(packageId), '_blank', 'noopener')
|
|
6750
|
-
})
|
|
6751
|
-
actions.appendChild(exportBtn)
|
|
6576
|
+
}))
|
|
6752
6577
|
}
|
|
6753
|
-
|
|
6754
|
-
|
|
6755
|
-
delBtn.className = 'btn-picker-action is-delete'
|
|
6756
|
-
delBtn.textContent = '删除'
|
|
6757
|
-
delBtn.disabled = !canDelete || !packageId
|
|
6758
|
-
if (!canDelete) {
|
|
6759
|
-
delBtn.title = '系统内置工具不可删除'
|
|
6760
|
-
}
|
|
6761
|
-
delBtn.addEventListener('click', function () {
|
|
6762
|
-
if (delBtn.disabled) return
|
|
6578
|
+
buttons.push(createManageRowBtn('删除', 'is-delete', function () {
|
|
6579
|
+
if (!canDelete || !packageId) return
|
|
6763
6580
|
fetch(buildRuntimeToolDeleteUrl(packageId), { method: 'DELETE' })
|
|
6764
6581
|
.then(function (r) {
|
|
6765
6582
|
return r.json().catch(function () { return {} }).then(function (b) { return { r: r, b: b } })
|
|
@@ -6773,23 +6590,28 @@
|
|
|
6773
6590
|
return refreshToolPickerRows()
|
|
6774
6591
|
})
|
|
6775
6592
|
.catch(function (e) { window.alert('删除失败: ' + e) })
|
|
6776
|
-
})
|
|
6777
|
-
|
|
6778
|
-
|
|
6779
|
-
return div
|
|
6593
|
+
}, { disabled: !canDelete || !packageId, title: !canDelete ? '系统内置工具不可删除' : '' }))
|
|
6594
|
+
tr.appendChild(createManageActionsTd(buttons))
|
|
6595
|
+
return tr
|
|
6780
6596
|
}
|
|
6781
6597
|
const renderToolsRows = function () {
|
|
6782
|
-
|
|
6783
|
-
|
|
6784
|
-
|
|
6598
|
+
setPickerContentMode('table')
|
|
6599
|
+
setPickerTableHead(['名称', '类型', '操作'])
|
|
6600
|
+
clearPickerTableBody()
|
|
6601
|
+
setPickerContentState('', false)
|
|
6602
|
+
const q = getPickerSearchQuery()
|
|
6603
|
+
const rows = toolPickerState.installedRows.filter(function (row) {
|
|
6604
|
+
return toolMatches(row, q)
|
|
6605
|
+
})
|
|
6785
6606
|
if (!rows.length) {
|
|
6786
|
-
|
|
6607
|
+
setPickerContentState(toolPickerState.installedRows.length ? '(无匹配项)' : '(暂无已安装工具)', false)
|
|
6787
6608
|
return
|
|
6788
6609
|
}
|
|
6789
|
-
|
|
6790
|
-
|
|
6791
|
-
|
|
6610
|
+
const frag = document.createDocumentFragment()
|
|
6611
|
+
for (let i = 0; i < rows.length; i++) frag.appendChild(makeToolTableRow(rows[i]))
|
|
6612
|
+
if (pickerEntriesBody) pickerEntriesBody.appendChild(frag)
|
|
6792
6613
|
}
|
|
6614
|
+
pickerRenderContent = renderToolsRows
|
|
6793
6615
|
refreshToolPickerRows = function () {
|
|
6794
6616
|
return fetchToolRows(buildToolInstalledListUrl).then(function (rows) {
|
|
6795
6617
|
toolPickerState.installedRows = rows
|
|
@@ -6797,12 +6619,9 @@
|
|
|
6797
6619
|
})
|
|
6798
6620
|
}
|
|
6799
6621
|
void refreshToolPickerRows().catch(function (e) {
|
|
6800
|
-
|
|
6622
|
+
setPickerContentState('加载失败: ' + e, true)
|
|
6801
6623
|
})
|
|
6802
6624
|
} else if (kind === 'mcp') {
|
|
6803
|
-
const mcpPickerState = {
|
|
6804
|
-
activeTab: 'base',
|
|
6805
|
-
}
|
|
6806
6625
|
fetch(buildMcpServersListUrl())
|
|
6807
6626
|
.then(function (r) {
|
|
6808
6627
|
return r.json().then(function (b) {
|
|
@@ -6818,231 +6637,153 @@
|
|
|
6818
6637
|
const mcpLabel = function (row) {
|
|
6819
6638
|
return row.s.name + (row.s.disabled ? '(已禁用)' : '')
|
|
6820
6639
|
}
|
|
6821
|
-
|
|
6640
|
+
/** 将 MCP 启用状态写入 agent 配置并立即持久化 */
|
|
6641
|
+
const persistMcpSelectionNow = function () {
|
|
6642
|
+
agentConfigState.mcpServers = [...pickerSelected].sort()
|
|
6643
|
+
renderBindChips()
|
|
6644
|
+
return persistAgentConfigAndRestartSession({ silent: true })
|
|
6645
|
+
}
|
|
6646
|
+
const mcpSourceLabel = function (source) {
|
|
6647
|
+
if (source === 'runtime') return '本地'
|
|
6648
|
+
if (source === 'remote') return '远程'
|
|
6649
|
+
return source || '—'
|
|
6650
|
+
}
|
|
6651
|
+
const makeMcpTableRow = function (row, opts) {
|
|
6822
6652
|
const options = opts || {}
|
|
6823
6653
|
const showExport = !!options.showExport
|
|
6824
6654
|
const showDelete = !!options.showDelete
|
|
6825
|
-
const
|
|
6826
|
-
|
|
6827
|
-
const
|
|
6828
|
-
|
|
6829
|
-
|
|
6830
|
-
|
|
6831
|
-
|
|
6832
|
-
|
|
6833
|
-
|
|
6834
|
-
|
|
6835
|
-
|
|
6836
|
-
|
|
6655
|
+
const id = row.id
|
|
6656
|
+
const source = row.s && row.s.source ? String(row.s.source) : ''
|
|
6657
|
+
const tr = document.createElement('tr')
|
|
6658
|
+
const nameTd = document.createElement('td')
|
|
6659
|
+
nameTd.textContent = mcpLabel(row)
|
|
6660
|
+
tr.appendChild(nameTd)
|
|
6661
|
+
const sourceTd = document.createElement('td')
|
|
6662
|
+
sourceTd.textContent = mcpSourceLabel(source)
|
|
6663
|
+
tr.appendChild(sourceTd)
|
|
6664
|
+
const buttons = []
|
|
6665
|
+
if (showExport) {
|
|
6666
|
+
const canExport = source === 'runtime'
|
|
6667
|
+
buttons.push(createManageRowBtn('导出', '', function () {
|
|
6668
|
+
if (!canExport) return
|
|
6669
|
+
const pkgId = row.s && row.s.packageId ? String(row.s.packageId) : id
|
|
6670
|
+
window.open(buildRuntimeMcpExportUrl(pkgId), '_blank', 'noopener')
|
|
6671
|
+
}, { disabled: !canExport, title: !canExport ? '仅 runtime MCP 支持导出' : '' }))
|
|
6837
6672
|
}
|
|
6838
|
-
|
|
6839
|
-
const
|
|
6840
|
-
|
|
6841
|
-
|
|
6842
|
-
|
|
6843
|
-
div.className = 'agent-picker-item'
|
|
6844
|
-
const labelEl = document.createElement('div')
|
|
6845
|
-
labelEl.className = 'agent-picker-item-label'
|
|
6846
|
-
labelEl.textContent = mcpLabel(row)
|
|
6847
|
-
div.appendChild(labelEl)
|
|
6848
|
-
const actions = document.createElement('div')
|
|
6849
|
-
actions.className = 'agent-picker-actions'
|
|
6850
|
-
if (showExport) {
|
|
6851
|
-
const exportBtn = document.createElement('button')
|
|
6852
|
-
exportBtn.type = 'button'
|
|
6853
|
-
exportBtn.className = 'btn-picker-action'
|
|
6854
|
-
exportBtn.textContent = '导出'
|
|
6855
|
-
const canExport = source === 'runtime'
|
|
6856
|
-
exportBtn.disabled = !canExport
|
|
6857
|
-
if (!canExport) {
|
|
6858
|
-
exportBtn.title = '仅 runtime MCP 支持导出'
|
|
6673
|
+
buttons.push(createManageRowBtn('编辑', '', function () {
|
|
6674
|
+
const src = source === 'remote' ? 'remote' : 'runtime'
|
|
6675
|
+
openMcpItemConfigEditor(id, src, function () {
|
|
6676
|
+
if (typeof refreshMcpPickerRows === 'function') {
|
|
6677
|
+
void refreshMcpPickerRows().then(function () { renderMcpRows() })
|
|
6859
6678
|
}
|
|
6860
|
-
|
|
6861
|
-
|
|
6862
|
-
|
|
6863
|
-
|
|
6679
|
+
})
|
|
6680
|
+
}))
|
|
6681
|
+
const selected = pickerSelected.has(id)
|
|
6682
|
+
const toggleBtn = createManageRowBtn(selected ? '禁用' : '启用', selected ? 'is-on' : '', function () {
|
|
6683
|
+
toggleBtn.disabled = true
|
|
6684
|
+
if (pickerSelected.has(id)) pickerSelected.delete(id)
|
|
6685
|
+
else pickerSelected.add(id)
|
|
6686
|
+
persistMcpSelectionNow()
|
|
6687
|
+
.then(function () {
|
|
6688
|
+
renderMcpRows()
|
|
6864
6689
|
})
|
|
6865
|
-
|
|
6866
|
-
|
|
6867
|
-
const editBtn = document.createElement('button')
|
|
6868
|
-
editBtn.type = 'button'
|
|
6869
|
-
editBtn.className = 'btn-picker-action'
|
|
6870
|
-
editBtn.textContent = '编辑'
|
|
6871
|
-
editBtn.addEventListener('click', function () {
|
|
6872
|
-
const src = source === 'remote' ? 'remote' : 'runtime'
|
|
6873
|
-
openMcpItemConfigEditor(id, src, function () {
|
|
6874
|
-
if (typeof refreshMcpPickerRows === 'function') {
|
|
6875
|
-
void refreshMcpPickerRows().then(function () {
|
|
6876
|
-
renderMcpRows()
|
|
6877
|
-
})
|
|
6878
|
-
}
|
|
6690
|
+
.catch(function (e) {
|
|
6691
|
+
window.alert('切换启用状态失败: ' + e)
|
|
6879
6692
|
})
|
|
6880
|
-
|
|
6881
|
-
|
|
6882
|
-
const toggleBtn = document.createElement('button')
|
|
6883
|
-
toggleBtn.type = 'button'
|
|
6884
|
-
toggleBtn.className = 'btn-picker-action'
|
|
6885
|
-
const enabledNow = pickerSelected.has(id)
|
|
6886
|
-
toggleBtn.textContent = enabledNow ? '禁用' : '启用'
|
|
6887
|
-
toggleBtn.addEventListener('click', function () {
|
|
6888
|
-
toggleBtn.disabled = true
|
|
6889
|
-
if (enabledNow) {
|
|
6890
|
-
pickerSelected.delete(id)
|
|
6891
|
-
agentConfigState.mcpServers = agentConfigState.mcpServers.filter(function (name) {
|
|
6892
|
-
return name !== id
|
|
6893
|
-
})
|
|
6894
|
-
} else {
|
|
6895
|
-
pickerSelected.add(id)
|
|
6896
|
-
if (agentConfigState.mcpServers.indexOf(id) < 0) {
|
|
6897
|
-
agentConfigState.mcpServers.push(id)
|
|
6898
|
-
}
|
|
6899
|
-
}
|
|
6900
|
-
persistAgentConfigAndRestartSession({ silent: true })
|
|
6901
|
-
.then(function () {
|
|
6902
|
-
renderBindChips()
|
|
6903
|
-
renderMcpRows()
|
|
6904
|
-
})
|
|
6905
|
-
.catch(function (e) {
|
|
6906
|
-
window.alert('切换启用状态失败: ' + e)
|
|
6693
|
+
.finally(function () {
|
|
6694
|
+
toggleBtn.disabled = false
|
|
6907
6695
|
})
|
|
6908
|
-
|
|
6909
|
-
|
|
6910
|
-
|
|
6911
|
-
|
|
6912
|
-
|
|
6913
|
-
|
|
6914
|
-
const
|
|
6915
|
-
|
|
6916
|
-
|
|
6917
|
-
|
|
6918
|
-
const canDelete = source === 'runtime' || source === 'remote'
|
|
6919
|
-
delBtn.disabled = !canDelete
|
|
6920
|
-
if (!canDelete) {
|
|
6921
|
-
delBtn.title = '基础MCP不可删除'
|
|
6922
|
-
}
|
|
6923
|
-
delBtn.addEventListener('click', function () {
|
|
6924
|
-
if (delBtn.disabled) return
|
|
6925
|
-
const ok = window.confirm('确认删除 MCP?\n服务器名:' + id)
|
|
6926
|
-
if (!ok) return
|
|
6927
|
-
delBtn.disabled = true
|
|
6928
|
-
if (source === 'remote') {
|
|
6929
|
-
fetch(buildRemoteMcpJsonUrl())
|
|
6930
|
-
.then(function (r) {
|
|
6931
|
-
return r.json().then(function (body) {
|
|
6932
|
-
return { r: r, body: body }
|
|
6933
|
-
})
|
|
6934
|
-
})
|
|
6935
|
-
.then(function (x) {
|
|
6936
|
-
if (!x.r.ok) throw new Error(x.body.message || x.body.error || x.r.statusText)
|
|
6937
|
-
let parsed
|
|
6938
|
-
try {
|
|
6939
|
-
parsed = JSON.parse(String(x.body.content || '{}'))
|
|
6940
|
-
} catch {
|
|
6941
|
-
parsed = { mcpServers: {} }
|
|
6942
|
-
}
|
|
6943
|
-
if (!parsed.mcpServers || typeof parsed.mcpServers !== 'object' || Array.isArray(parsed.mcpServers)) {
|
|
6944
|
-
parsed.mcpServers = {}
|
|
6945
|
-
}
|
|
6946
|
-
delete parsed.mcpServers[id]
|
|
6947
|
-
return fetch(buildRemoteMcpJsonUrl(), {
|
|
6948
|
-
method: 'POST',
|
|
6949
|
-
headers: { 'Content-Type': 'application/json; charset=utf-8' },
|
|
6950
|
-
body: JSON.stringify({ content: JSON.stringify(parsed, null, 2) }),
|
|
6951
|
-
})
|
|
6952
|
-
})
|
|
6953
|
-
.then(function (r) {
|
|
6954
|
-
return r.json().then(function (body) {
|
|
6955
|
-
return { r: r, body: body }
|
|
6956
|
-
})
|
|
6957
|
-
})
|
|
6958
|
-
.then(function (x) {
|
|
6959
|
-
if (!x.r.ok) throw new Error(x.body.message || x.body.error || x.r.statusText)
|
|
6960
|
-
remoteMcpServers = Array.isArray(x.body.servers)
|
|
6961
|
-
? x.body.servers.map(String)
|
|
6962
|
-
: []
|
|
6963
|
-
pickerSelected.delete(id)
|
|
6964
|
-
agentConfigState.mcpServers = agentConfigState.mcpServers.filter(function (name) {
|
|
6965
|
-
return name !== id
|
|
6966
|
-
})
|
|
6967
|
-
renderBindChips()
|
|
6968
|
-
renderMcpRows()
|
|
6969
|
-
})
|
|
6970
|
-
.catch(function (e) {
|
|
6971
|
-
window.alert('删除失败: ' + e)
|
|
6972
|
-
})
|
|
6973
|
-
.finally(function () {
|
|
6974
|
-
delBtn.disabled = !canDelete
|
|
6975
|
-
})
|
|
6976
|
-
return
|
|
6977
|
-
}
|
|
6978
|
-
const pkgId = row.s && row.s.packageId ? String(row.s.packageId) : id
|
|
6979
|
-
fetch(buildRuntimeMcpDeleteUrl(pkgId), { method: 'DELETE' })
|
|
6696
|
+
})
|
|
6697
|
+
buttons.push(toggleBtn)
|
|
6698
|
+
if (showDelete) {
|
|
6699
|
+
const canDelete = source === 'runtime' || source === 'remote'
|
|
6700
|
+
buttons.push(createManageRowBtn('删除', 'is-delete', function () {
|
|
6701
|
+
if (!canDelete) return
|
|
6702
|
+
const ok = window.confirm('确认删除 MCP?\n服务器名:' + id)
|
|
6703
|
+
if (!ok) return
|
|
6704
|
+
if (source === 'remote') {
|
|
6705
|
+
fetch(buildRemoteMcpJsonUrl())
|
|
6980
6706
|
.then(function (r) {
|
|
6981
|
-
return r.json().
|
|
6982
|
-
|
|
6983
|
-
|
|
6984
|
-
|
|
6707
|
+
return r.json().then(function (body) { return { r: r, body: body } })
|
|
6708
|
+
})
|
|
6709
|
+
.then(function (x) {
|
|
6710
|
+
if (!x.r.ok) throw new Error(x.body.message || x.body.error || x.r.statusText)
|
|
6711
|
+
let parsed
|
|
6712
|
+
try { parsed = JSON.parse(String(x.body.content || '{}')) } catch { parsed = { mcpServers: {} } }
|
|
6713
|
+
if (!parsed.mcpServers || typeof parsed.mcpServers !== 'object' || Array.isArray(parsed.mcpServers)) {
|
|
6714
|
+
parsed.mcpServers = {}
|
|
6715
|
+
}
|
|
6716
|
+
delete parsed.mcpServers[id]
|
|
6717
|
+
return fetch(buildRemoteMcpJsonUrl(), {
|
|
6718
|
+
method: 'POST',
|
|
6719
|
+
headers: { 'Content-Type': 'application/json; charset=utf-8' },
|
|
6720
|
+
body: JSON.stringify({ content: JSON.stringify(parsed, null, 2) }),
|
|
6985
6721
|
})
|
|
6986
6722
|
})
|
|
6723
|
+
.then(function (r) {
|
|
6724
|
+
return r.json().then(function (body) { return { r: r, body: body } })
|
|
6725
|
+
})
|
|
6987
6726
|
.then(function (x) {
|
|
6988
|
-
if (!x.r.ok) throw new Error(x.
|
|
6727
|
+
if (!x.r.ok) throw new Error(x.body.message || x.body.error || x.r.statusText)
|
|
6728
|
+
remoteMcpServers = Array.isArray(x.body.servers) ? x.body.servers.map(String) : []
|
|
6989
6729
|
pickerSelected.delete(id)
|
|
6990
|
-
agentConfigState.mcpServers = agentConfigState.mcpServers.filter(function (name) {
|
|
6991
|
-
return name !== id
|
|
6992
|
-
})
|
|
6730
|
+
agentConfigState.mcpServers = agentConfigState.mcpServers.filter(function (name) { return name !== id })
|
|
6993
6731
|
renderBindChips()
|
|
6994
6732
|
return Promise.all([
|
|
6995
6733
|
persistAgentConfigAndRestartSession({ silent: true }),
|
|
6996
|
-
|
|
6997
|
-
|
|
6998
|
-
return r.json().then(function (b) {
|
|
6999
|
-
return { r: r, b: b }
|
|
7000
|
-
})
|
|
7001
|
-
})
|
|
7002
|
-
.then(function (res) {
|
|
7003
|
-
if (!res.r.ok) throw new Error(res.b.message || res.r.statusText)
|
|
7004
|
-
const serv = res.b.servers || []
|
|
7005
|
-
rows.splice(0, rows.length)
|
|
7006
|
-
for (let i = 0; i < serv.length; i++) {
|
|
7007
|
-
rows.push({ id: serv[i].name, s: serv[i] })
|
|
7008
|
-
}
|
|
7009
|
-
}),
|
|
7010
|
-
]).then(function () {
|
|
7011
|
-
renderMcpRows()
|
|
7012
|
-
})
|
|
7013
|
-
})
|
|
7014
|
-
.catch(function (e) {
|
|
7015
|
-
window.alert('删除失败: ' + e)
|
|
6734
|
+
typeof refreshMcpPickerRows === 'function' ? refreshMcpPickerRows() : Promise.resolve(),
|
|
6735
|
+
])
|
|
7016
6736
|
})
|
|
7017
|
-
.
|
|
7018
|
-
delBtn.disabled = !canDelete
|
|
6737
|
+
.then(function () {
|
|
7019
6738
|
renderMcpRows()
|
|
7020
6739
|
})
|
|
7021
|
-
|
|
7022
|
-
|
|
7023
|
-
|
|
7024
|
-
|
|
7025
|
-
|
|
6740
|
+
.catch(function (e) { window.alert('删除失败: ' + e) })
|
|
6741
|
+
return
|
|
6742
|
+
}
|
|
6743
|
+
const pkgId = row.s && row.s.packageId ? String(row.s.packageId) : id
|
|
6744
|
+
fetch(buildRuntimeMcpDeleteUrl(pkgId), { method: 'DELETE' })
|
|
6745
|
+
.then(function (r) {
|
|
6746
|
+
return r.json().catch(function () { return {} }).then(function (b) { return { r: r, b: b } })
|
|
6747
|
+
})
|
|
6748
|
+
.then(function (x) {
|
|
6749
|
+
if (!x.r.ok) throw new Error(x.b.message || x.r.statusText)
|
|
6750
|
+
pickerSelected.delete(id)
|
|
6751
|
+
agentConfigState.mcpServers = agentConfigState.mcpServers.filter(function (name) { return name !== id })
|
|
6752
|
+
renderBindChips()
|
|
6753
|
+
return Promise.all([
|
|
6754
|
+
persistAgentConfigAndRestartSession({ silent: true }),
|
|
6755
|
+
fetch(buildMcpServersListUrl())
|
|
6756
|
+
.then(function (r) { return r.json().then(function (b) { return { r: r, b: b } }) })
|
|
6757
|
+
.then(function (res) {
|
|
6758
|
+
if (!res.r.ok) throw new Error(res.b.message || res.r.statusText)
|
|
6759
|
+
const serv = res.b.servers || []
|
|
6760
|
+
rows.splice(0, rows.length)
|
|
6761
|
+
for (let i = 0; i < serv.length; i++) rows.push({ id: serv[i].name, s: serv[i] })
|
|
6762
|
+
}),
|
|
6763
|
+
]).then(function () { renderMcpRows() })
|
|
6764
|
+
})
|
|
6765
|
+
.catch(function (e) { window.alert('删除失败: ' + e) })
|
|
6766
|
+
}, { disabled: !canDelete, title: !canDelete ? '基础MCP不可删除' : '' }))
|
|
7026
6767
|
}
|
|
7027
|
-
|
|
6768
|
+
tr.appendChild(createManageActionsTd(buttons))
|
|
6769
|
+
return tr
|
|
7028
6770
|
}
|
|
7029
6771
|
const renderMcpRows = function () {
|
|
7030
|
-
|
|
7031
|
-
|
|
7032
|
-
|
|
7033
|
-
|
|
7034
|
-
|
|
7035
|
-
|
|
7036
|
-
],
|
|
7037
|
-
mcpPickerState.activeTab,
|
|
7038
|
-
function (id) {
|
|
7039
|
-
mcpPickerState.activeTab = id
|
|
7040
|
-
renderMcpRows()
|
|
7041
|
-
},
|
|
7042
|
-
)
|
|
7043
|
-
const mergedRows = rows
|
|
6772
|
+
setPickerContentMode('table')
|
|
6773
|
+
setPickerTableHead(['名称', '来源', '操作'])
|
|
6774
|
+
clearPickerTableBody()
|
|
6775
|
+
setPickerContentState('', false)
|
|
6776
|
+
const q = getPickerSearchQuery()
|
|
6777
|
+
const sectionRows = rows
|
|
7044
6778
|
.filter(function (row) {
|
|
7045
|
-
|
|
6779
|
+
if (!q) return true
|
|
6780
|
+
const src = row.s && row.s.source ? String(row.s.source) : ''
|
|
6781
|
+
const srcText = mcpSourceLabel(src)
|
|
6782
|
+
return (
|
|
6783
|
+
mcpLabel(row).toLowerCase().indexOf(q) >= 0 ||
|
|
6784
|
+
String(row.id).toLowerCase().indexOf(q) >= 0 ||
|
|
6785
|
+
srcText.toLowerCase().indexOf(q) >= 0
|
|
6786
|
+
)
|
|
7046
6787
|
})
|
|
7047
6788
|
.sort(function (a, b) {
|
|
7048
6789
|
const as = pickerSelected.has(a.id) ? 0 : 1
|
|
@@ -7050,28 +6791,21 @@
|
|
|
7050
6791
|
if (as !== bs) return as - bs
|
|
7051
6792
|
return a.id.localeCompare(b.id)
|
|
7052
6793
|
})
|
|
7053
|
-
if (
|
|
7054
|
-
|
|
7055
|
-
showExport: true,
|
|
7056
|
-
showDelete: true,
|
|
7057
|
-
}))
|
|
6794
|
+
if (!sectionRows.length) {
|
|
6795
|
+
setPickerContentState(rows.length ? '(无匹配项)' : '(暂无)', false)
|
|
7058
6796
|
return
|
|
7059
6797
|
}
|
|
7060
|
-
const
|
|
7061
|
-
|
|
7062
|
-
|
|
7063
|
-
|
|
7064
|
-
|
|
7065
|
-
|
|
7066
|
-
|
|
7067
|
-
|
|
7068
|
-
|
|
7069
|
-
})
|
|
7070
|
-
agentPickerList.appendChild(createMcpSection('远程MCP', remoteRows, {
|
|
7071
|
-
showExport: false,
|
|
7072
|
-
showDelete: false,
|
|
7073
|
-
}))
|
|
6798
|
+
const frag = document.createDocumentFragment()
|
|
6799
|
+
for (let i = 0; i < sectionRows.length; i++) {
|
|
6800
|
+
const rowSource = sectionRows[i].s && sectionRows[i].s.source ? String(sectionRows[i].s.source) : ''
|
|
6801
|
+
frag.appendChild(makeMcpTableRow(sectionRows[i], {
|
|
6802
|
+
showExport: rowSource === 'runtime',
|
|
6803
|
+
showDelete: rowSource === 'runtime' || rowSource === 'remote',
|
|
6804
|
+
}))
|
|
6805
|
+
}
|
|
6806
|
+
if (pickerEntriesBody) pickerEntriesBody.appendChild(frag)
|
|
7074
6807
|
}
|
|
6808
|
+
pickerRenderContent = renderMcpRows
|
|
7075
6809
|
const loadRemoteMcpRows = function () {
|
|
7076
6810
|
return fetch(buildRemoteMcpJsonUrl())
|
|
7077
6811
|
.then(function (r) {
|
|
@@ -7111,93 +6845,85 @@
|
|
|
7111
6845
|
})
|
|
7112
6846
|
})
|
|
7113
6847
|
.catch(function (e) {
|
|
7114
|
-
|
|
6848
|
+
setPickerContentState('加载失败: ' + e, true)
|
|
7115
6849
|
})
|
|
7116
6850
|
} else if (kind === 'agentTeams') {
|
|
7117
|
-
|
|
7118
|
-
const
|
|
7119
|
-
|
|
7120
|
-
|
|
7121
|
-
|
|
7122
|
-
|
|
7123
|
-
|
|
7124
|
-
|
|
7125
|
-
)
|
|
7126
|
-
|
|
7127
|
-
|
|
7128
|
-
|
|
7129
|
-
|
|
7130
|
-
|
|
7131
|
-
|
|
7132
|
-
|
|
7133
|
-
|
|
7134
|
-
|
|
7135
|
-
|
|
7136
|
-
|
|
7137
|
-
|
|
7138
|
-
|
|
7139
|
-
|
|
7140
|
-
|
|
7141
|
-
|
|
7142
|
-
|
|
7143
|
-
|
|
7144
|
-
|
|
7145
|
-
|
|
7146
|
-
|
|
6851
|
+
let teamRows = []
|
|
6852
|
+
const teamLabelFn = function (row) {
|
|
6853
|
+
const s = row.s || {}
|
|
6854
|
+
const parts = [String(s.agentType || row.id || '')]
|
|
6855
|
+
if (s.model) parts.push('model:' + s.model)
|
|
6856
|
+
if (s.effort !== undefined && s.effort !== null && String(s.effort) !== '') {
|
|
6857
|
+
parts.push('effort:' + String(s.effort))
|
|
6858
|
+
}
|
|
6859
|
+
if (s.background === true) parts.push('bg:true')
|
|
6860
|
+
if (s.isolation) parts.push('iso:' + s.isolation)
|
|
6861
|
+
return parts.join(' · ')
|
|
6862
|
+
}
|
|
6863
|
+
const teamConfigFn = function (row) {
|
|
6864
|
+
const s = row.s || {}
|
|
6865
|
+
const tags = []
|
|
6866
|
+
if (Array.isArray(s.tools) && s.tools.length > 0) tags.push('tools:' + s.tools.length)
|
|
6867
|
+
if (Array.isArray(s.disallowedTools) && s.disallowedTools.length > 0) tags.push('deny:' + s.disallowedTools.length)
|
|
6868
|
+
const summary = typeof s.whenToUse === 'string' && s.whenToUse.trim()
|
|
6869
|
+
? String(s.whenToUse).slice(0, 100) : ''
|
|
6870
|
+
return (tags.length ? tags.join(' ') : '—') + (summary ? ' — ' + summary : '')
|
|
6871
|
+
}
|
|
6872
|
+
const renderAgentTeamsRows = function () {
|
|
6873
|
+
setPickerContentMode('table')
|
|
6874
|
+
setPickerTableHead(['成员', '配置', '操作'])
|
|
6875
|
+
clearPickerTableBody()
|
|
6876
|
+
setPickerContentState('', false)
|
|
6877
|
+
const q = getPickerSearchQuery()
|
|
6878
|
+
const filtered = teamRows.filter(function (row) {
|
|
6879
|
+
if (!q) return true
|
|
6880
|
+
const lab = teamLabelFn(row) + ' ' + teamConfigFn(row)
|
|
6881
|
+
return lab.toLowerCase().indexOf(q) >= 0 || String(row.id).toLowerCase().indexOf(q) >= 0
|
|
6882
|
+
})
|
|
6883
|
+
if (!filtered.length) {
|
|
6884
|
+
setPickerContentState(teamRows.length ? '(无匹配项)' : '(暂无成员)', false)
|
|
6885
|
+
return
|
|
7147
6886
|
}
|
|
7148
6887
|
const frag = document.createDocumentFragment()
|
|
7149
|
-
for (let i = 0; i <
|
|
7150
|
-
const row =
|
|
6888
|
+
for (let i = 0; i < filtered.length; i++) {
|
|
6889
|
+
const row = filtered[i]
|
|
7151
6890
|
const id = row.id
|
|
7152
|
-
const
|
|
7153
|
-
const
|
|
7154
|
-
|
|
7155
|
-
|
|
7156
|
-
|
|
7157
|
-
|
|
7158
|
-
|
|
7159
|
-
const actions = document.createElement('div')
|
|
7160
|
-
actions.className = 'agent-picker-actions'
|
|
7161
|
-
const toggleBtn = document.createElement('button')
|
|
7162
|
-
toggleBtn.type = 'button'
|
|
6891
|
+
const tr = document.createElement('tr')
|
|
6892
|
+
const memberTd = document.createElement('td')
|
|
6893
|
+
memberTd.textContent = teamLabelFn(row)
|
|
6894
|
+
tr.appendChild(memberTd)
|
|
6895
|
+
const configTd = document.createElement('td')
|
|
6896
|
+
configTd.textContent = teamConfigFn(row)
|
|
6897
|
+
tr.appendChild(configTd)
|
|
7163
6898
|
const selected = pickerSelected.has(id)
|
|
7164
|
-
|
|
7165
|
-
|
|
7166
|
-
|
|
7167
|
-
|
|
7168
|
-
|
|
7169
|
-
|
|
7170
|
-
|
|
7171
|
-
|
|
7172
|
-
div.appendChild(actions)
|
|
7173
|
-
frag.appendChild(div)
|
|
7174
|
-
}
|
|
7175
|
-
if (!frag.childNodes.length) {
|
|
7176
|
-
agentPickerList.appendChild(document.createTextNode('(无匹配项)'))
|
|
7177
|
-
return
|
|
6899
|
+
tr.appendChild(createManageActionsTd([
|
|
6900
|
+
createManageRowBtn(selected ? '禁用' : '启用', selected ? 'is-on' : '', function () {
|
|
6901
|
+
if (pickerSelected.has(id)) pickerSelected.delete(id)
|
|
6902
|
+
else pickerSelected.add(id)
|
|
6903
|
+
renderAgentTeamsRows()
|
|
6904
|
+
}),
|
|
6905
|
+
]))
|
|
6906
|
+
frag.appendChild(tr)
|
|
7178
6907
|
}
|
|
7179
|
-
|
|
6908
|
+
if (pickerEntriesBody) pickerEntriesBody.appendChild(frag)
|
|
7180
6909
|
}
|
|
6910
|
+
pickerRenderContent = renderAgentTeamsRows
|
|
7181
6911
|
fetch(buildAgentTeamsListUrl())
|
|
7182
6912
|
.then(function (r) {
|
|
7183
|
-
return r.json().then(function (b) {
|
|
7184
|
-
return { r: r, b: b }
|
|
7185
|
-
})
|
|
6913
|
+
return r.json().then(function (b) { return { r: r, b: b } })
|
|
7186
6914
|
})
|
|
7187
6915
|
.then(function (x) {
|
|
7188
6916
|
if (!x.r.ok) throw new Error(x.b.message || x.r.statusText)
|
|
7189
6917
|
const list = x.b.teamAgentTypes || []
|
|
7190
|
-
|
|
7191
|
-
|
|
7192
|
-
})
|
|
7193
|
-
renderAgentTeamsRows(rows)
|
|
6918
|
+
teamRows = list.map(function (s) { return { id: s.agentType, s: s } })
|
|
6919
|
+
renderAgentTeamsRows()
|
|
7194
6920
|
})
|
|
7195
6921
|
.catch(function (e) {
|
|
7196
|
-
|
|
6922
|
+
setPickerContentState('加载失败: ' + e, true)
|
|
7197
6923
|
})
|
|
7198
6924
|
} else {
|
|
7199
6925
|
const skillPickerState = {
|
|
7200
|
-
activeTab: '
|
|
6926
|
+
activeTab: 'list',
|
|
7201
6927
|
baseRows: [],
|
|
7202
6928
|
installedRows: [],
|
|
7203
6929
|
cloudRows: [],
|
|
@@ -7233,112 +6959,87 @@
|
|
|
7233
6959
|
(s.description ? ' — ' + String(s.description).slice(0, 100) : '')
|
|
7234
6960
|
)
|
|
7235
6961
|
}
|
|
7236
|
-
|
|
6962
|
+
/** 将 Skill 启用状态写入 agent 配置并立即持久化 */
|
|
6963
|
+
const persistSkillSelectionNow = function () {
|
|
6964
|
+
agentConfigState.skills = [...pickerSelected].sort()
|
|
6965
|
+
renderBindChips()
|
|
6966
|
+
return persistAgentConfigAndRestartSession({ silent: true })
|
|
6967
|
+
}
|
|
6968
|
+
/** 系统 skill 不可删除;agent 层已安装 skill 可删除 */
|
|
6969
|
+
const isSkillDeletable = function (row) {
|
|
6970
|
+
const s = row.s || {}
|
|
6971
|
+
return s.canManage === true || s.runtimeLayer === 'agent'
|
|
6972
|
+
}
|
|
6973
|
+
const mergeSkillListRows = function () {
|
|
6974
|
+
const merged = skillPickerState.baseRows.concat(skillPickerState.installedRows)
|
|
6975
|
+
merged.sort(function (a, b) {
|
|
6976
|
+
const as = a.s && a.s.runtimeLayer === 'system' ? 0 : 1
|
|
6977
|
+
const bs = b.s && b.s.runtimeLayer === 'system' ? 0 : 1
|
|
6978
|
+
if (as !== bs) return as - bs
|
|
6979
|
+
return String(a.id).localeCompare(String(b.id))
|
|
6980
|
+
})
|
|
6981
|
+
return merged
|
|
6982
|
+
}
|
|
6983
|
+
const makeSkillTableRow = function (row) {
|
|
7237
6984
|
const id = row.id
|
|
7238
|
-
const
|
|
7239
|
-
|
|
7240
|
-
const
|
|
7241
|
-
|
|
7242
|
-
|
|
7243
|
-
|
|
7244
|
-
const
|
|
7245
|
-
|
|
7246
|
-
|
|
7247
|
-
toggleBtn.type = 'button'
|
|
6985
|
+
const canDelete = isSkillDeletable(row)
|
|
6986
|
+
const tr = document.createElement('tr')
|
|
6987
|
+
const nameTd = document.createElement('td')
|
|
6988
|
+
nameTd.textContent = '/' + (row.s && row.s.name ? row.s.name : id)
|
|
6989
|
+
tr.appendChild(nameTd)
|
|
6990
|
+
const descTd = document.createElement('td')
|
|
6991
|
+
const desc = row.s && row.s.description ? String(row.s.description).slice(0, 100) : '—'
|
|
6992
|
+
descTd.textContent = desc
|
|
6993
|
+
tr.appendChild(descTd)
|
|
7248
6994
|
const selected = pickerSelected.has(id)
|
|
7249
|
-
toggleBtn
|
|
7250
|
-
|
|
7251
|
-
toggleBtn.addEventListener('click', function () {
|
|
6995
|
+
const toggleBtn = createManageRowBtn(selected ? '禁用' : '启用', selected ? 'is-on' : '', function () {
|
|
6996
|
+
toggleBtn.disabled = true
|
|
7252
6997
|
if (pickerSelected.has(id)) pickerSelected.delete(id)
|
|
7253
6998
|
else pickerSelected.add(id)
|
|
7254
|
-
|
|
6999
|
+
persistSkillSelectionNow()
|
|
7000
|
+
.then(function () {
|
|
7001
|
+
renderSkillRows()
|
|
7002
|
+
})
|
|
7003
|
+
.catch(function (e) {
|
|
7004
|
+
window.alert('切换启用状态失败: ' + e)
|
|
7005
|
+
})
|
|
7006
|
+
.finally(function () {
|
|
7007
|
+
toggleBtn.disabled = false
|
|
7008
|
+
})
|
|
7255
7009
|
})
|
|
7256
|
-
|
|
7010
|
+
const buttons = [toggleBtn]
|
|
7257
7011
|
if (!canDelete) {
|
|
7258
|
-
|
|
7259
|
-
editBtn.type = 'button'
|
|
7260
|
-
editBtn.className = 'btn-picker-action'
|
|
7261
|
-
editBtn.textContent = '编辑'
|
|
7262
|
-
editBtn.addEventListener('click', function () {
|
|
7263
|
-
openSkillMdModal(id)
|
|
7264
|
-
})
|
|
7265
|
-
actions.appendChild(editBtn)
|
|
7012
|
+
buttons.push(createManageRowBtn('编辑', '', function () { openSkillMdModal(id) }))
|
|
7266
7013
|
}
|
|
7267
7014
|
if (canDelete) {
|
|
7268
|
-
|
|
7269
|
-
exportBtn.type = 'button'
|
|
7270
|
-
exportBtn.className = 'btn-picker-action'
|
|
7271
|
-
exportBtn.textContent = '导出'
|
|
7272
|
-
exportBtn.addEventListener('click', function () {
|
|
7015
|
+
buttons.push(createManageRowBtn('导出', '', function () {
|
|
7273
7016
|
window.open(buildRuntimeSkillExportUrl(id), '_blank', 'noopener')
|
|
7274
|
-
})
|
|
7275
|
-
actions.appendChild(exportBtn)
|
|
7017
|
+
}))
|
|
7276
7018
|
}
|
|
7277
|
-
|
|
7278
|
-
|
|
7279
|
-
|
|
7280
|
-
delBtn.textContent = '删除'
|
|
7281
|
-
delBtn.disabled = !canDelete
|
|
7282
|
-
if (!canDelete) delBtn.title = '系统技能不可删除'
|
|
7283
|
-
delBtn.addEventListener('click', function () {
|
|
7284
|
-
if (delBtn.disabled) return
|
|
7285
|
-
const targetSkill = id
|
|
7286
|
-
const ok = window.confirm('确认删除 Skill 包?\nSkill:' + targetSkill)
|
|
7019
|
+
buttons.push(createManageRowBtn('删除', 'is-delete', function () {
|
|
7020
|
+
if (!canDelete) return
|
|
7021
|
+
const ok = window.confirm('确认删除 Skill 包?\nSkill:' + id)
|
|
7287
7022
|
if (!ok) return
|
|
7288
|
-
|
|
7289
|
-
fetch(buildRuntimeSkillDeleteUrl(targetSkill), { method: 'DELETE' })
|
|
7023
|
+
fetch(buildRuntimeSkillDeleteUrl(id), { method: 'DELETE' })
|
|
7290
7024
|
.then(function (r) {
|
|
7291
|
-
return r.json().catch(function () {
|
|
7292
|
-
return {}
|
|
7293
|
-
}).then(function (b) {
|
|
7294
|
-
return { r: r, b: b }
|
|
7295
|
-
})
|
|
7025
|
+
return r.json().catch(function () { return {} }).then(function (b) { return { r: r, b: b } })
|
|
7296
7026
|
})
|
|
7297
7027
|
.then(function (x) {
|
|
7298
7028
|
if (!x.r.ok) throw new Error(x.b.message || x.r.statusText)
|
|
7299
|
-
pickerSelected.delete(
|
|
7300
|
-
agentConfigState.skills = agentConfigState.skills.filter(function (name) {
|
|
7301
|
-
return name !== targetSkill
|
|
7302
|
-
})
|
|
7029
|
+
pickerSelected.delete(id)
|
|
7030
|
+
agentConfigState.skills = agentConfigState.skills.filter(function (name) { return name !== id })
|
|
7303
7031
|
renderBindChips()
|
|
7304
7032
|
void persistAgentConfigAndRestartSession({ silent: true })
|
|
7305
7033
|
return refreshSkillPickerRows()
|
|
7306
7034
|
})
|
|
7307
|
-
.catch(function (e) {
|
|
7308
|
-
|
|
7309
|
-
|
|
7310
|
-
|
|
7311
|
-
})
|
|
7312
|
-
actions.appendChild(delBtn)
|
|
7313
|
-
div.appendChild(actions)
|
|
7314
|
-
return div
|
|
7035
|
+
.catch(function (e) { window.alert('删除失败: ' + e) })
|
|
7036
|
+
}, { disabled: !canDelete, title: !canDelete ? '系统技能不可删除' : '' }))
|
|
7037
|
+
tr.appendChild(createManageActionsTd(buttons))
|
|
7038
|
+
return tr
|
|
7315
7039
|
}
|
|
7316
|
-
const
|
|
7317
|
-
|
|
7318
|
-
|
|
7319
|
-
const titleEl = document.createElement('div')
|
|
7320
|
-
titleEl.className = 'agent-picker-section-title'
|
|
7321
|
-
titleEl.textContent = title
|
|
7322
|
-
sec.appendChild(titleEl)
|
|
7323
|
-
if (!rows.length) {
|
|
7324
|
-
const empty = document.createElement('div')
|
|
7325
|
-
empty.className = 'agent-picker-empty'
|
|
7326
|
-
empty.textContent = '(暂无)'
|
|
7327
|
-
sec.appendChild(empty)
|
|
7328
|
-
return sec
|
|
7329
|
-
}
|
|
7330
|
-
for (let i = 0; i < rows.length; i++) {
|
|
7331
|
-
sec.appendChild(makeSkillRow(rows[i], canDelete))
|
|
7332
|
-
}
|
|
7333
|
-
return sec
|
|
7334
|
-
}
|
|
7335
|
-
const renderCloudSkillSection = function () {
|
|
7336
|
-
const sec = document.createElement('div')
|
|
7337
|
-
sec.className = 'agent-picker-section'
|
|
7338
|
-
const titleEl = document.createElement('div')
|
|
7339
|
-
titleEl.className = 'agent-picker-section-title'
|
|
7340
|
-
titleEl.textContent = 'skill商店'
|
|
7341
|
-
sec.appendChild(titleEl)
|
|
7040
|
+
const renderCloudSkillPanel = function () {
|
|
7041
|
+
if (!pickerCloudPanel) return
|
|
7042
|
+
pickerCloudPanel.innerHTML = ''
|
|
7342
7043
|
const cloudSearch = document.createElement('input')
|
|
7343
7044
|
cloudSearch.type = 'search'
|
|
7344
7045
|
cloudSearch.className = 'agent-picker-cloud-search'
|
|
@@ -7349,120 +7050,112 @@
|
|
|
7349
7050
|
skillPickerState.cloudPage = 1
|
|
7350
7051
|
void loadCloudSkillRows()
|
|
7351
7052
|
}
|
|
7352
|
-
|
|
7053
|
+
pickerCloudPanel.appendChild(cloudSearch)
|
|
7353
7054
|
const meta = document.createElement('div')
|
|
7354
7055
|
meta.className = 'agent-picker-cloud-meta'
|
|
7355
|
-
if (skillPickerState.cloudLoading)
|
|
7356
|
-
|
|
7357
|
-
|
|
7358
|
-
|
|
7359
|
-
|
|
7360
|
-
|
|
7361
|
-
|
|
7362
|
-
|
|
7363
|
-
|
|
7364
|
-
|
|
7056
|
+
if (skillPickerState.cloudLoading) meta.textContent = '加载中…'
|
|
7057
|
+
else if (skillPickerState.cloudError) meta.textContent = '加载失败:' + skillPickerState.cloudError
|
|
7058
|
+
else meta.textContent = '展示前 ' + skillPickerState.cloudRows.length + ' 项'
|
|
7059
|
+
pickerCloudPanel.appendChild(meta)
|
|
7060
|
+
if (!skillPickerState.cloudError && skillPickerState.cloudRows.length) {
|
|
7061
|
+
for (let i = 0; i < skillPickerState.cloudRows.length; i++) {
|
|
7062
|
+
const item = skillPickerState.cloudRows[i]
|
|
7063
|
+
const row = document.createElement('div')
|
|
7064
|
+
row.className = 'agent-picker-item'
|
|
7065
|
+
const label = document.createElement('div')
|
|
7066
|
+
label.className = 'agent-picker-item-label'
|
|
7067
|
+
label.textContent = item.title + ' · /' + item.skillName + (item.description ? ' — ' + item.description : '')
|
|
7068
|
+
row.appendChild(label)
|
|
7069
|
+
const actions = document.createElement('div')
|
|
7070
|
+
actions.className = 'agent-picker-actions'
|
|
7071
|
+
const installing = !!skillPickerState.installingMap[item.id]
|
|
7072
|
+
const installed = !!item.installed
|
|
7073
|
+
const installBtn = createManageRowBtn(
|
|
7074
|
+
installing ? '处理中…' : installed ? '卸载' : '安装', '', function () {
|
|
7075
|
+
if (installBtn.disabled) return
|
|
7076
|
+
skillPickerState.installingMap[item.id] = true
|
|
7077
|
+
renderSkillRows()
|
|
7078
|
+
const request = installed
|
|
7079
|
+
? fetch(buildRuntimeSkillDeleteUrl(item.packageId), { method: 'DELETE' })
|
|
7080
|
+
: fetch(buildCloudSkillInstallUrl(), {
|
|
7081
|
+
method: 'POST',
|
|
7082
|
+
headers: { 'Content-Type': 'application/json; charset=utf-8' },
|
|
7083
|
+
body: JSON.stringify({ id: item.id }),
|
|
7084
|
+
})
|
|
7085
|
+
request
|
|
7086
|
+
.then(function (r) {
|
|
7087
|
+
return r.json().catch(function () { return {} }).then(function (b) { return { r: r, b: b } })
|
|
7088
|
+
})
|
|
7089
|
+
.then(function (x) {
|
|
7090
|
+
if (!x.r.ok) throw new Error(x.b.message || x.r.statusText)
|
|
7091
|
+
if (installed) pickerSelected.delete(item.skillName || item.id)
|
|
7092
|
+
else pickerSelected.add(item.skillName || item.id)
|
|
7093
|
+
setStatus('云端技能已' + (installed ? '卸载' : '安装') + ':' + item.title, serverReady ? 'ready' : '')
|
|
7094
|
+
return persistSkillSelectionNow().then(function () {
|
|
7095
|
+
return refreshSkillPickerRows()
|
|
7096
|
+
})
|
|
7097
|
+
})
|
|
7098
|
+
.catch(function (e) { window.alert((installed ? '卸载' : '安装') + '失败: ' + e) })
|
|
7099
|
+
.finally(function () {
|
|
7100
|
+
delete skillPickerState.installingMap[item.id]
|
|
7101
|
+
renderSkillRows()
|
|
7102
|
+
})
|
|
7103
|
+
}, { disabled: installing },
|
|
7104
|
+
)
|
|
7105
|
+
actions.appendChild(installBtn)
|
|
7106
|
+
row.appendChild(actions)
|
|
7107
|
+
pickerCloudPanel.appendChild(row)
|
|
7108
|
+
}
|
|
7109
|
+
pickerCloudPanel.appendChild(createCloudPager({
|
|
7110
|
+
page: skillPickerState.cloudPage,
|
|
7111
|
+
totalPages: skillPickerState.cloudTotalPages,
|
|
7112
|
+
loading: skillPickerState.cloudLoading,
|
|
7113
|
+
}, function (nextPage) {
|
|
7114
|
+
skillPickerState.cloudPage = nextPage
|
|
7115
|
+
void loadCloudSkillRows()
|
|
7116
|
+
}))
|
|
7117
|
+
} else if (!skillPickerState.cloudError) {
|
|
7365
7118
|
const empty = document.createElement('div')
|
|
7366
7119
|
empty.className = 'agent-picker-empty'
|
|
7367
7120
|
empty.textContent = skillPickerState.cloudLoading ? '(技能商店加载中)' : '(无匹配项)'
|
|
7368
|
-
|
|
7369
|
-
return sec
|
|
7370
|
-
}
|
|
7371
|
-
for (let i = 0; i < skillPickerState.cloudRows.length; i++) {
|
|
7372
|
-
const item = skillPickerState.cloudRows[i]
|
|
7373
|
-
const row = document.createElement('div')
|
|
7374
|
-
row.className = 'agent-picker-item'
|
|
7375
|
-
const label = document.createElement('div')
|
|
7376
|
-
label.className = 'agent-picker-item-label'
|
|
7377
|
-
label.textContent = item.title + ' · /' + item.skillName + (item.description ? ' — ' + item.description : '')
|
|
7378
|
-
row.appendChild(label)
|
|
7379
|
-
const actions = document.createElement('div')
|
|
7380
|
-
actions.className = 'agent-picker-actions'
|
|
7381
|
-
const installBtn = document.createElement('button')
|
|
7382
|
-
installBtn.type = 'button'
|
|
7383
|
-
installBtn.className = 'btn-picker-action'
|
|
7384
|
-
const installing = !!skillPickerState.installingMap[item.id]
|
|
7385
|
-
const installed = !!item.installed
|
|
7386
|
-
installBtn.textContent = installing ? '处理中…' : installed ? '卸载' : '安装'
|
|
7387
|
-
installBtn.disabled = installing
|
|
7388
|
-
installBtn.addEventListener('click', function () {
|
|
7389
|
-
if (installBtn.disabled) return
|
|
7390
|
-
skillPickerState.installingMap[item.id] = true
|
|
7391
|
-
renderSkillRows()
|
|
7392
|
-
const request = installed
|
|
7393
|
-
? fetch(buildRuntimeSkillDeleteUrl(item.packageId), { method: 'DELETE' })
|
|
7394
|
-
: fetch(buildCloudSkillInstallUrl(), {
|
|
7395
|
-
method: 'POST',
|
|
7396
|
-
headers: { 'Content-Type': 'application/json; charset=utf-8' },
|
|
7397
|
-
body: JSON.stringify({ id: item.id }),
|
|
7398
|
-
})
|
|
7399
|
-
request
|
|
7400
|
-
.then(function (r) {
|
|
7401
|
-
return r.json().catch(function () {
|
|
7402
|
-
return {}
|
|
7403
|
-
}).then(function (b) {
|
|
7404
|
-
return { r: r, b: b }
|
|
7405
|
-
})
|
|
7406
|
-
})
|
|
7407
|
-
.then(function (x) {
|
|
7408
|
-
if (!x.r.ok) throw new Error(x.b.message || x.r.statusText)
|
|
7409
|
-
if (installed) {
|
|
7410
|
-
pickerSelected.delete(item.skillName || item.id)
|
|
7411
|
-
} else {
|
|
7412
|
-
pickerSelected.add(item.skillName || item.id)
|
|
7413
|
-
}
|
|
7414
|
-
setStatus('云端技能已' + (installed ? '卸载' : '安装') + ':' + item.title, serverReady ? 'ready' : '')
|
|
7415
|
-
restartCurrentSessionSubprocessWithReason(installed ? 'cloud-skill-uninstall' : 'cloud-skill-install')
|
|
7416
|
-
return refreshSkillPickerRows()
|
|
7417
|
-
})
|
|
7418
|
-
.catch(function (e) {
|
|
7419
|
-
window.alert((installed ? '卸载' : '安装') + '失败: ' + e)
|
|
7420
|
-
})
|
|
7421
|
-
.finally(function () {
|
|
7422
|
-
delete skillPickerState.installingMap[item.id]
|
|
7423
|
-
renderSkillRows()
|
|
7424
|
-
})
|
|
7425
|
-
})
|
|
7426
|
-
actions.appendChild(installBtn)
|
|
7427
|
-
row.appendChild(actions)
|
|
7428
|
-
sec.appendChild(row)
|
|
7121
|
+
pickerCloudPanel.appendChild(empty)
|
|
7429
7122
|
}
|
|
7430
|
-
return sec
|
|
7431
7123
|
}
|
|
7432
7124
|
const renderSkillRows = function () {
|
|
7433
|
-
|
|
7434
|
-
agentPickerList.innerHTML = ''
|
|
7435
|
-
renderPickerHeaderTabs(
|
|
7125
|
+
renderPickerNavTabs(
|
|
7436
7126
|
[
|
|
7437
|
-
{ id: '
|
|
7438
|
-
{ id: 'installed', label: '已安装skill' },
|
|
7127
|
+
{ id: 'list', label: 'Skill' },
|
|
7439
7128
|
{ id: 'cloud', label: 'skill商店' },
|
|
7440
7129
|
],
|
|
7441
7130
|
skillPickerState.activeTab,
|
|
7442
|
-
function (id) {
|
|
7443
|
-
skillPickerState.activeTab = id
|
|
7444
|
-
renderSkillRows()
|
|
7445
|
-
},
|
|
7131
|
+
function (id) { skillPickerState.activeTab = id; renderSkillRows() },
|
|
7446
7132
|
)
|
|
7447
|
-
if (skillPickerState.activeTab === '
|
|
7448
|
-
|
|
7133
|
+
if (skillPickerState.activeTab === 'cloud') {
|
|
7134
|
+
setPickerContentMode('cloud')
|
|
7135
|
+
renderCloudSkillPanel()
|
|
7449
7136
|
return
|
|
7450
7137
|
}
|
|
7451
|
-
|
|
7452
|
-
|
|
7138
|
+
setPickerContentMode('table')
|
|
7139
|
+
setPickerTableHead(['名称', '描述', '操作'])
|
|
7140
|
+
clearPickerTableBody()
|
|
7141
|
+
setPickerContentState('', false)
|
|
7142
|
+
const q = getPickerSearchQuery()
|
|
7143
|
+
const sourceRows = mergeSkillListRows()
|
|
7144
|
+
const rows = sourceRows.filter(function (row) {
|
|
7145
|
+
if (!q) return true
|
|
7146
|
+
return skillLabel(row).toLowerCase().indexOf(q) >= 0 || String(row.id).toLowerCase().indexOf(q) >= 0
|
|
7147
|
+
})
|
|
7148
|
+
if (!rows.length) {
|
|
7149
|
+
setPickerContentState(sourceRows.length ? '(无匹配项)' : '(暂无 Skill)', false)
|
|
7453
7150
|
return
|
|
7454
7151
|
}
|
|
7455
|
-
const
|
|
7456
|
-
|
|
7457
|
-
|
|
7458
|
-
|
|
7459
|
-
|
|
7460
|
-
}, function (nextPage) {
|
|
7461
|
-
skillPickerState.cloudPage = nextPage
|
|
7462
|
-
void loadCloudSkillRows()
|
|
7463
|
-
}))
|
|
7464
|
-
agentPickerList.appendChild(cloud)
|
|
7152
|
+
const frag = document.createDocumentFragment()
|
|
7153
|
+
for (let i = 0; i < rows.length; i++) {
|
|
7154
|
+
frag.appendChild(makeSkillTableRow(rows[i]))
|
|
7155
|
+
}
|
|
7156
|
+
if (pickerEntriesBody) pickerEntriesBody.appendChild(frag)
|
|
7465
7157
|
}
|
|
7158
|
+
pickerRenderContent = renderSkillRows
|
|
7466
7159
|
const loadCloudSkillRows = function () {
|
|
7467
7160
|
const seq = skillPickerState.cloudSeq + 1
|
|
7468
7161
|
skillPickerState.cloudSeq = seq
|
|
@@ -7566,7 +7259,7 @@
|
|
|
7566
7259
|
}
|
|
7567
7260
|
}
|
|
7568
7261
|
|
|
7569
|
-
function
|
|
7262
|
+
function applyPickerSave() {
|
|
7570
7263
|
const ids = [...pickerSelected].sort()
|
|
7571
7264
|
if (pickerKind === 'tools') {
|
|
7572
7265
|
agentConfigState.tools = ids
|
|
@@ -7578,7 +7271,7 @@
|
|
|
7578
7271
|
agentConfigState.skills = ids
|
|
7579
7272
|
}
|
|
7580
7273
|
renderBindChips()
|
|
7581
|
-
|
|
7274
|
+
closePickerManageView(false)
|
|
7582
7275
|
void persistAgentConfigAndRestartSession({ silent: true })
|
|
7583
7276
|
}
|
|
7584
7277
|
|
|
@@ -7593,16 +7286,19 @@
|
|
|
7593
7286
|
ev.stopPropagation()
|
|
7594
7287
|
closeRepoManageView()
|
|
7595
7288
|
closeAgentSettingsView()
|
|
7289
|
+
closePickerManageView(false)
|
|
7596
7290
|
const items = sidebarNavEl.querySelectorAll('.sidebar-nav-row')
|
|
7597
7291
|
for (let i = 0; i < items.length; i++) {
|
|
7598
7292
|
items[i].classList.toggle('is-active', items[i] === btn)
|
|
7599
7293
|
}
|
|
7600
|
-
void
|
|
7294
|
+
void openScheduleManageView()
|
|
7601
7295
|
return
|
|
7602
7296
|
}
|
|
7603
7297
|
if (k === 'repo') {
|
|
7604
7298
|
ev.preventDefault()
|
|
7605
7299
|
ev.stopPropagation()
|
|
7300
|
+
closeScheduleManageView(false)
|
|
7301
|
+
closePickerManageView(false)
|
|
7606
7302
|
const items = sidebarNavEl.querySelectorAll('.sidebar-nav-row')
|
|
7607
7303
|
for (let i = 0; i < items.length; i++) {
|
|
7608
7304
|
items[i].classList.toggle('is-active', items[i] === btn)
|
|
@@ -7615,30 +7311,36 @@
|
|
|
7615
7311
|
ev.stopPropagation()
|
|
7616
7312
|
closeRepoManageView()
|
|
7617
7313
|
closeAgentSettingsView()
|
|
7314
|
+
closeScheduleManageView(false)
|
|
7618
7315
|
const items = sidebarNavEl.querySelectorAll('.sidebar-nav-row')
|
|
7619
7316
|
for (let i = 0; i < items.length; i++) {
|
|
7620
7317
|
items[i].classList.toggle('is-active', items[i] === btn)
|
|
7621
7318
|
}
|
|
7622
|
-
|
|
7319
|
+
openPickerManageView(k)
|
|
7623
7320
|
}
|
|
7624
7321
|
})
|
|
7625
7322
|
}
|
|
7626
|
-
if (
|
|
7627
|
-
|
|
7628
|
-
|
|
7629
|
-
|
|
7323
|
+
if (btnPickerCancel) {
|
|
7324
|
+
btnPickerCancel.addEventListener('click', function () {
|
|
7325
|
+
closePickerManageView(true)
|
|
7326
|
+
})
|
|
7630
7327
|
}
|
|
7631
|
-
if (
|
|
7632
|
-
|
|
7633
|
-
|
|
7328
|
+
if (btnPickerSave) {
|
|
7329
|
+
btnPickerSave.addEventListener('click', function () {
|
|
7330
|
+
applyPickerSave()
|
|
7634
7331
|
})
|
|
7635
7332
|
}
|
|
7636
|
-
if (
|
|
7637
|
-
|
|
7333
|
+
if (btnPickerMcpJson) {
|
|
7334
|
+
btnPickerMcpJson.addEventListener('click', function () {
|
|
7638
7335
|
if (pickerKind !== 'mcp') return
|
|
7639
7336
|
openMcpJsonInputModal()
|
|
7640
7337
|
})
|
|
7641
7338
|
}
|
|
7339
|
+
if (pickerSearch) {
|
|
7340
|
+
pickerSearch.addEventListener('input', function () {
|
|
7341
|
+
if (typeof pickerRenderContent === 'function') pickerRenderContent()
|
|
7342
|
+
})
|
|
7343
|
+
}
|
|
7642
7344
|
if (btnMcpJsonInputModalClose) {
|
|
7643
7345
|
btnMcpJsonInputModalClose.addEventListener('click', closeMcpJsonInputModal)
|
|
7644
7346
|
}
|
|
@@ -7768,7 +7470,7 @@
|
|
|
7768
7470
|
setStatus('remote mcp.json 已保存', serverReady ? 'ready' : '')
|
|
7769
7471
|
if (pickerKind === 'mcp' && typeof refreshMcpPickerRows === 'function') {
|
|
7770
7472
|
void refreshMcpPickerRows().catch(function (e) {
|
|
7771
|
-
|
|
7473
|
+
setPickerContentState('加载失败: ' + e, true)
|
|
7772
7474
|
})
|
|
7773
7475
|
}
|
|
7774
7476
|
})
|
|
@@ -7783,19 +7485,9 @@
|
|
|
7783
7485
|
})
|
|
7784
7486
|
}
|
|
7785
7487
|
|
|
7786
|
-
if (btnScheduleManageModalClose) {
|
|
7787
|
-
btnScheduleManageModalClose.addEventListener('click', closeScheduleManageModal)
|
|
7788
|
-
}
|
|
7789
|
-
if (scheduleManageModalBackdrop) {
|
|
7790
|
-
scheduleManageModalBackdrop.addEventListener('click', closeScheduleManageModal)
|
|
7791
|
-
}
|
|
7792
|
-
const btnScheduleRunsModalClose = $('btnScheduleRunsModalClose')
|
|
7793
7488
|
const btnScheduleRunsRefresh = $('btnScheduleRunsRefresh')
|
|
7794
|
-
if (
|
|
7795
|
-
|
|
7796
|
-
}
|
|
7797
|
-
if (scheduleRunsModalBackdrop) {
|
|
7798
|
-
scheduleRunsModalBackdrop.addEventListener('click', closeScheduleRunsModal)
|
|
7489
|
+
if (btnScheduleRunsBack) {
|
|
7490
|
+
btnScheduleRunsBack.addEventListener('click', closeScheduleRunsView)
|
|
7799
7491
|
}
|
|
7800
7492
|
if (btnScheduleRunsRefresh) {
|
|
7801
7493
|
btnScheduleRunsRefresh.addEventListener('click', function () {
|
|
@@ -7838,21 +7530,6 @@
|
|
|
7838
7530
|
})
|
|
7839
7531
|
})
|
|
7840
7532
|
|
|
7841
|
-
if (btnManageAgents) {
|
|
7842
|
-
btnManageAgents.addEventListener('click', function (ev) {
|
|
7843
|
-
ev.preventDefault()
|
|
7844
|
-
ev.stopPropagation()
|
|
7845
|
-
closeRepoManageView()
|
|
7846
|
-
closeAgentSettingsView()
|
|
7847
|
-
if (sidebarNavEl) {
|
|
7848
|
-
const items = sidebarNavEl.querySelectorAll('.sidebar-nav-row')
|
|
7849
|
-
for (let i = 0; i < items.length; i++) {
|
|
7850
|
-
items[i].classList.toggle('is-active', items[i] === btnManageAgents)
|
|
7851
|
-
}
|
|
7852
|
-
}
|
|
7853
|
-
})
|
|
7854
|
-
}
|
|
7855
|
-
|
|
7856
7533
|
function closeAgentMdModal() {
|
|
7857
7534
|
if (!agentMdModal) return
|
|
7858
7535
|
agentMdModal.classList.remove('is-open')
|
|
@@ -8019,6 +7696,8 @@
|
|
|
8019
7696
|
function openAgentSettingsView(initialTab) {
|
|
8020
7697
|
if (!agentSettingsView) return
|
|
8021
7698
|
closeRepoManageView()
|
|
7699
|
+
closePickerManageView(false)
|
|
7700
|
+
closeScheduleManageView(false)
|
|
8022
7701
|
if (initialTab === 'agentMd' || initialTab === 'settings') {
|
|
8023
7702
|
agentEnvActiveTab = initialTab
|
|
8024
7703
|
} else {
|
|
@@ -8581,18 +8260,18 @@
|
|
|
8581
8260
|
})
|
|
8582
8261
|
})
|
|
8583
8262
|
}
|
|
8584
|
-
if (
|
|
8585
|
-
|
|
8263
|
+
if (btnPickerImport && pickerImportInput) {
|
|
8264
|
+
btnPickerImport.addEventListener('click', function () {
|
|
8586
8265
|
if (pickerKind !== 'tools' && pickerKind !== 'mcp' && pickerKind !== 'skills') return
|
|
8587
|
-
|
|
8588
|
-
|
|
8266
|
+
pickerImportInput.value = ''
|
|
8267
|
+
pickerImportInput.click()
|
|
8589
8268
|
})
|
|
8590
|
-
|
|
8591
|
-
const f =
|
|
8269
|
+
pickerImportInput.addEventListener('change', function () {
|
|
8270
|
+
const f = pickerImportInput.files && pickerImportInput.files[0]
|
|
8592
8271
|
if (!f) return
|
|
8593
8272
|
const fd = new FormData()
|
|
8594
8273
|
fd.append('file', f)
|
|
8595
|
-
|
|
8274
|
+
btnPickerImport.disabled = true
|
|
8596
8275
|
const importUrl = pickerKind === 'mcp'
|
|
8597
8276
|
? buildRuntimeMcpImportUrl()
|
|
8598
8277
|
: pickerKind === 'skills'
|
|
@@ -8608,7 +8287,7 @@
|
|
|
8608
8287
|
})
|
|
8609
8288
|
})
|
|
8610
8289
|
.then(function (x) {
|
|
8611
|
-
|
|
8290
|
+
btnPickerImport.disabled = false
|
|
8612
8291
|
if (!x.r.ok) {
|
|
8613
8292
|
window.alert('导入失败:' + (x.body.message || x.body.error || x.r.statusText))
|
|
8614
8293
|
return
|
|
@@ -8634,20 +8313,20 @@
|
|
|
8634
8313
|
)
|
|
8635
8314
|
if (pickerKind === 'tools' && typeof refreshToolPickerRows === 'function') {
|
|
8636
8315
|
void refreshToolPickerRows().catch(function (e) {
|
|
8637
|
-
|
|
8316
|
+
setPickerContentState('加载失败: ' + e, true)
|
|
8638
8317
|
})
|
|
8639
8318
|
} else if (pickerKind === 'mcp' && typeof refreshMcpPickerRows === 'function') {
|
|
8640
8319
|
void refreshMcpPickerRows().catch(function (e) {
|
|
8641
|
-
|
|
8320
|
+
setPickerContentState('加载失败: ' + e, true)
|
|
8642
8321
|
})
|
|
8643
8322
|
} else if (pickerKind === 'skills' && typeof refreshSkillPickerRows === 'function') {
|
|
8644
8323
|
void refreshSkillPickerRows().catch(function (e) {
|
|
8645
|
-
|
|
8324
|
+
setPickerContentState('加载失败: ' + e, true)
|
|
8646
8325
|
})
|
|
8647
8326
|
}
|
|
8648
8327
|
})
|
|
8649
8328
|
.catch(function (e) {
|
|
8650
|
-
|
|
8329
|
+
btnPickerImport.disabled = false
|
|
8651
8330
|
window.alert('导入失败: ' + e)
|
|
8652
8331
|
})
|
|
8653
8332
|
})
|
|
@@ -8722,12 +8401,8 @@
|
|
|
8722
8401
|
}
|
|
8723
8402
|
document.addEventListener('keydown', function (ev) {
|
|
8724
8403
|
if (ev.key !== 'Escape') return
|
|
8725
|
-
if (
|
|
8726
|
-
|
|
8727
|
-
return
|
|
8728
|
-
}
|
|
8729
|
-
if (agentPickerModal && agentPickerModal.classList.contains('is-open')) {
|
|
8730
|
-
closeAgentPickerModal()
|
|
8404
|
+
if (pickerManageState.viewActive) {
|
|
8405
|
+
closePickerManageView(true)
|
|
8731
8406
|
return
|
|
8732
8407
|
}
|
|
8733
8408
|
if (mcpJsonInputModal && mcpJsonInputModal.classList.contains('is-open')) {
|
|
@@ -8742,12 +8417,12 @@
|
|
|
8742
8417
|
closeSkillMdModal()
|
|
8743
8418
|
return
|
|
8744
8419
|
}
|
|
8745
|
-
if (
|
|
8746
|
-
|
|
8420
|
+
if (scheduleManageState.viewActive && scheduleManageState.contentView === 'runs') {
|
|
8421
|
+
closeScheduleRunsView()
|
|
8747
8422
|
return
|
|
8748
8423
|
}
|
|
8749
|
-
if (
|
|
8750
|
-
|
|
8424
|
+
if (scheduleManageState.viewActive) {
|
|
8425
|
+
closeScheduleManageView(true)
|
|
8751
8426
|
return
|
|
8752
8427
|
}
|
|
8753
8428
|
if (toolFilesModal && toolFilesModal.classList.contains('is-open')) {
|
|
@@ -8807,33 +8482,9 @@
|
|
|
8807
8482
|
brandAgentSwitchBtnEl.addEventListener('click', function (ev) {
|
|
8808
8483
|
ev.preventDefault()
|
|
8809
8484
|
ev.stopPropagation()
|
|
8810
|
-
|
|
8485
|
+
goToAgentHomePage()
|
|
8811
8486
|
})
|
|
8812
8487
|
}
|
|
8813
|
-
if (agentSwitchDropdownEl) {
|
|
8814
|
-
agentSwitchDropdownEl.addEventListener('click', function (ev) {
|
|
8815
|
-
ev.stopPropagation()
|
|
8816
|
-
})
|
|
8817
|
-
}
|
|
8818
|
-
document.addEventListener('click', function (ev) {
|
|
8819
|
-
if (!agentSwitchOpen) return
|
|
8820
|
-
const t = ev.target
|
|
8821
|
-
if (t instanceof Node) {
|
|
8822
|
-
if (agentSwitchWrapEl && agentSwitchWrapEl.contains(t)) return
|
|
8823
|
-
if (agentSwitchDropdownEl && agentSwitchDropdownEl.contains(t)) return
|
|
8824
|
-
}
|
|
8825
|
-
closeAgentSwitchMenu()
|
|
8826
|
-
})
|
|
8827
|
-
window.addEventListener('resize', function () {
|
|
8828
|
-
if (agentSwitchOpen) positionAgentSwitchDropdown()
|
|
8829
|
-
})
|
|
8830
|
-
window.addEventListener(
|
|
8831
|
-
'scroll',
|
|
8832
|
-
function () {
|
|
8833
|
-
if (agentSwitchOpen) positionAgentSwitchDropdown()
|
|
8834
|
-
},
|
|
8835
|
-
true
|
|
8836
|
-
)
|
|
8837
8488
|
|
|
8838
8489
|
updateBrandAgent()
|
|
8839
8490
|
void syncAgentDisplayNameCatalog()
|