google / google/adk-java

Hard-coded `new InMemoryRunner(...)` prevents injection and custom runner implementations

オープン
#642 コメント 6 件 リアクション 5 件 担当者 1 名 @hemasekhar-p が担当を希望しています GitHub で見る
needs review
主要言語
Java
スター
1.7k
フォーク
420
平均マージ
4日 12時間
マージ済み PR(30日)
31

説明

In the current implementation of `AgentTool.runAsync(...)`, the runner instance is created directly via constructor:

```java
Runner runner = new InMemoryRunner(this.agent, toolContext.agentName());
```

This introduces a structural limitation:
the code forces a specific runner implementation and does not allow the caller to provide their own `Runner` or override behaviour.

### Why this is problematic

1. **No ability to inject alternative Runner implementations**
Any attempt to replace `InMemoryRunner` (e.g., with a distributed runner, persistent runner, mocked test runner, or custom lifecycle-managed runner) becomes impossible. The hard-coded `new` eliminates extensibility.

2. **Loss of execution context**
The runner manages sessions and state. By creating it directly inside the tool, the execution context may diverge from the tool context, especially when session/state lifecycles are coordinated elsewhere in the system.
This can lead to unexpected state resets or inconsistent flow.

3. **Unexpected or non-deterministic behaviour**
When tooling relies on a specific execution model, but the tool enforces `InMemoryRunner`, callers may get results that differ from their expected environment (e.g., summarization rules, session persistence, or event pipelines).

4. **Violation of dependency-injection principles**
The tool is not inversion-of-control–friendly, which makes it harder to integrate into larger orchestrators or frameworks.

### Proposed solution

Two possible fixes:

#### **A. Inject runner instance externally**

E.g. pass `Runner` via constructor or provide a `RunnerFactory`:

```java
public AgentTool(BaseAgent agent, boolean skipSummarization, RunnerFactory factory) {
this.runnerFactory = factory;
}
```

This keeps the tool composable, testable, and compatible with custom infrastructures.

#### **B. If only a single atomic action is required, avoid the full Runner and call the LLM directly**

If the intention is to execute a one-off LLM request without full agent orchestration, then using a full `Runner` is unnecessary overhead.

A direct LLM call would be more predictable, cheaper, and avoids unwanted runner logic (session creation, events, summarization pipelines, etc.).

---

### Please review

If the current implementation has hidden assumptions requiring `InMemoryRunner` specifically, or if there are constraints that justify not injecting it, then please adjust this issue accordingly. Otherwise, replacing the direct constructor call with a proper injection mechanism will make the system more modular and avoid context inconsistencies in the future.

コントリビューションガイド

コントリビューションガイドを開く

評価

この issue はまだ評価されていません。

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。