Conversation
- 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.
Learn moreAll Green is an AI agent that automatically: ✅ Addresses code review comments ✅ Fixes failing CI checks ✅ Resolves merge conflicts |
|
🤖 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. |
|
Caution Review failedThe pull request is closed. Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings. WalkthroughAdds standardized streaming support and data-tool-progress events across many Mastra tools and client providers, normalizes legacy progress formats, updates ESLint unused-var rules, registers new agents and middleware, introduces a browser color-change tool, refactors document chunking/embeddings, and removes many tool test files. Changes
Sequence Diagram(s)sequenceDiagram
participant Tool as Tool (e.g., Copywriter)
participant Mastra as Mastra/AgentRegistry
participant Agent as Mastra Agent
participant Writer as Writer/Client Stream
participant Tracer as Tracing/Span
Tool->>Mastra: getAgent(name) or fallback local
Mastra-->>Tool: Agent (may be undefined)
Tool->>Agent: check for stream()
alt stream available
Tool->>Agent: agent.stream(prompt)
activate Agent
Agent-->>Tool: MastraModelOutput (textStream/fullStream/object)
Tool->>Writer: emit data-tool-progress (in-progress)
Tool->>Writer: pipe textStream/fullStream -> client
Tool->>Tool: accumulate resultText / parse object
deactivate Agent
else fallback
Tool->>Agent: agent.generate(prompt)
Agent-->>Tool: response (text/object)
Tool->>Tool: parse response text/object
end
alt error
Tool->>Tracer: record exception, set span ERROR
Tool->>Writer: emit data-tool-progress (done/error)
Tool-->>Client: return failure
else success
Tool->>Tracer: record metrics, end span
Tool->>Writer: emit data-tool-progress (done)
Tool-->>Client: return result
end
Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: ASSERTIVE Plan: Pro 📒 Files selected for processing (4)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
🤖 I'm sorry @ssdeanx, but I was unable to process your request. Please see the logs for more details. |
Summary of ChangesHello @ssdeanx, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request introduces a significant standardization effort for streaming and progress event conventions across various tools and client-side components. It involves refactoring several agent-based tools to adopt a unified streaming pattern and updating client-side parsers to handle these new events. Additionally, the document chunking and reranking capabilities have been enhanced, and a substantial number of outdated test files have been removed to clean up the codebase and align with current development practices. Documentation has also been updated to reflect these changes. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
Greptile OverviewGreptile SummaryThis PR standardizes streaming and progress event patterns across the codebase by replacing Key Changes
Issues Found
Confidence Score: 3/5
Important Files ChangedFile Analysis
Sequence DiagramsequenceDiagram
participant Client
participant Tool as Tool (e.g. copywriter-agent-tool)
participant Context as RuntimeContext
participant Agent as Agent (copywriter/editor/etc)
participant Writer as Context Writer
Client->>Tool: execute(inputData, context)
Tool->>Writer: custom({ type: 'data-tool-progress', status: 'in-progress' })
Tool->>Context: mastra.getAgent('agentName')
alt Agent found in context
Context-->>Tool: return agent instance
else Agent not found
Tool->>Tool: fallback to local import
end
Tool->>Tool: validate agent has generate or stream method
alt No valid methods
Tool->>Writer: custom({ type: 'data-tool-progress', status: 'done', message: 'error' })
Tool-->>Client: return error
end
alt Agent has stream method
Tool->>Agent: stream(prompt)
Agent-->>Tool: MastraModelOutput { textStream, fullStream, text, object }
Tool->>Writer: custom({ type: 'data-tool-progress', message: 'Streaming...' })
alt Has textStream
Tool->>Writer: textStream.pipeTo(writer)
else Has fullStream
Tool->>Writer: fullStream.pipeTo(writer)
end
Agent-->>Tool: await stream.text
Tool->>Tool: parse response object or text
else Agent has generate only
Tool->>Agent: generate(prompt)
Agent-->>Tool: { text, object }
Tool->>Tool: parse response object or text
end
Tool->>Writer: custom({ type: 'data-tool-progress', status: 'done' })
Tool-->>Client: return result
|
| data: { | ||
| status: "in-progress", // "in-progress" | "done" | ||
| message: "Descriptive progress message...", | ||
| message: "Descriptive progress message ${inputData.context}....`,", |
There was a problem hiding this comment.
syntax: malformed template string in documentation example - has mismatched quotes and backticks
| message: "Descriptive progress message ${inputData.context}....`,", | |
| message: "Descriptive progress message...", |
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/mastra/tools/AGENTS.md
Line: 105:105
Comment:
**syntax:** malformed template string in documentation example - has mismatched quotes and backticks
```suggestion
message: "Descriptive progress message...",
```
How can I resolve this? If you propose a fix, please make it concise.| 'no-unused-vars': ['warn', { }], | ||
| '@typescript-eslint/no-unused-vars': ['warn', {}], |
There was a problem hiding this comment.
logic: removed ignore patterns for underscore-prefixed variables/args - this will cause warnings for intentionally unused parameters like _context or _req
| 'no-unused-vars': ['warn', { }], | |
| '@typescript-eslint/no-unused-vars': ['warn', {}], | |
| 'no-unused-vars': ['warn', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }], | |
| '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }], |
Prompt To Fix With AI
This is a comment left during a code review.
Path: eslint.config.js
Line: 65:66
Comment:
**logic:** removed ignore patterns for underscore-prefixed variables/args - this will cause warnings for intentionally unused parameters like `_context` or `_req`
```suggestion
'no-unused-vars': ['warn', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
'@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
```
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
Code Review
This pull request primarily focuses on standardizing tool streaming and progress event conventions across various agents and client-side providers, as detailed in the newly added TASK001-update-2025-12-14.md documentation. Key changes include updating copywriter-agent-tool.ts, editor-agent-tool.ts, evaluateResultTool.ts, extractLearningsTool.ts, and financial-chart-tools.ts to use streaming APIs (agent.stream) with MastraModelOutput and emit data-tool-progress events, replacing older data-tool-agent messages. Client-side parsers in app/networks/providers/network-context.tsx and app/workflows/providers/workflow-context.tsx were updated to normalize these legacy agent events into the new progress event format. The document-chunking.tool.ts received significant updates, including new helper functions for metadata sanitization and weight normalization, batching for embedding generation, improved error handling, and refined chunking strategies. Additionally, eslint.config.js was modified to remove argsIgnorePattern and varsIgnorePattern from unused variable rules, and AGENTS.md was updated with the new conventions and a typo fix. Review comments highlighted the complexity of message extraction logic in client-side providers, a typo in the AGENTS.md example, inconsistency in JSON parsing fallbacks in copywriter-agent-tool.ts, and verbosity in text extraction from metadata in document-chunking.tool.ts.
| const msg = typeof dataObj?.text === 'string' ? dataObj.text | ||
| : typeof dataObj?.message === 'string' ? dataObj.message | ||
| : typeof eventData?.message === 'string' ? eventData.message | ||
| : typeof eventData?.text === 'string' ? eventData.text | ||
| : '' |
There was a problem hiding this comment.
| 'no-unused-vars': ['warn', { }], | ||
| '@typescript-eslint/no-unused-vars': ['warn', {}], |
There was a problem hiding this comment.
Removing the argsIgnorePattern and varsIgnorePattern options means we can no longer mark intentionally unused variables with an underscore to suppress warnings. This might lead to unnecessary warnings for variables that are required by an interface but not used in the implementation. Was this change intentional? If so, what is the new convention for handling such cases?
| 'no-unused-vars': ['warn', { }], | |
| '@typescript-eslint/no-unused-vars': ['warn', {}], | |
| 'no-unused-vars': ['warn', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }], | |
| '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }], |
| data: { | ||
| status: "in-progress", // "in-progress" | "done" | ||
| message: "Descriptive progress message...", | ||
| message: "Descriptive progress message ${inputData.context}....`,", |
There was a problem hiding this comment.
There appears to be a typo in the example message string. It contains an extra backtick and a comma at the end, which could be confusing for developers referencing this documentation.
| message: "Descriptive progress message ${inputData.context}....`,", | |
| message: `Descriptive progress message ${inputData.context}....`, |
| if (writer && typeof agentWithStream.stream === 'function') { | ||
| const stream = await agentWithStream.stream(prompt) | ||
| const text = (await stream?.text) ?? '' | ||
| const responseObject = stream?.object ?? (() => { try { return JSON.parse(text) } catch { return {} } })() |
There was a problem hiding this comment.
The fallback for JSON parsing in the streaming path returns an empty object ({}) on failure, while the fallback in the generate path (line 233) returns undefined. For consistency and clearer intent, it would be better to have both fallbacks return undefined and then handle the undefined case explicitly.
| const responseObject = stream?.object ?? (() => { try { return JSON.parse(text) } catch { return {} } })() | |
| const responseObject = stream?.object ?? (() => { try { return JSON.parse(text) } catch { return undefined } })() |
| initialResults.map((result) => ({ | ||
| id: result.id, | ||
| text: result.metadata?.text as string, | ||
| text: (result.metadata?.text as string) ?? (typeof result.metadata?.text === 'undefined' ? '' : String(result.metadata?.text)), |
There was a problem hiding this comment.
This logic to safely extract text from metadata is a bit verbose. It can be simplified using String() and nullish coalescing, which would be more concise and achieve the same goal of safely converting the value to a string, handling null, undefined, and other types gracefully.
| text: (result.metadata?.text as string) ?? (typeof result.metadata?.text === 'undefined' ? '' : String(result.metadata?.text)), | |
| text: String(result.metadata?.text ?? ''), |
There was a problem hiding this comment.
Pull request overview
This PR performs maintenance and standardization work by removing 11 outdated test files and documenting streaming/progress convention updates. The changes align tool implementations with a new data-tool-progress event pattern and normalize nested-agent streaming across multiple tools.
Key Changes
- Test File Removal: Deleted 11 test files for various tools (web-scraper, weather, serpapi, data validation, document chunking, etc.)
- Streaming Convention Updates: Standardized tools to use
data-tool-progressevents andMastraModelOutputtyping - Client-Side Normalization: Updated UI providers to handle legacy
data-tool-agentevents
Reviewed changes
Copilot reviewed 29 out of 30 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
src/mastra/tools/tests/*.test.ts (11 files) |
Removed outdated test files - tests appear comprehensive but deletion reduces coverage |
memory-bank/tasks/TASK001-update-2025-12-14.md |
Added documentation of streaming convention changes |
src/mastra/tools/financial-chart-tools.ts |
Updated to use new streaming pattern with agent fallbacks |
src/mastra/tools/extractLearningsTool.ts |
Migrated from data-tool-agent to data-tool-progress events |
src/mastra/tools/evaluateResultTool.ts |
Added streaming support with MastraModelOutput |
src/mastra/tools/editor-agent-tool.ts |
Implemented nested agent streaming pattern |
src/mastra/tools/document-chunking.tool.ts |
Enhanced with embedding batching and metadata sanitization |
src/mastra/tools/copywriter-agent-tool.ts |
Updated streaming implementation |
src/mastra/tools/AGENTS.md |
Updated documentation with progress event format |
app/workflows/providers/workflow-context.tsx |
Normalized legacy event handling |
app/networks/providers/network-context.tsx |
Normalized legacy event handling |
app/chat/providers/chat-context.tsx |
Minor parameter rename |
eslint.config.js |
Removed underscore ignore patterns for unused variables |
memory-bank/*.md (3 files) |
Updated memory bank with streaming conventions |
|
|
||
| const sendMessage = useCallback( | ||
| (text: string, _files?: File[]) => { | ||
| (text: string, files?: File[]) => { |
There was a problem hiding this comment.
The unused parameter files (renamed from _files) will now trigger ESLint warnings due to the ESLint configuration change that removed the underscore ignore pattern. If this parameter is intentionally unused but required by the function signature, it should be prefixed with underscore to document this intent.
| (text: string, files?: File[]) => { | |
| (text: string, _files?: File[]) => { |
| data: { | ||
| status: "in-progress", // "in-progress" | "done" | ||
| message: "Descriptive progress message...", | ||
| message: "Descriptive progress message ${inputData.context}....`,", |
There was a problem hiding this comment.
The string literal template interpolation syntax has incorrect quoting. The backtick for template literal starts mid-string and ends with a mismatched quote character. This appears to be:
message: "Descriptive progress message ${inputData.context}....`,",
Should likely be either a full template literal or a regular string without interpolation.
| message: "Descriptive progress message ${inputData.context}....`,", | |
| message: `Descriptive progress message ${inputData.context}....`, |
| 'no-unused-vars': ['warn', { }], | ||
| '@typescript-eslint/no-unused-vars': ['warn', {}], |
There was a problem hiding this comment.
The ESLint configuration change removes important ignore patterns for unused variables starting with underscore. The empty object {} means ALL unused variables will now trigger warnings, even those intentionally prefixed with _ to indicate they're unused but required (e.g., function signatures matching interfaces).
This will likely cause numerous false-positive warnings throughout the codebase where developers intentionally use _ prefix to indicate "I know this parameter is unused but it's required by the signature".
| 'no-unused-vars': ['warn', { }], | |
| '@typescript-eslint/no-unused-vars': ['warn', {}], | |
| 'no-unused-vars': [ | |
| 'warn', | |
| { | |
| argsIgnorePattern: '^_', | |
| varsIgnorePattern: '^_', | |
| }, | |
| ], | |
| '@typescript-eslint/no-unused-vars': [ | |
| 'warn', | |
| { | |
| argsIgnorePattern: '^_', | |
| varsIgnorePattern: '^_', | |
| }, | |
| ], |
There was a problem hiding this comment.
Actionable comments posted: 23
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (10)
src/mastra/tools/document-chunking.tool.ts (4)
198-201:mastraChunkernever emits adoneprogress event (success/error).Guidelines require tools to emit
data-tool-progresswithstatus: 'done'.mastraChunkeronly emitsin-progress. Adddoneon both success and failure.logStepEnd('mastra-chunker', output, totalProcessingTime) - + await context?.writer?.custom({ + type: 'data-tool-progress', + data: { status: 'done', message: `✅ Processed ${chunks.length} chunks successfully`, stage: 'mastra:chunker' }, + id: 'mastra:chunker', + }) return output } catch (error) { @@ span.setStatus({ code: SpanStatusCode.ERROR, message: errorMessage }); + + await context?.writer?.custom({ + type: 'data-tool-progress', + data: { status: 'done', message: `❌ Failed: ${errorMessage}`, stage: 'mastra:chunker' }, + id: 'mastra:chunker', + }) return { success: false,As per coding guidelines, tools must emit
data-tool-progresswithstatusandstage.Also applies to: 384-411
652-699: Index creation + dimension mismatch is being swallowed; logging should be actionable.If
createIndexfails due to dimension mismatch (or perms), continuing toupsertcan produce confusing runtime failures. At minimum, logindexName, intendeddimension, and decide whether to skip upsert when the index cannot be ensured.try { await pgVector.createIndex({ indexName: inputData.indexName, dimension: embeddings[0]?.length || 0 }) } catch (idxErr) { - log.info('createIndex skipped or failed', { error: (idxErr as Error)?.message ?? idxErr }) + logError('mdocument-chunker-createIndex', idxErr, { + indexName: inputData.indexName, + dimension: embeddings[0]?.length || 0, + }) }Based on coding guidelines, keep comments/logging accurate and actionable.
719-747: Emitdoneprogress on error paths too (mdocument chunker).
mdocumentChunkeremitsdoneonly on success; in errors it returns without a final progress event. Mirror the success behavior incatch(and consider including the error message).
940-965: Emitdoneprogress on reranker failures as well.
documentRerankerToolemitsdoneon success and “no results”, but not in the error path. Add a finaldoneevent incatchbefore returning. As per coding guidelines, tools must emitdata-tool-progresscompletion consistently.src/mastra/tools/AGENTS.md (1)
1-1: Inconsistent date format in metadata.The
last_updatedfield was changed from ISO 8601 format with time and timezone (2025-11-27T00:00:00Z) to a plain date (2025-12-14). This inconsistency may break tooling that parses this metadata and expects a standardized format.Apply this diff to maintain consistent ISO 8601 formatting:
-<!-- AGENTS-META {\"title\":\"Mastra Tools\",\"version\":\"2.2.0\",\"last_updated\":\"2025-11-27T00:00:00Z\",\"applies_to\":\"/src/mastra/tools\",\"tags\":[\"layer:backend\",\"domain:rag\",\"type:tools\",\"status\":\"stable\"]} --> +<!-- AGENTS-META {\"title\":\"Mastra Tools\",\"version\":\"2.2.0\",\"last_updated\":\"2025-12-14T00:00:00Z\",\"applies_to\":\"/src/mastra/tools\",\"tags\":[\"layer:backend\",\"domain:rag\",\"type:tools\",\"status\":\"stable\"]} -->app/workflows/providers/workflow-context.tsx (1)
322-340: Legacy event normalization implemented correctly.The normalization logic effectively handles multiple legacy event formats by:
- Extracting message text from various nested field paths with fallbacks
- Deriving stage from available metadata or part type
- Only emitting progress events when meaningful message content exists
The type guards (
typeof === 'string') ensure type safety, and the tolerant extraction pattern handles variations in legacy event structures appropriately.For improved readability, consider extracting the message derivation into a helper function:
// Before the loop or as a module-level helper function extractMessageFromLegacyEvent(eventData?: Record<string, unknown>): string { const dataObj = eventData?.data as Record<string, unknown> | undefined if (typeof dataObj?.text === 'string') return dataObj.text if (typeof dataObj?.message === 'string') return dataObj.message if (typeof eventData?.message === 'string') return eventData.message if (typeof eventData?.text === 'string') return eventData.text return 'Agent executing tool' } // In the event handler const msg = extractMessageFromLegacyEvent(eventData)This reduces the cognitive complexity of the inline ternary chain on lines 327-328.
app/networks/providers/network-context.tsx (1)
298-324: Legacy event normalization correctly implemented for network context.The normalization logic properly handles legacy event formats and appropriately extracts agentId for multi-agent network scenarios. The pattern is consistent with the workflow-context.tsx implementation.
For improved maintainability, consider extracting the message derivation into a shared helper function (similar to the suggestion for workflow-context.tsx):
// Could be shared between network-context.tsx and workflow-context.tsx function extractLegacyEventMessage(eventData?: Record<string, unknown>): string { const dataObj = eventData?.data as Record<string, unknown> | undefined return ( (typeof dataObj?.text === 'string' ? dataObj.text : null) ?? (typeof dataObj?.message === 'string' ? dataObj.message : null) ?? (typeof eventData?.message === 'string' ? eventData.message : null) ?? (typeof eventData?.text === 'string' ? eventData.text : null) ?? '' ) }This would reduce duplication across context providers and make the extraction logic easier to test and maintain.
src/mastra/tools/copywriter-agent-tool.ts (1)
180-183: Incomplete implementation: 'general' contentType throws an error.The
contentTypeinput schema includes'general'as a valid option (Line 27), but the switch statement throws an error for this case. This will cause runtime failures for users selecting 'general'.Either implement the 'general' case or remove it from the input schema:
case 'general': { - throw new Error('Not implemented yet: "general" case') + prompt += + '\n\nCreate clear, well-structured content appropriate for the topic and audience.' + break }src/mastra/tools/financial-chart-tools.ts (2)
1-736: Significant code duplication across all four chart tools.The streaming logic, JSON parsing with
```jsonregex extraction, and progress event emission are nearly identical in all four tools. Consider extracting shared helpers.Example helpers:
// Shared streaming helper async function streamFromAgent( agent: Agent, prompt: string, writer?: WritableStream ): 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); } else if (stream?.textStream && writer) { await stream.textStream.pipeTo(writer); } return (await stream?.text) ?? ''; } const result = await agent.generate(prompt); return result.text; } // Shared JSON extraction function extractJsonFromResponse(text: string): unknown { const jsonMatch = /```json\s*([\s\S]*?)\s*```/.exec(text); if (jsonMatch?.[1]) return JSON.parse(jsonMatch[1]); return JSON.parse(text); }
196-198: UseSpanStatusCode.ERRORinstead of magic number2.Other tools use the named constant
SpanStatusCode.ERRORfrom@opentelemetry/api. Using the magic number2reduces readability and maintainability.- span.setStatus({ code: 2, message: errorMsg }) + span.setStatus({ code: SpanStatusCode.ERROR, message: errorMsg })Note: This pattern appears at Lines 197, 362, 546, 724 - all should use the named constant. You'll need to add
SpanStatusCodeto the import on Line 1.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (30)
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/tools/AGENTS.md(4 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/json-to-csv.tool.test.ts
- src/mastra/tools/tests/extractLearningsTool.test.ts
- src/mastra/tools/tests/serpapi-academic-local.tool.test.ts
- src/mastra/tools/tests/evaluateResultTool.test.ts
- src/mastra/tools/tests/serpapi-news-trends.tool.test.ts
- src/mastra/tools/tests/csv-to-json.tool.test.ts
- src/mastra/tools/tests/editor-agent-tool.test.ts
- src/mastra/tools/tests/copywriter-agent-tool.test.ts
- src/mastra/tools/tests/web-scraper-tool.test.ts
- src/mastra/tools/tests/document-chunking.tool.test.ts
- src/mastra/tools/tests/serpapi-shopping.tool.test.ts
- src/mastra/tools/tests/serpapi-search.tool.test.ts
- src/mastra/tools/tests/weather-tool.test.ts
- src/mastra/tools/tests/data-file-manager.test.ts
- src/mastra/tools/tests/data-validator.tool.test.ts
🧰 Additional context used
📓 Path-based instructions (22)
**/*.md
📄 CodeRabbit inference engine (.github/instructions/markdown.instructions.md)
**/*.md: Use appropriate heading levels (H2, H3, etc.) to structure markdown content. Do not use H1 headings, as these will be generated from the title. Use##for H2 and###for H3 in a hierarchical manner. Recommend restructuring if content includes H4 or higher levels.
Use bullet points (with-) or numbered lists (with1.) for lists in markdown. Indent nested lists with two spaces and ensure proper indentation and spacing.
Use fenced code blocks (triple backticks) for code snippets in markdown. Specify the language after the opening backticks for syntax highlighting (e.g.,csharp).
Use proper markdown syntax for links:[link text](URL). Ensure that link text is descriptive and URLs are valid and accessible.
Use proper markdown syntax for images:. Include a brief description of the image in the alt text for accessibility.
Use markdown tables (with|delimiters) for tabular data. Ensure proper formatting, alignment, and inclusion of headers.
Limit line length to 80 characters in markdown for readability. Use soft line breaks for long paragraphs.
Use appropriate whitespace in markdown to separate sections and improve readability. Use blank lines between sections and avoid excessive whitespace.
Include YAML front matter at the beginning of markdown files with required metadata fields:post_title,author1,post_slug,microsoft_alias,featured_image,categories(from /categories.txt),tags,ai_note,summary, andpost_date.
Files:
memory-bank/memory-bank-instructions.mdmemory-bank/tasks/TASK001-tool-streaming.mdmemory-bank/copilot-rules.mdsrc/mastra/tools/AGENTS.mdmemory-bank/tasks/TASK001-update-2025-12-14.md
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (.github/instructions/next-js.instructions.md)
**/*.{js,jsx,ts,tsx}: Usenext/dynamicfor dynamic imports to load components only when needed, improving initial load time.
Usenext/imagecomponent for automatic image optimization, including lazy loading and responsive images.
Use React.memo to prevent unnecessary re-renders of components.
Use the<Link prefetch>tag to prefetch pages that are likely to be visited.
Use getServerSideProps, getStaticProps, or server components for fetching data on the server-side.
Use SWR or React Query for client-side data fetching and caching.
Use CSS Modules, Styled Components, or Tailwind CSS for component-level styling. Prefer Tailwind CSS for rapid development.
Use React Context, Zustand, Jotai, or Recoil for managing global state. Avoid Redux unless necessary.
Usereact-hook-formfor managing forms and validation.
Only fetch the data that is needed by the component to avoid over-fetching.
Avoid long-running synchronous operations in the main thread to prevent blocking.
Always usesetStateor hooks to update state instead of mutating state directly.
Include a complete dependency array inuseEffecthooks to prevent unexpected behavior.
Avoid writing server-side code in client components to prevent exposing secrets or causing unexpected behavior.
Usetry...catchblocks for handling errors in asynchronous operations.
Implement error boundary components usinggetDerivedStateFromErrororcomponentDidCatchlifecycle methods.
Sanitize user input to prevent Cross-Site Scripting (XSS) attacks. Be especially careful when rendering HTML directly from user input.
Store authentication tokens in HTTP-only cookies or local storage securely.
Implement role-based access control to restrict access to sensitive resources.
Clean up event listeners and timers inuseEffecthooks to avoid memory leaks.
Only update state when necessary to reduce the number of re-renders and improve performance.
Use immutable data structures and avoid mutating data directly to prevent unexpected...
Files:
src/mastra/tools/extractLearningsTool.tssrc/mastra/tools/evaluateResultTool.tssrc/mastra/tools/financial-chart-tools.tseslint.config.jssrc/mastra/tools/editor-agent-tool.tsapp/networks/providers/network-context.tsxsrc/mastra/tools/copywriter-agent-tool.tsapp/workflows/providers/workflow-context.tsxsrc/mastra/tools/document-chunking.tool.tsapp/chat/providers/chat-context.tsx
**/*.{js,ts}
📄 CodeRabbit inference engine (.github/instructions/next-js.instructions.md)
Use parameterized queries or an ORM to prevent SQL injection attacks.
Files:
src/mastra/tools/extractLearningsTool.tssrc/mastra/tools/evaluateResultTool.tssrc/mastra/tools/financial-chart-tools.tseslint.config.jssrc/mastra/tools/editor-agent-tool.tssrc/mastra/tools/copywriter-agent-tool.tssrc/mastra/tools/document-chunking.tool.ts
src/mastra/tools/**/*.ts
📄 CodeRabbit inference engine (src/mastra/AGENTS.md)
src/mastra/tools/**/*.ts: Use thecreateToolpattern with Zod schemas when adding new tools undersrc/mastra/tools
Use explicit Zod schemas for every tool input/outputImplement tools using createTool({ id, inputSchema, outputSchema, execute }) pattern with strict Zod schemas
Files:
src/mastra/tools/extractLearningsTool.tssrc/mastra/tools/evaluateResultTool.tssrc/mastra/tools/financial-chart-tools.tssrc/mastra/tools/editor-agent-tool.tssrc/mastra/tools/copywriter-agent-tool.tssrc/mastra/tools/document-chunking.tool.ts
src/mastra/{tools,workflows}/**/*.ts
📄 CodeRabbit inference engine (src/mastra/AGENTS.md)
Use
RuntimeContextto enforce access control in tools and workflows
Files:
src/mastra/tools/extractLearningsTool.tssrc/mastra/tools/evaluateResultTool.tssrc/mastra/tools/financial-chart-tools.tssrc/mastra/tools/editor-agent-tool.tssrc/mastra/tools/copywriter-agent-tool.tssrc/mastra/tools/document-chunking.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/tools/extractLearningsTool.tssrc/mastra/tools/evaluateResultTool.tssrc/mastra/tools/financial-chart-tools.tseslint.config.jssrc/mastra/tools/editor-agent-tool.tsapp/networks/providers/network-context.tsxsrc/mastra/tools/copywriter-agent-tool.tsapp/workflows/providers/workflow-context.tsxsrc/mastra/tools/document-chunking.tool.tsapp/chat/providers/chat-context.tsx
**/*.{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 thenext-devtools-mcpserver for all Next.js related queries
Files:
src/mastra/tools/extractLearningsTool.tssrc/mastra/tools/evaluateResultTool.tssrc/mastra/tools/financial-chart-tools.tseslint.config.jssrc/mastra/tools/editor-agent-tool.tsapp/networks/providers/network-context.tsxsrc/mastra/tools/copywriter-agent-tool.tsapp/workflows/providers/workflow-context.tsxsrc/mastra/tools/document-chunking.tool.tsapp/chat/providers/chat-context.tsx
**/*.{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/tools/extractLearningsTool.tssrc/mastra/tools/evaluateResultTool.tssrc/mastra/tools/financial-chart-tools.tssrc/mastra/tools/editor-agent-tool.tsapp/networks/providers/network-context.tsxsrc/mastra/tools/copywriter-agent-tool.tsapp/workflows/providers/workflow-context.tsxsrc/mastra/tools/document-chunking.tool.tsapp/chat/providers/chat-context.tsx
src/mastra/**/*
📄 CodeRabbit inference engine (src/AGENTS.md)
mastramodules can import fromutils, but must not import fromapporcli(excepttypes)
Files:
src/mastra/tools/extractLearningsTool.tssrc/mastra/tools/evaluateResultTool.tssrc/mastra/tools/AGENTS.mdsrc/mastra/tools/financial-chart-tools.tssrc/mastra/tools/editor-agent-tool.tssrc/mastra/tools/copywriter-agent-tool.tssrc/mastra/tools/document-chunking.tool.ts
**/*.{css,tsx,ts}
📄 CodeRabbit inference engine (AGENTS.md)
Use Tailwind CSS 4 with oklch color variables for styling
Files:
src/mastra/tools/extractLearningsTool.tssrc/mastra/tools/evaluateResultTool.tssrc/mastra/tools/financial-chart-tools.tssrc/mastra/tools/editor-agent-tool.tsapp/networks/providers/network-context.tsxsrc/mastra/tools/copywriter-agent-tool.tsapp/workflows/providers/workflow-context.tsxsrc/mastra/tools/document-chunking.tool.tsapp/chat/providers/chat-context.tsx
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/extractLearningsTool.tssrc/mastra/tools/evaluateResultTool.tssrc/mastra/tools/financial-chart-tools.tssrc/mastra/tools/editor-agent-tool.tssrc/mastra/tools/copywriter-agent-tool.tssrc/mastra/tools/document-chunking.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/extractLearningsTool.tssrc/mastra/tools/evaluateResultTool.tssrc/mastra/tools/financial-chart-tools.tssrc/mastra/tools/editor-agent-tool.tssrc/mastra/tools/copywriter-agent-tool.tssrc/mastra/tools/document-chunking.tool.ts
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
**/app/**
📄 CodeRabbit inference engine (.github/instructions/next-js.instructions.md)
Use the
app/directory structure for route handlers, server components, and client components (Next.js 13+). Prefer this over thepages/directory for new projects.
Files:
app/networks/providers/network-context.tsxapp/workflows/providers/workflow-context.tsxapp/chat/providers/chat-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/networks/providers/network-context.tsxapp/workflows/providers/workflow-context.tsxapp/chat/providers/chat-context.tsx
app/networks/**/*.tsx
📄 CodeRabbit inference engine (app/networks/AGENTS.md)
app/networks/**/*.tsx: UseuseChatfrom@ai-sdk/reactwithDefaultChatTransportfor streaming responses from the/networkroute 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
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/networks/providers/network-context.tsxapp/workflows/providers/workflow-context.tsxapp/chat/providers/chat-context.tsx
app/**/*.tsx
📄 CodeRabbit inference engine (AGENTS.md)
Use @ai-sdk/react for streaming and AI interactions in React components
Files:
app/networks/providers/network-context.tsxapp/workflows/providers/workflow-context.tsxapp/chat/providers/chat-context.tsx
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
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
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
🧬 Code graph analysis (5)
src/mastra/tools/extractLearningsTool.ts (2)
src/mastra/index.ts (1)
mastra(95-488)src/mastra/config/logger.ts (1)
log(14-18)
src/mastra/tools/evaluateResultTool.ts (1)
src/mastra/agents/evaluationAgent.ts (1)
evaluationAgent(18-140)
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/editor-agent-tool.ts (1)
src/mastra/agents/editorAgent.ts (1)
editorAgent(18-133)
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)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: CodeQL analysis (javascript-typescript)
- GitHub Check: Agent
- GitHub Check: Codacy Security Scan
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (12)
eslint.config.js (1)
65-66: No breaking change from previous configuration - this is a new ESLint setup.The eslint.config.js file is newly created (not modifying an existing configuration), and the codebase already has no underscore-prefixed unused variables in the linted source files. The concern about a breaking change requiring widespread refactoring is unfounded, as the strict
no-unused-varsrules are already compatible with the current codebase.Likely an incorrect or invalid review comment.
src/mastra/tools/document-chunking.tool.ts (2)
511-517: The review incorrectly targets the code. Lines 511–517 are correct; the bug exists elsewhere.According to Mastra RAG documentation,
MDocument.chunk()expectsseparators: string[](plural, array) for thecharacterstrategy.
- Lines 511–517 (mdocumentChunker): Already correctly use
separators: ['\n']✓- Lines ~255–261 (mastraChunker): Incorrectly use
separator: '\n'(singular) and should be fixed toseparators: ['\n']The review points to the wrong location and its suggested fix would make correct code incorrect.
Likely an incorrect or invalid review comment.
883-897: Verify thererank()function contract and result shape to ensure defensive text mapping is necessary.The defensive text selection pattern
(result.metadata?.text as string) ?? (typeof result.metadata?.text === 'undefined' ? '' : String(result.metadata?.text))suggests potential type safety issues between whatrerank()returns and what this tool expects. Without clear type definitions for the rerank result shape (specifically wheretext,score,metadata, andidfields are located), this pattern may indicate either:
- A type mismatch that needs addressing in the
rerank()contract- Unnecessary defensive code that can be simplified
If the rerank input/output types are documented but complex, consider extracting this mapping logic into a dedicated adapter function to improve readability and maintainability.
Also applies to lines 911-925.
src/mastra/tools/AGENTS.md (1)
135-136: LGTM!The added note effectively cross-references the task documentation and provides helpful context about the standardization effort.
src/mastra/tools/evaluateResultTool.ts (3)
78-89: LGTM: Error handling in streaming path is thorough.The error path correctly records the exception, sets span status to ERROR, ends the span, emits a final progress event, and returns a consistent failure response.
54-56: LGTM: Agent retrieval pattern is correct.The fallback pattern
context?.mastra?.getAgent?.('evaluationAgent') ?? evaluationAgentcorrectly prefers the runtime-registered agent while falling back to the imported agent.
64-70: The pipeTo() + await text pattern is valid and documented as the standard approach.The codebase documentation (
copilot-rules.md) explicitly recommends this exact pattern: pipetextStream/fullStreamto the writer for UI updates, then awaitstream.textfor final text. TheMastraModelOutputbuffers text independently, soawait stream.textdoes not fail afterpipeTo(). This pattern is consistently used across 10+ tool and workflow files.The type cast
as unknown as WritableStreamis a pragmatic workaround used throughout the codebase. WhileWritableStreamcompatibility should ideally be enforced at the context type level, this is a localized code quality issue rather than a runtime bug—most implementations function correctly. Consider using runtime type checks (as shown inweather-workflow.ts) for additional safety, but this is not blocking.src/mastra/tools/editor-agent-tool.ts (1)
149-155: LGTM: Return value construction with fallbacks.The return statement correctly provides fallback values for all fields, ensuring a valid response shape even when the agent returns unexpected data.
src/mastra/tools/copywriter-agent-tool.ts (3)
225-227: Unusual defensive try-catch aroundspan.setStatus.This defensive pattern isn't used in other tools and may mask underlying issues with the span's state. If
setStatuscan fail, consider investigating why rather than silently ignoring.Is there a known issue where
span.setStatuscan throw? If not, this try-catch may hide bugs.
212-222: LGTM: Response object handling with null guard.The
Boolean(responseObject) && typeof responseObject === 'object'check correctly handles the JavaScript quirk wheretypeof null === 'object'.
108-130: LGTM: Thorough agent capability validation.The validation for
generateandstreammethods with a graceful fallback return provides a good user experience when the agent is unavailable.src/mastra/tools/extractLearningsTool.ts (1)
59-74: LGTM: Graceful handling when Mastra or agent is unavailable.The early returns with meaningful messages and proper span cleanup provide a good user experience when the runtime context is incomplete.
|
|
||
| const sendMessage = useCallback( | ||
| (text: string, _files?: File[]) => { | ||
| (text: string, files?: File[]) => { |
There was a problem hiding this comment.
Inconsistent parameter naming: removed underscore from unused parameter.
The parameter name was changed from _files to files, but:
- The parameter is not used in the function body (lines 325-328)
- The interface definition at line 95 still uses
_fileswith the underscore prefix - Removing the underscore suggests the parameter should be used, but it isn't
The underscore prefix is a convention for intentionally unused parameters (especially important with no-unused-vars ESLint rules).
Either keep the underscore prefix for consistency:
- (text: string, files?: File[]) => {
+ (text: string, _files?: File[]) => {Or implement file handling if the parameter is meant to be used:
(text: string, files?: File[]) => {
if (!text.trim() || isLoading) {return}
setChatError(null)
- aiSendMessage({ text: text.trim() })
+ aiSendMessage({
+ text: text.trim(),
+ // Handle files if needed
+ })
},Note: The interface at line 95 should also be updated to match whichever approach you choose.
🤖 Prompt for AI Agents
In app/chat/providers/chat-context.tsx around line 324, the parameter name was
changed from `_files` to `files` but the parameter is unused (and the interface
at line 95 still uses `_files`), causing inconsistent naming and confusing
intent; restore the underscore to indicate an intentionally unused parameter by
renaming the parameter back to `_files` here and update the interface at line 95
to match, OR if file handling is intended, implement the file processing logic
inside the function and update the interface at line 95 to use `files` (ensuring
ESLint no-unused-vars compliance and consistent names across both declaration
and implementation).
| const eventData = progressPart.data | ||
|
|
||
| if (eventData?.status && (eventData.status === "in-progress" || eventData.status === "done" || eventData.status === "error")) { | ||
| if (typeof eventData?.status === 'string' && (eventData.status === "in-progress" || eventData.status === "done")) { |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cd /repo && head -50 app/networks/providers/network-context.tsxRepository: ssdeanx/AgentStack
Length of output: 117
🏁 Script executed:
cd /repo && sed -n '30,45p' app/networks/providers/network-context.tsxRepository: ssdeanx/AgentStack
Length of output: 117
🏁 Script executed:
cd /repo && sed -n '325,340p' app/networks/providers/network-context.tsxRepository: ssdeanx/AgentStack
Length of output: 117
🏁 Script executed:
cd /repo && rg -n 'data-tool-progress' --type=tsx -A 8Repository: ssdeanx/AgentStack
Length of output: 117
🏁 Script executed:
cd /repo && rg -n 'ProgressEvent' --type=tsx -B 2 -A 5Repository: ssdeanx/AgentStack
Length of output: 117
🏁 Script executed:
cd /repo && rg -n 'data-tool-error' --type=tsx -A 5Repository: ssdeanx/AgentStack
Length of output: 117
🏁 Script executed:
wc -l app/networks/providers/network-context.tsxRepository: ssdeanx/AgentStack
Length of output: 108
🏁 Script executed:
sed -n '30,45p' app/networks/providers/network-context.tsxRepository: ssdeanx/AgentStack
Length of output: 324
🏁 Script executed:
sed -n '325,340p' app/networks/providers/network-context.tsxRepository: ssdeanx/AgentStack
Length of output: 937
🏁 Script executed:
rg -n 'data-tool-progress' --type=tsx -A 8Repository: ssdeanx/AgentStack
Length of output: 89
🏁 Script executed:
rg -n 'ProgressEvent' --type=tsx -B 2 -A 5Repository: ssdeanx/AgentStack
Length of output: 89
🏁 Script executed:
rg -n 'status.*error' app/networks/providers/network-context.tsx -B 2 -A 2Repository: ssdeanx/AgentStack
Length of output: 692
🏁 Script executed:
rg -n 'data-tool-error' app/networks/providers/network-context.tsx -B 2 -A 5Repository: ssdeanx/AgentStack
Length of output: 44
🏁 Script executed:
rg -n 'status.*error\|error.*status' app/networks/providers/network-context.tsx -B 3 -A 3Repository: ssdeanx/AgentStack
Length of output: 44
🏁 Script executed:
grep -n 'part\.type' app/networks/providers/network-context.tsx | head -20Repository: ssdeanx/AgentStack
Length of output: 728
🏁 Script executed:
sed -n '275,360p' app/networks/providers/network-context.tsxRepository: ssdeanx/AgentStack
Length of output: 3772
🏁 Script executed:
find . -name "workflow-context.tsx" -o -name "workflow-context.ts"Repository: ssdeanx/AgentStack
Length of output: 108
🏁 Script executed:
sed -n '380,430p' app/workflows/providers/workflow-context.tsxRepository: ssdeanx/AgentStack
Length of output: 2606
🏁 Script executed:
grep -n 'status.*error\|error.*status' app/workflows/providers/workflow-context.tsx -B 2 -A 2Repository: ssdeanx/AgentStack
Length of output: 945
Include "error" status in the data-tool-progress condition to match the ProgressEvent interface and workflow-context.tsx pattern.
The status check at line 331 excludes "error", causing progress events with status: "error" to be silently dropped. The ProgressEvent interface (line 37) defines status as "in-progress" | "done" | "error", and workflow-context.tsx (line 399-400) explicitly includes all three statuses when handling similar data-workflow-progress events.
Change line 331 from:
if (typeof eventData?.status === 'string' && (eventData.status === "in-progress" || eventData.status === "done"))To:
if (typeof eventData?.status === 'string' && (eventData.status === "in-progress" || eventData.status === "done" || eventData.status === "error"))🤖 Prompt for AI Agents
In app/networks/providers/network-context.tsx around line 331, the conditional
that filters data-tool-progress events only allows "in-progress" and "done"
statuses and therefore drops "error" events; update the check to also accept
eventData.status === "error" so it matches the ProgressEvent interface and the
pattern used in workflow-context.tsx, ensuring error status events are processed
the same way as the other statuses.
| ```typescript | ||
| await context?.writer?.custom({ | ||
| type: 'data-tool-progress', | ||
| data: { | ||
| status: 'in-progress', | ||
| message: `📈 Fetching tool-id data for ${inputData.symbol}/${inputData.market}`, | ||
| stage: 'tool-id' | ||
| }, | ||
| id: 'tool-id' | ||
| }); | ||
| ``` |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Improve consistency of placeholder values in example.
The progress event example mixes generic placeholders ("tool-id") with specific financial API fields (inputData.symbol, inputData.market), creating confusion about what values should be used.
Either use fully generic placeholders:
await context?.writer?.custom({
type: 'data-tool-progress',
data: {
status: 'in-progress',
- message: `📈 Fetching tool-id data for ${inputData.symbol}/${inputData.market}`,
+ message: `Processing ${toolName} with input: ${inputData.param}`,
stage: 'tool-id'
},
id: 'tool-id'
});Or use a complete real-world example:
await context?.writer?.custom({
type: 'data-tool-progress',
data: {
status: 'in-progress',
message: `📈 Fetching Alpha Vantage crypto data for ${inputData.symbol}/${inputData.market}`,
- stage: 'tool-id'
+ stage: 'alpha-vantage-crypto'
},
- id: 'tool-id'
+ id: 'alpha-vantage-crypto'
});The second approach matches the real example shown in AGENTS.md (lines 124-132) and provides clearer guidance.
📝 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.
| ```typescript | |
| await context?.writer?.custom({ | |
| type: 'data-tool-progress', | |
| data: { | |
| status: 'in-progress', | |
| message: `📈 Fetching tool-id data for ${inputData.symbol}/${inputData.market}`, | |
| stage: 'tool-id' | |
| }, | |
| id: 'tool-id' | |
| }); | |
| ``` |
🤖 Prompt for AI Agents
In memory-bank/copilot-rules.md around lines 167 to 177, the progress event
example mixes generic placeholders ("tool-id") with concrete fields
(inputData.symbol/inputData.market); update the example for consistency by
choosing one style and applying it throughout—either replace the specific fields
with generic placeholders (e.g., ${symbol}/${market}) and keep id as 'tool-id',
or convert id to a realistic value and use a complete real-world example
matching AGENTS.md (lines 124-132); ensure the chosen approach is applied to all
keys (type, data.status, data.message, data.stage, id) and update the message
text accordingly so placeholders are consistent across the snippet.
| - Status check → + progress.md | ||
| ``` | ||
|
|
||
| Note: For tool implementation tasks, consult `memory-bank/tasks/TASK001-tool-streaming.md` which documents the standard streaming and progress-event conventions (use `context.writer` with `data-tool-progress` start/in-progress/done events, and prefer `agent.stream()` with `MastraModelOutput` when available). Update the task scratchpad with any deviations or agent-specific details. |
There was a problem hiding this comment.
Excessive line length in markdown documentation.
Line 40 exceeds 300 characters, violating the project's markdown guideline to limit lines to 80 characters for readability.
Apply this diff to reformat the note with proper line breaks:
-Note: For tool implementation tasks, consult `memory-bank/tasks/TASK001-tool-streaming.md` which documents the standard streaming and progress-event conventions (use `context.writer` with `data-tool-progress` start/in-progress/done events, and prefer `agent.stream()` with `MastraModelOutput` when available). Update the task scratchpad with any deviations or agent-specific details.
+Note: For tool implementation tasks, consult
+`memory-bank/tasks/TASK001-tool-streaming.md` which documents the standard
+streaming and progress-event conventions (use `context.writer` with
+`data-tool-progress` start/in-progress/done events, and prefer
+`agent.stream()` with `MastraModelOutput` when available). Update the task
+scratchpad with any deviations or agent-specific details.As per coding guidelines, limit line length to 80 characters in markdown for readability.
📝 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.
| Note: For tool implementation tasks, consult `memory-bank/tasks/TASK001-tool-streaming.md` which documents the standard streaming and progress-event conventions (use `context.writer` with `data-tool-progress` start/in-progress/done events, and prefer `agent.stream()` with `MastraModelOutput` when available). Update the task scratchpad with any deviations or agent-specific details. | |
| Note: For tool implementation tasks, consult | |
| `memory-bank/tasks/TASK001-tool-streaming.md` which documents the standard | |
| streaming and progress-event conventions (use `context.writer` with | |
| `data-tool-progress` start/in-progress/done events, and prefer | |
| `agent.stream()` with `MastraModelOutput` when available). Update the task | |
| scratchpad with any deviations or agent-specific details. |
🤖 Prompt for AI Agents
In memory-bank/memory-bank-instructions.md around line 40, the Note paragraph
exceeds the project's 80-character markdown line-length rule; reflow the
sentence into multiple lines no longer than 80 characters, preserving all
content and inline code/backticks (e.g.,
`memory-bank/tasks/TASK001-tool-streaming.md`, `context.writer`,
`data-tool-progress`, `agent.stream()`, `MastraModelOutput`), and ensure the
final wrapped paragraph reads naturally and keeps the instruction to update the
task scratchpad with any deviations.
| @@ -1 +1 @@ | |||
| # [Task 001] - Implement Tool Streaming with Writer in ALL Tools\n\n**Status:** In Progress \n**Added:** 2025-11-22 \n**Updated:** 2025-11-22\n\n## Original Request\n\nUser: Fetch Mastra tool streaming docs, implement in #file:tools. Clarified: ALL tools use writer directly, no utility.\n\n## Thought Process\n\nMastra docs: execute({context, writer?}): await writer?.write({type:'custom-event'| 'progress', ...}); return result. 12 tools need surgical updates: add writer param, emit start/progress/end.\n\n## Implementation Plan\n\n- Create tasks structure\n- Update all 12 .tool.ts executes\n- Add streaming tests\n- Update AGENTS.md\n\n## Progress Tracking\n\n**Overall Status:** In Progress - 10%\n\n### Subtasks\n\n| ID | Description | Status | Updated | Notes \n|-----|--------------------------------------|-------------|-------------|-------\n| 1.1 | Create tasks/ folder & files | Complete | 2025-11-22 | Done\n| 1.2 | Read all tool files | In Progress | 2025-11-22 | 3 read, 9 pending\n| 1.3 | Edit weather-tool.ts | Not Started | | \n| 1.4 | Edit serpapi-search.tool.ts | Not Started | | \n| ... | Edit remaining tools | Not Started | | \n| 1.x | Tests & AGENTS.md | Not Started | | \n\n## Progress Log\n\n### 2025-11-22\n- Created tasks structure\n- Read 3 sample tools\n- Planning batch edits\n No newline at end of file | |||
| # [Task 001] - Implement Tool Streaming with Writer in ALL Tools\n\n**Status:** In Progress \n**Added:** 2025-11-22 \n**Updated:** 2025-11-22\n\n## Original Request\n\nUser: Fetch Mastra tool streaming docs, implement in #file:tools. Clarified: ALL tools use writer directly, no utility.\n\n## Thought Process\n\nMastra docs: execute({context, writer?}): await writer?.write({type:'custom-event'| 'progress', ...}); return result. 12 tools need surgical updates: add writer param, emit start/progress/end.\n\n## Implementation Plan\n\n- Create tasks structure\n- Update all 12 .tool.ts executes\n- Add streaming tests\n- Update AGENTS.md\n\n## Progress Tracking\n\n**Overall Status:** In Progress - 10%\n\n### Subtasks\n\n| ID | Description | Status | Updated | Notes \n|-----|--------------------------------------|-------------|-------------|-------\n| 1.1 | Create tasks/ folder & files | Complete | 2025-11-22 | Done\n| 1.2 | Read all tool files | In Progress | 2025-11-22 | 3 read, 9 pending\n| 1.3 | Edit weather-tool.ts | Not Started | | \n| 1.4 | Edit serpapi-search.tool.ts | Not Started | | \n| ... | Edit remaining tools | Not Started | | \n| 1.x | Tests & AGENTS.md | Not Started | | \n\n## Progress Log\n\n### 2025-11-22\n- Created tasks structure\n- Read 3 sample tools\n- Planning batch edits\n | |||
There was a problem hiding this comment.
Incorrect file format: markdown stored as escaped single-line string.
This markdown file is stored as a single line with \n escape sequences instead of actual line breaks. Markdown files should use proper multi-line formatting for readability and maintainability.
The content should be reformatted as a proper multi-line markdown file. For example, the beginning should be:
-# [Task 001] - Implement Tool Streaming with Writer in ALL Tools\n\n**Status:** In Progress \n**Added:** 2025-11-22 \n**Updated:** 2025-11-22\n\n## Original Request\n\nUser: Fetch Mastra tool streaming docs, implement in #file:tools. Clarified: ALL tools use writer directly, no utility.\n\n## Thought Process\n\nMastra docs: execute({context, writer?}): await writer?.write({type:'custom-event'| 'progress', ...}); return result. 12 tools need surgical updates: add writer param, emit start/progress/end.\n\n## Implementation Plan\n\n- Create tasks structure\n- Update all 12 .tool.ts executes\n- Add streaming tests\n- Update AGENTS.md\n\n## Progress Tracking\n\n**Overall Status:** In Progress - 10%\n\n### Subtasks\n\n| ID | Description | Status | Updated | Notes \n|-----|--------------------------------------|-------------|-------------|-------\n| 1.1 | Create tasks/ folder & files | Complete | 2025-11-22 | Done\n| 1.2 | Read all tool files | In Progress | 2025-11-22 | 3 read, 9 pending\n| 1.3 | Edit weather-tool.ts | Not Started | | \n| 1.4 | Edit serpapi-search.tool.ts | Not Started | | \n| ... | Edit remaining tools | Not Started | | \n| 1.x | Tests & AGENTS.md | Not Started | | \n\n## Progress Log\n\n### 2025-11-22\n- Created tasks structure\n- Read 3 sample tools\n- Planning batch edits\n
+# [Task 001] - Implement Tool Streaming with Writer in ALL Tools
+
+**Status:** In Progress
+**Added:** 2025-11-22
+**Updated:** 2025-11-22
+
+## Original Request
+
+User: Fetch Mastra tool streaming docs, implement in #file:tools. Clarified: ALL tools use writer directly, no utility.
+
+## Thought Process
+
+Mastra docs: execute({context, writer?}): await writer?.write({type:'custom-event'| 'progress', ...}); return result. 12 tools need surgical updates: add writer param, emit start/progress/end.
+
+## Implementation Plan
+
+- Create tasks structure
+- Update all 12 .tool.ts executes
+- Add streaming tests
+- Update AGENTS.md
+
+## Progress Tracking
+
+**Overall Status:** In Progress - 10%
+
+### Subtasks
+
+| ID | Description | Status | Updated | Notes |
+|-----|--------------------------------------|-------------|-------------|-------|
+| 1.1 | Create tasks/ folder & files | Complete | 2025-11-22 | Done |
+| 1.2 | Read all tool files | In Progress | 2025-11-22 | 3 read, 9 pending |
+| 1.3 | Edit weather-tool.ts | Not Started | | |
+| 1.4 | Edit serpapi-search.tool.ts | Not Started | | |
+| ... | Edit remaining tools | Not Started | | |
+| 1.x | Tests & AGENTS.md | Not Started | | |
+
+## Progress Log
+
+### 2025-11-22
+- Created tasks structure
+- Read 3 sample tools
+- Planning batch editsAs per coding guidelines, limit line length to 80 characters in markdown for readability and use proper whitespace between sections.
🤖 Prompt for AI Agents
In memory-bank/tasks/TASK001-tool-streaming.md around lines 1 to 1, the markdown
content is stored as a single-line string containing literal "\n" sequences
instead of real line breaks; convert it into a proper multi-line markdown file
by replacing the escaped "\n" with actual newlines, restoring the intended
headings/paragraphs and list formatting, break long lines to a maximum of ~80
characters for readability, and ensure proper blank lines between sections
(headings, lists, code blocks) per markdown conventions.
| const truncatedContent = (result?.content ?? '').slice(0, 8000); | ||
| const contentWithTruncation = (result?.content ?? '').length > 8000 ? truncatedContent + 'AAAA...' : truncatedContent; | ||
|
|
There was a problem hiding this comment.
Likely typo: 'AAAA...' as truncation indicator.
The string 'AAAA...' appended to truncated content looks like a typo. Consider using a more descriptive indicator.
const truncatedContent = (result?.content ?? '').slice(0, 8000);
- const contentWithTruncation = (result?.content ?? '').length > 8000 ? truncatedContent + 'AAAA...' : truncatedContent;
+ const contentWithTruncation = (result?.content ?? '').length > 8000 ? truncatedContent + '... [truncated]' : truncatedContent;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const truncatedContent = (result?.content ?? '').slice(0, 8000); | |
| const contentWithTruncation = (result?.content ?? '').length > 8000 ? truncatedContent + 'AAAA...' : truncatedContent; | |
| const truncatedContent = (result?.content ?? '').slice(0, 8000); | |
| const contentWithTruncation = (result?.content ?? '').length > 8000 ? truncatedContent + '... [truncated]' : truncatedContent; |
🤖 Prompt for AI Agents
In src/mastra/tools/extractLearningsTool.ts around lines 54 to 56, the
truncation suffix currently uses the string 'AAAA...' which appears to be a
typo; replace it with a clear truncation indicator such as '... (truncated)' or
'… (truncated)' to make it obvious content was cut off, e.g., compute
truncatedContent as before and set contentWithTruncation to truncatedContent +
'... (truncated)' when the original length exceeds 8000.
| if (typeof agent.stream === 'function') { | ||
| // Use MastraModelOutput for accurate typing and pipe fullStream into the writer (Mastra nested-agent pattern) | ||
| await writer?.custom({ type: 'data-tool-progress', data: { status: 'in-progress', message: '🔁 Streaming learnings from agent', stage: 'extract-learnings' }, id: 'extract-learnings' }); | ||
| const stream = await agent.stream(prompt) as MastraModelOutput | undefined; | ||
| if (stream?.fullStream !== undefined && writer) { await stream.fullStream.pipeTo(writer as unknown as WritableStream) } | ||
|
|
||
| if (stream) { | ||
| const text = (await stream.text) ?? ''; | ||
| try { responseObject = stream.object ?? (text ? JSON.parse(text) : {}) } catch { responseObject = {} } | ||
| } else { | ||
| responseObject = {} | ||
| } | ||
| } else { | ||
| const response = await agent.generate(prompt); | ||
| try { responseObject = response.object ?? (response.text ? JSON.parse(response.text) : {}) } catch { responseObject = {} } | ||
| } |
There was a problem hiding this comment.
Missing textStream fallback in streaming path.
Unlike other tools (e.g., editorTool, evaluateResultTool), this tool only checks fullStream and doesn't fall back to textStream. This may result in lost streaming output for agents that only provide textStream.
Add textStream fallback:
if (typeof agent.stream === 'function') {
await writer?.custom({ type: 'data-tool-progress', data: { status: 'in-progress', message: '🔁 Streaming learnings from agent', stage: 'extract-learnings' }, id: 'extract-learnings' });
const stream = await agent.stream(prompt) as MastraModelOutput | undefined;
- if (stream?.fullStream !== undefined && writer) { await stream.fullStream.pipeTo(writer as unknown as WritableStream) }
+ 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);
+ }📝 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.
| if (typeof agent.stream === 'function') { | |
| // Use MastraModelOutput for accurate typing and pipe fullStream into the writer (Mastra nested-agent pattern) | |
| await writer?.custom({ type: 'data-tool-progress', data: { status: 'in-progress', message: '🔁 Streaming learnings from agent', stage: 'extract-learnings' }, id: 'extract-learnings' }); | |
| const stream = await agent.stream(prompt) as MastraModelOutput | undefined; | |
| if (stream?.fullStream !== undefined && writer) { await stream.fullStream.pipeTo(writer as unknown as WritableStream) } | |
| if (stream) { | |
| const text = (await stream.text) ?? ''; | |
| try { responseObject = stream.object ?? (text ? JSON.parse(text) : {}) } catch { responseObject = {} } | |
| } else { | |
| responseObject = {} | |
| } | |
| } else { | |
| const response = await agent.generate(prompt); | |
| try { responseObject = response.object ?? (response.text ? JSON.parse(response.text) : {}) } catch { responseObject = {} } | |
| } | |
| if (typeof agent.stream === 'function') { | |
| // Use MastraModelOutput for accurate typing and pipe fullStream into the writer (Mastra nested-agent pattern) | |
| await writer?.custom({ type: 'data-tool-progress', data: { status: 'in-progress', message: '🔁 Streaming learnings from agent', stage: 'extract-learnings' }, id: 'extract-learnings' }); | |
| 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); | |
| } | |
| if (stream) { | |
| const text = (await stream.text) ?? ''; | |
| try { responseObject = stream.object ?? (text ? JSON.parse(text) : {}) } catch { responseObject = {} } | |
| } else { | |
| responseObject = {} | |
| } | |
| } else { | |
| const response = await agent.generate(prompt); | |
| try { responseObject = response.object ?? (response.text ? JSON.parse(response.text) : {}) } catch { responseObject = {} } | |
| } |
| const learningLength = parsed.data.learning.length ?? 0; | ||
| const followUpQuestionsCount = parsed.data.followUpQuestions?.length ?? 0; |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Minor: Redundant nullish coalescing on learning.length.
Since parsed.data.learning is validated as a string by the Zod schema, .length will always be a number. The ?? 0 is unnecessary for Line 129 (though correct for Line 130 with the optional chaining).
- const learningLength = parsed.data.learning.length ?? 0;
+ const learningLength = parsed.data.learning.length;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const 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 ?? 0; |
🤖 Prompt for AI Agents
In src/mastra/tools/extractLearningsTool.ts around lines 129-130, remove the
redundant nullish coalescing on the validated string length: change the
learningLength assignment to use parsed.data.learning.length (drop the "?? 0"),
and keep the followUpQuestionsCount line unchanged since it needs the optional
chaining and fallback.
| 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 | ||
| } |
There was a problem hiding this comment.
Missing null check on writer before pipeTo.
Lines 143 and 145 call pipeTo(writer as unknown as WritableStream) without first verifying writer is defined. While the outer context may ensure it exists, explicit guards would prevent potential runtime errors.
Add writer check before piping:
if (typeof agent.stream === 'function') {
const stream = await agent.stream(prompt) as MastraModelOutput | undefined
- if (stream?.fullStream) {
+ if (stream?.fullStream && writer) {
await stream.fullStream.pipeTo(writer as unknown as WritableStream)
- } else if (stream?.textStream) {
+ } else if (stream?.textStream && writer) {
await stream.textStream.pipeTo(writer as unknown as WritableStream)
}📝 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.
| 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 | |
| } | |
| 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) | |
| } | |
| const text = stream?.text ? await stream.text : undefined | |
| resultText = text ?? '' | |
| } else { | |
| const result = await agent.generate(prompt) | |
| resultText = result.text | |
| } |
🤖 Prompt for AI Agents
In src/mastra/tools/financial-chart-tools.ts around lines 140 to 152, the code
calls stream.fullStream.pipeTo(writer as unknown as WritableStream) and
stream.textStream.pipeTo(...) without checking writer; add an explicit guard so
you only call pipeTo when writer is defined (e.g., if (writer) { await
stream.fullStream.pipeTo(writer as unknown as WritableStream) } else { /*
fallback: skip piping or handle error */ }), and ensure the fallback path still
obtains text from stream.text (or throws/returns a meaningful error) so you
avoid runtime exceptions when writer is undefined.
| try { | ||
| const agent = context?.mastra?.getAgent('chartGeneratorAgent') | ||
| if (!agent) { | ||
| const agent = context?.mastra?.getAgent?.('chartGeneratorAgent') ?? chartGeneratorAgent | ||
| if (typeof agent.generate !== 'function' && typeof agent.stream !== 'function') { | ||
| await context?.writer?.custom({ type: 'data-tool-progress', data: { status: 'done', message: '❌ chartGeneratorAgent not found', stage: 'chart-generator' }, id: 'chart-generator' }) | ||
| throw new Error('Agent chartGeneratorAgent not found'); | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Inconsistent error handling: chartGeneratorTool throws while chartSupervisorTool returns error.
chartSupervisorTool (Line 112-117) returns { success: false, error: ... } when the agent is unavailable, but chartGeneratorTool throws an error. This inconsistency may confuse callers expecting uniform behavior.
Consider standardizing: either all tools return error objects or all throw. Given the output schema includes an optional error field for some tools, returning error objects may be more consistent.
🤖 Prompt for AI Agents
In src/mastra/tools/financial-chart-tools.ts around lines 277 to 282, the code
currently throws an Error when the chartGeneratorAgent is unavailable which is
inconsistent with chartSupervisorTool that returns an error object; change the
behavior to return a standardized error response (e.g., { success: false, error:
'Agent chartGeneratorAgent not found' }) instead of throwing, keep the existing
context.writer.custom call that emits the progress message, and ensure the
returned object matches the same shape used by chartSupervisorTool so callers
can handle errors uniformly.
- 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.

Deleted the following test files as they are no longer needed:
src/mastra/tools/tests/serpapi-news-trends.tool.test.tssrc/mastra/tools/tests/serpapi-search.tool.test.tssrc/mastra/tools/tests/serpapi-shopping.tool.test.tssrc/mastra/tools/tests/weather-tool.test.tssrc/mastra/tools/tests/web-scraper-tool.test.tsAdded a new task documentation file
memory-bank/tasks/TASK001-update-2025-12-14.mddetailing updates made to align tools with the streaming and progress convention:data-tool-agentmessages withdata-tool-progressin various tools.data-tool-agentparts.src/mastra/tools/AGENTS.md.