mirror of
https://github.com/tiennm99/goclaw.git
synced 2026-10-11 14:13:21 +00:00
Model listing and chat provider construction rewrite localhost to host.docker.internal via config.DockerLocalhost() when running inside Docker, but all three memory.NewOpenAIEmbeddingProvider call sites (verify-embedding handler, runtime memory embedding) passed the raw api_base through. In Docker the container resolved localhost to itself, so Ollama Verify Embedding and runtime embedding failed with connection refused while the model dropdown loaded fine. Centralize the rewrite inside the constructor so no call site can miss it, add a SetInDockerForTest hook for environment-independent regression tests, and pin Docker detection off in httptest-based suites. Fixes #1519
56 lines
1.5 KiB
Go
56 lines
1.5 KiB
Go
package config
|
|
|
|
import (
|
|
"os"
|
|
"strings"
|
|
"sync"
|
|
"sync/atomic"
|
|
)
|
|
|
|
var (
|
|
dockerOnce sync.Once
|
|
dockerCached bool
|
|
|
|
// inDockerForTest overrides Docker detection. Production code MUST never
|
|
// set this; use SetInDockerForTest exclusively from *_test.go.
|
|
inDockerForTest atomic.Pointer[bool]
|
|
)
|
|
|
|
// SetInDockerForTest forces InDocker to return v, bypassing the /.dockerenv
|
|
// probe. Returns a restore func that reinstates the previous override (or real
|
|
// detection when none was active). Test-only.
|
|
func SetInDockerForTest(v bool) func() {
|
|
prev := inDockerForTest.Load()
|
|
inDockerForTest.Store(&v)
|
|
return func() { inDockerForTest.Store(prev) }
|
|
}
|
|
|
|
// InDocker returns true when running inside a Docker container.
|
|
// Result is cached after the first call.
|
|
func InDocker() bool {
|
|
if override := inDockerForTest.Load(); override != nil {
|
|
return *override
|
|
}
|
|
dockerOnce.Do(func() {
|
|
_, err := os.Stat("/.dockerenv")
|
|
dockerCached = err == nil
|
|
})
|
|
return dockerCached
|
|
}
|
|
|
|
// DockerLocalhost rewrites localhost or 127.0.0.1 in url to host.docker.internal
|
|
// when running inside Docker, so the container can reach host services.
|
|
// Returns the url unchanged when not in Docker or when it doesn't reference loopback.
|
|
func DockerLocalhost(url string) string {
|
|
if !InDocker() {
|
|
return url
|
|
}
|
|
if strings.Contains(url, "localhost") {
|
|
return strings.Replace(url, "localhost", "host.docker.internal", 1)
|
|
}
|
|
if strings.Contains(url, "127.0.0.1") {
|
|
return strings.Replace(url, "127.0.0.1", "host.docker.internal", 1)
|
|
}
|
|
return url
|
|
}
|