perf: memo GridCard, fuse save fns, fix slash tab active color
This commit is contained in:
@@ -9,6 +9,7 @@ import { hasUserAiConsent } from '@/lib/consent/server-consent'
|
||||
import { loadTranslations, getTranslationValue, SupportedLanguage } from '@/lib/i18n'
|
||||
import { toolRegistry } from '@/lib/ai/tools'
|
||||
import { checkEntitlementOrThrow, QuotaExceededError, incrementUsageAsync } from '@/lib/entitlements'
|
||||
import { ByokUnavailableError } from '@/lib/byok'
|
||||
import { trackFeatureUsage } from '@/lib/usage-tracker'
|
||||
import { readFile } from 'fs/promises'
|
||||
import path from 'path'
|
||||
@@ -70,6 +71,12 @@ export async function POST(req: Request) {
|
||||
if (err instanceof QuotaExceededError) {
|
||||
return Response.json(err.toJSON(), { status: 402 })
|
||||
}
|
||||
if (err instanceof ByokUnavailableError) {
|
||||
return Response.json(
|
||||
{ error: 'byok_unavailable', message: 'Votre clé API BYOK est configurée mais n\'a pas pu être chargée. Vérifiez vos paramètres BYOK.' },
|
||||
{ status: 503 }
|
||||
)
|
||||
}
|
||||
console.error('[chat] Quota check error (fail-open):', err)
|
||||
}
|
||||
|
||||
@@ -410,40 +417,49 @@ Focus ONLY on this note unless asked otherwise.`
|
||||
]
|
||||
const wantsChart = chartKeywords.some(k => lastMessage.includes(k))
|
||||
|
||||
const { result, usedByok } = await runLaneWithBillingUser(
|
||||
'chat',
|
||||
sysConfig,
|
||||
userId,
|
||||
async (provider) =>
|
||||
streamText({
|
||||
model: provider.getModel(),
|
||||
system: systemPrompt,
|
||||
messages: incomingMessages,
|
||||
tools: chatTools,
|
||||
toolChoice: wantsChart && chatTools.insert_chart ? { type: 'tool', toolName: 'insert_chart' } : undefined,
|
||||
stopWhen: stepCountIs(5),
|
||||
onFinish: async (final) => {
|
||||
const userContent = incomingMessages[incomingMessages.length - 1].content
|
||||
await prisma.chatMessage.create({
|
||||
data: { conversationId: conversation.id, role: 'user', content: userContent },
|
||||
})
|
||||
await prisma.chatMessage.create({
|
||||
data: { conversationId: conversation.id, role: 'assistant', content: final.text },
|
||||
})
|
||||
if (!usedByok) {
|
||||
trackFeatureUsage(userId, 'chat', final.usage?.totalTokens ?? 0)
|
||||
incrementUsageAsync(userId, 'chat')
|
||||
}
|
||||
logAuditEvent({
|
||||
userId,
|
||||
action: 'AI_REQUEST',
|
||||
resource: 'chat',
|
||||
metadata: { tokens: final.usage?.totalTokens, byok: usedByok },
|
||||
ip: getClientIp(req),
|
||||
})
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
||||
return result.toUIMessageStreamResponse()
|
||||
try {
|
||||
const { result, usedByok } = await runLaneWithBillingUser(
|
||||
'chat',
|
||||
sysConfig,
|
||||
userId,
|
||||
async (provider) =>
|
||||
streamText({
|
||||
model: provider.getModel(),
|
||||
system: systemPrompt,
|
||||
messages: incomingMessages,
|
||||
tools: chatTools,
|
||||
toolChoice: wantsChart && chatTools.insert_chart ? { type: 'tool', toolName: 'insert_chart' } : undefined,
|
||||
stopWhen: stepCountIs(5),
|
||||
onFinish: async (final) => {
|
||||
const userContent = incomingMessages[incomingMessages.length - 1].content
|
||||
await prisma.chatMessage.create({
|
||||
data: { conversationId: conversation.id, role: 'user', content: userContent },
|
||||
})
|
||||
await prisma.chatMessage.create({
|
||||
data: { conversationId: conversation.id, role: 'assistant', content: final.text },
|
||||
})
|
||||
if (!usedByok) {
|
||||
trackFeatureUsage(userId, 'chat', final.usage?.totalTokens ?? 0)
|
||||
incrementUsageAsync(userId, 'chat')
|
||||
}
|
||||
logAuditEvent({
|
||||
userId,
|
||||
action: 'AI_REQUEST',
|
||||
resource: 'chat',
|
||||
metadata: { tokens: final.usage?.totalTokens, byok: usedByok },
|
||||
ip: getClientIp(req),
|
||||
})
|
||||
},
|
||||
}),
|
||||
)
|
||||
return result.toUIMessageStreamResponse()
|
||||
} catch (err) {
|
||||
if (err instanceof ByokUnavailableError) {
|
||||
return Response.json(
|
||||
{ error: 'byok_unavailable', message: 'Votre clé API BYOK est configurée mais n\'a pas pu être chargée. Vérifiez vos paramètres dans Réglages > Clés API.' },
|
||||
{ status: 503 }
|
||||
)
|
||||
}
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user