feat: add prompt placeholder substitution with {filename} syntax
This commit is contained in:
parent
760eac5a7b
commit
3de3614433
6 changed files with 274 additions and 33 deletions
|
|
@ -13,7 +13,6 @@ from hokusai.builder import (
|
|||
_collect_all_deps, # pyright: ignore[reportPrivateUsage]
|
||||
_collect_dep_files, # pyright: ignore[reportPrivateUsage]
|
||||
_collect_extra_params, # pyright: ignore[reportPrivateUsage]
|
||||
_resolve_prompt, # pyright: ignore[reportPrivateUsage]
|
||||
run_build,
|
||||
)
|
||||
from hokusai.config import GenerateTargetConfig, ProjectConfig
|
||||
|
|
@ -112,21 +111,6 @@ def _fake_providers() -> list[Provider]:
|
|||
return [FakeTextProvider(), FakeImageProvider()]
|
||||
|
||||
|
||||
class TestResolvePrompt:
|
||||
"""Test prompt resolution (file vs inline)."""
|
||||
|
||||
def test_inline_prompt(self, project_dir: Path) -> None:
|
||||
assert _resolve_prompt("Just a string", project_dir) == "Just a string"
|
||||
|
||||
def test_file_prompt(self, project_dir: Path, prompt_file: Path) -> None:
|
||||
result = _resolve_prompt(prompt_file.name, project_dir)
|
||||
assert result == "This prompt comes from a file"
|
||||
|
||||
def test_nonexistent_file_treated_as_inline(self, project_dir: Path) -> None:
|
||||
result = _resolve_prompt("no_such_file.txt", project_dir)
|
||||
assert result == "no_such_file.txt"
|
||||
|
||||
|
||||
class TestCollectHelpers:
|
||||
"""Test dependency collection helpers."""
|
||||
|
||||
|
|
@ -568,3 +552,47 @@ class TestDownloadTarget:
|
|||
assert "description.txt" in result.built
|
||||
assert (project_dir / "fish.png").read_bytes() == b"fake fish image"
|
||||
assert (project_dir / "description.txt").exists()
|
||||
|
||||
|
||||
class TestPlaceholderPrompts:
|
||||
"""Tests for prompt placeholder substitution in builds."""
|
||||
|
||||
async def test_placeholder_in_prompt_triggers_rebuild(
|
||||
self, project_dir: Path, write_config: WriteConfig
|
||||
) -> None:
|
||||
_ = (project_dir / "style.txt").write_text("impressionist")
|
||||
config = write_config(
|
||||
{
|
||||
"targets": {
|
||||
"out.txt": {"prompt": "Paint in {style.txt} style"},
|
||||
}
|
||||
}
|
||||
)
|
||||
with patch("hokusai.builder._create_providers", return_value=_fake_providers()):
|
||||
r1 = await run_build(config, project_dir, _PROJECT)
|
||||
assert r1.built == ["out.txt"]
|
||||
content1 = (project_dir / "out.txt").read_text()
|
||||
assert "impressionist" in content1
|
||||
|
||||
# Change the placeholder file
|
||||
_ = (project_dir / "style.txt").write_text("cubist")
|
||||
r2 = await run_build(config, project_dir, _PROJECT)
|
||||
assert r2.built == ["out.txt"]
|
||||
|
||||
async def test_placeholder_deps_in_collect_all(
|
||||
self, write_config: WriteConfig
|
||||
) -> None:
|
||||
config = write_config(
|
||||
{
|
||||
"targets": {
|
||||
"out.txt": {
|
||||
"prompt": "Use {a.txt} and {b.txt}",
|
||||
"inputs": ["c.txt"],
|
||||
},
|
||||
}
|
||||
}
|
||||
)
|
||||
deps = _collect_all_deps("out.txt", config)
|
||||
assert "a.txt" in deps
|
||||
assert "b.txt" in deps
|
||||
assert "c.txt" in deps
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue