Skip to content

Commit a6ebb41

Browse files
committed
Feature: fine-tuning and model chat eval
Signed-off-by: Brent Salisbury <[email protected]>
1 parent b0fbfab commit a6ebb41

File tree

24 files changed

+6568
-3659
lines changed

24 files changed

+6568
-3659
lines changed

package-lock.json

Lines changed: 4067 additions & 3658 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,16 @@
1919
"dependencies": {
2020
"@fortawesome/fontawesome-svg-core": "^6.7.2",
2121
"@next/env": "^15.1.4",
22+
"@patternfly/chatbot": "^2.1.0-prerelease.17",
2223
"@patternfly/react-core": "^6.1.0",
2324
"@patternfly/react-icons": "^6.0.0",
2425
"@patternfly/react-styles": "^6.0.0",
2526
"axios": "^1.7.9",
27+
"@patternfly/react-table": "^6.1.0",
28+
"@patternfly/virtual-assistant": "^2.0.2",
29+
"date-fns": "^4.1.0",
30+
"dompurify": "^3.2.3",
31+
"fs": "^0.0.1-security",
2632
"isomorphic-git": "^1.29.0",
2733
"js-yaml": "^4.1.0",
2834
"next": "^15.1.3",
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// src/pages/api/fine-tune/data-sets.ts
2+
'use server';
3+
4+
import { NextRequest, NextResponse } from 'next/server';
5+
6+
export async function GET(req: NextRequest) {
7+
try {
8+
const API_SERVER = process.env.NEXT_PUBLIC_API_SERVER!;
9+
10+
const response = await fetch(`${API_SERVER}/data`);
11+
const data = await response.json();
12+
13+
if (!response.ok) {
14+
return NextResponse.json({ error: 'Failed to fetch datasets' }, { status: response.status });
15+
}
16+
17+
return NextResponse.json(data, { status: 200 });
18+
} catch (error) {
19+
console.error('Error fetching datasets:', error);
20+
return NextResponse.json({ error: 'Internal Server Error' }, { status: 500 });
21+
}
22+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
'use server';
2+
3+
import { NextResponse } from 'next/server';
4+
5+
export async function POST(request: Request) {
6+
try {
7+
const API_SERVER = process.env.NEXT_PUBLIC_API_SERVER!;
8+
9+
const response = await fetch(`${API_SERVER}/data/generate`, {
10+
method: 'POST'
11+
});
12+
13+
if (!response.ok) {
14+
console.error('Error response from API server:', response.status, response.statusText);
15+
return NextResponse.json({ error: 'Failed to generate data' }, { status: response.status });
16+
}
17+
18+
const responseData = await response.json();
19+
20+
return NextResponse.json(responseData, { status: 200 });
21+
} catch (error) {
22+
console.error('Error generating data:', error);
23+
return NextResponse.json({ error: 'An error occurred while generating data' }, { status: 500 });
24+
}
25+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// src/app/api/native/fine-tune/git/branches/route.ts
2+
import { NextResponse } from 'next/server';
3+
import * as git from 'isomorphic-git';
4+
import fs from 'fs';
5+
import path from 'path';
6+
7+
const REMOTE_TAXONOMY_ROOT_DIR = process.env.NEXT_PUBLIC_TAXONOMY_ROOT_DIR || '';
8+
9+
export async function GET() {
10+
const REPO_DIR = path.join(REMOTE_TAXONOMY_ROOT_DIR, '/taxonomy');
11+
try {
12+
console.log(`Checking local taxonomy directory for branches: ${REPO_DIR}`);
13+
14+
// Ensure the repository path exists
15+
if (!fs.existsSync(REPO_DIR)) {
16+
console.log('Local repository path does not exist:', REPO_DIR);
17+
return NextResponse.json({ error: 'Local repository path does not exist.' }, { status: 400 });
18+
}
19+
20+
console.log('Local taxonomy directory exists. Proceeding with branch listing.');
21+
22+
// List all branches in the repository
23+
const branches = await git.listBranches({ fs, dir: REPO_DIR });
24+
console.log(`Branches found: ${branches.join(', ')}`);
25+
26+
const branchDetails = [];
27+
28+
for (const branch of branches) {
29+
const branchCommit = await git.resolveRef({
30+
fs,
31+
dir: REPO_DIR,
32+
ref: branch
33+
});
34+
const commitDetails = await git.readCommit({
35+
fs,
36+
dir: REPO_DIR,
37+
oid: branchCommit
38+
});
39+
40+
const commitMessage = commitDetails.commit.message;
41+
42+
// Check for Signed-off-by line
43+
const signoffMatch = commitMessage.match(/^Signed-off-by: (.+)$/m);
44+
const signoff = signoffMatch ? signoffMatch[1] : null;
45+
const messageStr = commitMessage.split('Signed-off-by');
46+
47+
branchDetails.push({
48+
name: branch,
49+
creationDate: commitDetails.commit.committer.timestamp * 1000,
50+
message: messageStr[0].replace(/\n+$/, ''),
51+
author: signoff
52+
});
53+
}
54+
55+
// Sort by creation date, newest first
56+
branchDetails.sort((a, b) => b.creationDate - a.creationDate);
57+
58+
console.log('Total branches present in native taxonomy (fine-tune):', branchDetails.length);
59+
60+
return NextResponse.json({ branches: branchDetails }, { status: 200 });
61+
} catch (error) {
62+
console.error('Failed to list branches from local taxonomy (fine-tune):', error);
63+
return NextResponse.json({ error: 'Failed to list branches from local taxonomy (fine-tune)' }, { status: 500 });
64+
}
65+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// src/app/api/fine-tune/gpu-free/route.ts
2+
'use server';
3+
4+
import { NextResponse } from 'next/server';
5+
6+
export async function GET() {
7+
try {
8+
const API_SERVER = process.env.NEXT_PUBLIC_API_SERVER!;
9+
const endpoint = `${API_SERVER}/gpu-free`;
10+
11+
const resp = await fetch(endpoint);
12+
if (!resp.ok) {
13+
console.error('gpu-free error from API server:', resp.status, resp.statusText);
14+
return NextResponse.json({ free_gpus: 0 }, { status: 200 });
15+
// Return 0 in case of error
16+
}
17+
18+
const data = await resp.json();
19+
return NextResponse.json(data, { status: 200 });
20+
} catch (error) {
21+
console.error('Unexpected error in gpu-free route:', error);
22+
return NextResponse.json({ free_gpus: 0 }, { status: 200 });
23+
}
24+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// src/app/api/fine-tune/jobs/[job_id]/logs/route.ts
2+
import { NextResponse } from 'next/server';
3+
4+
const API_SERVER = process.env.NEXT_PUBLIC_API_SERVER!;
5+
6+
export async function GET(request: Request, { params }: { params: { job_id: string } }) {
7+
const { job_id } = await Promise.resolve(params);
8+
9+
try {
10+
const response = await fetch(`${API_SERVER}/jobs/${job_id}/logs`, {
11+
method: 'GET'
12+
});
13+
14+
if (!response.ok) {
15+
const errorText = await response.text();
16+
console.error('Error from API server:', errorText);
17+
return NextResponse.json({ error: 'Error fetching logs' }, { status: 500 });
18+
}
19+
20+
const logs = await response.text();
21+
return new NextResponse(logs, {
22+
status: 200,
23+
headers: { 'Content-Type': 'text/plain' }
24+
});
25+
} catch (error) {
26+
console.error('Error fetching logs:', error);
27+
return NextResponse.json({ error: 'Error fetching logs' }, { status: 500 });
28+
}
29+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// src/app/api/fine-tune/jobs/[job_id]/status/route.ts
2+
'use server';
3+
4+
import { NextResponse } from 'next/server';
5+
6+
export async function GET(request: Request, { params }: { params: { job_id: string } }) {
7+
const { job_id } = params;
8+
const API_SERVER = process.env.NEXT_PUBLIC_API_SERVER!;
9+
10+
try {
11+
// Forward the request to the API server
12+
const response = await fetch(`${API_SERVER}/jobs/${job_id}/status`, {
13+
method: 'GET'
14+
});
15+
16+
if (!response.ok) {
17+
const errorText = await response.text();
18+
console.error('Error from API server:', errorText);
19+
return NextResponse.json({ error: 'Error fetching job status' }, { status: 500 });
20+
}
21+
22+
const result = await response.json();
23+
// Return the job status to the client
24+
return NextResponse.json(result, { status: 200 });
25+
} catch (error) {
26+
console.error('Error fetching job status:', error);
27+
return NextResponse.json({ error: 'Error fetching job status' }, { status: 500 });
28+
}
29+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// src/app/api/fine-tune/jobs/route.ts
2+
'use server';
3+
4+
import { NextResponse } from 'next/server';
5+
6+
export async function GET(request: Request) {
7+
const API_SERVER = process.env.NEXT_PUBLIC_API_SERVER!;
8+
9+
try {
10+
const response = await fetch(`${API_SERVER}/jobs`);
11+
if (!response.ok) {
12+
const errorText = await response.text();
13+
console.error('Error from API server:', errorText);
14+
return NextResponse.json({ error: 'Error fetching jobs' }, { status: 500 });
15+
}
16+
const result = await response.json();
17+
return NextResponse.json(result, { status: 200 });
18+
} catch (error) {
19+
console.error('Error fetching jobs:', error);
20+
return NextResponse.json({ error: 'Error fetching jobs' }, { status: 500 });
21+
}
22+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// src/app/api/model/serve-base/route.ts
2+
'use server';
3+
4+
import { NextResponse } from 'next/server';
5+
6+
export async function POST() {
7+
try {
8+
console.log('Received serve-base model request');
9+
10+
const API_SERVER = process.env.NEXT_PUBLIC_API_SERVER!;
11+
const endpoint = `${API_SERVER}/model/serve-base`;
12+
13+
console.log(`Forwarding request to the API server: ${endpoint}`);
14+
15+
// No request body needed for serving the base model
16+
const response = await fetch(endpoint, {
17+
method: 'POST',
18+
headers: { 'Content-Type': 'application/json' }
19+
});
20+
21+
console.log('Response from API server (serve-base):', {
22+
status: response.status,
23+
statusText: response.statusText
24+
});
25+
26+
if (!response.ok) {
27+
console.error('Error response from the API server:', response.status, response.statusText);
28+
return NextResponse.json({ error: 'Failed to serve the base model on the API server' }, { status: response.status });
29+
}
30+
31+
// Parse response safely
32+
let responseData;
33+
try {
34+
const text = await response.text();
35+
responseData = text ? JSON.parse(text) : {};
36+
console.log('Parsed response data (serve-base):', responseData);
37+
} catch (error) {
38+
console.error('Error parsing JSON response from API server:', error);
39+
return NextResponse.json({ error: 'Invalid JSON response from the API server' }, { status: 500 });
40+
}
41+
42+
if (!responseData.job_id) {
43+
console.error('Missing job_id in API server response for serve-base:', responseData);
44+
return NextResponse.json({ error: 'API server response does not contain job_id' }, { status: 500 });
45+
}
46+
47+
console.log('Returning success response with job_id (serve-base):', responseData.job_id);
48+
return NextResponse.json(responseData, { status: 200 });
49+
} catch (error) {
50+
console.error('Unexpected error during serve-base:', error);
51+
return NextResponse.json({ error: 'An unexpected error occurred during serving the base model' }, { status: 500 });
52+
}
53+
}

0 commit comments

Comments
 (0)