-
Notifications
You must be signed in to change notification settings - Fork 2.4k
feat(utils): Add support for nested state access in template injection #3664
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat(utils): Add support for nested state access in template injection #3664
Conversation
Resolves google#575 Previously, inject_session_state only supported flat state access, preventing users from accessing nested properties in state objects. This limited the ability to work with complex, hierarchical state structures. This change adds support for: - Nested dict/object access using dot notation: {user.profile.role} - Optional chaining with ? operator: {user?.profile?.role?} - Deep nesting and mixed dict/object access - Compatible with existing prefixed state (app:, user:, temp:) Example usage: async def build_instruction(readonly_context: ReadonlyContext) -> str: template = ( "Current user is {user?.name} and {user?.profile?.role}. " "Please greet them by name and designation." ) return await inject_session_state(template, readonly_context) # With state: state = { "user": { "name": "John", "profile": {"role": "Software Engineer", "age": 30} } } # Result: "Current user is John and Software Engineer. # Please greet them by name and designation." # Missing fields with optional chaining return empty strings # instead of raising errors. Includes comprehensive test coverage with 12 new test cases covering nested access, optional chaining, error handling, and edge cases.
Summary of ChangesHello @Jainish-S, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances the Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request introduces a valuable feature for accessing nested state variables in instruction templates, including support for optional chaining. The implementation is mostly solid, with a new _get_nested_value helper function that correctly handles nested access for both dictionaries and objects. The test coverage is extensive and covers many scenarios for the new feature. However, I've identified a high-severity issue in the error handling logic within inject_session_state that could lead to incorrect behavior by silently ignoring missing required variables. My review includes a specific comment with a suggested fix for this issue.
|
Response from ADK Triaging Agent Hello @Jainish-S, thank you for your contribution! Before we can merge this PR, we need you to sign the Contributor License Agreement (CLA). The CLA check is currently failing. You can review and sign the agreement here: https://cla.developers.google.com/ Once the CLA is signed, we can proceed with the review. Thanks! |
The previous implementation incorrectly treated entire paths as optional
if any segment contained '?', violating per-segment optional chaining
semantics. For example, {user.profile?} with missing 'user' would
incorrectly return empty string instead of raising an error.
Root cause: The catch block checked 'if '?' in full_path' to decide
whether to suppress KeyError. This was wrong because _get_nested_value()
already handles optional segments correctly by returning None for
missing optional parts. Any KeyError that propagates means a required
segment was missing and should be fatal.
Fix: Removed the conditional suppression logic. Now all KeyErrors from
_get_nested_value() are properly re-raised, maintaining correct
per-segment optional chaining semantics.
Examples:
- {user?.profile} with user missing → empty string (correct: user? is optional)
- {user.profile?} with user missing → KeyError (correct: user is required)
- {user?.profile?.role} with user missing → empty string (correct: chain stops at user?)
Added test case to verify required parent with optional child raises error.
0feec27 to
da4c9a7
Compare
1. Link to an existing issue (if applicable):
2. Or, if no issue exists, describe the change:
Problem:
Previously,
inject_session_state()only supported flat state access (e.g.,{user_name}), preventing users from accessing nested properties within state objects. This limitation forced developers to either flatten their state structure or manually handle template replacement, reducing code readability and flexibility when working with complex, hierarchical state structures.Solution:
Added support for nested state access in template injection using dot notation with optional chaining. The implementation adds a
_get_nested_value()helper function that:__getitem__) and attribute access (getattr)?operator for safe navigationKeyErrorfor missing required pathsThis solution was chosen because it:
Testing Plan
Unit Tests:
Summary of pytest results:
Added 12 comprehensive test cases covering:
Manual End-to-End (E2E) Tests: Created a sample agent to demonstrate the feature (located at
contributing/samples/nested_state_agent/, not included in this PR). Setup:Agent code:
Expected behavior:
Actual output:
✅ Result: Nested state values correctly injected into instruction template
Checklist
Additional context
Note: This PR re-implements the solution for issue #575. A previous implementation existed but was not merged due to merge conflicts. This is a fresh implementation with the same functionality. Feature highlights:
Files changed:
Key improvements made: