feat(page-ai): add resumable run journal descriptors
This commit is contained in:
@@ -6,6 +6,7 @@ export function createSidebarPageAiRenderRuntime(context) {
|
||||
documentRef,
|
||||
escapeHtml,
|
||||
localMarkdownRelativePathFromPageAiDocumentId,
|
||||
pageAiAgentDescriptor,
|
||||
pageAiAgentRecord,
|
||||
pageAiAllSkillEntries,
|
||||
pageAiBuildAllowedRoots,
|
||||
@@ -18,6 +19,8 @@ export function createSidebarPageAiRenderRuntime(context) {
|
||||
pageAiCurrentSkillSource,
|
||||
pageAiCurrentSkillSourceLabel,
|
||||
pageAiDefaultChatOnlyProfileSpec,
|
||||
pageAiDescriptorFieldOptions,
|
||||
pageAiDescriptorFieldValue,
|
||||
pageAiEditorTargetCandidates,
|
||||
pageAiEnsureContextRefState,
|
||||
pageAiFilteredHistoryRows,
|
||||
@@ -125,7 +128,9 @@ export function createSidebarPageAiRenderRuntime(context) {
|
||||
|
||||
function pageAiCurrentAgentSelectionLabel() {
|
||||
var agentId = pageAiCurrentAgentId();
|
||||
if (agentId === 'reasonix') return 'Reasonix';
|
||||
var descriptor = pageAiAgentDescriptor(agentId);
|
||||
var descriptorLabel = String(descriptor && (descriptor.displayName || descriptor.label) || '').trim();
|
||||
if (agentId === 'reasonix') return descriptorLabel || 'Reasonix';
|
||||
var profile = pageAiCurrentProfileRecord();
|
||||
var chatOnlySpec = pageAiChatOnlyProfileSpec(profile || pageAiCurrentProfile());
|
||||
if (agentId === 'chat_only') {
|
||||
@@ -134,8 +139,8 @@ export function createSidebarPageAiRenderRuntime(context) {
|
||||
if (chatOnlySpec) {
|
||||
return 'ChatOnly / ' + chatOnlySpec.label;
|
||||
}
|
||||
if (agentId === 'hermes') return 'Hermes / ' + pageAiProfileDisplayLabel(profile, pageAiCurrentProfile());
|
||||
return pageAiAgentRecord(agentId).label;
|
||||
if (agentId === 'hermes') return (descriptorLabel || 'Hermes') + ' / ' + pageAiProfileDisplayLabel(profile, pageAiCurrentProfile());
|
||||
return descriptorLabel || pageAiAgentRecord(agentId).label;
|
||||
}
|
||||
|
||||
function pageAiRenderAgentProfileOption(agentId, profile, label, detail) {
|
||||
@@ -148,6 +153,59 @@ export function createSidebarPageAiRenderRuntime(context) {
|
||||
'</button>';
|
||||
}
|
||||
|
||||
function pageAiAgentDescriptorDetail(descriptor) {
|
||||
if (!descriptor) return '';
|
||||
var capabilities = pageAiNormalizeArray(descriptor.capabilities);
|
||||
var toolCount = Number(descriptor.toolCount || pageAiNormalizeArray(descriptor.tools).length || 0);
|
||||
var parts = [];
|
||||
parts.push(descriptor.canWriteFiles === false ? '只读/聊天' : '可写授权文件');
|
||||
if (capabilities.length) parts.push('capability ' + capabilities.length);
|
||||
if (toolCount) parts.push('tool ' + toolCount);
|
||||
return parts.join(' · ');
|
||||
}
|
||||
|
||||
function pageAiRenderDescriptorField(field) {
|
||||
var key = String(field && field.key || '').trim();
|
||||
if (!key || field.secret === true) return '';
|
||||
var label = String(field.label || key).trim();
|
||||
var kind = String(field.kind || 'string').trim();
|
||||
var value = pageAiDescriptorFieldValue(field);
|
||||
var options = pageAiDescriptorFieldOptions(field);
|
||||
var control = '';
|
||||
if (kind === 'select' || options.length) {
|
||||
control = '<select data-page-ai-descriptor-field="' + escapeHtml(key) + '" data-page-ai-descriptor-kind="select">' +
|
||||
options.map(function(option) {
|
||||
return '<option value="' + escapeHtml(option.value) + '"' + (String(value) === String(option.value) ? ' selected' : '') + '>' + escapeHtml(option.label) + '</option>';
|
||||
}).join('') +
|
||||
'</select>';
|
||||
} else if (kind === 'boolean' || kind === 'toggle') {
|
||||
control = '<input type="checkbox" data-page-ai-descriptor-field="' + escapeHtml(key) + '" data-page-ai-descriptor-kind="boolean"' + (value === true ? ' checked' : '') + ' />';
|
||||
} else {
|
||||
control = '<input type="text" value="' + escapeHtml(value == null ? '' : String(value)) + '" data-page-ai-descriptor-field="' + escapeHtml(key) + '" data-page-ai-descriptor-kind="' + escapeHtml(kind || 'string') + '" />';
|
||||
}
|
||||
return '' +
|
||||
'<label class="wolai-page-ai-profile-select" data-page-ai-descriptor-field-row="' + escapeHtml(key) + '">' +
|
||||
'<span>' + escapeHtml(label) + '</span>' +
|
||||
control +
|
||||
'</label>';
|
||||
}
|
||||
|
||||
function pageAiRenderAgentDescriptorCard(agentId, fallbackTitle) {
|
||||
var descriptor = pageAiAgentDescriptor(agentId) || pageAiAgentRecord(agentId);
|
||||
var title = String(descriptor && (descriptor.displayName || descriptor.label) || fallbackTitle || agentId).trim();
|
||||
var fields = pageAiNormalizeArray(descriptor && descriptor.fields).map(pageAiRenderDescriptorField).filter(Boolean).join('');
|
||||
var disabled = pageAiNormalizeArray(descriptor && descriptor.disabledCapabilities);
|
||||
var disabledText = disabled.length ? '<div class="wolai-page-ai-tool-meta">disabled: ' + escapeHtml(disabled.join(', ')) + '</div>' : '';
|
||||
return '' +
|
||||
'<section class="wolai-page-ai-memory-card" data-page-ai-agent-descriptor-card="' + escapeHtml(agentId) + '">' +
|
||||
'<div class="wolai-page-ai-memory-head">' +
|
||||
'<div><div class="wolai-page-ai-memory-title">' + escapeHtml(title) + '</div><div class="wolai-page-ai-memory-scope">' + escapeHtml(pageAiAgentDescriptorDetail(descriptor) || 'descriptor fallback') + '</div></div>' +
|
||||
'</div>' +
|
||||
disabledText +
|
||||
(fields ? '<div class="wolai-page-ai-settings-grid">' + fields + '</div>' : '<div class="wolai-page-ai-tool-meta">当前 agent 没有可配置字段。</div>') +
|
||||
'</section>';
|
||||
}
|
||||
|
||||
function pageAiCurrentModelLabel() {
|
||||
var profile = pageAiCurrentProfileRecord();
|
||||
var toolModel = pageAiMnoteToolModel();
|
||||
@@ -277,6 +335,9 @@ export function createSidebarPageAiRenderRuntime(context) {
|
||||
return pageAiRenderAgentProfileOption('hermes', profile, pageAiProfileDisplayLabel(profile, profileId), scope);
|
||||
}).join('');
|
||||
var reasonixActive = activeAgentId === 'reasonix';
|
||||
var reasonixDescriptor = pageAiAgentDescriptor('reasonix');
|
||||
var reasonixLabel = String(reasonixDescriptor && (reasonixDescriptor.displayName || reasonixDescriptor.label) || 'Reasonix').trim() || 'Reasonix';
|
||||
var reasonixDetail = pageAiAgentDescriptorDetail(reasonixDescriptor) || '可读取并在授权目录内写文件';
|
||||
agentPopover.innerHTML = '' +
|
||||
'<div class="wolai-page-ai-context-popover-head">' +
|
||||
'<strong>选择 Agent</strong>' +
|
||||
@@ -294,8 +355,8 @@ export function createSidebarPageAiRenderRuntime(context) {
|
||||
'<div class="wolai-page-ai-agent-popover-title">Reasonix</div>' +
|
||||
'<div class="wolai-page-ai-agent-option-list">' +
|
||||
'<button type="button" class="wolai-page-ai-agent-option' + (reasonixActive ? ' is-active' : '') + '" data-page-ai-agent-id="reasonix" aria-pressed="' + (reasonixActive ? 'true' : 'false') + '">' +
|
||||
'<span class="wolai-page-ai-agent-option-label">Reasonix</span>' +
|
||||
'<span class="wolai-page-ai-agent-option-detail">可读取并在授权目录内写文件</span>' +
|
||||
'<span class="wolai-page-ai-agent-option-label">' + escapeHtml(reasonixLabel) + '</span>' +
|
||||
'<span class="wolai-page-ai-agent-option-detail">' + escapeHtml(reasonixDetail) + '</span>' +
|
||||
'</button>' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
@@ -414,9 +475,11 @@ export function createSidebarPageAiRenderRuntime(context) {
|
||||
var agentPanel = drawer.querySelector('[data-page-ai-agent-panel]');
|
||||
if (agentPanel instanceof HTMLElement) {
|
||||
agentPanel.innerHTML = '' +
|
||||
(pageUiState.pageAiAgentDescriptorError ? '<div class="wolai-page-ai-inline-error">' + escapeHtml(pageUiState.pageAiAgentDescriptorError) + '</div>' : '') +
|
||||
'<section class="wolai-page-ai-memory-card">' +
|
||||
'<div class="wolai-page-ai-memory-head"><div class="wolai-page-ai-memory-title">授权区域</div><div class="wolai-page-ai-memory-scope">' + escapeHtml(pageAiBuildAllowedRoots().length ? 'SQLite directory_grants' : '需要授权') + '</div></div>' +
|
||||
'</section>' +
|
||||
pageAiRenderAgentDescriptorCard(activeAgentId, pageAiCurrentAgentSelectionLabel()) +
|
||||
'<section class="wolai-page-ai-memory-card">' +
|
||||
'<div class="wolai-page-ai-memory-head"><div class="wolai-page-ai-memory-title">默认上下文</div><div class="wolai-page-ai-memory-scope">ContextRefs</div></div>' +
|
||||
'</section>' +
|
||||
@@ -512,7 +575,7 @@ export function createSidebarPageAiRenderRuntime(context) {
|
||||
}
|
||||
var hermesMemoryPanel = drawer.querySelector('[data-page-ai-hermes-panel]');
|
||||
if (hermesMemoryPanel instanceof HTMLElement) {
|
||||
hermesMemoryPanel.innerHTML = ['soul', 'user', 'memory'].map(function(section) {
|
||||
hermesMemoryPanel.innerHTML = pageAiRenderAgentDescriptorCard('hermes', 'Hermes') + ['soul', 'user', 'memory'].map(function(section) {
|
||||
var label = pageAiMemoryFileLabel(section);
|
||||
var value = pageUiState.pageAiProfileMemoryDrafts[section] || '';
|
||||
return '' +
|
||||
@@ -713,6 +776,7 @@ export function createSidebarPageAiRenderRuntime(context) {
|
||||
var reasonixPanel = drawer.querySelector('[data-page-ai-reasonix-panel]');
|
||||
if (reasonixPanel instanceof HTMLElement) {
|
||||
reasonixPanel.innerHTML = '' +
|
||||
pageAiRenderAgentDescriptorCard('reasonix', 'Reasonix') +
|
||||
'<section class="wolai-page-ai-memory-card">' +
|
||||
'<div class="wolai-page-ai-memory-head">' +
|
||||
'<div><div class="wolai-page-ai-memory-title">Reasonix 专属设置</div><div class="wolai-page-ai-memory-scope">ACP runtime / memory</div></div>' +
|
||||
@@ -723,7 +787,8 @@ export function createSidebarPageAiRenderRuntime(context) {
|
||||
}
|
||||
var chatOnlyPanel = drawer.querySelector('[data-page-ai-chat-only-panel]');
|
||||
if (chatOnlyPanel instanceof HTMLElement) {
|
||||
chatOnlyPanel.innerHTML = '<section class="wolai-page-ai-memory-card"><div class="wolai-page-ai-memory-head"><div class="wolai-page-ai-memory-title">Chat-only</div><div class="wolai-page-ai-memory-scope">默认不申请文件写权限</div></div></section>';
|
||||
chatOnlyPanel.innerHTML = pageAiRenderAgentDescriptorCard('chat_only', 'Chat-only') +
|
||||
'<section class="wolai-page-ai-memory-card"><div class="wolai-page-ai-memory-head"><div class="wolai-page-ai-memory-title">Chat-only</div><div class="wolai-page-ai-memory-scope">默认不申请文件写权限</div></div></section>';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user