feat(guardrails): resolve BYOG by validator name only [AL-510] - #1021
Merged
Conversation
The Agents backend now enforces BYOG validator-name uniqueness per tenant and no longer accepts a connection id at validation nor persists one in the agent (UiPath/Agents#5959): the name alone resolves the configuration and the Integration Service connection is taken from it server-side, so an admin rebind is always honored. Counterpart of UiPath/uipath-python#1840. - UiPathByoGuardrailMiddleware: remove the connection_id kwarg and stop setting byo_connection_id on the guardrail; docstring drops the now-wrong "names are only unique per connection" advice. - Sample: reference the configuration by BYOG_VALIDATOR_NAME alone; README and docs replace the "Always pass the connection id" guidance with the per-tenant uniqueness rule, and discovery copies ByoValidatorName only. - Tests: middleware/decorator/parity suites assert the name-only wire contract; the parity scenario additionally pins that no connection id rides along (tolerant of uipath-platform releases before and after the field removal, floor stays >=0.2.14). - Bump to 0.15.3 (0.15.2 is published on PyPI). Verified live on alpha against the real BYOG harmful-content configuration with the validator name alone: benign topic evaluates on both flavors and returns a joke; harmful topic is logged by the agent-scope guardrail, then blocked by the LLM-scope guardrail with the vendor verdict "Harmful content detected: Violence (severity 4)" - proving server-side resolution by name. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR updates the BYOG (Bring Your Own Guardrail) surface in uipath-langchain to align with the backend change that resolves BYOG configurations by validator name only (unique per tenant), removing the now-dead connection_id from middleware, samples, docs, and tests.
Changes:
- Removed
connection_idfromUiPathByoGuardrailMiddlewareand stopped emittingbyoConnectionIdon the wire. - Updated docs and the BYOG sample to use validator name as the sole identifier.
- Updated tests (middleware, decorator path, and parity scenario) to assert the name-only contract and tolerate platform versions where the legacy field may be absent.
Reviewed changes
Copilot reviewed 10 out of 11 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
uv.lock |
Bumps locked package version to 0.15.3. |
pyproject.toml |
Bumps project version to 0.15.3. |
src/uipath_langchain/guardrails/middlewares/byo.py |
Removes connection_id kwarg and no longer sets byo_connection_id on the guardrail payload. |
docs/guardrails.md |
Updates BYOG documentation to remove connection_id and describe name-only identity. |
samples/joke-agent-bring-your-own-guardrail/README.md |
Updates sample instructions to use validator name only. |
samples/joke-agent-bring-your-own-guardrail/graph.py |
Removes BYOG_CONNECTION_ID and uses ByoValidator(name) / middleware name-only wiring. |
tests/guardrails/test_byo_validator.py |
Updates decorator-path tests to construct ByoValidator with name only and assert name-only contract. |
tests/guardrails/middlewares/test_byo.py |
Updates middleware tests to remove connection-id assertions and tolerate legacy field absence/None. |
tests/cli/test_guardrails_in_langgraph.py |
Updates BYOG parity scenario to assert name-only wire contract. |
tests/cli/mocks/parity_agent_middleware.py |
Updates parity middleware mock agent to remove connection_id usage. |
tests/cli/mocks/parity_agent_decorator.py |
Updates parity decorator mock agent to remove connection_id usage. |
Suppressed comments (1)
src/uipath_langchain/guardrails/middlewares/byo.py:90
- The docstring says to read BYOG parameter IDs from
uip agent guardrails list, but BYOG configs are listed viauip agent guardrails list --byo(as referenced a few lines above). Updating this keeps the CLI guidance consistent.
validator_parameters: Optional list of validator parameters. BYO
parameter schemas are connector-defined, so values are passed
through as-is; read the ids and allowed values from the
validator's ``Parameters`` in ``uip agent guardrails list``.
Comment on lines
+674
to
+676
| # BYOG identity is the name alone; no connection id may ride along | ||
| # (works both before and after uipath-platform drops the field). | ||
| assert not getattr(g, "byo_connection_id", None) |
|
valentinabojan
approved these changes
Aug 3, 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.



What changed?
The Agents backend now enforces BYOG validator-name uniqueness per tenant and no longer accepts a connection id at validation nor persists one in the agent (UiPath/Agents#5959, AL-510): the name alone resolves the configuration, and the Integration Service connection is taken from it server-side — an admin rebind is always honored. This PR removes the now-dead connection id from the langchain BYOG surface. Counterpart of UiPath/uipath-python#1840 (platform side); the two are independent — no release-ordering coupling.
UiPathByoGuardrailMiddleware— theconnection_idkwarg is removed and the middleware no longer setsbyo_connection_idon the guardrail. The docstring's "validator names are only unique per connection" advice — now factually wrong — is replaced with the per-tenant rule.joke-agent-bring-your-own-guardrail— references the configuration byBYOG_VALIDATOR_NAMEalone;BYOG_CONNECTION_IDis gone.docs/guardrails.md, both BYOG sections — examples and the middleware parameter table loseconnection_id; the "> Always pass the connection id" callout becomes "the name is the identity"; discovery copiesByoValidatorNameonly.getattr/.get) so it passes withuipath-platformreleases both before and after the field removal — the floor stays>=0.2.14.Version-skew safety: published
uipath-langchain0.14.18–0.15.2 still sendbyoConnectionId; the server ignores unknown fields, and the platform model keepsextra="allow", so every old/new combination keeps working. This PR only stops producing the field.How has this been tested?
tests/guardrails/middlewares/test_byo.py— name-only construction; wire dump assertsbyoConnectionIdisNone/absent.tests/guardrails/test_byo_validator.py—ByoValidatorname-only through@guardrail(tool / plain function / reuse).test_byog_agent_block, both flavors) — identical block contract + name-only wire contract.ruff check,ruff format --check,mypyclean;uv lock --checkclean; BYOG doc fences compile.AdminStudioTest) with the validator name alone against the real BYOG harmful-content configuration: benign topic → both flavors evaluate, joke returned; harmful topic → agent-scope guardrail logs, LLM-scope guardrail blocks with the vendor verdict "Harmful content detected: Violence (severity 4)" — proving the server resolves the configuration and its IS connection from the name only.Are there any breaking changes?
UiPathByoGuardrailMiddleware(connection_id=...)from 0.14.18–0.15.2 now raisesTypeError. The parameter shipped days ago (July 30) and the server already ignores the field it fed — deliberate hard removal in agreement with the backend change rather than a deprecation shim.🤖 Generated with Claude Code