[FEATURE] Port ReflectAndRetryToolPlugin from adk-python
Los mantenedores suelen responder en 1 día
@hemasekhar-p ya está trabajando en esto.
Desde el 3/8/2026.
Evaluación
Este issue todavía no se ha evaluado.
Descripción
Please make sure you read the contribution guide and file the issues in the right place.
Contribution guide.
🔴 Required Information
Is your feature request related to a specific problem?
When a tool fails, adk-java gives the model no way to learn what went wrong and try again. A tool
that reports its failure ends the invocation on the first attempt, even when the failure is one the
model could have corrected — malformed arguments, the wrong tool for the job, a precondition it
could have satisfied first.
adk-python ships a plugin for exactly this — ReflectAndRetryToolPlugin. adk-java
has no equivalent.
Describe the Solution You'd Like
ReflectAndRetryToolPlugin in com.google.adk.plugins.reflectandretry, registered on a Runner
like any other plugin, behaving as adk-python's does:
- intercept tool failures through the two hooks that already exist on
Plugin—
onToolErrorCallbackfor a tool that signals an error, andafterToolCallbackfor a result that
carries one; - track consecutive failures per tool within a scope, so a success with one tool resets that
tool's counter without forgiving another's; - substitute a structured reflection response — error type, error details, retry count, and guidance
telling the model to analyze the arguments and not repeat the identical call — for each failure up
tomaxRetries; - past the limit, either propagate the original error or return a final "stop using this tool"
message, per a constructor flag; - scope the counters per invocation (default) or globally, via a
TrackingScopeenum.
No existing class changes and no existing API changes: registration uses the plugin surfaces already
present.
Impact on your work
Applications wanting adk-python's behavior have to reimplement it in application code, where it
drifts from upstream. Not blocking and there is no timeline — this is a parity gap, not an outage.
Willingness to contribute
Yes. A PR follows immediately after this issue: one new public plugin class plus four small
supporting types in a plugins.reflectandretry subpackage, with tests. No existing file is
modified.
🟡 Recommended Information
Describe Alternatives You've Considered
Retry inside the tool itself. This is the obvious workaround and it is not the same thing. A
loop inside the tool repeats the identical call; the point of reflection is to hand the model the
error and its own arguments so it can call differently. A tool cannot fix arguments it did not
choose.
Implement the plugin in application code. It works — the behavior above was verified using
public API only. But it is per-application boilerplate for something the plugin surface exists to
ship once, and every copy drifts from upstream separately.
Widen onToolErrorCallback semantics instead. That would change existing behavior for every
plugin. A new opt-in plugin changes nothing for anyone who does not register it.
Proposed API / Implementation
Registration needs no new API:
Runner runner =
new InMemoryRunner(agent, "my-app", ImmutableList.of(new ReflectAndRetryToolPlugin(3)));
Both hooks are already declared on Plugin, and both already return the type the plugin needs —
Maybe<Map<String, Object>>, matching Python's Optional[dict[str, Any]]:
// Plugin.java:188
default Maybe<Map<String, Object>> afterToolCallback(
BaseTool tool, Map<String, Object> toolArgs, ToolContext toolContext, Map<String, Object> result)
// Plugin.java:206
default Maybe<Map<String, Object>> onToolErrorCallback(
BaseTool tool, Map<String, Object> toolArgs, ToolContext toolContext, Throwable error)
The class is written and tested; the PR carries it.
Additional Context
Observed on 1.7.1-SNAPSHOT, Windows 11 (not OS-specific).
- Lenguaje dominante
- Java
- Estrellas
- 1.7k
- Forks
- 421
- Merge medio
- 3 d 14 h
- PR fusionados (30 d)
- 31
Preparar el entorno
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de google/adk-java
-
Dificultad 4/5 3-5 días Aptitud para principiantes 68/100
Los mantenedores suelen responder en 1 día
-
Dificultad 3/5 1-2 días Aptitud para principiantes 72/100
Los mantenedores suelen responder en 1 día
-
Approved tool call re-runs on every later user turn if it never got a function responsePosiblemente ocupada @hemasekhar-p la tomó hace 2 días. Abiertoneeds review
google/adk-java#1556 · 1 comentario · 1 asignado ·
Los mantenedores suelen responder en 1 día
-
LocalSkillSource.listResources returns backslash-separated paths on WindowsPosiblemente ocupada @hemasekhar-p la tomó hace 3 días. Abiertoneeds review
google/adk-java#1541 · 1 comentario · 1 asignado ·
Los mantenedores suelen responder en 1 día
-
Context caching (ContextCacheConfig) is a silent no-op: config is plumbed to InvocationContext but never readPosiblemente ocupada @hemasekhar-p la tomó hace 4 días. Abiertoneeds review
Dificultad 5/5 Más de una semana Aptitud para principiantes 35/100
google/adk-java#1530 · 1 comentario · 1 asignado ·
Los mantenedores suelen responder en 1 día
Todos los issues de google/adk-java
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
OpenAPITools/openapi-generator#25014 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 92/100
AloisSeckar/demos-java#380 ·
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
openhab/openhab-core#5847 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
appsmithorg/appsmith#42297 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100