google / google/adk-java

Feature Request: Run Cancellation / Abort Support for Java ADK

Offen
#1,341 2 Kommentare 0 Reaktionen 1 zugewiesene Person Beansprucht von @hemasekhar-p Auf GitHub ansehen
needs review
Vorherrschende Sprache
Java
Sterne
1.7k
Forks
420
Ø Merge
4 T. 12 Std.
Gemergte PRs (30 T.)
31

Beschreibung

## Summary

Java ADK currently lacks a mechanism to cancel/abort a running agent invocation. TypeScript ADK already ships mature `AbortSignal`-based cancellation ([docs/runtime/cancel.md](https://google.github.io/adk-docs/runtime/cancel/)), and Python ADK has active work in progress (google/adk-python#4825, google/adk-python#5983). **Java ADK has no equivalent — no API, no internal checkpoints, and no graceful shutdown path.**

## Motivation

Cancellation is essential for production agent deployments:

- **User-facing "Stop" button** — long-running multi-tool loops need immediate, graceful termination when the user clicks stop.
- **Timeout enforcement** — server-side request deadlines (e.g., HTTP gateway timeouts) must propagate into the agent execution.
- **Resource cleanup** — without cooperative cancellation, in-flight LLM streaming connections and tool executions leak resources.
- **Cost control** — aborting early avoids unnecessary LLM token consumption.

## Current State

| Language | Status | Mechanism |
|----------|--------|-----------|
| **TypeScript** | ✅ Shipped | `runner.runAsync(params, { signal })` with `AbortSignal`; checkpoints in LLM call, tool execution, and plugin callbacks; graceful generator completion (no throw) |
| **Python** | 🚧 In progress | google/adk-python#4825 (`stop_event: asyncio.Event`), google/adk-python#5983 (`/cancel` API + `task.cancel()`) |
| **Java** | ❌ Missing | Only `InvocationContext.endInvocation` (internal flag, not externally triggerable); `Disposable.dispose()` is a hard RxJava cut (not graceful, tools don't check it); no `RunConfig` timeout/cancel field |

## Proposed Design (aligned with TypeScript)

### API Surface

```java
// Option A: CancellationToken (similar to .NET / structured concurrency)
CancellationTokenSource cts = new CancellationTokenSource();
RunConfig config = RunConfig.builder()
.cancellationToken(cts.token())
.build();

Flowable events = runner.runAsync(userId, sessionId, content, config);
// Later:
cts.cancel(); // triggers graceful shutdown

// Option B: RxJava-native (Disposable already exists, but needs cooperative checks)
// Enhance internal checkpoints to check subscription disposal state
```

### Internal Checkpoints (minimum)

Following TypeScript's lead, cancellation should be checked at:

1. **Before each LLM call** — `BaseLlmFlow.runOneStep()` (already checks `endInvocation`, easy to extend)
2. **Before each tool execution** — `Functions.handleFunctionCalls()` (**currently has NO cancellation check**)
3. **During LLM streaming** — between chunks (for long generations)
4. **Plugin/callback boundaries** — `beforeModel` / `afterModel` / `beforeTool` / `afterTool`

### Semantics (align with TypeScript `cancel.md`)

- **Graceful**: the Flowable completes normally (no error signal), already-emitted events are preserved in the session.
- **Cooperative**: cancellation is checked at defined points; in-flight atomic operations (single LLM call, single tool run) may complete before the next checkpoint.
- **Idempotent**: calling cancel multiple times is safe.

## Questions for Maintainers

1. **API preference**: `CancellationToken` (explicit, testable) vs. leveraging RxJava `Disposable` semantics (less new API surface but less portable)?
2. **Scope**: Should cancellation also cover `runLive` (streaming/live mode), or start with `runAsync` only?
3. **Event emission on cancel**: Should the framework emit a final "cancelled" event (like Python's `temp:cancelled` state proposal), or just complete silently (like TypeScript)?

## References

- TypeScript ADK cancel docs: https://google.github.io/adk-docs/runtime/cancel/
- Python ADK cancellation PR: google/adk-python#4825
- Python ADK `/cancel` API PR: google/adk-python#5983
- Python ADK cancellation discussion: google/adk-python#4156

---

I'm happy to contribute the implementation once the API direction is agreed upon. I have production experience implementing cooperative cancellation in a Java ADK-based agent platform (checkpoint-based, with checks at beforeModel/beforeTool/afterEvent boundaries).

Beitragsleitfaden

Beitragsleitfaden öffnen

Bewertung

Dieses Issue wurde noch nicht bewertet.

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.