Repository navigation
feat: let callers set the agent at the start of the User-Agent header - #425
Merged
Merged
Conversation
Usage reporting groups requests by the first agent in the User-Agent header, which was always nominal-streaming. Connectors built on this crate could not be told apart. Add ProductAgent and a user_agent option on NominalStreamOpts and NominalLogStreamOpts, plus NominalApiClients::try_from_url_with_agent for upload and ingest callers. A set agent comes first, followed by nominal-streaming/<crate version>. Without one, the header is unchanged. ProductAgent::new never fails. Names and versions the HTTP client would reject are changed to the closest accepted value, with a warning, because the client panics on invalid names and sends invalid versions as 0.0.0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add with_user_agent(name, version) and a user_agent property to PyNominalStreamOpts and PyNominalLogStreamOpts. Review fixes: - Ignore an agent whose name has no letters instead of sending "unknown". - Log the cleanup warning when clients are built, after logging is set up. - Keep -rcN and git-describe suffixes followed by other text. - Turn each run of rejected name characters into one hyphen. - Borrow the agent in try_from_url_with_agent. - Say which streams NominalStreamOpts::user_agent applies to. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
smithednominal
marked this pull request as ready for review
November 7, 2026 00:34
alxhill
approved these changes
Nov 10, 2026
…alid names and versions
…eparate _with_agent variants
Contributor
|
@smithednominal thx for the PR! updated it with a cleaner structure, will merge and release now |
Merged
This was referenced Nov 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Usage reporting groups requests by the first agent in the User-Agent header, which was always
nominal-streaming. Connectors built on this crate could not be told apart.Goal: allow every connector using code derived from this library to report a full user agent chain, e.g.
nominal-matlab/0.3.0 nominal-streaming/0.10.7 ....Changes
ProductAgent, a validated program name and version.ProductAgent::default()isnominal-streaming/<crate version>.user_agent: ProductAgentoption onNominalStreamOpts(withwith_user_agent) andNominalLogStreamOpts. With the default, the header is unchanged. With any other agent, the header starts with<name>/<version> nominal-streaming/<crate version>.ProductAgent::newreturnsResult<Self, ProductAgentError>. The HTTP client panics on a name it rejects and silently sends a version it rejects as0.0.0, so both are rejected up front:-rcNand agit describesuffix such as-5-gabc123. Suffixes like-dirtyor-beta.1are not accepted.PyNominalStreamOptsandPyNominalLogStreamOptsgainwith_user_agent(name, version), which raisesValueErrorfor an invalid name or version, and auser_agentproperty returningname/version.Breaking changes
These client constructors now take the agent as an argument:
NominalApiClients::try_from_url(base_url, &ProductAgent)async_conjure_streaming_client(uri, &ProductAgent)async_conjure_client(service, uri, &ProductAgent)NominalApiClients::from_uriis unchanged and uses the default agent. Pass&ProductAgent::default()to keep the previous behaviour elsewhere.Testing
cargo test --workspacecargo clippy --all-targets --all-featuresjust python dev && just python test && just python check