更新 TransEngine 以支持嵌入管理器,优化日志输出,添加删除确认对话框功能,改进 ChatView 组件的文件管理和上下文信息处理,确保更好的用户体验和代码可读性。

This commit is contained in:
duanfuxiang 2025-07-05 16:24:49 +08:00
parent bbd89fbfa4
commit a2fcb7c20f
4 changed files with 242 additions and 45 deletions

View File

@ -1312,15 +1312,15 @@ const Chat = forwardRef<ChatRef, ChatProps>((props, ref) => {
</button>
<button
onClick={() => {
if (tab === 'workspace') {
if (tab === 'insights') {
setTab('chat')
} else {
setTab('workspace')
setTab('insights')
}
}}
className="infio-chat-list-dropdown"
>
<Box size={18} color={tab === 'workspace' ? 'var(--text-accent)' : 'var(--text-color)'} />
<Brain size={18} color={tab === 'insights' ? 'var(--text-accent)' : 'var(--text-color)'} />
</button>
<button
onClick={() => {
@ -1334,6 +1334,18 @@ const Chat = forwardRef<ChatRef, ChatProps>((props, ref) => {
>
<Search size={18} color={tab === 'search' ? 'var(--text-accent)' : 'var(--text-color)'} />
</button>
<button
onClick={() => {
if (tab === 'workspace') {
setTab('chat')
} else {
setTab('workspace')
}
}}
className="infio-chat-list-dropdown"
>
<Box size={18} color={tab === 'workspace' ? 'var(--text-accent)' : 'var(--text-color)'} />
</button>
<button
onClick={() => {
// switch between chat and prompts
@ -1372,18 +1384,6 @@ const Chat = forwardRef<ChatRef, ChatProps>((props, ref) => {
>
<Server size={18} color={tab === 'mcp' ? 'var(--text-accent)' : 'var(--text-color)'} />
</button>
<button
onClick={() => {
if (tab === 'insights') {
setTab('chat')
} else {
setTab('insights')
}
}}
className="infio-chat-list-dropdown"
>
<Brain size={18} color={tab === 'insights' ? 'var(--text-accent)' : 'var(--text-color)'} />
</button>
</div>
</div>
{/* main view */}

View File

@ -50,6 +50,8 @@ const InsightView = () => {
// 删除洞察状态
const [isDeleting, setIsDeleting] = useState(false)
const [deletingInsightId, setDeletingInsightId] = useState<number | null>(null)
// 确认对话框状态
const [showDeleteConfirm, setShowDeleteConfirm] = useState(false)
const loadInsights = useCallback(async () => {
setIsLoading(true)
@ -243,6 +245,11 @@ const InsightView = () => {
}
}, [getTransEngine, settings, workspaceManager, loadInsights])
// 确认删除工作区洞察
const handleDeleteWorkspaceInsights = useCallback(() => {
setShowDeleteConfirm(true)
}, [])
// 删除工作区洞察
const deleteWorkspaceInsights = useCallback(async () => {
setIsDeleting(true)
@ -280,6 +287,17 @@ const InsightView = () => {
}
}, [getTransEngine, settings, workspaceManager, loadInsights])
// 确认删除工作区洞察
const confirmDeleteWorkspaceInsights = useCallback(async () => {
setShowDeleteConfirm(false)
await deleteWorkspaceInsights()
}, [deleteWorkspaceInsights])
// 取消删除确认
const cancelDeleteConfirm = useCallback(() => {
setShowDeleteConfirm(false)
}, [])
// 删除单个洞察
const deleteSingleInsight = useCallback(async (insightId: number) => {
setDeletingInsightId(insightId)
@ -482,7 +500,7 @@ const InsightView = () => {
{isInitializing ? '初始化中...' : '初始化洞察'}
</button>
<button
onClick={deleteWorkspaceInsights}
onClick={handleDeleteWorkspaceInsights}
disabled={isDeleting || isLoading || isInitializing}
className="obsidian-insight-delete-btn"
title="删除当前工作区的所有转换和洞察"
@ -564,6 +582,42 @@ const InsightView = () => {
</div>
)}
{/* 确认删除对话框 */}
{showDeleteConfirm && (
<div className="obsidian-confirm-dialog-overlay">
<div className="obsidian-confirm-dialog">
<div className="obsidian-confirm-dialog-header">
<h3></h3>
</div>
<div className="obsidian-confirm-dialog-body">
<p>
</p>
<p className="obsidian-confirm-dialog-warning">
</p>
<div className="obsidian-confirm-dialog-scope">
<strong>:</strong> {currentScope}
</div>
</div>
<div className="obsidian-confirm-dialog-footer">
<button
onClick={cancelDeleteConfirm}
className="obsidian-confirm-dialog-cancel-btn"
>
</button>
<button
onClick={confirmDeleteWorkspaceInsights}
className="obsidian-confirm-dialog-confirm-btn"
>
</button>
</div>
</div>
</div>
)}
{/* 洞察结果 */}
<div className="obsidian-insight-results">
{!isLoading && insightGroupedResults.length > 0 && (
@ -1098,6 +1152,117 @@ const InsightView = () => {
color: var(--text-faint);
font-style: italic;
}
/* 确认对话框样式 */
.obsidian-confirm-dialog-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
}
.obsidian-confirm-dialog {
background-color: var(--background-primary);
border: 1px solid var(--background-modifier-border);
border-radius: var(--radius-l);
box-shadow: var(--shadow-l);
max-width: 400px;
width: 90%;
max-height: 80vh;
overflow: hidden;
}
.obsidian-confirm-dialog-header {
padding: 16px 20px;
border-bottom: 1px solid var(--background-modifier-border);
background-color: var(--background-secondary);
}
.obsidian-confirm-dialog-header h3 {
margin: 0;
color: var(--text-normal);
font-size: var(--font-ui-large);
font-weight: 600;
}
.obsidian-confirm-dialog-body {
padding: 20px;
color: var(--text-normal);
font-size: var(--font-ui-medium);
line-height: 1.5;
}
.obsidian-confirm-dialog-body p {
margin: 0 0 12px 0;
}
.obsidian-confirm-dialog-warning {
border: 1px solid var(--background-modifier-border);
border-radius: var(--radius-s);
padding: 12px;
margin: 12px 0;
color: var(--text-error);
font-size: var(--font-ui-small);
font-weight: 500;
}
.obsidian-confirm-dialog-scope {
background-color: var(--background-secondary);
border: 1px solid var(--background-modifier-border);
border-radius: var(--radius-s);
padding: 8px 12px;
margin: 12px 0 0 0;
font-size: var(--font-ui-small);
color: var(--text-muted);
}
.obsidian-confirm-dialog-footer {
padding: 16px 20px;
border-top: 1px solid var(--background-modifier-border);
background-color: var(--background-secondary);
display: flex;
justify-content: flex-end;
gap: 12px;
}
.obsidian-confirm-dialog-cancel-btn {
padding: 8px 16px;
background-color: var(--interactive-normal);
border: 1px solid var(--background-modifier-border);
border-radius: var(--radius-s);
color: var(--text-normal);
font-size: var(--font-ui-small);
cursor: pointer;
transition: all 0.2s ease;
font-weight: 500;
}
.obsidian-confirm-dialog-cancel-btn:hover {
background-color: var(--interactive-hover);
}
.obsidian-confirm-dialog-confirm-btn {
padding: 8px 16px;
background-color: #dc3545;
border: 1px solid #dc3545;
border-radius: var(--radius-s);
color: white;
font-size: var(--font-ui-small);
cursor: pointer;
transition: all 0.2s ease;
font-weight: 500;
}
.obsidian-confirm-dialog-confirm-btn:hover {
background-color: #c82333;
border-color: #c82333;
}
`}
</style>
</div>

View File

@ -20,6 +20,15 @@ import { SIMPLE_SUMMARY_DESCRIPTION, SIMPLE_SUMMARY_PROMPT } from '../prompts/tr
import { TABLE_OF_CONTENTS_DESCRIPTION, TABLE_OF_CONTENTS_PROMPT } from '../prompts/transformations/table-of-contents';
import { getEmbeddingModel } from '../rag/embedding';
// EmbeddingManager 类型定义
type EmbeddingManager = {
modelLoaded: boolean
currentModel: string | null
loadModel(modelId: string, useGpu: boolean): Promise<any>
embed(text: string): Promise<{ vec: number[] }>
embedBatch(texts: string[]): Promise<{ vec: number[] }[]>
}
/**
*
*/
@ -298,21 +307,24 @@ export class TransEngine {
private llmManager: LLMManager;
private insightManager: InsightManager | null = null;
private embeddingModel: EmbeddingModel | null = null;
private embeddingManager?: EmbeddingManager;
constructor(
app: App,
settings: InfioSettings,
dbManager: DBManager,
embeddingManager?: EmbeddingManager,
) {
this.app = app;
this.settings = settings;
this.llmManager = new LLMManager(settings);
this.insightManager = dbManager.getInsightManager();
this.embeddingManager = embeddingManager;
// 初始化 embedding model
if (settings.embeddingModelId && settings.embeddingModelId.trim() !== '') {
try {
this.embeddingModel = getEmbeddingModel(settings);
this.embeddingModel = getEmbeddingModel(settings, embeddingManager);
} catch (error) {
console.warn('Failed to initialize embedding model:', error);
this.embeddingModel = null;
@ -334,7 +346,7 @@ export class TransEngine {
// 重新初始化 embedding model
if (settings.embeddingModelId && settings.embeddingModelId.trim() !== '') {
try {
this.embeddingModel = getEmbeddingModel(settings);
this.embeddingModel = getEmbeddingModel(settings, this.embeddingManager);
} catch (error) {
console.warn('Failed to initialize embedding model:', error);
this.embeddingModel = null;
@ -395,7 +407,12 @@ export class TransEngine {
> {
// 如果没有必要的参数,跳过缓存检查
if (!this.embeddingModel || !this.insightManager) {
console.log("no embeddingModel or insightManager");
console.log("TransEngine: 跳过缓存检查");
console.log("embeddingModel:", this.embeddingModel ? "已初始化" : "未初始化");
console.log("insightManager:", this.insightManager ? "已初始化" : "未初始化");
console.log("embeddingModelId:", this.settings.embeddingModelId);
console.log("embeddingModelProvider:", this.settings.embeddingModelProvider);
console.log("提示:请在插件设置中配置嵌入模型,或点击'一键配置'按钮");
return {
success: true,
foundCache: false
@ -488,6 +505,11 @@ export class TransEngine {
contentType: 'document' | 'tag' | 'folder'
): Promise<void> {
if (!this.embeddingModel || !this.insightManager) {
console.log("TransEngine: 无法保存到数据库");
console.log("embeddingModel:", this.embeddingModel ? "已初始化" : "未初始化");
console.log("insightManager:", this.insightManager ? "已初始化" : "未初始化");
console.log("embeddingModelId:", this.settings.embeddingModelId);
console.log("embeddingModelProvider:", this.settings.embeddingModelProvider);
return;
}
@ -1027,6 +1049,11 @@ export class TransEngine {
> {
if (!this.embeddingModel || !this.insightManager) {
console.warn('TransEngine: embedding model or insight manager not available')
console.log("embeddingModel:", this.embeddingModel ? "已初始化" : "未初始化");
console.log("insightManager:", this.insightManager ? "已初始化" : "未初始化");
console.log("embeddingModelId:", this.settings.embeddingModelId);
console.log("embeddingModelProvider:", this.settings.embeddingModelProvider);
console.log("提示:请在插件设置中配置嵌入模型,或点击'一键配置'按钮");
return []
}
@ -1082,6 +1109,11 @@ export class TransEngine {
async getAllInsights(): Promise<Omit<import('../../database/schema').SelectSourceInsight, 'embedding'>[]> {
if (!this.embeddingModel || !this.insightManager) {
console.warn('TransEngine: embedding model or insight manager not available')
console.log("embeddingModel:", this.embeddingModel ? "已初始化" : "未初始化");
console.log("insightManager:", this.insightManager ? "已初始化" : "未初始化");
console.log("embeddingModelId:", this.settings.embeddingModelId);
console.log("embeddingModelProvider:", this.settings.embeddingModelProvider);
console.log("提示:请在插件设置中配置嵌入模型,或点击'一键配置'按钮");
return []
}

View File

@ -640,7 +640,7 @@ export default class InfioPlugin extends Plugin {
if (!this.transEngineInitPromise) {
this.transEngineInitPromise = (async () => {
const dbManager = await this.getDbManager()
this.transEngine = new TransEngine(this.app, this.settings, dbManager)
this.transEngine = new TransEngine(this.app, this.settings, dbManager, this.embeddingManager)
return this.transEngine
})()
}