mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-21 07:40:11 +08:00
refactor[Logger]: replace console logging with logger service (#8271)
* refactor: replace console logging with logger service across multiple components - Updated various files to utilize the logger service instead of console.log for improved logging consistency and error tracking. - Enhanced logging levels to better categorize messages, including debug and error levels. - Refactored logging in components such as ApiClientFactory, KnowledgeService, and MemoryProcessor to align with the new logging standards. * refactor: update logging level in App component from error to info - Changed the logging level in the App component to provide a more appropriate context for initialization messages, enhancing clarity in the logging output. * refactor(logging): replace console.log with logger service in middleware and update ESLint comments - Updated the logging implementation in the createSimpleLoggingMiddleware function to use logger.debug and logger.error instead of console.log and console.error for improved logging consistency. - Added eslint-disable comments for restricted syntax in preload and useAppInit hooks to suppress warnings.
This commit is contained in:
parent
f9c5ca258a
commit
7764ffc8bb
@ -80,7 +80,6 @@ import { ChunkType } from '@renderer/types' // 调整路径
|
|||||||
|
|
||||||
export const createSimpleLoggingMiddleware = (): CompletionsMiddleware => {
|
export const createSimpleLoggingMiddleware = (): CompletionsMiddleware => {
|
||||||
return (api: MiddlewareAPI<AiProviderMiddlewareCompletionsContext, [CompletionsParams]>) => {
|
return (api: MiddlewareAPI<AiProviderMiddlewareCompletionsContext, [CompletionsParams]>) => {
|
||||||
// console.log(`[LoggingMiddleware] Initialized for provider: ${api.getProviderId()}`);
|
|
||||||
|
|
||||||
return (next: (context: AiProviderMiddlewareCompletionsContext, params: CompletionsParams) => Promise<any>) => {
|
return (next: (context: AiProviderMiddlewareCompletionsContext, params: CompletionsParams) => Promise<any>) => {
|
||||||
return async (context: AiProviderMiddlewareCompletionsContext, params: CompletionsParams): Promise<void> => {
|
return async (context: AiProviderMiddlewareCompletionsContext, params: CompletionsParams): Promise<void> => {
|
||||||
@ -88,7 +87,7 @@ export const createSimpleLoggingMiddleware = (): CompletionsMiddleware => {
|
|||||||
// 从 context 中获取 onChunk (它最初来自 params.onChunk)
|
// 从 context 中获取 onChunk (它最初来自 params.onChunk)
|
||||||
const onChunk = context.onChunk
|
const onChunk = context.onChunk
|
||||||
|
|
||||||
console.log(
|
logger.debug(
|
||||||
`[LoggingMiddleware] Request for ${context.methodName} with params:`,
|
`[LoggingMiddleware] Request for ${context.methodName} with params:`,
|
||||||
params.messages?.[params.messages.length - 1]?.content
|
params.messages?.[params.messages.length - 1]?.content
|
||||||
)
|
)
|
||||||
@ -104,14 +103,14 @@ export const createSimpleLoggingMiddleware = (): CompletionsMiddleware => {
|
|||||||
// 如果在之前,那么它需要自己处理 rawSdkResponse 或确保下游会处理。
|
// 如果在之前,那么它需要自己处理 rawSdkResponse 或确保下游会处理。
|
||||||
|
|
||||||
const duration = Date.now() - startTime
|
const duration = Date.now() - startTime
|
||||||
console.log(`[LoggingMiddleware] Request for ${context.methodName} completed in ${duration}ms.`)
|
logger.debug(`[LoggingMiddleware] Request for ${context.methodName} completed in ${duration}ms.`)
|
||||||
|
|
||||||
// 假设下游已经通过 onChunk 发送了所有数据。
|
// 假设下游已经通过 onChunk 发送了所有数据。
|
||||||
// 如果这个中间件是链的末端,并且需要确保 BLOCK_COMPLETE 被发送,
|
// 如果这个中间件是链的末端,并且需要确保 BLOCK_COMPLETE 被发送,
|
||||||
// 它可能需要更复杂的逻辑来跟踪何时所有数据都已发送。
|
// 它可能需要更复杂的逻辑来跟踪何时所有数据都已发送。
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const duration = Date.now() - startTime
|
const duration = Date.now() - startTime
|
||||||
console.error(`[LoggingMiddleware] Request for ${context.methodName} failed after ${duration}ms:`, error)
|
logger.error(`[LoggingMiddleware] Request for ${context.methodName} failed after ${duration}ms:`, error)
|
||||||
|
|
||||||
// 如果 onChunk 可用,可以尝试发送一个错误块
|
// 如果 onChunk 可用,可以尝试发送一个错误块
|
||||||
if (onChunk) {
|
if (onChunk) {
|
||||||
@ -207,7 +206,7 @@ export default middlewareConfig
|
|||||||
|
|
||||||
### 调试技巧
|
### 调试技巧
|
||||||
|
|
||||||
- 在中间件的关键点使用 `console.log` 或调试器来检查 `params`、`context` 的状态以及 `next` 的返回值。
|
- 在中间件的关键点使用 `logger.debug` 或调试器来检查 `params`、`context` 的状态以及 `next` 的返回值。
|
||||||
- 暂时简化中间件链,只保留你正在调试的中间件和最简单的核心逻辑,以隔离问题。
|
- 暂时简化中间件链,只保留你正在调试的中间件和最简单的核心逻辑,以隔离问题。
|
||||||
- 编写单元测试来独立验证每个中间件的行为。
|
- 编写单元测试来独立验证每个中间件的行为。
|
||||||
|
|
||||||
|
|||||||
@ -129,8 +129,8 @@ if (!app.requestSingleInstanceLock()) {
|
|||||||
|
|
||||||
if (isDev) {
|
if (isDev) {
|
||||||
installExtension([REDUX_DEVTOOLS, REACT_DEVELOPER_TOOLS])
|
installExtension([REDUX_DEVTOOLS, REACT_DEVELOPER_TOOLS])
|
||||||
.then((name) => console.log(`Added Extension: ${name}`))
|
.then((name) => logger.info(`Added Extension: ${name}`))
|
||||||
.catch((err) => console.log('An error occurred: ', err))
|
.catch((err) => logger.error('An error occurred: ', err))
|
||||||
}
|
}
|
||||||
|
|
||||||
//start selection assistant service
|
//start selection assistant service
|
||||||
|
|||||||
@ -205,9 +205,9 @@ export default class MineruPreprocessProvider extends BasePreprocessProvider {
|
|||||||
try {
|
try {
|
||||||
// 步骤1: 获取上传URL
|
// 步骤1: 获取上传URL
|
||||||
const { batchId, fileUrls } = await this.getBatchUploadUrls(file)
|
const { batchId, fileUrls } = await this.getBatchUploadUrls(file)
|
||||||
logger.info(`Got upload URLs for batch: ${batchId}`)
|
logger.debug(`Got upload URLs for batch: ${batchId}`)
|
||||||
|
|
||||||
console.log('batchId:', batchId, 'fileurls:', fileUrls)
|
logger.debug(`batchId: ${batchId}, fileurls: ${fileUrls}`)
|
||||||
// 步骤2: 上传文件到获取的URL
|
// 步骤2: 上传文件到获取的URL
|
||||||
await this.putFileToUrl(file.path, fileUrls[0])
|
await this.putFileToUrl(file.path, fileUrls[0])
|
||||||
logger.info(`File uploaded successfully: ${file.path}`)
|
logger.info(`File uploaded successfully: ${file.path}`)
|
||||||
|
|||||||
@ -57,7 +57,7 @@ class FileStorage {
|
|||||||
|
|
||||||
findDuplicateFile = async (filePath: string): Promise<FileMetadata | null> => {
|
findDuplicateFile = async (filePath: string): Promise<FileMetadata | null> => {
|
||||||
const stats = fs.statSync(filePath)
|
const stats = fs.statSync(filePath)
|
||||||
console.log('stats', stats, filePath)
|
logger.debug('stats', stats, filePath)
|
||||||
const fileSize = stats.size
|
const fileSize = stats.size
|
||||||
|
|
||||||
const files = await fs.promises.readdir(this.storageDir)
|
const files = await fs.promises.readdir(this.storageDir)
|
||||||
|
|||||||
@ -156,7 +156,7 @@ class KnowledgeService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public delete = async (_: Electron.IpcMainInvokeEvent, id: string): Promise<void> => {
|
public delete = async (_: Electron.IpcMainInvokeEvent, id: string): Promise<void> => {
|
||||||
console.log('id', id)
|
logger.debug('delete id', id)
|
||||||
const dbPath = path.join(this.storageDir, id)
|
const dbPath = path.join(this.storageDir, id)
|
||||||
if (fs.existsSync(dbPath)) {
|
if (fs.existsSync(dbPath)) {
|
||||||
fs.rmSync(dbPath, { recursive: true })
|
fs.rmSync(dbPath, { recursive: true })
|
||||||
|
|||||||
@ -622,7 +622,7 @@ class McpService {
|
|||||||
const client = await this.initClient(server)
|
const client = await this.initClient(server)
|
||||||
const result = await client.callTool({ name, arguments: args }, undefined, {
|
const result = await client.callTool({ name, arguments: args }, undefined, {
|
||||||
onprogress: (process) => {
|
onprogress: (process) => {
|
||||||
console.log('[MCP] Progress:', process.progress / (process.total || 1))
|
logger.debug(`Progress: ${process.progress / (process.total || 1)}`)
|
||||||
window.api.mcp.setProgress(process.progress / (process.total || 1))
|
window.api.mcp.setProgress(process.progress / (process.total || 1))
|
||||||
},
|
},
|
||||||
timeout: server.timeout ? server.timeout * 1000 : 60000, // Default timeout of 1 minute
|
timeout: server.timeout ? server.timeout * 1000 : 60000, // Default timeout of 1 minute
|
||||||
|
|||||||
@ -364,6 +364,7 @@ if (process.contextIsolated) {
|
|||||||
getFiles: (vaultName: string) => ipcRenderer.invoke(IpcChannel.Obsidian_GetFiles, vaultName)
|
getFiles: (vaultName: string) => ipcRenderer.invoke(IpcChannel.Obsidian_GetFiles, vaultName)
|
||||||
})
|
})
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
console.error(error)
|
console.error(error)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -26,7 +26,7 @@ import TranslatePage from './pages/translate/TranslatePage'
|
|||||||
const logger = loggerService.withContext('App.tsx')
|
const logger = loggerService.withContext('App.tsx')
|
||||||
|
|
||||||
function App(): React.ReactElement {
|
function App(): React.ReactElement {
|
||||||
logger.error('App initialized')
|
logger.info('App initialized')
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { loggerService } from '@logger'
|
||||||
import { Provider } from '@renderer/types'
|
import { Provider } from '@renderer/types'
|
||||||
|
|
||||||
import { AihubmixAPIClient } from './AihubmixAPIClient'
|
import { AihubmixAPIClient } from './AihubmixAPIClient'
|
||||||
@ -10,6 +11,8 @@ import { OpenAIAPIClient } from './openai/OpenAIApiClient'
|
|||||||
import { OpenAIResponseAPIClient } from './openai/OpenAIResponseAPIClient'
|
import { OpenAIResponseAPIClient } from './openai/OpenAIResponseAPIClient'
|
||||||
import { PPIOAPIClient } from './ppio/PPIOAPIClient'
|
import { PPIOAPIClient } from './ppio/PPIOAPIClient'
|
||||||
|
|
||||||
|
const logger = loggerService.withContext('ApiClientFactory')
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory for creating ApiClient instances based on provider configuration
|
* Factory for creating ApiClient instances based on provider configuration
|
||||||
* 根据提供者配置创建ApiClient实例的工厂
|
* 根据提供者配置创建ApiClient实例的工厂
|
||||||
@ -20,7 +23,7 @@ export class ApiClientFactory {
|
|||||||
* 为给定的提供者创建ApiClient实例
|
* 为给定的提供者创建ApiClient实例
|
||||||
*/
|
*/
|
||||||
static create(provider: Provider): BaseApiClient {
|
static create(provider: Provider): BaseApiClient {
|
||||||
console.log(`[ApiClientFactory] Creating ApiClient for provider:`, {
|
logger.debug(`Creating ApiClient for provider:`, {
|
||||||
id: provider.id,
|
id: provider.id,
|
||||||
type: provider.type
|
type: provider.type
|
||||||
})
|
})
|
||||||
@ -29,17 +32,17 @@ export class ApiClientFactory {
|
|||||||
|
|
||||||
// 首先检查特殊的provider id
|
// 首先检查特殊的provider id
|
||||||
if (provider.id === 'aihubmix') {
|
if (provider.id === 'aihubmix') {
|
||||||
console.log(`[ApiClientFactory] Creating AihubmixAPIClient for provider: ${provider.id}`)
|
logger.debug(`Creating AihubmixAPIClient for provider: ${provider.id}`)
|
||||||
instance = new AihubmixAPIClient(provider) as BaseApiClient
|
instance = new AihubmixAPIClient(provider) as BaseApiClient
|
||||||
return instance
|
return instance
|
||||||
}
|
}
|
||||||
if (provider.id === 'new-api') {
|
if (provider.id === 'new-api') {
|
||||||
console.log(`[ApiClientFactory] Creating NewAPIClient for provider: ${provider.id}`)
|
logger.debug(`Creating NewAPIClient for provider: ${provider.id}`)
|
||||||
instance = new NewAPIClient(provider) as BaseApiClient
|
instance = new NewAPIClient(provider) as BaseApiClient
|
||||||
return instance
|
return instance
|
||||||
}
|
}
|
||||||
if (provider.id === 'ppio') {
|
if (provider.id === 'ppio') {
|
||||||
console.log(`[ApiClientFactory] Creating PPIOAPIClient for provider: ${provider.id}`)
|
logger.debug(`Creating PPIOAPIClient for provider: ${provider.id}`)
|
||||||
instance = new PPIOAPIClient(provider) as BaseApiClient
|
instance = new PPIOAPIClient(provider) as BaseApiClient
|
||||||
return instance
|
return instance
|
||||||
}
|
}
|
||||||
@ -63,7 +66,7 @@ export class ApiClientFactory {
|
|||||||
instance = new AnthropicAPIClient(provider) as BaseApiClient
|
instance = new AnthropicAPIClient(provider) as BaseApiClient
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
console.log(`[ApiClientFactory] Using default OpenAIApiClient for provider: ${provider.id}`)
|
logger.debug(`Using default OpenAIApiClient for provider: ${provider.id}`)
|
||||||
instance = new OpenAIAPIClient(provider) as BaseApiClient
|
instance = new OpenAIAPIClient(provider) as BaseApiClient
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,12 @@
|
|||||||
|
import { loggerService } from '@logger'
|
||||||
import { Chunk } from '@renderer/types/chunk'
|
import { Chunk } from '@renderer/types/chunk'
|
||||||
|
|
||||||
import { CompletionsResult } from '../schemas'
|
import { CompletionsResult } from '../schemas'
|
||||||
import { CompletionsContext } from '../types'
|
import { CompletionsContext } from '../types'
|
||||||
import { createErrorChunk } from '../utils'
|
import { createErrorChunk } from '../utils'
|
||||||
|
|
||||||
|
const logger = loggerService.withContext('ErrorHandlerMiddleware')
|
||||||
|
|
||||||
export const MIDDLEWARE_NAME = 'ErrorHandlerMiddleware'
|
export const MIDDLEWARE_NAME = 'ErrorHandlerMiddleware'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -25,7 +28,7 @@ export const ErrorHandlerMiddleware =
|
|||||||
// 尝试执行下一个中间件
|
// 尝试执行下一个中间件
|
||||||
return await next(ctx, params)
|
return await next(ctx, params)
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.log('ErrorHandlerMiddleware_error', error)
|
logger.error('ErrorHandlerMiddleware_error', error)
|
||||||
// 1. 使用通用的工具函数将错误解析为标准格式
|
// 1. 使用通用的工具函数将错误解析为标准格式
|
||||||
const errorChunk = createErrorChunk(error)
|
const errorChunk = createErrorChunk(error)
|
||||||
// 2. 调用从外部传入的 onError 回调
|
// 2. 调用从外部传入的 onError 回调
|
||||||
|
|||||||
@ -1,9 +1,12 @@
|
|||||||
|
import { loggerService } from '@logger'
|
||||||
import { ChunkType } from '@renderer/types/chunk'
|
import { ChunkType } from '@renderer/types/chunk'
|
||||||
import { flushLinkConverterBuffer, smartLinkConverter } from '@renderer/utils/linkConverter'
|
import { flushLinkConverterBuffer, smartLinkConverter } from '@renderer/utils/linkConverter'
|
||||||
|
|
||||||
import { CompletionsParams, CompletionsResult, GenericChunk } from '../schemas'
|
import { CompletionsParams, CompletionsResult, GenericChunk } from '../schemas'
|
||||||
import { CompletionsContext, CompletionsMiddleware } from '../types'
|
import { CompletionsContext, CompletionsMiddleware } from '../types'
|
||||||
|
|
||||||
|
const logger = loggerService.withContext('WebSearchMiddleware')
|
||||||
|
|
||||||
export const MIDDLEWARE_NAME = 'WebSearchMiddleware'
|
export const MIDDLEWARE_NAME = 'WebSearchMiddleware'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -99,7 +102,7 @@ export const WebSearchMiddleware: CompletionsMiddleware =
|
|||||||
stream: enhancedStream
|
stream: enhancedStream
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log(`[${MIDDLEWARE_NAME}] No stream to process or not a ReadableStream.`)
|
logger.debug(`No stream to process or not a ReadableStream.`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,12 @@
|
|||||||
import { linter } from '@codemirror/lint' // statically imported by @uiw/codemirror-extensions-basic-setup
|
import { linter } from '@codemirror/lint' // statically imported by @uiw/codemirror-extensions-basic-setup
|
||||||
import { EditorView } from '@codemirror/view'
|
import { EditorView } from '@codemirror/view'
|
||||||
|
import { loggerService } from '@logger'
|
||||||
import { useCodeStyle } from '@renderer/context/CodeStyleProvider'
|
import { useCodeStyle } from '@renderer/context/CodeStyleProvider'
|
||||||
import { Extension, keymap } from '@uiw/react-codemirror'
|
import { Extension, keymap } from '@uiw/react-codemirror'
|
||||||
import { useEffect, useMemo, useState } from 'react'
|
import { useEffect, useMemo, useState } from 'react'
|
||||||
|
|
||||||
|
const logger = loggerService.withContext('CodeEditorHooks')
|
||||||
|
|
||||||
// 语言对应的 linter 加载器
|
// 语言对应的 linter 加载器
|
||||||
const linterLoaders: Record<string, () => Promise<any>> = {
|
const linterLoaders: Record<string, () => Promise<any>> = {
|
||||||
json: async () => {
|
json: async () => {
|
||||||
@ -39,7 +42,7 @@ async function loadLanguageExtension(language: string, languageMap: Record<strin
|
|||||||
try {
|
try {
|
||||||
return await specialLoader()
|
return await specialLoader()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.debug(`Failed to load language ${normalizedLang}`, error)
|
logger.debug(`Failed to load language ${normalizedLang}`, error)
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -50,7 +53,7 @@ async function loadLanguageExtension(language: string, languageMap: Record<strin
|
|||||||
const extension = loadLanguage(normalizedLang as any)
|
const extension = loadLanguage(normalizedLang as any)
|
||||||
return extension || null
|
return extension || null
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.debug(`Failed to load language ${normalizedLang}`, error)
|
logger.debug(`Failed to load language ${normalizedLang}`, error)
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -65,7 +68,7 @@ async function loadLinterExtension(language: string): Promise<Extension | null>
|
|||||||
try {
|
try {
|
||||||
return await loader()
|
return await loader()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.debug(`Failed to load linter for ${language}`, error)
|
logger.debug(`Failed to load linter for ${language}`, error)
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,7 +108,7 @@ export const useLanguageExtensions = (language: string, lint?: boolean) => {
|
|||||||
setExtensions(results)
|
setExtensions(results)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (!cancelled) {
|
if (!cancelled) {
|
||||||
console.debug('Failed to load language extensions:', error)
|
logger.debug('Failed to load language extensions:', error)
|
||||||
setExtensions([])
|
setExtensions([])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import {
|
|||||||
PushpinOutlined,
|
PushpinOutlined,
|
||||||
ReloadOutlined
|
ReloadOutlined
|
||||||
} from '@ant-design/icons'
|
} from '@ant-design/icons'
|
||||||
|
import { loggerService } from '@logger'
|
||||||
import { isLinux, isMac, isWin } from '@renderer/config/constant'
|
import { isLinux, isMac, isWin } from '@renderer/config/constant'
|
||||||
import { DEFAULT_MIN_APPS } from '@renderer/config/minapps'
|
import { DEFAULT_MIN_APPS } from '@renderer/config/minapps'
|
||||||
import { useBridge } from '@renderer/hooks/useBridge'
|
import { useBridge } from '@renderer/hooks/useBridge'
|
||||||
@ -31,6 +32,8 @@ import styled from 'styled-components'
|
|||||||
|
|
||||||
import WebviewContainer from './WebviewContainer'
|
import WebviewContainer from './WebviewContainer'
|
||||||
|
|
||||||
|
const logger = loggerService.withContext('MinappPopupContainer')
|
||||||
|
|
||||||
interface AppExtraInfo {
|
interface AppExtraInfo {
|
||||||
canPinned: boolean
|
canPinned: boolean
|
||||||
isPinned: boolean
|
isPinned: boolean
|
||||||
@ -296,7 +299,7 @@ const MinappPopupContainer: React.FC = () => {
|
|||||||
const handleWebviewNavigate = (appid: string, url: string) => {
|
const handleWebviewNavigate = (appid: string, url: string) => {
|
||||||
// 记录当前URL,用于GoogleLoginTip判断
|
// 记录当前URL,用于GoogleLoginTip判断
|
||||||
if (appid === currentMinappId) {
|
if (appid === currentMinappId) {
|
||||||
console.log('URL changed:', url)
|
logger.debug('URL changed:', url)
|
||||||
setCurrentUrl(url)
|
setCurrentUrl(url)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,6 +34,7 @@ export function useAppInit() {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
document.getElementById('spinner')?.remove()
|
document.getElementById('spinner')?.remove()
|
||||||
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
console.timeEnd('init')
|
console.timeEnd('init')
|
||||||
|
|
||||||
// Initialize MemoryService after app is ready
|
// Initialize MemoryService after app is ready
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { loggerService } from '@logger'
|
||||||
import { db } from '@renderer/databases'
|
import { db } from '@renderer/databases'
|
||||||
import KnowledgeQueue from '@renderer/queue/KnowledgeQueue'
|
import KnowledgeQueue from '@renderer/queue/KnowledgeQueue'
|
||||||
import { getKnowledgeBaseParams } from '@renderer/services/KnowledgeService'
|
import { getKnowledgeBaseParams } from '@renderer/services/KnowledgeService'
|
||||||
@ -26,6 +27,8 @@ import { v4 as uuidv4 } from 'uuid'
|
|||||||
import { useAgents } from './useAgents'
|
import { useAgents } from './useAgents'
|
||||||
import { useAssistants } from './useAssistant'
|
import { useAssistants } from './useAssistant'
|
||||||
|
|
||||||
|
const logger = loggerService.withContext('useKnowledge')
|
||||||
|
|
||||||
export const useKnowledge = (baseId: string) => {
|
export const useKnowledge = (baseId: string) => {
|
||||||
const dispatch = useDispatch()
|
const dispatch = useDispatch()
|
||||||
const base = useSelector((state: RootState) => state.knowledge.bases.find((b) => b.id === baseId))
|
const base = useSelector((state: RootState) => state.knowledge.bases.find((b) => b.id === baseId))
|
||||||
@ -53,7 +56,7 @@ export const useKnowledge = (baseId: string) => {
|
|||||||
processingError: '',
|
processingError: '',
|
||||||
retryCount: 0
|
retryCount: 0
|
||||||
}))
|
}))
|
||||||
console.log('Adding files:', filesItems)
|
logger.debug('Adding files:', filesItems)
|
||||||
dispatch(addFilesAction({ baseId, items: filesItems }))
|
dispatch(addFilesAction({ baseId, items: filesItems }))
|
||||||
setTimeout(() => KnowledgeQueue.checkAllBases(), 0)
|
setTimeout(() => KnowledgeQueue.checkAllBases(), 0)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { RedoOutlined } from '@ant-design/icons'
|
import { RedoOutlined } from '@ant-design/icons'
|
||||||
|
import { loggerService } from '@logger'
|
||||||
import CustomTag from '@renderer/components/CustomTag'
|
import CustomTag from '@renderer/components/CustomTag'
|
||||||
import { HStack } from '@renderer/components/Layout'
|
import { HStack } from '@renderer/components/Layout'
|
||||||
import { useKnowledge } from '@renderer/hooks/useKnowledge'
|
import { useKnowledge } from '@renderer/hooks/useKnowledge'
|
||||||
@ -20,6 +21,7 @@ import KnowledgeNotes from './items/KnowledgeNotes'
|
|||||||
import KnowledgeSitemaps from './items/KnowledgeSitemaps'
|
import KnowledgeSitemaps from './items/KnowledgeSitemaps'
|
||||||
import KnowledgeUrls from './items/KnowledgeUrls'
|
import KnowledgeUrls from './items/KnowledgeUrls'
|
||||||
|
|
||||||
|
const logger = loggerService.withContext('KnowledgeContent')
|
||||||
interface KnowledgeContentProps {
|
interface KnowledgeContentProps {
|
||||||
selectedBase: KnowledgeBase
|
selectedBase: KnowledgeBase
|
||||||
}
|
}
|
||||||
@ -52,7 +54,7 @@ const KnowledgeContent: FC<KnowledgeContentProps> = ({ selectedBase }) => {
|
|||||||
}),
|
}),
|
||||||
|
|
||||||
window.electron.ipcRenderer.on('directory-processing-percent', (_, { itemId, percent }) => {
|
window.electron.ipcRenderer.on('directory-processing-percent', (_, { itemId, percent }) => {
|
||||||
console.log('[Progress] Directory:', itemId, percent)
|
logger.debug('[Progress] Directory:', itemId, percent)
|
||||||
setProgressMap((prev) => new Map(prev).set(itemId, percent))
|
setProgressMap((prev) => new Map(prev).set(itemId, percent))
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
|
|||||||
@ -17,6 +17,7 @@ import { useState } from 'react'
|
|||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
|
|
||||||
|
const logger = loggerService.withContext('KnowledgeSettings')
|
||||||
interface ShowParams {
|
interface ShowParams {
|
||||||
base: KnowledgeBase
|
base: KnowledgeBase
|
||||||
}
|
}
|
||||||
@ -25,8 +26,6 @@ interface Props extends ShowParams {
|
|||||||
resolve: (data: any) => void
|
resolve: (data: any) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const logger = loggerService.withContext('KnowledgeSettings')
|
|
||||||
|
|
||||||
const PopupContainer: React.FC<Props> = ({ base: _base, resolve }) => {
|
const PopupContainer: React.FC<Props> = ({ base: _base, resolve }) => {
|
||||||
const { preprocessProviders } = usePreprocessProviders()
|
const { preprocessProviders } = usePreprocessProviders()
|
||||||
const { ocrProviders } = useOcrProviders()
|
const { ocrProviders } = useOcrProviders()
|
||||||
@ -96,7 +95,7 @@ const PopupContainer: React.FC<Props> = ({ base: _base, resolve }) => {
|
|||||||
|
|
||||||
const onOk = async () => {
|
const onOk = async () => {
|
||||||
try {
|
try {
|
||||||
console.log('newbase', newBase)
|
logger.debug('newbase', newBase)
|
||||||
updateKnowledgeBase(newBase)
|
updateKnowledgeBase(newBase)
|
||||||
setOpen(false)
|
setOpen(false)
|
||||||
resolve(newBase)
|
resolve(newBase)
|
||||||
|
|||||||
@ -1,10 +1,12 @@
|
|||||||
import { CheckCircleOutlined, CloseCircleOutlined } from '@ant-design/icons'
|
import { CheckCircleOutlined, CloseCircleOutlined } from '@ant-design/icons'
|
||||||
|
import { loggerService } from '@logger'
|
||||||
import { KnowledgeBase, ProcessingStatus } from '@renderer/types'
|
import { KnowledgeBase, ProcessingStatus } from '@renderer/types'
|
||||||
import { Progress, Tooltip } from 'antd'
|
import { Progress, Tooltip } from 'antd'
|
||||||
import React, { FC, useMemo } from 'react'
|
import React, { FC, useMemo } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
|
|
||||||
|
const logger = loggerService.withContext('StatusIcon')
|
||||||
interface StatusIconProps {
|
interface StatusIconProps {
|
||||||
sourceId: string
|
sourceId: string
|
||||||
base: KnowledgeBase
|
base: KnowledgeBase
|
||||||
@ -26,7 +28,7 @@ const StatusIcon: FC<StatusIconProps> = ({
|
|||||||
const status = getProcessingStatus(sourceId)
|
const status = getProcessingStatus(sourceId)
|
||||||
const item = base.items.find((item) => item.id === sourceId)
|
const item = base.items.find((item) => item.id === sourceId)
|
||||||
const errorText = item?.processingError
|
const errorText = item?.processingError
|
||||||
console.log('[StatusIcon] Rendering for item:', item?.id, 'Status:', status, 'Progress:', progress)
|
logger.debug('[StatusIcon] Rendering for item:', item?.id, 'Status:', status, 'Progress:', progress)
|
||||||
|
|
||||||
return useMemo(() => {
|
return useMemo(() => {
|
||||||
if (!status) {
|
if (!status) {
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { DeleteOutlined } from '@ant-design/icons'
|
import { DeleteOutlined } from '@ant-design/icons'
|
||||||
|
import { loggerService } from '@logger'
|
||||||
import Ellipsis from '@renderer/components/Ellipsis'
|
import Ellipsis from '@renderer/components/Ellipsis'
|
||||||
import { useKnowledge } from '@renderer/hooks/useKnowledge'
|
import { useKnowledge } from '@renderer/hooks/useKnowledge'
|
||||||
import FileItem from '@renderer/pages/files/FileItem'
|
import FileItem from '@renderer/pages/files/FileItem'
|
||||||
@ -16,6 +17,8 @@ import { FC, useEffect, useState } from 'react'
|
|||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
|
|
||||||
|
const logger = loggerService.withContext('KnowledgeFiles')
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ClickableSpan,
|
ClickableSpan,
|
||||||
FlexAlignCenter,
|
FlexAlignCenter,
|
||||||
@ -113,7 +116,7 @@ const KnowledgeFiles: FC<KnowledgeContentProps> = ({ selectedBase, progressMap,
|
|||||||
})
|
})
|
||||||
.filter(({ ext }) => fileTypes.includes(ext))
|
.filter(({ ext }) => fileTypes.includes(ext))
|
||||||
const uploadedFiles = await FileManager.uploadFiles(_files)
|
const uploadedFiles = await FileManager.uploadFiles(_files)
|
||||||
console.log('uploadedFiles', uploadedFiles)
|
logger.debug('uploadedFiles', uploadedFiles)
|
||||||
addFiles(uploadedFiles)
|
addFiles(uploadedFiles)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -338,7 +338,7 @@ const MemoriesPage = () => {
|
|||||||
const loadMemories = useCallback(
|
const loadMemories = useCallback(
|
||||||
async (userId?: string) => {
|
async (userId?: string) => {
|
||||||
const targetUser = userId || currentUser
|
const targetUser = userId || currentUser
|
||||||
console.log('Loading all memories for user:', targetUser)
|
logger.debug('Loading all memories for user:', targetUser)
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
try {
|
try {
|
||||||
// First, ensure the memory service is using the correct user
|
// First, ensure the memory service is using the correct user
|
||||||
@ -349,7 +349,7 @@ const MemoriesPage = () => {
|
|||||||
|
|
||||||
// Get all memories for current user context (load up to 10000)
|
// Get all memories for current user context (load up to 10000)
|
||||||
const result = await memoryService.list({ limit: 10000, offset: 0 })
|
const result = await memoryService.list({ limit: 10000, offset: 0 })
|
||||||
console.log('Loaded memories for user:', targetUser, 'count:', result.results?.length || 0)
|
logger.debug('Loaded memories for user:', targetUser, 'count:', result.results?.length || 0)
|
||||||
setAllMemories(result.results || [])
|
setAllMemories(result.results || [])
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error('Failed to load memories:', error)
|
logger.error('Failed to load memories:', error)
|
||||||
@ -363,7 +363,7 @@ const MemoriesPage = () => {
|
|||||||
|
|
||||||
// Sync memoryService with Redux store on mount and when currentUser changes
|
// Sync memoryService with Redux store on mount and when currentUser changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log('useEffect triggered for currentUser:', currentUser)
|
logger.debug('useEffect triggered for currentUser:', currentUser)
|
||||||
// Reset to first page when user changes
|
// Reset to first page when user changes
|
||||||
setCurrentPage(1)
|
setCurrentPage(1)
|
||||||
loadMemories(currentUser)
|
loadMemories(currentUser)
|
||||||
@ -453,7 +453,7 @@ const MemoriesPage = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleUserSwitch = async (userId: string) => {
|
const handleUserSwitch = async (userId: string) => {
|
||||||
console.log('Switching to user:', userId)
|
logger.debug('Switching to user:', userId)
|
||||||
|
|
||||||
// First update Redux state
|
// First update Redux state
|
||||||
dispatch(setCurrentUserId(userId))
|
dispatch(setCurrentUserId(userId))
|
||||||
|
|||||||
@ -207,7 +207,7 @@ const AihubmixPage: FC<{ Options: string[] }> = ({ Options }) => {
|
|||||||
|
|
||||||
// 确保渲染速度参数正确传递
|
// 确保渲染速度参数正确传递
|
||||||
const renderSpeed = painting.renderingSpeed || 'DEFAULT'
|
const renderSpeed = painting.renderingSpeed || 'DEFAULT'
|
||||||
console.log('使用渲染速度:', renderSpeed)
|
logger.silly(`使用渲染速度: ${renderSpeed}`)
|
||||||
formData.append('rendering_speed', renderSpeed)
|
formData.append('rendering_speed', renderSpeed)
|
||||||
|
|
||||||
formData.append('num_images', String(painting.numImages || 1))
|
formData.append('num_images', String(painting.numImages || 1))
|
||||||
@ -215,7 +215,7 @@ const AihubmixPage: FC<{ Options: string[] }> = ({ Options }) => {
|
|||||||
// Convert aspect ratio format from ASPECT_1_1 to 1x1 for V3 API
|
// Convert aspect ratio format from ASPECT_1_1 to 1x1 for V3 API
|
||||||
if (painting.aspectRatio) {
|
if (painting.aspectRatio) {
|
||||||
const aspectRatioValue = painting.aspectRatio.replace('ASPECT_', '').replace('_', 'x').toLowerCase()
|
const aspectRatioValue = painting.aspectRatio.replace('ASPECT_', '').replace('_', 'x').toLowerCase()
|
||||||
console.log('转换后的宽高比:', aspectRatioValue)
|
logger.silly(`转换后的宽高比: ${aspectRatioValue}`)
|
||||||
formData.append('aspect_ratio', aspectRatioValue)
|
formData.append('aspect_ratio', aspectRatioValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,39 +223,39 @@ const AihubmixPage: FC<{ Options: string[] }> = ({ Options }) => {
|
|||||||
// 确保样式类型与API文档一致,保持大写形式
|
// 确保样式类型与API文档一致,保持大写形式
|
||||||
// V3 API支持的样式类型: AUTO, GENERAL, REALISTIC, DESIGN
|
// V3 API支持的样式类型: AUTO, GENERAL, REALISTIC, DESIGN
|
||||||
const styleType = painting.styleType
|
const styleType = painting.styleType
|
||||||
console.log('使用样式类型:', styleType)
|
logger.silly(`使用样式类型: ${styleType}`)
|
||||||
formData.append('style_type', styleType)
|
formData.append('style_type', styleType)
|
||||||
} else {
|
} else {
|
||||||
// 确保明确设置默认样式类型
|
// 确保明确设置默认样式类型
|
||||||
console.log('使用默认样式类型: AUTO')
|
logger.silly('使用默认样式类型: AUTO')
|
||||||
formData.append('style_type', 'AUTO')
|
formData.append('style_type', 'AUTO')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (painting.seed) {
|
if (painting.seed) {
|
||||||
console.log('使用随机种子:', painting.seed)
|
logger.silly(`使用随机种子: ${painting.seed}`)
|
||||||
formData.append('seed', painting.seed)
|
formData.append('seed', painting.seed)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (painting.negativePrompt) {
|
if (painting.negativePrompt) {
|
||||||
console.log('使用负面提示词:', painting.negativePrompt)
|
logger.silly(`使用负面提示词: ${painting.negativePrompt}`)
|
||||||
formData.append('negative_prompt', painting.negativePrompt)
|
formData.append('negative_prompt', painting.negativePrompt)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (painting.magicPromptOption !== undefined) {
|
if (painting.magicPromptOption !== undefined) {
|
||||||
const magicPrompt = painting.magicPromptOption ? 'ON' : 'OFF'
|
const magicPrompt = painting.magicPromptOption ? 'ON' : 'OFF'
|
||||||
console.log('使用魔法提示词:', magicPrompt)
|
logger.silly(`使用魔法提示词: ${magicPrompt}`)
|
||||||
formData.append('magic_prompt', magicPrompt)
|
formData.append('magic_prompt', magicPrompt)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 打印所有FormData内容
|
// 打印所有FormData内容
|
||||||
console.log('FormData内容:')
|
logger.silly('FormData内容:')
|
||||||
for (const pair of formData.entries()) {
|
for (const pair of formData.entries()) {
|
||||||
console.log(pair[0] + ': ' + pair[1])
|
logger.silly(`${pair[0]}: ${pair[1]}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
body = formData
|
body = formData
|
||||||
// For V3 endpoints - 使用模板字符串而不是字符串连接
|
// For V3 endpoints - 使用模板字符串而不是字符串连接
|
||||||
console.log('API 端点:', `${aihubmixProvider.apiHost}/ideogram/v1/ideogram-v3/generate`)
|
logger.silly(`API 端点: ${aihubmixProvider.apiHost}/ideogram/v1/ideogram-v3/generate`)
|
||||||
|
|
||||||
// 调整请求头,可能需要指定multipart/form-data
|
// 调整请求头,可能需要指定multipart/form-data
|
||||||
// 注意:FormData会自动设置Content-Type,不应手动设置
|
// 注意:FormData会自动设置Content-Type,不应手动设置
|
||||||
@ -275,7 +275,7 @@ const AihubmixPage: FC<{ Options: string[] }> = ({ Options }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const data = await response.json()
|
const data = await response.json()
|
||||||
console.log('V3 API响应:', data)
|
logger.silly(`V3 API响应: ${data}`)
|
||||||
const urls = data.data.map((item) => item.url)
|
const urls = data.data.map((item) => item.url)
|
||||||
|
|
||||||
if (urls.length > 0) {
|
if (urls.length > 0) {
|
||||||
@ -391,7 +391,7 @@ const AihubmixPage: FC<{ Options: string[] }> = ({ Options }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const data = await response.json()
|
const data = await response.json()
|
||||||
console.log('V3 Remix API响应:', data)
|
logger.silly(`V3 Remix API响应: ${data}`)
|
||||||
const urls = data.data.map((item) => item.url)
|
const urls = data.data.map((item) => item.url)
|
||||||
|
|
||||||
// Handle the downloaded images
|
// Handle the downloaded images
|
||||||
@ -461,7 +461,7 @@ const AihubmixPage: FC<{ Options: string[] }> = ({ Options }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const data = await response.json()
|
const data = await response.json()
|
||||||
console.log('通用API响应:', data)
|
logger.silly(`通用API响应: ${data}`)
|
||||||
const urls = data.data.filter((item) => item.url).map((item) => item.url)
|
const urls = data.data.filter((item) => item.url).map((item) => item.url)
|
||||||
const base64s = data.data.filter((item) => item.b64_json).map((item) => item.b64_json)
|
const base64s = data.data.filter((item) => item.b64_json).map((item) => item.b64_json)
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { loggerService } from '@logger'
|
||||||
import { useAppDispatch } from '@renderer/store'
|
import { useAppDispatch } from '@renderer/store'
|
||||||
import { setDefaultPaintingProvider } from '@renderer/store/settings'
|
import { setDefaultPaintingProvider } from '@renderer/store/settings'
|
||||||
import { PaintingProvider } from '@renderer/types'
|
import { PaintingProvider } from '@renderer/types'
|
||||||
@ -10,6 +11,8 @@ import NewApiPage from './NewApiPage'
|
|||||||
import SiliconPage from './SiliconPage'
|
import SiliconPage from './SiliconPage'
|
||||||
import TokenFluxPage from './TokenFluxPage'
|
import TokenFluxPage from './TokenFluxPage'
|
||||||
|
|
||||||
|
const logger = loggerService.withContext('PaintingsRoutePage')
|
||||||
|
|
||||||
const Options = ['aihubmix', 'silicon', 'dmxapi', 'tokenflux', 'new-api']
|
const Options = ['aihubmix', 'silicon', 'dmxapi', 'tokenflux', 'new-api']
|
||||||
|
|
||||||
const PaintingsRoutePage: FC = () => {
|
const PaintingsRoutePage: FC = () => {
|
||||||
@ -18,7 +21,7 @@ const PaintingsRoutePage: FC = () => {
|
|||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.debug('defaultPaintingProvider', provider)
|
logger.debug('defaultPaintingProvider', provider)
|
||||||
if (provider && Options.includes(provider)) {
|
if (provider && Options.includes(provider)) {
|
||||||
dispatch(setDefaultPaintingProvider(provider as PaintingProvider))
|
dispatch(setDefaultPaintingProvider(provider as PaintingProvider))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -125,7 +125,7 @@ export const syncTokenLanYunServers = async (
|
|||||||
|
|
||||||
// Transform Token servers to MCP servers format
|
// Transform Token servers to MCP servers format
|
||||||
const addedServers: MCPServer[] = []
|
const addedServers: MCPServer[] = []
|
||||||
console.log('TokenLanYun servers:', servers)
|
logger.debug('TokenLanYun servers:', servers)
|
||||||
for (const server of servers) {
|
for (const server of servers) {
|
||||||
try {
|
try {
|
||||||
if (!server.operationalUrls?.[0]?.url) continue
|
if (!server.operationalUrls?.[0]?.url) continue
|
||||||
|
|||||||
@ -370,7 +370,7 @@ export async function fetchChatCompletion({
|
|||||||
// TODO
|
// TODO
|
||||||
// onChunkStatus: (status: 'searching' | 'processing' | 'success' | 'error') => void
|
// onChunkStatus: (status: 'searching' | 'processing' | 'success' | 'error') => void
|
||||||
}) {
|
}) {
|
||||||
console.log('fetchChatCompletion', messages, assistant)
|
logger.debug('fetchChatCompletion', messages, assistant)
|
||||||
|
|
||||||
const provider = getAssistantProvider(assistant)
|
const provider = getAssistantProvider(assistant)
|
||||||
const AI = new AiProvider(provider)
|
const AI = new AiProvider(provider)
|
||||||
@ -518,12 +518,12 @@ async function processConversationMemory(messages: Message[], assistant: Assista
|
|||||||
memoryProcessor
|
memoryProcessor
|
||||||
.processConversation(conversationMessages, processorConfig)
|
.processConversation(conversationMessages, processorConfig)
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
console.log('Memory processing completed:', result)
|
logger.debug('Memory processing completed:', result)
|
||||||
if (result.facts.length > 0) {
|
if (result.facts.length > 0) {
|
||||||
console.log('Extracted facts from conversation:', result.facts)
|
logger.debug('Extracted facts from conversation:', result.facts)
|
||||||
console.log('Memory operations performed:', result.operations)
|
logger.debug('Memory operations performed:', result.operations)
|
||||||
} else {
|
} else {
|
||||||
console.log('No facts extracted from conversation')
|
logger.debug('No facts extracted from conversation')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
|
|||||||
@ -61,7 +61,7 @@ export const getKnowledgeBaseParams = (base: KnowledgeBase): KnowledgeBaseParams
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const getFileFromUrl = async (url: string): Promise<FileMetadata | null> => {
|
export const getFileFromUrl = async (url: string): Promise<FileMetadata | null> => {
|
||||||
console.log('getFileFromUrl', url)
|
logger.debug('getFileFromUrl', url)
|
||||||
let fileName = ''
|
let fileName = ''
|
||||||
|
|
||||||
if (url && url.includes('CherryStudio')) {
|
if (url && url.includes('CherryStudio')) {
|
||||||
@ -73,10 +73,10 @@ export const getFileFromUrl = async (url: string): Promise<FileMetadata | null>
|
|||||||
fileName = url.split('\\Data\\Files\\')[1]
|
fileName = url.split('\\Data\\Files\\')[1]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log('fileName', fileName)
|
logger.debug('fileName', fileName)
|
||||||
if (fileName) {
|
if (fileName) {
|
||||||
const actualFileName = fileName.split(/[/\\]/).pop() || fileName
|
const actualFileName = fileName.split(/[/\\]/).pop() || fileName
|
||||||
console.log('actualFileName', actualFileName)
|
logger.debug('actualFileName', actualFileName)
|
||||||
const fileId = actualFileName.split('.')[0]
|
const fileId = actualFileName.split('.')[0]
|
||||||
const file = await FileManager.getFile(fileId)
|
const file = await FileManager.getFile(fileId)
|
||||||
if (file) {
|
if (file) {
|
||||||
@ -135,7 +135,7 @@ export const searchKnowledgeBase = async (
|
|||||||
return await Promise.all(
|
return await Promise.all(
|
||||||
limitedResults.map(async (item) => {
|
limitedResults.map(async (item) => {
|
||||||
const file = await getFileFromUrl(item.metadata.source)
|
const file = await getFileFromUrl(item.metadata.source)
|
||||||
console.log('Knowledge search item:', item, 'File:', file)
|
logger.debug('Knowledge search item:', item, 'File:', file)
|
||||||
return { ...item, file }
|
return { ...item, file }
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|||||||
@ -238,7 +238,7 @@ export class MemoryProcessor {
|
|||||||
limit
|
limit
|
||||||
})
|
})
|
||||||
|
|
||||||
console.log(
|
logger.debug(
|
||||||
'Searching memories with query:',
|
'Searching memories with query:',
|
||||||
query,
|
query,
|
||||||
'for user:',
|
'for user:',
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { loggerService } from '@logger'
|
||||||
import { autoRenameTopic } from '@renderer/hooks/useTopic'
|
import { autoRenameTopic } from '@renderer/hooks/useTopic'
|
||||||
import i18n from '@renderer/i18n'
|
import i18n from '@renderer/i18n'
|
||||||
import { EVENT_NAMES, EventEmitter } from '@renderer/services/EventService'
|
import { EVENT_NAMES, EventEmitter } from '@renderer/services/EventService'
|
||||||
@ -21,6 +22,7 @@ import { isFocused, isOnHomePage } from '@renderer/utils/window'
|
|||||||
|
|
||||||
import { BlockManager } from '../BlockManager'
|
import { BlockManager } from '../BlockManager'
|
||||||
|
|
||||||
|
const logger = loggerService.withContext('BaseCallbacks')
|
||||||
interface BaseCallbacksDependencies {
|
interface BaseCallbacksDependencies {
|
||||||
blockManager: BlockManager
|
blockManager: BlockManager
|
||||||
dispatch: any
|
dispatch: any
|
||||||
@ -68,7 +70,7 @@ export const createBaseCallbacks = (deps: BaseCallbacksDependencies) => {
|
|||||||
},
|
},
|
||||||
|
|
||||||
onError: async (error: any) => {
|
onError: async (error: any) => {
|
||||||
console.dir(error, { depth: null })
|
logger.debug('onError', error)
|
||||||
const isErrorTypeAbort = isAbortError(error)
|
const isErrorTypeAbort = isAbortError(error)
|
||||||
let pauseErrorLanguagePlaceholder = ''
|
let pauseErrorLanguagePlaceholder = ''
|
||||||
if (isErrorTypeAbort) {
|
if (isErrorTypeAbort) {
|
||||||
|
|||||||
@ -43,9 +43,9 @@ export const createCitationCallbacks = (deps: CitationCallbacksDependencies) =>
|
|||||||
onLLMWebSearchInProgress: async () => {
|
onLLMWebSearchInProgress: async () => {
|
||||||
if (blockManager.hasInitialPlaceholder) {
|
if (blockManager.hasInitialPlaceholder) {
|
||||||
// blockManager.lastBlockType = MessageBlockType.CITATION
|
// blockManager.lastBlockType = MessageBlockType.CITATION
|
||||||
console.log('blockManager.initialPlaceholderBlockId', blockManager.initialPlaceholderBlockId)
|
logger.debug('blockManager.initialPlaceholderBlockId', blockManager.initialPlaceholderBlockId)
|
||||||
citationBlockId = blockManager.initialPlaceholderBlockId!
|
citationBlockId = blockManager.initialPlaceholderBlockId!
|
||||||
console.log('citationBlockId', citationBlockId)
|
logger.debug('citationBlockId', citationBlockId)
|
||||||
|
|
||||||
const changes = {
|
const changes = {
|
||||||
type: MessageBlockType.CITATION,
|
type: MessageBlockType.CITATION,
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
|
import { loggerService } from '@logger'
|
||||||
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
|
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
|
||||||
import FileManager from '@renderer/services/FileManager'
|
import FileManager from '@renderer/services/FileManager'
|
||||||
import { FileMetadata, KnowledgeBase, KnowledgeItem, ProcessingStatus } from '@renderer/types'
|
import { FileMetadata, KnowledgeBase, KnowledgeItem, ProcessingStatus } from '@renderer/types'
|
||||||
|
|
||||||
|
const logger = loggerService.withContext('Store:Knowledge')
|
||||||
|
|
||||||
export interface KnowledgeState {
|
export interface KnowledgeState {
|
||||||
bases: KnowledgeBase[]
|
bases: KnowledgeBase[]
|
||||||
}
|
}
|
||||||
@ -176,7 +179,7 @@ const knowledgeSlice = createSlice({
|
|||||||
action: PayloadAction<{ baseId: string; itemId: string; uniqueId: string; uniqueIds: string[] }>
|
action: PayloadAction<{ baseId: string; itemId: string; uniqueId: string; uniqueIds: string[] }>
|
||||||
) {
|
) {
|
||||||
const base = state.bases.find((b) => b.id === action.payload.baseId)
|
const base = state.bases.find((b) => b.id === action.payload.baseId)
|
||||||
console.log('base2', base)
|
logger.silly('base2', base)
|
||||||
if (base) {
|
if (base) {
|
||||||
const item = base.items.find((item) => item.id === action.payload.itemId)
|
const item = base.items.find((item) => item.id === action.payload.itemId)
|
||||||
if (item) {
|
if (item) {
|
||||||
@ -191,10 +194,10 @@ const knowledgeSlice = createSlice({
|
|||||||
action: PayloadAction<{ baseId: string; itemId: string; isPreprocessed: boolean }>
|
action: PayloadAction<{ baseId: string; itemId: string; isPreprocessed: boolean }>
|
||||||
) {
|
) {
|
||||||
const base = state.bases.find((b) => b.id === action.payload.baseId)
|
const base = state.bases.find((b) => b.id === action.payload.baseId)
|
||||||
console.log('base', base)
|
logger.silly('base', base)
|
||||||
if (base) {
|
if (base) {
|
||||||
const item = base.items.find((item) => item.id === action.payload.itemId)
|
const item = base.items.find((item) => item.id === action.payload.itemId)
|
||||||
console.log('item', item)
|
logger.silly('item', item)
|
||||||
if (item) {
|
if (item) {
|
||||||
item.isPreprocessed = action.payload.isPreprocessed
|
item.isPreprocessed = action.payload.isPreprocessed
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { loggerService } from '@logger'
|
||||||
import { BundledLanguage, BundledTheme } from 'shiki/bundle/web'
|
import { BundledLanguage, BundledTheme } from 'shiki/bundle/web'
|
||||||
import { getTokenStyleObject, type HighlighterGeneric, SpecialLanguage, ThemedToken } from 'shiki/core'
|
import { getTokenStyleObject, type HighlighterGeneric, SpecialLanguage, ThemedToken } from 'shiki/core'
|
||||||
|
|
||||||
@ -6,6 +7,8 @@ import { AsyncInitializer } from './asyncInitializer'
|
|||||||
export const DEFAULT_LANGUAGES = ['javascript', 'typescript', 'python', 'java', 'markdown', 'json']
|
export const DEFAULT_LANGUAGES = ['javascript', 'typescript', 'python', 'java', 'markdown', 'json']
|
||||||
export const DEFAULT_THEMES = ['one-light', 'material-theme-darker']
|
export const DEFAULT_THEMES = ['one-light', 'material-theme-darker']
|
||||||
|
|
||||||
|
const logger = loggerService.withContext('Shiki')
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* shiki 初始化器,避免并发问题
|
* shiki 初始化器,避免并发问题
|
||||||
*/
|
*/
|
||||||
@ -87,7 +90,7 @@ export async function loadThemeIfNeeded(highlighter: HighlighterGeneric<any, any
|
|||||||
await highlighter.loadTheme(themeData)
|
await highlighter.loadTheme(themeData)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// 回退到 one-light
|
// 回退到 one-light
|
||||||
console.debug(`Failed to load theme '${theme}', falling back to 'one-light':`, error)
|
logger.debug(`Failed to load theme '${theme}', falling back to 'one-light':`, error)
|
||||||
const oneLightTheme = await shiki.bundledThemes['one-light']()
|
const oneLightTheme = await shiki.bundledThemes['one-light']()
|
||||||
await highlighter.loadTheme(oneLightTheme)
|
await highlighter.loadTheme(oneLightTheme)
|
||||||
loadedTheme = 'one-light'
|
loadedTheme = 'one-light'
|
||||||
@ -153,7 +156,7 @@ export async function getMarkdownIt(theme: string, markdown: string) {
|
|||||||
try {
|
try {
|
||||||
actualTheme = await loadThemeIfNeeded(highlighter, theme)
|
actualTheme = await loadThemeIfNeeded(highlighter, theme)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.debug(`Failed to load theme '${theme}', using 'one-light' as fallback:`, error)
|
logger.debug(`Failed to load theme '${theme}', using 'one-light' as fallback:`, error)
|
||||||
actualTheme = 'one-light'
|
actualTheme = 'one-light'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
/// <reference lib="webworker" />
|
/// <reference lib="webworker" />
|
||||||
|
|
||||||
|
import { loggerService } from '@logger'
|
||||||
|
|
||||||
|
const logger = loggerService.withContext('PyodideWorker')
|
||||||
|
|
||||||
// 定义输出结构类型
|
// 定义输出结构类型
|
||||||
interface PyodideOutput {
|
interface PyodideOutput {
|
||||||
result: any
|
result: any
|
||||||
@ -47,7 +51,7 @@ const pyodidePromise = (async () => {
|
|||||||
})
|
})
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
const errorMessage = error instanceof Error ? error.message : String(error)
|
const errorMessage = error instanceof Error ? error.message : String(error)
|
||||||
console.error('Failed to load Pyodide:', errorMessage)
|
logger.error('Failed to load Pyodide:', errorMessage)
|
||||||
|
|
||||||
// 通知主线程初始化错误
|
// 通知主线程初始化错误
|
||||||
self.postMessage({
|
self.postMessage({
|
||||||
@ -77,7 +81,7 @@ function processResult(result: any): any {
|
|||||||
return result
|
return result
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
const errorMessage = error instanceof Error ? error.message : String(error)
|
const errorMessage = error instanceof Error ? error.message : String(error)
|
||||||
console.error('Result processing error:', errorMessage)
|
logger.error('Result processing error:', errorMessage)
|
||||||
return { __error__: 'Result processing failed', details: errorMessage }
|
return { __error__: 'Result processing failed', details: errorMessage }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -89,7 +93,7 @@ pyodidePromise
|
|||||||
})
|
})
|
||||||
.catch((error: unknown) => {
|
.catch((error: unknown) => {
|
||||||
const errorMessage = error instanceof Error ? error.message : String(error)
|
const errorMessage = error instanceof Error ? error.message : String(error)
|
||||||
console.error('Failed to load Pyodide:', errorMessage)
|
logger.error('Failed to load Pyodide:', errorMessage)
|
||||||
self.postMessage({ type: 'error', error: errorMessage })
|
self.postMessage({ type: 'error', error: errorMessage })
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -141,7 +145,7 @@ self.onmessage = async (event) => {
|
|||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
// 处理所有其他错误
|
// 处理所有其他错误
|
||||||
const errorMessage = error instanceof Error ? error.message : String(error)
|
const errorMessage = error instanceof Error ? error.message : String(error)
|
||||||
console.error('Python processing error:', errorMessage)
|
logger.error('Python processing error:', errorMessage)
|
||||||
|
|
||||||
if (output.error) {
|
if (output.error) {
|
||||||
output.error += `\nSystem error:\n${errorMessage}`
|
output.error += `\nSystem error:\n${errorMessage}`
|
||||||
|
|||||||
@ -1,11 +1,14 @@
|
|||||||
/// <reference lib="webworker" />
|
/// <reference lib="webworker" />
|
||||||
|
|
||||||
|
import { loggerService } from '@logger'
|
||||||
import { LRUCache } from 'lru-cache'
|
import { LRUCache } from 'lru-cache'
|
||||||
import type { HighlighterCore, SpecialLanguage, ThemedToken } from 'shiki/core'
|
import type { HighlighterCore, SpecialLanguage, ThemedToken } from 'shiki/core'
|
||||||
|
|
||||||
// 注意保持 ShikiStreamTokenizer 依赖简单,避免打包出问题
|
// 注意保持 ShikiStreamTokenizer 依赖简单,避免打包出问题
|
||||||
import { ShikiStreamTokenizer, ShikiStreamTokenizerOptions } from '../services/ShikiStreamTokenizer'
|
import { ShikiStreamTokenizer, ShikiStreamTokenizerOptions } from '../services/ShikiStreamTokenizer'
|
||||||
|
|
||||||
|
const logger = loggerService.withContext('ShikiStreamWorker')
|
||||||
|
|
||||||
// Worker 消息类型
|
// Worker 消息类型
|
||||||
type WorkerMessageType = 'init' | 'highlight' | 'cleanup' | 'dispose'
|
type WorkerMessageType = 'init' | 'highlight' | 'cleanup' | 'dispose'
|
||||||
|
|
||||||
@ -93,7 +96,7 @@ async function ensureLanguageAndThemeLoaded(
|
|||||||
await highlighter.loadTheme(themeData)
|
await highlighter.loadTheme(themeData)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// 回退到 one-light
|
// 回退到 one-light
|
||||||
console.debug(`Worker: Failed to load theme '${theme}', falling back to 'one-light':`, error)
|
logger.debug(`Worker: Failed to load theme '${theme}', falling back to 'one-light':`, error)
|
||||||
const { bundledThemes } = await import('shiki')
|
const { bundledThemes } = await import('shiki')
|
||||||
const oneLightTheme = await bundledThemes['one-light']()
|
const oneLightTheme = await bundledThemes['one-light']()
|
||||||
await highlighter.loadTheme(oneLightTheme)
|
await highlighter.loadTheme(oneLightTheme)
|
||||||
@ -154,7 +157,7 @@ async function highlightCodeChunk(
|
|||||||
recall: result.recall
|
recall: result.recall
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Worker failed to highlight code chunk:', error)
|
logger.error('Worker failed to highlight code chunk:', error)
|
||||||
|
|
||||||
// 提供简单的 fallback
|
// 提供简单的 fallback
|
||||||
const fallbackToken: ThemedToken = { content: chunk || '', color: '#000000', offset: 0 }
|
const fallbackToken: ThemedToken = { content: chunk || '', color: '#000000', offset: 0 }
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user