diff --git a/litellm/llms/sap/chat/transformation.py b/litellm/llms/sap/chat/transformation.py index 82f8b10ca9e..aef3ebe4016 100755 --- a/litellm/llms/sap/chat/transformation.py +++ b/litellm/llms/sap/chat/transformation.py @@ -219,25 +219,57 @@ class GenAIHubOrchestrationConfig(OpenAIGPTConfig): headers: dict, ) -> dict: optional_params.pop("deployment_url", None) - model_version = optional_params.pop("model_version", "latest") + + def _build_prompt_module( + *, + model_name: str, + template_messages: List[Dict[str, str]], + params: dict, + ) -> dict: + model_version = params.pop("model_version", "latest") + + tools_ = params.pop("tools", []) + tools = {"tools": tools_} if tools_ else {} + + response_format = params.pop("response_format", {}) + resp_type = response_format.get("type", None) + if resp_type: + if resp_type == "json_schema": + response_format = validate_dict(response_format, ResponseFormatJSONSchema) + else: + response_format = validate_dict(response_format, ResponseFormat) + response_format = {"response_format": response_format} + else: + response_format = {} + + placeholder_defaults = params.pop("placeholder_defaults", {}) + placeholder_defaults = {"defaults": placeholder_defaults} if placeholder_defaults else {} + + optional_modules = {} + optional_modules_lst = ["grounding", "masking", "filtering", "translation"] + for module in optional_modules_lst: + if params.get(module, None): + optional_modules[module] = params.pop(module) + + return { + "prompt_templating": { + "prompt": { + "template": template_messages, + **placeholder_defaults, + **tools, + **response_format, + }, + "model": { + "name": model_name, + "params": params, + "version": model_version, + }, + }, + **optional_modules, + } + template = messages - tools_ = optional_params.pop("tools", []) - if tools_ != []: - tools = {"tools": tools_} - else: - tools = {} - - response_format = optional_params.pop("response_format", {}) - resp_type = response_format.get("type", None) - if resp_type: - if resp_type == "json_schema": - response_format = validate_dict( - response_format, ResponseFormatJSONSchema - ) - else: - response_format = validate_dict(response_format, ResponseFormat) - response_format = {"response_format": response_format} optional_params.pop("stream", False) stream_config = {} if "stream_options" in optional_params: @@ -246,88 +278,33 @@ class GenAIHubOrchestrationConfig(OpenAIGPTConfig): if "delimiters" in stream_options: stream_config["delimiters"] = stream_options.get("delimiters") - placeholder_defaults = optional_params.pop("placeholder_defaults", {}) - if placeholder_defaults: - placeholder_defaults = {"defaults": placeholder_defaults} - placeholder_values = optional_params.pop("placeholder_values", {}) - if placeholder_values: - placeholder_values = {"placeholder_values": placeholder_values} - - optional_modules = {} - optional_modules_lst = ["grounding", "masking", "filtering", "translation"] - for module in optional_modules_lst: - if optional_params.get(module, None): - optional_modules[module] = optional_params.pop(module) + placeholder_values = {"placeholder_values": placeholder_values} if placeholder_values else {} fallback_modules = optional_params.pop("fallback_modules", []) + modules = [ - { - "prompt_templating": { - "prompt": { - "template": template, - **placeholder_defaults, - **tools, - **response_format - }, - "model": { - "name": model, - "params": optional_params, - "version": model_version, - }, - }, - **optional_modules - } - ] + _build_prompt_module( + model_name=model, + template_messages=template, + params=optional_params, + ) + ] + for modules_dict in fallback_modules: fallback_model = modules_dict.pop("model") - fallback_model_version = modules_dict.pop("model_version", "latest") + if fallback_model.startswith("sap"): + fallback_model = fallback_model[4:] fallback_template = modules_dict.pop("messages", []) - fallback_tools_ = modules_dict.pop("tools", []) - if fallback_tools_ != []: - fallback_tools = {"tools": fallback_tools_} - else: - fallback_tools = {} - - fallback_response_format = modules_dict.pop("response_format", {}) - fallback_resp_type = fallback_response_format.get("type", None) - if fallback_resp_type: - if fallback_resp_type == "json_schema": - fallback_response_format = validate_dict(response_format, ResponseFormatJSONSchema) - else: - fallback_response_format = validate_dict(response_format, ResponseFormat) - fallback_response_format = {"response_format": fallback_response_format} - - fallback_placeholder_defaults = modules_dict.pop("placeholder_defaults", {}) - if fallback_placeholder_defaults: - fallback_placeholder_defaults = {"placeholder_defaults": fallback_placeholder_defaults} - - fallback_optional_modules = {} - for module in optional_modules_lst: - if modules_dict.get(module, None): - fallback_optional_modules[module] = modules_dict.pop(module) modules.append( - { - "prompt_templating": { - "prompt": { - "template": fallback_template, - **fallback_placeholder_defaults, - **fallback_tools, - **fallback_response_format - }, - "model": { - "name": fallback_model, - "params": modules_dict, - "version": fallback_model_version, - }, - }, - **fallback_optional_modules - } + _build_prompt_module( + model_name=fallback_model, + template_messages=fallback_template, + params=modules_dict, + ) ) - - request_body = { "config": { "modules": modules, @@ -337,7 +314,6 @@ class GenAIHubOrchestrationConfig(OpenAIGPTConfig): } validate_dict(request_body, OrchestrationRequest) - print(request_body) return request_body diff --git a/tests/test_litellm/llms/sap/chat/test_sap_additional_modules.py b/tests/test_litellm/llms/sap/chat/test_sap_additional_modules.py index cf7347e1979..ae0a241db8b 100644 --- a/tests/test_litellm/llms/sap/chat/test_sap_additional_modules.py +++ b/tests/test_litellm/llms/sap/chat/test_sap_additional_modules.py @@ -12,8 +12,8 @@ def test_sap_placeholder_defaults(): headers={} ) - assert config["config"]["modules"]["prompt_templating"]["prompt"]["defaults"] == {"user_query": "default value"} - assert config["config"]["modules"]["prompt_templating"]["model"]["params"] == {} + assert config["config"]["modules"][0]["prompt_templating"]["prompt"]["defaults"] == {"user_query": "default value"} + assert config["config"]["modules"][0]["prompt_templating"]["model"]["params"] == {} def test_sap_placeholder_values(): placeholder_values = {"user_query": "Some text"} @@ -29,7 +29,7 @@ def test_sap_placeholder_values(): ) assert config["placeholder_values"] == placeholder_values - assert config["config"]["modules"]["prompt_templating"]["model"]["params"] == {} + assert config["config"]["modules"][0]["prompt_templating"]["model"]["params"] == {} def test_sap_grounding(): grounding_config = { @@ -58,9 +58,9 @@ def test_sap_grounding(): litellm_params={}, headers={} ) - assert config["config"]["modules"]["grounding"] == grounding_config + assert config["config"]["modules"][0]["grounding"] == grounding_config assert config["placeholder_values"] == placeholder_values - assert config["config"]["modules"]["prompt_templating"]["model"]["params"] == {} + assert config["config"]["modules"][0]["prompt_templating"]["model"]["params"] == {} def test_sap_filtering(): filtering_config_azure = { @@ -123,8 +123,8 @@ def test_sap_filtering(): litellm_params={}, headers={} ) - assert config["config"]["modules"]["filtering"] == filtering_config_azure - assert config["config"]["modules"]["prompt_templating"]["model"]["params"] == {} + assert config["config"]["modules"][0]["filtering"] == filtering_config_azure + assert config["config"]["modules"][0]["prompt_templating"]["model"]["params"] == {} config = GenAIHubOrchestrationConfig().transform_request( model="gpt-4o", @@ -134,8 +134,8 @@ def test_sap_filtering(): litellm_params={}, headers={} ) - assert config["config"]["modules"]["filtering"] == filtering_config_llama - assert config["config"]["modules"]["prompt_templating"]["model"]["params"] == {} + assert config["config"]["modules"][0]["filtering"] == filtering_config_llama + assert config["config"]["modules"][0]["prompt_templating"]["model"]["params"] == {} def test_sap_masking(): masking_config = { @@ -163,8 +163,8 @@ def test_sap_masking(): litellm_params={}, headers={} ) - assert config["config"]["modules"]["masking"] == masking_config - assert config["config"]["modules"]["prompt_templating"]["model"]["params"] == {} + assert config["config"]["modules"][0]["masking"] == masking_config + assert config["config"]["modules"][0]["prompt_templating"]["model"]["params"] == {} def test_sap_translation(): translation_config = { @@ -190,5 +190,42 @@ def test_sap_translation(): litellm_params={}, headers={} ) - assert config["config"]["modules"]["translation"] == translation_config - assert config["config"]["modules"]["prompt_templating"]["model"]["params"] == {} \ No newline at end of file + assert config["config"]["modules"][0]["translation"] == translation_config + assert config["config"]["modules"][0]["prompt_templating"]["model"]["params"] == {} + +def test_sap_multiple_modules(): + translation_config = { + 'input': + {'type': 'sap_document_translation', + 'config': + {'source_language': 'en-US', + 'target_language': 'de-DE'} + }, + 'output': + {'type': 'sap_document_translation', + 'config': + {'source_language': 'de-DE', + 'target_language': 'fr-FR'} + } + } + + config = GenAIHubOrchestrationConfig().transform_request( + model="gpt-4o", + messages=[{"role": "user", "content": "Hello."}], + optional_params={'deployment_url': "shouldn't be in results", + "fallback_modules":[{"model": "sap/gpt-5", + "messages": [{"role": "user", "content": "Hello world!"}], + "translation": translation_config + }] + , + }, + litellm_params={}, + headers={} + ) + assert "translation" not in config["config"]["modules"][0] + assert config["config"]["modules"][1]["translation"] == translation_config + assert config["config"]["modules"][1]["prompt_templating"]["model"]["name"] == "gpt-5" + assert config["config"]["modules"][0]["prompt_templating"]["model"]["name"] == "gpt-4o" + assert config["config"]["modules"][0]["prompt_templating"]["model"]["params"] == {} + assert config["config"]["modules"][1]["prompt_templating"]["prompt"]["template"][0]["content"] == "Hello world!" + assert config["config"]["modules"][0]["prompt_templating"]["prompt"]["template"][0]["content"] == "Hello." \ No newline at end of file