createBashTool function
Builds the tool that runs shell commands in the workspace.
Implementation
Tool<JsonMap, String> createBashTool(
Genkit ai, {
required ToolRuntime runtime,
}) {
const toolName = 'bash';
return ai.defineTool(
name: toolName,
description: 'Runs a shell command in the current workspace.',
inputSchema: createJsonObjectSchema(
description: 'Input for the bash tool.',
properties: <String, $Schema>{
'command': $Schema.string(
description: 'The shell command to execute.',
),
'workdir': $Schema.string(
description: 'Optional working directory. Defaults to the current workspace directory.',
),
'timeout_ms': $Schema.integer(
description: 'Optional timeout in milliseconds. Defaults to 30000.',
),
},
required: <String>['command'],
),
outputSchema: stringOutputSchema,
fn: (input, _) async {
final command = readString(input, 'command')?.trim();
final workdirInput = readString(input, 'workdir')?.trim();
final timeoutMs = readInt(input, 'timeout_ms') ?? 30000;
if (command == null || command.isEmpty) {
const error = 'Error: `command` is required.';
runtime.endTool(toolName, error);
return error;
}
final workdir = workdirInput == null || workdirInput.isEmpty
? runtime.currentWorkingDirectory
: runtime.resolveDirectory(workdirInput);
if (!runtime.isWithinWorkspace(workdir)) {
const error = 'Error: `workdir` must stay inside the workspace.';
runtime.endTool(toolName, error);
return error;
}
final assessment = assessBashCommand(command);
if (assessment.requiresApproval) {
final approved = await runtime.requestApproval(
ToolApprovalRequest(
toolName: toolName,
reason: assessment.reason ?? 'This command requires approval.',
command: command,
),
);
if (!approved) {
const rejected = 'Error: command was not approved by the user.';
runtime.endTool(toolName, rejected);
return rejected;
}
}
runtime.startTool(toolName, '$command @ $workdir');
final output = await _runCommand(
command: command,
workdir: workdir,
timeoutMs: timeoutMs < 1 ? 1 : timeoutMs,
);
runtime.endTool(toolName, output);
return output;
},
);
}