Repository navigation
feat(skills): skill bundles for coded agents [PC-5187] - #1962
cristian-groza wants to merge 4 commits into
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
Unbounded download buffering risks memory exhaustion, while blocking local-source operations prevent enforcement of the timeout and timely cancellation.
4 open issues
What changed in this PR
Adds preview skill-bundle support to the UiPath Python SDK, providing the platform layer for the planned LangChain integration.
Changes:
- Introduces
sdk.skillsfor bundle loading, file access, metadata retrieval and tracing, with local, mock and Orchestrator sources. - Adds
skillBundleoverrides and improves CLI handling of unsupported bindings and overwrite types. - Adds tests and documentation, and bumps
uipathto 2.14.45 anduipath-platformto 0.2.42.
| File | Description |
|---|---|
packages/uipath/uv.lock |
Updates package versions and platform dependencies. |
packages/uipath/tests/resource_overrides/test_resource_overrides.py |
Tests skill overrides and concise warnings. |
packages/uipath/tests/cli/test_studio_project_overwrites.py |
Tests Studio overwrite parsing and unknown-kind handling. |
packages/uipath/tests/cli/test_push.py |
Tests skipped-binding explanations. |
packages/uipath/src/uipath/_resources/CLI_REFERENCE.md |
Refreshes generated CLI documentation. |
packages/uipath/src/uipath/_cli/_utils/_studio_project.py |
Skips unrecognized Studio overwrites with warnings. |
packages/uipath/src/uipath/_cli/_utils/_common.py |
Adds concise overwrite-error formatting. |
packages/uipath/src/uipath/_cli/_push/_resolvers.py |
Clarifies why unsupported bindings are skipped. |
packages/uipath/scripts/update_agents_md.py |
Removes builtins. prefixes from generated signatures. |
packages/uipath/pyproject.toml |
Bumps SDK version and platform dependency floor. |
packages/uipath/mkdocs.yml |
Adds the Skills documentation page to navigation. |
packages/uipath/docs/core/skills.md |
Documents loading, sources, overrides and limits. |
packages/uipath/docs/core/release_notes.md |
Adds unreleased skill-support notes. |
packages/uipath/docs/core/environment_variables.md |
Documents skill-source configuration. |
packages/uipath/docs/core/agents.md |
Introduces skills in the agent guide. |
packages/uipath-platform/uv.lock |
Updates platform version and YAML dependencies. |
packages/uipath-platform/tests/test_uipath_facade.py |
Tests facade service types and caching. |
packages/uipath-platform/tests/services/tests_data/skills/ops/vendor-lookup/SKILL.md |
Adds a same-named skill fixture across bundles. |
packages/uipath-platform/tests/services/tests_data/skills/ops/bundle.json |
Defines operations bundle metadata. |
packages/uipath-platform/tests/services/tests_data/skills/finance/vendor-lookup/SKILL.md |
Adds a finance lookup skill fixture. |
packages/uipath-platform/tests/services/tests_data/skills/finance/invoice-triage/SKILL.md |
Adds an invoice-triage skill fixture. |
packages/uipath-platform/tests/services/tests_data/skills/finance/invoice-triage/reference/vendors.md |
Adds a nested reference-file fixture. |
packages/uipath-platform/tests/services/tests_data/skills/finance/bundle.json |
Defines finance bundle metadata. |
packages/uipath-platform/tests/services/skills/test_telemetry.py |
Tests skill spans, events and attributes. |
packages/uipath-platform/tests/services/skills/test_sources_orchestrator.py |
Tests API-backed downloads and failure handling. |
packages/uipath-platform/tests/services/skills/test_sources_local.py |
Tests local copying, filtering and size limits. |
packages/uipath-platform/tests/services/skills/test_skill_md.py |
Tests frontmatter description parsing. |
packages/uipath-platform/tests/services/skills/test_package_imports.py |
Tests lightweight imports and lazy exports. |
packages/uipath-platform/tests/services/skills/test_overwrites.py |
Tests override precedence and validation. |
packages/uipath-platform/tests/services/skills/test_models.py |
Tests models, manifests, reads and cleanup. |
packages/uipath-platform/tests/services/skills/test_layout.py |
Tests bundle layout helpers. |
packages/uipath-platform/tests/services/skills/test_get_bundle_source.py |
Tests environment-based source selection. |
packages/uipath-platform/tests/services/skills/helpers.py |
Shares skill-fixture paths. |
packages/uipath-platform/tests/services/skills/conftest.py |
Provides filesystem, retry and tracing fixtures. |
packages/uipath-platform/tests/services/skills/__init__.py |
Marks the skills tests as a package. |
packages/uipath-platform/tests/common/test_bindings_skill_bundle.py |
Tests typed skill-bundle overwrite parsing. |
packages/uipath-platform/src/uipath/platform/skills/skills.py |
Defines bundle models and SkillSet operations. |
packages/uipath-platform/src/uipath/platform/skills/_telemetry.py |
Records bundle-resolution and skill-read telemetry. |
packages/uipath-platform/src/uipath/platform/skills/_sources.py |
Implements local and API-backed bundle sources. |
packages/uipath-platform/src/uipath/platform/skills/_skills_service.py |
Coordinates loading, overrides, failures and cleanup. |
packages/uipath-platform/src/uipath/platform/skills/_skills_api.py |
Adds the Skills API client and folder-backed mock. |
packages/uipath-platform/src/uipath/platform/skills/_skill_md.py |
Extracts descriptions from YAML frontmatter. |
packages/uipath-platform/src/uipath/platform/skills/_overwrites.py |
Applies deployment overrides to bundle references. |
packages/uipath-platform/src/uipath/platform/skills/_layout.py |
Provides file discovery and path-validation helpers. |
packages/uipath-platform/src/uipath/platform/skills/_constants.py |
Defines shared names, limits and environment variables. |
packages/uipath-platform/src/uipath/platform/skills/__init__.py |
Exposes models and lazy service exports. |
packages/uipath-platform/src/uipath/platform/common/_bindings.py |
Adds the skill-bundle overwrite model. |
packages/uipath-platform/src/uipath/platform/common/__init__.py |
Exports the new overwrite type. |
packages/uipath-platform/src/uipath/platform/_uipath.py |
Exposes cached sdk.skills access. |
packages/uipath-platform/pyproject.toml |
Bumps platform version and adds YAML dependencies. |
Review effort: Balanced
… setup [PC-5187] Addresses the review of #1962: - LocalFolderBundleSource copies on a worker thread with a stop flag, so the event loop keeps running and the 20 s budget applies to it too. On timeout or cancellation the copy stops before its next file and materialize waits for the thread, so nothing lands in a bundle folder after the service removes it. - A temp folder that cannot be created is reported as source_unavailable on the span, the caller's source is closed, and the run continues. - A blank versionMode in a skillBundle overwrite counts as unset, like the other fields, instead of rejecting the whole entry. - A comment on the point-in-time Skill load span. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Coded agents can use skill bundles, the versioned SKILL.md bundles that low-code agents use. uipath-platform (0.2.42): - uipath.platform.skills, exposed as sdk.skills. load_all_async(refs) resolves the bundles an agent declares, writes them to disk at run start and returns a SkillSet; load_async loads one bundle; both have sync twins. SkillSet offers names(), prompt_section(), read() and failures. - A bundle that cannot be resolved never fails the run: it is reported in failures with a reason (not_found, version_not_found, forbidden, too_large, invalid, source_unavailable). - Sources are chosen with UIPATH_SKILLS_SOURCE: local (the default, reading ./skills or UIPATH_SKILLS_LOCAL_ROOT) and orchestrator, a placeholder that reports every bundle as source_unavailable until the Orchestrator Skills API exists. Custom sources implement SkillBundleSource. - A skill folder holds SKILL.md in any case; it is written as SKILL.md. - Limits of 512 KiB per file, 24 MiB per bundle and 20 s per bundle. Scripts are copied, never executed. - Spans: "Skill bundles resolved" per load call and "Skill load - <bundle>/<skill>" per SKILL.md read. - SkillBundleResourceOverwrite: a skillBundle.<name>[.<folder>] resource overwrite replaces the whole binding, like the other bindings (name, folderPath and versionMode, plus version when pinned). load_all_async applies it before fetching; the agent keeps the declared name. An incomplete or invalid overwrite is skipped with a warning. - pyyaml becomes a direct dependency, for SKILL.md frontmatter. uipath (2.14.45, requires uipath-platform>=0.2.42): - uipath run, debug and eval skip a resource overwrite kind they do not know, with a one-line warning, instead of failing. - Docs: a new core/skills.md page, the skills environment variables, a link from agents.md, and the sdk.skills entries in SDK_REFERENCE.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
02b75eb to
efcdc65
Compare
🚨 Heads up:
|
🚨 Heads up:
|
Add skill_load_span, a context manager that keeps the Skill load span current while the SKILL.md is read, so the tool call that reads it becomes its child. The caller settles the load with loaded(size) or fail(reason); a load left unsettled, or one that raises, ends with an error status. record_skill_loaded now wraps it, so SkillSet.read is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
main moved uipath-platform to 0.3.0 and uipath to 2.15.0. Keep the skills bump on top of them: uipath-platform 0.3.1 (with pyyaml and types-PyYAML) and uipath 2.15.1 requiring uipath-platform>=0.3.1,<0.4.0. Lockfiles regenerated with uv lock, keeping main's lock headers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|





PR stack (skills for coded agents and the advanced harness), merge in this order
sdk.skillsinuipath-platform0.2.42 andskillBundleoverrides inuipath2.14.45.uipath_langchain.skills(UiPathSkills,load_skilltool, skills middleware) and theskills-agentsample. Draft until this PR is released; it then raises its floors to these versions.uipath.platform.skillsanduipath_langchain.skills, so both runtimes run one implementation. It bumps its pins once [1/3] and [2/3] are released.Summary
Coded agents can now use skill bundles, the same versioned
SKILL.mdbundles that low-code agents use (design: Confluence "Skills as tool").uipath.platform.skills/sdk.skills(uipath-platform):load_all_async(refs)resolves the bundles an agent declares, writes them to disk at run start and returns aSkillSet.load_asyncloads one bundle. Both have sync twins.SkillSetexposesnames(),prompt_section()(the## Skillssystem-prompt block),read(name, path)andfailures.failureswith a reason:not_found,version_not_found,forbidden,too_large,invalidorsource_unavailable(which also covers the per-bundle timeout).UIPATH_SKILLS_SOURCE:local(the default) reads./skills, orUIPATH_SKILLS_LOCAL_ROOT. A bundle's version comes from an optionalbundle.json.orchestratoris a placeholder: every bundle is reported assource_unavailableand the agent runs without skills. See "Orchestrator Skills API" below.SkillBundleSource(materialize(ref, dest),aclose()) and raisesBundleSourceError(detail, reason=...).SKILL.mdin any case (skill.mdcounts); it is written to the bundle folder asSKILL.md, so every reader finds it by the usual name.Skill bundles resolvedspan per load call and aSkill load - <bundle>/<skill>span perSKILL.mdread.pyyamlbecomes a direct dependency ofuipath-platform, to read theSKILL.mdfrontmatter (uipathalready depends on it).skillBundle.<name>[.<folder>]resource overwrite (SkillBundleResourceOverwrite) replaces the whole binding, like every other binding:name,folderPathandversionModeare required, plusversionwhenversionModeispinned.load_all_asyncapplies it before fetching. Itsnameonly changes which bundle is fetched; the agent keeps the declared name (folder, prompt, manifest).uipath):uipath run/debug/evalskip a resource overwrite kind they don't know, with a one-line warning, instead of failing.core/skills.mdpage (mkdocs nav), the skills environment variables, a link fromagents.md, and thesdk.skillsentries in the generatedSDK_REFERENCE.md. Release notes are left for when the releases are cut.MANIFEST_FILE_NAMEis exported, so the advanced harness recognises a workspace the SDK materialized ([3/3]).uipath-platform0.2.42;uipath2.14.45, which requiresuipath-platform>=0.2.42.Orchestrator Skills API
The API does not exist yet and its final shape is not known, so this PR does not guess it: there is no HTTP client, no mock of the API and no
retrieve/listmetadata calls.OrchestratorBundleSourceis a placeholder behind theSkillBundleSourceseam. When the API is defined, the client andOrchestratorBundleSource.materializeland inuipath-platform, metadata calls can be added as new methods, andorchestratorbecomes the default.SkillSet, the overrides, the spans, #1179 and #829 sit above the seam and do not change. The docs mark the feature as preview.Test plan
packages/uipath-platform: full suite (2067 passed, 8 skipped),ruff check,ruff format --check,mypy --config-file pyproject.toml ..packages/uipath: full suite (2652 passed, 1 skipped, 1 xfailed),ruff check,ruff format --check,mypy --config-file pyproject.toml ..check_version_uniqueness.pyandcheck_dependency_version_bumps.pypass locally against this PR's range.tests/skills(110 passed) and UiPath/uipath-agents-python#829tests/unit(1312 passed).localsource: two bundles resolved, Claude Haiku 4.5 calledload_skill("ops/escalation-policy")and the run succeeded with theSkill loadspan recorded. Also checked:opsto thefinancefolder while the agent keeps the nameops;skill.mdloads.🤖 Generated with Claude Code