feat(server): meter AI point usage across tenant AI features
Adds an ai_point_usage_logs ledger and a reserve/refund/complete pipeline that charges AI points for article selection optimize, template analyze /title/outline, and KOL prompt generate/optimize. Pending reservations are reconciled when the kol-assist worker and template-assist tasks finish or fail, so points refund automatically on errors. Workspace now exposes the AI quota status and a paginated usage ledger. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -47,26 +47,42 @@ func (s *KolAssistService) Run(
|
||||
req.Description = s.enrichGenerateDescription(ctx, req.Description)
|
||||
}
|
||||
|
||||
reservation, err := s.reserveStreamingAIPoints(ctx, actor, req)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
generateReq, err := BuildKolAssistGenerateRequest(req)
|
||||
if err != nil {
|
||||
s.refundReservedAIPoints(context.Background(), actor, reservation, err.Error())
|
||||
return nil, "", response.ErrInternal(50087, "kol_assist_prompt_build_failed", err.Error())
|
||||
}
|
||||
|
||||
streamAccumulator := newKolAssistContentStream(onDelta)
|
||||
generated, err := s.llm.Generate(ctx, generateReq, streamAccumulator.ConsumeRawDelta)
|
||||
if err != nil {
|
||||
s.refundReservedAIPoints(context.Background(), actor, reservation, err.Error())
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
result, err := ParseKolAssistResponse(generated.Content)
|
||||
if err != nil {
|
||||
s.refundReservedAIPoints(context.Background(), actor, reservation, err.Error())
|
||||
return nil, "", response.ErrInternal(50086, "kol_assist_result_invalid", err.Error())
|
||||
}
|
||||
result, err = FinalizeKolAssistResult(req, result)
|
||||
if err != nil {
|
||||
s.refundReservedAIPoints(context.Background(), actor, reservation, err.Error())
|
||||
return nil, "", response.ErrInternal(50086, "kol_assist_result_invalid", err.Error())
|
||||
}
|
||||
|
||||
completeCtx, cancel := newGenerationCleanupContext()
|
||||
if err := CompleteAIPoints(completeCtx, s.pool, actor.TenantID, *reservation, generated.Model); err != nil {
|
||||
cancel()
|
||||
return nil, "", response.ErrInternal(50086, "kol_assist_result_invalid", "failed to confirm ai points usage")
|
||||
}
|
||||
cancel()
|
||||
|
||||
return result, generated.Model, nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user