Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions docs/changes/unreleased/1870-codex-model-catalog-version.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
kind: fixed
title: Codex discovery lists newer models available to the signed-in account
pr: 1870
surface: [chat, engine]
invalidates: []
---

Update the shared catalog client version from 0.144.1 to 0.162.1. The account
backend gates model visibility by client version, so the older version omitted
newer models even for accounts with access. Direct listing and translated
catalog requests use the same version; account permissions and visibility
filtering are unchanged.
85 changes: 85 additions & 0 deletions internal/codexauth/models_version_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package codexauth

import (
"context"
"encoding/json"
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"

"github.com/Agent-Field/codeaf/internal/provider"
)

func TestCatalogVersionExposesNewModelsThroughBothDoors(t *testing.T) {
for _, door := range []string{"direct", "translated"} {
t.Run(door, func(t *testing.T) {
now := time.Unix(1_800_000_000, 0)
dir := t.TempDir()
if err := Save(dir, validTokens(now)); err != nil {
t.Fatal(err)
}
backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet || r.URL.Path != "/models" ||
r.Header.Get("Authorization") != "Bearer access-token-secret" ||
r.Header.Get("chatgpt-account-id") != "account-one" ||
r.Header.Get("originator") != Originator ||
r.Header.Get("User-Agent") != provider.DirectUserAgent {
http.Error(w, "unexpected catalog request", http.StatusBadRequest)
return
}
rows := []map[string]any{
{"slug": "baseline", "visibility": "list"},
{"slug": "hidden", "visibility": "hide"},
}
// The backend fixture pins the released version independently of
// clientVersion, so restoring the old advertisement hides the row.
if r.URL.Query().Get("client_version") == "0.162.1" {
rows = append(rows, map[string]any{
"slug": "new-model", "visibility": "list", "context_window": 272000,
"supported_reasoning_levels": []map[string]string{{"effort": "high"}},
})
}
_ = json.NewEncoder(w).Encode(map[string]any{"models": rows})
}))
defer backend.Close()
options := Options{Backend: backend.URL, HTTPClient: backend.Client(), Now: func() time.Time { return now }}
var ids []string
if door == "direct" {
models, err := List(context.Background(), dir, options)
if err != nil {
t.Fatal(err)
}
for _, model := range models {
ids = append(ids, model.ID)
}
} else {
response, err := ClientWithOptions(dir, options).Get(backend.URL + "/models")
if err != nil {
t.Fatal(err)
}
defer response.Body.Close()
if response.StatusCode != http.StatusOK {
t.Fatalf("catalog status = %d", response.StatusCode)
}
var catalog struct {
Data []struct{ ID string } `json:"data"`
}
if err := json.NewDecoder(response.Body).Decode(&catalog); err != nil {
t.Fatal(err)
}
for _, model := range catalog.Data {
ids = append(ids, model.ID)
}
}
if strings.Join(ids, ",") != "baseline,new-model" {
t.Fatalf("visible models = %v; newer catalog models must be exposed and hidden rows excluded", ids)
}
cached := loadModels(dir)
if len(cached) != 2 || cached[1].ID != "new-model" || cached[1].ContextLength != 272000 || strings.Join(cached[1].ReasoningLevels, ",") != "high" {
t.Fatalf("cached catalog metadata = %+v", cached)
}
})
}
}
2 changes: 1 addition & 1 deletion internal/codexauth/tokens.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const (
ClientID = "app_EMoamEEZ73f0CkXaXp7hrann"
Sentinel = "chatgpt"
Originator = "codex_cli_rs"
clientVersion = "0.144.1"
clientVersion = "0.162.1"
)

// signInExpiredError is terminal before the provider's ordinary transport
Expand Down
Loading