# Function kinds

URL: /code/function-kinds · Id: `page:code/function-kinds`

> One Verb, `Lease.notify`, written in each kind a Function takes, so the choice of kind changes no caller.

A [Function](/business/nouns/function) runs a [Verb](/business/nouns/verb) as code, a model call, an [Agent](/business/nouns/agent) or a [Human](/business/nouns/human) [Task](/business/nouns/task). Leaseline declares a `Lease` [Noun](/business/nouns/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](/business/nouns/template) and the lease's own fields.

```ts title="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.

```ts
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](/business/nouns/tool), each a Verb under its [Limits](/business/nouns/limit). The [Success Manager](/agents/customer/success-manager) agent writes the notice this way.

```ts
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](/business/nouns/role) as a Task, with a form generated from the Verb. A cascade tries each kind in order; `ctx.decline` passes to the next.

```ts
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](/business/nouns/action) with its input, output, cost and Function [Version](/business/nouns/version). Swapping one kind for another changes no caller. [Functions](/code/platform/functions) lists what each kind declares.