@relevanceai/sdk 3.0.0 → 3.1.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/README.md CHANGED
@@ -1,691 +1,91 @@
1
1
  # Relevance AI JavaScript SDK
2
2
 
3
- A comprehensive JavaScript/TypeScript SDK for building AI-powered applications
4
- with Relevance AI's workforce platform. Build, deploy, and scale AI workforces
5
- across any JavaScript runtime.
3
+ The official JavaScript/TypeScript SDK for building applications
4
+ with Relevance AI agents and workforces.
6
5
 
7
- ## Description
8
-
9
- The Relevance AI JavaScript SDK provides a unified interface for integrating
10
- AI workforces and agents into your applications. Whether you're building
11
- server-side applications, browser-based interfaces, or edge computing solutions,
12
- this SDK delivers consistent, type-safe access to Relevance AI's powerful agent
13
- ecosystem.
14
-
15
- ### Key Features
16
-
17
- - **Universal Compatibility**: Works seamlessly across Node.js, Deno, Bun,
18
- Cloudflare Workers, and browsers
19
- - **Event-Driven Architecture**: Real-time updates via native EventTarget API
20
- - **Type Safety**: Full TypeScript support with comprehensive type definitions
21
- - **Zero Dependencies**: Built on web standards for minimal footprint
22
-
23
- ## Quick Start
24
-
25
- Get up and running in seconds:
26
-
27
- ```typescript
28
- import { Agent, createClient, EU_REGION } from "@relevanceai/sdk";
29
-
30
- // Initialize client with your credentials
31
- const client = createClient({
32
- apiKey: process.env.RELEVANCE_API_KEY,
33
- region: EU_REGION,
34
- project: process.env.PROJECT_ID,
35
- });
36
-
37
- // Load an agent
38
- const agent = await Agent.get("agent-id");
39
- // Start a conversation
40
- const task = await agent.sendMessage("Hello, how can you help me today?");
41
- // Listen for agent responses
42
- task.addEventListener("message", ({ detail: { message } }) => {
43
- if (message.isAgent()) {
44
- console.log("Agent:", message.text);
45
- }
46
- });
47
-
48
- // Or use a workforce of agents
49
-
50
- import { Workforce } from "@relevanceai/sdk";
51
-
52
- // Load the workforce
53
- const workforce = await Workforce.get("workforce-id");
54
- // Start delegating
55
- const task = await workforce.sendMessage("Analyze this complex dataset");
56
- ```
6
+ - **Universal runtime support** - Node.js, Deno, Bun, Cloudflare
7
+ Workers, and browsers
8
+ - **Event-driven architecture** - real-time updates via the native
9
+ EventTarget API
10
+ - **Type-safe** - full TypeScript support with comprehensive type
11
+ definitions
12
+ - **Zero dependencies** - built entirely on web standards
57
13
 
58
14
  ## Installation
59
15
 
60
- Choose the installation method for your runtime:
61
-
62
- ### Node.js / Bun
63
-
64
16
  ```bash
65
17
  npm install @relevanceai/sdk@latest
66
- # or
67
- yarn add @relevanceai/sdk@latest
68
- # or
69
- pnpm add @relevanceai/sdk@latest
70
- # or
71
- bun add @relevanceai/sdk@latest
72
18
  ```
73
19
 
74
- ### Deno
75
-
76
- ```bash
77
- deno add jsr:@relevanceai/sdk
78
- ```
79
-
80
- Or import directly:
81
-
82
- ```typescript
83
- import { createClient } from "jsr:@relevanceai/sdk";
84
- ```
85
-
86
- ### Cloudflare Workers
87
-
88
- ```bash
89
- npm install @relevanceai/sdk@latest
90
- ```
91
-
92
- ### Browser (with bundler)
93
-
94
- ```bash
95
- npm install @relevanceai/sdk@latest
96
- ```
97
-
98
- For bundlers that warn about `node:crypto`, create a shim:
99
-
100
- ```javascript
101
- // shims/crypto.js
102
- export default window.crypto;
103
- ```
104
-
105
- Configure your bundler to use the shim:
106
-
107
- - [Vite configuration](https://vite.dev/config/shared-options.html#resolve-alias)
108
- - [Webpack configuration](https://webpack.js.org/configuration/resolve/#resolvealias)
109
- - [Rollup configuration](https://www.npmjs.com/package/@rollup/plugin-alias)
110
-
111
- ### Browser (CDN)
112
-
113
- ```html
114
- <script type="importmap">
115
- {
116
- "imports": {
117
- "@relevanceai/sdk": "https://esm.run/@relevanceai/sdk"
118
- }
119
- }
120
- </script>
121
- <script type="module">
122
- import { createClient } from "@relevanceai/sdk";
123
- // Your code here
124
- </script>
125
- ```
126
-
127
- ## Usage
128
-
129
- ### Authentication
130
-
131
- The SDK supports two authentication methods for different use cases:
132
-
133
- #### API Keys (server-side)
134
-
135
- API keys grant full access to your project. Use these for server applications
136
- and secure environments:
137
-
138
- ```typescript
139
- import { createClient, AU_REGION } from "@relevanceai/sdk";
140
-
141
- const client = createClient({
142
- apiKey: "sk-...",
143
- region: AU_REGION,
144
- project: "project-uuid",
145
- });
146
- ```
20
+ For Deno, Bun, CDN, and browser bundler setup, see the
21
+ [Setup guide](./docs/00_SETUP.md).
147
22
 
148
- You can also create a Key instance explicitly:
149
-
150
- ```typescript
151
- import { Client, Key, AU_REGION } from "@relevanceai/sdk";
152
-
153
- const key = new Key({
154
- key: "sk-...",
155
- region: AU_REGION,
156
- project: "project-uuid",
157
- });
158
-
159
- const client = new Client(key);
160
- ```
161
-
162
- #### Embed Keys (client-side)
163
-
164
- For public-facing applications, use embed keys which are scoped to a specific
165
- public agent. Embed keys need to be generated and should be stored in your
166
- applications local storage or database. Each embed key corresponds to a single
167
- agent or workforce.
23
+ ## Quick Start
168
24
 
169
25
  ```typescript
170
- import { Key, createClient, US_REGION } from "@relevanceai/sdk";
26
+ import { Agent, createClient, REGION_US } from "@relevanceai/sdk";
171
27
 
172
- const embedKey = await Key.generateEmbedKey({
173
- region: US_REGION,
174
- project: "project-uuid",
175
- agentId: "public-agent-id", // Must be a public agent
28
+ createClient({
29
+ apiKey: process.env.RELEVANCE_API_KEY,
30
+ region: REGION_US,
31
+ project: process.env.PROJECT_ID,
176
32
  });
177
33
 
178
- const client = createClient(embedKey);
179
- ```
180
-
181
- ### Agents
182
-
183
- #### Loading agents
184
-
185
- ```typescript
186
- // fetch all agents (with pagination)
187
- const agents = await Agent.getAll({ pageSize: 20, page: 1 });
188
-
189
- // fetch all agents with custom page size
190
- const agents = await Agent.getAll({ pageSize: 50, page: 3 });
191
-
192
- // fetch all agents using default options (pageSize: 20, page: 1)
193
- const agents = await Agent.getAll();
194
-
195
- // using the default client
196
34
  const agent = await Agent.get("agent-id");
35
+ const task = await agent.sendMessage("Hello!");
197
36
 
198
- // or using a specific client
199
- const agent = await Agent.get("agent-id", client);
200
-
201
- // accessing agent properties
202
- console.log(agent.name);
203
- console.log(agent.avatar);
204
- console.log(agent.description);
205
- ```
206
-
207
- #### Sending messages
208
-
209
- Use `Agent#sendMessage()` to send messages to an agent.
210
-
211
- ```typescript
212
- // create a new task
213
- const task = await agent.sendMessage("What's the weather like today?");
214
-
215
- // reply to existing tasks
216
- await agent.sendMessage("What about tomorrow?", task);
217
-
218
- // sending attachments
219
- const contents = await Deno.readFile("./contract.pdf");
220
- const contract = new File([contents], "contract.pdf", {
221
- type: "application/pdf",
222
- });
223
- await agent.sendMessage("Summarize this contract", [contract]);
224
- ```
225
-
226
- Note: `Agent#sendMessage()` returns once the message is sent and doesn't wait for
227
- a response. See Tasks for handling message events.
228
-
229
- #### Retrieving tasks
230
-
231
- Fetch and filter tasks for an agent:
232
-
233
- ```typescript
234
- // specific task
235
- const task = await agent.getTask("<task-id>");
236
-
237
- // pagination
238
- const tasks = await agent.getTasks({
239
- pageSize: 10,
240
- page: 1,
241
- sort: { updatedAt: "desc" },
242
- });
243
-
244
- // filtering
245
- const activeTasks = await agent.getTasks({
246
- filter: { status: ["queued", "running", "idle"] },
247
- });
248
-
249
- // searching
250
- const searchResults = await agent.getTasks({
251
- search: "weather",
252
- sort: { createdAt: "asc" },
253
- });
254
- ```
255
-
256
- ### Workforces
257
-
258
- #### Loading workforces
259
-
260
- ```typescript
261
- // using the default client
262
- const workforce = await Workforce.get("<workforce-id>");
263
-
264
- // or with a specific client
265
- const workforce = await Workforce.get("<workforce-id>", client);
266
-
267
- // accessing workforce properties
268
- console.log(workforce.name);
269
- ```
270
-
271
- #### Sending messages
272
-
273
- Use `Workforce#sendMessage()` to send messages to a workforce.
274
-
275
- ```typescript
276
- // create a new task
277
- const task = await agent.sendMessage("What's the weather like today?");
278
-
279
- // reply to existing tasks
280
- await agent.sendMessage("What about tomorrow?", task);
281
- ```
282
-
283
- Note: `Workforce#sendMessage()` returns once the message is sent and doesn't
284
- wait for a response. See Tasks for handling message events.
285
-
286
- #### Retrieving tasks
287
-
288
- Load existing workforce tasks.
289
-
290
- ```typescript
291
- const task = await workforce.getTask("<task-id>");
292
- ```
293
-
294
- ### Tasks
295
-
296
- Agents and workforces, subjects, all return an instance of a `Task` when sending
297
- messages. Tasks dispatch events as they would occur on the the subjects timeline
298
- in the Relevance AI workforce platform.
299
-
300
- #### Available Events
301
-
302
- - **`update`**: Whenever a subject has been update.
303
- - **`message`**: Unified event for all message types
304
- - **`error`**: Error notifications
305
-
306
- #### Listening for Events
307
-
308
- ```typescript
309
- // Listen for all messages (agent, user, and tool)
310
37
  task.addEventListener("message", ({ detail: { message } }) => {
311
- // use message helpers to determine the message
312
38
  if (message.isAgent()) {
313
39
  console.log("Agent:", message.text);
314
- } else if (message.isUser()) {
315
- console.log("User:", message.text);
316
- } else if (message.isTool()) {
317
- console.log("Tool:", message.status);
318
40
  }
319
41
  });
320
-
321
- // catching errors
322
- task.addEventListener("error", ({ detail: { message } }) => {
323
- console.error("Task error:", message.lastError);
324
- });
325
- ```
326
-
327
- #### Unsubscribing
328
-
329
- It's important that you unsubscribe from tasks once they have moved out of
330
- scope in your application. This will prevent memory leaks by removing dead
331
- subscriptions.
332
-
333
- ```typescript
334
- task.unsubscribe();
335
- ```
336
-
337
- ### Advanced Usage
338
-
339
- #### Default Client Pattern
340
-
341
- Use a singleton client throughout your application:
342
-
343
- ```typescript
344
- // Initialize once at startup
345
- createClient({ apiKey, region, project });
346
-
347
- // Access anywhere in your app
348
- import { Client } from "@relevanceai/sdk";
349
-
350
- const client = Client.default();
351
42
  ```
352
43
 
353
- #### Multiple Clients
354
-
355
- Manage multiple projects or authentication scopes:
356
-
357
- ```typescript
358
- import { Client, Key, EU_REGION } from "@relevanceai/sdk";
359
-
360
- const projectOneKey = new Key({
361
- key: "sk-project1",
362
- region: EU_REGION,
363
- project: "project-1-id",
364
- });
365
-
366
- const projectTwoKey = new Key({
367
- key: "sk-project2",
368
- region: EU_REGION,
369
- project: "project-2-id",
370
- });
371
-
372
- const clientOne = new Client(projectOneKey);
373
- const clientTwo = new Client(projectTwoKey);
44
+ ## Documentation
374
45
 
375
- // Use different clients for different agents
376
- const agentOne = await Agent.get("agent-1", clientOne);
377
- const agentTwo = await Agent.get("agent-2", clientTwo);
378
- ```
46
+ | Guide | Description |
47
+ | ----- | ----------- |
48
+ | [Setup](./docs/00_SETUP.md) | Installation and runtime configuration |
49
+ | [Authentication](./docs/01_AUTH.md) | API keys, embed keys, and regions |
50
+ | [Client](./docs/02_CLIENT.md) | Client initialization and singleton pattern |
51
+ | [Agents](./docs/03_AGENTS.md) | Loading agents and starting conversations |
52
+ | [Tasks](./docs/04_TASKS.md) | Task lifecycle, events, and subscriptions |
53
+ | [Messaging](./docs/05_MESSAGING.md) | Messages, attachments, and type guards |
54
+ | [Workforces](./docs/06_WORKFORCES.md) | Multi-agent orchestration |
55
+ | [Streaming](./docs/07_STREAMING.md) | Real-time thinking and typing tokens |
379
56
 
380
57
  ## Examples
381
58
 
382
- For complete working examples, check out the `internal/examples` directory:
383
-
384
- - **Deno Examples** (`internal/examples/deno/`):
385
-
386
- - (Agent) Creating tasks
387
- - (Agent) Getting a task
388
- - (Agent) Getting all agents
389
- - (Agent) Getting all tasks
390
- - (Agent) Getting an agent
391
- - (Workforce) Creating a task
392
-
393
- - **Browser Example** (`internal/examples/browser/`):
394
- - Full chat application with Preact
395
- - Real-time message handling
396
- - UI components for agent interactions
397
-
398
- ## API Reference
399
-
400
- ### Client
401
-
402
- ```typescript
403
- class Client {
404
- constructor(key: Key);
405
-
406
- static default(): Client;
407
-
408
- readonly key: Key;
409
- readonly region: Region;
410
- readonly project: string;
411
-
412
- isEmbedKey(): boolean;
413
-
414
- fetch<T>(endpoint: string, init?: RequestInit): Promise<T>;
415
-
416
- url(path: string): URL;
417
- }
418
-
419
- function createClient(keyOrOptions: Key | CreateClientOptions): Client;
420
-
421
- interface CreateClientOptions {
422
- apiKey: string;
423
- region: Region;
424
- project: string;
425
- }
426
- ```
427
-
428
- ### Key
429
-
430
- ```typescript
431
- class Key {
432
- static async generateEmbedKey(options: GenerateEmbedKeyOptions): Promise<Key>;
433
-
434
- constructor(options: CreateKeyOptions);
435
-
436
- readonly region: Region;
437
- readonly project: string;
438
- readonly agentId?: string;
439
- readonly taskPrefix?: string;
440
-
441
- isEmbed(): boolean;
442
-
443
- fetchHeaders(): HeadersInit;
444
-
445
- toJSON(): CreateKeyOptions;
446
- }
447
-
448
- interface CreateKeyOptions {
449
- key: string;
450
- region: Region;
451
- project: string;
452
- agentId?: string;
453
- taskPrefix?: string;
454
- }
455
-
456
- interface GenerateEmbedKeyOptions {
457
- region: Region;
458
- project: string;
459
- agentId: string;
460
- }
461
- ```
462
-
463
- ### Agent
464
-
465
- ```typescript
466
- class Agent {
467
- static async get(id: string, client?: Client): Promise<Agent>;
468
-
469
- static async getAll(
470
- options?: GetAllOptions,
471
- client?: Client
472
- ): Promise<Agent[]>;
473
-
474
- readonly id: string;
475
- readonly name?: string;
476
- readonly description?: string;
477
- readonly avatar?: string;
478
- readonly createdAt: Date;
479
- readonly updatedAt: Date;
480
- readonly region: Region;
481
- readonly project: string;
482
-
483
- getTask(taskId: string): Promise<Task>;
484
-
485
- getTasks(): Promise<Task[]>;
486
- getTasks(options: GetTaskOptions): Promise<Task[]>;
487
-
488
- sendMessage(message: string): Promise<Task>;
489
- sendMessage(message: string, task: Task): Promise<Task>;
490
- sendMessage(
491
- message: string,
492
- attachments: (File | Attachment)[]
493
- ): Promise<Task>;
494
- sendMessage(
495
- message: string,
496
- attachments: (File | Attachment)[],
497
- task: Task
498
- ): Promise<Task>;
499
- }
500
-
501
- interface Attachment {
502
- fileName: string;
503
- fileUrl: string;
504
- }
505
-
506
- interface GetTaskOptions {
507
- pageSize?: number; // default: 100
508
- page?: number; // default: 1
509
- // default: { createdAt: "asc" }
510
- sort?: { createdAt: "asc" | "desc" } | { updatedAt: "asc" | "desc" };
511
- search?: string;
512
- filter?: {
513
- status?: TaskStatus[];
514
- };
515
- }
516
-
517
- interface GetAllOptions {
518
- pageSize?: number; // default: 20
519
- page?: number; // default: 1
520
- }
521
- ```
522
-
523
- ### Workforce
524
-
525
- ```typescript
526
- class Workforce {
527
- static async get(id: string, client?: Client): Promise<Workforce>;
528
-
529
- readonly id: string;
530
- readonly name: string;
531
- readonly region: Region;
532
- readonly project: string;
533
-
534
- getTask(taskId: string): Promise<Task>;
535
-
536
- sendMessage(message: string): Promise<Task>;
537
- sendMessage(message: string, task: Task): Promise<Task>;
538
- }
539
- ```
540
-
541
- ### Task
542
-
543
- ```typescript
544
- class Task<T extends Agent | Workforce = Agent> extends EventTarget {
545
- readonly id: string;
546
- readonly title: string;
547
- readonly status: TaskStatus;
548
- readonly subject: Agent | Workforce;
549
-
550
- isRunning(): boolean;
551
-
552
- getMessages(): Promise<AnyTaskMessage[]>;
553
- getMessages(options: { from: Date }): Promise<AnyTaskMessage[]>;
554
-
555
- subscribe(): void;
556
-
557
- unsubscribe(): void;
558
-
559
- addEventListener(type: string, listener: EventListener): void;
560
-
561
- removeEventListener(type: string, listener: EventListener): void;
562
- }
563
-
564
- type TaskStatus =
565
- | "not-started"
566
- | "idle"
567
- | "queued"
568
- | "running"
569
- | "action"
570
- | "completed"
571
- | "error";
572
- ```
573
-
574
- ### Messages
575
-
576
- ```typescript
577
- abstract class GenericMessage {
578
- readonly id: string;
579
- readonly type: MessageType;
580
- readonly createdAt: Date;
581
-
582
- isAgent(): boolean; // Check if message is from agent
583
- isUser(): boolean; // Check if message is from user
584
- isTool(): boolean; // Check if message is a tool execution
585
- isAgentError(): boolean; // Check if message is an agent error
586
- }
587
-
588
- class AgentMessage extends GenericMessage {
589
- readonly text: string;
590
- }
591
-
592
- class UserMessage extends GenericMessage {
593
- readonly text: string;
594
- }
595
-
596
- class ToolMessage extends GenericMessage {
597
- readonly status: "cancelled" | "pending" | "running" | "completed" | "failed";
598
- readonly tool?: Tool; // Available when message is from a tool (not subagent)
599
- readonly toolOrAgentId: string; // ID of the tool or subagent
59
+ Working examples are available in `internal/examples/`:
600
60
 
601
- isSubAgent(): boolean; // Check if this is a subagent execution
602
- subAgentTaskId: string | null; // Task ID if this is a subagent, null otherwise
603
- }
61
+ - **Deno** (`internal/examples/deno/`) - agent tasks, pagination,
62
+ embed keys, image OCR, workforce tasks
63
+ - **Browser** (`internal/examples/browser/chat/`) - full chat
64
+ application built with Preact
604
65
 
605
- class AgentErrorMessage extends GenericMessage {}
66
+ ## Development
606
67
 
607
- class WorkforceAgentMessage extends GenericMessage {}
608
-
609
- class WorkforceAgentHandoverMessage extends GenericMessage {}
610
- ```
611
-
612
- ### Tool
613
-
614
- ```typescript
615
- class Tool {
616
- readonly id: string;
617
- readonly name: string;
618
- readonly avatar?: string;
619
- readonly description?: string;
620
- readonly region: Region;
621
- readonly project: string;
622
- readonly parametersSchema: JSONSchema4;
623
- }
624
- ```
625
-
626
- ## Contributing
627
-
628
- We welcome contributions to improve the SDK. Please follow these guidelines:
629
-
630
- ### Development Setup
631
-
632
- 1. Clone the repository
633
- 2. Install Deno (primary development environment)
68
+ The SDK is developed with Deno and published to npm and JSR.
634
69
 
635
70
  ```bash
636
- # Build npm package
637
- deno run dnt
638
- ```
71
+ # clone the repository
72
+ git clone https://github.com/RelevanceAI/relevance-js-sdk.git
73
+ cd relevance-js-sdk
639
74
 
640
- ### Code Style
641
-
642
- - Use TypeScript for all code
643
- - Follow existing patterns and conventions
644
- - Maintain 80-character line width where practical
645
- - Write clear, concise commit messages
646
-
647
- ### Submitting Changes
648
-
649
- 1. Fork the repository
650
- 2. Create a feature branch
651
- 3. Make your changes
652
- 4. Submit a pull request with clear description
653
-
654
- ## Roadmap
655
-
656
- ### Current
657
-
658
- - [x] Core client functionality
659
- - [x] Task creation
660
- - [x] Event-driven messaging
661
- - [x] Multi-environment support
662
- - [x] Workforce support
75
+ # build the npm package
76
+ deno run -A internal/tasks/dnt.ts
77
+ ```
663
78
 
664
- ### Upcoming Features
79
+ ## License
665
80
 
666
- - [ ] Streaming responses
667
- - [ ] File upload support
668
- - [ ] Enhanced error recovery
669
- - [ ] Agent and task management
670
- - [ ] Tool support
81
+ MIT
671
82
 
672
- ### Future Considerations (2.0)
83
+ ## Security
673
84
 
674
- - [ ] WebSocket support for real-time updates
675
- - [ ] Offline queue management
676
- - [ ] Tool building architecture
677
- - [ ] Voice modality
85
+ For security vulnerabilities, please email security@relevanceai.com
86
+ directly rather than using public issue trackers.
678
87
 
679
88
  ## Support
680
89
 
681
- - **Issues**: [GitHub Issues](https://github.com/RelevanceAI/relevance-js-sdk/issues)
682
- - **Community**: [Discord Server](https://discord.gg/relevanceai)
683
-
684
- ## License
685
-
686
- MIT License. See [LICENSE](./LICENSE) for details.
687
-
688
- ## Security
689
-
690
- For security vulnerabilities, please email security@relevanceai.com directly
691
- rather than using public issue trackers.
90
+ - [GitHub Issues](https://github.com/RelevanceAI/relevance-js-sdk/issues)
91
+ - [Discord](https://discord.gg/relevanceai)