notte-sdk 0.0.22 → 1.9.0
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/LICENSE +21 -0
- package/README.md +501 -102
- package/dist/index.d.mts +1623 -229
- package/dist/index.d.ts +1623 -229
- package/dist/index.js +2784 -670
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2735 -676
- package/dist/index.mjs.map +1 -1
- package/dist/proxy/core.d.mts +1 -1
- package/dist/proxy/core.d.ts +1 -1
- package/dist/proxy/core.js +6 -4
- package/dist/proxy/core.js.map +1 -1
- package/dist/proxy/core.mjs +6 -4
- package/dist/proxy/core.mjs.map +1 -1
- package/dist/proxy/next.d.mts +12 -7
- package/dist/proxy/next.d.ts +12 -7
- package/dist/proxy/next.js +6 -4
- package/dist/proxy/next.js.map +1 -1
- package/dist/proxy/next.mjs +6 -4
- package/dist/proxy/next.mjs.map +1 -1
- package/dist/{types-DmqqdEMP.d.mts → types-C5V9BOux.d.mts} +3 -1
- package/dist/{types-DmqqdEMP.d.ts → types-C5V9BOux.d.ts} +3 -1
- package/package.json +29 -3
package/README.md
CHANGED
|
@@ -4,8 +4,85 @@
|
|
|
4
4
|
|
|
5
5
|
The official TypeScript SDK for Notte API, providing cloud-hosted browser sessions with precise control, LLM-powered web agents for automated tasks, serverless functions, and secure credential management.
|
|
6
6
|
|
|
7
|
+
## Contributing
|
|
8
|
+
|
|
9
|
+
This directory is a standalone npm package. Node.js 22 and 24 are tested in CI;
|
|
10
|
+
Python tooling is not required to build or test it.
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
cd node-sdk
|
|
14
|
+
npm ci
|
|
15
|
+
npm run typecheck
|
|
16
|
+
npm run test:unit -- --run
|
|
17
|
+
npx vitest run test/function-stream.local.test.ts # also part of npm run test:unit
|
|
18
|
+
npm run build
|
|
19
|
+
node scripts/check-package.js
|
|
20
|
+
npm pack --dry-run
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
`npm run build` compiles the checked-in client without contacting the API.
|
|
24
|
+
To update the generated client, run `npm run generate:staging`, review the diff,
|
|
25
|
+
and commit it. `npm run check:staging` checks for drift without editing your files.
|
|
26
|
+
|
|
27
|
+
For the isolated live test, set `NOTTE_API_KEY` and
|
|
28
|
+
`NOTTE_API_URL=https://us-staging.notte.cc`, then run:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npx vitest run test/function-create-run.integration.test.ts
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
This test creates its own function and deletes it afterward. Other live suites
|
|
35
|
+
may require pre-existing fixtures; see [test documentation](test/README.md).
|
|
36
|
+
The `node sdk cicd` workflow runs on every PR touching `node-sdk/`:
|
|
37
|
+
|
|
38
|
+
- `tests` runs unit tests, local HTTP integration tests, type checks, and package
|
|
39
|
+
checks on Node.js 22 and 24, including for fork PRs.
|
|
40
|
+
- `integration-tests` runs the isolated live function lifecycle tests against
|
|
41
|
+
staging on same-repository PRs. Fork PRs skip this credentialed job.
|
|
42
|
+
|
|
43
|
+
Both jobs also run on main pushes and manual workflow runs on main. API drift
|
|
44
|
+
checks remain limited to main pushes and manual workflow runs on main.
|
|
45
|
+
|
|
46
|
+
### Releases
|
|
47
|
+
|
|
48
|
+
The npm package remains `notte-sdk`. Its MIT license is in [LICENSE](LICENSE);
|
|
49
|
+
the repository root license does not replace this package's license.
|
|
50
|
+
|
|
51
|
+
The Node SDK is released together with the Python SDK, from the same tag and at
|
|
52
|
+
the same version. Cutting a release means creating a GitHub release tagged
|
|
53
|
+
`vX.Y.Z` on [nottelabs/notte](https://github.com/nottelabs/notte/releases):
|
|
54
|
+
|
|
55
|
+
- `pypi-release.yml` publishes the Python packages to PyPI as `X.Y.Z`.
|
|
56
|
+
- `node-sdk-publish.yml` sets this package's version to `X.Y.Z`, runs the
|
|
57
|
+
typecheck, unit tests, streaming test and export smoke test, publishes to npm
|
|
58
|
+
with provenance, then installs the published version back from npm to verify it.
|
|
59
|
+
|
|
60
|
+
`package.json` stays at `0.0.0-dev` on `main`; the version is only set in CI
|
|
61
|
+
from the tag, like the `.dev` placeholder in the Python `pyproject.toml` files.
|
|
62
|
+
Publishing uses npm trusted publishing (GitHub OIDC) bound to this repository,
|
|
63
|
+
workflow `node-sdk-publish.yml` and environment `npm`, so no npm token is stored
|
|
64
|
+
in the repository. To dry-run a release build locally, run `make release X.Y.Z`
|
|
65
|
+
in this directory; it never publishes.
|
|
66
|
+
|
|
67
|
+
Importing the SDK does not contact the npm registry. Constructing a `NotteClient`
|
|
68
|
+
performs a one-time, non-blocking check per process and warns when a newer
|
|
69
|
+
release exists, like the Python SDK. Set `NOTTE_SDK_DISABLE_VERSION_CHECK=1` to
|
|
70
|
+
disable it. To explicitly check for an update, call `await checkForLatestVersion()`
|
|
71
|
+
from `notte-sdk`.
|
|
72
|
+
API URLs must use HTTPS, except HTTP loopback addresses for local development.
|
|
73
|
+
|
|
7
74
|
## Features
|
|
8
75
|
|
|
76
|
+
### Server-side proxy security
|
|
77
|
+
|
|
78
|
+
`createNotteProxy` from `notte-sdk/next` requires an `authenticate` callback at
|
|
79
|
+
runtime. Without one, requests return 401 even when a server API key is configured.
|
|
80
|
+
The callback must verify caller identity and authorize access to requested
|
|
81
|
+
resources. Returning a user-specific Notte API key isolates accounts; returning
|
|
82
|
+
void uses the shared server key and requires application-level ownership checks.
|
|
83
|
+
An endpoint allowlist is not a substitute for authorization. Relative HTTP proxy
|
|
84
|
+
clients poll agent status for completion because they cannot use backend WebSockets.
|
|
85
|
+
|
|
9
86
|
- 🌐 **Cloud Browser Sessions** - Access remote browsers with full control
|
|
10
87
|
- 🤖 **LLM-Powered Agents** - Intelligent web automation with natural language
|
|
11
88
|
- 🔒 **Secret Vaults** - Enterprise-grade credential management with end-to-end encryption
|
|
@@ -14,6 +91,7 @@ The official TypeScript SDK for Notte API, providing cloud-hosted browser sessio
|
|
|
14
91
|
- 📡 **Real-time Updates** - WebSocket support for live agent monitoring
|
|
15
92
|
- 📝 **Type Safety** - Full TypeScript support with generated types
|
|
16
93
|
- ⚡ **Serverless Functions** - Run pre-built automation workflows with simple API calls
|
|
94
|
+
- 🔍 **Web Search, Secrets and Usage** - Search the web, manage workspace secrets and read billing usage
|
|
17
95
|
- 🔄 **Auto-sync** - Generated from OpenAPI spec, always up-to-date
|
|
18
96
|
|
|
19
97
|
## Installation
|
|
@@ -35,7 +113,7 @@ const notte = new NotteClient({
|
|
|
35
113
|
});
|
|
36
114
|
|
|
37
115
|
// Use session with automatic cleanup (mirrors Python's context manager)
|
|
38
|
-
await notte.Session({
|
|
116
|
+
await notte.Session({ idle_timeout_minutes: 5 }).use(async (session) => {
|
|
39
117
|
const status = await session.status();
|
|
40
118
|
console.log('Session status:', status);
|
|
41
119
|
});
|
|
@@ -52,13 +130,13 @@ const notte = new NotteClient();
|
|
|
52
130
|
await notte.Session().use(async (session) => {
|
|
53
131
|
const agent = notte.Agent({ session, max_steps: 10 });
|
|
54
132
|
|
|
55
|
-
const response = await agent.run(
|
|
56
|
-
"Find the best Italian restaurant in San Francisco and book a table for 2 at 7pm today",
|
|
57
|
-
(update) => {
|
|
133
|
+
const response = await agent.run({
|
|
134
|
+
task: "Find the best Italian restaurant in San Francisco and book a table for 2 at 7pm today",
|
|
135
|
+
updateHandler: (update) => {
|
|
58
136
|
// Receive real-time updates via WebSocket
|
|
59
|
-
console.log(`
|
|
137
|
+
console.log(`[${update.type}]`, update.data);
|
|
60
138
|
}
|
|
61
|
-
);
|
|
139
|
+
});
|
|
62
140
|
|
|
63
141
|
console.log(`Agent completed: ${response.success ? 'Success' : 'Failed'}`);
|
|
64
142
|
console.log(`Answer: ${response.answer}`);
|
|
@@ -74,10 +152,15 @@ The main client for interacting with the Notte API.
|
|
|
74
152
|
```typescript
|
|
75
153
|
import { NotteClient } from 'notte-sdk';
|
|
76
154
|
|
|
77
|
-
const notte = new NotteClient(
|
|
155
|
+
const notte = new NotteClient({
|
|
156
|
+
apiKey: process.env.NOTTE_API_KEY, // defaults to NOTTE_API_KEY
|
|
157
|
+
baseUrl: 'https://api.notte.cc', // defaults to NOTTE_API_URL or https://api.notte.cc
|
|
158
|
+
timeoutMs: 60_000, // per-request timeout, default 60 s
|
|
159
|
+
verbose: false, // log every request
|
|
160
|
+
});
|
|
78
161
|
|
|
79
162
|
// Create sessions
|
|
80
|
-
const session = notte.Session({
|
|
163
|
+
const session = notte.Session({ idle_timeout_minutes: 5, max_duration_minutes: 30 });
|
|
81
164
|
|
|
82
165
|
// Create agents
|
|
83
166
|
const agent = notte.Agent({ session, max_steps: 15 });
|
|
@@ -87,8 +170,32 @@ const vault = notte.Vault({ name: 'My Vault' });
|
|
|
87
170
|
|
|
88
171
|
// Create personas
|
|
89
172
|
const persona = notte.Persona({ create_vault: true });
|
|
173
|
+
|
|
174
|
+
// Check that the API is reachable (rejects with NotteAPIError otherwise)
|
|
175
|
+
await notte.healthCheck();
|
|
90
176
|
```
|
|
91
177
|
|
|
178
|
+
#### Listing resources
|
|
179
|
+
|
|
180
|
+
Every resource has a `list()` namespace, mirroring `client.sessions.list()` and
|
|
181
|
+
friends in Python. Options are the generated query parameters of the matching
|
|
182
|
+
endpoint (`SessionListOptions`, `AgentListOptions`, `VaultListOptions`,
|
|
183
|
+
`FunctionListOptions`, `PersonaListOptions`).
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
const sessions = await notte.sessions.list({ only_active: true });
|
|
187
|
+
const agents = await notte.agents.list({ page_size: 10 });
|
|
188
|
+
const vaults = await notte.vaults.list();
|
|
189
|
+
const functions = await notte.functions.list();
|
|
190
|
+
const personas = await notte.personas.list({ only_active: true });
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
#### Database preview branches
|
|
194
|
+
|
|
195
|
+
Set `NOTTE_DB_PREVIEW_BRANCH` (or pass `dbPreview` to the client) to route every
|
|
196
|
+
request and websocket handshake to a database preview branch. This is an internal
|
|
197
|
+
option used when testing API changes.
|
|
198
|
+
|
|
92
199
|
### Session
|
|
93
200
|
|
|
94
201
|
Manages browser sessions with automatic lifecycle management.
|
|
@@ -99,7 +206,7 @@ import { NotteClient } from 'notte-sdk';
|
|
|
99
206
|
const notte = new NotteClient();
|
|
100
207
|
|
|
101
208
|
// Context manager pattern (automatic start/stop)
|
|
102
|
-
await notte.Session({
|
|
209
|
+
await notte.Session({ idle_timeout_minutes: 5 }).use(async (session) => {
|
|
103
210
|
// Session is automatically started
|
|
104
211
|
console.log('Session ID:', session.getId());
|
|
105
212
|
|
|
@@ -120,7 +227,7 @@ try {
|
|
|
120
227
|
}
|
|
121
228
|
|
|
122
229
|
// Async iterator pattern
|
|
123
|
-
for await (const session of notte.Session({
|
|
230
|
+
for await (const session of notte.Session({ max_duration_minutes: 15 })) {
|
|
124
231
|
// Use session here
|
|
125
232
|
const status = await session.status();
|
|
126
233
|
console.log('Session active:', status);
|
|
@@ -128,15 +235,102 @@ for await (const session of notte.Session({ timeoutMinutes: 15 })) {
|
|
|
128
235
|
}
|
|
129
236
|
```
|
|
130
237
|
|
|
238
|
+
#### Browser control
|
|
239
|
+
|
|
240
|
+
Drive the page with typed actions, exactly like `session.execute(...)` in Python.
|
|
241
|
+
Element ids (`B1`, `I2`, ...) must come from a live `observe()` call.
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
import { NotteClient, actions, ActionExecutionError } from 'notte-sdk';
|
|
245
|
+
|
|
246
|
+
const notte = new NotteClient();
|
|
247
|
+
|
|
248
|
+
await notte.Session().use(async (session) => {
|
|
249
|
+
await session.execute(actions.goto({ url: 'https://www.notte.cc' }));
|
|
250
|
+
|
|
251
|
+
const observation = await session.observe({ perception_type: 'deep' });
|
|
252
|
+
console.log(observation.space);
|
|
253
|
+
|
|
254
|
+
// Plain objects work too; the `type` field is a discriminated union
|
|
255
|
+
await session.execute({ type: 'click', id: 'B1' });
|
|
256
|
+
await session.execute(actions.fill({ selector: 'internal:text="Email"', value: 'me@example.com' }));
|
|
257
|
+
|
|
258
|
+
// A failed action throws ActionExecutionError with the server-side error type
|
|
259
|
+
try {
|
|
260
|
+
await session.execute(actions.click({ id: 'B999' }));
|
|
261
|
+
} catch (error) {
|
|
262
|
+
if (error instanceof ActionExecutionError) console.log(error.errorType, error.userMessage);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// Or inspect the result yourself
|
|
266
|
+
const result = await session.execute(actions.click({ id: 'B999' }), { raiseOnFailure: false });
|
|
267
|
+
console.log(result.success, result.message);
|
|
268
|
+
|
|
269
|
+
// Run JavaScript in the page and fetch through the page (cookies, proxy, fingerprint).
|
|
270
|
+
// Relative URLs resolve against the page; plaintext http targets are refused unless allowInsecure is set.
|
|
271
|
+
const title = await session.evaluateJs('document.title');
|
|
272
|
+
const summary = await session.fetch('/api/rest_v1/page/summary/Main_Page').then(r => r.json());
|
|
273
|
+
|
|
274
|
+
// Scrape the current page
|
|
275
|
+
const markdown = await session.scrape({ only_main_content: true });
|
|
276
|
+
|
|
277
|
+
// Cookies
|
|
278
|
+
const cookies = await session.getCookies();
|
|
279
|
+
await session.setCookies(cookies);
|
|
280
|
+
});
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
#### Playwright access
|
|
284
|
+
|
|
285
|
+
`playwright-core` is an optional peer dependency (`npm install playwright-core`),
|
|
286
|
+
the counterpart of `pip install notte-sdk[playwright]`:
|
|
287
|
+
|
|
288
|
+
```typescript
|
|
289
|
+
await notte.Session().use(async (session) => {
|
|
290
|
+
const page = await session.page(); // connected over CDP, cached
|
|
291
|
+
await page.goto('https://www.notte.cc');
|
|
292
|
+
await page.screenshot({ path: 'screenshot.png' });
|
|
293
|
+
|
|
294
|
+
// Or connect your own tooling
|
|
295
|
+
const cdpUrl = await session.cdpUrl();
|
|
296
|
+
});
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
#### Replays and cookie files
|
|
300
|
+
|
|
301
|
+
```typescript
|
|
302
|
+
// Persist login state between runs: loaded on start, appended on stop
|
|
303
|
+
const session = notte.Session({ cookie_file: './cookies.json' });
|
|
304
|
+
|
|
305
|
+
await session.use(async () => { /* ... */ });
|
|
306
|
+
|
|
307
|
+
// Replays are generated after stop(); replay() polls until ready (240 s by default)
|
|
308
|
+
const replay = await session.replay();
|
|
309
|
+
await session.downloadReplay('./session.mp4');
|
|
310
|
+
```
|
|
311
|
+
|
|
131
312
|
#### Session Methods
|
|
132
313
|
|
|
133
|
-
- `start()` - Start the session
|
|
134
|
-
- `stop()` - Stop the session
|
|
314
|
+
- `start()` - Start the session (retries 5xx errors 3 times, waits 30 s on cluster overload)
|
|
315
|
+
- `stop(closeReason?)` - Stop the session
|
|
135
316
|
- `status()` - Get session status
|
|
136
|
-
- `viewer()` - Open the live session viewer in the local default browser
|
|
137
317
|
- `use(callback)` - Context manager pattern
|
|
138
318
|
- `getId()` - Get session ID
|
|
139
319
|
- `isSessionActive()` - Check if session is running
|
|
320
|
+
- `execute(action, options?)` - Execute a typed action; throws `ActionExecutionError` on failure unless `raiseOnFailure: false`
|
|
321
|
+
- `observe(options?)` - Observe the page (`perception_type`, `min_nb_actions`, `max_nb_actions`)
|
|
322
|
+
- `scrape(options?)` - Scrape the page as markdown, images, or structured data (see [Scraping](#scraping))
|
|
323
|
+
- `evaluateJs(code, options?)` - Evaluate JavaScript and return the stringified result
|
|
324
|
+
- `fetch(url, options?)` - Issue an HTTP request from inside the page
|
|
325
|
+
- `setCookies(cookies)` / `setCookiesFromFile(path)` / `getCookies()` - Manage cookies
|
|
326
|
+
- `cdpUrl()` - Chrome DevTools Protocol websocket URL
|
|
327
|
+
- `page()` - Playwright `Page` connected over CDP (requires `playwright-core`)
|
|
328
|
+
- `debugInfo()` / `debugTabInfo(tabIdx?)` - Debug URLs and tab metadata
|
|
329
|
+
- `replay(options?)` / `downloadReplay(path?)` - Session recording
|
|
330
|
+
- `getScript(options?)` - Python code reproducing the session
|
|
331
|
+
- `viewer()` - Open the live session viewer in the local default browser
|
|
332
|
+
- `storage` - The `RemoteFileStorage` attached with the `storage` option
|
|
333
|
+
- `client.sessions.list(options?)` - List sessions
|
|
140
334
|
|
|
141
335
|
### Agent
|
|
142
336
|
|
|
@@ -153,25 +347,25 @@ await notte.Session().use(async (session) => {
|
|
|
153
347
|
max_steps: 10
|
|
154
348
|
});
|
|
155
349
|
|
|
156
|
-
// Non-blocking: start agent and get ID
|
|
157
|
-
|
|
158
|
-
console.log('Agent started:', agentId);
|
|
350
|
+
// Non-blocking: start agent and get its ID
|
|
351
|
+
await agent.start({ task: "Navigate to Google and search for 'TypeScript'" });
|
|
352
|
+
console.log('Agent started:', agent.agentId);
|
|
159
353
|
|
|
160
354
|
// Check agent status
|
|
161
355
|
const status = await agent.status();
|
|
162
356
|
console.log('Agent status:', status);
|
|
163
357
|
|
|
164
358
|
// Blocking: run agent and wait for completion with live updates
|
|
165
|
-
const response = await agent.run(
|
|
166
|
-
"Find the latest TypeScript documentation",
|
|
167
|
-
(update) => {
|
|
359
|
+
const response = await agent.run({
|
|
360
|
+
task: "Find the latest TypeScript documentation",
|
|
361
|
+
updateHandler: (update) => {
|
|
168
362
|
if (update.type === 'step') {
|
|
169
363
|
console.log(`Step update:`, update.data);
|
|
170
364
|
} else if (update.type === 'completion') {
|
|
171
365
|
console.log(`Completed:`, update.data);
|
|
172
366
|
}
|
|
173
367
|
}
|
|
174
|
-
);
|
|
368
|
+
});
|
|
175
369
|
|
|
176
370
|
console.log('Final result:', response);
|
|
177
371
|
});
|
|
@@ -179,12 +373,15 @@ await notte.Session().use(async (session) => {
|
|
|
179
373
|
|
|
180
374
|
#### Agent Methods
|
|
181
375
|
|
|
182
|
-
- `start(
|
|
183
|
-
- `run(
|
|
376
|
+
- `start(request)` - Start agent with `{ task, url?, ... }` (non-blocking)
|
|
377
|
+
- `run(request)` - Start agent and wait for completion (blocking); pass `updateHandler` for live updates
|
|
184
378
|
- `status()` - Get agent status
|
|
185
379
|
- `stop()` - Stop the agent
|
|
186
|
-
- `
|
|
187
|
-
- `
|
|
380
|
+
- `agentId` - The agent ID (read-only property, available after `start()` / `run()`)
|
|
381
|
+
- `sessionId` - The session ID the agent runs in (read-only property)
|
|
382
|
+
- `hasStarted()` - Whether `start()`/`run()` was called on this instance (local check)
|
|
383
|
+
- `isActive()` - Whether the agent is still active on the server (fetches the status)
|
|
384
|
+
- `isRunning()` - Deprecated alias of `hasStarted()`; it does not contact the API
|
|
188
385
|
|
|
189
386
|
#### Structured answers with Zod
|
|
190
387
|
|
|
@@ -231,15 +428,6 @@ await vault.addCredentials('https://github.com/', {
|
|
|
231
428
|
const strongPassword = vault.generatePassword(20, true); // 20 chars with special chars
|
|
232
429
|
const simplePassword = vault.generatePassword(12, false); // 12 chars, no special chars
|
|
233
430
|
|
|
234
|
-
// Add credit card information
|
|
235
|
-
await vault.setCreditCard({
|
|
236
|
-
card_holder_name: 'John Doe',
|
|
237
|
-
card_number: '4111111111111111',
|
|
238
|
-
card_cvv: '123',
|
|
239
|
-
expiry_month: '12',
|
|
240
|
-
expiry_year: '2025'
|
|
241
|
-
});
|
|
242
|
-
|
|
243
431
|
// Use with agents for automatic credential management
|
|
244
432
|
await notte.Session().use(async (session) => {
|
|
245
433
|
const agent = notte.Agent({
|
|
@@ -259,22 +447,21 @@ const credentials = await existingVault.listCredentials();
|
|
|
259
447
|
|
|
260
448
|
// Cleanup
|
|
261
449
|
await vault.deleteCredentials('https://github.com/');
|
|
262
|
-
await vault.deleteCreditCard();
|
|
263
450
|
await vault.stop(); // Deletes entire vault
|
|
264
451
|
```
|
|
265
452
|
|
|
266
453
|
#### Vault Methods
|
|
267
454
|
|
|
268
|
-
- `addCredentials(url, credentials)` - Store credentials for a URL
|
|
269
|
-
- `
|
|
455
|
+
- `addCredentials(url, credentials)` - Store credentials for a URL (validated client-side like Python: root domain, exactly one of `email`/`username`, base32 `mfa_secret`)
|
|
456
|
+
- `addCredentialsFromEnv(url)` - Read `{DOMAIN}_EMAIL` / `{DOMAIN}_USERNAME` / `{DOMAIN}_PASSWORD` / `{DOMAIN}_MFA_SECRET` from the environment
|
|
457
|
+
- `getCredentials(url)` - Retrieve credentials for a URL; throws `NotteAPIError` when none exist
|
|
458
|
+
- `hasCredential(url)` - Whether credentials exist for a URL
|
|
270
459
|
- `deleteCredentials(url)` - Delete credentials for a URL
|
|
271
460
|
- `listCredentials()` - List all stored credentials
|
|
272
|
-
- `setCreditCard(card)` - Store credit card information
|
|
273
|
-
- `getCreditCard()` - Retrieve credit card information
|
|
274
|
-
- `deleteCreditCard()` - Delete credit card information
|
|
275
461
|
- `generatePassword(length?, includeSpecialChars?)` - Generate secure passwords
|
|
276
462
|
- `delete()` - Delete the entire vault
|
|
277
463
|
- `stop()` - Stop and delete the vault
|
|
464
|
+
- `client.vaults.list(options?)` - List vaults
|
|
278
465
|
|
|
279
466
|
#### Security Features
|
|
280
467
|
|
|
@@ -292,15 +479,12 @@ import { NotteClient } from 'notte-sdk';
|
|
|
292
479
|
|
|
293
480
|
const notte = new NotteClient();
|
|
294
481
|
|
|
295
|
-
// Create a new persona with vault
|
|
296
|
-
const persona = notte.Persona({
|
|
297
|
-
create_vault: true,
|
|
298
|
-
create_phone_number: true
|
|
299
|
-
});
|
|
482
|
+
// Create a new persona with a vault
|
|
483
|
+
const persona = notte.Persona({ create_vault: true });
|
|
300
484
|
|
|
301
|
-
// Get persona information
|
|
302
|
-
|
|
303
|
-
console.log(`
|
|
485
|
+
// Get persona information (the first call initializes the persona)
|
|
486
|
+
const info = await persona.get();
|
|
487
|
+
console.log(`Email: ${info.email}`);
|
|
304
488
|
|
|
305
489
|
// Read emails sent to the persona
|
|
306
490
|
const emails = await persona.emails({
|
|
@@ -323,9 +507,9 @@ await notte.Session().use(async (session) => {
|
|
|
323
507
|
vault_id: persona.vault.vaultId // Agent will use persona's vault
|
|
324
508
|
});
|
|
325
509
|
|
|
326
|
-
const result = await agent.run(
|
|
327
|
-
`Create an account on GitHub using the persona credentials`
|
|
328
|
-
);
|
|
510
|
+
const result = await agent.run({
|
|
511
|
+
task: `Create an account on GitHub using the persona credentials`
|
|
512
|
+
});
|
|
329
513
|
console.log(`Account created: ${result.success}`);
|
|
330
514
|
});
|
|
331
515
|
|
|
@@ -345,10 +529,9 @@ await persona.stop(); // Deletes persona and all associated data
|
|
|
345
529
|
|
|
346
530
|
#### Persona Methods
|
|
347
531
|
|
|
532
|
+
- `get()` - Fetch (and initialize) the persona information
|
|
348
533
|
- `emails(options?)` - Read emails sent to the persona
|
|
349
534
|
- `sms(options?)` - Read SMS messages sent to the persona
|
|
350
|
-
- `createNumber(options?)` - Create a phone number for the persona
|
|
351
|
-
- `deleteNumber()` - Delete the persona's phone number
|
|
352
535
|
- `addCredentials(url)` - Add auto-generated credentials to the persona's vault
|
|
353
536
|
- `delete()` - Delete the persona
|
|
354
537
|
- `stop()` - Stop and delete the persona
|
|
@@ -368,7 +551,7 @@ const sms = await persona.sms(options);
|
|
|
368
551
|
|
|
369
552
|
#### Persona Features
|
|
370
553
|
|
|
371
|
-
- **Complete Digital Identity** - Unique email address
|
|
554
|
+
- **Complete Digital Identity** - Unique email address
|
|
372
555
|
- **2FA Support** - Receive and read SMS verification codes automatically
|
|
373
556
|
- **Automated Account Creation** - Seamless integration with agents for signup flows
|
|
374
557
|
- **Vault Integration** - Optional secure credential storage
|
|
@@ -390,16 +573,17 @@ const fn = notte.NotteFunction({
|
|
|
390
573
|
decryption_key: 'optional-decryption-key' // optional, for encrypted outputs
|
|
391
574
|
});
|
|
392
575
|
|
|
393
|
-
//
|
|
576
|
+
// Stream logs to console.log and wait for the final result (default)
|
|
394
577
|
const result = await fn.run({
|
|
395
578
|
url: 'https://example.com',
|
|
396
579
|
query: 'extract pricing information'
|
|
397
580
|
});
|
|
398
581
|
|
|
399
582
|
console.log('Run ID:', result.function_run_id);
|
|
583
|
+
console.log('Result:', result.result);
|
|
400
584
|
|
|
401
585
|
// Retrieve the run result / metadata later
|
|
402
|
-
const metadata = await fn.
|
|
586
|
+
const metadata = await fn.getRun(result.function_run_id);
|
|
403
587
|
console.log('Status:', metadata.status); // 'active' | 'closed' | 'failed'
|
|
404
588
|
console.log('Result:', metadata);
|
|
405
589
|
```
|
|
@@ -424,28 +608,60 @@ fail explicitly if that runtime is unavailable or at capacity; they do not fall
|
|
|
424
608
|
back to Lambda. Browser sessions keep their own duration limits. Existing
|
|
425
609
|
schedules continue to use the standard runtime during the pilot.
|
|
426
610
|
|
|
427
|
-
####
|
|
611
|
+
#### Create a run before execution
|
|
428
612
|
|
|
429
|
-
|
|
613
|
+
`createRun()` is optional: use it when you need a run ID before execution starts.
|
|
614
|
+
It only creates the cloud run record. Pass the returned ID as `functionRunId` to
|
|
615
|
+
execute that record; omitting `functionRunId` makes `run()` create a new run.
|
|
430
616
|
|
|
431
617
|
```typescript
|
|
432
618
|
const fn = notte.NotteFunction({ function_id: 'your-function-id' });
|
|
433
|
-
const { function_run_id } = await fn.
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
619
|
+
const { function_run_id } = await fn.createRun();
|
|
620
|
+
console.log('Run ID before execution:', function_run_id);
|
|
621
|
+
|
|
622
|
+
const pending = fn.run(
|
|
623
|
+
{ url: 'https://example.com' },
|
|
624
|
+
{ functionRunId: function_run_id },
|
|
625
|
+
);
|
|
626
|
+
|
|
627
|
+
// Do other work here, then wait for completion.
|
|
628
|
+
const result = await pending;
|
|
629
|
+
console.log(result.result);
|
|
630
|
+
|
|
631
|
+
const metadata = await fn.getRun(function_run_id);
|
|
632
|
+
console.log(metadata.status);
|
|
447
633
|
```
|
|
448
634
|
|
|
635
|
+
`getRun()` fetches the current status and stored result without waiting for execution
|
|
636
|
+
to finish. `retrieve()` remains a compatible alias. Execution results contain the
|
|
637
|
+
function's structured output; the stored `metadata.result` is serialized JSON.
|
|
638
|
+
|
|
639
|
+
Keeping the promise lets your JavaScript continue while the HTTP request remains
|
|
640
|
+
open. Keep the process running until it completes. This is not a detached job.
|
|
641
|
+
With `{ stream: false }`, the SDK returns JSON without live logs, but standard
|
|
642
|
+
execution still waits for completion.
|
|
643
|
+
|
|
644
|
+
#### Streaming options and migration
|
|
645
|
+
|
|
646
|
+
**Breaking change:** `run()` now defaults to `stream: true`, matching the Python SDK.
|
|
647
|
+
It consumes the event stream, prints logs as they arrive, and resolves with the
|
|
648
|
+
final response, including `status` and `result`. Existing callers that require a
|
|
649
|
+
JSON response without live logs must add `{ stream: false }` as the second argument.
|
|
650
|
+
|
|
651
|
+
Failed executions throw by default. Set `raiseOnFailure: false` to inspect the
|
|
652
|
+
failed response yourself. Transport and malformed-stream errors still throw.
|
|
653
|
+
Use `onLog` to route logs to your application (or `onLog: () => {}` to silence them):
|
|
654
|
+
|
|
655
|
+
```typescript
|
|
656
|
+
const result = await fn.run({ url: 'https://example.com' }, {
|
|
657
|
+
onLog: message => console.log('[function]', message),
|
|
658
|
+
raiseOnFailure: false,
|
|
659
|
+
});
|
|
660
|
+
```
|
|
661
|
+
|
|
662
|
+
Options belong in the second argument; a `stream` field in the first argument
|
|
663
|
+
is a script input and does not change streaming behavior.
|
|
664
|
+
|
|
449
665
|
#### Downloading the function code
|
|
450
666
|
|
|
451
667
|
```typescript
|
|
@@ -472,24 +688,153 @@ const fn = notte.NotteFunction({
|
|
|
472
688
|
const code = await fn.download();
|
|
473
689
|
```
|
|
474
690
|
|
|
691
|
+
#### Creating and managing functions
|
|
692
|
+
|
|
693
|
+
Upload a Python script to create a function, like `NotteFunction(path=...)` in Python.
|
|
694
|
+
Creation is lazy: the upload happens on the first call that needs the function id.
|
|
695
|
+
|
|
696
|
+
```typescript
|
|
697
|
+
const fn = notte.NotteFunction({ path: './my_function.py', name: 'price-monitor', description: 'Checks prices' });
|
|
698
|
+
|
|
699
|
+
const details = await fn.get(); // metadata, versions and download link
|
|
700
|
+
await fn.update({ path: './my_function_v2.py' }); // upload a new version
|
|
701
|
+
await fn.updateMetadata({ name: 'price-monitor-v2' });
|
|
702
|
+
await fn.rollback({ version: details.latest_version });
|
|
703
|
+
|
|
704
|
+
await fn.setSchedule({ cron: '0 9 * * *', variables: { url: 'https://example.com' } });
|
|
705
|
+
await fn.deleteSchedule();
|
|
706
|
+
|
|
707
|
+
const runs = await fn.runs(); // all runs, including completed ones
|
|
708
|
+
const functions = await notte.functions.list();
|
|
709
|
+
|
|
710
|
+
await fn.delete();
|
|
711
|
+
```
|
|
712
|
+
|
|
713
|
+
`run()` waits at most 300 s by default; pass `timeoutMs` to change it. A failed
|
|
714
|
+
run throws `FailedToRunCloudFunctionError` unless `raiseOnFailure: false`.
|
|
715
|
+
|
|
475
716
|
#### Function Methods
|
|
476
717
|
|
|
477
|
-
- `run(variables?)` -
|
|
478
|
-
- `
|
|
718
|
+
- `run(variables?, options?)` - Stream logs and wait for completion; use `stream: false` for the backend's JSON response without live logs. Options: `runtime`, `functionRunId`, `onLog`, `raiseOnFailure`, `timeoutMs`
|
|
719
|
+
- `get(options?)` - Function metadata, versions and download link
|
|
720
|
+
- `update(options)` / `updateMetadata(body)` - Upload a new version / change name, description
|
|
721
|
+
- `delete()` - Delete the function
|
|
722
|
+
- `setSchedule(body)` / `deleteSchedule()` - Manage the cron schedule
|
|
723
|
+
- `rollback(options)` - Roll back to a previous version
|
|
724
|
+
- `runs(options?)` - List runs (all runs by default, `only_active: true` for active ones)
|
|
725
|
+
- `createRun()` - Create a cloud run record without executing it
|
|
726
|
+
- `getRun(functionRunId)` - Get current metadata/result for a specific run
|
|
727
|
+
- `retrieve(functionRunId)` - Compatibility alias for `getRun()`
|
|
479
728
|
- `download(options?)` - Download the function code, optionally writing it to `options.path`
|
|
480
729
|
- `getUrl(options?)` - Get the (decrypted) download url of the function code
|
|
481
730
|
- `getFunctionId()` - Get the function ID
|
|
482
731
|
- `functionId` - The function ID (read-only property)
|
|
483
732
|
- `decryptionKey` - The decryption key, if provided (read-only property)
|
|
484
733
|
|
|
734
|
+
### File Storage
|
|
735
|
+
|
|
736
|
+
Upload files for a session to use and download files the session produced,
|
|
737
|
+
the counterpart of `client.FileStorage()` in Python.
|
|
738
|
+
|
|
739
|
+
```typescript
|
|
740
|
+
import { NotteClient, FileExistsError } from 'notte-sdk';
|
|
741
|
+
|
|
742
|
+
const notte = new NotteClient();
|
|
743
|
+
const storage = notte.FileStorage();
|
|
744
|
+
let sessionId = '';
|
|
745
|
+
let fileId = '';
|
|
746
|
+
|
|
747
|
+
await notte.Session({ storage }).use(async (session) => {
|
|
748
|
+
sessionId = session.getId()!;
|
|
749
|
+
|
|
750
|
+
// Upload from a path, a Blob or a Uint8Array
|
|
751
|
+
const uploaded = await storage.upload('./invoice.pdf');
|
|
752
|
+
fileId = uploaded.id;
|
|
753
|
+
|
|
754
|
+
// ... let the session / an agent download something ...
|
|
755
|
+
|
|
756
|
+
const downloads = await storage.list({ source: 'session_download' });
|
|
757
|
+
for (const file of downloads.files) {
|
|
758
|
+
const path = await storage.download(file.id, './downloads');
|
|
759
|
+
console.log('saved', path);
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
const info = await storage.metadata(uploaded.id);
|
|
763
|
+
await storage.delete(uploaded.id);
|
|
764
|
+
});
|
|
765
|
+
|
|
766
|
+
// Files of a closed session
|
|
767
|
+
const files = notte.FileStorage(sessionId);
|
|
768
|
+
await files.download(fileId, './downloads', { force: true }); // overwrite instead of FileExistsError
|
|
769
|
+
```
|
|
770
|
+
|
|
771
|
+
`notte.Files(sessionId)` exposes the same operations returning `Blob`s instead of writing to disk.
|
|
772
|
+
|
|
773
|
+
### Web Search
|
|
774
|
+
|
|
775
|
+
Search the public web with `POST /search`. The default `outputType` returns
|
|
776
|
+
ranked results; `sourcedAnswer` returns a written answer with its sources.
|
|
777
|
+
|
|
778
|
+
```typescript
|
|
779
|
+
const { results } = await notte.search('notte browser automation', { depth: 'fast' });
|
|
780
|
+
results.forEach(item => console.log(item.name, item.url));
|
|
781
|
+
|
|
782
|
+
const { answer, sources } = await notte.search('what is notte?', { outputType: 'sourcedAnswer' });
|
|
783
|
+
console.log(answer, sources.map(s => s.url));
|
|
784
|
+
```
|
|
785
|
+
|
|
786
|
+
Extra fields such as `maxResults` or `includeDomains` are forwarded to the search
|
|
787
|
+
provider. `SearchOptions` and the `SearchResultsResponse` /
|
|
788
|
+
`SearchSourcedAnswerResponse` shapes are exported.
|
|
789
|
+
|
|
790
|
+
### Anything API
|
|
791
|
+
|
|
792
|
+
`notte.anything.start({ task })` (`POST /anything/start`) turns a plain-English
|
|
793
|
+
description of a web task into a deployed, reusable function. Building is slow and
|
|
794
|
+
billable; prefer `notte.functions.list()` when a ready-made function already fits.
|
|
795
|
+
The API response is not typed by the OpenAPI spec and is exposed as an opaque
|
|
796
|
+
`AnythingStartResponse` record (it references the built function, e.g. `function_id`).
|
|
797
|
+
|
|
798
|
+
```typescript
|
|
799
|
+
const started = await notte.anything.start({ task: 'fetch the top 3 hacker news posts' });
|
|
800
|
+
console.log(started);
|
|
801
|
+
```
|
|
802
|
+
|
|
803
|
+
### Secrets
|
|
804
|
+
|
|
805
|
+
Workspace secrets (`/secrets`) are scoped by namespace: `llm_provider` keys are
|
|
806
|
+
used by agents and scraping, `function_env` values are injected into function runs.
|
|
807
|
+
Listing never returns values, only metadata with a `key_hint`.
|
|
808
|
+
|
|
809
|
+
```typescript
|
|
810
|
+
const meta = await notte.secrets.store({ namespace: 'function_env', name: 'API_TOKEN', value: 'xyz' });
|
|
811
|
+
const { value } = await notte.secrets.get('API_TOKEN', 'function_env');
|
|
812
|
+
const secrets = await notte.secrets.list({ namespace: 'function_env' });
|
|
813
|
+
await notte.secrets.delete(meta.id);
|
|
814
|
+
```
|
|
815
|
+
|
|
816
|
+
### Usage
|
|
817
|
+
|
|
818
|
+
Read billing usage for the current (or a given) monthly period, and page through
|
|
819
|
+
per-request usage logs.
|
|
820
|
+
|
|
821
|
+
```typescript
|
|
822
|
+
const usage = await notte.usage.get();
|
|
823
|
+
console.log(`${usage.session_count} sessions, $${usage.total_cost} this period`);
|
|
824
|
+
|
|
825
|
+
const page = await notte.usage.logs({ endpoint: 'sessions.start', page: 1, page_size: 50 });
|
|
826
|
+
page.items.forEach(log => console.log(log.created_at, log.endpoint, log.duration_ms));
|
|
827
|
+
```
|
|
828
|
+
|
|
485
829
|
## Advanced Usage
|
|
486
830
|
|
|
487
831
|
### Session Configuration
|
|
488
832
|
|
|
489
833
|
```typescript
|
|
490
834
|
const session = notte.Session({
|
|
491
|
-
|
|
492
|
-
//
|
|
835
|
+
idle_timeout_minutes: 5, // Close the session after this much inactivity
|
|
836
|
+
max_duration_minutes: 45, // Hard limit on the session lifetime
|
|
837
|
+
// Add other session options as supported by the API (SessionOptions)
|
|
493
838
|
});
|
|
494
839
|
```
|
|
495
840
|
|
|
@@ -504,36 +849,79 @@ const agent = notte.Agent({
|
|
|
504
849
|
|
|
505
850
|
### Error Handling
|
|
506
851
|
|
|
852
|
+
Every error thrown by the SDK extends `NotteError`, mirroring `notte_sdk.errors`
|
|
853
|
+
in Python. Generated API calls reject with a `NotteAPIError` carrying the request
|
|
854
|
+
`path`, the HTTP `statusCode` and the parsed response body in `error`; the API can
|
|
855
|
+
flag failures as `NotteAPIExecutionError`. Client-side problems use dedicated
|
|
856
|
+
classes: `AuthenticationError` (missing key), `InvalidRequestError`,
|
|
857
|
+
`NotteTimeoutError` (request or wait deadline exceeded),
|
|
858
|
+
`FailedToRunCloudFunctionError`, `ScrapeFailedError` and `ActionExecutionError`.
|
|
859
|
+
|
|
507
860
|
```typescript
|
|
861
|
+
import { NotteAPIError, NotteError, NotteTimeoutError } from 'notte-sdk';
|
|
862
|
+
|
|
508
863
|
try {
|
|
509
864
|
await notte.Session().use(async (session) => {
|
|
510
865
|
const agent = notte.Agent({ session });
|
|
511
|
-
const response = await agent.run("Complete a complex task");
|
|
866
|
+
const response = await agent.run({ task: "Complete a complex task" });
|
|
512
867
|
|
|
513
868
|
if (!response.success) {
|
|
514
|
-
console.error('Agent failed:', response.
|
|
869
|
+
console.error('Agent failed:', response.answer);
|
|
515
870
|
}
|
|
516
871
|
});
|
|
517
872
|
} catch (error) {
|
|
518
|
-
|
|
873
|
+
if (error instanceof NotteAPIError) {
|
|
874
|
+
console.error(`API ${error.statusCode} on ${error.path}:`, error.apiMessage ?? error.error);
|
|
875
|
+
} else if (error instanceof NotteTimeoutError) {
|
|
876
|
+
console.error('Timed out:', error.message);
|
|
877
|
+
} else if (error instanceof NotteError) {
|
|
878
|
+
console.error('SDK error:', error.message);
|
|
879
|
+
} else {
|
|
880
|
+
throw error;
|
|
881
|
+
}
|
|
519
882
|
}
|
|
520
883
|
```
|
|
521
884
|
|
|
885
|
+
### Timeouts and retries
|
|
886
|
+
|
|
887
|
+
The client applies a per-request timeout (`timeoutMs`, default 60 000 ms; `0`
|
|
888
|
+
disables it) through response-body consumption and rejects with `NotteTimeoutError`
|
|
889
|
+
when it elapses. Explicit streams use the caller's signal for body cancellation;
|
|
890
|
+
function runs supply their own execution deadline. `retry()` wraps an async function so it is re-attempted on failure, like the Python
|
|
891
|
+
`@retry` decorator:
|
|
892
|
+
|
|
893
|
+
```typescript
|
|
894
|
+
import { NotteClient, retry } from 'notte-sdk';
|
|
895
|
+
|
|
896
|
+
const notte = new NotteClient({ timeoutMs: 30_000 });
|
|
897
|
+
|
|
898
|
+
const start = retry(() => notte.Session().start(), {
|
|
899
|
+
maxTries: 3,
|
|
900
|
+
delayMs: 1_000,
|
|
901
|
+
shouldRetry: error => error instanceof NotteTimeoutError,
|
|
902
|
+
});
|
|
903
|
+
await start();
|
|
904
|
+
```
|
|
905
|
+
|
|
522
906
|
### WebSocket Updates
|
|
523
907
|
|
|
524
|
-
The `agent.run()` method provides real-time updates via WebSocket
|
|
908
|
+
The `agent.run()` method provides real-time updates via WebSocket through the
|
|
909
|
+
`updateHandler` option:
|
|
525
910
|
|
|
526
911
|
```typescript
|
|
527
|
-
const response = await agent.run(
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
912
|
+
const response = await agent.run({
|
|
913
|
+
task: "Your task",
|
|
914
|
+
updateHandler: (update) => {
|
|
915
|
+
switch (update.type) {
|
|
916
|
+
case 'step':
|
|
917
|
+
console.log('Step:', update.data);
|
|
918
|
+
break;
|
|
919
|
+
case 'completion':
|
|
920
|
+
console.log('Task completed:', update.data);
|
|
921
|
+
break;
|
|
922
|
+
default:
|
|
923
|
+
console.log('Update:', update);
|
|
924
|
+
}
|
|
537
925
|
}
|
|
538
926
|
});
|
|
539
927
|
```
|
|
@@ -571,7 +959,7 @@ from notte_sdk import NotteClient
|
|
|
571
959
|
notte = NotteClient()
|
|
572
960
|
|
|
573
961
|
# Session context manager
|
|
574
|
-
with notte.Session(
|
|
962
|
+
with notte.Session(idle_timeout_minutes=2) as session:
|
|
575
963
|
status = session.status()
|
|
576
964
|
print(status)
|
|
577
965
|
|
|
@@ -589,7 +977,7 @@ import { NotteClient } from 'notte-sdk';
|
|
|
589
977
|
const notte = new NotteClient();
|
|
590
978
|
|
|
591
979
|
// Session context manager equivalent
|
|
592
|
-
await notte.Session({
|
|
980
|
+
await notte.Session({ idle_timeout_minutes: 2 }).use(async (session) => {
|
|
593
981
|
const status = await session.status();
|
|
594
982
|
console.log(status);
|
|
595
983
|
});
|
|
@@ -597,7 +985,7 @@ await notte.Session({ timeoutMinutes: 2 }).use(async (session) => {
|
|
|
597
985
|
// Agent usage
|
|
598
986
|
await notte.Session().use(async (session) => {
|
|
599
987
|
const agent = notte.Agent({ session, max_steps: 10 });
|
|
600
|
-
const response = await agent.run("Find the best italian restaurant in SF");
|
|
988
|
+
const response = await agent.run({ task: "Find the best italian restaurant in SF" });
|
|
601
989
|
console.log(`Agent completed: ${response.success}, answer: ${response.answer}`);
|
|
602
990
|
});
|
|
603
991
|
```
|
|
@@ -635,7 +1023,7 @@ npm test
|
|
|
635
1023
|
npm run test -- --coverage
|
|
636
1024
|
|
|
637
1025
|
# Run specific test file
|
|
638
|
-
npm run test
|
|
1026
|
+
npm run test test/client.test.ts
|
|
639
1027
|
```
|
|
640
1028
|
|
|
641
1029
|
### Regenerating from API
|
|
@@ -654,15 +1042,15 @@ This will fetch the latest API specification and update the generated client cod
|
|
|
654
1042
|
The SDK is built with full TypeScript support:
|
|
655
1043
|
|
|
656
1044
|
```typescript
|
|
657
|
-
import { NotteClient,
|
|
1045
|
+
import { NotteClient, type SessionResponse, type LegacyAgentStatusResponse } from 'notte-sdk';
|
|
658
1046
|
|
|
659
1047
|
const notte = new NotteClient();
|
|
660
1048
|
|
|
661
1049
|
// All types are properly inferred
|
|
662
1050
|
await notte.Session().use(async (session) => {
|
|
663
|
-
const status:
|
|
1051
|
+
const status: SessionResponse = await session.status();
|
|
664
1052
|
const agent = notte.Agent({ session });
|
|
665
|
-
const response:
|
|
1053
|
+
const response: LegacyAgentStatusResponse = await agent.run({ task: "task" });
|
|
666
1054
|
});
|
|
667
1055
|
```
|
|
668
1056
|
|
|
@@ -670,24 +1058,35 @@ await notte.Session().use(async (session) => {
|
|
|
670
1058
|
|
|
671
1059
|
### Types
|
|
672
1060
|
|
|
673
|
-
The SDK exports all generated types from the OpenAPI specification
|
|
1061
|
+
The SDK exports all generated types from the OpenAPI specification alongside the
|
|
1062
|
+
hand-written option types:
|
|
674
1063
|
|
|
675
1064
|
```typescript
|
|
676
1065
|
import type {
|
|
677
1066
|
NotteClientConfig,
|
|
678
1067
|
SessionOptions,
|
|
679
|
-
|
|
1068
|
+
SessionResponse,
|
|
1069
|
+
SessionListOptions,
|
|
680
1070
|
AgentConstructor,
|
|
681
1071
|
AgentRunRequest,
|
|
682
1072
|
AgentUpdateHandler,
|
|
1073
|
+
AgentListOptions,
|
|
683
1074
|
VaultConstructor,
|
|
684
|
-
|
|
685
|
-
|
|
1075
|
+
VaultListOptions,
|
|
1076
|
+
CredentialsDictInput,
|
|
686
1077
|
Credential,
|
|
687
1078
|
PersonaConstructor,
|
|
688
1079
|
MessageReadOptions,
|
|
689
1080
|
PersonaListOptions,
|
|
690
|
-
|
|
1081
|
+
FunctionConstructor,
|
|
1082
|
+
FunctionListOptions,
|
|
1083
|
+
RetryOptions,
|
|
1084
|
+
NotteAPIErrorBody,
|
|
1085
|
+
SearchOptions,
|
|
1086
|
+
SearchResultsResponse,
|
|
1087
|
+
AnythingStartResponse,
|
|
1088
|
+
SecretMetadata,
|
|
1089
|
+
UsageResponse,
|
|
691
1090
|
} from 'notte-sdk';
|
|
692
1091
|
```
|
|
693
1092
|
|
|
@@ -698,6 +1097,6 @@ MIT
|
|
|
698
1097
|
## Support
|
|
699
1098
|
|
|
700
1099
|
For issues and questions:
|
|
701
|
-
- GitHub Issues: [Report issues](https://github.com/notte/
|
|
1100
|
+
- GitHub Issues: [Report issues](https://github.com/nottelabs/notte/issues)
|
|
702
1101
|
- Documentation: [docs.notte.cc](https://docs.notte.cc)
|
|
703
1102
|
- Python SDK: [notte-sdk](https://pypi.org/project/notte-sdk/)
|