@@ -623,34 +623,34 @@ func (api *API) taskSend(rw http.ResponseWriter, r *http.Request) {
623
623
return
624
624
}
625
625
626
- type messagePayload struct {
627
- Content string `json:"content"`
628
- Type string `json:"type"`
629
- }
630
- payload ,err := json .Marshal (messagePayload {Content :req .Input ,Type :"user" })
631
- if err != nil {
632
- httpapi .Write (ctx ,rw ,http .StatusInternalServerError , codersdk.Response {
633
- Message :"Internal error encoding request payload." ,
634
- Detail :err .Error (),
635
- })
636
- return
637
- }
638
-
639
626
if err = api .authAndDoWithTaskSidebarAppClient (r ,taskID ,func (ctx context.Context ,client * http.Client ,appURL * url.URL )error {
640
- // Build the request to the agent local app (we expect agentapi on the other side).
641
- appReqURL := appURL
642
- appReqURL .Path = path .Join (appURL .Path ,"message" )
643
-
644
- newReq ,err := http .NewRequestWithContext (ctx ,http .MethodPost ,appReqURL .String (),bytes .NewReader (payload ))
627
+ status ,err := doAgentapiStatusRequest (ctx ,client ,appURL )
645
628
if err != nil {
646
- return httperror .NewResponseError (http .StatusInternalServerError , codersdk.Response {
647
- Message :"Internal error creating request to task app." ,
648
- Detail :err .Error (),
629
+ return err
630
+ }
631
+
632
+ if status != "stable" {
633
+ return httperror .NewResponseError (http .StatusBadGateway , codersdk.Response {
634
+ Message :"Task app is not ready to accept input." ,
635
+ Detail :fmt .Sprintf ("Status: %s" ,status ),
649
636
})
650
637
}
651
- newReq .Header .Set ("Content-Type" ,"application/json" )
652
638
653
- resp ,err := client .Do (newReq )
639
+ var reqBody struct {
640
+ Body struct {
641
+ Content string `json:"content"`
642
+ Type string `json:"type"`
643
+ }`json:"body"`
644
+ }
645
+ reqBody .Body .Content = req .Input
646
+ reqBody .Body .Type = "user"
647
+
648
+ req ,err := newAgentapiRequest (ctx ,http .MethodPost ,appURL ,"message" ,reqBody )
649
+ if err != nil {
650
+ return err
651
+ }
652
+
653
+ resp ,err := client .Do (req )
654
654
if err != nil {
655
655
return httperror .NewResponseError (http .StatusBadGateway , codersdk.Response {
656
656
Message :"Failed to reach task app endpoint." ,
@@ -799,3 +799,70 @@ func (api *API) authAndDoWithTaskSidebarAppClient(
799
799
}
800
800
return do (ctx ,client ,parsedURL )
801
801
}
802
+
803
+ func newAgentapiRequest (ctx context.Context ,method string ,appURL * url.URL ,appURLPath string ,body any ) (* http.Request ,error ) {
804
+ u := * appURL
805
+ u .Path = path .Join (appURL .Path ,appURLPath )
806
+
807
+ var bodyReader io.Reader
808
+ if body != nil {
809
+ b ,err := json .Marshal (body )
810
+ if err != nil {
811
+ return nil ,httperror .NewResponseError (http .StatusBadRequest , codersdk.Response {
812
+ Message :"Failed to marshal task app request body." ,
813
+ Detail :err .Error (),
814
+ })
815
+ }
816
+ bodyReader = bytes .NewReader (b )
817
+ }
818
+
819
+ req ,err := http .NewRequestWithContext (ctx ,method ,u .String (),bodyReader )
820
+ if err != nil {
821
+ return nil ,httperror .NewResponseError (http .StatusBadRequest , codersdk.Response {
822
+ Message :"Failed to create task app request." ,
823
+ Detail :err .Error (),
824
+ })
825
+ }
826
+ req .Header .Set ("Content-Type" ,"application/json" )
827
+ req .Header .Set ("Accept" ,"application/json" )
828
+
829
+ return req ,nil
830
+ }
831
+
832
+ func doAgentapiStatusRequest (ctx context.Context ,client * http.Client ,appURL * url.URL ) (string ,error ) {
833
+ req ,err := newAgentapiRequest (ctx ,http .MethodGet ,appURL ,"status" ,nil )
834
+ if err != nil {
835
+ return "" ,err
836
+ }
837
+
838
+ resp ,err := client .Do (req )
839
+ if err != nil {
840
+ return "" ,httperror .NewResponseError (http .StatusBadGateway , codersdk.Response {
841
+ Message :"Failed to reach task app endpoint." ,
842
+ Detail :err .Error (),
843
+ })
844
+ }
845
+ defer resp .Body .Close ()
846
+
847
+ if resp .StatusCode != http .StatusOK {
848
+ return "" ,httperror .NewResponseError (http .StatusBadGateway , codersdk.Response {
849
+ Message :"Task app status returned an error." ,
850
+ Detail :fmt .Sprintf ("Status code: %d" ,resp .StatusCode ),
851
+ })
852
+ }
853
+
854
+ var respBody struct {
855
+ Body struct {
856
+ Status string `json:"status"`
857
+ }`json:"body"`
858
+ }
859
+
860
+ if err := json .NewDecoder (resp .Body ).Decode (& respBody );err != nil {
861
+ return "" ,httperror .NewResponseError (http .StatusBadGateway , codersdk.Response {
862
+ Message :"Failed to decode task app status response body." ,
863
+ Detail :err .Error (),
864
+ })
865
+ }
866
+
867
+ return respBody .Body .Status ,nil
868
+ }