Files
HomeAgent/internal/sdk/proxy.go
JianFeeeee 3f834794c5 refactor: SDK module 路径统一改为 hologramagentsdk(59 文件 + go.mod)
## 为什么必须做

SDK 仓(独立仓库)已把 module 从 `github.com/JianFeeeee/homeagentsdk`
改名为 `hologramagentsdk`。主仓通过 `replace` 直接引用它的**物理目录**:

    replace github.com/JianFeeeee/homeagentsdk => ./third_party/homeagent-sdk

一旦 SDK 侧改成新 module 名,主仓立刻炸:

    go: ./third_party/homeagent-sdk@ used for two different module paths
        (github.com/JianFeeeee/hologramagentsdk and github.com/JianFeeeee/homeagentsdk)

Go **不允许**同一目录被两个 module 路径 replace。所以不能"新旧并存",
只能把主仓 59 个文件的 import 全部改到新名,并删掉旧 replace。

## 一个被证伪的前提

我最初按"third_party/homeagent-sdk 是独立仓库,不能在此仓修改其源码"
来处理,并因此判断两个仓的改动可以隔离。实际上主仓是靠 `replace` 指向
该目录的物理副本 —— **两个仓的改动不可能真正隔离**:SDK 侧改 module 名,
主仓必然跟着改 import。

这个前提应该在做任何改动之前用 `go list -m` 验证,而不是假设。

## 连带修掉两处

| 缺陷 | 性质 |
|---|---|
| `TestLuaSDKMockSingleSource` 失败 | SDK 的 `sdk/lua/sdk.lua` 变了,主仓内嵌副本未同步(跑 `scripts/sync-lua-sdk.sh` 修复) |
| `sdkModuleNames` 分散两处 | 已在 SDK 仓合并为单一数据源(见 SDK 仓 725732b) |

第一条是**副本一致性判据抓到的**,不是我自己发现的 —— 这类判据的价值在此:
两个仓必然有副本,靠人记住"改了 A 要同步 B"是做不到的。

## 验证

- `go build ./...` / `go vet ./...` 干净
- `go test ./... -count=1`:**58 包 0 失败**
- `internal/plugin`(Lua SDK 副本一致性)+ `internal/sdk` 全绿
- 主仓 `third_party/homeagent-sdk/` 与 SDK 仓 `main` 无差异
2026-10-23 15:51:02 +08:00

122 lines
4.3 KiB
Go
Raw 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 sdk —— 反代声明的内核侧登记表。
//
// 契约定义在公开 SDK(pubsdk.ProxyDef)。本文件只做两件事:
//
// 1. 把公开类型重新导出,让内核侧调用方只需 import 本包。
// 2. 维护**内置插件**的声明表(它们没有 plugin.json,扫目录发现不了)。
//
// 外部插件的声明由反代层直接读 plugin.json 得到,不经过这里 —— 那份声明
// 是静态的、插件没启动也可见,而内置插件的声明只能运行期拿到。两种来源在
// 反代层合并(见 webui.buildProxyTable)。
package sdk
import (
"strings"
"sync"
pubsdk "github.com/JianFeeeee/hologramagentsdk/sdk"
)
// ProxyDef 是一条反代声明(见 pubsdk.ProxyDef 的完整文档,含「单一入口原则」)。
// 与 ConfigDef / ChannelDef / ToolDef 同族:SDK 定契约,内核实现行为。
type ProxyDef = pubsdk.ProxyDef
// 鉴权与 Host 规范化的常量/函数转发(调用方不必两处 import)。
const (
// ProxyAuthAgent 表示由内核统一保护(门户会话或 X-API-Key)。
ProxyAuthAgent = pubsdk.ProxyAuthAgent
ProxyAuthNone = pubsdk.ProxyAuthNone
// ProxyAuthAgentLegacy 是旧值 "homeagent":存量 plugin.json 里写的仍是它。
// 只用于兼容读取;判断时一律先过 EffectiveProxyAuth 归一化。
ProxyAuthAgentLegacy = pubsdk.ProxyAuthAgentLegacy
// ProxyAuthHomeAgent 是 ProxyAuthAgent 的旧名,仅为存量源码保留。
//
// Deprecated: 用 ProxyAuthAgent。
ProxyAuthHomeAgent = pubsdk.ProxyAuthHomeAgent
)
// ValidateProxyDef 校验一条声明,返回人类可读的错误(合法时为空)。
func ValidateProxyDef(d ProxyDef) string { return pubsdk.ValidateProxyDef(d) }
// EffectiveProxyAuth 返回生效的鉴权模式(空串与旧值都归一化为 ProxyAuthAgent)。
func EffectiveProxyAuth(auth string) string { return pubsdk.EffectiveProxyAuth(auth) }
// ValidProxyAuth 判断鉴权取值是否合法。
func ValidProxyAuth(auth string) bool { return pubsdk.ValidProxyAuth(auth) }
// NormalizeProxyHost 由插件名推导默认的 Host 标签。
func NormalizeProxyHost(plugin string) string { return pubsdk.NormalizeProxyHost(plugin) }
// ValidProxyHostLabel 校验子域名标签是否合法(DNS label 规则)。
func ValidProxyHostLabel(label string) bool { return pubsdk.ValidProxyHostLabel(label) }
// 内置插件(编译进内核、无 plugin.json)的反代声明表。
//
// 版本号 builtinProxyVer 每次变更自增。反代层据此判断缓存的路由表是否过期 ——
// 比每次请求都重新聚合一遍便宜得多。
var (
builtinProxyMu sync.RWMutex
builtinProxyVer int64
builtinProxyDefs = map[string][]ProxyDef{}
)
// RegisterBuiltinProxy 登记一个内置插件的服务声明(由 RegisterProxy 转发)。
//
// ProxyDef.Name 由调用方保证非空(RegisterProxy 会在缺失时兜底为 "service")。
func RegisterBuiltinProxy(plugin, name string, d ProxyDef) {
if plugin == "" || strings.TrimSpace(d.Target) == "" {
return
}
if d.Name == "" {
d.Name = name
}
if d.Name == "" {
d.Name = "service"
}
builtinProxyMu.Lock()
defer builtinProxyMu.Unlock()
// 同名重复登记(如自动重启后再次 Start)视为刷新,不重复累积。
list := builtinProxyDefs[plugin]
for i := range list {
if list[i].Name == d.Name {
list[i] = d
builtinProxyVer++
return
}
}
builtinProxyDefs[plugin] = append(list, d)
builtinProxyVer++
}
// ClearBuiltinProxyDefs 清除某插件的声明(插件停止/卸载时调用)。
func ClearBuiltinProxyDefs(plugin string) {
builtinProxyMu.Lock()
defer builtinProxyMu.Unlock()
if _, ok := builtinProxyDefs[plugin]; ok {
delete(builtinProxyDefs, plugin)
builtinProxyVer++
}
}
// BuiltinProxyDefs 返回内置声明的快照(plugin → defs)。
func BuiltinProxyDefs() map[string][]ProxyDef {
builtinProxyMu.RLock()
defer builtinProxyMu.RUnlock()
out := make(map[string][]ProxyDef, len(builtinProxyDefs))
for k, v := range builtinProxyDefs {
cp := make([]ProxyDef, len(v))
copy(cp, v)
out[k] = cp
}
return out
}
// BuiltinProxyVersion 是声明表的版本号,供反代层判断缓存是否过期。
func BuiltinProxyVersion() int64 {
builtinProxyMu.RLock()
defer builtinProxyMu.RUnlock()
return builtinProxyVer
}