Function kinds
One Verb, Lease.notify, written in each kind a Function takes, so the choice of kind changes no caller.
A Function runs a Verb as code, a model call, an Agent or a Human Task. Leaseline declares a Lease Noun, and its Lease.notify reads the same to every caller whichever kind runs it.
Code
Code is deterministic: the notice comes from a Template and the lease's own fields.
export default async (lease: Lease, input: LeaseNotifyInput, $: $) =>
$.Message.create({ medium: 'email', direction: 'outbound', to: lease.resident, body: `Your lease for ${lease.unit} ends ${lease.endsOn}. Reply to renew.` })A model call
A generative Function makes one model call that writes the notice from its instructions.
import { fn } from 'startup-builder'
export default fn('Lease.notify', {
kind: 'generative',
instructions: 'Write a two-sentence renewal notice. State the end date. Never state a rent the manager has not set.',
model: 'write',
})An agent
An agentic Function plans over several steps and calls Tools, each a Verb under its Limits. The Success Manager agent writes the notice this way.
import { fn } from 'startup-builder'
export default fn('Lease.notify', {
kind: 'agentic',
instructions: 'Write the renewal notice from the renewal-notice Template. State the end date and the new rent.',
tools: ['Lease.get', 'Message.schedule'],
model: 'write',
maxSteps: 8,
budget: { amount: 0.5, currency: 'USD' },
})A person, and a cascade
A human Function gives the work to a Role as a Task, with a form generated from the Verb. A cascade tries each kind in order; ctx.decline passes to the next.
import { fn } from 'startup-builder'
export default fn('Lease.notify', {
cascade: ['code', 'human'],
async code({ lease }, ctx) {
const found = await ctx.$.Lease.get({ id: lease })
if (!found.resident) return ctx.decline('The lease has no resident to notify')
await ctx.$.Message.create({ medium: 'email', direction: 'outbound', to: found.resident, body: `Your lease for ${found.unit} ends ${found.endsOn}.` })
return found
},
role: 'customer/ success-manager',
sla: 'PT4H',
})Every kind returns one Action with its input, output, cost and Function Version. Swapping one kind for another changes no caller. Functions lists what each kind declares.