diff --git a/sessions_message.go b/sessions_message.go index 3c1bd3c..2baa5c1 100644 --- a/sessions_message.go +++ b/sessions_message.go @@ -61,6 +61,12 @@ type SessionMessageRequest struct { // agent answer through its reply tool only; check the ack to see whether // the server accepted it. DeliveryMode string `json:"delivery_mode,omitempty"` + // Steering asks the session's running turn to take this message in at its + // next step instead of queueing it for a turn of its own. Its answer then + // comes from that running turn, so read it from the session's event stream + // rather than only from this message's own invocation. Ignored when no turn + // is running. + Steering bool `json:"steering,omitempty"` // TeamID binds a new session to a team (0 = account scope). TeamID int64 `json:"team_id,omitempty"` // EnvironmentKind selects the execution environment: "cloud" or "byoc". diff --git a/sessions_message_test.go b/sessions_message_test.go index 7ba0840..b5d1bcd 100644 --- a/sessions_message_test.go +++ b/sessions_message_test.go @@ -35,6 +35,9 @@ func TestSessionsWriteMessageSendsRequestAndDecodesAck(t *testing.T) { if _, ok := body["team_id"]; ok { t.Errorf("zero team_id must be omitted: %v", body) } + if _, ok := body["steering"]; ok { + t.Errorf("false steering must be omitted: %v", body) + } w.WriteHeader(http.StatusAccepted) _, _ = io.WriteString(w, `{"request_id":"r1","data":{"session_id":"s1","invocation_id":"i1","root_invocation_id":"i1","delivery_mode":"reply_only"}}`) }) @@ -58,6 +61,23 @@ func TestSessionsWriteMessageSendsRequestAndDecodesAck(t *testing.T) { } } +func TestSessionsWriteMessageSendsSteering(t *testing.T) { + c := newTestClient(t, func(w http.ResponseWriter, r *http.Request) { + var body map[string]any + if err := json.NewDecoder(r.Body).Decode(&body); err != nil { + t.Fatal(err) + } + if body["steering"] != true { + t.Errorf("steering = %v, want true", body["steering"]) + } + w.WriteHeader(http.StatusAccepted) + _, _ = io.WriteString(w, `{"request_id":"r1","data":{"session_id":"s1","invocation_id":"i2","root_invocation_id":"i2"}}`) + }) + if _, _, err := c.Sessions.WriteMessage(context.Background(), &SessionMessageRequest{SessionID: "s1", Query: "and now?", Steering: true}); err != nil { + t.Fatalf("WriteMessage: %v", err) + } +} + func TestSessionsWriteMessageSurfacesAPIError(t *testing.T) { c := newTestClient(t, func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusBadRequest)