From e15aa4b918435613e1a3a59e5c8a50d504cd4183 Mon Sep 17 00:00:00 2001 From: Kristopher Overholt Date: Fri, 26 Jun 2026 12:31:45 -0500 Subject: [PATCH 1/3] Secure CI workflows with zizmor ahead of enforced rollout (#1872) * ci: pin actions to SHAs and harden workflows with zizmor auto-fixes * ci: set least-privilege GITHUB_TOKEN permissions on workflows * ci: move PR/issue context into env vars to prevent template injection --- .github/workflows/build-docs.yaml | 11 ++++++--- .github/workflows/feature-matrix-updater.yaml | 8 ++++--- .github/workflows/go-fmt.yaml | 15 ++++++++---- .github/workflows/go-snippets-pr-check.yaml | 19 +++++++++++---- .../workflows/kotlin-snippets-pr-check.yaml | 23 ++++++++++++++----- .github/workflows/link-checker.yaml | 9 ++++++-- .github/workflows/publish-docs.yaml | 8 ++++--- .github/workflows/python-lint.yaml | 17 ++++++++++---- .github/workflows/python-tests.yaml | 23 +++++++++++++------ .github/workflows/update-python-docs.yaml | 14 +++++++---- 10 files changed, 104 insertions(+), 43 deletions(-) diff --git a/.github/workflows/build-docs.yaml b/.github/workflows/build-docs.yaml index 43d0eca177..67e06a0211 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 6733f99caa..a8aa9b4a8f 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 687a2c02b0..5091cd6ecb 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 5b89c29846..f0a5cb53e6 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 75c12fe64f..5345e9859b 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 4655844edd..6a5b81212c 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 98686d1042..fe2595e1ea 100644 --- a/.github/workflows/publish-docs.yaml +++ b/.github/workflows/publish-docs.yaml @@ -26,16 +26,18 @@ jobs: deploy: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false - 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 9459fd5308..34661348df 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 0aa92edb19..2055b38d15 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 4b419aab1b..c404bbd0bf 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}" From d472a52e6f22223e3f8b8fde10145f12151632bb Mon Sep 17 00:00:00 2001 From: Kristopher Overholt Date: Fri, 26 Jun 2026 13:12:21 -0500 Subject: [PATCH 2/3] ci: keep persisted credentials for mkdocs gh-deploy (#1879) --- .github/workflows/publish-docs.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/publish-docs.yaml b/.github/workflows/publish-docs.yaml index fe2595e1ea..3b61baaeb9 100644 --- a/.github/workflows/publish-docs.yaml +++ b/.github/workflows/publish-docs.yaml @@ -26,9 +26,7 @@ jobs: deploy: runs-on: ubuntu-latest steps: - - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 - with: - persist-credentials: false + - 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] From 73a1beb4b61bf1f50745c58403576f673bf22d60 Mon Sep 17 00:00:00 2001 From: Perseus Computing <51974392+tcconnally@users.noreply.github.com> Date: Fri, 26 Jun 2026 13:16:38 -0500 Subject: [PATCH 3/3] =?UTF-8?q?feat(integrations):=20add=20Mimir=20Memory?= =?UTF-8?q?=20=E2=80=94=20persistent=20cross-session=20memory=20for=20ADK?= =?UTF-8?q?=20(#1877)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(integrations): add Mimir Memory — persistent cross-session memory for ADK Adds MimirMemoryService integration documentation: - Persistent, local, encrypted memory backend for ADK agents - AES-256-GCM encryption, FTS5+dense hybrid search - Zero cloud dependencies — single Rust binary + SQLite - Includes Perseus live context agent sample - Backend comparison table vs InMemory, VertexAi, RAG Package: https://github.com/Perseus-Computing-LLC/adk-mimir-memory Refs: google/adk-python#6169 * Formatting edits * Fix Mimir Memory code samples, install steps, and comparison table * Fix unrelated link failure for Arize Phoenix * Add link to PyPI package --------- Co-authored-by: Kristopher Overholt --- docs/integrations/assets/mimir.svg | 12 +++ docs/integrations/mimir.md | 148 +++++++++++++++++++++++++++++ docs/integrations/phoenix.md | 4 +- 3 files changed, 162 insertions(+), 2 deletions(-) create mode 100644 docs/integrations/assets/mimir.svg create mode 100644 docs/integrations/mimir.md diff --git a/docs/integrations/assets/mimir.svg b/docs/integrations/assets/mimir.svg new file mode 100644 index 0000000000..ed50338b98 --- /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 0000000000..1a338b4070 --- /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 e297bc9c27..d13587c49a 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]