@relevanceai/sdk 3.0.0-alpha.4 → 3.0.0-alpha.5

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.
Files changed (72) hide show
  1. package/README.md +195 -100
  2. package/esm/agent.d.ts +41 -8
  3. package/esm/agent.js +150 -13
  4. package/esm/client.d.ts +6 -1
  5. package/esm/client.js +38 -4
  6. package/esm/event.d.ts +6 -25
  7. package/esm/event.js +4 -19
  8. package/esm/key.d.ts +1 -1
  9. package/esm/message/agent-error.d.ts +7 -2
  10. package/esm/message/agent-error.js +8 -2
  11. package/esm/message/agent.d.ts +2 -2
  12. package/esm/message/agent.js +2 -2
  13. package/esm/message/task.d.ts +25 -4
  14. package/esm/message/task.js +26 -2
  15. package/esm/message/tool.d.ts +16 -6
  16. package/esm/message/tool.js +32 -6
  17. package/esm/message/user.d.ts +2 -2
  18. package/esm/message/user.js +2 -2
  19. package/esm/message/workforce-agent-handover.d.ts +23 -0
  20. package/esm/message/workforce-agent-handover.js +3 -0
  21. package/esm/message/workforce-agent.d.ts +23 -0
  22. package/esm/message/workforce-agent.js +3 -0
  23. package/esm/mod.d.ts +1 -6
  24. package/esm/mod.js +1 -1
  25. package/esm/task/agent-strategy.d.ts +26 -0
  26. package/esm/task/agent-strategy.js +63 -0
  27. package/esm/task/task.d.ts +59 -0
  28. package/esm/task/task.js +166 -0
  29. package/esm/task/workforce-strategy.d.ts +17 -0
  30. package/esm/task/workforce-strategy.js +68 -0
  31. package/esm/utils.d.ts +1 -0
  32. package/esm/utils.js +4 -0
  33. package/esm/workforce.d.ts +22 -0
  34. package/esm/workforce.js +50 -0
  35. package/package.json +1 -1
  36. package/script/agent.d.ts +41 -8
  37. package/script/agent.js +151 -13
  38. package/script/client.d.ts +6 -1
  39. package/script/client.js +37 -3
  40. package/script/event.d.ts +6 -25
  41. package/script/event.js +6 -23
  42. package/script/key.d.ts +1 -1
  43. package/script/message/agent-error.d.ts +7 -2
  44. package/script/message/agent-error.js +7 -1
  45. package/script/message/agent.d.ts +2 -2
  46. package/script/message/agent.js +1 -1
  47. package/script/message/task.d.ts +25 -4
  48. package/script/message/task.js +28 -4
  49. package/script/message/tool.d.ts +16 -6
  50. package/script/message/tool.js +31 -5
  51. package/script/message/user.d.ts +2 -2
  52. package/script/message/user.js +1 -1
  53. package/script/message/workforce-agent-handover.d.ts +23 -0
  54. package/script/message/workforce-agent-handover.js +7 -0
  55. package/script/message/workforce-agent.d.ts +23 -0
  56. package/script/message/workforce-agent.js +7 -0
  57. package/script/mod.d.ts +1 -6
  58. package/script/mod.js +3 -3
  59. package/script/task/agent-strategy.d.ts +26 -0
  60. package/script/task/agent-strategy.js +67 -0
  61. package/script/task/task.d.ts +59 -0
  62. package/script/task/task.js +170 -0
  63. package/script/task/workforce-strategy.d.ts +17 -0
  64. package/script/task/workforce-strategy.js +72 -0
  65. package/script/utils.d.ts +1 -0
  66. package/script/utils.js +5 -0
  67. package/script/workforce.d.ts +22 -0
  68. package/script/workforce.js +54 -0
  69. package/esm/task.d.ts +0 -57
  70. package/esm/task.js +0 -259
  71. package/script/task.d.ts +0 -57
  72. package/script/task.js +0 -263
package/README.md CHANGED
@@ -1,15 +1,15 @@
1
1
  # Relevance AI JavaScript SDK
2
2
 
3
3
  A comprehensive JavaScript/TypeScript SDK for building AI-powered applications
4
- with Relevance AI's workforce platform. Build, deploy, and scale AI agents
4
+ with Relevance AI's workforce platform. Build, deploy, and scale AI workforces
5
5
  across any JavaScript runtime.
6
6
 
7
7
  ## Description
8
8
 
9
9
  The Relevance AI JavaScript SDK provides a unified interface for integrating
10
- AI agents into your applications. Whether you're building server-side
11
- applications, browser-based interfaces, or edge computing solutions, this SDK
12
- delivers consistent, type-safe access to Relevance AI's powerful agent
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
13
  ecosystem.
14
14
 
15
15
  ### Key Features
@@ -18,13 +18,11 @@ ecosystem.
18
18
  Cloudflare Workers, and browsers
19
19
  - **Event-Driven Architecture**: Real-time updates via native EventTarget API
20
20
  - **Type Safety**: Full TypeScript support with comprehensive type definitions
21
- - **Multi-Client Support**: Manage multiple projects and authentication scopes
22
- simultaneously
23
21
  - **Zero Dependencies**: Built on web standards for minimal footprint
24
22
 
25
23
  ## Quick Start
26
24
 
27
- Get up and running with AI agents in under 5 minutes:
25
+ Get up and running in seconds:
28
26
 
29
27
  ```typescript
30
28
  import { Agent, createClient, EU_REGION } from "@relevanceai/sdk";
@@ -36,16 +34,25 @@ const client = createClient({
36
34
  project: process.env.PROJECT_ID,
37
35
  });
38
36
 
39
- // Load an agent and start a conversation
37
+ // Load an agent
40
38
  const agent = await Agent.get("agent-id");
39
+ // Start a conversation
41
40
  const task = await agent.sendMessage("Hello, how can you help me today?");
42
-
43
41
  // Listen for agent responses
44
42
  task.addEventListener("message", ({ detail: { message } }) => {
45
43
  if (message.isAgent()) {
46
44
  console.log("Agent:", message.text);
47
45
  }
48
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");
49
56
  ```
50
57
 
51
58
  ## Installation
@@ -123,7 +130,7 @@ Configure your bundler to use the shim:
123
130
 
124
131
  The SDK supports two authentication methods for different use cases:
125
132
 
126
- #### API Keys (Server-side)
133
+ #### API Keys (server-side)
127
134
 
128
135
  API keys grant full access to your project. Use these for server applications
129
136
  and secure environments:
@@ -152,10 +159,12 @@ const key = new Key({
152
159
  const client = new Client(key);
153
160
  ```
154
161
 
155
- #### Embed Keys (Client-side)
162
+ #### Embed Keys (client-side)
156
163
 
157
164
  For public-facing applications, use embed keys which are scoped to a specific
158
- public agent:
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.
159
168
 
160
169
  ```typescript
161
170
  import { Key, createClient, US_REGION } from "@relevanceai/sdk";
@@ -169,105 +178,150 @@ const embedKey = await Key.generateEmbedKey({
169
178
  const client = createClient(embedKey);
170
179
  ```
171
180
 
172
- ### Fetching Agents
181
+ ### Agents
173
182
 
174
- Load agents before creating tasks:
183
+ #### Loading agents
175
184
 
176
185
  ```typescript
177
- // Using default client
186
+ // using the default client
178
187
  const agent = await Agent.get("agent-id");
179
188
 
180
- // Using specific client
181
- const customClient = createClient({
182
- /* config */
183
- });
184
- const agent = await Agent.get("agent-id", customClient);
189
+ // or using a specific client
190
+ const agent = await Agent.get("agent-id", client);
185
191
 
186
- // Access agent properties
192
+ // accessing agent properties
187
193
  console.log(agent.name);
188
194
  console.log(agent.avatar);
189
195
  console.log(agent.description);
190
196
  ```
191
197
 
192
- ### Sending Messages
198
+ #### Sending messages
193
199
 
194
- #### Create a New Task
195
-
196
- Start a new conversation with an agent:
200
+ Use `Agent#sendMessage()` to send messages to an agent.
197
201
 
198
202
  ```typescript
199
- const agent = await Agent.get("agent-id");
203
+ // create a new task
200
204
  const task = await agent.sendMessage("What's the weather like today?");
205
+
206
+ // reply to existing tasks
207
+ await agent.sendMessage("What about tomorrow?", task);
208
+
209
+ // sending attachments
210
+ const contents = await Deno.readFile("./contract.pdf");
211
+ const contract = new File([contents], "contract.pdf", {
212
+ type: "application/pdf",
213
+ });
214
+ await agent.sendMessage("Summarize this contract", [contract]);
215
+ ```
216
+
217
+ Note: `Agent#sendMessage()` returns once the message is sent and doesn't wait for
218
+ a response. See Tasks for handling message events.
219
+
220
+ #### Retrieving tasks
221
+
222
+ Fetch and filter tasks for an agent:
223
+
224
+ ```typescript
225
+ // specific task
226
+ const task = await agent.getTask("<task-id>");
227
+
228
+ // pagination
229
+ const tasks = await agent.getTasks({
230
+ pageSize: 10,
231
+ page: 1,
232
+ sort: { updatedAt: "desc" },
233
+ });
234
+
235
+ // filtering
236
+ const activeTasks = await agent.getTasks({
237
+ filter: { status: ["queued", "running", "idle"] },
238
+ });
239
+
240
+ // searching
241
+ const searchResults = await agent.getTasks({
242
+ search: "weather",
243
+ sort: { createdAt: "asc" },
244
+ });
245
+ ```
246
+
247
+ ### Workforces
248
+
249
+ #### Loading workforces
250
+
251
+ ```typescript
252
+ // using the default client
253
+ const workforce = await Workforce.get("<workforce-id>");
254
+
255
+ // or with a specific client
256
+ const workforce = await Workforce.get("<workforce-id>", client);
257
+
258
+ // accessing workforce properties
259
+ console.log(workforce.name);
201
260
  ```
202
261
 
203
- #### Send to Existing Task
262
+ #### Sending messages
204
263
 
205
- Continue an existing conversation:
264
+ Use `Workforce#sendMessage()` to send messages to a workforce.
206
265
 
207
266
  ```typescript
208
- // Get an existing task
209
- const task = await agent.getTask("task-id");
267
+ // create a new task
268
+ const task = await agent.sendMessage("What's the weather like today?");
210
269
 
211
- // Send a follow-up message
270
+ // reply to existing tasks
212
271
  await agent.sendMessage("What about tomorrow?", task);
213
272
  ```
214
273
 
215
- Note: `sendMessage` returns once the message is sent and doesn't wait for a
216
- response. Use event listeners to handle responses.
274
+ Note: `Workforce#sendMessage()` returns once the message is sent and doesn't
275
+ wait for a response. See Tasks for handling message events.
217
276
 
218
- ### Event Handling
277
+ #### Retrieving tasks
219
278
 
220
- Tasks use an event-driven architecture for real-time updates:
279
+ Load existing workforce tasks.
280
+
281
+ ```typescript
282
+ const task = await workforce.getTask("<task-id>");
283
+ ```
284
+
285
+ ### Tasks
286
+
287
+ Agents and workforces, subjects, all return an instance of a `Task` when sending
288
+ messages. Tasks dispatch events as they would occur on the the subjects timeline
289
+ in the Relevance AI workforce platform.
221
290
 
222
291
  #### Available Events
223
292
 
224
- - **`start`**: Task initialization
225
- - **`status`**: Status changes (queued, running, complete, error)
226
- - **`message`**: New messages from agent or user
227
- - **`update`**: Tool execution updates
293
+ - **`updated`**: Whenever a subject has been updated.
294
+ - **`message`**: Unified event for all message types
228
295
  - **`error`**: Error notifications
229
296
 
230
297
  #### Listening for Events
231
298
 
232
299
  ```typescript
233
- // Listen for messages
234
- task.addEventListener("message", ({ detail }) => {
235
- const { message } = detail;
236
-
300
+ // Listen for all messages (agent, user, and tool)
301
+ task.addEventListener("message", ({ detail: { message } }) => {
302
+ // use message helpers to determine the message
237
303
  if (message.isAgent()) {
238
304
  console.log("Agent:", message.text);
305
+ } else if (message.isUser()) {
306
+ console.log("User:", message.text);
307
+ } else if (message.isTool()) {
308
+ console.log("Tool:", message.status);
239
309
  }
240
310
  });
241
311
 
242
- // Listen for status changes
243
- task.addEventListener("status", ({ detail }) => {
244
- console.log("Status changed to:", detail.status);
245
- });
246
-
247
- // Listen for tool updates
248
- task.addEventListener("update", ({ detail }) => {
249
- console.log("Tool update:", detail.message);
250
- });
251
-
252
- // Listen for errors
253
- task.addEventListener("error", ({ detail }) => {
254
- console.error("Task error:", detail.message);
312
+ // catching errors
313
+ task.addEventListener("error", ({ detail: { message } }) => {
314
+ console.error("Task error:", message.lastError);
255
315
  });
256
-
257
- // Clean up when done
258
- task.unsubscribe();
259
316
  ```
260
317
 
261
- #### Managing Subscriptions
318
+ #### Unsubscribing
262
319
 
263
- The SDK automatically starts listening when you add event listeners. Remember
264
- to clean up:
320
+ It's important that you unsubscribe from tasks once they have moved out of
321
+ scope in your application. This will prevent memory leaks by removing dead
322
+ subscriptions.
265
323
 
266
324
  ```typescript
267
- // Start listening (called automatically with addEventListener)
268
- task.subscribe();
269
-
270
- // Stop listening and clean up
271
325
  task.unsubscribe();
272
326
  ```
273
327
 
@@ -319,10 +373,11 @@ For complete working examples, check out the `internal/examples` directory:
319
373
 
320
374
  - **Deno Examples** (`internal/examples/deno/`):
321
375
 
322
- - Client setup and configuration
323
- - Creating and managing tasks
324
- - Fetching agent information
325
- - Retrieving existing tasks
376
+ - (Agent) Creating tasks
377
+ - (Agent) Getting a task
378
+ - (Agent) Getting all tasks
379
+ - (Agent) Getting an agent
380
+ - (Workforce) Creating a task
326
381
 
327
382
  - **Browser Example** (`internal/examples/browser/`):
328
383
  - Full chat application with Preact
@@ -405,27 +460,72 @@ class Agent {
405
460
  readonly project: string;
406
461
 
407
462
  getTask(taskId: string): Promise<Task>;
408
- sendMessage(message: string, task?: Task): Promise<Task>;
463
+
464
+ getTasks(): Promise<Task[]>;
465
+ getTasks(options: GetTaskOptions): Promise<Task[]>;
466
+
467
+ sendMessage(message: string): Promise<Task>;
468
+ sendMessage(message: string, task: Task): Promise<Task>;
469
+ sendMessage(
470
+ message: string,
471
+ attachments: (File | Attachment)[]
472
+ ): Promise<Task>;
473
+ sendMessage(
474
+ message: string,
475
+ attachments: (File | Attachment)[],
476
+ task: Task
477
+ ): Promise<Task>;
478
+ }
479
+
480
+ interface Attachment {
481
+ fileName: string;
482
+ fileUrl: string;
483
+ }
484
+
485
+ interface GetTaskOptions {
486
+ pageSize?: number; // default: 100
487
+ page?: number; // default: 1
488
+ // default: { createdAt: "asc" }
489
+ sort?: { createdAt: "asc" | "desc" } | { updatedAt: "asc" | "desc" };
490
+ search?: string;
491
+ filter?: {
492
+ status?: TaskStatus[];
493
+ };
409
494
  }
410
495
  ```
411
496
 
412
- ### Task
497
+ ### Workforce
413
498
 
414
499
  ```typescript
415
- class Task extends EventTarget {
416
- static async get(
417
- id: string,
418
- agentOrAgentId: Agent | string,
419
- client?: Client
420
- ): Promise<Task>;
500
+ class Workforce {
501
+ static async get(id: string, client?: Client): Promise<Workforce>;
421
502
 
503
+ readonly id: string;
504
+ readonly name: string;
505
+ readonly region: Region;
506
+ readonly project: string;
507
+
508
+ getTask(taskId: string): Promise<Task>;
509
+
510
+ sendMessage(message: string): Promise<Task>;
511
+ sendMessage(message: string, task: Task): Promise<Task>;
512
+ }
513
+ ```
514
+
515
+ ### Task
516
+
517
+ ```typescript
518
+ class Task<T extends Agent | Workforce = Agent> extends EventTarget {
422
519
  readonly id: string;
423
520
  readonly title: string;
424
521
  readonly status: TaskStatus;
425
- readonly agent: Agent;
522
+ readonly subject: Agent | Workforce;
426
523
 
427
524
  isRunning(): boolean;
428
- getMessages(options?: { from?: Date }): Promise<AnyTaskMessage[]>;
525
+
526
+ getMessages(): Promise<AnyTaskMessage[]>;
527
+ getMessages(options: { from: Date }): Promise<AnyTaskMessage[]>;
528
+
429
529
  subscribe(): void;
430
530
  unsubscribe(): void;
431
531
 
@@ -439,46 +539,41 @@ type TaskStatus =
439
539
  | "queued"
440
540
  | "running"
441
541
  | "action"
442
- | "complete"
542
+ | "completed"
443
543
  | "error";
444
544
  ```
445
545
 
446
546
  ### Messages
447
547
 
448
548
  ```typescript
449
- abstract class TaskMessage {
549
+ abstract class GenericMessage {
450
550
  readonly id: string;
451
551
  readonly type: MessageType;
452
552
  readonly createdAt: Date;
453
553
 
454
- isAgent(): boolean;
554
+ isAgent(): boolean; // Check if message is from agent
555
+ isUser(): boolean; // Check if message is from user
556
+ isTool(): boolean; // Check if message is a tool execution
557
+ isAgentError(): boolean; // Check if message is an agent error
455
558
  }
456
559
 
457
- class AgentMessage extends TaskMessage {
560
+ class AgentMessage extends GenericMessage {
458
561
  readonly text: string;
459
562
  }
460
563
 
461
- class UserMessage extends TaskMessage {
564
+ class UserMessage extends GenericMessage {
462
565
  readonly text: string;
463
566
  }
464
567
 
465
- class ToolMessage extends TaskMessage {
466
- readonly status: "pending" | "running" | "completed" | "failed";
568
+ class ToolMessage extends GenericMessage {
569
+ readonly status: "cancelled" | "pending" | "running" | "completed" | "failed";
467
570
  }
468
571
 
469
- class AgentErrorMessage extends TaskMessage {
470
- readonly error: string;
471
- }
472
- ```
572
+ class AgentErrorMessage extends GenericMessage {}
473
573
 
474
- ### Types
475
-
476
- ```typescript
477
- type Region = "us" | "eu" | "au";
574
+ class WorkforceAgentMessage extends GenericMessage {}
478
575
 
479
- const US_REGION: Region = "us";
480
- const EU_REGION: Region = "eu";
481
- const AU_REGION: Region = "au";
576
+ class WorkforceAgentHandoverMessage extends GenericMessage {}
482
577
  ```
483
578
 
484
579
  ## Contributing
@@ -514,9 +609,10 @@ deno run dnt
514
609
  ### Current
515
610
 
516
611
  - [x] Core client functionality
517
- - [x] Agent and task creation
612
+ - [x] Task creation
518
613
  - [x] Event-driven messaging
519
614
  - [x] Multi-environment support
615
+ - [x] Workforce support
520
616
 
521
617
  ### Upcoming Features
522
618
 
@@ -524,7 +620,6 @@ deno run dnt
524
620
  - [ ] File upload support
525
621
  - [ ] Enhanced error recovery
526
622
  - [ ] Agent and task management
527
- - [ ] Workforce support
528
623
  - [ ] Tool support
529
624
 
530
625
  ### Future Considerations (2.0)
package/esm/agent.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { Client } from "./client.js";
1
+ import { type Attachment, Client } from "./client.js";
2
2
  import type { Region } from "./region.js";
3
- import { Task } from "./task.js";
4
- interface AgentConfig {
3
+ import { Task, type TaskStatus } from "./task/task.js";
4
+ export interface AgentConfig {
5
5
  agent_id: string;
6
6
  public: boolean;
7
7
  name?: string;
@@ -9,21 +9,54 @@ interface AgentConfig {
9
9
  emoji?: string;
10
10
  insert_date_: string;
11
11
  update_date_: string;
12
+ model: string;
12
13
  }
14
+ export type AgentTaskState = "idle" | "starting-up" | "running" | "pending-approval" | "waiting-for-capacity" | "cancelled" | "timed-out" | "escalated" | "unrecoverable" | "paused" | "completed" | "errored-pending-approval" | "queued-for-approval" | "queued-for-rerun";
15
+ /**
16
+ * Converts an AgentTaskState to a simplified TaskStatus.
17
+ *
18
+ * @dev
19
+ * We want to simplify because our states are simplified in the UI and also
20
+ * some states have combined reasoning that the consumer does not need to care
21
+ * about. i.e. "queued-for-approval" "queued-for-rerun" should just be "queued".
22
+ *
23
+ * @param {AgentTaskState} state The agent task state to convert.
24
+ * @returns {TaskStatus} The simplified task status.
25
+ */
26
+ export declare function stateToStatus(state: AgentTaskState): TaskStatus;
27
+ type SortDirection = "asc" | "desc";
28
+ type GetTaskOptionSort = {
29
+ createdAt: SortDirection;
30
+ } | {
31
+ updatedAt: SortDirection;
32
+ };
33
+ type GetTaskOptions = {
34
+ pageSize?: number;
35
+ page?: number;
36
+ sort?: GetTaskOptionSort;
37
+ search?: string;
38
+ filter?: {
39
+ status?: TaskStatus[];
40
+ };
41
+ };
13
42
  export declare class Agent {
14
43
  #private;
15
- private readonly client;
16
44
  static get(id: string, client?: Client): Promise<Agent>;
45
+ private readonly client;
17
46
  constructor(config: AgentConfig, client: Client);
18
47
  get id(): string;
48
+ get region(): Region;
49
+ get project(): string;
19
50
  get name(): string | undefined;
20
51
  get description(): string | undefined;
21
52
  get avatar(): string | undefined;
22
53
  get createdAt(): Date;
23
54
  get updatedAt(): Date;
24
- get region(): Region;
25
- get project(): string;
26
- getTask(taskId: string): Promise<Task>;
27
- sendMessage(message: string, task?: Task): Promise<Task>;
55
+ getTask(taskId: string): Promise<Task<Agent>>;
56
+ getTasks({ sort, pageSize, page, search, filter, }?: GetTaskOptions): Promise<Task<Agent>[]>;
57
+ sendMessage(message: string): Promise<Task<Agent>>;
58
+ sendMessage(message: string, task: Task<Agent>): Promise<Task<Agent>>;
59
+ sendMessage(message: string, attachments: (Attachment | File)[]): Promise<Task<Agent>>;
60
+ sendMessage(message: string, attachments: (Attachment | File)[], task: Task<Agent>): Promise<Task<Agent>>;
28
61
  }
29
62
  export {};