Repository navigation
feat: add RunConfig.dollarEscapedPlaceholders to leave escaped placeholders in instructions as written - #1569
Conversation
|
Hi @Laurianti, Thank you for your contribution and for taking the time to submit this pull request. Our team is currently reviewing your changes and we will reach out if we need any further information. Thank you. |
|
Thanks for the port and the clear write-up. We cannot take this as-is on 1.x. adk-java 1.x does not ship behavior changes, and this changes the output of templates that work today:
None of these throw an error, so callers only notice when values stop reaching the model. adk-python made this change in 2.10.0 and listed it under behavior changes. For Java, we want this opt-in on 1.x, default in 2.0. If you need this change, could you rework the PR to put the new parsing behind a flag? Here is what we need:
NOTE: The listed changes might not be the only changes needed to make it work. If you decide to follow-up, make sure the impact of your change is fully covered. |
fd023bd to
4cb1a5e
Compare
|
Thanks for the table and the precise list. Reworked in 9928b62, still one commit:
On impact: |
4cb1a5e to
9928b62
Compare
dosadczuk
left a comment
There was a problem hiding this comment.
Hi! With this change we need to be very careful, because it can negatively affect multiple users of the library.
Could you consider moving the preserveEscapePlaceholders flag into RunConfig? I'd like to see pros and cons of the change, because it seems like current solution has some negative side effects, e.g. root agent can set different flag value than specific agent. Also, let's find better name for the flag.
Let's discuss the solution, then we'll follow up with the changes.
|
Thanks, agreed. Here is how moving it to
I don't see a case where one agent of a run needs today's substitution and another the adk-python rule, so one value per run seems the better fit. It also matches how For the name, I'd suggest |
|
Thanks! Let's try |
9928b62 to
81c5ed7
Compare
|
Done: the flag is now |
dosadczuk
left a comment
There was a problem hiding this comment.
Thanks for the update. The new pattern matches adk-python's, and the default output is unchanged. Two things are still missing:
1. tokt drops the flag without an error.
KotlinAdkToJava.asJavaRunner converts the caller's RunConfig with RunConfigCodec.fromJava (tokt/src/main/kotlin/com/google/adk/tokt/codecs/RunConfigCodec.kt). That method rejects each Java setting the Kotlin engine cannot honor, but it does not check the new flag. The Kotlin engine cannot honor the flag, so add it to the unsupported list:
if (config.dollarEscapedPlaceholders()) add("dollarEscapedPlaceholders")Then add a test that expects an IllegalArgumentException naming dollarEscapedPlaceholders.
2. The Instruction Javadoc no longer describes the rule.
Your previous revision added it to the templating paragraph in core/src/main/java/com/google/adk/agents/Instruction.java; this revision dropped it. Please add it back, pointing at the new flag.
…olders in instructions as written
81c5ed7 to
72b4af8
Compare
|
Thanks, both done in 72b4af8:
The description is updated. |
Link to Issue or Description of Change
2. Or, if no issue exists, describe the change:
Ports the adk-python templating rule of google/adk-python@0caecd2 (google/adk-python#5706) as an opt-in: adk-python made it the default in 2.10.0 and listed it under behavior changes, while adk-java 1.x keeps today's output unless a run opts in.
Problem:
InstructionUtils.injectSessionStateresolves a placeholder right after$or\like any other and keeps the character in front, so instructions that show a template syntax cannot reach the model as written:The formatString supports interpolation via ${expression} syntax.IllegalArgumentException: Context variable not foundWorkflow syntax: ${{expression}}(expression= foo)Workflow syntax: $fooPrice: ${price}(price= 9.99)Price: $9.99A ${var?} B(varmissing)A $ B\{user_name}(user_name= Foo)\FooSolution:
RunConfig.dollarEscapedPlaceholders(), defaultfalse, lets a run opt into the adk-python rule: a placeholder right after$or\is left as written, backslash included, so each template above reaches the model unchanged. Other placeholders, including{{key}}and optional ones, resolve as before.RunConfig: thedollarEscapedPlaceholdersproperty, set tofalsebybuilder()and copied bybuilder(RunConfig).InstructionUtils.injectSessionState: selects the adk-python pattern whencontext.runConfig().dollarEscapedPlaceholders()istrue; the current pattern stays the default, also whenrunConfig()is null. The rule is documented in its Placeholder Syntax section and in the templating paragraph ofInstruction.RunConfigCodec.fromJava(tokt): the Kotlin engine cannot honor the flag, so aRunConfigwith it set is rejected with anIllegalArgumentExceptionnamingdollarEscapedPlaceholders, like the other unsupported settings.Every templated instruction goes through
injectSessionState, so the flag applies to agent instructions, global instructions andGlobalInstructionPlugin. AnInstruction.Provideris not templated, so the flag does not affect it.Testing Plan
Unit Tests:
I have added or updated unit tests for my change.
All unit tests pass locally.
InstructionUtilsTest: the four adk-python cases with the flag on, the escaped case as\{user_name}with state set, plusPrice: ${price},A ${var?} B,\{{user_name}}, and unescaped{key},{{key}}and{key?}still resolving with the flag on. With the defaultRunConfig, today's output is pinned:${expression}throws,${{expression}}renders$foo,Price: ${price}renders$9.99,A ${var?} BrendersA $ B,\{user_name}renders\Foo.InstructionsTest: agent instruction with the flag on and with the default; global and sub-agent instructions with the flag on; a provider instruction left untouched.GlobalInstructionPluginTest: the plugin with the flag on; the existing tests, whose mocked context returns a nullrunConfig(), keep today's output.RunConfigTest: the default, and the flag kept bybuilder(RunConfig)andtoBuilder().KtRunnerInteropTest:RunConfigCodec.fromJavawith the flag on throws anIllegalArgumentExceptionnamingdollarEscapedPlaceholders.Each production change fails at least one of these tests when reverted on its own.
mvn -pl core,tokt -am test: core 2477 tests, 0 failures, 0 errors, 28 skipped; tokt 107 tests, 0 failures, 0 errors, 1 skipped.Manual End-to-End (E2E) Tests:
Covered by the
InstructionsTestcases above, which check the system instruction built for the model request.Checklist