Files
wehub-resource-sync a06f331eb8
CI / benchmark (push) Has been skipped
install-script / posix-syntax (push) Successful in 6m1s
CI / build-onnx (push) Failing after 6m43s
init-smoke / dry-run (push) Failing after 15m57s
security / govulncheck (push) Has been cancelled
security / trivy-fs (push) Has been cancelled
CI / test (1.26, ubuntu-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
CI / test (1.26, macos-latest) (push) Has been cancelled
CI / build-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
install-script / powershell-syntax (push) Has been cancelled
install-script / install (macos-14) (push) Has been cancelled
install-script / install (ubuntu-latest) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:33:42 +08:00

124 lines
3.5 KiB
Go

package main
import (
"fmt"
"time"
"github.com/zzet/gortex/internal/config"
"github.com/zzet/gortex/internal/daemon"
gortexmcp "github.com/zzet/gortex/internal/mcp"
)
// resolveFederationConfig loads the .gortex.yaml `federation:` block and
// maps it to the daemon's FederationConfig. Unset knobs stay zero so
// NewFederator's defaults apply. Best-effort: a config load error yields
// the all-default config.
func resolveFederationConfig() daemon.FederationConfig {
cfg, err := config.Load(cfgFile)
if err != nil || cfg == nil {
return daemon.FederationConfig{}
}
f := cfg.Federation
return daemon.FederationConfig{
PerRemoteTimeout: time.Duration(f.PerRemoteTimeoutMs) * time.Millisecond,
Budget: time.Duration(f.BudgetMs) * time.Millisecond,
BreakerThreshold: f.BreakerThreshold,
BreakerCooldown: time.Duration(f.BreakerCooldownMs) * time.Millisecond,
NameKeyedFallback: f.NameKeyedFallback,
}
}
// resolveFederationEdgesConfig loads the federation.edges (cross-daemon
// proxy-edge) block from the active config. Returns the zero value
// (feature off) on a load error.
func resolveFederationEdgesConfig() config.FederationEdgesConfig {
cfg, err := config.Load(cfgFile)
if err != nil || cfg == nil {
return config.FederationEdgesConfig{}
}
return cfg.Federation.Edges
}
// sessionRemoteOverrideSink bridges the MCP session proxy-toggle tools to
// the daemon's per-session overrides and the live router's roster. It is
// wired into the shared MCP server at daemon start; the router accessor
// is dynamic so it tracks a live ControlProxy swap.
type sessionRemoteOverrideSink struct {
sessions *daemon.SessionRegistry
router func() *daemon.Router
}
func (s *sessionRemoteOverrideSink) currentRoster() *daemon.ServersConfig {
if s.router == nil {
return nil
}
r := s.router()
if r == nil {
return nil
}
return r.CurrentConfig()
}
func (s *sessionRemoteOverrideSink) validateSlug(slug string) error {
cfg := s.currentRoster()
if cfg == nil || len(cfg.Server) == 0 {
return fmt.Errorf("no remotes are configured")
}
for _, srv := range cfg.Server {
if srv.Slug == slug {
return nil
}
}
return fmt.Errorf("unknown remote slug %q", slug)
}
func (s *sessionRemoteOverrideSink) SetRemoteOverride(sessionID, slug string, enabled bool) error {
if err := s.validateSlug(slug); err != nil {
return err
}
sess := s.sessions.GetByID(sessionID)
if sess == nil {
return fmt.Errorf("no active session for this override")
}
sess.SetRemoteOverride(slug, enabled)
return nil
}
func (s *sessionRemoteOverrideSink) ClearRemoteOverride(sessionID, slug string) error {
sess := s.sessions.GetByID(sessionID)
if sess == nil {
return fmt.Errorf("no active session for this override")
}
sess.ClearRemoteOverride(slug)
return nil
}
func (s *sessionRemoteOverrideSink) RemoteRosterStatus(sessionID string) ([]gortexmcp.RemoteRosterStatus, error) {
cfg := s.currentRoster()
if cfg == nil {
return nil, nil
}
var ov map[string]bool
if sess := s.sessions.GetByID(sessionID); sess != nil {
ov = sess.RemoteOverrides()
}
out := make([]gortexmcp.RemoteRosterStatus, 0, len(cfg.Server))
for _, srv := range cfg.Server {
global := srv.IsEnabled()
effective := global
var override *bool
if v, set := ov[srv.Slug]; set {
vv := v
override = &vv
effective = v
}
out = append(out, gortexmcp.RemoteRosterStatus{
Slug: srv.Slug,
GlobalEnabled: global,
SessionOverride: override,
Effective: effective,
})
}
return out, nil
}