Conversation
|
Response from ADK Triaging Agent Hello @ScottMansfield, thank you for creating this PR! I see that this is a draft PR. When you are ready, please ensure you have read the contribution guide and filled out the PR template, including:
This information will help reviewers to review your PR more efficiently. Thanks! |
e3f5d6a to
49c7bf5
Compare
|
Looks like we have one open for the community repo: google/adk-python-community#104 |
|
Hi @ScottMansfield , Thank you for your contribution! We appreciate you taking the time to submit this pull request. |
|
Hi @ScottMansfield , is this PR still in draft? If not can you please fill in the details for the PR. |
These updates are derived from @anmolg1997 PR on the community repo: google/adk-python-community#104
|
I believe this is ready for review but I'm testing it with a real firestore instance |
This creates a new memories collection to hold indexed events.
|
|
||
| from __future__ import annotations | ||
|
|
||
| DEFAULT_STOP_WORDS = { |
There was a problem hiding this comment.
Is this something specific to the firestore implementation? Should this be something we apply to all memory service?
| """Session service that uses Google Cloud Firestore as the backend. | ||
|
|
||
| It creates a hierarchy in Firestore to hold events by user and session: | ||
| adk-session |
|
|
||
|
|
||
| @pytest.mark.asyncio | ||
| async def test_list_sessions_with_user_id(mock_firestore_client): |
There was a problem hiding this comment.
Add a test that there are multiple apps, and only specific app is fetched?
| if event.partial: | ||
| return event | ||
|
|
||
| self._apply_temp_state(session, event) |
There was a problem hiding this comment.
Also a test covering this?
| self._search_by_keyword(app_name, user_id, keyword) | ||
| for keyword in keywords | ||
| ] | ||
| results = await asyncio.gather(*tasks) |
There was a problem hiding this comment.
Add a test to verify that failures in parallel tasks are handled
| else: | ||
| session_updates[key] = value | ||
|
|
||
| if app_updates: |
There was a problem hiding this comment.
The current append_event implementation updates App, User, and Session states across multiple independent transactions and batches. This lacks atomicity; if the final batch.commit() fails after the state transactions have finished, the storage layers will become desynchronized. Please wrap all related state and event updates into a single Firestore transaction to ensure consistency.
| has_updates = True | ||
|
|
||
| if has_updates: | ||
| await batch.commit() |
There was a problem hiding this comment.
This adds all session events to a single write batch without checking size. This will crash if a session exceeds Firestore's 500-operation limit. Please implement a batch-splitting mechanism similar to the 500-count logic already used in delete_session
Adding support for Firestore for both session and memory storage.
This started by copying the Firestore support from the Java ADK into the Python ADK and also takes inspiration from @anmolg1997's PR google/adk-python-community#104. It does things differently from both.
Firestore contains a hierarchical set of data for sessions:
The firestore memory service creates a top-level collection that hold indexed memories when sessions are added.
Link to Issue or Description of Change
This is from an existing customer request for firestore support.
Testing Plan
Unit Tests:
Manual End-to-End (E2E) Tests:
I created a demo app locally to test the session and memory storage with a real firebase instance. It successfully records sessions and memories, verified by manually checking the cloud console.
Memory did require an index, which will be created by the user the first time the memory session is used. Firestore has a specific deep link that it will create to give the exact index needed. After that, memory worked fine.
Checklist