Skip to content

Develop#52

Merged
ssdeanx merged 2 commits intomainfrom
develop
Dec 14, 2025
Merged

Develop#52
ssdeanx merged 2 commits intomainfrom
develop

Conversation

@ssdeanx
Copy link
Owner

@ssdeanx ssdeanx commented Dec 14, 2025

No description provided.

- Deleted the following test files as they are no longer needed:
  - `src/mastra/tools/tests/serpapi-news-trends.tool.test.ts`
  - `src/mastra/tools/tests/serpapi-search.tool.test.ts`
  - `src/mastra/tools/tests/serpapi-shopping.tool.test.ts`
  - `src/mastra/tools/tests/weather-tool.test.ts`
  - `src/mastra/tools/tests/web-scraper-tool.test.ts`

- Added a new task documentation file `memory-bank/tasks/TASK001-update-2025-12-14.md` detailing updates made to align tools with the streaming and progress convention:
  - Replaced `data-tool-agent` messages with `data-tool-progress` in various tools.
  - Normalized nested-agent streaming patterns across tools.
  - Updated financial chart tools to use the new streaming pattern.
  - Updated client-side parsers to handle legacy `data-tool-agent` parts.
  - Documented changes in `src/mastra/tools/AGENTS.md`.
  - Noted that tests will be added to verify progress events and streaming behavior.
- Updated access control enforcement in tools and workflows to use `RequestContext` and agent-specific runtime context types.
- Added optional fields `userId` and `researchPhase` to `ResearchRuntimeContext` for improved context handling.
- Imported new agents: `calendarAgent`, `bgColorAgent`, and `danePackagePublisher` into the main index.
- Implemented a new tool `colorChangeTool` to change the background color with a defined input schema.
Copilot AI review requested due to automatic review settings December 14, 2025 07:10
@continue
Copy link

continue bot commented Dec 14, 2025

All Green - Keep your PRs mergeable

Learn more

All Green is an AI agent that automatically:

✅ Addresses code review comments

✅ Fixes failing CI checks

✅ Resolves merge conflicts

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.

Sorry @ssdeanx, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@coderabbitai
Copy link

coderabbitai bot commented Dec 14, 2025

Summary by CodeRabbit

  • New Features

    • Three new utility agents now available: calendar, background color, and package publisher agents.
    • Added color-change tool for dynamic background customization.
    • Enhanced streaming support for agent-based tools with improved progress event tracking.
  • Improvements

    • Better error handling and progress notifications during tool execution.
    • Document processing enhanced with embedding and metadata filtering capabilities.
    • Improved agent availability fallbacks and runtime context handling.
  • Documentation

    • Added comprehensive guidance for tool streaming and progress events.
    • Updated agent documentation with context management best practices.

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

Walkthrough

This PR refactors tool progress event handling across the Mastra framework. It normalizes legacy event data into standardized progress events, adds streaming support to multiple tools with proper progress tracking, registers new agents, updates provider contexts to normalize legacy events, and removes legacy test files. Documentation and ESLint configurations are updated to align with new streaming conventions.

Changes

Cohort / File(s) Change Summary
Chat Context API
app/chat/providers/chat-context.tsx
Renamed second parameter of sendMessage from _files to files in ChatContextValue interface; removes underscore prefix convention.
Provider Event Normalization
app/networks/providers/network-context.tsx
app/workflows/providers/workflow-context.tsx
Normalized legacy data-tool-agent and data-tool-workflow events by extracting message text from multiple fields, deriving stage from original type, and validating status before emitting progress events; added agentId extraction where available.
ESLint Configuration
eslint.config.js
Removed underscore ignore patterns (argsIgnorePattern, varsIgnorePattern) from unused variable rules, changing how underscore-prefixed unused variables are reported.
Documentation & Memory Bank
memory-bank/copilot-rules.md
memory-bank/memory-bank-instructions.md
memory-bank/tasks/TASK001-tool-streaming.md
memory-bank/tasks/TASK001-update-2025-12-14.md
Added "Tool Streaming & Progress Events" guidance with standardized patterns for agent streaming, MastraModelOutput usage, progress event emission (start/in-progress/done), and references to TASK001 documentation for implementation details.
Agent Core & Setup
src/mastra/index.ts
Registered new agents (calendarAgent, bgColorAgent, danePackagePublisher); added RequestContext-based middleware to populate context from request headers (temperature-unit, userId, user-tier, language, researchPhase) and timing logger.
Research Agent
src/mastra/agents/researchAgent.ts
Extended ResearchRuntimeContext with optional userId and researchPhase fields; changed Pro tier model from googleAI to 'google/gemini-2.5-flash-preview-09-2025'.
Documentation
src/mastra/AGENTS.md
src/mastra/tools/AGENTS.md
Updated guidance to prefer per-request or agent-specific contexts over RuntimeContext; added progress event example interpolation and TASK001 memory-bank reference; updated changelog for 2.4.0 (Custom Agent nest events).
New Tool
src/mastra/tools/color-change-tool.ts
Added new colorChangeTool that updates CSS variable --background on document body; includes changeBgColor() helper function.
Tool Streaming Enhancements
src/mastra/tools/copywriter-agent-tool.ts
src/mastra/tools/editor-agent-tool.ts
src/mastra/tools/evaluateResultTool.ts
src/mastra/tools/extractLearningsTool.ts
src/mastra/tools/financial-chart-tools.ts
Added streaming support via agent.stream() with fallback to agent.generate(), piped textStream/fullStream to writer, extracted content from stream.object or parsed stream.text; emitted progress events (start/in-progress/done) with status and message; added error handling and tracing span completion via finally blocks.
Document Chunking Tool
src/mastra/tools/document-chunking.tool.ts
Added metadata sanitization (sanitizeMetadata) and weight normalization (normalizeWeights); extended schemas with embeddingModel, embeddingBatchSize, and filter/include options; refactored embedding generation to use batched ModelRouterEmbeddingModel with error fallback and PgVector storage with stable chunk IDs.
Test Removals
src/mastra/tools/tests/*.test.ts
Removed 16 test files covering copywriter-agent, csv-to-json, data-file-manager, data-validator, document-chunking, editor-agent, evaluateResult, extractLearnings, json-to-csv, serpapi-academic-local, serpapi-news-trends, serpapi-search, serpapi-shopping, weather, and web-scraper tools; no production code changed.

Sequence Diagram

sequenceDiagram
    actor User
    participant ToolRuntime as Tool Runtime
    participant Agent as Agent<br/>(runtime or imported)
    participant Writer as Writer/<br/>Progress Events
    participant Client as Client UI

    User->>ToolRuntime: Execute tool with input
    ToolRuntime->>ToolRuntime: Emit progress event<br/>(start)
    ToolRuntime->>Agent: Resolve agent<br/>(mastra.getAgent ∣∣ fallback)
    alt Agent has stream()
        ToolRuntime->>Agent: Invoke agent.stream(prompt)
        Agent-->>ToolRuntime: MastraModelOutput
        ToolRuntime->>Writer: Pipe textStream/fullStream
        Writer-->>Client: Stream chunks to UI
        ToolRuntime->>ToolRuntime: Extract text/object<br/>from stream
    else Agent has generate() only
        ToolRuntime->>Agent: Invoke agent.generate(prompt)
        Agent-->>ToolRuntime: Response
        ToolRuntime->>ToolRuntime: Parse response.object<br/>or response.text
    end
    ToolRuntime->>ToolRuntime: Emit progress event<br/>(in-progress/done)
    ToolRuntime->>Writer: Custom event with<br/>status, message, stage
    Writer-->>Client: Progress update to UI
    ToolRuntime-->>User: Return structured result
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Areas requiring extra attention:

  • Provider context normalization logic (network-context.tsx, workflow-context.tsx): Verify correctness of field extraction from legacy event data (text vs. message, stage derivation) and that progress event emission guards are applied consistently.
  • Streaming implementation pattern consistency (multiple tools): Confirm that all refactored tools follow identical fallback logic (stream → generate), error handling, and progress event emission patterns; check span completion in finally blocks.
  • Document chunking embedding changes (document-chunking.tool.ts): Review batched embedding logic, metadata sanitization, chunk ID generation, and PgVector upsert flow for correctness.
  • Test removals justification: Verify that removed test coverage is addressed elsewhere or intentionally deferred (per TASK001 notes).

Possibly Related PRs

Poem

🐰 Hops through the streams of flowing code,
Progress events light the dev's load,
Chunks and chunks and colors too,
Legacy ghosts are made anew—
Tests take rest, the path runs clear,
AgentStack's spring is finally here! 🌿✨

Pre-merge checks and finishing touches

❌ Failed checks (3 warnings)
Check name Status Explanation Resolution
Title check ⚠️ Warning The title 'Develop' is too vague and does not describe the actual changes in the pull request, which involve significant refactoring of agent streaming, progress events, ESLint rules, and tool implementations. Use a descriptive title that summarizes the main changes, such as 'Refactor agent streaming with progress events and normalize legacy tool agents' or similar.
Description check ⚠️ Warning No pull request description was provided by the author, making it impossible to understand the intent and scope of these extensive changes. Add a comprehensive description explaining the objectives, changes made, and any migration notes or breaking changes for reviewers and future maintainers.
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✨ 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

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

@github-actions
Copy link

🤖 I'm sorry @ssdeanx, but I was unable to process your request. Please see 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 introduces significant architectural improvements to the agent and tool ecosystem, focusing on standardizing how agents stream information and report progress. It refines core functionalities like document processing and context management, making the system more robust and extensible. The changes also reflect an updated approach to development guidelines and potentially testing practices.

Highlights

  • Standardized Agent Streaming & Progress Events: Refactored multiple tools (Copywriter, Editor, Evaluation, Learning Extraction, Financial Chart tools) to adopt a consistent streaming pattern for nested agent calls. This includes preferring runtime agent instances, piping textStream or fullStream to the tool writer, and emitting standardized data-tool-progress events with detailed status messages.
  • Enhanced Document Chunking & Reranking: Improved the document chunking tool with batched embedding generation, error handling for embeddings, and more robust vector storage with index creation and metadata sanitization. The reranking tool now supports configurable embedding models, metadata filtering, and normalized weights.
  • Dynamic Request Context Middleware: Introduced a new middleware in the main Mastra instance to dynamically populate RequestContext with values derived from request headers, such as country, user ID, user tier, language, and research phase, providing richer context to agents and tools.
  • New Tool & Agent Integrations: Added a new colorChangeTool for dynamic UI adjustments and integrated calendarAgent, bgColorAgent, and danePackagePublisher into the Mastra framework.
  • Stricter Linting Rules: Updated eslint.config.js to enforce stricter no-unused-vars rules by removing ignore patterns, promoting cleaner code.
  • Documentation & Task Tracking: Added new documentation (memory-bank/copilot-rules.md, memory-bank/memory-bank-instructions.md, memory-bank/tasks/TASK001-update-2025-12-14.md) to outline and track the new streaming and progress event conventions across tools.
  • Test File Removal: Numerous test files within src/mastra/tools/tests/ were removed, indicating a potential shift in the project's testing strategy or framework.
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
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 introduces a significant and valuable refactoring to standardize tool streaming and progress events across the application. The changes improve consistency and align with modern agent interaction patterns. The code quality is high, with many tools being updated to a more robust and readable standard. However, there is a critical issue that must be addressed: a large number of test files have been removed. Given the scale of the refactoring, this introduces significant risk. The tests must be restored or rewritten to ensure the stability and correctness of the new implementations before this PR can be merged. I have also included a few minor suggestions to improve code readability in some of the more complex new logic.

I am having trouble creating individual review comments. Click here to see my feedback.

app/chat/providers/chat-context.tsx (324)

medium

The files parameter is declared but never used within the sendMessage function. The recent ESLint configuration change will now flag this as a warning. If this parameter is not intended to be used, it should be removed to keep the function signature clean.

    (text: string) => {

app/networks/providers/network-context.tsx (304-308)

medium

This long chain of ternary operators to determine the msg value is difficult to read and maintain. Consider refactoring this logic into a helper function or a series of if statements to improve clarity. This would make it easier to understand the priority of fields (dataObj.text, dataObj.message, etc.) and to modify the logic in the future.

app/networks/providers/network-context.tsx (310)

medium

Similar to the msg variable, this nested ternary for determining the stage is complex and reduces readability. Refactoring this into a more straightforward conditional structure would make the code easier to follow.

app/workflows/providers/workflow-context.tsx (327)

medium

This chain of ternary operators for assigning the msg variable is complex and hard to read. To improve maintainability and clarity, please consider refactoring this into a small helper function or a series of if/else statements. This would make the logic for selecting the message source more explicit.

src/mastra/index.ts (483-488)

medium

The checks authHeader !== null && authHeader !== '' and userId !== null && userId !== '' are slightly redundant. Since authHeader is initialized with ?? '', it will never be null. A simple truthiness check would be more concise and achieve the same result.

          if (!userId && authHeader?.startsWith('Bearer ')) {
            const token = authHeader.slice('Bearer '.length)
            const exec = /user:([^;\s]+)/.exec(token)
            if (exec) { userId = exec[1] }
          }
          if (userId) { requestContext.set('userId', userId) }

src/mastra/tools/AGENTS.md (105)

medium

There appears to be a typo in the example code block. The line ends with ....,`, which includes an extra comma and backtick.

    message: "Descriptive progress message ${inputData.context}....",

src/mastra/tools/document-chunking.tool.ts (341-347)

medium

The duplicated span.end() call and its comment have been removed. This is a good cleanup. However, it's even better to ensure span.end() is called in all circumstances by using a finally block. I see this has been correctly implemented later in the file (lines 409-411), which is excellent practice!

src/mastra/tools/document-chunking.tool.ts (886)

medium

This expression to safely access the text from metadata is a bit complex. It can be simplified to be more readable while achieving the same goal of providing an empty string as a fallback.

          text: String(result.metadata?.text ?? ''),

src/mastra/tools/financial-chart-tools.ts (338)

medium

The use of the nullish coalescing operator (??) here is more concise and idiomatic than the previous !== undefined check. This is a good improvement for code readability.

@greptile-apps
Copy link

greptile-apps bot commented Dec 14, 2025

Greptile Overview

Greptile Summary

This PR implements a comprehensive refactoring of the agent tool streaming architecture and adds new middleware for request context management.

Key Changes

  • Streaming Architecture Standardization: Refactored 7+ agent tools (copywriterTool, editorTool, evaluateResultTool, extractLearningsTool, and all financial chart tools) to use the nested-agent streaming pattern with MastraModelOutput types. Tools now properly pipe agent streams (textStream or fullStream) to the context writer for real-time UI updates.

  • Progress Event Convention: Replaced legacy data-tool-agent events with standardized data-tool-progress events across all tools. Events now follow the convention: { type: "data-tool-progress", data: { status: "in-progress" | "done", message: string, stage: string }, id: string }.

  • Request Context Middleware: Added middleware in src/mastra/index.ts that extracts user context from HTTP headers (CF-IPCountry, Authorization, x-user-id, x-user-tier, accept-language) and populates RequestContext for agent/tool consumption. Includes temperature unit localization, user tier detection, and language preference.

  • Document Processing Enhancements: document-chunking.tool.ts received significant improvements including metadata sanitization (removes keys with $ or .), weight normalization for reranking, configurable embedding models/batch sizes, and proper error handling with batched embedding operations.

  • Legacy Event Compatibility: Frontend providers (network-context.tsx, workflow-context.tsx) now normalize legacy data-tool-agent and data-tool-workflow events into the new data-tool-progress format for backward compatibility.

  • Test Cleanup: Removed 4,585 lines of test files across the tools directory (likely outdated or being restructured).

Issues Found

  • Token parsing in middleware uses regex without length validation (potential ReDoS)
  • Markdown chunking strategy has incorrect property name (sections should be headers)
  • Minor typo in truncation marker (AAAA... should be ...)

The refactoring follows Mastra's nested-agent-streaming pattern consistently and aligns with the project's AGENTS.md guidelines.

Confidence Score: 4/5

  • This PR is safe to merge with minor issues that should be addressed
  • The refactoring follows consistent patterns and improves the codebase architecture significantly. The streaming implementation is well-structured with proper error handling. However, there are a few issues: (1) token parsing without length validation could cause performance problems, (2) property name mismatch in document chunking could cause runtime errors, and (3) massive test deletion without replacement raises concerns about test coverage.
  • Pay special attention to src/mastra/index.ts (token parsing security) and src/mastra/tools/document-chunking.tool.ts (property name fix needed)

Important Files Changed

File Analysis

Filename Score Overview
src/mastra/index.ts 4/5 Added new agents (calendarAgent, bgColorAgent, danePackagePublisher) and comprehensive request middleware for user context extraction from headers. Middleware extracts user-tier, temperature-unit, language, and userId from Cloudflare and custom headers.
src/mastra/tools/copywriter-agent-tool.ts 4/5 Refactored to use proper nested-agent streaming pattern with MastraModelOutput types. Improved agent validation, replaced legacy data-tool-agent events with data-tool-progress events following new conventions.
src/mastra/tools/editor-agent-tool.ts 5/5 Upgraded to nested-agent streaming pattern with proper MastraModelOutput typing, streams piped to writer for real-time UI updates. Replaced custom events with standardized data-tool-progress format.
src/mastra/tools/document-chunking.tool.ts 3/5 Major enhancements: added metadata sanitization, weight normalization, configurable embedding model/batch size, and improved error handling. Fixed span lifecycle (moved to finally block). Uses ModelRouterEmbeddingModel and ModelRouterLanguageModel for reranking.
src/mastra/tools/evaluateResultTool.ts 4/5 Refactored to use nested-agent streaming pattern with proper error handling and MastraModelOutput types. Added comprehensive progress events and improved agent null-safety checks.
src/mastra/tools/extractLearningsTool.ts 4/5 Complete rewrite with nested-agent streaming support, null-safe data access, and standardized progress events. Added explicit mastra instance validation and improved error handling.
src/mastra/tools/financial-chart-tools.ts 4/5 Updated all four chart tools (supervisor, generator, processor, advisor) to use MastraModelOutput streaming pattern with proper type safety. Added agent capability validation and direct imports as fallbacks.

Sequence Diagram

sequenceDiagram
    participant Client as Frontend UI
    participant Mastra as Mastra Runtime
    participant Tool as Agent Tool
    participant Agent as Nested Agent
    participant Writer as Stream Writer
    
    Client->>Mastra: POST /chat with message
    Mastra->>Mastra: Apply middleware (extract user context from headers)
    Note over Mastra: Extract userId, user-tier, language, temperature-unit
    Mastra->>Tool: Execute tool (e.g. copywriterTool)
    Tool->>Writer: Emit progress: "in-progress" - Starting agent
    Tool->>Mastra: Get agent instance via context.mastra.getAgent()
    Mastra-->>Tool: Return agent or fallback to import
    Tool->>Agent: Call agent.stream(prompt)
    Agent-->>Tool: Return MastraModelOutput stream
    Tool->>Writer: Emit progress: "in-progress" - Streaming from agent
    Tool->>Writer: Pipe stream.textStream or stream.fullStream
    Writer->>Client: Stream nested agent chunks (text-delta, reasoning-delta)
    Agent-->>Tool: Stream completes with text/object
    Tool->>Tool: Parse response (JSON or text)
    Tool->>Writer: Emit progress: "done" - Operation complete
    Tool-->>Mastra: Return tool result
    Mastra->>Client: Stream complete with final result
    
    Note over Client,Writer: Legacy Event Normalization
    Client->>Client: Normalize data-tool-agent → data-tool-progress
    Client->>Client: Display progress events in UI
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.

34 files reviewed, 3 comments

Edit Code Review Agent Settings | Greptile

Comment on lines 528 to 530
return {
strategy: 'html' as const,
...baseParams,
Copy link

Choose a reason for hiding this comment

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

syntax: mismatch in property name: headers should be used instead of sections for markdown strategy

Suggested change
return {
strategy: 'html' as const,
...baseParams,
headers: [
['#', 'title'],
['##', 'section'],
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/mastra/tools/document-chunking.tool.ts
Line: 528:530

Comment:
**syntax:** mismatch in property name: `headers` should be used instead of `sections` for markdown strategy

```suggestion
              headers: [
                ['#', 'title'],
                ['##', 'section'],
```

How can I resolve this? If you propose a fix, please make it concise.

await writer?.custom({ type: 'data-tool-progress', data: { status: 'in-progress', message: '🤖 Generating insights with learning agent', stage: 'extract-learnings' }, id: 'extract-learnings' });

const truncatedContent = (result?.content ?? '').slice(0, 8000);
const contentWithTruncation = (result?.content ?? '').length > 8000 ? truncatedContent + 'AAAA...' : truncatedContent;
Copy link

Choose a reason for hiding this comment

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

style: typo in truncation marker - should be three dots or ellipsis

Suggested change
const contentWithTruncation = (result?.content ?? '').length > 8000 ? truncatedContent + 'AAAA...' : truncatedContent;
const contentWithTruncation = (result?.content ?? '').length > 8000 ? truncatedContent + '...' : truncatedContent;
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/mastra/tools/extractLearningsTool.ts
Line: 55:55

Comment:
**style:** typo in truncation marker - should be three dots or ellipsis

```suggestion
      const contentWithTruncation = (result?.content ?? '').length > 8000 ? truncatedContent + '...' : truncatedContent;
```

How can I resolve this? If you propose a fix, please make it concise.

Comment on lines +487 to +489
}
if (userId !== null && userId !== '') { requestContext.set('userId', userId) }

Copy link

Choose a reason for hiding this comment

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

logic: regex on untrusted bearer tokens without length validation could cause performance issues - add token length check before regex execution

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/mastra/index.ts
Line: 487:489

Comment:
**logic:** regex on untrusted bearer tokens without length validation could cause performance issues - add token length check before regex execution

How can I resolve this? If you propose a fix, please make it concise.

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

Caution

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

⚠️ Outside diff range comments (7)
app/workflows/providers/workflow-context.tsx (1)

322-340: Consider refactoring complex message extraction logic.

The normalization of legacy data-tool-agent events works correctly and provides good backward compatibility. However, the message extraction logic on line 327 is quite complex with multiple fallbacks and type assertions, making it difficult to read and maintain.

Consider extracting this into a helper function for clarity:

// Helper function at the top of the file or in a utils module
function extractAgentMessage(eventData: Record<string, unknown> | undefined): string {
  if (!eventData) {
    return 'Agent executing tool'
  }
  
  const dataObj = eventData.data as Record<string, unknown> | undefined
  
  // Check nested data object first
  if (typeof dataObj?.text === 'string') {
    return dataObj.text
  }
  if (typeof dataObj?.message === 'string') {
    return dataObj.message
  }
  
  // Fallback to top-level message
  if (typeof eventData.message === 'string') {
    return eventData.message
  }
  
  return 'Agent executing tool'
}

function extractStage(eventData: Record<string, unknown> | undefined): string {
  return typeof eventData?.stage === 'string' ? eventData.stage : 'tool agent'
}

Then simplify the usage:

           // Handle legacy tool agent events (data-tool-agent) by normalizing into progress events
           if (part.type === "data-tool-agent") {
             const agentPart = part as { data?: AgentDataPart }
             const eventData = agentPart.data as Record<string, unknown> | undefined
-            const dataObj = eventData?.data as Record<string, unknown> | undefined
-            const msg = typeof dataObj?.text === 'string' ? dataObj.text : (typeof dataObj?.message === 'string' ? dataObj.message : (typeof eventData?.message === 'string' ? eventData.message : `Agent executing tool`))
-            const stage = typeof eventData?.stage === 'string' ? eventData.stage : 'tool agent'
+            const msg = extractAgentMessage(eventData)
+            const stage = extractStage(eventData)

             if (msg && msg.trim().length > 0) {

This improves readability while maintaining the same functionality and defensive checks.

app/chat/providers/chat-context.tsx (1)

323-330: Implementation signature doesn't match interface definition—use underscore prefix to align with ChatContext.

The sendMessage implementation (line 324) declares files?: File[], but the ChatContext interface (line 95) declares _files?: File[]. This mismatch will cause type errors. Since the parameter is unused, align the implementation with the interface:

  const sendMessage = useCallback(
-   (text: string, files?: File[]) => {
+   (text: string, _files?: File[]) => {
      if (!text.trim() || isLoading) {return}
      setChatError(null)
      aiSendMessage({ text: text.trim() })
    },
src/mastra/tools/editor-agent-tool.ts (1)

8-164: Missing TSDoc documentation for the tool.

Per coding guidelines, public APIs should have TSDoc comments including parameter descriptions, return types, and examples. Consider adding documentation for editorTool.

/**
 * Editor tool that calls the editor agent to improve content across multiple formats.
 * Supports streaming responses and emits progress events during execution.
 * 
 * @example
 * ```typescript
 * const result = await editorTool.execute({
 *   content: "Draft blog post...",
 *   contentType: "blog",
 *   tone: "professional"
 * }, context);
 * ```
 */
export const editorTool = createTool({
src/mastra/tools/financial-chart-tools.ts (2)

16-206: Missing TSDoc documentation for chartSupervisorTool.

Per coding guidelines, tools should have TSDoc comments. The existing JSDoc comment on line 12-15 is minimal. Consider expanding with @param, @returns, and @example tags.


84-205: chartSupervisorTool should explicitly orchestrate chartDataProcessorTool before chart generation.

The tool currently delegates the entire pipeline to chartSupervisorAgent, which has chartDataProcessorTool available but doesn't mandate its use. Per coding guidelines, financial chart tools must explicitly orchestrate data processing through dedicated processors. Consider refactoring the execute function to explicitly call chartDataProcessorTool first to transform the fetched financial data into Recharts-compatible format, then pass the processed data to chartSupervisorAgent or chartGeneratorTool for component generation.

src/mastra/tools/copywriter-agent-tool.ts (1)

180-182: Critical: 'general' contentType throws error despite being a valid input option.

The general content type is defined as a valid option in the inputSchema (line 27) and documented as the default, but the switch statement throws Error('Not implemented yet: "general" case'). This will break the tool for any user selecting or defaulting to 'general'.

Either implement the 'general' case or remove it from the enum:

         case 'general': {
-          throw new Error('Not implemented yet: "general" case')
+          prompt += '\n\nCreate clear, well-organized content appropriate for the topic and audience.'
+          break
         }
src/mastra/tools/document-chunking.tool.ts (1)

916-920: Complex nested fallback logic for text extraction.

This output formatting code has deeply nested ternary operators with type assertions, making it difficult to understand and maintain. This is related to the text extraction complexity on line 886.

Using the extractText helper suggested earlier, create another helper for the rerank result:

/**
 * Extract text from a rerank result with proper fallback chain
 */
function extractRerankText(r: RerankResult): string {
  // Try result.document first (if it's a string)
  if (typeof r.result?.document === 'string') {
    return r.result.document
  }
  
  // Try result.text
  const resultWithText = r.result as { text?: unknown }
  if (typeof resultWithText?.text === 'string') {
    return resultWithText.text
  }
  
  // Try result.metadata.text
  return extractText(r.result?.metadata)
}

Then simplify the output formatting:

 const rerankedDocuments = rerankedResults.map((r, index) => ({
   id: r.result?.id ?? `rerank_${index}`,
-  text:
-    (typeof r.result?.document === 'string' ? r.result.document : undefined) ??
-    (typeof (r.result as { text?: unknown })?.text === 'string' ? (r.result as unknown as { text: string }).text : undefined) ??
-    (r.result?.metadata?.text as string) ??
-    '',
+  text: extractRerankText(r),
   metadata: r.result?.metadata ?? {},
   relevanceScore: r.score,
   rank: index + 1,
 }))
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1f144f5 and 1579228.

📒 Files selected for processing (34)
  • app/chat/providers/chat-context.tsx (1 hunks)
  • app/networks/providers/network-context.tsx (2 hunks)
  • app/workflows/providers/workflow-context.tsx (1 hunks)
  • eslint.config.js (1 hunks)
  • memory-bank/copilot-rules.md (1 hunks)
  • memory-bank/memory-bank-instructions.md (1 hunks)
  • memory-bank/tasks/TASK001-tool-streaming.md (1 hunks)
  • memory-bank/tasks/TASK001-update-2025-12-14.md (1 hunks)
  • src/mastra/AGENTS.md (1 hunks)
  • src/mastra/agents/researchAgent.ts (3 hunks)
  • src/mastra/index.ts (4 hunks)
  • src/mastra/tools/AGENTS.md (4 hunks)
  • src/mastra/tools/color-change-tool.ts (1 hunks)
  • src/mastra/tools/copywriter-agent-tool.ts (3 hunks)
  • src/mastra/tools/document-chunking.tool.ts (16 hunks)
  • src/mastra/tools/editor-agent-tool.ts (4 hunks)
  • src/mastra/tools/evaluateResultTool.ts (3 hunks)
  • src/mastra/tools/extractLearningsTool.ts (3 hunks)
  • src/mastra/tools/financial-chart-tools.ts (10 hunks)
  • src/mastra/tools/tests/copywriter-agent-tool.test.ts (0 hunks)
  • src/mastra/tools/tests/csv-to-json.tool.test.ts (0 hunks)
  • src/mastra/tools/tests/data-file-manager.test.ts (0 hunks)
  • src/mastra/tools/tests/data-validator.tool.test.ts (0 hunks)
  • src/mastra/tools/tests/document-chunking.tool.test.ts (0 hunks)
  • src/mastra/tools/tests/editor-agent-tool.test.ts (0 hunks)
  • src/mastra/tools/tests/evaluateResultTool.test.ts (0 hunks)
  • src/mastra/tools/tests/extractLearningsTool.test.ts (0 hunks)
  • src/mastra/tools/tests/json-to-csv.tool.test.ts (0 hunks)
  • src/mastra/tools/tests/serpapi-academic-local.tool.test.ts (0 hunks)
  • src/mastra/tools/tests/serpapi-news-trends.tool.test.ts (0 hunks)
  • src/mastra/tools/tests/serpapi-search.tool.test.ts (0 hunks)
  • src/mastra/tools/tests/serpapi-shopping.tool.test.ts (0 hunks)
  • src/mastra/tools/tests/weather-tool.test.ts (0 hunks)
  • src/mastra/tools/tests/web-scraper-tool.test.ts (0 hunks)
💤 Files with no reviewable changes (15)
  • src/mastra/tools/tests/serpapi-news-trends.tool.test.ts
  • src/mastra/tools/tests/serpapi-academic-local.tool.test.ts
  • src/mastra/tools/tests/document-chunking.tool.test.ts
  • src/mastra/tools/tests/web-scraper-tool.test.ts
  • src/mastra/tools/tests/serpapi-search.tool.test.ts
  • src/mastra/tools/tests/copywriter-agent-tool.test.ts
  • src/mastra/tools/tests/csv-to-json.tool.test.ts
  • src/mastra/tools/tests/evaluateResultTool.test.ts
  • src/mastra/tools/tests/serpapi-shopping.tool.test.ts
  • src/mastra/tools/tests/data-validator.tool.test.ts
  • src/mastra/tools/tests/editor-agent-tool.test.ts
  • src/mastra/tools/tests/weather-tool.test.ts
  • src/mastra/tools/tests/json-to-csv.tool.test.ts
  • src/mastra/tools/tests/data-file-manager.test.ts
  • src/mastra/tools/tests/extractLearningsTool.test.ts
🧰 Additional context used
📓 Path-based instructions (25)
**/*.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:

  • src/mastra/AGENTS.md
  • memory-bank/tasks/TASK001-update-2025-12-14.md
  • src/mastra/tools/AGENTS.md
  • memory-bank/memory-bank-instructions.md
  • memory-bank/tasks/TASK001-tool-streaming.md
  • memory-bank/copilot-rules.md
src/mastra/**/*

📄 CodeRabbit inference engine (src/AGENTS.md)

mastra modules can import from utils, but must not import from app or cli (except types)

Files:

  • src/mastra/AGENTS.md
  • src/mastra/index.ts
  • src/mastra/tools/evaluateResultTool.ts
  • src/mastra/tools/financial-chart-tools.ts
  • src/mastra/agents/researchAgent.ts
  • src/mastra/tools/color-change-tool.ts
  • src/mastra/tools/AGENTS.md
  • src/mastra/tools/extractLearningsTool.ts
  • src/mastra/tools/copywriter-agent-tool.ts
  • src/mastra/tools/document-chunking.tool.ts
  • src/mastra/tools/editor-agent-tool.ts
**/*.{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:

  • src/mastra/index.ts
  • app/chat/providers/chat-context.tsx
  • src/mastra/tools/evaluateResultTool.ts
  • app/workflows/providers/workflow-context.tsx
  • app/networks/providers/network-context.tsx
  • src/mastra/tools/financial-chart-tools.ts
  • src/mastra/agents/researchAgent.ts
  • src/mastra/tools/color-change-tool.ts
  • src/mastra/tools/extractLearningsTool.ts
  • src/mastra/tools/copywriter-agent-tool.ts
  • eslint.config.js
  • src/mastra/tools/document-chunking.tool.ts
  • src/mastra/tools/editor-agent-tool.ts
**/*.{js,ts}

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

Use parameterized queries or an ORM to prevent SQL injection attacks.

Files:

  • src/mastra/index.ts
  • src/mastra/tools/evaluateResultTool.ts
  • src/mastra/tools/financial-chart-tools.ts
  • src/mastra/agents/researchAgent.ts
  • src/mastra/tools/color-change-tool.ts
  • src/mastra/tools/extractLearningsTool.ts
  • src/mastra/tools/copywriter-agent-tool.ts
  • eslint.config.js
  • src/mastra/tools/document-chunking.tool.ts
  • src/mastra/tools/editor-agent-tool.ts
**/*.{ts,tsx,js,jsx,py,java,cs,rb,go,rs,cpp,c,h,hpp,swift,kotlin,php,scala,clj,groovy,lua,sh,bash}

📄 CodeRabbit inference engine (.github/instructions/self-explanatory-code-commenting.instructions.md)

**/*.{ts,tsx,js,jsx,py,java,cs,rb,go,rs,cpp,c,h,hpp,swift,kotlin,php,scala,clj,groovy,lua,sh,bash}: Write code that speaks for itself. Comment only when necessary to explain WHY, not WHAT. Avoid obvious comments that state what the code literally does.
Avoid redundant comments that simply repeat what the code is doing
Keep comments accurate and up-to-date with code changes. Remove or update outdated comments that no longer match the implementation.
Write comments for complex business logic that explain the WHY behind specific calculations or business rules
Document non-obvious algorithms with comments explaining the algorithm choice and its reasoning
Add comments explaining what regex patterns match, especially for complex patterns
Document API constraints, rate limits, gotchas, and external dependencies with explanatory comments
Avoid commenting out dead code. Use version control instead of maintaining commented code blocks.
Do not maintain code change history or modification logs as comments. Rely on git history and commit messages instead.
Avoid decorative divider comments (e.g., lines of equals signs or asterisks) for section separation
Ensure comments are placed appropriately above or adjacent to the code they describe
Write comments using proper grammar, spelling, and professional language
Prefer self-documenting code with clear variable/function names over adding comments to explain unclear code

Files:

  • src/mastra/index.ts
  • app/chat/providers/chat-context.tsx
  • src/mastra/tools/evaluateResultTool.ts
  • app/workflows/providers/workflow-context.tsx
  • app/networks/providers/network-context.tsx
  • src/mastra/tools/financial-chart-tools.ts
  • src/mastra/agents/researchAgent.ts
  • src/mastra/tools/color-change-tool.ts
  • src/mastra/tools/extractLearningsTool.ts
  • src/mastra/tools/copywriter-agent-tool.ts
  • eslint.config.js
  • src/mastra/tools/document-chunking.tool.ts
  • src/mastra/tools/editor-agent-tool.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.github/instructions/self-explanatory-code-commenting.instructions.md)

**/*.{ts,tsx,js,jsx}: Document public APIs with TSDoc/JSDoc comments including parameter descriptions, return types, examples, and thrown exceptions
Add TSDoc comments to configuration constants and environment variables explaining their source, reasoning, or constraints
Use TSDoc annotation tags (TODO, FIXME, HACK, NOTE, WARNING, PERF, SECURITY, BUG, REFACTOR, DEPRECATED) to mark special comments
Include file headers with @fileoverview, @author, @copyright, and @license tags to document file purpose and ownership
Document function parameters with @param tags, return values with @returns tags, and exceptions with @throws tags in TSDoc comments
Use @see tags in TSDoc comments to reference related functions, methods, or documentation
Include @example tags in public API documentation with code examples showing typical usage

**/*.{ts,tsx,js,jsx}: Use Mastra mcp tools (#mastradocs, #mastraChanges, #mastraexamples, #mastraBlog) for Mastra framework development to stay updated with latest features and best practices
When working with Next.js projects, always utilize the next-devtools-mcp server for all Next.js related queries

Files:

  • src/mastra/index.ts
  • app/chat/providers/chat-context.tsx
  • src/mastra/tools/evaluateResultTool.ts
  • app/workflows/providers/workflow-context.tsx
  • app/networks/providers/network-context.tsx
  • src/mastra/tools/financial-chart-tools.ts
  • src/mastra/agents/researchAgent.ts
  • src/mastra/tools/color-change-tool.ts
  • src/mastra/tools/extractLearningsTool.ts
  • src/mastra/tools/copywriter-agent-tool.ts
  • eslint.config.js
  • src/mastra/tools/document-chunking.tool.ts
  • src/mastra/tools/editor-agent-tool.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/instructions/self-explanatory-code-commenting.instructions.md)

**/*.{ts,tsx}: Document interface and type definitions with TSDoc comments explaining their purpose and usage context
Document interface properties with /** */ comments explaining each field's purpose and constraints
Document generic type parameters with @template tags explaining what each type parameter represents
Use type guards with comments explaining the runtime validation logic being performed
Document advanced/complex TypeScript types with explanatory comments about their purpose and use cases

Files:

  • src/mastra/index.ts
  • app/chat/providers/chat-context.tsx
  • src/mastra/tools/evaluateResultTool.ts
  • app/workflows/providers/workflow-context.tsx
  • app/networks/providers/network-context.tsx
  • src/mastra/tools/financial-chart-tools.ts
  • src/mastra/agents/researchAgent.ts
  • src/mastra/tools/color-change-tool.ts
  • src/mastra/tools/extractLearningsTool.ts
  • src/mastra/tools/copywriter-agent-tool.ts
  • src/mastra/tools/document-chunking.tool.ts
  • src/mastra/tools/editor-agent-tool.ts
src/mastra/index.ts

📄 CodeRabbit inference engine (src/AGENTS.md)

Enforce registration pattern in mastra/index.ts for AI orchestration modules composition

Files:

  • src/mastra/index.ts
**/*.{css,tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

Use Tailwind CSS 4 with oklch color variables for styling

Files:

  • src/mastra/index.ts
  • app/chat/providers/chat-context.tsx
  • src/mastra/tools/evaluateResultTool.ts
  • app/workflows/providers/workflow-context.tsx
  • app/networks/providers/network-context.tsx
  • src/mastra/tools/financial-chart-tools.ts
  • src/mastra/agents/researchAgent.ts
  • src/mastra/tools/color-change-tool.ts
  • src/mastra/tools/extractLearningsTool.ts
  • src/mastra/tools/copywriter-agent-tool.ts
  • src/mastra/tools/document-chunking.tool.ts
  • src/mastra/tools/editor-agent-tool.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/chat/providers/chat-context.tsx
  • app/workflows/providers/workflow-context.tsx
  • app/networks/providers/network-context.tsx
app/**/*.{tsx,ts}

📄 CodeRabbit inference engine (app/AGENTS.md)

app/**/*.{tsx,ts}: Use Tailwind CSS 4 with oklch color variables for styling in Next.js App Router pages and layouts
Use React 19 latest features in component implementations within the app directory

Files:

  • app/chat/providers/chat-context.tsx
  • app/workflows/providers/workflow-context.tsx
  • app/networks/providers/network-context.tsx
app/chat/providers/chat-context.tsx

📄 CodeRabbit inference engine (app/chat/AGENTS.md)

app/chat/providers/chat-context.tsx: Use ChatContext provider with AI SDK v5 types in chat-context.tsx to manage chat state, agent selection, and streaming messages across the application
Use DefaultChatTransport from @ai-sdk/react with the Mastra /chat route endpoint, configure prepareSendMessagesRequest to include resourceId and agentId in the request body for proper agent routing

Files:

  • app/chat/providers/chat-context.tsx
app/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Frontend uses Next.js 16 App Router with React 19; use shadcn/ui base components (34 components) from ui/ directory

Files:

  • app/chat/providers/chat-context.tsx
  • app/workflows/providers/workflow-context.tsx
  • app/networks/providers/network-context.tsx
app/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

Use @ai-sdk/react for streaming and AI interactions in React components

Files:

  • app/chat/providers/chat-context.tsx
  • app/workflows/providers/workflow-context.tsx
  • app/networks/providers/network-context.tsx
src/mastra/tools/**/*.ts

📄 CodeRabbit inference engine (src/mastra/AGENTS.md)

src/mastra/tools/**/*.ts: Use the createTool pattern with Zod schemas when adding new tools under src/mastra/tools
Use explicit Zod schemas for every tool input/output

Implement tools using createTool({ id, inputSchema, outputSchema, execute }) pattern with strict Zod schemas

Files:

  • src/mastra/tools/evaluateResultTool.ts
  • src/mastra/tools/financial-chart-tools.ts
  • src/mastra/tools/color-change-tool.ts
  • src/mastra/tools/extractLearningsTool.ts
  • src/mastra/tools/copywriter-agent-tool.ts
  • src/mastra/tools/document-chunking.tool.ts
  • src/mastra/tools/editor-agent-tool.ts
src/mastra/{tools,workflows}/**/*.ts

📄 CodeRabbit inference engine (src/mastra/AGENTS.md)

Use RuntimeContext to enforce access control in tools and workflows

Files:

  • src/mastra/tools/evaluateResultTool.ts
  • src/mastra/tools/financial-chart-tools.ts
  • src/mastra/tools/color-change-tool.ts
  • src/mastra/tools/extractLearningsTool.ts
  • src/mastra/tools/copywriter-agent-tool.ts
  • src/mastra/tools/document-chunking.tool.ts
  • src/mastra/tools/editor-agent-tool.ts
src/mastra/{tools,agents,workflows}/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Use Zod schemas for strict input/output validation in tools, agents, and workflows

Files:

  • src/mastra/tools/evaluateResultTool.ts
  • src/mastra/tools/financial-chart-tools.ts
  • src/mastra/agents/researchAgent.ts
  • src/mastra/tools/color-change-tool.ts
  • src/mastra/tools/extractLearningsTool.ts
  • src/mastra/tools/copywriter-agent-tool.ts
  • src/mastra/tools/document-chunking.tool.ts
  • src/mastra/tools/editor-agent-tool.ts
src/mastra/tools/**/*.{ts,tool.ts}

📄 CodeRabbit inference engine (src/mastra/tools/AGENTS.md)

All tool exports must be named exports matching the pattern {descriptiveName}Tool and must include Zod input/output schemas

Files:

  • src/mastra/tools/evaluateResultTool.ts
  • src/mastra/tools/financial-chart-tools.ts
  • src/mastra/tools/color-change-tool.ts
  • src/mastra/tools/extractLearningsTool.ts
  • src/mastra/tools/copywriter-agent-tool.ts
  • src/mastra/tools/document-chunking.tool.ts
  • src/mastra/tools/editor-agent-tool.ts
app/workflows/providers/workflow-context.tsx

📄 CodeRabbit inference engine (app/workflows/AGENTS.md)

app/workflows/providers/workflow-context.tsx: State management in workflow-context.tsx should use useChat hook from @ai-sdk/react with DefaultChatTransport for real-time streaming
Workflow-context.tsx should provide WorkflowContextValue interface with state management for selectedWorkflow, workflowStatus, currentRun, activeStepIndex, and streaming data

Files:

  • app/workflows/providers/workflow-context.tsx
app/networks/**/*.tsx

📄 CodeRabbit inference engine (app/networks/AGENTS.md)

app/networks/**/*.tsx: Use useChat from @ai-sdk/react with DefaultChatTransport for streaming responses from the /network route in the networks feature
Support real-time streaming with stop/cancel functionality, reasoning visualization for chain-of-thought models, and tool invocation display showing agent tool calls
Provide a responsive layout with collapsible sidebar on mobile for the networks feature

Files:

  • app/networks/providers/network-context.tsx
app/networks/providers/network-context.tsx

📄 CodeRabbit inference engine (app/networks/AGENTS.md)

Implement state management using useNetworkContext() hook that provides selectedNetwork, networkConfig, networkStatus, messages, streamingOutput, routingSteps, and control functions (sendMessage, stopExecution, clearHistory)

Files:

  • app/networks/providers/network-context.tsx
src/mastra/tools/*financial-chart*.ts

📄 CodeRabbit inference engine (src/mastra/tools/AGENTS.md)

Financial chart tools must orchestrate data processing through dedicated processors before chart generation

Files:

  • src/mastra/tools/financial-chart-tools.ts
src/mastra/agents/**/*.ts

📄 CodeRabbit inference engine (src/mastra/AGENTS.md)

Add new agent definitions under src/mastra/agents that wire tools together into higher-level behaviors

Agents must compose tools into specialized behaviors and be located in src/mastra/agents

Files:

  • src/mastra/agents/researchAgent.ts
src/mastra/agents/*.ts

📄 CodeRabbit inference engine (src/mastra/agents/AGENTS.md)

src/mastra/agents/*.ts: Agent file naming convention: Create agent files using kebab-case with .ts extension in /src/mastra/agents/ directory (e.g., your-agent-name.ts)
Each agent must follow the pattern: export agent as const yourAgent = new Agent({ id: 'your-agent-id', name: 'Your Agent Name', description: '...' })

Files:

  • src/mastra/agents/researchAgent.ts
src/mastra/tools/**/*.tool.ts

📄 CodeRabbit inference engine (src/mastra/tools/AGENTS.md)

src/mastra/tools/**/*.tool.ts: All tools must emit progress events with type 'data-tool-progress' containing status ('in-progress' or 'done'), message, and stage fields, with id placed outside the data object
Data validation in tools must use Zod schemas for runtime validation

Files:

  • src/mastra/tools/document-chunking.tool.ts
🧬 Code graph analysis (5)
src/mastra/tools/evaluateResultTool.ts (3)
src/mastra/agents/evaluationAgent.ts (1)
  • evaluationAgent (18-140)
src/mastra/services/VectorQueryService.ts (1)
  • query (419-442)
src/mastra/config/logger.ts (1)
  • log (14-18)
src/mastra/tools/financial-chart-tools.ts (1)
src/mastra/agents/recharts.ts (4)
  • chartSupervisorAgent (378-539)
  • chartGeneratorAgent (237-372)
  • chartDataProcessorAgent (131-231)
  • chartTypeAdvisorAgent (44-125)
src/mastra/tools/copywriter-agent-tool.ts (2)
src/mastra/index.ts (1)
  • mastra (99-523)
src/mastra/agents/copywriterAgent.ts (1)
  • copywriterAgent (27-148)
src/mastra/tools/document-chunking.tool.ts (2)
src/mastra/config/logger.ts (3)
  • logStepStart (72-88)
  • logError (153-174)
  • log (14-18)
src/mastra/config/pg-storage.ts (1)
  • pgVector (77-84)
src/mastra/tools/editor-agent-tool.ts (1)
src/mastra/agents/editorAgent.ts (1)
  • editorAgent (18-133)
⏰ 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). (6)
  • GitHub Check: CodeQL analysis (javascript-typescript)
  • GitHub Check: Agent
  • GitHub Check: Codacy Security Scan
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: Codacy Security Scan
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (28)
src/mastra/AGENTS.md (1)

48-48: LGTM! Improved context guidance.

The updated guidance to use RequestContext or agent-specific runtime context types provides clearer direction for developers implementing access control. This aligns with the middleware patterns introduced elsewhere in the codebase.

app/chat/providers/chat-context.tsx (1)

95-95: Public API parameter name changed.

The parameter name changed from _files to files in the public interface. While this doesn't affect consumers (parameter names in interfaces are for documentation), be aware this parameter remains unused in the implementation (see line 324).

src/mastra/tools/AGENTS.md (1)

135-136: LGTM! Documentation properly updated.

The documentation updates correctly reference the TASK001 tracking, update timestamps, and add appropriate changelog entries for the streaming and progress event changes.

Also applies to: 151-151, 163-163

src/mastra/agents/researchAgent.ts (3)

37-39: LGTM! Well-designed runtime context extensions.

The new userId and researchPhase fields enable user-aware and phase-specific research behavior. The union type for researchPhase ('initial' | 'followup' | 'validation' | string) provides good flexibility while documenting common phases.


52-53: LGTM! Proper context field integration.

The new runtime context fields are correctly read with sensible defaults ('anonymous', 'initial') and integrated into the system prompt. This enables the research agent to adapt its behavior based on user identity and research phase.

Also applies to: 62-63


171-172: Lines 169 and 175 use non-existent google.chat() method that will fail at runtime.

Line 172 (pro tier) returns a valid string format 'google/gemini-2.5-flash-preview-09-2025'. However, lines 169 and 175 call google.chat() which does not exist in the @ai-sdk/google library. This pattern is used identically in scriptWriterAgent.ts and editorAgent.ts.

Align all tiers with the working pattern used in most other agents (e.g., stockAnalysisAgent.ts, weather-agent.ts):

  model: ({ requestContext }: { requestContext: RequestContext<ResearchRuntimeContext> }) => {
    const userTier = requestContext.get('user-tier') ?? 'free'
    if (userTier === 'enterprise') {
      // higher quality (chat style) for enterprise
-     return google.chat('gemini-3-pro-preview')
+     return googleAIPro
    } else if (userTier === 'pro') {
      // cheaper/faster model for pro tier
-     return 'google/gemini-2.5-flash-preview-09-2025'
+     return googleAI
    }
    // cheaper/faster model for free tier
-   return google.chat('gemini-2.5-flash-preview-09-2025')
+   return googleAIFlashLite
  },

Likely an incorrect or invalid review comment.

memory-bank/memory-bank-instructions.md (1)

40-40: LGTM! Helpful cross-reference to streaming conventions.

The addition of the TASK001-tool-streaming.md reference provides developers with clear guidance on implementing standardized streaming and progress events. This helps maintain consistency across tool implementations.

app/networks/providers/network-context.tsx (2)

298-323: LGTM - Robust legacy event normalization.

The defensive extraction of message text from multiple possible fields (dataObj?.text, dataObj?.message, eventData?.message, eventData?.text) with proper type guards handles varying legacy event formats well. The stage derivation fallback and agentId extraction are appropriately guarded.


331-341: The condition correctly filters for the actual status values emitted by tools. All tools in the codebase emit only status: "in-progress" or status: "done"; error conditions are indicated via the stage field (e.g., status: "done", stage: "error"), not through a "error" status value. The "error" status defined in the ProgressEvent type is never created by any tool implementation and appears to be unused in the current codebase.

However, the ProgressEvent type definition includes "error" as a valid status value, creating a mismatch between the type and actual usage. Consider either removing "error" from the type definition or implementing support for error progress events if they're intended for future use.

memory-bank/copilot-rules.md (1)

155-179: LGTM - Clear streaming convention documentation.

The guidance provides actionable patterns for:

  • Runtime agent resolution with fallback
  • Stream API usage with textStream/fullStream piping
  • Structured progress event emission

This aligns well with the implementation changes in evaluateResultTool.ts and other tools in this PR.

src/mastra/index.ts (3)

54-56: LGTM - New agent imports.

The new agent imports for calendarAgent, bgColorAgent, and danePackagePublisher follow the established pattern.


147-151: LGTM - Agent registration follows established pattern.

New agents are properly registered in the Mastra agent registry with descriptive comments.


484-497: Token parsing is basic pattern matching - verify this is intentional.

The userId and userTier extraction from Bearer tokens uses simple string pattern matching (/user:([^;\s]+)/, token.includes('enterprise')), not cryptographic JWT validation. This appears to be development/convenience logic.

Ensure this approach is intentional and that proper authentication is handled elsewhere (e.g., API gateway, separate auth middleware). Based on coding guidelines, authentication tokens should be handled securely.

src/mastra/tools/evaluateResultTool.ts (4)

5-5: LGTM - Type import for streaming support.

Adding MastraModelOutput type import aligns with the streaming pattern documented in copilot-rules.md.


54-55: LGTM - Runtime agent resolution with fallback.

Follows the TASK001 streaming convention: prefer runtime agent via context.mastra.getAgent(), fallback to local import.


90-93: LGTM - Generate fallback path with defensive parsing.

The fallback to agent.generate() when streaming is unavailable, with defensive JSON parsing using an IIFE, handles both structured and text responses appropriately.


64-72: The code correctly implements the official Mastra nested-agent streaming pattern. After calling pipeTo() on stream.textStream or stream.fullStream, awaiting stream.text works as intended because MastraModelOutput maintains a separate internal buffer for the .text property independent of stream consumption. This pattern is documented in the project's memory bank and consistently used across all agent-calling tools without issues.

Likely an incorrect or invalid review comment.

src/mastra/tools/editor-agent-tool.ts (4)

38-51: LGTM - Progress event initialization.

The progress event structure follows the standardized data-tool-progress pattern with appropriate status, message, and stage fields.


115-121: Good error handling in streaming block.

The error handling correctly records exceptions on the span, sets error status, and rethrows. This ensures observability while preserving the error for the outer catch block.


91-92: The type assertion as MastraModelOutput | undefined itself lacks runtime validation, but the code already implements comprehensive defensive checks that prevent the claimed issues. Property accesses use optional chaining (stream?.textStream, stream?.fullStream, stream?.text), and fallback values are provided via the null coalescing operator (?? ''). The if-else-if structure on lines 97–110 handles all cases: textStream, fullStream, or fallback to agent.generate(). This is the documented standard pattern in your codebase (per memory-bank/copilot-rules.md) for agent streaming, and the try-catch block (lines 90–121) provides additional error handling.

Likely an incorrect or invalid review comment.


97-106: This implementation follows the documented Mastra tool streaming pattern referenced in the official docs. The code already includes runtime guards checking for writer existence before calling pipeTo(), preventing the runtime errors this comment suggests. The unsafe cast is an intentional design of Mastra's tool context to support different runtime environments, and this pattern is consistently implemented across all agent-based tools in the codebase. No changes are needed.

src/mastra/tools/financial-chart-tools.ts (1)

108-117: Agent capability check validates correctly.

The check typeof agent.generate !== 'function' && typeof agent.stream !== 'function' correctly validates that the agent has at least one invocation method before proceeding. This is a good defensive pattern.

src/mastra/tools/copywriter-agent-tool.ts (1)

108-130: Good defensive validation for agent availability.

The check for agent invocation methods and graceful fallback with a user-friendly message is well implemented.

src/mastra/tools/extractLearningsTool.ts (1)

76-92: Good streaming implementation with proper fallback.

The streaming logic correctly checks for stream function availability, uses MastraModelOutput typing, and falls back to generate when streaming is unavailable.

src/mastra/tools/document-chunking.tool.ts (4)

409-411: LGTM! Proper span cleanup in finally block.

Adding finally blocks to ensure span.end() is called prevents OpenTelemetry span leaks and follows tracing best practices. This pattern is correctly applied across all three tools in this file.


841-847: LGTM! Proper weight normalization with informative logging.

The weight normalization ensures valid input to the reranker and provides helpful debugging information when user-supplied weights don't sum to 1. The floating-point comparison threshold is appropriate.


199-199: LGTM! Progress events follow coding guidelines.

The tool progress events are properly structured with type: 'data-tool-progress', include required fields (status, message, stage), and place the id outside the data object as required by the coding guidelines. This pattern is consistently applied across all three tools.

Based on coding guidelines: "All tools must emit progress events with type 'data-tool-progress' containing status ('in-progress' or 'done'), message, and stage fields, with id placed outside the data object."


46-56: Remove unnecessary export of normalizeWeights function.

The function is only used internally within document-chunking.tool.ts (line 842) and has no external usages. Remove the export keyword to keep the module's public API focused and prevent accidental external dependencies.

Likely an incorrect or invalid review comment.

Comment on lines +65 to +66
'no-unused-vars': ['warn', { }],
'@typescript-eslint/no-unused-vars': ['warn', {}],
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

🧩 Analysis chain

🏁 Script executed:

# First, let's examine the eslint.config.js file around lines 65-66
cat -n eslint.config.js | sed -n '50,80p'

Repository: ssdeanx/AgentStack

Length of output: 1444


🏁 Script executed:

# Check git history to see what the previous config looked like
git log --oneline -n 20 eslint.config.js

Repository: ssdeanx/AgentStack

Length of output: 121


🏁 Script executed:

# Search for underscore-prefixed parameters in the codebase
rg -nP '\(_[a-zA-Z]' --type=ts --type=tsx --type=js --type=jsx -g '!node_modules' -g '!.next' | head -50

Repository: ssdeanx/AgentStack

Length of output: 89


🏁 Script executed:

# Specific check for the chat-context.tsx file mentioned in the review
cat -n app/chat/providers/chat-context.tsx | sed -n '320,330p'

Repository: ssdeanx/AgentStack

Length of output: 393


🏁 Script executed:

# Let's try a different approach to find underscore-prefixed variables
rg '(_[a-zA-Z])' --type=ts --type=js -g '!node_modules' -g '!.next' | grep -E '\(.*_[a-zA-Z]|=.*_[a-zA-Z]' | head -30

Repository: ssdeanx/AgentStack

Length of output: 6576


🏁 Script executed:

# Let's also search more directly for function parameters starting with underscore
rg '\([^)]*_[a-zA-Z][a-zA-Z0-9]*[^)]*\)' -g '!node_modules' -g '!.next' | head -40

Repository: ssdeanx/AgentStack

Length of output: 48439


🏁 Script executed:

# Check if there's a git diff showing what changed
git diff HEAD~1 eslint.config.js 2>/dev/null || echo "No previous commit available"

Repository: ssdeanx/AgentStack

Length of output: 90


🏁 Script executed:

# Get more context about the PR/commit
git show --stat 2>/dev/null | head -30

Repository: ssdeanx/AgentStack

Length of output: 1882


🏁 Script executed:

# Search for function parameters starting with underscore more carefully
rg '(\(|,)\s*_[a-zA-Z]' -g '!node_modules' -g '!.next' --context=2 | head -80

Repository: ssdeanx/AgentStack

Length of output: 50375


🏁 Script executed:

# Check specifically for any existing underscore usage that would now fail linting
find . -name '*.ts' -o -name '*.tsx' -o -name '*.js' -o -name '*.jsx' | grep -v node_modules | grep -v .next | xargs grep -l '(_[a-zA-Z]' 2>/dev/null | head -20

Repository: ssdeanx/AgentStack

Length of output: 751


🏁 Script executed:

# Let's verify the exact change by looking at git diff of eslint.config.js
git diff HEAD~1 eslint.config.js 2>/dev/null || echo "Can't get diff, showing current lines 60-70"
cat eslint.config.js | sed -n '60,70p'

Repository: ssdeanx/AgentStack

Length of output: 490


Verify impact of stricter ESLint unused-vars rules causing new lint warnings.

The removal of argsIgnorePattern and varsIgnorePattern from both no-unused-vars rules has already been applied in the current configuration. This change makes the linting rules stricter and will flag unused variables that start with underscores, which developers commonly use to indicate intentionally unused parameters.

The codebase contains at least two existing instances of underscore-prefixed unused parameters that will now trigger warnings:

  • src/mastra/tools/web-scraper-tool.ts line with (_i, element) => {...}
  • src/mastra/tools/execa-tool.ts with transform(chunk, _encoding, callback)

Additionally, the unused files parameter in app/chat/providers/chat-context.tsx line 324 will trigger a warning regardless of underscore convention.

🤖 Prompt for AI Agents
In eslint.config.js around lines 65-66, removing
argsIgnorePattern/varsIgnorePattern made unused-vars rules flag
underscore-prefixed parameters and other unused params; restore the original
ignore patterns (e.g., argsIgnorePattern and varsIgnorePattern matching ^_) to
exempt intentionally unused underscore-prefixed variables, and/or fix the
reported sites by either removing the unused parameter, renaming it to a clearly
ignored name (e.g., _unused) or adding a targeted eslint-disable-next-line
comment; specifically address src/mastra/tools/web-scraper-tool.ts (_i
parameter), src/mastra/tools/execa-tool.ts (transform's _encoding), and
app/chat/providers/chat-context.tsx (remove or use the unused files parameter)
so no new warnings remain.

Comment on lines +1 to +27
# TASK001 - Update Log (2025-12-14)

Summary of changes performed to align tools with the streaming + progress convention:

- Replaced `data-tool-agent` messages with `data-tool-progress` (standard in-progress/done events) in:
- `src/mastra/tools/evaluateResultTool.ts`
- `src/mastra/tools/extractLearningsTool.ts`
- `src/mastra/tools/editor-agent-tool.ts`
- `src/mastra/tools/copywriter-agent-tool.ts`

- Normalized nested-agent streaming pattern in tools to:
- Prefer `context.mastra.getAgent()` runtime instance if available, otherwise fall back to local agent import
- Use `agent.stream(prompt)` returning `MastraModelOutput` when available
- Pipe `textStream` / `fullStream` to `context.writer`
- Parse `stream.object` or JSON text safely for structured output

- Updated `src/mastra/tools/financial-chart-tools.ts` to use the same streaming pattern and to validate agent capability (check for `generate` or `stream`).

- Updated client-side parsers to normalize legacy `data-tool-agent` parts into `data-tool-progress` events:
- `app/networks/providers/network-context.tsx`
- `app/workflows/providers/workflow-context.tsx`

- Updated `src/mastra/tools/AGENTS.md` with a note referencing this task and the progress convention.

Notes:
- Tests will be added next to verify that progress events and streaming behavior are emitted consistently. (Pending)
- If you'd like, I can add/restore unit tests and run the test suite now.
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Missing YAML front matter.

Per coding guidelines, markdown files should include YAML front matter with required metadata fields (post_title, author1, post_slug, etc.). Consider adding front matter if this document is intended for publication or documentation systems.

🤖 Prompt for AI Agents
In memory-bank/tasks/TASK001-update-2025-12-14.md around lines 1 to 27, this
markdown lacks the required YAML front matter; add a top-of-file YAML block
delimited by --- that includes at minimum post_title, author1, post_slug and
date (e.g., date: 2025-12-14) and any other project-required fields (tags,
summary) ensuring keys use valid YAML syntax and values are properly quoted if
needed; place the block before any content so tooling/publishers recognize the
metadata.

@@ -0,0 +1,27 @@
# TASK001 - Update Log (2025-12-14)
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Use H2 instead of H1 for the document heading.

Per coding guidelines, H1 headings should not be used as they are generated from the title. Replace # with ##.

-# TASK001 - Update Log (2025-12-14)
+## TASK001 - Update Log (2025-12-14)
📝 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
# TASK001 - Update Log (2025-12-14)
## TASK001 - Update Log (2025-12-14)
🤖 Prompt for AI Agents
In memory-bank/tasks/TASK001-update-2025-12-14.md around lines 1 to 1, the
document uses an H1 heading ("# TASK001 - Update (2025-12-14)") but coding
guidelines require H2 headings; change the leading "#" to "##" so the file
starts with "## TASK001 - Update (2025-12-14)" to comply with the guideline that
H1 is reserved for the generated title.

Comment on lines +26 to +27
- Tests will be added next to verify that progress events and streaming behavior are emitted consistently. (Pending)
- If you'd like, I can add/restore unit tests and run the test suite now.
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Remove conversational tone from documentation.

Line 27 contains conversational language ("If you'd like, I can...") which is inappropriate for task documentation. Consider rephrasing to be more declarative.

-- If you'd like, I can add/restore unit tests and run the test suite now.
+- Unit tests should be added/restored and the test suite run to verify changes.
📝 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
- Tests will be added next to verify that progress events and streaming behavior are emitted consistently. (Pending)
- If you'd like, I can add/restore unit tests and run the test suite now.
- Tests will be added next to verify that progress events and streaming behavior are emitted consistently. (Pending)
- Unit tests should be added/restored and the test suite run to verify changes.
🤖 Prompt for AI Agents
In memory-bank/tasks/TASK001-update-2025-12-14.md around lines 26-27, replace
the conversational sentence "If you'd like, I can add/restore unit tests and run
the test suite now." with a declarative statement that describes the planned
action (for example, state that unit tests will be added or restored and the
test suite will be run), removing first‑person/offering phrasing and keeping it
concise and factual.

Comment on lines +483 to +498
if (!userId && authHeader !== null && authHeader !== '' && authHeader.startsWith('Bearer ')) {
const token = authHeader.slice('Bearer '.length)
const exec = /user:([^;\s]+)/.exec(token)
if (exec) { userId = exec[1] }
}
if (userId !== null && userId !== '') { requestContext.set('userId', userId) }

// user-tier: prefer explicit header, otherwise derive from token hints
let userTier = headerUserTier
if (!userTier && authHeader !== null && authHeader !== '' && authHeader.startsWith('Bearer ')) {
const token = authHeader.slice('Bearer '.length)
if (token.includes('enterprise')) { userTier = 'enterprise' }
else if (token.includes('pro')) { userTier = 'pro' }
else { userTier = 'free' }
}
if (userTier !== null && userTier !== '') { requestContext.set('user-tier', userTier) }
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Simplify redundant null checks.

Since authHeader is defaulted to '' on line 469, the !== null checks are redundant. Similarly, userId and userTier can only be string | undefined, not null.

-          if (!userId && authHeader !== null && authHeader !== '' && authHeader.startsWith('Bearer ')) {
+          if (!userId && authHeader.startsWith('Bearer ')) {
             const token = authHeader.slice('Bearer '.length)
             const exec = /user:([^;\s]+)/.exec(token)
             if (exec) { userId = exec[1] }
           }
-          if (userId !== null && userId !== '') { requestContext.set('userId', userId) }
+          if (userId) { requestContext.set('userId', userId) }

           // user-tier: prefer explicit header, otherwise derive from token hints
           let userTier = headerUserTier
-          if (!userTier && authHeader !== null && authHeader !== '' && authHeader.startsWith('Bearer ')) {
+          if (!userTier && authHeader.startsWith('Bearer ')) {
             const token = authHeader.slice('Bearer '.length)
             if (token.includes('enterprise')) { userTier = 'enterprise' }
             else if (token.includes('pro')) { userTier = 'pro' }
             else { userTier = 'free' }
           }
-          if (userTier !== null && userTier !== '') { requestContext.set('user-tier', userTier) }
+          if (userTier) { requestContext.set('user-tier', userTier) }
🤖 Prompt for AI Agents
In src/mastra/index.ts around lines 483 to 498, remove redundant `!== null`
checks and simplify truthiness checks: since `authHeader` is defaulted to '' and
`userId`/`userTier` are `string | undefined`, use concise conditions like `if
(!userId && authHeader.startsWith('Bearer '))` and `if (!userTier &&
authHeader.startsWith('Bearer '))`, and when setting the context use `if
(userId)` / `if (userTier)` or `if (userId !== '')` to avoid null checks; ensure
behavior is unchanged while eliminating unnecessary null comparisons.


if (stream) {
const text = (await stream.text) ?? '';
try { responseObject = stream.object ?? (text ? JSON.parse(text) : {}) } catch { responseObject = {} }
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Complex one-liner JSON parsing is hard to maintain.

The nested try/catch with ternary in one line reduces readability:

-          try { responseObject = stream.object ?? (text ? JSON.parse(text) : {}) } catch { responseObject = {} }
+          try {
+            responseObject = stream.object ?? (text ? JSON.parse(text) : {});
+          } catch {
+            responseObject = {};
+          }
🤖 Prompt for AI Agents
In src/mastra/tools/extractLearningsTool.ts around line 85, the complex one-line
that attempts to set responseObject with a nested ternary and try/catch is hard
to read and swallows errors; refactor into a few clear statements: first compute
a fallback (e.g., const raw = stream.object ?? text), then if raw is a string
attempt JSON.parse inside a try/catch that only handles parsing and sets
responseObject = parsed or {} on failure, otherwise assign responseObject = raw,
and optionally log parse errors instead of silently ignoring them.

Comment on lines +129 to +130
const learningLength = parsed.data.learning.length ?? 0;
const followUpQuestionsCount = parsed.data.followUpQuestions?.length ?? 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

Unnecessary nullish coalescing on string .length.

parsed.data.learning.length is always a number (string always has length property). The ?? 0 is redundant:

-      const learningLength = parsed.data.learning.length ?? 0;
-      const followUpQuestionsCount = parsed.data.followUpQuestions?.length ?? 0;
+      const learningLength = parsed.data.learning.length;
+      const followUpQuestionsCount = parsed.data.followUpQuestions.length;

Note: followUpQuestions is defined as z.array(z.string()) in the schema, so after successful parse it's guaranteed to be an array with a .length property.

📝 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
const learningLength = parsed.data.learning.length ?? 0;
const followUpQuestionsCount = parsed.data.followUpQuestions?.length ?? 0;
const learningLength = parsed.data.learning.length;
const followUpQuestionsCount = parsed.data.followUpQuestions.length;
🤖 Prompt for AI Agents
In src/mastra/tools/extractLearningsTool.ts around lines 129-130, remove the
unnecessary nullish coalescing on .length: parsed.data.learning.length and
parsed.data.followUpQuestions.length are guaranteed numbers after schema
validation, so delete the "?? 0" fallbacks and use the .length values directly;
adjust any related variable typings if needed to reflect they will always be
numbers.

Comment on lines +140 to 152
if (typeof agent.stream === 'function') {
const stream = await agent.stream(prompt) as MastraModelOutput | undefined
if (stream?.fullStream) {
await stream.fullStream.pipeTo(writer as unknown as WritableStream)
} else if (stream.textStream) {
} else if (stream?.textStream) {
await stream.textStream.pipeTo(writer as unknown as WritableStream)
}
resultText = (await stream.text) ?? ''
const text = stream?.text ? await stream.text : undefined
resultText = text ?? ''
} else {
const result = await agentWithStream.generate(prompt)
const result = await agent.generate(prompt)
resultText = result.text
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Consider extracting duplicated streaming logic into a helper function.

The streaming pattern (check for stream function, call agent.stream(), pipe fullStream or textStream, extract text) is repeated across all four chart tools. This violates DRY principles and increases maintenance burden.

// Suggested helper in a shared utility file
async function executeAgentWithStreaming(
  agent: { stream?: Function; generate: Function },
  prompt: string,
  writer?: unknown
): Promise<string> {
  if (typeof agent.stream === 'function') {
    const stream = await agent.stream(prompt) as MastraModelOutput | undefined;
    if (stream?.fullStream && writer) {
      await stream.fullStream.pipeTo(writer as unknown as WritableStream);
    } else if (stream?.textStream && writer) {
      await stream.textStream.pipeTo(writer as unknown as WritableStream);
    }
    return stream?.text ? await stream.text : '';
  }
  const result = await agent.generate(prompt);
  return result.text;
}
🤖 Prompt for AI Agents
In src/mastra/tools/financial-chart-tools.ts around lines 140 to 152, the
streaming and fallback logic for calling agent.stream() or agent.generate() is
duplicated; extract that block into a shared helper function (e.g., in a
utilities module) that accepts the agent, prompt, and optional writer, performs
the typeof agent.stream check, awaits agent.stream(prompt) when available, pipes
fullStream or textStream to the writer when present, awaits and returns
stream.text (or ''), and otherwise calls agent.generate(prompt) and returns
result.text; replace the repeated blocks in all four chart tools with calls to
this helper.

Comment on lines +142 to 143
if (stream?.fullStream) {
await stream.fullStream.pipeTo(writer as unknown as WritableStream)
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

Same unsafe WritableStream cast as in editor-agent-tool.

This cast pattern writer as unknown as WritableStream is repeated across all chart tools. If the writer is not a valid WritableStream, this will fail at runtime. See earlier comment on editor-agent-tool for suggested fix.

🤖 Prompt for AI Agents
In src/mastra/tools/financial-chart-tools.ts around lines 142-143 the code
unsafely casts writer as unknown as WritableStream before calling
stream.fullStream.pipeTo(writer), which can throw at runtime if writer is not a
web WritableStream; replace the blind cast with a safe conversion/guard: detect
the writer type at runtime (e.g., if it already implements WritableStream-like
pipeTo/abort/closed methods, or if it's a Node.js Writable stream) and either
convert Node writable to a web WritableStream (or wrap the web stream around
Node writer) or call an appropriate pipe method for that writer; factor this
logic into a small helper (e.g., ensureWritableStream(writer): WritableStream)
and use it here so pipeTo is only invoked on a verified WritableStream, and
throw a clear error if conversion is not possible.

Comment on lines +147 to +148
const text = stream?.text ? await stream.text : undefined
resultText = text ?? ''
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Potential issue with conditional await on stream.text.

The pattern stream?.text ? await stream.text : undefined is correct if stream.text is a Promise. However, if stream.text is already resolved (synchronous), the conditional check stream?.text would be truthy and await would work fine. The pattern is safe but could be simplified:

-        const text = stream?.text ? await stream.text : undefined
-        resultText = text ?? ''
+        resultText = (await stream?.text) ?? ''
📝 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
const text = stream?.text ? await stream.text : undefined
resultText = text ?? ''
resultText = (await stream?.text) ?? ''
🤖 Prompt for AI Agents
In src/mastra/tools/financial-chart-tools.ts around lines 147-148, simplify the
conditional await: replace the two-line pattern that reads stream?.text ? await
stream.text : undefined and then sets resultText to text ?? '' with a single
expression that awaits stream.text if present and defaults to empty string (use
parentheses so await applies to the optional property), then assign that value
to resultText.

@ssdeanx ssdeanx merged commit d7d9632 into main Dec 14, 2025
247 of 252 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 pull request removes test files and implements streaming improvements across multiple tools, focusing on standardizing progress events and nested agent streaming patterns. The changes update 11 test files, several tool implementations, agent configurations, and related infrastructure.

  • Test file cleanup: Deletion of 11 test files across various tool suites
  • Tool streaming pattern standardization: Adoption of MastraModelOutput and data-tool-progress events
  • Agent improvements: Addition of new agents and runtime context enhancements

Reviewed changes

Copilot reviewed 33 out of 34 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/mastra/tools/tests/*.test.ts Multiple test files deleted, removing test coverage
src/mastra/tools/financial-chart-tools.ts Standardized agent streaming pattern with fallback logic
src/mastra/tools/extractLearningsTool.ts Improved error handling and streaming with safe parsing
src/mastra/tools/evaluateResultTool.ts Added streaming support and consistent progress events
src/mastra/tools/editor-agent-tool.ts Implemented nested agent streaming with writer piping
src/mastra/tools/document-chunking.tool.ts Enhanced chunking with metadata sanitization and batch embedding
src/mastra/tools/copywriter-agent-tool.ts Standardized streaming pattern and progress events
src/mastra/tools/color-change-tool.ts New tool for background color changes
src/mastra/tools/AGENTS.md Documentation updates for progress event format
src/mastra/index.ts Added new agents and comprehensive middleware
src/mastra/agents/researchAgent.ts Added runtime context fields for userId and researchPhase
eslint.config.js Removed pattern matching from unused vars rule
app/workflows/providers/workflow-context.tsx Normalized legacy events into progress events
app/networks/providers/network-context.tsx Improved event parsing with type safety
app/chat/providers/chat-context.tsx Fixed unused parameter warning
memory-bank/* Added task tracking documentation
Comments suppressed due to low confidence (2)

src/mastra/tools/tests/web-scraper-tool.test.ts:1

  • This test file for web-scraper-tool has been removed. Given that other similar tool files have comprehensive test coverage, this removal significantly reduces test coverage for the web scraping functionality, which includes critical components like HtmlProcessor, ValidationUtils, and multiple scraping tools (webScraperTool, batchWebScraperTool, etc.).
    src/mastra/tools/tests/weather-tool.test.ts:1
  • Removal of weather-tool tests eliminates coverage for temperature unit handling, location resolution, API error handling, and tracing context. This tool handles external API calls and various edge cases that should be tested.

await writer?.custom({ type: 'data-tool-progress', data: { status: 'in-progress', message: '🤖 Generating insights with learning agent', stage: 'extract-learnings' }, id: 'extract-learnings' });

const truncatedContent = (result?.content ?? '').slice(0, 8000);
const contentWithTruncation = (result?.content ?? '').length > 8000 ? truncatedContent + 'AAAA...' : truncatedContent;
Copy link

Copilot AI Dec 14, 2025

Choose a reason for hiding this comment

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

The truncation marker 'AAAA...' appears to be a debug placeholder instead of a meaningful ellipsis. This should be changed to a standard ellipsis '...' or a more descriptive truncation indicator.

Suggested change
const contentWithTruncation = (result?.content ?? '').length > 8000 ? truncatedContent + 'AAAA...' : truncatedContent;
const contentWithTruncation = (result?.content ?? '').length > 8000 ? truncatedContent + '...' : truncatedContent;

Copilot uses AI. Check for mistakes.
chunkOverlap: inputData.chunkOverlap,
},
id: `chunk_${Date.now()}_${index}`,
id: chunk.metadata?.id ?? `chunk_${Date.now()}_${randomUUID()}`,
Copy link

Copilot AI Dec 14, 2025

Choose a reason for hiding this comment

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

Using Date.now() in the ID generation for every chunk may create collisions if multiple chunks are processed in the same millisecond. Consider using only randomUUID() or a sequential counter combined with a session UUID for better uniqueness guarantees.

Suggested change
id: chunk.metadata?.id ?? `chunk_${Date.now()}_${randomUUID()}`,
id: chunk.metadata?.id ?? `chunk_${index}_${randomUUID()}`,

Copilot uses AI. Check for mistakes.

// userId: prefer explicit header, otherwise try to parse from a bearer token (format: "Bearer user:<id>")
let userId = headerUserId
if (!userId && authHeader !== null && authHeader !== '' && authHeader.startsWith('Bearer ')) {
Copy link

Copilot AI Dec 14, 2025

Choose a reason for hiding this comment

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

The condition checks for both !== null and !== '' separately before calling startsWith(). Since empty string is falsy, these conditions can be simplified to if (!userId && authHeader && authHeader.startsWith('Bearer ')) for better readability.

Copilot uses AI. Check for mistakes.
Comment on lines +65 to +66
'no-unused-vars': ['warn', { }],
'@typescript-eslint/no-unused-vars': ['warn', {}],
Copy link

Copilot AI Dec 14, 2025

Choose a reason for hiding this comment

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

Removing the argsIgnorePattern and varsIgnorePattern options means variables/parameters prefixed with underscore will now trigger warnings. This breaks a common convention for explicitly unused variables. Consider restoring these patterns to allow intentional unused parameters marked with underscore.

Suggested change
'no-unused-vars': ['warn', { }],
'@typescript-eslint/no-unused-vars': ['warn', {}],
'no-unused-vars': [
'warn',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
},
],
'@typescript-eslint/no-unused-vars': [
'warn',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
},
],

Copilot uses AI. Check for mistakes.

const sendMessage = useCallback(
(text: string, _files?: File[]) => {
(text: string, files?: File[]) => {
Copy link

Copilot AI Dec 14, 2025

Choose a reason for hiding this comment

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

The files parameter was renamed from _files (explicitly unused) to files, but it's still not used in the function body. This will now trigger an unused variable warning. Either use the parameter or revert to _files to indicate intentional non-use.

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