Skip to content

feat(ai): add AI-powered workflow execution quality evaluation#257

Merged
zhubzy merged 8 commits intomainfrom
feat/eval-agent
Jan 12, 2026
Merged

feat(ai): add AI-powered workflow execution quality evaluation#257
zhubzy merged 8 commits intomainfrom
feat/eval-agent

Conversation

@zhubzy
Copy link
Contributor

@zhubzy zhubzy commented Jan 12, 2026

Summary

Related Issues

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Refactor
  • New Bubble Integration
  • Other (please describe):

Checklist

  • My code follows the code style of this project
  • I have added appropriate tests for my changes
  • I have run pnpm check and all tests pass
  • I have tested my changes locally
  • I have linked relevant issues

Screenshots (Required)

For New Bubble Integrations

📋 Integration Flow Tests: When creating a new bubble, you must write an integration flow test that exercises all operations end-to-end in realistic scenarios—including edge cases. This flow should be runnable in bubble studio and return structured results tracking each operation's success/failure with details. See packages/bubble-core/src/bubbles/service-bubble/google-sheets/google-sheets.integration.flow.ts for a complete reference implementation.

⚠️ If your integration requires API credits for testing, please reach out to the team for test credentials.

  • Integration flow test (.integration.flow.ts) covers all operations
  • Screenshots showing full test results in Bubble Studio attached above

Additional Context

Summary by CodeRabbit

  • New Features

    • Workflow evaluation UX: live loading, results modal, quality score, issue classification, and actionable "Fix with Pearl" CTAs
    • Per-execution history: selectable list, viewable full logs, and restore/replay support
  • Backend

    • Automated post-run evaluations via a new evaluation agent; results persisted with execution logs
    • New API to fetch a single execution with full logs
  • Chores

    • Added framer-motion for animations
    • Centralized credential configuration in shared schemas

✏️ Tip: You can customize this high-level summary in your review settings.

Copilot AI review requested due to automatic review settings January 12, 2026 11:08
@coderabbitai
Copy link

coderabbitai bot commented Jan 12, 2026

📝 Walkthrough

Walkthrough

Adds Rice evaluation to execution lifecycle: DB migrations and schema, API route to fetch execution details, backend Rice evaluator and trigger, streaming changes to collect/persist logs and emit evaluation events, frontend store/hooks updates, new UI components (loading/results) and framer-motion dependency.

Changes

Cohort / File(s) Summary
Backend: Evaluation & Execution
apps/bubblelab-api/src/services/ai/rice.ts, apps/bubblelab-api/src/services/evaluation-trigger.ts, apps/bubblelab-api/src/services/bubble-flow-execution.ts, apps/bubblelab-api/src/services/execution.ts
New Rice evaluator, evaluation decision/persistence, integrated evaluation run into execution flow, unified streaming path, added evalPerformance flag and evaluation lifecycle.
API Routes & Schemas
apps/bubblelab-api/src/routes/bubble-flows.ts, apps/bubblelab-api/src/schemas/bubble-flows.ts
New GET /bubble-flow/:id/executions/:executionId route returning execution detail with logs; streaming route accepts evalPerformance.
DB Migrations & Schema
apps/bubblelab-api/drizzle-*/0016_add-evaluations-and-execution-logs.sql, apps/bubblelab-api/drizzle-*/meta/..., apps/bubblelab-api/src/db/schema-*.ts, apps/bubblelab-api/src/db/schema.ts
New bubble_flow_evaluations table, added execution_logs/executionLogs to executions, relation wiring and snapshots for Postgres/SQLite.
Shared Schemas / Types
packages/bubble-shared-schemas/src/rice.ts, .../streaming-events.ts, .../bubbleflow-execution-schema.ts, .../credential-schema.ts, .../bubbleflow-generation-prompts.ts, src/index.ts
Rice request/response schemas and types; streaming events extended with start_evaluating/end_evaluating and evaluationResult; execution detail schema; credential config + generateCredentialsSummary; re-export rice.
Frontend: Stores & Hooks
apps/bubble-studio/src/stores/executionStore.ts, .../liveOutputStore.ts, apps/bubble-studio/src/hooks/useExecutionDetail.ts, useRunExecution.ts, (deleted) useExecutionStream.ts
Added evaluation state/actions (isEvaluating, evaluationResult, showEvaluationPopup), processEvent/restoreFromHistory, fetch execution detail hook, refactored streaming handler to centralized processor, removed legacy stream hook.
Frontend: Execution UI
apps/bubble-studio/src/components/execution_logs/AllEventsView.tsx, ExecutionHistory.tsx, LiveOutput.tsx
UI wiring for evaluation lifecycle: Evaluation tab/results integration, per-execution log fetching, evaluation popups integrated, updated handleFixWithPearl signature.
Frontend: New UI Components
apps/bubble-studio/src/components/execution_logs/EvaluationLoadingPopup.tsx, EvaluationIssuePopup.tsx
New animated loading popup (uses framer-motion) and evaluation result modal with rating, issue type, summary and conditional "Fix with Pearl" CTA.
Frontend: Credentials Page
apps/bubble-studio/src/pages/CredentialsPage.tsx
Replaced local credential config with shared CREDENTIAL_TYPE_CONFIG import.
Frontend Dependency
apps/bubble-studio/package.json
Added dependency framer-motion: ^12.26.0.
sequenceDiagram
    participant Browser as User (Browser)
    participant Frontend as Frontend UI/Store
    participant API as API Server
    participant Rice as Rice Evaluator
    participant DB as Database

    Browser->>Frontend: Start workflow (evalPerformance=true)
    Frontend->>API: Start streaming execution
    API->>Frontend: SSE streaming events (execution logs)
    Frontend->>Frontend: processEvent() updates UI/store
    API->>DB: persist execution + collected logs
    API->>API: shouldEvaluateExecution()
    alt shouldEvaluate == true
        API->>Frontend: emit start_evaluating
        Frontend->>Frontend: show EvaluationLoadingPopup
        API->>Rice: runRice(executionLogs, workflowCode)
        Rice->>API: return evaluationResult
        API->>DB: storeEvaluation()
        API->>Frontend: emit end_evaluating with evaluationResult
        Frontend->>Frontend: show EvaluationIssuePopup
    else skip
        API->>Frontend: no evaluation events
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested reviewers

  • iqbalbhatti49
  • Selinali01

Poem

🐰 Pearl Patrol
I nibbled logs and chased a thread,
A Rice-lit lantern overhead,
Ratings glinting, issues shown,
A Pearl to fix what once was unknown,
Hop, patch, and sprint — then off I sped!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 79.17% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately summarizes the main feature: adding AI-powered quality evaluation for workflow executions. It is concise, clear, and directly related to the core changeset.

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

✨ Finishing touches
  • 📝 Generate docstrings

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.

@bubblelab-pearl
Copy link
Contributor

Suggested PR title from Pearl

Title: feat(evaluation): add AI-powered workflow execution quality evaluation

Body:
Introduces Rice, an AI agent that evaluates workflow execution quality by analyzing execution logs and workflow code. Provides automated quality assessment with actionable feedback and issue categorization.

What's New

Rice Evaluation Agent

  • AI-powered agent that analyzes workflow executions
  • Evaluates based on execution logs and workflow code
  • Provides quality ratings (1-10 scale) and issue detection
  • Categorizes issues as setup, workflow, or input problems
  • Generates actionable summaries with fix steps

Evaluation Trigger Logic

  • Runs on first execution of any workflow (opt-in via evalPerformance flag)
  • Automatically re-evaluates if previous execution had issues
  • Skips evaluation if previous execution was successful
  • Non-blocking - execution completes even if evaluation fails

Frontend Updates

  • New "Check Results" tab in execution logs showing evaluation results
  • Animated loading popup during evaluation (using framer-motion)
  • Issue details popup with quality score and summary
  • "Fix with Pearl" integration for workflow issues
  • Execution history can now restore and view detailed logs
  • Click on past executions to replay logs in console

Backend Changes

  • New bubble_flow_evaluations table for storing evaluation results
  • Added execution_logs column to store StreamingLogEvent[] for history replay
  • New /bubble-flow/:id/executions/:executionId endpoint for execution details
  • Evaluation service with trigger logic and storage
  • Streaming events extended with start_evaluating and end_evaluating types

Database Schema

  • bubble_flow_evaluations: stores evaluation results (working, issue_type, summary, rating)
  • bubble_flow_executions.execution_logs: stores full execution logs as JSONB for replay
  • Relations between evaluations, executions, and flows

Shared Schema Updates

  • New Rice agent schemas (request, response, evaluation result)
  • Credential configuration moved to shared schemas for AI agent access
  • Extended streaming event types for evaluation lifecycle
  • New execution detail schema with logs

Issue Type Classification

  • setup: Configuration/credential issues (fixed in Settings, not workflow code)
  • workflow: Logic/code issues (fixable by editing workflow with Pearl)
  • input: Invalid input data (user needs different input)

Implementation Details

  • Uses shared processEvent logic for both live streaming and historical replay
  • Execution logs sanitized to prevent token limits (truncates long strings, replaces binary data)
  • Low temperature (0.1) for consistent evaluation results
  • Bubble Studio knowledge included in system prompt for context-aware evaluation
  • Detects binary data in AI agent messages as workflow issues

Closes #[issue_number_if_applicable]

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Jan 12, 2026

Deploying bubble-studio with  Cloudflare Pages  Cloudflare Pages

Latest commit: da51029
Status: ✅  Deploy successful!
Preview URL: https://3bb50c0c.bubble-studio.pages.dev
Branch Preview URL: https://feat-eval-agent.bubble-studio.pages.dev

View logs

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Jan 12, 2026

Deploying bubblelab-documentation with  Cloudflare Pages  Cloudflare Pages

Latest commit: da51029
Status: ✅  Deploy successful!
Preview URL: https://c8b75f8d.bubblelab-documentation.pages.dev
Branch Preview URL: https://feat-eval-agent.bubblelab-documentation.pages.dev

View logs

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces "Rice", an AI-powered workflow evaluation agent that automatically assesses execution quality after workflows run. It adds database schema for storing evaluations, implements the Rice agent service, and creates frontend UI components to display evaluation results to users.

Changes:

  • Added Rice evaluation agent using AIAgentBubble with structured output for quality assessment
  • Created database tables for storing evaluation results (working status, issue type, summary, rating)
  • Implemented conditional evaluation logic (first execution and after failures)
  • Added frontend popups and UI for displaying evaluation results and integrating with Pearl for fixes

Reviewed changes

Copilot reviewed 34 out of 35 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
apps/bubblelab-api/src/services/ai/rice.ts New Rice evaluation agent with prompt engineering and log sanitization
apps/bubblelab-api/src/services/evaluation-trigger.ts Logic for determining when to run evaluations
apps/bubblelab-api/src/db/schema-*.ts Added bubbleFlowEvaluations table and executionLogs column
apps/bubble-studio/src/stores/executionStore.ts Extended store with evaluation state and event processing
apps/bubble-studio/src/components/execution_logs/*.tsx New popup components for displaying evaluation results
packages/bubble-shared-schemas/src/rice.ts Schema definitions for Rice request/response
packages/bubble-shared-schemas/src/credential-schema.ts Refactored credential config to be shared between frontend and backend
pnpm-lock.yaml Added framer-motion dependency for animations
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

Comment on lines +151 to 152
console.log('[useRunExecution] received event', eventData.type);

Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

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

Console.log statement should be removed before merging to production. Debug logging should be removed or replaced with proper logging mechanisms.

Suggested change
console.log('[useRunExecution] received event', eventData.type);

Copilot uses AI. Check for mistakes.
jsonMode: true,
},
tools: [], // No tools needed - bubble knowledge is in system prompt
maxIterations: 5, // One-shot evaluation
Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

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

The maxIterations parameter is set to 5 but the comment says "One-shot evaluation". For a one-shot evaluation that doesn't need iterations, this should be set to 1 instead of 5 to avoid unnecessary processing.

Suggested change
maxIterations: 5, // One-shot evaluation
maxIterations: 1, // One-shot evaluation

Copilot uses AI. Check for mistakes.
Comment on lines 98 to 99
console.log('evaluationResult', evaluationResult);

Copy link

Copilot AI Jan 12, 2026

Choose a reason for hiding this comment

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

Console.log statement should be removed before merging to production. Debug logging should be removed or replaced with proper logging mechanisms.

Suggested change
console.log('evaluationResult', evaluationResult);

Copilot uses AI. Check for mistakes.
@zhubzy zhubzy changed the title Feat/eval agent feat(bubble-runtime): add AI-powered workflow execution quality evaluation Jan 12, 2026
@zhubzy zhubzy changed the title feat(bubble-runtime): add AI-powered workflow execution quality evaluation feat(ai): add AI-powered workflow execution quality evaluation Jan 12, 2026
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
packages/bubble-shared-schemas/src/credential-schema.ts (1)

386-392: Typo in scope description.

Line 389 has "all ofyour" which should be "all of your".

✏️ Suggested fix
           {
             scope: 'https://www.googleapis.com/auth/drive',
             description:
-              'View and manage all ofyour Google Drive files and folders (will see a warning about an "untrusted app" during authentication. Choose only if you need extra permissions)',
+              'View and manage all of your Google Drive files and folders (will see a warning about an "untrusted app" during authentication. Choose only if you need extra permissions)',
             defaultEnabled: false,
           },
apps/bubble-studio/src/hooks/useRunExecution.ts (1)

282-284: Unused variable from event parsing.

The result of line.substring(6).trim() is not assigned or used. If the event type is needed, assign it; otherwise, remove the statement.

🔧 Proposed fix
             if (line.startsWith('event:')) {
-              line.substring(6).trim();
+              // Event type is available in the data payload, skip the SSE event: line
               continue;
             }
🤖 Fix all issues with AI agents
In @apps/bubble-studio/package.json:
- Line 29: The dependency entry "framer-motion": "^12.26.0" is invalid and
incompatible with React 19; either remove the "framer-motion" dependency,
replace it with a React‑19‑compatible animation library, or pin to a published
version such as "framer-motion": "^12.23.0" and then run install and test; if
you must keep framer-motion, update package.json to the valid version, run
npm/yarn install, and verify app behavior (note upstream issue #2668 re: React
19 incompatibility) or alternatively downgrade React to a supported version.

In @apps/bubble-studio/src/components/execution_logs/AllEventsView.tsx:
- Line 98: Remove the debug console.log that prints evaluationResult on every
render; either delete the line console.log('evaluationResult', evaluationResult)
from AllEventsView.tsx or guard it behind a development-only check (e.g., if
(process.env.NODE_ENV !== 'production') console.log('evaluationResult',
evaluationResult)); ensure no other stray debug logs remain in the AllEventsView
component.

In @apps/bubble-studio/src/components/execution_logs/EvaluationIssuePopup.tsx:
- Around line 111-115: The backdrop click should be disabled while a fix is in
progress to match the disabled close button; update the backdrop div in
EvaluationIssuePopup (the element with onClick={onClose}) to only call onClose
when isFixingWithPearl is false (e.g., onClick={() => !isFixingWithPearl &&
onClose()}), or alternatively prevent pointer events / add a guard that returns
early if isFixingWithPearl is true; ensure the same isFixingWithPearl flag used
by the close button is referenced so backdrop clicks cannot close the modal
during the "Analyzing..." state.

In @apps/bubble-studio/src/components/execution_logs/ExecutionHistory.tsx:
- Around line 310-324: The status badge uses the global isCurrentlyExecuting
flag causing every history item to show "executing"; update the per-item check
in the ExecutionHistory component to compute a local boolean (e.g., const
isThisExecuting = currentExecution?.id === execution.id or compare whatever
unique id/RunId exists) and use isThisExecuting in the span className and label
instead of isCurrentlyExecuting so only the matching execution shows "executing"
while others use execution.status.
- Around line 295-303: The status icon logic uses the global
isCurrentlyExecuting flag for every history item, causing all items to show as
executing; update the condition to only show the pulsing amber icon when this
specific execution is the running one (e.g., replace isCurrentlyExecuting with a
per-item check like isCurrentlyExecuting && execution.id ===
currentExecution?.id or execution.id === runningExecutionId), leaving the checks
for execution.status === 'success' and 'error' unchanged so historical items
render their actual status icons.
🧹 Nitpick comments (10)
apps/bubble-studio/src/stores/liveOutputStore.ts (1)

340-367: Consider adding explicit handling for the evaluation tab.

The getEventsForTab method handles results and item explicitly but relies on the fallthrough return [] for the new evaluation kind. While this works correctly (since evaluation data comes from executionStore.evaluationResult), adding an explicit case improves readability and prevents confusion during future maintenance.

♻️ Suggested improvement
     } else if (tab.kind === 'item') {
       const orderedItems = get().getOrderedItems();
       const item = orderedItems[tab.index];
       if (!item) return [];

       if (item.kind === 'global') {
         return [item.event];
       } else {
         return item.events;
       }
+    } else if (tab.kind === 'evaluation') {
+      // Evaluation results are managed by executionStore, not via events
+      return [];
     }

     return [];
packages/bubble-shared-schemas/src/streaming-events.ts (1)

73-79: Import RiceEvaluationResult from rice.ts instead of defining inline.

The evaluationResult type is defined inline here but matches RiceEvaluationResult already exported from rice.ts and used elsewhere in the codebase. Import and reuse the existing type to maintain a single source of truth and prevent type drift.

apps/bubblelab-api/drizzle-postgres/0016_add-evaluations-and-execution-logs.sql (1)

1-15: Consider adding indexes on foreign key columns for query performance.

The execution_id and bubble_flow_id columns are likely to be used in WHERE clauses and JOINs when querying evaluations. PostgreSQL does not automatically create indexes on foreign key columns.

📈 Suggested index additions
 CREATE TABLE "bubble_flow_evaluations" (
 	"id" serial PRIMARY KEY NOT NULL,
 	"execution_id" integer NOT NULL,
 	"bubble_flow_id" integer NOT NULL,
 	"working" boolean NOT NULL,
 	"issue_type" text,
 	"summary" text NOT NULL,
 	"rating" integer NOT NULL,
 	"model_used" text NOT NULL,
 	"evaluated_at" timestamp NOT NULL
 );
 --> statement-breakpoint
+CREATE INDEX "bubble_flow_evaluations_execution_id_idx" ON "bubble_flow_evaluations" ("execution_id");--> statement-breakpoint
+CREATE INDEX "bubble_flow_evaluations_bubble_flow_id_idx" ON "bubble_flow_evaluations" ("bubble_flow_id");--> statement-breakpoint
 ALTER TABLE "bubble_flow_executions" ADD COLUMN "execution_logs" jsonb;--> statement-breakpoint
packages/bubble-shared-schemas/src/bubbleflow-execution-schema.ts (1)

218-232: Consider defining a stricter schema for executionLogs array items.

Using z.array(z.any()) provides no type safety for log events. If the log structure is stable, consider defining a union schema or at least a base shape for better validation and IDE support.

💡 Example with a base log event schema
+// Base schema for streaming log events (can be extended with union types)
+const baseLogEventSchema = z.object({
+  type: z.string(),
+  timestamp: z.string().optional(),
+}).passthrough(); // Allow additional properties

 export const bubbleFlowExecutionDetailSchema = bubbleFlowExecutionSchema.extend(
   {
     executionLogs: z
-      .array(z.any())
+      .array(baseLogEventSchema)
       .optional()
       .openapi({
         description: 'Array of streaming log events from the execution',
       }),
   }
 );

As per coding guidelines, remember to run pnpm build:core after modifying shared schemas.

apps/bubble-studio/src/components/execution_logs/EvaluationLoadingPopup.tsx (2)

69-93: SVG gradient ID may cause conflicts if component is rendered multiple times.

The id="pearlGradient" is hardcoded. If multiple instances of this component are ever rendered simultaneously (even briefly during AnimatePresence transitions), the gradient IDs will conflict, causing unexpected visual behavior.

Consider using a unique ID
+import { useId } from 'react';
...
export function EvaluationLoadingPopup({
  isEvaluating,
}: EvaluationLoadingPopupProps) {
+  const gradientId = useId();
...
                    <linearGradient
-                      id="pearlGradient"
+                      id={gradientId}
...
                    <circle
...
-                      stroke="url(#pearlGradient)"
+                      stroke={`url(#${gradientId})`}

134-139: Consider adding error handling for the Pearl image.

If /pearl.png fails to load (e.g., during development or if the asset is missing), the component will show a broken image. A fallback or error handler would improve resilience.

Add image error handling
+import { useState } from 'react';
...
+  const [imageError, setImageError] = useState(false);
...
-                <img
-                  src="/pearl.png"
-                  alt="Pearl"
-                  className="w-full h-full object-cover"
-                />
+                {imageError ? (
+                  <div className="w-full h-full bg-purple-600 flex items-center justify-center">
+                    <span className="text-white text-xl">✨</span>
+                  </div>
+                ) : (
+                  <img
+                    src="/pearl.png"
+                    alt="Pearl"
+                    className="w-full h-full object-cover"
+                    onError={() => setImageError(true)}
+                  />
+                )}
apps/bubblelab-api/drizzle-postgres/meta/0016_snapshot.json (1)

7-92: Consider adding an index on bubble_flow_id for the evaluations table.

The getLatestEvaluation and getEvaluationsForFlow functions in evaluation-trigger.ts query by bubbleFlowId with ordering by evaluatedAt. Without an index, these queries will perform full table scans as the evaluations table grows.

Suggested index

Add an index on (bubble_flow_id, evaluated_at DESC) to optimize the common query pattern:

CREATE INDEX idx_evaluations_flow_evaluated 
ON bubble_flow_evaluations(bubble_flow_id, evaluated_at DESC);
apps/bubble-studio/src/components/execution_logs/AllEventsView.tsx (1)

1009-1023: Consider extracting shared rating helper functions.

The getRatingColor and getRatingLabel functions are duplicated between this file and EvaluationIssuePopup.tsx. Consider extracting them to a shared utility file to maintain consistency and reduce duplication.

apps/bubblelab-api/src/services/ai/rice.ts (1)

167-169: Consider removing or reducing verbose logging in production.

Line 169 logs the raw AI response, which could be verbose. Consider using a debug log level or removing for production to reduce log noise.

🔧 Suggested improvement
     // Parse the agent's JSON response
     const responseText = result.data?.response || '';
-    console.log('[Rice] Raw response:', responseText);
+    // Debug: console.log('[Rice] Raw response:', responseText);

Or use a conditional based on environment:

if (env.isDev) {
  console.log('[Rice] Raw response:', responseText);
}
apps/bubble-studio/src/stores/executionStore.ts (1)

23-34: Consider reusing existing findBubbleByVariableId from bubbleUtils.ts.

A more comprehensive findBubbleByVariableId already exists in apps/bubble-studio/src/utils/bubbleUtils.ts (lines 73-111) that also searches through dependencyGraph. The simplified version here performs only a flat search and may miss nested bubbles.

If the simpler version is intentional for performance, consider adding a comment explaining this trade-off. Otherwise, consider importing and reusing the existing utility.

♻️ Suggested change to reuse existing utility
-import type {
-  StreamingLogEvent,
-  ParsedBubbleWithInfo,
-} from '@bubblelab/shared-schemas';
-
-/**
- * Result of processing an execution event.
- * Contains information the caller can use for UI updates.
- */
-export interface ProcessEventResult {
-  /** The bubble ID (variableId as string) affected by this event, if any */
-  bubbleId?: string;
-  /** Whether this event signals execution should stop */
-  shouldStop?: boolean;
-  /** Whether this event signals execution is complete (but may still have evaluation) */
-  isComplete?: boolean;
-  /** Event type for caller to handle UI-specific logic */
-  eventType: StreamingLogEvent['type'];
-}
-
-/**
- * Helper to find a bubble by its variableId in the bubbleParameters record
- */
-function findBubbleByVariableId(
-  bubbleParameters: Record<string, ParsedBubbleWithInfo> | undefined,
-  variableId: number
-): ParsedBubbleWithInfo | undefined {
-  if (!bubbleParameters) return undefined;
-  return Object.values(bubbleParameters).find(
-    (bubble) => bubble.variableId === variableId
-  );
-}
+import type {
+  StreamingLogEvent,
+  ParsedBubbleWithInfo,
+} from '@bubblelab/shared-schemas';
+import { findBubbleByVariableId as findBubble } from '../utils/bubbleUtils';
+
+/**
+ * Result of processing an execution event.
+ * Contains information the caller can use for UI updates.
+ */
+export interface ProcessEventResult {
+  /** The bubble ID (variableId as string) affected by this event, if any */
+  bubbleId?: string;
+  /** Whether this event signals execution should stop */
+  shouldStop?: boolean;
+  /** Whether this event signals execution is complete (but may still have evaluation) */
+  isComplete?: boolean;
+  /** Event type for caller to handle UI-specific logic */
+  eventType: StreamingLogEvent['type'];
+}
+
+/**
+ * Wrapper to adapt bubbleUtils.findBubbleByVariableId to ParsedBubbleWithInfo
+ */
+function findBubbleByVariableId(
+  bubbleParameters: Record<string, ParsedBubbleWithInfo> | undefined,
+  variableId: number
+): ParsedBubbleWithInfo | undefined {
+  if (!bubbleParameters) return undefined;
+  const found = findBubble(bubbleParameters, variableId);
+  return found as ParsedBubbleWithInfo | undefined;
+}
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6e5691d and a565ef1.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (34)
  • apps/bubble-studio/package.json
  • apps/bubble-studio/src/components/execution_logs/AllEventsView.tsx
  • apps/bubble-studio/src/components/execution_logs/EvaluationIssuePopup.tsx
  • apps/bubble-studio/src/components/execution_logs/EvaluationLoadingPopup.tsx
  • apps/bubble-studio/src/components/execution_logs/ExecutionHistory.tsx
  • apps/bubble-studio/src/components/execution_logs/LiveOutput.tsx
  • apps/bubble-studio/src/hooks/useExecutionDetail.ts
  • apps/bubble-studio/src/hooks/useExecutionStream.ts
  • apps/bubble-studio/src/hooks/useRunExecution.ts
  • apps/bubble-studio/src/pages/CredentialsPage.tsx
  • apps/bubble-studio/src/services/bubbleFlowApi.ts
  • apps/bubble-studio/src/stores/executionStore.ts
  • apps/bubble-studio/src/stores/liveOutputStore.ts
  • apps/bubblelab-api/drizzle-postgres/0016_add-evaluations-and-execution-logs.sql
  • apps/bubblelab-api/drizzle-postgres/meta/0016_snapshot.json
  • apps/bubblelab-api/drizzle-postgres/meta/_journal.json
  • apps/bubblelab-api/drizzle-sqlite/0016_add-evaluations-and-execution-logs.sql
  • apps/bubblelab-api/drizzle-sqlite/meta/0016_snapshot.json
  • apps/bubblelab-api/drizzle-sqlite/meta/_journal.json
  • apps/bubblelab-api/src/db/schema-postgres.ts
  • apps/bubblelab-api/src/db/schema-sqlite.ts
  • apps/bubblelab-api/src/db/schema.ts
  • apps/bubblelab-api/src/routes/bubble-flows.ts
  • apps/bubblelab-api/src/schemas/bubble-flows.ts
  • apps/bubblelab-api/src/services/ai/rice.ts
  • apps/bubblelab-api/src/services/bubble-flow-execution.ts
  • apps/bubblelab-api/src/services/evaluation-trigger.ts
  • apps/bubblelab-api/src/services/execution.ts
  • packages/bubble-shared-schemas/src/bubbleflow-execution-schema.ts
  • packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts
  • packages/bubble-shared-schemas/src/credential-schema.ts
  • packages/bubble-shared-schemas/src/index.ts
  • packages/bubble-shared-schemas/src/rice.ts
  • packages/bubble-shared-schemas/src/streaming-events.ts
💤 Files with no reviewable changes (1)
  • apps/bubble-studio/src/hooks/useExecutionStream.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/packages/bubble-shared-schemas/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/api.mdc)

**/packages/bubble-shared-schemas/**/*.{ts,tsx}: Write shared schemas between frontend and backend in /packages/bubble-shared-schemas directory
Run pnpm build:core after modifying shared schemas since it is a separate package and types need to be regenerated

Files:

  • packages/bubble-shared-schemas/src/streaming-events.ts
  • packages/bubble-shared-schemas/src/credential-schema.ts
  • packages/bubble-shared-schemas/src/index.ts
  • packages/bubble-shared-schemas/src/bubbleflow-execution-schema.ts
  • packages/bubble-shared-schemas/src/rice.ts
  • packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts
packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts

📄 CodeRabbit inference engine (.cursor/rules/bubblelab.mdc)

Refer to packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts for documentation on how bubble flow is supposed to be generated

Files:

  • packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts
🧠 Learnings (14)
📚 Learning: 2025-12-19T03:17:06.825Z
Learnt from: CR
Repo: bubblelabai/BubbleLab PR: 0
File: .cursor/rules/bundling.mdc:0-0
Timestamp: 2025-12-19T03:17:06.825Z
Learning: Applies to apps/bubble-studio/public/bubble-types.txt : The bundle file at `apps/bubble-studio/public/bubble-types.txt` must be kept synchronized with `packages/bubble-core/dist/bubble-bundle.d.ts` after each build

Applied to files:

  • apps/bubble-studio/src/stores/liveOutputStore.ts
  • apps/bubble-studio/package.json
  • apps/bubble-studio/src/pages/CredentialsPage.tsx
  • packages/bubble-shared-schemas/src/credential-schema.ts
  • packages/bubble-shared-schemas/src/index.ts
  • apps/bubblelab-api/src/db/schema.ts
  • apps/bubblelab-api/src/db/schema-sqlite.ts
  • packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts
📚 Learning: 2025-12-19T03:17:06.825Z
Learnt from: CR
Repo: bubblelabai/BubbleLab PR: 0
File: .cursor/rules/bundling.mdc:0-0
Timestamp: 2025-12-19T03:17:06.825Z
Learning: Applies to packages/bubble-core/src/index.ts : All new types and classes added to bubble-core must be exported from `packages/bubble-core/src/index.ts` to ensure they are included in the generated bundle

Applied to files:

  • apps/bubble-studio/src/stores/liveOutputStore.ts
  • apps/bubble-studio/src/pages/CredentialsPage.tsx
  • packages/bubble-shared-schemas/src/index.ts
  • packages/bubble-shared-schemas/src/bubbleflow-execution-schema.ts
  • apps/bubblelab-api/src/db/schema.ts
  • packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts
📚 Learning: 2025-12-22T09:55:47.873Z
Learnt from: CR
Repo: bubblelabai/BubbleLab PR: 0
File: .cursor/rules/bubblelab.mdc:0-0
Timestamp: 2025-12-22T09:55:47.873Z
Learning: Applies to apps/bubble-studio/public/bubbles.json : Refer to apps/bubble-studio/public/bubbles.json for a condensed definition of all bubbles (building/bundling is required)

Applied to files:

  • apps/bubble-studio/package.json
  • apps/bubblelab-api/src/db/schema.ts
📚 Learning: 2025-12-22T09:55:47.873Z
Learnt from: CR
Repo: bubblelabai/BubbleLab PR: 0
File: .cursor/rules/bubblelab.mdc:0-0
Timestamp: 2025-12-22T09:55:47.873Z
Learning: Applies to packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts : Refer to packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts for documentation on how bubble flow is supposed to be generated

Applied to files:

  • apps/bubble-studio/src/services/bubbleFlowApi.ts
  • apps/bubble-studio/src/components/execution_logs/AllEventsView.tsx
  • apps/bubblelab-api/src/services/bubble-flow-execution.ts
  • packages/bubble-shared-schemas/src/credential-schema.ts
  • apps/bubble-studio/src/hooks/useRunExecution.ts
  • apps/bubble-studio/src/stores/executionStore.ts
  • apps/bubblelab-api/src/db/schema-postgres.ts
  • packages/bubble-shared-schemas/src/index.ts
  • packages/bubble-shared-schemas/src/bubbleflow-execution-schema.ts
  • apps/bubblelab-api/src/db/schema.ts
  • packages/bubble-shared-schemas/src/rice.ts
  • apps/bubblelab-api/src/schemas/bubble-flows.ts
  • apps/bubblelab-api/src/db/schema-sqlite.ts
  • packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts
📚 Learning: 2025-12-19T03:17:06.825Z
Learnt from: CR
Repo: bubblelabai/BubbleLab PR: 0
File: .cursor/rules/bundling.mdc:0-0
Timestamp: 2025-12-19T03:17:06.825Z
Learning: Applies to apps/bubble-studio/src/components/MonacoEditor.tsx : The Monaco Editor integration in `apps/bubble-studio/src/components/MonacoEditor.tsx` must fetch the bundled types from `/bubble-types.txt`, wrap them in a module declaration for `bubblelab/bubble-core`, and add them to Monaco's TypeScript type system

Applied to files:

  • apps/bubble-studio/src/pages/CredentialsPage.tsx
  • apps/bubble-studio/src/hooks/useRunExecution.ts
📚 Learning: 2025-12-19T03:16:48.801Z
Learnt from: CR
Repo: bubblelabai/BubbleLab PR: 0
File: .cursor/rules/api.mdc:0-0
Timestamp: 2025-12-19T03:16:48.801Z
Learning: Applies to **/packages/bubble-shared-schemas/**/*.{ts,tsx} : Write shared schemas between frontend and backend in `/packages/bubble-shared-schemas` directory

Applied to files:

  • apps/bubble-studio/src/pages/CredentialsPage.tsx
  • packages/bubble-shared-schemas/src/credential-schema.ts
  • apps/bubblelab-api/src/db/schema-postgres.ts
  • packages/bubble-shared-schemas/src/index.ts
  • packages/bubble-shared-schemas/src/bubbleflow-execution-schema.ts
  • apps/bubblelab-api/src/db/schema.ts
  • packages/bubble-shared-schemas/src/rice.ts
  • apps/bubblelab-api/src/schemas/bubble-flows.ts
  • apps/bubblelab-api/src/db/schema-sqlite.ts
  • packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts
📚 Learning: 2025-12-19T03:17:06.825Z
Learnt from: CR
Repo: bubblelabai/BubbleLab PR: 0
File: .cursor/rules/bundling.mdc:0-0
Timestamp: 2025-12-19T03:17:06.825Z
Learning: Applies to packages/bubble-core/dist/**/*.d.ts : All external imports (except relative imports) must be removed from the bundled output to prevent circular processing and external dependency issues

Applied to files:

  • apps/bubble-studio/src/pages/CredentialsPage.tsx
  • packages/bubble-shared-schemas/src/index.ts
  • apps/bubblelab-api/src/db/schema.ts
📚 Learning: 2025-12-22T09:55:47.873Z
Learnt from: CR
Repo: bubblelabai/BubbleLab PR: 0
File: .cursor/rules/bubblelab.mdc:0-0
Timestamp: 2025-12-22T09:55:47.873Z
Learning: Applies to packages/bubble-runtime/src/extraction/README.md : Refer to packages/bubble-runtime/src/extraction/README.md for information about bubble parsing, dependency graphs, and per-invocation cloning

Applied to files:

  • apps/bubblelab-api/src/services/bubble-flow-execution.ts
  • packages/bubble-shared-schemas/src/index.ts
📚 Learning: 2025-12-22T09:55:47.873Z
Learnt from: CR
Repo: bubblelabai/BubbleLab PR: 0
File: .cursor/rules/bubblelab.mdc:0-0
Timestamp: 2025-12-22T09:55:47.873Z
Learning: Applies to apps/bubble-studio/src/components/flow_visualizer/README.md : Refer to apps/bubble-studio/src/components/flow_visualizer/README.md for documentation on flow visualizer architecture and node rendering

Applied to files:

  • apps/bubblelab-api/src/services/bubble-flow-execution.ts
  • packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts
📚 Learning: 2025-12-19T03:17:06.825Z
Learnt from: CR
Repo: bubblelabai/BubbleLab PR: 0
File: .cursor/rules/bundling.mdc:0-0
Timestamp: 2025-12-19T03:17:06.825Z
Learning: Applies to packages/bubble-core/dist/**/*.d.ts : The type bundling system for Monaco Editor must process TypeScript declaration files (.d.ts) and inline all dependencies into a single self-contained bundle in `packages/bubble-core/dist/bubble-bundle.d.ts`

Applied to files:

  • apps/bubble-studio/src/hooks/useRunExecution.ts
  • packages/bubble-shared-schemas/src/index.ts
📚 Learning: 2025-12-19T03:17:06.825Z
Learnt from: CR
Repo: bubblelabai/BubbleLab PR: 0
File: .cursor/rules/bundling.mdc:0-0
Timestamp: 2025-12-19T03:17:06.825Z
Learning: When adding new types to `bubblelab/shared-schemas`, they are automatically included in the bundle without requiring manual configuration changes

Applied to files:

  • packages/bubble-shared-schemas/src/index.ts
  • packages/bubble-shared-schemas/src/bubbleflow-execution-schema.ts
  • apps/bubblelab-api/src/db/schema.ts
  • apps/bubblelab-api/src/db/schema-sqlite.ts
📚 Learning: 2025-12-19T03:16:48.801Z
Learnt from: CR
Repo: bubblelabai/BubbleLab PR: 0
File: .cursor/rules/api.mdc:0-0
Timestamp: 2025-12-19T03:16:48.801Z
Learning: Applies to **/packages/bubble-shared-schemas/**/*.{ts,tsx} : Run `pnpm build:core` after modifying shared schemas since it is a separate package and types need to be regenerated

Applied to files:

  • packages/bubble-shared-schemas/src/index.ts
  • packages/bubble-shared-schemas/src/bubbleflow-execution-schema.ts
  • apps/bubblelab-api/src/db/schema.ts
  • packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts
📚 Learning: 2025-12-19T03:17:06.825Z
Learnt from: CR
Repo: bubblelabai/BubbleLab PR: 0
File: .cursor/rules/bundling.mdc:0-0
Timestamp: 2025-12-19T03:17:06.825Z
Learning: Shared schemas must be bundled separately using `bundleSharedSchemas()` and inlined after Zod stubs but before bubble-core types in the final bundle structure

Applied to files:

  • packages/bubble-shared-schemas/src/index.ts
📚 Learning: 2025-12-22T09:55:47.873Z
Learnt from: CR
Repo: bubblelabai/BubbleLab PR: 0
File: .cursor/rules/bubblelab.mdc:0-0
Timestamp: 2025-12-22T09:55:47.873Z
Learning: Applies to packages/bubble-runtime/src/injection/README.md : Refer to packages/bubble-runtime/src/injection/README.md for information about credential injection and bubble parameter reinitialization

Applied to files:

  • packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts
🧬 Code graph analysis (12)
apps/bubble-studio/src/hooks/useExecutionDetail.ts (2)
packages/bubble-shared-schemas/src/bubbleflow-execution-schema.ts (1)
  • BubbleFlowExecutionDetail (230-232)
apps/bubble-studio/src/services/bubbleFlowApi.ts (1)
  • bubbleFlowApi (8-77)
apps/bubble-studio/src/services/bubbleFlowApi.ts (2)
packages/bubble-shared-schemas/src/bubbleflow-execution-schema.ts (1)
  • BubbleFlowExecutionDetail (230-232)
apps/bubble-studio/src/lib/api.ts (1)
  • api (263-263)
apps/bubble-studio/src/components/execution_logs/ExecutionHistory.tsx (4)
apps/bubble-studio/src/hooks/useExecutionDetail.ts (1)
  • useFetchExecutionDetail (17-26)
apps/bubble-studio/src/stores/uiStore.ts (1)
  • useUIStore (207-307)
apps/bubble-studio/src/stores/executionStore.ts (1)
  • getExecutionStore (1033-1036)
packages/bubble-shared-schemas/src/streaming-events.ts (1)
  • StreamingLogEvent (12-80)
apps/bubblelab-api/src/services/ai/rice.ts (3)
packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts (2)
  • BUBBLE_STUDIO_INSTRUCTIONS (81-135)
  • BUBBLE_SPECIFIC_INSTRUCTIONS (312-364)
packages/bubble-shared-schemas/src/rice.ts (4)
  • RiceRequest (98-98)
  • RiceResponse (100-100)
  • RiceEvaluationResult (93-93)
  • RiceEvaluationResultSchema (25-50)
apps/bubblelab-api/src/config/env.ts (1)
  • env (67-95)
apps/bubble-studio/src/hooks/useRunExecution.ts (2)
packages/bubble-shared-schemas/src/bubbleflow-schema.ts (1)
  • BubbleFlowDetailsResponse (395-397)
apps/bubble-studio/src/stores/executionStore.ts (2)
  • ProcessEventResult (12-21)
  • getExecutionStore (1033-1036)
apps/bubble-studio/src/stores/executionStore.ts (3)
packages/bubble-shared-schemas/src/streaming-events.ts (1)
  • StreamingLogEvent (12-80)
apps/bubble-studio/src/utils/bubbleUtils.ts (1)
  • findBubbleByVariableId (74-112)
packages/bubble-shared-schemas/src/bubble-definition-schema.ts (1)
  • ParsedBubbleWithInfo (224-224)
apps/bubblelab-api/src/db/schema-postgres.ts (1)
apps/bubblelab-api/src/db/schema-sqlite.ts (4)
  • bubbleFlowEvaluations (91-109)
  • bubbleFlowExecutions (74-89)
  • bubbleFlows (20-47)
  • bubbleFlowEvaluationsRelations (211-223)
packages/bubble-shared-schemas/src/rice.ts (2)
packages/bubble-shared-schemas/src/ai-models.ts (2)
  • AvailableModel (33-33)
  • AvailableModels (4-31)
packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts (1)
  • RECOMMENDED_MODELS (17-26)
apps/bubble-studio/src/components/execution_logs/LiveOutput.tsx (5)
apps/bubble-studio/src/stores/executionStore.ts (1)
  • useExecutionStore (956-992)
apps/bubble-studio/src/hooks/usePearlChatStore.ts (1)
  • usePearlChatStore (442-1083)
apps/bubble-studio/src/stores/uiStore.ts (1)
  • useUIStore (207-307)
apps/bubble-studio/src/components/execution_logs/EvaluationLoadingPopup.tsx (1)
  • EvaluationLoadingPopup (7-222)
apps/bubble-studio/src/components/execution_logs/EvaluationIssuePopup.tsx (1)
  • EvaluationIssuePopup (32-257)
apps/bubblelab-api/src/schemas/bubble-flows.ts (1)
packages/bubble-shared-schemas/src/bubbleflow-execution-schema.ts (1)
  • bubbleFlowExecutionDetailSchema (219-228)
apps/bubblelab-api/src/db/schema-sqlite.ts (1)
apps/bubblelab-api/src/db/schema-postgres.ts (4)
  • bubbleFlowEvaluations (97-115)
  • bubbleFlowExecutions (82-95)
  • bubbleFlows (30-59)
  • bubbleFlowEvaluationsRelations (217-229)
packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts (1)
packages/bubble-shared-schemas/src/credential-schema.ts (1)
  • generateCredentialsSummary (251-259)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: CodeQL analysis (javascript-typescript)
  • GitHub Check: Agent
  • GitHub Check: test
  • GitHub Check: Cloudflare Pages: bubblelab-documentation
🔇 Additional comments (56)
apps/bubble-studio/src/stores/liveOutputStore.ts (1)

25-30: LGTM! Clean extension of the TabType discriminated union.

The new evaluation variant integrates well with the existing results and item types. The comment accurately describes the new tab's purpose.

apps/bubblelab-api/drizzle-sqlite/meta/_journal.json (1)

116-123: LGTM!

The new migration journal entry follows the established pattern with correct indexing, version, and descriptive tag name.

apps/bubblelab-api/drizzle-postgres/meta/_journal.json (1)

116-123: LGTM!

The PostgreSQL migration journal entry correctly mirrors the SQLite migration with consistent indexing and tag naming, maintaining schema parity across databases.

apps/bubblelab-api/src/services/execution.ts (1)

37-41: Flag is properly integrated across the execution flow.

The evalPerformance flag is actively used: the frontend passes it as a query parameter, the route handler extracts and forwards it, the execution service checks it before running evaluation, and the evaluation trigger service gates evaluation based on this flag. The implementation correctly gates post-execution Rice evaluation as intended.

apps/bubblelab-api/src/db/schema.ts (1)

22-35: Correct the claim about alphabetical ordering.

The new bubbleFlowEvaluations and bubbleFlowEvaluationsRelations exports are correctly added and do exist in both schema-postgres.ts and schema-sqlite.ts. However, the exports are not in alphabetical order—they follow a functional grouping pattern (tables grouped together, relations grouped together). The comment should be updated to reflect this actual organization.

export const {
  bubbleFlows,
  webhooks,
  bubbleFlowExecutions,
  bubbleFlowEvaluations,
  userCredentials,
  userServiceUsage,
  waitlistedUsers,
  bubbleFlowsRelations,
  webhooksRelations,
  bubbleFlowExecutionsRelations,
  bubbleFlowEvaluationsRelations,
  users,
} = schema;

Likely an incorrect or invalid review comment.

packages/bubble-shared-schemas/src/index.ts (1)

21-21: LGTM!

The re-export of the Rice evaluation module follows the established pattern. As per coding guidelines, remember to run pnpm build:core after modifying shared schemas to regenerate types.

packages/bubble-shared-schemas/src/credential-schema.ts (2)

248-259: LGTM!

Clean utility function that generates a human-readable credential summary for AI agents. The implementation correctly exposes only non-sensitive metadata (labels, types, descriptions).


5-14: LGTM!

The CredentialConfig interface provides a clean contract for UI display metadata. The credentialConfigurations: Record<string, unknown> allows flexibility for credential-specific settings like ignoreSSL.

apps/bubble-studio/src/hooks/useExecutionDetail.ts (1)

17-26: LGTM!

The use of useMutation for this fetch operation is well-justified by the comment—it's triggered imperatively by user action rather than declaratively bound to component lifecycle. The consuming components can handle errors via the mutation's onError callback or by checking mutation.error.

apps/bubble-studio/src/services/bubbleFlowApi.ts (1)

64-76: LGTM!

The new getBubbleFlowExecutionDetail method follows the established patterns in this file: properly typed using shared schemas, consistent URL construction, and delegating to the base api client for HTTP handling.

packages/bubble-shared-schemas/src/streaming-events.ts (1)

32-34: LGTM!

The new start_evaluating and end_evaluating event types follow the existing naming conventions and appropriately extend the streaming event lifecycle to support Rice evaluation.

apps/bubblelab-api/src/schemas/bubble-flows.ts (1)

668-725: LGTM!

The new route follows the established patterns in this file: proper param validation with numeric regex, consistent error response handling, and correct usage of the shared bubbleFlowExecutionDetailSchema. The 404 description appropriately covers both BubbleFlow and execution not found cases.

apps/bubble-studio/src/components/execution_logs/LiveOutput.tsx (2)

103-116: LGTM on popup integration.

The evaluation popups are correctly integrated:

  • EvaluationLoadingPopup shows during evaluation (non-dismissable overlay)
  • EvaluationIssuePopup only renders when evaluationResult exists, preventing unnecessary portal creation
  • Props are correctly wired to store state and handlers

46-65: This concern is unfounded—emptyState includes all required evaluation properties.

The emptyState object (lines 865-924 in executionStore.ts) fully defines evaluationResult, showEvaluationPopup, dismissEvaluationPopup (as an empty function), and isEvaluating. All properties destructured in LiveOutput.tsx are present, so no runtime errors will occur when flowId is null.

apps/bubblelab-api/drizzle-sqlite/meta/0016_snapshot.json (1)

7-98: LGTM - Schema snapshot correctly captures evaluation table.

The bubble_flow_evaluations table definition is consistent with the Postgres migration. SQLite-appropriate type mappings are used (integer for boolean/timestamps, text for strings). Foreign key cascade behavior matches the Postgres schema.

packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts (2)

10-13: Import update looks correct.

The expanded import now includes generateCredentialsSummary alongside SYSTEM_CREDENTIALS. This aligns with the function definition in credential-schema.ts (lines 250-258 in the relevant code snippet).

Based on coding guidelines, remember to run pnpm build:core after modifying shared schemas since it is a separate package and types need to be regenerated.


94-105: Documentation updates are well-structured.

The dynamic credentials summary injection and updated documentation for the Credentials page and History section accurately reflect the new evaluation features. The text is clear and user-friendly.

apps/bubble-studio/src/components/execution_logs/EvaluationLoadingPopup.tsx (1)

1-222: Well-designed loading component with polished animations.

The component effectively uses framer-motion for smooth enter/exit transitions and multiple layered animations. The structure is clean and the prop interface is minimal.

Minor accessibility note: The overlay has no focus trap or aria-busy attribute, but for a transient loading state this is acceptable.

apps/bubble-studio/src/pages/CredentialsPage.tsx (2)

20-26: Good refactor to centralize credential configuration.

Moving CREDENTIAL_TYPE_CONFIG to the shared schemas package and using type-only imports for CredentialResponse and CreateCredentialRequest improves maintainability. The credential configuration is now shared between frontend and backend as intended per coding guidelines.


342-344: Usage of shared CREDENTIAL_TYPE_CONFIG is consistent.

The placeholder access pattern CREDENTIAL_TYPE_CONFIG[formData.credentialType as CredentialType].namePlaceholder is used consistently throughout. The type assertion is needed since formData.credentialType is typed as the enum value.

apps/bubblelab-api/drizzle-sqlite/0016_add-evaluations-and-execution-logs.sql (1)

1-15: SQLite migration aligns with Postgres schema.

The table structure correctly adapts to SQLite conventions (integer for boolean working, integer for timestamp evaluated_at). Foreign key cascades are properly defined.

Same operational consideration as Postgres: an index on bubble_flow_id would benefit query performance for evaluation lookups as the table grows.

apps/bubblelab-api/src/services/evaluation-trigger.ts (3)

37-67: Evaluation trigger logic is well-designed.

The decision logic is clear:

  1. Check if evaluation is enabled (opt-in via evalPerformance)
  2. First execution always evaluates
  3. Re-evaluate only if previous evaluation had issues

The discriminated union for reason provides good observability for debugging.


81-101: No action needed. The evaluatedAt field in both PostgreSQL and SQLite schemas defines .$defaultFn(() => new Date()), so the insert operation correctly omits it and the database will automatically set the current timestamp.

Likely an incorrect or invalid review comment.


123-140: The execution relation is properly defined in the schema at schema-postgres.ts (lines 220-223) and correctly maps bubbleFlowEvaluations.executionId to bubbleFlowExecutions.id. The code in getEvaluationsForFlow() using with: { execution: ... } will work correctly and will not fail at runtime.

apps/bubble-studio/src/components/execution_logs/ExecutionHistory.tsx (3)

211-216: Selection clearing effect is correctly implemented.

The effect properly clears the selected execution when a new execution starts, ensuring the UI doesn't show stale historical data during a live execution.


413-427: View Logs indicator provides good UX feedback.

The indicator section clearly shows the current state (loading, selected, or available for viewing) and the click hint text guides users appropriately. The stopPropagation calls on nested buttons prevent accidental log viewing when using "Use Version".


195-199: Type assertion on executionLogs should be validated or properly typed in the schema.

The cast as StreamingLogEvent[] assumes the API returns data conforming to the StreamingLogEvent interface, but the schema defines executionLogs as z.array(z.any()) with no enforced structure. Without runtime validation, if the stored logs have a different structure (missing required fields like type or timestamp), restoreFromHistory will fail at runtime when processEvent accesses expected properties.

Either add runtime validation before calling restoreFromHistory, or update the schema to properly type executionLogs as StreamingLogEvent[].

apps/bubblelab-api/drizzle-postgres/meta/0016_snapshot.json (1)

59-64: The evaluated_at column has a default value defined at the ORM level. In schema-postgres.ts (lines 112-114), evaluatedAt is configured with .$defaultFn(() => new Date()), which instructs Drizzle ORM to automatically populate the timestamp during insert. The storeEvaluation function correctly omits evaluatedAt from the insert values, allowing the ORM's default function to handle it. No issue exists here.

apps/bubblelab-api/src/routes/bubble-flows.ts (2)

434-435: LGTM!

The evalPerformance query parameter extraction is straightforward and safe. The string comparison to 'true' is a common and correct pattern for boolean query parameters.


955-1022: LGTM! Well-structured endpoint with proper authorization checks.

The new execution detail route correctly:

  • Validates both id and executionId parameters
  • Verifies the flow belongs to the authenticated user before fetching execution
  • Uses a compound query to ensure the execution belongs to the specified flow
  • Returns appropriate 400/404 status codes for invalid/missing resources
apps/bubblelab-api/src/services/bubble-flow-execution.ts (3)

128-142: LGTM! Clean callback pattern for log collection.

The collection callback elegantly captures all streaming events for storage while transparently forwarding to the original callback when present. This ensures logs are available for history replay regardless of whether the execution was streamed.


176-185: Evaluation is fire-and-forget without awaiting completion.

The evaluation runs asynchronously after execution completes, but there's no guarantee the evaluation completes before the response is sent to the client. If the SSE connection closes before runEvaluationIfNeeded finishes, the streamCallback calls inside it may fail silently.

This is likely intentional (non-blocking evaluation), but verify this is the desired behavior. The client may miss end_evaluating events if the connection is closed prematurely.


221-297: Robust error handling in evaluation helper.

The evaluation flow correctly:

  • Checks conditions before running evaluation
  • Wraps the entire flow in try-catch to prevent execution failures
  • Streams both success and error states to the client
  • Stores evaluation results on success

One minor note: the await on line 230 for shouldEvaluateExecution is correct since it returns a Promise.

apps/bubble-studio/src/components/execution_logs/AllEventsView.tsx (2)

601-649: LGTM! Well-designed evaluation status section.

The Workflow Check section appropriately:

  • Only renders when evaluation is in progress or has results
  • Shows distinct icons for loading, success, and error states
  • Displays a rating badge with appropriate color coding
  • Integrates seamlessly with the existing tab navigation

988-1157: LGTM! Comprehensive evaluation results UI.

The evaluation tab content handles all states well:

  • Loading state with clear messaging
  • Success/failure status with visual distinction
  • Quality score with contextual labels
  • Appropriate CTAs based on issue type (Pearl fix only for workflow issues)
  • Helpful guidance text for setup/input issues
apps/bubble-studio/src/components/execution_logs/EvaluationIssuePopup.tsx (1)

32-256: LGTM! Well-implemented modal component.

The component provides a polished evaluation results popup with:

  • Clear visual hierarchy distinguishing success from failure states
  • Issue type categorization with appropriate icons and descriptions
  • Quality score display with contextual rating labels
  • Conditional "Fix with Pearl" CTA only for workflow issues
  • Proper disabled states during async operations
apps/bubble-studio/src/hooks/useRunExecution.ts (2)

151-167: LGTM! Good pattern using React Query cache for fresh data.

Fetching latestFlow from the query cache ensures bubble parameters are up-to-date after validation, avoiding stale closure issues that could occur with the currentFlow from the hook's closure.


170-254: LGTM! Clean event handling with centralized processor.

The switch statement handles UI-specific actions (highlighting, tab selection) while delegating state management to the centralized store processor. This separation of concerns improves maintainability.

packages/bubble-shared-schemas/src/rice.ts (1)

1-100: LGTM! Well-designed shared schema for Rice evaluation.

The schema design follows best practices:

  • Clear documentation via .describe() for each field
  • Appropriate use of z.input vs z.infer for optional fields with defaults
  • Proper constraints (int, min/max for rating)
  • Nullable issueType aligns with the domain model (null when working=true)

As per coding guidelines, shared schemas between frontend and backend are correctly placed in /packages/bubble-shared-schemas. Remember to run pnpm build:core after merging to regenerate types.

apps/bubblelab-api/src/services/ai/rice.ts (3)

216-251: LGTM! Robust binary data detection.

The binary data detection covers common cases:

  • Base64 data URLs and long base64 strings
  • Common image format headers (PNG, GIF, JPEG)
  • PDF content markers
  • Non-printable character ratio check as a fallback

This prevents token waste and potential issues when sending binary data to the AI model.


259-298: LGTM! Safe recursive sanitization with depth limiting.

The sanitization correctly:

  • Prevents infinite recursion with depth check
  • Handles all JavaScript types appropriately
  • Truncates long strings while preserving useful context
  • Replaces binary data with informative placeholders

111-211: LGTM! Well-structured Rice evaluation agent.

The implementation:

  • Builds comprehensive evaluation prompts with sanitized data
  • Uses low temperature for consistent evaluation results
  • Has robust JSON parsing with fallback extraction
  • Validates responses against the schema before returning
  • Handles errors gracefully with informative messages
apps/bubblelab-api/src/db/schema-postgres.ts (5)

92-92: LGTM!

The executionLogs column addition is appropriate for storing streaming log events. Using jsonb allows efficient querying and storage of the event array.


97-115: Well-structured evaluation table.

The schema correctly establishes foreign key relationships with cascade deletes. The rating field's 1-10 range is documented in comments—consider adding application-level validation when inserting records to enforce this constraint.


193-197: LGTM!

The evaluations relation is correctly added to enable querying evaluations from a bubble flow.


206-215: LGTM!

The relation signature correctly extends to support both one and many relations, and the evaluations relation is properly defined.


217-229: LGTM!

The bubbleFlowEvaluationsRelations correctly establishes bidirectional relations with both bubbleFlowExecutions and bubbleFlows tables.

apps/bubble-studio/src/stores/executionStore.ts (6)

8-21: LGTM!

The ProcessEventResult interface is well-documented and provides a clean contract for event processing results that UI components can act upon.


146-166: LGTM!

The evaluation state fields are well-documented and align with the evaluation result structure defined in StreamingLogEvent.evaluationResult from the shared schemas.


300-351: LGTM!

The evaluation action interfaces and event processing method signatures are well-documented with clear JSDoc comments explaining their purpose and usage patterns.


585-731: Well-implemented event processor.

The processEvent method comprehensively handles all relevant streaming event types. The logic at line 637 (success !== false) correctly treats both undefined and true as successful outcomes, which is appropriate default behavior.

One minor note: the switch statement doesn't have a default case, which is fine since unhandled event types simply return the base result without side effects.


733-751: LGTM!

The restoreFromHistory method correctly resets execution state before replaying events, and appropriately suppresses the evaluation popup for historical data viewing.


771-791: LGTM!

The reset methods and emptyState are consistently updated to include evaluation-related fields, ensuring proper state cleanup and safe defaults when no flow is selected.

Also applies to: 883-913

apps/bubblelab-api/src/db/schema-sqlite.ts (3)

84-84: LGTM!

The executionLogs column correctly uses SQLite's text with mode: 'json' as the equivalent of Postgres jsonb.


91-109: LGTM!

The bubbleFlowEvaluations table correctly mirrors the Postgres schema with appropriate SQLite type mappings (int with mode: 'boolean' for booleans, int with mode: 'timestamp' for dates).


187-223: LGTM!

The relation definitions correctly mirror the Postgres schema, maintaining cross-database parity. Both bubbleFlowsRelations and bubbleFlowExecutionsRelations are properly extended, and bubbleFlowEvaluationsRelations establishes correct bidirectional references.


const contentScrollRef = useRef<HTMLDivElement>(null);

console.log('evaluationResult', evaluationResult);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Remove debug console.log before merging.

This debug statement logs evaluationResult on every render, which will clutter the console in production.

🔧 Proposed fix
-  console.log('evaluationResult', evaluationResult);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
console.log('evaluationResult', evaluationResult);
🤖 Prompt for AI Agents
In @apps/bubble-studio/src/components/execution_logs/AllEventsView.tsx at line
98, Remove the debug console.log that prints evaluationResult on every render;
either delete the line console.log('evaluationResult', evaluationResult) from
AllEventsView.tsx or guard it behind a development-only check (e.g., if
(process.env.NODE_ENV !== 'production') console.log('evaluationResult',
evaluationResult)); ensure no other stray debug logs remain in the AllEventsView
component.

@bubblelabai bubblelabai deleted a comment from coderabbitai bot Jan 12, 2026
…agent integration, including evaluation result handling and UI updates for displaying evaluation issues
… enhance issue categorization and summary display

- Changed evaluation result structure to include issueType ('setup', 'workflow', 'input') and summary.
- Updated UI components to reflect new evaluation result format, displaying appropriate messages based on evaluation outcomes.
- Enhanced user guidance for fixing issues, with specific help text for different issue types.
- Introduced new icons and labels for better visual representation of evaluation results.
…nce execution history component

- Implemented a new feature to view execution logs from historical executions, allowing users to fetch full execution details and restore them to the store.
- Enhanced the ExecutionHistory component with loading states and visual indicators for selected executions.
- Introduced a new hook, useExecutionDetail, for fetching execution details with logs.
- Updated the execution store to support restoring execution state from historical logs.
- Added API endpoint for retrieving execution details with logs.
… enhance AI agent instructions

- Moved credential type configuration to a centralized schema for better maintainability and consistency across the application.
- Updated AI agent instructions to include specific context for Bubble Studio, improving the evaluation process.
- Enhanced the summary generation for available credentials, providing clearer guidance for users on credential setup and usage.
- Removed redundant code and improved overall code organization in the CredentialsPage and related files.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/bubble-shared-schemas/src/credential-schema.ts (1)

388-392: Typo in scope description.

Line 389 has "all ofyour" which should be "all of your".

✏️ Proposed fix
           {
             scope: 'https://www.googleapis.com/auth/drive',
             description:
-              'View and manage all ofyour Google Drive files and folders (will see a warning about an "untrusted app" during authentication. Choose only if you need extra permissions)',
+              'View and manage all of your Google Drive files and folders (will see a warning about an "untrusted app" during authentication. Choose only if you need extra permissions)',
             defaultEnabled: false,
           },
🤖 Fix all issues with AI agents
In @apps/bubble-studio/src/components/execution_logs/ExecutionHistory.tsx:
- Around line 196-199: The call to
getExecutionStore(flowId).restoreFromHistory(...) currently casts
executionDetail.executionLogs to StreamingLogEvent[] without runtime checks; add
a validation step that verifies each item matches the StreamingLogEvent shape
(using your Zod schema or a type guard) before calling restoreFromHistory:
iterate executionDetail.executionLogs, run zodSchema.parse/parseAsync or a guard
on each item, collect only valid events (or log/filter invalid ones), then pass
the validated StreamingLogEvent[] to restoreFromHistory to avoid silently
processing malformed events.

In @apps/bubblelab-api/src/services/ai/rice.ts:
- Around line 149-152: The inline comment says "One-shot evaluation" but the
configuration sets maxIterations = 5, causing a mismatch; either change
maxIterations to 1 to enforce true one-shot behavior or update the comment to
explain that multiple iterations/retries are allowed (e.g., "Allow up to 5
iterations/retries"); locate the code where maxIterations is assigned (the
object literal containing tools, maxIterations, credentials — referencing the
maxIterations property) and make the comment/value consistent.

In @apps/bubblelab-api/src/services/bubble-flow-execution.ts:
- Around line 228-236: The call to shouldEvaluateExecution(bubbleFlowId, true)
hardcodes the evalPerformance flag and bypasses the actual
options.evalPerformance value checked earlier; change the call to
shouldEvaluateExecution(bubbleFlowId, options.evalPerformance) (or, if the
hardcoded true is intentional, add a clear inline comment above the call
referencing why evalPerformance is overridden and the prior check at
options.evalPerformance) so the behavior is consistent and obvious when locating
the code around shouldEvaluateExecution and bubbleFlowId.
🧹 Nitpick comments (11)
apps/bubble-studio/src/hooks/useRunExecution.ts (2)

123-123: Consider making evalPerformance configurable.

The evalPerformance=true query parameter is hardcoded. Based on the PR description, evaluation should only run when opt-in via this flag. Consider exposing this as an option in RunExecutionOptions to allow callers to control whether evaluation runs.

♻️ Suggested refactor
 interface RunExecutionOptions {
   validateCode?: boolean;
   updateCredentials?: boolean;
   inputs?: Record<string, unknown>;
+  evalPerformance?: boolean;
 }

Then in executeWithStreaming:

-          `/bubble-flow/${flowId}/execute-stream?evalPerformance=true`,
+          `/bubble-flow/${flowId}/execute-stream${payload.evalPerformance !== false ? '?evalPerformance=true' : ''}`,

282-284: Unused variable from event: line parsing.

The result of line.substring(6).trim() is computed but never assigned or used. This appears to be dead code.

♻️ Suggested fix
            if (line.startsWith('event:')) {
-              line.substring(6).trim();
+              // SSE event type line - currently unused, just skip
               continue;
             }
apps/bubblelab-api/src/db/schema-postgres.ts (1)

97-115: Schema design looks correct; consider adding indexes and constraints for better performance and data integrity.

The bubbleFlowEvaluations table structure is sound with appropriate foreign keys and cascade deletes. However, the current implementation lacks a few database-level safeguards:

  1. Missing index on executionId: Foreign key lookups would benefit from an index for optimal query performance.
  2. Rating constraint: The rating column (1-10) lacks a check constraint at the schema level. Currently relies on application-level validation only.
  3. issueType as enum: Consider using a PostgreSQL ENUM type instead of plain text to enforce valid values ('setup', 'workflow', 'input') at the database level rather than through comments.
packages/bubble-shared-schemas/src/bubbleflow-execution-schema.ts (1)

218-232: Consider stronger typing for executionLogs.

The executionLogs field uses z.array(z.any()), which loses type safety. Since the PR description indicates these are StreamingLogEvent[], consider importing and using the streaming event schema for better type safety and API documentation:

+import { streamingLogEventSchema } from './streaming-events';
+
 export const bubbleFlowExecutionDetailSchema = bubbleFlowExecutionSchema.extend(
   {
     executionLogs: z
-      .array(z.any())
+      .array(streamingLogEventSchema)
       .optional()
       .openapi({
         description: 'Array of streaming log events from the execution',
       }),
   }
 );

If the schema is intentionally loose to avoid tight coupling or to handle various event formats, this is acceptable as-is.

As per coding guidelines, remember to run pnpm build:core after modifying shared schemas since it is a separate package and types need to be regenerated.

apps/bubble-studio/src/components/execution_logs/LiveOutput.tsx (1)

121-122: Redundant dual export.

Having both a default export (line 31) and a named export (line 122) for the same component is redundant. Consider removing one for consistency.

 export default function LiveOutput({
   ...
 }
-
-// Export the connect function for external use
-export { LiveOutput };
apps/bubble-studio/src/components/execution_logs/ExecutionHistory.tsx (1)

272-290: Consider adding aria attributes for accessibility.

The clickable execution items should have proper accessibility attributes for keyboard navigation and screen readers.

♿ Optional accessibility enhancement
                   <div
                     key={execution.id}
                     onClick={() =>
                       canViewLogs && handleViewExecutionLogs(execution.id)
                     }
+                    role={canViewLogs ? 'button' : undefined}
+                    tabIndex={canViewLogs ? 0 : undefined}
+                    onKeyDown={(e) => {
+                      if (canViewLogs && (e.key === 'Enter' || e.key === ' ')) {
+                        e.preventDefault();
+                        handleViewExecutionLogs(execution.id);
+                      }
+                    }}
                     className={`rounded-lg border p-4 transition-colors ${
apps/bubble-studio/src/components/execution_logs/AllEventsView.tsx (1)

1007-1021: Consider extracting rating utilities to avoid duplication.

The getRatingColor and getRatingLabel functions are duplicated between this file and EvaluationIssuePopup.tsx. Consider extracting them to a shared utility.

♻️ Extract to shared utility

Create a new file utils/evaluationUtils.ts:

export function getRatingColor(rating: number): string {
  if (rating >= 7) return 'text-emerald-400 bg-emerald-500/20 border-emerald-500/30';
  if (rating >= 4) return 'text-yellow-400 bg-yellow-500/20 border-yellow-500/30';
  return 'text-red-400 bg-red-500/20 border-red-500/30';
}

export function getRatingLabel(rating: number): string {
  if (rating >= 9) return 'Excellent';
  if (rating >= 7) return 'Good';
  if (rating >= 5) return 'Fair';
  if (rating >= 3) return 'Poor';
  return 'Critical';
}
apps/bubble-studio/src/components/execution_logs/EvaluationIssuePopup.tsx (2)

12-17: Consider importing EvaluationResult type from shared schemas.

The EvaluationResult interface duplicates the structure from @bubblelab/shared-schemas. Importing the shared type ensures consistency and reduces maintenance burden.

♻️ Use shared type
-interface EvaluationResult {
-  working: boolean;
-  issueType: 'setup' | 'workflow' | 'input' | null;
-  summary: string;
-  rating: number;
-}
+import type { RiceEvaluationResult as EvaluationResult } from '@bubblelab/shared-schemas';

111-117: Add keyboard escape handler for accessibility.

The modal should close when the user presses Escape, unless a fix is in progress.

♿ Add escape key handler

Add a useEffect to handle the Escape key:

import { useEffect } from 'react';

// Inside the component, before the return:
useEffect(() => {
  const handleKeyDown = (e: KeyboardEvent) => {
    if (e.key === 'Escape' && !isFixingWithPearl) {
      onClose();
    }
  };
  
  if (isOpen) {
    document.addEventListener('keydown', handleKeyDown);
    return () => document.removeEventListener('keydown', handleKeyDown);
  }
}, [isOpen, isFixingWithPearl, onClose]);
apps/bubblelab-api/src/services/evaluation-trigger.ts (1)

109-114: Consider adding explicit return type annotation.

While TypeScript can infer the return type, explicit annotations improve readability and catch unintended changes.

📝 Add return type
-export async function getLatestEvaluation(bubbleFlowId: number) {
+export async function getLatestEvaluation(bubbleFlowId: number): Promise<typeof bubbleFlowEvaluations.$inferSelect | undefined> {
   return await db.query.bubbleFlowEvaluations.findFirst({
packages/bubble-shared-schemas/src/rice.ts (1)

57-59: Consider typing executionLogs more strictly.

Using z.array(z.unknown()) loses type safety. Since StreamingLogEvent is defined in this package, consider importing and using it.

📝 Stronger typing option

If circular import issues prevent direct use of StreamingLogEvent, the current unknown[] approach is acceptable with the comment noting the expected type. Otherwise:

+import { StreamingLogEventSchema } from './streaming-events.js';

 export const RiceRequestSchema = z.object({
   executionLogs: z
-    .array(z.unknown())
+    .array(StreamingLogEventSchema)
     .describe('StreamingLogEvent[] from execution'),
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a565ef1 and b29ca0f.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (35)
  • apps/bubble-studio/package.json
  • apps/bubble-studio/src/components/execution_logs/AllEventsView.tsx
  • apps/bubble-studio/src/components/execution_logs/EvaluationIssuePopup.tsx
  • apps/bubble-studio/src/components/execution_logs/EvaluationLoadingPopup.tsx
  • apps/bubble-studio/src/components/execution_logs/ExecutionHistory.tsx
  • apps/bubble-studio/src/components/execution_logs/LiveOutput.tsx
  • apps/bubble-studio/src/hooks/useExecutionDetail.ts
  • apps/bubble-studio/src/hooks/useExecutionStream.ts
  • apps/bubble-studio/src/hooks/useRunExecution.ts
  • apps/bubble-studio/src/pages/CredentialsPage.tsx
  • apps/bubble-studio/src/pages/DashboardPage.tsx
  • apps/bubble-studio/src/services/bubbleFlowApi.ts
  • apps/bubble-studio/src/stores/executionStore.ts
  • apps/bubble-studio/src/stores/liveOutputStore.ts
  • apps/bubblelab-api/drizzle-postgres/0016_add-evaluations-and-execution-logs.sql
  • apps/bubblelab-api/drizzle-postgres/meta/0016_snapshot.json
  • apps/bubblelab-api/drizzle-postgres/meta/_journal.json
  • apps/bubblelab-api/drizzle-sqlite/0016_add-evaluations-and-execution-logs.sql
  • apps/bubblelab-api/drizzle-sqlite/meta/0016_snapshot.json
  • apps/bubblelab-api/drizzle-sqlite/meta/_journal.json
  • apps/bubblelab-api/src/db/schema-postgres.ts
  • apps/bubblelab-api/src/db/schema-sqlite.ts
  • apps/bubblelab-api/src/db/schema.ts
  • apps/bubblelab-api/src/routes/bubble-flows.ts
  • apps/bubblelab-api/src/schemas/bubble-flows.ts
  • apps/bubblelab-api/src/services/ai/rice.ts
  • apps/bubblelab-api/src/services/bubble-flow-execution.ts
  • apps/bubblelab-api/src/services/evaluation-trigger.ts
  • apps/bubblelab-api/src/services/execution.ts
  • packages/bubble-shared-schemas/src/bubbleflow-execution-schema.ts
  • packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts
  • packages/bubble-shared-schemas/src/credential-schema.ts
  • packages/bubble-shared-schemas/src/index.ts
  • packages/bubble-shared-schemas/src/rice.ts
  • packages/bubble-shared-schemas/src/streaming-events.ts
💤 Files with no reviewable changes (1)
  • apps/bubble-studio/src/hooks/useExecutionStream.ts
🚧 Files skipped from review as they are similar to previous changes (14)
  • apps/bubblelab-api/src/services/execution.ts
  • apps/bubble-studio/src/components/execution_logs/EvaluationLoadingPopup.tsx
  • apps/bubble-studio/package.json
  • apps/bubblelab-api/drizzle-postgres/meta/_journal.json
  • packages/bubble-shared-schemas/src/index.ts
  • apps/bubblelab-api/src/schemas/bubble-flows.ts
  • apps/bubblelab-api/drizzle-postgres/meta/0016_snapshot.json
  • apps/bubblelab-api/drizzle-postgres/0016_add-evaluations-and-execution-logs.sql
  • apps/bubblelab-api/drizzle-sqlite/0016_add-evaluations-and-execution-logs.sql
  • apps/bubblelab-api/drizzle-sqlite/meta/0016_snapshot.json
  • apps/bubble-studio/src/stores/liveOutputStore.ts
  • apps/bubblelab-api/src/db/schema.ts
  • apps/bubblelab-api/drizzle-sqlite/meta/_journal.json
  • apps/bubble-studio/src/stores/executionStore.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/packages/bubble-shared-schemas/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/api.mdc)

**/packages/bubble-shared-schemas/**/*.{ts,tsx}: Write shared schemas between frontend and backend in /packages/bubble-shared-schemas directory
Run pnpm build:core after modifying shared schemas since it is a separate package and types need to be regenerated

Files:

  • packages/bubble-shared-schemas/src/streaming-events.ts
  • packages/bubble-shared-schemas/src/credential-schema.ts
  • packages/bubble-shared-schemas/src/bubbleflow-execution-schema.ts
  • packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts
  • packages/bubble-shared-schemas/src/rice.ts
packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts

📄 CodeRabbit inference engine (.cursor/rules/bubblelab.mdc)

Refer to packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts for documentation on how bubble flow is supposed to be generated

Files:

  • packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts
🧠 Learnings (12)
📚 Learning: 2025-12-19T03:17:06.825Z
Learnt from: CR
Repo: bubblelabai/BubbleLab PR: 0
File: .cursor/rules/bundling.mdc:0-0
Timestamp: 2025-12-19T03:17:06.825Z
Learning: Applies to apps/bubble-studio/public/bubble-types.txt : The bundle file at `apps/bubble-studio/public/bubble-types.txt` must be kept synchronized with `packages/bubble-core/dist/bubble-bundle.d.ts` after each build

Applied to files:

  • apps/bubble-studio/src/pages/CredentialsPage.tsx
  • packages/bubble-shared-schemas/src/credential-schema.ts
  • packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts
  • apps/bubblelab-api/src/db/schema-sqlite.ts
📚 Learning: 2025-12-19T03:16:48.801Z
Learnt from: CR
Repo: bubblelabai/BubbleLab PR: 0
File: .cursor/rules/api.mdc:0-0
Timestamp: 2025-12-19T03:16:48.801Z
Learning: Applies to **/packages/bubble-shared-schemas/**/*.{ts,tsx} : Write shared schemas between frontend and backend in `/packages/bubble-shared-schemas` directory

Applied to files:

  • apps/bubble-studio/src/pages/CredentialsPage.tsx
  • packages/bubble-shared-schemas/src/credential-schema.ts
  • packages/bubble-shared-schemas/src/bubbleflow-execution-schema.ts
  • packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts
  • apps/bubblelab-api/src/db/schema-postgres.ts
  • packages/bubble-shared-schemas/src/rice.ts
  • apps/bubblelab-api/src/db/schema-sqlite.ts
📚 Learning: 2025-12-19T03:17:06.825Z
Learnt from: CR
Repo: bubblelabai/BubbleLab PR: 0
File: .cursor/rules/bundling.mdc:0-0
Timestamp: 2025-12-19T03:17:06.825Z
Learning: Applies to apps/bubble-studio/src/components/MonacoEditor.tsx : The Monaco Editor integration in `apps/bubble-studio/src/components/MonacoEditor.tsx` must fetch the bundled types from `/bubble-types.txt`, wrap them in a module declaration for `bubblelab/bubble-core`, and add them to Monaco's TypeScript type system

Applied to files:

  • apps/bubble-studio/src/pages/CredentialsPage.tsx
  • apps/bubble-studio/src/hooks/useRunExecution.ts
📚 Learning: 2025-12-19T03:17:06.825Z
Learnt from: CR
Repo: bubblelabai/BubbleLab PR: 0
File: .cursor/rules/bundling.mdc:0-0
Timestamp: 2025-12-19T03:17:06.825Z
Learning: Applies to packages/bubble-core/src/index.ts : All new types and classes added to bubble-core must be exported from `packages/bubble-core/src/index.ts` to ensure they are included in the generated bundle

Applied to files:

  • apps/bubble-studio/src/pages/CredentialsPage.tsx
  • packages/bubble-shared-schemas/src/bubbleflow-execution-schema.ts
  • packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts
📚 Learning: 2025-12-22T09:55:47.873Z
Learnt from: CR
Repo: bubblelabai/BubbleLab PR: 0
File: .cursor/rules/bubblelab.mdc:0-0
Timestamp: 2025-12-22T09:55:47.873Z
Learning: Applies to packages/bubble-runtime/src/injection/README.md : Refer to packages/bubble-runtime/src/injection/README.md for information about credential injection and bubble parameter reinitialization

Applied to files:

  • apps/bubble-studio/src/pages/CredentialsPage.tsx
  • packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts
📚 Learning: 2025-12-19T03:17:06.825Z
Learnt from: CR
Repo: bubblelabai/BubbleLab PR: 0
File: .cursor/rules/bundling.mdc:0-0
Timestamp: 2025-12-19T03:17:06.825Z
Learning: Applies to packages/bubble-core/dist/**/*.d.ts : All external imports (except relative imports) must be removed from the bundled output to prevent circular processing and external dependency issues

Applied to files:

  • apps/bubble-studio/src/pages/CredentialsPage.tsx
  • apps/bubble-studio/src/hooks/useRunExecution.ts
  • packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts
📚 Learning: 2025-12-22T09:55:47.873Z
Learnt from: CR
Repo: bubblelabai/BubbleLab PR: 0
File: .cursor/rules/bubblelab.mdc:0-0
Timestamp: 2025-12-22T09:55:47.873Z
Learning: Applies to packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts : Refer to packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts for documentation on how bubble flow is supposed to be generated

Applied to files:

  • packages/bubble-shared-schemas/src/credential-schema.ts
  • apps/bubble-studio/src/services/bubbleFlowApi.ts
  • apps/bubble-studio/src/pages/DashboardPage.tsx
  • apps/bubble-studio/src/hooks/useRunExecution.ts
  • apps/bubble-studio/src/components/execution_logs/AllEventsView.tsx
  • apps/bubblelab-api/src/services/bubble-flow-execution.ts
  • packages/bubble-shared-schemas/src/bubbleflow-execution-schema.ts
  • packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts
  • apps/bubblelab-api/src/db/schema-postgres.ts
  • packages/bubble-shared-schemas/src/rice.ts
  • apps/bubblelab-api/src/db/schema-sqlite.ts
📚 Learning: 2025-12-19T03:17:06.825Z
Learnt from: CR
Repo: bubblelabai/BubbleLab PR: 0
File: .cursor/rules/bundling.mdc:0-0
Timestamp: 2025-12-19T03:17:06.825Z
Learning: Applies to packages/bubble-core/dist/**/*.d.ts : The type bundling system for Monaco Editor must process TypeScript declaration files (.d.ts) and inline all dependencies into a single self-contained bundle in `packages/bubble-core/dist/bubble-bundle.d.ts`

Applied to files:

  • apps/bubble-studio/src/hooks/useRunExecution.ts
  • packages/bubble-shared-schemas/src/bubbleflow-execution-schema.ts
📚 Learning: 2025-12-22T09:55:47.873Z
Learnt from: CR
Repo: bubblelabai/BubbleLab PR: 0
File: .cursor/rules/bubblelab.mdc:0-0
Timestamp: 2025-12-22T09:55:47.873Z
Learning: Applies to packages/bubble-runtime/src/extraction/README.md : Refer to packages/bubble-runtime/src/extraction/README.md for information about bubble parsing, dependency graphs, and per-invocation cloning

Applied to files:

  • apps/bubblelab-api/src/services/bubble-flow-execution.ts
📚 Learning: 2025-12-19T03:17:06.825Z
Learnt from: CR
Repo: bubblelabai/BubbleLab PR: 0
File: .cursor/rules/bundling.mdc:0-0
Timestamp: 2025-12-19T03:17:06.825Z
Learning: When adding new types to `bubblelab/shared-schemas`, they are automatically included in the bundle without requiring manual configuration changes

Applied to files:

  • packages/bubble-shared-schemas/src/bubbleflow-execution-schema.ts
  • packages/bubble-shared-schemas/src/rice.ts
📚 Learning: 2025-12-19T03:16:48.801Z
Learnt from: CR
Repo: bubblelabai/BubbleLab PR: 0
File: .cursor/rules/api.mdc:0-0
Timestamp: 2025-12-19T03:16:48.801Z
Learning: Applies to **/packages/bubble-shared-schemas/**/*.{ts,tsx} : Run `pnpm build:core` after modifying shared schemas since it is a separate package and types need to be regenerated

Applied to files:

  • packages/bubble-shared-schemas/src/bubbleflow-execution-schema.ts
  • packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts
📚 Learning: 2025-12-22T09:55:47.873Z
Learnt from: CR
Repo: bubblelabai/BubbleLab PR: 0
File: .cursor/rules/bubblelab.mdc:0-0
Timestamp: 2025-12-22T09:55:47.873Z
Learning: Applies to apps/bubble-studio/src/components/flow_visualizer/README.md : Refer to apps/bubble-studio/src/components/flow_visualizer/README.md for documentation on flow visualizer architecture and node rendering

Applied to files:

  • packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts
🧬 Code graph analysis (10)
apps/bubble-studio/src/hooks/useExecutionDetail.ts (2)
packages/bubble-shared-schemas/src/bubbleflow-execution-schema.ts (1)
  • BubbleFlowExecutionDetail (230-232)
apps/bubble-studio/src/services/bubbleFlowApi.ts (1)
  • bubbleFlowApi (8-77)
apps/bubblelab-api/src/services/ai/rice.ts (2)
packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts (2)
  • BUBBLE_STUDIO_INSTRUCTIONS (81-135)
  • BUBBLE_SPECIFIC_INSTRUCTIONS (312-364)
packages/bubble-shared-schemas/src/rice.ts (5)
  • RiceRequest (98-98)
  • RiceResponse (100-100)
  • RICE_DEFAULT_MODEL (6-6)
  • RiceEvaluationResult (93-93)
  • RiceEvaluationResultSchema (25-50)
apps/bubble-studio/src/services/bubbleFlowApi.ts (2)
packages/bubble-shared-schemas/src/bubbleflow-execution-schema.ts (1)
  • BubbleFlowExecutionDetail (230-232)
apps/bubble-studio/src/lib/api.ts (1)
  • api (263-263)
apps/bubble-studio/src/hooks/useRunExecution.ts (1)
apps/bubble-studio/src/stores/executionStore.ts (2)
  • ProcessEventResult (12-21)
  • getExecutionStore (1033-1036)
apps/bubblelab-api/src/routes/bubble-flows.ts (4)
apps/bubblelab-api/src/schemas/bubble-flows.ts (1)
  • getBubbleFlowExecutionDetailRoute (669-725)
apps/bubblelab-api/src/middleware/auth.ts (1)
  • getUserId (284-293)
apps/bubblelab-api/src/db/schema-postgres.ts (1)
  • bubbleFlowExecutions (82-95)
apps/bubblelab-api/src/db/schema-sqlite.ts (1)
  • bubbleFlowExecutions (74-89)
apps/bubble-studio/src/components/execution_logs/ExecutionHistory.tsx (6)
apps/bubble-studio/src/hooks/useExecutionDetail.ts (1)
  • useFetchExecutionDetail (17-26)
apps/bubble-studio/src/stores/uiStore.ts (1)
  • useUIStore (207-307)
apps/bubble-studio/src/stores/executionStore.ts (1)
  • getExecutionStore (1033-1036)
packages/bubble-shared-schemas/src/streaming-events.ts (1)
  • StreamingLogEvent (12-80)
apps/bubble-studio/src/utils/executionLogsFormatUtils.tsx (1)
  • formatTimestamp (68-70)
apps/bubble-studio/src/components/execution_logs/JsonRenderer.tsx (1)
  • JsonRenderer (800-844)
apps/bubblelab-api/src/services/bubble-flow-execution.ts (11)
packages/bubble-shared-schemas/src/streaming-events.ts (1)
  • StreamingLogEvent (12-80)
apps/bubblelab-api/src/services/execution.ts (1)
  • runBubbleFlowWithStreaming (286-315)
apps/bubblelab-api/src/config/pricing.ts (1)
  • getPricingTable (544-546)
apps/bubblelab-api/src/db/schema-postgres.ts (1)
  • bubbleFlowExecutions (82-95)
apps/bubblelab-api/src/db/schema-sqlite.ts (1)
  • bubbleFlowExecutions (74-89)
packages/bubble-core/src/logging/BubbleLogger.ts (1)
  • error (585-606)
packages/bubble-core/src/logging/StreamingBubbleLogger.ts (1)
  • error (360-387)
packages/bubble-core/src/logging/WebhookStreamLogger.ts (1)
  • error (242-269)
apps/bubblelab-api/src/services/evaluation-trigger.ts (2)
  • shouldEvaluateExecution (37-67)
  • storeEvaluation (81-101)
apps/bubblelab-api/src/services/ai/rice.ts (2)
  • runRice (111-211)
  • getRiceModelUsed (399-401)
apps/bubblelab-api/src/config/env.ts (1)
  • env (67-95)
packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts (1)
packages/bubble-shared-schemas/src/credential-schema.ts (1)
  • generateCredentialsSummary (251-259)
apps/bubblelab-api/src/db/schema-postgres.ts (1)
apps/bubblelab-api/src/db/schema-sqlite.ts (4)
  • bubbleFlowEvaluations (91-109)
  • bubbleFlowExecutions (74-89)
  • bubbleFlows (20-47)
  • bubbleFlowEvaluationsRelations (211-223)
packages/bubble-shared-schemas/src/rice.ts (2)
packages/bubble-shared-schemas/src/ai-models.ts (2)
  • AvailableModel (33-33)
  • AvailableModels (4-31)
packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts (1)
  • RECOMMENDED_MODELS (17-26)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: test
  • GitHub Check: Cloudflare Pages: bubblelab-documentation
🔇 Additional comments (43)
packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts (2)

10-13: LGTM!

The import correctly adds generateCredentialsSummary alongside SYSTEM_CREDENTIALS from the credential schema. This enables injecting credential metadata into AI prompts.


94-105: LGTM!

The credentials summary is properly injected into the Bubble Studio instructions prompt. The bold markdown formatting (**...**) appropriately highlights this information for AI agents. The updated Console and History descriptions align with the PR's execution history replay feature.

As per coding guidelines, ensure pnpm build:core is run after merging since this is in the shared schemas package.

apps/bubble-studio/src/pages/CredentialsPage.tsx (1)

16-26: LGTM!

Good refactoring to centralize credential configuration in the shared schemas package. The import structure correctly separates:

  • Runtime value (CREDENTIAL_TYPE_CONFIG) in regular imports
  • Type-only imports (ScopeDescription, CredentialResponse, CreateCredentialRequest) using type keyword

This ensures better tree-shaking and clearer intent.

packages/bubble-shared-schemas/src/credential-schema.ts (3)

5-14: LGTM!

The CredentialConfig interface is well-structured with clear property names that serve both UI rendering and AI prompt generation purposes. The credentialConfigurations field using Record<string, unknown> provides flexibility for credential-specific settings like ignoreSSL.


19-246: LGTM!

The CREDENTIAL_TYPE_CONFIG constant is well-structured with comprehensive metadata for all credential types. The as const satisfies Record<CredentialType, CredentialConfig> pattern ensures compile-time type safety while preserving literal types for better inference.

As per coding guidelines, ensure pnpm build:core is run after merging since this modifies the shared schemas package.


248-259: LGTM!

The generateCredentialsSummary function correctly iterates over the credential configuration and produces a human-readable summary suitable for AI agent context. The format clearly presents label, type key, and description for each credential.

apps/bubble-studio/src/hooks/useRunExecution.ts (1)

165-253: Event processing refactor looks well-structured.

The centralized processEvent approach with a switch for UI-specific actions is clean and maintainable. The new evaluation events (start_evaluating, end_evaluating) are correctly delegated to the store's processEvent method, keeping UI logic separate from state management.

apps/bubblelab-api/src/db/schema-postgres.ts (1)

206-229: Relations are correctly wired.

The bidirectional relations between bubbleFlowExecutions, bubbleFlowEvaluations, and bubbleFlows are properly configured. The many relation from executions to evaluations allows for potential future re-evaluations of the same execution.

apps/bubblelab-api/src/db/schema-sqlite.ts (2)

91-109: SQLite schema correctly mirrors PostgreSQL structure.

The bubbleFlowEvaluations table definition correctly uses SQLite-appropriate types (int with mode: 'boolean', int with mode: 'timestamp') while maintaining structural parity with the PostgreSQL schema. The foreign key constraints and cascade deletes are properly configured.


200-223: Relations correctly match PostgreSQL schema.

The relation definitions maintain consistency with the PostgreSQL schema, ensuring the ORM layer works correctly across both database backends.

apps/bubble-studio/src/services/bubbleFlowApi.ts (1)

64-76: New API method follows existing patterns.

The getBubbleFlowExecutionDetail method is well-implemented:

  • Properly typed with BubbleFlowExecutionDetail return type
  • Follows the existing URL pattern conventions
  • JSDoc correctly references the shared schema
packages/bubble-shared-schemas/src/streaming-events.ts (2)

32-34: New evaluation event types correctly extend the streaming contract.

The start_evaluating and end_evaluating event types align with the evaluation lifecycle described in the PR. These events enable the frontend to show loading states and results respectively.


73-79: evaluationResult structure aligns with database schema.

The evaluationResult field correctly mirrors the core fields from bubbleFlowEvaluations table (working, issueType, summary, rating). The issueType union matches the documented classification: 'setup' (config/credentials), 'workflow' (code logic), 'input' (bad input data), or null if working.

After modifying shared schemas in this package, run pnpm build:core from the repository root to regenerate types, as specified in the coding guidelines.

apps/bubble-studio/src/hooks/useExecutionDetail.ts (1)

1-26: LGTM!

The hook implementation is clean and well-documented. Using useMutation for an imperatively-triggered fetch (user clicking on execution history) is a reasonable pattern, and the comment clearly explains the rationale.

apps/bubble-studio/src/components/execution_logs/LiveOutput.tsx (2)

46-65: LGTM - Evaluation lifecycle integration looks correct.

The evaluation state management and Pearl integration are properly wired:

  • Defensive check for flowId before starting Pearl generation
  • Proper dismissal of popup after triggering fix
  • Clean separation of concerns between evaluation state and Pearl chat

108-116: Callback signature is correctly implemented.

The onFixWithPearl callback is properly typed in EvaluationIssuePopup (line 23: onFixWithPearl: (issueDescription: string) => void) and correctly invoked with a string argument at lines 98-101. The popup constructs an issueContext string and passes it to the callback, matching the expected signature in LiveOutput.tsx.

Likely an incorrect or invalid review comment.

apps/bubble-studio/src/pages/DashboardPage.tsx (1)

147-169: Good refactor - extracted AI agent logic into reusable helper.

The askAIAgent helper improves code organization and makes the flow template more readable.

One minor concern: result.data.response assumes a specific shape for the AI agent's response data. If result.data could have a different structure, this could cause runtime issues. Consider adding a type guard or null check:

return result.data?.response ?? '';

However, if AIAgentBubble guarantees this structure when result.success is true, the current implementation is fine.

apps/bubblelab-api/src/routes/bubble-flows.ts (2)

434-435: LGTM - evalPerformance query param integration.

Clean extraction of the evalPerformance flag from query params and proper forwarding to the execution tracking service. The boolean conversion using string comparison is correct.

Also applies to: 452-452


955-1022: LGTM - Well-implemented execution detail endpoint.

The new route handler follows the established patterns in this file and includes proper security controls:

  • User ownership verification before returning data (line 970-988)
  • Execution scoped to the specific flow via bubbleFlowId constraint (line 995)
  • Appropriate error responses (400 for invalid IDs, 404 for not found)
  • Consistent response shape with the detail schema
apps/bubble-studio/src/components/execution_logs/ExecutionHistory.tsx (4)

1-25: LGTM - Imports are well-organized.

The new imports for execution detail fetching, store access, UI state management, and the StreamingLogEvent type are correctly added to support the execution log viewing feature.


40-49: LGTM - State management for execution selection.

The selectedExecutionId state and fetchExecutionDetailMutation are properly initialized to track the selected execution and manage the fetch lifecycle.


211-216: LGTM - Clean effect for clearing selection on new execution.

The effect properly clears the selected execution when a new execution starts, preventing stale state display.


409-423: LGTM - Clear visual feedback for log viewing state.

The "View Logs" indicator provides good UX with loading spinner, selected state icon, and instructive text.

apps/bubblelab-api/src/services/bubble-flow-execution.ts (4)

10-25: LGTM - Clean imports for evaluation integration.

The imports for evaluation triggers, Rice helpers, and credential types are properly organized and support the new evaluation flow.


128-142: LGTM - Well-designed log collection pattern.

The collection callback approach elegantly captures all streaming events while optionally forwarding to the original callback. This ensures logs are always available for history replay.


176-185: Evaluation only runs when originalCallback exists - is this intentional?

The condition if (originalCallback && options.evalPerformance) means webhook/cron executions without a streaming client won't trigger evaluation. Verify this aligns with the intended behavior where evaluation should only run for interactive executions.


288-296: LGTM - Proper non-blocking error handling for evaluation.

The evaluation errors are caught and streamed as end_evaluating events without failing the primary execution. This ensures evaluation failures don't impact the user's workflow.

apps/bubble-studio/src/components/execution_logs/AllEventsView.tsx (4)

84-91: LGTM - Clean destructuring of evaluation state.

The extraction of isEvaluating and evaluationResult from the execution store properly enables the evaluation UI flow.


258-271: LGTM - Well-designed handleFixWithPearl enhancement.

The optional issueDetails parameter allows for context-aware Pearl prompts while maintaining backward compatibility with generic error handling.


599-647: LGTM - Clear Workflow Check UI with status indicators.

The Workflow Check section provides good visual feedback with appropriate icons for loading, success, and failure states, plus a rating badge when complete.


1101-1129: LGTM - Correct conditional rendering of "Fix with Pearl" CTA.

The CTA is properly shown only for workflow issues, correctly excluding setup and input issues that require user action outside the workflow editor.

apps/bubble-studio/src/components/execution_logs/EvaluationIssuePopup.tsx (2)

157-166: LGTM - Proper close button with disabled state.

The close button correctly disables during the "Fix with Pearl" operation, preventing accidental closure of the modal while analysis is in progress.


234-253: LGTM - Clean footer with conditional Fix with Pearl button.

The footer properly shows the "Fix with Pearl" button only for workflow issues, and handles the loading state with a spinner.

apps/bubblelab-api/src/services/ai/rice.ts (4)

29-102: LGTM - Comprehensive system prompt with clear evaluation criteria.

The system prompt provides excellent context including Bubble Studio instructions, issue type definitions, rating scale, and specific evaluation criteria. The binary data detection guidance is particularly valuable.


221-228: Binary regex patterns may have issues with raw byte matching.

The patterns like /^\x89PNG/i and /^\xFF\xD8\xFF/ attempt to match binary file headers in JavaScript strings. These will only work if the binary data has been decoded as ISO-8859-1 or similar, not if it's base64-encoded or UTF-8 interpreted. The base64 patterns should catch most cases, but consider this edge case.

The earlier patterns for base64 and data URLs should handle most real-world cases, so this is likely fine in practice.


259-298: LGTM - Robust sanitization with recursion protection.

The sanitizeValue function properly handles nested structures with a depth limit, binary data detection, and string truncation. Good defensive coding.


344-394: LGTM - Clean log summarization for token efficiency.

The summarizeLogs function extracts key metrics (event counts, errors, warnings, execution status) that enable quick analysis without needing to process full logs.

apps/bubblelab-api/src/services/evaluation-trigger.ts (3)

16-23: LGTM - Clear evaluation trigger result type.

The EvaluationTriggerResult interface with its discriminated reason union makes the evaluation decision logic transparent and easy to debug.


37-67: LGTM - Well-structured evaluation trigger logic.

The decision tree is clear: disabled → skip, first execution → evaluate, previous issues → evaluate, otherwise skip. Good documentation explains each path.


81-101: LGTM - Clean evaluation storage with proper null handling.

The storeEvaluation function correctly handles the nullable issueType field and returns the inserted record ID for reference.

packages/bubble-shared-schemas/src/rice.ts (3)

1-6: LGTM - Clean imports and model constant.

The default model constant is properly typed and references the shared RECOMMENDED_MODELS configuration.


25-50: LGTM - Well-designed evaluation result schema.

The schema has clear field definitions with appropriate constraints (rating 1-10, nullable issueType) and excellent documentation via .describe() calls.


92-100: LGTM - Correct use of z.input vs z.infer.

Using z.input for RiceRequest correctly represents what callers provide (before defaults are applied), while z.infer for the response represents the parsed/validated output. Good TypeScript/Zod practice with helpful comments.

Comment on lines +196 to +199
getExecutionStore(flowId).restoreFromHistory(
executionDetail.executionLogs as StreamingLogEvent[],
currentFlow?.bubbleParameters
);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Find the BubbleFlowExecutionDetail type definition
rg -n "BubbleFlowExecutionDetail" --type=ts -A 10 | head -50

Repository: bubblelabai/BubbleLab

Length of output: 3942


🏁 Script executed:

# Check the ExecutionHistory.tsx file context around line 196-199
rg -n "executionDetail" apps/bubble-studio/src/components/execution_logs/ExecutionHistory.tsx -B 5 -A 5

Repository: bubblelabai/BubbleLab

Length of output: 837


🏁 Script executed:

# Find StreamingLogEvent type definition
rg -n "StreamingLogEvent" --type=ts -A 5 | head -40

Repository: bubblelabai/BubbleLab

Length of output: 3469


🏁 Script executed:

# Check how executionLogs is defined in the type
rg -n "executionLogs" --type=ts -B 3 -A 3 | head -60

Repository: bubblelabai/BubbleLab

Length of output: 5752


🏁 Script executed:

# Find and read the bubbleFlowExecutionDetailSchema definition
rg -n "bubbleFlowExecutionDetailSchema" --type=ts -A 30 | head -80

Repository: bubblelabai/BubbleLab

Length of output: 6115


🏁 Script executed:

# Check what type executionLogs has in the schema
rg -n "executionLogs" packages/bubble-shared-schemas/src/bubbleflow-execution-schema.ts -B 2 -A 2

Repository: bubblelabai/BubbleLab

Length of output: 230


🏁 Script executed:

# Search for StreamingLogEvent schema definition
rg -n "streamingLogEvent" packages/bubble-shared-schemas/src --type=ts -i | head -20

Repository: bubblelabai/BubbleLab

Length of output: 398


🏁 Script executed:

# Check the full bubbleflowExecutionSchema to see StreamingLogEvent usage
rg -n "StreamingLogEvent" packages/bubble-shared-schemas/src/bubbleflow-execution-schema.ts -B 3 -A 3

Repository: bubblelabai/BubbleLab

Length of output: 47


🏁 Script executed:

# Check the StreamingLogEvent interface definition
cat -n packages/bubble-shared-schemas/src/streaming-events.ts | head -50

Repository: bubblelabai/BubbleLab

Length of output: 2007


🏁 Script executed:

# Look for Zod schema for StreamingLogEvent
rg -n "streamingLogEventSchema\|StreamingLogEvent.*z\\.object\|streamingLogEvent.*z\\." packages/bubble-shared-schemas/src --type=ts -i

Repository: bubblelabai/BubbleLab

Length of output: 47


🏁 Script executed:

# Check if there's a Zod schema defined for StreamingLogEvent anywhere
rg -n "z\\.object.*type.*|.*StreamingLogEvent" packages/bubble-shared-schemas/src --type=ts -B 2 -A 10 | grep -A 10 "z\.object"

Repository: bubblelabai/BubbleLab

Length of output: 47


🏁 Script executed:

# Look at how executionLogs are stored in the database to see what validation exists there
rg -n "executionLogs" apps/bubblelab-api/src/services/bubble-flow-execution.ts -B 3 -A 3

Repository: bubblelabai/BubbleLab

Length of output: 1345


Consider adding runtime validation for executionLogs array items before casting.

The executionLogs field is typed as z.array(z.any()).optional() in the schema, providing no validation of individual event structures. While the nullish check at line 190 ensures the array exists, the subsequent as StreamingLogEvent[] cast assumes all items conform to the expected shape without runtime verification. If backend data ever deviates from the expected structure, the code would silently process malformed events.

Add a runtime validation step (using Zod or a type guard) to ensure each event matches the StreamingLogEvent interface before passing to restoreFromHistory().

🤖 Prompt for AI Agents
In @apps/bubble-studio/src/components/execution_logs/ExecutionHistory.tsx around
lines 196 - 199, The call to getExecutionStore(flowId).restoreFromHistory(...)
currently casts executionDetail.executionLogs to StreamingLogEvent[] without
runtime checks; add a validation step that verifies each item matches the
StreamingLogEvent shape (using your Zod schema or a type guard) before calling
restoreFromHistory: iterate executionDetail.executionLogs, run
zodSchema.parse/parseAsync or a guard on each item, collect only valid events
(or log/filter invalid ones), then pass the validated StreamingLogEvent[] to
restoreFromHistory to avoid silently processing malformed events.

Comment on lines +149 to +152
tools: [], // No tools needed - bubble knowledge is in system prompt
maxIterations: 5, // One-shot evaluation
credentials: finalCredentials,
});
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Comment-code inconsistency: "One-shot" vs maxIterations: 5.

The comment says "One-shot evaluation" but maxIterations is set to 5. Clarify whether this is intentional (allowing retries) or if it should be 1.

📝 Suggested fix
       tools: [], // No tools needed - bubble knowledge is in system prompt
-      maxIterations: 5, // One-shot evaluation
+      maxIterations: 1, // One-shot evaluation - no tool calls needed
       credentials: finalCredentials,

Or if 5 is intentional:

       tools: [], // No tools needed - bubble knowledge is in system prompt
-      maxIterations: 5, // One-shot evaluation
+      maxIterations: 5, // Allow up to 5 iterations for complex evaluations
       credentials: finalCredentials,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
tools: [], // No tools needed - bubble knowledge is in system prompt
maxIterations: 5, // One-shot evaluation
credentials: finalCredentials,
});
tools: [], // No tools needed - bubble knowledge is in system prompt
maxIterations: 1, // One-shot evaluation - no tool calls needed
credentials: finalCredentials,
});
🤖 Prompt for AI Agents
In @apps/bubblelab-api/src/services/ai/rice.ts around lines 149 - 152, The
inline comment says "One-shot evaluation" but the configuration sets
maxIterations = 5, causing a mismatch; either change maxIterations to 1 to
enforce true one-shot behavior or update the comment to explain that multiple
iterations/retries are allowed (e.g., "Allow up to 5 iterations/retries");
locate the code where maxIterations is assigned (the object literal containing
tools, maxIterations, credentials — referencing the maxIterations property) and
make the comment/value consistent.

Comment on lines +228 to +236
try {
// Check if we should evaluate
const evalTrigger = await shouldEvaluateExecution(bubbleFlowId, true);
console.log('[Evaluation] Trigger result:', evalTrigger);

if (!evalTrigger.shouldEvaluate) {
console.log('[Evaluation] Skipping evaluation:', evalTrigger.reason);
return;
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Hardcoded true bypasses the evalPerformance flag check.

Line 230 calls shouldEvaluateExecution(bubbleFlowId, true) with a hardcoded true, which means the evalPerformance parameter passed to this function is ignored. The intent appears to be that we've already verified options.evalPerformance is true at line 177.

Consider adding a comment to clarify this, or pass the actual flag for consistency:

📝 Suggested fix for clarity
   try {
-    // Check if we should evaluate
-    const evalTrigger = await shouldEvaluateExecution(bubbleFlowId, true);
+    // Check if we should evaluate (evalPerformance already verified by caller)
+    const evalTrigger = await shouldEvaluateExecution(bubbleFlowId, true);
     console.log('[Evaluation] Trigger result:', evalTrigger);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
try {
// Check if we should evaluate
const evalTrigger = await shouldEvaluateExecution(bubbleFlowId, true);
console.log('[Evaluation] Trigger result:', evalTrigger);
if (!evalTrigger.shouldEvaluate) {
console.log('[Evaluation] Skipping evaluation:', evalTrigger.reason);
return;
}
try {
// Check if we should evaluate (evalPerformance already verified by caller)
const evalTrigger = await shouldEvaluateExecution(bubbleFlowId, true);
console.log('[Evaluation] Trigger result:', evalTrigger);
if (!evalTrigger.shouldEvaluate) {
console.log('[Evaluation] Skipping evaluation:', evalTrigger.reason);
return;
}
🤖 Prompt for AI Agents
In @apps/bubblelab-api/src/services/bubble-flow-execution.ts around lines 228 -
236, The call to shouldEvaluateExecution(bubbleFlowId, true) hardcodes the
evalPerformance flag and bypasses the actual options.evalPerformance value
checked earlier; change the call to shouldEvaluateExecution(bubbleFlowId,
options.evalPerformance) (or, if the hardcoded true is intentional, add a clear
inline comment above the call referencing why evalPerformance is overridden and
the prior check at options.evalPerformance) so the behavior is consistent and
obvious when locating the code around shouldEvaluateExecution and bubbleFlowId.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts (1)

96-97: Consider the placement and formatting of credential information.

Two observations:

  1. JSON.stringify(..., null, 2) produces multi-line indented JSON which may not render cleanly within this paragraph context. Consider using .join(', ') for inline formatting.

  2. generateCredentialsSummary() describes "Available credentials that users can configure" (all credential types), but it's placed in the "SYSTEM CREDENTIALS" section. This may confuse the AI since system credentials aren't user-configurable. Consider moving this summary to the "USER CREDENTIALS" section or creating a separate generateSystemCredentialsSummary() function.

💡 Suggested inline formatting for the credentials list
-  - Available system credentials: ${JSON.stringify(Array.from(SYSTEM_CREDENTIALS), null, 2)}
-  - ${generateCredentialsSummary()}
+  - Available system credentials: ${Array.from(SYSTEM_CREDENTIALS).join(', ')}

Then move generateCredentialsSummary() to the USER CREDENTIALS section if appropriate.

apps/bubble-studio/src/components/execution_logs/ExecutionHistory.tsx (1)

197-201: Consider validating executionLogs structure before type casting.

The as StreamingLogEvent[] cast assumes the API response matches the expected type. If the backend returns a different structure (e.g., schema drift), this could cause silent runtime errors in restoreFromHistory.

Consider adding runtime validation or using a type guard:

// Example validation before casting
if (!Array.isArray(executionDetail.executionLogs)) {
  toast.error('Invalid execution logs format');
  return;
}
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b29ca0f and da51029.

📒 Files selected for processing (2)
  • apps/bubble-studio/src/components/execution_logs/ExecutionHistory.tsx
  • packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/packages/bubble-shared-schemas/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/api.mdc)

**/packages/bubble-shared-schemas/**/*.{ts,tsx}: Write shared schemas between frontend and backend in /packages/bubble-shared-schemas directory
Run pnpm build:core after modifying shared schemas since it is a separate package and types need to be regenerated

Files:

  • packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts
packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts

📄 CodeRabbit inference engine (.cursor/rules/bubblelab.mdc)

Refer to packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts for documentation on how bubble flow is supposed to be generated

Files:

  • packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts
🧠 Learnings (9)
📚 Learning: 2025-12-22T09:55:47.873Z
Learnt from: CR
Repo: bubblelabai/BubbleLab PR: 0
File: .cursor/rules/bubblelab.mdc:0-0
Timestamp: 2025-12-22T09:55:47.873Z
Learning: Applies to packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts : Refer to packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts for documentation on how bubble flow is supposed to be generated

Applied to files:

  • packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts
📚 Learning: 2025-12-19T03:16:48.801Z
Learnt from: CR
Repo: bubblelabai/BubbleLab PR: 0
File: .cursor/rules/api.mdc:0-0
Timestamp: 2025-12-19T03:16:48.801Z
Learning: Applies to **/packages/bubble-shared-schemas/**/*.{ts,tsx} : Write shared schemas between frontend and backend in `/packages/bubble-shared-schemas` directory

Applied to files:

  • packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts
📚 Learning: 2025-12-22T09:55:47.873Z
Learnt from: CR
Repo: bubblelabai/BubbleLab PR: 0
File: .cursor/rules/bubblelab.mdc:0-0
Timestamp: 2025-12-22T09:55:47.873Z
Learning: Applies to packages/bubble-runtime/src/injection/README.md : Refer to packages/bubble-runtime/src/injection/README.md for information about credential injection and bubble parameter reinitialization

Applied to files:

  • packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts
📚 Learning: 2025-12-19T03:17:06.825Z
Learnt from: CR
Repo: bubblelabai/BubbleLab PR: 0
File: .cursor/rules/bundling.mdc:0-0
Timestamp: 2025-12-19T03:17:06.825Z
Learning: Applies to packages/bubble-core/src/index.ts : All new types and classes added to bubble-core must be exported from `packages/bubble-core/src/index.ts` to ensure they are included in the generated bundle

Applied to files:

  • packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts
📚 Learning: 2025-12-19T03:16:48.801Z
Learnt from: CR
Repo: bubblelabai/BubbleLab PR: 0
File: .cursor/rules/api.mdc:0-0
Timestamp: 2025-12-19T03:16:48.801Z
Learning: Applies to **/packages/bubble-shared-schemas/**/*.{ts,tsx} : Run `pnpm build:core` after modifying shared schemas since it is a separate package and types need to be regenerated

Applied to files:

  • packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts
📚 Learning: 2025-12-19T03:17:06.825Z
Learnt from: CR
Repo: bubblelabai/BubbleLab PR: 0
File: .cursor/rules/bundling.mdc:0-0
Timestamp: 2025-12-19T03:17:06.825Z
Learning: Applies to packages/bubble-core/dist/**/*.d.ts : All external imports (except relative imports) must be removed from the bundled output to prevent circular processing and external dependency issues

Applied to files:

  • packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts
📚 Learning: 2025-12-22T09:55:47.873Z
Learnt from: CR
Repo: bubblelabai/BubbleLab PR: 0
File: .cursor/rules/bubblelab.mdc:0-0
Timestamp: 2025-12-22T09:55:47.873Z
Learning: Applies to apps/bubble-studio/src/components/flow_visualizer/README.md : Refer to apps/bubble-studio/src/components/flow_visualizer/README.md for documentation on flow visualizer architecture and node rendering

Applied to files:

  • packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts
📚 Learning: 2025-12-22T09:55:47.873Z
Learnt from: CR
Repo: bubblelabai/BubbleLab PR: 0
File: .cursor/rules/bubblelab.mdc:0-0
Timestamp: 2025-12-22T09:55:47.873Z
Learning: Applies to packages/bubble-core/CREATE_BUBBLE_README.md : Refer to packages/bubble-core/CREATE_BUBBLE_README.md for instructions on how to create bubbles

Applied to files:

  • packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts
📚 Learning: 2025-12-22T09:55:47.873Z
Learnt from: CR
Repo: bubblelabai/BubbleLab PR: 0
File: .cursor/rules/bubblelab.mdc:0-0
Timestamp: 2025-12-22T09:55:47.873Z
Learning: Applies to README.md : Refer to README.md for general information about bubble lab and project structure

Applied to files:

  • packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts
🧬 Code graph analysis (1)
packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts (1)
packages/bubble-shared-schemas/src/credential-schema.ts (2)
  • SYSTEM_CREDENTIALS (294-307)
  • generateCredentialsSummary (251-259)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: test
  • GitHub Check: Cloudflare Pages: bubblelab-documentation
🔇 Additional comments (10)
packages/bubble-shared-schemas/src/bubbleflow-generation-prompts.ts (4)

10-13: LGTM!

The imports are correctly sourced and both SYSTEM_CREDENTIALS and generateCredentialsSummary are used appropriately later in the file to enhance the prompt documentation.


122-123: LGTM!

The updated panel descriptions accurately reflect the new execution history and log replay functionality described in the PR objectives.


318-327: LGTM!

The new credential error debugging section provides clear, actionable guidance that addresses a real user pain point. The explicit instruction to avoid directing users to the Credentials page for system credentials is particularly valuable and consistent with the documentation added earlier in the file.


10-13: Reminder: Run pnpm build:core after merging.

As per coding guidelines, shared schemas in /packages/bubble-shared-schemas require rebuilding since it's a separate package and types need to be regenerated.

apps/bubble-studio/src/components/execution_logs/ExecutionHistory.tsx (6)

1-25: LGTM!

Imports are well-organized and align with the new functionality. Good practice using type for the StreamingLogEvent import.


40-49: LGTM!

State and mutation hook initialization is clean and follows React patterns correctly.


213-218: LGTM!

Good UX consideration: clearing the historical execution view when a new execution begins ensures users see fresh results.


274-292: LGTM!

Good implementation of the selectable execution items:

  • Per-item loading state tracking via mutation variables comparison
  • Conditional click handling prevents interaction with running executions
  • Visual feedback with selection highlighting and cursor styling

335-356: Good use of event propagation control.

The stopPropagation() on the "Use Version" button correctly prevents the row click handler from firing when users interact with the nested button.


411-425: Clean loading indicator implementation.

The conditional rendering of spinner vs. eye icon provides clear visual feedback for the current action state. The indicator placement at the bottom with the helper text is a nice UX touch.

@zhubzy zhubzy merged commit c86e63a into main Jan 12, 2026
3 of 4 checks passed
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