mirror of
https://github.com/Crosstalk-Solutions/project-nomad.git
synced 2026-03-28 03:29:25 +01:00
* feat(benchmark): Require full benchmark with AI for community sharing Only allow users to share benchmark results with the community leaderboard when they have completed a full benchmark that includes AI performance data. Frontend changes: - Add AI Assistant installation check via service API query - Show pre-flight warning when clicking Full Benchmark without AI installed - Disable AI Only button when AI Assistant not installed - Show "Partial Benchmark" info alert for non-shareable results - Only display "Share with Community" for full benchmarks with AI data - Add note about AI installation requirement with link to Apps page Backend changes: - Validate benchmark_type is 'full' before allowing submission - Require ai_tokens_per_second > 0 for community submission - Return clear error messages explaining requirements Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(benchmark): UI improvements and GPU detection fix - Fix GPU detection to properly identify AMD discrete GPUs - Fix gauge colors (high scores now green, low scores red) - Fix gauge centering (SVG size matches container) - Add info tooltips for Tokens/sec and Time to First Token Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(benchmark): Extract iGPU from AMD APU CPU name as fallback When systeminformation doesn't detect graphics controllers (common on headless Linux), extract the integrated GPU name from AMD APU CPU model strings like "AMD Ryzen AI 9 HX 370 w/ Radeon 890M". Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(benchmark): Add Builder Tag system for community leaderboard - Add builder_tag column to benchmark_results table - Create BuilderTagSelector component with word dropdowns + randomize - Add 50 adjectives and 50 nouns for NOMAD-themed tags (e.g., Tactical-Llama-1234) - Add anonymous sharing option checkbox - Add builder tag display in Benchmark Details section - Add Benchmark History section showing all past benchmarks - Update submission API to accept anonymous flag - Add /api/benchmark/builder-tag endpoint to update tags Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(benchmark): Add HMAC signing for leaderboard submissions Sign benchmark submissions with HMAC-SHA256 to prevent casual API abuse. Includes X-NOMAD-Timestamp and X-NOMAD-Signature headers. Note: Since NOMAD is open source, a determined attacker could extract the secret. This provides protection against casual abuse only. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
144 lines
5.8 KiB
TypeScript
144 lines
5.8 KiB
TypeScript
/*
|
|
|--------------------------------------------------------------------------
|
|
| Routes file
|
|
|--------------------------------------------------------------------------
|
|
|
|
|
| The routes file is used for defining the HTTP routes.
|
|
|
|
|
*/
|
|
import BenchmarkController from '#controllers/benchmark_controller'
|
|
import DocsController from '#controllers/docs_controller'
|
|
import DownloadsController from '#controllers/downloads_controller'
|
|
import EasySetupController from '#controllers/easy_setup_controller'
|
|
import HomeController from '#controllers/home_controller'
|
|
import MapsController from '#controllers/maps_controller'
|
|
import OpenWebUIController from '#controllers/openwebui_controller'
|
|
import SettingsController from '#controllers/settings_controller'
|
|
import SystemController from '#controllers/system_controller'
|
|
import ZimController from '#controllers/zim_controller'
|
|
import router from '@adonisjs/core/services/router'
|
|
import transmit from '@adonisjs/transmit/services/main'
|
|
|
|
transmit.registerRoutes()
|
|
|
|
router.get('/', [HomeController, 'index'])
|
|
router.get('/home', [HomeController, 'home'])
|
|
router.on('/about').renderInertia('about')
|
|
router.get('/maps', [MapsController, 'index'])
|
|
|
|
router.get('/easy-setup', [EasySetupController, 'index'])
|
|
router.get('/easy-setup/complete', [EasySetupController, 'complete'])
|
|
router.get('/api/easy-setup/curated-categories', [EasySetupController, 'listCuratedCategories'])
|
|
|
|
router
|
|
.group(() => {
|
|
router.get('/system', [SettingsController, 'system'])
|
|
router.get('/apps', [SettingsController, 'apps'])
|
|
router.get('/legal', [SettingsController, 'legal'])
|
|
router.get('/maps', [SettingsController, 'maps'])
|
|
router.get('/models', [SettingsController, 'models'])
|
|
router.get('/update', [SettingsController, 'update'])
|
|
router.get('/zim', [SettingsController, 'zim'])
|
|
router.get('/zim/remote-explorer', [SettingsController, 'zimRemote'])
|
|
router.get('/benchmark', [SettingsController, 'benchmark'])
|
|
})
|
|
.prefix('/settings')
|
|
|
|
router
|
|
.group(() => {
|
|
router.get('/:slug', [DocsController, 'show'])
|
|
router.get('/', ({ inertia }) => {
|
|
return inertia.render('Docs/Index', {
|
|
title: 'Documentation',
|
|
content: 'Welcome to the documentation!',
|
|
})
|
|
})
|
|
})
|
|
.prefix('/docs')
|
|
|
|
router
|
|
.group(() => {
|
|
router.get('/regions', [MapsController, 'listRegions'])
|
|
router.get('/styles', [MapsController, 'styles'])
|
|
router.get('/preflight', [MapsController, 'checkBaseAssets'])
|
|
router.get('/curated-collections', [MapsController, 'listCuratedCollections'])
|
|
router.post('/fetch-latest-collections', [MapsController, 'fetchLatestCollections'])
|
|
router.post('/download-base-assets', [MapsController, 'downloadBaseAssets'])
|
|
router.post('/download-remote', [MapsController, 'downloadRemote'])
|
|
router.post('/download-remote-preflight', [MapsController, 'downloadRemotePreflight'])
|
|
router.post('/download-collection', [MapsController, 'downloadCollection'])
|
|
router.delete('/:filename', [MapsController, 'delete'])
|
|
})
|
|
.prefix('/api/maps')
|
|
|
|
router
|
|
.group(() => {
|
|
router.get('/list', [DocsController, 'list'])
|
|
})
|
|
.prefix('/api/docs')
|
|
|
|
router
|
|
.group(() => {
|
|
router.get('/jobs', [DownloadsController, 'index'])
|
|
router.get('/jobs/:filetype', [DownloadsController, 'filetype'])
|
|
})
|
|
.prefix('/api/downloads')
|
|
|
|
router.get('/api/health', () => {
|
|
return { status: 'ok' }
|
|
})
|
|
|
|
router
|
|
.group(() => {
|
|
router.get('/models', [OpenWebUIController, 'models'])
|
|
router.get('/installed-models', [OpenWebUIController, 'installedModels'])
|
|
router.post('/download-model', [OpenWebUIController, 'dispatchModelDownload'])
|
|
router.post('/delete-model', [OpenWebUIController, 'deleteModel'])
|
|
})
|
|
.prefix('/api/openwebui')
|
|
|
|
router
|
|
.group(() => {
|
|
router.get('/info', [SystemController, 'getSystemInfo'])
|
|
router.get('/internet-status', [SystemController, 'getInternetStatus'])
|
|
router.get('/services', [SystemController, 'getServices'])
|
|
router.post('/services/affect', [SystemController, 'affectService'])
|
|
router.post('/services/install', [SystemController, 'installService'])
|
|
router.post('/services/force-reinstall', [SystemController, 'forceReinstallService'])
|
|
router.get('/latest-version', [SystemController, 'checkLatestVersion'])
|
|
router.post('/update', [SystemController, 'requestSystemUpdate'])
|
|
router.get('/update/status', [SystemController, 'getSystemUpdateStatus'])
|
|
router.get('/update/logs', [SystemController, 'getSystemUpdateLogs'])
|
|
})
|
|
.prefix('/api/system')
|
|
|
|
router
|
|
.group(() => {
|
|
router.get('/list', [ZimController, 'list'])
|
|
router.get('/list-remote', [ZimController, 'listRemote'])
|
|
router.get('/curated-collections', [ZimController, 'listCuratedCollections'])
|
|
router.post('/fetch-latest-collections', [ZimController, 'fetchLatestCollections'])
|
|
router.post('/download-remote', [ZimController, 'downloadRemote'])
|
|
router.post('/download-collection', [ZimController, 'downloadCollection'])
|
|
router.post('/save-installed-tier', [ZimController, 'saveInstalledTier'])
|
|
router.delete('/:filename', [ZimController, 'delete'])
|
|
})
|
|
.prefix('/api/zim')
|
|
|
|
router
|
|
.group(() => {
|
|
router.post('/run', [BenchmarkController, 'run'])
|
|
router.post('/run/system', [BenchmarkController, 'runSystem'])
|
|
router.post('/run/ai', [BenchmarkController, 'runAI'])
|
|
router.get('/results', [BenchmarkController, 'results'])
|
|
router.get('/results/latest', [BenchmarkController, 'latest'])
|
|
router.get('/results/:id', [BenchmarkController, 'show'])
|
|
router.post('/submit', [BenchmarkController, 'submit'])
|
|
router.post('/builder-tag', [BenchmarkController, 'updateBuilderTag'])
|
|
router.get('/comparison', [BenchmarkController, 'comparison'])
|
|
router.get('/status', [BenchmarkController, 'status'])
|
|
router.get('/settings', [BenchmarkController, 'settings'])
|
|
router.post('/settings', [BenchmarkController, 'updateSettings'])
|
|
})
|
|
.prefix('/api/benchmark')
|