Skip to content

Commit 6b831d5

Browse files
GWealecopybara-github
authored andcommitted
feat: add OpenAI Responses API support in labs
Add OpenAIResponsesLlm and AzureOpenAIResponsesLlm under labs.openai, a BaseLlm targeting the OpenAI Responses API: request/response/streaming conversion, reasoning summaries, structured output, tool mapping, and usage metadata. Merge #6188 Closes #3209 Co-authored-by: Luca Frigato <37444661+FrigaZzz@users.noreply.github.com> Co-authored-by: George Weale <gweale@google.com> PiperOrigin-RevId: 938272066
1 parent 7e8191a commit 6b831d5

8 files changed

Lines changed: 2742 additions & 25 deletions

File tree

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ optional-dependencies.extensions = [
154154
"llama-index-embeddings-google-genai>=0.3",
155155
"llama-index-readers-file>=0.4",
156156
"lxml>=5.3",
157+
"openai>=2.20,<3",
157158
"pypika>=0.50",
158159
"toolbox-adk>=1,<2",
159160
]
@@ -224,7 +225,7 @@ optional-dependencies.test = [
224225
"llama-index-readers-file>=0.4",
225226
"lxml>=5.3",
226227
"mcp>=1.24,<2",
227-
"openai>=1.100.2",
228+
"openai>=2.20,<3",
228229
"opentelemetry-exporter-gcp-logging>=1.9.0a0,<=1.12.0a0",
229230
"opentelemetry-exporter-gcp-monitoring>=1.9.0a0,<2",
230231
"opentelemetry-exporter-gcp-trace>=1.9,<2",

src/google/adk/flows/llm_flows/contents.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,12 @@ async def run_async(
6969
id_pairing_model_types.append(LiteLlm)
7070
except (ImportError, OSError):
7171
pass
72+
try:
73+
from ...labs.openai import OpenAIResponsesLlm
74+
75+
id_pairing_model_types.append(OpenAIResponsesLlm)
76+
except (ImportError, OSError):
77+
pass
7278
if isinstance(canonical_model, tuple(id_pairing_model_types)):
7379
preserve_function_call_ids = True
7480

src/google/adk/labs/openai/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@
1313
# limitations under the License.
1414

1515
from ._openai_llm import OpenAILlm
16+
from ._openai_responses_llm import AzureOpenAIResponsesLlm
17+
from ._openai_responses_llm import OpenAIResponsesLlm
1618

1719
__all__ = [
20+
'AzureOpenAIResponsesLlm',
1821
'OpenAILlm',
22+
'OpenAIResponsesLlm',
1923
]

src/google/adk/labs/openai/_openai_llm.py

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
from ...models.base_llm import BaseLlm
4747
from ...models.llm_request import LlmRequest
4848
from ...models.llm_response import LlmResponse
49+
from ._openai_schema import enforce_strict_openai_schema
4950

5051
logger = logging.getLogger("google_adk." + __name__)
5152

@@ -180,29 +181,6 @@ def _content_to_openai_messages(
180181
return messages
181182

182183

183-
def _enforce_strict_openai_schema(schema: dict[str, Any]) -> None:
184-
"""Recursively transforms a JSON schema for OpenAI strict structured outputs."""
185-
if not isinstance(schema, dict):
186-
return
187-
if "$ref" in schema:
188-
for key in list(schema.keys()):
189-
if key != "$ref":
190-
del schema[key]
191-
return
192-
if schema.get("type") == "object" and "properties" in schema:
193-
schema["additionalProperties"] = False
194-
schema["required"] = sorted(schema["properties"].keys())
195-
for defn in schema.get("$defs", {}).values():
196-
_enforce_strict_openai_schema(defn)
197-
for prop in schema.get("properties", {}).values():
198-
_enforce_strict_openai_schema(prop)
199-
for key in ("anyOf", "oneOf", "allOf"):
200-
for item in schema.get(key, []):
201-
_enforce_strict_openai_schema(item)
202-
if "items" in schema and isinstance(schema["items"], dict):
203-
_enforce_strict_openai_schema(schema["items"])
204-
205-
206184
def _update_type_string(value: Any):
207185
"""Lowercases nested JSON schema type strings for OpenAI compatibility."""
208186
if isinstance(value, list):
@@ -406,7 +384,7 @@ async def generate_content_async(
406384
schema_name = str(schema_dict["title"])
407385

408386
if schema_dict:
409-
_enforce_strict_openai_schema(schema_dict)
387+
enforce_strict_openai_schema(schema_dict)
410388
response_format = {
411389
"type": "json_schema",
412390
"json_schema": {

0 commit comments

Comments
 (0)