139 lines
4.7 KiB
Diff
139 lines
4.7 KiB
Diff
diff --git a/internal/client/codex/models/experimental_context_test.go b/internal/client/codex/models/experimental_context_test.go
|
|
new file mode 100644
|
|
index 00000000..e41a1ec1
|
|
--- /dev/null
|
|
+++ b/internal/client/codex/models/experimental_context_test.go
|
|
@@ -0,0 +1,37 @@
|
|
+package models
|
|
+
|
|
+import (
|
|
+ "encoding/json"
|
|
+ "testing"
|
|
+
|
|
+ "github.com/router-for-me/CLIProxyAPI/v8/internal/registry"
|
|
+)
|
|
+
|
|
+func TestCodexExperimentalContextFollowsCanonicalAlias(t *testing.T) {
|
|
+ r := registry.GetGlobalRegistry()
|
|
+ const clientID = "experimental-context-alias-test"
|
|
+ r.RegisterClient(clientID, "codex", []*registry.ModelInfo{
|
|
+ {ID: "context-test-alias", MetadataModelID: "gpt-6-astra"},
|
|
+ {ID: "context-test-unrelated"},
|
|
+ })
|
|
+ t.Cleanup(func() { r.UnregisterClient(clientID) })
|
|
+ response := BuildResponseForClient([]map[string]any{
|
|
+ {"id": "gpt-6-astra"}, {"id": "context-test-alias"}, {"id": "context-test-unrelated"},
|
|
+ }, r.GetModelProviders, false, "0.155.0")
|
|
+ encoded, err := MarshalCompact(response)
|
|
+ if err != nil {
|
|
+ t.Fatal(err)
|
|
+ }
|
|
+ var decoded codexClientModelsPayload
|
|
+ if err := json.Unmarshal(encoded, &decoded); err != nil || len(decoded.Models) != 3 {
|
|
+ t.Fatalf("serialized catalog = %s, err = %v", encoded, err)
|
|
+ }
|
|
+ for _, entry := range decoded.Models {
|
|
+ slug := stringModelValue(entry, "slug")
|
|
+ want := slug != "context-test-unrelated"
|
|
+ got, present := entry["supports_experimental_context"].(bool)
|
|
+ if got != want || (slug != "context-test-unrelated" && !present) {
|
|
+ t.Fatalf("%s experimental context = %v, want %v", slug, got, want)
|
|
+ }
|
|
+ }
|
|
+}
|
|
diff --git a/internal/registry/codex_client_models.go b/internal/registry/codex_client_models.go
|
|
index 370abf29..1fae27be 100644
|
|
--- a/internal/registry/codex_client_models.go
|
|
+++ b/internal/registry/codex_client_models.go
|
|
@@ -10,6 +10,8 @@ import (
|
|
"sync"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
+ "github.com/tidwall/gjson"
|
|
+ "github.com/tidwall/sjson"
|
|
)
|
|
|
|
//go:embed models/codex_client_models.json
|
|
@@ -59,6 +61,17 @@ func loadCodexClientModelsFromBytes(data []byte, source string) (bool, error) {
|
|
return false, fmt.Errorf("%s: %w", source, err)
|
|
}
|
|
|
|
+ // This patched host supports Astra experimental context, including after remote refresh.
|
|
+ for i, model := range gjson.GetBytes(data, "models").Array() {
|
|
+ if model.Get("slug").String() == "gpt-6-astra" {
|
|
+ updated, err := sjson.SetBytes(data, fmt.Sprintf("models.%d.supports_experimental_context", i), true)
|
|
+ if err != nil {
|
|
+ return false, fmt.Errorf("%s: supplement experimental context capability: %w", source, err)
|
|
+ }
|
|
+ data = updated
|
|
+ }
|
|
+ }
|
|
+
|
|
cloned := append([]byte(nil), data...)
|
|
codexClientCatalogStore.mu.Lock()
|
|
defer codexClientCatalogStore.mu.Unlock()
|
|
diff --git a/internal/registry/codex_experimental_context_test.go b/internal/registry/codex_experimental_context_test.go
|
|
new file mode 100644
|
|
index 00000000..c8d5e3ef
|
|
--- /dev/null
|
|
+++ b/internal/registry/codex_experimental_context_test.go
|
|
@@ -0,0 +1,58 @@
|
|
+package registry
|
|
+
|
|
+import (
|
|
+ "context"
|
|
+ "encoding/json"
|
|
+ "net/http"
|
|
+ "net/http/httptest"
|
|
+ "testing"
|
|
+)
|
|
+
|
|
+func TestExperimentalContextCatalogRefresh(t *testing.T) {
|
|
+ original, _ := GetCodexClientModelsSnapshot()
|
|
+ previousURLs := codexClientModelsURLs
|
|
+ t.Cleanup(func() {
|
|
+ codexClientModelsURLs = previousURLs
|
|
+ if _, err := loadCodexClientModelsFromBytes(original, "test cleanup"); err != nil {
|
|
+ t.Fatal(err)
|
|
+ }
|
|
+ })
|
|
+ for _, tc := range []struct {
|
|
+ name string
|
|
+ value any
|
|
+ want bool
|
|
+ }{
|
|
+ {"missing", nil, true},
|
|
+ {"explicit false", false, true},
|
|
+ {"explicit true", true, true},
|
|
+ } {
|
|
+ t.Run(tc.name, func(t *testing.T) {
|
|
+ model := testCodexClientModel("gpt-6-astra", 2)
|
|
+ if tc.value != nil {
|
|
+ model["supports_experimental_context"] = tc.value
|
|
+ }
|
|
+ catalog := testCodexClientCatalog(t, testCodexClientModel("gpt-5.5", 1), model)
|
|
+ server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
+ _, _ = w.Write(catalog)
|
|
+ }))
|
|
+ defer server.Close()
|
|
+ codexClientModelsURLs = []string{server.URL}
|
|
+ tryRefreshCodexClientModels(context.Background(), "test experimental refresh")
|
|
+ data, revision := GetCodexClientModelsSnapshot()
|
|
+ var payload codexClientModelsPayload
|
|
+ if err := json.Unmarshal(data, &payload); err != nil {
|
|
+ t.Fatal(err)
|
|
+ }
|
|
+ if got := payload.Models[1]["supports_experimental_context"]; got != tc.want {
|
|
+ t.Fatalf("experimental context = %v, want %v", got, tc.want)
|
|
+ }
|
|
+ if _, exists := payload.Models[0]["supports_experimental_context"]; exists {
|
|
+ t.Fatal("unrelated model gained experimental context")
|
|
+ }
|
|
+ tryRefreshCodexClientModels(context.Background(), "test repeated refresh")
|
|
+ if GetCodexClientModelsRevision() != revision {
|
|
+ t.Fatal("unchanged catalog advanced revision")
|
|
+ }
|
|
+ })
|
|
+ }
|
|
+}
|