Repository navigation
fix(api): serve Muse Code's model catalog at /muse-code/models (HOUSE-114) - #30
Conversation
…-114) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
✅ Accepted riskAccepted by ericlitman: HOUSE-114 (authority 48fa77b) 🟡 Medium · Redirects replace the upstream status and body 🟡 Medium · Catalog requests ignore configured Meta headers 🟡 Medium · Catalog route pins lowest-ID Meta credential, ignoring its health DetailsRun: @unfret review · @unfret status · @unfret help |
| req.Header.Set("Authorization", "Bearer "+token) | ||
| req.Header.Set("Accept", "application/json") | ||
|
|
||
| resp, errDo := helps.NewProxyAwareHTTPClient(ctx, s.getConfig(), credential, 0).Do(req) |
There was a problem hiding this comment.
🟡 Medium · Redirects replace the upstream status and body
NewProxyAwareHTTPClient leaves CheckRedirect unset, so this call follows redirects rather than preserving the catalog endpoint's response. For example, an upstream 302 Location: /login with a JSON error becomes the login page's 200 text/html response. This was reproduced through the registered route and violates the required status/body passthrough, presenting non-catalog bytes as a successful response.
| req.Header.Set("Authorization", "Bearer "+token) | ||
| req.Header.Set("Accept", "application/json") | ||
|
|
||
| resp, errDo := helps.NewProxyAwareHTTPClient(ctx, s.getConfig(), credential, 0).Do(req) |
There was a problem hiding this comment.
🟡 Medium · Catalog requests ignore configured Meta headers
Meta credentials support custom headers, which the normal Meta executor applies through ApplyCustomHeadersFromAttrs. This request instead sends only the hard-coded headers; NewProxyAwareHTTPClient configures transport but does not apply credential headers. For a configured Meta gateway requiring an extra authentication header, inference succeeds but /muse-code/models returns 403 and Muse Code still cannot start without a cached catalog. A route-level reproduction confirmed this difference using the same credential. Also reported for this defect: - Catalog requests drop configured credential headers (internal/api/server_muse_code_models.go:38-41): Meta credentials support custom headers through header:* attributes, which the existing Meta executor applies, but this request sends only the built-in headers. If the configured Meta origin requires an additional header such as X-Tenant-Key, normal Meta requests succeed while /muse-code/models returns 403, leaving Muse unable to start. Passing the credential to NewProxyAwareHTTPClient does not apply those headers; it only configures transport.
Also affects:
| if !strings.EqualFold(candidate.Provider, "meta") || candidate.Disabled || candidate.Status == auth.StatusDisabled { | ||
| continue | ||
| } | ||
| baseURL, token := helps.MetaCreds(candidate) | ||
| if token == "" { | ||
| continue | ||
| } | ||
| if chosen == nil || candidate.ID < chosen.ID { | ||
| chosen, chosenBaseURL, chosenToken = candidate, baseURL, token |
There was a problem hiding this comment.
🟡 Medium · Catalog route pins lowest-ID Meta credential, ignoring its health
museCodeCredential skips only Disabled/StatusDisabled credentials and then always picks the lexically lowest ID. It ignores the error, unavailable and cooldown state that the auth manager uses to steer model traffic away from a broken credential, and it never falls back to another candidate. Scenario: two Meta credentials. meta-a has the lowest ID and a revoked key, so the manager marks it errored and serves model requests through meta-b, which is healthy. Every GET /muse-code/models still uses meta-a and forwards the upstream 401, so Muse Code cannot fetch its catalog or start even though a usable credential exists. The same pinning causes a permanent 502 when the lowest-ID credential has a malformed base_url while others are valid.
|
Waiver for head 21eb29d (HOUSE-114). All three blocking findings are pre-accepted: their triggers lie outside our actual usage, and none involves security, secret exposure, data loss, or gate integrity.
If any of these occurs in production, it becomes a ticket fixed with a class rule. |
✅ Merged into
|
Summary
Muse Code pointed at the proxy fetches its model catalog from
<origin>/muse-code/models. The proxy had no such route, so hosts without a cached catalog could not start Muse Code (HOUSE-113).Evidence
GET /muse-code/modelswith the client key → 404. studio1 with no cached catalog:muse exec→failed to fetch model catalog: API error 404: empty response body.21eb29dd434ef9cc26c5021ac43eeced1034b621) built and run on studio2 at port 18317 with only the live Meta credential:muse-wonder-full-1.0-contributor muse-wonder-full-1.0 muse-wonder-1.0-contributor muse-wonder-1.0 muse-spark-1.3-contributor muse-spark-1.3 muse-image-1.0 muse-spark-1.2-contributor muse-spark-1.2TestMuseCodeModelsRoute(table test through the registered route, fake upstream): catalog bytes and status (418) forwarded, upstream saw/muse-code/modelswith no query and the Meta bearer; no Meta credential → 503; no client key → 401 with no upstream call. All three cases fail with 404 on main.Merge Danger
Door: two-way
A new route and a moved function; reverting removes both.
Blast Radius: small
Only
GET /muse-code/modelsis new. Meta model requests now resolve credentials throughhelps.MetaCreds, a byte-for-byte move ofmetaCreds(same body, renamed).Acceptance criteria
Met: live 200 with Meta's catalog above; unit case
proxies_catalog.Met: unit case
no_meta_credential→ 503{"error":"no usable Meta credential for Muse Code models"}.Met:
AuthMiddleware(s.accessManager); live 401 without a key; unit casemissing_client_key.Met with one exception noted below.
Pending deploy after merge.
Gate results (head
21eb29dd434ef9cc26c5021ac43eeced1034b621, run by the orchestrator on studio2)gofmt -lon changed filesgo build -o test-output ./cmd/servergo vet ./internal/api/ ./internal/runtime/executor/...go test -count=1 ./...sdk/cliproxyTestServiceHeartbeatFailoverDoesNotDrainBlockingScopefailed. The same test fails 2 of 10 runs on unchanged main (a9b5081), so it is a pre-existing flake unrelated to this diff.Not verified
helps.MetaCreds; no other comments to review.🤖 Generated with Claude Code
Open in [code]smith · Need help on this PR? Tag
@codesmith-botwith what you need.