()
| 117 | } |
| 118 | |
| 119 | func (s *Server) registerOutbound() { |
| 120 | // 202 Accepted is the HITL-hold outcome of every outbound op: the message |
| 121 | // is queued as a pending_review draft rather than sent. Declared |
| 122 | // explicitly because Huma infers only the single DefaultStatus (200). |
| 123 | held202 := func() *huma.Response { |
| 124 | return s.jsonResponse(reflect.TypeOf(SendResultView{}), "SendResultView", |
| 125 | "Accepted — held for human approval (status=pending_review).") |
| 126 | } |
| 127 | |
| 128 | huma.Register(s.API, huma.Operation{ |
| 129 | OperationID: "sendMessage", Method: http.MethodPost, Path: "/v1/agents/{email}/messages", |
| 130 | Summary: "Send a new email", Tags: []string{"messages"}, |
| 131 | Description: "Send a new email from the agent named in the path (a new thread). The sender is the path agent — `reply`/`forward` are their own sub-resources. 202 + pending_review when the agent has HITL enabled. Honors Idempotency-Key.", |
| 132 | Security: []map[string][]string{{"bearer": {}}}, |
| 133 | MaxBodyBytes: maxOutboundBytes, |
| 134 | Responses: map[string]*huma.Response{"202": held202(), "default": s.errorEnvelopeResponse()}, |
| 135 | }, s.handleCreateMessage) |
| 136 | |
| 137 | huma.Register(s.API, huma.Operation{ |
| 138 | OperationID: "replyToMessage", Method: http.MethodPost, Path: "/v1/agents/{email}/messages/{id}/reply", |
| 139 | Summary: "Reply to a message", Tags: []string{"messages"}, |
| 140 | Description: "Reply to an inbound message; recipients/threading are derived from the original. 202 when held for HITL.", |
| 141 | Security: []map[string][]string{{"bearer": {}}}, |
| 142 | MaxBodyBytes: maxOutboundBytes, |
| 143 | Responses: map[string]*huma.Response{"202": held202(), "default": s.errorEnvelopeResponse()}, |
| 144 | }, s.handleReply) |
| 145 | |
| 146 | huma.Register(s.API, huma.Operation{ |
| 147 | OperationID: "forwardMessage", Method: http.MethodPost, Path: "/v1/agents/{email}/messages/{id}/forward", |
| 148 | Summary: "Forward a message", Tags: []string{"messages"}, |
| 149 | Description: "Forward an inbound message to new recipients; the original is quoted and its attachments are carried over by default. Any attachments[] you supply are added on top of the originals. 202 when held for HITL.", |
| 150 | Security: []map[string][]string{{"bearer": {}}}, |
| 151 | MaxBodyBytes: maxOutboundBytes, |
| 152 | Responses: map[string]*huma.Response{"202": held202(), "default": s.errorEnvelopeResponse()}, |
| 153 | }, s.handleForward) |
| 154 | |
| 155 | huma.Register(s.API, huma.Operation{ |
| 156 | OperationID: "testAgent", Method: http.MethodPost, Path: "/v1/agents/{email}/test", |
| 157 | Summary: "Send a test email to the agent's own address", Tags: []string{"agents"}, |
| 158 | Description: "Send a platform test email to the agent's own address to confirm inbound delivery. 202 when held for HITL.", |
| 159 | Security: []map[string][]string{{"bearer": {}}}, |
| 160 | Responses: map[string]*huma.Response{"202": held202(), "default": s.errorEnvelopeResponse()}, |
| 161 | }, s.handleTestSend) |
| 162 | } |
| 163 | |
| 164 | func (s *Server) handleTestSend(ctx context.Context, in *AddressParam) (*sendOutput, error) { |
| 165 | ag, err := s.resolveOwnedAgent(ctx, in.Address) |
no test coverage detected