Skip to content

feat(skills): add skills support to advanced agents with sandboxed cli tool - #989

Open
mariadhakalUipath wants to merge 1 commit into
mainfrom
feat/uipath-skills-for-advanced
Open

feat(skills): add skills support to advanced agents with sandboxed cli tool#989
mariadhakalUipath wants to merge 1 commit into
mainfrom
feat/uipath-skills-for-advanced

Conversation

@mariadhakalUipath

@mariadhakalUipath mariadhakalUipath commented Jul 14, 2026

Copy link
Copy Markdown

Title: Uipath Skills with Cli tool for advanced agents.

Summary

Adds skills feature for advanced agents. Agent can act on it — run uip commands, review what it ran, and verify what it scaffolded.

⚠️ Note for coded agents

The feature flag exists for low-code graph builder reached only via agent.json
AgentsRuntimeFactory_build_advanced_agent.

Coded agents resolve to a different runtime factory (langgraph.json) and never evaluate that flag. A coded author who writes:
from uipath_langchain.agent.tools.internal_tools import create_uipath_cli_tool

gets full uip execution with no kill switch at this layer.

If you are adding this tool to a coded agent and need destructive commands restricted, wrap it with your own validation before handing it to the agent. Do not rely on a tool-level @guardrail, which does not fire for this tool.
For example, delegate to the tool from your own StructuredTool that rejects the commands you care
about, and apply platform guardrails at the agent/graph level rather than the tool level.

Copilot AI review requested due to automatic review settings July 14, 2026 21:20

Copilot AI 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.

Pull request overview

Adds initial “skills” plumbing to advanced agents and introduces a sandbox-oriented internal tool for running uip commands inside an agent workspace.

Changes:

  • Introduces a new create_uipath_cli_tool() (uipath_cli) StructuredTool that runs one uip command per invocation with command validation.
  • Adds unit tests covering command parsing, validation, subprocess result mapping, and timeout behavior for the new tool.
  • Extends advanced-agent builders to accept and forward a skills parameter into the underlying deepagents agent construction.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
tests/agent/tools/internal_tools/test_uipath_cli_tool.py Adds test coverage for the new sandboxed CLI tool.
src/uipath_langchain/agent/tools/internal_tools/uipath_cli_tool.py Implements the sandboxed uipath_cli tool and its input/output schemas.
src/uipath_langchain/agent/tools/internal_tools/__init__.py Exports create_uipath_cli_tool from the internal tools package.
src/uipath_langchain/agent/advanced/agent.py Adds skills parameter propagation to deepagents agent creation/wrappers.

Comment thread src/uipath_langchain/agent/tools/internal_tools/uipath_cli_tool.py
Comment thread src/uipath_langchain/agent/tools/internal_tools/uipath_cli_tool.py
Comment thread src/uipath_langchain/agent/tools/internal_tools/uipath_cli_tool.py Outdated
Comment thread tests/agent/tools/internal_tools/test_uipath_cli_tool.py
@mariadhakalUipath
mariadhakalUipath force-pushed the feat/uipath-skills-for-advanced branch from d79b0c1 to 5b5dea8 Compare July 14, 2026 21:27
@mariadhakalUipath mariadhakalUipath changed the title feat: add skills support to advanced agents with sandboxed workspace tools feat: add skills support to advanced agents with sandboxed cli tool Jul 14, 2026
@mariadhakalUipath
mariadhakalUipath force-pushed the feat/uipath-skills-for-advanced branch from 5b5dea8 to 36f2b2c Compare July 14, 2026 21:32
@mariadhakalUipath mariadhakalUipath changed the title feat: add skills support to advanced agents with sandboxed cli tool feat(skills): add skills support to advanced agents with sandboxed cli tool Jul 14, 2026
@mariadhakalUipath
mariadhakalUipath force-pushed the feat/uipath-skills-for-advanced branch from 36f2b2c to 2f7b1c1 Compare July 14, 2026 21:38

Copilot AI 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.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

Comments suppressed due to low confidence (1)

src/uipath_langchain/agent/advanced/agent.py:45

  • The create_advanced_agent docstring documents memory but not the newly added skills parameter, which is part of the public API. Update the docstring to describe what skills does and how an empty value is handled.
    """Create a deepagents agent with planning, filesystem, and sub-agent tools.

    ``memory`` is a list of file paths loaded via deepagents' ``MemoryMiddleware``:
    each is read from ``backend`` and injected into the system prompt every turn,
    and the model maintains them with ``edit_file``. Empty disables the middleware.
    """

Comment thread src/uipath_langchain/agent/tools/internal_tools/uipath_cli_tool.py
Comment thread src/uipath_langchain/agent/tools/internal_tools/uipath_cli_tool.py Outdated
Comment thread tests/agent/tools/internal_tools/test_uipath_cli_tool.py
Comment thread src/uipath_langchain/agent/advanced/agent.py

Copilot AI 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.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Comment thread src/uipath_langchain/agent/tools/internal_tools/uipath_cli_tool.py Outdated
Comment thread src/uipath_langchain/agent/tools/internal_tools/uipath_cli_tool.py Outdated
Comment thread src/uipath_langchain/agent/advanced/agent.py Outdated

Copilot AI 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.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Comment thread src/uipath_langchain/agent/tools/internal_tools/uipath_cli_tool.py Outdated

Copilot AI 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.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

src/uipath_langchain/agent/advanced/agent.py:42

  • create_advanced_agent now accepts skills, but the docstring only documents memory. Since empty skills collapses to None (disabling skills support), documenting this behavior would help callers understand how to enable/disable the feature.
    skills: Sequence[str] = (),
) -> CompiledStateGraph[Any, Any, Any, Any]:
    """Create a deepagents agent with planning, filesystem, and sub-agent tools.

    ``memory`` is a list of file paths loaded via deepagents' ``MemoryMiddleware``:

Comment thread src/uipath_langchain/agent/tools/internal_tools/uipath_cli_tool.py
Comment thread src/uipath_langchain/agent/tools/internal_tools/uipath_cli_tool.py Outdated
@mariadhakalUipath
mariadhakalUipath force-pushed the feat/uipath-skills-for-advanced branch 2 times, most recently from 9bbae6c to 850386e Compare July 15, 2026 18:11

Copilot AI 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.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Comment thread src/uipath_langchain/agent/tools/internal_tools/uipath_cli_tool.py
Comment thread src/uipath_langchain/agent/tools/internal_tools/uipath_cli_tool.py Outdated
@mariadhakalUipath
mariadhakalUipath force-pushed the feat/uipath-skills-for-advanced branch 5 times, most recently from 7d9ca46 to b02dd2b Compare August 6, 2026 20:29

Copilot AI 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.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.

Suppressed comments (3)

src/uipath_langchain/agent/tools/internal_tools/uipath_cli_tool.py:37

  • The tool description says “A negative exit_code means the command was refused”. That’s inaccurate because real subprocess exit codes can be negative on Unix when terminated by a signal. The contract in UiPathCliOutput/test cases is specifically “exit_code == -1000 indicates refusal”, so the description should match to avoid confusing the agent.
    "Run a single UiPath `uip` command in the agent workspace; returns "
    "exit_code/stdout/stderr. Only the uip/uipath binaries, one command per call; "
    "shell chaining is refused. A negative exit_code means the command was refused "
    "before it ran and stderr explains why. Use `subdir` to target a scaffolded "
    "project folder."

src/uipath_langchain/agent/tools/internal_tools/uipath_cli_tool.py:167

  • On timeout, proc.kill() can raise ProcessLookupError if the process exits between the timeout firing and the kill call. That would crash the tool instead of returning the recoverable _REJECTED_EXIT_CODE payload.
    except asyncio.TimeoutError:
        proc.kill()
        await proc.wait()
        return _rejected(
            echoed, f"Command timed out after {_COMMAND_TIMEOUT_SECONDS}s."

src/uipath_langchain/agent/advanced/agent.py:110

  • This PR introduces a sandboxed uipath_cli tool, but create_advanced_agent only forwards the skills list into deepagents and never registers the new tool. The new tool module’s docstring says it is “injected programmatically by the agent graph builder when UiPath skills are active”, but there is currently no call site for create_uipath_cli_tool in src/ (verified by repo search). If skills are expected to prescribe uip commands, the agent needs the tool added to its tool list when skills are enabled (and a FilesystemBackend workspace exists).
        memory=list(memory) or None,
        middleware=list(middleware),
        skills=list(skills) if skills else None,

@mariadhakalUipath
mariadhakalUipath deleted the feat/uipath-skills-for-advanced branch August 6, 2026 20:40
@mariadhakalUipath
mariadhakalUipath restored the feat/uipath-skills-for-advanced branch August 6, 2026 20:41
@mariadhakalUipath
mariadhakalUipath force-pushed the feat/uipath-skills-for-advanced branch from b02dd2b to 4083836 Compare August 10, 2026 16:14
Comment thread src/uipath_langchain/agent/tools/internal_tools/uipath_cli_tool.py Outdated
response_format: ResponseFormat[Any] | None = None,
memory: Sequence[str] = (),
middleware: Sequence[AgentMiddleware[Any, Any]] = (),
skills: Sequence[str] | None = None,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

this is a logic-changing public change, but the pr does not bump the package version. main is already at 0.16.2 while this branch still has 0.16.1. rebase and bump to the next version in pyproject.toml before merge.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Okay will do this before I merge.

Comment thread src/uipath_langchain/agent/tools/internal_tools/uipath_cli_tool.py
Comment thread src/uipath_langchain/agent/tools/internal_tools/uipath_cli_tool.py Outdated
Comment thread src/uipath_langchain/agent/advanced/agent.py
@mariadhakalUipath
mariadhakalUipath force-pushed the feat/uipath-skills-for-advanced branch from 4083836 to b8d13be Compare August 13, 2026 18:20
@mariadhakalUipath
mariadhakalUipath force-pushed the feat/uipath-skills-for-advanced branch 2 times, most recently from 817b196 to e88d052 Compare August 24, 2026 18:24
stdout, stderr = await asyncio.wait_for(
proc.communicate(), timeout=_COMMAND_TIMEOUT_SECONDS
)
except asyncio.TimeoutError:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Handle task cancellation here as well. Cancelling proc.communicate() only cancels the coroutine that drains the pipes and waits for completion; it does not terminate the separate OS process. I reproduced this with a real child process: after cancelling _run_uip_subprocess, proc.returncode remained None and the child kept running.

Add this cancellation branch alongside the timeout branch:

    except asyncio.CancelledError:
        try:
            proc.kill()
        except ProcessLookupError:
            pass
        await asyncio.shield(proc.wait())
        raise

This kills and reaps the child, while the bare raise preserves the original cancellation. Add a regression test that cancels the task and asserts both kill() and wait() are called. This covers graceful asyncio cancellation only; a hard kill of the Python parent bypasses all cleanup and must be handled by the process supervisor.

@radu-mocanu radu-mocanu Aug 25, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

FYI this protection is for graceful stopping only. serverless force kill will most likely not stop the underlying CLI command

@mariadhakalUipath
mariadhakalUipath force-pushed the feat/uipath-skills-for-advanced branch 2 times, most recently from e8fbfe1 to 73f918e Compare August 25, 2026 18:33
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@mariadhakalUipath
mariadhakalUipath force-pushed the feat/uipath-skills-for-advanced branch from 73f918e to 6ddc4c3 Compare August 25, 2026 18:49
@sonarqubecloud

Copy link
Copy Markdown

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.

4 participants