From 8b17311fff6140b505cfb86146957e5d7f7bea1a Mon Sep 17 00:00:00 2001 From: Victoria Hall Date: Tue, 6 Jan 2026 14:33:14 -0600 Subject: [PATCH 1/2] update mcp & openai api spec --- azure/functions/decorators/function_app.py | 127 +++++++++--------- azure/functions/decorators/mcp.py | 2 +- azure/functions/decorators/openai.py | 16 +-- azure/functions/mcp.py | 4 +- .../official/jobs/publish-release.yml | 2 +- tests/decorators/test_mcp.py | 14 +- tests/decorators/test_openai.py | 48 +++---- tests/test_mcp.py | 38 +++--- 8 files changed, 124 insertions(+), 127 deletions(-) diff --git a/azure/functions/decorators/function_app.py b/azure/functions/decorators/function_app.py index 16482aa3..b1972fb9 100644 --- a/azure/functions/decorators/function_app.py +++ b/azure/functions/decorators/function_app.py @@ -42,12 +42,12 @@ parse_iterable_param_to_enums, StringifyEnumJsonEncoder from azure.functions.http import HttpRequest from .generic import GenericInputBinding, GenericTrigger, GenericOutputBinding -from .openai import AssistantSkillTrigger, OpenAIModels, TextCompletionInput, \ - AssistantCreateOutput, \ - AssistantQueryInput, AssistantPostInput, InputType, EmbeddingsInput, \ +from .openai import _AssistantSkillTrigger, OpenAIModels, _TextCompletionInput, \ + _AssistantCreateOutput, \ + _AssistantQueryInput, _AssistantPostInput, InputType, _EmbeddingsInput, \ semantic_search_system_prompt, \ - SemanticSearchInput, EmbeddingsStoreOutput -from .mcp import MCPToolTrigger, build_property_metadata + _SemanticSearchInput, _EmbeddingsStoreOutput +from .mcp import _MCPToolTrigger, build_property_metadata from .retry_policy import RetryPolicy from .function_name import FunctionName from .warmup import WarmUpTrigger @@ -1533,8 +1533,7 @@ def mcp_tool_trigger(self, tool_properties: Optional[str] = None, data_type: Optional[Union[DataType, str]] = None, **kwargs) -> Callable[..., Any]: - """ - The `mcp_tool_trigger` decorator adds :class:`MCPToolTrigger` to the + """The `mcp_tool_trigger` decorator adds :class:`MCPToolTrigger` to the :class:`FunctionBuilder` object for building a :class:`Function` object used in the worker function indexing model. @@ -1563,7 +1562,7 @@ def mcp_tool_trigger(self, def wrap(fb): def decorator(): fb.add_trigger( - trigger=MCPToolTrigger( + trigger=_MCPToolTrigger( name=arg_name, tool_name=tool_name, description=description, @@ -1578,12 +1577,12 @@ def decorator(): return wrap def mcp_tool(self): - """ - Decorator to register an MCP tool function. + """Decorator to register an MCP tool function. + Ref: https://aka.ms/remote-mcp-functions-python - Automatically: + This decorator performs the following actions automatically: - Infers tool name from function name - - Extracts first line of docstring as description + - Extracts docstrings as description - Extracts parameters and types for tool properties - Handles MCPToolContext injection """ @@ -1645,7 +1644,7 @@ async def wrapper(context: str, *args, **kwargs): # Add the MCP trigger fb.add_trigger( - trigger=MCPToolTrigger( + trigger=_MCPToolTrigger( name="context", tool_name=tool_name, description=description, @@ -1663,23 +1662,16 @@ def mcp_tool_property(self, arg_name: str, as_array: Optional[bool] = False): """ Decorator for defining explicit MCP tool property metadata for a specific argument. + Ref: https://aka.ms/remote-mcp-functions-python - :param arg_name: The name of the argument. - :param description: The description of the argument. - :param property_type: The type of the argument. - :param is_required: If the argument is required or not. - :param as_array: If the argument should be passed as an array or not. - + :param str arg_name: The name of the argument. + :keyword str description: The description of the argument. + :keyword property_type: The type of the argument. + :type property_type: + ~azure.functions.decorators.core.McpPropertyType + :keyword bool is_required: If the argument is required or not. + :keyword bool as_array: If the argument should be passed as an array or not. :return: Decorator function. - - Example: - @app.mcp_tool_property( - arg_name="snippetname", - description="The name of the snippet.", - property_type=func.McpPropertyType.STRING, - is_required=True, - as_array=False - ) """ def decorator(func): # If this function is already wrapped by FunctionBuilder or similar, unwrap it @@ -1859,15 +1851,14 @@ def assistant_skill_trigger(self, data_type: Optional[ Union[DataType, str]] = None, **kwargs: Any) -> Callable[..., Any]: - """ - Assistants build on top of chat functionality by supporting custom skills + """Assistants build on top of chat functionality by supporting custom skills defined as functions. This internally uses OpenAI’s function calling capabilities in GPT models to determine which functions to invoke and when. Ref: https://platform.openai.com/docs/guides/function-calling You can define functions to be triggered by assistants using the - `assistantSkillTrigger` trigger binding. These functions are invoked by the + assistantSkillTrigger trigger binding. These functions are invoked by the extension when an assistant signals it would like to invoke a function in response to a user prompt. @@ -1875,19 +1866,21 @@ def assistant_skill_trigger(self, parameter descriptions are all used as hints by the language model to determine when and how to invoke an assistant function. - :param arg_name: The name of the trigger parameter in the function code. - :param function_description: A description of the assistant function, + :param str arg_name: The name of the trigger parameter in the function code. + :param str function_description: A description of the assistant function, which is provided to the model. - :param function_name: The name of the assistant function, which is + :keyword str function_name: The name of the assistant function, which is passed to the language model. - :param parameter_description_json: A JSON-formatted description of the + :keyword str parameter_description_json: A JSON-formatted description of the function parameters, provided to the model. If omitted, the description is autogenerated. - :param data_type: Defines how the Functions runtime should treat the + :keyword data_type: Defines how the Functions runtime should treat the parameter value. - :param kwargs: Additional keyword arguments for specifying binding fields + :type data_type: + ~azure.functions.decorators.core.DataType or + str or None + :keyword kwargs: Additional keyword arguments for specifying binding fields to include in the `function.json`. - :return: Decorator function. """ @@ -1895,7 +1888,7 @@ def assistant_skill_trigger(self, def wrap(fb): def decorator(): fb.add_trigger( - trigger=AssistantSkillTrigger( + trigger=_AssistantSkillTrigger( name=arg_name, function_description=function_description, function_name=function_name, @@ -3413,7 +3406,7 @@ def text_completion_input(self, def wrap(fb): def decorator(): fb.add_binding( - binding=TextCompletionInput( + binding=_TextCompletionInput( name=arg_name, prompt=prompt, ai_connection_name=ai_connection_name, @@ -3436,14 +3429,16 @@ def assistant_create_output(self, arg_name: str, Union[DataType, str]] = None, **kwargs) \ -> Callable[..., Any]: - """ - The `assistantCreate` output binding creates a new assistant with a specified system prompt. - - :param arg_name: The name of the binding parameter in the function code. - :param data_type: Defines how the Functions runtime should treat the parameter value. - :param kwargs: Additional keyword arguments for specifying extra binding fields + """The assistantCreate output binding creates a new assistant with a specified system + prompt. + + :param str arg_name: The name of the binding parameter in the function code. + :keyword data_type: Defines how the Functions runtime should treat the parameter value. + :type data_type: + ~azure.functions.decorators.core.DataType or + str or None + :keyword kwargs: Additional keyword arguments for specifying extra binding fields to include in the `function.json`. - :return: Decorator function. """ @@ -3451,7 +3446,7 @@ def assistant_create_output(self, arg_name: str, def wrap(fb): def decorator(): fb.add_binding( - binding=AssistantCreateOutput( + binding=_AssistantCreateOutput( name=arg_name, data_type=parse_singular_param_to_enum(data_type, DataType), @@ -3472,27 +3467,29 @@ def assistant_query_input(self, Union[DataType, str]] = None, **kwargs) \ -> Callable[..., Any]: - """ - The `assistantQuery` input binding retrieves assistant chat history and + """The `assistantQuery` input binding retrieves assistant chat history and passes it to the function. This is typically used to provide the function access to previous messages in a conversation, enabling more context-aware responses. - :param arg_name: The name of the binding parameter in the function code. - :param timestamp_utc: The earliest timestamp (in UTC) for the messages to + :param str arg_name: The name of the binding parameter in the function code. + :param str id: The unique identifier of the assistant whose history is being + queried. + :param str timestamp_utc: The earliest timestamp (in UTC) for the messages to retrieve from the chat history. Must be in ISO 8601 format, e.g., `"2023-08-01T00:00:00Z"`. - :param chat_storage_connection_setting: The name of the configuration section + :keyword str chat_storage_connection_setting: The name of the configuration section containing the connection settings for assistant chat storage. Defaults to - `"AzureWebJobsStorage"`. - :param collection_name: The name of the table or collection used for assistant - chat storage. Defaults to `"ChatState"`. - :param id: The unique identifier of the assistant whose history is being - queried. - :param data_type: Defines how the Functions runtime should treat the + "AzureWebJobsStorage". + :keyword str collection_name: The name of the table or collection used for assistant + chat storage. Defaults to "ChatState". + :keyword data_type: Defines how the Functions runtime should treat the parameter value. - :param kwargs: Additional keyword arguments for specifying binding fields to + :type data_type: + ~azure.functions.decorators.core.DataType or + str or None + :keyword kwargs: Additional keyword arguments for specifying binding fields to include in the `function.json`. :return: Decorator function. @@ -3502,7 +3499,7 @@ def assistant_query_input(self, def wrap(fb): def decorator(): fb.add_binding( - binding=AssistantQueryInput( + binding=_AssistantQueryInput( name=arg_name, id=id, timestamp_utc=timestamp_utc, @@ -3580,7 +3577,7 @@ def assistant_post_input(self, arg_name: str, def wrap(fb): def decorator(): fb.add_binding( - binding=AssistantPostInput( + binding=_AssistantPostInput( name=arg_name, id=id, user_message=user_message, @@ -3654,7 +3651,7 @@ def embeddings_input(self, def wrap(fb): def decorator(): fb.add_binding( - binding=EmbeddingsInput( + binding=_EmbeddingsInput( name=arg_name, input=input, input_type=input_type, @@ -3746,7 +3743,7 @@ def semantic_search_input(self, def wrap(fb): def decorator(): fb.add_binding( - binding=SemanticSearchInput( + binding=_SemanticSearchInput( name=arg_name, search_connection_name=search_connection_name, collection=collection, @@ -3829,7 +3826,7 @@ def embeddings_store_output(self, def wrap(fb): def decorator(): fb.add_binding( - binding=EmbeddingsStoreOutput( + binding=_EmbeddingsStoreOutput( name=arg_name, input=input, input_type=input_type, diff --git a/azure/functions/decorators/mcp.py b/azure/functions/decorators/mcp.py index 91a51777..4f92dae8 100644 --- a/azure/functions/decorators/mcp.py +++ b/azure/functions/decorators/mcp.py @@ -22,7 +22,7 @@ } -class MCPToolTrigger(Trigger): +class _MCPToolTrigger(Trigger): @staticmethod def get_binding_name() -> str: diff --git a/azure/functions/decorators/openai.py b/azure/functions/decorators/openai.py index f0e4901d..0d6fb429 100644 --- a/azure/functions/decorators/openai.py +++ b/azure/functions/decorators/openai.py @@ -23,7 +23,7 @@ class OpenAIModels(StringifyEnum): DefaultEmbeddingsModel = "text-embedding-ada-002" -class AssistantSkillTrigger(Trigger): +class _AssistantSkillTrigger(Trigger): @staticmethod def get_binding_name() -> str: @@ -42,7 +42,7 @@ def __init__(self, super().__init__(name=name, data_type=data_type) -class TextCompletionInput(InputBinding): +class _TextCompletionInput(InputBinding): @staticmethod def get_binding_name() -> str: @@ -71,7 +71,7 @@ def __init__(self, super().__init__(name=name, data_type=data_type) -class AssistantQueryInput(InputBinding): +class _AssistantQueryInput(InputBinding): @staticmethod def get_binding_name(): @@ -92,7 +92,7 @@ def __init__(self, super().__init__(name=name, data_type=data_type) -class EmbeddingsInput(InputBinding): +class _EmbeddingsInput(InputBinding): @staticmethod def get_binding_name() -> str: @@ -137,7 +137,7 @@ def __init__(self, to the end of your answer on a separate line.""" -class SemanticSearchInput(InputBinding): +class _SemanticSearchInput(InputBinding): @staticmethod def get_binding_name() -> str: @@ -179,7 +179,7 @@ def __init__(self, super().__init__(name=name, data_type=data_type) -class AssistantPostInput(InputBinding): +class _AssistantPostInput(InputBinding): @staticmethod def get_binding_name(): @@ -214,7 +214,7 @@ def __init__(self, name: str, super().__init__(name=name, data_type=data_type) -class EmbeddingsStoreOutput(OutputBinding): +class _EmbeddingsStoreOutput(OutputBinding): @staticmethod def get_binding_name() -> str: @@ -246,7 +246,7 @@ def __init__(self, super().__init__(name=name, data_type=data_type) -class AssistantCreateOutput(OutputBinding): +class _AssistantCreateOutput(OutputBinding): @staticmethod def get_binding_name(): diff --git a/azure/functions/mcp.py b/azure/functions/mcp.py index 5e09ec18..97a9c923 100644 --- a/azure/functions/mcp.py +++ b/azure/functions/mcp.py @@ -12,8 +12,8 @@ class MCPToolContext(typing.Dict[str, typing.Any]): pass -class MCPToolTriggerConverter(meta.InConverter, binding='mcpToolTrigger', - trigger=True): +class _MCPToolTriggerConverter(meta.InConverter, binding='mcpToolTrigger', + trigger=True): @classmethod def check_input_type_annotation(cls, pytype: type) -> bool: diff --git a/eng/templates/official/jobs/publish-release.yml b/eng/templates/official/jobs/publish-release.yml index 811ff9be..16fa8312 100644 --- a/eng/templates/official/jobs/publish-release.yml +++ b/eng/templates/official/jobs/publish-release.yml @@ -145,7 +145,7 @@ jobs: # Modify SDK Version in pyproject.toml Write-Host "Replacing SDK version in worker's pyproject.toml" - ((Get-Content workers/pyproject.toml) -replace '"azure-functions==(\d)+.(\d)+.*"','"azure-functions==$(NewLibraryVersion)"' -join "`n") + "`n" | Set-Content -NoNewline workers/pyproject.toml + ((Get-Content workers/pyproject.toml) -replace '"azure-functions==[\d\.a-z]+; python_version >= ''3\.10''"','"azure-functions==$(NewLibraryVersion); python_version >= ''3.10''"' -join "`n") + "`n" | Set-Content -NoNewline workers/pyproject.toml # Commit Python Version Write-Host "Pushing $newBranch to azure-functions-python-worker repo" diff --git a/tests/decorators/test_mcp.py b/tests/decorators/test_mcp.py index a142810f..8905b590 100644 --- a/tests/decorators/test_mcp.py +++ b/tests/decorators/test_mcp.py @@ -6,14 +6,14 @@ import azure.functions as func from azure.functions import DataType, MCPToolContext from azure.functions.decorators.core import BindingDirection -from azure.functions.decorators.mcp import MCPToolTrigger -from azure.functions.mcp import MCPToolTriggerConverter +from azure.functions.decorators.mcp import _MCPToolTrigger +from azure.functions.mcp import _MCPToolTriggerConverter from azure.functions.meta import Datum class TestMCP(unittest.TestCase): def test_mcp_tool_trigger_valid_creation(self): - trigger = MCPToolTrigger( + trigger = _MCPToolTrigger( name="context", tool_name="hello", description="Hello world.", @@ -21,7 +21,7 @@ def test_mcp_tool_trigger_valid_creation(self): data_type=DataType.UNDEFINED, dummy_field="dummy", ) - self.assertEqual(trigger.get_binding_name(), "mcpToolTrigger") + self.assertEqual(trigger.get_binding_name(), "_MCPToolTrigger") self.assertEqual( trigger.get_dict_repr(), { @@ -29,7 +29,7 @@ def test_mcp_tool_trigger_valid_creation(self): "toolName": "hello", "description": "Hello world.", "toolProperties": "[]", - "type": "mcpToolTrigger", + "type": "_MCPToolTrigger", "dataType": DataType.UNDEFINED, "dummyField": "dummy", "direction": BindingDirection.IN, @@ -39,13 +39,13 @@ def test_mcp_tool_trigger_valid_creation(self): def test_trigger_converter(self): # Test with string data datum = Datum(value='{"arguments":{}}', type='string') - result = MCPToolTriggerConverter.decode(datum, trigger_metadata={}) + result = _MCPToolTriggerConverter.decode(datum, trigger_metadata={}) self.assertEqual(result, '{"arguments":{}}') self.assertIsInstance(result, str) # Test with json data datum_json = Datum(value={"arguments": {}}, type='json') - result_json = MCPToolTriggerConverter.decode(datum_json, trigger_metadata={}) + result_json = _MCPToolTriggerConverter.decode(datum_json, trigger_metadata={}) self.assertEqual(result_json, {"arguments": {}}) self.assertIsInstance(result_json, dict) diff --git a/tests/decorators/test_openai.py b/tests/decorators/test_openai.py index 424fb200..21a5c6a9 100644 --- a/tests/decorators/test_openai.py +++ b/tests/decorators/test_openai.py @@ -3,22 +3,22 @@ from azure.functions import DataType from azure.functions.decorators.core import BindingDirection from azure.functions.decorators.openai import ( - AssistantSkillTrigger, - TextCompletionInput, + _AssistantSkillTrigger, + _TextCompletionInput, OpenAIModels, - AssistantQueryInput, - EmbeddingsInput, - AssistantCreateOutput, - SemanticSearchInput, - EmbeddingsStoreOutput, - AssistantPostInput, + _AssistantQueryInput, + _EmbeddingsInput, + _AssistantCreateOutput, + _SemanticSearchInput, + _EmbeddingsStoreOutput, + _AssistantPostInput, ) class TestOpenAI(unittest.TestCase): def test_assistant_skill_trigger_valid_creation(self): - trigger = AssistantSkillTrigger( + trigger = _AssistantSkillTrigger( name="test", function_description="description", function_name="test_function_name", @@ -26,7 +26,7 @@ def test_assistant_skill_trigger_valid_creation(self): data_type=DataType.UNDEFINED, dummy_field="dummy", ) - self.assertEqual(trigger.get_binding_name(), "assistantSkillTrigger") + self.assertEqual(trigger.get_binding_name(), "_AssistantSkillTrigger") self.assertEqual( trigger.get_dict_repr(), { @@ -35,14 +35,14 @@ def test_assistant_skill_trigger_valid_creation(self): "functionName": "test_function_name", "parameterDescriptionJson": "test_json", "dataType": DataType.UNDEFINED, - "type": "assistantSkillTrigger", + "type": "_AssistantSkillTrigger", "dummyField": "dummy", "direction": BindingDirection.IN, }, ) def test_text_completion_input_valid_creation(self): - input = TextCompletionInput( + input = _TextCompletionInput( name="test", prompt="test_prompt", temperature="1", @@ -72,7 +72,7 @@ def test_text_completion_input_valid_creation(self): ) def test_text_completion_input_with_string_chat_model(self): - input = TextCompletionInput( + input = _TextCompletionInput( name="test", prompt="test_prompt", temperature="1", @@ -102,14 +102,14 @@ def test_text_completion_input_with_string_chat_model(self): ) def test_assistant_query_input_valid_creation(self): - input = AssistantQueryInput( + input = _AssistantQueryInput( name="test", timestamp_utc="timestamp_utc", chat_storage_connection_setting="AzureWebJobsStorage", # noqa: E501 collection_name="ChatState", data_type=DataType.UNDEFINED, id="test_id", - type="assistantQueryInput", + type="_AssistantQueryInput", dummy_field="dummy", ) self.assertEqual(input.get_binding_name(), "assistantQuery") @@ -129,7 +129,7 @@ def test_assistant_query_input_valid_creation(self): ) def test_embeddings_input_valid_creation(self): - input = EmbeddingsInput( + input = _EmbeddingsInput( name="test", data_type=DataType.UNDEFINED, input="test_input", @@ -159,7 +159,7 @@ def test_embeddings_input_valid_creation(self): ) def test_embeddings_input_with_enum_embeddings_model(self): - input = EmbeddingsInput( + input = _EmbeddingsInput( name="test", data_type=DataType.UNDEFINED, input="test_input", @@ -189,7 +189,7 @@ def test_embeddings_input_with_enum_embeddings_model(self): ) def test_assistant_create_output_valid_creation(self): - output = AssistantCreateOutput( + output = _AssistantCreateOutput( name="test", data_type=DataType.UNDEFINED ) self.assertEqual(output.get_binding_name(), "assistantCreate") @@ -204,7 +204,7 @@ def test_assistant_create_output_valid_creation(self): ) def test_assistant_post_input_valid_creation(self): - input = AssistantPostInput( + input = _AssistantPostInput( name="test", id="test_id", chat_model="test_model", @@ -240,7 +240,7 @@ def test_assistant_post_input_valid_creation(self): ) def test_assistant_post_input_with_enum_chat_model(self): - input = AssistantPostInput( + input = _AssistantPostInput( name="test", id="test_id", chat_model=OpenAIModels.DefaultChatModel, @@ -276,7 +276,7 @@ def test_assistant_post_input_with_enum_chat_model(self): ) def test_semantic_search_input_valid_creation(self): - input = SemanticSearchInput( + input = _SemanticSearchInput( name="test", data_type=DataType.UNDEFINED, chat_model=OpenAIModels.DefaultChatModel, @@ -316,7 +316,7 @@ def test_semantic_search_input_valid_creation(self): ) def test_semantic_search_input_with_string_models(self): - input = SemanticSearchInput( + input = _SemanticSearchInput( name="test", data_type=DataType.UNDEFINED, chat_model="gpt-4o", @@ -356,7 +356,7 @@ def test_semantic_search_input_with_string_models(self): ) def test_embeddings_store_output_valid_creation(self): - output = EmbeddingsStoreOutput( + output = _EmbeddingsStoreOutput( name="test", data_type=DataType.UNDEFINED, input="test_input", @@ -390,7 +390,7 @@ def test_embeddings_store_output_valid_creation(self): ) def test_embeddings_store_output_with_string_embeddings_model(self): - output = EmbeddingsStoreOutput( + output = _EmbeddingsStoreOutput( name="test", data_type=DataType.UNDEFINED, input="test_input", diff --git a/tests/test_mcp.py b/tests/test_mcp.py index e322c25e..de46c0e4 100644 --- a/tests/test_mcp.py +++ b/tests/test_mcp.py @@ -3,74 +3,74 @@ import unittest import azure.functions as func from azure.functions.meta import Datum -from azure.functions.mcp import MCPToolTriggerConverter +from azure.functions.mcp import _MCPToolTriggerConverter class TestMCPToolTriggerConverter(unittest.TestCase): - """Unit tests for MCPToolTriggerConverter""" + """Unit tests for _MCPToolTriggerConverter""" def test_check_input_type_annotation_valid_types(self): - self.assertTrue(MCPToolTriggerConverter.check_input_type_annotation(str)) - self.assertTrue(MCPToolTriggerConverter.check_input_type_annotation(dict)) - self.assertTrue(MCPToolTriggerConverter.check_input_type_annotation(bytes)) - self.assertTrue(MCPToolTriggerConverter.check_input_type_annotation(func.MCPToolContext)) + self.assertTrue(_MCPToolTriggerConverter.check_input_type_annotation(str)) + self.assertTrue(_MCPToolTriggerConverter.check_input_type_annotation(dict)) + self.assertTrue(_MCPToolTriggerConverter.check_input_type_annotation(bytes)) + self.assertTrue(_MCPToolTriggerConverter.check_input_type_annotation(func.MCPToolContext)) def test_check_input_type_annotation_invalid_type(self): with self.assertRaises(TypeError): - MCPToolTriggerConverter.check_input_type_annotation(123) # not a type + _MCPToolTriggerConverter.check_input_type_annotation(123) # not a type class Dummy: pass - self.assertFalse(MCPToolTriggerConverter.check_input_type_annotation(Dummy)) + self.assertFalse(_MCPToolTriggerConverter.check_input_type_annotation(Dummy)) def test_has_implicit_output(self): - self.assertTrue(MCPToolTriggerConverter.has_implicit_output()) + self.assertTrue(_MCPToolTriggerConverter.has_implicit_output()) def test_decode_json(self): data = Datum(type='json', value={'foo': 'bar'}) - result = MCPToolTriggerConverter.decode(data, trigger_metadata={}) + result = _MCPToolTriggerConverter.decode(data, trigger_metadata={}) self.assertEqual(result, {'foo': 'bar'}) def test_decode_string(self): data = Datum(type='string', value='hello') - result = MCPToolTriggerConverter.decode(data, trigger_metadata={}) + result = _MCPToolTriggerConverter.decode(data, trigger_metadata={}) self.assertEqual(result, 'hello') def test_decode_bytes(self): data = Datum(type='bytes', value=b'data') - result = MCPToolTriggerConverter.decode(data, trigger_metadata={}) + result = _MCPToolTriggerConverter.decode(data, trigger_metadata={}) self.assertEqual(result, b'data') def test_decode_other_without_python_value(self): data = Datum(type='other', value='fallback') - result = MCPToolTriggerConverter.decode(data, trigger_metadata={}) + result = _MCPToolTriggerConverter.decode(data, trigger_metadata={}) self.assertEqual(result, 'fallback') def test_encode_none(self): - result = MCPToolTriggerConverter.encode(None) + result = _MCPToolTriggerConverter.encode(None) self.assertEqual(result.type, 'string') self.assertEqual(result.value, '') def test_encode_string(self): - result = MCPToolTriggerConverter.encode('hello') + result = _MCPToolTriggerConverter.encode('hello') self.assertEqual(result.type, 'string') self.assertEqual(result.value, 'hello') def test_encode_bytes(self): - result = MCPToolTriggerConverter.encode(b'\x00\x01') + result = _MCPToolTriggerConverter.encode(b'\x00\x01') self.assertEqual(result.type, 'bytes') self.assertEqual(result.value, b'\x00\x01') def test_encode_bytearray(self): - result = MCPToolTriggerConverter.encode(bytearray(b'\x01\x02')) + result = _MCPToolTriggerConverter.encode(bytearray(b'\x01\x02')) self.assertEqual(result.type, 'bytes') self.assertEqual(result.value, b'\x01\x02') def test_encode_other_type(self): - result = MCPToolTriggerConverter.encode(42) + result = _MCPToolTriggerConverter.encode(42) self.assertEqual(result.type, 'string') self.assertEqual(result.value, '42') - result = MCPToolTriggerConverter.encode({'a': 1}) + result = _MCPToolTriggerConverter.encode({'a': 1}) self.assertEqual(result.type, 'string') self.assertIn("'a'", result.value) From 0ec6640ed334c5c3e9bd51d00669268da42c9ae9 Mon Sep 17 00:00:00 2001 From: Victoria Hall Date: Tue, 6 Jan 2026 14:55:54 -0600 Subject: [PATCH 2/2] fix tests --- tests/decorators/test_mcp.py | 4 ++-- tests/decorators/test_openai.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/decorators/test_mcp.py b/tests/decorators/test_mcp.py index 8905b590..bf9a8fe0 100644 --- a/tests/decorators/test_mcp.py +++ b/tests/decorators/test_mcp.py @@ -21,7 +21,7 @@ def test_mcp_tool_trigger_valid_creation(self): data_type=DataType.UNDEFINED, dummy_field="dummy", ) - self.assertEqual(trigger.get_binding_name(), "_MCPToolTrigger") + self.assertEqual(trigger.get_binding_name(), "mcpToolTrigger") self.assertEqual( trigger.get_dict_repr(), { @@ -29,7 +29,7 @@ def test_mcp_tool_trigger_valid_creation(self): "toolName": "hello", "description": "Hello world.", "toolProperties": "[]", - "type": "_MCPToolTrigger", + "type": "mcpToolTrigger", "dataType": DataType.UNDEFINED, "dummyField": "dummy", "direction": BindingDirection.IN, diff --git a/tests/decorators/test_openai.py b/tests/decorators/test_openai.py index 21a5c6a9..42e403ff 100644 --- a/tests/decorators/test_openai.py +++ b/tests/decorators/test_openai.py @@ -26,7 +26,7 @@ def test_assistant_skill_trigger_valid_creation(self): data_type=DataType.UNDEFINED, dummy_field="dummy", ) - self.assertEqual(trigger.get_binding_name(), "_AssistantSkillTrigger") + self.assertEqual(trigger.get_binding_name(), "assistantSkillTrigger") self.assertEqual( trigger.get_dict_repr(), { @@ -35,7 +35,7 @@ def test_assistant_skill_trigger_valid_creation(self): "functionName": "test_function_name", "parameterDescriptionJson": "test_json", "dataType": DataType.UNDEFINED, - "type": "_AssistantSkillTrigger", + "type": "assistantSkillTrigger", "dummyField": "dummy", "direction": BindingDirection.IN, },