package main import ( "bytes" "context" "encoding/json" "net/http" "net/http/httptest" "testing" "time" "git.cin.su/m/Assistant/contracts/capability" "git.cin.su/m/Assistant/contracts/cognitive" ) func TestBuiltinInterpretationTimeoutRetainsDeterministicCandidate(t *testing.T) { request := cognitive.GatewayInterpretationRequest{ Version: cognitive.CreatorAdvisoryV1, RequestID: "request-1", DeterministicSpeechAct: "QUESTION", DeterministicConfidence: 720, DeterministicApplicability: cognitive.InterpretationNeedsBroader, RequestedOutcome: "вывести список настроек", } response := (cognitiveGateway{}).interpretWithBuiltin(context.Background(), request, 4096) if response.FinishReason != cognitive.FinishCompleted { t.Fatalf("finish reason=%q", response.FinishReason) } if response.Candidate.PrimarySpeechAct != "QUESTION" || response.Candidate.ConfidenceMillis != 720 || response.Candidate.RequestedOutcome != request.RequestedOutcome { t.Fatalf("candidate did not retain deterministic meaning: %+v", response.Candidate) } } func TestInterpretationProviderFailureUsesLocalLifeboat(t *testing.T) { selected := gatewaySelection() selected.Binding.DataPolicy = capability.DataPolicyLocalOnly primary := &stubAdvisoryProvider{response: cognitive.AdvisoryResponse{FinishReason: cognitive.FinishProviderUnavailable}} lifeboat := &stubAdvisoryProvider{response: cognitive.AdvisoryResponse{AdvisoryText: `{"primary_speech_act":"QUESTION","secondary_speech_act":"","confidence_millis":900,"applicability":"APPLICABLE","requested_outcome":"","needs_cognition":true,"clarification":"NOT_REQUIRED","selection_reason":"local lifeboat","capability_hints":["COGNITIVE_REASONING"]}`, FinishReason: cognitive.FinishCompleted}} gateway := cognitiveGateway{ resolver: ®istryStub{selected: selected}, providers: map[capability.ProviderKind][]providerRegistration{ selected.Provider.Kind: {{ProviderInstanceID: selected.Provider.ID, Kind: selected.Provider.Kind, Provider: primary}}, }, builtinLocal: &providerRegistration{Provider: lifeboat}, now: time.Now, } request := cognitive.GatewayInterpretationRequest{Version: cognitive.CreatorAdvisoryV1, RequestID: "request-1", ActorID: "actor-1", PrincipalID: "principal-1", ScopeID: "scope-1", Message: "сколько фигур в шахматах?", Locale: "ru", MaxOutputBytes: 4096, DataPolicy: capability.DataPolicyLocalOnly, DeterministicSpeechAct: "QUESTION", DeterministicConfidence: 800, DeterministicApplicability: cognitive.InterpretationApplicable} payload, _ := json.Marshal(request) recorder := httptest.NewRecorder() gateway.interpretationHandler(recorder, httptest.NewRequest(http.MethodPost, "/v1/interpretations", bytes.NewReader(payload))) if recorder.Code != http.StatusOK || !primary.called || !lifeboat.called { t.Fatalf("status=%d primary=%t lifeboat=%t body=%s", recorder.Code, primary.called, lifeboat.called, recorder.Body.String()) } var response cognitive.GatewayInterpretationResponse if err := json.Unmarshal(recorder.Body.Bytes(), &response); err != nil { t.Fatal(err) } if response.FinishReason != cognitive.FinishCompleted || response.Candidate.SelectionReason != "local lifeboat" { t.Fatalf("response=%+v", response) } }