返回 DeepSeek-Reasonix
submit_request.go
根目录 / internal / serve / submit_request.go
1 package serve
2
3 import (
4 "encoding/json"
5 "net/http"
6 "strings"
7
8 "reasonix/internal/control"
9 )
10
11 // submit runs raw user input as a turn (slash commands and @-references
12 // resolved by the controller). Returns 202 — output arrives on the event stream.
13 // An optional "format":"json_object" asks the model for structured JSON output
14 // on this turn (text.format on the wire).
15 type submitRequest struct {
16 SubmissionID string `json:"submissionId"`
17 Input string `json:"input"`
18 Format string `json:"format"`
19 Action string `json:"action"`
20 RecoveryID string `json:"recoveryId"`
21 }
22
23 func decodeSubmitRequest(w http.ResponseWriter, r *http.Request) (submitRequest, string, bool) {
24 var body submitRequest
25 if err := json.NewDecoder(r.Body).Decode(&body); err != nil || (body.Input == "" && body.Action != control.ProtocolRecoveryAction) {
26 http.Error(w, "missing input", http.StatusBadRequest)
27 return submitRequest{}, "", false
28 }
29 if len(body.SubmissionID) > 256 {
30 http.Error(w, "submissionId is too long", http.StatusBadRequest)
31 return submitRequest{}, "", false
32 }
33 body.Format = strings.TrimSpace(body.Format)
34 body.Action = strings.TrimSpace(body.Action)
35 if body.Action == control.ProtocolRecoveryAction && strings.TrimSpace(body.RecoveryID) == "" {
36 http.Error(w, "missing recoveryId", http.StatusBadRequest)
37 return submitRequest{}, "", false
38 }
39 switch body.Format {
40 case "", "json_object":
41 // Supported: empty = default text output, json_object = structured.
42 default:
43 http.Error(w, `unsupported format (supported: "json_object")`, http.StatusBadRequest)
44 return submitRequest{}, "", false
45 }
46 if err := validateSubmitAction(body.Format, body.Action); err != nil {
47 http.Error(w, err.Error(), http.StatusBadRequest)
48 return submitRequest{}, "", false
49 }
50 trimmed := strings.TrimSpace(body.Input)
51 // Typed recovery guidance is never dispatched as a management command.
52 if body.Action != "" {
53 trimmed = ""
54 }
55 if strings.HasPrefix(trimmed, "!") {
56 http.Error(w, "shell commands are unavailable over HTTP", http.StatusForbidden)
57 return submitRequest{}, "", false
58 }
59 return body, trimmed, true
60 }
61
61 lines GO