diff --git a/src/google/adk/tools/skill_toolset.py b/src/google/adk/tools/skill_toolset.py index 4b4fd069d7..c09b2dcdda 100644 --- a/src/google/adk/tools/skill_toolset.py +++ b/src/google/adk/tools/skill_toolset.py @@ -97,6 +97,11 @@ def _build_skill_system_instruction(prefix: str | None = None) -> str: f"6. If `{p}run_skill_script` returns an error (for example " f"`SCRIPT_NOT_FOUND`), do not retry the same script or guess a " "different script path. Report the error to the user and stop.\n" + f"7. Loading a skill only retrieves its instructions; it does NOT " + f"complete your turn. After a `{p}load_skill` call returns, continue " + "in the SAME turn: call whatever tools the skill's steps require " + "(search, data retrieval, render), then write your reply. Never end " + "your turn with an empty response right after loading a skill.\n" ) diff --git a/tests/unittests/tools/test_skill_toolset.py b/tests/unittests/tools/test_skill_toolset.py index e9386bb063..450dbe3f30 100644 --- a/tests/unittests/tools/test_skill_toolset.py +++ b/tests/unittests/tools/test_skill_toolset.py @@ -1758,6 +1758,24 @@ def test_system_instruction_references_run_skill_script(): ) +def test_system_instruction_marks_load_skill_as_non_terminal(): + """Rule 7 must tell the model load_skill does not complete the turn. + + Without it, some models (notably Gemini) treat the load_skill tool call as + the entire turn and stop with no visible output, producing empty responses. + """ + instruction = skill_toolset.DEFAULT_SKILL_SYSTEM_INSTRUCTION + assert "does NOT complete your turn" in instruction + assert "empty response" in instruction + + +def test_prefixed_system_instruction_includes_continue_after_load_rule(): + """The prefixed builder variant must also carry rule 7 (with the prefix).""" + instruction = skill_toolset._build_skill_system_instruction(prefix="my") + assert "does NOT complete your turn" in instruction + assert "my_load_skill" in instruction + + # ── Finding 2: empty files are mounted (not silently dropped) ──