[e2e] cover unversioned Vertex models, versioned config ids, and count-tokens

Extend the agent-network e2e to the Vertex request shapes a customer
actually sends through Claude Code:

- Register the Vertex provider's model under the raw "@version" id the
  Google console documents, so the router's candidate normalization is
  exercised end to end (previously the provider was created with no
  models array, leaving Vertex per-provider matching untested).
- Allowlist the raw "@version" id in the guardrail, so entry
  normalization is exercised against version-stripped request models.
- Drive the unversioned model id (…/models/claude-sonnet-4-5:rawPredict)
  through the tunnel and require 200 — the customer-reported shape.
- Drive the token-count endpoint (…/models/count-tokens:rawPredict, real
  model in the body) via the new harness VertexCountTokens: an
  allowlisted body model must serve 200, a disallowed one must deny 403
  before the upstream.
This commit is contained in:
Maycon Santos
2026-07-22 17:56:07 +00:00
parent a69fe9ba8c
commit 1b7d23ee9f
3 changed files with 44 additions and 15 deletions
+9
View File
@@ -231,6 +231,15 @@ func (cl *Client) Vertex(ctx context.Context, endpoint, proxyIP, project, region
return cl.post(ctx, endpoint, proxyIP, path, body, withSessionID(nil, sessionID))
}
// VertexCountTokens issues the Anthropic-on-Vertex token-count POST: the URL
// carries the "count-tokens" pseudo-model and the real model travels in the
// body, so the proxy must resolve the body model for the allowlist and routing.
func (cl *Client) VertexCountTokens(ctx context.Context, endpoint, proxyIP, project, region, model string) (int, string, error) {
path := fmt.Sprintf("/v1/projects/%s/locations/%s/publishers/anthropic/models/count-tokens:rawPredict", project, region)
body := fmt.Sprintf(`{"model":%q,"messages":[{"role":"user","content":"hi"}]}`, model)
return cl.post(ctx, endpoint, proxyIP, path, body, nil)
}
// Bedrock issues a native AWS Bedrock InvokeModel POST over the tunnel. The
// model id is carried in the request path (/model/{id}/invoke), so the proxy
// routes by path; the body uses the bedrock anthropic_version rather than a