from __future__ import annotations from pathlib import Path import unittest from agent_builder.builder import ( BUILDER_SKILL_SOURCE, SYSTEM_PROMPT, _builder_skill_files, _with_builder_skills, ) from deepagents.backends import StateBackend class BuilderPromptTests(unittest.TestCase): def test_outer_agent_uses_500_recursion_limit(self) -> None: agent_source = Path(__file__).resolve().parents[1].joinpath("agent.py").read_text() self.assertIn("DEEPAGENTS_RECURSION_LIMIT = 500", agent_source) self.assertIn( "config={\"recursion_limit\": DEEPAGENTS_RECURSION_LIMIT}", agent_source, ) def test_prompt_requires_resource_mirror_for_heavy_agents(self) -> None: self.assertIn("declare resources in BOTH places", SYSTEM_PROMPT) self.assertIn("resources = Resources", SYSTEM_PROMPT) self.assertIn("runtime:", SYSTEM_PROMPT) self.assertIn("max_runtime_seconds", SYSTEM_PROMPT) def test_prompt_requires_live_schema_check_and_manim_contract(self) -> None: self.assertIn("live_skills[].input_schema", SYSTEM_PROMPT) self.assertIn("class GeneratedDeck(Slide)", SYSTEM_PROMPT) self.assertIn("manim-slides render --CE -ql", SYSTEM_PROMPT) self.assertIn("render: bool = False", SYSTEM_PROMPT) self.assertIn('config={"recursion_limit": 500}', SYSTEM_PROMPT) def test_prompt_requires_workspace_mounted_execution_for_outputs(self) -> None: self.assertIn("ctx.workspace_shell", SYSTEM_PROMPT) self.assertIn("ctx.workspace_python", SYSTEM_PROMPT) self.assertIn("/workspace/outputs/...", SYSTEM_PROMPT) self.assertIn("not workspace-mounted", SYSTEM_PROMPT) def test_prompt_and_backend_load_packaged_builder_skills(self) -> None: expected = { "deepagent-agent-design", "a2apack-agent-authoring", "deepagents-implementation-patterns", "workspace-artifact-safety", "agent-quality-review", } for skill_name in expected: self.assertIn(skill_name, SYSTEM_PROMPT) self.assertIn("deepagent-agent-design", SYSTEM_PROMPT) self.assertIn("write_agent_skill", SYSTEM_PROMPT) self.assertIn("workspace_access = WorkspaceAccess.dynamic", SYSTEM_PROMPT) files = _builder_skill_files() self.assertTrue( {path.split("/", 1)[0] for path in files}.issuperset(expected) ) self.assertIn("skills=[RUNTIME_SKILLS_ROOT]", files["deepagent-agent-design/SKILL.md"]) self.assertIn("from a2a_pack import", files["a2apack-agent-authoring/SKILL.md"]) self.assertIn("ctx.workspace_shell", files["a2apack-agent-authoring/SKILL.md"]) self.assertIn("create_deep_agent", files["deepagents-implementation-patterns/SKILL.md"]) self.assertIn('config={"recursion_limit": 500}', files["deepagents-implementation-patterns/SKILL.md"]) self.assertIn("ctx.write_artifact", files["workspace-artifact-safety/SKILL.md"]) self.assertIn("ctx.workspace_shell", files["workspace-artifact-safety/SKILL.md"]) self.assertIn("/workspace/outputs/...", files["workspace-artifact-safety/SKILL.md"]) self.assertIn("live_skills[].input_schema", files["agent-quality-review/SKILL.md"]) self.assertIn("ctx.workspace_python", files["agent-quality-review/SKILL.md"]) backend = _with_builder_skills(StateBackend()) listing = backend.ls(BUILDER_SKILL_SOURCE) paths = [entry["path"] for entry in (listing.entries or [])] for skill_name in expected: self.assertIn(f"{BUILDER_SKILL_SOURCE}{skill_name}/", paths)