From 236e8082dc8f6f95c34781987aaf328da14c15cf Mon Sep 17 00:00:00 2001 From: evalstate <1936278+evalstate@users.noreply.github.com> Date: Tue, 25 Nov 2025 23:34:59 +0000 Subject: [PATCH] integration test --- src/fast_agent/core/fastagent.py | 9 +++++ .../integration/instruction_templates/FOO.md | 1 + .../fastagent.config.yaml | 7 ++++ .../test_file_silent_instruction.py | 38 +++++++++++++++++++ 4 files changed, 55 insertions(+) create mode 100644 tests/integration/instruction_templates/FOO.md create mode 100644 tests/integration/instruction_templates/fastagent.config.yaml create mode 100644 tests/integration/instruction_templates/test_file_silent_instruction.py diff --git a/src/fast_agent/core/fastagent.py b/src/fast_agent/core/fastagent.py index 79e3f174..b0693684 100644 --- a/src/fast_agent/core/fastagent.py +++ b/src/fast_agent/core/fastagent.py @@ -865,6 +865,15 @@ def _apply_instruction_context( if request_params is not None: request_params.systemPrompt = resolved + # TODO -- find a cleaner way of doing this + # Keep any attached LLM in sync so the provider sees the resolved prompt + llm = getattr(agent, "_llm", None) + if llm is not None: + if getattr(llm, "default_request_params", None) is not None: + llm.default_request_params.systemPrompt = resolved + if hasattr(llm, "instruction"): + llm.instruction = resolved + def _apply_skills_to_agent_configs(self, default_skills: list[SkillManifest]) -> None: self._default_skill_manifests = list(default_skills) diff --git a/tests/integration/instruction_templates/FOO.md b/tests/integration/instruction_templates/FOO.md new file mode 100644 index 00000000..5b1daa9b --- /dev/null +++ b/tests/integration/instruction_templates/FOO.md @@ -0,0 +1 @@ +This text came from FOO.md and should replace the placeholder. diff --git a/tests/integration/instruction_templates/fastagent.config.yaml b/tests/integration/instruction_templates/fastagent.config.yaml new file mode 100644 index 00000000..6adebe3f --- /dev/null +++ b/tests/integration/instruction_templates/fastagent.config.yaml @@ -0,0 +1,7 @@ +default_model: passthrough + +logger: + level: "error" + progress_display: false + show_chat: false + show_tools: false diff --git a/tests/integration/instruction_templates/test_file_silent_instruction.py b/tests/integration/instruction_templates/test_file_silent_instruction.py new file mode 100644 index 00000000..0ba63dcb --- /dev/null +++ b/tests/integration/instruction_templates/test_file_silent_instruction.py @@ -0,0 +1,38 @@ +from pathlib import Path + +import pytest + + +@pytest.mark.integration +@pytest.mark.asyncio +async def test_file_silent_reaches_llm_request_params(fast_agent): + """Ensure {{file_silent:...}} is resolved before the LLM sees the system prompt.""" + fast = fast_agent + file_text = Path("FOO.md").read_text(encoding="utf-8").strip() + + @fast.agent( + name="file_template_agent", + instruction="System prompt start. {{file_silent:FOO.md}}", + model="passthrough", + ) + async def agent_function(): + async with fast.run() as agent_app: + agent = agent_app.file_template_agent + + # Agent-facing instruction should have the file contents applied + assert "{{file_silent:FOO.md}}" not in agent.instruction + assert file_text in agent.instruction + + # The LLM request params (what the provider sees) should also be resolved + request_params = agent.llm.get_request_params() + assert request_params.systemPrompt is not None + assert "{{file_silent:FOO.md}}" not in request_params.systemPrompt + assert file_text in request_params.systemPrompt + + # Default params should stay in sync for future calls + assert file_text in agent.llm.default_request_params.systemPrompt + + response = await agent.send("ping") + assert "ping" in response + + await agent_function()