diff --git a/extensions/HuggingFace/python/src/aiconfig_extension_hugging_face/local_inference/automatic_speech_recognition.py b/extensions/HuggingFace/python/src/aiconfig_extension_hugging_face/local_inference/automatic_speech_recognition.py index d3484aab8..125e9fd47 100644 --- a/extensions/HuggingFace/python/src/aiconfig_extension_hugging_face/local_inference/automatic_speech_recognition.py +++ b/extensions/HuggingFace/python/src/aiconfig_extension_hugging_face/local_inference/automatic_speech_recognition.py @@ -118,7 +118,7 @@ async def run( aiconfig: "AIConfigRuntime", options: InferenceOptions, parameters: Dict[str, Any], - **kwargs, + run_with_dependencies: Optional[bool] = False, ) -> list[Output]: await aiconfig.callback_manager.run_callbacks( CallbackEvent( @@ -128,6 +128,7 @@ async def run( "prompt": prompt, "options": options, "parameters": parameters, + "run_with_dependencies": run_with_dependencies, }, ) ) diff --git a/extensions/HuggingFace/python/src/aiconfig_extension_hugging_face/local_inference/image_2_text.py b/extensions/HuggingFace/python/src/aiconfig_extension_hugging_face/local_inference/image_2_text.py index 4aedf0500..be7af81b6 100644 --- a/extensions/HuggingFace/python/src/aiconfig_extension_hugging_face/local_inference/image_2_text.py +++ b/extensions/HuggingFace/python/src/aiconfig_extension_hugging_face/local_inference/image_2_text.py @@ -142,7 +142,7 @@ async def run( aiconfig: "AIConfigRuntime", options: InferenceOptions, parameters: Dict[str, Any], - **kwargs, + run_with_dependencies: Optional[bool] = False, ) -> list[Output]: await aiconfig.callback_manager.run_callbacks( CallbackEvent( @@ -152,6 +152,7 @@ async def run( "prompt": prompt, "options": options, "parameters": parameters, + "run_with_dependencies": run_with_dependencies, }, ) ) diff --git a/extensions/HuggingFace/python/src/aiconfig_extension_hugging_face/remote_inference_client/automatic_speech_recognition.py b/extensions/HuggingFace/python/src/aiconfig_extension_hugging_face/remote_inference_client/automatic_speech_recognition.py index 7747c1e15..dffa759a9 100644 --- a/extensions/HuggingFace/python/src/aiconfig_extension_hugging_face/remote_inference_client/automatic_speech_recognition.py +++ b/extensions/HuggingFace/python/src/aiconfig_extension_hugging_face/remote_inference_client/automatic_speech_recognition.py @@ -237,7 +237,7 @@ async def run( aiconfig: "AIConfigRuntime", options: InferenceOptions, parameters: Dict[str, Any], - **kwargs, + run_with_dependencies: Optional[bool] = False, ) -> list[Output]: """ Invoked to run a prompt in the .aiconfig. This method should perform @@ -263,6 +263,7 @@ async def run( "prompt": prompt, "options": options, "parameters": parameters, + "run_with_dependencies": run_with_dependencies, }, ) ) diff --git a/extensions/HuggingFace/python/src/aiconfig_extension_hugging_face/remote_inference_client/image_2_text.py b/extensions/HuggingFace/python/src/aiconfig_extension_hugging_face/remote_inference_client/image_2_text.py index cfdd91ad6..859e0e2af 100644 --- a/extensions/HuggingFace/python/src/aiconfig_extension_hugging_face/remote_inference_client/image_2_text.py +++ b/extensions/HuggingFace/python/src/aiconfig_extension_hugging_face/remote_inference_client/image_2_text.py @@ -243,7 +243,7 @@ async def run( aiconfig: "AIConfigRuntime", options: InferenceOptions, parameters: Dict[str, Any], - **kwargs, + run_with_dependencies: Optional[bool] = False, ) -> list[Output]: """ Invoked to run a prompt in the .aiconfig. This method should perform @@ -270,6 +270,7 @@ async def run( "prompt": prompt, "options": sanitized_options, "parameters": parameters, + "run_with_dependencies": run_with_dependencies, }, ) ) diff --git a/python/src/aiconfig/Config.py b/python/src/aiconfig/Config.py index 33ea6e26a..fad43b599 100644 --- a/python/src/aiconfig/Config.py +++ b/python/src/aiconfig/Config.py @@ -290,7 +290,7 @@ async def run( prompt_name: str, params: Optional[dict] = None, options: Optional[InferenceOptions] = None, - **kwargs, + run_with_dependencies: Optional[bool] = False, ): """ Executes the AI model with the resolved parameters and returns the API response. @@ -309,7 +309,7 @@ async def run( "prompt_name": prompt_name, "params": params, "options": options, - "kwargs": kwargs, + "run_with_dependencies": run_with_dependencies, }, ) await self.callback_manager.run_callbacks(event) @@ -330,11 +330,7 @@ async def run( self.delete_output(prompt_name) response = await model_provider.run( - prompt_data, - self, - options, - params, - **kwargs, # TODO: We should remove and make argument explicit + prompt_data, self, options, params, run_with_dependencies ) event = CallbackEvent( diff --git a/python/src/aiconfig/default_parsers/parameterized_model_parser.py b/python/src/aiconfig/default_parsers/parameterized_model_parser.py index dd4ee4c95..611cdb7e1 100644 --- a/python/src/aiconfig/default_parsers/parameterized_model_parser.py +++ b/python/src/aiconfig/default_parsers/parameterized_model_parser.py @@ -45,10 +45,9 @@ async def run( aiconfig: AIConfig, options: Optional[InferenceOptions] = None, parameters: Dict = {}, - **kwargs, # TODO: We should remove and make arguments explicit + run_with_dependencies: Optional[bool] = False, ) -> List[Output]: - # maybe use prompt metadata instead of kwargs? - if kwargs.get("run_with_dependencies", False): + if run_with_dependencies: return await self.run_with_dependencies( prompt, aiconfig, options, parameters ) diff --git a/python/src/aiconfig/model_parser.py b/python/src/aiconfig/model_parser.py index b582185e2..d1dc88e32 100644 --- a/python/src/aiconfig/model_parser.py +++ b/python/src/aiconfig/model_parser.py @@ -66,7 +66,7 @@ async def run( aiconfig: AIConfig, options: Optional["InferenceOptions"] = None, parameters: Dict = {}, - **kwargs, # TODO: Remove this, just a hack for now to ensure that it doesn't break + run_with_dependencies: Optional[bool] = False, ) -> ExecuteResult: """ Execute model inference based on completion data to be constructed in deserialize(), which includes the input prompt and diff --git a/python/tests/aiconfigs/travel_gpt_prompts_with_dependency.json b/python/tests/aiconfigs/travel_gpt_prompts_with_dependency.json new file mode 100644 index 000000000..6270cb44d --- /dev/null +++ b/python/tests/aiconfigs/travel_gpt_prompts_with_dependency.json @@ -0,0 +1,35 @@ +{ + "name": "NYC Trip Planner", + "schema_version": "latest", + "description": "Intrepid explorer with ChatGPT and AIConfig", + + "metadata": { + "parameters": {}, + "models": { + "gpt-3.5-turbo": { + "model": "gpt-3.5-turbo", + "top_p": 1, + "temperature": 1, + "stream": false + } + } + }, + + "prompts": [ + { + "name": "get_activities", + "input": "Tell me 10 fun attractions to do in {{city}}.", + "metadata": { + "model": "gpt-3.5-turbo" + } + }, + { + "name": "gen_itinerary", + "input": "Generate an itinerary ordered by {{order_by}} for these activities: {{get_activities.output}}.", + "metadata": { + "model": "gpt-3.5-turbo" + } + } + ], + "$schema": "https://json.schemastore.org/aiconfig-1.0" +} diff --git a/python/tests/conftest.py b/python/tests/conftest.py index 9e737fb3a..c7fd80643 100644 --- a/python/tests/conftest.py +++ b/python/tests/conftest.py @@ -99,6 +99,99 @@ def mock_openai_chat_completion(**kwargs): raise Exception("Unexpected arguments:\n {}".format(kwargs)) +def mock_openai_chat_completion_with_dependencies(**kwargs): + response_map_list = [ + [ + { + "model": "gpt-3.5-turbo", + "top_p": 1, + "temperature": 1, + "stream": False, + "messages": [ + { + "content": "Tell me 10 fun attractions to do in NYC.", + "role": "user", + } + ], + }, + ChatCompletion( + **{ + "id": "chatcmpl-8khHUHbetNyprE1ftmRu5WyVNP3O3", + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "content": '1. Visit Times Square: Experience the iconic "Crossroads of the World" with its dazzling billboards, Broadway shows, and lively atmosphere.\n2. Explore Central Park: Take a leisurely stroll or rent a bike to discover this sprawling oasis in the heart of Manhattan, complete with picturesque landscapes, walking trails, and various attractions.\n3. Take a ferry to the Statue of Liberty: Visit the renowned Statue of Liberty on Liberty Island and enjoy stunning views of the city skyline from the ferry ride itself.\n4. Visit the Metropolitan Museum of Art: Immerse yourself in world-class art collections spanning thousands of years and diverse cultures, all housed in the magnificent Met museum.\n5. Explore the High Line: Walk along the elevated park built on a historic freight rail line, offering beautiful green spaces, public art installations, and fantastic views of the city.\n6. Enjoy a Broadway show: Watch a live performance of a Broadway musical or play in one of the iconic theaters in the Theater District, offering a memorable experience for theater enthusiasts.\n7. Visit the 9/11 Memorial and Museum: Pay your respects at the site of the former World Trade Center twin towers and learn about the events of September 11, 2001, at the informative museum.\n8. Take a food tour in Greenwich Village: Indulge in a delicious gastronomic adventure, exploring the vibrant food scene in Greenwich Village, renowned for its diverse restaurants and eateries.\n9. Visit the Brooklyn Bridge: Take a walk across this iconic suspension bridge, providing breathtaking views of the Manhattan skyline and the East River.\n10. Explore the Museum of Modern Art (MoMA): Discover a vast collection of modern and contemporary art, including works by artists like Van Gogh, Picasso, Warhol, and many more at this renowned art institution.', + "role": "assistant", + }, + } + ], + "created": 1706140152, + "model": "gpt-3.5-turbo-0613", + "object": "chat.completion", + "usage": { + "completion_tokens": 363, + "prompt_tokens": 18, + "total_tokens": 381, + }, + } + ), + ], + # Example 2 + [ + { + "model": "gpt-3.5-turbo", + "temperature": 1, + "top_p": 1, + "stream": False, + "messages": [ + { + "content": "Tell me 10 fun attractions to do in NYC.", + "role": "user", + }, + { + "content": '1. Visit Times Square: Experience the iconic "Crossroads of the World" with its dazzling billboards, Broadway shows, and lively atmosphere.\n2. Explore Central Park: Take a leisurely stroll or rent a bike to discover this sprawling oasis in the heart of Manhattan, complete with picturesque landscapes, walking trails, and various attractions.\n3. Take a ferry to the Statue of Liberty: Visit the renowned Statue of Liberty on Liberty Island and enjoy stunning views of the city skyline from the ferry ride itself.\n4. Visit the Metropolitan Museum of Art: Immerse yourself in world-class art collections spanning thousands of years and diverse cultures, all housed in the magnificent Met museum.\n5. Explore the High Line: Walk along the elevated park built on a historic freight rail line, offering beautiful green spaces, public art installations, and fantastic views of the city.\n6. Enjoy a Broadway show: Watch a live performance of a Broadway musical or play in one of the iconic theaters in the Theater District, offering a memorable experience for theater enthusiasts.\n7. Visit the 9/11 Memorial and Museum: Pay your respects at the site of the former World Trade Center twin towers and learn about the events of September 11, 2001, at the informative museum.\n8. Take a food tour in Greenwich Village: Indulge in a delicious gastronomic adventure, exploring the vibrant food scene in Greenwich Village, renowned for its diverse restaurants and eateries.\n9. Visit the Brooklyn Bridge: Take a walk across this iconic suspension bridge, providing breathtaking views of the Manhattan skyline and the East River.\n10. Explore the Museum of Modern Art (MoMA): Discover a vast collection of modern and contemporary art, including works by artists like Van Gogh, Picasso, Warhol, and many more at this renowned art institution.', + "role": "assistant", + }, + { + "content": "Generate an itinerary ordered by geographic location for these activities: 1. Visit Times Square: Experience the iconic "Crossroads of the World" with its dazzling billboards, Broadway shows, and lively atmosphere.\n2. Explore Central Park: Take a leisurely stroll or rent a bike to discover this sprawling oasis in the heart of Manhattan, complete with picturesque landscapes, walking trails, and various attractions.\n3. Take a ferry to the Statue of Liberty: Visit the renowned Statue of Liberty on Liberty Island and enjoy stunning views of the city skyline from the ferry ride itself.\n4. Visit the Metropolitan Museum of Art: Immerse yourself in world-class art collections spanning thousands of years and diverse cultures, all housed in the magnificent Met museum.\n5. Explore the High Line: Walk along the elevated park built on a historic freight rail line, offering beautiful green spaces, public art installations, and fantastic views of the city.\n6. Enjoy a Broadway show: Watch a live performance of a Broadway musical or play in one of the iconic theaters in the Theater District, offering a memorable experience for theater enthusiasts.\n7. Visit the 9/11 Memorial and Museum: Pay your respects at the site of the former World Trade Center twin towers and learn about the events of September 11, 2001, at the informative museum.\n8. Take a food tour in Greenwich Village: Indulge in a delicious gastronomic adventure, exploring the vibrant food scene in Greenwich Village, renowned for its diverse restaurants and eateries.\n9. Visit the Brooklyn Bridge: Take a walk across this iconic suspension bridge, providing breathtaking views of the Manhattan skyline and the East River.\n10. Explore the Museum of Modern Art (MoMA): Discover a vast collection of modern and contemporary art, including works by artists like Van Gogh, Picasso, Warhol, and many more at this renowned art institution..", + "role": "user", + }, + ], + }, + ChatCompletion( + **{ + "id": "chatcmpl-8khHahyYOoH456N6fjXgs2PQjfqDD", + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "content": "Here's an itinerary ordered by geographic location:\n\n1. Start your day at Times Square.\n2. From there, head south to the 9/11 Memorial and Museum.\n3. After paying your respects, take a walk to the nearby Staten Island Ferry Terminal to catch a ferry to the Statue of Liberty on Liberty Island.\n4. Return from the ferry and head north to the High Line, located in the Chelsea neighborhood.\n5. Continue north to the Museum of Modern Art (MoMA) in Midtown Manhattan.\n6. From MoMA, head east to visit Central Park.\n7. Explore Central Park at your leisure, taking a stroll or renting a bike to fully enjoy the park's attractions.\n8. Afterward, head downtown to the Metropolitan Museum of Art (Met) on the Upper East Side to immerse yourself in its world-class art collections.\n9. From the Met, travel southwest to Greenwich Village for a delightful food tour, exploring the diverse culinary offerings.\n10. Wrap up your day by walking across the Brooklyn Bridge to enjoy stunning views of the Manhattan skyline and the East River.\n\nNote: This itinerary can be adjusted based on personal preferences and time availability.", + "role": "assistant", + }, + } + ], + "created": 1706140158, + "model": "gpt-3.5-turbo-0613", + "object": "chat.completion", + "usage": { + "completion_tokens": 236, + "prompt_tokens": 767, + "total_tokens": 1003, + }, + } + ), + ], + ] + + for input_params, response in response_map_list: + if kwargs == input_params: + return response + raise Exception("Unexpected arguments:\n {}".format(kwargs)) + + @pytest.fixture def set_temporary_env_vars(): """ diff --git a/python/tests/test_run_config.py b/python/tests/test_run_config.py index 702824a32..518e0f4de 100644 --- a/python/tests/test_run_config.py +++ b/python/tests/test_run_config.py @@ -1,9 +1,14 @@ +from unittest.mock import Mock + import openai import pytest from aiconfig.Config import AIConfigRuntime from mock import patch -from .conftest import mock_openai_chat_completion +from .conftest import ( + mock_openai_chat_completion, + mock_openai_chat_completion_with_dependencies, +) from .util.file_path_utils import get_absolute_file_path_from_relative @@ -48,3 +53,37 @@ async def test_load_parametrized_data_config(set_temporary_env_vars): }, ], } + + +@pytest.mark.asyncio +async def test_running_prompt_with_dependencies(set_temporary_env_vars): + """Test running a prompt with dependencies with the run_with_dependencies flag set to True""" + + mock_openai = Mock( + side_effect=mock_openai_chat_completion_with_dependencies + ) + + with patch.object( + openai.resources.chat.Completions, + "create", + new=mock_openai, + ): + config_relative_path = ( + "aiconfigs/travel_gpt_prompts_with_dependency.json" + ) + config_absolute_path = get_absolute_file_path_from_relative( + __file__, config_relative_path + ) + config = AIConfigRuntime.load(config_absolute_path) + + combined_prompt_parameters = { + "city": "NYC", + "order_by": "geographic location", + } + await config.run( + "gen_itinerary", + combined_prompt_parameters, + run_with_dependencies=True, + ) + + assert mock_openai.call_count == 2