Substitute Prior Results into Tool Arguments
Problem Statement
In a tool plan, one call's arguments reference an earlier call's output via placeholders like $1.city. Resolve these placeholders against a results map before executing.
Background
A placeholder has the form <step>.<key>∗∗(e.g.∗∗1.city) or $<step> for the whole result. Given results mapping step id -> value (a dict or scalar), replace any argument whose value is a placeholder string with the looked-up value. Non-placeholder values pass through. A missing reference raises KeyError.
Your Task
Implement:
def resolve_refs(args, results):
- args: dict of name -> value (values may be placeholder strings).
- results: dict of int step -> result.
- Return a new args dict with placeholders resolved.
Input Format
- args (dict), results (dict of int -> value).
Output Format
- A dict.
Sample
print(resolve_refs({"q": "$1.city"}, {1: {"city": "Paris"}}))
Output:
{'q': 'Paris'}
Example:
print(resolve_refs({"q": "$1.city"}, {1: {"city": "Paris"}})){'q': 'Paris'}- Iterate through the input dictionary
args, identifying the single entry where the key is"q"and the value is the string"$1.city". - Parse the placeholder string to extract the step identifier and the specific key: the numeric part
1indicates step 1, and the suffixcityindicates the target field. - Look up step 1 in the
resultsmap, which yields the nested dictionary{"city": "Paris"}. - Access the
cityfield within that result, retrieving the scalar value"Paris", and assign it to the output dictionary under the original key"q". - The final output is
{'q': 'Paris'}
Constraints:
- A placeholder is a string starting with
$then digits, optionally.key. $nreturnsresults[n];$n.keyreturnsresults[n][key].- Non-placeholder values are returned unchanged; missing step/key raises KeyError.
1. Background Knowledge
This problem centers on placeholder resolution, a core mechanism in AI agent pipelines where multi-step tool calls depend on prior outputs. In a tool plan, step 2 might need the city extracted by step 1. Instead of hard-coding values, the plan uses symbolic references like $1.city that are resolved at execution time against a results map (a dictionary keyed by step ID).
The placeholder syntax follows a simple grammar: <step>∗∗referstotheentireresultofthatstep,while∗∗<step>.<key> drills into a nested dictionary. For example, if results is {"city": "Paris", "zip": "75001"}, then 1.city∗∗resolvesto∗∗"Paris"∗∗and∗∗1 resolves to the whole dict. This pattern mirrors variable substitution in shell scripting or template engines, but constrained to a two-level namespace (step ID and optional key).
A critical design decision is immutability: the function must return a new dictionary rather than mutating the input. This ensures the original plan remains intact for potential retries or logging, following the principle of pure functions in functional programming.
2. Algorithm Approach
The solution follows a map-and-lookup pattern:
- Iterate over each key-value pair in args.
- For each value, determine if it is a placeholder string (starts with $).
- If it is a placeholder, parse the step ID and optional key, then perform a dictionary lookup in results.
- If the lookup succeeds, substitute the resolved value; if it fails, raise KeyError.
- If the value is not a placeholder, pass it through unchanged.
- Collect all resolved pairs into a new dictionary and return it.
This is a single-pass, linear-time transformation with no recursion or sorting required.
3. Step-by-Step Strategy
- Detect placeholders: Check if the value is a string and starts with $. Non-string values (ints, lists, etc.) pass through directly.
- Parse the reference: Strip the leading $, then split on the first . to separate the step ID from the optional key.
- If no . is present, the reference is to the whole result: results[step_id].
- If a . is present, the reference is to a nested key: results[step_id][key].
- Convert step ID: The step ID in the placeholder is a string (e.g., "1"), but results is keyed by int. Convert using int().
- Perform lookup: Access results[step_id]. If the key is missing, Python naturally raises KeyError, which satisfies the requirement.
- Handle nested keys: If a key was parsed, access result[key]. Again, a missing key raises KeyError.
- Build new dict: Use a dictionary comprehension or a loop to construct the output dict, ensuring the original args is not modified.
Continue the full explanation
You're reading the free preview. Unlock the complete walkthrough, the code editor, test runner and reference solution with Premium.
Editor locked
The code editor is locked for Pro problems. It is only available for free problems. Please upgrade to gain access to the code editor for all problems.