Skip to content

refactor: Extract reusable dashboard AI tools - #650

Merged
ilyabo merged 3 commits into
mainfrom
extract-reusable-dashboard-ai-tools
May 21, 2026
Merged

ilyabo merged 3 commits into
mainfrom
extract-reusable-dashboard-ai-tools

Conversation

@ilyabo

@ilyabo ilyabo commented May 20, 2026 •

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • Refactor

    • Consolidated dashboard AI features into a reusable, adapter-driven package and simplified UI wiring.
  • Bug Fixes

    • Improved validation and clearer failure responses when operating on dashboards or panels.
  • Tests

    • Added comprehensive tests covering dashboard AI workflows: artifact creation, table resolution, and panel operations.
  • Documentation

    • Expanded README with a “Dashboard AI Tools” section and adapter examples.
  • Chores

    • Added package export map for the mosaic package.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 20, 2026 •

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 63be4614-654d-4410-bdce-c725953977a6

📥 Commits

Reviewing files that changed from the base of the PR and between 795b06c and e14d3d5.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (11)
  • apps/sqlrooms-cli-ui/package.json
  • apps/sqlrooms-cli-ui/src/createDashboardAgent.ts
  • apps/sqlrooms-cli-ui/src/createDashboardAiTools.ts
  • apps/sqlrooms-cli-ui/src/createDashboardToolDeps.ts
  • apps/sqlrooms-cli-ui/src/dashboardAgentInstructions.ts
  • knip.json
  • packages/mosaic/README.md
  • packages/mosaic/__tests__/dashboard-ai.test.ts
  • packages/mosaic/package.json
  • packages/mosaic/src/ai.ts
  • packages/mosaic/src/chart-types/remove-panel-tool.ts
💤 Files with no reviewable changes (2)
  • apps/sqlrooms-cli-ui/package.json
  • apps/sqlrooms-cli-ui/src/dashboardAgentInstructions.ts
✅ Files skipped from review due to trivial changes (1)
  • packages/mosaic/README.md

📝 Walkthrough

Walkthrough

Extracts dashboard AI tooling into @sqlrooms/mosaic/ai, defines adapter and public contracts, implements reusable deps/tools/agent, adds app-side adapter and thin delegations, introduces tests and package exports, updates README, tightens remove-panel validation, and removes an app dependency and minor config formatting.

Changes

Dashboard AI Extraction to Reusable Library

Layer / File(s) Summary
Mosaic AI public contracts and adapter types
packages/mosaic/src/ai.ts
Defines TypeScript interfaces and types for adapter/store contracts and agent/tool result shapes.
Instructions and Zod schemas
packages/mosaic/src/ai.ts
Exports LLM instruction constants and Zod schemas for dashboard-artifact creation and agent inputs.
Table/column helper utilities
packages/mosaic/src/ai.ts
Provides helpers to filter tables with column metadata and format available-table information for prompts.
Reusable artifact/table resolution & deps
packages/mosaic/src/ai.ts
Implements artifact resolution/creation and table selection logic and wires panel CRUD and current-artifact handling to the adapter.
Reusable dashboard AI toolset
packages/mosaic/src/ai.ts
Implements createDashboardAiTools to assemble artifact creation, chart tools, profiler/text/list/remove panel tools using shared deps.
Agent prompt and metadata helpers
packages/mosaic/src/ai.ts
Builds table-aware prompts, validates tables, ensures/creates dashboard artifacts, and computes execution metadata.
Reusable dashboard agent tool
packages/mosaic/src/ai.ts
Implements createDashboardAgentTool that configures and runs a ToolLoopAgent and returns structured DashboardAgentResult.
App-side adapter implementation and delegations
apps/sqlrooms-cli-ui/src/createDashboardToolDeps.ts, apps/sqlrooms-cli-ui/src/*
Adds createDashboardAiAdapter(store); rewrites createDashboardToolDeps to delegate to the reusable implementation; refactors createDashboardAiTools and dashboardAgentTool into thin wrappers that call the mosaic helpers.
App changes and minor packaging
apps/sqlrooms-cli-ui/package.json, knip.json
Removes direct ai dependency from the app and reformats knip.json arrays (minor config formatting).
Package exports, tests, docs, and validation
packages/mosaic/package.json, packages/mosaic/__tests__/dashboard-ai.test.ts, packages/mosaic/README.md, packages/mosaic/src/chart-types/remove-panel-tool.ts
Adds exports map, comprehensive Jest tests for deps/tools, new README section for Dashboard AI Tools, and adds dashboard/panel existence checks to remove-panel tool.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • sqlrooms/sqlrooms#634: Introduced the initial in-app dashboardAgentTool and instructions that are refactored into the reusable library here.
  • sqlrooms/sqlrooms#638: Related to dashboard tool-deps wiring and propagation of data-point limits through DashboardToolDeps.
  • sqlrooms/sqlrooms#646: Changed primary run-context artifact handling which this refactor integrates via adapter/run-context helpers.

Suggested reviewers

  • dmitriy-kostianetskiy
  • lixun910

Poem

🐇 I stitched a library from app-held thread,
Agents hop where adapters led,
Tests drum paws, docs hum the tune,
Panels bloom beneath the moon,
Hooray — the rabbit code parade!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'refactor: Extract reusable dashboard AI tools' accurately describes the main change—extracting dashboard AI tool logic from app-specific files into reusable utilities in the Mosaic package.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch extract-reusable-dashboard-ai-tools

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 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 `@apps/sqlrooms-cli-ui/src/createDashboardAgent.ts`:
- Around line 12-22: The getModel implementation always uses
createOpenAICompatible which breaks Anthropic; update getModel in
createDashboardAgent.ts to first attempt provider-specific model creation (e.g.,
call the same getCustomModel hook used in chatTransport.ts) using the resolved
provider and baseURL from
state.ai.getBaseUrlFromSettings()/state.ai.getApiKeyFromSettings(), and only if
that returns null/undefined fall back to createOpenAICompatible(...). Use the
existing variables currentSession, provider and modelId to pass into the
provider-specific hook and maintain the existing fallback behavior.

In `@packages/mosaic/src/ai.ts`:
- Around line 136-138: The createQueryTools contract allows arbitrary tool keys
which can break callers that expect a stable "query" tool
(DASHBOARD_AGENT_INSTRUCTIONS and calculateAgentMetadata hardcode "query" and
queriesRun relies on it); update the type/signature of createQueryTools to
require an object with a "query" Tool key (e.g., make it return { query: Tool }
or Record<'query', Tool>), update any call sites to supply the "query" key, and
adjust related code paths that reference createQueryTools to use the guaranteed
"query" tool rather than arbitrary names.
- Around line 612-678: Declare dashboardId in the outer scope before the try
block (e.g., let dashboardId = '') so it can be referenced in the catch, assign
it the value returned by getOrCreateDashboard inside the try, and in the catch
return that dashboardId instead of an empty string; update the catch return
object (success: false) to include dashboardId (and optionally any partial
metadata if available) so callers retain the handle to partially created/updated
dashboards.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: e675ca33-bcdf-43c8-933c-653ce03ee285

📥 Commits

Reviewing files that changed from the base of the PR and between 94ca393 and b2d1d31.

📒 Files selected for processing (9)
  • apps/sqlrooms-cli-ui/src/createDashboardAgent.ts
  • apps/sqlrooms-cli-ui/src/createDashboardAiTools.ts
  • apps/sqlrooms-cli-ui/src/createDashboardToolDeps.ts
  • apps/sqlrooms-cli-ui/src/dashboardAgentInstructions.ts
  • packages/mosaic/README.md
  • packages/mosaic/__tests__/dashboard-ai.test.ts
  • packages/mosaic/package.json
  • packages/mosaic/src/ai.ts
  • packages/mosaic/src/chart-types/remove-panel-tool.ts
💤 Files with no reviewable changes (1)
  • apps/sqlrooms-cli-ui/src/dashboardAgentInstructions.ts

Comment on lines +12 to +22
getModel: ({state}) => {
const currentSession = state.ai.getCurrentSession();
const provider = currentSession?.modelProvider || 'openai';
const modelId = currentSession?.model || 'gpt-4.1';

return createOpenAICompatible({
apiKey: state.ai.getApiKeyFromSettings(),
name: provider || '',
baseURL:
state.ai.getBaseUrlFromSettings() || 'https://api.openai.com/v1',
}).chatModel(modelId);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== modelProvider usages and AI settings helpers ==="
rg -n -C 3 --type ts --type tsx '\bmodelProvider\b|\bgetBaseUrlFromSettings\s*\(|\bgetApiKeyFromSettings\s*\('

echo
echo "=== model factory usage across the repo ==="
rg -n -C 3 --type ts --type tsx 'createOpenAICompatible|createAnthropic|createGoogle|createOpenRouter|chatModel\(|languageModel\('

Repository: sqlrooms/sqlrooms

Length of output: 160


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Explore repository structure ==="
fd -t f "createDashboardAgent" --max-one-result

echo
echo "=== Search for modelProvider, getBaseUrlFromSettings, getApiKeyFromSettings ==="
rg -n -C 3 "modelProvider|getBaseUrlFromSettings|getApiKeyFromSettings"

echo
echo "=== Search for provider factory patterns ==="
rg -n "createOpenAICompatible|createAnthropic|createGoogle|createOpenRouter"

echo
echo "=== Look for state.ai structure and provider options ==="
rg -n "state\.ai\.|getCurrentSession|\.model|\.modelProvider" | head -50

Repository: sqlrooms/sqlrooms

Length of output: 350


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Find createDashboardAgent file ==="
fd "createDashboardAgent"

echo
echo "=== Search for modelProvider and settings functions ==="
rg -n "modelProvider|getBaseUrlFromSettings|getApiKeyFromSettings" | head -40

echo
echo "=== Search for provider factory patterns ==="
rg -n "createOpenAICompatible|createAnthropic|createGoogle" | head -40

echo
echo "=== Search for AI state structure and getCurrentSession ==="
rg -n "getCurrentSession|state\.ai" | head -50

Repository: sqlrooms/sqlrooms

Length of output: 11000


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== View getBaseUrlFromSettings implementation in AiSlice.ts ==="
rg -n -A 20 "getBaseUrlFromSettings\s*:\s*\(" packages/ai-core/src/AiSlice.ts

echo
echo "=== View chatTransport.ts provider routing logic ==="
sed -n '270,300p' packages/ai-core/src/chatTransport.ts

echo
echo "=== Check how createOpenAICompatible is used in chatTransport.ts ==="
rg -n -B 5 -A 10 "createOpenAICompatible" packages/ai-core/src/chatTransport.ts | head -50

Repository: sqlrooms/sqlrooms

Length of output: 4354


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Find supported provider definitions ==="
rg -n "providers\[" packages/ai-core/src/AiSlice.ts | head -20

echo
echo "=== Look for Anthropic-specific model creation ==="
rg -n "anthropic|createAnthropic" --ignore-case

echo
echo "=== Check AiSlice test for all provider scenarios ==="
sed -n '50,120p' packages/ai-core/__tests__/AiSlice.modelSelection.test.ts

echo
echo "=== View more of getBaseUrlFromSettings implementation ==="
sed -n '891,930p' packages/ai-core/src/AiSlice.ts

Repository: sqlrooms/sqlrooms

Length of output: 8788


This code will fail for Anthropic providers because createOpenAICompatible() is incompatible with Anthropic's API.

While getBaseUrlFromSettings() correctly resolves provider-specific base URLs, createDashboardAgent.ts always instantiates the model through createOpenAICompatible(...). Anthropic is a supported provider (as shown in tests), but it requires a different factory. Compare this to chatTransport.ts (line 286–296), which uses a getCustomModel hook to allow provider-specific model creation before falling back to createOpenAICompatible. The createDashboardAgent needs the same pattern.

🤖 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 `@apps/sqlrooms-cli-ui/src/createDashboardAgent.ts` around lines 12 - 22, The
getModel implementation always uses createOpenAICompatible which breaks
Anthropic; update getModel in createDashboardAgent.ts to first attempt
provider-specific model creation (e.g., call the same getCustomModel hook used
in chatTransport.ts) using the resolved provider and baseURL from
state.ai.getBaseUrlFromSettings()/state.ai.getApiKeyFromSettings(), and only if
that returns null/undefined fall back to createOpenAICompatible(...). Use the
existing variables currentSession, provider and modelId to pass into the
provider-specific hook and maintain the existing fallback behavior.

Comment thread packages/mosaic/src/ai.ts Outdated
Comment thread packages/mosaic/src/ai.ts
@ilyabo
ilyabo force-pushed the extract-reusable-dashboard-ai-tools branch from 795b06c to e14d3d5 Compare May 21, 2026 09:38
@ilyabo
ilyabo merged commit 71a0d0d into main May 21, 2026
4 checks passed
@ilyabo
ilyabo deleted the extract-reusable-dashboard-ai-tools branch May 21, 2026 09:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants