feat/Implement a new AgentLLM provider to Delegate Task Master LLM calls to an MCP client without requiring API keys#933
feat/Implement a new AgentLLM provider to Delegate Task Master LLM calls to an MCP client without requiring API keys#933rtmcrc wants to merge 97 commits intoeyaltoledano:nextfrom
Conversation
This commit introduces a new "AgentLLM" provider and associated MCP tool to delegate LLM calls to an agent. This allows Taskmaster MCP sever to offload LLM operations to the agent calling it. Key changes include: - **New `AgentLLMProvider`:** An AI provider that, instead of calling an LLM directly, returns a delegation signal with an `interactionId` and LLM request details. - **New `agent_llm` MCP Tool:** A tool that facilitates communication between Taskmaster and the agent. Taskmaster uses it to request LLM calls, and the agent uses it to return the LLM response. - **TaskMasterMCPServer Enhancements:** The server now manages pending agent interactions, pausing the original operation and resuming it upon receiving the agent's response. - **Documentation:** Added `docs/agent-llm-workflow.md` to outline the complete workflow. - **Rules:** Added rules `assets/rules/agent_llm.mdc`for the `agent_llm` MCP tool and `AgentLLMProvider`. The workflow involves Taskmaster initiating a delegated LLM call, the agent performing the LLM call, and the agent calling `agent_llm` back to Taskmaster with the results. An `interactionId` is used to correlate requests and responses.
🦋 Changeset detectedLatest commit: c034605 The changes in this PR will be included in the next version bump. Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Potentially duplicate of #863 |
|
Tested with Windsurf and now it works with Cursor also |
|
This is an excellent improvement, saving windsurf and cursor users some money ;-) |
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughAdds AgentLLM delegation: new AgentLLM provider that emits delegation signals, an Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Client as Client
participant MCP as MCP Server
participant Tool as Tool (e.g., expand_task)
participant Executor as AgentLLMProviderExecutor
participant AgentTool as agent_llm Tool
participant Agent as Agent Client
participant Saver as AgentLLM Saver
Client->>MCP: call tool
MCP->>Tool: execute
Tool->>Executor: execute wrapped provider -> provider returns delegation (agent_llm_delegation)
Executor-->>Tool: initial pending response (needsAgentDelegation / pendingInteraction)
Executor->>AgentTool: dispatch pendingInteraction (interactionId, llmRequestForAgent)
AgentTool-->>Agent: pendingInteraction payload (out-of-band)
Note right of Agent: Agent performs external LLM call using provided details
Agent->>AgentTool: POST agent_llm (interactionId + agentLLMResponse)
AgentTool->>Executor: deliver agent response
Executor->>Saver: _handlePostProcessing(finalLLMOutput)
Saver->>MCP: persist updates (tasks.json, md files)
Executor-->>Tool: resolve pending promise with mainResult
Tool-->>Client: return final result
Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes
Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
715c1a7 to
0e5abb5
Compare
…g systems, especially Windows, where backslashes are used as path separators. fix: vscode does not see rules without .instructions.md extension Merge. Format
* fix: prevent CLAUDE.md overwrite by using imports - Copy Task Master instructions to .taskmaster/CLAUDE.md - Add import section to user's CLAUDE.md instead of overwriting - Preserve existing user content - Clean removal of Task Master content on uninstall Closes eyaltoledano#929 * chore: add changeset for Claude import fix
…edano#968) * feat: add task master (tm) custom slash commands Add comprehensive task management system integration via custom slash commands. Includes commands for: - Project initialization and setup - Task parsing from PRD documents - Task creation, update, and removal - Subtask management - Dependency tracking and validation - Complexity analysis and task expansion - Project status and reporting - Workflow automation This provides a complete task management workflow directly within Claude Code. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: add changeset --------- Co-authored-by: neno-is-ooo <204701868+neno-is-ooo@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com>
* chore: create extension scaffolding * chore: fix workspace for changeset * chore: fix package-lock
…ano#980) * add .mcp.json with claude profile * add changeset * update changeset * update test
…toledano#979) Co-authored-by: Ben Vargas <ben@example.com>
…oledano#978) * feat: complete Groq provider integration and add Kimi K2 model - Add missing getRequiredApiKeyName() method to GroqProvider class - Register GroqProvider in ai-services-unified.js PROVIDERS object - Add Groq API key handling to config-manager.js (isApiKeySet and getMcpApiKeyStatus) - Add GROQ_API_KEY to env.example with format hint - Add moonshotai/kimi-k2-instruct model to Groq provider ($1/$3 per 1M tokens, 16k max) - Fix import sorting for linting compliance - Add GroqProvider mock to ai-services-unified tests Fixes missing implementation pieces that prevented Groq provider from working. * chore: improve changeset --------- Co-authored-by: Ben Vargas <ben@example.com> Co-authored-by: Ralph Khreish <35776126+Crunchyman-ralph@users.noreply.github.com>
…#973) * Amp profile + tests * generatlize to Agent instead of Claude Code to support any agent * add changeset * unnecessary tab formatting * fix exports * fix formatting
…altoledano#974) * zed profile * add changeset * update changeset
…#972) * add OLLAMA_API_KEY * add missing API keys * add changeset * update keys and fix OpenAI comment * chore: create extension scaffolding (eyaltoledano#989) * chore: create extension scaffolding * chore: fix workspace for changeset * chore: fix package-lock * feat(profiles): Add MCP configuration to Claude Code rules (eyaltoledano#980) * add .mcp.json with claude profile * add changeset * update changeset * update test * fix: show command no longer requires complexity report to exist (eyaltoledano#979) Co-authored-by: Ben Vargas <ben@example.com> * feat: complete Groq provider integration and add Kimi K2 model (eyaltoledano#978) * feat: complete Groq provider integration and add Kimi K2 model - Add missing getRequiredApiKeyName() method to GroqProvider class - Register GroqProvider in ai-services-unified.js PROVIDERS object - Add Groq API key handling to config-manager.js (isApiKeySet and getMcpApiKeyStatus) - Add GROQ_API_KEY to env.example with format hint - Add moonshotai/kimi-k2-instruct model to Groq provider ($1/$3 per 1M tokens, 16k max) - Fix import sorting for linting compliance - Add GroqProvider mock to ai-services-unified tests Fixes missing implementation pieces that prevented Groq provider from working. * chore: improve changeset --------- Co-authored-by: Ben Vargas <ben@example.com> Co-authored-by: Ralph Khreish <35776126+Crunchyman-ralph@users.noreply.github.com> * docs: Auto-update and format models.md * feat: Add Amp rule profile with AGENT.md and MCP config (eyaltoledano#973) * Amp profile + tests * generatlize to Agent instead of Claude Code to support any agent * add changeset * unnecessary tab formatting * fix exports * fix formatting * feat: Add Zed editor rule profile with agent rules and MCP config (eyaltoledano#974) * zed profile * add changeset * update changeset --------- Co-authored-by: Ralph Khreish <35776126+Crunchyman-ralph@users.noreply.github.com> Co-authored-by: Ben Vargas <ben@vargas.com> Co-authored-by: Ben Vargas <ben@example.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
…ledano#970) * add opencode to profile lists * add opencode profile / modify mcp config after add * add changeset * not necessary; main config being updated * add issue link * add/fix tests * fix url and docsUrl * update test for new urls * fix formatting * update/fix tests
* chore: add coderabbit configuration * chore: fix coderabbit config * chore: improve coderabbit config * chore: more coderabbit reviews * chore: remove all defaults
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
scripts/modules/dependency-manager.js (1)
62-70: Fix tag-aware task loading before aborting
readJSONreturns the tagged root object, sodata.tasksis undefined under the standard multi-tag layout. This guard therefore trips on every tagged project and exits before any dependency work happens, breaking the command. Resolve the tag first and validate the resulting array instead.- const data = readJSON(tasksPath, context.projectRoot, context.tag); - if (!data || !data.tasks) { - log('error', 'No valid tasks found in tasks.json'); - process.exit(1); - } - - const tag = context.tag || 'master'; - const tasks = getTasksForTag(data, tag); + const data = readJSON(tasksPath, context.projectRoot, context.tag); + const tag = context.tag || 'master'; + + if (!data) { + log('error', 'No valid tasks found in tasks.json'); + process.exit(1); + } + + const tasks = getTasksForTag(data, tag); + if (!Array.isArray(tasks)) { + log('error', `No valid tasks found for tag '${tag}' in tasks.json`); + process.exit(1); + }Based on learnings
♻️ Duplicate comments (1)
mcp-server/src/core/direct-functions/research.js (1)
68-288: Restore canonical error codes in researchDirect.The direct-function guidelines require all responses to use the shared codes (
INPUT_VALIDATION_ERROR,FILE_NOT_FOUND_ERROR,CORE_FUNCTION_ERROR,UNEXPECTED_ERROR). This block still returns bespoke values (MISSING_PARAMETER,INVALID_PARAMETER,INVALID_CORE_RESPONSE,RESEARCH_ERROR), so clients relying on the standardized codes can’t interpret failures correctly. Please swap each return to the canonical constants and normalize the catch path, e.g.:- error: { - code: 'MISSING_PARAMETER', + error: { + code: 'INPUT_VALIDATION_ERROR', message: 'The query parameter is required and must be a non-empty string' } ... - error: { - code: 'INVALID_PARAMETER', + error: { + code: 'INPUT_VALIDATION_ERROR', message: `Detail level must be one of: ${validDetailLevels.join(', ')}` } ... - error: { - code: 'INVALID_CORE_RESPONSE', + error: { + code: 'CORE_FUNCTION_ERROR', message: 'Core research function returned invalid data.' } ... - error: { - code: error.code || 'RESEARCH_ERROR', - message: error.message - } + const validCodes = new Set([ + 'INPUT_VALIDATION_ERROR', + 'FILE_NOT_FOUND_ERROR', + 'CORE_FUNCTION_ERROR', + 'UNEXPECTED_ERROR' + ]); + error: { + code: validCodes.has(error.code) ? error.code : 'CORE_FUNCTION_ERROR', + message: error.message + }This preserves compatibility with other tools and satisfies the direct-function contract. As per coding guidelines.
🧹 Nitpick comments (1)
.changeset/four-bugs-occur.md (1)
5-7: Refocus changeset summary on user-facing impact.The current description emphasizes internal implementation details (removal of file and parameter, complexity reduction for AI agents) rather than the user-facing benefit. Per coding guidelines, changesets should describe what changed in the released version that is relevant to users or consumers of the package.
Additionally, line 7 could be more concise—consider removing the verbose explanation or making it user-centric.
Consider this revision:
- remove file and complexity report parameter from get-tasks and get-task mcp tool - - - In an effort to reduce complexity and context bloat for ai coding agents, we simplified the parameters of these tools + Simplify get-tasks and get-task MCP tools for improved clarityIf the removed file or parameter change is significant to document, add a brief user-facing note explaining the impact (e.g., "improves response clarity" or "reduces unnecessary data").
As per coding guidelines.
| @@ -0,0 +1,5 @@ | |||
| --- | |||
| "task-master-ai": patch | |||
There was a problem hiding this comment.
Reconsider semantic versioning: should be minor, not patch.
The PR introduces a substantial new feature (AgentLLM provider for delegating LLM calls to MCP clients), which warrants a minor version bump, not patch. Patch releases are for bug fixes and non-breaking maintenance; new features require at least a minor version increment. Additionally, the PR comments from the reviewer explicitly requested the changeset be marked as "minor" to avoid bumping to v1.0.
Apply this diff:
-"task-master-ai": patch
+"task-master-ai": minorBased on coding guidelines and PR review context.
📝 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.
| "task-master-ai": patch | |
| "task-master-ai": minor |
🤖 Prompt for AI Agents
.changeset/lazy-suits-smell.md around line 2: the changeset currently marks the
release as "patch" but the PR adds a significant new feature (AgentLLM
provider), so update the changeset to use "minor" instead of "patch". Edit the
file to change the version bump line from `"task-master-ai": patch` to
`"task-master-ai": minor` (preserve YAML/changeset format and surrounding
content) so the release level correctly reflects a feature addition.
| "task-master-ai": patch | ||
| --- | ||
|
|
||
| Improve session persistence reliability No newline at end of file |
There was a problem hiding this comment.
Rewrite description to be user-facing and match the PR scope.
The description "Improve session persistence reliability" is generic and does not reflect the actual feature being added. Changesets should describe user-facing impact in imperative mood, typically a single line. The PR introduces an AgentLLM provider that enables delegating LLM calls to connected MCP agents, eliminating the need for direct API keys.
Apply this diff:
-Improve session persistence reliability
+Add AgentLLM provider for delegating LLM calls to MCP agents without requiring API keysAs per coding guidelines: changesets should describe user-facing impact rather than internal implementation details.
📝 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.
| Improve session persistence reliability | |
| Add AgentLLM provider for delegating LLM calls to MCP agents without requiring API keys |
🤖 Prompt for AI Agents
In .changeset/lazy-suits-smell.md around line 5, the changeset description is
generic; replace it with a concise, user-facing imperative sentence that
reflects the PR scope — e.g. "Add AgentLLM provider to delegate LLM calls to
connected MCP agents so users can operate without direct API keys." Ensure the
changeset is a single-line, imperative description and remove
internal-implementation phrasing.
There was a problem hiding this comment.
The lazy-suits-smell.md does not apply to AgentLLM
There was a problem hiding this comment.
@rtmcrc, understood! You're absolutely right—lazy-suits-smell.md is for session persistence improvements and is separate from the AgentLLM feature.
I can see that the AgentLLM provider implementation is documented in the quiet-ties-battle.md changeset, which correctly describes adding the AgentLLM provider for delegating LLM calls to MCP agents without requiring API keys.
Thank you for the clarification!
🧠 Learnings used
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1091
File: assets/claude/agents/task-orchestrator.md:69-78
Timestamp: 2025-08-06T21:13:05.240Z
Learning: For Claude agent instruction files in .claude/agents/ and assets/claude/agents/ directories, ignore markdownlint issues (like MD031 blanks-around-fences, MD040 fenced-code-language, MD041 missing top-level heading) as these files follow Claude's specific agent format requirements rather than standard markdown documentation conventions.
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/changeset.mdc:0-0
Timestamp: 2025-07-18T17:07:53.100Z
Learning: Applies to .changeset/*.md : The changeset summary should be user-facing, describing what changed in the released version that is relevant to users or consumers of the package.
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/changeset.mdc:0-0
Timestamp: 2025-07-18T17:07:53.100Z
Learning: Applies to .changeset/*.md : When running `npm run changeset` or `npx changeset add`, provide a concise summary of the changes for the `CHANGELOG.md` in imperative mood, typically a single line, and not a detailed Git commit message.
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/new_features.mdc:0-0
Timestamp: 2025-07-18T17:12:57.903Z
Learning: Applies to .changeset/* : Create appropriate changesets for new features, use semantic versioning, include tagged system information in release notes, and document breaking changes if any.
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/changeset.mdc:0-0
Timestamp: 2025-07-18T17:07:53.100Z
Learning: Every pull request containing new features, bug fixes, breaking changes, performance improvements, significant refactoring, user-facing documentation updates, dependency updates, or impactful build/tooling changes should include a changeset file.
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/changeset.mdc:0-0
Timestamp: 2025-07-18T17:07:53.100Z
Learning: Do not add a changeset for trivial chores such as very minor code cleanup, adding comments that don't clarify behavior, or typo fixes in non-user-facing code or internal docs.
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/changeset.mdc:0-0
Timestamp: 2025-07-18T17:07:53.100Z
Learning: Always stage and commit the generated `.changeset/*.md` file along with your relevant code changes.
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-27T17:16:25.430Z
Learning: Applies to .changeset/*.md : Changesets should describe user-facing impact rather than internal implementation details
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1091
File: .changeset/wide-actors-report.md:0-0
Timestamp: 2025-08-06T21:14:23.071Z
Learning: For changeset files (.changeset/*.md), the first line after the frontmatter must be a plain, unstyled summary line that gets integrated directly into the changelog. Do not add markdown headings or styling as this would interfere with the changelog generation process. Ignore markdownlint MD041 rule for these files.
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/changeset.mdc:0-0
Timestamp: 2025-07-18T17:07:53.100Z
Learning: Do not add a changeset for non-impactful test updates, such as minor refactoring of tests or adding tests for existing functionality without fixing bugs.
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1285
File: .changeset/nice-ways-hope.md:5-17
Timestamp: 2025-10-08T12:21:14.455Z
Learning: For changeset files (.changeset/*.md): The first line should be concise and in imperative mood, but the body after the first line can include as many user-facing details as desired (bullets, explanations, links, etc.) to provide context for the CHANGELOG.md.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (2)
mcp-server/src/tools/scope-up.js (2)
94-100: Agent delegation logic looks correct, but consider logging.The delegation handling follows the new pattern introduced in this PR: calling
createAgentDelegationResponseafter the direct function completes and short-circuiting if delegation is triggered. The guidance message appropriately instructs the agent to reanalyze project complexity after scoping up.However, per coding guidelines, successful completion should be logged with a result summary. Consider adding a log statement when delegation occurs:
const delegation = createAgentDelegationResponse( result, log, 'scope_up_task', "Your Next Action: After you have scoped the task reanalyze the project complexity with 'analyze_project_complexity' tool including this task ID in 'ids' parameter." ); -if (delegation.delegated) return delegation.response; +if (delegation.delegated) { + log.info('Delegation triggered for scope_up_task'); + return delegation.response; +}
102-108: Response handling is correct; consider adding success logging.The fallback to
handleApiResultis appropriate and follows guidelines. However, per coding guidelines, successful operations should be logged with a result summary. Consider adding:+ log.info('Scope-up completed successfully'); return handleApiResult( result, log, 'Error scoping up task', undefined, args.projectRoot );
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
docs/models.md(6 hunks)mcp-server/src/tools/scope-down.js(2 hunks)mcp-server/src/tools/scope-up.js(2 hunks)packages/tm-core/src/common/constants/providers.ts(1 hunks)scripts/modules/ai-services-unified.js(4 hunks)scripts/modules/config-manager.js(4 hunks)scripts/modules/supported-models.json(2 hunks)scripts/modules/task-manager/analyze-task-complexity.js(2 hunks)src/ai-providers/index.js(1 hunks)tests/unit/ai-services-unified.test.js(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
- scripts/modules/config-manager.js
- scripts/modules/task-manager/analyze-task-complexity.js
- mcp-server/src/tools/scope-down.js
- tests/unit/ai-services-unified.test.js
🧰 Additional context used
📓 Path-based instructions (13)
scripts/modules/ai-services-unified.js
📄 CodeRabbit inference engine (.cursor/rules/ai_providers.mdc)
Integrate the new provider module with scripts/modules/ai-services-unified.js by importing it and adding an entry to the PROVIDER_FUNCTIONS map.
scripts/modules/ai-services-unified.js: Centralize all LLM calls throughgenerateTextServiceorgenerateObjectService.
Do not import or call anything from the oldai-services.js,ai-client-factory.js, orai-client-utils.jsfiles.
Do not fetch AI-specific parameters (model ID, max tokens, temp) usingconfig-manager.jsgetters for the AI call. Pass theroleinstead.
Do not implement fallback or retry logic outsideai-services-unified.js.
Do not handle API key resolution outside the service layer (it usesutils.jsinternally).The telemetryData object returned by ai-services-unified.js must include the fields: timestamp, userId, commandName, modelUsed, providerName, inputTokens, outputTokens, totalTokens, totalCost, and currency.
Files:
scripts/modules/ai-services-unified.js
scripts/modules/*.js
📄 CodeRabbit inference engine (.cursor/rules/architecture.mdc)
Each module in scripts/modules/ should be focused on a single responsibility, following the modular architecture (e.g., commands.js for CLI command handling, task-manager.js for task data and core logic, dependency-manager.js for dependency management, ui.js for CLI output formatting, ai-services-unified.js for AI service integration, config-manager.js for configuration management, utils.js for utility functions).
scripts/modules/*.js: Export all core functions, helper functions, and utility methods needed by your new function or command from their respective modules. Explicitly review the module's export block to ensure every required dependency is included.
Pass all required parameters to functions you call within your implementation and verify that direct function parameters match their core function counterparts.
Use consistent file naming conventions: 'task_${id.toString().padStart(3, '0')}.txt', use path.join for composing file paths, and use appropriate file extensions (.txt for tasks, .json for data).
Use structured error objects with code and message properties, include clear error messages, and handle both function-specific and file system errors.
Import all silent mode utilities together from 'scripts/modules/utils.js' and always use isSilentMode() to check global silent mode status. Wrap core function calls within direct functions using enableSilentMode() and disableSilentMode() in a try/finally block if the core function might produce console output.
Core functions should check outputFormat === 'text' before displaying UI elements and use internal logging that respects silent mode.
Design functions to accept dependencies as parameters (dependency injection) and avoid hard-coded dependencies that are difficult to mock.
Keep pure logic separate from I/O operations or UI rendering to allow testing the logic without mocking complex dependencies.
When implementing core logic for new features, do so in 'scripts/modules/' before CLI or MCP interfaces, and d...
Files:
scripts/modules/ai-services-unified.js
scripts/modules/**
📄 CodeRabbit inference engine (.cursor/rules/dev_workflow.mdc)
When using the MCP server, restart it if core logic in
scripts/modulesor MCP tool/direct function definitions change.
Files:
scripts/modules/ai-services-unified.jsscripts/modules/supported-models.json
scripts/modules/ai-services*.js
📄 CodeRabbit inference engine (.cursor/rules/new_features.mdc)
Ensure AI calls correctly handle and propagate telemetryData as described in 'telemetry.mdc'.
Files:
scripts/modules/ai-services-unified.js
scripts/modules/*
📄 CodeRabbit inference engine (.cursor/rules/tags.mdc)
scripts/modules/*: Every command that reads or writes tasks.json must be tag-aware
All command files must import getCurrentTag from utils.js
Every CLI command that operates on tasks must include the --tag CLI option
All commands must resolve the tag using the pattern: options.tag || getCurrentTag(projectRoot) || 'master'
All commands must find projectRoot with error handling before proceeding
All commands must pass { projectRoot, tag } as context to core functions
MCP direct functions must accept and use a context object containing projectRoot and tag, and pass them to core functions
Do not hard-code tag resolution (e.g., const tag = options.tag || 'master';); always use getCurrentTag
Do not omit the --tag CLI option in commands that operate on tasks
Do not omit the context parameter when calling core functions from commands
Do not call readJSON or writeJSON without passing projectRoot and tag
Files:
scripts/modules/ai-services-unified.jsscripts/modules/supported-models.json
**/*.js
📄 CodeRabbit inference engine (.cursor/rules/tests.mdc)
**/*.js: Declare and initialize global variables at the top of modules to avoid hoisting issues.
Use proper function declarations to avoid hoisting issues and initialize variables before they are referenced.
Do not reference variables before their declaration in module scope.
Use dynamic imports (import()) to avoid initialization order issues in modules.
Files:
scripts/modules/ai-services-unified.jssrc/ai-providers/index.jsmcp-server/src/tools/scope-up.js
src/ai-providers/*.js
📄 CodeRabbit inference engine (.cursor/rules/ai_providers.mdc)
src/ai-providers/*.js: Create a new provider module file in src/ai-providers/ named .js when adding a new AI provider.
Provider modules must export three functions: generateText, streamText, and generateObject.
Provider modules must import the provider's create function from @ai-sdk/, and import generateText, streamText, generateObject from the core ai package, as well as the log utility from ../../scripts/modules/utils.js.
Implement generateText, streamText, and generateObject functions in provider modules with basic validation and try/catch error handling.Provider-specific wrappers for Vercel AI SDK functions must be implemented in src/ai-providers/*.js, each file corresponding to a provider.
Files:
src/ai-providers/index.js
mcp-server/src/tools/*.js
📄 CodeRabbit inference engine (.cursor/rules/architecture.mdc)
MCP server tools in mcp-server/src/tools/*.js must have their execute methods wrapped with the withNormalizedProjectRoot higher-order function from tools/utils.js to ensure consistent path handling.
mcp-server/src/tools/*.js: MCP tools must follow a specific structure: use server.addTool with snake_case tool names, define parameters using Zod, and implement the execute function as an async function.
All MCP tool execute methods that require access to the project root MUST be wrapped with the withNormalizedProjectRoot Higher-Order Function (HOF) from mcp-server/src/tools/utils.js.
MCP tools should always call *Direct wrappers instead of executeTaskMasterCommand, except as a fallback if a direct function is not yet implemented.
Use camelCase with Tool suffix for tool registration functions in mcp-server/src/tools/.
Use snake_case for tool names exposed to MCP clients in server.addTool definitions.
Log the start of execution with arguments (sanitized if sensitive), log successful completion with result summary, log all error conditions with appropriate log levels, and include the cache status in result logs in MCP tool files.
Do not log entire large data structures or sensitive information in MCP tool files.
Use handleApiResult to format and return the response from MCP tools.
mcp-server/src/tools/*.js: Create tool definitions in 'mcp-server/src/tools/', use Zod for parameter validation, include optional tag parameter for multi-context support, and follow established naming conventions.
For long-running operations that should not block the client, use the AsyncOperationManager in MCP tools and implement progress reporting.
Files:
mcp-server/src/tools/scope-up.js
mcp-server/src/{tools,core/direct-functions}/*.js
📄 CodeRabbit inference engine (.cursor/rules/mcp.mdc)
mcp-server/src/{tools,core/direct-functions}/*.js: Use kebab-case for all file names in mcp-server/src/tools/ and mcp-server/src/core/direct-functions/.
Use helpers from mcp-server/src/tools/utils.js, mcp-server/src/core/utils/path-utils.js, and mcp-server/src/core/utils/ai-client-utils.js for centralized utilities.
Files:
mcp-server/src/tools/scope-up.js
mcp-server/src/tools/**/*.js
📄 CodeRabbit inference engine (.cursor/rules/telemetry.mdc)
MCP tool files in mcp-server/src/tools/ must call the corresponding direct function wrapper and pass the result to handleApiResult(result, log) from mcp-server/src/tools/utils.js, ensuring telemetryData is included in the final MCP response.
Files:
mcp-server/src/tools/scope-up.js
mcp-server/src/{core/utils,tools}/**/*.js
📄 CodeRabbit inference engine (.cursor/rules/utilities.mdc)
Place utilities specifically designed to support the MCP server implementation into the appropriate subdirectories within
mcp-server/src/(e.g., path/core logic helpers inmcp-server/src/core/utils/, tool execution/response helpers inmcp-server/src/tools/utils.js).
Files:
mcp-server/src/tools/scope-up.js
scripts/modules/supported-models.json
📄 CodeRabbit inference engine (.cursor/rules/ai_providers.mdc)
Add a new key for the provider and an array of model objects under it in scripts/modules/supported-models.json, including id, name, allowed_roles, and optionally swe_score, cost_per_1m_tokens, and max_tokens.
Files:
scripts/modules/supported-models.json
docs/**/*
📄 CodeRabbit inference engine (.cursor/rules/new_features.mdc)
Add feature documentation to '/docs' folder, include tagged system usage examples, update command reference documentation, and provide migration notes if relevant.
Files:
docs/models.md
🧠 Learnings (65)
📓 Common learnings
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/glossary.mdc:0-0
Timestamp: 2025-07-18T17:10:53.657Z
Learning: Guidelines for implementing and interacting with the Task Master MCP Server (mcp.mdc).
Learnt from: rtmcrc
Repo: eyaltoledano/claude-task-master PR: 933
File: mcp-server/src/tools/agent-llm.js:1-3
Timestamp: 2025-10-12T11:06:36.374Z
Learning: The agent_llm MCP tool in mcp-server/src/tools/agent-llm.js is an exception to the standard MCP tool pattern. It should NOT use handleApiResult because it handles delegated LLM calls rather than direct API calls. Using createErrorResponse for error messages is the correct approach for this tool.
Learnt from: rtmcrc
Repo: eyaltoledano/claude-task-master PR: 933
File: assets/rules/agentllm.mdc:57-60
Timestamp: 2025-10-15T18:18:36.402Z
Learning: In agentllm delegation mode, the `expand_all` tool returns a list of `delegatedTaskIds` that are eligible for expansion, and the MCP client must then call `expand_task` individually for each returned task ID. This differs from normal mode where `expand_all` automatically submits all eligible tasks for expansion without requiring subsequent `expand_task` calls.
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/glossary.mdc:0-0
Timestamp: 2025-07-18T17:10:53.657Z
Learning: Comprehensive reference for Taskmaster MCP tools and CLI commands with tagged task lists information (taskmaster.mdc).
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/dev_workflow.mdc:0-0
Timestamp: 2025-07-18T17:10:12.881Z
Learning: Use the Taskmaster command set (`task-master` CLI or MCP tools) for all task management operations: listing, expanding, updating, tagging, and status changes.
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_services.mdc:0-0
Timestamp: 2025-07-18T17:06:57.833Z
Learning: Applies to scripts/modules/task-manager/*.js : Centralize all LLM calls through `generateTextService` or `generateObjectService`.
📚 Learning: 2025-07-18T17:06:04.909Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_providers.mdc:0-0
Timestamp: 2025-07-18T17:06:04.909Z
Learning: Applies to scripts/modules/ai-services-unified.js : Integrate the new provider module with scripts/modules/ai-services-unified.js by importing it and adding an entry to the PROVIDER_FUNCTIONS map.
Applied to files:
scripts/modules/ai-services-unified.jssrc/ai-providers/index.jspackages/tm-core/src/common/constants/providers.ts
📚 Learning: 2025-07-18T17:06:57.833Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_services.mdc:0-0
Timestamp: 2025-07-18T17:06:57.833Z
Learning: Applies to scripts/modules/ai-services-unified.js : Centralize all LLM calls through `generateTextService` or `generateObjectService`.
Applied to files:
scripts/modules/ai-services-unified.jssrc/ai-providers/index.js
📚 Learning: 2025-07-18T17:06:04.909Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_providers.mdc:0-0
Timestamp: 2025-07-18T17:06:04.909Z
Learning: Applies to src/ai-providers/*.js : Provider modules must import the provider's create<ProviderName> function from ai-sdk/<provider-name>, and import generateText, streamText, generateObject from the core ai package, as well as the log utility from ../../scripts/modules/utils.js.
Applied to files:
scripts/modules/ai-services-unified.jssrc/ai-providers/index.jspackages/tm-core/src/common/constants/providers.ts
📚 Learning: 2025-07-18T17:06:57.833Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_services.mdc:0-0
Timestamp: 2025-07-18T17:06:57.833Z
Learning: Applies to scripts/modules/ai-services-unified.js : Do not fetch AI-specific parameters (model ID, max tokens, temp) using `config-manager.js` getters for the AI call. Pass the `role` instead.
Applied to files:
scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:12:57.903Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/new_features.mdc:0-0
Timestamp: 2025-07-18T17:12:57.903Z
Learning: Applies to scripts/modules/ai-services*.js : Ensure AI calls correctly handle and propagate telemetryData as described in 'telemetry.mdc'.
Applied to files:
scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:18:17.759Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/utilities.mdc:0-0
Timestamp: 2025-07-18T17:18:17.759Z
Learning: Applies to scripts/modules/task-manager/**/*.js : Do not call AI-specific getters (like `getMainModelId`, `getMainMaxTokens`) from core logic functions in `scripts/modules/task-manager/*`; instead, pass the `role` to the unified AI service.
Applied to files:
scripts/modules/ai-services-unified.jsscripts/modules/supported-models.json
📚 Learning: 2025-07-18T17:06:57.833Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_services.mdc:0-0
Timestamp: 2025-07-18T17:06:57.833Z
Learning: Applies to scripts/modules/ai-services-unified.js : Do not import or call anything from the old `ai-services.js`, `ai-client-factory.js`, or `ai-client-utils.js` files.
Applied to files:
scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:06:57.833Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_services.mdc:0-0
Timestamp: 2025-07-18T17:06:57.833Z
Learning: Applies to scripts/modules/task-manager/*.js : Centralize all LLM calls through `generateTextService` or `generateObjectService`.
Applied to files:
scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:06:04.909Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_providers.mdc:0-0
Timestamp: 2025-07-18T17:06:04.909Z
Learning: Applies to src/ai-providers/*.js : Implement generate<ProviderName>Text, stream<ProviderName>Text, and generate<ProviderName>Object functions in provider modules with basic validation and try/catch error handling.
Applied to files:
scripts/modules/ai-services-unified.jssrc/ai-providers/index.jspackages/tm-core/src/common/constants/providers.ts
📚 Learning: 2025-07-18T17:12:57.903Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/new_features.mdc:0-0
Timestamp: 2025-07-18T17:12:57.903Z
Learning: Applies to scripts/modules/ai-services.js : Features that use AI models belong in 'scripts/modules/ai-services.js'.
Applied to files:
scripts/modules/ai-services-unified.jssrc/ai-providers/index.js
📚 Learning: 2025-07-18T17:14:54.131Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/telemetry.mdc:0-0
Timestamp: 2025-07-18T17:14:54.131Z
Learning: Applies to scripts/modules/commands.js : CLI command definitions in scripts/modules/commands.js must call the appropriate core logic function with outputFormat: 'text', and must not call displayAiUsageSummary directly if the core logic function already handles it.
Applied to files:
scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:14:54.131Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/telemetry.mdc:0-0
Timestamp: 2025-07-18T17:14:54.131Z
Learning: Applies to scripts/modules/task-manager/**/*.js : If the core logic function handles CLI output (outputFormat === 'text' or 'cli'), and aiServiceResponse.telemetryData is available, it must call displayAiUsageSummary(aiServiceResponse.telemetryData, 'cli') from scripts/modules/ui.js.
Applied to files:
scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:12:57.903Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/new_features.mdc:0-0
Timestamp: 2025-07-18T17:12:57.903Z
Learning: Applies to scripts/modules/*.js : Core functions should check outputFormat === 'text' before displaying UI elements and use internal logging that respects silent mode.
Applied to files:
scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:11:36.732Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/mcp.mdc:0-0
Timestamp: 2025-07-18T17:11:36.732Z
Learning: Applies to mcp-server/src/core/direct-functions/*.js : Do not wrap calls to the unified AI service (generateTextService, generateObjectService) in silent mode; their logging is handled internally.
Applied to files:
scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:14:54.131Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/telemetry.mdc:0-0
Timestamp: 2025-07-18T17:14:54.131Z
Learning: Applies to scripts/modules/task-manager/**/*.js : Functions in scripts/modules/task-manager/ that invoke AI services must call the appropriate AI service function (e.g., generateObjectService), passing commandName and outputType in the params object.
Applied to files:
scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:12:57.903Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/new_features.mdc:0-0
Timestamp: 2025-07-18T17:12:57.903Z
Learning: Applies to scripts/modules/commands.js : Use consistent patterns for option naming and help text in CLI commands.
Applied to files:
scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:06:57.833Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_services.mdc:0-0
Timestamp: 2025-07-18T17:06:57.833Z
Learning: Applies to scripts/modules/commands.js : Do not fetch AI-specific parameters (model ID, max tokens, temp) using `config-manager.js` getters for the AI call. Pass the `role` instead.
Applied to files:
scripts/modules/ai-services-unified.js
📚 Learning: 2025-10-12T11:06:36.374Z
Learnt from: rtmcrc
Repo: eyaltoledano/claude-task-master PR: 933
File: mcp-server/src/tools/agent-llm.js:1-3
Timestamp: 2025-10-12T11:06:36.374Z
Learning: The agent_llm MCP tool in mcp-server/src/tools/agent-llm.js is an exception to the standard MCP tool pattern. It should NOT use handleApiResult because it handles delegated LLM calls rather than direct API calls. Using createErrorResponse for error messages is the correct approach for this tool.
Applied to files:
scripts/modules/ai-services-unified.jsmcp-server/src/tools/scope-up.js
📚 Learning: 2025-07-18T17:06:04.909Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_providers.mdc:0-0
Timestamp: 2025-07-18T17:06:04.909Z
Learning: When assigning a model to a role using the MCP tool or CLI, do not include the provider: prefix in the model ID; use only the model ID itself.
Applied to files:
scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-21T02:41:13.453Z
Learnt from: rtmcrc
Repo: eyaltoledano/claude-task-master PR: 933
File: scripts/modules/task-manager/expand-all-tasks.js:0-0
Timestamp: 2025-07-21T02:41:13.453Z
Learning: In scripts/modules/task-manager/expand-all-tasks.js, the success flag should always be true when the expansion process completes successfully, even if individual tasks fail due to LLM errors. Failed tasks are designed to be expanded on subsequent iterations, so individual task failures don't constitute overall operation failure.
Applied to files:
scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-21T17:51:07.239Z
Learnt from: joedanz
Repo: eyaltoledano/claude-task-master PR: 748
File: scripts/modules/task-manager/parse-prd.js:726-733
Timestamp: 2025-07-21T17:51:07.239Z
Learning: In CLI contexts within task-manager modules like scripts/modules/task-manager/parse-prd.js, using process.exit(1) for validation failures and error conditions is correct and preferred over throwing errors, as it provides immediate termination with appropriate exit codes for scripting. The code should distinguish between MCP contexts (throw errors) and CLI contexts (use process.exit).
Applied to files:
scripts/modules/ai-services-unified.js
📚 Learning: 2025-10-11T22:32:11.922Z
Learnt from: rtmcrc
Repo: eyaltoledano/claude-task-master PR: 933
File: mcp-server/src/providers/agentllm-provider-tool-executor.js:289-329
Timestamp: 2025-10-11T22:32:11.922Z
Learning: In the Taskmaster codebase, when detecting agent-llm pending-interaction signals in tool results (agentllm-provider-tool-executor.js), the data is always stored in content[0], so there's no need to loop through all content items.
Applied to files:
scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:06:57.833Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_services.mdc:0-0
Timestamp: 2025-07-18T17:06:57.833Z
Learning: Applies to scripts/modules/task-manager/*.js : Determine the appropriate `role` (`main`, `research`, `fallback`) in your core logic and pass it to the service.
Applied to files:
scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:06:57.833Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_services.mdc:0-0
Timestamp: 2025-07-18T17:06:57.833Z
Learning: Applies to scripts/modules/task-manager/*.js : Do not implement fallback or retry logic outside `ai-services-unified.js`.
Applied to files:
scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:09:13.815Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/context_gathering.mdc:0-0
Timestamp: 2025-07-18T17:09:13.815Z
Learning: Commands such as `analyze-complexity`, `expand-task`, `update-task`, and `add-task` should consider adopting the context gathering pattern for improved AI-powered assistance.
Applied to files:
scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:06:57.833Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_services.mdc:0-0
Timestamp: 2025-07-18T17:06:57.833Z
Learning: Applies to scripts/modules/task-manager/*.js : Do not fetch AI-specific parameters (model ID, max tokens, temp) using `config-manager.js` getters for the AI call. Pass the `role` instead.
Applied to files:
scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:13:11.229Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/self_improve.mdc:0-0
Timestamp: 2025-07-18T17:13:11.229Z
Learning: Patterns should be consistently enforced
Applied to files:
scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:07:39.336Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/architecture.mdc:0-0
Timestamp: 2025-07-18T17:07:39.336Z
Learning: Applies to src/ai-providers/*.js : Provider-specific wrappers for Vercel AI SDK functions must be implemented in src/ai-providers/*.js, each file corresponding to a provider.
Applied to files:
scripts/modules/ai-services-unified.jssrc/ai-providers/index.jspackages/tm-core/src/common/constants/providers.ts
📚 Learning: 2025-07-18T17:06:04.909Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_providers.mdc:0-0
Timestamp: 2025-07-18T17:06:04.909Z
Learning: Applies to src/ai-providers/*.js : Provider modules must export three functions: generate<ProviderName>Text, stream<ProviderName>Text, and generate<ProviderName>Object.
Applied to files:
scripts/modules/ai-services-unified.jssrc/ai-providers/index.jspackages/tm-core/src/common/constants/providers.ts
📚 Learning: 2025-07-18T17:06:04.909Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_providers.mdc:0-0
Timestamp: 2025-07-18T17:06:04.909Z
Learning: Applies to tests/unit/ai-providers/*.test.js : Create unit tests for the new provider in tests/unit/ai-providers/<provider-name>.test.js, mocking ai-sdk/<provider-name> and core ai module functions, and testing all exported functions for correct behavior and error handling.
Applied to files:
scripts/modules/ai-services-unified.jssrc/ai-providers/index.jspackages/tm-core/src/common/constants/providers.ts
📚 Learning: 2025-09-29T13:33:46.952Z
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1246
File: src/ai-providers/claude-code.js:40-42
Timestamp: 2025-09-29T13:33:46.952Z
Learning: Claude Code provider should use environment variable isolation to control API key access, temporarily managing ANTHROPIC_API_KEY during client creation to prevent the ai-sdk-provider-claude-code package from automatically picking up API keys intended for other providers, while allowing explicit CLAUDE_CODE_API_KEY usage as a fallback to OAuth authentication.
Applied to files:
scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:06:04.909Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_providers.mdc:0-0
Timestamp: 2025-07-18T17:06:04.909Z
Learning: Applies to src/ai-providers/*.js : Create a new provider module file in src/ai-providers/ named <provider-name>.js when adding a new AI provider.
Applied to files:
scripts/modules/ai-services-unified.jssrc/ai-providers/index.jspackages/tm-core/src/common/constants/providers.ts
📚 Learning: 2025-09-29T13:33:46.952Z
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1246
File: src/ai-providers/claude-code.js:40-42
Timestamp: 2025-09-29T13:33:46.952Z
Learning: Claude Code provider should use CLAUDE_CODE_API_KEY environment variable instead of automatically picking up ANTHROPIC_API_KEY to avoid conflicts, since the ai-sdk-provider-claude-code package follows standard Anthropic patterns and prioritizes API keys over OAuth authentication, which can cause unexpected API charges.
Applied to files:
scripts/modules/ai-services-unified.js
📚 Learning: 2025-10-31T18:07:17.384Z
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1360
File: src/ai-providers/glm.js:0-0
Timestamp: 2025-10-31T18:07:17.384Z
Learning: In src/ai-providers/glm.js, the GLM provider's getClient method should allow defaulting to the 'coding' endpoint when an invalid or unspecified route parameter is provided, as this is the correct behavior per Z.ai's OpenAI-compatible API documentation. Do not enforce strict route validation that throws errors for unknown routes.
Applied to files:
scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:06:57.833Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_services.mdc:0-0
Timestamp: 2025-07-18T17:06:57.833Z
Learning: Applies to scripts/modules/commands.js : Determine the appropriate `role` (`main`, `research`, `fallback`) in your core logic and pass it to the service.
Applied to files:
scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:06:04.909Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_providers.mdc:0-0
Timestamp: 2025-07-18T17:06:04.909Z
Learning: Applies to scripts/modules/config-manager.js : Update scripts/modules/config-manager.js to add the new provider to MODEL_MAP, ensure it is included in VALID_PROVIDERS, and update API key handling logic.
Applied to files:
src/ai-providers/index.jsscripts/modules/supported-models.jsonpackages/tm-core/src/common/constants/providers.ts
📚 Learning: 2025-09-26T19:05:47.555Z
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1252
File: packages/ai-sdk-provider-grok-cli/package.json:11-13
Timestamp: 2025-09-26T19:05:47.555Z
Learning: In the eyaltoledano/claude-task-master repository, internal tm/ packages use a specific export pattern where the "exports" field points to TypeScript source files (./src/index.ts) while "main" points to compiled output (./dist/index.js) and "types" points to source files (./src/index.ts). This pattern is used consistently across internal packages like tm/core and tm/ai-sdk-provider-grok-cli because they are consumed directly during build-time bundling with tsdown rather than being published as separate packages.
Applied to files:
src/ai-providers/index.js
📚 Learning: 2025-07-18T17:14:54.131Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/telemetry.mdc:0-0
Timestamp: 2025-07-18T17:14:54.131Z
Learning: Applies to mcp-server/src/tools/**/*.js : MCP tool files in mcp-server/src/tools/ must call the corresponding direct function wrapper and pass the result to handleApiResult(result, log) from mcp-server/src/tools/utils.js, ensuring telemetryData is included in the final MCP response.
Applied to files:
mcp-server/src/tools/scope-up.js
📚 Learning: 2025-07-18T17:11:36.732Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/mcp.mdc:0-0
Timestamp: 2025-07-18T17:11:36.732Z
Learning: Applies to mcp-server/src/core/direct-functions/*.js : Check that all helper functions your direct function needs are properly exported from their source modules and import these dependencies explicitly at the top of your file in direct functions.
Applied to files:
mcp-server/src/tools/scope-up.js
📚 Learning: 2025-07-18T17:11:36.732Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/mcp.mdc:0-0
Timestamp: 2025-07-18T17:11:36.732Z
Learning: Applies to mcp-server/src/{tools,core/direct-functions}/*.js : Use helpers from mcp-server/src/tools/utils.js, mcp-server/src/core/utils/path-utils.js, and mcp-server/src/core/utils/ai-client-utils.js for centralized utilities.
Applied to files:
mcp-server/src/tools/scope-up.js
📚 Learning: 2025-07-18T17:12:57.903Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/new_features.mdc:0-0
Timestamp: 2025-07-18T17:12:57.903Z
Learning: Applies to mcp-server/src/core/direct-functions/*.js : Create direct function wrappers in 'mcp-server/src/core/direct-functions/' for MCP tool implementation, following silent mode patterns and using findTasksJsonPath for consistent path resolution.
Applied to files:
mcp-server/src/tools/scope-up.js
📚 Learning: 2025-07-18T17:11:36.732Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/mcp.mdc:0-0
Timestamp: 2025-07-18T17:11:36.732Z
Learning: Applies to mcp-server/src/tools/*.js : All MCP tool execute methods that require access to the project root MUST be wrapped with the withNormalizedProjectRoot Higher-Order Function (HOF) from mcp-server/src/tools/utils.js.
Applied to files:
mcp-server/src/tools/scope-up.js
📚 Learning: 2025-07-18T17:07:39.336Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/architecture.mdc:0-0
Timestamp: 2025-07-18T17:07:39.336Z
Learning: Applies to mcp-server/src/tools/*.js : MCP server tools in mcp-server/src/tools/*.js must have their execute methods wrapped with the withNormalizedProjectRoot higher-order function from tools/utils.js to ensure consistent path handling.
Applied to files:
mcp-server/src/tools/scope-up.js
📚 Learning: 2025-07-18T17:18:17.759Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/utilities.mdc:0-0
Timestamp: 2025-07-18T17:18:17.759Z
Learning: Applies to mcp-server/src/tools/utils.js : Use `normalizeProjectRoot(rawPath, log)`, `getRawProjectRootFromSession(session, log)`, and `withNormalizedProjectRoot(executeFn)` in `mcp-server/src/tools/utils.js` to ensure project root paths are normalized for MCP tools.
Applied to files:
mcp-server/src/tools/scope-up.js
📚 Learning: 2025-07-18T17:11:36.732Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/mcp.mdc:0-0
Timestamp: 2025-07-18T17:11:36.732Z
Learning: Applies to mcp-server/src/core/direct-functions/*.js : The *Direct function is responsible for finding the exact tasks.json path using findTasksJsonPath, relying on the projectRoot passed in args.
Applied to files:
mcp-server/src/tools/scope-up.js
📚 Learning: 2025-07-18T17:13:30.188Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/tags.mdc:0-0
Timestamp: 2025-07-18T17:13:30.188Z
Learning: Applies to scripts/modules/task-manager/* : All core functions in scripts/modules/task-manager/ must use readJSON(tasksPath, projectRoot, tag) and writeJSON(tasksPath, data, projectRoot, tag)
Applied to files:
mcp-server/src/tools/scope-up.js
📚 Learning: 2025-07-18T17:18:17.759Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/utilities.mdc:0-0
Timestamp: 2025-07-18T17:18:17.759Z
Learning: Applies to mcp-server/src/core/utils/path-utils.js : Call `findTasksJsonPath(args, log)` from within direct function wrappers in `mcp-server/src/core/direct-functions/` to get the absolute path to the relevant `tasks.json`.
Applied to files:
mcp-server/src/tools/scope-up.js
📚 Learning: 2025-07-18T17:14:54.131Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/telemetry.mdc:0-0
Timestamp: 2025-07-18T17:14:54.131Z
Learning: Applies to scripts/modules/task-manager/**/*.js : Core logic functions in scripts/modules/task-manager/ must return an object that includes aiServiceResponse.telemetryData.
Applied to files:
mcp-server/src/tools/scope-up.js
📚 Learning: 2025-07-18T17:13:30.188Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/tags.mdc:0-0
Timestamp: 2025-07-18T17:13:30.188Z
Learning: Applies to scripts/modules/* : All commands must find projectRoot with error handling before proceeding
Applied to files:
mcp-server/src/tools/scope-up.js
📚 Learning: 2025-07-18T05:38:17.352Z
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 943
File: scripts/modules/task-manager/move-task.js:24-24
Timestamp: 2025-07-18T05:38:17.352Z
Learning: In the Claude Task Master system, core task-manager functions are designed with fallback mechanisms for missing projectRoot parameters using the pattern `const projectRoot = providedProjectRoot || findProjectRoot();`. The readJSON and writeJSON functions have default parameters (projectRoot = null, tag = null) and handle missing parameters gracefully. Adding strict validation to these core functions would break the established flexible architecture pattern.
Applied to files:
mcp-server/src/tools/scope-up.js
📚 Learning: 2025-07-18T17:06:04.909Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_providers.mdc:0-0
Timestamp: 2025-07-18T17:06:04.909Z
Learning: Applies to scripts/modules/supported-models.json : Add a new key for the provider and an array of model objects under it in scripts/modules/supported-models.json, including id, name, allowed_roles, and optionally swe_score, cost_per_1m_tokens, and max_tokens.
Applied to files:
scripts/modules/supported-models.jsondocs/models.md
📚 Learning: 2025-07-21T14:14:48.694Z
Learnt from: rtmcrc
Repo: eyaltoledano/claude-task-master PR: 933
File: scripts/modules/supported-models.json:238-238
Timestamp: 2025-07-21T14:14:48.694Z
Learning: Model version updates in scripts/modules/supported-models.json may be included in feature PRs if they provide practical improvements like reduced error rates, even if not directly related to the main feature being implemented.
Applied to files:
scripts/modules/supported-models.jsondocs/models.md
📚 Learning: 2025-08-08T11:34:45.482Z
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1105
File: .changeset/vast-weeks-fetch.md:5-5
Timestamp: 2025-08-08T11:34:45.482Z
Learning: In this repo, supported-models.md is auto-generated by CI from supported-models.json; do not request manual edits to that file—ensure JSON entries are correct instead.
Applied to files:
scripts/modules/supported-models.jsondocs/models.md
📚 Learning: 2025-08-08T11:34:45.482Z
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1105
File: .changeset/vast-weeks-fetch.md:5-5
Timestamp: 2025-08-08T11:34:45.482Z
Learning: This repo’s supported models list is CI-generated into docs/models.md from scripts/modules/supported-models.json (workflow: .github/workflows/update-models-md.yml using docs/scripts/models-json-to-markdown.js). Don’t request manual edits to the Markdown; ensure the JSON is correct instead. README links to docs/models.md.
Applied to files:
scripts/modules/supported-models.jsondocs/models.md
📚 Learning: 2025-08-08T11:34:45.482Z
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1105
File: .changeset/vast-weeks-fetch.md:5-5
Timestamp: 2025-08-08T11:34:45.482Z
Learning: In this repo, the supported models list is auto-generated by CI into docs/models.md from scripts/modules/supported-models.json via .github/workflows/update-models-md.yml and docs/scripts/models-json-to-markdown.js. Don’t request manual edits to the Markdown; ensure the JSON is correct instead.
Applied to files:
scripts/modules/supported-models.jsondocs/models.md
📚 Learning: 2025-07-18T17:10:53.657Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/glossary.mdc:0-0
Timestamp: 2025-07-18T17:10:53.657Z
Learning: Guidelines for integrating new features into the Task Master CLI with tagged system considerations (new_features.mdc).
Applied to files:
scripts/modules/supported-models.json
📚 Learning: 2025-10-15T18:18:36.402Z
Learnt from: rtmcrc
Repo: eyaltoledano/claude-task-master PR: 933
File: assets/rules/agentllm.mdc:57-60
Timestamp: 2025-10-15T18:18:36.402Z
Learning: In agentllm delegation mode, the `expand_all` tool returns a list of `delegatedTaskIds` that are eligible for expansion, and the MCP client must then call `expand_task` individually for each returned task ID. This differs from normal mode where `expand_all` automatically submits all eligible tasks for expansion without requiring subsequent `expand_task` calls.
Applied to files:
scripts/modules/supported-models.json
📚 Learning: 2025-07-18T17:06:04.909Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_providers.mdc:0-0
Timestamp: 2025-07-18T17:06:04.909Z
Learning: Update relevant documentation files (such as README.md) to mention the new provider and its configuration.
Applied to files:
packages/tm-core/src/common/constants/providers.ts
📚 Learning: 2025-08-06T21:12:20.981Z
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1091
File: assets/claude/agents/task-executor.md:1-6
Timestamp: 2025-08-06T21:12:20.981Z
Learning: In the eyaltoledano/claude-task-master repository, agent files in assets/claude/agents/ are intended for distribution to users (for copying), while identical files in .claude/agents/ are for internal project use. This intentional duplication serves different purposes and is not a DRY violation.
Applied to files:
packages/tm-core/src/common/constants/providers.ts
📚 Learning: 2025-07-18T17:13:11.229Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/self_improve.mdc:0-0
Timestamp: 2025-07-18T17:13:11.229Z
Learning: Document breaking changes
Applied to files:
docs/models.md
📚 Learning: 2025-09-24T15:12:58.855Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: assets/AGENTS.md:0-0
Timestamp: 2025-09-24T15:12:58.855Z
Learning: Applies to assets/.taskmaster/config.json : Never manually edit .taskmaster/config.json; use task-master models to change AI model settings
Applied to files:
docs/models.md
📚 Learning: 2025-07-18T17:10:12.881Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/dev_workflow.mdc:0-0
Timestamp: 2025-07-18T17:10:12.881Z
Learning: Applies to .taskmaster/config.json : Do not manually edit `.taskmaster/config.json` unless you are certain of the changes; use the `task-master models` command or `models` MCP tool for configuration.
Applied to files:
docs/models.md
📚 Learning: 2025-09-24T15:12:58.855Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: assets/AGENTS.md:0-0
Timestamp: 2025-09-24T15:12:58.855Z
Learning: Applies to assets/.taskmaster/tasks/tasks.json : Never manually edit .taskmaster/tasks/tasks.json; use task-master commands to modify tasks
Applied to files:
docs/models.md
📚 Learning: 2025-07-31T22:08:16.039Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/taskmaster.mdc:0-0
Timestamp: 2025-07-31T22:08:16.039Z
Learning: Applies to {.taskmaster/tasks/tasks.json,.taskmaster/reports/task-complexity-report.json,.taskmaster/docs/research/**} : Do not manually edit generated files such as .taskmaster/tasks/tasks.json, .taskmaster/reports/task-complexity-report.json, or files in .taskmaster/docs/research/. Always use Taskmaster commands to modify these files.
Applied to files:
docs/models.md
🧬 Code graph analysis (2)
scripts/modules/ai-services-unified.js (5)
scripts/modules/config-manager.js (1)
providerName(718-718)scripts/modules/commands.js (1)
commandName(148-148)mcp-server/src/core/direct-functions/add-task.js (1)
tagInfo(146-146)mcp-server/src/tools/utils.js (1)
tagInfo(298-298)scripts/modules/task-manager/research.js (1)
tagInfo(315-315)
mcp-server/src/tools/scope-up.js (1)
mcp-server/src/core/direct-functions/scope-up.js (1)
result(82-97)
⏰ 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 (12)
mcp-server/src/tools/scope-up.js (4)
8-17: LGTM!Imports follow the established patterns and include the new
createAgentDelegationResponseutility needed for agent delegation support.
23-55: LGTM!Tool registration follows MCP conventions with snake_case naming, Zod parameter validation, and clear parameter descriptions.
56-92: LGTM!The execute function correctly uses
withNormalizedProjectRoot, logs execution start, resolves the tag context, finds the tasks path with proper error handling, and calls the direct function wrapper.
109-112: LGTM!Error handling is appropriate with proper logging and use of
createErrorResponsehelper.docs/models.md (1)
1-1: Do not manually edit this auto-generated file.This file is automatically generated by CI from
scripts/modules/supported-models.json. All changes should be made to the JSON source file instead, not directly to this Markdown file.Based on learnings
Also applies to: 39-39, 107-107, 153-153, 183-183, 246-246
scripts/modules/ai-services-unified.js (3)
40-40: LGTM!The AgentLLMProvider import and registration follow the established pattern for provider integration in this module.
Also applies to: 86-86
595-613: LGTM!The enhanced skip logic with inline documentation clearly explains the workaround for agentllm in non-MCP contexts. The addition of the explanatory comment addresses maintainability concerns.
705-728: LGTM!The delegation handling includes proper type validation, conditional debug logging, and returns a consistent structure with
tagInfo. The implementation correctly propagates the delegation signal for MCP tool processing.src/ai-providers/index.js (1)
18-18: LGTM!The AgentLLMProvider export follows the established pattern for provider exports in this central index file.
packages/tm-core/src/common/constants/providers.ts (1)
33-33: LGTM!The AGENTLLM provider constant addition follows the established naming convention and pattern for custom providers.
scripts/modules/supported-models.json (2)
381-381: LGTM!The Gemini model version update to the May 20 preview provides practical error-reduction improvements as previously discussed.
Based on learnings
1199-1215: LGTM!The agentllm provider entry is well-structured with comprehensive metadata:
- Properly explains the delegation mechanism in
descriptionandnotesfields- Correctly sets
cost_per_1m_tokensto 0 (agent-determined costs)- Uses
nullforcontext_windowandmax_tokens(agent-determined capabilities)- Includes all three roles in
allowed_rolesfor maximum flexibility- Extended metadata fields (
supports_tools,supports_image_input) appropriately indicate agent-determined capabilitiesThe structure follows the required pattern and provides clear guidance for users about delegation behavior.
As per coding guidelines
|
Ok guys, i've made the corrections and resolved the conflicts and it is functional just like it was functional from the day this pr was created. |
|
Hey @rtmcrc I've been seeing your efforts, and I'm impressed, let me give this a test, maybe we include it as part of next release. Thanks a ton! I've already created a branch locally for it, and will be testing it tomorrow. GGs! |
| } | ||
|
|
||
| // If both title+description are provided and AgentLLM is not preferred, take manual path as before. | ||
| const finalIsManualCreation = !isAgentLLMPreferred && isManualCreation; |
There was a problem hiding this comment.
Bug: Unwanted AI-Driven Creation Overrides Manual Task Intent
Silent behavior change when AgentLLM is configured: When a user calls add-task with title and description (intending manual task creation without AI), the code now synthesizes a prompt and forces AI-driven creation if AgentLLM is detected as the provider. This changes the intended behavior from manual to AI-driven creation without user consent. Lines 100-112 synthesize a prompt from title/description when AgentLLM is preferred, and line 115 sets finalIsManualCreation = false, overriding the user's explicit choice to create a task manually. This violates the principle of least surprise - users explicitly providing title/description without a prompt expect manual creation, not AI generation. The correct behavior would be to respect the user's original intent (manual vs AI-driven) regardless of which LLM provider is configured.
There was a problem hiding this comment.
This may be discarded during the review. From my personal experience i was surprised that when i was making a add task requests i every time expected that when agentllm is set as a provider a prompt is generated but as it turned out llms were going manual path by default without even my realization. This workaround was made specially to agentllm only because when a user asks to add a task an llm may create a basic task filling those fields manually, but if a system prompt is passed in the response of add_task tool the result of a users request is going to be better.
This workaround maybe discarded and a rule created in agentllm.mdc for add_task tool to take AI driven path by default.
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (6)
mcp-server/src/tools/add-task.js (1)
94-94: Fix typo in comment.The comment contains a typo: "functionP" should be "function".
Apply this diff to fix the typo:
- // Call the direct functionP + // Call the direct functionscripts/modules/utils.js (1)
760-769: Fix metadata merge: don’t spread metadata fields into tag rootCurrent merge flattens tag.metadata into root and may drop/duplicate fields (“updated” stays at root). Preserve tag object and overwrite only tasks (and metadata if provided).
- finalData = { - ...rawFullData, - [resolvedTag]: { - // Preserve existing tag metadata if it exists, otherwise use what's passed - ...(rawFullData[resolvedTag]?.metadata || {}), - ...(data.metadata ? { metadata: data.metadata } : {}), - tasks: data.tasks - } - }; + const existingTag = rawFullData[resolvedTag] || {}; + finalData = { + ...rawFullData, + [resolvedTag]: { + ...existingTag, + tasks: data.tasks, + ...(data.metadata ? { metadata: data.metadata } : {}) + } + };scripts/modules/task-manager/generate-task-files.js (1)
67-75: Default tag handling: compute targetTag once and reuse safeTagIf options.tag is undefined,
tagData = rawData[tag]is undefined. DerivetargetTag = tag || resolvedData.tag || 'master'and reusesafeTag = slugifyTagForFilePath(targetTag)across logs/regex/filenames.- const tagData = rawData[tag]; + const targetTag = tag || resolvedData.tag || 'master'; + const tagData = rawData[targetTag]; @@ - `Preparing to regenerate ${tasksForGeneration.length} task files for tag '${slugifyTagForFilePath(tag)}'` + `Preparing to regenerate ${tasksForGeneration.length} task files for tag '${slugifyTagForFilePath(targetTag)}'` @@ - `Checking for orphaned task files to clean up for tag '${slugifyTagForFilePath(tag)}'...` + `Checking for orphaned task files to clean up for tag '${slugifyTagForFilePath(targetTag)}'...` @@ - const taggedFilePattern = new RegExp( - `^task_(\\d+)_${slugifyTagForFilePath(tag)}\\.txt$` - ); + const taggedFilePattern = new RegExp( + `^task_(\\d+)_${slugifyTagForFilePath(targetTag)}\\.txt$` + ); @@ - `Found ${orphanedFiles.length} orphaned task files to remove for tag '${slugifyTagForFilePath(tag)}'` + `Found ${orphanedFiles.length} orphaned task files to remove for tag '${slugifyTagForFilePath(targetTag)}'` @@ - `Generating individual task files for tag '${slugifyTagForFilePath(tag)}'...` + `Generating individual task files for tag '${slugifyTagForFilePath(targetTag)}'...` @@ - tag === 'master' + targetTag === 'master' @@ - : `task_${task.id.toString().padStart(3, '0')}_${slugifyTagForFilePath(tag)}.txt`; + : `task_${task.id.toString().padStart(3, '0')}_${slugifyTagForFilePath(targetTag)}.txt`; @@ - `All ${tasksForGeneration.length} tasks for tag '${slugifyTagForFilePath(tag)}' have been generated into '${outputDir}'.` + `All ${tasksForGeneration.length} tasks for tag '${slugifyTagForFilePath(targetTag)}' have been generated into '${outputDir}'.`Also applies to: 80-84, 97-103, 107-109, 156-160, 164-167, 224-228
scripts/modules/dependency-manager.js (2)
62-70: Make the initial validation tag-aware (don’t check rootdata.tasks).The check can fail for tagged data. Validate the tag-scoped array instead and include the tag in the error.
Based on learnings
- const data = readJSON(tasksPath, context.projectRoot, context.tag); - if (!data || !data.tasks) { - log('error', 'No valid tasks found in tasks.json'); - process.exit(1); - } - - const tag = context.tag || 'master'; - const tasks = getTasksForTag(data, tag); + const data = readJSON(tasksPath, context.projectRoot, context.tag); + const tag = context.tag || 'master'; + const tasks = getTasksForTag(data, tag); + if (!data || !Array.isArray(tasks)) { + log('error', `No valid tasks found for tag '${tag}' in tasks.json`); + process.exit(1); + }
1334-1338: Fix logger wiring for traverseDependencies (current code falls back to console.warn).
logis a function, solog.warnis undefined. Pass a wrapper.- return traverseDependencies(sourceTasks, allTasks, { - ...options, - direction: 'forward', - logger: { warn: log.warn || console.warn } - }); + return traverseDependencies(sourceTasks, allTasks, { + ...options, + direction: 'forward', + logger: { warn: (...args) => log('warn', ...args) } + });Apply the same wrapper in other calls (e.g., reverse traversal).
Also applies to: 1538-1542
mcp-server/src/tools/research.js (1)
55-66: Restore backward compatibility forsaveToRenaming the public parameter to
saveToTaskwithout keepingsaveToin the schema will reject every existing MCP client that still sends the old field—the Zod validator fails before the fallbackargs.saveToever runs. Please accept both keys (mark the legacy one deprecated in docs if needed) so previously working clients don’t break.saveToTask: z .string() .optional() .describe( 'Automatically save research results to specified task/subtask ID (e.g., "15" or "15.2")' ), + // Back-compat: accept legacy saveTo until all clients migrate. + saveTo: z + .string() + .optional() + .describe( + '(Deprecated) Legacy alias for saveToTask; kept for backward compatibility.' + ),As per coding guidelines
♻️ Duplicate comments (2)
tests/unit/mcp-server/src/tools/agent_llm.tool.test.js (1)
292-299: Don’t spy on a literal{ execute }object; remove or rewrite schema testsThis spy pattern doesn’t track the real function and was flagged earlier; schema validation happens before execute.
- const executeSpy = jest.spyOn({ execute }, 'execute'); - try { - await execute(args, { log: mockLog, session: mockSession }); - } catch (e) {} - expect(executeSpy).not.toHaveBeenCalled(); + // Schema validation is handled by the MCP framework pre-execute. + // Placeholder to document expected rejection. + expect(true).toBe(true);Also applies to: 310-317
mcp-server/src/core/direct-functions/research.js (1)
68-288: Switch to the shared error codesThe direct-function rules still require the canonical codes (
INPUT_VALIDATION_ERROR,CORE_FUNCTION_ERROR,FILE_NOT_FOUND_ERROR,UNEXPECTED_ERROR). This file continues to emit custom strings (MISSING_PARAMETER,INVALID_PARAMETER,INVALID_CORE_RESPONSE,RESEARCH_ERROR), so callers can’t rely on the standardized contract. Please map each branch to the shared constants (and do the same for the catch block).- error: { - code: 'MISSING_PARAMETER', + error: { + code: 'INPUT_VALIDATION_ERROR', message: 'The query parameter is required and must be a non-empty string' } ... - error: { - code: 'INVALID_PARAMETER', + error: { + code: 'INPUT_VALIDATION_ERROR', message: `Detail level must be one of: ${validDetailLevels.join(', ')}` } ... - error: { - code: 'INVALID_CORE_RESPONSE', + error: { + code: 'CORE_FUNCTION_ERROR', message: 'Core research function returned invalid data.' } ... - error: { - code: error.code || 'RESEARCH_ERROR', + error: { + code: + error.code === 'INPUT_VALIDATION_ERROR' || + error.code === 'FILE_NOT_FOUND_ERROR' || + error.code === 'CORE_FUNCTION_ERROR' + ? error.code + : 'UNEXPECTED_ERROR', message: error.message }As per coding guidelines
🧹 Nitpick comments (4)
tests/unit/scripts/modules/task-manager/generate-task-files.test.js (1)
49-52: Align slugifyTagForFilePath mock with prod behavior to avoid test driftMirror prod: trim leading/trailing dashes, collapse repeats, cap length, default 'unknown-tag'.
- slugifyTagForFilePath: jest.fn((tag) => - tag ? tag.replace(/[^a-zA-Z0-9_-]/g, '-').toLowerCase() : 'master' - ) + slugifyTagForFilePath: jest.fn((tag) => { + if (!tag || typeof tag !== 'string') return 'unknown-tag'; + return tag + .replace(/[^a-zA-Z0-9_-]/g, '-') + .replace(/^-+|-+$/g, '') + .replace(/-+/g, '-') + .toLowerCase() + .substring(0, 50); + })tests/unit/mcp-server/src/tools/agent_llm.tool.test.js (1)
270-281: Avoid asserting exact error strings; assert general propertiesPer testing guidelines, prefer shape over exact text.
- expect(utilsModule.createErrorResponse).toHaveBeenCalledWith( - "Invalid parameters for agent_llm tool: Must provide either 'delegatedCallDetails' or 'agentLLMResponse'.", - { mcpToolError: true } - ); - expect(result.isError).toBe(true); - expect(result.errorDetails).toContain( - 'Invalid parameters for agent_llm tool' - ); + expect(utilsModule.createErrorResponse).toHaveBeenCalled(); + expect(result.isError).toBe(true); + expect(result.mcpToolError).toBe(true);As per coding guidelines
mcp-server/src/core/utils/agentllm-update-tool-saver.js (1)
10-43: Optional: normalize logger methods to no-ops for cleaner debug usageAvoid guarded calls by binding fallbacks once.
- if (typeof agentOutput === 'string') { + if (typeof agentOutput === 'string') { + const dbg = + logWrapper && typeof logWrapper.debug === 'function' + ? logWrapper.debug.bind(logWrapper) + : () => {}; @@ - logWrapper.debug && - logWrapper.debug(`${this.toolName}: Direct JSON.parse failed: ${e.message}`); + dbg(`${this.toolName}: Direct JSON.parse failed: ${e.message}`); @@ - logWrapper.debug && - logWrapper.debug(`${this.toolName}: Substring array parse failed: ${e.message}`); + dbg(`${this.toolName}: Substring array parse failed: ${e.message}`); @@ - logWrapper.debug && - logWrapper.debug(`${this.toolName}: Substring object parse failed: ${e.message}`); + dbg(`${this.toolName}: Substring object parse failed: ${e.message}`);Also applies to: 55-61, 75-83
mcp-server/src/providers/agentllm-provider-tool-executor.js (1)
22-25: Use computedtagfor default tagInfo to avoid mismatches.If agent didn’t return tagInfo, prefer the computed tag instead of hardcoding 'master'.
- return { + return { mainResult: mainResultMessage, telemetryData: null, - tagInfo: llmRequestForAgent?.requestParameters?.tagInfo || { - currentTag: 'master', - availableTags: ['master'] - } + tagInfo: + llmRequestForAgent?.requestParameters?.tagInfo || { + currentTag: tag, + availableTags: [tag] + } }Also applies to: 333-341
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
scripts/modules/dependency-manager.js (1)
62-66: Validate tasks array from getTasksForTag, not data.tasks directly.The check
!data || !data.tasksat line 63 assumes legacy format and doesn't work with tagged data structure. Line 69 correctly usesgetTasksForTag, but the validation should check the returnedtasksarray instead.Apply this fix:
const data = readJSON(tasksPath, context.projectRoot, context.tag); - if (!data || !data.tasks) { - log('error', 'No valid tasks found in tasks.json'); - process.exit(1); - } - const tag = context.tag || 'master'; const tasks = getTasksForTag(data, tag); + if (!data || !Array.isArray(tasks) || tasks.length === 0) { + log('error', 'No valid tasks found in tasks.json'); + process.exit(1); + }This pattern aligns with how
fixDependenciesCommandvalidates at lines 744-746.Also applies to: 254-260
♻️ Duplicate comments (1)
tests/unit/mcp-server/src/tools/agent_llm.tool.test.js (1)
278-313: Schema validation tests need revision or removal.These tests create spies on object literals which doesn't properly track the execute function. Since validation occurs in the MCP framework before execute is called, these tests don't meaningfully verify behavior in this isolated environment.
Consider either:
- Removing these tests with a comment explaining validation is handled by the MCP framework
- Rewriting to actually test validation behavior if that's possible
🧹 Nitpick comments (3)
mcp-server/src/providers/agentllm-provider-tool-executor.js (1)
13-341: Post-processing handles diverse tool outputs.The function properly:
- Resolves tags with
getCurrentTagfallback and guard against undefinedprojectRoot(line 24)- Routes to appropriate savers with normalized inputs
- Handles special cases like research text extraction (lines 211-236) and saveTo sanitization (lines 243-256)
- Validates IDs for scope tools (lines 282-286, 308-312)
The if-else chain is verbose but each branch has distinct normalization needs. Extracting to a handler map would require significant refactoring and may not improve clarity given the heterogeneous requirements.
Optional: Consider handler map for maintainability.
If this function grows further, extracting tool-specific logic into a handler mapping could improve maintainability:
const toolHandlers = { parse_prd: async (params) => { /* ... */ }, expand_task: async (params) => { /* ... */ }, // ... };This is optional as the current structure is functional and each branch has unique logic.
scripts/modules/task-manager/research.js (1)
278-327: Consider debug level for verbose logging in production.Lines 278-327 use
infolevel for detailed type checks, object inspection, and content previews. While valuable during development, this verbosity may clutter production logs.Optionally adjust log levels for detail-heavy messages:
- logFn.info(`performResearch: generateTextService call completed.`); - logFn.info(`performResearch: aiResult raw: ${JSON.stringify(aiResult)}`); + logFn.debug(`performResearch: generateTextService call completed.`); + logFn.debug(`performResearch: aiResult raw: ${JSON.stringify(aiResult)}`);Apply similar changes to lines 281-299, 317-327 to reduce production log volume while preserving debug capability.
tests/unit/dependency-manager.test.js (1)
1037-1040: Consider removing unusedtagproperty for clarity.The mock returns
{ tasks: [...], tag: 'master' }, but thetagproperty at the root level doesn't appear to be used bygetTasksForTagor other code. The mock works correctly becausegetTasksForTagchecksdata.tasksfirst, but including the unused property may cause confusion.Apply this diff to simplify the mock:
-mockReadJSON.mockImplementation(() => ({ - tasks: structuredClone(crossLevelDependencyTasks.tasks), - tag: 'master' -})); +mockReadJSON.mockImplementation(() => ({ + tasks: structuredClone(crossLevelDependencyTasks.tasks) +}));
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
scripts/modules/task-manager/research.js (1)
149-176: Preserve subtask identifiers when displaying sorted task IDs.Sorting via
parseIntstrips everything after the dot (parseInt('15.2') === 15), so subtask IDs are shown as their parent task. Users will see “15” even if the match was “15.2”, which is misleading when they try to act on the referenced subtask.Switch to a numeric-aware string compare so the full ID survives:
- const sortedTaskIds = finalTaskIds - .map((id) => parseInt(id)) - .sort((a, b) => a - b) - .map((id) => id.toString()); + const sortedTaskIds = finalTaskIds + .map((id) => id.toString()) + .sort((a, b) => a.localeCompare(b, undefined, { numeric: true })); @@ - const sortedProvidedIds = taskIds - .map((id) => parseInt(id)) - .sort((a, b) => a - b) - .map((id) => id.toString()); + const sortedProvidedIds = taskIds + .map((id) => id.toString()) + .sort((a, b) => a.localeCompare(b, undefined, { numeric: true })); @@ - const sortedAutoIds = uniqueAutoDiscovered - .map((id) => parseInt(id)) - .sort((a, b) => a - b) - .map((id) => id.toString()); + const sortedAutoIds = uniqueAutoDiscovered + .map((id) => id.toString()) + .sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));
♻️ Duplicate comments (1)
tests/unit/mcp-server/src/tools/agent_llm.tool.test.js (1)
280-322: Schema validation tests are correctly implemented.Contrary to the past review comment, these tests appropriately use
safeParseto directly test the Zod schema validation. Since schema validation occurs in the MCP framework beforeexecuteis invoked, testing the schema itself (rather than trying to spy on execute) is the correct unit testing approach. These tests effectively document expected validation behavior.
🧹 Nitpick comments (1)
tests/unit/mcp-server/src/tools/agent_llm.tool.test.js (1)
82-322: Consider adding test coverage for the optional tag parameter.The current tests provide strong coverage of core delegation flows. As an optional enhancement, consider adding a test that includes the
tagparameter to verify it's properly handled in both Taskmaster-to-Agent and Agent-to-Taskmaster flows, ensuring the multi-context routing feature is testable.
…deduplication. research: correct numerical sorting of task IDs
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (2)
tests/unit/dependency-manager.test.js (2)
20-53: Consider addinggetTasksForTagandsetTasksForTagto the global mock setup.The cross-level dependency test suite (lines 1010–1021) mocks
getTasksForTagandsetTasksForTag, but these are absent from the global mock setup. If the module under test or other test suites invoke these utilities, they will encounter undefined function errors. For consistency and to prevent fragile test ordering, export these mocks at the top level alongside the other utility mocks.Apply this diff to add the missing mocks to the global setup:
isEmpty: jest.fn((v) => v == null ? true : Array.isArray(v) ? v.length === 0 : typeof v === 'object' ? Object.keys(v).length === 0 : false ), // Common extras enableSilentMode: jest.fn(), disableSilentMode: jest.fn(), getTaskManager: jest.fn(async () => ({})), getTagAwareFilePath: jest.fn((basePath, _tag, projectRoot = '.') => basePath), readComplexityReport: jest.fn(() => null), createLogger: jest.fn(() => ({ debug: jest.fn(), error: jest.fn(), info: jest.fn(), success: jest.fn(), warn: jest.fn() - })) + })), + getTasksForTag: jest.fn((data, tag) => { + if (data.tasks && Array.isArray(data.tasks)) { + return data.tasks; + } + return data[tag]?.tasks || []; + }), + setTasksForTag: jest.fn((data, tag, tasks) => { + if (!data[tag]) data[tag] = {}; + data[tag].tasks = tasks; + }) }));
1034-1036: Data structure inconsistency between test suites may cause confusion.The cross-level dependency tests use a flat
{ tasks: [...] }structure (line 1034), while other tests in this file use the tagged{ master: { tasks: [...] } }structure (e.g., lines 651–669). ThegetTasksForTagmock (lines 1010–1017) bridges both formats with fallback logic, but this dual-mode approach can make it harder to reason about test behavior and could mask issues where code incorrectly assumes one structure or the other.Consider standardizing all tests to use the tagged structure for consistency, or document why the cross-level tests require the flat structure.
Also applies to: 1010-1017
…sertion - Add mocks for getTasksForTag and setTasksForTag functions - Update test to include independent subtask and correct assertion for deduplicated dependencies - Format research.js sort function for readability
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (1)
scripts/modules/task-manager/research.js (1)
277-299: Verbose logging persists at info level.The detailed logging of AI result types and content previews remains at info level, which can be too verbose for production. This was flagged in a previous review.
Consider changing these detailed log statements from
logFn.infotologFn.debug:- logFn.debug(`performResearch: generateTextService call completed.`); - logFn.debug(`performResearch: aiResult raw: ${JSON.stringify(aiResult)}`); + logFn.debug(`performResearch: generateTextService call completed.`); + logFn.debug(`performResearch: aiResult raw: ${JSON.stringify(aiResult)}`);The
logFn.debugcalls are already at debug level, but consider whether the content preview logging (lines 290-293) should also be at debug level for production.
🧹 Nitpick comments (2)
tests/unit/dependency-manager.test.js (1)
1013-1032: Consider extracting duplicate mock setup to reduce maintenance burden.The mock factory functions (
createLogger,getTasksForTag,setTasksForTag) are duplicated between the top-leveljest.mock()(lines 46-62) and thisbeforeEachblock. Extract them to a shared factory:+// Shared mock factory +const createUtilsMockFactory = () => ({ + createLogger: jest.fn(() => ({ + debug: jest.fn(), + error: jest.fn(), + info: jest.fn(), + success: jest.fn(), + warn: jest.fn() + })), + getTasksForTag: jest.fn((data, tag) => { + if (data.tasks && Array.isArray(data.tasks)) { + return data.tasks; + } + return data[tag]?.tasks || []; + }), + setTasksForTag: jest.fn((data, tag, tasks) => { + if (!data[tag]) data[tag] = {}; + data[tag].tasks = tasks; + }), + readComplexityReport: jest.fn(() => null) +}); jest.mock('../../scripts/modules/utils.js', () => ({ log: mockLog, ... - createLogger: jest.fn(() => ({ ... })), - getTasksForTag: jest.fn(...), + ...createUtilsMockFactory() }));Then reuse in the
unstable_mockModulecall.scripts/modules/task-manager/research.js (1)
1101-1101: Optional: Remove unused timestamp variable.The
timestampvariable is defined but not used in the output string (line 1102 inline constructs the timestamp again).Consider removing the unused variable:
- // const timestamp = new Date().toISOString(); // Not currently used in output string let formatted = `## Research Session - ${new Date().toLocaleDateString()} ${new Date().toLocaleTimeString()}\n\n`;
There was a problem hiding this comment.
This PR is being reviewed by Cursor Bugbot
Details
Your team is on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle for each member of your team.
To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.
| // Indicates successful non-delegated expansion | ||
| const subtasksAdded = coreResult.task.subtasks | ||
| ? coreResult.task.subtasks.length - subtasksCountBefore | ||
| : 0 - subtasksCountBefore; // If subtasks became undefined (unlikely) |
There was a problem hiding this comment.
Bug: Arithmetic Error: Negative Instead of Zero
Incorrect arithmetic calculation: when coreResult.task.subtasks is falsy, subtasksAdded is set to 0 - subtasksCountBefore. This produces a negative number instead of 0. For example, if subtasksCountBefore is 2 and subtasks become undefined, the result is -2, which is semantically incorrect for counting added subtasks. It should be 0.
|
@rtmcrc I'm handling the conflicts, don't worry about it |
|
This was an ambitious contribution, delegating LLM calls via MCP is a cool concept. The codebase has changed dramatically since this was opened (92 files touched tells the story), and it would need a ground-up rewrite to align with the current architecture. Going to close this, but the idea has merit. If you're still interested, we'd be happy to discuss the approach in an issue before you invest time in a new PR. Thanks for the effort! |
Add AgentLLM Provider for Delegated AI Operations
📋 Overview
This PR introduces new AgentLLM Provider, a new delegation system that allows Taskmaster to offload Large Language Model (LLM) calls to connected agents through the MCP (Model Context Protocol) interface. Instead of making direct API calls to LLM providers, Taskmaster can now delegate AI operations to MCP clients that manage their own LLM infrastructure and credentials.
🚀 Key Features
Agent-Delegated LLM Calls
parse_prd,analyze_project_complexity,expand_task,expand_all,update,update_task,update_subtask,add_task,research) tools can now delegate LLM calls to MCP clients.MCP Tool Integration
Flexible Architecture
🔧 Technical Implementation
Core Components
1. AgentLLMProvider Class
2. Enhanced MCP Server Logic
3. Agent Communication Protocol
Workflow Overview
📖 Usage Examples
Configuration
Agent Response Handling
javascript// Success response
// Error response
🎯 Benefits
For Users
For Developers
🧪 Testing
📚 Documentation
assets/rules/agent_llm.mdcfor the agent_llm MCP tool. (Note: These rules are crucial for MCP clients to understand the correct workflow.) Once a Taskmaster is initialized rules has to be added with a rule tool for the desired client, or they maybe added manually to a client that is not in the list).🔄 Backward Compatibility
🎉 Impact
This feature significantly expands Taskmaster's deployment flexibility, allowing it to work in environments where:
Direct LLM API access is restricted
Custom LLM infrastructure is preferred
Local or specialized models in MCP context need to be integrated
Summary by CodeRabbit
Note
Introduces AgentLLM provider and agent_llm MCP tool to delegate LLM calls, with end-to-end pending-interaction handling and post-processing across core tools.
AgentLLMProviderand integrate into provider registry; treat as no-API-key provider.AgentLLMProviderToolExecutor, pending-interaction tracking, and resume-on-response.agent_llmtool (Taskmaster→Agent request, Agent→Taskmaster response) and tooling updates to auto-propagate delegation viacreateAgentDelegationResponse.expand_allnow returnsdelegatedTaskIds).add-task: synthesize prompt when AgentLLM is preferred; support provider checks.research: normalizesaveTo, improved validation, optional auto-save to task/subtask/file.in-progress.createLogger; hardenwriteJSONfor tagged data; tag-aware task file generation and dependency manager uses tag getters/setters.agentllmin config;ai-services-unifiedsurfaces delegation signals.apps/docs/archive/agent-llm-workflow.mdxandassets/rules/agentllm.mdc.agentllm/agent-delegated-model; Gemini ID refresh).Written by Cursor Bugbot for commit c034605. This will update automatically on new commits. Configure here.