adk-web icon indicating copy to clipboard operation
adk-web copied to clipboard

Support Custom Runners with `adk web`

Open andrewburtnett opened this issue 6 months ago • 4 comments

adk web is great for developing and testing agents, but very quickly you need custom runners to manage things like artifacts and more advanced behavior. Since there is no way to use a custom Runner in adk web if you have tools that rely on things like custom ArtifactServices and SessionServices than you can no longer use adk web and have to build more complicated development environments.

andrewburtnett avatar Jun 19 '25 17:06 andrewburtnett

adk web is a great utility; however, it can quickly be unusable as they don't support custom runners. adk web could be very useful if it supported custom runners.

gauravfs-14 avatar Jun 24 '25 23:06 gauravfs-14

plus one to this one!

nicksav avatar Jul 01 '25 04:07 nicksav

Hi, you can switch fastapi to use your custom runner in adk-python, then start api-server and this web code separatly to get what you want. Custom runner support directly in adk web is not something we have planned yet.

wyf7107 avatar Jul 14 '25 20:07 wyf7107

Hi,

I tried to get the complete web interface but with my assets, session and memory services also. Here's how I made it.

import os
from pathlib import Path
from google.adk.artifacts.in_memory_artifact_service import InMemoryArtifactService
from google.adk.auth.credential_service.in_memory_credential_service import InMemoryCredentialService
from google.adk.cli.adk_web_server import AdkWebServer
from google.adk.cli.utils.agent_loader import AgentLoader
from google.adk.evaluation.local_eval_set_results_manager import LocalEvalSetResultsManager
from google.adk.evaluation.local_eval_sets_manager import LocalEvalSetsManager
from google.adk.memory.in_memory_memory_service import InMemoryMemoryService
from google.adk.sessions.database_session_service import DatabaseSessionService
from google.adk.sessions.in_memory_session_service import InMemorySessionService
import uvicorn
from google.adk.cli.fast_api import get_fast_api_app

from custom_memory import CustomMemoryService
from local_folder_artifact_service import LocalFolderArtifactService

AGENT_DIR = os.path.dirname(os.path.abspath(__file__))
SESSION_DB_URL = "sqlite:///session_db.db"
ALLOWED_ORIGINS = ["http://localhost", "http://localhost:8080", "*"]
SERVE_WEB_INTERFACE = True

# Build  the Credential service
credential_service = InMemoryCredentialService()

# initialize Agent Loader
agent_loader = AgentLoader(AGENT_DIR)

# session_service = InMemorySessionService()

session_service = DatabaseSessionService(
    db_url=SESSION_DB_URL,
)
# artifact_service = InMemoryArtifactService()
ARTIFACT_DIR = os.path.dirname(os.path.abspath(__file__)) + "/artifacts"
artifact_service = LocalFolderArtifactService(base_path=ARTIFACT_DIR)
memory_service = CustomMemoryService()
eval_sets_manager = LocalEvalSetsManager(agents_dir=AGENT_DIR)
eval_set_results_manager = LocalEvalSetResultsManager(agents_dir=AGENT_DIR)

adk_web_server = AdkWebServer(
      agent_loader=agent_loader,
      session_service=session_service,
      artifact_service=artifact_service,
      memory_service=memory_service,
      credential_service=credential_service,
      eval_sets_manager=eval_sets_manager,
      eval_set_results_manager=eval_set_results_manager,
      agents_dir=AGENT_DIR,
    #   extra_plugins=extra_plugins,
  )
  
extra_fast_api_args = {}
if SERVE_WEB_INTERFACE:
    import google.adk.cli
    ANGULAR_DIST_PATH = Path(google.adk.cli.__file__).parent / "browser"
    extra_fast_api_args.update(
        web_assets_dir=ANGULAR_DIST_PATH,
    )

app = adk_web_server.get_fast_api_app(
    #   lifespan=lifespan,
    allow_origins=ALLOWED_ORIGINS,
    # otel_to_cloud=None,
    **extra_fast_api_args,
  )

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))

I hope it can be of help for testing custom services.

antiv avatar Oct 10 '25 08:10 antiv