9. Model success-or-error as a discriminated union
You want the LLM to reliably tell a success response from an error and branch on it โ like a TypeScript discriminated union.
Problem. You want the LLM to reliably tell a success response from an error and branch on it โ like a TypeScript discriminated union.
Solution. Use literal true/false on a shared key. They compile to JSON Schema const.
# @rbs type success = { success: true, applicant_id: String, current_stage: String }
# @rbs type output = success | error # error has success: falseReturn the matching shape from call, and give callers a recoverable error:
def call(applicant_id:, workflow_id:)
applicant = find_applicant(applicant_id)
return not_found_error(applicant_id) unless applicant
{ success: true, applicant_id: applicant_id, current_stage: "screening" }
end
def not_found_error(id)
{
success: false,
error: {
code: "applicant_not_found",
message: "No applicant found with ID #{id}",
hint: "Use fetch_latest_applicant to get a valid ID before retrying."
}
}
endResult. The oneOf carries "success": { "const": true } vs { "const": false }. Clients narrow on it exactly like if (res.success). The hint field is gold for agents โ it tells the model how to recover instead of giving up.
Collected from COOKBOOK.md in the repository. Edit it there, not here.