From 881148357efd38e0a159f696710261bac7004a04 Mon Sep 17 00:00:00 2001 From: RaymondVerhoef Date: Fri, 22 May 2026 20:00:47 +0200 Subject: [PATCH] refactor: remove Diagnostics component and related LLM call telemetry --- src/components/admin/Diagnostics.jsx | 162 --------------------------- src/lib/db.js | 11 -- src/pages/Admin/index.jsx | 12 +- 3 files changed, 1 insertion(+), 184 deletions(-) delete mode 100644 src/components/admin/Diagnostics.jsx diff --git a/src/components/admin/Diagnostics.jsx b/src/components/admin/Diagnostics.jsx deleted file mode 100644 index d39dd18..0000000 --- a/src/components/admin/Diagnostics.jsx +++ /dev/null @@ -1,162 +0,0 @@ -import { useEffect, useState } from 'react'; -import { RefreshCw, AlertCircle, CheckCircle2 } from 'lucide-react'; -import Card from '../ui/Card'; -import Button from '../ui/Button'; -import Tag from '../ui/Tag'; -import * as db from '../../lib/db'; - -// Public Anthropic pricing per 1M tokens. Update manually when prices change. -const PRICES = { - 'claude-haiku-4-5-20251001': { input: 1.0, output: 5.0, cache_read: 0.10, cache_write: 1.25 }, - 'claude-haiku-4-5': { input: 1.0, output: 5.0, cache_read: 0.10, cache_write: 1.25 }, - 'claude-sonnet-4-6': { input: 3.0, output: 15.0, cache_read: 0.30, cache_write: 3.75 }, - 'claude-opus-4-7': { input: 15.0, output: 75.0, cache_read: 1.50, cache_write: 18.75 }, -}; - -function pricesFor(model) { - if (!model) return null; - if (PRICES[model]) return PRICES[model]; - if (model.includes('haiku')) return PRICES['claude-haiku-4-5']; - if (model.includes('sonnet')) return PRICES['claude-sonnet-4-6']; - if (model.includes('opus')) return PRICES['claude-opus-4-7']; - return null; -} - -function costUsd(row) { - const p = pricesFor(row.model); - if (!p) return null; - const inTok = (row.input_tokens || 0) - (row.cache_read_tokens || 0) - (row.cache_create_tokens || 0); - const out = row.output_tokens || 0; - const cr = row.cache_read_tokens || 0; - const cc = row.cache_create_tokens || 0; - const usd = (Math.max(inTok, 0) * p.input + out * p.output + cr * p.cache_read + cc * p.cache_write) / 1_000_000; - return usd; -} - -function fmtUsd(n) { - if (n == null) return '—'; - if (n < 0.0001) return '<$0.0001'; - return `$${n.toFixed(4)}`; -} - -function fmtMs(n) { - if (n == null) return '—'; - if (n < 1000) return `${Math.round(n)}ms`; - return `${(n / 1000).toFixed(1)}s`; -} - -const Diagnostics = () => { - const [rows, setRows] = useState([]); - const [loading, setLoading] = useState(false); - - const load = async () => { - setLoading(true); - try { - const r = await db.getRecentLlmCalls(100); - setRows(r); - } finally { - setLoading(false); - } - }; - - useEffect(() => { load(); }, []); - - const totals = rows.reduce((acc, r) => { - acc.input += r.input_tokens || 0; - acc.output += r.output_tokens || 0; - acc.cacheRead += r.cache_read_tokens || 0; - acc.cacheCreate += r.cache_create_tokens || 0; - const c = costUsd(r); - if (c != null) acc.cost += c; - acc.duration += r.duration_ms || 0; - if (r.ok) acc.ok++; - else acc.fail++; - return acc; - }, { input: 0, output: 0, cacheRead: 0, cacheCreate: 0, cost: 0, duration: 0, ok: 0, fail: 0 }); - - const cacheHitRate = totals.input > 0 - ? Math.round((totals.cacheRead / totals.input) * 100) - : 0; - - return ( -
-
-

- Laatste 100 LLM-aanroepen. Kosten worden lokaal berekend met publieke Anthropic-prijzen (handmatig verversen). -

- -
- -
- -

Calls

-

{rows.length}

-

{totals.ok} ok · {totals.fail} fail

-
- -

Tokens (in/out)

-

{totals.input.toLocaleString()} / {totals.output.toLocaleString()}

-

cache read: {totals.cacheRead.toLocaleString()} ({cacheHitRate}%)

-
- -

Geschatte kosten

-

{fmtUsd(totals.cost)}

-

over deze 100 aanroepen

-
- -

Gem. duur

-

{rows.length ? fmtMs(totals.duration / rows.length) : '—'}

-
-
- - -
- - - - - - - - - - - - - - - - - {rows.length === 0 ? ( - - ) : rows.map(r => ( - - - - - - - - - - - - - ))} - -
TijdTaskTierModelInOutCache$DuurStatus
Nog geen aanroepen geregistreerd.
- {r.created ? new Date(r.created).toLocaleString() : '—'} - {r.task || '—'}{r.tier || '—'}{r.model || '—'}{(r.input_tokens || 0).toLocaleString()}{(r.output_tokens || 0).toLocaleString()}{(r.cache_read_tokens || 0).toLocaleString()}{fmtUsd(costUsd(r))}{fmtMs(r.duration_ms)} - {r.ok - ? ok - : {(r.error_msg || r.stop_reason || 'fail').slice(0, 24)}} -
-
-
-
- ); -}; - -export default Diagnostics; diff --git a/src/lib/db.js b/src/lib/db.js index 7c91242..dd8e05c 100644 --- a/src/lib/db.js +++ b/src/lib/db.js @@ -299,17 +299,6 @@ export async function bulkSetCurriculum(year, weeks) { ); } -// ── LLM Call Telemetry ─────────────────────────────────────────────────────── - -export async function getRecentLlmCalls(limit = 100) { - try { - const r = await pb.collection('llm_calls').getList(1, limit, { sort: '-created' }); - return r.items; - } catch { - return []; - } -} - // ── Reset for Smoke Testing ────────────────────────────────────────────────── /** diff --git a/src/pages/Admin/index.jsx b/src/pages/Admin/index.jsx index 8ddb76a..9a587d6 100644 --- a/src/pages/Admin/index.jsx +++ b/src/pages/Admin/index.jsx @@ -1,5 +1,5 @@ import { useState, useEffect } from 'react'; -import { Database, FileText, Settings, Users, Network, Clock, CheckCircle2, AlertCircle, Save, Info, Layers, CheckSquare, CalendarDays, Activity, RefreshCw, AlertTriangle } from 'lucide-react'; +import { Database, FileText, Settings, Users, Network, Clock, CheckCircle2, AlertCircle, Save, Info, Layers, CheckSquare, CalendarDays, RefreshCw, AlertTriangle } from 'lucide-react'; import Card from '../../components/ui/Card'; import Tag from '../../components/ui/Tag'; import Button from '../../components/ui/Button'; @@ -12,7 +12,6 @@ import ContentManager from '../../components/admin/ContentManager'; import TestManager from '../../components/admin/TestManager'; import TeamManager from '../../components/admin/TeamManager'; import CurriculumManager from '../../components/admin/CurriculumManager'; -import Diagnostics from '../../components/admin/Diagnostics'; import { Trash2 } from 'lucide-react'; const TIER_PLACEHOLDERS = { @@ -93,7 +92,6 @@ const Admin = () => { { key: 'curriculum', icon: CalendarDays, label: 'Curriculum' }, { key: 'graph', icon: Network, label: 'Graph' }, { key: 'team', icon: Users, label: 'Team' }, - { key: 'diagnostics', icon: Activity, label: 'Diagnostics' }, { key: 'settings', icon: Settings, label: 'Settings', bottom: true }, ]; @@ -204,14 +202,6 @@ const Admin = () => { )} - {activeTab === 'diagnostics' && ( -
-

Diagnostics

-

LLM-aanroepen, tokenverbruik en geschatte kosten.

- -
- )} - {activeTab === 'settings' && (

Settings