mirror of
https://github.com/NCBM/plyngent.git
synced 2026-07-25 08:04:57 +08:00
core/config: split agent system_prompt and tool_directives
This commit is contained in:
@@ -2,7 +2,12 @@ from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from plyngent.config import DEFAULT_SYSTEM_PROMPT, load
|
||||
from plyngent.config import (
|
||||
DEFAULT_SYSTEM_PROMPT,
|
||||
DEFAULT_TOOL_DIRECTIVES,
|
||||
compose_agent_system_content,
|
||||
load,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from pathlib import Path
|
||||
@@ -13,7 +18,9 @@ def test_agent_section_defaults(tmp_path: Path) -> None:
|
||||
_ = path.write_text("", encoding="utf-8")
|
||||
store = load(path)
|
||||
assert store.agent_config.system_prompt == DEFAULT_SYSTEM_PROMPT
|
||||
assert store.agent_config.tool_directives == DEFAULT_TOOL_DIRECTIVES
|
||||
assert "professional coding agent" in store.agent_config.system_prompt
|
||||
assert "### Workspace" in store.agent_config.tool_directives
|
||||
assert store.agent_config.max_tool_result_chars == 32_000
|
||||
assert store.agent_config.parallel_tools is True
|
||||
assert store.agent_config.confirm_destructive is True
|
||||
@@ -21,12 +28,31 @@ def test_agent_section_defaults(tmp_path: Path) -> None:
|
||||
assert store.agent_config.max_context_tokens == 200_000
|
||||
|
||||
|
||||
def test_compose_defaults_join_persona_and_directives() -> None:
|
||||
body = compose_agent_system_content(DEFAULT_SYSTEM_PROMPT, DEFAULT_TOOL_DIRECTIVES)
|
||||
assert body is not None
|
||||
assert body.startswith("You are a professional coding agent")
|
||||
assert "\n\n### Workspace" in body
|
||||
assert "### Todos" in body
|
||||
# No double-blank-line collapse issues between parts.
|
||||
assert "\n\n\n" not in body
|
||||
|
||||
|
||||
def test_compose_empty_combinations() -> None:
|
||||
assert compose_agent_system_content("", "") is None
|
||||
assert compose_agent_system_content(" ", "\n") is None
|
||||
assert compose_agent_system_content("Only persona", "") == "Only persona"
|
||||
assert compose_agent_system_content("", "Only tools") == "Only tools"
|
||||
assert compose_agent_system_content("Persona", "Tools") == "Persona\n\nTools"
|
||||
|
||||
|
||||
def test_agent_section_parse(tmp_path: Path) -> None:
|
||||
path = tmp_path / "c.toml"
|
||||
_ = path.write_text(
|
||||
"""
|
||||
[agent]
|
||||
system_prompt = "Be brief."
|
||||
tool_directives = "Use tools carefully."
|
||||
max_tool_result_chars = 100
|
||||
parallel_tools = false
|
||||
confirm_destructive = false
|
||||
@@ -37,14 +63,20 @@ max_context_tokens = 5000
|
||||
)
|
||||
store = load(path)
|
||||
assert store.agent_config.system_prompt == "Be brief."
|
||||
assert store.agent_config.tool_directives == "Use tools carefully."
|
||||
assert store.agent_config.max_tool_result_chars == 100
|
||||
assert store.agent_config.parallel_tools is False
|
||||
assert store.agent_config.confirm_destructive is False
|
||||
assert store.agent_config.path_denylist == ["/secrets/", ".ssh/"]
|
||||
assert store.agent_config.max_context_tokens == 5000
|
||||
composed = compose_agent_system_content(
|
||||
store.agent_config.system_prompt,
|
||||
store.agent_config.tool_directives,
|
||||
)
|
||||
assert composed == "Be brief.\n\nUse tools carefully."
|
||||
|
||||
|
||||
def test_agent_system_prompt_empty_disables(tmp_path: Path) -> None:
|
||||
def test_agent_system_prompt_empty_disables_persona_only(tmp_path: Path) -> None:
|
||||
path = tmp_path / "c.toml"
|
||||
_ = path.write_text(
|
||||
"""
|
||||
@@ -55,3 +87,52 @@ system_prompt = ""
|
||||
)
|
||||
store = load(path)
|
||||
assert store.agent_config.system_prompt == ""
|
||||
assert store.agent_config.tool_directives == DEFAULT_TOOL_DIRECTIVES
|
||||
body = compose_agent_system_content(
|
||||
store.agent_config.system_prompt,
|
||||
store.agent_config.tool_directives,
|
||||
)
|
||||
assert body is not None
|
||||
assert "### Workspace" in body
|
||||
assert "professional coding agent" not in body
|
||||
|
||||
|
||||
def test_agent_tool_directives_empty_disables_playbook_only(tmp_path: Path) -> None:
|
||||
path = tmp_path / "c.toml"
|
||||
_ = path.write_text(
|
||||
"""
|
||||
[agent]
|
||||
tool_directives = ""
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
store = load(path)
|
||||
assert store.agent_config.tool_directives == ""
|
||||
assert store.agent_config.system_prompt == DEFAULT_SYSTEM_PROMPT
|
||||
body = compose_agent_system_content(
|
||||
store.agent_config.system_prompt,
|
||||
store.agent_config.tool_directives,
|
||||
)
|
||||
assert body is not None
|
||||
assert "professional coding agent" in body
|
||||
assert "### Workspace" not in body
|
||||
|
||||
|
||||
def test_agent_both_empty_disables_system(tmp_path: Path) -> None:
|
||||
path = tmp_path / "c.toml"
|
||||
_ = path.write_text(
|
||||
"""
|
||||
[agent]
|
||||
system_prompt = ""
|
||||
tool_directives = ""
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
store = load(path)
|
||||
assert (
|
||||
compose_agent_system_content(
|
||||
store.agent_config.system_prompt,
|
||||
store.agent_config.tool_directives,
|
||||
)
|
||||
is None
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user