Skip to content

Name collision in google.genai.interactions: triggers.Interaction shadows response model Interaction in static type checkers #3013

Description

@IvanLH

Summary

In google-genai (v2.25.0+), google.genai.interactions exposes types for the Interactions API using wildcard star-imports:

# google/genai/interactions.py (lines 23-32)
# Import triggers before interactions so that interactions.Interaction (the
# resource class) overrides triggers.Interaction (the TypeAliasType representing
# nested interactions inside triggers) in the exported namespace, resolving
# the name collision.
from ._gaos.types.triggers import *  # noqa: F401,F403
from ._gaos.types.triggers import __all__ as _triggers_all
from ._gaos.types.environments import *  # noqa: F401,F403
from ._gaos.types.environments import __all__ as _environments_all
from ._gaos.types.interactions import *  # noqa: F401,F403
from ._gaos.types.interactions import __all__ as _interactions_all

As the comment in google/genai/interactions.py notes, there is a name collision between:

  1. google.genai._gaos.types.triggers.Interaction (TypeAliasType = Union[CreateAgentInteraction, CreateModelInteraction])
  2. google.genai._gaos.types.interactions.interaction.Interaction (Pydantic BaseModel representing the interaction response object with .steps, .output_text, .output_image, .output_audio, etc.)

While Python's runtime assigns interactions.Interaction to the later-imported response class, static type checkers (such as mypy with follow_imports = normal) resolve interactions.Interaction to triggers.Interaction (CreateAgentInteraction | CreateModelInteraction).

Steps to Reproduce

Consider the following type-annotated code:

from google.genai import interactions

def inspect_response(interaction: interactions.Interaction) -> None:
    if interaction.output_image is not None:
        print(interaction.output_image.data)
    if interaction.output_audio is not None:
        print(interaction.output_audio.data)
    if interaction.steps:
        print(len(interaction.steps))

Run mypy with follow-imports=normal:

mypy --follow-imports=normal repro.py

Actual Behavior

mypy fails with union-attr errors because it resolves interactions.Interaction to CreateAgentInteraction | CreateModelInteraction:

repro.py:4: error: Item "CreateAgentInteraction" of "CreateAgentInteraction | CreateModelInteraction" has no attribute "output_image"  [union-attr]
repro.py:4: error: Item "CreateModelInteraction" of "CreateAgentInteraction | CreateModelInteraction" has no attribute "output_image"  [union-attr]
repro.py:6: error: Item "CreateAgentInteraction" of "CreateAgentInteraction | CreateModelInteraction" has no attribute "output_audio"  [union-attr]
repro.py:6: error: Item "CreateModelInteraction" of "CreateAgentInteraction | CreateModelInteraction" has no attribute "output_audio"  [union-attr]
repro.py:8: error: Item "CreateAgentInteraction" of "CreateAgentInteraction | CreateModelInteraction" has no attribute "steps"  [union-attr]
repro.py:8: error: Item "CreateModelInteraction" of "CreateAgentInteraction | CreateModelInteraction" has no attribute "steps"  [union-attr]

Expected Behavior

interactions.Interaction should unambiguously resolve to the response model class google.genai._gaos.types.interactions.interaction.Interaction both at runtime and during static type checking.

Workaround

Currently, consumer projects must use a conditional type-checking import workaround:

from typing import TYPE_CHECKING
from google.genai import interactions

if TYPE_CHECKING:
    from google.genai._gaos.types.interactions.interaction import Interaction
else:
    Interaction = interactions.Interaction

Suggested Solution

In google/genai/interactions.py:

  1. Avoid wildcard star imports or explicitly re-export the response model after the star imports:
    from ._gaos.types.interactions.interaction import Interaction as Interaction
  2. Or rename triggers.Interaction in _gaos/types/triggers to TriggerInteraction / InteractionTriggerParam so the names do not collide.

Environment Details

  • OS: Linux
  • Python: 3.12 / 3.13 / 3.14
  • google-genai version: 2.25.0
  • mypy version: 1.14+

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

priority: p2Moderately-important priority. Fix may not be included in next release.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions