openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
96 lines (95 loc) • 3.93 kB
JavaScript
import { C as parseStrictNonNegativeInteger } from "./number-coercion-CLj0HTDM.js";
import { a as wrapExternalContent } from "./external-content-CpqslxXH.js";
import "./number-runtime-Cy4drVnh.js";
import "./security-runtime-Ckf0kc0h.js";
import { a as DIR_LIST_TOOL_DESCRIPTOR, i as DIR_LIST_HARD_MAX_ENTRIES } from "./descriptors-Cun0f4Hd.js";
import { t as appendFileTransferAudit } from "./audit-Cw95_l64.js";
import { i as readClampedInt, n as readRequiredNodePath, t as invokeNodeToolPayload } from "./node-tool-invoke-CBLfLEy7.js";
//#region extensions/file-transfer/src/tools/dir-list-tool.ts
const DIRECTORY_TEXT_MAX_BYTES = 8192;
function directoryListingText(canonicalPath, entries, pageToken, nextPageToken, truncated) {
const offset = parseStrictNonNegativeInteger(pageToken) ?? 0;
const visible = [];
const render = () => {
const limited = visible.length < entries.length;
const continuation = limited ? visible.length > 0 ? String(offset + visible.length) : void 0 : nextPageToken;
const listing = JSON.stringify({
path: canonicalPath,
returnedCount: entries.length,
displayedCount: visible.length,
entries: visible,
truncated: limited || truncated,
nextPageToken: continuation
});
const note = limited && visible.length === 0 ? "No entries displayed: the next complete entry or directory metadata exceeds the text budget or contains reserved markers. Pagination cannot advance; use available node-local directory capabilities." : (limited || truncated) && !continuation ? "More entries available; the node supplied no continuation token." : "If present, pass nextPageToken as pageToken; keep node and path.";
const wrapped = wrapExternalContent(`${listing}\n${note}`, { source: "unknown" });
return wrapped.includes(listing) && Buffer.byteLength(wrapped, "utf8") <= DIRECTORY_TEXT_MAX_BYTES ? wrapped : void 0;
};
let text = render();
for (const { name, isDir, size } of entries) {
visible.push({
name,
isDir,
size
});
const candidate = render();
if (!candidate) break;
text = candidate;
}
return text ?? wrapExternalContent("Directory listing omitted: the canonical path or continuation metadata cannot be represented safely within the 8192-byte text limit. No usable paths or continuation token are shown; use available node-local directory capabilities.", { source: "unknown" });
}
function createDirListTool() {
return {
...DIR_LIST_TOOL_DESCRIPTOR,
execute: async (_toolCallId, args) => {
const params = args;
const { node, requestedPath: dirPath } = readRequiredNodePath(params);
const maxEntries = readClampedInt({
input: params,
key: "maxEntries",
defaultValue: 200,
hardMin: 1,
hardMax: DIR_LIST_HARD_MAX_ENTRIES
});
const pageToken = typeof params.pageToken === "string" && params.pageToken.trim() ? params.pageToken.trim() : void 0;
const { nodeId, nodeDisplayName, payload, startedAt } = await invokeNodeToolPayload({
node,
params,
command: "dir.list",
commandParams: {
path: dirPath,
pageToken,
maxEntries
},
requestedPath: dirPath
});
const canonicalPath = typeof payload.path === "string" ? payload.path : dirPath;
const entries = Array.isArray(payload.entries) ? payload.entries : [];
const truncated = payload.truncated === true;
const nextPageToken = typeof payload.nextPageToken === "string" ? payload.nextPageToken : void 0;
await appendFileTransferAudit({
op: "dir.list",
nodeId,
nodeDisplayName,
requestedPath: dirPath,
canonicalPath,
decision: "allowed",
durationMs: Date.now() - startedAt
});
return {
content: [{
type: "text",
text: directoryListingText(canonicalPath, entries, pageToken, nextPageToken, truncated)
}],
details: {
path: canonicalPath,
entries,
nextPageToken,
truncated
}
};
}
};
}
//#endregion
export { createDirListTool };