feat: Add FloatingResponse component with bubbleResponse MCP tool

Add a floating response panel that allows the agent to display messages
directly in the UI instead of through the terminal. Includes support for
info, success, warning, and error message types with auto-dismiss.
This commit is contained in:
2026-02-13 19:55:17 -06:00
parent 607527d98d
commit 86b3246fa1
7 changed files with 557 additions and 3 deletions

View File

@@ -7,16 +7,19 @@ import ComponentsDropdown from './components/ComponentsDropdown.vue'
import ToolsDropdown from './components/ToolsDropdown.vue'
import ConnectionDropdown from './components/ConnectionDropdown.vue'
import FloatingTerminal from './components/FloatingTerminal.vue'
import FloatingResponse from './components/FloatingResponse.vue'
import PwaInstallBanner from './components/PwaInstallBanner.vue'
import { initWebMCP, getWebMCP, startTokenPolling, stopTokenPolling, connectWithToken } from './services/webmcp'
import { initToolRegistry, activatePageTools, initToolsOnRefresh } from './services/toolRegistry'
import { setTerminalControls } from './services/tools/handlers/terminalHandlers'
import { setResponseControls } from './services/tools/handlers/responseHandlers'
import { useCanvasStore } from './stores/canvas'
const route = useRoute()
const router = useRouter()
const showTerminal = ref(false)
const terminalRef = ref<InstanceType<typeof FloatingTerminal> | null>(null)
const responseRef = ref<InstanceType<typeof FloatingResponse> | null>(null)
const canvasStore = useCanvasStore()
type PageName = 'home' | 'canvas' | 'components' | 'themes' | 'projects' | 'project-canvas' | 'database' | 'source' | 'terminal' | 'tools'
@@ -69,6 +72,28 @@ onMounted(async () => {
}
})
// Setup response controls for MCP tools
setResponseControls({
addMessage: (message: string, type?: 'info' | 'success' | 'warning' | 'error') => {
if (responseRef.value) {
return responseRef.value.addMessage(message, type)
}
return ''
},
removeMessage: (id: string) => {
responseRef.value?.removeMessage(id)
},
clearAll: () => {
responseRef.value?.clearAll()
},
getMessages: () => {
return responseRef.value?.getMessages() || []
},
move: (x: number, y: number) => {
responseRef.value?.move(x, y)
}
})
// Start polling for token if not connected
const webmcp = getWebMCP()
if (!webmcp?.isConnected) {
@@ -134,6 +159,9 @@ watch(() => route.name, (newPage) => {
<!-- Floating Terminal -->
<FloatingTerminal ref="terminalRef" v-model="showTerminal" />
<!-- Floating Response (Agent UI messages) -->
<FloatingResponse ref="responseRef" />
</div>
</template>