Skip to content

feat(business-rules): add BusinessRulesService with run() - #1912

Open
ashishupadhyay88 wants to merge 29 commits into
mainfrom
feat/business-rules-evaluate
Open

ashishupadhyay88 wants to merge 29 commits into
mainfrom
feat/business-rules-evaluate

Conversation

@ashishupadhyay88

@ashishupadhyay88 ashishupadhyay88 commented Sep 28, 2026 •

Copy link
Copy Markdown

Summary

Jira: MST-15365

Adds sdk.business_rules, a client for the Business Rules service. It runs a business rule deployed to Orchestrator against one input.

This is PR 1 of 2. #1917 adds debug runs of undeployed rules, with the SDK picking the endpoint.

from uipath.platform import UiPath
from uipath.platform.business_rules import BusinessRuleCaller, TraceContext

result = UiPath().business_rules.run(
    "Loan Pricing",                  # rule name first, like processes.invoke(name, input_arguments)
    {"creditScore": 740},
    version="1.0.3",                 # optional; active version if omitted
    folder_path="Finance",           # or folder_key=..., or UIPATH_FOLDER_KEY / _PATH
    decision_names=["RiskGrade"],    # optional; every decision if omitted
    caller=BusinessRuleCaller(run_key="…"),                        # optional; defaults from the job
    trace_context=TraceContext(trace_id="…", parent_span_id="…"),  # optional; automatic if omitted
)
result.status                 # Success | PartialSuccess | AllFailed
result.decisions[0].outputs   # {"Grade": "B", "Rate": 3.5}

Errors from the service come back as EnrichedException, with the service's own code:

from uipath.platform.errors import EnrichedException

try:
    UiPath().business_rules.run("Missing Rule", {"creditScore": 740}, folder_path="Finance")
except EnrichedException as e:
    e.status_code             # 404
    e.error_info.error_code   # "RULE_NOT_FOUND"
    e.error_info.message      # "no such rule"

run_async() has the same signature, for callers already running on an event loop, such as LangGraph or FastAPI.

Flow

flowchart LR
    A["run(name, input)"] --> F{"Folder key?<br/>folder_key, folder_path<br/>or the environment"}
    F -- no --> X["ValueError<br/>nothing sent"]
    F -- yes --> E["POST /evaluate<br/>x-uipath-folderkey"]
    E -- "200 / 207" --> R["BusinessRuleRunResult"]
    E -- "4xx / 5xx" --> ER["EnrichedException"]
Loading

Before sending, the SDK applies any businessRule binding and checks the rule name and input. BaseService adds the token, the org/tenant URL, the trace header and retries. The Design section below has the details.

Design

The contract follows the service after UiPath/business-rules#124, #126 and #130, and the .NET client 2.0.0 (UiPath/business-rules#131). The call shape follows this SDK's resource conventions.

  • Name first, like every resource call. run(name, input, *, version=None, …) matches processes.invoke(name, input_arguments). The endpoint and the request builder (_evaluate_spec) are private.
  • One input on the wire. The request sends input and the response is read from result. The deprecated inputs batch is never sent, and a successful response without result raises ValueError.
  • The folder is named by key only.
    • folder_key is sent as is; folder_path is looked up through FolderService and sent as its key. Only x-uipath-folderkey goes on the wire, never the numeric folder id.
    • Required: one of the two, or the env (UIPATH_FOLDER_KEY, then UIPATH_FOLDER_PATH). A blank value counts as not given. Without a folder, run() raises before anything is sent.
    • Exclusive: folder_key and folder_path together are a ValueError, as in header_folder() across the SDK.
  • No explain. The service decides what it traces.
  • Caller audit. caller is sent for the execution audit. Each BusinessRuleCaller field defaults to the job's value: resource_key from UIPATH_PROCESS_UUID, run_key from UIPATH_JOB_KEY, folder_key from UIPATH_FOLDER_KEY. That last one is the caller's folder, not the rule's. Blank fields are left out, and so is caller when every field is blank.
  • Resource overrides. A solution's businessRule bindings can remap the rule name and folder per environment, through a private helper decorated with @resource_override(resource_type="businessRule"). When a binding remaps the rule, its folder replaces the caller's, including a folder_key.
  • Checks before sending:
    • rule names checked with the service's own allowlist (BusinessRuleNames.requireSafe): letters and numbers in any script, space and '._()[]{}+,&@!~=:;-, at most 256 characters, never ... The SDK accepts exactly the names the service accepts; the error names the characters it refused
    • input a mapping with at most 256 keys
  • Status. An input-level error means AllFailed. Otherwise the status comes from how many decisions failed. A 207 partial result is returned normally, with top_level_error when the service reports one.
  • Errors. Three kinds, each reaching the caller:
    • a call the SDK can refuse itself (no folder, unsafe name, input not a mapping) raises ValueError, and nothing is sent;
    • a 4xx or 5xx from the service, after the platform's retries, raises EnrichedException with status_code, the response body, and error_info.error_code / error_info.message read from the service's {"error": {"code", "message"}} envelope;
    • a decision or input that failed inside a 200 / 207 comes back in the result, as decision.error or errors, with the status set accordingly.
  • Tracing: the service records the run; the SDK opens no span.
    • run() / run_async() are deliberately not @traced. The service publishes the run's decision and rule spans to Trace View, so a client span would only wrap them and record the rule's input and outputs on the client. The .NET client opens no spans and never logs input data either.
    • x-uipath-traceparent-id names the caller's current span by default (trace id from UIPATH_TRACE_ID when set), so the service's spans nest directly under the caller's. Outside any trace no header is sent, and the service starts a trace of its own.
    • Callers can override it with trace_context=TraceContext(trace_id, parent_span_id), the same shape as .NET's, with the ids checked when it's created.
    • The explicit value travels in the headers handed to BaseService, as a small dict that ignores BaseService's later write of the ambient header. There are no request hooks and no change to BaseService, and it survives retries.
  • Inherited from BaseService:
    • bearer auth, including S2S
    • URL scoping
    • retries on timeouts and 408, 429, 502, 503, 504, 524 (the shared platform policy; nothing business-rules specific)
    • UIPATH_SERVICE_URL_BUSINESSRULES local override

For reviewers

  • Account and tenant headers. The SDK doesn't send x-uipath-internal-accountid / -tenantid; the gateway adds them, confirmed on alpha.
  • Shared code. Two small additions:
    • "businessRule" in GenericResourceOverwrite (common/_bindings.py), as feat: add memorySpace to resource overwrite types #1586 / fix: accept remoteA2aAgent in GenericResourceOverwrite #1581 did for their kinds.
    • a businessrules_ error extractor (errors/_extractors/_businessrules.py, registered in _router.py). The service nests its error as {"error": {"code", "message"}}; the generic extractor reads only the message from there, so EnrichedException.error_info.error_code was None. It now carries the service's code (RULE_NOT_FOUND, INVALID_REQUEST, …), like .NET's BusinessRulesException.Code. Other shapes, such as gateway errors, still go through the generic extractor.
  • Version bump. uipath-platform goes to 0.2.35 (main released 0.2.34). uv lock --check passes for both packages.
  • Latest commits, since the first review:
    • Contract update (ca881df3): the service's single-input contract. input / result, no explain, folder key only (organization_unit_id removed), caller added, RunMode / result.mode removed.
    • Service error codes (a8bb4596): the businessrules_ error extractor above.
    • Control characters (e29c9161): a rule name now refuses only Unicode Cc, the same set as .NET's char.IsControl. Before, str.isprintable() also refused non-breaking and zero-width spaces, so a name pasted from a document could pass .NET and fail here.
    • SDK conventions (ce7fe087): the request builder is a method (self._evaluate_spec), folder resolution is _resolve_folder_key / _resolve_folder_key_async as in context grounding, memory and AgentHub, helpers have clearer names, and a folder_path matching no folder now says so. No behaviour change.
    • Docs page (ce7fe087): docs/core/business_rules.md and a Business Rules entry under Services in mkdocs.yml, so sdk.business_rules appears in the published SDK docs. Checked with mkdocs build.
    • No client span (2c8bcb03): @traced removed from run() / run_async(), as described under Tracing.
    • Shared sync/async steps (fa84d396): run() and run_async() no longer repeat each other. _prepare_run() applies the binding, validates and picks the folder; only the folder lookup and the request() call differ. request() stays in the public methods, because BaseService names x-uipath-user-agent after the method that calls it; a test now pins run_async's user agent too.
    • Readable names (39b9ea67): locals and internal parameters renamed (run_target, request_spec, business_rule_name, request_body, wire_response, …). The public run(name, input) is unchanged.
    • Rule-name allowlist (4a2c2ec5), answering the review question: Orchestrator only bounds a name at creation ([Required], [MaxLength(100)], no character rules), while the service refuses anything outside its allowlist. The SDK's blocklist let names like Loan#1 through to a 400; it now uses the service's allowlist. Verified on alpha: 24 names sent straight to the service, 0 disagreements with the SDK.
    • Up to date with main (05748b93).
  • Copilot threads (binding folder over folder_key; non-dict input) were fixed in 162cf34a and are resolved.

Test plan

  • 80 tests in tests/services/test_business_rules_service.py, covering:
    • request body and headers (input, no inputs or explain)
    • folder key and path, the env fallbacks and their order, a required folder, blank values, a path that matches no folder
    • caller defaults from the env, explicit fields, blank fields, no caller
    • input checks, and the rule-name allowlist: 19 names the service refuses (#, ?, *, $, ", |, emoji, non-breaking / zero-width space, control characters, /, \, %, .., over 256) and 8 it accepts
    • each status, 207 responses, a response without result, error responses
    • explicit vs automatic trace (no leak, survives a retry); the header naming the caller's own span, sync and async; no header outside a trace; and, with a real tracer provider, no client span recorded
    • businessRule overrides (including over folder_key)
    • run_async
  • 3 tests in tests/errors/test_enriched_exception.py for the error extractor: the service's envelope, a code without a message, and other shapes falling back to the generic extractor.
  • The full uipath-platform suite passes: 1855 passed, 7 skipped (live credentials).
  • ruff check, ruff format --check and mypy src tests are clean.
  • Real alpha (bruleswe/DefaultTenant), checked on the wire:
    • folder_path="Shared" → looked up, only x-uipath-folderkey sent → Success
    • run_async with folder_key and decision_names → only that decision
    • an unknown rule → 404 EnrichedException; no folder → ValueError, nothing sent
    • a service 401 → error_info.error_code == "UNAUTHENTICATED"
    • rule names: 24 names sent straight to the service (skipping the SDK check); the service refused exactly the ones the SDK refuses

🤖 Generated with Claude Code

Adds sdk.business_rules, a client for the Business Rules service that
evaluates a DMN business rule deployed to Orchestrator against one input.

- evaluate / evaluate_async: single input in, decisions out; the
  service's batch contract stays internal, matching the .NET client
- folder scoping by folder_key or folder_path (resolved to a key, as the
  service accepts keys only), falling back to UIPATH_FOLDER_KEY/PATH
- client-side validation of rule name and input size, mirroring the
  service and the .NET client
- overall status (Success / PartialSuccess / AllFailed) derived from
  decision- and input-level errors; 207 partial results are returned,
  error envelopes raise EnrichedException
- auth, retry, tenant URL scoping and trace propagation are inherited
  from BaseService

Bumps uipath-platform to 0.2.33.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings September 28, 2026 04:18
@github-actions github-actions Bot added test:uipath-langchain Triggers tests in the uipath-langchain-python repository test:uipath-integrations labels Sep 28, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Fix the folder key/path presence check and add coverage for the documented UIPATH_FOLDER_PATH fallback.

Review effort: Lite
Findings: 1 Low severity

Open (1)
What changed in this PR

Adds Business Rules evaluation support to uipath-platform, including sync/async APIs, validation, folder resolution, and response handling.

Changes:

  • Added Business Rules models and service client.
  • Exposed UiPath.business_rules.
  • Added tests, documentation, and version updates.
File Reviewed changes
packages/​uipath/​uv.lock Dependency lock update
packages/​uipath-platform/​uv.lock Platform version lock update
packages/​uipath-platform/​tests/​services/​test_business_rules_service.py Service behavior tests
packages/​uipath-platform/​src/​uipath/​platform/​business_rules/​business_rules.py Evaluation models and statuses
packages/​uipath-platform/​src/​uipath/​platform/​business_rules/​_business_rules_service.py Evaluation service, validation, folder resolution, and response mapping
packages/​uipath-platform/​src/​uipath/​platform/​business_rules/​__init__.py Public API exports
packages/​uipath-platform/​src/​uipath/​platform/​_uipath.py business_rules client integration
packages/​uipath-platform/​pyproject.toml Package version bump
packages/​uipath-platform/​CLAUDE.md Service documentation

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@ashishupadhyay88
ashishupadhyay88 marked this pull request as draft September 28, 2026 05:18
Replaces the public evaluate()/evaluate_async() with run()/run_async(),
modelled on the .NET client's RunAsync: the caller passes a run context
(DeployedRunContext(rule_name, version)) and never picks an endpoint.
The result is BusinessRuleRunResult, stamped with the RunMode that ran.

The evaluate request builder stays private, so a debug run context can
be added later without changing the public entry point.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ashishupadhyay88 ashishupadhyay88 changed the title feat(business-rules): add BusinessRulesService with evaluate feat(business-rules): add BusinessRulesService with run() Sep 29, 2026
@ashishupadhyay88
ashishupadhyay88 marked this pull request as ready for review September 29, 2026 02:27
@ashishupadhyay88

Copy link
Copy Markdown
Author

Tested against alpha

This tests run() / run_async() with DeployedRunContext, on commit 3795b306.

Setup

  • Tenant: alpha.uipath.com/bruleswe/DefaultTenant
  • Login: uipath auth --alpha (user token)
  • Folder: Shared/Solution_ashish1 (key 4973409f-…)
  • Rule: Business Rules
  • Input: {"age": 14}
# Call Result
1 run(..., deployed=DeployedRunContext(rule_name="Business Rules"), folder_path=...) ✅ Success: {"category": "minor"}, service reported version 1.1.4
2 same + version="1.1.4" ✅ Success, same output
3 same + explain=True ✅ Success, same output (no 400: folder key sent)
4 version="1.1.4" + explain=True ✅ Success, same output
5 run_async(...), same as 1 ✅ Success, same output
6 unknown rule name ✅ EnrichedException 404 RULE_NOT_FOUND (service's own error body)

What this confirms

  • Gateway headers. The request went through the real gateway: POST https://alpha.uipath.com/bruleswe/DefaultTenant/businessrules_/v1/business-rules/evaluate. The service returns 400 if the account or tenant header is missing, so the gateway adds x-uipath-internal-accountid / -tenantid, and the SDK doesn't need to send them. This settles the open reviewer question.
  • Folder path. folder_path was turned into a key and sent as x-uipath-folderkey.
  • Result handling. The single input was sent as input-1, and the result was picked out and mapped to mode: Deployed / status: Success.

Checks in the locked uv environment (Python 3.11)

  • uv lock --check passes for uipath-platform and uipath, so the hand-edited lockfile versions are consistent.
  • 20 Business Rules tests pass.
  • The full suite passes: 1767 passed, 7 skipped.
  • ruff check, ruff format --check and mypy src tests are clean.

ashishupadhyay88 and others added 3 commits September 29, 2026 09:35
- Add sync and async tests for the UIPATH_FOLDER_PATH env fallback,
  which resolves the path to a key before sending x-uipath-folderkey,
  and a test that UIPATH_FOLDER_KEY wins over UIPATH_FOLDER_PATH
  without a lookup (Copilot review).
- Build DeployedRunContext outside pytest.raises so each block has a
  single call that can raise (Sonar python:S5778).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…sync()

Callers can now pass TraceContext(trace_id, parent_span_id), like the
.NET client's TraceContext, to file the run's spans under a trace of
their choosing. When it is omitted the header stays automatic: the
trace from UIPATH_TRACE_ID and the current span, as for every service.

- TraceContext validates at construction: 32-hex (or UUID) trace id,
  16-hex parent span id, neither all zeros; ids are normalised.
- BaseService always sets the ambient header, so a request hook on this
  service's own sync and async httpx clients replaces it with the
  explicit value just before sending. Shared code is unchanged.
- The explicit value lives in a ContextVar for the duration of the
  call, so it never leaks into the next call or across concurrent
  async runs, and it survives retries.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🔵 Needs a closer look

Address non-mapping input validation and malformed trace ID validation.

Review effort: Lite
Findings: None

Resolved since last review (1)

@NishankSiddharth NishankSiddharth left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

do we need to add get, list methods for business rules (listing BRs, getting details for BRs)?

Comment thread packages/uipath-platform/CLAUDE.md Outdated
Addresses review on #1912:

- run()/run_async() take the rule name as the first parameter, like
  processes.invoke(name, input_arguments):
  run("Loan Pricing", {"age": 14}, version=..., folder_path=...).
  DeployedRunContext is removed (never released); version is a keyword.
- @resource_override(resource_type="businessRule") on both, so a
  solution's bindings can remap the rule name and folder per
  environment. "businessRule" is the Studio resource kind.
- Add "businessRule" to GenericResourceOverwrite so such bindings parse,
  as done for memorySpace (#1586) and remoteA2aAgent (#1581).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ashishupadhyay88 added a commit that referenced this pull request Sep 29, 2026
Brings #1912's review fix (name-first run() with resource overrides)
into the debug PR and reshapes debug runs to match:

- run(name, input, *, debug=DebugRunContext(...)): the rule name is the
  first parameter for both modes, so bindings can remap it for debug
  runs too. DebugRunContext drops rule_name and keeps project_id,
  file_name, job_key and organization_unit_id.
- Without project_id, the run resolves the project from the job's
  lineage and needs job_key (or UIPATH_JOB_KEY) and organization_unit_id.
- version applies to deployed rules only and is rejected with debug.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ashishupadhyay88 and others added 2 commits September 29, 2026 18:50
Addresses review: describe the service in product terms in the package
guide and docstrings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ashishupadhyay88 added a commit that referenced this pull request Sep 29, 2026
Brings #1912's wording change into the debug PR and rewords the debug
docstrings and field descriptions the same way. Literal .dmn file names
in examples and tests are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fixes Sonar python:S7503 on the async request hook, which had to be
`async` for httpx but awaited nothing.

The explicit trace_context is now carried in the headers passed to
BaseService: a small dict that ignores BaseService's later write of the
ambient trace header when an explicit one is set. This removes both
httpx request hooks, the async hook function and the ContextVar. Each
call gets its own headers, so nothing leaks between calls or across
concurrent async runs, and retries reuse them (new test). Shared code
is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Three unresolved moderate findings remain in the Business Rules service implementation.

Review effort: Lite
Findings: 2 Medium severity

Open (2)

ashishupadhyay88 added a commit that referenced this pull request Oct 7, 2026
Brings in #1912's renames and applies them to the debug path too:
_run_spec(run_target, rule_input, ...), _debug_evaluate_spec(rule_name,
rule_input, ...) with request_body, _RunTarget(rule_name, ...,
debug_job_key), and debug_job_key in _resolve_debug_job_key. The debug
tests use the renamed _service_response / _single_decision_result helpers,
whose local is now response_body. No behaviour change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ashishupadhyay88 and others added 2 commits October 7, 2026 20:10
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Internal parameters, locals, _RunTarget's field, the name validator
(_validate_business_rule_name) and its constants now say
business_rule_name, matching the wire's businessRuleName and
BusinessRuleRunResult.business_rule_name. The public run(name, input)
and its error messages are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ashishupadhyay88 added a commit that referenced this pull request Oct 7, 2026
Brings in #1912's rule_name -> business_rule_name rename and applies it to the debug path too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The internal helpers take it as input, the same name as run()'s parameter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ashishupadhyay88 added a commit that referenced this pull request Oct 7, 2026
Brings in #1912's rule_input -> input rename and applies it to the debug path too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ashishupadhyay88 and others added 2 commits October 7, 2026 20:22
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Answers the review question of whether the name check matches what the
platform enforces:

- Orchestrator only bounds a name when the rule is created: [Required],
  [MaxLength(100)] (LengthRestrictions.BusinessRuleName), no character rules.
- The business-rules service, on both the deployed and the debug path, runs
  BusinessRuleNames.requireSafe: letters and numbers in any script (\p{L},
  \p{N}), space and '._()[]{}+,&@!~=:;-, at most 256, and never "..".

The SDK used a blocklist (/ \ .. % and control characters), looser than the
service, so names like "Loan#1", "Rule?" or one with a non-breaking space
passed it and then failed at the service with a 400. It now applies the
service's allowlist, so both accept exactly the same names and a bad one
fails before anything is sent. The error names the characters it refused.

Checked against alpha: 24 names sent straight to the service, skipping the
SDK check, and the SDK agreed with the service on every one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ashishupadhyay88 added a commit that referenced this pull request Oct 7, 2026
Brings in #1912's rule-name allowlist, which debug runs share.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…valuate

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ashishupadhyay88 added a commit that referenced this pull request Oct 7, 2026
Brings in latest main through #1912.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ashishupadhyay88
ashishupadhyay88 force-pushed the feat/business-rules-evaluate branch from f365f2f to f61841f Compare October 7, 2026 15:58
ashishupadhyay88 added a commit that referenced this pull request Oct 7, 2026
Name-first run() with debug context.

Brings #1912's review fix (name-first run() with resource overrides)
into the debug PR and reshapes debug runs to match:

- run(name, input, *, debug=DebugRunContext(...)): the rule name is the
  first parameter for both modes, so bindings can remap it for debug
  runs too. DebugRunContext drops rule_name and keeps project_id,
  file_name, job_key and organization_unit_id.
- Without project_id, the run resolves the project from the job's
  lineage and needs job_key (or UIPATH_JOB_KEY) and organization_unit_id.
- version applies to deployed rules only and is rejected with debug.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ashishupadhyay88 added a commit that referenced this pull request Oct 7, 2026
Say business rules, not DMN.

Brings #1912's wording change into the debug PR and rewords the debug
docstrings and field descriptions the same way. Literal .dmn file names
in examples and tests are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ashishupadhyay88 added a commit that referenced this pull request Oct 7, 2026
Organization_unit_id on run() for debug too.

Brings #1912's organization_unit_id into the debug PR and applies the
"require only what's needed, accept optional values" rule to debug runs:

- organization_unit_id moves from DebugRunContext to run(), next to
  folder_key / folder_path. Job-lineage mode requires it (and a job key,
  explicit or UIPATH_JOB_KEY); project mode needs no folder at all.
- Project mode no longer rejects a job key or folder id the caller
  passes: they're sent as given. UIPATH_JOB_KEY is still not added on its
  own, and businessRuleName is still never sent with projectId.
- version is sent with debug runs when given, instead of being rejected.
- explain=True needs a folder key in every mode.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ashishupadhyay88 added a commit that referenced this pull request Oct 7, 2026
#1912 now takes 0.2.34 (main released 0.2.33), so this PR moves to the
next version.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ashishupadhyay88 added a commit that referenced this pull request Oct 7, 2026
Brings in latest main through #1912.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ashishupadhyay88 added a commit that referenced this pull request Oct 7, 2026
#1912 now takes 0.2.35 (main released 0.2.34), so this PR moves to the
next version.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ashishupadhyay88 added a commit that referenced this pull request Oct 7, 2026
Brings in the business rules error extractor from #1912.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ashishupadhyay88 added a commit that referenced this pull request Oct 7, 2026
Brings in the rule-name control-character fix from #1912.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ashishupadhyay88 added a commit that referenced this pull request Oct 7, 2026
Brings in #1912's convention refactor and docs page. The debug path follows
the same shape: the debug request builder is a method,
self._debug_evaluate_spec(name, input, *, job_key, decision_names), and the
routing helper is _resolve_debug_job_key. No behaviour change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ashishupadhyay88 added a commit that referenced this pull request Oct 7, 2026
Brings in #1912's removal of the client span; debug runs open none either.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ashishupadhyay88 added a commit that referenced this pull request Oct 7, 2026
Brings in #1912's shared run()/run_async() steps. The debug path joins
them: _RunTarget also carries the debug job key (and no folder), decided in
_prepare_run() before the binding, and _run_spec() builds the request for
the endpoint the target names. run() and run_async() stay three steps each.
No behaviour change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ashishupadhyay88 added a commit that referenced this pull request Oct 7, 2026
Brings in #1912's renames and applies them to the debug path too:
_run_spec(run_target, rule_input, ...), _debug_evaluate_spec(rule_name,
rule_input, ...) with request_body, _RunTarget(rule_name, ...,
debug_job_key), and debug_job_key in _resolve_debug_job_key. The debug
tests use the renamed _service_response / _single_decision_result helpers,
whose local is now response_body. No behaviour change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ashishupadhyay88 added a commit that referenced this pull request Oct 7, 2026
Brings in #1912's rule_name -> business_rule_name rename and applies it to the debug path too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ashishupadhyay88 added a commit that referenced this pull request Oct 7, 2026
Brings in #1912's rule_input -> input rename and applies it to the debug path too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ashishupadhyay88 added a commit that referenced this pull request Oct 7, 2026
Brings in #1912's rule-name allowlist, which debug runs share.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ashishupadhyay88 added a commit that referenced this pull request Oct 7, 2026
Brings in latest main through #1912.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Lists the Business Rules models under Models, as Documents does, so the
service page links BusinessRuleRunResult and its other types.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sonarqubecloud

sonarqubecloud Bot commented Oct 7, 2026

Copy link
Copy Markdown

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

test:uipath-integrations test:uipath-langchain Triggers tests in the uipath-langchain-python repository

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants