feat: Implement torch system via HTTP for multi-browser control

- Add /api/torch endpoints for torch state management
- Torch system uses HTTP polling instead of WebSocket
- Only browser with torch connects to MCP
- Other browsers disconnect and poll for torch state
- Auto-assign torch to first registered client
- Auto-reassign torch when holder disconnects

This approach requires no changes to WebMCP library.
This commit is contained in:
2026-02-14 16:32:52 -06:00
parent 647fb03516
commit fe99c9ff61
5 changed files with 394 additions and 115 deletions

View File

@@ -8,7 +8,8 @@ import FloatingTerminal from './components/FloatingTerminal.vue'
import FloatingResponse from './components/FloatingResponse.vue'
import FloatingVoice from './components/FloatingVoice.vue'
import PwaInstallBanner from './components/PwaInstallBanner.vue'
import { initWebMCP, getWebMCP, autoConnect, startTokenPolling, stopTokenPolling, connectWithToken } from './services/webmcp'
import { initWebMCP, getWebMCP } from './services/webmcp'
import { initTorch, destroyTorch } from './services/torch'
import { endpoints } from './config/endpoints'
import { initToolRegistry, activatePageTools, initToolsOnRefresh } from './services/toolRegistry'
import { setTerminalControls } from './services/tools/handlers/terminalHandlers'
@@ -320,29 +321,12 @@ onMounted(async () => {
})
}
// Auto-connect to WebMCP if not connected
const webmcp = getWebMCP()
if (!webmcp?.isConnected) {
// Try auto-connect (works in both dev and HTTPS via API proxy)
const connected = await autoConnect()
if (connected) {
canvasStore.showNotification('WebMCP connected!', 'success')
} else {
// Fallback to polling (for older WebMCP versions without /token endpoint)
console.log('[App] Auto-connect failed, falling back to token polling...')
startTokenPolling(async (token) => {
console.log('[App] Token received, connecting...')
const success = await connectWithToken(token)
if (success) {
canvasStore.showNotification('WebMCP connected!', 'success')
}
})
}
}
// Initialize torch system (handles MCP connection based on torch state)
await initTorch()
})
onUnmounted(() => {
stopTokenPolling()
destroyTorch()
if (statusReconnectTimeout) clearTimeout(statusReconnectTimeout)
if (processingTimeout) clearTimeout(processingTimeout)
if (sessionStartTimeout) clearTimeout(sessionStartTimeout)