Conversation
- Refactored research synthesis workflow to unify progress logging under 'data-tool-progress' type. - Removed redundant logging steps and streamlined the workflow for better clarity and performance. - Updated stock analysis workflow to use 'data-tool-progress' for all progress updates, enhancing consistency. - Modified weather workflow to replace 'data-workflow-progress' with 'data-tool-progress' for fetching and planning activities. - Added new instructions for taming Copilot to ensure better adherence to user directives and coding standards. - Introduced AI Elements usage guide to provide comprehensive documentation for building AI-native applications. - Updated TypeScript configuration to include workflow files for better type checking.
Learn moreAll Green is an AI agent that automatically: ✅ Addresses code review comments ✅ Fixes failing CI checks ✅ Resolves merge conflicts |
Reviewer's GuideThis PR standardizes workflow/tool progress logging around the Sequence diagram for standardized data-tool-progress events in workflowssequenceDiagram
actor User
participant BrowserApp
participant WorkflowProvider
participant AIBackend
participant WorkflowStep
participant Writer
User->>BrowserApp: click run workflow
BrowserApp->>WorkflowProvider: runWorkflow(input)
WorkflowProvider->>AIBackend: send workflow request
AIBackend->>WorkflowStep: execute(inputData, writer)
activate WorkflowStep
note over WorkflowStep: start step
WorkflowStep->>Writer: custom(type: data-tool-progress, data.status: in-progress)
Writer-->>AIBackend: stream event (data-tool-progress)
AIBackend-->>WorkflowProvider: assistant message with data-tool-progress
WorkflowProvider->>WorkflowProvider: map to progressEvent(status: in-progress)
note over WorkflowStep: intermediate progress
WorkflowStep->>Writer: custom(type: data-tool-progress, data.status: in-progress)
Writer-->>AIBackend: stream event
AIBackend-->>WorkflowProvider: assistant message with data-tool-progress
WorkflowProvider->>WorkflowProvider: update progressEvents
alt success
WorkflowStep->>Writer: custom(type: data-tool-progress, data.status: done)
Writer-->>AIBackend: final progress event
AIBackend-->>WorkflowProvider: assistant message with data-tool-progress
WorkflowProvider->>WorkflowProvider: set step status to done
else error
WorkflowStep->>Writer: custom(type: data-workflow-step-error)
Writer-->>AIBackend: error event
AIBackend-->>WorkflowProvider: assistant message with data-workflow-step-error
WorkflowProvider->>WorkflowProvider: add error progressEvent(status: error)
end
WorkflowStep-->>AIBackend: return result or throw
deactivate WorkflowStep
AIBackend-->>WorkflowProvider: final completion message
WorkflowProvider-->>BrowserApp: context with progressEvents
BrowserApp-->>User: render unified progress UI
Sequence diagram for streaming agent output through writer in toolssequenceDiagram
actor User
participant App
participant Tool
participant Agent
participant Writer
User->>App: trigger tool (e.g. chartSupervisorTool, copywriterTool)
App->>Tool: execute(inputData, context)
Tool->>Writer: custom(type: data-tool-progress, status: in-progress)
Tool->>Agent: getAgent(id)
alt agent available
Tool->>Agent: stream(prompt)
Agent-->>Tool: streamResult(fullStream, textStream, text)
alt fullStream available and writer present
Tool->>Writer: pipe fullStream to writer
else textStream available
Tool->>Writer: pipe textStream to writer
else no streaming support
Tool->>Agent: generate(prompt)
Agent-->>Tool: result(text)
end
Tool->>Tool: assemble resultText from stream or generate
Tool-->>App: structured result(parsed from resultText)
Tool->>Writer: custom(type: data-tool-progress, status: done)
else agent missing
Tool->>Writer: custom(type: data-tool-progress, status: done, message: agent not found)
Tool-->>App: fallback result with error description
end
Class diagram for updated tool context types and execution flowclassDiagram
class ToolExecutionContext {
+writer
+mastra
+requestContext
}
class Writer {
+custom(type, data, id) Promise~void~
}
class RequestContext_T_ {
+get(key) T
}
class CopywriterTool {
+execute(inputData, context) Promise~CopywriterResult~
}
class MultiStringEditTool {
+execute(inputData, context) Promise~MultiStringEditOutput~
}
class FindSymbolTool {
+execute(inputData, context) Promise~FindSymbolOutput~
-extractSymbolInfo(node, symbolType, searchTerm, caseSensitive) SymbolInfo
-matchesSearch(name, searchTerm, caseSensitive) boolean
-isSymbolExported(sourceFile, symbolName) boolean
}
class SymbolContext {
+maxResults number
+excludePatterns string[]
+includeNodeModules boolean
+caseSensitive boolean
+searchType string
}
class MultiStringEditContext {
+maxFileSize number
+createBackup boolean
+dryRun boolean
+operationType string
}
class CopywriterResult {
+content string
+contentType string
+title string
+summary string
+keyPoints string[]
+wordCount number
}
class MultiStringEditOutput {
+filesProcessed number
+filesChanged number
+diffSummary string
}
class FindSymbolOutput {
+symbols SymbolInfo[]
+processedFiles number
+summary string
}
class SymbolInfo {
+name string
+kind string
+filePath string
+isExported boolean
}
CopywriterTool --> ToolExecutionContext : uses
MultiStringEditTool --> ToolExecutionContext : uses
FindSymbolTool --> ToolExecutionContext : uses
ToolExecutionContext --> Writer : uses
ToolExecutionContext --> RequestContext_T_ : uses
RequestContext_T_ --> SymbolContext : specializes
RequestContext_T_ --> MultiStringEditContext : specializes
FindSymbolTool --> SymbolInfo : returns
FindSymbolTool --> FindSymbolOutput : returns
MultiStringEditTool --> MultiStringEditOutput : returns
CopywriterTool --> CopywriterResult : returns
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
🤖 Hi @ssdeanx, I've received your request, and I'm working on it now! You can track my progress in the logs for more details. |
Summary by CodeRabbitRelease Notes
✏️ Tip: You can customize this high-level summary in your review settings. WalkthroughThis PR refactors progress reporting across tools and workflows by replacing workflow-focused events with tool-focused events (data-tool-progress), adds structured progress metadata (status, stage, id), introduces streaming support in agent-based tools with fallback logic, updates dependencies for AI SDK packages, and adds new documentation while removing outdated guidance sections. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
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 significantly refactors the internal logging and progress reporting infrastructure, moving towards a more unified and consistent 'data-tool-progress' event type across various AI-driven workflows and tools. This change streamlines how progress and status updates are communicated, improving observability and debugging. Furthermore, it introduces streaming capabilities for agent interactions, enabling real-time feedback, and enhances the robustness of several tools by adding agent availability checks. The PR also includes important documentation for AI Elements and minor dependency updates. 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
|
|
🤖 I'm sorry @ssdeanx, but I was unable to process your request. Please see the logs for more details. |
There was a problem hiding this comment.
Hey there - I've reviewed your changes - here's some feedback:
- In
fetchStockDataStep's error handler you emit awriter.customevent withtype: 'data-workflow-p', which looks like a typo and likely should be aligned with the other error events (e.g.data-workflow-step-errorordata-tool-progress). - In
financial-report-workflow.tsseveralwriter?.write({ type: 'progress', ... })calls now send astatusstring instead of the original numericpercent, which may break any consumers expecting the previous schema forprogressevents; consider either keeping the original shape or introducing a separate event type for the new payload.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `fetchStockDataStep`'s error handler you emit a `writer.custom` event with `type: 'data-workflow-p'`, which looks like a typo and likely should be aligned with the other error events (e.g. `data-workflow-step-error` or `data-tool-progress`).
- In `financial-report-workflow.ts` several `writer?.write({ type: 'progress', ... })` calls now send a `status` string instead of the original numeric `percent`, which may break any consumers expecting the previous schema for `progress` events; consider either keeping the original shape or introducing a separate event type for the new payload.
## Individual Comments
### Comment 1
<location> `src/mastra/workflows/stock-analysis-workflow.ts:79-88` </location>
<code_context>
execute: async (inputData, context): Promise<CodeSearchOutput> => {
const writer = context?.writer;
- await writer?.custom({ type: 'data-tool-progress', data: { message: `🔎 Starting code search for pattern '${inputData.pattern}'` } });
+ await writer?.custom({
+ type: 'data-tool-progress',
+ data: {
</code_context>
<issue_to_address>
**issue (bug_risk):** The custom writer event type `'data-workflow-p'` looks like a typo and may break downstream handling.
Other error events use names like `'data-workflow-step-error'` or `'data-tool-progress'`, so `'data-workflow-p'` is likely not recognized by existing handlers. Please update this to the correct existing event type (probably `'data-workflow-step-error'` or another defined error event) so `fetch-stock-data` errors are reported correctly.
</issue_to_address>
### Comment 2
<location> `src/mastra/workflows/document-processing-workflow.ts:408` </location>
<code_context>
+ type: 'data-tool-progress',
data: {
+ status: "done", // must be "done" for the UI to show the step as completed
+ message: "Text passed through successfully ${inputData.content}`,",
stepId: 'pass-text-through',
- success: true,
</code_context>
<issue_to_address>
**issue (bug_risk):** The success message string for `pass-text-through` is malformed and won’t interpolate `inputData.content`.
Because the message is in double quotes, `${inputData.content}` is treated as plain text, and there’s also an extra backtick and comma. To interpolate the value, use a template literal (e.g. ``message: `Text passed through successfully ${inputData.content}` ``); otherwise remove the placeholder and stray punctuation.
</issue_to_address>
### Comment 3
<location> `src/mastra/workflows/research-synthesis-workflow.ts:73-80` </location>
<code_context>
const writer = context?.writer;
- await writer?.custom({ type: 'data-tool-progress', data: { message: `🔎 Starting code search for pattern '${inputData.pattern}'` } });
+ await writer?.custom({
+ type: 'data-tool-progress',
+ data: {
+ status: 'in-progress',
+ message: `🔎 Starting code search for pattern '${inputData.pattern}'`,
+ stage: 'coding:codeSearch'
</code_context>
<issue_to_address>
**issue (bug_risk):** Error handling for `research-topic-item` emits an `in-progress` status even when an error occurs.
In the catch block, this event still uses `status: 'in-progress'` while only changing the message to describe an error. That makes it hard for consumers to reliably detect failures based on status alone. Please use a distinct terminal status (e.g. `'error'` or `'done'`) so error states are clearly distinguishable from active work.
</issue_to_address>
### Comment 4
<location> `app/workflows/providers/workflow-context.tsx:419` </location>
<code_context>
id: `${message.id}-${part.type}-${partIndex}`,
stage: "tool",
- status: eventData.status === "success" ? "done" : eventData.status === "pending" ? "in-progress" : "error",
+ status: eventData.status === "done" ? "done" : (eventData.status === "pending" || eventData.status === "in-progress") ? "in-progress" : "error",
message: eventData.message ?? `${eventData.toolName ?? 'Tool'} ${eventData.status}`,
timestamp: new Date(),
</code_context>
<issue_to_address>
**issue (bug_risk):** The new status mapping only treats `'done'` as success; other success-like statuses (e.g. `'success'`, `'completed'`) will be treated as errors.
Since several producers still emit statuses like `'success'`/`'completed'` via `data-tool-progress`, this change will cause many genuinely successful events to appear as errors in the UI. Either standardize all producers to emit `'done'` on success, or expand this mapping to recognize other known success statuses as `'done'` instead of `'error'`.
</issue_to_address>
### Comment 5
<location> `src/mastra/workflows/content-studio-workflow.ts:106-111` </location>
<code_context>
const writer = context?.writer;
- await writer?.custom({ type: 'data-tool-progress', data: { message: `🔎 Starting code search for pattern '${inputData.pattern}'` } });
+ await writer?.custom({
+ type: 'data-tool-progress',
+ data: {
+ status: 'in-progress',
</code_context>
<issue_to_address>
**issue (bug_risk):** Using `status: "success"` for completion is inconsistent with the `WorkflowProvider` status mapping and may render as an error.
Completion events in this workflow (research, evaluation, learning, strategy, hook, body, review, refine) currently emit `status: "success"`, but `WorkflowProvider` now only treats `'done'` as completed and maps all other unknown statuses to `'error'`. To avoid these being shown as errors, update them to use `status: "done"` (or otherwise align both sides on a shared status enum).
</issue_to_address>
### Comment 6
<location> `src/mastra/tools/multi-string-edit.tool.ts:235-237` </location>
<code_context>
+ execute: async (inputData, context) => {
+ const { edits, dryRun = false, createBackup = true, projectRoot } = inputData;
const writer = context?.writer;
+ const requestContext = context?.requestContext as RequestContext<MultiStringEditContext>;
+
+ const maxFileSize = requestContext?.get('maxFileSize') ?? 1_000_000;
+
</code_context>
<issue_to_address>
**question (bug_risk):** Switching `maxFileSize` to come from `requestContext` changes behavior and may ignore user-specified limits in `inputData`.
Previously callers could set a per-invocation limit via `inputData.maxFileSize ?? 1_000_000`. Now the limit is only read from `requestContext`, which may be unset or differently configured, and any `maxFileSize` in the tool input is ignored. If that’s not deliberate, consider preferring `inputData.maxFileSize` when present, and otherwise falling back to `requestContext` or the default.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| await writer?.custom({ | ||
| type: 'data-tool-progress', | ||
| data: { | ||
| status: 'in-progress', | ||
| message: `Fetching stock data for ${inputData.symbol}...`, | ||
| stage: 'workflow', | ||
| }, | ||
| id: 'fetch-stock-data', | ||
| }); | ||
|
|
There was a problem hiding this comment.
issue (bug_risk): The custom writer event type 'data-workflow-p' looks like a typo and may break downstream handling.
Other error events use names like 'data-workflow-step-error' or 'data-tool-progress', so 'data-workflow-p' is likely not recognized by existing handlers. Please update this to the correct existing event type (probably 'data-workflow-step-error' or another defined error event) so fetch-stock-data errors are reported correctly.
| type: 'data-tool-progress', | ||
| data: { | ||
| status: "done", // must be "done" for the UI to show the step as completed | ||
| message: "Text passed through successfully ${inputData.content}`,", |
There was a problem hiding this comment.
issue (bug_risk): The success message string for pass-text-through is malformed and won’t interpolate inputData.content.
Because the message is in double quotes, ${inputData.content} is treated as plain text, and there’s also an extra backtick and comma. To interpolate the value, use a template literal (e.g. message: `Text passed through successfully ${inputData.content}` ); otherwise remove the placeholder and stray punctuation.
| type: 'data-tool-progress', | ||
| data: { | ||
| type: 'data-workflow-step-start', | ||
| data: { | ||
| 'initialize-research': { | ||
| topicsCount: inputData.topics.length, | ||
| concurrency: inputData.concurrency, | ||
| }, | ||
| }, | ||
| }, | ||
| id: 'initialize-research', | ||
| }); | ||
|
|
||
| await writer?.custom({ | ||
| type: 'data-workflow-progress', | ||
| data: { | ||
| status: "50%", | ||
| status: "in-progress", | ||
| message: `Researching topic: ${inputData.topics}...`, | ||
| stage: "workflow", | ||
| stage: "researchAgent", | ||
| }, | ||
| id: 'initialize-research', | ||
| }); |
There was a problem hiding this comment.
issue (bug_risk): Error handling for research-topic-item emits an in-progress status even when an error occurs.
In the catch block, this event still uses status: 'in-progress' while only changing the message to describe an error. That makes it hard for consumers to reliably detect failures based on status alone. Please use a distinct terminal status (e.g. 'error' or 'done') so error states are clearly distinguishable from active work.
| type: 'data-tool-progress', | ||
| data: { | ||
| status: "20%", | ||
| status: "in-progress", | ||
| message: "Starting research phase", | ||
| stepId: "research-step", | ||
| }, |
There was a problem hiding this comment.
issue (bug_risk): Using status: "success" for completion is inconsistent with the WorkflowProvider status mapping and may render as an error.
Completion events in this workflow (research, evaluation, learning, strategy, hook, body, review, refine) currently emit status: "success", but WorkflowProvider now only treats 'done' as completed and maps all other unknown statuses to 'error'. To avoid these being shown as errors, update them to use status: "done" (or otherwise align both sides on a shared status enum).
| const requestContext = context?.requestContext as RequestContext<MultiStringEditContext>; | ||
|
|
||
| const maxFileSize = requestContext?.get('maxFileSize') ?? 1_000_000; |
There was a problem hiding this comment.
question (bug_risk): Switching maxFileSize to come from requestContext changes behavior and may ignore user-specified limits in inputData.
Previously callers could set a per-invocation limit via inputData.maxFileSize ?? 1_000_000. Now the limit is only read from requestContext, which may be unset or differently configured, and any maxFileSize in the tool input is ignored. If that’s not deliberate, consider preferring inputData.maxFileSize when present, and otherwise falling back to requestContext or the default.
There was a problem hiding this comment.
Code Review
This pull request introduces a significant and valuable refactoring to standardize logging events across various workflows and tools, unifying them under the data-tool-progress type. This greatly improves consistency and observability. The changes also include adding streaming support to several tools, enhancing error handling, and updating documentation to reflect these new patterns.
However, the refactoring appears to be incomplete or inconsistent in some workflows, where legacy logging events are still present. I've also identified a few critical bugs where error states are being reported with an incorrect status (e.g., done or in-progress instead of error), which could lead to misleading workflow monitoring. Additionally, there are some minor opportunities to improve code clarity and fix typos.
Overall, this is a great step forward, but the identified issues, especially the critical ones related to error reporting, should be addressed to ensure the reliability of the new logging mechanism.
| data: { | ||
| stepId: 'chunk-document', | ||
| error: error instanceof Error ? error.message : 'Unknown error', | ||
| status: "done", |
There was a problem hiding this comment.
In the error handling block for chunkDocumentStep, the progress event is being sent with status: "done". This is incorrect and will misrepresent the step's outcome as successful when it has actually failed. The status should be "error" to correctly reflect the failure.
| status: "done", | |
| status: "error", |
| topic: inputData.topic, | ||
| status: 'error', | ||
| error: error instanceof Error ? error.message : 'Unknown error', | ||
| status: 'in-progress', |
There was a problem hiding this comment.
| stepId: 'fetch-stock-data', | ||
| error: error instanceof Error ? error.message : 'Unknown error', | ||
| await writer?.custom({ | ||
| type: 'data-workflow-p', |
There was a problem hiding this comment.
The event type data-workflow-p appears to be a typo. To align with the standardized logging format of this pull request, it should be data-tool-progress. Additionally, since this is an error path, the status in the event data should be 'error'.
| type: 'data-workflow-p', | |
| type: 'data-tool-progress', |
| await writer?.custom({ | ||
| type: 'data-tool-progress', | ||
| data: { | ||
| type: 'workflow', | ||
| data: 'extract-learnings', | ||
| id: 'extract-learnings', | ||
| }, | ||
| id: 'extract-learnings', | ||
| }); |
There was a problem hiding this comment.
This workflow still uses a mix of old (data-workflow-step-start, data-workflow-step-error) and new (data-tool-progress) logging events. To align with the PR's goal of standardizing logging, all workflow events should be migrated to the data-tool-progress format. For example, this step-start event should be an in-progress event.
| await writer?.custom({ | |
| type: 'data-tool-progress', | |
| data: { | |
| type: 'workflow', | |
| data: 'extract-learnings', | |
| id: 'extract-learnings', | |
| }, | |
| id: 'extract-learnings', | |
| }); | |
| await writer?.custom({ | |
| type: 'data-tool-progress', | |
| data: { | |
| status: 'in-progress', | |
| message: 'Starting step: extract-learnings', | |
| stage: 'workflow', | |
| }, | |
| id: 'extract-learnings', | |
| }); |
| await writer?.custom({ | ||
| type: 'data-workflow-step-error', | ||
| data: { | ||
| stepId: 'get-company-news', | ||
| error: error instanceof Error ? error.message : 'Unknown error', | ||
| }, | ||
| id: 'get-company-news', | ||
| }); |
There was a problem hiding this comment.
This workflow still uses the legacy data-workflow-step-error event type. To align with the PR's goal of standardizing logging, all workflow events should be migrated to the data-tool-progress format with an appropriate status (e.g., 'error').
| await writer?.custom({ | |
| type: 'data-workflow-step-error', | |
| data: { | |
| stepId: 'get-company-news', | |
| error: error instanceof Error ? error.message : 'Unknown error', | |
| }, | |
| id: 'get-company-news', | |
| }); | |
| await writer?.custom({ | |
| type: 'data-tool-progress', | |
| data: { | |
| status: 'error', | |
| message: error instanceof Error ? error.message : 'Unknown error', | |
| stage: 'workflow', | |
| }, | |
| id: 'get-company-news', | |
| }); |
| id: `${message.id}-${part.type}-${partIndex}`, | ||
| stage: "tool", | ||
| status: eventData.status === "success" ? "done" : eventData.status === "pending" ? "in-progress" : "error", | ||
| status: eventData.status === "done" ? "done" : (eventData.status === "pending" || eventData.status === "in-progress") ? "in-progress" : "error", |
| @@ -215,67 +238,67 @@ function extractSymbolInfo( | |||
| ): { name: string; kind: string } | null { | |||
There was a problem hiding this comment.
In the extractSymbolInfo function, the checks like if (name && name !== undefined && ...) are redundant. The name variable is of type string | undefined. A simple truthiness check if (name) is sufficient to guard against undefined and empty strings. The additional name !== undefined check adds unnecessary verbosity and can be removed to improve code clarity.
| priceData.push({ symbol, timestamp: new Date().toISOString() }); | ||
| } | ||
|
|
||
| // |
Greptile OverviewGreptile SummaryThis PR successfully refactors workflow logging to use a unified Key Changes:
Issues Found:
Confidence Score: 3/5
Important Files ChangedFile Analysis
Sequence DiagramsequenceDiagram
participant User
participant Workflow
participant Writer
participant Agent/Tool
participant Logger
User->>Workflow: Execute workflow step
Workflow->>Logger: logStepStart()
Workflow->>Writer: custom({ type: "data-tool-progress" })
Note over Writer: status: "in-progress"<br/>message: "Starting..."<br/>stage: "step-id"
Writer-->>User: Stream progress update
Workflow->>Agent/Tool: Execute operation
Agent/Tool->>Writer: custom({ type: "data-tool-progress" })
Note over Writer: Tool emits progress<br/>with same format
Writer-->>User: Stream tool progress
Agent/Tool-->>Workflow: Return result
Workflow->>Writer: custom({ type: "data-tool-progress" })
Note over Writer: status: "done"<br/>message: "Completed..."<br/>stage: "step-id"
Writer-->>User: Stream completion
Workflow->>Logger: logStepEnd()
Workflow-->>User: Return final output
alt Error occurs
Agent/Tool->>Writer: custom({ type: "data-tool-progress" })
Note over Writer: status: "error"<br/>message: error details
Writer-->>User: Stream error
Workflow->>Logger: logError()
end
|
| stepId: 'fetch-stock-data', | ||
| error: error instanceof Error ? error.message : 'Unknown error', | ||
| await writer?.custom({ | ||
| type: 'data-workflow-p', |
There was a problem hiding this comment.
syntax: type is incomplete - data-workflow-p should be data-tool-progress to match the refactoring pattern
| type: 'data-workflow-p', | |
| type: 'data-tool-progress', |
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/mastra/workflows/stock-analysis-workflow.ts
Line: 136:136
Comment:
**syntax:** type is incomplete - `data-workflow-p` should be `data-tool-progress` to match the refactoring pattern
```suggestion
type: 'data-tool-progress',
```
How can I resolve this? If you propose a fix, please make it concise.| type: 'data-workflow-step-complete', | ||
| type: 'data-tool-progress', | ||
| data: { | ||
| status: "success", |
There was a problem hiding this comment.
syntax: invalid status value - according to the style guide (src/mastra/tools/AGENTS.md lines 104-105), valid status values are "in-progress", "done", or "error" (not "success")
| status: "success", | |
| status: "done", |
Context Used: Context from dashboard - src/mastra/tools/AGENTS.md (source)
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/mastra/workflows/content-studio-workflow.ts
Line: 143:143
Comment:
**syntax:** invalid status value - according to the style guide (src/mastra/tools/AGENTS.md lines 104-105), valid status values are `"in-progress"`, `"done"`, or `"error"` (not `"success"`)
```suggestion
status: "done",
```
**Context Used:** Context from `dashboard` - src/mastra/tools/AGENTS.md ([source](https://app.greptile.com/review/custom-context?memory=82f7e036-3842-48e0-99d2-74ff94205ff1))
How can I resolve this? If you propose a fix, please make it concise.| type: 'data-tool-progress', | ||
| data: { | ||
| status: "100%", | ||
| status: "success", |
There was a problem hiding this comment.
syntax: invalid status value - should be "done" not "success"
| status: "success", | |
| status: "done", |
Context Used: Context from dashboard - src/mastra/tools/AGENTS.md (source)
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/mastra/workflows/content-studio-workflow.ts
Line: 199:199
Comment:
**syntax:** invalid status value - should be `"done"` not `"success"`
```suggestion
status: "done",
```
**Context Used:** Context from `dashboard` - src/mastra/tools/AGENTS.md ([source](https://app.greptile.com/review/custom-context?memory=82f7e036-3842-48e0-99d2-74ff94205ff1))
How can I resolve this? If you propose a fix, please make it concise.| type: 'data-tool-progress', | ||
| data: { | ||
| status: "100%", | ||
| status: "success", |
There was a problem hiding this comment.
syntax: invalid status value - should be "done" not "success"
| status: "success", | |
| status: "done", |
Context Used: Context from dashboard - src/mastra/tools/AGENTS.md (source)
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/mastra/workflows/content-studio-workflow.ts
Line: 253:253
Comment:
**syntax:** invalid status value - should be `"done"` not `"success"`
```suggestion
status: "done",
```
**Context Used:** Context from `dashboard` - src/mastra/tools/AGENTS.md ([source](https://app.greptile.com/review/custom-context?memory=82f7e036-3842-48e0-99d2-74ff94205ff1))
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
Actionable comments posted: 30
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (13)
src/mastra/tools/editor-agent-tool.ts (2)
28-36: Validate/normalize agent output againstoutputSchemabefore returning.Right now
parsedResultis untyped and can violateoutputSchema(e.g.,changesnot an array), which can break downstream UI/tooling despite having a schema defined.Suggested hardening:
- return { + return editorTool.outputSchema.parse({ editedContent: parsedResult.editedContent ?? parsedResult.copy ?? result.text, contentType: parsedResult.contentType ?? contentType, changes: parsedResult.changes ?? [ 'Content edited and improved', ], suggestions: parsedResult.suggestions ?? [], - } + })If
editorTool.outputSchemaisn’t accessible here, useoutputSchema.parse(...)by extracting it or defining a localconst outputSchema = ....Also applies to: 72-99
42-106: Span lifecycle: end spans in afinallyto avoid future early-return leaks.Current flow ends the span on success before the last
writer.custom, and on error within catch; that’s OK today, but brittle if more returns/throws are added insidetry. Prefertry/catch/finallywithspan.end()infinally(and keepSpanStatusCode.ERRORin catch).src/mastra/tools/finnhub-tools.ts (1)
69-112: Consider adding HTTP response status checking and timeouts.The tools have comprehensive error handling, but there are some gaps that could impact reliability:
HTTP status codes are not checked before attempting to parse the response. If the API returns a 4xx or 5xx status, the code might fail unexpectedly or miss the error condition.
No timeouts on fetch calls, which could cause requests to hang indefinitely if the API is slow or unresponsive.
No retry logic for transient failures, which could improve resilience.
No rate limiting to prevent resource exhaustion from excessive API calls.
Suggested improvements:
- Check HTTP status before parsing:
const response = await fetch(url); +if (!response.ok) { + throw new Error(`HTTP ${response.status}: ${response.statusText}`); +} const data = await response.json();
- Add timeout using AbortController:
const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), 10000); // 10s timeout try { const response = await fetch(url, { signal: controller.signal }); // ... rest of code } finally { clearTimeout(timeoutId); }
Consider implementing retry logic with exponential backoff for transient failures (5xx errors, network issues).
Consider implementing rate limiting to comply with API limits and prevent resource exhaustion.
Based on coding guidelines: "Implement try-catch error handling, clear error messages, and retries for API calls in tools" and "set timeouts for performance optimization in tools".
Also applies to: 223-286, 401-461, 570-622, 743-820, 926-956
app/workflows/providers/workflow-context.tsx (2)
259-266: ReplaceuseMemowithuseEffectfor side effects.Using
useMemofor side effects (updating state) is an anti-pattern in React.useMemoshould be pure and only compute derived values. State updates should be performed inuseEffect.Apply this diff:
- // Update workflow status based on chat status - useMemo(() => { - if (status === "streaming") { - setWorkflowStatus("running") - } else if (status === "ready" && workflowStatus === "running") { - setWorkflowStatus("completed") - } - }, [status, workflowStatus]) + // Update workflow status based on chat status + useEffect(() => { + if (status === "streaming") { + setWorkflowStatus("running") + } else if (status === "ready" && workflowStatus === "running") { + setWorkflowStatus("completed") + } + }, [status, workflowStatus])
411-425: Status mapping silently converts multiple non-compliant status values to "error".The handler at line 419 only recognizes
"done","pending", and"in-progress"as valid status values. Any other value—including"success","completed", and percentage strings like"20%"or"100%"—is silently mapped to"error".This affects multiple workflows currently in the codebase:
content-studio-workflow.ts: 8 emissions with"success"statuslearning-extraction-workflow.ts: 5 emissions with"completed"statusfinancial-report-workflow.ts: 3 emissions with"completed", 3 with"50%"statuschangelog.ts: 5 emissions with percentage statuses ("20%","50%","100%")document-processing-workflow.ts: 1 emission with"80%"statusAdd validation to log unexpected status values and clarify acceptable values, similar to the
data-workflow-progresshandler (lines 31-32):if (eventData && eventData.status !== null && typeof eventData.status === "string") { + // Warn on unexpected status values + if (!["done", "pending", "in-progress"].includes(eventData.status)) { + console.warn(`Unexpected data-tool-progress status: "${eventData.status}"`) + } + allProgressEvents.push({src/mastra/tools/financial-chart-tools.ts (1)
18-22: Consider adding format validation for stock symbols.The
symbolsarray accepts any string. For financial tools, stock symbols typically follow specific formats (e.g., 1-5 uppercase letters). Adding format validation would prevent malformed inputs and reduce prompt injection risk.symbols: z .array(z.string()) + .transform(arr => arr.map(s => s.toUpperCase().trim())) + .refine(arr => arr.every(s => /^[A-Z]{1,5}$/.test(s)), { + message: 'Symbols must be 1-5 uppercase letters' + }) .min(1) .describe('Stock symbols to visualize (e.g., ["AAPL", "GOOGL"])'),src/mastra/tools/copywriter-agent-tool.ts (2)
132-134: Dead code: condition is always true.Line 74 guarantees
userIdis always a non-empty string (either the extracted value or'anonymous'), so this check will always pass.- if (userId !== undefined) { - prompt += `\n\nUser: ${userId}` - } + prompt += `\n\nUser: ${userId}`
177-179: Throwing for valid enum value breaks runtime for users.
'general'is a validcontentTypeenum option in the input schema (line 24), but selecting it will throw an unhandled error. Either implement the case, remove it from the enum, or return a graceful error response similar to the agent unavailable handling.case 'general': { - throw new Error('Not implemented yet: "general" case') + prompt += + '\n\nCreate versatile general-purpose content suitable for multiple contexts.' + break }src/mastra/workflows/changelog.ts (1)
25-26: UnusedstartTimevariable.
startTimeis declared but never used in eitherstepA1orstepA2. If timing metrics are intended, add them to the progress events or span attributes; otherwise, remove the dead code.execute: async ({ mastra, writer }) => { - const startTime = Date.now();Also applies to: 241-242
src/mastra/workflows/content-review-workflow.ts (1)
244-268: Inconsistent stage naming pattern.The
draftContentStepuses generic stage names ("first","second","third") while other steps use agent-specific names like"researchAgent". Consider using a consistent naming convention across all steps—either descriptive stages tied to the step's purpose or a uniform pattern.Also applies to: 302-310
src/mastra/workflows/content-studio-workflow.ts (2)
153-153: Remove extraneous semicolons.Multiple step definitions end with double semicolons (
});;). While syntactically valid, these are likely typos and should be cleaned up.-});; +});Also applies to: 209-209, 263-263, 332-332, 493-493, 563-563
105-113: Missingstageproperty in progress events.The progress events in this file use
stepIdinstead ofstage, which differs from the pattern used in other workflow files (e.g.,content-review-workflow.ts,stock-analysis-workflow.ts). For consistency across the codebase, consider adding thestageproperty.await writer?.custom({ type: 'data-tool-progress', data: { status: "in-progress", message: "Starting research phase", + stage: "research-step", stepId: "research-step", }, id: 'research-step', });src/mastra/workflows/research-synthesis-workflow.ts (1)
253-260: Consider addingstagefield for consistency.Several
data-tool-progressevents in this file include astagefield (e.g., lines 75-78, 110-113, 129-132, 505), while others omit it. For consistent observability and filtering, consider addingstage: 'researchAgent'orstage: 'workflow'to these events as well.Also applies to: 267-274, 350-357, 419-426, 432-439
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (23)
.kilocode/rules/ai-elements-usage.md(1 hunks)app/workflows/providers/workflow-context.tsx(1 hunks)package.json(2 hunks)src/mastra/tools/AGENTS.md(0 hunks)src/mastra/tools/code-search.tool.ts(3 hunks)src/mastra/tools/copywriter-agent-tool.ts(4 hunks)src/mastra/tools/editor-agent-tool.ts(1 hunks)src/mastra/tools/financial-chart-tools.ts(10 hunks)src/mastra/tools/find-symbol.tool.ts(5 hunks)src/mastra/tools/finnhub-tools.ts(6 hunks)src/mastra/tools/multi-string-edit.tool.ts(2 hunks)src/mastra/workflows/AGENTS.md(2 hunks)src/mastra/workflows/changelog.ts(4 hunks)src/mastra/workflows/content-review-workflow.ts(14 hunks)src/mastra/workflows/content-studio-workflow.ts(16 hunks)src/mastra/workflows/document-processing-workflow.ts(17 hunks)src/mastra/workflows/financial-report-workflow.ts(18 hunks)src/mastra/workflows/governed-rag-index.workflow.ts(5 hunks)src/mastra/workflows/learning-extraction-workflow.ts(22 hunks)src/mastra/workflows/research-synthesis-workflow.ts(14 hunks)src/mastra/workflows/stock-analysis-workflow.ts(19 hunks)src/mastra/workflows/weather-workflow.ts(4 hunks)tsconfig.json(1 hunks)
💤 Files with no reviewable changes (1)
- src/mastra/tools/AGENTS.md
🧰 Additional context used
📓 Path-based instructions (20)
**/*.{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/editor-agent-tool.tssrc/mastra/workflows/governed-rag-index.workflow.tssrc/mastra/workflows/content-studio-workflow.tssrc/mastra/workflows/stock-analysis-workflow.tssrc/mastra/workflows/changelog.tssrc/mastra/tools/finnhub-tools.tssrc/mastra/tools/copywriter-agent-tool.tssrc/mastra/workflows/weather-workflow.tssrc/mastra/workflows/learning-extraction-workflow.tssrc/mastra/tools/financial-chart-tools.tssrc/mastra/workflows/research-synthesis-workflow.tssrc/mastra/workflows/document-processing-workflow.tssrc/mastra/workflows/financial-report-workflow.tssrc/mastra/tools/multi-string-edit.tool.tsapp/workflows/providers/workflow-context.tsxsrc/mastra/tools/find-symbol.tool.tssrc/mastra/workflows/content-review-workflow.tssrc/mastra/tools/code-search.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/tools/editor-agent-tool.tssrc/mastra/workflows/governed-rag-index.workflow.tssrc/mastra/workflows/content-studio-workflow.tssrc/mastra/workflows/stock-analysis-workflow.tssrc/mastra/workflows/changelog.tssrc/mastra/tools/finnhub-tools.tssrc/mastra/tools/copywriter-agent-tool.tssrc/mastra/workflows/weather-workflow.tssrc/mastra/workflows/learning-extraction-workflow.tssrc/mastra/tools/financial-chart-tools.tssrc/mastra/workflows/research-synthesis-workflow.tssrc/mastra/workflows/document-processing-workflow.tssrc/mastra/workflows/financial-report-workflow.tssrc/mastra/tools/multi-string-edit.tool.tssrc/mastra/tools/find-symbol.tool.tssrc/mastra/workflows/content-review-workflow.tssrc/mastra/tools/code-search.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
src/mastra/tools/**/*.ts: Emit progress events with exact format:type: 'data-tool-progress', withidoutsidedataobject andstatus/message/stageinsidedata
Implement try-catch error handling, clear error messages, and retries for API calls in tools
Sanitize inputs, mask secrets, and rate-limit in tools for security
Implement caching, stream large data, and set timeouts for performance optimization in tools
Add OpenTelemetry (Otel) spans on all tool executions for observability
Files:
src/mastra/tools/editor-agent-tool.tssrc/mastra/tools/finnhub-tools.tssrc/mastra/tools/copywriter-agent-tool.tssrc/mastra/tools/financial-chart-tools.tssrc/mastra/tools/multi-string-edit.tool.tssrc/mastra/tools/find-symbol.tool.tssrc/mastra/tools/code-search.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/editor-agent-tool.tssrc/mastra/workflows/governed-rag-index.workflow.tssrc/mastra/workflows/content-studio-workflow.tssrc/mastra/workflows/stock-analysis-workflow.tssrc/mastra/workflows/changelog.tssrc/mastra/tools/finnhub-tools.tssrc/mastra/tools/copywriter-agent-tool.tssrc/mastra/workflows/weather-workflow.tssrc/mastra/workflows/learning-extraction-workflow.tssrc/mastra/tools/financial-chart-tools.tssrc/mastra/workflows/research-synthesis-workflow.tssrc/mastra/workflows/document-processing-workflow.tssrc/mastra/workflows/financial-report-workflow.tssrc/mastra/tools/multi-string-edit.tool.tssrc/mastra/tools/find-symbol.tool.tssrc/mastra/workflows/content-review-workflow.tssrc/mastra/tools/code-search.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/editor-agent-tool.tssrc/mastra/workflows/governed-rag-index.workflow.tssrc/mastra/workflows/content-studio-workflow.tssrc/mastra/workflows/stock-analysis-workflow.tssrc/mastra/workflows/changelog.tssrc/mastra/tools/finnhub-tools.tssrc/mastra/tools/copywriter-agent-tool.tssrc/mastra/workflows/weather-workflow.tssrc/mastra/workflows/learning-extraction-workflow.tssrc/mastra/tools/financial-chart-tools.tssrc/mastra/workflows/research-synthesis-workflow.tssrc/mastra/workflows/document-processing-workflow.tssrc/mastra/workflows/financial-report-workflow.tssrc/mastra/tools/multi-string-edit.tool.tsapp/workflows/providers/workflow-context.tsxsrc/mastra/tools/find-symbol.tool.tssrc/mastra/workflows/content-review-workflow.tssrc/mastra/tools/code-search.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 thenext-devtools-mcpserver for all Next.js related queries
Files:
src/mastra/tools/editor-agent-tool.tssrc/mastra/workflows/governed-rag-index.workflow.tssrc/mastra/workflows/content-studio-workflow.tssrc/mastra/workflows/stock-analysis-workflow.tssrc/mastra/workflows/changelog.tssrc/mastra/tools/finnhub-tools.tssrc/mastra/tools/copywriter-agent-tool.tssrc/mastra/workflows/weather-workflow.tssrc/mastra/workflows/learning-extraction-workflow.tssrc/mastra/tools/financial-chart-tools.tssrc/mastra/workflows/research-synthesis-workflow.tssrc/mastra/workflows/document-processing-workflow.tssrc/mastra/workflows/financial-report-workflow.tssrc/mastra/tools/multi-string-edit.tool.tsapp/workflows/providers/workflow-context.tsxsrc/mastra/tools/find-symbol.tool.tssrc/mastra/workflows/content-review-workflow.tssrc/mastra/tools/code-search.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/tools/editor-agent-tool.tssrc/mastra/workflows/governed-rag-index.workflow.tssrc/mastra/workflows/content-studio-workflow.tssrc/mastra/workflows/stock-analysis-workflow.tssrc/mastra/workflows/changelog.tssrc/mastra/tools/finnhub-tools.tssrc/mastra/tools/copywriter-agent-tool.tssrc/mastra/workflows/weather-workflow.tssrc/mastra/workflows/learning-extraction-workflow.tssrc/mastra/tools/financial-chart-tools.tssrc/mastra/workflows/research-synthesis-workflow.tssrc/mastra/workflows/document-processing-workflow.tssrc/mastra/workflows/financial-report-workflow.tssrc/mastra/tools/multi-string-edit.tool.tsapp/workflows/providers/workflow-context.tsxsrc/mastra/tools/find-symbol.tool.tssrc/mastra/workflows/content-review-workflow.tssrc/mastra/tools/code-search.tool.ts
src/mastra/**/*
📄 CodeRabbit inference engine (src/AGENTS.md)
mastramodules can import fromutils, but must not import fromapporcli(excepttypes)
Files:
src/mastra/tools/editor-agent-tool.tssrc/mastra/workflows/governed-rag-index.workflow.tssrc/mastra/workflows/content-studio-workflow.tssrc/mastra/workflows/stock-analysis-workflow.tssrc/mastra/workflows/changelog.tssrc/mastra/tools/finnhub-tools.tssrc/mastra/tools/copywriter-agent-tool.tssrc/mastra/workflows/weather-workflow.tssrc/mastra/workflows/learning-extraction-workflow.tssrc/mastra/tools/financial-chart-tools.tssrc/mastra/workflows/research-synthesis-workflow.tssrc/mastra/workflows/document-processing-workflow.tssrc/mastra/workflows/financial-report-workflow.tssrc/mastra/tools/multi-string-edit.tool.tssrc/mastra/tools/find-symbol.tool.tssrc/mastra/workflows/content-review-workflow.tssrc/mastra/tools/code-search.tool.tssrc/mastra/workflows/AGENTS.md
**/*.{css,tsx,ts}
📄 CodeRabbit inference engine (AGENTS.md)
Use Tailwind CSS 4 with oklch color variables for styling
Files:
src/mastra/tools/editor-agent-tool.tssrc/mastra/workflows/governed-rag-index.workflow.tssrc/mastra/workflows/content-studio-workflow.tssrc/mastra/workflows/stock-analysis-workflow.tssrc/mastra/workflows/changelog.tssrc/mastra/tools/finnhub-tools.tssrc/mastra/tools/copywriter-agent-tool.tssrc/mastra/workflows/weather-workflow.tssrc/mastra/workflows/learning-extraction-workflow.tssrc/mastra/tools/financial-chart-tools.tssrc/mastra/workflows/research-synthesis-workflow.tssrc/mastra/workflows/document-processing-workflow.tssrc/mastra/workflows/financial-report-workflow.tssrc/mastra/tools/multi-string-edit.tool.tsapp/workflows/providers/workflow-context.tsxsrc/mastra/tools/find-symbol.tool.tssrc/mastra/workflows/content-review-workflow.tssrc/mastra/tools/code-search.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/editor-agent-tool.tssrc/mastra/workflows/governed-rag-index.workflow.tssrc/mastra/workflows/content-studio-workflow.tssrc/mastra/workflows/stock-analysis-workflow.tssrc/mastra/workflows/changelog.tssrc/mastra/tools/finnhub-tools.tssrc/mastra/tools/copywriter-agent-tool.tssrc/mastra/workflows/weather-workflow.tssrc/mastra/workflows/learning-extraction-workflow.tssrc/mastra/tools/financial-chart-tools.tssrc/mastra/workflows/research-synthesis-workflow.tssrc/mastra/workflows/document-processing-workflow.tssrc/mastra/workflows/financial-report-workflow.tssrc/mastra/tools/multi-string-edit.tool.tssrc/mastra/tools/find-symbol.tool.tssrc/mastra/workflows/content-review-workflow.tssrc/mastra/tools/code-search.tool.ts
src/mastra/tools/**/*.{ts,tsx}
📄 CodeRabbit inference engine (src/mastra/tools/AGENTS.md)
Define inputSchema and outputSchema using Zod for all tools in the tools directory
Files:
src/mastra/tools/editor-agent-tool.tssrc/mastra/tools/finnhub-tools.tssrc/mastra/tools/copywriter-agent-tool.tssrc/mastra/tools/financial-chart-tools.tssrc/mastra/tools/multi-string-edit.tool.tssrc/mastra/tools/find-symbol.tool.tssrc/mastra/tools/code-search.tool.ts
src/mastra/workflows/**/*.ts
📄 CodeRabbit inference engine (src/mastra/AGENTS.md)
Add new workflow definitions under
src/mastra/workflowsto orchestrate multi-step flowsUse Mastra DSL for multi-step workflow definitions in src/mastra/workflows
src/mastra/workflows/**/*.ts: Use the standardizedwriterpattern for all workflow step instrumentation with consistent progress tracking including step-start, progress updates (percentage-based), step-complete, and step-error events
Always include step-start at the beginning of each step's execute function using thedata-workflow-step-startmessage type
Use percentage-based status in progress updates (e.g., '20%', '50%', '90%', '100%') instead of 'in-progress'/'done' or other formats
Include step-complete with success status and duration in milliseconds for all successfully completed workflow steps
Include step-error in catch blocks to report workflow step failures with error message details
Add progress update checkpoints at logical stages (e.g., 20%, 50%, 90%) in addition to initial and final progress reports
Define workflows using Mastra DSL patterns (sequential.then(), parallel.parallel(), conditional.branch(), loop.dowhile(), iteration.foreach(), or human-in-the-loopsuspend()/resume())
Use tools and agents as building blocks in workflows; prefer composition over duplication
Keep workflow steps idempotent when possible and implement checkpointing for long-running operations
Reuse tools across workflows to reduce duplication
Add logs and robust error handling to workflow steps
UseTracingContextto instrument workflow steps with spans and useful metadata
Files:
src/mastra/workflows/governed-rag-index.workflow.tssrc/mastra/workflows/content-studio-workflow.tssrc/mastra/workflows/stock-analysis-workflow.tssrc/mastra/workflows/changelog.tssrc/mastra/workflows/weather-workflow.tssrc/mastra/workflows/learning-extraction-workflow.tssrc/mastra/workflows/research-synthesis-workflow.tssrc/mastra/workflows/document-processing-workflow.tssrc/mastra/workflows/financial-report-workflow.tssrc/mastra/workflows/content-review-workflow.ts
tsconfig*.json
📄 CodeRabbit inference engine (AGENTS.md)
Configure TypeScript with separate tsconfig.json for app (ES2022) and tsconfig.cli.json for CLI builds (CommonJS)
Files:
tsconfig.json
src/mastra/tools/**/*.tool.ts
📄 CodeRabbit inference engine (src/mastra/tools/AGENTS.md)
Create tools using
createTool()with Zod schemas for inputs and outputs in/src/mastra/tools
Files:
src/mastra/tools/multi-string-edit.tool.tssrc/mastra/tools/find-symbol.tool.tssrc/mastra/tools/code-search.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 thepages/directory for new projects.
Files:
app/workflows/providers/workflow-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/workflows/providers/workflow-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/workflows/providers/workflow-context.tsx
app/**/*.tsx
📄 CodeRabbit inference engine (AGENTS.md)
Use @ai-sdk/react for streaming and AI interactions in React components
Files:
app/workflows/providers/workflow-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
**/*.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:
src/mastra/workflows/AGENTS.md
🧬 Code graph analysis (2)
src/mastra/tools/copywriter-agent-tool.ts (1)
src/mastra/index.ts (1)
mastra(95-488)
src/mastra/workflows/learning-extraction-workflow.ts (1)
src/mastra/index.ts (1)
mastra(95-488)
⏰ 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). (5)
- GitHub Check: CodeQL analysis (javascript-typescript)
- GitHub Check: Agent
- GitHub Check: Sourcery review
- GitHub Check: Codacy Security Scan
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (28)
src/mastra/workflows/AGENTS.md (3)
44-141: Code examples effectively demonstrate data-tool-progress workflow patterns.The new "Agents and Tools events Workflows" section provides concrete examples that align well with the PR's unified progress logging objective. The
agentTextStreamWorkflowdemonstrates text streaming with agents using thewriter.pipeTo()pattern, and the examples show proper integration ofdata-tool-progressevents with structured metadata (status, stage, id).
143-396: Branching workflow examples properly implement event reporting pattern.The nested workflow examples (standard and express processing) correctly demonstrate
data-tool-progressevents with consistent stage naming and status updates. Error handling in thevalidateOrderstep (lines 182–200) properly includes error event reporting with thedata-tool-progresstype, showing good observability practices.
398-402: Clarify intent of empty sequence diagram section.The sequence diagram section is now empty. Per the AI summary, this content was removed/replaced intentionally as part of the PR. Please confirm whether this section should be:
- Retained with new sequence diagram content reflecting the updated event patterns, or
- Removed entirely if it's no longer needed.
src/mastra/tools/editor-agent-tool.ts (2)
37-41: EnforceRuntimeContextaccess control in tool execution.Guidelines call out
RuntimeContextfor tools/workflows;executecurrently runs without any explicit authorization/tenant scoping checks. If enforcement is done elsewhere, add a clear guard here (or document why it’s safe).
1-6: FixInferUIToolimport spacing.Line 1 has inconsistent spacing in the import statement:
import type { InferUITool}should beimport type { InferUITool }(add space before closing brace).src/mastra/tools/finnhub-tools.ts (1)
46-50: LGTM! Progress event structure follows guidelines correctly.The enriched progress events across all six Finnhub tools correctly implement the required format with
idoutside thedataobject andstatus,message, andstageinside thedataobject. The messages are contextual and descriptive, enhancing traceability of in-flight operations.Based on coding guidelines: "Emit progress events with exact format:
type: 'data-tool-progress', withidoutsidedataobject andstatus/message/stageinsidedata"Also applies to: 200-204, 378-382, 547-551, 720-724, 903-907
src/mastra/tools/financial-chart-tools.ts (2)
93-103: Good: Progress events follow the required format.The progress event structure correctly places
idoutside thedataobject and includesstatus,message, andstageinsidedata, complying with the coding guidelines.
95-103: Good: OpenTelemetry instrumentation is properly implemented.Spans are created with appropriate attributes and closed in both success and error paths (except for the early return cases noted separately).
src/mastra/tools/code-search.tool.ts (3)
84-92: Progress event format is correct.The structured progress event follows the required format with
idoutside thedataobject andstatus/message/stageinsidedata, aligning with the coding guidelines for tool progress events.
130-138: Intermediate progress update is well-structured.This provides useful feedback on the number of files to be searched, following the consistent progress event format.
223-231: Completion event provides a clear summary.The final progress event correctly signals completion with
status: 'done'and includes useful metrics about matches found..kilocode/rules/ai-elements-usage.md (2)
1-6: Well-structured documentation guide.The AI Elements usage guide provides comprehensive coverage of installation, usage patterns, component categories, and best practices. The glob patterns appropriately target relevant directories.
195-199: TheuseChathook from@ai-sdk/reactdoes returnsendMessageas shown in the code. The official API documentation confirms thatuseChatreturnssendMessage(message: CreateUIMessage | string, options?: ChatRequestOptions): voidalong withmessages,id,status, and other properties. The code snippet is correct and requires no changes.Likely an incorrect or invalid review comment.
src/mastra/tools/multi-string-edit.tool.ts (2)
243-244: Progress events follow the correct format.The progress events correctly use
type: 'data-tool-progress'withidoutside thedataobject andstatus/message/stageinsidedata, matching the coding guidelines.
235-237: TheRequestContexttype assertion and usage pattern are correct and follow established conventions throughout the codebase. Optional chaining (?.get()) provides null-safety, and the fallback value (?? 1_000_000) handles missing configuration appropriately. No guard is necessary here, as this pattern is consistently used across multiple tools without guards (csv-to-json.tool.ts, find-symbol.tool.ts, pnpm-tool.ts, etc.). TheRequestContextfrom@mastra/core/request-contextis the appropriate type for configuration access in tools.package.json (1)
46-49: Patch version updates are valid.All four AI SDK packages have been verified to exist on npm:
- @ai-sdk/google-vertex@3.0.91 ✓
- @ai-sdk/openai@2.0.86 ✓
- @ai-sdk/openai-compatible@1.0.29 ✓
- @ai-sdk/react@2.0.115 ✓
These are safe minor patch bumps for the AI SDK packages.
src/mastra/tools/find-symbol.tool.ts (1)
78-87: Progress event format looks correct.The progress event structure follows the required format with
type: 'data-tool-progress',idoutside thedataobject, andstatus/message/stageinsidedata. This aligns with the PR objective to standardize progress logging.src/mastra/tools/copywriter-agent-tool.ts (1)
73-74: LGTM on userId extraction with fallback.Good defensive handling with trim check and fallback to 'anonymous'.
src/mastra/workflows/changelog.ts (1)
37-46: Progress event format follows the standardized pattern.The event structure correctly uses
type: 'data-tool-progress'withstatus,message, andstageinside thedataobject, andidoutside. Stage renamed togitDiffAgentaligns with the PR's agent-specific naming convention.src/mastra/workflows/weather-workflow.ts (2)
57-65: Progress events in fetch-weather follow correct format.Events properly use
type: 'data-tool-progress'withidoutsidedataandstatus/messageinside. Good consistency with the PR's standardization effort.Also applies to: 106-114
217-228: This concern is incorrect;response.textandtextStreamare independent in Mastra's stream API.The pattern of piping
textStreamto a writer and then accessingtextis used consistently throughout the codebase (content-review-workflow.ts, financial-report-workflow.ts, spec-generation-workflow.ts) without issues. Thetextproperty is a separate Promise that doesn't get consumed bypipeTo(). The code is correctly designed to stream progress updates viatextStreamwhile simultaneously collecting the full text viatextfor parsing.Likely an incorrect or invalid review comment.
src/mastra/workflows/governed-rag-index.workflow.ts (1)
75-82: Missingidfield in progress event.Per coding guidelines, progress events should include
idoutside thedataobject. This event and subsequent ones in this file are missing theidfield, which is inconsistent with other files in this PR.await writer?.custom({ type: 'data-tool-progress', data: { status: "in-progress", message: `PgVector index ${indexName} created or already exists with 1568 dimensions`, stage: "documentIndexingAgent", - } + }, + id: "index-documents" });Likely an incorrect or invalid review comment.
src/mastra/workflows/stock-analysis-workflow.ts (2)
78-106: LGTM on progress signaling pattern.The progress signaling in
fetchStockDataStepcorrectly uses the newdata-tool-progresstype with consistent'in-progress'and'done'status values and a uniform'workflow'stage.
182-216: Good graceful degradation for missing API key.The handling when
FINNHUB_API_KEYis not set properly emits progress events, logs the situation, and returns a valid empty result rather than throwing. This maintains workflow resilience.src/mastra/workflows/financial-report-workflow.ts (1)
680-688: Good use of 'completed' status for step finalization.The merge-data, analyze-data, and generate-report steps consistently use
'completed'status with descriptive messages for their final progress events. This provides clear signaling of step completion.Also applies to: 852-860, 1024-1032
src/mastra/workflows/learning-extraction-workflow.ts (1)
139-162: LGTM on progress signaling consistency.The progress events in
extractLearningsStepcorrectly use thedata-tool-progresstype with consistentstatus,message, andstageproperties. The status transitions ('in-progress'→'completed') are logical.Also applies to: 237-245
src/mastra/workflows/content-studio-workflow.ts (2)
126-136: Good defensive parsing with schema validation.The steps properly handle JSON parsing failures by catching exceptions and falling back to default values that satisfy the output schemas. Using Zod's
.parse()for runtime validation adds an extra layer of type safety.Also applies to: 182-193, 238-247, 302-316, 362-370, 410-416, 462-476, 540-546
567-586: LGTM on workflow definition and loop condition.The workflow is well-structured using Mastra DSL patterns with a clear
dowhileloop that continues refinement until the score reaches 80 or above.
| {messages.map(({ role, parts }, index) => ( | ||
| <Message from={role} key={index}> |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Consider using stable keys in the example.
Using array index as React key (key={index}) can cause issues with component state when messages are reordered or removed. For a production-ready example, consider using message.id if available:
{messages.map((message) => (
<Message from={message.role} key={message.id}>This would align better with the streaming example on line 219 which uses message.id.
🤖 Prompt for AI Agents
In .kilocode/rules/ai-elements-usage.md around lines 73 to 74, the example uses
array index as the React key (key={index}) which can break component identity
when messages change; replace the index with a stable identifier such as
message.id (e.g., key={message.id}) and if message.id may be undefined, fall
back to a stable alternative (like a generated UUID assigned when creating the
message) so keys remain stable across reorders/removals.
| if (writer && typeof agentWithStream.stream === 'function') { | ||
| const stream = await agentWithStream.stream(prompt) | ||
|
|
||
| if (stream.fullStream) { | ||
| await stream.fullStream.pipeTo(writer as unknown as WritableStream) | ||
| } else if (stream.textStream) { | ||
| await stream.textStream.pipeTo(writer as unknown as WritableStream) | ||
| } | ||
|
|
||
| contentText = (await stream.text) ?? '' | ||
| } else { | ||
| const result = await agentWithStream.generate(prompt) | ||
| contentText = result.text | ||
| } |
There was a problem hiding this comment.
Streaming logic lacks error handling and uses unsafe casts.
The streaming path has several concerns:
- No try-catch around
pipeTowhich can throw if the writer is closed or incompatible - If streaming completes via
pipeTo, the writer may be closed, butcontentTextextraction still occurs - Heavy use of
unknowncasts bypasses type safety
Consider wrapping the streaming logic in try-catch and verifying the writer interface compatibility.
let contentText = ''
if (writer && typeof agentWithStream.stream === 'function') {
- const stream = await agentWithStream.stream(prompt)
-
- if (stream.fullStream) {
- await stream.fullStream.pipeTo(writer as unknown as WritableStream)
- } else if (stream.textStream) {
- await stream.textStream.pipeTo(writer as unknown as WritableStream)
+ try {
+ const stream = await agentWithStream.stream(prompt)
+ if (stream.fullStream) {
+ await stream.fullStream.pipeTo(writer as unknown as WritableStream)
+ } else if (stream.textStream) {
+ await stream.textStream.pipeTo(writer as unknown as WritableStream)
+ }
+ contentText = (await stream.text) ?? ''
+ } catch (streamError) {
+ log.warn('Streaming failed, falling back to generate', { error: streamError })
+ const result = await agentWithStream.generate(prompt)
+ contentText = result.text
}
-
- contentText = (await stream.text) ?? ''
} else {| if (!agent) { | ||
| await context?.writer?.custom({ type: 'data-tool-progress', data: { status: 'done', message: '❌ chartSupervisorAgent not found', stage: 'chart-supervisor' }, id: 'chart-supervisor' }) | ||
| return { | ||
| success: false, | ||
| sources: [], | ||
| error: 'Agent chartSupervisorAgent not found', | ||
| } | ||
| } |
There was a problem hiding this comment.
Span is not closed on early return when agent is not found.
When the agent is missing, the function returns early but the OpenTelemetry span started at line 96 is never closed. This will cause span leaks and incomplete traces.
if (!agent) {
await context?.writer?.custom({ type: 'data-tool-progress', data: { status: 'done', message: '❌ chartSupervisorAgent not found', stage: 'chart-supervisor' }, id: 'chart-supervisor' })
+ span.setStatus({ code: 2, message: 'Agent not found' })
+ span.end()
return {
success: false,
sources: [],
error: 'Agent chartSupervisorAgent not found',
}
}The same issue exists in chartDataProcessorTool (lines 441-456) - span needs to be closed there as well.
📝 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 (!agent) { | |
| await context?.writer?.custom({ type: 'data-tool-progress', data: { status: 'done', message: '❌ chartSupervisorAgent not found', stage: 'chart-supervisor' }, id: 'chart-supervisor' }) | |
| return { | |
| success: false, | |
| sources: [], | |
| error: 'Agent chartSupervisorAgent not found', | |
| } | |
| } | |
| if (!agent) { | |
| await context?.writer?.custom({ type: 'data-tool-progress', data: { status: 'done', message: '❌ chartSupervisorAgent not found', stage: 'chart-supervisor' }, id: 'chart-supervisor' }) | |
| span.setStatus({ code: 2, message: 'Agent not found' }) | |
| span.end() | |
| return { | |
| success: false, | |
| sources: [], | |
| error: 'Agent chartSupervisorAgent not found', | |
| } | |
| } |
🤖 Prompt for AI Agents
In src/mastra/tools/financial-chart-tools.ts around lines 107 to 114 (and
similarly for chartDataProcessorTool around lines 441 to 456), the OpenTelemetry
span started earlier (line ~96) is not ended on the early return when the agent
is not found; update the code to ensure the span is closed before returning by
calling span.end() (and also setting span status or recording the error if
available) right before sending the progress message and returning the error
object; apply the same fix in the chartDataProcessorTool early-return path so
both spans are properly ended on error.
| const agentWithStream = agent as unknown as { | ||
| stream?: (_prompt: string) => Promise<{ fullStream?: ReadableStream<unknown>; textStream?: ReadableStream<unknown>; text?: Promise<string | undefined> }> | ||
| generate: (_prompt: string) => Promise<{ text: string }> | ||
| } | ||
|
|
||
| if (writer && typeof agentWithStream.stream === 'function') { | ||
| const stream = await agentWithStream.stream(prompt) | ||
| if (stream.fullStream) { | ||
| await stream.fullStream.pipeTo(writer as unknown as WritableStream) | ||
| } else if (stream.textStream) { | ||
| await stream.textStream.pipeTo(writer as unknown as WritableStream) | ||
| } | ||
| resultText = (await stream.text) ?? '' | ||
| } else { | ||
| const result = await agentWithStream.generate(prompt) | ||
| resultText = result.text | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
Extract duplicated streaming logic into a helper function.
This streaming pattern with type casting is repeated verbatim across all four tools (lines 136-152, 308-324, 484-500, 661-677). This violates DRY and introduces maintenance burden.
Additionally, the as unknown as {...} cast bypasses type safety entirely. Consider defining a proper interface for streamable agents.
Extract to a shared helper:
// At file top or in a shared module
interface StreamableAgent {
stream?: (prompt: string) => Promise<{
fullStream?: ReadableStream<unknown>;
textStream?: ReadableStream<unknown>;
text?: Promise<string | undefined>;
}>;
generate: (prompt: string) => Promise<{ text: string }>;
}
async function executeAgentWithStreaming(
agent: unknown,
prompt: string,
writer?: { custom: (data: unknown) => Promise<void> } & WritableStream
): Promise<string> {
const streamableAgent = agent as StreamableAgent;
if (writer && typeof streamableAgent.stream === 'function') {
const stream = await streamableAgent.stream(prompt);
if (stream.fullStream) {
await stream.fullStream.pipeTo(writer as unknown as WritableStream);
} else if (stream.textStream) {
await stream.textStream.pipeTo(writer as unknown as WritableStream);
}
return (await stream.text) ?? '';
}
const result = await streamableAgent.generate(prompt);
return result.text;
}Then replace each duplicated block with:
const resultText = await executeAgentWithStreaming(agent, prompt, writer);🤖 Prompt for AI Agents
In src/mastra/tools/financial-chart-tools.ts around lines 136 to 152, the
streaming/generate logic is duplicated verbatim across four locations and uses
an unsafe as unknown as {...} cast; extract that logic to a single helper and
use a proper typed interface. Define a StreamableAgent interface (stream? and
generate) at the top or in a shared module, implement an async helper (e.g.,
executeAgentWithStreaming(agent, prompt, writer)) that performs the stream
checks (fullStream/textStream piping) and falls back to generate, and then
replace the duplicated blocks at lines 136-152, 308-324, 484-500, 661-677 with a
single call to that helper returning resultText. Ensure you remove the unsafe
cast and cast only to the new typed interface inside the helper.
| if (writer && typeof agentWithStream.stream === 'function') { | ||
| const stream = await agentWithStream.stream(prompt) | ||
| if (stream.fullStream) { | ||
| await stream.fullStream.pipeTo(writer as unknown as WritableStream) | ||
| } else if (stream.textStream) { | ||
| await stream.textStream.pipeTo(writer as unknown as WritableStream) | ||
| } | ||
| resultText = (await stream.text) ?? '' | ||
| } else { | ||
| const result = await agentWithStream.generate(prompt) | ||
| resultText = result.text | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Consider adding timeout protection for agent calls.
Per coding guidelines, tools should "set timeouts for performance optimization." The agent stream() and generate() calls have no timeout protection and could hang indefinitely.
Consider wrapping agent calls with Promise.race() or using AbortController:
const AGENT_TIMEOUT_MS = 30000;
const timeoutPromise = new Promise<never>((_, reject) =>
setTimeout(() => reject(new Error('Agent call timed out')), AGENT_TIMEOUT_MS)
);
const result = await Promise.race([
agentWithStream.generate(prompt),
timeoutPromise
]);🤖 Prompt for AI Agents
In src/mastra/tools/financial-chart-tools.ts around lines 141-152, the
agentWithStream.stream() and .generate() calls lack timeout protection and may
hang indefinitely; add a timeout (e.g., AGENT_TIMEOUT_MS) by racing the agent
promise against a rejecting timeout promise or by using an AbortController if
the agent supports abort signals, ensure the controller is aborted on timeout to
free resources, handle and rethrow or log the timeout error, and make sure any
writer or partial streams are properly closed/cleaned up when a timeout occurs.
| if (!inputData.requireApproval) { | ||
| await writer?.write({ | ||
| type: 'progress', | ||
| percent: 100, | ||
| message: 'Auto-approval (requireApproval=false)...', | ||
| await writer?.custom({ | ||
| type: 'data-tool-progress', | ||
| data: { | ||
| status: 'completed', | ||
| message: 'Auto-approval (requireApproval=false)...', | ||
| stage: 'workflow', | ||
| }, | ||
| id: 'human-approval', | ||
| }); |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Status message could be more accurate.
The status is 'completed' with message 'Auto-approval (requireApproval=false)...'. Consider using a more specific status like 'auto-approved' or adjusting the message to not end with ellipsis since this is a terminal state.
await writer?.custom({
type: 'data-tool-progress',
data: {
- status: 'completed',
- message: 'Auto-approval (requireApproval=false)...',
+ status: 'completed',
+ message: 'Auto-approved (human approval not required)',
stage: 'workflow',
},
id: 'human-approval',
});📝 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 (!inputData.requireApproval) { | |
| await writer?.write({ | |
| type: 'progress', | |
| percent: 100, | |
| message: 'Auto-approval (requireApproval=false)...', | |
| await writer?.custom({ | |
| type: 'data-tool-progress', | |
| data: { | |
| status: 'completed', | |
| message: 'Auto-approval (requireApproval=false)...', | |
| stage: 'workflow', | |
| }, | |
| id: 'human-approval', | |
| }); | |
| if (!inputData.requireApproval) { | |
| await writer?.custom({ | |
| type: 'data-tool-progress', | |
| data: { | |
| status: 'completed', | |
| message: 'Auto-approved (human approval not required)', | |
| stage: 'workflow', | |
| }, | |
| id: 'human-approval', | |
| }); |
🤖 Prompt for AI Agents
In src/mastra/workflows/learning-extraction-workflow.ts around lines 322 to 331,
the progress event for auto-approval uses a generic status 'completed' and a
message that ends with an ellipsis; change the status to a more specific
terminal value such as 'auto-approved' (or 'approved:auto') and update the
message to a definitive sentence without trailing ellipsis (e.g., 'Auto-approved
(requireApproval=false)'). Ensure the id and stage remain the same and update
any downstream consumers if they rely on the old 'completed' status.
| await writer?.custom({ | ||
| type: 'data-workflow-topic-progress', | ||
| type: 'data-tool-progress', | ||
| data: { | ||
| topic: inputData.topic, | ||
| status: 'error', | ||
| error: error instanceof Error ? error.message : 'Unknown error', | ||
| status: 'in-progress', | ||
| message: `Research error for ${inputData.topic}...`, | ||
| stage: 'researchAgent', | ||
| }, | ||
| id: 'research-topic-item', | ||
| }); |
There was a problem hiding this comment.
Fix incorrect error status.
The error handler uses status: 'in-progress' which incorrectly suggests the operation is still running. Additionally, this deviates from the error handling pattern used in other steps (lines 388-395, 535-543) which use data-workflow-step-error.
Apply this diff to align with the error handling pattern used elsewhere in this file:
await writer?.custom({
- type: 'data-tool-progress',
+ type: 'data-workflow-step-error',
data: {
- status: 'in-progress',
- message: `Research error for ${inputData.topic}...`,
- stage: 'researchAgent',
+ stepId: 'research-topic-item',
+ error: error instanceof Error ? error.message : `Research error for ${inputData.topic}`,
},
id: 'research-topic-item',
});🤖 Prompt for AI Agents
In src/mastra/workflows/research-synthesis-workflow.ts around lines 211 to 219,
the error handler currently emits a progress event with status 'in-progress' and
type 'data-tool-progress'; change it to follow the file's error pattern by
emitting type 'data-workflow-step-error' and status 'error' (keep the message,
stage 'researchAgent' and id 'research-topic-item' consistent), so the event
aligns with other error handlers in this workflow.
| await writer?.custom({ | ||
| type: 'data-workflow-p', | ||
| data: { | ||
| stepId: 'fetch-stock-data', | ||
| error: error instanceof Error ? error.message : 'Unknown error', | ||
| }, | ||
| id: 'fetch-stock-data', | ||
| }); |
There was a problem hiding this comment.
Critical typo in error event type.
The event type 'data-workflow-p' appears to be a truncated/typo version of 'data-workflow-step-error'. This will cause error events to not be properly recognized by consumers, breaking error handling and observability.
await writer?.custom({
- type: 'data-workflow-p',
+ type: 'data-workflow-step-error',
data: {
stepId: 'fetch-stock-data',
error: error instanceof Error ? error.message : 'Unknown error',
},
id: 'fetch-stock-data',
});🤖 Prompt for AI Agents
In src/mastra/workflows/stock-analysis-workflow.ts around lines 135 to 142, the
event type string 'data-workflow-p' is a typo and should be
'data-workflow-step-error'; update the writer.custom call to use type:
'data-workflow-step-error' (leave the rest of the payload intact), and verify
any other occurrences in this file or related consumers are using the corrected
type so error events are recognized properly.
| if (writer !== undefined && writer !== null) { | ||
| if (fullStream !== undefined && typeof (fullStream as unknown as { pipeTo?: unknown }).pipeTo === 'function') { | ||
| await (fullStream as unknown as ReadableStream<unknown>).pipeTo(writer as unknown as WritableStream) | ||
| } else if (textStream !== undefined && typeof (textStream as unknown as { pipeTo?: unknown }).pipeTo === 'function') { | ||
| await (textStream as unknown as ReadableStream<unknown>).pipeTo(writer as unknown as WritableStream) | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Excessive type assertions reduce maintainability.
The nested as unknown as casts bypass type safety. If the Mastra agent's stream API is typed, consider importing and using those types. If not, this could be a candidate for creating a shared utility or type definition.
🤖 Prompt for AI Agents
In src/mastra/workflows/weather-workflow.ts around lines 220 to 225, the code
uses nested "as unknown as" casts to force types for fullStream/textStream and
writer which bypasses TypeScript safety; replace these casts by importing or
declaring the correct stream interfaces (e.g., the Mastra agent
ReadableStream/WritableStream types or standard DOM/stream types) and use a
proper type guard (function isReadableWithPipeTo(x): x is ReadableStream<any> {
return x && typeof (x as any).pipeTo === 'function' }) before calling pipeTo,
typing writer as the corresponding WritableStream type; if Mastra does not
export types, add a small shared type definition or utility type and reuse it
rather than double-casting.
| ".next/dev/types/**/*.ts", | ||
| "app/**/*.ts", | ||
| "app/**/*.tsx", | ||
| "src/mastra/workflows/*.ts", |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Redundant include pattern.
The pattern "src/mastra/workflows/*.ts" is already covered by "src/**/*.ts" on line 52. This entry can be removed unless you intend to prioritize or explicitly document workflow files.
- "src/mastra/workflows/*.ts",📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| "src/mastra/workflows/*.ts", |
🤖 Prompt for AI Agents
In tsconfig.json around line 51 the include entry "src/mastra/workflows/*.ts" is
redundant because "src/**/*.ts" on line 52 already covers it; remove the
specific workflows include (or explicitly document/justify it if you intend
special handling) so the include list is not duplicated and keep only the
broader pattern unless you have a deliberate reason to prioritize workflow
files.
There was a problem hiding this comment.
Pull request overview
This PR refactors the logging mechanism across multiple workflows and tools to standardize progress tracking under the 'data-tool-progress' event type. The changes aim to improve consistency and clarity in how workflow execution progress is communicated to clients.
Key Changes:
- Unified all progress logging to use 'data-tool-progress' type instead of mixed types ('data-workflow-progress', 'data-workflow-step-start', etc.)
- Standardized status values to 'in-progress', 'done', and 'error' (replacing percentage-based values)
- Removed redundant step-start and step-complete logging events
- Added comprehensive documentation for AI Elements usage and Copilot instructions
- Updated TypeScript configuration to include workflow files
- Minor package version updates for AI SDK dependencies
Reviewed changes
Copilot reviewed 22 out of 25 changed files in this pull request and generated 38 comments.
Show a summary per file
| File | Description |
|---|---|
| tsconfig.json | Added workflow directory to TypeScript compilation |
| src/mastra/workflows/*.ts | Refactored 8 workflow files to use unified 'data-tool-progress' logging pattern |
| src/mastra/tools/*.ts | Updated 6 tool files to include proper status, message, and stage fields in progress events |
| src/mastra/workflows/AGENTS.md | Expanded with detailed workflow examples and event patterns |
| .kilocode/rules/ai-elements-usage.md | New comprehensive guide for AI Elements library usage |
| .github/-/taming-copilot.instructions.md | New instructions for controlling Copilot behavior |
| app/workflows/providers/workflow-context.tsx | Updated status handling to support both 'success' and 'done' values |
| package.json & package-lock.json | Minor version bumps for AI SDK packages |
Comments suppressed due to low confidence (1)
src/mastra/workflows/document-processing-workflow.ts:408
- This string is not a template literal, but appears to reference the variable inputData.
message: "Text passed through successfully ${inputData.content}`,",
| excludePatterns?: string[]; | ||
| includeNodeModules?: boolean; | ||
| caseSensitive?: boolean; | ||
| searchType: 'semantic' | 'text'; // Required field |
There was a problem hiding this comment.
The SymbolContext interface defines searchType as a required field with specific values ('semantic' | 'text'), but this field is never accessed or used in the tool's execute function. This creates unnecessary requirements for consumers of this interface.
| searchType: 'semantic' | 'text'; // Required field |
| type: 'data-tool-progress', | ||
| data: { | ||
| status: "100%", | ||
| status: "success", |
There was a problem hiding this comment.
The status field uses 'success' which is inconsistent with the standardized status values. According to the PR pattern, this should be 'done' to indicate completion. This pattern appears multiple times in this file (lines 199, 253, 322, 376, 420, 483, 553).
| status: "success", | |
| status: "done", |
| type: 'data-tool-progress', | ||
| data: { | ||
| status: "done", // must be "done" for the UI to show the step as completed | ||
| message: "Text passed through successfully ${inputData.content}`,", |
There was a problem hiding this comment.
The message has incomplete interpolation syntax with a trailing backtick and comma: "Text passed through successfully ${inputData.content}`,". This will cause a syntax error. The template literal is not properly closed.
| message: "Text passed through successfully ${inputData.content}`,", | |
| message: `Text passed through successfully ${inputData.content}`, |
| priceData.push({ symbol, timestamp: new Date().toISOString() }); | ||
| } | ||
|
|
||
| // |
There was a problem hiding this comment.
Incomplete comment with just "// " at this line. This should either be removed or completed with meaningful content.
| // |
| const userIdVal = context?.requestContext?.get('userId') | ||
| const userId = typeof userIdVal === 'string' && userIdVal.trim().length > 0 ? userIdVal : 'anonymous' |
There was a problem hiding this comment.
The removal of Zod schema validation for the copywriter context and replacement with a simple string check reduces type safety. The original copywriterToolContextSchema.parse() provided runtime validation, while the new code only checks if the value is a non-empty string. Consider maintaining type safety while simplifying the code.
| stage: 'analyze-data', | ||
| }, | ||
| id: 'analyze-data', | ||
| }) |
There was a problem hiding this comment.
Avoid automated semicolon insertion (93% of all statements in the enclosing function have an explicit semicolon).
| }) | |
| }); |
| stage: 'analyze-data', | ||
| }, | ||
| id: 'analyze-data', | ||
| }) |
There was a problem hiding this comment.
Avoid automated semicolon insertion (93% of all statements in the enclosing function have an explicit semicolon).
| }) | |
| }); |
| stage: 'generate-report', | ||
| }, | ||
| id: 'generate-report', | ||
| }) |
There was a problem hiding this comment.
Avoid automated semicolon insertion (92% of all statements in the enclosing function have an explicit semicolon).
| }) | |
| }); |
| stage: 'generate-report', | ||
| }, | ||
| id: 'generate-report', | ||
| }) |
There was a problem hiding this comment.
Avoid automated semicolon insertion (92% of all statements in the enclosing function have an explicit semicolon).
| }) | |
| }); |
| stage: 'generate-report', | ||
| }, | ||
| id: 'generate-report', | ||
| }) |
There was a problem hiding this comment.
Avoid automated semicolon insertion (92% of all statements in the enclosing function have an explicit semicolon).
| }) | |
| }); |

Summary by Sourcery
Standardize tool and workflow progress logging onto
data-tool-progressevents, enhance streaming behavior for several AI tools and workflows, and expand documentation and typing support for AI/semantic tooling.New Features:
Bug Fixes:
doneandin-progressstates for tool events.Enhancements:
data-tool-progress, simplifying UI handling and status mapping.Build:
Documentation: