diff --git a/src/google/adk/agents/llm_agent.py b/src/google/adk/agents/llm_agent.py index bb1af0a1..64c453af 100644 --- a/src/google/adk/agents/llm_agent.py +++ b/src/google/adk/agents/llm_agent.py @@ -1008,7 +1008,7 @@ class LlmAgent(BaseAgent, abc.ABC): __maybe_save_output_to_state skips them and the text on those events is dropped from output_key. Accumulate every non-partial text-bearing event from this agent across the model turn so the segments survive - in session state. See issue #5590. + in session state. No-op when accumulation doesn't apply (different author, no output_key, output_schema set, partial event, no content, no text). diff --git a/src/google/adk/cli/built_in_agents/tools/write_config_files.py b/src/google/adk/cli/built_in_agents/tools/write_config_files.py index cecefff7..9948efe0 100644 --- a/src/google/adk/cli/built_in_agents/tools/write_config_files.py +++ b/src/google/adk/cli/built_in_agents/tools/write_config_files.py @@ -426,7 +426,7 @@ def _validate_single_config( } # Step 3: Additional structural validation - # TODO: b/455645705 - Remove once the frontend performs these validations before calling + # TODO: Remove once the frontend performs these validations before calling # this tool. name_warning = _normalize_agent_name_field(config_dict, path) structural_validation = _validate_structure(config_dict, path) diff --git a/src/google/adk/models/gemini_llm_connection.py b/src/google/adk/models/gemini_llm_connection.py index d6c70d71..1a146223 100644 --- a/src/google/adk/models/gemini_llm_connection.py +++ b/src/google/adk/models/gemini_llm_connection.py @@ -308,8 +308,9 @@ class GeminiLlmConnection(BaseLlmConnection): last_grounding_metadata = None tool_call_metadata = None async with Aclosing(self._gemini_session.receive()) as agen: - # TODO(b/440101573): Reuse StreamingResponseAggregator to accumulate - # partial content and emit responses as needed. + # Pending cleanup: reuse StreamingResponseAggregator to accumulate + # partial content and emit responses as needed, once that aggregator + # handles the live-connection message shapes. async for message in agen: logger.debug('Got LLM Live message: %s', message) live_session_id = self._gemini_session.session_id diff --git a/src/google/adk/plugins/bigquery_agent_analytics_plugin.py b/src/google/adk/plugins/bigquery_agent_analytics_plugin.py index 7c67e0fa..30bd6779 100644 --- a/src/google/adk/plugins/bigquery_agent_analytics_plugin.py +++ b/src/google/adk/plugins/bigquery_agent_analytics_plugin.py @@ -1870,7 +1870,7 @@ class _SpanRecord: with ``GOOGLE_CLOUD_AGENT_ENGINE_ENABLE_TELEMETRY=true``), those plugin-owned spans were exported to Cloud Trace alongside the framework's real spans — producing a duplicate-span view for - every BQAA-instrumented operation. See haiyuan-eng-google/BQAA-SDK#94. + every BQAA-instrumented operation. The plugin already tracked all parent / child relationships on this internal stack, so the OTel span object was incidental to @@ -5616,7 +5616,7 @@ class BigQueryAgentAnalyticsPlugin(BasePlugin): ``InvocationContext.agent.name`` with no None guard, but ``agent`` is legitimately ``None`` for workflow-driven invocations with deterministic nodes. Reading it at row-build time then raised ``AttributeError``, which - ``@_safe_callback`` swallowed, silently dropping the row (issue #6063). + ``@_safe_callback`` swallowed, silently dropping the row. Resolution order: @@ -6563,7 +6563,7 @@ class BigQueryAgentAnalyticsPlugin(BasePlugin): try: # Capture trace_id BEFORE popping the invocation-root span so # that INVOCATION_COMPLETED shares the same trace_id as all - # earlier events in this invocation (fixes #4645). + # earlier events in this invocation. callback_ctx = CallbackContext(invocation_context) trace_id = TraceManager.get_trace_id(callback_ctx) diff --git a/src/google/adk/plugins/multimodal_tool_results_plugin.py b/src/google/adk/plugins/multimodal_tool_results_plugin.py index 43af5cdc..a103b52a 100644 --- a/src/google/adk/plugins/multimodal_tool_results_plugin.py +++ b/src/google/adk/plugins/multimodal_tool_results_plugin.py @@ -34,7 +34,6 @@ class MultimodalToolResultsPlugin(BasePlugin): Should be removed in favor of directly supporting FunctionResponsePart when these are supported outside of computer use tool. - For context see: https://github.com/google/adk-python/issues/3064#issuecomment-3463067459 """ def __init__(self, name: str = "multimodal_tool_results_plugin"): diff --git a/src/google/adk/sessions/schemas/v0.py b/src/google/adk/sessions/schemas/v0.py index 6bd88aff..c53e6e1b 100644 --- a/src/google/adk/sessions/schemas/v0.py +++ b/src/google/adk/sessions/schemas/v0.py @@ -20,8 +20,7 @@ v0 schema, see https://github.com/google/adk-python/blob/main/docs/upgrading_from_1_22_0.md. The latest schema is defined in `v1.py`. That module uses JSON serialization -for the EventActions data as well as other fields in the `events` table. See -https://github.com/google/adk-python/discussions/3605 for more details. +for the EventActions data as well as other fields in the `events` table. """ from __future__ import annotations diff --git a/src/google/adk/sessions/schemas/v1.py b/src/google/adk/sessions/schemas/v1.py index 9b5862d5..9cce9ac7 100644 --- a/src/google/adk/sessions/schemas/v1.py +++ b/src/google/adk/sessions/schemas/v1.py @@ -17,8 +17,6 @@ This module defines SQLAlchemy models for storing session and event data in a relational database with the "events" table using JSON serialization for Event data. - -See https://github.com/google/adk-python/discussions/3605 for more details. """ from __future__ import annotations diff --git a/src/google/adk/telemetry/tracing.py b/src/google/adk/telemetry/tracing.py index 4d5c1445..389565e9 100644 --- a/src/google/adk/telemetry/tracing.py +++ b/src/google/adk/telemetry/tracing.py @@ -142,9 +142,8 @@ def trace_agent_invocation( agent: Agent from which attributes are gathered. ctx: InvocationContext from which attributes are gathered. - Inference related fields are not set, due to their planned removal from - invoke_agent span: - https://github.com/open-telemetry/semantic-conventions/issues/2632 + Inference related fields are not set, because the OpenTelemetry semantic + conventions plan to remove them from the invoke_agent span. `gen_ai.agent.id` is not set because currently it's unclear what attributes this field should have, specifically: @@ -296,7 +295,8 @@ def trace_merged_tool_calls( span.set_attribute(GEN_AI_TOOL_DESCRIPTION, "(merged tools)") span.set_attribute(GEN_AI_TOOL_CALL_ID, response_event_id) - # TODO(b/441461932): See if these are still necessary + # Pending cleanup: drop these placeholder attributes once no downstream + # consumer reads them. span.set_attribute("gcp.vertex.agent.tool_call_args", "N/A") span.set_attribute("gcp.vertex.agent.event_id", response_event_id) try: diff --git a/src/google/adk/tools/_automatic_function_calling_util.py b/src/google/adk/tools/_automatic_function_calling_util.py index 720335d4..5e8df09f 100644 --- a/src/google/adk/tools/_automatic_function_calling_util.py +++ b/src/google/adk/tools/_automatic_function_calling_util.py @@ -222,7 +222,8 @@ def build_function_declaration( ) ) # Add response schema only for VERTEX_AI - # TODO(b/421991354): Remove this check once the bug is fixed. + # Pending cleanup: remove this check once the Gemini API accepts + # response_json_schema. if variant != GoogleLLMVariant.VERTEX_AI: declaration.response_json_schema = None return declaration diff --git a/tests/unittests/a2a/converters/test_event_converter.py b/tests/unittests/a2a/converters/test_event_converter.py index a2d5e533..3e7a3658 100644 --- a/tests/unittests/a2a/converters/test_event_converter.py +++ b/tests/unittests/a2a/converters/test_event_converter.py @@ -1076,7 +1076,7 @@ class TestA2AToEventConverters: class TestRoleMappingRegression: - """Regression tests for issue #5186: role mapping in A2A→ADK conversion.""" + """Regression tests for role mapping in A2A→ADK conversion.""" def setup_method(self): """Set up test fixtures.""" diff --git a/tests/unittests/a2a/converters/test_part_converter.py b/tests/unittests/a2a/converters/test_part_converter.py index 8b64cfc7..15b8eaaa 100644 --- a/tests/unittests/a2a/converters/test_part_converter.py +++ b/tests/unittests/a2a/converters/test_part_converter.py @@ -445,7 +445,7 @@ class TestConvertGenaiPartToA2aPart: def test_convert_empty_text_part(self): """Test that Part(text='') is preserved, not dropped. - Regression test for #5341: empty-string text parts are valid and + Regression test: empty-string text parts are valid and must not fall through to the unsupported-part warning. """ # Arrange diff --git a/tests/unittests/agents/test_gemini_context_cache_manager.py b/tests/unittests/agents/test_gemini_context_cache_manager.py index ee02c8d5..4e3ae7c3 100644 --- a/tests/unittests/agents/test_gemini_context_cache_manager.py +++ b/tests/unittests/agents/test_gemini_context_cache_manager.py @@ -270,8 +270,6 @@ class TestGeminiContextCacheManager: async def test_create_cache_gates_on_prefix_not_full_prompt(self): """Cache creation is gated on the cacheable prefix, not the full prompt. - Regression test for https://github.com/google/adk-python/issues/5847. - On a long conversation the previous-prompt token count (``cacheable_contents_token_count``) can be well above Gemini's 4096-token minimum while the cached prefix ``contents[:cache_contents_count]`` is far diff --git a/tests/unittests/agents/test_llm_agent_fields.py b/tests/unittests/agents/test_llm_agent_fields.py index 70d6b069..f993aaf8 100644 --- a/tests/unittests/agents/test_llm_agent_fields.py +++ b/tests/unittests/agents/test_llm_agent_fields.py @@ -362,7 +362,7 @@ def test_allow_transfer_by_default(): assert not agent.disallow_transfer_to_peers -# TODO(b/448114567): Remove TestCanonicalTools once the workaround +# Pending cleanup: remove TestCanonicalTools once the workaround # is no longer needed. class TestCanonicalTools: """Unit tests for canonical_tools in LlmAgent.""" diff --git a/tests/unittests/agents/test_llm_agent_streaming_output.py b/tests/unittests/agents/test_llm_agent_streaming_output.py index 3426fd9a..45869092 100644 --- a/tests/unittests/agents/test_llm_agent_streaming_output.py +++ b/tests/unittests/agents/test_llm_agent_streaming_output.py @@ -57,7 +57,7 @@ def _event( @pytest.mark.asyncio async def test_run_async_accumulates_text_around_tool_calls(): - """Regression test for issue #5590. + """Regression test for dropped output_key text around tool calls. Under StreamingMode.SSE with tools, an LlmAgent emits text in several non-partial events: some carry text only, others carry text alongside a diff --git a/tests/unittests/agents/test_remote_a2a_agent.py b/tests/unittests/agents/test_remote_a2a_agent.py index 4a713986..fe39a29c 100644 --- a/tests/unittests/agents/test_remote_a2a_agent.py +++ b/tests/unittests/agents/test_remote_a2a_agent.py @@ -1615,7 +1615,7 @@ class TestRemoteA2aAgentMessageHandling: ): """Test streaming A2A response handling when content/parts are missing. - This verifies the fix for issue #3769 where the code could raise when it + This verifies the fix for the case where the code could raise when it tried to read parts[0] without checking for empty/missing content. """ mock_a2a_task = create_autospec(A2ATask, instance=True) @@ -1898,7 +1898,7 @@ class TestRemoteA2aAgentMessageHandling: class TestRemoteA2aAgentStreamingArtifactChunks: - """Regression tests for chunked artifact streams (#6343).""" + """Regression tests for chunked artifact streams.""" def setup_method(self): """Setup test fixtures.""" diff --git a/tests/unittests/evaluation/test_evaluation_generator.py b/tests/unittests/evaluation/test_evaluation_generator.py index 60591846..cb3b6c84 100644 --- a/tests/unittests/evaluation/test_evaluation_generator.py +++ b/tests/unittests/evaluation/test_evaluation_generator.py @@ -1338,7 +1338,7 @@ class TestLiveSessionCallbacks: def test_convert_events_preserves_tool_calls_when_skip_summarization(): - """Regression test for #5410. + """Regression test for tool calls dropped from invocation_events. When an event has skip_summarization=True, is_final_response() returns True even if the event contains function calls. Previously such an event was diff --git a/tests/unittests/evaluation/test_local_eval_service.py b/tests/unittests/evaluation/test_local_eval_service.py index a3a896dc..e8ee9769 100644 --- a/tests/unittests/evaluation/test_local_eval_service.py +++ b/tests/unittests/evaluation/test_local_eval_service.py @@ -632,7 +632,7 @@ def test_generate_final_eval_status_doesn_t_throw_on(eval_service): async def test_mcp_stdio_agent_no_runtime_error(mocker): """Test that LocalEvalService can handle MCP stdio agents without RuntimeError. - This is a regression test for GitHub issue #2196: + This is a regression test for the reported failure: "RuntimeError: Attempted to exit cancel scope in a different task than it was entered in" diff --git a/tests/unittests/evaluation/test_trajectory_evaluator.py b/tests/unittests/evaluation/test_trajectory_evaluator.py index 8a3dae02..204d558b 100644 --- a/tests/unittests/evaluation/test_trajectory_evaluator.py +++ b/tests/unittests/evaluation/test_trajectory_evaluator.py @@ -491,7 +491,7 @@ def test_evaluate_invocations_invocation_events_format_exact_match( ): """InvocationEvents intermediate_data format should score 1.0 on exact match. - Regression test for #5410: tool_trajectory_avg_score returned 0.0 even when + Regression test: tool_trajectory_avg_score returned 0.0 even when tool name and args were identical because function-call events with skip_summarization=True were incorrectly excluded from invocation_events. """ diff --git a/tests/unittests/flows/llm_flows/test_base_llm_flow.py b/tests/unittests/flows/llm_flows/test_base_llm_flow.py index ff702e38..ea81355b 100644 --- a/tests/unittests/flows/llm_flows/test_base_llm_flow.py +++ b/tests/unittests/flows/llm_flows/test_base_llm_flow.py @@ -172,7 +172,7 @@ async def test_preprocess_handles_mixed_tools_and_toolsets(): assert mock_toolset.process_llm_request_called -# TODO(b/448114567): Remove the following test_preprocess_with_google_search +# Pending cleanup: remove the following test_preprocess_with_google_search # tests once the workaround is no longer needed. @pytest.mark.asyncio async def test_preprocess_with_google_search_only(): @@ -490,7 +490,7 @@ class _AsyncProcessLlmRequestTool: self._on_process(self.name) -# TODO(b/448114567): Remove the following +# Pending cleanup: remove the following # test_handle_after_model_callback_grounding tests once the workaround # is no longer needed. def dummy_tool(): @@ -1681,7 +1681,7 @@ def _make_agent_tree(): @pytest.mark.asyncio async def test_empty_stop_after_tool_call_surfaces_error_event(): - """Regression test for empty Gemini turn after a successful tool call (#5631). + """Regression test for an empty Gemini turn after a successful tool call. Turn 1 returns a function_call which executes successfully, then turn 2 returns Content(role='model', parts=[]) with finish_reason=STOP and no error. diff --git a/tests/unittests/flows/llm_flows/test_code_execution.py b/tests/unittests/flows/llm_flows/test_code_execution.py index c19ce0f1..83106927 100644 --- a/tests/unittests/flows/llm_flows/test_code_execution.py +++ b/tests/unittests/flows/llm_flows/test_code_execution.py @@ -207,7 +207,7 @@ def test_data_file_helper_lib_defines_crop(): assert crop('x' * 100, max_chars=10) == 'x' * 7 + '...' assert crop('abcdef', max_chars=2) == 'ab' - # Regression for #4011: explore_df raised NameError when crop was undefined. + # Regression: explore_df raised NameError when crop was undefined. namespace['explore_df'](pd.DataFrame({'a': [1, 2], 'b': ['x', 'y']})) diff --git a/tests/unittests/flows/llm_flows/test_contents.py b/tests/unittests/flows/llm_flows/test_contents.py index 50bbdb29..7243fbe7 100644 --- a/tests/unittests/flows/llm_flows/test_contents.py +++ b/tests/unittests/flows/llm_flows/test_contents.py @@ -1324,7 +1324,7 @@ async def test_adk_function_call_ids_preserved_for_interactions_model(): @pytest.mark.asyncio async def test_adk_function_call_ids_preserved_for_anthropic_model(): """Anthropic ids must round-trip through replay so Claude can match - tool_use blocks with their tool_result blocks (issue #5074). + tool_use blocks with their tool_result blocks. """ from google.adk.models.anthropic_llm import AnthropicLlm @@ -1875,8 +1875,8 @@ def test_recover_compacted_function_calls_uses_latest_sibling_response(): def test_get_contents_recovers_compacted_long_running_call_on_resume(): """A long-running call compacted before resume is restored during assembly. - Reproduces issue #5602: the call and its intermediate placeholder response are - summarized away, then the real result arrives on resume. Without recovery, + The call and its intermediate placeholder response are summarized away, then + the real result arrives on resume. Without recovery, assembly raises because the resumed response has no matching call. """ compaction = EventCompaction( diff --git a/tests/unittests/flows/llm_flows/test_functions_thread_pool.py b/tests/unittests/flows/llm_flows/test_functions_thread_pool.py index 2c22a59e..23ddaf90 100644 --- a/tests/unittests/flows/llm_flows/test_functions_thread_pool.py +++ b/tests/unittests/flows/llm_flows/test_functions_thread_pool.py @@ -795,7 +795,7 @@ class TestCallToolInThreadPool: @pytest.mark.asyncio async def test_sync_tool_returning_none_runs_exactly_once(self): - """Regression test for issue #5284. + """Regression test for double invocation of a None-returning sync tool. A sync FunctionTool whose underlying function returns None must not be re-invoked through the run_async fallback path. diff --git a/tests/unittests/flows/llm_flows/test_nl_planning.py b/tests/unittests/flows/llm_flows/test_nl_planning.py index d4ff1e23..f3e27ac1 100644 --- a/tests/unittests/flows/llm_flows/test_nl_planning.py +++ b/tests/unittests/flows/llm_flows/test_nl_planning.py @@ -162,7 +162,7 @@ class NonOverriddenBuiltInPlanner(BuiltInPlanner): async def test_overridden_subclass_process_planning_response_called(): """Test that subclasses overriding process_planning_response have it called. - Regression test for issue #4133. + Regression test: the base implementation used to be called instead. """ planner = OverriddenBuiltInPlanner(thinking_config=types.ThinkingConfig()) agent = Agent(name='test_agent', planner=planner) diff --git a/tests/unittests/models/test_litellm.py b/tests/unittests/models/test_litellm.py index 899c453e..0836b9e7 100644 --- a/tests/unittests/models/test_litellm.py +++ b/tests/unittests/models/test_litellm.py @@ -5019,8 +5019,8 @@ async def test_finish_reason_propagation( def test_model_response_to_generate_content_response_no_message_with_finish_reason(): """Test response with no message but finish_reason returns empty LlmResponse. - This test covers issue #3618: when a turn ends with tool calls and no final - message, we should return an empty LlmResponse instead of raising ValueError. + When a turn ends with tool calls and no final message, we should return an + empty LlmResponse instead of raising ValueError. """ response = ModelResponse( model="test_model", diff --git a/tests/unittests/plugins/test_bigquery_agent_analytics_plugin.py b/tests/unittests/plugins/test_bigquery_agent_analytics_plugin.py index 6a6c0ea8..7388fe9c 100644 --- a/tests/unittests/plugins/test_bigquery_agent_analytics_plugin.py +++ b/tests/unittests/plugins/test_bigquery_agent_analytics_plugin.py @@ -659,7 +659,7 @@ class TestBigQueryAgentAnalyticsPlugin: dummy_arrow_schema, mock_asyncio_to_thread, ): - """Regression test for cross-region writes (issue #262). + """Regression test for cross-region writes. The Storage Write API streaming AppendRows RPC does not auto-populate the request-routing header, so writes to a dataset @@ -2111,7 +2111,7 @@ class TestBigQueryAgentAnalyticsPlugin: callback_context, dummy_arrow_schema, ): - """Regression for #6063: None agent falls back to source event author.""" + """Regression: None agent falls back to source event author.""" # Workflow-driven invocations leave ``InvocationContext.agent`` as None. # Reading ``callback_context.agent_name`` then raised ``AttributeError``, # which ``@_safe_callback`` swallowed, silently dropping the BigQuery row. @@ -2143,7 +2143,7 @@ class TestBigQueryAgentAnalyticsPlugin: callback_context, dummy_arrow_schema, ): - """Regression for #6063: callback-only row with no agent writes null.""" + """Regression: callback-only row with no agent writes null.""" callback_context._invocation_context.agent = None await bq_plugin_inst._log_event( @@ -2573,7 +2573,7 @@ class TestBigQueryAgentAnalyticsPlugin: """Verify no quota_project_id is set when credentials don't provide one. This is critical for Workload Identity Federation flows where setting - quota_project_id on the client breaks auth token refresh (issue #4370). + quota_project_id on the client breaks auth token refresh. """ mock_creds = mock.create_autospec( google.auth.credentials.Credentials, instance=True, spec_set=True @@ -2822,7 +2822,7 @@ class TestBigQueryAgentAnalyticsPlugin: self, callback_context, ): - """Regression guard for the duplicate-Cloud-Trace bug (issue #94). + """Regression guard for the duplicate-Cloud-Trace bug. The plugin must NOT call ``tracer.start_span(...)`` from ``push_span`` / ``pop_span``. Any owned OTel span goes through @@ -2858,7 +2858,7 @@ class TestBigQueryAgentAnalyticsPlugin: async def test_push_pop_does_not_export_spans_through_real_provider( self, callback_context ): - """End-to-end regression guard against #94 with a real OTel + """End-to-end guard against duplicate Cloud Trace spans with a real OTel provider + in-memory exporter. @@ -2901,7 +2901,7 @@ class TestBigQueryAgentAnalyticsPlugin: assert exporter.get_finished_spans() == (), ( "Plugin must not export OTel spans; any owned span would" " surface as a duplicate in Cloud Trace alongside the" - " framework's real spans (issue #94)." + " framework's real spans." ) provider.shutdown() @@ -5861,7 +5861,7 @@ class TestHITLTracing: # ============================================================================== -# TEST CLASS: Span Hierarchy Isolation (Issue #4561) +# TEST CLASS: Span Hierarchy Isolation # ============================================================================== @@ -6724,7 +6724,7 @@ class TestAnalyticsViews: # ============================================================================== -# Trace-ID Continuity Tests (Issue #4645) +# Trace-ID Continuity Tests # ============================================================================== class TestTraceIdContinuity: """Tests for trace_id continuity across all events in an invocation. @@ -6740,9 +6740,9 @@ class TestTraceIdContinuity: async def test_trace_id_continuity_no_ambient_span(self, callback_context): """All events share one trace_id when no ambient OTel span exists. - Simulates the #4645 scenario: OTel IS configured (real TracerProvider) - but the Runner's ambient span is NOT present (e.g. Agent Engine, - custom runners). + Simulates the broken-continuity scenario: OTel IS configured (real + TracerProvider) but the Runner's ambient span is NOT present (e.g. Agent + Engine, custom runners). """ from opentelemetry.sdk.trace import TracerProvider as SdkProvider from opentelemetry.sdk.trace.export import SimpleSpanProcessor @@ -7267,7 +7267,7 @@ class TestStackLeakSafety: def test_clear_stack_does_not_export_spans(self, callback_context): """``clear_stack()`` clears the internal records but does NOT - export any OTel spans (issue #94 regression guard). + export any OTel spans (duplicate-Cloud-Trace regression guard). Pre-fix, ``clear_stack()`` called ``record.span.end()`` for every owned record, which delivered the now-finished span to whatever @@ -7304,11 +7304,11 @@ class TestStackLeakSafety: result = bigquery_agent_analytics_plugin._span_records_ctx.get() assert result == [] - # Still no exported spans — the regression guard for #94. + # Still no exported spans — the duplicate-Cloud-Trace guard. assert exporter.get_finished_spans() == (), ( "clear_stack() must not export OTel spans; any owned span" " would surface as a duplicate in Cloud Trace alongside the" - " framework's real spans (issue #94)." + " framework's real spans." ) provider.shutdown() @@ -8226,7 +8226,7 @@ class TestA2AInteractionLogging: # ================================================================ -# TEST CLASS: Dataset location handling (Issue #5476) +# TEST CLASS: Dataset location handling # ================================================================ class TestDatasetLocationHandling: """Tests that BQ client is created without a default location. @@ -8324,7 +8324,7 @@ class TestDatasetLocationHandling: # ================================================================ -# TEST CLASS: Fork detection after pickle (Issue #86 / PR #5528) +# TEST CLASS: Fork detection after pickle # ================================================================ class TestForkDetectionAfterPickle: """Tests that unpickled plugins do not false-positive fork detection.""" @@ -8394,7 +8394,7 @@ class TestForkDetectionAfterPickle: # ================================================================ -# TEST CLASS: GCS offload unit mismatch fix (Issue #5561) +# TEST CLASS: GCS offload unit mismatch fix # ================================================================ class TestOffloadUnitSeparation: """Tests that byte-based inline limit and character-based truncation @@ -8608,7 +8608,7 @@ class TestOffloadUnitSeparation: # ================================================================ -# TEST CLASS: AGENT_RESPONSE logging (Issue #87) +# TEST CLASS: AGENT_RESPONSE logging # ================================================================ class TestAgentResponseLogging: """Tests that final agent response events are captured correctly.""" diff --git a/tests/unittests/plugins/test_context_filtering_plugin.py b/tests/unittests/plugins/test_context_filtering_plugin.py index 01aa891e..bf0c9b3f 100644 --- a/tests/unittests/plugins/test_context_filtering_plugin.py +++ b/tests/unittests/plugins/test_context_filtering_plugin.py @@ -222,12 +222,12 @@ def _create_function_response_content(name: str, call_id: str) -> types.Content: async def test_filter_preserves_function_call_response_pairs(): """Tests that function_call and function_response pairs are kept together. - This tests the fix for issue #4027 where filtering could create orphaned + This tests the fix for the case where filtering could create orphaned function_response messages without their corresponding function_call. """ plugin = ContextFilterPlugin(num_invocations_to_keep=2) - # Simulate conversation from issue #4027: + # Simulate the reported conversation: # user -> model -> user -> model(function_call) -> user(function_response) # -> model -> user -> model(function_call) -> user(function_response) contents = [ diff --git a/tests/unittests/plugins/test_notification_error_callbacks.py b/tests/unittests/plugins/test_notification_error_callbacks.py index 8095fb6f..21ed7455 100644 --- a/tests/unittests/plugins/test_notification_error_callbacks.py +++ b/tests/unittests/plugins/test_notification_error_callbacks.py @@ -14,7 +14,7 @@ """Tests for on_agent_error_callback and on_run_error_callback. -Validates RFC #5044: agent-level and runner-level error callbacks. +Validates the agent-level and runner-level error callback contract. """ import asyncio diff --git a/tests/unittests/plugins/test_reflect_retry_tool_plugin.py b/tests/unittests/plugins/test_reflect_retry_tool_plugin.py index 26259264..8f315cad 100644 --- a/tests/unittests/plugins/test_reflect_retry_tool_plugin.py +++ b/tests/unittests/plugins/test_reflect_retry_tool_plugin.py @@ -57,8 +57,8 @@ class CustomErrorExtractionPlugin(ReflectAndRetryToolPlugin): return None -# Inheriting from IsolatedAsyncioTestCase ensures consistent behavior. -# See https://github.com/pytest-dev/pytest-asyncio/issues/1039 +# Inheriting from IsolatedAsyncioTestCase ensures consistent behavior, because +# pytest-asyncio's own event-loop scoping varies across versions. class TestReflectAndRetryToolPlugin(IsolatedAsyncioTestCase): """Comprehensive tests for ReflectAndRetryToolPlugin focusing on behavior.""" diff --git a/tests/unittests/sessions/test_session_service.py b/tests/unittests/sessions/test_session_service.py index 9ecb3d7e..a8a57039 100644 --- a/tests/unittests/sessions/test_session_service.py +++ b/tests/unittests/sessions/test_session_service.py @@ -2014,7 +2014,7 @@ def test_database_session_service_visible_in_module_namespace(): """DatabaseSessionService must be in dir() so Sphinx autodoc renders it. It is imported lazily via module __getattr__, so without an explicit - __dir__ it drops out of the generated API reference (issue #4331). + __dir__ it drops out of the generated API reference. """ import google.adk.sessions as sessions_module @@ -2131,7 +2131,7 @@ async def test_database_session_service_requires_one_argument(): async def test_database_session_service_sqlite_file_timestamp_read_after_reopen( tmp_path, ): - """Regression test for #6352 (SQLite REAL-affinity timestamp reads).""" + """Regression test for SQLite REAL-affinity timestamp reads.""" # SQLite REAL-affinity columns can end up storing raw Unix epoch floats # instead of the text format SQLAlchemy's DateTime type normally writes # (for example, if the row was written by a different code path than the diff --git a/tests/unittests/sessions/test_vertex_ai_session_service.py b/tests/unittests/sessions/test_vertex_ai_session_service.py index ff7d465e..b589d8c3 100644 --- a/tests/unittests/sessions/test_vertex_ai_session_service.py +++ b/tests/unittests/sessions/test_vertex_ai_session_service.py @@ -1170,7 +1170,7 @@ async def test_append_event(): async def test_append_event_strips_unsupported_part_metadata( mock_api_client_instance: MockAsyncClient, ) -> None: - """part_metadata must not reach the Sessions API (#6014). + """part_metadata must not reach the Sessions API. ``Part.part_metadata`` is a Gemini Developer API-only field; the Vertex AI Agent Engine Sessions ``appendEvent`` API rejects it with 400 INVALID_ARGUMENT @@ -1212,7 +1212,7 @@ async def test_append_event_strips_unsupported_part_metadata( async def test_append_event_with_part_metadata_round_trips( mock_api_client_instance: MockAsyncClient, ) -> None: - """Reconstruction side of #6014: an event carrying part_metadata appends and + """Reconstruction side: an event carrying part_metadata appends and reads back without error. part_metadata is dropped (unsupported on Vertex), but the session round-trips and the part text is preserved. """ diff --git a/tests/unittests/telemetry/functional_test_cases.py b/tests/unittests/telemetry/functional_test_cases.py index 2a2a334e..2a3348f6 100644 --- a/tests/unittests/telemetry/functional_test_cases.py +++ b/tests/unittests/telemetry/functional_test_cases.py @@ -2384,7 +2384,7 @@ EXPECTED_METRICS_V2: dict[str, frozenset[MetricPoint]] = { # ``error.type`` across the duration metrics (see the metric constants below). # # ``google.genai`` collapses every 4xx into ``ClientError`` / 5xx into -# ``ServerError``, so before b/534739207 every such failure reported +# ``ServerError``, so historically every such failure reported # ``error.type=ClientError``. ADK now uses the provider's HTTP status code # (e.g. ``429``), falling back to the exception class name for non-API errors # (e.g. ``ValueError``). @@ -2728,7 +2728,7 @@ ALL_CASES: list[FunctionalTestCase] = [ metric_points=EXPECTED_METRICS_V2, ), ), - # Inference failures (b/534739207): the mock raises before responding, so + # Inference failures: the mock raises before responding, so # the scenario aborts and the failure surfaces on ``error.type``. A 429 # surfaces its HTTP status code ``429`` (not a blanket ``ClientError``); a # plain ``ValueError`` falls back to the class name. diff --git a/tests/unittests/test_runners.py b/tests/unittests/test_runners.py index 35fb0cdf..b76953ea 100644 --- a/tests/unittests/test_runners.py +++ b/tests/unittests/test_runners.py @@ -1909,9 +1909,9 @@ class TestRunnerInferAgentOrigin: def test_infer_agent_origin_no_false_positive_for_direct_llm_agent(self): """Test that using LlmAgent directly doesn't trigger mismatch warning. - Regression test for GitHub issue #3143: Users who instantiate LlmAgent - directly and run from a directory that is a parent of the ADK installation - were getting false positive 'App name mismatch' warnings. + Regression test: users who instantiate LlmAgent directly and run from a + directory that is a parent of the ADK installation were getting false + positive 'App name mismatch' warnings. This also verifies that _infer_agent_origin returns None for ADK internal modules (google.adk.*). diff --git a/tests/unittests/tools/test_build_function_declaration.py b/tests/unittests/tools/test_build_function_declaration.py index 6898f453..24f3a5f3 100644 --- a/tests/unittests/tools/test_build_function_declaration.py +++ b/tests/unittests/tools/test_build_function_declaration.py @@ -680,7 +680,7 @@ class TestBuildFunctionDeclarationWithJsonSchema: get_data, variant=GoogleLLMVariant.GEMINI_API ) - # GEMINI_API should not have response_json_schema due to bug b/421991354 + # GEMINI_API should not have response_json_schema: the API rejects it. assert decl.response_json_schema is None @pytest.mark.parametrize( diff --git a/tests/unittests/tools/test_google_search_agent_tool.py b/tests/unittests/tools/test_google_search_agent_tool.py index cdfcf593..5c3c3f55 100644 --- a/tests/unittests/tools/test_google_search_agent_tool.py +++ b/tests/unittests/tools/test_google_search_agent_tool.py @@ -31,7 +31,7 @@ function_call_no_schema = Part.from_function_call( grounding_metadata = types.GroundingMetadata(web_search_queries=['test query']) -# TODO(b/448114567): Remove test_grounding_metadata_ tests once the workaround +# Pending cleanup: remove test_grounding_metadata_ tests once the workaround # is no longer needed. diff --git a/tests/unittests/workflow/test_workflow_hitl.py b/tests/unittests/workflow/test_workflow_hitl.py index 17de8206..3097989e 100644 --- a/tests/unittests/workflow/test_workflow_hitl.py +++ b/tests/unittests/workflow/test_workflow_hitl.py @@ -2139,7 +2139,7 @@ async def test_request_input_resume_after_earlier_invocation_completed( ): """A completed earlier invocation must not block a later HITL resume. - Regression test for #6497. The first invocation finishes on the `finish` + Regression test. The first invocation finishes on the `finish` branch. The second invocation takes the `clarify` branch and pauses for input. When the replay sequence was built from every event in the session, the terminal `finish` event of the first invocation entered the sequence