MCPcopy Index your code
hub / github.com/coder/coder / streamChat

Method streamChat

coderd/exp_chats.go:3446–3580  ·  view source on GitHub ↗

EXPERIMENTAL: this endpoint is experimental and is subject to change. @Summary Stream chat events via WebSockets @ID stream-chat-events-via-websockets @Security CoderSessionToken @Tags Chats @Produce json @Param chat path string true "Chat ID" format(uuid) @Success 200 {object} codersdk.ChatStreamE

(rw http.ResponseWriter, r *http.Request)

Source from the content-addressed store, hash-verified

3444// @Router /api/experimental/chats/{chat}/stream [get]
3445// @Description Experimental: this endpoint is subject to change.
3446func (api *API) streamChat(rw http.ResponseWriter, r *http.Request) {
3447 ctx := r.Context()
3448 chat := httpmw.ChatParam(r)
3449 chatID := chat.ID
3450 logger := api.Logger.Named("chat_streamer").With(slog.F("chat_id", chatID))
3451
3452 if api.chatDaemon == nil {
3453 httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
3454 Message: "Chat streaming is not available.",
3455 Detail: "Chat processor is not configured.",
3456 })
3457 return
3458 }
3459
3460 var afterMessageID int64
3461 if v := r.URL.Query().Get("after_id"); v != "" {
3462 var err error
3463 afterMessageID, err = strconv.ParseInt(v, 10, 64)
3464 if err != nil {
3465 httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
3466 Message: "Invalid after_id parameter.",
3467 Detail: err.Error(),
3468 })
3469 return
3470 }
3471 }
3472
3473 // Subscribe before accepting the WebSocket so that failures
3474 // can still be reported as normal HTTP errors.
3475 snapshot, events, cancelSub, ok := api.chatDaemon.SubscribeAuthorized(ctx, chat, r.Header, afterMessageID)
3476 // Subscribe only fails today when the receiver is nil, which
3477 // the chatDaemon == nil guard above already catches. This is
3478 // defensive against future Subscribe failure modes.
3479 if !ok {
3480 httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
3481 Message: "Chat streaming is not available.",
3482 Detail: "Chat stream state is not configured.",
3483 })
3484 return
3485 }
3486 defer cancelSub()
3487
3488 conn, err := websocket.Accept(rw, r, nil)
3489 if err != nil {
3490 httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
3491 Message: "Failed to open chat stream.",
3492 Detail: err.Error(),
3493 })
3494 return
3495 }
3496
3497 ctx, cancel := context.WithCancel(ctx)
3498 defer cancel()
3499
3500 _ = conn.CloseRead(context.Background())
3501
3502 ctx, wsNetConn := codersdk.WebsocketNetConn(ctx, conn, websocket.MessageText)
3503 defer wsNetConn.Close()

Callers

nothing calls this directly

Calls 15

markChatAsReadMethod · 0.95
ChatParamFunction · 0.92
WriteFunction · 0.92
WebsocketNetConnFunction · 0.92
HeartbeatCloseFunction · 0.92
APIKeyFunction · 0.92
NamedMethod · 0.80
SubscribeAuthorizedMethod · 0.80
EncodeMethod · 0.80
ContextMethod · 0.65
GetMethod · 0.65
CloseMethod · 0.65

Tested by

no test coverage detected