diff --git a/rust/crates/mnote-web/src/ssr/pages/layout.rs b/rust/crates/mnote-web/src/ssr/pages/layout.rs
index 9efb2bcd..217e63b6 100644
--- a/rust/crates/mnote-web/src/ssr/pages/layout.rs
+++ b/rust/crates/mnote-web/src/ssr/pages/layout.rs
@@ -3634,15 +3634,18 @@ const SIDEBAR_TREE_JS: &str = r##"
button.classList.toggle('is-active', active);
button.setAttribute('aria-pressed', active ? 'true' : 'false');
});
- var subtitle = drawer.querySelector('.wolai-page-ai-subtitle');
- if (subtitle instanceof HTMLElement) {
- subtitle.textContent = '当前页面上下文优先 · ' + pageAiProviderLabel(pageUiState.pageAiProvider);
+ var providerNode = drawer.querySelector('.wolai-page-ai-subtitle span:first-child');
+ if (providerNode instanceof HTMLElement) {
+ providerNode.textContent = pageAiProviderLabel(pageUiState.pageAiProvider);
}
}
function renderPageAiControls() {
var drawer = ensurePageAiDrawer();
var activeProfile = pageAiCurrentProfile();
+ drawer.setAttribute('data-page-ai-page', pageUiState.pageAiPage || 'chat');
+ var profileSummary = drawer.querySelector('[data-page-ai-profile-summary]');
+ if (profileSummary instanceof HTMLElement) profileSummary.textContent = activeProfile;
var profileSelect = drawer.querySelector('[data-page-ai-profile-select]');
if (profileSelect instanceof HTMLSelectElement) {
var profiles = pageUiState.pageAiProfiles.length ? pageUiState.pageAiProfiles : [{ name: activeProfile, active: true }];
@@ -3696,8 +3699,10 @@ const SIDEBAR_TREE_JS: &str = r##"
}
var memoryError = drawer.querySelector('[data-page-ai-memory-error]');
if (memoryError instanceof HTMLElement) {
- memoryError.textContent = pageUiState.pageAiProfileMemoryError || '';
- memoryError.hidden = !pageUiState.pageAiProfileMemoryError;
+ var memoryErrorText = pageUiState.pageAiProfileMemoryError || '';
+ if (memoryErrorText && memoryErrorText === pageUiState.pageAiProfileError) memoryErrorText = '';
+ memoryError.textContent = memoryErrorText;
+ memoryError.hidden = !memoryErrorText;
}
var agentPanel = drawer.querySelector('[data-page-ai-agent-panel]');
if (agentPanel instanceof HTMLElement) {
@@ -3814,53 +3819,27 @@ const SIDEBAR_TREE_JS: &str = r##"
'
' +
- '' +
- '
' +
- '会话' +
- '等待 Hermes session' +
- '
' +
- '
' +
- '状态' +
- '空闲' +
- '
' +
- '
' +
- '模型' +
- '由 Hermes 决定' +
- '
' +
- '
' +
- '上下文' +
- '当前页' +
- '
' +
- '
' +
- '
' +
- '' +
- '
' +
- '' +
- '' +
- '' +
- '' +
- '
' +
'
' +
+ '' +
+ '' +
+ '当前页' +
+ '空闲' +
+ '
' +
+ '' +
'' +
- '' +
- '
' +
- 'mnote tools' +
- '暂无 tool call' +
- '
' +
- '
' +
- '
' +
- '
' +
- '' +
'' +
'
' +
+ '' +
+ '
' +
+ '
' +
+ '' +
+ '' +
+ '' +
+ '
' +
+ '
' +
+ '' +
+ '' +
+ '' +
+ '
' +
+ '' +
'' +
'' +
'' +
'
' +
+ '' +
+ '
' +
+ '
' +
+ '' +
+ '' +
+ '' +
+ '
' +
+ '
' +
'' +
'
' +
'';
@@ -3920,6 +3945,10 @@ const SIDEBAR_TREE_JS: &str = r##"
var drawer = ensurePageAiDrawer();
var list = drawer.querySelector('[data-page-ai-panel="chat"] [data-page-ai-suggestion-list]');
if (!(list instanceof HTMLElement)) return;
+ var container = list.closest('.wolai-page-ai-suggestions');
+ if (container instanceof HTMLElement) {
+ container.hidden = pageUiState.pageAiPage !== 'chat' || pageUiState.pageAiMessages.length > 0;
+ }
var suggestions = pageAiSuggestions();
var offset = pageUiState.pageAiSuggestionIndex % suggestions.length;
var ordered = suggestions.slice(offset).concat(suggestions.slice(0, offset)).slice(0, 3);
@@ -3930,6 +3959,7 @@ const SIDEBAR_TREE_JS: &str = r##"
function renderPageAiConversation() {
var drawer = ensurePageAiDrawer();
+ renderPageAiSuggestions();
var conversation = drawer.querySelector('[data-page-ai-panel="' + cssEscape(pageUiState.pageAiPage || 'chat') + '"] [data-page-ai-conversation]');
if (!(conversation instanceof HTMLElement)) return;
if (pageUiState.pageAiPage === 'history') {
diff --git a/rust/crates/mnote-web/src/ssr/styles.rs b/rust/crates/mnote-web/src/ssr/styles.rs
index a0fc7abe..b398edab 100644
--- a/rust/crates/mnote-web/src/ssr/styles.rs
+++ b/rust/crates/mnote-web/src/ssr/styles.rs
@@ -2654,10 +2654,10 @@ body {
height: 100%;
display: flex;
flex-direction: column;
- gap: 14px;
- padding: 16px;
+ gap: 12px;
+ padding: 14px;
border: 1px solid rgba(27, 28, 28, 0.08);
- border-radius: 18px;
+ border-radius: 14px;
background: rgba(255, 255, 255, 0.98);
box-shadow: -18px 0 42px rgba(27, 28, 28, 0.14);
}
@@ -2668,19 +2668,28 @@ body {
gap: 4px;
}
-.wolai-page-ai-statusbar {
- display: grid;
- grid-template-columns: minmax(0, 1fr) minmax(68px, auto) minmax(82px, auto) minmax(72px, auto) auto;
- gap: 8px;
- align-items: stretch;
+.wolai-page-ai-header-actions {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
}
-.wolai-page-ai-statusitem {
- min-width: 0;
- padding: 8px;
- border: 1px solid rgba(27, 28, 28, 0.08);
- border-radius: 8px;
- background: #FAFAFA;
+.wolai-page-ai-icon {
+ width: 28px;
+ height: 28px;
+ border: 0;
+ border-radius: 6px;
+ background: transparent;
+ color: #5A5A5A;
+ font-size: 16px;
+ line-height: 1;
+ cursor: pointer;
+}
+
+.wolai-page-ai-icon:hover,
+.wolai-page-ai-icon.is-active {
+ background: #F3F3F2;
+ color: #1B1C1C;
}
.wolai-page-ai-statuslabel,
@@ -2695,6 +2704,27 @@ body {
line-height: 16px;
}
+.wolai-page-ai-subtitle {
+ display: flex;
+ min-width: 0;
+ flex-wrap: wrap;
+ gap: 4px 8px;
+}
+
+.wolai-page-ai-subtitle span {
+ min-width: 0;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.wolai-page-ai-subtitle span:not(:first-child)::before,
+.wolai-page-ai-chat-meta span:not(:first-child)::before {
+ margin-right: 8px;
+ color: #C9C5BE;
+ content: "·";
+}
+
.wolai-page-ai-statusvalue {
display: block;
min-width: 0;
@@ -2726,7 +2756,7 @@ body {
cursor: not-allowed;
}
-.wolai-page-ai-topbar {
+.wolai-page-ai-settings-grid {
display: grid;
grid-template-columns: minmax(0, 1fr) 132px;
gap: 8px;
@@ -2769,13 +2799,7 @@ body {
min-height: 0;
flex: 1 1 auto;
flex-direction: column;
- gap: 16px;
-}
-
-.wolai-page-ai-tabs {
- display: grid;
- grid-template-columns: repeat(4, minmax(0, 1fr));
- gap: 6px;
+ gap: 10px;
}
.wolai-page-ai-panel-section {
@@ -2783,17 +2807,87 @@ body {
min-height: 0;
flex: 1 1 auto;
flex-direction: column;
- gap: 12px;
+ gap: 10px;
}
.wolai-page-ai-panel-section[hidden] {
display: none !important;
}
+.wolai-page-ai-drawer:not([data-page-ai-page="chat"]) .wolai-page-ai-footer {
+ display: none;
+}
+
+.wolai-page-ai-chat-meta {
+ display: flex;
+ min-height: 24px;
+ align-items: center;
+ gap: 8px;
+ overflow: hidden;
+ color: #8B8782;
+ font-size: 11px;
+ line-height: 16px;
+}
+
+.wolai-page-ai-session-button {
+ min-width: 0;
+ max-width: 190px;
+ overflow: hidden;
+ padding: 0;
+ border: 0;
+ background: transparent;
+ color: #5A5A5A;
+ font: inherit;
+ text-align: left;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ cursor: pointer;
+}
+
+.wolai-page-ai-session-button:hover {
+ color: #1B1C1C;
+}
+
+.wolai-page-ai-settings-head {
+ display: grid;
+ grid-template-columns: auto minmax(0, 1fr);
+ gap: 8px;
+ align-items: center;
+}
+
+.wolai-page-ai-back {
+ height: 30px;
+ padding: 0 8px;
+ border: 0;
+ border-radius: 6px;
+ background: transparent;
+ color: #5A5A5A;
+ font-size: 12px;
+ cursor: pointer;
+}
+
+.wolai-page-ai-back:hover {
+ background: #F3F3F2;
+ color: #1B1C1C;
+}
+
+.wolai-page-ai-settings-tabs {
+ display: grid;
+ grid-template-columns: repeat(3, minmax(0, 1fr));
+ gap: 4px;
+ padding: 2px;
+ border-radius: 8px;
+ background: #F3F3F2;
+}
+
.wolai-page-ai-suggestions {
display: flex;
flex-direction: column;
- gap: 10px;
+ gap: 8px;
+}
+
+.wolai-page-ai-suggestions[hidden] {
+ display: none !important;
}
.wolai-page-ai-suggestions-header,
@@ -2886,10 +2980,10 @@ body {
}
.wolai-page-ai-suggestion {
- min-height: 32px;
- padding: 8px 10px;
+ min-height: 30px;
+ padding: 6px 9px;
border: 1px solid rgba(27, 28, 28, 0.08);
- border-radius: 10px;
+ border-radius: 8px;
background: #FFF;
color: #1B1C1C;
font-size: 12px;
@@ -3057,7 +3151,18 @@ body {
.wolai-page-ai-footer {
display: flex;
flex-direction: column;
- gap: 10px;
+ gap: 8px;
+}
+
+.wolai-page-ai-tab {
+ min-height: 28px;
+ padding: 0 8px;
+ border: 0;
+ border-radius: 6px;
+ background: transparent;
+ color: #5A5A5A;
+ font-size: 12px;
+ cursor: pointer;
}
.wolai-page-ai-tab.is-active {
@@ -3070,33 +3175,90 @@ body {
color: #FFF;
}
-.wolai-page-ai-input-row {
+.wolai-page-ai-composer {
display: flex;
- gap: 8px;
- align-items: flex-end;
+ flex-direction: column;
+ overflow: hidden;
+ border: 1px solid rgba(27, 28, 28, 0.12);
+ border-radius: 10px;
+ background: #FFF;
+}
+
+.wolai-page-ai-composer:focus-within {
+ border-color: rgba(27, 28, 28, 0.32);
+}
+
+.wolai-page-ai-composer-bar {
+ display: flex;
+ min-height: 36px;
+ align-items: center;
+ gap: 6px;
+ padding: 0 6px 6px;
+}
+
+.wolai-page-ai-composer-spacer {
+ flex: 1 1 auto;
+}
+
+.wolai-page-ai-tool-button {
+ width: 28px;
+ height: 28px;
+ border: 1px solid rgba(27, 28, 28, 0.1);
+ border-radius: 6px;
+ background: #FFF;
+ color: #5A5A5A;
+ font-size: 14px;
+ cursor: pointer;
+}
+
+.wolai-page-ai-tool-button:hover {
+ border-color: rgba(27, 28, 28, 0.2);
+ color: #1B1C1C;
}
.wolai-page-ai-input {
- flex: 1 1 auto;
- min-height: 88px;
- padding: 10px 12px;
- border: 1px solid rgba(27, 28, 28, 0.1);
- border-radius: 12px;
- background: #FFF;
+ width: 100%;
+ min-height: 76px;
+ padding: 10px 10px 4px;
+ border: 0;
+ background: transparent;
color: #1B1C1C;
font-size: 13px;
line-height: 20px;
resize: none;
}
-.wolai-page-ai-send {
- width: 36px;
- height: 36px;
+.wolai-page-ai-input:focus {
+ outline: none;
+}
+
+.wolai-page-ai-stop {
+ min-width: 42px;
+ height: 28px;
+ padding: 0 10px;
border: 0;
- border-radius: 10px;
+ border-radius: 6px;
+ background: #F3F3F2;
+ color: #5A5A5A;
+ font-size: 12px;
+ cursor: pointer;
+}
+
+.wolai-page-ai-stop:disabled {
+ color: #B5B1AA;
+ cursor: not-allowed;
+}
+
+.wolai-page-ai-send {
+ min-width: 52px;
+ height: 28px;
+ padding: 0 12px;
+ border: 0;
+ border-radius: 6px;
background: #1B1C1C;
color: #FFF;
- font-size: 16px;
+ font-size: 12px;
+ font-weight: 600;
cursor: pointer;
}
@@ -3119,11 +3281,8 @@ body {
width: min(100vw - 24px, 420px);
}
- .wolai-page-ai-statusbar {
- grid-template-columns: repeat(2, minmax(0, 1fr));
- }
-
- .wolai-page-ai-topbar {
+ .wolai-page-ai-settings-grid,
+ .wolai-page-ai-settings-head {
grid-template-columns: minmax(0, 1fr);
}
diff --git a/scripts/task-hermes-page-ai-agent-skill-smoke.js b/scripts/task-hermes-page-ai-agent-skill-smoke.js
index 49700e14..462ed887 100644
--- a/scripts/task-hermes-page-ai-agent-skill-smoke.js
+++ b/scripts/task-hermes-page-ai-agent-skill-smoke.js
@@ -166,19 +166,19 @@ async function main() {
);
await page.getByTestId("wolai-floating-ai").click({ timeout: UI_TIMEOUT_MS });
+ await page.locator('.wolai-page-ai-icon[data-page-ai-tab="agent"]').click({ timeout: UI_TIMEOUT_MS });
await page.locator("[data-page-ai-profile-select]").selectOption("chemist", { timeout: UI_TIMEOUT_MS });
await page.waitForFunction(() => document.documentElement.getAttribute("data-mnote-page-ai-profile") === "chemist", null, {
timeout: UI_TIMEOUT_MS,
});
- await page.locator('[data-page-ai-tab="agent"]').click({ timeout: UI_TIMEOUT_MS });
await page.locator('[data-page-ai-memory-editor="soul"]').fill(`SOUL-${suffix}`, { timeout: UI_TIMEOUT_MS });
await page.locator('[data-page-ai-memory-save="soul"]').click({ timeout: UI_TIMEOUT_MS });
await page.waitForFunction(() => document.documentElement.getAttribute("data-mnote-page-ai-memory-saved") === "soul", null, {
timeout: UI_TIMEOUT_MS,
});
- await page.locator('[data-page-ai-tab="skills"]').click({ timeout: UI_TIMEOUT_MS });
+ await page.locator('.wolai-page-ai-panel-section:not([hidden]) [data-page-ai-tab="skills"]').click({ timeout: UI_TIMEOUT_MS });
await page.locator("[data-page-ai-skill-search]").fill("writing", { timeout: UI_TIMEOUT_MS });
await page.locator('[data-page-ai-skill-toggle="ai-writing-detection"]').click({ timeout: UI_TIMEOUT_MS });
await page.waitForFunction(
@@ -187,7 +187,7 @@ async function main() {
{ timeout: UI_TIMEOUT_MS },
);
- await page.locator('[data-page-ai-tab="chat"]').click({ timeout: UI_TIMEOUT_MS });
+ await page.locator('.wolai-page-ai-panel-section:not([hidden]) [data-page-ai-tab="chat"]').click({ timeout: UI_TIMEOUT_MS });
await page.locator("[data-page-ai-input]").fill(`请使用 chemist agent 总结 ${title}`, { timeout: UI_TIMEOUT_MS });
await page.locator('[data-page-ai-action="send"]').click({ timeout: UI_TIMEOUT_MS });
await page.waitForFunction(
diff --git a/scripts/task-hermes-page-ai-runtime-controls-smoke.js b/scripts/task-hermes-page-ai-runtime-controls-smoke.js
index 6ea86b6d..623017a9 100644
--- a/scripts/task-hermes-page-ai-runtime-controls-smoke.js
+++ b/scripts/task-hermes-page-ai-runtime-controls-smoke.js
@@ -119,6 +119,8 @@ async function main() {
);
await page.getByTestId("wolai-floating-ai").click({ timeout: UI_TIMEOUT_MS });
+ await page.locator('.wolai-page-ai-icon[data-page-ai-tab="agent"]').click({ timeout: UI_TIMEOUT_MS });
+ await page.locator('.wolai-page-ai-panel-section:not([hidden]) [data-page-ai-tab="runtime"]').click({ timeout: UI_TIMEOUT_MS });
await page.waitForFunction(
(expected) => window.__mnoteHermesSettingsUrl === expected,
EXPECTED_SETTINGS_URL,
@@ -132,7 +134,9 @@ async function main() {
const settingsDisabled = await page.locator('[data-page-ai-action="open-hermes-settings"]').isDisabled();
assert.equal(settingsDisabled, false, "配置 Hermes upstream 后设置入口不应禁用");
+ await page.locator('.wolai-page-ai-panel-section:not([hidden]) [data-page-ai-tab="agent"]').click({ timeout: UI_TIMEOUT_MS });
await page.locator("[data-page-ai-context-scope]").selectOption("options", { timeout: UI_TIMEOUT_MS });
+ await page.locator('.wolai-page-ai-panel-section:not([hidden]) [data-page-ai-tab="chat"]').click({ timeout: UI_TIMEOUT_MS });
await page.locator("[data-page-ai-input]").fill(`请只读取页面设置 ${title}`, { timeout: UI_TIMEOUT_MS });
await page.locator('[data-page-ai-action="send"]').click({ timeout: UI_TIMEOUT_MS });
await page.waitForFunction(