diff --git a/backend/packages/harness/deerflow/agents/lead_agent/prompt.py b/backend/packages/harness/deerflow/agents/lead_agent/prompt.py index 4aa2141e1..71af2e653 100644 --- a/backend/packages/harness/deerflow/agents/lead_agent/prompt.py +++ b/backend/packages/harness/deerflow/agents/lead_agent/prompt.py @@ -417,6 +417,9 @@ You: "Deploying to staging..." [proceed] - Use `read_file` tool to read uploaded files using their paths from the list - For PDF, PPT, Excel, and Word files, converted Markdown versions (*.md) are available alongside originals - All temporary work happens in `/mnt/user-data/workspace` +- Treat `/mnt/user-data/workspace` as your default current working directory for coding and file-editing tasks +- When writing scripts or commands that create/read files from the workspace, prefer relative paths such as `hello.txt`, `../uploads/data.csv`, and `../outputs/report.md` +- Avoid hardcoding `/mnt/user-data/...` inside generated scripts when a relative path from the workspace is enough - Final deliverables must be copied to `/mnt/user-data/outputs` and presented using `present_file` tool {acp_section} diff --git a/backend/packages/harness/deerflow/subagents/builtins/bash_agent.py b/backend/packages/harness/deerflow/subagents/builtins/bash_agent.py index 094ec65e7..8ebe2cbc3 100644 --- a/backend/packages/harness/deerflow/subagents/builtins/bash_agent.py +++ b/backend/packages/harness/deerflow/subagents/builtins/bash_agent.py @@ -20,7 +20,8 @@ Do NOT use for simple single commands - use bash tool directly instead.""", - Use parallel execution when commands are independent - Report both stdout and stderr when relevant - Handle errors gracefully and explain what went wrong -- Use absolute paths for file operations +- Use workspace-relative paths for files under the default workspace, uploads, and outputs directories +- Use absolute paths only when the task references deployment-configured custom mounts outside the default workspace layout - Be cautious with destructive operations (rm, overwrite, etc.) @@ -38,6 +39,8 @@ You have access to the sandbox environment: - User workspace: `/mnt/user-data/workspace` - Output files: `/mnt/user-data/outputs` - Deployment-configured custom mounts may also be available at other absolute container paths; use them directly when the task references those mounted directories +- Treat `/mnt/user-data/workspace` as the default working directory for file IO +- Prefer relative paths from the workspace, such as `hello.txt`, `../uploads/input.csv`, and `../outputs/result.md`, when composing commands or helper scripts """, tools=["bash", "ls", "read_file", "write_file", "str_replace"], # Sandbox tools only diff --git a/backend/packages/harness/deerflow/subagents/builtins/general_purpose.py b/backend/packages/harness/deerflow/subagents/builtins/general_purpose.py index d09d1a00b..08f0c7593 100644 --- a/backend/packages/harness/deerflow/subagents/builtins/general_purpose.py +++ b/backend/packages/harness/deerflow/subagents/builtins/general_purpose.py @@ -39,6 +39,8 @@ You have access to the same sandbox environment as the parent agent: - User workspace: `/mnt/user-data/workspace` - Output files: `/mnt/user-data/outputs` - Deployment-configured custom mounts may also be available at other absolute container paths; use them directly when the task references those mounted directories +- Treat `/mnt/user-data/workspace` as the default working directory for coding and file IO +- Prefer relative paths from the workspace, such as `hello.txt`, `../uploads/input.csv`, and `../outputs/result.md`, when writing scripts or shell commands """, tools=None, # Inherit all tools from parent diff --git a/backend/tests/test_lead_agent_prompt.py b/backend/tests/test_lead_agent_prompt.py index 4962e1d8d..6817e7678 100644 --- a/backend/tests/test_lead_agent_prompt.py +++ b/backend/tests/test_lead_agent_prompt.py @@ -50,6 +50,24 @@ def test_apply_prompt_template_includes_custom_mounts(monkeypatch): assert "Custom Mounted Directories" in prompt +def test_apply_prompt_template_includes_relative_path_guidance(monkeypatch): + config = SimpleNamespace( + sandbox=SimpleNamespace(mounts=[]), + skills=SimpleNamespace(container_path="/mnt/skills"), + ) + monkeypatch.setattr("deerflow.config.get_app_config", lambda: config) + monkeypatch.setattr(prompt_module, "_get_enabled_skills", lambda: []) + monkeypatch.setattr(prompt_module, "get_deferred_tools_prompt_section", lambda: "") + monkeypatch.setattr(prompt_module, "_build_acp_section", lambda: "") + monkeypatch.setattr(prompt_module, "_get_memory_context", lambda agent_name=None: "") + monkeypatch.setattr(prompt_module, "get_agent_soul", lambda agent_name=None: "") + + prompt = prompt_module.apply_prompt_template() + + assert "Treat `/mnt/user-data/workspace` as your default current working directory" in prompt + assert "`hello.txt`, `../uploads/data.csv`, and `../outputs/report.md`" in prompt + + def test_refresh_skills_system_prompt_cache_async_reloads_immediately(monkeypatch, tmp_path): def make_skill(name: str) -> Skill: skill_dir = tmp_path / name diff --git a/backend/tests/test_subagent_prompt_security.py b/backend/tests/test_subagent_prompt_security.py index 46433500f..d0e5a949f 100644 --- a/backend/tests/test_subagent_prompt_security.py +++ b/backend/tests/test_subagent_prompt_security.py @@ -39,3 +39,17 @@ def test_build_subagent_section_includes_bash_when_available(monkeypatch) -> Non assert "For command execution (git, build, test, deploy operations)" in section assert 'bash("npm test")' in section assert "available tools (bash, ls, read_file, web_search, etc.)" in section + + +def test_bash_subagent_prompt_mentions_workspace_relative_paths() -> None: + from deerflow.subagents.builtins.bash_agent import BASH_AGENT_CONFIG + + assert "Treat `/mnt/user-data/workspace` as the default working directory for file IO" in BASH_AGENT_CONFIG.system_prompt + assert "`hello.txt`, `../uploads/input.csv`, and `../outputs/result.md`" in BASH_AGENT_CONFIG.system_prompt + + +def test_general_purpose_subagent_prompt_mentions_workspace_relative_paths() -> None: + from deerflow.subagents.builtins.general_purpose import GENERAL_PURPOSE_CONFIG + + assert "Treat `/mnt/user-data/workspace` as the default working directory for coding and file IO" in GENERAL_PURPOSE_CONFIG.system_prompt + assert "`hello.txt`, `../uploads/input.csv`, and `../outputs/result.md`" in GENERAL_PURPOSE_CONFIG.system_prompt