UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

53 lines (52 loc) • 3.97 kB
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; }