mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-07 02:59:05 +00:00
working showing user the raw request / response
This commit is contained in:
parent
a1f5002638
commit
cdd625972c
3 changed files with 115 additions and 68 deletions
|
|
@ -1,55 +1,121 @@
|
|||
import React from 'react';
|
||||
import { Typography, Space, Button, Divider } from 'antd';
|
||||
import { WarningOutlined, InfoCircleOutlined } from '@ant-design/icons';
|
||||
import { ErrorViewer } from '../view_logs/ErrorViewer';
|
||||
import { Typography, Space, Button, Divider, message } from 'antd';
|
||||
import { WarningOutlined, InfoCircleOutlined, CopyOutlined } from '@ant-design/icons';
|
||||
import { testConnectionRequest } from "../networking";
|
||||
import { prepareModelAddRequest } from "./handle_add_model_submit";
|
||||
|
||||
const { Text } = Typography;
|
||||
|
||||
interface ConnectionErrorDisplayProps {
|
||||
error: Error | string;
|
||||
formValues: Record<string, any>;
|
||||
accessToken: string;
|
||||
testMode: string;
|
||||
modelName?: string;
|
||||
onClose?: () => void;
|
||||
}
|
||||
|
||||
const ConnectionErrorDisplay: React.FC<ConnectionErrorDisplayProps> = ({
|
||||
error,
|
||||
modelName = "this model",
|
||||
formValues,
|
||||
accessToken,
|
||||
testMode,
|
||||
modelName = "this model",
|
||||
onClose
|
||||
}) => {
|
||||
const errorMessage = typeof error === 'string' ? error : error.message;
|
||||
|
||||
// Create an error info object compatible with ErrorViewer
|
||||
const errorInfo = {
|
||||
error_message: errorMessage.split('\n')[0],
|
||||
traceback: errorMessage,
|
||||
// We don't have these fields from the connection test error, but the component handles undefined
|
||||
error_class: undefined,
|
||||
llm_provider: undefined,
|
||||
error_code: undefined
|
||||
const [error, setError] = React.useState<Error | string | null>(null);
|
||||
const [rawRequest, setRawRequest] = React.useState<any>(null);
|
||||
const [rawResponse, setRawResponse] = React.useState<any>(null);
|
||||
|
||||
const testModelConnection = async () => {
|
||||
try {
|
||||
const result = await prepareModelAddRequest(formValues, accessToken, null);
|
||||
if (!result) throw new Error("Failed to prepare model data");
|
||||
|
||||
const { litellmParamsObj } = result;
|
||||
const requestBody = { ...litellmParamsObj, mode: testMode };
|
||||
|
||||
const response = await testConnectionRequest(accessToken, requestBody);
|
||||
if (response.status === "success") {
|
||||
message.success("Connection test successful!");
|
||||
setError(null);
|
||||
} else {
|
||||
const errorMessage = response.result?.error || response.message || "Unknown error";
|
||||
setError(errorMessage);
|
||||
setRawRequest(requestBody);
|
||||
setRawResponse(response.result?.raw_request_typed_dict);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Test connection error:", error);
|
||||
setError(error instanceof Error ? error.message : String(error));
|
||||
}
|
||||
};
|
||||
|
||||
React.useEffect(() => {
|
||||
testModelConnection();
|
||||
}, []);
|
||||
|
||||
const errorMessage = typeof error === 'string' ? error : error?.message;
|
||||
|
||||
const formatCurlCommand = (apiBase: string, requestBody: Record<string, any>, requestHeaders: Record<string, string>) => {
|
||||
const formattedBody = JSON.stringify(requestBody, null, 2)
|
||||
.split('\n')
|
||||
.map(line => ` ${line}`)
|
||||
.join('\n');
|
||||
|
||||
const headerString = Object.entries(requestHeaders)
|
||||
.map(([key, value]) => `-H '${key}: ${value}'`)
|
||||
.join(' \\\n ');
|
||||
|
||||
return `curl -X POST \\
|
||||
${apiBase} \\
|
||||
${headerString ? `${headerString} \\\n ` : ''}-H 'Content-Type: application/json' \\
|
||||
-d '{
|
||||
${formattedBody}
|
||||
}'`;
|
||||
};
|
||||
|
||||
const curlCommand = rawResponse ? formatCurlCommand(
|
||||
rawResponse.raw_request_api_base,
|
||||
rawResponse.raw_request_body,
|
||||
rawResponse.raw_request_headers || {}
|
||||
) : '';
|
||||
|
||||
return (
|
||||
|
||||
<div style={{ padding: '16px 24px' }}>
|
||||
|
||||
|
||||
{/* Use the ErrorViewer component for consistent error display */}
|
||||
<ErrorViewer errorInfo={errorInfo} />
|
||||
|
||||
<Divider style={{ margin: '16px 0' }} />
|
||||
|
||||
<div style={{ display: 'flex', justifyContent: 'flex-start' }}>
|
||||
<Button
|
||||
type="link"
|
||||
href="https://docs.litellm.ai/docs/providers"
|
||||
target="_blank"
|
||||
icon={<InfoCircleOutlined />}
|
||||
>
|
||||
View Documentation
|
||||
</Button>
|
||||
<div style={{ padding: '16px 24px' }}>
|
||||
<Divider style={{ margin: '16px 0' }} />
|
||||
{error && (
|
||||
<div>
|
||||
<Text type="danger">{errorMessage}</Text>
|
||||
<Divider style={{ margin: '16px 0' }} />
|
||||
<div>
|
||||
<h3>Raw Request</h3>
|
||||
<pre style={{ backgroundColor: '#f5f5f5', padding: '16px', borderRadius: '6px' }}>
|
||||
{curlCommand || "No request data"}
|
||||
</pre>
|
||||
<Button
|
||||
type="text"
|
||||
icon={<CopyOutlined />}
|
||||
onClick={() => {
|
||||
navigator.clipboard.writeText(curlCommand || '');
|
||||
message.success('Copied to clipboard');
|
||||
}}
|
||||
>
|
||||
Copy to Clipboard
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<Divider style={{ margin: '16px 0' }} />
|
||||
<div style={{ display: 'flex', justifyContent: 'flex-start' }}>
|
||||
<Button
|
||||
type="link"
|
||||
href="https://docs.litellm.ai/docs/providers"
|
||||
target="_blank"
|
||||
icon={<InfoCircleOutlined />}
|
||||
>
|
||||
View Documentation
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import AdvancedSettings from "./advanced_settings";
|
|||
import { Providers, providerLogoMap, getPlaceholder } from "../provider_info_helpers";
|
||||
import type { Team } from "../key_team_helpers/key_list";
|
||||
import { CredentialItem } from "../networking";
|
||||
import { testModelConnection } from "./test_connection_handler";
|
||||
import ConnectionErrorDisplay from "./ConnectionErrorDisplay";
|
||||
|
||||
interface AddModelTabProps {
|
||||
|
|
@ -61,26 +60,6 @@ const AddModelTab: React.FC<AddModelTabProps> = ({
|
|||
const [isTestModalVisible, setIsTestModalVisible] = useState<boolean>(false);
|
||||
const [connectionError, setConnectionError] = useState<Error | string | null>(null);
|
||||
|
||||
// Add a function to handle test connection
|
||||
const handleTestConnection = async () => {
|
||||
// Clear any previous errors
|
||||
setConnectionError(null);
|
||||
|
||||
try {
|
||||
const formValues = form.getFieldsValue();
|
||||
|
||||
// Call the existing testModelConnection function
|
||||
const result = await testModelConnection(formValues, accessToken, testMode, setConnectionError);
|
||||
|
||||
// Only close the modal on success
|
||||
if (result && result.status === "success") {
|
||||
setIsTestModalVisible(false);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Test connection failed:", error);
|
||||
}
|
||||
};
|
||||
|
||||
// Show test modal with mode selection
|
||||
const showTestModal = () => {
|
||||
setConnectionError(null);
|
||||
|
|
@ -252,7 +231,7 @@ const AddModelTab: React.FC<AddModelTabProps> = ({
|
|||
<Button
|
||||
key="test"
|
||||
type="primary"
|
||||
onClick={handleTestConnection}
|
||||
onClick={() => setConnectionError("Test connection logic is now in ConnectionErrorDisplay")}
|
||||
loading={false} // You might want to add a loading state
|
||||
>
|
||||
Test Connection
|
||||
|
|
@ -281,8 +260,11 @@ const AddModelTab: React.FC<AddModelTabProps> = ({
|
|||
<Typography.Title level={5} type="danger">Connection Test Failed</Typography.Title>
|
||||
<div className="border border-red-300 rounded-md overflow-hidden">
|
||||
<ConnectionErrorDisplay
|
||||
error={connectionError}
|
||||
modelName={form.getFieldValue('model_name') || form.getFieldValue('model')}
|
||||
formValues={form.getFieldsValue()}
|
||||
accessToken={accessToken}
|
||||
testMode={testMode}
|
||||
modelName={form.getFieldValue('model_name') || form.getFieldValue('model')}
|
||||
onClose={() => setIsTestModalVisible(false)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ export const testModelConnection = async (
|
|||
formValues: Record<string, any>,
|
||||
accessToken: string,
|
||||
testMode: string,
|
||||
setConnectionError?: (error: Error | string | null) => void
|
||||
setConnectionError?: (error: Error | string | null, rawRequest?: any, rawResponse?: any) => void
|
||||
) => {
|
||||
try {
|
||||
// Prepare the model data using the existing function
|
||||
|
|
@ -20,30 +20,30 @@ export const testModelConnection = async (
|
|||
|
||||
// Create the request body for the test connection
|
||||
const requestBody = {
|
||||
...litellmParamsObj, // Unfurl the parameters directly
|
||||
...litellmParamsObj,
|
||||
mode: testMode
|
||||
};
|
||||
|
||||
console.log("Request Body:", requestBody); // Debugging log
|
||||
|
||||
// Call the test connection endpoint
|
||||
const response = await testConnectionRequest(accessToken, requestBody);
|
||||
|
||||
console.log("Response:", response); // Debugging log
|
||||
|
||||
if (response.status === "success") {
|
||||
message.success("Connection test successful!");
|
||||
// Clear any previous error when successful
|
||||
if (setConnectionError) {
|
||||
setConnectionError(null);
|
||||
}
|
||||
} else {
|
||||
// Extract the detailed error message from the response
|
||||
let errorMessage = response.message || "Unknown error";
|
||||
|
||||
// Check if there's a more detailed error in the result
|
||||
if (response.result && response.result.error) {
|
||||
errorMessage = response.result.error;
|
||||
}
|
||||
|
||||
if (setConnectionError) {
|
||||
setConnectionError(errorMessage);
|
||||
setConnectionError(errorMessage, requestBody, response.result.raw_request_typed_dict);
|
||||
} else {
|
||||
message.error("Connection test failed: " + errorMessage);
|
||||
}
|
||||
|
|
@ -53,9 +53,8 @@ export const testModelConnection = async (
|
|||
} catch (error) {
|
||||
console.error("Test connection error:", error);
|
||||
|
||||
// Set the error for ConnectionErrorDisplay
|
||||
if (setConnectionError) {
|
||||
setConnectionError(error);
|
||||
setConnectionError(error, requestBody, null);
|
||||
} else {
|
||||
message.error("Test connection failed: " + error, 10);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue