Skip to content

feat(api_server): expose session rewind as a REST endpoint - #7178

Open
chelsealong wants to merge 1 commit into
google:mainfrom
chelsealong:fix-7177-rewind-session-api-endpoint
Open

chelsealong wants to merge 1 commit into
google:mainfrom
chelsealong:fix-7177-rewind-session-api-endpoint

Conversation

@chelsealong

Copy link
Copy Markdown
Contributor

Please ensure you have read the contribution guide before creating a pull request.

Link to Issue or Description of Change

1. Link to an existing issue (if applicable):

Problem:
Runner.rewind_async already implements rewinding a session to before a
given invocation (added in a recent refactor of sessions/_rewind_utils.py),
but no HTTP endpoint exposed it. The issue reports that adk api_server
deployments have no clean way to abort a generation and rewind the session
to the previous state, even though the underlying capability already exists
in the Runner.

Solution:
Add a POST /apps/{app_name}/users/{user_id}/sessions/{session_id}/rewind
endpoint to api_server.py, following the exact conventions already used by
the neighboring get_session / create_session / delete_session /
update_session endpoints in that file (this is also inherited by the dev
server behind adk web, since DevServer extends ApiServer). The request
body carries rewind_before_invocation_id (the same parameter name
Runner.rewind_async already uses, and the exact name the issue itself
suggested), and the endpoint returns the rewound Session. A ValueError
(including SessionNotFoundError, which subclasses it) raised by
rewind_async — e.g. an unknown invocation ID or missing session — is
mapped to an HTTP 404, matching the error-handling pattern used by the
other session endpoints in this file.

Testing Plan

Unit Tests:

  • I have added or updated unit tests for my change.
  • All unit tests pass locally.

Added test_rewind_session (verifies the endpoint calls
Runner.rewind_async with the right user_id/session_id/
rewind_before_invocation_id and returns the session) and
test_rewind_session_invocation_not_found (verifies a ValueError from
rewind_async becomes an HTTP 404) to
tests/unittests/cli/test_fast_api.py.

Confirmed both new tests fail without the fix (git checkout HEAD~1 -- src/google/adk/cli/api_server.py, rerun): both get a plain FastAPI 404
Not Found because the route doesn't exist yet:

FAILED tests/unittests/cli/test_fast_api.py::test_rewind_session - assert 404 == 200
FAILED tests/unittests/cli/test_fast_api.py::test_rewind_session_invocation_not_found - AssertionError: assert 'missing-invocation-id' in 'Not Found'
2 failed, 132 deselected, 1 warning in 2.69s

With the fix restored, the full file passes:

$ python -m pytest tests/unittests/cli/test_fast_api.py -q
128 passed, 5 skipped, 1 xfailed, 12 warnings in 24.97s

Also ran the existing rewind-focused suites to confirm no regressions in
the underlying rewind logic:

$ python -m pytest tests/unittests/runners/test_runner_rewind.py tests/unittests/sessions/test_rewind_utils.py -q
10 passed in 0.99s

Lint/format (isort, pyink) pass clean on both changed files. ruff check reports one pre-existing unrelated finding (sys imported but
unused) in tests/unittests/cli/test_fast_api.py that already exists on
unmodified main.

Manual End-to-End (E2E) Tests:

Not performed beyond the unit tests above (no live LLM/agent environment
available in this session); the endpoint is a thin wrapper around the
already-tested Runner.rewind_async/_rewind_utils.rewind_session path.

Checklist

  • I have read the CONTRIBUTING.md document.
  • I have performed a self-review of my own code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have added tests that prove my fix is effective or that my feature works.
  • New and existing unit tests pass locally with my changes.
  • I have manually tested my changes end-to-end.
  • Any dependent changes have been merged and published in downstream modules.

Additional context

This PR was developed with AI assistance (Claude Code), including reading
the existing api_server.py conventions, writing the endpoint/tests, and
running the verification steps described above; all changes were reviewed
before being pushed.

Runner.rewind_async already implements rewinding a session to before a
given invocation, but no HTTP endpoint exposed it in either the
production api server or the dev server used by `adk web`. Add a POST
/apps/{app_name}/users/{user_id}/sessions/{session_id}/rewind endpoint
to api_server.py (inherited by the dev server) so `adk api_server`
deployments can rewind a session, following the existing session
endpoint conventions in that file.

Fixes google#7177
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make rewind session upon cancellation accessible via API server

1 participant