@sema-agent/core
Version:
Stateless, task-oriented AI agent core
57 lines (56 loc) • 3.14 kB
JavaScript
import { programRows } from "../tools/fs/program-read-model.js";
import { DURATION_SPELLING } from "../tools/fs/program-read-model.rows.js";
export function shellWrapperProjection() {
const out = {};
for (const row of programRows()) {
const projected = projectRow(row);
if (projected !== undefined)
out[row.key] = projected;
}
return out;
}
function spellings(row) {
const out = new Map();
for (const g of row.grammars) {
const add = (spelling, spec) => {
const e = out.get(spelling) ?? { spec, arities: new Set() };
e.arities.add(spec.arity);
out.set(spelling, e);
};
for (const [l, spec] of Object.entries(g.short))
add(`-${l}`, spec);
for (const [n, spec] of Object.entries(g.long))
add(`--${n}`, spec);
for (const [n, spec] of Object.entries(g.dashWords ?? {}))
add(`-${n}`, spec);
}
return [...out].map(([spelling, e]) => ({ spelling, spec: e.spec, arity: e.arities.size === 1 ? [...e.arities][0] : "disputed" }));
}
const runsCommand = (spec) => spec.effect === "executes" || spec.value?.kind === "shell-text" || spec.value?.kind === "command";
function projectRow(row) {
const sorted = (xs) => [...new Set(xs)].sort();
const all = spellings(row);
const viaShell = row.reentry?.kind === "shell" || row.launcher?.shellText !== undefined || row.body === "first-operand" || row.body === "assignment-values" || (row.operands?.rest?.kind === "program-text" && row.operands.rest.language === "arithmetic");
if (row.launcher === undefined) {
if (viaShell)
return { valueFlags: [], flags: [], commandString: [], viaShell: true };
const executes = sorted(all.filter((o) => runsCommand(o.spec)).map((o) => o.spelling));
return executes.length > 0 ? { valueFlags: [], flags: [], commandString: [], executes } : undefined;
}
const commandString = sorted(all.filter((o) => o.spec.value?.kind === "shell-text").map((o) => o.spelling));
const values = all.filter((o) => o.spec.value?.kind !== "shell-text" && o.spec.mode !== "queries");
const attached = sorted(values.filter((o) => o.arity === "attached" && !o.spelling.startsWith("--")).map((o) => o.spelling));
const required = row.launcher.requiredOperands ?? 0;
const duration = required > 0 && row.launcher.requiredOperandSpelling === DURATION_SPELLING;
return {
valueFlags: sorted(values.filter((o) => o.arity === 1).map((o) => o.spelling)),
flags: sorted(values.filter((o) => o.arity === 0 || (o.arity === "attached" && o.spelling.startsWith("--"))).map((o) => o.spelling)),
...(attached.length > 0 ? { attached } : {}),
commandString,
...(required > 0 && !duration ? { positional: row.launcher.requiredOperandSpelling ?? /^/ } : {}),
...(duration ? { duration: true } : {}),
...(row.launcher.bareDash === true ? { bareDash: true } : {}),
...(row.launcher.assignmentOperands === true ? { assignments: true } : {}),
...(viaShell ? { viaShell: true } : {}),
};
}