# Iii Observe

Use when observing iii functions with iii.observe, writing filters, reacting to engine...

- Repository: https://github.com/iii-hq/iii (18876 stars)
- Category: Writing
- License: see repository
- Last updated: 2026-11-01
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add iii-hq/iii --skill iii-observe -g -a claude-code -y`
Codex: `npx skills add iii-hq/iii --skill iii-observe -g -a codex -y`
Cursor: `npx skills add iii-hq/iii --skill iii-observe -g -a cursor -y`
Gemini CLI: `npx skills add iii-hq/iii --skill iii-observe -g -a gemini-cli -y`

## Description

Use when observing iii functions with iii.observe, writing filters, reacting to engine events, writing observable functions with owner delivery (onObserverAdded, obs.emit, obs.call), tuning local dispatch, or migrating from the deprecated registerTrigger / registerTriggerType across TypeScript, browser, Python, Rust, and Go.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# Observe

Since iii 0.25 every function is observable. `iii.observe(source, target, options?)` connects a
source function to a target function: each event of the source that passes the observer's filters
invokes the target. It replaces `registerTrigger`, and an `observe` descriptor on
`registerFunction` replaces `registerTriggerType`. Both old APIs still work in 0.25 (see
[Migrating from triggers](#migrating-from-triggers)).

| Part | Fields | Notes |
| --- | --- | --- |
| `source` (left side) | `function_id`, `namespace?`, `args?`, `filters?`, `on?`, `capture?`, `deliver?` | `args` only for owner-delivered functions. `on` (auto only): `success` (default), `error`, `complete`. `capture` (auto and `obs.emit`): default `['input', 'output', 'caller']`, `[]` allowed. `deliver`: `envelope` (default), `input`, `output` |
| `target` (right side) | a registered function id (or `{ function_id, namespace }`) | No inline handler. The observer stays `pending` until the target is registered |
| `options` | `id?`, `max_fires?`, `expires_in_ms?`, `max_in_flight?`, `metadata?` | `id` defaults to a UUID kept across replays. `metadata` is the sidecar of every activation |

The source namespace resolves like `trigger()`: the worker's namespace, except `engine::*` and
`configuration::*`, which resolve in `default`.

## Observe a function

Register the target first, then observe. This alerts on failed charges of 500 or more:

```typescript
import { registerWorker, type Observed } from "iii-sdk";

const iii = registerWorker(process.env.III_URL ?? "ws://localhost:49134");

iii.registerFunction("alerts::payment-failed", async (event: Observed<{ amount: number }>) => {
  console.log(event.function_id, event.error?.code, event.input?.amount, event.caller?.worker_name);
  return null; // ignored for auto delivery
});

The rest: https://github.com/iii-hq/iii/blob/HEAD/skills/iii-observe/SKILL.md
