Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

process_schema() fails for recursive schemas #319

Closed
azaroth42 opened this issue Feb 12, 2025 · 1 comment
Closed

process_schema() fails for recursive schemas #319

azaroth42 opened this issue Feb 12, 2025 · 1 comment
Assignees
Labels
api: gemini-api priority: p2 Moderately-important priority. Fix may not be included in next release. type: feature request ‘Nice-to-have’ improvement, new feature or different behavior or design.

Comments

@azaroth42
Copy link

azaroth42 commented Feb 12, 2025

Per https://github.com/googleapis/python-genai/blob/main/google/genai/_transformers.py#L397 the process_schema() function tries to inline all of the $defs in the schema. This generates an infinite recursion for recursive schemas.

Proposal: Provide a maximum_depth configurable parameter that will break out of any infinite loops like this at a certain point.

Environment details

  • Programming language: Python
  • OS: MacOS
  • Language runtime version: 3.12.7
  • Package version: github master at 2025-02-27

Steps to reproduce

  1. Create a recursive schema in pydantic or json schema, as below
  2. Set it as the response_schema in the config
  3. Attempt to generate content and observe the infinite recursion error

Observed Behavior:

File "/Users/rs2668/Development/llm/python-genai/./test.py", line 58, in generate
    for chunk in client.models.generate_content_stream(
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/rs2668/Development/llm/python-genai/google/genai/models.py", line 4808, in generate_content_stream
    for chunk in response:
                 ^^^^^^^^
  File "/Users/rs2668/Development/llm/python-genai/google/genai/models.py", line 3864, in _generate_content_stream
    request_dict = _GenerateContentParameters_to_vertex(
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/rs2668/Development/llm/python-genai/google/genai/models.py", line 1190, in _GenerateContentParameters_to_vertex
    _GenerateContentConfig_to_vertex(
  File "/Users/rs2668/Development/llm/python-genai/google/genai/models.py", line 1037, in _GenerateContentConfig_to_vertex
    t.t_schema(api_client, getv(from_object, ['response_schema'])),
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/rs2668/Development/llm/python-genai/google/genai/_transformers.py", line 596, in t_schema
    process_schema(schema, client)
  File "/Users/rs2668/Development/llm/python-genai/google/genai/_transformers.py", line 471, in process_schema
    process_schema(sub_schema, client, defs)
  File "/Users/rs2668/Development/llm/python-genai/google/genai/_transformers.py", line 523, in process_schema
    process_schema(sub_schema, client, defs)
  File "/Users/rs2668/Development/llm/python-genai/google/genai/_transformers.py", line 547, in process_schema
    process_schema(ref, client, defs)
  File "/Users/rs2668/Development/llm/python-genai/google/genai/_transformers.py", line 523, in process_schema
    process_schema(sub_schema, client, defs)
  File "/Users/rs2668/Development/llm/python-genai/google/genai/_transformers.py", line 547, in process_schema
    process_schema(ref, client, defs)
...
RecursionError: maximum recursion depth exceeded

Expected Behavior:

That the schema would be processed

Test Case

Here is a minimal test case that produces the recursion error. I hope that it's clear.

from typing import List
from pydantic import BaseModel
from google import genai
from google.genai import types

class Node(BaseModel):
    name: str
    kids: List['Node']
Node.model_rebuild()

client = genai.Client(
      vertexai=True,
      project=" project name here ",
      location="us-central1",
)

textsi = """
You will be given a hierarchy in text. Please construct a tree of JSON objects.
Each JSON object has a "name" property for the name of the node in the hierarchy, and a "kids" property which is an array of JSON objects.
"""

generated_config = types.GenerateContentConfig(
    response_mime_type = "application/json",
    response_schema = Node,
    system_instruction=[types.Part.from_text(text=textsi)],
)

def generate(prompt):
  contents = [
    types.Content(
      role="user",
      parts=[types.Part.from_text(text=prompt)]
    )
  ]
  output = []
  for chunk in client.models.generate_content_stream(
    model = "gemini-2.0-flash-001",
    contents = contents,
    config = generated_config,
    ):
    output.append(chunk.text)
  return ''.join(output)


prompt = """
* Top
  * Materials
    * Metals
      * Gold
      * Silver
      * Bronze
    * Stone
      * Flint
      * Granite
      * Marble
"""

res = generate(prompt)

Thank you!

@azaroth42 azaroth42 added priority: p2 Moderately-important priority. Fix may not be included in next release. type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns. labels Feb 12, 2025
@sararob sararob self-assigned this Feb 12, 2025
@sararob sararob added type: feature request ‘Nice-to-have’ improvement, new feature or different behavior or design. api: gemini-api and removed type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns. labels Feb 18, 2025
@sararob
Copy link
Contributor

sararob commented Feb 18, 2025

The API doesn't currently support recursive schemas.

@sararob sararob closed this as completed Feb 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api: gemini-api priority: p2 Moderately-important priority. Fix may not be included in next release. type: feature request ‘Nice-to-have’ improvement, new feature or different behavior or design.
Projects
None yet
Development

No branches or pull requests

2 participants