Skip to main content
Every ingress path ends at admit in managed/agent.ts, and from this point on the loop is the same whether the text came by invoke, by RPC, from the messaging webhook or from another channel. A call is the one exception, and The Voice Loop describes it.
Three things happen.
  • The sender is written to state first, so that the memory profile is known before the harness exists.
  • ready() returns the harness, building it on the first call of an activation and recovering any run a crash interrupted.
  • accept() admits one run under the key and queues it as a task on the instance.
this.setState({ from }) is setState(). It merges from into the state and leaves every other key as it was. harness.accept(text, { key }) is accept().
  • text is the input the run executes.
  • key is the idempotency key. It is the caller’s key, or a fresh UUID when none was given.
  • A key seen before returns the first run with duplicate: true and admits nothing.
  • runId and duplicate are what admit returns to the caller.
ready() builds the harness and recovers it:
A call asks for ready({ calls: true }), which The Voice Loop covers: the harness for calls leaves out every tool marked ask, and is the same instance when there is none. harness.recover() is recover().
  • It queues the task of every run still to be executed, including the runs a restart interrupted.
  • Every entrypoint that touches the harness goes through ready(), so recovery runs once per activation, before any new work.
  • A recovery that throws is tried again by the next call.
admit returns the run id at once, well inside the 30-second budget of the inbound call. The Harness is what ready() built.