@sema-agent/core
Version:
Stateless, task-oriented AI agent core
79 lines (78 loc) • 5 kB
JavaScript
import { formatLocalDate } from "../../prompts/default.js";
import { SKILL_TOOL_NAME } from "./synthetic-tools.js";
import { renderAgentListingDelta } from "./turn-attachments.js";
export function prepareListings(input) {
const { spec, tools, onceLedger, sessionId, toolFaceSnapshot, activeTools, resume, skillsListing, listingBudget, listingRideRef, renderWithDate, envFacts, tzValid, userTz, dateAnchor } = input;
if (spec.agents !== undefined && spec.agents.length > 0) {
const known = new Set(tools.flatMap((t) => [t.name, ...(t.aliases ?? [])]));
for (const def of spec.agents) {
const unknownAllow = (def.allowTools ?? []).filter((n) => n !== "*" && !known.has(n));
if (unknownAllow.length > 0) {
try {
onceLedger.onError(new Error(`TaskSpec.agents: agent "${def.name}" allows tool(s) ${unknownAllow.join(", ")} not present in this task's assembled roster — likely a typo (the entry would be item-filtered at spawn; the agent stays usable). Advisory only: the delegation pool can differ from this roster, so a tool mounted only on the delegation tool or produced by per-spawn extraTools makes this spurious.`), { phase: "config", sessionId });
}
catch {
}
}
for (const n of def.denyTools ?? []) {
if (n === "*")
continue;
if (!known.has(n)) {
const e = new Error(`TaskSpec.agents: agent "${def.name}" declares tool "${n}" in its denied tools, but no such tool exists in this deployment — fix the agent's tools list or mount the tool.`);
e.code = "config.agent.unknown_tool";
throw e;
}
}
}
}
const rosterBearingSpec = (spec.tools ?? []).find((t) => t.agentListing !== undefined && t.agentListing.length > 0);
const rosterFaceDeferred = rosterBearingSpec !== undefined &&
!(toolFaceSnapshot.exclude?.includes(rosterBearingSpec.name) ?? false) &&
(toolFaceSnapshot.defer?.includes(rosterBearingSpec.name) ?? false) &&
!activeTools.has(rosterBearingSpec.name);
const agentListingSpec = rosterBearingSpec !== undefined &&
!rosterFaceDeferred &&
!(toolFaceSnapshot.exclude?.includes(rosterBearingSpec.name) ?? false)
? rosterBearingSpec
: undefined;
const agentListing = agentListingSpec
? {
entries: agentListingSpec.agentListing,
toolName: agentListingSpec.name,
budget: listingBudget,
seedAnnounced: resume !== undefined || spec.sessionId !== undefined,
...(agentListingSpec.agentModels !== undefined ? { models: agentListingSpec.agentModels } : {}),
}
:
!rosterFaceDeferred && ((resume?.seed.announcedListings?.agents?.length ?? 0) > 0 || spec.sessionId !== undefined)
?
{
entries: [],
toolName: (spec.tools ?? []).find((t) => t.agentListing !== undefined)?.name ?? "Agent",
budget: listingBudget,
seedAnnounced: true,
}
: undefined;
if (spec.attachments?.agentListing === false && agentListing !== undefined && agentListing.entries.length > 0) {
onceLedger.onError(new Error(`attachments.agentListing is explicitly false but the "${agentListing.toolName}" delegation tool mounts a ${agentListing.entries.length}-type roster — the model will never see the agent-type listing its tool description points to.`), { phase: "config", sessionId });
}
if (spec.attachments?.skillsListing === false && skillsListing !== undefined && skillsListing.entries.length > 0) {
onceLedger.onError(new Error(`attachments.skillsListing is explicitly false but ${skillsListing.entries.length} skill(s) are mounted — the model will never see the skills listing the ${SKILL_TOOL_NAME} tool description points to.`), { phase: "config", sessionId });
}
const announcedListingsRef = onceLedger.arms();
if (rosterFaceDeferred && rosterBearingSpec !== undefined) {
const rideEntries = rosterBearingSpec.agentListing;
const rideModels = rosterBearingSpec.agentModels;
listingRideRef.current = (newly) => {
if (!newly.includes(rosterBearingSpec.name))
return undefined;
if ((announcedListingsRef.agents?.length ?? 0) > 0)
return undefined;
return renderAgentListingDelta({ announcedAgentTypes: undefined }, rideEntries, rosterBearingSpec.name, rideModels, listingBudget);
};
}
const dateChange = renderWithDate
? { legDate: envFacts.date, today: () => formatLocalDate(new Date(), tzValid ? userTz : undefined), anchor: dateAnchor }
: undefined;
return { agentListing, announcedListingsRef, dateChange };
}