/
outbreak
/
kilocode
Обзор
Документация
Войти
/
outbreak
/
kilocode
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/core/tools/RunSlashCommandTool.ts
124 строки
4 KB
Daniel
feat: enable multiple native tool calls per turn with failure guardrails (#9273)
26 ноя 2025, 04:21
Не верифицирован
26 ноя 2025, 04:21
05f3573
Код
Авторство
О чём код?
import { Task } from "../task/Task" import { formatResponse } from "../prompts/responses" import { getCommand, getCommandNames } from "../../services/command/commands" import { EXPERIMENT_IDS, experiments } from "../../shared/experiments" import { BaseTool, ToolCallbacks } from "./BaseTool" import type { ToolUse } from "../../shared/tools" interface RunSlashCommandParams { command: string args?: string } export class RunSlashCommandTool extends BaseTool<"run_slash_command"> { readonly name = "run_slash_command" as const parseLegacy(params: Partial<Record<string, string>>): RunSlashCommandParams { return { command: params.command || "", args: params.args, } } async execute(params: RunSlashCommandParams, task: Task, callbacks: ToolCallbacks): Promise<void> { const { command: commandName, args } = params const { askApproval, handleError, pushToolResult, toolProtocol } = callbacks // Check if run slash command experiment is enabled const provider = task.providerRef.deref() const state = await provider?.getState() const isRunSlashCommandEnabled = experiments.isEnabled( state?.experiments ?? {}, EXPERIMENT_IDS.RUN_SLASH_COMMAND, ) if (!isRunSlashCommandEnabled) { pushToolResult( formatResponse.toolError( "Run slash command is an experimental feature that must be enabled in settings. Please enable 'Run Slash Command' in the Experimental Settings section.", ), ) return } try { if (!commandName) { task.consecutiveMistakeCount++ task.recordToolError("run_slash_command") task.didToolFailInCurrentTurn = true pushToolResult(await task.sayAndCreateMissingParamError("run_slash_command", "command")) return } task.consecutiveMistakeCount = 0 // Get the command from the commands service const command = await getCommand(task.cwd, commandName) if (!command) { // Get available commands for error message const availableCommands = await getCommandNames(task.cwd) task.recordToolError("run_slash_command") task.didToolFailInCurrentTurn = true pushToolResult( formatResponse.toolError( `Command '${commandName}' not found. Available commands: ${availableCommands.join(", ") || "(none)"}`, ), ) return } const toolMessage = JSON.stringify({ tool: "runSlashCommand", command: commandName, args: args, source: command.source, description: command.description, }) const didApprove = await askApproval("tool", toolMessage) if (!didApprove) { return } // Build the result message let result = `Command: /${commandName}` if (command.description) { result += `\nDescription: ${command.description}` } if (command.argumentHint) { result += `\nArgument hint: ${command.argumentHint}` } if (args) { result += `\nProvided arguments: ${args}` } result += `\nSource: ${command.source}` result += `\n\n--- Command Content ---\n\n${command.content}` // Return the command content as the tool result pushToolResult(result) } catch (error) { await handleError("running slash command", error as Error) } } override async handlePartial(task: Task, block: ToolUse<"run_slash_command">): Promise<void> { const commandName: string | undefined = block.params.command const args: string | undefined = block.params.args const partialMessage = JSON.stringify({ tool: "runSlashCommand", command: this.removeClosingTag("command", commandName, block.partial), args: this.removeClosingTag("args", args, block.partial), }) await task.ask("tool", partialMessage, block.partial).catch(() => {}) } } export const runSlashCommandTool = new RunSlashCommandTool()