Skip to content

fix(python): fill omitted template variables from prompt input.default - #601

Open
huangjeff5 wants to merge 5 commits into
google:mainfrom
huangjeff5:dotprompt-py-v3-1-model-defaults
Open

fix(python): fill omitted template variables from prompt input.default#601
huangjeff5 wants to merge 5 commits into
google:mainfrom
huangjeff5:dotprompt-py-v3-1-model-defaults

Conversation

@huangjeff5

@huangjeff5 huangjeff5 commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

input.default in a .prompt file fills any template key the caller left out. Call defaults overlay the file. Runtime input wins that key. render and compile take a DataArgument, not a plain dict. Model and config layers compose: instance default, then the file, then compile metadata, then the call.

from dotpromptz import Dotprompt
from dotpromptz.typing import DataArgument, PromptInputConfig, PromptMetadata

source = """---
model: gemini-2.5-flash
input:
  default:
    name: World
---
Hello, {{name}}!"""

await Dotprompt().render(source, DataArgument(input={}))
# model gemini-2.5-flash, text 'Hello, World!'

await Dotprompt().render(source, DataArgument(input={'name': 'Ada'}))
# 'Hello, Ada!'

await Dotprompt().render(
    """---
input:
  default:
    first: Ada
    last: Lovelace
---
{{first}} {{last}}""",
    DataArgument(input={'first': 'Grace'}),
)
# 'Grace Lovelace'

await Dotprompt().render(source, {'input': {'name': 'Ada'}})
# TypeError: data must be a DataArgument

Decisions

  • DataArgument() and DataArgument(input={}) are both “no keys supplied.” File defaults fill.
  • A key the caller did set, including None / False / 0 / '', replaces the default. Nested objects replace; they do not deep-merge.
  • Call PromptMetadata(input=PromptInputConfig(default=…)) overlays the file for those keys. Compile metadata overlays the file; the call overlays compile; runtime input is last.
  • The returned prompt config still carries the merged input.default map. That is the same overlay the template used.
  • render and compile require DataArgument. A mapping is TypeError.
  • Model: instance default_model, then file model:, then compile metadata, then the call. An empty string means absent, not a model named "".
  • Config: the selected model’s model_configs entry, then file config:, then compile, then the call. Later keys overlay.
  • YAML model: is kept on the parsed prompt.

@huangjeff5 huangjeff5 changed the title fix(python): accept mapping prompt data without dropping defaults fix(python): preserve prompt model and input defaults Sep 3, 2026
@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Sep 3, 2026
What the aggressive test pass found and fixed:
- instance default_model selected config but disappeared from RenderedPrompt.model
- compile/call input metadata replaced prompt defaults and schema instead of overlaying
- compile metadata used unvalidated model_copy updates
- empty model strings could leave model/config inconsistent
- plain dict misuse raised an accidental AttributeError instead of a clear TypeError

Settled precedence:
- defaults: prompt < compile metadata < call metadata < runtime DataArgument.input
- model: instance default < prompt < compile metadata < call metadata
- config: selected model config < prompt < compile metadata < call metadata
- schemas persist through default-only overlays and change only when a later schema is explicit

The 24 new product cells cover absent/partial/falsy/shallow runtime input, all four defaults layers, schema preservation/replacement, renderer reuse and caller retention, every model layer, empty models, config composition, and DataArgument enforcement.

Verification:
- all five reviewers approved after three rounds
- 59 focused tests passed
- full Python suite: 506 passed, 95% coverage
- changed-file Ruff checks and formatting passed
- full-repo Ruff/Pyrefly still report only the known pre-existing findings
- patch reapplies cleanly to ceb4fc5 and reproduces the exact reviewed tree
@huangjeff5
huangjeff5 requested a review from pavelgj September 9, 2026 22:22
File and compile input.default stay on the returned prompt config.
Only this call's options.input.default plus DataArgument.input fill {{name}}.
@huangjeff5 huangjeff5 changed the title fix(python): preserve prompt model and input defaults fix(python): keep prompt input defaults off template variables Sep 10, 2026
input.default in a .prompt file fills any template key the caller left out.
Runtime input wins that key.
@huangjeff5 huangjeff5 changed the title fix(python): keep prompt input defaults off template variables fix(python): fill omitted template variables from prompt input.default Sep 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation dotpromptz python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants