feat: add remote config and host metadata
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -12,6 +12,7 @@ type Config struct {
|
|||||||
Events Events `toml:"events"`
|
Events Events `toml:"events"`
|
||||||
Notify Notify `toml:"notify"`
|
Notify Notify `toml:"notify"`
|
||||||
Inbox Inbox `toml:"inbox"`
|
Inbox Inbox `toml:"inbox"`
|
||||||
|
Remote Remote `toml:"remote"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Events struct {
|
type Events struct {
|
||||||
@@ -38,6 +39,13 @@ type Inbox struct {
|
|||||||
TimeoutMS int `toml:"timeout_ms"`
|
TimeoutMS int `toml:"timeout_ms"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Remote struct {
|
||||||
|
Enabled bool `toml:"enabled"`
|
||||||
|
URL string `toml:"url"`
|
||||||
|
Token string `toml:"token"`
|
||||||
|
TimeoutMS int `toml:"timeout_ms"`
|
||||||
|
}
|
||||||
|
|
||||||
func Default() Config {
|
func Default() Config {
|
||||||
return Config{
|
return Config{
|
||||||
Events: Events{Stop: true, Response: true, Idle: false, Tool: false},
|
Events: Events{Stop: true, Response: true, Idle: false, Tool: false},
|
||||||
@@ -49,13 +57,17 @@ func Default() Config {
|
|||||||
BodyTool: "工具执行完成",
|
BodyTool: "工具执行完成",
|
||||||
},
|
},
|
||||||
Inbox: Inbox{
|
Inbox: Inbox{
|
||||||
Enabled: true,
|
Enabled: false,
|
||||||
Socket: DefaultInboxSocket(),
|
Socket: DefaultInboxSocket(),
|
||||||
RemoteSocket: DefaultInboxRemoteSocket(),
|
RemoteSocket: DefaultInboxRemoteSocket(),
|
||||||
Addr: "127.0.0.1:17777",
|
Addr: "127.0.0.1:17777",
|
||||||
FallbackLocal: true,
|
FallbackLocal: true,
|
||||||
TimeoutMS: 500,
|
TimeoutMS: 500,
|
||||||
},
|
},
|
||||||
|
Remote: Remote{
|
||||||
|
Enabled: false,
|
||||||
|
TimeoutMS: 2000,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ func TestDefaultConfig(t *testing.T) {
|
|||||||
if cfg.Notify.Protocol != "osc777" {
|
if cfg.Notify.Protocol != "osc777" {
|
||||||
t.Fatalf("expected osc777, got %q", cfg.Notify.Protocol)
|
t.Fatalf("expected osc777, got %q", cfg.Notify.Protocol)
|
||||||
}
|
}
|
||||||
if !cfg.Inbox.Enabled {
|
if cfg.Inbox.Enabled {
|
||||||
t.Fatal("expected inbox enabled by default")
|
t.Fatal("expected inbox disabled by default")
|
||||||
}
|
}
|
||||||
if cfg.Inbox.Addr != "127.0.0.1:17777" {
|
if cfg.Inbox.Addr != "127.0.0.1:17777" {
|
||||||
t.Fatalf("expected default inbox addr, got %q", cfg.Inbox.Addr)
|
t.Fatalf("expected default inbox addr, got %q", cfg.Inbox.Addr)
|
||||||
@@ -104,6 +104,16 @@ func TestDefaultInboxSocketPrefersXDGRuntimeDir(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDefaultRemoteDisabledInbox(t *testing.T) {
|
||||||
|
cfg := Default()
|
||||||
|
if cfg.Inbox.Enabled {
|
||||||
|
t.Fatal("inbox should default disabled")
|
||||||
|
}
|
||||||
|
if cfg.Remote.TimeoutMS != 2000 {
|
||||||
|
t.Fatalf("remote timeout: got %d", cfg.Remote.TimeoutMS)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestEventEnabled(t *testing.T) {
|
func TestEventEnabled(t *testing.T) {
|
||||||
cfg := Default()
|
cfg := Default()
|
||||||
if !cfg.EventEnabled("stop") {
|
if !cfg.EventEnabled("stop") {
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package hostmeta
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"sort"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Hostname() (string, error) {
|
||||||
|
return os.Hostname()
|
||||||
|
}
|
||||||
|
|
||||||
|
func IPs() []string {
|
||||||
|
seen := make(map[string]struct{})
|
||||||
|
var ips []string
|
||||||
|
|
||||||
|
ifaces, err := net.Interfaces()
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
for _, iface := range ifaces {
|
||||||
|
if iface.Flags&net.FlagUp == 0 || iface.Flags&net.FlagLoopback != 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
addrs, err := iface.Addrs()
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for _, addr := range addrs {
|
||||||
|
var ip net.IP
|
||||||
|
switch v := addr.(type) {
|
||||||
|
case *net.IPNet:
|
||||||
|
ip = v.IP
|
||||||
|
case *net.IPAddr:
|
||||||
|
ip = v.IP
|
||||||
|
default:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if ip == nil || ip.IsLoopback() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if ip4 := ip.To4(); ip4 != nil {
|
||||||
|
ip = ip4
|
||||||
|
}
|
||||||
|
s := ip.String()
|
||||||
|
if _, ok := seen[s]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
seen[s] = struct{}{}
|
||||||
|
ips = append(ips, s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sort.Strings(ips)
|
||||||
|
return ips
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package hostmeta
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestHostnameNonEmpty(t *testing.T) {
|
||||||
|
h, err := Hostname()
|
||||||
|
if err != nil || h == "" {
|
||||||
|
t.Fatalf("hostname: %q err=%v", h, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIPsSkipsLoopback(t *testing.T) {
|
||||||
|
ips := IPs()
|
||||||
|
for _, ip := range ips {
|
||||||
|
if ip == "127.0.0.1" || ip == "::1" {
|
||||||
|
t.Fatalf("loopback in ips: %v", ips)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user