Files
memind/billing-token-state.test.mjs
T
john 32fb2cdeaf feat: chat uploads, vision turn isolation, and MindSpace agent improvements
Add chat file/image upload UX, attachment proxying, vision thumbnails, and per-turn image scoping so agents only use the current upload. Extend MindSpace asset context, billing token state, OA/scenario verify scripts, and related runtime config.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-11 00:23:01 +08:00

116 lines
3.9 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import {
enrichTokenStateForBilling,
estimateAccumulatedCostUsd,
loadCostEstimateConfig,
pickSessionAccumulatedCost,
resolveBillingTokenState,
} from './billing-token-state.mjs';
import { computeDeltaCostCents } from './billing.mjs';
test('pickSessionAccumulatedCost reads snake_case and camelCase', () => {
assert.equal(pickSessionAccumulatedCost({ accumulated_cost: 0.12 }), 0.12);
assert.equal(pickSessionAccumulatedCost({ accumulatedCost: 0.34 }), 0.34);
assert.equal(pickSessionAccumulatedCost({}), null);
});
test('estimateAccumulatedCostUsd uses DeepSeek-ish defaults', () => {
const estimate = estimateAccumulatedCostUsd(
{ accumulatedInputTokens: 1_000_000, accumulatedOutputTokens: 10_000 },
{ enabled: true, inputUsdPer1M: 0.27, outputUsdPer1M: 1.1 },
);
assert.equal(estimate, 0.281);
});
test('enrichTokenStateForBilling prefers upstream cost over estimate', () => {
const enriched = enrichTokenStateForBilling(
{ accumulatedInputTokens: 1000, accumulatedOutputTokens: 100, accumulatedCost: 0.05 },
{},
{ H5_USE_BACKEND_COST: '1' },
);
assert.equal(enriched.accumulatedCost, 0.05);
});
test('enrichTokenStateForBilling fills session cost when Finish omits it', () => {
const enriched = enrichTokenStateForBilling(
{ accumulatedInputTokens: 1000, accumulatedOutputTokens: 100 },
{ sessionCost: { accumulated_cost: 0.08 } },
{ H5_USE_BACKEND_COST: '1' },
);
assert.equal(enriched.accumulatedCost, 0.08);
});
test('enrichTokenStateForBilling estimates when cost mode enabled and upstream missing', () => {
const enriched = enrichTokenStateForBilling(
{ accumulatedInputTokens: 1_000_000, accumulatedOutputTokens: 0 },
{},
{
H5_USE_BACKEND_COST: '1',
H5_COST_ESTIMATE_FROM_TOKENS: '1',
H5_COST_ESTIMATE_INPUT_USD_PER_1M: '0.27',
H5_COST_ESTIMATE_OUTPUT_USD_PER_1M: '1.1',
},
);
assert.equal(enriched.accumulatedCost, 0.27);
});
test('loadCostEstimateConfig disables estimate when cost mode off', () => {
const cfg = loadCostEstimateConfig({ H5_USE_BACKEND_COST: '0' });
assert.equal(cfg.enabled, false);
});
test('resolveBillingTokenState fetches session before estimating', async () => {
let fetched = false;
const resolved = await resolveBillingTokenState(
{ accumulatedInputTokens: 1000, accumulatedOutputTokens: 100 },
{
sessionId: '20260710_11',
fetchSession: async (sessionId) => {
fetched = true;
assert.equal(sessionId, '20260710_11');
return { accumulated_cost: 0.42 };
},
},
{ H5_USE_BACKEND_COST: '1' },
);
assert.equal(fetched, true);
assert.equal(resolved.accumulatedCost, 0.42);
});
test('enriched cost drives 1.2x billing instead of flat fallback', () => {
const previous = { lastInputTokens: 224853, lastOutputTokens: 6685, lastAccumulatedCost: null };
const tokenState = enrichTokenStateForBilling(
{ accumulatedInputTokens: 2908661, accumulatedOutputTokens: 15349 },
{},
{
H5_USE_BACKEND_COST: '1',
H5_COST_ESTIMATE_FROM_TOKENS: '1',
H5_COST_ESTIMATE_INPUT_USD_PER_1M: '0.27',
H5_COST_ESTIMATE_OUTPUT_USD_PER_1M: '1.1',
},
);
const previousCost = estimateAccumulatedCostUsd(
{ accumulatedInputTokens: 224853, accumulatedOutputTokens: 6685 },
loadCostEstimateConfig({
H5_USE_BACKEND_COST: '1',
H5_COST_ESTIMATE_FROM_TOKENS: '1',
H5_COST_ESTIMATE_INPUT_USD_PER_1M: '0.27',
H5_COST_ESTIMATE_OUTPUT_USD_PER_1M: '1.1',
}),
);
const costCents = computeDeltaCostCents(
{ ...previous, lastAccumulatedCost: previousCost },
tokenState,
{
useBackendCost: true,
usdCnyRate: 7.2,
marginMultiplier: 1.2,
inputCentsPer1k: 2,
outputCentsPer1k: 6,
minBillCents: 1,
},
);
assert.ok(costCents < 1000, `expected cost-mode charge under ¥10, got ${costCents} cents`);
});