Repository: jakecyr/openai-function-calling

Issue:
Add support of `strict: True` for function json schema generation
## Overview of Feature

OpenAI API has provided `strict` parameter months ago, I think it would be nice to support a new parameter when use `to_json_schema`, like `function_name.to_json_schema(strict: True)`

https://platform.openai.com/docs/guides/function-calling#function-calling-with-structured-outputs

## Why add this feature?

When you enable Structured Outputs by supplying `strict: true`, the OpenAI API will pre-process your supplied schema on your first request, and then use this artifact to constrain the model to your schema.

Hints from issue comments:
@jakecyr: @cestivan Added a new `strict` parameter to the `Function` constructor. Thank you for the suggestion!

Solution patch:
diff --git a/openai_function_calling/function.py b/openai_function_calling/function.py
index cf0de34..c921497 100644
--- a/openai_function_calling/function.py
+++ b/openai_function_calling/function.py
@@ -26,6 +26,7 @@ class FunctionDict(TypedDict):
     name: str
     description: str
     parameters: ParametersDict
+    strict: NotRequired[bool]
 
 
 class Function:
@@ -37,6 +38,7 @@ class Function:
         description: str,
         parameters: list[Parameter] | None = None,
         required_parameters: list[str] | None = None,
+        strict: bool | None = None,
     ) -> None:
         """Create a new function instance.
 
@@ -46,12 +48,14 @@ class Function:
             parameters: A list of parameters.
             required_parameters: A list of parameter names that are required to run the\
                 function.
+            strict: If the function should enforce strict parameters.
 
         """
         self.name: str = name
         self.description: str = description
         self.parameters: list[Parameter] = parameters or []
         self.required_parameters: list[str] = required_parameters or []
+        self.strict: bool | None = strict
 
         self.validate()
 
@@ -110,6 +114,9 @@ class Function:
             },
         }
 
+        if self.strict is not None:
+            output_dict["strict"] = self.strict
+
         if self.required_parameters is None or len(self.required_parameters) == 0:
             return output_dict
 


Test patch:
diff --git a/tests/test_function.py b/tests/test_function.py
index 5d14ced..4314783 100644
--- a/tests/test_function.py
+++ b/tests/test_function.py
@@ -343,3 +343,35 @@ def test_merge_with_no_parameters_does_not_add_any() -> None:
     get_current_weather_function.merge(get_tomorrows_weather_function)
 
     assert len(get_current_weather_function.parameters) == 0
+
+
+def test_function_with_strict_true_includes_strict_in_output() -> None:
+    func = Function(
+        name="example_function",
+        description="An example function",
+        strict=True,
+    )
+    func_dict: FunctionDict = func.to_json_schema()
+
+    assert func_dict.get("strict") is True
+
+
+def test_function_with_strict_false_includes_strict_in_output() -> None:
+    func = Function(
+        name="example_function",
+        description="An example function",
+        strict=False,
+    )
+    func_dict: FunctionDict = func.to_json_schema()
+
+    assert func_dict.get("strict") is False
+
+
+def test_function_without_strict_excludes_strict_in_output() -> None:
+    func = Function(
+        name="example_function",
+        description="An example function",
+    )
+    func_dict: FunctionDict = func.to_json_schema()
+
+    assert "strict" not in func_dict