Scope custom proxy base to Playground

This commit is contained in:
Chesars 2026-01-06 12:17:22 -03:00
parent 229d280141
commit cd38e1c9de
13 changed files with 68 additions and 24 deletions

View file

@ -92,12 +92,6 @@ const updateServerRootPath = (receivedServerRootPath: string) => {
};
export const getProxyBaseUrl = (): string => {
// Check for custom proxy base URL from sessionStorage first
const customProxyBaseUrl = sessionStorage.getItem("customProxyBaseUrl");
if (customProxyBaseUrl && customProxyBaseUrl.trim() !== "") {
return customProxyBaseUrl;
}
if (proxyBaseUrl) {
return proxyBaseUrl;
}

View file

@ -365,7 +365,7 @@ const ChatUI: React.FC<ChatUIProps> = ({
const loadAgents = async () => {
try {
const agents = await fetchAvailableAgents(userApiKey);
const agents = await fetchAvailableAgents(userApiKey, customProxyBaseUrl || undefined);
setAgentInfo(agents);
// Clear selection if current agent not in list
if (selectedAgent && !agents.some((a) => a.agent_name === selectedAgent)) {
@ -377,7 +377,7 @@ const ChatUI: React.FC<ChatUIProps> = ({
};
loadAgents();
}, [accessToken, apiKeySource, apiKey, endpointType]);
}, [accessToken, apiKeySource, apiKey, endpointType, customProxyBaseUrl, selectedAgent]);
useEffect(() => {
// Scroll to the bottom of the chat whenever chatHistory updates
@ -862,6 +862,7 @@ const ChatUI: React.FC<ChatUIProps> = ({
useAdvancedParams ? temperature : undefined,
useAdvancedParams ? maxTokens : undefined,
updateTotalLatency,
customProxyBaseUrl || undefined,
);
} else if (endpointType === EndpointType.IMAGE) {
// For image generation
@ -872,6 +873,7 @@ const ChatUI: React.FC<ChatUIProps> = ({
effectiveApiKey,
selectedTags,
signal,
customProxyBaseUrl || undefined,
);
} else if (endpointType === EndpointType.SPEECH) {
// For audio speech
@ -883,6 +885,9 @@ const ChatUI: React.FC<ChatUIProps> = ({
effectiveApiKey,
selectedTags,
signal,
undefined, // responseFormat
undefined, // speed
customProxyBaseUrl || undefined,
);
} else if (endpointType === EndpointType.IMAGE_EDITS) {
// For image edits
@ -895,6 +900,7 @@ const ChatUI: React.FC<ChatUIProps> = ({
effectiveApiKey,
selectedTags,
signal,
customProxyBaseUrl || undefined,
);
}
} else if (endpointType === EndpointType.RESPONSES) {
@ -933,6 +939,7 @@ const ChatUI: React.FC<ChatUIProps> = ({
handleMCPEvent, // Pass MCP event handler
codeInterpreter.enabled, // Enable Code Interpreter tool
codeInterpreter.setResult, // Handle code interpreter output
customProxyBaseUrl || undefined,
);
} else if (endpointType === EndpointType.ANTHROPIC_MESSAGES) {
const apiChatHistory = [
@ -956,6 +963,7 @@ const ChatUI: React.FC<ChatUIProps> = ({
selectedVectorStores.length > 0 ? selectedVectorStores : undefined,
selectedGuardrails.length > 0 ? selectedGuardrails : undefined,
selectedMCPTools, // Pass the selected tools array
customProxyBaseUrl || undefined,
);
} else if (endpointType === EndpointType.EMBEDDINGS) {
await makeOpenAIEmbeddingsRequest(
@ -964,6 +972,7 @@ const ChatUI: React.FC<ChatUIProps> = ({
selectedModel,
effectiveApiKey,
selectedTags,
customProxyBaseUrl || undefined,
);
} else if (endpointType === EndpointType.TRANSCRIPTION) {
// For audio transcriptions
@ -975,6 +984,11 @@ const ChatUI: React.FC<ChatUIProps> = ({
effectiveApiKey,
selectedTags,
signal,
undefined, // language
undefined, // prompt
undefined, // responseFormat
undefined, // temperature
customProxyBaseUrl || undefined,
);
}
}
@ -991,6 +1005,7 @@ const ChatUI: React.FC<ChatUIProps> = ({
updateTimingData,
updateTotalLatency,
updateA2AMetadata,
customProxyBaseUrl || undefined,
);
}
} catch (error) {
@ -1116,9 +1131,25 @@ const ChatUI: React.FC<ChatUIProps> = ({
</div>
<div>
<Text className="font-medium block mb-2 text-gray-700 flex items-center">
<SettingOutlined className="mr-2" /> Custom Proxy Base URL
</Text>
<div className="flex items-center justify-between mb-2">
<Text className="font-medium text-gray-700 flex items-center">
<SettingOutlined className="mr-2" /> Custom Proxy Base URL
</Text>
{customProxyBaseUrl && (
<Button
type="link"
size="small"
icon={<ClearOutlined />}
onClick={() => {
setCustomProxyBaseUrl("");
sessionStorage.removeItem("customProxyBaseUrl");
}}
className="text-gray-500 hover:text-gray-700"
>
Clear
</Button>
)}
</div>
<TextInput
placeholder="Optional: Enter custom proxy URL (e.g., http://localhost:5000)"
onValueChange={(value) => {

View file

@ -106,6 +106,9 @@ export default function CompareUI({ accessToken, disabledPersonalKeyCreation }:
);
const [customApiKey, setCustomApiKey] = useState("");
const [debouncedCustomApiKey, setDebouncedCustomApiKey] = useState("");
const [customProxyBaseUrl] = useState<string>(
() => sessionStorage.getItem("customProxyBaseUrl") || ""
);
useEffect(() => {
const timer = setTimeout(() => {
setDebouncedCustomApiKey(customApiKey);
@ -171,7 +174,7 @@ export default function CompareUI({ accessToken, disabledPersonalKeyCreation }:
}
setIsLoadingAgents(true);
try {
const agents = await fetchAvailableAgents(effectiveApiKey);
const agents = await fetchAvailableAgents(effectiveApiKey, customProxyBaseUrl || undefined);
if (!active) return;
setAgentOptions(agents);
} catch (error) {
@ -598,6 +601,8 @@ export default function CompareUI({ accessToken, disabledPersonalKeyCreation }:
undefined,
(time) => updateTimingDataForComparison(prepared.id, time),
(latency) => updateTotalLatencyForComparison(prepared.id, latency),
undefined, // onA2AMetadata
customProxyBaseUrl || undefined,
)
: makeOpenAIChatCompletionRequest(
prepared.apiChatHistory,
@ -618,6 +623,7 @@ export default function CompareUI({ accessToken, disabledPersonalKeyCreation }:
useAdvancedParams ? prepared.temperature : undefined,
useAdvancedParams ? prepared.maxTokens : undefined,
(latency) => updateTotalLatencyForComparison(prepared.id, latency),
customProxyBaseUrl || undefined,
);
requestPromise

View file

@ -113,8 +113,9 @@ export const makeA2ASendMessageRequest = async (
onTimingData?: (timeToFirstToken: number) => void,
onTotalLatency?: (totalLatency: number) => void,
onA2AMetadata?: (metadata: A2ATaskMetadata) => void,
customBaseUrl?: string,
): Promise<void> => {
const proxyBaseUrl = getProxyBaseUrl();
const proxyBaseUrl = customBaseUrl || getProxyBaseUrl();
const url = proxyBaseUrl
? `${proxyBaseUrl}/a2a/${agentId}/message/send`
: `/a2a/${agentId}/message/send`;
@ -242,8 +243,9 @@ export const makeA2AStreamMessageRequest = async (
onTimingData?: (timeToFirstToken: number) => void,
onTotalLatency?: (totalLatency: number) => void,
onA2AMetadata?: (metadata: A2ATaskMetadata) => void,
customBaseUrl?: string,
): Promise<void> => {
const proxyBaseUrl = getProxyBaseUrl();
const proxyBaseUrl = customBaseUrl || getProxyBaseUrl();
const url = proxyBaseUrl
? `${proxyBaseUrl}/a2a/${agentId}`
: `/a2a/${agentId}`;

View file

@ -18,6 +18,7 @@ export async function makeAnthropicMessagesRequest(
vector_store_ids?: string[],
guardrails?: string[],
selectedMCPTools?: string[],
customBaseUrl?: string,
) {
if (!accessToken) {
throw new Error("Virtual Key is required");
@ -28,7 +29,7 @@ export async function makeAnthropicMessagesRequest(
console.log = function () {};
}
const proxyBaseUrl = getProxyBaseUrl();
const proxyBaseUrl = customBaseUrl || getProxyBaseUrl();
// Prepare headers with tags and trace ID
const headers: Record<string, string> = {};

View file

@ -13,6 +13,7 @@ export async function makeOpenAIAudioSpeechRequest(
signal?: AbortSignal,
responseFormat?: string,
speed?: number,
customBaseUrl?: string,
) {
// base url should be the current base_url
const isLocal = process.env.NODE_ENV === "development";
@ -20,7 +21,7 @@ export async function makeOpenAIAudioSpeechRequest(
console.log = function () {};
}
console.log("isLocal:", isLocal);
const proxyBaseUrl = getProxyBaseUrl();
const proxyBaseUrl = customBaseUrl || getProxyBaseUrl();
const client = new openai.OpenAI({
apiKey: accessToken,
baseURL: proxyBaseUrl,

View file

@ -13,6 +13,7 @@ export async function makeOpenAIAudioTranscriptionRequest(
prompt?: string,
responseFormat?: string,
temperature?: number,
customBaseUrl?: string,
) {
// base url should be the current base_url
const isLocal = process.env.NODE_ENV === "development";
@ -20,7 +21,7 @@ export async function makeOpenAIAudioTranscriptionRequest(
console.log = function () {};
}
console.log("isLocal:", isLocal);
const proxyBaseUrl = getProxyBaseUrl();
const proxyBaseUrl = customBaseUrl || getProxyBaseUrl();
const client = new openai.OpenAI({
apiKey: accessToken,

View file

@ -23,6 +23,7 @@ export async function makeOpenAIChatCompletionRequest(
temperature?: number,
max_tokens?: number,
onTotalLatency?: (latency: number) => void,
customBaseUrl?: string,
) {
// base url should be the current base_url
const isLocal = process.env.NODE_ENV === "development";
@ -30,7 +31,7 @@ export async function makeOpenAIChatCompletionRequest(
console.log = function () {};
}
console.log("isLocal:", isLocal);
const proxyBaseUrl = getProxyBaseUrl();
const proxyBaseUrl = customBaseUrl || getProxyBaseUrl();
// Prepare headers with tags and trace ID
const headers: Record<string, string> = {};
if (tags && tags.length > 0) {

View file

@ -7,6 +7,7 @@ export async function makeOpenAIEmbeddingsRequest(
selectedModel: string,
accessToken: string,
tags?: string[],
customBaseUrl?: string,
) {
if (!accessToken) {
throw new Error("Virtual Key is required");
@ -18,7 +19,7 @@ export async function makeOpenAIEmbeddingsRequest(
console.log = function () {};
}
const proxyBaseUrl = getProxyBaseUrl();
const proxyBaseUrl = customBaseUrl || getProxyBaseUrl();
// Prepare headers with tags and trace ID
const headers: Record<string, string> = {};
if (tags && tags.length > 0) {

View file

@ -16,9 +16,12 @@ export interface Agent {
/**
* Fetches available A2A agents from /v1/agents endpoint.
*/
export const fetchAvailableAgents = async (accessToken: string): Promise<Agent[]> => {
export const fetchAvailableAgents = async (
accessToken: string,
customBaseUrl?: string,
): Promise<Agent[]> => {
try {
const proxyBaseUrl = getProxyBaseUrl();
const proxyBaseUrl = customBaseUrl || getProxyBaseUrl();
const url = proxyBaseUrl ? `${proxyBaseUrl}/v1/agents` : `/v1/agents`;
const response = await fetch(url, {

View file

@ -10,6 +10,7 @@ export async function makeOpenAIImageEditsRequest(
accessToken: string,
tags?: string[],
signal?: AbortSignal,
customBaseUrl?: string,
) {
// base url should be the current base_url
const isLocal = process.env.NODE_ENV === "development";
@ -17,7 +18,7 @@ export async function makeOpenAIImageEditsRequest(
console.log = function () {};
}
console.log("isLocal:", isLocal);
const proxyBaseUrl = getProxyBaseUrl();
const proxyBaseUrl = customBaseUrl || getProxyBaseUrl();
const client = new openai.OpenAI({
apiKey: accessToken,

View file

@ -9,6 +9,7 @@ export async function makeOpenAIImageGenerationRequest(
accessToken: string,
tags?: string[],
signal?: AbortSignal,
customBaseUrl?: string,
) {
// base url should be the current base_url
const isLocal = process.env.NODE_ENV === "development";
@ -16,7 +17,7 @@ export async function makeOpenAIImageGenerationRequest(
console.log = function () {};
}
console.log("isLocal:", isLocal);
const proxyBaseUrl = getProxyBaseUrl();
const proxyBaseUrl = customBaseUrl || getProxyBaseUrl();
const client = new openai.OpenAI({
apiKey: accessToken,
baseURL: proxyBaseUrl,

View file

@ -32,6 +32,7 @@ export async function makeOpenAIResponsesRequest(
onMCPEvent?: (event: MCPEvent) => void,
codeInterpreterEnabled?: boolean,
onCodeInterpreterResult?: (result: CodeInterpreterResult) => void,
customBaseUrl?: string,
) {
if (!accessToken) {
throw new Error("Virtual Key is required");
@ -47,7 +48,7 @@ export async function makeOpenAIResponsesRequest(
console.log = function () {};
}
const proxyBaseUrl = getProxyBaseUrl();
const proxyBaseUrl = customBaseUrl || getProxyBaseUrl();
// Prepare headers with tags and trace ID
const headers: Record<string, string> = {};
if (tags && tags.length > 0) {