Skip to content

Commit d07db08

Browse files
committed
fix session manager bugs
1 parent b1e0173 commit d07db08

File tree

7 files changed

+563
-607
lines changed

7 files changed

+563
-607
lines changed

src/context.ts

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
33
import type { Config } from "../config.d.ts";
44
import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
55
import { listResources, readResource } from "./mcp/resources.js";
6-
import { getSession, defaultSessionId } from "./sessionManager.js";
6+
import { SessionManager } from "./sessionManager.js";
77
import type { MCPTool, BrowserSession } from "./types/types.js";
88

99
/**
@@ -16,24 +16,38 @@ import type { MCPTool, BrowserSession } from "./types/types.js";
1616
export class Context {
1717
public readonly config: Config;
1818
private server: Server;
19-
public currentSessionId: string = defaultSessionId;
19+
private sessionManager: SessionManager;
2020

21-
constructor(server: Server, config: Config) {
21+
// currentSessionId is a getter that delegates to SessionManager to ensure synchronization
22+
// This prevents desync between Context and SessionManager session tracking
23+
public get currentSessionId(): string {
24+
return this.sessionManager.getActiveSessionId();
25+
}
26+
27+
constructor(server: Server, config: Config, contextId?: string) {
2228
this.server = server;
2329
this.config = config;
30+
this.sessionManager = new SessionManager(contextId);
2431
}
2532

2633
public getServer(): Server {
2734
return this.server;
2835
}
2936

37+
public getSessionManager(): SessionManager {
38+
return this.sessionManager;
39+
}
40+
3041
/**
3142
* Gets the Stagehand instance for the current session from SessionManager
3243
*/
3344
public async getStagehand(
3445
sessionId: string = this.currentSessionId,
3546
): Promise<Stagehand> {
36-
const session = await getSession(sessionId, this.config);
47+
const session = await this.sessionManager.getSession(
48+
sessionId,
49+
this.config,
50+
);
3751
if (!session) {
3852
throw new Error(`No session found for ID: ${sessionId}`);
3953
}
@@ -42,7 +56,10 @@ export class Context {
4256

4357
public async getActivePage(): Promise<BrowserSession["page"] | null> {
4458
// Get page from session manager
45-
const session = await getSession(this.currentSessionId, this.config);
59+
const session = await this.sessionManager.getSession(
60+
this.currentSessionId,
61+
this.config,
62+
);
4663
if (session && session.page && !session.page.isClosed()) {
4764
return session.page;
4865
}
@@ -53,7 +70,7 @@ export class Context {
5370
public async getActiveBrowser(
5471
createIfMissing: boolean = true,
5572
): Promise<BrowserSession["browser"] | null> {
56-
const session = await getSession(
73+
const session = await this.sessionManager.getSession(
5774
this.currentSessionId,
5875
this.config,
5976
createIfMissing,

src/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import * as dotenv from "dotenv";
22
dotenv.config();
33

4+
import { randomUUID } from "crypto";
5+
46
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
57
import { z } from "zod";
68
import type { MCPToolsArray } from "./types/types.js";
@@ -151,7 +153,8 @@ export default function ({ config }: { config: z.infer<typeof configSchema> }) {
151153
const internalConfig: Config = config as Config;
152154

153155
// Create the context, passing server instance and config
154-
const context = new Context(server.server, internalConfig);
156+
const contextId = randomUUID();
157+
const context = new Context(server.server, internalConfig, contextId);
155158

156159
server.server.registerCapabilities({
157160
resources: {

src/program.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { fileURLToPath } from "url";
66
import createServerFunction from "./index.js";
77
import { ServerList } from "./server.js";
88
import { startHttpTransport, startStdioTransport } from "./transport.js";
9-
import * as stagehandStore from "./stagehandStore.js";
109

1110
import { resolveConfig } from "./config.js";
1211

@@ -85,7 +84,8 @@ function setupExitWatchdog(serverList: ServerList) {
8584
const handleExit = async () => {
8685
setTimeout(() => process.exit(0), 15000);
8786
try {
88-
await Promise.all([stagehandStore.removeAll(), serverList.closeAll()]);
87+
// SessionManager within each server handles session cleanup
88+
await serverList.closeAll();
8989
} catch (error) {
9090
console.error("Error during cleanup:", error);
9191
}

0 commit comments

Comments
 (0)