Skip to content

Commit 2a0a6f1

Browse files
Amnah199sjrl
andauthored
feat: Add Chat Generator supporting OpenAI Responses API (#9808)
* Add working ChatGenerator * rename * Improve and add live tests * Updates * Update the tests * Fix errors * Add release notes * Add support for openai tools * Remove openai tools test that times out * fix tool calls * Update release notes * PR comments * remove edits to chat message * Add a test * PR comments * Send back reasoning to model * Fix reasoning support * Add reasoning support * Fix tests * Refactor * Simplify methods * Fix mypy * Stream responses, tool calls etc * Update docstrings * Fix errors while using in Agent * Fix call_id and fc_id * Update tests * Updates * Add extra in ToolCall and ToolCallDelta * Update streaming chunk * Fix tests and linting * Update api key resolve * PR comments * PR comments * Updates * some type fixes and also make sure to use flatten_tools_or_toolsets * fix docs * Fix streaming chunks so assistant header is properly captured * Add finish_reason and update test * Skip streaming + pydantic model test b/c of known issue in openai python sdk openai/openai-python#2305 * Fix pylint --------- Co-authored-by: Sebastian Husch Lee <[email protected]>
1 parent 21502f4 commit 2a0a6f1

File tree

7 files changed

+2741
-1
lines changed

7 files changed

+2741
-1
lines changed

docs/pydoc/config/generators_api.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ loaders:
1212
"chat/hugging_face_local",
1313
"chat/hugging_face_api",
1414
"chat/openai",
15+
"chat/openai_responses",
1516
"chat/fallback",
1617
]
1718
ignore_when_discovered: ["__init__"]

docs/pydoc/config_docusaurus/generators_api.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ loaders:
1212
"chat/hugging_face_local",
1313
"chat/hugging_face_api",
1414
"chat/openai",
15+
"chat/openai_responses",
1516
"chat/fallback",
1617
]
1718
ignore_when_discovered: ["__init__"]

haystack/components/generators/chat/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
_import_structure = {
1111
"openai": ["OpenAIChatGenerator"],
12+
"openai_responses": ["OpenAIResponsesChatGenerator"],
1213
"azure": ["AzureOpenAIChatGenerator"],
1314
"hugging_face_local": ["HuggingFaceLocalChatGenerator"],
1415
"hugging_face_api": ["HuggingFaceAPIChatGenerator"],
@@ -21,6 +22,7 @@
2122
from .hugging_face_api import HuggingFaceAPIChatGenerator as HuggingFaceAPIChatGenerator
2223
from .hugging_face_local import HuggingFaceLocalChatGenerator as HuggingFaceLocalChatGenerator
2324
from .openai import OpenAIChatGenerator as OpenAIChatGenerator
25+
from .openai_responses import OpenAIResponsesChatGenerator as OpenAIResponsesChatGenerator
2426

2527
else:
2628
sys.modules[__name__] = LazyImporter(name=__name__, module_file=__file__, import_structure=_import_structure)

haystack/components/generators/chat/openai_responses.py

Lines changed: 824 additions & 0 deletions
Large diffs are not rendered by default.

haystack/dataclasses/streaming_chunk.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class ToolCallDelta:
3030
index: int
3131
tool_name: Optional[str] = field(default=None)
3232
arguments: Optional[str] = field(default=None)
33-
id: Optional[str] = field(default=None) # noqa: A003
33+
id: Optional[str] = field(default=None)
3434
extra: Optional[dict[str, Any]] = field(default=None)
3535

3636
def to_dict(self) -> dict[str, Any]:
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
---
2+
features:
3+
- |
4+
Added the OpenAIResponsesChatGenerator, a new component that integrates OpenAI's Responses API into Haystack.
5+
This unlocks several advanced capabilities from the Responses API:
6+
- Allowing retrieval of concise summaries of the model's reasoning process.
7+
- Allowing the use of native OpenAI or MCP tool formats, along with Haystack Tool objects and Toolset instances.
8+
9+
Example with reasoning and web search tool:
10+
```python
11+
from haystack.components.generators.chat import OpenAIResponsesChatGenerator
12+
from haystack.dataclasses import ChatMessage
13+
14+
chat_generator = OpenAIResponsesChatGenerator(
15+
model="o3-mini",
16+
generation_kwargs={
17+
{"summary": "auto", "effort": "low"}
18+
},
19+
tools=[{"type": "web_search"}]
20+
)
21+
22+
response = chat_generator.run(
23+
messages=[
24+
ChatMessage.from_user("What's a positive news story from today?")
25+
]
26+
)
27+
print(response["replies"][0].text)
28+
```
29+
30+
Example with structured output:
31+
```python
32+
from pydantic import BaseModel
33+
from haystack.components.generators.chat import OpenAIResponsesChatGenerator
34+
from haystack.dataclasses import ChatMessage
35+
36+
class WeatherInfo(BaseModel):
37+
location: str
38+
temperature: float
39+
conditions: str
40+
41+
chat_generator = OpenAIResponsesChatGenerator(
42+
model="gpt-5-mini",
43+
generation_kwargs={"text_format": WeatherInfo}
44+
)
45+
46+
response = chat_generator.run(
47+
messages=[ChatMessage.from_user("What's the weather in Paris?")]
48+
)
49+
```

0 commit comments

Comments
 (0)