Describe the bug
The schema allows a ContributeElement to be dict[str, ContributeValue], documented as
"Contribution of a specific value instead of the default one", and ContributeTarget includes
context. But contributing a specific value to the built-in context target fails at runtime:
text:
- def: STEP
text: "FULL-RESULT-BODY"
contribute:
- result
- context:
value: "TINY-SUMMARY"
- "end"
PDLRuntimeError: Error during the evaluation of ${ context }: 'context' is undefined
The failure occurs during contribution processing itself — no downstream consumer of the context is
involved. The equivalent named-aggregator form (an aggregator: declared in defs, as in
examples/aggregators/contribute_in_file.pdl) works correctly.
Root cause (from reading the interpreter)
In process_contribution, the plain-string cases result / context return early, but the
dict() case has no special-casing for the built-in targets: after evaluating the value it falls
through to get_contribute_aggregator(block, target, scope, loc), whose str() branch does
get_var(target, scope, loc) and requires the result to be an Aggregator. context is not a
scope variable, so the lookup raises; if a variable named context did exist, it would then fail
"An aggregator was expected". The same applies to result as a dict target.
process_contribution (main @ 045f052):
|
def process_contribution( |
get_contribute_aggregator (main @ 045f052):
|
def get_contribute_aggregator( |
Expected behavior
contribute: [result, {context: {value: <expr>}}] contributes the evaluated value to the
background context in place of the block's result — the "small summary to context, full result
returned" pattern the schema description implies — mirroring how the plain context target and the
named-aggregator dict form already behave.
Versions / reproduction
Why it matters
This is the language's only mechanism for contributing a compressed representation to the
accumulated context while returning the full result — the natural tool for large-payload pipelines.
As it stands, the schema advertises the capability and the interpreter cannot execute it.
Describe the bug
The schema allows a
ContributeElementto bedict[str, ContributeValue], documented as"Contribution of a specific value instead of the default one", and
ContributeTargetincludescontext. But contributing a specific value to the built-incontexttarget fails at runtime:The failure occurs during contribution processing itself — no downstream consumer of the context is
involved. The equivalent named-aggregator form (an
aggregator:declared indefs, as inexamples/aggregators/contribute_in_file.pdl) works correctly.Root cause (from reading the interpreter)
In
process_contribution, the plain-string casesresult/contextreturn early, but thedict()case has no special-casing for the built-in targets: after evaluating the value it fallsthrough to
get_contribute_aggregator(block, target, scope, loc), whosestr()branch doesget_var(target, scope, loc)and requires the result to be anAggregator.contextis not ascope variable, so the lookup raises; if a variable named
contextdid exist, it would then fail"An aggregator was expected". The same applies to
resultas a dict target.process_contribution(main @ 045f052):prompt-declaration-language/src/pdl/pdl_interpreter.py
Line 1637 in 045f052
get_contribute_aggregator(main @ 045f052):prompt-declaration-language/src/pdl/pdl_interpreter.py
Line 2803 in 045f052
Expected behavior
contribute: [result, {context: {value: <expr>}}]contributes the evaluated value to thebackground context in place of the block's result — the "small summary to context, full result
returned" pattern the schema description implies — mirroring how the plain
contexttarget and thenamed-aggregator dict form already behave.
Versions / reproduction
prompt-declaration-language0.9.3 (latest PyPI release) and on currentmain(045f052 — the dict path is unchanged by refactor: better separate leaf and structured blocks #1669).
parameters: {mock_response: ...}on a model block.mention this defect; fix: contribute directly a value to the context #991 fixed the wrapping of successfully contributed values, not the
dict-target routing.
Why it matters
This is the language's only mechanism for contributing a compressed representation to the
accumulated context while returning the full result — the natural tool for large-payload pipelines.
As it stands, the schema advertises the capability and the interpreter cannot execute it.