UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

66 lines (65 loc) • 2.5 kB
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"); }