EXPERIMENTAL: this endpoint is experimental and is subject to change. nolint:revive // HTTP handler writes to ResponseWriter.
(rw http.ResponseWriter, r *http.Request)
| 7758 | // |
| 7759 | //nolint:revive // HTTP handler writes to ResponseWriter. |
| 7760 | func (api *API) postChatToolResults(rw http.ResponseWriter, r *http.Request) { |
| 7761 | ctx := r.Context() |
| 7762 | chat := httpmw.ChatParam(r) |
| 7763 | apiKey := httpmw.APIKey(r) |
| 7764 | |
| 7765 | // Submitting tool results resumes LLM inference, |
| 7766 | // requiring update permission on the org-scoped chat resource. |
| 7767 | if !api.Authorize(r, policy.ActionUpdate, chat.RBACObject()) { |
| 7768 | httpapi.ResourceNotFound(rw) |
| 7769 | return |
| 7770 | } |
| 7771 | |
| 7772 | // Only the chat owner may submit tool results. See |
| 7773 | // postChatMessages for the security rationale. |
| 7774 | if apiKey.UserID != chat.OwnerID { |
| 7775 | httpapi.Write(ctx, rw, http.StatusForbidden, codersdk.Response{ |
| 7776 | Message: "Only the chat owner may submit tool results.", |
| 7777 | }) |
| 7778 | return |
| 7779 | } |
| 7780 | |
| 7781 | if chat.Archived { |
| 7782 | httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{ |
| 7783 | Message: "Cannot submit tool results to an archived chat.", |
| 7784 | }) |
| 7785 | return |
| 7786 | } |
| 7787 | |
| 7788 | // Cap the raw request body to prevent excessive memory use. |
| 7789 | r.Body = http.MaxBytesReader(rw, r.Body, int64(2*maxSystemPromptLenBytes)) |
| 7790 | var req codersdk.SubmitToolResultsRequest |
| 7791 | |
| 7792 | if !httpapi.Read(ctx, rw, r, &req) { |
| 7793 | return |
| 7794 | } |
| 7795 | |
| 7796 | if len(req.Results) == 0 { |
| 7797 | httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{ |
| 7798 | Message: "At least one tool result is required.", |
| 7799 | }) |
| 7800 | return |
| 7801 | } |
| 7802 | |
| 7803 | // Fast-path check outside the transaction. The authoritative |
| 7804 | // check happens inside SubmitToolResults under a row lock. |
| 7805 | if chat.Status != database.ChatStatusRequiresAction { |
| 7806 | httpapi.Write(ctx, rw, http.StatusConflict, codersdk.Response{ |
| 7807 | Message: "Chat is not waiting for tool results.", |
| 7808 | Detail: fmt.Sprintf("Chat status is %q, expected %q.", chat.Status, database.ChatStatusRequiresAction), |
| 7809 | }) |
| 7810 | return |
| 7811 | } |
| 7812 | |
| 7813 | var dynamicTools json.RawMessage |
| 7814 | if chat.DynamicTools.Valid { |
| 7815 | dynamicTools = chat.DynamicTools.RawMessage |
| 7816 | } |
| 7817 |
nothing calls this directly
no test coverage detected