diff --git a/playground/src/app/api/agents/start/graph.tsx b/playground/src/apis/routes.tsx similarity index 71% rename from playground/src/app/api/agents/start/graph.tsx rename to playground/src/apis/routes.tsx index 76a4c9a0..2f31c337 100644 --- a/playground/src/app/api/agents/start/graph.tsx +++ b/playground/src/apis/routes.tsx @@ -1,108 +1,159 @@ -import { LanguageMap } from "@/common/constant"; - -export const voiceNameMap: LanguageMap = { - "zh-CN": { - azure: { - male: "zh-CN-YunxiNeural", - female: "zh-CN-XiaoxiaoNeural", - }, - elevenlabs: { - male: "pNInz6obpgDQGcFmaJgB", // Adam - female: "Xb7hH8MSUJpSbSDYk0k2", // Alice - }, - polly: { - male: "Zhiyu", - female: "Zhiyu", - }, - }, - "en-US": { - azure: { - male: "en-US-BrianNeural", - female: "en-US-JaneNeural", - }, - elevenlabs: { - male: "pNInz6obpgDQGcFmaJgB", // Adam - female: "Xb7hH8MSUJpSbSDYk0k2", // Alice - }, - polly: { - male: "Matthew", - female: "Ruth", - }, - }, - "ja-JP": { - azure: { - male: "ja-JP-KeitaNeural", - female: "ja-JP-NanamiNeural", - }, - }, - "ko-KR": { - azure: { - male: "ko-KR-InJoonNeural", - female: "ko-KR-JiMinNeural", - }, - }, -}; - -// Get the graph properties based on the graph name, language, and voice type -// This is the place where you can customize the properties for different graphs to override default property.json -export const getGraphProperties = (graphName: string, language: string, voiceType: string) => { - let localizationOptions = { - "greeting": "ASTRA agent connected. How can i help you today?", - "checking_vision_text_items": "[\"Let me take a look...\",\"Let me check your camera...\",\"Please wait for a second...\"]", - } - - if (language === "zh-CN") { - localizationOptions = { - "greeting": "Astra已连接,需要我为您提供什么帮助?", - "checking_vision_text_items": "[\"让我看看你的摄像头...\",\"让我看一下...\",\"我看一下,请稍候...\"]", - } - } else if (language === "ja-JP") { - localizationOptions = { - "greeting": "ASTRAエージェントに接続されました。今日は何をお手伝いしましょうか?", - "checking_vision_text_items": "[\"ちょっと見てみます...\",\"カメラをチェックします...\",\"少々お待ちください...\"]", - } - } else if (language === "ko-KR") { - localizationOptions = { - "greeting": "ASTRA 에이전트에 연결되었습니다. 오늘은 무엇을 도와드릴까요?", - "checking_vision_text_items": "[\"조금만 기다려 주세요...\",\"카메라를 확인해 보겠습니다...\",\"잠시만 기다려 주세요...\"]", - } - } - - if (graphName == "camera.va.openai.azure") { - return { - "agora_rtc": { - "agora_asr_language": language, - }, - "openai_chatgpt": { - "model": "gpt-4o", - ...localizationOptions - }, - "azure_tts": { - "azure_synthesis_voice_name": voiceNameMap[language]["azure"][voiceType] - } - } - } else if (graphName == "va.openai.azure") { - return { - "agora_rtc": { - "agora_asr_language": language, - }, - "openai_chatgpt": { - "model": "gpt-4o-mini", - ...localizationOptions - }, - "azure_tts": { - "azure_synthesis_voice_name": voiceNameMap[language]["azure"][voiceType] - } - } - } else if (graphName == "va.qwen.rag") { - return { - "agora_rtc": { - "agora_asr_language": language, - }, - "azure_tts": { - "azure_synthesis_voice_name": voiceNameMap[language]["azure"][voiceType] - } - } - } - return {} -} \ No newline at end of file +import { LanguageMap } from '@/common/constant'; +import { NextRequest, NextResponse } from 'next/server'; + + +const { AGENT_SERVER_URL } = process.env; + +// Check if environment variables are available +if (!AGENT_SERVER_URL) { + throw "Environment variables AGENT_SERVER_URL are not available"; +} + + +export const voiceNameMap: LanguageMap = { + "zh-CN": { + azure: { + male: "zh-CN-YunxiNeural", + female: "zh-CN-XiaoxiaoNeural", + }, + elevenlabs: { + male: "pNInz6obpgDQGcFmaJgB", // Adam + female: "Xb7hH8MSUJpSbSDYk0k2", // Alice + }, + polly: { + male: "Zhiyu", + female: "Zhiyu", + }, + }, + "en-US": { + azure: { + male: "en-US-BrianNeural", + female: "en-US-JaneNeural", + }, + elevenlabs: { + male: "pNInz6obpgDQGcFmaJgB", // Adam + female: "Xb7hH8MSUJpSbSDYk0k2", // Alice + }, + polly: { + male: "Matthew", + female: "Ruth", + }, + }, + "ja-JP": { + azure: { + male: "ja-JP-KeitaNeural", + female: "ja-JP-NanamiNeural", + }, + }, + "ko-KR": { + azure: { + male: "ko-KR-InJoonNeural", + female: "ko-KR-JiMinNeural", + }, + }, +}; + +// Get the graph properties based on the graph name, language, and voice type +// This is the place where you can customize the properties for different graphs to override default property.json +export const getGraphProperties = (graphName: string, language: string, voiceType: string) => { + let localizationOptions = { + "greeting": "ASTRA agent connected. How can i help you today?", + "checking_vision_text_items": "[\"Let me take a look...\",\"Let me check your camera...\",\"Please wait for a second...\"]", + } + + if (language === "zh-CN") { + localizationOptions = { + "greeting": "Astra已连接,需要我为您提供什么帮助?", + "checking_vision_text_items": "[\"让我看看你的摄像头...\",\"让我看一下...\",\"我看一下,请稍候...\"]", + } + } else if (language === "ja-JP") { + localizationOptions = { + "greeting": "ASTRAエージェントに接続されました。今日は何をお手伝いしましょうか?", + "checking_vision_text_items": "[\"ちょっと見てみます...\",\"カメラをチェックします...\",\"少々お待ちください...\"]", + } + } else if (language === "ko-KR") { + localizationOptions = { + "greeting": "ASTRA 에이전트에 연결되었습니다. 오늘은 무엇을 도와드릴까요?", + "checking_vision_text_items": "[\"조금만 기다려 주세요...\",\"카메라를 확인해 보겠습니다...\",\"잠시만 기다려 주세요...\"]", + } + } + + if (graphName == "camera.va.openai.azure") { + return { + "agora_rtc": { + "agora_asr_language": language, + }, + "openai_chatgpt": { + "model": "gpt-4o", + ...localizationOptions + }, + "azure_tts": { + "azure_synthesis_voice_name": voiceNameMap[language]["azure"][voiceType] + } + } + } else if (graphName == "va.openai.azure") { + return { + "agora_rtc": { + "agora_asr_language": language, + }, + "openai_chatgpt": { + "model": "gpt-4o-mini", + ...localizationOptions + }, + "azure_tts": { + "azure_synthesis_voice_name": voiceNameMap[language]["azure"][voiceType] + } + } + } else if (graphName == "va.qwen.rag") { + return { + "agora_rtc": { + "agora_asr_language": language, + }, + "azure_tts": { + "azure_synthesis_voice_name": voiceNameMap[language]["azure"][voiceType] + } + } + } + return {} +} + +export async function startAgent(request: NextRequest) { + try{ + const body = await request.json(); + const { + request_id, + channel_name, + user_uid, + graph_name, + language, + voice_type, + } = body; + + // Send a POST request to start the agent + const response = await fetch(`${AGENT_SERVER_URL}/start`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + request_id, + channel_name, + user_uid, + graph_name, + // Get the graph properties based on the graph name, language, and voice type + properties: getGraphProperties(graph_name, language, voice_type), + }), + }); + + const responseData = await response.json(); + + return NextResponse.json(responseData, { status: response.status }); + } catch (error) { + if (error instanceof Response) { + const errorData = await error.json(); + return NextResponse.json(errorData, { status: error.status }); + } else { + return NextResponse.json({ code: "1", data: null, msg: "Internal Server Error" }, { status: 500 }); + } + } +} diff --git a/playground/src/app/api/agents/start/route.tsx b/playground/src/app/api/agents/start/route.tsx deleted file mode 100644 index 5a7b4440..00000000 --- a/playground/src/app/api/agents/start/route.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import { NextRequest, NextResponse } from 'next/server'; -import { getGraphProperties } from './graph'; - -/** - * Handles the POST request to start an agent. - * - * @param request - The NextRequest object representing the incoming request. - * @returns A NextResponse object representing the response to be sent back to the client. - */ -export async function POST(request: NextRequest) { - try { - const { AGENT_SERVER_URL } = process.env; - - // Check if environment variables are available - if (!AGENT_SERVER_URL) { - throw "Environment variables are not available"; - } - - const body = await request.json(); - const { - request_id, - channel_name, - user_uid, - graph_name, - language, - voice_type, - } = body; - - // Send a POST request to start the agent - const response = await fetch(`${AGENT_SERVER_URL}/start`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - request_id, - channel_name, - user_uid, - graph_name, - // Get the graph properties based on the graph name, language, and voice type - properties: getGraphProperties(graph_name, language, voice_type), - }), - }); - - const responseData = await response.json(); - - return NextResponse.json(responseData, { status: response.status }); - } catch (error) { - if (error instanceof Response) { - const errorData = await error.json(); - return NextResponse.json(errorData, { status: error.status }); - } else { - return NextResponse.json({ code: "1", data: null, msg: "Internal Server Error" }, { status: 500 }); - } - } -} \ No newline at end of file diff --git a/playground/src/common/request.ts b/playground/src/common/request.ts index 7e6e094f..a6acda1f 100644 --- a/playground/src/common/request.ts +++ b/playground/src/common/request.ts @@ -15,7 +15,7 @@ interface GenAgoraDataConfig { } export const apiGenAgoraData = async (config: GenAgoraDataConfig) => { - // the request will be rewrite at next.config.mjs to send to $AGENT_SERVER_URL + // the request will be rewrite at middleware.tsx to send to $AGENT_SERVER_URL const url = `/api/token/generate` const { userId, channel } = config const data = { @@ -35,7 +35,7 @@ export const apiGenAgoraData = async (config: GenAgoraDataConfig) => { } export const apiStartService = async (config: StartRequestConfig): Promise => { - // look at app/api/agents/start/route.tsx for the server-side implementation + // look at app/apis/route.tsx for the server-side implementation const url = `/api/agents/start` const { channel, userId, graphName, language, voiceType } = config const data = { @@ -58,7 +58,7 @@ export const apiStartService = async (config: StartRequestConfig): Promise } export const apiStopService = async (channel: string) => { - // the request will be rewrite at next.config.mjs to send to $AGENT_SERVER_URL + // the request will be rewrite at middleware.tsx to send to $AGENT_SERVER_URL const url = `/api/agents/stop` const data = { request_id: genUUID(), @@ -76,6 +76,7 @@ export const apiStopService = async (channel: string) => { } export const apiGetDocumentList = async () => { + // the request will be rewrite at middleware.tsx to send to $AGENT_SERVER_URL const url = `/api/vector/document/preset/list` let resp: any = await fetch(url, { method: "GET", @@ -91,7 +92,7 @@ export const apiGetDocumentList = async () => { } export const apiUpdateDocument = async (options: { channel: string, collection: string, fileName: string }) => { - // the request will be rewrite at next.config.mjs to send to $AGENT_SERVER_URL + // the request will be rewrite at middleware.tsx to send to $AGENT_SERVER_URL const url = `/api/vector/document/update` const { channel, collection, fileName } = options const data = { @@ -114,7 +115,7 @@ export const apiUpdateDocument = async (options: { channel: string, collection: // ping/pong export const apiPing = async (channel: string) => { - // the request will be rewrite at next.config.mjs to send to $AGENT_SERVER_URL + // the request will be rewrite at middleware.tsx to send to $AGENT_SERVER_URL const url = `/api/agents/ping` const data = { request_id: genUUID(), diff --git a/playground/src/middleware.tsx b/playground/src/middleware.tsx index 724e0b4d..66e3a549 100644 --- a/playground/src/middleware.tsx +++ b/playground/src/middleware.tsx @@ -1,5 +1,6 @@ // middleware.js import { NextRequest, NextResponse } from 'next/server'; +import { startAgent } from './apis/routes'; const { AGENT_SERVER_URL } = process.env; @@ -11,28 +12,27 @@ if (!AGENT_SERVER_URL) { export function middleware(req: NextRequest) { const { pathname } = req.nextUrl; + const url = req.nextUrl.clone(); - if (pathname.startsWith('/api/agents/')) { + if (pathname.startsWith(`/api/agents/`)) { if (!pathname.startsWith('/api/agents/start')) { - // Proxy all other agents API requests - const url = req.nextUrl.clone(); url.href = `${AGENT_SERVER_URL}${pathname.replace('/api/agents/', '/')}`; // console.log(`Rewriting request to ${url.href}`); return NextResponse.rewrite(url); + } else { + return startAgent(req); } - } else if (pathname.startsWith('/api/vector/')) { + } else if (pathname.startsWith(`/api/vector/`)) { // Proxy all other documents requests - const url = req.nextUrl.clone(); url.href = `${AGENT_SERVER_URL}${pathname.replace('/api/vector/', '/vector/')}`; // console.log(`Rewriting request to ${url.href}`); return NextResponse.rewrite(url); - } else if (pathname.startsWith('/api/token/')) { + } else if (pathname.startsWith(`/api/token/`)) { // Proxy all other documents requests - const url = req.nextUrl.clone(); url.href = `${AGENT_SERVER_URL}${pathname.replace('/api/token/', '/token/')}`; // console.log(`Rewriting request to ${url.href}`);