feat: integrate navi_ui MCP server (card_grid + form) into master
Port the internal navi_ui MCP server from the vmkdemo branch (it never
landed on master). The server exposes render_component, which returns a
structured JSON envelope; navi/mcp/tools.py extracts metadata.ui_component
onto the role="tool" message, and the webclient renders the component
(card_grid, form) inline inside the assistant turn.

Backend
- navi/mcp/ui_server/: FastMCP server + component registry with card_grid
  and form components (pydantic-validated payloads, LLM-friendly schema docs)
- mcp_servers.d/navi_ui.json: streamable_http config, group "ui"
- config.py: navi_ui_mcp_enabled/host/port flags
- main.py: start UI server in lifespan (task + wait-for-ready + cancel)
- mcp/tools.py: navi_ui envelope parsing; "Error:" results surface as
  failed tool calls so the UI card is not green
- orchestrator.py + agent.py: run_stream(hidden=) for form submissions
  (single is_display=False, is_context=True user message)
- api/websocket.py: extract _start_agent_run helper, add form_submit
  branch that delivers submitted form values as a hidden user message
- profiles/secretary: enable navi_ui "ui" group (agent + subagent)
- .env.example: NAVI_UI_MCP_* flags
- tests/unit/mcp/test_ui_server.py

Webclient
- components/ui/{registry.js,CardGrid.vue,Form.vue}: auto-discovered
  renderers (snake_case <-> PascalCase aliasing)
- components/messages/UiComponentCard.vue: wrapper rendered in
  AssistantMessage when entry.kind === 'ui_component'
- stores/chat.js: extract ui_component from tool_call metadata in both
  live stream and history-replay paths
- composables/useWebSocket.js: note that ui_component rides tool_call
- tests/unit/components/ui/* (17 tests)
- dist rebuilt

Excluded from the vmkdemo port: the stale single-file navi/mcp/ui_server.py
duplicate, the realtor profile, and the vmk_data server (unrelated real
estate work that was interleaved with navi_ui on vmkdemo).

Co-Authored-By: Claude <noreply@anthropic.com>
1 parent de093d8 commit 9dfdb4825f9ea26483a0cd77d53347ef9caa6014
@Eugene Sukhodolskiy Eugene Sukhodolskiy authored 1 day ago
Showing 33 changed files
View
.env.example
View
mcp_servers.d/navi_ui.json 0 → 100644
View
navi/api/websocket.py
View
navi/config.py
View
navi/core/agent.py
View
navi/core/orchestrator.py
View
navi/main.py
View
navi/mcp/tools.py
View
navi/mcp/ui_server/__init__.py 0 → 100644
View
navi/mcp/ui_server/components/__init__.py 0 → 100644
View
navi/mcp/ui_server/components/base.py 0 → 100644
View
navi/mcp/ui_server/components/card_grid.py 0 → 100644
View
navi/mcp/ui_server/components/form.py 0 → 100644
View
navi/mcp/ui_server/components/registry.py 0 → 100644
View
navi/mcp/ui_server/server.py 0 → 100644
View
navi/profiles/secretary/config.json
View
tests/unit/mcp/test_ui_server.py 0 → 100644
View
webclient/dist/assets/index-Bgnk3REC.css 100644 → 0
View
webclient/dist/assets/index-CmNmE5eg.css 0 → 100644
View
webclient/dist/assets/index-DNhMM63Q.js 0 → 100644
Not supported
View
webclient/dist/assets/index-DzAywTTN.js 100644 → 0
Not supported
View
webclient/dist/index.html
View
webclient/src/components/messages/AssistantMessage.vue
View
webclient/src/components/messages/UiComponentCard.vue 0 → 100644
View
webclient/src/components/ui/CardGrid.vue 0 → 100644
View
webclient/src/components/ui/Form.vue 0 → 100644
View
webclient/src/components/ui/registry.js 0 → 100644
View
webclient/src/composables/useWebSocket.js
View
webclient/src/stores/chat.js
View
webclient/tests/unit/components/ui/CardGrid.test.js 0 → 100644
View
webclient/tests/unit/components/ui/Form.test.js 0 → 100644
View
webclient/tests/unit/components/ui/UiComponentCard.test.js 0 → 100644
View
webclient/tests/unit/components/ui/registry.test.js 0 → 100644