Conversation
- Updated tool type casting in AgentTools component for better type safety. - Changed trend color classes in StatCard and AgentEvalsTab components to use new design tokens. - Modified LogsPage component to initialize selectedTransport and levelFilter states with "all" for improved filtering. - Adjusted ObservabilityPage component to set spanTypeFilter and entityTypeFilter defaults to "all". - Enhanced DashboardPage component styles to align with new design guidelines. - Updated Mastra configuration to include new headers and commented out unused middleware for clarity.
|
Keep this PR in a mergeable state → Learn moreAll Green is an AI agent that automatically: ✅ Addresses code review comments ✅ Fixes failing CI checks ✅ Resolves merge conflicts |
Reviewer's GuideRefactors several dashboard and logging components to use consistent design tokens and more explicit default filter sentinel values like "all", tightens null/undefined handling with nullish coalescing and boolean casting, adjusts key and style fallbacks, and updates Mastra server configuration headers while commenting out an unused body-parsing middleware. Sequence diagram for logs filtering with "all" sentinel statesequenceDiagram
actor User
participant UI as LogsPage
participant LT as useLogTransports
participant UL as useLogs
participant URL as useRunLogs
User->>UI: Load logs dashboard
activate UI
UI->>LT: useLogTransports()
LT-->>UI: transports
UI->>UL: useLogs(undefined)
note over UI,UL: selectedTransport = "all" so hook arg is undefined
UL-->>UI: logs
UI->>URL: useRunLogs(null, undefined)
URL-->>UI: runLogs
UI-->>User: Render logs with all transports and levels
deactivate UI
User->>UI: Change transport select to specificTransport
activate UI
UI->>UI: setSelectedTransport("specificTransport")
UI->>UL: useLogs("specificTransport")
UL-->>UI: filtered logs for specificTransport
UI->>URL: useRunLogs(runIdOrNull, "specificTransport")
URL-->>UI: filtered runLogs for specificTransport
UI-->>User: Render logs filtered by transport
deactivate UI
User->>UI: Change level select to info
activate UI
UI->>UI: setLevelFilter("info")
UI->>UI: filter logsArray in memory
UI-->>User: Render logs where level == info
deactivate UI
Class diagram for updated dashboard and logging componentsclassDiagram
class LogsPage {
- string selectedTransport
- string runIdFilter
- string searchQuery
- string levelFilter
- any transports
- any logs
- any runLogs
+ render()
}
class LogEntry {
- any log
- map~string,any~ levelConfig
- string level
+ render()
}
class ObservabilityPage {
- number page
- number perPage
- string nameFilter
- string spanTypeFilter
- string entityTypeFilter
- any traces
- string selectedTraceId
+ render()
}
class TraceDetails {
- string traceId
- any traceData
- any scoreResult
+ render()
}
class DashboardPage {
- map~string,string~ colorVariants
+ render()
}
class QuickLinkCard {
- string title
- string description
- string icon
- string href
- string color
+ render()
}
class StatCard {
- string title
- string value
- any icon
- any trend
+ render()
}
class AgentEvalsTab {
- string agentId
- any evaluations
+ render()
}
class AgentTools {
- any tools
+ render()
}
class ToolHeader {
- string title
- string type
- string state
+ render()
}
%% Relationships
LogsPage --> LogEntry : uses
ObservabilityPage --> TraceDetails : renders
DashboardPage --> QuickLinkCard : renders
DashboardPage --> StatCard : renders
AgentEvalsTab --> StatCard : may render trends
AgentTools --> ToolHeader : renders
%% Notable type refinements
ToolHeader : type toolType
AgentTools : toolType cast to tool-prefix string
StatCard : trend.positive controls accent vs destructive color
LogsPage : selectedTransport uses all as sentinel
LogsPage : levelFilter uses all as sentinel
ObservabilityPage : spanTypeFilter uses all as sentinel
ObservabilityPage : entityTypeFilter uses all as sentinel
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
🤖 Hi @ssdeanx, I've received your request, and I'm working on it now! You can track my progress in the logs for more details. |
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings. WalkthroughMultiple dashboard components updated with design token styling changes, filter value defaults shifted from empty strings to "all", null-safety improvements using nullish coalescing operators throughout logs and observability pages, and CORS configuration expanded with additional headers. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary of ChangesHello @ssdeanx, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request focuses on a comprehensive refactoring effort to enhance code quality, improve user experience, and streamline development. Key changes include updating component styles to leverage a new design token system, refining state management for filtering functionalities in log and observability pages, and strengthening type safety in critical components. Additionally, the PR includes minor adjustments to the Mastra configuration for better API interaction. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
|
🤖 I'm sorry @ssdeanx, but I was unable to process your request. Please see the logs for more details. |
There was a problem hiding this comment.
Hey there - I've reviewed your changes - here's some feedback:
- Several of the new conditional expressions wrap values with
Boolean(...)or extra parentheses (e.g.(Boolean(span.duration)),(selectedTraceId)), which makes the JSX harder to read without changing behavior; consider reverting these to simple truthy checks. - The Mastra
middlewarearray now only contains a large commented-out function, which is harder to maintain and visually noisy; consider either removing this block entirely or moving it behind a feature flag/config toggle instead of keeping it inline and commented. - In
ObservabilityPage,entityTypeFilteris cast to"agent" | "workflow" | undefinedwhile the select options still include"tool", which creates a mismatch between the UI and the TS type; consider updating the type union or options so they are consistent and avoid theascast.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Several of the new conditional expressions wrap values with `Boolean(...)` or extra parentheses (e.g. `(Boolean(span.duration))`, `(selectedTraceId)`), which makes the JSX harder to read without changing behavior; consider reverting these to simple truthy checks.
- The Mastra `middleware` array now only contains a large commented-out function, which is harder to maintain and visually noisy; consider either removing this block entirely or moving it behind a feature flag/config toggle instead of keeping it inline and commented.
- In `ObservabilityPage`, `entityTypeFilter` is cast to `"agent" | "workflow" | undefined` while the select options still include `"tool"`, which creates a mismatch between the UI and the TS type; consider updating the type union or options so they are consistent and avoid the `as` cast.
## Individual Comments
### Comment 1
<location> `app/dashboard/observability/page.tsx:54-56` </location>
<code_context>
- spanType: spanTypeFilter || undefined,
- entityType: (entityTypeFilter || undefined) as "agent" | "workflow" | undefined,
+ spanType: spanTypeFilter === "all" ? undefined : spanTypeFilter,
+ entityType: (entityTypeFilter === "all" ? undefined : entityTypeFilter) as
+ | "agent"
+ | "workflow"
+ | undefined,
},
</code_context>
<issue_to_address>
**issue:** The `entityType` type cast excludes the `"tool"` option that the UI exposes.
The `Select` for entity type allows a `"tool"` value, but the `entityType` assertion only permits `"agent" | "workflow" | undefined`. This misaligns the UI and types. Please either include `"tool"` in the union or narrow `entityTypeFilter` so it can’t be `"tool"` (or any other value) when passed here.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| entityType: (entityTypeFilter === "all" ? undefined : entityTypeFilter) as | ||
| | "agent" | ||
| | "workflow" |
There was a problem hiding this comment.
issue: The entityType type cast excludes the "tool" option that the UI exposes.
The Select for entity type allows a "tool" value, but the entityType assertion only permits "agent" | "workflow" | undefined. This misaligns the UI and types. Please either include "tool" in the union or narrow entityTypeFilter so it can’t be "tool" (or any other value) when passed here.
There was a problem hiding this comment.
Code Review
This pull request introduces a series of refactorings across the dashboard components to align with new design tokens, improve type safety, and standardize filter state management. The changes are generally positive, enhancing consistency and maintainability. For instance, hardcoded colors have been replaced with theme-aware design tokens, and the use of the nullish coalescing operator (??) improves robustness. However, in app/dashboard/observability/page.tsx, several changes introduce redundant Boolean() wrappers and unnecessary parentheses in JSX expressions. While functionally correct, these changes reduce code readability, and I've provided suggestions to simplify them.
| {span.spanType ?? "unknown"} | ||
| </Badge> | ||
| {span.duration && ( | ||
| {(Boolean(span.duration)) && ( |
There was a problem hiding this comment.
| </div> | ||
| <div className="text-xs text-muted-foreground mt-1"> | ||
| {span.startTime ? new Date(span.startTime).toLocaleString() : "No timestamp"} | ||
| {(span.startTime) ? new Date(span.startTime).toLocaleString() : "No timestamp"} |
There was a problem hiding this comment.
| </button> | ||
| ))} | ||
| {(!traces || !(traces as any)?.spans?.length) && ( | ||
| {(!traces || !((traces as any)?.spans?.length)) && ( |
| {/* Trace Details */} | ||
| <div className="flex-1 overflow-auto"> | ||
| {selectedTraceId ? ( | ||
| {(selectedTraceId) ? ( |
| /> | ||
| </div> | ||
| {scoreResult && ( | ||
| {(Boolean(scoreResult)) && ( |
| <CardContent> | ||
| <div className="text-2xl font-bold"> | ||
| {traceData?.duration ? `${traceData.duration}ms` : "N/A"} | ||
| {(traceData?.duration) ? `${traceData.duration}ms` : "N/A"} |
| </div> | ||
| <div className="flex items-center gap-2"> | ||
| {span.duration && ( | ||
| {(Boolean(span.duration)) && ( |
| </div> | ||
| </div> | ||
| {span.attributes && Object.keys(span.attributes).length > 0 && ( | ||
| {(Boolean(span.attributes)) && Object.keys(span.attributes).length > 0 && ( |
There was a problem hiding this comment.
The Boolean() wrapper for span.attributes is unnecessary. The expression span.attributes && Object.keys(span.attributes).length > 0 works identically and is more idiomatic.
| {(Boolean(span.attributes)) && Object.keys(span.attributes).length > 0 && ( | |
| {span.attributes && Object.keys(span.attributes).length > 0 && ( |
| </CardHeader> | ||
| <CardContent> | ||
| {traceData?.attributes ? ( | ||
| {(traceData?.attributes) ? ( |
Greptile OverviewGreptile SummaryThis PR implements a comprehensive refactoring of component styles and state management across the dashboard and chat interfaces. Key Changes:
Impact: Confidence Score: 5/5
Important Files ChangedFile Analysis
Sequence DiagramsequenceDiagram
participant Dev as Developer
participant UI as UI Components
participant Filter as Filter State
participant Design as Design System
participant API as Mastra API
Dev->>UI: Update component styles
Note over UI,Design: Style Refactor
UI->>Design: Replace hardcoded colors
Design-->>UI: Apply design tokens
Note right of Design: text-accent<br/>text-destructive<br/>text-primary<br/>bg-primary/10
Note over Filter,UI: State Management
Dev->>Filter: Change default states
Filter->>Filter: "" → "all"
Filter->>UI: Initialize with "all"
UI->>UI: Compare: "all" vs value
UI->>API: Pass undefined when "all"
API-->>UI: Return filtered data
Note over UI: Null Handling
UI->>UI: Replace || with ??
UI->>UI: Use explicit Boolean()
Note over API: API Configuration
Dev->>API: Update CORS headers
API->>API: Add x-mastra-client-type
API->>API: Add exposeHeaders
Dev->>API: Comment out middleware
Note over UI,Design: Result
UI-->>Dev: Consistent design tokens
Filter-->>Dev: Improved filtering logic
API-->>Dev: Enhanced CORS support
|
There was a problem hiding this comment.
Actionable comments posted: 2
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (7)
app/chat/components/agent-tools.tsx(1 hunks)app/dashboard/_components/stat-card.tsx(1 hunks)app/dashboard/agents/_components/agent-evals-tab.tsx(1 hunks)app/dashboard/logs/page.tsx(8 hunks)app/dashboard/observability/page.tsx(12 hunks)app/dashboard/page.tsx(3 hunks)src/mastra/index.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (14)
**/app/**
📄 CodeRabbit inference engine (.github/instructions/next-js.instructions.md)
Use the
app/directory structure for route handlers, server components, and client components (Next.js 13+). Prefer this over thepages/directory for new projects.
Files:
app/chat/components/agent-tools.tsxapp/dashboard/agents/_components/agent-evals-tab.tsxapp/dashboard/observability/page.tsxapp/dashboard/_components/stat-card.tsxapp/dashboard/page.tsxapp/dashboard/logs/page.tsx
**/components/**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (.github/instructions/next-js.instructions.md)
Use PascalCase for component file names (e.g.,
ComponentName.jsxorComponentName.tsx).
Files:
app/chat/components/agent-tools.tsx
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (.github/instructions/next-js.instructions.md)
**/*.{js,jsx,ts,tsx}: Usenext/dynamicfor dynamic imports to load components only when needed, improving initial load time.
Usenext/imagecomponent for automatic image optimization, including lazy loading and responsive images.
Use React.memo to prevent unnecessary re-renders of components.
Use the<Link prefetch>tag to prefetch pages that are likely to be visited.
Use getServerSideProps, getStaticProps, or server components for fetching data on the server-side.
Use SWR or React Query for client-side data fetching and caching.
Use CSS Modules, Styled Components, or Tailwind CSS for component-level styling. Prefer Tailwind CSS for rapid development.
Use React Context, Zustand, Jotai, or Recoil for managing global state. Avoid Redux unless necessary.
Usereact-hook-formfor managing forms and validation.
Only fetch the data that is needed by the component to avoid over-fetching.
Avoid long-running synchronous operations in the main thread to prevent blocking.
Always usesetStateor hooks to update state instead of mutating state directly.
Include a complete dependency array inuseEffecthooks to prevent unexpected behavior.
Avoid writing server-side code in client components to prevent exposing secrets or causing unexpected behavior.
Usetry...catchblocks for handling errors in asynchronous operations.
Implement error boundary components usinggetDerivedStateFromErrororcomponentDidCatchlifecycle methods.
Sanitize user input to prevent Cross-Site Scripting (XSS) attacks. Be especially careful when rendering HTML directly from user input.
Store authentication tokens in HTTP-only cookies or local storage securely.
Implement role-based access control to restrict access to sensitive resources.
Clean up event listeners and timers inuseEffecthooks to avoid memory leaks.
Only update state when necessary to reduce the number of re-renders and improve performance.
Use immutable data structures and avoid mutating data directly to prevent unexpected...
Files:
app/chat/components/agent-tools.tsxapp/dashboard/agents/_components/agent-evals-tab.tsxapp/dashboard/observability/page.tsxsrc/mastra/index.tsapp/dashboard/_components/stat-card.tsxapp/dashboard/page.tsxapp/dashboard/logs/page.tsx
app/**/*.{tsx,ts}
📄 CodeRabbit inference engine (app/AGENTS.md)
app/**/*.{tsx,ts}: Use Tailwind CSS 4 with oklch color variables for styling in Next.js App Router pages and layouts
Use React 19 latest features in component implementations within the app directory
Files:
app/chat/components/agent-tools.tsxapp/dashboard/agents/_components/agent-evals-tab.tsxapp/dashboard/observability/page.tsxapp/dashboard/_components/stat-card.tsxapp/dashboard/page.tsxapp/dashboard/logs/page.tsx
app/chat/components/**/*.{ts,tsx}
📄 CodeRabbit inference engine (app/chat/AGENTS.md)
app/chat/components/**/*.{ts,tsx}: Use AI SDK v5 types and patterns in chat components: import types like UIMessage, DynamicToolUIPart, TextUIPart, ReasoningUIPart from 'ai' and use type guard functions like isTextUIPart, isReasoningUIPart, isToolOrDynamicToolUIPart to filter message parts
Access message content through message.parts array using type guards rather than message.content, extracting specific parts like text using const textPart = message.parts?.find(isTextUIPart)
Handle Mastra stream chunk types correctly: use 'text-delta' for streaming text, 'reasoning-delta' for streaming reasoning (NOT 'reasoning'), 'tool-call' for tool invocation, 'tool-result' for tool completion, 'source' for research sources, and 'finish' for completion with usage data
Use AI Elements components (Conversation, Message, PromptInput, ModelSelector, Reasoning, Tool, Sources, Artifact) from the AI Elements library in their respective chat component files as specified in the architecture
Files:
app/chat/components/agent-tools.tsx
app/chat/components/agent-tools.tsx
📄 CodeRabbit inference engine (app/chat/AGENTS.md)
Display tool invocations with Tool AI Elements component showing input-available, output-available, and output-error states when the tools feature flag is enabled for the agent
Files:
app/chat/components/agent-tools.tsx
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Never commit API keys or secrets to the repository; use maskSensitiveMessageData() helper from src/mastra/config/pg-storage.ts when logging
Files:
app/chat/components/agent-tools.tsxapp/dashboard/agents/_components/agent-evals-tab.tsxapp/dashboard/observability/page.tsxsrc/mastra/index.tsapp/dashboard/_components/stat-card.tsxapp/dashboard/page.tsxapp/dashboard/logs/page.tsx
app/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use Next.js 16 App Router with React 19 for frontend development in the app/ directory
Files:
app/chat/components/agent-tools.tsxapp/dashboard/agents/_components/agent-evals-tab.tsxapp/dashboard/observability/page.tsxapp/dashboard/_components/stat-card.tsxapp/dashboard/page.tsxapp/dashboard/logs/page.tsx
{app,ui,src/components}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use Tailwind CSS 4 with oklch color variables for styling in UI components
Files:
app/chat/components/agent-tools.tsxapp/dashboard/agents/_components/agent-evals-tab.tsxapp/dashboard/observability/page.tsxapp/dashboard/_components/stat-card.tsxapp/dashboard/page.tsxapp/dashboard/logs/page.tsx
{app,src/components}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
{app,src/components}/**/*.{ts,tsx}: Use shadcn/ui base components (34 components) located in ui/ directory for common UI elements
Use AI Elements library (30 components) from src/components/ai-elements/ for chat, reasoning, and canvas UIs
Files:
app/chat/components/agent-tools.tsxapp/dashboard/agents/_components/agent-evals-tab.tsxapp/dashboard/observability/page.tsxapp/dashboard/_components/stat-card.tsxapp/dashboard/page.tsxapp/dashboard/logs/page.tsx
app/dashboard/**/*.{ts,tsx}
📄 CodeRabbit inference engine (app/dashboard/AGENTS.md)
app/dashboard/**/*.{ts,tsx}: Use custom React hooks fromlib/hooks/use-mastra.tsto wrap MastraClient for data fetching (e.g.,useAgents(),useAgent(id),useWorkflows(),useTools(), etc.) in dashboard pages
Use action hooks for dashboard mutations (e.g.,useExecuteTool(),useCreateMemoryThread(),useUpdateWorkingMemory(),useVectorQuery(),useScoreTraces()) instead of direct MastraClient calls
Files:
app/dashboard/agents/_components/agent-evals-tab.tsxapp/dashboard/observability/page.tsxapp/dashboard/_components/stat-card.tsxapp/dashboard/page.tsxapp/dashboard/logs/page.tsx
**/app/**/page.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (.github/instructions/next-js.instructions.md)
Represent route UIs using
page.tsxorpage.jsxfiles within theapp/directory structure.
Files:
app/dashboard/observability/page.tsxapp/dashboard/page.tsxapp/dashboard/logs/page.tsx
**/*.{js,ts}
📄 CodeRabbit inference engine (.github/instructions/next-js.instructions.md)
Use parameterized queries or an ORM to prevent SQL injection attacks.
Files:
src/mastra/index.ts
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Run eslint with --max-warnings=0 on src/**/*.{ts,tsx} to enforce linting standards
Files:
src/mastra/index.ts
🧬 Code graph analysis (2)
app/dashboard/observability/page.tsx (3)
lib/hooks/use-mastra.ts (1)
useAITraces(193-217)ui/select.tsx (1)
SelectItem(180-180)ui/badge.tsx (1)
Badge(46-46)
app/dashboard/logs/page.tsx (4)
lib/hooks/use-mastra.ts (2)
useLogs(230-237)useRunLogs(239-247)src/mastra/config/logger.ts (1)
log(14-18)ui/select.tsx (1)
SelectItem(180-180)lib/types/mastra-api.ts (1)
LogEntry(145-145)
⏰ 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: Agent
- GitHub Check: Sourcery review
- GitHub Check: Codacy Security Scan
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (10)
app/dashboard/agents/_components/agent-evals-tab.tsx (1)
55-57: LGTM! Design token migration approved.The color updates from explicit color classes to semantic design tokens (text-accent/text-destructive) align with the broader theming updates across the dashboard.
app/chat/components/agent-tools.tsx (1)
37-37: LGTM! Type safety improvement approved.The explicit type assertion ensures the toolType matches the expected template literal type
tool-${string}, improving type safety without changing runtime behavior.app/dashboard/_components/stat-card.tsx (1)
59-59: LGTM! Design token migration approved.The color updates to semantic tokens (text-accent/text-destructive) maintain the positive/negative logic while aligning with the new design system.
src/mastra/index.ts (1)
648-670: Clarify intent of commented middleware.The request body extraction middleware has been entirely commented out rather than removed. This preserves the code but disables the functionality. Is this intentional (temporary disable for debugging/testing) or should this code be removed permanently?
If the middleware is no longer needed, consider removing it entirely to reduce code clutter. If it's temporarily disabled, add a comment explaining why and under what conditions it should be re-enabled.
app/dashboard/page.tsx (1)
193-194: LGTM! Design token migration with dark mode support approved.The updates consistently apply token-based theming (primary/accent/secondary/muted) with corresponding dark mode variants across icon containers and QuickLinkCard color variants. The removal of explicit text colors from inner icons allows container-level theming to take effect.
Also applies to: 261-262, 377-380
app/dashboard/logs/page.tsx (3)
35-40: LGTM! Filter defaults improved with explicit "all" value.The changes standardize filter handling by:
- Using "all" as an explicit value instead of empty strings for default states
- Passing
undefinedto data hooks when "all" is selected to fetch unfiltered data- Updating the matching logic to treat "all" as a wildcard
This makes the filter state more explicit and easier to reason about.
Also applies to: 44-44, 53-53, 83-83, 100-100
148-148: LGTM! Null safety improved with nullish coalescing.The changes from logical OR (
||) to nullish coalescing (??) operators provide more precise null/undefined handling:
- Key generation now correctly handles falsy IDs like
0- Log level extraction safely defaults to "info" only for null/undefined
- Message display preserves empty strings while falling back for null/undefined
Also applies to: 193-193, 224-224, 252-252
219-220: LGTM! Dark mode variants added for consistency.The log level configurations now include dark mode color variants (dark:text-secondary-foreground, dark:bg-secondary/30, etc.) aligning with the design token migration across the dashboard.
app/dashboard/observability/page.tsx (2)
45-46: LGTM! Filter defaults standardized with "all" value.The changes mirror the logs page improvements:
- Explicit "all" value for default filter states
- Conditional logic to pass
undefinedwhen "all" is selected- Clearer filter semantics in the UI
This provides consistency across dashboard pages.
Also applies to: 53-57, 92-92, 104-104
138-152: LGTM! Enhanced null safety throughout trace rendering.The widespread adoption of nullish coalescing (
??) and explicit boolean checks provides:
- Safer fallbacks for display values (e.g., "unknown", "N/A", "No timestamp")
- More precise null/undefined handling vs. logical OR
- Better type narrowing for TypeScript
The consistent application across trace list, trace details, and span rendering improves code robustness.
Also applies to: 256-256, 318-318, 344-344, 359-359, 387-393, 405-405
| {span.spanType ?? "unknown"} | ||
| </Badge> | ||
| {span.duration && ( | ||
| {(Boolean(span.duration)) && ( |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Optional: Consider simplifying Boolean() wrappers.
While the explicit Boolean(...) wrappers work correctly and make intent clear, they're somewhat verbose for simple truthiness checks in conditional contexts where JavaScript's implicit coercion is sufficient:
-{(Boolean(span.duration)) && (
+{span.duration && (However, the current approach does provide clarity and may help with TypeScript type narrowing, so this is purely a style consideration.
Also applies to: 285-285, 399-399, 409-409
🤖 Prompt for AI Agents
In app/dashboard/observability/page.tsx around lines 143, 285, 399, and 409, the
conditionals wrap expressions in Boolean(...), which is verbose; replace each
Boolean(expr) with a direct truthiness check (e.g., if (expr) or {expr &&
(...)}) or, if you want an explicit boolean cast for clarity, use the shorter
!!expr; update those four locations accordingly while preserving current
behavior and any necessary TypeScript narrowing.
| allowHeaders: ["Content-Type", "Authorization", 'x-mastra-client-type'], | ||
| exposeHeaders: ["Content-Length", "X-Requested-With"], |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Search for usage of x-mastra-client-type header
rg -n "x-mastra-client-type" --type=ts --type=tsx -C 3Repository: ssdeanx/AgentStack
Length of output: 89
🏁 Script executed:
#!/bin/bash
# Also search for Content-Length and X-Requested-With usage
rg -n "Content-Length|X-Requested-With" --type=ts --type=tsx -C 2Repository: ssdeanx/AgentStack
Length of output: 89
🏁 Script executed:
#!/bin/bash
# Get broader context on CORS configuration and header usage
rg -n "allowHeaders|exposeHeaders" --type=ts --type=tsx -C 3Repository: ssdeanx/AgentStack
Length of output: 89
🏁 Script executed:
#!/bin/bash
# Search for x-mastra-client-type without type restrictions
rg -n "x-mastra-client-type"Repository: ssdeanx/AgentStack
Length of output: 164
🏁 Script executed:
#!/bin/bash
# Search for CORS header usage patterns
rg -n "x-mastra-client-type|Content-Length|X-Requested-With" -A 2 -B 2Repository: ssdeanx/AgentStack
Length of output: 505
🏁 Script executed:
#!/bin/bash
# Check the actual CORS configuration in index.ts
cat -n src/mastra/index.ts | sed -n '630,660p'Repository: ssdeanx/AgentStack
Length of output: 1464
🏁 Script executed:
#!/bin/bash
# Search for fetch calls and custom header configurations
rg -n "headers\s*[:{]|fetch\(|axios|request" -A 3 -B 1 | head -100Repository: ssdeanx/AgentStack
Length of output: 8255
🏁 Script executed:
#!/bin/bash
# Look for client-side API utilities
find . -type f \( -name "*api*" -o -name "*client*" -o -name "*fetch*" \) \( -name "*.ts" -o -name "*.js" \) | grep -v node_modules | head -20Repository: ssdeanx/AgentStack
Length of output: 648
🏁 Script executed:
#!/bin/bash
# Search specifically for any client component setting headers
rg -n "setRequestHeader|headers.*=" -B 2 -A 2Repository: ssdeanx/AgentStack
Length of output: 8255
🏁 Script executed:
#!/bin/bash
# Check the mastra client implementation
cat lib/mastra-client.ts | head -150Repository: ssdeanx/AgentStack
Length of output: 631
🏁 Script executed:
#!/bin/bash
# Search for header configuration in mastra-client
rg -n "headers|fetch|request" lib/mastra-client.ts -A 2 -B 1 | head -80Repository: ssdeanx/AgentStack
Length of output: 148
Review CORS header configuration - unused headers exposed.
The CORS configuration exposes headers that are not actively used by the frontend client:
x-mastra-client-typeis inallowHeadersbut never set bymastraClient(headers: {} at lib/mastra-client.ts:16)Content-LengthandX-Requested-Withare standard HTTP headers managed automatically by browsers/servers and should not require explicit CORS exposure unless actively needed- Consider removing unused header declarations to maintain a minimal CORS policy surface, or implement actual usage of
x-mastra-client-typeif it's required for client identification
🤖 Prompt for AI Agents
In src/mastra/index.ts around lines 643-644, the CORS config unnecessarily
includes headers not used by the client; remove 'x-mastra-client-type' from
allowHeaders and remove 'Content-Length' and 'X-Requested-With' from
exposeHeaders to tighten the CORS surface unless you intentionally use them — if
the client actually needs to send an identifying header, add that header to the
mastra client (lib/mastra-client.ts) and then keep it in allowHeaders, otherwise
delete these entries and keep the CORS policy minimal.
There was a problem hiding this comment.
Pull request overview
This PR implements a multi-faceted refactoring focused on improving type safety, migrating to design tokens for better theming support, and standardizing filter state management. The changes span configuration updates in Mastra, component styling improvements with dark mode support, and filter initialization patterns across dashboard pages.
Key Changes:
- Migration from direct color classes to design tokens with dark mode variants for improved theming consistency
- Standardization of filter state initialization to use "all" as default value with explicit undefined conversion
- Addition of new CORS headers in Mastra configuration and commented out middleware for future reference
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 15 comments.
Show a summary per file
| File | Description |
|---|---|
src/mastra/index.ts |
Added CORS headers (x-mastra-client-type, exposeHeaders) and commented out middleware for request body parsing |
app/dashboard/page.tsx |
Migrated color classes to design tokens with dark mode support for Workflows and Recent Traces card icons |
app/dashboard/observability/page.tsx |
Changed filter defaults to "all", replaced || with ??, added parentheses to conditionals, and wrapped values with Boolean() |
app/dashboard/logs/page.tsx |
Updated filter initialization to "all", replaced || with ?? for null coalescing, and migrated log level colors to design tokens |
app/dashboard/agents/_components/agent-evals-tab.tsx |
Replaced text-green-500 with text-accent and text-red-500 with text-destructive for evaluation pass/fail indicators |
app/dashboard/_components/stat-card.tsx |
Changed trend colors from text-green-500/text-red-500 to text-accent/text-destructive |
app/chat/components/agent-tools.tsx |
Added type assertion as \tool-${string}`` for better TypeScript type safety |
| /> | ||
| </div> | ||
| {scoreResult && ( | ||
| {(Boolean(scoreResult)) && ( |
There was a problem hiding this comment.
Wrapping scoreResult with Boolean() is unnecessary. Using {scoreResult && (...)} is the idiomatic React pattern for conditional rendering and is more concise.
| {(Boolean(scoreResult)) && ( | |
| {scoreResult && ( |
| warn: { icon: AlertTriangle, color: "text-secondary dark:text-secondary-foreground", bg: "bg-secondary/10 dark:bg-secondary/30" }, | ||
| info: { icon: Info, color: "text-primary dark:text-primary-foreground", bg: "bg-primary/10 dark:bg-primary/30" }, |
There was a problem hiding this comment.
Inconsistent color token migration. While info and warn levels now use design tokens (text-primary, text-secondary), the error level still uses text-destructive (already a token) but the debug level uses text-muted-foreground without dark mode variants. For consistency with the info/warn pattern, consider adding dark mode support to all levels: text-muted-foreground dark:text-muted-foreground or similar.
| className={cn( | ||
| "text-xs mt-1", | ||
| trend.positive ? "text-green-500" : "text-red-500" | ||
| trend.positive ? "text-accent" : "text-destructive" |
There was a problem hiding this comment.
Inconsistent color token usage across the codebase. This change maps positive/negative trends to text-accent/text-destructive, but other parts of the codebase still use text-green-500/text-red-500 for similar success/error semantics (e.g., app/chat/components/agent-task.tsx, app/workflows/components/workflow-node.tsx). Consider applying this design token approach consistently across all components.
| // if (c.req.method === "POST") { | ||
| // try { | ||
| // const clonedReq = c.req.raw.clone(); | ||
| /// const body = await clonedReq.json(); |
There was a problem hiding this comment.
Comment has three forward slashes /// instead of the standard two //. This appears to be a typo.
| /// const body = await clonedReq.json(); | |
| // const body = await clonedReq.json(); |
| {span.spanType ?? "unknown"} | ||
| </Badge> | ||
| {span.duration && ( | ||
| {(Boolean(span.duration)) && ( |
There was a problem hiding this comment.
Wrapping span.duration with Boolean() is unnecessary for conditional rendering. In JSX, {span.duration && (...)} already performs truthiness checking correctly and is more idiomatic. The number 0 would not render anyway, and Boolean() adds no additional benefit here.
| {(Boolean(span.duration)) && ( | |
| {span.duration && ( |
| <CardContent> | ||
| <div className="text-2xl font-bold"> | ||
| {traceData?.duration ? `${traceData.duration}ms` : "N/A"} | ||
| {(traceData?.duration) ? `${traceData.duration}ms` : "N/A"} |
There was a problem hiding this comment.
Unnecessary parentheses around the ternary condition. traceData?.duration ? ... : ... is more readable than (traceData?.duration) ? ... : ....
| {(traceData?.duration) ? `${traceData.duration}ms` : "N/A"} | |
| {traceData?.duration ? `${traceData.duration}ms` : "N/A"} |
| </CardHeader> | ||
| <CardContent> | ||
| {traceData?.attributes ? ( | ||
| {(traceData?.attributes) ? ( |
There was a problem hiding this comment.
Unnecessary parentheses around the ternary condition. traceData?.attributes ? ... : ... is clearer than (traceData?.attributes) ? ... : ....
| {(traceData?.attributes) ? ( | |
| {traceData?.attributes ? ( |
| </button> | ||
| ))} | ||
| {(!traces || !(traces as any)?.spans?.length) && ( | ||
| {(!traces || !((traces as any)?.spans?.length)) && ( |
There was a problem hiding this comment.
The double negation with extra parentheses !((traces as any)?.spans?.length) is unnecessarily complex. !(traces as any)?.spans?.length or !traces?.spans?.length is clearer and achieves the same result.
| {(!traces || !((traces as any)?.spans?.length)) && ( | |
| {(!traces || !(traces as any)?.spans?.length) && ( |
| </div> | ||
| <div className="text-xs text-muted-foreground mt-1"> | ||
| {span.startTime ? new Date(span.startTime).toLocaleString() : "No timestamp"} | ||
| {(span.startTime) ? new Date(span.startTime).toLocaleString() : "No timestamp"} |
There was a problem hiding this comment.
Unnecessary parentheses around the ternary condition. span.startTime ? ... : ... is clearer and more idiomatic than (span.startTime) ? ... : ....
| {(span.startTime) ? new Date(span.startTime).toLocaleString() : "No timestamp"} | |
| {span.startTime ? new Date(span.startTime).toLocaleString() : "No timestamp"} |
| <div className="flex items-center gap-3"> | ||
| {evaluation.passed ? ( | ||
| <CheckCircle2 className="h-4 w-4 text-green-500" /> | ||
| <CheckCircle2 className="h-4 w-4 text-accent" /> |
There was a problem hiding this comment.
Inconsistent color token usage across the codebase. While this component uses text-accent for success states, many other similar components throughout the codebase still use text-green-500 (e.g., in app/chat/components/agent-task.tsx, app/networks/components/network-agents.tsx, app/workflows/components/workflow-node.tsx). For consistency, either update all success indicators to use text-accent, or keep text-green-500 for semantic color meanings.
| <CheckCircle2 className="h-4 w-4 text-accent" /> | |
| <CheckCircle2 className="h-4 w-4 text-green-500" /> |
Summary by Sourcery
Align dashboard UI and filtering behavior with new design tokens and consistent "all" filter semantics across observability and logs pages.
Enhancements: