Skip to content

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.

nouns/Lease.notify.ts
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.

TypeScript
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.

TypeScript
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.

TypeScript
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.