Skip to content

docs: fix 1.6 cost catalog, unpriced cost field, and OTLP attribute names - #1163

Merged
artberger merged 4 commits into
mainfrom
adb-16-followups
Oct 1, 2026
Merged

artberger merged 4 commits into
mainfrom
adb-16-followups

Conversation

@artberger

@artberger artberger commented Oct 1, 2026 •

Copy link
Copy Markdown
Collaborator

Follow-ups found while reviewing and testing the 1.6 pr-tracker PRs. Each fix was tested live or checked in code, as listed under each item.

Built-in model catalog (main)

Since agentgateway/agentgateway#3191 (c3f27907), the proxy always loads a built-in catalog (catalog/model-catalog.json). With no catalog configured, gpt-4o-mini was priced on both standalone and Kubernetes (nightly), and the built-in catalog tags 234 aws.bedrock models as runtime or mantle.

  • Bedrock pages (both modes): replaced "Without a catalog, no model carries either tag" with a sentence that says the built-in catalog already tags Bedrock models.
  • K8s main costs.md: describes the built-in catalog. It no longer reuses cost-catalog-default.md, which is still correct for 1.4.x and 1.5.x and is also used by the archived 1.4.x dir, where a version gate would render empty.
  • Dashboard pages (main, both modes): a catalog is no longer required for costs.
  • NoCatalog status (main): a running proxy cannot report it, because the built-in catalog always loads.

How catalog sources combine (new section, main)

This behavior is new in 1.6 (from_catalogs in llm/catalog/mod.rs). I tested it in standalone:

  • A catalog with metadata.generatedAt is a candidate base. That includes the built-in catalog, every agctl catalog import output, and the UI Refresh base costs button. Only the newest base is used.
  • An imported catalog older than the built-in one is ignored, and the proxy logs no warning.
  • Catalogs without metadata are overlays, applied in order.

The old "merged in order, later wins" sentence is kept for 1.5 only.

Important

Please have the dev team confirm that silently ignoring an older imported catalog is intended. If it isn't, the caution in the new section should change to point to an issue.

Unpriced requests omit the cost field (1.5 and 1.6)

When a request can't be priced, the access log leaves out agw.ai.usage.cost.total. It is never 0. I tested this on v1.5.0 and on main (missing model and tags-only entry), and log.rs is the same in both versions. Fixed on K8s latest and main costs.md, and on the shared standalone cost asset.

OTLP access-log attribute names (main)

Since agentgateway/agentgateway#3182, OTLP records use the OpenTelemetry semantic-convention names (server.address, url.path, http.response.status_code, and so on). Stdout keeps http.host, http.path and http.status. The OTLP remove list matches the new names, so remove: [http.host] now removes nothing and gives no error. I tested this on standalone and K8s (nightly).

  • Shared K8s export.md: the filter example output, the attributes YAML (remove: server.address) and its example output now have a version-gated pair. Latest keeps the 1.5 content.
  • Standalone main export.md: the example removes server.address, with a short explanation.

Trace span attribute names (main)

Request spans on main use the same semantic-convention names. Tested in docker standalone (dd7a4b32 vs v1.5.0) and on K8s nightly (d078aa12):

  • Main request spans: client.address (IP only), http.request.method, server.address, url.path (without the query), network.protocol.version, http.response.status_code, and new url.scheme, server.port, url.query.
  • v1.5.0 request spans: src.addr, http.method, http.host, http.path (with the query), http.version, http.status, and also url.scheme and network.protocol.version, which the reference didn't list.
  • remove: [src.addr, http.version] on main: removes nothing and gives no error, in both modes. remove: [client.address, network.protocol.version] works.
  • Outbound child spans (policy and backend calls) keep the old http.* names on both versions (httpproxy.rs), so the policy child span table is unchanged.

Changes:

  • Shared traces/attribute-reference.md: gated pair of the core HTTP table. Latest adds the two missing rows. Main adds a short note on which names apply where.
  • Shared K8s traces/setup.md: the TraceQL queries now use span.url.path and span.http.response.status_code on main, and the remove example is a gated pair.
  • Standalone main traces/setup.md: the remove example uses the new names.

AgentgatewayModel default and virtual model error code (K8s main)

  • On by default: Enable AgentgatewayModel by default agentgateway#3492 (0dd07740) changed the agentgatewayModels.enabled default to true. On the agw-review nightly install, which has no override, the controller env AGW_ENABLE_AGENTGATEWAY_MODELS is true.
    • models/about.md: the warning and the known limitation no longer say "disabled by default" or "experimental". They say the API is v1alpha1, and the warning explains how to turn it off.
    • models/serve.md: "Enable the AgentgatewayModel feature" became "Verify the AgentgatewayModel feature". The section runs the env check and explains how to turn the API back on, instead of running a helm upgrade. The troubleshooting step that pointed to a nonexistent Helm step in Before you begin now links to that section. The generated serve-model doc test no longer runs the Helm upgrade.
    • The shared agentgatewaymodel-enable.md snippet is unchanged, because it is still right for latest (1.5).
  • Error code: a virtual model whose target is attached to a different router fails with 404 virtual_model_target_not_found, not virtual_model_not_resolved. Tested on the nightly with a Gateway-parent virtual model and an HTTPRoute-parent target. The virtual model still reports Accepted: True, and the page now says so. virtual_model_not_resolved fires only when a weighted pick fails (model_router.rs).

Verification

  • A full hugo build is clean.
  • I checked the rendered text on K8s 1.4.x, latest and main, and on standalone latest and main, including the trace attribute tables and setup pages. Latest still shows the 1.5 text, main shows the new text, and no shortcodes leak.
  • The generated K8s main doc test for export.md now includes only the server.address block.

Not in this PR

  • llm/tracing.md still shows 1.5 names, but it is only consumed by parked .txt files and does not build.
  • The outbound backend child span (agentgateway.outbound.kind: Primary) is not documented on the attribute reference page.
  • K8s virtual.md "Without a health policy…" is fixed by [Automated] Draft docs (agentgateway): llm: automatically enable eviction for failover #1122 (now merged).
  • Four shared "Model-centric alternative" callouts (alias.md, failover.md, content-routing.md, load-balancing.md) still call AgentgatewayModel "experimental". I left them, because they say nothing about the default.

🤖 Generated with Claude Code

artberger and others added 3 commits October 1, 2026 10:14
…ames

- Describe the built-in model catalog (c3f27907) and how catalog sources
  combine: metadata catalogs compete as the base, newest wins, others are
  ignored; catalogs without metadata are overlays.
- agw.ai.usage.cost.total is omitted, not 0, for unpriced requests (1.5 and 1.6).
- Bedrock pages: the built-in catalog already tags Bedrock models.
- OTLP access logs on main use semconv names; remove: [http.host] no longer
  matches, so the examples use server.address. Latest keeps the 1.5 names.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Art Berger <art.berger@solo.io>
Request spans on main use the OTel semconv HTTP names (#3182), so the old
remove list (src.addr, http.version) and the TraceQL queries on
span.http.path/span.http.status match nothing. Gate the attribute table,
remove examples, and TraceQL rows; latest keeps the 1.5 names and gains the
url.scheme and network.protocol.version rows it already emits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Art Berger <art.berger@solo.io>
#3492 enabled AgentgatewayModel by default on main, so models/about.md no
longer says it is disabled, and serve.md verifies the feature instead of
running a helm upgrade. A virtual model whose target is on another router
fails with 404 virtual_model_target_not_found (tested on the nightly), not
virtual_model_not_resolved.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Art Berger <art.berger@solo.io>
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Deploying agentproxy with  Cloudflare Pages  Cloudflare Pages

Latest commit: 06a3d8a
Status:⚡️  Build in progress...

View logs

@artberger
artberger marked this pull request as ready for review October 1, 2026 14:22

> [!WARNING]
> The `{{< reuse "agw-docs/snippets/agentgatewaymodel.md" >}}` API is experimental and disabled by default. The `v1alpha1` API is subject to change in a future release. To enable it, set the `agentgatewayModels.enabled=true` Helm value on the {{< reuse "agw-docs/snippets/agentgateway.md" >}} control plane.
> The `{{< reuse "agw-docs/snippets/agentgatewaymodel.md" >}}` API is enabled by default. It is a `v1alpha1` API, so it is subject to change in a future release. To turn it off, set the `agentgatewayModels.enabled=false` Helm value on the {{< reuse "agw-docs/snippets/agentgateway.md" >}} control plane.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "experimental" wording now disagrees between pages. about.md drops "experimental", but the callouts in alias.md, failover.md, content-routing.md and load-balancing.md still use it.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Fixed in 06a3d8a: the "experimental" word in the four Model-centric alternative callouts (alias.md, failover.md, content-routing.md, load-balancing.md) is now version-gated. Main drops it to match about.md, and latest (1.5) keeps it, because the API is still experimental and off by default there. Checked the built pages for latest and main.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Art Berger <art.berger@solo.io>
@artberger
artberger merged commit 3a07dcc into main Oct 1, 2026
23 of 24 checks passed
@artberger
artberger deleted the adb-16-followups branch October 1, 2026 20:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants