createWriteTool function
Builds the tool that writes whole files inside the workspace.
Implementation
Tool<JsonMap, String> createWriteTool(
Genkit ai, {
required ToolRuntime runtime,
}) {
return defineTextTool(
ai,
runtime: runtime,
name: 'write',
description: _description,
properties: <String, Object?>{
'file_path': stringProperty('The absolute path of the file to write.'),
'content': stringProperty('The full content to write to the file.'),
},
required: <String>['file_path', 'content'],
run: (input) async {
final path = runtime.resolvePath(requireString(input, 'file_path'));
final content = readString(input, 'content');
if (content == null) {
throw const ToolFailure('`content` is required.');
}
if (!runtime.isWithinWorkspace(path)) {
throw ToolFailure('$path is outside the workspace ${runtime.workspaceRoot}.');
}
final file = File(path);
final existed = await file.exists();
if (existed) {
if (runtime.trackedFile(path) == null) {
throw const ToolFailure('The file already exists. Read it with the read tool before overwriting it.');
}
if (!await runtime.fileMatchesTrackedState(path)) {
throw const ToolFailure('The file changed since it was last read. Read it again before overwriting it.');
}
}
runtime.startTool('write', runtime.displayPath(path));
await file.parent.create(recursive: true);
await file.writeAsString(content);
runtime.recordFileRead(path, content, await file.stat());
final lineCount = content.isEmpty ? 0 : '\n'.allMatches(content.trimRight()).length + 1;
return existed ? 'Overwrote $path ($lineCount lines).' : 'Created $path ($lineCount lines).';
},
);
}