Initial commit: RA-H Open Source Edition
Local-first knowledge management system with BYO API keys. Features: - 3-panel UI (Nodes | Focus | Helpers) - SQLite + sqlite-vec for vector search - Agent system (Easy/Hard mode orchestrators) - Content extraction (YouTube, PDF, web) - Integrate workflow for connection discovery - Dimension system with auto-assignment Tech stack: - Next.js 15 + TypeScript + Tailwind CSS - Anthropic (Claude) + OpenAI (GPT) via Vercel AI SDK Setup: npm install && npm rebuild better-sqlite3 scripts/dev/bootstrap-local.sh npm run dev MIT License
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import type { CacheStats } from '@/types/prompts';
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line no-var
|
||||
var lastCacheStats: CacheStats | undefined;
|
||||
}
|
||||
|
||||
export async function GET() {
|
||||
try {
|
||||
const stats = global.lastCacheStats;
|
||||
|
||||
if (!stats) {
|
||||
return NextResponse.json({
|
||||
error: 'No cache statistics available yet',
|
||||
message: 'Send a message to ra-h to generate cache stats'
|
||||
}, { status: 404 });
|
||||
}
|
||||
|
||||
const hitRate = stats.cacheReadInputTokens > 0 ? 'HIT' : 'MISS';
|
||||
const totalInputTokens = stats.inputTokens + stats.cacheCreationInputTokens + stats.cacheReadInputTokens;
|
||||
|
||||
// Cost calculation (Sonnet 4.5 pricing)
|
||||
const baseCost = 3.0; // $3 per million input tokens
|
||||
const writeCost = baseCost * 1.25; // $3.75 per million
|
||||
const readCost = baseCost * 0.1; // $0.30 per million
|
||||
|
||||
const actualCost = (
|
||||
(stats.inputTokens * baseCost) +
|
||||
(stats.cacheCreationInputTokens * writeCost) +
|
||||
(stats.cacheReadInputTokens * readCost)
|
||||
) / 1_000_000;
|
||||
|
||||
const noCacheCost = (totalInputTokens * baseCost) / 1_000_000;
|
||||
const costSavingsPercentage = noCacheCost > 0
|
||||
? Math.round(((noCacheCost - actualCost) / noCacheCost) * 100)
|
||||
: 0;
|
||||
|
||||
return NextResponse.json({
|
||||
status: 'success',
|
||||
timestamp: new Date().toISOString(),
|
||||
lastRequest: {
|
||||
hitRate,
|
||||
tokens: {
|
||||
cacheWrite: stats.cacheCreationInputTokens,
|
||||
cacheRead: stats.cacheReadInputTokens,
|
||||
regular: stats.inputTokens,
|
||||
totalInput: totalInputTokens,
|
||||
output: stats.outputTokens
|
||||
},
|
||||
savings: {
|
||||
tokenPercentage: stats.savingsPercentage,
|
||||
costPercentage: costSavingsPercentage,
|
||||
actualCostUSD: actualCost.toFixed(6),
|
||||
noCacheCostUSD: noCacheCost.toFixed(6),
|
||||
savedUSD: (noCacheCost - actualCost).toFixed(6)
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
return NextResponse.json(
|
||||
{ error: 'Failed to fetch cache stats', details: errorMessage },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user