Files
gemini-nexus/src/server/modules/proxy/proxy.controller.ts
T
2026-01-10 01:07:09 +08:00

93 lines
3.0 KiB
TypeScript

import { Controller, Get, Post, Body, Res, HttpStatus, UseGuards } from '@nestjs/common';
import { FastifyReply } from 'fastify';
import { ProxyService } from './proxy.service';
import { Observable } from 'rxjs';
import { OpenAIChatRequest, AnthropicChatRequest } from './interfaces/request-interfaces';
import { ProxyGuard } from './proxy.guard';
@Controller('v1')
@UseGuards(ProxyGuard)
export class ProxyController {
constructor(private readonly proxyService: ProxyService) {}
@Get('models')
getModels() {
return {
object: 'list',
data: [
// Gemini Native
{
id: 'gemini-2.5-flash-thinking',
object: 'model',
created: 1734336000,
owned_by: 'google',
},
{ id: 'gemini-2.5-flash', object: 'model', created: 1734336000, owned_by: 'google' },
{ id: 'gemini-2.5-pro', object: 'model', created: 1734336000, owned_by: 'google' },
{ id: 'gemini-3-flash', object: 'model', created: 1734336000, owned_by: 'google' },
// Claude Native (Mapped)
{ id: 'claude-sonnet-4-5', object: 'model', created: 1734336000, owned_by: 'anthropic' },
{
id: 'claude-sonnet-4-5-thinking',
object: 'model',
created: 1734336000,
owned_by: 'anthropic',
},
// Image Models
{ id: 'gemini-3-pro-image', object: 'model', created: 1734336000, owned_by: 'google' },
],
};
}
@Post('chat/completions')
async chatCompletions(@Body() body: OpenAIChatRequest, @Res() res: FastifyReply) {
try {
const result = await this.proxyService.handleChatCompletions(body);
if (body.stream && result instanceof Observable) {
res.header('Content-Type', 'text/event-stream');
res.header('Cache-Control', 'no-cache');
res.header('Connection', 'keep-alive');
res.send(result);
} else {
res.status(HttpStatus.OK).send(result);
}
} catch (error) {
const message = error instanceof Error ? error.message : 'Internal Server Error';
res.status(HttpStatus.INTERNAL_SERVER_ERROR).send({
error: {
message: message,
type: 'server_error',
},
});
}
}
@Post('messages')
async anthropicMessages(@Body() body: AnthropicChatRequest, @Res() res: FastifyReply) {
try {
const result = await this.proxyService.handleAnthropicMessages(body);
if (body.stream && result instanceof Observable) {
res.header('Content-Type', 'text/event-stream');
res.header('Cache-Control', 'no-cache');
res.header('Connection', 'keep-alive');
res.send(result);
} else {
res.status(HttpStatus.OK).send(result);
}
} catch (error) {
const message = error instanceof Error ? error.message : 'Internal Server Error';
res.status(HttpStatus.INTERNAL_SERVER_ERROR).send({
type: 'error',
error: {
type: 'api_error',
message: message,
},
});
}
}
}