Skip to content
Open
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 packages/uipath/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "uipath"
version = "2.14.13"
version = "2.14.14"
description = "Python SDK and CLI for UiPath Platform, enabling programmatic interaction with automation services, process management, and deployment tools."
readme = { file = "README.md", content-type = "text/markdown" }
requires-python = ">=3.11"
Expand Down
80 changes: 78 additions & 2 deletions packages/uipath/src/uipath/_cli/cli_new.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
from ._utils._console import ConsoleLogger
from ._utils._project_files import resolve_existing_project_id
from .middlewares import Middlewares
from .models.agent_frameworks import AgentFramework, installed_agent_frameworks
from .models.project_types import ProjectType

console = ConsoleLogger()

Expand Down Expand Up @@ -57,10 +59,49 @@ def generate_uipath_json(target_directory):
json.dump(uipath_config, f, indent=2)


def _detect_agent_framework(installed: list[AgentFramework]) -> AgentFramework:
"""Resolve an unset --agent-framework from the installed integrations.

Called with at most one installed integration (several error out before
this): the single installed one wins, none installed errors with the
list of frameworks and their packages.
"""
if installed:
framework = installed[0]
console.info(f"Using the installed '{framework}' agent framework.")
return framework
packages = "\n".join(f" {framework.package}" for framework in AgentFramework)
console.error(
"No agent framework integration is installed.\n"
"Please install the package for the framework you want "
"(`pip install <package>` or `uv add <package>`):\n\n" + packages
)


@click.command()
@click.argument("name", type=str, default="")
@click.option(
"--type",
"project_type",
type=click.Choice([t.value for t in ProjectType]),
default=ProjectType.AUTO.value,
show_default=True,
help="Project type to scaffold. 'auto' scaffolds an agent when an agent "
"framework package (e.g. uipath-langchain) is installed and a function "
"otherwise; 'agent' requires one explicitly.",
)
@click.option(
"--agent-framework",
"agent_framework",
type=click.Choice([f.value for f in AgentFramework]),
default=None,
help=(
"Agent framework to scaffold for. Only valid together with `--type agent`; "
"defaults to the framework whose integration package is installed."
),
)
@track_command("new")
def new(name: str):
def new(name: str, project_type: str, agent_framework: str | None):
"""Generate a quick-start project."""
directory = os.getcwd()

Expand All @@ -69,7 +110,30 @@ def new(name: str):
"Please specify a name for your project:\n`uipath new hello-world`"
)

result = Middlewares.next("new", name)
scaffold_type = ProjectType(project_type)
framework = AgentFramework(agent_framework) if agent_framework else None

if framework and scaffold_type is not ProjectType.AGENT:
console.error(
"`--agent-framework` can only be used together with `--type agent`."
)

if framework is None and scaffold_type is not ProjectType.FUNCTION:
installed = installed_agent_frameworks()
if len(installed) > 1:
console.error(
"Multiple agent frameworks are installed: "
+ ", ".join(sorted(installed))
+ ".\nPick one with `--type agent --agent-framework <framework>`, "
f"or run `uipath new {name} --type function` to create a "
"function project."
)
if scaffold_type is ProjectType.AGENT:
framework = _detect_agent_framework(installed)

result = Middlewares.next(
"new", name, project_type=scaffold_type, agent_framework=framework
)

if result.error_message:
console.error(
Expand All @@ -82,6 +146,18 @@ def new(name: str):
if not result.should_continue:
return

if framework is not None: # only set for agent scaffolds
console.error(
f"The '{framework.package}' package is required to scaffold a "
f"'{framework}' agent.\n"
"Please install it:\n\n"
" # Using pip:\n"
f" pip install {framework.package}\n\n"
" # Using uv:\n"
f" uv add {framework.package}\n\n"
f"Or run `uipath new {name}` to create a function project."
)

with console.spinner(f"Creating new project {name} in current directory ..."):
generate_script(directory)
console.success("Created 'main.py' file.")
Expand Down
51 changes: 51 additions & 0 deletions packages/uipath/src/uipath/_cli/models/agent_frameworks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
"""Agent frameworks supported by `uipath new --type agent`.

Each framework's integration package registers a middleware that claims
agent scaffolds for its framework.
"""

import importlib.metadata
from enum import StrEnum


class AgentFramework(StrEnum):
"""Agent frameworks with a UiPath integration package."""

CLAUDE_SDK = "claude-sdk"
GOOGLE_ADK = "google-adk"
LANGCHAIN = "langchain"
LLAMAINDEX = "llamaindex"
MICROSOFT_AGENT_FRAMEWORK = "microsoft-agent-framework"
OPENAI_AGENTS = "openai-agents"
PYDANTIC_AI = "pydantic-ai"

@property
def package(self) -> str:
"""PyPI package that provides this framework's UiPath integration."""
return _AGENT_FRAMEWORK_PACKAGES[self]


# uipath-langchain lives in its own repo; the rest come from
# UiPath/uipath-integrations-python (note: microsoft-agent-framework ships
# as `uipath-agent-framework`).
_AGENT_FRAMEWORK_PACKAGES = {
AgentFramework.CLAUDE_SDK: "uipath-claude-sdk",
AgentFramework.GOOGLE_ADK: "uipath-google-adk",
AgentFramework.LANGCHAIN: "uipath-langchain",
AgentFramework.LLAMAINDEX: "uipath-llamaindex",
AgentFramework.MICROSOFT_AGENT_FRAMEWORK: "uipath-agent-framework",
AgentFramework.OPENAI_AGENTS: "uipath-openai-agents",
AgentFramework.PYDANTIC_AI: "uipath-pydantic-ai",
}


def installed_agent_frameworks() -> list[AgentFramework]:
"""Agent frameworks whose integration package is installed in this environment."""
installed = []
for framework in AgentFramework:
try:
importlib.metadata.distribution(framework.package)
except importlib.metadata.PackageNotFoundError:
continue
installed.append(framework)
return installed
21 changes: 21 additions & 0 deletions packages/uipath/src/uipath/_cli/models/project_types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"""Project types scaffolded by `uipath new`.

Framework integrations (uipath-langchain and the packages in
UiPath/uipath-integrations-python) import this to decide whether a
`uipath new` invocation is theirs to handle.
"""

from enum import StrEnum


class ProjectType(StrEnum):
"""What `uipath new` scaffolds.

AUTO (the default) lets an installed agent framework claim the scaffold
and falls back to a function project; FUNCTION and AGENT request one
explicitly.
"""

AUTO = "auto"
FUNCTION = "function"
AGENT = "agent"
Loading
Loading