feat(mcp): add workspace sync status UI tool#1043
feat(mcp): add workspace sync status UI tool#1043Aaron ("AJ") Steers (aaronsteers) merged 43 commits into
Conversation
Co-Authored-By: AJ Steers <aj@airbyte.io>
Co-Authored-By: AJ Steers <aj@airbyte.io>
Co-Authored-By: AJ Steers <aj@airbyte.io>
Co-Authored-By: AJ Steers <aj@airbyte.io>
Co-Authored-By: AJ Steers <aj@airbyte.io>
Co-Authored-By: AJ Steers <aj@airbyte.io>
Co-Authored-By: AJ Steers <aj@airbyte.io>
Co-Authored-By: AJ Steers <aj@airbyte.io>
Adds a new Prefab UI tool that renders a sync history dashboard for an Airbyte Cloud connection. Includes: - Metric cards (total syncs, success rate, records/bytes synced) - Stacked bar chart of success/failure by date - Line charts of records and bytes over time - Detailed job history data table The tool uses the existing Cloud API (get_previous_sync_logs) and renders via the Prefab UI framework for MCP Apps-capable clients. Co-Authored-By: AJ Steers <aj@airbyte.io>
Fixes pyrefly type errors: - Tab uses 'title' not 'label' keyword - chart_data typed as list[dict[str, int | str]] to match actual data Co-Authored-By: AJ Steers <aj@airbyte.io>
Co-Authored-By: AJ Steers <aj@airbyte.io>
- Fix DataTable parameter: data= -> rows= (fixes empty table rendering) - Add model_preview_count/limit/truncated/omitted_count/render_note to agent_summary following the pattern in _registry_ui.py Co-Authored-By: AJ Steers <aj@airbyte.io>
…arts Co-Authored-By: AJ Steers <aj@airbyte.io>
Co-Authored-By: AJ Steers <aj@airbyte.io>
Three-tier control for agent text response verbosity: - verbose: full job-level data for detailed follow-up analysis - default: aggregates and key observations only - min: one-liner confirmation that the dashboard rendered All tiers explicitly state the user has already been shown the dashboard, suppressing re-summarization by the agent. Co-Authored-By: AJ Steers <aj@airbyte.io>
Co-Authored-By: AJ Steers <aj@airbyte.io>
…_ui param Co-Authored-By: AJ Steers <aj@airbyte.io>
Co-Authored-By: AJ Steers <aj@airbyte.io>
- Dashboard heading shows connection name - Subtitle links connection name to job timeline URL - Source and destination names linked to their actor URLs - Job History table wrapped in collapsible Accordion (collapsed by default) - _build_agent_text now includes connection_name in context Co-Authored-By: AJ Steers <aj@airbyte.io>
…ry' into devin/1780460965-workspace-sync-status # Conflicts: # airbyte/mcp/interactive/_sync_history_ui.py
Co-Authored-By: AJ Steers <aj@airbyte.io>
Co-Authored-By: AJ Steers <aj@airbyte.io>
…ry' into devin/1780460965-workspace-sync-status # Conflicts: # airbyte/mcp/interactive/__init__.py
|
Completed Goose Desktop runtime evidence for the pie-chart update. Goose Desktop assertions
Evidence/privacy noteA full annotated Goose Desktop recording was captured in the Devin session and will be attached in the user-facing report. I did not embed the raw recording directly in this public PR comment because it contains sandbox workspace/connection IDs. The screenshot that shows the suggested tool call is redacted. |
…space-sync-status # Conflicts: # airbyte/mcp/interactive/__init__.py
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughAdds ChangesWorkspace Sync Status Interactive Dashboard
Sequence DiagramsequenceDiagram
participant Agent as Agent/Context
participant Tool as show_workspace_sync_status
participant CloudAPI as Airbyte Cloud API
participant UIBuilder as Prefab UI Builder
participant Result as ToolResult
Agent->>Tool: call(workspace_id, max_connections, max_jobs_per_connection, recent_hours, agent_context, suppress_ui)
Tool->>CloudAPI: load workspace & list connections(limit)
CloudAPI-->>Tool: workspace + connection list
loop per connection
Tool->>CloudAPI: fetch recent sync logs(limit per connection, from_tail)
CloudAPI-->>Tool: sync logs & job statuses
Tool->>Tool: _summarize_connection -> WorkspaceConnectionSyncStatus
end
Tool->>Tool: _build_workspace_metric_summary
Tool->>UIBuilder: _build_workspace_sync_status_app (metrics, pie, table, detail)
UIBuilder-->>Tool: structured_content (Prefab view)
Tool->>Result: return bounded text + structured_content (or text-only if suppress_ui)
Result-->>Agent: ToolResult with metadata and optional UI
Estimated Code Review Effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly Related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
tests/unit_tests/test_mcp_workspace_sync_status.py (1)
88-204: ⚡ Quick winNice, thorough fixture-driven test. One optional gap: every fixture connection has exactly one completed job, so the running-job branch (
running_job_id,latest_status == "running") and thesuppress_ui=Truepath are never exercised — and those are exactly the branches tied to thelatest_display_resultquestion above. Would you consider adding a connection whose newest job is still running plus asuppress_ui=Trueassertion to lock in that behavior? wdyt?🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/unit_tests/test_mcp_workspace_sync_status.py` around lines 88 - 204, Add a fixture connection whose newest sync result has status JobStatusEnum.RUNNING and a non-null running_job_id so the running-job branch is exercised: create another _ConnectionLike with a _SyncResultLike entry having status=JobStatusEnum.RUNNING, start_time=now - timedelta(minutes=5) and set running_job_id (or latest_status == "running" field) as needed; then call show_workspace_sync_status as before and add an assertion that the returned raw_result includes the suppress_ui flag (raw_result["suppress_ui"] is True) to lock in the suppress-UI path behavior. Reference the existing test helpers/_types: _ConnectionLike, _SyncResultLike, JobStatusEnum and the function show_workspace_sync_status to locate where to add this new connection and assertion.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@airbyte/mcp/interactive/_workspace_sync_status_ui.py`:
- Around line 266-276: _current logic in _summarize_connection always picks
latest_result over latest_completed_result making the completed fallback
unreachable; change latest_display_result to prefer latest_completed_result when
the newest run is not completed: detect the terminal/completed status of
latest_result (use _sync_status_value(latest_result) or the status enum/value
used elsewhere) and if it indicates an in-progress/non-final state, set
latest_display_result = latest_completed_result, otherwise keep latest_result;
update related derived vars (latest_status, latest_records, latest_bytes,
latest_start_time) to use the selected latest_display_result.
- Around line 503-515: Pie slice colors can drift because PieChart maps palette
slots to slice index, so when status_pie_rows filters out zero-count statuses
the remaining slices shift; fix by ensuring status_pie_rows always includes all
status categories with count 0 (so indices remain stable) before passing to
PieChart (or alternatively rebuild _STATUS_PIE_CHART_STYLE to compute palette
order based on the filtered status ordering), and apply the same change for the
other PieChart usage that builds status rows elsewhere; reference
status_pie_rows, PieChart, and _STATUS_PIE_CHART_STYLE when making the change.
---
Nitpick comments:
In `@tests/unit_tests/test_mcp_workspace_sync_status.py`:
- Around line 88-204: Add a fixture connection whose newest sync result has
status JobStatusEnum.RUNNING and a non-null running_job_id so the running-job
branch is exercised: create another _ConnectionLike with a _SyncResultLike entry
having status=JobStatusEnum.RUNNING, start_time=now - timedelta(minutes=5) and
set running_job_id (or latest_status == "running" field) as needed; then call
show_workspace_sync_status as before and add an assertion that the returned
raw_result includes the suppress_ui flag (raw_result["suppress_ui"] is True) to
lock in the suppress-UI path behavior. Reference the existing test
helpers/_types: _ConnectionLike, _SyncResultLike, JobStatusEnum and the function
show_workspace_sync_status to locate where to add this new connection and
assertion.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 8d164d95-4df3-4cb3-87b7-46647e8741c8
📒 Files selected for processing (5)
AGENTS.mdairbyte/mcp/interactive/__init__.pyairbyte/mcp/interactive/_workspace_sync_status_ui.pytests/unit_tests/test_mcp_connector_registry.pytests/unit_tests/test_mcp_workspace_sync_status.py
Goose Desktop test: 360px pie chart + status filteringRan Goose Desktop against the configured sandbox workspace with Assertions:
Caveat: an earlier larger invocation ( Devin session: https://app.devin.ai/sessions/67a83acc838848baa6a5c06bf8b94744 |
Goose Desktop evidence: compact workspace layoutRan Goose Desktop 1.36.0 against the local
Caveat: the latest |
Summary
Add
show_workspace_sync_statusas a workspace-level interactive MCP dashboard now targetingmainafter the prerequisite interactive UI PRs landed. The tool fetches real Airbyte Cloud workspace connections and recent sync jobs, then renders bounded agent text plus Prefab UI content: summary metrics, a status pie chart, and a connection table with drill-down affordances.The dashboard follows the mainline MCP UI registration pattern:
show_tool naming,INTERACTIVE_UI_ANNOTATION,PrefabAppConfig,register_interactive_tools(), and imports shared sync-history formatting from_sync_history_ui.py. The pie chart pins the demo-critical colors: Succeeded = green (#22c55e), Canceled = yellow (#eab308), and No syncs = grey (#94a3b8).Drill-down is implemented with a Prefab
SendMessagebutton plus per-rowsuggested_tool_call, e.g.show_connection_sync_history(connection_id="..."), so the agent can invoke the per-connection sync-history UI from #1042. This is intended for AJ's Snowflake Summit demo workflow.Validation
origin/maininto this branch; PR is mergeable with no conflicts after the latest push.UV_PYTHON=3.10 uv run ruff format airbyte/mcp/interactive/__init__.py airbyte/mcp/interactive/_sync_history_ui.py airbyte/mcp/interactive/_workspace_sync_status_ui.py tests/unit_tests/test_mcp_workspace_sync_status.py tests/unit_tests/test_mcp_connector_registry.py— 5 files left unchanged.UV_PYTHON=3.10 uv run ruff check airbyte/mcp/interactive/__init__.py airbyte/mcp/interactive/_sync_history_ui.py airbyte/mcp/interactive/_workspace_sync_status_ui.py tests/unit_tests/test_mcp_workspace_sync_status.py tests/unit_tests/test_mcp_connector_registry.py— passed.UV_PYTHON=3.10 uv run pyrefly check airbyte/mcp/interactive/__init__.py airbyte/mcp/interactive/_sync_history_ui.py airbyte/mcp/interactive/_workspace_sync_status_ui.py tests/unit_tests/test_mcp_workspace_sync_status.py tests/unit_tests/test_mcp_connector_registry.py— 0 errors.UV_PYTHON=3.10 uv run pytest tests/unit_tests/test_mcp_workspace_sync_status.py tests/unit_tests/test_mcp_connector_registry.py -q— 27 passed.structured_contentcontains$prefab, and JSON-serialized the Prefab payload successfully.Ask for sync historyrenders the follow-up per-connection sync-history widget inline: feat(mcp): add workspace sync status UI tool #1043 (comment)Link to Devin session: https://app.devin.ai/sessions/67a83acc838848baa6a5c06bf8b94744
Requested by: Aaron ("AJ") Steers (@aaronsteers)
Summary by CodeRabbit
New Features
Documentation
Tests