Expose per-mount subpath/alias/permission on the SessionV2 GraphQL node
- Dominant language
- Python
- Stars
- 670
- Forks
- 183
- Avg merge
- 17h 7m
- Merged PRs (30d)
- 358
Description
Part of the per-mount metadata epic: #11962
## Goal
Expose per-mount **subpath**, **alias** (mount destination), and **permission** on the new Strawberry `SessionV2GQL` node, replacing the `# TODO: Add vfolder_mounts dynamic field` placeholder at `src/ai/backend/manager/api/gql/session/types.py:437`.
This is the v2-first path mandated by project rules (`api/gql/CLAUDE.md`). The data is already available in the v2 adapter, so no DB/loader/query change is needed.
## Changes
1. **DTO** — `src/ai/backend/common/dto/manager/v2/session/response.py`
- Add `class SessionMount(BaseResponseModel)` with: `vfolder_id: UUID`, `name: str`, `subpath: str | None`, `mount_destination: str`, `permission: str`, `usage_mode: str`.
- Add `mounts: list[SessionMount]` to `SessionNode`.
2. **Adapter** — `src/ai/backend/manager/api/adapters/session/adapter.py`, `_session_data_to_node()` (~line 901)
- Populate `mounts=[SessionMount(...) for m in (data.vfolder_mounts or [])]`, mapping `vfid.folder_id`, `name`, `str(vfsubpath)` → `None` when `"."`, `str(kernel_path)`, `mount_perm.value`, `usage_mode.value`. Data is already present here.
3. **GQL type** — `src/ai/backend/manager/api/gql/session/types.py`
- Add `SessionMountGQL` via `@gql_pydantic_type(model=SessionMount, name="SessionMount")` (use `name="SessionMountV2"` if supergraph composition collides — see federation caveat in `api/gql/CLAUDE.md`).
- Replace the TODO at `:437` with a `mounts` field on `SessionV2GQL` using `gql_added_field(BackendAIGQLMeta(added_version=NEXT_RELEASE_VERSION, ...))` returning `list[SessionMountGQL]`. Plain field (data rides on the already-loaded DTO via `session_loader`).
- **Optional follow-up:** add a `vfolder` resolver on `SessionMountGQL` → `VFolderGQL | None` (v2 type at `api/gql/vfolder_v2/types/node.py`) via `info.context.data_loaders` + `strawberry.lazy()`, so the UI can drill into the folder.
4. **Schema** — run `scripts/generate-graphql-schema.sh` and confirm supergraph composition succeeds.
5. **Tests** — `tests/unit/manager/...`
- Adapter test: `SessionData` with a non-default `vfsubpath` + custom `kernel_path` + `ro` perm yields the expected `SessionNode.mounts`, incl. `"."` → `null` normalization.
- GQL resolver test for the `mounts` field shape.
## Verification
Restart manager (`./dev restart mgr`) and query `SessionV2 { mounts { vfolderId name subpath mountDestination permission usageMode } }`. Cross-check against a session created with explicit subpath + custom mount path.
## Out of scope
- Legacy `ComputeSession` schema (separate sub-issue).
- Changing how mounts are stored or created.
Contributor guide
Assessment
This issue has not been assessed yet.