Expose per-mount metadata (subpath, alias, permission) on GraphQL Session nodes
- Dominant language
- Python
- Stars
- 670
- Forks
- 183
- Avg merge
- 15h 13m
- Merged PRs (30d)
- 368
Description
## Summary
A vfolder mount on a session carries per-mount metadata beyond the vfolder identity — **subpath**, **alias** (custom mount destination), and an effective **permission**. This data is persisted on the session but is **not exposed through any GraphQL Session schema**, so the WebUI cannot render it.
## Background
When mounting a vfolder, the caller may set:
| Concept | Stored field (`VFolderMount`) | Meaning |
|---|---|---|
| subpath | `vfsubpath` (`PurePosixPath`, default `.`) | which subdirectory inside the vfolder is mounted |
| alias | `kernel_path` (`PurePosixPath`, default `/home/work/{name}`) | the mount destination path inside the container |
| permission | `mount_perm` | per-mount `ro`/`rw`/`wd` override |
These are stored in the `sessions.vfolder_mounts` JSON column (`StructuredJSONObjectListColumn(VFolderMount)`, `src/ai/backend/manager/models/session/row.py:512`).
## The gap (current state)
Nothing in GraphQL exposes the per-mount `subpath`/`alias`/`permission`:
- **Legacy `ComputeSession.mounts`** (`gql_legacy/session.py:1022`) → deduped vfolder **names** only.
- **Legacy `ComputeSession.vfolder_mounts` / `ComputeSessionNode.vfolder_mounts`** (`:1023`, `:249`) → vfolder **UUIDs** only (already marked for deprecation, `:379`).
- **Legacy `vfolder_nodes` connection** (`:256`, resolver `:471`) → resolves the vfolder **entity** by `folder_id` and **discards** all per-mount fields.
- **New `SessionV2GQL`** (`api/gql/session/types.py:305`) → **no mount field at all**; explicit `# TODO: Add vfolder_mounts dynamic field` at `types.py:437`.
## Key finding — the data already flows to the adapter
No DB/loader change is required. `SessionData.vfolder_mounts: list[VFolderMountData] | None` (`manager/data/session/types.py:175`) is already populated (`models/session/row.py:733`) and is in hand inside the v2 adapter `_session_data_to_node()` (`api/adapters/session/adapter.py:901`) — it is simply dropped before reaching the schema. The work is confined to the **DTO → GraphQL output** path.
## Proposed output shape
A per-mount object mapped from `VFolderMountData`:
| Field | Source | Notes |
|---|---|---|
| `vfolder_id` | `vfid.folder_id` | navigation / dedupe |
| `name` | `name` | vfolder name |
| `subpath` | `vfsubpath` | normalize `.` → `null` (root) |
| `mount_destination` | `kernel_path` | the **alias** (container path) |
| `permission` | `mount_perm` | `ro`/`rw`/`wd` |
| `usage_mode` | `usage_mode` | general/model/data |
(`host_path` is intentionally excluded — internal storage path.)
## Sub-issues
- [ ] #11963 — (v2) Expose per-mount subpath/alias/permission on the SessionV2 GraphQL node
- [ ] #11964 — (legacy) Expose per-mount subpath/alias/permission on the legacy ComputeSession GraphQL node
## Related
- #11936 — Allow mounting the same vfolder at multiple subpaths in a single session (makes per-mount detail even more necessary, since one vfolder may appear multiple times with different subpaths/aliases).
- #11901, #11904 — precedent for enriching the SessionV2 / VFolder v2 GraphQL nodes.
Contributor guide
Research direction
Start with SessionData.vfolder_mounts in manager/data/session/types.py and the DTO mapping in api/adapters/session/adapter.py, then read the SessionV2 and legacy GraphQL definitions at the paths named in the issue. Track sub-issues #11963 and #11964 separately; done means both session schemas expose the specified per-mount fields without exposing host_path.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- graphql, python
- Domain
- api, backend-api-design
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 65/100