llm prompt -t filepath.yaml support, closes #897

This commit is contained in:
Simon Willison 2025-04-08 13:35:08 -07:00
parent bf622a27cc
commit 56d7f2f13a
3 changed files with 26 additions and 2 deletions

View file

@ -64,6 +64,10 @@ Templates can also be specified as full URLs to YAML files:
llm -t https://raw.githubusercontent.com/simonw/llm-templates/refs/heads/main/python-app.yaml \
'Python app to pick a random line from a file'
```
Or as a direct path to a YAML file on disk:
```bash
llm -t path/to/template.yaml 'extra prompt here'
```
(prompt-templates-list)=

View file

@ -3198,7 +3198,7 @@ def _parse_yaml_template(name, content):
def load_template(name: str) -> Template:
"Or raises LoadTemplateError(msg)"
"Load template, or raise LoadTemplateError(msg)"
if name.startswith("https://") or name.startswith("http://"):
response = httpx.get(name)
try:
@ -3218,7 +3218,13 @@ def load_template(name: str) -> Template:
except Exception as ex:
raise LoadTemplateError("Could not load template {}: {}".format(name, ex))
path = template_dir() / f"{name}.yaml"
# First try local file
potential_path = pathlib.Path(name)
if potential_path.exists():
path = potential_path
else:
# Look for in template_dir()
path = template_dir() / f"{name}.yaml"
if not path.exists():
raise LoadTemplateError(f"Invalid template: {name}")
content = path.read_text()

View file

@ -356,3 +356,17 @@ def test_execute_prompt_from_template_url(httpx_mock, template, expected):
)
assert result.exit_code == 0
assert result.output.strip() == expected.strip()
def test_execute_prompt_from_template_path():
runner = CliRunner()
with runner.isolated_filesystem() as temp_dir:
path = pathlib.Path(temp_dir) / "my-template.yaml"
path.write_text("system: system\nprompt: prompt", "utf-8")
result = runner.invoke(
cli,
["-t", str(path), "-m", "echo"],
catch_exceptions=False,
)
assert result.exit_code == 0
assert result.output.strip() == "system:\nsystem\n\nprompt:\nprompt"