auto-save 2026-05-11 17:39 (~4)
This commit is contained in:
@@ -1,18 +1,5 @@
|
|||||||
{
|
{
|
||||||
"entries": [
|
"entries": [
|
||||||
{
|
|
||||||
"files_changed": 1,
|
|
||||||
"hash": "8a6ae80",
|
|
||||||
"message": "auto-save 2026-05-10 08:50 (~1)",
|
|
||||||
"ts": "2026-05-10T08:50:53+08:00",
|
|
||||||
"type": "commit"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"files_changed": 1,
|
|
||||||
"message": "Codex 会话活跃 · 最近命令:codex · 分支 master · 1 项未提交变更 · 最近提交:auto-save 2026-05-10 08:50 (~1)",
|
|
||||||
"ts": "2026-05-10T00:56:24Z",
|
|
||||||
"type": "session-heartbeat"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"files_changed": 1,
|
"files_changed": 1,
|
||||||
"hash": "6f92814",
|
"hash": "6f92814",
|
||||||
@@ -3265,6 +3252,19 @@
|
|||||||
"message": "auto-save 2026-05-11 17:27 (~4)",
|
"message": "auto-save 2026-05-11 17:27 (~4)",
|
||||||
"hash": "c4716b8",
|
"hash": "c4716b8",
|
||||||
"files_changed": 4
|
"files_changed": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-11T17:33:29+08:00",
|
||||||
|
"type": "commit",
|
||||||
|
"message": "auto-save 2026-05-11 17:33 (~1)",
|
||||||
|
"hash": "5b3c07c",
|
||||||
|
"files_changed": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ts": "2026-05-11T09:36:29Z",
|
||||||
|
"type": "session-heartbeat",
|
||||||
|
"message": "Codex 会话活跃 · 最近命令:codex · 分支 master · 3 项未提交变更 · 最近提交:auto-save 2026-05-11 17:33 (~1)",
|
||||||
|
"files_changed": 3
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
13
src/app.js
13
src/app.js
@@ -644,16 +644,21 @@ function switchTab(name, options = {}) {
|
|||||||
}
|
}
|
||||||
if (name === "cron") refreshCron();
|
if (name === "cron") refreshCron();
|
||||||
if (name === "memory") refreshMemory();
|
if (name === "memory") refreshMemory();
|
||||||
if (name === "tools") refreshTools();
|
if (name === "models") {
|
||||||
if (name === "integrations") refreshFeishuApps();
|
|
||||||
if (name === "settings") {
|
|
||||||
renderWeeklyReports();
|
|
||||||
renderModelProfiles();
|
renderModelProfiles();
|
||||||
refreshUiConfig().catch((error) => {
|
refreshUiConfig().catch((error) => {
|
||||||
setSharedConfigStatus("共享配置读取失败: " + (error.message || error), true);
|
setSharedConfigStatus("共享配置读取失败: " + (error.message || error), true);
|
||||||
});
|
});
|
||||||
refreshHermesConfig();
|
refreshHermesConfig();
|
||||||
}
|
}
|
||||||
|
if (name === "tools") {
|
||||||
|
refreshTools();
|
||||||
|
refreshHermesConfig();
|
||||||
|
}
|
||||||
|
if (name === "integrations") refreshFeishuApps();
|
||||||
|
if (name === "settings") {
|
||||||
|
renderWeeklyReports();
|
||||||
|
}
|
||||||
if (name === "runs") setTimeout(() => document.getElementById("runPrompt")?.focus(), 50);
|
if (name === "runs") setTimeout(() => document.getElementById("runPrompt")?.focus(), 50);
|
||||||
if (name === "dashboard" && _dashboardDirty) {
|
if (name === "dashboard" && _dashboardDirty) {
|
||||||
// 推迟到下一帧,避免阻塞切换动画
|
// 推迟到下一帧,避免阻塞切换动画
|
||||||
|
|||||||
287
src/index.html
287
src/index.html
@@ -11,7 +11,7 @@
|
|||||||
<link rel="icon" type="image/svg+xml" href="./icon.svg">
|
<link rel="icon" type="image/svg+xml" href="./icon.svg">
|
||||||
<link rel="apple-touch-icon" href="./icon.svg">
|
<link rel="apple-touch-icon" href="./icon.svg">
|
||||||
<title>爱马仕 · AI</title>
|
<title>爱马仕 · AI</title>
|
||||||
<link rel="stylesheet" href="./styles.css?v=20260511-whiteout-v32">
|
<link rel="stylesheet" href="./styles.css?v=20260511-settings-ia-v33">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
@@ -62,6 +62,10 @@
|
|||||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2a5 5 0 0 0-5 5v2H5a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-9a2 2 0 0 0-2-2h-2V7a5 5 0 0 0-5-5z"/><circle cx="9" cy="14" r="1"/><circle cx="15" cy="14" r="1"/></svg>
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2a5 5 0 0 0-5 5v2H5a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-9a2 2 0 0 0-2-2h-2V7a5 5 0 0 0-5-5z"/><circle cx="9" cy="14" r="1"/><circle cx="15" cy="14" r="1"/></svg>
|
||||||
<span>Agent</span>
|
<span>Agent</span>
|
||||||
</button>
|
</button>
|
||||||
|
<button class="side-item" data-tab="models">
|
||||||
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2v20"/><path d="M2 12h20"/><path d="M4.93 4.93 19.07 19.07"/><path d="M19.07 4.93 4.93 19.07"/></svg>
|
||||||
|
<span>模型</span>
|
||||||
|
</button>
|
||||||
<button class="side-item" data-tab="integrations">
|
<button class="side-item" data-tab="integrations">
|
||||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/><path d="M10 6.5h4"/><path d="M6.5 10v4"/><path d="M17.5 10v4"/><path d="M10 17.5h4"/></svg>
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/><path d="M10 6.5h4"/><path d="M6.5 10v4"/><path d="M17.5 10v4"/><path d="M10 17.5h4"/></svg>
|
||||||
<span>集成</span>
|
<span>集成</span>
|
||||||
@@ -641,6 +645,130 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<!-- TAB: 模型 -->
|
||||||
|
<section class="tab-panel" id="tab-models">
|
||||||
|
<div class="panel-head">
|
||||||
|
<div class="panel-head-row">
|
||||||
|
<div>
|
||||||
|
<h2>模型</h2>
|
||||||
|
<p>管理 AI 模型 Profiles、Provider、Base URL 与线上 Hermes agent 默认运行模型。</p>
|
||||||
|
</div>
|
||||||
|
<div class="panel-head-actions">
|
||||||
|
<button class="glass-btn-sm" onclick="refreshHermesConfig(true)">
|
||||||
|
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12a9 9 0 0 1 15.5-6.3L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-15.5 6.3L3 16"/><path d="M3 21v-5h5"/></svg>
|
||||||
|
读取运行配置
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="models-scroll settings-scroll">
|
||||||
|
<div class="settings-group wide">
|
||||||
|
<div class="settings-group-head">
|
||||||
|
<div class="settings-group-icon">
|
||||||
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2v20"/><path d="M2 12h20"/><path d="M4.93 4.93 19.07 19.07"/><path d="M19.07 4.93 4.93 19.07"/></svg>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="settings-group-title">运行模型</div>
|
||||||
|
<div class="settings-group-desc">线上 Hermes agent 当前默认调用的模型接入配置</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="settings-group-body">
|
||||||
|
<div class="settings-grid-3">
|
||||||
|
<div class="settings-field">
|
||||||
|
<label for="hermesModelDefault">默认模型 ID</label>
|
||||||
|
<input type="text" id="hermesModelDefault" placeholder="google/gemini-3.1-pro-preview" autocomplete="off">
|
||||||
|
</div>
|
||||||
|
<div class="settings-field">
|
||||||
|
<label for="hermesModelProvider">Provider</label>
|
||||||
|
<input type="text" id="hermesModelProvider" placeholder="openrouter" autocomplete="off">
|
||||||
|
</div>
|
||||||
|
<div class="settings-field">
|
||||||
|
<label for="hermesModelBaseUrl">Base URL</label>
|
||||||
|
<input type="text" id="hermesModelBaseUrl" placeholder="https://openrouter.ai/api/v1" autocomplete="off">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="settings-grid-3">
|
||||||
|
<div class="settings-field">
|
||||||
|
<label for="hermesModelApiKeyRef">AI API Key</label>
|
||||||
|
<input type="password" id="hermesModelApiKeyRef" placeholder="服务器环境变量,不在浏览器显示" disabled>
|
||||||
|
<div class="settings-help">真实 Key 仍只放在服务器环境变量;这里不保存、不回显密钥。</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="settings-actions">
|
||||||
|
<button class="glass-btn-sm" onclick="refreshHermesConfig(true)">读取模型配置</button>
|
||||||
|
<button class="glass-btn-sm primary" id="hermesModelSaveBtn" onclick="saveModelConfig()">
|
||||||
|
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.3" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/><path d="M17 21v-8H7v8"/><path d="M7 3v5h8"/></svg>
|
||||||
|
保存模型并重启
|
||||||
|
</button>
|
||||||
|
<div class="settings-help" id="hermesModelStatus">打开模型页后自动读取。</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="settings-group wide">
|
||||||
|
<div class="settings-group-head">
|
||||||
|
<div class="settings-group-icon">
|
||||||
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="4" y="4" width="16" height="16" rx="2"/><path d="M9 9h6v6H9z"/><path d="M9 1v3"/><path d="M15 1v3"/><path d="M9 20v3"/><path d="M15 20v3"/><path d="M20 9h3"/><path d="M20 14h3"/><path d="M1 9h3"/><path d="M1 14h3"/></svg>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="settings-group-title">模型 Profiles</div>
|
||||||
|
<div class="settings-group-desc">给不同 Agent 绑定不同模型、Provider、Base URL 和服务器端 Key 引用</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="settings-group-body">
|
||||||
|
<div class="settings-subpanel">
|
||||||
|
<div class="settings-subpanel-head">
|
||||||
|
<div>
|
||||||
|
<div class="settings-subtitle">已配置 Profiles</div>
|
||||||
|
<div class="settings-help" id="modelProfilesCount">用于给不同智能体绑定不同模型接入信息。</div>
|
||||||
|
</div>
|
||||||
|
<button class="glass-btn-sm" type="button" onclick="clearModelProfileForm()">新增 Profile</button>
|
||||||
|
</div>
|
||||||
|
<div class="model-profile-list" id="modelProfilesList">
|
||||||
|
<div class="settings-help">正在读取服务器共享配置...</div>
|
||||||
|
</div>
|
||||||
|
<div class="model-profile-form">
|
||||||
|
<div class="settings-subtitle" id="modelProfileFormTitle">新增模型 Profile</div>
|
||||||
|
<div class="settings-grid-3">
|
||||||
|
<div class="settings-field">
|
||||||
|
<label for="modelProfileName">显示名</label>
|
||||||
|
<input type="text" id="modelProfileName" placeholder="例如 OpenRouter Gemini" autocomplete="off">
|
||||||
|
</div>
|
||||||
|
<div class="settings-field">
|
||||||
|
<label for="modelProfileProvider">Provider</label>
|
||||||
|
<input type="text" id="modelProfileProvider" placeholder="openrouter / openai / anthropic" autocomplete="off">
|
||||||
|
</div>
|
||||||
|
<div class="settings-field">
|
||||||
|
<label for="modelProfileModel">模型 ID</label>
|
||||||
|
<input type="text" id="modelProfileModel" placeholder="google/gemini-3.1-pro-preview" autocomplete="off">
|
||||||
|
</div>
|
||||||
|
<div class="settings-field">
|
||||||
|
<label for="modelProfileBaseUrl">Base URL</label>
|
||||||
|
<input type="text" id="modelProfileBaseUrl" placeholder="https://openrouter.ai/api/v1" autocomplete="off">
|
||||||
|
</div>
|
||||||
|
<div class="settings-field">
|
||||||
|
<label for="modelProfileApiKeyRef">API Key 引用</label>
|
||||||
|
<input type="text" id="modelProfileApiKeyRef" placeholder="OPENROUTER_API_KEY / 服务器环境变量" autocomplete="off">
|
||||||
|
<div class="settings-help">只填服务器环境变量名;前端不保存真实 Key。Agent 使用该 Profile 时会由桥接服务代理请求。</div>
|
||||||
|
</div>
|
||||||
|
<div class="settings-field model-profile-checks">
|
||||||
|
<label class="settings-checkline"><input type="checkbox" id="modelProfileEnabled" checked> 启用</label>
|
||||||
|
<label class="settings-checkline"><input type="checkbox" id="modelProfileDefault"> 作为默认</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="settings-actions">
|
||||||
|
<button class="glass-btn-sm primary" type="button" onclick="saveModelProfile()">保存 Profile</button>
|
||||||
|
<button class="glass-btn-sm" type="button" onclick="clearModelProfileForm()">清空表单</button>
|
||||||
|
<div class="settings-help" id="sharedConfigStatus">共享配置会保存到服务器,供同事端同步。</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<!-- TAB: 工具 (真实 Hermes tools list) -->
|
<!-- TAB: 工具 (真实 Hermes tools list) -->
|
||||||
<section class="tab-panel" id="tab-tools">
|
<section class="tab-panel" id="tab-tools">
|
||||||
<div class="panel-head">
|
<div class="panel-head">
|
||||||
@@ -657,7 +785,39 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="tools-grid" id="toolsGrid">加载中…</div>
|
<div class="tools-scroll">
|
||||||
|
<div class="tools-grid" id="toolsGrid">加载中…</div>
|
||||||
|
|
||||||
|
<div class="settings-group wide tools-mcp-group">
|
||||||
|
<div class="settings-group-head">
|
||||||
|
<div class="settings-group-icon">
|
||||||
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/><path d="M3.3 7 12 12l8.7-5"/><path d="M12 22V12"/></svg>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="settings-group-title">MCP 工具接入</div>
|
||||||
|
<div class="settings-group-desc">外部工具、知识库和服务调用配置</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="settings-group-body">
|
||||||
|
<div class="settings-field">
|
||||||
|
<label for="mcpServersYaml">MCP Servers YAML</label>
|
||||||
|
<textarea id="mcpServersYaml" rows="8" spellcheck="false" placeholder='mcp_servers:
|
||||||
|
time:
|
||||||
|
command: uvx
|
||||||
|
args: ["mcp-server-time"]'></textarea>
|
||||||
|
<div class="settings-help">留空会移除 <code>mcp_servers</code>;保存只改工具接入,不要求同时填写模型配置。</div>
|
||||||
|
</div>
|
||||||
|
<div class="settings-actions">
|
||||||
|
<button class="glass-btn-sm" onclick="refreshHermesConfig(true)">读取 MCP 配置</button>
|
||||||
|
<button class="glass-btn-sm primary" id="hermesMcpSaveBtn" onclick="saveMcpConfig()">
|
||||||
|
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.3" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/><path d="M17 21v-8H7v8"/><path d="M7 3v5h8"/></svg>
|
||||||
|
保存 MCP 并重启
|
||||||
|
</button>
|
||||||
|
<div class="settings-help" id="hermesMcpStatus">打开工具页后自动读取。</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- TAB: 异步任务 (/v1/runs + SSE 事件流) -->
|
<!-- TAB: 异步任务 (/v1/runs + SSE 事件流) -->
|
||||||
@@ -1199,127 +1359,6 @@ git push # Gitea kangwan/hermes-glass-ui-personal
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- AI 模型接入 -->
|
|
||||||
<div class="settings-group wide">
|
|
||||||
<div class="settings-group-head">
|
|
||||||
<div class="settings-group-icon">
|
|
||||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2v20"/><path d="M2 12h20"/><path d="M4.93 4.93 19.07 19.07"/><path d="M19.07 4.93 4.93 19.07"/></svg>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div class="settings-group-title">AI 模型接入</div>
|
|
||||||
<div class="settings-group-desc">AI 模型 Profiles 与线上 Hermes agent 默认运行模型</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="settings-group-body">
|
|
||||||
<div class="settings-grid-3">
|
|
||||||
<div class="settings-field">
|
|
||||||
<label for="hermesModelDefault">默认模型 ID</label>
|
|
||||||
<input type="text" id="hermesModelDefault" placeholder="google/gemini-3.1-pro-preview" autocomplete="off">
|
|
||||||
</div>
|
|
||||||
<div class="settings-field">
|
|
||||||
<label for="hermesModelProvider">Provider</label>
|
|
||||||
<input type="text" id="hermesModelProvider" placeholder="openrouter" autocomplete="off">
|
|
||||||
</div>
|
|
||||||
<div class="settings-field">
|
|
||||||
<label for="hermesModelBaseUrl">Base URL</label>
|
|
||||||
<input type="text" id="hermesModelBaseUrl" placeholder="https://openrouter.ai/api/v1" autocomplete="off">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="settings-grid-3">
|
|
||||||
<div class="settings-field">
|
|
||||||
<label for="hermesModelApiKeyRef">AI API Key</label>
|
|
||||||
<input type="password" id="hermesModelApiKeyRef" placeholder="服务器环境变量,不在浏览器显示" disabled>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="settings-actions">
|
|
||||||
<button class="glass-btn-sm" onclick="refreshHermesConfig(true)">读取模型配置</button>
|
|
||||||
<button class="glass-btn-sm primary" id="hermesModelSaveBtn" onclick="saveModelConfig()">
|
|
||||||
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.3" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/><path d="M17 21v-8H7v8"/><path d="M7 3v5h8"/></svg>
|
|
||||||
保存模型并重启
|
|
||||||
</button>
|
|
||||||
<div class="settings-help" id="hermesModelStatus">打开设置页后自动读取。</div>
|
|
||||||
</div>
|
|
||||||
<div class="settings-subpanel">
|
|
||||||
<div class="settings-subpanel-head">
|
|
||||||
<div>
|
|
||||||
<div class="settings-subtitle">模型 Profiles</div>
|
|
||||||
<div class="settings-help" id="modelProfilesCount">用于给不同智能体绑定不同模型接入信息。</div>
|
|
||||||
</div>
|
|
||||||
<button class="glass-btn-sm" type="button" onclick="clearModelProfileForm()">新增 Profile</button>
|
|
||||||
</div>
|
|
||||||
<div class="model-profile-list" id="modelProfilesList">
|
|
||||||
<div class="settings-help">正在读取服务器共享配置...</div>
|
|
||||||
</div>
|
|
||||||
<div class="model-profile-form">
|
|
||||||
<div class="settings-subtitle" id="modelProfileFormTitle">新增模型 Profile</div>
|
|
||||||
<div class="settings-grid-3">
|
|
||||||
<div class="settings-field">
|
|
||||||
<label for="modelProfileName">显示名</label>
|
|
||||||
<input type="text" id="modelProfileName" placeholder="例如 OpenRouter Gemini" autocomplete="off">
|
|
||||||
</div>
|
|
||||||
<div class="settings-field">
|
|
||||||
<label for="modelProfileProvider">Provider</label>
|
|
||||||
<input type="text" id="modelProfileProvider" placeholder="openrouter / openai / anthropic" autocomplete="off">
|
|
||||||
</div>
|
|
||||||
<div class="settings-field">
|
|
||||||
<label for="modelProfileModel">模型 ID</label>
|
|
||||||
<input type="text" id="modelProfileModel" placeholder="google/gemini-3.1-pro-preview" autocomplete="off">
|
|
||||||
</div>
|
|
||||||
<div class="settings-field">
|
|
||||||
<label for="modelProfileBaseUrl">Base URL</label>
|
|
||||||
<input type="text" id="modelProfileBaseUrl" placeholder="https://openrouter.ai/api/v1" autocomplete="off">
|
|
||||||
</div>
|
|
||||||
<div class="settings-field">
|
|
||||||
<label for="modelProfileApiKeyRef">API Key 引用</label>
|
|
||||||
<input type="text" id="modelProfileApiKeyRef" placeholder="OPENROUTER_API_KEY / 服务器环境变量" autocomplete="off">
|
|
||||||
<div class="settings-help">只填服务器环境变量名;前端不保存真实 Key。Agent 使用该 Profile 时会由桥接服务代理请求。</div>
|
|
||||||
</div>
|
|
||||||
<div class="settings-field model-profile-checks">
|
|
||||||
<label class="settings-checkline"><input type="checkbox" id="modelProfileEnabled" checked> 启用</label>
|
|
||||||
<label class="settings-checkline"><input type="checkbox" id="modelProfileDefault"> 作为默认</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="settings-actions">
|
|
||||||
<button class="glass-btn-sm primary" type="button" onclick="saveModelProfile()">保存 Profile</button>
|
|
||||||
<button class="glass-btn-sm" type="button" onclick="clearModelProfileForm()">清空表单</button>
|
|
||||||
<div class="settings-help" id="sharedConfigStatus">共享配置会保存到服务器,供同事端同步。</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- MCP 工具接入 -->
|
|
||||||
<div class="settings-group wide">
|
|
||||||
<div class="settings-group-head">
|
|
||||||
<div class="settings-group-icon">
|
|
||||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/><path d="M3.3 7 12 12l8.7-5"/><path d="M12 22V12"/></svg>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<div class="settings-group-title">MCP 工具接入</div>
|
|
||||||
<div class="settings-group-desc">外部工具、知识库和服务调用配置</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="settings-group-body">
|
|
||||||
<div class="settings-field">
|
|
||||||
<label for="mcpServersYaml">MCP Servers YAML</label>
|
|
||||||
<textarea id="mcpServersYaml" rows="8" spellcheck="false" placeholder='mcp_servers:
|
|
||||||
time:
|
|
||||||
command: uvx
|
|
||||||
args: ["mcp-server-time"]'></textarea>
|
|
||||||
<div class="settings-help">留空会移除 <code>mcp_servers</code>;保存只改工具接入,不再要求同时填写模型配置。</div>
|
|
||||||
</div>
|
|
||||||
<div class="settings-actions">
|
|
||||||
<button class="glass-btn-sm" onclick="refreshHermesConfig(true)">读取 MCP 配置</button>
|
|
||||||
<button class="glass-btn-sm primary" id="hermesMcpSaveBtn" onclick="saveMcpConfig()">
|
|
||||||
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.3" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/><path d="M17 21v-8H7v8"/><path d="M7 3v5h8"/></svg>
|
|
||||||
保存 MCP 并重启
|
|
||||||
</button>
|
|
||||||
<div class="settings-help" id="hermesMcpStatus">打开设置页后自动读取。</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 对话偏好 -->
|
<!-- 对话偏好 -->
|
||||||
<div class="settings-group">
|
<div class="settings-group">
|
||||||
<div class="settings-group-head">
|
<div class="settings-group-head">
|
||||||
@@ -1462,6 +1501,6 @@ git push # Gitea kangwan/hermes-glass-ui-personal
|
|||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="./app.js?v=20260511-whiteout-v32"></script>
|
<script src="./app.js?v=20260511-settings-ia-v33"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -3558,8 +3558,37 @@ a { color: var(--orange-3); text-decoration: none; }
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ========== Tools ========== */
|
/* ========== Tools ========== */
|
||||||
|
.models-scroll {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tab-models,
|
||||||
|
#tab-tools {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tab-models .settings-subpanel {
|
||||||
|
border: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
background: transparent;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tools-scroll {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
min-height: 0;
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
padding-right: 6px;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: minmax(0, 1.15fr) minmax(360px, 0.85fr);
|
||||||
|
align-items: start;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
.tools-grid {
|
.tools-grid {
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
|
min-height: 0;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
padding-right: 6px;
|
padding-right: 6px;
|
||||||
display: grid;
|
display: grid;
|
||||||
@@ -3567,6 +3596,31 @@ a { color: var(--orange-3); text-decoration: none; }
|
|||||||
gap: 10px;
|
gap: 10px;
|
||||||
align-content: start;
|
align-content: start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tools-scroll .tools-grid {
|
||||||
|
overflow: visible;
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tools-mcp-group {
|
||||||
|
grid-column: auto;
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tools-mcp-group .settings-field textarea {
|
||||||
|
min-height: min(360px, 42vh);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1180px) {
|
||||||
|
.tools-scroll {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
.tools-mcp-group {
|
||||||
|
position: static;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.tool-chip {
|
.tool-chip {
|
||||||
padding: 14px 16px;
|
padding: 14px 16px;
|
||||||
background: var(--card-bg);
|
background: var(--card-bg);
|
||||||
|
|||||||
Reference in New Issue
Block a user