Conversation
- Updated AGENTS.md with new version (2.3.0) and increased counts for enterprise tools (34+), specialized agents (38), and UI components (64). - Updated README.md with new version (3.3.0) and updated counts for enterprise tools (34+), specialized agents (38), and UI components (64). - Refactored chat API route to streamline agent selection and improve runtime context handling. - Enhanced createAgentStreamResponse function to optimize streaming response handling and support new agent execution options. - Added documentation comments for mastraClient to clarify usage for frontend and server-side interactions.
|
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 the server-side chat streaming flow to use core Mastra types and a single agent.stream call that supports both ReadableStream and AsyncIterable outputs, simplifies the chat API route to use a concrete agent with runtime context, clarifies mastraClient usage, and updates README/AGENTS metadata and capability counts. Sequence diagram for updated /api/chat POST flow with runtime contextsequenceDiagram
actor User
participant ChatUI as ChatUI
participant APIRoute as NextApiChatRoute
participant Mastra as Mastra
participant Agent as weatherAgent
participant RuntimeContext as RuntimeContext
User->>ChatUI: Type message and optional data
ChatUI->>APIRoute: POST /api/chat { messages, data }
APIRoute->>Mastra: getAgent(weatherAgent)
Mastra-->>APIRoute: Agent
APIRoute->>RuntimeContext: new RuntimeContext()
alt data present
APIRoute->>RuntimeContext: set(key, value) for each data entry
end
APIRoute->>Agent: stream(messages, runtimeContext, format aisdk)
Agent-->>APIRoute: stream
APIRoute->>Agent: toUIMessageStreamResponse()
Agent-->>APIRoute: Response (streaming)
APIRoute-->>ChatUI: Streaming HTTP response
ChatUI-->>User: Render streamed assistant messages
Sequence diagram for createAgentStreamResponse streaming behaviorsequenceDiagram
participant Caller as APIRouteOrServer
participant Mastra as Mastra
participant Agent as Agent
participant Helper as createAgentStreamResponse
participant AISDK as AISDKTransform
Caller->>Helper: createAgentStreamResponse(mastra, agentId, messages, options)
Helper->>Mastra: getAgent(agentId)
Mastra-->>Helper: Agent
Helper->>Agent: stream(messages, streamOptions)
Agent-->>Helper: StreamResult
alt format aisdk and toUIMessageStreamResponse exists
Helper->>Agent: toUIMessageStreamResponse()
Agent-->>Caller: Response (UIMessageStream)
else fallback to manual AISDK format
Helper->>AISDK: toAISdkFormat(StreamResult, from agent)
AISDK-->>Helper: aiSdkResult
alt aiSdkResult is ReadableStream
Helper->>Helper: asyncIterableFromReadableStream(aiSdkResult)
Helper-->>Caller: Response via createUIMessageStreamResponse(iterable)
else aiSdkResult is AsyncIterable
Helper-->>Caller: Response via createUIMessageStreamResponse(aiSdkResult)
end
end
Class diagram for Mastra streaming and client usage changesclassDiagram
class Mastra {
+getAgent(id string) Agent
}
class Agent {
+stream(messages unknown, options AgentStreamOptions) StreamResult
}
class AgentStreamOptions {
+format string
+threadId string
+resourceId string
+memory AgentExecutionMemory
+maxSteps number
}
class AgentExecutionMemory {
<<type alias from AgentExecutionOptions.memory>>
}
class StreamResult {
<<extends MastraModelOutput>>
+toUIMessageStreamResponse() Response
}
class RuntimeContext {
+set(key string, value unknown) void
}
class MastraClient {
+MastraClient(baseUrl string, retries number, timeout number)
}
class mastraClient {
<<instance>>
+baseUrl string
+retries number
+timeout number
}
class createAgentStreamResponse {
+createAgentStreamResponse(mastra Mastra, agentId string, messages unknown, options AgentStreamOptions) Promise Response
}
class isReadableStream {
+isReadableStream(value unknown) boolean
}
class asyncIterableFromReadableStream {
+asyncIterableFromReadableStream(stream ReadableStream) AsyncIterable
}
Mastra --> Agent : getAgent
Agent --> StreamResult : stream
createAgentStreamResponse --> Mastra : uses
createAgentStreamResponse --> Agent : uses
createAgentStreamResponse --> StreamResult : uses
createAgentStreamResponse --> isReadableStream : calls
createAgentStreamResponse --> asyncIterableFromReadableStream : calls
mastraClient --> MastraClient : instance of
AgentStreamOptions --> AgentExecutionMemory : memory
APIRoute ..> RuntimeContext : creates and passes to Agent.stream
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
Summary by CodeRabbitRelease Notes
✏️ Tip: You can customize this high-level summary in your review settings. WalkthroughVersion bump (2.2.0→2.3.0 AGENTS, 3.2.0→3.3.0 README), product metrics updated (UI components 49→64, agents 25+→38, tools 30+→34+). API route refactored to use fixed weather agent with RuntimeContext. Stream handling logic simplified with new type guards and fallback paths. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50–65 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 |
|
🤖 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 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 primarily focuses on synchronizing project documentation with the latest feature counts and significantly enhancing the backend logic for the chat API. It ensures that the framework's capabilities are accurately communicated while also improving the efficiency and flexibility of agent streaming responses and clarifying the appropriate usage of the Mastra client across different application layers. 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
|
There was a problem hiding this comment.
Hey there - I've reviewed your changes - here's some feedback:
- The chat API route has been simplified to a hard-coded
weatherAgentand no longer validatesagentIdor supports agent discovery via GET; if this endpoint is meant to remain generic, consider preserving the previous dynamic agent selection and validation behavior while still passing the newRuntimeContext. - The JSDoc/example paths for
createAgentStreamResponseand the comment inmastra-client.tsreference"@/lib/server/agent-stream"/"@/lib/client-stream-to-ai-sdk", but the actual implementation still lives inlib/client-stream-to-ai-sdk.ts; aligning these import paths or relocating the file would avoid confusion for consumers. - The relative import
import { mastra } from "../../../src/mastra";in the chat route is more brittle than the previous alias-based import ("@/src/mastra"); if possible, keep using path aliases to avoid breakage on directory moves or depth changes.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The chat API route has been simplified to a hard-coded `weatherAgent` and no longer validates `agentId` or supports agent discovery via GET; if this endpoint is meant to remain generic, consider preserving the previous dynamic agent selection and validation behavior while still passing the new `RuntimeContext`.
- The JSDoc/example paths for `createAgentStreamResponse` and the comment in `mastra-client.ts` reference `"@/lib/server/agent-stream"` / `"@/lib/client-stream-to-ai-sdk"`, but the actual implementation still lives in `lib/client-stream-to-ai-sdk.ts`; aligning these import paths or relocating the file would avoid confusion for consumers.
- The relative import `import { mastra } from "../../../src/mastra";` in the chat route is more brittle than the previous alias-based import (`"@/src/mastra"`); if possible, keep using path aliases to avoid breakage on directory moves or depth changes.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
|
🤖 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.
Code Review
This pull request updates project metadata in AGENTS.md and README.md, and refactors the chat API and related streaming utilities. The documentation updates are consistent with the new version. The enhancements to createAgentStreamResponse in lib/client-stream-to-ai-sdk.ts are excellent, improving performance by avoiding duplicate stream calls and adding robust handling for different stream types. The changes in lib/mastra-client.ts also improve clarity by separating client and server concerns. However, the refactoring of the /api/chat route has introduced a couple of regressions. I've left specific comments with suggestions to re-introduce the maxDuration configuration to prevent timeouts and to restore dynamic agent selection to maintain the endpoint's flexibility.
| import { mastra } from "../../../src/mastra"; | ||
| import { RuntimeContext } from "@mastra/core/runtime-context"; | ||
|
|
There was a problem hiding this comment.
The export const maxDuration = 60; line was removed. This configuration is important for serverless environments like Vercel to prevent the API route from timing out on long-running agent executions. Without it, the function might time out prematurely, using the platform's default which is often shorter. I recommend re-adding it to ensure stability for potentially long-running agent tasks.
import { mastra } from "../../../src/mastra";
import { RuntimeContext } from "@mastra/core/runtime-context";
export const maxDuration = 60;| export async function POST(req: Request) { | ||
| const body: ChatRequestBody = await req.json(); | ||
|
|
||
| // Get available agents dynamically from mastra | ||
| const agentsMap = await mastra.getAgents(); | ||
| const availableAgents = Object.keys(agentsMap); | ||
|
|
||
| // Use first available agent if none specified | ||
| const agentId = body.agentId || availableAgents[0]; | ||
|
|
||
| if (!agentId || !availableAgents.includes(agentId)) { | ||
| return Response.json( | ||
| { error: `Invalid or missing agentId. Available: ${availableAgents.join(", ")}` }, | ||
| { status: 400 } | ||
| ); | ||
| } | ||
| const { messages, data } = await req.json(); | ||
| const myAgent = mastra.getAgent("weatherAgent"); | ||
|
|
||
| if (!body.messages?.length) { | ||
| return Response.json({ error: "messages required" }, { status: 400 }); | ||
| } | ||
|
|
||
| try { | ||
| return await createAgentStreamResponse(mastra as Parameters<typeof createAgentStreamResponse>[0], agentId, body.messages, { | ||
| threadId: body.threadId, | ||
| resourceId: body.resourceId, | ||
| memory: body.memory, | ||
| maxSteps: body.maxSteps ?? 50, | ||
| }); | ||
| } catch (error) { | ||
| return Response.json( | ||
| { error: error instanceof Error ? error.message : "Stream failed" }, | ||
| { status: 500 } | ||
| ); | ||
| const runtimeContext = new RuntimeContext(); | ||
|
|
||
| if (data) { | ||
| for (const [key, value] of Object.entries(data)) { | ||
| runtimeContext.set(key, value); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| export async function GET() { | ||
| const agentsMap = await mastra.getAgents(); | ||
| const availableAgents = Object.keys(agentsMap); | ||
| return Response.json({ agents: availableAgents, count: availableAgents.length }); | ||
| } | ||
| const stream = await myAgent.stream(messages, { | ||
| runtimeContext, | ||
| format: "aisdk", | ||
| }); | ||
| return stream.toUIMessageStreamResponse(); | ||
| } No newline at end of file |
There was a problem hiding this comment.
The chat API has been hardcoded to only use the weatherAgent. This significantly reduces the flexibility of this endpoint, which previously supported dynamic agent selection. While the PR description mentions this is a simplification, it makes the generic /api/chat route less reusable. To restore flexibility while keeping the new RuntimeContext logic, I suggest selecting the agent based on a property in the data object from the request body. This also includes adding a check to ensure the agent exists, providing a clearer error message to the client if it doesn't.
export async function POST(req: Request) {
const { messages, data } = await req.json();
const agentId = data?.agentId ?? "weatherAgent";
const agent = mastra.getAgent(agentId);
if (!agent) {
const availableAgents = Object.keys(await mastra.getAgents());
return Response.json(
{ error: `Agent '${agentId}' not found. Available agents: ${availableAgents.join(', ')}` },
{ status: 400 }
);
}
const runtimeContext = new RuntimeContext();
if (data) {
const { agentId: _, ...contextData } = data;
for (const [key, value] of Object.entries(contextData)) {
runtimeContext.set(key, value);
}
}
const stream = await agent.stream(messages, {
runtimeContext,
format: "aisdk",
});
return stream.toUIMessageStreamResponse();
}There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
lib/mastra-client.ts (1)
10-18: Configuration looks good;abortSignal: undefinedis redundant.The retry configuration with
backoffMsandmaxBackoffMsis a sensible addition for resilience. However,abortSignal: undefinedhas no effect and can be omitted for cleaner code.export const mastraClient = new MastraClient({ baseUrl: process.env.NEXT_PUBLIC_MASTRA_API_URL || "http://localhost:4111", retries: 3, backoffMs: 300, maxBackoffMs: 5000, - abortSignal: undefined, headers: {}, credentials: "same-origin", });README.md (1)
291-291: Inconsistent count: shadcn/ui should be 34, not 19.This line shows "shadcn/ui (19)" but should be "shadcn/ui (34)" to match the other references in the document (lines 16, 60, 70, 215).
-| **💻 UI** | AI Elements (30), shadcn/ui (19), Radix primitives | Chat/Reasoning/Canvas interfaces | +| **💻 UI** | AI Elements (30), shadcn/ui (34), Radix primitives | Chat/Reasoning/Canvas interfaces |
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (5)
AGENTS.md(4 hunks)README.md(10 hunks)app/api/chat/route.ts(1 hunks)lib/client-stream-to-ai-sdk.ts(5 hunks)lib/mastra-client.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
**/*.md
📄 CodeRabbit inference engine (.github/instructions/markdown.instructions.md)
**/*.md: Use appropriate heading levels (H2, H3, etc.) to structure markdown content. Do not use H1 headings, as these will be generated from the title. Use##for H2 and###for H3 in a hierarchical manner. Recommend restructuring if content includes H4 or higher levels.
Use bullet points (with-) or numbered lists (with1.) for lists in markdown. Indent nested lists with two spaces and ensure proper indentation and spacing.
Use fenced code blocks (triple backticks) for code snippets in markdown. Specify the language after the opening backticks for syntax highlighting (e.g.,csharp).
Use proper markdown syntax for links:[link text](URL). Ensure that link text is descriptive and URLs are valid and accessible.
Use proper markdown syntax for images:. Include a brief description of the image in the alt text for accessibility.
Use markdown tables (with|delimiters) for tabular data. Ensure proper formatting, alignment, and inclusion of headers.
Limit line length to 80 characters in markdown for readability. Use soft line breaks for long paragraphs.
Use appropriate whitespace in markdown to separate sections and improve readability. Use blank lines between sections and avoid excessive whitespace.
Include YAML front matter at the beginning of markdown files with required metadata fields:post_title,author1,post_slug,microsoft_alias,featured_image,categories(from /categories.txt),tags,ai_note,summary, andpost_date.
Files:
AGENTS.mdREADME.md
**/*.{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:
lib/client-stream-to-ai-sdk.tslib/mastra-client.tsapp/api/chat/route.ts
**/*.{js,ts}
📄 CodeRabbit inference engine (.github/instructions/next-js.instructions.md)
Use parameterized queries or an ORM to prevent SQL injection attacks.
Files:
lib/client-stream-to-ai-sdk.tslib/mastra-client.tsapp/api/chat/route.ts
**/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/api/chat/route.ts
**/app/api/**/route.{js,ts}
📄 CodeRabbit inference engine (.github/instructions/next-js.instructions.md)
**/app/api/**/route.{js,ts}: Define server-side route handlers usingroute.tsorroute.jsfiles within theapp/apidirectory.
Use Next.js API routes for serverless functions.
Always validate user input on the server-side using a validation library likezodoryup.
Use authentication middleware to protect API endpoints.
Store API keys and sensitive data in environment variables and access them on the server-side only.
Configure caching with appropriate Cache-Control headers to improve performance and reduce server load.
Enable Gzip or Brotli compression on your server to reduce the size of transferred files.
Implement rate limiting to prevent abuse of your API.
Properly encode API responses to prevent injection attacks.
Files:
app/api/chat/route.ts
{app,src/components}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use Next.js 16 App Router with React 19 for frontend development
Files:
app/api/chat/route.ts
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/api/chat/route.ts
🧬 Code graph analysis (1)
app/api/chat/route.ts (3)
app/api/completion/route.ts (1)
POST(3-12)app/api/chat-extra/route.ts (1)
POST(4-21)src/mastra/index.ts (1)
mastra(85-611)
🪛 LanguageTool
AGENTS.md
[grammar] ~125-~125: Use a hyphen to join words.
Context: .../mastra/AGENTS.md`: top-level code-agent focused docs (this file is mirrored to s...
(QB_NEW_EN_HYPHEN)
⏰ 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). (3)
- GitHub Check: Agent
- GitHub Check: Sourcery review
- GitHub Check: Codacy Security Scan
🔇 Additional comments (10)
AGENTS.md (2)
1-1: Version and metadata update looks correct.The version bump to 2.3.0 and updated timestamp align with the PR objectives and are consistent with README.md changes.
92-99: Component counts are consistent and well-documented.The updated counts (34 frontend components, 34+ tools, 38 agents) are consistent throughout the Architecture & conventions section and align with the README.md updates.
README.md (2)
1-1: Version and metadata update looks correct.The version bump to 3.3.0 and updated timestamp are consistent with the AGENTS.md changes and PR objectives.
16-16: Component counts are consistent across the main sections.The updated counts (34+ tools, 38 agents, 64 UI components) are well-aligned across the product description, comparison table, and core capabilities sections.
Also applies to: 47-47, 56-60
lib/client-stream-to-ai-sdk.ts (5)
27-33: Well-implemented type guard for ReadableStream detection.The
isReadableStreamtype guard correctly checks for the presence ofgetReadermethod, providing a reliable way to differentiate betweenReadableStreamandAsyncIterablereturn types.
35-48: Good resource management in async generator.The
asyncIterableFromReadableStreamhelper correctly releases the reader lock in thefinallyblock, preventing resource leaks even if iteration is interrupted.
90-96: Simplified streaming approach is a good improvement.The refactored single-stream call with conditional
toUIMessageStreamResponseusage is cleaner than the previous two-step approach. The early return when the native method is available avoids unnecessary transformation overhead.
122-130: Deprecated function correctly throws with guidance.The
createMastraStreamResponsedeprecation is well-handled: it throws an error with a clear migration path rather than silently failing. The JSDoc@deprecatedtag helps IDEs surface the warning.
60-60: Verify import path consistency between documentation and implementation.The example at line 60 references
@/lib/server/agent-stream, whilelib/mastra-client.ts(lines 7-8) may reference@/lib/client-stream-to-ai-sdk. Confirm these paths match the actual file structure and update documentation if paths differ.lib/mastra-client.ts (1)
3-9: The import path in the mastra-client.ts comment is correct; the inconsistency exists in lib/client-stream-to-ai-sdk.ts instead.The comment in lib/mastra-client.ts (lines 7-8) correctly directs users to import
createAgentStreamResponsefrom@/lib/client-stream-to-ai-sdk, and that function is indeed exported from that file (line 74). However, the example code in lib/client-stream-to-ai-sdk.ts (line 60) contains an incorrect import path: it shows importing from@/lib/server/agent-stream, which does not exist. The example should import from@/lib/client-stream-to-ai-sdkinstead.Likely an incorrect or invalid review comment.
| - `ui/AGENTS.md`: shadcn/ui base components (19 components) | ||
| - `ui/AGENTS.md`: shadcn/ui base components (34 components) | ||
| - `src/components/ai-elements/AGENTS.md`: AI Elements library (30 components) | ||
| - `src/mastra/AGENTS.md`: top-level code-agent focused docs (this file is mirrored to subfolders) |
There was a problem hiding this comment.
Minor grammar fix: use hyphen in compound modifier.
Per static analysis, "code-agent focused" should use a hyphen when used as a compound adjective.
-- `src/mastra/AGENTS.md`: top-level code-agent focused docs (this file is mirrored to subfolders)
+- `src/mastra/AGENTS.md`: top-level code-agent-focused docs (this file is mirrored to subfolders)📝 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.
| - `src/mastra/AGENTS.md`: top-level code-agent focused docs (this file is mirrored to subfolders) | |
| - `src/mastra/AGENTS.md`: top-level code-agent-focused docs (this file is mirrored to subfolders) |
🧰 Tools
🪛 LanguageTool
[grammar] ~125-~125: Use a hyphen to join words.
Context: .../mastra/AGENTS.md`: top-level code-agent focused docs (this file is mirrored to s...
(QB_NEW_EN_HYPHEN)
🤖 Prompt for AI Agents
In AGENTS.md around line 125, the phrase "code-agent focused" should be
corrected to the compound modifier "code-agent-focused"; update that occurrence
(and any other identical occurrences in the file) to use a hyphen so the
compound adjective is grammatically correct.
| import { mastra } from "../../../src/mastra"; | ||
| import { RuntimeContext } from "@mastra/core/runtime-context"; |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Import path uses relative path instead of alias.
The import uses "../../../src/mastra" instead of the path alias "@/src/mastra". While functional, path aliases improve readability and maintainability. The AI summary indicates this was changed from the alias to relative path.
-import { mastra } from "../../../src/mastra";
+import { mastra } from "@/src/mastra";📝 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 { mastra } from "../../../src/mastra"; | |
| import { RuntimeContext } from "@mastra/core/runtime-context"; | |
| import { mastra } from "@/src/mastra"; | |
| import { RuntimeContext } from "@mastra/core/runtime-context"; |
🤖 Prompt for AI Agents
In app/api/chat/route.ts around lines 1 to 2, the file imports mastra using a
relative path ("../../../src/mastra"); update the import to use the project path
alias (e.g. "@/src/mastra") so it reads import { mastra } from "@/src/mastra";
ensure other imports use the alias consistently and that tsconfig/next config
contains the corresponding path mapping so the build resolves the alias.
| export async function POST(req: Request) { | ||
| const body: ChatRequestBody = await req.json(); | ||
|
|
||
| // Get available agents dynamically from mastra | ||
| const agentsMap = await mastra.getAgents(); | ||
| const availableAgents = Object.keys(agentsMap); | ||
|
|
||
| // Use first available agent if none specified | ||
| const agentId = body.agentId || availableAgents[0]; | ||
|
|
||
| if (!agentId || !availableAgents.includes(agentId)) { | ||
| return Response.json( | ||
| { error: `Invalid or missing agentId. Available: ${availableAgents.join(", ")}` }, | ||
| { status: 400 } | ||
| ); | ||
| } | ||
| const { messages, data } = await req.json(); | ||
| const myAgent = mastra.getAgent("weatherAgent"); | ||
|
|
||
| if (!body.messages?.length) { | ||
| return Response.json({ error: "messages required" }, { status: 400 }); | ||
| } | ||
|
|
||
| try { | ||
| return await createAgentStreamResponse(mastra as Parameters<typeof createAgentStreamResponse>[0], agentId, body.messages, { | ||
| threadId: body.threadId, | ||
| resourceId: body.resourceId, | ||
| memory: body.memory, | ||
| maxSteps: body.maxSteps ?? 50, | ||
| }); | ||
| } catch (error) { | ||
| return Response.json( | ||
| { error: error instanceof Error ? error.message : "Stream failed" }, | ||
| { status: 500 } | ||
| ); | ||
| const runtimeContext = new RuntimeContext(); | ||
|
|
||
| if (data) { | ||
| for (const [key, value] of Object.entries(data)) { | ||
| runtimeContext.set(key, value); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| export async function GET() { | ||
| const agentsMap = await mastra.getAgents(); | ||
| const availableAgents = Object.keys(agentsMap); | ||
| return Response.json({ agents: availableAgents, count: availableAgents.length }); | ||
| } | ||
| const stream = await myAgent.stream(messages, { | ||
| runtimeContext, | ||
| format: "aisdk", | ||
| }); | ||
| return stream.toUIMessageStreamResponse(); | ||
| } No newline at end of file |
There was a problem hiding this comment.
Missing error handling for async operations.
Per coding guidelines, use try...catch blocks for handling errors in asynchronous operations. The route lacks error handling for JSON parsing, agent retrieval, and streaming failures.
export async function POST(req: Request) {
+ try {
const { messages, data } = await req.json();
const myAgent = mastra.getAgent("weatherAgent");
const runtimeContext = new RuntimeContext();
if (data) {
for (const [key, value] of Object.entries(data)) {
runtimeContext.set(key, value);
}
}
const stream = await myAgent.stream(messages, {
runtimeContext,
format: "aisdk",
});
return stream.toUIMessageStreamResponse();
+ } catch (error) {
+ console.error("Chat API error:", error);
+ return new Response(
+ JSON.stringify({ error: "Failed to process chat request" }),
+ { status: 500, headers: { "Content-Type": "application/json" } }
+ );
+ }
}🤖 Prompt for AI Agents
In app/api/chat/route.ts around lines 4 to 21, the POST handler performs
multiple asynchronous operations (req.json(), mastra.getAgent, agent.stream,
stream.toUIMessageStreamResponse) without error handling; wrap the body in a
try...catch, validate and guard req.json() output, check that myAgent exists
before using it, await and catch failures from myAgent.stream and
stream.toUIMessageStreamResponse, log the caught error for diagnostics, and
return an appropriate HTTP Response (e.g., JSON error message with a 400 or 500
status as appropriate) from the catch block so failures are surfaced to clients
instead of crashing the server.
| export async function POST(req: Request) { | ||
| const body: ChatRequestBody = await req.json(); | ||
|
|
||
| // Get available agents dynamically from mastra | ||
| const agentsMap = await mastra.getAgents(); | ||
| const availableAgents = Object.keys(agentsMap); | ||
|
|
||
| // Use first available agent if none specified | ||
| const agentId = body.agentId || availableAgents[0]; | ||
|
|
||
| if (!agentId || !availableAgents.includes(agentId)) { | ||
| return Response.json( | ||
| { error: `Invalid or missing agentId. Available: ${availableAgents.join(", ")}` }, | ||
| { status: 400 } | ||
| ); | ||
| } | ||
| const { messages, data } = await req.json(); | ||
| const myAgent = mastra.getAgent("weatherAgent"); |
There was a problem hiding this comment.
Missing input validation for request body.
As per coding guidelines, API routes should validate user input server-side using a validation library like zod or yup. The messages and data fields are destructured without validation, which could lead to runtime errors or unexpected behavior.
+import { z } from "zod";
+
+const ChatRequestSchema = z.object({
+ messages: z.array(z.object({
+ role: z.string(),
+ content: z.string(),
+ })),
+ data: z.record(z.unknown()).optional(),
+});
+
export async function POST(req: Request) {
- const { messages, data } = await req.json();
+ const body = await req.json();
+ const { messages, data } = ChatRequestSchema.parse(body);
const myAgent = mastra.getAgent("weatherAgent");📝 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.
| export async function POST(req: Request) { | |
| const body: ChatRequestBody = await req.json(); | |
| // Get available agents dynamically from mastra | |
| const agentsMap = await mastra.getAgents(); | |
| const availableAgents = Object.keys(agentsMap); | |
| // Use first available agent if none specified | |
| const agentId = body.agentId || availableAgents[0]; | |
| if (!agentId || !availableAgents.includes(agentId)) { | |
| return Response.json( | |
| { error: `Invalid or missing agentId. Available: ${availableAgents.join(", ")}` }, | |
| { status: 400 } | |
| ); | |
| } | |
| const { messages, data } = await req.json(); | |
| const myAgent = mastra.getAgent("weatherAgent"); | |
| import { z } from "zod"; | |
| const ChatRequestSchema = z.object({ | |
| messages: z.array(z.object({ | |
| role: z.string(), | |
| content: z.string(), | |
| })), | |
| data: z.record(z.unknown()).optional(), | |
| }); | |
| export async function POST(req: Request) { | |
| const body = await req.json(); | |
| const { messages, data } = ChatRequestSchema.parse(body); | |
| const myAgent = mastra.getAgent("weatherAgent"); |
🤖 Prompt for AI Agents
In app/api/chat/route.ts around lines 4 to 6, the request body is destructured
into messages and data without validation; add server-side validation (use zod
or yup) by defining a schema for the expected shape (e.g., messages as an array
of message objects and data as an optional object), parse the incoming JSON with
the schema (use safeParse/validate) and if validation fails return a 400
response with an error message; on success use the typed/validated values for
the rest of the handler to avoid runtime errors.
| ); | ||
| } | ||
| const { messages, data } = await req.json(); | ||
| const myAgent = mastra.getAgent("weatherAgent"); |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Hardcoded agent name reduces flexibility.
The agent is hardcoded to "weatherAgent". Consider accepting the agent ID from the request body or environment variable to support different agents, similar to how createAgentStreamResponse in lib/client-stream-to-ai-sdk.ts accepts agentId as a parameter.
🤖 Prompt for AI Agents
In app/api/chat/route.ts around line 6 the agent is hardcoded as "weatherAgent";
update the handler to accept an agentId (e.g., from the request body or a query
param) and pass that to mastra.getAgent instead of the literal string; validate
the incoming agentId (non-empty string), fall back to a sensible default or to
an environment variable like process.env.DEFAULT_AGENT if not provided, and
ensure any errors for unknown/missing agents are handled and logged before
proceeding.
| for await (const value of iterable) { | ||
| writer.write(value as Parameters<typeof writer.write>[0]); | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Type assertion is acceptable but consider stronger typing.
The cast value as Parameters<typeof writer.write>[0] works but is somewhat opaque. Consider defining an explicit type for the stream chunk if this pattern is used elsewhere.
🤖 Prompt for AI Agents
In lib/client-stream-to-ai-sdk.ts around lines 109 to 111, the loop casts each
iterated value with an opaque assertion (value as Parameters<typeof
writer.write>[0]); define an explicit chunk type (e.g., type StreamChunk = ...
or export an interface) that matches writer.write's parameter and use that type
for the iterable (for await (const value of iterable as
AsyncIterable<StreamChunk>)) and for writer.write(value) so the cast is removed
and the types are clear and reusable across the codebase.
Greptile OverviewGreptile SummaryThis PR updates metadata (version bumps and component counts in AGENTS.md and README.md) and refactors the chat API with streaming improvements. However, the chat API refactoring introduces critical breaking changes: Major Issues:
Improvements:
The metadata changes are safe, but the chat API refactoring appears incomplete or incorrectly simplified, breaking existing multi-agent functionality. Confidence Score: 0/5
Important Files ChangedFile Analysis
Sequence DiagramsequenceDiagram
participant Client as Frontend Client
participant API as /api/chat Route
participant Mastra as Mastra Instance
participant Agent as Weather Agent
participant RC as RuntimeContext
participant Stream as Agent Stream
Client->>API: POST /api/chat<br/>{messages, data}
API->>API: Extract messages & data
API->>Mastra: getAgent("weatherAgent")
Note over API,Mastra: ⚠️ ISSUE: Agent ID is "weather-agent"<br/>not "weatherAgent"
Mastra-->>API: Agent instance (or error)
API->>RC: new RuntimeContext()
alt data provided
loop for each key-value
API->>RC: set(key, value)
end
end
API->>Agent: stream(messages, {runtimeContext, format: "aisdk"})
Agent->>Stream: Create AI SDK stream
Stream-->>API: Stream with toUIMessageStreamResponse()
API->>Stream: toUIMessageStreamResponse()
Stream-->>Client: Response (streaming)
|
| ); | ||
| } | ||
| const { messages, data } = await req.json(); | ||
| const myAgent = mastra.getAgent("weatherAgent"); |
There was a problem hiding this comment.
logic: Agent ID mismatch - weatherAgent doesn't exist. The agent is registered with ID weather-agent (see src/mastra/agents/weather-agent.ts:18). This will cause runtime errors.
| const myAgent = mastra.getAgent("weatherAgent"); | |
| const myAgent = mastra.getAgent("weather-agent"); |
Prompt To Fix With AI
This is a comment left during a code review.
Path: app/api/chat/route.ts
Line: 6:6
Comment:
**logic:** Agent ID mismatch - `weatherAgent` doesn't exist. The agent is registered with ID `weather-agent` (see `src/mastra/agents/weather-agent.ts:18`). This will cause runtime errors.
```suggestion
const myAgent = mastra.getAgent("weather-agent");
```
How can I resolve this? If you propose a fix, please make it concise.| import { mastra } from "../../../src/mastra"; | ||
| import { RuntimeContext } from "@mastra/core/runtime-context"; | ||
|
|
||
| export async function POST(req: Request) { | ||
| const body: ChatRequestBody = await req.json(); | ||
|
|
||
| // Get available agents dynamically from mastra | ||
| const agentsMap = await mastra.getAgents(); | ||
| const availableAgents = Object.keys(agentsMap); | ||
|
|
||
| // Use first available agent if none specified | ||
| const agentId = body.agentId || availableAgents[0]; | ||
|
|
||
| if (!agentId || !availableAgents.includes(agentId)) { | ||
| return Response.json( | ||
| { error: `Invalid or missing agentId. Available: ${availableAgents.join(", ")}` }, | ||
| { status: 400 } | ||
| ); | ||
| } | ||
| const { messages, data } = await req.json(); | ||
| const myAgent = mastra.getAgent("weatherAgent"); | ||
|
|
||
| if (!body.messages?.length) { | ||
| return Response.json({ error: "messages required" }, { status: 400 }); | ||
| } | ||
|
|
||
| try { | ||
| return await createAgentStreamResponse(mastra as Parameters<typeof createAgentStreamResponse>[0], agentId, body.messages, { | ||
| threadId: body.threadId, | ||
| resourceId: body.resourceId, | ||
| memory: body.memory, | ||
| maxSteps: body.maxSteps ?? 50, | ||
| }); | ||
| } catch (error) { | ||
| return Response.json( | ||
| { error: error instanceof Error ? error.message : "Stream failed" }, | ||
| { status: 500 } | ||
| ); | ||
| const runtimeContext = new RuntimeContext(); | ||
|
|
||
| if (data) { | ||
| for (const [key, value] of Object.entries(data)) { | ||
| runtimeContext.set(key, value); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| export async function GET() { | ||
| const agentsMap = await mastra.getAgents(); | ||
| const availableAgents = Object.keys(agentsMap); | ||
| return Response.json({ agents: availableAgents, count: availableAgents.length }); | ||
| } | ||
| const stream = await myAgent.stream(messages, { | ||
| runtimeContext, | ||
| format: "aisdk", | ||
| }); | ||
| return stream.toUIMessageStreamResponse(); | ||
| } No newline at end of file |
There was a problem hiding this comment.
logic: Removed all dynamic agent selection, error handling, validation, and the GET endpoint. The previous implementation supported any agent via agentId parameter and had proper error handling. Now it only works with one hardcoded agent. Is this intentional? This breaks existing functionality for multi-agent chat.
Prompt To Fix With AI
This is a comment left during a code review.
Path: app/api/chat/route.ts
Line: 1:21
Comment:
**logic:** Removed all dynamic agent selection, error handling, validation, and the GET endpoint. The previous implementation supported any agent via `agentId` parameter and had proper error handling. Now it only works with one hardcoded agent. Is this intentional? This breaks existing functionality for multi-agent chat.
How can I resolve this? If you propose a fix, please make it concise.| { status: 400 } | ||
| ); | ||
| } | ||
| const { messages, data } = await req.json(); |
There was a problem hiding this comment.
logic: No validation for required messages field - will throw if undefined/missing from request body
Prompt To Fix With AI
This is a comment left during a code review.
Path: app/api/chat/route.ts
Line: 5:5
Comment:
**logic:** No validation for required `messages` field - will throw if undefined/missing from request body
How can I resolve this? If you propose a fix, please make it concise.| export async function POST(req: Request) { | ||
| const body: ChatRequestBody = await req.json(); | ||
|
|
||
| // Get available agents dynamically from mastra | ||
| const agentsMap = await mastra.getAgents(); | ||
| const availableAgents = Object.keys(agentsMap); | ||
|
|
||
| // Use first available agent if none specified | ||
| const agentId = body.agentId || availableAgents[0]; | ||
|
|
||
| if (!agentId || !availableAgents.includes(agentId)) { | ||
| return Response.json( | ||
| { error: `Invalid or missing agentId. Available: ${availableAgents.join(", ")}` }, | ||
| { status: 400 } | ||
| ); | ||
| } | ||
| const { messages, data } = await req.json(); | ||
| const myAgent = mastra.getAgent("weatherAgent"); | ||
|
|
||
| if (!body.messages?.length) { | ||
| return Response.json({ error: "messages required" }, { status: 400 }); | ||
| } | ||
|
|
||
| try { | ||
| return await createAgentStreamResponse(mastra as Parameters<typeof createAgentStreamResponse>[0], agentId, body.messages, { | ||
| threadId: body.threadId, | ||
| resourceId: body.resourceId, | ||
| memory: body.memory, | ||
| maxSteps: body.maxSteps ?? 50, | ||
| }); | ||
| } catch (error) { | ||
| return Response.json( | ||
| { error: error instanceof Error ? error.message : "Stream failed" }, | ||
| { status: 500 } | ||
| ); | ||
| const runtimeContext = new RuntimeContext(); | ||
|
|
||
| if (data) { | ||
| for (const [key, value] of Object.entries(data)) { | ||
| runtimeContext.set(key, value); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| export async function GET() { | ||
| const agentsMap = await mastra.getAgents(); | ||
| const availableAgents = Object.keys(agentsMap); | ||
| return Response.json({ agents: availableAgents, count: availableAgents.length }); | ||
| } | ||
| const stream = await myAgent.stream(messages, { | ||
| runtimeContext, | ||
| format: "aisdk", | ||
| }); | ||
| return stream.toUIMessageStreamResponse(); |
There was a problem hiding this comment.
logic: No try-catch error handling - unhandled exceptions will crash the API route instead of returning proper error responses
Prompt To Fix With AI
This is a comment left during a code review.
Path: app/api/chat/route.ts
Line: 4:20
Comment:
**logic:** No try-catch error handling - unhandled exceptions will crash the API route instead of returning proper error responses
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
Pull request overview
This PR updates version numbers and counts across documentation files (AGENTS.md and README.md) to reflect new features (v2.3.0/v3.3.0), and refactors the chat API to use a more direct approach with RuntimeContext. However, the refactoring introduces several critical issues, particularly the removal of dynamic agent selection and error handling.
Key Changes:
- Documentation updated to reflect 34+ tools, 38 agents, and 64 UI components (up from 30 tools, 22-25 agents, and 49 components)
- Removed re-exports from
lib/mastra-client.tsto separate client and server-side concerns - Enhanced
createAgentStreamResponseto handle both ReadableStream and AsyncIterable return types - Simplified chat API route but removed dynamic agent selection, error handling, and maxDuration config
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| AGENTS.md | Version bump to 2.3.0 and updated component/tool/agent counts |
| README.md | Version bump to 3.3.0 with updated metrics throughout the documentation |
| lib/mastra-client.ts | Removed re-exports and added documentation clarifying client vs server usage |
| lib/client-stream-to-ai-sdk.ts | Refactored to optimize stream handling, support both ReadableStream and AsyncIterable, and improve type safety |
| app/api/chat/route.ts | Simplified implementation using RuntimeContext, but hardcoded agent selection and removed error handling |
| * // app/api/chat/route.ts | ||
| * import { mastra } from "@/src/mastra"; | ||
| * import { createAgentStreamResponse } from "@/lib/client-stream-to-ai-sdk"; | ||
| * import { createAgentStreamResponse } from "@/lib/server/agent-stream"; |
There was a problem hiding this comment.
The documentation references an incorrect import path @/lib/server/agent-stream, but this function is exported from @/lib/client-stream-to-ai-sdk. The actual usage in app/api/chat/route.ts doesn't use this function at all. Update the example to match the actual implementation pattern.
| * import { createAgentStreamResponse } from "@/lib/server/agent-stream"; | |
| * import { createAgentStreamResponse } from "@/lib/client-stream-to-ai-sdk"; |
| const { messages, data } = await req.json(); | ||
| const myAgent = mastra.getAgent("weatherAgent"); |
There was a problem hiding this comment.
The chat API is hardcoded to use only "weatherAgent", removing the ability to select different agents dynamically. The previous implementation supported dynamic agent selection via agentId parameter. This is a breaking change that significantly reduces the API's flexibility and contradicts the PR description which mentions "streamline agent selection" - this completely removes it instead.
| const { messages, data } = await req.json(); | |
| const myAgent = mastra.getAgent("weatherAgent"); | |
| const { messages, data, agentId } = await req.json(); | |
| const myAgent = mastra.getAgent(agentId ?? "weatherAgent"); |
| { status: 400 } | ||
| ); | ||
| } | ||
| const { messages, data } = await req.json(); |
There was a problem hiding this comment.
Missing input validation for required fields. The code assumes messages exists but doesn't validate it, which could lead to runtime errors if the request body is malformed. Add validation to check that messages is present and is an array before processing.
| const { messages, data } = await req.json(); | |
| const { messages, data } = await req.json(); | |
| if (!Array.isArray(messages)) { | |
| return new Response( | |
| JSON.stringify({ error: "Missing or invalid 'messages' field. Must be an array." }), | |
| { status: 400, headers: { "Content-Type": "application/json" } } | |
| ); | |
| } |
| export async function POST(req: Request) { | ||
| const body: ChatRequestBody = await req.json(); | ||
|
|
||
| // Get available agents dynamically from mastra | ||
| const agentsMap = await mastra.getAgents(); | ||
| const availableAgents = Object.keys(agentsMap); | ||
|
|
||
| // Use first available agent if none specified | ||
| const agentId = body.agentId || availableAgents[0]; | ||
|
|
||
| if (!agentId || !availableAgents.includes(agentId)) { | ||
| return Response.json( | ||
| { error: `Invalid or missing agentId. Available: ${availableAgents.join(", ")}` }, | ||
| { status: 400 } | ||
| ); | ||
| } | ||
| const { messages, data } = await req.json(); | ||
| const myAgent = mastra.getAgent("weatherAgent"); | ||
|
|
||
| if (!body.messages?.length) { | ||
| return Response.json({ error: "messages required" }, { status: 400 }); | ||
| } | ||
|
|
||
| try { | ||
| return await createAgentStreamResponse(mastra as Parameters<typeof createAgentStreamResponse>[0], agentId, body.messages, { | ||
| threadId: body.threadId, | ||
| resourceId: body.resourceId, | ||
| memory: body.memory, | ||
| maxSteps: body.maxSteps ?? 50, | ||
| }); | ||
| } catch (error) { | ||
| return Response.json( | ||
| { error: error instanceof Error ? error.message : "Stream failed" }, | ||
| { status: 500 } | ||
| ); | ||
| const runtimeContext = new RuntimeContext(); | ||
|
|
||
| if (data) { | ||
| for (const [key, value] of Object.entries(data)) { | ||
| runtimeContext.set(key, value); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| export async function GET() { | ||
| const agentsMap = await mastra.getAgents(); | ||
| const availableAgents = Object.keys(agentsMap); | ||
| return Response.json({ agents: availableAgents, count: availableAgents.length }); | ||
| } | ||
| const stream = await myAgent.stream(messages, { | ||
| runtimeContext, | ||
| format: "aisdk", | ||
| }); | ||
| return stream.toUIMessageStreamResponse(); | ||
| } No newline at end of file |
There was a problem hiding this comment.
The simplified API removed error handling that was present in the previous implementation. Consider wrapping the stream call in a try-catch block to handle potential errors gracefully and return appropriate error responses to the client.
| } | ||
| import { mastra } from "../../../src/mastra"; | ||
| import { RuntimeContext } from "@mastra/core/runtime-context"; | ||
|
|
There was a problem hiding this comment.
The removed maxDuration export could cause timeout issues. The previous implementation set maxDuration = 60 which is important for Next.js API routes that need longer execution times for streaming responses. Without this, the route may timeout prematurely on platforms like Vercel.
| export const maxDuration = 60; |
| const stream = await agent.stream(messages, streamOptions) as StreamResult; | ||
|
|
||
| // Preferred: Use built-in AI SDK format when available | ||
| if (streamOptions.format === "aisdk" && stream.toUIMessageStreamResponse) { |
There was a problem hiding this comment.
The code calls agent.stream() once and stores the result, which is good. However, when format === "aisdk" but toUIMessageStreamResponse is not available, the code falls through to the manual transformation that may attempt to process an already-consumed stream. Consider checking if the stream can be reused or restructuring to avoid potential stream consumption issues.
| if (streamOptions.format === "aisdk" && stream.toUIMessageStreamResponse) { | |
| if (streamOptions.format === "aisdk" && typeof stream.toUIMessageStreamResponse === "function") { |
| /** | ||
| * Client-side Mastra SDK instance for frontend use. | ||
| * Use this in React components to interact with the Mastra API. | ||
| * | ||
| * For server-side streaming in API routes, import createAgentStreamResponse | ||
| * directly from "@/lib/client-stream-to-ai-sdk" instead. | ||
| */ |
There was a problem hiding this comment.
The comment directs users to import from @/lib/client-stream-to-ai-sdk, but this creates a confusing API surface. The previous approach of re-exporting from a single entry point was cleaner. Consider either: (1) restoring the exports for convenience, or (2) creating a separate @/lib/server directory to make the client/server distinction clearer.
Summary by Sourcery
Update chat streaming utilities and API route to better align with core Mastra types while improving streaming compatibility, and refresh project metadata to reflect current agent, tool, and UI component counts.
New Features:
Enhancements:
Documentation: