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

Method postChats

coderd/exp_chats.go:1015–1294  ·  view source on GitHub ↗

EXPERIMENTAL: this endpoint is experimental and is subject to change. @Summary Create chat @ID create-chat @Security CoderSessionToken @Tags Chats @Accept json @Produce json @Param request body codersdk.CreateChatRequest true "Create chat request" @Success 201 {object} codersdk.Chat @Router /api/ex

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

Source from the content-addressed store, hash-verified

1013// @Router /api/experimental/chats [post]
1014// @Description Experimental: this endpoint is subject to change.
1015func (api *API) postChats(rw http.ResponseWriter, r *http.Request) {
1016 ctx := r.Context()
1017 apiKey := httpmw.APIKey(r)
1018
1019 // Cap the raw request body to prevent excessive memory use
1020 // from large dynamic tool schemas.
1021 r.Body = http.MaxBytesReader(rw, r.Body, int64(2*maxSystemPromptLenBytes))
1022
1023 var req codersdk.CreateChatRequest
1024 if !httpapi.Read(ctx, rw, r, &req) {
1025 return
1026 }
1027
1028 aReq, commitAudit := audit.InitRequest[database.Chat](rw, &audit.RequestParams{
1029 Audit: *api.Auditor.Load(),
1030 Log: api.Logger,
1031 Request: r,
1032 Action: database.AuditActionCreate,
1033 OrganizationID: req.OrganizationID,
1034 })
1035 defer commitAudit()
1036
1037 // Validate organization membership.
1038 if req.OrganizationID == uuid.Nil {
1039 httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
1040 Message: "organization_id is required.",
1041 })
1042 return
1043 }
1044 isMember, err := httpmw.UserAuthorization(ctx).HasOrganizationMembership(req.OrganizationID)
1045 if err != nil {
1046 httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
1047 Message: "Failed to validate organization membership.",
1048 Detail: xerrors.Errorf("check organization membership: %w", err).Error(),
1049 })
1050 return
1051 }
1052 if !isMember {
1053 httpapi.Write(ctx, rw, http.StatusForbidden, codersdk.Response{
1054 Message: "You are not a member of the specified organization.",
1055 })
1056 return
1057 }
1058 // NOTE: This authorize check is intentionally placed after request
1059 // parsing because we need req.OrganizationID to scope the RBAC check
1060 // to the correct org. The request body is bounded by MaxBytesReader
1061 // above, limiting the cost of parsing before rejection.
1062 if !api.Authorize(r, policy.ActionCreate, rbac.ResourceChat.WithOwner(apiKey.UserID.String()).InOrg(req.OrganizationID)) {
1063 httpapi.Forbidden(rw)
1064 return
1065 }
1066
1067 // Validate per-chat system prompt length.
1068 const maxSystemPromptLen = 10000
1069 if len(req.SystemPrompt) > maxSystemPromptLen {
1070 httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
1071 Message: "System prompt exceeds maximum length.",
1072 Detail: fmt.Sprintf("System prompt must be at most %d characters, got %d.", maxSystemPromptLen, len(req.SystemPrompt)),

Callers

nothing calls this directly

Calls 15

AuthorizeMethod · 0.95
linkFilesToChatMethod · 0.95
fetchChatFileMetadataMethod · 0.95
APIKeyFunction · 0.92
ReadFunction · 0.92
InitRequestFunction · 0.92
WriteFunction · 0.92
UserAuthorizationFunction · 0.92
ForbiddenFunction · 0.92
AsSystemRestrictedFunction · 0.92

Tested by

no test coverage detected