Skip to content

Add SessionManager behind sessionManagementV2 flag (Phase 2)#3906

Merged
yrobla merged 2 commits intomainfrom
issue-3866
Mar 3, 2026
Merged

Add SessionManager behind sessionManagementV2 flag (Phase 2)#3906
yrobla merged 2 commits intomainfrom
issue-3866

Conversation

@yrobla
Copy link
Copy Markdown
Contributor

@yrobla yrobla commented Feb 20, 2026

Implement RFC THV-0038 Phase 2: a vmcpSessionManager that bridges the MultiSession/MultiSessionFactory domain logic to the MCP SDK's SessionIdManager interface. The feature is gated behind a sessionManagementV2 config flag (default false), leaving the existing code path completely unchanged when disabled.

Key changes:

  • pkg/vmcp/server/session_manager.go: new vmcpSessionManager with two-phase creation — Generate() stores a placeholder, CreateSession() (called from OnRegisterSession hook) replaces it with a fully-formed MultiSession via MakeSessionWithID(). Terminate() calls Close() before deleting to release backend connections. GetAdaptedTools() returns SDK tools with session-scoped handlers delegating to CallTool().
  • pkg/vmcp/session/factory.go: add MakeSessionWithID() to the MultiSessionFactory interface; refactor MakeSession to share a private makeSession() implementation.
  • pkg/transport/session/manager.go: add ReplaceSession() upsert to swap a placeholder with a fully-formed MultiSession.
  • pkg/vmcp/config/config.go: add SessionManagementV2 bool field.
  • pkg/vmcp/server/server.go: wire vmcpSessionManager when flag+factory are set; add handleSessionRegistrationV2() hook handler.
  • pkg/vmcp/discovery/middleware.go: skip Phase 1 routing-table reconstruction for Phase 2 MultiSession sessions.
  • Tests: unit tests for all new methods, ReplaceSession coverage in transport/session, and an end-to-end integration test covering initialize, tool call routing, and the old-path-unaffected case.

Closes: #3866

Large PR Justification

This is an atomic PR that covers an isolated functionality, and includes complete tests. Cannot be split.

@github-actions github-actions bot added the size/XL Extra large PR: 1000+ lines changed label Feb 20, 2026
Copy link
Copy Markdown
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Large PR Detected

This PR exceeds 1000 lines of changes and requires justification before it can be reviewed.

How to unblock this PR:

Add a section to your PR description with the following format:

## Large PR Justification

[Explain why this PR must be large, such as:]
- Generated code that cannot be split
- Large refactoring that must be atomic
- Multiple related changes that would break if separated
- Migration or data transformation

Alternative:

Consider splitting this PR into smaller, focused changes (< 1000 lines each) for easier review and reduced risk.

See our Contributing Guidelines for more details.


This review will be automatically dismissed once you add the justification section.

@yrobla yrobla requested a review from Copilot February 20, 2026 11:14
@github-actions github-actions bot added size/XL Extra large PR: 1000+ lines changed and removed size/XL Extra large PR: 1000+ lines changed labels Feb 20, 2026
Copy link
Copy Markdown
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

Implements RFC THV-0038 Phase 2 by introducing a feature-flagged vmcpSessionManager that bridges MultiSession/MultiSessionFactory to the MCP SDK SessionIdManager, enabling session-scoped backend client lifecycle while keeping the existing path unchanged when disabled.

Changes:

  • Add vmcpSessionManager behind SessionManagementV2 to generate/validate/terminate sessions and register per-session tools.
  • Extend MultiSessionFactory with MakeSessionWithID() and add transportsession.Manager.ReplaceSession() to support two-phase session creation.
  • Update discovery middleware to bypass Phase 1 routing-table reconstruction for Phase 2 MultiSession sessions; add unit + integration tests.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
pkg/vmcp/server/session_manager.go New Phase 2 session manager (Generate/CreateSession/Validate/Terminate + tool adaptation).
pkg/vmcp/server/server.go Wires Phase 2 manager behind SessionManagementV2 and registers session tools in OnRegisterSession.
pkg/vmcp/session/factory.go Adds MakeSessionWithID() and refactors shared makeSession() implementation.
pkg/transport/session/manager.go Adds ReplaceSession() upsert for swapping placeholder → real session.
pkg/vmcp/discovery/middleware.go Skips Phase 1 routing-table reconstruction when the stored session is a MultiSession.
pkg/vmcp/config/config.go Adds sessionManagementV2 operational config flag.
pkg/vmcp/server/session_manager_test.go Unit tests for Phase 2 session manager behavior.
pkg/transport/session/manager_test.go Unit tests for ReplaceSession() behavior.
pkg/vmcp/server/session_management_v2_integration_test.go End-to-end tests for v2 initialize + tool routing and “old path unaffected” case.

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

@github-actions github-actions bot added size/XL Extra large PR: 1000+ lines changed and removed size/XL Extra large PR: 1000+ lines changed labels Feb 20, 2026
@github-actions github-actions bot dismissed their stale review February 20, 2026 11:22

Large PR justification has been provided. Thank you!

@github-actions
Copy link
Copy Markdown
Contributor

✅ Large PR justification has been provided. The size review has been dismissed and this PR can now proceed with normal review.

@codecov
Copy link
Copy Markdown

codecov bot commented Feb 20, 2026

Codecov Report

❌ Patch coverage is 85.46099% with 41 lines in your changes missing coverage. Please review.
✅ Project coverage is 68.04%. Comparing base (06663f0) to head (bd00b45).
⚠️ Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
pkg/vmcp/server/server.go 60.37% 17 Missing and 4 partials ⚠️
pkg/vmcp/server/sessionmanager/session_manager.go 88.40% 11 Missing and 5 partials ⚠️
pkg/vmcp/discovery/middleware.go 84.00% 3 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3906      +/-   ##
==========================================
+ Coverage   67.95%   68.04%   +0.08%     
==========================================
  Files         435      436       +1     
  Lines       43988    44221     +233     
==========================================
+ Hits        29893    30088     +195     
- Misses      11753    11785      +32     
- Partials     2342     2348       +6     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions github-actions bot added size/XL Extra large PR: 1000+ lines changed and removed size/XL Extra large PR: 1000+ lines changed labels Feb 20, 2026
@yrobla yrobla requested a review from Copilot February 20, 2026 12:00
Copy link
Copy Markdown
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

Copilot reviewed 17 out of 17 changed files in this pull request and generated 6 comments.


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

@github-actions github-actions bot added size/XL Extra large PR: 1000+ lines changed and removed size/XL Extra large PR: 1000+ lines changed labels Feb 20, 2026
@github-actions github-actions bot added size/XL Extra large PR: 1000+ lines changed and removed size/XL Extra large PR: 1000+ lines changed labels Mar 2, 2026
jerm-dro
jerm-dro previously approved these changes Mar 2, 2026
Copy link
Copy Markdown
Contributor

@jerm-dro jerm-dro left a comment

Choose a reason for hiding this comment

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

Thanks for all the testing! No major comments, but some questions to make sure I understand. I also have some suggestions you may want to address in subsequent PRs. Approving so you can continue to make progress.

Implement RFC THV-0038 Phase 2: a vmcpSessionManager that bridges
the MultiSession/MultiSessionFactory domain logic to the MCP SDK's
SessionIdManager interface. The feature is gated behind a
sessionManagementV2 config flag (default false), leaving the
existing code path completely unchanged when disabled.

Key changes:
  - pkg/vmcp/server/session_manager.go: new vmcpSessionManager with
    two-phase creation — Generate() stores a placeholder, CreateSession()
    (called from OnRegisterSession hook) replaces it with a fully-formed
    MultiSession via MakeSessionWithID(). Terminate() calls Close() before
    deleting to release backend connections. GetAdaptedTools() returns
    SDK tools with session-scoped handlers delegating to CallTool().
  - pkg/vmcp/session/factory.go: add MakeSessionWithID() to the
    MultiSessionFactory interface; refactor MakeSession to share a private
    makeSession() implementation.
  - pkg/transport/session/manager.go: add ReplaceSession() upsert to
    swap a placeholder with a fully-formed MultiSession.
  - pkg/vmcp/config/config.go: add SessionManagementV2 bool field.
  - pkg/vmcp/server/server.go: wire vmcpSessionManager when flag+factory
    are set; add handleSessionRegistrationV2() hook handler.
  - pkg/vmcp/discovery/middleware.go: skip Phase 1 routing-table
    reconstruction for Phase 2 MultiSession sessions.
  - Tests: unit tests for all new methods, ReplaceSession coverage in
    transport/session, and an end-to-end integration test covering
    initialize, tool call routing, and the old-path-unaffected case.

Closes: #3866
@github-actions github-actions bot added size/XL Extra large PR: 1000+ lines changed and removed size/XL Extra large PR: 1000+ lines changed labels Mar 3, 2026
@yrobla yrobla requested review from Copilot and jerm-dro March 3, 2026 08:57
@github-actions github-actions bot added size/XL Extra large PR: 1000+ lines changed and removed size/XL Extra large PR: 1000+ lines changed labels Mar 3, 2026
Copy link
Copy Markdown
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

Copilot reviewed 25 out of 25 changed files in this pull request and generated 3 comments.


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

@github-actions github-actions bot added size/XL Extra large PR: 1000+ lines changed and removed size/XL Extra large PR: 1000+ lines changed labels Mar 3, 2026
@github-actions github-actions bot added size/XL Extra large PR: 1000+ lines changed and removed size/XL Extra large PR: 1000+ lines changed labels Mar 3, 2026
@yrobla yrobla requested a review from Copilot March 3, 2026 09:40
Copy link
Copy Markdown
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

Copilot reviewed 25 out of 25 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (1)

pkg/vmcp/conversion/content.go:48

  • ConvertMCPContent() defines contentTypeResource but still hard-codes "resource" in several return values. Using the constant consistently would avoid drift if the string ever changes and keeps the conversion symmetric with ToMCPContent().
	if res, ok := mcp.AsEmbeddedResource(content); ok {
		if textRes, ok := mcp.AsTextResourceContents(res.Resource); ok {
			return vmcp.Content{Type: "resource", Text: textRes.Text, URI: textRes.URI, MimeType: textRes.MIMEType}
		}
		if blobRes, ok := mcp.AsBlobResourceContents(res.Resource); ok {
			return vmcp.Content{Type: "resource", Data: blobRes.Blob, URI: blobRes.URI, MimeType: blobRes.MIMEType}
		}
		slog.Debug("Embedded resource has unknown resource contents type", "type", fmt.Sprintf("%T", res.Resource))
		return vmcp.Content{Type: "resource"}
	}

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

@github-actions github-actions bot added size/XL Extra large PR: 1000+ lines changed and removed size/XL Extra large PR: 1000+ lines changed labels Mar 3, 2026
Copy link
Copy Markdown
Member

@aponcedeleonch aponcedeleonch left a comment

Choose a reason for hiding this comment

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

Great work on this PR! The two-phase session creation pattern is clean, race conditions are thoughtfully handled with the double-check pattern, and the test coverage is thorough. Approving with two minor suggestions that can be addressed in a follow-up.

@yrobla yrobla merged commit a6ccdf1 into main Mar 3, 2026
64 of 65 checks passed
@yrobla yrobla deleted the issue-3866 branch March 3, 2026 11:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/XL Extra large PR: 1000+ lines changed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[vMCP] Implement SessionManager and wire up behind feature flag (Phase 2)

5 participants