feat: 添加 AI 分类功能,支持交易自动分类与标签生成
This commit is contained in:
63
src/services/ai/aiService.js
Normal file
63
src/services/ai/aiService.js
Normal file
@@ -0,0 +1,63 @@
|
||||
import { buildTransactionEnrichmentMessages } from '../../lib/aiPrompt.js'
|
||||
import { useSettingsStore } from '../../stores/settings.js'
|
||||
import {
|
||||
applyAiEnrichment,
|
||||
fetchRecentTransactionsForAi,
|
||||
markTransactionAiFailed,
|
||||
} from '../transactionService.js'
|
||||
import { DeepSeekProvider } from './deepseekProvider.js'
|
||||
|
||||
const clampThreshold = (value) => {
|
||||
const numeric = Number(value)
|
||||
if (!Number.isFinite(numeric)) return 0.9
|
||||
return Math.min(Math.max(numeric, 0), 1)
|
||||
}
|
||||
|
||||
const createProvider = (settingsStore) => {
|
||||
if (settingsStore.aiProvider !== 'deepseek') {
|
||||
throw new Error(`Unsupported AI provider: ${settingsStore.aiProvider}`)
|
||||
}
|
||||
|
||||
return new DeepSeekProvider({
|
||||
apiKey: settingsStore.aiApiKey,
|
||||
model: settingsStore.aiModel,
|
||||
})
|
||||
}
|
||||
|
||||
export const isAiReady = (settingsStore = useSettingsStore()) =>
|
||||
!!settingsStore.aiAutoCategoryEnabled && !!settingsStore.aiApiKey
|
||||
|
||||
export const maybeEnrichTransactionWithAi = async (transaction) => {
|
||||
if (!transaction?.id) return transaction
|
||||
|
||||
const settingsStore = useSettingsStore()
|
||||
if (!isAiReady(settingsStore)) {
|
||||
return transaction
|
||||
}
|
||||
|
||||
try {
|
||||
const provider = createProvider(settingsStore)
|
||||
const similarTransactions = await fetchRecentTransactionsForAi(6, transaction.id)
|
||||
const messages = buildTransactionEnrichmentMessages({
|
||||
transaction,
|
||||
similarTransactions,
|
||||
})
|
||||
const result = await provider.enrichTransaction({ messages })
|
||||
const threshold = clampThreshold(settingsStore.aiAutoApplyThreshold)
|
||||
|
||||
const updated = await applyAiEnrichment(transaction.id, result.normalized, {
|
||||
applyCategory: result.normalized.confidence >= threshold,
|
||||
model: result.model,
|
||||
})
|
||||
|
||||
return updated || transaction
|
||||
} catch (error) {
|
||||
console.warn('[ai] transaction enrichment failed', error)
|
||||
const failed = await markTransactionAiFailed(
|
||||
transaction.id,
|
||||
error?.message || 'AI enrichment failed',
|
||||
settingsStore.aiModel,
|
||||
)
|
||||
return failed || transaction
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user