Skip to content

llm v0.15.0

Choose a tag to compare

@zy84338719 zy84338719 released this 21 Oct 08:49
· 29 commits to main since this release

下游要做什么

什么都不用做——纯增量:字段缺省为 nil 时行为逐字不变,现有调用方不需要改。

想给 LLM 出站挂守卫的宿主,改一行:

hc, err := netguard.NewClient(nil, netguard.Allow{Private: true, Loopback: true})
cfg.HTTPClient = hc   // hc.Transport 挂了 netguard.DialFunc

(netguard 在 agent-harness 仓;这里是说明接线形态,本仓不依赖它。)

为什么需要

写面校验(按 URL 判)拦不住 DNS rebinding——两次解析之间权威 DNS 可以改口:

写面校验:evil.example → 1.2.3.4        (公网,放行)
实际请求:evil.example → 169.254.169.254 (元数据段,已不在判定面内)

要闭合它,守卫必须挂在 Transport.DialContext 上,这要求宿主能提供自己的 *http.Transport(或整个 *http.Client)。而 LLM 档案的 base_url 是用户可配的(平台代发 LLM 请求的目标),是这条链上暴露最大的一个面。

语义:显式注入优先于内部构造

宿主注入 捕获 Retry-After 行为
否 否 返回 nil——走 openai 包内部缺省(既有行为逐字不变)
否 是 自建 client(既有行为逐字不变)
是 否 原样使用宿主注入的 client
是 是 在宿主注入的 Transport 外面套一层 RetryAfterTransport

最后一行是此前做不到的组合:自建 client 走 http.DefaultTransport,宿主的守卫挂不上去——CaptureRetryAfter 与自定义守卫此前是互相排斥的。现在合流。

派生时复制一份 client,不就地改写宿主传进来的那个。

超时语义:注入后由注入的 Client 完全接管(eino 侧同一口径——设了 HTTPClient 就不再用 config.Timeout)。

顺带抬的地板

oekit/pkg         v0.18.0 → v0.20.0
oekit/concurrency v0.18.0 → v0.19.0

对本仓零行为差异:本仓只 import concurrency/async 与 concurrency/breaker,这两个包在 v0.18.0→v0.19.0 之间一字未动。

门禁

go vet / test -race   ✅ 5 包全绿
gofmt -l .            ✅ 空
golangci-lint         ✅ 0 issues