AdkApp.async_stream_query(session_events=...) creates a managed session per call and never deletes it
I maintainer di solito rispondono entro 5 giorni
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 3/5
- Tempo stimato
- 1-2 giorni
- Idoneità per principianti
- 74/100
Direzione di ricerca
Inizia in vertexai/agent_engines/templates/adk.py, in async_stream_query, quindi confronta il suo ramo session_events con il percorso gemello _StreamRunRequest intorno a adk.py:1364. Riproduci il problema con session_events=[] su un engine distribuito ed elenca le sessioni in seguito. Il lavoro è completato quando la sessione temporanea non viene resa persistente come sessione gestita e viene ripulita dopo lo streaming.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Summary
Every async_stream_query(session_events=...) call against a deployed Agent Engine creates a persisted Vertex session, appends the caller's supplied transcript to it, and abandons it. The session id is never returned to the caller, so it cannot be deleted, and it persists until TTL — 365 days by default.
This is independent of #7118. That issue is about session_events raising an AttributeError; this is about the session created before the raise. The fix suggested in #7118 does not address it, so applying that fix alone changes the behaviour from "leaks a session and fails" to "leaks a session and succeeds".
Environment
google-cloud-aiplatform1.163.0 and 2.0.1 (read from 1.162.0 in the wheel cache; #7118 confirms the same code atadk.py:1182in 1.163.0 andadk.py:1229in 2.0.1)google-adk2.6.3- Deployed Agent Engine,
europe-west1
Cause
In vertexai/agent_engines/templates/adk.py, async_stream_query:
if not session_id:
session = await self.async_create_session(user_id=user_id) # persisted session
session_id = session["id"]
if session_events is not None:
session_service = self._tmpl_attrs.get("session_service") # VertexAiSessionService when deployed
for event in session_events:
await session_service.append_event(session=session, event=event)
The generator's finally calls only _force_flush_otel. There is no delete_session.
Three things make it unrecoverable for the caller:
- The id is never surfaced. It is bound to a local and not yielded.
google/adk/events/event.pydefines nosession_idfield, so nothing in the response stream carries it either. - It accumulates per turn, not per conversation.
session_eventsexists for callers that hold their own history and replay it, so an N-turn conversation leaves N sessions, each holding a longer prefix of the same transcript. - No retention control reaches it.
ttlandexpire_timecannot be passed throughasync_stream_query, so every one of them gets the 365-day default.
Reproduction
Against a deployed engine:
async for event in remote_app.async_stream_query(
message="hello", user_id="u", session_events=[]
):
print(event)
session_events=[] is deliberate: the loop body never runs, so there is no exception and none of #7118 is involved. Then list sessions on the engine — one new session per call, none of them reachable from the code that made them.
Impact
The main use for session_events is a caller that owns the transcript and does not want a server-side copy of user-supplied conversation content. As implemented, a server-side copy is created anyway, in a resource the caller cannot address, delete, or set a retention policy on. For anything handling personal data, that turns an opt-out into an undeletable copy with the longest available lifetime.
Suggested fix
The sibling _StreamRunRequest path already does the right thing: when no session_id is supplied it uses in_memory_session_service and deletes the session in a finally (around adk.py:1364). Routing the session_events branch the same way fits — the session is throwaway by construction, so it does not need to be managed. It also removes the per-event round trips noted in #7118's second follow-up point, since in-memory appends are local.
Related observation
The async_create_session call sits above the session_events check, so any async_stream_query call without a session_id creates a managed session that is never deleted and whose id is never returned. That broader case may be intended — the docstring says a new session will be created — but the id not being returned makes it unusable as a resumable session either way. Filing this scoped to session_events, where there is a clear expectation of no server-side copy.
- Lingua principale
- Python
- Stelle
- 907
- Fork
- 467
- Merge medio
- 1g 11h
- PR unite (30g)
- 35
Preparare l'ambiente
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di googleapis/python-aiplatform
-
Protobuf 7.35.1+ supportApertaapi: vertex-ai
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 85/100
googleapis/python-aiplatform#7132 ·
I maintainer di solito rispondono entro 5 giorni
-
api: vertex-ai
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
googleapis/python-aiplatform#7097 ·
I maintainer di solito rispondono entro 5 giorni
-
CustomContainerTrainingJob.run drops max_wait_duration=0 instead of requesting indefinite DWS waitApertaapi: vertex-ai
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
googleapis/python-aiplatform#7067 · 1 commento ·
I maintainer di solito rispondono entro 5 giorni
-
api: vertex-ai
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
googleapis/python-aiplatform#6877 ·
I maintainer di solito rispondono entro 5 giorni
-
api: vertex-ai
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
googleapis/python-aiplatform#6865 · 1 commento ·
I maintainer di solito rispondono entro 5 giorni
Tutte le issue di googleapis/python-aiplatform
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
PedestrianDynamics/pyFDS-Evac#199 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
521xueweihan/HelloGitHub#3790 ·
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
sandialabs/atlas-ui-3#978 ·
I maintainer di solito rispondono entro 1 giorno
-
area: tests perceived difficulty: 2
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
Nitjsefnie-Harness-Commons/daedalus#1255 ·
I maintainer di solito rispondono entro 1 giorno
-
hf-audiolm-qwen: `generate_until` hardcodes `.to("cuda")` and aborts on non-CUDA acceleratorsAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 86/100
EleutherAI/lm-evaluation-harness#4256 ·
I maintainer di solito rispondono entro 1 giorno