Skip to content

feat: update AGENTS and README metadata, enhance chat API#5

Merged
ssdeanx merged 1 commit intomainfrom
develop
Dec 5, 2025
Merged

feat: update AGENTS and README metadata, enhance chat API#5
ssdeanx merged 1 commit intomainfrom
develop

Conversation

@ssdeanx
Copy link
Owner

@ssdeanx ssdeanx commented Dec 5, 2025

  • 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.

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:

  • Support agent execution memory options directly via core AgentExecutionOptions in the streaming helper.
  • Allow chat streaming fallback to handle both ReadableStream and AsyncIterable agent outputs.

Enhancements:

  • Refine createAgentStreamResponse to use the core Mastra type, avoid duplicate streaming calls, and prefer built-in AI SDK responses when available.
  • Simplify the chat API route to target a specific weather agent and propagate runtime context data into agent execution.
  • Clarify separation of concerns between the frontend Mastra client and server-side streaming helper via documentation comments and exports cleanup.

Documentation:

  • Update README and AGENTS metadata versions and last updated dates, and revise counts/descriptions for tools, agents, and UI components across diagrams, tables, and resource links to reflect the expanded catalog.

- 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.
Copilot AI review requested due to automatic review settings December 5, 2025 17:44
@continue
Copy link

continue bot commented Dec 5, 2025

Keep this PR in a mergeable state →

Learn more

All Green is an AI agent that automatically:

✅ Addresses code review comments

✅ Fixes failing CI checks

✅ Resolves merge conflicts

@sourcery-ai
Copy link

sourcery-ai bot commented Dec 5, 2025

Reviewer's Guide

Refactors 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 context

sequenceDiagram
  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
Loading

Sequence diagram for createAgentStreamResponse streaming behavior

sequenceDiagram
  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
Loading

Class diagram for Mastra streaming and client usage changes

classDiagram
  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
Loading

File-Level Changes

Change Details Files
Generalize agent streaming helper to use core Mastra types and handle both ReadableStream and AsyncIterable outputs while avoiding duplicate stream invocations.
  • Replace custom MastraInstance and memory typings with core Mastra and AgentExecutionOptions["memory"] types.
  • Introduce a StreamResult helper type plus isReadableStream type guard and asyncIterableFromReadableStream adapter.
  • Call agent.stream once, reuse its result, and prefer toUIMessageStreamResponse when format is aisdk and the helper exists.
  • Fallback path now passes the single stream result through toAISdkFormat, then adapts either a ReadableStream or AsyncIterable into the AI SDK writer loop.
lib/client-stream-to-ai-sdk.ts
Simplify the chat API route to target a specific agent and pass runtime context instead of handling dynamic agent selection and GET inspection.
  • Switch mastra import to a relative path compatible with the app router and add RuntimeContext from @mastra/core/runtime-context.
  • Replace the previous body schema (agent selection, memory, thread metadata, error handling) with a minimal messages + data payload.
  • Instantiate a concrete weatherAgent via mastra.getAgent, build a RuntimeContext from the request data entries, and invoke agent.stream with runtimeContext and aisdk format, returning toUIMessageStreamResponse().
  • Remove the GET endpoint that listed available agents.
app/api/chat/route.ts
Clarify separation of frontend Mastra client usage from server-side streaming utilities.
  • Add JSDoc explaining mastraClient as the client-side SDK for React usage and directing server-side streaming to the server helper instead.
  • Remove re-exports of createAgentStreamResponse and StreamToAISdkOptions from mastra-client to avoid server utilities leaking into client bundle.
lib/mastra-client.ts
Refresh documentation metadata and capability counts to reflect new versions, tool/agent/component counts, and architecture details.
  • Bump README AGENTS-META version and last_updated fields, and increase counts for enterprise tools, agents, and UI components across the tagline, feature bullets, comparison table, diagrams, and structure sections.
  • Update resource links and roadmap bullets to reference the new counts for UI components, agents, and tools.
  • Update root AGENTS.md AGENTS-META version/last_updated plus descriptive text for frontend components, tools, and agents counts, and adjust references to sub-AGENTS files accordingly.
README.md
AGENTS.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai
Copy link

coderabbitai bot commented Dec 5, 2025

Summary by CodeRabbit

Release Notes

  • New Features

    • Expanded agent library from 22+ to 38 agents
    • Increased available tools from 30+ to 34+
    • Enhanced UI component library from 49 to 64 components (including 34 new base primitives)
  • Chores

    • Version bumped to v2.3.0 and v3.3.0
    • Updated documentation to reflect expanded platform capabilities

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

Walkthrough

Version 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

Cohort / File(s) Summary
Documentation Updates
AGENTS.md, README.md
Version bumps and component/agent/tool counts updated across metadata and product descriptions to reflect expanded scope (34 UI components, 38 agents, 34+ tools). Last updated timestamps refreshed.
API Route Refactoring
app/api/chat/route.ts
Replaced dynamic agent selection with fixed weather agent retrieval. Introduced RuntimeContext for data injection. Removed public exports (maxDuration, ChatRequestBody), GET handler, and createAgentStreamResponse dependency. Simplified POST logic with mastra.getAgent("weatherAgent") and stream-based response.
Stream Handling Refactor
lib/client-stream-to-ai-sdk.ts
Changed mastra parameter type from MastraInstance to Mastra. Updated memory field type to AgentExecutionOptions["memory"]. Refactored stream handling to single initial agent.stream call with fallback transformation path. Added isReadableStream type guard and asyncIterableFromReadableStream helper for uniform stream/async-iterable handling.
Client Configuration
lib/mastra-client.ts
Added client-side documentation. Expanded MastraClient instantiation with backoffMs, maxBackoffMs, and abortSignal options. Removed public exports of createAgentStreamResponse and StreamToAISdkOptions.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50–65 minutes

  • lib/client-stream-to-ai-sdk.ts: Dense refactoring with type signature changes, stream abstraction layer, and fallback transformation logic requiring careful verification of backward compatibility.
  • app/api/chat/route.ts: Behavioral shift from dynamic to fixed agent selection; verify that simplified POST logic maintains intended functionality and that removed exports are not used elsewhere.
  • Public API changes: Type changes (Mastra vs. MastraInstance) and memory field type redefinition should be checked for downstream impact.
  • Export removals: Confirm createAgentStreamResponse removal does not break dependents and lib/mastra-client.ts correctly surfaces remaining APIs.

Poem

🐰 Thirty-four components now dance in the light,
Thirty-eight agents ready to take flight,
Streams flow simpler, weather shines bright,
RuntimeContext injects what's just right,
Version bumps hop—the code feels so tight! 🚀

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately captures the main changes: metadata updates (AGENTS and README) and chat API enhancements align with the comprehensive refactoring across multiple files.
Description check ✅ Passed The description comprehensively covers all major changes including metadata updates, chat API refactoring, streaming function enhancements, and documentation improvements, with good alignment to the actual changeset.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch develop

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions
Copy link

github-actions bot commented Dec 5, 2025

🤖 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.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @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

  • Documentation Updates: The AGENTS.md and README.md files have been updated to reflect new version numbers (2.3.0 and 3.3.0 respectively) and increased counts for enterprise tools (34+), specialized agents (38), and UI components (64), ensuring the project's capabilities are accurately represented.
  • Chat API Refactoring: The app/api/chat/route.ts has undergone a significant refactoring, moving from dynamic agent selection to directly using a specific agent (weatherAgent) and incorporating RuntimeContext for more streamlined context handling during agent execution.
  • Stream Response Enhancement: The createAgentStreamResponse utility in lib/client-stream-to-ai-sdk.ts has been improved to handle various stream types more robustly, supporting new agent execution options and ensuring optimal streaming response handling.
  • Mastra Client Documentation: JSDoc comments have been added to the mastraClient in lib/mastra-client.ts to clearly define its purpose for frontend interactions and differentiate its use from server-side streaming mechanisms.
Using Gemini Code Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey there - I've reviewed your changes - here's some feedback:

  • 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.
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.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@github-actions
Copy link

github-actions bot commented Dec 5, 2025

🤖 I'm sorry @ssdeanx, but I was unable to process your request. Please see the logs for more details.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

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.

Comment on lines +1 to 3
import { mastra } from "../../../src/mastra";
import { RuntimeContext } from "@mastra/core/runtime-context";

Copy link
Contributor

Choose a reason for hiding this comment

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

high

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;

Comment on lines 4 to +21
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
Copy link
Contributor

Choose a reason for hiding this comment

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

high

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();
}

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 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: undefined is redundant.

The retry configuration with backoffMs and maxBackoffMs is a sensible addition for resilience. However, abortSignal: undefined has 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

📥 Commits

Reviewing files that changed from the base of the PR and between d729737 and 27d8e92.

📒 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 (with 1.) 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: ![alt text](image URL). 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, and post_date.

Files:

  • AGENTS.md
  • README.md
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.github/instructions/next-js.instructions.md)

**/*.{js,jsx,ts,tsx}: Use next/dynamic for dynamic imports to load components only when needed, improving initial load time.
Use next/image component 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.
Use react-hook-form for 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 use setState or hooks to update state instead of mutating state directly.
Include a complete dependency array in useEffect hooks to prevent unexpected behavior.
Avoid writing server-side code in client components to prevent exposing secrets or causing unexpected behavior.
Use try...catch blocks for handling errors in asynchronous operations.
Implement error boundary components using getDerivedStateFromError or componentDidCatch lifecycle 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 in useEffect hooks 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.ts
  • lib/mastra-client.ts
  • app/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.ts
  • lib/mastra-client.ts
  • app/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 the pages/ 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 using route.ts or route.js files within the app/api directory.
Use Next.js API routes for serverless functions.
Always validate user input on the server-side using a validation library like zod or yup.
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 isReadableStream type guard correctly checks for the presence of getReader method, providing a reliable way to differentiate between ReadableStream and AsyncIterable return types.


35-48: Good resource management in async generator.

The asyncIterableFromReadableStream helper correctly releases the reader lock in the finally block, preventing resource leaks even if iteration is interrupted.


90-96: Simplified streaming approach is a good improvement.

The refactored single-stream call with conditional toUIMessageStreamResponse usage 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 createMastraStreamResponse deprecation is well-handled: it throws an error with a clear migration path rather than silently failing. The JSDoc @deprecated tag 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, while lib/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 createAgentStreamResponse from @/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-sdk instead.

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)
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

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.

Suggested change
- `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.

Comment on lines +1 to +2
import { mastra } from "../../../src/mastra";
import { RuntimeContext } from "@mastra/core/runtime-context";
Copy link

Choose a reason for hiding this comment

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

🧹 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.

Suggested change
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.

Comment on lines 4 to +21
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
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

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.

Comment on lines 4 to +6
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");
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

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.

Suggested change
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");
Copy link

Choose a reason for hiding this comment

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

🧹 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.

Comment on lines +109 to 111
for await (const value of iterable) {
writer.write(value as Parameters<typeof writer.write>[0]);
}
Copy link

Choose a reason for hiding this comment

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

🧹 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-apps
Copy link

greptile-apps bot commented Dec 5, 2025

Greptile Overview

Greptile Summary

This 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:

  • The chat route now hardcodes agent ID as "weatherAgent" but the actual agent is registered with ID "weather-agent" (app/api/chat/route.ts:6). This will cause immediate runtime failures.
  • Removed dynamic agent selection that previously supported any agent via agentId parameter
  • Removed all error handling (no try-catch blocks)
  • Removed input validation for required messages field
  • Removed the GET endpoint that listed available agents

Improvements:

  • lib/client-stream-to-ai-sdk.ts was enhanced with better type handling for ReadableStream and AsyncIterable, plus stream optimization to prevent duplicate calls
  • lib/mastra-client.ts documentation clarified client vs server-side usage

The metadata changes are safe, but the chat API refactoring appears incomplete or incorrectly simplified, breaking existing multi-agent functionality.

Confidence Score: 0/5

  • This PR contains critical runtime errors that will cause immediate failures in production
  • Score reflects multiple critical issues in app/api/chat/route.ts: incorrect hardcoded agent ID that doesn't match the registered agent (weatherAgent vs weather-agent), complete removal of error handling and validation, and loss of multi-agent functionality without apparent justification. The agent ID mismatch alone will crash the API on every request.
  • app/api/chat/route.ts requires immediate attention - contains agent ID mismatch and missing error handling that will cause runtime failures

Important Files Changed

File Analysis

Filename Score Overview
AGENTS.md 5/5 Updated version to 2.3.0 and component counts (34+ tools, 38 agents, 64 UI components) - metadata only
README.md 5/5 Updated version to 3.3.0 and component counts (34+ tools, 38 agents, 64 UI components) - metadata only
app/api/chat/route.ts 0/5 BREAKING: Hardcoded wrong agent ID (weatherAgent vs weather-agent), removed dynamic agent selection, validation, error handling, and GET endpoint
lib/client-stream-to-ai-sdk.ts 4/5 Optimized stream handling to call agent.stream once, added ReadableStream/AsyncIterable type guards, improved TypeScript types
lib/mastra-client.ts 5/5 Added documentation clarifying client vs server usage, removed re-exports to prevent confusion

Sequence Diagram

sequenceDiagram
    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)
Loading

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

5 files reviewed, 4 comments

Edit Code Review Agent Settings | Greptile

);
}
const { messages, data } = await req.json();
const myAgent = mastra.getAgent("weatherAgent");
Copy link

Choose a reason for hiding this comment

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

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.

Suggested change
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.

Comment on lines +1 to +21
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
Copy link

Choose a reason for hiding this comment

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

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();
Copy link

Choose a reason for hiding this comment

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

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.

Comment on lines 4 to +20
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();
Copy link

Choose a reason for hiding this comment

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

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.

@ssdeanx ssdeanx merged commit cefa8f1 into main Dec 5, 2025
116 of 118 checks passed
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR 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.ts to separate client and server-side concerns
  • Enhanced createAgentStreamResponse to 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";
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

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

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.

Suggested change
* import { createAgentStreamResponse } from "@/lib/server/agent-stream";
* import { createAgentStreamResponse } from "@/lib/client-stream-to-ai-sdk";

Copilot uses AI. Check for mistakes.
Comment on lines +5 to +6
const { messages, data } = await req.json();
const myAgent = mastra.getAgent("weatherAgent");
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

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

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.

Suggested change
const { messages, data } = await req.json();
const myAgent = mastra.getAgent("weatherAgent");
const { messages, data, agentId } = await req.json();
const myAgent = mastra.getAgent(agentId ?? "weatherAgent");

Copilot uses AI. Check for mistakes.
{ status: 400 }
);
}
const { messages, data } = await req.json();
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

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

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.

Suggested change
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" } }
);
}

Copilot uses AI. Check for mistakes.
Comment on lines 4 to +21
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
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
}
import { mastra } from "../../../src/mastra";
import { RuntimeContext } from "@mastra/core/runtime-context";

Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

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

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.

Suggested change
export const maxDuration = 60;

Copilot uses AI. Check for mistakes.
const stream = await agent.stream(messages, streamOptions) as StreamResult;

// Preferred: Use built-in AI SDK format when available
if (streamOptions.format === "aisdk" && stream.toUIMessageStreamResponse) {
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

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

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.

Suggested change
if (streamOptions.format === "aisdk" && stream.toUIMessageStreamResponse) {
if (streamOptions.format === "aisdk" && typeof stream.toUIMessageStreamResponse === "function") {

Copilot uses AI. Check for mistakes.
Comment on lines +3 to +9
/**
* 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.
*/
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant