@sema-agent/core
Version:
Stateless, task-oriented AI agent core
30 lines (29 loc) • 1.94 kB
JavaScript
import { lexShell, literalTextOf } from "../../shell/lex.js";
import { readProgramPosition } from "./bash-program-position.js";
import { SPECIAL_BUILTINS, projectSegment } from "./shell-read-bindings.js";
import { reentryText } from "./shell-reentry-text.js";
export function functionCallOf(argv, functions, stateOf = () => "maybe") {
const pos = readProgramPosition(argv);
const headAt = pos.launchers[0]?.index ?? pos.program?.index;
if (headAt === undefined || functions.size === 0)
return undefined;
const stateOfWord = (w) => (w.pieces.some((p) => p.expansion !== undefined || p.literal === undefined) ? ([...functions].some((name) => stateOf(name) !== "absent") ? "maybe" : "absent") : functions.has(w.folded) ? stateOf(w.folded) : "absent");
const headWord = argv[headAt];
const head = stateOfWord(headWord);
if (head !== "absent")
return head === "defined" && !SPECIAL_BUILTINS.has(headWord.folded) ? "named" : "maybe";
if (pos.program === undefined || pos.launchers.length === 0 || pos.launchers.some((l) => l.name === "builtin" || l.name === "command"))
return undefined;
return stateOfWord(argv[pos.program.index]) === "absent" ? undefined : "maybe";
}
export function evalDefinedFunctions(argvs, depth = 0) {
return depth > 4 ? [] : argvs.flatMap((argv) => {
const pos = readProgramPosition(argv);
const words = pos.program?.basename === "eval" ? argv.slice(pos.program.index + 1).map((w) => literalTextOf(w.pieces)) : [];
const lexed = words.length > 0 && words.every((t) => t !== undefined) ? lexShell(reentryText("eval", words) ?? "") : undefined;
if (lexed === undefined || "parseFailure" in lexed)
return [];
const inner = lexed.segments.map((segment) => projectSegment(segment));
return [...inner.flatMap((p) => p.defines), ...evalDefinedFunctions(inner.map((p) => p.argv), depth + 1)];
});
}