64 lines
2.0 KiB
JavaScript
64 lines
2.0 KiB
JavaScript
|
|
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
|
||
|
|
}
|
||
|
|
}
|