Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "uipath-langchain"
version = "0.9.11"
version = "0.9.12"
description = "Python SDK that enables developers to build and deploy LangGraph agents to the UiPath Cloud Platform"
readme = { file = "README.md", content-type = "text/markdown" }
requires-python = ">=3.11"
Expand Down
28 changes: 28 additions & 0 deletions src/uipath_langchain/agent/tools/static_args.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from langchain_core.messages import ToolCall
from langchain_core.tools import BaseTool, StructuredTool
from pydantic import BaseModel
from typing_extensions import deprecated
from uipath.agent.models.agent import (
AgentToolArgumentArgumentProperties,
AgentToolArgumentProperties,
Expand Down Expand Up @@ -132,6 +133,33 @@ def _apply_static_arguments_to_schema(
return modified_tool


@deprecated(
"Use StaticArgsHandler to modify LLM tool calls directly."
"Applying static args in the tool node conflicts with guardrails"
)
def resolve_static_args(
tool: ArgumentPropertiesMixin,
agent_input: dict[str, Any],
) -> dict[str, Any]:
"""Resolves static arguments for a given resource with a given input.

Args:
tool: The tool with argument_properties.
agent_input: The input arguments passed to the agent.

Returns:
A dictionary of expanded arguments to be used in the tool call.
"""

static_arguments = _resolve_argument_properties(
tool.argument_properties, agent_input
)
return {
json_path: static_argument.value
for json_path, static_argument in static_arguments.items()
}


def apply_static_args(
static_args: dict[str, Any],
kwargs: dict[str, Any],
Expand Down
118 changes: 118 additions & 0 deletions tests/agent/tools/test_static_args.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@
)

from uipath_langchain.agent.tools.static_args import (
ArgumentPropertiesMixin,
StaticArgsHandler,
apply_static_args,
resolve_static_args,
)
from uipath_langchain.agent.tools.structured_tool_with_argument_properties import (
StructuredToolWithArgumentProperties,
Expand Down Expand Up @@ -461,3 +463,119 @@ def test_apply_static_args_replace_entire_array(self):
"enabled": True,
}
assert result == expected


class TestResolveStaticArgs:
"""Test cases for resolve_static_args function."""

def test_resolve_static_args_with_argument_properties(self):
"""Test resolve_static_args with an object that has argument_properties."""

class ResourceWithProps(ArgumentPropertiesMixin):
argument_properties = {
"$['host']": AgentToolStaticArgumentProperties(
is_sensitive=False, value="api.example.com"
),
}

result = resolve_static_args(ResourceWithProps(), {"unused": "input"})

assert result == {"$['host']": "api.example.com"}

def test_resolve_static_args_with_static_values_of_different_types(self):
"""Test resolve_static_args resolves string, integer, and object static values."""

class ResourceWithProps(ArgumentPropertiesMixin):
argument_properties = {
"$['connection_id']": AgentToolStaticArgumentProperties(
is_sensitive=False, value="12345"
),
"$['timeout']": AgentToolStaticArgumentProperties(
is_sensitive=False, value=30
),
"$['config']": AgentToolStaticArgumentProperties(
is_sensitive=False, value={"enabled": True, "retries": 3}
),
}

result = resolve_static_args(ResourceWithProps(), {"unused": "input"})

assert result == {
"$['connection_id']": "12345",
"$['timeout']": 30,
"$['config']": {"enabled": True, "retries": 3},
}

def test_resolve_static_args_with_argument_properties_extracts_from_agent_input(
self,
):
"""Test resolve_static_args resolves AgentToolArgumentArgumentProperties from agent_input."""

class ResourceWithProps(ArgumentPropertiesMixin):
argument_properties = {
"$['user_id']": AgentToolArgumentArgumentProperties(
is_sensitive=False, argument_path="userId"
),
"$['query']": AgentToolArgumentArgumentProperties(
is_sensitive=False, argument_path="searchQuery"
),
}

agent_input = {
"userId": "user123",
"searchQuery": "test search",
"unused_arg": "not_used",
}

result = resolve_static_args(ResourceWithProps(), agent_input)

assert result == {
"$['user_id']": "user123",
"$['query']": "test search",
}

def test_resolve_static_args_with_mixed_static_and_argument_properties(self):
"""Test resolve_static_args with both static and argument properties."""

class ResourceWithProps(ArgumentPropertiesMixin):
argument_properties = {
"$['api_key']": AgentToolStaticArgumentProperties(
is_sensitive=False, value="secret_key"
),
"$['user_id']": AgentToolArgumentArgumentProperties(
is_sensitive=False, argument_path="userId"
),
"$['version']": AgentToolStaticArgumentProperties(
is_sensitive=False, value="v1"
),
}

agent_input = {"userId": "user456"}

result = resolve_static_args(ResourceWithProps(), agent_input)

assert result == {
"$['api_key']": "secret_key",
"$['user_id']": "user456",
"$['version']": "v1",
}

def test_resolve_static_args_skips_missing_argument_values(self):
"""Test that argument properties referencing missing agent_input keys are skipped."""

class ResourceWithProps(ArgumentPropertiesMixin):
argument_properties = {
"$['existing_param']": AgentToolArgumentArgumentProperties(
is_sensitive=False, argument_path="existingArg"
),
"$['missing_param']": AgentToolArgumentArgumentProperties(
is_sensitive=False, argument_path="missingArg"
),
}

agent_input = {"existingArg": "exists"}

result = resolve_static_args(ResourceWithProps(), agent_input)

assert result == {"$['existing_param']": "exists"}
assert "$['missing_param']" not in result
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading