Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Shared, adapter-backed key/value store addressed by scope and key, with a reactive `state` trigger so other functions can run on every create, update, or delete without polling.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | -33% | 0% |
| case-03 | ✗→✓ | ▲ Improved | -19% | 0% |
| case-04 | ✗→✓ | ▲ Improved | -47% | 0% |
| case-05 | ✗→✓ | ▲ Improved | -39% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 23% | 0% |
The iii-state worker is a server-side key/value store. Values are addressed by a scope (namespace) and a key, shared across every worker connected to the engine, and persisted through a pluggable adapter (kv, redis, or bridge). Callers reach the store through six state::* functions invoked with iii.trigger({ function_id: 'state::...', payload }).
State does not push updates to SDK clients. Reactivity is delivered by a state trigger type that fires state:created, state:updated, or state:deleted after every successful mutation, so downstream functions can react to data changes without polling. The kv adapter (default) supports in_memory or file_based persistence; redis proxies to a Redis backend; bridge forwards operations to a remote iii engine. The function surface is identical across adapters.
scope/key watched and reacted to only when that slot changes.configuration when entries need a registered JSON Schema and validation.state::get, state::list, state::list_groups) never fire triggers; only set/update/delete do.state:deleted with a null old value.iii-stream, not here.state::set — write or replace the value at a scope/key; fires state:created or state:updated.state::get — read one value by scope and key.state::delete — remove a key and fire state:deleted with the prior value.state::update — apply ordered atomic ops (set, merge, increment, decrement, append, remove) to the stored value.state::list — enumerate every value stored in a scope.state::list_groups — enumerate which scopes currently contain data.Bind a state trigger when a function should run automatically after a value changes — without polling state::get. The engine evaluates every registered state trigger after a successful state::set, state::update, or state::delete and invokes matching handlers asynchronously.
Reach for it when:
condition_function_id so the handler only runs when a predicate on the event is truthy.If you only need the new value inside the same function that wrote it, use the mutator's returned old_value / new_value instead of binding a trigger.
iii.registerFunction('orders::on-status-change', handler).typescriptiii.registerTrigger({ type: 'state', function_id: 'orders::on-status-change', config: { scope: 'orders', // optional. Omit to match every scope. key: 'status', // optional. Omit to match every key in the scope. // condition_function_id is also supported. }, })
All config fields are optional; tighter filters reduce how often the handler runs. To watch several specific keys, register one trigger per scope/key pair. Mutations that fire the trigger: state::set, state::update, state::delete.
For the event payload shape, call iii get function info on the trigger type or handler function id.
Other measured skills in the registry, with their headline benchmark lift.