Repository navigation
Conversation
…e dependencies, and refresh README documentation.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Reviewer's GuideRefines the chat UI and sidebars with richer AI-oriented UX, removes the logs tab, wires Mastra agents more deeply into the UI, enables TanStack Query at the app root, updates Mastra workspaces/agents and server features, upgrades AI-related dependencies, and refreshes README stats and configuration. Class diagram for updated Agent type and related Mastra agentsclassDiagram
direction TB
class Agent {
+string id
+string name
+string description
+any instructions
+Record~string, any~ tools
+Record~string, any~ workflows
+Record~string, AgentRef~ agents
+any[] skills
+string[] workspaceTools
+string workspaceId
+string provider
+string modelId
+string modelVersion
+ModelConfig[] modelList
+ProcessorRef[] inputProcessors
+ProcessorRef[] outputProcessors
+any defaultOptions
+any defaultGenerateOptionsLegacy
+any defaultStreamOptionsLegacy
+string requestContextSchema
+AgentSource source
+AgentStatus status
+string activeVersionId
+boolean hasDraft
}
class AgentRef {
+string id
+string name
}
class ModelConfig {
+string id
+boolean enabled
+number maxRetries
+ModelRef model
}
class ModelRef {
+string modelId
+string provider
+string modelVersion
}
class ProcessorRef {
+string id
+string name
}
class AgentSource {
<<enumeration>>
code
stored
}
class AgentStatus {
<<enumeration>>
draft
published
archived
}
Agent --> AgentRef : uses
Agent --> ModelConfig : uses
ModelConfig --> ModelRef : uses
Agent --> ProcessorRef : uses
Agent --> AgentSource : source
Agent --> AgentStatus : status
class ResearchAgent {
<<MastraAgentInstance>>
+string id
+string name
+string description
+mainWorkspace workspace
+any tools
}
class WeatherAgent {
<<MastraAgentInstance>>
+string id
+string name
+string description
+mainWorkspace workspace
+any tools
}
class A2ACoordinatorAgent {
<<MastraAgentInstance>>
+string id
+string name
+string description
}
class Workspace {
+string id
+string name
}
class DaytonaSandbox {
+string id
+string name
+string image
+number cpu
+number memory
+number disk
+string language
+number timeout
+string apiKey
+string apiUrl
}
Agent <|-- ResearchAgent : conforms_to
Agent <|-- WeatherAgent : conforms_to
Agent <|-- A2ACoordinatorAgent : conforms_to
Workspace <.. DaytonaSandbox : may_use
ResearchAgent --> Workspace : workspace
WeatherAgent --> Workspace : workspace
Class diagram for QueryProvider and React Query integrationclassDiagram
direction TB
class QueryProvider {
+QueryProvider(children ReactNode)
-QueryClient queryClient
}
class QueryClient {
+QueryClient(options QueryClientOptions)
}
class QueryClientOptions {
+DefaultOptions defaultOptions
}
class DefaultOptions {
+QueryDefaults queries
}
class QueryDefaults {
+number staleTime
}
QueryProvider --> QueryClient : creates
QueryClient --> QueryClientOptions : configured_by
QueryClientOptions --> DefaultOptions : has
DefaultOptions --> QueryDefaults : has
class RootLayout {
+RootLayout(params any)
}
RootLayout --> QueryProvider : wraps_app
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. |
There was a problem hiding this comment.
Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.
Summary of ChangesHello, 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 enhancing the user interface of the chat application, particularly the layout and sidebars, to improve navigation and user experience. It also solidifies the integration of AI Elements and Mastra agents by updating configurations, refining agent instructions, and expanding type definitions. Key dependencies have been upgraded, and a new data fetching library, React Query, has been introduced to streamline data management across the application. Highlights
Changelog
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. |
Summary by CodeRabbitRelease Notes
WalkthroughThis PR restructures chat layout with focus mode handling, introduces React Query provider for state management, updates agent workspace configuration, refactors AI Elements components, and upgrades dependencies. It removes a completed task tracking document and updates type definitions and UI component styling. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
There was a problem hiding this comment.
Hey - I've found 3 issues, and left some high level feedback:
- In
chat-sidebar.tsxyou now treatagentConfigas potentially undefined (e.g.,agentConfig?.name) but still indexCATEGORY_LABELS[agentConfig.category]without a null check; consider using optional chaining or an early return to avoid a runtime error whenagentConfigis missing. - In
research-tools.tsxtheScrollAreaheight class was changed fromh-[300px]toh-75, which isn’t a standard Tailwind utility and likely won’t apply; either restore the arbitrary value or use a valid Tailwind height token. - In
workspaces.tsthedaytonaSandboxinstance is created but commented out in theWorkspaceconfig, leaving it unused; either wire it intomainWorkspaceor remove the constant to avoid dead code and potential lint issues.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `chat-sidebar.tsx` you now treat `agentConfig` as potentially undefined (e.g., `agentConfig?.name`) but still index `CATEGORY_LABELS[agentConfig.category]` without a null check; consider using optional chaining or an early return to avoid a runtime error when `agentConfig` is missing.
- In `research-tools.tsx` the `ScrollArea` height class was changed from `h-[300px]` to `h-75`, which isn’t a standard Tailwind utility and likely won’t apply; either restore the arbitrary value or use a valid Tailwind height token.
- In `workspaces.ts` the `daytonaSandbox` instance is created but commented out in the `Workspace` config, leaving it unused; either wire it into `mainWorkspace` or remove the constant to avoid dead code and potential lint issues.
## Individual Comments
### Comment 1
<location path="ui/resizable.tsx" line_range="9-17" />
<code_context>
function ResizablePanelGroup({
className,
+ orientation = 'horizontal',
...props
}: React.ComponentProps<typeof ResizablePrimitive.Group>) {
return (
<ResizablePrimitive.Group
data-slot="resizable-panel-group"
+ orientation={orientation}
className={cn(
- 'flex h-full w-full data-[panel-group-direction=vertical]:flex-col',
</code_context>
<issue_to_address>
**issue (bug_risk):** `orientation`/`panel-group-orientation` likely don't line up with the underlying resizable library API.
This wrapper switched from `direction`/`data-[panel-group-direction=...]` to `orientation`/`data-[panel-group-orientation=...]`, but `react-resizable-panels` still expects `direction` and `data-panel-group-direction`. Unless the library API was upgraded to match, the `orientation` prop will be ignored and the new data selectors won’t apply, breaking vertical layout and handle styling. Please verify the library version and either keep using `direction`/`data-panel-group-direction` or update the library and confirm the new names are supported.
</issue_to_address>
### Comment 2
<location path="src/mastra/workspaces.ts" line_range="4-12" />
<code_context>
import { Workspace, LocalFilesystem, LocalSandbox } from '@mastra/core/workspace';
+import { DaytonaSandbox } from '@mastra/daytona'
+
+const daytonaSandbox = new DaytonaSandbox({
+ id: 'daytona-sandbox',
+ name: 'Daytona Sandbox',
+ image: 'node:20-slim',
+ resources: { cpu: 2, memory: 4, disk: 6 },
+ language: 'typescript',
+ timeout: 120_000,
+ apiKey: process.env.DAYTONA_API_KEY,
+ apiUrl: process.env.DAYTONA_API_URL,
+});
</code_context>
<issue_to_address>
**suggestion:** The `daytonaSandbox` instance is created but never used, which may cause linting or tree-shaking issues.
Since `mainWorkspace` still uses `LocalSandbox` and the `daytonaSandbox` wiring is commented out, we incur the cost of constructing `DaytonaSandbox` without any usage. Either connect `daytonaSandbox` to `mainWorkspace` (if it’s ready) or remove/comment out its declaration until you actually switch over.
</issue_to_address>
### Comment 3
<location path="README.md" line_range="91" />
<code_context>
+- **🤖 41 Agents**: Research → Learn → Report → Edit → Analyze (stock/crypto/copywriter/evaluator/data pipeline/business-legal/charting/image/coding/dane/social media/SEO/translation/customer support/project management)
</code_context>
<issue_to_address>
**issue (typo):** Possible typo in agent list: "dane" may be incorrect.
This role name stands out as inconsistent with the others; if it’s meant to be something like “data” or another specific role, please update it to avoid confusion.
Suggested implementation:
```
- **🤖 41 Agents**: Research → Learn → Report → Edit → Analyze (stock/crypto/copywriter/evaluator/data pipeline/business-legal/charting/image/coding/data/social media/SEO/translation/customer support/project management)
```
If your project uses a specific term (e.g. “data scientist”, “data QA”, or another role name) elsewhere in the docs or codebase, you may want to align this label with that existing terminology instead of the generic “data”.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| function ResizablePanelGroup({ | ||
| className, | ||
| orientation = 'horizontal', | ||
| ...props | ||
| }: React.ComponentProps<typeof ResizablePrimitive.Group>) { | ||
| return ( | ||
| <ResizablePrimitive.Group | ||
| data-slot="resizable-panel-group" | ||
| orientation={orientation} |
There was a problem hiding this comment.
issue (bug_risk): orientation/panel-group-orientation likely don't line up with the underlying resizable library API.
This wrapper switched from direction/data-[panel-group-direction=...] to orientation/data-[panel-group-orientation=...], but react-resizable-panels still expects direction and data-panel-group-direction. Unless the library API was upgraded to match, the orientation prop will be ignored and the new data selectors won’t apply, breaking vertical layout and handle styling. Please verify the library version and either keep using direction/data-panel-group-direction or update the library and confirm the new names are supported.
| const daytonaSandbox = new DaytonaSandbox({ | ||
| id: 'daytona-sandbox', | ||
| name: 'Daytona Sandbox', | ||
| image: 'node:20-slim', | ||
| resources: { cpu: 2, memory: 4, disk: 6 }, | ||
| language: 'typescript', | ||
| timeout: 120_000, | ||
| apiKey: process.env.DAYTONA_API_KEY, | ||
| apiUrl: process.env.DAYTONA_API_URL, |
There was a problem hiding this comment.
suggestion: The daytonaSandbox instance is created but never used, which may cause linting or tree-shaking issues.
Since mainWorkspace still uses LocalSandbox and the daytonaSandbox wiring is commented out, we incur the cost of constructing DaytonaSandbox without any usage. Either connect daytonaSandbox to mainWorkspace (if it’s ready) or remove/comment out its declaration until you actually switch over.
| - **💰 Financial Intelligence**: 30+ tools (Polygon quotes/aggs/fundamentals, Finnhub analysis, AlphaVantage indicators) | ||
| - **🔍 Semantic RAG**: PgVector (3072D embeddings) + MDocument chunking + rerank + graph traversal | ||
| - **🤖 48+ Agents**: Research → Learn → Report → Edit → Analyze (stock/crypto/copywriter/evaluator/data pipeline/business-legal/charting/image/coding/dane/social media/SEO/translation/customer support/project management) | ||
| - **🤖 41 Agents**: Research → Learn → Report → Edit → Analyze (stock/crypto/copywriter/evaluator/data pipeline/business-legal/charting/image/coding/dane/social media/SEO/translation/customer support/project management) |
There was a problem hiding this comment.
issue (typo): Possible typo in agent list: "dane" may be incorrect.
This role name stands out as inconsistent with the others; if it’s meant to be something like “data” or another specific role, please update it to avoid confusion.
Suggested implementation:
- **🤖 41 Agents**: Research → Learn → Report → Edit → Analyze (stock/crypto/copywriter/evaluator/data pipeline/business-legal/charting/image/coding/data/social media/SEO/translation/customer support/project management)
If your project uses a specific term (e.g. “data scientist”, “data QA”, or another role name) elsewhere in the docs or codebase, you may want to align this label with that existing terminology instead of the generic “data”.
There was a problem hiding this comment.
Code Review
This pull request primarily focuses on significant UI/UX enhancements and refactoring across the chat interface, alongside dependency updates and minor code adjustments. Key changes include a major overhaul of the chat layout to integrate the chat sidebar more dynamically, especially with a new focus mode, and a complete redesign of the chat sidebar itself, removing the 'Logs' tab and introducing a more modern, glossy appearance with scrollable content. The main sidebar was also refactored to include collapsible sections for agents, workflows, and tools, with tooltips providing detailed agent information on hover. Additionally, a new QueryProvider was introduced for TanStack Query integration, and the Agent type definition was expanded for more explicit properties. Dependency versions for @ai-sdk/*, ai, and axios were updated, and @mastra/daytona was added. Minor changes include updating an OpenAI model name in .env.example, adding a .gitignore entry, removing a detailed task list markdown file, and updating README statistics. A review comment suggests conditionally disabling Swagger UI, API request logging, and OpenAPI documentation in production environments for security reasons.
| swaggerUI: true, | ||
| apiReqLogs: true, | ||
| openAPIDocs: true, |
There was a problem hiding this comment.
Enabling Swagger UI, API request logging, and OpenAPI documentation in production can expose sensitive information about your API structure and potentially leak sensitive data in logs. It is recommended to disable these features in production or protect them behind authentication.
| swaggerUI: true, | |
| apiReqLogs: true, | |
| openAPIDocs: true, | |
| swaggerUI: process.env.NODE_ENV !== 'production', | |
| apiReqLogs: process.env.NODE_ENV !== 'production', | |
| openAPIDocs: process.env.NODE_ENV !== 'production', |
There was a problem hiding this comment.
Actionable comments posted: 20
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (6)
app/chat/components/chat-sidebar.tsx (1)
45-1008: 🧹 Nitpick | 🔵 TrivialConsider splitting component into smaller, focused components.
The ChatSidebar component is quite large (~1000 lines) and handles multiple concerns (threads, agents, tools, workflows, traces, vectors, memory, config). While it functions correctly, consider extracting each tab's content into separate components for better maintainability and testability.
For example, you could create:
ThreadsTab.tsxAgentsTab.tsxToolsTab.tsxWorkflowsTab.tsxTracesTab.tsxVectorsTab.tsxMemoryTab.tsxConfigTab.tsxEach would receive only the props it needs, making the code easier to test and maintain.
As per coding guidelines: "Keep functions small and focused, ideally under 20-30 lines" and "Apply Single Responsibility Principle: each function/class should do one thing well".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/chat/components/chat-sidebar.tsx` around lines 45 - 1008, ChatSidebar is too large and mixes many responsibilities; extract each TabsContent block into focused child components (e.g., ThreadsTab, AgentsTab, ToolsTab, WorkflowsTab, TracesTab, VectorsTab, MemoryTab, ConfigTab) that receive only the props they need (data arrays like agents/threads/vectors, loading flags, refresh callbacks such as onRefreshAgents/onRefreshThreads/onRefreshVectors, and handlers like restoreCheckpoint, handleSaveMemory, handleUpdateInstructions) while keeping shared hooks/useMastraQuery calls and state (selectedAgent, agentConfig, instructions, tempThreadId/tempResourceId, etc.) in ChatSidebar; replace the inline JSX for each tab (the TabsContent with value="...") with the new component imports and pass the referenced symbols (agentsQuery data -> agents, loadingAgents, traces (from tracesRes), memoryStatus, enhanceInstructions, setIsEditingInstructions, setInstructions, setThreadId/setResourceId) so behavior remains identical but the file is split for maintainability and testability.lib/a2a.ts (2)
12-153: 🛠️ Refactor suggestion | 🟠 MajorRefactor the main function to improve maintainability.
The
mainfunction is 141 lines long and violates the Single Responsibility Principle by performing multiple distinct operations: fetching agent cards, sending messages, checking task status, and demonstrating A2A communication. Additionally, it contains magic strings for agent IDs.Consider breaking this into smaller, focused functions:
getAgentCard(agentId)- for fetching agent capabilitiessendAgentMessage(a2aClient, query)- for sending messagescheckTaskStatus(a2aClient, taskId)- for status checksdemonstrateA2AWorkflow()- for the coordination exampleThis would improve testability, reusability, and maintainability. As per coding guidelines, functions should ideally be under 20-30 lines and follow the Single Responsibility Principle.
♻️ Example refactoring approach
// Constants for agent IDs const COORDINATOR_AGENT_ID = 'a2aCoordinatorAgent' const CONTENT_CREATOR_AGENT_ID = 'contentCreatorAgent' async function getAgentCard(a2aClient: ReturnType<typeof client.getA2A>) { console.log('📋 Fetching agent card...') const agentCard = await a2aClient.getCard() console.log(`\nAgent Name: ${agentCard.name}`) console.log(`Description: ${agentCard.description}`) console.log(`Capabilities: ${JSON.stringify(agentCard.capabilities)}`) console.log(`API Version: ${agentCard.version}`) console.log('\n-------------------\n') return agentCard } async function sendAgentMessage( a2aClient: ReturnType<typeof client.getA2A>, query: string ) { const messageId = `message-${Date.now()}` console.log(`📤 Sending message to agent (Message ID: ${messageId})...`) console.log(`Query: ${query}`) const response = await a2aClient.sendMessage({ message: { role: 'user', parts: [{ kind: 'text', text: query }], kind: 'message', messageId, }, }) if ('error' in response) { throw new Error(response.error.message) } return response } async function main() { try { const a2aClient = client.getA2A(COORDINATOR_AGENT_ID) await getAgentCard(a2aClient) await sendAgentMessage(a2aClient, 'What are the latest developments in AI agent networks?') // ... continue with other operations } catch (error) { console.error('❌ Error in A2A example:', error) } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/a2a.ts` around lines 12 - 153, The main function is doing too many jobs; refactor by extracting focused helper functions and constants: create COORDINATOR_AGENT_ID and CONTENT_CREATOR_AGENT_ID constants to replace magic strings, implement getAgentCard(a2aClient) to call a2aClient.getCard() and log/return the card, implement sendAgentMessage(a2aClient, query) to build the messageId, call a2aClient.sendMessage(), handle the 'error' and 'messageId' cases and return the response, implement checkTaskStatus(a2aClient, taskId) to call a2aClient.getTask() and handle errors/return status, and implement demonstrateA2AWorkflow() which uses client.getA2A(COORDINATOR_AGENT_ID)/client.getA2A(CONTENT_CREATOR_AGENT_ID) plus sendAgentMessage and checkTaskStatus to perform the research->content flow; then simplify main to get the A2A client via client.getA2A(COORDINATOR_AGENT_ID), call getAgentCard, call sendAgentMessage for the initial query, inspect returned task id via response.result.id and call checkTaskStatus as needed, and call demonstrateA2AWorkflow for the agent-to-agent example so each function (getAgentCard, sendAgentMessage, checkTaskStatus, demonstrateA2AWorkflow, main) stays small and single-responsibility.
52-63:⚠️ Potential issue | 🟠 MajorAddress unreachable code after early returns.
The comment on line 52 states "Mastra's current A2A implementation will always return a task, rather than a message." If this is accurate, the early returns at lines 53, 109, and 138 will always trigger, making all subsequent code unreachable. This pattern repeats three times:
- Lines 56-63 (after line 53 early return)
- Lines 112-117 (after line 109 early return)
- Lines 141-146 (after line 138 early return)
This dead code misleads readers about the example's functionality and violates code cleanliness principles.
Recommended actions:
- If the code is truly unreachable, remove it
- If it's intended for future API versions, wrap it with a feature flag or version check
- If the condition is incorrect, fix the logic to allow proper execution
🗑️ Option 1: Remove dead code if truly unreachable
} else if ('messageId' in response.result) { - // Mastra's current A2A implementation will always return a task, rather than a message - return + console.log('⚠️ Received messageId instead of task - this is unexpected in current Mastra A2A implementation') + return } - - console.log(`\nTask Status: ${response.result.status.state}`) - console.log('\n🤖 Agent Response:') - console.log( - response.result.status.message?.parts[0].kind === 'text' - ? response.result.status.message?.parts[0].text - : 'No response content' - ) - - console.log('\n-------------------\n')🔧 Option 2: Handle task-based responses properly
- if ('error' in response) { - throw new Error(response.error.message) - } else if ('messageId' in response.result) { - // Mastra's current A2A implementation will always return a task, rather than a message - return - } - - console.log(`\nTask Status: ${response.result.status.state}`) + if ('error' in response) { + throw new Error(response.error.message) + } + + // Handle task-based response (current Mastra behavior) + if ('messageId' in response.result) { + console.log('ℹ️ Mastra A2A currently returns tasks, not direct messages') + return + } + + // This code handles direct message responses (future API behavior) + console.log(`\nTask Status: ${response.result.status.state}`)Also applies to: 107-117, 136-146
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/a2a.ts` around lines 52 - 63, The early unconditional returns after the comment about Mastra's A2A returning a task make the subsequent console.log blocks (which read response.result.status, response.result.status.message and access parts[0].text) unreachable; fix by either removing the dead message-handling blocks or changing the early return into a proper conditional/feature-flag/version check (e.g., test response.result.status type or an isTaskResponse flag) so that when response.result.status indicates a message the code that logs response.result.status.message?.parts[0].text executes, and when it indicates a task the code handles the task path—apply the same change consistently for all three occurrences around the response/result logging and message handling.src/mastra/workspaces.ts (1)
4-22: 🧹 Nitpick | 🔵 TrivialRemove unused
daytonaSandboxconfiguration or enable it.The
daytonaSandboxinstance (lines 4-13) is created but never used since line 22 is commented out. This constitutes dead code that increases maintenance burden and could confuse future developers.Either remove the unused configuration or uncomment line 22 to enable the Daytona sandbox.
Option 1: Remove unused code
import { Workspace, LocalFilesystem, LocalSandbox } from '@mastra/core/workspace'; -import { DaytonaSandbox } from '@mastra/daytona' - -const daytonaSandbox = new DaytonaSandbox({ - id: 'daytona-sandbox', - name: 'Daytona Sandbox', - image: 'node:20-slim', - resources: { cpu: 2, memory: 4, disk: 6 }, - language: 'typescript', - timeout: 120_000, - apiKey: process.env.DAYTONA_API_KEY, - apiUrl: process.env.DAYTONA_API_URL, -}); export const mainWorkspace = new Workspace({ id: "main-Workspace", name: "MainWorkspace", filesystem: new LocalFilesystem({ id: 'filesystem', basePath: './workspace', }), - // sandbox: daytonaSandbox, sandbox: new LocalSandbox({Option 2: Enable Daytona sandbox
- // sandbox: daytonaSandbox, + sandbox: daytonaSandbox, - sandbox: new LocalSandbox({ - id: 'sandbox', - workingDirectory: './workspace', - }),🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/mastra/workspaces.ts` around lines 4 - 22, The daytonaSandbox instance is created but unused; either delete the daytonaSandbox block (remove the const daytonaSandbox = new DaytonaSandbox({...}) declaration) to eliminate dead code, or enable it by restoring the sandbox assignment in the mainWorkspace configuration (uncomment/add sandbox: daytonaSandbox inside the new Workspace({...}) so mainWorkspace uses the DaytonaSandbox). Ensure you update any related imports for DaytonaSandbox if you remove the block or rely on it.lib/types/mastra-api.ts (1)
209-214:⚠️ Potential issue | 🟡 Minor
AgentSchemais out of sync with the expandedAgentinterface.The Zod
AgentSchemaonly validates 4 fields (id,name,description,modelId), while the newAgentinterface defines 34 properties. This drift may cause runtime validation to miss required fields or accept invalid data.Consider either expanding the schema to match the interface, or documenting which subset of the interface the schema validates.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@lib/types/mastra-api.ts` around lines 209 - 214, AgentSchema currently validates only four fields but the Agent interface now contains many more properties; update the schema or document its intent. Either (A) expand AgentSchema to include all required/optional properties from the Agent interface (match types and optionality for fields such as status, settings, createdAt, updatedAt, ownerId, permissions, etc.) so runtime validation aligns with the interface, or (B) add a clear comment and/or create a narrower schema name (e.g., AgentSummarySchema) that explicitly lists and documents the subset it validates; locate and update the Zod definition named AgentSchema and the TypeScript Agent interface to ensure names and field coverage are consistent.app/layout.tsx (1)
65-77:⚠️ Potential issue | 🟡 MinorDuplicate Open Graph and Twitter meta tags.
The manual
<meta>tags in the<head>(lines 65-77) duplicate theopenGraphandmetadataobject (lines 29-51). Next.js automatically injects these from the metadata export, so the manual tags are redundant and could cause duplicate meta tags in the rendered HTML.🧹 Consider removing duplicates
<head> <meta name="robots" content="index,follow" /> <link rel="canonical" href="https://deanmachines.com/" /> - <meta - property="og:title" - content="AgentStack | Multi-Agent Framework" - /> - <meta - property="og:description" - content="Production-grade multi-agent framework for AI applications with 22+ agents, 30+ tools." - /> - <meta - property="og:image" - content="https://deanmachines.com/og-image.png" - /> - <meta name="twitter:card" content="summary_large_image" /> - <meta name="twitter:site" content="@ssdeanx" /> <scriptNote: Keep
twitter:siteif needed since it's not in the metadata export, but the other OG/Twitter tags are duplicated.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/layout.tsx` around lines 65 - 77, The manual <meta> tags for Open Graph and Twitter in the head (og:title, og:description, og:image, twitter:card) are duplicates of the properties defined in the exported metadata object; remove those manual meta entries and rely on the exported metadata to avoid duplicate tags, keeping any unique tags not present in metadata (e.g., twitter:site) if required; update the JSX in app/layout.tsx by deleting the duplicated <meta> nodes while leaving the exported metadata object unchanged and verifying no other manual OG/Twitter tags remain.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.env.example:
- Line 15: Update the .env.example to include the Daytona-related environment
variables referenced by src/mastra/workspaces.ts: add DAYTONA_API_KEY and
DAYTONA_API_URL entries (with placeholder values and a short comment indicating
their purpose) so developers can see and set the API key and base URL required
by the Daytona integration.
In `@app/chat/components/chat-sidebar.tsx`:
- Around line 245-301: The TabsTrigger elements repeat the same long className;
extract that string into a constant (e.g., TABS_TRIGGER_CLASS) declared after
imports and before the ChatSidebar component, then replace each TabsTrigger's
className with that constant (referencing TabsTrigger and the existing TabsList
block); ensure the constant includes the full original class string so all 8
triggers (values:
"threads","agents","tools","workflows","traces","vectors","memory","config") use
it to keep behavior identical.
- Around line 250-299: The repeated icon className "size-3
group-hover/tab:scale-110 transition-transform duration-300" used in each
TabsTrigger should be extracted to a shared constant for consistency and easier
maintenance; add a constant (e.g., ICON_CLASS or ICON_TRIGGER_CLASS) near the
existing TAB_TRIGGER_CLASS and replace inline className values on each icon
component (MessageSquareIcon, BotIcon, CpuIcon, WorkflowIcon, ActivityIcon,
LayersIcon, BrainIcon, SettingsIcon) to reference that constant.
In `@app/chat/components/main-sidebar.tsx`:
- Line 312: The paragraph element in main-sidebar.tsx has a duplicated CSS class
("italic") in its className (the JSX <p ...> with className "text-xs italic
text-muted-foreground/60 italic leading-relaxed"); remove the redundant "italic"
so the className only includes it once (e.g., "text-xs italic
text-muted-foreground/60 leading-relaxed") to avoid duplication.
- Around line 50-56: The toggleSection function is recreated on every render and
should be memoized with useCallback for consistency with other handlers; change
toggleSection to a useCallback that depends on openSection and calls
setOpenSection(openSection === section ? null : section), keeping the same
signature so references like onOpenChange still work and align with
handleAgentClick's pattern.
In `@app/components/query-provider.tsx`:
- Around line 9-15: The QueryClient instantiation (new QueryClient with
defaultOptions -> queries) lacks explicit production-safe retry and
garbage-collection settings; update the defaultOptions.queries object in the
QueryClient creation to add an explicit retry policy (e.g., retry: <number> or
retry: (failureCount) => boolean, and optional retryDelay) and set cache/gc
timing (gcTime or cacheTime) to control resource retention; modify the
QueryClient callsite where defaultOptions and staleTime are set so it includes
these keys alongside staleTime for predictable production behavior.
In `@lib/types/mastra-api.ts`:
- Around line 122-126: The Agent interface uses `any` for multiple properties
(instructions, tools, workflows, agents, skills, defaultOptions,
defaultGenerateOptionsLegacy, defaultStreamOptionsLegacy), weakening type
safety; replace those `any` usages with safer types—prefer `unknown` if you want
callers to explicitly narrow, or define/consume proper interfaces (e.g.,
SystemMessage, GetToolResponse, GetWorkflowResponse, SkillMetadata,
DefaultOptions, DefaultGenerateOptionsLegacy, DefaultStreamOptionsLegacy) and
use those named types on the Agent properties (and the same spots called out
around lines 144-146) so the compiler forces correct usage and avoids implicit
any.
In `@package.json`:
- Line 65: The dependency declaration for "@mastra/daytona" uses a caret range
"^0.0.1"; to give stricter control either pin it to the exact version "0.0.1" or
implement a monitoring/update strategy: change the dependency spec for
"@mastra/daytona" from a caret range to the exact version string in package.json
(or add an automated dependabot/rust-style workflow to watch for new releases)
and document the chosen approach in the repo README or dependabot configuration
so future updates are tracked.
In `@README.md`:
- Line 40: The README paragraph containing the AgentStack summary exceeds the
80-character markdown line-length limit; soft-wrap that long sentence into
multiple lines under 80 characters (preserving words and punctuation) so the
paragraph is split into readable lines, and apply the same soft-wrapping fix to
the other long lines noted (lines referenced in the comment at 91 and 93) so all
three affected README paragraphs comply with the 80-char guideline.
- Around line 22-25: README has inconsistent capability counts across the file
(the badges for "Agents", "Tools", "Workflows", "Networks" disagree with other
mentions like "48+", "12", "13"); fix by choosing a single canonical source for
counts (e.g., generate_counts script or a central constant) and update all
occurrences to use that source, replacing the hard-coded badge numbers and the
conflicting entries in the "Features"/badges sections so they match the
canonical values; ensure the badges lines containing "Agents", "Tools",
"Workflows", and "Networks" and the later textual references ("48+", "12", "13"
etc.) are updated to reference or be generated from the same source.
- Line 1: Replace the HTML metadata comment "<!-- AGENTS-META ... -->" at the
top of README.md with a YAML front matter block (---) placed at the very
beginning of the file containing the required keys: post_title, author1,
post_slug, microsoft_alias, featured_image, categories (choose entries from
/categories.txt), tags, ai_note, summary, and post_date; you may retain the
original AGENTS-META HTML comment below or after the front matter if desired,
but ensure the YAML front matter is the first thing in the file and all fields
are populated with appropriate values.
In `@src/components/ai-elements/persona.tsx`:
- Around line 267-285: The effect that sets Rive inputs (useEffect containing
updateRiveInputs) only depends on state and can miss applying state when the
Rive input refs become available later; update the dependency list so the effect
also re-runs when the inputs load (for example add listeningRef.current,
thinkingRef.current, speakingRef.current, asleepRef.current or a
riveLoaded/riveInstance boolean to the dependency array) so updateRiveInputs
runs both on state changes and when inputs become available, keeping the persona
visuals synchronized.
In `@src/components/ai-elements/tools/research-tools.tsx`:
- Line 64: Replace the invalid Tailwind class on the ScrollArea component: the
className "h-75 pr-4" should use a valid height utility (e.g. "h-[350px] pr-4")
or derive the value from a named constant. Update the ScrollArea usage in the
ResearchTools component to reference a constant like SCROLL_AREA_HEIGHT (or a
semantic name) instead of the magic string so the height is both valid and
maintainable.
- Line 53: The variable `news` (derived from `output.news_results ?? output.data
?? []` in research-tools.tsx) may be a non-array and will break when later used
with `news.map(...)`; update the assignment to validate and normalize the shape
to an array before iteration (e.g., check Array.isArray on `output.news_results`
and `output.data`, fall back to an empty array, and optionally wrap a single
object into an array) so `news.map` is safe; adjust the initializer where `news`
is declared and ensure any later uses (e.g., rendering) assume an array.
In `@src/mastra/a2a/a2aCoordinatorAgent.ts`:
- Line 43: Delete the dead commented line "// const userId =
requestContext.get('userId')" from a2aCoordinatorAgent.ts and simplify the
callback signature that currently includes requestContext (the `instructions`
callback) by removing the unused requestContext parameter; update any call sites
of the `instructions` function in this module to match the reduced signature so
there are no unused parameters remaining.
In `@src/mastra/agents/researchAgent.ts`:
- Around line 27-28: The import convexMemory is unused in researchAgent.ts while
the code still references pgMemory (e.g., the pgMemory usage around the agent
setup); either complete the migration by replacing pgMemory references with
convexMemory where intended (update any variable names and initialization code
using convexMemory) or remove the unused import line for convexMemory; locate
the import statement for convexMemory and the pgMemory references (search for
convexMemory and pgMemory in researchAgent.ts) and make the corresponding change
so no imported symbol is unused.
In `@src/mastra/config/google.ts`:
- Line 29: Extract the inline model ID 'gemini-2.5-flash' into a named constant
(e.g., GEMINI_2_5_FLASH_MODEL_ID) and replace the usage in the config entry
gemini25Flash: google.chat('gemini-2.5-flash') with the constant (gemini25Flash:
google.chat(GEMINI_2_5_FLASH_MODEL_ID)); add the constant near the other
provider model ID constants in this module so all provider model IDs are
centralized and consistent.
In `@tests/test-results/test-results.json`:
- Line 1: The committed JSON is a generated test artifact (contains keys like
"success" and "testResults") and should be removed from VCS; delete
tests/test-results/test-results.json from the commit, add the
tests/test-results/ pattern to .gitignore, and commit that change so future
generated test output is not tracked, then re-run the test suite locally/CI to
investigate why "success": false and "testResults" is empty and fix the test
configuration if needed.
- Line 1: The JSON test-results file is unformatted; pretty-print the JSON (use
a JSON formatter or run Prettier) so keys like "numTotalTestSuites" and
"startTime" are indented and human-readable, then replace the existing content
in the test-results.json with the formatted version and commit the change;
ensure your formatter preserves valid JSON and run the repo's
formatter/pre-commit hook before pushing.
In `@ui/sidebar.tsx`:
- Line 675: The long single-line className string in ui/sidebar.tsx should be
split into multiple concatenated lines for readability and consistency with
nearby components like SidebarMenuAction and SidebarMenuBadge; locate the long
string (the className array entry containing 'text-sidebar-foreground
ring-sidebar-ring cursor-pointer hover:bg-sidebar-accent ... [&>svg]:shrink-0')
and break it into logical groups (layout, spacing, state styles, svg rules) each
on its own line, preserving the exact class tokens and quoting/commas so the
final array element remains the same string value.
---
Outside diff comments:
In `@app/chat/components/chat-sidebar.tsx`:
- Around line 45-1008: ChatSidebar is too large and mixes many responsibilities;
extract each TabsContent block into focused child components (e.g., ThreadsTab,
AgentsTab, ToolsTab, WorkflowsTab, TracesTab, VectorsTab, MemoryTab, ConfigTab)
that receive only the props they need (data arrays like agents/threads/vectors,
loading flags, refresh callbacks such as
onRefreshAgents/onRefreshThreads/onRefreshVectors, and handlers like
restoreCheckpoint, handleSaveMemory, handleUpdateInstructions) while keeping
shared hooks/useMastraQuery calls and state (selectedAgent, agentConfig,
instructions, tempThreadId/tempResourceId, etc.) in ChatSidebar; replace the
inline JSX for each tab (the TabsContent with value="...") with the new
component imports and pass the referenced symbols (agentsQuery data -> agents,
loadingAgents, traces (from tracesRes), memoryStatus, enhanceInstructions,
setIsEditingInstructions, setInstructions, setThreadId/setResourceId) so
behavior remains identical but the file is split for maintainability and
testability.
In `@app/layout.tsx`:
- Around line 65-77: The manual <meta> tags for Open Graph and Twitter in the
head (og:title, og:description, og:image, twitter:card) are duplicates of the
properties defined in the exported metadata object; remove those manual meta
entries and rely on the exported metadata to avoid duplicate tags, keeping any
unique tags not present in metadata (e.g., twitter:site) if required; update the
JSX in app/layout.tsx by deleting the duplicated <meta> nodes while leaving the
exported metadata object unchanged and verifying no other manual OG/Twitter tags
remain.
In `@lib/a2a.ts`:
- Around line 12-153: The main function is doing too many jobs; refactor by
extracting focused helper functions and constants: create COORDINATOR_AGENT_ID
and CONTENT_CREATOR_AGENT_ID constants to replace magic strings, implement
getAgentCard(a2aClient) to call a2aClient.getCard() and log/return the card,
implement sendAgentMessage(a2aClient, query) to build the messageId, call
a2aClient.sendMessage(), handle the 'error' and 'messageId' cases and return the
response, implement checkTaskStatus(a2aClient, taskId) to call
a2aClient.getTask() and handle errors/return status, and implement
demonstrateA2AWorkflow() which uses
client.getA2A(COORDINATOR_AGENT_ID)/client.getA2A(CONTENT_CREATOR_AGENT_ID) plus
sendAgentMessage and checkTaskStatus to perform the research->content flow; then
simplify main to get the A2A client via client.getA2A(COORDINATOR_AGENT_ID),
call getAgentCard, call sendAgentMessage for the initial query, inspect returned
task id via response.result.id and call checkTaskStatus as needed, and call
demonstrateA2AWorkflow for the agent-to-agent example so each function
(getAgentCard, sendAgentMessage, checkTaskStatus, demonstrateA2AWorkflow, main)
stays small and single-responsibility.
- Around line 52-63: The early unconditional returns after the comment about
Mastra's A2A returning a task make the subsequent console.log blocks (which read
response.result.status, response.result.status.message and access parts[0].text)
unreachable; fix by either removing the dead message-handling blocks or changing
the early return into a proper conditional/feature-flag/version check (e.g.,
test response.result.status type or an isTaskResponse flag) so that when
response.result.status indicates a message the code that logs
response.result.status.message?.parts[0].text executes, and when it indicates a
task the code handles the task path—apply the same change consistently for all
three occurrences around the response/result logging and message handling.
In `@lib/types/mastra-api.ts`:
- Around line 209-214: AgentSchema currently validates only four fields but the
Agent interface now contains many more properties; update the schema or document
its intent. Either (A) expand AgentSchema to include all required/optional
properties from the Agent interface (match types and optionality for fields such
as status, settings, createdAt, updatedAt, ownerId, permissions, etc.) so
runtime validation aligns with the interface, or (B) add a clear comment and/or
create a narrower schema name (e.g., AgentSummarySchema) that explicitly lists
and documents the subset it validates; locate and update the Zod definition
named AgentSchema and the TypeScript Agent interface to ensure names and field
coverage are consistent.
In `@src/mastra/workspaces.ts`:
- Around line 4-22: The daytonaSandbox instance is created but unused; either
delete the daytonaSandbox block (remove the const daytonaSandbox = new
DaytonaSandbox({...}) declaration) to eliminate dead code, or enable it by
restoring the sandbox assignment in the mainWorkspace configuration
(uncomment/add sandbox: daytonaSandbox inside the new Workspace({...}) so
mainWorkspace uses the DaytonaSandbox). Ensure you update any related imports
for DaytonaSandbox if you remove the block or rely on it.
ℹ️ Review info
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (25)
.env.example.gitignoreAI_ELEMENTS_INTEGRATION_TODO.mdREADME.mdapp/chat/components/chat-layout.tsxapp/chat/components/chat-messages.tsxapp/chat/components/chat-sidebar.tsxapp/chat/components/main-sidebar.tsxapp/components/query-provider.tsxapp/layout.tsxlib/a2a.tslib/types/mastra-api.tspackage.jsonsrc/components/ai-elements/custom/index.tssrc/components/ai-elements/persona.tsxsrc/components/ai-elements/tools/research-tools.tsxsrc/mastra/a2a/a2aCoordinatorAgent.tssrc/mastra/agents/researchAgent.tssrc/mastra/agents/weather-agent.tssrc/mastra/config/google.tssrc/mastra/index.tssrc/mastra/workspaces.tstests/test-results/test-results.jsonui/resizable.tsxui/sidebar.tsx
🔥 Files not summarized due to errors (8)
- lib/a2a.ts: Error: Server error: no LLM provider could handle the message
- ui/sidebar.tsx: Error: Server error: no LLM provider could handle the message
- README.md: Error: Server error: no LLM provider could handle the message
- app/chat/components/chat-sidebar.tsx: Error: Server error: no LLM provider could handle the message
- src/mastra/config/google.ts: Error: Server error: no LLM provider could handle the message
- src/mastra/workspaces.ts: Error: Server error: no LLM provider could handle the message
- src/components/ai-elements/tools/research-tools.tsx: Error: Server error: no LLM provider could handle the message
- tests/test-results/test-results.json: Error: Server error: no LLM provider could handle the message
💤 Files with no reviewable changes (2)
- src/components/ai-elements/custom/index.ts
- AI_ELEMENTS_INTEGRATION_TODO.md
| OPENAI_API_KEY='your_openai_api_key_here' | ||
| OPENAI_BASE_URL='https://api.openai.com/v1' | ||
| OPENAI_MODEL='gpt-5.1-mini' | ||
| OPENAI_MODEL='gpt-5-mini' |
There was a problem hiding this comment.
Add missing Daytona environment variables.
The src/mastra/workspaces.ts file references DAYTONA_API_KEY and DAYTONA_API_URL environment variables, but they are not documented in .env.example. This makes it difficult for developers to know these variables exist.
As per coding guidelines: "Update .env.example file when new environment variables are added to the codebase."
📝 Proposed addition
# Smithery Configuration (optional, for advanced mcp)
SMITHERY_API_KEY='your_smithery_api_key_here'
SMITHERY_PROFILE='your_smithery_profile_here'
+# Daytona Sandbox Configuration (optional, for cloud sandbox execution)
+DAYTONA_API_KEY='your_daytona_api_key_here'
+DAYTONA_API_URL='https://api.daytona.io'
+
# Convex Configuration🧰 Tools
🪛 dotenv-linter (4.0.0)
[warning] 15-15: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.env.example at line 15, Update the .env.example to include the
Daytona-related environment variables referenced by src/mastra/workspaces.ts:
add DAYTONA_API_KEY and DAYTONA_API_URL entries (with placeholder values and a
short comment indicating their purpose) so developers can see and set the API
key and base URL required by the Daytona integration.
| <TabsList className="w-full grid grid-cols-8 gap-0.5 p-1 bg-black/40 rounded-xl h-auto border border-white/10 shadow-inner overflow-x-auto no-scrollbar"> | ||
| <TabsTrigger | ||
| value="threads" | ||
| className="flex items-center gap-1 text-xs" | ||
| className="flex flex-col items-center gap-1 text-[10px] py-1.5 data-[state=active]:bg-primary/20 data-[state=active]:text-primary transition-all duration-300 rounded-lg group/tab data-[state=active]:shadow-[0_0_20px_rgba(var(--primary),0.1)] border border-transparent data-[state=active]:border-primary/20" | ||
| > | ||
| <MessageSquareIcon className="size-3" /> Threads | ||
| <MessageSquareIcon className="size-3 group-hover/tab:scale-110 transition-transform duration-300" /> | ||
| <span className="opacity-70 group-data-[state=active]:opacity-100 font-semibold tracking-tight text-[8px]">Threads</span> | ||
| </TabsTrigger> | ||
| <TabsTrigger | ||
| value="agents" | ||
| className="flex items-center gap-1 text-xs" | ||
| className="flex flex-col items-center gap-1 text-[10px] py-1.5 data-[state=active]:bg-primary/20 data-[state=active]:text-primary transition-all duration-300 rounded-lg group/tab data-[state=active]:shadow-[0_0_20px_rgba(var(--primary),0.1)] border border-transparent data-[state=active]:border-primary/20" | ||
| > | ||
| <BotIcon className="size-3" /> Agents | ||
| <BotIcon className="size-3 group-hover/tab:scale-110 transition-transform duration-300" /> | ||
| <span className="opacity-70 group-data-[state=active]:opacity-100 font-semibold tracking-tight text-[8px]">Agents</span> | ||
| </TabsTrigger> | ||
| <TabsTrigger | ||
| value="tools" | ||
| className="flex items-center gap-1 text-xs" | ||
| className="flex flex-col items-center gap-1 text-[10px] py-1.5 data-[state=active]:bg-primary/20 data-[state=active]:text-primary transition-all duration-300 rounded-lg group/tab data-[state=active]:shadow-[0_0_20px_rgba(var(--primary),0.1)] border border-transparent data-[state=active]:border-primary/20" | ||
| > | ||
| <CpuIcon className="size-3" /> Tools | ||
| <CpuIcon className="size-3 group-hover/tab:scale-110 transition-transform duration-300" /> | ||
| <span className="opacity-70 group-data-[state=active]:opacity-100 font-semibold tracking-tight text-[8px]">Tools</span> | ||
| </TabsTrigger> | ||
| <TabsTrigger | ||
| value="workflows" | ||
| className="flex items-center gap-1 text-xs" | ||
| className="flex flex-col items-center gap-1 text-[10px] py-1.5 data-[state=active]:bg-primary/20 data-[state=active]:text-primary transition-all duration-300 rounded-lg group/tab data-[state=active]:shadow-[0_0_20px_rgba(var(--primary),0.1)] border border-transparent data-[state=active]:border-primary/20" | ||
| > | ||
| <WorkflowIcon className="size-3" /> Flows | ||
| <WorkflowIcon className="size-3 group-hover/tab:scale-110 transition-transform duration-300" /> | ||
| <span className="opacity-70 group-data-[state=active]:opacity-100 font-semibold tracking-tight text-[8px]">Flows</span> | ||
| </TabsTrigger> | ||
| <TabsTrigger | ||
| value="traces" | ||
| className="flex items-center gap-1 text-xs" | ||
| className="flex flex-col items-center gap-1 text-[10px] py-1.5 data-[state=active]:bg-primary/20 data-[state=active]:text-primary transition-all duration-300 rounded-lg group/tab data-[state=active]:shadow-[0_0_20px_rgba(var(--primary),0.1)] border border-transparent data-[state=active]:border-primary/20" | ||
| > | ||
| <ActivityIcon className="size-3" /> Traces | ||
| <ActivityIcon className="size-3 group-hover/tab:scale-110 transition-transform duration-300" /> | ||
| <span className="opacity-70 group-data-[state=active]:opacity-100 font-semibold tracking-tight text-[8px]">Traces</span> | ||
| </TabsTrigger> | ||
| <TabsTrigger | ||
| value="vectors" | ||
| className="flex items-center gap-1 text-xs" | ||
| > | ||
| <LayersIcon className="size-3" /> Vectors | ||
| </TabsTrigger> | ||
| <TabsTrigger | ||
| value="logs" | ||
| className="flex items-center gap-1 text-xs" | ||
| className="flex flex-col items-center gap-1 text-[10px] py-1.5 data-[state=active]:bg-primary/20 data-[state=active]:text-primary transition-all duration-300 rounded-lg group/tab data-[state=active]:shadow-[0_0_20px_rgba(var(--primary),0.1)] border border-transparent data-[state=active]:border-primary/20" | ||
| > | ||
| <ScrollTextIcon className="size-3" /> Logs | ||
| <LayersIcon className="size-3 group-hover/tab:scale-110 transition-transform duration-300" /> | ||
| <span className="opacity-70 group-data-[state=active]:opacity-100 font-semibold tracking-tight text-[8px]">Vectors</span> | ||
| </TabsTrigger> | ||
| <TabsTrigger | ||
| value="memory" | ||
| className="flex items-center gap-1 text-xs" | ||
| className="flex flex-col items-center gap-1 text-[10px] py-1.5 data-[state=active]:bg-primary/20 data-[state=active]:text-primary transition-all duration-300 rounded-lg group/tab data-[state=active]:shadow-[0_0_20px_rgba(var(--primary),0.1)] border border-transparent data-[state=active]:border-primary/20" | ||
| > | ||
| <BrainIcon className="size-3" /> Memory | ||
| <BrainIcon className="size-3 group-hover/tab:scale-110 transition-transform duration-300" /> | ||
| <span className="opacity-70 group-data-[state=active]:opacity-100 font-semibold tracking-tight text-[8px]">Memory</span> | ||
| </TabsTrigger> | ||
| <TabsTrigger | ||
| value="config" | ||
| className="flex items-center gap-1 text-xs" | ||
| className="flex flex-col items-center gap-1 text-[10px] py-1.5 data-[state=active]:bg-primary/20 data-[state=active]:text-primary transition-all duration-300 rounded-lg group/tab data-[state=active]:shadow-[0_0_20px_rgba(var(--primary),0.1)] border border-transparent data-[state=active]:border-primary/20" | ||
| > | ||
| <SettingsIcon className="size-3" /> Config | ||
| <SettingsIcon className="size-3 group-hover/tab:scale-110 transition-transform duration-300" /> | ||
| <span className="opacity-70 group-data-[state=active]:opacity-100 font-semibold tracking-tight text-[8px]">Config</span> | ||
| </TabsTrigger> |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Extract repetitive className to improve maintainability.
The same className string is duplicated across all 8 TabsTrigger elements. This violates the DRY principle and makes maintenance difficult—any styling change requires updating 8 locations.
♻️ Suggested refactor to extract common className
Add a constant near the top of the component (after imports, before the component definition):
+const TAB_TRIGGER_CLASS =
+ "flex flex-col items-center gap-1 text-[10px] py-1.5 data-[state=active]:bg-primary/20 data-[state=active]:text-primary transition-all duration-300 rounded-lg group/tab data-[state=active]:shadow-[0_0_20px_rgba(var(--primary),0.1)] border border-transparent data-[state=active]:border-primary/20"
+
export function ChatSidebar() {Then simplify each TabsTrigger:
<TabsTrigger
value="threads"
- className="flex flex-col items-center gap-1 text-[10px] py-1.5 data-[state=active]:bg-primary/20 data-[state=active]:text-primary transition-all duration-300 rounded-lg group/tab data-[state=active]:shadow-[0_0_20px_rgba(var(--primary),0.1)] border border-transparent data-[state=active]:border-primary/20"
+ className={TAB_TRIGGER_CLASS}
>Apply the same change to all 8 TabsTrigger elements (agents, tools, workflows, traces, vectors, memory, config).
As per coding guidelines: "Avoid code duplication (DRY principle)".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@app/chat/components/chat-sidebar.tsx` around lines 245 - 301, The TabsTrigger
elements repeat the same long className; extract that string into a constant
(e.g., TABS_TRIGGER_CLASS) declared after imports and before the ChatSidebar
component, then replace each TabsTrigger's className with that constant
(referencing TabsTrigger and the existing TabsList block); ensure the constant
includes the full original class string so all 8 triggers (values:
"threads","agents","tools","workflows","traces","vectors","memory","config") use
it to keep behavior identical.
| <MessageSquareIcon className="size-3 group-hover/tab:scale-110 transition-transform duration-300" /> | ||
| <span className="opacity-70 group-data-[state=active]:opacity-100 font-semibold tracking-tight text-[8px]">Threads</span> | ||
| </TabsTrigger> | ||
| <TabsTrigger | ||
| value="agents" | ||
| className="flex items-center gap-1 text-xs" | ||
| className="flex flex-col items-center gap-1 text-[10px] py-1.5 data-[state=active]:bg-primary/20 data-[state=active]:text-primary transition-all duration-300 rounded-lg group/tab data-[state=active]:shadow-[0_0_20px_rgba(var(--primary),0.1)] border border-transparent data-[state=active]:border-primary/20" | ||
| > | ||
| <BotIcon className="size-3" /> Agents | ||
| <BotIcon className="size-3 group-hover/tab:scale-110 transition-transform duration-300" /> | ||
| <span className="opacity-70 group-data-[state=active]:opacity-100 font-semibold tracking-tight text-[8px]">Agents</span> | ||
| </TabsTrigger> | ||
| <TabsTrigger | ||
| value="tools" | ||
| className="flex items-center gap-1 text-xs" | ||
| className="flex flex-col items-center gap-1 text-[10px] py-1.5 data-[state=active]:bg-primary/20 data-[state=active]:text-primary transition-all duration-300 rounded-lg group/tab data-[state=active]:shadow-[0_0_20px_rgba(var(--primary),0.1)] border border-transparent data-[state=active]:border-primary/20" | ||
| > | ||
| <CpuIcon className="size-3" /> Tools | ||
| <CpuIcon className="size-3 group-hover/tab:scale-110 transition-transform duration-300" /> | ||
| <span className="opacity-70 group-data-[state=active]:opacity-100 font-semibold tracking-tight text-[8px]">Tools</span> | ||
| </TabsTrigger> | ||
| <TabsTrigger | ||
| value="workflows" | ||
| className="flex items-center gap-1 text-xs" | ||
| className="flex flex-col items-center gap-1 text-[10px] py-1.5 data-[state=active]:bg-primary/20 data-[state=active]:text-primary transition-all duration-300 rounded-lg group/tab data-[state=active]:shadow-[0_0_20px_rgba(var(--primary),0.1)] border border-transparent data-[state=active]:border-primary/20" | ||
| > | ||
| <WorkflowIcon className="size-3" /> Flows | ||
| <WorkflowIcon className="size-3 group-hover/tab:scale-110 transition-transform duration-300" /> | ||
| <span className="opacity-70 group-data-[state=active]:opacity-100 font-semibold tracking-tight text-[8px]">Flows</span> | ||
| </TabsTrigger> | ||
| <TabsTrigger | ||
| value="traces" | ||
| className="flex items-center gap-1 text-xs" | ||
| className="flex flex-col items-center gap-1 text-[10px] py-1.5 data-[state=active]:bg-primary/20 data-[state=active]:text-primary transition-all duration-300 rounded-lg group/tab data-[state=active]:shadow-[0_0_20px_rgba(var(--primary),0.1)] border border-transparent data-[state=active]:border-primary/20" | ||
| > | ||
| <ActivityIcon className="size-3" /> Traces | ||
| <ActivityIcon className="size-3 group-hover/tab:scale-110 transition-transform duration-300" /> | ||
| <span className="opacity-70 group-data-[state=active]:opacity-100 font-semibold tracking-tight text-[8px]">Traces</span> | ||
| </TabsTrigger> | ||
| <TabsTrigger | ||
| value="vectors" | ||
| className="flex items-center gap-1 text-xs" | ||
| > | ||
| <LayersIcon className="size-3" /> Vectors | ||
| </TabsTrigger> | ||
| <TabsTrigger | ||
| value="logs" | ||
| className="flex items-center gap-1 text-xs" | ||
| className="flex flex-col items-center gap-1 text-[10px] py-1.5 data-[state=active]:bg-primary/20 data-[state=active]:text-primary transition-all duration-300 rounded-lg group/tab data-[state=active]:shadow-[0_0_20px_rgba(var(--primary),0.1)] border border-transparent data-[state=active]:border-primary/20" | ||
| > | ||
| <ScrollTextIcon className="size-3" /> Logs | ||
| <LayersIcon className="size-3 group-hover/tab:scale-110 transition-transform duration-300" /> | ||
| <span className="opacity-70 group-data-[state=active]:opacity-100 font-semibold tracking-tight text-[8px]">Vectors</span> | ||
| </TabsTrigger> | ||
| <TabsTrigger | ||
| value="memory" | ||
| className="flex items-center gap-1 text-xs" | ||
| className="flex flex-col items-center gap-1 text-[10px] py-1.5 data-[state=active]:bg-primary/20 data-[state=active]:text-primary transition-all duration-300 rounded-lg group/tab data-[state=active]:shadow-[0_0_20px_rgba(var(--primary),0.1)] border border-transparent data-[state=active]:border-primary/20" | ||
| > | ||
| <BrainIcon className="size-3" /> Memory | ||
| <BrainIcon className="size-3 group-hover/tab:scale-110 transition-transform duration-300" /> | ||
| <span className="opacity-70 group-data-[state=active]:opacity-100 font-semibold tracking-tight text-[8px]">Memory</span> | ||
| </TabsTrigger> | ||
| <TabsTrigger | ||
| value="config" | ||
| className="flex items-center gap-1 text-xs" | ||
| className="flex flex-col items-center gap-1 text-[10px] py-1.5 data-[state=active]:bg-primary/20 data-[state=active]:text-primary transition-all duration-300 rounded-lg group/tab data-[state=active]:shadow-[0_0_20px_rgba(var(--primary),0.1)] border border-transparent data-[state=active]:border-primary/20" | ||
| > | ||
| <SettingsIcon className="size-3" /> Config | ||
| <SettingsIcon className="size-3 group-hover/tab:scale-110 transition-transform duration-300" /> |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Extract repetitive icon className for consistency.
The icon className "size-3 group-hover/tab:scale-110 transition-transform duration-300" is repeated 8 times across all tab icons. Consider extracting this to a constant alongside the TabsTrigger className.
♻️ Optional refactor for icon styling
Add alongside the TAB_TRIGGER_CLASS constant:
const TAB_TRIGGER_CLASS =
"flex flex-col items-center gap-1 text-[10px] py-1.5 data-[state=active]:bg-primary/20 data-[state=active]:text-primary transition-all duration-300 rounded-lg group/tab data-[state=active]:shadow-[0_0_20px_rgba(var(--primary),0.1)] border border-transparent data-[state=active]:border-primary/20"
+const TAB_ICON_CLASS = "size-3 group-hover/tab:scale-110 transition-transform duration-300"Then apply to each icon:
- <MessageSquareIcon className="size-3 group-hover/tab:scale-110 transition-transform duration-300" />
+ <MessageSquareIcon className={TAB_ICON_CLASS} />🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@app/chat/components/chat-sidebar.tsx` around lines 250 - 299, The repeated
icon className "size-3 group-hover/tab:scale-110 transition-transform
duration-300" used in each TabsTrigger should be extracted to a shared constant
for consistency and easier maintenance; add a constant (e.g., ICON_CLASS or
ICON_TRIGGER_CLASS) near the existing TAB_TRIGGER_CLASS and replace inline
className values on each icon component (MessageSquareIcon, BotIcon, CpuIcon,
WorkflowIcon, ActivityIcon, LayersIcon, BrainIcon, SettingsIcon) to reference
that constant.
| const [openSection, setOpenSection] = useState<string | null>(null) | ||
|
|
||
| const activeAgentFromUrl = searchParams.get('agent') | ||
|
|
||
| const toggleSection = (section: string) => { | ||
| setOpenSection(openSection === section ? null : section) | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Consider memoizing toggleSection with useCallback.
The toggleSection function is passed to onOpenChange handlers and recreated on every render. While the impact is minimal here, wrapping it in useCallback would be consistent with handleAgentClick and other handlers in this component.
♻️ Suggested improvement
- const toggleSection = (section: string) => {
- setOpenSection(openSection === section ? null : section)
- }
+ const toggleSection = useCallback((section: string) => {
+ setOpenSection((prev) => (prev === section ? null : section))
+ }, [])📝 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.
| const [openSection, setOpenSection] = useState<string | null>(null) | |
| const activeAgentFromUrl = searchParams.get('agent') | |
| const toggleSection = (section: string) => { | |
| setOpenSection(openSection === section ? null : section) | |
| } | |
| const [openSection, setOpenSection] = useState<string | null>(null) | |
| const activeAgentFromUrl = searchParams.get('agent') | |
| const toggleSection = useCallback((section: string) => { | |
| setOpenSection((prev) => (prev === section ? null : section)) | |
| }, []) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@app/chat/components/main-sidebar.tsx` around lines 50 - 56, The toggleSection
function is recreated on every render and should be memoized with useCallback
for consistency with other handlers; change toggleSection to a useCallback that
depends on openSection and calls setOpenSection(openSection === section ? null :
section), keeping the same signature so references like onOpenChange still work
and align with handleAgentClick's pattern.
| </p> | ||
| </div> | ||
| ) : ( | ||
| <p className="text-xs italic text-muted-foreground/60 italic leading-relaxed"> |
There was a problem hiding this comment.
Duplicate italic class.
The className contains italic twice, which is redundant.
🧹 Proposed fix
- <p className="text-xs italic text-muted-foreground/60 italic leading-relaxed">
+ <p className="text-xs italic text-muted-foreground/60 leading-relaxed">📝 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.
| <p className="text-xs italic text-muted-foreground/60 italic leading-relaxed"> | |
| <p className="text-xs italic text-muted-foreground/60 leading-relaxed"> |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@app/chat/components/main-sidebar.tsx` at line 312, The paragraph element in
main-sidebar.tsx has a duplicated CSS class ("italic") in its className (the JSX
<p ...> with className "text-xs italic text-muted-foreground/60 italic
leading-relaxed"); remove the redundant "italic" so the className only includes
it once (e.g., "text-xs italic text-muted-foreground/60 leading-relaxed") to
avoid duplication.
| 'A2A Coordinator that orchestrates multiple specialized agents in parallel. Routes tasks dynamically, coordinates workflows, and synthesizes results using the A2A protocol.', | ||
| instructions: ({ requestContext }) => { | ||
| const userId = requestContext.get('userId') | ||
| // const userId = requestContext.get('userId') |
There was a problem hiding this comment.
Remove commented-out code and keep instructions signature minimal.
Line 43 leaves dead code in place. If user context is intentionally removed, delete the commented line (and simplify the callback signature since requestContext is no longer used).
Suggested cleanup
- instructions: ({ requestContext }) => {
- // const userId = requestContext.get('userId')
+ instructions: () => {As per coding guidelines, "Never comment out code; remove it instead and use version control history if needed."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/mastra/a2a/a2aCoordinatorAgent.ts` at line 43, Delete the dead commented
line "// const userId = requestContext.get('userId')" from
a2aCoordinatorAgent.ts and simplify the callback signature that currently
includes requestContext (the `instructions` callback) by removing the unused
requestContext parameter; update any call sites of the `instructions` function
in this module to match the reduced signature so there are no unused parameters
remaining.
| import { mainWorkspace } from '../workspaces' | ||
| import { convexMemory } from '../config/convex' |
There was a problem hiding this comment.
Unused import: convexMemory is imported but never used.
The convexMemory import is added but the agent still uses pgMemory (line 119). If this is an incomplete migration, please complete it; otherwise, remove the unused import to reduce bundle size.
🧹 Proposed fix to remove unused import
import { InternalSpans } from '@mastra/core/observability'
import { mainWorkspace } from '../workspaces'
-import { convexMemory } from '../config/convex'📝 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.
| import { mainWorkspace } from '../workspaces' | |
| import { convexMemory } from '../config/convex' | |
| import { mainWorkspace } from '../workspaces' |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/mastra/agents/researchAgent.ts` around lines 27 - 28, The import
convexMemory is unused in researchAgent.ts while the code still references
pgMemory (e.g., the pgMemory usage around the agent setup); either complete the
migration by replacing pgMemory references with convexMemory where intended
(update any variable names and initialization code using convexMemory) or remove
the unused import line for convexMemory; locate the import statement for
convexMemory and the pgMemory references (search for convexMemory and pgMemory
in researchAgent.ts) and make the corresponding change so no imported symbol is
unused.
| gemini25Pro: google.chat('gemini-2.5-pro'), | ||
| // Gemini 2.5 Flash model for general-purpose applications | ||
| gemini25Flash: google.chat('gemini-2.5-flash-preview-09-2025'), | ||
| gemini25Flash: google.chat('gemini-2.5-flash'), |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat -n src/mastra/config/google.tsRepository: ssdeanx/AgentStack
Length of output: 4037
🌐 Web query:
@ai-sdk/google Vercel AI SDK gemini-2.5-flash model ID validity latest documentation
💡 Result:
gemini-2.5-flash is a valid (stable) Gemini API model code in Google’s current model list. [1]
For Vercel AI SDK using @ai-sdk/google, the documented model ID is used like this (no google/ prefix):
import { google } from "@ai-sdk/google";
import { generateText } from "ai";
const { text } = await generateText({
model: google("gemini-2.5-flash"),
prompt: "Hello",
});[2]
If you’re using the Vercel AI Gateway (instead of calling Google directly), the model ID is:
google/gemini-2.5-flash[3]
Also note: Vercel’s AI Gateway docs/changelog show Gemini 3 Flash is available as google/gemini-3-flash, which may be the newer default choice depending on what you’re targeting. [4]
Sources: [1] [2] [3] [4]
Extract magic string model ID to a named constant at line 29.
'gemini-2.5-flash' is a valid, stable Gemini model supported by @ai-sdk/google. However, per coding guidelines, inline provider model IDs should be centralized as named constants to avoid drift and typos across aliases and default exports. This pattern appears throughout the file (lines 23, 25, 27, 31–35, 42, 45–47, 52), so consider a comprehensive refactor.
Suggested refactor
+const GOOGLE_CHAT_MODEL_IDS = {
+ GEMINI_25_FLASH: 'gemini-2.5-flash',
+} as const
+
export const googleChatModels = {
- gemini25Flash: google.chat('gemini-2.5-flash'),
+ gemini25Flash: google.chat(GOOGLE_CHAT_MODEL_IDS.GEMINI_25_FLASH),
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/mastra/config/google.ts` at line 29, Extract the inline model ID
'gemini-2.5-flash' into a named constant (e.g., GEMINI_2_5_FLASH_MODEL_ID) and
replace the usage in the config entry gemini25Flash:
google.chat('gemini-2.5-flash') with the constant (gemini25Flash:
google.chat(GEMINI_2_5_FLASH_MODEL_ID)); add the constant near the other
provider model ID constants in this module so all provider model IDs are
centralized and consistent.
| @@ -1 +1 @@ | |||
| {"numTotalTestSuites":0,"numPassedTestSuites":0,"numFailedTestSuites":0,"numPendingTestSuites":0,"numTotalTests":0,"numPassedTests":0,"numFailedTests":0,"numPendingTests":0,"numTodoTests":0,"snapshot":{"added":0,"failure":false,"filesAdded":0,"filesRemoved":0,"filesRemovedList":[],"filesUnmatched":0,"filesUpdated":0,"matched":0,"total":0,"unchecked":0,"uncheckedKeysByFile":[],"unmatched":0,"updated":0,"didUpdate":false},"startTime":1771231281982,"success":false,"testResults":[]} No newline at end of file | |||
| {"numTotalTestSuites":0,"numPassedTestSuites":0,"numFailedTestSuites":0,"numPendingTestSuites":0,"numTotalTests":0,"numPassedTests":0,"numFailedTests":0,"numPendingTests":0,"numTodoTests":0,"snapshot":{"added":0,"failure":false,"filesAdded":0,"filesRemoved":0,"filesRemovedList":[],"filesUnmatched":0,"filesUpdated":0,"matched":0,"total":0,"unchecked":0,"uncheckedKeysByFile":[],"unmatched":0,"updated":0,"didUpdate":false},"startTime":1772263249793,"success":false,"testResults":[]} No newline at end of file | |||
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Generated test results should not be committed to version control.
This file appears to be auto-generated test output. Committing generated test results creates unnecessary noise in the git history, can lead to merge conflicts, and provides no value in the repository. Consider adding tests/test-results/ to your .gitignore file instead.
Additionally, the test run shows success: false with zero tests executed, which may indicate a test configuration issue worth investigating separately.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@tests/test-results/test-results.json` at line 1, The committed JSON is a
generated test artifact (contains keys like "success" and "testResults") and
should be removed from VCS; delete tests/test-results/test-results.json from the
commit, add the tests/test-results/ pattern to .gitignore, and commit that
change so future generated test output is not tracked, then re-run the test
suite locally/CI to investigate why "success": false and "testResults" is empty
and fix the test configuration if needed.
🧹 Nitpick | 🔵 Trivial
Format JSON for readability.
If this file must be committed, it should be formatted with proper indentation for readability. As per coding guidelines, use a code formatter like Prettier to automatically format code.
📝 Formatted JSON
-{"numTotalTestSuites":0,"numPassedTestSuites":0,"numFailedTestSuites":0,"numPendingTestSuites":0,"numTotalTests":0,"numPassedTests":0,"numFailedTests":0,"numPendingTests":0,"numTodoTests":0,"snapshot":{"added":0,"failure":false,"filesAdded":0,"filesRemoved":0,"filesRemovedList":[],"filesUnmatched":0,"filesUpdated":0,"matched":0,"total":0,"unchecked":0,"uncheckedKeysByFile":[],"unmatched":0,"updated":0,"didUpdate":false},"startTime":1772263249793,"success":false,"testResults":[]}
+{
+ "numTotalTestSuites": 0,
+ "numPassedTestSuites": 0,
+ "numFailedTestSuites": 0,
+ "numPendingTestSuites": 0,
+ "numTotalTests": 0,
+ "numPassedTests": 0,
+ "numFailedTests": 0,
+ "numPendingTests": 0,
+ "numTodoTests": 0,
+ "snapshot": {
+ "added": 0,
+ "failure": false,
+ "filesAdded": 0,
+ "filesRemoved": 0,
+ "filesRemovedList": [],
+ "filesUnmatched": 0,
+ "filesUpdated": 0,
+ "matched": 0,
+ "total": 0,
+ "unchecked": 0,
+ "uncheckedKeysByFile": [],
+ "unmatched": 0,
+ "updated": 0,
+ "didUpdate": false
+ },
+ "startTime": 1772263249793,
+ "success": false,
+ "testResults": []
+}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@tests/test-results/test-results.json` at line 1, The JSON test-results file
is unformatted; pretty-print the JSON (use a JSON formatter or run Prettier) so
keys like "numTotalTestSuites" and "startTime" are indented and human-readable,
then replace the existing content in the test-results.json with the formatted
version and commit the change; ensure your formatter preserves valid JSON and
run the repo's formatter/pre-commit hook before pushing.
| data-active={isActive} | ||
| className={cn( | ||
| 'text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground [&>svg]:text-sidebar-accent-foreground flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 outline-hidden focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0', | ||
| 'text-sidebar-foreground ring-sidebar-ring cursor-pointer hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground [&>svg]:text-sidebar-accent-foreground flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 outline-hidden focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0', |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Break long className into multiple lines for consistency and readability.
This className string spans over 600 characters on a single line, making it difficult to read and maintain. Other similar components in this file (e.g., SidebarMenuAction at lines 547-556, SidebarMenuBadge at lines 571-578) consistently format their className strings across multiple lines.
♻️ Suggested refactor for improved readability
className={cn(
- 'text-sidebar-foreground ring-sidebar-ring cursor-pointer hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground [&>svg]:text-sidebar-accent-foreground flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 outline-hidden focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0',
+ 'text-sidebar-foreground ring-sidebar-ring cursor-pointer hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground [&>svg]:text-sidebar-accent-foreground flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 outline-hidden focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50',
+ '[&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0',
'data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground',
size === 'sm' && 'text-xs',
size === 'md' && 'text-sm',📝 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.
| 'text-sidebar-foreground ring-sidebar-ring cursor-pointer hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground [&>svg]:text-sidebar-accent-foreground flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 outline-hidden focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0', | |
| <button | |
| ref={ref} | |
| className={cn( | |
| 'text-sidebar-foreground ring-sidebar-ring cursor-pointer hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground [&>svg]:text-sidebar-accent-foreground flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 outline-hidden focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50', | |
| '[&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0', | |
| 'data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground', | |
| size === 'sm' && 'text-xs', | |
| size === 'md' && 'text-sm', |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@ui/sidebar.tsx` at line 675, The long single-line className string in
ui/sidebar.tsx should be split into multiple concatenated lines for readability
and consistency with nearby components like SidebarMenuAction and
SidebarMenuBadge; locate the long string (the className array entry containing
'text-sidebar-foreground ring-sidebar-ring cursor-pointer
hover:bg-sidebar-accent ... [&>svg]:shrink-0') and break it into logical groups
(layout, spacing, state styles, svg rules) each on its own line, preserving the
exact class tokens and quoting/commas so the final array element remains the
same string value.
…e dependencies, and refresh README documentation.
Summary by Sourcery
Refine the chat experience and Mastra agent integration across the UI, enhance agent/workspace/server configuration, and update dependencies and documentation.
New Features:
Enhancements:
Build:
Documentation:
Chores: