Repository navigation
fix(go): start the doc comments after the optional loadAgentCard on their own line - #485
Merged
Merged
Conversation
…heir own line
The {{- if ExtendedAgentCard }} action trimmed the blank line before it, so
the generated main.go ran the next doc comment into the closing brace of the
function above. Without the extended agent card that was
`} // newRootCmd builds...`, with it `}// loadAgentCard reads...`, which
gofmt leaves as a trailing comment and godoc no longer attaches to the
function.
Trim after the action instead, so both layouts keep a blank line before
each doc comment.
inference-gateway-releaser Bot
added a commit
that referenced
this pull request
Oct 5, 2026
## [0.67.2](v0.67.1...v0.67.2) (2026-10-05) ### 🐛 Bug Fixes * **go:** start the doc comments after the optional loadAgentCard on their own line ([#485](#485)) ([e03f35f](e03f35f))
Contributor
|
🎉 This PR is included in version 0.67.2 🎉 The release is available on: Your semantic-release bot 📦🚀 |
edenreich
added a commit
to inference-gateway/cli
that referenced
this pull request
Oct 5, 2026
… a2a-auth example (#1542) ## Summary Lets `infer` authenticate to A2A agents that protect `/a2a`. An agent entry in `agents.yaml` can carry an `auth` block with a static bearer token or an OIDC client-credentials grant. Closes #1514 and closes #1512, which adds `examples/a2a-auth` on top of it. ```yaml agents: - name: research url: https://research.example.com auth: token_env: RESEARCH_AGENT_TOKEN - name: billing url: https://billing.example.com auth: oidc: client_id: infer client_secret_env: BILLING_AGENT_CLIENT_SECRET audience: billing-agent ``` ## How it works - **Secrets stay in the environment.** The `auth` block names environment variables and never holds a value. `LoadYAML` expands `${VAR}` over the whole file and every `infer agents add/update/remove` writes the result back, so a `token: ${VAR}` field would have ended up on disk in plain text. With variable names, the file, `infer agents list` and `infer agents show` cannot leak a secret. - **Every request is covered.** The credentials are added by a transport inside `a2ainfra.NewClient`, the one constructor behind the agent card fetch, `SendMessage`, `GetTask` polling, `CancelTask`, the liveness probe and `infer agents status`. ADK `Config.Headers` does not reach the card fetch, a transport does. - **Credentials stay on their agent.** `agent_url` comes from the model, so the transport only authenticates requests to the scheme, host and port of the configured agent. A redirect target or another port on the same host gets nothing. - **The agent card says where tokens come from.** As the A2A protocol defines, the agent declares how to authenticate in the `securitySchemes` of its card. The CLI reads the token endpoint from there: the discovery URL of an `openIdConnect` scheme, or the token URL of an `oauth2` client-credentials flow, with the scopes the card's `securityRequirements` list. `agents.yaml` only holds the client id, the secret variable and an optional audience. - **Optional `issuer_url`, pin and fallback.** The client secret goes to whatever endpoint the card names, and the card is fetched unauthenticated. With `auth.oidc.issuer_url` set, a card that points outside that issuer is refused before the secret is sent. The same field is the fallback for a card that declares no scheme at all, as agents generated before ADL CLI v0.67.0 do. - **OIDC tokens are reused.** One `clientcredentials` token source per grant lives for the process, fetches once and refreshes shortly before expiry. This adds `golang.org/x/oauth2` as a direct dependency. - **Auth failures are named.** A 401 or 403, a missing variable or a failed token request reaches the model as `Authentication failed for A2A agent "<name>": ...`, without the response body. Background polling ends the job on it instead of retrying forever. ## Example (#1512) `examples/a2a-auth/` runs one `mock-agent` 0.5.0 behind `A2A_AUTH_TOKEN` and one behind OIDC against Keycloak, with a tokenless mock model and no provider API key. The credentials are in the example's `.infer/agents.yaml`, with the secrets read from the environment. Each agent declares its scheme on its card, so the OIDC entry only holds the client and `infer` reads the token endpoint from the card. | Task | Result | | --- | --- | | `task token` | delegation to the token agent completes | | `task oidc` | delegation to the OIDC agent completes with a token from Keycloak | | `task wrong-token` | `Authentication failed for A2A agent "token-agent": the agent rejected the request with status 401` | | `task missing-token` | `Authentication failed for A2A agent "token-agent": environment variable TOKEN_AGENT_TOKEN is not set` | | `task wrong-secret` | `Authentication failed for A2A agent "oidc-agent": fetching the OIDC token: the token endpoint answered with status 401 unauthorized_client` | Keycloak and the OIDC agent share a network namespace, so the issuer is `http://localhost:8090/realms/a2a` for `infer` on the host and for the agent in its container. `docs/examples.md` lists the example and `docs/agents-configuration.md` links it. ## Testing - `infrastructure/auth_test.go`: the header on the card fetch, `SendTask`, `GetTask` and `CancelTask`, no header on another origin or after a cross-origin redirect, the OIDC token endpoint read from an `openIdConnect` and an `oauth2` card scheme, one token fetch across requests plus a refetch once the token expires, a card with no usable scheme or outside the pinned issuer refused before the secret is sent, the auth-failure message for 401 and 403, an unset variable. - `config/agents_test.go`: origin matching and a load and rewrite of `agents.yaml` that never contains the secret. - `submit_task_error_handling_test.go`: a rejected submission and a rejected poll both end with the named error. - Manual: all five example scenarios above and `task status` run against `mock-agent` 0.5.0 and Keycloak 26.3.2 with a local build, with no `issuer_url` configured. - `task precommit:run` passes. ## Not in this PR - `infer agents add/update` flags for `auth`. Edit `agents.yaml` directly for now. - Credentials for an agent that is only in `INFER_A2A_AGENTS` with no `agents.yaml` entry. - Authentication on artifact downloads. - ADK v0.33.0 has no typed HTTP error, so a 401 or 403 is recognised from the error text. A test pins the wording. A typed error in `inference-gateway/adk` would remove the text match and the roughly 6 second retry before a credential error surfaces on task requests. ## Affected repos - `inference-gateway/docs` needs the new `auth` block documented, tracked in inference-gateway/docs#985. - `inference-gateway/adl-cli`: generated Go agents did not declare their runtime auth mode in the card's `securitySchemes`. Fixed in inference-gateway/adl-cli#483 (closes inference-gateway/adl-cli#482), released in v0.67.0. - `inference-gateway/mock-agent`: its hand-maintained `main.go` was re-synced with the template in inference-gateway/mock-agent#172, released in 0.5.0, which the example pins. - inference-gateway/adl-cli#485 fixes an older template bug found during that sync, a doc comment glued onto the closing brace above it. It does not affect this PR. - `inference-gateway/adk` could expose a typed HTTP status error (optional follow-up, see above).
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.
Summary
The generated Go
main.goruns a doc comment into the closing brace of the function above it, so godoc no longer attaches the comment to its function:extendedAgentCard} // newRootCmd builds...}, blank line,// newRootCmd builds...extendedAgentCard: true}// loadAgentCard reads...(gofmt:} // loadAgentCard reads...)}, blank line,// loadAgentCard reads...The
{{- if .ADL.Spec.Capabilities.ExtendedAgentCard }}action trimmed the blank line before it. Trimming after the action instead ({{ if ... -}}) keeps the blank line in both layouts.The bug predates #483, which only moved it from
taskWorkerstoadvertiseAuthScheme. inference-gateway/mock-agent fixes the line by hand in its hand-maintainedmain.go(see inference-gateway/mock-agent#172).Testing
TestGoMainTemplate_DocCommentsStartOnTheirOwnLinerendersmain.gowith and without the extended agent card. It fails onmainand passes with the fix.mock-agentmanifest with a local build, with and withoutextendedAgentCard: true. Neithermain.gohas a} //line, andgofmt -lreports nothing.task lint(0 issues) andtask testpass.