aa75d3724f
- on_text_delta dropped whitespace-only deltas, so concatenating the `text` events no longer reproduced the answer (a newline between paragraphs was lost). Only None/"" (the turn-end sentinel) is skipped now. - The emitter was attached only after credentials + agent init succeeded, so a missing key or unknown provider exited 1 with an EMPTY stdout and the provider error rendered through ChatConsole (stdout). The emitter is now built before _ensure_runtime_credentials/_init_agent; that path closes the protocol with init + a failed `result` (exit_code 1, error) and the credential error goes to stderr whenever stdout is machine-readable (tool_progress_mode == "off", i.e. -Q and stream-json). - _tool_started was keyed by tool name, so concurrent same-name calls clobbered each other's start time; key on tool_call_id when the caller passes one and surface it on tool_use/tool_result. Live: `hermes chat -q … --format stream-json` with no provider and with a dead custom base_url both yield pure JSONL (`system` + `result`, exit 1).