Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions src/core/assistant-message/presentAssistantMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ import { askFollowupQuestionTool } from "../tools/askFollowupQuestionTool"
import { switchModeTool } from "../tools/switchModeTool"
import { attemptCompletionTool } from "../tools/attemptCompletionTool"
import { newTaskTool } from "../tools/newTaskTool"
import { dispatchTaskTool } from "../tools/dispatchTaskTool"
import { getTaskStatusTool } from "../tools/getTaskStatusTool"
import { consolidateResultsTool } from "../tools/consolidateResultsTool"
import { cancelTaskTool } from "../tools/cancelTaskTool"
import { releaseTasksTool } from "../tools/releaseTasksTool"
import { resumeParentTaskTool } from "../tools/resumeParentTaskTool"
import { startConversationTool } from "../tools/startConversationTool" // Added startConversationTool

import { checkpointSave } from "../checkpoints"

Expand Down Expand Up @@ -211,6 +218,24 @@ export async function presentAssistantMessage(cline: Task) {
const modeName = getModeBySlug(mode, customModes)?.name ?? mode
return `[${block.name} in ${modeName} mode: '${message}']`
}
case "dispatch_task": { // Added for dispatch_task
const mode = block.params.mode ?? defaultModeSlug
const message = block.params.message ?? "(no message)"
const modeName = getModeBySlug(mode, customModes)?.name ?? mode
return `[${block.name} in ${modeName} mode: '${message}']`
}
case "get_task_status":
return `[${block.name} for '${block.params.task_instance_ids}']`
case "consolidate_results":
return `[${block.name} for '${block.params.task_instance_ids}']`
case "cancel_task":
return `[${block.name} for task '${block.params.task_instance_id}']`
case "release_tasks":
return `[${block.name} for tasks '${block.params.task_instance_ids}']`
case "resume_parent_task":
return `[${block.name} for parent '${block.params.original_parent_id}']`
case "start_conversation": // Added for start_conversation
return `[${block.name} with initial prompt: '${block.params.initial_prompt}']`
}
}

Expand Down Expand Up @@ -504,6 +529,27 @@ export async function presentAssistantMessage(cline: Task) {
case "new_task":
await newTaskTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
break
case "dispatch_task":
await dispatchTaskTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag, toolDescription)
break
case "get_task_status":
await getTaskStatusTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
break
case "consolidate_results":
await consolidateResultsTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
break
case "cancel_task":
await cancelTaskTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
break
case "release_tasks":
await releaseTasksTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
break
case "resume_parent_task":
await resumeParentTaskTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
break
case "start_conversation": // Added for start_conversation
await startConversationTool(cline, block, askApproval, handleError, pushToolResult, removeClosingTag)
break
case "attempt_completion":
await attemptCompletionTool(
cline,
Expand Down
15 changes: 15 additions & 0 deletions src/core/prompts/tools/cancelTask.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { ToolDefinition } from "./types"

export const cancelTaskToolDefinition: ToolDefinition = {
name: "cancel_task",
description:
"Requests the cancellation of an actively running sub-task previously dispatched by `dispatch_task`. The target task will be moved to an 'aborted' state. This does not immediately remove the task record; use `release_tasks` for cleanup after confirming cancellation if needed.",
parameters: [
{
name: "task_instance_id",
description: "The instance ID of the task to be cancelled.",
type: "string",
required: true,
},
],
}
16 changes: 16 additions & 0 deletions src/core/prompts/tools/consolidateResults.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { ToolDefinition } from "./types"

export const consolidateResultsToolDefinition: ToolDefinition = {
name: "consolidate_results",
description:
"Waits for one or more dispatched sub-tasks (identified by their instance IDs) to complete, fail, or be aborted. This is a blocking tool; the current task will pause until all specified sub-tasks have terminated. It then returns an aggregated list of their final statuses and results. After using this, consider calling `release_tasks` to clean up terminated task records.",
parameters: [
{
name: "task_instance_ids",
description:
"A comma-separated string of task instance IDs whose results are to be consolidated (e.g., 'id1,id2,id3').",
type: "string",
required: true,
},
],
}
22 changes: 22 additions & 0 deletions src/core/prompts/tools/dispatchTask.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { ToolDefinition } from "./types"

export const dispatchTaskToolDefinition: ToolDefinition = {
name: "dispatch_task",
description:
"Dispatches a new sub-task to be executed in parallel. This tool is non-blocking; the current task will continue to execute immediately after dispatching the sub-task. The sub-task will run independently. Use `get_task_status` to check its progress and `consolidate_results` to retrieve its output once completed.",
parameters: [
{
name: "mode",
description:
"The mode (persona or capability set) in which the new sub-task should operate (e.g., 'code', 'debug', 'architect', or a custom mode slug).",
type: "string",
required: true,
},
{
name: "message",
description: "The initial message or instruction for the new sub-task.",
type: "string",
required: true,
},
],
}
16 changes: 16 additions & 0 deletions src/core/prompts/tools/getTaskStatus.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { ToolDefinition } from "./types"

export const getTaskStatusToolDefinition: ToolDefinition = {
name: "get_task_status",
description:
"Checks the current status of one or more actively running sub-tasks that were previously dispatched using `dispatch_task`. Tasks are identified by their instance IDs. If a task ID is not found among active tasks, its status will be reported as 'unknown'. To get final results of completed/failed tasks, use `consolidate_results`.",
parameters: [
{
name: "task_instance_ids",
description:
"A comma-separated string of task instance IDs for which to retrieve the status (e.g., 'id1,id2,id3').",
type: "string",
required: true,
},
],
}
126 changes: 126 additions & 0 deletions src/core/prompts/tools/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,128 @@ import { getUseMcpToolDescription } from "./use-mcp-tool"
import { getAccessMcpResourceDescription } from "./access-mcp-resource"
import { getSwitchModeDescription } from "./switch-mode"
import { getNewTaskDescription } from "./new-task"
import { dispatchTaskToolDefinition } from "./dispatchTask"
import { getTaskStatusToolDefinition } from "./getTaskStatus"
import { consolidateResultsToolDefinition } from "./consolidateResults"
import { cancelTaskToolDefinition } from "./cancelTask"
import { releaseTasksToolDefinition } from "./releaseTasks"
import { resumeParentTaskToolDefinition } from "./resumeParentTask"
import { startConversationToolDefinition } from "./startConversation" // Import new definition
import { getCodebaseSearchDescription } from "./codebase-search"
import { CodeIndexManager } from "../../../services/code-index/manager"

// Function for the new tool's description
function getDispatchTaskDescription(): string {
return `<tool_description>
<tool_name>${dispatchTaskToolDefinition.name}</tool_name>
<description>${dispatchTaskToolDefinition.description}</description>
<parameters>
${dispatchTaskToolDefinition.parameters
.map(
(param) =>
`<parameter>\n<name>${param.name}</name>\n<type>${param.type}</type>\n<description>${param.description}</description>\n</parameter>`,
)
.join("\n\t\t")}
</parameters>
</tool_description>`
}

// Function for get_task_status tool's description
function getGetTaskStatusDescription(): string {
return `<tool_description>
<tool_name>${getTaskStatusToolDefinition.name}</tool_name>
<description>${getTaskStatusToolDefinition.description}</description>
<parameters>
${getTaskStatusToolDefinition.parameters
.map(
(param) =>
`<parameter>\n<name>${param.name}</name>\n<type>${param.type}</type>\n<description>${param.description}</description>\n</parameter>`,
)
.join("\n\t\t")}
</parameters>
</tool_description>`
}

// Function for consolidate_results tool's description
function getConsolidateResultsDescription(): string {
return `<tool_description>
<tool_name>${consolidateResultsToolDefinition.name}</tool_name>
<description>${consolidateResultsToolDefinition.description}</description>
<parameters>
${consolidateResultsToolDefinition.parameters
.map(
(param) =>
`<parameter>\n<name>${param.name}</name>\n<type>${param.type}</type>\n<description>${param.description}</description>\n</parameter>`,
)
.join("\n\t\t")}
</parameters>
</tool_description>`
}

// Function for cancel_task tool's description
function getCancelTaskDescription(): string {
return `<tool_description>
<tool_name>${cancelTaskToolDefinition.name}</tool_name>
<description>${cancelTaskToolDefinition.description}</description>
<parameters>
${cancelTaskToolDefinition.parameters
.map(
(param) =>
`<parameter>\n<name>${param.name}</name>\n<type>${param.type}</type>\n<description>${param.description}</description>\n</parameter>`,
)
.join("\n\t\t")}
</parameters>
</tool_description>`
}

// Function for release_tasks tool's description
function getReleaseTasksDescription(): string {
return `<tool_description>
<tool_name>${releaseTasksToolDefinition.name}</tool_name>
<description>${releaseTasksToolDefinition.description}</description>
<parameters>
${releaseTasksToolDefinition.parameters
.map(
(param) =>
`<parameter>\n<name>${param.name}</name>\n<type>${param.type}</type>\n<description>${param.description}</description>\n</parameter>`,
)
.join("\n\t\t")}
</parameters>
</tool_description>`
}

// Function for resume_parent_task tool's description
function getResumeParentTaskDescription(): string {
return `<tool_description>
<tool_name>${resumeParentTaskToolDefinition.name}</tool_name>
<description>${resumeParentTaskToolDefinition.description}</description>
<parameters>
${resumeParentTaskToolDefinition.parameters
.map(
(param) =>
`<parameter>\n<name>${param.name}</name>\n<type>${param.type}</type>\n<description>${param.description}</description>\n</parameter>`,
)
.join("\n\t\t")}
</parameters>
</tool_description>`
}

// Function for start_conversation tool's description
function getStartConversationDescription(): string {
return `<tool_description>
<tool_name>${startConversationToolDefinition.name}</tool_name>
<description>${startConversationToolDefinition.description}</description>
<parameters>
${startConversationToolDefinition.parameters
.map(
(param) =>
`<parameter>\n<name>${param.name}</name>\n<type>${param.type}</type>\n<description>${param.description}</description>\n</parameter>`,
)
.join("\n\t\t")}
</parameters>
</tool_description>`
}

// Map of tool names to their description functions
const toolDescriptionMap: Record<string, (args: ToolArgs) => string | undefined> = {
execute_command: (args) => getExecuteCommandDescription(args),
Expand All @@ -41,6 +160,13 @@ const toolDescriptionMap: Record<string, (args: ToolArgs) => string | undefined>
codebase_search: () => getCodebaseSearchDescription(),
switch_mode: () => getSwitchModeDescription(),
new_task: (args) => getNewTaskDescription(args),
dispatch_task: () => getDispatchTaskDescription(),
get_task_status: () => getGetTaskStatusDescription(),
consolidate_results: () => getConsolidateResultsDescription(),
cancel_task: () => getCancelTaskDescription(),
release_tasks: () => getReleaseTasksDescription(),
resume_parent_task: () => getResumeParentTaskDescription(),
start_conversation: () => getStartConversationDescription(), // Added start_conversation
insert_content: (args) => getInsertContentDescription(args),
search_and_replace: (args) => getSearchAndReplaceDescription(args),
apply_diff: (args) =>
Expand Down
16 changes: 16 additions & 0 deletions src/core/prompts/tools/releaseTasks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { ToolDefinition } from "./types"

export const releaseTasksToolDefinition: ToolDefinition = {
name: "release_tasks",
description:
"Releases the records of one or more terminated (completed, failed, or aborted) sub-tasks from active memory. This should be called after results have been consolidated and the task records are no longer needed. This tool only affects tasks that are already in a terminal state.",
parameters: [
{
name: "task_instance_ids",
description:
"A comma-separated string of task instance IDs whose records are to be released (e.g., 'id1,id2,id3').",
type: "string",
required: true,
},
],
}
22 changes: 22 additions & 0 deletions src/core/prompts/tools/resumeParentTask.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { ToolDefinition } from "./types"

export const resumeParentTaskToolDefinition: ToolDefinition = {
name: "resume_parent_task",
description:
"Called by a mediator agent after it has processed a task's original result. This tool signals that the original parent task (if one exists) should now be resumed using the (potentially modified) result provided by the mediator. If the original task was a root task, this tool indicates the mediation is complete.",
parameters: [
{
name: "original_parent_id",
description:
"The instance ID of the original parent task that was awaiting mediation. Should be 'null' (as a string) if the original task was a root task.",
type: "string", // Will be parsed, 'null' string for actual null
required: true,
},
{
name: "mediated_result",
description: "The final result (potentially modified by the mediator) to be passed to the original parent task or considered the final output if the original was a root task.",
type: "string",
required: true,
},
],
}
34 changes: 34 additions & 0 deletions src/core/prompts/tools/startConversation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { ToolDefinition } from "./types"

export const startConversationToolDefinition: ToolDefinition = {
name: "start_conversation",
description:
"Initiates and manages a structured, turn-by-turn conversation (debate) between two dynamically defined AI agents to collaboratively refine ideas, critique plans, or create artifacts. The conversation continues until a specified termination condition is met, as judged by a referee LLM. Returns the full conversation transcript.",
parameters: [
{
name: "participants",
description:
"A JSON string representing an array of two participant agent definitions. Each definition object should have: `base_mode` (optional string, e.g., 'code', 'architect', defaults to general agent mode) and `dynamic_persona_instructions` (required string, specific instructions for this agent in this conversation). Example: '[{\"base_mode\": \"code\", \"dynamic_persona_instructions\": \"You are a senior Python developer. Focus on code clarity and efficiency.\"}, {\"dynamic_persona_instructions\": \"You are a QA engineer. Focus on edge cases and potential bugs.\"}]'",
type: "string", // JSON string
required: true,
},
{
name: "shared_context",
description: "The initial data, document, code snippet, or problem statement that the conversation should be based on. This will be provided to both agents.",
type: "string",
required: true,
},
{
name: "initial_prompt",
description: "The first message to start the conversation, which will be delivered to the first participant.",
type: "string",
required: true,
},
{
name: "termination_condition",
description: "A clear, objective question that a referee LLM will use to determine if the debate is over after each round (e.g., 'Have the participants produced a final, agreed-upon list of changes?'). The referee will answer 'yes' or 'no'.",
type: "string",
required: true,
},
],
}
Loading
Loading