mirror of
				https://github.com/meta-llama/llama-stack.git
				synced 2025-10-25 17:11:12 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			105 lines
		
	
	
	
		
			3 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			105 lines
		
	
	
	
		
			3 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| import { NextRequest, NextResponse } from "next/server";
 | |
| 
 | |
| // Get backend URL from environment variable or default to localhost for development
 | |
| const BACKEND_URL =
 | |
|   process.env.LLAMA_STACK_BACKEND_URL ||
 | |
|   `http://localhost:${process.env.LLAMA_STACK_PORT || 8321}`;
 | |
| 
 | |
| async function proxyRequest(request: NextRequest, method: string) {
 | |
|   try {
 | |
|     // Extract the path from the request URL
 | |
|     const url = new URL(request.url);
 | |
|     const pathSegments = url.pathname.split("/");
 | |
| 
 | |
|     // Remove /api from the path to get the actual API path
 | |
|     // /api/v1/models/list -> /v1/models/list
 | |
|     const apiPath = pathSegments.slice(2).join("/"); // Remove 'api' segment
 | |
|     const targetUrl = `${BACKEND_URL}/${apiPath}${url.search}`;
 | |
| 
 | |
|     console.log(`Proxying ${method} ${url.pathname} -> ${targetUrl}`);
 | |
| 
 | |
|     // Prepare headers (exclude host and other problematic headers)
 | |
|     const headers = new Headers();
 | |
|     request.headers.forEach((value, key) => {
 | |
|       // Skip headers that might cause issues in proxy
 | |
|       if (
 | |
|         !["host", "connection", "content-length"].includes(key.toLowerCase())
 | |
|       ) {
 | |
|         headers.set(key, value);
 | |
|       }
 | |
|     });
 | |
| 
 | |
|     // Prepare the request options
 | |
|     const requestOptions: RequestInit = {
 | |
|       method,
 | |
|       headers,
 | |
|     };
 | |
| 
 | |
|     // Add body for methods that support it
 | |
|     if (["POST", "PUT", "PATCH"].includes(method) && request.body) {
 | |
|       requestOptions.body = await request.text();
 | |
|     }
 | |
| 
 | |
|     // Make the request to FastAPI backend
 | |
|     const response = await fetch(targetUrl, requestOptions);
 | |
| 
 | |
|     // Get response data
 | |
|     const responseText = await response.text();
 | |
| 
 | |
|     console.log(
 | |
|       `Response from FastAPI: ${response.status} ${response.statusText}`
 | |
|     );
 | |
| 
 | |
|     // Create response with same status and headers
 | |
|     const proxyResponse = new NextResponse(responseText, {
 | |
|       status: response.status,
 | |
|       statusText: response.statusText,
 | |
|     });
 | |
| 
 | |
|     // Copy response headers (except problematic ones)
 | |
|     response.headers.forEach((value, key) => {
 | |
|       if (!["connection", "transfer-encoding"].includes(key.toLowerCase())) {
 | |
|         proxyResponse.headers.set(key, value);
 | |
|       }
 | |
|     });
 | |
| 
 | |
|     return proxyResponse;
 | |
|   } catch (error) {
 | |
|     console.error("Proxy request failed:", error);
 | |
| 
 | |
|     return NextResponse.json(
 | |
|       {
 | |
|         error: "Proxy request failed",
 | |
|         message: error instanceof Error ? error.message : "Unknown error",
 | |
|         backend_url: BACKEND_URL,
 | |
|         timestamp: new Date().toISOString(),
 | |
|       },
 | |
|       { status: 500 }
 | |
|     );
 | |
|   }
 | |
| }
 | |
| 
 | |
| // HTTP method handlers
 | |
| export async function GET(request: NextRequest) {
 | |
|   return proxyRequest(request, "GET");
 | |
| }
 | |
| 
 | |
| export async function POST(request: NextRequest) {
 | |
|   return proxyRequest(request, "POST");
 | |
| }
 | |
| 
 | |
| export async function PUT(request: NextRequest) {
 | |
|   return proxyRequest(request, "PUT");
 | |
| }
 | |
| 
 | |
| export async function DELETE(request: NextRequest) {
 | |
|   return proxyRequest(request, "DELETE");
 | |
| }
 | |
| 
 | |
| export async function PATCH(request: NextRequest) {
 | |
|   return proxyRequest(request, "PATCH");
 | |
| }
 | |
| 
 | |
| export async function OPTIONS(request: NextRequest) {
 | |
|   return proxyRequest(request, "OPTIONS");
 | |
| }
 |