Files
Ivan Cheung 8834593806 [ADK Go] Merging all Go docs from the private repo (#885)
* 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>
2025-11-06 14:13:13 -05:00

13 KiB
Raw Permalink Blame History

Session: Tracking Individual Conversations

Supported in ADKPython v0.1.0Java v0.1.0Go v0.1.0

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 multiple Session(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 (Event objects – 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 manage state in 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 Session objects 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 (Event objects) to a session's history. This is also the mechanism through which session state gets updated (more in the State section).
  • Listing Conversations: Finding the active session threads for a particular user and application.
  • Cleaning Up: Deleting Session objects 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:

  1. 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()
       ```
    
  2. 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.
    • 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.")
      }
      ```
    
  3. DatabaseSessionService

    Supported 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

Session lifecycle

Here’s a simplified flow of how Session and SessionService work together during a conversation turn:

  1. Start or Resume: Your application needs to use the SessionService to either create_session (for a new chat) or use an existing session id.
  2. Context Provided: The Runner gets the appropriate Session object from the appropriate service method, providing the agent with access to the corresponding Session's state and events.
  3. Agent Processing: The user prompts the agent with a query. The agent analyzes the query and potentially the session state and events history to determine the response.
  4. Response & State Update: The agent generates a response (and potentially flags data to be updated in the state). The Runner packages this as an Event.
  5. Save Interaction: The Runner calls sessionService.append_event(session, event) with the session and the new event as the arguments. The service adds the Event to the history and updates the session's state in storage based on information within the event. The session's last_update_time also get updated.
  6. Ready for Next: The agent's response goes to the user. The updated Session is now stored by the SessionService, ready for the next turn (which restarts the cycle at step 1, usually with the continuation of the conversation in the current session).
  7. 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.