// Underwriting review as a MixtureOfAgents swarm: three specialists score
// their part of a submission in parallel and an aggregator writes the memo.
// The underwriter reads the memo and makes the accept, refer or decline call.
const SWARMS_API = "https://api.swarms.world/v1/swarm/completions"
type Submission = {
applicant: string
propertyType: string
yearBuilt: number
constructionClass: string
zip: string
priorLosses: { year: number; peril: string; paidUsd: number }[]
requestedLimitUsd: number
}
const specialist = (name: string, model: string, focus: string) => ({
agent_name: name,
system_prompt:
"You are a commercial property underwriting analyst. " +
focus +
" Score your area from 1 (favorable) to 5 (adverse), list the facts behind the score and name any guideline that requires referral.",
model_name: model,
max_loops: 1,
})
export async function reviewSubmission(s: Submission) {
const losses = s.priorLosses.map((l) => `${l.year} ${l.peril} $${l.paidUsd.toLocaleString()}`).join("; ") || "none"
const res = await fetch(SWARMS_API, {
method: "POST",
headers: {
"x-api-key": process.env.SWARMS_API_KEY!,
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "Underwriting Submission Review",
swarm_type: "MixtureOfAgents",
task:
`Submission from ${s.applicant}: ${s.propertyType}, built ${s.yearBuilt}, ` +
`construction class ${s.constructionClass}, ZIP ${s.zip}, requested limit $${s.requestedLimitUsd.toLocaleString()}. ` +
`Prior losses: ${losses}. Produce a referral memo with a composite score and the factors that drove it.`,
agents: [
specialist("Property Agent", "gpt-5.4-mini", "Assess age, construction class, roof and systems for the property type."),
specialist("Loss History Agent", "claude-haiku-5-5", "Assess frequency and severity of prior losses against the line's loss ratio targets."),
specialist("Location Agent", "gemini-2.5-flash", "Assess wind, wildfire, flood and crime exposure for the ZIP and the protection class."),
{
agent_name: "Underwriting Aggregator",
system_prompt:
"You are a senior underwriter. Combine the three scores into a composite from 1 to 5, write a one-page referral memo and end with the reasons a human underwriter must review before any quote is issued.",
model_name: "claude-sonnet-5-5", // the memo is the deliverable, so the strongest writer
max_loops: 1,
},
],
max_loops: 1,
}),
})
if (!res.ok) throw new Error(`Swarms API ${res.status}: ${await res.text()}`)
const data = await res.json()
return { memo: data.output as string, usage: data.usage }
}
reviewSubmission({
applicant: "Harbor Street Bakery LLC",
propertyType: "single-story retail with commercial kitchen",
yearBuilt: 1987,
constructionClass: "joisted masonry",
zip: "33139",
priorLosses: [{ year: 2024, peril: "kitchen fire", paidUsd: 42_000 }],
requestedLimitUsd: 1_200_000,
}).then((r) => console.log(r.memo))