Skip to content

Events

Goose uses EventFormat::Goose. It is run with goose run --output-format stream-json, which emits a line-delimited JSON stream on standard output: each non-empty line is a complete JSON object carrying a top-level type. The harness layer parses that stream and maps each record onto the normalized harness events.

The stream is made up of four record types:

Goose recordHandling
messageA serialized conversation message whose content is an array of blocks (text, thinking/redactedThinking, toolRequest, toolResponse) processed in order.
notificationSurfaced verbatim as an unknown event rather than parsed from prose.
errorBecomes an error event.
completeThe run boundary. It carries usage (consumed for metrics) and flushes any pending assistant span.

Within a message, assistant text blocks are agent progress and assistant thinking blocks are the model’s reasoning; user text is the echoed prompt and is ignored, and redactedThinking blocks carry no readable text. Goose streams each fragment as cumulative-or-delta records sharing a message id, so fragments of the same kind and id are accumulated into one pending span: a record that restates the pending text replaces it (a cumulative update), and any other same-kind, same-id record is appended (a delta). A pending span is flushed when activity of a different kind or id follows, or when the run completes — so a message’s reasoning is reported just ahead of its agent message.

A toolRequest block is recorded against its call id and resolved when the matching toolResponse arrives; the two are correlated by id. The response’s toolResult.status (success/error) sets the event’s success field. A toolRequest that cannot be parsed becomes an unknown event.

RawNormalized
assistant text blockagent (accumulated across same-id fragments, then flushed)
assistant thinking blockreasoning (accumulated across same-id fragments, then flushed)
user text, redactedThinkingconsumed — no event
toolRequest + matching toolResponsethe tool event for the tool, or unknown
completeconsumed for usage; flushes pending text — no event of its own
errorerror
notificationunknown
unrecognized record / block typeunknown

The harness layer does not capture a session id from Goose’s stream, so harness events from a Goose run carry no session ID.

Goose and MCP servers prefix tool names with an extension id (such as developer__shell); the name is split on __ and the extension prefix is stripped before classification. Tools from the todo extension are consumed as internal session state. The remaining base names map as follows:

Goose toolEvent
read, read_imageread (an image’s path comes from its source field)
write, editwrite
text_editorread or write, by its command (view/read read; write/create/overwrite/edit/str_replace/insert/move/rename/delete write; anything else unknown)
shellcommand, or a recognized file operation
grep, globsearch
list, treelist
load_skill, skillskill
todo__*consumed — internal session state, no event
any other toolunknown

See Harness Events for the normalized event contract.