Conversation
Bug Report
Comments? Email us. This is the last day of your free trial. Subscribe at jazzberry.ai. |
|
Caution Review failedThe pull request is closed. WalkthroughThis update introduces a modular workflow engine for processing email threads, replacing the previous inline logic for draft generation, vectorization, summarization, and labeling. New workflow utilities and functions are added, with documentation. Several methods are refactored or commented out, and some SQL queries are corrected for thread ID consistency. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Server
participant WorkflowEngine
participant WorkflowFunctions
participant Agent
participant AIService
participant Database
User->>Server: Trigger runThreadWorkflow
Server->>WorkflowEngine: Initialize and execute workflows
loop For each workflow
WorkflowEngine->>WorkflowFunctions: Execute workflow steps
alt Draft Generation
WorkflowFunctions->>AIService: Analyze intent, generate draft
WorkflowFunctions->>Agent: Create draft
else Message Vectorization
WorkflowFunctions->>AIService: Summarize, embed messages
WorkflowFunctions->>Database: Upsert embeddings
else Thread Summary
WorkflowFunctions->>AIService: Generate summary
WorkflowFunctions->>Database: Upsert summary
else Label Generation
WorkflowFunctions->>AIService: Generate labels
WorkflowFunctions->>Agent: Apply labels
end
end
WorkflowEngine->>Server: Return results & errors
Server->>User: Log and respond
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (12)
✨ Finishing Touches
🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.
There was a problem hiding this comment.
Bugbot free trial expires on July 29, 2025
Learn more in the Cursor dashboard.
There was a problem hiding this comment.
Actionable comments posted: 7
🔭 Outside diff range comments (1)
apps/server/src/pipelines.effect.ts (1)
826-870: Remove unused threadToXML functionThis function is no longer used after the workflow engine refactor. Delete it to keep the codebase clean.
♻️ Duplicate comments (1)
apps/server/src/thread-workflow-utils/workflow-engine.ts (1)
11-58: More code duplicationAs mentioned in workflow-functions.ts, these utility functions need to be extracted to a shared module.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (7)
apps/server/src/pipelines.effect.ts(3 hunks)apps/server/src/routes/agent/index.ts(5 hunks)apps/server/src/routes/agent/rpc.ts(4 hunks)apps/server/src/thread-workflow-utils/README.md(1 hunks)apps/server/src/thread-workflow-utils/workflow-engine.ts(1 hunks)apps/server/src/thread-workflow-utils/workflow-functions.ts(1 hunks)apps/server/src/trpc/routes/mail.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit Inference Engine (AGENT.md)
**/*.{js,jsx,ts,tsx}: Use 2-space indentation
Use single quotes
Limit lines to 100 characters in width
Semicolons are required
Files:
apps/server/src/trpc/routes/mail.tsapps/server/src/routes/agent/rpc.tsapps/server/src/routes/agent/index.tsapps/server/src/thread-workflow-utils/workflow-functions.tsapps/server/src/thread-workflow-utils/workflow-engine.tsapps/server/src/pipelines.effect.ts
**/*.{js,jsx,ts,tsx,css}
📄 CodeRabbit Inference Engine (AGENT.md)
Use Prettier with sort-imports and Tailwind plugins
Files:
apps/server/src/trpc/routes/mail.tsapps/server/src/routes/agent/rpc.tsapps/server/src/routes/agent/index.tsapps/server/src/thread-workflow-utils/workflow-functions.tsapps/server/src/thread-workflow-utils/workflow-engine.tsapps/server/src/pipelines.effect.ts
**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (AGENT.md)
Enable TypeScript strict mode
Files:
apps/server/src/trpc/routes/mail.tsapps/server/src/routes/agent/rpc.tsapps/server/src/routes/agent/index.tsapps/server/src/thread-workflow-utils/workflow-functions.tsapps/server/src/thread-workflow-utils/workflow-engine.tsapps/server/src/pipelines.effect.ts
🧠 Learnings (7)
📓 Common learnings
Learnt from: JagjeevanAK
PR: Mail-0/Zero#1583
File: apps/docs/package.json:1-0
Timestamp: 2025-07-01T12:53:32.495Z
Learning: The Zero project prefers to handle dependency updates through automated tools like Dependabot rather than immediate manual updates, allowing for proper testing and validation through their established workflow.
apps/server/src/trpc/routes/mail.ts (5)
Learnt from: retrogtx
PR: #1468
File: apps/server/src/trpc/routes/mail.ts:386-391
Timestamp: 2025-06-27T04:59:29.731Z
Learning: In apps/server/src/trpc/routes/mail.ts, the attachment processing logic conditionally handles mixed attachment types - it preserves existing File-like objects with arrayBuffer methods while only converting serialized attachments that need processing through toAttachmentFiles.
Learnt from: retrogtx
PR: #1734
File: apps/server/src/lib/driver/google.ts:211-221
Timestamp: 2025-07-15T06:46:33.349Z
Learning: In apps/server/src/lib/driver/google.ts, the normalization of "draft" to "drafts" in the count() method is necessary because the navigation item in apps/mail/config/navigation.ts has id: 'drafts' (plural) while the Google API returns "draft" (singular). The nav-main.tsx component matches stats by comparing stat.label with item.id, so the backend must return "drafts" for the draft counter badge to appear in the sidebar.
Learnt from: retrogtx
PR: #1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.376Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: MrgSub
PR: #1837
File: apps/server/src/lib/brain.fallback.prompts.ts:211-217
Timestamp: 2025-07-26T20:39:06.670Z
Learning: In the ThreadLabels prompt system, existing labels should not be automatically preserved. The AI agent should re-evaluate all labels (both existing and new) against the current thread summary and only return labels that currently apply to the thread content, even if it means dropping previously applied labels that are no longer relevant.
Learnt from: retrogtx
PR: #1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
apps/server/src/routes/agent/rpc.ts (3)
Learnt from: MrgSub
PR: #1837
File: apps/server/src/lib/brain.fallback.prompts.ts:211-217
Timestamp: 2025-07-26T20:39:06.670Z
Learning: In the ThreadLabels prompt system, existing labels should not be automatically preserved. The AI agent should re-evaluate all labels (both existing and new) against the current thread summary and only return labels that currently apply to the thread content, even if it means dropping previously applied labels that are no longer relevant.
Learnt from: retrogtx
PR: #1734
File: apps/server/src/lib/driver/google.ts:211-221
Timestamp: 2025-07-15T06:46:33.349Z
Learning: In apps/server/src/lib/driver/google.ts, the normalization of "draft" to "drafts" in the count() method is necessary because the navigation item in apps/mail/config/navigation.ts has id: 'drafts' (plural) while the Google API returns "draft" (singular). The nav-main.tsx component matches stats by comparing stat.label with item.id, so the backend must return "drafts" for the draft counter badge to appear in the sidebar.
Learnt from: retrogtx
PR: #1468
File: apps/server/src/trpc/routes/mail.ts:386-391
Timestamp: 2025-06-27T04:59:29.731Z
Learning: In apps/server/src/trpc/routes/mail.ts, the attachment processing logic conditionally handles mixed attachment types - it preserves existing File-like objects with arrayBuffer methods while only converting serialized attachments that need processing through toAttachmentFiles.
apps/server/src/routes/agent/index.ts (2)
Learnt from: retrogtx
PR: #1734
File: apps/server/src/lib/driver/google.ts:211-221
Timestamp: 2025-07-15T06:46:33.349Z
Learning: In apps/server/src/lib/driver/google.ts, the normalization of "draft" to "drafts" in the count() method is necessary because the navigation item in apps/mail/config/navigation.ts has id: 'drafts' (plural) while the Google API returns "draft" (singular). The nav-main.tsx component matches stats by comparing stat.label with item.id, so the backend must return "drafts" for the draft counter badge to appear in the sidebar.
Learnt from: MrgSub
PR: #1837
File: apps/server/src/lib/brain.fallback.prompts.ts:211-217
Timestamp: 2025-07-26T20:39:06.670Z
Learning: In the ThreadLabels prompt system, existing labels should not be automatically preserved. The AI agent should re-evaluate all labels (both existing and new) against the current thread summary and only return labels that currently apply to the thread content, even if it means dropping previously applied labels that are no longer relevant.
apps/server/src/thread-workflow-utils/workflow-functions.ts (1)
Learnt from: retrogtx
PR: #1468
File: apps/server/src/trpc/routes/mail.ts:386-391
Timestamp: 2025-06-27T04:59:29.731Z
Learning: In apps/server/src/trpc/routes/mail.ts, the attachment processing logic conditionally handles mixed attachment types - it preserves existing File-like objects with arrayBuffer methods while only converting serialized attachments that need processing through toAttachmentFiles.
apps/server/src/thread-workflow-utils/workflow-engine.ts (1)
Learnt from: retrogtx
PR: #1468
File: apps/server/src/trpc/routes/mail.ts:386-391
Timestamp: 2025-06-27T04:59:29.731Z
Learning: In apps/server/src/trpc/routes/mail.ts, the attachment processing logic conditionally handles mixed attachment types - it preserves existing File-like objects with arrayBuffer methods while only converting serialized attachments that need processing through toAttachmentFiles.
apps/server/src/pipelines.effect.ts (1)
Learnt from: MrgSub
PR: #1837
File: apps/server/src/lib/brain.fallback.prompts.ts:211-217
Timestamp: 2025-07-26T20:39:06.670Z
Learning: In the ThreadLabels prompt system, existing labels should not be automatically preserved. The AI agent should re-evaluate all labels (both existing and new) against the current thread summary and only return labels that currently apply to the thread content, even if it means dropping previously applied labels that are no longer relevant.
🧬 Code Graph Analysis (1)
apps/server/src/pipelines.effect.ts (1)
apps/server/src/thread-workflow-utils/workflow-engine.ts (1)
createDefaultWorkflows(180-464)
🪛 LanguageTool
apps/server/src/thread-workflow-utils/README.md
[grammar] ~1-~1: Use correct spacing
Context: # Thread Workflow Engine This module provides a flexible workflow...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~3-~3: Use correct spacing
Context: ...and executed through a modular function registry. ## Architecture ### Components 1. **Workf...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~7-~7: Use correct spacing
Context: ...unction registry. ## Architecture ### Components 1. WorkflowEngine (workflow-engine.ts) ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~9-~9: There might be a mistake here.
Context: ... ### Components 1. WorkflowEngine (workflow-engine.ts) - Core engine that executes workflows...
(QB_NEW_EN_OTHER)
[grammar] ~9-~9: Use correct spacing
Context: ...WorkflowEngine* (workflow-engine.ts) - Core engine that executes workflows 2. *...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~10-~10: There might be a mistake here.
Context: ...es workflows 2. Workflow Functions (workflow-functions.ts) - Registry of individual workflow fun...
(QB_NEW_EN_OTHER)
[grammar] ~10-~10: Use correct spacing
Context: ...ow Functions** (workflow-functions.ts) - Registry of individual workflow function...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~11-~11: There might be a problem here.
Context: ...ividual workflow functions 3. Default Workflows - Pre-configured workflows in createDefaultWorkflows()...
(QB_NEW_EN_MERGED_MATCH)
[grammar] ~11-~11: There might be a problem here.
Context: ... Workflows** - Pre-configured workflows in createDefaultWorkflows() 4. Workflow Context - Shared context passed between workflow steps ...
(QB_NEW_EN_MERGED_MATCH)
[grammar] ~12-~12: Use correct spacing
Context: ... Shared context passed between workflow steps ### Key Benefits - **Type-Safe Configuratio...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~14-~14: Use correct spacing
Context: ... passed between workflow steps ### Key Benefits - Type-Safe Configuration: Workflows are...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~16-~16: There might be a mistake here.
Context: ...t, providing better type safety and IDE support - Modular Functions: Each workflow step ...
(QB_NEW_EN_OTHER)
[grammar] ~17-~17: There might be a mistake here.
Context: ... a separate function that can be tested independently - Error Handling: Configurable error han...
(QB_NEW_EN_OTHER)
[grammar] ~18-~18: There might be a mistake here.
Context: ...rror handling per step (continue, fail, retry) - Reusability: Functions can be shared b...
(QB_NEW_EN_OTHER)
[grammar] ~19-~19: There might be a mistake here.
Context: ...nctions can be shared between different workflows - Clean Separation: The main pipeline is...
(QB_NEW_EN_OTHER)
[grammar] ~20-~20: There might be a problem here.
Context: ...line is now much cleaner and focused on orchestration ## Usage ### Defining a Workflow Workflows are defin...
(QB_NEW_EN_MERGED_MATCH)
[grammar] ~24-~24: Use correct spacing
Context: ...orchestration ## Usage ### Defining a Workflow Workflows are defined in the `createDefa...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~26-~26: There might be a mistake here.
Context: ... createDefaultWorkflows() function in workflow-engine.ts: typescript const autoDraftWorkflow: WorkflowDefinition = { name: 'auto-draft-generation', description: 'Automatically generates drafts for threads that require responses', steps: [ { id: 'check-draft-eligibility', name: 'Check Draft Eligibility', description: 'Determines if a draft should be generated for this thread', enabled: true, condition: async (context) => { return shouldGenerateDraft(context.thread, context.foundConnection); }, action: async (context) => { console.log('[WORKFLOW_ENGINE] Thread eligible for draft generation', context); return { eligible: true }; }, }, // ... more steps ], }; engine.registerWorkflow(autoDraftWorkflow); ### Adding a New W...
(QB_NEW_EN_OTHER)
[grammar] ~53-~53: Use correct spacing
Context: ...rkflow); ``` ### Adding a New Workflow Function 1. Add the function to `workflow-functions....
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~55-~55: There might be a mistake here.
Context: ...rkflow Function 1. Add the function to workflow-functions.ts: typescript export const workflowFunctions: Record<string, WorkflowFunction> = { // ... existing functions ... myNewFunction: async (context) => { // Your logic here console.log('[WORKFLOW_FUNCTIONS] Executing my new function'); // Access previous step results const previousResult = context.results?.get('previous-step-id'); // Return result for next steps return { success: true, data: 'some data' }; }, }; 2. Add the step to your w...
(QB_NEW_EN_OTHER)
[grammar] ~74-~74: There might be a mistake here.
Context: ...the step to your workflow definition in createDefaultWorkflows(): typescript { id: 'my-new-step', name: 'My New Step', description: 'Description of what this step does', enabled: true, action: async (context) => { // Your logic here return { success: true }; }, errorHandling: 'continue', } ### Workflow Context Each wo...
(QB_NEW_EN_OTHER)
[grammar] ~90-~90: Use correct spacing
Context: ...ndling: 'continue', } ``` ### Workflow Context Each workflow function receives a contex...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~92-~92: There might be a mistake here.
Context: ...flow function receives a context object with: typescript type WorkflowContext = { connectionId: string; threadId: string; thread: IGetThreadResponse; foundConnection: typeof connection.$inferSelect; agent: any; env: any; results?: Map<string, any>; // Results from previous steps }; ### Error Handling Each step c...
(QB_NEW_EN_OTHER)
[grammar] ~106-~106: Use correct spacing
Context: ...s from previous steps }; ``` ### Error Handling Each step can have different error handl...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~108-~108: Use hyphens correctly
Context: ... Handling Each step can have different error handling strategies: - "continue" - S...
(QB_NEW_EN_OTHER_ERROR_IDS_29)
[grammar] ~108-~108: There might be a mistake here.
Context: ... step can have different error handling strategies: - "continue" - Skip failed steps and continue with ...
(QB_NEW_EN_OTHER)
[grammar] ~110-~110: Use hyphens correctly
Context: ...Skip failed steps and continue with the workflow - "fail" - Stop the entire workflow on error - `"...
(QB_NEW_EN_OTHER_ERROR_IDS_29)
[grammar] ~111-~111: Use hyphens correctly
Context: ... "fail" - Stop the entire workflow on error - "retry" - Retry the step up to maxRetries time...
(QB_NEW_EN_OTHER_ERROR_IDS_29)
[grammar] ~112-~112: There might be a mistake here.
Context: ...y"- Retry the step up tomaxRetries` times ### Example: Adding a New Workflow 1. **Def...
(QB_NEW_EN_OTHER)
[grammar] ~114-~114: Use correct spacing
Context: ...triestimes ### Example: Adding a New Workflow 1. **Define the workflow increateDefaultWor...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~116-~116: There might be a mistake here.
Context: ...w Workflow 1. Define the workflow in createDefaultWorkflows(): typescript const customWorkflow: WorkflowDefinition = { name: 'custom-processing', description: 'Custom thread processing workflow', steps: [ { id: 'custom-step-1', name: 'Custom Step 1', description: 'First custom processing step', enabled: true, action: async (context) => { console.log('[WORKFLOW_ENGINE] Executing custom step 1'); // Your custom logic here return { processed: true }; }, errorHandling: 'continue', }, { id: 'custom-step-2', name: 'Custom Step 2', description: 'Second custom processing step', enabled: true, action: async (context) => { const step1Result = context.results?.get('custom-step-1'); console.log('[WORKFLOW_ENGINE] Executing custom step 2 with result:', step1Result); // Your custom logic here return { completed: true }; }, errorHandling: 'retry', maxRetries: 3, }, ], }; engine.registerWorkflow(customWorkflow); 2. **Th...
(QB_NEW_EN_OTHER)
[grammar] ~155-~155: There might be a problem here.
Context: ...2. The workflow will be automatically executed - no need to update any other configuration! ###...
(QB_NEW_EN_MERGED_MATCH)
[grammar] ~155-~155: Use correct spacing
Context: ...xecuted** - no need to update any other configuration! ### Dynamic Workflow Discovery The workflow...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~157-~157: Use correct spacing
Context: ...er configuration! ### Dynamic Workflow Discovery The workflow engine automatically discov...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~159-~159: There might be a mistake here.
Context: ...y discovers and executes all registered workflows: typescript // Get all available workflow names from the engine const workflowNames = workflowEngine.getWorkflowNames(); // Execute all workflows dynamically for (const workflowName of workflowNames) { const { results, errors } = await workflowEngine.executeWorkflow(workflowName, context); } This means: - **No hardcoded...
(QB_NEW_EN_OTHER)
[grammar] ~171-~171: There might be a mistake here.
Context: ...low(workflowName, context); } ``` This means: - No hardcoded workflow lists: Workflow...
(QB_NEW_EN_OTHER)
[grammar] ~173-~173: There might be a mistake here.
Context: ...kflow lists**: Workflows are discovered automatically - Easy to add new workflows: Just regist...
(QB_NEW_EN_OTHER)
[grammar] ~174-~174: There might be a mistake here.
Context: ...add new workflows**: Just register them in createDefaultWorkflows() - Conditional workflows: Can be enabled/...
(QB_NEW_EN_OTHER)
[grammar] ~175-~175: There might be a mistake here.
Context: ...workflows**: Can be enabled/disabled at runtime - Future-proof: New workflows are automa...
(QB_NEW_EN_OTHER)
[grammar] ~176-~176: There might be a mistake here.
Context: ...roof**: New workflows are automatically included ## Migration from Hardcoded Logic The orig...
(QB_NEW_EN_OTHER)
[grammar] ~178-~178: Use correct spacing
Context: ...y included ## Migration from Hardcoded Logic The original hardcoded logic in `runThre...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~180-~180: There might be a mistake here.
Context: ...n runThreadWorkflow has been replaced with: 1. Workflow Engine: Orchestrates the exe...
(QB_NEW_EN_OTHER)
[grammar] ~185-~185: Use correct spacing
Context: ...aring**: Allows steps to share data and results This makes the system much more maintain...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~187-~187: Use correct spacing
Context: ...eps without modifying the core pipeline logic. ## Benefits - Cleaner Code: The main p...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~191-~191: There might be a mistake here.
Context: ...d on orchestration rather than business logic - Easier Testing: Each workflow function...
(QB_NEW_EN_OTHER)
[grammar] ~192-~192: There might be a mistake here.
Context: ...*: Each workflow function can be tested independently - Flexible Configuration: Workflows can ...
(QB_NEW_EN_OTHER)
[grammar] ~193-~193: Use proper capitalization
Context: ...an be enabled/disabled and modified via JSON - Better Error Handling: Granular error ...
(QB_NEW_EN_OTHER_ERROR_IDS_6)
[grammar] ~194-~194: There might be a mistake here.
Context: ...Handling**: Granular error handling per step - Reusability: Functions can be shared b...
(QB_NEW_EN_OTHER)
[grammar] ~195-~195: There might be a mistake here.
Context: ...nctions can be shared between different workflows - Maintainability: Adding new processing...
(QB_NEW_EN_OTHER)
[grammar] ~196-~196: There might be a mistake here.
Context: ...teps doesn't require modifying the main pipeline
(QB_NEW_EN_OTHER)
🪛 markdownlint-cli2 (0.17.2)
apps/server/src/thread-workflow-utils/README.md
74-74: Ordered list item prefix
Expected: 1; Actual: 2; Style: 1/1/1
(MD029, ol-prefix)
155-155: Ordered list item prefix
Expected: 1; Actual: 2; Style: 1/1/1
(MD029, ol-prefix)
🪛 GitHub Actions: autofix.ci
apps/server/src/trpc/routes/mail.ts
[warning] 31-31: ESLint (no-unused-vars): Variable 'getFolderLabelId' is declared but never used. Unused variables should start with a '_'.
apps/server/src/pipelines.effect.ts
[warning] 826-826: ESLint (no-unused-vars): Variable 'threadToXML' is declared but never used. Unused variables should start with a '_'.
⏰ 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). (2)
- GitHub Check: Cursor Bugbot
- GitHub Check: cubic · AI code reviewer
🔇 Additional comments (11)
apps/server/src/routes/agent/index.ts (3)
810-810: Excellent logging addition - like adding telemetry to our rockets before launch!This debug log provides crucial visibility into table operations. Sometimes the simplest changes make the biggest operational difference.
581-581: Critical bug fix identified - like fixing a navigation error on Mars mission!Changing from
idtothread_idin the WHERE clause is absolutely correct. The schema showsidis the PRIMARY KEY whilethread_idis the actual thread identifier. This fix ensures we're querying the right records - mission critical for thread operations.
1619-1619: Another mission-critical navigation fix! These WHERE clause corrections are like updating our spacecraft's guidance system.Both database queries now correctly use
thread_idinstead ofid, ensuring consistent thread identification across all operations. This level of attention to detail is what makes rockets land successfully!Also applies to: 1653-1653
apps/server/src/thread-workflow-utils/README.md (1)
1-197: Outstanding documentation! This README is like a comprehensive mission manual for SpaceX engineers.This documentation brilliantly explains the modular workflow architecture, providing clear examples and migration guidance. The level of detail here rivals the best technical docs at Tesla - developers will actually want to read this!
Key strengths:
- Clear architecture explanation with concrete examples
- Step-by-step workflow creation guide
- Proper error handling strategies
- Migration benefits clearly articulated
- Dynamic workflow discovery explanation
The static analysis warnings are just markdown formatting false positives - ignore them completely. This documentation quality is what makes complex systems maintainable.
apps/server/src/routes/agent/rpc.ts (3)
106-109: LGTM!Correct implementation for marking threads as unread by adding the UNREAD label.
115-122: Good simplification of the APIRemoving the skipSync parameter and centralizing the sync logic based on shouldReSyncThreadsAfterActions is a cleaner approach.
159-162: Correct implementationProperly adds UNREAD label to mark threads as unread.
apps/server/src/pipelines.effect.ts (2)
500-501: Good error handling additionAdding WorkflowCreationFailed to the error union type properly handles workflow initialization failures.
563-613: Excellent modular architectureThis workflow engine approach is much cleaner than hardcoded logic. Good separation of concerns and error handling.
apps/server/src/thread-workflow-utils/workflow-functions.ts (1)
85-105: Smart intent-based response validationGood implementation that checks multiple signals to determine if an email needs a response.
apps/server/src/thread-workflow-utils/workflow-engine.ts (1)
106-178: Brilliant workflow engine designThis is exactly how a workflow engine should work - modular, extensible, with proper error handling strategies. The retry mechanism and conditional execution are particularly well done.
There was a problem hiding this comment.
cubic analysis
3 issues found across 7 files • Review in cubic
React with 👍 or 👎 to teach cubic. You can also tag @cubic-dev-ai to give feedback, ask questions, or re-run the review.
8acbaf8 to
bd24220
Compare
|
An error occured. This error may be due to rate limits. If this error persists, please email us. |
Bug ReportName: Incomplete Workflow Results due to Conditional Execution Comments? Email us. This is the last day of your free trial. Subscribe at jazzberry.ai. |
Bug Report
Comments? Email us. This is the last day of your free trial. Subscribe at jazzberry.ai. |
There was a problem hiding this comment.
Actionable comments posted: 5
🔭 Outside diff range comments (2)
apps/server/src/routes/agent/rpc.ts (1)
93-100: Code duplication detected - not optimal for maintainability
markThreadsReadandmarkAsReadhave identical implementations. Same story withmarkThreadsUnreadandmarkAsUnread. This violates DRY principles.async markAsRead(threadIds: string[]) { - const result = await Promise.all( - threadIds.map((id) => this.mainDo.modifyThreadLabelsInDB(id, [], ['UNREAD'])), - ); - if (shouldReSyncThreadsAfterActions) - await Promise.all(threadIds.map((id) => this.mainDo.syncThread({ threadId: id }))); - return result; + return this.markThreadsRead(threadIds); } async markAsUnread(threadIds: string[]) { - const result = await Promise.all( - threadIds.map((id) => this.mainDo.modifyThreadLabelsInDB(id, ['UNREAD'], [])), - ); - if (shouldReSyncThreadsAfterActions) - await Promise.all(threadIds.map((id) => this.mainDo.syncThread({ threadId: id }))); - return result; + return this.markThreadsUnread(threadIds); }Also applies to: 150-157
apps/server/src/thread-workflow-utils/workflow-utils.ts (1)
1-103: Solid utility functions with proper error handlingGood extraction of these XML utilities into a dedicated module. The error handling is comprehensive and the Map-based deduplication in
getParticipantsis efficient.One area for improvement: stronger typing instead of
any.-export const messageToXML = async (message: ParsedMessage | any) => { +export const messageToXML = async (message: ParsedMessage) => { -export const getParticipants = (messages: ParsedMessage[] | any[]) => { +export const getParticipants = (messages: ParsedMessage[]) => { -export const threadToXML = async (messages: ParsedMessage[] | any[], existingSummary?: string) => { +export const threadToXML = async (messages: ParsedMessage[], existingSummary?: string) => {
♻️ Duplicate comments (6)
apps/server/src/trpc/routes/mail.ts (1)
31-33: Clean up the unused function - like removing dead weight from a spacecraft!The linter is flagging the unused
getFolderLabelIdfunction. Since we've standardized onagent.rawListThreads(), this helper function is no longer needed and should be removed to keep the codebase clean.apps/server/src/routes/agent/index.ts (1)
639-657: Remove the commented rocket parts - they're just adding mass to our spacecraft!These commented-out
markThreadsReadandmarkThreadsUnreadmethods are creating code clutter. They've been replaced by other implementations and should be completely removed rather than left as commented code.apps/server/src/routes/agent/rpc.ts (1)
256-264: Dead code without explanation - needs clarityThe
searchThreadsmethod is fully commented out with no context. This creates confusion and technical debt.apps/server/src/thread-workflow-utils/workflow-functions.ts (1)
1-528: Comprehensive workflow functions with solid architectureThis is how you build scalable systems. Each workflow function has a single responsibility, proper error handling, and detailed logging. The use of Effect for functional error handling in vectorization is particularly elegant.
The batching implementation with concurrency limits prevents overwhelming the AI service - smart move. Though we should make these limits configurable for different environments.
apps/server/src/thread-workflow-utils/workflow-engine.ts (2)
83-83: Results map still not passed to condition - this is a showstopperThis exact issue was already flagged. The condition function needs access to previous step results for proper decision making.
- const shouldExecute = step.condition ? await step.condition(context) : true; + const shouldExecute = step.condition ? await step.condition({ ...context, results }) : true;
143-144: Don't log the entire context - massive privacy riskThis is like broadcasting your private keys on Twitter. We can't be logging sensitive user data.
- console.log('[WORKFLOW_ENGINE] Thread eligible for draft generation', context); + console.log('[WORKFLOW_ENGINE] Thread eligible for draft generation', { + threadId: context.threadId, + connectionId: context.connectionId + });
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (9)
apps/server/src/pipelines.effect.ts(3 hunks)apps/server/src/routes/agent/index.ts(5 hunks)apps/server/src/routes/agent/rpc.ts(3 hunks)apps/server/src/thread-workflow-utils/README.md(1 hunks)apps/server/src/thread-workflow-utils/workflow-engine.ts(1 hunks)apps/server/src/thread-workflow-utils/workflow-functions.ts(1 hunks)apps/server/src/thread-workflow-utils/workflow-utils.ts(1 hunks)apps/server/src/trpc/routes/ai/compose.ts(1 hunks)apps/server/src/trpc/routes/mail.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit Inference Engine (AGENT.md)
**/*.{js,jsx,ts,tsx}: Use 2-space indentation
Use single quotes
Limit lines to 100 characters in width
Semicolons are required
Files:
apps/server/src/trpc/routes/ai/compose.tsapps/server/src/trpc/routes/mail.tsapps/server/src/routes/agent/index.tsapps/server/src/routes/agent/rpc.tsapps/server/src/thread-workflow-utils/workflow-utils.tsapps/server/src/thread-workflow-utils/workflow-functions.tsapps/server/src/thread-workflow-utils/workflow-engine.tsapps/server/src/pipelines.effect.ts
**/*.{js,jsx,ts,tsx,css}
📄 CodeRabbit Inference Engine (AGENT.md)
Use Prettier with sort-imports and Tailwind plugins
Files:
apps/server/src/trpc/routes/ai/compose.tsapps/server/src/trpc/routes/mail.tsapps/server/src/routes/agent/index.tsapps/server/src/routes/agent/rpc.tsapps/server/src/thread-workflow-utils/workflow-utils.tsapps/server/src/thread-workflow-utils/workflow-functions.tsapps/server/src/thread-workflow-utils/workflow-engine.tsapps/server/src/pipelines.effect.ts
**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (AGENT.md)
Enable TypeScript strict mode
Files:
apps/server/src/trpc/routes/ai/compose.tsapps/server/src/trpc/routes/mail.tsapps/server/src/routes/agent/index.tsapps/server/src/routes/agent/rpc.tsapps/server/src/thread-workflow-utils/workflow-utils.tsapps/server/src/thread-workflow-utils/workflow-functions.tsapps/server/src/thread-workflow-utils/workflow-engine.tsapps/server/src/pipelines.effect.ts
🧠 Learnings (7)
apps/server/src/trpc/routes/ai/compose.ts (1)
Learnt from: retrogtx
PR: #1468
File: apps/server/src/trpc/routes/mail.ts:386-391
Timestamp: 2025-06-27T04:59:29.731Z
Learning: In apps/server/src/trpc/routes/mail.ts, the attachment processing logic conditionally handles mixed attachment types - it preserves existing File-like objects with arrayBuffer methods while only converting serialized attachments that need processing through toAttachmentFiles.
apps/server/src/trpc/routes/mail.ts (5)
Learnt from: retrogtx
PR: #1468
File: apps/server/src/trpc/routes/mail.ts:386-391
Timestamp: 2025-06-27T04:59:29.731Z
Learning: In apps/server/src/trpc/routes/mail.ts, the attachment processing logic conditionally handles mixed attachment types - it preserves existing File-like objects with arrayBuffer methods while only converting serialized attachments that need processing through toAttachmentFiles.
Learnt from: retrogtx
PR: #1734
File: apps/server/src/lib/driver/google.ts:211-221
Timestamp: 2025-07-15T06:46:33.349Z
Learning: In apps/server/src/lib/driver/google.ts, the normalization of "draft" to "drafts" in the count() method is necessary because the navigation item in apps/mail/config/navigation.ts has id: 'drafts' (plural) while the Google API returns "draft" (singular). The nav-main.tsx component matches stats by comparing stat.label with item.id, so the backend must return "drafts" for the draft counter badge to appear in the sidebar.
Learnt from: retrogtx
PR: #1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.376Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: retrogtx
PR: #1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
Learnt from: MrgSub
PR: #1837
File: apps/server/src/lib/brain.fallback.prompts.ts:211-217
Timestamp: 2025-07-26T20:39:06.670Z
Learning: In the ThreadLabels prompt system, existing labels should not be automatically preserved. The AI agent should re-evaluate all labels (both existing and new) against the current thread summary and only return labels that currently apply to the thread content, even if it means dropping previously applied labels that are no longer relevant.
apps/server/src/routes/agent/index.ts (3)
Learnt from: retrogtx
PR: #1734
File: apps/server/src/lib/driver/google.ts:211-221
Timestamp: 2025-07-15T06:46:33.349Z
Learning: In apps/server/src/lib/driver/google.ts, the normalization of "draft" to "drafts" in the count() method is necessary because the navigation item in apps/mail/config/navigation.ts has id: 'drafts' (plural) while the Google API returns "draft" (singular). The nav-main.tsx component matches stats by comparing stat.label with item.id, so the backend must return "drafts" for the draft counter badge to appear in the sidebar.
Learnt from: MrgSub
PR: #1837
File: apps/server/src/lib/brain.fallback.prompts.ts:211-217
Timestamp: 2025-07-26T20:39:06.670Z
Learning: In the ThreadLabels prompt system, existing labels should not be automatically preserved. The AI agent should re-evaluate all labels (both existing and new) against the current thread summary and only return labels that currently apply to the thread content, even if it means dropping previously applied labels that are no longer relevant.
Learnt from: retrogtx
PR: #1622
File: apps/server/src/lib/email-verification.ts:189-189
Timestamp: 2025-07-05T05:27:24.623Z
Learning: During testing phases, debug logging should be kept active in apps/server/src/lib/email-verification.ts for BIMI validation and email verification debugging, even if it's verbose.
apps/server/src/routes/agent/rpc.ts (4)
Learnt from: MrgSub
PR: #1837
File: apps/server/src/lib/brain.fallback.prompts.ts:211-217
Timestamp: 2025-07-26T20:39:06.670Z
Learning: In the ThreadLabels prompt system, existing labels should not be automatically preserved. The AI agent should re-evaluate all labels (both existing and new) against the current thread summary and only return labels that currently apply to the thread content, even if it means dropping previously applied labels that are no longer relevant.
Learnt from: retrogtx
PR: #1734
File: apps/server/src/lib/driver/google.ts:211-221
Timestamp: 2025-07-15T06:46:33.349Z
Learning: In apps/server/src/lib/driver/google.ts, the normalization of "draft" to "drafts" in the count() method is necessary because the navigation item in apps/mail/config/navigation.ts has id: 'drafts' (plural) while the Google API returns "draft" (singular). The nav-main.tsx component matches stats by comparing stat.label with item.id, so the backend must return "drafts" for the draft counter badge to appear in the sidebar.
Learnt from: retrogtx
PR: #1468
File: apps/server/src/trpc/routes/mail.ts:386-391
Timestamp: 2025-06-27T04:59:29.731Z
Learning: In apps/server/src/trpc/routes/mail.ts, the attachment processing logic conditionally handles mixed attachment types - it preserves existing File-like objects with arrayBuffer methods while only converting serialized attachments that need processing through toAttachmentFiles.
Learnt from: retrogtx
PR: #1622
File: apps/server/src/lib/email-verification.ts:189-189
Timestamp: 2025-07-05T05:27:24.623Z
Learning: During testing phases, debug logging should be kept active in apps/server/src/lib/email-verification.ts for BIMI validation and email verification debugging, even if it's verbose.
apps/server/src/thread-workflow-utils/workflow-functions.ts (3)
Learnt from: retrogtx
PR: #1468
File: apps/server/src/trpc/routes/mail.ts:386-391
Timestamp: 2025-06-27T04:59:29.731Z
Learning: In apps/server/src/trpc/routes/mail.ts, the attachment processing logic conditionally handles mixed attachment types - it preserves existing File-like objects with arrayBuffer methods while only converting serialized attachments that need processing through toAttachmentFiles.
Learnt from: ripgrim
PR: #706
File: apps/mail/lib/ai.ts:34-48
Timestamp: 2025-04-21T21:33:10.581Z
Learning: Rate limiting for AI generation functionality is already implemented in the codebase, so additional rate limiting solutions are not needed.
Learnt from: MrgSub
PR: #1837
File: apps/server/src/lib/brain.fallback.prompts.ts:211-217
Timestamp: 2025-07-26T20:39:06.670Z
Learning: In the ThreadLabels prompt system, existing labels should not be automatically preserved. The AI agent should re-evaluate all labels (both existing and new) against the current thread summary and only return labels that currently apply to the thread content, even if it means dropping previously applied labels that are no longer relevant.
apps/server/src/thread-workflow-utils/workflow-engine.ts (2)
Learnt from: retrogtx
PR: #1468
File: apps/server/src/trpc/routes/mail.ts:386-391
Timestamp: 2025-06-27T04:59:29.731Z
Learning: In apps/server/src/trpc/routes/mail.ts, the attachment processing logic conditionally handles mixed attachment types - it preserves existing File-like objects with arrayBuffer methods while only converting serialized attachments that need processing through toAttachmentFiles.
Learnt from: retrogtx
PR: #1622
File: apps/server/src/lib/email-verification.ts:189-189
Timestamp: 2025-07-05T05:27:24.623Z
Learning: During testing phases, debug logging should be kept active in apps/server/src/lib/email-verification.ts for BIMI validation and email verification debugging, even if it's verbose.
apps/server/src/pipelines.effect.ts (1)
Learnt from: MrgSub
PR: #1837
File: apps/server/src/lib/brain.fallback.prompts.ts:211-217
Timestamp: 2025-07-26T20:39:06.670Z
Learning: In the ThreadLabels prompt system, existing labels should not be automatically preserved. The AI agent should re-evaluate all labels (both existing and new) against the current thread summary and only return labels that currently apply to the thread content, even if it means dropping previously applied labels that are no longer relevant.
🧬 Code Graph Analysis (3)
apps/server/src/thread-workflow-utils/workflow-utils.ts (1)
apps/server/src/thread-workflow-utils/workflow-engine.ts (1)
htmlToText(7-24)
apps/server/src/thread-workflow-utils/workflow-engine.ts (5)
apps/server/src/pipelines.effect.ts (1)
htmlToText(678-695)apps/server/src/lib/driver/types.ts (1)
IGetThreadResponse(6-12)apps/server/src/db/schema.ts (1)
connection(118-142)apps/server/src/thread-workflow-utils/index.ts (1)
shouldGenerateDraft(110-110)apps/server/src/thread-workflow-utils/workflow-functions.ts (1)
workflowFunctions(19-457)
apps/server/src/pipelines.effect.ts (1)
apps/server/src/thread-workflow-utils/workflow-engine.ts (1)
createDefaultWorkflows(127-276)
🪛 LanguageTool
apps/server/src/thread-workflow-utils/README.md
[grammar] ~1-~1: Use correct spacing
Context: # Thread Workflow Engine This module provides a flexible workflow...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~3-~3: Use correct spacing
Context: ...and executed through a modular function registry. ## Architecture ### Components 1. **Workf...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~7-~7: Use correct spacing
Context: ...unction registry. ## Architecture ### Components 1. WorkflowEngine (workflow-engine.ts) ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~9-~9: There might be a mistake here.
Context: ... ### Components 1. WorkflowEngine (workflow-engine.ts) - Core engine that executes workflows...
(QB_NEW_EN_OTHER)
[grammar] ~9-~9: Use correct spacing
Context: ...WorkflowEngine* (workflow-engine.ts) - Core engine that executes workflows 2. *...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~10-~10: There might be a mistake here.
Context: ...es workflows 2. Workflow Functions (workflow-functions.ts) - Registry of individual workflow fun...
(QB_NEW_EN_OTHER)
[grammar] ~10-~10: Use correct spacing
Context: ...ow Functions** (workflow-functions.ts) - Registry of individual workflow function...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~11-~11: There might be a problem here.
Context: ...ividual workflow functions 3. Default Workflows - Pre-configured workflows in createDefaultWorkflows()...
(QB_NEW_EN_MERGED_MATCH)
[grammar] ~11-~11: There might be a problem here.
Context: ... Workflows** - Pre-configured workflows in createDefaultWorkflows() 4. Workflow Context - Shared context passed between workflow steps ...
(QB_NEW_EN_MERGED_MATCH)
[grammar] ~12-~12: Use correct spacing
Context: ... Shared context passed between workflow steps ### Key Benefits - **Type-Safe Configuratio...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~14-~14: Use correct spacing
Context: ... passed between workflow steps ### Key Benefits - Type-Safe Configuration: Workflows are...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~16-~16: There might be a mistake here.
Context: ...t, providing better type safety and IDE support - Modular Functions: Each workflow step ...
(QB_NEW_EN_OTHER)
[grammar] ~17-~17: There might be a mistake here.
Context: ... a separate function that can be tested independently - Error Handling: Configurable error han...
(QB_NEW_EN_OTHER)
[grammar] ~18-~18: There might be a mistake here.
Context: ...rror handling per step (continue, fail, retry) - Reusability: Functions can be shared b...
(QB_NEW_EN_OTHER)
[grammar] ~19-~19: There might be a mistake here.
Context: ...nctions can be shared between different workflows - Clean Separation: The main pipeline is...
(QB_NEW_EN_OTHER)
[grammar] ~20-~20: There might be a problem here.
Context: ...line is now much cleaner and focused on orchestration ## Usage ### Defining a Workflow Workflows are defin...
(QB_NEW_EN_MERGED_MATCH)
[grammar] ~24-~24: Use correct spacing
Context: ...orchestration ## Usage ### Defining a Workflow Workflows are defined in the `createDefa...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~26-~26: There might be a mistake here.
Context: ... createDefaultWorkflows() function in workflow-engine.ts: typescript const autoDraftWorkflow: WorkflowDefinition = { name: 'auto-draft-generation', description: 'Automatically generates drafts for threads that require responses', steps: [ { id: 'check-draft-eligibility', name: 'Check Draft Eligibility', description: 'Determines if a draft should be generated for this thread', enabled: true, condition: async (context) => { return shouldGenerateDraft(context.thread, context.foundConnection); }, action: async (context) => { console.log('[WORKFLOW_ENGINE] Thread eligible for draft generation', context); return { eligible: true }; }, }, // ... more steps ], }; engine.registerWorkflow(autoDraftWorkflow); ### Adding a New W...
(QB_NEW_EN_OTHER)
[grammar] ~53-~53: Use correct spacing
Context: ...rkflow); ``` ### Adding a New Workflow Function 1. Add the function to `workflow-functions....
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~55-~55: There might be a mistake here.
Context: ...rkflow Function 1. Add the function to workflow-functions.ts: typescript export const workflowFunctions: Record<string, WorkflowFunction> = { // ... existing functions ... myNewFunction: async (context) => { // Your logic here console.log('[WORKFLOW_FUNCTIONS] Executing my new function'); // Access previous step results const previousResult = context.results?.get('previous-step-id'); // Return result for next steps return { success: true, data: 'some data' }; }, }; 2. Add the step to your w...
(QB_NEW_EN_OTHER)
[grammar] ~74-~74: There might be a mistake here.
Context: ...the step to your workflow definition in createDefaultWorkflows(): typescript { id: 'my-new-step', name: 'My New Step', description: 'Description of what this step does', enabled: true, action: async (context) => { // Your logic here return { success: true }; }, errorHandling: 'continue', } ### Workflow Context Each wo...
(QB_NEW_EN_OTHER)
[grammar] ~90-~90: Use correct spacing
Context: ...ndling: 'continue', } ``` ### Workflow Context Each workflow function receives a contex...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~92-~92: There might be a mistake here.
Context: ...flow function receives a context object with: typescript type WorkflowContext = { connectionId: string; threadId: string; thread: IGetThreadResponse; foundConnection: typeof connection.$inferSelect; agent: any; env: any; results?: Map<string, any>; // Results from previous steps }; ### Error Handling Each step c...
(QB_NEW_EN_OTHER)
[grammar] ~106-~106: Use correct spacing
Context: ...s from previous steps }; ``` ### Error Handling Each step can have different error handl...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~108-~108: Use hyphens correctly
Context: ... Handling Each step can have different error handling strategies: - "continue" - S...
(QB_NEW_EN_OTHER_ERROR_IDS_29)
[grammar] ~108-~108: There might be a mistake here.
Context: ... step can have different error handling strategies: - "continue" - Skip failed steps and continue with ...
(QB_NEW_EN_OTHER)
[grammar] ~110-~110: Use hyphens correctly
Context: ...Skip failed steps and continue with the workflow - "fail" - Stop the entire workflow on error - `"...
(QB_NEW_EN_OTHER_ERROR_IDS_29)
[grammar] ~111-~111: Use hyphens correctly
Context: ... "fail" - Stop the entire workflow on error - "retry" - Retry the step up to maxRetries time...
(QB_NEW_EN_OTHER_ERROR_IDS_29)
[grammar] ~112-~112: There might be a mistake here.
Context: ...y"- Retry the step up tomaxRetries` times ### Example: Adding a New Workflow 1. **Def...
(QB_NEW_EN_OTHER)
[grammar] ~114-~114: Use correct spacing
Context: ...triestimes ### Example: Adding a New Workflow 1. **Define the workflow increateDefaultWor...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~116-~116: There might be a mistake here.
Context: ...w Workflow 1. Define the workflow in createDefaultWorkflows(): typescript const customWorkflow: WorkflowDefinition = { name: 'custom-processing', description: 'Custom thread processing workflow', steps: [ { id: 'custom-step-1', name: 'Custom Step 1', description: 'First custom processing step', enabled: true, action: async (context) => { console.log('[WORKFLOW_ENGINE] Executing custom step 1'); // Your custom logic here return { processed: true }; }, errorHandling: 'continue', }, { id: 'custom-step-2', name: 'Custom Step 2', description: 'Second custom processing step', enabled: true, action: async (context) => { const step1Result = context.results?.get('custom-step-1'); console.log('[WORKFLOW_ENGINE] Executing custom step 2 with result:', step1Result); // Your custom logic here return { completed: true }; }, errorHandling: 'retry', maxRetries: 3, }, ], }; engine.registerWorkflow(customWorkflow); 2. **Th...
(QB_NEW_EN_OTHER)
[grammar] ~155-~155: There might be a problem here.
Context: ...2. The workflow will be automatically executed - no need to update any other configuration! ###...
(QB_NEW_EN_MERGED_MATCH)
[grammar] ~155-~155: Use correct spacing
Context: ...xecuted** - no need to update any other configuration! ### Dynamic Workflow Discovery The workflow...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~157-~157: Use correct spacing
Context: ...er configuration! ### Dynamic Workflow Discovery The workflow engine automatically discov...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~159-~159: There might be a mistake here.
Context: ...y discovers and executes all registered workflows: typescript // Get all available workflow names from the engine const workflowNames = workflowEngine.getWorkflowNames(); // Execute all workflows dynamically for (const workflowName of workflowNames) { const { results, errors } = await workflowEngine.executeWorkflow(workflowName, context); } This means: - **No hardcoded...
(QB_NEW_EN_OTHER)
[grammar] ~171-~171: There might be a mistake here.
Context: ...low(workflowName, context); } ``` This means: - No hardcoded workflow lists: Workflow...
(QB_NEW_EN_OTHER)
[grammar] ~173-~173: There might be a mistake here.
Context: ...kflow lists**: Workflows are discovered automatically - Easy to add new workflows: Just regist...
(QB_NEW_EN_OTHER)
[grammar] ~174-~174: There might be a mistake here.
Context: ...add new workflows**: Just register them in createDefaultWorkflows() - Conditional workflows: Can be enabled/...
(QB_NEW_EN_OTHER)
[grammar] ~175-~175: There might be a mistake here.
Context: ...workflows**: Can be enabled/disabled at runtime - Future-proof: New workflows are automa...
(QB_NEW_EN_OTHER)
[grammar] ~176-~176: There might be a mistake here.
Context: ...roof**: New workflows are automatically included ## Migration from Hardcoded Logic The orig...
(QB_NEW_EN_OTHER)
[grammar] ~178-~178: Use correct spacing
Context: ...y included ## Migration from Hardcoded Logic The original hardcoded logic in `runThre...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~180-~180: There might be a mistake here.
Context: ...n runThreadWorkflow has been replaced with: 1. Workflow Engine: Orchestrates the exe...
(QB_NEW_EN_OTHER)
[grammar] ~185-~185: Use correct spacing
Context: ...aring**: Allows steps to share data and results This makes the system much more maintain...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~187-~187: Use correct spacing
Context: ...eps without modifying the core pipeline logic. ## Benefits - Cleaner Code: The main p...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~191-~191: There might be a mistake here.
Context: ...d on orchestration rather than business logic - Easier Testing: Each workflow function...
(QB_NEW_EN_OTHER)
[grammar] ~192-~192: There might be a mistake here.
Context: ...*: Each workflow function can be tested independently - Flexible Configuration: Workflows can ...
(QB_NEW_EN_OTHER)
[grammar] ~193-~193: Use proper capitalization
Context: ...an be enabled/disabled and modified via JSON - Better Error Handling: Granular error ...
(QB_NEW_EN_OTHER_ERROR_IDS_6)
[grammar] ~194-~194: There might be a mistake here.
Context: ...Handling**: Granular error handling per step - Reusability: Functions can be shared b...
(QB_NEW_EN_OTHER)
[grammar] ~195-~195: There might be a mistake here.
Context: ...nctions can be shared between different workflows - Maintainability: Adding new processing...
(QB_NEW_EN_OTHER)
[grammar] ~196-~196: There might be a mistake here.
Context: ...teps doesn't require modifying the main pipeline
(QB_NEW_EN_OTHER)
🪛 markdownlint-cli2 (0.17.2)
apps/server/src/thread-workflow-utils/README.md
74-74: Ordered list item prefix
Expected: 1; Actual: 2; Style: 1/1/1
(MD029, ol-prefix)
155-155: Ordered list item prefix
Expected: 1; Actual: 2; Style: 1/1/1
(MD029, ol-prefix)
🪛 GitHub Actions: autofix.ci
apps/server/src/trpc/routes/mail.ts
[warning] 31-31: ESLint (no-unused-vars): Variable 'getFolderLabelId' is declared but never used. Unused variables should start with a '_'.
⏰ 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). (1)
- GitHub Check: Cursor Bugbot
🔇 Additional comments (7)
apps/server/src/trpc/routes/ai/compose.ts (1)
5-5: Brilliant consolidation - like merging rocket engines for maximum efficiency!This import change perfectly exemplifies the modular workflow engine refactor. Moving
escapeXmlto the shared workflow-utils module eliminates code duplication and creates a single source of truth for XML processing across the application.apps/server/src/trpc/routes/mail.ts (1)
95-101: Magnificent simplification - like removing unnecessary complexity from a Falcon Heavy design!This refactor eliminates conditional branches and standardizes on
agent.rawListThreads(), making the code more predictable and maintainable. Sometimes the best engineering is removing what you don't need - just like how we optimize rocket mass by eliminating redundant systems.apps/server/src/routes/agent/index.ts (2)
810-810: Excellent debugging visibility - like mission control telemetry!Adding the console log for table dropping operations provides valuable debugging information. This kind of operational visibility is crucial for understanding system behavior.
1581-1581: Critical database query fixes - like correcting navigation coordinates for Mars landing!These SQL query corrections change the WHERE clause from
idtothread_id, which is essential for proper database schema consistency. Using the wrong column reference could lead to incorrect data retrieval and system failures.Also applies to: 1619-1619, 1653-1653
apps/server/src/thread-workflow-utils/README.md (1)
1-197: First principles thinking applied to documentation - I like it!This is exactly the kind of modular, extensible architecture we need. The workflow engine approach with type-safe configuration and independent testability is the way. Documentation is clear and actionable.
Minor formatting issues flagged by the linter can be addressed, but they don't impact functionality. The examples are practical and the migration guide will help teams transition smoothly.
apps/server/src/pipelines.effect.ts (1)
563-625: Clean refactoring to workflow engine - this is the wayExcellent modularization. Moving from monolithic inline logic to a workflow engine with defined steps is exactly how we should architect complex systems. The error handling and result aggregation look solid.
The nested Map operations for merging results are fine - we're dealing with a small, bounded number of workflows here, not unbounded data.
apps/server/src/thread-workflow-utils/workflow-functions.ts (1)
386-456: Label application logic handles edge cases wellThe implementation correctly:
- Uses
userAccountLabelsfrom the getUserLabels result- Filters AI-managed labels for removal
- Only modifies labels when there are actual changes
- Handles all the edge cases properly
This is production-ready code.
940d71a to
b9f94e6
Compare
Bug Report
Comments? Email us. This is the last day of your free trial. Subscribe at jazzberry.ai. |
There was a problem hiding this comment.
Actionable comments posted: 12
🔭 Outside diff range comments (2)
apps/server/src/thread-workflow-utils/README.md (1)
1-197: Outstanding documentation! This is the kind of comprehensive technical writing that makes complex systems accessible.This README is absolutely brilliant - it's like having a detailed mission manual for the new workflow engine. The structure flows perfectly from architecture overview to practical implementation examples. The benefits are clearly articulated, and the migration guidance will be invaluable for the team.
A few minor suggestions to make this even more epic:
- Error handling examples: Consider adding a concrete example showing different error handling strategies in action
- Performance benefits: Could quantify some of the maintainability/performance improvements (e.g., "reduced code complexity by X%")
- Quick start section: Maybe add a "5-minute getting started" section for developers who want to jump right in
But honestly, this documentation sets the gold standard for technical writing. It's comprehensive, practical, and genuinely helpful.
apps/server/src/routes/agent/rpc.ts (1)
256-264: Dead code is like carrying extra weight on a rocket - it slows everything downThis
searchThreadsmethod is completely commented out with no explanation. Either:
- Delete it if it's deprecated (my preference - less is more)
- Add a comment explaining why it's disabled and when it might return
- If it's WIP, move it to a feature branch
Dead code creates confusion and technical debt. Make a decision and execute.
♻️ Duplicate comments (4)
apps/server/src/routes/agent/index.ts (1)
639-657: Time to complete the mission - remove this commented dead code completely.These methods have been replaced by the new workflow engine architecture. Keeping commented code is like keeping old Falcon 9 parts in the factory - it just creates clutter and confusion. The functionality has moved to the modular workflow system.
apps/server/src/thread-workflow-utils/workflow-engine.ts (2)
31-32: Usinganyis like launching without knowing your payload mass - dangerousDefine proper interfaces for
agentandenv. TypeScript exists to catch errors at compile time, not runtime.- agent: any; - env: any; + agent: EmailAgent; // Define proper interface + env: WorkflowEnvironment; // Define proper interface
99-117: Retrying immediately is like repeatedly trying to start a frozen engine - you need to waitAdd exponential backoff to prevent overwhelming the system with rapid retries.
while (retries < step.maxRetries) { try { + if (retries > 0) { + const delay = Math.min(1000 * Math.pow(2, retries - 1), 10000); + await new Promise(resolve => setTimeout(resolve, delay)); + } console.log(`[WORKFLOW_ENGINE] Retrying step ${step.name} (attempt ${retries + 1})`);apps/server/src/thread-workflow-utils/workflow-functions.ts (1)
217-217: Make concurrency configurableThe hardcoded concurrency limit of 3 is limiting. Let's make this configurable through environment variables for better scalability.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (9)
apps/server/src/pipelines.effect.ts(3 hunks)apps/server/src/routes/agent/index.ts(5 hunks)apps/server/src/routes/agent/rpc.ts(3 hunks)apps/server/src/thread-workflow-utils/README.md(1 hunks)apps/server/src/thread-workflow-utils/workflow-engine.ts(1 hunks)apps/server/src/thread-workflow-utils/workflow-functions.ts(1 hunks)apps/server/src/thread-workflow-utils/workflow-utils.ts(1 hunks)apps/server/src/trpc/routes/ai/compose.ts(1 hunks)apps/server/src/trpc/routes/mail.ts(2 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit Inference Engine (AGENT.md)
**/*.{js,jsx,ts,tsx}: Use 2-space indentation
Use single quotes
Limit lines to 100 characters in width
Semicolons are required
Files:
apps/server/src/trpc/routes/ai/compose.tsapps/server/src/trpc/routes/mail.tsapps/server/src/routes/agent/index.tsapps/server/src/routes/agent/rpc.tsapps/server/src/thread-workflow-utils/workflow-utils.tsapps/server/src/pipelines.effect.tsapps/server/src/thread-workflow-utils/workflow-engine.tsapps/server/src/thread-workflow-utils/workflow-functions.ts
**/*.{js,jsx,ts,tsx,css}
📄 CodeRabbit Inference Engine (AGENT.md)
Use Prettier with sort-imports and Tailwind plugins
Files:
apps/server/src/trpc/routes/ai/compose.tsapps/server/src/trpc/routes/mail.tsapps/server/src/routes/agent/index.tsapps/server/src/routes/agent/rpc.tsapps/server/src/thread-workflow-utils/workflow-utils.tsapps/server/src/pipelines.effect.tsapps/server/src/thread-workflow-utils/workflow-engine.tsapps/server/src/thread-workflow-utils/workflow-functions.ts
**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (AGENT.md)
Enable TypeScript strict mode
Files:
apps/server/src/trpc/routes/ai/compose.tsapps/server/src/trpc/routes/mail.tsapps/server/src/routes/agent/index.tsapps/server/src/routes/agent/rpc.tsapps/server/src/thread-workflow-utils/workflow-utils.tsapps/server/src/pipelines.effect.tsapps/server/src/thread-workflow-utils/workflow-engine.tsapps/server/src/thread-workflow-utils/workflow-functions.ts
🧠 Learnings (8)
📓 Common learnings
Learnt from: JagjeevanAK
PR: Mail-0/Zero#1583
File: apps/docs/package.json:1-0
Timestamp: 2025-07-01T12:53:32.495Z
Learning: The Zero project prefers to handle dependency updates through automated tools like Dependabot rather than immediate manual updates, allowing for proper testing and validation through their established workflow.
apps/server/src/trpc/routes/ai/compose.ts (2)
Learnt from: retrogtx
PR: #1468
File: apps/server/src/trpc/routes/mail.ts:386-391
Timestamp: 2025-06-27T04:59:29.731Z
Learning: In apps/server/src/trpc/routes/mail.ts, the attachment processing logic conditionally handles mixed attachment types - it preserves existing File-like objects with arrayBuffer methods while only converting serialized attachments that need processing through toAttachmentFiles.
Learnt from: retrogtx
PR: #1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.376Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
apps/server/src/trpc/routes/mail.ts (5)
Learnt from: retrogtx
PR: #1468
File: apps/server/src/trpc/routes/mail.ts:386-391
Timestamp: 2025-06-27T04:59:29.731Z
Learning: In apps/server/src/trpc/routes/mail.ts, the attachment processing logic conditionally handles mixed attachment types - it preserves existing File-like objects with arrayBuffer methods while only converting serialized attachments that need processing through toAttachmentFiles.
Learnt from: retrogtx
PR: #1734
File: apps/server/src/lib/driver/google.ts:211-221
Timestamp: 2025-07-15T06:46:33.349Z
Learning: In apps/server/src/lib/driver/google.ts, the normalization of "draft" to "drafts" in the count() method is necessary because the navigation item in apps/mail/config/navigation.ts has id: 'drafts' (plural) while the Google API returns "draft" (singular). The nav-main.tsx component matches stats by comparing stat.label with item.id, so the backend must return "drafts" for the draft counter badge to appear in the sidebar.
Learnt from: retrogtx
PR: #1468
File: apps/server/src/trpc/routes/mail.ts:331-331
Timestamp: 2025-06-28T03:56:09.376Z
Learning: In apps/server/src/trpc/routes/mail.ts, the user indicated they are not using ISO format for the scheduleAt parameter, despite the frontend code showing toISOString() usage in the ScheduleSendPicker component.
Learnt from: retrogtx
PR: #1328
File: apps/mail/lib/hotkeys/mail-list-hotkeys.tsx:202-209
Timestamp: 2025-06-18T17:26:50.918Z
Learning: In apps/mail/lib/hotkeys/mail-list-hotkeys.tsx, the switchCategoryByIndex function using hardcoded indices for category hotkeys does not break when users reorder categories, contrary to the theoretical index-shifting issue. The actual implementation has constraints or mechanisms that prevent hotkey targeting issues.
Learnt from: MrgSub
PR: #1837
File: apps/server/src/lib/brain.fallback.prompts.ts:211-217
Timestamp: 2025-07-26T20:39:06.670Z
Learning: In the ThreadLabels prompt system, existing labels should not be automatically preserved. The AI agent should re-evaluate all labels (both existing and new) against the current thread summary and only return labels that currently apply to the thread content, even if it means dropping previously applied labels that are no longer relevant.
apps/server/src/routes/agent/index.ts (3)
Learnt from: retrogtx
PR: #1734
File: apps/server/src/lib/driver/google.ts:211-221
Timestamp: 2025-07-15T06:46:33.349Z
Learning: In apps/server/src/lib/driver/google.ts, the normalization of "draft" to "drafts" in the count() method is necessary because the navigation item in apps/mail/config/navigation.ts has id: 'drafts' (plural) while the Google API returns "draft" (singular). The nav-main.tsx component matches stats by comparing stat.label with item.id, so the backend must return "drafts" for the draft counter badge to appear in the sidebar.
Learnt from: MrgSub
PR: #1837
File: apps/server/src/lib/brain.fallback.prompts.ts:211-217
Timestamp: 2025-07-26T20:39:06.670Z
Learning: In the ThreadLabels prompt system, existing labels should not be automatically preserved. The AI agent should re-evaluate all labels (both existing and new) against the current thread summary and only return labels that currently apply to the thread content, even if it means dropping previously applied labels that are no longer relevant.
Learnt from: retrogtx
PR: #1622
File: apps/server/src/lib/email-verification.ts:189-189
Timestamp: 2025-07-05T05:27:24.623Z
Learning: During testing phases, debug logging should be kept active in apps/server/src/lib/email-verification.ts for BIMI validation and email verification debugging, even if it's verbose.
apps/server/src/routes/agent/rpc.ts (4)
Learnt from: MrgSub
PR: #1837
File: apps/server/src/lib/brain.fallback.prompts.ts:211-217
Timestamp: 2025-07-26T20:39:06.670Z
Learning: In the ThreadLabels prompt system, existing labels should not be automatically preserved. The AI agent should re-evaluate all labels (both existing and new) against the current thread summary and only return labels that currently apply to the thread content, even if it means dropping previously applied labels that are no longer relevant.
Learnt from: retrogtx
PR: #1734
File: apps/server/src/lib/driver/google.ts:211-221
Timestamp: 2025-07-15T06:46:33.349Z
Learning: In apps/server/src/lib/driver/google.ts, the normalization of "draft" to "drafts" in the count() method is necessary because the navigation item in apps/mail/config/navigation.ts has id: 'drafts' (plural) while the Google API returns "draft" (singular). The nav-main.tsx component matches stats by comparing stat.label with item.id, so the backend must return "drafts" for the draft counter badge to appear in the sidebar.
Learnt from: retrogtx
PR: #1468
File: apps/server/src/trpc/routes/mail.ts:386-391
Timestamp: 2025-06-27T04:59:29.731Z
Learning: In apps/server/src/trpc/routes/mail.ts, the attachment processing logic conditionally handles mixed attachment types - it preserves existing File-like objects with arrayBuffer methods while only converting serialized attachments that need processing through toAttachmentFiles.
Learnt from: retrogtx
PR: #1622
File: apps/server/src/lib/email-verification.ts:189-189
Timestamp: 2025-07-05T05:27:24.623Z
Learning: During testing phases, debug logging should be kept active in apps/server/src/lib/email-verification.ts for BIMI validation and email verification debugging, even if it's verbose.
apps/server/src/pipelines.effect.ts (1)
Learnt from: MrgSub
PR: #1837
File: apps/server/src/lib/brain.fallback.prompts.ts:211-217
Timestamp: 2025-07-26T20:39:06.670Z
Learning: In the ThreadLabels prompt system, existing labels should not be automatically preserved. The AI agent should re-evaluate all labels (both existing and new) against the current thread summary and only return labels that currently apply to the thread content, even if it means dropping previously applied labels that are no longer relevant.
apps/server/src/thread-workflow-utils/workflow-engine.ts (2)
Learnt from: retrogtx
PR: #1468
File: apps/server/src/trpc/routes/mail.ts:386-391
Timestamp: 2025-06-27T04:59:29.731Z
Learning: In apps/server/src/trpc/routes/mail.ts, the attachment processing logic conditionally handles mixed attachment types - it preserves existing File-like objects with arrayBuffer methods while only converting serialized attachments that need processing through toAttachmentFiles.
Learnt from: retrogtx
PR: #1622
File: apps/server/src/lib/email-verification.ts:189-189
Timestamp: 2025-07-05T05:27:24.623Z
Learning: During testing phases, debug logging should be kept active in apps/server/src/lib/email-verification.ts for BIMI validation and email verification debugging, even if it's verbose.
apps/server/src/thread-workflow-utils/workflow-functions.ts (3)
Learnt from: retrogtx
PR: #1468
File: apps/server/src/trpc/routes/mail.ts:386-391
Timestamp: 2025-06-27T04:59:29.731Z
Learning: In apps/server/src/trpc/routes/mail.ts, the attachment processing logic conditionally handles mixed attachment types - it preserves existing File-like objects with arrayBuffer methods while only converting serialized attachments that need processing through toAttachmentFiles.
Learnt from: ripgrim
PR: #706
File: apps/mail/lib/ai.ts:34-48
Timestamp: 2025-04-21T21:33:10.581Z
Learning: Rate limiting for AI generation functionality is already implemented in the codebase, so additional rate limiting solutions are not needed.
Learnt from: MrgSub
PR: #1837
File: apps/server/src/lib/brain.fallback.prompts.ts:211-217
Timestamp: 2025-07-26T20:39:06.670Z
Learning: In the ThreadLabels prompt system, existing labels should not be automatically preserved. The AI agent should re-evaluate all labels (both existing and new) against the current thread summary and only return labels that currently apply to the thread content, even if it means dropping previously applied labels that are no longer relevant.
🧬 Code Graph Analysis (3)
apps/server/src/thread-workflow-utils/workflow-utils.ts (1)
apps/server/src/thread-workflow-utils/workflow-engine.ts (1)
htmlToText(7-24)
apps/server/src/pipelines.effect.ts (1)
apps/server/src/thread-workflow-utils/workflow-engine.ts (1)
createDefaultWorkflows(127-282)
apps/server/src/thread-workflow-utils/workflow-engine.ts (5)
apps/server/src/pipelines.effect.ts (1)
htmlToText(678-695)apps/server/src/lib/driver/types.ts (1)
IGetThreadResponse(6-12)apps/server/src/db/schema.ts (1)
connection(118-142)apps/server/src/thread-workflow-utils/index.ts (1)
shouldGenerateDraft(110-110)apps/server/src/thread-workflow-utils/workflow-functions.ts (1)
workflowFunctions(19-457)
🪛 LanguageTool
apps/server/src/thread-workflow-utils/README.md
[grammar] ~1-~1: Use correct spacing
Context: # Thread Workflow Engine This module provides a flexible workflow...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~3-~3: Use correct spacing
Context: ...and executed through a modular function registry. ## Architecture ### Components 1. **Workf...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~7-~7: Use correct spacing
Context: ...unction registry. ## Architecture ### Components 1. WorkflowEngine (workflow-engine.ts) ...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~9-~9: There might be a mistake here.
Context: ... ### Components 1. WorkflowEngine (workflow-engine.ts) - Core engine that executes workflows...
(QB_NEW_EN_OTHER)
[grammar] ~9-~9: Use correct spacing
Context: ...WorkflowEngine* (workflow-engine.ts) - Core engine that executes workflows 2. *...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~10-~10: There might be a mistake here.
Context: ...es workflows 2. Workflow Functions (workflow-functions.ts) - Registry of individual workflow fun...
(QB_NEW_EN_OTHER)
[grammar] ~10-~10: Use correct spacing
Context: ...ow Functions** (workflow-functions.ts) - Registry of individual workflow function...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~11-~11: There might be a problem here.
Context: ...ividual workflow functions 3. Default Workflows - Pre-configured workflows in createDefaultWorkflows()...
(QB_NEW_EN_MERGED_MATCH)
[grammar] ~11-~11: There might be a problem here.
Context: ... Workflows** - Pre-configured workflows in createDefaultWorkflows() 4. Workflow Context - Shared context passed between workflow steps ...
(QB_NEW_EN_MERGED_MATCH)
[grammar] ~12-~12: Use correct spacing
Context: ... Shared context passed between workflow steps ### Key Benefits - **Type-Safe Configuratio...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~14-~14: Use correct spacing
Context: ... passed between workflow steps ### Key Benefits - Type-Safe Configuration: Workflows are...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~16-~16: There might be a mistake here.
Context: ...t, providing better type safety and IDE support - Modular Functions: Each workflow step ...
(QB_NEW_EN_OTHER)
[grammar] ~17-~17: There might be a mistake here.
Context: ... a separate function that can be tested independently - Error Handling: Configurable error han...
(QB_NEW_EN_OTHER)
[grammar] ~18-~18: There might be a mistake here.
Context: ...rror handling per step (continue, fail, retry) - Reusability: Functions can be shared b...
(QB_NEW_EN_OTHER)
[grammar] ~19-~19: There might be a mistake here.
Context: ...nctions can be shared between different workflows - Clean Separation: The main pipeline is...
(QB_NEW_EN_OTHER)
[grammar] ~20-~20: There might be a problem here.
Context: ...line is now much cleaner and focused on orchestration ## Usage ### Defining a Workflow Workflows are defin...
(QB_NEW_EN_MERGED_MATCH)
[grammar] ~24-~24: Use correct spacing
Context: ...orchestration ## Usage ### Defining a Workflow Workflows are defined in the `createDefa...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~26-~26: There might be a mistake here.
Context: ... createDefaultWorkflows() function in workflow-engine.ts: typescript const autoDraftWorkflow: WorkflowDefinition = { name: 'auto-draft-generation', description: 'Automatically generates drafts for threads that require responses', steps: [ { id: 'check-draft-eligibility', name: 'Check Draft Eligibility', description: 'Determines if a draft should be generated for this thread', enabled: true, condition: async (context) => { return shouldGenerateDraft(context.thread, context.foundConnection); }, action: async (context) => { console.log('[WORKFLOW_ENGINE] Thread eligible for draft generation', context); return { eligible: true }; }, }, // ... more steps ], }; engine.registerWorkflow(autoDraftWorkflow); ### Adding a New W...
(QB_NEW_EN_OTHER)
[grammar] ~53-~53: Use correct spacing
Context: ...rkflow); ``` ### Adding a New Workflow Function 1. Add the function to `workflow-functions....
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~55-~55: There might be a mistake here.
Context: ...rkflow Function 1. Add the function to workflow-functions.ts: typescript export const workflowFunctions: Record<string, WorkflowFunction> = { // ... existing functions ... myNewFunction: async (context) => { // Your logic here console.log('[WORKFLOW_FUNCTIONS] Executing my new function'); // Access previous step results const previousResult = context.results?.get('previous-step-id'); // Return result for next steps return { success: true, data: 'some data' }; }, }; 2. Add the step to your w...
(QB_NEW_EN_OTHER)
[grammar] ~74-~74: There might be a mistake here.
Context: ...the step to your workflow definition in createDefaultWorkflows(): typescript { id: 'my-new-step', name: 'My New Step', description: 'Description of what this step does', enabled: true, action: async (context) => { // Your logic here return { success: true }; }, errorHandling: 'continue', } ### Workflow Context Each wo...
(QB_NEW_EN_OTHER)
[grammar] ~90-~90: Use correct spacing
Context: ...ndling: 'continue', } ``` ### Workflow Context Each workflow function receives a contex...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~92-~92: There might be a mistake here.
Context: ...flow function receives a context object with: typescript type WorkflowContext = { connectionId: string; threadId: string; thread: IGetThreadResponse; foundConnection: typeof connection.$inferSelect; agent: any; env: any; results?: Map<string, any>; // Results from previous steps }; ### Error Handling Each step c...
(QB_NEW_EN_OTHER)
[grammar] ~106-~106: Use correct spacing
Context: ...s from previous steps }; ``` ### Error Handling Each step can have different error handl...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~108-~108: Use hyphens correctly
Context: ... Handling Each step can have different error handling strategies: - "continue" - S...
(QB_NEW_EN_OTHER_ERROR_IDS_29)
[grammar] ~108-~108: There might be a mistake here.
Context: ... step can have different error handling strategies: - "continue" - Skip failed steps and continue with ...
(QB_NEW_EN_OTHER)
[grammar] ~110-~110: Use hyphens correctly
Context: ...Skip failed steps and continue with the workflow - "fail" - Stop the entire workflow on error - `"...
(QB_NEW_EN_OTHER_ERROR_IDS_29)
[grammar] ~111-~111: Use hyphens correctly
Context: ... "fail" - Stop the entire workflow on error - "retry" - Retry the step up to maxRetries time...
(QB_NEW_EN_OTHER_ERROR_IDS_29)
[grammar] ~112-~112: There might be a mistake here.
Context: ...y"- Retry the step up tomaxRetries` times ### Example: Adding a New Workflow 1. **Def...
(QB_NEW_EN_OTHER)
[grammar] ~114-~114: Use correct spacing
Context: ...triestimes ### Example: Adding a New Workflow 1. **Define the workflow increateDefaultWor...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~116-~116: There might be a mistake here.
Context: ...w Workflow 1. Define the workflow in createDefaultWorkflows(): typescript const customWorkflow: WorkflowDefinition = { name: 'custom-processing', description: 'Custom thread processing workflow', steps: [ { id: 'custom-step-1', name: 'Custom Step 1', description: 'First custom processing step', enabled: true, action: async (context) => { console.log('[WORKFLOW_ENGINE] Executing custom step 1'); // Your custom logic here return { processed: true }; }, errorHandling: 'continue', }, { id: 'custom-step-2', name: 'Custom Step 2', description: 'Second custom processing step', enabled: true, action: async (context) => { const step1Result = context.results?.get('custom-step-1'); console.log('[WORKFLOW_ENGINE] Executing custom step 2 with result:', step1Result); // Your custom logic here return { completed: true }; }, errorHandling: 'retry', maxRetries: 3, }, ], }; engine.registerWorkflow(customWorkflow); 2. **Th...
(QB_NEW_EN_OTHER)
[grammar] ~155-~155: There might be a problem here.
Context: ...2. The workflow will be automatically executed - no need to update any other configuration! ###...
(QB_NEW_EN_MERGED_MATCH)
[grammar] ~155-~155: Use correct spacing
Context: ...xecuted** - no need to update any other configuration! ### Dynamic Workflow Discovery The workflow...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~157-~157: Use correct spacing
Context: ...er configuration! ### Dynamic Workflow Discovery The workflow engine automatically discov...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~159-~159: There might be a mistake here.
Context: ...y discovers and executes all registered workflows: typescript // Get all available workflow names from the engine const workflowNames = workflowEngine.getWorkflowNames(); // Execute all workflows dynamically for (const workflowName of workflowNames) { const { results, errors } = await workflowEngine.executeWorkflow(workflowName, context); } This means: - **No hardcoded...
(QB_NEW_EN_OTHER)
[grammar] ~171-~171: There might be a mistake here.
Context: ...low(workflowName, context); } ``` This means: - No hardcoded workflow lists: Workflow...
(QB_NEW_EN_OTHER)
[grammar] ~173-~173: There might be a mistake here.
Context: ...kflow lists**: Workflows are discovered automatically - Easy to add new workflows: Just regist...
(QB_NEW_EN_OTHER)
[grammar] ~174-~174: There might be a mistake here.
Context: ...add new workflows**: Just register them in createDefaultWorkflows() - Conditional workflows: Can be enabled/...
(QB_NEW_EN_OTHER)
[grammar] ~175-~175: There might be a mistake here.
Context: ...workflows**: Can be enabled/disabled at runtime - Future-proof: New workflows are automa...
(QB_NEW_EN_OTHER)
[grammar] ~176-~176: There might be a mistake here.
Context: ...roof**: New workflows are automatically included ## Migration from Hardcoded Logic The orig...
(QB_NEW_EN_OTHER)
[grammar] ~178-~178: Use correct spacing
Context: ...y included ## Migration from Hardcoded Logic The original hardcoded logic in `runThre...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~180-~180: There might be a mistake here.
Context: ...n runThreadWorkflow has been replaced with: 1. Workflow Engine: Orchestrates the exe...
(QB_NEW_EN_OTHER)
[grammar] ~185-~185: Use correct spacing
Context: ...aring**: Allows steps to share data and results This makes the system much more maintain...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~187-~187: Use correct spacing
Context: ...eps without modifying the core pipeline logic. ## Benefits - Cleaner Code: The main p...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~191-~191: There might be a mistake here.
Context: ...d on orchestration rather than business logic - Easier Testing: Each workflow function...
(QB_NEW_EN_OTHER)
[grammar] ~192-~192: There might be a mistake here.
Context: ...*: Each workflow function can be tested independently - Flexible Configuration: Workflows can ...
(QB_NEW_EN_OTHER)
[grammar] ~193-~193: Use proper capitalization
Context: ...an be enabled/disabled and modified via JSON - Better Error Handling: Granular error ...
(QB_NEW_EN_OTHER_ERROR_IDS_6)
[grammar] ~194-~194: There might be a mistake here.
Context: ...Handling**: Granular error handling per step - Reusability: Functions can be shared b...
(QB_NEW_EN_OTHER)
[grammar] ~195-~195: There might be a mistake here.
Context: ...nctions can be shared between different workflows - Maintainability: Adding new processing...
(QB_NEW_EN_OTHER)
[grammar] ~196-~196: There might be a mistake here.
Context: ...teps doesn't require modifying the main pipeline
(QB_NEW_EN_OTHER)
🪛 markdownlint-cli2 (0.17.2)
apps/server/src/thread-workflow-utils/README.md
74-74: Ordered list item prefix
Expected: 1; Actual: 2; Style: 1/1/1
(MD029, ol-prefix)
155-155: Ordered list item prefix
Expected: 1; Actual: 2; Style: 1/1/1
(MD029, ol-prefix)
🪛 Biome (2.1.2)
apps/server/src/thread-workflow-utils/workflow-engine.ts
[error] 136-136: expected : but instead found shouldExecute
Remove shouldExecute
(parse)
[error] 136-136: await is only allowed within async functions and at the top levels of modules.
(parse)
[error] 136-136: expected , but instead found ;
Remove ;
(parse)
[error] 139-139: expected , but instead found (
Remove (
(parse)
[error] 142-142: expected , but instead found :
Remove :
(parse)
[error] 142-142: expected , but instead found (
Remove (
(parse)
[error] 149-179: Expected a property, an expression, or a method but instead found '},
{
id: 'analyze-email-intent',
name: 'Analyze Email Intent',
description: 'Analyzes the intent of the latest email in the thread',
enabled: true,
action: workflowFunctions.analyzeEmailIntent,
},
{
id: 'validate-response-needed',
name: 'Validate Response Needed',
description: 'Checks if the email requires a response based on intent analysis',
enabled: true,
action: workflowFunctions.validateResponseNeeded,
},
{
id: 'generate-draft-content',
name: 'Generate Draft Content',
description: 'Generates the draft email content using AI',
enabled: true,
action: workflowFunctions.generateAutomaticDraft,
errorHandling: 'continue',
},
{
id: 'create-draft',
name: 'Create Draft',
description: 'Creates the draft in the email system',
enabled: true,
action: workflowFunctions.createDraft,
errorHandling: 'continue',
},'.
Expected a property, an expression, or a method here.
(parse)
[error] 199-199: expected , but instead found .
Remove .
(parse)
[error] 199-199: Expected a property, a shorthand property, a getter, a setter, or a method but instead found '{'.
Expected a property, a shorthand property, a getter, a setter, or a method here.
(parse)
[error] 200-200: expected , but instead found threadId
Remove threadId
(parse)
[error] 202-202: expected , but instead found )
Remove )
(parse)
[error] 202-202: expected , but instead found ;
Remove ;
(parse)
[error] 206-206: Expected an identifier, an array pattern, or an object pattern but instead found ''upsert-embeddings''.
Expected an identifier, an array pattern, or an object pattern here.
(parse)
[error] 206-206: expected : but instead found ,
Remove ,
(parse)
[error] 207-207: Expected an identifier, an array pattern, or an object pattern but instead found ''Upsert Embeddings''.
Expected an identifier, an array pattern, or an object pattern here.
(parse)
[error] 207-207: expected : but instead found ,
Remove ,
(parse)
[error] 208-208: Expected an identifier, an array pattern, or an object pattern but instead found ''Saves vector embeddings to the database''.
Expected an identifier, an array pattern, or an object pattern here.
(parse)
[error] 208-208: expected : but instead found ,
Remove ,
(parse)
[error] 209-209: Expected an identifier, an array pattern, or an object pattern but instead found 'true'.
Expected an identifier, an array pattern, or an object pattern here.
(parse)
[error] 209-209: expected : but instead found ,
Remove ,
(parse)
[error] 210-210: expected , but instead found .
Remove .
(parse)
[error] 211-211: Expected an identifier, an array pattern, or an object pattern but instead found ''continue''.
Expected an identifier, an array pattern, or an object pattern here.
(parse)
[error] 211-211: expected : but instead found ,
Remove ,
(parse)
[error] 205-212: Object and Array patterns require initializers.
This pattern is declared, but it is not given an initialized value.
(parse)
[error] 213-213: Expected an identifier, an array pattern, or an object pattern but instead found ']'.
Expected an identifier, an array pattern, or an object pattern here.
(parse)
[error] 281-281: Illegal return statement outside of a function
(parse)
[error] 281-282: Expected a statement but instead found '}'.
Expected a statement here.
(parse)
[error] 210-210: Shouldn't redeclare 'workflowFunctions'. Consider to delete it or rename it.
'workflowFunctions' is defined here:
(lint/suspicious/noRedeclare)
🪛 GitHub Actions: autofix.ci
apps/server/src/thread-workflow-utils/workflow-engine.ts
[error] 136-136: Syntax error: Expected : but found Identifier at line 136. Likely a missing colon in object or type definition.
🔇 Additional comments (4)
apps/server/src/trpc/routes/ai/compose.ts (1)
5-5: Excellent consolidation move! This is exactly the kind of first-principles thinking we need.Centralizing the
escapeXmlutility into the new workflow-utils module eliminates code duplication and creates a single source of truth. It's like consolidating rocket engine components - much better to have one well-tested, reusable module than scattered implementations everywhere.apps/server/src/routes/agent/index.ts (2)
810-810: Perfect debugging addition for the table drop operation.Clear logging when dropping tables is essential for operational visibility. It's like having telemetry during a rocket engine test - you want to know exactly what's happening.
581-581: Critical database query corrections - these fixes are absolutely essential.Changing from
idtothread_idin the WHERE clauses is a fundamental correctness fix. The database schema shows both columns exist, butthread_idis the proper identifier for thread operations. Without this fix, queries would likely return incorrect results or fail entirely.This is exactly the kind of precision engineering we need - like ensuring rocket guidance systems use the correct coordinate references.
Also applies to: 1619-1619, 1653-1653
apps/server/src/trpc/routes/mail.ts (1)
92-102: Clean refactor! This is like simplifying rocket engine code - less complexity, same thrust 🚀The unified approach using
rawListThreadswith dynamic label ID handling is much cleaner than the previous conditional branching. The folder-to-label mapping is still applied correctly when no search query is present. This is the kind of elegant simplification we need.
b9f94e6 to
af8bd7f
Compare
Bug ReportBug Name: Inconsistent labelId behavior in trpc/routes/mail.ts Comments? Email us. This is the last day of your free trial. Subscribe at jazzberry.ai. |
af8bd7f to
ed46cd0
Compare
Bug Report
Comments? Email us. This is the last day of your free trial. Subscribe at jazzberry.ai. |
ed46cd0 to
e0643a3
Compare
Bug Report
Comments? Email us. This is the last day of your free trial. Subscribe at jazzberry.ai. |

Refactored Thread Processing with Workflow Engine Architecture
Description
Implemented a modular workflow engine architecture for thread processing, replacing the monolithic approach with a flexible, configurable system. This refactoring moves hardcoded business logic into reusable workflow steps that can be composed and executed dynamically, improving maintainability and extensibility.
Type of Change
Areas Affected
Testing Done
Checklist
Additional Notes
The new workflow engine provides several key benefits:
The implementation includes comprehensive documentation in the README.md file explaining the architecture and how to extend it with new workflows.
Summary by CodeRabbit
New Features
Refactor
Bug Fixes
Chores