feat(router.py): support mock testing fallbacks flag

allow user to test if fallbacks work as expected with a `mock_testing_fallbacks = True` flag set during a call
This commit is contained in:
Krrish Dholakia 2024-04-24 20:13:10 -07:00
parent 94cbe5516e
commit 5650e8ea44
5 changed files with 32 additions and 11 deletions

View file

@ -136,6 +136,21 @@ curl --location 'http://0.0.0.0:4000/chat/completions' \
' '
``` ```
### Test it!
```bash
curl --location 'http://0.0.0.0:4000/chat/completions' \
--header 'Content-Type: application/json' \
--data-raw '{
"model": "zephyr-beta", # 👈 MODEL NAME to fallback from
"messages": [
{"role": "user", "content": "what color is red"}
],
"mock_testing_fallbacks": true
}'
```
## Advanced - Context Window Fallbacks ## Advanced - Context Window Fallbacks
**Before call is made** check if a call is within model context window with **`enable_pre_call_checks: true`**. **Before call is made** check if a call is within model context window with **`enable_pre_call_checks: true`**.

View file

@ -2521,9 +2521,10 @@ class ProxyConfig:
# decode base64 # decode base64
decoded_b64 = base64.b64decode(v) decoded_b64 = base64.b64decode(v)
# decrypt value # decrypt value
_litellm_params[k] = decrypt_value( _value = decrypt_value(value=decoded_b64, master_key=master_key)
value=decoded_b64, master_key=master_key # sanity check if string > size 0
) if len(_value) > 0:
_litellm_params[k] = _value
_litellm_params = LiteLLM_Params(**_litellm_params) _litellm_params = LiteLLM_Params(**_litellm_params)
else: else:
verbose_proxy_logger.error( verbose_proxy_logger.error(

View file

@ -1309,7 +1309,7 @@ class Router:
Try calling the function_with_retries Try calling the function_with_retries
If it fails after num_retries, fall back to another model group If it fails after num_retries, fall back to another model group
""" """
mock_testing_fallbacks = kwargs.get("mock_testing_fallbacks", None) mock_testing_fallbacks = kwargs.pop("mock_testing_fallbacks", None)
model_group = kwargs.get("model") model_group = kwargs.get("model")
fallbacks = kwargs.get("fallbacks", self.fallbacks) fallbacks = kwargs.get("fallbacks", self.fallbacks)
context_window_fallbacks = kwargs.get( context_window_fallbacks = kwargs.get(
@ -1369,7 +1369,10 @@ class Router:
elif fallbacks is not None: elif fallbacks is not None:
verbose_router_logger.debug(f"inside model fallbacks: {fallbacks}") verbose_router_logger.debug(f"inside model fallbacks: {fallbacks}")
for item in fallbacks: for item in fallbacks:
if list(item.keys())[0] == model_group: key_list = list(item.keys())
if len(key_list) == 0:
continue
if key_list[0] == model_group:
fallback_model_group = item[model_group] fallback_model_group = item[model_group]
break break
if fallback_model_group is None: if fallback_model_group is None:

View file

@ -57,11 +57,12 @@ async function testFallbackModelResponse(
content: "Hi, this is a test message", content: "Hi, this is a test message",
}, },
], ],
mock_testing_fallbacks: true
}); });
message.success( message.success(
<span> <span>
Test model=<strong>{selectedModel}</strong>, received model=<strong>{responseModel}</strong>. Test model=<strong>{selectedModel}</strong>, received model=<strong>{response.model}</strong>.
See <a href="#" onClick={() => window.open('https://docs.litellm.ai/docs/proxy/reliability', '_blank')} style={{ textDecoration: 'underline', color: 'blue' }}>curl</a> See <a href="#" onClick={() => window.open('https://docs.litellm.ai/docs/proxy/reliability', '_blank')} style={{ textDecoration: 'underline', color: 'blue' }}>curl</a>
</span> </span>
); );
@ -154,14 +155,12 @@ const GeneralSettings: React.FC<GeneralSettingsPageProps> = ({
const updatedVariables = Object.fromEntries( const updatedVariables = Object.fromEntries(
Object.entries(router_settings).map(([key, value]) => { Object.entries(router_settings).map(([key, value]) => {
if (key === 'routing_strategy_args' && typeof value === 'string') { if (key !== 'routing_strategy_args') {
return [key, JSON.parse(value as string)];
} else {
return [key, (document.querySelector(`input[name="${key}"]`) as HTMLInputElement)?.value || value]; return [key, (document.querySelector(`input[name="${key}"]`) as HTMLInputElement)?.value || value];
} }
}) return null;
}).filter(entry => entry !== null) as Iterable<[string, unknown]>
); );
console.log("updatedVariables", updatedVariables); console.log("updatedVariables", updatedVariables);
const payload = { const payload = {

View file

@ -106,6 +106,9 @@ const handleSubmit = async (formValues: Record<string, any>, accessToken: string
litellmParamsObj["model"] = litellm_model litellmParamsObj["model"] = litellm_model
let modelName: string = ""; let modelName: string = "";
for (const [key, value] of Object.entries(formValues)) { for (const [key, value] of Object.entries(formValues)) {
if (value === '') {
continue;
}
if (key == "model_name") { if (key == "model_name") {
modelName = modelName + value modelName = modelName + value
} }