fix(billing): read Goose accumulated_cost from PostgreSQL fallback
Goosed GET /sessions/:id returns accumulated_cost null while memind_sessions PG has the real upstream cost. Fall back to PG before token estimate billing. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+36
-13
@@ -1,4 +1,5 @@
|
||||
import { normalizeTokenState } from './billing.mjs';
|
||||
import { fetchGooseSessionAccumulatedCostUsd } from './goose-session-cost.mjs';
|
||||
|
||||
export function loadCostEstimateConfig(env = process.env) {
|
||||
const useBackendCost = env.H5_USE_BACKEND_COST === '1';
|
||||
@@ -56,22 +57,44 @@ export function enrichTokenStateForBilling(
|
||||
return state;
|
||||
}
|
||||
|
||||
async function resolveSessionCostPayload(sessionId, fetchSession, fetchSessionCostFromPg, env) {
|
||||
let sessionCost = null;
|
||||
if (typeof fetchSession === 'function' && sessionId) {
|
||||
try {
|
||||
sessionCost = await fetchSession(sessionId);
|
||||
} catch {
|
||||
sessionCost = null;
|
||||
}
|
||||
}
|
||||
if (pickSessionAccumulatedCost(sessionCost) != null) {
|
||||
return sessionCost;
|
||||
}
|
||||
|
||||
const readPgCost =
|
||||
typeof fetchSessionCostFromPg === 'function'
|
||||
? fetchSessionCostFromPg
|
||||
: (sid) => fetchGooseSessionAccumulatedCostUsd(sid, env);
|
||||
const pgUsd = env.H5_USE_BACKEND_COST === '1' ? await readPgCost(sessionId) : null;
|
||||
if (pgUsd != null) {
|
||||
return {
|
||||
...(sessionCost && typeof sessionCost === 'object' ? sessionCost : {}),
|
||||
accumulated_cost: pgUsd,
|
||||
};
|
||||
}
|
||||
return sessionCost;
|
||||
}
|
||||
|
||||
export async function resolveBillingTokenState(
|
||||
tokenStateRaw,
|
||||
{ sessionId = null, fetchSession = null } = {},
|
||||
{ sessionId = null, fetchSession = null, fetchSessionCostFromPg = null } = {},
|
||||
env = process.env,
|
||||
) {
|
||||
const state = normalizeTokenState(tokenStateRaw);
|
||||
|
||||
if (typeof fetchSession === 'function' && sessionId) {
|
||||
try {
|
||||
const session = await fetchSession(sessionId);
|
||||
const enriched = enrichTokenStateForBilling(state, { sessionCost: session }, env);
|
||||
if (enriched.accumulatedCost != null) return enriched;
|
||||
} catch {
|
||||
// Best-effort: fall through to inline cost / token estimate.
|
||||
}
|
||||
}
|
||||
|
||||
return enrichTokenStateForBilling(state, {}, env);
|
||||
const sessionCost = await resolveSessionCostPayload(
|
||||
sessionId,
|
||||
fetchSession,
|
||||
fetchSessionCostFromPg,
|
||||
env,
|
||||
);
|
||||
return enrichTokenStateForBilling(state, { sessionCost }, env);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user