@sema-agent/core
Version:
Stateless, task-oriented AI agent core
66 lines (65 loc) • 2.5 kB
JavaScript
import { FileError } from "../../internal/harness.js";
import { HomeViewUnreadError, homeViewsOf } from "./read-deny-home.js";
import { DATA_LABEL_UNSAFE, quoteDataLabel } from "../../internal/llm.js";
export const DIRECTORY_LISTING_MAX_ENTRIES = 1000;
export function createEntryDenyJudge(env, deny, signal) {
const views = homeViewsOf(env, deny, signal);
return async (path, leaf) => {
const hit = deny.matchPath(path);
if (hit)
return hit;
const home = await views.of(path, leaf !== undefined ? { leaf } : undefined);
const viewHit = home.view !== undefined ? deny.matchPath(home.view) : null;
if (viewHit === null && home.unread !== undefined)
throw new HomeViewUnreadError(path, home.unread);
return viewHit;
};
}
export async function enumerateDirectory(env, dir, judge, signal, list = (d) => env.listDir(d, signal)) {
const listing = await list(dir);
if (!listing.ok)
return listing;
const infos = [...listing.value].sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
const kept = [];
let omitted = 0;
const omittedPatterns = [];
let incomplete = false;
for (const info of infos) {
if (signal?.aborted) {
incomplete = true;
break;
}
let hit;
try {
hit = judge === undefined ? null : await judge(info.path, info.kind === "directory" ? undefined : "file");
}
catch (e) {
if (e instanceof HomeViewUnreadError)
return { ok: false, error: new FileError("unknown", e.message, info.path) };
throw e;
}
if (hit) {
omitted++;
if (!omittedPatterns.includes(hit.pattern))
omittedPatterns.push(hit.pattern);
continue;
}
kept.push({ name: info.name, kind: info.kind });
}
return {
ok: true,
value: {
entries: kept.slice(0, DIRECTORY_LISTING_MAX_ENTRIES),
more: Math.max(0, kept.length - DIRECTORY_LISTING_MAX_ENTRIES),
omitted,
omittedPatterns,
incomplete,
},
};
}
export function renderDirectoryListing(l) {
const lines = l.entries.map((e) => `${DATA_LABEL_UNSAFE.test(e.name) ? quoteDataLabel(e.name) : e.name}${e.kind === "directory" ? "/" : ""}`);
if (l.more > 0)
lines.push(`… and ${l.more} more entries`);
return lines.join("\n");
}