-
Notifications
You must be signed in to change notification settings - Fork 41
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Brent Salisbury <[email protected]>
- Loading branch information
Showing
11 changed files
with
1,420 additions
and
1 deletion.
There are no files selected for viewing
31 changes: 31 additions & 0 deletions
31
src/app/api/playground/ragchat/collections/[collectionName]/delete/route.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
'use server'; | ||
|
||
import { NextRequest, NextResponse } from 'next/server'; | ||
import fetch from 'node-fetch'; | ||
|
||
export async function DELETE(req: NextRequest, { params }: { params: { collectionName: string } }) { | ||
const { collectionName } = params; | ||
|
||
try { | ||
console.log(`Deleting collection: ${collectionName}`); | ||
|
||
// Make the API request to the backend to delete the collection | ||
const response = await fetch(`http://127.0.0.1:8000/collections/${encodeURIComponent(collectionName)}`, { | ||
method: 'DELETE' | ||
}); | ||
|
||
// Check if the response was successful | ||
if (!response.ok) { | ||
const errorText = await response.text(); | ||
console.error(`Failed to delete collection: ${errorText}`); | ||
throw new Error(`Failed to delete collection: ${errorText}`); | ||
} | ||
|
||
// Return a success response to the client | ||
console.log(`Collection ${collectionName} deleted successfully.`); | ||
return NextResponse.json({ message: `Collection ${collectionName} deleted successfully.` }, { status: 200 }); | ||
} catch (error: any) { | ||
console.error('Error deleting collection:', error.message); | ||
return NextResponse.json({ error: error.message }, { status: 500 }); | ||
} | ||
} |
47 changes: 47 additions & 0 deletions
47
src/app/api/playground/ragchat/collections/[collectionName]/documents/file/route.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// src/app/api/playground/ragchat/collections/[collectionName]/documents/file/route.ts | ||
'use server'; | ||
|
||
import { NextRequest, NextResponse } from 'next/server'; | ||
import fetch from 'node-fetch'; | ||
import FormData from 'form-data'; | ||
|
||
export async function POST(req: NextRequest, { params }: { params: { collectionName: string } }) { | ||
const { collectionName } = params; | ||
|
||
try { | ||
// Parse the form data from the incoming request | ||
const formData = await req.formData(); | ||
const file = formData.get('files') as File | null; | ||
|
||
if (!file) { | ||
throw new Error('File is required for upload'); | ||
} | ||
|
||
// Create FormData for the backend request | ||
const backendFormData = new FormData(); | ||
|
||
// Convert the file to a Buffer for the Node.js environment | ||
const buffer = Buffer.from(await file.arrayBuffer()); | ||
|
||
// Append the file buffer to FormData | ||
backendFormData.append('file', buffer, file.name); | ||
|
||
// Send the file to the backend service | ||
const backendResponse = await fetch(`http://127.0.0.1:8000/collections/${encodeURIComponent(collectionName)}/documents/file`, { | ||
method: 'POST', | ||
body: backendFormData, | ||
headers: backendFormData.getHeaders() | ||
}); | ||
|
||
const backendResponseText = await backendResponse.text(); | ||
|
||
if (!backendResponse.ok) { | ||
throw new Error(`Failed to upload file to backend: ${backendResponseText}`); | ||
} | ||
|
||
return NextResponse.json({ message: 'File uploaded successfully', data: backendResponseText }, { status: 200 }); | ||
} catch (error: any) { | ||
console.error('Error during file upload:', error.message); | ||
return NextResponse.json({ error: error.message }, { status: 500 }); | ||
} | ||
} |
31 changes: 31 additions & 0 deletions
31
src/app/api/playground/ragchat/collections/[collectionName]/documents/url/route.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// src/app/api/playground/ragchat/collections/[collectionName]/documents/url/route.ts | ||
`use server`; | ||
|
||
import { NextRequest, NextResponse } from 'next/server'; | ||
|
||
export async function POST(req: NextRequest, { params }: { params: { collectionName: string } }) { | ||
const { collectionName } = params; | ||
|
||
try { | ||
const { http_source } = await req.json(); | ||
|
||
const response = await fetch(`http://localhost:8000/collections/${encodeURIComponent(collectionName)}/documents/url`, { | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json' | ||
}, | ||
body: JSON.stringify({ http_source }) | ||
}); | ||
|
||
const responseText = await response.text(); | ||
|
||
if (!response.ok) { | ||
throw new Error(`Failed to upload URL: ${responseText}`); | ||
} | ||
|
||
return NextResponse.json({ message: 'URL uploaded successfully', data: responseText }, { status: 200 }); | ||
} catch (error: any) { | ||
console.error('Error uploading URL:', error.message); | ||
return NextResponse.json({ error: error.message }, { status: 500 }); | ||
} | ||
} |
44 changes: 44 additions & 0 deletions
44
src/app/api/playground/ragchat/collections/[collectionName]/query/route.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// src/app/api/playground/ragchat/collections/[collectionName]/query/route.ts | ||
'use server'; | ||
|
||
import { NextRequest, NextResponse } from 'next/server'; | ||
import fetch from 'node-fetch'; | ||
|
||
export async function POST(req: NextRequest, { params }: { params: { collectionName: string } }) { | ||
const { collectionName } = params; | ||
|
||
try { | ||
const { question } = await req.json(); | ||
|
||
console.log(`Received question: ${question} for collection: ${collectionName}`); | ||
|
||
// Make the API request to the backend using node-fetch | ||
const response = await fetch(`http://127.0.0.1:8000/collections/${encodeURIComponent(collectionName)}/query`, { | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json' | ||
}, | ||
body: JSON.stringify({ question }) | ||
}); | ||
|
||
// Check if the response was successful | ||
if (!response.ok) { | ||
const errorText = await response.text(); | ||
console.error(`Failed to query collection: ${errorText}`); | ||
throw new Error(`Failed to query collection: ${errorText}`); | ||
} | ||
|
||
// Parse the backend response | ||
const responseData = await response.json(); | ||
console.log('Backend response data:', responseData); | ||
|
||
// Extract the 'answer' and 'sources' fields | ||
const { answer, sources } = responseData; | ||
|
||
// Return the answer and sources to the client | ||
return NextResponse.json({ answer, sources }, { status: 200 }); | ||
} catch (error: any) { | ||
console.error('Error querying collection:', error.message); | ||
return NextResponse.json({ error: error.message }, { status: 500 }); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// src/app/api/playground/ragchat/collections/route.ts | ||
'use server'; | ||
|
||
import { NextRequest, NextResponse } from 'next/server'; | ||
import fetch from 'node-fetch'; | ||
|
||
export async function GET(req: NextRequest) { | ||
console.log('Received request to fetch collections'); | ||
|
||
try { | ||
console.log('Making fetch call to backend service...'); | ||
|
||
const response = await fetch('http://127.0.0.1:8000/collections', { | ||
method: 'GET', | ||
headers: { | ||
Accept: 'application/json' // Ensure Accept header is set properly | ||
} | ||
}); | ||
|
||
const rawText = await response.text(); | ||
console.log('Raw response text from backend:', rawText); | ||
|
||
const data = JSON.parse(rawText); | ||
console.log('Parsed collections data:', data); | ||
|
||
return NextResponse.json(data, { status: 200 }); | ||
} catch (error: any) { | ||
console.error('Error fetching collections:', error.message); | ||
return NextResponse.json({ error: error.message }, { status: 500 }); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
// src/app/api/playground/ragchat/index-files/route.ts | ||
'use server'; | ||
|
||
import { NextRequest, NextResponse } from 'next/server'; | ||
import fetch from 'node-fetch'; | ||
|
||
async function authenticate(USERNAME: string, API_KEY: string, DS_HOST: string, retries: number = 3): Promise<string> { | ||
for (let attempt = 0; attempt < retries; attempt++) { | ||
try { | ||
console.log('Starting authentication...'); | ||
const authResponse = await fetch(`${DS_HOST}/api/cps/user/v1/user/token`, { | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
Authorization: `Basic ${Buffer.from(`${USERNAME}:${API_KEY}`).toString('base64')}` | ||
}, | ||
body: JSON.stringify({}) | ||
}); | ||
|
||
const authText = await authResponse.text(); | ||
console.log('Auth response text:', authText); | ||
|
||
if (!authResponse.ok) { | ||
throw new Error(authText); | ||
} | ||
|
||
const authData = JSON.parse(authText); | ||
console.log('Authentication successful. Token obtained.'); | ||
return authData.access_token; | ||
} catch (error) { | ||
console.error(`Authentication attempt ${attempt + 1} failed:`, error.message); | ||
if (attempt < retries - 1) { | ||
console.log('Retrying in 3 seconds...'); | ||
await new Promise((resolve) => setTimeout(resolve, 3000)); | ||
} else { | ||
throw new Error('Failed to authenticate after multiple attempts'); | ||
} | ||
} | ||
} | ||
} | ||
|
||
async function fetchDocuments(DS_HOST: string, PROJ_KEY: string, dsIndexKey: string, token: string, retries: number = 3) { | ||
for (let attempt = 0; attempt < retries; attempt++) { | ||
try { | ||
console.log('Fetching documents...'); | ||
const response = await fetch(`${DS_HOST}/api/cps/public/v2/project/${PROJ_KEY}/data_indices/${dsIndexKey}/documents/`, { | ||
method: 'GET', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
Authorization: `Bearer ${token}` | ||
} | ||
}); | ||
|
||
console.log('API response status:', response.status); | ||
|
||
if (!response.ok) { | ||
const errorText = await response.text(); | ||
throw new Error(errorText); | ||
} | ||
|
||
const data = await response.json(); | ||
console.log('Fetched documents:', data.documents); | ||
return data.documents.filter((doc: any) => doc.status === 'SUCCESS'); | ||
} catch (error) { | ||
console.error(`Fetch attempt ${attempt + 1} failed:`, error.message); | ||
if (attempt < retries - 1) { | ||
console.log('Retrying in 3 seconds...'); | ||
await new Promise((resolve) => setTimeout(resolve, 3000)); | ||
} else { | ||
throw new Error('Failed to fetch documents after multiple attempts'); | ||
} | ||
} | ||
} | ||
} | ||
|
||
export async function GET(req: NextRequest) { | ||
const { searchParams } = new URL(req.url); | ||
const dsIndexKey = searchParams.get('indexKey'); | ||
const USERNAME = process.env.DS_USERNAME; | ||
const API_KEY = process.env.DS_API_KEY; | ||
const DS_HOST = process.env.DS_HOST; | ||
const PROJ_KEY = process.env.DS_PROJ_KEY; | ||
|
||
console.log('Received request for data index:', dsIndexKey); | ||
|
||
if (!dsIndexKey || !USERNAME || !API_KEY || !DS_HOST || !PROJ_KEY) { | ||
console.error('Missing required parameters or environment variables', { dsIndexKey, USERNAME, API_KEY, DS_HOST, PROJ_KEY }); | ||
return NextResponse.json({ error: 'Missing required parameters or environment variables' }, { status: 400 }); | ||
} | ||
|
||
try { | ||
const token = await authenticate(USERNAME, API_KEY, DS_HOST); | ||
const documents = await fetchDocuments(DS_HOST, PROJ_KEY, dsIndexKey, token); | ||
return NextResponse.json({ documents }, { status: 200 }); | ||
} catch (error) { | ||
console.error('Server error:', error.message); | ||
return NextResponse.json({ error: error.message }, { status: 500 }); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
// src/app/api/playground/ragchat/query/route.ts | ||
'use server'; | ||
|
||
import { NextRequest, NextResponse } from 'next/server'; | ||
import fetch from 'node-fetch'; | ||
import { dsauthenticate } from '../../../../../utils/dsauthenticate'; | ||
|
||
async function queryRAG( | ||
DS_HOST: string, | ||
DS_TOKEN: string, | ||
DS_PROJ_KEY: string, | ||
indexKey: string, | ||
question: string, | ||
model_id: string, | ||
doc_hash: string | null | ||
) { | ||
const queryUrl = `${DS_HOST}/api/orchestrator/api/v1/query/run`; | ||
console.log('Querying RAG backend:', queryUrl); | ||
|
||
const payload = { | ||
query: { | ||
variables: {}, | ||
template: { | ||
version: '1', | ||
tasks: [ | ||
{ | ||
id: 'QA', | ||
kind: 'SemanticRag', | ||
inputs: {}, | ||
parameters: { | ||
question, | ||
model_id, | ||
retr_k: 10, | ||
use_reranker: false, | ||
hybrid_search_text_weight: 0.1, | ||
gen_timeout: 25, | ||
return_prompt: true, | ||
...(doc_hash ? { doc_id: doc_hash } : {}) // doc_hash is added only if the user selects a specific doc to query | ||
}, | ||
'@resource': { | ||
type: 'semantic_backend_genai_runner', | ||
proj_key: DS_PROJ_KEY, | ||
index_key: indexKey | ||
} | ||
} | ||
], | ||
outputs: { | ||
answers: { | ||
task_id: 'QA', | ||
output_id: 'answers' | ||
}, | ||
retrieval: { | ||
task_id: 'QA', | ||
output_id: 'retrieval' | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
|
||
try { | ||
const response = await fetch(queryUrl, { | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
'X-Authorization': `Bearer ${DS_TOKEN}` | ||
}, | ||
body: JSON.stringify(payload) | ||
}); | ||
|
||
if (!response.ok) { | ||
const errorText = await response.text(); | ||
throw new Error(errorText); | ||
} | ||
|
||
const data = await response.json(); | ||
console.log('RAG backend response:', data); | ||
return data.result.outputs.answers[0].prompt; | ||
} catch (error) { | ||
console.error('Error querying RAG backend:', error.message); | ||
throw error; | ||
} | ||
} | ||
|
||
export async function POST(req: NextRequest) { | ||
const { question, dataIndex, docHash } = await req.json(); | ||
const USERNAME = process.env.DS_USERNAME; | ||
const API_KEY = process.env.DS_API_KEY; | ||
const DS_HOST = process.env.DS_HOST; | ||
const DS_PROJ_KEY = process.env.DS_PROJ_KEY; | ||
const DS_MODEL_ID = process.env.DS_MODEL_ID; | ||
|
||
if (!USERNAME || !API_KEY || !DS_HOST || !DS_PROJ_KEY || !DS_MODEL_ID) { | ||
console.error('Missing required parameters or environment variables', { USERNAME, API_KEY, DS_HOST, DS_PROJ_KEY, DS_MODEL_ID }); | ||
return NextResponse.json({ error: 'Missing required parameters or environment variables' }, { status: 400 }); | ||
} | ||
|
||
try { | ||
const token = await dsauthenticate(USERNAME, API_KEY, DS_HOST); | ||
const prompt = await queryRAG(DS_HOST, token, DS_PROJ_KEY, dataIndex, question, DS_MODEL_ID, docHash); | ||
console.log('Prompt received:', prompt); | ||
return NextResponse.json({ prompt }, { status: 200 }); | ||
} catch (error) { | ||
console.error('Server error:', error.message); | ||
return NextResponse.json({ error: error.message }, { status: 500 }); | ||
} | ||
} |
Oops, something went wrong.