feat: get all transformers

This commit is contained in:
musistudio
2025-07-30 11:55:55 +08:00
parent 112d7ef8f9
commit ad17b27c3d
4 changed files with 40 additions and 12 deletions

View File

@@ -13,6 +13,18 @@ export const createServer = (config: any): Server => {
return await readConfigFile(); return await readConfigFile();
}); });
server.app.get("/api/transformers", async () => {
const transformers =
server.app._server!.transformerService.getAllTransformers();
const transformerList = Array.from(transformers.entries()).map(
([name, transformer]: any) => ({
name,
endpoint: transformer.endPoint || null,
})
);
return { transformers: transformerList };
});
// Add endpoint to save config.json // Add endpoint to save config.json
server.app.post("/api/config", async (req) => { server.app.post("/api/config", async (req) => {
const newConfig = req.body; const newConfig = req.body;
@@ -26,8 +38,8 @@ export const createServer = (config: any): Server => {
// Restart the service after a short delay to allow response to be sent // Restart the service after a short delay to allow response to be sent
setTimeout(() => { setTimeout(() => {
const { spawn } = require('child_process'); const { spawn } = require("child_process");
spawn('ccr', ['restart'], { detached: true, stdio: 'ignore' }); spawn("ccr", ["restart"], { detached: true, stdio: "ignore" });
}, 1000); }, 1000);
}); });
@@ -35,7 +47,7 @@ export const createServer = (config: any): Server => {
server.app.register(fastifyStatic, { server.app.register(fastifyStatic, {
root: join(__dirname, "..", "dist"), root: join(__dirname, "..", "dist"),
prefix: "/ui/", prefix: "/ui/",
maxAge: "1h" maxAge: "1h",
}); });
// Redirect /ui to /ui/ for proper static file serving // Redirect /ui to /ui/ for proper static file serving

View File

@@ -1,4 +1,4 @@
import { useState, useRef } from "react"; import { useState, useRef, useEffect } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
@@ -18,6 +18,7 @@ import { X, Trash2, Plus } from "lucide-react";
import { Badge } from "@/components/ui/badge"; import { Badge } from "@/components/ui/badge";
import { Combobox } from "@/components/ui/combobox"; import { Combobox } from "@/components/ui/combobox";
import { ComboInput } from "@/components/ui/combo-input"; import { ComboInput } from "@/components/ui/combo-input";
import { api } from "@/lib/api";
export function Providers() { export function Providers() {
@@ -28,8 +29,23 @@ export function Providers() {
const [hasFetchedModels, setHasFetchedModels] = useState<Record<number, boolean>>({}); const [hasFetchedModels, setHasFetchedModels] = useState<Record<number, boolean>>({});
const [providerParamInputs, setProviderParamInputs] = useState<Record<string, {name: string, value: string}>>({}); const [providerParamInputs, setProviderParamInputs] = useState<Record<string, {name: string, value: string}>>({});
const [modelParamInputs, setModelParamInputs] = useState<Record<string, {name: string, value: string}>>({}); const [modelParamInputs, setModelParamInputs] = useState<Record<string, {name: string, value: string}>>({});
const [availableTransformers, setAvailableTransformers] = useState<{name: string; endpoint: string | null;}[]>([]);
const comboInputRef = useRef<HTMLInputElement>(null); const comboInputRef = useRef<HTMLInputElement>(null);
// Fetch available transformers when component mounts
useEffect(() => {
const fetchTransformers = async () => {
try {
const response = await api.get<{transformers: {name: string; endpoint: string | null;}[]}>('/transformers');
setAvailableTransformers(response.transformers);
} catch (error) {
console.error('Failed to fetch transformers:', error);
}
};
fetchTransformers();
}, []);
if (!config) { if (!config) {
return null; return null;
} }
@@ -438,9 +454,9 @@ export function Providers() {
{/* Add new transformer */} {/* Add new transformer */}
<div className="flex gap-2"> <div className="flex gap-2">
<Combobox <Combobox
options={config.transformers.map(t => ({ options={availableTransformers.map(t => ({
label: t.path.split('/').pop() || t.path, label: t.name,
value: t.path value: t.name
}))} }))}
value="" value=""
onChange={(value) => { onChange={(value) => {
@@ -591,9 +607,9 @@ export function Providers() {
<div className="flex gap-2"> <div className="flex gap-2">
<div className="flex-1 flex gap-2"> <div className="flex-1 flex gap-2">
<Combobox <Combobox
options={config.transformers.map(t => ({ options={availableTransformers.map(t => ({
label: t.path.split('/').pop() || t.path, label: t.name,
value: t.path value: t.name
}))} }))}
value="" value=""
onChange={(value) => { onChange={(value) => {

View File

@@ -1,6 +1,6 @@
{ {
"app": { "app": {
"title": "Configuration", "title": "Claude Code Router",
"save": "Save", "save": "Save",
"save_and_restart": "Save and Restart", "save_and_restart": "Save and Restart",
"cancel": "Cancel", "cancel": "Cancel",

View File

@@ -1,6 +1,6 @@
{ {
"app": { "app": {
"title": "配置", "title": "Claude Code Router",
"save": "保存", "save": "保存",
"save_and_restart": "保存并重启", "save_and_restart": "保存并重启",
"cancel": "取消", "cancel": "取消",