@happyrobot-ai/sdk 0.1.2 → 0.1.4
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 +164 -23
- package/chat-client.d.ts +106 -0
- package/chat-client.js +251 -0
- package/chat-client.mjs +3 -0
- package/client.d.ts +6 -3
- package/client.js +8 -4
- package/core/http.js +3 -2
- package/index.d.ts +6 -2
- package/index.js +8 -4
- package/package.json +3 -2
- package/resources/artifacts.d.ts +7 -0
- package/resources/artifacts.js +18 -0
- package/resources/artifacts.mjs +3 -0
- package/resources/chat.d.ts +26 -0
- package/resources/chat.js +37 -0
- package/resources/chat.mjs +3 -0
- package/resources/usage.d.ts +0 -27
- package/resources/usage.js +0 -70
- package/resources/usage.mjs +0 -3
package/README.md
CHANGED
|
@@ -113,15 +113,16 @@ const { workflow } = await createFromTemplate(client, {
|
|
|
113
113
|
| `client.knowledgeBases` | `KnowledgeBasesResource` | Knowledge base document management |
|
|
114
114
|
| `client.workflowFolders` | `WorkflowFoldersResource` | Workflow folder organization |
|
|
115
115
|
| `client.mcp` | `MCPResource` | MCP server management |
|
|
116
|
-
| `client.usage` | `UsageResource` | Usage metrics (call minutes, tokens, etc.) |
|
|
117
116
|
| `client.billing` | `BillingResource` | Billing usage details and totals |
|
|
118
117
|
| `client.apiKey` | `ApiKeyResource` | API key introspection |
|
|
118
|
+
| `client.artifacts` | `ArtifactsResource` | Resolve fresh artifact URLs |
|
|
119
119
|
| `client.adversarialSuites` | `AdversarialSuitesResource` | Adversarial suite management and execution |
|
|
120
120
|
| `client.adversarialTests` | `AdversarialTestsResource` | Adversarial test management and execution |
|
|
121
121
|
| `client.northstars` | `NorthstarsResource` | Northstar quality criteria management |
|
|
122
122
|
| `client.customEvals` | `CustomEvalsResource` | Custom eval management and execution |
|
|
123
123
|
| `client.issues` | `IssuesResource` | Quality issue (flag) status management |
|
|
124
124
|
| `client.auditRemarks` | `AuditRemarksResource` | Audit remark feedback management |
|
|
125
|
+
| `client.chat` | `ChatResource` | Chat session management, messaging, and file uploads |
|
|
125
126
|
|
|
126
127
|
---
|
|
127
128
|
|
|
@@ -301,6 +302,20 @@ await client.messages.createFlag("message-id", { type: "incorrect", note: "..."
|
|
|
301
302
|
|
|
302
303
|
---
|
|
303
304
|
|
|
305
|
+
## `client.artifacts`
|
|
306
|
+
|
|
307
|
+
```ts
|
|
308
|
+
const resolved = await client.artifacts.resolve({
|
|
309
|
+
s3_keys: ["artifacts/<media_id>/extracted_text.txt"],
|
|
310
|
+
});
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
| Method | HTTP | Path | Description |
|
|
314
|
+
|---|---|---|---|
|
|
315
|
+
| `resolve(body)` | POST | `/artifacts/resolve` | Resolve fresh presigned URLs for artifacts |
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
304
319
|
## `client.variables`
|
|
305
320
|
|
|
306
321
|
Variables are scoped to a workflow.
|
|
@@ -507,28 +522,6 @@ await client.mcp.refresh("mcp-id");
|
|
|
507
522
|
|
|
508
523
|
---
|
|
509
524
|
|
|
510
|
-
## `client.usage`
|
|
511
|
-
|
|
512
|
-
All methods accept a `UsageQuery` with `workflow_id`, `start_date`, and `end_date`.
|
|
513
|
-
|
|
514
|
-
```ts
|
|
515
|
-
const data = await client.usage.callMinutes({ workflow_id: "wf-id", start_date: "2024-01-01", end_date: "2024-01-31" });
|
|
516
|
-
await client.usage.llmTokens({ ... });
|
|
517
|
-
await client.usage.textCount({ ... });
|
|
518
|
-
await client.usage.ocrCount({ ... });
|
|
519
|
-
await client.usage.rpaMinutes({ ... });
|
|
520
|
-
```
|
|
521
|
-
|
|
522
|
-
| Method | HTTP | Path | Description |
|
|
523
|
-
|---|---|---|---|
|
|
524
|
-
| `callMinutes(query)` | GET | `/usage/call-minutes` | Voice call minutes consumed |
|
|
525
|
-
| `llmTokens(query)` | GET | `/usage/llm-tokens` | LLM tokens consumed |
|
|
526
|
-
| `textCount(query)` | GET | `/usage/text-count` | Text messages sent |
|
|
527
|
-
| `ocrCount(query)` | GET | `/usage/ocr-count` | OCR operations performed |
|
|
528
|
-
| `rpaMinutes(query)` | GET | `/usage/rpa-minutes` | RPA automation minutes consumed |
|
|
529
|
-
|
|
530
|
-
---
|
|
531
|
-
|
|
532
525
|
## `client.billing`
|
|
533
526
|
|
|
534
527
|
```ts
|
|
@@ -729,6 +722,154 @@ await client.auditRemarks.deleteFeedback("audit-remark-id");
|
|
|
729
722
|
|
|
730
723
|
---
|
|
731
724
|
|
|
725
|
+
## Chat (`client.chat` + `HappyRobotChatClient`)
|
|
726
|
+
|
|
727
|
+
Build custom chat UIs powered by your workflows. Uses a two-tier auth model:
|
|
728
|
+
|
|
729
|
+
1. **Your server** creates a scoped client token using the API key (keeps it secret)
|
|
730
|
+
2. **Your browser** uses `HappyRobotChatClient` with that token for all chat operations
|
|
731
|
+
|
|
732
|
+
### Server-side: Create a client token
|
|
733
|
+
|
|
734
|
+
```ts
|
|
735
|
+
// --- YOUR SERVER (e.g. Next.js API route, Express handler) ---
|
|
736
|
+
import { HappyRobotClient } from "@happyrobot-ai/sdk";
|
|
737
|
+
|
|
738
|
+
const client = new HappyRobotClient({ apiKey: process.env.HAPPYROBOT_API_KEY });
|
|
739
|
+
|
|
740
|
+
app.post("/api/chat-token", async (req, res) => {
|
|
741
|
+
const { token, expires_at } = await client.chat.createToken({
|
|
742
|
+
workflow_id: "your-workflow-id",
|
|
743
|
+
});
|
|
744
|
+
res.json({ token, expires_at });
|
|
745
|
+
});
|
|
746
|
+
```
|
|
747
|
+
|
|
748
|
+
### Browser-side: `HappyRobotChatClient`
|
|
749
|
+
|
|
750
|
+
```ts
|
|
751
|
+
// --- YOUR BROWSER CODE (React, Vue, vanilla JS, etc.) ---
|
|
752
|
+
import { HappyRobotChatClient } from "@happyrobot-ai/sdk";
|
|
753
|
+
|
|
754
|
+
// 1. Get a client token from your server
|
|
755
|
+
const { token } = await fetch("/api/chat-token", { method: "POST" }).then(r => r.json());
|
|
756
|
+
|
|
757
|
+
// 2. Initialize the browser-side client
|
|
758
|
+
const chat = new HappyRobotChatClient({ token });
|
|
759
|
+
|
|
760
|
+
// 3. Create a session
|
|
761
|
+
const { session_id } = await chat.createSession();
|
|
762
|
+
|
|
763
|
+
// 4. Connect bidirectional WebSocket
|
|
764
|
+
const connection = chat.connect(session_id, {
|
|
765
|
+
onResponseStart: () => {
|
|
766
|
+
// Show typing indicator
|
|
767
|
+
},
|
|
768
|
+
onResponseChunk: (content) => {
|
|
769
|
+
// Append streamed text to the UI
|
|
770
|
+
},
|
|
771
|
+
onResponseEnd: (content) => {
|
|
772
|
+
// Full response complete — hide typing indicator
|
|
773
|
+
},
|
|
774
|
+
onSessionClosed: (event) => {
|
|
775
|
+
// Session ended: event.status, event.reason, event.duration
|
|
776
|
+
},
|
|
777
|
+
onTokenExpired: () => {
|
|
778
|
+
// Token expired — fetch a new token from your server and reconnect
|
|
779
|
+
},
|
|
780
|
+
});
|
|
781
|
+
|
|
782
|
+
// 5. Send messages through the WebSocket
|
|
783
|
+
const ack = await connection.sendMessage({ content: "Hello!" });
|
|
784
|
+
console.log(ack.message.id); // server-assigned message ID
|
|
785
|
+
|
|
786
|
+
// 6. Send messages with file attachments
|
|
787
|
+
const artifact = await chat.uploadFile(fileBlob, "photo.png", "image/png");
|
|
788
|
+
await connection.sendMessage({ content: "Here's the photo", artifacts: [artifact] });
|
|
789
|
+
|
|
790
|
+
// 7. Get history (page reload, reconnect)
|
|
791
|
+
const { messages } = await chat.getHistory(session_id);
|
|
792
|
+
|
|
793
|
+
// 8. Clean up
|
|
794
|
+
connection.close();
|
|
795
|
+
```
|
|
796
|
+
|
|
797
|
+
### Browser-side: File uploads
|
|
798
|
+
|
|
799
|
+
```ts
|
|
800
|
+
// Option A: Use the convenience method (handles all 3 steps)
|
|
801
|
+
const artifact = await chat.uploadFile(fileBlob, "photo.png", "image/png");
|
|
802
|
+
await connection.sendMessage({
|
|
803
|
+
content: "Here's the photo",
|
|
804
|
+
artifacts: [artifact],
|
|
805
|
+
});
|
|
806
|
+
|
|
807
|
+
// Option B: Manual 3-step flow for more control
|
|
808
|
+
const upload = await chat.getPresignedUpload({ filename: "photo.png", mime_type: "image/png" });
|
|
809
|
+
await fetch(upload.upload_url, { method: "PUT", body: fileBlob, headers: { "Content-Type": "image/png" } });
|
|
810
|
+
await chat.completeUpload({
|
|
811
|
+
artifact_id: upload.artifact_id,
|
|
812
|
+
s3_uri: upload.s3_uri,
|
|
813
|
+
filename: "photo.png",
|
|
814
|
+
mime_type: "image/png",
|
|
815
|
+
size_bytes: fileBlob.size,
|
|
816
|
+
});
|
|
817
|
+
await connection.sendMessage({
|
|
818
|
+
content: "Here's the photo",
|
|
819
|
+
artifacts: [{ media_id: upload.artifact_id, mime_type: "image/png", filename: "photo.png", size_bytes: fileBlob.size }],
|
|
820
|
+
});
|
|
821
|
+
```
|
|
822
|
+
|
|
823
|
+
### `HappyRobotClient` (server-side)
|
|
824
|
+
|
|
825
|
+
| Method | Description |
|
|
826
|
+
|---|---|
|
|
827
|
+
| `client.chat.createToken({ workflow_id, env? })` | Create a scoped client token (1 hour expiry) |
|
|
828
|
+
|
|
829
|
+
### `HappyRobotChatClient` (browser-side)
|
|
830
|
+
|
|
831
|
+
| Method | Description |
|
|
832
|
+
|---|---|
|
|
833
|
+
| `chat.createSession()` | Create a new chat session |
|
|
834
|
+
| `chat.connect(sessionId, handlers)` | Open bidirectional WebSocket — returns `ChatConnection` |
|
|
835
|
+
| `chat.sendMessage(sessionId, { content, artifacts? })` | Send a user message via HTTP (fallback if WS unavailable) |
|
|
836
|
+
| `chat.getHistory(sessionId)` | Get message history |
|
|
837
|
+
| `chat.uploadFile(file, filename, mimeType)` | Upload a file (convenience method) |
|
|
838
|
+
| `chat.getPresignedUpload({ filename, mime_type })` | Get presigned S3 upload URL |
|
|
839
|
+
| `chat.completeUpload({ artifact_id, s3_uri, ... })` | Register uploaded artifact |
|
|
840
|
+
|
|
841
|
+
### `ChatConnection`
|
|
842
|
+
|
|
843
|
+
| Method | Description |
|
|
844
|
+
|---|---|
|
|
845
|
+
| `connection.sendMessage({ content, artifacts? })` | Send a message via WebSocket. Returns a `Promise` that resolves with the server ack |
|
|
846
|
+
| `connection.close()` | Close the WebSocket connection |
|
|
847
|
+
| `connection.ws` | The underlying `WebSocket` instance |
|
|
848
|
+
|
|
849
|
+
### WebSocket Events
|
|
850
|
+
|
|
851
|
+
**Server → Client:**
|
|
852
|
+
|
|
853
|
+
| Event | Fields | Description |
|
|
854
|
+
|---|---|---|
|
|
855
|
+
| `connected` | `session_id` | Connection established |
|
|
856
|
+
| `response-start` | `content` | AI started generating a response |
|
|
857
|
+
| `response-chunk` | `content` | Partial response text |
|
|
858
|
+
| `response-end` | `content` | Complete response text |
|
|
859
|
+
| `session-closed` | `session_id`, `status`, `reason`, `duration`, `timestamp` | Session ended |
|
|
860
|
+
| `token-expired` | — | JWT expired — reconnect with a fresh token |
|
|
861
|
+
| `message-ack` | `id`, `message` | Server confirmed the message was sent |
|
|
862
|
+
| `message-error` | `id`, `error` | Server failed to send the message |
|
|
863
|
+
| `heartbeat` | — | Keep-alive (every 15s) |
|
|
864
|
+
|
|
865
|
+
**Client → Server:**
|
|
866
|
+
|
|
867
|
+
| Event | Fields | Description |
|
|
868
|
+
|---|---|---|
|
|
869
|
+
| `message` | `content`, `artifacts?`, `id?` | Send a user message. `id` is echoed back in ack/error |
|
|
870
|
+
|
|
871
|
+
---
|
|
872
|
+
|
|
732
873
|
## Pagination
|
|
733
874
|
|
|
734
875
|
List methods that are paginated return a `PaginatedResponse<T>`:
|
package/chat-client.d.ts
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HappyRobotChatClient — lightweight browser-side client for chat sessions.
|
|
3
|
+
*
|
|
4
|
+
* Initialized with a scoped client token (created server-side via
|
|
5
|
+
* `client.chat.createToken()`). Does NOT require an API key.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { HappyRobotChatClient } from "@happyrobot-ai/sdk";
|
|
10
|
+
*
|
|
11
|
+
* // Token comes from your server
|
|
12
|
+
* const chat = new HappyRobotChatClient({ token });
|
|
13
|
+
*
|
|
14
|
+
* const { session_id } = await chat.createSession();
|
|
15
|
+
*
|
|
16
|
+
* chat.connect(session_id, {
|
|
17
|
+
* onResponseStart: () => { },
|
|
18
|
+
* onResponseChunk: (content) => { },
|
|
19
|
+
* onResponseEnd: (content) => { },
|
|
20
|
+
* onSessionClosed: (event) => { },
|
|
21
|
+
* });
|
|
22
|
+
*
|
|
23
|
+
* await chat.sendMessage(session_id, { content: "Hello!" });
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
import type { ChatClientConfig, CreateChatSessionResponse, SendChatMessageBody, SendChatMessageResponse, ChatHistoryResponse, PresignedUploadQuery, PresignedUploadResponse, CompleteUploadBody, CompleteUploadResponse, ChatWsSessionClosedEvent, ChatWsMessageAckEvent } from "./types/chat.types";
|
|
27
|
+
export interface ChatConnectionHandlers {
|
|
28
|
+
/** AI started generating a response. */
|
|
29
|
+
onResponseStart?: () => void;
|
|
30
|
+
/** Partial response text chunk. */
|
|
31
|
+
onResponseChunk?: (content: string) => void;
|
|
32
|
+
/** Complete response text. */
|
|
33
|
+
onResponseEnd?: (content: string) => void;
|
|
34
|
+
/** Session was closed by the server. */
|
|
35
|
+
onSessionClosed?: (event: ChatWsSessionClosedEvent) => void;
|
|
36
|
+
/** Connection established. */
|
|
37
|
+
onConnected?: (sessionId: string) => void;
|
|
38
|
+
/** Token expired — reconnect with a fresh token to continue. */
|
|
39
|
+
onTokenExpired?: () => void;
|
|
40
|
+
/** WebSocket error. */
|
|
41
|
+
onError?: (error: Event) => void;
|
|
42
|
+
/** WebSocket closed. */
|
|
43
|
+
onClose?: (event: {
|
|
44
|
+
code: number;
|
|
45
|
+
reason: string;
|
|
46
|
+
}) => void;
|
|
47
|
+
}
|
|
48
|
+
export interface ChatConnection {
|
|
49
|
+
/** Close the WebSocket connection only (no server-side cleanup). */
|
|
50
|
+
close(): void;
|
|
51
|
+
/**
|
|
52
|
+
* End the session on the server (stops the AI agent) and close the WebSocket.
|
|
53
|
+
* Use this when the user is done with the conversation.
|
|
54
|
+
*/
|
|
55
|
+
endSession(): Promise<void>;
|
|
56
|
+
/** Send a message through the WebSocket. Returns the ack from the server. */
|
|
57
|
+
sendMessage(body: SendChatMessageBody): Promise<ChatWsMessageAckEvent>;
|
|
58
|
+
/** The underlying WebSocket instance. */
|
|
59
|
+
readonly ws: WebSocket;
|
|
60
|
+
}
|
|
61
|
+
export declare class HappyRobotChatClient {
|
|
62
|
+
private readonly token;
|
|
63
|
+
private readonly baseUrl;
|
|
64
|
+
private readonly fetchFn;
|
|
65
|
+
constructor(config: ChatClientConfig);
|
|
66
|
+
/** Create a new chat session. */
|
|
67
|
+
createSession(): Promise<CreateChatSessionResponse>;
|
|
68
|
+
/** Send a user message to a chat session. */
|
|
69
|
+
sendMessage(sessionId: string, body: SendChatMessageBody): Promise<SendChatMessageResponse>;
|
|
70
|
+
/** Get message history for a chat session. */
|
|
71
|
+
getHistory(sessionId: string): Promise<ChatHistoryResponse>;
|
|
72
|
+
/**
|
|
73
|
+
* Get a presigned S3 URL for file upload.
|
|
74
|
+
*
|
|
75
|
+
* Upload flow:
|
|
76
|
+
* 1. `getPresignedUpload()` — get the upload URL
|
|
77
|
+
* 2. `PUT` the file directly to `upload_url`
|
|
78
|
+
* 3. `completeUpload()` — register the artifact
|
|
79
|
+
* 4. Include the artifact in `sendMessage()` via the `artifacts` array
|
|
80
|
+
*/
|
|
81
|
+
getPresignedUpload(query: PresignedUploadQuery): Promise<PresignedUploadResponse>;
|
|
82
|
+
/** Register an uploaded artifact after direct S3 upload. */
|
|
83
|
+
completeUpload(body: CompleteUploadBody): Promise<CompleteUploadResponse>;
|
|
84
|
+
/**
|
|
85
|
+
* Upload a file and return the artifact metadata ready for `sendMessage()`.
|
|
86
|
+
*
|
|
87
|
+
* Convenience method that combines `getPresignedUpload()`, S3 upload, and
|
|
88
|
+
* `completeUpload()` into a single call.
|
|
89
|
+
*/
|
|
90
|
+
uploadFile(file: Blob, filename: string, mimeType: string): Promise<{
|
|
91
|
+
media_id: string;
|
|
92
|
+
mime_type: string;
|
|
93
|
+
filename: string;
|
|
94
|
+
size_bytes: number;
|
|
95
|
+
}>;
|
|
96
|
+
/**
|
|
97
|
+
* Connect a bidirectional WebSocket for sending messages and receiving
|
|
98
|
+
* real-time AI response streaming.
|
|
99
|
+
*
|
|
100
|
+
* Returns a `ChatConnection` with `sendMessage()` and `close()` methods.
|
|
101
|
+
* Pass event handlers to react to streaming chunks, completed responses,
|
|
102
|
+
* and session lifecycle events.
|
|
103
|
+
*/
|
|
104
|
+
connect(sessionId: string, handlers?: ChatConnectionHandlers): ChatConnection;
|
|
105
|
+
private request;
|
|
106
|
+
}
|
package/chat-client.js
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* HappyRobotChatClient — lightweight browser-side client for chat sessions.
|
|
4
|
+
*
|
|
5
|
+
* Initialized with a scoped client token (created server-side via
|
|
6
|
+
* `client.chat.createToken()`). Does NOT require an API key.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { HappyRobotChatClient } from "@happyrobot-ai/sdk";
|
|
11
|
+
*
|
|
12
|
+
* // Token comes from your server
|
|
13
|
+
* const chat = new HappyRobotChatClient({ token });
|
|
14
|
+
*
|
|
15
|
+
* const { session_id } = await chat.createSession();
|
|
16
|
+
*
|
|
17
|
+
* chat.connect(session_id, {
|
|
18
|
+
* onResponseStart: () => { },
|
|
19
|
+
* onResponseChunk: (content) => { },
|
|
20
|
+
* onResponseEnd: (content) => { },
|
|
21
|
+
* onSessionClosed: (event) => { },
|
|
22
|
+
* });
|
|
23
|
+
*
|
|
24
|
+
* await chat.sendMessage(session_id, { content: "Hello!" });
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
28
|
+
exports.HappyRobotChatClient = void 0;
|
|
29
|
+
const DEFAULT_BASE_URL = "https://platform.happyrobot.ai/api/v2";
|
|
30
|
+
class HappyRobotChatClient {
|
|
31
|
+
token;
|
|
32
|
+
baseUrl;
|
|
33
|
+
fetchFn;
|
|
34
|
+
constructor(config) {
|
|
35
|
+
if (!config.token) {
|
|
36
|
+
throw new Error("token is required");
|
|
37
|
+
}
|
|
38
|
+
this.token = config.token;
|
|
39
|
+
const customBaseUrl = config.baseUrl;
|
|
40
|
+
const isTesting = typeof process !== "undefined" && process.env?.HR_TESTING === "true";
|
|
41
|
+
if (customBaseUrl && !isTesting) {
|
|
42
|
+
throw new Error("baseUrl can not be overridden");
|
|
43
|
+
}
|
|
44
|
+
this.baseUrl = (customBaseUrl ?? DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
45
|
+
this.fetchFn = config.fetch ?? globalThis.fetch.bind(globalThis);
|
|
46
|
+
}
|
|
47
|
+
/** Create a new chat session. */
|
|
48
|
+
async createSession() {
|
|
49
|
+
return this.request("POST", "/chat/sessions");
|
|
50
|
+
}
|
|
51
|
+
/** Send a user message to a chat session. */
|
|
52
|
+
async sendMessage(sessionId, body) {
|
|
53
|
+
return this.request("POST", `/chat/sessions/${enc(sessionId)}/messages`, body);
|
|
54
|
+
}
|
|
55
|
+
/** Get message history for a chat session. */
|
|
56
|
+
async getHistory(sessionId) {
|
|
57
|
+
return this.request("GET", `/chat/sessions/${enc(sessionId)}/history`);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Get a presigned S3 URL for file upload.
|
|
61
|
+
*
|
|
62
|
+
* Upload flow:
|
|
63
|
+
* 1. `getPresignedUpload()` — get the upload URL
|
|
64
|
+
* 2. `PUT` the file directly to `upload_url`
|
|
65
|
+
* 3. `completeUpload()` — register the artifact
|
|
66
|
+
* 4. Include the artifact in `sendMessage()` via the `artifacts` array
|
|
67
|
+
*/
|
|
68
|
+
async getPresignedUpload(query) {
|
|
69
|
+
const params = new URLSearchParams({
|
|
70
|
+
filename: query.filename,
|
|
71
|
+
mime_type: query.mime_type,
|
|
72
|
+
});
|
|
73
|
+
return this.request("GET", `/chat/upload/presigned?${params.toString()}`);
|
|
74
|
+
}
|
|
75
|
+
/** Register an uploaded artifact after direct S3 upload. */
|
|
76
|
+
async completeUpload(body) {
|
|
77
|
+
return this.request("POST", "/chat/upload/complete", body);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Upload a file and return the artifact metadata ready for `sendMessage()`.
|
|
81
|
+
*
|
|
82
|
+
* Convenience method that combines `getPresignedUpload()`, S3 upload, and
|
|
83
|
+
* `completeUpload()` into a single call.
|
|
84
|
+
*/
|
|
85
|
+
async uploadFile(file, filename, mimeType) {
|
|
86
|
+
const upload = await this.getPresignedUpload({
|
|
87
|
+
filename,
|
|
88
|
+
mime_type: mimeType,
|
|
89
|
+
});
|
|
90
|
+
await this.fetchFn(upload.upload_url, {
|
|
91
|
+
method: "PUT",
|
|
92
|
+
body: file,
|
|
93
|
+
headers: { "Content-Type": mimeType },
|
|
94
|
+
});
|
|
95
|
+
const completed = await this.completeUpload({
|
|
96
|
+
artifact_id: upload.artifact_id,
|
|
97
|
+
s3_uri: upload.s3_uri,
|
|
98
|
+
filename,
|
|
99
|
+
mime_type: mimeType,
|
|
100
|
+
size_bytes: file.size,
|
|
101
|
+
});
|
|
102
|
+
return {
|
|
103
|
+
media_id: completed.artifact_id,
|
|
104
|
+
mime_type: mimeType,
|
|
105
|
+
filename,
|
|
106
|
+
size_bytes: file.size,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Connect a bidirectional WebSocket for sending messages and receiving
|
|
111
|
+
* real-time AI response streaming.
|
|
112
|
+
*
|
|
113
|
+
* Returns a `ChatConnection` with `sendMessage()` and `close()` methods.
|
|
114
|
+
* Pass event handlers to react to streaming chunks, completed responses,
|
|
115
|
+
* and session lifecycle events.
|
|
116
|
+
*/
|
|
117
|
+
connect(sessionId, handlers = {}) {
|
|
118
|
+
const wsBase = this.baseUrl
|
|
119
|
+
.replace(/^http:/, "ws:")
|
|
120
|
+
.replace(/^https:/, "wss:");
|
|
121
|
+
const url = `${wsBase}/chat/sessions/${enc(sessionId)}/ws?token=${enc(this.token)}`;
|
|
122
|
+
const ws = new WebSocket(url);
|
|
123
|
+
// Pending message-ack/message-error callbacks keyed by client-generated id.
|
|
124
|
+
const pending = new Map();
|
|
125
|
+
ws.onmessage = (event) => {
|
|
126
|
+
try {
|
|
127
|
+
const data = JSON.parse(event.data);
|
|
128
|
+
switch (data.type) {
|
|
129
|
+
case "connected":
|
|
130
|
+
handlers.onConnected?.(data.session_id);
|
|
131
|
+
break;
|
|
132
|
+
case "response-start":
|
|
133
|
+
handlers.onResponseStart?.();
|
|
134
|
+
break;
|
|
135
|
+
case "response-chunk":
|
|
136
|
+
handlers.onResponseChunk?.(data.content);
|
|
137
|
+
break;
|
|
138
|
+
case "response-end":
|
|
139
|
+
handlers.onResponseEnd?.(data.content);
|
|
140
|
+
break;
|
|
141
|
+
case "session-closed":
|
|
142
|
+
handlers.onSessionClosed?.(data);
|
|
143
|
+
break;
|
|
144
|
+
case "token-expired":
|
|
145
|
+
handlers.onTokenExpired?.();
|
|
146
|
+
break;
|
|
147
|
+
case "message-ack": {
|
|
148
|
+
const id = data.id;
|
|
149
|
+
if (id && pending.has(id)) {
|
|
150
|
+
pending.get(id).resolve(data);
|
|
151
|
+
pending.delete(id);
|
|
152
|
+
}
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
case "message-error": {
|
|
156
|
+
const id = data.id;
|
|
157
|
+
if (id && pending.has(id)) {
|
|
158
|
+
pending.get(id).reject(new Error(data.error));
|
|
159
|
+
pending.delete(id);
|
|
160
|
+
}
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
case "heartbeat":
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
// Ignore malformed messages
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
ws.onerror = (event) => {
|
|
172
|
+
handlers.onError?.(event);
|
|
173
|
+
};
|
|
174
|
+
ws.onclose = (event) => {
|
|
175
|
+
// Reject all pending messages on close
|
|
176
|
+
for (const [, { reject }] of pending) {
|
|
177
|
+
reject(new Error("WebSocket closed"));
|
|
178
|
+
}
|
|
179
|
+
pending.clear();
|
|
180
|
+
handlers.onClose?.(event);
|
|
181
|
+
};
|
|
182
|
+
const sendMessage = (body) => {
|
|
183
|
+
return new Promise((resolve, reject) => {
|
|
184
|
+
if (ws.readyState !== WebSocket.OPEN) {
|
|
185
|
+
reject(new Error("WebSocket is not open"));
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
const id = crypto.randomUUID();
|
|
189
|
+
pending.set(id, { resolve, reject });
|
|
190
|
+
ws.send(JSON.stringify({
|
|
191
|
+
type: "message",
|
|
192
|
+
id,
|
|
193
|
+
content: body.content,
|
|
194
|
+
...(body.artifacts && body.artifacts.length > 0
|
|
195
|
+
? { artifacts: body.artifacts }
|
|
196
|
+
: {}),
|
|
197
|
+
}));
|
|
198
|
+
});
|
|
199
|
+
};
|
|
200
|
+
const endSession = async () => {
|
|
201
|
+
await this.request("POST", `/chat/sessions/${enc(sessionId)}/close`);
|
|
202
|
+
ws.close();
|
|
203
|
+
};
|
|
204
|
+
return {
|
|
205
|
+
close: () => ws.close(),
|
|
206
|
+
endSession,
|
|
207
|
+
sendMessage,
|
|
208
|
+
get ws() {
|
|
209
|
+
return ws;
|
|
210
|
+
},
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
// ── Internal ──
|
|
214
|
+
async request(method, path, body) {
|
|
215
|
+
const url = `${this.baseUrl}${path}`;
|
|
216
|
+
const headers = {
|
|
217
|
+
Authorization: `Bearer ${this.token}`,
|
|
218
|
+
Accept: "application/json",
|
|
219
|
+
};
|
|
220
|
+
if (body !== undefined) {
|
|
221
|
+
headers["Content-Type"] = "application/json";
|
|
222
|
+
}
|
|
223
|
+
const response = await this.fetchFn(url, {
|
|
224
|
+
method,
|
|
225
|
+
headers,
|
|
226
|
+
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
227
|
+
});
|
|
228
|
+
if (!response.ok) {
|
|
229
|
+
const errorBody = await response.text().catch(() => "");
|
|
230
|
+
let parsed = {};
|
|
231
|
+
try {
|
|
232
|
+
parsed = JSON.parse(errorBody);
|
|
233
|
+
}
|
|
234
|
+
catch {
|
|
235
|
+
// ignore
|
|
236
|
+
}
|
|
237
|
+
throw new Error(parsed.error ||
|
|
238
|
+
parsed.message ||
|
|
239
|
+
`Request failed with status ${response.status}`);
|
|
240
|
+
}
|
|
241
|
+
const text = await response.text();
|
|
242
|
+
if (!text)
|
|
243
|
+
return undefined;
|
|
244
|
+
return JSON.parse(text);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
exports.HappyRobotChatClient = HappyRobotChatClient;
|
|
248
|
+
function enc(s) {
|
|
249
|
+
return encodeURIComponent(s);
|
|
250
|
+
}
|
|
251
|
+
//# sourceMappingURL=chat-client.js.map
|
package/chat-client.mjs
ADDED
package/client.d.ts
CHANGED
|
@@ -24,7 +24,6 @@ import { ContactsResource } from "./resources/contacts";
|
|
|
24
24
|
import { KnowledgeBasesResource } from "./resources/knowledge-bases";
|
|
25
25
|
import { WorkflowFoldersResource } from "./resources/workflow-folders";
|
|
26
26
|
import { MCPResource } from "./resources/mcp";
|
|
27
|
-
import { UsageResource } from "./resources/usage";
|
|
28
27
|
import { BillingResource } from "./resources/billing";
|
|
29
28
|
import { ApiKeyResource } from "./resources/api-key";
|
|
30
29
|
import { AdversarialSuitesResource } from "./resources/adversarial-suites";
|
|
@@ -33,6 +32,8 @@ import { NorthstarsResource } from "./resources/northstars";
|
|
|
33
32
|
import { CustomEvalsResource } from "./resources/custom-evals";
|
|
34
33
|
import { IssuesResource } from "./resources/issues";
|
|
35
34
|
import { AuditRemarksResource } from "./resources/audit-remarks";
|
|
35
|
+
import { ChatResource } from "./resources/chat";
|
|
36
|
+
import { ArtifactsResource } from "./resources/artifacts";
|
|
36
37
|
export declare class HappyRobotClient {
|
|
37
38
|
private readonly http;
|
|
38
39
|
/** Workflow CRUD, publishing, runs, and templates. */
|
|
@@ -63,8 +64,6 @@ export declare class HappyRobotClient {
|
|
|
63
64
|
readonly workflowFolders: WorkflowFoldersResource;
|
|
64
65
|
/** MCP server management. */
|
|
65
66
|
readonly mcp: MCPResource;
|
|
66
|
-
/** Usage metrics (call minutes, tokens, etc.). */
|
|
67
|
-
readonly usage: UsageResource;
|
|
68
67
|
/** Billing usage details and totals. */
|
|
69
68
|
readonly billing: BillingResource;
|
|
70
69
|
/** API key introspection. */
|
|
@@ -81,5 +80,9 @@ export declare class HappyRobotClient {
|
|
|
81
80
|
readonly issues: IssuesResource;
|
|
82
81
|
/** Audit remark feedback management. */
|
|
83
82
|
readonly auditRemarks: AuditRemarksResource;
|
|
83
|
+
/** Chat session management and messaging. */
|
|
84
|
+
readonly chat: ChatResource;
|
|
85
|
+
/** Artifact URL resolution. */
|
|
86
|
+
readonly artifacts: ArtifactsResource;
|
|
84
87
|
constructor(config: ClientConfig);
|
|
85
88
|
}
|
package/client.js
CHANGED
|
@@ -27,7 +27,6 @@ const contacts_1 = require("./resources/contacts");
|
|
|
27
27
|
const knowledge_bases_1 = require("./resources/knowledge-bases");
|
|
28
28
|
const workflow_folders_1 = require("./resources/workflow-folders");
|
|
29
29
|
const mcp_1 = require("./resources/mcp");
|
|
30
|
-
const usage_1 = require("./resources/usage");
|
|
31
30
|
const billing_1 = require("./resources/billing");
|
|
32
31
|
const api_key_1 = require("./resources/api-key");
|
|
33
32
|
const adversarial_suites_1 = require("./resources/adversarial-suites");
|
|
@@ -36,6 +35,8 @@ const northstars_1 = require("./resources/northstars");
|
|
|
36
35
|
const custom_evals_1 = require("./resources/custom-evals");
|
|
37
36
|
const issues_1 = require("./resources/issues");
|
|
38
37
|
const audit_remarks_1 = require("./resources/audit-remarks");
|
|
38
|
+
const chat_1 = require("./resources/chat");
|
|
39
|
+
const artifacts_1 = require("./resources/artifacts");
|
|
39
40
|
class HappyRobotClient {
|
|
40
41
|
http;
|
|
41
42
|
/** Workflow CRUD, publishing, runs, and templates. */
|
|
@@ -66,8 +67,6 @@ class HappyRobotClient {
|
|
|
66
67
|
workflowFolders;
|
|
67
68
|
/** MCP server management. */
|
|
68
69
|
mcp;
|
|
69
|
-
/** Usage metrics (call minutes, tokens, etc.). */
|
|
70
|
-
usage;
|
|
71
70
|
/** Billing usage details and totals. */
|
|
72
71
|
billing;
|
|
73
72
|
/** API key introspection. */
|
|
@@ -84,6 +83,10 @@ class HappyRobotClient {
|
|
|
84
83
|
issues;
|
|
85
84
|
/** Audit remark feedback management. */
|
|
86
85
|
auditRemarks;
|
|
86
|
+
/** Chat session management and messaging. */
|
|
87
|
+
chat;
|
|
88
|
+
/** Artifact URL resolution. */
|
|
89
|
+
artifacts;
|
|
87
90
|
constructor(config) {
|
|
88
91
|
this.http = new http_1.HttpClient(config);
|
|
89
92
|
this.workflows = new workflows_1.WorkflowsResource(this.http);
|
|
@@ -100,7 +103,6 @@ class HappyRobotClient {
|
|
|
100
103
|
this.knowledgeBases = new knowledge_bases_1.KnowledgeBasesResource(this.http);
|
|
101
104
|
this.workflowFolders = new workflow_folders_1.WorkflowFoldersResource(this.http);
|
|
102
105
|
this.mcp = new mcp_1.MCPResource(this.http);
|
|
103
|
-
this.usage = new usage_1.UsageResource(this.http);
|
|
104
106
|
this.billing = new billing_1.BillingResource(this.http);
|
|
105
107
|
this.apiKey = new api_key_1.ApiKeyResource(this.http);
|
|
106
108
|
this.adversarialSuites = new adversarial_suites_1.AdversarialSuitesResource(this.http);
|
|
@@ -109,6 +111,8 @@ class HappyRobotClient {
|
|
|
109
111
|
this.customEvals = new custom_evals_1.CustomEvalsResource(this.http);
|
|
110
112
|
this.issues = new issues_1.IssuesResource(this.http);
|
|
111
113
|
this.auditRemarks = new audit_remarks_1.AuditRemarksResource(this.http);
|
|
114
|
+
this.chat = new chat_1.ChatResource(this.http);
|
|
115
|
+
this.artifacts = new artifacts_1.ArtifactsResource(this.http);
|
|
112
116
|
}
|
|
113
117
|
}
|
|
114
118
|
exports.HappyRobotClient = HappyRobotClient;
|
package/core/http.js
CHANGED
|
@@ -22,8 +22,9 @@ class HttpClient {
|
|
|
22
22
|
}
|
|
23
23
|
this.apiKey = config.apiKey;
|
|
24
24
|
const customBaseUrl = config.baseUrl;
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
const isTesting = typeof process !== "undefined" && process.env?.HR_TESTING === "true";
|
|
26
|
+
if (customBaseUrl && !isTesting) {
|
|
27
|
+
throw new Error("baseUrl can not be overridden");
|
|
27
28
|
}
|
|
28
29
|
this.baseUrl = (customBaseUrl ?? DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
29
30
|
this.timeout = config.timeout ?? DEFAULT_TIMEOUT;
|
package/index.d.ts
CHANGED
|
@@ -22,6 +22,8 @@
|
|
|
22
22
|
* ```
|
|
23
23
|
*/
|
|
24
24
|
export { HappyRobotClient } from "./client";
|
|
25
|
+
export { HappyRobotChatClient } from "./chat-client";
|
|
26
|
+
export type { ChatConnectionHandlers, ChatConnection } from "./chat-client";
|
|
25
27
|
export type { ClientConfig, RequestConfig, PaginatedResponse, PaginationMetadata, PaginationQuery } from "./core/types";
|
|
26
28
|
export { HappyRobotError, ApiError, AuthenticationError, NotFoundError, ValidationError, RateLimitError, TimeoutError, NetworkError, } from "./core/errors";
|
|
27
29
|
export type { ApiErrorBody } from "./core/errors";
|
|
@@ -43,7 +45,6 @@ export { ContactsResource } from "./resources/contacts";
|
|
|
43
45
|
export { KnowledgeBasesResource } from "./resources/knowledge-bases";
|
|
44
46
|
export { WorkflowFoldersResource } from "./resources/workflow-folders";
|
|
45
47
|
export { MCPResource } from "./resources/mcp";
|
|
46
|
-
export { UsageResource } from "./resources/usage";
|
|
47
48
|
export { BillingResource } from "./resources/billing";
|
|
48
49
|
export { ApiKeyResource } from "./resources/api-key";
|
|
49
50
|
export { AdversarialSuitesResource } from "./resources/adversarial-suites";
|
|
@@ -52,6 +53,8 @@ export { NorthstarsResource } from "./resources/northstars";
|
|
|
52
53
|
export { CustomEvalsResource } from "./resources/custom-evals";
|
|
53
54
|
export { IssuesResource } from "./resources/issues";
|
|
54
55
|
export { AuditRemarksResource } from "./resources/audit-remarks";
|
|
56
|
+
export { ChatResource } from "./resources/chat";
|
|
57
|
+
export { ArtifactsResource } from "./resources/artifacts";
|
|
55
58
|
export type * from "./types/workflows.types";
|
|
56
59
|
export type * from "./types/versions.types";
|
|
57
60
|
export type * from "./types/nodes.types";
|
|
@@ -62,7 +65,6 @@ export type * from "./types/sip-trunks.types";
|
|
|
62
65
|
export type * from "./types/integrations.types";
|
|
63
66
|
export type * from "./types/contacts.types";
|
|
64
67
|
export type * from "./types/knowledge-bases.types";
|
|
65
|
-
export type * from "./types/usage.types";
|
|
66
68
|
export type * from "./types/variables.types";
|
|
67
69
|
export type * from "./types/messages.types";
|
|
68
70
|
export type * from "./types/mcp.types";
|
|
@@ -73,3 +75,5 @@ export type * from "./types/northstars.types";
|
|
|
73
75
|
export type * from "./types/custom-evals.types";
|
|
74
76
|
export type * from "./types/issues.types";
|
|
75
77
|
export type * from "./types/audit-remarks.types";
|
|
78
|
+
export type * from "./types/chat.types";
|
|
79
|
+
export type * from "./types/artifacts.types";
|
package/index.js
CHANGED
|
@@ -23,10 +23,12 @@
|
|
|
23
23
|
* ```
|
|
24
24
|
*/
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.AuditRemarksResource = exports.IssuesResource = exports.CustomEvalsResource = exports.NorthstarsResource = exports.AdversarialTestsResource = exports.AdversarialSuitesResource = exports.ApiKeyResource = exports.BillingResource = exports.
|
|
27
|
-
// ──
|
|
26
|
+
exports.ArtifactsResource = exports.ChatResource = exports.AuditRemarksResource = exports.IssuesResource = exports.CustomEvalsResource = exports.NorthstarsResource = exports.AdversarialTestsResource = exports.AdversarialSuitesResource = exports.ApiKeyResource = exports.BillingResource = exports.MCPResource = exports.WorkflowFoldersResource = exports.KnowledgeBasesResource = exports.ContactsResource = exports.IntegrationsResource = exports.SipTrunksResource = exports.PhoneNumbersResource = exports.VariablesResource = exports.MessagesResource = exports.SessionsResource = exports.RunsResource = exports.NodesResource = exports.VersionsResource = exports.WorkflowsResource = exports.iterateSSE = exports.paginate = exports.NetworkError = exports.TimeoutError = exports.RateLimitError = exports.ValidationError = exports.NotFoundError = exports.AuthenticationError = exports.ApiError = exports.HappyRobotError = exports.HappyRobotChatClient = exports.HappyRobotClient = void 0;
|
|
27
|
+
// ── Clients ──
|
|
28
28
|
var client_1 = require("./client");
|
|
29
29
|
Object.defineProperty(exports, "HappyRobotClient", { enumerable: true, get: function () { return client_1.HappyRobotClient; } });
|
|
30
|
+
var chat_client_1 = require("./chat-client");
|
|
31
|
+
Object.defineProperty(exports, "HappyRobotChatClient", { enumerable: true, get: function () { return chat_client_1.HappyRobotChatClient; } });
|
|
30
32
|
var errors_1 = require("./core/errors");
|
|
31
33
|
Object.defineProperty(exports, "HappyRobotError", { enumerable: true, get: function () { return errors_1.HappyRobotError; } });
|
|
32
34
|
Object.defineProperty(exports, "ApiError", { enumerable: true, get: function () { return errors_1.ApiError; } });
|
|
@@ -69,8 +71,6 @@ var workflow_folders_1 = require("./resources/workflow-folders");
|
|
|
69
71
|
Object.defineProperty(exports, "WorkflowFoldersResource", { enumerable: true, get: function () { return workflow_folders_1.WorkflowFoldersResource; } });
|
|
70
72
|
var mcp_1 = require("./resources/mcp");
|
|
71
73
|
Object.defineProperty(exports, "MCPResource", { enumerable: true, get: function () { return mcp_1.MCPResource; } });
|
|
72
|
-
var usage_1 = require("./resources/usage");
|
|
73
|
-
Object.defineProperty(exports, "UsageResource", { enumerable: true, get: function () { return usage_1.UsageResource; } });
|
|
74
74
|
var billing_1 = require("./resources/billing");
|
|
75
75
|
Object.defineProperty(exports, "BillingResource", { enumerable: true, get: function () { return billing_1.BillingResource; } });
|
|
76
76
|
var api_key_1 = require("./resources/api-key");
|
|
@@ -87,4 +87,8 @@ var issues_1 = require("./resources/issues");
|
|
|
87
87
|
Object.defineProperty(exports, "IssuesResource", { enumerable: true, get: function () { return issues_1.IssuesResource; } });
|
|
88
88
|
var audit_remarks_1 = require("./resources/audit-remarks");
|
|
89
89
|
Object.defineProperty(exports, "AuditRemarksResource", { enumerable: true, get: function () { return audit_remarks_1.AuditRemarksResource; } });
|
|
90
|
+
var chat_1 = require("./resources/chat");
|
|
91
|
+
Object.defineProperty(exports, "ChatResource", { enumerable: true, get: function () { return chat_1.ChatResource; } });
|
|
92
|
+
var artifacts_1 = require("./resources/artifacts");
|
|
93
|
+
Object.defineProperty(exports, "ArtifactsResource", { enumerable: true, get: function () { return artifacts_1.ArtifactsResource; } });
|
|
90
94
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@happyrobot-ai/sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "TypeScript SDK for the HappyRobot Public API",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"module": "./index.mjs",
|
|
@@ -37,7 +37,8 @@
|
|
|
37
37
|
"license": "MIT",
|
|
38
38
|
"repository": {
|
|
39
39
|
"type": "git",
|
|
40
|
-
"url": "https://github.com/happyrobot-ai/app-v2"
|
|
40
|
+
"url": "git+https://github.com/happyrobot-ai/app-v2.git",
|
|
41
|
+
"directory": "packages/public_api"
|
|
41
42
|
},
|
|
42
43
|
"dependencies": {}
|
|
43
44
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { HttpClient } from "../core/http";
|
|
2
|
+
import type { ResolveArtifactsBody, ResolveArtifactsResponse } from "../types/artifacts.types";
|
|
3
|
+
export declare class ArtifactsResource {
|
|
4
|
+
private readonly http;
|
|
5
|
+
constructor(http: HttpClient);
|
|
6
|
+
resolve(body: ResolveArtifactsBody): Promise<ResolveArtifactsResponse>;
|
|
7
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ArtifactsResource = void 0;
|
|
4
|
+
class ArtifactsResource {
|
|
5
|
+
http;
|
|
6
|
+
constructor(http) {
|
|
7
|
+
this.http = http;
|
|
8
|
+
}
|
|
9
|
+
async resolve(body) {
|
|
10
|
+
return this.http.request({
|
|
11
|
+
method: "POST",
|
|
12
|
+
path: "/artifacts/resolve",
|
|
13
|
+
body,
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.ArtifactsResource = ArtifactsResource;
|
|
18
|
+
//# sourceMappingURL=artifacts.js.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chat resource — client.chat.*
|
|
3
|
+
*
|
|
4
|
+
* Server-side only. Creates scoped client tokens that are passed to the
|
|
5
|
+
* browser-side `HappyRobotChatClient`.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* const client = new HappyRobotClient({ apiKey: "sk_live_..." });
|
|
10
|
+
* const { token } = await client.chat.createToken({ workflow_id: "..." });
|
|
11
|
+
* // Pass `token` to the browser → new HappyRobotChatClient({ token })
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
import type { HttpClient } from "../core/http";
|
|
15
|
+
import type { CreateChatTokenBody, CreateChatTokenResponse } from "../types/chat.types";
|
|
16
|
+
export declare class ChatResource {
|
|
17
|
+
private readonly http;
|
|
18
|
+
constructor(http: HttpClient);
|
|
19
|
+
/**
|
|
20
|
+
* Create a scoped client token for browser-side chat operations.
|
|
21
|
+
*
|
|
22
|
+
* Call this from your server, then pass the returned `token` to the browser
|
|
23
|
+
* where it can be used to initialize `HappyRobotChatClient`.
|
|
24
|
+
*/
|
|
25
|
+
createToken(body: CreateChatTokenBody): Promise<CreateChatTokenResponse>;
|
|
26
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Chat resource — client.chat.*
|
|
4
|
+
*
|
|
5
|
+
* Server-side only. Creates scoped client tokens that are passed to the
|
|
6
|
+
* browser-side `HappyRobotChatClient`.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* const client = new HappyRobotClient({ apiKey: "sk_live_..." });
|
|
11
|
+
* const { token } = await client.chat.createToken({ workflow_id: "..." });
|
|
12
|
+
* // Pass `token` to the browser → new HappyRobotChatClient({ token })
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.ChatResource = void 0;
|
|
17
|
+
class ChatResource {
|
|
18
|
+
http;
|
|
19
|
+
constructor(http) {
|
|
20
|
+
this.http = http;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Create a scoped client token for browser-side chat operations.
|
|
24
|
+
*
|
|
25
|
+
* Call this from your server, then pass the returned `token` to the browser
|
|
26
|
+
* where it can be used to initialize `HappyRobotChatClient`.
|
|
27
|
+
*/
|
|
28
|
+
async createToken(body) {
|
|
29
|
+
return this.http.request({
|
|
30
|
+
method: "POST",
|
|
31
|
+
path: "/chat/tokens",
|
|
32
|
+
body,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
exports.ChatResource = ChatResource;
|
|
37
|
+
//# sourceMappingURL=chat.js.map
|
package/resources/usage.d.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Usage resource — client.usage.*
|
|
3
|
-
*
|
|
4
|
-
* Maps to:
|
|
5
|
-
* GET /usage/call-minutes
|
|
6
|
-
* GET /usage/llm-tokens
|
|
7
|
-
* GET /usage/text-count
|
|
8
|
-
* GET /usage/ocr-count
|
|
9
|
-
* GET /usage/rpa-minutes
|
|
10
|
-
*/
|
|
11
|
-
import type { HttpClient } from "../core/http";
|
|
12
|
-
import type { UsageQuery, DetailedUsageResponse } from "../types/usage.types";
|
|
13
|
-
export declare class UsageResource {
|
|
14
|
-
private readonly http;
|
|
15
|
-
constructor(http: HttpClient);
|
|
16
|
-
/** Get call minutes usage. */
|
|
17
|
-
callMinutes(query: UsageQuery): Promise<DetailedUsageResponse>;
|
|
18
|
-
/** Get LLM token usage. */
|
|
19
|
-
llmTokens(query: UsageQuery): Promise<DetailedUsageResponse>;
|
|
20
|
-
/** Get text message count usage. */
|
|
21
|
-
textCount(query: UsageQuery): Promise<DetailedUsageResponse>;
|
|
22
|
-
/** Get OCR count usage. */
|
|
23
|
-
ocrCount(query: UsageQuery): Promise<DetailedUsageResponse>;
|
|
24
|
-
/** Get RPA minutes usage. */
|
|
25
|
-
rpaMinutes(query: UsageQuery): Promise<DetailedUsageResponse>;
|
|
26
|
-
private toQuery;
|
|
27
|
-
}
|
package/resources/usage.js
DELETED
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Usage resource — client.usage.*
|
|
4
|
-
*
|
|
5
|
-
* Maps to:
|
|
6
|
-
* GET /usage/call-minutes
|
|
7
|
-
* GET /usage/llm-tokens
|
|
8
|
-
* GET /usage/text-count
|
|
9
|
-
* GET /usage/ocr-count
|
|
10
|
-
* GET /usage/rpa-minutes
|
|
11
|
-
*/
|
|
12
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
-
exports.UsageResource = void 0;
|
|
14
|
-
class UsageResource {
|
|
15
|
-
http;
|
|
16
|
-
constructor(http) {
|
|
17
|
-
this.http = http;
|
|
18
|
-
}
|
|
19
|
-
/** Get call minutes usage. */
|
|
20
|
-
async callMinutes(query) {
|
|
21
|
-
return this.http.request({
|
|
22
|
-
method: "GET",
|
|
23
|
-
path: "/usage/call-minutes",
|
|
24
|
-
query: this.toQuery(query),
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
/** Get LLM token usage. */
|
|
28
|
-
async llmTokens(query) {
|
|
29
|
-
return this.http.request({
|
|
30
|
-
method: "GET",
|
|
31
|
-
path: "/usage/llm-tokens",
|
|
32
|
-
query: this.toQuery(query),
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
/** Get text message count usage. */
|
|
36
|
-
async textCount(query) {
|
|
37
|
-
return this.http.request({
|
|
38
|
-
method: "GET",
|
|
39
|
-
path: "/usage/text-count",
|
|
40
|
-
query: this.toQuery(query),
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
/** Get OCR count usage. */
|
|
44
|
-
async ocrCount(query) {
|
|
45
|
-
return this.http.request({
|
|
46
|
-
method: "GET",
|
|
47
|
-
path: "/usage/ocr-count",
|
|
48
|
-
query: this.toQuery(query),
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
/** Get RPA minutes usage. */
|
|
52
|
-
async rpaMinutes(query) {
|
|
53
|
-
return this.http.request({
|
|
54
|
-
method: "GET",
|
|
55
|
-
path: "/usage/rpa-minutes",
|
|
56
|
-
query: this.toQuery(query),
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
toQuery(query) {
|
|
60
|
-
const { workflow_id, start_date, end_date } = query;
|
|
61
|
-
const ids = Array.isArray(workflow_id) ? workflow_id : [workflow_id];
|
|
62
|
-
return {
|
|
63
|
-
workflow_id: ids.join(","),
|
|
64
|
-
start_date,
|
|
65
|
-
end_date,
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
exports.UsageResource = UsageResource;
|
|
70
|
-
//# sourceMappingURL=usage.js.map
|
package/resources/usage.mjs
DELETED