project-nomad/admin/app/models/benchmark_setting.ts
Chris Sherwood 755807f95e feat: Add system benchmark feature with NOMAD Score
Add comprehensive benchmarking capability to measure server performance:

Backend:
- BenchmarkService with CPU, memory, disk, and AI benchmarks using sysbench
- Database migrations for benchmark_results and benchmark_settings tables
- REST API endpoints for running benchmarks and retrieving results
- CLI commands: benchmark:run, benchmark:results, benchmark:submit
- BullMQ job for async benchmark execution with SSE progress updates
- Synchronous mode option (?sync=true) for simpler local dev setup

Frontend:
- Benchmark settings page with circular gauges for scores
- NOMAD Score display with weighted composite calculation
- System Performance section (CPU, Memory, Disk Read/Write)
- AI Performance section (tokens/sec, time to first token)
- Hardware Information display
- Expandable Benchmark Details section
- Progress simulation during sync benchmark execution

Easy Setup Integration:
- Added System Benchmark to Additional Tools section
- Built-in capability pattern for non-Docker features
- Click-to-navigate behavior for built-in tools

Fixes:
- Docker log multiplexing issue (Tty: true) for proper output parsing
- Consolidated disk benchmarks into single container execution

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 21:48:12 -08:00

61 lines
1.7 KiB
TypeScript

import { DateTime } from 'luxon'
import { BaseModel, column, SnakeCaseNamingStrategy } from '@adonisjs/lucid/orm'
import type { BenchmarkSettingKey } from '../../types/benchmark.js'
export default class BenchmarkSetting extends BaseModel {
static namingStrategy = new SnakeCaseNamingStrategy()
@column({ isPrimary: true })
declare id: number
@column()
declare key: BenchmarkSettingKey
@column()
declare value: string | null
@column.dateTime({ autoCreate: true })
declare created_at: DateTime
@column.dateTime({ autoCreate: true, autoUpdate: true })
declare updated_at: DateTime
/**
* Get a setting value by key
*/
static async getValue(key: BenchmarkSettingKey): Promise<string | null> {
const setting = await this.findBy('key', key)
return setting?.value ?? null
}
/**
* Set a setting value by key (creates if not exists)
*/
static async setValue(key: BenchmarkSettingKey, value: string | null): Promise<BenchmarkSetting> {
const setting = await this.firstOrCreate({ key }, { key, value })
if (setting.value !== value) {
setting.value = value
await setting.save()
}
return setting
}
/**
* Get all benchmark settings as a typed object
*/
static async getAllSettings(): Promise<{
allow_anonymous_submission: boolean
installation_id: string | null
last_benchmark_run: string | null
}> {
const settings = await this.all()
const map = new Map(settings.map((s) => [s.key, s.value]))
return {
allow_anonymous_submission: map.get('allow_anonymous_submission') === 'true',
installation_id: map.get('installation_id') ?? null,
last_benchmark_run: map.get('last_benchmark_run') ?? null,
}
}
}