@uipath/delegate-sdk 0.1.9 → 0.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Run the UiPath Delegate agent from Node — login, prompts, screenshots, UI automation, all headless. The native C# interop service is bundled in a platform-specific runtime package and auto-spawns when needed.
4
4
 
5
- Looking for the terminal experience? That's **`@uipath/delegate-cli`** — a thin wrapper over this SDK that owns the `delegate-cli` bin. This package is programmatic-only.
5
+ This package is programmatic-only. The terminal experience lives in **`@uipath/delegate-cli`**, a separate package that wraps this SDK and owns the `delegate-cli` bin — install it alongside this one with `npm install @uipath/delegate-cli`, from the same registry you installed this package from. Everything below is the SDK's own API; nothing here requires the CLI.
6
6
 
7
7
  - **Platforms**: macOS arm64, Windows x64, Linux x64. Linux is text-and-file only — bash, file, download, and system tools work; computer use (screenshots, window management, coordinate-based actions, `execute-prompt`, element find, Office tools) is unavailable and throws, so run Linux with `enableComputerUse=false`.
8
8
 
@@ -19,24 +19,33 @@ npm pulls the SDK plus your platform's runtime package (Mac arm64, Win x64, or L
19
19
  ## Quick start
20
20
 
21
21
  ```ts
22
- import { DelegateAgent, loadAndRefreshAuth } from '@uipath/delegate-sdk';
22
+ import { DelegateAgent, loadAndRefreshAuth, runLoginFlow } from '@uipath/delegate-sdk';
23
+
24
+ // Reuse the saved login if there is one, otherwise open the browser once.
25
+ const auth = (await loadAndRefreshAuth()) ?? (await runLoginFlow({ env: 'production' }));
23
26
 
24
27
  const agent = new DelegateAgent();
25
28
  await agent.initialize({
26
29
  backendUrl: 'https://cloud.uipath.com/<org>/<tenant>/delegate_',
27
- auth: await loadAndRefreshAuth(), // saved login from `delegate-cli login`
30
+ auth,
28
31
  });
29
32
  await agent.sendMessage('take a screenshot and tell me what is open');
30
33
  await agent.destroy();
31
34
  ```
32
35
 
33
- The saved login comes from `delegate-cli login --env <env>` (browser OAuth → `~/.aria/sdk-auth.json`); see the `@uipath/delegate-cli` README for the full terminal surface (prompts, `models`, `whoami`, host mode). Both `backendUrl` and the login environment are always explicit — the SDK never picks an environment on your behalf.
36
+ `runLoginFlow({ env })` runs browser OAuth and saves the grant to `~/.aria/sdk-auth.json`; `loadAndRefreshAuth()` reads it back on later runs. Both `backendUrl` and the login environment are always explicit — the SDK never picks an environment on your behalf. The separate `@uipath/delegate-cli` package writes the same file from a terminal, so a login performed either way is usable by the other.
34
37
 
35
38
  ---
36
39
 
37
40
  ## Authentication
38
41
 
39
- `delegate-cli login --env <env>` runs OAuth PKCE in your browser and saves to `~/.aria/sdk-auth.json` (`--env` is required — there is no default cloud). The browser is sent back to a loopback listener on `http://localhost:8055/oidc/login`; when that port is busy the login falls back to 42042, then 8104 (the three callbacks registered for the built-in client — 8104 is `uip login`'s fixed port, so it is tried last):
42
+ ```ts
43
+ import { runLoginFlow } from '@uipath/delegate-sdk';
44
+
45
+ const auth = await runLoginFlow({ env: 'production' }); // 'alpha' | 'staging' | 'production'
46
+ ```
47
+
48
+ `runLoginFlow` runs OAuth PKCE in your browser and saves to `~/.aria/sdk-auth.json` (`env`, or an explicit `baseUrl`, is required — there is no default cloud; `tenant` picks a tenant by name, `silent: true` suppresses the console output). The browser is sent back to a loopback listener on `http://localhost:8055/oidc/login`; when that port is busy the login falls back to 42042, then 8104 (the three callbacks registered for the built-in client — 8104 is `uip login`'s fixed port, so it is tried last):
40
49
 
41
50
  ```json
42
51
  {
@@ -50,9 +59,17 @@ The saved login comes from `delegate-cli login --env <env>` (browser OAuth → `
50
59
 
51
60
  The `orgLogicalName` + `tenantName` slugs are what let a consumer build the full backend URL (`{cloud}/{org}/{tenant}/delegate_`) — see `buildDelegateServiceUrl`.
52
61
 
53
- **Refresh**: `loadAndRefreshAuth()` proactively refreshes tokens with < 30 % lifetime left. The host command (`runHostCommand`) keeps refreshing tokens automatically from `~/.aria/sdk-auth.json` for as long as it runs (rotated refresh tokens are persisted back). The programmatic login flow is exported as `runLoginFlow`; its `tenant` option signs into a tenant by name instead of the organization's first one (the CLI exposes it as `delegate-cli login --tenant <name>`).
62
+ **Refresh**: `loadAndRefreshAuth()` proactively refreshes tokens with < 30 % lifetime left. The host command (`runHostCommand`) keeps refreshing tokens automatically from `~/.aria/sdk-auth.json` for as long as it runs (rotated refresh tokens are persisted back).
54
63
 
55
- **Tenants**: tokens are issued per organization, so the tenant can change without a new login. `listTenants(auth)` returns the organization's tenants (`{ id, name }`), `switchTenant(auth, name)` returns a copy of the login pointed at the named tenant (case-insensitive; an unknown name throws listing the tenants that exist), and `saveAuthData` persists it, returning `false` (after logging) when the file could not be written. `loadAndRefreshSdkLogin()` is the loader to pair with that write: it reads `~/.aria/sdk-auth.json` only, never the desktop app's fallback file, so another product's tokens cannot end up in the SDK's file. `delegate-cli tenant <name>` is exactly this sequence.
64
+ **Tenants**: tokens are issued per organization, so the tenant can change without a new login. `listTenants(auth)` returns the organization's tenants (`{ id, name }`), `switchTenant(auth, name)` returns a copy of the login pointed at the named tenant (case-insensitive; an unknown name throws listing the tenants that exist), and `saveAuthData` persists it, returning `false` (after logging) when the file could not be written. `loadAndRefreshSdkLogin()` is the loader to pair with that write: it reads `~/.aria/sdk-auth.json` only, never the desktop app's fallback file, so another product's tokens cannot end up in the SDK's file:
65
+
66
+ ```ts
67
+ import { loadAndRefreshSdkLogin, saveAuthData, switchTenant } from '@uipath/delegate-sdk';
68
+
69
+ const auth = await loadAndRefreshSdkLogin();
70
+ if (!auth) throw new Error('No saved login — call runLoginFlow first.');
71
+ saveAuthData(await switchTenant(auth, 'Finance'));
72
+ ```
56
73
 
57
74
  ### Using your own identity app
58
75
 
@@ -90,7 +107,9 @@ Notes:
90
107
 
91
108
  ## Computer use & interop lifecycle
92
109
 
93
- When `enableComputerUse` is on, the SDK spawns the platform-matching C# binary from `node_modules/@uipath/delegate-runtime-<platform>/interop/` on a free port (the runtime package ships that tree as `interop.zip`; the first start expands it in place, a one-off cost of a few seconds — loose `.dll` files would not survive a UiPath Studio project pack) and routes screenshot / UIA / mouse / keyboard calls to it.
110
+ When `autoSpawnInterop` is on (and no `interopUrl` was supplied), the SDK spawns the platform-matching C# binary from `node_modules/@uipath/delegate-runtime-<platform>/interop/` on a free port (the runtime package ships that tree as `interop.zip`; the first start expands it in place, a one-off cost of a few seconds — loose `.dll` files would not survive a UiPath Studio project pack) and routes calls to it.
111
+
112
+ `autoSpawnInterop` is the gate, not `enableComputerUse`, because interop is the shared backend for far more than the screen: Excel, Word, PowerPoint, PDF, Mail, Calendar, FileSystem and shell all resolve through the same URL. `enableComputerUse: false` only removes the screen-dependent surface — screenshots, window list, focused element, and the UI-automation tools — and leaves everything else running. Skills are the exception to both: they are read through Node (`runtime/nodeSkillsHostAccess.ts`) and load at every level.
94
113
 
95
114
  | Mode | Spawn | Cleanup |
96
115
  |---|---|---|
@@ -100,7 +119,7 @@ When `enableComputerUse` is on, the SDK spawns the platform-matching C# binary f
100
119
 
101
120
  PID file: `~/.delegate-sdk/interop.pid`. Stale entries (dead process or `/health` not responding) are cleaned up automatically.
102
121
 
103
- **Turn-policy snapshots**: the interop denies governed endpoints (filesystem, shell, Office, PDF, computer use) unless the request carries an `X-Delegate-Policy-Snapshot` header naming a pre-registered snapshot. The SDK handles this automatically whenever an interop is engaged: it registers a full-access global snapshot per agent turn (and one ambient snapshot for out-of-turn calls like skills scanning) and attaches the header. Registration needs an organization id from the auth provider; without one, turns fail with "Local access policy could not be selected".
122
+ **Turn-policy snapshots**: the interop denies governed endpoints (filesystem, shell, Office, PDF, computer use) unless the request carries an `X-Delegate-Policy-Snapshot` header naming a pre-registered snapshot. The SDK handles this automatically whenever an interop is engaged: it registers a full-access global snapshot per agent turn (and one ambient snapshot for interop calls made outside any turn) and attaches the header. Registration needs an organization id from the auth provider; without one, turns fail with "Local access policy could not be selected".
104
123
 
105
124
  **macOS first run**: grant *Accessibility* + *Screen Recording* permissions to your terminal/node in *System Settings → Privacy & Security* when prompted.
106
125
 
@@ -113,14 +132,10 @@ PID file: `~/.delegate-sdk/interop.pid`. Stale entries (dead process or `/health
113
132
  ESM only — use `import`, not `require()`.
114
133
 
115
134
  ```ts
116
- import { DelegateAgent } from '@uipath/delegate-sdk';
117
- import fs from 'fs';
118
- import os from 'os';
119
- import path from 'node:path';
135
+ import { DelegateAgent, loadAndRefreshAuth } from '@uipath/delegate-sdk';
120
136
 
121
- const auth = JSON.parse(
122
- fs.readFileSync(path.join(os.homedir(), '.aria', 'sdk-auth.json'), 'utf-8'),
123
- );
137
+ const auth = await loadAndRefreshAuth();
138
+ if (!auth) throw new Error('No saved login — call runLoginFlow({ env }) first.');
124
139
 
125
140
  const agent = new DelegateAgent();
126
141
 
@@ -147,19 +162,20 @@ await agent.destroy();
147
162
  | Option | Default | Notes |
148
163
  |---|---|---|
149
164
  | `backendUrl` | — (required unless `environment` is set) | Full agent service URL, e.g. `https://cloud.uipath.com/<org>/<tenant>/delegate_`. `initialize()` rejects when neither it nor `environment` selects a backend — the SDK has no default. An explicit value (or the `BACKEND_URL` env var) wins over `environment`. |
150
- | `environment` | unset | `alpha` \| `staging` \| `production` \| `localhost`. Derives `backendUrl` when it is omitted: `localhost` → `http://localhost:5002`; a cloud → `<cloud>/<org>/<tenant>/delegate_` from the `organizationName` (or `orgLogicalName`) and `tenantName` slugs on `auth` — a saved `delegate-cli login` record works as-is. Fails loudly when the slugs are missing. Same resolution as the CLI's `--env`, also exported as `resolveBackendUrl(env, auth, explicitUrl)`. |
165
+ | `environment` | unset | `alpha` \| `staging` \| `production` \| `localhost`. Derives `backendUrl` when it is omitted: `localhost` → `http://localhost:5002`; a cloud → `<cloud>/<org>/<tenant>/delegate_` from the `organizationName` (or `orgLogicalName`) and `tenantName` slugs on `auth` — a login saved by `runLoginFlow` works as-is. Fails loudly when the slugs are missing. Also exported on its own as `resolveBackendUrl(env, auth, explicitUrl)`. |
151
166
  | `model` | `gemini_3_6_flash` | LLM id. |
152
- | `enableComputerUse` | `true` | False → skip interop entirely. |
153
- | `autoSpawnInterop` | `true` | False → manage interop yourself, pass `interopUrl`. |
167
+ | `enableComputerUse` | `true` | False → drop the **screen**, not interop: no screenshots, no window list, no focused element, and `AppFind` / `AppAct` / `AppGetDescriptor` leave the tool catalog. File, Office, PDF and shell tools are unaffected — they reach interop through the same URL. Pair with `autoSpawnInterop: true` (the default) to keep them working. |
168
+ | `autoSpawnInterop` | `true` | False → manage interop yourself, pass `interopUrl`. This, not `enableComputerUse`, is the gate on whether interop exists at all. False **and** no `interopUrl` → no interop, so every interop-backed tool fails; skills still load (they read through Node). |
154
169
  | `keepInteropAlive` | `false` | True → leave interop running after `destroy()`. |
155
170
  | `enableConnections` | `true` | Orchestrator ConnectionService prewarm. |
156
171
  | `enableSecurity` | `true` | Tool security wrapper. |
157
172
  | `enableSkills` | `true` | Skills system. Local + remote skills always load when enabled; the app-shipped bundle additionally requires a discoverable path (a warning fires if none is found — skills are not disabled). |
158
173
  | `bundledSkillsPath` | auto | Absolute path to a bundled skills directory. **Merged** (deduped by path) with `DELEGATE_BUNDLED_SKILLS_PATH` env and any installed UiPath desktop app — every existing root loads, not just the first. Installed-app locations: `/Applications/UiPath Delegate.app/Contents/Resources/skills` (standalone Delegate) and `/Applications/UiPath Assistant.app/Contents/Resources/skills` (merged Delegate + Assistant bundle) on macOS, `%LOCALAPPDATA%\Programs\UiPath\UiPath.Delegate\resources\skills` / `%PROGRAMFILES%\…` (Windows). Linux has no installed-app source; pass this option or set the env var. Same skill name across two roots is deduped downstream (explicit > env > app). |
174
+ | `preloadSkills` | `[]` | Skill names attached to SDK-created sessions before the first model turn. |
159
175
  | `maxSteps` | `0` | Hard cap on agentic-loop steps (`0` = unlimited). |
160
- | `workingDirectory` | unset | Two effects: (1) default cwd for the shell tools (`ExecutePowershellCommand` / `ExecuteBashCommand`), seeding the per-session cwd commands fall back to when the model omits `workingDirectory`; (2) the userData base — the wiki and plans land under it (`<workingDirectory>/sessions/<sessionId>/wiki`, or `<workingDirectory>/projects/<projectId>/wiki` when `projectId` is set) instead of `~/.aria-sdk`. Absolute path; not created. |
176
+ | `workingDirectory` | unset | Default cwd for shell tools and the userData base for wiki/project state. Must be absolute; created at `initialize()` if missing. |
161
177
  | `shellPathPrepend` | `[]` | Directories to prepend to `PATH` for every shell-tool command (`ExecuteBashCommand` / `ExecutePowershellCommand`), first entry wins. For harnesses that shadow real CLIs with mock scripts (e.g. a sandbox's `mocks/uip` must beat the installed `uip`). Delivered through the per-command `variables` env the interop service applies, so it reaches commands even though they run inside interop; any existing occurrence of a listed dir is de-duplicated out of the base PATH. |
162
- | `projectId` | unset | Bind the agent's sessions to a project id for local wiki routing: **every** session the agent handles (SDK-created or passed to `sendMessage`) resolves its wiki to `<userDataBase>/projects/<projectId>/wiki` instead of `<userDataBase>/sessions/<sessionId>/wiki` (userDataBase = `workingDirectory` when set, else `~/.aria-sdk`). Don't set it on an agent driving unrelated sessions you want kept separate. Client-side routing key only — does not create or link a backend project row. |
178
+ | `projectId` | unset | Local project routing key. Wiki state uses `<userDataBase>/projects/<projectId>/wiki`; the id is not sent to the backend. It is used as that folder name verbatim, so `initialize()` rejects an id that is not a safe single segment (`isSafeProjectFolderSegment`, exported for callers that validate earlier). With `business-analysis` preloaded, the SDK also supplies project paths and seeds its checklist/progress files without overwriting existing files. |
163
179
  | `sessionId` | unset | Pin the session id used when a `sendMessage` call omits one, so the standalone wiki lands at `<userDataBase>/sessions/<sessionId>/wiki` deterministically instead of a random server-assigned id. `projectId` takes precedence. Unlike `projectId`, the id is a backend entity: a pinned id skips `createSession`, so it must be one the backend accepts. An explicit `sendMessage` sessionId argument overrides it. |
164
180
  | `effort` | model default | Reasoning-effort tier: `low` / `medium` / `high` / `xhigh` / `max`. Forwarded to the backend as `user_config.effort`. Invalid values are ignored. |
165
181
  | `requestHeaders` | `{}` | Extra HTTP headers stamped on every backend request (REST + SSE), applied at `initialize()`. For service-token (S2S) callers that must supply `X-UiPath-Internal-*` context headers, or per-request routing flags. |
@@ -184,7 +200,25 @@ for (const check of result.checks) console.log(check.name, check.status, check.d
184
200
  if (!result.ok) process.exit(1);
185
201
  ```
186
202
 
187
- Three entries come back, in order: `auth` (token not expired, and consistent with `backendUrl` as above), `backend` (one authenticated, read-only `GET <backendUrl>/v1/config`), and `interop` (`spawn` starts the bundled interop, waits for `/health`, and stops it again unless one was already running; `{ url }` probes an interop you manage; `skip` reports `skipped`). Failures are reported in the result, never thrown, so every problem is listed at once. The CLI exposes it as `delegate-cli check`.
203
+ Three entries come back, in order: `auth` (token not expired, and consistent with `backendUrl` as above), `backend` (one authenticated, read-only `GET <backendUrl>/v1/config`), and `interop` (`spawn` starts the bundled interop, waits for `/health`, and stops it again unless one was already running; `{ url }` probes an interop you manage; `skip` reports `skipped`). Failures are reported in the result, never thrown, so every problem is listed at once.
204
+
205
+ ---
206
+
207
+ ## Cartographer / Business Analysis
208
+
209
+ Cartographer uses the existing skills API; there is no separate project-template API. Explicitly preload the desktop template's skills and provide a stable project directory:
210
+
211
+ ```ts
212
+ await agent.initialize({
213
+ environment: 'alpha',
214
+ auth,
215
+ preloadSkills: ['business-analysis', 'project-checklist', 'knowledge-base'],
216
+ projectId: 'invoice-approval',
217
+ workingDirectory: '/srv/engagements',
218
+ });
219
+ ```
220
+
221
+ Before the first message, the SDK copies the bundled Business Analysis `checklist.md` and `progress.yaml` assets into `projects/invoice-approval/` if absent. Each turn receives `ProjectId`, `ChecklistPath`, and `ProgressPath`; `{WikiPath}` in preloaded skill content resolves to the same project's `wiki/` directory.
188
222
 
189
223
  ---
190
224
 
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
1
  [diffend] Oversized file quarantined before diffing.
2
2
  name: package/dist/index.mjs
3
- size: 54758591 bytes
4
- sha256: 996d35eba8f8873c7fc4bf74b7b0e86969b46f90de5d9fcac7f7af964b172a51
3
+ size: 59597048 bytes
4
+ sha256: c02951fd2ab3019f027808f733e541f4d81a0c3d133e63b0357fbd81971d6457
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uipath/delegate-sdk",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
4
4
  "description": "UiPath Delegate SDK - Programmatic agent interface",
5
5
  "license": "Apache-2.0",
6
6
  "type": "commonjs",
@@ -50,9 +50,9 @@
50
50
  "zod-to-json-schema": "^3.25.1"
51
51
  },
52
52
  "optionalDependencies": {
53
- "@uipath/delegate-runtime-darwin-arm64": "0.1.9",
54
- "@uipath/delegate-runtime-win32-x64": "0.1.9",
55
- "@uipath/delegate-runtime-linux-x64": "0.1.9"
53
+ "@uipath/delegate-runtime-darwin-arm64": "0.1.10",
54
+ "@uipath/delegate-runtime-win32-x64": "0.1.10",
55
+ "@uipath/delegate-runtime-linux-x64": "0.1.10"
56
56
  },
57
57
  "devDependencies": {
58
58
  "@types/node": "^22.0.0",