@tritard/waterbrother 0.16.20 → 0.16.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/tools.js +87 -0
package/package.json
CHANGED
package/src/tools.js
CHANGED
|
@@ -1112,6 +1112,87 @@ export function createToolRuntime({
|
|
|
1112
1112
|
currentTurn.touchedPaths = uniqueStrings([...(currentTurn.touchedPaths || []), ...normalizePathList(paths)]);
|
|
1113
1113
|
}
|
|
1114
1114
|
|
|
1115
|
+
async function buildImplicitVerificationEntries(toolName, args = {}, parsedResult = null) {
|
|
1116
|
+
if (!args?.path) return [];
|
|
1117
|
+
|
|
1118
|
+
const writeRoots = [...getCurrentWriteRoots(), ...getContractWriteRoots()];
|
|
1119
|
+
const commandLabel = `${toolName} ${String(args.path)}`;
|
|
1120
|
+
|
|
1121
|
+
try {
|
|
1122
|
+
if (toolName === "make_directory") {
|
|
1123
|
+
const target = resolveSandboxPath(cwd, args.path, allowOutsideCwd, {
|
|
1124
|
+
allowedWriteRoots: writeRoots
|
|
1125
|
+
});
|
|
1126
|
+
const stat = await fs.stat(target);
|
|
1127
|
+
return [{
|
|
1128
|
+
command: commandLabel,
|
|
1129
|
+
ok: stat.isDirectory(),
|
|
1130
|
+
implicit: true,
|
|
1131
|
+
tool: toolName,
|
|
1132
|
+
path: args.path,
|
|
1133
|
+
detail: stat.isDirectory() ? "directory exists" : "target exists but is not a directory"
|
|
1134
|
+
}];
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
if (toolName === "write_file" || toolName === "replace_in_file") {
|
|
1138
|
+
const target = resolveSandboxPath(cwd, args.path, allowOutsideCwd, {
|
|
1139
|
+
allowedWriteRoots: writeRoots
|
|
1140
|
+
});
|
|
1141
|
+
const stat = await fs.stat(target);
|
|
1142
|
+
const entries = [{
|
|
1143
|
+
command: commandLabel,
|
|
1144
|
+
ok: stat.isFile(),
|
|
1145
|
+
implicit: true,
|
|
1146
|
+
tool: toolName,
|
|
1147
|
+
path: args.path,
|
|
1148
|
+
detail: stat.isFile() ? "file exists after write" : "target exists but is not a file"
|
|
1149
|
+
}];
|
|
1150
|
+
if (toolName === "write_file" && parsedResult?.bytes != null) {
|
|
1151
|
+
entries.push({
|
|
1152
|
+
command: `${toolName} bytes ${String(args.path)}`,
|
|
1153
|
+
ok: stat.size === Number(parsedResult.bytes),
|
|
1154
|
+
implicit: true,
|
|
1155
|
+
tool: toolName,
|
|
1156
|
+
path: args.path,
|
|
1157
|
+
detail: `expected ${Number(parsedResult.bytes)} bytes, found ${stat.size}`
|
|
1158
|
+
});
|
|
1159
|
+
}
|
|
1160
|
+
return entries;
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
if (toolName === "delete_path") {
|
|
1164
|
+
const target = resolveSandboxPath(cwd, args.path, allowOutsideCwd, {
|
|
1165
|
+
allowedWriteRoots: writeRoots
|
|
1166
|
+
});
|
|
1167
|
+
let exists = true;
|
|
1168
|
+
try {
|
|
1169
|
+
await fs.access(target);
|
|
1170
|
+
} catch {
|
|
1171
|
+
exists = false;
|
|
1172
|
+
}
|
|
1173
|
+
return [{
|
|
1174
|
+
command: commandLabel,
|
|
1175
|
+
ok: !exists,
|
|
1176
|
+
implicit: true,
|
|
1177
|
+
tool: toolName,
|
|
1178
|
+
path: args.path,
|
|
1179
|
+
detail: exists ? "path still exists" : "path no longer exists"
|
|
1180
|
+
}];
|
|
1181
|
+
}
|
|
1182
|
+
} catch (error) {
|
|
1183
|
+
return [{
|
|
1184
|
+
command: commandLabel,
|
|
1185
|
+
ok: false,
|
|
1186
|
+
implicit: true,
|
|
1187
|
+
tool: toolName,
|
|
1188
|
+
path: args.path,
|
|
1189
|
+
detail: error instanceof Error ? error.message : String(error)
|
|
1190
|
+
}];
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
return [];
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1115
1196
|
function recordToolCall(entry = {}) {
|
|
1116
1197
|
currentTurn.toolCalls.push({
|
|
1117
1198
|
startedAt: new Date().toISOString(),
|
|
@@ -2246,6 +2327,12 @@ ${clipped}`;
|
|
|
2246
2327
|
if ((MUTATING_TOOLS.has(name) || name === "restore_checkpoint") && toolEntry.status === "ok") {
|
|
2247
2328
|
currentTurn.mutated = true;
|
|
2248
2329
|
}
|
|
2330
|
+
if (toolEntry.status === "ok") {
|
|
2331
|
+
const implicitVerification = await buildImplicitVerificationEntries(name, args, parsed);
|
|
2332
|
+
if (implicitVerification.length > 0) {
|
|
2333
|
+
currentTurn.verification = [...(currentTurn.verification || []), ...implicitVerification];
|
|
2334
|
+
}
|
|
2335
|
+
}
|
|
2249
2336
|
return result;
|
|
2250
2337
|
} catch (error) {
|
|
2251
2338
|
toolEntry.status = "error";
|