chore: checkpoint turso and ai runtime work

This commit is contained in:
Agent Board
2026-07-03 23:20:16 +08:00
parent a75b3d11f9
commit 36d027a4a1
67 changed files with 4224 additions and 914 deletions
@@ -1469,7 +1469,7 @@ export const createResourceTabRuntime = (dependencies = {}) => {
const isKnowledgeRagSourceEntry = (entry) => {
if (!entry || String(entry.sourceKind || '').trim() !== 'local_folder') return false;
if (!String(entry.rootUri || '').trim() || !String(entry.path || '').trim()) return false;
return entry.kind === 'image' || entry.kind === 'pdf';
return ['image', 'pdf', 'markdown', 'text', 'code'].includes(entry.kind);
};
const knowledgeRagProvider = () => {
@@ -1487,11 +1487,11 @@ export const createResourceTabRuntime = (dependencies = {}) => {
const statusNode = entry.panel.querySelector('[data-mnote-knowledge-rag-status-text]');
if (statusNode instanceof HTMLElement) {
statusNode.textContent = message || (
normalizedStatus === 'done' ? '资料库已索引'
: normalizedStatus === 'running' ? '资料库索引中'
: normalizedStatus === 'failed' ? '资料库索引失败'
: normalizedStatus === 'stale' ? '资料库需更新'
: '资料库未索引'
normalizedStatus === 'done' ? '知识库已索引'
: normalizedStatus === 'running' ? '知识库索引中'
: normalizedStatus === 'failed' ? '知识库索引失败'
: normalizedStatus === 'stale' ? '知识库需更新'
: '知识库未索引'
);
}
const openButton = entry.panel.querySelector('[data-mnote-knowledge-rag-action="open"]');
@@ -1523,7 +1523,7 @@ export const createResourceTabRuntime = (dependencies = {}) => {
artifactRootRelativePath: '',
provider: knowledgeRagProvider(),
status,
stageLabel: status === 'done' ? '资料库已索引' : status === 'failed' ? '资料库需重建' : '资料库索引中',
stageLabel: status === 'done' ? '知识库已索引' : status === 'failed' ? '知识库需重建' : '知识库索引中',
stale: registryEntry.stale === true,
updatedAtMs: Number(registryEntry.updatedAtMs || registryEntry.updated_at_ms || Date.now()),
finishedAtMs: status === 'done' ? Number(registryEntry.indexedAtMs || registryEntry.indexed_at_ms || Date.now()) : null,
@@ -1750,7 +1750,7 @@ export const createResourceTabRuntime = (dependencies = {}) => {
.filter((node) => node instanceof HTMLButtonElement);
taskToggles.forEach((toggle) => {
const opensSettings = toggle.getAttribute('data-mnote-action') === 'open-knowledge-rag-settings';
const label = runningCount > 0 ? `${runningCount}资料库索引处理中,打开资料库设置` : (jobs.length > 0 ? `${jobs.length}资料库任务,打开资料库设置` : '资料库设置');
const label = runningCount > 0 ? `${runningCount}知识库索引处理中,打开知识库设置` : (jobs.length > 0 ? `${jobs.length}知识库任务,打开知识库设置` : '知识库设置');
const taskLabel = runningCount > 0 ? `${runningCount} 个后台任务正在运行` : (jobs.length > 0 ? `${jobs.length} 个后台任务` : '后台任务');
toggle.setAttribute('title', opensSettings ? label : taskLabel);
toggle.setAttribute('aria-label', opensSettings ? label : taskLabel);
@@ -1811,7 +1811,7 @@ export const createResourceTabRuntime = (dependencies = {}) => {
row.setAttribute('data-mnote-knowledge-rag-task-row', String(job.sourceRootRelativePath || ''));
row.setAttribute('data-mnote-knowledge-rag-task-status', String(job.status || ''));
row.setAttribute('data-mnote-knowledge-rag-task-category', knowledgeRagTaskCategory(job));
const title = String(job.sourceRootRelativePath || '').split('/').filter(Boolean).pop() || '资料库索引';
const title = String(job.sourceRootRelativePath || '').split('/').filter(Boolean).pop() || '知识库索引';
const category = knowledgeRagTaskCategory(job);
const progress = knowledgeRagTaskProgress(job);
row.innerHTML = '<div class="mnote-knowledge-rag-task-main"><div class="mnote-knowledge-rag-task-title-line"><strong></strong><em></em></div><span></span><div class="mnote-knowledge-rag-task-progress" role="progressbar"><i></i></div></div><div class="mnote-knowledge-rag-task-actions"><button type="button" data-mnote-knowledge-rag-task-open>打开</button><button type="button" data-mnote-knowledge-rag-task-retry>重试</button><button type="button" data-mnote-knowledge-rag-task-clear>清除</button><button type="button" data-mnote-knowledge-rag-task-delete>删除</button></div>';
@@ -1909,9 +1909,9 @@ export const createResourceTabRuntime = (dependencies = {}) => {
const entryRootUri = String(entry.rootUri || '').trim();
if (entryRootUri) knowledgeRagTaskState.rootUri = entryRootUri;
const startedAt = Date.now();
const pendingJob = knowledgeRagTaskSnapshotFromEntry(entry, 'running', knowledgeRagProvider(), '资料库索引中', startedAt);
const pendingJob = knowledgeRagTaskSnapshotFromEntry(entry, 'running', knowledgeRagProvider(), '知识库索引中', startedAt);
pendingJob.taskKind = 'knowledge_rag';
setKnowledgeRagStatus(entry, 'running', '资料库索引中', pendingJob);
setKnowledgeRagStatus(entry, 'running', '知识库索引中', pendingJob);
updateKnowledgeRagTaskState(pendingJob);
const workspaceId = String(entry.workspaceId || currentWebShellWorkspaceId() || '').trim();
const body = {
@@ -1945,12 +1945,12 @@ export const createResourceTabRuntime = (dependencies = {}) => {
const job = knowledgeRagJobFromRegistryEntry(registryEntry, entryRootUri) || {
...pendingJob,
status: payload.retryRequired ? 'running' : 'done',
stageLabel: payload.retryRequired ? '知识库忙碌,等待重试' : '资料库已提交索引',
stageLabel: payload.retryRequired ? '知识库忙碌,等待重试' : '知识库已提交索引',
updatedAtMs: Date.now(),
finishedAtMs: payload.retryRequired ? null : Date.now(),
};
const displayStatus = knowledgeRagDisplayStatus(job, 'done');
setKnowledgeRagStatus(entry, displayStatus, displayStatus === 'stale' ? '资料库需更新' : statusTextForKnowledgeRagTask(job), job);
setKnowledgeRagStatus(entry, displayStatus, displayStatus === 'stale' ? '知识库需更新' : statusTextForKnowledgeRagTask(job), job);
if (job) updateKnowledgeRagTaskState(job);
window.dispatchEvent(new CustomEvent('mnote:knowledge-rag-source-updated', {
detail: { rootUri: entryRootUri, workspaceId, sourceRootRelativePath: String(entry.path || '').trim(), result: payload }
@@ -2003,6 +2003,25 @@ export const createResourceTabRuntime = (dependencies = {}) => {
const workspaceId = currentWebShellWorkspaceId();
const seen = new Set();
const candidates = [];
const rawDocumentId = String(documentId || '').trim();
const markdownPath = rawDocumentId.startsWith('local-md:') ? localMarkdownRelativePathFromDocumentId(rawDocumentId) : '';
if (markdownPath) {
seen.add(markdownPath);
const title = markdownPath.split('/').filter(Boolean).pop() || markdownPath;
candidates.push({
sourceKind: 'local_folder',
rootUri,
path: markdownPath,
kind: 'markdown',
title,
fileName: title,
documentId,
ownerDocumentId: documentId,
workspaceId,
objectIdentity: `local-md:${markdownPath}`,
assetId: `local-md:${markdownPath}`,
});
}
document.querySelectorAll(`.document-pane[data-pane-role="${role}"] .ProseMirror img`).forEach((image) => {
if (!(image instanceof HTMLImageElement)) return;
const sourcePath = localFileOpenPathFromTiptapHref(image.getAttribute('src') || image.src || '');
@@ -2146,13 +2165,13 @@ export const createResourceTabRuntime = (dependencies = {}) => {
});
});
}
setKnowledgeRagStatus(entry, 'idle', '资料库未索引', null);
setKnowledgeRagStatus(entry, 'idle', '知识库未索引', null);
ensureKnowledgeRagTaskDock();
void loadKnowledgeRagTasks(entry.rootUri).catch(() => undefined);
void readKnowledgeRagStatus(entry).then((job) => {
if (!job) return;
const displayStatus = knowledgeRagDisplayStatus(job, 'done');
setKnowledgeRagStatus(entry, displayStatus, displayStatus === 'stale' ? '资料库需更新' : statusTextForKnowledgeRagTask(job), job);
setKnowledgeRagStatus(entry, displayStatus, displayStatus === 'stale' ? '知识库需更新' : statusTextForKnowledgeRagTask(job), job);
updateKnowledgeRagTaskState(job);
}).catch(() => undefined);
};