import { z } from "zod";
import { defineContract } from "@withboundary/contract";
const contract = defineContract({
name: "lead-scoring",
schema: z.object({
tier: z.enum(["hot", "warm", "cold"]),
score: z.number().min(0).max(100),
reason: z.string(),
}),
rules: [
{
name: "hot_requires_high_score",
description: "Hot leads must have a score of at least 70",
fields: ["tier", "score"],
check: (lead) =>
lead.tier !== "hot" || lead.score >= 70
|| `tier is "hot" but score is ${lead.score} (minimum 70 for hot)`,
},
{
name: "reason_required",
description: "Every scoring decision must have a non-empty reason",
fields: ["reason"],
check: (lead) =>
lead.reason.trim().length > 0 || "reason cannot be empty",
},
],
retry: { maxAttempts: 3 },
repairs: {
REFUSAL: false, // don't retry on refusal
},
});
const result = await contract.accept(async (attempt) => {
const response = await callYourLLM({
messages: [
{
role: "user",
content: [
"Score this lead as JSON.",
attempt.instructions,
leadSummary,
].join("\n\n"),
},
...attempt.repairs,
],
});
return response.text;
});