@dexto/tools-filesystem 1.7.1 → 1.8.0
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/dist/directory-approval.cjs +5 -4
- package/dist/directory-approval.d.ts +2 -1
- package/dist/directory-approval.d.ts.map +1 -1
- package/dist/directory-approval.integration.test.cjs +73 -33
- package/dist/directory-approval.integration.test.js +73 -33
- package/dist/directory-approval.js +2 -1
- package/dist/edit-file-tool.cjs +52 -37
- package/dist/edit-file-tool.d.ts +1 -1
- package/dist/edit-file-tool.d.ts.map +1 -1
- package/dist/edit-file-tool.js +43 -29
- package/dist/edit-file-tool.test.cjs +159 -2
- package/dist/edit-file-tool.test.js +159 -2
- package/dist/errors.cjs +53 -53
- package/dist/errors.d.ts +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +1 -1
- package/dist/file-tool-types.d.ts +1 -1
- package/dist/file-tool-types.d.ts.map +1 -1
- package/dist/filesystem-service.cjs +60 -60
- package/dist/filesystem-service.d.ts +1 -1
- package/dist/filesystem-service.d.ts.map +1 -1
- package/dist/filesystem-service.js +5 -5
- package/dist/filesystem-service.test.cjs +1 -3
- package/dist/filesystem-service.test.js +1 -3
- package/dist/glob-files-tool.cjs +27 -24
- package/dist/glob-files-tool.d.ts +1 -1
- package/dist/glob-files-tool.d.ts.map +1 -1
- package/dist/glob-files-tool.js +24 -21
- package/dist/glob-files-tool.test.cjs +100 -88
- package/dist/glob-files-tool.test.js +101 -67
- package/dist/grep-content-tool.cjs +129 -44
- package/dist/grep-content-tool.d.ts +1 -1
- package/dist/grep-content-tool.d.ts.map +1 -1
- package/dist/grep-content-tool.js +120 -41
- package/dist/grep-content-tool.test.cjs +122 -87
- package/dist/grep-content-tool.test.js +123 -66
- package/dist/index.d.cts +3 -4
- package/dist/path-validator.d.ts +1 -1
- package/dist/path-validator.d.ts.map +1 -1
- package/dist/read-file-tool.cjs +43 -14
- package/dist/read-file-tool.d.ts +1 -1
- package/dist/read-file-tool.d.ts.map +1 -1
- package/dist/read-file-tool.js +40 -11
- package/dist/read-file-tool.test.cjs +119 -0
- package/dist/read-file-tool.test.d.ts +2 -0
- package/dist/read-file-tool.test.d.ts.map +1 -0
- package/dist/read-file-tool.test.js +96 -0
- package/dist/read-media-file-tool.cjs +4 -4
- package/dist/read-media-file-tool.d.ts +1 -1
- package/dist/read-media-file-tool.d.ts.map +1 -1
- package/dist/read-media-file-tool.js +1 -1
- package/dist/tool-factory.cjs +2 -2
- package/dist/tool-factory.js +1 -1
- package/dist/types.d.ts +0 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/workspace-paths.cjs +87 -0
- package/dist/workspace-paths.d.ts +4 -0
- package/dist/workspace-paths.d.ts.map +1 -0
- package/dist/workspace-paths.js +51 -0
- package/dist/write-file-tool.cjs +74 -34
- package/dist/write-file-tool.d.ts +1 -2
- package/dist/write-file-tool.d.ts.map +1 -1
- package/dist/write-file-tool.js +68 -29
- package/dist/write-file-tool.test.cjs +262 -11
- package/dist/write-file-tool.test.js +262 -11
- package/package.json +3 -3
package/dist/read-file-tool.cjs
CHANGED
|
@@ -22,23 +22,24 @@ __export(read_file_tool_exports, {
|
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(read_file_tool_exports);
|
|
24
24
|
var import_zod = require("zod");
|
|
25
|
-
var
|
|
25
|
+
var import_tools = require("@dexto/core/tools");
|
|
26
26
|
var import_directory_approval = require("./directory-approval.js");
|
|
27
|
+
var import_workspace_paths = require("./workspace-paths.js");
|
|
27
28
|
const ReadFileInputSchema = import_zod.z.object({
|
|
28
29
|
file_path: import_zod.z.string().min(1).describe("Absolute path to the file to read"),
|
|
29
30
|
limit: import_zod.z.number().int().positive().optional().describe("Maximum number of lines to read (optional)"),
|
|
30
31
|
offset: import_zod.z.number().int().min(1).optional().describe("Starting line number (1-based, optional)")
|
|
31
32
|
}).strict();
|
|
32
33
|
function createReadFileTool(getFileSystemService) {
|
|
33
|
-
return (0,
|
|
34
|
+
return (0, import_tools.defineTool)({
|
|
34
35
|
id: "read_file",
|
|
35
36
|
aliases: ["read"],
|
|
36
37
|
description: "Read the UTF-8 text contents of a file with optional pagination. Returns file content, line count, encoding, MIME type, and whether the output was truncated. Use limit and offset parameters for large files to read specific sections. Use read_media_file for image, audio, video, PDF, and other binary files.",
|
|
37
38
|
inputSchema: ReadFileInputSchema,
|
|
38
39
|
presentation: {
|
|
39
|
-
describeHeader: (input) => (0,
|
|
40
|
+
describeHeader: (input) => (0, import_tools.createLocalToolCallHeader)({
|
|
40
41
|
title: "Read",
|
|
41
|
-
argsText: (0,
|
|
42
|
+
argsText: (0, import_tools.truncateForHeader)(input.file_path, 140)
|
|
42
43
|
})
|
|
43
44
|
},
|
|
44
45
|
...(0, import_directory_approval.createDirectoryAccessApprovalHandlers)({
|
|
@@ -49,19 +50,26 @@ function createReadFileTool(getFileSystemService) {
|
|
|
49
50
|
resolvePaths: (input, fileSystemService) => (0, import_directory_approval.resolveFilePath)(fileSystemService.getWorkingDirectory(), input.file_path)
|
|
50
51
|
}),
|
|
51
52
|
async execute(input, context) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
53
|
+
if (!context.services) {
|
|
54
|
+
throw new Error("read_file requires ToolExecutionContext.services");
|
|
55
|
+
}
|
|
56
|
+
const handle = await context.services.workspaceManager.open({ intent: "read" });
|
|
57
|
+
if (typeof handle.files.readText !== "function") {
|
|
58
|
+
throw new Error(`Workspace file read unavailable: ${input.file_path}`);
|
|
59
|
+
}
|
|
60
|
+
const workspacePath = (0, import_workspace_paths.toWorkspaceRelativePath)(
|
|
61
|
+
"read_file",
|
|
62
|
+
handle.context.path,
|
|
63
|
+
input.file_path
|
|
57
64
|
);
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
65
|
+
const content = await handle.files.readText(workspacePath);
|
|
66
|
+
const result = applyLineWindow(content, {
|
|
67
|
+
limit: input.limit,
|
|
68
|
+
offset: input.offset
|
|
61
69
|
});
|
|
62
70
|
const _display = {
|
|
63
71
|
type: "file",
|
|
64
|
-
path:
|
|
72
|
+
path: input.file_path,
|
|
65
73
|
operation: "read",
|
|
66
74
|
size: result.size,
|
|
67
75
|
lineCount: result.lines
|
|
@@ -72,12 +80,33 @@ function createReadFileTool(getFileSystemService) {
|
|
|
72
80
|
encoding: result.encoding,
|
|
73
81
|
truncated: result.truncated,
|
|
74
82
|
size: result.size,
|
|
75
|
-
...result.mimeType && { mimeType: result.mimeType },
|
|
76
83
|
_display
|
|
77
84
|
};
|
|
78
85
|
}
|
|
79
86
|
});
|
|
80
87
|
}
|
|
88
|
+
function applyLineWindow(content, options) {
|
|
89
|
+
const lines = content.split("\n");
|
|
90
|
+
if (!options.offset && options.limit === void 0) {
|
|
91
|
+
return {
|
|
92
|
+
content,
|
|
93
|
+
lines: lines.length,
|
|
94
|
+
encoding: "utf-8",
|
|
95
|
+
truncated: false,
|
|
96
|
+
size: Buffer.byteLength(content, "utf-8")
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
const start = options.offset && options.offset > 0 ? Math.max(0, options.offset - 1) : 0;
|
|
100
|
+
const end = options.limit !== void 0 ? start + options.limit : lines.length;
|
|
101
|
+
const selectedContent = lines.slice(start, end).join("\n");
|
|
102
|
+
return {
|
|
103
|
+
content: selectedContent,
|
|
104
|
+
lines: selectedContent.length > 0 ? selectedContent.split("\n").length : 0,
|
|
105
|
+
encoding: "utf-8",
|
|
106
|
+
truncated: end < lines.length,
|
|
107
|
+
size: Buffer.byteLength(selectedContent, "utf-8")
|
|
108
|
+
};
|
|
109
|
+
}
|
|
81
110
|
// Annotate the CommonJS export names for ESM import in node:
|
|
82
111
|
0 && (module.exports = {
|
|
83
112
|
createReadFileTool
|
package/dist/read-file-tool.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Internal tool for reading file contents with size limits and pagination
|
|
5
5
|
*/
|
|
6
6
|
import { z } from 'zod';
|
|
7
|
-
import type { Tool } from '@dexto/core';
|
|
7
|
+
import type { Tool } from '@dexto/core/tools';
|
|
8
8
|
import type { FileSystemServiceGetter } from './file-tool-types.js';
|
|
9
9
|
declare const ReadFileInputSchema: z.ZodObject<{
|
|
10
10
|
file_path: z.ZodString;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read-file-tool.d.ts","sourceRoot":"","sources":["../src/read-file-tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAmB,IAAI,EAAwB,MAAM,
|
|
1
|
+
{"version":3,"file":"read-file-tool.d.ts","sourceRoot":"","sources":["../src/read-file-tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAmB,IAAI,EAAwB,MAAM,mBAAmB,CAAC;AACrF,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAKpE,QAAA,MAAM,mBAAmB;;;;kBAgBZ,CAAC;AAEd;;GAEG;AACH,wBAAgB,kBAAkB,CAC9B,oBAAoB,EAAE,uBAAuB,GAC9C,IAAI,CAAC,OAAO,mBAAmB,CAAC,CAgElC"}
|
package/dist/read-file-tool.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { createLocalToolCallHeader, defineTool, truncateForHeader } from "@dexto/core";
|
|
2
|
+
import { createLocalToolCallHeader, defineTool, truncateForHeader } from "@dexto/core/tools";
|
|
3
3
|
import { createDirectoryAccessApprovalHandlers, resolveFilePath } from "./directory-approval.js";
|
|
4
|
+
import { toWorkspaceRelativePath } from "./workspace-paths.js";
|
|
4
5
|
const ReadFileInputSchema = z.object({
|
|
5
6
|
file_path: z.string().min(1).describe("Absolute path to the file to read"),
|
|
6
7
|
limit: z.number().int().positive().optional().describe("Maximum number of lines to read (optional)"),
|
|
@@ -26,19 +27,26 @@ function createReadFileTool(getFileSystemService) {
|
|
|
26
27
|
resolvePaths: (input, fileSystemService) => resolveFilePath(fileSystemService.getWorkingDirectory(), input.file_path)
|
|
27
28
|
}),
|
|
28
29
|
async execute(input, context) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
if (!context.services) {
|
|
31
|
+
throw new Error("read_file requires ToolExecutionContext.services");
|
|
32
|
+
}
|
|
33
|
+
const handle = await context.services.workspaceManager.open({ intent: "read" });
|
|
34
|
+
if (typeof handle.files.readText !== "function") {
|
|
35
|
+
throw new Error(`Workspace file read unavailable: ${input.file_path}`);
|
|
36
|
+
}
|
|
37
|
+
const workspacePath = toWorkspaceRelativePath(
|
|
38
|
+
"read_file",
|
|
39
|
+
handle.context.path,
|
|
40
|
+
input.file_path
|
|
34
41
|
);
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
42
|
+
const content = await handle.files.readText(workspacePath);
|
|
43
|
+
const result = applyLineWindow(content, {
|
|
44
|
+
limit: input.limit,
|
|
45
|
+
offset: input.offset
|
|
38
46
|
});
|
|
39
47
|
const _display = {
|
|
40
48
|
type: "file",
|
|
41
|
-
path:
|
|
49
|
+
path: input.file_path,
|
|
42
50
|
operation: "read",
|
|
43
51
|
size: result.size,
|
|
44
52
|
lineCount: result.lines
|
|
@@ -49,12 +57,33 @@ function createReadFileTool(getFileSystemService) {
|
|
|
49
57
|
encoding: result.encoding,
|
|
50
58
|
truncated: result.truncated,
|
|
51
59
|
size: result.size,
|
|
52
|
-
...result.mimeType && { mimeType: result.mimeType },
|
|
53
60
|
_display
|
|
54
61
|
};
|
|
55
62
|
}
|
|
56
63
|
});
|
|
57
64
|
}
|
|
65
|
+
function applyLineWindow(content, options) {
|
|
66
|
+
const lines = content.split("\n");
|
|
67
|
+
if (!options.offset && options.limit === void 0) {
|
|
68
|
+
return {
|
|
69
|
+
content,
|
|
70
|
+
lines: lines.length,
|
|
71
|
+
encoding: "utf-8",
|
|
72
|
+
truncated: false,
|
|
73
|
+
size: Buffer.byteLength(content, "utf-8")
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
const start = options.offset && options.offset > 0 ? Math.max(0, options.offset - 1) : 0;
|
|
77
|
+
const end = options.limit !== void 0 ? start + options.limit : lines.length;
|
|
78
|
+
const selectedContent = lines.slice(start, end).join("\n");
|
|
79
|
+
return {
|
|
80
|
+
content: selectedContent,
|
|
81
|
+
lines: selectedContent.length > 0 ? selectedContent.split("\n").length : 0,
|
|
82
|
+
encoding: "utf-8",
|
|
83
|
+
truncated: end < lines.length,
|
|
84
|
+
size: Buffer.byteLength(selectedContent, "utf-8")
|
|
85
|
+
};
|
|
86
|
+
}
|
|
58
87
|
export {
|
|
59
88
|
createReadFileTool
|
|
60
89
|
};
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
10
|
+
for (let key of __getOwnPropNames(from))
|
|
11
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
12
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
13
|
+
}
|
|
14
|
+
return to;
|
|
15
|
+
};
|
|
16
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
17
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
18
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
19
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
20
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
21
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
22
|
+
mod
|
|
23
|
+
));
|
|
24
|
+
var import_core = require("@dexto/core");
|
|
25
|
+
var import_storage = require("@dexto/core/storage");
|
|
26
|
+
var import_node_path = __toESM(require("node:path"), 1);
|
|
27
|
+
var import_vitest = require("vitest");
|
|
28
|
+
var import_read_file_tool = require("./read-file-tool.js");
|
|
29
|
+
async function createContext(content, readText = import_vitest.vi.fn(async () => content)) {
|
|
30
|
+
const stores = new import_storage.InMemoryDextoStores();
|
|
31
|
+
await stores.connect();
|
|
32
|
+
const logger = (0, import_core.createLogger)({
|
|
33
|
+
agentId: "test-agent",
|
|
34
|
+
config: { level: "error", transports: [{ type: "silent" }] }
|
|
35
|
+
});
|
|
36
|
+
const workspaceManager = new import_core.WorkspaceManager(
|
|
37
|
+
stores.getStore("workspaces"),
|
|
38
|
+
new import_core.AgentEventBus(),
|
|
39
|
+
logger,
|
|
40
|
+
{
|
|
41
|
+
open: import_vitest.vi.fn(async ({ context }) => ({
|
|
42
|
+
context,
|
|
43
|
+
capabilities: ["files"],
|
|
44
|
+
files: {
|
|
45
|
+
readFile: import_vitest.vi.fn(async () => content),
|
|
46
|
+
readText,
|
|
47
|
+
glob: import_vitest.vi.fn(async () => []),
|
|
48
|
+
writeFile: import_vitest.vi.fn(async () => void 0),
|
|
49
|
+
listFiles: import_vitest.vi.fn(async () => [])
|
|
50
|
+
}
|
|
51
|
+
}))
|
|
52
|
+
}
|
|
53
|
+
);
|
|
54
|
+
await workspaceManager.setWorkspace({ path: "/repo" });
|
|
55
|
+
return {
|
|
56
|
+
logger,
|
|
57
|
+
services: {
|
|
58
|
+
approval: {},
|
|
59
|
+
search: {},
|
|
60
|
+
resources: {},
|
|
61
|
+
prompts: {},
|
|
62
|
+
skills: {},
|
|
63
|
+
mcp: {},
|
|
64
|
+
taskForker: null,
|
|
65
|
+
workspaceManager
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
(0, import_vitest.describe)("read_file tool", () => {
|
|
70
|
+
(0, import_vitest.it)("reads text through WorkspaceManager.open", async () => {
|
|
71
|
+
const getFileSystemService = import_vitest.vi.fn(async () => {
|
|
72
|
+
throw new Error("read_file execute must not use FileSystemService");
|
|
73
|
+
});
|
|
74
|
+
const tool = (0, import_read_file_tool.createReadFileTool)(getFileSystemService);
|
|
75
|
+
const result = await tool.execute({ file_path: "local.txt" }, await createContext("alpha"));
|
|
76
|
+
(0, import_vitest.expect)(getFileSystemService).not.toHaveBeenCalled();
|
|
77
|
+
(0, import_vitest.expect)(result).toMatchObject({
|
|
78
|
+
content: "alpha",
|
|
79
|
+
lines: 1,
|
|
80
|
+
encoding: "utf-8",
|
|
81
|
+
truncated: false,
|
|
82
|
+
size: Buffer.byteLength("alpha", "utf-8")
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
(0, import_vitest.it)("applies pagination after workspace reads", async () => {
|
|
86
|
+
const tool = (0, import_read_file_tool.createReadFileTool)(import_vitest.vi.fn());
|
|
87
|
+
const result = await tool.execute(
|
|
88
|
+
{ file_path: "local.txt", offset: 2, limit: 2 },
|
|
89
|
+
await createContext("one\ntwo\nthree\nfour")
|
|
90
|
+
);
|
|
91
|
+
(0, import_vitest.expect)(result).toMatchObject({
|
|
92
|
+
content: "two\nthree",
|
|
93
|
+
lines: 2,
|
|
94
|
+
encoding: "utf-8",
|
|
95
|
+
truncated: true,
|
|
96
|
+
size: Buffer.byteLength("two\nthree", "utf-8")
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
(0, import_vitest.it)("normalizes workspace-contained absolute paths before reading", async () => {
|
|
100
|
+
const readText = import_vitest.vi.fn(async () => "alpha");
|
|
101
|
+
const tool = (0, import_read_file_tool.createReadFileTool)(import_vitest.vi.fn());
|
|
102
|
+
await tool.execute(
|
|
103
|
+
{ file_path: import_node_path.default.join("/repo", "local.txt") },
|
|
104
|
+
await createContext("alpha", readText)
|
|
105
|
+
);
|
|
106
|
+
(0, import_vitest.expect)(readText).toHaveBeenCalledWith("local.txt");
|
|
107
|
+
});
|
|
108
|
+
(0, import_vitest.it)("rejects external absolute paths before file provider calls", async () => {
|
|
109
|
+
const readText = import_vitest.vi.fn(async () => "alpha");
|
|
110
|
+
const tool = (0, import_read_file_tool.createReadFileTool)(import_vitest.vi.fn());
|
|
111
|
+
await (0, import_vitest.expect)(
|
|
112
|
+
tool.execute(
|
|
113
|
+
{ file_path: "/outside/local.txt" },
|
|
114
|
+
await createContext("alpha", readText)
|
|
115
|
+
)
|
|
116
|
+
).rejects.toMatchObject({ code: import_core.ToolErrorCode.VALIDATION_FAILED });
|
|
117
|
+
(0, import_vitest.expect)(readText).not.toHaveBeenCalled();
|
|
118
|
+
});
|
|
119
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read-file-tool.test.d.ts","sourceRoot":"","sources":["../src/read-file-tool.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { AgentEventBus, createLogger, ToolErrorCode, WorkspaceManager } from "@dexto/core";
|
|
2
|
+
import { InMemoryDextoStores } from "@dexto/core/storage";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { describe, expect, it, vi } from "vitest";
|
|
5
|
+
import { createReadFileTool } from "./read-file-tool.js";
|
|
6
|
+
async function createContext(content, readText = vi.fn(async () => content)) {
|
|
7
|
+
const stores = new InMemoryDextoStores();
|
|
8
|
+
await stores.connect();
|
|
9
|
+
const logger = createLogger({
|
|
10
|
+
agentId: "test-agent",
|
|
11
|
+
config: { level: "error", transports: [{ type: "silent" }] }
|
|
12
|
+
});
|
|
13
|
+
const workspaceManager = new WorkspaceManager(
|
|
14
|
+
stores.getStore("workspaces"),
|
|
15
|
+
new AgentEventBus(),
|
|
16
|
+
logger,
|
|
17
|
+
{
|
|
18
|
+
open: vi.fn(async ({ context }) => ({
|
|
19
|
+
context,
|
|
20
|
+
capabilities: ["files"],
|
|
21
|
+
files: {
|
|
22
|
+
readFile: vi.fn(async () => content),
|
|
23
|
+
readText,
|
|
24
|
+
glob: vi.fn(async () => []),
|
|
25
|
+
writeFile: vi.fn(async () => void 0),
|
|
26
|
+
listFiles: vi.fn(async () => [])
|
|
27
|
+
}
|
|
28
|
+
}))
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
await workspaceManager.setWorkspace({ path: "/repo" });
|
|
32
|
+
return {
|
|
33
|
+
logger,
|
|
34
|
+
services: {
|
|
35
|
+
approval: {},
|
|
36
|
+
search: {},
|
|
37
|
+
resources: {},
|
|
38
|
+
prompts: {},
|
|
39
|
+
skills: {},
|
|
40
|
+
mcp: {},
|
|
41
|
+
taskForker: null,
|
|
42
|
+
workspaceManager
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
describe("read_file tool", () => {
|
|
47
|
+
it("reads text through WorkspaceManager.open", async () => {
|
|
48
|
+
const getFileSystemService = vi.fn(async () => {
|
|
49
|
+
throw new Error("read_file execute must not use FileSystemService");
|
|
50
|
+
});
|
|
51
|
+
const tool = createReadFileTool(getFileSystemService);
|
|
52
|
+
const result = await tool.execute({ file_path: "local.txt" }, await createContext("alpha"));
|
|
53
|
+
expect(getFileSystemService).not.toHaveBeenCalled();
|
|
54
|
+
expect(result).toMatchObject({
|
|
55
|
+
content: "alpha",
|
|
56
|
+
lines: 1,
|
|
57
|
+
encoding: "utf-8",
|
|
58
|
+
truncated: false,
|
|
59
|
+
size: Buffer.byteLength("alpha", "utf-8")
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
it("applies pagination after workspace reads", async () => {
|
|
63
|
+
const tool = createReadFileTool(vi.fn());
|
|
64
|
+
const result = await tool.execute(
|
|
65
|
+
{ file_path: "local.txt", offset: 2, limit: 2 },
|
|
66
|
+
await createContext("one\ntwo\nthree\nfour")
|
|
67
|
+
);
|
|
68
|
+
expect(result).toMatchObject({
|
|
69
|
+
content: "two\nthree",
|
|
70
|
+
lines: 2,
|
|
71
|
+
encoding: "utf-8",
|
|
72
|
+
truncated: true,
|
|
73
|
+
size: Buffer.byteLength("two\nthree", "utf-8")
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
it("normalizes workspace-contained absolute paths before reading", async () => {
|
|
77
|
+
const readText = vi.fn(async () => "alpha");
|
|
78
|
+
const tool = createReadFileTool(vi.fn());
|
|
79
|
+
await tool.execute(
|
|
80
|
+
{ file_path: path.join("/repo", "local.txt") },
|
|
81
|
+
await createContext("alpha", readText)
|
|
82
|
+
);
|
|
83
|
+
expect(readText).toHaveBeenCalledWith("local.txt");
|
|
84
|
+
});
|
|
85
|
+
it("rejects external absolute paths before file provider calls", async () => {
|
|
86
|
+
const readText = vi.fn(async () => "alpha");
|
|
87
|
+
const tool = createReadFileTool(vi.fn());
|
|
88
|
+
await expect(
|
|
89
|
+
tool.execute(
|
|
90
|
+
{ file_path: "/outside/local.txt" },
|
|
91
|
+
await createContext("alpha", readText)
|
|
92
|
+
)
|
|
93
|
+
).rejects.toMatchObject({ code: ToolErrorCode.VALIDATION_FAILED });
|
|
94
|
+
expect(readText).not.toHaveBeenCalled();
|
|
95
|
+
});
|
|
96
|
+
});
|
|
@@ -22,21 +22,21 @@ __export(read_media_file_tool_exports, {
|
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(read_media_file_tool_exports);
|
|
24
24
|
var import_zod = require("zod");
|
|
25
|
-
var
|
|
25
|
+
var import_tools = require("@dexto/core/tools");
|
|
26
26
|
var import_directory_approval = require("./directory-approval.js");
|
|
27
27
|
const ReadMediaFileInputSchema = import_zod.z.object({
|
|
28
28
|
file_path: import_zod.z.string().min(1).describe("Absolute path to the image, audio, video, PDF, or binary file to read")
|
|
29
29
|
}).strict();
|
|
30
30
|
function createReadMediaFileTool(getFileSystemService) {
|
|
31
|
-
return (0,
|
|
31
|
+
return (0, import_tools.defineTool)({
|
|
32
32
|
id: "read_media_file",
|
|
33
33
|
aliases: ["read_media"],
|
|
34
34
|
description: "Read an image, audio, video, PDF, or other binary file. Returns MIME-aware base64 data using media/file shapes that multimodal UIs can render directly. Use read_file for UTF-8 text files.",
|
|
35
35
|
inputSchema: ReadMediaFileInputSchema,
|
|
36
36
|
presentation: {
|
|
37
|
-
describeHeader: (input) => (0,
|
|
37
|
+
describeHeader: (input) => (0, import_tools.createLocalToolCallHeader)({
|
|
38
38
|
title: "Read Media",
|
|
39
|
-
argsText: (0,
|
|
39
|
+
argsText: (0, import_tools.truncateForHeader)(input.file_path, 140)
|
|
40
40
|
})
|
|
41
41
|
},
|
|
42
42
|
...(0, import_directory_approval.createDirectoryAccessApprovalHandlers)({
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Internal tool for reading media or binary files as base64 with MIME metadata.
|
|
5
5
|
*/
|
|
6
6
|
import { z } from 'zod';
|
|
7
|
-
import type { Tool } from '@dexto/core';
|
|
7
|
+
import type { Tool } from '@dexto/core/tools';
|
|
8
8
|
import type { FileSystemServiceGetter } from './file-tool-types.js';
|
|
9
9
|
declare const ReadMediaFileInputSchema: z.ZodObject<{
|
|
10
10
|
file_path: z.ZodString;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read-media-file-tool.d.ts","sourceRoot":"","sources":["../src/read-media-file-tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAmB,IAAI,EAAwB,MAAM,
|
|
1
|
+
{"version":3,"file":"read-media-file-tool.d.ts","sourceRoot":"","sources":["../src/read-media-file-tool.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAmB,IAAI,EAAwB,MAAM,mBAAmB,CAAC;AACrF,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAGpE,QAAA,MAAM,wBAAwB;;kBAOjB,CAAC;AAEd,wBAAgB,uBAAuB,CACnC,oBAAoB,EAAE,uBAAuB,GAC9C,IAAI,CAAC,OAAO,wBAAwB,CAAC,CAkEvC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { createLocalToolCallHeader, defineTool, truncateForHeader } from "@dexto/core";
|
|
2
|
+
import { createLocalToolCallHeader, defineTool, truncateForHeader } from "@dexto/core/tools";
|
|
3
3
|
import { createDirectoryAccessApprovalHandlers, resolveFilePath } from "./directory-approval.js";
|
|
4
4
|
const ReadMediaFileInputSchema = z.object({
|
|
5
5
|
file_path: z.string().min(1).describe("Absolute path to the image, audio, video, PDF, or binary file to read")
|
package/dist/tool-factory.cjs
CHANGED
|
@@ -21,7 +21,7 @@ __export(tool_factory_exports, {
|
|
|
21
21
|
fileSystemToolsFactory: () => fileSystemToolsFactory
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(tool_factory_exports);
|
|
24
|
-
var
|
|
24
|
+
var import_tools = require("@dexto/core/tools");
|
|
25
25
|
var import_filesystem_service = require("./filesystem-service.js");
|
|
26
26
|
var import_read_file_tool = require("./read-file-tool.js");
|
|
27
27
|
var import_read_media_file_tool = require("./read-media-file-tool.js");
|
|
@@ -52,7 +52,7 @@ const fileSystemToolsFactory = {
|
|
|
52
52
|
const createScopedFileSystemService = (context, baseConfig) => {
|
|
53
53
|
const approvalManager = context.services?.approval;
|
|
54
54
|
if (!approvalManager) {
|
|
55
|
-
throw
|
|
55
|
+
throw import_tools.ToolError.configInvalid(
|
|
56
56
|
"filesystem-tools requires ToolExecutionContext.services.approval"
|
|
57
57
|
);
|
|
58
58
|
}
|
package/dist/tool-factory.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ToolError } from "@dexto/core";
|
|
1
|
+
import { ToolError } from "@dexto/core/tools";
|
|
2
2
|
import { FileSystemService } from "./filesystem-service.js";
|
|
3
3
|
import { createReadFileTool } from "./read-file-tool.js";
|
|
4
4
|
import { createReadMediaFileTool } from "./read-media-file-tool.js";
|
package/dist/types.d.ts
CHANGED
|
@@ -172,8 +172,6 @@ export interface SearchResult {
|
|
|
172
172
|
* Options for writing files
|
|
173
173
|
*/
|
|
174
174
|
export interface WriteFileOptions {
|
|
175
|
-
/** Create parent directories if they don't exist */
|
|
176
|
-
createDirs?: boolean | undefined;
|
|
177
175
|
/** File encoding (default: utf-8) */
|
|
178
176
|
encoding?: BufferEncoding | undefined;
|
|
179
177
|
/** Create backup before overwriting */
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var workspace_paths_exports = {};
|
|
30
|
+
__export(workspace_paths_exports, {
|
|
31
|
+
assertWorkspaceRelativeGlob: () => assertWorkspaceRelativeGlob,
|
|
32
|
+
isWorkspaceFileNotFound: () => isWorkspaceFileNotFound,
|
|
33
|
+
toWorkspaceRelativePath: () => toWorkspaceRelativePath
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(workspace_paths_exports);
|
|
36
|
+
var import_node_path = __toESM(require("node:path"), 1);
|
|
37
|
+
var import_errors = require("@dexto/core/errors");
|
|
38
|
+
var import_workspace = require("@dexto/core/workspace");
|
|
39
|
+
var import_tools = require("@dexto/core/tools");
|
|
40
|
+
function toWorkspaceRelativePath(toolName, workspaceRoot, filePath) {
|
|
41
|
+
if (!import_node_path.default.isAbsolute(filePath)) {
|
|
42
|
+
assertRelativePath(toolName, filePath);
|
|
43
|
+
return filePath.split(import_node_path.default.sep).join("/");
|
|
44
|
+
}
|
|
45
|
+
const relativePath = import_node_path.default.relative(workspaceRoot, filePath);
|
|
46
|
+
if (relativePath === "") {
|
|
47
|
+
return ".";
|
|
48
|
+
}
|
|
49
|
+
if (relativePath.startsWith("..") || import_node_path.default.isAbsolute(relativePath)) {
|
|
50
|
+
throw import_tools.ToolError.validationFailed(
|
|
51
|
+
toolName,
|
|
52
|
+
`Path must be inside the active workspace: ${filePath}`,
|
|
53
|
+
{ file_path: filePath, workspaceRoot }
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
return relativePath.split(import_node_path.default.sep).join("/");
|
|
57
|
+
}
|
|
58
|
+
function isWorkspaceFileNotFound(error) {
|
|
59
|
+
if (error instanceof import_errors.DextoRuntimeError && error.code === import_workspace.WorkspaceErrorCodes.FILE_NOT_FOUND) {
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
return typeof error === "object" && error !== null && "code" in error && error.code === import_workspace.WorkspaceErrorCodes.FILE_NOT_FOUND;
|
|
63
|
+
}
|
|
64
|
+
function assertWorkspaceRelativeGlob(toolName, pattern) {
|
|
65
|
+
if (import_node_path.default.isAbsolute(pattern) || pattern.split(/[\\/]/).includes("..")) {
|
|
66
|
+
throw import_tools.ToolError.validationFailed(
|
|
67
|
+
toolName,
|
|
68
|
+
`Glob pattern must stay inside the active workspace: ${pattern}`,
|
|
69
|
+
{ pattern }
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function assertRelativePath(toolName, filePath) {
|
|
74
|
+
if (filePath.split(/[\\/]/).includes("..")) {
|
|
75
|
+
throw import_tools.ToolError.validationFailed(
|
|
76
|
+
toolName,
|
|
77
|
+
`Path must stay inside the active workspace: ${filePath}`,
|
|
78
|
+
{ file_path: filePath }
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
83
|
+
0 && (module.exports = {
|
|
84
|
+
assertWorkspaceRelativeGlob,
|
|
85
|
+
isWorkspaceFileNotFound,
|
|
86
|
+
toWorkspaceRelativePath
|
|
87
|
+
});
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare function toWorkspaceRelativePath(toolName: string, workspaceRoot: string, filePath: string): string;
|
|
2
|
+
export declare function isWorkspaceFileNotFound(error: unknown): boolean;
|
|
3
|
+
export declare function assertWorkspaceRelativeGlob(toolName: string, pattern: string): void;
|
|
4
|
+
//# sourceMappingURL=workspace-paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-paths.d.ts","sourceRoot":"","sources":["../src/workspace-paths.ts"],"names":[],"mappings":"AAKA,wBAAgB,uBAAuB,CACnC,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,GACjB,MAAM,CAkBR;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAU/D;AAED,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAQnF"}
|