Files
木子不是木子狸 c9b8263378 sessions, gateway: Sessions lists gateway sessions, and can keep their text on this computer when turned on (#1355, mu-zi-lee)
What changed: the Sessions page lists sessions seen only through the
gateway (from the usage ledger, read-only, a native session of the same id
wins), and shows in gateway mode. A Sessions switch, off by default and
confirmed before it turns on, records each gateway exchange's text under
the config dir (scrubbed, at most 7 days and 256 MiB, cleaned hourly).
Settings sync and restore can't turn it on; POST /api/sessions/recording
turns it on or off and can clear what was kept.

Why: users of magpie as a gateway (gateway mode, LAN clients) had no way
to see their conversations; the owner chose this design on the PR.

Squashed from PR head 6a343ba1 onto origin/main. Conflicts: gui-shell.md
(kept main's placeMenu text, took the PR's Sessions in gateway mode) and
settings_keep_test.go (main's fields plus GatewayConversations).

Run: go build ./..., go vet on gateway, gui, sessions, settings, usage;
go test -race -timeout 900s on those five packages: all ok.
2026-10-10 04:24:18 +08:00

80 lines
2.5 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package gui
import (
"encoding/json"
"fmt"
"net/http"
"sync/atomic"
"github.com/yetone/magpie/internal/agent"
"github.com/yetone/magpie/internal/settings"
)
// Gateway mode (Player on Discord): `magpie web` on a server that is only
// the gateway for other machines' agents shows what such a gateway needs —
// Providers, Gateway, Routing, Usage, Sessions, Plugins and Settings — and leaves out
// what is this machine's agents' (Agents, Library, the settings
// written into agents' files) and its desktop's (the tray, the Dock, open
// at login, notifications). It is the browser page's alone: the app's
// windows show everything whatever it says.
//
// Settings' choice (settings.GatewayMode, "on" or "off") wins; with none,
// `magpie web --gateway` turns it on, and so does a magpie web with no
// agent on its machine (a container, a NAS). Settings › General turns it
// off again, which brings the pages back.
// WebGateway is `magpie web --gateway`'s.
var WebGateway atomic.Bool
// webPage is set once the page is served by `magpie web`: settingsState,
// which has no Windows, tells the page its gateway mode by it.
var webPage atomic.Bool
// gatewayMode says whether the page is in gateway mode, and why: "on" or
// "off" (Settings' choice), "flag" (magpie web --gateway), "no-agents", or
// "" (the app's windows, or magpie web on a machine with agents).
func gatewayMode(web bool) (bool, string) {
if !web {
return false, ""
}
switch m := settings.Load().GatewayMode; m {
case "on", "off":
return m == "on", m
}
if WebGateway.Load() {
return true, "flag"
}
if !agentsHere() {
return true, "no-agents"
}
return false, ""
}
// agentsHere says whether an agent is found on this computer; a test's own.
var agentsHere = func() bool { return len(agent.Detected()) > 0 }
// gatewayModeRoutes: POST /api/settings/gateway-mode {"mode": "on" | "off"
// | ""} sets Settings' choice, "" leaving it to magpie again.
func gatewayModeRoutes(mux *http.ServeMux) {
mux.HandleFunc("POST /api/settings/gateway-mode", func(rw http.ResponseWriter, r *http.Request) {
var in struct {
Mode string `json:"mode"`
}
if err := json.NewDecoder(r.Body).Decode(&in); err != nil {
fail(rw, err)
return
}
if in.Mode != "" && in.Mode != "on" && in.Mode != "off" {
fail(rw, fmt.Errorf("gateway mode is on, off or \"\" (automatic), not %q", in.Mode))
return
}
s := settings.Load()
s.GatewayMode = in.Mode
if err := settings.Save(s); err != nil {
fail(rw, err)
return
}
writeJSON(rw, settingsState())
})
}