feat: configurable tool pricing, Sub2API channel, and alpha search billing

Add admin-configurable tool-call prices with cross-provider surcharge
settlement, Sub2API channel support, /v1/alpha/search relay, and usage-log
surcharge UI.
This commit is contained in:
CaIon
2026-07-26 20:05:15 +08:00
parent 3e1e728279
commit 2d23cdf291
65 changed files with 3210 additions and 431 deletions
@@ -0,0 +1,157 @@
/*
Copyright (C) 2023-2026 QuantumNous
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import assert from 'node:assert/strict'
import { after, describe, test } from 'node:test'
import { Window } from 'happy-dom'
import type React from 'react'
const domWindow = new Window()
const domGlobals = [
'window',
'document',
'navigator',
'HTMLElement',
'SVGElement',
'Node',
'Element',
'Event',
'CustomEvent',
'MutationObserver',
'requestAnimationFrame',
'cancelAnimationFrame',
'getComputedStyle',
] as const
for (const key of domGlobals) {
Object.defineProperty(globalThis, key, {
configurable: true,
value: domWindow[key],
})
}
const { act } = await import('react')
const { createRoot } = await import('react-dom/client')
const { createInstance } = await import('i18next')
const { I18nextProvider, initReactI18next } = await import('react-i18next')
const i18n = createInstance()
await i18n.use(initReactI18next).init({
lng: 'en',
resources: {
en: {
translation: {
Subscription: 'Subscription',
'Deducted by subscription': 'Deducted by subscription',
'Includes tool-call surcharge': 'Includes tool-call surcharge',
},
},
},
})
const { LogCostDisplay } = await import('../log-cost-display')
const { formatLogQuota } = await import('@/lib/format')
const reactTestGlobals = globalThis as typeof globalThis & {
IS_REACT_ACT_ENVIRONMENT?: boolean
}
reactTestGlobals.IS_REACT_ACT_ENVIRONMENT = true
type RenderedCost = {
container: HTMLDivElement
root: ReturnType<typeof createRoot>
}
async function renderCost(
props: React.ComponentProps<typeof LogCostDisplay>
): Promise<RenderedCost> {
const container = document.createElement('div')
document.body.append(container)
const root = createRoot(container)
await act(async () => {
root.render(
<I18nextProvider i18n={i18n}>
<LogCostDisplay {...props} />
</I18nextProvider>
)
})
return { container, root }
}
async function unmountCost(rendered: RenderedCost) {
await act(async () => rendered.root.unmount())
rendered.container.remove()
}
function normalizedText(value: string | null): string {
return (value ?? '').replaceAll(/\s/g, '')
}
describe('log cost display', () => {
after(() => {
domWindow.close()
})
test('keeps the regular cost visible and adds an accessible surcharge marker', async () => {
const rendered = await renderCost({
quota: 12500,
other: {
tool_surcharges: [{ name: 'lookup_customer', count: 1, price: 5 }],
},
})
assert.equal(
normalizedText(rendered.container.textContent).includes(
normalizedText(formatLogQuota(12500))
),
true
)
const marker = rendered.container.querySelector(
'[data-tool-surcharge-indicator="true"]'
)
assert.ok(marker)
assert.equal(
marker.getAttribute('aria-label'),
'Includes tool-call surcharge'
)
assert.equal(marker.getAttribute('tabindex'), '0')
await unmountCost(rendered)
})
test('preserves the subscription badge and adds the same legacy surcharge marker', async () => {
const rendered = await renderCost({
quota: 5000,
other: {
billing_source: 'subscription',
web_search: true,
web_search_call_count: 1,
web_search_price: 10,
},
})
assert.equal(rendered.container.textContent?.includes('Subscription'), true)
assert.ok(
rendered.container.querySelector('[data-tool-surcharge-indicator="true"]')
)
await unmountCost(rendered)
})
})
@@ -58,6 +58,7 @@ import {
} from '../../lib/utils'
import type { LogOtherData } from '../../types'
import { DetailsDialog } from '../dialogs/details-dialog'
import { LogCostDisplay } from '../log-cost-display'
import { ModelBadge } from '../model-badge'
import { TimingMetricsCell, StreamTpsCell } from '../timing-metrics-cell'
import { useUsageLogsContext } from '../usage-logs-provider'
@@ -93,12 +94,6 @@ function getGroupRatio(other: LogOtherData | null): number | null {
return null
}
function splitQuotaDisplay(value: string): { prefix: string; amount: string } {
const match = value.match(/^([^0-9+\-.,\s]+)(.+)$/)
if (!match) return { prefix: '', amount: value }
return { prefix: match[1], amount: match[2] }
}
function buildDetailSegments(
log: UsageLog,
other: LogOtherData | null,
@@ -703,46 +698,7 @@ export function useCommonLogsColumns(isAdmin: boolean): ColumnDef<UsageLog>[] {
const quota = row.getValue('quota') as number
const other = parseLogOther(log.other)
const isSubscription = other?.billing_source === 'subscription'
if (isSubscription) {
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger
render={
<StatusBadge
label={t('Subscription')}
variant='success'
size='sm'
copyable={false}
className='cursor-help'
/>
}
/>
<TooltipContent>
<span>
{t('Deducted by subscription')}: {formatLogQuota(quota)}
</span>
</TooltipContent>
</Tooltip>
</TooltipProvider>
)
}
const quotaStr = formatLogQuota(quota)
const quotaDisplay = splitQuotaDisplay(quotaStr)
return (
<div className='flex flex-col gap-0.5'>
<span className='border-border/80 bg-muted/60 inline-flex h-6 w-fit items-center rounded-md border px-2 [font-family:var(--font-body)] text-sm leading-none font-semibold tabular-nums'>
{quotaDisplay.prefix && (
<span className='mr-1'>{quotaDisplay.prefix}</span>
)}
<span>{quotaDisplay.amount}</span>
</span>
</div>
)
return <LogCostDisplay quota={quota} other={other} />
},
},
@@ -0,0 +1,144 @@
/*
Copyright (C) 2023-2026 QuantumNous
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import { Wrench01Icon } from '@hugeicons/core-free-icons'
import { HugeiconsIcon } from '@hugeicons/react'
import { useTranslation } from 'react-i18next'
import { StatusBadge } from '@/components/status-badge'
import { Badge } from '@/components/ui/badge'
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from '@/components/ui/tooltip'
import { formatLogQuota } from '@/lib/format'
import { hasToolSurcharge } from '../lib/format'
import type { LogOtherData } from '../types'
interface LogCostDisplayProps {
quota: number
other: LogOtherData | null
}
function splitQuotaDisplay(value: string): { prefix: string; amount: string } {
const match = value.match(/^([^0-9+\-.,\s]+)(.+)$/)
if (!match) return { prefix: '', amount: value }
return { prefix: match[1], amount: match[2] }
}
function ToolSurchargeMarker() {
const { t } = useTranslation()
const label = t('Includes tool-call surcharge')
return (
<Tooltip>
<TooltipTrigger
render={
<Badge
variant='warning'
className='h-5 min-w-5 cursor-help gap-0 rounded-full px-1'
role='img'
aria-label={label}
tabIndex={0}
data-tool-surcharge-indicator='true'
>
<HugeiconsIcon
icon={Wrench01Icon}
strokeWidth={2}
aria-hidden='true'
/>
<span
className='text-[9px] leading-none font-bold'
aria-hidden='true'
>
+
</span>
</Badge>
}
/>
<TooltipContent>{label}</TooltipContent>
</Tooltip>
)
}
function QuotaBadge(props: { quota: number }) {
const quotaDisplay = splitQuotaDisplay(formatLogQuota(props.quota))
return (
<span className='border-border/80 bg-muted/60 inline-flex h-6 w-fit items-center rounded-md border px-2 [font-family:var(--font-body)] text-sm leading-none font-semibold tabular-nums'>
{quotaDisplay.prefix ? (
<span className='mr-1'>{quotaDisplay.prefix}</span>
) : null}
<span>{quotaDisplay.amount}</span>
</span>
)
}
function SubscriptionBadge(props: { quota: number }) {
const { t } = useTranslation()
return (
<Tooltip>
<TooltipTrigger
render={
<StatusBadge
label={t('Subscription')}
variant='success'
size='sm'
copyable={false}
className='cursor-help'
/>
}
/>
<TooltipContent>
<span>
{t('Deducted by subscription')}: {formatLogQuota(props.quota)}
</span>
</TooltipContent>
</Tooltip>
)
}
export function LogCostDisplay(props: LogCostDisplayProps) {
const isSubscription = props.other?.billing_source === 'subscription'
const showToolSurcharge = hasToolSurcharge(props.other)
if (!isSubscription && !showToolSurcharge) {
return (
<div className='flex flex-col gap-0.5'>
<QuotaBadge quota={props.quota} />
</div>
)
}
return (
<TooltipProvider>
<div className='inline-flex items-center gap-1'>
{isSubscription ? (
<SubscriptionBadge quota={props.quota} />
) : (
<QuotaBadge quota={props.quota} />
)}
{showToolSurcharge ? <ToolSurchargeMarker /> : null}
</div>
</TooltipProvider>
)
}
@@ -0,0 +1,99 @@
/*
Copyright (C) 2023-2026 QuantumNous
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
For commercial licensing, please contact support@quantumnous.com
*/
import assert from 'node:assert/strict'
import { describe, test } from 'node:test'
import type { LogOtherData } from '../../types'
import { hasToolSurcharge } from '../format'
describe('tool surcharge detection', () => {
test('shows the marker for a charged structured tool surcharge', () => {
assert.equal(
hasToolSurcharge({
tool_surcharges: [{ name: 'lookup_customer', count: 2, price: 5 }],
}),
true
)
})
const legacyCases: Array<{
name: string
other: LogOtherData
}> = [
{
name: 'Web Search',
other: {
web_search: true,
web_search_call_count: 1,
web_search_price: 10,
},
},
{
name: 'File Search',
other: {
file_search: true,
file_search_call_count: 2,
file_search_price: 2.5,
},
},
{
name: 'Image Generation',
other: {
image_generation_call: true,
image_generation_call_price: 0.04,
},
},
]
for (const scenario of legacyCases) {
test(`keeps the marker visible for legacy ${scenario.name} charges`, () => {
assert.equal(hasToolSurcharge(scenario.other), true)
})
}
test('hides the marker when surcharge entries are empty or not chargeable', () => {
const invalidCases: Array<LogOtherData | null> = [
null,
{},
{ tool_surcharges: [] },
{
tool_surcharges: [{ name: 'lookup_customer', count: 0, price: 5 }],
},
{
tool_surcharges: [{ name: 'lookup_customer', count: 1, price: 0 }],
},
{
tool_surcharges: [{ name: ' ', count: 1, price: 5 }],
},
{
web_search: true,
web_search_call_count: 1,
web_search_price: 0,
},
{
image_generation_call: false,
image_generation_call_price: 0.04,
},
]
for (const other of invalidCases) {
assert.equal(hasToolSurcharge(other), false)
}
})
})
+61
View File
@@ -92,6 +92,67 @@ export function isViolationFeeLog(other: LogOtherData | null): boolean {
)
}
function isPositiveFiniteNumber(value: unknown): value is number {
return typeof value === 'number' && Number.isFinite(value) && value > 0
}
function hasLegacySearchSurcharge(
enabled: boolean | undefined,
count: number | undefined,
price: number | undefined
): boolean {
return (
enabled === true &&
isPositiveFiniteNumber(count) &&
isPositiveFiniteNumber(price)
)
}
/**
* Check whether a consume log includes an actual tool-call surcharge.
* Structured surcharge items cover current logs, while the legacy fields keep
* historical Web Search, File Search, and Image Generation logs visible.
*/
export function hasToolSurcharge(other: LogOtherData | null): boolean {
if (!other) return false
const hasStructuredSurcharge =
Array.isArray(other.tool_surcharges) &&
other.tool_surcharges.some(
(item) =>
typeof item?.name === 'string' &&
item.name.trim() !== '' &&
isPositiveFiniteNumber(item.count) &&
isPositiveFiniteNumber(item.price)
)
if (hasStructuredSurcharge) return true
if (
hasLegacySearchSurcharge(
other.web_search,
other.web_search_call_count,
other.web_search_price
)
) {
return true
}
if (
hasLegacySearchSurcharge(
other.file_search,
other.file_search_call_count,
other.file_search_price
)
) {
return true
}
return (
other.image_generation_call === true &&
isPositiveFiniteNumber(other.image_generation_call_price)
)
}
/**
* Parse the 'other' field from JSON string to object
*/
+8
View File
@@ -106,6 +106,12 @@ export const USAGE_BILLING_PATH = {
export type UsageBillingPath =
(typeof USAGE_BILLING_PATH)[keyof typeof USAGE_BILLING_PATH]
export interface ToolSurchargeItem {
name: string
count: number
price: number
}
export interface LogOtherData {
admin_info?: {
is_multi_key?: boolean
@@ -197,11 +203,13 @@ export interface LogOtherData {
file_search?: boolean
file_search_call_count?: number
file_search_price?: number
tool_surcharges?: ToolSurchargeItem[]
audio_input_seperate_price?: boolean
audio_input_token_count?: number
audio_input_price?: number
image_generation_call?: boolean
image_generation_call_price?: number
image_generation_call_count?: number
is_system_prompt_overwritten?: boolean
po?: string[]
billing_source?: string