feat: ai proxy v1 (#3898)
* feat: ai proxy v1 * perf: ai proxy channel crud * feat: ai proxy logs * feat: channel test * doc * update lock
This commit is contained in:
72
projects/app/src/pages/api/aiproxy/[...path].ts
Normal file
72
projects/app/src/pages/api/aiproxy/[...path].ts
Normal file
@@ -0,0 +1,72 @@
|
||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||
import { jsonRes } from '@fastgpt/service/common/response';
|
||||
import { request } from 'https';
|
||||
import { authSystemAdmin } from '@fastgpt/service/support/permission/user/auth';
|
||||
|
||||
const baseUrl = process.env.AIPROXY_API_ENDPOINT;
|
||||
const token = process.env.AIPROXY_API_TOKEN;
|
||||
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
try {
|
||||
await authSystemAdmin({ req });
|
||||
|
||||
if (!baseUrl || !token) {
|
||||
throw new Error('AIPROXY_API_ENDPOINT or AIPROXY_API_TOKEN is not set');
|
||||
}
|
||||
|
||||
const { path = [], ...query } = req.query as any;
|
||||
|
||||
if (!path.length) {
|
||||
throw new Error('url is empty');
|
||||
}
|
||||
|
||||
const queryStr = new URLSearchParams(query).toString();
|
||||
const requestPath = queryStr
|
||||
? `/${path?.join('/')}?${new URLSearchParams(query).toString()}`
|
||||
: `/${path?.join('/')}`;
|
||||
|
||||
const parsedUrl = new URL(baseUrl);
|
||||
delete req.headers?.cookie;
|
||||
delete req.headers?.host;
|
||||
delete req.headers?.origin;
|
||||
|
||||
const requestResult = request({
|
||||
protocol: parsedUrl.protocol,
|
||||
hostname: parsedUrl.hostname,
|
||||
port: parsedUrl.port,
|
||||
path: requestPath,
|
||||
method: req.method,
|
||||
headers: {
|
||||
...req.headers,
|
||||
Authorization: `Bearer ${token}`
|
||||
},
|
||||
timeout: 30000
|
||||
});
|
||||
|
||||
req.pipe(requestResult);
|
||||
|
||||
requestResult.on('response', (response) => {
|
||||
Object.keys(response.headers).forEach((key) => {
|
||||
// @ts-ignore
|
||||
res.setHeader(key, response.headers[key]);
|
||||
});
|
||||
response.statusCode && res.writeHead(response.statusCode);
|
||||
response.pipe(res);
|
||||
});
|
||||
requestResult.on('error', (e) => {
|
||||
res.send(e);
|
||||
res.end();
|
||||
});
|
||||
} catch (error) {
|
||||
jsonRes(res, {
|
||||
code: 500,
|
||||
error
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const config = {
|
||||
api: {
|
||||
bodyParser: false
|
||||
}
|
||||
};
|
||||
33
projects/app/src/pages/api/aiproxy/api/createChannel.ts
Normal file
33
projects/app/src/pages/api/aiproxy/api/createChannel.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import type { ApiRequestProps, ApiResponseType } from '@fastgpt/service/type/next';
|
||||
import { authSystemAdmin } from '@fastgpt/service/support/permission/user/auth';
|
||||
import axios from 'axios';
|
||||
import { getErrText } from '@fastgpt/global/common/error/utils';
|
||||
|
||||
const baseUrl = process.env.AIPROXY_API_ENDPOINT;
|
||||
const token = process.env.AIPROXY_API_TOKEN;
|
||||
|
||||
async function handler(req: ApiRequestProps, res: ApiResponseType<any>) {
|
||||
try {
|
||||
await authSystemAdmin({ req });
|
||||
|
||||
if (!baseUrl || !token) {
|
||||
return Promise.reject('AIPROXY_API_ENDPOINT or AIPROXY_API_TOKEN is not set');
|
||||
}
|
||||
|
||||
const { data } = await axios.post(`${baseUrl}/api/channel/`, req.body, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`
|
||||
}
|
||||
});
|
||||
|
||||
res.json(data);
|
||||
} catch (error) {
|
||||
res.json({
|
||||
success: false,
|
||||
message: getErrText(error),
|
||||
data: error
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default handler;
|
||||
@@ -60,6 +60,7 @@ const testLLMModel = async (model: LLMModelItemType) => {
|
||||
const ai = getAIApi({
|
||||
timeout: 10000
|
||||
});
|
||||
|
||||
const requestBody = llmCompletionsBodyFormat(
|
||||
{
|
||||
model: model.model,
|
||||
|
||||
Reference in New Issue
Block a user