diff --git a/.github/workflows/build-docs.yaml b/.github/workflows/build-docs.yaml index 43d0eca17..67e06a021 100644 --- a/.github/workflows/build-docs.yaml +++ b/.github/workflows/build-docs.yaml @@ -17,16 +17,21 @@ name: Build Docs on: pull_request: +permissions: + contents: read + jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 - - uses: actions/setup-python@v6 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false + - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 with: python-version: 3.x - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV - - uses: actions/cache@v5 + - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: key: mkdocs-material-${{ env.cache_id }} path: .cache diff --git a/.github/workflows/feature-matrix-updater.yaml b/.github/workflows/feature-matrix-updater.yaml index 6733f99ca..a8aa9b4a8 100644 --- a/.github/workflows/feature-matrix-updater.yaml +++ b/.github/workflows/feature-matrix-updater.yaml @@ -9,10 +9,12 @@ jobs: pull-requests: write steps: - name: Checkout adk-docs repo - uses: actions/checkout@v6 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false - name: Set up Go - uses: actions/setup-go@v6 + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 with: go-version: '1.22' @@ -27,7 +29,7 @@ jobs: GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }} - name: Create Pull Request - uses: peter-evans/create-pull-request@v8 + uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1 with: token: ${{ secrets.ADK_BOT_GITHUB_TOKEN }} commit-message: "feat: propose update to feature matrix" diff --git a/.github/workflows/go-fmt.yaml b/.github/workflows/go-fmt.yaml index 687a2c02b..5091cd6ec 100644 --- a/.github/workflows/go-fmt.yaml +++ b/.github/workflows/go-fmt.yaml @@ -5,21 +5,28 @@ on: paths: - '**.go' +permissions: + contents: read + jobs: gofmt: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: fetch-depth: 0 # Fetch all history for all tags and branches - - uses: actions/setup-go@v6 + persist-credentials: false + - uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 with: go-version: '1.25' - name: Run gofmt on changed files + env: + BASE_SHA: ${{ github.event.pull_request.base.sha }} + HEAD_SHA: ${{ github.event.pull_request.head.sha }} run: | # List changed Go files in the pull request. # The `|| true` is to prevent the command from failing if no go files are found - changed_files=$(git diff --name-only --diff-filter=ACMRT ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }} | grep '\.go$' || true) + changed_files=$(git diff --name-only --diff-filter=ACMRT "${BASE_SHA}..${HEAD_SHA}" | grep '\.go$' || true) if [ -z "$changed_files" ]; then echo "No Go files changed in this PR." @@ -38,4 +45,4 @@ jobs: exit 1 else echo "All changed Go files are formatted correctly." - fi \ No newline at end of file + fi diff --git a/.github/workflows/go-snippets-pr-check.yaml b/.github/workflows/go-snippets-pr-check.yaml index 5b89c2984..f0a5cb53e 100644 --- a/.github/workflows/go-snippets-pr-check.yaml +++ b/.github/workflows/go-snippets-pr-check.yaml @@ -23,6 +23,9 @@ on: schedule: - cron: '0 3 * * 0' +permissions: + contents: read + jobs: # This job builds and runs the Go snippets. test: @@ -30,18 +33,19 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v6 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: # Fetch the entire history to compare branches in the PR. fetch-depth: 0 + persist-credentials: false - name: Set up Go - uses: actions/setup-go@v6 + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 with: go-version: '1.25' - name: Cache Go modules - uses: actions/cache@v5 + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: path: ~/go/pkg/mod key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} @@ -60,11 +64,14 @@ jobs: - name: Get changed Go snippet files (PR only) if: github.event_name == 'pull_request' id: changed-files + env: + BASE_SHA: ${{ github.event.pull_request.base.sha }} + HEAD_SHA: ${{ github.event.pull_request.head.sha }} run: | # This command gets the list of changed .go files in the snippets directory # between the PR's head and the base branch. # The output is an escaped, space-separated string suitable for shell commands. - CHANGED_FILES=$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }} -- 'examples/go/snippets/**/*.go' | xargs) + CHANGED_FILES=$(git diff --name-only "${BASE_SHA}" "${HEAD_SHA}" -- 'examples/go/snippets/**/*.go' | xargs) echo "changed_files=${CHANGED_FILES}" >> $GITHUB_OUTPUT echo "Detected changes in: ${CHANGED_FILES}" @@ -72,7 +79,9 @@ jobs: if: github.event_name == 'pull_request' && steps.changed-files.outputs.changed_files != '' run: | echo "Building only the changed Go files..." - ./tools/go-snippets/runner.sh build ${{ steps.changed-files.outputs.changed_files }} + ./tools/go-snippets/runner.sh build ${STEPS_CHANGED_FILES_OUTPUTS_CHANGED_FILES} + env: + STEPS_CHANGED_FILES_OUTPUTS_CHANGED_FILES: ${{ steps.changed-files.outputs.changed_files }} # --- Scheduled Checks --- # These steps only run on the weekly schedule. diff --git a/.github/workflows/kotlin-snippets-pr-check.yaml b/.github/workflows/kotlin-snippets-pr-check.yaml index 75c12fe64..5345e9859 100644 --- a/.github/workflows/kotlin-snippets-pr-check.yaml +++ b/.github/workflows/kotlin-snippets-pr-check.yaml @@ -19,6 +19,9 @@ on: pull_request: branches: [ "main" ] +permissions: + contents: read + jobs: # This job builds the Kotlin snippets. test: @@ -26,19 +29,20 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v6 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: # Fetch the entire history to compare branches in the PR. fetch-depth: 0 + persist-credentials: false - name: Set up JDK 17 - uses: actions/setup-java@v4 + uses: actions/setup-java@c1e323688fd81a25caa38c78aa6df2d33d3e20d9 # v4.8.0 with: java-version: '17' distribution: 'temurin' - name: Setup Gradle - uses: gradle/actions/setup-gradle@v4 + uses: gradle/actions/setup-gradle@ed408507eac070d1f99cc633dbcf757c94c7933a # v4.4.3 # --- PR-Specific Checks --- # These steps only run for pull request events. @@ -52,10 +56,13 @@ jobs: - name: Get changed Kotlin snippet files (PR only) if: github.event_name == 'pull_request' id: changed-files + env: + BASE_SHA: ${{ github.event.pull_request.base.sha }} + HEAD_SHA: ${{ github.event.pull_request.head.sha }} run: | # This command gets the list of changed .kt files in the snippets directory # between the PR's head and the base branch. - CHANGED_FILES=$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }} -- 'examples/kotlin/snippets/**/*.kt' | xargs) + CHANGED_FILES=$(git diff --name-only "${BASE_SHA}" "${HEAD_SHA}" -- 'examples/kotlin/snippets/**/*.kt' | xargs) echo "changed_files=${CHANGED_FILES}" >> $GITHUB_OUTPUT echo "Detected changes in: ${CHANGED_FILES}" @@ -63,10 +70,14 @@ jobs: if: github.event_name == 'pull_request' && steps.changed-files.outputs.changed_files != '' run: | echo "Building only the changed Kotlin files..." - ./tools/kotlin-snippets/runner.sh build ${{ steps.changed-files.outputs.changed_files }} + ./tools/kotlin-snippets/runner.sh build ${STEPS_CHANGED_FILES_OUTPUTS_CHANGED_FILES} + env: + STEPS_CHANGED_FILES_OUTPUTS_CHANGED_FILES: ${{ steps.changed-files.outputs.changed_files }} - name: Lint changed Kotlin snippets (PR only) if: github.event_name == 'pull_request' && steps.changed-files.outputs.changed_files != '' run: | echo "Linting only the changed Kotlin files..." - ./tools/kotlin-snippets/runner.sh lint ${{ steps.changed-files.outputs.changed_files }} + ./tools/kotlin-snippets/runner.sh lint ${STEPS_CHANGED_FILES_OUTPUTS_CHANGED_FILES} + env: + STEPS_CHANGED_FILES_OUTPUTS_CHANGED_FILES: ${{ steps.changed-files.outputs.changed_files }} diff --git a/.github/workflows/link-checker.yaml b/.github/workflows/link-checker.yaml index 4655844ed..6a5b81212 100644 --- a/.github/workflows/link-checker.yaml +++ b/.github/workflows/link-checker.yaml @@ -20,14 +20,19 @@ on: - main pull_request: +permissions: + contents: read + jobs: link-check: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false - name: Check links - uses: lycheeverse/lychee-action@v2 + uses: lycheeverse/lychee-action@8646ba30535128ac92d33dfc9133794bfdd9b411 # v2.8.0 with: args: >- --verbose diff --git a/.github/workflows/publish-docs.yaml b/.github/workflows/publish-docs.yaml index 98686d104..3b61baaeb 100644 --- a/.github/workflows/publish-docs.yaml +++ b/.github/workflows/publish-docs.yaml @@ -26,16 +26,16 @@ jobs: deploy: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 # zizmor: ignore[artipacked] - gh-deploy needs the persisted GITHUB_TOKEN to push to gh-pages - name: Configure Git Credentials run: | git config user.name github-actions[bot] git config user.email 41898282+github-actions[bot]@users.noreply.github.com - - uses: actions/setup-python@v6 + - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 with: python-version: 3.x - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV - - uses: actions/cache@v5 + - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: key: mkdocs-material-${{ env.cache_id }} path: .cache diff --git a/.github/workflows/python-lint.yaml b/.github/workflows/python-lint.yaml index 9459fd530..34661348d 100644 --- a/.github/workflows/python-lint.yaml +++ b/.github/workflows/python-lint.yaml @@ -32,15 +32,19 @@ on: schedule: - cron: "0 0 * * 0" +permissions: + contents: read + jobs: get_sample_dirs: runs-on: ubuntu-latest outputs: sample_dirs: ${{ steps.get_dirs.outputs.sample_dirs }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ github.event.pull_request.head.sha }} + persist-credentials: false - name: Get Sample Directories id: get_dirs @@ -61,12 +65,13 @@ jobs: - get_sample_dirs steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ github.event.pull_request.head.sha }} + persist-credentials: false - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v6 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 with: python-version: ${{ matrix.python-version }} cache: "pip" @@ -78,6 +83,8 @@ jobs: - name: Run Black and Flake8 Linting in ${{ matrix.sample_dir }} run: | - cd ${{ matrix.sample_dir }} + cd ${MATRIX_SAMPLE_DIR} black . - flake8 . \ No newline at end of file + flake8 . + env: + MATRIX_SAMPLE_DIR: ${{ matrix.sample_dir }} diff --git a/.github/workflows/python-tests.yaml b/.github/workflows/python-tests.yaml index 0aa92edb1..2055b38d1 100644 --- a/.github/workflows/python-tests.yaml +++ b/.github/workflows/python-tests.yaml @@ -32,15 +32,19 @@ on: schedule: - cron: "0 0 * * 0" +permissions: + contents: read + jobs: get_sample_dirs: runs-on: ubuntu-latest outputs: sample_dirs: ${{ steps.get_dirs.outputs.sample_dirs }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ github.event.pull_request.head.sha }} + persist-credentials: false - name: Get Sample Directories id: get_dirs @@ -61,12 +65,13 @@ jobs: fail-fast: false # Important: Don't stop if one matrix configuration fails steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: ref: ${{ github.event.pull_request.head.sha }} + persist-credentials: false - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v6 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 with: python-version: ${{ matrix.python-version }} cache: "pip" @@ -75,13 +80,17 @@ jobs: run: | python -m pip install --upgrade pip pip install pytest coverage - pip install -r ${{ matrix.sample_dir }}/requirements.txt - pip install -r ${{ matrix.sample_dir }}/requirements-test.txt + pip install -r ${MATRIX_SAMPLE_DIR}/requirements.txt + pip install -r ${MATRIX_SAMPLE_DIR}/requirements-test.txt + env: + MATRIX_SAMPLE_DIR: ${{ matrix.sample_dir }} - name: Run pytest in ${{ matrix.sample_dir }} run: | - cd ${{ matrix.sample_dir }} + cd ${MATRIX_SAMPLE_DIR} pytest | tee pytest.txt + env: + MATRIX_SAMPLE_DIR: ${{ matrix.sample_dir }} - name: Show failed tests and overall summary run: | @@ -93,7 +102,7 @@ jobs: fi - name: Upload pytest test results - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: pytest-results-${{ matrix.python-version }}-${{ matrix.sample_dir }} path: | diff --git a/.github/workflows/update-python-docs.yaml b/.github/workflows/update-python-docs.yaml index 4b419aab1..c404bbd0b 100644 --- a/.github/workflows/update-python-docs.yaml +++ b/.github/workflows/update-python-docs.yaml @@ -14,6 +14,8 @@ on: issues: types: [opened, labeled] +permissions: {} + jobs: update-adk-python-docs-from-issue: if: contains(github.event.issue.labels.*.name, 'docs updates') @@ -21,25 +23,26 @@ jobs: steps: - name: Checkout ADK Python repository - uses: actions/checkout@v6 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: repository: google/adk-python path: ./adk-python token: ${{ secrets.ADK_BOT_GITHUB_TOKEN }} + persist-credentials: false - name: Set up Python - uses: actions/setup-python@v6 + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 with: python-version: '3.11' - name: Authenticate to Google Cloud id: auth - uses: 'google-github-actions/auth@v3' + uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # v3.0.0 with: credentials_json: '${{ secrets.ADK_GCP_SA_KEY }}' - name: Load adk-bot SSH Private Key - uses: webfactory/ssh-agent@v0.9.0 + uses: webfactory/ssh-agent@dc588b651fe13675774614f8e6a936a468676387 # v0.9.0 with: ssh-private-key: ${{ secrets.ADK_BOT_SSH_PRIVATE_KEY }} @@ -65,5 +68,6 @@ jobs: CODE_REPO: 'adk-python' INTERACTIVE: 0 PYTHONPATH: adk-python/contributing/samples/adk_team/adk_documentation + ISSUE_NUMBER: ${{ github.event.issue.number }} run: - python -m adk_docs_updater.main --issue_number ${{ github.event.issue.number }} + python -m adk_docs_updater.main --issue_number "${ISSUE_NUMBER}" diff --git a/docs/integrations/assets/mimir.svg b/docs/integrations/assets/mimir.svg new file mode 100644 index 000000000..ed50338b9 --- /dev/null +++ b/docs/integrations/assets/mimir.svg @@ -0,0 +1,12 @@ + + + + + + + + + M + + + diff --git a/docs/integrations/mimir.md b/docs/integrations/mimir.md new file mode 100644 index 000000000..1a338b407 --- /dev/null +++ b/docs/integrations/mimir.md @@ -0,0 +1,148 @@ +--- +catalog_title: Mimir Memory +catalog_description: Add persistent, local, encrypted cross-session memory to ADK agents +catalog_icon: /integrations/assets/mimir.svg +catalog_tags: ["data"] +--- + +# Mimir Memory integration for ADK + +
+ Supported in ADKPython +
+ +The [`adk-mimir-memory`](https://github.com/Perseus-Computing-LLC/adk-mimir-memory) +integration connects your ADK agent to +[Mimir](https://github.com/Perseus-Computing-LLC/mimir), a persistent, +cross-session memory backend. Backed by a single Rust binary with an embedded +SQLite database, it requires **zero cloud dependencies**, and everything runs +locally. Memory is encrypted at rest with AES-256-GCM, and search combines FTS5 +keyword matching with dense vector retrieval. + +## Use cases + +- **Persistent agent memory across restarts**: Sessions survive process + restarts, and agents recall past conversations automatically +- **Private, air-gapped deployments**: No cloud dependency, and Mimir runs + entirely on your machine with optional AES-256-GCM encryption +- **Hybrid search across memories**: Combine keyword (FTS5/BM25) and semantic + (dense vector) search to find relevant past interactions +- **Workspace-aware agents**: Pair with Perseus for agents that know about your + project files, git state, and configuration + +## Prerequisites + +- Python 3.10+ +- The `mimir` binary (see [Installation](#installation)) +- `google-adk>=1.0.0` + +## Installation + +Install the Python package: + +```bash +pip install adk-mimir-memory +``` + +Then install the `mimir` binary: download the build for your platform from the +[Mimir releases page](https://github.com/Perseus-Computing-LLC/mimir/releases) +and place it on your `PATH`. The service looks for `mimir` by default, or pass +`mimir_binary="/absolute/path/to/mimir"` to `MimirMemoryService`. + +## Use with agent + +Create the `MimirMemoryService`, pass it to your `Runner`, and give the agent +the `load_memory` tool so it can recall past sessions: + +```python +from adk_mimir_memory import MimirMemoryService +from google.adk.agents import Agent +from google.adk.runners import Runner +from google.adk.sessions import InMemorySessionService +from google.adk.tools import load_memory + +agent = Agent( + name="memory_assistant", + model="gemini-flash-latest", + instruction="You are a helpful assistant with long-term memory.", + tools=[load_memory], +) + +runner = Runner( + agent=agent, + app_name="mimir_app", + session_service=InMemorySessionService(), + memory_service=MimirMemoryService(db_path="~/.adk/mimir.db"), +) +``` + +After a session completes, call +`await memory_service.add_session_to_memory(session)` to persist it. The agent +recalls relevant memories in later sessions through the `load_memory` tool. See +[ADK memory](/sessions/memory/) for the full ingest-and-recall flow. + +### Perseus live context (optional) + +For live workspace awareness, install the `perseus` extra: + +```bash +pip install adk-mimir-memory[perseus] +``` + +Then use the prebuilt `perseus_context_agent`, which resolves `@file`, +`@search`, and `@memory` directives at inference time: + +```python +from adk_mimir_memory.perseus_context import perseus_context_agent +from google.adk.runners import Runner +from google.adk.sessions import InMemorySessionService + +# The pre-built agent ships without a model; set one before use. +perseus_context_agent.model = "gemini-flash-latest" + +runner = Runner( + agent=perseus_context_agent, + app_name="perseus_app", + session_service=InMemorySessionService(), + memory_service=MimirMemoryService(db_path="~/.adk/mimir.db"), +) +``` + +Set Perseus directives via session state when creating the session (inside an +async function): + +```python +session = await runner.session_service.create_session( + app_name="perseus_app", + user_id="user", + state={ + "_perseus_directives": "@file AGENTS.md @file README.md @memory deployment", + "_perseus_workspace": "/path/to/project", + }, +) +``` + +## Available memory operations + +| Method | Description | +|---|---| +| `add_session_to_memory(session)` | Persist a full session's events | +| `add_events_to_memory(...)` | Append incremental event deltas | +| `add_memory(...)` | Store explicit memory entries | +| `search_memory(...)` | FTS5 keyword search across memories | + +## Backend comparison + +| Backend | Dependencies | At-rest encryption | Search | Hosting | +|---|---|---|---|---| +| **InMemoryMemoryService** | None | Not persisted | Keyword | Local (ephemeral) | +| **VertexAiMemoryBankService** | Google Cloud | Google-managed (CMEK optional) | Semantic (Gemini) | Google Cloud | +| **VertexAiRagMemoryService** | Google Cloud | Google-managed (CMEK optional) | Vector similarity | Google Cloud | +| **MimirMemoryService** | `mimir` binary | Local AES-256-GCM (optional) | Hybrid (FTS5 + dense) | Local | + +## Resources + +- [adk-mimir-memory on GitHub](https://github.com/Perseus-Computing-LLC/adk-mimir-memory) +- [adk-mimir-memory on PyPI](https://pypi.org/project/adk-mimir-memory/) +- [Mimir (backing service)](https://github.com/Perseus-Computing-LLC/mimir) +- [Perseus (context engine)](https://github.com/Perseus-Computing-LLC/perseus) diff --git a/docs/integrations/phoenix.md b/docs/integrations/phoenix.md index e297bc9c2..d13587c49 100644 --- a/docs/integrations/phoenix.md +++ b/docs/integrations/phoenix.md @@ -11,7 +11,7 @@ catalog_tags: ["observability", "evaluation"] Supported in ADKPython -[Phoenix](https://arize.com/docs/phoenix) is an open-source, self-hosted observability platform for monitoring, debugging, and improving LLM applications and AI Agents at scale. It provides comprehensive tracing and evaluation capabilities for your Google ADK applications. To get started, sign up for a [free account](https://phoenix.arize.com/). +[Phoenix](https://arize.com/docs/phoenix) is an open-source, self-hosted observability platform for monitoring, debugging, and improving LLM applications and AI Agents at scale. It provides comprehensive tracing and evaluation capabilities for your Google ADK applications. To get started, sign up for a [free account](https://arize.com/phoenix/). ## Overview @@ -37,7 +37,7 @@ pip install openinference-instrumentation-google-adk google-adk arize-phoenix-ot These instructions show you how to use Phoenix Cloud. You can also [launch Phoenix](https://arize.com/docs/phoenix/integrations/llm-providers/google-gen-ai/google-adk-tracing) in a notebook, from your terminal, or self-host it using a container. -1. Sign up for a [free Phoenix account](https://phoenix.arize.com/). +1. Sign up for a [free Phoenix account](https://arize.com/phoenix/). 2. From the Settings page of your new Phoenix Space, create your API key 3. Copy your endpoint which should look like: https://app.phoenix.arize.com/s/[your-space-name]