Skip to content

feat(BA-3919): Add SessionV2 strawberry GQL schema#8641

Open
jopemachine wants to merge 25 commits intomainfrom
feat/BA-3919-session-v2-schema
Open

feat(BA-3919): Add SessionV2 strawberry GQL schema#8641
jopemachine wants to merge 25 commits intomainfrom
feat/BA-3919-session-v2-schema

Conversation

@jopemachine
Copy link
Member

@jopemachine jopemachine commented Feb 6, 2026

resolves #8085 (BA-3919)

Checklist: (if applicable)

  • Milestone metadata specifying the target backport version
  • Mention to the original issue
  • Installer updates including:
    • Fixtures for db schema changes
    • New mandatory config options
  • Update of end-to-end CLI integration tests in ai.backend.test
  • API server-client counterparts (e.g., manager API -> client SDK)
  • Test case(s) to:
    • Demonstrate the difference of before/after
    • Demonstrate the flow of abstract/conceptual models with a concrete implementation
  • Documentation
    • Contents in the docs directory
    • docstrings in public interfaces and type annotations

📚 Documentation preview 📚: https://sorna--8641.org.readthedocs.build/en/8641/


📚 Documentation preview 📚: https://sorna-ko--8641.org.readthedocs.build/ko/8641/

@jopemachine jopemachine added this to the 26.2 milestone Feb 6, 2026
@jopemachine jopemachine force-pushed the feat/BA-3919-session-v2-schema branch from fae5f12 to 380a647 Compare February 6, 2026 07:47
@github-actions github-actions bot added size:XL 500~ LoC area:docs Documentations comp:manager Related to Manager component labels Feb 6, 2026
@jopemachine jopemachine force-pushed the feat/BA-3919-session-v2-schema branch 2 times, most recently from 2be7e73 to 2595b13 Compare February 11, 2026 01:43
@jopemachine jopemachine marked this pull request as ready for review February 11, 2026 02:32
@jopemachine jopemachine force-pushed the feat/BA-3919-session-v2-schema branch from 14b020c to a5a649c Compare February 11, 2026 02:37
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request introduces the SessionV2 GraphQL schema types using Strawberry, modernizing the session API with structured types that replace legacy JSON scalar fields. The changes align with the ongoing V2 API migration (following patterns established in AgentV2GQL and KernelV2GQL) and prepare the foundation for implementing the full SessionV2 functionality.

Changes:

  • Adds new SessionV2 GraphQL type with Relay Node pattern and structured info sub-types (metadata, resource, lifecycle, runtime, network)
  • Introduces common GraphQL enums (SessionStatusGQL, SessionTypeGQL, SessionResultGQL, ClusterModeGQL) with internal type conversion methods
  • Refactors KernelV2GQL to use new common types and adds a session relationship field
  • Creates session_legacy.py for federation support and updates imports accordingly

Reviewed changes

Copilot reviewed 18 out of 19 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
src/ai/backend/manager/api/gql/session/types.py Defines SessionV2GQL type with info sub-types, enums, filter/order types, and connection types
src/ai/backend/manager/api/gql/session/resolver/session.py Adds session_v2 and admin_sessions_v2 resolver stubs
src/ai/backend/manager/api/gql/session/fetcher/session.py Adds fetch_session and fetch_sessions fetcher stubs
src/ai/backend/manager/api/gql/session/init.py Exports session types, resolvers, and fetchers
src/ai/backend/manager/api/gql/session_legacy.py Creates federation stub for legacy ComputeSessionNode compatibility
src/ai/backend/manager/api/gql/schema.py Integrates session_v2 resolvers into Query type
src/ai/backend/manager/api/gql/kernel/types.py Updates to use SessionResultGQL, renames session field to session_info, adds lazy-loaded session relationship
src/ai/backend/manager/api/gql/deployment/types/revision.py Migrates from local ClusterMode enum to common ClusterModeGQL
src/ai/backend/manager/api/gql/common/types.py Adds shared enums (ClusterModeGQL, SessionTypeGQL, SessionResultGQL)
src/ai/backend/manager/api/gql/common/init.py Exports new enum types (SessionResultGQL, SessionTypeGQL)
docs/manager/graphql-reference/v2-schema.graphql Updates GraphQL schema with SessionV2 types and fields
docs/manager/graphql-reference/supergraph.graphql Updates federation supergraph schema
changes/8641.feature.md Documents the feature addition

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 7 to 20
from .types import (
SessionConnectionV2GQL,
SessionEdgeGQL,
SessionFilterGQL,
SessionLifecycleInfoGQL,
SessionMetadataInfoGQL,
SessionNetworkInfoGQL,
SessionOrderByGQL,
SessionOrderFieldGQL,
SessionResourceInfoGQL,
SessionStatusFilterGQL,
SessionStatusGQL,
SessionV2GQL,
)
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SessionRuntimeInfoGQL type is defined in types.py and is a public field of SessionV2GQL, but it's not exported in the __all__ list. This type should be exported for consistency with other info types and to allow external consumers to reference it directly.

Copilot uses AI. Check for mistakes.
Comment on lines +73 to +74
case _:
# RESTARTING, RUNNING_DEGRADED, ERROR are not exposed via GQL
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment on line 74 states that ERROR is not exposed via GQL and is mapped to CANCELLED in the default case. However, this behavior may be confusing for API consumers. Consider explicitly handling the ERROR case in the match statement for clarity, or update the comment to explain why ERROR maps to CANCELLED instead of TERMINATED, which might be more semantically correct for error states.

Suggested change
case _:
# RESTARTING, RUNNING_DEGRADED, ERROR are not exposed via GQL
case SessionStatus.RESTARTING | SessionStatus.RUNNING_DEGRADED:
# Internal transitional states are not exposed via GraphQL.
# They are reported to clients as CANCELLED for backward compatibility.
return cls.CANCELLED
case SessionStatus.ERROR:
# Internal ERROR is also not exposed via GraphQL.
# It is mapped to CANCELLED instead of TERMINATED to preserve existing API behaviour.
return cls.CANCELLED
case _:
# Fallback for any future internal states not yet handled explicitly.
# For compatibility, these are currently mapped to CANCELLED.

Copilot uses AI. Check for mistakes.
Comment on lines 105 to 115
@strawberry.enum(
name="SessionOrderField",
description="Added in 26.2.0. Fields available for ordering sessions.",
)
class SessionOrderFieldGQL(StrEnum):
CREATED_AT = "created_at"
TERMINATED_AT = "terminated_at"
STATUS = "status"
ID = "id"
NAME = "name"

Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SessionOrderFieldGQL enum includes fields CREATED_AT, TERMINATED_AT, STATUS, ID, and NAME. However, according to the linked issue #8085, the required order fields should include SCHEDULED_AT. The current implementation has TERMINATED_AT but is missing SCHEDULED_AT. Additionally, the issue mentions that SessionOrders repository methods should include scheduled_at(), created_at(), and id(), but the enum doesn't align with this requirement. Please verify which order fields are actually needed and ensure consistency between the GraphQL enum and the issue requirements.

Copilot uses AI. Check for mistakes.
Comment on lines +175 to +177
created_at: datetime | None = strawberry.field(
description="Timestamp when the session was created."
)
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The created_at field is duplicated in both SessionMetadataInfoGQL (lines 175-177) and SessionLifecycleInfoGQL (lines 206-208). This duplication is inconsistent with the design pattern where each info type should contain logically grouped fields without overlap. The created_at field should only be in SessionLifecycleInfoGQL since it's a lifecycle timestamp, not metadata.

Suggested change
created_at: datetime | None = strawberry.field(
description="Timestamp when the session was created."
)

Copilot uses AI. Check for mistakes.
Comment on lines 157 to 179
@strawberry.type(
name="SessionMetadataInfo",
description="Added in 26.2.0. Metadata information for a session.",
)
class SessionMetadataInfoGQL:
creation_id: str = strawberry.field(
description="Server-generated unique token for tracking session creation."
)
name: str = strawberry.field(description="Human-readable name of the session.")
session_type: SessionTypeGQL = strawberry.field(
description="Type of the session (interactive, batch, inference)."
)
access_key: str = strawberry.field(description="Access key used to create this session.")
cluster_mode: ClusterModeGQL = strawberry.field(
description="Cluster mode for distributed sessions (single-node, multi-node)."
)
cluster_size: int = strawberry.field(description="Number of nodes in the cluster.")
priority: int = strawberry.field(description="Scheduling priority of the session.")
created_at: datetime | None = strawberry.field(
description="Timestamp when the session was created."
)
tag: str | None = strawberry.field(description="Optional user-provided tag for the session.")

Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SessionMetadataInfoGQL type mixes different concerns. It includes cluster configuration fields (cluster_mode, cluster_size) and scheduling fields (priority) that should be in separate info types for better organization. Based on the linked issue #8085, there should be a SessionClusterInfoGQL type for cluster-related fields. Consider reorganizing these fields to match the issue requirements.

Copilot uses AI. Check for mistakes.
Comment on lines 15 to 36
@@ -29,4 +31,6 @@
"ResourceOptsInput",
"ServicePortEntryGQL",
"ServicePortsGQL",
"SessionResultGQL",
"SessionTypeGQL",
]
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ClusterModeGQL enum is defined in common/types.py and is used in multiple places (session types, deployment types, kernel types), but it's not exported in the __all__ list in common/__init__.py. This type should be exported for consistency and to allow external consumers to reference it directly.

Copilot uses AI. Check for mistakes.
from typing import Any, Self

import strawberry
from strawberry.relay import Connection, Edge, Node, NodeID
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Import of 'Connection' is not used.

Suggested change
from strawberry.relay import Connection, Edge, Node, NodeID
from strawberry.relay import Edge, Node, NodeID

Copilot uses AI. Check for mistakes.
@jopemachine jopemachine force-pushed the feat/BA-3919-session-v2-schema branch from da518d1 to 725a911 Compare February 12, 2026 01:37
@jopemachine jopemachine force-pushed the feat/BA-3919-session-v2-schema branch from 9f244b9 to bf29007 Compare February 13, 2026 05:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:docs Documentations comp:manager Related to Manager component size:XL 500~ LoC

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Define SessionV2 GraphQL schema types with structured fields

3 participants