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