feat(streaming): configurable nginx, controller, and UI inactivity ti…#1973
feat(streaming): configurable nginx, controller, and UI inactivity ti…#1973yanivmn wants to merge 3 commits into
Conversation
…meouts
Helm chart (`helm/kagent/`)
- values.yaml:
- Add `ui.streamTimeoutSeconds` (default 1800) - client-side chat stream
inactivity timeout, propagated to the browser via the UI ConfigMap.
- Add `ui.nginx.proxyReadTimeout` / `proxySendTimeout` (default 1800s) -
templated into the UI sidecar nginx config in place of the previously
hard-coded per-location values.
- Add `ui.openshiftRoute.annotations` with `haproxy.router.openshift.io/timeout: 120m`
required for A2A/SSE streaming through the OpenShift router (default
~60s caused ERR_INCOMPLETE_CHUNKED_ENCODING in the browser).
- Keep `controller.streaming.timeout` at 1800s (pre-PR default).
- files/nginx.conf: replace hard-coded `proxy_read_timeout` /
`proxy_send_timeout` values (600s / 1800s / 3600s) with a single
templated value driven by `ui.nginx.*`.
- templates/openshift-route.yaml: render `ui.openshiftRoute.annotations`.
- templates/ui-deployment.yaml: expose `streamTimeoutSeconds` to the UI
container.
UI (`ui/`)
- Add `ui/src/app/actions/config.ts` to load runtime config (stream timeout).
- `ui/src/app/a2a/[namespace]/[agentName]/route.ts`: keep upstream
connection alive while the stream is open.
- `ui/src/components/chat/ChatInterface.tsx`: drive the EventSource
inactivity timeout from the configured `streamTimeoutSeconds` and add
keep-alive timers to prevent idle browser disconnects.
Authored-by: Yuri Khrakovski
Co-authored-by: Cursor <cursoragent@cursor.com>
Signed-off-by: Yaniv Marom Nachumi <yanivmar@amdocs.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
This PR aims to make A2A/SSE streaming more robust by extending proxy/browser timeouts and making the client-side stream inactivity timeout configurable at runtime (via Helm-provided env).
Changes:
- Add runtime UI config lookup for stream inactivity timeout and use it in the chat stream consumer.
- Start SSE keep-alives earlier in the A2A proxy route to avoid HAProxy idle timeouts before the first full SSE frame.
- Helm chart updates: introduce configurable UI stream timeout, propagate env var, expose nginx proxy timeouts, and allow OpenShift Route timeout annotations.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| ui/src/components/chat/ChatInterface.tsx | Use runtime-configured stream inactivity timeout instead of a fixed 10-minute constant. |
| ui/src/app/actions/config.ts | Add server-side runtime config accessor reading timeout from env with a default fallback. |
| ui/src/app/a2a/[namespace]/[agentName]/route.ts | Reset keep-alive timer as soon as upstream bytes arrive and at stream start. |
| helm/kagent/values.yaml | Add UI stream timeout + nginx timeout defaults + OpenShift Route timeout annotations. |
| helm/kagent/templates/ui-deployment.yaml | Wire Helm value into KAGENT_STREAM_TIMEOUT_MS env var for the UI container. |
| helm/kagent/templates/openshift-route.yaml | Allow user-provided Route annotations for timeouts. |
| helm/kagent/files/nginx.conf | Parameterize proxy read/send timeouts via Helm values for streaming endpoints. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
thanks for the PR! Can you please address the PR comments? |
- Read streamTimeoutMs from ref inside startTimeout() so runtime config updates are picked up mid-stream - Export DEFAULT_STREAM_TIMEOUT_MS from config.ts as single source of truth instead of duplicating in ChatInterface.tsx - Use Math.ceil for timeout label and fall back to seconds for sub-minute values to avoid displaying "0 minutes" - Remove trailing whitespace in route.ts Signed-off-by: Yaniv Marom Nachumi <yanivmar@amdocs.com> Co-authored-by: Cursor <cursoragent@cursor.com>
Addressed all issues |
"use server" files can only export async functions. Move the constant to lib/constants.ts and import it in both config.ts and ChatInterface.tsx. Signed-off-by: Yaniv Marom Nachumi <yanivmar@amdocs.com> Co-authored-by: Cursor <cursoragent@cursor.com>
|
@peterj anything else required for this PR? |
|
Hey @yanivmn, sorry for letting this fall through, can you resolve conflicts and then we can push it through |
…meouts
Helm chart (
helm/kagent/)ui.streamTimeoutSeconds(default 1800) - client-side chat stream inactivity timeout, propagated to the browser via the UI ConfigMap.ui.nginx.proxyReadTimeout/proxySendTimeout(default 1800s) - templated into the UI sidecar nginx config in place of the previously hard-coded per-location values.ui.openshiftRoute.annotationswithhaproxy.router.openshift.io/timeout: 120mrequired for A2A/SSE streaming through the OpenShift router (default ~60s caused ERR_INCOMPLETE_CHUNKED_ENCODING in the browser).controller.streaming.timeoutat 1800s (pre-PR default).proxy_read_timeout/proxy_send_timeoutvalues (600s / 1800s / 3600s) with a single templated value driven byui.nginx.*.ui.openshiftRoute.annotations.streamTimeoutSecondsto the UI container.UI (
ui/)ui/src/app/actions/config.tsto load runtime config (stream timeout).ui/src/app/a2a/[namespace]/[agentName]/route.ts: keep upstream connection alive while the stream is open.ui/src/components/chat/ChatInterface.tsx: drive the EventSource inactivity timeout from the configuredstreamTimeoutSecondsand add keep-alive timers to prevent idle browser disconnects.Authored-by: Yuri Khrakovski