fix(quotas): unifier le décompte IA (BYOK, rollback) et combler les fuites
Centralise la réserve via ai-quota, corrige admin unavailable (-1), brancher les routes sans quota et le host-pays brainstorm, avec usage-meter élargi, noms de clusters, MCP et ajustements dashboard/insights. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -10,6 +10,7 @@ import { clusteringService } from './clustering.service'
|
||||
import { getChatProvider } from '@/lib/ai/factory'
|
||||
import { getSystemConfig } from '@/lib/config'
|
||||
import { calculateNextRun } from '@/lib/agents/schedule'
|
||||
import { withAiQuota } from '@/lib/ai-quota'
|
||||
|
||||
const MIN_CLUSTER_NOTES = 3
|
||||
const MAX_SUGGESTIONS_PER_RUN = 3
|
||||
@@ -51,6 +52,7 @@ function clusterCoveredByAgent(
|
||||
}
|
||||
|
||||
async function buildSuggestionWithLlm(
|
||||
userId: string,
|
||||
topic: string,
|
||||
noteTitles: string[],
|
||||
noteCount: number,
|
||||
@@ -63,10 +65,6 @@ async function buildSuggestionWithLlm(
|
||||
}
|
||||
|
||||
try {
|
||||
const config = await getSystemConfig()
|
||||
const provider = getChatProvider(config)
|
||||
if (!provider) return fallback
|
||||
|
||||
const prompt = `Tu proposes un agent IA pour un second cerveau (prise de notes).
|
||||
Thème détecté: "${topic}"
|
||||
Notes liées (titres): ${noteTitles.slice(0, 5).join(' | ') || 'sans titre'}
|
||||
@@ -75,7 +73,14 @@ Nombre de notes: ${noteCount}
|
||||
Retourne UNIQUEMENT du JSON valide:
|
||||
{"reason":"1 phrase pourquoi un agent est utile","suggestedRole":"prompt système de l'agent (2-3 phrases, français)","suggestedType":"researcher|monitor","suggestedFrequency":"daily|weekly"}`
|
||||
|
||||
const raw = await provider.generateText(prompt)
|
||||
const raw = await withAiQuota(userId, 'reformulate', async () => {
|
||||
const config = await getSystemConfig()
|
||||
const provider = getChatProvider(config)
|
||||
if (!provider) return null
|
||||
return provider.generateText(prompt)
|
||||
}, { lane: 'chat' })
|
||||
|
||||
if (!raw) return fallback
|
||||
const match = raw.match(/\{[\s\S]*\}/)
|
||||
if (!match) return fallback
|
||||
const parsed = JSON.parse(match[0])
|
||||
@@ -122,6 +127,7 @@ export class AgentSuggestionService {
|
||||
select: { title: true },
|
||||
})
|
||||
const llm = await buildSuggestionWithLlm(
|
||||
userId,
|
||||
topic,
|
||||
notes.map(n => n.title || 'Sans titre'),
|
||||
cluster.noteIds.length,
|
||||
|
||||
Reference in New Issue
Block a user