google / google/adk-java

[FEATURE] Port ReflectAndRetryToolPlugin from adk-python

Aperta
#1,390 1 commento 0 reazioni 1 assegnatario Rivendicata da @hemasekhar-p Vedi su GitHub
needs review
Lingua principale
Java
Stelle
1.7k
Fork
420
Merge medio
4g 12h
PR unite (30g)
31

Descrizione

**Please make sure you read the contribution guide and file the issues in the right place.**
[Contribution guide.](https://google.github.io/adk-docs/contributing-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` —
`onToolErrorCallback` for a tool that signals an error, and `afterToolCallback` for 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
to `maxRetries`;
- 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 `TrackingScope` enum.

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:

```java
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>`, matching Python's `Optional[dict[str, Any]]`:

```java
// Plugin.java:188
default Maybe> afterToolCallback(
BaseTool tool, Map toolArgs, ToolContext toolContext, Map result)

// Plugin.java:206
default Maybe> onToolErrorCallback(
BaseTool tool, Map 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).

Guida per i contributori

Apri la guida per i contributori

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.