@sema-agent/core
Version:
Stateless, task-oriented AI agent core
53 lines (52 loc) • 3.97 kB
JavaScript
import { ORG_ADJUDICATION_TIMEOUT_MS } from "../permission-rule-org.js";
import { createSyntheticWriteJudge } from "../synthetic-read-verdict.js";
import { CONSOLIDATION_WRITE_REFUSED_CODE } from "../memory-engine/consolidation-driver.js";
import { ConsolidationRefusedError } from "../memory-engine/consolidation.js";
import { memoryConsolidationRefusedNotice } from "../memory-engine/engine.js";
import { deliverEngineNotice } from "../engine-notice.js";
import { toolPolicyPathRules } from "../tool-policy.js";
import { RosterBuilder, toolCallFaceOf } from "../tool-roster.js";
import { createHeadLeads } from "../path-rule-binding.js";
import { legCallTargetStamp } from "../effective-path-target.js";
import { createWriteFileTool } from "../../tools/fs/fs-write.js";
import { whereItsAnsweredPrefixLeads } from "../../tools/fs/read-deny-home.js";
import { NodeExecutionEnv } from "../../engine/execution-env/node-execution-env.js";
import { ASK_USER_QUESTION_TOOL_NAME } from "../ask-question.js";
import { createPermissionRuleLanes } from "./permission-rule-lanes.js";
import { createPersonPathRows } from "./person-path-rows.js";
const noLine = () => undefined;
let engineWrite;
function engineWriteFace() {
if (engineWrite === undefined) {
const roster = new RosterBuilder(new Map());
roster.mount(createWriteFileTool(new NodeExecutionEnv({ cwd: "/" }), new Map(), "/"), { source: "builtin", mountedBy: "hands" });
engineWrite = toolCallFaceOf(roster.snapshot({ effects: new Map(), egress: new Set(), irreversibilityTier: new Map(), reversibilityProbes: new Map(), deferred: new Set(), trustedTools: new Set() }), "Write");
}
return engineWrite;
}
export function createConsolidationWriteJudge(input, leg) {
const owner = { provider: input.ruleStoreProvider, localOwnerDeclared: input.localOwnerDeclared === true, principal: input.principal };
const { rows, lanes, layers, facts } = leg ?? hostLeg(input, owner);
const { personal, org } = createPermissionRuleLanes({ ...owner, ...lanes, rows });
const judge = createSyntheticWriteJudge({ ...layers, ...(input.callerPolicy !== undefined ? { callerPolicy: input.callerPolicy } : {}), ...(personal !== undefined ? { persistedRuleLane: personal } : {}), ...(org !== undefined ? { orgRuleLane: org } : {}) }, facts);
return (target) => judge({ file_path: target.path }, "memory-consolidation", { deadlineAt: Date.now() + ORG_ADJUDICATION_TIMEOUT_MS });
}
function hostLeg(input, owner) {
const { root, home } = input.anchors ?? {};
const env = input.executionEnv ?? new NodeExecutionEnv({ cwd: root ?? "/" });
const leads = createHeadLeads((part) => whereItsAnsweredPrefixLeads(env, part));
const chainTop = { ...(root !== undefined ? { root } : {}), ...(home !== undefined ? { home } : {}) };
const sessionId = input.sessionId;
return {
rows: createPersonPathRows({ ...owner, sessionId, root, rootCanonical: undefined, leads, chainTop, onDisclosure: noLine, onUnread: noLine, onRowsDropped: noLine }),
lanes: { sessionId, root, rootCanonical: undefined, chainTop, leads, liveCwd: () => root, home, questionToolMounted: false, questionToolName: ASK_USER_QUESTION_TOOL_NAME, onRevisionDefect: noLine, onDisclosure: noLine },
layers: { stampCallTarget: legCallTargetStamp({ env, root: root ?? "/", cwd: () => root, judgesPaths: () => true, leads: () => leads.resolve(toolPolicyPathRules([input.callerPolicy], chainTop)) }) },
facts: () => ({ face: engineWriteFace(), ...(root !== undefined ? { root, cwd: root } : {}) }),
};
}
export function deliverWriteRefusal(err, scope, onNotice) {
if (!(err instanceof ConsolidationRefusedError) || err.code !== CONSOLIDATION_WRITE_REFUSED_CODE)
return false;
deliverEngineNotice(onNotice, memoryConsolidationRefusedNotice({ code: CONSOLIDATION_WRITE_REFUSED_CODE, scope, reason: err.message, occurrenceId: err.occurrenceId }));
return true;
}