Responses API: emit response.in_progress and built-in-tool event families
#7
Open
opened 2026-05-31 08:19:37 +00:00 by grenade
·
2 comments
No Branch/Tag Specified
main
feat/397-replicas
feat/385-acestep-memory
fix/376-models-unhealthy-node
feat/music-surprise-genres
feat/web-decisions-route
fix/cold-load-serialise
fix/music-hide-stale-on-compose
feat/audio-disk-guard
feat/music-studio-ux
fix/cortex-glibc-floor
feat/music-history-sidebar
feat/audio-flac-mp3
feat/393-heartmula-serving
feat/391-heartmula-port
feat/387-acestep-rollout
feat/383-acestep-engine
feat/390-heartmula-fixtures
feat/381-acestep-fixtures
feat/402-music-ui
feat/386-audio-rates
feat/382-audio-job-api
feat/356-systemone-playground
fix/bench-skip-decision-models
feat/341-laya-residency
feat/341-laya-rollout
feat/337-laya-perf
feat/338-neuron-systemone
feat/335-laya-prompt-builder
feat/336-laya-engine
feat/339-laya-lang-detect
feat/338-systemone-surface
feat/334-laya-reference-fixtures
feat/96-mtp-probe
fix/324-qsa-visible-set
feat/310-ple-random-advice
feat/neuron-phase-timing
fix/qwen4-ple-conv-launch-bound
feat/318-per-layer-activation-hop
fix/318-release-host-memory
feat/318-per-model-max-in-flight
fix/318-logits-last-position
fix/318-cached-experts-residency
feat/318-host-source-tensors
feat/318-host-resident-experts
fix/322-cache-telemetry
feat/322-isq-cache
test/323-parity-long-prompt
fix/323-layer-type-alias
fix/323-qsa-scores-in-f32
feat/310-mmap-ngram-table
fix/quant-fallback-match-llamacpp
fix/qwen4-exp-expert-row-width
fix/qwen4-exp-load-reporting-and-pool-trim
fix/320-isq-reachable-and-log-levels
feat/qwen4-exp-quantised-experts
feat/qwen4-exp-expert-bank
feat/qwen4-exp-mtp-head
docs/mtp-wiring-settled
feat/qwen4-exp-snapshot
feat/rustingface-always
feat/qwen4-exp-harness
feat/qwen4-exp-qsa-oracle
feat/qwen4-exp-model
feat/qwen4-exp-decoder
feat/qwen4-exp-linear-attn
feat/qwen4-exp-moe
feat/qwen4-exp-full-attn
feat/qwen4-exp-qsa-indexer
feat/qwen4-exp-config
feat/qwen4-exp-qsa-selection
feat/qwen4-exp-ple-consumption
fix/seed-cutlass-anonymously
feat/qwen4-exp-ple-hashing
fix/seed-cutlass-in-cuda-ci
feat/hf-endpoint-env
feat/qwen4-exp-hyper-connections
feat/qwen4-exp-norm-primitives
fix/alias-test-temp-catalogue-collision
chore/retire-vestigial-reasoning-ladder
fix/context-limit-honours-kv-budget
feat/server-advertised-reasoning-ladder
feat/web-chat-collapsible-working
fix/router-sync-restarts-only-on-settings-change
feat/ci-owns-the-router-config
fix/infra-setup-ships-ratelimit-to-gateway
fix/nginx-preflight-checks-every-grant
fix/restore-max-in-flight-8
fix/retire-qwen36-27b
fix/nginx-sync-must-not-block-cortex-deploy
feat/nginx-search-alias-and-sync
fix/wire-surface-in-neuron-spans
fix/295-ignore-tiny-prefill-samples
fix/300-anthropic-streaming-thinking
fix/300-return-the-models-reasoning
feat/operator-repetition-knobs
fix/292-prefix-cache-budget
feat/stamp-preserve-thinking-state
fix/296-one-step-one-assistant-turn
feat/preserve-thinking-ab-gate
fix/client-capability-misattributions
fix/291-max-in-flight-and-config-only-ci
feat/290-reasoning-rungs-from-the-model
fix/284-gdn-state-f32
feat/bench-measurement-regimes
feat/285-nonstreaming-through-engine
fix/288-bench-authenticates
feat/283-operator-sampling-override
fix/286-clippy-all-targets
fix/replay-only-the-latest-reasoning
fix/developer-role-maps-to-system
fix/223-reasoning-effort-off
fix/fetch-the-models-own-prompt-format
fix/278-advertise-the-real-limits
fix/277-responses-reasoning-roundtrip
fix/272-sampling-gaps
fix/clippy-1.98-result-large-err
feat/sampling-defaults
fix/streaming-completion-log
fix/prometheus-histogram-buckets
fix/responses-reasoning-events
fix/stream-reasoning-content
fix/cortex-stream-read-timeout
fix/sse-keepalive-during-prefill
fix/anonymous-yields-to-authenticated
fix/upstream-test-fixture-collisions
fix/docs-directory-index
feat/angels-internal-vhost
v0.1.16
v0.1.15
v0.1.14
v0.1.12
v0.1.11
v0.1.10
v0.1.9
v0.1.8
v0.1.7
v0.1.6
v0.1.5
v0.1.4
v0.1.3
v0.1.2
v0.1.1
v0.1.0
Labels
Clear labels
out-of-scope
p1-now
p2-next
p3-later
Outside helexa's constraining principles: near-frontier models on consumer hardware, served transparently and predictably
Active pain or unblocking work — pick up first
Engine levers — start once P1 baselines exist
Dependent on earlier work, or demand-driven
No labels
p3-later
Milestone
No items
No Milestone
Projects
Clear projects
No projects
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: helexa/helexa#7
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
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.