> ## Documentation Index
> Fetch the complete documentation index at: https://actelos.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Environment Bindings

> Callbacks an environment module receives from the host

`EnvironmentBindings` is the callback surface cyrnel hands to an environment
module at activation. The environment calls *into* these to talk to the
host.

```ts theme={null}
interface EnvironmentBindings {
  invokeTool(input: InvokeInput): Promise<unknown>;
  setState(eid: number, data: ExecutionState): void;
  setError(eid: number, data: string): void;
  emitStdout(eid: number, data: Buffer): void;
  emitStderr(eid: number, data: Buffer): void;
  emitOutput(eid: number, data: Record<string, unknown>): void;
}
```

## Tool Invocation

User code drives tool execution through the environment's runtime surface
(`cyrnel.services[id].tools[t].invoke(...)`), which proxies through to
this callback.

## Execution Reporting

The environment **must** report execution state via these callbacks. The
host uses them to keep the process record in sync with what's actually
happening.

| Callback                   | When to call                                                                                      |
| -------------------------- | ------------------------------------------------------------------------------------------------- |
| `setState(eid, "queued")`  | Execution accepted but not yet running.                                                           |
| `setState(eid, "running")` | Execution started in the runtime.                                                                 |
| `setError(eid, message)`   | Execution failed; supply a human-readable message. The host writes this to `process.error`.       |
| `emitStdout(eid, buf)`     | User code wrote to stdout. The host append-decodes.                                               |
| `emitStderr(eid, buf)`     | User code wrote to stderr.                                                                        |
| `emitOutput(eid, obj)`     | User code emitted a structured output payload. The host `Object.assign`s into the running output. |

`eid` always matches the process `pid`, it's the value the host passed
in `ExecutionInput.eid`. Mixing up `eid` values silently mis-routes
output between processes.

## Buffers and Strings

`emitStdout` and `emitStderr` take `Buffer`. The host owns the decode.
It runs each stream through a `StringDecoder("utf8")` so multi-byte
characters split across chunks are reassembled correctly. The
environment should pass raw bytes; do not decode and re-encode.

`emitOutput` takes a plain object. The host treats it as a partial patch
(`Object.assign`), so subsequent emits with the same key overwrite, and
new keys are appended.

## Implementation Notes

* **Idempotency**: `setState` calls are advisory. The host ignores
  duplicate transitions (`running` → `running`) and rejects nonsensical
  ones (`idle` → `running`). Don't rely on every call landing.
* **Ordering**: callbacks happen in whatever order the environment
  invokes them. The host does not buffer or reorder. If you need
  ordering guarantees with respect to execution completion, finish the
  callbacks before resolving `execute`.
* **Thread safety**: these are plain functions on the host's event loop.
  An environment using worker threads must marshal calls back through
  references (the bundled `typescript-ivm` does this with
  `ivm.Reference`).
