(params: {
messageId: string
userId: string
stripeCustomerId?: string | null
agentId: string
clientId: string | null
clientRequestId: string | null
startTime: Date
model: string
reasoningText: string
responseText: string
usageData: UsageData
byok: boolean
logger: Logger
costMode?: string
ttftMs?: number | null
})
| 113 | } |
| 114 | |
| 115 | export async function consumeCreditsForMessage(params: { |
| 116 | messageId: string |
| 117 | userId: string |
| 118 | stripeCustomerId?: string | null |
| 119 | agentId: string |
| 120 | clientId: string | null |
| 121 | clientRequestId: string | null |
| 122 | startTime: Date |
| 123 | model: string |
| 124 | reasoningText: string |
| 125 | responseText: string |
| 126 | usageData: UsageData |
| 127 | byok: boolean |
| 128 | logger: Logger |
| 129 | costMode?: string |
| 130 | ttftMs?: number | null |
| 131 | }): Promise<number> { |
| 132 | const { |
| 133 | messageId, |
| 134 | userId, |
| 135 | stripeCustomerId, |
| 136 | agentId, |
| 137 | clientId, |
| 138 | clientRequestId, |
| 139 | startTime, |
| 140 | model, |
| 141 | reasoningText, |
| 142 | responseText, |
| 143 | usageData, |
| 144 | byok, |
| 145 | logger, |
| 146 | costMode, |
| 147 | ttftMs, |
| 148 | } = params |
| 149 | |
| 150 | // Calculate initial credits based on cost |
| 151 | const initialCredits = Math.round(usageData.cost * 100 * (1 + PROFIT_MARGIN)) |
| 152 | |
| 153 | // FREE mode: only specific agents using their expected models cost 0 credits |
| 154 | // This is the strictest check - validates: |
| 155 | // 1. The cost mode is 'free' |
| 156 | // 2. The agent is in the allowed free-mode agents list |
| 157 | // 3. The model matches what that specific agent is allowed to use |
| 158 | // 4. The agent is either internal or published by 'codebuff' (prevents publisher spoofing) |
| 159 | const isFreeModeAndAllowed = |
| 160 | isFreeMode(costMode) && isFreeModeAllowedAgentModel(agentId, model) |
| 161 | |
| 162 | // Free tier agents (like file-picker) also don't charge credits for small requests |
| 163 | // This is separate from FREE mode and helps with BYOK users |
| 164 | // Also validates publisher to prevent spoofing attacks |
| 165 | const isFreeAgentSmallRequest = isFreeAgent(agentId) && initialCredits < 5 |
| 166 | |
| 167 | const credits = |
| 168 | isFreeModeAndAllowed || isFreeAgentSmallRequest ? 0 : initialCredits |
| 169 | |
| 170 | if (isFreeModeAndAllowed) { |
| 171 | await recordMessageWithoutBilling({ |
| 172 | messageId, |
no test coverage detected