Repository: langchain
Issue: LangChain incorrectly applies strict (OpenAIs Structured Output) in schema generation from Pydantic model with union, causing OpenAI validation errors
Labels: 🤖:bug,investigate

### Checked other resources

- [X] I added a very descriptive title to this issue.
- [X] I searched the LangChain documentation with the integrated search.
- [X] I used the GitHub search to find a similar question and didn't find it.
- [X] I am sure that this is a bug in LangChain rather than my code.
- [X] The bug is not resolved by updating to the latest stable version of LangChain (or the specific integration package).

### Example Code

```python
import getpass
import os
from typing import Union

from langchain_openai import ChatOpenAI
from openai import OpenAI
from pydantic import BaseModel, Field


class Cooked(BaseModel):
    cooked_recipe_name: str = Field(
        description='Recipe name.'
    )


class Baked(BaseModel):
    baked_recipe_name: str = Field(
        description='Recipe name.'
    )


class Recipes(BaseModel):
    recipes: list[Union[Cooked, Baked]] = Field(
        description='A list of recipes or tables representing the data sources.'
    )


if "OPENAI_API_KEY" not in os.environ:
    os.environ["OPENAI_API_KEY"] = getpass.getpass("Enter your OpenAI API key: ")


client = OpenAI()
model = "gpt-4o-2024-08-06"
recipe_names = "Garlic Butter Lobster Tail, Pumpkin Spice Muffins, Spicy Korean Beef Bulgogi, Raspberry Almond Scones"

completion = client.beta.chat.completions.parse(
    model=model,
    messages=[
        {"role": "user", "content": recipe_names},
    ],
    response_format=Recipes,
)
print("OpenAI:", completion.choices[0].message.parsed)

llm = ChatOpenAI(model=model)
llm = llm.with_structured_output(Recipes, strict=True)
response = llm.invoke(recipe_names)
print("Langchain:", response)
```
### Error Message and Stack Trace (if applicable)

openai.BadRequestError: Error code: 400 - {'error': {'message': "Invalid schema for function 'Recipes': In context=('properties', 'recipes', 'items', 'anyOf', '0'), 'additionalProperties' is required to be supplied and to be false.", 'type': 'invalid_request_error', 'param': 'tools[0].function.parameters', 'code': 'invalid_function_parameters'}}

### Description

The problem is that LangChain incorrectly applies the strict keyword to the schema generated from the Pydantic model for the specific case in the example code above. The culprit here is the union. The same Pydantic class works when I feed it directly to OpenAI. When I injected 'additionalProperties': False into the schema for the `Baked` and `Cooked` classes, the issue disappeared. 
I encountered the same problem when I had a Pydantic tool schema with a union similar to the one above.

OpenAI only threw error when `cooked_recipe_name` and `baked_recipe_name` were `recipe_name`, so I guess that is something to be careful about.

OpenAI schema before calling API:
```
{'$defs': {'Baked': {'properties': {'baked_recipe_name': {'description': 'Recipe name.', 'title': 'Baked Recipe Name', 'type': 'string'}}, 'required': ['baked_recipe_name'], 'title': 'Baked', 'type': 'object', 'additionalProperties': False}, 'Cooked': {'properties': {'cooked_recipe_name': {'description': 'Recipe name.', 'title': 'Cooked Recipe Name', 'type': 'string'}}, 'required': ['cooked_recipe_name'], 'title': 'Cooked', 'type': 'object', 'additionalProperties': False}}, 'properties': {'recipes': {'description': 'A list of recipes or tables representing the data sources.', 'items': {'anyOf': [{'$ref': '#/$defs/Cooked'}, {'$ref': '#/$defs/Baked'}]}, 'title': 'Recipes', 'type': 'array'}}, 'required': ['recipes'], 'title': 'Recipes', 'type': 'object', 'additionalProperties': False}
```

LangChain schema before calling API:
```
{'name': 'Recipes', 'description': '', 'parameters': {'properties': {'recipes': {'description': 'A list of recipes or tables representing the data sources.', 'items': {'anyOf': [{'properties': {'cooked_recipe_name': {'description': 'Recipe name.', 'title': 'Cooked Recipe Name', 'type': 'string'}}, 'required': ['cooked_recipe_name'], 'title': 'Cooked', 'type': 'object'}, {'properties': {'baked_recipe_name': {'description': 'Recipe name.', 'title': 'Baked Recipe Name', 'type': 'string'}}, 'required': ['baked_recipe_name'], 'title': 'Baked', 'type': 'object'}]}, 'type': 'array'}}, 'required': ['recipes'], 'type': 'object', 'additionalProperties': False}, 'strict': True}
```

### System Info

aiohappyeyeballs==2.4.3
aiohttp==3.11.0
aiosignal==1.3.1
annotated-types==0.7.0
anyio==4.6.2.post1
async-timeout==4.0.3
attrs==24.2.0
certifi==2024.8.30
charset-normalizer==3.4.0
distro==1.9.0
exceptiongroup==1.2.2
frozenlist==1.5.0
greenlet==3.1.1
h11==0.14.0
httpcore==1.0.6
httpx==0.27.2
idna==3.10
jiter==0.7.1
jsonpatch==1.33
jsonpointer==3.0.0
langchain==0.3.7
langchain-core==0.3.18
langchain-openai==0.2.8
langchain-text-splitters==0.3.2
langsmith==0.1.143
multidict==6.1.0
numpy==1.26.4
openai==1.54.4
orjson==3.10.11
packaging==24.2
propcache==0.2.0
pydantic==2.9.2
pydantic_core==2.23.4
PyYAML==6.0.2
regex==2024.11.6
requests==2.32.3
requests-toolbelt==1.0.0
sniffio==1.3.1
SQLAlchemy==2.0.36
tenacity==9.0.0
tiktoken==0.8.0
tqdm==4.67.0
typing_extensions==4.12.2
urllib3==2.2.3
yarl==1.17.1