mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-25 19:30:17 +08:00
* build: 添加 tesseract.js 及其类型定义依赖 * feat(ocr): 添加OCR类型定义文件以支持OCR功能扩展 * feat(ocr): 添加 Tesseract OCR 提供程序配置 * feat(ocr): 添加Tesseract.js的logo * refactor(settings): 重构文档预处理设置模块结构 将PreprocessSettings重命名为DocProcessSettings并调整文件结构 更新相关路由和组件引用以保持功能一致性 * refactor(config): 重命名OCR_PROVIDER_CONFIG为BUILTIN_OCR_PROVIDERS以更准确描述用途 * refactor(ocr): 更改文件名 * refactor(ocr): 将获取OCR提供商logo的功能移动到utils目录 将getOcrProviderLogo函数从config/ocr.ts移动到utils/ocr.ts,保持功能集中 * refactor(ocr): 重构OCR配置结构以支持默认提供者 将内置OCR提供者数组重构为单独定义的常量,并添加默认OCR提供者映射。这提高了代码的可维护性并支持未来扩展。 * feat(store): 添加OCR状态管理切片 实现OCR提供商的增删改查功能,使用Redux Toolkit管理OCR相关状态 * feat(types): 添加图片文件类型守卫函数 添加 ImageFileMetadata 类型和 isImageFile 类型守卫函数,用于检查文件是否为图片类型 * feat(ocr): 添加对OCR支持文件类型的类型定义和校验函数 添加SupportedOcrFileType类型和isSupportedOcrFileType校验函数 添加SupportedOcrFile类型和isSupportedOcrFile校验函数 * feat(ocr): 添加OCR功能支持 实现基于Tesseract的OCR功能,包括文件类型检查、服务接口和IPC通信 新增OCR相关类型定义和服务实现 * refactor(OcrService): 更新日志上下文为'main:OcrService' * feat(ocr): 添加OCR服务基础功能 实现OCR服务的基础功能,通过调用window.api.ocr接口处理支持的文件类型 * feat(store): 添加ocr模块到redux store * feat(ocr): 添加OCR功能支持及文件类型校验 添加OCR功能钩子useOcr,支持图片文件识别 添加不支持文件类型的错误提示国际化文案 * refactor(ocr): 重命名updatePreprocessProvider为updateOcrProvider以保持命名一致性 * feat(ocr): 添加设置图片OCR提供商的功能 * refactor(ocr): 统一OCR类型导入路径 将所有OCR相关类型从'@renderer/types/ocr'改为从'@renderer/types'或'@types'导入 优化DEFAULT_OCR_PROVIDER类型定义 * feat(store): 更新持久化存储版本并添加OCR配置迁移 添加137版本迁移逻辑,初始化OCR提供者和默认图像提供者配置 * feat(ocr): 添加OCR服务设置界面及提供商选择功能 实现OCR服务设置界面,包含图片OCR提供商的选择功能 修复ocr.ts中imageProvider的类型定义 添加相关国际化文本 * fix(ocr): 添加图像大小检查并优化错误处理 检查图像文件大小是否超过50MB限制 使用buffer读取文件替代直接路径识别 简化错误处理逻辑,直接抛出原始错误 * feat(OCR服务): 支持base64字符串作为OCR输入 扩展tesseractOcr函数以接受base64字符串或图像文件作为输入 * feat(hooks): 添加useFiles钩子用于文件选择功能 * refactor(useFiles): 移除multipleSelections参数并重构文件选择逻辑 将multipleSelections从组件props移动到onSelectFile方法参数中,简化组件接口 重构文件选择逻辑,移除不必要的useMemo,提升代码可维护性 * refactor(useFiles): 使用useMemo优化扩展名处理逻辑 将扩展名处理逻辑移至useMemo中,避免不必要的重复计算。当props.extensions未提供时默认返回['*'] * feat(文件选择): 增强文件选择功能并添加清除文件方法 - 为文件选择API添加返回类型声明 - 完善文件选择回调函数的文档注释 - 修改文件选择逻辑以返回选中的文件数组 - 添加清除文件列表的方法 * refactor(useFiles): 将参数从布尔值改为对象以增强可扩展性 * feat(hooks): 在useFiles钩子中暴露selecting状态 * feat(translate): 添加文件OCR功能支持 在翻译页面新增浮动按钮,支持通过OCR识别文件内容并自动填充到输入框。添加相关hooks和文件类型检查逻辑,提升用户输入便捷性。 * build: 将 tesseract.js 从 devDependencies 移至 dependencies 确保生产环境能正确使用 tesseract.js 功能 * refactor(ocr): 将Tesseract服务文件移动到tesseract子目录并更新配置 * refactor(TesseractService): 添加日志记录并更新worker配置 添加loggerService用于记录worker日志,并更新createWorker配置以使用自定义logger * feat(翻译页面): 添加OCR处理中的加载状态提示 在翻译页面中添加OCR处理时的加载状态提示,提升用户体验 * fix(translate): 为OCR处理消息添加无限持续时间 防止OCR处理过程中消息自动消失,确保用户明确知道处理状态 * fix: 添加OCR未知错误的翻译并更新错误提示 在OCR处理失败时,使用翻译后的错误消息替代原始错误提示 * style(translate): 调整浮动按钮位置从右上到左下 * fix(translate): 处理未选择文件时提前返回以避免空指针异常 * feat(i18n): 添加OCR功能的多语言支持 * feat(fs): 添加自动识别编码读取文本文件功能 实现通过自动检测文件编码来读取文本文件的功能 在IPC通道、预加载API和文件服务中添加相关方法 * feat(翻译): 添加文件读取功能并改进错误处理 添加对文本文件的支持并优化文件处理流程 改进错误提示信息,包括文件过大和读取失败的场景 * fix(i18n): 更新文件大小限制错误信息并添加多语言支持 修改文件大小限制的错误信息格式,移除括号内的限制范围 为多种语言添加文件操作相关的翻译条目 在错误提示中动态显示文件大小限制范围 * refactor(AttachmentButton): 移除类型注释,使用自动类型推断 * fix(hooks): 返回变量supportedFiles * fix(ocr): 改进OCR处理中的消息管理和错误处理 在useOcr钩子中统一管理OCR处理的消息提示,并完善错误处理逻辑 移除TranslatePage中重复的消息管理代码,简化OCR处理流程 * fix(translate): 在选择文件后清除文件状态以避免残留 在文件选择完成后调用clearFiles以清除文件状态 * refactor(preload): 移动OCR类型定义到共享类型文件 将OCR相关的类型定义(OcrProvider, OcrResult, SupportedOcrFile)从渲染进程类型文件移动到共享类型文件@types,以提高代码复用性和维护性 * refactor(ocr): 修改tesseractOcr返回完整识别结果而非仅文本 返回完整识别结果以便后续处理使用更多OCR信息,同时简化imageOcr中的条件判断逻辑 * fix(ocr): 修复文件类型与OCR提供者能力不匹配时的错误抛出位置 将错误抛出语句移至else分支 * refactor(ocr): 简化 DEFAULT_OCR_PROVIDER 的类型定义 * build: 将 tesseract.js 从 devDependencies 移至 dependencies 确保生产环境能正确使用 tesseract.js 功能 * refactor(ocr): 将Tesseract服务文件移动到tesseract子目录并更新配置 * refactor(TesseractService): 添加日志记录并更新worker配置 添加loggerService用于记录worker日志,并更新createWorker配置以使用自定义logger * feat(i18n): 添加OCR功能的多语言支持 * refactor(preload): 移动OCR类型定义到共享类型文件 将OCR相关的类型定义(OcrProvider, OcrResult, SupportedOcrFile)从渲染进程类型文件移动到共享类型文件@types,以提高代码复用性和维护性 * refactor(ocr): 修改tesseractOcr返回完整识别结果而非仅文本 返回完整识别结果以便后续处理使用更多OCR信息,同时简化imageOcr中的条件判断逻辑 * fix(ocr): 修复文件类型与OCR提供者能力不匹配时的错误抛出位置 将错误抛出语句移至else分支 * refactor(ocr): 简化 DEFAULT_OCR_PROVIDER 的类型定义 * fix(ocr): 改进OCR处理中的消息管理和错误处理 在useOcr钩子中统一管理OCR处理的消息提示,并完善错误处理逻辑 移除TranslatePage中重复的消息管理代码,简化OCR处理流程 * feat(i18n): 添加OCR相关的错误和状态翻译文本 * fix(useOcr): 修复未支持文件类型错误抛出位置 将不支持的OCR文件类型错误抛出逻辑移至条件判断内 * refactor(ocr): ocrImage实现使用OcrService并更新日志上下文 将ocrImage函数从useOcr钩子移动到OcrService中,提高代码复用性 更新日志服务上下文从'main'改为'renderer'以更准确反映模块位置 * style(TabContainer): 移除多余的空行并保持代码整洁 * refactor(ocr): 简化OCR文件类型检查逻辑 使用现有的isImageFile函数替代冗余的类型检查逻辑,提高代码复用性 * fix: 将迁移错误日志从136更新为137 * feat(ocr): enhance Tesseract service with language support and worker management - Added support for multiple Tesseract languages: Chinese (Simplified and Traditional) and English. - Refactored Tesseract worker management into a class for better encapsulation and reuse. - Introduced methods to dynamically determine language path based on IP country and manage worker lifecycle. * update cn url * support cn data * change to asyn * use register design mode * add type * use bind function * refactor(ipc): 简化OCR处理程序参数 * refactor(ocr): 修改ocrProviderCapabilityRecord类型定义 允许只定义部分能力 * refactor(ocr): 将Tesseract相关配置移至服务内部 将语言列表和下载URL常量从共享配置移至Tesseract服务内部 使用常量定义图片大小阈值以提高可读性 * refactor(ocr): 统一使用 SupportedOcrFile 类型替换 FileMetadata 更新 OCR 服务及其 Tesseract 实现,使用 SupportedOcrFile 类型替代原有的 FileMetadata 类型,以提高类型安全性和一致性。同时在 OcrService 中添加重复注册的警告日志。 * refactor(ocr): 重构OCR类型定义以支持模型和API配置 将OCR提供者配置拆分为独立类型,增加模型能力记录和API配置类型检查 添加OCR处理程序类型定义,为未来扩展提供更好的类型支持 * refactor(OcrService): 移除重复的OcrHandler类型定义 已在@types中定义OcrHandler类型,移除重复定义以提高代码一致性 * refactor(ocr): 将OcrService移动到ocr目录下并更新引用路径 * feat(ocr): 添加OCR API客户端工厂及示例实现 实现OCR API客户端工厂模式,支持根据不同提供商创建对应的客户端 新增OcrBaseApiClient作为基础类,提供通用功能 添加OcrExampleApiClient作为示例实现 修改OcrService以使用新的客户端工厂 * refactor(ocr): 添加日志记录以跟踪OCR文件处理 在OCR服务中添加日志记录功能,便于跟踪文件处理过程 * fix(deps): 更新 tesseract.js 依赖并添加补丁文件 修复 tesseract.js 类型定义问题并添加语言常量支持 * refactor(ocr): 移除注释掉的tesseract语言映射代码 使用Tesseract.js的LanguageCode类型替代硬编码的语言列表,提高类型安全性 * feat(ocr): 添加 Tesseract OCR 配置类型 * refactor(OCR设置): 重命名OcrImageProviderSettings为OcrImageSettings并优化代码结构 * refactor(ocr): 将 Tesseract 相关类型移动到文件底部以改善代码组织 * feat(ocr): 添加 Tesseract OCR 提供者类型检查函数 * feat(ocr): 添加更新OCR提供者配置的功能 * feat: 添加OCR提供者钩子函数 实现useOcrProvider钩子用于获取和更新OCR提供者配置 * refactor(ocr): 修改removeOcrProvider参数为字符串id 简化removeOcrProvider方法的参数类型,直接使用字符串id进行过滤,提高代码简洁性 * refactor(ocr): 将内置OCR提供者从数组改为映射结构 重构OCR配置模块,使用映射结构存储内置OCR提供者以便于扩展和维护 * refactor(ocr): 将BUILTIN_OCR_PROVIDERS改为只读数组 使用Object.freeze确保数组不可变,提高代码安全性 * feat(ocr): 添加OCR提供者管理功能并改进错误处理 添加useOcrProviders钩子用于管理OCR提供者的添加和删除 当内置OCR提供者不存在时自动恢复默认配置 改进错误提示信息并增加国际化支持 * Revert "refactor(ocr): 将BUILTIN_OCR_PROVIDERS改为只读数组" This reverts commitf23e37941a. * feat(ocr): 为Tesseract OCR添加多语言支持配置 添加对简体中文、繁体中文和英文的语言支持配置,扩展OCR功能以满足多语言识别需求 * refactor(types): 将Tesseract.LanguageCode重命名为TesseractLangCode以提高可读性 * feat(OCR设置): 添加OCR提供商设置组件及状态管理 新增OCR提供商设置组件,支持显示当前选择的OCR提供商信息 在OCR图片设置中添加状态管理,同步提供商选择到父组件 添加Tesseract OCR设置组件,支持多语言选择(暂不可用) * fix(DocProcessSettings): 修复OCR语言选择默认值问题 * feat(i18n): 添加OCR提供商相关错误和警告的翻译 * fix(ocr): 将 Tesseract 语言配置类型改为部分 * fix(ocr): 修复ocrImage函数未使用await导致的问题 * fix(ocr): 修复迁移配置中ocr状态的初始化方式 将分散的属性赋值改为对象整体赋值,避免潜在的属性丢失问题 * chore: 移除不再使用的@types/tesseract.js依赖 * refactor(OCR设置): 添加错误边界处理并移除无用注释 在OCR设置组件中添加ErrorBoundary以处理潜在错误 移除OcrTesseractSettings中的TODO注释 * build: 添加 sharp 依赖以支持图片处理功能 * refactor(ocr): 添加OCR图像预处理功能并优化TesseractService Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com> * refactor(ocr): 移除独立的灰度处理模块并改进预处理流程 将灰度处理功能直接集成到OCR预处理中,不再需要单独的image模块 添加normalise和threshold处理以提升OCR识别效果 * feat(i18n): 添加文件上传tool tip的翻译文本 * feat(hooks): 添加useDrag钩子实现拖拽功能 * feat(translate): 添加拖拽上传文件功能 实现文件拖拽上传功能,包括拖拽区域高亮显示和提示文本 添加多文件上传错误提示和未知错误处理 * feat(i18n): 添加文件拖拽和多文件上传错误提示的翻译 * refactor(PasteService): 优化粘贴服务逻辑并移除不必要的翻译依赖 将`t`参数改为布尔类型的`showMessage`参数,简化消息显示逻辑 添加默认的粘贴文本长度阈值 使文件扩展名检查变为可选参数 更新相关调用处的参数传递 * Revert "refactor(PasteService): 优化粘贴服务逻辑并移除不必要的翻译依赖" This reverts commit07c7ecd0cf. * fix(preload): 为文件获取方法添加返回类型声明 添加Promise<FileMetadata | null>返回类型以明确get方法的返回值类型,提高代码可读性和类型安全性 * refactor(TopView): 移除未使用的loggerService导入和调用 * feat(TranslatePage): 添加对粘贴上传文件的支持 新增粘贴上传文件功能,处理剪贴板中的文件数据并支持图片临时文件创建 添加文件类型检查和不支持类型的错误提示 重构文件选择逻辑到通用函数 getSingleFile * feat(i18n): 添加不支持文件类型的多语言翻译 * feat(translate): 添加翻译输入状态并优化内容更新逻辑 添加translateInput状态以存储翻译输入内容 优化setTranslatedContent reducer直接修改状态而非返回新对象 * refactor(translate): 将文本输入状态迁移至redux存储 移除本地状态_text和使用useState管理的text,改为从redux store中获取和管理输入文本 * fix(translate): 修复依赖数组中缺少setText导致的状态更新问题 * fix(store): 初始化翻译输入为空字符串 修复迁移配置时未初始化翻译输入的问题,避免潜在的undefined错误 * fix(hooks): 使 useDrag 的 onDrop 参数变为可选 处理 onDrop 未定义时的调用情况,避免运行时错误 * fix(拖拽): 修复拖拽状态未正确更新的问题 修复 handleDragOver 中未设置 isDragging 状态的问题 为输入区域添加独立的拖拽状态处理 防止容器元素意外触发文件拖放 * refactor(translate): 在文件拖放错误处理中移动错误提示位置 将文件拖放错误提示从空文件检查移动到文件读取错误捕获中 * improve image preprocess --------- Co-authored-by: beyondkmp <beyondkmp@gmail.com> Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
440 lines
25 KiB
TypeScript
440 lines
25 KiB
TypeScript
import type { ExtractChunkData } from '@cherrystudio/embedjs-interfaces'
|
|
import { electronAPI } from '@electron-toolkit/preload'
|
|
import { SpanEntity, TokenUsage } from '@mcp-trace/trace-core'
|
|
import { SpanContext } from '@opentelemetry/api'
|
|
import { UpgradeChannel } from '@shared/config/constant'
|
|
import type { LogLevel, LogSourceWithContext } from '@shared/config/logger'
|
|
import { IpcChannel } from '@shared/IpcChannel'
|
|
import {
|
|
AddMemoryOptions,
|
|
AssistantMessage,
|
|
FileListResponse,
|
|
FileMetadata,
|
|
FileUploadResponse,
|
|
KnowledgeBaseParams,
|
|
KnowledgeItem,
|
|
MCPServer,
|
|
MemoryConfig,
|
|
MemoryListOptions,
|
|
MemorySearchOptions,
|
|
OcrProvider,
|
|
OcrResult,
|
|
Provider,
|
|
S3Config,
|
|
Shortcut,
|
|
SupportedOcrFile,
|
|
ThemeMode,
|
|
WebDavConfig
|
|
} from '@types'
|
|
import { contextBridge, ipcRenderer, OpenDialogOptions, shell, webUtils } from 'electron'
|
|
import { Notification } from 'src/renderer/src/types/notification'
|
|
import { CreateDirectoryOptions } from 'webdav'
|
|
|
|
import type { ActionItem } from '../renderer/src/types/selectionTypes'
|
|
|
|
export function tracedInvoke(channel: string, spanContext: SpanContext | undefined, ...args: any[]) {
|
|
if (spanContext) {
|
|
const data = { type: 'trace', context: spanContext }
|
|
return ipcRenderer.invoke(channel, ...args, data)
|
|
}
|
|
return ipcRenderer.invoke(channel, ...args)
|
|
}
|
|
|
|
// Custom APIs for renderer
|
|
const api = {
|
|
getAppInfo: () => ipcRenderer.invoke(IpcChannel.App_Info),
|
|
reload: () => ipcRenderer.invoke(IpcChannel.App_Reload),
|
|
setProxy: (proxy: string | undefined, bypassRules?: string) =>
|
|
ipcRenderer.invoke(IpcChannel.App_Proxy, proxy, bypassRules),
|
|
checkForUpdate: () => ipcRenderer.invoke(IpcChannel.App_CheckForUpdate),
|
|
showUpdateDialog: () => ipcRenderer.invoke(IpcChannel.App_ShowUpdateDialog),
|
|
setLanguage: (lang: string) => ipcRenderer.invoke(IpcChannel.App_SetLanguage, lang),
|
|
setEnableSpellCheck: (isEnable: boolean) => ipcRenderer.invoke(IpcChannel.App_SetEnableSpellCheck, isEnable),
|
|
setSpellCheckLanguages: (languages: string[]) => ipcRenderer.invoke(IpcChannel.App_SetSpellCheckLanguages, languages),
|
|
setLaunchOnBoot: (isActive: boolean) => ipcRenderer.invoke(IpcChannel.App_SetLaunchOnBoot, isActive),
|
|
setLaunchToTray: (isActive: boolean) => ipcRenderer.invoke(IpcChannel.App_SetLaunchToTray, isActive),
|
|
setTray: (isActive: boolean) => ipcRenderer.invoke(IpcChannel.App_SetTray, isActive),
|
|
setTrayOnClose: (isActive: boolean) => ipcRenderer.invoke(IpcChannel.App_SetTrayOnClose, isActive),
|
|
setTestPlan: (isActive: boolean) => ipcRenderer.invoke(IpcChannel.App_SetTestPlan, isActive),
|
|
setTestChannel: (channel: UpgradeChannel) => ipcRenderer.invoke(IpcChannel.App_SetTestChannel, channel),
|
|
setTheme: (theme: ThemeMode) => ipcRenderer.invoke(IpcChannel.App_SetTheme, theme),
|
|
handleZoomFactor: (delta: number, reset: boolean = false) =>
|
|
ipcRenderer.invoke(IpcChannel.App_HandleZoomFactor, delta, reset),
|
|
setAutoUpdate: (isActive: boolean) => ipcRenderer.invoke(IpcChannel.App_SetAutoUpdate, isActive),
|
|
select: (options: Electron.OpenDialogOptions) => ipcRenderer.invoke(IpcChannel.App_Select, options),
|
|
hasWritePermission: (path: string) => ipcRenderer.invoke(IpcChannel.App_HasWritePermission, path),
|
|
resolvePath: (path: string) => ipcRenderer.invoke(IpcChannel.App_ResolvePath, path),
|
|
isPathInside: (childPath: string, parentPath: string) =>
|
|
ipcRenderer.invoke(IpcChannel.App_IsPathInside, childPath, parentPath),
|
|
setAppDataPath: (path: string) => ipcRenderer.invoke(IpcChannel.App_SetAppDataPath, path),
|
|
getDataPathFromArgs: () => ipcRenderer.invoke(IpcChannel.App_GetDataPathFromArgs),
|
|
copy: (oldPath: string, newPath: string, occupiedDirs: string[] = []) =>
|
|
ipcRenderer.invoke(IpcChannel.App_Copy, oldPath, newPath, occupiedDirs),
|
|
setStopQuitApp: (stop: boolean, reason: string) => ipcRenderer.invoke(IpcChannel.App_SetStopQuitApp, stop, reason),
|
|
flushAppData: () => ipcRenderer.invoke(IpcChannel.App_FlushAppData),
|
|
isNotEmptyDir: (path: string) => ipcRenderer.invoke(IpcChannel.App_IsNotEmptyDir, path),
|
|
relaunchApp: (options?: Electron.RelaunchOptions) => ipcRenderer.invoke(IpcChannel.App_RelaunchApp, options),
|
|
openWebsite: (url: string) => ipcRenderer.invoke(IpcChannel.Open_Website, url),
|
|
getCacheSize: () => ipcRenderer.invoke(IpcChannel.App_GetCacheSize),
|
|
clearCache: () => ipcRenderer.invoke(IpcChannel.App_ClearCache),
|
|
logToMain: (source: LogSourceWithContext, level: LogLevel, message: string, data: any[]) =>
|
|
ipcRenderer.invoke(IpcChannel.App_LogToMain, source, level, message, data),
|
|
setFullScreen: (value: boolean): Promise<void> => ipcRenderer.invoke(IpcChannel.App_SetFullScreen, value),
|
|
mac: {
|
|
isProcessTrusted: (): Promise<boolean> => ipcRenderer.invoke(IpcChannel.App_MacIsProcessTrusted),
|
|
requestProcessTrust: (): Promise<boolean> => ipcRenderer.invoke(IpcChannel.App_MacRequestProcessTrust)
|
|
},
|
|
notification: {
|
|
send: (notification: Notification) => ipcRenderer.invoke(IpcChannel.Notification_Send, notification)
|
|
},
|
|
system: {
|
|
getDeviceType: () => ipcRenderer.invoke(IpcChannel.System_GetDeviceType),
|
|
getHostname: () => ipcRenderer.invoke(IpcChannel.System_GetHostname)
|
|
},
|
|
devTools: {
|
|
toggle: () => ipcRenderer.invoke(IpcChannel.System_ToggleDevTools)
|
|
},
|
|
zip: {
|
|
compress: (text: string) => ipcRenderer.invoke(IpcChannel.Zip_Compress, text),
|
|
decompress: (text: Buffer) => ipcRenderer.invoke(IpcChannel.Zip_Decompress, text)
|
|
},
|
|
backup: {
|
|
backup: (filename: string, content: string, path: string, skipBackupFile: boolean) =>
|
|
ipcRenderer.invoke(IpcChannel.Backup_Backup, filename, content, path, skipBackupFile),
|
|
restore: (path: string) => ipcRenderer.invoke(IpcChannel.Backup_Restore, path),
|
|
backupToWebdav: (data: string, webdavConfig: WebDavConfig) =>
|
|
ipcRenderer.invoke(IpcChannel.Backup_BackupToWebdav, data, webdavConfig),
|
|
restoreFromWebdav: (webdavConfig: WebDavConfig) =>
|
|
ipcRenderer.invoke(IpcChannel.Backup_RestoreFromWebdav, webdavConfig),
|
|
listWebdavFiles: (webdavConfig: WebDavConfig) =>
|
|
ipcRenderer.invoke(IpcChannel.Backup_ListWebdavFiles, webdavConfig),
|
|
checkConnection: (webdavConfig: WebDavConfig) =>
|
|
ipcRenderer.invoke(IpcChannel.Backup_CheckConnection, webdavConfig),
|
|
createDirectory: (webdavConfig: WebDavConfig, path: string, options?: CreateDirectoryOptions) =>
|
|
ipcRenderer.invoke(IpcChannel.Backup_CreateDirectory, webdavConfig, path, options),
|
|
deleteWebdavFile: (fileName: string, webdavConfig: WebDavConfig) =>
|
|
ipcRenderer.invoke(IpcChannel.Backup_DeleteWebdavFile, fileName, webdavConfig),
|
|
backupToLocalDir: (
|
|
data: string,
|
|
fileName: string,
|
|
localConfig: { localBackupDir?: string; skipBackupFile?: boolean }
|
|
) => ipcRenderer.invoke(IpcChannel.Backup_BackupToLocalDir, data, fileName, localConfig),
|
|
restoreFromLocalBackup: (fileName: string, localBackupDir?: string) =>
|
|
ipcRenderer.invoke(IpcChannel.Backup_RestoreFromLocalBackup, fileName, localBackupDir),
|
|
listLocalBackupFiles: (localBackupDir?: string) =>
|
|
ipcRenderer.invoke(IpcChannel.Backup_ListLocalBackupFiles, localBackupDir),
|
|
deleteLocalBackupFile: (fileName: string, localBackupDir?: string) =>
|
|
ipcRenderer.invoke(IpcChannel.Backup_DeleteLocalBackupFile, fileName, localBackupDir),
|
|
checkWebdavConnection: (webdavConfig: WebDavConfig) =>
|
|
ipcRenderer.invoke(IpcChannel.Backup_CheckConnection, webdavConfig),
|
|
|
|
backupToS3: (data: string, s3Config: S3Config) => ipcRenderer.invoke(IpcChannel.Backup_BackupToS3, data, s3Config),
|
|
restoreFromS3: (s3Config: S3Config) => ipcRenderer.invoke(IpcChannel.Backup_RestoreFromS3, s3Config),
|
|
listS3Files: (s3Config: S3Config) => ipcRenderer.invoke(IpcChannel.Backup_ListS3Files, s3Config),
|
|
deleteS3File: (fileName: string, s3Config: S3Config) =>
|
|
ipcRenderer.invoke(IpcChannel.Backup_DeleteS3File, fileName, s3Config),
|
|
checkS3Connection: (s3Config: S3Config) => ipcRenderer.invoke(IpcChannel.Backup_CheckS3Connection, s3Config)
|
|
},
|
|
file: {
|
|
select: (options?: OpenDialogOptions): Promise<FileMetadata[] | null> =>
|
|
ipcRenderer.invoke(IpcChannel.File_Select, options),
|
|
upload: (file: FileMetadata) => ipcRenderer.invoke(IpcChannel.File_Upload, file),
|
|
delete: (fileId: string) => ipcRenderer.invoke(IpcChannel.File_Delete, fileId),
|
|
deleteDir: (dirPath: string) => ipcRenderer.invoke(IpcChannel.File_DeleteDir, dirPath),
|
|
read: (fileId: string, detectEncoding?: boolean) =>
|
|
ipcRenderer.invoke(IpcChannel.File_Read, fileId, detectEncoding),
|
|
clear: (spanContext?: SpanContext) => ipcRenderer.invoke(IpcChannel.File_Clear, spanContext),
|
|
get: (filePath: string): Promise<FileMetadata | null> => ipcRenderer.invoke(IpcChannel.File_Get, filePath),
|
|
/**
|
|
* 创建一个空的临时文件
|
|
* @param fileName 文件名
|
|
* @returns 临时文件路径
|
|
*/
|
|
createTempFile: (fileName: string): Promise<string> => ipcRenderer.invoke(IpcChannel.File_CreateTempFile, fileName),
|
|
/**
|
|
* 写入文件
|
|
* @param filePath 文件路径
|
|
* @param data 数据
|
|
*/
|
|
write: (filePath: string, data: Uint8Array | string) => ipcRenderer.invoke(IpcChannel.File_Write, filePath, data),
|
|
|
|
writeWithId: (id: string, content: string) => ipcRenderer.invoke(IpcChannel.File_WriteWithId, id, content),
|
|
open: (options?: OpenDialogOptions) => ipcRenderer.invoke(IpcChannel.File_Open, options),
|
|
openPath: (path: string) => ipcRenderer.invoke(IpcChannel.File_OpenPath, path),
|
|
save: (path: string, content: string | NodeJS.ArrayBufferView, options?: any) =>
|
|
ipcRenderer.invoke(IpcChannel.File_Save, path, content, options),
|
|
selectFolder: (spanContext?: SpanContext) => ipcRenderer.invoke(IpcChannel.File_SelectFolder, spanContext),
|
|
saveImage: (name: string, data: string) => ipcRenderer.invoke(IpcChannel.File_SaveImage, name, data),
|
|
binaryImage: (fileId: string) => ipcRenderer.invoke(IpcChannel.File_BinaryImage, fileId),
|
|
base64Image: (fileId: string) => ipcRenderer.invoke(IpcChannel.File_Base64Image, fileId),
|
|
saveBase64Image: (data: string) => ipcRenderer.invoke(IpcChannel.File_SaveBase64Image, data),
|
|
download: (url: string, isUseContentType?: boolean) =>
|
|
ipcRenderer.invoke(IpcChannel.File_Download, url, isUseContentType),
|
|
copy: (fileId: string, destPath: string) => ipcRenderer.invoke(IpcChannel.File_Copy, fileId, destPath),
|
|
base64File: (fileId: string) => ipcRenderer.invoke(IpcChannel.File_Base64File, fileId),
|
|
pdfInfo: (fileId: string) => ipcRenderer.invoke(IpcChannel.File_GetPdfInfo, fileId),
|
|
getPathForFile: (file: File) => webUtils.getPathForFile(file),
|
|
openFileWithRelativePath: (file: FileMetadata) => ipcRenderer.invoke(IpcChannel.File_OpenWithRelativePath, file),
|
|
isTextFile: (filePath: string): Promise<boolean> => ipcRenderer.invoke(IpcChannel.File_IsTextFile, filePath)
|
|
},
|
|
fs: {
|
|
read: (pathOrUrl: string, encoding?: BufferEncoding) => ipcRenderer.invoke(IpcChannel.Fs_Read, pathOrUrl, encoding),
|
|
readText: (pathOrUrl: string): Promise<string> => ipcRenderer.invoke(IpcChannel.Fs_ReadText, pathOrUrl)
|
|
},
|
|
export: {
|
|
toWord: (markdown: string, fileName: string) => ipcRenderer.invoke(IpcChannel.Export_Word, markdown, fileName)
|
|
},
|
|
obsidian: {
|
|
getVaults: () => ipcRenderer.invoke(IpcChannel.Obsidian_GetVaults),
|
|
getFolders: (vaultName: string) => ipcRenderer.invoke(IpcChannel.Obsidian_GetFiles, vaultName),
|
|
getFiles: (vaultName: string) => ipcRenderer.invoke(IpcChannel.Obsidian_GetFiles, vaultName)
|
|
},
|
|
openPath: (path: string) => ipcRenderer.invoke(IpcChannel.Open_Path, path),
|
|
shortcuts: {
|
|
update: (shortcuts: Shortcut[]) => ipcRenderer.invoke(IpcChannel.Shortcuts_Update, shortcuts)
|
|
},
|
|
knowledgeBase: {
|
|
create: (base: KnowledgeBaseParams, context?: SpanContext) =>
|
|
tracedInvoke(IpcChannel.KnowledgeBase_Create, context, base),
|
|
reset: (base: KnowledgeBaseParams) => ipcRenderer.invoke(IpcChannel.KnowledgeBase_Reset, base),
|
|
delete: (id: string) => ipcRenderer.invoke(IpcChannel.KnowledgeBase_Delete, id),
|
|
add: ({
|
|
base,
|
|
item,
|
|
userId,
|
|
forceReload = false
|
|
}: {
|
|
base: KnowledgeBaseParams
|
|
item: KnowledgeItem
|
|
userId?: string
|
|
forceReload?: boolean
|
|
}) => ipcRenderer.invoke(IpcChannel.KnowledgeBase_Add, { base, item, forceReload, userId }),
|
|
remove: ({ uniqueId, uniqueIds, base }: { uniqueId: string; uniqueIds: string[]; base: KnowledgeBaseParams }) =>
|
|
ipcRenderer.invoke(IpcChannel.KnowledgeBase_Remove, { uniqueId, uniqueIds, base }),
|
|
search: ({ search, base }: { search: string; base: KnowledgeBaseParams }, context?: SpanContext) =>
|
|
tracedInvoke(IpcChannel.KnowledgeBase_Search, context, { search, base }),
|
|
rerank: (
|
|
{ search, base, results }: { search: string; base: KnowledgeBaseParams; results: ExtractChunkData[] },
|
|
context?: SpanContext
|
|
) => tracedInvoke(IpcChannel.KnowledgeBase_Rerank, context, { search, base, results }),
|
|
checkQuota: ({ base, userId }: { base: KnowledgeBaseParams; userId: string }) =>
|
|
ipcRenderer.invoke(IpcChannel.KnowledgeBase_Check_Quota, base, userId)
|
|
},
|
|
memory: {
|
|
add: (messages: string | AssistantMessage[], options?: AddMemoryOptions) =>
|
|
ipcRenderer.invoke(IpcChannel.Memory_Add, messages, options),
|
|
search: (query: string, options: MemorySearchOptions) =>
|
|
ipcRenderer.invoke(IpcChannel.Memory_Search, query, options),
|
|
list: (options?: MemoryListOptions) => ipcRenderer.invoke(IpcChannel.Memory_List, options),
|
|
delete: (id: string) => ipcRenderer.invoke(IpcChannel.Memory_Delete, id),
|
|
update: (id: string, memory: string, metadata?: Record<string, any>) =>
|
|
ipcRenderer.invoke(IpcChannel.Memory_Update, id, memory, metadata),
|
|
get: (id: string) => ipcRenderer.invoke(IpcChannel.Memory_Get, id),
|
|
setConfig: (config: MemoryConfig) => ipcRenderer.invoke(IpcChannel.Memory_SetConfig, config),
|
|
deleteUser: (userId: string) => ipcRenderer.invoke(IpcChannel.Memory_DeleteUser, userId),
|
|
deleteAllMemoriesForUser: (userId: string) =>
|
|
ipcRenderer.invoke(IpcChannel.Memory_DeleteAllMemoriesForUser, userId),
|
|
getUsersList: () => ipcRenderer.invoke(IpcChannel.Memory_GetUsersList)
|
|
},
|
|
window: {
|
|
setMinimumSize: (width: number, height: number) =>
|
|
ipcRenderer.invoke(IpcChannel.Windows_SetMinimumSize, width, height),
|
|
resetMinimumSize: () => ipcRenderer.invoke(IpcChannel.Windows_ResetMinimumSize),
|
|
getSize: (): Promise<[number, number]> => ipcRenderer.invoke(IpcChannel.Windows_GetSize)
|
|
},
|
|
fileService: {
|
|
upload: (provider: Provider, file: FileMetadata): Promise<FileUploadResponse> =>
|
|
ipcRenderer.invoke(IpcChannel.FileService_Upload, provider, file),
|
|
list: (provider: Provider): Promise<FileListResponse> => ipcRenderer.invoke(IpcChannel.FileService_List, provider),
|
|
delete: (provider: Provider, fileId: string) => ipcRenderer.invoke(IpcChannel.FileService_Delete, provider, fileId),
|
|
retrieve: (provider: Provider, fileId: string): Promise<FileUploadResponse> =>
|
|
ipcRenderer.invoke(IpcChannel.FileService_Retrieve, provider, fileId)
|
|
},
|
|
selectionMenu: {
|
|
action: (action: string) => ipcRenderer.invoke('selection-menu:action', action)
|
|
},
|
|
|
|
vertexAI: {
|
|
getAuthHeaders: (params: { projectId: string; serviceAccount?: { privateKey: string; clientEmail: string } }) =>
|
|
ipcRenderer.invoke(IpcChannel.VertexAI_GetAuthHeaders, params),
|
|
getAccessToken: (params: { projectId: string; serviceAccount?: { privateKey: string; clientEmail: string } }) =>
|
|
ipcRenderer.invoke(IpcChannel.VertexAI_GetAccessToken, params),
|
|
clearAuthCache: (projectId: string, clientEmail?: string) =>
|
|
ipcRenderer.invoke(IpcChannel.VertexAI_ClearAuthCache, projectId, clientEmail)
|
|
},
|
|
config: {
|
|
set: (key: string, value: any, isNotify: boolean = false) =>
|
|
ipcRenderer.invoke(IpcChannel.Config_Set, key, value, isNotify),
|
|
get: (key: string) => ipcRenderer.invoke(IpcChannel.Config_Get, key)
|
|
},
|
|
miniWindow: {
|
|
show: () => ipcRenderer.invoke(IpcChannel.MiniWindow_Show),
|
|
hide: () => ipcRenderer.invoke(IpcChannel.MiniWindow_Hide),
|
|
close: () => ipcRenderer.invoke(IpcChannel.MiniWindow_Close),
|
|
toggle: () => ipcRenderer.invoke(IpcChannel.MiniWindow_Toggle),
|
|
setPin: (isPinned: boolean) => ipcRenderer.invoke(IpcChannel.MiniWindow_SetPin, isPinned)
|
|
},
|
|
aes: {
|
|
encrypt: (text: string, secretKey: string, iv: string) =>
|
|
ipcRenderer.invoke(IpcChannel.Aes_Encrypt, text, secretKey, iv),
|
|
decrypt: (encryptedData: string, iv: string, secretKey: string) =>
|
|
ipcRenderer.invoke(IpcChannel.Aes_Decrypt, encryptedData, iv, secretKey)
|
|
},
|
|
mcp: {
|
|
removeServer: (server: MCPServer) => ipcRenderer.invoke(IpcChannel.Mcp_RemoveServer, server),
|
|
restartServer: (server: MCPServer) => ipcRenderer.invoke(IpcChannel.Mcp_RestartServer, server),
|
|
stopServer: (server: MCPServer) => ipcRenderer.invoke(IpcChannel.Mcp_StopServer, server),
|
|
listTools: (server: MCPServer, context?: SpanContext) => tracedInvoke(IpcChannel.Mcp_ListTools, context, server),
|
|
callTool: (
|
|
{ server, name, args, callId }: { server: MCPServer; name: string; args: any; callId?: string },
|
|
context?: SpanContext
|
|
) => tracedInvoke(IpcChannel.Mcp_CallTool, context, { server, name, args, callId }),
|
|
listPrompts: (server: MCPServer) => ipcRenderer.invoke(IpcChannel.Mcp_ListPrompts, server),
|
|
getPrompt: ({ server, name, args }: { server: MCPServer; name: string; args?: Record<string, any> }) =>
|
|
ipcRenderer.invoke(IpcChannel.Mcp_GetPrompt, { server, name, args }),
|
|
listResources: (server: MCPServer) => ipcRenderer.invoke(IpcChannel.Mcp_ListResources, server),
|
|
getResource: ({ server, uri }: { server: MCPServer; uri: string }) =>
|
|
ipcRenderer.invoke(IpcChannel.Mcp_GetResource, { server, uri }),
|
|
getInstallInfo: () => ipcRenderer.invoke(IpcChannel.Mcp_GetInstallInfo),
|
|
checkMcpConnectivity: (server: any) => ipcRenderer.invoke(IpcChannel.Mcp_CheckConnectivity, server),
|
|
uploadDxt: async (file: File) => {
|
|
const buffer = await file.arrayBuffer()
|
|
return ipcRenderer.invoke(IpcChannel.Mcp_UploadDxt, buffer, file.name)
|
|
},
|
|
abortTool: (callId: string) => ipcRenderer.invoke(IpcChannel.Mcp_AbortTool, callId),
|
|
getServerVersion: (server: MCPServer): Promise<string | null> =>
|
|
ipcRenderer.invoke(IpcChannel.Mcp_GetServerVersion, server)
|
|
},
|
|
python: {
|
|
execute: (script: string, context?: Record<string, any>, timeout?: number) =>
|
|
ipcRenderer.invoke(IpcChannel.Python_Execute, script, context, timeout)
|
|
},
|
|
shell: {
|
|
openExternal: (url: string, options?: Electron.OpenExternalOptions) => shell.openExternal(url, options)
|
|
},
|
|
copilot: {
|
|
getAuthMessage: (headers?: Record<string, string>) =>
|
|
ipcRenderer.invoke(IpcChannel.Copilot_GetAuthMessage, headers),
|
|
getCopilotToken: (device_code: string, headers?: Record<string, string>) =>
|
|
ipcRenderer.invoke(IpcChannel.Copilot_GetCopilotToken, device_code, headers),
|
|
saveCopilotToken: (access_token: string) => ipcRenderer.invoke(IpcChannel.Copilot_SaveCopilotToken, access_token),
|
|
getToken: (headers?: Record<string, string>) => ipcRenderer.invoke(IpcChannel.Copilot_GetToken, headers),
|
|
logout: () => ipcRenderer.invoke(IpcChannel.Copilot_Logout),
|
|
getUser: (token: string) => ipcRenderer.invoke(IpcChannel.Copilot_GetUser, token)
|
|
},
|
|
// Binary related APIs
|
|
isBinaryExist: (name: string) => ipcRenderer.invoke(IpcChannel.App_IsBinaryExist, name),
|
|
getBinaryPath: (name: string) => ipcRenderer.invoke(IpcChannel.App_GetBinaryPath, name),
|
|
installUVBinary: () => ipcRenderer.invoke(IpcChannel.App_InstallUvBinary),
|
|
installBunBinary: () => ipcRenderer.invoke(IpcChannel.App_InstallBunBinary),
|
|
protocol: {
|
|
onReceiveData: (callback: (data: { url: string; params: any }) => void) => {
|
|
const listener = (_event: Electron.IpcRendererEvent, data: { url: string; params: any }) => {
|
|
callback(data)
|
|
}
|
|
ipcRenderer.on('protocol-data', listener)
|
|
return () => {
|
|
ipcRenderer.off('protocol-data', listener)
|
|
}
|
|
}
|
|
},
|
|
nutstore: {
|
|
getSSOUrl: () => ipcRenderer.invoke(IpcChannel.Nutstore_GetSsoUrl),
|
|
decryptToken: (token: string) => ipcRenderer.invoke(IpcChannel.Nutstore_DecryptToken, token),
|
|
getDirectoryContents: (token: string, path: string) =>
|
|
ipcRenderer.invoke(IpcChannel.Nutstore_GetDirectoryContents, token, path)
|
|
},
|
|
searchService: {
|
|
openSearchWindow: (uid: string) => ipcRenderer.invoke(IpcChannel.SearchWindow_Open, uid),
|
|
closeSearchWindow: (uid: string) => ipcRenderer.invoke(IpcChannel.SearchWindow_Close, uid),
|
|
openUrlInSearchWindow: (uid: string, url: string) => ipcRenderer.invoke(IpcChannel.SearchWindow_OpenUrl, uid, url)
|
|
},
|
|
webview: {
|
|
setOpenLinkExternal: (webviewId: number, isExternal: boolean) =>
|
|
ipcRenderer.invoke(IpcChannel.Webview_SetOpenLinkExternal, webviewId, isExternal),
|
|
setSpellCheckEnabled: (webviewId: number, isEnable: boolean) =>
|
|
ipcRenderer.invoke(IpcChannel.Webview_SetSpellCheckEnabled, webviewId, isEnable)
|
|
},
|
|
storeSync: {
|
|
subscribe: () => ipcRenderer.invoke(IpcChannel.StoreSync_Subscribe),
|
|
unsubscribe: () => ipcRenderer.invoke(IpcChannel.StoreSync_Unsubscribe),
|
|
onUpdate: (action: any) => ipcRenderer.invoke(IpcChannel.StoreSync_OnUpdate, action)
|
|
},
|
|
selection: {
|
|
hideToolbar: () => ipcRenderer.invoke(IpcChannel.Selection_ToolbarHide),
|
|
writeToClipboard: (text: string) => ipcRenderer.invoke(IpcChannel.Selection_WriteToClipboard, text),
|
|
determineToolbarSize: (width: number, height: number) =>
|
|
ipcRenderer.invoke(IpcChannel.Selection_ToolbarDetermineSize, width, height),
|
|
setEnabled: (enabled: boolean) => ipcRenderer.invoke(IpcChannel.Selection_SetEnabled, enabled),
|
|
setTriggerMode: (triggerMode: string) => ipcRenderer.invoke(IpcChannel.Selection_SetTriggerMode, triggerMode),
|
|
setFollowToolbar: (isFollowToolbar: boolean) =>
|
|
ipcRenderer.invoke(IpcChannel.Selection_SetFollowToolbar, isFollowToolbar),
|
|
setRemeberWinSize: (isRemeberWinSize: boolean) =>
|
|
ipcRenderer.invoke(IpcChannel.Selection_SetRemeberWinSize, isRemeberWinSize),
|
|
setFilterMode: (filterMode: string) => ipcRenderer.invoke(IpcChannel.Selection_SetFilterMode, filterMode),
|
|
setFilterList: (filterList: string[]) => ipcRenderer.invoke(IpcChannel.Selection_SetFilterList, filterList),
|
|
processAction: (actionItem: ActionItem, isFullScreen: boolean = false) =>
|
|
ipcRenderer.invoke(IpcChannel.Selection_ProcessAction, actionItem, isFullScreen),
|
|
closeActionWindow: () => ipcRenderer.invoke(IpcChannel.Selection_ActionWindowClose),
|
|
minimizeActionWindow: () => ipcRenderer.invoke(IpcChannel.Selection_ActionWindowMinimize),
|
|
pinActionWindow: (isPinned: boolean) => ipcRenderer.invoke(IpcChannel.Selection_ActionWindowPin, isPinned)
|
|
},
|
|
quoteToMainWindow: (text: string) => ipcRenderer.invoke(IpcChannel.App_QuoteToMain, text),
|
|
setDisableHardwareAcceleration: (isDisable: boolean) =>
|
|
ipcRenderer.invoke(IpcChannel.App_SetDisableHardwareAcceleration, isDisable),
|
|
trace: {
|
|
saveData: (topicId: string) => ipcRenderer.invoke(IpcChannel.TRACE_SAVE_DATA, topicId),
|
|
getData: (topicId: string, traceId: string, modelName?: string) =>
|
|
ipcRenderer.invoke(IpcChannel.TRACE_GET_DATA, topicId, traceId, modelName),
|
|
saveEntity: (entity: SpanEntity) => ipcRenderer.invoke(IpcChannel.TRACE_SAVE_ENTITY, entity),
|
|
getEntity: (spanId: string) => ipcRenderer.invoke(IpcChannel.TRACE_GET_ENTITY, spanId),
|
|
bindTopic: (topicId: string, traceId: string) => ipcRenderer.invoke(IpcChannel.TRACE_BIND_TOPIC, topicId, traceId),
|
|
tokenUsage: (spanId: string, usage: TokenUsage) => ipcRenderer.invoke(IpcChannel.TRACE_TOKEN_USAGE, spanId, usage),
|
|
cleanHistory: (topicId: string, traceId: string, modelName?: string) =>
|
|
ipcRenderer.invoke(IpcChannel.TRACE_CLEAN_HISTORY, topicId, traceId, modelName),
|
|
cleanTopic: (topicId: string, traceId?: string) =>
|
|
ipcRenderer.invoke(IpcChannel.TRACE_CLEAN_TOPIC, topicId, traceId),
|
|
openWindow: (topicId: string, traceId: string, autoOpen?: boolean, modelName?: string) =>
|
|
ipcRenderer.invoke(IpcChannel.TRACE_OPEN_WINDOW, topicId, traceId, autoOpen, modelName),
|
|
setTraceWindowTitle: (title: string) => ipcRenderer.invoke(IpcChannel.TRACE_SET_TITLE, title),
|
|
addEndMessage: (spanId: string, modelName: string, context: string) =>
|
|
ipcRenderer.invoke(IpcChannel.TRACE_ADD_END_MESSAGE, spanId, modelName, context),
|
|
cleanLocalData: () => ipcRenderer.invoke(IpcChannel.TRACE_CLEAN_LOCAL_DATA),
|
|
addStreamMessage: (spanId: string, modelName: string, context: string, message: any) =>
|
|
ipcRenderer.invoke(IpcChannel.TRACE_ADD_STREAM_MESSAGE, spanId, modelName, context, message)
|
|
},
|
|
codeTools: {
|
|
run: (
|
|
cliTool: string,
|
|
model: string,
|
|
directory: string,
|
|
env: Record<string, string>,
|
|
options?: { autoUpdateToLatest?: boolean }
|
|
) => ipcRenderer.invoke(IpcChannel.CodeTools_Run, cliTool, model, directory, env, options)
|
|
},
|
|
ocr: {
|
|
ocr: (file: SupportedOcrFile, provider: OcrProvider): Promise<OcrResult> =>
|
|
ipcRenderer.invoke(IpcChannel.OCR_ocr, file, provider)
|
|
}
|
|
}
|
|
|
|
// Use `contextBridge` APIs to expose Electron APIs to
|
|
// renderer only if context isolation is enabled, otherwise
|
|
// just add to the DOM global.
|
|
if (process.contextIsolated) {
|
|
try {
|
|
contextBridge.exposeInMainWorld('electron', electronAPI)
|
|
contextBridge.exposeInMainWorld('api', api)
|
|
} catch (error) {
|
|
// eslint-disable-next-line no-restricted-syntax
|
|
console.error('[Preload]Failed to expose APIs:', error as Error)
|
|
}
|
|
} else {
|
|
// @ts-ignore (define in dts)
|
|
window.electron = electronAPI
|
|
// @ts-ignore (define in dts)
|
|
window.api = api
|
|
}
|
|
|
|
export type WindowApiType = typeof api
|