Responses API: emit response.in_progress and built-in-tool event families
#7
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Scope cut from Step 2 (commit
957f704)The Responses projector emits a tight 8-event sequence:
response.created→response.output_item.added→response.content_part.added→response.output_text.delta× N →response.output_text.done→response.content_part.done→response.output_item.done→response.completedThat's enough for a Responses client to recover the assistant text. Out-of-scope today:
response.in_progress— OpenAI emits this betweenresponse.createdand the first content delta to signal "we're past prompt validation, model is generating". Some clients render a different spinner state based on it.response.web_search_call.*,response.code_interpreter_call.*,response.file_search_call.*,response.image_generation_call.*. These exist for OpenAI's hosted tools; neuron doesn't have any of those tools wired up, so the events would never fire — but the clients that look for them will today render an error or fall back to chat-completions semantics.See
crates/cortex-core/src/responses.rs::eventsfor the constants module, andcrates/neuron/src/wire/openai_responses.rs::emit_start_frames/emit_finish_framesfor the emission sites.Why it was cut
Most of these events carry no information the consumer doesn't already get from the surrounding events.
in_progressis a marker, not a payload; the built-in-tool families are no-ops without the underlying tools. The minimum useful set was what mattered for Stage 6 of helexa-acp to start exercising the route.What implementation looks like
response.in_progresspub const IN_PROGRESS: &str = "response.in_progress";tocortex_core::responses::events.response.createdand the first output_item event inemit_start_frames. Payload mirrorsresponse.created— the shell withstatus: "in_progress".full_stream_emits_expected_event_sequenceto assert it's present.That one is trivial. The next two depend on tool wiring that doesn't exist:
Hosted-tool families
Don't emit anything until we have the tools themselves. When we do (e.g. a
web_searchtool that proxies to an external search engine):InferenceEventwithToolInvocation { tool_id, name, status, … }variants.TextDeltas.ToolInvocationevents to the appropriateresponse.<tool>_call.*family.This is the natural extension once tool wiring lands. No work to do until then.
Acceptance
response.in_progresslands cleanly with a test.Tracking
Cosmetic for in_progress (some clients are fussier than others). Hosted-tool families are blocked on actually having hosted tools; not relevant for neuron's current scope.
Scope-narrowing note (2026-06-12 positioning): split this issue's three parts. (1)
response.in_progress— worth emitting; cheap, real clients key spinner state off it; part of the same contract-completeness work as #24. (2) Built-in-tool event families (web_search_call.*,code_interpreter_call.*, …) — out of scope: those are hosted-platform tools helexa deliberately does not have, and emitting their event shapes without the backing tools would be fake compatibility. Clients that need hosted tools need a cloud provider, and that is fine. (3) Reasoning / function-call families stay tracked in their own issues. Suggest retitling to just theresponse.in_progressdeliverable when picked up.Triage: the
response.in_progresshalf of this issue is already implemented and tested onmain— it was landed in a prior commit but the issue wasn't updated.cortex_core::responses::events::IN_PROGRESS(crates/cortex-core/src/responses.rs:243).emit_start_frames(crates/neuron/src/wire/openai_responses.rs:358-361) emits it immediately afterresponse.created, carrying the samein_progressshell, with a comment explaining the created/in_progress pairing.full_stream_emits_expected_event_sequenceasserts the full ordered sequence includingevents::IN_PROGRESSat position 2 (openai_responses.rs:820). Verified green just now.So acceptance item 1 ("
response.in_progresslands cleanly with a test") is met.The remaining scope is the hosted-tool event families (
response.web_search_call.*,code_interpreter_call.*,file_search_call.*,image_generation_call.*), which — per this issue's own writeup — are no-ops until the underlying hosted tools exist in neuron (none are wired). There's nothing to emit until that tool wiring lands. TheInferenceEvent::ToolCallprojector arm already carries a// Future work tracked in #7breadcrumb for it.Recommend narrowing this issue to just the deferred hosted-tool families (or closing and re-filing when tool wiring is on the roadmap), since the in_progress deliverable is done. Leaving it open and scoped to the tool-families for now.