5a558eb09e
TypeScript SDK Compatibility V1.x E2E Tests / Select Node version matrix (push) Has been cancelled
TypeScript SDK Compatibility V1.x E2E Tests / TypeScript SDK Compatibility V1.x E2E Tests Node ${{matrix.node_version}} (push) Has been cancelled
TypeScript SDK E2E Tests / TypeScript SDK E2E Tests Node ${{matrix.node_version}} (push) Has been cancelled
Opik Optimizer - E2E Tests / build-opik (push) Has been cancelled
TypeScript SDK Compatibility V1.x E2E Tests / build-opik (push) Has been cancelled
Python SDK E2E Tests / Select Python version matrix (push) Has been cancelled
Python SDK E2E Tests / Python SDK E2E Tests ${{matrix.python_version}} (push) Has been cancelled
Python SDK E2E Tests / build-opik (push) Has been cancelled
Python SDK Compatibility V1.x E2E Tests / Select Python version matrix (push) Has been cancelled
Python SDK Compatibility V1.x E2E Tests / Python SDK Compatibility V1.x E2E Tests ${{matrix.python_version}} (push) Has been cancelled
Python SDK Compatibility V1.x E2E Tests / build-opik (push) Has been cancelled
TypeScript SDK E2E Tests / Select Node version matrix (push) Has been cancelled
TypeScript SDK E2E Tests / build-opik (push) Has been cancelled
Opik Optimizer - E2E Tests / Opik Optimizer E2E Tests Python ${{matrix.python_version}} (push) Has been cancelled
Opik Optimizer - E2E Tests / Opik Optimizer Integration Smoke Tests (push) Has been cancelled
🐙 Code Quality / detect (push) Has been cancelled
🐙 Code Quality / lint (${{ matrix.leg.name }}) (push) Has been cancelled
🐙 Code Quality / summary (push) Has been cancelled
TypeScript SDK Library Integration Tests / Check Secrets (push) Has been cancelled
TypeScript SDK Library Integration Tests / opik-vercel (Vercel AI SDK / eve) (push) Has been cancelled
SDK Library Integration Tests Runner / Check Secrets (push) Has been cancelled
SDK Library Integration Tests Runner / Missed OpenAI API Key Warning (push) Has been cancelled
SDK Library Integration Tests Runner / Build (push) Has been cancelled
SDK Library Integration Tests Runner / openai_tests (push) Has been cancelled
SDK Library Integration Tests Runner / langchain_tests (push) Has been cancelled
SDK Library Integration Tests Runner / langchain_legacy_tests (push) Has been cancelled
SDK Library Integration Tests Runner / llama_index_tests (push) Has been cancelled
SDK Library Integration Tests Runner / anthropic_tests (push) Has been cancelled
SDK Library Integration Tests Runner / mistral_tests (push) Has been cancelled
SDK Library Integration Tests Runner / groq_tests (push) Has been cancelled
SDK Library Integration Tests Runner / aisuite_tests (push) Has been cancelled
SDK Library Integration Tests Runner / haystack_tests (push) Has been cancelled
SDK Library Integration Tests Runner / dspy_tests (push) Has been cancelled
SDK Library Integration Tests Runner / crewai_v0_tests (push) Has been cancelled
SDK Library Integration Tests Runner / crewai_v1_tests (push) Has been cancelled
SDK Library Integration Tests Runner / genai_tests (push) Has been cancelled
SDK Library Integration Tests Runner / adk_tests (push) Has been cancelled
SDK Library Integration Tests Runner / adk_legacy_1_3_0_tests (push) Has been cancelled
SDK Library Integration Tests Runner / evaluation_metrics_tests (push) Has been cancelled
SDK Library Integration Tests Runner / bedrock_tests (push) Has been cancelled
SDK Library Integration Tests Runner / litellm_tests (push) Has been cancelled
SDK Library Integration Tests Runner / harbor_tests (push) Has been cancelled
SDK Library Integration Tests Runner / Slack Notification (push) Has been cancelled
Lint Opik Helm Chart / render-equality (push) Has been cancelled
Opik Optimizer - Unit Tests / Opik Optimizer Unit Tests Python ${{matrix.python_version}} (push) Has been cancelled
Python BE E2E Tests / Python BE E2E (push) Has been cancelled
Python Backend Tests / run-python-backend-tests (push) Has been cancelled
Python SDK Unit Tests / Python SDK Unit Tests ${{matrix.python_version}} (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
SDK E2E Libraries Integration Tests / Check Secrets (push) Has been cancelled
SDK E2E Libraries Integration Tests / Missed OpenAI API Key Warning (push) Has been cancelled
SDK E2E Libraries Integration Tests / build-opik (push) Has been cancelled
SDK E2E Libraries Integration Tests / E2E Lib Integration Python ${{matrix.python_version}} (push) Has been cancelled
TypeScript SDK Integration Build & Publish / build-and-publish (opik-gemini) (push) Has been cancelled
TypeScript SDK Integration Build & Publish / build-and-publish (opik-langchain) (push) Has been cancelled
TypeScript SDK Integration Build & Publish / build-and-publish (opik-openai) (push) Has been cancelled
TypeScript SDK Integration Build & Publish / build-and-publish (opik-otel) (push) Has been cancelled
TypeScript SDK Integration Build & Publish / build-and-publish (opik-vercel) (push) Has been cancelled
TypeScript SDK Build & Publish / build-and-publish (push) Has been cancelled
TypeScript SDK Unit Tests / Test on Node ${{ matrix.node-version }} (push) Has been cancelled
Backend Tests / discover-tests (push) Has been cancelled
Backend Tests / ${{ matrix.name }} (push) Has been cancelled
Build and Publish SDK / build-and-publish (push) Has been cancelled
Build Opik Docker Images / set-version (push) Has been cancelled
Build Opik Docker Images / build-backend (push) Has been cancelled
Build Opik Docker Images / build-sandbox-executor-python (push) Has been cancelled
Build Opik Docker Images / build-python-backend (push) Has been cancelled
Build Opik Docker Images / build-frontend (push) Has been cancelled
Build Opik Docker Images / create-git-tag (push) Has been cancelled
ClickHouse Migration Cluster Check / validate-clickhouse-migrations (push) Has been cancelled
Docs - Publish / run (push) Has been cancelled
E2E Tests - Post Merge (v2) / 🧪 E2E v2 Tests (${{ github.event.inputs.tier || 't1' }}) (push) Has been cancelled
E2E Tests - Post Merge (v2) / 📢 Slack Notification (push) Has been cancelled
Frontend Unit Tests / Test on Node 20 (push) Has been cancelled
Guardrails E2E Tests / Select Python version matrix (push) Has been cancelled
Guardrails E2E Tests / Guardrails E2E Tests ${{matrix.python_version}} (push) Has been cancelled
Guardrails E2E Tests / 📢 Slack Notification (push) Has been cancelled
Guardrails Backend Unit Tests / Guardrails Backend Unit Tests (push) Has been cancelled
Guardrails Backend Unit Tests / 📢 Slack Notification (push) Has been cancelled
Lint Opik Helm Chart / lint-helm-chart (Helm v3.21.0) (push) Has been cancelled
Lint Opik Helm Chart / lint-helm-chart (Helm v4.2.0) (push) Has been cancelled
Lint Opik Helm Chart / unittest-helm-chart (push) Has been cancelled
145 lines
5.2 KiB
Python
145 lines
5.2 KiB
Python
from typing import AsyncIterator, Iterator, List, Optional, Union
|
|
|
|
import google
|
|
import pytest
|
|
from google.adk import (
|
|
agents as adk_agents,
|
|
runners as adk_runners,
|
|
sessions as adk_sessions,
|
|
events as adk_events,
|
|
)
|
|
|
|
from opik import semantic_version
|
|
from opik.integrations.adk import OpikTracer
|
|
from .constants import APP_NAME, USER_ID, SESSION_ID, MODEL_NAME
|
|
|
|
|
|
pytest_skip_for_adk_older_than_1_3_0 = pytest.mark.skipif(
|
|
semantic_version.SemanticVersion.parse(google.adk.__version__) < "1.3.0",
|
|
reason="Test only applies to ADK versions >= 1.3.0",
|
|
)
|
|
|
|
|
|
def build_sync_runner(root_agent: adk_agents.Agent) -> adk_runners.Runner:
|
|
session_service = adk_sessions.InMemorySessionService()
|
|
_ = session_service.create_session_sync(
|
|
app_name=APP_NAME, user_id=USER_ID, session_id=SESSION_ID
|
|
)
|
|
runner = adk_runners.Runner(
|
|
agent=root_agent, app_name=APP_NAME, session_service=session_service
|
|
)
|
|
return runner
|
|
|
|
|
|
def extract_final_response_text(
|
|
events_generator: Iterator[adk_events.Event],
|
|
) -> Optional[str]:
|
|
"""
|
|
Exhausts the iterator of ADK events and returns the response text
|
|
from the last event that actually carries content.
|
|
|
|
ADK (1.31+) sometimes emits a trailing terminator event with content=None
|
|
after the real final response, so we walk the list in reverse to find
|
|
the last event whose content.parts is populated.
|
|
"""
|
|
events = list(events_generator)
|
|
if len(events) == 0:
|
|
# As the error might occur in the background, we raise an exception here
|
|
raise Exception("Agent failed to execute.")
|
|
|
|
final_event = _pick_final_response_event(events)
|
|
return final_event.content.parts[0].text
|
|
|
|
|
|
async def async_build_runner(
|
|
root_agent: Union[adk_agents.Agent, adk_agents.SequentialAgent],
|
|
) -> adk_runners.Runner:
|
|
session_service = adk_sessions.InMemorySessionService()
|
|
_ = await session_service.create_session(
|
|
app_name=APP_NAME, user_id=USER_ID, session_id=SESSION_ID
|
|
)
|
|
runner = adk_runners.Runner(
|
|
agent=root_agent, app_name=APP_NAME, session_service=session_service
|
|
)
|
|
return runner
|
|
|
|
|
|
async def async_extract_final_response_text(
|
|
events_generator: AsyncIterator[adk_events.Event],
|
|
) -> Optional[str]:
|
|
"""
|
|
Exhausts the async iterator of ADK events and returns the response text
|
|
from the last event that actually carries content. See the sync variant
|
|
for the rationale on scanning in reverse.
|
|
"""
|
|
collected_events = []
|
|
async for event in events_generator:
|
|
collected_events.append(event)
|
|
|
|
if len(collected_events) == 0:
|
|
# As the error might occur in the background, we raise an exception here
|
|
raise Exception("Agent failed to execute.")
|
|
|
|
final_event = _pick_final_response_event(collected_events)
|
|
return final_event.content.parts[0].text
|
|
|
|
|
|
def _pick_final_response_event(
|
|
events: List[adk_events.Event],
|
|
) -> adk_events.Event:
|
|
"""Return the last event that is a final agent response with text
|
|
content. Skips trailing terminator events (content=None) that ADK
|
|
1.31+ sometimes emits, and skips intermediate events such as
|
|
pre-tool model messages or function_call/function_response parts —
|
|
otherwise tool-failure tests (which never reach a final text
|
|
response) would silently pick up a pre-tool chatter event and stop
|
|
raising. Raises if no qualifying event is found."""
|
|
for event in reversed(events):
|
|
if not event.is_final_response():
|
|
continue
|
|
content = event.content
|
|
if content is None or not content.parts:
|
|
continue
|
|
if content.parts[0].text is None:
|
|
continue
|
|
return event
|
|
raise AssertionError(
|
|
f"No final-response event with text content found among {len(events)} events. "
|
|
f"Last event: {events[-1]!r}"
|
|
)
|
|
|
|
|
|
def root_agent_sequential_with_translator_and_summarizer(
|
|
opik_tracer: OpikTracer,
|
|
) -> adk_agents.SequentialAgent:
|
|
translator_to_english = adk_agents.Agent(
|
|
name="Translator",
|
|
model=MODEL_NAME,
|
|
description="Translates text to English.",
|
|
instruction="Translate to English.",
|
|
before_agent_callback=opik_tracer.before_agent_callback,
|
|
after_agent_callback=opik_tracer.after_agent_callback,
|
|
before_model_callback=opik_tracer.before_model_callback,
|
|
after_model_callback=opik_tracer.after_model_callback,
|
|
)
|
|
|
|
summarizer = adk_agents.Agent(
|
|
name="Summarizer",
|
|
model=MODEL_NAME,
|
|
description="Summarizes text to 1 sentence.",
|
|
instruction="Summarize to one sentence.",
|
|
before_agent_callback=opik_tracer.before_agent_callback,
|
|
after_agent_callback=opik_tracer.after_agent_callback,
|
|
before_model_callback=opik_tracer.before_model_callback,
|
|
after_model_callback=opik_tracer.after_model_callback,
|
|
)
|
|
|
|
root_agent = adk_agents.SequentialAgent(
|
|
name="TextProcessingAssistant",
|
|
sub_agents=[translator_to_english, summarizer],
|
|
description="Runs translator to english then summarizer, in order.",
|
|
before_agent_callback=opik_tracer.before_agent_callback,
|
|
after_agent_callback=opik_tracer.after_agent_callback,
|
|
)
|
|
return root_agent
|