1
1
import { z } from "zod" ;
2
- // Import ToolResult and adjust Tool type usage
3
- import type { Tool , ToolSchema , ToolContext , ToolResult } from "./tool.js" ; // Assuming these exist
4
- import { createSuccessResult , createErrorResult } from "./toolUtils.js" ; // Assuming these exist
2
+ import type { Tool , ToolSchema , ToolResult } from "./tool.js" ; // Assuming these exist
5
3
import type { Context } from "../context.js" ; // For handle signature
6
4
import type { ToolActionResult } from "../context.js" ; // For action return type
7
- import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js" ;
8
- // Remove Browserbase SDK import if not needed directly anymore
9
- // import Browserbase from "@browserbasehq/sdk";
10
- import dotenv from "dotenv" ;
11
5
12
6
// Import SessionManager functions
13
7
import {
@@ -17,8 +11,6 @@ import {
17
11
type BrowserSession ,
18
12
} from "../sessionManager.js" ;
19
13
20
- // Remove redundant dotenv config call
21
- // dotenv.config();
22
14
23
15
// --- Tool: Create Session ---
24
16
const CreateSessionInputSchema = z . object ( {
@@ -54,13 +46,10 @@ async function handleCreateSession(
54
46
if ( params . sessionId ) {
55
47
targetSessionId = params . sessionId ;
56
48
process . stderr . write (
57
- `[tool.createSession] Attempting to create/assign session with specified ID: ${ targetSessionId } \n `
49
+ `[tool.createSession] Attempting to create/assign session with specified ID: ${ targetSessionId } `
58
50
) ;
59
51
} else {
60
52
targetSessionId = defaultSessionId ;
61
- process . stderr . write (
62
- `[tool.createSession] Attempting to create/ensure default session (ID: ${ targetSessionId } )\n`
63
- ) ;
64
53
}
65
54
66
55
let session : BrowserSession ;
@@ -78,9 +67,11 @@ async function handleCreateSession(
78
67
79
68
context . currentSessionId = targetSessionId ;
80
69
process . stderr . write (
81
- `[tool.createSession ] Successfully ensured session. Internal ID: ${ targetSessionId } , Actual ID: ${ session . sessionId } \n `
70
+ `[tool.connected ] Successfully connected to Browserbase session. Internal ID: ${ targetSessionId } , Actual ID: ${ session . sessionId } `
82
71
) ;
83
72
73
+ process . stderr . write ( `[SessionManager] Browserbase Live Debugger URL: https://www.browserbase.com/sessions/${ session . sessionId } ` ) ;
74
+
84
75
return {
85
76
content : [
86
77
{
@@ -93,7 +84,7 @@ async function handleCreateSession(
93
84
process . stderr . write (
94
85
`[tool.createSession] Action failed: ${
95
86
error . message || String ( error )
96
- } \n `
87
+ } `
97
88
) ;
98
89
// Re-throw to be caught by Context.run's error handling for actions
99
90
throw new Error (
@@ -120,5 +111,127 @@ const createSessionTool: Tool<typeof CreateSessionInputSchema> = {
120
111
handle : handleCreateSession ,
121
112
} ;
122
113
123
- // Export the single tool object as default
124
- export default createSessionTool ;
114
+ // --- Tool: Close Session ---
115
+ const CloseSessionInputSchema = z . object ( {
116
+ random_string : z
117
+ . string ( )
118
+ . optional ( )
119
+ . describe ( "Dummy parameter to ensure consistent tool call format." ) ,
120
+ } ) ;
121
+ type CloseSessionInput = z . infer < typeof CloseSessionInputSchema > ;
122
+
123
+ const closeSessionSchema : ToolSchema < typeof CloseSessionInputSchema > = {
124
+ name : "browserbase_session_close" ,
125
+ description :
126
+ "Closes the current Browserbase session by disconnecting the Playwright browser. This will terminate the recording for the session." ,
127
+ inputSchema : CloseSessionInputSchema ,
128
+ } ;
129
+
130
+ async function handleCloseSession (
131
+ context : Context ,
132
+ _params : CloseSessionInput
133
+ ) : Promise < ToolResult > {
134
+ const code = [ `// Attempting to close the current Browserbase session.` ] ;
135
+
136
+ const action = async ( ) : Promise < ToolActionResult > => {
137
+ // Store the current session ID before it's potentially changed.
138
+ // This allows us to reference the original session ID later if needed.
139
+ const previousSessionId = context . currentSessionId ; // Capture the ID before any changes
140
+ let browser : BrowserSession [ "browser" ] | null = null ;
141
+ let browserClosedSuccessfully = false ;
142
+ let browserCloseErrorMessage = "" ;
143
+
144
+ // Step 1: Attempt to get the active browser instance
145
+ try {
146
+ // This call might be associated with 'previousSessionId' (which could be default or specific)
147
+ browser = await context . getActiveBrowser ( ) ;
148
+ } catch ( error : any ) {
149
+ process . stderr . write (
150
+ `[tool.closeSession] Error retrieving active browser (session ID was ${ previousSessionId || 'default/unknown' } ): ${ error . message || String ( error ) } `
151
+ ) ;
152
+ // If we can't even get the browser, we can't close it.
153
+ // We will still proceed to reset context.
154
+ }
155
+
156
+ // Step 2: If a browser instance was retrieved, attempt to close it
157
+ if ( browser ) {
158
+ try {
159
+ process . stderr . write (
160
+ `[tool.closeSession] Attempting to close browser for session: ${ previousSessionId || 'default (actual might differ)' } `
161
+ ) ;
162
+ await browser . close ( ) ;
163
+ browserClosedSuccessfully = true ;
164
+ process . stderr . write (
165
+ `[tool.closeSession] Browser connection for session (was ${ previousSessionId } ) closed.`
166
+ ) ;
167
+
168
+ process . stderr . write (
169
+ `[tool.closeSession] View session replay at https://www.browserbase.com/sessions/${ previousSessionId } `
170
+ ) ;
171
+
172
+ } catch ( error : any ) {
173
+ browserCloseErrorMessage = error . message || String ( error ) ;
174
+ process . stderr . write (
175
+ `[tool.closeSession] Error during browser.close() for session (was ${ previousSessionId } ): ${ browserCloseErrorMessage } `
176
+ ) ;
177
+ }
178
+ } else {
179
+ process . stderr . write (
180
+ `[tool.closeSession] No active browser instance found to close. (Session ID in context was: ${ previousSessionId || 'default/unknown' } ).`
181
+ ) ;
182
+ }
183
+
184
+ // Step 3: Always reset the context's current session ID to default
185
+ // and clear snapshot if the previous session was a specific one.
186
+ const oldContextSessionId = context . currentSessionId ; // This should effectively be 'previousSessionId'
187
+ context . currentSessionId = defaultSessionId ;
188
+ if ( oldContextSessionId && oldContextSessionId !== defaultSessionId ) {
189
+ context . clearLatestSnapshot ( ) ;
190
+ process . stderr . write (
191
+ `[tool.closeSession] Snapshot cleared for previous session: ${ oldContextSessionId } .`
192
+ ) ;
193
+ }
194
+ process . stderr . write (
195
+ `[tool.closeSession] Session context reset to default. Previous context session ID was ${ oldContextSessionId || 'default/unknown' } .`
196
+ ) ;
197
+
198
+ // Step 4: Determine the result message
199
+ if ( browser && ! browserClosedSuccessfully ) { // An attempt was made to close, but it failed
200
+ throw new Error (
201
+ `Failed to close the Browserbase browser (session ID in context was ${ previousSessionId || 'default/unknown' } ). Error: ${ browserCloseErrorMessage } . Session context has been reset to default.`
202
+ ) ;
203
+ }
204
+
205
+ if ( browserClosedSuccessfully ) { // Browser was present and closed
206
+ let successMessage = `Browserbase session (associated with context ID ${ previousSessionId || 'default' } ) closed successfully. Context reset to default.` ;
207
+ if ( previousSessionId && previousSessionId !== defaultSessionId ) {
208
+ successMessage += ` If this was a uniquely named session (${ previousSessionId } ), view replay (if available) at https://browserbase.com/sessions/${ previousSessionId } ` ;
209
+ }
210
+ return { content : [ { type : "text" , text : successMessage } ] } ;
211
+ }
212
+
213
+ // No browser was found, or browser was null initially.
214
+ let infoMessage = "No active browser instance was found to close. Session context has been reset to default." ;
215
+ if ( previousSessionId && previousSessionId !== defaultSessionId ) {
216
+ // This means a specific session was in context, but no browser for it.
217
+ infoMessage = `No active browser found for session ID '${ previousSessionId } ' in context. The context has been reset to default.` ;
218
+ }
219
+ return { content : [ { type : "text" , text : infoMessage } ] } ;
220
+ } ;
221
+
222
+ return {
223
+ action : action ,
224
+ code : code ,
225
+ captureSnapshot : false ,
226
+ waitForNetwork : false ,
227
+ } ;
228
+ }
229
+
230
+ const closeSessionTool : Tool < typeof CloseSessionInputSchema > = {
231
+ capability : "core" ,
232
+ schema : closeSessionSchema ,
233
+ handle : handleCloseSession ,
234
+ } ;
235
+
236
+ // Export an array of the tool objects as default
237
+ export default [ createSessionTool , closeSessionTool ] ;
0 commit comments