Files
mnote/rust/crates/mnote-web/browser/sidebar-page-ai-profile-runtime.js
T
lix-2026 9f4b5c4d48 fix: stabilize local folder AI document workflow
- scope local-folder PageTree revision and document sidebar rendering to fileTreeScope

- preserve projected table/image attrs for local Markdown aggregate fallback

- avoid FileTree restore forced layouts on cold design open

- add API ChatOnly provider runtime and local OCR task handling regressions
2026-06-02 17:17:49 +08:00

221 lines
8.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
export function createSidebarPageAiProfileRuntime(context) {
const {
chatOnlyProfileRegistry,
documentRef,
pageAiAgentRecord,
pageAiCurrentAgentId,
pageAiNormalizeAgentId,
pageUiState,
} = context;
const PAGE_AI_CHAT_ONLY_PROFILE_REGISTRY = Array.isArray(chatOnlyProfileRegistry) ? chatOnlyProfileRegistry : [];
function pageAiProviderLabel(provider) {
if (provider === 'codex') return 'Codex';
if (provider === 'claudecode') return 'ClaudeCode';
return 'Hermes';
}
function pageAiNormalizeArray(value) {
return Array.isArray(value) ? value : [];
}
function pageAiDefaultAcpRuntimes() {
return [
{
name: 'reasonix',
title: 'ACP · Reasonix',
description: '通过 ACP 协议直连 ReasonixDeepSeek 缓存优先)',
model: 'deepseek-chat',
preset: 'auto'
},
{
name: 'hermes',
title: 'ACP · Hermes',
description: '通过 ACP 协议直连 Hermes agent runtime'
}
];
}
function pageAiNormalizeAcpRuntimes(runtimes) {
var byName = {};
pageAiDefaultAcpRuntimes().forEach(function(runtime) {
byName[runtime.name] = Object.assign({}, runtime);
});
pageAiNormalizeArray(runtimes).forEach(function(runtime) {
var name = String(runtime && runtime.name || '').trim();
if (name !== 'reasonix' && name !== 'hermes') return;
byName[name] = Object.assign({}, byName[name] || {}, runtime, { name: name });
});
return ['reasonix', 'hermes'].map(function(name) { return byName[name]; }).filter(Boolean);
}
function pageAiUnwrapUpstream(payload) {
if (payload && typeof payload === 'object' && payload.upstream) return payload.upstream;
return payload || null;
}
function pageAiProfileValue(profile) {
if (profile && typeof profile === 'object') {
return String(profile.profileId || profile.name || profile.profile || profile.id || '').trim();
}
return String(profile || '').trim();
}
function pageAiCurrentProfile() {
var active = String(pageUiState.pageAiActiveProfileName || '').trim();
if (active) return active;
var selected = pageUiState.pageAiProfiles.find(function(profile) {
return profile && profile.active;
});
return pageAiProfileValue(selected) || 'mnoteai';
}
function pageAiRunProfile() {
if (String(pageUiState.pageAiAcpRuntime || 'reasonix').trim() === 'reasonix') return 'reasonix';
if (pageAiCurrentAgentId() === 'chat_only') return pageAiNormalizeChatOnlyProfileId(pageAiCurrentProfile());
return pageAiCurrentProfile();
}
function pageAiMnoteToolModel() {
var doc = documentRef || document;
return String(doc.documentElement.getAttribute('data-mnote-page-ai-tool-model') || 'deepseek-v4-flash').trim() || 'deepseek-v4-flash';
}
function pageAiCurrentProfileRecord() {
var active = pageAiCurrentProfile();
return pageUiState.pageAiProfiles.find(function(profile) {
return pageAiProfileValue(profile) === active;
}) || null;
}
function pageAiChatOnlyProfileSpec(profile) {
var profileId = pageAiProfileValue(profile);
var baseProfile = String(profile && profile.baseProfile || '').trim();
var isolatedProfile = String(profile && profile.isolatedProfile || '').trim();
return PAGE_AI_CHAT_ONLY_PROFILE_REGISTRY.find(function(spec) {
return spec.profileId === profileId || spec.baseProfile === profileId || spec.baseProfile === baseProfile || isolatedProfile.indexOf(spec.baseProfile) >= 0;
}) || null;
}
function pageAiDefaultChatOnlyProfileSpec() {
return PAGE_AI_CHAT_ONLY_PROFILE_REGISTRY[0] || { profileId: 'shared_deepseek_chat', baseProfile: 'deepseek-chat', label: 'DeepSeek' };
}
function pageAiNormalizeChatOnlyProfileId(profileId) {
var profile = pageAiProfileRecordById(profileId) || { profileId: String(profileId || '').trim(), name: String(profileId || '').trim() };
var spec = pageAiChatOnlyProfileSpec(profile);
return (spec || pageAiDefaultChatOnlyProfileSpec()).profileId;
}
function pageAiProfileDisplayLabel(profile, fallback) {
var alias = String(profile && profile.alias || '').trim();
var displayName = String(profile && (profile.displayName || profile.label || '') || '').trim();
var name = pageAiProfileValue(profile);
return alias || displayName || fallback || name || 'default';
}
function pageAiProfileRecordById(profileId) {
var normalized = String(profileId || '').trim();
if (!normalized) return null;
return pageAiNormalizeArray(pageUiState.pageAiProfiles).find(function(profile) {
return pageAiProfileValue(profile) === normalized;
}) || null;
}
function pageAiSessionAgentFilterValue(session) {
var agentId = pageAiNormalizeAgentId(session && session.agentId);
if (agentId === 'reasonix') return 'reasonix';
var profileId = String(session && (session.profileId || session.profile) || '').trim();
if (agentId === 'chat_only') profileId = pageAiNormalizeChatOnlyProfileId(profileId);
return agentId + ':' + profileId;
}
function pageAiSessionAgentLabel(session) {
var agentId = pageAiNormalizeAgentId(session && session.agentId);
if (agentId === 'reasonix') return 'Reasonix';
var profileId = String(session && (session.profileId || session.profile) || '').trim();
var profile = pageAiProfileRecordById(profileId) || { profileId: profileId, name: profileId };
var chatOnlySpec = pageAiChatOnlyProfileSpec(profile);
if (agentId === 'chat_only') {
return 'ChatOnly / ' + (chatOnlySpec || pageAiDefaultChatOnlyProfileSpec()).label;
}
if (agentId === 'hermes') return 'Hermes / ' + pageAiProfileDisplayLabel(profile, profileId);
return pageAiAgentRecord(agentId).label;
}
function pageAiSessionPreviewText(session) {
var preview = Array.isArray(session && session.messages) && session.messages.length
? String(session.messages.slice(-1)[0].content || '')
: String(session && (session.snippet || session.preview || '暂无消息') || '暂无消息');
preview = preview.replace(/\s+/g, ' ').trim();
var limit = 96;
return preview.length > limit ? preview.slice(0, limit) + '…' : preview;
}
function pageAiSessionAgentFilterOptions(rows) {
var byValue = { all: '全部 agent' };
pageAiNormalizeArray(rows).forEach(function(session) {
var value = pageAiSessionAgentFilterValue(session);
byValue[value] = pageAiSessionAgentLabel(session);
});
return Object.keys(byValue).map(function(value) {
return { value: value, label: byValue[value] };
});
}
function pageAiFilteredHistoryRows(rows) {
var filterValue = String(pageUiState.pageAiSessionAgentFilter || 'all').trim() || 'all';
var normalized = pageAiNormalizeArray(rows);
if (filterValue === 'all') return normalized;
return normalized.filter(function(session) {
return pageAiSessionAgentFilterValue(session) === filterValue;
});
}
function pageAiTimestamp(value) {
if (typeof value === 'number' && Number.isFinite(value)) return value;
if (typeof value === 'string' && value.trim()) {
var parsed = Date.parse(value);
if (Number.isFinite(parsed)) return parsed;
}
return Date.now();
}
function pageAiUsageSummary(usage) {
if (!usage || typeof usage !== 'object') return '';
var used = usage.used ?? usage.contextUsed ?? usage.input_tokens ?? usage.inputTokens ?? usage.prompt_tokens ?? usage.promptTokens;
var size = usage.size ?? usage.contextSize ?? usage.total_tokens ?? usage.totalTokens;
var output = usage.output_tokens ?? usage.outputTokens ?? usage.completion_tokens ?? usage.completionTokens;
var parts = [];
if (Number.isFinite(Number(used))) parts.push('ctx ' + Number(used));
if (Number.isFinite(Number(size)) && Number(size) > 0) parts.push('/ ' + Number(size));
if (Number.isFinite(Number(output)) && Number(output) > 0) parts.push('out ' + Number(output));
return parts.join(' ') || '';
}
return {
pageAiProviderLabel,
pageAiNormalizeArray,
pageAiDefaultAcpRuntimes,
pageAiNormalizeAcpRuntimes,
pageAiUnwrapUpstream,
pageAiProfileValue,
pageAiCurrentProfile,
pageAiRunProfile,
pageAiMnoteToolModel,
pageAiCurrentProfileRecord,
pageAiChatOnlyProfileSpec,
pageAiDefaultChatOnlyProfileSpec,
pageAiNormalizeChatOnlyProfileId,
pageAiProfileDisplayLabel,
pageAiProfileRecordById,
pageAiSessionAgentFilterValue,
pageAiSessionAgentLabel,
pageAiSessionPreviewText,
pageAiSessionAgentFilterOptions,
pageAiFilteredHistoryRows,
pageAiTimestamp,
pageAiUsageSummary
};
}