import { ElectronAPI } from '@electron-toolkit/preload' import { Contact, Message, MessagesAroundResult } from '../shared/types' import { GroupReportExportRequest, GroupReportExportResult, GroupReportRenderSnapshotExportRequest } from '../shared/group-report' import type { InstalledReportTemplate, ReportTemplateOperationResult } from '../shared/report-template-package' import type { ReportTemplateCatalogInstallResult, ReportTemplateCatalogResult } from '../shared/report-template-market' import { LocalApiTestRequest, LocalApiTestResponse } from '../shared/local-api-test' import { DeleteGeneratedReportResult, ReportHistoryResult, SaveGeneratedReportRequest, SaveGeneratedReportResult, PrepareGeneratedReportTemplateSwitchResult, UpdateGeneratedReportTemplateRequest, UpdateGeneratedReportTemplateResult } from '../shared/report-history' import type { DatabaseKeyEnvironment, DatabaseInitResult, DatabaseKeyStorageResult, DatabaseKeyValidationResult, AccountDiscoveryResult } from '../shared/database-key' import type { ImageDecoderSelectionResult, ImageDecoderStatus, ImageDecryptionStatus, ImageDecryptionTestResult, ImageKeyConfigResult, SaveImageKeyRequest, TestImageDecryptionRequest } from '../shared/image-decryption' import type { AIChatRequestOptions, AiSearchExternalAuthorizationRequest, AiSearchExternalAuthorizationResult, AiSearchProviderStatus, AIConnectionTestResult, AIProviderConfig, AIProviderListResult, AIRuntimeModelConfig, AIVisionRuntimeConfig, AIVisionTestRequest, AIVisionTestResult, LegacyAIConfig } from '../shared/ai-provider' import type { ImageAnalysisRequest, ImageAnalysisResponse, ImageCandidate, ImageCandidateQuery, ImageInsight } from '../shared/image-insight' import type { SystemOcrCapability, SystemOcrRequest, SystemOcrResult } from '../shared/system-ocr' import type { ImageTextIndexCountResult, ImageTextIndexRepairResult, ImageTextIndexStartOptions, ImageTextIndexStatus } from '../shared/image-text-index' import type { AgentHubActionResult, AgentHubLogEntry, AgentHubStatus } from '../shared/agent-hub' import type { AgentHubConversation, AgentHubConversationMessage, AgentHubConversationSummary } from '../shared/agent-hub-conversation' import type { PersonalWechatGeneratedTtsVoiceRequest, PersonalWechatGeneratedTtsVoiceResult, PersonalWechatSendRequest, PersonalWechatSendResult, PersonalWechatSenderStatus, PersonalWechatVoiceDiagnostic } from '../shared/personal-wechat' import type { PersonalWechatSendCapability } from '../shared/personal-wechat' import type { GroupMemberStatsQuery, GroupMemberStatsResult } from '../shared/group-stats' import type { ScheduledReportExecution, ScheduledReportNotification, ScheduledReportNotificationCapability, ScheduledReportNotificationSettings, ScheduledReportNotificationSettingsResult, ScheduledReportResult } from '../shared/scheduled-report' import type { PersonalWechatVoiceEncodingEnvironment, PersonalWechatVoiceEncodingEnvironmentResult } from '../shared/personal-wechat-voice-runtime' import type { AppLogEntry } from '../shared/app-log' import type { GroupExitMonitorEvent, GroupExitMonitorState } from '../shared/group-exit-monitor' import type { AutomationExecution, AutomationRule, AutomationRuleDraft, AutomationStatusSummary, ScheduledRuleRunOutcome } from '../shared/automation' import type { ActionLogEntry } from '../shared/action-log' import type { AppUpdateCheckResult, AppUpdateInstallResult, AppUpdateOpenDownloadPageResult, AppUpdateState } from '../shared/app-update' import type { CacheClearScope, CacheSummary } from '../shared/cache' import type { ExportRequest, ExportJobProgress, ExportResult } from '../shared/export' import type { VoiceBatchPreflight, VoiceBatchConversationSummary, VoiceBatchProgress, VoiceBatchRequest, VoiceMessageReference, VoiceModelDownloadResult, VoiceModelProgressEvent, VoiceModelStatus, VoiceRecognitionResult, VoiceTranscriptSnapshot } from '../shared/voice-recognition' import type { AiSearchCancelResult, AiSearchPipelineRequest, AiSearchPipelineResult, AiSearchProgressEvent } from '../shared/ai-search' import type { AskWechatConfig, AskWechatQueryRequest, AskWechatQueryResult, QueryAgentProgressEvent } from '../shared/query-agent' import type { KnowledgeRuntimeStatus, KnowledgeSearchIpcRequest, KnowledgeSearchIpcResult } from '../shared/knowledge' import type { PublishWechatShareCardRequest, PublishWechatShareCardResult, WechatShareServiceConfig, WechatShareServiceConfigResult } from '../shared/wechat-share-card' import type { ListTextToSpeechVoicesRequest, ListTextToSpeechVoicesResult, SaveTextToSpeechSettingsRequest, SynthesizeTextToSpeechRequest, SynthesizeTextToSpeechResult, TextToSpeechSettingsResult } from '../shared/text-to-speech' export type ParsedContent = | { type: 'text'; content: string } | { type: 'voice'; duration?: number } | { type: 'location'; poiname?: string; label?: string; lat: number; lng: number } | { type: 'card'; username: string; nickname: string; avatarUrl?: string } | { type: 'share' title: string des?: string url: string appname?: string typeVal?: string } | { type: 'miniProgram' title: string description?: string appName?: string iconUrl?: string thumbMd5?: string thumbDatName?: string thumbDataUrl?: string } | { type: 'redPacket'; title: string; description?: string; url?: string } | { type: 'voip'; duration?: number; status: string; roomType?: number } | { type: 'image'; md5?: string; datName?: string; aeskey?: string; encrypVer?: number } | { type: 'video' md5?: string newMd5?: string rawMd5?: string byteLength?: number duration?: number width?: number height?: number } | { type: 'sticker' md5?: string url?: string thumbUrl?: string encryptUrl?: string aeskey?: string } | { type: 'quote' title?: string content?: string sender?: string quotedContent?: string quotedSender?: string quotedType?: string } | { type: 'system'; content: string } | { type: 'unknown'; raw: string } declare global { interface Window { electron: ElectronAPI api: { writeAppLog: (entry: AppLogEntry) => Promise getAppLogPath: () => Promise revealAppLog: () => Promise getAppUpdateState: () => Promise checkAppUpdate: () => Promise downloadAppUpdate: () => Promise installAppUpdate: () => Promise openAppUpdateDownloadPage: () => Promise onAppUpdateState: (callback: (state: AppUpdateState) => void) => () => void getCacheSummary: () => Promise clearCache: (scope: CacheClearScope) => Promise openKnowledgeDirectory: () => Promise<{ success: boolean; error?: string }> initDb: (key: string, accountRoot: string) => Promise discoverAccounts: (inputPath: string) => Promise getBootstrapCache: () => Promise<{ self?: { wxid: string; nickname: string; avatar?: string; accountRoot: string } contacts: Contact[] updatedAt: number } | null> getStartupCache: () => Promise<{ self?: { wxid: string; nickname: string; avatar?: string; accountRoot: string } contacts: Contact[] updatedAt: number } | null> getContacts: (filter?: string) => Promise getContactAvatars: ( usernames: string[], options?: { refresh?: boolean } ) => Promise> getCachedMessages: ( userMd5: string, startTime?: number, endTime?: number ) => Promise getCachedMessagePage: ( userMd5: string, startTime?: number, endTime?: number ) => Promise<{ hit: boolean messages: Message[] groupSnapshot?: { roomId: string memberCount: number members: { wxid: string nickname: string groupNickname: string wechatNickname: string remark: string avatar: string }[] } }> getMessages: ( userMd5: string, startTime?: number, endTime?: number, options?: { limit?: number } ) => Promise getMessagesAround: ( userMd5: string, messageId: string, anchorSeconds?: number, radiusSeconds?: number ) => Promise getGroupSnapshot: (userMd5: string) => Promise<{ roomId: string memberCount: number members: { wxid: string nickname: string groupNickname: string wechatNickname: string remark: string avatar: string }[] } | null> getGroupMemberStats: (request: GroupMemberStatsQuery) => Promise getGroupExitMonitorState: () => Promise listGroupExitMonitorEvents: (query?: { roomId?: string sinceMs?: number untilMs?: number limit?: number }) => Promise setGroupExitMonitorEnabled: (enabled: boolean) => Promise /** 保存**监控范围**。通知配置已迁到「自动化 → 退群通知」。 */ setGroupExitMonitorGroups: (roomIds: string[]) => Promise checkGroupExitMonitorNow: () => Promise clearGroupExitMonitorEvents: () => Promise markGroupExitMonitorRead: (readAt?: number) => Promise listWechatActionLogs: () => Promise getAutomationStatus: () => Promise listAutomationRules: () => Promise createAutomationRule: (draft: AutomationRuleDraft) => Promise updateAutomationRule: ( id: string, draft: AutomationRuleDraft ) => Promise deleteAutomationRule: (id: string) => Promise setAutomationRuleEnabled: (id: string, enabled: boolean) => Promise listAutomationExecutions: (query?: { limit?: number }) => Promise clearAutomationExecutions: () => Promise listAutomationGroups: () => Promise> /** 保存「退群通知」规则(singleton upsert)。 */ saveLeaveNotificationRule: (draft: AutomationRuleDraft) => Promise /** 「指定好友」的可选项;已在 main 侧过滤掉群聊 / 公众号 / 文件传输助手 / 自己。 */ listSendableContacts: () => Promise> onGroupExitMonitorState: (callback: (state: GroupExitMonitorState) => void) => () => void search: (keyword: string) => Promise searchKnowledge: (request: KnowledgeSearchIpcRequest) => Promise runAiSearch: (request: AiSearchPipelineRequest) => Promise cancelAiSearch: (requestId: string) => Promise onAiSearchProgress: (callback: (progress: AiSearchProgressEvent) => void) => () => void getAskWechatConfig: () => Promise runAskWechatQuery: (request: AskWechatQueryRequest) => Promise onAskWechatProgress: ( callback: (requestId: string, event: QueryAgentProgressEvent) => void ) => () => void forgetAskWechatConversation: () => Promise getKnowledgeStatus: () => Promise startKnowledgeIndex: () => Promise cancelKnowledgeIndex: () => Promise<{ cancellable: boolean; cancelled: boolean }> onKnowledgeStatus: (callback: (status: KnowledgeRuntimeStatus) => void) => () => void aiChat: ( messages: { role: string; content: string }[], options?: AIChatRequestOptions ) => Promise<{ success: boolean data?: string finishReason?: string usage?: { input?: number output?: number total?: number estimated?: boolean } error?: string }> listAIProviders: () => Promise getAIRuntimeConfig: () => Promise getAIVisionRuntimeConfig: () => Promise getAiSearchProviderStatus: () => Promise authorizeAiSearchExternalProvider: ( request: AiSearchExternalAuthorizationRequest ) => Promise saveAIProvider: (provider: AIProviderConfig) => Promise deleteAIProvider: (providerId: string) => Promise setDefaultAIProvider: (providerId: string) => Promise testAIProvider: (providerId: string) => Promise testAIVision: (request: AIVisionTestRequest) => Promise migrateLegacyAIConfig: (config: LegacyAIConfig) => Promise getTextToSpeechSettings: () => Promise saveTextToSpeechSettings: ( request: SaveTextToSpeechSettingsRequest ) => Promise listTextToSpeechVoices: ( request?: ListTextToSpeechVoicesRequest ) => Promise synthesizeTextToSpeech: ( request: SynthesizeTextToSpeechRequest ) => Promise removeGeneratedTextToSpeechAudio: ( filePath: string ) => Promise<{ success: boolean; error?: string }> openFishAudioApiKeys: () => Promise<{ success: boolean; error?: string }> copyImage: (base64String: string) => Promise<{ success: boolean; error?: string }> getVoiceData: ( sessionId: string, localId: number, createTime: number, svrId?: string | number ) => Promise<{ success: boolean; data?: string; error?: string }> showVoiceSourceContextMenu: ( reference: VoiceMessageReference ) => Promise<{ success: boolean; error?: string }> getVoiceModelStatus: () => Promise downloadVoiceModel: () => Promise cancelVoiceModelDownload: () => Promise<{ success: boolean }> removeVoiceModel: () => Promise openVoiceModelDirectory: () => Promise<{ success: boolean; error?: string }> recognizeVoice: ( reference: VoiceMessageReference, options?: { force?: boolean } ) => Promise getVoiceTranscriptSnapshot: ( reference: VoiceMessageReference ) => Promise cancelVoiceRecognition: (reference: VoiceMessageReference) => Promise<{ success: boolean }> getVoiceBatchPreflight: (request: VoiceBatchRequest) => Promise getVoiceBatchConversationSummaries: ( request: VoiceBatchRequest ) => Promise getVoiceBatchProgress: () => Promise startVoiceBatch: (request: VoiceBatchRequest) => Promise cancelVoiceBatch: () => Promise<{ success: boolean }> retryFailedVoiceBatch: () => Promise onVoiceBatchProgress: (callback: (progress: VoiceBatchProgress) => void) => () => void onVoiceModelProgress: (callback: (status: VoiceModelProgressEvent) => void) => () => void parseMessage: (content: string, messageType: number) => Promise getImage: ( imageMd5?: string, imageDatNameOrThumb?: string | boolean, sessionId?: string, options?: { force?: boolean preferThumbnail?: boolean priority?: number includeData?: boolean } ) => Promise<{ success: boolean data?: string error?: string isThumb?: boolean filePath?: string }> getVideo: ( hashes: string[], options?: { createTime?: number byteLength?: number duration?: number width?: number height?: number } ) => Promise<{ success: boolean; url?: string; poster?: string; error?: string }> getSticker: ( cdnUrl?: string, md5?: string ) => Promise<{ success: boolean data?: string error?: string failureCode?: import('../shared/sticker').StickerFailureCode httpStatus?: number }> startExport: (request: ExportRequest) => Promise selectExportDirectory: () => Promise<{ canceled: boolean; path?: string }> cancelExport: (jobId: string) => Promise<{ success: boolean }> revealExport: (path: string) => Promise<{ success: boolean; error?: string }> onExportProgress: (callback: (progress: ExportJobProgress) => void) => () => void exportGroupReport: (request: GroupReportExportRequest) => Promise exportGroupReportSnapshot: ( request: GroupReportRenderSnapshotExportRequest ) => Promise listReportTemplates: () => Promise installReportTemplate: (packagePath: string) => Promise uninstallReportTemplate: ( id: string, version: string ) => Promise listReportTemplateCatalog: () => Promise installReportTemplateFromCatalog: ( id: string, version: string ) => Promise prepareGeneratedReportTemplateSwitch: ( reportId: string ) => Promise listGeneratedReports: () => Promise saveGeneratedReport: ( request: SaveGeneratedReportRequest ) => Promise updateGeneratedReportTemplate: ( request: UpdateGeneratedReportTemplateRequest ) => Promise deleteGeneratedReport: (reportId: string) => Promise revealGroupReport: (filePath: string) => Promise<{ success: boolean; error?: string }> getWechatShareConfig: () => Promise saveWechatShareConfig: ( config: WechatShareServiceConfig ) => Promise publishWechatShareCard: ( request: PublishWechatShareCardRequest ) => Promise getSavedDbKey: (accountRoot: string) => Promise getDatabaseKeyEnvironment: () => Promise readDatabaseKeyClipboard: () => Promise<{ success: boolean value?: string error?: string }> installIntelMacKeyRuntime: () => Promise<{ success: boolean error?: string code?: string }> autoGetDbKey: ( accountRoot: string, options?: { save?: boolean } ) => Promise<{ success: boolean key?: string error?: string code?: string saved?: boolean warning?: string }> autoGetImageKey: (options?: { save?: boolean }) => Promise<{ success: boolean xorKey?: number aesKey?: string verified?: boolean error?: string imageXorKey?: string imageAesKey?: string settings?: { dbRoot: string apiEnabled: boolean apiHost: string apiPort: number imageKeyRoot: string ffmpegPath: string recallProtectionEnabled: boolean debugEnabled: boolean autoLogin: boolean autoLoginPreferenceSet: boolean appearanceTheme: 'system' | 'light' | 'dark' compactMode: boolean showStartupProgress: boolean ttsSelectedVoiceId: string ttsModel: import('../shared/text-to-speech').TextToSpeechModel windowsWechatPort: string reportImagePostfixText: string imageXorKey: string imageAesKey: string } }> getImageKeyConfig: () => Promise getImageDecryptionStatus: () => Promise selectImageDecoder: () => Promise getImageDecoderStatus: () => Promise openImageDecoderDownload: () => Promise<{ success: boolean; error?: string }> saveImageKeyConfig: (request: SaveImageKeyRequest) => Promise testImageDecryption: ( request: TestImageDecryptionRequest ) => Promise clearImageKeyConfig: () => Promise<{ success: boolean; error?: string }> pasteAndSaveDbKey: ( accountRoot: string ) => Promise<{ success: boolean; key?: string; error?: string }> saveDbKey: (accountRoot: string, key: string) => Promise clearSavedDbKey: (accountRoot: string) => Promise<{ success: boolean; error?: string }> onWcdbChange: (callback: (payload: { type: string; json: string }) => void) => () => void onDbKeyStatus: (callback: (payload: { message: string }) => void) => () => void onImageKeyStatus: (callback: (payload: { message: string }) => void) => () => void getSettings: () => Promise<{ settings: { dbRoot: string apiEnabled: boolean apiHost: string apiPort: number imageKeyRoot: string ffmpegPath: string recallProtectionEnabled: boolean debugEnabled: boolean autoLogin: boolean autoLoginPreferenceSet: boolean appearanceTheme: 'system' | 'light' | 'dark' compactMode: boolean showStartupProgress: boolean ttsSelectedVoiceId: string ttsModel: import('../shared/text-to-speech').TextToSpeechModel windowsWechatPort: string reportImagePostfixText: string imageXorKey: string imageAesKey: string } settingsPath: string }> setSettings: ( patch: Partial<{ dbRoot: string apiEnabled: boolean apiHost: string apiPort: number imageKeyRoot: string ffmpegPath: string recallProtectionEnabled: boolean debugEnabled: boolean autoLogin: boolean autoLoginPreferenceSet: boolean appearanceTheme: 'system' | 'light' | 'dark' compactMode: boolean showStartupProgress: boolean ttsSelectedVoiceId: string ttsModel: import('../shared/text-to-speech').TextToSpeechModel windowsWechatPort: string reportImagePostfixText: string imageXorKey: string imageAesKey: string }> ) => Promise<{ settings: { dbRoot: string apiEnabled: boolean apiHost: string apiPort: number imageKeyRoot: string ffmpegPath: string recallProtectionEnabled: boolean debugEnabled: boolean autoLogin: boolean autoLoginPreferenceSet: boolean appearanceTheme: 'system' | 'light' | 'dark' compactMode: boolean showStartupProgress: boolean windowsWechatPort: string imageXorKey: string imageAesKey: string } settingsPath: string }> getSelf: () => Promise< | { ready: true info: { wxid: string; nickname: string; avatar?: string; accountRoot: string } } | { ready: false } > testConnection: (key: string, accountRoot?: string) => Promise reopenWithRoot: (accountRoot: string) => Promise<{ success: boolean error?: string info?: { wxid: string; nickname: string; avatar?: string; accountRoot: string } }> selectDbRoot: () => Promise<{ canceled: boolean; path?: string }> openAccountRoot: () => Promise<{ success: boolean; error?: string }> disconnectDb: (options?: { closeNative?: boolean }) => Promise<{ success: boolean; error?: string }> apiStatus: () => Promise<{ running: boolean host: string port: number error?: string }> apiTokenStatus: () => Promise revealApiToken: () => Promise copyApiToken: () => Promise rotateApiToken: () => Promise apiStart: ( host?: string, port?: number ) => Promise<{ running: boolean; host: string; port: number; error?: string }> apiStop: () => Promise<{ running: boolean; host: string; port: number; error?: string }> apiToggle: (enabled: boolean) => Promise<{ running: boolean host: string port: number error?: string }> getReaderSkillStatus: () => Promise<{ available: boolean version?: string filePath?: string directoryPath?: string source: 'development' | 'bundled' githubUrl: string error?: string }> readReaderSkill: () => Promise<{ success: boolean; content?: string; error?: string }> revealReaderSkill: () => Promise<{ success: boolean; error?: string }> openReaderSkillGithub: () => Promise<{ success: boolean; error?: string }> testLocalApiRequest: (request: LocalApiTestRequest) => Promise copyLocalApiCurl: ( request: LocalApiTestRequest ) => Promise copyText: (text: string) => Promise<{ success: boolean; error?: string }> // ============================================================ // AI 图片理解基础设施(ImageInsightService) // ============================================================ imageListCandidates: (query: ImageCandidateQuery) => Promise<{ success: boolean candidates: ImageCandidate[] error?: string }> imageAnalyze: (request: ImageAnalysisRequest) => Promise getImageInsight: (imageHash: string) => Promise<{ success: boolean; insight?: ImageInsight }> listImageInsights: ( sessionId: string, limit?: number ) => Promise<{ success: boolean; insights: ImageInsight[] }> // 本地图片文字识别(System OCR,本地 Runtime,非 AI Provider) getSystemOcrCapability: () => Promise recognizeLocalImageText: (request: SystemOcrRequest) => Promise getImageTextIndexStatus: () => Promise countImageMessages: (sinceMs?: number) => Promise startImageTextIndex: ( options?: ImageTextIndexStartOptions ) => Promise<{ started: boolean; state: string }> pauseImageTextIndex: () => Promise<{ paused: boolean; state: string }> resumeImageTextIndex: ( options?: ImageTextIndexStartOptions ) => Promise<{ started: boolean; state: string }> cancelImageTextIndex: () => Promise<{ cancellable: boolean; cancelled: boolean }> clearImageTextIndex: () => Promise<{ removed: boolean; removedBytes: number }> resetImageTextIndexFailures: () => Promise<{ reset: number }> repairImageTextIndex: () => Promise onImageTextIndexStatus: (callback: (status: ImageTextIndexStatus) => void) => () => void getPersonalWechatSenderStatus: () => Promise getPersonalWechatSendCapability: () => Promise checkPersonalWechatSenderStatus: (port?: string) => Promise checkPersonalWechatVoiceEncodingEnvironment: () => Promise installPersonalWechatPilk: () => Promise openPersonalWechatVoicePythonDownload: () => Promise<{ success: boolean; error?: string }> openPersonalWechatVoiceFfmpegDownload: () => Promise<{ success: boolean; error?: string }> rebindPersonalWechatSender: () => Promise sendGeneratedTtsVoice: ( request: PersonalWechatGeneratedTtsVoiceRequest ) => Promise sendPersonalWechatMessage: ( request: PersonalWechatSendRequest ) => Promise /** 定时日报:「立即执行」——与 scheduler 走同一条执行链路(manual trigger)。 */ runScheduledReportRule: ( ruleId: string ) => Promise<{ success: boolean; error?: string; data?: ScheduledRuleRunOutcome }> /** 定时日报:旧执行记录**只读存档**(旧记录无法无损转换,原样展示)。 */ listScheduledReportLegacyExecutions: ( ruleId?: string ) => Promise /** 定时日报:微信异常通知开关与能力检测。 */ getScheduledReportNotificationSettings: () => Promise getScheduledReportNotificationCapability: () => Promise setScheduledReportNotificationEnabled: ( enabled: boolean ) => Promise testScheduledReportErrorNotification: ( ruleId: string ) => Promise> getPersonalWechatVoiceDiagnostic: () => Promise getAgentHubStatus: () => Promise getAgentHubLogs: () => Promise clearAgentHubLogs: () => Promise startAgentHubLogin: () => Promise cancelAgentHubLogin: () => Promise reconnectAgentHub: () => Promise disconnectAgentHub: () => Promise selectAgentHubTestImage: () => Promise<{ canceled: boolean; path?: string }> getAgentHubConversations: () => Promise getAgentHubConversation: (userId: string) => Promise clearAgentHubConversations: () => Promise<{ success: boolean }> onAgentHubConversation: ( callback: (payload: { summary: AgentHubConversationSummary message: AgentHubConversationMessage }) => void ) => () => void onAgentHubConversationsCleared: (callback: () => void) => () => void onAgentHubStatus: (callback: (status: AgentHubStatus) => void) => () => void onAgentHubLog: (callback: (entry: AgentHubLogEntry) => void) => () => void } } }