feat(integrations): add NextJS LLM/Grafana integration + enable dashboard embedding
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
* NextJS Integration for Homelab LLM & Grafana
|
||||
*
|
||||
* ═══════════════════════════════════════════════════════════════════════════════
|
||||
* SETUP
|
||||
* ═══════════════════════════════════════════════════════════════════════════════
|
||||
*
|
||||
* 1. Copy files to your NextJS project:
|
||||
* cp integrations/nextjs/*.ts your-nextjs-app/lib/
|
||||
*
|
||||
* 2. Environment variables (.env.local):
|
||||
* LLM_BASE_URL=https://api.riotpiao.com/v1
|
||||
* GRAFANA_URL=https://grafana.riotpiao.com
|
||||
* GRAFANA_API_TOKEN=<service-account-token>
|
||||
* NEXT_PUBLIC_GRAFANA_URL=https://grafana.riotpiao.com
|
||||
*
|
||||
* 3. Create Grafana service account (for API access):
|
||||
* - Grafana UI > Administration > Service Accounts
|
||||
* - Create account with Viewer role
|
||||
* - Generate token, save to GRAFANA_API_TOKEN
|
||||
*
|
||||
* 4. Copy API routes (see api-routes.ts for templates):
|
||||
* - app/api/chat/route.ts (LLM chat endpoint)
|
||||
* - app/api/metrics/route.ts (Grafana metrics proxy)
|
||||
*
|
||||
* ═══════════════════════════════════════════════════════════════════════════════
|
||||
* USAGE EXAMPLES
|
||||
* ═══════════════════════════════════════════════════════════════════════════════
|
||||
*
|
||||
* Server-side (API routes, server components):
|
||||
*
|
||||
* import { chat, streamChat } from '@/lib/llm-client';
|
||||
* import { getLLMMetrics, getDashboard } from '@/lib/grafana-client';
|
||||
*
|
||||
* // Non-streaming chat
|
||||
* const response = await chat({
|
||||
* model: 'reasoning',
|
||||
* messages: [{ role: 'user', content: 'Hello' }],
|
||||
* });
|
||||
*
|
||||
* // Streaming chat
|
||||
* for await (const chunk of streamChat({ model: 'reasoning', messages })) {
|
||||
* process.stdout.write(chunk);
|
||||
* }
|
||||
*
|
||||
* // Get LLM pod metrics
|
||||
* const metrics = await getLLMMetrics();
|
||||
* console.log(`Pods ready: ${metrics.podsReady}`);
|
||||
*
|
||||
* Client-side (React components):
|
||||
*
|
||||
* import { useChat, useLLMMetrics, useGrafanaEmbed } from '@/lib/hooks';
|
||||
*
|
||||
* function ChatUI() {
|
||||
* const { messages, send, isLoading } = useChat({ model: 'reasoning' });
|
||||
*
|
||||
* return (
|
||||
* <div>
|
||||
* {messages.map((m, i) => <p key={i}>{m.role}: {m.content}</p>)}
|
||||
* <button onClick={() => send('Hello')} disabled={isLoading}>
|
||||
* Send
|
||||
* </button>
|
||||
* </div>
|
||||
* );
|
||||
* }
|
||||
*
|
||||
* function MetricsDashboard() {
|
||||
* const { metrics, isLoading } = useLLMMetrics(30000);
|
||||
* const { iframeProps } = useGrafanaEmbed('llm-frontend', 2);
|
||||
*
|
||||
* if (isLoading) return <p>Loading...</p>;
|
||||
*
|
||||
* return (
|
||||
* <div>
|
||||
* <p>Pods ready: {metrics?.podsReady}</p>
|
||||
* {iframeProps && <iframe {...iframeProps} />}
|
||||
* </div>
|
||||
* );
|
||||
* }
|
||||
*
|
||||
* ═══════════════════════════════════════════════════════════════════════════════
|
||||
* AVAILABLE MODELS
|
||||
* ═══════════════════════════════════════════════════════════════════════════════
|
||||
*
|
||||
* | model | Engine | Notes |
|
||||
* |--------------------|---------|--------------------------------|
|
||||
* | reasoning | vLLM | Qwen3-32B, best for complex |
|
||||
* | ornith:35b | Ollama | General purpose |
|
||||
* | qwen2.5:3b-instruct| Ollama | Fast, smaller tasks |
|
||||
*
|
||||
* ═══════════════════════════════════════════════════════════════════════════════
|
||||
* GRAFANA EMBEDDING (optional, requires config change)
|
||||
* ═══════════════════════════════════════════════════════════════════════════════
|
||||
*
|
||||
* To enable iframe embedding, add to grafana.ini:
|
||||
* security:
|
||||
* allow_embedding: true
|
||||
*
|
||||
* Or via Helm values (k8s/infra/logging/grafana-values.yaml):
|
||||
* grafana.ini:
|
||||
* security:
|
||||
* allow_embedding: true
|
||||
*
|
||||
* Panel embed URLs follow pattern:
|
||||
* https://grafana.riotpiao.com/d-solo/llm-frontend?panelId=2&from=now-6h&to=now
|
||||
*
|
||||
* Dashboard UID for LLM: llm-frontend
|
||||
* Panel IDs: 2 (pods ready), 11 (CPU), 12 (Memory), 13 (Restarts)
|
||||
*/
|
||||
|
||||
// Re-export all modules
|
||||
export * from './llm-client';
|
||||
export * from './grafana-client';
|
||||
export * from './hooks';
|
||||
Reference in New Issue
Block a user