@sema-agent/core
Version:
Stateless, task-oriented AI agent core
69 lines (68 loc) • 4.86 kB
JavaScript
import { readArtifactHostCapabilities } from "../artifact-host.js";
import { ARTIFACT_TOOL_NAME } from "../tool-catalog-entries.js";
import { deliverEngineNotice } from "../engine-notice.js";
import { RosterBuilder } from "../tool-roster.js";
import { defineTool } from "../tools.js";
import { inlineUntrusted } from "../untrusted-text.js";
import { physicalPathOfExisting } from "../physical-path.js";
import { resolveKey, rootAdmittingArtifactStore, violationDetails, violationText } from "../../tools/fs/safety.js";
import { createArtifactTool } from "../../tools/artifact/artifact-tool.js";
import { thrownText } from "../thrown-value.js";
export function prepareArtifact(input) {
const { deps, runId, taskId, sessionId, agentName, onAsk: approver, toolOccurrences, permissionMode, executionEnv, rootCanonical, additionalRootsCanonical, readDenyMatcher, resolvedReadFace, handsCwdRef, roster, firstPartyOffload, envHandToolNames, artifactStoreRef } = input;
const host = deps.artifactHost;
if (host === undefined)
return { artifactPlane: undefined };
const refuse = (problem) => {
deliverEngineNotice(deps.onNotice, {
code: "config.artifact_host_invalid",
message: `RunnerDeps.artifactHost is wired but unusable, so no Artifact tool is mounted for this task: ${problem}`,
detail: { problem, sessionId, runId },
});
return { artifactPlane: undefined };
};
const verdict = readArtifactHostCapabilities(host);
if (!verdict.ok)
return refuse(verdict.problem);
const storageDir = verdict.capabilities.storageDir;
const storePhysical = storageDir !== undefined && rootCanonical !== undefined ? physicalPathOfExisting(storageDir) : undefined;
if (artifactStoreRef !== undefined)
artifactStoreRef.current = storePhysical;
if (storePhysical !== undefined && rootCanonical !== undefined) {
const overlapping = rootAdmittingArtifactStore(storePhysical, [rootCanonical, ...additionalRootsCanonical()]);
if (overlapping !== undefined)
return refuse(`the local artifact store ${storageDir} and a root this run may reach through its file tools (${overlapping}) overlap — the store lies inside a root, or the root inside the store; put the store outside every task root and additional directory`);
}
try {
host.onMount?.(runId);
}
catch (err) {
return refuse(`artifactHost.onMount threw: ${thrownText(err)}`);
}
const readLocalFile = async (path, maxBytes, signal) => {
if (rootCanonical === undefined)
return { ok: false, reason: "refused", text: "Error (Artifact): this task has no filesystem root, so a local file cannot be published." };
await additionalRootsCanonical.ready(signal);
const rk = await resolveKey(executionEnv, rootCanonical, path, signal, handsCwdRef?.current, additionalRootsCanonical, undefined, readDenyMatcher, resolvedReadFace);
if (!rk.ok)
return { ok: false, reason: "refused", text: violationText("Artifact", rk.violation), details: violationDetails(rk.violation) };
const meta = await executionEnv.fileInfo(rk.key, signal);
if (!meta.ok)
return { ok: false, reason: "refused", text: `Error (Artifact): cannot stat ${inlineUntrusted(path, 200)} (${inlineUntrusted(meta.error.code, 40)}).` };
if (meta.value.kind !== "file")
return { ok: false, reason: "not_a_file", kind: meta.value.kind };
if (meta.value.size > maxBytes)
return { ok: false, reason: "too_large", size: meta.value.size, limit: maxBytes, judgedOn: "metadata" };
const r = await executionEnv.readBinaryFile(rk.key, signal);
if (!r.ok)
return { ok: false, reason: "refused", text: `Error (Artifact): cannot read ${inlineUntrusted(path, 200)} (${inlineUntrusted(r.error.code, 40)}).` };
if (r.value.byteLength > maxBytes)
return { ok: false, reason: "too_large", size: r.value.byteLength, limit: maxBytes, judgedOn: "bytes" };
return { ok: true, key: rk.key, bytes: r.value };
};
const onAsk = typeof approver === "function" ? (req, signal) => toolOccurrences.whileAwaitingUser(req.toolCallId, () => approver(req, signal)) : approver;
const artifactSpec = createArtifactTool({ host, capabilities: verdict.capabilities, runId, taskId, sessionId, ...(agentName !== undefined ? { agentName } : {}), readLocalFile, ...(onAsk !== undefined ? { onAsk } : {}), permissionMode: () => permissionMode.current, ...(deps.onNotice !== undefined ? { onNotice: deps.onNotice } : {}) });
roster.mount(firstPartyOffload(defineTool(artifactSpec)), { source: "builtin", mountedBy: "optional" });
envHandToolNames.add(ARTIFACT_TOOL_NAME);
return { artifactPlane: verdict.capabilities.plane };
}