From b10e18fe42b436e758729ea8d53890c7b800ab4a Mon Sep 17 00:00:00 2001 From: mlsmaycon Date: Wed, 19 Aug 2026 06:43:27 +0000 Subject: [PATCH] [e2e] Close the two gaps the first spike run left on Vertex MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The publisher listing answered only under v1beta1, and returned two models — fewer than the catalog ships. That is what a publisher-global list looks like rather than what a given project has enabled, and per-project availability is most of why live discovery beats a static catalogue. The project-scoped form was only tried under v1, which 404s like every other v1 path here, so try it under the version that answers. Also ask for all versions. A publisher model is addressed as '@' on the rawPredict path while the plain listing reports one versionId per model, so a model with several live versions would have the rest silently hidden from a picker. Report the version in the extracted id for the same reason: Vertex splits the wire id across name and versionId, and a listing that showed only the name would look usable without being so. --- e2e/providerdiscovery/discovery_spike_test.go | 36 +++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/e2e/providerdiscovery/discovery_spike_test.go b/e2e/providerdiscovery/discovery_spike_test.go index f8fe4134b..e15f1ecb8 100644 --- a/e2e/providerdiscovery/discovery_spike_test.go +++ b/e2e/providerdiscovery/discovery_spike_test.go @@ -231,6 +231,28 @@ func vertexProbes(t *testing.T) []probe { "/locations/" + region + "/publishers/anthropic/models", headers: auth, }, + { + // The project-scoped list under the version that actually answers. + // The first run's publisher list returned only two models, fewer + // than the catalog ships, which is what a publisher-global list + // looks like rather than what THIS project has enabled — and + // per-project availability is most of why live discovery beats a + // static catalogue. The v1 form 404s, so v1beta1 is the one form + // left that could carry it. + surface: "vertex_ai_api", variant: "v1beta1-project-scoped", + url: "https://" + host + "/v1beta1/projects/" + project + + "/locations/" + region + "/publishers/anthropic/models", + headers: auth, + }, + { + // A publisher model is addressed as "@" on the + // rawPredict path, and the plain listing reports one versionId per + // model. If a model has several live versions, a picker that only + // ever saw one would silently hide the rest. + surface: "vertex_ai_api", variant: "v1beta1-all-versions", + url: "https://" + host + "/v1beta1/publishers/anthropic/models?listAllVersions=true", + headers: auth, + }, } } @@ -322,9 +344,19 @@ func extractIDs(body []byte) (string, []string) { ids := make([]string, 0, len(entries)) for _, entry := range entries { var id string - if err := json.Unmarshal(entry[shape.idField], &id); err == nil && id != "" { - ids = append(ids, id) + if err := json.Unmarshal(entry[shape.idField], &id); err != nil || id == "" { + continue } + // Vertex splits the wire id across two fields: a publisher model is + // addressed as "@" on rawPredict, so a listing that + // reported only the name would look usable and not be. + var version string + if raw, ok := entry["versionId"]; ok { + if err := json.Unmarshal(raw, &version); err == nil && version != "" { + id += "@" + version + } + } + ids = append(ids, id) } return shape.envelope, ids }