Skip to content

gemini-2.5-flash is not found for API version v1alpha , using the latest google-adk version #2591

@Rvey

Description

@Rvey

Hello

Describe the bug
i can't use models/gemini-2.5-flash :
websockets.exceptions.ConnectionClosedError: received 1008 (policy violation) models/gemini-2.5-flash is not found for API version v1alpha, or is not supported for bidiGenerateContent. Call ListModels ; then sent 1008 (policy violation) models/gemini-2.5-flash is not found for API version v1alpha, or is not supported for bidiGenerateContent. Call ListModels

To Reproduce
Steps to reproduce the behavior:

  1. Install 'google-adk'
  2. Run 'uvicorn main:app --host 0.0.0.0 --port 8004'
  3. Open 'through a react app'
  4. See error :
    websockets.exceptions.ConnectionClosedError: received 1008 (policy violation) models/gemini-2.5-flash is not found for API version v1alpha, or is not supported for bidiGenerateContent. Call ListModels ; then sent 1008 (policy violation) models/gemini-2.5-flash is not found for API version v1alpha, or is not supported for bidiGenerateContent. Call ListModels

Expected behavior
Accept the model

Desktop (please complete the following information):

  • OS: [mac m1]
  • Python version(Python 3.12.4):
  • ADK version(pip show google-adk):
    Name: google-adk
    Version: 1.11.0
    Summary: Agent Development Kit
    Home-page:
    Author:
    Author-email: Google LLC googleapis-packages@google.com
    Requires: absolufy-imports, anyio, authlib, click, fastapi, google-api-python-client, google-cloud-aiplatform, google-cloud-secret-manager, google-cloud-spanner, google-cloud-speech, google-cloud-storage, google-genai, graphviz, mcp, opentelemetry-api, opentelemetry-exporter-gcp-trace, opentelemetry-sdk, pydantic, python-dateutil, python-dotenv, PyYAML, requests, sqlalchemy, starlette, tenacity, typing-extensions, tzlocal, uvicorn, watchdog, websockets

Model Information:
For example, which model is being used.

Additional context
code :

from google.adk.agents import Agent, LlmAgent
from google.adk.tools import google_search  # Import the tool


billing_agent = Agent(name="Billing", description="Handles billing inquiries.")
support_agent = Agent(name="Support", description="Handles technical support requests.")

root_agent = Agent(
    name="HelpDeskCoordinator",
    model="gemini-2.5-flash",
    instruction="Route user requests: Use Billing agent for payment issues, Support agent for technical problems.",
    description="Main help desk router.",
    # allow_transfer=True is often implicit with sub_agents in AutoFlow
    sub_agents=[billing_agent, support_agent]
)

main.py

import os
import json
import asyncio
import base64

from pathlib import Path
from dotenv import load_dotenv

from google.genai.types import (
    Part,
    Content,
    Blob,
)

from google.adk.runners import Runner , InMemoryRunner
from google.adk.agents import LiveRequestQueue
from google.adk.agents.run_config import RunConfig
from google.adk.sessions.in_memory_session_service import InMemorySessionService

from fastapi import FastAPI, WebSocket
from fastapi.staticfiles import StaticFiles
from fastapi.responses import FileResponse

from fastapi.middleware.cors import CORSMiddleware

load_dotenv()
APP_NAME = os.getenv("APP_NAME", "default_app_name")

async def start_agent_session(user_id, is_audio=False):
    """Starts an agent session"""

    # Create a Runner
    runner = InMemoryRunner(
        app_name=APP_NAME,
        agent=root_agent,
    )

    # Create a Session
    session = await runner.session_service.create_session(
        app_name=APP_NAME,
        user_id=user_id,  # Replace with actual user ID
    )

    # Set response modality
    modality = "AUDIO" if is_audio else "TEXT"
    run_config = RunConfig(response_modalities=[modality])

    # Create a LiveRequestQueue for this session
    live_request_queue = LiveRequestQueue()

    # Start agent session
    live_events = runner.run_live(
        session=session,
        live_request_queue=live_request_queue,
        run_config=run_config,
    )
    return live_events, live_request_queue

async def agent_to_client_messaging(websocket, live_events):
    """Agent to client communication"""
    print("[AGENT TO CLIENT]: Coroutine started")
    try:
        while True:
            async for event in live_events:
                # If the turn complete or interrupted, send it
                if event.turn_complete or event.interrupted:
                    message = {
                        "turn_complete": event.turn_complete,
                        "interrupted": event.interrupted,
                    }
                    await websocket.send_text(json.dumps(message))
                    print(f"[AGENT TO CLIENT]: {message}")
                    continue

                # Read the Content and its first Part
                part: Part = (
                    event.content and event.content.parts and event.content.parts[0]
                )
                if not part:
                    continue

                # If it's audio, send Base64 encoded audio data
                is_audio = part.inline_data and part.inline_data.mime_type.startswith("audio/pcm")
                if is_audio:
                    audio_data = part.inline_data and part.inline_data.data
                    if audio_data:
                        message = {
                            "mime_type": "audio/pcm",
                            "data": base64.b64encode(audio_data).decode("ascii")
                        }
                        await websocket.send_text(json.dumps(message))
                        print(f"[AGENT TO CLIENT]: audio/pcm: {len(audio_data)} bytes.")
                        continue

                # If it's text and a parial text, send it
                if part.text and event.partial:
                    message = {
                        "mime_type": "text/plain",
                        "data": part.text
                    }
                    await websocket.send_text(json.dumps(message))
                    print(f"[AGENT TO CLIENT]: text/plain: {message}")
    except Exception as e:
        import traceback
        print(f"[AGENT TO CLIENT]: Exception: {e}")
        traceback.print_exc()
    finally:
        print("[AGENT TO CLIENT]: Coroutine ended")

async def client_to_agent_messaging(websocket, live_request_queue):
    """Client to agent communication"""
    print("[CLIENT TO AGENT]: Coroutine started")
    from starlette.websockets import WebSocketDisconnect
    try:
        while True:
            # Decode JSON message
            message_json = await websocket.receive_text()
            message = json.loads(message_json)
            mime_type = message["mime_type"]
            data = message["data"]

            # Send the message to the agent
            if mime_type == "text/plain":
                # Send a text message
                content = Content(role="user", parts=[Part.from_text(text=data)])
                live_request_queue.send_content(content=content)
                print(f"[CLIENT TO AGENT]: {data}")
            elif mime_type == "audio/pcm":
                # Send an audio data
                decoded_data = base64.b64decode(data)
                live_request_queue.send_realtime(Blob(data=decoded_data, mime_type=mime_type))
            else:
                raise ValueError(f"Mime type not supported: {mime_type}")
    except WebSocketDisconnect:
        print("[CLIENT TO AGENT]: WebSocket disconnected by client.")
    except Exception as e:
        import traceback
        print(f"[CLIENT TO AGENT]: Exception: {e}")
        traceback.print_exc()
    finally:
        print("[CLIENT TO AGENT]: Coroutine ended")
        

app = FastAPI()
# logger = getLogger(__name__)

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


# STATIC_DIR = Path("static")
# app.mount("/static", StaticFiles(directory=STATIC_DIR), name="static")


@app.get("/")
async def root():
    """Serves the index.html"""
    return "Welcome to the Google Search Agent!"


@app.websocket("/ws/{user_id}")
async def websocket_endpoint(websocket: WebSocket, user_id: str, is_audio: str):
    """Client websocket endpoint"""
    try:
        # Wait for client connection
        await websocket.accept()
        print(f"Client #{user_id} connected, audio mode: {is_audio}")

        # Start agent session
        live_events, live_request_queue = await start_agent_session(user_id, is_audio == "false")

        # Start tasks
        agent_to_client_task = asyncio.create_task(
            agent_to_client_messaging(websocket, live_events)
        )
        client_to_agent_task = asyncio.create_task(
            client_to_agent_messaging(websocket, live_request_queue)
        )

        # Wait until the websocket is disconnected or an error occurs
        tasks = [agent_to_client_task, client_to_agent_task]
        await asyncio.wait(tasks, return_when=asyncio.FIRST_EXCEPTION)

        # Close LiveRequestQueue
        live_request_queue.close()

        # Disconnected
        print(f"Client #{user_id} disconnected")
    except Exception as e:
        import traceback
        print(f"Error in websocket connection for user {user_id}: {e}")
        traceback.print_exc()

Metadata

Metadata

Assignees

Labels

live[Component] This issue is related to live, voice and video chat

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions