Conversation
| async function pollBackground(invocationId) { | ||
| const deadline = Date.now() + 180000; | ||
| while (Date.now() < deadline) { | ||
| while (true) { |
There was a problem hiding this comment.
are there any downsides of polling forever vs just raising the timeout?
There was a problem hiding this comment.
Yes: a stuck run can keep this tab busy and continue making status reads. Raising the timeout would bound the wait, but would still discard a healthy long-running result without cancelling the backend invocation.
In f0208da I kept terminal-state waiting and added a small backoff in both templates: 850 ms initially, increasing to a 5-second cap (about 12 reads/minute once capped). The tradeoff is up to five seconds before noticing completion, plus request latency. Requests remain sequential and the event list is capped at 80. Completion/failure, HTTP errors (including 404), and network errors stop polling. Closing/reloading the page stops client polling; it does not cancel the agent or automatically resume waiting after reload. Stop-waiting/reconnect support remains separate work.
Verified in recorded browser tests: a 185-second fixture remained active at 181 seconds and displayed its result once, with 41 polls over ~191 seconds. Both frameworks also stopped polling and restored the composer for 404, 503, and network failure; premature SSE closure reported an error.
Partially addresses ML-70352 and ML-70355.
Chat displayed Markdown literally, could report Ready after a failed stream, and stopped waiting after three minutes while a background agent was still running. The model picker hid services after its twentieth entry. Live Opus 5.5 reasoning tests also exposed LangGraph failures on absent token-usage details, duplicated final answers, and line breaks between token fragments.
This change renders assistant Markdown during streaming, on completion, and when loading history; Copy preserves the source Markdown. A pinned local markdown-it parser escapes raw HTML and disables images. Typed reasoning/signature blocks remain outside answer chat. Responses API fixes omit absent usage details, retain the last meaningful event across metadata events, and carry the output index on text deltas so LangChain assembles them correctly.
The UI uses Foreground / Background / Streaming, lists all discovered models, reports failed/disconnected streams, and waits for background completion without an arbitrary deadline. Polling backs off from 850 ms to a five-second cap to reduce traffic during long waits; this adds up to five seconds of completion-detection delay. A stuck run can still keep the tab busy. Closing/reloading stops browser polling without cancelling the agent; reconnect/stop-waiting UX is outside this patch.
Feedback addressed
Before / after
Validation
Tested source: f0208da. Generated UI assets were byte-compared with this commit; runs began before committing the identical backoff patch. Main baseline: ed3ed6b.
ml-inference-staging: newly generated OpenAI and LangGraph apps, Chrome → FastAPI → real adapters → Sonnet 4.5/Opus 5.5. Both frameworks passed all three modes, Markdown/exact code, one assistant answer, and codeword memory across model switching and a follow-up. Temporary test scaffolds enabled Responsesreasoning.effort=mediumandinclude=["reasoning.encrypted_content"]for Opus. LangGraph returned real encrypted payloads (820/900 characters) outside answer chat; OpenAI passed but did not expose encrypted items to the browser. The original visible-ciphertext symptom did not recur on current main; the recorded before/after demonstrates the reproduced duplicate-output/HTTP failures.Live tests use local generated servers with the checkout's packages, including the changed LangChain integration; they do not deploy a Databricks App. Template updates apply to newly generated projects; existing projects need refreshed UI files. Discovery outside
system.airemains a follow-up.