UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

79 lines (78 loc) • 5 kB
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 }; }