Improve drive layer prompt guidance

This commit is contained in:
Yanli 盐粒 2026-06-25 21:59:24 +08:00
parent f7478e0ea2
commit ff74c3f8bd
2 changed files with 41 additions and 19 deletions

View File

@ -4,11 +4,10 @@ The API backend sends the full drive skill catalog plus the ordered drive keys
mentioned in the prompt. When the layer enters a run context it eagerly pulls
those mentioned skills/files from the Dify inner drive bridge, materializes them
under the fixed Agent Stub drive base for ``drive_ref``, and contributes a
concise prompt block describing what was loaded and what other skills remain
available for lazy pull. It also contributes a suffix prompt with
``dify-agent drive`` and ``dify-agent file`` usage so the model has concrete
Agent Stub commands for materializing drive content and workflow files when a
shell layer is available.
concise prompt block describing what was loaded. It also contributes a suffix
prompt with the remaining skill catalog plus ``dify-agent drive`` and
``dify-agent file`` usage so the model has concrete Agent Stub commands for
materializing drive content and workflow files when a shell layer is available.
"""
from __future__ import annotations
@ -103,7 +102,7 @@ class DifyDriveLayer(PlainLayer[DifyDriveDeps, DifyDriveLayerConfig, EmptyRuntim
@property
@override
def suffix_prompts(self) -> list[str]:
return [_AGENT_STUB_CLI_USAGE_PROMPT]
return [self.build_suffix_prompt()]
@override
async def on_context_create(self) -> None:
@ -124,7 +123,13 @@ class DifyDriveLayer(PlainLayer[DifyDriveDeps, DifyDriveLayerConfig, EmptyRuntim
skill = next((item for item in self.config.skills if item.skill_md_key == skill_key), None)
if skill is None:
continue
loaded_skill_sections.append(f"Path: {skill.path}\nName: {skill.name}\nSKILL.md:\n{body}")
pulled_skill_path = self._pulled_file_paths.get(skill_key)
if pulled_skill_path is None:
continue
local_path = Path(pulled_skill_path).parent
loaded_skill_sections.append(
f"Path: {skill.path}\nLocal path: {local_path}\nName: {skill.name}\nSKILL.md:\n{body}"
)
if loaded_skill_sections:
sections.append("Loaded mentioned skills:\n\n" + "\n\n".join(loaded_skill_sections))
@ -136,18 +141,30 @@ class DifyDriveLayer(PlainLayer[DifyDriveDeps, DifyDriveLayerConfig, EmptyRuntim
if mentioned_files:
sections.append("Mentioned files pulled to local drive:\n" + "\n".join(mentioned_files))
other_skills = [
f"- {skill.path}: {skill.name}{skill.description}"
for skill in self.config.skills
if skill.skill_md_key not in set(self.config.mentioned_skill_keys)
]
if other_skills:
sections.append("Other available skills:\n" + "\n".join(other_skills))
if not sections:
return ""
return "\n\n".join(sections)
def build_suffix_prompt(self) -> str:
sections: list[str] = []
mentioned_skill_keys = set(self.config.mentioned_skill_keys)
other_skills = [
(
f"- {skill.path}: {skill.name}{skill.description}. "
f"Pull with `dify-agent drive pull {self._skill_prefix(skill.skill_md_key)}`."
)
for skill in self.config.skills
if skill.skill_md_key not in mentioned_skill_keys
]
if other_skills:
sections.append(
"Other available skills:\n"
+ "\n".join(other_skills)
+ "\n\nIf you want to use one, pull it first with `dify-agent drive pull <SKILL_PATH>/`."
)
sections.append(_AGENT_STUB_CLI_USAGE_PROMPT)
return "\n\n".join(sections)
async def _pull_mentioned_targets(self) -> None:
self._loaded_skill_bodies = {}
self._pulled_file_paths = {}

View File

@ -97,6 +97,9 @@ def test_drive_layer_exposes_agent_stub_cli_usage_suffix_prompt(tmp_path: Path)
assert len(layer.suffix_prompts) == 1
prompt = layer.suffix_prompts[0]
assert "Other available skills" in prompt
assert "other-skill: Other Skill — Fallback catalog entry." in prompt
assert "`dify-agent drive pull other-skill/`" in prompt
assert "dify-agent drive list [REMOTE_PREFIX]" in prompt
assert "dify-agent drive pull [REMOTE ...] [--to LOCAL_DIR]" in prompt
assert "--to ." in prompt
@ -145,10 +148,11 @@ async def test_on_context_create_loads_mentioned_targets_into_prompt(
prompt = layer.build_prompt_context()
assert "Loaded mentioned skills" in prompt
assert f"Local path: {tmp_path / 'tender-analyzer'}" in prompt
assert "# Tender Analyzer\nUse carefully." in prompt
assert f"files/report.pdf -> {tmp_path / 'files' / 'report.pdf'}" in prompt
assert "Other available skills" in prompt
assert "other-skill: Other Skill — Fallback catalog entry." in prompt
assert "Other available skills" not in prompt
assert "other-skill: Other Skill — Fallback catalog entry." not in prompt
@pytest.mark.anyio
@ -185,10 +189,11 @@ async def test_on_context_resume_loads_mentioned_targets_into_prompt(
prompt = layer.build_prompt_context()
assert "Loaded mentioned skills" in prompt
assert f"Local path: {tmp_path / 'tender-analyzer'}" in prompt
assert "# Tender Analyzer\nUse carefully." in prompt
assert f"files/report.pdf -> {tmp_path / 'files' / 'report.pdf'}" in prompt
assert "Other available skills" in prompt
assert "other-skill: Other Skill — Fallback catalog entry." in prompt
assert "Other available skills" not in prompt
assert "other-skill: Other Skill — Fallback catalog entry." not in prompt
@pytest.mark.anyio