Skip to content

Receiving events

Everything the CLI says arrives as an AbstractEvent subclass.

import { AssistantEvent, ResultEvent, SystemEvent } from 'activecli';
command.subscribe((event) => {
if (event instanceof AssistantEvent && event.hasText()) {
process.stdout.write(event.text);
}
if (event instanceof ResultEvent) {
console.log('turn finished:', event.raw['subtype']);
}
});

AssistantEvent.text is the walk into message.content that every caller was otherwise writing by hand — the CLI nests its text there as an array of blocks, only some of which are text. It is empty when the assistant only called a tool, which is normal and not the same as the assistant having said nothing.

  • Unmodelled entries still arrive. An entry type the library has no class for becomes a GenericEvent rather than being dropped, so a CLI that gets ahead of this library does not silently lose events.
  • Non-protocol output is skipped, not treated as failure. CLIs write warnings to the same stream as their protocol. A line that is not JSON is passed over.

Every event keeps the CLI’s original entry intact under raw, with no field removed or renamed:

command.subscribe((event) => {
const unknown = event.raw['unknown_future_field']; // still there
});

That is what makes a GenericEvent useful rather than merely non-fatal: the entry the library did not model is still fully readable by a caller that does understand it.