Files
gpt-load/web/e2e/visual-api.ts
T

426 lines
11 KiB
TypeScript

import type { Page, Route } from '@playwright/test'
import { visualClock, visualFixtureData, type VisualScenario } from './visual-fixtures'
export const visualAuthKey = 'visual-fixture-auth'
const group = {
id: 7,
name: visualFixtureData.groupName,
upstream_url: 'https://visual-fixture.example/v1',
protocols: ['openai'],
models: [
{ id: visualFixtureData.modelName, alias: 'stable-public-alias' },
{ id: 'visual-fixture-secondary-model', alias: '' },
],
enabled: true,
key_count: 4,
}
const accessKey = {
id: 12,
name: visualFixtureData.longIdentifier,
masked_key: `sk-gl-••••••••${visualFixtureData.accessKeySuffix}`,
status: 'active',
filters: {
groups: [group.id],
protocols: ['openai'],
models: [visualFixtureData.modelName],
},
rpm_limit: 120,
created_at: '2026-07-28T10:00:00.000Z',
updated_at: visualClock,
}
const requestLogHealth = {
enqueued_total: 8,
persisted_total: 6,
dropped_not_running_total: 0,
dropped_queue_full_total: 1,
dropped_stopping_total: 0,
dropped_persist_failed_total: 1,
dropped_shutdown_total: 0,
dropped_total: 2,
write_failure_total: 1,
retention_delete_failure_total: 0,
queue_depth: 2,
queue_capacity: 256,
last_write_failure_at: '2026-07-28T23:50:00.000Z',
last_retention_failure_at: null,
}
const normalHealth = {
observed_at: visualClock,
snapshot_revision: 42,
stats_window_seconds: 300,
counts: { total: 4, available: 4, cooldown: 0, blacklisted: 0, disabled: 0 },
groups: [
{
id: group.id,
name: group.name,
enabled: true,
counts: { total: 4, available: 4, cooldown: 0, blacklisted: 0, disabled: 0 },
},
],
cooldown_keys: [],
blacklisted_keys: [],
request_log: {
...requestLogHealth,
dropped_queue_full_total: 0,
dropped_persist_failed_total: 0,
dropped_total: 0,
write_failure_total: 0,
last_write_failure_at: null,
},
}
const anomalyHealth = {
...normalHealth,
counts: { total: 4, available: 1, cooldown: 1, blacklisted: 1, disabled: 1 },
groups: [
{
id: group.id,
name: group.name,
enabled: true,
counts: { total: 4, available: 1, cooldown: 1, blacklisted: 1, disabled: 1 },
},
],
cooldown_keys: [
{
key_id: 91,
group_id: group.id,
group_name: group.name,
cooldown_until: '2026-07-29T00:10:00.000Z',
failure_count: 3,
recent_success_count: 1,
recent_failure_count: 3,
consecutive_failure_count: 2,
weight_manual: null,
weight_auto: 35,
recovery: {
automatic: true,
mode: 'cooldown_expiry',
at: '2026-07-29T00:10:00.000Z',
},
},
],
blacklisted_keys: [
{
key_id: 92,
group_id: group.id,
group_name: group.name,
failure_count: 8,
recent_success_count: 0,
recent_failure_count: 5,
consecutive_failure_count: 5,
weight_manual: 50,
weight_auto: 0,
recovery: { automatic: true, mode: 'validation_probe', at: null },
},
],
request_log: requestLogHealth,
}
const aggregate = {
request_count: 6,
success_count: 4,
failure_count: 2,
uncached_input_tokens: 1200,
cache_read_tokens: 300,
cache_write_5m_tokens: 120,
cache_write_1h_tokens: 80,
output_tokens: 500,
total_tokens: 2200,
estimated_cost_usd: 0.01234,
usage_missing_count: 1,
partial_count: 1,
unpriced_request_count: 2,
}
const usageReport = {
range: '24h',
granularity: 'hour',
timezone: 'UTC',
from: '2026-07-28T00:00:00.000Z',
to: '2026-07-29T00:00:00.000Z',
observed_at: '2026-07-28T23:59:59.000Z',
summary: aggregate,
series: [
{
...aggregate,
bucket_start: '2026-07-28T23:00:00.000Z',
bucket_end: '2026-07-29T00:00:00.000Z',
},
],
breakdown: [{ ...aggregate, group_id: group.id, model: visualFixtureData.modelName }],
breakdown_truncated: true,
collection_health: {
scope: 'current_process',
dropped_total: 2,
write_failure_total: 1,
last_write_failure_at: '2026-07-28T23:50:00.000Z',
},
}
const settings = {
values: {
connect_timeout: 15,
first_byte_timeout: 120,
request_timeout: 600,
stream_idle_timeout: 300,
header_rules: { set: { 'X-Visual-Fixture': 'stable-value' }, remove: ['X-Legacy'] },
inject_usage_options: true,
request_log_retention_days: 7,
},
overrides: [],
}
const modelPrices = {
price_unit: 'usd_per_million_tokens',
builtin: [
{
pattern: 'visual-model-*',
source: 'builtin',
prices: {
uncached_input: 1.25,
cache_read: 0,
cache_write_5m: null,
cache_write_1h: 2.5,
output: 7.5,
},
source_url: 'https://visual-fixture.example/pricing',
updated_at: visualClock,
pricing_policy: {
input_threshold_tokens: 272000,
input_multiplier: 2,
output_multiplier: 1.5,
},
},
],
overrides: [
{
pattern: '*',
source: 'user',
prices: {
uncached_input: 2,
cache_read: 0,
cache_write_5m: null,
cache_write_1h: null,
output: 8,
},
source_url: null,
updated_at: visualClock,
pricing_policy: null,
},
],
}
const requestLogPage = {
items: [
{
request_id: visualFixtureData.requestId,
completed_at: visualClock,
access_key: { id: accessKey.id, name: accessKey.name, deleted: false },
protocol: 'openai',
client_model: 'stable-public-alias',
upstream_model: visualFixtureData.modelName,
status: 'error',
status_code: 429,
duration_ms: 842,
error_code: 'RATE_LIMITED',
error_summary: 'Fixture upstream rate limit',
affinity_hit: false,
attempts: [
{
sequence: 1,
group_id: group.id,
group_name: group.name,
key_id: 91,
upstream_model: visualFixtureData.modelName,
status_code: 429,
duration_ms: 842,
failure_category: 'rate_limited',
action: 'cooldown_key',
will_retry: false,
error_code: 'RATE_LIMITED',
error_summary: 'Fixture upstream rate limit',
committed: true,
},
],
group_id: group.id,
usage_state: 'missing',
cost_state: 'unpriced',
uncached_input_tokens: 0,
cache_read_tokens: 0,
cache_write_5m_tokens: 0,
cache_write_1h_tokens: 0,
output_tokens: 0,
estimated_cost_usd: 0,
},
],
next_cursor: null,
}
const routeInspection = {
observed_at: visualClock,
snapshot_revision: 42,
protocol: 'openai',
external_model: 'stable-public-alias',
access_key: { id: accessKey.id, name: accessKey.name, status: 'active' },
routable: true,
reason_code: null,
groups: [
{
group_id: group.id,
group_name: group.name,
upstream_model: visualFixtureData.modelName,
weight_manual: null,
included: true,
routable: true,
reason_code: null,
keys: [
{
key_id: 91,
available: true,
reason_code: null,
weight_manual: null,
weight_auto: 72,
effective_weight: 5184,
cooldown_until: null,
},
],
},
],
}
function success(data: unknown, headers: Record<string, string> = {}) {
return {
status: 200,
headers: { 'content-type': 'application/json; charset=utf-8', ...headers },
body: JSON.stringify({ code: 0, message: 'OK', data }),
}
}
function failure() {
return {
status: 503,
headers: { 'content-type': 'application/json; charset=utf-8' },
body: JSON.stringify({
code: 'SERVICE_UNAVAILABLE',
message: 'Fixture service unavailable',
}),
}
}
export interface VisualApiState {
healthRequests: number
unexpectedRequests: string[]
}
export async function installVisualApi(
page: Page,
scenario: VisualScenario,
): Promise<VisualApiState> {
const state: VisualApiState = { healthRequests: 0, unexpectedRequests: [] }
await page.route('**/api/**', async (route: Route) => {
const request = route.request()
const url = new URL(request.url())
const method = request.method()
if (url.pathname === '/api/auth/session') {
await route.fulfill(success({ authenticated: true }))
return
}
if (url.pathname === '/api/groups' && method === 'GET') {
await route.fulfill(success(scenario === 'home-empty-error' ? [] : [group]))
return
}
if (url.pathname === '/api/access-keys/options' && method === 'GET') {
await route.fulfill(
success(
scenario === 'home-empty-error'
? []
: [{ id: accessKey.id, name: accessKey.name, status: accessKey.status }],
),
)
return
}
if (url.pathname === '/api/access-keys' && method === 'GET') {
await route.fulfill(success([accessKey]))
return
}
if (
url.pathname === '/api/access-keys' &&
method === 'POST' &&
scenario === 'access-key-operation'
) {
await route.abort('connectionreset')
return
}
if (url.pathname === '/api/health' && method === 'GET') {
state.healthRequests += 1
if (
scenario === 'home-empty-error' ||
(scenario === 'home-anomaly' && state.healthRequests > 1)
) {
await route.fulfill(failure())
return
}
await route.fulfill(success(scenario === 'home-anomaly' ? anomalyHealth : normalHealth))
return
}
if (url.pathname === '/api/usage' && method === 'GET') {
await route.fulfill(scenario === 'home-empty-error' ? failure() : success(usageReport))
return
}
if (url.pathname === '/api/logs' && method === 'GET') {
await route.fulfill(success(requestLogPage))
return
}
if (url.pathname === '/api/settings' && method === 'GET') {
await route.fulfill(
success(settings, {
etag: '"sha256-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"',
}),
)
return
}
if (url.pathname === '/api/system/info' && method === 'GET') {
await route.fulfill(
success({
version: '2.0.0-visual',
deployment: {
instance_mode: 'single',
database: 'sqlite',
distribution: 'single_binary',
},
data_dir: '/visual/data',
auth_key: { source: 'environment', path: null },
encryption: { enabled: true, source: 'environment', path: null },
}),
)
return
}
if (url.pathname === '/api/model-prices' && method === 'GET') {
await route.fulfill(success(modelPrices))
return
}
if (url.pathname === '/api/route/inspect' && method === 'POST') {
await route.fulfill(success(routeInspection))
return
}
const identity = `${method} ${url.pathname}${url.search}`
state.unexpectedRequests.push(identity)
await route.fulfill({
status: 500,
contentType: 'application/json',
body: JSON.stringify({
code: 'VISUAL_FIXTURE_UNEXPECTED_REQUEST',
message: identity,
}),
})
})
return state
}