@sema-agent/core
Version:
Stateless, task-oriented AI agent core
33 lines (32 loc) • 2.04 kB
JavaScript
function presentAt(at, steps) {
if (steps.length === 0)
return at !== undefined;
if (at === null || (typeof at !== "object" && typeof at !== "function"))
return false;
const [step, ...rest] = steps;
if (!step.endsWith("[]"))
return presentAt(Reflect.get(at, step), rest);
const items = Reflect.get(at, step.slice(0, -2));
return Array.isArray(items) && items.some((item) => presentAt(item, rest));
}
export function retiredKeyOf(bag, table) {
for (const [key, replacement] of Object.entries(table)) {
if (presentAt(bag, key.split(".")))
return { key, replacement };
}
return undefined;
}
export function assertNoRetiredKeys(bag, table, owner) {
const hit = retiredKeyOf(bag, table);
if (hit === undefined)
return;
const e = new Error(`${owner}.${hit.key} is retired and is not read by this engine — ${hit.replacement}. Refused rather than ignored: a seat that is silently dropped reads to the deployment as wired.`);
e.code = owner === "TaskSpec" ? "config.spec_retired_key" : "config.deps_retired_key";
throw e;
}
export const RETIRED_TASK_SPEC_KEYS = Object.freeze({
autoModeRequested: 'the permission mode is one key now — write `permissionMode: "auto"`',
approverPosture: 'a posture never authorized anything; drop the key (the engine renders the posture from the effective mode). Releasing asks is a separate decision: `permissionMode: "bypassPermissions"`',
"attachments.planModeReminder": "the read-only planning posture is stated whenever the leg's mode is `plan` (first turn, every 5 turns, and an exit frame when it ends) — drop the key",
"skills[].manifest": "a skill's tools are its `allowedTools` / `disallowedTools` now — an allow-rule and a deny-rule source for the run the skill is activated in, never a fence; move `manifest.allowTools` to `allowedTools`. To fence tools write deny rules (or a delegated agent definition's `allowTools`); to fence write paths use session `allowDirs`",
});