@robota-sdk/agent-tools 3.0.0-beta.56 → 3.0.0-beta.57
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/README.md +4 -0
- package/dist/node/index.cjs +27 -4
- package/dist/node/index.js +31 -8
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -57,6 +57,10 @@ const agent = new Robota({
|
|
|
57
57
|
| `webFetchTool` | WebFetch | Fetch URL content (HTML-to-text conversion) |
|
|
58
58
|
| `webSearchTool` | WebSearch | Web search via Brave Search API |
|
|
59
59
|
|
|
60
|
+
## Edit and Write Safety
|
|
61
|
+
|
|
62
|
+
Recent file tool updates keep write/edit behavior atomic and make Edit tool results easier for higher layers to display. The Edit tool returns line metadata for changed regions, allowing the CLI to render concise context hunks instead of dumping full files or opaque summaries.
|
|
63
|
+
|
|
60
64
|
## Tool Infrastructure
|
|
61
65
|
|
|
62
66
|
| Export | Description |
|
package/dist/node/index.cjs
CHANGED
|
@@ -1031,9 +1031,33 @@ var readTool = createZodFunctionTool(
|
|
|
1031
1031
|
);
|
|
1032
1032
|
|
|
1033
1033
|
// src/builtins/write-tool.ts
|
|
1034
|
+
var import_zod3 = require("zod");
|
|
1035
|
+
|
|
1036
|
+
// src/builtins/atomic-file-write.ts
|
|
1037
|
+
var import_node_crypto = require("crypto");
|
|
1034
1038
|
var import_promises2 = require("fs/promises");
|
|
1035
1039
|
var import_node_path = require("path");
|
|
1036
|
-
var
|
|
1040
|
+
var TEMP_RANDOM_BYTES = 6;
|
|
1041
|
+
function createTempFilePath(filePath) {
|
|
1042
|
+
const dir = (0, import_node_path.dirname)(filePath);
|
|
1043
|
+
const name = (0, import_node_path.basename)(filePath);
|
|
1044
|
+
const suffix = (0, import_node_crypto.randomBytes)(TEMP_RANDOM_BYTES).toString("hex");
|
|
1045
|
+
return (0, import_node_path.join)(dir, `.${name}.robota-tmp-${process.pid}-${Date.now()}-${suffix}`);
|
|
1046
|
+
}
|
|
1047
|
+
async function atomicWriteUtf8File(filePath, content) {
|
|
1048
|
+
const dir = (0, import_node_path.dirname)(filePath);
|
|
1049
|
+
await (0, import_promises2.mkdir)(dir, { recursive: true });
|
|
1050
|
+
const tempFilePath = createTempFilePath(filePath);
|
|
1051
|
+
try {
|
|
1052
|
+
await (0, import_promises2.writeFile)(tempFilePath, content, "utf8");
|
|
1053
|
+
await (0, import_promises2.rename)(tempFilePath, filePath);
|
|
1054
|
+
} catch (error) {
|
|
1055
|
+
await (0, import_promises2.rm)(tempFilePath, { force: true }).catch(() => void 0);
|
|
1056
|
+
throw error;
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
// src/builtins/write-tool.ts
|
|
1037
1061
|
var WriteSchema = import_zod3.z.object({
|
|
1038
1062
|
filePath: import_zod3.z.string().describe("The absolute path to the file to write"),
|
|
1039
1063
|
content: import_zod3.z.string().describe("The content to write to the file")
|
|
@@ -1041,8 +1065,7 @@ var WriteSchema = import_zod3.z.object({
|
|
|
1041
1065
|
async function writeFileTool(args) {
|
|
1042
1066
|
const { filePath, content } = args;
|
|
1043
1067
|
try {
|
|
1044
|
-
await (
|
|
1045
|
-
await (0, import_promises2.writeFile)(filePath, content, "utf8");
|
|
1068
|
+
await atomicWriteUtf8File(filePath, content);
|
|
1046
1069
|
const result = {
|
|
1047
1070
|
success: true,
|
|
1048
1071
|
output: `Written ${Buffer.byteLength(content, "utf8")} bytes to ${filePath}`
|
|
@@ -1113,7 +1136,7 @@ async function editFileTool(args) {
|
|
|
1113
1136
|
}
|
|
1114
1137
|
const updated = replaceAll ? content.split(oldString).join(newString) : content.slice(0, content.indexOf(oldString)) + newString + content.slice(content.indexOf(oldString) + oldString.length);
|
|
1115
1138
|
try {
|
|
1116
|
-
await (
|
|
1139
|
+
await atomicWriteUtf8File(filePath, updated);
|
|
1117
1140
|
} catch (err) {
|
|
1118
1141
|
const result2 = {
|
|
1119
1142
|
success: false,
|
package/dist/node/index.js
CHANGED
|
@@ -981,9 +981,33 @@ var readTool = createZodFunctionTool(
|
|
|
981
981
|
);
|
|
982
982
|
|
|
983
983
|
// src/builtins/write-tool.ts
|
|
984
|
-
import { writeFile, mkdir } from "fs/promises";
|
|
985
|
-
import { dirname } from "path";
|
|
986
984
|
import { z as z3 } from "zod";
|
|
985
|
+
|
|
986
|
+
// src/builtins/atomic-file-write.ts
|
|
987
|
+
import { randomBytes } from "crypto";
|
|
988
|
+
import { mkdir, rename, rm, writeFile } from "fs/promises";
|
|
989
|
+
import { basename, dirname, join } from "path";
|
|
990
|
+
var TEMP_RANDOM_BYTES = 6;
|
|
991
|
+
function createTempFilePath(filePath) {
|
|
992
|
+
const dir = dirname(filePath);
|
|
993
|
+
const name = basename(filePath);
|
|
994
|
+
const suffix = randomBytes(TEMP_RANDOM_BYTES).toString("hex");
|
|
995
|
+
return join(dir, `.${name}.robota-tmp-${process.pid}-${Date.now()}-${suffix}`);
|
|
996
|
+
}
|
|
997
|
+
async function atomicWriteUtf8File(filePath, content) {
|
|
998
|
+
const dir = dirname(filePath);
|
|
999
|
+
await mkdir(dir, { recursive: true });
|
|
1000
|
+
const tempFilePath = createTempFilePath(filePath);
|
|
1001
|
+
try {
|
|
1002
|
+
await writeFile(tempFilePath, content, "utf8");
|
|
1003
|
+
await rename(tempFilePath, filePath);
|
|
1004
|
+
} catch (error) {
|
|
1005
|
+
await rm(tempFilePath, { force: true }).catch(() => void 0);
|
|
1006
|
+
throw error;
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
// src/builtins/write-tool.ts
|
|
987
1011
|
var WriteSchema = z3.object({
|
|
988
1012
|
filePath: z3.string().describe("The absolute path to the file to write"),
|
|
989
1013
|
content: z3.string().describe("The content to write to the file")
|
|
@@ -991,8 +1015,7 @@ var WriteSchema = z3.object({
|
|
|
991
1015
|
async function writeFileTool(args) {
|
|
992
1016
|
const { filePath, content } = args;
|
|
993
1017
|
try {
|
|
994
|
-
await
|
|
995
|
-
await writeFile(filePath, content, "utf8");
|
|
1018
|
+
await atomicWriteUtf8File(filePath, content);
|
|
996
1019
|
const result = {
|
|
997
1020
|
success: true,
|
|
998
1021
|
output: `Written ${Buffer.byteLength(content, "utf8")} bytes to ${filePath}`
|
|
@@ -1017,7 +1040,7 @@ var writeTool = createZodFunctionTool(
|
|
|
1017
1040
|
);
|
|
1018
1041
|
|
|
1019
1042
|
// src/builtins/edit-tool.ts
|
|
1020
|
-
import { readFile as readFile2
|
|
1043
|
+
import { readFile as readFile2 } from "fs/promises";
|
|
1021
1044
|
import { z as z4 } from "zod";
|
|
1022
1045
|
var EditSchema = z4.object({
|
|
1023
1046
|
filePath: z4.string().describe("The absolute path to the file to modify"),
|
|
@@ -1063,7 +1086,7 @@ async function editFileTool(args) {
|
|
|
1063
1086
|
}
|
|
1064
1087
|
const updated = replaceAll ? content.split(oldString).join(newString) : content.slice(0, content.indexOf(oldString)) + newString + content.slice(content.indexOf(oldString) + oldString.length);
|
|
1065
1088
|
try {
|
|
1066
|
-
await
|
|
1089
|
+
await atomicWriteUtf8File(filePath, updated);
|
|
1067
1090
|
} catch (err) {
|
|
1068
1091
|
const result2 = {
|
|
1069
1092
|
success: false,
|
|
@@ -1165,7 +1188,7 @@ var globTool = createZodFunctionTool(
|
|
|
1165
1188
|
|
|
1166
1189
|
// src/builtins/grep-tool.ts
|
|
1167
1190
|
import { readFile as readFile3, readdir, stat as stat3 } from "fs/promises";
|
|
1168
|
-
import { join, resolve as resolve2 } from "path";
|
|
1191
|
+
import { join as join2, resolve as resolve2 } from "path";
|
|
1169
1192
|
import { z as z6 } from "zod";
|
|
1170
1193
|
var GrepSchema = z6.object({
|
|
1171
1194
|
pattern: z6.string().describe("The regular expression pattern to search for in file contents"),
|
|
@@ -1199,7 +1222,7 @@ async function collectFiles(dirPath, glob) {
|
|
|
1199
1222
|
}
|
|
1200
1223
|
for (const name of entryNames) {
|
|
1201
1224
|
if (name === "node_modules" || name === ".git") continue;
|
|
1202
|
-
const fullPath =
|
|
1225
|
+
const fullPath = join2(current, name);
|
|
1203
1226
|
let fileStat;
|
|
1204
1227
|
try {
|
|
1205
1228
|
fileStat = await stat3(fullPath);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@robota-sdk/agent-tools",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.57",
|
|
4
4
|
"description": "Tool registry and implementations for Robota SDK",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/node/index.js",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"zod": "^3.24.0"
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
|
-
"@robota-sdk/agent-core": "3.0.0-beta.
|
|
37
|
+
"@robota-sdk/agent-core": "3.0.0-beta.57"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"openapi-types": "^12.1.3",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"tsup": "^8.0.1",
|
|
43
43
|
"typescript": "^5.3.3",
|
|
44
44
|
"vitest": "^1.6.1",
|
|
45
|
-
"@robota-sdk/agent-core": "3.0.0-beta.
|
|
45
|
+
"@robota-sdk/agent-core": "3.0.0-beta.57"
|
|
46
46
|
},
|
|
47
47
|
"license": "MIT",
|
|
48
48
|
"publishConfig": {
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
"build:js": "tsup src/index.ts --format esm,cjs --out-dir dist/node --clean",
|
|
54
54
|
"build:types": "tsup src/index.ts --format esm,cjs --dts-only --out-dir dist/node",
|
|
55
55
|
"test": "vitest run --passWithNoTests",
|
|
56
|
+
"test:coverage": "vitest run --coverage --passWithNoTests",
|
|
56
57
|
"typecheck": "tsc --noEmit",
|
|
57
58
|
"lint": "eslint src/ --ext .ts,.tsx",
|
|
58
59
|
"lint:fix": "eslint src/ --ext .ts,.tsx --fix",
|