feat: purge legacy agent hosts and land vault Chrome extension path
Retire ACP/Hermes/OpenCode surfaces and rename hermes_tools to mnote_agent_tools so Page AI stays on Pi Lab only. Add Chrome vault extension + extension token route, pre-release purge design, and soft-retire legacy smokes for the small-group production cut.
This commit is contained in:
@@ -599,7 +599,6 @@ export function createSidebarPageSettingsRuntime(context) {
|
||||
'<div class="mnote-extensions-subtabs" role="tablist" aria-label="扩展子面板">' +
|
||||
'<button type="button" class="mnote-extensions-subtab is-active" role="tab" aria-selected="true" data-extensions-subtab="knowledge">知识库</button>' +
|
||||
'<button type="button" class="mnote-extensions-subtab" role="tab" aria-selected="false" data-extensions-subtab="skills">Skills</button>' +
|
||||
'<button type="button" class="mnote-extensions-subtab" role="tab" aria-selected="false" data-extensions-subtab="mcp">MCP</button>' +
|
||||
'<button type="button" class="mnote-extensions-subtab" role="tab" aria-selected="false" data-extensions-subtab="tools">Agent 工具</button>' +
|
||||
'</div>' +
|
||||
'<div class="mnote-extensions-subpanel" data-extensions-panel="knowledge">' +
|
||||
@@ -608,9 +607,6 @@ export function createSidebarPageSettingsRuntime(context) {
|
||||
'<div class="mnote-extensions-subpanel" data-extensions-panel="skills" hidden>' +
|
||||
'<div class="mnote-extensions-status" data-extensions-status="skills"><span class="mnote-extensions-loading">加载中...</span></div>' +
|
||||
'</div>' +
|
||||
'<div class="mnote-extensions-subpanel" data-extensions-panel="mcp" hidden>' +
|
||||
'<div class="mnote-extensions-status" data-extensions-status="mcp"><span class="mnote-extensions-loading">加载中...</span></div>' +
|
||||
'</div>' +
|
||||
'<div class="mnote-extensions-subpanel" data-extensions-panel="tools" hidden>' +
|
||||
'<div class="mnote-extensions-status" data-extensions-status="tools"><span class="mnote-extensions-loading">加载中...</span></div>' +
|
||||
'</div>' +
|
||||
@@ -625,17 +621,12 @@ export function createSidebarPageSettingsRuntime(context) {
|
||||
'<div class="mnote-dashboard-card" data-dashboard-card="skills">' +
|
||||
'<div class="mnote-dashboard-card-title">Skills</div>' +
|
||||
'<div class="mnote-dashboard-card-value" data-dashboard-value="skills">--</div>' +
|
||||
'<div class="mnote-dashboard-card-desc">已安装 / 可用</div>' +
|
||||
'<div class="mnote-dashboard-card-desc">工具清单中的 skill 能力</div>' +
|
||||
'</div>' +
|
||||
'<div class="mnote-dashboard-card" data-dashboard-card="mcp">' +
|
||||
'<div class="mnote-dashboard-card-title">MCP</div>' +
|
||||
'<div class="mnote-dashboard-card-value" data-dashboard-value="mcp">--</div>' +
|
||||
'<div class="mnote-dashboard-card-desc">服务器 / 已连接</div>' +
|
||||
'</div>' +
|
||||
'<div class="mnote-dashboard-card" data-dashboard-card="agent">' +
|
||||
'<div class="mnote-dashboard-card-title">Agent Runs</div>' +
|
||||
'<div class="mnote-dashboard-card-value" data-dashboard-value="agent">--</div>' +
|
||||
'<div class="mnote-dashboard-card-desc">最近 7 天运行次数</div>' +
|
||||
'<div class="mnote-dashboard-card" data-dashboard-card="tools">' +
|
||||
'<div class="mnote-dashboard-card-title">Agent 工具</div>' +
|
||||
'<div class="mnote-dashboard-card-value" data-dashboard-value="tools">--</div>' +
|
||||
'<div class="mnote-dashboard-card-desc">/api/mnote/tools/manifest</div>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'<button type="button" class="wolai-page-settings-index-add" style="margin-top:10px" data-dashboard-action="refresh">刷新仪表盘</button>' +
|
||||
@@ -3003,10 +2994,29 @@ export function createSidebarPageSettingsRuntime(context) {
|
||||
// 切换时懒加载对应面板数据
|
||||
if (subtabName === 'knowledge') refreshKnowledgeExtensionsPanel();
|
||||
else if (subtabName === 'skills') refreshSkillsExtensionsPanel();
|
||||
else if (subtabName === 'mcp') refreshMcpExtensionsPanel();
|
||||
else if (subtabName === 'tools') refreshToolsExtensionsPanel();
|
||||
}
|
||||
|
||||
async function fetchAgentToolsManifest() {
|
||||
var resp = await fetch('/api/mnote/tools/manifest');
|
||||
if (!resp.ok) throw new Error('HTTP ' + resp.status);
|
||||
var data = await resp.json();
|
||||
var tools = Array.isArray(data && data.tools) ? data.tools : [];
|
||||
var capabilities = data && data.capabilities && typeof data.capabilities === 'object'
|
||||
? data.capabilities
|
||||
: {};
|
||||
return { data: data, tools: tools, capabilities: capabilities };
|
||||
}
|
||||
|
||||
function isSkillRelatedTool(tool) {
|
||||
if (!tool || typeof tool !== 'object') return false;
|
||||
var name = String(tool.name || tool.function_name || '');
|
||||
if (/skill/i.test(name)) return true;
|
||||
var scopes = tool.capabilityScope || tool.capabilities || [];
|
||||
if (Array.isArray(scopes) && scopes.some(function(s) { return /skill/i.test(String(s)); })) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// 当切换到扩展 tab 时刷新当前子面板
|
||||
function refreshExtensionsPanel() {
|
||||
var popover = ensurePageSettingsPopover();
|
||||
@@ -3051,26 +3061,30 @@ export function createSidebarPageSettingsRuntime(context) {
|
||||
}
|
||||
}
|
||||
|
||||
// --- Skills 子面板 ---
|
||||
// --- Skills 子面板(来自 /api/mnote/tools/manifest,非历史 agent 网关) ---
|
||||
async function refreshSkillsExtensionsPanel() {
|
||||
var statusEl = document.querySelector('[data-extensions-status="skills"]');
|
||||
if (!statusEl) return;
|
||||
statusEl.innerHTML = '<span class="mnote-extensions-loading">加载中...</span>';
|
||||
try {
|
||||
var resp = await fetch('/api/page-ai/agent-descriptors');
|
||||
if (!resp.ok) throw new Error('HTTP ' + resp.status);
|
||||
var data = await resp.json();
|
||||
var descriptors = data.descriptors || data || [];
|
||||
// 从 agent descriptor 中收集 skills 信息
|
||||
var pack = await fetchAgentToolsManifest();
|
||||
var allSkills = [];
|
||||
descriptors.forEach(function(desc) {
|
||||
var caps = desc.capabilities || desc.capabilityStates || {};
|
||||
if (caps.skills && Array.isArray(caps.skills)) {
|
||||
caps.skills.forEach(function(s) { allSkills.push({ name: s, source: desc.name || desc.id || 'unknown' }); });
|
||||
}
|
||||
pack.tools.forEach(function(tool) {
|
||||
if (!isSkillRelatedTool(tool)) return;
|
||||
allSkills.push({
|
||||
name: tool.name || tool.function_name || 'skill',
|
||||
source: 'mnote-agent-tools'
|
||||
});
|
||||
});
|
||||
var caps = pack.capabilities;
|
||||
Object.keys(caps).forEach(function(key) {
|
||||
if (!/skill/i.test(key)) return;
|
||||
var entry = caps[key];
|
||||
var label = entry && (entry.name || entry.id) ? (entry.name || entry.id) : key;
|
||||
allSkills.push({ name: String(label), source: 'capability' });
|
||||
});
|
||||
if (!allSkills.length) {
|
||||
allSkills.push({ name: 'skill-read (内置)', source: 'hermes' });
|
||||
allSkills.push({ name: 'mnote.skill.read', source: 'builtin' });
|
||||
}
|
||||
var html = '';
|
||||
allSkills.forEach(function(skill) {
|
||||
@@ -3078,63 +3092,29 @@ export function createSidebarPageSettingsRuntime(context) {
|
||||
'<div class="mnote-extensions-item-row"><span class="mnote-extensions-label">' + escapeHtml(skill.name) + '</span><span class="mnote-extensions-source">' + escapeHtml(skill.source) + '</span></div>' +
|
||||
'</div>';
|
||||
});
|
||||
if (!html) html = '<div class="mnote-extensions-item"><span>暂无已安装 Skills</span></div>';
|
||||
if (!html) html = '<div class="mnote-extensions-item"><span>暂无 Skills</span></div>';
|
||||
statusEl.innerHTML = html;
|
||||
} catch (err) {
|
||||
statusEl.innerHTML = '<div class="mnote-extensions-item"><span class="mnote-extensions-error">无法加载 Skills 信息</span></div>';
|
||||
}
|
||||
}
|
||||
|
||||
// --- MCP 子面板 ---
|
||||
async function refreshMcpExtensionsPanel() {
|
||||
var statusEl = document.querySelector('[data-extensions-status="mcp"]');
|
||||
if (!statusEl) return;
|
||||
statusEl.innerHTML = '<span class="mnote-extensions-loading">加载中...</span>';
|
||||
try {
|
||||
var resp = await fetch('/api/hermes/mcp/servers');
|
||||
if (!resp.ok) throw new Error('HTTP ' + resp.status);
|
||||
var servers = await resp.json();
|
||||
var list = Array.isArray(servers) ? servers : (servers.servers || []);
|
||||
var html = '';
|
||||
if (list.length === 0) {
|
||||
html = '<div class="mnote-extensions-item"><span>暂无已配置 MCP 服务器</span></div>';
|
||||
} else {
|
||||
list.forEach(function(srv) {
|
||||
var name = srv.name || srv.id || '未命名';
|
||||
var url = srv.url || srv.command || '';
|
||||
var connected = srv.connected ? '已连接' : '未连接';
|
||||
var connClass = srv.connected ? 'mnote-status-ready' : 'mnote-status-pending';
|
||||
html += '<div class="mnote-extensions-item">' +
|
||||
'<div class="mnote-extensions-item-row"><span class="mnote-extensions-label">' + escapeHtml(name) + '</span><span class="' + connClass + '">' + connected + '</span></div>' +
|
||||
(url ? '<div class="mnote-extensions-item-row"><span class="mnote-extensions-detail">' + escapeHtml(String(url)) + '</span></div>' : '') +
|
||||
'</div>';
|
||||
});
|
||||
}
|
||||
statusEl.innerHTML = html;
|
||||
} catch (err) {
|
||||
statusEl.innerHTML = '<div class="mnote-extensions-item"><span class="mnote-extensions-error">无法加载 MCP 配置</span></div>';
|
||||
}
|
||||
}
|
||||
|
||||
// --- Agent 工具子面板 ---
|
||||
async function refreshToolsExtensionsPanel() {
|
||||
var statusEl = document.querySelector('[data-extensions-status="tools"]');
|
||||
if (!statusEl) return;
|
||||
statusEl.innerHTML = '<span class="mnote-extensions-loading">加载中...</span>';
|
||||
try {
|
||||
var resp = await fetch('/api/page-ai/agent-descriptors');
|
||||
if (!resp.ok) throw new Error('HTTP ' + resp.status);
|
||||
var data = await resp.json();
|
||||
var descriptors = data.descriptors || data || [];
|
||||
var pack = await fetchAgentToolsManifest();
|
||||
var html = '';
|
||||
descriptors.forEach(function(desc) {
|
||||
var tools = desc.tools || [];
|
||||
var name = desc.name || desc.id || 'unknown';
|
||||
if (!tools.length) return;
|
||||
if (!pack.tools.length) {
|
||||
html = '<div class="mnote-extensions-item"><span>暂无 Agent 工具信息</span></div>';
|
||||
} else {
|
||||
html += '<div class="mnote-extensions-item mnote-extensions-agent-group">' +
|
||||
'<div class="mnote-extensions-agent-name">' + escapeHtml(name) + '</div>';
|
||||
tools.forEach(function(tool) {
|
||||
'<div class="mnote-extensions-agent-name">mnote agent tools</div>';
|
||||
pack.tools.forEach(function(tool) {
|
||||
var toolName = tool.name || tool.function_name || '';
|
||||
if (!toolName) return;
|
||||
var disabled = tool.disabled ? ' (已禁用)' : '';
|
||||
html += '<div class="mnote-extensions-tool-item">' +
|
||||
'<span class="mnote-extensions-tool-name">' + escapeHtml(toolName) + '</span>' +
|
||||
@@ -3142,8 +3122,7 @@ export function createSidebarPageSettingsRuntime(context) {
|
||||
'</div>';
|
||||
});
|
||||
html += '</div>';
|
||||
});
|
||||
if (!html) html = '<div class="mnote-extensions-item"><span>暂无 Agent 工具信息</span></div>';
|
||||
}
|
||||
statusEl.innerHTML = html;
|
||||
} catch (err) {
|
||||
statusEl.innerHTML = '<div class="mnote-extensions-item"><span class="mnote-extensions-error">无法加载 Agent 工具信息</span></div>';
|
||||
@@ -3371,14 +3350,9 @@ export function createSidebarPageSettingsRuntime(context) {
|
||||
// --- 仪表盘 ---
|
||||
function refreshDashboardPanel() {
|
||||
var popover = ensurePageSettingsPopover();
|
||||
// 知识库状态
|
||||
refreshDashboardKnowledgeCard(popover);
|
||||
// Skills
|
||||
refreshDashboardSkillsCard(popover);
|
||||
// MCP
|
||||
refreshDashboardMcpCard(popover);
|
||||
// Agent runs
|
||||
refreshDashboardAgentCard(popover);
|
||||
refreshDashboardToolsCard(popover);
|
||||
}
|
||||
|
||||
async function refreshDashboardKnowledgeCard(popover) {
|
||||
@@ -3408,49 +3382,22 @@ export function createSidebarPageSettingsRuntime(context) {
|
||||
if (!el) return;
|
||||
el.textContent = '加载中...';
|
||||
try {
|
||||
var resp = await fetch('/api/page-ai/agent-descriptors');
|
||||
if (!resp.ok) throw new Error('HTTP ' + resp.status);
|
||||
var data = await resp.json();
|
||||
var descriptors = data.descriptors || data || [];
|
||||
var count = 0;
|
||||
descriptors.forEach(function(d) {
|
||||
var caps = d.capabilities || d.capabilityStates || {};
|
||||
if (caps.skills && Array.isArray(caps.skills)) count += caps.skills.length;
|
||||
});
|
||||
if (!count) count = 1; // skill-read 内置
|
||||
var pack = await fetchAgentToolsManifest();
|
||||
var count = pack.tools.filter(isSkillRelatedTool).length;
|
||||
if (!count) count = 1; // mnote.skill.read 内置
|
||||
el.textContent = count + ' 个';
|
||||
} catch (_) {
|
||||
el.textContent = '--';
|
||||
}
|
||||
}
|
||||
|
||||
async function refreshDashboardMcpCard(popover) {
|
||||
var el = popover.querySelector('[data-dashboard-value="mcp"]');
|
||||
async function refreshDashboardToolsCard(popover) {
|
||||
var el = popover.querySelector('[data-dashboard-value="tools"]');
|
||||
if (!el) return;
|
||||
el.textContent = '加载中...';
|
||||
try {
|
||||
var resp = await fetch('/api/hermes/mcp/servers');
|
||||
if (!resp.ok) throw new Error('HTTP ' + resp.status);
|
||||
var servers = await resp.json();
|
||||
var list = Array.isArray(servers) ? servers : (servers.servers || []);
|
||||
var connected = list.filter(function(s) { return s.connected; }).length;
|
||||
el.textContent = list.length + ' / ' + connected + ' 已连接';
|
||||
} catch (_) {
|
||||
el.textContent = '--';
|
||||
}
|
||||
}
|
||||
|
||||
async function refreshDashboardAgentCard(popover) {
|
||||
var el = popover.querySelector('[data-dashboard-value="agent"]');
|
||||
if (!el) return;
|
||||
el.textContent = '加载中...';
|
||||
try {
|
||||
var resp = await fetch('/api/hermes/client/runs?limit=100');
|
||||
if (!resp.ok) throw new Error('HTTP ' + resp.status);
|
||||
var data = await resp.json();
|
||||
var runs = Array.isArray(data) ? data : (data.runs || []);
|
||||
var recentCount = runs.length;
|
||||
el.textContent = recentCount + ' 次';
|
||||
var pack = await fetchAgentToolsManifest();
|
||||
el.textContent = pack.tools.length + ' 个';
|
||||
} catch (_) {
|
||||
el.textContent = '--';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user