<commit_before>+++
title = "4. Lifecycle"
weight = 20
template = "doc.html"
+++

In the last lesson we looked at a couple of useful things used as boilerplate in
most agents. Now we're going to get into the guts of how agents work, and start
looking at what the agent arms do. The first thing we'll look at is the agent's
state, and the three arms for managing it: `on-init`, `on-save`, and `on-load`.
These arms handle what we call an agent's "lifecycle".

## Lifecycle

An agent's lifecycle starts when it's first installed. At this point, the
agent's `on-init` arm is called. This is the _only_ time `on-init` is ever
called - its purpose is just to initialize the agent. The `on-init` arm might be
very simple and just set an initial value for the state, or even do nothing at
all and return the agent core exactly as-is. It may also be more complicated,
and perform some [scries](/docs/arvo/concepts/scry) to obtain extra data or
check that another agent is also installed. It might send off some `card`s to
other agents or vanes to do things like load data in to the `%settings-store`
agent, bind an Eyre endpoint, or anything else. It all depends on the needs of
your particular application. If `on-init` fails for whatever reason, the agent
installation will fail and be aborted.

Once initialized, an agent will just go on doing its thing - processing events,
updating its state, producing effects, etc. At some point, you'll likely want to
push an update for your agent. Maybe it's a bug fix, maybe you want to add extra
features. Whatever the reason, you need to change the source code of your agent,
so you commit a modified version of the file to Clay. When the commit completes, Gall updates the app as follows:

- The agent's `on-save` arm is called, which packs the agent's state in a `vase`
  and exports it.
- The new version of the agent is built and loaded into Gall.
- The previously exported `vase` is passed to the `on-load` arm of the newly
  built agent. The `on-load` arm will process it, convert it to the new version
  of the state if necessary, and load it back into the state of the agent.

A `vase` is just a cell of `[type-of-the-noun the-noun]` - it's used extensively
for sending data between agents, vanes and ships. A vase is made with the
[zapgar](/docs/hoon/reference/rune/zap#-zapgar) (`!>`) rune like
`!>(some-data)`, and unpacked with the
[zapgal](/docs/hoon/reference/rune/zap#-zapgal) (`!<`) rune like
`!<(type-to-extract vase)`. Have a read through the [`vase` section of the type
reference for details](/docs/userspace/gall-guide/types#vase).

We'll look at the three arms described here in a little more detail, but first
we need to touch on the state itself.

## Versioned state type

In the previous lesson we introduced the idea of composing additional cores into
the subject of the agent core. Here we'll look at using such a core to define<commit_msg>gall-guide: lifecycle - fix vase explanation<commit_after>+++
title = "4. Lifecycle"
weight = 20
template = "doc.html"
+++

In the last lesson we looked at a couple of useful things used as boilerplate in
most agents. Now we're going to get into the guts of how agents work, and start
looking at what the agent arms do. The first thing we'll look at is the agent's
state, and the three arms for managing it: `on-init`, `on-save`, and `on-load`.
These arms handle what we call an agent's "lifecycle".

## Lifecycle

An agent's lifecycle starts when it's first installed. At this point, the
agent's `on-init` arm is called. This is the _only_ time `on-init` is ever
called - its purpose is just to initialize the agent. The `on-init` arm might be
very simple and just set an initial value for the state, or even do nothing at
all and return the agent core exactly as-is. It may also be more complicated,
and perform some [scries](/docs/arvo/concepts/scry) to obtain extra data or
check that another agent is also installed. It might send off some `card`s to
other agents or vanes to do things like load data in to the `%settings-store`
agent, bind an Eyre endpoint, or anything else. It all depends on the needs of
your particular application. If `on-init` fails for whatever reason, the agent
installation will fail and be aborted.

Once initialized, an agent will just go on doing its thing - processing events,
updating its state, producing effects, etc. At some point, you'll likely want to
push an update for your agent. Maybe it's a bug fix, maybe you want to add extra
features. Whatever the reason, you need to change the source code of your agent,
so you commit a modified version of the file to Clay. When the commit completes, Gall updates the app as follows:

- The agent's `on-save` arm is called, which packs the agent's state in a `vase`
  and exports it.
- The new version of the agent is built and loaded into Gall.
- The previously exported `vase` is passed to the `on-load` arm of the newly
  built agent. The `on-load` arm will process it, convert it to the new version
  of the state if necessary, and load it back into the state of the agent.

A `vase` is just a cell of `[type-of-the-noun the-noun]`. Most data an agent
sends or receives will be encapsulated in a vase. A vase is made with the
[zapgar](/docs/hoon/reference/rune/zap#-zapgar) (`!>`) rune like
`!>(some-data)`, and unpacked with the
[zapgal](/docs/hoon/reference/rune/zap#-zapgal) (`!<`) rune like
`!<(type-to-extract vase)`. Have a read through the [`vase` section of the type
reference for details](/docs/userspace/gall-guide/types#vase).

We'll look at the three arms described here in a little more detail, but first
we need to touch on the state itself.

## Versioned state type

In the previous lesson we introduced the idea of composing additional cores into
the subject of the agent core. Here we'll look at using such a core to define
{'fraction_non_alphanumeric': 0.07425827473846681, 'fraction_numerical': 0.0010289830217801406, 'mean_word_length': 4.049350649350649, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '247034', 'n_tokens_mistral': 1709, 'n_tokens_neox': 1640, 'n_words': 949}