Skip to content

refactor(escalation): promote tools to subpackage with shared seam#877

Draft
cotovanu-cristian wants to merge 2 commits into
mainfrom
refactor/escalation-tools
Draft

refactor(escalation): promote tools to subpackage with shared seam#877
cotovanu-cristian wants to merge 2 commits into
mainfrom
refactor/escalation-tools

Conversation

@cotovanu-cristian
Copy link
Copy Markdown
Collaborator

Summary of Changes

Lifts the existing flat escalation files into a dedicated agent/tools/escalation/ subpackage and extracts the helpers that both the app-task escalation and the new QuickForm escalation duplicate. Quick-form escalation was a near-verbatim copy of the app-task factory — same recipient resolution, same task-title preamble, same result post-processing, same LangGraph wrapper, with only the platform task-creation call genuinely differing. This refactor makes the variant-specific code small and the shared seam explicit, paving the way for any additional variant (and slightly de-noises the existing app-task and IXP-VS tools too).

Stacked on #876. Merge that first; this PR rebases the flat-path QuickForm tool into the subpackage as part of the move.

  • New subpackage (src/uipath_langchain/agent/tools/escalation/)

    • app_task.py — renamed and trimmed from escalation_tool.py (the existing Action Center app-task escalation flow).
    • ixp_vs.py — renamed from ixp_escalation_tool.py (IXP visual studio extraction validation).
    • memory.py — renamed wholesale from escalation_memory.py (cache lookup / ingest).
    • quick_form.py — relocated from quick_form_escalation_tool.py, body trimmed to use the shared seam.
    • common.py — extracted shared primitives: EscalationAction, resolve_recipient_value, resolve_asset, _parse_task_data, _resolve_escalation_action, make_escalation_tool_output, EscalationInvocationCtx, build_invocation_ctx, finalize_escalation_result, make_escalation_wrapper.
    • __init__.py re-exports create_escalation_tool, create_ixp_escalation_tool, create_quick_form_escalation_tool, EscalationAction, resolve_asset, resolve_recipient_value.
    • CLAUDE.md (+222) documents the subpackage boundary, variant table, shared-seam contract, and patch-path conventions for tests so future contributors can find their way without re-reading every file.
  • Removed

    • src/uipath_langchain/agent/tools/escalation_tool.py (−501) — superseded by escalation/app_task.py.
    • src/uipath_langchain/agent/tools/quick_form_escalation_tool.py (−243) — superseded by escalation/quick_form.py.
  • Consumer updates

    • agent/tools/__init__.py re-exports the three factories from the new path.
    • agent/tools/tool_factory.py imports the three factories from .escalation.
    • agent/guardrails/actions/escalate_action.py switches its lazy import of resolve_recipient_value to the new path.
  • Test relocations (no behavioural changes) — existing escalation tests updated to import from the new subpackage and patch the new module paths.

Branch totals on top of feat/quick-form-escalation-tool: 17 files, +1,143 / −858.

Files Changed

  • src/uipath_langchain/agent/tools/escalation/quick_form.py+148 relocated, trimmed.
  • src/uipath_langchain/agent/tools/escalation/common.py+333 new shared seam.
  • src/uipath_langchain/agent/tools/escalation/app_task.py+284 relocated app-task tool.
  • src/uipath_langchain/agent/tools/escalation/CLAUDE.md+222 subpackage docs.
  • src/uipath_langchain/agent/tools/escalation/__init__.py+33 re-exports.
  • src/uipath_langchain/agent/tools/escalation/ixp_vs.py — renamed from ixp_escalation_tool.py, +11 / −8 adjustments.
  • src/uipath_langchain/agent/tools/escalation/memory.py — pure rename of escalation_memory.py.
  • src/uipath_langchain/agent/tools/escalation_tool.py−501 removed.
  • src/uipath_langchain/agent/tools/quick_form_escalation_tool.py−243 removed.
  • src/uipath_langchain/agent/tools/__init__.py — +6 / −2: import path update.
  • src/uipath_langchain/agent/tools/tool_factory.py — +5 / −3: import path update.
  • src/uipath_langchain/agent/guardrails/actions/escalate_action.py — +2 / −2: import path update.
  • tests/agent/tools/test_escalation_tool.py — +46 / −44: patch-path updates.
  • tests/agent/tools/test_escalation_memory.py — +32 / −32: patch-path updates.
  • tests/agent/tools/test_ixp_escalation_tool.py — +8 / −8: patch-path updates.
  • tests/agent/guardrails/actions/test_escalate_action.py — +12 / −12: import-path updates.
  • tests/cli/test_agent_with_guardrails.py — +2 / −2: import-path updates.

Test plan

  • python -c "from uipath_langchain.agent.tools import create_quick_form_escalation_tool, create_escalation_tool, create_ixp_escalation_tool" — re-exports import cleanly.
  • python -c "from uipath_langchain.agent.tools.escalation import resolve_recipient_value, resolve_asset, EscalationAction" — shared seam exports verified.
  • git diff feat/quick-form-escalation-tool..HEAD --stat — 17 files, +1143 / −858 confirmed.
  • Not verified: full pytest tests/ run; test files were import-path-updated only, no semantic changes.
  • Not verified: end-to-end run.

Known limitations

Are there any breaking changes?

  • None for external consumers — uipath_langchain.agent.tools re-exports create_escalation_tool, create_ixp_escalation_tool, and create_quick_form_escalation_tool from the same package path as before.
  • Internal-only: direct imports from uipath_langchain.agent.tools.escalation_tool, …escalation_memory, …ixp_escalation_tool, and …quick_form_escalation_tool will fail. No downstream callers in this repo; out-of-tree consumers must move to uipath_langchain.agent.tools.escalation.

🤖 Generated with Claude Code

cotovanu-cristian and others added 2 commits May 27, 2026 19:50
Introduces create_quick_form_escalation_tool, a langchain StructuredTool
that materialises AgentQuickFormEscalationResourceConfig
(escalationType=2) into a HITL task whose form is rendered from the
channel's HitlSchema. The tool reads schema_id + schema from
AgentEscalationChannel, calls
TasksService.create_quickform_async (uipath-platform), suspends inside
durable_interrupt on WaitEscalation, and on resume maps the channel's
outcome_mapping to CONTINUE / END — matching the existing app-task
escalation contract.

Helpers (resolve_recipient_value, _parse_task_data,
_resolve_escalation_action, EscalationAction) are reused from
escalation_tool.py rather than extracting a shared seam; keeping QF and
the existing escalation tool side-by-side mirrors how ixp_escalation_tool
and escalation_memory live today.

Wired into agent/tools/__init__.py (re-export) and tool_factory.py
(dispatch on AgentQuickFormEscalationResourceConfig).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Quick-form escalation was a near-verbatim copy of the app-task
escalation factory — same recipient resolution, same task-title
preamble, same result post-processing, same LangGraph wrapper, with
only the platform task-creation call genuinely differing.  Reorganise
into agent/tools/escalation/ (mirroring agent/tools/mcp/) and lift the
shared scaffolding into a common.py seam so the per-variant factories
own only what is actually variant-specific.

* common.py — EscalationAction, recipient/asset resolution, output
  schema builder, invocation preamble, post-interrupt finaliser, and
  the LangGraph tool wrapper factory.
* app_task.py, quick_form.py, ixp_vs.py — assemble those primitives;
  escalation-memory persistence stays inside app_task.py (its only
  caller).
* memory.py — escalation_memory.py moved under the subpackage.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
0.0% Coverage on New Code (required ≥ 90%)

See analysis details on SonarQube Cloud

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.

1 participant