* docs: Add Go language quickstart * updates based on review comments * fix tab stops * update based on review comments * sync with main * update to tested version * Added google_search snippet * Fix: Address Go style guide issues in google_search.go * Migrated to new API * Fixed tool info in md file * Added partial check * Added function-tools sample * Migrated to new API * Added partial check * Ran linter * feat: add go fmt check * Run go fmt only on changed files * Added google_search snippet * Fix: Address Go style guide issues in google_search.go * Migrated to new API * Added partial check * Added function-tools sample * Migrated to new API * Added partial check * Ran linter * feat: add go fmt check * Run go fmt only on changed files * Feat: Add Golang example for LLM agents * Added schema agent * Added session support * Migrated to new API * Added back OutputKey * Added missing snippets * Moved snipped to its own package * Minor cleanup * Reverted llm-agents.md * Added back correct changes to llm-agents.md * Updated to newest API * Ran linter * WIP * WIP: Added the rest of the agents * Added sequential agent * Migrated agents to new API * Fixed snippet tags * Updated parallel and sequential with OutputKey * Updated loop agent * Cleanup * Fixed and ran linter * Removed comment * Ran linter * Added custom agent snippets * Migrated to new API * Fixed incorrect info about channels since run returns an Iterator, not Channel * Cleanup and renaming * Ran linter * Fixed md * Added multi-agent docs * Updated to use AgentTool * Split snippets * Added missing file * Ran linter and fixed API * Added Models snippets * Migrated to new API * Embedded imports * Ran linter * Added long running tool * Ran linter and fixed API * Switched to two-turn style * Ran linter * Added callback snippets * Added back imports * Added types of callbacks snippets * feat(go): align callback snippets with other languages * Ran linter and updated API * Added tool callbacks * Added artifact snippets * Use story.pdf instead of random bytes * Fixed issue with artifact loading * Cleanup unneeded fixes * Added back inadvertently removed GCS section * Addressed PR comments * Ran linter * feat: Added context snippets * Fixed callback signature * Fixed additional callbacks * Added remaining snippets * Added conceptual runner example * Removed duplicate code * Clean up tags and imports * Updated API * Twaked text * Ran linter * Fixed broken API issues * Updated to latest Go ADK API * Added func param info * Interleaved Py and Go * Revert mistakes * Removed extra newline * Added example cloud run code and update md with Go (#41) * Added example cloud run code and update md with Go * Added a2a_agent_url and fixed future tense * Moved Go before Java --------- Co-authored-by: ivanmkc <ivanmkc@google.com> * adding go snippets to runconfig docs * realigning runconfig go examples with current state of adk-go. * adding language support tags to individual runtime config fields * removing unsupported supportcfc go examples * removing unsupported streamingmode.bidi go snippets * Added AgentTool examples (#31) * Added AgentTool example * Ran formatter --------- Co-authored-by: ivanmkc <ivanmkc@google.com> * adding initial go sessions.sessions snippets * updating go session docs + session examples * update go session snippets * updating DatabaseSessionService language support tag * cleaning up go vertex ai comments * removing go.mod for session_management_example * docs: add language support tags for Go * initial go runtime sample updates * fixing runtime go snippet formatting * formatting updates to runtime go snippets * updating runtime go examples to streamline to newer go features * adding go snippets for events * updating go snippets for events * adding artifactdelta snippet for go * minor java fixes, cleaning up go event.content * Custom tools: Merging again (#44) * Added missing custom-tools snippets * Split user_preference runner code * Split more files * Tweaks * Split session into 1 and 2 and added artifact saving * Fixed conflict --------- Co-authored-by: ivanmkc <ivanmkc@google.com> * Fixed tab issue with cloud-run md (#45) Co-authored-by: ivanmkc <ivanmkc@google.com> * adding initial go snippets for memory services * updating go memory sample, adding python formatting in docs to clarify current support. * removing go replace for memory example * removing go.sum from memory_example * fixing go formatting for memory example * fixing go memory snippets to streamline examples in docs * removing unnecessary go.mod for memory_example.go and snippet cleanup * adding go session state snippets." * adding additional go state examples for state injection * fixing go formatting * fixing language ordering on session/state.md; removing unnecessary go.mod files * reworking error functions in go session state samples * fixing go formatting on session state samples * initial go snippets for safety tools * fixing go snippet formatting in safety/index.md * temp storing safety example * cleaning up go snippets in safety docs; deferring safety go full example * cleaning up go safety snippets * Added link to Go API docs (#47) Co-authored-by: ivanmkc <ivanmkc@google.com> * Added a2a_basic sample (#46) * Added a2a_basic sample * Removed dummy LLMs * Added md Fix inaccuracies in md Ran formatter * Cleaned up index --------- Co-authored-by: ivanmkc <ivanmkc@google.com> * Reverted to proper ToC and added missing links (#48) Co-authored-by: ivanmkc <ivanmkc@google.com> * Added missing get-started/go.md (#50) Co-authored-by: ivanmkc <ivanmkc@google.com> * Added missing JSON tags for Go structs (#51) * Added json tags * Added jsonschema and json tags --------- Co-authored-by: ivanmkc <ivanmkc@google.com> * Renamed Golang to Go (#52) Co-authored-by: ivanmkc <ivanmkc@google.com> --------- Co-authored-by: Joe Fernandez <joefernandez@google.com> Co-authored-by: ivanmkc <ivanmkc@google.com> Co-authored-by: Toni Klopfenstein <tklopfenstein@google.com>
13 KiB
Session: Tracking Individual Conversations
Following our Introduction, let's dive into the Session. Think back to the
idea of a "conversation thread." Just like you wouldn't start every text message
from scratch, agents need context regarding the ongoing interaction.
Session is the ADK object designed specifically to track and manage these
individual conversation threads.
The Session Object
When a user starts interacting with your agent, the SessionService creates a
Session object (google.adk.sessions.Session). This object acts as the
container holding everything related to that one specific chat thread. Here
are its key properties:
- Identification (
id,appName,userId): Unique labels for the conversation.id: A unique identifier for this specific conversation thread, essential for retrieving it later. A SessionService object can handle multipleSession(s). This field identifies which particular session object are we referring to. For example, "test_id_modification".app_name: Identifies which agent application this conversation belongs to. For example, "id_modifier_workflow".userId: Links the conversation to a particular user.
- History (
events): A chronological sequence of all interactions (Eventobjects – user messages, agent responses, tool actions) that have occurred within this specific thread. - Session State (
state): A place to store temporary data relevant only to this specific, ongoing conversation. This acts as a scratchpad for the agent during the interaction. We will cover how to use and managestatein detail in the next section. - Activity Tracking (
lastUpdateTime): A timestamp indicating the last time an event occurred in this conversation thread.
Example: Examining Session Properties
=== "Python"
```py
from google.adk.sessions import InMemorySessionService, Session
# Create a simple session to examine its properties
temp_service = InMemorySessionService()
example_session = await temp_service.create_session(
app_name="my_app",
user_id="example_user",
state={"initial_key": "initial_value"} # State can be initialized
)
print(f"--- Examining Session Properties ---")
print(f"ID (`id`): {example_session.id}")
print(f"Application Name (`app_name`): {example_session.app_name}")
print(f"User ID (`user_id`): {example_session.user_id}")
print(f"State (`state`): {example_session.state}") # Note: Only shows initial state here
print(f"Events (`events`): {example_session.events}") # Initially empty
print(f"Last Update (`last_update_time`): {example_session.last_update_time:.2f}")
print(f"---------------------------------")
# Clean up (optional for this example)
temp_service = await temp_service.delete_session(app_name=example_session.app_name,
user_id=example_session.user_id, session_id=example_session.id)
print("The final status of temp_service - ", temp_service)
```
=== "Java"
```java
import com.google.adk.sessions.InMemorySessionService;
import com.google.adk.sessions.Session;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentHashMap;
String sessionId = "123";
String appName = "example-app"; // Example app name
String userId = "example-user"; // Example user id
ConcurrentMap<String, Object> initialState = new ConcurrentHashMap<>(Map.of("newKey", "newValue"));
InMemorySessionService exampleSessionService = new InMemorySessionService();
// Create Session
Session exampleSession = exampleSessionService.createSession(
appName, userId, initialState, Optional.of(sessionId)).blockingGet();
System.out.println("Session created successfully.");
System.out.println("--- Examining Session Properties ---");
System.out.printf("ID (`id`): %s%n", exampleSession.id());
System.out.printf("Application Name (`appName`): %s%n", exampleSession.appName());
System.out.printf("User ID (`userId`): %s%n", exampleSession.userId());
System.out.printf("State (`state`): %s%n", exampleSession.state());
System.out.println("------------------------------------");
// Clean up (optional for this example)
var unused = exampleSessionService.deleteSession(appName, userId, sessionId);
```
=== "Go"
```go
--8<-- "examples/go/snippets/sessions/session_management_example/session_management_example.go:examine_session"
```
(Note: The state shown above is only the initial state. State updates happen via events, as discussed in the State section.)
Managing Sessions with a SessionService
As seen above, you don't typically create or manage Session objects directly.
Instead, you use a SessionService. This service acts as the central
manager responsible for the entire lifecycle of your conversation sessions.
Its core responsibilities include:
- Starting New Conversations: Creating fresh
Sessionobjects when a user begins an interaction. - Resuming Existing Conversations: Retrieving a specific
Session(using its ID) so the agent can continue where it left off. - Saving Progress: Appending new interactions (
Eventobjects) to a session's history. This is also the mechanism through which sessionstategets updated (more in theStatesection). - Listing Conversations: Finding the active session threads for a particular user and application.
- Cleaning Up: Deleting
Sessionobjects and their associated data when conversations are finished or no longer needed.
SessionService Implementations
ADK provides different SessionService implementations, allowing you to choose
the storage backend that best suits your needs:
-
InMemorySessionService- How it works: Stores all session data directly in the application's memory.
- Persistence: None. All conversation data is lost if the application restarts.
- Requires: Nothing extra.
- Best for: Quick development, local testing, examples, and scenarios where long-term persistence isn't required.
=== "Python"
```py from google.adk.sessions import InMemorySessionService session_service = InMemorySessionService() ```=== "Java"
```java import com.google.adk.sessions.InMemorySessionService; InMemorySessionService exampleSessionService = new InMemorySessionService(); ```=== "Go"
```go import "google.golang.org/adk/session" inMemoryService := session.InMemoryService() ``` -
VertexAiSessionService- How it works: Uses Google Cloud Vertex AI infrastructure via API calls for session management.
- Persistence: Yes. Data is managed reliably and scalably via Vertex AI Agent Engine.
- Requires:
- A Google Cloud project (
pip install vertexai) - A Google Cloud storage bucket that can be configured by this step.
- A Reasoning Engine resource name/ID that can setup following this tutorial.
- If you do not have a Google Cloud project and you want to try the VertexAiSessionService for free, see how to try Session and Memory for free.
- A Google Cloud project (
- Best for: Scalable production applications deployed on Google Cloud, especially when integrating with other Vertex AI features.
=== "Python"
```py # Requires: pip install google-adk[vertexai] # Plus GCP setup and authentication from google.adk.sessions import VertexAiSessionService PROJECT_ID = "your-gcp-project-id" LOCATION = "us-central1" # The app_name used with this service should be the Reasoning Engine ID or name REASONING_ENGINE_APP_NAME = "projects/your-gcp-project-id/locations/us-central1/reasoningEngines/your-engine-id" session_service = VertexAiSessionService(project=PROJECT_ID, location=LOCATION) # Use REASONING_ENGINE_APP_NAME when calling service methods, e.g.: # session_service = await session_service.create_session(app_name=REASONING_ENGINE_APP_NAME, ...) ```=== "Java"
```java // Please look at the set of requirements above, consequently export the following in your bashrc file: // export GOOGLE_CLOUD_PROJECT=my_gcp_project // export GOOGLE_CLOUD_LOCATION=us-central1 // export GOOGLE_API_KEY=my_api_key import com.google.adk.sessions.VertexAiSessionService; import java.util.UUID; String sessionId = UUID.randomUUID().toString(); String reasoningEngineAppName = "123456789"; String userId = "u_123"; // Example user id ConcurrentMap<String, Object> initialState = new ConcurrentHashMap<>(); // No initial state needed for this example VertexAiSessionService sessionService = new VertexAiSessionService(); Session mySession = sessionService .createSession(reasoningEngineAppName, userId, initialState, Optional.of(sessionId)) .blockingGet(); ```=== "Go"
```go import "google.golang.org/adk/session" // 2. VertexAIService // Before running, ensure your environment is authenticated: // gcloud auth application-default login // export GOOGLE_CLOUD_PROJECT="your-gcp-project-id" // export GOOGLE_CLOUD_LOCATION="your-gcp-location" modelName := "gemini-1.5-flash-001" // Replace with your desired model vertexService, err := session.VertexAIService(ctx, modelName) if err != nil { log.Printf("Could not initialize VertexAIService (this is expected if the gcloud project is not set): %v", err) } else { fmt.Println("Successfully initialized VertexAIService.") } ``` -
DatabaseSessionServiceSupported in ADKPython v0.1.0Go v0.1.0- How it works: Connects to a relational database (e.g., PostgreSQL, MySQL, SQLite) to store session data persistently in tables.
- Persistence: Yes. Data survives application restarts.
- Requires: A configured database.
- Best for: Applications needing reliable, persistent storage that you manage yourself.
from google.adk.sessions import DatabaseSessionService # Example using a local SQLite file: db_url = "sqlite:///./my_agent_data.db" session_service = DatabaseSessionService(db_url=db_url)
Choosing the right SessionService is key to defining how your agent's
conversation history and temporary data are stored and persist.
The Session Lifecycle
Here’s a simplified flow of how Session and SessionService work together
during a conversation turn:
- Start or Resume: Your application needs to use the
SessionServiceto eithercreate_session(for a new chat) or use an existing session id. - Context Provided: The
Runnergets the appropriateSessionobject from the appropriate service method, providing the agent with access to the corresponding Session'sstateandevents. - Agent Processing: The user prompts the agent with a query. The agent
analyzes the query and potentially the session
stateandeventshistory to determine the response. - Response & State Update: The agent generates a response (and potentially
flags data to be updated in the
state). TheRunnerpackages this as anEvent. - Save Interaction: The
RunnercallssessionService.append_event(session, event)with thesessionand the neweventas the arguments. The service adds theEventto the history and updates the session'sstatein storage based on information within the event. The session'slast_update_timealso get updated. - Ready for Next: The agent's response goes to the user. The updated
Sessionis now stored by theSessionService, ready for the next turn (which restarts the cycle at step 1, usually with the continuation of the conversation in the current session). - End Conversation: When the conversation is over, your application calls
sessionService.delete_session(...)to clean up the stored session data if it is no longer required.
This cycle highlights how the SessionService ensures conversational continuity
by managing the history and state associated with each Session object.