#!/usr/bin/env node /** * AgentBay SDK - Context Mount Example * * This example demonstrates the Context Mount (direct-mount persistence) feature: * - Mounting a context at session creation time * - Write-through persistence (no manual sync needed) * - Cross-session data persistence via mount * - Dynamic mounting using bind() */ import type { CreateSessionParams } from 'wuying-agentbay-sdk'; import { AgentBay, BetaContextMount, logError } from 'wuying-agentbay-sdk'; async function main(): Promise { console.log('๐Ÿ“Œ AgentBay Context Mount Example'); const apiKey = process.env.AGENTBAY_API_KEY || ''; if (!apiKey) { console.log('โŒ Please set AGENTBAY_API_KEY environment variable'); process.exit(1); } const agentBay = new AgentBay({ apiKey }); try { await contextMountDemo(agentBay); } catch (error) { console.log(`โŒ Example execution failed: ${error}`); logError('Error:', error); } console.log('โœ… Context mount example completed'); } async function contextMountDemo(agentBay: AgentBay): Promise { console.log('\n๐Ÿ”„ === Context Mount Demonstration ==='); // Step 1: Create a context for persistent storage console.log('\n๐Ÿ“ฆ Step 1: Creating context for persistent storage...'); const contextName = `mount-demo-${Date.now()}`; const contextResult = await agentBay.context.get(contextName, true); if (!contextResult.success) { console.log(`โŒ Context creation failed: ${contextResult.errorMessage}`); return; } const context = contextResult.context; console.log(`โœ… Context created: ${context.id} (name: ${context.name})`); // Step 2: Create first session with context mount // BetaContextMount requires imageId="aio-ubuntu-2404" console.log('\n๐Ÿ”ง Step 2: Creating first session with context mount...'); const contextMount = new BetaContextMount(context.id, '/tmp/mounted_data'); const imageId = 'aio-ubuntu-2404'; const params1: CreateSessionParams = { imageId, betaContextMount: [contextMount] }; const session1Result = await agentBay.create(params1); if (!session1Result.success) { console.log(`โŒ First session creation failed: ${session1Result.errorMessage}`); return; } const session1 = session1Result.session; console.log(`โœ… First session created: ${session1.sessionId}`); const session1Id = session1.sessionId; try { // Step 3: Write data โ€” persisted immediately via write-through console.log('\n๐Ÿ’พ Step 3: Writing data (write-through persistence)...'); await session1.command.executeCommand('mkdir -p /tmp/mounted_data/config'); const configData = { app: 'mount-demo', version: '1.0', session: session1.sessionId }; const configResult = await session1.fileSystem.writeFile( '/tmp/mounted_data/config/app.json', JSON.stringify(configData, null, 2) ); if (configResult.success) { console.log('โœ… Config file written (persisted immediately)'); } else { console.log(`โŒ Failed to write config: ${configResult.errorMessage}`); } const dataResult = await session1.fileSystem.writeFile( '/tmp/mounted_data/notes.txt', 'This data is persisted via Context Mount.\nNo manual sync() call needed!' ); if (dataResult.success) { console.log('โœ… Data file written (persisted immediately)'); } else { console.log(`โŒ Failed to write data: ${dataResult.errorMessage}`); } // List files console.log('\n๐Ÿ“‹ Files in mounted path:'); const listResult = await session1.command.executeCommand('find -L /tmp/mounted_data -type f'); if (listResult.success) { console.log(listResult.output); } } finally { // No sync needed โ€” data is already persisted console.log('\n๐Ÿงน Deleting first session (no sync needed for mount)...'); const deleteResult1 = await agentBay.delete(session1); if (deleteResult1.success) { console.log('โœ… First session deleted'); } else { console.log(`โŒ First session deletion failed: ${deleteResult1.errorMessage}`); } } // Step 4: Create second session to verify cross-session persistence console.log('\n๐Ÿ”ง Step 4: Creating second session to verify persistence...'); const params2: CreateSessionParams = { imageId, betaContextMount: [contextMount] }; const session2Result = await agentBay.create(params2); if (!session2Result.success) { console.log(`โŒ Second session creation failed: ${session2Result.errorMessage}`); return; } const session2 = session2Result.session; console.log(`โœ… Second session created: ${session2.sessionId}`); try { console.log('\n๐Ÿ” Step 5: Verifying persisted data in second session...'); const filesToCheck = [ '/tmp/mounted_data/config/app.json', '/tmp/mounted_data/notes.txt', ]; let filesFound = 0; for (const filePath of filesToCheck) { console.log(`\n๐Ÿ” Checking: ${filePath}`); const readResult = await session2.fileSystem.readFile(filePath); if (readResult.success) { console.log('โœ… File found!'); const preview = readResult.content.substring(0, 120); console.log(` ๐Ÿ“„ Content: ${preview}`); filesFound++; } else { console.log(`โŒ Not found: ${readResult.errorMessage}`); } } // Step 6: Dynamic mount demo (bind) console.log('\n๐Ÿ”ง Step 6: Dynamic mount using bind()...'); const dynamicCtxResult = await agentBay.context.get(`dynamic-mount-${Date.now()}`, true); if (dynamicCtxResult.success) { const dynamicMount = new BetaContextMount(dynamicCtxResult.context.id, '/tmp/dynamic_mount'); const bindResult = await session2.context.bind(dynamicMount); if (bindResult.success) { console.log('โœ… Dynamic mount bound successfully'); const writeResult = await session2.fileSystem.writeFile( '/tmp/dynamic_mount/dynamic.txt', 'Dynamically mounted data!' ); if (writeResult.success) { console.log('โœ… Wrote to dynamically mounted path'); } } else { console.log(`โŒ Dynamic bind failed: ${bindResult.errorMessage}`); } // Clean up dynamic context await agentBay.context.delete(dynamicCtxResult.context); } // Summary console.log('\n๐Ÿ“Š === Persistence Summary ==='); console.log(`โœ… Context ID: ${context.id}`); console.log(`โœ… Session 1: ${session1Id} (deleted)`); console.log(`โœ… Session 2: ${session2.sessionId} (active)`); console.log(`โœ… Files found: ${filesFound}/${filesToCheck.length}`); if (filesFound === filesToCheck.length) { console.log('๐ŸŽ‰ Context Mount persistence verification SUCCESSFUL!'); } else { console.log('โš ๏ธ Some files not found โ€” mount may still be initializing'); } } finally { console.log('\n๐Ÿงน Cleaning up second session...'); const deleteResult2 = await agentBay.delete(session2); if (deleteResult2.success) { console.log('โœ… Second session deleted'); } } // Clean up context console.log('\n๐Ÿงน Cleaning up context...'); const deleteCtxResult = await agentBay.context.delete(context); if (deleteCtxResult.success) { console.log(`โœ… Context deleted`); } } if (require.main === module) { main().catch(error => { logError('Error in main execution:', error); process.exit(1); }); }