fix: the assistant's web search and page reading on by default, as the chat - they refused («ассистент выключен в профиле») anyone who never touched the switch

This commit is contained in:
redtea committed 2026-10-18 11:26:20 +03:00
1 parent 114f8b1e1b
commit 054fc97da8
4 files changed
+51 -3

No files matched your search

+7 -1
View File
@@ -47,6 +47,12 @@ func aiNativeKey(id string) string { return "ai_native_" + id }
// default; an explicit "0" means the user turned it off. // default; an explicit "0" means the user turned it off.
func aiUserKey(id int64) string { return "ai_user_" + strconv.FormatInt(id, 10) } func aiUserKey(id int64) string { return "ai_user_" + strconv.FormatInt(id, 10) }
// aiOn: the user has the assistant - on unless turned off.
func (s *Server) aiOn(id int64) bool {
v, _ := s.db.GetConfig(aiUserKey(id))
return v != "0"
}
// aiConfig is one model the assistant can ask: its id and the names the chat // aiConfig is one model the assistant can ask: its id and the names the chat
// shows (Short, up to 12 characters, on the button of the model in use), the // shows (Short, up to 12 characters, on the button of the model in use), the
// kind of API, its address, model and key. // kind of API, its address, model and key.
@@ -833,7 +839,7 @@ func (s *Server) aiAdopt(owner int64) {
// text with "[ошибка: …]". // text with "[ошибка: …]".
func (s *Server) handleAIChat(w http.ResponseWriter, r *http.Request) { func (s *Server) handleAIChat(w http.ResponseWriter, r *http.Request) {
a := s.currentAdmin(r) a := s.currentAdmin(r)
if on, _ := s.db.GetConfig(aiUserKey(a.ID)); on == "0" { if !s.aiOn(a.ID) {
http.Error(w, "ассистент выключен в профиле", http.StatusForbidden) http.Error(w, "ассистент выключен в профиле", http.StatusForbidden)
return return
} }
+42
View File
@@ -0,0 +1,42 @@
package server
import (
"fmt"
"net/http"
"net/http/httptest"
"strings"
"testing"
)
// The assistant is on unless the user turned it off - for the web search
// and page reading as for the chat (a user who never touched the switch
// has no setting at all).
func TestAISearchAndFetchOnByDefault(t *testing.T) {
s, c := newTestServer(t)
sx := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, `{"results":[{"title":"Intel","url":"https://example.com/intel","content":"процессоры"}]}`)
}))
defer sx.Close()
_ = s.db.SetConfig(cfgSearchEngine, "searxng")
_ = s.db.SetConfig(cfgSearchURL, sx.URL)
post := func(path, body string) string {
req := httptest.NewRequest(http.MethodPost, path, strings.NewReader(body))
req.AddCookie(c)
w := httptest.NewRecorder()
s.Handler().ServeHTTP(w, req)
return w.Body.String()
}
if got := post("/api/panel/ai/search", `{"q":"intel"}`); !strings.Contains(got, `"ok":true`) {
t.Fatalf("search by default: %s", got)
}
if got := post("/api/panel/ai/fetch", `{"url":"не адрес"}`); strings.Contains(got, "выключен") {
t.Fatalf("fetch by default: %s", got)
}
a, _ := s.db.AdminByUsername("adm")
_ = s.db.SetConfig(aiUserKey(a.ID), "0")
for _, p := range []string{"/api/panel/ai/search", "/api/panel/ai/fetch"} {
if got := post(p, `{"q":"intel","url":"https://example.com"}`); !strings.Contains(got, "выключен") {
t.Fatalf("%s with the assistant off: %s", p, got)
}
}
}
+1 -1
View File
@@ -179,7 +179,7 @@ func pageText(page string) (string, string) {
// assistant on. // assistant on.
func (s *Server) handleAIFetch(w http.ResponseWriter, r *http.Request) { func (s *Server) handleAIFetch(w http.ResponseWriter, r *http.Request) {
a := s.currentAdmin(r) a := s.currentAdmin(r)
if on, _ := s.db.GetConfig(aiUserKey(a.ID)); on != "1" { if !s.aiOn(a.ID) {
writeJSON(w, map[string]any{"ok": false, "error": "ассистент выключен в профиле"}) writeJSON(w, map[string]any{"ok": false, "error": "ассистент выключен в профиле"})
return return
} }
+1 -1
View File
@@ -262,7 +262,7 @@ func webSearch(ctx context.Context, q string, n int) ([]searchResult, error) {
// assistant on (the «Поиск» switch is the page's: it lets the model ask). // assistant on (the «Поиск» switch is the page's: it lets the model ask).
func (s *Server) handleAISearch(w http.ResponseWriter, r *http.Request) { func (s *Server) handleAISearch(w http.ResponseWriter, r *http.Request) {
a := s.currentAdmin(r) a := s.currentAdmin(r)
if on, _ := s.db.GetConfig(aiUserKey(a.ID)); on != "1" { if !s.aiOn(a.ID) {
writeJSON(w, map[string]any{"ok": false, "error": "ассистент выключен в профиле"}) writeJSON(w, map[string]any{"ok": false, "error": "ассистент выключен в профиле"})
return return
} }