|
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>
|
|---|
|
|
| .env.example |
|---|
| mcp_servers.d/navi_ui.json 0 → 100644 |
|---|
| navi/api/websocket.py |
|---|
| navi/config.py |
|---|
| navi/core/agent.py |
|---|
| navi/core/orchestrator.py |
|---|
| navi/main.py |
|---|
| navi/mcp/tools.py |
|---|
| navi/mcp/ui_server/__init__.py 0 → 100644 |
|---|
| navi/mcp/ui_server/components/__init__.py 0 → 100644 |
|---|
| navi/mcp/ui_server/components/base.py 0 → 100644 |
|---|
| navi/mcp/ui_server/components/card_grid.py 0 → 100644 |
|---|
| navi/mcp/ui_server/components/form.py 0 → 100644 |
|---|
| navi/mcp/ui_server/components/registry.py 0 → 100644 |
|---|
| navi/mcp/ui_server/server.py 0 → 100644 |
|---|
| navi/profiles/secretary/config.json |
|---|
| tests/unit/mcp/test_ui_server.py 0 → 100644 |
|---|
| webclient/dist/assets/index-Bgnk3REC.css 100644 → 0 |
|---|
| webclient/dist/assets/index-CmNmE5eg.css 0 → 100644 |
|---|
| webclient/dist/assets/index-DNhMM63Q.js 0 → 100644 |
|---|
|
Not supported
|
| webclient/dist/assets/index-DzAywTTN.js 100644 → 0 |
|---|
|
Not supported
|
| webclient/dist/index.html |
|---|
| webclient/src/components/messages/AssistantMessage.vue |
|---|
| webclient/src/components/messages/UiComponentCard.vue 0 → 100644 |
|---|
| webclient/src/components/ui/CardGrid.vue 0 → 100644 |
|---|
| webclient/src/components/ui/Form.vue 0 → 100644 |
|---|
| webclient/src/components/ui/registry.js 0 → 100644 |
|---|
| webclient/src/composables/useWebSocket.js |
|---|
| webclient/src/stores/chat.js |
|---|
| webclient/tests/unit/components/ui/CardGrid.test.js 0 → 100644 |
|---|
| webclient/tests/unit/components/ui/Form.test.js 0 → 100644 |
|---|
| webclient/tests/unit/components/ui/UiComponentCard.test.js 0 → 100644 |
|---|
| webclient/tests/unit/components/ui/registry.test.js 0 → 100644 |
|---|