mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-07-26 07:57:57 +00:00
fix(subagents): prohibit task tool in general-purpose system prompt (#4161)
* fix(subagents): prohibit task tool in general-purpose system prompt (#4159) The general-purpose subagent correctly lists `task` in disallowed_tools to prevent recursive nesting. However, the system prompt did not explicitly tell the LLM that `task` is unavailable. When the subagent sees the parent agent use `task`, it infers the tool is available and attempts to call it, triggering a LangGraph tool validation error. Add an explicit <tool_restrictions> block to the system prompt stating that `task` is NOT available and the subagent must NEVER attempt to call it. This prevents the LLM from attempting the call in the first place, rather than relying on runtime rejection. Add a regression test verifying the prompt contains the prohibition. * fix(security): register tool_restrictions in input sanitization denylist PR #4161 added <tool_restrictions> to general_purpose.py subagent prompt but did not register it in _BLOCKED_TAG_NAMES. The anti-drift test test_denylist_covers_framework_authority_blocks caught this: forging <tool_restrictions> in untrusted input could trick the model into believing it has (or lacks) tool restrictions it does not. Add 'tool_restrictions' to _BLOCKED_TAG_NAMES alongside the other subagent authority blocks (file_editing_workflow / guidelines / output_format / working_directory).
This commit is contained in:
parent
9c77046d10
commit
60e50537f3
@ -90,6 +90,10 @@ _BLOCKED_TAG_NAMES: frozenset[str] = frozenset(
|
||||
"guidelines",
|
||||
"output_format",
|
||||
"working_directory",
|
||||
# Subagent system-prompt block (general_purpose.py): declares the task
|
||||
# tool off-limits. Forging this in untrusted input could trick the
|
||||
# model into believing it has (or lacks) tool restrictions it does not.
|
||||
"tool_restrictions",
|
||||
# Common prompt-injection tag patterns
|
||||
"system",
|
||||
"instruction",
|
||||
|
||||
@ -24,6 +24,14 @@ Do NOT use for simple, single-step operations.""",
|
||||
- Do NOT ask for clarification - work with the information provided
|
||||
</guidelines>
|
||||
|
||||
<tool_restrictions>
|
||||
You are a subagent - the `task` tool is NOT available to you.
|
||||
You must NEVER attempt to call `task` or dispatch further subagents.
|
||||
Complete your delegated work directly using `bash`, `web_search`, `web_fetch`,
|
||||
`read_file`, and other available tools.
|
||||
If parallelism is needed, use bash background processes or handle steps sequentially.
|
||||
</tool_restrictions>
|
||||
|
||||
<file_editing_workflow>
|
||||
When revising an existing file, prefer `str_replace` over `write_file` —
|
||||
it sends only the diff and avoids re-emitting the whole file (mirrors
|
||||
|
||||
@ -55,3 +55,17 @@ def test_general_purpose_subagent_prompt_mentions_workspace_relative_paths() ->
|
||||
|
||||
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
|
||||
|
||||
|
||||
def test_general_purpose_subagent_prompt_prohibits_task_tool() -> None:
|
||||
"""The system prompt must explicitly tell the LLM that `task` is unavailable.
|
||||
|
||||
Without this, subagents may attempt to call `task` after seeing the parent
|
||||
agent use it, triggering a LangGraph tool validation error (#4159).
|
||||
"""
|
||||
from deerflow.subagents.builtins.general_purpose import GENERAL_PURPOSE_CONFIG
|
||||
|
||||
prompt = GENERAL_PURPOSE_CONFIG.system_prompt
|
||||
assert "task" in prompt.lower()
|
||||
assert "NOT available" in prompt or "must NEVER" in prompt
|
||||
assert "disallowed_tools" not in prompt # don't leak internal implementation details
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user