Merge branch 'main' into feat-knowlege-ocr

This commit is contained in:
Chen Tao
2025-06-05 09:28:52 +08:00
committed by GitHub
6 changed files with 114 additions and 59 deletions
+1 -1
View File
@@ -96,7 +96,7 @@
"pdf-to-img": "^4.4.0",
"pdfjs-dist": "4.2.67",
"proxy-agent": "^6.5.0",
"selection-hook": "^0.9.20",
"selection-hook": "^0.9.21",
"tar": "^7.4.3",
"turndown": "^7.2.0",
"webdav": "^5.8.0",
+19 -3
View File
@@ -1,8 +1,13 @@
interface IBlacklist {
interface IFilterList {
WINDOWS: string[]
MAC?: string[]
}
interface IFinetunedList {
EXCLUDE_CLIPBOARD_CURSOR_DETECT: IFilterList
INCLUDE_CLIPBOARD_DELAY_READ: IFilterList
}
/*************************************************************************
* 注意:请不要修改此配置,除非你非常清楚其含义、影响和行为的目的
* Note: Do not modify this configuration unless you fully understand its meaning, implications, and intended behavior.
@@ -13,7 +18,7 @@ interface IBlacklist {
*
* Specification: must be all lowercase, need to accurately find the actual running program name
*************************************************************************/
export const SELECTION_PREDEFINED_BLACKLIST: IBlacklist = {
export const SELECTION_PREDEFINED_BLACKLIST: IFilterList = {
WINDOWS: [
// Screenshot
'snipaste.exe',
@@ -36,6 +41,17 @@ export const SELECTION_PREDEFINED_BLACKLIST: IBlacklist = {
'maya.exe',
// CAD
'acad.exe',
'sldworks.exe'
'sldworks.exe',
// Remote Desktop
'mstsc.exe'
]
}
export const SELECTION_FINETUNED_LIST: IFinetunedList = {
EXCLUDE_CLIPBOARD_CURSOR_DETECT: {
WINDOWS: ['acrobat.exe', 'wps.exe', 'cajviewer.exe']
},
INCLUDE_CLIPBOARD_DELAY_READ: {
WINDOWS: ['acrobat.exe', 'wps.exe', 'cajviewer.exe', 'foxitphantom.exe']
}
}
+19 -4
View File
@@ -1,4 +1,4 @@
import { SELECTION_PREDEFINED_BLACKLIST } from '@main/configs/SelectionConfig'
import { SELECTION_FINETUNED_LIST, SELECTION_PREDEFINED_BLACKLIST } from '@main/configs/SelectionConfig'
import { isDev, isWin } from '@main/constant'
import { IpcChannel } from '@shared/IpcChannel'
import { BrowserWindow, ipcMain, screen } from 'electron'
@@ -157,6 +157,7 @@ export class SelectionService {
this.filterList = configManager.getSelectionAssistantFilterList()
this.setHookGlobalFilterMode(this.filterMode, this.filterList)
this.setHookFineTunedList()
configManager.subscribe(ConfigKeys.SelectionAssistantTriggerMode, (triggerMode: TriggerMode) => {
const oldTriggerMode = this.triggerMode
@@ -205,9 +206,9 @@ export class SelectionService {
if (!this.selectionHook) return
const modeMap = {
default: 0,
whitelist: 1,
blacklist: 2
default: SelectionHook!.FilterMode.DEFAULT,
whitelist: SelectionHook!.FilterMode.INCLUDE_LIST,
blacklist: SelectionHook!.FilterMode.EXCLUDE_LIST
}
let combinedList: string[] = list
@@ -237,6 +238,20 @@ export class SelectionService {
}
}
private setHookFineTunedList() {
if (!this.selectionHook) return
this.selectionHook.setFineTunedList(
SelectionHook!.FineTunedListType.EXCLUDE_CLIPBOARD_CURSOR_DETECT,
SELECTION_FINETUNED_LIST.EXCLUDE_CLIPBOARD_CURSOR_DETECT.WINDOWS
)
this.selectionHook.setFineTunedList(
SelectionHook!.FineTunedListType.INCLUDE_CLIPBOARD_DELAY_READ,
SELECTION_FINETUNED_LIST.INCLUDE_CLIPBOARD_DELAY_READ.WINDOWS
)
}
/**
* Start the selection service and initialize required windows
* @returns {boolean} Success status of service start
@@ -1,8 +1,10 @@
import { nanoid } from '@reduxjs/toolkit'
import { CodeTool, usePreviewToolHandlers, usePreviewTools } from '@renderer/components/CodeToolbar'
import SvgSpinners180Ring from '@renderer/components/Icons/SvgSpinners180Ring'
import { useMermaid } from '@renderer/hooks/useMermaid'
import { Flex } from 'antd'
import React, { memo, startTransition, useCallback, useEffect, useRef, useState } from 'react'
import { Flex, Spin } from 'antd'
import { debounce } from 'lodash'
import React, { memo, startTransition, useCallback, useEffect, useMemo, useRef, useState } from 'react'
import styled from 'styled-components'
interface Props {
@@ -10,12 +12,16 @@ interface Props {
setTools?: (value: React.SetStateAction<CodeTool[]>) => void
}
/** 预览 Mermaid 图表
* 通过防抖渲染提供比较统一的体验,减少闪烁。
* FIXME: 等将来容易判断代码块结束位置时再重构。
*/
const MermaidPreview: React.FC<Props> = ({ children, setTools }) => {
const { mermaid, isLoading, error: mermaidError } = useMermaid()
const { mermaid, isLoading: isLoadingMermaid, error: mermaidError } = useMermaid()
const mermaidRef = useRef<HTMLDivElement>(null)
const [error, setError] = useState<string | null>(null)
const diagramId = useRef<string>(`mermaid-${nanoid(6)}`).current
const errorTimeoutRef = useRef<NodeJS.Timeout | null>(null)
const [error, setError] = useState<string | null>(null)
const [isRendering, setIsRendering] = useState(false)
// 使用通用图像工具
const { handleZoom, handleCopyImage, handleDownload } = usePreviewToolHandlers(mermaidRef, {
@@ -32,55 +38,69 @@ const MermaidPreview: React.FC<Props> = ({ children, setTools }) => {
handleDownload
})
const render = useCallback(async () => {
try {
if (!children) return
// 实际的渲染函数
const renderMermaid = useCallback(
async (content: string) => {
if (!content || !mermaidRef.current) return
// 验证语法,提前抛出异常
await mermaid.parse(children)
try {
setIsRendering(true)
if (!mermaidRef.current) return
const { svg } = await mermaid.render(diagramId, children, mermaidRef.current)
// 验证语法,提前抛出异常
await mermaid.parse(content)
// 避免不可见时产生 undefined 和 NaN
const fixedSvg = svg.replace(/translate\(undefined,\s*NaN\)/g, 'translate(0, 0)')
mermaidRef.current.innerHTML = fixedSvg
const { svg } = await mermaid.render(diagramId, content, mermaidRef.current)
// 没有语法错误时清除错误记录和定时器
setError(null)
if (errorTimeoutRef.current) {
clearTimeout(errorTimeoutRef.current)
errorTimeoutRef.current = null
}
} catch (error) {
// 延迟显示错误
if (errorTimeoutRef.current) clearTimeout(errorTimeoutRef.current)
errorTimeoutRef.current = setTimeout(() => {
// 避免不可见时产生 undefined 和 NaN
const fixedSvg = svg.replace(/translate\(undefined,\s*NaN\)/g, 'translate(0, 0)')
mermaidRef.current.innerHTML = fixedSvg
// 渲染成功,清除错误记录
setError(null)
} catch (error) {
setError((error as Error).message)
}, 500)
}
}, [children, diagramId, mermaid])
// 渲染Mermaid图表
useEffect(() => {
if (isLoading) return
startTransition(render)
// 清理定时器
return () => {
if (errorTimeoutRef.current) {
clearTimeout(errorTimeoutRef.current)
errorTimeoutRef.current = null
} finally {
setIsRendering(false)
}
},
[diagramId, mermaid]
)
// debounce 渲染
const debouncedRender = useMemo(
() =>
debounce((content: string) => {
startTransition(() => renderMermaid(content))
}, 300),
[renderMermaid]
)
// 触发渲染
useEffect(() => {
if (isLoadingMermaid) return
if (children) {
setIsRendering(true)
debouncedRender(children)
} else {
debouncedRender.cancel()
setIsRendering(false)
}
}, [isLoading, render])
return () => {
debouncedRender.cancel()
}
}, [children, isLoadingMermaid, debouncedRender])
const isLoading = isLoadingMermaid || isRendering
return (
<Flex vertical>
{(mermaidError || error) && <StyledError>{mermaidError || error}</StyledError>}
<StyledMermaid ref={mermaidRef} className="mermaid" />
</Flex>
<Spin spinning={isLoading} indicator={<SvgSpinners180Ring color="var(--color-text-2)" />}>
<Flex vertical style={{ minHeight: isLoading ? '2rem' : 'auto' }}>
{(mermaidError || error) && <StyledError>{mermaidError || error}</StyledError>}
<StyledMermaid ref={mermaidRef} className="mermaid" />
</Flex>
</Spin>
)
}
@@ -305,7 +305,11 @@ export default class GeminiProvider extends BaseProvider {
const effortRatio = EFFORT_RATIO[reasoningEffort]
if (effortRatio > 1) {
return {}
return {
thinkingConfig: {
includeThoughts: true
}
}
}
const { max } = findTokenLimit(model.id) || { max: 0 }
+5 -5
View File
@@ -5694,7 +5694,7 @@ __metadata:
remark-math: "npm:^6.0.0"
rollup-plugin-visualizer: "npm:^5.12.0"
sass: "npm:^1.88.0"
selection-hook: "npm:^0.9.20"
selection-hook: "npm:^0.9.21"
shiki: "npm:^3.4.2"
string-width: "npm:^7.2.0"
styled-components: "npm:^6.1.11"
@@ -16543,13 +16543,13 @@ __metadata:
languageName: node
linkType: hard
"selection-hook@npm:^0.9.20":
version: 0.9.20
resolution: "selection-hook@npm:0.9.20"
"selection-hook@npm:^0.9.21":
version: 0.9.21
resolution: "selection-hook@npm:0.9.21"
dependencies:
node-gyp: "npm:latest"
node-gyp-build: "npm:^4.8.4"
checksum: 10c0/2508fc5093a735467bd7082ae84432e2b7d8675d194f9bcf74dab755a63f72ffcbbeee2784297402fbb295faddd590b0333ca290b37047d8af25ed584cd04e60
checksum: 10c0/e458f8d37c049899e0f9450ca29f882ee01e11b15490f7ee2ddd088843e3e9a201fd5410083faebfbf11e1259a2a74b0b736ff8f1789b626a21ea48ef0ca8705
languageName: node
linkType: hard