diff --git a/app/api/evaluations/stt/datasets/[dataset_id]/route.ts b/app/api/evaluations/stt/datasets/[dataset_id]/route.ts
index 4455161..add9a77 100644
--- a/app/api/evaluations/stt/datasets/[dataset_id]/route.ts
+++ b/app/api/evaluations/stt/datasets/[dataset_id]/route.ts
@@ -1,4 +1,4 @@
-import { NextResponse, NextRequest } from 'next/server';
+import { NextResponse } from 'next/server';
export async function GET(
request: Request,
@@ -8,6 +8,13 @@ export async function GET(
const backendUrl = process.env.NEXT_PUBLIC_BACKEND_URL || 'http://localhost:8000';
const apiKey = request.headers.get('X-API-KEY');
+ if (!apiKey) {
+ return NextResponse.json(
+ { success: false, error: 'Unauthorized: Missing API key', data: null },
+ { status: 401 }
+ );
+ }
+
try {
// Get query parameters from the request
const { searchParams } = new URL(request.url);
@@ -19,13 +26,12 @@ export async function GET(
if (includeSamples) backendParams.append('include_samples', includeSamples);
if (includeAudio) backendParams.append('include_audio', includeAudio);
- const backendUrlWithParams = `${backendUrl}/api/v1/evaluations/stt/datasets/${dataset_id}${
- backendParams.toString() ? `?${backendParams.toString()}` : ''
- }`;
+ const backendUrlWithParams = `${backendUrl}/api/v1/evaluations/stt/datasets/${dataset_id}${backendParams.toString() ? `?${backendParams.toString()}` : ''
+ }`;
const response = await fetch(backendUrlWithParams, {
headers: {
- 'X-API-KEY': apiKey || '',
+ 'X-API-KEY': apiKey,
},
});
diff --git a/app/api/evaluations/tts/datasets/[dataset_id]/route.ts b/app/api/evaluations/tts/datasets/[dataset_id]/route.ts
new file mode 100644
index 0000000..309b178
--- /dev/null
+++ b/app/api/evaluations/tts/datasets/[dataset_id]/route.ts
@@ -0,0 +1,33 @@
+import { NextResponse } from 'next/server';
+
+export async function GET(
+ request: Request,
+ { params }: { params: Promise<{ dataset_id: string }> }
+) {
+ const { dataset_id } = await params;
+ const backendUrl = process.env.NEXT_PUBLIC_BACKEND_URL || 'http://localhost:8000';
+ const apiKey = request.headers.get('X-API-KEY');
+
+ if (!apiKey) {
+ return NextResponse.json(
+ { success: false, error: 'Unauthorized: Missing API key', data: null },
+ { status: 401 }
+ );
+ }
+
+ try {
+ const response = await fetch(`${backendUrl}/api/v1/evaluations/tts/datasets/${dataset_id}`, {
+ headers: {
+ 'X-API-KEY': apiKey,
+ },
+ });
+
+ const data = await response.json();
+ return NextResponse.json(data, { status: response.status });
+ } catch (error) {
+ return NextResponse.json(
+ { success: false, error: 'Failed to fetch dataset', data: null },
+ { status: 500 }
+ );
+ }
+}
diff --git a/app/api/evaluations/tts/datasets/route.ts b/app/api/evaluations/tts/datasets/route.ts
new file mode 100644
index 0000000..4fe9f11
--- /dev/null
+++ b/app/api/evaluations/tts/datasets/route.ts
@@ -0,0 +1,53 @@
+import { NextResponse, NextRequest } from 'next/server';
+
+export async function GET(request: Request) {
+ const backendUrl = process.env.NEXT_PUBLIC_BACKEND_URL || 'http://localhost:8000';
+ const apiKey = request.headers.get('X-API-KEY');
+
+ try {
+ const response = await fetch(`${backendUrl}/api/v1/evaluations/tts/datasets`, {
+ headers: {
+ 'X-API-KEY': apiKey || '',
+ },
+ });
+
+ const data = await response.json();
+ return NextResponse.json(data, { status: response.status });
+ } catch (error) {
+ return NextResponse.json(
+ { success: false, error: error, data: null },
+ { status: 500 }
+ );
+ }
+}
+
+export async function POST(request: NextRequest) {
+ try {
+ const apiKey = request.headers.get('X-API-KEY');
+ if (!apiKey) {
+ return NextResponse.json(
+ { error: 'Missing X-API-KEY. Either generate an API Key. Contact Kaapi team for more details' },
+ { status: 401 }
+ );
+ }
+ const body = await request.json();
+ const backendUrl = process.env.NEXT_PUBLIC_BACKEND_URL || 'http://localhost:8000';
+
+ const response = await fetch(`${backendUrl}/api/v1/evaluations/tts/datasets`, {
+ method: 'POST',
+ body: JSON.stringify(body),
+ headers: {
+ 'X-API-KEY': apiKey,
+ 'Content-Type': 'application/json',
+ },
+ });
+ const data = await response.json();
+ return NextResponse.json(data, { status: response.status });
+ } catch (error) {
+ console.error('Proxy error:', error);
+ return NextResponse.json(
+ { error: 'Failed to forward request to backend', details: error instanceof Error ? error.message : String(error) },
+ { status: 500 }
+ );
+ }
+}
diff --git a/app/api/evaluations/tts/results/[result_id]/route.ts b/app/api/evaluations/tts/results/[result_id]/route.ts
new file mode 100644
index 0000000..126d21e
--- /dev/null
+++ b/app/api/evaluations/tts/results/[result_id]/route.ts
@@ -0,0 +1,63 @@
+import { NextResponse } from 'next/server';
+
+export async function GET(
+ request: Request,
+ { params }: { params: Promise<{ result_id: string }> }
+) {
+ const { result_id } = await params;
+ const backendUrl = process.env.NEXT_PUBLIC_BACKEND_URL || 'http://localhost:8000';
+ const apiKey = request.headers.get('X-API-KEY');
+
+ try {
+ const response = await fetch(`${backendUrl}/api/v1/evaluations/tts/results/${result_id}`, {
+ headers: {
+ 'X-API-KEY': apiKey || '',
+ },
+ });
+
+ const data = await response.json();
+ return NextResponse.json(data, { status: response.status });
+ } catch (error) {
+ return NextResponse.json(
+ { success: false, error: 'Failed to fetch results', data: null },
+ { status: 500 }
+ );
+ }
+}
+
+export async function PATCH(
+ request: Request,
+ { params }: { params: Promise<{ result_id: string }> }
+) {
+ const { result_id } = await params;
+ const backendUrl = process.env.NEXT_PUBLIC_BACKEND_URL || 'http://localhost:8000';
+ const apiKey = request.headers.get('X-API-KEY');
+
+ if (!apiKey) {
+ return NextResponse.json(
+ { error: 'Missing X-API-KEY header' },
+ { status: 401 }
+ );
+ }
+
+ try {
+ const body = await request.json();
+
+ const response = await fetch(`${backendUrl}/api/v1/evaluations/tts/results/${result_id}`, {
+ method: 'PATCH',
+ headers: {
+ 'X-API-KEY': apiKey || '',
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(body),
+ });
+
+ const data = await response.json();
+ return NextResponse.json(data, { status: response.status });
+ } catch (error) {
+ return NextResponse.json(
+ { success: false, error: 'Failed to update result feedback', data: null },
+ { status: 500 }
+ );
+ }
+}
diff --git a/app/api/evaluations/tts/runs/[run_id]/route.ts b/app/api/evaluations/tts/runs/[run_id]/route.ts
new file mode 100644
index 0000000..e782d4a
--- /dev/null
+++ b/app/api/evaluations/tts/runs/[run_id]/route.ts
@@ -0,0 +1,33 @@
+import { NextResponse } from 'next/server';
+
+export async function GET(
+ request: Request,
+ { params }: { params: Promise<{ run_id: string }> }
+) {
+ const { run_id } = await params;
+ const backendUrl = process.env.NEXT_PUBLIC_BACKEND_URL || 'http://localhost:8000';
+ const apiKey = request.headers.get('X-API-KEY');
+
+ const { searchParams } = new URL(request.url);
+ const queryString = searchParams.toString();
+
+ try {
+ const backendUrlWithParams = queryString
+ ? `${backendUrl}/api/v1/evaluations/tts/runs/${run_id}?${queryString}`
+ : `${backendUrl}/api/v1/evaluations/tts/runs/${run_id}`;
+
+ const response = await fetch(backendUrlWithParams, {
+ headers: {
+ 'X-API-KEY': apiKey || '',
+ },
+ });
+
+ const data = await response.json();
+ return NextResponse.json(data, { status: response.status });
+ } catch (error) {
+ return NextResponse.json(
+ { success: false, error: 'Failed to fetch the run', data: null },
+ { status: 500 }
+ );
+ }
+}
diff --git a/app/api/evaluations/tts/runs/route.ts b/app/api/evaluations/tts/runs/route.ts
new file mode 100644
index 0000000..9cd9143
--- /dev/null
+++ b/app/api/evaluations/tts/runs/route.ts
@@ -0,0 +1,53 @@
+import { NextResponse, NextRequest } from 'next/server';
+
+export async function GET(request: Request) {
+ const backendUrl = process.env.NEXT_PUBLIC_BACKEND_URL || 'http://localhost:8000';
+ const apiKey = request.headers.get('X-API-KEY');
+
+ try {
+ const response = await fetch(`${backendUrl}/api/v1/evaluations/tts/runs`, {
+ headers: {
+ 'X-API-KEY': apiKey || '',
+ },
+ });
+
+ const data = await response.json();
+ return NextResponse.json(data, { status: response.status });
+ } catch (error) {
+ return NextResponse.json(
+ { success: false, error: error, data: null },
+ { status: 500 }
+ );
+ }
+}
+
+export async function POST(request: NextRequest) {
+ try {
+ const apiKey = request.headers.get('X-API-KEY');
+ if (!apiKey) {
+ return NextResponse.json(
+ { error: 'Missing X-API-KEY. Either generate an API Key. Contact Kaapi team for more details' },
+ { status: 401 }
+ );
+ }
+ const body = await request.json();
+ const backendUrl = process.env.NEXT_PUBLIC_BACKEND_URL || 'http://localhost:8000';
+
+ const response = await fetch(`${backendUrl}/api/v1/evaluations/tts/runs`, {
+ method: 'POST',
+ body: JSON.stringify(body),
+ headers: {
+ 'X-API-KEY': apiKey,
+ 'Content-Type': 'application/json',
+ },
+ });
+ const data = await response.json();
+ return NextResponse.json(data, { status: response.status });
+ } catch (error) {
+ console.error('Proxy error:', error);
+ return NextResponse.json(
+ { error: 'Failed to forward request to backend', details: error instanceof Error ? error.message : String(error) },
+ { status: 500 }
+ );
+ }
+}
diff --git a/app/components/DetailedResultsTable.tsx b/app/components/DetailedResultsTable.tsx
index 8b7f7ef..f95540a 100644
--- a/app/components/DetailedResultsTable.tsx
+++ b/app/components/DetailedResultsTable.tsx
@@ -118,10 +118,10 @@ export default function DetailedResultsTable({ job }: DetailedResultsTableProps)
Question
- Answer
+ Ground Truth
|
- Ground Truth
+ Answer
|
{scoreNames.map((scoreName) => (
@@ -153,12 +153,12 @@ export default function DetailedResultsTable({ job }: DetailedResultsTableProps)
}}
>
{/* Row Number */}
- |
+ |
{index + 1}
|
{/* Question */}
-
+ |
|
- {/* Answer */}
-
+ {/* Ground Truth */}
+ |
- {answer}
+ {groundTruth}
|
- {/* Ground Truth */}
-
+ {/* Answer */}
+ |
- {groundTruth}
+ {answer}
|
@@ -205,7 +205,7 @@ export default function DetailedResultsTable({ job }: DetailedResultsTableProps)
const { value, color, bg } = formatScoreValue(score);
return (
-
+ |
{/* Question ID - matching row format # column */}
-
+ |
{group.question_id}
|
{/* Question - matching row format text cell */}
-
+ |
{/* Ground Truth - matching row format text cell */}
-
+ |
+
{answer ? (
-
- {tabs.map((tab) => {
- const isActive = activeTab === tab.id;
- return (
-
- );
- })}
-
+
+ {tabs.map((tab) => {
+ const isActive = activeTab === tab.id;
+ return (
+
+ );
+ })}
);
}
diff --git a/app/evaluations/page.tsx b/app/evaluations/page.tsx
index 2b81ec7..b4a633b 100644
--- a/app/evaluations/page.tsx
+++ b/app/evaluations/page.tsx
@@ -9,6 +9,7 @@
"use client"
import { useState, useEffect, useCallback, Suspense } from 'react';
import {format, toZonedTime} from "date-fns-tz"
+import { colors } from '@/app/lib/colors';
import { useRouter, useSearchParams } from 'next/navigation'
import { APIKey } from '../keystore/page';
import { STORAGE_KEY } from '../keystore/page';
@@ -280,7 +281,7 @@ function SimplifiedEvalContent() {
};
return (
-
+
{/* Sidebar - Full Height */}
@@ -288,52 +289,20 @@ function SimplifiedEvalContent() {
{/* Main Content */}
{/* Title Section with Collapse Button */}
-
+
- Evaluations
+ Text Evaluation
+ Compare model response quality on your datasets across different configs
@@ -349,8 +318,8 @@ function SimplifiedEvalContent() {
/>
{/* Tab Content */}
-
-
+
+
{activeTab === 'datasets' ? (
+
{/* API Key Selection Card */}
-
-
- Select API Key
+
+ Select API Key
{/* Dataset Selection Card */}
-
-
- Select QnA Dataset
+
+ Select QnA Dataset
| | | |