fix: surface pi rust diagnostics in ui
This commit is contained in:
@@ -39,6 +39,7 @@
|
||||
COMPACT: '/api/page-ai/pi/compact',
|
||||
CONFIGURE: '/api/page-ai/pi/configure',
|
||||
QUEUE_CONFIG: '/api/page-ai/pi/queue-config',
|
||||
DIAGNOSTICS: '/api/page-ai/pi/diagnostics',
|
||||
EFFECTIVE: '/api/ai-settings/effective',
|
||||
};
|
||||
|
||||
@@ -81,6 +82,7 @@
|
||||
runtimeInstallHint: '',
|
||||
runtimeError: '',
|
||||
runtimePid: null,
|
||||
advancedRuntime: {},
|
||||
warmupRunning: false,
|
||||
warmupSessionId: null,
|
||||
managedBuiltinTools: [],
|
||||
@@ -584,6 +586,7 @@
|
||||
'.wolai-page-ai-pi-lab-diagnostics{display:none;border-top:1px solid #e6e2da;background:#fff;flex:0 0 auto}' +
|
||||
'.wolai-page-ai-pi-lab-drawer[data-config-open="true"] .wolai-page-ai-pi-lab-diagnostics{display:block}' +
|
||||
'.wolai-page-ai-pi-lab-diagnostics>summary{cursor:pointer;padding:8px 12px;font-size:11px;color:#6f6a60}' +
|
||||
'.wolai-page-ai-pi-lab-diagnostic-actions{display:flex;flex-wrap:wrap;gap:6px;align-items:center;padding:0 12px 8px}.wolai-page-ai-pi-lab-diagnostic-actions button{height:26px;border:1px solid #ddd8cf;border-radius:7px;background:#fff;color:#42403a;padding:0 8px;font-size:11px;cursor:pointer}.wolai-page-ai-pi-lab-diagnostic-actions button:hover{background:#f8f7f3}.wolai-page-ai-pi-lab-diagnostic-actions input{height:26px;min-width:120px;border:1px solid #ddd8cf;border-radius:7px;background:#fff;color:#42403a;padding:0 8px;font-size:11px;outline:none}.wolai-page-ai-pi-lab-diagnostic-output[hidden]{display:none!important}.wolai-page-ai-pi-lab-diagnostic-output{border-top:1px solid #eee9e0;background:#faf9f6}' +
|
||||
'.wolai-page-ai-pi-lab-diagnostics pre{margin:0;padding:0 12px 10px;white-space:pre-wrap;word-break:break-word;font:11px/1.45 ui-monospace,SFMono-Regular,Menlo,monospace;color:#5d594f}' +
|
||||
'@media (max-width: 760px){.wolai-page-ai-pi-lab-drawer{left:10px;right:10px;top:58px;bottom:10px;width:auto}.wolai-page-ai-pi-lab-history-panel{width:min(320px,calc(100vw - 34px))}.wolai-page-ai-pi-lab-rail{left:14px;right:14px;top:auto;bottom:132px;width:auto;max-height:min(360px,calc(100% - 164px))}.wolai-page-ai-pi-lab-config{grid-template-columns:1fr}}' +
|
||||
'@media (max-width: 520px){.wolai-page-ai-pi-lab-topbar{height:54px;padding:0 14px}.wolai-page-ai-pi-lab-title strong{font-size:21px}.wolai-page-ai-pi-lab-commandbar{height:50px;margin:0 14px 12px;gap:6px;overflow:hidden}.wolai-page-ai-pi-lab-history-panel{top:116px;left:12px;right:12px;max-height:min(300px,calc(100% - 300px))}.wolai-page-ai-pi-lab-history-row{grid-template-columns:1fr}.wolai-page-ai-pi-lab-history-actions{justify-content:flex-start}.wolai-page-ai-pi-lab-input{min-height:88px;padding:16px 58px 10px 18px;font-size:16px}.wolai-page-ai-pi-lab-modebar{min-height:48px;flex-wrap:nowrap;gap:6px;padding:6px 10px}.wolai-page-ai-pi-lab-model-control-wrap{flex:1 1 130px;min-width:92px;max-width:none}.wolai-page-ai-pi-lab-toast-stack{left:14px;right:14px;bottom:154px}.wolai-page-ai-pi-lab-toast{width:100%}}';
|
||||
@@ -2018,7 +2021,17 @@
|
||||
'</div>' +
|
||||
'<details class="wolai-page-ai-pi-lab-diagnostics" data-page-ai-pi-lab-diagnostics>' +
|
||||
'<summary>诊断</summary>' +
|
||||
'<div class="wolai-page-ai-pi-lab-diagnostic-actions">' +
|
||||
'<button type="button" data-page-ai-pi-lab-diagnostic-command="doctor">doctor</button>' +
|
||||
'<button type="button" data-page-ai-pi-lab-diagnostic-command="context-preview">context-preview</button>' +
|
||||
'<button type="button" data-page-ai-pi-lab-diagnostic-command="list">list</button>' +
|
||||
'<button type="button" data-page-ai-pi-lab-diagnostic-command="update-index">update-index</button>' +
|
||||
'<input type="search" data-page-ai-pi-lab-diagnostic-query placeholder="search/info keyword">' +
|
||||
'<button type="button" data-page-ai-pi-lab-diagnostic-command="search">search</button>' +
|
||||
'<button type="button" data-page-ai-pi-lab-diagnostic-command="info">info</button>' +
|
||||
'</div>' +
|
||||
'<pre data-page-ai-pi-lab-diag-text></pre>' +
|
||||
'<pre class="wolai-page-ai-pi-lab-diagnostic-output" data-page-ai-pi-lab-diagnostic-output hidden></pre>' +
|
||||
'</details>' +
|
||||
'</div>';
|
||||
}
|
||||
@@ -2714,6 +2727,7 @@
|
||||
lines.push('providerSession=' + (piLabState.providerSessionId || 'none'));
|
||||
lines.push('model=' + currentModelLabel());
|
||||
lines.push('runtime=' + currentRuntimeLabel());
|
||||
lines.push('advancedRuntime=' + advancedRuntimeSummary(piLabState.advancedRuntime));
|
||||
lines.push('managedBuiltinTools=' + ((Array.isArray(piLabState.managedBuiltinTools) && piLabState.managedBuiltinTools.length) ? piLabState.managedBuiltinTools.join('/') : 'pending'));
|
||||
if (Array.isArray(piLabState.piExtensionSources) && piLabState.piExtensionSources.length) {
|
||||
lines.push('piExtensions=' + piLabState.piExtensionSources.join(','));
|
||||
@@ -2723,6 +2737,29 @@
|
||||
pre.textContent = lines.join('\n');
|
||||
}
|
||||
|
||||
function advancedRuntimeSummary(config) {
|
||||
config = config || {};
|
||||
var pairs = [
|
||||
['extensionPolicy', config.extensionPolicy],
|
||||
['repairPolicy', config.repairPolicy],
|
||||
['sessionDurability', config.sessionDurability],
|
||||
['requestTimeoutSecs', config.requestTimeoutSecs],
|
||||
['maxToolIterations', config.maxToolIterations],
|
||||
['hideCwdInPrompt', config.hideCwdInPrompt === true ? 'true' : 'false'],
|
||||
].filter(function (item) { return item[1] !== undefined && item[1] !== null && item[1] !== ''; });
|
||||
return pairs.length ? pairs.map(function (item) { return item[0] + '=' + item[1]; }).join(',') : 'default';
|
||||
}
|
||||
|
||||
function setDiagnosticOutput(payload) {
|
||||
if (!piLabPanelEl) return;
|
||||
var output = piLabPanelEl.querySelector('[data-page-ai-pi-lab-diagnostic-output]');
|
||||
var details = piLabPanelEl.querySelector('[data-page-ai-pi-lab-diagnostics]');
|
||||
if (!output) return;
|
||||
if (details) details.open = true;
|
||||
output.hidden = false;
|
||||
output.textContent = typeof payload === 'string' ? payload : JSON.stringify(payload || {}, null, 2);
|
||||
}
|
||||
|
||||
function updatePiFloatingLayerPosition(layer) {
|
||||
if (!layer || !piLabPanelEl) return;
|
||||
var composer = piLabPanelEl.querySelector('.wolai-page-ai-pi-lab-composer');
|
||||
@@ -3479,6 +3516,55 @@
|
||||
});
|
||||
}
|
||||
|
||||
function runPiDiagnostic(command) {
|
||||
var input = piLabPanelEl && piLabPanelEl.querySelector('[data-page-ai-pi-lab-diagnostic-query]');
|
||||
var keyword = input ? String(input.value || '').trim() : '';
|
||||
var params = {};
|
||||
if (command === 'doctor') params.format = 'json';
|
||||
if (command === 'context-preview') {
|
||||
params.format = 'json';
|
||||
params.query = [keyword || 'MNote Pi Rust diagnostics'];
|
||||
}
|
||||
if (command === 'search') {
|
||||
if (!keyword) {
|
||||
showPiToast('请输入 search keyword', 'warning');
|
||||
return Promise.resolve();
|
||||
}
|
||||
params.query = keyword;
|
||||
params.limit = 10;
|
||||
}
|
||||
if (command === 'info') {
|
||||
if (!keyword) {
|
||||
showPiToast('请输入 info name/id', 'warning');
|
||||
return Promise.resolve();
|
||||
}
|
||||
params.name = keyword;
|
||||
}
|
||||
updateDiagnostics('Pi diagnostics: ' + command);
|
||||
setDiagnosticOutput('Running ' + command + '...');
|
||||
return fetch(API.DIAGNOSTICS, {
|
||||
method: 'POST',
|
||||
credentials: 'same-origin',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
command: command,
|
||||
params: params,
|
||||
rootUri: piLabState.session && piLabState.session.rootUri || undefined,
|
||||
workspaceId: piLabState.session && piLabState.session.workspaceId || undefined,
|
||||
}),
|
||||
}).then(function (response) {
|
||||
return responseJsonOrError(response, 'Diagnostics failed');
|
||||
}).then(function (payload) {
|
||||
setDiagnosticOutput(payload);
|
||||
updateDiagnostics('Pi diagnostics done: ' + command);
|
||||
return payload;
|
||||
}).catch(function (error) {
|
||||
setDiagnosticOutput({ ok: false, command: command, error: error.message || String(error), payload: error.payload || null });
|
||||
updateDiagnostics('Pi diagnostics failed: ' + (error.message || String(error)));
|
||||
showPiToast('诊断失败', 'error');
|
||||
});
|
||||
}
|
||||
|
||||
function checkStatus() {
|
||||
return Promise.all([
|
||||
fetch(API.STATUS, { credentials: 'same-origin', cache: 'no-store' }).then(function (r) { return r.json(); }),
|
||||
@@ -3511,6 +3597,7 @@
|
||||
piLabState.runtimeInstallHint = data.runtimeInstallHint || data.runtime_install_hint || '';
|
||||
piLabState.runtimeError = data.runtimeError || (data.session && data.session.runtimeError) || '';
|
||||
piLabState.runtimePid = data.pid || (data.session && data.session.runtimePid) || piLabState.runtimePid || null;
|
||||
piLabState.advancedRuntime = data.advancedRuntime || (data.session && data.session.advancedRuntime) || (data.session && data.session.runtimePolicySnapshot && data.session.runtimePolicySnapshot.piRuntime) || piLabState.advancedRuntime || {};
|
||||
piLabState.warmupRunning = data.warmupRunning === true;
|
||||
piLabState.warmupSessionId = data.warmupSessionId || null;
|
||||
piLabState.managedBuiltinTools = data.managedPiBuiltinTools || data.managedBuiltinTools || piLabState.managedBuiltinTools || [];
|
||||
@@ -3589,6 +3676,7 @@
|
||||
piLabState.runtimeInstallHint = data.runtimeInstallHint || data.runtime_install_hint || '';
|
||||
piLabState.runtimeError = session.runtimeError || data.runtimeError || '';
|
||||
piLabState.runtimePid = session.runtimePid || data.pid || piLabState.runtimePid || null;
|
||||
piLabState.advancedRuntime = data.advancedRuntime || session.advancedRuntime || (session.runtimePolicySnapshot && session.runtimePolicySnapshot.piRuntime) || piLabState.advancedRuntime || {};
|
||||
piLabState.managedBuiltinTools = data.managedPiBuiltinTools || data.managedBuiltinTools || piLabState.managedBuiltinTools || [];
|
||||
piLabState.piExtensionSources = data.piExtensionSources || piLabState.piExtensionSources || [];
|
||||
piLabState.piExtensionToolNames = data.piExtensionToolNames || piLabState.piExtensionToolNames || [];
|
||||
@@ -3733,6 +3821,7 @@
|
||||
piLabState.runtimePid = payload.pid || piLabState.runtimePid;
|
||||
piLabState.runtimeMode = payload.runtimeMode || piLabState.runtimeMode;
|
||||
piLabState.managedBuiltinTools = payload.managedBuiltinTools || payload.managedPiBuiltinTools || piLabState.managedBuiltinTools;
|
||||
piLabState.advancedRuntime = payload.advancedRuntime || piLabState.advancedRuntime || {};
|
||||
piLabState.piExtensionSources = payload.piExtensionSources || piLabState.piExtensionSources || [];
|
||||
piLabState.piExtensionToolNames = payload.piExtensionToolNames || piLabState.piExtensionToolNames || [];
|
||||
setState(STATE_STARTED);
|
||||
@@ -4723,11 +4812,16 @@
|
||||
});
|
||||
return;
|
||||
}
|
||||
var openSessionJsonl = event.target && event.target.closest ? event.target.closest('[data-page-ai-pi-lab-open-session-jsonl]') : null;
|
||||
if (openSessionJsonl) {
|
||||
openCurrentSessionJsonl();
|
||||
return;
|
||||
}
|
||||
var openSessionJsonl = event.target && event.target.closest ? event.target.closest('[data-page-ai-pi-lab-open-session-jsonl]') : null;
|
||||
if (openSessionJsonl) {
|
||||
openCurrentSessionJsonl();
|
||||
return;
|
||||
}
|
||||
var diagnosticCommand = event.target && event.target.closest ? event.target.closest('[data-page-ai-pi-lab-diagnostic-command]') : null;
|
||||
if (diagnosticCommand) {
|
||||
runPiDiagnostic(diagnosticCommand.getAttribute('data-page-ai-pi-lab-diagnostic-command') || 'doctor');
|
||||
return;
|
||||
}
|
||||
var openArtifact = event.target && event.target.closest ? event.target.closest('[data-page-ai-pi-lab-artifact-open]') : null;
|
||||
if (openArtifact) {
|
||||
var artUrl = openArtifact.getAttribute('data-page-ai-pi-lab-artifact-open') || openArtifact.getAttribute('href') || '';
|
||||
|
||||
@@ -1040,6 +1040,12 @@ const AI_ADMIN_SCRIPT: &str = r#"
|
||||
root.addEventListener('click', function (event) {
|
||||
var closeTarget = event.target && event.target.closest ? event.target.closest('[data-action="close-user-drawer"], [data-ai-admin-drawer-backdrop]') : null;
|
||||
if (closeTarget && drawer) drawer.classList.remove('is-open');
|
||||
var piDiagnosticTarget = event.target && event.target.closest ? event.target.closest('[data-ai-admin-pi-diagnostic-command]') : null;
|
||||
if (piDiagnosticTarget) {
|
||||
event.preventDefault();
|
||||
runPiDiagnostic(piDiagnosticTarget.getAttribute('data-ai-admin-pi-diagnostic-command') || 'doctor');
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
function setText(node, value) {
|
||||
@@ -1081,6 +1087,66 @@ const AI_ADMIN_SCRIPT: &str = r#"
|
||||
return '<div class="mnote-ai-admin-kv"><span>' + escapeHtml(label) + '</span><strong>' + escapeHtml(value == null || value === '' ? '-' : value) + '</strong></div>';
|
||||
}
|
||||
|
||||
function advancedRuntimeSummary(config) {
|
||||
config = config || {};
|
||||
var pairs = [
|
||||
['extensionPolicy', config.extensionPolicy || config.extension_policy],
|
||||
['repairPolicy', config.repairPolicy || config.repair_policy],
|
||||
['sessionDurability', config.sessionDurability || config.session_durability],
|
||||
['requestTimeoutSecs', config.requestTimeoutSecs || config.request_timeout_secs],
|
||||
['maxToolIterations', config.maxToolIterations || config.max_tool_iterations],
|
||||
['hideCwdInPrompt', (config.hideCwdInPrompt === true || config.hide_cwd_in_prompt === true) ? 'true' : 'false'],
|
||||
].filter(function (item) { return item[1] !== undefined && item[1] !== null && item[1] !== ''; });
|
||||
return pairs.length ? pairs.map(function (item) { return item[0] + '=' + item[1]; }).join(', ') : 'default';
|
||||
}
|
||||
|
||||
function piDiagnosticParams(command) {
|
||||
var input = root.querySelector('[data-ai-admin-pi-diagnostic-query]');
|
||||
var keyword = input ? String(input.value || '').trim() : '';
|
||||
var params = {};
|
||||
if (command === 'doctor') params.format = 'json';
|
||||
if (command === 'context-preview') {
|
||||
params.format = 'json';
|
||||
params.query = [keyword || 'MNote Pi Rust diagnostics'];
|
||||
}
|
||||
if (command === 'search') {
|
||||
if (!keyword) throw new Error('请输入 search keyword');
|
||||
params.query = keyword;
|
||||
params.limit = 10;
|
||||
}
|
||||
if (command === 'info') {
|
||||
if (!keyword) throw new Error('请输入 info name/id');
|
||||
params.name = keyword;
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
function setPiDiagnosticOutput(payload) {
|
||||
var details = root.querySelector('[data-ai-admin-pi-diagnostics-card]');
|
||||
var output = root.querySelector('[data-ai-admin-pi-diagnostics-output]');
|
||||
if (details) details.open = true;
|
||||
if (!output) return;
|
||||
output.hidden = false;
|
||||
output.textContent = typeof payload === 'string' ? payload : JSON.stringify(payload || {}, null, 2);
|
||||
}
|
||||
|
||||
async function runPiDiagnostic(command) {
|
||||
try {
|
||||
var params = piDiagnosticParams(command);
|
||||
setPiDiagnosticOutput('Running ' + command + '...');
|
||||
var payload = await requestJson('/api/page-ai/pi/diagnostics', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
command: command,
|
||||
params: params,
|
||||
}),
|
||||
});
|
||||
setPiDiagnosticOutput(payload);
|
||||
} catch (err) {
|
||||
setPiDiagnosticOutput({ ok: false, command: command, error: err.message || '诊断失败' });
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeDirectoryGrants(payload) {
|
||||
var grants = payload && (payload.grants || (payload.policy && payload.policy.grants) || payload.allowedRoots || payload.allowed_roots || []);
|
||||
return Array.isArray(grants) ? grants.filter(Boolean) : [];
|
||||
@@ -1216,6 +1282,7 @@ const AI_ADMIN_SCRIPT: &str = r#"
|
||||
var piRuntimeBinary = piStatus ? (piStatus.runtimeBinary || piStatus.runtime_binary || '-') : '-';
|
||||
var piRuntimeAvailable = !piStatus || piStatus.runtimeAvailable !== false;
|
||||
var piRuntimeError = piStatus && (piStatus.runtimeError || piStatus.runtime_error || piStatus.runtimeInstallHint || piStatus.runtime_install_hint || '');
|
||||
var advancedRuntime = piStatus && (piStatus.advancedRuntime || piStatus.advanced_runtime) || {};
|
||||
var piRunning = piStatus && piStatus.running === true;
|
||||
var piExtensions = piStatus && Array.isArray(piStatus.piExtensionSources)
|
||||
? piStatus.piExtensionSources
|
||||
@@ -1242,9 +1309,24 @@ const AI_ADMIN_SCRIPT: &str = r#"
|
||||
renderKv('Runtime PID', piStatus && piStatus.pid ? String(piStatus.pid) : 'none') +
|
||||
renderKv('受控 Pi 原生工具', (piStatus && piStatus.managedPiBuiltinTools || ['read','write','edit','bash','grep','find','ls','hashline_edit']).join(', ')) +
|
||||
renderKv('Pi 扩展包', piExtensions.length ? piExtensions.join(', ') : '待 runtime 启动') +
|
||||
renderKv('Advanced runtime', advancedRuntimeSummary(advancedRuntime)) +
|
||||
renderKv('Receipt storage', piStatus && piStatus.receiptStorage ? piStatus.receiptStorage : 'control-plane / provider-neutral adapter') +
|
||||
renderKv('Session dir policy', piStatus && piStatus.managedPiSessionDirPolicy ? piStatus.managedPiSessionDirPolicy : '<workspace>/.mnote/ai/pi-sessions/<actor>/<session>') +
|
||||
'</div>' +
|
||||
'<details data-ai-admin-pi-diagnostics-card style="margin-top:12px;">' +
|
||||
'<summary style="font-size:12px;color:#8B8782;cursor:pointer;">Pi 官方诊断 / effective runtime</summary>' +
|
||||
'<div class="mnote-ai-admin-actions-bar" style="margin:10px 0;gap:6px;flex-wrap:wrap;">' +
|
||||
'<button type="button" class="mnote-ai-admin-btn" data-ai-admin-pi-diagnostic-command="doctor">doctor</button>' +
|
||||
'<button type="button" class="mnote-ai-admin-btn" data-ai-admin-pi-diagnostic-command="context-preview">context-preview</button>' +
|
||||
'<button type="button" class="mnote-ai-admin-btn" data-ai-admin-pi-diagnostic-command="list">list</button>' +
|
||||
'<button type="button" class="mnote-ai-admin-btn" data-ai-admin-pi-diagnostic-command="update-index">update-index</button>' +
|
||||
'<input type="search" data-ai-admin-pi-diagnostic-query placeholder="search/info keyword" style="height:30px;min-width:160px;border:1px solid #ddd8cf;border-radius:8px;padding:0 10px;">' +
|
||||
'<button type="button" class="mnote-ai-admin-btn" data-ai-admin-pi-diagnostic-command="search">search</button>' +
|
||||
'<button type="button" class="mnote-ai-admin-btn" data-ai-admin-pi-diagnostic-command="info">info</button>' +
|
||||
'</div>' +
|
||||
'<pre class="mnote-ai-admin-json" data-ai-admin-pi-diagnostics-output hidden></pre>' +
|
||||
'<pre class="mnote-ai-admin-json" data-ai-admin-pi-advanced-runtime-json>' + escapeHtml(JSON.stringify(advancedRuntime, null, 2)) + '</pre>' +
|
||||
'</details>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'<div class="mnote-ai-admin-admin-card">' +
|
||||
|
||||
Reference in New Issue
Block a user