Build a custom machine
Entry points
What the Ownbox calls in the machine, and when. Each runs in the machine's own unit.
| Entry point | Declared with | The Ownbox calls it | Time limit |
|---|---|---|---|
| A job | @m.every(seconds) | at its time; as soon as the machine starts; when a person taps its button | — |
| A page | @m.screen(path) | each time a person opens the page | 20 s |
| A card | m.panel(slot, title=, render=) | each time the screen with that slot is drawn | 20 s |
| A tool | m.tool(name, fn=, ...) | when the owner's AI asks it | 60 s |
| A Morning Review part | m.reporter(title, fn) | once a pass; the latest answer is shown | — |
| An approval | m.on_approve(kind, fn) | once, after a person says yes to its proposal | — |
| A forget | def on_forget(person_id) | when the owner erases a person (not called yet) | — |
- A job runs every 15 seconds to once a week. A run that raises is reported, and the next one goes ahead.
- A page or a card that does not answer within 20 seconds shows This machine did not answer in time, with a Try again button.
- A tool's answer reaches the owner's AI quoted, as the machine's own words, at most 8 KB.
render(result)writes it in words; each argument is a string of at most 500 characters, a whole number or a true/false. - A Morning Review part answers
fn(day)with{"title", "headline": {"value", "label"}, ...}, or{}to show nothing that day. A slow part never holds the review up. on_forgetis not called yet: erasing a person on the Ownbox does not reach a machine's own data until it is. Write it now. A machine that names people data is refused without it.